Markdown to PowerPoint with editable slides

Use Pandoc to convert Markdown to PowerPoint when the handoff needs editable text and tables, and set the slide boundary explicitly. Choose among three cases: a deck colleagues will revise, a deck whose appearance matters most, and a deck with private speaker notes. In our local conversions, a prose insertion changed pagination and a reader change exposed a private cue. 8

Choose the route by what must stay editable

Choose native slide objects for editing, image-based export for a rendered appearance, and a notes-aware reader for private cues.

Feature you need How to recognize the requirement Route
Editable wording and table cells Write down the required edit: a recipient must change the wording of a bullet or the contents of an individual table cell inside PowerPoint Pandoc's PPTX writer, followed by layout work
A rendered slide appearance Compare the handoff requirements with the rendered preview: preserve the page's appearance, and accept that editing its text is secondary Consider a rendering-first exporter such as Marp, with its documented PPTX limits
Private presenter material Search for a rehearsal phrase in the slide and notes pane: it must appear in notes and stay absent from the audience slide Pandoc Markdown with a plain notes block, using the syntax below

In our simple Pandoc deck, the package contained text shapes and a native table, with no picture objects. 8

Marp CLI documents a different default: its PPTX slides contain rendered images. Its experimental editable export requires additional software, including LibreOffice, and does not support presenter notes. Marp was not executed for this guide. 3

Material already locked in an old deck needs extraction before it needs a new slide theme. Markovo's PowerPoint to Markdown route is a signed-in beta for that upstream task. It produces Markdown from a deck. It does not provide the Markdown-to-PowerPoint rendering tested here or promise a layout round trip.

Convert Markdown to PowerPoint with explicit boundaries

Set the slide level explicitly so a prose edit does not silently change which heading level starts a content slide.

Use a section heading to group the deck and content headings to name the audience slides. Save the following sample as input.md before running the command. It includes a short table so the conversion exercises both text and cell structure. 8

# Project review
        
        ## Scope
        
        - Keep the wording editable.
        - Keep the audience view concise.
        
        | Item | Owner |
        | --- | --- |
        | Draft | Mira |
        | Review | Omar |
        
        ## Decision
        
        Approve the pilot.
        
pandoc --from=markdown input.md --slide-level=2 --output=output.pptx
        

Pandoc places headings above that level on section slides and uses headings at the chosen level to start content slides. Deeper headings belong within those content slides. 1

Output from our editable-table sample, unedited:

Scope
        Keep the wording editable.
        Keep the audience view concise.
        Item
        Owner
        Draft
        Mira
        

The transcript lists words extracted from the slide objects. The table remains a native table in the package, so the line-by-line extraction above describes its text rather than its layout. 89

Automatic slide selection gave the original sample three slides. Its section heading was followed immediately by a content heading. 8

Adding a short introduction below that section heading collapsed the automatic output into a single slide. The headings had not changed, but their relationship to body text had. 8

Explicit slide selection preserved the content-slide boundary, yet the introduction still added a separate slide. The introductory variant produced four slides. A Pandoc issue also reports an unexpected extra slide after adding section text. Our fixture checks the related minimal pattern, not the reporter's complete environment. 84

Move section commentary into a named content slide or into speaker notes when you do not want an extra introduction slide. Omitting body text after section headings avoids the added introduction in this fixture.

Failure condition What you see What to change
Automatic selection after adding section prose Previously separate content headings share an audience slide Set the intended slide level explicitly
Section prose with an explicit content level The content slides remain, but an introduction slide appears Give the prose its own content heading or move it into notes
Too much content under a valid heading The structure can be correct while the layout remains unproven Shorten or divide the content before adjusting its theme

Keep speaker notes out of the audience view

Use a plain notes block with Pandoc's Markdown reader, because changing the reader or adding a class can move the cue onto the slide.

Append this block beneath the content it accompanies. Its text is deliberately recognizable, so you can search for that phrase in both the audience slide and the notes pane after opening your own deck. In our package inspection, this form placed the phrase in notes and omitted it from slide text. 8

::: notes
        
        Private rehearsal cue.
        
        - Pause before the decision.
        
        :::
        

The conversion command above uses Pandoc Markdown. Replacing that reader with GFM left the cue in the audience slide and created no matching speaker note in our fixture. 8

Output from our GFM-reader sample, unedited:

Decision
        Approve the pilot.
        ::: notes
        Private rehearsal cue.
        Pause before the decision.
        :::
        

Changing the opening fence to ::: {.notes .extra} also exposed the cue, even with the Pandoc Markdown reader. Pandoc's version-pinned writer source explains this result: its notes predicate accepts a class list containing only the notes class. The writer uses that predicate when separating speaker notes from ordinary slide blocks. 28

Input or reader choice Observed result Decision
Plain notes block, Pandoc Markdown Cue in notes, absent from audience text Use this form for the tested route
Same source, GFM reader Cue and fence text in audience text Keep the reader explicit when notes matter
Notes block with an extra class Cue in audience text, absent from notes Remove the extra class from the notes container
HTML comment Cue absent from both slide text and notes Do not use comments as a substitute for speaker notes
Blockquote Quoted wording remains audience text Use it for visible quotations

