0

Is there an environment that provides a functionality similar to \ensuremath{} (except that I am actually interested in inserting \[ … \] instead of \( … \))?

Motivation: I want to define a math-like environment that the user would be able to nest. Thus I want this behavior (simplified example): the environment would create an array environment. If we are not in math mode already, it would enclose it in \[ … \]. Because \[ … \] cannot be nested, the first sketch of the code:

\newenvironment{myenv}{%
  \[
  \begin{array}{|l}
}{%
  \end{array}
  \]%
}

obviously does not work as intended. I cannot do this either:

\newenvironment{myenv}{%
  \TextOrMath{\[}{}
  \begin{array}{|l}
}{%
  \end{array}
  % Here we are in math mode anyway, so to know when to insert \],
  % we need to remember at which level of nesting we are.
}

So a half-solution would be counting the levels of nesting, which may work in most cases. However, it fails in the (unlikely?) case when a myenv is nested inside text-mode content inside a myenv. To accurately keep track of nesting, we should use a stack. If possible at all with pure (La)TeX, this starts exceeding my TeX skills by far.

2 Answers 2

1

This could be considered a terrible hack, but it seems to me the simplest solution:

\documentclass{minimal}
\newenvironment{suremath}
{\ifmmode \def\endsuremath{}\else\def\endsuremath{\]}\[\fi}{}

\begin{document}

\begin{suremath}
  \begin{array}{c}
    a = b x + c \\ z = u x - v
  \end{array}
\end{suremath}

\begin{equation}
  \begin{suremath}
    E = mc^2
  \end{suremath}
\end{equation}

\end{document}

enter image description here

1
  • Ah, so this solution supports nesting after all, because command definitions are apparently local to each environment (so that, when a nested environment redefines \endsuremath, it does not erase the definition of the same name used by the surrounding environment). I had forgotten that. :-) What piece of *TeX code could not be considered a terrible hack anyway?
    – Maëlan
    Commented Feb 21, 2021 at 22:05
0

Inspired by Pieter van Oostrum’s answer, here is another working solution that should be a less terrible hack than redefining \end<NAME OF ENV> itself. It sets a flag to true if the current environment was opened from text, and false if it was opened from math.

All instances of the suremath environment use the same name for the flag (suremath@InText), but nesting works nonetheless because environments form groups and, in TeX, variables are local to groups. So when a nested environment redefines (changes the value of) a variable, it does not affect the variable of the same name in the enclosing environment.

\makeatletter

  \newif\ifsuremath@InText

  \newenvironment{suremath}{%
    \TextOrMath{%
      % if opening from text context:
      \suremath@InTexttrue%
      \[%
    }{%
      % if opening from math context:
      \suremath@InTextfalse%
    }%
  }{%
    \ifsuremath@InText%
      % if closing back to text context:
      \]%
    \else%
      % if closing back to math context:
    \fi%
  }

\makeatother

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .