DIRECTORY ImagerFont USING [BYTE, XChar], Rope USING [ROPE], Rosary USING [ROSARY], TextLooks USING [Looks, allLooks, noLooks, Runs]; ImmutableTioga: CEDAR DEFINITIONS ~ BEGIN 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; Prop: TYPE ~ REF PropRep; PropRep: TYPE ~ RECORD [name: ATOM, value: REF]; PropList: TYPE ~ LIST OF Prop; MapPropsAction: TYPE ~ PROC [name: ATOM, value: REF] RETURNS [quit: BOOL _ FALSE]; Node: TYPE ~ REF NodeRep; -- immutable NodeRep: TYPE ~ RECORD [ text: Text, children: ROSARY --OF Node--, depth: INT ]; Text: TYPE ~ REF TextRep; -- immutable TextRep: TYPE ~ RECORD [ rope: ROPE, runs: Runs, charSets: ROSARY --OF REF CharSet--, charProps: ROSARY --OF PropList--, props: Props ]; Props: TYPE ~ REF PropsRep; -- immutable PropsRep: TYPE ~ RECORD [ propList: PropList _ NIL, formatName: ATOM _ NIL, -- value of $Format property comment: BOOL _ FALSE, -- value of $Comment property hasStyleDef: BOOL _ FALSE, -- true if propList has $StyleDef prop (accelerator) hasPrefix: BOOL _ FALSE, -- true if propList has $Prefix prop (accelerator) hasPostfix: BOOL _ FALSE, -- true if propList has $Postfix prop (accelerator) hasArtwork: BOOL _ FALSE -- true if propList has $Artwork prop (accelerator) ]; maxLen: INT ~ INT.LAST; NewText: PROC [props: Props _ NIL] RETURNS [Text]; TextFromRope: PROC [rope: ROPE, looks: Looks _ noLooks] RETURNS [Text]; PropListGet: PROC [propList: PropList, name: ATOM] RETURNS [value: REF]; PropListPut: PROC [propList: PropList, name: ATOM, value: REF] RETURNS [PropList]; PropListMap: PROC [propList: PropList, action: MapPropsAction] RETURNS [BOOL]; PropsGet: PROC [props: Props, name: ATOM] RETURNS [value: REF]; PropsPut: PROC [props: Props, name: ATOM, value: REF] RETURNS [Props]; PropsMap: PROC [props: Props, action: MapPropsAction] RETURNS [BOOL]; PropReader: TYPE ~ PROC [name: ATOM, specs: ROPE] RETURNS [value: REF]; PropWriter: TYPE ~ PROC [name: ATOM, value: REF] RETURNS [specs: ROPE]; ReadProp: PropReader; WriteProp: PropWriter; RegisterProp: PROC [name: ATOM, reader: PropReader, writer: PropWriter]; Size: PROC [text: Text] RETURNS [INT]; FetchChar: PROC [text: Text, index: INT] RETURNS [XChar]; FetchLooks: PROC [text: Text, index: INT] RETURNS [Looks]; Fetch: PROC [text: Text, index: INT] RETURNS [char: XChar, looks: Looks]; GetProp: PROC [text: Text, name: ATOM] RETURNS [REF]; GetComment: PROC [text: Text] RETURNS [BOOL]; GetFormat: PROC [text: Text] RETURNS [ATOM]; MapProps: PROC [node: Node, action: MapPropsAction] RETURNS [quit: BOOL]; GetCharProp: PROC [text: Text, index: INT, name: ATOM] RETURNS [value: REF]; GetCharPropList: PROC [text: Text, index: INT] RETURNS [PropList]; MapCharProps: PROC [node: Node, index: INT, action: MapPropsAction] RETURNS [BOOL]; ReplaceText: PROC [dest: Text, destStart: INT _ 0, destLen: INT _ maxLen, source: Text _ NIL, sourceStart: INT _ 0, sourceLen: INT _ maxLen] RETURNS [Text]; DeleteText: PROC [dest: Text, destStart: INT _ 0, destLen: INT _ maxLen] RETURNS [Text]; ReplaceByRope: PROC [dest: Text, destStart: INT, destLen: INT, rope: ROPE, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0] RETURNS [Text]; SetProp: PROC [text: Text, name: ATOM, value: REF] RETURNS [Text]; SetComment: PROC [text: Text, comment: BOOL] RETURNS [Text]; SetFormat: PROC [text: Text, formatName: ATOM] RETURNS [Text]; SetCharProp: PROC [text: Text, start: INT _ 0, len: INT _ maxLen, name: ATOM, value: REF] RETURNS [Text]; SetCharPropList: PROC [text: Text, start: INT _ 0, len: INT _ maxLen, propList: PropList] RETURNS [Text]; END. )πImmutableTioga.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Doug Wyatt, September 16, 1986 4:46:35 pm PDT Types Defined elsewhere PropList Node Location, Span nodeItself: INT ~ -1; 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]] }; 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]; World World: TYPE ~ REF WorldRep; WorldRep: TYPE; Tree operations Parent, Sibling, Child Parent: PROC [n: Node] RETURNS [Node]; returns parent of n returns NIL if n is root Root: PROC [n: Node] RETURNS [Node]; returns root of tree containing n Next: PROC [n: Node] RETURNS [Node]; returns next sibling of n returns NIL if n is last sibling Previous: PROC [n: Node, parent: Node _ NIL] RETURNS [Node]; returns previous sibling of n returns NIL if n is first sibling runs faster if can supply parent IsLastSibling: PROC [n: Node] RETURNS [BOOL]; IsLastSibling[n] == Next[n]=NIL. FirstChild: PROC [n: Node] RETURNS [Node]; Parent[FirstChild[n]] = n; Previous[FirstChild[n]] = NIL. LastChild: PROC [n: Node] RETURNS [Node]; Parent[FirstChild[n]] = n; Next[LastChild[n]] = NIL. FirstSibling: PROC [n: Node] RETURNS [Node]; FirstSibling[n] = FirstChild[Parent[n]] LastSibling: PROC [n: Node] RETURNS [Node]; LastSibling[n] = LastChild[Parent[n]] LastWithin: PROC [n: Node] RETURNS [Node]; returns the last node within the branch i.e., goes to last child of last child of last child ... until no child Level: PROC [n: Node] RETURNS [INT]; Level[Root[x]] == 0; Level[FirstChild[n]]=Level[n]+1 Counting NthChild: PROC [n: Node, index: INT] RETURNS [Node]; NthChild[n, 0] == FirstChild[n]; NthChild[n, k+1] == Next[NthChild[n, k]] NthSibling: PROC [n: Node, index: INT] RETURNS [Node]; CountChildren: PROC [n: Node] RETURNS [count: INT]; CountFollowing: PROC [n: Node] RETURNS [count: INT]; CountToParent: PROC [n: Node] RETURNS [count: INT, parent: Node]; CountToChild: PROC [parent, child: Node] RETURNS [count: INT]; Forward, Backward Forward: PROC [node: Node] RETURNS [nx: Node, levelDelta: INT]; 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: Node, parent: Node _ NIL] RETURNS [back, backparent: Node, levelDelta: INT]; for backing through tree runs faster if can supply parent levelDelta same as for Forward ForwardClipped: PROC [node: Node, maxLevel: INT, nodeLevel: INT _ 0] RETURNS [nx: Node, nxLevel: INT]; 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: Node, maxLevel: INT, parent: Node _ NIL, nodeLevel: INT _ 0] RETURNS [back, backparent: Node, backLevel: INT]; like Backward, but limits how deep will go in tree backLevel = Level[back] <= MAX[maxLevel,Level[node]] Locations BadArgs: ERROR; LocRelative: PROC [location: Location, count: INT, break: INT _ 1, skipCommentNodes: BOOL _ FALSE] RETURNS [Location]; count is interpreted as a character offset from given location returns 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: Node, count: INT, break: INT _ 1, skipCommentNodes: BOOL _ FALSE] RETURNS [Location]; LocRelative[[n, 0], ...]; count is offset from beginning of given node LocOffset: PROC [loc1, loc2: Location, break: INT _ 1, skipCommentNodes: BOOL _ FALSE] 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 LocNumber: PROC [at: Location, break: INT _ 1, skipCommentNodes: BOOL _ FALSE] RETURNS [count: INT]; returns character offset of location relative to root LastLocWithin: PROC [n: Node] RETURNS [Location]; returns the last location within the branch Node order Order: TYPE ~ { before, same, after, disjoint }; CompareNodeOrder: PROC [node1, node2: Node] RETURNS [Order]; determines relative order in tree of the nodes returns "same" if node1 = node2 returns "before" if node1 comes before node2 returns "after" if node1 comes after node2 returns "disjoint" if nodes are not from the same tree CompareLocOrder: PROC [loc1, loc2: Location] RETURNS [Order]; Node operations Creation create a text node from a normal rope FromRefText: PROC [text: REF READONLY TEXT] RETURNS [Node]; copies the contents of the text FromString: PROC [string: String] RETURNS [Node]; copies the contents of the string DocFromNode: PROC [child: Node] RETURNS [root: Node]; returns root node which has one child child typically created by FromRope or FromString Properties Read, Write props used when reading files; convert from external specs to internal REF used when writing files; convert from internal REF to external specs calls the registered reader for this property name if no reader is registered, returns specs calls the registered writer for this property name if no writer is registered, returns value if it is a rope, NIL otherwise registers procs for given property name they will be called by ReadProp, WriteProp, CopyProp Fetch Text information fetches the indexed character use rope readers if want characters from contiguous locations returns the looks for the character at the given location use readers if getting looks for sequence of locations fetches the indexed information, except for character properties use rope & looks readers if want info from contiguous locations apply the action to each name & value pair for the node returns true if&when an action returns true apply the action to each name & value pair for the indexed character Editing Edit Text Sets the $Comment property of a node. Sets the $Format property of a node. Places the value on the character property lists of the chars in the specified range. Use value=NIL to remove a character property. ModifyPropsAction: TYPE ~ PROC [value: REF, start: INT, len: INT] RETURNS [quit: BOOL _ FALSE, newValue: REF]; ModifyCharProps: PROC [world: World, text: Text, name: ATOM, action: ModifyPropsAction, root: Node _ NIL] RETURNS [quit: BOOL]; Used for traversing and altering the values of a character property over a range of characters; the action procedure is called for runs of properties, but adjacent runs are not necessarily merged. Edit Spans Place: TYPE ~ { before, after, sibling, child }; these are modifiers for the destination of a Move or Copy or Insert only apply when destination is an entire node (i.e., dest.where = nodeItself) place = before means insert as sibling before dest place = after means insert as sibling after dest; inherit children of dest place = sibling means insert as sibling after dest; don't inherit children of dest place = child means insert as first child of dest Replace: PROC [world: World, destRoot, sourceRoot: Node, dest, source: Span, saveForPaste: BOOL _ TRUE] RETURNS [result: Span]; replace dest span by copy of source span result is the new copy of source Delete: PROC [world: World, root: Node, del: Span, saveForPaste: BOOL _ TRUE]; SaveForPaste: PROC [world: World, span: Span]; SavedForPaste: PROC [world: World] RETURNS [span: Span]; result is last thing deleted or explicitly saved for Paste Copy: PROC [world: World, destRoot, sourceRoot: Node, dest: Location, source: Span, where: Place _ after, nesting: INTEGER _ 0] RETURNS [result: Span]; result is the new copy of source Move: PROC [world: World, destRoot, sourceRoot: Node, dest: Location, source: Span, where: Place _ after, nesting: INTEGER _ 0] RETURNS [result: Span]; dest cannot be within source or get error CannotDoEdit result is moved span nesting is relative to dest e.g., where=after and nesting=1 makes source be child of dest MoveOnto: PROC [world: World, destRoot, sourceRoot: Node, dest, source: Span, saveForPaste: BOOL _ TRUE] RETURNS [result: Span]; like Replace, but moves source instead of copying it result is moved span Transpose: PROC [world: World, alphaRoot, betaRoot: Node, alpha, beta: Span] RETURNS [newAlpha, newBeta: Span]; alpha and beta must not overlap or get error CannotDoEdit newAlpha is new location of alpha span; ditto for newBeta CannotDoEdit: ERROR; Node properties SetStyle: PROC [world: World, node: Node, styleName: ROPE, root: Node _ NIL]; appends style to end of node prefix Insert, Split, Merge, Nest Insert: PROC [world: World, root, old: Node, where: Place _ after, inherit: BOOL _ TRUE] RETURNS [new: Node]; new empty node is inserted in tree in position determined by "where" if inherit, new node inherits properties of old Split: PROC [world: World, root: Node, loc: Location] RETURNS [new: Node]; inserts copy of loc.node is inserted directly before loc.node (as sibling) new adopts children of old (if any) if loc.where # nodeItself and loc.node is a text node, then text after loc.where moves to new node text before loc.where stays in old node returns the new node Merge: PROC [world: World, root, node: Node] RETURNS [loc: Location]; copies text of node to end of previous node then deletes node ChangeNesting: PROC [world: World, root: Node, span: Span, change: INT] RETURNS [Span]; moves all nodes of span, even if entire nodes not selected change>0 is deeper in the tree, change<0 is shallower Looks, Caps ChangeTextLooks: PROC [world: World, root: Node, text: Text, remove, add: Looks]; first remove then add in the given range ChangeLooks: PROC [world: World, root: Node, span: Span, remove, add: Looks]; first remove then add in the given span CapChange: TYPE ~ {allCaps, allLower, initCaps, firstCap}; ChangeTextCaps: PROC [world: World, root: Node, text: Text, how: CapChange _ allCaps]; ChangeCaps: PROC [world: World, root: Node, span: Span, how: CapChange _ allCaps]; ΚΟ˜codešœ™Kšœ Οmœ1™K™——™š‘œžœžœžœ™?Kšœ-™-šœA™AKšœ*™*Kšœ%™%Kšœ;™;K™——š ‘œžœžœžœ&žœ™cKšœ™Kšœ ™ Kšœ™K™—š ‘œžœžœ žœžœžœ™gKšœ1™1Kšœ4™4Kšœžœ™0K™—š‘œžœžœžœ žœžœ%žœ™‹Kšœ2™2Kšœžœ™4K™——™ šœ žœ™K™—š‘ œžœžœ žœžœžœžœ ™wKšœ>™>Kšœ5™5Kšœ-™-KšœB™BK™—š‘ œžœžœ žœžœžœžœ ™jKšœF™FK™—š‘ œžœžœžœžœžœ žœ™mKšœ;™;Kšœ!™!Kšœ0žœ™=KšœB™BK™—š‘ œžœžœžœžœžœ žœ™eKšœ5™5K™—š‘ œžœ žœ ™1Kšœ,™,K™——™ šœžœ%™0K™—š‘œžœžœ ™K™$K™—š‘ œžœžœ žœžœ žœžœ˜iKšœU™UKšœ žœ ™-K™—š ‘œžœžœ žœžœ˜iK™—šœžœžœ žœ žœžœžœžœžœ žœ™oK™—š ‘œžœ"žœ*žœžœžœ™K™ΔK™——™ šœžœ%™0KšœC™CKšœM™MKšœ2™2KšœJ™JKšœR™RKšœ1™1K™—š ‘œžœOžœžœžœ™€Kšœ(™(Kšœ ™ K™—š‘œžœ5žœžœ™NK™—š‘ œžœ™.K™—š‘ œžœžœ™8Kšœ:™:K™—š‘œžœjžœžœ™˜Kšœ ™ K™—š‘œžœjžœžœ™˜Kšœ6™6Kšœ™šœ™Kšœ=™=—K™—š ‘œžœOžœžœžœ™Kšœ4™4Kšœ™K™—š‘ œžœ>žœ™pKšœ9™9Kšœ9™9K™—š‘ œžœ™K™——šœ™š‘œžœ'žœžœ™MKšœ*™*K™——™š ‘œžœAžœžœžœ ™nKšœD™DK™/K™—š‘œžœ+žœ ™JšœJ™JKšœ#™#—šœ;™;Kšœ&™&Kšœ'™'—Kšœ™K™—š‘œžœ"žœ™EKšœ+™+Kšœ™K™—š‘ œžœ0žœžœ™WKšœ:™:K™5K™——™ š‘œžœ<™QKšœ(™(K™—š‘ œžœ<™MKšœ'™'K™—šœ žœ+™:K™—š‘œžœB™VK™—š‘ œžœB™RK™———K˜Kšžœ˜—…—ΐH