deps: update CeTZ 0.3.4 to 0.5.2 with coordinate fixes
CeTZ 0.5.2 requires 3D coordinate vectors (x, y, z) for raw coordinate tuples passed to coordinate.resolve(). Update internal wire computations (dodge, guided) to use 3-element tuples, fix .last() to .at(1) for y-component access on resolved coordinates, and add a normalize-coord utility that automatically pads user- provided 2D points (x, y) to (x, y, 0) so users do not need to specify the z dimension.
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 11 KiB |
BIN
gallery/test.png
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 195 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 5.8 KiB |
BIN
manual.pdf
@@ -1 +1 @@
|
||||
#import "@preview/cetz:0.3.4": *
|
||||
#import "@preview/cetz:0.5.2": *
|
||||
43
src/util.typ
@@ -73,4 +73,45 @@
|
||||
#let valid-anchors = (
|
||||
"center", "north", "east", "west", "south",
|
||||
"north-east", "north-west", "south-east", "south-west"
|
||||
)
|
||||
)
|
||||
|
||||
/// Normalizes a coordinate so that 2D points (x, y) are padded
|
||||
/// to (x, y, 0) as required by CeTZ's coordinate resolver.
|
||||
/// Also handles function-based and dictionary-based coordinates
|
||||
/// recursively.
|
||||
///
|
||||
/// - coord (any): A CeTZ-compatible coordinate
|
||||
/// -> any
|
||||
#let normalize-coord(coord) = {
|
||||
if type(coord) == array {
|
||||
if coord.len() == 2 {
|
||||
let (a, b) = coord
|
||||
// Raw 2D point: (x, y) -> (x, y, 0)
|
||||
if type(a) in (int, float) and type(b) in (int, float) {
|
||||
return (a, b, 0)
|
||||
}
|
||||
// Function-based coordinate: (fn, point)
|
||||
if type(a) == function {
|
||||
let orig = a
|
||||
return (v => {
|
||||
let result = orig(v)
|
||||
if type(result) == array and result.len() == 2 {
|
||||
let (rx, ry) = result
|
||||
if type(rx) in (int, float) and type(ry) in (int, float) {
|
||||
return (rx, ry, 0)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
if type(coord) == dictionary {
|
||||
let result = (:)
|
||||
for (key, value) in coord {
|
||||
result.insert(key, normalize-coord(value))
|
||||
}
|
||||
return result
|
||||
}
|
||||
return coord
|
||||
}
|
||||
25
src/wire.typ
@@ -1,5 +1,5 @@
|
||||
#import "/src/cetz.typ": draw, coordinate
|
||||
#import "util.typ": opposite-anchor
|
||||
#import "util.typ": opposite-anchor, normalize-coord
|
||||
|
||||
/// List of valid wire styles
|
||||
/// #examples.wires
|
||||
@@ -68,8 +68,8 @@
|
||||
|
||||
let (ctx, p0) = coordinate.resolve(ctx, start)
|
||||
let (ctx, p3) = coordinate.resolve(ctx, end)
|
||||
p0 = (x: p0.first(), y: p0.last())
|
||||
p3 = (x: p3.first(), y: p3.last())
|
||||
p0 = (x: p0.first(), y: p0.at(1))
|
||||
p3 = (x: p3.first(), y: p3.at(1))
|
||||
|
||||
let dx1 = margin-start
|
||||
let dx2 = margin-end
|
||||
@@ -86,13 +86,13 @@
|
||||
if side-end == "east" {
|
||||
dx2 *= -1
|
||||
}
|
||||
p1 = (p0.x + dx1, p0.y)
|
||||
p2 = (p3.x - dx2, p0.y)
|
||||
p1 = (p0.x + dx1, p0.y, 0)
|
||||
p2 = (p3.x - dx2, p0.y, 0)
|
||||
|
||||
let points = (
|
||||
start,
|
||||
(horizontal: p1, vertical: ()),
|
||||
(horizontal: (), vertical: (0, dodge-y)),
|
||||
(horizontal: (), vertical: (0, dodge-y, 0)),
|
||||
(horizontal: p2, vertical: ()),
|
||||
(horizontal: (), vertical: end),
|
||||
end
|
||||
@@ -147,18 +147,18 @@
|
||||
|
||||
|
||||
// points that are closest to the edge points
|
||||
let p1 = (p0.x + dx1, p0.y + dy1)
|
||||
let p5 = (p6.x + dx2, p6.y + dy2)
|
||||
let p1 = (p0.x + dx1, p0.y + dy1, 0)
|
||||
let p5 = (p6.x + dx2, p6.y + dy2, 0)
|
||||
|
||||
|
||||
// middle point
|
||||
let center_x = p0.x + box_width * center_horizontal / 100%
|
||||
let center_y = p0.y + box_height * center_vertical / 100%
|
||||
let p3 = (center_x, center_y)
|
||||
let p3 = (center_x, center_y, 0)
|
||||
|
||||
// setting up the points for that touch the guides
|
||||
let p2 = (0,0)
|
||||
let p4 = (0,0)
|
||||
let p2 = (0, 0, 0)
|
||||
let p4 = (0, 0, 0)
|
||||
if side-start in ("north", "south") {
|
||||
p2 = (horizontal: p3, vertical: p1)
|
||||
} else {
|
||||
@@ -240,6 +240,9 @@
|
||||
if pts.len() != 2 {
|
||||
panic("Wrong number of points (got " + str(pts.len()) + " instead of 2)")
|
||||
}
|
||||
|
||||
// Normalize user-provided coordinates: (x, y) -> (x, y, 0)
|
||||
let pts = pts.map(normalize-coord)
|
||||
|
||||
let stroke = (
|
||||
paint: color,
|
||||
|
||||