4

I know this is not something that you’re supposed to do. But for fun, I played around with the idea of changing the \mathcode of all letters to "8000 and defining them as commands. Each such command would then correspond to the variable with that symbol. Below, I tried doing this with the letter j, though it partly failed. Similarly, I would like to redefine +, -, and all the other common math symbols.

So far, everything seems to work more or less as before. Command names, environment names, and key names containing j seem to work just fine. I have four questions:

  • Which LaTeX functionality would you break if you did this for all letters? What if you did it for common symbols like + and -?
  • How can I fix the below MWE so that j simply prints j (using \oldletter caused a loop)?
  • Am I doing it the “right way”, or should I rather use a different construction, e.g. using \everymath, \everydisplay, and \AtBeginDocument?
  • What would be the best way to wrap all of this functionality into a single command, called something like \RedefineMathLetter{<letter>} or \RedefineMathSymbol{<symbol>}?
\documentclass{article}

\let\oldletter=j

\mathcode`\j="8000

\catcode`\j=\active

\NewDocumentCommand{j}{ o }{%
    J% using \oldletter caused a loop
    \IfValueT{#1}{_{#1}}%
}

\catcode`\j=11

\begin{document}

\( j = j[1] \)

\end{document}

enter image description here

2
  • See egreg's answer at tex.stackexchange.com/questions/538642/…: If a character is assigned \mathcode 32768 (that is, "8000 in TeX hexadecimal notation), the following happens when the character is found: nothing at all when TeX is not typesetting (for instance when looking for arguments of every kind, even of primitives); the character is printed when TeX is in horizontal mode; the current definition of the character as active when TeX is in math mode and examines the character for adding it to the math list under construction. Aug 24, 2021 at 11:38
  • Also relevant: tex.stackexchange.com/questions/109436/… Aug 24, 2021 at 13:10

2 Answers 2

4

enter image description here

\documentclass{article}

\mathchardef\oldletter=\mathcode`j

\mathcode`\j="8000

\catcode`\j=\active

\NewDocumentCommand{j}{ o }{%
    \oldletter
    \IfValueT{#1}{_{#1}}%
}

\catcode`\j=11

\begin{document}

\( j = j[1] \)

\end{document}

or wrapped as a command form:

\documentclass{article}



\def\mathdef#1{%
  \expandafter\mathchardef\csname old#1\endcsname\mathcode`#1 %
  \mathcode`#1="8000 %
  \begingroup
  \lccode`\~=`#1 %
  \lowercase{\endgroup\NewDocumentCommand~}}

\mathdef{j}{o}{\oldj\IfValueT{#1}{_{#1}}}

\begin{document}

\( j = j[1] \)

\end{document}
14
  • 2
    @Gaussler I added a command definition wrapper Aug 24, 2021 at 11:42
  • 1
    I never understood: Why the need to use the \lowercase trick?
    – Gaussler
    Aug 24, 2021 at 11:52
  • 1
    @Gaussler there must be an answer on site about that, but lowercase ~ gives you an active j (it's about the only thing \lowercase is good for, it can't be used for lowercasing text other than English) Aug 24, 2021 at 12:00
  • 1
    \mathcode`j=\oldj @Gaussler Aug 24, 2021 at 13:14
  • 2
    @Gaussler tradition Aug 24, 2021 at 15:22
2

There's still no expl3 interface for \mathchardef.

\documentclass{article}

\ExplSyntaxOn

\cs_new_protected:Nn \gaussler_mathchardef:Nn
 {
  \tex_mathchardef:D #1 = #2 \scan_stop:
 }
\cs_generate_variant:Nn \gaussler_mathchardef:Nn { c }

\NewDocumentCommand{\RedefineMathLetter}{mmm}
 {% #1 = letter to redefine, #2 = args spec, #3 = replacement text
  % save the original math code
  \gaussler_mathchardef:cn { __gaussler_letter_#1: } { \char_value_mathcode:n { `#1 } }
  % define a new command to replace the letter
  \exp_args:Nc \NewDocumentCommand { __gaussler_letter_new_#1 } { #2 } { #3 }
  % define the active equivalent
  \char_set_active_eq:nc { `#1 } { __gaussler_letter_new_#1 }
  % at begin document set math code "8000
  \AtBeginDocument
   {
    \char_set_mathcode:nn { `#1 } { "8000 }
   }
 }
% in the replacement text, instead of the letter x, use \STD{x}
\NewDocumentCommand{\STD}{m}{ \use:c { __gaussler_letter_#1: } }

\ExplSyntaxOff

\RedefineMathLetter{J}{o}{\STD{J}\IfValueT{#1}{_{#1}}}

\begin{document}

$J+J[1]$

\end{document}

enter image description here

The \STD{J} trick avoids infinite loops.

6
  • Regarding my other question, would there be any unintended consequences of doing this to all letters (and maybe also to symbols like + and -)?
    – Gaussler
    Aug 25, 2021 at 13:00
  • @Gaussler I see no consequence apart from obscuring your input
    – egreg
    Aug 25, 2021 at 13:27
  • Well, I used to type “a squared” as \va[pow=2]. Now I can do a[pow=2]. Slightly less obscure, in fact. ;-)
    – Gaussler
    Aug 26, 2021 at 11:16
  • @Gaussler Less obscure than a^2?
    – egreg
    Aug 26, 2021 at 12:58
  • Indeed, a^2 is simple and short, but it would not be semantic. Superscripts can mean a lot of different things in mathematics. Plus, it’s not as easy to centrally adjust the spacing around the 2. When you use a command with keyval syntax, you can. And for more complicated constructions from advanced mathematics, it’s nice to be able to control the notation centrally.
    – Gaussler
    Aug 26, 2021 at 13:12

You must log in to answer this question.

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