In my attempt to make my library zx-calculus based on tikz & tikzcd compatible with tikz externalize (to save compilation time), I've basically been using this solution https://tex.stackexchange.com/a/362104/116348 except that I wrap my own library inside it instead of tikzcd.
It works fine so far, but this solution defines globally:
\def\temp{&} \catcode`&=\active \let&=\temp
otherwise the compilation does not treat the & symbol correctly.
I have to admit that I don't fully understand how this lines works (I would be curious if you could let me know), however I'm worried that the changes are global to the whole file. I remember having issues with quantikz that redefine this very same symbol globally (maybe for that reason) and that creates errors when using other packages like tabularray.
Is there any solution to redefine this locally? I tried to move it inside the \mytikzcdcontext function, but without much success.
MWE:
\documentclass{article}
\usepackage{tikz, environ, etoolbox}
\usetikzlibrary{cd, external}
\tikzexternalize
% activate the following such that you can check the macro expansion in
% *-figure0.md5 manually
%\tikzset{external/up to date check=diff}
%%% How to avoid redefining this globally?
\def\temp{&} \catcode`&=\active \let&=\temp
\newcommand{\mytikzcdcontext}[2]{
\begin{tikzpicture}[baseline=(maintikzcdnode.base)]
\node (maintikzcdnode) [inner sep=0, outer sep=0] {\begin{tikzcd}[#2]
#1
\end{tikzcd}};
\end{tikzpicture}}
\NewEnviron{mytikzcd}[1][]{%
% In the following, we need \BODY to expanded before \mytikzcdcontext
% such that the md5 function gets the tikzcd content with \BODY expanded.
% Howerver, expand it only once, because the \tikz-macros aren't
% defined at this point yet. The same thing holds for the arguments to
% the tikzcd-environment.
\def\myargs{#1}%
\edef\mydiagram{\noexpand\mytikzcdcontext{\expandonce\BODY}{\expandonce\myargs}}%
\mydiagram%
}
\begin{document}
\begin{equation}
\begin{mytikzcd}[row sep=huge,baseline = (B.base)]
A \arrow[rd] \arrow[r, "\varphi"] & |[alias=B]| B \ & C
\end{mytikzcd}
\hbox{sharing a baseline with } B
\end{equation}
\end{document}
For references, here is what I've been trying to do with my library:
\documentclass[options]{article}
\usepackage{tikz}
\makeatletter
%%% Download this at https://github.com/leo-colisson/zx-calculus
\input{tikzlibraryzx-calculus.code.tex}
\makeatother
\usetikzlibrary{external}
\tikzexternalize % activate!
\NewExpandableDocumentCommand\zxE{O{}m}{
\begin{tikzpicture}[baseline=(tmpdirty.base)]
\nodeinner sep=0pt,outer sep=0pt{\begin{ZX}[#1]
#2
\end{ZX}};
\end{tikzpicture}
}
%% Use myZXE instead, this fails in math environment, no idea why.
\NewDocumentEnvironment{ZXE}{O{}+b}{%
\def\myargs{#1}%
\def\mybody{#2}%
\edef\mydiagram{\noexpand\zxE[\expandonce\myargs]{\expandonce\mybody}}%
\mydiagram%
}
\usepackage{environ}
\NewEnviron{myZXE}[1][]{%
% In the following, we need \BODY to expanded before \mytikzcdcontext
% such that the md5 function gets the tikzcd content with \BODY expanded.
% Howerver, expand it only once, because the \tikz-macros aren't
% defined at this point yet. The same thing holds for the arguments to
% the tikzcd-environment.
\def\myargs{#1}%
\edef\mydiagram{\noexpand\zxE[\expandonce\myargs]{\expandonce\BODY}}%
\mydiagram%
}
\NewDocumentEnvironment{myZXEw}{}{%
\bgroup%
\def\temp{&} \catcode`&=\active \let&=\temp%
\begin{myZXE}%
}{%
\end{myZXE}%
\egroup
}
\begin{document}
%% Redefine locally?
\def\temp{&} \catcode`&=\active \let&=\temp%
Works:
$x = \zxE[math baseline=kk]{
\zxX{\alpha} & \zxZ{\beta}\
\zxZ[a=kk]{}
}$.
Works:
$x = $\begin{ZXE}[math baseline=kk]
\zxX[a=kk]{\epsilon} & \zxX{\epsilon}\
\zxZ{abcd}
\end{ZXE}
% % Fails:
% $x = \begin{ZXE}[math baseline=kk]
% \zxX[a=kk]{\epsilon}\
% \zxZ{}
% \end{ZXE}$
Works:
$x = \begin{myZXEw}[math baseline=kk]
\zxX[a=kk]{\delta} & \zxZ{\alpha}\
\zxZ{}
\end{myZXE}$
\end{document}

\NewExpandableDocumentCommand\zxEisn't going to be expandable since it is atikzpictureAlso why use the (ancient)environ\NewEnvironform when you are already using theboption from\NewDocumentEnvironmentwhich does the same thing, but better? – David Carlisle Feb 04 '22 at 09:46\NewEnviron, this is visible in my second MWE: I have no idea why butNewDocumentEnvironmentfails in the math environment in my precise example (see the commented "fail" part). If you know what's wrong I'm curious to know. – tobiasBora Feb 04 '22 at 10:05