shapdf = shape + pdf
Create Shapes into PDF
- 🌐 Try it online: shapdf.wqzhao.org
- 📚 Documentation: docs.rs/shapdf
- 💻 Source: github.com/Teddy-van-Jerry/shapdf
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 *;
use Error;
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>.pdfin place.shapdf --output output/shape.pdf -reads the script fromstdin(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 writessample_shapes.pdfbeside it.generate_stdin.sh: inlines the same script, pipes it overstdin, and producessample_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-landscapepage size <width> <height>(acceptsmm,cm,in,pt)set default_page_size <width> <height>set default_width <length>set default_color <color>(named colors,#RRGGBB,rgb(r,g,b), orgray(v))set default_cap butt|round|squareset default_angle <value>(degdefault, orrad)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 wasmto enableshapdf::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.orgfor the full React/TypeScript web editor implementation.
Python Bindings
Python bindings are available via the pyshapdf package:
=
See python/README.md for full documentation, examples, and API reference.
Implementation Facts
- Filled circle is actually implemented using a zero-length line with the rounded line cap.
License
This project is distributed under the GPL-3.0 License.
© 2025 Teddy van Jerry (Wuqiong Zhao)