3

A colleague of mine had a LaTeX-specific issue for which I did not exactly know the cause of the issue. I have distilled a Minimal Working Example to illustrate the issue.

Originally my colleague had several files and used \include in the following way:

Main .tex file: testi.tex:

\documentclass{article}
\usepackage{graphics}

\makeatletter
    \newcommand{\test@}{test}
\makeatother

\begin{document}

\scalebox{0.8}{
    \input{testii}
}

\end{document}

Included .tex file: testii.tex:

\makeatletter
    \test@
\makeatother

This worked without any problems (the included constructs of this form originated from automated generated code to annotate .pdf images). Then, my colleague tried to make a single *.tex file. Hence, he replaced the \input command by including the content of testii.tex in testi.tex:

Single-file testi.tex: testd.tex:

\documentclass{article}
\usepackage{graphics}

\makeatletter
    \newcommand{\test@}{test}
\makeatother

\begin{document}

\scalebox{0.8}{
    \makeatletter
        \test@
    \makeatother
}

\end{document}

The file testd.tex did, however, not compile: the error message was:

! Undefined control sequence.
 <argument>  \makeatletter \test

Hence: LaTeX reads the command \test instead of \test@, which should have been read due to the \makeatletter construct. We found a way to resolve the issue (by placing \scalebox inside a \makeatletter/\makeatother pair), but still I am wondering what the cause (bug?) of the differences in behavior between inlined LaTeX code and \input-ed LaTeX code is.

1 Answers1

2

This is unrelated to \input (or to the specifics of \scalebox)

in

\scalebox{0.8}{
    \makeatletter
        \test@
    \makeatother
}

the argument has already been parsed and tokenised as \test @ before it is executed, so \makeatletter has no effect. This is the same reason that you can not use \verb in the argument to another command. You need

    \makeatletter
\scalebox{0.8}{%< don't forget this
        \test@
}
    \makeatother
David Carlisle
  • 757,742
  • I'm facing this issue with latexpand (I'm the author). When expanding \scalebox{}{ \input{figure.pdf_t} } I can't find a clean way to put a \makeatletter at the right place automatically. Your solution works well when writing the code manually though, and thanks for the explanation! – Matthieu Moy May 11 '15 at 17:50
  • @MatthieuMoy 99.999% of the time you can just put a single \makeatletter in the preamble and forget about the issue. – David Carlisle May 11 '15 at 18:19
  • Thanks. I used to have a more brute-force approach to \makeatletter but I got complains from a user referencing http://tex.stackexchange.com/questions/11750/how-bad-is-slack-makeatother-discipline-really For now, I documented the bug and workaround in latexpand --help. – Matthieu Moy May 11 '15 at 18:35