从已建的水平盒子中删除角色

从已建的水平盒子中删除角色

第 5.9.6 节TeX 按主题分类展示了一种算法,通过反复使用 删除最后一行,将 vbox 分解为 hbox 形式的单独行\lastbox。还有类似的命令用于删除框的其他组件,\unskip\unkern\unpenalty

不幸的是,在尝试剖析水平盒时,同样的方法似乎不起作用。以下示例说明了这个问题:

\documentclass{article}

\begin{document}
\def\inspect{%
    \unhbox0
    \count0=\lastnodetype
    \setbox1=\lastbox
    \fbox{\box1}, \the\count0
}
\setbox0=\hbox{abc}\hbox{\inspect}

\setbox0=\hbox{ab\hbox{c}}\hbox{\inspect}
\end{document}

输出:

在此处输入图片描述

当我们尝试使用\lastbox从第一个 hbox 中删除最后一个字符时,结果只是一个空框。使用 打印节点类型可以说明原因:最后一个字符不是框,而是“char 节点”(节点类型 0)。当将 包装到 extra 中\lastnodetype时,结果正如预期的那样是“hlist 节点”(节点类型 1)。c\hbox

是否有一种仅在 (La)TeX/e-TeX 中的方法可以遍历已构建的 hbox 的内容,类似于 vbox 方法?e-TeX 文档列出了列表中可能出现的 16 种节点类型,但我只能看到一种方法来删除其中五种节点,只要它们已添加到列表中。

答案1

如果没有 LuaTeX,这是不可能的。

当然,使用 LuaTeX 很容易,但你必须决定如何存储字形,因为没有用于存储孤立glyph节点的 TeX 寄存器。(字形节点是 LuaTeX 中的字符节点等价物,如果你使用 存储它们,你会丢失有关字体的信息\chardef

一个选项是将字形节点包装在\hbox盒子寄存器中存储:

\documentclass{article}

\newcommand\setlastcharbox{\directlua{
  local nest = tex.nest[tex.nest.ptr]
  local tail = nest.tail
  if tail.id == node.id'glyph' then
    tail.prev.next = nil
    nest.tail = tail.prev
    tex.box[token.scan_int()] = node.hpack(tail)
    print(tail)
  else
    tex.box[token.scan_int()] = nil
  end
}}
\begin{document}
\def\inspect{%
    \unhbox0
    \count0=\lastnodetype
    \setlastcharbox1
    \fbox{\box1}, \the\count0
}
\setbox0=\hbox{}\hbox{\inspect}

\setbox0=\hbox{abc}\hbox{\inspect}
\end{document}

在此处输入图片描述

相关内容