是否有可能根据包的存在来改变编译器引擎

是否有可能根据包的存在来改变编译器引擎

我习惯同时使用pdflatexxelatex引擎来编译我的文档,xelatex以防.tex文件包含polyglossia包和pdflatex其他文件

我的问题是,是否有一种方法(使用 latexmk 或 arara 或任何其他程序)可以有条件地编译我的文档

if tex file contain "polyglossia" then 
  use xelatex 
else 
  use pdflatex
fi 

注意:我的电脑上有 Windows 操作系统。

答案1

我也在 Windows 上。我的编辑器 Winedt 具有宏功能,编写宏来启动编译很容易,这正是您所需要的。使用其他脚本语言设计具有类似效果的其他方法也并不困难。

但恕我直言,你很快就会讨厌这种自动化。

很容易想象到您的测试无法达到预期效果的文档。从可以使用两种引擎编译的文档开始,应该使用 xetex 但使用 babel 而不是 polyglossia 的文档,相关包埋在 preamble.tex 中的文档,\end{document} 后面是注释和其他文档的其余部分的文档,一些包被注释或在\if-clauses 中的文档,没有 fontspec 或 polyglossia 但应该使用 xetex 编译的文档,因为它们使用 pstricks,...

还很容易想象您不想要自动化的情况,例如,如果您想将 xelatex 编译的输出与 lualatex 或 pdflatex 或 latex + dvipdfmx 编译的输出进行比较。

我认为处理所有这些情况要比在顶部添加关于编译的注释花费更多的时间。此外,作为人类,你在决定正确的编译方法方面比脚本要好得多。


编辑:如何在 WinEdt 中实现这一点?

就像喝一杯水一样简单......(几乎)

XeORPdf.edt在 WinEdt Appdata 目录中创建一个名为的文件%b\Exec\TeX,其内容如下:

// xelatex or pdflatex?

PushTagsandRegisters;

  GetPreamble("\begin{document}",9);
  FindInString("%!9","<@{ }\\usepackage@{\[**\]}\{@^{\}|%%|polyglossia}polyglossia{,| |\}}",7,8,11);
  IfNum(%!7,%!8,"<",!"Exe('%b\Exec\TeX\XeLaTeX.edt');",!"Exe('%b\Exec\TeX\PDFLaTeX.edt');");

PopTagsandRegisters;

End;

然后,在你的本地MainMenu.ini(通过选项界面打开)添加以下几行

  ITEM="XeORPdf"
    CAPTION="XeLaTeX or PDFLaTeX"
    IMAGE="Question"
    SAVE_INPUT=1
    MACRO="Exe('%b\Exec\TeX\XeORPdf.edt');"
    REQ_FILTER=:"%!M=TeX"|"%!M=TeX:STY"|"%!M=TeX:AUX"
  ITEM="-"

在某处,比如说在以下几行之后

MENU="TeX_Menu"
  CAPTION="Te&X"
  CONFIG_FILTER="Default;MiKTeX;TeX Live"

将新命令放在“TeX”菜单的顶部:

在此处输入图片描述

如果你也想将它添加到工具栏中,只需添加以下行

  BUTTON="XeORPdf"

在您所在地区的某处Toolbar.ini

使用选项界面中的“加载脚本”图标来加载脚本,或者我使用Options->maintenance->rebuild all

现在如果你的.tex文件包含一个非注释行,例如

\usepackage[...]{...,polyglossia,...}

执行 xelatex,否则执行 pdflatex。

答案2

其优点arara是,您可以根据每个文档自定义构建过程,而不必依赖必须设法确定构建顺序的工具。使用 Java 应用程序执行可以在脚本中轻松完成的操作似乎有些过分,但如果您确实想使用arara并且问题案例不适用于您的文档,那么这里有一种方法可以实现它。

根据 @samcarter 的评论,ararav4.0 允许条件,但您需要对模式¹ 非常挑剔。例如,不是检查 的任何实例polyglossia,而是专门检查 是否\usepackage{polyglossia}出现在行首:

% arara: xelatex if found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
% arara: pdflatex unless found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
\documentclass{article}

\usepackage{polyglossia}

\begin{document}
Test.
\end{document}

这将运行xelatex,而

% arara: xelatex if found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
% arara: pdflatex unless found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
\documentclass{article}

%\usepackage{polyglossia}

\begin{document}
Test.
\end{document}

运行pdflatex,也将运行

% arara: xelatex if found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
% arara: pdflatex unless found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
\documentclass{article}

 \usepackage{polyglossia}

\begin{document}
Test.
\end{document}

(因为行首和 之间有一个空格字符\usepackage{polyglossia})。

在某些情况下,这会出错,正如 Ulrike 的回答中提到的那样。例如:

% arara: xelatex if found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
% arara: pdflatex unless found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
\documentclass{article}

\begin{document}
\begin{verbatim}
\usepackage{polyglossia}
\end{verbatim}
\end{document}

或者

% arara: xelatex if found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
% arara: pdflatex unless found("tex", "\\R\\\\usepackage\\{polyglossia\\}")
\documentclass{article}

\newif\ifusepoly
\usepolyfalse

\ifusepoly
\usepackage{polyglossia}
\else
\usepackage{babel}
\fi

\begin{document}
Test.
\end{document}

¹查看模式类文档以获取可用正则表达式构造的列表。这有点尴尬,因为在将表达式作为字符串提供时,反斜杠需要转义,因此\R表示换行符,但需要这样写以\\R避免被解释为控制字符。

答案3

如果polyglossia可能隐藏在其他包或子文件中,或者另一个包需要 xelatex,也许您可​​以使用明确的错误消息来检测是否需要 xelatex。

arara 4.0如果尚无文件,则以下示例需要额外运行.log

% !TeX program = txs:///arara
% arara: pdflatex: {interaction: nonstopmode} if !exists('log') 
% arara: pdflatex: {interaction: nonstopmode} if exists('log') && !found('log', 'cannot-use-pdftex') 
% arara: xelatex: {interaction: nonstopmode} if exists('log') && found('log', 'cannot-use-pdftex') 

\documentclass{article}
\usepackage{polyglossia}

\begin{document}
test
\end{document}

但请确保您的图像或部分名称不是巧合cannot-use-pdftex:)


此技术还可用于不需要使用 xelatex 编译但这是“预期”编译链的文档。例如,metropolisbeamer 主题有一个使用 pdflatex 编译的后备方案,但会告诉您:

您需要使用 XeLaTeX 或 LuaLaTeX 进行编译才能使用 Fira 字体

答案4

使用的示例ifxetex应该ifluatex适用于任何编译器:

\documentclass{article}
\usepackage{ifxetex,ifluatex}
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
  \usepackage[T1]{fontenc}
  \usepackage[utf8]{inputenc}
  \usepackage[spanish]{babel}
  \def\xxx{using \texttt{pdflatex}}
\else % if luatex or xelatex
  \ifxetex
    \usepackage{mathspec}
    \usepackage{polyglossia}
  \def\xxx{using \texttt{xetex}}
  \else
    \usepackage{fontspec}
    \usepackage{polyglossia}
    \def\xxx{using \texttt{luatex}}
  \fi
  \defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase}
\fi

\begin{document}
Test \xxx
\end{document}

相关内容