Turn markdown manuscripts into polished, print-ready PDFs.
Pocketbook is a Ruby toolchain for generating book-style PDFs from markdown using theme templates and print CSS. It is built for:
- authors and self-publishers who write in markdown
- developers who need reproducible markdown-to-PDF output
- designers and publishers who want layout control via reusable themes
- Markdown-first: Keep content in plain markdown files. Use one file or many.
- Print-first: Render with CSS
@page, named pages, running elements, and mirrored margins. - Theme-driven: Package templates and style variants together for consistent output.
- Publishable output: Produce polished PDFs ready to share, review, or print.
- Regression-safe: Validate layout stability with fixture-driven visual regression tests.
gem install pocketbookpocketbook build \
book.md \
--theme classic \
--style light \
--size A4 \
--output book-a4.pdfFor a plain document without cover, TOC, or back cover sections, use the basic theme:
pocketbook build \
book.md \
--theme basic \
--style plain \
--size A4 \
--output document-a4.pdfclassic is the default bundled theme. Use --theme themes/basic when you want a plain content-only layout.
When --theme receives a bare name such as classic, Pocketbook first looks for a bundled theme with that name. If none exists, it falls back to resolving the value from the current working directory. Any explicit path such as themes/classic, ./my-theme, or /abs/path/to/theme.yml is resolved directly as a path.
Your PDF is ready at output/book-a4.pdf.
To automatically open the generated PDF in your default viewer:
pocketbook build book.md --openUse the dedicated watch command to rebuild the PDF when relevant files change.
pocketbook watch \
examples/sample.md \
--theme themes/classic \
--style light \
--size A4 \
--output output/book-a4.pdfBy default, changes are debounced by 350ms. You can tune it:
pocketbook watch \
examples/sample.md \
--theme themes/classic \
--output output/book-a4.pdf \
--debounce-ms 500After each successful rebuild, Pocketbook prints:
- a
file://...PDF link - an
xdg-open "..."command you can run directly
- cover page
- generated table of contents
- body pages with mirrored margins
- running header, footer, and page marker
- backcover page
Pass files positionally to concatenate them in order:
pocketbook build \
chapters/01-intro.md \
chapters/02-method.md \
chapters/03-results.md \
--theme themes/classic \
--style light \
--size A4 \
--output output/book-multi-input.pdfRuntime requirements:
- Ruby 3.x
- local Chrome or Chromium (used by
ferrum)
Development/test-only dependencies:
- ImageMagick (
compare) for visual diff metric checks inbin/test-render - Poppler tools (
pdftoppm,pdfinfo,pdftotext) for page rasterization and text/page-count assertions
Example package names:
- Debian/Ubuntu:
imagemagick poppler-utils chromium - macOS (Homebrew):
imagemagick poppler
Pocketbook supports progressive theming. Start simple, then add structure only when you need it.
Use the bundled default theme:
pocketbook build book.md --output output/book.pdfCreate a folder with theme.css:
themes/
clean/
theme.cssThen build with it:
pocketbook build book.md --theme themes/clean --output output/book.pdfAdd template.html.erb (or layout.html.erb) to the theme directory:
themes/
clean/
theme.css
template.html.erbtheme.yml is optional. Use it only when you need explicit style maps, template path overrides, or defaults.
Supported top-level keys:
nameversiontemplatestylesdefaults
Supported defaults keys:
styletitlesubtitleauthorpublisherbackcover_textsize
Example theme.yml:
name: classic
version: 0.2.0
template: template.html.erb
styles:
light:
- styles/base.css
- styles/light.css
dark:
- styles/base.css
- styles/dark.css
defaults:
style: light
publisher: Pocketbook LabsStyle selection precedence:
--styleCLI flagdefaults.styleintheme.yml(if manifest exists)defaultstyle when discoverable (for exampletheme.css)- first discovered style
The first markdown input file can include YAML front matter.
Supported keys:
titlesubtitleauthorpublisherbackcover_textsize
Metadata precedence:
- CLI flags
- markdown front matter
- theme defaults
- renderer defaults
Pocketbook ships with fixture-driven visual regression tests using minitest.
# Check current output against expected fixtures
bin/test-render check
# Rebuild expected fixtures from current renderer output
bin/test-render update
# Print configured fixture case IDs
bin/test-render listFixture layout:
test/fixtures/inputs/: markdown fixturestest/fixtures/expected/<case-id>/pages/: expected PNG pagestest/fixtures/cases.yml: case manifest
Usage: pocketbook build FILE.md [MORE.md ...] [options]
Main commands:
build Build a PDF (default command)
watch Rebuild PDF on file changes
theme new NAME Scaffold a new theme directory
theme validate [THEME] Validate that a theme resolves correctly
theme inspect [THEME] Print resolved theme details
theme get URL Download a theme from a GitHub theme.yml URL
Theme command examples:
# Themes are stored globally by default in ~/.pocketbook/themes
pocketbook theme new clean
pocketbook theme new clean --with-template
pocketbook theme validate clean
pocketbook theme inspect classic --style dark
pocketbook theme get https://github.com/org/repo/blob/main/themes/minimal/theme.ymlBuild diagnostics example:
pocketbook build examples/sample.md --diagnostics --openContributions are welcome.
Start with CONTRIBUTING.md for setup, validation commands, and pull request expectations.
Quick path:
- Fork the repo and create a feature branch.
- Run
bundle install. - Make your changes and run
bin/test-render check. - Open a pull request with a short summary and rationale.
This project is licensed under the MIT License. See LICENSE.
