我做了几个简单的测试,对比了一下pdflatex和xelatex的编译速度,和大多数人说的一样,我也发现xelatex总是比pdflatex慢很多。
我发现 xelatex 速度慢的原因是 xelatex 中的 eps 转换过程。
我使用 Adobe 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 方法只需删除build
和converted
。此外,如果您使用像 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 的转换