DIRECTORY Atom USING [GetPName], Buttons USING [ButtonProc, Create], FS USING [Error], Commander USING [CommandProc, Handle, Register], EditSpan USING [CannotDoEdit, ChangeNesting, Delete, InsertTextNode], InputFocus USING [GetInputFocus], IO USING [EndOfStream, GetTokenRope, PutFR, PutRope, RIS, STREAM], MessageWindow USING [Append, Blink], NodeProps USING [GetProp, GetSpecs, MapProps, MapPropsAction, PutProp, true], ProcessExtras USING [CheckForAbort], PutGet USING [FromFile, ToFile], Rope USING [Cat, Equal, Find, IsEmpty, ROPE], TextEdit USING [AppendRope], TextNode USING [FirstChild, Forward, Level, MakeNodeSpan, Ref, RefTextNode], TiogaOps USING [CancelSelection, Jump, Lock, Unlock, ViewerDoc], ViewerClasses USING [Viewer]; AnnotateProperties: CEDAR PROGRAM IMPORTS Atom, Buttons, FS, Commander, EditSpan, InputFocus, IO, MessageWindow, NodeProps, ProcessExtras, PutGet, Rope, TextEdit, TextNode, TiogaOps = { commentAtom: ATOM ~ $Comment; propertyAnnotationAtom: ATOM ~ $PropertyAnnotation; trueRope: Rope.ROPE ~ "TRUE"; DoAnnotations: Commander.CommandProc = { execOut: IO.STREAM = cmd.out; filename: Rope.ROPE; commandLineStream: IO.STREAM = IO.RIS[cmd.commandLine]; annotate: BOOL _ cmd.procData.clientData = $Annotate; rootNode: TextNode.Ref; DO -- process each file in command line filename _ IO.GetTokenRope[commandLineStream ! IO.EndOfStream => {filename _ NIL; CONTINUE}].token; IF filename.IsEmpty THEN EXIT; IF filename.Find["."] = -1 THEN -- add .mesa extension filename _ filename.Cat[".mesa"]; { ENABLE FS.Error => { execOut.PutRope[filename]; execOut.PutRope[" not found.\n"]; result _ $Warning; msg _ "Some files not found"; LOOP }; ProcessExtras.CheckForAbort[]; rootNode _ PutGet.FromFile[filename]; ProcessExtras.CheckForAbort[]; }; TRUSTED { TiogaOps.Lock[LOOPHOLE[rootNode]]; }; IF annotate THEN AddAnnotationNodes[rootNode] ELSE PruneAnnotationNodes[rootNode]; [] _ PutGet.ToFile[filename, rootNode]; TRUSTED { TiogaOps.Unlock[LOOPHOLE[rootNode]]; }; ENDLOOP; }; AddAnnotationNodes: PROCEDURE [rootNode: TextNode.Ref] = { annotationNode: TextNode.RefTextNode; CreateRootAnnotationNode: PROCEDURE = { annotationNode _ EditSpan.InsertTextNode[rootNode, rootNode, child]; [] _ TextEdit.AppendRope[rootNode, annotationNode, "<>"]; NodeProps.PutProp[annotationNode, propertyAnnotationAtom, trueRope]; NodeProps.PutProp[annotationNode, commentAtom, NodeProps.true]; }; CreateAnnotationNode: PROCEDURE [thisNode: TextNode.Ref, level: INTEGER] = { annotationNode _ EditSpan.InsertTextNode[root~rootNode, old~thisNode, where~before]; IF TextNode.Level[annotationNode] > TextNode.Level[thisNode] THEN [] _ EditSpan.ChangeNesting[ root~rootNode, span~TextNode.MakeNodeSpan[annotationNode, annotationNode], change~TextNode.Level[thisNode]-TextNode.Level[annotationNode]]; [] _ TextEdit.AppendRope[ rootNode, annotationNode, IO.PutFR["<>"]; NodeProps.PutProp[annotationNode, propertyAnnotationAtom, trueRope]; NodeProps.PutProp[annotationNode, commentAtom, NodeProps.true]; }; AnnotateProps: NodeProps.MapPropsAction = { nodeRope: Rope.ROPE _ Rope.Cat[", ", Atom.GetPName[name], ": ", NodeProps.GetSpecs[name, value]]; [] _ TextEdit.AppendRope[rootNode, annotationNode, nodeRope]; RETURN[FALSE]}; next: TextNode.Ref; level, levelDelta: INTEGER _ 1; IF AnAnnotationNode[TextNode.FirstChild[rootNode]] THEN RETURN; CreateRootAnnotationNode[]; [next, levelDelta] _ TextNode.Forward[TextNode.FirstChild[rootNode]]; WHILE next#NIL DO level _ level+levelDelta; CreateAnnotationNode[next, level]; [next, levelDelta] _ TextNode.Forward[next]; ENDLOOP; }; PruneAnnotationNodes: PROCEDURE [rootNode: TextNode.Ref] = { next, prev: TextNode.Ref; [next, ] _ TextNode.Forward[rootNode]; WHILE next#NIL DO IF AnAnnotationNode[next] THEN { prev _ next; [next, ] _ TextNode.Forward[next]; EditSpan.Delete[ root: rootNode, del: TextNode.MakeNodeSpan[prev, prev], saveForPaste: FALSE ! EditSpan.CannotDoEdit => CONTINUE]} ELSE [next, ] _ TextNode.Forward[next]; ENDLOOP; }; AnAnnotationNode: PROC [node: TextNode.Ref] RETURNS[BOOLEAN] = { propValue: REF; IF node#NIL THEN IF (propValue _ NodeProps.GetProp[node, propertyAnnotationAtom])#NIL THEN IF Rope.Equal[trueRope, NodeProps.GetSpecs[propertyAnnotationAtom, propValue]] THEN RETURN[TRUE]; RETURN[FALSE]; }; TiogaPropsButton: Buttons.ButtonProc ~ { viewer: ViewerClasses.Viewer ~ InputFocus.GetInputFocus[].owner; rootNode: TextNode.Ref; IF viewer = NIL THEN { MessageWindow.Append[message: "Please select a viewer first.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN; }; IF viewer.class.flavor # $Text THEN { MessageWindow.Append[message: "Selected viewer is not a Tioga viewer.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN; }; TiogaOps.CancelSelection[primary]; TRUSTED { rootNode _ LOOPHOLE[TiogaOps.ViewerDoc[viewer]] }; TRUSTED { TiogaOps.Lock[LOOPHOLE[rootNode]]; }; IF mouseButton = red THEN AddAnnotationNodes[rootNode] ELSE PruneAnnotationNodes[rootNode]; TRUSTED { TiogaOps.Unlock[LOOPHOLE[rootNode]]; }; TRUSTED { TiogaOps.Jump[viewer, [LOOPHOLE[rootNode], 0]]; }; }; Commander.Register[ "AnnotateProperties", DoAnnotations, "Annotate a Tioga document by inserting nodes identifying properties and styles of each node", $Annotate]; Commander.Register[ "PruneAnnotations", DoAnnotations, "Prune the nodes created by the AnnotateProperties command", $Prune]; [] _ Buttons.Create[ info: [name: "TiogaProps"], proc: TiogaPropsButton, documentation: "Annotate a Tioga viewer; right-click to remove annotations"]; }. dAnnotateProperties.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Beach, May 1982 Paxton July 9, 1982 1:52 pm McGregor September 10, 1982 2:18 pm Maxwell, January 14, 1983 8:44 am Plass, April 21, 1983 10:59 am Russ Atkinson, September 29, 1983 11:51 am Last Edited by: Beach, October 24, 1984 8:20:16 pm PDT [cmd: Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL] Edited on October 24, 1984 7:38:46 pm PDT, by Beach Added locking to prevent Tioga disasters if someone messed with the document, like trying to scroll it! CreateAnnotationNode (local of AddAnnotationNodes) correctly sets the nesting level of created annotation nodes Edited on October 24, 1984 8:18:38 pm PDT, by Beach Cancelled the selection to avoid PruneAnnotations deleting the node that was selected and hence wedging the selection machinery after the scroll. Ê瘚Ïc™Jšœ Ïmœ1™˜MJšœŸœ˜$JšœŸœ˜ JšœŸœŸœ˜-Jšœ Ÿœ˜Jšœ Ÿœ>˜LJšœ Ÿœ2˜@JšœŸœ ˜J˜—šœŸ ˜"šŸ˜JšœŸœ#ŸœY˜—J˜Jšœ Ÿœ ˜JšœŸœ˜3JšœŸœ ˜J˜—šÏn œ˜(Jšœ?™?Jšœ ŸœŸœ ˜JšœŸœ˜Jš œŸœŸœŸœŸœ˜7Jšœ Ÿœ'˜5J˜šŸœ$˜'šœ Ÿœ˜,JšœŸœŸœŸœ ˜6—JšŸœŸœŸœ˜šŸœŸœ˜8J˜!—šœŸ˜šŸœ ˜ J˜J˜!Jšœ˜J˜JšŸœ˜—Jšœ˜J˜%Jšœ˜J˜—JšŸœŸœ˜/šŸœ ˜ JšŸœ˜!JšŸœ ˜$—J˜'JšŸœŸœ˜1JšŸœ˜—J˜J˜—š œŸ œ˜:Jšœ$ ˜%š œŸ œ˜'J˜DJ˜AJ˜1J˜9J˜DJ˜?J˜—š œŸ œ!Ÿœ˜LJ˜TšŸœ:Ÿœ˜Bšœ˜Jšœ˜Jšœ;˜;Jšœ@˜@——šœ˜Jšœ ˜ Jšœ˜JšŸœ-˜/—J˜1J˜9J˜DJ˜?J˜—š  œ˜+JšœŸœN˜aJ˜=JšŸœŸœ˜—J˜JšœŸœ˜JšŸœ1ŸœŸœ˜?Jšœ˜J˜EšŸœŸœŸ˜J˜Jšœ"˜"J˜,JšŸœ˜—J˜J˜—š œŸ œ˜