4

I am trying to export tikz pictures using tikz-cd to pdf. In order to run the tikz-cd, I had to disable the external library as shown below

\documentclass{article}
\usepackage{amsfonts}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{braket}
\usepackage{graphicx}
\usepackage{subcaption}
\usepackage{hyperref}
\usepackage[dvipsnames]{xcolor}
\usepackage{amssymb}
\usepackage{dsfont}
\usepackage{verbatim}
\usepackage{amsmath,amscd}
\usepackage[all,cmtip]{xy}
\usepackage{multirow}
\usepackage{etoolbox,tikz}
\usetikzlibrary{decorations.pathmorphing}
\usetikzlibrary{cd}
\usetikzlibrary{external}
\tikzexternalize

 \AtBeginEnvironment{tikzcd}{\tikzexternaldisable}
 \AtEndEnvironment{tikzcd}{\tikzexternalenable}
\begin{document}

\begin{tikzcd}
 ABC \arrow[loop right, "x"]{} \arrow[loop left, "y"]{} \arrow[out=240, 
in=320, 
 loop] \arrow[out=220, in=300, loop,crossing over, "z" swap, pos=0.58] \\
\end{tikzcd}


\begin{tikzcd}
D \arrow[loop left]{} \arrow[d]{} \arrow[r]{} & AC \arrow[out=240, in=320, 
loop] 
\arrow[out=220, in=300, loop,crossing over]  \\
DB \arrow[out=240, in=320, loop] \arrow[out=220, in=300, loop,crossing over]  
& 
\\
\end{tikzcd}

\end{document}

and as mentioned here. I tried to use the other answers mentioned but they didn't work for me. How do I export each tikzcd picture to pdf separately?

user25957
  • 623
  • Just wondering here: what would be the benefit of externalizing tikz-CD diagrams? – daleif Jun 01 '19 at 06:20
  • 2
    The externalize library documentation is clear: you can only externalize tikzpicture environments. Since tikzcd internally calls \tikzpicture, the library gets confused and can't find the end of its job anyway. – egreg Jun 01 '19 at 11:15
  • tikzcd is not too far away from a tikzpicture. Eventually it sets up a \matrix node with appropriate options. – Symbol 1 Jun 02 '19 at 22:26
  • @daleif Some journals require to submit figure pdfs separately. And if you have many tikz-cd figures in your file, externalizing helps to export them to pdfs in one go. As of now, I am using standalone document class to make a pdf for each tikz-cd figure – user25957 Jun 06 '19 at 14:08
  • 1
    @egreg I guess another version of my question would be how to export multiple tikz-cd figures to separate pdfs in one run – user25957 Jun 06 '19 at 14:10

2 Answers2

2

The following solution only works when the proper LaTeX enviroments (i.e. \begin{tikzcd} and \end{tikzcd}) are used. Using \tikzcd … \endtikzcd will break externalizing or just not compile.
A solution that's a bit more sophisticated will be needed to cover all use-cases. (Though, since external only works with LaTeX in the first place there aren't many left, I believe.)


The external library needs \end{tikzpicture} to be on the input stream when \begin{tikzpicture} triggers the library's mechanisms.

I'd suggest adjusting the tikzcd environment so that it can be used inside a TikZ picture which doesn't interfere with the externalization process. This means you need

\begin{tikzpicture}
\begin{tikzcd}
…
\end{tikzcd}
\end{tikzpicture}

to externalize a CD. (This is also how it works with PGFPlots.)

In the code below I'm adding the necessary check to the \tikzcd macro (i.e. \begin{tikzcd}) which detects whether you're using the tikzcd environment inside of a tikzpicture by checking whether \path is TikZ' own \path.

If it is it will change the tikzpicture that is used inside tikzcd into a scope which will accepts the optional argument of tikzcd instead.

If you have used the tikzcd diagram outside of a tikzpicture (i.e. \path is not TikZ's \path) then it will disable the externalization for this diagram.

This will also break putting a nesting TikZ pictures but this is never a good idea to begin with.

However it allows to use multiple CDs in one TikZ picture. (Remember, these are just \matrixes. However you need to use

\begin{tikzcd}[every matrix/.append style={…}]

to change the option to the \matrix (e.g. the name or any placements). It'd probably help to define a shortcut like

\tikzcdset{matrices/.style={every matrix/.append style={#1}}}

to make it more easier to change the style.


The \pgfkeys stuff is basically etoolbox's \preto but with on-board ressources of TikZ.

Code

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{cd,external}
\tikzexternalize
\makeatletter
\pgfkeys{
  /utils/temp/.initial/.expand once=\tikzcd,
  /utils/temp/.prefix=%
    \ifx\path\tikz@command@path % we're inside a tikzpicture
      \let\tikzpicture\scope
      \let\endtikzpicture\endscope
    \else % we're not inside a tikzpicture, disable externalizing
      \tikzexternaldisable
    \fi,
  /utils/temp/.get=\tikzcd}
\makeatother
\begin{document}
\begin{tikzpicture}
\begin{tikzcd}
 ABC \arrow[loop right, "x"]
     \arrow[loop left,  "y"]
     \arrow[out=240, in=320, loop]
     \arrow[out=220, in=300, loop, crossing over, "z" swap, pos=0.58] \\
\end{tikzcd}
\end{tikzpicture}

\begin{tikzpicture} \begin{tikzcd} D \arrow[loop left] \arrow[d] \arrow[r] & AC \arrow[out=240, in=320, loop] \arrow[out=220, in=300, loop, crossing over] \ DB \arrow[out=240, in=320, loop] \arrow[out=220, in=300, loop, crossing over] \end{tikzcd} \end{tikzpicture}

\begin{tikzcd} ABC \arrow[loop right, "x"] \arrow[loop left, "y"] \arrow[out=240, in=320, loop] \arrow[out=220, in=300, loop, crossing over, "z" swap, pos=0.58] \ \end{tikzcd}

\begin{tikzcd} D \arrow[loop left] \arrow[d] \arrow[r] & AC \arrow[out=240, in=320, loop] \arrow[out=220, in=300, loop, crossing over] \ DB \arrow[out=240, in=320, loop] \arrow[out=220, in=300, loop, crossing over] \end{tikzcd} \end{document}

Output

Three PDFs:

  1. First tikzpicture externalized.
  2. Second tikzpicture externalized.
  3. Main document with four TikZ pictures.
Qrrbrbirlbel
  • 119,821
2

Just to say that memoize can now externalise tikzcd, at least if you understand things better than I do and figure out the correct options. These are courtesy of memoize's author, Sašo Živanović.

\documentclass{article}
% addaswyd o gwestiwn user25957: https://tex.stackexchange.com/q/493622/
\usepackage{memoize}
\mmzset{%
  %   path={dir=memos}, % v. 1
  %   mkdir, % v. 1
  prefix=memos/, % v. 1.1 and later
  % Sašo Živanović: https://chat.stackexchange.com/transcript/message/64689784#64689784
  auto={tikzcd}{memoize,verbatim},
}
\usepackage{tikz-cd}
\begin{document}
\begin{tikzcd}
  ABC \arrow[loop right, "x"]{} \arrow[loop left, "y"]{} \arrow[out=240, 
  in=320, 
  loop] \arrow[out=220, in=300, loop,crossing over, "z" swap, pos=0.58] \\
\end{tikzcd}

\begin{tikzcd} D \arrow[loop left]{} \arrow[d]{} \arrow[r]{} & AC \arrow[out=240, in=320, loop] \arrow[out=220, in=300, loop,crossing over] \ DB \arrow[out=240, in=320, loop] \arrow[out=220, in=300, loop,crossing over]
& \ \end{tikzcd} \end{document}

memoized tikzcd diagrams

cfr
  • 198,882
  • 1
    path doesn't seem to be recognized anymore (using v1.2.0). Instead, use memo dir=<name>, which saves the files in <name>.memo.dir – red_trumpet Mar 27 '24 at 11:32
  • @red_trumpet Thanks. Actually, it should be prefix now. I'll update my answer. (I don't like dots in directory names except as the first character.) And mkdir is unnecessary. – cfr Mar 27 '24 at 15:53