DEV Community

Chest Nuts
Chest Nuts

Posted on AI-assisted

How to Convert Markdown to Word Without Breaking Tables and Math

You write in Markdown. Someone else wants a Word document. Usually that's fine, until the file has a table, an equation, or a code block, and the .docx you send comes out looking broken.

This guide shows how to convert Markdown to Word properly, mostly with pandoc, and covers the problems I ran into after doing it a lot.

The one-liner

If you have pandoc installed, a basic Markdown to Word conversion is one command:

pandoc notes.md -o notes.docx
Enter fullscreen mode Exit fullscreen mode

Headings become real Word heading styles (so the navigation pane and table of contents work), lists become real lists, and pipe tables become Word tables. For a plain document, you can stop here.

Make it look like your documents: the reference doc

The default output uses pandoc's built-in styles. To match your company or school template, generate the reference file, edit its styles in Word, and pass it back:

pandoc -o reference.docx --print-default-data-file reference.docx
# open reference.docx in Word, change the styles (Heading 1, Normal, Table...), save
pandoc notes.md --reference-doc=reference.docx -o notes.docx
Enter fullscreen mode Exit fullscreen mode

Only the styles in reference.docx are used, not its content. If a change doesn't show up, you probably edited the text formatting directly instead of modifying the style.

Math: get real Word equations, not images

This is where most Markdown to Word converters fail. Pandoc's docx writer turns TeX math into native Word equations (OMML), so the equation stays editable in Word. You just have to make sure pandoc recognizes the math first.

Pandoc's Markdown understands $...$ and $$...$$ by default. But a lot of Markdown in the wild, including what you copy out of ChatGPT, uses \(...\) and \[...\]. Enable that explicitly:

pandoc -f markdown+tex_math_single_backslash notes.md -o notes.docx
Enter fullscreen mode Exit fullscreen mode

Two gotchas worth knowing:

  1. Dollar signs that are prices. Pandoc only treats $...$ as math when the opening $ has a non-space character right after it, and the closing $ has a non-space character right before it and is not followed by a digit. That rule keeps It costs $5 and $10 as text, but documents that mix prices and formulas on the same line can still trip it up. The safest habit is to escape prices as \$5.
  2. Display math inside lists. $$ blocks indented inside a list item sometimes get parsed as part of the paragraph. Put a blank line before and after the block.

Tables

Pipe tables convert fine:

| Plan    | Price | Change |
|---------|------:|-------:|
| Basic   |  $9   |   +4%  |
| Pro     |  $29  |  -2%   |
Enter fullscreen mode Exit fullscreen mode

Things to watch:

  • Column widths. Pandoc lets Word auto-size the columns. Wide tables with long text can overflow the page; set widths in your reference doc's table style, or fix them by hand in Word.
  • Line breaks in cells. Pipe tables can't hold multi-paragraph cells. Use <br> for a line break, or switch to pandoc's grid tables if you need real paragraphs.
  • Numbers. In Word a number in a table is just text. If the reader is going to sum the column, they want Excel, not Word.

Code blocks

Fenced code blocks with a language tag keep a monospace font and get syntax highlighting in the .docx:

```python
def growth(start, end, years):
    return (end / start) ** (1 / years) - 1
```
Enter fullscreen mode Exit fullscreen mode

Always add the language tag. Without it you get a plain monospace block, which is fine but harder to read.

Mermaid diagrams

Pandoc doesn't render Mermaid. Inside the .docx you'd just see the source code. Render diagrams to images first with mermaid-cli, then reference the image:

npx -p @mermaid-js/mermaid-cli mmdc -i flow.mmd -o flow.png
Enter fullscreen mode Exit fullscreen mode
![Signup flow](flow.png)
Enter fullscreen mode Exit fullscreen mode

Tall diagrams (vertical flowcharts) can run off the bottom of the page. Add a height attribute so pandoc scales them by height: ![Signup flow](flow.png){height=8in}.

A full command

Putting it together:

pandoc notes.md \
  -f markdown+tex_math_single_backslash \
  --reference-doc=reference.docx \
  -o notes.docx
Enter fullscreen mode Exit fullscreen mode

The no-install option

If you don't want to set up pandoc, or you need to hand this to non-developer colleagues, I built a browser tool for exactly this: a Markdown to Word converter where you paste Markdown, check the preview, and download a .docx. It runs the same kind of pipeline on the server, with the math delimiter handling, table sizing and Mermaid rendering above already done for you. Your first export doesn't need an account.

Pasting Markdown with a table and a formula into the editor before exporting to Word

Checklist

  • [ ] -f markdown+tex_math_single_backslash if your source uses \( \)
  • [ ] Escape $ when it means money
  • [ ] Blank lines around $$ blocks
  • [ ] Language tag on every code block
  • [ ] Mermaid rendered to PNG before conversion
  • [ ] --reference-doc for house styles

What breaks for you when you convert Markdown to Word? I'm collecting edge cases, so drop them in the comments.


Disclosure: I'm the developer of TODOC, the converter mentioned in the "no-install option" section. Everything else in this post works with plain pandoc.

Top comments (0)