24

How can I limit the scope of a \newcommand to a \section? This is what I'd like to have:

  1. The command is defined only inside the \section, not globally;
  2. The command scope is that \section and cannot be seen outside of it;
  3. It should not matter if a \subsection sees the command or not (it probably makes sense that it sees it as well); and
  4. The command can be defined again in a different \section without generating errors (I know that \renewcommand could solve it but I'd like to use \newcommand if possible).

What I have is (which generates an error because of the two definitions):

\documentclass{article}
\begin{document}

\section{First section}
\newcommand*{\blipo}{Jill}
Hello \blipo{}. \blipo{} is blonde.

\section{Second section}
\newcommand*{\blipo}{ET}
Hello \blipo{}. \blipo{} is green.

\section{Third section}
Not defined here. Attempt to use it generates error.

\end{document}

[edit] In my particular case, I'll be having around 20-30 different \newcommand in a single section which may or may not be used (redefined) in different sections of the document.

  • 1
    You should use \renewcommand as in CountZero's answer, the definition can easily be made local by using { before the definition and } where you want it to go out of scope but that makes all (local) definitions scoped to that section that may or may not have unexpected affects depending on what other commands you are using. (It will also increase TeX's memory consumption as the previous values of all those definitions need to be saved to be restored at group end) – David Carlisle Mar 28 '13 at 13:00
  • Edited the question: I'll be having a lot of new commands in a section. (Not sure if it's relevant to the problem though.) – Daniel Mar 28 '13 at 13:14
15

You can add code to \section so that \blipo gets undefined:

\documentclass{article}
\usepackage{etoolbox}

\preto\section{\undef\blipo}


\begin{document}

\section{First section}
\newcommand*{\blipo}{Jill}
Hello \blipo{}. \blipo{} is blonde.

\section{Second section}
\newcommand*{\blipo}{ET}
Hello \blipo{}. \blipo{} is green.

\section{Third section}
Not defined here. Attempt to use it generates error.
\blipo{}

\end{document}

Here's a piece of the terminal session:

! Undefined control sequence.
l.19 \blipo
           {}
?

enter image description here


For a more general version, where you want several commands to get undefined at each section, use the list processing functions of etoolbox:

\documentclass{article}
\usepackage{etoolbox}

%%% The helper macros
\newcommand{\onlysectioncommands}[1]{%
  \forcsvlist{\listadd\sectioncommandslist}{#1}}
\preto\section{%
  \forlistloop{\undef}{\sectioncommandslist}}

%%% Here we set the special commands; the
%%% list can be augmented anywhere
\onlysectioncommands{\blipo,\foo}


\begin{document}

\section{First section}
\newcommand*{\blipo}{Jill}
\newcommand{\foo}{foo}

Hello \blipo{}. \blipo{} is blonde. \foo

\section{Second section}
\newcommand*{\blipo}{ET}
\newcommand{\foo}{bar}

Hello \blipo{}. \blipo{} is green. \foo

\section{Third section}
\newcommand{\foo}{baz}

Not defined here. Attempt to use it generates error.
\blipo{}
\foo

\end{document}

With \preto we add code at the start of \section. If the class or packages you're using redefine \section, you may need to use

\usepackage{xpatch}

\xpretocmd{\section}
  {\forlistloop{\undef}{\sectioncommandslist}}
  {}{}

instead.

  • What is the meaning of \preto? – Daniel Mar 28 '13 at 13:20
  • 1
    @Daniel I've added a more general version allowing to specify several commands; also \preto meaning is explained. – egreg Mar 28 '13 at 13:28
18

It seems that this can simply be solved by enclosing the scope with braces. A minimal example could look like:

\documentclass[10pt,a4paper]{article}
\begin{document}

\section{Section A}
{
\newcommand{\sectionowner}{me}
This section belongs to \sectionowner
}
\section{Section B}
{
\newcommand{\sectionowner}{you}
This section belongs to \sectionowner
}

\end{document}

where the command \sectionowner is defined two times using \newcommand.

7

Use \renewcommand:

\documentclass{article}
\begin{document}

\section{First section}
\newcommand*{\blipo}{Jill}
Hello \blipo{}. \blipo{} is blonde.

\section{Second section}
\renewcommand*{\blipo}{ET}
Hello \blipo{}. \blipo{} is green.

\section{Third section}
Not defined here. Attempt to use it generates error.

\end{document}
  • Thank you for the suggestion. I'm aware of the \renewcommand but I'd prefer not using it. I'm editing many files and I don't want to be keeping track if I have defined a certain variable or not. – Daniel Mar 28 '13 at 12:58
  • 4
    @Daniel You should just use \renewcommand in all sections without worrying about which section you first do this in, but use \newcommand once for each one in your preamble or local package to get them initialised. Using a group may seem simpler to start with but it will bite you in the end. – David Carlisle Mar 28 '13 at 13:03
  • 1
    @David: could you expand on how grouping may bite you in the end? I'm currently facing the same problem as OP, and grouping seems to be the simpler solution. From a software engineering perspective, it also seems like the cleaner solution. – arvixx Sep 25 '18 at 9:40
  • 2
    @arvixx you are expecting all code in any packages used that accumulates information to be making assignments that will escape the group, latex counters are always global (if accessed via the latex interfaces) but other things, who knows, also ending a group in "unexpected" places can have odd affects on paragraph formatting that are hard to understand if the group start/begin is not visible. – David Carlisle Sep 25 '18 at 9:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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