[Tex/LaTex] Why using @ inside \newcommand gives “Undefined control sequence” error

listingsmacros

I'm trying to create a command that temporarily changes the size of a lstinline, so that I can properly use it in a footnote. The following commands seem to work fine:

\makeatletter
\lst@AddToHook{TextStyle}{\let\lst@basicstyle=\footnotesize}
\makeatother

However, if I try to add them on a newcommand and then use it:

\newcommand{\testcmm}{
    \makeatletter
    \lst@AddToHook{TextStyle}{\let\lst@basicstyle=\footnotesize}
    \makeatother
}
\testcmm

I get the folowing error:

! Undefined control sequence.\testcmm -> \makeatletter \lst@AddToHook{TextStyle}{\let \lst @basicstyle=n... \testcmm

I know that this error usually happens when the command is not defined, for example, whan you forget to add the library that contains it. In this case however, it only happens inside the \newcommand. Why?


MWE:

\documentclass{article}
\usepackage{listings}

\newcommand{\testcmm}{
    \makeatletter
    \lst@AddToHook{TextStyle}{\let\lst@basicstyle=\footnotesize}
    \makeatother
}

\begin{document}
\testcmm
\end{document}

Best Answer

The error you get is

! Undefined control sequence.
\testcmm ->\makeatletter \lst
                              @AddToHook{TextStyle}{\let \lst @basicstyle=\f...
l.12 \testcmm

because TeX has absorbed the definition text when \makeatletter is not in force, so it has stored

\lst@AddToHook

as eleven tokens \lst•@•A•d•d•T•o•H•o•o•k.

You want instead that in the replacement text @ is treated as a letter, so

\documentclass{article}
\usepackage{listings}

\makeatletter
\newcommand{\testcmm}{%
    \lst@AddToHook{TextStyle}{\let\lst@basicstyle=\footnotesize}%
}
\makeatother

\begin{document}

\testcmm

\end{document}

Don't forget to protect endlines.