[luatex] node.isert_before() bug?

Khaled Hosny khaledhosny at eglug.org
Mon Jun 20 08:38:34 CEST 2011


On Mon, Jun 20, 2011 at 07:45:52AM +0200, Paul Isambert wrote:
> Le 19/06/2011 23:40, Taco Hoekwater a écrit :
> >Hi,
> >
> >On 19 jun. 2011, at 21:44, Khaled Hosny<khaledhosny at eglug.org>  wrote:
> >
> >>Hi all,
> >>I just found that when node.insert_before() is executed on the very
> >>first node in an hlist no nodes get inserted, I'm not sure if this is a
> >>bug, feature or some dumb thing in the code I wrote. Tested with luatex
> >>0.70.1 and 0.67.0.
> >
> >I write this 'blind' now, but iirc node.insert_before() has  a return value. But if not, remeber that variables do not auto-update themselves in side-effects in lua, so if you need to alter a list head, you will need to do something like
> >
> >   head = newdir_var
> >
> >somewhere.
> 
> To say it otherwise, the new node is correctly inserted before the
> head (i.e. prev and next pointers are right), but the container (the
> box) still points to the original head; hence the new node is in the
> list but before its starting point, and thus ignored. Thus
> node.insert_before() should be used as:
> 
> head = node.insert_before(head, head, n)
> 
> if the head is returned somewhere, or even more explicitely otherwise, e.g:
> 
> tex.box[0].head = node.insert_before(tex.box[0].head, tex.box[0].head, n)

Thanks Taco and Paul, I got it to work now. I already tried:

   head = node.insert_before(head, n, newdir("+TLT"))

but I missed the point of assigning to sublists (the code checks if a
node is an {h,v}list and runs recursively but never assigns the new,
mutated, head to the sublist). Now I can see why I've weired bugs in all
my node manipulation code :)

Regards,
 Khaled

-- 
 Khaled Hosny
 Egyptian
 Arab
-------------- next part --------------
rtlmath = {}

local glyph     = node.id("glyph")
local hlist     = node.id("hlist")
local vlist     = node.id("vlist")

local function isnumber(n)
    local c = n.char
    if c <= 0x39 and c >= 0x30 then
        return true
    else
        return false
    end
end

local function newdir(dir)
    local n = node.new("whatsit","dir")
    n.dir = dir
    return n
end

local function donumbers(head)
    local start = false
    for n in node.traverse(head) do
        if n.id == glyph then
            if isnumber(n) then
                if start then
                    if n.next and n.next.id == glyph and isnumber(n.next) then
                    else
                        head = node.insert_after(head, n, newdir("-TLT"))
                        start = false
                    end
                else
                    if n.next and n.next.id == glyph and isnumber(n.next) then
                        head = node.insert_before(head, n, newdir("+TLT"))
                        start = true
                    else
                    end
                end
            end
        else
            if start then
                head = node.insert_after(head, n, newdir("-TLT"))
                start = false
            end
            if n.id == hlist or n.id == vlist then
                n.list = donumbers(n.list)
            end
        end
    end
    return head
end

rtlmath.numbers = donumbers

nodes.tasks.appendaction("math", "after", "rtlmath.numbers")
--[[
callback.register("mlist_to_hlist",
    function(h, s, b)
        h = node.mlist_to_hlist(h, s, b)
        h = donumbers(h)
        return h
    end
    )
--]]


More information about the luatex mailing list