6

It is possible to make conditional constructs based on the version ⟨date⟩ of a ⟨package⟩, thanks to \@ifpackagelater{⟨package⟩}{⟨date⟩}{⟨yes⟩}{⟨no⟩}. So far, so good.

But this doesn't work for babel-* "packages" (in fact lan­guage def­i­ni­tion files):

\documentclass[english]{article}
\usepackage{babel}
\makeatletter
\@ifpackagelater{english}{2012/08/20}{%
  \typeout{After}
}{%
  \typeout{Before}
}
\makeatother
\begin{document}
\end{document}

as the corresponding files are .ldf and not .sty files.

Is there another way for conditional constructs based on the version ⟨date⟩ of lan­guage def­i­ni­tion files?

5

In LaTeX, Version dates can be declared by:

\ProvidesClass{<class name>}[YYYY/MM/DD ...]
\ProvidesPackage{<package name>}[YYYY/MM/DD ...]
\ProvidesFile{<file name>}[YYYY/MM/DD ...]

and LaTeX provides:

\@ifclasslater
\@ifpackagelater

\@iffilelater is missing and both commands can only be used in the preamble.

Package ltxcmds closes the gap by defining the complete set:

\ltx@ifclasslater
\ltx@ifpackagelater
\ltx@iffilelater

All three commands can also be used after \begin{document}.

Example:

\documentclass[english]{article}
\usepackage{babel}
\usepackage{ltxcmds}
\makeatletter
\ltx@iffilelater{english.ldf}{2012/08/20}{%
  \typeout{After}
}{%
  \typeout{Before}
}
\makeatother
\begin{document}
\end{document}
5

The babel language files use \ProvidesFile with some version information argument -- this setup is necessary to use the LaTeX core macro \@ifl@ter to check the file date, if it is applied with the correct extension.

It checks the file date, see the definition and the usage in latex.ltx:

\def\@ifl@ter#1#2{%
  \expandafter\@ifl@t@r
    \csname ver@#2.#1\endcsname}
\@onlypreamble\@ifl@ter
\def\@ifl@t@r#1#2{%
  \ifnum\expandafter\@parse@version#1//00\@nil<%
        \expandafter\@parse@version#2//00\@nil
    \expandafter\@secondoftwo
  \else
    \expandafter\@firstoftwo
  \fi}
\@onlypreamble\@ifl@t@r
\def\@parse@version#1/#2/#3#4#5\@nil{#1#2#3#4 }
\@onlypreamble\@parse@version
% Some lines omitted
\def\@ifpackagelater{\@ifl@ter\@pkgextension}
\def\@ifclasslater{\@ifl@ter\@clsextension}
\@onlypreamble\@ifpackagelater
\@onlypreamble\@ifclasslater

As can be seen, the macros \@ifpackagelater and \@ifclasslater do not have arguments actually (they are moving!) and the final treatment of the {true}{false} branches is left over to \@ifl@t@r.

So all that is to the is to define a separate macro that checks for a babel definition file, say \@ifbabellater and provide the \@b@belextension here.

\documentclass[english]{article}

\makeatletter
\def\@b@belextension{ldf}
\def\@ifbabellater{%
  \@ifl@ter\@b@belextension%
}
\makeatother
\usepackage{babel}
\makeatletter
\@ifbabellater{english}{2012/08/20}{%
  \typeout{After}
}{%
  \typeout{Before}
}
\makeatother
\begin{document}
\end{document}

In my setup it prints 'After' on the console.

Apparently, there's a package for such macros, but I've done with core methods ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.