如何强制 xelatex 将 eps 转换为 pdf?xelatex 编译速度慢的问题

如何强制 xelatex 将 eps 转换为 pdf?xelatex 编译速度慢的问题

我做了几个简单的测试,对比了一下pdflatex和xelatex的编译速度,和大多数人说的一样,我也发现xelatex总是比pdflatex慢很多。

我发现 xelatex 速度慢的原因是 xelatex 中的 eps 转换过程。

我使用 Adob​​e Illustrator 创建的 eps 图像文件,eps 文件的平均大小为 1MB。似乎每次我使用 xelatex 编译时,转换 eps 文件都会花费相当多的时间。但 pdflatex 在第一次编译时只使用“epstopdf”包将 eps 转换为 pdf。第一次编译后,pdflatex 只使用转换后的 pdf 图像文件。好消息是,这些转换后的 pdf 图像文件比原始 eps 文件小得多,只有 20K 左右。

我尝试在xelatex中使用pdflatex生成的pdf图像文件,确实大大加快了编译速度,虽然还是没有pdflatex快,但也取得了很大的进步。

但是“epstopdf”在 xelatex 中不起作用。有没有其他方法可以强制 xelatex 动态将 eps 图像转换为 pdf 文件,这样它就可以从第一次编译开始就使用 pdf 图像文件,就像 pdflatex 中的“epstopdf”一样?

答案1

为什么epstopdf file.eps不在运行 xelatex 之前简单地调用一次来转换你的 eps?

除此之外:当文件不存在时,动态转换文件并不困难。例如使用以下命令编译此文件xelatex --shell-escape

\documentclass{article}
\usepackage{graphicx}
\begin{document}
\IfFileExists{testeps1.pdf}{}{\immediate\write18{epstopdf testeps1.eps}}
\includegraphics{testeps1}
\end{document}

但是 epstopdf 不仅在文件不存在时才进行转换,还会比较文件日期并在 eps 发生更改时更新文件,而这在 xelatex 中更难实现,因为所使用的某些原语似乎不存在。因此,当您更改 eps 时,您必须确保再次触发转换。

答案2

如果您的文档变得越来越复杂,您应该考虑实现自动化。

一个很好的工具就是 Make: http://gnuwin32.sourceforge.net/packages/make.htm

您必须编写一个Makefile,这是一个简单的文本文件(但没有结尾)。Makefile 是一组规则,描述了如何target制作 以及它具有哪些依赖关系。

所有规则看起来都与此类似:

target: dependecy1 dependency2 ... 
       command1
       command2

当您在包含 Makefile 的目录中调用简单命令时make,make 会运行它遇到的第一条规则。它会构建依赖项树并从上到下处理它们。它会检查哪些文件是依赖项,是否比上一个目标版本更新,并在必要时运行命令。

按照惯例,第一条规则应该是all,它应该构成您的最终目标。

因此,对于使用 biblatex/biber 的包含参考书目的 LaTeX 案例,它可能看起来像这样:

all: mydocument.pdf

mydocument.pdf: mydocument.tex myreferences.tex
    xelatex mydocument.tex
    biber mydocument.bcf
    xelatex mydocument.tex
    xelatex mydocument.tex

如果您需要将图形从 eps 转换为 pdf,那么将它们放入自己的文件夹中并定义将它们转换为 pdf 的规则是有意义的。

这看起来像这样:

all: mydocument.pdf

mydocument.pdf: mydocument.tex converted/fig1.pdf converted/fig2.pdf
    xelatex mydocument.tex

converted/%.pdf: epsfigures/%.pdf
     epstopdf $< --outfile=$@

$@是目标文件的名称,$<是第一个依赖项,请参阅https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html.%匹配所有带有其周围模式的文件。

但是,这需要converted目录存在。因此,应该添加一条规则来创建目录并将其添加为静态依赖项(静态依赖项不会检查日期,它们只需存在即可。)。这些依赖项位于常规依赖项之后,以竖线分隔|

all: mydocument.pdf

mydocument.pdf: mydocument.tex converted/fig1.pdf converted/fig2.pdf
    xelatex mydocument.tex

converted/%.pdf: epsfigures/%.pdf | converted
     epstopdf $< --outfile=$@

converted:
    mkdir -p converted

另一个方便的约定是,应该有一个名为的规则clean,它删除 Makefile 创建的所有输出。这里 tex 选项--output-directory=<dir>就派上用场了。如果我们使用目录构建 LaTeX 输出,则 clean 方法只需删除buildconverted。此外,如果您使用像 make 这样的自动构建系统,TeX 通常不会在发生错误时停止。

为了向您展示 Makefile 如何处理变量,我将 texoption 放在一个变量中:

texoptions = --interaction=nonstopmode --output-directory=build
all: build/mydocument.pdf

build/mydocument.pdf: mydocument.tex converted/fig1.pdf converted/fig2.pdf | build
    xelatex $(texoptions) mydocument.tex

converted/%.pdf: epsfigures/%.pdf | converted
     epstopdf $< --outfile=$@

converted:
    mkdir -p converted

build:
    mkdir -p build


clean:
    rm -rf build
    rm -rf converted

您可以通过 调用单个规则make <rule>。因此make clean将删除您创建的所有文件以进行全新启动,例如在发生错误后。

答案3

我自己想出了一个办法,而且效果还不错。所以我在这里回答我自己的问题。这是一种使用外部 .bat 的方法,分三步。

第一的,在latex目录下建立一个名为bat的文件conversion.bat,内容如下

SETLOCAL ENABLEDELAYEDEXPANSION

for %%G in (*.eps) do @if not exist "%%~nG.pdf" (epstopdf "%%G") else (
(for /f "delims=" %%i in ('dir /B /O:D "%%G" "%%~nG.pdf"') do set newest=%%~xi) & (
if !newest!==.eps echo "%%G" modification time is newer & (epstopdf "%%G") else (
(for /f "delims=" %%i in ('dir /B /T:C /O:D "%%G" "%%~nG.pdf"') do set newest=%%~xi) & (
if !newest!==.eps echo "%%G" creation time is newer & (epstopdf "%%G")))))

说明:上述 cmd 批处理代码将首先比较 .eps 和 .pdf 的修改时间,如果有修改时间较新的 .eps 文件则运行epstopdf转换。然后比较 .eps 和 .pdf 的创建时间,并转换较新的 .eps 文件。

第二,在你的 latex 文档中,添加

\begin{document}
\immediate\write18{conversion.bat}

text here

\end{document}

第三,如果您使用winedt设置option-->excution modes-->console application-->xelatex-->switches--shell-escape

现在编译您的文档。外部conversion.bat将自动处理 .eps 到 .pdf 的转换

相关内容