发现 lua-visual-debug 显示哪个 (La)Tex 元素(打印到标准输出)?

发现 lua-visual-debug 显示哪个 (La)Tex 元素(打印到标准输出)?

我正在尝试解决代码中发生的问题图片/绘图与表格组图的位置(和/或大小)错误(......和不连续性)?。因此我\usepackage{lua-visual-debug}在该示例中添加了内容,并用 构建了它lualatex test.tex;结果如下:

测试05

据我所知(通过查阅 的lvdebug-doc.pdf文档lua-visual-debug),那些从左边“推开”图的灰色水平线是胶水。问题是 - 我不知道如何分辨哪个这些都是胶水;更糟糕的是,在运行结束时,lualatex 注意到:

...
仍在使用节点内存的 9093 个字:
123 个 hlist、1 个 vlist、1 个规则、32 个数学、638胶水, 33 glyph, 69 glue_spec, 1 wri
te, 1561 pdf_literal, 18 pdf_colorstack 节点
可用列表:1:1,2:44,3:2341,4:710,6:41,7:1,9:130
...

...所以,即使我有各种胶水名称的列表,也很难手动搜索 638 种胶水。

理想情况下,我想要的是在 LaTex 胶水的呈现行旁边排版其名称lua-visual-debug;例如,我可以看到负责它的代码lua-visual-debug.lua是:

  elseif head.id == 10 then -- glue
      print "Got glue" -- added for debug
      local wd = head.spec.width
      local color = "0.5 G"
      if parent.glue_sign == 1 and parent.glue_order == head.spec.stretch_order then
        wd = wd + parent.glue_set * head.spec.stretch
        color = "0 0 1 RG"
      elseif parent.glue_sign == 2 and parent.glue_order == head.spec.shrink_order then
        wd = wd - parent.glue_set * head.spec.shrink
        color = "1 0 1 RG"
      end
      local pdfstring = node.new("whatsit","pdf_literal")
      local wd_bp = math.round(wd / number_sp_in_a_pdf_point,2)
      if parent.id == 0 then --hlist
        pdfstring.data = string.format("q %s [0.2] 0 d  0.5 w 0 0  m %g 0 l s Q",color,wd_bp)
      else -- vlist
        pdfstring.data = string.format("q 0.1 G 0.1 w -0.5 0 m 0.5 0 l -0.5 %g m 0.5 %g l s [0.2] 0 d  0.5 w 0.25 0  m 0.25 %g l s Q",-wd_bp,-wd_bp,-wd_bp)
      end
      parent.list = node.insert_before(parent.list,head,pdfstring)
      -- print("Got glue; wd " .. tostring(wd))

所以,基本上,如果我想排版这些名称,我必须插入 PDF 基元;我尝试添加到(Hello world) Tjpdfstring.data但什么也没有出来。

考虑到排版 638 个名称会有点拥挤,我还会在 PDF 中排版数字索引,然后打印到标准输出包含索引、命令/长度/胶水的 LaTex 名称以及可能的宽度/长度值的列表;这应该可以让检查变得更容易一些。

我真正无法说的是这个 - 所以这些是我的问题:

  • 此时lua-visual-debug,代码中的原始 Tex 命令名称是否可用?(我可以看到 LuaTex 引用有token.command_name,但此时我有“节点”[什么节点?],而不是“令牌”)
  • 如果我启用最后一个print,我可以打印宽度;结果发现,大多数宽度都是 0,但是有些像“Got glue; wd 27571199”——这个 27571199 是bp单位吗?我怎么才能以厘米或英寸为单位打印出来?
  • 此时在 lua 代码中插入文本 PDF 基元是否可行?

答案1

好的,我想我已经找到了某个地方 - 下面的胶水标有“GL”+一个数字(我不知道它是什么意思,但在Lua中显示为任何Lua节点tostring(node)- 也是胶水节点 - 并且似乎是唯一的),它看起来像这样:

测试-unc.png

问题在于将这个数字与 Latex 源中的实际元素联系起来;luatexref-t.pdf文档中没有提到它可能意味着什么,但它提到了(粘合?)节点的一些属性,可以用来获取更好的信息。

很快,我就没有足够的时间来正确写作了——首先,参考:

下面是一个有效的 PDF 流示例:

/F1 24 Tf            % font select; must have! /F1 must be correct ref.; size (24) can be arbitrary 
0 1 0 rg 100 100 Td  % position text - text reacts on fill (rg) only!
( Hello World ) Tj   % output text
%q  1.5 w  0 0 m  30 30 l  S  Q % example line q/Q push/restore graph. stack, width, moveto, lineto
0 1 0 RG  1.5 w  0 0 m  30 30 l  S % example colored line - reacts on stroke (RG) only!

第一名inspect.luahttps://github.com/kikito/inspect.lua) 在 /path/to/texlive/2011/texmf-dist/tex/luatex/lua-visual-debug/ 目录中;然后lua-visual-debug.lua像这样进行破解:

...
module(...,package.seeall)

