Markdown Publishing skill for Claude Code
One Markdown source, clean PDF, DOCX and HTML. Claude sets up repeatable pandoc builds instead of one-off commands: a defaults file per output, a reference.docx that carries your Word house styles, citeproc with real CSL styles, and the right PDF engine for the job, whether LaTeX, Typst or WeasyPrint. It handles cross-references, math, diagrams and Lua filters, then opens each output to check it.
- name
markdown-publishing - size190 lines · ≈1,800 tokens
- files1
- licenseMIT
- updated
What Claude sees before loading it
This description is the only part of the skill that sits in context all the time. Claude reads it to decide when to load the full playbook below.
description: Converts Markdown into polished HTML, PDF, and DOCX with pandoc — YAML metadata, defaults files for repeatable builds, tables of contents and numbered sections, citations with citeproc and CSL styles, reference.docx styling for Word output, PDF engines (LaTeX, Typst, WeasyPrint), custom templates, Lua filters, and diagram handling. Use when the user wants Markdown turned into a PDF report, Word document, standalone HTML page, or ebook, needs a consistent house style across exports, or has citations, TOC, or math to render. Try asking
- Convert our Markdown handbook into a styled PDF and Word version
- Make pandoc use our company Word template when exporting this report
- Add citations with APA style to this Markdown paper and build a PDF
Use it when
- Markdown needs to ship as PDF, DOCX, or standalone HTML
- Several documents must share one consistent house style
- A Markdown document has citations, math, or a table of contents
- Builds must be reproducible in CI from committed config
Skip it when
- You are building a navigable multi-page docs website — use docs-site instead
- The document is authored directly in LaTeX — use latex-documents instead
How to check the result
Every target builds from a clean directory without citation or missing-resource warnings, and each output is opened or rendered to confirm the TOC, figures, tables and citations.
The common mistake it prevents
Styling Word output by editing the generated DOCX each time instead of the reference.docx styles, so every rebuild loses the formatting work.
Done well means: one command (or one defaults file) rebuilds every output from the same Markdown source; headings, TOC, citations, figures, and code render correctly in each format; Word output uses the house styles from a reference document; and you opened or rendered each output to check it rather than trusting the exit code.
Setup
brew install pandoc # or apt install pandoc / download a 3.x release; check: pandoc --version
# PDF engines (pick one):
brew install --cask mactex-no-gui # LaTeX (lualatex/xelatex); Debian: apt install texlive-luatex texlive-latex-extra
brew install typst # Typst: fast, small install (pandoc 3.1.2+)
pip install weasyprint # HTML + CSS to PDF
Choose the PDF route
| Need | Route |
|---|---|
| Academic look, math-heavy, precise typography | --pdf-engine=lualatex (LaTeX template) |
| Fast builds, simple install, modern defaults | --pdf-engine=typst |
| Design matches a website / CSS skills on hand | HTML + CSS, --pdf-engine=weasyprint |
| Must be edited by others in Word | DOCX with --reference-doc, then PDF from Word if required |
Source conventions
---
title: "Incident Review: Checkout Latency"
subtitle: "March 2026"
author: ["Jane Doe", "Platform Team"]
date: 2026-03-02
lang: en-GB
bibliography: refs.bib
csl: ieee.csl
link-citations: true
abstract: |
One-paragraph summary.
---
# Summary {#sec-summary}
Latency rose after the cache change [@dean2013tail, p. 76]. See @fig-latency.
{#fig-latency width=80%}
| Region | p99 (ms) |
|:-------|---------:|
| EMEA | 310 |
: Latency by region {#tbl-latency}
- One
#level per document section; do not skip levels. - Image paths are relative to the working directory pandoc runs in (or
--resource-path). - Pipe tables cannot hold multi-line cells; use grid tables or list tables (filter) for that.
- Raw HTML in Markdown only survives HTML outputs; raw LaTeX only LaTeX/PDF outputs.
Defaults file (repeatable builds)
pdf.yaml:
from: markdown+smart
to: pdf
pdf-engine: lualatex
input-files: [report.md]
output-file: build/report.pdf
standalone: true
table-of-contents: true
toc-depth: 2
number-sections: true
citeproc: true
resource-path: [".", "figures"]
variables:
geometry: margin=2.5cm
mainfont: "Source Serif 4"
monofont: "JetBrains Mono"
colorlinks: true
linkcolor: blue
docx.yaml and html.yaml follow the same shape. Build:
pandoc -d pdf.yaml
pandoc -d docx.yaml
pandoc -d html.yaml
Equivalent one-liners:
pandoc report.md -o build/report.html --standalone --embed-resources --toc --citeproc --css style.css
pandoc report.md -o build/report.docx --toc --citeproc --reference-doc=reference.docx
pandoc report.md -o build/report.pdf --pdf-engine=typst --toc --number-sections --citeproc
pandoc report.md -o build/report.pdf --pdf-engine=weasyprint --css print.css --citeproc
--embed-resources --standalone inlines images, CSS, and scripts into one HTML file
(the older --self-contained flag is deprecated).
Word output with house styles
- Generate the default reference document:
pandoc -o reference.docx --print-default-data-file reference.docx - Open it in Word or LibreOffice and modify the styles (Normal, Heading 1–3, Title, Body Text, First Paragraph, Compact, Table, Source Code, Hyperlink, header/footer, margins). Do not add content; only styles and page setup are used.
- Build with
--reference-doc=reference.docx.
Pandoc maps Markdown to those named styles, so changing a style changes every document.
Custom paragraph styles: ::: {custom-style="Callout"} … ::: uses a style named
“Callout” in the reference doc.
Citations
- Bibliography formats: BibTeX/BibLaTeX (
.bib), CSL JSON (.json), CSL YAML. - Styles: download
.cslfiles from the Zotero Style Repository / citation-style-language styles repo (e.g.apa.csl,ieee.csl,chicago-author-date.csl). - Syntax:
[@key],[@key, p. 4],[-@key](suppress author),@key(in-text),[@a; @b]. The bibliography is placed at the end, or where::: {#refs} :::appears. - Unresolved keys print as
?keyand pandoc warnsCiteproc: citation key not found; treat warnings as errors in CI (--fail-if-warnings). - Never invent references; use the user’s bibliography and flag anything unverifiable.
Cross-references, math, code, diagrams
- Cross-references (
@fig-latency→ “Figure 1”): use thepandoc-crossreffilter (--filter pandoc-crossref, before--citeproc), or Quarto, which builds on pandoc and supports them natively. Plain pandoc does not number figure references by itself. - Math:
$...$and$$...$$. HTML needs--mathjaxor--katex; DOCX converts to native Word equations; LaTeX/Typst PDF render natively. - Code highlighting is on by default; choose a theme with
--highlight-style=tango(newer pandoc releases also accept--syntax-highlighting; checkpandoc --help). - Mermaid/PlantUML: pandoc does not render them. Pre-render to SVG/PDF (see
mermaid-diagrams:
mmdc -i README.md -o README.out.mdreplaces blocks with images) or use a filter. For PDF via LaTeX, use PDF or PNG figures; SVG needsrsvg-convertinstalled.
Templates and filters
- Inspect and customize a template:
pandoc -D html > templates/report.html, then--template templates/report.html. Same forlatex,typst. - Small transformations belong in Lua filters, not regex post-processing:
-- filters/callout.lua: turn > **Note:** blockquotes into a styled div
function BlockQuote(el)
local first = el.content[1]
if first and first.t == "Para" and first.content[1] and first.content[1].t == "Strong" then
local label = pandoc.utils.stringify(first.content[1])
if label == "Note:" then
return pandoc.Div(el.content, pandoc.Attr("", {"callout"}))
end
end
end
pandoc report.md --lua-filter filters/callout.lua -o report.html
Gotchas
- PDF via LaTeX fails on Unicode glyphs missing from the font (emoji, CJK). Set
mainfontto a font with coverage and use lualatex/xelatex, or use Typst. - Wide tables overflow PDF pages; use landscape sections, smaller font via template, or split the table.
- Relative links between Markdown files (
other.md) stay as.mdlinks in HTML; rewrite with a Lua filter or a site generator if publishing multiple pages. - Smart quotes and dashes come from the
smartextension; disable withmarkdown-smartfor code-heavy prose that must keep straight quotes. - DOCX tables take the reference doc’s “Table” style; pandoc does not apply Word table styles beyond that.
Verification
- Build every target from a clean
build/directory with--fail-if-warningswhere practical; nocitation key not foundor missing-resource warnings. - Open each output (render the PDF first page to PNG with
pdftoppm -png -r 60 -f 1 -l 1, inspect the DOCX with docx-documents tooling, view the HTML) and check TOC, headings, figures, tables, citations, and code blocks. - Commit the defaults files, reference.docx, CSL, templates, and filters so builds are reproducible.
About this skill
Written and maintained by the Claude Skills editors to the same editorial standard as every skill in the directory: a selective trigger, a real workflow, known pitfalls and a verification step. First published , last updated . MIT licensed.