21 - the ADF tables carry ADF's nouns
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import type { AdfDocument, AdfNode } from '../../adf/document.ts'
|
||||
import type { BlockDirective } from '../../adf/block-directives.ts'
|
||||
import type { BlockNode } from '../../adf/block-nodes.ts'
|
||||
import { adfDocumentFault, carriesOnly, nodeAttrs, nodeContent, nodeMarks } from '../../adf/document.ts'
|
||||
import { blockDirective, blockDirectives } from '../../adf/block-directives.ts'
|
||||
import { blockDirectiveForm } from '../block-directive-forms.ts'
|
||||
import { blockNodeNamed, blockNodes } from '../../adf/block-nodes.ts'
|
||||
import { carriedBlock } from '../opaque-carry.ts'
|
||||
import { emitInlineLine } from './inline-line.ts'
|
||||
import { failure, faulted, success, type ConvertErrorPath, type Result } from '../../result.ts'
|
||||
@@ -87,11 +87,11 @@ function interruptsParagraph(node: AdfNode): boolean {
|
||||
}
|
||||
|
||||
function emitBlock(node: AdfNode, path: ConvertErrorPath, depth: number, memo: SpellingMemo | undefined): Result<EmittedBlock> {
|
||||
const directive = blockDirective(node.type)
|
||||
if (directive === undefined) return commonMarkLine(carriedBlock(node, path, depth))
|
||||
const blockNode = blockNodeNamed(node.type)
|
||||
if (blockNode === undefined) return commonMarkLine(carriedBlock(node, path, depth))
|
||||
const readable = readableBlock(node, path, depth, memo)
|
||||
if (readable !== undefined) return readable
|
||||
return emitDirectiveBlock(node, directive, path, depth, () => walkBlocks(nodeContent(node), path, depth + 1, memo))
|
||||
return emitDirectiveBlock(node, blockNode, path, depth, () => walkBlocks(nodeContent(node), path, depth + 1, memo))
|
||||
}
|
||||
|
||||
export function commonMarkSpelling(node: AdfNode, path: ConvertErrorPath, depth: number, memo: SpellingMemo): Result<null> | undefined {
|
||||
@@ -143,18 +143,18 @@ function directivePair(node: AdfNode, opener: string, body: string, headroom: nu
|
||||
return { headroom, spelling: 'directive', text: `${opener}\n${body === '' ? '' : `${body}\n`}${spellDirectiveCloser(node.type)}` }
|
||||
}
|
||||
|
||||
function emitDirectiveBlock(node: AdfNode, directive: BlockDirective, path: ConvertErrorPath, depth: number, walkBody: () => Result<Walk>): Result<EmittedBlock> {
|
||||
function emitDirectiveBlock(node: AdfNode, blockNode: BlockNode, path: ConvertErrorPath, depth: number, walkBody: () => Result<Walk>): Result<EmittedBlock> {
|
||||
if (node.text !== undefined) return failure('unsupported-node-shape', `a ${node.type} carries no text: this one holds text`, path)
|
||||
if (blockDirectiveForm(node.type) === 'leaf' && nodeContent(node).length > 0) return failure('unsupported-node-shape', `a ${node.type} holds no content: this one holds some`, path)
|
||||
if (directive.contentModel === 'code') return emitCodeDirective(node, directive, path, depth)
|
||||
const opener = spellBlockDirectiveOpener(node, directive)
|
||||
if (blockNode.contentModel === 'code') return emitCodeDirective(node, blockNode, path, depth)
|
||||
const opener = spellBlockDirectiveOpener(node, blockNode)
|
||||
if (opener === undefined) return commonMarkLine(carriedBlock(node, path, depth))
|
||||
return emitDirectiveBody(node, directive, opener, path, walkBody)
|
||||
return emitDirectiveBody(node, blockNode, opener, path, walkBody)
|
||||
}
|
||||
|
||||
function emitDirectiveBody(node: AdfNode, directive: BlockDirective, opener: string, path: ConvertErrorPath, walkBody: () => Result<Walk>): Result<EmittedBlock> {
|
||||
function emitDirectiveBody(node: AdfNode, blockNode: BlockNode, opener: string, path: ConvertErrorPath, walkBody: () => Result<Walk>): Result<EmittedBlock> {
|
||||
if (blockDirectiveForm(node.type) === 'leaf') return success({ headroom: Number.POSITIVE_INFINITY, spelling: 'directive', text: opener })
|
||||
if (directive.contentModel === 'inline') {
|
||||
if (blockNode.contentModel === 'inline') {
|
||||
const line = emitInlineLine(nodeContent(node), 'paragraph', path)
|
||||
if (!line.ok) return line
|
||||
return success(directivePair(node, opener, line.value))
|
||||
@@ -184,9 +184,9 @@ function tryCodeBlock(node: AdfNode, path: ConvertErrorPath): Result<EmittedBloc
|
||||
return success(commonMarkText(fencedCodeBlock(slot.kind === 'fence' ? slot.info : '', text.value)))
|
||||
}
|
||||
|
||||
function emitCodeDirective(node: AdfNode, directive: BlockDirective, path: ConvertErrorPath, depth: number): Result<EmittedBlock> {
|
||||
function emitCodeDirective(node: AdfNode, blockNode: BlockNode, path: ConvertErrorPath, depth: number): Result<EmittedBlock> {
|
||||
const slot = languageSlot(nodeAttrs(node)['language'])
|
||||
const opener = spellBlockDirectiveOpener(node, directive, slot.kind === 'attribute' ? [] : ['language'])
|
||||
const opener = spellBlockDirectiveOpener(node, blockNode, slot.kind === 'attribute' ? [] : ['language'])
|
||||
if (opener === undefined) return commonMarkLine(carriedBlock(node, path, depth))
|
||||
const text = codeBlockText(node, path)
|
||||
if (!text.ok) return text
|
||||
@@ -246,7 +246,7 @@ function tryList(node: AdfNode, path: ConvertErrorPath, depth: number, memo: Spe
|
||||
const line = tryListItemLines(item.walk.blocks, ordered ? `${start + offset}. ` : '- ')
|
||||
if (line === undefined) {
|
||||
if (headroom < 1) return tooDeep(path)
|
||||
return emitDirectiveBlock(node, ordered ? blockDirectives.orderedList : blockDirectives.bulletList, path, depth, () => success({ blocks: directiveItems(walked), headroom: headroom - 1 }))
|
||||
return emitDirectiveBlock(node, ordered ? blockNodes.orderedList : blockNodes.bulletList, path, depth, () => success({ blocks: directiveItems(walked), headroom: headroom - 1 }))
|
||||
}
|
||||
lines.push(line)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import type { AdfNode } from '../../adf/document.ts'
|
||||
import type { BlockDirective } from '../../adf/block-directives.ts'
|
||||
import type { BlockNode } from '../../adf/block-nodes.ts'
|
||||
import { blockArgument } from '../block-directive-arguments.ts'
|
||||
import { isBareToken, spellAttributes, spellDirectiveOpener, spellJsonAttribute, spellVocabulary } from '../directive-syntax.ts'
|
||||
import { markValues, marksAttribute } from '../block-directive-marks.ts'
|
||||
import { nodeAttrs, nodeMarks } from '../../adf/document.ts'
|
||||
import { vocabularyPairs } from '../../adf/attribute-vocabulary.ts'
|
||||
|
||||
export function spellBlockDirectiveOpener(node: AdfNode, directive: BlockDirective, spelledByBody: readonly string[] = []): string | undefined {
|
||||
export function spellBlockDirectiveOpener(node: AdfNode, blockNode: BlockNode, spelledByBody: readonly string[] = []): string | undefined {
|
||||
const argumentAttribute = blockArgument(node.type)
|
||||
const slot = bareArgument(node, argumentAttribute)
|
||||
if (slot === undefined) return undefined
|
||||
const spelled = argumentAttribute === undefined ? spelledByBody : [argumentAttribute, ...spelledByBody]
|
||||
const pairs = vocabularyPairs(nodeAttrs(node), directive.attributes, spelled)
|
||||
const pairs = vocabularyPairs(nodeAttrs(node), blockNode.attributes, spelled)
|
||||
if (pairs === undefined) return undefined
|
||||
const spelledPairs = spellVocabulary(pairs)
|
||||
const marks = nodeMarks(node)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { AdfNode } from '../../adf/document.ts'
|
||||
import type { InlineDirective } from '../../adf/inline-directives.ts'
|
||||
import type { InlineNode } from '../../adf/inline-nodes.ts'
|
||||
import { nodeAttrs } from '../../adf/document.ts'
|
||||
import { spellAttributes, spellVocabulary } from '../directive-syntax.ts'
|
||||
import { vocabularyPairs } from '../../adf/attribute-vocabulary.ts'
|
||||
|
||||
export function spellInlineNodeAttributes(node: AdfNode, directive: InlineDirective): string | undefined {
|
||||
const pairs = vocabularyPairs(nodeAttrs(node), directive.attributes, directive.textAttribute === undefined ? [] : [directive.textAttribute])
|
||||
export function spellInlineNodeAttributes(node: AdfNode, inlineNode: InlineNode): string | undefined {
|
||||
const pairs = vocabularyPairs(nodeAttrs(node), inlineNode.attributes, inlineNode.textAttribute === undefined ? [] : [inlineNode.textAttribute])
|
||||
return pairs === undefined ? undefined : spellAttributes(spellVocabulary(pairs))
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { AdfMark, AdfNode } from '../../adf/document.ts'
|
||||
import type { InlineDirective } from '../../adf/inline-directives.ts'
|
||||
import type { InlineNode } from '../../adf/inline-nodes.ts'
|
||||
import { assembleInlineLine, isSyntax, type InlineEscaping, type InlineSegment, type LineContainer, type NodeRange } from './line-escaping.ts'
|
||||
import { carriedInline } from '../opaque-carry.ts'
|
||||
import { claimsLine, holdsNullCharacter, trimTrailingSpace } from '../commonmark/grammar.ts'
|
||||
import { commonMarkLink, linkHref, markSpelling, spellMarkAttributes } from '../mark-spellings.ts'
|
||||
import { escapeUnbalanced, spellDestination } from '../commonmark/link-syntax.ts'
|
||||
import { failure, faulted, success, type ConvertErrorPath, type Result } from '../../result.ts'
|
||||
import { inlineDirective } from '../../adf/inline-directives.ts'
|
||||
import { inlineNodeNamed } from '../../adf/inline-nodes.ts'
|
||||
import { largestNesting } from '../../nesting.ts'
|
||||
import { longestBacktickRun } from '../commonmark/backtick-runs.ts'
|
||||
import { nodeAttrs, nodeContent, nodeMarks } from '../../adf/document.ts'
|
||||
@@ -196,7 +196,7 @@ function nodePath(context: InlineContext, index: number): ConvertErrorPath {
|
||||
|
||||
function carries(node: AdfNode, carried: ReadonlySet<number>, index: number): boolean {
|
||||
if (carried.has(index)) return true
|
||||
return node.type !== 'text' && inlineDirective(node.type) === undefined
|
||||
return node.type !== 'text' && inlineNodeNamed(node.type) === undefined
|
||||
}
|
||||
|
||||
function emitLeaf(node: AdfNode, context: InlineContext, index: number): Result<Emission> {
|
||||
@@ -208,27 +208,27 @@ function emitLeaf(node: AdfNode, context: InlineContext, index: number): Result<
|
||||
}
|
||||
const types = nodeMarks(node).map((mark) => mark.type)
|
||||
if (new Set(types).size !== types.length) return failure('unsupported-node-shape', `a ${node.type} node carries one mark type twice`, path)
|
||||
const directive = inlineDirective(node.type)
|
||||
if (directive === undefined) return emitText(node, context, index, path)
|
||||
if (node.type === 'hardBreak') return emitHardBreak(node, directive, context, index, path)
|
||||
return emitInlineDirective(node, directive, index, path)
|
||||
const inlineNode = inlineNodeNamed(node.type)
|
||||
if (inlineNode === undefined) return emitText(node, context, index, path)
|
||||
if (node.type === 'hardBreak') return emitHardBreak(node, inlineNode, context, index, path)
|
||||
return emitInlineDirective(node, inlineNode, index, path)
|
||||
}
|
||||
|
||||
function emitHardBreak(node: AdfNode, directive: InlineDirective, context: InlineContext, index: number, path: ConvertErrorPath): Result<Emission> {
|
||||
function emitHardBreak(node: AdfNode, inlineNode: InlineNode, context: InlineContext, index: number, path: ConvertErrorPath): Result<Emission> {
|
||||
const empty = refuseContentAndText(node, path)
|
||||
if (!empty.ok) return empty
|
||||
const attributes = spellInlineNodeAttributes(node, directive)
|
||||
const attributes = spellInlineNodeAttributes(node, inlineNode)
|
||||
if (attributes === undefined) return success({ carry: { first: index, last: index } })
|
||||
if (attributes === '' && context.spansLines && !context.atBlockEnd) return success({ segments: [syntax('\\\n')] })
|
||||
return success({ segments: [syntax(spellInlineLeafDirective('hardBreak', attributes))] })
|
||||
}
|
||||
|
||||
function emitInlineDirective(node: AdfNode, directive: InlineDirective, index: number, path: ConvertErrorPath): Result<Emission> {
|
||||
function emitInlineDirective(node: AdfNode, inlineNode: InlineNode, index: number, path: ConvertErrorPath): Result<Emission> {
|
||||
const empty = refuseContentAndText(node, path)
|
||||
if (!empty.ok) return empty
|
||||
const attributes = spellInlineNodeAttributes(node, directive)
|
||||
const attributes = spellInlineNodeAttributes(node, inlineNode)
|
||||
if (attributes === undefined) return success({ carry: { first: index, last: index } })
|
||||
const slot = directive.textAttribute === undefined ? undefined : nodeAttrs(node)[directive.textAttribute]
|
||||
const slot = inlineNode.textAttribute === undefined ? undefined : nodeAttrs(node)[inlineNode.textAttribute]
|
||||
if (slot === undefined) return success({ segments: [syntax(spellInlineLeafDirective(node.type, attributes))] })
|
||||
if (typeof slot !== 'string') return success({ carry: { first: index, last: index } })
|
||||
const spans = slotLineEndingFault(node.type, slot)
|
||||
|
||||
Reference in New Issue
Block a user