diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx | 975 |
1 files changed, 975 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx new file mode 100644 index 00000000000..0885d4f1aa7 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx @@ -0,0 +1,975 @@ +% \iffalse meta-comment +% +% File: siunitx-print.dtx Copyright (C) 2016-2019,2021 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} +\ProvideDocumentCommand\foreign{m}{\textit{#1}} +% 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} +% +% \section{Printing quantities} +% +% 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{bfseries}, \cs{mathrm}, \cs{mathversion}, +% \cs{fontfamily}, \cs{fontseries} and \cs{fontshape}, \cs{familydefault}, +% \cs{seriesdefault}, \cs{shapedefault} and \cs{selectfont}. +% 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_number:n, \siunitx_print_number:V, +% \siunitx_print_number:x, +% \siunitx_print_unit:n, \siunitx_print_unit:V, +% \siunitx_print_unit:x +% } +% \begin{syntax} +% \cs{siunitx_print_number:n} \Arg{material} +% \cs{siunitx_print_unit:n} \Arg{material} +% \end{syntax} +% Prints the \meta{material} according the the prevailing settings for the +% submodule as applicable to the \meta{type} of content (|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{function} +% {\siunitx_print_match:n, \siunitx_print_math:n, \siunitx_print_text:n} +% \begin{syntax} +% \cs{siunitx_print_match:n} \Arg{material} +% \cs{siunitx_print_math:n} \Arg{material} +% \cs{siunitx_print_text:n} \Arg{material} +% \end{syntax} +% Prints the \meta{material} as described for \cs{siunitx_print_\dots:n} but +% with a fixed text or math mode output. The printing does \emph{not} set +% color (which is managed on a |unit|/|number| basis), but otherwise sets +% the font as described above. The |match| function uses either the prevailing +% math or text mode. +% \end{function} +% +% \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| = |match|\verb"|"|math|\verb"|"|text| +% \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_\dots:n} 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| = |match|\verb"|"|math|\verb"|"|text| +% \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_prin_number:n} 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_\dots:n} 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 text 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 text 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 text 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-font-command} +% \begin{syntax} +% |text-font-command| = \meta{cmd} +% \end{syntax} +% Command applied to text during output, inserted after any reset of +% font set-up. This can therefore be used to apply non-standard font +% set up when printing in text mode. The standard setting is empty. +% \end{function} +% +% \begin{function}{text-series-to-math} +% \begin{syntax} +% |text-series-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 set . 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| = |match|\verb"|"|math|\verb"|"|text| +% \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_\dots:n} is called. The +% |math| and |text| options choose the relevant \TeX{} mode for printing. +% The standard setting is |math|. +% \end{function} +% +% \begin{function}{series-version-mapping} +% \begin{syntax} +% |series-version-mapping| |/| \meta{weight} = \meta{version} +% \end{syntax} +% Defines how \pkg{siunitx} maps from text font weight to math font +% version. The pre-defined weights are those used as-standard by +% \pkg{autoinst}: +% \begin{itemize} +% \item \texttt{ul} +% \item \texttt{el} +% \item \texttt{l} +% \item \texttt{sl} +% \item \texttt{m} +% \item \texttt{sb} +% \item \texttt{b} +% \item \texttt{eb} +% \item \texttt{ub} +% \end{itemize} +% As standard, the \texttt{m} weight maps to \texttt{normal} math version +% whilst all of the \texttt{b} weights map to \texttt{bold} and all of the +% \texttt{l} weights map to \texttt{light}. +% \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} +% +% \begin{macro}{\tl_replace_all:NVn} +% Required variants. +% \begin{macrocode} +\cs_generate_variant:Nn \tl_replace_all:Nnn { NV } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\l_@@_tmp_box, \l_@@_tmp_tl} +% Scratch space. +% \begin{macrocode} +\box_new:N \l_@@_tmp_box +\tl_new:N \l_@@_tmp_tl +% \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. As we are doing typesetting (if only in a box), we +% need to be right at the start of the document: this also avoids any issue +% with \pkg{fontspec}. With a sufficiently recent \LaTeXe{} this is easy; +% for older kernels, we have to do things manually. +% \begin{macrocode} +\IfFormatAtLeastTF { 2020-10-01 } + { \hook_gput_code:nnn { begindocument/end } { siunitx } } + { \tl_put_right:Nn \document } + { + \@@_store_fam:n { rm } + \@@_store_fam:n { sf } + \@@_store_fam:n { tt } + } +\IfFormatAtLeastTF { 2020-10-01 } + { } + { \tl_put_right:Nn \document { \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_@@_text_font_tl , +% \l_@@_math_weight_bool +% } +% 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-font-command .tl_set:N = + \l_@@_text_font_tl , + text-series-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{variable} +% { +% \l_@@_version_ul_tl , +% \l_@@_version_el_tl , +% \l_@@_version_l_tl , +% \l_@@_version_sl_tl , +% \l_@@_version_m_tl , +% \l_@@_version_sb_tl , +% \l_@@_version_b_tl , +% \l_@@_version_eb_tl , +% \l_@@_version_ub_tl +% } +% One set of \enquote{focussed} options. +% \begin{macrocode} +\keys_define:nn { siunitx / series-version-mapping } + { + ul . tl_set:N = \l_@@_version_ul_tl , + el . tl_set:N = \l_@@_version_el_tl , + l . tl_set:N = \l_@@_version_l_tl , + sl . tl_set:N = \l_@@_version_sl_tl , + m . tl_set:N = \l_@@_version_m_tl , + sb . tl_set:N = \l_@@_version_sb_tl , + b . tl_set:N = \l_@@_version_b_tl , + eb . tl_set:N = \l_@@_version_eb_tl , + ub . tl_set:N = \l_@@_version_ub_tl + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro} +% { +% \siunitx_print_number:n, \siunitx_print_number:V, +% \siunitx_print_number:x, +% \siunitx_print_unit:n, \siunitx_print_unit:V, +% \siunitx_print_unit:x +% } +% \begin{macro}{\@@_aux:nn} +% 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_number:n #1 + { \@@_aux:nn { number } {#1} } +\cs_generate_variant:Nn \siunitx_print_number:n { V , x } +\cs_new_protected:Npn \siunitx_print_unit:n #1 + { \@@_aux:nn { unit } {#1} } +\cs_generate_variant:Nn \siunitx_print_unit:n { V , x } +\cs_new_protected:Npn \@@_aux:nn #1#2 + { + \tl_if_empty:cTF { l_@@_ #1 _color_tl } + { \use:n } + { \exp_args:Nv \textcolor { l_@@_ #1 _color_tl } } + { + \use:c + { + siunitx_print_ + \tl_use:c { l_@@_ #1 _mode_tl } :n + } + {#2} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\siunitx_print_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 \siunitx_print_match:n #1 + { + \mode_if_math:TF + { \siunitx_print_math:n {#1} } + { \siunitx_print_text:n {#1} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_replace_font:N} +% A simple auxiliary for \enquote{zapping} the unit font. +% \begin{macrocode} +\cs_new_protected:Npn \@@_replace_font:N #1 + { + \tl_if_empty:NF \l_siunitx_unit_font_tl + { + \tl_replace_all:NVn #1 + \l_siunitx_unit_font_tl + { \use:n } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{variable} +% { +% \c_@@_weight_uc_tl , +% \c_@@_weight_ecl_tl , +% \c_@@_weight_c_tl , +% \c_@@_weight_sc_tl , +% \c_@@_weight_sx_tl , +% \c_@@_weight_x_tl , +% \c_@@_weight_ex_tl , +% \c_@@_weight_ux_tl +% } +% Font widths where the |m| for weight is omitted. +% \begin{macrocode} +\clist_map_inline:nn { uc , ec , c , sc , sx , x , ex , ux } + { \tl_const:cn { c_@@_weight_ #1 _tl } { m } } +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \c_@@_weight_l_tl , +% \c_@@_weight_m_tl , +% \c_@@_weight_b_tl +% } +% Font widths with one letter. +% \begin{macrocode} +\clist_map_inline:nn { l , m , b } + { \tl_const:cn { c_@@_weight_ #1 _tl } { #1 } } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_print_math:n} +% \begin{macro}[EXP]{\@@_extract_series:Nw} +% \begin{macro}[EXP]{\@@_convert_series:n, \@@_convert_series:v} +% \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 \siunitx_print_math:n #1 + { + \bool_if:NTF \l_@@_math_weight_bool + { + \tl_set:Nx \l_@@_tmp_tl + { \exp_after:wN \@@_extract_series:Nw \f@series ? \q_stop } + \tl_if_empty:NTF \l_@@_tmp_tl + { \@@_math_auxi:n {#1} } + { \@@_math_version:Vn \l_@@_tmp_tl {#1} } + } + { \@@_math_auxi:n {#1} } + } +% \end{macrocode} +% Look up the math version from the text series. The weight is omitted +% if it is |m| plus there are either one or two letters, so we have a little +% work to do. To keep things fast, we use a hash table based lookup rather +% than a sequence or property list. +% \begin{macrocode} +\cs_new:Npn \@@_extract_series:Nw #1#2 ? #3 \q_stop + { + \cs_if_exist:cTF { c_@@_weight_ #1#2 _tl } + { \@@_convert_series:v { c_@@_weight_ #1#2 _tl } } + { + \cs_if_exist:cTF { c_@@_weight_ #1 _tl } + { \@@_convert_series:v { c_@@_weight_ #1 _tl } } + { \@@_convert_series:n {#1#2} } + } + } +\cs_new:Npn \@@_convert_series:n #1 + { \tl_use:c { l_@@_version_ #1 _tl } } +\cs_generate_variant:Nn \@@_convert_series:n { v } +\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:VnTF \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. +% The test here is on a string basis as |\f@family| and the |\...default| +% commands have different |\long| status. +% \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_e: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 font commands 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} + \@@_replace_font:N \exp_not:N \l_@@_tmp_tl + \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} + \@@_replace_font:N \l_@@_tmp_tl + \tl_use:N \l_@@_tmp_tl + \group_end: + } +% \end{macrocode} +% For \pkg{tex4ht}, we need to have category code $12$ |^| tokens in math +% mode. We handle that by intercepting at the first auxiliary that makes +% sense. +% \begin{macrocode} +\AtBeginDocument + { + \@ifpackageloaded { tex4ht } + { + \cs_set_protected:Npn \@@_math_auxii:n #1 + { + \tl_set:Nn \l_@@_tmp_tl {#1} + \exp_args:NNnx \tl_replace_all:Nnn \l_@@_tmp_tl + { ^ } { \token_to_str:N ^ } + \ensuremath { \exp_args:NV \@@_math_auxiii:n \l_@@_tmp_tl } + } + } + { } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\siunitx_print_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 \siunitx_print_text:n #1 + { + \text + { + \bool_if:NT \l_@@_text_family_bool + { \fontfamily { \familydefault } } + \bool_if:NT \l_@@_text_series_bool + { \fontseries { \seriesdefault } } + \bool_if:NT \l_@@_text_shape_bool + { \fontshape { \shapedefault } } + \bool_lazy_any:nT + { + { \l_@@_text_family_bool } + { \l_@@_text_series_bool } + { \l_@@_text_shape_bool } + } + { \selectfont } + \tl_use:N \l_@@_text_font_tl + \@@_text_replace:n {#1} + } + } +% \end{macrocode} +% To get math mode material to print in text mode, various search-and-replace +% steps are needed. +% \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 + { + \@@_replace_font:N #1 + \exp_not:N \@@_text_replace:NNn #1 + \exp_not:N \mathord { } + \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} +% When the \pkg{bidi} package is loaded, we need to make sure +% that \cs{text} is doing the correct thing. +% \begin{macrocode} +\sys_if_engine_xetex:T + { + \AtBeginDocument + { + \@ifpackageloaded { bidi } + { + \cs_set_protected:Npn \@@_text_replace:n #1 + { + \group_begin: + \tl_set:Nn \l_@@_tmp_tl {#1} + \@@_text_replace:N \l_@@_tmp_tl + \LRE { \tl_use:N \l_@@_tmp_tl } + \group_end: + } + } + { } + } + } +% \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-font-command = , + text-series-to-math = false , + unit-color = , + unit-mode = math + } +% \end{macrocode} +% +% These are separate as they all fall inside the same key. +% \begin{macrocode} +\keys_set:nn { siunitx / series-version-mapping } + { + ul = light , + el = light , + l = light , + sl = light , + m = normal , + sb = bold , + b = bold , + eb = bold , + ub = bold + } +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex |