# Expl3 get everything before first subscript or apostrophe token

I work with thousands of "symbols" that are either variables or constants. I want any variable x to be typeset as \variable{x}, and any constant a to be typeset as \constant{a}.

If the "symbol" is at least two characters long, then this symbol is a constant. If the symbol is one character long and in the range [a-h] or [A-H], then this symbol is a constant. Otherwise the symbol is a variable.

Assuming symbols are made of letters only, the following Expl3 code does this just right:

\documentclass{article}

\usepackage{xparse}

\newcommand{\constant}[1]{\mathsf{#1}}
\newcommand{\variable}[1]{#1}

\ExplSyntaxOn
\NewDocumentCommand \symbol { m } {
\str_case_x:nnTF { #1 } {
{i}{}{j}{}{k}{}{r}{}{m}{}{n}{}{o}{}{p}{}{q}{}{r}{}{s}{}{t}{}{u}{}{v}{}{w}{}{x}{}{y}{}{z}{}
{I}{}{J}{}{K}{}{R}{}{M}{}{N}{}{O}{}{P}{}{Q}{}{R}{}{S}{}{T}{}{U}{}{V}{}{W}{}{X}{}{Y}{}{Z}{}
}{\variable{#1}}{\constant{#1}}
}
\ExplSyntaxOff

\begin{document}

$\symbol{lorem}, \symbol{ipsum}, \symbol{a}, \symbol{x}$

\end{document}


However I would like some improvements, and I don't know how to do.

• If a symbol ends with one or several apostrophes (for example x''), these apostrophes need not be accounted in the rules above (that is, x'' is a variable);
• If a symbol uses a subscript (for example x_2), then the subscript need not be accounted in the rules above (that is, x_2 is a variable)

Currently I use an ugly adaptation of the code above where I added i' to z', i'' to z'' and i''' to z''' in the tests (and likewise for capital symbols). However I have no solution for subscripts. I think I could find one if I could make the following code work, but the string is not split as I expect it:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand \bla { m } {
\seq_set_split:Nnn \test {\c_math_subscript_token} {#1}
\seq_use:Nn \test {,}
}
\ExplSyntaxOff

\begin{document}

$\bla{A_1}$

\end{document}


(This produces A with 1 as subscript, and not A followed by a comma followed by 1).

Just so that this makes sense to you, I apply this \symbol macro to a comma separated list, which allows me to write things like a, x, y, z, b, a, g instead of \constant a, \variable x, \variable y, \variable z, \constant b, \constant a, \constant g. I use thousands of symbols throughout my document and these shortcuts are really handy for me and make my LaTeX source code way more readable.

This screams regular expressions!

• A run of two or more letters [A-Za-z]{2,} or
• one letter in a-h or A-X

should become \constant{...}.

\documentclass{article}
\usepackage{xparse,l3regex}

\newcommand{\constant}[1]{\mathsf{#1}}

\ExplSyntaxOn
\NewDocumentCommand{\sym}{m}
{
\tl_set:Nn \l_pijcke_symbol_tl { #1 }
\regex_replace_all:nnN { ([a-z]{2,}|[A-Ha-h]{1}) } { \c{constant}\cB\{\1\cE\} } \l_pijcke_symbol_tl
\tl_use:N \l_pijcke_symbol_tl
}
\tl_new:N \l_pijcke_symbol_tl
\ExplSyntaxOff

\begin{document}

$\sym{lorem}, \sym{ipsum}, \sym{a}, \sym{x}$

$\sym{a'}, \sym{B_1}, \sym{x''}, \sym{x_1}$

\end{document}


• Oh my god! I didn't knew Expl3 had them! Is this a new feature? I'm not sure it is reasonable for me to ask my advisor to use some git version of l3kernel :p – Fabian Pijcke Mar 20 '17 at 16:35
• @FabianPijcke It's still marked as “experimental”, but it is in every up-to-date distribution. – egreg Mar 20 '17 at 16:37
• I just saw that l3regex addition in \usepackage. The official documentation says it was released two days ago :D Well if you say I can be confident in its availability, I'll just trust you :-) Thank your very much! – Fabian Pijcke Mar 20 '17 at 16:39
• @FabianPijcke There was a new release two days ago, but l3regex has been available, essentially in the same form, for four years. You can also try $\sym{abc+def+x+h}$. – egreg Mar 20 '17 at 16:41
• For those interested, I ended up using the following form, which allows me to use the \variable command, would it be something more than identity: \regex_match:nnTF { (?i)(^[a-z]{2,}|[a-h]{1}) } { #1 } { \constant{#1} } { \variable{#1} } – Fabian Pijcke Mar 20 '17 at 17:31