3

I am looking for a way to automatically bold certain characters in math mode (for vectors and matrices) but not if the character is followed by an underscore. The substitution of normal characters to their bold counterparts should only happen in math mode.

Ideally, the code

\DeclareVectors{abuvxyz}
\DeclareMatrices{ABM}
\DeclareBB{R}

$A\in R^{q\times n}$ is a matrix with entries $A_{ij}$ and

$v\in R^n$ is a vector with $n$ coordinates, i.e., $v=(v_1,...,v_n)$.

should automatically produce the image desired output The question is how to write the commands

\DeclareVectors{abuvxyz}
\DeclareMatrices{ABM}
\DeclareBB{R}

or if there exists a package that provides the desired behavior.

The closest solution appears to be how to automatic mathbold all capital letters?, although it does not provide a solution to unbold letters that are followed by underscore as in v_1,...,v_n.

Some Remarks:

  • the goal is to improve code readability and reduce as much as possible code overhead. Commands \bm, \boldsymbol etc could of course be used but that is not the goal.
  • to reduce typing overhead, https://tex.stackexchange.com/a/45724/207532 is interesting but I hope that a solution can get a step further and reduce the need to type backslashes entirely.
  • What if you want both a scalar V and a matrix V in the document? That's a tradeoff, if a solution working as above exists, you would have to choose for each letter to be either bold or normal or bb.
jlewk
  • 183
  • If the goal is to have more-readable code, another option is to paste in and from the Mathematical Unicode Symbols block into your UTF-8 source. In the modern toolchain with unicode-math, this just works. With legacy font packages, you could load newunicodechar and enable it with \newunicodechar{}{\ensuremath{\mathbf A}}, etc. – Davislor Apr 20 '20 at 02:15
  • Beyond readable code, my motivations are typing speed and to relieve my pinky (typing too many backslashes hurt). Is there an efficient way to input and without copy-pasting? – jlewk Apr 20 '20 at 02:32

2 Answers2

3

You will soon regret doing this, because it's rather inflexible.

