如何在使用 pandoc 从 .tex 转换的 .docx 文件中生成居中并带有标题的 TikZ 图形?

如何在使用 pandoc 从 .tex 转换的 .docx 文件中生成居中并带有标题的 TikZ 图形?

最近,我在 LaTeX 中使用 TikZ 时遇到了一些问题。我想使用 pandoc 将我的博士论文(用 LaTeX 编写)转换为 .docx。我能够使用 lua 过滤器让 pandoc 转换 TikZ 图像,感谢帮助这里

然而,一个小问题仍然存在。在 .docx 文件中,TikZ 图像未居中。我的标题也没有包括在内:似乎 pandoc 只是忽略了\begin{figure}我随后添加的这些命令。

问题

如何为使用 pandoc 转换的 .docx 文件中的 TikZ 图形添加标题并将其置于中心?

我可能正在寻找解决方案,但由于我缺乏编程经验,所以我不知道如何解决这个问题。

这是我的 .tex 文件:

\documentclass[a4paper,12pt]{book}
\usepackage{graphicx}
\usepackage[english]{babel}

\usepackage{tikz}

\begin{document}

 \begin{figure}
    
   \centering

    \begin{tikzpicture}

             \draw circle(5cm);
    
    \end{tikzpicture}
    
  \caption{Admire my circle!}

\end{figure}

\end{document}

这是我的 .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

--- 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\\usetikzlibrary{arrows.meta,positioning}\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

这是我在终端中输入的命令:

pandoc -s --from latex+raw_tex --lua-filter=tikz.lua test.tex -o test.docx

答案1

我做过类似的事情,从以下示例开始pandoc.org/lua-filters.html#building-images-with-tikz

最重要的是,过滤器会查找以 '\begin{tikzpicture}' 开头的原始 LaTeX 块,而您的块以 '\begin{figure}' 开头。您可以将前者替换为后者。

然后我修改了“tikz_doc_template”以供我使用。

这是我使用的过滤器:gitlab.com/twsh/pandoc-lua-filters/-/blob/master/tikz-qtree.lua

--[[ Turn figure environments into SVG images
Links are relative
Only one tikzpicture per block
If there is a \caption{...}, set the title text to ...;
pandoc will turn this into a <figcaption> for HTML.
It is assumed that the caption finishes at a line break ]]

local system = require 'pandoc.system'

local tikz_doc_template =
[[
\documentclass{standalone}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz-qtree}
\usepackage{amsmath}
\begin{document}
%s
\end{document}
]]

local function tikz2image(src, 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')
                    os.execute('pdf2svg tikz.pdf ' .. outfile)
                end
            )
        end
    )
end

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)
    tikz = el.text:match('\\begin{tikzpicture}(.+)\\end{tikzpicture}')
    if tikz then
        local fname = pandoc.sha1(tikz) .. '.' .. 'svg'
        local fpath = system.get_working_directory() .. '/' .. fname
        if not file_exists(fpath) then
            tikz2image(tikz, fpath)
        end
        local caption = el.text:match('\\caption{(.+)}\n')
        if caption then
            local caption_text = pandoc.utils.stringify(pandoc.read(caption, 'latex').blocks)
            return pandoc.Para({pandoc.Image({pandoc.Str(caption_text)}, fname, 'fig:')})
        else
            return pandoc.Para({pandoc.Image({}, fname, 'fig:')})
        end
    else
        return el
    end
end

答案2

作为一名连环潜水员,我没有资格发表评论。对此我深表歉意。

Image Magick 似乎在版本 7 及更高版本中将其命令从“转换”更新为“Magick”(https://imagemagick.org/script/command-line-tools.php)。进行这样的编辑使得我也可以通过 Image Magick 路线使用它。

相关内容