e-TeX 扩展旨在解决 Knuth 原始 TeX 的一些缺点,而且由于 LaTeX2e 暂时需要它们,因此大多数软件包作者都可以依赖它们。现在有一些资源可用于学习纯 TeX 宏用法,包括这次讨论在这个网站上,以及e-TeX 的好处总的来说,我想看到一些具体的例子,了解 e-TeX 扩展如何让宏编写者的工作变得更轻松。
特别是,关于使用扩展和解析相关命令的一些实用建议/技巧\protected
,\unexpanded
和\detokenize
\scantokens
我将不胜感激。它们对我来说很有用,但我从未意识到什么时候可以使用它们来简化事情(e-TeX 手册对它们也非常简洁)。
问题的范围相当广泛,但我最感兴趣的是上面列出的扩展。以下是关于其他扩展的一些进一步想法,我也很乐意讨论。
对于某些扩展,它们的实用性对我来说是显而易见的,包括
- 由于每种类型的槽数增加到 32767 个,因此无需担心分配新的寄存器
- 方便的等表达式命令,方便进行算术
\numexpr
运算\dimexpr
\unless
作为否定\if
,尤其是与 s 结合使用,\loop
否则,如果只要条件为假,就执行循环,则必须定义新的条件- 各种新的跟踪命令和选项,有助于诊断
但是,有些特性让我怀疑它们是否真的被现有的软件包使用,或者它们是否已被更“现代”的方法所取代,例如
- 与等混合方向排版
\beginL
。\beginR
- 状态查询,如、
\currentgrouptype
等。\currentiftype
\lastnodetype
- 可以保存内置页面顶部的废弃项目
\pagediscards
- 特定处罚
\interlinepenalties
等
答案1
以 e-TeX 中的“大件”物品为例:
\protected
让我们创建不在或类似内容内扩展的宏\edef
:\protected\def\foo{\let\baz\bong} \edef\test{Some text\foo}
通常会给出错误(假设没有
\baz
/的定义\bong
),但这里是“安全的”。如果你看看 LaTeX2e\protect
机制,上面是一个很多 更易于使用、更可靠:\protected
宏绝不在 -type 定义内部扩展x
,而使用 LaTeX2e 方法则需要\protected@edef
,等等。\unexpanded
让我们保护任意 token 免于扩展,而无需使用 toks\edef\test{Some text\unexpanded{lots of \textbf{stuff}}}
这对于任意用户输入非常有用。它还允许类似
\edef\demo{\unexpanded{tokens #}}
这意味着可以轻松地存储
#
在宏内部(参见expl3
tl
数据类型)。\detokenize
有利于使内容“安全”,例如如果它可能有活动角色\csname Tokens\detokenize{&_~^\foo}\endcsname
例如,如果在 LaTeX 中使用活动字符进行 UTF-8 输入,则尤其如此
\numexpr
等,非常适合轻松进行可扩展计算
答案2
通过对 TeX Live 中的源文件进行 grep,我可以对至少在我看来不太普遍的 e-TeX 功能的使用增加一些见解。
对于一些状态查询基元,Heiko Oberdiek 的软件包为它们的应用提供了一些说明。该atbegshi
软件包展示了一个巧妙的技巧,即如何重新定义一个以框为参数的基元(\shipout
在本例中),同时考虑到如果要用和拦截参数,\setbox
则\afterassignment
在分配后插入的标记可能会或可能不会落入框内,具体取决于框是作为box0
还是作为给出\hbox{...}
。它看起来或多或少像这样:
\def\shipout{%
\edef\saved@grouplevel{\number\currentgrouplevel}
\afterassignment\@test
\setbox\mybox=}
\def\@test{%
\ifnum\saved@grouplevel<\currentgrouplevel
\expandafter\aftergroup
\fi
\output
}
它使用 e-TeX\currentgrouplevel
来确定是否\@test
落在盒子里面(打开了一个组),在这种情况下,随后的\output
操作将推迟到盒子之后。
另一个有用的事实是,\lastnodetype
对于所有不可丢弃的东西,都小于 11,如果当前列表仍然为空,则为 -1(例如,请参阅setouterhbox
这些应用的示例)。
正如 egreg 在评论中指出的那样,\currentgrouptype
可以在数学模式下进行查询以决定是否使用\middle
分隔符变体,就像\currentgrouptype
在由打开的组中的 16 一样\left
(例如这里)。
e-TeX 的双向排版TeX 形式的功能——XeT 是 XeTeX 所使用的,该bidi
软件包为其提供了这些功能的接口。对于一些标准的 LaTeX 软件包来说,babel-hebrew
这似乎是可行的方法。然而,LuaTeX 已经放弃了\beginL
等\beginR
原语,而是集成了 Omega TeX 扩展。
再说一次,对于几个功能,我还没有找到任何实际应用。它们出现的唯一地方是可能所有原语都会出现的地方,例如 LaTeX3 内核、ConTeXt MkIV 和包unravel
,以及作者试图提高与使用它们的其他包的兼容性的其他几个地方。这些功能包括\currentif{type,branch,level}
查询、\pagediscards
功能和特定于行的\{inter,club,widow}linepenalties
。