% \iffalse meta-comment
%
% File: siunitx-print.dtx Copyright (C) 2016-2017 Joseph Wright
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file
%
%    https://www.latex-project.org/lppl.txt
%
% This file is part of the "siunitx bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% The released version of this bundle is available from CTAN.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
%    https://github.com/josephwright/siunitx
%
% for those people who are interested.
%
% -----------------------------------------------------------------------
%
%<*driver>
\documentclass{l3doc}
% The next line is needed so that \GetFileInfo will be able to pick up
% version data
\usepackage{siunitx}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \GetFileInfo{siunitx.sty}
%
% \title{^^A
%   \pkg{siunitx-print} -- Printing material with font control^^A
%   \thanks{This file describes \fileversion,
%     last revised \filedate.}^^A
% }
%
% \author{^^A
%  Joseph Wright^^A
%  \thanks{^^A
%    E-mail:
%    \href{mailto:joseph.wright@morningstar2.co.uk}
%      {joseph.wright@morningstar2.co.uk}^^A
%   }^^A
% }
%
% \date{Released \filedate}
%
% \maketitle
%
% \begin{documentation}
%
% This submodule is focussed on providing controlled printing for numbers and
% units. Key to this is control of font: conventions for printing quantities
% mean that the exact nature of the output is important. At the same time, this
% module provides flexibility for the user in terms of which aspects of the font
% are responsive to the surrounding general text. Printing material may also
% take place in text or math mode.
%
% The printing routines assume that normal \LaTeXe{} font selection commands
% are available, in particular \cs{bfsries}, \cs{mathrm}, \cs{mathversion},
% \cs{mdseries}, \cs{rmfamily} and \cs{upshape}. It also requires the standard
% \LaTeXe{} kernel commands \cs{ensuremath}, \cs{textsubscript} and
% \cs{textsuperscript} for printing in text mode. The following packages are
% also required to provide the functionality detailed.
% \begin{itemize}
%   \item \pkg{color}: support for color using \cs{textcolor}
%   \item \pkg{textcomp}: \cs{textminus} and \cs{textpm} for printing
%     in text mode
%   \item \pkg{amstext}: the \cs{text} command for printing in text mode
% \end{itemize}
%
% \begin{function}{\siunitx_print:nn, \siunitx_print:nV}
%   \begin{syntax}
%     \cs{siunitx_print:nn} \Arg{type} \Arg{material}
%   \end{syntax}
%   Prints the \meta{material} according the the prevailing settings for the
%   submodule as applicable to the \meta{type} of content: the latter should be
%   either |number| or |unit|. The \meta{material} should comprise normal
%   \LaTeX{} mark-up for numbers or units. In particular, units will typically
%   use |\mathrm| to indicate material to be printed in the current upright
%   roman font, and |^| and |_| will typically be used to indicate super- and
%   subscripts, respectively. These elements will be correctly handled when
%   printing for example using |\mathsf| in math mode, or using only text
%   fonts.
% \end{function}
%
% \begin{variable}{\l_siunitx_print_series_prop}
%   This properly list contains mappings from text mode font weights to math
%   mode font versions. The standard settings here cover
%   \begin{itemize}
%     \item[\texttt{m}] Standard (mid) weight, mapping to math version
%       |normal|.
%     \item[\texttt{bx}] Bold exanded weight, mapping to math version |bold|.
%     \item[\texttt{lt}] Light weight, mapping to math version |light|.
%     \item[\texttt{l}] Light weight, mapping to math version |light|.
%   \end{itemize}
% \end{variable}
%
% \subsection{Key--value options}
%
% The options defined by this submodule are available within the \pkg{l3keys}
% |siunitx| tree.
%
% \begin{function}{color}
%   \begin{syntax}
%     |color| = \meta{color}
%   \end{syntax}
%   Color to apply to printed output: the latter should be a named color
%   defined for use with \cs{textcolor}. The standard setting is empty (no
%   color).
% \end{function}
%
% \begin{function}{mode}
%   \begin{syntax}
%     |mode| = \meta{choice}
%   \end{syntax}
%   Selects which mode (math or text) the output is printed in: a choice
%   from the options |match|, |math| or |text|. The option |match| matches
%   the mode prevailing at the point \cs{siunitx_print:nn} is called. The
%   |math| and |text| options choose the relevant \TeX{} mode for printing.
%   The standard setting is |math|.
% \end{function}
%
% \begin{function}{number-color}
%   \begin{syntax}
%     |number-color| = \meta{color}
%   \end{syntax}
%   Color to apply to numbers in output: the latter should be a named color
%   defined for use with \cs{textcolor}. The standard setting is empty (no
%   color).
% \end{function}
%
% \begin{function}{number-mode}
%   \begin{syntax}
%     |number-mode| = \meta{choice}
%   \end{syntax}
%   Selects which mode (math or text) the numbers are printed in: a choice
%   from the options |match|, |math| or |text|. The option |match| matches
%   the mode prevailing at the point \cs{siunitx_print:nn} is called. The
%   |math| and |text| options choose the relevant \TeX{} mode for printing.
%   The standard setting is |math|.
% \end{function}
%
% \begin{function}{propagate-math-font}
%   \begin{syntax}
%     |propagate-math-font| = |true|\verb"|"|false|
%   \end{syntax}
%   Switch to determine if the currently-active math font is applied within
%   printed output. This is relevant only when \cs{siunitx_print:nn} is
%   called from within math mode: in text mode there is not active math
%   font. When not active, math mode material will be typeset using
%   standard math mode fonts without any changes being made to the
%   supplied argument. The standard setting is |false|.
% \end{function}
%
% \begin{function}{reset-math-version}
%   \begin{syntax}
%     |reset-math-version| = |true|\verb"|"|false|
%   \end{syntax}
%   Switch to determine whether the active \cs{mathversion} is reset to
%   |normal| when printing in math mode. Note that math version is typically
%   used to select \cs{boldmath}, though it is also be used by
%   \foreign{e.g.}~\pkg{sansmath}. The standard setting is |true|.
% \end{function}
%
% \begin{function}{reset-text-family}
%   \begin{syntax}
%     |reset-text-family| = |true|\verb"|"|false|
%   \end{syntax}
%   Switch to determine whether the active math family is reset to
%   \cs{rmfamily} when printing in text mode. The standard setting is |true|.
% \end{function}
%
% \begin{function}{reset-text-series}
%   \begin{syntax}
%     |reset-text-series| = |true|\verb"|"|false|
%   \end{syntax}
%   Switch to determine whether the active math series is reset to
%   \cs{mdseries} when printing in text mode. The standard setting is |true|.
% \end{function}
%
% \begin{function}{reset-text-shape}
%   \begin{syntax}
%     |reset-text-shape| = |true|\verb"|"|false|
%   \end{syntax}
%   Switch to determine whether the active math shape is reset to
%   \cs{upshape} when printing in text mode. The standard setting is |true|.
% \end{function}
%
% \begin{function}{text-family-to-math}
%   \begin{syntax}
%     |text-family-to-math| = |true|\verb"|"|false|
%   \end{syntax}
%   Switch to determine if the family of the current text font should be
%   applied (where possible) to printing in math mode. The standard setting is
%   |false|.
% \end{function}
%
% \begin{function}{text-weight-to-math}
%   \begin{syntax}
%     |text-weight-to-math| = |true|\verb"|"|false|
%   \end{syntax}
%   Switch to determine if the weight of the current text font should be
%   applied (where possible) to printing in math mode. This is achieved by
%   setting the \cs{mathversion}, and so will override |reset-math-version|.
%   The mappings between text and math weight are stored in
%   \cs{l_siunitx_print_series_prop}. The standard setting is |false|.
% \end{function}
%
% \begin{function}{unit-color}
%   \begin{syntax}
%     |unit-color| = \meta{color}
%   \end{syntax}
%   Color to apply to units in output: the latter should be a named color
%   defined for use with \cs{textcolor}. The standard setting is empty (no
%   color).
% \end{function}
%
% \begin{function}{unit-mode}
%   \begin{syntax}
%     |unit-mode| = \meta{choice}
%   \end{syntax}
%   Selects which mode (math or text) units are printed in: a choice
%   from the options |match|, |math| or |text|. The option |match| matches
%   the mode prevailing at the point \cs{siunitx_print:nn} is called. The
%   |math| and |text| options choose the relevant \TeX{} mode for printing.
%   The standard setting is |math|.
% \end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{siunitx-print} implementation}
%
% Start the \pkg{DocStrip} guards.
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention): only
% internal material in this \emph{submodule} should be used directly.
%    \begin{macrocode}
%<@@=siunitx_print>
%    \end{macrocode}
%
% \subsection{Initial set up}
%
% The printing routines depend on \pkg{amstext} for text mode working.
%    \begin{macrocode}
\RequirePackage { amstext }
%    \end{macrocode}
%
% Color support is always required.
%    \begin{macrocode}
\RequirePackage { color }
%    \end{macrocode}
%
% For a sensible \cs{textminus} we load \pkg{textcomp} if \pkg{fontspec}
% is not in use.
%    \begin{macrocode}
\AtBeginDocument
  {
    \@ifpackageloaded { fontspec }
      { }
      { \RequirePackage { textcomp } }
  }
