Convert documents between formats using pandoc. Supports Markdown, Word (DOCX), HTML, LaTeX, PDF, and more. Ships with a styled Word reference template for polished Markdown-to-DOCX output. Use when the user asks to convert, export, or transform documents between formats.
Convert documents between formats using pandoc. This skill handles any conversion pandoc supports, with first-class support for producing polished Word documents from Markdown.
Pandoc must be installed on the system. Check with:
pandoc --version
If not installed, recommend:
brew install pandocsudo apt install pandocchoco install pandoc or download from https://pandoc.org/installing.htmlFor PDF output, a LaTeX engine is also required (e.g., brew install basictex or sudo apt install texlive).
This is the primary use case. Use the bundled reference template for styled output:
pandoc input.md -o output.docx \
--reference-doc=SKILL_PATH/assets/reference.docx \
--lua-filter=SKILL_PATH/assets/docx-polish.lua
Then fix list indentation (pandoc hardcodes deep nesting):
python SKILL_PATH/scripts/fix-list-indent.py output.docx
Replace SKILL_PATH with the actual path to this skill's directory. The reference template provides:
The Lua filter adds:
The post-processing script fixes:
# Markdown → HTML
pandoc input.md -o output.html --standalone
# Markdown → PDF (requires LaTeX)
pandoc input.md -o output.pdf
# Word → Markdown
pandoc input.docx -o output.md
# HTML → Markdown
pandoc input.html -o output.md
# Markdown → LaTeX
pandoc input.md -o output.tex
# Multiple inputs → single output
pandoc chapter1.md chapter2.md chapter3.md -o book.docx \
--reference-doc=SKILL_PATH/assets/reference.docx \
--lua-filter=SKILL_PATH/assets/docx-polish.lua
Always use the reference template and Lua filter unless the user provides their own:
pandoc input.md -o output.docx \
--reference-doc=SKILL_PATH/assets/reference.docx \
--lua-filter=SKILL_PATH/assets/docx-polish.lua
python SKILL_PATH/scripts/fix-list-indent.py output.docx
User-provided templates take priority. If the user specifies a custom .docx template, use it instead:
pandoc input.md -o output.docx --reference-doc=path/to/custom-template.docx
Table of contents — add --toc for longer documents:
pandoc input.md -o output.docx \
--reference-doc=SKILL_PATH/assets/reference.docx \
--lua-filter=SKILL_PATH/assets/docx-polish.lua --toc
python SKILL_PATH/scripts/fix-list-indent.py output.docx
Metadata — pandoc reads YAML front-matter from Markdown files for title, author, and date:
---
title: My Document
author: Author Name
date: 2025-01-15
---
--standalone (or -s) to produce a complete HTML file with <head> and <body>.--css=style.css or use --self-contained to embed styles inline.--pdf-engine=xelatex for better Unicode and font support.--variable geometry:margin=1in--extract-media=./media to save embedded images.| Error | Cause | Fix |
|---|---|---|
pandoc: command not found | Pandoc not installed | Install pandoc (see Prerequisites) |
Could not find reference.docx | Wrong path to reference template | Verify the SKILL_PATH and that assets/reference.docx exists |
pdflatex not found | No LaTeX engine for PDF output | Install LaTeX or convert to DOCX instead |
Could not convert image | Unsupported image format | Convert images to PNG/JPEG first |
The bundled assets/reference.docx can be further customized:
The scripts/customize-reference.py script can also regenerate the template from pandoc's defaults with the skill's style choices. It requires python-docx:
pip install python-docx
pandoc --print-default-data-file reference.docx > base.docx
python SKILL_PATH/scripts/customize-reference.py base.docx SKILL_PATH/assets/reference.docx
Obsidian uses ![[image.png]] syntax for image embeds, which pandoc doesn't understand natively. Use the bundled preprocessor to convert these to standard Markdown before passing to pandoc:
python SKILL_PATH/scripts/obsidian-img-preprocess.py input.md --image-dir attachments | \
pandoc -f markdown -o output.docx \
--reference-doc=SKILL_PATH/assets/reference.docx \
--lua-filter=SKILL_PATH/assets/docx-polish.lua
python SKILL_PATH/scripts/fix-list-indent.py output.docx
The --image-dir flag specifies the folder containing images (e.g., attachments, assets, media). If omitted, image paths are used as-is from the Markdown source.
Supported Obsidian syntax:
| Obsidian Syntax | Converted To |
|---|---|
![[image.png]] |  |
![[image.png|alt text]] |  |
![[image.png|600]] | { width=600px } |
![[image.png|800x400]] | { width=800px height=400px } |
![[subfolder/img.png]] |  |
Non-image embeds like ![[some-note]] are left unchanged.
You can also preprocess to a file instead of piping:
python SKILL_PATH/scripts/obsidian-img-preprocess.py input.md --image-dir attachments -o preprocessed.md
pandoc preprocessed.md -o output.docx \
--reference-doc=SKILL_PATH/assets/reference.docx \
--lua-filter=SKILL_PATH/assets/docx-polish.lua
Pandoc has extensive options. Some useful ones:
--wrap=none — don't wrap long lines in text output--columns=80 — wrap at 80 columns for text output--shift-heading-level-by=-1 — promote all headings by one level--strip-comments — remove HTML comments from input--lua-filter=filter.lua — apply custom transformations--metadata title="My Title" — set metadata from the command lineFor the full list, see pandoc --help or https://pandoc.org/MANUAL.html.
Edit PDFs with natural-language instructions using the nano-pdf CLI.