ListHyphenationImpl.mesa
Copyright Ó 1986, 1991, 1992 by Xerox Corporation. All rights reserved.
Michael Plass, January 30, 1992 12:54 pm PST
Hal Murray, December 22, 1986 4:01:03 pm PST
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 Char, NodeProps, RefText, Rope, RopeReader, SymTab, TEditFormat, TextNode, TextEdit;
~
BEGIN
ROPE: TYPE ~ Rope.ROPE;
HyphenationPositions:
TYPE ~ TEditFormat.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
char: Char.XCHAR ¬ TextEdit.FetchChar[node, start+i];
scratch[i] ¬ VAL[MIN[ORD[char], 127]];
scratch.length ¬ i+1;
IF char = Char.Make[357B, 43B]
THEN {
discretionary hyphen
IF j < TEditFormat.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: REF ¬ NIL;
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 < TEditFormat.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: ROPE ¬ NIL;
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..TEditFormat.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];
NodeProps.DeclarePropertyAttribute[$HyphenationList, $Visible];
[] ¬ TEditFormat.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.
[] ¬ TEditFormat.RegisterHyphenation[$English, ListHyphenation, NIL];