Keep the reserved info string beside the fence it spells, and one fenced-block spelling for both
CI / gate (push) Successful in 5s
CI / gate (push) Successful in 5s
This commit is contained in:
@@ -10,7 +10,7 @@ import { failure, success, type ConvertErrorPath, type Result } from './result.t
|
||||
import { holdsNullCharacter, isThematicBreak } from './commonmark-grammar.ts'
|
||||
import { isAdfDocument } from './adf-document.ts'
|
||||
import { largestNesting } from './nesting.ts'
|
||||
import { longestBacktickRun } from './backtick-runs.ts'
|
||||
import { fencedCodeBlock } from './backtick-runs.ts'
|
||||
|
||||
type BlockContainer = 'directive' | 'document' | 'list-item'
|
||||
type BlockSpelling = 'commonmark' | 'directive'
|
||||
@@ -81,7 +81,7 @@ function interruptsParagraph(node: AdfNode): boolean {
|
||||
function emitBlock(node: AdfNode, path: ConvertErrorPath, depth: number): Result<EmittedBlock> {
|
||||
if (node.type === 'blockquote') return commonMarkContainer(emitBlockquote(node, path, depth))
|
||||
if (node.type === 'bulletList' || node.type === 'orderedList') return commonMarkContainer(emitList(node, path, depth))
|
||||
if (node.type === 'codeBlock') return commonMarkLine(node.attrs?.['language'] === carryName ? carriedBlock(node, path) : emitCodeBlock(node, path))
|
||||
if (node.type === 'codeBlock') return commonMarkLine(emitCodeBlock(node, path))
|
||||
if (node.type === 'heading') return commonMarkLine(emitHeading(node, path))
|
||||
if (node.type === 'paragraph') return emitParagraph(node, path)
|
||||
if (node.type === 'rule') return commonMarkLine(emitRule(node, path))
|
||||
@@ -160,6 +160,7 @@ function emitBlockquote(node: AdfNode, path: ConvertErrorPath, depth: number): R
|
||||
}
|
||||
|
||||
function emitCodeBlock(node: AdfNode, path: ConvertErrorPath): Result<string> {
|
||||
if (node.attrs?.['language'] === carryName) return carriedBlock(node, path)
|
||||
const validation = validateBlockNode(node, ['language'], path)
|
||||
if (!validation.ok) return validation
|
||||
const info = spellCodeFenceInfo(node.attrs?.['language'], path)
|
||||
@@ -174,9 +175,7 @@ function emitCodeBlock(node: AdfNode, path: ConvertErrorPath): Result<string> {
|
||||
if (holdsNullCharacter(child.text)) return failure('unspellable-character', 'a codeBlock holds a null character CommonMark replaces', childPath)
|
||||
text += child.text
|
||||
}
|
||||
const fence = '`'.repeat(Math.max(3, longestBacktickRun(text) + 1))
|
||||
const opening = `${fence}${info.value}`
|
||||
return success(text === '' ? `${opening}\n${fence}` : `${opening}\n${text}\n${fence}`)
|
||||
return success(fencedCodeBlock(info.value, text))
|
||||
}
|
||||
|
||||
function spellCodeFenceInfo(language: JsonValue | undefined, path: ConvertErrorPath): Result<string> {
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
export function fencedCodeBlock(info: string, body: string): string {
|
||||
const fence = '`'.repeat(Math.max(3, longestBacktickRun(body) + 1))
|
||||
return body === '' ? `${fence}${info}\n${fence}` : `${fence}${info}\n${body}\n${fence}`
|
||||
}
|
||||
|
||||
export function longestBacktickRun(text: string): number {
|
||||
let longest = 0
|
||||
let current = 0
|
||||
|
||||
+3
-4
@@ -2,8 +2,8 @@ import type { AdfNode } from './adf-document.ts'
|
||||
import type { JsonSpelling } from './canonical-json.ts'
|
||||
import { failure, success, type ConvertErrorPath, type Result } from './result.ts'
|
||||
import { isJsonValue } from './json-value.ts'
|
||||
import { fencedCodeBlock } from './backtick-runs.ts'
|
||||
import { largestNesting } from './nesting.ts'
|
||||
import { longestBacktickRun } from './backtick-runs.ts'
|
||||
import { serializeCanonicalJson } from './canonical-json.ts'
|
||||
import { spellAttributes, spellStringAttribute } from './directive-attributes.ts'
|
||||
|
||||
@@ -12,8 +12,7 @@ export const carryName = 'adf'
|
||||
export function carriedBlock(node: AdfNode, path: ConvertErrorPath): Result<string> {
|
||||
const json = carriedJson(node, 'two-space', path)
|
||||
if (!json.ok) return json
|
||||
const fence = '`'.repeat(Math.max(3, longestBacktickRun(json.value) + 1))
|
||||
return success(`${fence}${carryName}\n${json.value}\n${fence}`)
|
||||
return success(fencedCodeBlock(carryName, json.value))
|
||||
}
|
||||
|
||||
export function carriedInline(node: AdfNode, path: ConvertErrorPath): Result<string> {
|
||||
@@ -24,7 +23,7 @@ export function carriedInline(node: AdfNode, path: ConvertErrorPath): Result<str
|
||||
|
||||
function carriedJson(node: AdfNode, spelling: JsonSpelling, path: ConvertErrorPath): Result<string> {
|
||||
if (!isJsonValue(node)) {
|
||||
return failure('unsupported-node-shape', `a carried node nests deeper than the ${largestNesting} levels the emitter carries`, path)
|
||||
return failure('unsupported-node-shape', `a carried node's JSON nests deeper than the ${largestNesting} levels the emitter carries`, path)
|
||||
}
|
||||
return success(serializeCanonicalJson(node, spelling))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user