mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-12 11:48:29 +01:00
Answer stability round 1: 1 🔴, 2 🟡 (0 misread); hold a pair whose opener may capture a held pair's delimiter, draw repeated units, pin the carry guards
This commit is contained in:
@@ -217,7 +217,11 @@ const lineLeaf = fc.oneof(
|
||||
{ arbitrary: fc.record({ attrs: fc.constantFrom({ id: 'a' }, { id: 'a', odd: 'b' }), marks: lineMarks }).map((held): AdfNode => ({ ...held, type: 'mention' })), weight: 1 },
|
||||
)
|
||||
export const lineContainer = fc.constantFrom<LineContainer>('heading', 'paragraph', 'table-cell')
|
||||
export const markedLine = fc.array(lineLeaf, { maxLength: 10, minLength: 1 })
|
||||
// A unit repeated is the line where one misread run re-pairs every copy after it.
|
||||
const repeatedUnit = fc
|
||||
.tuple(fc.array(lineLeaf, { maxLength: 2 }), fc.array(lineLeaf, { maxLength: 3, minLength: 1 }), fc.integer({ max: 5, min: 2 }), fc.array(lineLeaf, { maxLength: 2 }))
|
||||
.map(([head, unit, repeats, tail]) => [...head, ...Array.from({ length: repeats }, () => unit.map((node) => ({ ...node }))).flat(), ...tail])
|
||||
export const markedLine = fc.oneof(fc.array(lineLeaf, { maxLength: 10, minLength: 1 }), repeatedUnit)
|
||||
|
||||
export const adfDocument = fc.oneof(
|
||||
{ arbitrary: fc.array(positions.block, { depthIdentifier, maxLength: 4, minLength: 1 }).map((content): AdfDocument => ({ content, type: 'doc', version: 1 })), weight: 30 },
|
||||
|
||||
@@ -19,6 +19,8 @@ test('spells a line alike taking every fallback a pass finds or the first alone'
|
||||
[[{ marks: [{ type: 'em' }], text: 'a', type: 'text' }, { marks: [{ type: 'em' }, { type: 'strike' }, { type: 'strong' }], text: 'a', type: 'text' }, { text: 'a', type: 'text' }], 'paragraph'],
|
||||
[[1, 2, 3].flatMap(() => [{ text: 'un', type: 'text' }, { marks: [{ type: 'em' }, { type: 'strong' }], text: '-r', type: 'text' }]), 'paragraph'],
|
||||
[[{ text: 'un', type: 'text' }, { marks: [{ type: 'em' }, { type: 'strong' }], text: '-r', type: 'text' }, { marks: [{ type: 'strike' }], text: 'un', type: 'text' }, { marks: [{ type: 'strike' }, { type: 'em' }, { type: 'strong' }], text: '-r', type: 'text' }, { text: 'z', type: 'text' }], 'paragraph'],
|
||||
[[{ marks: [{ type: 'strike' }], text: ' b', type: 'text' }, { marks: [{ type: 'em' }], text: '!-', type: 'text' }], 'paragraph'],
|
||||
[[{ marks: [{ type: 'strike' }], text: 'r', type: 'text' }, { marks: [{ type: 'strike' }, { type: 'strong' }, { type: 'em' }], text: '[ ', type: 'text' }, ...[1, 2, 3, 4, 5].map(() => ({ marks: [{ type: 'strike' }], text: ' ', type: 'text' }))], 'heading'],
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
@@ -333,11 +333,22 @@ function misflankedHighlights(placed: readonly PlacedSegment[], output: string):
|
||||
return misflanked
|
||||
}
|
||||
|
||||
// A pair falls with the first where one run per pass would take it back too: one of its delimiters cannot flank however the unsettled pairs fall, and taking it back moves no delimiter another verdict reads.
|
||||
// A pair falls with the first where one run per pass would take it back too: one of its delimiters cannot flank however the unsettled pairs fall.
|
||||
function fallsWithFirst(sweep: PairSweep, judged: number): boolean {
|
||||
if (!fallsCleanly(sweep, judged)) return false
|
||||
const spellings = pairSpellings(sweep, judged, judged)
|
||||
return spellings !== undefined && spellings.every((character) => !mayFlank(sweep, judged, character, 'opener') || !mayFlank(sweep, judged, character, 'closer'))
|
||||
return spellings !== undefined && spellings.every((character) => !mayFlank(sweep, judged, character, 'opener') || (!mayFlank(sweep, judged, character, 'closer') && !holdsAlike(sweep, judged, character)))
|
||||
}
|
||||
|
||||
// An opener that may open can pair with a delimiter of its own character inside, so one run per pass may take back a pair standing there first.
|
||||
function holdsAlike({ fallen, pairs }: PairSweep, judged: number, character: string): boolean {
|
||||
const pair = pairs[judged]
|
||||
for (let held = judged - 1; pair !== undefined && held >= 0; held -= 1) {
|
||||
const inner = pairs[held]
|
||||
if (inner === undefined || inner.closer < pair.opener) return false
|
||||
if (fallen[held] === 0 && (inner.delimiter.length === 1 ? character !== '~' : inner.delimiter.startsWith(character))) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// A carry splits every pair holding it, so a carried pair holds no pair that may fall first; a dropped pair keeps its leaves where no run merges at its ends.
|
||||
|
||||
@@ -21,6 +21,9 @@ test('reduces a line alike dropping every run a pass may or the first alone', ()
|
||||
[[1, 2, 3].flatMap(() => [{ marks: [{ type: 'em' }, { type: 'strike' }, { type: 'strong' }], text: '(', type: 'text' }, { attrs: { id: 'a' }, type: 'mention' }]), 'paragraph'],
|
||||
[[{ text: 'z', type: 'text' }, ...[1, 2, 3].flatMap(() => [{ marks: [{ type: 'strike' }], text: '(b', type: 'text' }, { marks: [{ type: 'em' }], text: '(b', type: 'text' }])], 'paragraph'],
|
||||
[[...[1, 2, 3].flatMap(() => [{ marks: [{ type: 'strike' }], text: 'b(', type: 'text' }, { marks: [{ type: 'em' }], text: 'b(', type: 'text' }]), { text: 'z', type: 'text' }], 'paragraph'],
|
||||
[[...[1, 2, 3].flatMap(() => [{ marks: [{ type: 'em' }, { type: 'strong' }], text: '(', type: 'text' }, { marks: [{ type: 'em' }], text: '(', type: 'text' }]), { text: 'a', type: 'text' }], 'paragraph'],
|
||||
[[...[1, 2, 3, 4, 5].flatMap(() => [{ marks: [{ type: 'em' }, { type: 'strong' }], text: '~** ', type: 'text' }, { marks: [{ type: 'em' }], text: '- _', type: 'text' }]), { text: 'r', type: 'text' }], 'table-cell'],
|
||||
[[...[1, 2, 3].flatMap(() => [{ marks: [{ type: 'em' }, { type: 'strong' }], text: ' ~~ ', type: 'text' }, { marks: [{ type: 'em' }, { type: 'strike' }, { type: 'strong' }], text: ')', type: 'text' }]), { text: 'a', type: 'text' }, { marks: [{ type: 'strike' }, { type: 'strong' }], text: '.unun', type: 'text' }], 'heading'],
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user