I am trying to finalize and clean up some code (see Lozenge tilings) and I canβt make sense of something. I am trying to set up the function:
#let plot_lozenge_tiling(
/// The lozenge tiling to plot, as returned by `compute_lozenge_coordinates(...)`.
/// -> array
tiling,
/// Fill colors for lozenge types 0, 1, and 2 respectively.
/// -> array
colors: (blue.lighten(30%), red.lighten(30%), green.lighten(30%)),
/// Whether to draw a border around each lozenge globally.
/// -> bool
border: true,
/// Stroke color for lozenge borders (when `border` is `true`).
/// -> color
border-color: black,
/// Stroke thickness for lozenge borders (when `border` is `true`).
/// -> length
border-width: 0.5pt,
/// Whether to render each lozenge's index (its position in `tiling`) at its center.
/// -> bool
show-index: false,
/// Text size for the index labels rendered when `show-index` is `true`.
/// -> length
index-size: 6pt,
/// Per-lozenge style overrides, keyed by lozenge index.
/// Keys may be integers or their string equivalents.
/// Each value is a dictionary accepting any subset of:
/// - `color` (color) β override fill color for this lozenge
/// - `border` (bool) β override border visibility for this lozenge
/// - `border-color` (color) β override border stroke color for this lozenge
/// - `border-width` (length) β override border stroke width for this lozenge
///
/// Example:
/// ```typst
/// overrides: (
/// "0": (color: red),
/// "3": (border: false),
/// "7": (color: yellow, border-color: orange, border-width: 1pt),
/// )
/// ```
/// -> dictionary
overrides: (:),
/// Debug level for the CetZ canvas.
/// -> bool
debug-stat: false,
/// Content to insert on the CetZ canvas after the lozenge tiling is drawn.
/// -> content
overlay: none,
) = {
cetz.canvas(debug: debug-stat, {
import cetz.draw: *
for (idx, lozenge) in tiling.enumerate(start: 0) {
let ltype = lozenge.at(0)
let verts = lozenge.at(1)
// ββ Resolve style, starting from global defaults βββββββββββββββββββββββ
let fill-color = colors.at(ltype)
let show-border = border
let s-color = border-color
let s-width = border-width
// ββ Apply per-lozenge overrides ββββββββββββββββββββββββββββββββββββββββ
// Typst stores integer dict keys as their string representation,
// so str(idx) matches both (0: ...) and ("0": ...) in the caller.
let ov-key = str(idx)
if ov-key in overrides {
let ov = overrides.at(ov-key)
if "color" in ov { fill-color = ov.at("color") }
if "border" in ov { show-border = ov.at("border") }
if "border-color" in ov { s-color = ov.at("border-color") }
if "border-width" in ov { s-width = ov.at("border-width") }
}
// ββ Build stroke value βββββββββββββββββββββββββββββββββββββββββββββββββ
let stroke-style = if show-border {
(paint: s-color, thickness: s-width)
} else {
none
}
// ββ Draw the lozenge as a closed quadrilateral βββββββββββββββββββββββββ
line(
verts.at(0),
verts.at(1),
verts.at(2),
verts.at(3),
close: true,
fill: fill-color,
stroke: stroke-style,
)
// ββ Optionally label each lozenge with its index βββββββββββββββββββββββ
if show-index {
// Geometric centroid = average of the four vertices
let cx = (verts.at(0).at(0) + verts.at(1).at(0) + verts.at(2).at(0) + verts.at(3).at(0)) / 4
let cy = (verts.at(0).at(1) + verts.at(1).at(1) + verts.at(2).at(1) + verts.at(3).at(1)) / 4
content(
(cx, cy),
text(size: index-size, str(idx)),
anchor: "center",
)
}
// Insert user-provided content on the canvas
if overlay != none { overlay }
}
})
}
importantly using the overlay parameter to allow users to insert their own content. However, if I try and test this with
#plot_lozenge_tiling(
test_2_coords,
border: true,
border-color: black,
border-width: 1.3pt,
colors: (lq.color.map.petroff10.at(0), lq.color.map.petroff10.at(1), lq.color.map.petroff10.at(3)),
debug-stat: false,
show-index: false,
overlay: {
circle((50*calc.cos(calc.pi/6), -25), radius: 50*calc.cos(calc.pi/6), stroke: 10pt)
}
)
I get the error expected length or auto, found float, so I can only assume Typst reverts to its own circle function. However, the overlay content is inserted after the import cetz.draw: * line, so I donβt know why the overlay content doesnβt inherit the namespace. Can anyone clarify whatβs going on?