<> <> <> <> DIRECTORY Ascii, Atom, LooksReader, NodeProps, NodeStyle, Rope, RopeReader, TextLooks, TextNode, TSTranslate, TSTranslatePrivate, TSArtwork, TSFont, TSGraphic, TSGlue, TSObject, TSOps, TSTypes; TSTranslateImpl: PROGRAM IMPORTS Atom, LooksReader, NodeProps, NodeStyle, Rope, RopeReader, TextNode, TSTranslatePrivate, TSArtwork, TSFont, TSGraphic, TSObject, TSOps, TSTypes 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] = BEGIN state: State _ NewState[]; state.level _ 0; 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; style.ApplyAll[t, print]; IF NodeProps.GetProp[t, $Yum] # NIL THEN state.totalChars _ state.charsToGo _ 1; END; ProduceFromBranch: TSObject.ProducerProc = TRUSTED { state: State _ NARROW[listWriter.writerData]; deltaLevel: INTEGER _ 0; mark, artworkClass: ROPE; SkipOverBranch: PROCEDURE = { 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; }; ProduceMarkBranch: PROCEDURE = { contents: TSObject.ItemList; box: TSObject.Box; newMark: TSObject.MarkList _ NEW[TSObject.MarkListItem]; <> NodeProps.RemProp[state.currentNode, $Mark]; contents _ TreeToVlist[state.currentNode].galley; InitializeStateForNewNode[contents.listWriter, NARROW[contents.listWriter.writerData]]; box _ TSOps.GetSlimBoxFrom[contents]; newMark.link _ NIL; newMark.markKind _ Atom.MakeAtom[mark]; newMark.markValue _ box; listWriter.ProduceItem[newMark]; <> NodeProps.PutProp[state.currentNode, $Mark, mark]; }; ProduceArtworkBranch: PROCEDURE = { object: TSGraphic.Object; extent: Dimensions; box: TSObject.Box; objectFromBranch: TSArtwork.ObjectFromBranchProc _ TSArtwork.Lookup[artworkClass]; object _ objectFromBranch[state.currentNode]; extent _ object.Layout[ maxX: state.galleyWidth, maxY: RealDimn[6, in], suggestedX: state.galleyWidth ]; box _ NEW[graphic TSObject.BoxRec _ [extent, graphic [object]]]; listWriter.ProduceItem[box]; }; IF state.remainingLength = 0 THEN { DO -- move forward in the branch producing marks before initializing a text node [state.currentNode, deltaLevel] _ TextNode.Forward[state.currentNode]; state.level _ state.level + deltaLevel; IF state.progressProc # NIL THEN state.progressProc[100*(state.totalChars-state.charsToGo)/(state.totalChars+0.01)]; IF state.level <= 0 THEN { listWriter.ProduceItem[TSObject.fillGlue]; listWriter.ProduceEnd[]; IF state.progressProc # NIL THEN state.progressProc[100]; RETURN }; mark _ NARROW[NodeProps.GetProp[state.currentNode, $Mark]]; IF mark.Length = 0 THEN EXIT; ProduceMarkBranch[]; SkipOverBranch[]; IF state.level <= 0 THEN { listWriter.ProduceItem[TSObject.fillGlue]; listWriter.ProduceEnd[]; IF state.progressProc # NIL THEN state.progressProc[100]; RETURN }; ENDLOOP; InitializeStateForNewNode[listWriter, state]; }; artworkClass _ NARROW[NodeProps.GetProp[state.currentNode, $ArtworkClass]]; IF artworkClass.Length = 0 OR state.level=0 THEN ProduceFromTextNode[listWriter, state] ELSE { ProduceArtworkBranch[]; SkipOverBranch[]; IF state.level <= 0 THEN { listWriter.ProduceItem[TSObject.fillGlue]; listWriter.ProduceEnd[]; IF state.progressProc # NIL THEN state.progressProc[100]; RETURN }; }; }; ProduceFromTextNode: PROCEDURE [listWriter: TSObject.ListWriter, state: State] = { OPEN state^; r: TSObject.ListReader; hlist: TSObject.ItemList _ TSObject.CreateItemList[producer: NIL]; hlistWriter: TSObject.ListWriter _ hlist.listWriter; 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[]; char: CHAR _ RopeReader.Get[ropeReader]; looks: TextLooks.Looks _ LooksReader.Get[looksReader]; charsToGo _ charsToGo-1; remainingLength _ remainingLength - 1; IF looks # oldLooks OR underlining#None OR strikeout#None 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]; }; 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 <> <> <> <<>>