Challenge: create support for commutative diagram

After fews days online Typst has already some commutative diagram macros, see: https://gitlab.com/giacomogallina/typst-cd It could be a good exercise to write an analogous function for TeXmacs. One could for example implement a scheme macro which take a scheme expression that describe the diagram and produce a graph out of it. I believe we already have enough functionality to support this. It would also be nice to have nicer arrows, like those in that package.

1 Like

I looked briefly at https://gitlab.com/giacomogallina/typst-cd/-/blob/main/example.typ

and it seems to me that the syntax

#align(center)[#commutative_diagram(
  node((0, 0), [$X$]),
  node((0, 1), [$Y$]),
  node((1, 0), [$X \/ "ker"(f)$]),
  arr((0, 0), (0, 1), [$f$], label_pos: -1em),
  arr((1, 0), (0, 1), [$tilde(f)$]),
  arr((0, 0), (1, 0), [$pi$]),
)]

for a diagram might be adapted quickly, maybe with the help of a macro, to TeXmacs’ Scheme graphics.
Given that one can do this https://texmacs.github.io/notes/docs/modular-scheme-graphics.html :wink:

I don’t know how to do nicer arrows. Anyone has ideas?

On the other hand I think that TeXmacs needs to link on its home page https://github.com/texmacs/tm-forge; probably also needs something a bit more flexible because I find only an easy way to download all of tm-forge (git clone) but not individual packages. I think that having a place where users (including new users) can reliably and simply download extensions and can also contribute—this without having to be involved with the whole project and without having their work strongly filtered, id est with minimal moderation—would help TeXmacs a lot. Also a topic of discussion for a next possible Jolly Coders meeting IMHO.

This was an intentional choice. It is small enough that there is no advantage really to just download 1 or 2 packages. If it grows things may change. The burden to have an overly complicated package manager is not justified at the moment. I try to keep things simple.

What sort of graph would you like to produce? The coordinates of “Technical graphs” in TeXmacs are absolute, and I am not a fan of that approach. I think that it is possible to simply extend tabulars to support diagrams in TeXmacs.

1 Like

I’m not sure, one would need a way to tag certain positions in the document and retrieve their coordinates to have a graph. While not optimal, anything which allow to make relatively non-trivial commutative diagrams would be useful. At the moment there is no good solution. Alternatively one could extend the graph editor to have functionalities like https://q.uiver.app But again, a lot of talking and no code is like no talking :slight_smile:

1 Like

Absolute with respect to the centre of the graph in my recalling. I think you can re-define the coordinates as (* relative-coordinate graph-size) (I am pretending this is Scheme code).

The link to tm-forge from www.texmacs.org would still be nice. But the whole discussion is probably best for a Jolly Coders meeting.

I mean, just put these nodes into cells of a tabular, and allow arrows to be added between cells. An algorithm is needed to determine how the cells are stretched. I am not sure whether this is implementable via scheme codes.

More precisely, in the second example, we start with the tabular

<tformat|<table|<row|<cell|\<pi\><rsub|1><around*|(|X\<cap\>Y|)>>|<cell|\<pi\><rsub|1><around*|(|Y|)>>|<cell|>>|<row|<cell|\<pi\><rsub|1><around*|(|X|)>>|<cell|\<pi\><rsub|1><around*|(|Y|)>\<ast\><rsub|\<pi\><rsub|1><around*|(|X\<cap\>Y|)>>\<pi\><rsub|1><around*|(|X|)>>|<cell|>>|<row|<cell|>|<cell|>|<cell|\<pi\><rsub|1><around*|(|X\<cup\>Y|)>>>>>

Then we specify the remaining arrows. I am not sure how to interact with TeXmacs typesetting algorithms appropriately to have good spaces between these nodes.

1 Like

This is the approach of https://q.uiver.app

1 Like

An image instead of code :wink: ; made with Scheme graphics.

It took a bit of time to set-up the functions, but after that it is quicker to use them. Recurringly, I get slowed down because I forget which functions I defined, so I stopped using the functions :slight_smile:

I think I need (I am telling this to myself)

  • a good way of documenting the available functions so that they are easy to pickup after three months I am not using them
  • improvement of the syntax I am using; perhaps with some macros.

Here is the code that generates that image; I do not include any of the supporting code, it is just to give the idea. Also, comments are notes that I took when testing; if they are confusing it is because I was confused myself.

