-- TextNode.Mesa
-- written by Bill Paxton. December 1980
-- last written by Paxton. March 19, 1981 10:10 AM
DIRECTORY
Rope USING [Ref],
TextLooks USING [Runs];
TextNode: DEFINITIONS =
BEGIN
Card: TYPE = LONG CARDINAL;
Ref: TYPE = REF Body;
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
typename: TypeName ← nullTypeName, -- name of type for the node
last: BOOLEAN ← FALSE, -- true if this is last sibling
hasstyle: BOOLEAN ← FALSE, -- true if node has style prop
body: SELECT kind:OfNode FROM
text => [rope: Rope.Ref, runs: TextLooks.Runs],
other => [ref: REF ANY],
ENDCASE];
OfNode: TYPE = {text,other};
TextBody: TYPE = text Body;
RefTextNode: TYPE = REF TextBody;
OtherBody: TYPE = other Body;
RefOtherNode: TYPE = REF OtherBody;
NodeProps: TYPE = REF NodePropsBody;
NodePropsBody: TYPE; -- exported by NodePropsImpl
-- here are some inlines for use with nodes
Next: PROC [n: Ref] RETURNS [Ref] = INLINE {
RETURN[IF n.last THEN NIL ELSE n.next]};
Props: PROC [n: Ref] RETURNS [NodeProps] = INLINE {
RETURN[n.props]};
NodeType: PROC [n: Ref] RETURNS [TypeName] = INLINE {
RETURN[n.typename]};
IsLastSibling: PROC [n: Ref] RETURNS [BOOLEAN] = INLINE {
RETURN[n.last]};
FirstChild: PROC [n: Ref] RETURNS [Ref] = INLINE {
RETURN[n.child]};
NthChild: PROC [n: Ref, location: Card] RETURNS [child: Ref] = INLINE {
FOR child ← FirstChild[n], Next[child] UNTIL child=NIL OR location=0 DO
location ← location-1; ENDLOOP};
CountChildren: PROC [n: Ref] RETURNS [count: Card] = INLINE {
count ← 0;
FOR child: Ref ← FirstChild[n], Next[child] UNTIL child=NIL DO
count ← count+1; ENDLOOP};
CountFollowing: PROC [n: Ref] RETURNS [count: Card] = INLINE {
count ← 0;
UNTIL (n ← Next[n])=NIL DO count ← count+1; ENDLOOP};
CountToParent: PROC [n: Ref] RETURNS [count: Card, parent: Ref] = INLINE {
count ← 0;
UNTIL n.last DO count ← count+1; n ← n.next ENDLOOP;
parent ← n.next};
HasStyle: PROC [n: Ref] RETURNS [BOOLEAN] = INLINE {
RETURN[n.hasstyle]};
NodeRope: PROC [n: RefTextNode] RETURNS [Rope.Ref] = INLINE {
RETURN[n.rope]};
NodeRuns: PROC [n: RefTextNode] RETURNS [TextLooks.Runs] = INLINE {
RETURN[n.runs]};
Parent: PROC [n: Ref] RETURNS [Ref] = INLINE {
UNTIL n.last DO n ← n.next ENDLOOP; RETURN [n.next]};
LastSibling: PROC [n: Ref] RETURNS [Ref] = INLINE {
UNTIL n.last DO n ← n.next ENDLOOP; RETURN [n]};
FirstSibling: PROC [n: Ref] RETURNS [Ref] = INLINE {
RETURN[FirstChild[Parent[n]]]};
Previous: PROC [n: Ref] RETURNS [nx: Ref] = INLINE {
FOR nx ← FirstSibling[n], nx.next UNTIL nx.next=n DO ENDLOOP};
-- TypeNames and StyleNames are the same as names in TiogaJam
-- declared as separate records to get type checking
TypeName: TYPE = RECORD [local: BOOLEAN, index: NAT];
nullTypeName: TypeName = [FALSE, 0];
StyleName: TYPE = RECORD [local: BOOLEAN, index: NAT];
nullStyleName: StyleName = [FALSE, 0];
END.