[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