我不明白以下行为。
介绍
首先,这是我正在使用的宏的简化版本(它本身是 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}
根据我的测试,包含三个字母的字体信息以及和之间的字距b
。c
此类数据不适合作为宏参数吸收;字体字符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 排版了某些内容,它就进入了其存在的另一个阶段,并且无法恢复。
对您来说,最好的做法可能是将框中的内容保存为宏或令牌列表,然后根据需要重新使用它来产生您想要的所有结果。