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:
- First
tikzpicture externalized.
- Second
tikzpicture externalized.
- Main document with four TikZ pictures.
externalizelibrary documentation is clear: you can only externalizetikzpictureenvironments. Sincetikzcdinternally calls\tikzpicture, the library gets confused and can't find the end of its job anyway. – egreg Jun 01 '19 at 11:15\matrixnode with appropriate options. – Symbol 1 Jun 02 '19 at 22:26