I am trying to set up a tikz matrix (actually, in this case, a tikz-cd) where I call different macros within the cells, which will determine the content that appears. This all works fine provided I don't have optional arguments on the macros. However, once I use optional arguments, the text that is supposed to define the node instead appears as text. How can I fix this?
Here's an MWE:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{cd}
\newcommand{\qw}{\arrow[dash,thick]{l}}
%hardcoded parameters
\newcommand{\hardmeter}[0]{|[operator,label={[yshift=0.1cm]above right:0}]| {} \qw}
\newcommand{\hardgate}[1]{|[operator,fill=blue]| #1 \qw}
%optional parameters
\newcommand{\optmeter}[1][a]{|[operator,label={[yshift=0.1cm]above right:#1}]| {} \qw}
\newcommand{\optgate}[2][a]{|[operator,#1]| #2 \qw}
\tikzcdset{nodes in empty cells,every matrix/.append style={name=m}} %fix name of matrix as m
\tikzset{
every node/.style={
anchor=center,minimum size=0pt,inner sep=0pt,outer sep=0pt,thick
},
operator/.style={draw,fill=white,minimum size=1.5em}
}
\begin{document}
What's supposed to happen: \\\\
\begin{tikzcd}
& \hardgate{H} & \hardmeter
\end{tikzcd}\\\\
What actually happens:\\
\begin{tikzcd}
& \optgate[fill=blue]{H} & \optmeter[0]
\end{tikzcd}
\end{document}
I'm sure this will have been asked before, but perhaps without knowing the solution/correct search term, I'm struggling to find it.
Update:
@egreg's solution works for the problem as specified. However, as soon as I make my macros more complex, it stops working. For example, if I want to choose to do one of two different things based on the optional parameter, perhaps interpreting that parameter using pgfkeys, the the original issue recurs.
\documentclass{article}
\usepackage{tikz,xparse,ifthen}
\usetikzlibrary{cd}
\NewExpandableDocumentCommand{\meter}{O{}m}{%
\pgfkeys{#1}
\ifthenelse{\pgfkeysvalueof{/quant/wires}=1}{
|[operator,label=#2]| {}
}{
%do something different
foo
}
}
\tikzset{
every node/.style={
anchor=center,minimum size=0pt,inner sep=0pt,outer sep=0pt,thick
},
operator/.style={draw,fill=white,minimum size=1.5em}
}
\pgfkeys{/quant/wires/.initial=1}
\begin{document}
\begin{center}
\begin{tikzcd}
\meter{0} & \meter[/quant/wires=1]{0} & \meter[/quant/wires=2]{0}
\end{tikzcd}
\end{center}
\end{document}
\ifthenelse
is not expandable and should not be used inside a command that should be expandable. The ifthen package can be useful for simple switchs on the document level but is quite unsuited for all internal programming.