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 { 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: 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 < 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: 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..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]; [] _ TEditFormatExtras.RegisterHyphenation[$English, ListHyphenation, NIL]; END. tListHyphenationImpl.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: <> 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. Κg˜™Jšœ<™šœ˜Lšœœ˜!Lšœœ˜ Lšœœ˜ šœ˜šœ˜ Lšœœœ˜@Lšœœœ/˜R—Lšœ˜Lšœ˜—šœœ˜Lšœœ˜&Lšœœœ˜)Lšœ%˜%Lšœ˜—Lšœœ œ œ˜>Lšœ˜—Lšœ&˜&Lšœ ˜ Lšœœ œ˜0Lšœ ˜Lšœ˜L˜—šŸ œœœœ˜9Lšœœœ˜Lšœœœ˜+šŸœœœœ˜(Lšœ œœ˜šœ&œ˜.Lšœ*˜*Lšœ˜Lšœ˜—Jšœ0˜0Lšœ˜—š Ÿ œœœœœ œ˜Hšœœ˜šœœ˜ Lšœ˜Lšœœ˜šœœœ ˜/Lšœ œœ˜Lšœ˜Lšœ˜Lšœ ˜ Lšœ˜—Lšœ˜Lšœ˜Lšœ˜—Lšœœ˜—Lšœ˜—Lšœ'˜'Lšœ*˜*Lšœ˜Lšœ˜Lšœ˜L˜—šŸ œ;˜DL˜—šŸ œ˜(šœœ˜Lšœ2˜2Lšœ œ˜—Lšœ˜L˜—Lšœ<œ˜ALšœE˜ELšœCœ˜HL˜Lšœš™šLšœFœ˜K—L˜Lšœ˜—…—Ζ‘