\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\n}{m}
 {
  \cs_if_exist_use:cF { __jlewk_mathchar_#1: } { #1 }
 }

\NewDocumentCommand{\DeclareVectors}{m}
 {
  \tl_map_function:nN { #1 } \jlewk_make_vector:n
 }
\NewDocumentCommand{\DeclareMatrices}{m}
 {
  \tl_map_function:nN { #1 } \jlewk_make_matrix:n
 }
\NewDocumentCommand{\DeclareNumbersets}{m}
 {
  \tl_map_function:nN { #1 } \jlewk_make_numberset:n
 }

\cs_new_protected:Nn \jlewk_make_vector:n
 {
  \jlewk_make_check:Nn \mathbf { #1 }
 }
\cs_new_protected:Nn \jlewk_make_matrix:n
 {
  \jlewk_make_check:Nn \mathsf { #1 }
 }
\cs_new_protected:Nn \jlewk_make_numberset:n
 {
  \cs_new_protected:cn { __jlewk_char_#1: }
   { 
    \mathbb { \use:c { __jlewk_mathchar_#1: } }
   }
  \exp_args:Nc \mathchardef { __jlewk_mathchar_#1: }=\char_value_mathcode:n {`#1}
  \char_set_active_eq:Nc #1 { __jlewk_char_#1: }
  \AtBeginDocument
   {
    \char_set_mathcode:nn { `#1 } { "8000 }
   }
 }

\cs_new_protected:Nn \jlewk_make_check:Nn
 {
  \cs_new_protected:cn { __jlewk_char_#2: } { \jlewk_check:Nn #1 { #2 } }
  \exp_args:Nc \mathchardef { __jlewk_mathchar_#2: }=\char_value_mathcode:n {`#2}
  \char_set_active_eq:Nc #2 { __jlewk_char_#2: }
  \AtBeginDocument
   {
    \char_set_mathcode:nn { `#2 } { "8000 }
   }
 }
\cs_new_protected:Nn \jlewk_check:Nn
 {
  \peek_catcode:NTF \c_math_subscript_token
   {
    \use:c { __jlewk_mathchar_#2: }
   }
   {
    #1 { \use:c { __jlewk_mathchar_#2: } }
   }
 }

\ExplSyntaxOff

\DeclareVectors{abuvxyz}
\DeclareMatrices{ABM}
\DeclareNumbersets{R}

\begin{document}

$v=(v_1,v_2,\dots,v_n)\in R^n$

$A$ is a matrix

$\n{A}$ is not a matrix, nor $\n{R}$ is a number set and $\n{v}$ is normal

\end{document}

You need to make the character math active so that it outputs itself by mathcode, possibly as the argument of the appropriate font changing command.

So a number of character dependent functions are defined. Vectors and matrices use the check for a following _.

You can “deactivate” a character by using it as the single argument to \n.

enter image description here

egreg
  • 1,121,712
  • This is godsend. Thanks a lot. a_i^2 works as expected but a^2_i does not--I am not sure if that's easily fixable yet, I will try to understand your code. – jlewk Apr 18 '20 at 20:53
  • I am also wondering about a "deactivate" command that would let us define \newcommand{\E}{{\mathbb E}} even if \DeclareMatrices{E} is set, by writing instead \newcommand{\E}{\deactivate{{\mathbb E}}} – jlewk Apr 18 '20 at 20:58
  • 1
    @jlewk I said that this is rather inflexible and not really usable. You asked for “immediately followed by _”. It could be fixable, but the code would become very fragile. Learn to type v_i^2. Or learn to mark up your document in a clear way and you'll be happier. – egreg Apr 18 '20 at 21:01
  • I absolutely intend to use it :) Thanks again – jlewk Apr 18 '20 at 21:04
  • @jlewk I added a “deactivation” macro. – egreg Apr 18 '20 at 21:12
  • Thanks a lot. I found that the following code prevents operators such as \lim, \max, \sup from being modified by @egreg's code. ``\usepackage{bm}

    \makeatletter \renewcommand{\operator@font}{\mathrm{} \mathgroup\symoperators } \makeatother``

    – jlewk Apr 18 '20 at 23:58
  • Deactivation for single letters can also be obtained with a_{}, A_{} etc. It rather makes sense in hindsight but it took me some time to realize – jlewk Apr 19 '20 at 06:18
  • @egreg -- Consider the effect if a person trying to read a document is visually impaired, and must resort to an audio system. I'm not sure the result A_{} would be at all clear (although that isn't your suggestion). – barbara beeton Apr 20 '20 at 03:17
2

Given your stated goal of more-readable source, you might instead paste in the symbols from the Mathematical Unicode Characters block into your UTF-8 source file. An efficient way to enter them without copy-pasting would be to open up a character-map app (such as charmap on Windows or gnome-character-map on Linux).

In the modern toolchain with unicode-math, this just works, like a lot of other things. The legacy toolchain can be set up to support this with newunicodechar. You might find isomath and mathalpha useful for loading more math alphabets.

\documentclass{book}
\usepackage{iftex}

\ifPDFTeX
  \usepackage[T1]{fontenc}
  \usepackage[utf8]{inputenc} % The default since 2018.
  \usepackage{amsmath, amssymb}
  \usepackage{newunicodechar}

  \newunicodechar{}{\ensuremath{\mathbf A}}
  \newunicodechar{}{\ensuremath{\mathbf v}}
  \newunicodechar{ℝ}{\ensuremath{\mathbb R}}
\else
  \usepackage{unicode-math}
\fi

\begin{document}

$\in ℝ^{q\times n}$ is a matrix with entries $A_{ij}$ and

$\in ℝ^n$ is a vector with $n$ coordinates, i.e., $=(v_1,...,v_n)$

\end{document}

Font Sample

Davislor
  • 44,045