Skip to content
Source
Sign inSign up

threadSearch.ts

42 lines1.4 KB

1// A typed straight apostrophe finds a curly one: iOS keyboards type "’".
2const foldCharacters = (text: string) => text.replace(/ς/g, "σ").replace(/[‘’]/g, "'");
3​
4function foldThreadSearchCase(text: string): string {
5 const lowered = foldCharacters(text.toLowerCase());
6 if (lowered.length === text.length) return lowered;
7​
8 let folded = "";
9 for (const character of text) {
10 const loweredCharacter = foldCharacters(character.toLowerCase());
11 folded += loweredCharacter.length === character.length ? loweredCharacter : character;
12 }
13 return folded;
15​
16function scanThreadSearchOccurrences(text: string, query: string, offsets?: number[]): number {
17 if (text.length === 0 || query.length === 0) return 0;
18​
19 const foldedText = foldThreadSearchCase(text);
20 const foldedQuery = foldThreadSearchCase(query);
21 let count = 0;
22 let cursor = 0;
23​
24 while (cursor <= foldedText.length - foldedQuery.length) {
25 const offset = foldedText.indexOf(foldedQuery, cursor);
26 if (offset === -1) break;
27 offsets?.push(offset);
28 count += 1;
29 cursor = offset + foldedQuery.length;
30 }
31 return count;
33​
34export function countThreadSearchOccurrences(text: string, query: string): number {
35 return scanThreadSearchOccurrences(text, query);
37​
38export function findThreadSearchOccurrences(text: string, query: string): number[] {
39 const offsets: number[] = [];
40 scanThreadSearchOccurrences(text, query, offsets);
41 return offsets;