Skip to main content

text-compositor

日本語版 (Japanese version)

A tool that treats multiple text files as independent fragments and deterministically composes them into a single human-readable PDF document. Works equally well for AI-generated drafts refined by humans and for existing, hand-authored documents you want to organize and consolidate.

This README covers only the essentials needed to get started quickly. For a full walkthrough of config.yaml and how to write your source documents, see the usage guide (which can also be built into a PDF with cd doc/usage && python ../../build.py). For detailed design rationale and implementation status, see doc/spec.md. Differences from general-purpose tools like Quarto are summarized in doc/diff.md.

Features

  • Combines multiple text files (chapters) into a single PDF
  • Markdown → AST via markdown-it-py → deterministic conversion to Typst syntax → PDF output
  • Outputs other text files to the PDF unchanged
  • Separates the tool itself from the documentation (source files), which can live anywhere outside the repository
  • Python-centric with minimal downloads, no dependency on external servers or SaaS (runs the same way on GitHub Actions and locally on Windows/Linux/macOS)

Files listed in chapters are handled differently depending on their extension:

  • .md/.markdown: converted as Markdown
  • .yaml/.yml/.json: rendered as monospaced text with syntax highlighting
  • .dot/.gv, .mmd, .puml/.plantuml/.pu, .d2: each rendered as a one-chapter diagram (Graphviz, Mermaid, PlantUML, D2 respectively)
  • .csv: rendered as a structured Typst table
  • everything else (plain text, code files, etc.): rendered as plain monospaced text

See the usage guide for details.

Requirements

  • Python 3.10+

Windows note — Microsoft Store Python is not supported, even inside pipx/venv: If Python was installed from the Microsoft Store, this tool cannot be used with it, full stop — pipx or a venv does not work around this.

Windows redirects that Python's writes under %LOCALAPPDATA% into a package-private folder, and this redirection follows the Store installation into any venv/pipx environment created from it (verified by testing), breaking every subprocess-based feature (PlantUML, Mermaid, D2) even though the files appear to exist to Python itself.

Before installing this tool, install Python from python.org (or another non-Store distribution such as winget install Python.Python.3.12) and use that Python for the steps below. Run text-compositor --check-env afterward to confirm the environment is set up correctly.

There are two ways to install and run this tool.

pipx install text-compositor

pipx installs the tool into an isolated environment and exposes the text-compositor command — recommended for most users. If you're developing this tool itself, use a venv instead so an editable install (pip install -e .) picks up code changes immediately:

python -m venv .venv
.venv/bin/pip install -e .        # Windows: .venv\Scripts\pip install -e .

Option B: Clone and run directly (no installation)

pip install -r requirements.txt

No Typst compiler binary is bundled; it's obtained from the typst package (PyPI wheel) installed via pip install above. No additional downloads or installation steps are needed.

Using Mermaid diagrams (optional)

This is only needed if your source documents use ```mermaid fences (or specify an .mmd file directly in chapters). With Option A, install the mermaid extra:

pipx install "text-compositor[mermaid]"
# or, if already installed: pipx inject text-compositor playwright==1.62.0

With Option B (clone and run directly):

pip install playwright==1.62.0
  • A Google Chrome or Microsoft Edge installation already present on your system (no new download by default; it's auto-detected and reused at build time)
  • The playwright package above (used only to connect to the existing browser via CDP; Playwright's own browser-download feature is not used by default)

Node.js/npm is not required. At build time, the official single-file Mermaid bundle (mermaid.min.js, ~3.4MB) is fetched and loaded into a headless browser to convert diagrams to SVG (the bundle JS itself is cached under an OS-standard user cache directory — e.g. %LOCALAPPDATA%\text-compositor\Cache on Windows, ~/.cache/text-compositor on Linux — and conversion results are cached under .text-compositor/cache/; neither is re-fetched afterward). None of this is needed for documents that don't use Mermaid.

If no Chrome/Edge is found on the system, the build fails by default. Setting plugins: { mermaid_auto_download: true } instead auto-fetches Playwright's own Chromium, but this download is about 700MB (this setting exists as a last resort for when no pre-installed browser is available; downloading that much by default is intentionally avoided).

Using PlantUML diagrams (optional)

No extra config.yaml settings are needed to use ```plantuml fences in your source documents (or to specify a .puml file directly in chapters) — plugins.plantuml defaults to true and no additional pip install is required.

  • If Java (11+) is available locally, it's reused as-is
  • Otherwise, Eclipse Temurin JRE (Adoptium distribution, ~49.7MB) is auto-fetched and cached by default under the same user cache directory as above. Setting plugins: { plantuml_auto_download: false } disables the auto-fetch and fails the build instead
  • GitHub Actions' ubuntu-latest ships with Java by default, so no extra download happens on CI

