4.7 KiB
The HTML dialect
The HTML adfToHtml writes: semantic elements for the nodes and marks below, and the carry element
for every other node (docs/decisions.md §The HTML dialect). The written form is contract
(docs/decisions.md §The formats are API).
Blocks
One block a line: blocks are separated by a line feed, and a document holding any ends with one. A
document whose content is an empty array is the empty string.
| ADF | HTML |
|---|---|
paragraph |
<p>…</p> |
heading, level 1 to 6 |
<h1>…</h1> to <h6>…</h6> |
blockquote |
<blockquote>, a line feed, its blocks, a line feed, </blockquote> |
bulletList |
<ul>, a line feed, its items a line each, a line feed, </ul> |
orderedList |
as bulletList with <ol>; <ol start="3"> for an order of 3, a safe integer; no start where the list holds no order |
listItem |
<li>…</li>: a first paragraph holding content bare, its inline content straight after <li>, then each other block after a line feed and a line feed before </li>; with no bare paragraph, <li>, a line feed, its blocks, a line feed, </li> |
codeBlock |
<pre><code class="language-js">…</code></pre>, the language one token holding no whitespace; no class where it holds no language |
rule |
<hr> |
mediaSingle, centered, holding one external media |
<p><img src="…" alt="…"></p>, no alt where the media holds none; <p><a href="…"><img …></a></p> where a link marks it |
A container holding no content key is its element holding nothing: <blockquote></blockquote>,
<ul></ul>, <li></li>; so is a paragraph or heading, <p></p>.
Inline
| ADF | HTML |
|---|---|
text |
its text, escaped |
em, strong, code |
<em>, <strong>, <code> around the text |
link, holding href and an optional title |
<a href="…" title="…"> around the text |
hardBreak |
<br> |
A text node's marks nest in the order its marks array lists them, the first outermost:
<strong><em>manual</em></strong>. Each text node writes its own elements, so two text nodes a link
marks are two <a> elements.
Escaping
Text and attribute values escape &, <, > and " as &, <, > and ",
and a carriage return as , which an HTML parser would otherwise read as a line feed.
Attribute values are double-quoted. A link's href and an image's src are the URL as the ADF
holds it, whatever its scheme (docs/decisions.md §HTML writes a URL as the ADF holds it, whatever
its scheme).
The carry element
A node the sections above cannot write where it stands is the carry element: <div> in block
position, <span> inline, of class adf-carry, holding the node's JSON in data-adf and showing
the node's text.
<div class="adf-carry" data-adf="{"attrs":{"panelType":"info"},…,"type":"panel"}">Check the collation.</div>
<p>Ask <span class="adf-carry" data-adf="{"attrs":{"id":"5b10a2","text":"@Mikael"},"type":"mention"}">@Mikael</span></p>
data-adfholds the node's JSON compact, keys sorted, as!adf:carrydoes in markdown, its type included. A document holding nocontentkey is the block carry of{"type":"doc","version":1}.- The text shown is every text node's text below the node, and what a node holding no text shows
in its place: a mention's text, else
@and its id; an emoji's text, else itsshortName; a status's text; a date as2026-09-13in UTC; a card's URL, else its name, else the URL its data holds; media'salt, else an external one's URL; an extension's text; an expand's title. A line feed parts two blocks and stands for a hard break. Null characters are dropped. - A node rides the carry where it holds an attribute, mark or key its element does not write, an
empty
attrs,contentormarks, or a value its element cannot hold:- text holding no character, or a null character, which HTML cannot hold; text holding a mark
twice, or a mark with attributes besides a link's
hrefandtitle; - an unmarked text node straight after another, which would read back as one;
- a link or an image whose URL holds a null character;
- a code block holding more than one text node, a marked one, or a language holding whitespace;
- a list holding a node that is no
listItem, or an item holding attributes or marks: the whole list rides the carry; - a
listItemoutside a list, an inline node in block position and a block node inline.
- text holding no character, or a null character, which HTML cannot hold; text holding a mark
twice, or a mark with attributes besides a link's
- A block carry's JSON nests at most 500 levels less the depth it stands at, an inline carry's at most 500, as in markdown.