|
1 | 1 | // This is mostly broken out for testability |
2 | 2 |
|
3 | | -// This is a custom lookbehind which I'm using instead of \b, because I want links |
4 | | -// following non-word characters to be detectable. All patterns will match so long |
5 | | -// as they follow either the start of the string/line or any whitespace character. |
6 | | -const boundary = "(?<=^| |\t|\n)"; |
| 3 | +// Note to self: it'd be nice if I could just use a lookbehind pattern as the |
| 4 | +// start of my pattern, because then I don't have to make this a multi-stage |
| 5 | +// process. Unfortunately WebKit doesn't currently support that, and so iOS |
| 6 | +// Obsidian won't work with it. |
| 7 | +// WebKit bug for support: https://bugs.webkit.org/show_bug.cgi?id=174931 |
| 8 | +// Desired code: `(?<=^| |\t|\n)` + making the match function simpler. |
7 | 9 |
|
8 | 10 | export class SmartLinksPattern { |
| 11 | + boundary: RegExp = /(^| |\t|\n)$/; |
| 12 | + |
9 | 13 | regexp: RegExp; |
10 | | - replacement: string; |
| 14 | + replacement: string; |
11 | 15 | constructor(pattern: string, replacement: string) { |
12 | | - this.regexp = new RegExp(`${boundary}${pattern}`); |
13 | | - this.replacement = replacement; |
| 16 | + this.regexp = new RegExp(pattern); |
| 17 | + this.replacement = replacement; |
14 | 18 | } |
15 | 19 | match(text: string) : RegExpMatchArray|null { |
16 | | - return text.match(this.regexp); |
| 20 | + const match = text.match(this.regexp); |
| 21 | + if (match) { |
| 22 | + // Because of the above-mentioned lookbehind issue we're doing a |
| 23 | + // second check here, as a manual lookbehind. |
| 24 | + const preceding = text.charAt((match.index ?? 0) - 1); |
| 25 | + if (preceding.match(this.boundary)) { |
| 26 | + return match; |
| 27 | + } |
| 28 | + } |
| 29 | + return null; |
17 | 30 | } |
18 | 31 | } |
19 | 32 |
|
|
0 commit comments