0

This question already has an answer here:

I'm completely puzzled by this: I'm trying to create a simple command that will modify a savebox from an enumerate, and I've worked it down to a minimal example of some weirdness:

...
% Create our command
\newcommand{\hello}{
\savebox{\tmp}{Works!}
}
% Setup the box
\newsavebox{\tmp}
\savebox{\tmp}{Doesn't work!}

\hello

\usebox{\tmp}
% Will put: Works!

If I run the command from inside an enumerate, it does not work:

% Create our command
\newcommand{\hello}{
\savebox{\tmp}{Works!}
}
% Setup the box
\newsavebox{\tmp}
\savebox{\tmp}{Doesn't work!}

\begin{enumerate}
\item 
Something \hello
\end{enumerate}

\usebox{\tmp}
% Will put: Doesn't work!

I have absolutely no clue why it does this. No warnings or errors are given, and it does this on both pdfLatex and XeLaTex (the only two I had available to test). Any clues would be much appreciated!

marked as duplicate by egreg macros May 13 at 17:17

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

0

This issue is that the \savebox is exercised in a group, and is scope limited to within the enumerate.

Stealing David's answer here, Create a \savebox in a Group and have it available outside of group, and applying it to the OP's situation. In essence, substitute the primitives for \savebox and make them \global.

\documentclass{article}
\begin{document}
% Create our command
\newcommand{\hello}{
\global\expandafter\setbox\csname tmp\endcsname\hbox{Works!}
}
% Setup the box
\newsavebox{\tmp}
\savebox{\tmp}{Doesn't work!}

\begin{enumerate}
\item 
Something \hello
\usebox{\tmp} inside group

\end{enumerate}

\usebox{\tmp} outside group
% Will put: Doesn't work!
\end{document}

enter image description here

Technically, a given savebox should always be handled globally or locally. Here is one way to do that, by introducing global macros

\documentclass{article}
\newcommand\gnewsavebox[1]{\global\newsavebox#1}
\newcommand\gsavebox[2]{\global\setbox#1\hbox{#2}}
\begin{document}
% Create our command
\newcommand{\hello}{\gsavebox{\tmp}{Works!}
}
% Setup the box
\gnewsavebox{\tmp}
\gsavebox{\tmp}{Doesn't work!}

\begin{enumerate}
\item 
Something \hello
\usebox{\tmp} inside group

\end{enumerate}

\usebox{\tmp} outside group
% Will put: Doesn't work!
\end{document}

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