Building on Ulrikes answer I want to expand her solution and also give a bit more background, what's going on here, since a number of different things are involved that complicate the situation.
First, it's worth mentioning that siunitx
can operate in two different modes, nameley mode=text
and mode=math
. The siunitx
manual says the following about this option.
The mode
option determines whether siunitx
uses math or text mode when printing output. The choices are math
and text
. When using math mode, text is printed using a math font whereas in text mode a text font is used. The extent to which this is visually obvious depends on the fonts in use in the document. [...] This option has no effect if the detect-mode
switch is true
.
Here, I only discuss the mode=text
case, since Roboto is a text font and no math font anyway. For mode=math
a similar approach should be possible.
Since the font weight needs to be detected, we need to know what the current weight is that is stored in \f@series
. For the Roboto font, this mechanism was recently changed. For example, in the package version of 2019/04/19, bold font with the medium
option is defined as
\ifroboto@medium\def\bfseries@sf{medium}\fi
whereas for the newer version of 2019/12/11 this was changed to
\ifroboto@medium\def\bfseries@sf{sb}\fi
which lead Ulrike to state that a current LaTeX version is needed. In a similar way, a number of explicit words like light
or thin
were changed to shorthands like l
or el
. This does not really cause problems for the solution to follow, but it means that it needs to be adapted to the package version.
I first address the issue of regular weight not being detected, then I turn to the problem with bold text. Ulrike stated that siunitx
only tries to find out, whether bold is active or not, but doesn't check for additional weights that a font may provide. So let's have a look at the check that siuntix
performs in text mode.
\cs_new_protected:Npn \__siunitx_detect_font_weight_text: {
\tl_set:Nx \l__siunitx_tmpa_tl { \tl_head:N \f@series }
\str_if_eq:VnT \l__siunitx_tmpa_tl { b }
{
\cs_set:Npn \__siunitx_font_weight:
{
\boldmath
\bfseries
}
}
\str_if_eq:VnT \l__siunitx_tmpa_tl { l }
{ \cs_set:Npn \__siunitx_font_weight: { \lseries } }
}
So siunitx
looks whether \f@series
starts with letter b
and if yes, sets up things for bold printing. But it also checks, whether \f@series
starts with letter l
and if yes issues \lseries
. So it looks like this should work as-is, since it would issue \lseries
for light Roboto, do nothing for medium Roboto and setup bold for \f@series
starting with b
.
So why is the output wrong after switching to medium Roboto? It turns out that in order to set number and units in sans, siunitx
invokes \sffamily
. Now when medium weight was selected by \fontseries{m}\selectfont
or \mdseries
, then \sffamily
evaluates to \mdseries@sf
, which gets defined as
\ifroboto@light\def\mdseries@sf{l}
when the roboto
package is loaded with the light
option. So that means that \sffamily
actually explicitly switches back to light weight and produces the wrong output. I'm not quite sure, which package to blame here, since for both siunitx
and roboto
individually, their approaches appear plausible, but in combination it's causing trouble.
One possible solution is given by Ulrike by (locally) redefining \sffamily
, e.g. by using the convenient command that she gives.
\DeclareFontSeriesDefault[sf]{md}{m}
Another option is to (locally) tell siunitx
to use a different command to setup sans fonts using the siunitx
option text-sf
(or number-text-sf
and unit-text-sf
) that is undocumented as far as I can tell.
\sisetup{text-sf=\sffamily\fontseries{m}\selectfont}
The problem with bold is that the medium
option of the roboto
package sets up semibold and that the corresponding sb
, well, just doesn't start with letter b
. The only way I see here, is to patch the test \__siunitx_detect_font_weight_text:
.
This approach is similar to this answer, but evidently is not very reliable. As stated in that answer and by Ulrike in her comment, it's generally not a good idea to fumble around in internal commands of packages. The implementation or even the name of \__siunitx_detect_font_weight_text:
may change with future versions of siunitx
and then the patch has to be corrected accordingly.
\apptocmd \__siunitx_detect_font_weight_text: {
\str_if_eq:VnT \f@series { sb }
{
\cs_set:Npn \__siunitx_font_weight:
{
\boldmath
\bfseries
}
}
} { } { }
This patch uses the \apptocmd
functionality from etoolbox
. Note that there is an issue on GitHub that asks to add this very functionality, so hopefully, this patch will be obsolete in the future.
Finally a complete solution that combines all of the above may look as follows.
\documentclass{article}
\usepackage{etoolbox}
\usepackage[light,medium]{roboto}
\providecommand*\lseries{\fontseries{l}\selectfont}
\usepackage{siunitx}
\sisetup{detect-weight=true,detect-family=true,mode=text}
\makeatletter
\ExplSyntaxOn
\apptocmd \__siunitx_detect_font_weight_text: {
\str_if_eq:VnT \f@series { sb }
{
\cs_set:Npn \__siunitx_font_weight:
{
\boldmath
\bfseries
}
}
} { } { }
\ExplSyntaxOff
\makeatother
\newenvironment{RobotoRegular}{%
\begingroup%
\sisetup{text-sf=\sffamily\fontseries{m}\selectfont}%
\fontseries{m}\selectfont%
}{%
\endgroup%
}
\begin{document}
\sffamily
\makeatletter f@series is: \f@series. \quad
1\,mV \SI{1}{\milli\volt}
\begin{RobotoRegular}
\makeatletter f@series is: \f@series. \quad
1\,mV \SI{1}{\milli\volt}
\end{RobotoRegular}
\begingroup
\bfseries \makeatletter f@series is: \f@series. \quad
1\,mV \SI{1}{\milli\volt}
\endgroup
\end{document}

This solution now respects the weight for all three cases. If more of the weights that the roboto
package offers are needed, of course more changes along these lines may be necessary.
detect-*
together with eithermode=text
ormode=math
. All of them give the same result as in my question.