Static specimen. The markup is what src/model/schema.ts emits from toDOM, so every selector in prose.css is exercised against the document that will really be on screen.
A paragraph of body text at the document size, set ragged right rather than justified. The
measure comes from the width menu in the corner, and the same paragraph has to read
correctly at all three settings, which is one of the reasons the justification and
hyphenation this palette arrived with were left behind. A line can carry
bold, italic, struck out text, a code span, a
relative link to another document, and a bare URL such as
https://example.com/a/very/long/path/with/no/obvious/break/points/in/it
which has to wrap inside the measure instead of pushing the page sideways.
Size carries the first three levels. From the fourth down there is no size left to spend, so the scale changes signal instead: weight, then typeface, then case.
Still the book face and still semibold, one step above the body and clearly below the section that contains it.
Here a heading is the same size as the text under it, and the weight plus the space above it is what makes it a heading rather than a bold sentence.
Changing family is the strongest signal left once size and weight are spent, and by level five a heading has stopped being a title and become a label.
Uppercase, tracked out, secondary ink, and the smallest thing on the page that is still a heading. Six levels, none of them ambiguous against its neighbour.
A tight list, which is what a markdown list with no blank lines between items is:
First item at depth one
Depth two takes a hollow marker
Depth three takes a square
Depth four, where the cycle restarts and the indent disambiguates
Depth five, still inside the measure at the narrow setting
A sibling back at depth three
Second item at depth one
Third item at depth one
The same list loose, meaning the source has a blank line between the items:
A loose item gets its paragraph spacing back, which is the difference the file on disk is actually making.
A loose item can hold more than one paragraph.
Like this one, whose second paragraph is spaced rather than run on.
And a third.
Ordered lists stay decimal at every depth, and a start attribute is honoured:
Eight
Nested, and still numbered, because that is what the file says
Three deep
And its sibling
Nine
Ten, whose figures line up with the two above it
Task lists, checked and not:
Freeze the DTO contract and the IPC mirror
A done item that runs to more than one line, so the drop to secondary ink can be judged against a real block of text rather than against four words.
Wire the width menu to the root attribute
Nested, unchecked
Nested, checked
A mixed list, which GFM allows and the schema models as a bullet list holding both kinds of item:
An ordinary item
A checkbox item, text edge unmoved
A checked item, text edge unmoved
An ordinary item again
Inline code such as roots_list, Result<T, String> and
--code-surface sits inside the line box, so a paragraph carrying three of them
keeps the leading of the one above it. A fenced block with a language:
#[tauri::command(async)]
pub fn file_write(path: String, text: String, expected_modified_ms: Option<i64>) -> Result<WriteResult, String> {
// Long lines scroll rather than wrap: rewrapping a fence at a column the file knows nothing about stops it reading as code.
Err("not implemented".to_string())
}
And one with no language, which reserves no room for a label:
$ cargo check --all-targets
Finished dev [unoptimized + debuginfo] target(s) in 0.31s
Markdown the editor cannot model is kept byte for byte and shown as a raw block, which has to be legible as source and obviously not a fence:
<figure class="wide">
<img src="./assets/diagram.png" alt="the index" />
<figcaption>Something the schema has no node for</figcaption>
</figure>
A quote is not italic here. In a technical document it is as likely to be a paragraph of a spec or somebody's bug report as it is an epigraph, and neither of those wants to be set in italic.
A quote inside a quote, which is a reply, and it keeps full legibility.
Three levels deep, the bars and the indents carrying the depth.
Back at the first level, after the nesting closes.
A quote can hold other blocks:
A list
Inside a quote
git status --porcelain
Opening a file never writes it. The first edit rewrites it in one house style, and every save after that is byte stable.
The width menu has three steps, and wide exists for documents that are mostly tables.
Filename and H1 are unrelated. Nothing renames a file behind the user's back.
A construct with no node becomes a raw block rather than being reformatted into the nearest thing the editor understands.
Deletions go through the trash, never an unlink. These are the user's own files.
A details element on disk. The summary is an attribute rather than a child node, so it is plain text and a summary carrying markup belongs in a raw block.
Hidden until the marker is turned.
Wrapped, so the table is full width and its cells wrap:
| Command | Async | Calls |
|---|---|---|
file_read |
yes | 1284 |
file_write |
yes | 97 |
reveal_in_finder |
no | 6 |
Wider than the measure, so it scrolls inside itself and the page does not:
| Token | Light | Dark | Used by | Replaces | Delta L* |
|---|---|---|---|---|---|
--doc-rule |
#e3ddce |
#35302a |
table rules, callout border, figure border | --line |
10.4 |
--doc-rule-strong |
#cdc4ae |
#4a4339 |
quote bar, horizontal rule, checkbox, raw fence | --line-strong |
19.3 |
--code-surface |
#f2ece0 |
#282521 |
fenced blocks and maths blocks | --shell, --raised |
5.0 |
Bare, with no wrapper, which is the fallback shape and hugs its content:
| Step | Measure |
|---|---|
| Narrow | 494px |
| Normal | 598px |
| Wide | 728px |
A lone image is a paragraph with one child. The caption is a hook the image node view fills, because CSS cannot read an attribute off an img.
An image with no caption, which still gets the figure treatment:
Inline maths such as e^{i\pi}+1=0 and a block of it:
Find paints inline decorations over live text, so every match takes a wash and the one the caret is on takes the ink, which has to stay legible when the real selection lands on top of a match as well.