bland 0.2.1

Pure-Rust library for paper-ready, monochrome, hatch-patterned technical plots in the visual tradition of 1960s-80s engineering reports.
Documentation
# BLAND

> Pure-Rust library for paper-ready, monochrome, hatch-patterned
> technical plots in the visual tradition of 1960s–80s engineering reports.

BLAND emits SVG. Plots look at home next to a title block, a set of
fastener callouts, and a stack of punched cards — black ink on white
paper, serif type, thin rules, hatched fills. No color, no gradients, no
drop shadows.

```rust
use bland::{Figure, PaperSize, Stroke, TitleBlock};

let xs: Vec<f64> = (0..=200).map(|i| i as f64 / 20.0).collect();
let response: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
let envelope: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp()).collect();

let fig = Figure::new()
    .size(PaperSize::A5Landscape)
    .title("Damped oscillation")
    .xlabel("t [s]")
    .ylabel("x(t)")
    .line(&xs, &response, |s| s.label("response"))
    .line(&xs, &envelope, |s| s.label("envelope").stroke(Stroke::Dashed))
    .hline(0.0, |s| s.stroke(Stroke::Dotted))
    .legend_top_right()
    .title_block(
        TitleBlock::new()
            .project("BLAND Reference")
            .title("Fig. 1 · Damped oscillation")
            .drawn_by("JM")
            .date("2026-04-21")
            .scale("1:1")
            .sheet("1 of 1")
            .rev("A"),
    );

std::fs::write("oscillation.svg", fig.to_svg()).unwrap();
```

See the [docs.rs page](https://docs.rs/bland) for embedded example
images of every plot type.

## Why monochrome?

- **Prints clean.** Plots look the same on a laser printer, a color
  printer, and a photocopy. No "figure unreadable in proceedings"
  surprises.
- **Accessible by default.** Hatching, stroke dashing, and marker shape
  distinguish series — so plots survive grayscale rendering and are
  legible to readers with color vision deficiency.

## Features

- **Series**: line, scatter, bar (grouped), area, histogram, heatmap,
  polygon, error bars, box plots, stem plots, quiver / vector fields,
  contour iso-lines, reference rules
- **Hatch patterns**: 13 presets — diagonals, crosshatch, dots, brick,
  zigzag, checker
- **Markers**: 12 shape presets, alternating open / filled
- **Stroke dashes**: solid, dashed, dotted, dash-dot, long-dash, fine
- **Paper presets**: A4, A5, Letter, Legal, Square — portrait & landscape
- **Themes**: `report_1972` (serif), `blueprint` (monospace), `gazette`
  (newspaper)
- **Engineering title block** with project / drawn-by / date / scale /
  sheet / revision
- **Annotations**: in-data text and arrows with anti-overlap halos
- **Linear and log axes** with nice-rounded tick placement
- **Projections**: polar, Smith chart, Mercator, equirectangular
- **Built-in basemaps**: Earth coastlines & borders (Natural Earth
  1:110m, optional 1:50m), reference parallels, lunar maria
- **Multi-panel layouts** and composite helpers (Bode, Q-Q)
- **Pure Rust, zero runtime dependencies**

## Cargo features

- `gui` — adds `Figure::show()`: a matplotlib-style blocking display
  window that renders the figure in an OS-native webview, with a
  Save SVG button and zoom controls. Pulls in `tao` and `wry`. On
  Linux you must have `libwebkit2gtk-4.1-dev` installed system-wide.
- `high-res-basemaps` — adds Natural Earth 1:50m coastline and country
  data (~3 MB compiled). Off by default; the 1:110m datasets and the
  schematic outlines are always available.
- `regen-basemaps` — builds the dev-only `regen_basemaps` binary that
  re-converts Natural Earth GeoJSON into the static Rust data modules.
  Off by default so `cargo install bland` does not install a developer
  tool.

### Quick GUI usage

```rust,ignore
use bland::{Figure, PaperSize};

# fn main() {
let xs: Vec<f64> = (0..=100).map(|i| i as f64 / 10.0).collect();
let ys: Vec<f64> = xs.iter().map(|t| t.sin()).collect();

Figure::new()
    .size(PaperSize::A5Landscape)
    .title("sin(t)")
    .line(&xs, &ys, |s| s)
    .show();  // blocks until the window is closed
# }
```

Run the bundled demo with:

```bash
cargo run --features gui --example show_demo
```

## Examples

The repo ships 22 runnable examples covering every plot type. Run any
of them via:

```bash
cargo run --example damped_oscillation
cargo run --example world_map
cargo run --example smith
```

Output goes to `out/`.

## License

MIT.

This crate ports the Elixir BLAND library; the Natural Earth data
embedded under `src/basemaps/data/` is in the public domain.