我想要做的是使用 pandoc 将包含多个 TikZ 图形的 .tex 文件转换为 .docx 文件。我尝试遵循 pandoc 文档并使用 lua 过滤器来实现此目的。问题:每当我使用 lua 过滤器时,都会生成一个仅包含我的 .tex 文件标题的文件,而文件的其余部分都会被省略。我也看不到 TikZ 图形。
这是我在命令行中对 pandoc 的输入:
pandoc --from latex+raw_tex --lua-filter=tikz.lua -s file.tex -o test.docx
我的 lua 过滤器文件(tikz.lua)是从建议的原始过滤器更改而来的潘多克,根据给出的建议这个帖子。我已对该文件逐一采纳了所建议的更改:
local function file_exists(name)
local f = io.open(name, 'r')
if f ~= nil then io.close(f); return true
else return false end
end
function RawBlock(el)
-- Don't alter element if it's not a tikzpicture environment
if not el.text:match'^\\begin{tikzpicture}' then
return nil
-- Alternatively, parse the contained LaTeX now:
-- return pandoc.read(el.text, 'latex').blocks
end
local fname = pandoc.sha1(el.text) .. ".png"
if not file_exists(fname) then
tikz2image(el.text, fname)
end
return pandoc.Para({pandoc.Image({}, fname)})
end
--- Create a standalone LaTeX document which contains only the TikZ picture.
--- Convert to png via Imagemagick.
local function tikz2image(src, outfile)
local tmp = os.tmpname()
local tmpdir = string.match(tmp, "^(.*[\\/])") or "."
local f = io.open(tmp .. ".tex", 'w')
f:write("\\documentclass{standalone}\n")
-- include all packages needed to compile your images
f:write("\\usepackage{tikz}\n\\usepackage{stanli}\n")
f:write("\\begin{document}\n")
f:write(src)
f:write("\n\\end{document}\n")
f:close()
os.execute("pdflatex -output-directory " .. tmpdir .. " " .. tmp)
os.execute("convert " .. tmp .. ".pdf " .. outfile)
os.remove(tmp .. ".tex")
os.remove(tmp .. ".pdf")
os.remove(tmp .. ".log")
os.remove(tmp .. ".aux")
end
pdflatex 和 pdf2svg 以及 ImageMagick 都已安装。
简而言之,我应该可以走了,但出了点问题,我只看到我的标题。任何建议都欢迎!
这是我的代码:
\documentclass{book}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,positioning}
\begin{document}
\begin{tikzpicture}
\draw (0,0) -- (4,0);
\end{tikzpicture}
\end{document}
在 TexStudio 中渲染为 .pdf 文件时,会显示 TikZ 图形。使用 pandoc 时,没有任何反应。
希望您能发现我遗漏了什么!
答案1
过滤器会抛出错误,因为convert
不喜欢制作灰度 PNG。解决方案是添加选项。-colorspace RGB
最后,ImageMagick 似乎还有其他问题,所以我建议使用pdftoppm -png
poppler 工具反而:
local function file_exists(name)
local f = io.open(name, 'r')
if f ~= nil then io.close(f); return true
else return false end
end
--- Create a standalone LaTeX document which contains only the TikZ picture.
--- Convert to png via Imagemagick.
local function tikz2image(src, outfile)
local tmp = os.tmpname()
local tmpdir = string.match(tmp, "^(.*[\\/])") or "."
-- local tmpdir = "."
local f = io.open(tmp .. ".tex", 'w')
f:write("\\documentclass{standalone}\n")
-- include all packages needed to compile your images
f:write("\\usepackage{tikz}\n\\usepackage{stanli}\n")
f:write("\\begin{document}\n")
f:write(src)
f:write("\n\\end{document}\n")
f:close()
os.execute("pdflatex -output-directory " .. tmpdir .. " " .. tmp)
-- os.execute("convert " .. tmp .. ".pdf " .. "-colorspace RGB " .. outfile)
os.execute("pdftoppm -png " .. tmp .. ".pdf " .. "> " .. outfile)
os.remove(tmp .. ".tex")
os.remove(tmp .. ".pdf")
os.remove(tmp .. ".log")
os.remove(tmp .. ".aux")
end
function RawBlock(el)
-- Don't alter element if it's not a tikzpicture environment
if not el.text:match'^\\begin{tikzpicture}' then
return nil
-- Alternatively, parse the contained LaTeX now:
-- return pandoc.read(el.text, 'latex').blocks
end
local fname = pandoc.sha1(el.text) .. ".png"
if not file_exists(fname) then
tikz2image(el.text, fname)
end
return pandoc.Para({pandoc.Image({}, fname)})
end
如果您使用更复杂的 tikz 代码,请不要忘记将使用的库和包添加到过滤器中
您还可以扩展原装过滤器覆盖.docx
:
local system = require 'pandoc.system'
local tikz_doc_template = [[
\documentclass{standalone}
\usepackage{xcolor}
\usepackage{tikz}
\begin{document}
\nopagecolor
%s
\end{document}
]]
local function tikz2image(src, filetype, outfile)
system.with_temporary_directory('tikz2image', function (tmpdir)
system.with_working_directory(tmpdir, function()
local f = io.open('tikz.tex', 'w')
f:write(tikz_doc_template:format(src))
f:close()
os.execute('pdflatex tikz.tex')
if filetype == 'pdf' then
os.rename('tikz.pdf', outfile)
elseif filetype == 'png' then
os.execute("pdftoppm -png tikz.pdf > " .. outfile)
else
os.execute('pdf2svg tikz.pdf ' .. outfile)
end
end)
end)
end
extension_for = {
docx = 'png',
html = 'svg',
html4 = 'svg',
html5 = 'svg',
latex = 'pdf',
beamer = 'pdf' }
local function file_exists(name)
local f = io.open(name, 'r')
if f ~= nil then
io.close(f)
return true
else
return false
end
end
local function starts_with(start, str)
return str:sub(1, #start) == start
end
function RawBlock(el)
if starts_with('\\begin{tikzpicture}', el.text) then
local filetype = extension_for[FORMAT] or 'svg'
local fname = system.get_working_directory() .. '/' ..
pandoc.sha1(el.text) .. '.' .. filetype
if not file_exists(fname) then
tikz2image(el.text, filetype, fname)
end
return pandoc.Para({pandoc.Image({}, fname)})
else
return el
end
end
与以下文档一起使用:
\documentclass{book}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,positioning}
\begin{document}
\begin{tikzpicture}
\draw[fill] (1,2) circle (100pt);
\end{tikzpicture}
\end{document}
在命令行上:
pandoc --from latex+raw_tex --lua-filter=tikz.lua -s file.tex -o test.docx