glu
Markdown mode

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.md

This produces document.pdf. glu detects the mode by the file extension: .lua for Lua scripts, .md for Markdown.

Pipeline

The Markdown-to-PDF pipeline has several stages:

.md file → frontmatter → companion .lua → Lua blocks → inline expressions → goldmark → HTML → htmlbag → PDF

Each stage is optional — a plain Markdown file without any Lua or frontmatter works fine.

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
---
Field Description
title PDF document title
author PDF author field
css Additional CSS file to load
papersize Page size (a4, letter, 20cm 20cm, etc.)

Companion Lua file

If a Lua file with the same base name exists (e.g., report.lua for report.md), it is loaded automatically before the Markdown is processed. This is the place for function definitions, variable initialization, and callback registration.

report.md      ← your document
report.lua     ← loaded automatically (if present)

Example report.lua:

local frontend = require("glu.frontend")

function currency(amount)
    return string.format("%.2f €", amount)
end

total = 42 * 3

The functions and variables are available in the Markdown file via Lua blocks and inline expressions.

Lua blocks

Fenced code blocks with {lua} are executed and removed from the output:

```{lua}
result = math.sqrt(144)
```

Lua blocks run in the same Lua state as the companion file. They execute in document order, so later blocks can use variables from earlier ones.

Inline expressions

Use {= expr =} to insert the result of a Lua expression:

The total is {= total =} and the square root of 144 is {= math.sqrt(144) =}.

Any Lua expression that returns a value works — variables, function calls, arithmetic:

The price is {= currency(19.99) =}.

Markdown features

glu uses goldmark with these extensions:

  • Tables — pipe tables with alignment
  • Strikethrough~~deleted~~
  • Autolinks — URLs are automatically linked

Standard Markdown features: headings, bold, italic, code, lists, blockquotes, horizontal rules, and links.

Default stylesheet

Markdown mode includes a built-in CSS stylesheet that provides sensible defaults:

  • A4 page size with 2cm margins
  • Serif font (CrimsonPro) for body text at 10pt
  • Scaled heading sizes (h1: 24pt down to h6: 10pt italic)
  • Monospace font (CamingoCode) for code and pre blocks
  • Table styling with header borders
  • Blockquote indentation and italic style

The defaults can be overridden with a custom CSS file.

Custom CSS

Additional CSS can be loaded in two ways:

Via frontmatter:

---
css: style.css
---

Via command line:

glu --css style.css document.md

The custom CSS is applied after the default stylesheet, so it overrides matching rules. You can use @page to change the page size and margins:

@page {
    size: letter;
    margin: 1in;
}

body {
    font-size: 11pt;
    line-height: 1.5;
}

h1 {
    color: #333;
}

Go templates

The --template flag enables Go template expansion before Markdown processing:

glu --template document.md

This processes the file through Go’s text/template engine first, allowing template directives like {{.Variable}} and {{range}} loops.

Debug mode

The --markdown flag prints the expanded Markdown to stdout instead of generating a PDF. Useful for debugging Lua block and inline expression expansion:

glu --markdown document.md

Complete example

report.md:

---
title: Monthly Report
author: Jane Doe
---

# Monthly Report

This report covers the period from January to March.

| Month   | Revenue  | Expenses |
|---------|----------|----------|
| January | {= currency(15420) =} | {= currency(12300) =} |
| February| {= currency(18900) =} | {= currency(14100) =} |
| March   | {= currency(21050) =} | {= currency(15800) =} |

**Total revenue:** {= currency(15420 + 18900 + 21050) =}

---

> Report generated with glu.

report.lua:

function currency(amount)
    return string.format("%.2f €", amount)
end

Run:

glu report.md    # → report.pdf

Command line reference

glu [options] <filename.lua|filename.md>

Options:
  --loglevel LVL    Set the log level (debug, info, warn, error)
  -q, --quiet       Suppress output on console
  --template        Apply Go template expansion (Markdown mode)
  --css FILE        Additional CSS file (Markdown mode)
  --markdown        Print expanded Markdown to stdout (debug)