Pandoc Extension for VS Code
Convert Markdown to DOCX, HTML and PDF from inside Visual Studio Code — powered by Pandoc.
At a glance
- One-click conversionsDOCX, HTML and PDF from the editor or explorer context menu.
- Batch folder conversionRight-click a folder to convert every
.mdfile at once. - Built-in Lua filtersHeader IDs, Mermaid diagrams, page breaks, line breaks — enabled by default.
- Custom Pandoc argsPer-format args plus separate single-file vs. folder overrides.
- Reference docs & templatesUse your own
--reference-doc, CSS, or PDF engine. - Bring your own PandocUses
pandocfromPATH, or any path you configure.
Installation
The extension shells out to Pandoc, so you need Pandoc installed on your system first.
1. Install Pandoc
- macOS:
brew install pandoc - Windows:
winget install --id JohnMacFarlane.Pandoc— or download from pandoc.org. - Linux:
sudo apt install pandoc(Debian/Ubuntu) ·sudo dnf install pandoc(Fedora)
Verify the install:
pandoc --version
2. (Optional) PDF engine
PDF output requires a LaTeX engine. Recommended:
- Tectonic (modern, auto-downloads packages):
brew install tectonic - MacTeX / TeX Live / MiKTeX for a full
xelatex/pdflatexsetup.
3. (Optional) Mermaid CLI
Required only if you want the builtin:mermaid-filter to render Mermaid diagrams:
npm install -g @mermaid-js/mermaid-cli
4. Install the extension
From the Visual Studio Marketplace, or inside VS Code:
ext install AhmedYoussef.pandoc-vscode
Quick start
Convert the active file
- Open any
.mdfile. - Right-click in the editor → Pandoc → pick the target format.
- The output is written next to the source (or to
pandoc.outputDirif configured).
Convert a folder
- Right-click a folder in the Explorer.
- Pick Pandoc › Convert All Markdown to DOCX / HTML / PDF.
- Every
.mdfile in the folder is converted in one pass.
Generate a sample
From the Command Palette (Cmd/Ctrl+Shift+P), run Pandoc: Generate Sample Markdown. A demo file is dropped into your workspace showing how the built-in filters behave.
Commands
All commands are available in the Command Palette under the Pandoc category, and via the right-click menus in the Editor and Explorer.
| Command | ID | Where it appears |
|---|---|---|
| Convert Markdown to DOCX | pandoc.convertToDocx | Editor / Explorer (on .md) · Command Palette |
| Convert Markdown to HTML | pandoc.convertToHtml | Editor / Explorer (on .md) · Command Palette |
| Convert Markdown to PDF | pandoc.convertToPdf | Editor / Explorer (on .md) · Command Palette |
| Convert All Markdown to DOCX | pandoc.convertFolderToDocx | Explorer (on folders) |
| Convert All Markdown to HTML | pandoc.convertFolderToHtml | Explorer (on folders) |
| Convert All Markdown to PDF | pandoc.convertFolderToPdf | Explorer (on folders) |
| Generate Sample Markdown | pandoc.generateSampleMarkdown | Command Palette |
Settings
Every setting is namespaced under pandoc.* — search for "pandoc" in VS Code settings.
General
| Setting | Type | Default | Description |
|---|---|---|---|
pandoc.path |
string |
(empty) | Absolute path to the pandoc executable. Empty = use PATH. |
pandoc.outputDir |
string |
(empty) | Default output directory. Empty = next to the source file. Relative paths resolve against the workspace folder; ${workspaceFolder} is supported. |
pandoc.filters |
string[] |
All 4 built-ins | Ordered list of Lua filters. See Built-in Lua filters. |
Per-format arguments
For each format (docx, html, pdf) there are three settings that layer together:
| Setting | When applied |
|---|---|
pandoc.{format}.commonArgs | Always. |
pandoc.{format}.singleFileCustomArgs | Single-file conversions only — merged on top of commonArgs. |
pandoc.{format}.multipleFilesCustomArgs | Folder/batch conversions only — merged on top of commonArgs. |
pandoc.{format}.customArgs is deprecated in favour of commonArgs. If both are set, commonArgs wins.
Example
{
"pandoc.path": "/usr/local/bin/pandoc",
"pandoc.outputDir": "${workspaceFolder}/output",
"pandoc.filters": [
"builtin:header-id-from-comment",
"builtin:html-br-to-linebreak",
"builtin:mermaid-filter",
"builtin:page-break"
],
"pandoc.docx.commonArgs": [
"--reference-doc=${workspaceFolder}/templates/template.docx"
],
"pandoc.docx.multipleFilesCustomArgs": [
"--toc",
"--number-sections"
]
}
Built-in Lua filters
The extension ships with four Lua filters. They’re enabled by default; reorder, remove, or interleave your own filters via pandoc.filters.
| Filter | What it does |
|---|---|
builtin:header-id-from-comment |
Reads <!-- {#my-id} --> markers after a heading and assigns that ID, then rewrites cross-references to match. Useful for stable anchors across format conversions. |
builtin:html-br-to-linebreak |
Converts raw <br> tags in your Markdown into native Pandoc line breaks — so they survive into DOCX and PDF, not just HTML. |
builtin:mermaid-filter |
Detects mermaid-tagged code fences, renders them with mermaid-cli, and embeds the resulting image. Requires mmdc on PATH. Cached output goes into mermaid-images/ — add it to .gitignore. |
builtin:page-break |
Converts <!-- pagebreak --> comments into real page breaks for DOCX/PDF output. |
Custom filters
Mix in your own Lua filters by referencing absolute paths or workspace paths:
{
"pandoc.filters": [
"builtin:header-id-from-comment",
"builtin:page-break",
"${workspaceFolder}/filters/word-count.lua"
]
}
To disable all filters, set "pandoc.filters": [].
Custom Pandoc arguments
Anything you can pass to Pandoc on the command line, you can pass via these settings. The extension always invokes Pandoc as:
pandoc <source(s)> -o <output> \
<filter flags from pandoc.filters> \
<commonArgs> <singleFile|multipleFiles args>
Layering example
Say you want a base DOCX template for all conversions, but the folder/batch output should also include a TOC and numbered sections:
{
"pandoc.docx.commonArgs": [
"--reference-doc=${workspaceFolder}/templates/base.docx"
],
"pandoc.docx.singleFileCustomArgs": [],
"pandoc.docx.multipleFilesCustomArgs": [
"--toc",
"--number-sections",
"--reference-doc=${workspaceFolder}/templates/with-cover.docx"
]
}
Pandoc applies later --reference-doc flags last-wins, so the batch run picks up the cover-page template.
Common recipes
- Use XeLaTeX for PDF:
"pandoc.pdf.commonArgs": ["--pdf-engine=xelatex"] - Standalone styled HTML:
"pandoc.html.commonArgs": ["--standalone", "--css=style.css"] - Resolve relative images:
"pandoc.docx.commonArgs": ["--resource-path=.:./images"] - Numbered sections + TOC: add
"--toc"and"--number-sections".
Troubleshooting
"pandoc: command not found" / "spawn pandoc ENOENT"
The extension can’t find Pandoc on PATH. Either install Pandoc (see Installation) or set pandoc.path to the absolute path of the executable.
PDF conversion fails with a LaTeX error
Pandoc needs a LaTeX engine for PDF. Install one (Tectonic, MacTeX, MiKTeX, TeX Live) and, if needed, point Pandoc at it explicitly:
"pandoc.pdf.commonArgs": ["--pdf-engine=xelatex"]
Mermaid diagrams don’t render
Install mermaid-cli so the mmdc binary is on PATH:
npm install -g @mermaid-js/mermaid-cli
Then remove the cached mermaid-images/ folder and re-run the conversion.
Output goes to the wrong place
Check pandoc.outputDir. When empty, output is written next to the source file. Relative values resolve against the workspace folder — not the source file’s folder.
My custom filter isn’t running
- Filters in
pandoc.filtersrun in array order — make sure yours is in the list. - Use an absolute path or
${workspaceFolder}/.... Bare relative paths won’t resolve. - If you cleared the array entirely (
[]), no filters run — including the built-ins.
Still stuck?
Open an issue on GitHub with the VS Code Output panel contents (select the “Pandoc” channel) and your pandoc --version output.