Markdown → PDF converter with live preview, per-document CSS editing, and two PDF export modes:
- Selectable-text PDF (recommended): generated by a local FastAPI + Playwright service (prints HTML in headless Chromium)
- Fallback PDF: generated in the browser via
html2pdf(image-based; text is not selectable)
pip install -r requirements.txt
python -m playwright install chromiumpython server.pyOpen:
http://127.0.0.1:8010/
Now Download PDF will call /api/pdf and download a selectable-text PDF.
If the server isn’t running, the app automatically falls back to html2pdf.
You can open index.html directly, but browsers restrict some behaviors on file:// pages.
For the best experience (raw CSS loading + selectable-text PDFs), use the local server.
- Real-time preview with A4 pagination
- Markdown + CSS tabs (CSS is per-document)
- Save .md exports Markdown and embeds custom CSS only if changed
- Load .md restores both Markdown + embedded CSS
- Page numbers toggle (preview + PDFs)
- Preview zoom persists across refresh
- Fullscreen preview with floating Save/Download buttons
- Auto-save to browser storage (Markdown, CSS, zoom, page numbers)
- Manual page breaks via
<div class="page-break"></div>
- markdown-styles.css is the default Markdown styling.
- The CSS tab starts from that default and lets users customize styling for a specific document.
- PDFs always include the CSS currently in the CSS tab.
When you click Save .md, the app appends a comment block to the Markdown file containing the CSS.
When you upload that .md later, the app extracts the CSS back into the CSS tab automatically.
- Ctrl/Cmd + S: Save project (.mdfproj)
- Ctrl/Cmd + Alt + P: Export PDF
- Ctrl/Cmd + K: Clear editor
- Ctrl/Cmd + O: Upload file
- Ctrl/Cmd + Enter: Insert page break
- Alt + N: Insert
<br>line break - Alt + R: Float selected text right
- Ctrl/Cmd + B: Bold
- Ctrl/Cmd + I: Italic
- Ctrl/Cmd + E: Inline code
- Tab: Insert 4 spaces
Add this in your Markdown to force a new page:
<div class="page-break"></div>mdToPdf/
├── index.html # UI
├── styles.css # App styling
├── markdown-styles.css # Default Markdown styling
├── script.js # Client logic
├── server.py # FastAPI + Playwright PDF service + static host
├── requirements.txt # Python deps
└── README.md
- If you want the selectable-text PDF mode, run the server (
python server.py). - If you don’t run the server, PDF export still works, but it uses the image-based fallback.