Make Characters Active via Macro in Math Mode

You have to be careful with the declarations if you load amsmath; in the body of the definition, use \std{<char>} where you need the old meaning.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xcolor,etoolbox}

\makeatletter
\newcommand{\DeclareMathActive}[2]{%
  % #1 is the character, #2 is the definition
  \expandafter\edef\csname keep@#1@code\endcsname{\mathchar\the\mathcode`#1 }
  \begingroup\lccode`~=`#1\relax
  \lowercase{\endgroup\def~}{#2}%
  \AtBeginDocument{\mathcode`#1="8000 }%
}

\newcommand{\std}[1]{\csname keep@#1@code\endcsname}
\patchcmd{\newmcodes@}{\mathcode`\-\relax}{\std@minuscode\relax}{}{\ddt}
\AtBeginDocument{\edef\std@minuscode{\the\mathcode`-}}
\makeatother


\DeclareMathActive{+}{\mathbin{\textcolor{blue}{\std{+}}}}
\DeclareMathActive{!}{\mathclose{\textcolor{brown}{\std{!}}}}
\DeclareMathActive{-}{\mathbin{\textcolor{red}{\hat{\std{-}}}}}

\begin{document}

a=+b $c=+4+d+3!-1$ e=+f

\end{document}

Don't do \let\OldPlus=+.

enter image description here

With Unicode engines (xelatex or lualatex), the patch must be done differently. Here's a version that copes with all engines.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xcolor,etoolbox}
\usepackage{iftex}

\makeatletter
\newcommand{\DeclareMathActive}[2]{%
  % #1 is the character, #2 is the definition
  \expandafter\edef\csname keep@#1@code\endcsname{\mathchar\the\mathcode`#1 }
  \begingroup\lccode`~=`#1\relax
  \lowercase{\endgroup\def~}{#2}%
  \AtBeginDocument{\mathcode`#1="8000 }%
}

\newcommand{\std}[1]{\csname keep@#1@code\endcsname}
\iftutex
  \patchcmd{\newmcodes@}{\Umathcodenum `\-\relax}{\std@minuscode\relax}{}{\ddt}
\else
  \patchcmd{\newmcodes@}{\mathcode`\-\relax}{\std@minuscode\relax}{}{\ddt}
\fi
\AtBeginDocument{\edef\std@minuscode{\the\mathcode`-}}
\makeatother


\DeclareMathActive{+}{\mathbin{\textcolor{blue}{\std{+}}}}
\DeclareMathActive{!}{\mathclose{\textcolor{brown}{\std{!}}}}
\DeclareMathActive{-}{\mathbin{\textcolor{red}{\hat{\std{-}}}}}

\begin{document}

a=+b $c=+4+d+3!-1$ e=+f

\end{document}

You can define \mathdef declarator and then use it:

\input opmac \localcolor

\def\mathdef#1{\mathcode`#1="8000 \bgroup \lccode`~=`#1\lowercase{\egroup\def~}}

\mathdef +{\mathbin{\Red\mathchar`+}}
\mathdef ={\mathrel{\Green\mathchar`=}}

aha + $a+b+c=d$

\bye

The \input opmac is here only for setting colors \Red, \Green etc. If you are using another macro for colors then use only the second line \def\mathdef... in your macros.


There are a few problems:

\MakeActiveChar does \def#1{#2} which is not permitted since #1 is a character that is not active. Here's an alternative with The \lowercase trick

\NewDocumentCommand\MakeActiveChar{mm}
  {\begingroup\lccode`\~=`#1\lowercase{\endgroup\def~}{#2}%
   \catcode`#1=12 \mathcode`#1="8000 }

Apart from that, you have a missing = in a \let. The first equal is optional, so \let\a=\b is correct, the equal, however, is necessary when you want to let to = because if not, it would be treated as the optional one, so

\let\originalequal=

should be

\let\originalequal==

And the last part is that by making a character active in math mode, and then doing \newcommand\plus{\mathbin{\originalplus}} you get an endless loop like \def\a{\a}, so you need to use for instance \mathchar`\+ or \mathchar`+ instead.

Complete solution

\documentclass{article}
\usepackage{mathtools}
\usepackage{xparse}
\usepackage{xcolor}

\NewDocumentCommand\MakeActiveChar{mm}
  {\begingroup\lccode`\~=`#1\lowercase{\endgroup\def~}{#2}%
   \catcode`#1=12 \mathcode`#1="8000 }

\newcommand*\mathcolor[2]{\begingroup\color{#1}#2\endgroup}

\newcommand*\equal[1][green]{\mathrel{\mathcolor{#1}{\mathchar`\=}}}
\newcommand*\plus[1][blue]{\mathbin{\mathcolor{#1}{\mathchar`\+}}}
\newcommand*\factorial{\mathord{\mathcolor{brown}{\mathchar`\!}}}

\everymath{%
  \MakeActiveChar{=}{\equal}%
  \MakeActiveChar{+}{\plus}%
  \MakeActiveChar{!}{\factorial}%
}

\begin{document}
The ``math'' outside here is just to test that characters are active \emph{only} in math mode:

a=+b $c=+4+d+3!$ e=+f 
\end{document}

By the way, I defined \mathcolor because \textcolor works with \bgroup/\egroup which create an ord atom.