Markdown mode
glu can convert Markdown files directly to PDF. Instead of writing Lua scripts, you write Markdown and glu handles the typesetting automatically.
glu document.mdThis produces document.pdf. glu detects the mode by the file extension: .lua for Lua scripts, .md for Markdown.
For complete worked examples (a DIN 5008 letter, a ZUGFeRD invoice, letterheads, headers and footers, charts), see the How-tos.
YAML frontmatter
A YAML block at the beginning of the file sets document metadata:
---
title: My Document
author: Jane Doe
css: custom.css
papersize: a4
format: PDF/UA
lang: en
---| Field | Description |
|---|---|
title |
PDF document title |
author |
PDF author field |
css |
Additional CSS file to load, relative to the document |
papersize |
Page size (a4, letter, 20cm 20cm, etc.) |
format |
PDF conformance level: PDF/UA / PDF/UA-1 (tagged PDF, ISO 14289-1), PDF/UA-2 (PDF 2.0, ISO 14289-2) or PDF/A-3b |
lang |
Document language (e.g. de, en) |
math |
Enable TeX math ($…$, $$…$$). Off by default. See Math. |
highlight-style |
Syntax highlighting style (default: github) |
extensions |
Switch optional Markdown extensions on or off. See Optional Markdown extensions. |
footnotes |
Where footnotes go: page (default) at the foot of the page, end collected at the end of the document. See Footnotes. |
attachments |
List of files to embed in the PDF. See Attachments. |
trace |
Debug overlays drawn into the PDF: boxmodel, dests, hboxes, hyperlinks (single value or list; combined with --trace). See Debug overlays. |
You can add custom fields of your own. All fields are available from Lua as the _frontmatter table.
Markdown features
glu uses goldmark with these extensions:
- Tables: pipe tables with alignment
- Strikethrough:
~~deleted~~ - Autolinks: URLs are automatically linked
- Syntax highlighting: fenced code blocks with a language tag are highlighted using chroma
- Block attributes:
{.class #id key="value"}on headings and after blocks, see below
Further pandoc-style extensions (fenced divs, bracketed spans, footnotes, definition lists, table captions, smart punctuation, automatic heading identifiers, superscript and subscript) are switched through the frontmatter, see Optional Markdown extensions.
Standard Markdown features: headings, bold, italic, code, lists, blockquotes, horizontal rules, and links.
Raw HTML is supported inside Markdown. This allows using CSS features like leaders for table-of-contents dot fills via inline <span> elements, or generating barcodes with <barcode> elements.
CSS classes and attributes on blocks
Two syntaxes attach HTML attributes (classes, ids, key/value pairs) to the generated elements, so custom CSS can target individual blocks. ATX headings take an attribute suffix on the same line:
# Title {.right #main}renders as <h1 class="right" id="main">. Every other block type (paragraphs, blockquotes, lists, code fences, tables) takes an attribute line directly after the block, with no blank line in between (kramdown style):
Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore.
{.three}renders as <p class="three">. Together with a custom stylesheet this enables per-paragraph styling that plain Markdown has no syntax for, e.g. a drop cap:
p.three { initial-letter: 3; }An attribute line separated from the preceding block by a blank line attaches to nothing and is dropped from the output. For attributes on inline text, use bracketed spans; for attributes on a group of blocks, use fenced divs.
Optional Markdown extensions
The extensions: frontmatter key switches optional Markdown syntax on or off. It accepts extension names in pandoc spelling, either comma-separated or as a YAML list; a leading - disables a default-enabled extension:
---
extensions: smart, auto_identifiers, -footnotes
---| Extension | Default | Description |
|---|---|---|
fenced_divs |
on | ::: {.class} wraps blocks in a div |
bracketed_spans |
on | [text]{.class} attaches attributes to inline text |
footnotes |
on | [^1] footnote references and definitions |
definition_lists |
on | : definition lines build dl/dt/dd |
table_captions |
on | a Table: text paragraph next to a table becomes its caption |
smart |
off | typographic quotes, dashes, ellipsis |
auto_identifiers |
off | automatic id attributes on headings |
tex_math_dollars |
off | TeX math, same as math: true. See Math. |
superscript |
off | 2^10^ becomes 210; the text between the carets has no spaces |
subscript |
off | H~2~O becomes H2O; the text between the tildes has no spaces, ~~text~~ stays strikethrough |
The defaults are chosen so existing documents render unchanged: the default-on extensions use syntax that plain documents cannot contain (a Table: paragraph next to a table is a caption written by hand, which table_captions turns into a real one), while smart, superscript and subscript rewrite regular text and auto_identifiers changes the document’s link targets, so these are opt-in.
Fenced divs
A line of at least three colons plus attributes opens a block container, a line of colons alone closes it. This wraps any number of blocks in a <div> without writing raw HTML, for styling with custom CSS or for switching the language of a whole section:
::: {.note lang=en}
This section is in English and hyphenates accordingly.
It can contain multiple blocks, lists, tables and nested divs.
:::A single bare word is a class shorthand: ::: warning is the same as ::: {.warning}. Divs nest; each closing fence closes the innermost open div.
A lang= attribute switches the hyphenation language for the div’s content, and in PDF/UA mode the switch is also declared in the structure tree (/Lang on the element), so screen readers pronounce the section in the right language.
Bracketed spans
Bracketed text immediately followed by attributes becomes a <span> with those attributes:
A paragraph with [ein deutscher Einschub]{lang=de} in the middle,
or [specially styled text]{.spaced} for a CSS class.This is the inline counterpart to block attributes: language switches, custom classes and ids mid-paragraph without raw HTML. Links, emphasis and other inline markup work inside the brackets.
Footnotes
Some text with a footnote.[^1]
[^1]: The footnote text.Each note is set at the foot of the page that holds its reference, below a rule, in a smaller size, and numbered through the document. A note with several paragraphs keeps them on separate lines. A note referenced twice is set twice, once for each reference.
The note becomes <span class="footnote"> at the place of its reference, so CSS on span.footnote styles it; the default stylesheet sets font-size: 0.85em.
To collect the notes at the end of the document instead, set footnotes: end in the frontmatter. glu does that by itself, with a warning, when a note holds a block that cannot go into a footnote, such as a list or a code block. Endnotes are separated by a rule and set in a smaller size; the web-style ↩ backlink is hidden by the default stylesheet, bring it back with .footnote-backref { display: inline; }.
Definition lists
Term
: The definition of the term.
Another term
: Another definition.renders as <dl>/<dt>/<dd>, styled with a hanging indent by the default stylesheet.
Table captions
A paragraph that starts with Table: (or table:, or just :) and stands directly after or before a pipe table becomes the table’s <caption>, without the prefix. A blank line separates it from the table:
| Measure | Badness |
|---------|---------|
| 35 em | 18 |
| 16 em | 112 |
{#tab-results}
Table: Average badness per measure.The caption may hold inline markup and span several lines. A paragraph between two tables belongs to the one before it. An attribute line goes either directly below the table, as above, or directly below the caption; either way the attributes end up on the <table>, so #tab-results is a link target for a cross reference.
The caption is set above the table wherever it stands in the Markdown, and in PDF/UA mode it is tagged as the table’s Caption. CSS on caption styles it, for example a number from a counter:
table { counter-increment: table; }
caption::before { content: "Table " counter(table) ". "; }Smart punctuation
With smart enabled, straight quotes become typographic quotes, -- becomes an en dash, --- an em dash and ... an ellipsis. The quote style follows the document language: with lang: de (or any de-* tag) German quotation marks („…“ and ‚…‘) are used, any other language gets English ones (“…” and ‘…’).
Automatic heading identifiers
With auto_identifiers enabled, every heading without an explicit {#id} attribute gets an id derived from its text, following pandoc’s algorithm: letters are lowercased, spaces become hyphens, punctuation is dropped and non-ASCII letters survive (## Über uns becomes über-uns). Duplicate ids get -1, -2 suffixes. This enables internal links to headings without writing any attributes:
See [the introduction](#introduction).
## IntroductionSyntax highlighting
Fenced code blocks with a language identifier are automatically syntax-highlighted:
```go
func main() {
fmt.Println("Hello")
}
```The highlight style can be set in the frontmatter:
---
highlight-style: monokai
---The default style is github. Any chroma style can be used (e.g. monokai, dracula, solarized-dark, tango).
Internal links
HTML elements with an id attribute create PDF destinations. Use <a href="#..."> to link to them:
<h2 id="introduction">Introduction</h2>
Some text...
Go back to <a href="#introduction">Introduction</a>.The id attribute works on any HTML element, block-level or inline. The href must start with # followed by the target id.
Go templates
The --template flag enables Go template expansion before Markdown processing:
glu --template document.mdThis processes the file through Go’s text/template engine first, allowing template directives like {{.Variable}} and {{range}} loops.
How it works
The Markdown-to-PDF pipeline has several stages:
Each stage is optional: a plain Markdown file without any Lua or frontmatter works fine.
Debug modes
Two debug flags let you inspect intermediate stages of the pipeline:
--markdown prints the expanded Markdown (after Lua blocks and inline expressions, before goldmark) to stdout:
glu --markdown document.md--html prints the generated HTML (after goldmark conversion, before PDF rendering) to stdout:
glu --html document.mdBoth flags suppress PDF generation and write to stdout instead. Use them together with shell redirection to save the output:
glu --html document.md > output.htmlBeyond Markdown
- Styling with CSS: set a stylesheet with
css:or--css, and everything from the default stylesheet to margin boxes and cross references. - Math: set
math: trueto write formulas between dollars. - Standards:
format,langandattachmentsmake tagged, archival and e-invoice PDFs. - Lua in documents:
{lua}blocks,{= expr =}expressions and a companion file. - Print-ready PDF: PDF/X, spot colors, overprint, bleed and crop marks.