TeX-FAQ:宏名称中的非字母 - 特殊命令生成器

TeX-FAQ:宏名称中的非字母 - 特殊命令生成器

我查看了 TeX-FAQ宏名称中的非字母并尝试实施方法 #2。看来我遗漏了一些东西。稍后尝试引用新命令时,结果并不如我预期。

\documentclass{standalone}
\usepackage{tikz}
\begin{document}

\newcommand{\DefineNode}[2]
{
  \expandafter\newcommand\csname node-#1\endcsname{#2}
}
\newcommand{\GetNode}[1]{\csname node-#1\endcsname}

\begin{tikzpicture}
  \def \intra {1}
  \def \inter {3}

  % Calculate values
  \foreach \x [count=\xi from 0] in {a,...,c}
  {
    \pgfmathsetmacro\tmpi{\xi * \inter}
    \DefineNode{n\x.0}{\tmpi}

    \pgfmathsetmacro\tmpii{\xi * \inter + \intra}
    \DefineNode{n\x.1}{\tmpii}

    \message{\GetNode{n\x.0} ^^J}
    \message{\GetNode{n\x.1} ^^J}
  }

  % Doing something with them later
  \foreach \x in {a,...,c}
  {
    \message{\GetNode{n\x.0} ^^J}
    \message{\GetNode{n\x.1} ^^J}
  }
\end{tikzpicture}

\end{document}

结果是:

0.0
1.0
3.0
4.0
6.0
7.0
\node-na.0
\node-na.1
\node-nb.0
\node-nb.1
\node-nc.0
\node-nc.1

而不是重复数字两次。

编辑:通过强制名称为全局名称来解决组问题。

\newcommand{\DefineNode}[2]
{
  \globaldefs=1\relax
  \expandafter\newcommand\csname node-#1\endcsname{#2}
}

目前结果:

0.0
1.0
3.0
4.0
6.0
7.0
6.0
7.0
6.0
7.0
6.0
7.0

现在不再重复前 6 行,而是重复 6.0 和 7.0。这是因为只使用了两个宏 \tmpi 和 \tmpii。如何解决这个问题?

答案1

的一个特点\foreach是它以组为单位执行每个循环;它的主要目的是向tikzpicture正在构建的对象添加路径或节点,并且此操作确实是全局的。

正在做的\globaldefs=1不是这是一个很好的解决方法,因为\newcommand执行了几个你真的不想成为全局的任务。

你可以看看\global\renewcommand相当于\global\def对于\gnewcommand不需要的\globaldefs=1。然而,在当前情况下,一个更简单的

\newcommand{\DefineNode}[2]{%
  \expandafter\xdef\csname node-#1\endcsname{#2}%
}

似乎足够了。您需要\xdef扩展\tmpi\tmpii

你不会收到关于重新定义相同控制序列的警告。如果你真的需要这个功能,那么

\makeatletter
\providecommand\@nameedef[1]{\expandafter\edef\csname#1\endcsname}
\newcommand{\DefineNode}[2]{%
  \expandafter\@ifdefinable\expandafter{\csname node-#1\endcsname}{%
    \global\@nameedef\node-#1}{#2}%
  }%
}
\makeatother

就是你要找的。同样,需要扩展定义。

相关内容