close
Skip to content

Djot Syntax Reference

This document covers all Djot syntax supported by this library with input and output examples.

Block Elements

Headings

Headings use # characters. The number of # determines the level (1-6).

Input:

djot
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6
html
<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

Paragraphs are separated by blank lines. Text within a paragraph wraps normally.

Input:

djot
First paragraph with
multiple lines.

Second paragraph.
html
<p>First paragraph with
multiple lines.</p>
<p>Second paragraph.</p>

Code Blocks

Fenced code blocks use triple backticks with an optional language identifier.

Input:

djot
```php
function hello(): void {
    echo "Hello World";
}
```
html
<pre><code class="language-php">function hello(): void {
    echo "Hello World";
}
</code></pre>

Without a language:

Input:

djot
```
Plain code block
```
html
<pre><code>Plain code block
</code></pre>

Block Quotes

Block quotes use > at the start of each line.

Input:

djot
> This is a quote
> spanning multiple lines.
>
> With multiple paragraphs.
html
<blockquote>
<p>This is a quote
spanning multiple lines.</p>
<p>With multiple paragraphs.</p>
</blockquote>

Nested block quotes:

Input:

djot
> Outer quote
>
> > Nested quote
html
<blockquote>
<p>Outer quote</p>
<blockquote>
<p>Nested quote</p>
</blockquote>
</blockquote>

Block Quote Captions

Use ^ after a block quote to add an attribution/caption. The block quote will be wrapped in a <figure> element with a <figcaption>.

Input:

djot
> To be or not to be, that is the question.
^ William Shakespeare
html
<figure>
<blockquote>
<p>To be or not to be, that is the question.</p>
</blockquote>
<figcaption>William Shakespeare</figcaption>
</figure>

Lists

Bullet Lists

Use -, *, or + for bullet lists.

Input:

djot
- Item 1
- Item 2
- Item 3
html
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>

Ordered Lists

Use numbers followed by . or ).

Input:

djot
1. First
2. Second
3. Third
html
<ol>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ol>

Lists can start at any number:

Input:

djot
5. Fifth item
6. Sixth item
html
<ol start="5">
<li>Fifth item</li>
<li>Sixth item</li>
</ol>

Nested Lists

Indent with 2+ spaces for nested lists.

Input:

djot
- Item 1
  - Nested A
  - Nested B
- Item 2
html
<ul>
<li>Item 1
<ul>
<li>Nested A</li>
<li>Nested B</li>
</ul>
</li>
<li>Item 2</li>
</ul>

Task Lists

Use [ ] or [_] for unchecked and [x] or [X] for checked items.

The underscore notation [_] is useful on mobile devices or in editors without monospaced fonts, where the space in [ ] can be hard to type or see.

Input:

djot
- [ ] Todo item (space)
- [_] Todo item (underscore)
- [x] Done item
html
<ul class="task-list">
<li><input type="checkbox" disabled> Todo item (space)</li>
<li><input type="checkbox" disabled> Todo item (underscore)</li>
<li><input type="checkbox" disabled checked> Done item</li>
</ul>

List Item Attributes (Extension)

Attributes can be added to list items on the following indented line:

Input:

