# Save and restore the makeatletter/makeatother state

When posting snippets of latex code that define or modify commands containing @, one commonly includes the \makeatletter...\makeatother wrapper that's necessary if pasting the snippet into an ordinary document. However, such pasting then has bad effects if it happens to occur somewhere that \makeatletter is already in effect. Is there a good way to "save the state of 'at'", execute some code, and then restore the original state, whatever it might have been?

(Yes, I know that \makeatletter/\makeatother are local to groups. However, certain code doesn't work the same way inside a group, e.g. macro definitions are local to the group by default, so it would be better to avoid having to enclose the whole snippet in a group.)

• Where are you putting these commands? Unless you are misusing them, I'd think it'd be hard to get confused as to whether you need to use them or not? (E.g., don't use them in a .sty file.) – jon Oct 21 '16 at 4:13
• Think to \makeatletter and \makeatother as ”snippet delimiters“ – egreg Oct 21 '16 at 7:42
• To be honest, I don't actually have a use in mind for such commands. I was just curious if it was easy to do, because it seemed to me as though it would have been better if this is what \makeatletter and \makeatother actually did. – Mike Shulman Oct 21 '16 at 8:33

This is what -- in some situations -- I do:

\begingroup
\makeatletter
\@firstofone{%
\endgroup
...
< stuff/macro-definitions that
should take place outside the
local scope while @ is letter  >
...
}%


The argument of \@firstofone will be read and tokenized within a local scope where @ is a letter. When processing those tokens that came into being due to reading and tokenizing the argument of \@firstofone takes place, the first \endgroup will terminate that local scope, resetting the category code of @ to whatever it was before calling \makeatletter. Thus processing the remaining tokens of \@firstofone's argument does not take place within that local scope but with the catcode-régime that was in effect before processing the \makeatletter-token.

You could define a new macro to store the current catcode of @ and restore it using this macro later on:

\documentclass{article}

\def\safemakeatletter#1{%
\edef#1{\catcode@=\the\catcode@\relax}%
\makeatletter
}

\def\testat{catcode of \texttt{@} is: \the\catcode@\relax\par}

\begin{document}

\catcode@=10\relax
\testat
\makeatletter
\testat
\makeatother
\testat

\medskip

\catcode@=10\relax
\testat
\safemakeatletter\safemakeatother
\testat
\safemakeatother
\testat

\end{document}


As you can see in the output, \makeatother incorrectly restores the catcode in the first part, while \safemakeatother doesn't:

• Please see Why should the minimal class be avoided?. – Peter Grill Oct 21 '16 at 4:36
• @PeterGrill Thanks, I'll keep that in mind, though it makes no difference in this particular case, as far as I can see. – siracusa Oct 21 '16 at 4:40
• Yeah, I just wanted to have that there so that others who see this don't think that the minimal` class shoudl be used for MWEs. – Peter Grill Oct 21 '16 at 4:41