DIRECTORY TextNode, TextLooks, Rope; TextFind: CEDAR DEFINITIONS = BEGIN RefTextNode: TYPE = TextNode.RefTextNode; Offset: TYPE = TextNode.Offset; ROPE: TYPE = Rope.ROPE; MaxLen: Offset = LAST[Offset]; CR: CHAR = 'M-100B; MalformedPattern: ERROR [ec:PatternErrorCode]; PatternErrorCode: TYPE = { toobig, -- pattern too long endquote, -- pattern ends with ' endtilda, -- pattern ends with ~ boundary, -- pattern has | inside rather than at beginning or end missingNameEnd, -- pattern has < without matching > unmatchedNameEnd -- pattern has > without previous < }; Finder: TYPE = REF FinderRec; FinderRec: TYPE; NameLoc: PROC [finder: Finder, name: ROPE] RETURNS [at, atEnd: Offset]; NameLooks: PROC [finder: Finder, name: ROPE] RETURNS [looks: TextLooks.Looks]; Create: PROC [ pattern: RefTextNode, literal, word, ignoreLooks, ignoreCase, addBounds: BOOLEAN _ FALSE, patternStart: Offset _ 0, patternLen: Offset _ MaxLen] RETURNS [finder: Finder]; CreateFromRope: PROC [pattern: ROPE, literal, word, ignoreCase, addBounds: BOOLEAN _ FALSE, patternStart: Offset _ 0, patternLen: Offset _ MaxLen] RETURNS [finder: Finder]; SearchRope: PROC [finder: Finder, rope: Rope.ROPE, start: Offset _ 0, len: Offset _ MaxLen, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset]; Try: PROC [finder: Finder, text: RefTextNode, start: Offset _ 0, len: Offset _ MaxLen, looksExact: BOOLEAN _ FALSE, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset]; SearchRopeBackwards: PROC [finder: Finder, rope: Rope.ROPE, start: Offset _ 0, len: Offset _ MaxLen, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset]; TryBackwards: PROC [finder: Finder, text: RefTextNode, start: Offset _ 0, len: Offset _ MaxLen, looksExact: BOOLEAN _ FALSE, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset]; Find: PROC [pattern, text: RefTextNode, literal, word, ignoreLooks, ignoreCase, looksExact, addBounds: BOOLEAN _ FALSE, patternStart: Offset _ 0, patternLen: Offset _ MaxLen, textStart: Offset _ 0, textLen: Offset _ MaxLen, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset] = INLINE { [found,at,atEnd,before,after] _ Try[Create[pattern,literal,word,ignoreLooks,ignoreCase,addBounds,patternStart,patternLen], text,textStart,textLen,looksExact,interrupt] }; BackwardsFind: PROC [pattern, text: RefTextNode, literal, word, ignoreLooks, ignoreCase, looksExact, addBounds: BOOLEAN _ FALSE, patternStart: Offset _ 0, patternLen: Offset _ MaxLen, textStart: Offset _ 0, textLen: Offset _ MaxLen, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset] = INLINE { [found,at,atEnd,before,after] _ TryBackwards[ Create[pattern,literal,word,ignoreLooks,ignoreCase,addBounds,patternStart,patternLen], text,textStart,textLen,looksExact,interrupt] }; Start: PROC; -- for initialization only END. ò-- TextFind.mesa -- derived from EditorFind.Mesa of Laurel 6 -- written by Bill Paxton, May 1981 -- last edit by Paxton, December 30, 1982 10:33 am -- This module provides a "Find" operation for text nodes -- The pattern is given as a substring of a text node -- The text to be searched is also a substring of a text node -- The search can be in either direction within the substring -- If a match character in the pattern has looks, -- the looks of the matching character(s) in the text will include those looks. -- For example, if the pattern includes a * with looks x and y, -- the characters matching the * will have looks x and y too. -- The matching characters may have other looks too. -- name is the name of a subpattern -- value is where that subpattern matched last time -- name is the name of a subpattern -- value are looks that name had in the pattern -- creates a record containing a "compiled" version of the pattern -- if literal is true, each character in pattern is taken literally -- if word flag is true, pattern only matches if no adjacent letters or digits -- if ignoreLooks is true, then ignore the looks of the pattern characters -- if ignoreCase is false, then alpha chars in pattern must match case -- otherwise, they can match either upper or lower -- if addBounds is true, add |'s to both ends of pattern -- searches text for first match in [start..start+len) -- i.e., searches up from start until reaches start+len -- if finds a match, returns with found = true, -- at = beginning of match or location corresponding to { in pattern -- atEnd = end of match or location corresponding to } in pattern -- after = end of entire match, which may be > atEnd if used } in pattern -- before = start of entire match, which may be < at if used { in pattern -- if looksExact is true, then match by equality, else by subset -- if interrupt^ becomes true, will stop searching -- searches text for last match in [start..start+len) -- i.e., searches down from start+len until reaches start -- ***** Initialization Ê\˜JšÏc™Jš+™+Jš#™#Jš2™2J˜Jš9™9Jš5™5Jš=™=Jš=™=J˜š1™1šO™OJš?™?Jš=™=Jš4™4J˜——JšÏk ˜ J˜ J˜ J˜J˜Jšœ žœ˜Jšž˜J˜Jšœ žœ˜)Jšœžœ˜Jšžœžœžœ˜Jšœžœ ˜Jšžœžœ ˜J˜Jšœžœ˜.šœžœ˜Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ 7˜AJšœ#˜3Jšœ#˜4J˜J˜—Jšœžœžœ ˜Jšœ žœ˜J˜šÏnœžœžœžœ˜GJš#™#Jš3™3J˜—šŸ œžœžœžœ˜NJš#™#Jš/™/J˜—šŸœžœ˜JšœIžœžœ˜YJ˜6Jšžœ˜JšB™BJšC™CJšN™NJšJ™JšF™FJš2™2—Jš8™8J˜—š Ÿœžœ žœ(žœžœ˜[J˜6Jšžœ˜J˜—šŸ œžœžœ˜2Jš œ'žœ žœžœžœ˜CJšžœ žœ$˜;J˜—šŸœžœ$˜-J˜(Jšœ žœž˜Jšœ žœžœžœ˜Jšžœ žœ$˜;š6™6Jš7™7—Jš/™/JšD™DJšA™AJšI™IJšI™IJš@™@Jšœ2™2J˜—šŸœžœžœ˜;Jš œ'žœ žœžœžœ˜CJšžœ žœ$˜;J˜—šŸ œžœ$˜6J˜(Jšœ žœž˜Jšœ žœžœžœ˜Jšžœ žœ$˜;š5™5Jš9™9J˜——šŸœžœ˜'Jšœ?žœžœ˜OJ˜6Jšœ/ž˜0Jšœ žœžœžœ˜Jšžœ žœ&žœ˜E˜˜ZJšœ/˜/J˜———šŸ œžœ˜0Jšœ?žœžœ˜OJ˜6Jšœ/ž˜0Jšœ žœžœžœ˜Jšžœ žœ&žœ˜E˜-J˜VJšœ/˜/J˜J˜——Jš™J˜JšŸœžœ˜'J˜Jšžœ˜J˜—…— žì