feat: Add anchor-based zigzag bend placement via zigzag-at

Introduce a new `zigzag-at` parameter on `wire.wire` as an alternative
to `zigzag-ratio` for positioning the middle bend segment of a
`style: "zigzag"` wire. Instead of a fraction of the endpoint span,
the bend is placed on the axis of a referenced anchor via CeTZ's
perpendicular operator (`|-`):

  - zigzag-dir "vertical":   segment sits at anchor.x
  - zigzag-dir "horizontal": segment sits at anchor.y

Accepted forms:
  - str                         — raw CeTZ anchor name (e.g. port anchor
                                  "elmt-port-id" or "elmt.center")
  - array / native CeTZ dict    — used as-is
  - (rel: <length>, to: <coord>) with scalar rel — ergonomic axial
    offset, rewritten to (rel: (dx, 0), to: ...) for vertical dir or
    (rel: (0, dy), to: ...) for horizontal dir

`zigzag-ratio` default flipped from `50%` to `auto` (still resolves
to 50%) to allow detecting an explicit user override. Panics on
misuse:
  - `zigzag-at` set together with an explicit `zigzag-ratio`
  - `zigzag-at` set with a non-zigzag `style`

Add `examples.zigzag-at` demonstrating both the string-anchor and the
ergonomic offset forms.
This commit is contained in:
David Stadelmann committed 2026-09-14 17:47:09 +02:00
1 parent fff5b2ecd5
commit 72eab1620c
3 files changed
+8015 -7666

No files matched your search

+21
View File
@@ -447,3 +447,24 @@ element.block(x: 18.5, y: -3.5, w: 1.5, h: 1.5, id: "sB",
wire.wire("uSS", ("sA-port-out", "sB-port-out"),
style: "u-shape", u-side: "south", u-depth: 0.5)
```, vertical: true)
#let zigzag-at = example(```
// `zigzag-at` places the middle bend of a zigzag wire
// on the axis of a referenced anchor, overriding
// `zigzag-ratio`.
element.block(x: 0, y: 0, w: 1.5, h: 1.5, id: "src",
ports: (east: ((id: "o", name: "O"),),))
element.block(x: 3, y: -1.2, w: 1, h: 1, id: "ref",
fill: util.colors.pink,
ports: (west: ((id: "p", name: "R"),),))
element.block(x: 5.5, y: -2, w: 1.5, h: 1.5, id: "dst",
ports: (west: ((id: "i", name: "I"),),))
// String form: anchor name of a port.
wire.wire("w1", ("src-port-o", "dst-port-i"),
style: "zigzag",
zigzag-at: "ref-port-p")
// Ergonomic offset: shift 8pt right of ref.east.
wire.wire("w2", ("src-port-o", "dst-port-i"),
style: "zigzag",
zigzag-at: (rel: 8pt, to: "ref.east"))
```, vertical: true)