Fullbleed PDF Engine
Fullbleed PDF Engine is a deterministic, self-contained document-generation runtime for Python and Rust. It turns structured data plus static HTML/CSS into reports, invoices, statements, letters, forms, certificates, accessible PDFs, print-ready documents, and high-volume compiled VDP output—without a browser or system PDF stack.
It is designed for human developers, automation, and AI agents alike: the installed runtime exposes its exact version, capabilities, commands, schemas, compliance profiles, examples, limitations, and tool-selection boundary as a generated machine contract.
License: MIT.
- Install:
pip install fullbleed - Try:
fullbleed init . && python report.py - Discover:
fullbleed agent-contract --format json - Outputs:
output/report.pdf - Deterministic + reproducible (
--repro-record/--repro-check) - Agent-safe JSON schemas (
--json-only,--schema)
Positioning
Fullbleed is a deterministic, offline-first document rendering engine for structured print-document and transactional/VDP pipelines (not a browser, not a hosted web-to-print SaaS, and not a general editor for arbitrary existing PDF content).
HTML and CSS are used as a familiar DSL for layout, styling, and data placement in transactional documents.
Agent discovery and integrations
An agent does not need release-specific Fullbleed knowledge. The installed binary generates one canonical contract containing its actual version, selection boundary, capabilities, parser-derived CLI surface, result schemas, PDF profiles, examples, limitations, Agent Skill metadata, MCP tools, and acceptance tasks:
fullbleed agent-manifest --json
# Equivalent canonical form:
fullbleed agent-contract --format json
The committed fullbleed-agent-contract.json, cli_schema.md, and llms.txt are generated from the built wheel. CI rejects version, command, schema, profile, or capability drift. Runtime introspection remains authoritative.
The first-party, versionless skills/fullbleed/SKILL.md teaches tool selection and the render/preview/diagnose/verify loop without duplicating the manual. It is bundled in the wheel and can be exported into any absent or empty agent-skill directory:
fullbleed agent skill-path --json
fullbleed agent export-skill .agents/skills/fullbleed --json
For tool-calling agents, install the separately versioned adapter so the core package remains dependency-free:
python -m pip install fullbleed-mcp
fullbleed-mcp --root .
The stdio server confines document paths to the selected workspace and delegates every engine operation to the installed Fullbleed runtime. It exposes semantic discovery, project creation, render/preview, inspect, verify, assets, and fixed/reflow compiled VDP tools. The dependency-free core also provides fullbleed mcp --root ..
Use Fullbleed when the requested artifact is a deterministic print document built from structured content. Use a browser when the requested artifact is a screenshot or interactive state of an arbitrary live website. Use a general PDF editor when existing page content itself must be rewritten.
Cold-agent testing is available through fullbleed agent-acceptance; compact copyable workflows live in examples/agent_workflows, and the approach-neutral benchmark scaffold lives in agentdocbench.
This README is the canonical usage guide for:
fullbleedCLI (human workflows + machine/agent automation)fullbleedPython bindings (PdfEngine,AssetBundle, batch APIs)
Additional focused references are in docs/:
docs/install-non-technical.md(step-by-step setup for non-technical users)docs/css-coverage.md(validated CSS coverage, parity status, and active gaps)docs/README.mddocs/engine.mddocs/performance-architecture.mddocs/performance-pass-2026-08-04.mddocs/python-api.mddocs/ui-accessibility.mddocs/cli.mddocs/pdf-templates.md
What You Get
- No headless browser requirement for PDF generation.
- Deterministic render pipeline with optional SHA256 output hashing.
- Reproducibility workflow via
--repro-recordand--repro-check. - PDF
1.7as the production-stable default target. - Rust-native PDF template composition for VDP/transactional overlays.
- Native Rust image emission for overlay and finalized compose outputs (
--emit-image) without external PDF raster runtime dependencies. - Feature-driven page-to-template binding with per-page deterministic compose plans.
- Structured JSON result schemas for CI and AI agents.
- Offline-first asset model with explicit remote opt-in.
- Remote project template registry workflows (
new list,new search,new remote). - Python-first extension surface for hackability and custom workflows.
- Python render calls release the GIL while Rust rendering executes.
- Ordered standard-library worker pools for batch rendering and selected internal workloads.
- A deliberately small, license-audited Rust dependency graph and no required third-party Python runtime or build packages.
Concurrency Model
- Python binding render methods release the GIL during Rust execution through the Stable ABI bridge.
- Parallel batch APIs use Fullbleed's ordered standard-library worker pool (
render_pdf_batch_parallel(...)and parallel-to-file variants). - The same bounded worker implementation serves selected internal hotspots such as table layout and JIT paint paths.
- Do not assume every single-document render path will fully saturate all cores end-to-end.
Performance in 2.2
Fullbleed 2.2 retains exact TrueType glyph subsetting and adds compiled fixed-geometry variable-data binding. Across the five independent benchmark fixtures, PDFs are 95.5-97.3% smaller and ordinary warm rendering is 2.90x faster by geometric mean than released 2.0.0.
The new compile-once API freezes an immutable Q32.32 display document and can link it repeatedly
without rerunning HTML parsing, selector matching, layout, pagination, or command planning. For
identical untagged copies in one ordered PDF, CompiledDocument.render_pdf_batch(...) shares each
source page's content stream across the copied page dictionaries. The measured 20-copy lane is
200.7x faster per page by geometric mean than the released 2.0.0 warm renderer; a 1,000-page stress
run sustained 304,479-666,622 pages/s.
The 2.2 compiler includes a genuine fixed-geometry variable-data lane. A compiled invoice with six bound fields rendered 100,000 distinct records in a five-run median of 283.807 ms to memory (352,352 pages/s) and 295.999 ms directly to a flushed 88.1 MB PDF (337,839 pages/s). Including the one-time 4.168 ms compile gives 333,147 direct-file pages/s. The harness verified all 100,000 unique invoice IDs in page order, exact page count, resolved markers, deterministic bytes, and equal buffer/file SHA-256. Reproduce it with:
python tools/benchmark_fullbleed_vdp.py --records 100000 --repeats 5
Fixed-geometry slots may remain inside immutable page-space transforms and clips. The compiler captures that active coordinate-state program once and replays it in each compact record overlay; it does not rerun layout or clone the complete page display list.
The fixed-copy result remains scoped to identical content; the variable-data result is scoped to
paint-only text whose geometry does not reflow. Neither is a claim that arbitrary new HTML or
size-changing records render 200x faster. See
docs/performance-pass-2026-08-04.md for measurements and
docs/performance-architecture.md for the packed vector IR,
typed-binding, virtual-linker, and shader roadmap.
Fullbleed 2.2.5 hardens the third compiler lane introduced in 2.2.4 for
size-changing records: CompiledDocument.render_pdf_reflow_bindings(...). It parses and recovers
the template DOM once and compiles encountered structural flow variants into guarded fixed-point
display programs. Matching records bind directly into those programs; workers execute pre-shaped
text/TJ paint slots, cached static PDF page segments, page-local Deflate, and one ordered linker.
Explicit trusted structural slots use data-fb-bind-html="slot". A value that no compiled variant
can safely place runs ordinary fixed-point layout once to add another variant.
On the independent 1,000-distinct-record case study, the 29-sample hot direct-file median was
216.160 ms: 4,626 records/s and 8,096 pages/s. The 168.995 ms best sample reached 5,917
records/s and 10,355 pages/s. It produced
the exact 1,750-page 500/300/150/50 reflow distribution and verified all 24,900 markers. The
throughput-tuned 6,870,320-byte PDF was deterministic across all samples. With the compact
compression setting, compiled output was also byte-for-byte identical to ordinary rendering:
5,298,961 bytes and SHA-256 bb3c441313a08fb00d3bd15f23a567981f3bbbd550908e3a9fe7a07ca5d7f138.
This is a hot compiled-variant result, not a claim for previously unseen structure. The first
variant-discovery render measured 0.509 s (3,437 pages/s), and the fully cold job including setup,
bindings, compilation, discovery, and write measured 0.588 s (2,975 pages/s). The independently
observed hot-median speedup over the ordinary path was 43.8x.
Install
New to Python or setting up on a fresh machine? Start with docs/install-non-technical.md.
python -m pip install fullbleed
From a local wheel:
python -m pip install C:\path\to\fullbleed-2.3.0-cp310-abi3-win_amd64.whl
From a source checkout with Rust installed, no Python build package is needed:
python -m pip install --no-build-isolation --no-deps --editable .
To create deterministic release artifacts directly:
python build_backend/fullbleed_build_backend.py wheel --out dist
python build_backend/fullbleed_build_backend.py sdist --out dist
Platform artifact policy:
- Linux wheels cover
manylinux2014on x86-64, x86, ARM64, ARMv7, s390x, and ppc64le, plusmusllinux_1_2on x86-64, x86, ARM64, and ARMv7. - Windows wheels cover x86-64, x86, and ARM64; macOS wheels cover Intel and Apple silicon.
- The CPython stable ABI allows each platform wheel to support Python 3.10 through 3.14.
- CI installs and exercises every built wheel on its target architecture, using native runners or QEMU as appropriate. The x86-64 manylinux wheel is additionally tested on every supported Python version before publication.
Verify command surface:
fullbleed --help
fullbleed capabilities --json
fullbleed doctor --json
60-Second Quick Start (Project Happy Path)
Initialize project scaffold:
fullbleed init .
fullbleed init now vendors Bootstrap (5.0.0) into vendor/css/bootstrap.min.css,
vendors Bootstrap Icons (1.11.3) into vendor/icons/bootstrap-icons.svg,
vendors inter into vendor/fonts/Inter-Variable.ttf, writes license notices
(vendor/css/LICENSE.bootstrap.txt, vendor/icons/LICENSE.bootstrap-icons.txt, vendor/fonts/LICENSE.inter.txt),
and seeds assets.lock.json with pinned hashes.
The scaffolded report.py also runs a component mount smoke validation before
main render and writes output/component_mount_validation.json (fails fast on
missing glyphs, actual pagination overflow, or CSS miss signals). On current engines,
render-time pagination is authoritative for overflow; conservative JIT placement bounds
remain the compatibility fallback for older engines.
Scaffolded components now include components/primitives.py with reusable
layout/content helpers (Stack, Row, Text, table/list helpers, key/value rows, etc.).
Each scaffolded project also includes SCAFFOLDING.md, which should be your
first read before restructuring components.
It also includes AGENTS.md, which preserves the installed-runtime-first
document workflow across future coding-agent sessions without making other
document tools categorically forbidden.
Install additional project assets (defaults to ./vendor/... in project context):
fullbleed assets install inter --json
Bootstrap baseline note:
- We target Bootstrap (
5.0.0) as the default styling baseline for project workflows. - Re-run
fullbleed assets install bootstrap --jsononly if you want to explicitly refresh/bootstrap-manage outsideinit.
Render using the scaffolded component pipeline:
python report.py
Expected artifacts from scaffolded report.py:
output/report.pdfoutput/report_page1.png(or equivalent page preview from engine image APIs)output/component_mount_validation.jsonoutput/css_layers.json
Canonical static PDF reference:
python examples/canonical_reference/report.py
examples/canonical_reference/ is the exhaustive scaffold-shaped reference for
component composition, layered CSS, bundled fonts/SVG, inline SVG, raster data
URIs, linked and standalone HTML artifacts, PDF output, PNG previews, and
validation reports.
Project Bootstrap Templates (fullbleed new)
Use local starters:
fullbleed new local invoice ./my-invoice
fullbleed new local statement ./my-statement
fullbleed new local accessible ./my-accessible-doc
fullbleed new local reference ./my-reference-doc
Discover remote starters from registry:
fullbleed new list --json
fullbleed new search i9 --tag vdp --json
fullbleed new remote i9-stamped-vdp ./i9-job --json
fullbleed new local accessible is the verbose accessibility-first starter and
demonstrates the fullbleed.accessibility runtime surface (engine verifier,
PMR, PDF/UA-targeted seed checks, and non-visual trace artifacts).
fullbleed new local reference vendors the canonical static PDF reference shape
as a scaffolded project with component layers, assets, PDF/PNG outputs, page data,
and validation reports.
Optional registry override (for private/canary registries):
fullbleed new list --registry https://example.com/manifest.json --json
or:
set FULLBLEED_TEMPLATE_REGISTRY=https://example.com/manifest.json
fullbleed new search statement --json
Scaffold-First Workflow (Recommended)
fullbleed init is designed for component-first authoring rather than a single large HTML template.
Typical scaffold layout:
.
|-- SCAFFOLDING.md
|-- COMPLIANCE.md
|-- report.py
|-- components/
| |-- fb_ui.py
| |-- primitives.py
| |-- header.py
| |-- body.py
| |-- footer.py
| `-- styles/
| |-- primitives.css
| |-- header.css
| |-- body.css
| `-- footer.css
|-- styles/
| |-- tokens.css
| `-- report.css
|-- vendor/
| |-- css/
| |-- fonts/
| `-- icons/
`-- output/
Best-practice authoring model:
- Read
SCAFFOLDING.mdfirst for project conventions. - Keep composition and data loading in
report.py. - Keep reusable component building blocks in
components/primitives.py. - Keep section markup in
components/header.py,components/body.py,components/footer.py. - Keep component-local styles in
components/styles/*.css. - Keep page tokens/composition styles in
styles/tokens.cssandstyles/report.css.
Recommended CSS layer order:
styles/tokens.csscomponents/styles/primitives.csscomponents/styles/header.csscomponents/styles/body.csscomponents/styles/footer.cssstyles/report.css
Recommended iteration loop:
- Edit data loading + component props in
report.py. - Edit component markup in
components/*.py. - Edit styles in
components/styles/*.cssandstyles/*.css. - Run
python report.py. - Review
output/report_page1.png,output/component_mount_validation.json, andoutput/css_layers.json.
Optional scaffold diagnostics:
FULLBLEED_DEBUG=1to emit JIT traces.FULLBLEED_PERF=1to emit perf traces.FULLBLEED_EMIT_PAGE_DATA=1to persist page data JSON.FULLBLEED_IMAGE_DPI=144(or higher) for preview resolution.FULLBLEED_VALIDATE_STRICT=1for stricter validation gates in CI.
One-off Quick Render (No Project Scaffold)
Render inline HTML/CSS with reproducibility artifacts:
fullbleed --json render \
--html-str "<html><body><h1>Hello</h1></body></html>" \
--css-str "body{font-family:sans-serif}" \
--emit-manifest build/render.manifest.json \
--emit-jit build/render.jit.jsonl \
--emit-perf build/render.perf.jsonl \
--deterministic-hash build/render.sha256 \
--repro-record build/render.repro.json \
--out output/hello.pdf
--deterministic-hash writes the output PDF SHA-256 by default; when --emit-image is enabled, it writes an artifact-set digest (fullbleed.artifact_digest.v1) over PDF SHA-256 plus ordered page-image SHA-256 hashes. JSON outputs expose outputs.deterministic_hash_mode (pdf_only or artifact_set_v1), with outputs.artifact_sha256 and outputs.image_sha256 when images are emitted.
Re-run and enforce reproducibility against a stored record:
fullbleed --json render \
--html templates/report.html \
--css templates/report.css \
--repro-check build/render.repro.json \
--out output/report.rerun.pdf
Generate PNG page artifacts from an existing validation render:
fullbleed --json verify \
--html templates/report.html \
--css templates/report.css \
--emit-pdf output/report.verify.pdf \
--emit-image output/report_verify_pages \
--image-dpi 200
Compile-only plan (no render):
fullbleed --json plan \
--html templates/report.html \
--css templates/report.css
Template compose planning (no finalize write):
fullbleed --json plan \
--html templates/overlay.html \
--css templates/overlay.css \
--template-binding config/template_binding.json \
--templates config/template_catalog.json \
--emit-compose-plan output/compose_plan.json
PDF Template Composition (VDP / Transactional)
When overlaying variable data onto a source PDF, use the built-in Rust template compose path.
Minimal CLI auto-compose flow:
fullbleed --json render \
--html templates/overlay.html \
--css templates/overlay.css \
--asset templates/source.pdf --asset-kind pdf --asset-name source-template \
--template-binding config/template_binding.json \
--templates config/template_catalog.json \
--out output/composed.pdf
Compose image semantics:
- In template auto-compose mode,
--emit-imagePNGs are rasterized from finalized composed pages and reportoutputs.image_mode=composed_pdf. - In non-compose
render/verifyruns,--emit-imagereportsoutputs.image_mode=overlay_document.
Minimal template_binding example:
{
"default_template_id": "source-template",
"feature_prefix": "fb.feature.",
"by_feature": {
"front": "source-template",
"back_blank": "source-template"
}
}
Python API compose flow:
import fullbleed
engine = fullbleed.PdfEngine(template_binding=binding_spec)
overlay_bytes, _page_data, _bindings = engine.render_pdf_with_page_data_and_template_bindings(html, css)
open("output/overlay.pdf", "wb").write(overlay_bytes)
plan_result = engine.plan_template_compose(
html,
css,
[("source-template", "templates/source.pdf")],
0.0,
0.0,
)
plan = [
(
row["template_id"],
row["template_page"],
row["overlay_page"],
row["dx"],
row["dy"],
)
for row in plan_result["plan"]
]
fullbleed.finalize_compose_pdf(
[("source-template", "templates/source.pdf")],
plan,
"output/overlay.pdf",
"output/composed.pdf",
annotation_mode="link_only", # optional: link_only | none | carry_widgets
)
See docs/pdf-templates.md and examples/template-flagging-smoke/ for full production examples.
CLI Command Map
| Command | Purpose | JSON Schema |
|---|---|---|
render |
Render HTML/CSS to PDF with optional PNG page artifacts | fullbleed.render_result.v1 |
verify |
Validation render path with optional PDF and PNG emits | fullbleed.verify_result.v1 |
plan |
Compile/normalize inputs into manifest + warnings | fullbleed.plan_result.v1 |
run |
Render using Python module/file engine factory | fullbleed.run_result.v1 |
inspect pdf |
Inspect PDF metadata and composition compatibility | fullbleed.inspect_pdf.v1 |
inspect pdf-batch |
Inspect multiple PDFs with per-file status | fullbleed.inspect_pdf_batch.v1 |
inspect templates |
Inspect template catalog metadata/compatibility | fullbleed.inspect_templates.v1 |
compliance |
License/compliance report for legal/procurement | fullbleed.compliance.v1 |
debug-perf |
Summarize perf JSONL logs | fullbleed.debug_perf.v1 |
debug-jit |
Filter/inspect JIT JSONL logs | fullbleed.debug_jit.v1 |
doctor |
Runtime capability and health checks | fullbleed.doctor.v1 |
capabilities |
Machine-readable command/engine capabilities | fullbleed.capabilities.v1 |
assets list |
Installed and optional remote packages | fullbleed.assets_list.v1 |
assets info |
Package details + hashes/sizes | fullbleed.assets_info.v1 |
assets install |
Install builtin/remote package | fullbleed.assets_install.v1 |
assets verify |
Validate package and optional lock constraints | fullbleed.assets_verify.v1 |
assets lock |
Write/update assets.lock.json |
fullbleed.assets_lock.v1 |
cache dir |
Cache location | fullbleed.cache_dir.v1 |
cache prune |
Remove old cached packages | fullbleed.cache_prune.v1 |
init |
Initialize project scaffold | fullbleed.init.v1 |
new |
Create starter template files or query/install remote templates | fullbleed.new_template.v1, fullbleed.new_list.v1, fullbleed.new_search.v1, fullbleed.new_remote.v1 |
Schema discovery for any command/subcommand:
fullbleed --schema render
fullbleed --schema assets verify
fullbleed --schema inspect pdf
fullbleed --schema inspect templates
CLI Flags That Matter Most
Global machine flags:
--json: structured result payload to stdout--json-only: implies--jsonand--no-prompts--schema: emit schema definition and exit--no-prompts: disable interactive prompts--config: load defaults from a config file--log-level error|warn|info|debug: control CLI log verbosity--no-color: disable ANSI color output--version: print CLI version and exit
Render/verify/plan key flags:
- Inputs:
--html,--html-str,--css,--css-str--htmlaccepts.svgfiles for direct SVG-document rendering;--html-straccepts inline SVG markup. - Page setup:
--page-size,--page-width,--page-height,--margin,--page-margins - Engine toggles:
--reuse-xobjects,--svg-form-xobjects,--svg-raster-fallback,--shape-text,--unicode-support,--unicode-metrics - PDF/compliance:
--pdf-version,--pdf-profile,--color-space,--document-lang,--document-titleStable default is--pdf-version 1.7for shipping workflows. Profile targets:none,pdfa1a,pdfa1b,pdfa2a,pdfa2b,pdfa2u,pdfa3a,pdfa3b,pdfa3u,pdfa4,pdfa4e,pdfa4f,pdfx4,pdfua1,pdfua2,pdfvt1,wtpdf1r,wtpdf1a,tagged. Aliases:a,ua,vt,wt1r,wt1a,pdf/a,pdf/ua,pdf/vt. Output intent metadata (--output-intent-identifier|--output-intent-info|--output-intent-components) requires--output-intent-icc. Runpython tools/validate_pdf_profiles.py --download-verapdf --install-pdf-oxide --strict-externalto regenerate profile specimens, capture inspect/JIT evidence, replay deterministic hashes, validate PDF/A and PDF/UA with veraPDF, and validate PDF/X-4 withpdf_oxide. WTPDF profiles are validated with veraPDFwt1r/wt1aand include PDF Declaration evidence.pdfa4femits and checks an associatedEmbeddedFilesname tree.pdfvt1also emits and checks a parsed DPart graph (DPartRoot,DPartRootNode, one-levelNodeNameList, leaf page range, and page/DPartreferences), including a supplemental multipage specimen for/Startand/End, reported as granular booleans pluspdfvt_dpart_graph_valid; use a dedicated PDF/VT preflight tool for third-party PDF/VT certification, or wire one into the same harness with--pdfvt-cmd "tool --input {pdf}" --require-dedicated-pdfvt. - Watermarking:
--watermark-text,--watermark-html,--watermark-image,--watermark-layer,--watermark-semantics,--watermark-opacity,--watermark-rotation - Artifacts:
--emit-jit,--emit-perf,--emit-glyph-report,--emit-page-data,--emit-compose-plan,--emit-image,--image-dpi,--deterministic-hash - Assets:
--asset,--asset-kind,--asset-name,--asset-trusted,--allow-remote-assets - Profiles:
--profile dev|preflight|prod - Fail policy:
--fail-on overflow|missing-glyphs|font-subst|budget - Fallback policy:
--allow-fallbacks(keeps fallback diagnostics, but does not failmissing-glyphs/font-substgates) - Reproducibility:
--repro-record <path>,--repro-check <path> - Budget thresholds:
--budget-max-pages,--budget-max-bytes,--budget-max-ms - Release gates:
doctor --strict,compliance --strict --max-audit-age-days <n>
SVG Workflows
Fullbleed supports SVG in three practical CLI paths:
- Direct SVG document render via
--html <file.svg> - Inline SVG markup via
--html-str "<svg ...>...</svg>" - Referenced SVG assets via
--asset <file.svg>(kind auto-infers tosvg)
Standalone SVG file to PDF:
fullbleed --json render \
--html artwork/badge.svg \
--out output/badge.pdf
Inline SVG markup to PDF:
fullbleed --json render \
--html-str "<svg xmlns='http://www.w3.org/2000/svg' width='200' height='80'><rect width='200' height='80' fill='#0d6efd'/><text x='16' y='48' fill='white'>Hello SVG</text></svg>" \
--out output/inline-svg.pdf
HTML template with explicit SVG asset registration:
fullbleed --json render \
--html templates/report.html \
--css templates/report.css \
--asset assets/logo.svg \
--asset-kind svg \
--out output/report.pdf
SVG render behavior flags:
--svg-form-xobjects/--no-svg-form-xobjects--svg-raster-fallback/--no-svg-raster-fallback
Distributed Python wheels enable the svg_raster engine feature, so
--svg-raster-fallback can rasterize unsupported SVG constructs such as SVG
text, filters, masks, and foreignObject into deterministic image content.
Custom source builds must include --features python,svg_raster to advertise
and use that fallback path.
Machine discovery:
fullbleed capabilities --json
Inspect the svg object in fullbleed.capabilities.v1 for SVG support metadata. The engine
object also reports compiled-document/reflow availability and supported per-call compression modes.
It reports the compiled svg_raster build feature plus a feature matrix for
native-vector SVG, raster-fallback-required SVG, and unsupported/known-loss SVG
features.
Image Support Matrix
Launch-safe image claims:
- Supported direct raster inputs: PNG and JPEG.
- SVG is handled by the SVG pipeline described above, with native-vector output
where supported and raster fallback for fallback-only features when
svg_rasteris enabled. - Supported references include filesystem paths, registered bundle assets,
file/data URIs,
<img>, CSSbackground-image: url(...), list-style images, and watermark images. - Unsupported or not launch-claimed as direct inputs: WebP, GIF, TIFF, AVIF,
BMP, animated images,
<picture>,srcset,sizes, density descriptors, and browser-style responsive image selection. - For deterministic builds, prefer vendored local assets or registered
AssetBundleinputs; remote assets must be explicitly allowed.
Per-Page Templates (page_1, page_2, page_n)
Fullbleed uses ordered page templates internally. In docs, this is easiest to think of as:
page_1: first page templatepage_2: second page templatepage_n: repeating template for later pages
Configuration mapping:
- CLI
--page-marginskeys:1,2, ... and optional"n"(or"each"alias). - Python
PdfEngine(page_margins=...): same key model. - Missing numeric pages fall back to the base
margin. - The last configured template repeats for remaining pages.
Minimal CLI example:
{
"1": {"top": "12mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},
"2": {"top": "24mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},
"n": {"top": "30mm", "right": "12mm", "bottom": "12mm", "left": "12mm"}
}
fullbleed --json render \
--html templates/report.html \
--css templates/report.css \
--page-margins page_margins.json \
--header-each "Statement continued - Page {page} of {pages}" \
--out output/report.pdf
Minimal Python example:
import fullbleed
engine = fullbleed.PdfEngine(
page_width="8.5in",
page_height="11in",
margin="12mm",
page_margins={
1: {"top": "12mm", "right": "12mm", "bottom": "12mm", "left": "12mm"}, # page_1
2: {"top": "24mm", "right": "12mm", "bottom": "12mm", "left": "12mm"}, # page_2
"n": {"top": "30mm", "right": "12mm", "bottom": "12mm", "left": "12mm"} # page_n
},
header_first="Account Statement",
header_each="Statement continued - Page {page} of {pages}",
footer_last="Final page",
)
Note:
- CLI currently exposes
--header-each/--footer-each(and--header-html-each/--footer-html-each). - For
first/lastheader/footer variants (header_first,header_last,footer_first,footer_last), use the Python API.
Asset Workflow (CLI)
List installed + available packages:
fullbleed assets list --available --json
Install builtin assets:
fullbleed assets install bootstrap
fullbleed assets install bootstrap-icons
# `@bootstrap` / `@bootstrap-icons` are also supported aliases
PowerShell note:
- Quote
@aliases (for example"@bootstrap") to avoid shell parsing surprises.
Install remote asset package:
fullbleed assets install inter
Install broad Unicode fallback package (larger font payload):
fullbleed assets install noto-sans
Install to a custom vendor directory:
fullbleed assets install bootstrap --vendor ./vendor
Install to global cache:
fullbleed assets install inter --global
Install common barcode fonts (license-safe defaults):
fullbleed assets install libre-barcode-128
fullbleed assets install libre-barcode-39
fullbleed assets install libre-barcode-ean13-text
Verify against lock file with strict failure:
fullbleed assets verify inter --lock --strict --json
Preview cache cleanup without deleting files:
fullbleed cache prune --max-age-days 30 --dry-run --json
Notes:
- Builtin packages accept both plain and
@references (bootstrap==@bootstrap,bootstrap-icons==@bootstrap-icons,noto-sans==@noto-sans). noto-sansis available as a builtin fallback package, but it is intentionally larger thaninter; use it when your document requires broader glyph coverage.- Project installs default to
./vendor/when project markers are present (assets.lock.json,report.py, orfullbleed.tomlin CWD). - If no project markers are found,
assets installdefaults to global cache unless--vendoris explicitly set. - Do not hardcode cache paths like
%LOCALAPPDATA%/fullbleed/cache/...; useassets install --jsonand consumeinstalled_to. - Installed assets include license files in typed vendor directories (for example
vendor/fonts/,vendor/css/). assets lock --addis currently aimed at builtin package additions.- Barcode packages in the remote registry are currently OFL-1.1 families from Google Fonts (
Libre Barcode). - USPS IMB fonts are not currently auto-installable via
assets install; use local vetted font files and track licensing separately.
Bootstrap Vendoring
Bootstrap builtin package details:
- Package:
bootstrap(alias:@bootstrap) - Bundled version:
5.0.0 - Asset kind: CSS (
bootstrap.min.css) - Default install location:
vendor/css/bootstrap.min.css(project mode) - License:
MIT - License source:
https://raw.githubusercontent.com/twbs/bootstrap/v5.0.0/LICENSE
Bootstrap Icons builtin package details:
- Package:
bootstrap-icons(alias:@bootstrap-icons) - Bundled version:
1.11.3 - Asset kind: SVG sprite (
bootstrap-icons.svg) - Default install location:
vendor/icons/bootstrap-icons.svg(project mode) - License:
MIT - License source:
https://raw.githubusercontent.com/twbs/icons/v1.11.3/LICENSE
Bootstrap notes:
- Bootstrap is vendored and installable through the asset pipeline.
- Bootstrap CSS is consumed as an explicit local asset (
--asset @bootstraporAssetBundle); external HTML<link rel="stylesheet">is not an execution path. - Bootstrap preflight examples remain useful smoke examples, but they are not the canonical source of CSS parity claims.
Validated CSS Coverage
For the full, maintained coverage statement, see docs/css-coverage.md.
Summary as of May 19, 2026:
- Tracked CSS modules:
22 - Module state:
22/22 in_progress - Full CSS fixture lane:
86/86fixtures passing with603assertion/paint checks - Parity status check: green (
tools/generate_css_parity_status.py --check --json) - Canonical validation artifact:
_css_working/css_parity_status.json - Canonical validation artifact:
_css_working/tmp/fixture_full_latest.json - Canonical validation artifact:
_css_working/css_broad_coverage_sprint_s14.md
The complete pinned independent Wheel265 gate closed on August 9, 2026 with 1,642 PASS,
0 FAIL, and 20 REFERENCE-DISPUTED across 1,662 fixtures. That is strict 100% parity for
every adjudicable fixture in this named corpus; disputed references remain visible and are not
relabeled as implementation passes. Broader web-platform coverage remains bounded by the module
and known-gap contract in docs/css-coverage.md.
Flow/reflow hardening validated on August 5, 2026 adds fixed-height block,
one-column grid, and column-flex continuation slicing; avoids content
duplication; retains empty styled captions inside avoided figures; preserves
display: contents grid paint phase; and keeps positioned containing blocks
atomic. The independent review's targeted 18-case regression cluster passes
18/18 (13 pixel-exact, maximum above-floor difference 0.97030199%). This
targeted diagnostic does not replace the full external-corpus report.
Current validated behavior includes first-class parser -> evaluator -> calculator -> layout/paint coverage across broad static-document CSS domains (values math, layout primitives, pagination/fragmentation baselines, transforms phase-1, gradient/effects subsets including color-first and interleaved-color filter: drop-shadow(...) with computed lengths, modern rgb() shadow colors with mm lengths, duplicate drop-shadow(...) color rejection, empty optional filter-function defaults, explicit/currentColor backdrop-filter: drop-shadow(...) raster paint, strict box-shadow length/color grammar with modern rgb() plus mm paint coverage, softened blurred inset edge paint, and directional inset offset edge paint, overflow-gated text-overflow: ellipsis, physical min/max box constraints, horizontal-tb RTL direction inline inset/margin/padding/border mapping, vertical writing-mode direction: rtl inline inset remapping, vertical-rl logical sizing/insets/margin/padding/border/min-max constraints, vertical-lr logical sizing/min-max/insets/margin/padding/border remapping, basic vertical text columns with vertical-rl leftward and vertical-lr rightward line progression, and deterministic diagnostics).
Known gap categories are explicitly tracked for the final parity push:
- remaining filter/backdrop-filter function breadth beyond current subset, including SVG
url()filters, advanceddrop-shadow()forms beyond the current flexible-color-order foreground and baseline backdrop coverage, and PDF-native foreground filters - advanced
clip-pathgrammar beyond the current basic-shape subset, including SVG clip sources, SVG-specific geometry boxes, and deeper edge grammar - plus-lighter PDF-native parity and deeper nested compositing/isolation breadth
- deeper blurred inset shadow edge fidelity
- remaining multi-layer background image edge semantics beyond the current sized gradient-layer repeat-x/space/round and PNG
url(...)explicit-size/auto-auto-intrinsic/negative-size-invalid/contain/cover/auto-dimension-size/single-value-size/alpha-stack/default-repeat-repeat/repeat-y/repeat/repeat-no-repeat/no-repeat-repeat/space-space/round-round/round-space/space-round/round-repeat/round-no-repeat/no-repeat-round/no-repeat-space/space-no-repeat/repeat-space/repeat-round/space-repeat/logical-repeat-aliases/multi-layer-repeat-axis/background-list-repetition/percentage-position/edge-offset-position/logical-position-aliases/shorthand-position-size-repeat/content-box-origin-clip/multi-layer-origin-clip/background-blend-normal/background-blend-multiply/screen-mode/overlay-mode/exclusion-mode/hard-light-mode/darken-mode/lighten-mode/color-dodge-mode/color-burn-mode/soft-light-mode/hue-mode/saturation-mode/color-mode/luminosity-mode/plus-lighter-mode/list-repetition/truncation/raster-blend/raster-layer-mapping/mixed-raster-gradient-mapping/mixed-gradient-raster-mapping subset, including broader mixed raster stack combinations - table layout edge semantics hardening beyond the current fixed-layout width-hint, auto-width, caption-side placement, and invalid caption-side inheritance lanes
- full vertical text/layout flow beyond the current vertical static-layout and basic wrapped text-column baseline
run Command (Python Factory Interop)
run lets the CLI use a Python-created engine instance.
report.py:
import fullbleed
def create_engine():
return fullbleed.PdfEngine(page_width="8.5in", page_height="11in", margin="0.5in")
CLI invocation:
fullbleed --json run report:create_engine \
--html-str "<h1>From run</h1>" \
--css templates/report.css \
--out output/report.pdf
Entrypoint formats:
module_name:factory_or_enginepath/to/file.py:factory_or_engine
Python API Quick Start
import fullbleed
engine = fullbleed.PdfEngine(
page_width="8.5in",
page_height="11in",
margin="0.5in",
pdf_version="1.7",
pdf_profile="none",
color_space="rgb",
)
html = "<html><body><h1>Invoice</h1><p>Hello.</p></body></html>"
css = "body { font-family: sans-serif; }"
bytes_written = engine.render_pdf_to_file(html, css, "output/invoice.pdf")
print(bytes_written)
Register local assets with AssetBundle:
import fullbleed
bundle = fullbleed.AssetBundle()
bundle.add_file("vendor/css/bootstrap.min.css", "css", name="bootstrap")
bundle.add_file("vendor/fonts/Inter-Variable.ttf", "font", name="inter")
engine = fullbleed.PdfEngine(page_width="8.5in", page_height="11in")
engine.register_bundle(bundle)
engine.render_pdf_to_file("<h1>Styled</h1>", "", "output/styled.pdf")
Python API Signatures (Runtime-Verified)
Thes
No comments yet
Be the first to share your take.