ListHyphenationImpl.mesa
Copyright Ó 1986 by Xerox Corporation. All rights reserved.
Michael Plass, May 9, 1986 12:07:36 pm PDT
Registers a hyphenation routine with Tioga that looks for an explicit list of hyphenations on the node properties.
To use:
1. Run this program.
2. Add a node property with the key "HyphenationList" and the value consisting of a list of hyphenations ("-" between syllables, " " between words). This property applies to the node and everything under it.
3. Place the style rule
(List) hyphenation
so that it will be effective on the desired node. (Use a Postfix property, for example).
4. A hyphenation point may also be marked by using the discretionary hyphen character (357|043); this is used in the word "demonstrate" below, and overrides the rule in the list.
I won't vouch for the accuracy of the hyphenations in this example.
Example:
<<NodeLevel: 3, Comment: TRUE, CharProps: ..., Postfix: (List) hyphenation 1.7 in lineLength, HyphenationList: app-lic-a-bil-ity Ex-empl-ary de-mon-strate mat-er-ial hyph-en-ation tech-niques text-u-al ses-qui-ped-el-i-an >>
Exemplary textual material to dem#onstrate the applicability of hyphenation techniques to sesquipedelian words.
DIRECTORY NodeProps, NodePropsExtras, RefText, Rope, RopeReader, SymTab, TEditFormatExtras, TextNode, TextEdit;
ListHyphenationImpl: CEDAR PROGRAM
IMPORTS NodeProps, NodePropsExtras, RefText, Rope, RopeReader, SymTab, TEditFormatExtras, TextNode, TextEdit
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
HyphenationPositions: TYPE ~ TEditFormatExtras.HyphenationPositions;
ListHyphenation: PROC [node: TextNode.Ref, start, len: INT, hyphData: REF]
RETURNS [HyphenationPositions] ~ {
h: HyphenationPositions ← ALL[0];
j: NAT ← 0;
scratch: REF TEXT ~ RefText.ObtainScratch[512];
FOR i: NAT IN [0..NAT[MIN[len, scratch.maxLength]]) DO
set: [0..256); char: CHAR;
[charSet: set, char: char] ← TextEdit.Fetch[node, start+i];
scratch[i] ← char; scratch.length ← i+1;
IF set = 357B AND char=43C THEN {
discretionary hyphen
IF j < TEditFormatExtras.maxHyph THEN {h[j] ← i+1; j ← j+1};
};
ENDLOOP;
IF j = 0 THEN {
FOR p: TextNode.Ref ← node, TextNode.Parent[p] UNTIL p = NIL DO
dict: SymTab.Ref ← NIL;
prop: REF ~ NodeProps.GetProp[p, $HyphenationList];
v: REFNIL;
WITH prop SELECT FROM
s: SymTab.Ref => dict ← s;
r: ROPE => NodeProps.PutProp[p, $HyphenationList, (dict ← Internalize[r])];
ENDCASE => NULL;
IF dict # NIL THEN {
v ← SymTab.FetchText[dict, scratch].val;
WITH v SELECT FROM
vh: REF HyphenationPositions => {h ← vh^; EXIT};
ENDCASE => NULL;
};
ENDLOOP;
};
RefText.ReleaseScratch[scratch];
RETURN [h]
};
Internalize: PROC [rope: ROPE] RETURNS [SymTab.Ref] ~ {
scratch: REF TEXT ~ RefText.ObtainScratch[512];
symTab: SymTab.Ref ← SymTab.Create[101, FALSE];
ropeReader: RopeReader.Ref ~ RopeReader.GetRopeReader[];
c: CHAR;
RopeReader.SetPosition[ropeReader, rope];
RopeReader.SetCharForEndOfRope[ropeReader, 0C];
c ← RopeReader.Get[ropeReader];
WHILE c IN (0C..' ] DO c ← RopeReader.Get[ropeReader] ENDLOOP;
UNTIL c = 0C DO
h: HyphenationPositions ← ALL[0];
j: NAT ← 0;
i: NAT ← 0;
WHILE c > ' DO
IF c = '-
THEN {IF j < TEditFormatExtras.maxHyph THEN {h[j] ← i; j ← j+1}}
ELSE {IF i < scratch.maxLength THEN {scratch[i] ← c; scratch.length ← i ← i + 1}};
c ← RopeReader.Get[ropeReader];
ENDLOOP;
IF j > 0 THEN {
key: ROPE ~ Rope.FromRefText[scratch];
val: REF ~ NEW[HyphenationPositions ← h];
[] ← SymTab.Insert[symTab, key, val];
};
WHILE c IN (0C..' ] DO c ← RopeReader.Get[ropeReader] ENDLOOP;
ENDLOOP;
RopeReader.FreeRopeReader[ropeReader];
RefText.ReleaseScratch[scratch];
IF SymTab.GetSize[symTab] = 0 THEN symTab ← NIL;
RETURN [symTab];
};
Externalize: PROC [symTab: SymTab.Ref] RETURNS [ROPE] ~ {
rope: ROPENIL;
buf: REF TEXT ← RefText.ObtainScratch[512];
Put: PROC [r: ROPE, start, end: NAT] ~ {
IF end < start THEN RETURN;
IF end-start+buf.length > buf.maxLength THEN {
rope ← rope.Concat[Rope.FromRefText[buf]];
buf.length ← 0;
};
[] ← Rope.AppendChars[buf, r, start, end-start];
};
ForEachPair: PROC [key: ROPE, val: REF] RETURNS [quit: BOOL ← FALSE] ~ {
WITH val SELECT FROM
v: REF HyphenationPositions => {
h: HyphenationPositions ~ v^;
from: NAT ← 0;
FOR j: NAT IN [0..TEditFormatExtras.maxHyph) DO
IF h[j] = 0 THEN EXIT;
Put[key, from, h[j]];
Put["-", 0, 1];
from ← h[j];
ENDLOOP;
Put[key, from, Rope.Size[key]];
Put[" ", 0, 1];
};
ENDCASE => NULL;
};
[] ← SymTab.Pairs[symTab, ForEachPair];
rope ← rope.Concat[Rope.FromRefText[buf]];
RefText.ReleaseScratch[buf];
RETURN [rope];
};
ReadSpecs: NodeProps.ReadSpecsProc ~ { value ← Internalize[specs] };
WriteSpecs: NodeProps.WriteSpecsProc ~ {
WITH value SELECT FROM
symTab: SymTab.Ref => specs ← Externalize[symTab];
ENDCASE => specs ← NIL;
};
NodeProps.Register[$HyphenationList, ReadSpecs, WriteSpecs, NIL];
NodePropsExtras.DeclarePropertyAttribute[$HyphenationList, $Visible];
[] ← TEditFormatExtras.RegisterHyphenation[$List, ListHyphenation, NIL];
Note: This is a temporary hack until a real hyphenation routine for English is provided. It is here because (English) hyphenation is used in Cedar.style.
[] ← TEditFormatExtras.RegisterHyphenation[$English, ListHyphenation, NIL];
END.