DIRECTORY CardTab USING [Create, Ref, Update, UpdateAction], Rope USING [Cat, Fetch, FromChar, ROPE, Size], Rosary USING [CatSegments, Fetch, FromItem, MapRuns, ROSARY, RunActionType], TextLooks USING [Look, Looks, LooksAnd, LooksNot, LooksOr, MaxOffset, noLooks, RunAction, Runs]; TextLooksImpl: CEDAR PROGRAM IMPORTS CardTab, Rope, Rosary, TextLooks EXPORTS TextLooks = BEGIN OPEN TextLooks; ROPE: TYPE ~ Rope.ROPE; ROSARY: TYPE ~ Rosary.ROSARY; LooksToRope: PUBLIC PROC [looks: Looks] RETURNS [rope: ROPE] = { FOR lk: TextLooks.Look IN TextLooks.Look DO IF looks[lk] THEN rope _ Rope.Cat[rope, Rope.FromChar[lk]]; ENDLOOP; }; RopeToLooks: PUBLIC PROC [rope: ROPE] RETURNS [looks: Looks] = { looks _ noLooks; FOR i: INT IN [0..Rope.Size[rope]) DO char: CHAR _ Rope.Fetch[rope, i]; IF char IN Look THEN looks[char] _ TRUE; ENDLOOP; }; Size: PUBLIC PROC [runs: Runs] RETURNS [INT] ~ { RETURN [IF runs=NIL THEN 0 ELSE runs.size]; }; nilRosary: ROSARY ~ Rosary.FromItem[NIL, INT.LAST]; -- "infinite" rosary of NIL ItemNotNil: Rosary.RunActionType ~ { RETURN[quit: item#NIL] }; Replace: PUBLIC PROC [base: Runs, start, len: INT, replace: Runs, baseSize, repSize: INT] RETURNS [new: Runs] ~ { d: ROSARY ~ IF base=NIL THEN nilRosary ELSE base; d1: INT ~ MAX[LONG[0], MIN[start, baseSize]]; d2: INT ~ d1+MAX[LONG[0], MIN[len, baseSize-d1]]; s: ROSARY ~ IF replace=NIL THEN nilRosary ELSE replace; r: ROSARY ~ Rosary.CatSegments[[d, 0, d1], [s, 0, repSize], [d, d2, baseSize-d2]]; RETURN[IF Rosary.MapRuns[[r], ItemNotNil] THEN r ELSE NIL]; }; refFromLooksTab: CardTab.Ref ~ CardTab.Create[]; RefFromLooks: PROC [looks: Looks] RETURNS [ref: REF Looks _ NIL] ~ { refFromLooksAction: CardTab.UpdateAction ~ { IF found THEN { ref _ NARROW[val]; RETURN[op: none] } ELSE { ref _ NEW[Looks _ looks]; RETURN[op: store, new: ref] }; }; IF looks=noLooks THEN RETURN[NIL]; CardTab.Update[refFromLooksTab, LOOPHOLE[looks], refFromLooksAction]; IF ref^#looks THEN ERROR; }; CreateRun: PUBLIC PROC [len: INT, looks: Looks _ noLooks] RETURNS [Runs] ~ { refLooks: REF Looks ~ RefFromLooks[looks]; RETURN[Rosary.FromItem[refLooks, len]]; }; FetchLooks: PUBLIC PROC [runs: Runs, index: INT] RETURNS [Looks] = { IF runs#NIL THEN WITH Rosary.Fetch[runs, index] SELECT FROM refLooks: REF Looks => RETURN[refLooks^] ENDCASE; RETURN[noLooks]; }; CountRuns: PUBLIC PROC [runs: Runs, start: INT _ 0, len: INT _ MaxOffset] RETURNS [count: INT _ 0] ~ { countAction: Rosary.RunActionType ~ { count _ count+1 }; [] _ Rosary.MapRuns[[runs, start, len], countAction]; }; MapRuns: PUBLIC PROC [runs: Runs, action: RunAction, start: INT _ 0, len: INT _ MaxOffset] RETURNS [quit: BOOL] ~ { mapAction: Rosary.RunActionType ~ { refLooks: REF Looks ~ NARROW[item]; RETURN action[(IF refLooks=NIL THEN noLooks ELSE refLooks^), repeat]; }; RETURN Rosary.MapRuns[[runs, start, len], mapAction]; }; ModifyLooks: PUBLIC PROC [old, remove, add: Looks] RETURNS [Looks] ~ { RETURN [LooksOr[LooksAnd[old, LooksNot[remove]], add]]; }; ChangeLooks: PUBLIC PROC [runs: Runs, size: INT, remove, add: Looks, start, len: INT] RETURNS [Runs] ~ { d: ROSARY _ IF runs=NIL THEN nilRosary ELSE runs; changeLooksAction: Rosary.RunActionType ~ { oldLooks: Looks ~ IF item=NIL THEN noLooks ELSE NARROW[item, REF Looks]^; newLooks: Looks ~ ModifyLooks[oldLooks, remove, add]; replace: ROSARY ~ Rosary.FromItem[RefFromLooks[newLooks], repeat]; end: INT ~ start+repeat; d _ Rosary.CatSegments[[d, 0, start], [replace], [d, end, size-end]]; start _ end; }; [] _ Rosary.MapRuns[[d, start, len], changeLooksAction]; RETURN[IF Rosary.MapRuns[[d, 0, size], ItemNotNil] THEN d ELSE NIL]; }; END. hTextLooksImpl.mesa Copyright Σ 1985, 1986, 1988 by Xerox Corporation. All rights reserved. written by Bill Paxton, February 1981 Bill Paxton, December 13, 1982 1:17 pm Maxwell, January 5, 1983 3:54 pm Russ Atkinson, July 25, 1983 3:36 pm Michael Plass, March 29, 1985 5:24:46 pm PST Doug Wyatt, February 17, 1988 5:28:53 pm PST Rope conversion Edit operations General operations PROC [found: BOOL, val: Val] RETURNS [op: UpdateOperation _ none, new: Val _ NIL] returns the looks for the character at the given location Operation to change looks PROC [item: Item, repeat: INT] RETURNS [quit: BOOLEAN _ FALSE] Κt˜šœ™JšœH™HJšœ%™%Jšœ&™&Jšœ ™ Jšœ$™$Jšœ,™,Jšœ,™,J™—šΟk ˜ Jšœœ%˜2Jšœœœ ˜/Jšœœ)œ˜MJšœ œQ˜`J˜—JšΟn œœ˜Jšœ!˜(Jšœ ˜šœœœ ˜J˜Jšœœœ˜Jšœœ œ˜—headšœ™unitš ž œœœœœ˜@šœœ˜+Jšœ œ*˜;Jšœ˜—J˜—š ž œœœœœ˜@J˜šœœœ˜%Jšœœ˜!Jšœœœœ˜(Jšœ˜—J˜——šœ™š žœœœœœ˜0Jš œœœœœ ˜+J˜—Lš œ œœœœΟc˜OLšž œœ œ˜>š žœœœœ%œœ˜rIcodeš œœœœœ œ˜1Mš œœœœœ˜-Mš œœœœœ˜1Mš œœœ œœ œ ˜7MšœœI˜RMš œœ!œœœ˜;J˜——šœ™L˜0š ž œœœœ œ˜Dšœ,˜,Mšœ œ œ)œ™QMšœœ œœ ˜5Mšœ œœ˜?M˜—Mšœœœœ˜"Mšœ œ˜EMšœ œœ˜Mšœ˜—š ž œœœœœ ˜LMšœ œ˜*Mšœ!˜'M˜—š ž œœœœœ ˜DJšœ9™9š œœœœœ˜;Jšœ œ œ œ˜1—Jšœ ˜J˜—šž œœœœ œœ œ ˜gJ˜8J˜5J˜—šžœœœ)œ œœœ˜t˜#Jšœ œ œ˜#Jš œ œ œœ œ˜EJ˜—Jšœ/˜5J˜M˜——šœ™šž œœœœ ˜FMšœ1˜7M˜—š ž œœœœ#œœ ˜iMš œœœœœ œ˜1˜+Mš œœœœœ™>Mš œœœœ œœœ ˜IMšœ5˜5Mšœ œ3˜BMšœœ˜MšœE˜EMšœ ˜ Mšœ˜—Mšœ8˜8Mš œœ*œœœ˜DMšœ˜—J˜Jšœ˜——…—0