siunitx does not detect semi-bold font

If you are willing/able to use fontspec with XeLaTeX or LuaLaTeX and OpenType fonts, it works out of the box, using fontspec features to set the desired bold weight, like so:

\setsansfont{Myriad Pro}[BoldFont=Myriad Pro Semibold]

The complete code:

\documentclass{article}
\usepackage{fontspec}
\setsansfont{Myriad Pro}[BoldFont=Myriad Pro Semibold]
\usepackage[detect-all]{siunitx}

\begin{document}\sffamily
\textbf{\SI{230}{\volt} line voltage}

{\bfseries \SI{230}{\volt} line voltage}

\SI{230}{\volt} line voltage
\end{document}

enter image description here


I encountered the same issue when using LaTeX (not XeLaTeX): The current version of siunitx (2018-05-27) is incompatible with the current version of FiraSans (2019-06-06). More precisely, using, for instance, “book” as the regular (medium) fontseries and/or using “semibold” as the default bold fontseries confuses siunitx to the extent that numbers that should be regular are set in boldface and vice versa.

Based on Tobi’s code, I was able to solve the issue as follows (the relevant part is between % ==> and % <==):

% !TeX program = pdflatex


\documentclass[10pt, DIV=14]{scrartcl}


\usepackage[T1]{fontenc}

\usepackage[charter]{mathdesign}
\usepackage[scale=0.96]{XCharter}
\usepackage{FiraMono}
\usepackage[book, semibold, scale=0.92, lining, tabular]{FiraSans}
\DeclareRobustCommand{\lseries}{\fontseries{light}\selectfont}
\DeclareRobustCommand{\thseries}{\fontseries{thin}\selectfont}
\DeclareTextFontCommand{\textth}{\thseries}
\DeclareRobustCommand{\ulseries}{\fontseries{ultralight}\selectfont}
\DeclareTextFontCommand{\textul}{\ulseries}
\DeclareRobustCommand{\elseries}{\fontseries{extralight}\selectfont}
\DeclareTextFontCommand{\textel}{\elseries}
\DeclareRobustCommand{\ltseries}{\fontseries{light}\selectfont}
\DeclareTextFontCommand{\textlt}{\ltseries}
\DeclareRobustCommand\bkseries{\fontseries{book}\selectfont}
\DeclareTextFontCommand{\textbk}{\bkseries}
\DeclareRobustCommand\rgseries{\fontseries{regular}\selectfont}
\DeclareTextFontCommand{\textrg}{\rgseries}
\DeclareRobustCommand\meseries{\fontseries{medium}\selectfont}
\DeclareTextFontCommand{\textme}{\meseries}
\DeclareRobustCommand\sbseries{\fontseries{semibold}\selectfont}
\DeclareTextFontCommand{\textsb}{\sbseries}
\DeclareRobustCommand\bdseries{\fontseries{bold}\selectfont}
\DeclareTextFontCommand{\textbd}{\bdseries}
\DeclareRobustCommand\xbseries{\fontseries{extrabold}\selectfont}
\DeclareTextFontCommand{\textxb}{\xbseries}
\DeclareRobustCommand\hvseries{\fontseries{heavy}\selectfont}
\DeclareTextFontCommand{\texthv}{\hvseries}

\usepackage{siunitx}
\sisetup{detect-all}

% Fix incompatibility of siunitx (v2018-05-17) with FiraSans (v2019-06-06)
% ==>
\ExplSyntaxOn\makeatletter
\newcommand{\thisseries}{\f@series}
\newcommand{\thisshape}{\f@shape}
\cs_set_protected:Npn \__siunitx_detect_font_weight_text: {%
    \let\origmdseries\mdseries@sf%
    \let\origbfseries\bfseries@sf%
    \let\currentseries\f@series%
    \edef\XcurrentseriesX{/\f@series/}
        % Store the current fontseries but enclose it in some kind of delimiter,
        % because otherwise one-letter fontseries may erroneously triger \boldmath
        % (for instance, ``m'' is contained in ``semibold'')
    % Use \boldmath for any weight above semibold:
    \tl_if_in:noTF
        { /sb/ /b/ /bx/ /eb/ /ub/ /bold/ /extrabold/ /ultrabold/ /heavy/ /black/ /demibold/ /semibold/ }
        { \XcurrentseriesX }
        {% if included in the above list: switch to \mathversion{bold}
            \cs_set:Nn \__siunitx_font_weight: {%
                \boldmath%
                \let\bfseries@sf\currentseries%
                % necessary because siunitx in some way accesses
                % \bfseries@sf from the mweights package
                \fontseries{\bfseries@sf}\selectfont%
            }%
            \let\bfseries@sf\origbfseries%  % restore \bfseries@sf
        }
        {% if not: use \mathversion{normal}
            \cs_set:Nn \__siunitx_font_weight: {%
                \unboldmath
                \let\mdseries@sf\currentseries%
                % necessary because siunitx in some way accesses
                % \bfseries@sf from the mweights package
                \fontseries{\mdseries@sf}\selectfont%
            }%
            \let\mdseries@sf\origmdseries%  % restore \mdseries@sf
        }%
}
\makeatother\ExplSyntaxOff
% <==

\newcommand{\testSI}{%
    \begin{tabular}{@{} p{0.15\textwidth} *{3}{p{0.2\textwidth}} @{}}
        \thisseries/\thisshape &
        \SI{1.234e-5}{\micro\farad} &
        $\SI{1.234e-5}{\micro\farad}$ &
        $1.234 \times 10^{-5} \mathrm{\mu F}$
    \end{tabular}%
}