djot
- item 1
  {.highlight #id1}
- item 2
  {data-value="test"}
- item 3
html
<ul>
<li class="highlight" id="id1">item 1</li>
<li data-value="test">item 2</li>
<li>item 3</li>
</ul>

Works with all list types (unordered, ordered, and task lists). The attribute line must be indented to the content indentation level.

Tight vs Loose Lists

Lists in Djot can be tight or loose, which affects how list items are rendered.

Tight lists have no blank lines between items. List item content is rendered directly without <p> tags:

Input:

djot
- Item one
- Item two
- Item three
html
<ul>
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ul>

Loose lists have blank lines between items. Each item's content is wrapped in <p> tags:

Input:

djot
- Item one

- Item two

- Item three
html
<ul>
<li><p>Item one</p></li>
<li><p>Item two</p></li>
<li><p>Item three</p></li>
</ul>

The tight/loose distinction affects visual spacing. Loose lists typically have more vertical space between items due to paragraph margins in CSS.

Mixed Lists

A list is loose if any item is separated by a blank line. One blank line makes the entire list loose.

Nested lists require a blank line before the nested content in standard Djot:

djot
- Parent item

  - Nested item A
  - Nested item B

With significantNewlines mode enabled, nested lists can appear immediately without a blank line:

djot
- Parent item
  - Nested item A
  - Nested item B

See the API Reference for more on significantNewlines mode.

Definition Lists

Terms are prefixed with : and definitions are indented below.

djot
: Term 1

  Definition of term 1

: Term 2

  Definition of term 2
djot
: color
: colour

  The visual property of objects.
djot
: word

  First meaning.

: +

  Second meaning (separate dd).
html
<dl>
<dt>Term 1</dt>
<dd><p>Definition of term 1</p></dd>
<dt>Term 2</dt>
<dd><p>Definition of term 2</p></dd>
</dl>

Enhancements

  • Multiple terms: Consecutive : term lines share a definition
  • Multiple definitions: Use : + continuation for separate <dd> elements
  • Attributes: Add {.class} to <dl>, <dt>, or <dd> elements

See definition list enhancements for full details.

Definition List Attributes (Extension)

Attributes can be attached to individual definition list elements:

Input:

djot
{.vocabulary}
: color
{.american}
: colour
{.british}

  The visual property of objects.
  {.primary}
html
<dl class="vocabulary">
<dt class="american">color</dt>
<dt class="british">colour</dt>
<dd class="primary">
<p>The visual property of objects.</p>
</dd>
</dl>
  • {...} before first term → applies to <dl>
  • {...} on line after term → applies to that <dt>
  • {...} as last line in definition block → applies to that <dd>

Tables

Tables use | to separate columns.

Input:

djot
| Header 1 | Header 2 |
|----------|----------|
| Cell 1   | Cell 2   |
| Cell 3   | Cell 4   |
html
<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>

Column Alignment

Use : in the separator row for alignment.

Input:

djot
| Left | Center | Right |
|:-----|:------:|------:|
| L    | C      | R     |
html
<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>

Table Captions

Use ^ after the table for a caption.

Input:

djot
| A | B |
|---|---|
| 1 | 2 |
^ This is the caption
html
<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>

Table Row and Cell Attributes (Extension)

Attributes can be added to table rows and individual cells:

Row attributes (after final pipe):

djot
| Name | Age |{.header-row}
|------|-----|
| John | 30  |{.highlight}

Cell attributes (after opening pipe):

djot
|{.name} Name |{.age} Age |
|-------------|-----------|
|{.emphasis} John | 30 |
html
<table>
<tr class="header-row">
<th class="name">Name</th>
<th class="age">Age</th>
</tr>
<tr class="highlight">
<td class="emphasis">John</td>
<td>30</td>
</tr>
</table>

Table Multi-line Cells, Rowspan, and Colspan (Extension)

Multi-line cell content uses + prefix for continuation rows:

djot
| Name | Description      |
|------|------------------|
| Item | Long description |
+      | continued here   |

Rowspan uses ^ marker (points UP to cell above):

djot
| Category | Item   |
|----------|--------|
| Fruits   | Apple  |
| ^        | Banana |
| ^        | Orange |
html
<table>
<tr><th>Category</th><th>Item</th></tr>
<tr><td rowspan="3">Fruits</td><td>Apple</td></tr>
<tr><td>Banana</td></tr>
<tr><td>Orange</td></tr>
</table>

Colspan uses < marker (points LEFT to cell before):

djot
| Name  | Contact Info | <     |
|-------|--------------|-------|
| Alice | alice@ex.com | x5234 |
html
<table>
<tr><th>Name</th><th colspan="2">Contact Info</th></tr>
<tr><td>Alice</td><td>alice@ex.com</td><td>x5234</td></tr>
</table>

Use \^ or \< for literal characters. Content like a < b is NOT treated as colspan.

Thematic Breaks

Use ***, ---, or ___ (3+ characters) on a line by itself.

Input:

djot
Above

***

Below
html
<p>Above</p>
<hr>
<p>Below</p>

Divs

Fenced divs use ::: with an optional class name.

Input:

djot
::: warning
This is a warning message.
:::
html
<div class="warning">
<p>This is a warning message.</p>
</div>

Nested divs:

Input:

djot
::: outer
Outer content

::: inner
Inner content
:::

More outer
:::
html
<div class="outer">
<p>Outer content</p>
<div class="inner">
<p>Inner content</p>
</div>
<p>More outer</p>
</div>

Comments

Comments are not rendered in output.

Input:

djot
Visible text

{% This is a comment %}

More visible text

{% Multi-line
   comment here %}
html
<p>Visible text</p>
<p>More visible text</p>

Fenced Comments (Extension)

Standard {% %} comments cannot contain blank lines. For longer comments that need blank lines, use fenced comments with %%%:

Input:

djot
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
html
<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:

djot
Some text

%%%%
%%% This is not the end
Still inside the comment
%%%%

More text
html
<p>Some text</p>
<p>More text</p>

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:

djot
Lorem ipsum
%%%
comment
%%%
dolor sit amet
html
<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 ({% ... %}).

Line Blocks

Preserve line breaks using | at the start of each line. Useful for poetry or addresses.

Input:

djot
| Roses are red,
| Violets are blue,
| Sugar is sweet,
| And so are you.
html
<div class="line-block">
<p>Roses are red,<br>
Violets are blue,<br>
Sugar is sweet,<br>
And so are you.</p>
</div>

Block Attributes

Apply attributes to the following block using {...} syntax.

Input:

djot
{.highlight #intro}
# Introduction

{.note data-version="2.0"}
This is a note.
html
<h1 class="highlight" id="intro">Introduction</h1>
<p class="note" data-version="2.0">This is a note.</p>

Boolean Attribute Shorthand (Extension)

Boolean/flag attributes can be specified without a value:

Input:

djot
{reversed}
1. Third
2. Second
3. First

[Download](file.zip){download .btn}
html
<ol reversed="">
<li>Third</li>
<li>Second</li>
<li>First</li>
</ol>
<p><a href="file.zip" class="btn" download="">Download</a></p>

Common boolean attributes: {reversed} (lists), {open} (details), {hidden}, {download} (links).

Inline Elements

Emphasis and Strong

Use _underscores_ for emphasis and *asterisks* for strong.

Input:

djot
This is _emphasized_ and *strong* text.

You can _nest *strong* inside_ emphasis.
html
<p>This is <em>emphasized</em> and <strong>strong</strong> text.</p>
<p>You can <em>nest <strong>strong</strong> inside</em> emphasis.</p>

Code Spans

Use backticks for inline code.

Input:

djot
Use the `print()` function.

For literal backticks: `` `code` ``
html
<p>Use the <code>print()</code> function.</p>
<p>For literal backticks: <code>`code`</code></p>

Input:

djot
[Link text](https://example.com)

[Link with title](https://example.com "Title")
html
<p><a href="https://example.com">Link text</a></p>
<p><a href="https://example.com" title="Title">Link with title</a></p>

Input:

djot
[Link text][ref]

[Another link][ref]

[ref]: https://example.com
html
<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:

djot
[Click here][example]

{.external title="Example Site"}
[example]: https://example.com
html
<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:

djot
[Click here][example]{.button}

{.external}
[example]: https://example.com
html
<p><a href="https://example.com" class="external button">Click here</a></p>

Input:

djot
<https://example.com>

<user@example.com>
html
<p><a href="https://example.com">https://example.com</a></p>
<p><a href="mailto:user@example.com">user@example.com</a></p>

Images

Input:

djot
![Demo landscape](/demo.svg)

![Demo landscape](/demo.svg "A simple landscape")
html
<p><img src="/demo.svg" alt="Demo landscape"></p>
<p><img src="/demo.svg" alt="Demo landscape" title="A simple landscape"></p>

Image Captions

Use ^ after an image to add a caption. The image will be wrapped in a <figure> element with a <figcaption>.

Input:

djot
![Demo landscape](/demo.svg)
^ A simple landscape with sun, hills, and sky
html
<figure>
<img src="/demo.svg" alt="Demo landscape"><figcaption>A simple landscape with sun, hills, and sky</figcaption>
</figure>

Superscript and Subscript

Use ^ for superscript and ~ for subscript.

Input:

djot
E=mc^2^

H~2~O
html
<p>E=mc<sup>2</sup></p>
<p>H<sub>2</sub>O</p>

Highlight, Insert, Delete

Input:

djot
{=highlighted text=}

{+inserted text+}

{-deleted text-}
html
<p><mark>highlighted text</mark></p>
<p><ins>inserted text</ins></p>
<p><del>deleted text</del></p>

Spans with Attributes

Apply attributes to inline text.

Input:

djot
[styled text]{.highlight}

[more text]{#unique-id}

[data text]{data-value="42"}
html
<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>

Math

Inline Math

Input:

djot
The equation $`E = mc^2`$ is famous.
html
<p>The equation <span class="math inline">\(E = mc^2\)</span> is famous.</p>

Display Math

Input:

djot
$$`\sum_{i=0}^{n} i = \frac{n(n+1)}{2}`$$
html
<span class="math display">\[\sum_{i=0}^{n} i = \frac{n(n+1)}{2}\]</span>

Symbols

Use :name: for symbols.

Input:

djot
I :heart: Djot
html
<p>I <span class="symbol">heart</span> Djot</p>

Note: Symbol rendering can be customized via events. See the Cookbook for examples.

Footnotes

Input:

djot
Here is a statement[^1] with a footnote.

Another reference[^note].

[^1]: This is the first footnote.

[^note]: This is a named footnote.
html
<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>

Raw HTML

Inline Raw HTML

Input:

djot
Text `<span class="special">raw html</span>`{=html} more text
html
<p>Text <span class="special">raw html</span> more text</p>

Block Raw HTML

Input:

djot
``` =html
<div class="custom">
  <p>Raw HTML block</p>
</div>
```
html
<div class="custom">
  <p>Raw HTML block</p>
</div>

Smart Typography

The parser automatically converts certain character sequences.

Quotes

Input:

djot
"Double quotes" and 'single quotes'

"Nested 'quotes' work" too
html
<p>"Double quotes" and 'single quotes'</p>
<p>"Nested 'quotes' work" too</p>

Dashes

Input:

djot
En-dash: 1--10

Em-dash: wait---what?
html
<p>En-dash: 1–10</p>
<p>Em-dash: wait—what?</p>

Ellipsis

Input:

djot
Wait for it...
html
<p>Wait for it…</p>

Hard Line Breaks

End a line with a backslash for a hard break.

Input:

djot
Line one\
Line two\
Line three
html
<p>Line one<br>
Line two<br>
Line three</p>

Abbreviations (Extension)

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:

djot
The HTML specification is maintained by the W3C.

*[HTML]: Hyper Text Markup Language
*[W3C]: World Wide Web Consortium
html
<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:

djot
*[HTML]: Hyper Text Markup Language,
  the standard markup language for documents
  designed to be displayed in a web browser

Inline Abbreviations

For one-off abbreviations or to override a definition, use the inline span syntax:

Input:

djot
The [HTML]{abbr="Hyper Text Markup Language"} specification.
html
<p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification.</p>

The definition-based approach (*[ABBR]: ...) automatically applies to all matching text, while the inline [ABBR]{abbr="..."} approach allows marking specific occurrences.

Escaping

Use backslash to escape special characters.

Input:

djot
\*not strong\*

\# not a heading

\[not a link\]
html
<p>*not strong*</p>
<p># not a heading</p>
<p>[not a link]</p>

Non-Breaking Space

An escaped space (\ ) produces a non-breaking space.

Input:

djot
100\ km

Dr.\ Smith
html
<p>100&nbsp;km</p>
<p>Dr.&nbsp;Smith</p>

This is useful for keeping values and units together, titles and names, or any text that shouldn't be split across lines.