Check if argument is math expression. The case of making the first letter uppercase

In this example:

\documentclass{article}
\usepackage{xspace}
\newcommand{\pt}{\ensuremath{p_{T}}\xspace}
\newcommand{\capitalise}[1]{
% if string
\MakeUppercase #1
% if math expression
#1
}
\begin{document}
\capitalise{abc}
\capitalise{\pt}
\end{document}


\capitalise should capitalise the first letter of the argument if it is a string and should leave the argument unchanged if it is a math expression. How to check if the argument is a math expression?

• expl3 contains \tl_upper_case:n, which ignores math when changing case. – Phelype Oleinik Oct 12 '18 at 15:13
• See the textcase package, it has an alternative to \MakeUppercase that in most cases leaves math alone. – daleif Oct 12 '18 at 15:16
• \ifmmode tells you if you are in math mode, but obviously this does not work if you switch to math mode inside the argument of \capitalise. – user121799 Oct 12 '18 at 15:19
• @daleif I checked textcase but it nevertheless also capitalised the math expression. – Viesturs Oct 12 '18 at 15:21
• @Viesturs remember to read the manual either use the overload option like David did or use its \MakeTextUppercase – daleif Oct 12 '18 at 16:01

Using \tl_mixed_case:n this is trivial

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\capitalise}{m}{\tl_mixed_case:n{#1}}
\ExplSyntaxOff
\newcommand{\pt}{\ensuremath{p_{T}}}
\begin{document}
\capitalise{abc}
\capitalise{\pt}
\end{document}


The way this works is by expanding arguments token-by-token and then examining the 'unexpandable' results to see if they can be case-changed. In the case of math mode material, any tokens which produce a $ start a 'no case changing' approach, which is stopped by a matching $ (or for $$/$$ pairs). AS \ensuremath expands to insert a \$, this all works 'as expected'.

\documentclass{article}
\usepackage{xspace}
\newcommand{\pt}{\ensuremath{p_{T}}\xspace}
\newcommand{\capitalise}[1]{
% if string
\MakeUppercase #1
% if math expression
#1
}
\begin{document}
\capitalise{abc}
\capitalise{\pt}
\end{document}

• Thanks, now it works. How can I check from which package exactly a command such as \MakeUppercase is coming? I tried to use \show but I think it didn't work out. – Viesturs Oct 12 '18 at 16:06
• @Viesturs MakeUppercase is defined in the latex format, and textcase redefines it to be the same as MakeTeXUppercase if you use the overload option – David Carlisle Oct 12 '18 at 23:21