-- https://stackoverflow.com/questions/9168058/lua-table-dump-to-console
-- https://github.com/kikito/inspect.lua/blob/master/inspect.lua
-- this is enough
local inspectfile = assert(loadfile("/path/to/texlive/2011/texmf-dist/tex/luatex/lua-visual-debug/inspect.lua"))
local inspect = inspectfile()
print("inspect is" .. inspect(inspect))
...
function show_page_elements(parent)
...
  elseif head.id == 10 then -- glue
      local wd = head.spec.width
      ...
      local pdfstring = node.new("whatsit","pdf_literal")
      local wd_bp = math.round(wd / number_sp_in_a_pdf_point,2)
      if parent.id == 0 then --hlist
        pdfstring.data = string.format("q %s [0.2] 0 d  0.5 w 0 0  m %g 0 l s Q",color,wd_bp)
      else -- vlist
        pdfstring.data = string.format("q 0.1 G 0.1 w -0.5 0 m 0.5 0 l -0.5 %g m 0.5 %g l s [0.2] 0 d  0.5 w 0.25 0  m 0.25 %g l s Q",-wd_bp,-wd_bp,-wd_bp)
      end
      -- q: gsave; Q grestore; Tf selectfont; Td Move text position; Tj show text
--~       pdfstring.data = pdfstring.data .. "  q  0 1 0 RG  0 0 m 40 40 l  Q" -- this shows, but not color; '0 0 m' is relative!
      -- from a latex: /F8 15.0 Tf 0 0 Td (abcd)Tj should works; wrong size is rendered, wrong /F8 not - and even with all correct, if a character in string is not in the exported font, it will NOT work!
      -- so, in latex source file, make sure the used letters are output once! e.g.
      -- \node[text=white,anchor=west] at (0,0) {glueGLUE0123456789.};
      headstr = tostring(head)
      headmidnum = string.match(headstr, '.*<%s*(%d+)%s*>')
      pdfstring.data = pdfstring.data .. string.format("  q  /F1 24 Tf  0 0 Td  (GL%s) Tj  Q", tostring(headmidnum))
      parent.list = node.insert_before(parent.list,head,pdfstring)
      -- tostring(head.length):: head.length: Invalid field id length for node type glue (0)
      print("Got glue; wd " .. tostring(wd) .. "; " ..  "; " .. tostring(head))
      print("hd: " .. head.id .. ", " .. head.subtype .. ", " .. tostring(head.attr) .. ", ''" .. tostring(head.spec) .. "'', " .. tostring(head.leader) )
      -- no head.name: invalid field id name for node type glue (0)
      if (head.spec ~= nil) then
        print("hd spec: " .. head.spec.width .. ", " .. head.spec.stretch .. ", " .. head.spec.stretch_order .. ", " .. head.spec.shrink .. ", " .. head.spec.shrink_order .. ", " .. tostring(head.spec.writable))
      end
      if (head.attr ~= nil) then -- always nil
        print("attr: " .. node.fields(head.attr.id, head.attr.subtype ))
      end
      -- extract (apparently) "sequence index": the middle number in headstr='<node 126920 < 107034 > 107021'
      if (headmidnum ~= nil) then
        print("mid: " .. headmidnum)
      else print ("NO headmidnum!") end
      --print(inspect(head.tostring)) -- no __tostring() -- both invalid; no .number or .next.number
      -- print(inspect(head) .. " -- " .. inspect(getmetatable(head)) .. "--" .. inspect(node.fields(head.id, head.subtype))) -- <userdata 1>
      --~ Got glue; wd 0; ; <node 126920 < 107034 > 107021 : glue 2>
      --~ <userdata 1> -- {
      --~   __eq = <function 1>,
      --~   __index = <function 2>,
      --~   __newindex = <function 3>,
      --~   __tostring = <function 4>
      --~ }--{ "id", "subtype", "attr", "spec", "leader",
      --~   [-1] = "prev",
      --~   [0] = "next"

-- PDF font declarations - these seem to change always :(
--~ /Font
--~ <<
--~ /F47 5 0 R
--~ /F20 6 0 R
--~ /F46 7 0 R
--~ /F16 8 0 R
--~ /F45 9 0 R
--~ /F44 10 0 R
--~ /F39 11 0 R
--~ /F38 12 0 R
--~ /F35 13 0 R
--~ /F34 14 0 R
--~ /F33 15 0 R
--~ >>
...

完成后,在终端/控制台(此处使用bash)中执行以下操作:

# note that print() from lua goes to stdout - but not to Latex log!
# so capture entire stdout to another log with redirection: 
lualatex test.tex 2>&1 | tee test-lua.log

# must unpack the produced test.pdf file:
pdftk test.pdf output test-unc.pdf uncompress


# if want to make sure our literal is inserted:
# must use less -L to show entire contents:
less -L test-unc.pdf # or
grep '/F1 ' test-unc.pdf | head -2

# find one actual font reference - grep for 'GLUEgl'
# (note that regardless of \mbox, the text GLUEglue... may 
#  end up split in the .pdf!

grep 'glueGL' test-unc.pdf
# example output:
# /F15 9.96264 Tf 1 0 0 1 274.444 12.896 Tm [(glueGLU)]TJ

# now replace the `/F1 24` we had previously with a 
# proper reference (/F15) and smaller font size (5):
sed -i 's_/F1 24_/F15 5_g' test-unc.pdf

现在可以test-unc.pdf打开(例如,在 中evince),并且应该显示带标签的胶水,如上图所示。请注意,即使 PDF 查看器可能不会发出警告消息,PDF 仍会损坏,因为更改后,PDF xref 尾部可能不正确。您可能需要pdftk再次重新运行文件以尝试更正 - 但即使这样,我也无法使用 ImageMagickconvert来渲染test-unc.pdf(但我可以在 GIMP 中渲染它,这就是获得上图的方式)。

相关内容