Is there a possibility to change compiler engine depending on presence of a package
I'm on windows too. My editor, Winedt, has macro capabilities and it would be easy to write a macro to start the compilation which does want you ask for. It is also not every difficult to devise other methods with other scripts languages with similar effects.
But imho you would learn very fast to hate such automation.
It is so very easy to imagine documents where your test doesn't do what you want. Starting with documents which can be compiled with both engines, documents which should use xetex but use babel instead of polyglossia, documents where the relevant packages are buried in a preamble.tex, document where behind \end{document} are comments and rests of other documents, documents where some of the packages are commented or inside \if
-clauses, documents without fontspec or polyglossia but which should be compiled with xetex as they use pstricks, ...
It is also easy to imagine situations where you don't want an automation, e.g. if you want to compare the output of a xelatex compilation with a lualatex or pdflatex or latex + dvipdfmx compilation.
It would imho cost you much more time to handle all this situations than it would cost you to add a comment about the compilation at the top. Also you as a human are much better in deciding about the correct compilation method than a script.
EDIT: How to achieve this in WinEdt?
As simple as drinking a glass of water... (almost)
Create a file named XeORPdf.edt
in the WinEdt Appdata directory %b\Exec\TeX
with the following contents:
// 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;
Then, in your local MainMenu.ini
(open it through the options interface), add the following lines
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="-"
somewhere, let's say after the lines
MENU="TeX_Menu"
CAPTION="Te&X"
CONFIG_FILTER="Default;MiKTeX;TeX Live"
to have the new command on top of the "TeX" menu:
If you want to have it in the toolbar, too, simply add the line
BUTTON="XeORPdf"
somewhere in your local Toolbar.ini
.
Load the scripts with the "load script" icon in the options interface, or my using Options->maintenance->rebuild all
.
Now if your .tex
file contains a non-commented line like
\usepackage[...]{...,polyglossia,...}
xelatex is executed, otherwise pdflatex is.
The advantage of arara
is that you can customise the build process on a per-document basis rather than relying on a tool that has to try to work out the build sequence. It seems like overkill to use a Java application to perform something that could easily be done in a script, but if you really want to use arara
and the problem cases don't apply in your document, then here's one way to do achieve it.
Following on from @samcarter's comment, arara
v4.0 allows conditions, but you need to be quite particular about the pattern¹. For example, rather that checking for any instance of polyglossia
, check specifically for \usepackage{polyglossia}
occurring at the start of a line:
% 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}
This runs xelatex
, whereas
% 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}
runs pdflatex
and so will
% 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}
(since there's a space character between the start of the line and \usepackage{polyglossia}
).
There are some situations where this will go wrong, as already mentioned in Ulrike's answer. For example:
% 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}
or
% 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}
¹See the Pattern class documentation for a list of available regular expression constructs. It's a bit awkward as backslashes need escaping when supplying the expression as a string, so \R
indicates a line break but this needs to be written as \\R
to avoid being interpreted as a control character.
In case polyglossia
may be hidden in some other packages or subfiles or another package needs xelatex, maybe you could use an explicit error message to detect if xelatex is needed.
The following example requires arara 4.0
and an additional run if there is not yet a .log
file.
% !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}
But make sure that your images or sections are not coincidentally called cannot-use-pdftex
:)
This technique can also be used for documents, which do not need to be compiled with xelatex, but for which this is the "intended" compilation chain. For example the metropolis
beamer theme has a fallback for the compilation with pdflatex, but will tell you:
You need to compile with XeLaTeX or LuaLaTeX to use the Fira fonts