3

I try to locally change catcode in environment

\newenvironment{wse}
{
  \catcode`^=\active%
  \def^{\mathchar\numexpr"7000+`\^\relax}%
  $
}
{
  $
}

but the next code

\begin{wse}
  x^2
\end{wse}

breaks with

! Missing control sequence inserted.

What is wrong?

Bernard
  • 271,350
dann
  • 57

1 Answers1

5

When you do \newenvironment, the category code of ^ is 7 and this is not changed by \catcode`^=\active.

\begingroup
\catcode`^=\active
\gdef\changehat{\def^{\mathchar\numexpr"7000+`\^\relax}}
\endgroup

\newenvironment{wse}
 {%
  \catcode`^=\active
  \changehat
  $%
 }
 {%
  $%
 }

Full example

\documentclass{article}

\begingroup
\catcode`^=\active
\gdef\changehat{\def^{\mathchar\numexpr"7000+`\^\relax}}
\endgroup

\newenvironment{wse}
 {%
  \catcode`^=\active
  \changehat
  $%
 }
 {%
  $%
 }

\begin{document}

X$a^b$X\begin{wse}a^b\end{wse}X

\end{document}

enter image description here

An alternative with the \lowercase trick that assumes ~ is active.

\documentclass{article}

\newenvironment{wse}
 {%
  \catcode`^=\active
  \begingroup\lccode`~=`\^ \lowercase{\endgroup
    \def~{\mathchar\numexpr"7000+`\^\relax}}%
  $%
 }
 {%
  $%
 }

\begin{document}

X$a^b$X\begin{wse}a^b\end{wse}X

\end{document}
egreg
  • 1,121,712
  • It works like a charm! It look's like this is the only way i forget to try. It's because for some days i work on custom env and pretty tired to deal with TeX kind of matryoshka, i mean definition, redef, create local scope and so on. Thank you! – dann Sep 22 '17 at 20:54
  • @user6786661 Remember that a \def only stores character tokens with the category code they have at the moment the definition is made and that \def does no interpretation whatsoever of the tokens in the body. The above indirect method is one of the tricks to use; there exist variations on the theme, I showed also one of them. – egreg Sep 22 '17 at 20:57
  • It seems to be possible to put \changehat outside of the environment (eg just after the \endgroup. Is this incorrect, or is there any reason to prefer placing it in the environment? – JeanPierre Feb 11 '21 at 20:22
  • @JeanPierre What line are you referring to? The group is essential to have the proper category code of ^ at definition time. – egreg Feb 11 '21 at 20:30
  • I mean moving \changehat from the wse env definition to a global location, ie just after the \endgroup. This seems to work on this example so I'm just wondering. – JeanPierre Feb 11 '21 at 20:33
  • @JeanPierre This would make ^ active everywhere, with the impossibility of using it for superscripts. – egreg Feb 11 '21 at 20:35
  • No it does not, since just the \changehat is moved, not the \catcode thing. Try it! – JeanPierre Feb 11 '21 at 20:43
  • @JeanPierre Oh, sure. But my code has the advantage that you can have several versions of the active ^ in different environments. – egreg Feb 11 '21 at 20:51
  • Indeed, thanks! – JeanPierre Feb 11 '21 at 21:05