[luatex] reverse node lists

Patrick Gundlach patrick at gundla.ch
Tue Nov 1 09:44:13 CET 2011


Hi Arno,

> this is again a rather simple question and I am sorry for taking your time for this …
> In short, I want to reverse all glyph nodes in a line, and/or all lines in a paragraph. I tried something like the following (with the idea to store all lines in a list, then replace the lines with the list in reversed order):
> 
> function reverse(head)
> 
> newlines = {}
> i = 1
>  for line in node.traverse_id(node.id"hhead",head) do
>    newlines[i] = line

a lua idiom is newlines[#newlines + 1] = ... - easer to read to the average Lua hackr.


>    i = i+1
>  end
> 
> j = #newlines
> 
>  for line in node.traverse_id(node.id"hhead",head) do
>    node.insert_before(head,line,newlines[j])
>    j = j-1
>  end
>  return head
> end

I have to admit that I don't understand exactly what is going on here. I never use the node.insert_* functions as they are some black magic to me, I always change next/prev pointsers manually, so I have the feeling of what I have to do. Therefore my brain just blocks when I try to analyze your code. Sorry. If you want a manual solution, see the following code. 

Patrick



\documentclass{article}
\usepackage{luacode}
\begin{document}
\begin{luacode*}

function swap_lines(lines, lineno1,lineno2 )
  local line1 = lines[lineno1]
  local line2 = lines[lineno2]
  
  local first_line_prev  = line1.prev
  local first_line_next  = line1.next
  local second_line_prev = line2.prev
  local second_line_next = line2.next

  first_line_prev.next = line2
  line2.prev = first_line_prev
  line2.next = first_line_next
  first_line_next.prev = line2
  
  second_line_prev.next = line1
  line1.prev = second_line_prev
  line1.next = second_line_next
  
  if second_line_next then
    second_line_next.prev = line1
  end
end

function reverse_line( hlist )
  local head = hlist.list
  local rightskip = node.tail(head)

  -- "first" glyph
  local new_list = rightskip.prev
  local new_list_start = new_list

  -- new_list points to the last glyph
  head = new_list.prev

  while head do
    new_list.next = head
    new_list = head
    head = head.prev
  end
  new_list.next = rightskip
  new_list_start.prev = nil

  -- prev pointers are still garbled, fix 'em:
  node.slide(new_list_start)
  hlist.list=new_list_start
end

function myfunc( head )
  local lines = {}
  while head do
    if head.id == 0 then
      reverse_line(head)
      lines[#lines + 1] = head
    end
    head = head.next
  end
  for i=1,math.floor(#lines / 2) do
    swap_lines(lines,i,#lines + 1 - i)
  end
  return true
end

luatexbase.add_to_callback("post_linebreak_filter",myfunc,"reverse")

\end{luacode*}

When, while the lovely valley teems with vapour around me, and the meridian sun strikes the upper surface of the impenetrable foliage
of my trees, and but a few stray gleams steal into the inner sanctuary, I throw myself down among the tall grass by the trickling
stream; and, as I lie close to the earth, a thousand unknown plants are noticed by me: when I hear the buzz of the little world among
the stalks, and grow familiar with the countless indescribable forms of the insects and flies, then I feel the presence of the
Almighty, who formed us in his own image, and the breath of that universal love which bears and sustains us, as it floats around us
in an eternity of bliss; and then, my friend, when darkness overspreads my eyes, and heaven and earth seem to dwell in my soul and
absorb its power, like the form of a beloved mistress, then I often think with longing, Oh, would I could describe these conceptions,
could impress upon paper all that is living so full and warm within me, that it might be the mirror of my soul, as my soul is the
mirror of the infinite God!


\end{document}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.pdf
Type: application/pdf
Size: 18511 bytes
Desc: not available
URL: <http://tug.org/pipermail/luatex/attachments/20111101/18730b97/attachment-0001.pdf>


More information about the luatex mailing list