# Data structure: Define a command or environment only valid inside a certain type of environment

I want to script the generation of LaTeX documents, and therefore, I will need to use a data structure to organize the information. For example:

• Person:
• Name
• Phone

I know in LaTeX you can create new commands and environments, like:

\newenvironment{Person}{\bigskip\noindent}{\bigskip}
\begin{Person}\end{Person}


And commands/env's as OO-properties, if you will:

\newcommand{\Name}[1]{My name is #1}
\Name{John Doe}

\newcommand{Phone}[1]{Phone: #1}
\Phone{555-123-3221}



Is there a way that allows for OO-style 1) scope and 2) overloading? That is,

\begin{Person}\Name{Joey}\end{Person}


is valid (question #1), but this isn't:

This is outside the Person environment, \Name{Silly}!


I want those commands to only work inside the environment that I choose.

For question #2, if I write (using another new environment named Species):

\begin{Species}\Name{E. Coli}\end{Species}


I don't want it to print the same output as the Name belonging to Person. Is this even possible in LaTeX?

Yes, it's possible, but I wouldn't recommend making the same command into performing very different tasks depending on the context.

\newcommand{\Name}[1]{Do something with #1} % default action
\newcommand{\SpeciesName}[1]{Do something else with #1}

\newenvironment{Species}
{<something at the opening>%
\let\Name\SpeciesName
<something else at the opening>}
{<something at the end>}


You can also make \SpeciesName not (easily accessible):

\newcommand{\Name}[1]{Do something with #1}

\makeatletter
\newcommand{\Species@Name}[1]{Do something else with #1}

\newenvironment{Species}
{<something at the opening>%
\let\Name\Species@Name
<something else at the opening>}
{<something at the end>}
\makeatother


If you want to disallow using \Name except inside the Species environment, use

\makeatletter
\newcommand{\Name}[1]{%
\@latex@error{\noexpand\Name used in a wrong place}
{You dummy! How many times should I tell you?}%
}
\makeatother


for the “default definition”.

• I've updated my question clarify the part about scope and overloading. You are answering the part about overloading (same command name in different environments). But what about scope? Any ideas? Any way to make a command only work if it's called within a particular environment (as opposed to the naked document environment)? – tralston Jul 5 '15 at 15:47
• @tralston Don't give a “default definition”. Or, even better, define it to raise an error. I added the relevant code. – egreg Jul 5 '15 at 15:51