TextFind.mesa; derived from EditorFind.Mesa of Laurel 6
edited by McGregor, February 8, 1983 11:53 am
edited 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.
DIRECTORY
TiogaNode,
TiogaLooks,
Rope;
TextFind: CEDAR DEFINITIONS =
BEGIN
RefTextNode: TYPE = TiogaNode.RefTextNode;
Offset: TYPE = TiogaNode.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];
name is the name of a subpattern
value is where that subpattern matched last time
NameLooks: PROC [finder: Finder, name: ROPE] RETURNS [looks: TiogaLooks.Looks];
name is the name of a subpattern
value are looks that name had in the pattern
Create: PROC [
pattern: RefTextNode, literal, word, ignoreLooks, ignoreCase, addBounds: BOOLEANFALSE,
patternStart: Offset ← 0, patternLen: Offset ← MaxLen]
RETURNS [finder: Finder];
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
CreateFromRope: PROC [pattern: ROPE, literal, word, ignoreCase, addBounds: BOOLEANFALSE,
patternStart: Offset ← 0, patternLen: Offset ← MaxLen]
RETURNS [finder: Finder];
SearchRope: PROC [finder: Finder, rope: Rope.ROPE,
start: Offset ← 0, len: Offset ← MaxLen, interrupt: REF BOOLNIL]
RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset];
Try: PROC [finder: Finder, text: RefTextNode,
start: Offset ← 0, len: Offset ← MaxLen,
looksExact: BOOLEANFALSE,
interrupt: REF BOOLNIL]
RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset];
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
SearchRopeBackwards: PROC [finder: Finder, rope: Rope.ROPE,
start: Offset ← 0, len: Offset ← MaxLen, interrupt: REF BOOLNIL]
RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset];
TryBackwards: PROC [finder: Finder, text: RefTextNode,
start: Offset ← 0, len: Offset ← MaxLen,
looksExact: BOOLEANFALSE,
interrupt: REF BOOLNIL]
RETURNS [found: BOOLEAN, at, atEnd, before, after: Offset];
searches text for last match in [start..start+len)
i.e., searches down from start+len until reaches start
Find: PROC [pattern, text: RefTextNode,
literal, word, ignoreLooks, ignoreCase, looksExact, addBounds: BOOLEANFALSE,
patternStart: Offset ← 0, patternLen: Offset ← MaxLen,
textStart: Offset ← 0, textLen: Offset ← MaxLen,
interrupt: REF BOOLNIL]
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: BOOLEANFALSE,
patternStart: Offset ← 0, patternLen: Offset ← MaxLen,
textStart: Offset ← 0, textLen: Offset ← MaxLen,
interrupt: REF BOOLNIL]
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] };
END.