The layout engine is the pure-Java Smetana implementation, so no external binary like Graphviz (dot) is required. PlantUML itself (MIT edition, ~17.6MB) is cached under the same user cache directory, and conversion results are cached under .text-compositor/cache/, same as Mermaid.

Using D2 diagrams (optional)

No extra config.yaml settings are needed to use ```d2 fences in your source documents (or to specify a .d2 file directly in chapters) — plugins.d2 defaults to true and no additional pip install is required.

  • If the d2 command is available locally, it's reused as-is
  • Otherwise, the official D2 CLI binary (a single Go executable, ~13MB) is auto-fetched and cached by default under the same user cache directory as above. Setting plugins: { d2_auto_download: false } disables the auto-fetch and fails the build instead

Unlike Java (used by PlantUML) or a browser (used by Mermaid), GitHub Actions' ubuntu-latest does not ship with D2 preinstalled, so a d2 diagram triggers this ~13MB download on every CI run (this project's workflows don't persist the cache directory across separate runs).

Usage

If installed via pip/pipx (Option A):

text-compositor --config <path/to/text-compositor.config.yaml>

If cloned and run directly (Option B):

python build.py --config <path/to/text-compositor.config.yaml>

If --config is omitted, text-compositor.config.yaml (or .json) located directly in the current directory is auto-detected.

cd my-project/
python /path/to/text-compositor/build.py

Run text-compositor --check-env (or python build.py --check-env) to check your environment (dependencies, Typst version, cached assets, Mermaid/PlantUML/D2 prerequisites) without running a build.

Other flags control runtime behavior only (not document content, which stays entirely in config.yaml): -q/--quiet suppresses [Info]-level logging, -v/--verbose adds extra detail (which chapter is being processed, cache reuse), and --keep-temp keeps the intermediate temp_build.typ around after a successful build instead of deleting it (useful for debugging; it's always kept after a failed build).

See sample/text-compositor.config.yaml for how to write the config file, and the usage guide for details on document:/plugins:, front matter, Marp directives, and more. The Markdown files listed in chapters are concatenated in order to produce the PDF.

Trying the sample

cd sample/
python ../build.py

This generates sample/System_Specification.pdf.

Implementation status

The core feature implemented so far is combining multiple files into a single PDF according to the config file specified via --config (or auto-detected). Expanding CLI options (e.g., overriding the output path) is still in the planning stage. See GitHub Issues for known issues and upcoming plans.

License

MIT License

Release files for text-compositor 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for text-compositor 0.2.0
File Size Uploaded
text_compositor-0.2.0.tar.gz 71.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for text-compositor 0.2.0
File Interpreter ABI Platform
text_compositor-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size:134.0 kB

Release files / text_compositor-0.2.0.tar.gz

Download URL text_compositor-0.2.0.tar.gz
Size 71.9 kB
Tags Source
SHA-256 checksum
How to use checksums
83b1b8f1dca652d9f51ad44c34e9b869720288580c72dffeb419b503c4603f75
BLAKE2b-256 checksum
How to use checksums
43ec00786ed55b60dc43f5b8b2014e68c6a8375e4bdd0cafcb5a337713d28704
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.

Transparency log

Release files / text_compositor-0.2.0-py3-none-any.whl

Download URL text_compositor-0.2.0-py3-none-any.whl
Size 62.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1b0b22d29f06af248d5511398ef11e047b94adae5439fb3eba9d732dc88da192
BLAKE2b-256 checksum
How to use checksums
0d63e7c798278beaabbd50fa0ba0624445359a26609ccf62ec5c74eec39edcae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

This release

0.2.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page