1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//! # `shapdf` = `shape` + `pdf`
//! Create Shapes into PDF
//!
//! - **🌐 Try it online:** [shapdf.wqzhao.org](https://shapdf.wqzhao.org)
//! - **📚 Documentation:** [docs.rs/shapdf](https://docs.rs/shapdf)
//! - **💻 Source:** [github.com/Teddy-van-Jerry/shapdf](https://github.com/Teddy-van-Jerry/shapdf)
//!
//! ## Motivation
//! - Efficient programmable generation of shapes in PDF (rather than slow compilation of LaTeX [Ti*k*Z](https://tikz.dev/) or Typst [CeTZ](https://cetz-package.github.io/));
//! - Minimal dependencies in Rust, relying mostly on **PDF primitives**;
//! - A lightweight solution for machine generation of simple graphics.
//!
//! ## Capabilities
//! - [x] Shapes
//! - [x] Line
//! - [x] Circle (filled)
//! - [x] Rectangle (filled)
//! - [ ] Polygon
//! - [ ] Text
//! - [x] Color
//! - [ ] Opacity
//! - [x] Rotation & Anchor
//! - [x] PDF Stream Compression (feature `compress`)
//! - [x] CLI for declarative scripts
//! - [x] WebAssembly
//! - [x] Python Bindings
//!
//! More features are coming soon!
//!
//! ## Example
//! The usage of this library is quite simple:
//! ```rust
//! 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`](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/`](examples/cli/):
//! - [`sample_shapes.shapdf`](examples/cli/sample_shapes.shapdf): demonstrates multiple pages, colors, anchors, and rotations.
//! - [`generate_sample.sh`](examples/cli/generate_sample.sh): runs the CLI against the script file and writes `sample_shapes.pdf` beside it.
//! - [`generate_stdin.sh`](examples/cli/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](https://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`](examples/shapdf.wqzhao.org) for the full React/TypeScript web editor implementation.
//!
//! ## Python Bindings
//!
//! Python bindings are available via the `pyshapdf` package:
//!
//! ```sh
//! pip install pyshapdf
//! ```
//!
//! ```python
//! 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`](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](https://stackoverflow.com/a/46897816/15080514).
//!
//! ## License
//! This project is distributed under the [GPL-3.0 License](LICENSE).
//!
//! © 2025 [Teddy van Jerry](https://github.com/Teddy-van-Jerry) ([Wuqiong Zhao](https://wqzhao.org))
use *;
pub use *;
pub use render_script_to_bytes;
pub use render_script_to_pdf;
pub use ;