Closed jaroeichler closed 5 months ago
It could very well be possible. So far, I haven't quite figured out a syntax that I think is expressive enough. But here are my current thoughts about it:
It would be nice to use a &
-aligned math environment for convenient syntax. There is one hacky way I think this could be done:
#let edge(..options) = metadata((kind: "edge", options: options))
#let eq = $
G edge("r", ->, f) edge("d", ->>, pi) & im(f) \
G slash ker(f) edge("ur", ->, tilde(f))
$
If you look at #eq.fields()
, you’ll see that the “dictionary-structs” that represent edges are accessible through the metadata elements, so it’s conceivable that this could be translated into an array of nodes and elements, like a normal diagram.
As yet, I’ve not allowed the use of the nodes’ content where a coordinate is expected, but since this is all in math-mode, it might make sense do to that. That would allow things like:
#fletcher.diagram($
A edge(A, C, bend: #50deg) & B & C
$)
// would be equivalent to:
#fletcher.diagram(
node((0,0), $A$),
node((0,1), $B$),
node((0,2), $B$),
edge((0,0), (0,2), bend: 50deg),
)
At least then you could form edges between non-adjacent nodes.
Overall, I’m a bit hesitant to make the notation too magical, but I think there’s still something there…
Maybe it's better to use matrix syntax then. At least, it's intended to be used for 2d arrays and should be easier to work with. Also, you should still be able to form edges between non-adjacent nodes
#fletcher.diagram(
A edge(rr, bend: #50deg), B, C;
)
Another option would be to at least write out rr
to (2, 0)
. This would be closer to the CeTZ sytax of line((), rel: (2, 0))
.
This matrix/align notation gets confusing for bigger diagrams though. So maybe it's better to stick to coordinates and shorten the notation there. But I don't think calling nodes by their content is a good idea. You often have maps $A \to A$ or objects that don't make a good variable name like $H^i(X, R)$.
These are good comments. I’ve had a go at making something like this on the tikz-style
branch I just added.
On that branch, you can do this:
#fletcher.diagram(axes: (ltr, ttb), $
G edge(f, ->) edge(#(0,1), pi, ->>) & im(f) \
G slash ker(f) edge(#(1,0), tilde(f), "hook'-->")
$)
instead of this:
#fletcher.diagram(axes: (ltr, ttb),
node((0,0), $G$),
edge((0,0), (1,0), $f$, "->"),
edge((0,0), (0,1), $pi$, "->>"),
node((1,0), $im(f)$),
node((0,1), $G slash ker(f)$),
edge((0,1), (1,0), $tilde(f)$, "hook'-->")
)
It’s still rough around the edges. (I might have to make axes: (ltr, ttb)
the default, instead of (ltr, btt)
.)
The changes I made were:
edge((x2, y2), ..opts)
as edge(from: auto, to: (x2, y2), ..opts)
, that is, if you specify one coordinate for an edge, that is interpreted as its tip, and its base is whatever node
coordinate was last specified.edge(..opts)
as edge(from: auto, to: auto, ..opts)
, where to
is the coordinate of the next node
specified. I’m not sure if this is best, because you could also say that to
is the coordinate of the previous node
, and from
the second-previous.sym.arrow
and friends as mark shorthands, to allow them to be written directly in math-mode like edge(->)
instead of as strings edge("->")
. For more complex arrows, you can always use a string.&
-separated equations to specify nodes on a grid.Things that are tricky:
r
as the most natural notation for (Δx, Δy) = (+1, 0)
. I don’t know exactly how that would work, since in math-mode edge(r, ..)
means #edge($r$, ..)
. It seems like a hack to whitelist some single-letter math variables and interpret them as coordinates. Especially if coordinates are optional, that could lead to ambiguity.r = (rel: (1, 0)), ru = (rel: (1, 1)), u = (rel: (0, 1)), ………
but that's a lot of namespace pollution. Might be better to just have edge("r", ..)
. But then edge("r", "o->")
would be hard to parse, with both arguments as strings. Etcetera. In the meantime, you have to use #(x, y)
.Features I’m aiming for:
diagram(for x in range(4) { edge((0,0), (x,1), "->") })
etc in code-mode, whereas math-mode just gives you a grid and less $
s.I welcome any ideas!
This is done in v0.4.0 😃
You can now do:
G edge("r", ->, f) edge("d", ->>, pi) & im(f) \
G slash ker(f) edge("ur", ->, tilde(f))
Instead of writing
I'd like
In tikzcd the nodes are put into a matrix environment. The arrows are paths from the current node with a given direction to the target node. Is it possible to do something similar here?