26 - the container stack owns the directive depths, and the escape claim hands over after it records
This commit was merged in pull request #125.
This commit is contained in:
@@ -91,14 +91,15 @@ function escapeClaims(scan: string, escapings: readonly InlineEscaping[], contai
|
|||||||
if (index > line.start + line.text.length) line = scanLine(scan, line.start + line.text.length + 1)
|
if (index > line.start + line.text.length) line = scanLine(scan, line.start + line.text.length + 1)
|
||||||
const escaping = escapings[index]
|
const escaping = escapings[index]
|
||||||
const escapable = escaping === 'backslash' || escaping === 'bracketed'
|
const escapable = escaping === 'backslash' || escaping === 'bracketed'
|
||||||
afterEscape =
|
const claimed: boolean =
|
||||||
(escapable &&
|
(escapable &&
|
||||||
(claimsLineStart(line, index, container) ||
|
(claimsLineStart(line, index, container) ||
|
||||||
mergesWithSyntax(scan, escapings, index) ||
|
mergesWithSyntax(scan, escapings, index) ||
|
||||||
opensConstruct(scan, linkClose, index, escaping === 'bracketed', container, afterEscape))) ||
|
opensConstruct(scan, linkClose, index, escaping === 'bracketed', container, afterEscape))) ||
|
||||||
(escaping === 'bracketed-link-target' &&
|
(escaping === 'bracketed-link-target' &&
|
||||||
((scan.charAt(index) === '`' && opensCodeSpan(scan, index, afterEscape)) || claimsDirectivePrefix(scan, index)))
|
((scan.charAt(index) === '`' && opensCodeSpan(scan, index, afterEscape)) || claimsDirectivePrefix(scan, index)))
|
||||||
if (afterEscape) escaped.add(index)
|
if (claimed) escaped.add(index)
|
||||||
|
afterEscape = claimed
|
||||||
}
|
}
|
||||||
return escaped
|
return escaped
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export type DirectiveBlock = Extract<Block, { kind: 'directive' }>
|
|||||||
|
|
||||||
type ListBlock = Extract<Block, { items: Block[][] }>
|
type ListBlock = Extract<Block, { items: Block[][] }>
|
||||||
|
|
||||||
type OpenDirective = { blocks: Block[]; depths: number[]; index: number; kind: 'directive'; name: string; parent: Block[]; position: SourcePosition }
|
type OpenDirective = { blocks: Block[]; index: number; kind: 'directive'; name: string; parent: Block[]; position: SourcePosition }
|
||||||
|
|
||||||
type EdgeContainer = Extract<Block, { kind: 'blockquote' }> | { blocks: Block[]; indentation: number; kind: 'item'; list: ListBlock }
|
type EdgeContainer = Extract<Block, { kind: 'blockquote' }> | { blocks: Block[]; indentation: number; kind: 'item'; list: ListBlock }
|
||||||
|
|
||||||
@@ -65,6 +65,7 @@ type Line = { column: number; text: string }
|
|||||||
type LeafOpener = { index: number; position: SourcePosition }
|
type LeafOpener = { index: number; position: SourcePosition }
|
||||||
|
|
||||||
type ContainerStack = {
|
type ContainerStack = {
|
||||||
|
directiveDepth: (name: string) => number | undefined
|
||||||
drop: (depth: number) => OpenContainer[]
|
drop: (depth: number) => OpenContainer[]
|
||||||
edges: readonly { container: EdgeContainer; depth: number }[]
|
edges: readonly { container: EdgeContainer; depth: number }[]
|
||||||
open: readonly OpenContainer[]
|
open: readonly OpenContainer[]
|
||||||
@@ -72,7 +73,6 @@ type ContainerStack = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Walk = ParsedBlocks & {
|
type Walk = ParsedBlocks & {
|
||||||
directiveDepths: Map<string, number[]>
|
|
||||||
leaf: OpenLeaf | undefined
|
leaf: OpenLeaf | undefined
|
||||||
leafOpeners: Map<Block[], Map<string, LeafOpener>>
|
leafOpeners: Map<Block[], Map<string, LeafOpener>>
|
||||||
position: SourcePosition
|
position: SourcePosition
|
||||||
@@ -87,7 +87,6 @@ export function parseBlocks(markdown: string): ParsedBlocks {
|
|||||||
const walk: Walk = {
|
const walk: Walk = {
|
||||||
blocks: [],
|
blocks: [],
|
||||||
definitions: new Map(),
|
definitions: new Map(),
|
||||||
directiveDepths: new Map(),
|
|
||||||
leaf: undefined,
|
leaf: undefined,
|
||||||
leafOpeners: new Map(),
|
leafOpeners: new Map(),
|
||||||
position: { line: 1, offset: 0 },
|
position: { line: 1, offset: 0 },
|
||||||
@@ -102,13 +101,16 @@ export function parseBlocks(markdown: string): ParsedBlocks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function containerStack(): ContainerStack {
|
function containerStack(): ContainerStack {
|
||||||
|
const directiveDepths = new Map<string, number[]>()
|
||||||
|
const depthsOf = (name: string): number[] => entryOf(directiveDepths, name, () => [])
|
||||||
const edges: { container: EdgeContainer; depth: number }[] = []
|
const edges: { container: EdgeContainer; depth: number }[] = []
|
||||||
const open: OpenContainer[] = []
|
const open: OpenContainer[] = []
|
||||||
return {
|
return {
|
||||||
|
directiveDepth: (name) => directiveDepths.get(name)?.at(-1),
|
||||||
drop: (depth) => {
|
drop: (depth) => {
|
||||||
const dropped = open.splice(depth)
|
const dropped = open.splice(depth)
|
||||||
for (const container of dropped) {
|
for (const container of dropped) {
|
||||||
if (container.kind === 'directive') container.depths.pop()
|
if (container.kind === 'directive') depthsOf(container.name).pop()
|
||||||
else edges.pop()
|
else edges.pop()
|
||||||
}
|
}
|
||||||
return dropped
|
return dropped
|
||||||
@@ -117,7 +119,7 @@ function containerStack(): ContainerStack {
|
|||||||
open,
|
open,
|
||||||
push: (container) => {
|
push: (container) => {
|
||||||
const depth = open.push(container) - 1
|
const depth = open.push(container) - 1
|
||||||
if (container.kind === 'directive') container.depths.push(depth)
|
if (container.kind === 'directive') depthsOf(container.name).push(depth)
|
||||||
else edges.push({ container, depth })
|
else edges.push({ container, depth })
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -281,8 +283,7 @@ function openDirective(walk: Walk, directive: Extract<DirectiveLine, { kind: 'op
|
|||||||
entryOf(walk.leafOpeners, parent, () => new Map<string, LeafOpener>()).set(name, { index, position })
|
entryOf(walk.leafOpeners, parent, () => new Map<string, LeafOpener>()).set(name, { index, position })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const depths = entryOf(walk.directiveDepths, name, (): number[] => [])
|
walk.stack.push({ blocks: block.blocks, index, kind: 'directive', name, parent, position })
|
||||||
walk.stack.push({ blocks: block.blocks, depths, index, kind: 'directive', name, parent, position })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeDirective(walk: Walk, name: string): void {
|
function closeDirective(walk: Walk, name: string): void {
|
||||||
@@ -302,7 +303,7 @@ function closeDirective(walk: Walk, name: string): void {
|
|||||||
|
|
||||||
// A closer crosses no list item or blockquote edge.
|
// A closer crosses no list item or blockquote edge.
|
||||||
function openDirectiveDepth(walk: Walk, name: string): number | undefined {
|
function openDirectiveDepth(walk: Walk, name: string): number | undefined {
|
||||||
const depth = walk.directiveDepths.get(name)?.at(-1)
|
const depth = walk.stack.directiveDepth(name)
|
||||||
return depth === undefined || depth < (walk.stack.edges.at(-1)?.depth ?? -1) ? undefined : depth
|
return depth === undefined || depth < (walk.stack.edges.at(-1)?.depth ?? -1) ? undefined : depth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1064,7 +1064,7 @@ The done `todo.md` items in full, as they were written. `todo.md` keeps a one-li
|
|||||||
panel's first and second hardest places. `escapeClaims` hands each predicate the one fact
|
panel's first and second hardest places. `escapeClaims` hands each predicate the one fact
|
||||||
it reads — whether the character before was escaped — and `escapeClosedRuns` takes that
|
it reads — whether the character before was escaped — and `escapeClosedRuns` takes that
|
||||||
pass's set read-only and returns the whole. `containerStack` is the one writer of the stack,
|
pass's set read-only and returns the whole. `containerStack` is the one writer of the stack,
|
||||||
`edges` and each directive's `depths`, all read-only elsewhere; deriving `edges` from the
|
`edges` and the open directives' depths by name, all read-only elsewhere; deriving `edges` from the
|
||||||
stack instead makes every line walk the open directives, quadratic in their nesting.
|
stack instead makes every line walk the open directives, quadratic in their nesting.
|
||||||
|
|
||||||
## 5 — Ship `0.1.0`
|
## 5 — Ship `0.1.0`
|
||||||
|
|||||||
Reference in New Issue
Block a user