-- 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.