如何加快 tex4ht 图像生成过程?

如何加快 tex4ht 图像生成过程?

目前,我告诉 tex4ht 使用 svg 而不是 png 来处理数学图像。这样可以提高图像质量。但是,它在图像生成方面很慢,因为每次生成每个图像需要大约 1-2 秒的时间,因为它必须加载 idv 文件来为每个数学表达式生成每个图像。

有没有办法加快这个过程?我将描述我目前使用的流程以供参考。

我编辑 sudo vi /usr/local/texlive/2014/texmf-dist/tex4ht/base/unix/tex4ht.env并添加了以下两行

G.svg
Gdvisvgm -n -p %%2 -c 1.2,1.2 -s %%1 > %%3

如图所示

Mathematica 图形

接下来,编辑我的 tex4ht cfg 文件(称为 nma.cfg)并添加 svg 条目

 \Preamble{ext=htm,charset="utf-8",p-width,pic-align}
  \Configure{Picture}{.svg}  
  \makeatletter
  \Configure{graphics*}
  {svg}
  {
    {\Configure{Needs}{File: \[email protected]}\Needs{}}
    \Picture[\csname a:GraphicsAlt\endcsname]{\csname Gin@base\endcsname.svg
            \csname a:Gin-dim\endcsname}
  }
  \begin{document}
  \EndPreamble

接下来,我在 latex 文件上调用 tex4ht,如下所示

  make4ht -u foo.tex "nma,htm,pic-align,notoc*"

在哪里make4ht找到https://github.com/michal-h21/make4ht

如果你没有make4ht安装,那么命令

  htlatex foo.tex "nma,htm,pic-align,charset=utf-8,notoc*" " -cunihtf -utf8"

也可以。下面是包含 2 个方程的 foo.tex,它们将生成 2 幅图像

\documentclass[11pt]{article}
\usepackage{graphicx} %must be included
\begin{document}    
\[
  x = \sin(y)
\]
and
\[
  x2 = \sin(y)
\]    
\end{document}

现在我们看到 tex4ht 每次为每张图片加载 idv:

......
t4ht.c (2012-07-25-19:28 kpathsea)
t4ht -f/foo.tex 
(/usr/local/texlive/2014/texmf-dist/tex4ht/base/unix/tex4ht.env)

Entering foo.lg
System call: dvisvgm -n -p 1 -c 1.2,1.2 -s foo.idv > fo0x.svg
processing page 1
  page size: 58.1681pt x 13.0909pt (20.4437mm x 4.60093mm)
  page written to <stdout>
1 of 2 pages converted in 0.244021 seconds
System return: 0

System call: dvisvgm -n -p 2 -c 1.2,1.2 -s foo.idv > fo1x.svg
processing page 2
  page size: 64.7136pt x 13.0909pt (22.7442mm x 4.60093mm)
  page written to <stdout>
1 of 2 pages converted in 0.243742 seconds
System return: 0

有没有办法加快速度,避免每次为每个方程式加载 idv,而是一次性完成所有操作?目前,构建我的大型 latex 文件需要 4 天时间,我需要一种方法来加快速度。

答案1

每个生成的图片都放在一个特殊文件中的自己的页面上dvi,扩展名为idv。默认情况下,tex4ht分别在每个页面上调用转换命令,这通常不是问题,除非您有很多页面。在这种情况下,使用一个命令转换文件中的所有页面可能会更快idv。问题是我们无法以我们需要的方式命名输出文件,因此我们必须在转换后重命名它们。

如果您调用dvisvgm转换所有页面:

dvisvgm -n -p 1- 文件名.idv

文件将被命名为filename-01.svg,但我们需要它们被命名为filename0x.svg

可以使用make4ht构建文件来修复这个问题:

Make:add("dvisvgm","dvisvgm -n -TS1.25,1.25 -c 1.2,1.2 -p 1- ${input}.idv")

