Re: iftex, ifpdf, ifxetex, ifluatex

#87153
Up
0
Down
::

OldClaudio” post=86566Probabilmente vi comunico un segreto di Pulcinella.

Finora ho usato il pacchetto ifpdf per sapere se stavo componendo con pdflatex piuttosto che con latex o xelatex; e la cosa funzionava. poi ho provato a lanciare la compilazione di un documento la cui classe conteneva impostazioni diverse soggette alla verifica eseguita con [tt]\ifpdf[/tt]; con pdflatex funzionava dovere; con xelatex funzionava a dovere, con lualatex dava errori di ogni genere.

Allora ho scoperto il nuovissimo documento di riferimento lualatex-doc.pdf (leggibile con texdoc lualatex) del 5 maggio scorso e trovato ora per la prima volta su MacTeX 2013. Ottimo documento, con moltissime notizie interessanti. Ma la cosa più importante è quanto si trova scritto nel §2.2.2 “Engine and mode detection”, dal quale ho appreso che \ifpdf esegue solo un controllo su il valore contenuto nel contatore interno \pdfoutput; se questo valore vale 0 il documento viene composto in formato DVI e se vale qualunque numero maggiore di 0 il documento viene composto in pdf. Questo lo sapevo da quando esiste pdflatex, quindi non sono rimasto sorpreso. Sono invece rimasto sorpreso che anche laltex/lualatex usa lo stesso contatore interno emntre xelatex non ne fa uso (infatti il suo autput è in formato dvi esteso, ma lanciando xelatex questo si occupa anche della conversione immediata in formato pdf, quindi uno si dimentica facilmente che il formato pdf non è quello nativo di xetex/xelatex).

Ecco perché con lualatex la mia compilazione soggetta al controllo di \ifpdf falliva miseramente.

Ci sono allora i pacchetti ifxetex e ifluatex che permettono di contorllare il tipo di programma in uso. Ma non c’è un pacchetto equivalente ifpdftex; che faccia la stessa cosa.

Invece esiste il pacchetto \iftex che definisce i tre test \ifPDFTeX, \ifXeTeX e \ifLuaTeX, che invece effettivamente scoprono con quale motore di composizione si sta lavorando.

Ecco quindi: scrittori di classi e di pacchetti, usate il nuovissimo pacchetto iftex se volete sapere con quale motore sta girando la vostra classe o il vostro pacchetto; la cosa non riguarda la compilazione normale, ma riguarda la scrittura/creazione di classi o pacchetti che sappiano da soli che cosa fare in caso che debbano eseguire impostazioni diverse a seconda del motore di composizione.

Non è che iftex mi piaccia più di tanto. Che dici di questo checkengine?
`\RequirePackage{expl3}
\GetIdInfo$Id: checkengine.dtx 0.1 2013-06-25 12:00:00Z Enrico $
{Checks for the typesetting engine}
\ProvidesExplPackage
{\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}

\RequirePackage{pdftexcmds}

\msg_new:nnnn { checkengine } { wrong-engine }
{ Engine~is~not~#1~as~required }
{ You~have~required~#1~but~you~are~using~a~different~engine }

\msg_new:nnnn { checkengine } { wrong-output }
{ Output~is~not~#1~as~required }
{ You~have~required~#1~but~the~current~output~format~is~different }

\msg_new:nnnn { checkengine } { shell-escape }
{ Shell~escape~not~unrestricted }
{ You~have~required~the~unrestricted~shell~escape~but~%
the~status~is~\checkengine_shell_escape_status: }

\msg_new:nnnn { checkengine } { no-shell-escape }
{ Shell~escape~restricted }
{ You~have~required~the~restricted~shell~escape~but~%
the~status~is~\checkengine_shell_escape_status: }

\cs_new:Npn \checkengine_shell_escape_status:
{
\int_case:nnn { \c_shellescape_int }
{
{ 0 } { `No~shell~escape' }
{ 1 } { `Unestricted~shell~escape' }
{ 2 } { `Restricted~shell~escape' }
}
{}
}