\begin{document}


\section*{Serif font (XCharter)}

\textmd{\testSI -- \texttt{\textbackslash textmd}} \\
\textbf{\testSI -- \texttt{\textbackslash textbf}} \\
\itshape
\textmd{\testSI -- \texttt{\textbackslash textmd}} \\
\textbf{\testSI -- \texttt{\textbackslash textbf}} \\
\upshape
\testSI -- back to default


\sffamily

\section*{Fira Sans upright shapes}

\textmd{\testSI -- \texttt{\textbackslash textmd}} \\
\textbf{\testSI -- \texttt{\textbackslash textbf}}

\smallskip
\noindent
\textth{\testSI} \\
\textul{\testSI} \\
\textel{\testSI} \\
\textlt{\testSI} \\
\textbk{\testSI} \\
\textrg{\testSI} \\
\textme{\testSI} \\
\textsb{\testSI} \\
\textbd{\testSI} \\
\textxb{\testSI} \\
\texthv{\testSI} \\
\testSI -- back to default


\section*{\textit{Fira Sans italic shapes}}

\itshape
\textmd{\testSI -- \texttt{\textbackslash textmd}} \\
\textbf{\testSI -- \texttt{\textbackslash textbf}}

\smallskip
\noindent
\textth{\testSI} \\
\textul{\testSI} \\
\textel{\testSI} \\
\textlt{\testSI} \\
\textbk{\testSI} \\
\textrg{\testSI} \\
\textme{\testSI} \\
\textsb{\testSI} \\
\textbd{\testSI} \\
\textxb{\testSI} \\
\texthv{\testSI} \\
\testSI -- back to default

\rmfamily\upshape
\section*{Serif font again}

\textmd{\testSI -- \texttt{\textbackslash textmd}} \\
\textbf{\testSI -- \texttt{\textbackslash textbf}} \\
\itshape
\textmd{\testSI -- \texttt{\textbackslash textmd}} \\
\textbf{\testSI -- \texttt{\textbackslash textbf}} \\
\upshape
\testSI -- back to default

\smallskip
\noindent
It works! :-)


\end{document}

Here’s a screenshot of the output:

FiraSans and siunitx


Today I had the same problem. The cause is that the detection of weights relies on the first letter of the series and only checks for b(bold) and l (light). Therefore all other weighs are ignored. I posted an issue on GitHub.

A hacky solution would be to redefine an internal macro of siunitx, which is actually “forbidden” in LaTeX3 conventions and not reliable for future changes. Here’s an example using Open Sans (free) and fontspec to access all weights. The relevant code is between snip and snap

enter image description here

% !TeX program = xelatex
\documentclass[parskip=full]{scrartcl}

\usepackage{fontspec}
\setmainfont{Open Sans}[
   LetterSpace = 2,
   FontFace = {lt}{n}{* Light},
   FontFace = {sb}{n}{* Semibold},
   FontFace = {bf}{n}{* Bold},
   FontFace = {xb}{n}{* Extrabold},
   FontFace = {lt}{it}{* Light Italic},
   FontFace = {sb}{it}{* Semibold Italic},
   FontFace = {bf}{it}{* Bold Italic},
   FontFace = {xb}{it}{* Extrabold Italic},
]
\DeclareRobustCommand\ltseries{\fontseries{lt}\selectfont}
\DeclareTextFontCommand{\textlt}{\ltseries}
\DeclareRobustCommand\sbseries{\fontseries{sb}\selectfont}
\DeclareTextFontCommand{\textsb}{\sbseries}
\DeclareRobustCommand\xbseries{\fontseries{xb}\selectfont}
\DeclareTextFontCommand{\textxb}{\xbseries}

\usepackage{siunitx}
\sisetup{detect-all}

\ExplSyntaxOn\makeatletter

% --- snip ---
\cs_generate_variant:Nn \tl_if_in:nnTF { noTF }
\cs_set_protected:Npn \__siunitx_detect_font_weight_text: {
  \tl_if_in:noTF { sb bf xb } { \f@series }
    {
      \cs_set:Nn \__siunitx_font_weight: { \boldmath \use:c { \f@series series } }
    }
    {
      \cs_set:Nn \__siunitx_font_weight: { \use:c { \f@series series } }
    }
}
% --- snap ---

\makeatother\ExplSyntaxOff

\begin{document}
Upright shapes:

\textlt{Light: \SI{1.234e-5}{\micro\farad}}

Normal: \SI{1.234e-5}{\micro\farad}

\textsb{Semibold: \SI{1.234e-5}{\micro\farad}}

\textbf{Bold: \SI{1.234e-5}{\micro\farad}}

\textxb{Extrabold: \SI{1.234e-5}{\micro\farad}}


\bigskip
Italic shapes:

\itshape
\textlt{Light Italic: \SI{1.234e-5}{\micro\farad}}

Normal Italic: \SI{1.234e-5}{\micro\farad}

\textsb{Semibold Italic: \SI{1.234e-5}{\micro\farad}}

\textbf{Bold Italic: \SI{1.234e-5}{\micro\farad}}

\textxb{Extrabold Italic: \SI{1.234e-5}{\micro\farad}}
\end{document}

Tags:

Fonts

Siunitx