local max_count = 5
local image_format = "${input}-${zeroes}${page}.${ext}"
local oneimage_format = "${input}.${ext}"


local function file_exists(fn)
  local f = io.open(fn,"r")
  if f ==  nil then return false else f:close() return true end
end



local function locate_file(par,ext, count)
  local count = count or 0
  par.ext = ext
  local zeroes = string.rep("0",count)
  par.zeroes = zeroes
  if count > max_count then 
        local one = oneimage_format % par
        if file_exists(one) then
            return one
        else
          return false, "max_count exceeded" 
        end
    end
  local fn = image_format % par
  if file_exists(fn) then 
    return fn
  else 
    return locate_file(par, ext, count+1)
  end
end

Make:htlatex{}
Make:htlatex{}
Make:htlatex{}
Make:tex4ht{}
Make:t4ht{}

Make:dvisvgm{}
Make:image("svg$",function(arg)
   arg.input = arg.source:gsub(".idv$","")
   local fn,msg = locate_file(arg, "svg")  
   if not fn then
     print("Image processing error: "..msg)
   else
     arg.filename = fn
     local cmd = "mv ${filename} ${output}" % arg
     print(cmd)
     os.execute(cmd)
   end
 end
)

我们应该稍微传播一下这个文件:

Make:add("dvisvgm","dvisvgm -n -c 1.2,1.2 -p 1- ${input}.idv")

这个注册新命令,dvisvgm它将从idv文件中提取所有 svg 文件。${input}是用输入文件名替换的特殊指令。

Make:htlatex{}
Make:tex4ht{}
Make:t4ht{}
Make:dvisvgm{}

这是构建顺序,LaTeX 仅被调用一次,如果您使用 toc 或引用,您可能需要添加更多Make:htlatex调用。idv 文件是在tex4ht运行后创建的,因此我们需要显式调用Make:tex4ht{}Make:t4ht{},然后调用Make:dvisvgm{}

Make:image("svg$",function(arg)
   arg.input = arg.source:gsub(".idv$","")
   local fn,msg = locate_file(arg, "svg")  
   if not fn then
     print("Image processing error: "..msg)
   else
     arg.filename = fn
     local cmd = "mv ${filename} ${output}" % arg
     print(cmd)
     os.execute(cmd)
   end
 end
)

每个图像都会调用此函数。arg是具有图像属性的表,即idv文件名、页码和输出文件。要构造文件,我们需要.idv从中删除后缀来获取基本名称arg.source。我们尝试使用函数查找 svg 文件名locate_file,当我们找到它时,它会被移动到正确的位置,即变量中arg.output

local function locate_file(par,ext, count)
  local count = count or 0
  par.ext = ext
  local zeroes = string.rep("0",count)
  par.zeroes = zeroes
  if count > max_count then 
        local one = oneimage_format % par
        if file_exists(one) then
            return one
        else
          return false, "max_count exceeded" 
        end
    end
  local fn = image_format % par
  if file_exists(fn) then 
    return fn
  else 
    return locate_file(par, ext, count+1)
  end
end

因为我们不知道生成的确切文件名,所以dvisvgm我们需要找到它。由于dvisvgm可能会在页码前添加前导零,情况变得更加糟糕,因此当我们第一次尝试找不到该文件时,我们需要尝试几种可能性。

将 make 文件另存为foo.mk4。从命令行输出:

Make4ht: dvisvgm -n -c 1.2,1.2 -p 1- foo.idv
processing page 1
  page size: 58.1681pt x 13.0909pt (20.4437mm x 4.60093mm)
  page written to foo-01.svg
processing page 2
  page size: 64.7136pt x 13.0909pt (22.7442mm x 4.60093mm)
  page written to foo-02.svg
2 of 2 pages converted in 0.193865 seconds

和:

mv foo-01.svg foo0x.svg
mv foo-02.svg foo1x.svg

结果:

在此处输入图片描述

相关内容