Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,27 @@ concurrency:
cancel-in-progress: true

jobs:
rust-download:
name: Rust starter (Windows)
runs-on: windows-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: '1.97.0'
components: rustfmt
- run: python -m pip install pypdf==6.19.0 Pillow==12.3.0
- name: Verify the actual standalone Rust download
run: python tools/verify_rust_starter.py
- uses: actions/upload-artifact@v4
if: always()
with:
name: rust-starter-verification-Windows
path: output/rust-starter-verification
retention-days: 14
markdown:
name: Markdown starter (${{ matrix.os }})
strategy:
Expand Down Expand Up @@ -175,6 +196,18 @@ jobs:
retention-days: 7
- name: Compile and render the Rust quickstart examples
run: python tools/verify_rust_examples.py
- name: Verify the actual standalone Rust download
run: |
python -m pip install Pillow==12.3.0
python tools/build_rust_starter.py
git diff --exit-code -- docs/assets/rust-starter
python tools/verify_rust_starter.py
- uses: actions/upload-artifact@v4
if: always()
with:
name: rust-starter-verification-Linux
path: output/rust-starter-verification
retention-days: 14
- name: Verify the downloadable PDF regression starter
run: |
python -m venv output/pdf-regression-env
Expand Down Expand Up @@ -337,7 +370,7 @@ jobs:
path: site
deploy:
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
needs: [build, aspnet, chinese, markdown, tagged-notice]
needs: [build, aspnet, chinese, markdown, tagged-notice, rust-download]
runs-on: ubuntu-latest
permissions:
pages: write
Expand Down
Binary file added docs/assets/rust-starter/project.zip
Binary file not shown.
118 changes: 118 additions & 0 deletions docs/assets/rust-starter/source.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
{
"schema": "fullbleed.rust-starter.v1",
"repository": "https://github.com/fullbleed-engine/docs",
"engine": "2.5.11",
"prefix": "fullbleed-rust-starter/",
"files": [
{
"path": ".gitignore",
"source": null,
"bytes": 31,
"sha256": "d146e8d4d5305c063b357cf9ccfc176ee55c480da3b676f7af92726284ea8190"
},
{
"path": "Cargo.lock",
"source": "examples/rust/Cargo.lock",
"bytes": 1299,
"sha256": "48e97f97f7ff701bebbbc391b29114b6f5f45611a3824220243cbea5834e99f2"
},
{
"path": "Cargo.toml",
"source": "examples/rust/Cargo.toml",
"bytes": 272,
"sha256": "be5886957217168275d1a771b759974cf7d85dde29910d7c741ca8dc0d510be1"
},
{
"path": "LICENSE",
"source": "examples/rust/LICENSE",
"bytes": 1079,
"sha256": "36a2115938f6e68cf0d87eccff7a6a3e57c17017e909cbd640d51aff1fa0c5a9"
},
{
"path": "README.md",
"source": "examples/rust/STARTER.md",
"bytes": 3177,
"sha256": "851609cca16a16f8edff04c18077f71317e9057e1a63631fe790d880d0b213af"
},
{
"path": "fonts/BebasNeue-OFL.txt",
"source": "docs/assets/playground/fonts/BebasNeue-OFL.txt",
"bytes": 4337,
"sha256": "72082f6cb4d04be2ecf7cc7d9e1e7d73787f0af8a5a278a47cade70c16b78341"
},
{
"path": "fonts/BebasNeue-Regular.ttf",
"source": "docs/assets/playground/fonts/BebasNeue-Regular.ttf",
"bytes": 61400,
"sha256": "08e4623805102d819f58601e46e345648846075e363b2ceb23313c2d1c83ec73"
},
{
"path": "fonts/DMSerifDisplay-Italic.ttf",
"source": "docs/assets/playground/fonts/DMSerifDisplay-Italic.ttf",
"bytes": 71208,
"sha256": "df74c0ac387baeaeb0fe4f2324e1668e6a3ed8c09cd9796fe162c71753e19e45"
},
{
"path": "fonts/DMSerifDisplay-OFL.txt",
"source": "docs/assets/playground/fonts/DMSerifDisplay-OFL.txt",
"bytes": 4512,
"sha256": "aa49c876a28d8c0b0a3027d6c25b9c607eee8c0fb96165011d42a6ace1408fe1"
},
{
"path": "fonts/DMSerifDisplay-Regular.ttf",
"source": "docs/assets/playground/fonts/DMSerifDisplay-Regular.ttf",
"bytes": 76580,
"sha256": "8cc3643535edf039aa5d95440a8542735e9197e4f4b8d9303e980fefbf5ab616"
},
{
"path": "fonts/Inter-OFL.txt",
"source": "docs/assets/playground/fonts/Inter-OFL.txt",
"bytes": 4377,
"sha256": "5b9321a4298cfeb6b34354164a1c3afc3db114569984c502b9b35d988fd58c57"
},
{
"path": "fonts/Inter-Variable.ttf",
"source": "docs/assets/playground/fonts/Inter-Variable.ttf",
"bytes": 876576,
"sha256": "29160a80ff49ddcab2c97711247e08b1fab27a484a329ce8b813d820dc559031"
},
{
"path": "src/from_files.rs",
"source": "examples/rust/src/from_files.rs",
"bytes": 1462,
"sha256": "3d61f51a714d6c63aa91f5c0cbacdbac816fa950380fdfa6c3d57cf2fc475f6b"
},
{
"path": "src/hello.rs",
"source": "examples/rust/src/hello.rs",
"bytes": 383,
"sha256": "17b2b595c5f237e70f8ff85b7fdb1eaeedd12133a4af69ca4c1d25683c889221"
},
{
"path": "templates/invoice.css",
"source": "docs/assets/showcase/invoice.css",
"bytes": 3546,
"sha256": "cda22b39ab1f7a1eeac7cd76d162b05cd3568c2430c099123ba30a2fbd58a296"
},
{
"path": "templates/invoice.html",
"source": "docs/assets/showcase/invoice.html",
"bytes": 2933,
"sha256": "195725eeeb32c521e19b47dbacbb55048bebb6df8566ab135cdc41fbf33fe57a"
},
{
"path": "templates/report.css",
"source": "docs/assets/showcase/report.css",
"bytes": 4277,
"sha256": "519591ae75c239ec602324f008dd99108ebeae0b9306df7215fa5f0442905473"
},
{
"path": "templates/report.html",
"source": "docs/assets/showcase/report.html",
"bytes": 7756,
"sha256": "46b0e975d43914c8b4492218feae09ea0ad684091a9f9ee3b18f66a87202e521"
}
],
"zip_bytes": 587627,
"zip_sha256": "1747ac09391cae27c644a48bec9986d105f450884571238165b68eb445794b56"
}
45 changes: 31 additions & 14 deletions docs/getting-started/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Use the [`fullbleed` crate](https://crates.io/crates/fullbleed) directly in a
Rust application. The engine renders static HTML and CSS into print documents;
you do not need Python or a browser to render them.

For editable invoice and report templates with fonts included,
[start with the complete Rust project](#render-a-designed-invoice-or-report).

## Create your first PDF

With Rust 1.85 or newer and a working native Rust toolchain:
Expand Down Expand Up @@ -50,30 +53,41 @@ The Python wheel's bundled fonts are not included in the Rust crate.

## Render a designed invoice or report

The runnable example includes font registration, missing-glyph checking, and
PNG previews. It uses the same source and fonts as the
The standalone project includes font registration, missing-glyph checking, and
PNG previews. It contains the Rust source, pinned Cargo dependencies, editable
HTML/CSS, and four font faces with their license notices. It uses the same
document source and fonts as the
[editable browser playground](../playground.md).

[![Northstar invoice rendered with Fullbleed, with cream paper, serif typography, and a forest-green total panel.](../assets/showcase/invoice-1.png)](../assets/showcase/invoice.pdf)

Clone the documentation repository and run the example from its root:
[Download the Rust project](../assets/rust-starter/project.zip){ .md-button .md-button--primary }
[Source and checksums](../assets/rust-starter/source.json){ .md-button }

Extract the ZIP and open a terminal in `fullbleed-rust-starter`:

```bash
cargo run --release --locked --bin from-files -- templates/invoice.html templates/invoice.css fonts output/invoice
```

Open `output/invoice/document.pdf` and `output/invoice/page-1.png`. For the
three-page report:

```bash
git clone https://github.com/fullbleed-engine/docs.git fullbleed-docs
cd fullbleed-docs
cargo run --release --locked --manifest-path examples/rust/Cargo.toml --bin from-files -- docs/assets/showcase/invoice.html docs/assets/showcase/invoice.css docs/assets/playground/fonts output/rust-invoice
cargo run --release --locked --bin from-files -- templates/report.html templates/report.css fonts output/report
```

Open `output/rust-invoice/document.pdf` or `page-1.png` in the same directory.
Replace both `invoice` input filenames with `report` for the report design,
and choose a new output directory. The report produces three
pages. These examples pin Fullbleed 2.5.11 and include a Cargo lockfile.
Edit the files in `templates/` to customize the content and design. Render to a
new output directory after edits, so previews from a longer previous document
do not remain. The first Cargo build downloads dependencies and needs internet
access. These examples pin Fullbleed 2.5.11 and include a Cargo lockfile; the ZIP
is compiled and rendered on Windows and Linux with Rust 1.97.0.

For the service notice or your own edits, choose **Download project** in the
playground. Extract the ZIP into `my-project` in this repository, then run:
playground. Extract its ZIP into `my-project` inside the Rust starter, then run:

```bash
cargo run --release --locked --manifest-path examples/rust/Cargo.toml --bin from-files -- my-project/input.html my-project/style.css my-project/fonts output/my-project
cargo run --release --locked --bin from-files -- my-project/input.html my-project/style.css my-project/fonts output/my-project
```

The Rust example reads the exported HTML, CSS, and fonts directly. The individual
Expand Down Expand Up @@ -132,5 +146,8 @@ boundary.
This walkthrough was written by an AI coding agent for the Fullbleed project.
The [runnable Rust examples are compiled and rendered in documentation CI](https://github.com/fullbleed-engine/docs/actions/workflows/docs.yml),
where their fixture PDFs and PNG previews are compared with the playground's
output. See the [verification source](https://github.com/fullbleed-engine/docs/blob/main/tools/verify_rust_examples.py)
for the checks and their scope.
output. The [download verifier](https://github.com/fullbleed-engine/docs/blob/main/tools/verify_rust_starter.py)
also extracts the actual ZIP, compiles it outside the source tree, and checks
the invoice, report, edited HTML/CSS, failure handling, and repeated output.
See the [example verification source](https://github.com/fullbleed-engine/docs/blob/main/tools/verify_rust_examples.py)
for the playground comparisons and their scope.
6 changes: 6 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ Pick your application stack. Generate a PDF locally or download one from the bro

Use a native Rust toolchain and the published crate.

[Download the styled Rust project](assets/rust-starter/project.zip){ .md-button .md-button--primary }

The ZIP includes editable invoice/report templates, fonts, and a Cargo
lockfile. [Run the project](getting-started/rust.md#render-a-designed-invoice-or-report),
or start with the smaller example below.

```bash
cargo new invoice-demo
cd invoice-demo
Expand Down
21 changes: 21 additions & 0 deletions examples/rust/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Fullbleed Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
4 changes: 4 additions & 0 deletions examples/rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
These examples use the published `fullbleed` 2.5.11 crate. They require Rust
1.85 or newer and a working native Rust toolchain; they do not require Python.

For a standalone project with the templates, fonts, and license notices, use the
[Rust starter ZIP](https://docs.fullbleed.dev/assets/rust-starter/project.zip).
Its [README](STARTER.md) contains commands that run from the extracted directory.

From the root of this documentation repository:

```bash
Expand Down
74 changes: 74 additions & 0 deletions examples/rust/STARTER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Rust PDF starter

Generate a designed invoice and a three-page report from editable HTML/CSS.
This project includes the Rust source, a Cargo lockfile, four font faces, and
their license notices. The sample data is fictional.

## Run the invoice

Install a native Rust toolchain with a linker. The project declares Rust 1.85
as its minimum; the downloadable project is checked with Rust 1.97.0 on Windows
and Linux. No Python installation or browser is needed to render the documents.
Cargo downloads the pinned dependencies on the first build, so that build needs
internet access.

Extract the ZIP, open a terminal in `fullbleed-rust-starter`, and run:

```sh
cargo run --release --locked --bin from-files -- templates/invoice.html templates/invoice.css fonts output/invoice
```

Open `output/invoice/document.pdf` and `output/invoice/page-1.png`. The PNG is
rendered from the finalized PDF at 96 DPI. For the report:

```sh
cargo run --release --locked --bin from-files -- templates/report.html templates/report.css fonts output/report
```

Open `output/report/document.pdf` and its three page previews.

## Make it yours

Edit the HTML for the content and the CSS for typography, colors, tables, and
page layout. Then render to a new output directory:

```sh
cargo run --release --locked --bin from-files -- templates/invoice.html templates/invoice.css fonts output/edited-invoice
```

Use a new output directory when changing page counts: this small example does
not remove old preview files from an existing directory. Review every page
after changing content or styles. See the engine's
[supported CSS](https://docs.fullbleed.dev/css-coverage/) when adapting a web layout.

`src/from_files.rs` registers the four fonts explicitly and rejects characters
that the engine reports as missing. For another font, keep its license notice,
add its filename to the registration list, and use its family name in CSS.
Keep the font files beside the project when moving it.

The renderer takes trusted local paths and static HTML/CSS; it is not an HTTP
server or a sandbox. It does not execute document JavaScript. These examples
produce ordinary PDFs and do not select an accessibility or archival profile.

## Reuse the Rust API

`src/hello.rs` contains the smaller `FullBleed::builder()` and
`render_to_buffer()` example. Run it with:

```sh
cargo run --release --locked --bin hello
```

It writes `invoice.pdf` in the current directory. In an application, return the
PDF bytes from your handler or write them to your storage. Use the full
[Rust walkthrough](https://docs.fullbleed.dev/getting-started/rust/) for font
registration and preview details.

The project pins the published `fullbleed` crate to 2.5.11. `Cargo.lock` records
the resolved dependency versions. No local Fullbleed checkout is required.
The code and templates are MIT licensed; the fonts are SIL OFL 1.1.

This starter was assembled by an AI coding agent for Fullbleed from the
[checked Rust examples](https://github.com/fullbleed-engine/docs/tree/main/examples/rust).
The download is extracted, compiled, and rendered in documentation CI; its
checks cover the included fixtures and edited synthetic input.
Loading
Loading