我正在尝试设置一个 tikz 矩阵(实际上,在本例中是 tikz-cd),在其中调用单元格内的不同宏,这些宏将决定显示的内容。只要我在宏上没有可选参数,这一切都可以正常工作。但是,一旦我使用可选参数,应该定义节点的文本就会显示为文本。我该如何解决这个问题?
以下是 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}
我确信以前一定有人问过这个问题,但也许不知道解决方案/正确的搜索词,所以我很难找到它。
更新:
@egreg 的解决方案按照说明解决问题。但是,一旦我将宏变得更复杂,它就会停止工作。例如,如果我想根据可选参数选择执行两件事之一,也许使用 pgfkeys 解释该参数,则原始问题会再次出现。
\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}
答案1
您可以使用xparse
和\NewExpandableDocumentCommand
,但\optmeter
命令应该有一个虚拟的强制参数。
\documentclass{article}
\usepackage{tikz-cd}
\usepackage{xparse}
\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
\NewExpandableDocumentCommand{\optmeter}{O{a}m}{%
|[operator,label={[yshift=0.1cm]above right:#1}]| {} \qw
}
\NewExpandableDocumentCommand{\optgate}{O{a}{m}}{|[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}
答案2
只是为了完整性。Ti钾Z 允许您仅使用样式来执行大多数操作。也就是说,我不确定我是否会为此使用命令。
\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}
\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},
hard/.style={operator,label={[yshift=0.1cm]above right:#1},fill=blue,
append after command={\pgfextra{\arrow[dash,thick]{l}}}}
}
\begin{document}
What's supposed to happen: \\\\
\begin{tikzcd}
& \hardgate{H} & \hardmeter
\end{tikzcd}\\\\
What actually happens:\\
\begin{tikzcd}
& |[hard]| H & |[hard=0]| O & |[hard,fill=red]| U & |[hard=2,fill=red]| R
\end{tikzcd}
\end{document}
更新:对你更新的问题的回答。我修补了一些我认为应该做的事情。在我看来,这是一个非常奇怪的构造。基本技巧是将推迟到ifthenelse
,/quant/wires/
这必须成为代码,然后使用\pgfkeysalso
将选项偷运回节点样式。
\documentclass{article}
\usepackage{tikz,xparse,ifthen}
\usetikzlibrary{cd}
\NewExpandableDocumentCommand{\meter}{O{}m}{%
|[#1,label=#2]| {}
}
\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/.code={\ifcase#1
\or
\pgfkeysalso{/tikz/.cd,operator}
\or
\pgfkeysalso{/tikz/.cd,operator,fill=blue}
\or
\fi}}
\begin{document}
\begin{center}
\begin{tikzcd}
\meter{0} & \meter[/quant/wires=1]{0} & \meter[/quant/wires=2]{0}
\end{tikzcd}
\end{center}
\end{document}
我知道这会抹杀你对土拨鼠仅存的同情,但我确实不是我认为,仅仅因为一个可行的答案不符合后来添加的要求而拒绝接受它是一种很好的风格。我确实认为@egreg 值得在他的好答案旁边打勾,我在这里使用了它,你应该在这里提出一个新问题。毕竟,问题是免费的。