Searching
"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.
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;
FinderFromText:
PROC [pattern: Text,
literal, word, ignoreLooks, ignoreCase, addBounds:
BOOL ←
FALSE]
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
FinderFromRope:
PROC [pattern:
ROPE, start:
INT ← 0, len:
INT ← maxLen,
literal, word, ignoreCase, addBounds:
BOOL ←
FALSE]
RETURNS [finder: Finder];
NameLoc:
PROC [finder: Finder, name:
ROPE]
RETURNS [at, atEnd:
INT];
name is the name of a subpattern
value is where that subpattern matched last time
NameLooks:
PROC [finder: Finder, name:
ROPE]
RETURNS [looks: Looks];
name is the name of a subpattern
value are looks that name had in the pattern
SearchDirection:
TYPE ~ {forward, backward};
SearchText:
PROC [finder: Finder, text: Text, looksExact:
BOOL ←
FALSE,
direction: SearchDirection ← forward, interrupt:
REF
BOOL ←
NIL
]
RETURNS [found:
BOOL, at, atEnd, before, after:
INT];
if direction = forward, searches text for first match in [start..start+len)
i.e., searches up from start until reaches start+len
if direction = backward, searches for last match in [start..start+len)
i.e., searches down from start+len until reaches start
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
SearchRope:
PROC [finder: Finder, rope:
ROPE, start:
INT ← 0, len:
INT ← maxLen,
direction: SearchDirection ← forward, interrupt:
REF
BOOL ←
NIL
]
RETURNS [found:
BOOL, at, atEnd, before, after:
INT];
like SearchText, but searches a rope instead of a node
CommentControl:
TYPE = { includeComments, excludeComments, commentsOnly };
Search:
PROC [finder: Finder, span: Span, looksExact:
BOOL ←
FALSE,
commentControl: CommentControl ← includeComments,
checkFormat:
BOOL ←
FALSE, format:
ATOM ←
NIL,
checkStyle:
BOOL ←
FALSE, style:
ATOM ←
NIL,
styleProc:
PROC [Node]
RETURNS [
ATOM] ←
NIL,
direction: SearchDirection ← forward, interrupt:
REF
BOOL ←
NIL
]
RETURNS [found:
BOOL, where: Node, at, atEnd, before, after:
INT];
if direction = forward, searches from span.start to span.end
continues until finds a match or reaches end of span
if direction = backward, searches from span.end to span.start
continues until finds a match or reaches start of span
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
commentControl allows restriction of search to comments/noncomments
if checkFormat is true, then only match in nodes with given format
if checkStyle is true, then only match in nodes with given style
styleProc is supplied so called can determine style for nodes
if just interested in format/style, can pass finder=NIL
if interrupt^ becomes true, will stop searching
SearchApplyProc:
TYPE =
PROC [where: Node, at, atEnd, before, after:
INT]
RETURNS [continue, bumpCount:
BOOL, from, delta:
INT];
arg's are results from Search
if continue is true, SearchApply will Search again starting at "from" in "where"
delta tells change in length caused by the action
SearchApply does the following with delta:
IF where=span.end.node AND span.end.where < maxLen THEN
span.end.where ← span.end.where+delta
if bumpCount is true, SearchApply will increment its result counter
SearchApply:
PROC [finder: Finder, span: Span, proc: SearchApplyProc,
looksExact:
BOOL ←
FALSE, commentControl: CommentControl ← includeComments,
checkFormat:
BOOL ←
FALSE, format:
ATOM ←
NIL,
checkStyle:
BOOL ←
FALSE, style:
ATOM ←
NIL,
styleProc:
PROC [Node]
RETURNS [
ATOM] ←
NIL
]
RETURNS [count:
INT];
finds a span of text and calls proc