宏有条件地生成 tikz-cd 图

宏有条件地生成 tikz-cd 图

我正在尝试定义一个宏,它将根据我传递给宏调用的参数生成一个带有细微变化的 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

相关内容