7

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 '14 at 17:21
  • 3
    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 '14 at 17:22
  • @egreg Fancy (and functional)! Although this might break for Latin letters that are called by cs. – Sean Allred Mar 16 '14 at 17:25
11

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}

enter image description here

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}
  • Why not just \ifcat#1A to check if #1 is in category 13 (letters)? – FUZxxl Sep 27 '17 at 20:31
6

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 '14 at 18:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.