\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{freemath}

\protected\def\freemathon{%
	\AtBeginDocument{\@freemathon}%
}
\AtBeginDocument{\let\freemathon=\@freemathon}

\protected\def\@freemathon{%
	\catcode`\^=\active \catcode`\_=\active
	\lccode`~=`\^\lowercase{\let~\freemath@sp}%
	\lccode`~=`\_\lowercase{\let~\freemath@sb}%
	\freemath@activate abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\@nnil
}
\def\freemath@activate#1{%
	\ifx\@nnil#1\else
		\ifnum\mathcode`#1=\ifdefined\directlua"1000000 \else "8000\fi \else
			\expandafter\mathchardef\csname freemath@#1\endcsname \mathcode`#1
			\mathcode`#1="8000
			\begingroup \lccode`~=`#1\lowercase{\endgroup \def~}%
				{\freemath@collect\@iden#1}%
		\fi
		\expandafter\freemath@activate
	\fi
}
\protected\def\freemathoff{
	\catcode`\^=7 \catcode`\_=8
	\freemath@deactivate abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\@nnil
}
\def\freemath@deactivate#1{%
	\ifx\@nnil#1\else
		\ifcsname freemath@#1\endcsname
			\mathcode`#1=\csname freemath@#1\endcsname
		\fi
		\expandafter\freemath@deactivate
	\fi
}

\newtoks\freemath@do
\newtoks\freemath@word
\protected\def\freemath@collect#1#2{%
	\begingroup \ifnum\iffalse{\fi`}=\z@\fi
	\freemath@do={#1}%
	\freemath@word={#2}%
	\futurelet\next\freemath@collectA
}
\def\freemath@collectA{%
	\ifcat A\noexpand\next
		\expandafter\freemath@collectB
	\else
		\expandafter\freemath@collectC
	\fi
}
\def\freemath@collectB#1{%
	\freemath@word=\expandafter{\the\freemath@word #1}%
	\futurelet\next\freemath@collectA
}
\def\freemath@collectC{%
	\ifnum`{=\z@}\fi \edef\next{%
		\endgroup
		\the\freemath@do
		\if\relax\detokenize\expandafter{\the\freemath@word}\relax
			{}%
		\else
			\ifcsname \the\freemath@word \endcsname
				\if\relax\detokenize\expanded{{\expandafter\@gobble \the\freemath@word}}\relax
					{\noexpand\freemath@literal \the\freemath@word\noexpand\@nnil}%
				\else
					\expandafter\noexpand \csname \the\freemath@word \endcsname
				\fi
			\else
				{\noexpand\freemath@literal \the\freemath@word\noexpand\@nnil}%
			\fi
		\fi
	}\next
}

\def\freemath@literal#1{%
	\ifx\@nnil#1\else
		\csname freemath@#1\endcsname
		\expandafter\freemath@literal
	\fi
}

\protected\def\freemath@sp{%
	\ifincsname \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi
		^%
		{\relax\ifmmode \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi
			{\freemath@collect\freemath@spA{}}^}%
}
\def\freemath@spA#1{\if\relax\detokenize{#1}\relax \sp \else \sp{#1}\fi}
\protected\def\freemath@sb{%
	\ifincsname \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi
		_%
		{\relax\ifmmode \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi
			{\freemath@collect\freemath@sbA{}}_}%
}
\def\freemath@sbA#1{\if\relax\detokenize{#1}\relax \sb \else \sb{#1}\fi}

\g@addto@macro\operator@font\freemathoff

\endinput

freemath.sty, version 1.0

Copyright (C) 2025 plante
This package is released under the LaTeX Project Public License (LPPL) 1.3c.

freemath: LaTeX math without backslashes.

Any string of at least two consecutive letters appearing in math mode will automatically be turned into the control sequence with the same name, if it exists.

This package provides the `\freemathon` and `\freemathoff` commands which respectively activate and deactivate this behaviour. It is disabled by default upon loading.

Example:
With freemath: `lim_{n to infty} int_Omega n log left( 1 + frac{f}{n} right) d mu`.
Without freemath: `\lim_{n \to \infty} \int_\Omega n \log\left( 1 + \frac{f}{n} ) d\mu`.

See the documentation for known limitations.
