markpublisher
v1.3.0
Published
Convert extended Markdown into styled HTML and PDF for professional book publishing
Downloads
62
Maintainers
Readme
MarkPublisher
Convert extended Markdown (with HTML comment directives) into styled HTML and PDF for professional book publishing.
Quick Start
# Create a new book project
npx create-markpublisher-book my-book
cd my-book
markpublisher serveOr using npm:
npm install -g markpublisher
markpublisher init my-book
cd my-book
markpublisher serveFeatures
- Two-column layout via CSS multi-column with column breaks and spans
- Hyperlinked table of contents with dotted leaders and page numbers
- Footnotes via standard
[^1]syntax - Tables with custom column widths via
<!-- table: -->directive - Image CSS directives for per-image styling
- Running headers per page with chapter titles
- Configurable page numbering (arabic/none, persistent state)
- Wikilink includes (
![[path]]) for multi-file projects, project-root-first resolution - Fenced containers with nesting for styled blocks
- Offline HTML output — images, fonts, and CSS are bundled into
output/assets/ - Live-reload dev server for preview while editing
- Pagination toolbar — zoom, single/facing spread, page navigation in both serve and build
- Pluggable theme system with CSS
- PDF output via Puppeteer with full paged-media support
Configuration
Create a markpublisher.toml in your project root:
input = "book.md"
theme = "default"
outputDir = "./output"
[output]
html = true
pdf = true
[build]
failOnWarning = false
[serve]
port = 3000Markdown Extensions (Directives)
All directives use HTML comment syntax so they're invisible in Obsidian, GitHub, and VS Code.
Page Directives
| Directive | Description |
| ------------------------------ | -------------------------------------- |
| <!-- pagebreak --> | Start a new page |
| <!-- layout:twocol --> | Switch to two-column layout (default) |
| <!-- layout:singlecol --> | Switch to single-column layout |
| <!-- page-number:start=1 --> | Enable arabic numbering, reset counter |
| <!-- page-number:none --> | Hide page numbers |
| <!-- header:show --> | Show running headers |
| <!-- header:hide --> | Hide running headers |
Page directives persist across pagebreak boundaries until changed.
Flow / Content Directives
| Directive | Description |
| ----------------------------------------------------- | ----------------------------------------- |
| <!-- columnbreak --> | Force column break (ignored in singlecol) |
| <!-- toc:pages=N --> | Insert TOC, reserve N pages |
| <!-- toc:pages=N levels=1,2 --> | Insert TOC with specific heading levels |
| <!-- toc-exclude --> | Start excluding headings from TOC |
| <!-- /toc-exclude --> | Stop excluding headings from TOC |
| <!-- image: width: 80%; border: 1px solid #ccc; --> | Apply CSS to next image only |
| <!-- table: 25%, auto, 50% --> | Set column widths for next table |
| <!-- apply-next:.myclass #myid --> | Apply class/id to next block element |
| <!-- tag.class #id --> | Open wrapper container |
| <!-- /tag --> | Close wrapper container |
Wikilink Includes
![[chapter1]]
![[part1/intro.md]]- Resolved project-root-first, falling back to source-file-relative
.mdappended if extension omitted- Circular include detection (max depth 10)
- Missing files produce a visible
[Missing: path]placeholder
Front Matter Schema
---
title: Book Title
author: Author Name
date: 2026-01-01
lang: en
---CLI Reference
markpublisher build Build using markpublisher.toml
markpublisher serve Start live-reload dev server
markpublisher init <name> Scaffold new projectAlso available as a zero-config starter:
npx create-markpublisher-book my-bookExit codes: 0 (success), 1 (file not found), 2 (invalid config), 3 (render error).
Dev Server
markpublisher serve- Opens
http://localhost:3000(configurable via[serve].port) - Auto-reloads on file changes via SSE (watches main file and all
![[...]]includes) - Pagination toolbar with zoom, single/facing spread, page navigation
- Error overlay on render errors
Building
markpublisher build
# → output/output.html
# → output/output.pdfThe build output is fully offline — images, fonts, and CSS are bundled into output/assets/. The generated HTML includes the pagination toolbar for preview navigation. PDF generation uses Puppeteer (headless Chromium). On first run, Puppeteer downloads a compatible Chromium binary.
Pagination Toolbar
Both serve and build output include a toolbar with:
- Zoom: fit width, fit page, manual slider (10–300%)
- Spread: single page or facing pages
- Settings: column/row gap, page shadows, start-on-right
- Navigation: prev/next page, jump-to-page, page count
- Keyboard: ArrowLeft/ArrowRight for page navigation
Theme System
Themes are directories containing a single theme.css file (no theme.toml). Search paths:
<config-dir>/themes/<name>/(project-local)./themes/<name>/(cwd)~/.config/markpublisher/themes/<name>/(user global)
Page dimensions
PDF page size is parsed from theme.css. The renderer looks for @page { size: A4; } (standard sizes: A4, A5, Letter, Legal) or .page { width; height; } for custom dimensions. Falls back to A4 if neither is found.
CSS Conventions
The theme controls everything inside the page. The renderer provides page stacking, shadows, and toolbar styling.
| Class | Purpose | Owner |
| --------------------- | ----------------------- | -------- |
| .page | Page wrapper div | Theme |
| .page.twocol | Two-column page | Theme |
| .page.singlecol | Single-column page | Theme |
| .page.toc | TOC page | Theme |
| .page-number-hidden | Page with hidden number | Theme |
| .column-break | Column break element | Theme |
| .wide | Column-span all | Theme |
| .running-header | Running header element | Theme |
| .page-number | Page number element | Theme |
| .page-shell | Preview shell wrapper | Renderer |
| .toc-link | TOC row anchor | Renderer |
| .toc-leader | Dotted leader spacer | Renderer |
| .toc-entry | TOC list item | Renderer |
| #pagination-toolbar | Preview toolbar | Renderer |
The @page { size: ...; margin: 0; } rule should be set, with margins handled by .page padding.
Fonts
Themes can declare @font-face rules in CSS. Font files should be bundled in themes/<name>/fonts/ for reproducible, offline-friendly builds.
Remote fonts (@import / @font-face with http(s) URLs) are supported but emit warnings, as output depends on network availability.
Out of Scope (v1)
- Cross-references with auto page numbers ("see p. 42")
- Index generation
- Roman numeral page numbering
- EPUB export
- Automatic overflow pagination (content auto-reflow across pages)
- Math / LaTeX rendering
- SVG inline rendering
- Continuous PDF without pagebreak directives
License
MIT
