shapdf 0.2.1

Create Shapes into PDF
Documentation

shapdf = shape + pdf

Create Shapes into PDF

Motivation

  • Efficient programmable generation of shapes in PDF (rather than slow compilation of LaTeX TikZ or Typst CeTZ);
  • Minimal dependencies in Rust, relying mostly on PDF primitives;
  • A lightweight solution for machine generation of simple graphics.

Capabilities

  • Shapes
    • Line
    • Circle (filled)
    • Rectangle (filled)
    • Polygon
  • Text
  • Color
  • Opacity
  • Rotation & Anchor
  • PDF Stream Compression (feature compress)
  • CLI for declarative scripts
  • WebAssembly
  • Python Bindings

More features are coming soon!

Example

The usage of this library is quite simple:

use shapdf::*;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let mut generator = Generator::new("output/shapes.pdf".into());
    generator.add_page(); // use the default page size (US letter)
    generator
        .circle(Mm(20.), Mm(20.), Mm(10.))
        .with_color(NamedColor("blue"))
        .draw();
    generator
        .line(Pt(500.), Pt(600.), Pt(300.), Pt(400.))
        .with_width(Mm(10.))
        .with_cap_type(CapType::Round)
        .with_color(NamedColor("red"))
        .draw();
    generator.add_page_letter();
    generator
        .rectangle(Mm(80.), Mm(180.), Mm(50.), Mm(30.))
        .with_anchor(Anchor::Center)
        .with_angle(Degree(30.))
        .draw();
    generator
        .circle(Mm(80.), Mm(180.), Mm(1.))
        .with_color(NamedColor("green"))
        .draw();
    generator.add_page_a4();
    generator.write_pdf()?;
    println!("PDF generated successfully!");
    Ok(())
}

More examples are available in the examples directory.

CLI Usage

The binary reads declarative .shapdf scripts and renders them to PDF.

Install via cargo install shapdf (use cargo install --path . when working from a local checkout).

  • shapdf <script.shapdf> renders the file to <script>.pdf in place.
  • shapdf --output output/shape.pdf - reads the script from stdin (e.g. piped from another program).
  • Sample scripts and helpers live in examples/cli/:
    • sample_shapes.shapdf: demonstrates multiple pages, colors, anchors, and rotations.
    • generate_sample.sh: runs the CLI against the script file and writes sample_shapes.pdf beside it.
    • generate_stdin.sh: inlines the same script, pipes it over stdin, and produces sample_shapes_inline.pdf.

Library consumers can also call shapdf::render_script_to_pdf(script, output_path) to execute a script string directly.

.shapdf Script Syntax

  • Lines are command [args] [key=value ...]; blank lines or those starting with #/// are ignored.
  • Supported commands:
    • page default|letter|letter-landscape|a4|a4-landscape
    • page size <width> <height> (accepts mm, cm, in, pt)
    • set default_page_size <width> <height>
    • set default_width <length>
    • set default_color <color> (named colors, #RRGGBB, rgb(r,g,b), or gray(v))
    • set default_cap butt|round|square
    • set default_angle <value> (deg default, or rad)
    • line <x1> <y1> <x2> <y2> [width=...] [color=...] [cap=...]
    • circle <x> <y> <radius> [color=...]
  • rectangle <x> <y> <width> <height> [color=...] [anchor=...] [angle=...]
  • The first drawing command automatically inserts a default page if none was added.

WebAssembly & Web Editor

Try the online editor: shapdf.wqzhao.org

Using WASM in your own project:

  • Build the library with --features wasm to enable shapdf::render_script_to_bytes(script) for in-memory rendering.
  • The returned Vec<u8> contains the PDF bytes, ready to serve or download in a web context.
  • See examples/shapdf.wqzhao.org for the full React/TypeScript web editor implementation.

Python Bindings

Python bindings are available via the pyshapdf package:

pip install pyshapdf
import pyshapdf

script = """
page letter
circle 100mm 150mm 20mm color=blue
rectangle 50mm 50mm 40mm 30mm color=green angle=45deg anchor=center
"""

pyshapdf.render_script(script, "output.pdf")

See python/README.md for full documentation, examples, and API reference.

Implementation Facts

License

This project is distributed under the GPL-3.0 License.

© 2025 Teddy van Jerry (Wuqiong Zhao)