这是一个 LuaTeX 节点库问题,旨在了解它能做什么,而不是寻找通常的 LaTeX 答案。
假设我在align*
中设置的环境中有一组显示方程\vbox
。align*
环境很好地将内容居中到 的自然宽度。然后我从 中\vbox
复制环境生成的节点列表,并尝试align*
\vbox
递归重做 hpack目的是让它在具有不同文本宽度的页面上再次居中。但是这种方法无法使方程式居中,而且它还会弄乱 TeX 生成的数学间距。可以做些什么吗?限制在于您必须处理由生成的节点列表align*
(无需再次将环境转换align*
为节点列表),并且它应该自然地适应页面的宽度。
下面我的代码中有一个附带问题:执行
node.write(tex.getbox(0).head)
两次会导致程序挂起。为什么会这样?
代码:
\documentclass{article}
\usepackage{geometry}
\usepackage{unicode-math}
\usepackage{blindtext}
\directlua{
nodetree = require"nodetree"
local hlist_id = node.id("hlist")
function rehpack(n,h)
for nn in node.traverse_id(hlist_id,h) do
rehpack(nn,nn.head)
end
if not (n == nil) and n.id == hlist_id and not (n.head == nil) then
texio.write_nl("Previous width = " .. n.width)
local newn = node.hpack(h)
n.width = newn.width
newn.head = nil
node.free(newn)
texio.write_nl(".....New width = " .. n.width)
end
end
}
\begin{document}
\blindtext[1]
\setbox0=\vbox{{\begin{align*}
x^2+y^2 &= z^2\\
a^2+b^2+1 &= c^3
\end{align*}}}\copy0
\blindtext[1]
\newgeometry{textwidth=3in}
\blindtext[1]
\directlua{
local box0 = tex.getbox(0).head
box0.width = tex.sp("3in")
% nodetree.print(tex.getbox(0).head) % to print contents of box0
rehpack(nil,tex.getbox(0).head)
% nodetree.print(tex.getbox(0).head) % to print contents of box0
node.write(tex.getbox(0).head)
}
\blindtext[1]
\end{document}
安慰:
Previous width = 14208860
.....New width = 983040
Previous width = 0
.....New width = 0
Previous width = 297726
.....New width = 261030
Previous width = 297726
.....New width = 261030
Previous width = 2110904
.....New width = 2037512
Previous width = 2110904
.....New width = 2037512
Previous width = 3162361
.....New width = 2037512
Previous width = 297726
.....New width = 261030
Previous width = 1496049
.....New width = 1459353
Previous width = 1496049
.....New width = 1459353
Previous width = 1496049
.....New width = 1459353
Previous width = -11761186
.....New width = -11761186
Previous width = 16419596
.....New width = 15258051
Previous width = 0
.....New width = 0
Previous width = 297726
.....New width = 261030
Previous width = 297726
.....New width = 261030
Previous width = 3162361
.....New width = 3088969
Previous width = 3162361
.....New width = 3088969
Previous width = 3162361
.....New width = 3088969
Previous width = 297726
.....New width = 261030
Previous width = 1471801
.....New width = 1435105
Previous width = 1471801
.....New width = 1435105
Previous width = 1496049
.....New width = 1435105
Previous width = -11761186
.....New width = -11761186
Previous width = 16419596
.....New width = 16285260
答案1
我不认为 hpack 是你想要的,你需要重置左边(至少)跳过以重新居中,就像这样
\documentclass{article}
\usepackage{geometry}
\usepackage{unicode-math}
\usepackage{blindtext}
\directlua{
nodetree = require"nodetree"
local hlist_id = node.id("hlist")
function rehpack(h,oldw,neww)
local hlist_id = node.id("hlist")
for nn in node.traverse_id(hlist_id,h) do
local lsk=nn.head
if lsk.id == 12 then
local tsk=node.getglue(nn.head,false)
node.setglue(nn.head,tsk - (tex.sp(oldw)-tex.sp(neww))/2)
end
end
end
}
\begin{document}
\blindtext[1]
\setbox0=\vbox{{\begin{align*}
x^2+y^2 &= z^2\\
a^2+b^2+1 &= c^3
\end{align*}}}\copy0
\blindtext[1]
\newdimen\oldtw
\oldtw=\textwidth
\newgeometry{textwidth=3in}
\blindtext[1]
\directlua{
local box0 = tex.getbox(0).head
box0.width = tex.sp("3in")
rehpack(tex.getbox(0).head,"\the\oldtw","3in")
% nodetree.print(tex.getbox(0).head) % to print contents of box0
node.write(tex.getbox(0))
}
\blindtext[1]
\end{document}