Define the writer panel, split the carry fence into its own changelog entry, and say how an adf: fence stays code
This commit is contained in:
@@ -174,9 +174,9 @@ allow, rendered, shuffled, with no rationale and nothing saying what is implemen
|
||||
settle it; otherwise four more read, five of seven settle it, and less is a missing goal, asked.
|
||||
The verdict lands in `docs/decisions.md`.
|
||||
|
||||
Every new or changed markdown or HTML spelling goes to such a panel, seated by the people who read
|
||||
and write that format (README `## Audience`); a question about what an app relies on seats the
|
||||
developer personas.
|
||||
A writer panel settles every new or changed markdown or HTML spelling: a reader panel whose readers
|
||||
are the people who read and write that format (README `## Audience`). A question about what an app
|
||||
relies on goes to the developer personas instead.
|
||||
|
||||
### Stated numbers
|
||||
|
||||
|
||||
+12
-9
@@ -4,18 +4,21 @@
|
||||
|
||||
- **Breaking:** directives, the inline opaque carry among them (now `!adf:carry{json="…"}`), are
|
||||
spelled under an `!adf:` prefix (`!adf:name … !adf:/name`, `!adf:name[content]{attrs}`,
|
||||
`!adf:name arg {attrs}`) in place of the `:::`/`::`/`:name` forms, and the block carry is a code
|
||||
fence whose info string `adf:<type>` names the node's type, its body the node's JSON without
|
||||
`type`: text holding an unescaped `!adf:` and a code fence whose info string opens `adf:` are
|
||||
claimed, and `adf` is an ordinary code block language. Convert stored markdown per `MIGRATION.md`.
|
||||
`!adf:name arg {attrs}`) in place of the `:::`/`::`/`:name` forms: text holding an unescaped
|
||||
`!adf:` is claimed, and `adf` is an ordinary code block language. Convert stored markdown per
|
||||
`MIGRATION.md`.
|
||||
- **Breaking:** the block carry is a code fence whose info string `adf:<type>` names the node's
|
||||
type, its body the node's JSON without `type`, and a code fence whose info string opens `adf:` is
|
||||
claimed. Convert stored markdown per `MIGRATION.md`.
|
||||
- **Breaking:** `markdownToAdf` and `plainMarkdownToAdf` read markdown holding no block as a
|
||||
document whose `content` is empty, as Atlassian's schema requires; `!adf:doc {content=none}`
|
||||
spells a document holding no `content` key.
|
||||
- `markdownToAdf(adfToMarkdown(doc))` deep-equals `doc`: two adjacent text nodes a reader would
|
||||
join are parted by `!adf:textBreak{}`, an empty `attrs`, `content` or `marks` is spelled
|
||||
`{attrs=empty}`, `{content=empty}` or `{marks=empty}`, `-0` is spelled `-0`, and a `codeBlock`
|
||||
of several text nodes is a fence per node. A `codeBlock` holding other than plain text nodes
|
||||
rides the block carry, where it was refused.
|
||||
- `markdownToAdf(adfToMarkdown(doc))` deep-equals `doc` as JSON, for a document of plain objects as
|
||||
`JSON.parse` builds them: two adjacent text nodes CommonMark would read back as one are parted by
|
||||
`!adf:textBreak{}`, an empty `attrs`, `content` or `marks` is spelled `{attrs=empty}`,
|
||||
`{content=empty}` or `{marks=empty}`, `-0` is spelled `-0`, and a `codeBlock` of several text
|
||||
nodes is a fence per node. A `codeBlock` holding other than plain text nodes rides the block
|
||||
carry, where it was refused.
|
||||
- **Breaking:** `unspellable-link` leaves `ConvertErrorCode`; a link whose `href` or `title` no
|
||||
CommonMark escape spells is written as `!adf:link[text]{attrs}`.
|
||||
- **Breaking:** some directive refusals carry `malformed-directive` where they carried
|
||||
|
||||
+4
-4
@@ -5,9 +5,9 @@
|
||||
Directives moved under the `!adf:` prefix. `0.2.0` reads `0.1.0`'s spelling without an error,
|
||||
turning each directive into text and each carried node into an `adf` code block. Before `0.2.0`
|
||||
reads any `0.1.0` markdown, convert what is stored or in flight (an open editor, a queue) with the
|
||||
recipe below, and rewrite markdown your code writes or matches (templates, prompts, patterns) by
|
||||
the tables below. Stored ADF needs one change: a document `0.1.0` read from empty markdown holds
|
||||
no `content` key, and gets `content: []`, the empty document it meant.
|
||||
recipe below, and rewrite markdown your code writes or matches (templates, prompts, patterns) by the
|
||||
tables below. Stored ADF needs one change: give a document holding no `content` key `content: []`.
|
||||
`0.1.0` read empty markdown to that shape, meaning the empty document.
|
||||
|
||||
### Convert markdown
|
||||
|
||||
@@ -23,7 +23,7 @@ import { markdownToAdf as markdownToAdf010 } from 'adf-codec-0.1'
|
||||
|
||||
function migrateMarkdown(stored: string) {
|
||||
const parsed = markdownToAdf010(stored)
|
||||
// 0.1.0's reader was editor-normal, so a document with no content key always meant an empty one.
|
||||
// 0.1.0 dropped an empty content array, so a document with no content key meant an empty one.
|
||||
return parsed.ok ? adfToMarkdown({ ...parsed.value, content: parsed.value.content ?? [] }) : parsed
|
||||
}
|
||||
```
|
||||
|
||||
@@ -175,7 +175,7 @@ Parsing — `markdownToAdf` and `plainMarkdownToAdf`, and `htmlToAdf` at `0.2.0`
|
||||
|
||||
| Code | Fires when | What you can do |
|
||||
| --- | --- | --- |
|
||||
| `malformed-directive` | an `!adf:` the grammar cannot read — a prefix completing no directive, an unclosed container, `[content]` or `{attrs}`, a closer with no container of its name open, a leaf given a body, `{attrs}` out of order or duplicated, invalid JSON in an opaque carry | write the spelling the message names, or keep it literal: escape the prefix — `\!adf:`, block and inline alike — or wrap a code fence whose info string opens `adf:` in `!adf:codeBlock {language="adf:…"}` with a bare fence |
|
||||
| `malformed-directive` | an `!adf:` the grammar cannot read — a prefix completing no directive, an unclosed container, `[content]` or `{attrs}`, a closer with no container of its name open, a leaf given a body, `{attrs}` out of order or duplicated, invalid JSON in an opaque carry | write the spelling the message names, or keep it literal: escape the prefix — `\!adf:`, block and inline alike — or, for a code fence whose info string opens `adf:`, drop the info string and wrap the fence in `!adf:codeBlock {language="adf:…"}` |
|
||||
| `malformed-pipe-table` | a pipe row that is no pipe table — a missing or ragged `---` delimiter row, an alignment colon in it, or a row not opening with a pipe | open every row with a pipe and give the delimiter row the header's cell count; to keep the lines literal text instead, escape the leading pipe of every one — escaping a single row leaves the next to open a fresh table and fail the same way |
|
||||
| `unknown-directive-name` | a directive whose name is no node or mark this version spells | check the name in `spec/flavour.md`, or escape the prefix as `\!adf:`; the spelling itself is well formed, so a later minor may give the name meaning |
|
||||
| `unmappable-html` | the input holds an HTML construct the documented element set does not map, a comment and a processing instruction among them — at this version that is every raw HTML construct in markdown, the element set landing at `0.2.0` | remove the construct, or write what it holds in the lossless flavour |
|
||||
@@ -198,7 +198,7 @@ emit refuses:
|
||||
| `unspellable-line-start` | a paragraph line begins with a code span whose backticks would read back as a code fence | put any text before the code span |
|
||||
| `unspellable-whitespace` | an `emoji`, `mention` or `status` holds a newline in the text its inline directive spells in the content slot | replace it with a space — an inline directive never spans lines |
|
||||
| `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 carries an attribute, value, argument or body its type does not take, or lacks one it needs — or markdown writes as a directive a node or mark the lossless flavour spells as CommonMark | write the shape the message names, or remove the reserved directive it names; `spec/flavour.md` lists every type's attributes and body |
|
||||
| `unsupported-node-shape` | a node carries an attribute, value, argument or body its type does not take, or lacks one it needs — or markdown writes as a directive a node or mark the lossless flavour spells as CommonMark, or a reserved directive (`!adf:textBreak{}`, `!adf:listBreak`, `!adf:doc`) stands where it parts nothing | make the edit the message opens with; `spec/flavour.md` lists every type's attributes and body |
|
||||
|
||||
## The guarantees
|
||||
|
||||
@@ -213,12 +213,13 @@ Serves Goals 1, 3 and 4.
|
||||
name every exception.
|
||||
- Plain CommonMark is valid input to `markdownToAdf` apart from the raw HTML `unmappable-html`
|
||||
names, with four carve-outs — literal text matching directive, pipe-table or strikethrough syntax,
|
||||
and a code fence whose info string opens `adf:`, are claimed (escapable — `spec/flavour.md`) — and
|
||||
one gap: a CommonMark image fits only as its own title-less paragraph; mid-text and titled images
|
||||
are error results, save an image inside another's description, which flattens into the alt text.
|
||||
Converting back yields the library's canonical spelling, which round-trips byte-identically —
|
||||
where it converts back at all: a parse succeeding is no promise of that, so keep the source until
|
||||
the way back succeeds. ``` ` `` ` ``` reads cleanly and then refuses.
|
||||
and a code fence whose info string opens `adf:`, are claimed (each can be kept literal —
|
||||
`spec/flavour.md`) — and one gap: a CommonMark image fits only as its own title-less paragraph;
|
||||
mid-text and titled images are error results, save an image inside another's description, which
|
||||
flattens into the alt text. Converting back yields the library's canonical spelling, which
|
||||
round-trips byte-identically — where it converts back at all: a parse succeeding is no promise of
|
||||
that, so keep the source until the way back succeeds. ``` ` `` ` ``` reads cleanly and then
|
||||
refuses.
|
||||
- Four CommonMark spellings parse without an error and build a document the reference
|
||||
implementation renders differently: `[](/url)` and `[]()` stay literal text against CommonMark's
|
||||
empty link, a list continuing past a marker change stays one list against CommonMark's two, a
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ The grammar of the extended markdown `adfToMarkdown` emits and `markdownToAdf` p
|
||||
CommonMark is a subset apart from raw HTML (below), with four carve-outs: literal text that matches
|
||||
directive syntax below or reads as a pipe table is claimed by the flavour, a matched `~~` pair
|
||||
spells `strike` (escape the `!adf:`, `|` or `~` to keep it literal), and a code fence whose info
|
||||
string opens `adf:` is the opaque carry (wrap it as a bare fence in
|
||||
string opens `adf:` is the opaque carry (drop the info string and wrap the fence in
|
||||
`!adf:codeBlock {language="adf:…"}` to keep it code) — and one gap: a CommonMark image fits only as
|
||||
its own title-less paragraph — mid-text and titled images are named errors. The emitted form is
|
||||
contract (`docs/decisions.md` §The formats are API). Per-node syntaxes build on this grammar in the
|
||||
|
||||
Reference in New Issue
Block a user