1

I would like \forall to trigger a certain behavior (for the purpose of the example below: change the text color to red), which is cancelled when the next ( is encountered. I can make this work when the ( in question is not within a command, but not when it is. Here is an MWE:

\documentclass{article}
\usepackage{color}

\let\oldforall\forall

\renewcommand{\forall}{%
\oldforall%
\color[rgb]{1,0,0}%
\catcode`(=\active%
}

\let\lparen=(

\catcode`(=\active
\renewcommand{(}{%
\color[rgb]{0,0,0}%
\catcode`(=12\relax%
\lparen}%
\catcode`(=12

\newcommand{\acommand}[1]{#1}

\begin{document}

This works: $\forall x(x^2\geq0)$

This doesn't: \acommand{$\forall x(x^2\geq0)$}

\end{document}

enter image description here

I need a solution that doesn't involve changing the definition of \acommand, as this has to work for any macro that ( may find itself in.

I can understand from “Activate” active characters in argument passed as macro that the issue is that the ( is passed as a passive character to the macro, at which point it is too late to make it active. But I do not understand the solution, so I'm not able to adapt it to my problem.

3

Catcodes get frozen when a macro fetches its argument.

You can make a variant using the more flexible notion of "math activation", which escapes that restriction.

\documentclass{article}
\usepackage{color}

\usepackage{amsmath}
% added to test compatibility, because it is not generally
% possibly to have a globally (math) active ( with amsmath
% but here activation is done only temporarily

\let\oldforall\forall

\renewcommand{\forall}{%
    \oldforall
    \color[rgb]{1,0,0}%
    \edef\mathcodeofleftparen{\the\mathcode`\(}%
    \mathcode`\(="8000
}

\catcode`(=\active
\def({%
    \color[rgb]{0,0,0}%
    \mathcode`\(=\mathcodeofleftparen\relax
    \string(}
\catcode`(=12

\newcommand{\acommand}[1]{#1}

\begin{document}

This works: $\forall x(x^2\geq0), \forall y(y^3\leq0)$

This too: \acommand{$\forall x(x^2\geq0), \forall y(y^3\leq0)$}

By the way, spacing does not look ideal.

\end{document}

Blockquote

One may also envision redefining \forall as a delimited macro if it is always systematically used with a (.

But either a delimited macro or the approach in the code above does not allow things like \forall x \left(.... Thus I recommend a much simpler approach based on suitable mark-up, for example

\newcommand*{\cforall}[1]{\forall\color[rgb]{1,0,0}#1\color[rgb]{0,0,0}}

to be used as \cforall {x}(stuff), or \cforall x\left(stuff\right) etc...

  • Thank you for your help! With two modifications, your solution worked in my non-MWE real document. 1) The solution does not work if there are multiple occurrences of '\forall' before the first '('. I therefore moved \edef\mathcodeofleftparen{\the\mathcode`(}% outside of the macro. 2) \boldsymbol cannot be used while '(' is active. I found a workaround. – Casper Apr 2 '16 at 9:28
  • @Casper The incompatibility of a math active ( with \boldsymbol (from amsmath) is a known issue related to \resetMathstrut@ inner macro of amsmath. You can check the source code of package mathastext to find a way to redefine \resetMathstrut@ in a way which solves that problem. The code in mathastext.sty however needs some adjustment for general use, as it makes use of math groups defined by mathastext. – user4686 Apr 2 '16 at 16:28

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.