TiogaOps2Impl.mesa
Copyright Ó 1985, 1987, 1988 by Xerox Corporation. All rights reserved.
written by Bill Paxton. June 1982
last written by Paxton. December 30, 1982 11:13 am
Last Edited by: Maxwell, January 6, 1983 11:48 am
Russ Atkinson (RRA) January 23, 1986 0:02:15 am PST
Michael Plass, October 16, 1987 5:21:07 pm PDT
Rick Beach, March 28, 1985 10:15:04 am PST
Doug Wyatt, February 18, 1988 2:22:56 pm PST
DIRECTORY
Atom USING [GetPName, MakeAtom],
EditSpan USING [CompareNodeOrder, NodeOrder],
MessageWindow USING [Append],
NodeProps USING [CopyInfoProc, GetProp, MapProps, NullCopy, NullRead, NullWrite, PutProp, ReadSpecsProc, Register, RemProp, WriteSpecsProc],
NodeStyleOps USING [StyleNameForNode],
PutGet USING [FromFile, ToFile],
Rope USING [Concat, FromChar, IsEmpty, Map, ROPE],
TEditDocument USING [Selection, SpinAndLock, TEditDocumentData, Unlock],
TEditDocumentPrivate USING [CloseAndOpenPreviousFile, DefaultMenus, DoCloseAndNewViewer, DoCloseAndOpenImplFile, DoLoadFile, DoLoadImplFile, DoNewViewer, DoOpenFile, DoOpenImplFile, DoStoreFile, EmptyViewer, JumpToPrevious, LoadPreviousFile, OpenPreviousFile, Reselect, Reset, Save],
TEditInput USING [AllLevels, CloseEvent, CommandProc, FewerLevels, FirstLevelOnly, FreeTree, MoreLevels, Normalize, Register, UnRegister],
TEditInputOps USING [CallWithLocks, DoFindPlaceholders, DoNextViewer, DoSelectMatchingBrackets],
TEditOps USING [RememberCurrentPosition],
TEditProfile USING [selectionCaret],
TEditRefresh USING [ScrollToEndOfSel],
TEditScrolling USING [ScrollToPosition],
TEditSelection USING [FindWhere, MakeSelection, Position, pSel, SetSelLooks],
TextEdit USING [ChangeLooks, FetchLooks, FetchLooksRun, FromRope, LooksRun, Size],
TextFind USING [Finder, MalformedPattern, PatternErrorCode],
TextFindPrivate USING [FinderRecord],
TextLooks USING [allLooks, Look, Looks, LooksAnd, noLooks],
TextNode USING [FirstChild, FirstSibling, LastChild, LastLocWithin, LastSibling, LastWithin, Location, Next, Node, NodeRep, NodeProps, Parent, Previous, Root, StepBackward, StepForward],
TiogaExtraOps USING [MapPropsAction],
TiogaMenuOps USING [],
TiogaOps USING [CommandProc, CommentControl, Dir, Finder, FinderRec, Pattern, PatternErrorCode, PatternRec, SearchDir, SetSelection],
TiogaOpsDefs USING [Location, Order, WhichSelection],
TreeFind USING [CommentControl, Create, CreateFromRope, Try, TryBackwards],
ViewerClasses USING [Column, Viewer];
TiogaOps2Impl: CEDAR PROGRAM
IMPORTS Atom, EditSpan, MessageWindow, NodeProps, NodeStyleOps, PutGet, Rope, TEditDocument, TEditDocumentPrivate, TEditInput, TEditInputOps, TEditOps, TEditProfile, TEditRefresh, TEditScrolling, TEditSelection, TextEdit, TextFind, TextLooks, TextNode, TiogaOps, TreeFind
EXPORTS TiogaOpsDefs, TiogaOps, TiogaMenuOps, TiogaExtraOps
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
Viewer: TYPE ~ ViewerClasses.Viewer;
Column: TYPE ~ ViewerClasses.Column;
Node: TYPE = TextNode.Node; -- points to a Tioga node
NodeBody: PUBLIC TYPE = TextNode.NodeRep; -- export opaque type
Finder: TYPE = REF FinderRec;
FinderRec: PUBLIC TYPE = TextFindPrivate.FinderRecord; -- export opaque type
MakeName: PROC [r: ROPE] RETURNS [ATOM] ~ {
RETURN [IF r.IsEmpty THEN NIL ELSE Atom.MakeAtom[r]];
};
Search
LooksRope: PROC [looks: TextLooks.Looks] RETURNS [r: ROPE] = {
FOR c: CHAR IN TextLooks.Look DO
IF looks[c] THEN r ← Rope.Concat[r, Rope.FromChar[c]];
ENDLOOP
};
RopeToLooks: PROC [r: ROPE] RETURNS [looks: TextLooks.Looks] = {
Set: PROC [c: CHAR] RETURNS [quit: BOOLFALSE] = { looks[c] ← TRUE };
[] ← Rope.Map[base: r, action: Set];
};
tiogaOpsEcFromTextFindEc: ARRAY TextFind.PatternErrorCode OF TiogaOps.PatternErrorCode ← [
toobig: toobig,
endquote: endquote,
endtilda: endtilda,
boundary: boundary,
missingNameEnd: missingNameEnd,
unmatchedNameEnd: unmatchedNameEnd
];
MalformedPattern: PUBLIC ERROR [ec: TiogaOps.PatternErrorCode] ~ CODE;
ReportMalformedPattern: PROC [textFindEc: TextFind.PatternErrorCode] ~ {
tiogaOpsEc: TiogaOps.PatternErrorCode ~ tiogaOpsEcFromTextFindEc[textFindEc];
ERROR MalformedPattern[tiogaOpsEc];
};
CreateGeneralPattern: PUBLIC PROC [
target: Node, -- node from which to get the pattern
text: BOOLTRUE, -- if true, match target text
looks: BOOLFALSE, -- if true, match target looks
format: BOOLFALSE, -- if true, match target format
style: BOOLFALSE, -- if true, match target style
comment: BOOLFALSE, -- if true, match target comment property
case: BOOLTRUE, -- if true, match case
literal: BOOLFALSE, -- if true, treat target literally rather than as a pattern
word: BOOLFALSE, -- if true, match words only
subset: BOOLTRUE, -- if true, use subset for looks test, else use equality
addBounds: BOOLFALSE] -- if true, add |'s to both ends of pattern
RETURNS [pattern: TiogaOps.Pattern] = {
error: BOOLFALSE;
errorCode: TextFind.PatternErrorCode;
txt: Node = target;
patternTxt: Node ← txt;
pattern ← NEW[TiogaOps.PatternRec];
IF looks AND ~text THEN { -- make a phony search pattern and get the looks
size: INT = TextEdit.Size[txt];
lks: TextLooks.Looks = IF size=0 THEN TextLooks.noLooks ELSE TextEdit.FetchLooks[txt,0];
pattern.searchLooks ← LooksRope[lks];
FOR i: INT IN [1..size) DO
IF TextEdit.FetchLooks[txt,i]#lks THEN {
MessageWindow.Append["Search pattern does not have uniform looks.",TRUE];
MessageWindow.Append[" Using looks from first char."];
EXIT
};
ENDLOOP;
literal ← FALSE;
patternTxt ← TextEdit.FromRope["#*"];
TextEdit.ChangeLooks[root: NIL, node: patternTxt, remove: TextLooks.allLooks, add: lks];
};
pattern.text ← text;
pattern.looks ← looks;
pattern.word ← word;
pattern.looksExact ← ~subset;
pattern.commentControl ← IF ~comment OR txt=NIL THEN includeComments
ELSE IF txt.comment THEN commentsOnly ELSE excludeComments;
pattern.checkFormat ← format;
pattern.format ← IF target=NIL OR target.formatName=NIL THEN NIL ELSE
Atom.GetPName[target.formatName];
pattern.checkStyle ← style;
pattern.style ← IF ~style THEN NIL ELSE Atom.GetPName[NodeStyleOps.StyleNameForNode[target]];
IF text OR looks THEN { -- create a description of the pattern
pattern.finder ← TreeFind.Create[patternTxt, literal, word, ~looks, ~case, addBounds !
TextFind.MalformedPattern => { errorCode ← ec; error ← TRUE; CONTINUE }];
};
IF error THEN ReportMalformedPattern[errorCode];
};
CreateSimplePattern: PUBLIC PROC [
target: ROPE, -- node from which to get the pattern
case: BOOLTRUE, -- if true, match case
literal: BOOLFALSE, -- if true, treat target literally rather than as a pattern
word: BOOLFALSE, -- if true, match words only
addBounds: BOOLFALSE] -- if true, add |'s to both ends of pattern
RETURNS [pattern: TiogaOps.Pattern] = {
error: BOOLFALSE;
errorCode: TextFind.PatternErrorCode;
pattern ← NEW[TiogaOps.PatternRec];
pattern.text ← TRUE;
pattern.looks ← FALSE;
pattern.word ← word;
pattern.commentControl ← includeComments;
pattern.checkFormat ← FALSE;
pattern.format ← NIL;
pattern.checkStyle ← FALSE;
pattern.style ← NIL;
pattern.finder ← TreeFind.CreateFromRope[target, literal, word, ~case, addBounds !
TextFind.MalformedPattern => { errorCode ← ec; error ← TRUE; CONTINUE }];
IF error THEN ReportMalformedPattern[errorCode];
};
FindCC: PROC [cc: TiogaOps.CommentControl] RETURNS [TreeFind.CommentControl] = {
RETURN [SELECT cc FROM
includeComments => includeComments,
excludeComments => excludeComments,
commentsOnly => commentsOnly,
ENDCASE => ERROR]
};
SelectionSearch: PUBLIC PROC [
pattern: TiogaOps.Pattern, whichDir: TiogaOps.SearchDir ← forwards, interrupt: REF BOOLNIL,
startBoundaryNode, endBoundaryNode: Node ← NIL,
startBoundaryOffset: INT ← 0, endBoundaryOffset: INTLAST[INT]]
RETURNS [found: BOOL] = {
pSel: TEditDocument.Selection = TEditSelection.pSel;
Found: PROC [tSel: TEditDocument.Selection] = {
tSel.viewer ← pSel.viewer;
tSel.data ← pSel.data;
TEditOps.RememberCurrentPosition[pSel.viewer];
TEditSelection.SetSelLooks[tSel];
TEditSelection.MakeSelection[new: tSel];
TEditInput.CloseEvent[];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, FALSE]
};
Locations: PROC RETURNS [start, end: TextNode.Location] = {
start ← pSel.start.pos; end ← pSel.end.pos
};
found ← DoSearch[pattern, whichDir, interrupt, Found, Locations,
startBoundaryNode, endBoundaryNode,
startBoundaryOffset, endBoundaryOffset]
};
DocLoc: PROC [loc: TiogaOpsDefs.Location] RETURNS [TextNode.Location] = {
RETURN [[loc.node, loc.where]]
};
MyLoc: PROC [loc: TextNode.Location] RETURNS [TiogaOpsDefs.Location] = {
RETURN [[loc.node, loc.where]]
};
NodeSearch: PUBLIC PROC [
pattern: TiogaOps.Pattern, whichDir: TiogaOps.SearchDir ← forwards,
startLoc, endLoc: TiogaOpsDefs.Location, interrupt: REF BOOLNIL,
startBoundaryNode, endBoundaryNode: Node ← NIL,
startBoundaryOffset: INT ← 0, endBoundaryOffset: INTLAST[INT]]
RETURNS [found: BOOL, start, end: TiogaOpsDefs.Location] = {
Found: PROC [tSel: TEditDocument.Selection] = {
start ← MyLoc[tSel.start.pos]; end ← MyLoc[tSel.end.pos]
};
Locations: PROC RETURNS [start, end: TextNode.Location] = {
start ← DocLoc[startLoc]; end ← DocLoc[endLoc]
};
found ← DoSearch[pattern, whichDir, interrupt, Found, Locations,
startBoundaryNode, endBoundaryNode,
startBoundaryOffset, endBoundaryOffset]
};
DoSearch: PROC [
pattern: TiogaOps.Pattern, whichDir: TiogaOps.SearchDir ← forwards, interrupt: REF BOOLNIL,
foundProc: PROC [tSel: TEditDocument.Selection],
locationProc: PROC RETURNS [start, end: TextNode.Location],
startBoundaryNode, endBoundaryNode: Node ← NIL,
startBoundaryOffset: INT ← 0, endBoundaryOffset: INTLAST[INT]]
RETURNS [found: BOOL] = {
at, atEnd, offset: INT;
first: Node;
where: Node;
startLoc, endLoc: TextNode.Location;
DoLookForPattern: PROC [root: Node, tSel: TEditDocument.Selection] = {
Forwards: PROC = {
IF (offset ← endLoc.where+1) >=
TextEdit.Size[first ← endLoc.node] THEN {
first ← TextNode.StepForward[first]; offset ← 0
};
[found,where,at,atEnd,,] ←
TreeFind.Try[finder: pattern.finder, first: first, start: offset,
last: endBoundaryNode, lastLen: endBoundaryOffset,
interrupt: interrupt,
looksExact: pattern.looksExact,
checkFormat: pattern.checkFormat,
format: MakeName[pattern.format],
commentControl: FindCC[pattern.commentControl],
checkStyle: pattern.checkStyle,
style: MakeName[pattern.style],
styleProc: NodeStyleOps.StyleNameForNode]
};
Backwards: PROC = {
IF (offset ← startLoc.where)=0 THEN {
first ← TextNode.StepBackward[startLoc.node];
offset ← LAST[INT]
}
ELSE first ← startLoc.node;
[found,where,at,atEnd,,] ←
TreeFind.TryBackwards[finder: pattern.finder,
first: first, len: offset,
last: startBoundaryNode, lastStart: startBoundaryOffset,
interrupt: interrupt,
looksExact: pattern.looksExact,
checkFormat: pattern.checkFormat,
format: MakeName[pattern.format],
commentControl: FindCC[pattern.commentControl],
checkStyle: pattern.checkStyle,
style: MakeName[pattern.style],
styleProc: NodeStyleOps.StyleNameForNode]
};
[startLoc, endLoc] ← locationProc[];
IF interrupt#NIL THEN interrupt^ ← FALSE;
SELECT whichDir FROM
forwards => Forwards[];
backwards => Backwards[];
anywhere => {
Forwards[];
IF found THEN whichDir ← forwards ELSE {
whichDir ← backwards; Backwards[]
}
};
ENDCASE => ERROR;
IF ~found OR where=NIL THEN RETURN;
IF pattern.looks AND ~pattern.text AND ~pattern.word THEN
[at,atEnd] ← Extend[whichDir=forwards,
pattern.looksExact, RopeToLooks[pattern.searchLooks], where, at, atEnd];
tSel.start.pos ← [where,at];
tSel.end.pos ← [where,MAX[0,atEnd-1]];
tSel.granularity ←
IF ~pattern.looks AND ~pattern.text THEN node
ELSE IF pattern.word THEN word ELSE char;
tSel.insertion ← IF TEditProfile.selectionCaret=before THEN before ELSE after;
foundProc[tSel];
};
TEditInputOps.CallWithLocks[DoLookForPattern, read]
};
Extend: PROC [forward, looksExact: BOOL, searchLooks: TextLooks.Looks,
where: Node, at, atEnd: INT, last: Node ← NIL, lastLen: INTLAST[INT]
] RETURNS [newAt, newAtEnd: INT] = {
IF forward THEN { -- extend toward end of node
size: INT ~ TextEdit.Size[where];
end: INT ~ IF where=last THEN MIN[size, lastLen] ELSE size;
WHILE atEnd<end DO
looksRun: TextEdit.LooksRun ~ TextEdit.FetchLooksRun[where, atEnd];
looks: TextLooks.Looks ~ IF looksExact
THEN looksRun.looks
ELSE TextLooks.LooksAnd[looksRun.looks, searchLooks];
IF looks=searchLooks THEN atEnd ← MIN[looksRun.end, end] ELSE EXIT;
ENDLOOP;
}
ELSE { -- extend backward
WHILE at>0 DO
looksRun: TextEdit.LooksRun ~ TextEdit.FetchLooksRun[where, at-1];
looks: TextLooks.Looks ~ IF looksExact
THEN looksRun.looks
ELSE TextLooks.LooksAnd[looksRun.looks, searchLooks];
IF looks=searchLooks THEN at ← looksRun.start ELSE EXIT;
ENDLOOP;
};
RETURN[at, atEnd];
};
SelectMatchingBrackets: PUBLIC PROC [before, after: CHAR] RETURNS [found: BOOL] = {
found ← TEditInputOps.DoSelectMatchingBrackets[before, after]
};
NextPlaceholder: PUBLIC PROC [dir: TiogaOps.Dir ← forward, gotoend: BOOL,
startBoundaryNode, endBoundaryNode: Node ← NIL,
startBoundaryOffset: INT ← 0, endBoundaryOffset: INTLAST[INT]]
RETURNS [found, wenttoend: BOOL] = {
[found, wenttoend] ← TEditInputOps.DoFindPlaceholders[
dir=forward, gotoend,
startBoundaryNode, endBoundaryNode,
startBoundaryOffset, endBoundaryOffset]
};
NextViewer: PUBLIC PROC [dir: TiogaOps.Dir ← forward] RETURNS [found: BOOL] = {
found ← TEditInputOps.DoNextViewer[dir=forward]
};
SearchWhere: PROC [whichDir: TiogaOps.SearchDir] RETURNS [TEditSelection.FindWhere] = INLINE {
RETURN [SELECT whichDir FROM
forwards => forwards,
backwards => backwards,
anywhere => anywhere,
ENDCASE => ERROR]
};
Places menu commands
Position: PUBLIC PROC [viewer: Viewer] = {
TEditSelection.Position[viewer];
};
Normalize: PUBLIC PROC [viewer: Viewer] = {
[] ← TEditInput.Normalize[viewer];
};
PrevPlace: PUBLIC PROC [viewer: Viewer] = {
TEditDocumentPrivate.JumpToPrevious[viewer];
};
Reselect: PUBLIC PROC [viewer: Viewer] = {
TEditDocumentPrivate.Reselect[viewer];
};
Files and text viewers
Save: PUBLIC PROC [viewer: Viewer] = {
TEditDocumentPrivate.Save[viewer];
};
Load: PUBLIC PROC [viewer: Viewer, fileName: ROPENIL,
fileNameProcViewer: Viewer ← NIL] = {
[] ← TEditDocumentPrivate.DoLoadFile[viewer, fileName, FALSE, fileNameProcViewer];
};
Open: PUBLIC PROC [fileName: ROPENIL, fileNameProcViewer: Viewer ← NIL, column: Column ← left] RETURNS [Viewer] = {
RETURN [TEditDocumentPrivate.DoOpenFile[fileName, column, fileNameProcViewer]];
};
CloseAndOpen: PUBLIC PROC [viewer: Viewer, fileName: ROPENIL, fileNameProcViewer: Viewer ← NIL] RETURNS [Viewer] = {
RETURN [TEditDocumentPrivate.DoLoadFile[viewer, fileName, TRUE, fileNameProcViewer]];
};
LoadImpl: PUBLIC PROC [viewer: Viewer, fileName: ROPENIL] = {
[] ← TEditDocumentPrivate.DoLoadImplFile[viewer, fileName];
};
OpenImpl: PUBLIC PROC [fileName: ROPENIL, column: Column ← left] RETURNS [Viewer] = {
RETURN [TEditDocumentPrivate.DoOpenImplFile[fileName, column]];
};
CloseAndOpenImpl: PUBLIC PROC [viewer: Viewer, fileName: ROPENIL] RETURNS [Viewer] = {
RETURN [TEditDocumentPrivate.DoCloseAndOpenImplFile[viewer, fileName]];
};
LoadPreviousFile: PUBLIC PROC [parent: Viewer] = {
TEditDocumentPrivate.LoadPreviousFile[parent];
};
OpenPreviousFile: PUBLIC PROC [parent: Viewer] = {
TEditDocumentPrivate.OpenPreviousFile[parent];
};
CloseAndOpenPreviousFile: PUBLIC PROC [parent: Viewer] = {
TEditDocumentPrivate.CloseAndOpenPreviousFile[parent];
};
DefaultMenus: PUBLIC PROC [viewer: Viewer, paint: BOOLFALSE] = {
TEditDocumentPrivate.DefaultMenus[viewer, paint];
};
Store: PUBLIC PROC [viewer: Viewer, fileName: ROPENIL] = {
TEditDocumentPrivate.DoStoreFile[viewer, fileName];
};
New: PUBLIC PROC [column: Column ← left] RETURNS [Viewer] = {
RETURN [TEditDocumentPrivate.DoNewViewer[column]];
};
Empty: PUBLIC PROC [viewer: Viewer] = {
TEditDocumentPrivate.EmptyViewer[viewer];
};
CloseAndNewViewer: PUBLIC PROC [viewer: Viewer] RETURNS [Viewer] = {
RETURN [TEditDocumentPrivate.DoCloseAndNewViewer[viewer]];
};
Reset: PUBLIC PROC [viewer: Viewer] = {
TEditDocumentPrivate.Reset[viewer];
};
Jump: PUBLIC PROC [viewer: Viewer, loc: TiogaOpsDefs.Location] = {
[] ← TEditScrolling.ScrollToPosition[viewer, [loc.node, loc.where]];
};
Levels menu commands
FirstLevelOnly: PUBLIC PROC [viewer: Viewer] = { [] ← TEditInput.FirstLevelOnly[viewer] };
MoreLevels: PUBLIC PROC [viewer: Viewer] = { [] ← TEditInput.MoreLevels[viewer] };
FewerLevels: PUBLIC PROC [viewer: Viewer] = { [] ← TEditInput.FewerLevels[viewer] };
AllLevels: PUBLIC PROC [viewer: Viewer] = { [] ← TEditInput.AllLevels[viewer] };
TiogaExtraOps Implementation
Miscellaneous operations on nodes
GetRope: PUBLIC PROC [node: Node] RETURNS [ROPE] = {
RETURN [IF node=NIL THEN NIL ELSE node.rope]
};
Parent: PUBLIC PROC [node: Node] RETURNS [Node] = { RETURN [TextNode.Parent[node]] };
Root: PUBLIC PROC [node: Node] RETURNS [Node] = { RETURN [TextNode.Root[node]] };
Next: PUBLIC PROC [node: Node] RETURNS [Node] = { RETURN [TextNode.Next[node]] };
Previous: PUBLIC PROC [node: Node, parent: Node ← NIL] RETURNS [nx: Node] = { RETURN [TextNode.Previous[node]] };
StepForward: PUBLIC PROC [node: Node] RETURNS [nx: Node] = { RETURN [TextNode.StepForward[node]] };
StepBackward: PUBLIC PROC [node: Node, parent: Node ← NIL] RETURNS [back: Node] = { RETURN [TextNode.StepBackward[node, parent]] };
FirstSibling: PUBLIC PROC [node: Node] RETURNS [Node] = { RETURN [TextNode.FirstSibling[node]] };
LastSibling: PUBLIC PROC [node: Node] RETURNS [Node] = { RETURN [TextNode.LastSibling[node]] };
LastWithin: PUBLIC PROC [node: Node] RETURNS [Node] = { RETURN [TextNode.LastWithin[node]] };
LastLocWithin: PUBLIC PROC [node: Node] RETURNS [TiogaOpsDefs.Location] = {
loc: TextNode.Location ~ TextNode.LastLocWithin[node];
RETURN [[loc.node, loc.where]];
};
FirstChild: PUBLIC PROC [node: Node] RETURNS [Node] = { RETURN [TextNode.FirstChild[node]] };
LastChild: PUBLIC PROC [node: Node] RETURNS [Node] = { RETURN [TextNode.LastChild[node]] };
IsDirty: PUBLIC PROC [node: Node] RETURNS [BOOL] = { RETURN [node.dirty] };
IsNew: PUBLIC PROC [node: Node] RETURNS [BOOL] = { RETURN [node.new] };
ClearDirty: PUBLIC PROC [node: Node] = { node.dirty ← FALSE };
ClearNew: PUBLIC PROC [node: Node] = { node.new ← FALSE };
ViewerDoc: PUBLIC PROC [viewer: Viewer] RETURNS [root: Node] = {
tdd: TEditDocument.TEditDocumentData = NARROW[viewer.data];
IF tdd = NIL THEN RETURN [NIL];
[] ← TEditDocument.SpinAndLock[tdd, "ViewerDoc"]; -- make sure nothing else going on
root ← tdd.text;
TEditDocument.Unlock[tdd]
};
Node Property Lists
PutProp: PUBLIC PROC [n: Node, name: ATOM, value: REF] = {
NodeProps.PutProp[n, name, value]
};
GetProp: PUBLIC PROC [n: Node, name: ATOM] RETURNS [REF] = {
RETURN [NodeProps.GetProp[n, name]]
};
RemProp: PUBLIC PROC [n: Node, name: ATOM] = {
NodeProps.RemProp[n, name]
};
MapProps: PUBLIC PROC [n: Node, action: TiogaExtraOps.MapPropsAction, formatFlag, commentFlag: BOOLTRUE] RETURNS [BOOL] = {
RETURN [NodeProps.MapProps[n, action, formatFlag, commentFlag]]
};
read, write, copy props
RegisterPropProc: PUBLIC PROC [name: ATOM,
reader: NodeProps.ReadSpecsProc, writer: NodeProps.WriteSpecsProc, copier: NodeProps.CopyInfoProc] = {
NodeProps.Register[name, reader, writer, copier];
};
NullRead: PUBLIC NodeProps.ReadSpecsProc = { [] ← NodeProps.NullRead[name, specs] };
NullWrite: PUBLIC NodeProps.WriteSpecsProc = { [] ← NodeProps.NullWrite[name, value] };
NullCopy: PUBLIC NodeProps.CopyInfoProc = { [] ← NodeProps.NullCopy[name, value] };
Comparing order of nodes or locations in document
NodeOrder: PROC [order: EditSpan.NodeOrder] RETURNS [TiogaOpsDefs.Order] = {
RETURN [SELECT order FROM before => before, same => same, after => after, disjoint => disjoint, ENDCASE => ERROR] };
CompareLocOrder: PUBLIC PROC [loc1, loc2: TiogaOpsDefs.Location] RETURNS [order: TiogaOpsDefs.Order] = {
order ← NodeOrder[EditSpan.CompareNodeOrder[loc1.node, loc2.node]];
IF order=same THEN order ← SELECT loc1.where FROM
< loc2.where => before,
= loc2.where => same,
ENDCASE => after };
CompareNodeOrder: PUBLIC PROC [node1, node2: Node] RETURNS [order: TiogaOpsDefs.Order] = {
RETURN [NodeOrder[EditSpan.CompareNodeOrder[node1, node2]]] };
File I/O
GetFile: PUBLIC PROC [name: ROPE] RETURNS [root: Node] = {
RETURN [PutGet.FromFile[name]] };
PutFile: PUBLIC PROC [name: ROPE, root: Node] = { [] ← PutGet.ToFile[name, root] };
FreeTree: PUBLIC PROC [root: Node] = { TEditInput.FreeTree[root] };
Make point selection
SelectPoint: PUBLIC PROC [viewer: Viewer, caret: TiogaOpsDefs.Location, which: TiogaOpsDefs.WhichSelection ← primary] = {
TiogaOps.SetSelection[viewer: viewer, start: caret, end: caret, level: point, which: which];
};
Command registration
RegisterCommand: PUBLIC PROC [name: ATOM, proc: TiogaOps.CommandProc, before: BOOLTRUE] = {
TEditInput.Register[name, proc, before]
};
UnRegisterCommand: PUBLIC PROC [name: ATOM, proc: TiogaOps.CommandProc] = {
TEditInput.UnRegister[name, proc]
};
END.