Pandoc:将 Tikz 图形和其他环境从 Latex 导出为其他格式

Pandoc:将 Tikz 图形和其他环境从 Latex 导出为其他格式

我怎样才能改变答案这个问题(使用 lua 过滤器),以便输出tikzdocx 文档中的图形,还可以从中提取内容非 pandoc 友好环境(在 v2.2.3 中默认如此),例如tcolorbox。例如,创建main.tex

\documentclass{article} 
\usepackage{amsmath,tcolorbox,tikz}

\begin{document}

\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
  Some content and an equation $a=b$
\end{tcolorbox}

\begin{center}
\begin{tikzpicture}
\draw (0,0) -- (4,4);
\end{tikzpicture} 
\end{center} 

\end{document}

如果我运行:

pandoc main.tex -t docx -o main.docx

tcolorbox我将获得docx 中的内容,但不会获得tikz图片。然而,如果我运行:

pandoc main.tex --from latex+raw_tex -t docx -o main.docx --lua-filter=tikz-to-png.lua

我会得到图片,但得不到docx 中tikz的内容。tcolorbox

我在想也许 lua-filter 代码的这一部分应该返回除 nil 之外的其他内容:

function RawBlock(el)
-- Don't alter element if it's not a tikzpicture environment
if not el.text:match'^\\begin{tikzpicture}' then
    return nil
end

看过文档在 lua-filters 上Github,我感觉我需要使用类似的东西pandoc.walk_block,但却无法弄清楚。

tcolorbox(如果能将内容放在盒子里就更好了,不过那是以后的事了)

答案1

回答我自己的问题:

我相信pandocfilters以及较新的排箫Python 包提供了一种更简单的方法来编写过滤器。稍微调整一下此过滤器做了这个伎俩:

"""
Pandoc filter to process raw latex tikz environments into images.
Assumes that pdflatex is in the path, and that the standalone
package is available.  Also assumes that ImageMagick's convert
is in the path. Images are put in the tikz-images directory.
"""

import hashlib
import re
import os
import sys
import shutil
import panflute as pf
from subprocess import Popen, PIPE, call
from tempfile import mkdtemp

imagedir = "tikz-images"

def sha1(x):
    return hashlib.sha1(x.encode(sys.getfilesystemencoding())).hexdigest()


def tikz2image(tikz, filetype, outfile):
    tmpdir = mkdtemp()
    olddir = os.getcwd()
    os.chdir(tmpdir)
    f = open('tikz.tex', 'w')
    f.write("""\\documentclass{standalone}
             \\usepackage{tikz}
             \\begin{document}
             """)
    f.write(tikz)
    f.write("\n\\end{document}\n")
    f.close()
    p = call(["pdflatex", 'tikz.tex'], stdout=sys.stderr)
    os.chdir(olddir)
    if filetype == 'pdf':
        shutil.copyfile(tmpdir + '/tikz.pdf', outfile + '.pdf')
    else:
        call(["convert", tmpdir + '/tikz.pdf', outfile + '.' + filetype])
    shutil.rmtree(tmpdir)


def action(elem, doc):
    """
    return None -> element unchanged
    return [] -> delete element

    """
    if type(elem) == pf.RawBlock and elem.format == "latex":

        code = elem.text

        if code.strip().startswith(r"\begin{tikzpicture}"):
            outfile = imagedir + '/' + sha1(code)
            filetype = {'html': 'png', 'latex': 'pdf'}.get(doc.format, 'png')
            src = outfile + '.' + filetype
            if not os.path.isfile(src):
                try:
                    os.mkdir(imagedir)
                    sys.stderr.write('Created directory ' + imagedir + '\n')
                except OSError:
                    pass
                tikz2image(code, filetype, outfile)
                sys.stderr.write('Created image ' + src + '\n')

            return pf.Para(pf.Image(url=src))
        else:
            return pf.convert_text(code, input_format="latex")

def main(doc=None):
    return pf.run_filter(action, doc=doc)

if __name__ == "__main__":
   main()

特别是,该行return pf.convert_text(code, input_format="latex")确保所有其他 raw_tex 都得到处理。

相关内容