TextNode.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
written by Bill Paxton. December 1980
last written by Paxton. December 21, 1982 9:46 am
Last Edited by: Maxwell, January 5, 1983 12:37 pm
Rick Beach, March 27, 1985 1:08:21 pm PST
Michael Plass, March 26, 1985 12:18:42 pm PST
Doug Wyatt, March 2, 1985 3:27:50 pm PST
DIRECTORY
Rope USING [ROPE],
TextLooks USING [Runs];
TextNode: CEDAR DEFINITIONS
= BEGIN
Offset: TYPE = INT ← 0;
MaxLen: INT = LAST[INT];
ROPE: TYPE = Rope.ROPE;
Ref: TYPE = REF Body;
RefTextNode: TYPE = Ref; -- a synonym for backwards compatibility.
Body: TYPE = RECORD [
next: Ref, -- points to next sibling, or if last=true, to parent
child: Ref, -- points to first child, if any, of this node
props: NodeProps, -- points to node property list
formatName: ATOMNIL, -- name of format for the node
last: BOOLFALSE, -- true if this is last sibling
hasstyledef: BOOLFALSE, -- true if node has StyleDef prop (accelerator)
hasprefix: BOOLFALSE, -- true if node has Prefix prop (accelerator)
haspostfix: BOOLFALSE, -- true if node has Postfix prop (accelerator)
hascharprops: BOOLFALSE, -- true if node has CharProps prop (accelerator)
hascharsets: BOOLFALSE, -- true if node has CharSets prop (accelerator)
hasartwork: BOOLFALSE, -- true if node has Artwork prop (accelerator)
deleted: BOOLFALSE, -- true if has been deleted or is root pending delete
dirty: BOOLFALSE, -- true if has been edited (contents, or children moved, inserted, ...)
new: BOOLFALSE, -- true if created during this editing session (i.e., not from file)
comment: BOOLFALSE, -- true if node is a comment
count: [0..countMax] ← 0, -- incremented by text edit routines
rope: ROPE,
runs: TextLooks.Runs
];
Location: TYPE = RECORD [node: Ref, where: INT];
where >= length of text means at end
where = loc in [0..length) means before that character
e.g., where = 0 means at start of text
where = NodeItself means location is the node itself rather than in its contents
NodeItself: INT = -1;
nullLocation: Location = [node: NIL, where: NodeItself];
MakeNodeLoc: PROC [n: Ref] RETURNS [Location];
Span: TYPE = RECORD [start, end: Location ← nullLocation];
start.node can equal end.node
in which case either both start.where and end.where = NodeItself, or
neither do and start.where <= end.where
otherwise, end.node should follow start.node in the tree
nodes need not be siblings
no restrictions on start.where or end.where
nullSpan: Span = [nullLocation,nullLocation];
MakeNodeSpan: PROC [first, last: Ref] RETURNS [Span];
countMax: NAT = 31; -- 5 bits for count
OfNode: TYPE = {text, other};
NodeList: TYPE = REF NodeListBody;
NodeListBody: TYPE = RECORD [node: Ref, next: NodeList];
NodeProps: TYPE = REF NodePropsBody;
NodePropsBody: TYPE; -- exported by NodePropsImpl
NewTextNode: PROC RETURNS [txt: RefTextNode];
NarrowToTextNode: PROC [n: Ref] RETURNS [txt: RefTextNode];
For backwards compatability.
Parent: PROC [n: Ref] RETURNS [Ref];
Root: PROC [n: Ref] RETURNS [Ref];
Next: PROC [n: Ref] RETURNS [Ref];
returns next sibling of n
returns NIL if n is last sibling
Previous: PROC [n: Ref, parent: Ref ← NIL] RETURNS [nx: Ref];
returns previous sibling of n
returns NIL if n is first sibling
runs faster if can supply parent
Forward: PROC [node: Ref] RETURNS [nx: Ref, levelDelta: INTEGER];
returns next node in standard tree walk order
levelDelta is level(node)-level(nx), where level is depth in tree
levelDelta = 0 if nx and node are siblings
levelDelta = 1 if nx is child of node
levelDelta < 0 if do Parent* and Next to reach nx from node
Backward: PROC [node: Ref, parent: Ref ← NIL]
RETURNS [back, backparent: Ref, levelDelta: INTEGER];
for backing through tree
runs faster if can supply parent
levelDelta same as for Forward
StepForward: PROC [node: Ref] RETURNS [Ref];
returns next node in standard tree walk order
StepBackward: PROC [node: Ref, parent: Ref ← NIL] RETURNS [Ref];
returns preceding node in standard tree walk order
Level: PROC [node: Ref] RETURNS [level: INTEGER];
Level[Root[x]] == 0; Level[FirstChild[n]]=Level[n]+1
ForwardClipped: PROC [node: Ref, maxLevel: INTEGER, nodeLevel: INTEGER ← 0] RETURNS [nx: Ref, nxLevel: INTEGER];
like Forward, but limits how deep will go in tree
if pass nodeLevel=0, correct value will be computed
nxLevel = Level[nx] <= MAX[maxLevel,Level[node]]
BackwardClipped: PROC [node: Ref, maxLevel: INTEGER, parent: Ref ← NIL,
nodeLevel: INTEGER ← 0] RETURNS [back, backparent: Ref, backLevel: INTEGER];
like Backward, but limits how deep will go in tree
backLevel = Level[back] <= MAX[maxLevel,Level[node]]
LocRelative: PROC [location: Location, count: INT,
break: NAT ← 1, skipCommentNodes: BOOLFALSE] RETURNS [Location];
count is interpreted as a character offset from given location
returns <node,offset> location corresponding to count
adds in break at the end of each text subnode
if skipCommentNodes is true, then ignores them in walking the tree
LocWithin: PROC [n: Ref, count: INT, break: NAT ← 1, skipCommentNodes: BOOLFALSE] RETURNS [Location];
LocOffset: PROC [loc1, loc2: Location, break: NAT ← 1, skipCommentNodes: BOOLFALSE] RETURNS [count: INT];
returns character offset of location2 relative to location1
loc1 and loc2 can be in same node
but loc2 must not be in node before loc1 or get ERROR BadArgs
if skipCommentNodes is true, then ignores them in walking the tree
BadArgs: ERROR;
LocNumber: PROC [at: Location, break: NAT ← 1, skipCommentNodes: BOOLFALSE] RETURNS [count: INT];
returns character offset of location relative to root
FirstSibling: PROC [n: Ref] RETURNS [Ref];
LastSibling: PROC [n: Ref] RETURNS [Ref];
LastWithin: PROC [n: Ref] RETURNS [Ref];
returns the last node within the branch
i.e., goes to last child of last child of last child ... until no child
LastLocWithin: PROC [n: Ref] RETURNS [Location];
returns the last location within the branch
FirstChild: PROC [n: Ref] RETURNS [Ref];
LastChild: PROC [n: Ref] RETURNS [Ref];
NthChild: PROC [n: Ref, location: INT ← 0] RETURNS [child: Ref];
NthSibling: PROC [n: Ref, cnt: INT ← 0] RETURNS [Ref];
CountChildren: PROC [n: Ref] RETURNS [count: INT];
CountFollowing: PROC [n: Ref] RETURNS [count: INT];
CountToParent: PROC [n: Ref] RETURNS [count: INT, parent: Ref];
CountToChild: PROC [parent, child: Ref] RETURNS [count: INT];
NodeRope: PROC [n: RefTextNode] RETURNS [ROPE];
NodeRuns: PROC [n: RefTextNode] RETURNS [TextLooks.Runs];
Props: PROC [n: Ref] RETURNS [NodeProps];
NodeFormat: PROC [n: Ref] RETURNS [ATOM];
IsLastSibling: PROC [n: Ref] RETURNS [BOOL];
EndPos: PROC [n: Ref] RETURNS [INT];
END.