astoff / tikz-cd

Commutative diagrams with TikZ
45 stars 3 forks source link

"Nesting" tikz-cd matrices #12

Closed tobiasBora closed 2 years ago

tobiasBora commented 2 years ago

First, thanks a lot for this great library. I recently designed a library to typeset ZX-calculus on top of tikz-cd, and sometimes I would like to "nest" tikz-cd matrices, or, more precisely, to add at the end of the figure drawing a tikz-cd drawing (using the fit library) on top of an existing matrix. However, when I try that I get an error.

To illustrate my need, here is a simple example. The following code:

\begin{ZX}
  \zxX{} \rar \ar[r,o'] \ar[r,o.] & \zxZ{}
\end{ZX}

produces this picture: image

If I insert below some stuff, like that:

\begin{ZX}[math baseline=myb]
                     &[\zxwCol] \zxFracX-{\pi}{2}    & \zxX{} \rar \ar[r,o'] \ar[r,o.] & \zxZ{} &[\zxwCol]\\
  \zxN[a=myb]{} \rar &         \zxFracZ{\pi}{2} \rar & \zxFracX{\pi}{2} \rar           & \zxFracZ{\pi}{2} \rar & \zxN{}
\end{ZX}\\

then I get this picture: image

As you can see the initial drawing is now much wider, because of the nodes below. So I tried to include the first drawing in the second like that, but unfortunately it fails:

\begin{ZX}[
  execute at end picture={
    \node[fit=(start)(end)]
    {\zx{\zxX{} \rar \ar[r,o'] \ar[r,o.] & \zxZ{} &[\zxwCol]}};
  },
  math baseline=myb]
                     &[\zxwCol] \zxFracX-{\pi}{2} & \zxN[a=start]{}       & \zxN[a=end]\\
  \zxN[a=myb]{} \rar & \zxFracZ{\pi}{2} \rar      & \zxFracX{\pi}{2} \rar & \zxFracZ{\pi}{2} \rar & \zxN{}
\end{ZX}\\

the error I get is ! Package tikz-cd Error: Diagrams cannot be nested..

A first solution I found is to save the box before the drawing like that:

\newsavebox{\myZXbox}
\sbox{\myZXbox}{\zx[ampersand replacement=\&]{\zxX{} \rar \ar[r,o'] \ar[r,o.] \& \zxZ{}}}

\begin{ZX}[
  execute at end picture={
    \node[fit=(start)(end),yshift=-axis_height]
    {\usebox{\myZXbox}};
  },
  math baseline=myb]
                     &[\zxwCol] \zxFracX-{\pi}{2} & \zxN[a=start]{}       & \zxN[a=end]\\
  \zxN[a=myb]{} \rar & \zxFracZ{\pi}{2} \rar      & \zxFracX{\pi}{2} \rar & \zxFracZ{\pi}{2} \rar & \zxN{}
\end{ZX}

and I get the expected result:

image

This is better than nothing, but it is not really practical since I need to create the box before the matrix: therefore I can't create a command inside the matrix that will automatically add this code at the end. The following code indeed fails:

\begin{ZX}[
  execute at end picture={
    \node[fit=(start)(end),draw,yshift=-axis_height] {\sbox{\myZXboxA}{\zx[ampersand replacement=\&]{\zxX{} \rar \ar[r,o'] \ar[r,o.] \& \zxZ{}}}\usebox{\myZXboxA}};
  },
  math baseline=myb]
                     &[\zxwCol] \zxFracX-{\pi}{2} & \zxN[a=start]{}       & \zxN[a=end]\\
  \zxN[a=myb]{} \rar & \zxFracZ{\pi}{2} \rar      & \zxFracX{\pi}{2} \rar & \zxFracZ{\pi}{2} \rar & \zxN{}
\end{ZX}\\

Do you have any solution?

By the way, I'd love also a way to merge columns, it would be more robust to overlays than using the fit library. But I think it's quite hard to get.

astoff commented 2 years ago

The nesting restriction actually comes from PGF matrices (the error message is quite hopeful: "You cannot nest pgfmatrix environments, yet", but it's 15 years old).

Same for merging columns: if this was available from PGF/TikZ, then it would be immediately avaiable in tikz-cd.

tobiasBora commented 2 years ago

Ok thanks for your help. I was thinking that execute at end picture could escape this nesting issue, but I'll continue to use my method then. Thanks!