2

I'm trying to record position of glyph nodes while generating a pdf file but I always get values 0 from the call of pdf.getpos() function. How can I fix it? Here is my code and the output is recorded in the output file 'test.txt'.

\documentclass{article}
\usepackage{luacode,luatexbase}
\usepackage[letterpaper,left=1in,right=1in,top=1in,bottom=1in]{geometry}

\begin{document}
\begin{luacode*}
local GLYPH_ID = node.id("glyph")

function getposition(head)
  while head do
    if head.id == 0 or head.id == 1 then
      getposition(head.list)
    elseif head.id == GLYPH_ID then
      local savepos = node.new("whatsit","save_pos")
      local h,v  =  pdf.getpos()
      file = io.open("test.txt", "a")
      file:write(tostring(h), " ", tostring(v),"\n")
      file:close()
    end
    head = head.next
  end
  return true
end

luatexbase.add_to_callback("post_linebreak_filter",getposition,"getposition")
\end{luacode*}

My \emph{text} should be here and it can be really long so the lines can break but I still need to get position of glyph nodes.

\end{document}
5
  • 1
    the post linebreak filter happens as a paragraph has been broken in to lines and placed on the main vertical list but its final output position (or even which page it is on) is not known at that point. Commented Aug 18, 2021 at 21:39
  • So how can I get the final position of a character on the page? I found similar issue tex.stackexchange.com/questions/473249/… but I have problems adapting it to my case.
    – stgr
    Commented Aug 19, 2021 at 8:05
  • you need to hook to the output routine using new latex hook mechaniosm or a package such as everyshi (every shipout) and then traverse over the nodes being written out. or as you would normaly do with \pdfsavepos use a delayed tex \write so that the information gets written as the page is shipped out not as you traverse the nodes Commented Aug 19, 2021 at 8:18
  • Thanks for the advice. Could you drop a few lines of code how to do it or at least some links where I can read about it?
    – stgr
    Commented Aug 19, 2021 at 8:20
  • 1
    no sorry more code than I can do here now, and anyway the question seems to be an exact duplicate of the one you referenced. The answers there do exactly as I hint one hooks into shipout and one uses late_lua ie action delayed until page is shipped out. Commented Aug 19, 2021 at 8:23

1 Answer 1

2

Following this comment here https://tex.stackexchange.com/a/591608/249348, the answer is the following ((TeX Live 2021) (format=lualatex 2021.8.18)):

\documentclass{scrbook}

\usepackage{fontspec}
\usepackage{luacode}

\setmainfont{Libertinus Serif}
\begin{luacode}
function PrintPos()
    local x,y = pdf.getpos()
    file = io.open("test.txt", "a")
     file:write(x," ",y,"\string\n")
     file:close()
end
function ProcessList(head)
    for n in node.traverse(head) do
        if node.is_glyph(n) then
            local printpos = node.new("whatsit","late_lua")
            printpos.data = PrintPos
            node.insert_after(head, n, printpos)
        end
        if n.head ~= nil then
            ProcessList(n.head)
        end
    end
end
function PrintCoordinates()
    local soBox = tex.getbox("ShipoutBox")
    ProcessList(soBox)
end
\end{luacode}
\AddToHook{shipout/before}{\directlua{PrintCoordinates()}}

\begin{document}
My \emph{text} should be here and it can be really long so the lines can break but I still need to get position of glyph nodes.
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .