DIRECTORY Atom USING [PropList], Rope USING [ROPE], TextLooks USING [allLooks, Looks, noLooks, Runs], TextNode USING [Location, Node], UndoEvent USING [Event]; TextEdit: CEDAR DEFINITIONS = BEGIN ROPE: TYPE = Rope.ROPE; Runs: TYPE = TextLooks.Runs; Looks: TYPE = TextLooks.Looks; noLooks: Looks = TextLooks.noLooks; allLooks: Looks = TextLooks.allLooks; Node: TYPE = TextNode.Node; Location: TYPE = TextNode.Location; Event: TYPE = UndoEvent.Event; CharSet: TYPE ~ [0..256); -- for XNS 16-bit character set; use in conjunction with 8-bit CHAR Text: TYPE ~ RECORD [node: Node, start: INT _ 0, len: INT _ INT.LAST]; end: PROC [text: Text] RETURNS [INT] ~ INLINE { RETURN[text.start+text.len] }; LocationInText: PROC [loc: Location, text: Text] RETURNS [BOOL] ~ INLINE { RETURN[loc.node=text.node AND loc.where IN[text.start..text.end)]; }; FetchChar: PROC [text: Node, index: INT] RETURNS [charSet: CharSet, char: CHAR]; FetchLooks: PROC [text: Node, index: INT] RETURNS [Looks]; Fetch: PROC [text: Node, index: INT] RETURNS [charSet: CharSet, char: CHAR, looks: Looks]; GetRope: PROC [text: Node] RETURNS [ROPE]; GetRuns: PROC [text: Node] RETURNS [Runs]; Size: PROC [text: Node] RETURNS [INT]; Flatten: PROC [text: Node] RETURNS [BOOL]; FromRope: PROC [rope: ROPE] RETURNS [Node]; FromString: PROC [string: REF READONLY TEXT] RETURNS [Node]; DocFromNode: PROC [child: Node] RETURNS [root: Node]; ChangeLooks: PROC [root: Node, text: Text, remove, add: Looks, event: Event _ NIL]; AddLooks: PROC [root: Node, text: Text, add: Looks, event: Event _ NIL]; RemoveLooks: PROC [root: Node, text: Text, remove: Looks _ allLooks, event: Event _ NIL]; SetLooks: PROC [root: Node, text: Text, new: Looks, event: Event _ NIL]; ClearLooks: PROC [root: Node, text: Text, event: Event _ NIL]; GetCharProp: PROC [node: Node, index: INT, name: ATOM] RETURNS [value: REF]; PutCharProp: PROC [node: Node, index: INT, name: ATOM, value: REF, nChars: INT _ 1, event: Event _ NIL, root: Node _ NIL]; MapPropsAction: TYPE ~ PROC [name: ATOM, value: REF] RETURNS [quit: BOOL _ FALSE]; MapCharProps: PROC [node: Node, index: INT, action: MapPropsAction] RETURNS [quit: BOOL]; ModifyPropsAction: TYPE ~ PROC [value: REF, index: INT, nChars: INT] RETURNS [quit: BOOL _ FALSE, newValue: REF]; ModifyCharProps: PROC [node: Node, name: ATOM, index: INT _ 0, nChars: INT _ INT.LAST, action: ModifyPropsAction, event: Event _ NIL, root: Node _ NIL] RETURNS [quit: BOOL]; PropList: TYPE ~ Atom.PropList; GetCharPropList: PROC [node: Node, index: INT] RETURNS [PropList]; PutCharPropList: PROC [node: Node, index: INT, propList: PropList, nChars: INT _ 1, event: Event _ NIL, root: Node _ NIL]; GetPropFromList: PROC [propList: PropList, key: ATOM] RETURNS [value: REF]; PutPropOnList: PROC [propList: PropList, key: ATOM, value: REF] RETURNS [new: PropList]; ChangeFormat: PROC [node: Node, formatName: ATOM, event: Event _ NIL, root: Node _ NIL]; ChangeStyle: PROC [node: Node, name: ROPE, event: Event _ NIL, root: Node _ NIL]; PutProp: PROC [node: Node, name: ATOM, value: REF, event: Event _ NIL, root: Node _ NIL]; GetProp: PROC [node: Node, name: ATOM] RETURNS [value: REF]; ReplaceText: PROC [destRoot, sourceRoot: Node, dest: Text, source: Text, event: Event _ NIL] RETURNS [result: Text]; DeleteText: PROC [root: Node, text: Text, event: Event _ NIL]; CopyText: PROC [destRoot, sourceRoot: Node, dest: Location, source: Text, event: Event _ NIL] RETURNS [result: Text]; MoveText: PROC [destRoot, sourceRoot: Node, dest: Location, source: Text, event: Event _ NIL] RETURNS [result: Text]; MoveTextOnto: PROC [destRoot, sourceRoot: Node, dest: Text, source: Text, event: Event _ NIL] RETURNS [result: Text]; TransposeText: PROC [alphaRoot, betaRoot: Node, alpha: Text, beta: Text, event: Event _ NIL] RETURNS [alphaResult: Text, betaResult: Text]; ReplaceByChar: PROC [root: Node, dest: Text, char: CHAR, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0, event: Event _ NIL] RETURNS [result: Text]; InsertChar: PROC [root: Node, dest: Location, char: CHAR, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0, event: Event _ NIL] RETURNS [result: Text]; AppendChar: PROC [root: Node, dest: Node, char: CHAR, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0, event: Event _ NIL] RETURNS [result: Text]; ReplaceByRope: PROC [root: Node, dest: Text, rope: ROPE, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0, event: Event _ NIL] RETURNS [result: Text]; InsertRope: PROC [root: Node, dest: Location, rope: ROPE, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0, event: Event _ NIL] RETURNS [result: Text]; AppendRope: PROC [root: Node, dest: Node, rope: ROPE, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0, event: Event _ NIL] RETURNS [result: Text]; String: TYPE ~ RECORD [text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ NAT.LAST]; ReplaceByString: PROC [root: Node, dest: Text, string: String, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0, event: Event _ NIL] RETURNS [result: Text]; InsertString: PROC [root: Node, dest: Location, string: String, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0, event: Event _ NIL] RETURNS [result: Text]; AppendString: PROC [root: Node, dest: Node, string: String, inherit: BOOL _ TRUE, looks: Looks _ noLooks, charSet: CharSet _ 0, event: Event _ NIL] RETURNS [result: Text]; CapChange: TYPE = {allCaps, allLower, initCaps, firstCap}; ChangeCaps: PROC [root: Node, dest: Text, how: CapChange _ allCaps, event: Event _ NIL]; AllCaps: PROC [root: Node, dest: Text, event: Event _ NIL]; AllLower: PROC [root: Node, dest: Text, event: Event _ NIL]; InitialCaps: PROC [root: Node, dest: Text, event: Event _ NIL]; END. ’TextEdit.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. written by Bill Paxton, February 1981 last edit by Bill Paxton, April 23, 1982 6:14 am last edit by Russ Atkinson, July 22, 1983 9:51 am Michael Plass, April 1, 1985 4:05:55 pm PST Doug Wyatt, September 9, 1986 12:54:15 pm PDT Editing operations for text nodes. Note: Character properties are implemented using a ROSARY (an immutable sequence of REFs; see Rosary.mesa), appearing in the CharSets property of the node. The values in this ROSARY are of type REF CharSet. represents the characters [start..start+len) in node Overview A text node contains a rope and runs of looks Looks are represented by a vector of 32 bits Each character in a text node has looks vector associated with it Run encoding is used to reduce the storage needed to represent the looks See TextLooks.mesa for more information about looks See TextNode.mesa for the details of text node structure Text editing operations are provided to edit the contents of text nodes unlike ropes or runs of looks, text nodes are mutable i.e., the edit changes the node rather than returning a new node the looks related commands are AddLooks, RemoveLooks, SetLooks, ClearLooks, and ChangeLooks the text related commands are ReplaceText, DeleteText, CopyText, MoveText, MoveTextOnto, TransposeText in addition there are commands taking a character/string/rope as source ReplaceByChar, InsertChar, AppendChar ReplaceByString, InsertString, AppendString ReplaceByRope, InsertRope, AppendRope several commands are available for changing capitalization AllCaps, AllLower, InitialCaps Persistent addresses in text of a node You can associate an address with a character location in a text node the address persists with the same character even if the text is edited the address is an arbitrary REF supplied by the client program see NodeAddrs.mesa for the persistent addressing operations Property lists Each node includes a property list of key-value pairs The keys are ATOMs and the values are arbitrary REFs Clients can register routines to read/write properties to files and to copy property values when nodes are copied see NodeProps.Mesa for the property list operations Character property lists Each character may include a property list of key-value pairs The keys are ATOMs and the values are arbitrary REFs Filing There are operations to read and write files containing text nodes The characters go at the front of the file, followed by 0's then the information about looks, etc. and finally a password and a pointer to the end of the text. Thus programs that simply want to look at the characters can read up to 0's operations to read/write nodes to files are found in PutGet.mesa Edit notification procedures Client's can register procedures to be called before/after edits the client procedure is called with the node(s) changed by the edit and a record describing the details of the edit see EditNotify.mesa for more information Tree editing nodes can have children there is a set of tree editing operations available see EditSpan.mesa for details General operations fetches the indexed information 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 returns true if it decides to flatten rope & runs this is done automatically after a certain number of edits to the node Operations to create a text node create a text node with looks from a normal rope copies the contents of the string returns root node which has one child child typically created by FromRope or FromString Operations to add or delete looks first remove then add in the given range Character Properties Places the value on the character property lists of the chars in the specified range. Use value = NIL to remove a character property. Used for traversing all the properites attached to a particular character. Used for traversing and altering the values of a character property ofer a range of characters; the action procedure is called for runs of properties, but adjacent runs are not necessarily merged. This property list mechanism regards a PropList as an immutable value. Changing Style / Format / Property of node appends style to end of node prefix Editing Operations for text NOTE: edit operations do not create or delete addrs, but they can change their locations within the text replace the dest text by a copy of the source text addrs that are in the replaced text move to destStart addrs that are after the replaced text are adjusted delete the specified range of text addrs that are in the deleted section move to start copy the specified text add length of inserted text to addrs that are beyond dest.where move source to dest no-op if LocationInText[dest, source] addrs that are in the moved text do one of the following: move with the text if dest = source, or move to start if dest # source move source onto dest implemented by appropriate calls on MoveText and DeleteText transpose alpha and beta addrs treated same as in Move move with the text if alpha.node = beta.node, or move to respective starts if alpha.node # beta.node replacement characters don't get any character properties if inherit is false, char gets specifed looks if inherit is true, char gets looks in following manner: if dest length is 0, then gets looks from argument list, else if start > 0, then gets looks from previous char, else gets looks from char following replacement Caps and Lowercase force specified span to all uppercase force specified span to all lowercase force first letter of words uppercase Κ ˜codešœ ™ Kšœ Οmœ7™BKšœ%™%Kšœ0™0Kšœ1™1Kšœ+™+K™-—K˜Kšœ"™"K˜šΟk ˜ Kšœžœ ˜Kšœžœžœ˜Kšœ žœ"˜1Kšœ žœ˜ Kšœ žœ ˜—K˜KšΠblœžœž ˜šœž˜K˜Kšžœžœžœ˜Kšœžœ˜Kšœžœ˜K˜#K˜%Kšœžœ˜Kšœ žœ˜#Kšœžœ˜K˜šœ žœ Οc?Πck˜]Kš œ3žœžœYžœ žœ ™Ο—K™š œžœžœžœ žœžœžœ˜FK™4K˜—š œžœžœžœžœžœ˜NK˜—š Οnœžœžœžœžœ˜JKšžœžœ žœ˜BK˜K˜——head™Kšœ-™-Kšœ,™,KšœA™AKšœH™HKšœ3™3Kšœ8™8K˜šœ ™ šœ:™:Kšœ5™5Kšœ@™@—šœ™Kšœ<™<—šœ™KšœH™H—šœG™GKšœ%™%Kšœ+™+Kšœ%™%—šœ:™:Kšœ™K˜——šœ&™&KšœE™EKšœG™GKšœ?™?Kšœ;™;K˜—šœ™Kšœ5™5Kšœ4™4šœ?™?Kšœ1™1—Kšœ3™3K˜—šœ™Kšœ=™=Kšœ4™4K˜—šœ™KšœB™Bšœ;™;šœ&™&Kšœ<™<——KšœK™KKšœ@™@K˜—šœ™Kšœ@™@šœC™CKšœ/™/—Kšœ(™(K˜—šœ ™ Kšœ™Kšœ3™3Kšœ™K˜——šœ™š ’ œžœžœžœžœ˜PKšœ™Kšœ=™=K˜—š’ œžœžœžœ ˜:Kšœ9™9Kšœ6™6K˜—š ’œžœžœžœžœ˜ZKšœ@™@Kšœ?™?K˜—š’œžœžœžœ˜*K˜—š’œžœžœ˜*K˜—š’œžœžœžœ˜&K˜—K˜š’œžœžœžœ˜*Kšœ1™1KšœF™F——šœ ™ š’œžœžœžœ˜+Kšœ0™0K˜—š ’ œžœ žœžœžœžœ˜K˜——šœ™š ’ œžœžœžœžœ žœ˜LK˜—š’ œžœžœžœ žœ žœžœžœ˜{KšœU™UKšœ/™/K˜—šœžœžœžœ žœžœžœžœ˜RK˜—š ’ œžœžœžœžœ˜YK™JK™—šœžœžœ žœ žœ žœžœžœžœ žœ˜rK˜—š’œžœžœ žœžœžœžœ,žœžœžœžœ˜­K™ΔK™—šœ žœ˜KšœF™FK™—Kš’œžœžœžœ ˜Bš ’œžœžœžœžœžœ˜{K˜—Kš ’œžœžœžœ žœ˜KKš ’ œžœžœ žœžœ˜X—šœ*™*š ’ œžœžœžœžœ˜YK˜—š ’ œžœžœžœžœ˜RKšœ*™*K˜—š ’œžœžœ žœžœžœ˜ZK˜—š ’œžœžœžœ žœ˜Kšœ"™"Kšœ3™3K˜—š’œžœKžœžœ˜uKšœ™Kšœ?™?K˜—š’œžœKžœžœ˜uKšœ™Kšœ%™%šœ9™9Kšœ$™$Kšœ!™!K˜——š’ œžœGžœžœ˜uKšœ™Kšœ;™;K˜—š’ œžœEžœžœ'˜‹Kšœ™šœ™Kšœ-™-Kšœ6™6K˜——K˜š’ œžœ žœ žœžœ?žœžœ˜¨K™9Kšœ.™.šœ8™8Kšœ=™=Kšœ1™1Kšœ/™/K˜——š’ œžœ$žœ žœžœ?žœžœ˜ͺK˜—š’ œžœ žœ žœžœ?žœžœ˜¦K˜—š’ œžœ žœ žœžœ?žœžœ˜©K˜—š’ œžœ$žœ žœžœ?žœžœ˜ͺK˜—š’ œžœ žœ žœžœ?žœžœ˜¦K˜—šœžœžœžœžœžœ žœ žœžœžœ˜UK˜—š ’œžœ4žœžœ?žœžœ˜―K˜—š ’ œžœ8žœžœ?žœžœ˜°K˜—š ’ œžœ4žœžœ?žœžœ˜¬K˜——šœ™šœ žœ+˜:K˜—š’ œžœCžœ˜XK˜—š’œžœ)žœ˜;Kšœ%™%K˜—š’œžœ)žœ˜