# The Triplicate — `template_newspaper` > A data-driven, large-format **newspaper layout engine**. It renders a complete > 12-page US Tabloid (11″ × 17″) edition — *The Triplicate* of Crescent City, > California — to a print-ready PDF from structured YAML content, using > pure-Python ReportLab. Broadsheet is a supported alternate trim > (`render.page: broadsheet`); the shipped default is tabloid. Swapping editions > is a data edit; the engine never changes. ![12-page contact sheet](docs/contact-sheet.png) This is a canonical exemplar sibling of [`template_code_project`](../template_code_project/) and [`template_prose_project`](../template_prose_project/): same directory contract (`src/` + `tests/` + optional `scripts/`/`manuscript/`), same orchestration hooks, same documentation conventions — but where those render a *manuscript*, this renders a *newspaper*. ## When to use this template Use this template when you need **data-driven, large-format print layout**: multi-page broadsheets/tabloids with precise column geometry, typography-first constraints, and strict content/engine separation (YAML editions in `content/`, pure-Python ReportLab engine in `src/`). If you are producing a research manuscript rather than a designed layout, see [`template_code_project`](../template_code_project/) or [`template_prose_project`](../template_prose_project/) instead. Full roster: [`projects/AGENTS.md`](../../AGENTS.md#permanent-canonical-exemplars). ## Publication and rendering The publishing metadata and per-platform status below are **compiled from `manuscript/config.yaml`** by `infrastructure.publishing.status_report` — do not hand-edit between the markers; update the config and regenerate (see the legend). **The Triplicate: A Data-Driven Large-Format Newspaper Layout Engine** · v1.0.2 · MIT · Daniel Ari Friedman Concept DOI: [10.5281/zenodo.20533675](https://doi.org/10.5281/zenodo.20533675) | Version DOI: [10.5281/zenodo.20932039](https://zenodo.org/records/20932039) | Repository: [docxology/template_newspaper](https://github.com/docxology/template_newspaper) Publishing surface — 20 platforms, 9 published: | Platform | Tier | Status | Reference | Credentials | | --- | --- | --- | --- | --- | | zenodo | first-class | ✅ published | [10.5281/zenodo.20533675](https://doi.org/10.5281/zenodo.20533675) | `ZENODO_API_TOKEN` | | github | first-class | ✅ published | [docxology/template_newspaper](https://github.com/docxology/template_newspaper) | `GITHUB_TOKEN` | | arxiv | first-class | ⚪ available | — | — | | pypi | first-class | ✅ published | [https://test.pypi.org/project/template-newspaper/1.0.2/](https://test.pypi.org/project/template-newspaper/1.0.2/) | `PYPI_TOKEN`, `TESTPYPI_TOKEN` | | ipfs_pinata | first-class | ✅ published | [https://gateway.pinata.cloud/ipfs/QmUsept2d9X3sz42whTgEGM9TjdxjzSqxnuyPCbu3pPwku](https://gateway.pinata.cloud/ipfs/QmUsept2d9X3sz42whTgEGM9TjdxjzSqxnuyPCbu3pPwku) | `PINATA_JWT` | | ipfs_web3storage | first-class | ⚪ available | — | `WEB3_STORAGE_TOKEN` | | software_heritage | first-class | ✅ published | [https://archive.softwareheritage.org/browse/origin/?origin_url=https://github.com/docxology/template_newspaper](https://archive.softwareheritage.org/browse/origin/?origin_url=https://github.com/docxology/template_newspaper) | — | | github_pages | first-class | ✅ published | [https://docxology.github.io/template_newspaper/](https://docxology.github.io/template_newspaper/) | `GITHUB_TOKEN` | | cloudflare_pages | first-class | ⚪ available | — | `CLOUDFLARE_API_TOKEN` | | netlify | first-class | ✅ published | [https://6a4441f8d6dc10153d77788d--tranquil-kleicha-0c9203.netlify.app](https://6a4441f8d6dc10153d77788d--tranquil-kleicha-0c9203.netlify.app) | `NETLIFY_AUTH_TOKEN` | | huggingface_hub | first-class | ✅ published | [https://huggingface.co/datasets/ActiveInference/template_newspaper](https://huggingface.co/datasets/ActiveInference/template_newspaper) | `HUGGINGFACE_TOKEN`, `HF_TOKEN` | | osf | first-class | ✅ published | [https://osf.io/tzwf8/](https://osf.io/tzwf8/) | `OSF_TOKEN` | | amazon_kdp | documented | 🟡 planned | — | `AMAZON_KDP_EMAIL`, `AMAZON_KDP_PASSWORD` | | google_play_books | documented | 🟡 planned | — | `GOOGLE_PLAY_BOOKS_SERVICE_ACCOUNT_JSON` | | gumroad | documented | 🟡 planned | — | `GUMROAD_ACCESS_TOKEN` | | leanpub | documented | 🟡 planned | — | `LEANPUB_API_KEY` | | lulu | documented | 🟡 planned | — | `LULU_CLIENT_KEY`, `LULU_CLIENT_SECRET` | | draft2digital | documented | 🟡 planned | — | `DRAFT2DIGITAL_API_TOKEN` | | stripe | documented | 🟡 planned | — | `STRIPE_SECRET_KEY`, `STRIPE_PUBLISHABLE_KEY` | | ingramspark | documented | 🟡 planned | — | `INGRAMSPARK_CLIENT_ID`, `INGRAMSPARK_CLIENT_SECRET` | _Keywords: newspaper layout, typography, reportlab, reproducible publishing, document engineering._ _Status legend: ✅ published (durable identifier recorded in `config.yaml`) · 🔵 reserved (identifier reserved but not yet registered by final publication) · ⚪ available (adapter implemented and locally verifiable) · 🟡 planned. This block is generated — edit `manuscript/config.yaml`, then regenerate with `uv run python -m infrastructure.publishing.status_report --project --write`._ The 3 platforms still shown ⚪ available are not automatable to "published" with current tooling/credentials, not an oversight: **arXiv** has no submission API in this codebase (`infrastructure.publishing.arxiv` only prepares a local tarball — a human must upload it via arxiv.org and the resulting `arxiv` URL would then be added to `publication.published_artifacts`); **Cloudflare Pages** needs a `CLOUDFLARE_ACCOUNT_ID` the configured API token cannot auto-discover; **IPFS (Web3.Storage)** has no `WEB3_STORAGE_TOKEN` configured. - Canonical renderer: [docxology/template](https://github.com/docxology/template) with `--project templates/template_newspaper` - Tracked outputs: [`output/`](output/) in this project and `output/templates/template_newspaper/` in the monorepo; public output files above 50 MB stay out of git. To regenerate this exemplar from the public monorepo: ```bash git clone https://github.com/docxology/template cd template uv sync ./run.sh --project templates/template_newspaper --pipeline --core-only uv run python scripts/pipeline/stage_04_validate.py --project templates/template_newspaper uv run python scripts/pipeline/stage_05_copy.py --project templates/template_newspaper ``` Standalone repositories are publication mirrors for source, DOI metadata, and tracked rendered artifacts. Use the monorepo above when you need the full shared infrastructure, pipeline stages, or cross-template validation. --- ## What it produces A **12-page US Tabloid (11″ × 17″) edition**, `output/pdf/the-triplicate.pdf`: | Page | Section | Layout features | |-----:|---------|-----------------| | A1 | Front Page | Nameplate, ears, left rail (index/weather/refers), spanning lead headline, drop cap, halftone art, pull quote | | A2 | Local & Region | Section lead, "Around Del Norte" briefs, multi-story flow | | A3 | City & County | Council lead, public-notices box, government briefs | | A4 | Coast & Environment | Feature lead (jump from A1), tsunami-prep sidebar, charts | | A5 | Opinion | Staff masthead, editorial, letters, signed column, "Today in History" | | A6 | Business & Fishing | Dungeness landings chart, dock-price table, business briefs | | A7 | Community & Arts | Lighthouse feature, weekly calendar table, arts briefs | | A8 | Sports | Game lead, prep scoreboard + standings tables | | A9 | Education & Schools | Pelican Bay degree feature, school notes | | A10 | Public Record & Obituaries | Obituaries, sheriff's log, vital records, legal notices | | A11 | Classifieds & Marketplace | Dense flowing ads, service/worship directories, display ads | | A12 | Weather & Almanac | 7-day chart, tide curve, regional/marine tables, long history feature, colophon | Typography: **Didot** display + **Georgia** text + Helvetica sans labels, with a graceful fall-back to ReportLab's base-14 fonts on machines that lack them. **Color & advertising.** The editorial type is monochrome by design, but the template fully supports **color**: color figures (any RGB PNG), a color-capable **display-ad** system (logo, tint, accent, border styles) with worked examples on several pages, and an opt-in **spot color** for the masthead and section flags (`render.spot_color: true`). --- ## Quick start ```bash # From the repository root, with the workspace .venv active: cd projects/templates/template_newspaper # 1. generate figures (halftone engravings + grayscale charts) uv run python scripts/10_generate_figures.py # 2. render the 12-page PDF uv run python scripts/20_render_newspaper.py open output/pdf/the-triplicate.pdf ``` Or render programmatically: ```python from pathlib import Path from newspaper.engine import build_and_render result = build_and_render(Path("projects/templates/template_newspaper")) print(result.page_count, result.all_pages_fit) # 12 True ``` Run it through the repository orchestrator like any other project: ```bash ./run.sh --project templates/template_newspaper --pipeline ``` The project is discovered automatically; Stage 02 (analysis) runs `scripts/*.py` to generate figures and render the newspaper, and Stage 03 renders the descriptive manuscript under `manuscript/`. --- ## How it works ``` content/edition.yaml masthead + render settings + ordered page list content/pages/*.yaml one file per page: stories, boxes, figures │ ▼ src/newspaper/ geometry.py pure page/column arithmetic (no ReportLab) typography.py font registration + paragraph stylesheet content.py typed content model + strict YAML loaders config.py strict render configuration figures.py 6 halftone engravings (Pillow) + 3 charts (Matplotlib) + 4 colour ad graphics (13 total) components.py flowables: stories, drop caps, boxes, tables, pull quotes furniture.py canvas-drawn nameplate, section bands, folios, column rules layout.py column-frame construction + content flow engine.py top-level render → output/pdf/the-triplicate.pdf ``` The layout strategy is a **hybrid**: fixed *furniture* (nameplate, spanning lead headline, section banners, folios, hairline column rules) is drawn directly on the canvas, establishing where the column grid begins; the body content then *flows* through ReportLab column frames, which split paragraphs across columns automatically. An optional narrow **rail** carries the front-page index and weather. See [`docs/architecture.md`](docs/architecture.md). --- ## Make it your own paper 1. Edit `content/edition.yaml` — change the `nameplate`, `city`, `date`, etc. 2. Edit the files in `content/pages/` — each is a self-describing YAML page. 3. Drop your images in `output/figures/` (or extend `src/newspaper/figures.py`). 4. Re-render. The engine adapts to any number of pages, columns and sections. See [`docs/syntax_guide.md`](docs/syntax_guide.md) for the full content schema and [`docs/forking_guide.md`](docs/forking_guide.md) for turning this into a different title. --- ## Tests & quality ```bash uv run pytest # full suite uv run pytest --cov=newspaper # gate: 90% branch coverage; live baseline: docs/_generated/COUNTS.md uv run ruff check src scripts tests # clean uv run mypy src/newspaper # clean ``` > *The Triplicate* is a real newspaper (founded 1879, Crescent City, CA, and > named for the three copies of its first press run). This is a **template > edition**: the masthead is homage, but every story, byline, name and event in > the content files is illustrative and fictional. ## Template integrity - Forward backlog: [`TODO.md`](TODO.md). - Copy-and-customize config: [`manuscript/config.yaml.example`](manuscript/config.yaml.example). - Project validation: `uv run pytest projects/templates/template_newspaper/tests/ --cov=projects/templates/template_newspaper/src --cov-fail-under=90`. - Repo drift validation: `uv run python scripts/audit/check_template_drift.py --strict`. ## Directory & sub-document map Navigation links to in-tree documents (keeps them discoverable): - [AGENTS — data/](data/AGENTS.md) - [data/](data/README.md) - [AGENTS — docs/](docs/AGENTS.md) - [AGENTS — scripts/](scripts/AGENTS.md) - [Script Conventions](scripts/CONVENTIONS.md) - [scripts/](scripts/README.md) - [AGENTS — src/](src/AGENTS.md) - [src/ — the newspaper engine](src/README.md) - [src/ Style](src/STYLE.md) - [AGENTS — tests/](tests/AGENTS.md) - [Test Patterns](tests/PATTERNS.md) - [tests/](tests/README.md)