diff --git a/collects/scribblings/main/private/search.js b/collects/scribblings/main/private/search.js index 1261302f75..f5770ecdac 100644 --- a/collects/scribblings/main/private/search.js +++ b/collects/scribblings/main/private/search.js @@ -246,26 +246,26 @@ function AdjustResultsNum() { } } -// Terms are compared using Compare(), which returns one of several constants: -// - C_fail: there was no match -// - C_match: there was a match somewhere in the string -// - C_prefix: there was a prefix match (starts at 0) -// - C_rexact: there was a ("real") exact match -// There is also C_exact which can be returned by some of the X: operators. -// It's purpose is to be able to return a result that doesn't affect the -// exactness of the search (for example L:foo searches for a source module that -// is exactly `foo', but it will return C_exact which means that it doesn't -// change whether the match is considered exact or not). Note that these -// constants are ordered, so: -// - < exact => this match is inexact -// - = exact => does not affect the exactness of this match -// - > exact => this is an exact match as far as this predicate goes -// Finally, there is also a C_wordmatch that is used when there is no proper -// match, but all the words in the term match (where a word is an alphanumeric -// sequence or a punctuation, for example, "foo-bar!!" has these words: "foo", -// "-", "bar", "!!") +// Terms are compared using Compare(pat,str), which returns one of several +// constants, in increasing order of success: +// - C_fail: no match +// - C_words: all of the "subwords" in pat matched, where a word is an +// alphanumeric or a punctuation substring (for example, "foo-bar!!" has +// these words: "foo", "-", "bar", "!!"), and a match means a prefix of a +// subword in str matched one of pat's subwords +// - C_match: pat matched somewhere in str +// - C_prefix: pat is a prefix of str +// - C_exact: pat is equal to str +// - C_rexact: there was a ("real") exact match, see below +// Note that the value is searched from the last one and going back, so, for +// example, if pat is a prefix of str the result is C_prefix, and no subword +// matching is attempted. A result of C_exact can be returned by some of the +// `X:' operators: its purpose is to be able to return a result that doesn't +// affect the exactness of the search (for example L:foo searches for a source +// module that is exactly `foo', but it will return C_exact which means that it +// doesn't change whether the match is considered exact or not). var C_fail = 0, C_min = 0, - C_wordmatch = 1, + C_words = 1, C_match = 2, C_prefix = 3, C_exact = 4, @@ -287,18 +287,18 @@ function CompareRx(pat, str) { return C_match; } function MaxCompares(pat, strs) { - var r = C_min; + var r = C_min, c; for (var i=0; i= C_max) return r; + c = Compare(pat,strs[i]); + if (c > r) { if (c >= C_max) return c; else r = c; } } return r; } function MinComparesRx(pats, str) { - var r = C_max; + var r = C_max, c; for (var i=0; i= 0) words[i] = new RegExp("\\b"+words[i]); // (note: seems like removing duplicates is not important since search - // strings will not have them, except, maybe, for an occasional x-y-z) + // strings will not have them, except for dashes in things like x-y-z) return function(x) { var r = Compare(term,x[0]); - // only bindings can be used for exact matches - if (r >= C_exact) return (x[3] ? C_rexact : C_match); - if (r >= C_match) return r; - if (MinComparesRx(words,x[0]) > C_fail) return C_wordmatch; - return r; + // only bindings can be used for rexact matches + if (r >= C_rexact) return (x[3] ? r : C_exact); + if (r > C_words) return r; + if (MinComparesRx(words,x[0]) <= C_fail) return r; + return C_words; } } } function CompileAndTerms(preds) { return function(x) { - var r = C_max; + var r = C_max, c; for (var i=0; i= C_max) return r; + c = preds[i](x); + if (c > r) { if (c >= C_max) return c; else r = c; } } return r; }; @@ -471,27 +472,32 @@ function Search(data, term, is_pre, K) { if (K) { K(ret); return killer; } else return ret; } - var matches = new Array(), exacts = new Array(), wordmatches = new Array(); var i = 0; + var matches = new Array(C_max-C_min); + for (i=0; i 0) { var r, min = C_max, max = C_min; for (var j=0; j max) max = r; } - if (max >= C_rexact && min >= C_exact) exacts.push(data[i]); - else if (min > C_wordmatch) matches.push(data[i]); - else if (min > C_fail) wordmatches.push(data[i]); + if (max >= C_rexact && min >= C_exact) min = C_rexact; + if (min > C_min) matches[C_max - min].push(data[i]); fuel--; i++; } if (i