5

I am using the command \addmoretexcs for listings, which has its origin here. With the update to TeX Live 2014 (and probably an update to listings), the following code returns an error:

\documentclass{minimal}
\usepackage{ltxcmds}
\usepackage{listings}

\makeatletter
\newcommand{\IfPackageLoaded}[2]{\ltx@ifpackageloaded{#1}{#2}{}}
\makeatother


\IfPackageLoaded{listings}{%

\makeatletter
\newcommand*{\addmoretexcs}[2][common]{%
  \lowercase{\@ifundefined{lstlang@tex$#1}}{%
    \lstloadlanguages{[#1]TeX}%
  }{}%
  \lowercase{\expandafter\g@addto@macro\csname lstlang@tex$#1\endcsname}{%
    \lstset{moretexcs={#2}}%
  }%
}
\makeatother

}% End of \IfPackageLoaded

\addmoretexcs[LaTeX]{setlength}

\begin{document}
\end{document}

The error in question is

! You can't use `\spacefactor' in vertical mode.
\@->\spacefactor 
\@m 
l.23 \addmoretexcs[LaTeX]{setlength}

Note that, if I substitute \IfPackageLoaded with ltx@ifpackageloaded, the error disappears. This, however, is not a solution.

The actual error is likely inside the packages; I cannot debug this any further. Any hints about the origin of this error?

0

1 Answer 1

7

I doubt the code worked before updating to TeX Live 2014, because it would have been wrong in any case. With

\IfPackageLoaded{listings}{%

\makeatletter
\newcommand*{\addmoretexcs}[2][common]{%
  \lowercase{\@ifundefined{lstlang@tex$#1}}{%
    \lstloadlanguages{[#1]TeX}%
  }{}%
  \lowercase{\expandafter\g@addto@macro\csname lstlang@tex$#1\endcsname}{%
    \lstset{moretexcs={#2}}%
  }%
}
\makeatother

}% End of \IfPackageLoaded

the replacement text of \addmoretexcs (actually of an inner macro due to the fact your command has an optional argument) consists of the following tokens (• is used to separate tokens, for clarity)

\lowercase • { • \@ • i • f • u • ...

because the text given as argument to \IfPackageLoaded is already tokenized and TeX doesn't execute \makeatletter when absorbing this argument.

Correct code:

\makeatletter
\IfPackageLoaded{listings}{%
  \newcommand*{\addmoretexcs}[2][common]{%
    \lowercase{\@ifundefined{lstlang@tex$#1}}{%
      \lstloadlanguages{[#1]TeX}%
    }{}%
    \lowercase{\expandafter\g@addto@macro\csname lstlang@tex$#1\endcsname}{%
      \lstset{moretexcs={#2}}%
    }%
  }%
}% End of \IfPackageLoaded
\makeatother

Now, when the argument is absorbed, \@ifundefined is tokenized as a single token, not twelve.


Some more words

The original code may appear to work if it is included in a .sty file, because these files are read in with an implicit \makeatletter declaration at the beginning and an implicit \makeatother at the end (more precisely, the category code of @ is restored to the value it had at the moment the .sty file was opened).

As a general rule, \makeatletter and \makeatother should never appear in .sty files (except when belonging to the replacement text of some macro, which is not the case here). Your usage of \makeatother in the second argument of \IfPackageLoaded would be wrong in a .sty file, because it would change the category code of @ from that point on in case listings has already been loaded.

So, if you are going to use the previous code in a .sty file, remove the \makeatletter and \makeatother declarations.

4
  • Indeed, this solved it. However I can confirm that it worked before and also worked for about 3000 other people that downloaded my template. Commented Jun 26, 2014 at 6:14
  • @MatthiasPospiech Probably none of them loaded listings. Of course, I tried your example with TL 2012 and TL 2013, obviously receiving the same You can't use `\spacefactor' in vertical mode error in both cases.
    – egreg
    Commented Jun 26, 2014 at 6:51
  • My template loads about 100 packages, and listings is always loaded. Even if someone would disable it in the preamble, a package from myself loads it, so it would be loaded in any case. The code is not in a sty file. I must admit, that I did not test the MWE in TeX Live 2013, but the error first appeared in my template in 2014 and does not (in my full template) in 2013. Commented Jun 26, 2014 at 12:17
  • Yes! Thank you for pointing-out the \makeatletter and \makeatother problems with .sty files.
    – user59034
    Commented Jun 17, 2015 at 16:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .