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.
2
  • 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 2: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 2:32
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

8
  • 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
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

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.