\ifcase#1 语句后何时需要使用 \relax

\ifcase#1 语句后何时需要使用 \relax

在 LaTeX 内核 ( latex.ltx) 中,我们看到了一些示例 \ifcase#1\or a\or b\or ...(\ifcase没有添加\relax),但是当我们查看一些软件包时,大多数软件包在 之后添加了此语句\ifcase#1。所以我的问题是:什么时候需要这样做?

答案1

\ifcase@wipet 给出的答案解释了如果结果为零,则需要将数字的评估与所使用的材料分开,并解释了为什么“空间”或\relax可能根据输入而错误。

就 LaTeX 而言:当最初编写 LaTeX 时,每个字节都很重要,因此我们在不需要时会删除任何显式分隔,例如,

  \ifcase#1\or

这里零值的情况是空的,告诉\orTeX 计算的数字已经完成。在以下情况下

\ifcase\@eqcnt

我们知道这\@eqcnt是一个计数器,因此不需要空格或\relax(甚至正确)

最后,如果你真的不知道输入数据是什么,那么你必须求助于@wipet 与 David Carlisle 共同找到的解决方案,即

\def\zaprelax#1\relax{#1 }

 \ifcase\expandafter\zaprelax\number#1\relax

latex.ltx有一种情况,\ifcase\number#1但这也不能解决一般情况(正如我最初所想的);它只在那里起作用,因为所使用的输入实际上不是完全通用的。换句话说,\hexnumber@在内核中是完全正确定义的。如果输入是普通的,它就不会起作用0。)

无论如何,如果您不知道输入是什么,那么仅用结束评估\relax是错误的,正如@wipet 解释的那样:它正确地停止了评估,但您不知道是否\relax消失或成为零案例的一部分!

所以如果你

\def\foo#1{\ifcase#1\relax 7\or 8\else9\fi}

的替换文本\foo可能只是一个数字(7、8 或 9)或者\relax 7后者的行为与其他情况完全不同。

简而言之,\relax在包中使用可能是不必要的,但也可能完全是错误的。

答案2

具有\ifcase语法

\ifcase number zero case\or one\or two\or ...\fi

“数字”必须与“零大小写”分隔开。自然分隔符是空格,但有些“数字”格式中“数字”很紧凑(例如,来自的\countdef\chardef额外的空格占了“零大小写”的一部分)。您可以尝试:

\def\test#1{\ifcase#1 77zero\or one\fi}  % note the space before "77zero"

literal:\test{0}  % the space is a separator of the number, it disappears

\newcount\tmpnum  \tmpnum=0
countdef:\test{\tmpnum}  % the space is a part of the zero case, it is printed 

\chardef\tmp=0
chardef:\test{\tmp}  % the space is a part of the zero case, it is printed

\end

如果您需要每种类型的数字中没有空格,则可以将其用作\relax数字的分隔符。这样不会打印任何内容。但还有另一个问题:如果宏仅用于扩展目的并且评估零大小写,则 \relax 仍是结果的一部分。

编辑:如何解决各种数字格式的问题,#1以便不\relax扩展空格?恕我直言,只有通过 eTeX 原语才有可能\numexpr

\def\test#1{\ifcase\numexpr#1\relax 77zero\or 2one\fi}

编辑2:感谢 Frank 和 David,我们(在下面的讨论中)找到了经典 TeX 中数字分隔符的强大解决方案:

\def\zaprelax#1\relax{#1 }
\def\test#1{\ifcase\expandafter\zaprelax\number#1\relax 77zero\or 2one\or two\fi}

相关内容