Latex Tikz 中的顺序转换

Latex Tikz 中的顺序转换

我想通过使用例如 a 来顺序转换 tikz 中的对象,\foreach并为每个步骤迭代后的结果定义一个宏。下面是我想做的一个简单示例。在我看来,结果应该是 (2,0) 处的“X”。

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

\gdef\Stepi{\node at (0,0) {X};}
\newcount\Counter
\newcount\CounterOneLess

\Counter=1
\CounterOneLess=0
\foreach \i in {2,3}
{
    \global\advance\Counter by1
    \global\advance\CounterOneLess by1
    \expandafter\gdef\csname Step\romannumeral\Counter\endcsname
    {
        \protect\begin{scope}[shift={(1,0)}]
            \csname Step\romannumeral\CounterOneLess\endcsname
        \protect\end{scope}
    }
}

\Stepiii

\end{tikzpicture}

\end{document} 

但是,当我尝试运行 pdflatex 时,出现错误,提示 TeX 容量(更具体地说是允许的分组级别数)已超出。我猜这个错误意味着我无意中导致了无限循环,并且它与我对扩展的误解有关。有没有办法让这个概念发挥作用?

如果有帮助的话,如果我更换

\csname Step\romannumeral\CounterOneLess\endcsname

在范围环境中使用\Stepi。结果为预期位置处的 X(即,在这种情况下为 (1,0))。当然,进行这种替换违背了目的。

答案1

  • \xdef而不是在循环\gdef内部\foreach扩展定义文本和当前计数器值。

  • \noexpand而不是\protect阻止内部的扩展\xdef\protect仅适用于 LaTeX 宏(\protected@edef,...)。

修正示例:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

\gdef\Stepi{\node at (0,0) {X};}
\newcount\Counter
\newcount\CounterOneLess

\Counter=1
\CounterOneLess=0
\foreach \i in {2,3}
{
    \global\advance\Counter by1
    \global\advance\CounterOneLess by1
    \expandafter\xdef\csname Step\romannumeral\Counter\endcsname
    {
        \noexpand\begin{scope}[shift={(1,0)}]
            \expandafter\noexpand\csname Step\romannumeral\CounterOneLess\endcsname
        \noexpand\end{scope}
    }
}
\Stepiii
\end{tikzpicture}
\end{document}

这里不需要计数器业务,因为它\foreach已经提供了所有需要的功能:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

\gdef\Stepi{\node at (0,0) {X};}

\foreach \i [evaluate=\i as \ioneless using int(\i-1)] in {2,3}
{
    \expandafter\xdef\csname Step\romannumeral\i\endcsname
    {
        \noexpand\begin{scope}[shift={(1,0)}]
            \expandafter\noexpand\csname Step\romannumeral\ioneless\endcsname
        \noexpand\end{scope}
    }
}

\Stepiii

\end{tikzpicture}
\end{document}

答案2

使用更少的\noexpandtoken:

\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\DefineStep}{m}
 {
  \paige_definestep:xx { \int_to_roman:n { #1 } } { \int_to_roman:n { #1 - 1 } }
 }
\cs_new_protected:Nn \paige_definestep:nn
 {
  \cs_gset:cpn { Step#1 }
   {
    \begin{scope}[shift={(1,0)}]
    \use:c { Step#2 }
    \end{scope}
   }
 }
\cs_generate_variant:Nn \paige_definestep:nn { xx }
\ExplSyntaxOff

\begin{document}

\begin{tikzpicture}
  \gdef\Stepi{\node at (0,0) {X};}
  \foreach \i in {2,3} { \DefineStep{\i} }
  \Stepi \Stepii \Stepiii
\end{tikzpicture}

\footnotesize
\texttt{\meaning\Stepi}

\texttt{\meaning\Stepii}

\texttt{\meaning\Stepiii}

\end{document}

在此处输入图片描述

相关内容