DIRECTORY Rope USING [ROPE]; TextLooks: CEDAR DEFINITIONS = BEGIN Runs: TYPE = REF RunsBody; Looks: TYPE = PACKED ARRAY Look OF Bit; Look: TYPE = CHAR ['a..'a+31]; -- 32 bits; indexed from "a" Bit: TYPE = BOOL _ FALSE; noLooks: Looks = ALL[FALSE]; allLooks: Looks = ALL[TRUE]; MaxLen: INT = LAST[INT]; CreateRun: PROC [len: INT, looks: Looks _ noLooks] RETURNS [Runs]; FetchLooks: PROC [runs: Runs, index: INT] RETURNS [Looks]; CountRuns: PROC [runs: Runs, start, len: INT, limit: INT _ MaxLen, merge: BOOL _ FALSE, firstLooks: Looks _ noLooks ] RETURNS [count: INT, nonempty: BOOL, lastLooks: Looks]; Size: PROC [base: Runs] RETURNS [size: INT]; ChangeLooks: PROC [runs: Runs, size: INT, remove, add: Looks, start: INT _ 0, len: INT _ MaxLen] RETURNS [Runs]; Substr: PROC [base: Runs, start: INT, len: INT] RETURNS [Runs]; Flatten: PROC [base: Runs] RETURNS [new: Runs]; Concat: PROC [base, rest: Runs, baseLen, restLen: INT] RETURNS [Runs]; Replace: PROC [base: Runs, start, len: INT, replace: Runs, baseSize, repSize: INT, tryFlat: BOOL _ TRUE] RETURNS [Runs]; Copy: PROC [dest: Runs, destLoc: INT, source: Runs, start, len, destSize: INT] RETURNS [Runs]; ReplaceByRun: PROC [dest: Runs, start, len, runLen, destSize: INT, inherit: BOOL, looks: Looks] RETURNS [Runs]; LooksStats: PROC [base: Runs, start: INT _ 0, len: INT _ MaxLen] RETURNS [size, pieces, depth: INT]; OutOfBounds: ERROR; LooksToRope: PROC [looks: Looks] RETURNS [rope: Rope.ROPE]; RopeToLooks: PROC [rope: Rope.ROPE] RETURNS [looks: Looks]; LooksAND: PROC [looks1, looks2: Looks] RETURNS [Looks]; LooksOR: PROC [looks1, looks2: Looks] RETURNS [Looks]; LooksNOT: PROC [looks: Looks] RETURNS [Looks]; LooksBytes: TYPE = MACHINE DEPENDENT RECORD [ byte0(0:0..7), byte1(0:8..15), byte2(1:0..7), byte3(1:8..15): [0..255] _ 0 ]; RunsBody: TYPE = RECORD [ SELECT tag: * FROM base => [runs: SEQUENCE length: NAT OF Run], node => [ SELECT case: * FROM substr => [size: INT, base: Runs, start: INT], concat => [size: INT, base, rest: Runs, pos: INT], replace => [size: INT, base, replace: Runs, start, oldPos, newPos: INT], change => [size: INT, base: Runs, remove, add: Looks, start, len: INT], ENDCASE ], ENDCASE ]; Run: TYPE = RECORD [after: INT _ 0, looks: Looks _ noLooks]; BaseRuns: TYPE = REF Tbase; Tbase: TYPE = base RunsBody; Tsubstr: TYPE = substr node RunsBody; Tconcat: TYPE = concat node RunsBody; Treplace: TYPE = replace node RunsBody; Tchange: TYPE = change node RunsBody; FlatMax: INT = 10; -- flatten if length of run <= FlatMax END. PTextLooks.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. written by Bill Paxton, February 1981 last edit by Bill Paxton, December 13, 1982 1:17 pm Last Edited by: Maxwell, January 5, 1983 12:35 pm Michael Plass, March 14, 1985 10:00:03 am PST Doug Wyatt, September 3, 1986 1:14:39 pm PDT This package provides Looks for text in Tioga it allows a client to associate looks with characters in a rope looks are represented as a vector of 32 bits The implementation expects that long sequences will have the same looks and thus uses a run encoding to save space. The runs of looks are immutable just like the text in a rope. i.e., you don't change runs; instead you build new ones out of parts of old ones Also like ropes, we use piece tables in the implementation thus making the cost of setting looks independent of the size of the rope. General operations on runs returns the looks for the character at the given location counts the number of runs in the given range stops counting if reaches limit if merge is true, then doesn't count first run if its looks=firstLooks Operations to change looks first remove then add in the given range Editing Operations returns a substring of the runs returns a flattened version of base runs returns the concatenation of two Runs returns new Runs with the given range replaced equivalent to, but faster than, Replace[dest,start,len,CreateRun[runLen,xlooks],destSize,runLen] where xlooks determined in the following manner: if inherit is false, looks specifed in arg list if inherit is true, looks found in following manner: if destSize is 0, then take looks from argument list, else if start > 0, then looks of previous char, else looks following replacement Miscellaneous compute looks1 & looks2 compute looks1 v looks2 compute ~looks Internal declarations RunsBody is modeled after Rope.RopeRep ส:˜codešœ™Kšœ ฯmœ7™BKšœ%™%Kšœ3™3K™1K™-K™,—˜šœ-™-Kšœ?™?Kšœ,™,K˜—šœG™GKšœ+™+K˜—šœ=™=šœ™Kšœ4™4K˜——šœ;™;KšœK™K—K˜—šฯk ˜ Kšœžœžœ˜—K˜Kšะbl œžœž ˜šœž˜K˜Kšœžœžœ ˜Kš œžœžœžœžœ˜'Kšœžœžœฯc˜