宏和框内容的扩展

宏和框内容的扩展

我不明白以下行为。

介绍

首先,这是我正在使用的宏的简化版本(它本身是 gloss.tex 中宏的破解版本)。如果您有一个带MY|STRING分隔符的字符串(在本例中为竖线),\getmorphs MY|STRING|\\则将其拆分为部分MY和。请注意,当我们将其作为参数传递给时,STRING我们必须在末尾放置一个竖线,以便始终至少有一个“由竖线分隔的部分”(中的参数 #1 ):MY|STRING\getmorphs\getmorphs

\makeatletter
\def\getmorphs#1|#2\\{%
  \@getparts(#1,#2,\getmorphs)
}
\def\@getparts(#1,#2,#3){Printed: #1%
    \def\more{#2}%
    \ifx\more\empty\let\more=\donewords
    \expandafter\else\expandafter\let\expandafter\more=#3
    \fi
    \more#2\\%
   }
\gdef\donewords#1\\{}%
\makeatother

如下图所示,\getmorphs分别打印每个部分:

\getmorphs aaa|bbb|\\% Printed: aaa Printed: bbb (correct)

如果我们定义一个宏,将其扩展为带有竖线的文本,并将该宏作为参数传递给 ,它甚至可以正常工作\getmorphs。为了使其工作,我们必须使用 ,\expandafter以便\testmacro在 之前扩展\getmorphs

\def\testmacro{aaa|bbb}
\getmorphs\testmacro|\\% Printed: aaa|bbb (incorrect)

\expandafter\getmorphs\testmacro|\\% Printed: aaa Printed: bbb (correct)

问题

在我正在处理的实际代码中,我有一个 hbox,其内容是 aaa|bbb:

\newbox\testbox
\setbox\testbox=\hbox{aaa|bbb}

我不知道如何将该框的内容传递给\getmorphs。我尝试了以下变体

\getmorphs\unhbox\testbox|\\
\expandafter\getmorphs\unhbox\testbox|\

等等,甚至尝试定义一个临时宏来扩展为 \unhbox\testbox,然后将其作为参数传递给\getmorphs之前的代码:

\def\moretest{\unhbox\testbox}
\expandafter\getmorphs\moretest|\

什么都不起作用。有人知道我如何访问该 hbox 的内容并将其用作宏的参数吗?

答案1

你正在尝试做的事情注定会失败。原因有两个:基本原因和技术原因。

  • 基本原因:的内容\hbox已经排版,不再是标记形式。也就是说,\hbox{abc}根据我的测试,包含三个字母的字体信息以及和之间的字距bc此类数据不适合作为宏参数吸收;字体字符a与输入字符不同a

  • 技术原因:获取框内容的唯一方法是 到\unhbox它。但是,与框相关的所有命令都是不可扩展的:它们是可执行的,并由 TeX 引擎的不同模式处理。例如,写作\expandafter\getmorphs\unhbox\testbox|与写作相同,\getmorphs\unhbox\testbox|因为它\unhbox会扩展为自身并且不会“执行”。您构造的尝试\moretest失败了,因为您只是告诉\moretest它包含一对控制字,因此您的最后一个例子扩展为我上面写的内容。出于同样的原因,\unhbox\testbox写 也是无效的。\edef\moretest{\unhbox\testbox}\expandafter

技术原因在于,TeX 的所有宏处理功能都发生在“扩展”级别,而当 TeX 开始“执行”诸如\unhbox,所有先前的宏都已经已经已经扩展。没有办法将“水平材料”(例如框的内容)放入宏中,因为当读取该材料时,宏将不再存在。

更深入地讲,您可能会问 TeX 会对 之类的东西做什么\tenrm a,这\showbox告诉我 是 中的第一个东西\hbox{abc}。如果字体碰巧看起来a((例如,符号字体)怎么办?TeX 是否应该将其理解为a(,以及它将具有什么字符或类别代码?一旦 TeX 排版了某些内容,它就进入了其存在的另一个阶段,并且无法恢复。

对您来说,最好的做法可能是将框中的内容保存为宏或令牌列表,然后根据需要重新使用它来产生您想要的所有结果。

相关内容