放松并呼气
我习惯于\relax
在许多宏的末尾看到它。通常,我不明白其中的原理;有时这种放置对我来说似乎或多或少是随意的。
例如,计算数学橡胶长度,其拉伸和收缩是自然空间模量的一半,如下所示(基于https://tex.stackexchange.com/a/669865):
\newcommand{\flexibleMSkip}[1]{%%% 50 per cent of the modulus of the argument after plus and minus. The argument may be any integer or floating-point number.
\mskip#1
plus.5\muexpr\ifdim\mutoglue\muexpr#1<0pt -\fi#1\relax
minus.5\muexpr\ifdim\mutoglue\muexpr#1<0pt -\fi#1\relax
\relax
}
这个宏是如此\relax
强大,以至于不太可能需要向精神科医生倾诉。从技术上讲,如果没有第一个\relax
,则“减号”部分将被忽略,但为什么我们需要第二个和第三个\relax
呢?
现在考虑对文本模式进行相同的练习(我自己的创建):
\newcommand{\flexibleHSkip}[1]{%
\hskip#1
plus.5\dimexpr\ifdim #1<0pt -\fi#1
minus.5\dimexpr\ifdim #1<0pt -\fi#1
}
这个似乎\relax
根本没有 ed,但在小示例上对我来说没有压力。在这里,将 a 放在\relax
加号行的末尾或减号行的末尾或整个宏的末尾(就在 之前}
)对我的小示例没有任何影响。添加这些\relax
es 是否有必要,或者会带来任何快乐或不满,或者它是否会加快或减慢计算速度?
您可能会说 TeXbook 中的练习 27.4 总体上证明了这个问题,但是在我们上面的例子中,我们怎么可能错误地构造输入以导致出现非预期的含义而编译时却没有错误呢?
下面是一个完整的、不太复杂的\relax
示例,供您参考:
\documentclass{article}
%%% 50 per cent of the modulus of the argument after plus and minus. The argument may be any integer or floating-point number.
\newcommand{\flexibleMSkip}[1]{%
\mskip#1
plus.5\muexpr\ifdim\mutoglue\muexpr#1<0pt -\fi#1\relax
minus.5\muexpr\ifdim\mutoglue\muexpr#1<0pt -\fi#1
}
\newcommand{\flexibleHSkip}[1]{%
\hskip#1
plus.5\dimexpr\ifdim #1<0pt -\fi#1
minus.5\dimexpr\ifdim #1<0pt -\fi#1
}
\showoutput
\begin{document}
\(a\flexibleMSkip{-.5mu}b\)
c\flexibleHSkip{-.1em}d
\end{document}
顺便问一下,在加法和减法表达式中,为什么我们在前面乘以 .5,而不是在最后除以 2?这有什么区别吗?
答案1
\relax
有时用作通用的不可扩展标记来停止扫描,如
\hsize=3in\relax
但在这里你使用的是 e-tex 表达式,其中\relax
构成了表达式语法的一部分,因此与上面的不同
\hsize=\dimexpr3in\relax
被\relax
分配所消耗并且不会\relax
在流中留下标记。
所以
\muexpr\ifdim\mutoglue\muexpr#1<0pt -\fi#1\relax
最后的放松结束了(外部),\muexpr
否则minus
下一行的开头将构成该表达式的一部分。
比较
\documentclass{article}
%%% 50 per cent of the modulus of the argument after plus and minus. The argument may be any integer or floating-point number.
\newcommand{\flexibleMSkipA}[1]{%
\muskip0=#1
plus.5\muexpr\ifdim\mutoglue\muexpr#1<0pt -\fi#1\relax
minus.5\muexpr\ifdim\mutoglue\muexpr#1<0pt -\fi#1
\showthe\muskip0
}
\newcommand{\flexibleMSkipB}[1]{%
\muskip0=#1
plus.5\muexpr\ifdim\mutoglue\muexpr#1<0pt -\fi#1
minus.5\muexpr\ifdim\mutoglue\muexpr#1<0pt -\fi#1
\showthe\muskip0
}
\flexibleMSkipA{1mu}
\flexibleMSkipB{1mu}
\stop
这表明删除了\relax
更改值
> 1.0mu plus 0.5mu minus 0.5mu.
\flexibleMSkipA ...0pt -\fi #1 \showthe \muskip 0
l.18 \flexibleMSkipA{1mu}
?
> 1.0mu plus 0.5mu.
\flexibleMSkipB ...0pt -\fi #1 \showthe \muskip 0
l.20 \flexibleMSkipB{1mu}
?
在您不相关的第二个问题中,以 0.5 为前缀是经典的 tex <factor>
,并将自然长度减半,丢弃正负分量。/2
是 e-tex 除法并将所有组件减半。
\showthe\thickmuskip
\showthe\muexpr.5\thickmuskip\relax
\showthe\muexpr\thickmuskip/2\relax
生产
> 5.0mu plus 5.0mu.
> 2.5mu.
> 2.5mu plus 2.5mu.