mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-13 20:28:28 +01:00
Answer prose round 1: 0 🔴, 6 🟡; list unsupported-node-shape causes as sub-items with their remedies
This commit is contained in:
@@ -452,31 +452,33 @@ Every call can raise these:
|
||||
| --- | --- | --- |
|
||||
| `engine-limit` | in every call: a conversion that passes the longest array, `Map` or `Set` the JavaScript engine builds, or that the engine reports as out of memory; on JavaScriptCore (Bun, Safari), also one that passes its longest string, 2^31 − 1 characters | retry once; if it repeats, writing: set the document aside, keeping the ADF and passing it over or showing it read-only; reading: shorten the markdown, or nest its lists and quotes less deeply |
|
||||
| `unsupported-nesting-depth` | blocks, marks, an attribute's JSON or a carried node's JSON nest past 500 levels | keep the ADF and pass the document over, or show it read-only; flatten the input where you are the one who wrote it |
|
||||
| `unsupported-node-shape` | a node the call cannot read or write in its shape; the list below names each cause | the list below names each cause's remedy |
|
||||
| `unsupported-node-shape` | each cause listed below the table | the remedy beside each cause below |
|
||||
|
||||
`unsupported-node-shape` fires on these causes:
|
||||
|
||||
- **Reading, in `losslessMarkdownToAdf`**: markdown spells a node with an attribute, value,
|
||||
argument or body its type does not take, or without one it needs, puts a line ending or a null
|
||||
character in an `emoji`, `mention` or `status` content slot, wraps a directive mark around nothing
|
||||
or only hard breaks, writes as a directive a node or mark the lossless flavour spells as
|
||||
CommonMark, or puts a reserved directive out of place: `!adf:textBreak{}` parting nothing,
|
||||
`!adf:doc` anywhere but as the whole document. Fix what the message names;
|
||||
- **Reading, in `losslessMarkdownToAdf`.** Fix what the message names;
|
||||
[`spec/flavour.md`](https://github.com/larvit/adf-codec/blob/main/spec/flavour.md) lists every
|
||||
type's attributes and body. For a line ending in a content slot, replace it with a space or write
|
||||
the node as `!adf:carry`; for a null character there, write the node as `!adf:carry`.
|
||||
type's attributes and body. The markdown:
|
||||
- spells a node with an attribute, value, argument or body its type does not take, or without
|
||||
one it needs;
|
||||
- puts a line ending or a null character in an `emoji`, `mention` or `status` content slot:
|
||||
replace a line ending with a space, or, for either, write the node as `!adf:carry`;
|
||||
- wraps a directive mark around nothing or only hard breaks;
|
||||
- writes as a directive a node or mark the lossless flavour spells as CommonMark;
|
||||
- puts `!adf:textBreak{}` where it parts nothing, or `!adf:doc` anywhere but as the whole
|
||||
document.
|
||||
- **Writing, in `adfToLosslessMarkdown`**: a node not riding the carry that carries one mark type
|
||||
twice, a block or a non-text inline node holding `text`, or a leaf block or a non-text inline node
|
||||
holding `content`. Fix what the message names in the ADF.
|
||||
holding `content`. Keep the ADF and show the document read-only; where you built the ADF, fix
|
||||
what the message names.
|
||||
- **Writing, in `adfToPortableMarkdown`**: a line or task list the portable writer cannot spell.
|
||||
This is a bug in this library: report it.
|
||||
- **Past the longest string**: in both writers, a document whose markdown would be longer than
|
||||
536870888 characters, V8's longest string, on every engine, and in `adfToPortableMarkdown` also a
|
||||
document whose text alone is that long, edge whitespace included; in `losslessMarkdownToAdf`, a
|
||||
directive whose plain CommonMark would be that long; in every call, a conversion that passes V8's
|
||||
or SpiderMonkey's longest string. Writing, set the document aside, keeping the ADF and passing it
|
||||
over or showing it read-only; reading, shorten the markdown, or nest its lists and quotes less
|
||||
deeply.
|
||||
- **Past the engine's longest string**:
|
||||
- a writer's markdown would pass 536870888 characters, V8's longest string, on every engine;
|
||||
- in `adfToPortableMarkdown`, the document's text alone would, edge whitespace included;
|
||||
- in `losslessMarkdownToAdf`, a directive's plain CommonMark would;
|
||||
- in every call, a conversion passes V8's or SpiderMonkey's longest string.
|
||||
|
||||
When writing, set the document aside: keep the ADF, and pass it over or show it read-only. When
|
||||
reading, shorten the markdown, or nest its lists and quotes less deeply.
|
||||
|
||||
## The guarantees
|
||||
|
||||
@@ -518,9 +520,9 @@ Serves [Goals](#goals) 1, 4 and 5.
|
||||
the outer brackets literal text, which the spec requires and the reference itself breaks, nesting
|
||||
one `<a>` in the other.
|
||||
- Not every document converts back: `adfToLosslessMarkdown` refuses a document nesting past 500
|
||||
levels, the causes `unsupported-node-shape` lists, and a conversion `engine-limit`
|
||||
stops. Show the refusal and keep the document read-only; saving markdown you could not produce is the loss the round-trip exists to
|
||||
stop.
|
||||
levels, a document meeting a writing or longest-string cause `unsupported-node-shape` lists, and
|
||||
a conversion `engine-limit` stops. Show the refusal and keep the document read-only; saving
|
||||
markdown you could not produce is the loss the round-trip exists to stop.
|
||||
- Both readers narrow GFM's pipe table. A body row whose cell count differs from the header's is
|
||||
an error result, where GFM pads or cuts it. A line holding no `|` ends the table, where GFM reads
|
||||
it as a row.
|
||||
|
||||
@@ -134,7 +134,7 @@ function readNamedMark(type: string, text: string, index: number, path: ConvertE
|
||||
const vocabulary = markVocabularies.get(name)
|
||||
if (vocabulary === undefined) return failure('unsupported-node-shape', `the ${marksAttribute} attribute of ${type} names ${name}, no mark the flavour lists: write the marks as their JSON array, marks="[{\\"type\\":\\"${name}\\"}]"`, path)
|
||||
const start = index + name.length
|
||||
// A quoted value holds no directive, so a malformed pair takes no escape hint.
|
||||
// These {attrs} sit inside the quoted marks value, where no directive opens, so a malformed pair takes no escape hint.
|
||||
const attributes = text.charAt(start) === '{' ? readAttributes(text, start, attributePairCause) : { value: { attributes: new Map<string, DirectiveValue>(), end: start } }
|
||||
if (attributes.fault !== undefined) {
|
||||
return failure('unsupported-node-shape', `the ${name} mark in the ${marksAttribute} attribute of ${type}: ${attributes.fault.message}`, path)
|
||||
|
||||
@@ -227,7 +227,7 @@ document's whole tree. Give the node's path, and name its type and the attribute
|
||||
`emitLeaf` (`emit/inline-line.ts`) and `emitDirectiveBlock` (`emit/adf-to-markdown.ts`)
|
||||
refuse these with `unsupported-node-shape`, though `isAdfDocument` accepts them and the carry
|
||||
round-trips them; `docs/decisions.md` §The code list gives a cause the carry answers no code. Drop
|
||||
them from the emitting half of the README's `unsupported-node-shape` row. Found by the README-goals
|
||||
them from the README's `unsupported-node-shape` cause "Writing, in `adfToLosslessMarkdown`". Found by the README-goals
|
||||
audit, 2026-10-04.
|
||||
|
||||
### 75. Make the generated-markdown property write block carries as `adf:` fences, canonical and hostile.
|
||||
|
||||
Reference in New Issue
Block a user