使用 e-TeX 的宏技术

使用 e-TeX 的宏技术

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

相关内容