(define k-1 (phasor 0 1 'color "grey"))
(define k-2  (phasor 90 1 'color "grey"))
(define k-2-refl (phasor -90 0.7 'color "red" 'dash-style "11100"))
(define k-1-mark-text
  '(math
    (concat "k" (rsub "1") "<||>"
	    (with color "red"
	      (concat "k" (rsub "1, trans"))))))
(define k-2-mark-text
  '(math 
    (concat "k" (rsub "2"))))

(define k-2-refl-mark-text
  `(with color "red"
     (math 
      (concat "k" (rsub "2,refl")))))

(define k-1-mark (mark-line k-1 k-1-mark-text 1))
(define k-2-mark (mark-line k-2 k-2-mark-text 1))
;; 2021-03-09 it seems to complete the drawing, adding the red dashed arc,
;; which is later in the scheme-graphics list, even if k-2-mark is defined
;; "recursively" writing k-2-mark instead of k-2-mark-text; the terminal does
;; not report any error.

;; I do not know how but TeXmacs retained a previous definition of k-2-mark;
;; the mark text was placed in a position such that I did not notice it
;; immediately. Restarting TeXmacs made the command with k-2-mark fail with
;; "unbound variable", as it should

;; As observed in another case as well (same day 2021-03-09) a variable defined
;; through mark-line is a valid input for the txt argument of mark-line; the
;; positioning is quite off with respect to the positioning of "bare text" one
;; sets with the positioning input to mark-line To investigate this, one should
;; experiment with placing "text-at" markup in the text argument of text-at
;; markup (since the output of mark-line is a "text-at" markup)
(define k-2-refl-mark (mark-line k-2-refl k-2-refl-mark-text .7 .6))

(define scheme-drawing
  (scheme-graphics "8cm" "6cm" "center"
		   `((point 0 0)
		     ,(mark '(point "0" "0") "O" "SE")
		     ,k-1
		     ,k-2
		     ,k-2-refl
		     ,k-1-mark
		     ,k-2-refl-mark
		     ,k-2-mark
		     (with arrow-end "<gtr>" 
		       color "red" dash-style "11100"
		       ,(arc-polar '(0 0) 1 90 270))
		     )))


Finally, @re4zuaFe, Scheme is fun :slight_smile:

2 Likes

Sorry, this is different from what I imagine. I mean, I am thinking of commutative diagrams, and I wonder whether it is possible to write up some scheme codes to intervene the typesetting algorithms in TeXmacs, so that the user do not have to concern about the coordinates of each node. I think that the commutative diagrams in these examples explain well.

1 Like

Well, those are produced starting from node coordinates: https://gitlab.com/giacomogallina/typst-cd/-/blob/main/example.typ

But I think I know what you mean. As a first step, I would see if it is possible to create a “diagram node” entity in a TeXmacs drawing such that the entity has only a few points, somewhat distant from it, at which arrow ends can snap. If I find out anything I’ll report.

I do not think automatic placement is what you want. Parametric drawings. I guess you need to leave the user the choice on where to put vertices and which arrow to have and then the system should compute the precise location of the start/end of the arrows, etc… But again, this would require a lot of complex decisions which is not clear which criterion to use. It is just a diagram after all. All the user need is a fast way to produce a lot of similar diagrams. I’m fine with the approach of q.uiver.app : a grid where to place the vertices and arrows defined by some parameters. If you have rapid visual feedback things are fine. Our graphic editor has already much of the functionality but you would like to have a larger grid for a solid placement of the vertices and an easier way to parametric arrows and to choose their starting/ending points attached to some label, so that if one move the label, then also the arrows are moved.

Current TeXmacs arrows are UGLY. We deserve better arrows. Otherwise they are essentially useless.

2 Likes

I exactly take advantage of automatic placement (and so are all examples). Currently, I am using the Graph plugin with XYpic to do this. It basically satisfies my needs, but it is ugly, with very few source-code interaction with TeXmacs, and would lead to extremely large tm files (since compiled binary images are embedded), and a recompilation might lead to a different binary image which will mislead versioning tools.

Many of these sort of diagrams could be mimicked by tabulars, and this is why I would see it as an extension of tabulars. However, the mimic is ugly. For example:

<\equation*>
  <tabular*|<tformat|<table|<row|<cell|Hom<rsub|\<cal-C\>><around*|(|X,<big|oplus><rsub|i>Y<rsub|i>|)>>|<cell|\<longrightarrow\>>|<cell|Hom<rsub|\<cal-D\>><around*|(|F<around*|(|X|)>,F<around*|(|<big|oplus><rsub|i>Y<rsub|i>|)>|)>>>|<row|<cell|\<longdownarrow\>>|<cell|>|<cell|\<longdownarrow\>>>|<row|<cell|G<around*|(|Y|)>>|<cell|\<longrightarrow\>>|<cell|H<around*|(|Y|)>>>>>>
</equation*>

and

<\equation*>
  <tabular*|<tformat|<cwith|1|1|2|2|cell-row-span|1>|<cwith|1|1|2|2|cell-col-span|3>|<table|<row|<cell|A>|<cell|\<longrightarrow\>>|<cell|>|<cell|>|<cell|C>>|<row|<cell|\<longdownarrow\>>|<cell|>|<cell|>|<cell|>|<cell|\<longdownarrow\>>>|<row|<cell|B>|<cell|\<longrightarrow\>>|<cell|R>|<cell|\<longrightarrow\>>|<cell|D>>>>>
</equation*>
1 Like

I do not think this would work. Vertices are on a grid, but arrows can jump arbitrarily far, so they cannot be represented faithfully as cells of a table. Arrows are edges, so they are associated to pairs of vertices. I’m not sure also what you mean by automatic placement: in the example cited the vertices are manually placed in a grid, the automatic placement takes place for the start/end points of arrows, and I agree this can be done by a computer. However the bending of the arrows is matter of style and visual result and I think should be allowed to be hinted by the human, so you need a way to associate attributes to the arrows (+ labels). I do not see how you can do substantially better than something like

#align(center)[#commutative_diagram(width: 300pt, height: 200pt,
  node((0, 0), [$pi_1(X sect Y)$]),
  node((0, 1), [$pi_1(Y)$]),
  node((1, 0), [$pi_1(X)$]),
  node((1, 1), [$pi_1(Y) ast.op_(pi_1(X sect Y)) pi_1(X)$]),
  arr((0, 0), (0, 1), [$i_1$], label_pos: -1em, "inj"),
  arr((0, 0), (1, 0), [$i_2$], "inj"),
  arr((1, 0), (2, 2), [$j_1$], curve: -15deg, "surj"),
  arr((0, 1), (2, 2), [$j_2$], label_pos: -1em, curve: 20deg, "def"),
  arr((1, 1), (2, 2), [$k$], label_pos: 0, "dashed", "bij"),
  arr((1, 0), (1, 1), [], "dashed", "inj", "surj"),
  arr((0, 1), (1, 1), [], "dashed", "inj"),
  node((2, 2), [$pi_1(X union Y)$])
)]

What we can offer more than that is that labels can be edited directly in the resulting graph.

Thanks. I mistakenly thought that the spaces are variable, but after looking at those tools, it seems that the vertical and horizontal spaces are fixed respectively, and only the heads and tails of arrows are adapted.

However, realizing diagrams as tables seems to make this possible: such a table could be associated with values of “horizontal distance” and “vertical distance”, which indicates the distances between cells. For example, the distances for normal tables are zero.

I did not mean to represent arrows as cells of a table in general (the two mimics are indeed so).

I also suffer from editing source code inside TeXmacs, here is a solution:

(delayed (lazy-keyboard-force)
  (kbd-map
   (:mode in-prog?)
   ("A-c E" (let ((fn (url-glue (url-temp) ".code")) ;; TODO: add extension name
                  (snippet (tree-search-upwards (cursor-tree) 'document)))
              (tree-export snippet fn "verbatim")
              (system-1 "emacsclient -a 'nvim-qt --nofork' " fn)
              (let ((t (tree-ref (tree-import fn "verbatim") 0 0)))
                (tree-set snippet t)
                ;; without return and backspace, you cannot edit the same snippet twice
                (kbd-return)
                (kbd-backspace))))
   ))

Replace the editor if you want.

Are there any updates on the development of commutative diagram support in TeXmacs? I’m a big fan of TeXmacs, but the lack of adequate support for commutative diagrams (such as tikz-cd in LaTeX) is preventing me from using it on a daily basis instead of org-mode or plain LaTeX.