%    \end{macrocode}
%
% \begin{variable}{\l_@@_tmp_box}
%   Scratch space.
%    \begin{macrocode}
\box_new:N \l_@@_tmp_box
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\document}
% \begin{macro}{\@@_store_fam:n}
% \begin{variable}{\c_@@_mathrm_int, \c_@@_mathsf_int, \c_@@_mathtt_int}
%   In order to test math fonts, we need information about the \cs{fam} used
%   by the various options. This is run as a hook onto \cs{document}, rather
%   than using \tn{AtBeginDocument} as it has to come after anything that
%   \pkg{fontspec} does (nasty errors arise otherwise). As this is a true
%   one-off, we avoid wasting a box.
%    \begin{macrocode}
\tl_put_right:Nn \document
  {
    \@@_store_fam:n { rm }
    \@@_store_fam:n { sf }
    \@@_store_fam:n { tt }
    \ignorespaces
  }
\cs_new_protected:Npn \@@_store_fam:n #1
  {
    \group_begin:
      \hbox_set:Nn \l_@@_tmp_box
        {
          \ensuremath
            {
              \use:c { math #1 }
                { \int_const:cn { c_@@_math #1 _int } { \fam } }
            }
        }
    \group_end:
  }
%    \end{macrocode}
% \end{variable}
% \end{macro}
% \end{macro}
%
% \subsection{Printing routines}
%
% \begin{variable}
%   {
%     \l_@@_number_color_tl   ,
%     \l_@@_number_mode_tl    ,
%     \l_@@_unit_color_tl     ,
%     \l_@@_unit_mode_tl      ,
%     \l_@@_math_font_bool    ,
%     \l_@@_math_version_bool ,
%     \l_@@_math_family_bool  ,
%     \l_@@_math_weight_bool  ,
%     \l_@@_text_family_tl    ,
%     \l_@@_text_series_tl    ,
%     \l_@@_text_shape_tl
%   }
%   Options which apply to the main formatting routine, and so are not tied
%   to either symbolic or literal input.
%    \begin{macrocode}
\tl_new:N \l_@@_number_mode_tl
\tl_new:N \l_@@_unit_mode_tl
\keys_define:nn { siunitx }
  {
    color .meta:n =
      { number-color = #1 , unit-color = #1 } ,
    mode .meta:n =
      { number-mode = #1 , unit-mode = #1 } ,
    number-color .tl_set:N =
      \l_@@_number_color_tl ,
    number-mode .choices:nn =
      { match , math , text }
      {
        \tl_set_eq:NN
          \l_@@_number_mode_tl \l_keys_choice_tl
      } ,
    propagate-math-font .bool_set:N =
      \l_@@_math_font_bool ,
    reset-math-version .bool_set:N =
      \l_@@_math_version_bool ,
    reset-text-family .bool_set:N =
      \l_@@_text_family_bool ,
    reset-text-series .bool_set:N =
      \l_@@_text_series_bool ,
    reset-text-shape .bool_set:N =
      \l_@@_text_shape_bool ,
    text-family-to-math .bool_set:N =
      \l_@@_math_family_bool ,
    text-weight-to-math .bool_set:N =
      \l_@@_math_weight_bool ,
    unit-color .tl_set:N =
      \l_@@_unit_color_tl ,
    unit-mode .choices:nn =
      { match , math , text }
      {
        \tl_set_eq:NN
          \l_@@_unit_mode_tl \l_keys_choice_tl
      }
  }
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\siunitx_print:nn, \siunitx_print:nV}
%   The main printing function doesn't actually need to do very much: just set
%   the color and select the correct sub-function.
%    \begin{macrocode}
\cs_new_protected:Npn \siunitx_print:nn #1#2
  {
    \tl_if_empty:cTF { l_@@_ #1 _color_tl }
      { \use:n }
      { \exp_args:Nv \textcolor { l_@@_ #1 _color_tl } }
        {
          \use:c
            {
              @@_
              \tl_use:c { l_@@_ #1 _mode_tl } :n
            }
              {#2}
        }
  }
\cs_generate_variant:Nn \siunitx_print:nn { nV }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_match:n}
%   When the \emph{output} mode should match the input, a simple selection of
%   route can be made.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_match:n #1
  {
    \mode_if_math:TF
      { \@@_math:n {#1} }
      { \@@_text:n {#1} }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{variable}{\l_siunitx_print_series_prop}
%   Mapping data to relate text series to math version.
%    \begin{macrocode}
\prop_new:N \l_siunitx_print_series_prop
\prop_put:Nnn \l_siunitx_print_series_prop { m }  { normal }
\prop_put:Nnn \l_siunitx_print_series_prop { bx } { bold }
\prop_put:Nnn \l_siunitx_print_series_prop { l }  { light }
\prop_put:Nnn \l_siunitx_print_series_prop { lt } { light }
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\@@_math:n}
% \begin{macro}{\@@_math_version:nn, \@@_math_version:Vn}
% \begin{macro}
%   {
%     \@@_math_auxi:n,
%     \@@_math_auxii:n,
%     \@@_math_auxiii:n,
%     \@@_math_auxiv:n,
%     \@@_math_auxv:n
%   }
% \begin{macro}{\@@_math_aux:Nn, \@@_math_aux:cn}
% \begin{macro}{\@@_math_sub:n, \@@_math_super:n, \@@_math_script:n}
% \begin{macro}{\@@_math_text:n}
%   The first step in setting in math mode is to check on the math version.
%   The starting point is the question of whether text series needs to
%   propagate to math mode: if so, check on the mapping, otherwise check on
%   the current math version.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_math:n #1
  {
    \bool_if:NTF \l_@@_math_weight_bool
      {
        \prop_get:NVNTF \l_siunitx_print_series_prop
          \f@series \l_@@_tmp_tl
          { \@@_math_version:Vn \l_@@_tmp_tl {#1} }
          { \@@_math_auxi:n {#1} }
      }
      { \@@_math_auxi:n {#1} }
  }
\cs_new_protected:Npn \@@_math_auxi:n #1
  {
    \bool_if:NTF \l_@@_math_version_bool
      { \@@_math_version:nn { normal } {#1} }
      { \@@_math_auxii:n {#1} }
  }
%    \end{macrocode}
%   Any setting which changes the math version can only be set from text mode
%   (as it applies at the level of a formula). As such, the first test is to
%   see if that needs to be to check if the math version has to be set: if so,
%   switch to text mode, sort it out and switch back. That of course means
%   that in such cases, line breaking will not be possible.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_math_version:nn #1#2
  {
    \str_if_eq_x:nnTF { \math@version } { #1 }
      { \@@_math_auxii:n {#2} }
      {
        \mode_if_math:TF
          { \text }
          { \use:n }
            {
              \mathversion {#1}
              \@@_math_auxii:n {#2}
            }
       }
  }
\cs_generate_variant:Nn \@@_math_version:nn { V }
%    \end{macrocode}
%   At this point, force math mode then start dealing with setting math font
%   based on text family. If the text family is roman, life is slightly
%   different to if it is sanserif or monospaced. In all cases, the outcomes
%   can be handled using the same routines as for normal math mode treatment.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_math_auxii:n #1
  { \ensuremath { \@@_math_auxiii:n {#1} } }
\cs_new_protected:Npn \@@_math_auxiii:n #1
  {
    \bool_if:NTF \l_@@_math_family_bool
      {
        \str_case_x:nnF { \f@family }
          {
            { \rmdefault } { \@@_math_auxv:n }
            { \sfdefault } { \@@_math_aux:Nn \mathsf }
            { \ttdefault } { \@@_math_aux:Nn \mathtt }
          }
          { \@@_math_auxiv:n }
      }
      { \@@_math_auxiv:n }
        {#1}
  }
%    \end{macrocode}
%   Now we deal with the font selection in math mode. There are two possible
%   cases. First, we are retaining the current math font, and the active one is
%   \cs{mathsf} or \cs{mathtt}: that needs to be applied to the argument.
%   Alternatively, if the current font is not retained, ensure that
%   normal math mode rules are active. The parts here are split up to allow
%   reuse when picking up the text family.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_math_auxiv:n #1
  {
    \bool_if:NTF \l_@@_math_font_bool
      {
        \int_case:nnF \fam
          {
            \c_@@_mathsf_int { \@@_math_aux:Nn \mathsf }
            \c_@@_mathtt_int { \@@_math_aux:Nn \mathtt }
          }
          { \use:n }
      }
      { \@@_math_auxv:n }
        {#1}
  }
\cs_new_protected:Npn \@@_math_auxv:n #1
  {
    \bool_lazy_or:nnTF
      { \int_compare_p:nNn \fam = { -1 } }
      { \int_compare_p:nNn \fam = \c_@@_mathrm_int }
      { \use:n }
      { \mathrm }
        {#1}
  }
%    \end{macrocode}
%   Search-and-replace fun: deal with any \cs{mathrm} in the argument and
%   also inside sub/superscripts.
%    \begin{macrocode}
\cs_new_protected:Npx \@@_math_aux:Nn #1#2
  {
    \group_begin:
      \tl_set:Nn \exp_not:N \l_@@_tmp_tl {#2}
      \tl_replace_all:Nnn \exp_not:N \l_@@_tmp_tl
        { \exp_not:N \mathrm } { \exp_not:N \use:n }
      \tl_replace_all:Nnn \exp_not:N \l_@@_tmp_tl
        { \char_generate:nn { `\_ } { 8 } }
        { \exp_not:N \@@_math_sub:n }
      \tl_replace_all:Nnn \exp_not:N \l_@@_tmp_tl
        { ^ }
        { \exp_not:N \@@_math_super:n }
      #1 { \exp_not:N \tl_use:N \exp_not:N \l_@@_tmp_tl }
    \group_end:
  }
\cs_generate_variant:Nn \@@_math_aux:Nn { c }
\cs_new_protected:Npx \@@_math_sub:n #1
  {
    \char_generate:nn { `\_ } { 8 }
      { \exp_not:N \@@_math_script:n {#1} }
  }
\cs_new_protected:Npn \@@_math_super:n #1
  { ^ { \@@_math_script:n {#1} } }
\cs_new_protected:Npn \@@_math_script:n #1
  {
    \group_begin:
      \tl_set:Nn \l_@@_tmp_tl {#1}
      \tl_replace_all:Nnn \l_@@_tmp_tl { \mathrm } { \use:n }
      \tl_use:N \l_@@_tmp_tl
    \group_end:
  }
%    \end{macrocode}
%   To match the text mode font, there is a simple look-up of the current
%   font family. Luckily, mappings to math mode equivalents are easy. 
%    \begin{macrocode}

%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@@_text:n}
% \begin{macro}{\@@_text_replace:n}
% \begin{macro}{\@@_text_replace:N}
% \begin{macro}{\@@_text_replace:NNn}
% \begin{macro}{\@@_text_sub:n, \@@_text_super:n}
% \begin{macro}{\@@_text_scripts:NnN}
% \begin{macro}{\@@_text_scripts:}
% \begin{macro}{\@@_text_scripts_one:NnN}
% \begin{macro}{\@@_text_scripts_two:NnNn}
% \begin{macro}{\@@_text_scripts_two:nn}
% \begin{macro}{\@@_text_scripts_two:n}
%   Typesetting in text mode is easy in font control terms but more tricky
%   in the manipulation of the input. The easy part comes first.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_text:n #1
  {
    \text
      {
        \bool_if:NT \l_@@_text_family_bool
          { \rmfamily }
        \bool_if:NT \l_@@_text_series_bool
          { \mdseries }
        \bool_if:NT \l_@@_text_shape_bool
          { \upshape }
        \@@_text_replace:n {#1}
      }
  }
%    \end{macrocode}
%   To get math mode material to print in text mode, various search-and-replace
%   steps are needed. The \cs{mathrm} command is also disabled as it is
%   invalid in text mode.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_text_replace:n #1
  {
    \group_begin:
      \tl_set:Nn \l_@@_tmp_tl {#1}
      \@@_text_replace:N \l_@@_tmp_tl
      \tl_use:N \l_@@_tmp_tl
    \group_end:
  }
\cs_new_protected:Npx \@@_text_replace:N #1
  {
    \exp_not:N \@@_text_replace:NNn #1
      \exp_not:N \mathrm
        { \exp_not:N \use:n }
      \exp_not:N \pm
        { \exp_not:N \textpm }
      \exp_not:N \mp
        { \exp_not:n { \ensuremath { \mp } } }
      -
        { \exp_not:N \textminus }
      \char_generate:nn { `\_ } { 8 }
        { \exp_not:N \@@_text_sub:n }
      ^
        { \exp_not:N \@@_text_super:n }
      \exp_not:N \q_recursion_tail
        { ? }
      \exp_not:N \q_recursion_stop
  }
\cs_new_protected:Npn \@@_text_replace:NNn #1#2#3
  {
    \quark_if_recursion_tail_stop:N #2
    \tl_replace_all:Nnn #1 {#2} {#3}
    \@@_text_replace:NNn #1
  }
%    \end{macrocode}
%   Sub- and superscripts can be in any order in the source. The first step
%   of handling them is therefore to do a look-ahead to work out whether
%   only one or both are present.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_text_sub:n #1
  {
    \@@_text_scripts:NnN
      \textsubscript {#1} \@@_text_super:n
  }
\cs_new_protected:Npn \@@_text_super:n #1
  {
    \@@_text_scripts:NnN
      \textsuperscript {#1} \@@_text_sub:n
  }
\cs_new_protected:Npn \@@_text_scripts:NnN #1#2#3
  {
    \cs_set_protected:Npn \@@_text_scripts:
      {
        \if_meaning:w \l_peek_token #3
          \exp_after:wN \@@_text_scripts_two:NnNn
        \else:
          \exp_after:wN \@@_text_scripts_one:Nn
        \fi:
          #1 {#2}
      }
    \peek_after:Nw \@@_text_scripts:
  }
\cs_new_protected:Npn \@@_text_scripts: { }
%    \end{macrocode}
%   In the simple case of one script item, we have to do a search-and-replace
%   to deal with anything inside the argument.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_text_scripts_one:Nn #1#2
  {
    \group_begin:
      \tl_set:Nn \l_@@_tmp_tl {#2}
      \@@_text_replace:N \l_@@_tmp_tl
    \exp_args:NNV \group_end:
    #1 \l_@@_tmp_tl
  }
%    \end{macrocode}
%   For the two scripts case, we cannot use |\textsubscript|/|\textsuperscript|
%   as they don't stack directly. Instead, we sort out the ordering then use
%   an implementation for both parts that is the same as the kernel text
%   scripts.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_text_scripts_two:NnNn #1#2#3#4
  {
    \cs_if_eq:NNTF #1 \textsubscript
      { \@@_text_scripts_two:nn {#4} {#2} }
      { \@@_text_scripts_two:nn {#2} {#4} }
  }
\cs_new_protected:Npx \@@_text_scripts_two:nn #1#2
  {
    \group_begin:
      \exp_not:N \m@th
      \exp_not:N \ensuremath
        {
          ^ { \exp_not:N \@@_text_scripts_two:n {#1} }
          \char_generate:nn { `\_ } { 8 }
            { \exp_not:N \@@_text_scripts_two:n {#2} }
        }
    \group_end:
  }
\cs_new_protected:Npn \@@_text_scripts_two:n #1
  {
    \mbox
      {
        \fontsize \sf@size \z@ \selectfont
        \@@_text_scripts_one:Nn \use:n {#1}
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Standard settings for module options}
%
% Some of these follow naturally from the point of definition
% (\foreign{e.g.}~boolean variables are always |false| to begin with),
% but for clarity everything is set here.
%    \begin{macrocode}
\keys_set:nn { siunitx }
  {
    color               =       ,
    mode                = math  ,
    number-color        =       ,
    number-mode         = math  ,
    propagate-math-font = false ,
    reset-math-version  = true  ,
    reset-text-shape    = true  ,
    reset-text-series   = true  ,
    reset-text-family   = true  ,
    text-family-to-math = false ,
    text-weight-to-math = false ,
    unit-color          =       ,
    unit-mode           = math
  }
%    \end{macrocode}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex