Markdown reference
DocuCommit has exactly one Markdown engine: flexmark-java 0.64.8. The same parser and the same option set produce the HTML the editor edits, the HTML the server serves, the HTML that goes into PDF and HTML exports, and the Markdown written back to disk when you save. There is no second renderer and no per-surface dialect, so whatever renders correctly in one place renders the same way everywhere. The base is CommonMark, plus the five extensions described below: tables, task lists, strikethrough, wiki links, and YAML frontmatter.
Tables
GitHub-style pipe tables, with the usual alignment row.
| Field | Purpose | Required |
| --- | :---: | ---: |
| `title` | Display name | yes |
| `slug` | Pins the URL | no |
Task lists and strikethrough
- [x] Draft the runbook
- [ ] Review with the on-call rota
The old endpoint is ~~deprecated~~ removed.
Fenced code
Fenced blocks take a language tag on the info string. The tag becomes a language-* class, and
highlight.js colours the block in the browser.
```sql
select count(*) from documents where published_at is null;
```
Wiki links
Wiki links point at documents, not at file paths, so they survive moves and renames. The syntax puts the display text first and the target second:
See [[setup-guide]] for the install steps.
See [[the install steps|setup-guide]] if you prefer your own wording.
Jump straight to [[Setup Guide|setup-guide#prerequisites]].
With a single part, the text you type is the lookup key and the resolved document’s own title is
what renders. With two parts, the left side is what the reader sees and the right side is the
target. Anchors are appended to the target with #.
A target is looked up in this order: document uuid, then slug, then title — all
case-insensitively, with runs of whitespace collapsed. Slugs and titles resolve within the
library being rendered; a uuid resolves across every library the server knows about, which is
why the editor’s link picker inserts the title|uuid form.
When a target cannot be found, or when two documents claim the same slug or title, the link
renders as plain, non-clickable text carrying the dc-wikilink--broken class and a tooltip that
reads Unresolved link: <target> or Ambiguous link: <target>. Nothing is silently dropped and
nothing links to the wrong page.
Callouts
Four GitHub-style callouts are supported. The marker must be the first thing inside the blockquote and must sit alone on its line.
> [!NOTE]
> Background information a reader can safely skim.
> [!TIP]
> A shortcut or a better way to do the same thing.
> [!WARNING]
> Something that will bite you if you ignore it.
> [!CAUTION]
> Data loss, downtime, or another irreversible outcome.
Rendered, each becomes a coloured, left-bordered block with an uppercase label above the text: NOTE renders as Information, TIP as Success, WARNING as Warning, and CAUTION as Danger. Callouts are styled in PDF and HTML exports too.
Mermaid diagrams
A fenced block tagged mermaid is rendered as a diagram by Mermaid 11 in the browser, using the
neutral theme and strict security level.
```mermaid
flowchart LR
Draft --> Review --> Publish
```
An invalid diagram is replaced by an inline error box rather than a blank space, so a typo is visible rather than silent.
Includes
A fenced block whose info string is exactly include transcludes another document. The first
non-blank line inside it is the target: a path relative to the folder of the document doing the
including.
```include
shared/disclaimer.md
```
The whole target document is inlined — there is no heading or line-range slicing. Includes may
nest, and a cycle is caught and reported inline as a Circular include error rather than hanging
the render. A missing target reports Include not found. Expansion happens at render time only:
the file on disk always keeps the fence, and so does a raw Markdown export.
Frontmatter
Each document starts with a small YAML block that DocuCommit reads for title, sort, tags,
slug, uuid, and type. The frontmatter block is preserved verbatim on save — only the body
below it is reformatted — and any field DocuCommit does not recognise is kept and ignored. See
Repository layout for the full field table.
One formatting detail: tags is written as a YAML block list, one - tag per line, not as an
inline array.
---
title: Incident response
sort: 3
tags:
- runbook
- on-call
---
Deliberately not supported
- Footnotes
- Definition lists
[!IMPORTANT]callouts — only NOTE, TIP, WARNING, and CAUTION exist- Automatic linking of bare URLs (write
[text](url)or an explicit<url>) - Emoji shortcodes such as
:tada: - MDX and HTML component syntax
The dialect is small on purpose. The same flexmark option set has to parse your Markdown, render it to HTML for the WYSIWYG editor, convert the editor’s HTML back to Markdown, and canonicalise the result on save. Syntax outside that set would not survive the round trip intact, so it is left out rather than half-supported.
Details worth knowing
Saving canonicalises the body. The formatter rewrites list bullets to -, ordered-list
markers to ., collapses runs of blank lines to at most one, trims trailing blank lines, and
normalises tables (leading and trailing pipes, padded column widths, alignment applied, missing
cells filled). Line wrapping is left alone — there is no reflow. The practical consequence: the
first save of a hand-written file can produce a diff much larger than the edit you actually made.
Every save after that is clean.
Mermaid and syntax highlighting are browser-side. PDF and HTML exports contain the raw fenced source in a plain code block instead of a diagram or coloured code. draw.io diagrams are the exception — they are stored as SVG files and survive export intact.
Search indexes code separately from prose. The Lucene index keeps a body field with code
blocks stripped out and a separate code field holding only the contents of fenced and indented
code blocks, so a search for a function name does not have to compete with the surrounding prose.