(input: string, f: Finding)
| 480 | } |
| 481 | |
| 482 | function locateSpan(input: string, f: Finding): { start: number; end: number } { |
| 483 | // Re-derive the offset from line/col on the original text. |
| 484 | let offset = 0; |
| 485 | let line = 1; |
| 486 | while (line < f.line && offset < input.length) { |
| 487 | if (input[offset] === "\n") line++; |
| 488 | offset++; |
| 489 | } |
| 490 | offset += f.col - 1; |
| 491 | const pat = PATTERNS_BY_ID[f.id]; |
| 492 | if (!pat) return { start: -1, end: -1 }; |
| 493 | const re = new RegExp(pat.regex.source, withFlags(pat.regex.flags)); |
| 494 | re.lastIndex = Math.max(0, offset - 2); |
| 495 | const m = re.exec(input); |
| 496 | if (!m) return { start: -1, end: -1 }; |
| 497 | const span = m[1] ?? m[0]; |
| 498 | const start = m.index + (m[1] !== undefined ? m[0].indexOf(m[1]) : 0); |
| 499 | return { start, end: start + span.length }; |
| 500 | } |
| 501 | |
| 502 | function inStructuralToken(body: string, start: number, end: number): boolean { |
| 503 | // Markdown link target: [text](...span...). The span may sit anywhere inside |
no test coverage detected