This document covers all Djot syntax supported by this library with input and output examples.
Headings use # characters. The number of # determines the level (1-6).
Input:
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6
Output:
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>Paragraphs are separated by blank lines. Text within a paragraph wraps normally.
Input:
First paragraph with
multiple lines.
Second paragraph.
Output:
<p>First paragraph with
multiple lines.</p>
<p>Second paragraph.</p>Fenced code blocks use triple backticks with an optional language identifier.
Input:
```php
function hello(): void {
echo "Hello World";
}
```
Output:
<pre><code class="language-php">function hello(): void {
echo "Hello World";
}
</code></pre>Without a language:
Input:
```
Plain code block
```
Output:
<pre><code>Plain code block
</code></pre>Block quotes use > at the start of each line.
Input:
> This is a quote
> spanning multiple lines.
>
> With multiple paragraphs.
Output:
<blockquote>
<p>This is a quote
spanning multiple lines.</p>
<p>With multiple paragraphs.</p>
</blockquote>Nested block quotes:
Input:
> Outer quote
>
> > Nested quote
Output:
<blockquote>
<p>Outer quote</p>
<blockquote>
<p>Nested quote</p>
</blockquote>
</blockquote>Use ^ after a block quote to add an attribution/caption. The block quote will be wrapped in a <figure> element with a <figcaption>.
Input:
> To be or not to be, that is the question.
^ William Shakespeare
Output:
<figure>
<blockquote>
<p>To be or not to be, that is the question.</p>
</blockquote>
<figcaption>William Shakespeare</figcaption>
</figure>Use -, *, or + for bullet lists.
Input:
- Item 1
- Item 2
- Item 3
Output:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>Use numbers followed by . or ).
Input:
1. First
2. Second
3. Third
Output:
<ol>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ol>Lists can start at any number:
Input:
5. Fifth item
6. Sixth item
Output:
<ol start="5">
<li>Fifth item</li>
<li>Sixth item</li>
</ol>Indent with 2+ spaces for nested lists.
Input:
- Item 1
- Nested A
- Nested B
- Item 2
Output:
<ul>
<li>Item 1
<ul>
<li>Nested A</li>
<li>Nested B</li>
</ul>
</li>
<li>Item 2</li>
</ul>Use [ ] for unchecked and [x] or [X] for checked items.
Input:
- [ ] Todo item
- [x] Done item
- [ ] Another todo
Output:
<ul class="task-list">
<li><input type="checkbox" disabled> Todo item</li>
<li><input type="checkbox" disabled checked> Done item</li>
<li><input type="checkbox" disabled> Another todo</li>
</ul>Terms followed by : definitions.
Input:
Term 1
: Definition of term 1
Term 2
: Definition of term 2
: Alternative definition
Output:
<dl>
<dt>Term 1</dt>
<dd>Definition of term 1</dd>
<dt>Term 2</dt>
<dd>Definition of term 2</dd>
<dd>Alternative definition</dd>
</dl>Tables use | to separate columns.
Input:
| Header 1 | Header 2 |
|----------|----------|
| Cell 1 | Cell 2 |
| Cell 3 | Cell 4 |
Output:
<table>
<thead>
<tr><th>Header 1</th><th>Header 2</th></tr>
</thead>
<tbody>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 3</td><td>Cell 4</td></tr>
</tbody>
</table>Use : in the separator row for alignment.
Input:
| Left | Center | Right |
|:-----|:------:|------:|
| L | C | R |
Output:
<table>
<thead>
<tr><th style="text-align: left">Left</th><th style="text-align: center">Center</th><th style="text-align: right">Right</th></tr>
</thead>
<tbody>
<tr><td style="text-align: left">L</td><td style="text-align: center">C</td><td style="text-align: right">R</td></tr>
</tbody>
</table>Use ^ after the table for a caption.
Input:
| A | B |
|---|---|
| 1 | 2 |
^ This is the caption
Output:
<table>
<caption>This is the caption</caption>
<thead>
<tr><th>A</th><th>B</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>2</td></tr>
</tbody>
</table>Use ***, ---, or ___ (3+ characters) on a line by itself.
Input:
Above
***
Below
Output:
<p>Above</p>
<hr>
<p>Below</p>Fenced divs use ::: with an optional class name.
Input:
::: warning
This is a warning message.
:::
Output:
<div class="warning">
<p>This is a warning message.</p>
</div>Nested divs:
Input:
::: outer
Outer content
::: inner
Inner content
:::
More outer
:::
Output:
<div class="outer">
<p>Outer content</p>
<div class="inner">
<p>Inner content</p>
</div>
<p>More outer</p>
</div>Comments are not rendered in output.
Input:
Visible text
{% This is a comment %}
More visible text
{% Multi-line
comment here %}
Output:
<p>Visible text</p>
<p>More visible text</p>Standard {% %} comments cannot contain blank lines. For longer comments that need blank lines,
use fenced comments with %%%:
Input:
Visible text
%%%
This is a fenced comment block.
It can contain blank lines.
Multiple paragraphs of notes, TODOs,
or documentation that won't render.
%%%
More visible text
Output:
<p>Visible text</p>
<p>More visible text</p>Like code fences, you can use more than three % characters. The closing fence must have
at least as many % as the opening fence:
Input:
%%%%
%%% This is not the end
Still inside the comment
%%%%
Output:
Note: This is a djot-php extension, not part of the official Djot specification. See discussion for background.
Fenced comment blocks are block-level elements that break paragraph continuity. Unlike other block elements, fenced comments can interrupt paragraphs without requiring a preceding blank line - making them truly "invisible" from a formatting perspective:
Input:
Lorem ipsum
%%%
comment
%%%
dolor sit amet
Output:
<p>Lorem ipsum</p>
<p>dolor sit amet</p>This produces two separate paragraphs. For comments that should not interrupt
paragraph flow (keeping text in the same paragraph), use inline comments ({% ... %}).
Preserve line breaks using | at the start of each line. Useful for poetry or addresses.
Input:
| Roses are red,
| Violets are blue,
| Sugar is sweet,
| And so are you.
Output:
<div class="line-block">
<p>Roses are red,<br>
Violets are blue,<br>
Sugar is sweet,<br>
And so are you.</p>
</div>Apply attributes to the following block using {...} syntax.
Input:
{.highlight #intro}
# Introduction
{.note data-version="2.0"}
This is a note.
Output:
<h1 class="highlight" id="intro">Introduction</h1>
<p class="note" data-version="2.0">This is a note.</p>Use _underscores_ for emphasis and *asterisks* for strong.
Input:
This is _emphasized_ and *strong* text.
You can _nest *strong* inside_ emphasis.
Output:
<p>This is <em>emphasized</em> and <strong>strong</strong> text.</p>
<p>You can <em>nest <strong>strong</strong> inside</em> emphasis.</p>Use backticks for inline code.
Input:
Use the `print()` function.
For literal backticks: `` `code` ``
Output:
<p>Use the <code>print()</code> function.</p>
<p>For literal backticks: <code>`code`</code></p>Input:
[Link text](https://example.com)
[Link with title](https://example.com "Title")
Output:
<p><a href="https://example.com">Link text</a></p>
<p><a href="https://example.com" title="Title">Link with title</a></p>Input:
[Link text][ref]
[Another link][ref]
[ref]: https://example.com
Output:
<p><a href="https://example.com">Link text</a></p>
<p><a href="https://example.com">Another link</a></p>Attributes can be added to reference definitions and will be applied to all links using that reference.
Input:
[Click here][example]
{.external title="Example Site"}
[example]: https://example.com
Output:
<p><a href="https://example.com" class="external" title="Example Site">Click here</a></p>Link-level attributes can override or extend definition attributes:
Input:
[Click here][example]{.button}
{.external}
[example]: https://example.com
Output:
<p><a href="https://example.com" class="external button">Click here</a></p>Input:
<https://example.com>
<user@example.com>
Output:
<p><a href="https://example.com">https://example.com</a></p>
<p><a href="mailto:user@example.com">user@example.com</a></p>Input:


Output:
<p><img src="image.png" alt="Alt text"></p>
<p><img src="image.png" alt="Alt text" title="Title"></p>Use ^ after an image to add a caption. The image will be wrapped in a <figure> element with a <figcaption>.
Input:

^ A beautiful sunset captured at the beach
Output:
<figure>
<img src="sunset.jpg" alt="Sunset over the ocean"><figcaption>A beautiful sunset captured at the beach</figcaption>
</figure>Use ^ for superscript and ~ for subscript.
Input:
E=mc^2^
H~2~O
Output:
<p>E=mc<sup>2</sup></p>
<p>H<sub>2</sub>O</p>Input:
{=highlighted text=}
{+inserted text+}
{-deleted text-}
Output:
<p><mark>highlighted text</mark></p>
<p><ins>inserted text</ins></p>
<p><del>deleted text</del></p>Apply attributes to inline text.
Input:
[styled text]{.highlight}
[more text]{#unique-id}
[data text]{data-value="42"}
Output:
<p><span class="highlight">styled text</span></p>
<p><span id="unique-id">more text</span></p>
<p><span data-value="42">data text</span></p>Input:
The equation $`E = mc^2`$ is famous.
Output:
<p>The equation <span class="math inline">\(E = mc^2\)</span> is famous.</p>Input:
$$`\sum_{i=0}^{n} i = \frac{n(n+1)}{2}`$$
Output:
<span class="math display">\[\sum_{i=0}^{n} i = \frac{n(n+1)}{2}\]</span>Use :name: for symbols.
Input:
I :heart: Djot
Output:
<p>I <span class="symbol">heart</span> Djot</p>Note: Symbol rendering can be customized via events. See the Cookbook for examples.
Input:
Here is a statement[^1] with a footnote.
Another reference[^note].
[^1]: This is the first footnote.
[^note]: This is a named footnote.
Output:
<p>Here is a statement<sup id="fnref-1-1"><a href="#fn-1">1</a></sup> with a footnote.</p>
<p>Another reference<sup id="fnref-note-1"><a href="#fn-note">note</a></sup>.</p>
<div class="footnote" id="fn-1">
<p><sup>1</sup> This is the first footnote. <a href="#fnref-1-1">↩</a></p>
</div>
<div class="footnote" id="fn-note">
<p><sup>note</sup> This is a named footnote. <a href="#fnref-note-1">↩</a></p>
</div>Input:
Text `<span class="special">raw html</span>`{=html} more text
Output:
<p>Text <span class="special">raw html</span> more text</p>Input:
``` =html
<div class="custom">
<p>Raw HTML block</p>
</div>
```
Output:
<div class="custom">
<p>Raw HTML block</p>
</div>The parser automatically converts certain character sequences.
Input:
"Double quotes" and 'single quotes'
"Nested 'quotes' work" too
Output:
<p>"Double quotes" and 'single quotes'</p>
<p>"Nested 'quotes' work" too</p>Input:
En-dash: 1--10
Em-dash: wait---what?
Output:
<p>En-dash: 1–10</p>
<p>Em-dash: wait—what?</p>Input:
Wait for it...
Output:
<p>Wait for it…</p>End a line with a backslash for a hard break.
Input:
Line one\
Line two\
Line three
Output:
<p>Line one<br>
Line two<br>
Line three</p>Abbreviations allow you to define terms that will automatically be wrapped in <abbr> tags with their definitions. This is an extension feature inspired by PHP Markdown Extra.
Input:
The HTML specification is maintained by the W3C.
*[HTML]: Hyper Text Markup Language
*[W3C]: World Wide Web Consortium
Output:
<p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>.</p>Abbreviation definitions can appear anywhere in the document and will be applied to all matching text. Matching is:
- Case-sensitive (HTML ≠ html)
- Word-boundary aware (HTML won't match HTMLElement)
Definitions can span multiple lines if continuation lines are indented:
*[HTML]: Hyper Text Markup Language,
the standard markup language for documents
designed to be displayed in a web browser
Note: This feature works alongside the inline span approach documented in the cookbook. The definition-based approach automatically applies to all matching text, while the inline [HTML]{abbr="..."} approach allows overriding specific occurrences.
Use backslash to escape special characters.
Input:
\*not strong\*
\# not a heading
\[not a link\]
Output:
<p>*not strong*</p>
<p># not a heading</p>
<p>[not a link]</p>