TransWikia.com

LuaTeX node question: Can hpack be somehow reapplied for display math to adjust to new width?

TeX - LaTeX Asked on April 2, 2021

This is a LuaTeX node library question intended to understand what all it can do, am not looking for a usual LaTeX answer.

Let’s say I have a set of display equations in an align* environment that is set in a vbox. align* environment nicely centers the contents to the natural width of the vbox. Then I copy the nodelist produced by align* environment from the vbox, and try to recursively redo hpack with the intention to center it again on a page with different text width. But this recipe doesn’t work to center the equation, moreover it messes up the math spacing produced by TeX. Can something be done about it? The constrain is that you have to work on the nodelist produced by align* (no converting align* environment again to nodelist), and it should naturally adapt to the width of the page.

A sidenote question from my code below: Performing node.write(tex.getbox(0).head) twice makes the program hang. Why is that so?

Output:
Screenshot of output

Code:

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}

Console:

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

One Answer

I don't think hpack is what you want, you need to reset the left (at least) skips to re-center, something like this

enter image description here

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]
newdimenoldtw
oldtw=textwidth
newgeometry{textwidth=3in}

blindtext[1]

directlua{
    local box0 = tex.getbox(0).head
    box0.width = tex.sp("3in")
    rehpack(tex.getbox(0).head,"theoldtw","3in")
    % nodetree.print(tex.getbox(0).head) % to print contents of box0
    node.write(tex.getbox(0))
}

blindtext[1]

end{document}

Correct answer by David Carlisle on April 2, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP