forked from HEL/circuiteria
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c6e5f44df |
No files matched your search
@@ -71,6 +71,30 @@ wire.wire("w4", ("p6","p7"), style: "guided",
|
|||||||
|
|
||||||
```, vertical: true)
|
```, 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,
|
||||||
|
)
|
||||||
|
|
||||||
#let stub = example(```
|
#let stub = example(```
|
||||||
draw.circle((0, 0), radius: .1, name: "p")
|
draw.circle((0, 0), radius: .1, name: "p")
|
||||||
wire.stub("p", "north", name: "north", length: 1)
|
wire.stub("p", "north", name: "north", length: 1)
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
// Demonstrates the `(from: <anchor>, to: <port-id>)` port-alignment shorthand
|
|
||||||
// for the `x` parameter (analogous to the existing shorthand for `y`).
|
|
||||||
#import "/src/lib.typ": circuit, element, util, wire
|
|
||||||
|
|
||||||
#set page(width: auto, height: auto, margin: .5cm)
|
|
||||||
|
|
||||||
#circuit({
|
|
||||||
// Anchor block: absolute placement, with a single "addr" port on its
|
|
||||||
// north side (auto-centred horizontally by circuiteria).
|
|
||||||
element.block(
|
|
||||||
x: 0, y: 0, w: 2, h: 1.5,
|
|
||||||
id: "vcemem",
|
|
||||||
fill: util.colors.orange,
|
|
||||||
ports: (north: ((id: "addr"),), east: ((id: "out"),))
|
|
||||||
)
|
|
||||||
|
|
||||||
// This block's "addr" port (south side) is x-aligned with vcemem's "addr"
|
|
||||||
// port (north side), even though B is wider than vcemem and not
|
|
||||||
// horizontally aligned by default.
|
|
||||||
element.block(
|
|
||||||
x: (from: "vcemem-port-addr", to: "addr"),
|
|
||||||
y: (rel: 2, to: "vcemem.north"),
|
|
||||||
w: 4.5, h: 1,
|
|
||||||
id: "fsm",
|
|
||||||
fill: util.colors.yellow,
|
|
||||||
ports: (south: ((id: "addr"),), east: ((id: "out"),))
|
|
||||||
)
|
|
||||||
|
|
||||||
wire.wire("wAddr", ("vcemem-port-addr", "fsm-port-addr"), style: "zigzag")
|
|
||||||
})
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,46 +0,0 @@
|
|||||||
// Demonstrates the `(rel: <number>, to: <anchor>)` shorthand for the `y`
|
|
||||||
// parameter (analogous to the existing shorthand for `x`).
|
|
||||||
#import "/src/lib.typ": circuit, element, util, wire
|
|
||||||
|
|
||||||
#set page(width: auto, height: auto, margin: .5cm)
|
|
||||||
|
|
||||||
#circuit({
|
|
||||||
// Anchor block: absolute placement.
|
|
||||||
element.block(
|
|
||||||
x: 0, y: 0, w: 2, h: 1.5,
|
|
||||||
id: "A",
|
|
||||||
fill: util.colors.orange,
|
|
||||||
ports: (east: ((id: "out"),))
|
|
||||||
)
|
|
||||||
|
|
||||||
// X relative, Y absolute (existing feature).
|
|
||||||
element.block(
|
|
||||||
x: (rel: 1, to: "A.east"), y: 0, w: 2, h: 1.5,
|
|
||||||
id: "B",
|
|
||||||
fill: util.colors.yellow,
|
|
||||||
ports: (west: ((id: "in"),), east: ((id: "out"),))
|
|
||||||
)
|
|
||||||
|
|
||||||
// Both X and Y relative to another element's anchor (new feature).
|
|
||||||
element.block(
|
|
||||||
x: (rel: 1, to: "B.east"),
|
|
||||||
y: (rel: 2, to: "B.south-west"),
|
|
||||||
w: 2, h: 1.5,
|
|
||||||
id: "C",
|
|
||||||
fill: util.colors.green,
|
|
||||||
ports: (west: ((id: "in"),))
|
|
||||||
)
|
|
||||||
|
|
||||||
// Y relative only, X absolute.
|
|
||||||
element.block(
|
|
||||||
x: 0,
|
|
||||||
y: (rel: -2.5, to: "A.south-west"),
|
|
||||||
w: 2, h: 1.5,
|
|
||||||
id: "D",
|
|
||||||
fill: util.colors.blue,
|
|
||||||
ports: (east: ((id: "out"),))
|
|
||||||
)
|
|
||||||
|
|
||||||
wire.wire("wAB", ("A-port-out", "B-port-in"))
|
|
||||||
wire.wire("wBC", ("B-port-out", "C-port-in"), style: "zigzag")
|
|
||||||
})
|
|
||||||
+6766
-7050
File diff suppressed because it is too large.
Load diff
@@ -21,14 +21,10 @@
|
|||||||
/// - draw-shape (function): Draw function
|
/// - draw-shape (function): Draw function
|
||||||
/// - x (number, dictionary): The x position (bottom-left corner).
|
/// - x (number, dictionary): The x position (bottom-left corner).
|
||||||
///
|
///
|
||||||
/// If it is a dictionary, it can take one of two forms:
|
/// If it is a dictionary, it should be in the format `(rel: number, to: str)`, where `rel` is the offset and `to` the base anchor
|
||||||
/// - `(rel: number, to: str)`: `rel` is the x offset and `to` the base anchor
|
|
||||||
/// - `(from: str, to: str)`: `from` is the base anchor and `to` is the id of the port to align with the anchor (analogous to `y`)
|
|
||||||
/// - y (number, dictionary): The y position (bottom-left corner).
|
/// - y (number, dictionary): The y position (bottom-left corner).
|
||||||
///
|
///
|
||||||
/// If it is a dictionary, it can take one of two forms:
|
/// If it is a dictionary, it should be in the format `(from: str, to: str)`, where `from` is the base anchor and `to` is the id of the port to align with the anchor
|
||||||
/// - `(rel: number, to: str)`: `rel` is the y offset and `to` the base anchor (analogous to `x`)
|
|
||||||
/// - `(from: str, to: str)`: `from` is the base anchor and `to` is the id of the port to align with the anchor
|
|
||||||
/// - w (number): Width of the element
|
/// - w (number): Width of the element
|
||||||
/// - h (number): Height of the element
|
/// - h (number): Height of the element
|
||||||
/// - name (none, str): Optional name of the block
|
/// - name (none, str): Optional name of the block
|
||||||
@@ -43,7 +39,6 @@
|
|||||||
/// - stroke (stroke): Border stroke
|
/// - stroke (stroke): Border stroke
|
||||||
/// - id (str): The block id (for future reference)
|
/// - id (str): The block id (for future reference)
|
||||||
/// - auto-ports (bool): Whether to use auto port placements or not. If false, `draw-shape` is responsible for adding the appropiate ports
|
/// - auto-ports (bool): Whether to use auto port placements or not. If false, `draw-shape` is responsible for adding the appropiate ports
|
||||||
/// - ports-x (dictionary): Dictionary of the ports x offsets (used with `auto-ports: false`)
|
|
||||||
/// - ports-y (dictionary): Dictionary of the ports y offsets (used with `auto-ports: false`)
|
/// - ports-y (dictionary): Dictionary of the ports y offsets (used with `auto-ports: false`)
|
||||||
/// - debug (dictionary): Dictionary of debug options.
|
/// - debug (dictionary): Dictionary of debug options.
|
||||||
///
|
///
|
||||||
@@ -63,7 +58,6 @@
|
|||||||
stroke: black + 1pt,
|
stroke: black + 1pt,
|
||||||
id: "",
|
id: "",
|
||||||
auto-ports: true,
|
auto-ports: true,
|
||||||
ports-x: (:),
|
|
||||||
ports-y: (:),
|
ports-y: (:),
|
||||||
debug: (
|
debug: (
|
||||||
ports: false
|
ports: false
|
||||||
@@ -79,45 +73,14 @@
|
|||||||
if w == none { panic("Parameter w must be set") }
|
if w == none { panic("Parameter w must be set") }
|
||||||
if h == none { panic("Parameter h must be set") }
|
if h == none { panic("Parameter h must be set") }
|
||||||
|
|
||||||
if (type(x) == dictionary and "rel" in x) {
|
if (type(x) == dictionary) {
|
||||||
x = util.resolve-rel-coord(ctx, x, 0)
|
let offset = x.rel
|
||||||
} else if (type(x) == dictionary) {
|
|
||||||
let from = x.from
|
|
||||||
let to = x.to
|
let to = x.to
|
||||||
let (to-side, i) = find-port(ports, to)
|
let (ctx, to-pos) = coordinate.resolve(ctx, (rel: (offset, 0), to: to))
|
||||||
let margins = (0%, 0%)
|
x = to-pos.at(0)
|
||||||
if to-side in ports-margins {
|
|
||||||
margins = ports-margins.at(to-side)
|
|
||||||
}
|
|
||||||
|
|
||||||
let dx
|
|
||||||
let left-margin
|
|
||||||
if to-side in ("north", "south") {
|
|
||||||
let used-pct = 100% - margins.at(0) - margins.at(1)
|
|
||||||
let used-width = width * used-pct / 100%
|
|
||||||
left-margin = width * margins.at(0) / 100%
|
|
||||||
|
|
||||||
dx = used-width * (i + 1) / (ports.at(to-side).len() + 1)
|
|
||||||
|
|
||||||
if not auto-ports {
|
|
||||||
left-margin = 0
|
|
||||||
dx = ports-x.at(to)(width)
|
|
||||||
}
|
|
||||||
} else if to-side == "west" {
|
|
||||||
dx = 0
|
|
||||||
left-margin = 0
|
|
||||||
} else if to-side == "east" {
|
|
||||||
dx = width
|
|
||||||
left-margin = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
let (ctx, from-pos) = coordinate.resolve(ctx, from)
|
|
||||||
x = from-pos.at(0) + dx - width + left-margin
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type(y) == dictionary and "rel" in y) {
|
if (type(y) == dictionary) {
|
||||||
y = util.resolve-rel-coord(ctx, y, 1)
|
|
||||||
} else if (type(y) == dictionary) {
|
|
||||||
let from = y.from
|
let from = y.from
|
||||||
let to = y.to
|
let to = y.to
|
||||||
let (to-side, i) = find-port(ports, to)
|
let (to-side, i) = find-port(ports, to)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#import "/src/cetz.typ": draw, coordinate
|
#import "/src/cetz.typ": draw, coordinate
|
||||||
#import "/src/util.typ"
|
|
||||||
#import "../ports.typ": add-ports, add-port
|
#import "../ports.typ": add-ports, add-port
|
||||||
#import "../element.typ"
|
#import "../element.typ"
|
||||||
|
|
||||||
@@ -50,12 +49,13 @@
|
|||||||
if h == none { panic("Parameter h must be set") }
|
if h == none { panic("Parameter h must be set") }
|
||||||
|
|
||||||
if (type(x) == dictionary) {
|
if (type(x) == dictionary) {
|
||||||
x = util.resolve-rel-coord(ctx, x, 0)
|
let offset = x.rel
|
||||||
|
let to = x.to
|
||||||
|
let (ctx, to-pos) = coordinate.resolve(ctx, (rel: (offset, 0), to: to))
|
||||||
|
x = to-pos.at(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type(y) == dictionary and "rel" in y) {
|
if (type(y) == dictionary) {
|
||||||
y = util.resolve-rel-coord(ctx, y, 1)
|
|
||||||
} else if (type(y) == dictionary) {
|
|
||||||
let from = y.from
|
let from = y.from
|
||||||
let to = y.to
|
let to = y.to
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#import "/src/cetz.typ": draw, coordinate
|
#import "/src/cetz.typ": draw, coordinate
|
||||||
#import "/src/util.typ"
|
|
||||||
#import "../ports.typ": add-ports, add-port
|
#import "../ports.typ": add-ports, add-port
|
||||||
#import "../element.typ"
|
#import "../element.typ"
|
||||||
|
|
||||||
@@ -61,12 +60,13 @@
|
|||||||
if h == none { panic("Parameter h must be set") }
|
if h == none { panic("Parameter h must be set") }
|
||||||
|
|
||||||
if (type(x) == dictionary) {
|
if (type(x) == dictionary) {
|
||||||
x = util.resolve-rel-coord(ctx, x, 0)
|
let offset = x.rel
|
||||||
|
let to = x.to
|
||||||
|
let (ctx, to-pos) = coordinate.resolve(ctx, (rel: (offset, 0), to: to))
|
||||||
|
x = to-pos.at(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type(y) == dictionary and "rel" in y) {
|
if (type(y) == dictionary) {
|
||||||
y = util.resolve-rel-coord(ctx, y, 1)
|
|
||||||
} else if (type(y) == dictionary) {
|
|
||||||
let from = y.from
|
let from = y.from
|
||||||
let to = y.to
|
let to = y.to
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,3 @@
|
|||||||
#import "cetz.typ": coordinate
|
|
||||||
|
|
||||||
/// Resolves a relative coordinate shorthand of the form `(rel: <number>, to: <anchor>)`
|
|
||||||
/// to a single scalar along the requested axis.
|
|
||||||
///
|
|
||||||
/// Used to implement the shared `(rel:, to:)` shorthand accepted by the `x` and
|
|
||||||
/// `y` parameters of `elmt`, `gate` and `iec-gate`.
|
|
||||||
///
|
|
||||||
/// - ctx (dictionary): The current CeTZ context
|
|
||||||
/// - val (dictionary): A dictionary with fields `rel` (number) and `to` (anchor)
|
|
||||||
/// - axis (int): `0` for x, `1` for y
|
|
||||||
/// -> number
|
|
||||||
#let resolve-rel-coord(ctx, val, axis) = {
|
|
||||||
let offset = val.rel
|
|
||||||
let to = val.to
|
|
||||||
let delta = if axis == 0 { (offset, 0) } else { (0, offset) }
|
|
||||||
let (_, to-pos) = coordinate.resolve(ctx, (rel: delta, to: to))
|
|
||||||
return to-pos.at(axis)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Predefined color palette
|
/// Predefined color palette
|
||||||
/// #let w = 4
|
/// #let w = 4
|
||||||
/// #box(width: 100%, align(center)[
|
/// #box(width: 100%, align(center)[
|
||||||
|
|||||||
+136
-22
@@ -24,29 +24,123 @@
|
|||||||
return (pts, anchors)
|
return (pts, anchors)
|
||||||
}
|
}
|
||||||
|
|
||||||
#let get-zigzag-wire(pts, ratio, dir) = {
|
// Normalize an anchor-based placement value used by `zigzag-at`, `u-at`, and
|
||||||
|
// the `s-at-*` family.
|
||||||
|
//
|
||||||
|
// `axis` selects which cartesian component the offset applies to:
|
||||||
|
// - `"x"` → offset in x (used when the placement fixes an x coordinate, e.g.
|
||||||
|
// a vertical bend line for horizontal wire flow).
|
||||||
|
// - `"y"` → offset in y (used when the placement fixes a y coordinate).
|
||||||
|
//
|
||||||
|
// Accepted forms:
|
||||||
|
// - `none` → unset; caller falls back to
|
||||||
|
// depth/ratio-based placement.
|
||||||
|
// - `str` / tuple / native CeTZ dict → passed through as a CeTZ coordinate.
|
||||||
|
// - `(rel: <length>, to: <coord>)` with a *scalar* `rel`
|
||||||
|
// → ergonomic axial offset, rewritten
|
||||||
|
// to `(rel: (rel, 0), to: to)` for
|
||||||
|
// `axis == "x"` or
|
||||||
|
// `(rel: (0, rel), to: to)` for
|
||||||
|
// `axis == "y"`. If `rel` is already
|
||||||
|
// an array/tuple, the value is
|
||||||
|
// passed through unchanged.
|
||||||
|
#let normalize-scalar-offset(at, axis) = {
|
||||||
|
if at == none { return none }
|
||||||
|
if type(at) == dictionary and "rel" in at and "to" in at and type(at.rel) != array {
|
||||||
|
let r = at.rel
|
||||||
|
if axis == "x" {
|
||||||
|
return (rel: (r, 0), to: at.to)
|
||||||
|
} else {
|
||||||
|
return (rel: (0, r), to: at.to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return at
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backwards-compatible wrapper: translates the old `dir` vocabulary
|
||||||
|
// (`"vertical"` / `"horizontal"`) to the `axis` vocabulary used by
|
||||||
|
// `normalize-scalar-offset`.
|
||||||
|
#let normalize-zigzag-at(at, dir) = {
|
||||||
|
let axis = if dir == "vertical" { "x" } else { "y" }
|
||||||
|
return normalize-scalar-offset(at, axis)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to deduce the cardinal side a port anchor faces by comparing its
|
||||||
|
// position to the center of the element it belongs to. Returns none if the
|
||||||
|
// anchor is not a port-style anchor (i.e. does not contain "-port-") or if
|
||||||
|
// resolution fails.
|
||||||
|
#let detect-port-side(anchor, ctx) = {
|
||||||
|
if type(anchor) != str { return none }
|
||||||
|
let sep = "-port-"
|
||||||
|
if not anchor.contains(sep) { return none }
|
||||||
|
let elmt-id = anchor.split(sep).first()
|
||||||
|
let port-pos = none
|
||||||
|
let center-pos = none
|
||||||
|
// coordinate.resolve panics on unknown anchors; there is no try/catch in
|
||||||
|
// Typst, so we assume port anchors created by add-port always come with a
|
||||||
|
// matching group of the same name. If not, the user must set the relevant side parameter
|
||||||
|
// explicitly.
|
||||||
|
let (_, p1) = coordinate.resolve(ctx, anchor)
|
||||||
|
let (_, p2) = coordinate.resolve(ctx, elmt-id + ".center")
|
||||||
|
port-pos = p1
|
||||||
|
center-pos = p2
|
||||||
|
let dx = port-pos.at(0) - center-pos.at(0)
|
||||||
|
let dy = port-pos.at(1) - center-pos.at(1)
|
||||||
|
if calc.abs(dx) >= calc.abs(dy) {
|
||||||
|
return if dx >= 0 { "east" } else { "west" }
|
||||||
|
} else {
|
||||||
|
return if dy >= 0 { "north" } else { "south" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let get-zigzag-wire(pts, ratio, dir, at: none) = {
|
||||||
let start = pts.first()
|
let start = pts.first()
|
||||||
let end = pts.last()
|
let end = pts.last()
|
||||||
let mid = if dir == "vertical" {
|
|
||||||
(start, ratio, (horizontal: end, vertical: ()))
|
|
||||||
} else {
|
|
||||||
(start, ratio, (horizontal: (), vertical: end))
|
|
||||||
}
|
|
||||||
|
|
||||||
let points = if dir == "vertical" {
|
let points
|
||||||
(
|
if at == none {
|
||||||
start,
|
// Ratio-based placement (default).
|
||||||
(horizontal: mid, vertical: ()),
|
let mid = if dir == "vertical" {
|
||||||
(horizontal: (), vertical: end),
|
(start, ratio, (horizontal: end, vertical: ()))
|
||||||
end
|
} else {
|
||||||
)
|
(start, ratio, (horizontal: (), vertical: end))
|
||||||
|
}
|
||||||
|
|
||||||
|
points = if dir == "vertical" {
|
||||||
|
(
|
||||||
|
start,
|
||||||
|
(horizontal: mid, vertical: ()),
|
||||||
|
(horizontal: (), vertical: end),
|
||||||
|
end
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
start,
|
||||||
|
(horizontal: (), vertical: mid),
|
||||||
|
(horizontal: end, vertical: ()),
|
||||||
|
end
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
(
|
// Anchor-based placement: the middle bend segment sits on the axis
|
||||||
start,
|
// extracted from `at` via CeTZ's perpendicular operator `|-`:
|
||||||
(horizontal: (), vertical: mid),
|
// - vertical: middle segment at x = at.x
|
||||||
(horizontal: end, vertical: ()),
|
// - horizontal: middle segment at y = at.y
|
||||||
end
|
points = if dir == "vertical" {
|
||||||
)
|
(
|
||||||
|
start,
|
||||||
|
(at, "|-", start),
|
||||||
|
(at, "|-", end),
|
||||||
|
end
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
start,
|
||||||
|
(start, "|-", at),
|
||||||
|
(end, "|-", at),
|
||||||
|
end
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let anchors = (
|
let anchors = (
|
||||||
"start": start,
|
"start": start,
|
||||||
@@ -204,8 +298,9 @@
|
|||||||
/// - reverse (bool): If true, the start and end points will be swapped (useful in cases where the start point depends on the end point, for example with perpendiculars)
|
/// - reverse (bool): If true, the start and end points will be swapped (useful in cases where the start point depends on the end point, for example with perpendiculars)
|
||||||
/// - directed (bool): If true, the wire will be directed, meaning an arrow will be drawn at the endpoint
|
/// - 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
|
/// - rotate-name (bool): If true, the name will be rotated according to the wire's slope
|
||||||
/// - zigzag-ratio (ratio): Position of the zigzag vertical relative to the horizontal span (only with style "zigzag")
|
/// - 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 (str): The zigzag's direction. As either "vertical" or "horizontal" (only with dstyle "zigzag")
|
||||||
|
/// - 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-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")
|
/// - dodge-sides (array): The start and end sides (going out of the connected element) of the wire (only with style "dodge")
|
||||||
/// - dodge-margins (array): The start and end margins (i.e. space before dodging) of the wire (only with style "dodge")
|
/// - dodge-margins (array): The start and end margins (i.e. space before dodging) of the wire (only with style "dodge")
|
||||||
@@ -227,8 +322,9 @@
|
|||||||
guided-sides: ("east", "west"),
|
guided-sides: ("east", "west"),
|
||||||
directed: false,
|
directed: false,
|
||||||
rotate-name: true,
|
rotate-name: true,
|
||||||
zigzag-ratio: 50%,
|
zigzag-ratio: auto,
|
||||||
zigzag-dir: "vertical",
|
zigzag-dir: "vertical",
|
||||||
|
zigzag-at: none,
|
||||||
dodge-y: 0,
|
dodge-y: 0,
|
||||||
dodge-sides: ("east", "west"),
|
dodge-sides: ("east", "west"),
|
||||||
dodge-margins: (5%, 5%)
|
dodge-margins: (5%, 5%)
|
||||||
@@ -241,6 +337,19 @@
|
|||||||
panic("Wrong number of points (got " + str(pts.len()) + " instead of 2)")
|
panic("Wrong number of points (got " + str(pts.len()) + " instead of 2)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `zigzag-at` validation.
|
||||||
|
if zigzag-at != none {
|
||||||
|
if style != "zigzag" {
|
||||||
|
panic("wire '" + id + "': `zigzag-at` requires style: \"zigzag\" (got \""
|
||||||
|
+ style + "\")")
|
||||||
|
}
|
||||||
|
if zigzag-ratio != auto {
|
||||||
|
panic("wire '" + id
|
||||||
|
+ "': cannot combine `zigzag-at` with an explicit `zigzag-ratio`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let zigzag-ratio-effective = if zigzag-ratio == auto { 50% } else { zigzag-ratio }
|
||||||
|
|
||||||
// Normalize user-provided coordinates: (x, y) -> (x, y, 0)
|
// Normalize user-provided coordinates: (x, y) -> (x, y, 0)
|
||||||
let pts = pts.map(normalize-coord)
|
let pts = pts.map(normalize-coord)
|
||||||
|
|
||||||
@@ -259,7 +368,12 @@
|
|||||||
(points, anchors) = get-direct-wire(pts)
|
(points, anchors) = get-direct-wire(pts)
|
||||||
|
|
||||||
} else if style == "zigzag" {
|
} else if style == "zigzag" {
|
||||||
(points, anchors) = get-zigzag-wire(pts, zigzag-ratio, zigzag-dir)
|
(points, anchors) = get-zigzag-wire(
|
||||||
|
pts,
|
||||||
|
zigzag-ratio-effective,
|
||||||
|
zigzag-dir,
|
||||||
|
at: normalize-zigzag-at(zigzag-at, zigzag-dir),
|
||||||
|
)
|
||||||
|
|
||||||
} else if style == "dodge" {
|
} else if style == "dodge" {
|
||||||
(points, anchors) = get-dodge-wire(
|
(points, anchors) = get-dodge-wire(
|
||||||
|
|||||||
Reference in new issue
Block a user