我正在尝试解决代码中发生的问题图片/绘图与表格组图的位置(和/或大小)错误(......和不连续性)?。因此我\usepackage{lua-visual-debug}
在该示例中添加了内容,并用 构建了它lualatex test.tex
;结果如下:
据我所知(通过查阅 的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) Tj
,pdfstring.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)
- 也是胶水节点 - 并且似乎是唯一的),它看起来像这样:
问题在于将这个数字与 Latex 源中的实际元素联系起来;luatexref-t.pdf
文档中没有提到它可能意味着什么,但它提到了(粘合?)节点的一些属性,可以用来获取更好的信息。
很快,我就没有足够的时间来正确写作了——首先,参考:
- 如何生成在文档查看器中有效的纯文本源代码 PDF 示例? - VoidCC
- Imagemagick:为 PDF flate 嵌入生成原始图像数据? - VoidCC
- Lua初学者:表转储到控制台 - 代码日志
- 如何在lua中检查用户数据 - 代码日志
- 我怎样才能将盒子形象化? - TeX - LaTeX Stack Exchange
下面是一个有效的 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.lua
(https://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 中渲染它,这就是获得上图的方式)。