0

Is there a simple way of making nested and boxed sub-diagrams using the tikz-cd package?

For example (from Lawvere and Schanuel, Conceptual Mathematics):

Commutative diagram

I currently use the following environment to create boxed commutative diagrams, which works nicely:

\newenvironment{tikzcdb}
                     {\begin{lrbox}{\tikzcdbox}\begin{tikzcd}}
                     {\end{tikzcd}\end{lrbox}\fbox{\usebox{\tikzcdbox}}}
\newsavebox{\tikzcdbox}

I can't figure out how to do the nesting though, and then do nesting AND boxing.

1 Answers1

1

I hope this is helpful, it will depend on the kind of diagrams you need to do.

  1. We patch the tikzcd environment so that it detects when it is used inside a tikzpicture
  2. and add a few forwarded keys up so that the tikzcd environment acts as much as a normal TikZ \matrix as it can.
  3. The combination of between origins, overlayed TikZ labels and a custom padding for each TikZ-CD matrix make sure the boxes (i.e. the drawn matrices) have the same size. Of course, for this, all dots need to be the same size.
  4. The cd arrow key emulates as easy as possible TikZ-CD's own \ar(row) command.

Code

\documentclass{article}
\usepackage{tikz} \usetikzlibrary{cd, positioning, quotes}
\makeatletter
\tikzcdset{
  /utils/temp/.initial/.expand once=\tikzcd,
  /utils/temp/.prefix=\ifx\path\tikz@command@path\let\tikzpicture\scope\let\endtikzpicture\endscope\fi,
  /utils/temp/.get=\tikzcd,
  enable tikzcd quotes/.code=%
    \pgfkeyssetvalue{/handlers/first char syntax/\expandafter\meaning\string"}{\tikz@quote@parser}%
    \def\tikz@quotes@as##1##2{matrices={label={[direction shorthands,##2]##1}}},
  forwarded keys/.style={% the \pgfkeyslet stuff makes sure the keys work normal in an arrow label
    #1/.style={matrices={/tikz/#1={##1}}},
    every label/.append code=\pgfkeyslet{/tikz/commutative diagrams/#1/.@cmd}\pgfutil@undefined}}
\makeatother
\tikzcdset{
  forwarded keys/.list={below, left, right, above, name, anchor, matrix anchor},
  matrices/.style={every matrix/.append style={#1}},
  padding/.style args={#1:#2}{
    matrices={inner xsep={(#1)*1ex}, inner ysep={(#2)*1ex}}},
  tight/.style={inner sep=+.25ex}}
\tikzset{
  Dot Diagram/.code=%
    \tikzcdset{
      tikzcd to/.tip={Stealth[scale width=.75, inset=+.75pt +.5]}, % arrow tip
      matrices={draw, outer sep=+.5ex},
      diagrams={% between origins + overlay labels + padding makes it
                % easy to create matrices that have same dimensions
        enable tikzcd quotes,
        row sep={3em,between origins}, column sep={5em,between origins},
        /tikz/every label/.style={% the labels on matrices
          path only, math nodes, shape=asymmetrical rectangle,
          inner sep=+0pt, outer sep=+0pt},
        cells={
          /tikz/label distance=+-1ex, % because of outer sep=.5ex
          /tikz/every label/.style={% we need to reset all dot settings
            shape=rectangle, path only, overlay,
            commutative diagrams/every label},
          nodes={% these are our dots
            shape=circle, fill, inner sep=+0pt,
            outer sep=+.5ex, minimum size=+.7ex}}}},
  math nodes/.style={execute at begin node=$, execute at end node=$},
  cd arrow/.style={% a very simple TikZ-CD's \arrow implementation
    every edge/.append style={
      nodes={math nodes, commutative diagrams/every label},
      commutative diagrams/every arrow}}}
\begin{document}
\[
\begin{tikzpicture}[Dot Diagram, node distance=1.5em]
\begin{tikzcd}[name=aa,              "{{}=A^2}" right, padding=3:3.1]
  |["{(s, t)}"]|                                 & |["{(t, t)}"]| \\
  |["{(s, s)}" below]| \ar[ur, "{(a, a)}" tight] & |["{(t, s)}" below]|
\end{tikzcd}

\begin{tikzcd}[name=da, below=of aa, "{{}=A}" right, padding=3:1.7] |["s" left]| \ar[r, "a"] & |["t" right]| \end{tikzcd}

\begin{tikzcd}[name=la, left =of aa, "{A={}}" left, padding=1.7:3.1] |["t"]| \ |["s" below]| \ar[u, "a"] \end{tikzcd} % a very simple TikZ-CD's \arrow implementation \path[cd arrow] (aa) edge["p_1"] (da) edge["p_2"] (la); \end{tikzpicture} ] \end{document}

Output

enter image description here

Qrrbrbirlbel
  • 119,821
  • Thank you very much for this. I don't actually need the dots in the diagrams, I just want to use standard tikz-cd commutative diagrams with boxes around them and using, e.g. (s,s) for the nodes. I tried to edit your code to remove the dots, but failed. – Sharanjit Sep 26 '23 at 04:41