Compare commits

..
Author SHA1 Message Date
David Stadelmann beda61b9f4 feat: auto-detect zigzag-dir from port anchors
When `zigzag-dir` is `auto` (the new default), deduce it from the
endpoint port anchors using `detect-port-side`. East/west ports yield
"vertical" and north/south ports yield "horizontal". If the direction
cannot be deduced (no port anchor on either endpoint, or conflicting
directions) it falls back to "vertical", the previous default.
2026-10-22 00:32:01 +02:00
2 changed files with 6299 additions and 6197 deletions

No files matched your search

+6281 -6193
View File
File diff suppressed because it is too large. Load diff
+18 -4
View File
@@ -299,7 +299,7 @@
/// - directed (bool): If true, the wire will be directed, meaning an arrow will be drawn at the endpoint
/// - rotate-name (bool): If true, the name will be rotated according to the wire's slope
/// - zigzag-ratio (auto, ratio): Position of the zigzag middle bend segment relative to the horizontal (or vertical) span, as a fraction between the two endpoints (only with style "zigzag"). Defaults to `auto`, which resolves to `50%`. Panics if combined with an explicitly set `zigzag-at`.
/// - zigzag-dir (str): The zigzag's direction. As either "vertical" or "horizontal" (only with dstyle "zigzag")
/// - zigzag-dir (auto, str): The zigzag's direction, as either "vertical" or "horizontal" (only with style "zigzag"). If `auto`, it is deduced from the endpoints when they are port anchors of the form `<elmt-id>-port-<port-id>` by comparing each port's position with its element's `.center` anchor: east/west-facing ports yield `"vertical"` (wire exits horizontally) and north/south-facing ports yield `"horizontal"`. If the direction cannot be deduced (no port anchor on either endpoint, or conflicting directions), it falls back to `"vertical"`.
/// - zigzag-at (none, str, array, dictionary): Optional. Anchor-based placement of the zigzag middle bend segment (only with style "zigzag"). When set, overrides `zigzag-ratio` (which must be left at its default `auto`). The middle segment sits on the axis extracted from the given coordinate: `x` for `zigzag-dir: "vertical"`, `y` for `"horizontal"`. Accepted forms: a raw CeTZ anchor name string (e.g. `"elmt.center"` or `"elmt-port-a"`); any native CeTZ coordinate (tuple, dict such as `(rel: (dx, dy), to: anchor)`); or the ergonomic scalar-offset form `(rel: <length>, to: <coord>)`, which is rewritten to a `(dx, 0)` offset for `"vertical"` and `(0, dy)` for `"horizontal"`. See #examples.zigzag-at
/// - dodge-y (number): Y position to dodge the wire to (only with style "dodge")
/// - dodge-sides (array): The start and end sides (going out of the connected element) of the wire (only with style "dodge")
@@ -323,7 +323,7 @@
directed: false,
rotate-name: true,
zigzag-ratio: auto,
zigzag-dir: "vertical",
zigzag-dir: auto,
zigzag-at: none,
dodge-y: 0,
dodge-sides: ("east", "west"),
@@ -368,11 +368,25 @@
(points, anchors) = get-direct-wire(pts)
} else if style == "zigzag" {
let zz-dir = zigzag-dir
if zz-dir == auto {
let side-start = detect-port-side(pts.first(), ctx)
let side-end = detect-port-side(pts.last(), ctx)
let dir-from-side(s) = if s == none { none } else if s == "east" or s == "west" { "vertical" } else { "horizontal" }
let d-start = dir-from-side(side-start)
let d-end = dir-from-side(side-end)
// Fall back to "vertical" (the previous default) when the direction
// cannot be deduced (no port anchors, or conflicting endpoints).
if d-start != none and d-end != none and d-start != d-end { zz-dir = "vertical" }
else if d-start != none { zz-dir = d-start }
else if d-end != none { zz-dir = d-end }
else { zz-dir = "vertical" }
}
(points, anchors) = get-zigzag-wire(
pts,
zigzag-ratio-effective,
zigzag-dir,
at: normalize-zigzag-at(zigzag-at, zigzag-dir),
zz-dir,
at: normalize-zigzag-at(zigzag-at, zz-dir),
)
} else if style == "dodge" {