-- AnnotateProperties.mesa
-- written by Beach, May 1982
-- last written by Paxton July 9, 1982 1:52 pm
DIRECTORY
Atom USING [GetPName],
CIFS USING [Error],
EditSpan USING [CannotDoEdit, Delete, InsertTextNode],
IO,
NodeProps USING [GetProp, GetSpecs, MapProps, MapPropsAction, PutProp, true],
PutGet USING [FromFile, ToFile],
Rope USING [Cat, Equal, Find, ROPE, Size],
TextEdit USING [AppendRope],
TextNode USING [FirstChild, Forward, MakeNodeSpan, Ref, RefTextNode],
UserExec USING [CommandProc, ExecHandle, RegisterCommand],
WindowManager USING [UnWaitCursor, WaitCursor];
AnnotateProperties: PROGRAM
IMPORTS Atom, CIFS, EditSpan, IO, NodeProps, PutGet, Rope, TextEdit, TextNode, UserExec, WindowManager = {
rootNode: TextNode.Ref;
annotationNode: TextNode.RefTextNode;
commentAtom: ATOM = $Comment;
propertyAnnotationAtom: ATOM = $PropertyAnnotation;
trueRope: Rope.ROPE = "TRUE";
AnnotatePropertiesCommand: UserExec.CommandProc = TRUSTED {
RETURN[DoAnnotations[exec, TRUE]] };
PruneAnnotationsCommand: UserExec.CommandProc = TRUSTED {
RETURN[DoAnnotations[exec, FALSE]] };
DoAnnotations: PROC [exec: UserExec.ExecHandle, annotate: BOOLEAN ← TRUE]
RETURNS[ok: BOOLEAN ← TRUE] = {
ENABLE UNWIND => WindowManager.UnWaitCursor[];
filename: Rope.ROPE;
tabIndent: NAT ← 8;
WindowManager.WaitCursor[];
DO -- process each file in command line
filename ← IO.GetRope[exec.commandLineStream];
IF Rope.Size[filename]=0 THEN EXIT;
IF Rope.Find[filename,"."] = -1 THEN -- add .mesa extension
filename ← Rope.Cat[filename,".mesa"];
{ ENABLE CIFS.Error => {
exec.out.PutRope[filename];
exec.out.PutRope[" not found.\n"];
ok ← FALSE;
LOOP };
rootNode ← PutGet.FromFile[filename];
};
IF annotate THEN
AddAnnotationNodes[]
ELSE
PruneAnnotationNodes[];
[] ← PutGet.ToFile[filename, rootNode];
ENDLOOP;
WindowManager.UnWaitCursor[];
exec.out.PutRope[" Done."];
RETURN[ok];
};
AddAnnotationNodes: PROCEDURE = {
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 = {
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];
};
CreateRootAnnotationNode: PROCEDURE = {
annotationNode ← EditSpan.InsertTextNode[rootNode, rootNode, child];
[] ← TextEdit.AppendRope[rootNode, annotationNode, "<<RootNode"];
[] ← NodeProps.MapProps[rootNode, AnnotateProps];
[] ← 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[rootNode, thisNode, before];
[] ← TextEdit.AppendRope[rootNode, annotationNode, IO.PutFToRope["<<NodeLevel: %d", IO.int[level]]];
[] ← NodeProps.MapProps[thisNode, AnnotateProps];
[] ← TextEdit.AppendRope[rootNode, annotationNode, ">>"];
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]};
UserExec.RegisterCommand["AnnotateProperties", AnnotatePropertiesCommand, "Annotate a Tioga document by inserting nodes identifying properties and styles of each node"];
UserExec.RegisterCommand["PruneAnnotations", PruneAnnotationsCommand, "Prune the nodes created by the AnnotateProperties command"];
}.