Defined elsewhere
CharSet: TYPE ~ ImagerFont.BYTE;
XChar: TYPE ~ ImagerFont.XChar;
ROPE: TYPE ~ Rope.ROPE;
ROSARY: TYPE ~ Rosary.ROSARY;
Runs: TYPE ~ TextLooks.Runs;
Looks: TYPE ~ TextLooks.Looks;
noLooks: Looks ~ TextLooks.noLooks;
allLooks: Looks ~ TextLooks.allLooks;
Node
Node: TYPE ~ REF NodeRep;
NodeRep:
TYPE ~
RECORD [
-- 4 words
children: ROSARY --OF Node--,
text: Text
];
Text: TYPE ~ REF TextRep;
TextRep:
TYPE ~
RECORD [
-- 10 words
rope: ROPE,
runs: Runs,
charSets: ROSARY --OF REF CharSet--,
charProps: ROSARY --OF PropList--,
props: Props
];
Props: TYPE ~ REF PropsRep;
PropsRep:
TYPE ~
RECORD [
-- 5 words
propList: PropList,
formatName: ATOM ← NIL, -- name of format for the node
comment: BOOL ← FALSE, -- true if node is a comment
hasStyleDef: BOOL ← FALSE, -- true if node has StyleDef prop (accelerator)
hasPrefix: BOOL ← FALSE, -- true if node has Prefix prop (accelerator)
hasPostfix: BOOL ← FALSE, -- true if node has Postfix prop (accelerator)
hasArtwork: BOOL ← FALSE -- true if node has Artwork prop (accelerator)
];
PropList: TYPE ~ LIST OF Prop;
Prop: TYPE ~ REF PropRep;
PropRep:
TYPE ~
RECORD [name:
ATOM, value:
REF];
NodeIndex, Location, Text, Span
NodeIndex: TYPE ~ REF NodeIndexRep;
NodeIndexRep:
TYPE ~
RECORD [depth:
NAT, seq:
SEQUENCE size:
NAT
OF
INT];
IndexedNode: PROC [root: Node, index: NodeIndex] RETURNS [Node] ~ {
node: Node ← root;
FOR k: NAT IN [0..index.depth) DO
node ← NthChild[node, index[k]];
ENDLOOP;
RETURN[node];
};
Location: TYPE ~ RECORD [node: NodeIndex, where: INT ← 0];
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
nullLocation: Location ~ [node: NIL, where: nodeItself];
NodeLoc: PROC [n: Node] RETURNS [Location] ~ INLINE { RETURN[[n, nodeItself]] };
Text: TYPE ~ RECORD [content: NodeContent, start: INT ← 0, len: INT ← maxLen];
represents the characters [start..start+len) in content
end: PROC [text: Text] RETURNS [INT] ~ INLINE { RETURN[text.start+text.len] };
-- hack so t.start and t.end are uniformly usable
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 does 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];