# How can I check if the current code is inside a certain environment?

I would like to define a command which checks if it is executed inside a certain environment. Like this:

\documentclass{article}

\newenvironment{myenv}[0]{at start}{ at end}

\newcommand{\inner}[0]{%
% if iside a myenv
(inner)
% else
\begin{myenv}
(inner)%
\end{myenv}
% end
}

\begin{document}

\begin{myenv}
\inner
\end{myenv}

\inner

\end{document}


See the definition of \inner. Is an if-condition of this form possible?

LaTeX keeps the current environment in the macro \@currenvir

\makeatletter
\newcommand{\inner}{%
\ifx\@currenvir\@myenvname
(inner)
\else
\begin{myenv}(inner)\end{myenv}
\fi}
\newcommand*\@myenvname{myenv}
\makeatother


Another approach would be to define a global conditional that's set to true by myenv start code and to false by myenv end code. It depends mostly on what you are expecting from the myenv environment: can it appear nested inside itself?

• @Nickoley: Note that this doesn't work any longer when \inner is used inside another environment inside the myenv environment, e.g. \begin{myenv}\begin{center}\inner\end{center}\end{myenv}. Then \@currenvir will be center when \inner is expanded. – Martin Scharrer May 20 '11 at 10:28
• This does not seem to work on my end. It produces the "else" output both inside and outside a myenv environment. However, both \@currenvir and \@myenvname display the correct (and the same) output when placed inside the environment. – Danny Hansen Mar 25 '19 at 21:33
• @DannyHansen Right: in some update during the last eight years, the LaTeX kernel changed \@currenvir to not be \long as it used to be. Fixed by adding a *. – egreg Mar 25 '19 at 21:41

If you use pdftex, etex or xetex (I mean engine), you can define a fully expandable test:

\makeatletter \def\IfEnvir #1%
% implicit #2 "what if true"
% implicit #3 "what if false"
{%
\ifnum \strcmp{\@currenvir}{#1}=0
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}

\makeatother


Such a conditional is defined in the gmutils package: \@ifenvir, but there it's \protected for some reason.

• If you prefer the \if… … \else … \fi form, just replace \expandafter\@first/secondoftwo with your stuff, but i'd suggest the arguments-form because it's robust to unbalanced \if's. – Natror May 20 '11 at 9:06
• Please indent your code with four spaces (or use the '101010' button to do this) so that it is properly highlighted. Please don't use HTML for code formatting. Thanks. – Martin Scharrer May 20 '11 at 9:39
• the command is \strcmp in XeTeX and \pdfstrcmp in pdfTeX. One can load pdftexcmds and use \pdf@strcmp` in all engines (including LuaTeX). – egreg May 20 '11 at 10:04