CeTZ Integration
Fletcher aims to be compatible with CeTZ, in the sense that you can use as little or as much of fletcher’s features with CeTZ as you want, and vice versa. Under the hood, fletcher builds upon CeTZ by defining:
flexigrid(), which defines a coordinate system for table-like layouts within a CeTZ canvas;node()for placing content which influences the layout of an enclosingflexigrid();edge()for drawing paths with convenient styling options including automatic snapping, arrow marks, multistroke effects, corner rounding, and label placement;diagram(), which is simplyflexigrid()wrapped in a CeTZ canvas with styling shortcuts.
Drawing in a CeTZ canvas
Instead of using diagram(), you can place nodes and edges directly inside a CeTZ canvas. If you still want to use tabular layouts like in diagram(), you can wrap the objects in a flexigrid(). For example, the following are equivalent:
Using diagram() | Using cetz.canvas() |
| |
Drawing inside a CeTZ canvas is encouraged when your diagram does not have a natural table-like structure or is very complex. However, some features only work inside diagram() or flexigrid() (for example, in a cetz.canvas() edges cannot snap to nodes declared later).
Normal CeTZ objects may be placed in a flexigrid(), but must opt-in to use coordinates with (uv: coord), while nodes and edges use coordinates by default (you can use (xy: coord) to opt-out). Nodes and edges can be given names and participate in CeTZ’s anchoring system.
Applying edge effects to CeTZ paths
You can wrap a CeTZ path in edge() to apply edge effects to it (see Wrapping CeTZ paths). Using edge() in this way is a convenient wrapper to the path modification functions offered by fletcher, which includes path-effect() for applying corner rounding (for edge.corner-radius) and offsetting (for edge.extrude) to CeTZ paths, and apply-edge-effects() for placing marks and labels.
#cetz.canvas({
import cetz.draw: *
let path = line((0,0), (1,0), (2,1), (2,0), (3,0), stroke: 0.5pt)
path // plain cetz path
translate(y: -2)
edge(path, ")==>", text(blue)[_effects_], stroke: 1pt + blue)
})Snapping edges to CeTZ objects
You can use edge() to enable path snapping. You can make edges snap to nodes or plain CeTZ objects using the edge.snap-to option and providing a name. You can also make plain CeTZ paths snap to objects by wrapping them in edge().
#cetz.canvas({
import cetz.draw: *
// plain cetz objects with names
line((0,0), (1,1), (2,0), (1,-1), close: true, name: "l")
circle((3,0), radius: 0.3, name: "c")
set-style(edge: (stroke: 1pt + eastern)) // styles applied edge(..)
// fletcher edge snapping to cetz objects
edge((1,0), "-->", (3,0), bend: -40deg, snap-to: ("l", "c"))
// making a cetz path snap to cetz objects
let path = line((1,0), (1,2), (3,2), (3,0))
edge(path, "<=", snap-to: ("l", "c"))
})