# Automatically check if a math character is greek or latin

My question is similar to Bold math: Automatic choice between \mathbf and \boldsymbol for Latin and Greek symbols?, yet slightly different. My non-compilable minimal example is the following one:

\documentclass{book}
\usepackage{amssymb}
\newcommand{\tensor}[1]{if latin alphabet \mathbb{#1} else \mathbf{#1}}
\begin{document}
$\tensor{A}$ $\tensor{\Lambda}$
\end{document}


Is what is suggested achievable? From the example below, I understand that there is no efficient switch at this time between Latin and Greek math alphabets if one uses pdflatex. I also understand that one solution would be to switch to lualatex where Latin and Greek alphabets are handled differently.

-
You could conceivably check for containment in a token list with expl3 syntax. I'll write something up soon—my emacs is modal when it updates packages. –  Sean Allred Mar 16 at 17:21
Untested: \ifcat\noexpand#1\relax\mathbbgr{#1}\else\mathbb{#1}\fi. Since Greek letters are called with control sequences, while Latin letters are called by themselves, this might work. Of course \tensor{AB} would fail: only one token should be in the argument to \tensor. –  egreg Mar 16 at 17:22
@egreg Fancy (and functional)! Although this might break for Latin letters that are called by cs. –  Sean Allred Mar 16 at 17:25

I don't have the mtpro2 fonts, so I'll use a different choice of fonts.

The idea is that Latin letters are called by themselves (that is, characters), while Greek letters are called by control sequences. So

\documentclass{article}
\usepackage{bm}
\newcommand\tensor[1]{%
\ifcat\noexpand#1\relax % check if the argument is a control sequence
\bm{#1}% probably Greek
\else
\textsf{#1}% single character
\fi
}

\begin{document}
$\tensor{X}\tensor{\Lambda}$
\end{document}


Limitation. Only one token should be given as argument to \tensor. Either \tensor{AB} or \tensor{A\Lambda} or any multiple token variation thereof would fail.

A multitoken macro based on the same idea:

\documentclass{article}
\usepackage{xparse}
\usepackage{bm}

\ExplSyntaxOn
\NewDocumentCommand\tensor{m}
{
\pluton_tensor:n { #1 }
}

\cs_new_protected:Npn \pluton_tensor:n #1
{
\tl_map_inline:nn { #1 }
{
\token_if_cs:NTF ##1 { \bm { ##1 } } { \textsf { ##1 } }
}
}
\ExplSyntaxOff
\begin{document}
$\tensor{X}\tensor{\Lambda}$

$\tensor{X\Lambda}$
\end{document}


Of course this will still fail if arbitrary input is used.

A perhaps more robust version, with a fallback for unknown tokens.

\documentclass{article}
\usepackage{xparse}
\usepackage{bm}

\ExplSyntaxOn
\NewDocumentCommand\tensor{m}
{
\pluton_tensor:n { #1 }
}

\cs_new_protected:Npn \pluton_tensor:n #1
{
\tl_map_inline:nn { #1 }
{
\pluton_tensor_inner:n { ##1 }
}
}

\cs_new_protected:Npn \pluton_tensor_inner:n #1
{
\tl_if_in:VnTF \g_pluton_latin_tl { #1 }
{
\textsf { #1 } % a Latin letter
}
{
\tl_if_in:VnTF \g_pluton_greek_tl { #1 }
{
\bm { #1 } % a Greek letter
}
{
#1 % fall back
}
}
}

\tl_new:N \g_pluton_latin_tl
\tl_new:N \g_pluton_greek_tl
\tl_gset:Nn \g_pluton_latin_tl
{
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
}
\tl_gset:Nn \g_pluton_greek_tl
{
\Gamma\Delta\Theta\Lambda\Pi\Sigma\Upsilon\Phi\Chi\Psi\Omega
}

\ExplSyntaxOff
\begin{document}
$\tensor{X}\tensor{\Lambda}$

$\tensor{X\Lambda}$
\end{document}

-

If you wanted something more flexible, perhaps this can be of use in the future:

\documentclass{book}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\keys_define:nn { pluton / tensor } {
latin          .tl_set:N = \pluton_tensor_latin_tl,
greek          .tl_set:N = \pluton_tensor_greek_tl,
latin-alphabet .tl_set:N = \pluton_tensor_latin_alphabet_tl,
greek-alphabet .tl_set:N = \pluton_tensor_greek_alphabet_tl,
}
\cs_new:Nn \pluton_tensor:n {
\tl_if_in:NnTF \pluton_tensor_latin_alphabet_tl { #1 } {
\pluton_tensor_latin_tl { #1 }
} {
\tl_if_in:NnT \pluton_tensor_greek_alphabet_tl { #1 } {
\pluton_tensor_greek_tl { #1 }
}
}
}
\NewDocumentCommand \tensor { O{} m } {
\group_begin:
\keys_set:nn { pluton / tensor } {
latin-alphabet = abcdefhijklmnopqrstuvwxyz
ABCDEFHIJKLMNOPQRSTUVWXYZ,
greek-alphabet = \alpha\beta\delta\epsilon
\phi\gamma\eta\iota\theta
\kappa\lambda\mu\nu\pi\chi
\rho\sigma\tau\omega\xi\psi\xi
\Alpha\Beta\Delta\Epsilon  % capitals; some of
\Phi\Gamma\Eta\Iota\Theta  % these *definitely*
\Kappa\Lambda\Mu\Nu\Pi\Chi % aren't defined, but
\Rho\Sigma\Tau\Omega\Xi\Psi\Xi, % emacs helps :)
latin = \mathbf,
greek = \mathrm,
#1
}
\pluton_tensor:n { #2 }
\group_end:
}
\ExplSyntaxOff
\begin{document}
$\tensor{A}$ $\tensor{\Lambda}$
\end{document}

-
This looks very nice, even though I am not familiar with expl3. Thanks. –  pluton Mar 16 at 18:31