book-publishing
A pipeline skill to convert Markdown into print-ready or digital PDF books with native emoji support and professional formatting.
Install
mkdir -p .claude/skills/book-publishing && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15293" && unzip -o skill.zip -d .claude/skills/book-publishing && rm skill.zipInstalls to .claude/skills/book-publishing
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Markdown-to-PDF pipeline via Pandoc and LuaLaTeX with emoji rendering, dual output, and print-ready formattingKey capabilities
- →Process Markdown source files
- →Convert Markdown to LaTeX using Pandoc
- →Render LaTeX to PDF using LuaLaTeX
- →Generate dual PDF outputs for print and digital use
- →Handle emoji rendering in PDF documents
- →Prevent orphans and widows in text layout
How it works
The skill processes Markdown source through Pandoc to generate LaTeX, which LuaLaTeX then renders into two distinct PDF files: one configured for print and another for digital distribution.
Inputs & outputs
When to use book-publishing
- →Generating print-ready PDF books
- →Creating digital documentation bundles
- →Converting technical Markdown to professional PDFs
About this skill
Book Publishing
End-to-end book production pipeline: Markdown → Pandoc → LuaLaTeX → dual PDF (print + digital).
Staleness Watch: See EXTERNAL-API-REGISTRY.md for source URLs and recheck cadence
Scope: Inheritable skill. Covers the complete pipeline for producing professional-quality PDF books from Markdown source, including emoji handling, dual format output, and print-ready configuration.
Pipeline Architecture
Markdown Source
↓
Pandoc (--pdf-engine=lualatex)
↓
LuaLaTeX Engine
↓
├── Print PDF (twoside, crop marks, ISBN)
└── Digital PDF (oneside, hyperlinks, bookmarks)
Key Dependencies
| Tool | Version | Purpose |
|---|---|---|
| Pandoc | 3.x+ | Markdown → LaTeX conversion |
| LuaLaTeX | TeX Live 2024+ | PDF rendering (Unicode-native) |
| Twemoji | Latest | Cross-platform emoji rendering |
needspace package | LaTeX | Orphan/widow prevention |
Why LuaLaTeX: Native Unicode support (XeLaTeX works but LuaLaTeX handles emoji processing more reliably with Lua filters).
Emoji Handling (Critical)
The ZWJ Problem
Zero Width Joiner (ZWJ) sequences combine multiple emoji into one glyph. Sort order is critical:
| Emoji | Codepoints | Length |
|---|---|---|
| 👨👩👧👦 | U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466 | 7 |
| 👨👩👧 | U+1F468 U+200D U+1F469 U+200D U+1F467 | 5 |
| 👨👩 | U+1F468 U+200D U+1F469 | 3 |
| 👨 | U+1F468 | 1 |
CRITICAL RULE: The emoji replacement map MUST be sorted by length descending (longest sequences first). If you process 👨 before 👨👩👧👦, the family emoji gets partially replaced and corrupts the output.
Emoji Map File
Create an explicit emoji-map.json that controls all replacements:
{
"metadata": {
"version": "1.0",
"source": "Twemoji",
"sortOrder": "length-descending"
},
"emojis": [
{
"sequence": "👨👩👧👦",
"codepoints": "1f468-200d-1f469-200d-1f467-200d-1f466",
"image": "1f468-200d-1f469-200d-1f467-200d-1f466.png",
"length": 7
}
]
}
Rule: Never rely on automatic emoji detection. Use an explicit map file that you control and sort.
Twemoji Base64 Embedding
Embed Twemoji images directly as base64 in the LaTeX output to avoid external file dependencies:
-- Pandoc Lua filter for emoji replacement
function Str(elem)
-- Process emoji map (length-descending order)
for _, entry in ipairs(emoji_map) do
if elem.text:find(entry.sequence) then
local img = pandoc.Image("", entry.base64_data_uri)
-- Set size to match surrounding text
img.attributes.height = "1em"
return img
end
end
end
Windows Emoji Limitation
Windows cannot natively render flag emoji (🇺🇸, 🇬🇧, etc.) in many contexts. Solutions:
| Approach | Result |
|---|---|
| Twemoji replacement in PDF | Full flag rendering |
| HTML output with Twemoji CSS | Full flag rendering |
| Windows terminal/editor | Broken or missing flags |
Rule: Always preview emoji-heavy content in the PDF output, not in the editor.
Dual PDF Configuration
Print Edition
# pandoc-print.yaml
pdf-engine: lualatex
variables:
documentclass: book
classoption:
- twoside # Different left/right margins
- openright # Chapters start on right pages
geometry:
- inner=2.5cm # Binding side (wider)
- outer=2cm
- top=2.5cm
- bottom=2.5cm
fontsize: 11pt
mainfont: "Linux Libertine O"
monofont: "Fira Code"
linestretch: 1.15
Digital Edition
# pandoc-digital.yaml
pdf-engine: lualatex
variables:
documentclass: book
classoption:
- oneside # Symmetric margins
geometry:
- margin=2cm
fontsize: 11pt
colorlinks: true
linkcolor: blue
urlcolor: blue
toccolor: blue
Key Differences
| Feature | Digital | |
|---|---|---|
| Page layout | twoside (inner/outer margins) | oneside (symmetric) |
| Chapters | openright (start on right page) | No forced page side |
| Links | Black text (no hyperlinks on paper) | Blue, clickable |
| Crop marks | Yes (for professional printing) | No |
| Blank pages | Inserted for chapter openings | None |
Page Numbering
Front Matter vs. Body
| Section | Numbering | Style |
|---|---|---|
| Title page | None | — |
| Copyright, dedication | None | — |
| Table of Contents | Roman (i, ii, iii) | \pagenumbering{roman} |
| Foreword, preface | Roman (continues) | — |
| Chapter 1+ | Arabic (1, 2, 3) | \pagenumbering{arabic} |
| Appendices | Arabic (continues) or lettered | \appendix |
| Index | Arabic (continues) | — |
Rule: The transition from Roman to Arabic numbering resets at page 1 for the first chapter.
Table of Contents
LaTeX auto-generates TOC from headings. Configure depth:
\setcounter{tocdepth}{2} % Include down to subsections
\setcounter{secnumdepth}{2} % Number down to subsections
Heading Lint Before Build
Run a heading validation pass before PDF generation:
| Check | Rule | Why |
|---|---|---|
| No skipped levels | H1 → H2 → H3 (not H1 → H3) | TOC structure breaks |
| Unique within chapter | No duplicate H2 headings in same chapter | Anchor collisions |
| No trailing punctuation | "Getting Started" not "Getting Started." | TOC formatting |
| Consistent casing | Title Case or Sentence case, not mixed | Professional appearance |
Orphan/Widow Prevention
The needspace Package
Prevents headings from appearing at the bottom of a page with no following content:
\usepackage{needspace}
\needspace{4\baselineskip} % Ensure 4 lines available before heading
Configuration
| Element | Minimum Space |
|---|---|
| Chapter title | New page (automatic in book class) |
| Section heading | 4 \baselineskip |
| Subsection heading | 3 \baselineskip |
| Code block | 5 \baselineskip |
| Figure/table | Full figure height + caption |
Build Pipeline
Complete Build Script
#!/bin/bash
# build-book.sh — Dual PDF build
set -e
# Step 1: Lint headings
echo "Linting headings..."
python scripts/lint-headings.py chapters/*.md
# Step 2: Generate emoji map (sorted by length descending)
echo "Generating emoji map..."
python scripts/build-emoji-map.py --sort-by-length-desc
# Step 3: Build print edition
echo "Building print PDF..."
pandoc chapters/*.md \
--defaults=pandoc-print.yaml \
--lua-filter=filters/emoji.lua \
--lua-filter=filters/needspace.lua \
--toc \
--output=output/book-print.pdf
# Step 4: Build digital edition
echo "Building digital PDF..."
pandoc chapters/*.md \
--defaults=pandoc-digital.yaml \
--lua-filter=filters/emoji.lua \
--toc \
--output=output/book-digital.pdf
echo "Build complete: output/book-print.pdf, output/book-digital.pdf"
Build Validation
After building, verify:
| Check | How |
|---|---|
| Page count reasonable | Compare to previous build |
| TOC links work | Click in PDF reader |
| Emoji render correctly | Visual spot-check family/flag emoji |
| No orphan headings | Scan for headings at page bottom |
| Front matter numbering | Roman numerals before Chapter 1 |
| Chapter openings (print) | Always on right-hand page |
Project Structure
book/
├── chapters/
│ ├── 00-frontmatter.md
│ ├── 01-introduction.md
│ ├── 02-foundations.md
│ └── ...
├── filters/
│ ├── emoji.lua
│ └── needspace.lua
├── scripts/
│ ├── build-emoji-map.py
│ └── lint-headings.py
├── assets/
│ ├── emoji/ # Twemoji PNGs
│ └── images/ # Book images
├── output/ # Generated PDFs (gitignored)
├── emoji-map.json # Explicit emoji map
├── pandoc-print.yaml # Print edition config
├── pandoc-digital.yaml # Digital edition config
└── build-book.sh # Build script
When not to use it
- →When the source is not Markdown
- →When only a single PDF output is needed without specific print/digital configurations
- →When emoji rendering is not a requirement
Prerequisites
Limitations
- →The skill relies on specific versions of Pandoc and TeX Live.
- →Emoji rendering requires an explicit emoji map file.
- →Windows cannot natively render flag emoji in many contexts outside the PDF output.
How it compares
This workflow automates the creation of two distinct PDF versions with specific configurations for print and digital use, unlike a manual process that would require separate formatting adjustments for each output.
Compared to similar skills
book-publishing side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| book-publishing (this skill) | 0 | 3mo | Review | Intermediate |
| mdx-pdf-format | 0 | 1mo | Review | Intermediate |
| pdf-creator | 0 | 1mo | Review | Intermediate |
| markdown-to-pdf | 0 | 1mo | Review | Beginner |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by fabioc-aloha
View all by fabioc-aloha →You might also like
mdx-pdf-format
sazardev
Use whenever creating, renaming, or editing any file under docs/ in this repo, or when asked to compile/build the book PDF. Enforces the exact .mdx frontmatter, ID scheme, and heading-depth rules required by the go-pretty-pdf tool (https://github.com/sazardev/go-pretty-pdf) so the whole book keeps c
pdf-creator
seaworld008
Create PDF documents from markdown with proper Chinese font support using weasyprint. This skill should be used when converting markdown to PDF, generating formal documents (legal, trademark filings, reports), or when Chinese typography is required. Triggers include "convert to PDF", "generate PDF",
markdown-to-pdf
duc01226
[Document Processing] Use when you need to convert markdown files to PDF with syntax highlighting and custom CSS support.
ml-paper-writing
davila7
Write publication-ready ML/AI papers for NeurIPS, ICML, ICLR, ACL, AAAI, COLM. Use when drafting papers from research repos, structuring arguments, verifying citations, or preparing camera-ready submissions. Includes LaTeX templates, reviewer guidelines, and citation verification workflows.
docs-review
metabase
Review documentation changes for compliance with the Metabase writing style guide. Use when reviewing pull requests, files, or diffs containing documentation markdown files.
claude-md-improver
anthropics
Audit and improve CLAUDE.md files in repositories. Use when user asks to check, audit, update, improve, or fix CLAUDE.md files. Scans for all CLAUDE.md files, evaluates quality against templates, outputs quality report, then makes targeted updates. Also use when the user mentions "CLAUDE.md maintenance" or "project memory optimization".