Export existing Marp markdown files to PDF (default), HTML, PPTX, or PNG.
⚠️ Two silent failure modes (read first)
- Wrong theme dir → silent fallback. If the theme named in the file's
theme:frontmatter is not in the--theme-setdir, marp-cli does NOT error — it silently renders with the default theme (brand colors, headers, footers all gone). Always resolve the theme dir from the frontmatter theme name (Step 2). - Sandboxed PDF/PPTX export → CJK glyphs lost. When the Bash tool runs sandboxed, Chrome's printToPDF cannot access system CJK fonts: the PDF exports "successfully" but all Chinese/Japanese/Korean text is missing (only ASCII remains; file size drops sharply). Run PDF and PPTX exports with
dangerouslyDisableSandbox: true. HTML and PNG exports are unaffected.
Both failures are invisible in logs — they only show up when you render the produced PDF itself (Step 5).
Quick Reference
# Resolve THEME_DIR first (Step 2), then:
# PDF (default) — requires Chrome/Chromium; run UNSANDBOXED
npx @marp-team/marp-cli INPUT.md -o OUTPUT.pdf --theme-set "$THEME_DIR" --allow-local-files --html
HTML
npx @marp-team/marp-cli INPUT.md -o OUTPUT.html --theme-set "$THEME_DIR" --html
PPTX (editable, requires LibreOffice); run UNSANDBOXEDnpx @marp-team/marp-cli INPUT.md -o OUTPUT.pptx --pptx-editable --theme-set "$THEME_DIR" --allow-local-files
PNG sequencenpx @marp-team/marp-cli INPUT.md --images png -o OUTPUT_DIR/ --theme-set "$THEME_DIR"
## Workflow
### Step 1: Locate Input File
Find the Marp markdown file. It must contain `marp: true` in YAML frontmatter.
```bash
# Verify it's a Marp file
head -5 INPUT.md # should show "marp: true"
Step 2: Resolve Theme Directory (do NOT hardcode)
Read the theme: name from the input file's frontmatter, then find which skill's themes dir actually contains that CSS. Known theme locations:
| Theme dir | Themes |
|---|---|
~/.claude/skills/marp-slides-creator/themes/ |
academic, academic-lightblue, beam, border, gradient, jobs, simple, zju, … |
~/.claude/skills/marp-slides-lingnan/themes/ |
lingnan(Lingnan College, Sun Yat-sen University: crimson color scheme, school emblem in footer) |
THEME_NAME=$(sed -n 's/^theme:[[:space:]]*//p' INPUT.md | head -1)
THEME_DIR=$(grep -rl "@theme *$THEME_NAME\b" ~/.claude/skills/*/themes/*.css 2>/dev/null | head -1 | xargs dirname)
# Fallback: filename match
[ -z "$THEME_DIR" ] && THEME_DIR=$(ls ~/.claude/skills/*/themes/"$THEME_NAME".css 2>/dev/null | head -1 | xargs dirname)
echo "theme=$THEME_NAME dir=$THEME_DIR" # must be non-empty before exporting
If THEME_DIR is empty and the theme is not a marp built-in (default/gaia/uncover), STOP and locate the CSS — exporting anyway silently produces default-themed output.
Step 3: Detect Chrome/Chromium (for PDF/PPTX)
PDF and PPTX export require a Chrome/Chromium browser. Marp-cli auto-detects, but if it fails:
# macOS Chrome paths (check in order)
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version
/Applications/Chromium.app/Contents/MacOS/Chromium --version
/Applications/Microsoft\ Edge.app/Contents/MacOS/Microsoft\ Edge --version
# Set CHROME_PATH if auto-detection fails
export CHROME_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
If no browser found, fall back to HTML export and inform the user.
Step 4: Export
Default format is PDF. User can specify otherwise.
Output naming convention:
- Same directory as input file
- Same base name, different extension
- Example:
presentation.md→presentation.pdf
PDF export (Bash call must set dangerouslyDisableSandbox: true — sandboxed Chrome loses CJK fonts silently):
npx @marp-team/marp-cli INPUT.md \
-o OUTPUT.pdf \
--theme-set "$THEME_DIR" \
--allow-local-files \
--html
HTML export (sandbox OK):
npx @marp-team/marp-cli INPUT.md \
-o OUTPUT.html \
--theme-set "$THEME_DIR" \
--html
PPTX export (also unsandboxed — same Chrome print path as PDF):
npx @marp-team/marp-cli INPUT.md -o OUTPUT.pptx --pptx-editable --theme-set "$THEME_DIR" --allow-local-files --html
Step 5: Verify & Report
ls -lh is NOT enough — both silent failure modes produce a "successful" file. Render pages from the produced PDF itself and look at them:
ls -lh OUTPUT.pdf OUTPUT.html 2>/dev/null
# Render page 1 from the PDF (macOS, no extra deps)
sips -s format png -z 720 1280 OUTPUT.pdf --out /tmp/pdf_p1.png
# Or a specific page N with poppler:
pdftoppm -png -f N -l N -scale-to-x 1280 -scale-to-y 720 OUTPUT.pdf /tmp/pdf_pN
Then Read the PNG and visually confirm: theme styling present (brand colors, header/footer) and all text rendered (especially CJK). Do NOT rely on --images png output for verification — the screenshot path renders fine even when the PDF is missing glyphs.
Red flags:
- PDF file size far below a previous good export (e.g. 1.6M vs 2.7M for the same deck) → missing embedded CJK fonts
- Title page shows only ASCII fragments → sandboxed export; re-run unsandboxed
- Default-looking theme (no brand colors) → wrong
--theme-setdir; marp fell back silently
Report to user:
- Output file path(s), size(s), format(s)
- Which page(s) you visually verified
- Any warnings from marp-cli
Key Flags Reference
| Flag | Purpose | When to use |
|---|---|---|
--theme-set DIR/ |
Load custom themes | When custom .css themes exist |
--allow-local-files |
Allow local images | PDF/PPTX with local assets |
--html |
Enable HTML tags in markdown | Always recommended |
--pptx-editable |
Editable PPTX output | PPTX format (needs LibreOffice) |
--images png |
Export as PNG sequence | PNG format |
--pdf-notes |
Include speaker notes in PDF | When notes are present |
--pdf-outlines |
Add bookmarks to PDF | For long presentations |
Error Handling
| Error | Cause | Fix |
|---|---|---|
Chrome/Chromium not found |
No browser for PDF | Set CHROME_PATH or fall back to HTML |
theme not found |
Missing theme CSS | Check --theme-set path, use built-in theme |
Could not find an input |
Bad file path | Verify path and marp: true frontmatter |
| Blank/empty PDF | HTML tags without --html | Add --html flag |
| PDF missing all CJK text (no error shown) | Sandboxed Chrome can't read system fonts | Re-run export with dangerouslyDisableSandbox: true |
| Output uses default theme (no error shown) | theme: name not found in --theme-set dir |
Resolve THEME_DIR from frontmatter (Step 2); e.g. lingnan is in marp-slides-lingnan, not marp-slides-creator |
Examples
# Export a lingnan-themed deck to PDF (unsandboxed Bash call!)
npx @marp-team/marp-cli slides_project/05_final/presentation.md \
-o slides_project/05_final/slides.pdf \
--theme-set ~/.claude/skills/marp-slides-lingnan/themes/ \
--allow-local-files --html
# Quick HTML export (no Chrome needed)
npx @marp-team/marp-cli my-talk.md -o my-talk.html --html
# Batch export all .md files in a directory
for f in slides/*.md; do
npx @marp-team/marp-cli "$f" -o "${f%.md}.pdf" --allow-local-files --html
done