4.2: the ADF property #75
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"marks": [
|
||||||
|
{
|
||||||
|
"attrs": {
|
||||||
|
"href": "",
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
|
"type": "link"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"text": "a",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "paragraph"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "doc",
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[a](<> "")
|
||||||
+5
-4
@@ -43,10 +43,11 @@ normalizes to it through the round-trip.
|
|||||||
CommonMark admits no spelling — the end of a block, inside an ATX heading — or where the node
|
CommonMark admits no spelling — the end of a block, inside an ATX heading — or where the node
|
||||||
carries an attribute, it is the inline directive.
|
carries an attribute, it is the inline directive.
|
||||||
- An empty paragraph — real payloads carry them — is `::paragraph`.
|
- An empty paragraph — real payloads carry them — is `::paragraph`.
|
||||||
- Links `[text](url)`; `<…>` around a destination containing spaces; title in double quotes. A
|
- Links `[text](url)`; `<…>` around a destination containing spaces, `<>` an empty one beside a
|
||||||
backslash escapes a parenthesis the destination leaves unbalanced, and a quote inside the title;
|
title; title in double quotes. A backslash escapes a parenthesis the destination leaves
|
||||||
a balanced pair stays bare. `<url>` autolink form only when the text equals the destination and
|
unbalanced, and a quote inside the title; a balanced pair stays bare. `<url>` autolink form only
|
||||||
the destination is a valid CommonMark autolink (absolute URI).
|
when the text equals the destination and the destination is a valid CommonMark autolink
|
||||||
|
(absolute URI).
|
||||||
- Paragraphs on one line — no soft wrapping; a soft line break in input becomes a single space.
|
- Paragraphs on one line — no soft wrapping; a soft line break in input becomes a single space.
|
||||||
- Entity references in input decode to their characters; output backslash-escapes only where text
|
- Entity references in input decode to their characters; output backslash-escapes only where text
|
||||||
would otherwise parse as syntax, scanning the assembled line rather than each text node: escape
|
would otherwise parse as syntax, scanning the assembled line rather than each text node: escape
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { markSpelling, spellMarkAttributes } from '../mark-spellings.ts'
|
|||||||
import { nodeAttrs, nodeContent, nodeMarks } from '../../adf/document.ts'
|
import { nodeAttrs, nodeContent, nodeMarks } from '../../adf/document.ts'
|
||||||
import { sameMark } from '../../adf/editor-normal.ts'
|
import { sameMark } from '../../adf/editor-normal.ts'
|
||||||
import { slotLineEndingFault, spellLeafDirective } from '../directive-syntax.ts'
|
import { slotLineEndingFault, spellLeafDirective } from '../directive-syntax.ts'
|
||||||
import { spellDestination, spellTitle } from '../link-syntax.ts'
|
import { spellDestination, spellLinkTarget } from '../link-syntax.ts'
|
||||||
import { spellInlineNodeAttributes } from './inline-directive-spelling.ts'
|
import { spellInlineNodeAttributes } from './inline-directive-spelling.ts'
|
||||||
import { spellTextDirective } from '../text-directive.ts'
|
import { spellTextDirective } from '../text-directive.ts'
|
||||||
|
|
||||||
@@ -285,13 +285,11 @@ function emitLink(nodes: readonly AdfNode[], mark: AdfMark, depth: number, range
|
|||||||
const node = nodes[0]
|
const node = nodes[0]
|
||||||
const bare = nodes.length === 1 && node !== undefined && node.type === 'text' && node.text === href && nodeMarks(node).length === depth + 1
|
const bare = nodes.length === 1 && node !== undefined && node.type === 'text' && node.text === href && nodeMarks(node).length === depth + 1
|
||||||
if (bare && title === undefined && isAutolink(href) && !holdsEntityReference(href)) return success({ segments: [syntax(`<${href}>`)] })
|
if (bare && title === undefined && isAutolink(href) && !holdsEntityReference(href)) return success({ segments: [syntax(`<${href}>`)] })
|
||||||
const destination = spellDestination(href, path)
|
const target = spellLinkTarget(href, typeof title === 'string' ? title : undefined, path)
|
||||||
if (!destination.ok) return destination
|
if (!target.ok) return target
|
||||||
const spelledTitle = typeof title === 'string' ? spellTitle(title, path) : success('')
|
|
||||||
if (!spelledTitle.ok) return spelledTitle
|
|
||||||
const inner = emitRun(nodes, depth + 1, range.first, { ...context, bracketed: true })
|
const inner = emitRun(nodes, depth + 1, range.first, { ...context, bracketed: true })
|
||||||
if (!inner.ok) return inner
|
if (!inner.ok) return inner
|
||||||
if (inner.value.carry !== undefined) return inner
|
if (inner.value.carry !== undefined) return inner
|
||||||
return success({ segments: [syntax('['), ...inner.value.segments, syntax(`](${destination.value}${spelledTitle.value})`)] })
|
return success({ segments: [syntax('['), ...inner.value.segments, syntax(`](${target.value})`)] })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,15 @@ export function spellDestination(href: string, path: ConvertErrorPath): Result<s
|
|||||||
return success(escapeUnbalanced(href))
|
return success(escapeUnbalanced(href))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function spellTitle(title: string, path: ConvertErrorPath): Result<string> {
|
export function spellLinkTarget(href: string, title: string | undefined, path: ConvertErrorPath): Result<string> {
|
||||||
|
const destination = spellDestination(href, path)
|
||||||
|
if (!destination.ok || title === undefined) return destination
|
||||||
|
const spelledTitle = spellTitle(title, path)
|
||||||
|
if (!spelledTitle.ok) return spelledTitle
|
||||||
|
return success(`${destination.value === '' ? '<>' : destination.value}${spelledTitle.value}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function spellTitle(title: string, path: ConvertErrorPath): Result<string> {
|
||||||
if (/[\n\r\\]/.test(title)) {
|
if (/[\n\r\\]/.test(title)) {
|
||||||
return failure('unspellable-link', 'no canonical escape spells a backslash or newline in a link title', path)
|
return failure('unspellable-link', 'no canonical escape spells a backslash or newline in a link title', path)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user