| name | book_creation |
| description | PaperLab skill for book creation workflows in scientific writing and book production. |
Skill: Book Creation in PaperLab
When to Use
USE WHEN: creating a new scientific book project, writing chapter content,
running book notebooks, building/rendering a book, or troubleshooting the book
pipeline. This skill covers the complete lifecycle from book-new to final
rendered outputs in HTML/Word/PDF/ODF.
DO NOT USE for: paper writing workflows (use write_methods_section,
journal_formatting, etc. instead).
1. Book Project Structure
Every book lives under neqsim-paperlab/books/<slug>_<year>/. The critical
file is book.yaml — it defines metadata, chapter ordering, parts, and
rendering settings.
books/<book_slug>/
├── book.yaml # Master manifest — defines EVERYTHING
├── refs.bib # Master bibliography
├── nomenclature.yaml # Symbol definitions
├── frontmatter/
│ ├── title_page.md
│ ├── copyright.md
│ ├── dedication.md
│ └── preface.md
├── chapters/
│ ├── ch01_introduction/
│ │ ├── chapter.md # Chapter text (markdown with LaTeX math)
│ │ ├── figures/ # Generated figures (PNG)
│ │ └── notebooks/ # Jupyter notebooks that generate figures
│ ├── ch02_topic_name/
│ │ ├── chapter.md
│ │ ├── figures/
│ │ └── notebooks/
│ └── ...
├── backmatter/
│ ├── glossary.md
│ └── author_bio.md
└── submission/ # Rendered outputs
├── book.html
├── book.docx
├── book.pdf
├── book.odt
└── figures_chNN/ # PDF renderer copies figures here for Typst
book.yaml Structure
title: "Book Title"
subtitle: "Subtitle"
authors:
- name: "Author Name"
affiliation: "Institution"
email: "email@example.com"
edition: "1st"
year: 2026
publisher: "springer"
language: "en"
settings:
book_type: "textbook"
page_size: "b5"
font_size: 10
line_spacing: 1.2
two_sided: true
chapter_numbering: true
equation_numbering: "chapter"
frontmatter:
- title_page
- copyright
- dedication
- preface
parts:
- title: "Part I: Foundations"
chapters:
- dir: "ch01_introduction"
title: "Introduction and Context"
- dir: "ch02_topic_name"
title: "Topic Name"
- title: "Part II: Advanced"
chapters:
- dir: "ch03_another_topic"
title: "Another Topic"
backmatter:
- glossary
- author_bio
nomenclature:
file: "nomenclature.yaml"
position: "after_toc"
bibliography:
style: "numeric"
file: "refs.bib"
Critical Rules for book.yaml
dir values MUST match actual directory names under chapters/.
Mismatches cause the renderer to silently skip chapters.
- Chapter numbering is sequential across all parts — the renderers
count 1, 2, 3, ... regardless of part boundaries.
- Do not create alternate directory names (e.g.,
ch03_cubic_eos vs
ch03_cubic_equations_of_state). Only the dir listed in book.yaml
is used. Remove unused dirs to avoid confusion.
- Publisher profiles in
books/_publisher_profiles/ define page size,
margins, and fonts. The publisher key selects which profile to load.
Optional metadata
The following top-level keys are optional. Omit or leave them blank and the
renderers degrade gracefully (no author line, no publisher imprint, etc.):
authors, publisher, year, language, isbn.
1.1 Book Type Profiles (content level)
settings.book_type selects how much pedagogical scaffolding is included so
the same manuscript can be published at three different levels. It controls
whether the copyright page, learning objectives, exercises, and review sections
are rendered.
book_type | Audience / purpose | Learning Objectives | Exercises | Review Questions / Problems | Further Reading | Copyright page |
|---|
simple | Concise reference / handout | ✗ | ✗ | ✗ | ✗ | ✗ |
technical | Engineering description | ✗ | ✗ | ✗ | ✓ | ✓ |
textbook | Full university textbook | ✓ | ✓ | ✓ | ✓ | ✓ |
- Default is
textbook (everything included). Omitting book_type
reproduces the historic full-content behaviour, so existing books are
unaffected.
- The profile decides which
## <Heading> sections are stripped from each
chapter.md at render time. The chapter source files are never modified —
authors can keep all sections in the source and switch the output level from
book.yaml alone.
Overriding a profile
Explicit settings.include_* and settings.exclude_sections keys always win
over the book_type profile. This lets you start from a profile and tweak a
single aspect:
settings:
book_type: technical
include_copyright: false
settings:
book_type: simple
include_learning_objectives: true
Resolution order for each toggle: explicit settings key → book_type
profile default → built-in default (include). Accepted boolean strings are
case-insensitive: true/yes/1/on and false/no/0/off.
exclude_sections is additive — the titles you list are removed in
addition to whatever the profile already strips. Matching is case-insensitive
and ignores leading numbers (## 5.3 Problems matches Problems).
2. Creating a New Book
Command
cd neqsim-paperlab
python paperflow.py book-new "Book Title" --publisher springer --chapters 12
This creates the scaffold with empty chapters (ch01 through ch12).
Use --type to pick the content level (writes settings.book_type into the
generated book.yaml, see §1.1). Defaults to textbook:
python paperflow.py book-new "Field Handbook" --type technical --chapters 8
python paperflow.py book-new "Quick Reference" --type simple --chapters 4
Post-Scaffold Steps (MANDATORY)
-
Rename chapter directories to descriptive names:
ch01 → ch01_introduction
ch02 → ch02_thermodynamic_foundations
-
Update book.yaml to match the new directory names and set real titles.
-
Organize into parts by editing the parts: section in book.yaml.
-
Fill frontmatter — at minimum: title_page.md (title, authors),
preface.md (motivation, audience, acknowledgements).
-
Deep Literature Review and refs.bib (DO THIS BEFORE WRITING CHAPTERS):
This step is non-negotiable — a book with sparse references signals
shallow scholarship. Complete the bibliography BEFORE writing chapter content.
a. Build master refs.bib at the book root with 100+ entries minimum.
Organize into clearly commented sections by topic:
% ─── Foundational thermodynamics ───
@book{Prausnitz1999, ... }
% ─── Equations of state ───
@article{Soave1972, ... }
b. Mine existing PaperLab papers — Search papers/*/refs.bib for
related citations. Reuse BibTeX entries for consistency:
grep -rl "keyword" papers/*/refs.bib
c. Ensure coverage per chapter — Each chapter should have 10–20+ unique
references identified before writing begins.
d. Include all categories: seminal/foundational works, recent advances
(last 5 years), textbooks, experimental data sources, competing methods,
review articles.
See PAPER_WRITING_GUIDELINES.md "MANDATORY: Literature Review and Citation
Collection First" for the complete workflow and quality rules.
-
Import content from PaperLab papers (MANDATORY) — Before writing each
chapter, check papers/ for papers that cover the same topic:
grep -rl "chapter_keyword" papers/*/paper.md papers/*/plan.json
For each matching paper:
- Copy figures from
papers/<paper>/figures/*.png to chapters/chNN/figures/
- Copy tables (markdown) from
paper.md into chapter.md
- Incorporate results — numerical benchmarks, validation data, performance comparisons
- Adapt text — expand paper explanations for the book's broader audience
- Reuse equations — copy LaTeX from paper.md, ensure notation matches book nomenclature
This step ensures the book benefits from the detailed research already done
in PaperLab papers. See PAPER_WRITING_GUIDELINES.md for the full workflow.
-
Create chapter content — each chapter.md uses markdown with:
$$...$$ for display equations (rendered as OMML in Word, KaTeX in HTML)
$...$ for inline math
\cite{key} tags for every claim, equation origin, and data source
 for figures
- Standard markdown tables (rendered as booktabs-style)
3. Writing Chapter Content
Equations
Display equations use $$...$$ delimiters. They are automatically numbered
per-chapter (Eq. 1.1, 1.2, ..., Eq. 2.1, 2.2, ...).
The cubic equation of state is:
$$
P = \frac{RT}{V_m - b} - \frac{a(T)}{(V_m + \epsilon b)(V_m + \sigma b)}
$$
For the SRK model, the alpha function is:
$$
\alpha(T) = \left[1 + m\left(1 - \sqrt{T_r}\right)\right]^2
$$
Inline math uses $...$:
The acentric factor $\omega$ affects the alpha function $\alpha(T_r, \omega)$.
Equation Pipeline (per renderer)
| Renderer | Display Equations | Inline Math |
|---|
| Word (.docx) | LaTeX → MathML (latex2mathml) → OMML (MML2OMML.XSL) → native Word | Same OMML pipeline |
| HTML | KaTeX auto-render ($$...$$ blocks) | KaTeX inline |
| PDF | Pandoc → Typst (native math support) | Native Typst |
| ODF | Unicode fallback (Greek, sub/superscript) | Unicode fallback |
Word renderer dependency: Requires MML2OMML.XSL from Microsoft Office.
Location: C:\Program Files\Microsoft Office\root\Office16\MML2OMML.XSL.
The math_utils.py module handles the conversion pipeline.
Figures
Figures are generated by Jupyter notebooks in chapters/chNN/notebooks/ and
saved to chapters/chNN/figures/. Reference them in chapter.md as:

The renderers handle figure numbering automatically (Figure 1.1, 1.2, ...).
Tables
Use standard markdown tables. The Word renderer applies booktabs-style
formatting (horizontal rules only, no vertical lines):
| Component | Tc (K) | Pc (kPa) | ω |
|-----------|--------|----------|------|
| Methane | 190.56 | 4599 | 0.0115 |
| Ethane | 305.32 | 4872 | 0.0995 |
Code Blocks
Use fenced code blocks with language specifiers:
```python
from neqsim import jneqsim
fluid = jneqsim.thermo.system.SystemSrkEos(298.15, 50.0)
```
4. Jupyter Notebooks
Each chapter has a notebooks/ directory containing .ipynb files that
generate the chapter's figures.
Notebook Setup Cell (MANDATORY first cell)
import importlib, subprocess, sys
try:
from neqsim_dev_setup import neqsim_init, neqsim_classes
ns = neqsim_init(recompile=False)
ns = neqsim_classes(ns)
NEQSIM_MODE = "devtools"
print("NeqSim loaded via devtools (local dev mode)")
except Exception:
try:
import neqsim
except ImportError:
subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "neqsim"])
from neqsim import jneqsim
NEQSIM_MODE = "pip"
print("NeqSim loaded via pip package")
Saving Figures (MANDATORY pattern)
import matplotlib.pyplot as plt
from pathlib import Path
NOTEBOOK_DIR = Path(globals().get(
"__vsc_ipynb_file__", __file__
)).resolve().parent
FIGURES_DIR = NOTEBOOK_DIR.parent / "figures"
FIGURES_DIR.mkdir(exist_ok=True)
fig, ax = plt.subplots(figsize=(6, 4))
fig.savefig(FIGURES_DIR / "figure_name.png", dpi=150, bbox_inches="tight")
plt.show()
Running Notebooks
python paperflow.py book-run-notebooks books/<book_dir>
python paperflow.py book-run-notebooks books/<book_dir> --chapter ch04_association_theory
python paperflow.py book-run-notebooks books/<book_dir> --no-compile
python paperflow.py book-build books/<book_dir> --format all
5. Building and Rendering
Build Commands
cd neqsim-paperlab
python paperflow.py book-build books/<book_dir> --format all
python paperflow.py book-build books/<book_dir> --format all --skip-notebooks
python paperflow.py book-build books/<book_dir> --format all --no-compile
python paperflow.py book-build books/<book_dir> --format all --skip-notebooks --no-compile
python paperflow.py book-render books/<book_dir> --format docx
python paperflow.py book-render books/<book_dir> --format html
python paperflow.py book-render books/<book_dir> --format pdf
python paperflow.py book-render books/<book_dir> --format odf
Build Pipeline Steps
The book-build command runs these steps in order:
- Compile —
mvnw compile (ensures Java classes are current)
- Notebooks — execute all
.ipynb files, capturing errors
- Figure injection — auto-insert new figures into chapter.md
- Quality checks — structure, completeness, consistency
- Render — produce output in requested format(s)
Output Locations
| Format | Output Path | Size Guide |
|---|
| HTML | submission/book.html | Single-page with sidebar navigation, KaTeX |
| Word | submission/book.docx | Native OMML equations, TOC, page numbers |
| PDF | submission/book.pdf | Via Typst, publisher page size |
| ODT | submission/book.odt | Unicode equation fallback |
PDF Figure Handling
The PDF renderer copies chapter figures to submission/figures_chNN/ because
Typst needs them alongside the master .typ file. This is by design — the
copies are build artifacts in submission/ and should not be committed.
6. Quality Checks
python paperflow.py book-check books/<book_dir>
Checks: structure (dirs exist), completeness (word counts), consistency
(cross-references), bibliography, figure references, nomenclature.
7. Common Issues and Solutions
Issue: Chapter silently skipped in render
Cause: The dir value in book.yaml doesn't match the actual directory name.
Fix: Verify ls chapters/ matches every dir: entry in book.yaml.
Issue: Equations render as plain text in Word
Cause: MML2OMML.XSL not found (no Office installed) or latex2mathml
not installed.
Fix: Install Office or ensure MML2OMML.XSL is on the system. Install
dependencies: pip install latex2mathml lxml.
Issue: Equations render as Unicode instead of proper math in ODF
Expected: ODF renderer uses Unicode Greek/subscript/superscript as fallback.
Full equation rendering in ODF requires a dedicated math library.
Issue: Duplicate chapter directories
Cause: Chapters renamed but old directories not deleted.
Fix: Only the dir listed in book.yaml is used. Delete unused directories.
Issue: Stale Python module imports
Cause: __pycache__ holds old versions of modified tools.
Fix: Delete tools/__pycache__/ and re-run.
Issue: Figures not appearing in rendered output
Cause: Figure path in chapter.md doesn't match actual filename.
Fix: Use  — paths are relative to
the chapter directory.
Issue: PDF build fails
Cause: Missing pandoc or typst package.
Fix: Install pandoc (system package) and pip install typst.
Issue: Typst PDF compile fails with unexpected underscore
Cause: Bibliography entries from refs.bib contain LaTeX-style fragments
such as $_2$, {CO, or \textit{...}. When inserted into a Typst content
block these $...$ segments are read as math mode, where a leading _ has no
base.
Fix: The bibliography renderer in tools/book_render_pdf.py escapes
\ # $ { } _ * @ < > [ ] \``. Do not remove that escape table. If you add a new bibliography style, make sure the entry text is escaped before being embedded into a #par[...]` block.
Issue: Typst PDF compile fails with expected alignment or auto, found string
Cause: #set page(binding: "left") no longer accepts a string in Typst
0.14. The keyword expects an alignment value (left / right).
Fix: Use binding: left (no quotes) in the generated preamble.
7a. Professional Typesetting
The PDF renderer (tools/book_render_pdf.py, function
build_book_typst_preamble) emits a Typst preamble that produces a
publisher-quality book layout. When you modify the preamble, preserve the
following features and verify against the checklist below.
Layout Features Built In
| Feature | Implementation in preamble |
|---|
| Trim size | Parsed from publisher profile trim_size: "WxHmm" |
| Two-sided binding | binding: left + inside/outside margins |
| Running headers | #set page(header: context { ... }), querying nearest level-1 heading; suppressed on page 1; left-aligned on even pages, right-aligned on odd pages, in tracked smallcaps |
| Chapter opener | Smallcaps "Chapter N", thin colored rule, large coloured chapter title (level-1 #show rule) |
| Chapter forced to recto | pagebreak(weak: true, to: "odd") inside the level-1 rule |
| Equation numbering | (chapter.eq) via #set math.equation(numbering: ...) and counter reset at each level-1 heading |
| Booktabs tables | #set table(stroke: none, ...) plus a #show table: rule that wraps tables in a block with thin top/bottom rules and 9 pt text |
| Microtypography | #set text(hyphenate: true, ligatures: true, number-type: "lining") and justified paragraphs with leading: 0.78em |
| First-line indent | #set par(first-line-indent: (amount: 1.2em, all: false)) |
| Hanging-indent bib | Bib block sets hanging-indent: 1.6em and emits each entry as #par[#text(weight: "bold")[[N]] #h(0.5em) text] |
| Special-char escaping | Bib entries escape `\ # $ { } _ * @ < > [ ] `` to avoid Typst math/code triggers |
Typesetting Quality Checklist (run before final PDF render)
-
Publisher profile (books/_publisher_profiles/<name>.yaml) exists for the
value of publisher: in book.yaml. If missing, the renderer falls back
to A4 / generic margins — set the profile explicitly.
-
trim_size follows the format "WxHmm" (e.g. "155x235mm").
-
font is installed on the host (default "New Computer Modern"). On
Windows, install via the New Computer Modern release zip.
-
After running book-render --format pdf, open the PDF and verify:
- Chapter 1 starts on a recto (right-hand) page.
- Even-page header shows the chapter title left-aligned; odd-page header
shows it right-aligned; both in smallcaps.
- Page 1 (title page) has no running header.
- Each chapter opener shows the smallcaps "Chapter N" line, a thin
coloured rule, and the chapter title set in the heading colour.
- Equation labels read
(1.1), (2.1), ... and reset at every chapter.
- Tables show only thin top + bottom rules (booktabs style); no vertical
rules.
- Reference list is indented hanging-style, with bold reference numbers.
- Body text is justified with hyphenation; no rivers or large gaps.
-
Run the consistency checker:
python paperflow.py book-check books/<book_dir>
-
The generated submission/book.typ is a build artifact. Do not edit it
by hand — change tools/book_render_pdf.py and re-render.
Modifying the Preamble Safely
If you add new Typst rules to build_book_typst_preamble:
- The function returns an f-string; literal
{ and } must be doubled
({{ / }}).
- Test with the smallest book first:
python paperflow.py book-render books/<small_book> --format pdf.
- If compilation fails with a misleading message (e.g.
unexpected underscore from a bib entry), bisect by chapter — write _test.typ
inside submission/ so figure paths still resolve.
- Typst 0.14 syntax notes:
binding: takes an alignment, not a string.
#set page(width: ..., height: ...) uses keyword args, not a tuple.
pagebreak(to: ...) accepts "odd" / "even" strings or omit the arg.
- Use
query(heading.where(level: 1).before(here())) for running headers
(avoid shadowing the built-in here function with a local variable).
8. Workflow for Iterative Chapter Writing
The fastest iteration loop for writing/editing chapters:
- Edit
chapter.md (add equations, text, figure references)
- Render single format for preview:
python paperflow.py book-build books/<book_dir> --format html --skip-notebooks --no-compile
- Open
submission/book.html in browser — instant feedback
- When satisfied, do a full build:
python paperflow.py book-build books/<book_dir> --format all --skip-notebooks
For notebook development:
- Edit notebooks in VS Code / JupyterLab
- Run individual notebooks manually to iterate on figures
- When figures are ready, rebuild:
python paperflow.py book-build books/<book_dir> --format all --skip-notebooks --no-compile
9. Tools Reference
| Tool | Purpose |
|---|
tools/book_builder.py | Config loading, chapter iteration, scaffolding |
tools/book_notebook_runner.py | Notebook execution, figure injection, full build pipeline |
tools/book_render_html.py | HTML renderer (KaTeX, sidebar nav) |
tools/book_render_word.py | Word renderer (OMML equations, TOC, booktabs tables) |
tools/book_render_pdf.py | PDF renderer (Pandoc → Typst pipeline) |
tools/book_render_odf.py | ODF renderer (Unicode math fallback) |
tools/book_render_epub.py | EPUB 3 renderer (Pandoc → epub3 pipeline) |
tools/book_preview.py | Live HTML preview server with auto-reload |
tools/book_checker.py | Quality checks (structure, completeness, consistency, accessibility) |
tools/bib_enrich.py | Crossref DOI validation / enrichment for refs.bib |
tools/book_pdfx_postpass.py | PDF/X-1a or PDF/A conversion via Ghostscript |
tools/math_utils.py | LaTeX → OMML/Unicode conversion |
9a. Live preview while writing
python paperflow.py book-preview books/<book_dir>
9b. CSL citations
Add to book.yaml:
bibliography:
file: refs.bib
csl: styles/elsevier-harvard.csl
The PDF, HTML and EPUB renderers will route citations through Pandoc's
--citeproc engine when both files exist.
9c. EPUB output
python paperflow.py book-render books/<book_dir> --format epub
9d. Crossref bibliography enrichment
python paperflow.py book-enrich-bib books/<book_dir>
python paperflow.py book-enrich-bib books/<book_dir> --in-place
Validates every DOI, warns on title/year mismatches, and adds DOIs to
entries that don't have one when Crossref's top match exceeds the
threshold.
9e. PDF/X-1a or PDF/A conversion
If a publisher profile sets:
print_specs:
pdf_standard: PDF/X-1a:2003
color_profile: CMYK
then the PDF renderer automatically post-processes book.pdf with
Ghostscript. The original is kept as book.pre-pdfx.pdf.
9f. NeqSim integration for scientific writing
For chapters that defend numbers via NeqSim simulation, load the companion
skill skills/neqsim_in_writing/SKILL.md. It covers the dual-boot setup
cell, claim-to-test linkage (@neqsim:claim), equation-to-Java method
cross-references (@neqsim:eq), units enforcement against
nomenclature.yaml, and notebook-driven figure / results-table injection
(@neqsim:figure, @neqsim:table).
10. Full End-to-End Example
cd neqsim-paperlab
python paperflow.py book-new "Thermodynamic Modeling" --publisher springer --chapters 8
python paperflow.py book-run-notebooks books/thermodynamic_modeling_2026/
python paperflow.py book-build books/thermodynamic_modeling_2026/ --format all
python paperflow.py book-check books/thermodynamic_modeling_2026/
python paperflow.py book-build books/thermodynamic_modeling_2026/ --format html --skip-notebooks --no-compile