我正在尝试定义一个宏,它将根据我传递给宏调用的参数生成一个带有细微变化的 tikz-cd 图。我使用xstring
包来表达条件。
我的第一次尝试很成功:
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-cd}
\usepackage{xstring}
\newcommand\myPic[1]{
\begin{tikzcd}[
ampersand replacement=\&,
execute at end picture={
\IfStrEq{#1}{yes}{
\draw (a) -- (b);
}{
\draw (a) -- (c);
}
}
]
|[alias=a]| A \& |[alias=b]| B \\
|[alias=c]| C \& D \\
\end{tikzcd}
}
\begin{document}
\myPic{yes}
\myPic{no}
\end{document}
但是当我尝试更复杂的条件并将我的宏定义为
\newcommand\myPic[1]{
\begin{tikzcd}[
ampersand replacement=\&,
execute at end picture={
\IfStrEq{#1}{yes}{
\draw (a) -- (b);
}{
\draw (a) -- (c);
}
}
]
\IfStrEq{#1}{yes}{
|[alias=a]| A \& |[alias=b]| B \\
}{
|[alias=a]| A \& B \\
|[alias=c]| C \& D \\
}
\end{tikzcd}
}
我开始
main.tex:29:1: error: Package pgf Error: No shape named `a' is known.
错误。有人能帮我弄清楚为什么我会得到这些错误吗?我猜它没有按照我期望的顺序评估我的代码,但我不知道如何修复或调试它。
通常有没有什么办法可以实现我的愿望?
伊万
答案1
如果您使用可扩展的字符串相等测试,而不是代码提供的测试,则效果会很好。下面为此创建了-functionxstring
的副本。expl3
\str_if_eq:nnTF
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-cd}
\ExplSyntaxOn
\cs_new_eq:NN \myifstreq \str_if_eq:nnTF
\ExplSyntaxOff
\newcommand\myPic[1]{%
\begin{tikzcd}[
ampersand replacement=\&,
execute at end picture={%
\myifstreq{#1}{yes}{%
\draw (a) -- (b);
}{%
\draw (a) -- (c);
}%
}%
]
\myifstreq{#1}{yes}{%
|[alias=a]| A \& |[alias=b]| B \\
}{%
|[alias=a]| A \& B \\
|[alias=c]| C \& D \\
}%
\end{tikzcd}%
}
\begin{document}
\myPic{yes}
\myPic{no}
\end{document}
如果您打算添加更多不同的输出,您可以改用\str_case:nn
:
\documentclass[border=3.14]{standalone}
\usepackage{tikz}
\usepackage{tikz-cd}
\ExplSyntaxOn
\cs_new_eq:NN \mystrcase \str_case:nn
\ExplSyntaxOff
\newcommand\myPic[1]{%
\begin{tikzcd}[
ampersand replacement=\&,
execute at end picture={%
\mystrcase{#1}
{%
{yes}{\draw (a) -- (b);}
{no} {\draw (a) -- (c);}
}%
}%
]
\mystrcase{#1}
{%
{yes}{|[alias=a]| A \& |[alias=b]| B \\}
{no} {%
|[alias=a]| A \& B \\
|[alias=c]| C \& D \\
}
}%
\end{tikzcd}%
}
\begin{document}
\myPic{yes}
\myPic{no}
\end{document}
或者,您可以创建不同的宏来存储不同版本的代码。这可以通过以下方式实现(例如,其他方法也是可行的):
\makeatletter
\newcommand\mydrawing@yes{|[alias=a]| A \& |[alias=b]| B \\}
\newcommand\mydrawing@no
{%
|[alias=a]| A \& B \\
|[alias=c]| C \& D \\
}
\newcommand\myPic[1]{%
\begin{tikzcd}
\ifcsname mydrawing@\detokenize{#1}\endcsname
\csname mydrawing@\detokenize{#1}\endcsname
\else
\ERROR
\fi
\end{tikzcd}
\makeatother