Pocketbook
Turn markdown into easily shareable, print-ready PDFs.
Pocketbook is an alpha Ruby project for generating book-style PDFs from markdown using a theme template and print CSS. It is built for:
- authors and self-publishers who write in markdown
- developers who need repeatable markdown-to-PDF output
- designers and publishers who want layout control via reusable themes
Why Pocketbook
- 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 template and style variants together for consistent output.
- Shareable output: Produce a polished PDF that is easy to distribute.
- Testable rendering: Validate layout stability with fixture-driven visual regression tests.
Start In 60 Seconds
1. Install the gem
gem install pocketbook
2. Generate your first PDF
pocketbook build \
examples/sample.md \
--theme classic \
--style light \
--size A4 \
--output output/book-a4.pdf
For a plain document without cover, TOC, or back cover sections, use the basic theme:
pocketbook build \
examples/sample.md \
--theme themes/basic \
--style plain \
--size A4 \
--output output/document-a4.pdf
classic 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.
4. Open the result
Your PDF is ready at output/book-a4.pdf.
To automatically open the generated PDF in your default viewer:
pocketbook build examples/sample.md --open
Live Rebuild While Editing
Use 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.pdf
By 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 500
After each successful rebuild, Pocketbook prints:
- a
file://...PDF link - an
xdg-open "..."command you can run directly
What The Generated PDF Includes
- cover page
- generated table of contents
- body pages with mirrored margins
- running header, footer, and page marker
- backcover page
Build From Multiple Markdown Files
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.pdf
Requirements
Runtime 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
Theme Workflow (Progressive)
Pocketbook supports progressive themeing. Start simple, then add structure only if needed.
Level 0: no custom theme files
Use the bundled default theme:
pocketbook build book.md --output output/book.pdf
Level 1: CSS-only theme (recommended first step)
Create a folder with theme.css:
themes/
clean/
theme.css
Then build with it:
pocketbook build book.md --theme themes/clean --output output/book.pdf
Level 2: Optional custom template
Add template.html.erb (or layout.html.erb) to the theme directory:
themes/
clean/
theme.css
template.html.erb
Optional metadata manifest (theme.yml)
theme.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 Labs
Style selection precedence:
--styleCLI flagdefaults.styleintheme.yml(if manifest exists)defaultstyle when discoverable (for exampletheme.css)- first discovered style
Front Matter
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
Visual Regression Tests
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 list
Fixture layout:
test/fixtures/inputs/: markdown fixturestest/fixtures/expected/<case-id>/pages/: expected PNG pagestest/fixtures/cases.yml: case manifest
CLI
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.yml
Build diagnostics example:
pocketbook build examples/sample.md --diagnostics --open
Contributing
Contributions 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.
License
This project is licensed under the MIT License. See LICENSE.