005 - pdf / pdf-pptx / pdf-docx commands
Purpose: Export Office files to PDF via AppleScript (macOS only).
Status: Implemented (2026-05-07)
Requirements
Section titled “Requirements”mdd pdf-pptx [dir]finds PPTX files needing export, uses PowerPoint via AppleScriptmdd pdf-docx [dir]finds DOCX files needing export, uses Word via AppleScriptmdd pdf-docxupdates every table of contents, and best-effort every other field, before export, because Word does not evaluate fields on open and a TOC would otherwise be empty in the PDF;mdd pdf-docx --no-update-fields [dir]exports without the update.mdd pdfalways updatesmdd pdf-docxfirst closes, unsaved, any copy of the document Word already has open, because Word’sopenreturns that in-memory copy instead of re-reading the file- The
.docxis closed without saving, so the field update never changes the source or its mtime mdd pdf [dir]runs both- Staleness: only export if PDF missing or source is newer than PDF
- Excludes symlinks and files in
templates/directory - Skips (with a warning) a source whose
.pdfsibling is a symlink. The destination handed to the Office app is the resolved directory plus the.pdfname, never the resolved.pdfpath, so the app cannot be pointed at a link target; a.pdfthat is a symlink after the export counts as a failure. The[dir]argument itself may be a symlink - Skips (with a warning) files whose name contains control characters
- Double-extension output:
file.pptx.pdf,file.docx.pdf - Defaults to current directory if no
[dir]argument
Design Approach
Section titled “Design Approach”- Commands in
src/mdd/commands/pdf*.py; shared helpers insrc/mdd/utils/pdf_export.py - AppleScript invoked via
subprocess.run(['osascript', '-e', script, '--', src, pdf]); the script is a fixed constant with anon run argvhandler that reads the source and PDF paths asPOSIX file (item N of argv), so file names are data, never part of the program text. The Word script is assembled from fixed fragments bybuild_docx_applescript(update_fields=...) - Tables of contents are updated through Word’s
tables of contentscollection, notfields: pandoc wraps the TOC field in a content control, whichfieldsdoes not enumerate, and iteratingfieldscan fail outright with error -1708, so the general field pass runs insidetry - macOS only — fails gracefully on other platforms (osascript not found)
Implementation Notes
Section titled “Implementation Notes”Ported from quarto4sbp (cmd_pdf, cmd_pdf_pptx, cmd_pdf_docx). The
cmd_*(args) entrypoint shape was superseded by
S35’s register(subparsers, parents) convention;
the three modules now expose register() and _run_* handlers in
src/mdd/commands/pdf*.py.
Site built 2026-10-26.