1 | ;
|
2 | /*-----------------------------------------------------------------------------
|
3 | | Copyright (c) 2014-2017, PhosphorJS Contributors
|
4 | |
|
5 | | Distributed under the terms of the BSD 3-Clause License.
|
6 | |
|
7 | | The full license is in the file LICENSE, distributed with this software.
|
8 | |----------------------------------------------------------------------------*/
|
9 | Object.defineProperty(exports, "__esModule", { value: true });
|
10 | /**
|
11 | * The namespace for string-specific algorithms.
|
12 | */
|
13 | var StringExt;
|
14 | (function (StringExt) {
|
15 | /**
|
16 | * Find the indices of characters in a source text.
|
17 | *
|
18 | * @param source - The source text which should be searched.
|
19 | *
|
20 | * @param query - The characters to locate in the source text.
|
21 | *
|
22 | * @param start - The index to start the search.
|
23 | *
|
24 | * @returns The matched indices, or `null` if there is no match.
|
25 | *
|
26 | * #### Complexity
|
27 | * Linear on `sourceText`.
|
28 | *
|
29 | * #### Notes
|
30 | * In order for there to be a match, all of the characters in `query`
|
31 | * **must** appear in `source` in the order given by `query`.
|
32 | *
|
33 | * Characters are matched using strict `===` equality.
|
34 | */
|
35 | function findIndices(source, query, start) {
|
36 | if (start === void 0) { start = 0; }
|
37 | var indices = new Array(query.length);
|
38 | for (var i = 0, j = start, n = query.length; i < n; ++i, ++j) {
|
39 | j = source.indexOf(query[i], j);
|
40 | if (j === -1) {
|
41 | return null;
|
42 | }
|
43 | indices[i] = j;
|
44 | }
|
45 | return indices;
|
46 | }
|
47 | StringExt.findIndices = findIndices;
|
48 | /**
|
49 | * A string matcher which uses a sum-of-squares algorithm.
|
50 | *
|
51 | * @param source - The source text which should be searched.
|
52 | *
|
53 | * @param query - The characters to locate in the source text.
|
54 | *
|
55 | * @param start - The index to start the search.
|
56 | *
|
57 | * @returns The match result, or `null` if there is no match.
|
58 | * A lower `score` represents a stronger match.
|
59 | *
|
60 | * #### Complexity
|
61 | * Linear on `sourceText`.
|
62 | *
|
63 | * #### Notes
|
64 | * This scoring algorithm uses a sum-of-squares approach to determine
|
65 | * the score. In order for there to be a match, all of the characters
|
66 | * in `query` **must** appear in `source` in order. The index of each
|
67 | * matching character is squared and added to the score. This means
|
68 | * that early and consecutive character matches are preferred, while
|
69 | * late matches are heavily penalized.
|
70 | */
|
71 | function matchSumOfSquares(source, query, start) {
|
72 | if (start === void 0) { start = 0; }
|
73 | var indices = findIndices(source, query, start);
|
74 | if (!indices) {
|
75 | return null;
|
76 | }
|
77 | var score = 0;
|
78 | for (var i = 0, n = indices.length; i < n; ++i) {
|
79 | var j = indices[i] - start;
|
80 | score += j * j;
|
81 | }
|
82 | return { score: score, indices: indices };
|
83 | }
|
84 | StringExt.matchSumOfSquares = matchSumOfSquares;
|
85 | /**
|
86 | * A string matcher which uses a sum-of-deltas algorithm.
|
87 | *
|
88 | * @param source - The source text which should be searched.
|
89 | *
|
90 | * @param query - The characters to locate in the source text.
|
91 | *
|
92 | * @param start - The index to start the search.
|
93 | *
|
94 | * @returns The match result, or `null` if there is no match.
|
95 | * A lower `score` represents a stronger match.
|
96 | *
|
97 | * #### Complexity
|
98 | * Linear on `sourceText`.
|
99 | *
|
100 | * #### Notes
|
101 | * This scoring algorithm uses a sum-of-deltas approach to determine
|
102 | * the score. In order for there to be a match, all of the characters
|
103 | * in `query` **must** appear in `source` in order. The delta between
|
104 | * the indices are summed to create the score. This means that groups
|
105 | * of matched characters are preferred, while fragmented matches are
|
106 | * penalized.
|
107 | */
|
108 | function matchSumOfDeltas(source, query, start) {
|
109 | if (start === void 0) { start = 0; }
|
110 | var indices = findIndices(source, query, start);
|
111 | if (!indices) {
|
112 | return null;
|
113 | }
|
114 | var score = 0;
|
115 | var last = start - 1;
|
116 | for (var i = 0, n = indices.length; i < n; ++i) {
|
117 | var j = indices[i];
|
118 | score += j - last - 1;
|
119 | last = j;
|
120 | }
|
121 | return { score: score, indices: indices };
|
122 | }
|
123 | StringExt.matchSumOfDeltas = matchSumOfDeltas;
|
124 | /**
|
125 | * Highlight the matched characters of a source text.
|
126 | *
|
127 | * @param source - The text which should be highlighted.
|
128 | *
|
129 | * @param indices - The indices of the matched characters. They must
|
130 | * appear in increasing order and must be in bounds of the source.
|
131 | *
|
132 | * @param fn - The function to apply to the matched chunks.
|
133 | *
|
134 | * @returns An array of unmatched and highlighted chunks.
|
135 | */
|
136 | function highlight(source, indices, fn) {
|
137 | // Set up the result array.
|
138 | var result = [];
|
139 | // Set up the counter variables.
|
140 | var k = 0;
|
141 | var last = 0;
|
142 | var n = indices.length;
|
143 | // Iterator over each index.
|
144 | while (k < n) {
|
145 | // Set up the chunk indices.
|
146 | var i = indices[k];
|
147 | var j = indices[k];
|
148 | // Advance the right chunk index until it's non-contiguous.
|
149 | while (++k < n && indices[k] === j + 1) {
|
150 | j++;
|
151 | }
|
152 | // Extract the unmatched text.
|
153 | if (last < i) {
|
154 | result.push(source.slice(last, i));
|
155 | }
|
156 | // Extract and highlight the matched text.
|
157 | if (i < j + 1) {
|
158 | result.push(fn(source.slice(i, j + 1)));
|
159 | }
|
160 | // Update the last visited index.
|
161 | last = j + 1;
|
162 | }
|
163 | // Extract any remaining unmatched text.
|
164 | if (last < source.length) {
|
165 | result.push(source.slice(last));
|
166 | }
|
167 | // Return the highlighted result.
|
168 | return result;
|
169 | }
|
170 | StringExt.highlight = highlight;
|
171 | /**
|
172 | * A 3-way string comparison function.
|
173 | *
|
174 | * @param a - The first string of interest.
|
175 | *
|
176 | * @param b - The second string of interest.
|
177 | *
|
178 | * @returns `-1` if `a < b`, else `1` if `a > b`, else `0`.
|
179 | */
|
180 | function cmp(a, b) {
|
181 | return a < b ? -1 : a > b ? 1 : 0;
|
182 | }
|
183 | StringExt.cmp = cmp;
|
184 | })(StringExt = exports.StringExt || (exports.StringExt = {}));
|