Custom marks
It would be nice to move Fletcher's custom marks code to Cetz and have it here instead so that all Cetz and Fletcher code can use it.
I will look into copying fletchers marks into cetz.
@johannes-wolf Thank you! But I don't mean copying their marks. I mean copying ideas from their custom mark system.
This is what I have in Fletcher and it works beautifully:
#let add-custom-fletcher-marks() = fletcher.MARKS.update(m => (
m
+ (
"square-fork": (
draw: mark => fletcher.cetz.draw.line(
(0, 0),
(4, 2),
(-4, 2),
(-4, -2),
(4, -2),
stroke: 0pt,
close: true,
),
fill: auto,
tip-origin: 4,
tail-origin: -4,
tip-end: -1,
tail-end: -1,
),
"chevron": (
draw: mark => fletcher.cetz.draw.line(
(0, 0),
(4, 2),
(0, 2),
(-4, 0),
(0, -2),
(4, -2),
stroke: 0pt,
close: true,
),
fill: auto,
tip-origin: 4,
tail-origin: -4,
tip-end: -1,
tail-end: -1,
),
"diamond": (
draw: mark => fletcher.cetz.draw.line(
(4, 0),
(0, 2),
(-4, 0),
(0, -2),
stroke: 0pt,
close: true,
),
),
"semicircle": (
draw: mark => fletcher.cetz.draw.arc(
(0, -4),
start: -90deg,
stop: 90deg,
radius: 4,
stroke: 0pt,
mode: "PIE",
),
fill: auto,
tip-origin: 4,
tip-end: 2,
tail-end: 2,
),
)
))
I just learned from you about register-mark. Thank you for sharing that! It's not in the manual, but it looks like it is pretty close to Fletcher's system.
It may be nice to add:
- Fletcher's ability to easily reverse marks, and
- Fletcher's tip debugging functions (shows a blown-up image of the tip with lines showing where the marks start and end). You probably also don't need y-coordinates for tip-end, etc.
It might also be nice to copy Latex's more beautiful bezier version of stealth (left) compared with cetz's (right):
How do I create a reversed version of a custom mark? And what if I just want an alias? E.g.,
#let add-arch-marks() = fletcher.MARKS.update(m => (
m
+ (
"arrow-a": (inherit: "latex", fill: auto), // Alias
"arrow-b": (inherit: "square-fork", fill: auto, rev: true), // Reversed
)
))
Nicer stealth:
#let mark-scale = 0.07
#let stealthy-a = 0.4
#let stealthy-b = 0.1
#register-mark("stealthy", style => {
scale(mark-scale)
merge-path(
fill: style.stroke.paint,
stroke: (thickness: 1pt, join: "round"),
close: true,
{
bezier(
(2, 0),
(-1, 1),
(0, stealthy-a),
stroke: none,
)
bezier(
(-1, 1),
(-1, -1),
(-stealthy-b, 0),
stroke: none,
)
bezier(
(-1, -1),
(2, 0),
(0, -stealthy-a),
stroke: none,
)
}
)
anchor("tip", (2, 0))
anchor("base", (0, 0))
})
How do I create a reversed version of a custom mark? And what if I just want an alias? E.g.,
#let add-arch-marks() = fletcher.MARKS.update(m => ( m + ( "arrow-a": (inherit: "latex", fill: auto), // Alias "arrow-b": (inherit: "square-fork", fill: auto, rev: true), // Reversed ) ))
Cetz auto-reverses the mark for you, if you pass ..., reverse: true.
Example:
#cetz.canvas({
import cetz.draw: *
register-mark("~", ctx => {
scale(15%)
merge-path({
line((0, -1), (0, 1))
arc((), start: 90deg, delta: -180deg, radius: 1)
}, close: true)
anchor("tip", (1, 0))
anchor("base", (0, 0))
})
line((0,0), (1,0), mark: (end: (symbol: "~", reverse: true), start: "~"))
})
Gives:
I know that we need a "reversed-tip" and "reversed-base" anchor to make this more flexible.h Also a per-symbol style would be nice, as some marks should be wider by default etc.