如何使用 pandoc 将包含 TikZ 图形的 .tex 文件转换为 .docx 文件?

如何使用 pandoc 将包含 TikZ 图形的 .tex 文件转换为 .docx 文件?

我想要做的是使用 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 -pngpoppler 工具反而:

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

在此处输入图片描述

相关内容