<> <> <> <> DIRECTORY Atom USING [GetPName], CommandTool USING [DoCommand], FS USING [GetName, OpenFileFromStream, StreamOpen], IO USING [STREAM], NodeProps USING [GetProp, PutProp], NodeStyle USING [Ref], NodeStyleOps USING [Create, defaultStyleName], PressPrinter USING [Abort, CurrentStateMessage, Handle, ProgressProc, SendPressFile], Rope USING [Cat, Concat, Equal, Length, ROPE], TEditDocument USING [TEditDocumentData], TextNode USING [LastChild, NarrowToTextNode, NewTextNode, Ref], TSExtras USING [NodeProc], TSJaMPageBuilder USING [RunPageBuilder], TSObject USING [ItemList], TSOutput USING [Close, Handle], TSOutputPress USING [CreateWithCursor], TSTranslate USING [ProgressProc, TreeToVlist], TSViewer USING [], UserCredentials USING [Get], UserProfile USING [Token], ViewerClasses USING [Viewer]; <<>> TSExtrasImpl: CEDAR MONITOR IMPORTS CommandTool, FS, Atom, NodeProps, NodeStyleOps, PressPrinter, Rope, TextNode, TSJaMPageBuilder, TSOutput, TSOutputPress, TSTranslate, UserCredentials, UserProfile EXPORTS TSExtras = BEGIN PrintTiogaViewer: PUBLIC ENTRY PROCEDURE [ viewer: ViewerClasses.Viewer, nameForSeparatorPage: Rope.ROPE, aborted: REF BOOLEAN, server: Rope.ROPE _ NIL, copies: INT _ 1, messageProc: PROC [Rope.ROPE] _ NIL ] = {ENABLE UNWIND => NULL; node: TextNode.Ref _ NARROW[viewer.data, TEditDocument.TEditDocumentData].text; stream: IO.STREAM _ FS.StreamOpen["temp.press$", $create]; fullName: Rope.ROPE _ FS.GetName[FS.OpenFileFromStream[stream]].fullFName; outputHandle: TSOutput.Handle _ TSOutputPress.CreateWithCursor[ stream: stream, documentName: nameForSeparatorPage, cursorObject: NIL ]; galley: TSObject.ItemList; style: NodeStyle.Ref; isAborted: PROC RETURNS [BOOLEAN] = {RETURN[IF aborted = NIL THEN FALSE ELSE aborted^]}; progressProc: PressPrinter.ProgressProc = TRUSTED { IF messageProc # NIL THEN messageProc[handle.CurrentStateMessage[]]; IF aborted # NIL AND aborted^ THEN handle.Abort[]; }; IF Rope.Length[server] = 0 THEN server _ UserProfile.Token["Hardcopy.PressPrinter", "Clover"]; [galley, style] _ TSTranslate.TreeToVlist[node]; [] _ TSJaMPageBuilder.RunPageBuilder[ galley: galley, style: style, output: outputHandle, abortCheckProc: isAborted, documentName: nameForSeparatorPage ]; outputHandle.Close[]; IF server.Equal["*"] THEN { [] _ CommandTool.DoCommand[Rope.Concat["ShowPress ", fullName], NIL]; } ELSE [] _ PressPrinter.SendPressFile[ fileName: fullName, server: server, progressProc: progressProc, copies: copies, userName: UserCredentials.Get[].name ]; }; PrintSuppliedNodes: PUBLIC ENTRY PROCEDURE [ nodeProc: TSExtras.NodeProc, nameForSeparatorPage: Rope.ROPE, aborted: REF BOOLEAN, server: Rope.ROPE _ NIL, copies: INT _ 1, messageProc: PROC [Rope.ROPE] _ NIL] = { ENABLE UNWIND => NULL; stream: IO.STREAM _ FS.StreamOpen["temp.press$", $create]; fullName: Rope.ROPE _ FS.GetName[FS.OpenFileFromStream[stream]].fullFName; outputHandle: TSOutput.Handle _ TSOutputPress.CreateWithCursor[ stream: stream, documentName: nameForSeparatorPage, cursorObject: NIL ]; root: TextNode.Ref; node: TextNode.Ref; prevLast: TextNode.Ref _ NIL; prop: REF; galley: TSObject.ItemList; style: NodeStyle.Ref; isAborted: PROC RETURNS [BOOLEAN] = {RETURN[IF aborted = NIL THEN FALSE ELSE aborted^]}; progressProc: PressPrinter.ProgressProc = TRUSTED { IF messageProc # NIL THEN messageProc[handle.CurrentStateMessage[]]; IF aborted # NIL AND aborted^ THEN handle.Abort[]; }; <> <<-- if ~child then new is sibling of x>> <<-- else new is first child of x>> <> <> <> <> <> <> < node>> < root>> <<>> InsertNode: PROCEDURE [root, node: TextNode.Ref, child: BOOL _ FALSE] = { <<-- if ~child then new is sibling of x>> <<-- else new is first child of x>> IF child THEN { IF root.child # NIL THEN { node.next _ root.child; node.last _ FALSE } ELSE { node.next _ root; node.last _ TRUE }; root.child _ node } ELSE { node.next _ root.next; node.last _ root.last; root.next _ node; root.last _ FALSE }; }; <> <<-- prevLast is optional accelerator>> <> <> <> <<>> InsertAsLastChild: PROCEDURE [root, node, prevLast: TextNode.Ref] = { IF prevLast=NIL OR ~prevLast.last OR prevLast.next # root THEN prevLast _ TextNode.NarrowToTextNode[TextNode.LastChild[root]]; IF prevLast=NIL THEN InsertNode[root, node, TRUE] ELSE InsertNode[prevLast, node, FALSE]; }; IF Rope.Length[server]=0 THEN server _ UserProfile.Token["Hardcopy.PressPrinter", "Clover"]; <> root _ TextNode.NewTextNode[]; root.last _ TRUE; UNTIL (node _ nodeProc[]) = NIL DO InsertAsLastChild[root, node, prevLast]; prevLast _ node; <> style _ NodeStyleOps.Create[]; prop _ NodeProps.GetProp[node, $Prefix]; IF prop # NIL THEN NodeProps.PutProp[node, $Prefix, Rope.Cat[ NARROW[prop, Rope.ROPE], " \"", Atom.GetPName[NodeStyleOps.defaultStyleName], "\" style"]]; ENDLOOP; <> <> [galley, style] _ TSTranslate.TreeToVlist[root]; [] _ TSJaMPageBuilder.RunPageBuilder[ galley: galley, style: style, output: outputHandle, abortCheckProc: isAborted, documentName: nameForSeparatorPage]; outputHandle.Close[]; IF server.Equal["*"] THEN { [] _ CommandTool.DoCommand[Rope.Concat["ShowPress ", fullName], NIL]; } ELSE [] _ PressPrinter.SendPressFile[ fileName: fullName, server: server, progressProc: progressProc, copies: copies, userName: UserCredentials.Get[].name ]; }; <> <> <> <> <<] = {ENABLE UNWIND => NULL;>> <> <> <> <> <> <<[galley, style] _ TSTranslate.TreeToVlist[node];>> <<[] _ TSJaMPageBuilder.RunPageBuilder[>> <> <> <> <> <> <<];>> <> <<};>> <<>> <> <> <> <> < NULL;>> <> <> <> <> <> <> <> <> <> <<-- if ~child then new is sibling of x>> <<-- else new is first child of x>> <> <> <> <> <> <<};>> <> <> <> <> <<};>> <<-- build a tree with the supplied nodes, each with the right style property>> <> <> <> <> <> <<-- put "styleName" Style in Prefix property>> <