mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-12 19:58:28 +01:00
Answer principles round 1: 0 🔴, 2 🟡 (0 misread); the end of the text is destinationEnds' last stop, and a nested unclosed paren after a space is pinned
This commit is contained in:
@@ -33,6 +33,7 @@ test('a destination holding an unbalanced unescaped `(` at a space or the end re
|
||||
assert.deepEqual(targets('[a](b(c "t") [d](e)'), [undefined, { destination: 'e', length: 3 }])
|
||||
assert.deepEqual(targets('[a](b(c) "t")'), [{ destination: 'b(c)', length: 10, title: 't' }])
|
||||
assert.deepEqual(targets('[a](b((c) "t")'), [undefined])
|
||||
assert.deepEqual(targets('[a](b(c d))'), [undefined])
|
||||
assert.equal(readDestination('b(c', 0), undefined)
|
||||
assert.equal(readDestination('b(c d', 0), undefined)
|
||||
assert.deepEqual(readDestination('b(c) d', 0), { length: 4, value: 'b(c)' })
|
||||
|
||||
@@ -72,27 +72,20 @@ export function targetMemo(text: string): TargetMemo {
|
||||
return { destinationEnds: undefined, tails: new Map(), text }
|
||||
}
|
||||
|
||||
// Of the starts still open at a stop, only the innermost has its parentheses balanced; the others hold a `(` nothing closed and keep no end.
|
||||
function stopAt(ends: Int32Array, open: number[], index: number): void {
|
||||
const innermost = open.pop()
|
||||
if (innermost !== undefined) ends[innermost] = index
|
||||
open.length = 0
|
||||
}
|
||||
|
||||
// `ends[start]` is where an unbracketed destination from `start` stops, filled in one pass for every start a target can have: just after a `(`, a space or a control character, and 0, where `readDestination`'s run begins.
|
||||
// `ends[start]` is where an unbracketed destination from `start` stops, filled in one pass for every start a target can have: just after a `(`, a space or a control character, and 0, where `readDestination`'s run begins. At a stop only the innermost open start has its parentheses balanced, so the starts below it keep no end.
|
||||
function destinationEnds(text: string): Int32Array {
|
||||
const ends = new Int32Array(text.length + 1)
|
||||
const open = [0]
|
||||
for (let index = 0; index < text.length; index += backslashEscape(text, index) === undefined ? 1 : 2) {
|
||||
let open = [0]
|
||||
for (let index = 0; index <= text.length; index += backslashEscape(text, index) === undefined ? 1 : 2) {
|
||||
const character = text.charAt(index)
|
||||
if (character === '(') open.push(index + 1)
|
||||
const start = character === ')' ? open.pop() : undefined
|
||||
if (start !== undefined) ends[start] = index
|
||||
if (character !== ' ' && !holdsControlCharacter(character)) continue
|
||||
stopAt(ends, open, index)
|
||||
open.push(index + 1)
|
||||
if (index < text.length && character !== ' ' && !holdsControlCharacter(character)) continue
|
||||
const innermost = open.pop()
|
||||
if (innermost !== undefined) ends[innermost] = index
|
||||
open = [index + 1]
|
||||
}
|
||||
stopAt(ends, open, text.length)
|
||||
return ends
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user