10a - numbered lists whose numbering breaks merge as one bullet list keeping their numbers

This commit is contained in:
2026-09-25 19:39:54 +02:00
parent 8572d76ee9
commit dbd80b98c3
+23 -8
View File
@@ -131,24 +131,39 @@ function spliced(sequence: readonly AdfNode[], index: number, replacement: reado
// A numbered list whose markers run past CommonMark's keeps its numbers as text in a bullet list. // A numbered list whose markers run past CommonMark's keeps its numbers as text in a bullet list.
function numberedPastMarkers(list: AdfNode): AdfNode { function numberedPastMarkers(list: AdfNode): AdfNode {
const order = nodeAttrs(list)['order'] const order = nodeAttrs(list)['order']
const items = nodeContent(list) if (list.type !== 'orderedList' || typeof order !== 'number' || order + nodeContent(list).length - 1 <= largestListMarker) return list
if (list.type !== 'orderedList' || typeof order !== 'number' || order + items.length - 1 <= largestListMarker) return list return numberedAsText(list)
return { content: items.map((item, offset) => itemOf(marked(nodeContent(item), `${order + offset}.`))), type: 'bulletList' } }
function numberedAsText(list: AdfNode): AdfNode {
const order = Number(nodeAttrs(list)['order'])
return { content: nodeContent(list).map((item, offset) => itemOf(marked(nodeContent(item), `${order + offset}.`))), type: 'bulletList' }
} }
function mergedLists(blocks: readonly AdfNode[]): AdfNode[] { function mergedLists(blocks: readonly AdfNode[]): AdfNode[] {
const merged: AdfNode[] = [] const merged: AdfNode[] = []
for (const block of blocks) { for (const block of blocks) {
const previous = merged[merged.length - 1] let next = block
if (previous !== undefined && previous.type === block.type && (block.type === 'bulletList' || block.type === 'orderedList')) { for (let previous = merged.at(-1); previous !== undefined && previous.type === next.type && isList(next); previous = merged.at(-1)) {
merged[merged.length - 1] = { ...previous, content: [...nodeContent(previous), ...nodeContent(block)] } merged.pop()
} else { next = joinedLists(previous, next)
merged.push(block)
} }
merged.push(next)
} }
return merged return merged
} }
function isList(block: AdfNode): boolean {
return block.type === 'bulletList' || block.type === 'orderedList'
}
// Two numbered lists whose numbering breaks between them keep their numbers as text in one bullet list.
function joinedLists(first: AdfNode, second: AdfNode): AdfNode {
const breaks = first.type === 'orderedList' && nodeAttrs(second)['order'] !== Number(nodeAttrs(first)['order']) + nodeContent(first).length
const [head, tail] = breaks ? [numberedAsText(first), numberedAsText(second)] : [first, second]
return { ...head, content: [...nodeContent(head), ...nodeContent(tail)] }
}
function paragraph(content: readonly AdfNode[]): AdfNode { function paragraph(content: readonly AdfNode[]): AdfNode {
return { content: [...content], type: 'paragraph' } return { content: [...content], type: 'paragraph' }
} }