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 .md file 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 pandoc from PATH, 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 / pdflatex setup.

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

  1. Open any .md file.
  2. Right-click in the editor → Pandoc → pick the target format.
  3. The output is written next to the source (or to pandoc.outputDir if configured).

Convert a folder

  1. Right-click a folder in the Explorer.
  2. Pick Pandoc › Convert All Markdown to DOCX / HTML / PDF.
  3. Every .md file 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.

CommandIDWhere it appears
Convert Markdown to DOCXpandoc.convertToDocxEditor / Explorer (on .md) · Command Palette
Convert Markdown to HTMLpandoc.convertToHtmlEditor / Explorer (on .md) · Command Palette
Convert Markdown to PDFpandoc.convertToPdfEditor / Explorer (on .md) · Command Palette
Convert All Markdown to DOCXpandoc.convertFolderToDocxExplorer (on folders)
Convert All Markdown to HTMLpandoc.convertFolderToHtmlExplorer (on folders)
Convert All Markdown to PDFpandoc.convertFolderToPdfExplorer (on folders)
Generate Sample Markdownpandoc.generateSampleMarkdownCommand Palette

Settings

Every setting is namespaced under pandoc.* — search for "pandoc" in VS Code settings.

General

SettingTypeDefaultDescription
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:

SettingWhen applied
pandoc.{format}.commonArgsAlways.
pandoc.{format}.singleFileCustomArgsSingle-file conversions only — merged on top of commonArgs.
pandoc.{format}.multipleFilesCustomArgsFolder/batch conversions only — merged on top of commonArgs.
Deprecation: 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.

FilterWhat 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.filters run 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.