\prg_new_conditional:Npnn \pdf_if_output: { p , T , F , TF }
{
\bool_if:nTF
{ \xetex_if_engine_p: || \int_compare_p:n { \pdftex_pdfoutput:D > 0 } }
{ \prg_return_true: }
{ \prg_return_false: }
}

\cs_new:Npn \requirexetex
{
\xetex_if_engine:F
{
\msg_error:nnn { checkengine } { wrong-engine } { XeTeX }
\tex_end:D
}
}

\cs_new:Npn \requireluatex
{
\luatex_if_engine:F
{
\msg_error:nnn { checkengine } { wrong-engine } { LuaTeX }
\tex_end:D
}
}

\cs_new:Npn \requirepdftex
{
\pdftex_if_engine:F
{
\msg_error:nnn { checkengine } { wrong-engine } { pdfTeX }
\tex_end:D
}
}

\cs_new:Npn \requirepdfoutput
{
\pdf_if_output:F
{
\msg_error:nnn { checkengine } { wrong-output } { PDF }
\tex_end:D
}
}

\cs_new:Npn \requiredvioutput
{
\pdf_if_output:T
{
\msg_error:nnn { checkengine } { wrong-output } { DVI }
\tex_end:D
}
}

\int_const:Nn \c_shellescape_int { \pdf@shellescape }

\cs_new:Npn \requireshellescape
{
\int_compare:nF { \c_shellescape_int = 1 }
{
\msg_error:nnn { checkengine } { shell-escape }
\tex_end:D
}
}

\cs_new:Npn \requirenoshellescape
{
\int_compare:nF { \c_shellescape_int != 1 }
{
\msg_error:nnn { checkengine } { no-shell-escape }
\tex_end:D
}
}

\cs_new:Npn \ifengine #1 #2 #3
{
\group_begin:
\checkengine_make_equivalents:
\bool_if:nTF { #1 } { \group_end: #2 } { \group_end: #3 }
}

\cs_new:Npn \engine #1
{
TT\fi:
\group_begin:
\checkengine_make_equivalents:
\bool_if:nTF { #1 } { \group_end: \tex_iftrue:D } { \group_end: \tex_iffalse:D }
}

\cs_new_protected:Npn \checkengine_make_equivalents:
{
\cs_set_eq:NN \pdflatex \pdftex_if_engine_p:
\cs_set_eq:NN \xelatex \xetex_if_engine_p:
\cs_set_eq:NN \lualatex \luatex_if_engine_p:
\cs_set_eq:NN \pdfoutput \pdf_if_output_p:
}`

Test file:
`\documentclass{article}
\usepackage{checkengine}
%\requirepdftex
%\requirexetex
%\requireluatex
%\requirepdfoutput
%\requiredvioutput
%\requireshellescape
%\requirenoshellescape

\ifengine{ \pdflatex || \xelatex }
{ \typeout{pdflatex or xelatex} }
{ \typeout{something else} }

\if\engine{ \xelatex || \lualatex }
\usepackage{fontspec}
\else
\usepackage[utf8]{inputenc}
\fi`

Si possono usare tutti i [tt]\require…[/tt] elencati. La macro [tt]\ifengine[/tt] prende tre argomenti: il primo è una serie di parole chiave precedute da [tt]\[/tt]; la sintassi non è difficile: [tt]&&[/tt] significa “e”, [tt]||[/tt] significa “o” e [tt]![/tt] significa “non”. Si possono anche usare le parentesi per calcolare queste espressioni booleane. Naturalmente si può dare anche solo una parola chiave. Quelle ammesse sono
`\pdflatex \xelatex \lualatex \pdfoutput`
e non dovrebbe essere difficile capire come funziona. Il secondo argomento è ciò che si deve eseguire se le condizioni sono soddisfatte, altrimenti viene usato il terzo argomento.

C’è la sintassi alternativa
`\if\engine{}

\else

\fi`
ma propenderei per la prima versione.

Attendo proposte per estensioni o perfezionamenti.

Ciao
Enrico

Go to top