DIRECTORY Char, NodeProps, RefText, Rope, RopeReader, SymTab, TEditFormat, TextNode, TextEdit; ListHyphenationImpl: CEDAR PROGRAM IMPORTS 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 { 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]; [] ¬ TEditFormat.RegisterHyphenation[$English, ListHyphenation, NIL]; END. ° 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: <> Exemplary textual material to dem#onstrate the applicability of hyphenation techniques to sesquipedelian words. discretionary hyphen 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. ΚŸ•NewlineDelimiter –(cedarcode) style™™Jšœ Οeœ=™HJ™,Icode™,J™J™rJ™™J™J™ΠJ™…Jšœ²™²InotešœC™C—™J™ΰJ•CharSets!οM•HyphenationListoapp-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 –$(List) hyphenation 1.7 in lineLengthšœo™oL™——K˜šΟk œU˜^K˜—KšΠlnœžœž˜"KšžœT˜[šœž˜K˜Kšžœžœžœ˜šœžœ$˜>K˜—š Οnœžœ"žœ žœžœ˜mKšœžœ˜!Kšœžœ˜ Kšœ žœžœ˜/š žœžœžœžœžœž˜6Kšœ žœ%˜5Kšœ žœžœžœ˜&K˜šžœžœ˜%K™Kšžœžœ˜6Kšœ˜—Kšžœ˜—šžœžœ˜šžœ,žœžœž˜?Kšœžœ˜Kšœžœ*˜3Kšœžœžœ˜ šžœžœž˜Kšœ˜KšœžœD˜KKšžœžœ˜—šžœžœžœ˜Kšœ(˜(šžœžœž˜Kšœžœ#žœ˜0Kšžœžœ˜—Kšœ˜—Kšžœ˜—Kšœ˜—Kšœ ˜ Kšžœ˜ Kšœ˜K˜—š  œžœžœžœ˜7Kšœ žœžœ˜/Kšœ(žœ˜/Kšœ8˜8Kšœžœ˜Kšœ)˜)Kšœ/˜/Kšœ˜Kšžœžœ žœ žœ˜>šžœž˜Kšœžœ˜!Kšœžœ˜ Kšœžœ˜ šžœž˜šžœ˜ Kšžœžœžœ˜:Kšžœžœžœ/˜R—Kšœ˜Kšžœ˜—šžœžœ˜Kšœžœ˜&Kšœžœžœ˜)Kšœ%˜%Kšœ˜—Kšžœžœ žœ žœ˜>Kšžœ˜—Kšœ&˜&Kšœ ˜ Kšžœžœ žœ˜0Kšžœ ˜Kšœ˜K˜—š  œžœžœžœ˜9Kšœžœžœ˜Kšœžœžœ˜+š œžœžœžœ˜(Kšžœ žœžœ˜šžœ&žœ˜.Kšœ*˜*Kšœ˜Kšœ˜—Kšœ0˜0Kšœ˜—š  œžœžœžœžœžœžœ˜Hšžœžœž˜šœžœ˜ Kšœ˜Kšœžœ˜šžœžœžœž˜)Kšžœ žœžœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšžœ˜—Kšœ˜Kšœ˜Kšœ˜—Kšžœžœ˜—Kšœ˜—Kšœ'˜'Kšœ*˜*Kšœ˜Kšžœ˜Kšœ˜K˜—š  œ;˜DK˜—š  œ˜(šžœžœž˜Kšœ2˜2Kšžœ žœ˜—Kšœ˜K˜—Kšœ<žœ˜AKšœ?˜?Kšœ=žœ˜BK˜Kšœš™šKšœ@žœ˜E—K˜Kšžœ˜—…—pΏ