DIRECTORY Basics USING [BITAND], Rope USING [Cat, Equal, Fetch, FromChar, Map, MaxLen, ROPE, Size, Substr], RopeEdit USING [AlphaNumericChar, BlankChar, CharProperty, GetCharProp, LowerCase, MaxLen, UpperCase], RopeReader USING [Backwards, Create, Get, GetIndex, GetRope, Peek, ReadOffEnd, Ref, SetIndex, SetPosition], TextFind USING [Finder, PatternErrorCode, Try, TryBackwards], TextFindPrivate, TextLooks USING [FetchLooks, Looks, noLooks, Runs], TextNode USING [Node]; TextFindImpl: CEDAR PROGRAM IMPORTS Basics, TextLooks, Rope, RopeEdit, RopeReader, TextFind, TextFindPrivate EXPORTS TextFind, TextFindPrivate = BEGIN OPEN TextFind; ROPE: TYPE ~ Rope.ROPE; noLooks: TextLooks.Looks ~ TextLooks.noLooks; Node: TYPE ~ TextNode.Node; MalformedPattern: PUBLIC ERROR [ec:PatternErrorCode] = CODE; IsWord: PUBLIC PROC [rope: ROPE, at, atEnd: INT] RETURNS [BOOL] = { IF at > 0 AND RopeEdit.GetCharProp[Rope.Fetch[rope, at-1]] = alphaNumeric THEN RETURN [FALSE]; IF atEnd < Rope.Size[rope] AND RopeEdit.GetCharProp[Rope.Fetch[rope, atEnd]] = alphaNumeric THEN RETURN [FALSE]; RETURN [TRUE]; }; NameLoc: PUBLIC PROC [finder: Finder, name: ROPE] RETURNS [at, atEnd: INT _ 0] = { IF finder # NIL THEN { nameArray: REF TextFindPrivate.NameArray ~ finder.nameArray; IF nameArray = NIL THEN RETURN; FOR i: NAT IN [0..nameArray.length) DO IF Rope.Equal[nameArray[i].name, name] THEN RETURN [nameArray[i].at, nameArray[i].atEnd]; ENDLOOP; }; }; NameLooks: PUBLIC PROC [finder: Finder, name: ROPE] RETURNS [TextLooks.Looks _ TextLooks.noLooks] = { IF finder # NIL THEN { nameArray: REF TextFindPrivate.NameArray ~ finder.nameArray; IF nameArray = NIL THEN RETURN; FOR i: NAT IN [0..nameArray.length) DO IF Rope.Equal[nameArray[i].name, name] THEN RETURN [nameArray[i].looks]; ENDLOOP; }; }; Find: PUBLIC PROC [pattern, text: Node, literal, word, ignoreLooks, ignoreCase, looksExact, addBounds: BOOL _ FALSE, patternStart: INT _ 0, patternLen: INT _ LAST[INT], textStart: INT _ 0, textLen: INT _ LAST[INT], interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { [found,at,atEnd,before,after] _ TextFind.Try[Create[pattern,literal,word,ignoreLooks,ignoreCase,addBounds,patternStart,patternLen], text,textStart,textLen,looksExact,interrupt] }; BackwardsFind: PUBLIC PROC [pattern, text: Node, literal, word, ignoreLooks, ignoreCase, looksExact, addBounds: BOOL _ FALSE, patternStart: INT _ 0, patternLen: INT _ LAST[INT], textStart: INT _ 0, textLen: INT _ LAST[INT], interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { [found,at,atEnd,before,after] _ TextFind.TryBackwards[ Create[pattern,literal,word,ignoreLooks,ignoreCase,addBounds,patternStart,patternLen], text,textStart,textLen,looksExact,interrupt] }; Create: PUBLIC PROC [pattern: Node, literal, word, ignoreLooks, ignoreCase, addBounds: BOOL _ FALSE, patternStart: INT _ 0, patternLen: INT _ LAST[INT]] RETURNS [finder: Finder] = { patternRope: ROPE _ pattern.rope; patternRuns: TextLooks.Runs _ pattern.charLooks; RETURN [CreateFromParts[patternRope, patternRuns, literal, word, ignoreLooks, ignoreCase, addBounds, patternStart, patternLen]] }; CreateFromRope: PUBLIC PROC [pattern: ROPE, literal, word, ignoreCase, addBounds: BOOL _ FALSE, patternStart: INT _ 0, patternLen: INT _ LAST[INT]] RETURNS [finder: Finder] = { RETURN [CreateFromParts[pattern, NIL, literal, word, TRUE, ignoreCase, addBounds, patternStart, patternLen]] }; CreateFromParts: PROC [patternRope: ROPE, patternRuns: TextLooks.Runs, literal, word, ignoreLooks, ignoreCase, addBounds: BOOL _ FALSE, patternStart: INT _ 0, patternLen: INT _ LAST[INT]] RETURNS [finder: Finder] = { RETURN[NIL]; }; -- of Create SearchRope: PUBLIC PROC [finder: Finder, rope: Rope.ROPE, start: INT _ 0, len: INT _ RopeEdit.MaxLen, interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { [found, at, atEnd, before, after] _ Search[finder, rope, NIL, start, len, FALSE, interrupt] }; Try: PUBLIC PROC [finder: Finder, text: Node, start: INT _ 0, len: INT _ RopeEdit.MaxLen, looksExact: BOOL _ FALSE, interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { [found, at, atEnd, before, after] _ Search[ finder, text.rope, text.charLooks, start, len, looksExact, interrupt] }; Search: PROC [finder: Finder, rope: ROPE, runs: TextLooks.Runs, start: INT, len: INT, looksExact: BOOL, interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { IF finder.wordSearch THEN DO -- repeat search until find a word [found, at, atEnd, before, after] _ TryToFind[finder, rope, runs, start, len, looksExact, interrupt]; IF NOT found OR (interrupt#NIL AND interrupt^) THEN RETURN; -- failed IF IsWord[rope, at, atEnd] THEN RETURN; -- got it start _ after; -- try again ENDLOOP; [found, at, atEnd, before, after] _ TryToFind[finder, rope, runs, start, len, looksExact, interrupt] }; TryToFind: PROC [finder: Finder, rope: ROPE, runs: TextLooks.Runs, start: INT _ 0, len: INT _ RopeEdit.MaxLen, looksExact: BOOL _ FALSE, interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { RETURN[FALSE, 0, 0, 0, 0]; }; -- of Try -- SearchRopeBackwards: PUBLIC PROC [finder: Finder, rope: Rope.ROPE, start: INT _ 0, len: INT _ RopeEdit.MaxLen, interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { [found, at, atEnd, before, after] _ SearchBackwards[finder, rope, NIL, start, len, FALSE, interrupt] }; TryBackwards: PUBLIC PROC [finder: Finder, text: Node, start: INT _ 0, len: INT _ RopeEdit.MaxLen, looksExact: BOOL _ FALSE, interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { [found, at, atEnd, before, after] _ SearchBackwards[finder, text.rope, text.charLooks, start, len, looksExact, interrupt] }; SearchBackwards: PROC [finder: Finder, rope: ROPE, runs: TextLooks.Runs, start: INT, len: INT, looksExact: BOOL, interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { IF finder.wordSearch THEN DO -- repeat search until find a word [found, at, atEnd, before, after] _ TryToFindBackwards[finder, rope, runs, start, len, looksExact]; IF NOT found OR (interrupt#NIL AND interrupt^) THEN RETURN; -- failed IF IsWord[rope, at, atEnd] THEN RETURN; -- got it len _ before-start; -- try again ENDLOOP; [found, at, atEnd, before, after] _ TryToFindBackwards[finder, rope, runs, start, len, looksExact, interrupt] }; TryToFindBackwards: PROC [finder: Finder, rope: ROPE, runs: TextLooks.Runs, start: INT _ 0, len: INT _ RopeEdit.MaxLen, looksExact: BOOL _ FALSE, interrupt: REF BOOL _ NIL] RETURNS [found: BOOL, at, atEnd, before, after: INT] = { RETURN[FALSE, 0, 0, 0, 0]; }; END. ‚TextFindImpl.mesa Copyright Σ 1985, 1986, 1987, 1988 by Xerox Corporation. All rights reserved. derived from EditorFind.Mesa of Laurel 6 Paxton, February 23, 1983 4:13 pm Maxwell, January 5, 1983 4:03 pm Russ Atkinson, July 25, 1983 3:21 pm Michael Plass, October 19, 1987 10:14:15 am PDT Doug Wyatt, February 19, 1988 11:04:04 am PST Support Operations Forward Backwards Κ°˜codešœ™KšœN™NKšœ(™(Kšœ!™!Kšœ ™ Kšœ$™$Kšœ/™/Kšœ-™-K™—šΟk ˜ Kšœœœ˜Kšœœ,œ˜JKšœ œX˜fKšœ œ[˜kKšœ œ/˜=Kšœ˜Kšœ œ$˜3Kšœ œ˜K˜—KšΠln œœ˜KšœI˜PKšœ˜!šœœœ ˜K˜Kšœœœ˜J˜-Jšœœ˜Kšœœœœ˜œœœ˜pKšœœ˜K˜——šœ ™ K˜š Ÿœœœœœ œ ˜Ršœ œœ˜Kšœ œ.˜