20

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?

21

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?

  • 2
    @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 at 21:33
  • 1
    @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 at 21:41
5

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

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.