A local CommonMark HTML rendering made the syntax mismatch visible before PPTX export: the notes fence became an ordinary paragraph. This is a parser observation, not a second PowerPoint conversion route. Our CommonMark configuration also leaves the pipe table as paragraph text, so its HTML preview cannot stand in for Pandoc's table handling. 811

Output from our CommonMark notes sample, unedited:

<p>::: notes</p>
        <p>Private rehearsal cue.</p>
        <ul>
        <li>Pause before the decision.</li>
        </ul>
        <p>:::</p>
        

Apply a reference deck after the structure works

Apply a reference deck after the headings and notes work, because a theme does not repair the content-routing choices above.

Pandoc uses a reference PPTX for slide layouts and styling. Its documented layouts include Title Slide, Title and Content, and Section Header. A corporate template needs compatible named layouts. Its existing slides are not the content source for the new presentation. 1

These commands extract Pandoc's default reference deck and use it explicitly. We ran both commands locally. Supplying that default reference kept the simple fixture's slide and table structure unchanged, but it is not a test of a company's branded template. 8

pandoc --print-default-data-file=reference.pptx > reference.pptx
        pandoc --from=markdown input.md --slide-level=2 --reference-doc=reference.pptx --output=output.pptx
        
Symptom Layer to inspect Concrete distinction
A section has swallowed its content slides Heading and slide-level choices Rebuild the small heading fixture before changing the theme
A private cue appears on the audience slide Reader and notes-container syntax Search for the cue in both slide text and the notes pane
Text wraps badly or a table extends past the slide Content density, fonts, and layout Open the deck and inspect the affected text box or table
A branded reference deck fails Reference layouts Compare the named layouts with Pandoc's documented requirements

For an editable handoff, the repeatable path is Pandoc with an explicit content-heading level and plain notes syntax. Keep the Markdown focused on slide-sized claims, then apply the reference deck. Our experiment establishes the native objects, slide boundaries, and notes destinations in the package. Opening the generated deck remains necessary to judge its appearance.

How we tested

We tested local Markdown parsing and PPTX package structure, not rendering inside PowerPoint, Keynote, GitHub.com, or VS Code.

Tests ran on 2026-10-26 with Pandoc 3.11, markdown-it-py 4.0.0, and Python 3.11.14. Pandoc used its markdown and gfm readers. markdown-it used commonmark with html=True and no table or fenced-div plugin. Marp was not executed for this guide. Markovo is the service we build; its incoming PPTX-to-Markdown path was not part of this experiment.

Input under lab/renderers/ Represents
headings.md Section/content headings, bullets, a small pipe table
intro.md Same content with prose directly after the section heading
notes.md Plain notes container with a cue and list item
notes-extra.md Same notes content with an additional class
comment.md HTML comment containing the cue
quote.md Visible Markdown blockquote

Run from the repository root:

PYTHONDONTWRITEBYTECODE=1 tools/lab-venv/bin/python runs/2026-10-26-markovo-markdown-to-powerpoint/lab/renderers/run_render.py
        

The script records every subprocess argument, option, exit status, and stderr in lab/renderers/results.json. For each input it runs Pandoc to HTML and JSON AST with both readers, and markdown-it to HTML. It also runs the article's conversion commands. The explicit reference test uses Pandoc's extracted default reference deck, not an independently designed template. 8

Pandoc case Slides Native tables Pictures Cue in slide text Cue in notes
headings-auto 3 1 0 No No
headings-explicit 3 1 0 No No
intro-auto 1 1 0 No No
intro-explicit 4 1 0 No No
notes-markdown 3 1 0 No Yes
notes-gfm 3 1 0 Yes No
notes-extra 3 1 0 Yes No
comment-markdown 3 1 0 No No
quote-markdown 3 1 0 No No
reference-explicit 3 1 0 No No

The table is a direct summary of results.json cases, not a quality score. Slide counts enumerate ppt/slides/slideN.xml. Native tables count a:tbl; pictures count p:pic. Cue placement searches literal text in slide text runs and notes-body placeholders. These checks do not measure clipping, fonts, visual fidelity, or application compatibility. No PDF/OCR scorer or scores.json applies to this Markdown-rendering branch.

For the same notes.md source, the HTML structural comparison was:

Local implementation Notes div HTML table
Pandoc Markdown Yes Yes
Pandoc GFM No Yes
markdown-it CommonMark No No

Raw artifacts include notes-markdown.output.md, notes-gfm.output.md, and notes.commonmark.html.txt. The first two are text extracted from the package; the last is unedited HTML. Each generated case also has raw slide/notes XML saved with a .txt extension, and each Pandoc reader has a JSON AST for every input. The script and the results file define the complete artifact naming and counting rules. 891011

Sources

Sources

  1. Pandoc User's Guide
  2. Pandoc 3.11 PowerPoint writer source
  3. Marp CLI README: PowerPoint export
  4. Pandoc issue 6338: section text and extra slides
  5. Local results and full command record
  6. Extracted slide and notes text
  7. GFM-reader slide text
  8. CommonMark HTML output