DIRECTORY Ascii, Atom, LooksReader, NodeProps, NodeStyle, NodeStyleOps, Rope, RopeReader, TextLooks, TextNode, TSTranslate, TSTranslatePrivate, TSArtwork, TSFont, TSGraphic, TSGlue, TSObject, TSOps, TSTypes, TextEdit; TSTranslateImpl: CEDAR PROGRAM IMPORTS Atom, LooksReader, NodeProps, NodeStyleOps, Rope, RopeReader, TextNode, TSTranslatePrivate, TSArtwork, TSFont, TSGraphic, TSObject, TSOps, TSTypes, TextEdit EXPORTS TSTranslate = BEGIN OPEN TSTypes, TSTranslatePrivate; FontNotFound: PUBLIC SIGNAL [fontName: Rope.ROPE, location: INT] RETURNS [substitute: Rope.ROPE] = CODE; ROPE: TYPE = Rope.ROPE; underAndStrikeThickess: REAL _ 0.4; underlineDrop: REAL _ -3.0; strikeoutRise: REAL _ 3.0; TreeToVlist: PUBLIC PROCEDURE [t: TextNode.Ref, progressProc: TSTranslate.ProgressProc _ NIL] RETURNS [galley: TSObject.ItemList, style: NodeStyle.Ref] = TRUSTED BEGIN state: State _ NewState[]; state.level _ IF TextNode.Level[t] = 0 THEN 0 ELSE -1; state.currentNode _ t; state.remainingLength _ 0; state.progressProc _ progressProc; state.totalChars _ state.charsToGo _ TextNode.LocNumber[TextNode.LastLocWithin[t], 0]; galley _ TSObject.CreateItemList[ProduceFromBranch, state]; style _ state.nodeStyle; NodeStyleOps.ApplyAll[style, t, print]; IF NodeProps.GetProp[t, $Yum] # NIL THEN state.totalChars _ state.charsToGo _ 1; END; ProduceFromBranch: TSObject.ProducerProc = TRUSTED { state: State _ NARROW[listWriter.writerData]; ProduceEndOfDocument: PROCEDURE = TRUSTED { listWriter.ProduceItem[TSObject.fillGlue]; listWriter.ProduceEnd[]; IF state.progressProc # NIL THEN state.progressProc[100]; }; IF state.remainingLength = 0 THEN { DO IF state.level < 0 THEN state.level _ 0 ELSE { deltaLevel: INTEGER; [state.currentNode, deltaLevel] _ TextNode.Forward[state.currentNode]; state.level _ state.level + deltaLevel; IF state.progressProc # NIL THEN -- update progress as we advance nodes state.progressProc[100*(state.totalChars-state.charsToGo)/(state.totalChars+0.01)]; IF state.level <= 0 THEN { ProduceEndOfDocument[]; RETURN }; }; IF NOT IsAMarkNode[state.currentNode] THEN EXIT; -- the current node content should be formatted ProduceMarkBranch[listWriter, state]; SkipOverBranch[state]; IF state.level <= 0 THEN { ProduceEndOfDocument[]; RETURN }; ENDLOOP; InitializeStateForNewNode[listWriter, state]; }; IF IsAnArtworkNode[state.currentNode] THEN { ProduceArtworkBranch[listWriter, state]; SkipOverBranch[state]; IF state.level <= 0 THEN ProduceEndOfDocument[]; RETURN } ELSE ProduceFromTextNode[listWriter, state]; }; ProduceFromTextNode: PROCEDURE [listWriter: TSObject.ListWriter, state: State] = TRUSTED { OPEN state^; r: TSObject.ListReader; hlist: TSObject.ItemList _ TSObject.CreateItemList[producer: NIL]; hlistWriter: TSObject.ListWriter _ hlist.listWriter; hasCharProps: BOOL ~ currentNode.hascharprops; oldCharPostfix: REF _ NIL; hlist.listWriter _ NIL; IF leftFillParameter # NIL THEN hlistWriter.ProduceItem[leftFillParameter]; IF rightFillParameter # NIL THEN hlistWriter.ProduceItem[rightFillParameter]; IF leftFillParameter # NIL THEN FOR p: LIST OF REF ANY _ leftFillParameter.listParameter, p.rest UNTIL p=NIL DO hlistWriter.ProduceItem[p.first]; ENDLOOP; IF firstIndentItem # NIL THEN {hlistWriter.ProduceItem[firstIndentItem]; firstIndentItem _ NIL}; oldLooks _ TextLooks.allLooks; -- to force apply on first char UNTIL remainingLength = 0 DO ropeIndex: INT _ ropeReader.GetIndex[]; CharPostfixChange: PROC RETURNS [changed: BOOL] ~ CHECKED { charPostfix: REF ~ TextEdit.GetCharProp[currentNode, ropeIndex, $Postfix]; changed _ oldCharPostfix # charPostfix; oldCharPostfix _ charPostfix; }; char: CHAR _ RopeReader.Get[ropeReader]; looks: TextLooks.Looks _ LooksReader.Get[looksReader]; charPostfix: REF _ NIL; charsToGo _ charsToGo-1; remainingLength _ remainingLength - 1; IF looks # oldLooks OR underlining#None OR strikeout#None OR (hasCharProps AND CharPostfixChange[]) THEN { under, strike: Dimn _ zeroDimn; GetNewLooks[hlistWriter, state, looks ! TSFont.FontNotFound => TRUSTED {substituteName _ SIGNAL FontNotFound[name, state.totalChars-state.charsToGo]}]; SELECT underlining FROM None => {}; LettersAndDigits => IF char IN ['A..'Z] OR char IN ['a..'z] OR char IN ['0..'9] THEN under _ Pt[underAndStrikeThickess]; Visible => IF char IN (' ..'~] THEN under _ Pt[underAndStrikeThickess]; All => under _ Pt[underAndStrikeThickess]; ENDCASE => ERROR; SELECT strikeout FROM None => {}; LettersAndDigits => IF char IN ['A..'Z] OR char IN ['a..'z] OR char IN ['0..'9] THEN strike _ Pt[underAndStrikeThickess]; Visible => IF char IN (' ..'~] THEN strike _ Pt[underAndStrikeThickess]; All => strike _ Pt[underAndStrikeThickess]; ENDCASE => ERROR; hlistWriter.ProduceParameter[underlineThickness, under]; hlistWriter.ProduceParameter[strikeoutThickness, strike]; IF under#zeroDimn THEN hlistWriter.ProduceParameter[underlineBottom, Pt[underlineDrop]]; IF strike#zeroDimn THEN hlistWriter.ProduceParameter[strikeoutBottom, Pt[strikeoutRise]]; }; SELECT char FROM Ascii.CR => EXIT; Ascii.TAB => { hlistWriter.ProduceEnd[]; hlist _ Tabify[hlist, state]; hlistWriter _ hlist.listWriter; hlist.listWriter _ NIL; }; Ascii.SP => hlistWriter.ProduceFromRope[curfont, rope, ropeIndex, space]; ENDCASE => hlistWriter.ProduceFromRope[curfont, rope, ropeIndex, char]; ENDLOOP; IF progressProc#NIL THEN progressProc[100*(totalChars-charsToGo)/(totalChars+0.01)]; FOR p: LIST OF REF ANY _ endFill, p.rest UNTIL p=NIL DO hlistWriter.ProduceItem[p.first]; ENDLOOP; hlistWriter.ProduceEnd[]; r _ TSOps.BreakUp[hlist, right, galleyWidth].CreateReader[]; UNTIL r.End[] DO IF r.CurrentTag[] = exception THEN listWriter.ProduceItem[r.CurrentItem[]] ELSE ERROR; r.Next[]; ENDLOOP; r.DestroyReader[]; ProduceBottomLeadingStretchAndShrink[listWriter, state]; }; IsAnArtworkNode: PROC [node: TextNode.Ref] RETURNS [BOOLEAN] ~ { recursingOnThisArtwork: BOOLEAN _ NodeProps.GetProp[node, $TSetterProcessingArtwork] # NIL; IF recursingOnThisArtwork THEN RETURN [FALSE] ELSE RETURN [NOT Rope.IsEmpty[NARROW[NodeProps.GetProp[node, $ArtworkClass]]]]; }; ProduceArtworkBranch: PROCEDURE [listWriter: TSObject.ListWriter, state: State] = TRUSTED { artworkClass: ROPE _ NARROW[NodeProps.GetProp[state.currentNode, $ArtworkClass]]; box: TSObject.Box; NodeProps.PutProp[state.currentNode, $TSetterProcessingArtwork, $ArtworkClass]; box _ BoxFromArtworkBranch[state, artworkClass]; NodeProps.RemProp[state.currentNode, $TSetterProcessingArtwork]; { r: TSObject.ListReader; hlist: TSObject.ItemList _ TSObject.CreateItemList[producer: NIL]; hlistWriter: TSObject.ListWriter _ hlist.listWriter; hlist.listWriter _ NIL; IF state.leftFillParameter # NIL THEN hlistWriter.ProduceItem[state.leftFillParameter]; IF state.rightFillParameter # NIL THEN hlistWriter.ProduceItem[state.rightFillParameter]; IF state.leftFillParameter # NIL THEN FOR p: LIST OF REF ANY _ state.leftFillParameter.listParameter, p.rest UNTIL p=NIL DO hlistWriter.ProduceItem[p.first]; ENDLOOP; IF state.firstIndentItem # NIL THEN { hlistWriter.ProduceItem[state.firstIndentItem]; state.firstIndentItem _ NIL}; hlistWriter.ProduceItem[box]; -- we do all this for this box FOR p: LIST OF REF ANY _ state.endFill, p.rest UNTIL p=NIL DO hlistWriter.ProduceItem[p.first]; ENDLOOP; hlistWriter.ProduceEnd[]; r _ TSOps.BreakUp[hlist, right, state.galleyWidth].CreateReader[]; UNTIL r.End[] DO IF r.CurrentTag[] = exception THEN listWriter.ProduceItem[r.CurrentItem[]] ELSE ERROR; r.Next[]; ENDLOOP; r.DestroyReader[]; ProduceBottomLeadingStretchAndShrink[listWriter, state]; }; }; BoxFromArtworkBranch: PROCEDURE [state: State, artworkClass: ROPE] RETURNS [box: TSObject.Box] = TRUSTED { objectFromBranch: TSArtwork.ObjectFromBranchProc ~ TSArtwork.Lookup[artworkClass]; object: TSGraphic.Object ~ objectFromBranch[state.currentNode]; extent: Dimensions ~ object.Layout[ maxX: state.galleyWidth, maxY: RealDimn[11, in], suggestedX: state.galleyWidth ]; box _ NEW[graphic TSObject.BoxRec _ [extent, graphic [object]]]; }; IsAMarkNode: PROC [node: TextNode.Ref] RETURNS [BOOLEAN] ~ { recursingOnThisMark: BOOLEAN _ NodeProps.GetProp[node, $TSetterProcessingMark] # NIL; IF recursingOnThisMark THEN RETURN [FALSE] ELSE RETURN [NOT Rope.IsEmpty[NARROW[NodeProps.GetProp[node, $Mark]]]]; }; ProduceMarkBranch: PROCEDURE [listWriter: TSObject.ListWriter, state: State] = TRUSTED { contents: TSObject.ItemList; box: TSObject.Box; mark: ROPE _ NARROW[NodeProps.GetProp[state.currentNode, $Mark]]; newMark: TSObject.MarkList _ NEW[TSObject.MarkListItem]; NodeProps.PutProp[state.currentNode, $TSetterProcessingMark, $Mark]; contents _ TreeToVlist[state.currentNode].galley; box _ TSOps.GetSlimBoxFrom[contents]; newMark.link _ NIL; newMark.markKind _ Atom.MakeAtom[mark]; newMark.markValue _ box; listWriter.ProduceItem[newMark]; NodeProps.RemProp[state.currentNode, $TSetterProcessingMark]; }; SkipOverBranch: PROCEDURE [state: State] = { continuationNode: TextNode.Ref _ TextNode.LastWithin[state.currentNode]; state.charsToGo _ state.totalChars- TextNode.LocNumber[TextNode.LastLocWithin[state.currentNode], 0]; state.remainingLength _ 0; state.level _ state.level + TextNode.Level[continuationNode] - TextNode.Level[state.currentNode]; state.currentNode _ continuationNode; }; END. Michael Plass, June 28, 1982 8:56 am. Renamed from TPTranslateImpl. Michael Plass, July 15, 1982 11:20 am. Fixed it so CRs do not cause firstIndent on the next line. Michael Plass, September 15, 1982 10:54 am. Changed Rope.SP, etc, to refer to Ascii. Michael Plass, November 12, 1982 10:53 am. Added underline and strikeout. Michael Plass, November 17, 1982 9:13 am. Changed TreeToVlist to return style. Michael Plass, November 17, 1982 12:09 pm. Added FontNotFound. Michael Plass, December 8, 1982 3:38 pm. Took account of layout proc change. Rick Beach, May 18, 1983 8:26 am. Added marks to ProduceFromBranch., Rick lTSTranslateImpl.mesa Copyright (C) 1984, Xerox Corporation. All rights reserved. Translates from Tioga tree representation to box & glue representation. Michael Plass, June 24, 1985 2:20:47 pm PDT Rick Beach, February 11, 1985 10:05:57 am PST distinguish the case when t is the root of a document (and hence its content is ignored) from the case when t is the root of a subtree (and hence its content should be formatted). this is the distinguished case when a subtree root contains content to be formatted, so initialize but do not advance through the document until this node is consumed. otherwise advance through the document to the next node Inhibit infinite recursion. (remember artwork prop for debugging) Remove recursion block set up the fill parameters for centering and the like Inhibit infinite recursion. (remember mark prop for debugging) Remove recursion block Edited on May 18, 1983 8:24 am, by Beach Move production of Mark branch inside test for initialize new branch. Create: ProduceMarkBranch (local of ProduceFromBranch), ProduceArtworkBranch (local of ProduceFromBranch) Edited on December 28, 1983 4:08 pm, by Beach Restructure ProduceFromBranch to use Produce procedures that took a listWriter and updated the current state. Copied fill parameter handling code from ProduceTextNode to ProduceArtworkBranch. Edited on January 25, 1984 2:27 pm, by Beach changes to: ProduceArtworkBranch added firstIndentItem code. Edited on May 7, 1984 4:15:46 pm PDT, by Beach changes to: TSTranslateImpl, TreeToVlist, ProduceEndOfDocument (local of ProduceFromBranch), ProduceFromTextNode, ProduceArtworkBranch, ProduceMarkBranch Edited on December 5, 1984 2:48:17 pm PST, by Beach changes to: TreeToVlist, ProduceEndOfDocument (local of ProduceFromBranch), ProduceFromBranch Edited on December 6, 1984 3:45:50 pm PST, by Beach changes to: ProduceFromBranch Edited on December 8, 1984 3:05:54 pm PST, by Beach changes to: ProduceMarkBranch, ProduceArtworkBranch, BoxFromArtworkBranch, ProduceFromBranch Beach, February 11, 1985 10:05:57 am PST Modify the test for recursing on an Artwork or a Mark node without distrurbing the $ArtworkClass or $Mark properties. changes to: ProduceFromBranch, IsAnArtworkNode, ProduceArtworkBranch, BoxFromArtworkBranch, IsAMarkNode, ProduceMarkBranch, ProduceArtworkBranch, ProduceMarkBranch, ProduceEndOfDocument (local of ProduceFromBranch) Κ B– "cedar" style˜JšΟc™™žœ˜`Jšœ˜>šžœž˜Jšœ žœ˜'codeš Ÿœžœžœ žœžœ˜;Lšœ žœ:˜JLšœ'˜'Lšœ˜Lšœ˜—Jšœžœ˜(J˜6Jšœ žœžœ˜J˜J˜&š žœžœžœžœžœžœ˜jJ˜Jšœ?žœžœ8˜—šžœ ž˜Jšœ ˜ Jšœžœžœ žœžœ žœžœ žœ$˜xJšœ žœžœ žœ$˜GJšœ*˜*Jšžœžœ˜—šžœ ž˜Jšœ ˜ Jšœžœžœ žœžœ žœžœ žœ%˜yJšœ žœžœ žœ%˜HJšœ+˜+Jšžœžœ˜—Jšœ8˜8Jšœ9˜9JšžœžœB˜XJšžœžœB˜YJ˜—šžœž˜Jšœžœžœ˜šœžœ˜J˜J˜J˜Jšœžœ˜J˜—JšœžœA˜IJšžœ@˜G—Jšžœ˜—Jšžœžœžœ<˜Tšžœžœžœžœžœžœžœž˜7J˜!Jšžœ˜—J˜J˜<šžœ ž˜Jšžœžœ(˜JJšžœžœ˜ J˜ Jšžœ˜—J˜J˜8J˜J˜—šŸœžœžœžœ˜@Jšœžœ8žœ˜[šžœ˜Jšžœžœžœ˜Jšžœžœžœžœ+˜O—J˜J˜—šŸœž œ3žœ˜[Jšœžœžœ6˜QJšœ˜J˜JšœA™AJšœO˜OJ˜Jšœ0˜0J™J™Jšœ@˜@šœ˜J™5J˜Jšœ=žœ˜BJ˜4Jšœžœ˜šžœžœž˜%Jšœ1˜1—šžœžœž˜&Jšœ2˜2—šžœžœž˜%šžœžœžœžœžœ1žœžœž˜UJ˜!Jšžœ˜——šžœžœžœ˜%JšœHžœ˜M—J˜Jšœ˜=J˜šžœžœžœžœžœžœžœž˜=J˜!Jšžœ˜—J˜J˜Bšžœ ž˜Jšžœžœ(˜JJšžœžœ˜ J˜ Jšžœ˜—J˜J˜8Jšœ˜—J˜J˜—š Ÿœž œžœžœžœ˜jJ˜RJ˜?˜#J˜J˜J˜J˜—Jšœžœ7˜@J˜J˜—šŸ œžœžœžœ˜™>JšœD˜DJšœ1˜1Jšœ%˜%Jšœžœ˜Jšœ'˜'Jšœ˜Jšœ ˜ J™Jšœ=˜=J˜J˜—šŸœž œ˜,J˜H˜#J˜A—J˜˜J˜E—J˜%Jšœ˜—Jšžœ˜J˜J˜DJ˜bJšœ9žœ˜TJšœI˜IJšœN˜NJšœ?˜?JšœM˜MJšœDΟr˜JJ˜™(J™EJšœ‘œ‘œ™i—™-Jšœ ‘œX™uJ™Q—™,Jšœ ‘œ™<—™.Jšœ ‘2œ‘>™™—J™™3Jšœ ‘!œ‘™]J™—™3Jšœ ‘™J™—™3Jšœ ‘P™\—J™J™™(J™uJšœ ‘­œ™Φ—J™J™J™J™—…—&š:H