diff options
author | Karl Berry <karl@freefriends.org> | 2021-05-17 20:38:21 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-05-17 20:38:21 +0000 |
commit | 02d9f17ba92ad3f076e2dc14711462e1dfea6ec0 (patch) | |
tree | 1d9b453be69b5988dfe2bc0584d6425547563f69 /Master/texmf-dist/source/latex/siunitx | |
parent | 00085afeded239f44fcdb90c9f1ba8ec7f3680be (diff) |
siunitx (17may21)
git-svn-id: svn://tug.org/texlive/trunk@59239 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/siunitx')
18 files changed, 18163 insertions, 17604 deletions
diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-abbreviation.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-abbreviation.dtx new file mode 100644 index 00000000000..9fc5ddb2a52 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-abbreviation.dtx @@ -0,0 +1,331 @@ +% \iffalse meta-comment +% +% File: siunitx-abbreviation.dtx Copyright (C) 2018,2019 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-abbreviations} -- Abbreviatons^^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} +% +% \begin{function}{\A, \pA, \nA, \uA, \mA, \kA} +% Abbreviations for currents. +% \end{function} +% +% \begin{function}{\fg, \pg, \ng, \ug, \mg, \g, \kg} +% Abbreviations for masses. +% \end{function} +% +% \begin{function}{\K} +% Abbreviations for temperature. +% \end{function} +% +% \begin{function}{\m, \pm, \nm, \um, \mm, \cm, \dm, \km} +% Abbreviations for lengths. +% \end{function} +% +% \begin{function}{\s, \as, \fs, \ps, \ns, \us, \ms} +% Abbreviations for times. +% \end{function} +% +% \begin{function}{\Hz, \mHz, \kHz, \MHz, \GHz, \THz} +% Abbreviations for frequencies. +% \end{function} +% +% \begin{function}{\mol, \fmol, \pmol, \nmol, \umol, \mmol, \kmol} +% Abbreviations for moles. +% \end{function} +% +% \begin{function}{\V, \pV, \nV, \uV, \mV, \kV} +% Abbreviations for potentials. +% \end{function} +% +% \begin{function}{\hl, \l, \ml, \ul, \hL, \L, \mL, \uL} +% Abbreviations for volumes. +% \end{function} +% +% \begin{function}{\W, \uW, \mW, \kW, \MW, \GW} +% Abbreviations for powers. +% \end{function} +% +% \begin{function}{\kJ, \J, \mJ, \uJ, \eV, \meV, \keV, \MeV, \GeV, \TeV} +% Abbreviations for energies. +% \end{function} +% +% \begin{function}{\N, \mN, \kN, \MN} +% Abbreviations for forces. +% \end{function} +% +% \begin{function}{\Pa, \kPa, \MPa, \GPa} +% Abbreviations for pressures. +% \end{function} +% +% \begin{function}{\mohm, \kohm, \Mohm} +% Abbreviations for resistance. +% \end{function} +% +% \begin{function}{\F, \fF, \pF, \nF, \uF} +% Abbreviations for capacitance. +% \end{function} +% +% \begin{function}{\dB} +% Abbreviation for decibel. +% \end{function} +% +% \begin{function}{\kWh} +% Abbreviation for kilowatt--hours. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-abbreviation} implementation} +% +% Start the \pkg{DocStrip} guards. +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% The abbreviation file contains a number of short (mainly two or +% three letter) versions of the usual long names. They are divided up +% into related groups, mainly to avoid an overly long list in one +% place. +% +% \begin{macro}{\A, \pA, \nA, \uA, \mA, \kA} +% Currents. +% \begin{macrocode} +\siunitx_declare_unit:Nn \A { \ampere } +\siunitx_declare_unit:Nn \pA { \pico \ampere } +\siunitx_declare_unit:Nn \nA { \nano \ampere } +\siunitx_declare_unit:Nn \uA { \micro \ampere } +\siunitx_declare_unit:Nn \mA { \milli \ampere } +\siunitx_declare_unit:Nn \kA { \kilo \ampere } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\Hz, \mHz, \kHz, \MHz, \GHz, \THz} +% Then frequencies. +% \begin{macrocode} +\siunitx_declare_unit:Nn \Hz { \hertz } +\siunitx_declare_unit:Nn \mHz { \milli \hertz } +\siunitx_declare_unit:Nn \kHz { \kilo \hertz } +\siunitx_declare_unit:Nn \MHz { \mega \hertz } +\siunitx_declare_unit:Nn \GHz { \giga \hertz } +\siunitx_declare_unit:Nn \THz { \tera \hertz } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\mol, \fmol, \pmol, \nmol, \umol, \mmol, \kmol} +% Amounts of substance (moles). +% \begin{macrocode} +\siunitx_declare_unit:Nn \mol { \mole } +\siunitx_declare_unit:Nn \fmol { \femto \mole } +\siunitx_declare_unit:Nn \pmol { \pico \mole } +\siunitx_declare_unit:Nn \nmol { \nano \mole } +\siunitx_declare_unit:Nn \umol { \micro \mole } +\siunitx_declare_unit:Nn \mmol { \milli \mole } +\siunitx_declare_unit:Nn \kmol { \kilo \mole } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\V, \pV, \nV, \uV, \mV, \kV} +% Potentials. +% \begin{macrocode} +\siunitx_declare_unit:Nn \V { \volt } +\siunitx_declare_unit:Nn \pV { \pico \volt } +\siunitx_declare_unit:Nn \nV { \nano \volt } +\siunitx_declare_unit:Nn \uV { \micro \volt } +\siunitx_declare_unit:Nn \mV { \milli \volt } +\siunitx_declare_unit:Nn \kV { \kilo \volt } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\hl, \l, \ml, \ul, \hL, \L, \mL, \uL} +% Volumes. +% \begin{macrocode} +\siunitx_declare_unit:Nn \hl { \hecto \litre } +\siunitx_declare_unit:Nn \l { \litre } +\siunitx_declare_unit:Nn \ml { \milli \litre } +\siunitx_declare_unit:Nn \ul { \micro \litre } +\siunitx_declare_unit:Nn \hL { \hecto \liter } +\siunitx_declare_unit:Nn \L { \liter } +\siunitx_declare_unit:Nn \mL { \milli \liter } +\siunitx_declare_unit:Nn \uL { \micro \liter } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\fg, \pg, \ng, \ug, \mg, \g, \kg} +% Masses. +% \begin{macrocode} +\siunitx_declare_unit:Nn \fg { \femto \gram } +\siunitx_declare_unit:Nn \pg { \pico \gram } +\siunitx_declare_unit:Nn \ng { \nano \gram } +\siunitx_declare_unit:Nn \ug { \micro \gram } +\siunitx_declare_unit:Nn \mg { \milli \gram } +\siunitx_declare_unit:Nn \g { \gram } +\siunitx_declare_unit:Nn \kg { \kilo \gram } +% \end{macrocode} +% \end{macro} +% \begin{macro} +% { +% \W, \uW, \mW, \kW, \MW, \GW, +% \kJ, \J, \mJ, \uJ, +% \eV, \meV, \keV, \MeV, \GeV, \TeV, +% \kWh +% } +% Energies and powers +% \begin{macrocode} +\siunitx_declare_unit:Nn \W { \watt } +\siunitx_declare_unit:Nn \uW { \micro \watt } +\siunitx_declare_unit:Nn \mW { \milli \watt } +\siunitx_declare_unit:Nn \kW { \kilo \watt } +\siunitx_declare_unit:Nn \MW { \mega \watt } +\siunitx_declare_unit:Nn \GW { \giga \watt } +\siunitx_declare_unit:Nn \J { \joule } +\siunitx_declare_unit:Nn \uJ { \micro \joule } +\siunitx_declare_unit:Nn \mJ { \milli \joule } +\siunitx_declare_unit:Nn \kJ { \kilo \joule } +\siunitx_declare_unit:Nn \eV { \electronvolt } +\siunitx_declare_unit:Nn \meV { \milli \electronvolt } +\siunitx_declare_unit:Nn \keV { \kilo \electronvolt } +\siunitx_declare_unit:Nn \MeV { \mega \electronvolt } +\siunitx_declare_unit:Nn \GeV { \giga \electronvolt } +\siunitx_declare_unit:Nn \TeV { \tera \electronvolt } +\siunitx_declare_unit:Nnn \kWh { \kilo \watt \hour } + { inter-unit-product = } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\m, \pm, \nm, \um, \mm, \cm, \dm, \km} +% Lengths. +% \begin{macrocode} +\siunitx_declare_unit:Nn \m { \metre } +\siunitx_declare_unit:Nn \pm { \pico \metre } +\siunitx_declare_unit:Nn \nm { \nano \metre } +\siunitx_declare_unit:Nn \um { \micro \metre } +\siunitx_declare_unit:Nn \mm { \milli \metre } +\siunitx_declare_unit:Nn \cm { \centi \metre } +\siunitx_declare_unit:Nn \dm { \deci \metre } +\siunitx_declare_unit:Nn \km { \kilo \metre } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\K} +% Temperatures. +% \begin{macrocode} +\siunitx_declare_unit:Nn \K { \kelvin } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\dB} +% \begin{macrocode} +\siunitx_declare_unit:Nn \dB { \deci \bel } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\F, \fF, \pF, \nF, \uF} +% Capacitance. +% \begin{macrocode} +\siunitx_declare_unit:Nn \F { \farad } +\siunitx_declare_unit:Nn \fF { \femto \farad } +\siunitx_declare_unit:Nn \pF { \pico \farad } +\siunitx_declare_unit:Nn \nF { \nano \farad } +\siunitx_declare_unit:Nn \uF { \micro \farad } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\H, \mH, \uH} +% Capacitance. +% \begin{macrocode} +\siunitx_declare_unit:Nn \H { \henry } +\siunitx_declare_unit:Nn \mH { \milli \henry } +\siunitx_declare_unit:Nn \uH { \micro \henry } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\N, \mN, \kN, \MN} +% Forces. +% \begin{macrocode} +\siunitx_declare_unit:Nn \N { \newton } +\siunitx_declare_unit:Nn \mN { \milli \newton } +\siunitx_declare_unit:Nn \kN { \kilo \newton } +\siunitx_declare_unit:Nn \MN { \mega \newton } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\Pa, \kPa, \MPa, \GPa} +% Pressures. +% \begin{macrocode} +\siunitx_declare_unit:Nn \Pa { \pascal } +\siunitx_declare_unit:Nn \kPa { \kilo \pascal } +\siunitx_declare_unit:Nn \MPa { \mega \pascal } +\siunitx_declare_unit:Nn \GPa { \giga \pascal } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\mohm, \kohm, \Mohm} +% Resistances. +% \begin{macrocode} +\siunitx_declare_unit:Nn \mohm { \milli \ohm } +\siunitx_declare_unit:Nn \kohm { \kilo \ohm } +\siunitx_declare_unit:Nn \Mohm { \mega \ohm } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\s, \as, \fs, \ps, \ns, \us, \ms} +% Finally, times. +% \begin{macrocode} +\siunitx_declare_unit:Nn \s { \second } +\siunitx_declare_unit:Nn \as { \atto \second } +\siunitx_declare_unit:Nn \fs { \femto \second } +\siunitx_declare_unit:Nn \ps { \pico \second } +\siunitx_declare_unit:Nn \ns { \nano \second } +\siunitx_declare_unit:Nn \us { \micro \second } +\siunitx_declare_unit:Nn \ms { \milli \second } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-angle.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-angle.dtx new file mode 100644 index 00000000000..a3d46080670 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-angle.dtx @@ -0,0 +1,564 @@ +% \iffalse meta-comment +% +% File: siunitx-angle.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-angle} -- Formatting angles^^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{Formatting angles} +% +% \begin{function}{\siunitx_angle:n, \siunitx_angle:nnn} +% \begin{syntax} +% \cs{siunitx_angle:n} \Arg{angle} +% \cs{siunitx_angle:nnn} \Arg{degrees} \Arg{minutes} \Arg{seconds} +% \end{syntax} +% Typeset the \meta{angle} (which may be given as separate \meta{degree}, +% \meta{minute} and \meta{second} components). The \meta{angle} (or components) +% may be given as expressions. The \meta{angle} should be a number as understood +% by \cs{siunitx_format_number:nN}, with no uncertainty, exponent or imaginary +% part. The unit symbols for degrees, minutes and seconds are |\degree|, +% |\arcminute| and |\arcsecond|, respectively +% \end{function} +% +% \subsection{Key--value options} +% +% The options defined by this submodule are available within the \pkg{l3keys} +% |siunitx| tree. +% +% \begin{function}{angle-mode} +% \begin{syntax} +% |angle-mode| = \meta{choice} +% \end{syntax} +% Selects how angles are formatted: a choice from +% the options |arc|, |decimal| and |input|. The option |arc| means that angles +% will always be typeset in arc (degree, minute, second) format, whilst +% |decimal| means that angles are typeset as a single decimal value. The +% |input| setting means that the input format (\foreign{i.e.}~difference +% between \cs{siunitx_angle:n} and \cs{siunitx_angle:nnn}) is maintained. The +% standard setting is |input|. +% \end{function} +% +% \begin{function} +% { +% angle-symbol-degree , +% angle-symbol-minute , +% angle-symbol-second +% } +% \begin{syntax} +% |angle-symbol-degree| = \meta{symbol} +% \end{syntax} +% Sets the symbol used for arc degrees, minutes or seconds, respectively. +% \end{function} +% +% \begin{function}{angle-symbol-over-decimal} +% \begin{syntax} +% |angle-symbol-over-decimal| = |true|\verb"|"|false| +% \end{syntax} +% Determines if the arc separator is printed over the decimal marker, a +% format used in astronomy. The standard setting is |false|. +% \end{function} +% +% \begin{function}{arc-separator} +% \begin{syntax} +% |arc-separator| = \meta{separator} +% \end{syntax} +% Inserted between arc parts (degree, minute and second components). +% The standard setting is |\,|. +% \end{function} +% +% \begin{function}{fill-angle-degrees} +% \begin{syntax} +% |fill-arc-degrees| = |true|\verb"|"|false| +% \end{syntax} +% Determines whether a missing degrees part is zero-filled when printing an +% arc. The standard setting is |false|. +% \end{function} +% +% \begin{function}{fill-angle-minutes} +% \begin{syntax} +% |fill-arc-minutes| = |true|\verb"|"|false| +% \end{syntax} +% Determines whether a missing minutes part is zero-filled when printing an +% arc. The standard setting is |false|. +% \end{function} +% +% \begin{function}{fill-angle-seconds} +% \begin{syntax} +% |fill-arc-seconds| = |true|\verb"|"|false| +% \end{syntax} +% Determines whether a missing seconds part is zero-filled when printing an +% arc. The standard setting is |false|. +% \end{function} +% +% \begin{function}{number-angle-product} +% \begin{syntax} +% |number-angle-product| = \meta{separator} +% \end{syntax} +% Inserted between the value of an angle and the unit (degree, minute or +% second component). The standard setting is |\,|. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-angle} 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_angle> +% \end{macrocode} +% +% \begin{variable}{\l_@@_tmp_bool, \l_@@_tmp_dim, \l_@@_tmp_tl} +% Scratch space. +% \begin{macrocode} +\bool_new:N \l_@@_tmp_bool +\dim_new:N \l_@@_tmp_dim +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_@@_symbol_degree_tl , +% \l_@@_symbol_minute_tl , +% \l_@@_symbol_second_tl , +% \l_@@_force_arc_bool , +% \l_@@_force_decimal_bool , +% \l_@@_astronomy_bool , +% \l_@@_separator_tl , +% \l_@@_fill_degrees_bool , +% \l_@@_fill_minutes_bool , +% \l_@@_fill_seconds_bool , +% \l_@@_product_tl +% } +% \begin{macrocode} +\keys_define:nn { siunitx } + { + angle-mode .choice: , + angle-mode / arc .code:n = + { + \bool_set_true:N \l_@@_force_arc_bool + \bool_set_false:N \l_@@_force_decimal_bool + } , + angle-mode / decimal .code:n = + { + \bool_set_false:N \l_@@_force_arc_bool + \bool_set_true:N \l_@@_force_decimal_bool + } , + angle-mode / input .code:n = + { + \bool_set_false:N \l_@@_force_arc_bool + \bool_set_false:N \l_@@_force_decimal_bool + } , + angle-symbol-degree .tl_set:N = + \l_@@_symbol_degree_tl , + angle-symbol-minute .tl_set:N = + \l_@@_symbol_minute_tl , + angle-symbol-second .tl_set:N = + \l_@@_symbol_second_tl , + angle-symbol-over-decimal .bool_set:N = + \l_@@_astronomy_bool , + angle-separator .tl_set:N = + \l_@@_separator_tl , + fill-angle-degrees .bool_set:N = + \l_@@_fill_degrees_bool , + fill-angle-minutes .bool_set:N = + \l_@@_fill_minutes_bool , + fill-angle-seconds .bool_set:N = + \l_@@_fill_seconds_bool , + number-angle-product .tl_set:N = + \l_@@_product_tl + } +\bool_new:N \l_@@_force_arc_bool +\bool_new:N \l_@@_force_decimal_bool +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_angle:n} +% \begin{macro}{\siunitx_angle:nnn} +% \begin{macro}{\@@_arc_convert:n} +% The first step here is to force format conversion if required. Going to +% a decimal is easy, going to arc format is a bit more painful: avoid +% repeating calculations mainly for code readability. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_angle:n #1 + { + \bool_if:NTF \l_@@_force_arc_bool + { \exp_args:Ne \@@_arc_convert:n { \fp_eval:n {#1} } } + { + \siunitx_number_parse:nN {#1} \l_@@_degrees_tl + \tl_set:Nx \l_@@_degrees_tl + { \siunitx_number_output:NN \l_@@_degrees_tl \q_nil } + \@@_arc_print:VVV + \l_@@_degrees_tl + \c_empty_tl + \c_empty_tl + } + } +\cs_new_protected:Npn \siunitx_angle:nnn #1#2#3 + { + \bool_if:NTF \l_@@_force_decimal_bool + { + \exp_args:Ne \siunitx_angle:n + { \fp_eval:n { #1 + (#2) / 60 + (#3) / 3600 } } + } + { \@@_arc_sign:nnn {#1} {#2} {#3} } + } +\cs_new_protected:Npn \@@_arc_convert:n #1 + { + \use:x + { + \siunitx_angle:nnn + { \fp_eval:n { trunc(#1,0) } } + { \fp_eval:n { trunc((#1 - trunc(#1,0)) * 60,0) } } + { + \fp_eval:n + { + ( + (#1 - trunc(#1,0)) * 60 + - trunc((#1 - trunc(#1,0)) * 60,0) + ) + * 60 + } + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{variable}{\l_@@_degrees_tl, \l_@@_minutes_tl, \l_@@_seconds_tl} +% Space for formatting parsed numbers. +% \begin{macrocode} +\tl_new:N \l_@@_degrees_tl +\tl_new:N \l_@@_minutes_tl +\tl_new:N \l_@@_seconds_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_sign_tl} +% For the \enquote{sign shuffle}. +% \begin{macrocode} +\tl_new:N \l_@@_sign_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_arc_sign:nnn} +% \begin{macro}{\@@_arc_sign:nn} +% \begin{macro}{\@@_extract_sign:nnnnnnnn} +% \begin{macro}[EXP]{\@@_sign:nnnnnnn} +% To get the sign in the right place whilst dealing with zero filling +% means doing some shuffling. That means doing processing of each number +% manually. +% \begin{macrocode} +\cs_new_protected:Npn \@@_arc_sign:nnn #1#2#3 + { + \group_begin: + \keys_set:nn { siunitx } + { + input-close-uncertainty = , + input-exponent-markers = , + input-open-uncertainty = , + input-uncertainty-signs = + } + \tl_clear:N \l_@@_sign_tl + \@@_arc_sign:nn {#1} { degrees } + \@@_arc_sign:nn {#2} { minutes } + \@@_arc_sign:nn {#3} { seconds } + \tl_if_empty:NF \l_@@_sign_tl + { + \clist_map_inline:nn { degrees , minutes , seconds } + { + \tl_if_empty:cF { l_@@_ ##1 _tl } + { + \tl_set:cx { l_@@_ ##1 _tl } + { + { } + { \exp_not:V \l_@@_sign_tl } + \exp_after:wN \exp_after:wN \exp_after:wN + \@@_sign:nnnnnnn + \cs:w l_@@_ ##1 _tl \cs_end: + } + \clist_map_break: + } + } + } + \clist_map_inline:nn { degrees , minutes , seconds } + { + \tl_if_empty:cF { l_@@_ ##1 _tl } + { + \tl_set:cx { l_@@_ ##1 _tl } + { + \exp_args:Nc \siunitx_number_output:NN + { l_@@_ ##1 _tl } \q_nil + } + } + } + \@@_arc_print:VVV + \l_@@_degrees_tl + \l_@@_minutes_tl + \l_@@_seconds_tl + \group_end: + } +\cs_new_protected:Npn \@@_arc_sign:nn #1#2 + { + \tl_if_blank:nTF {#1} + { + \bool_if:cTF { l_@@_fill_ #2 _bool } + { + \tl_set:cn { l_@@_ #2 _tl } + { { } { } { 0 } { } { } { } { 0 } } + } + { \tl_clear:c { l_@@_ #2 _tl } } + } + { + \siunitx_number_parse:nN {#1} \l_@@_tmp_tl + \exp_after:wN \@@_extract_sign:nnnnnnnn \l_@@_tmp_tl {#2} + } + } +\cs_new_protected:Npn \@@_extract_sign:nnnnnnnn #1#2#3#4#5#6#7#8 + { + \tl_if_blank:nTF {#2} + { \tl_set_eq:cN { l_@@_ #8 _tl } \l_@@_tmp_tl } + { + \tl_set:cn { l_@@_ #8 _tl } + { {#1} { } {#3} {#4} {#5} {#6} {#7} } + \tl_set:Nn \l_@@_sign_tl {#2} + \keys_set:nn { siunitx } + { input-comparators = , input-signs = } + } + } +\cs_new:Npn \@@_sign:nnnnnnn #1#2#3#4#5#6#7 + { \exp_not:n { {#3} {#4} {#5} {#6} {#7} } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{variable}{\l_@@_marker_box, \l_@@_unit_box} +% For \enquote{astronomy style} angles. +% \begin{macrocode} +\box_new:N \l_@@_marker_box +\box_new:N \l_@@_unit_box +% \end{macrocode} +% \end{variable} +% +% \begin{macro} +% { +% \@@_arc_print:nnn, \@@_arc_print:VVV, +% \@@_arc_print_auxi:nnn, \@@_arc_print_auxi:nVn +% } +% \begin{macro}{\@@_arc_print_auxii:w} +% \begin{macro}{\@@_arc_print_auxiii:n} +% \begin{macro}{\@@_arc_print_auxiv:NN} +% \begin{macro}{\@@_arc_print_auxv:w} +% \begin{macro}{\@@_arc_print_auxvi:n} +% The final stage of printing an angle is to put together the three parts: +% this works even for decimal angles as they will blank arguments for the +% other two parts The need to handle astronomy-style formatting means that +% the number has to be decomposed into parts. +% \begin{macrocode} +\cs_new_protected:Npn \@@_arc_print:nnn #1#2#3 + { + \@@_arc_print_auxi:nVn {#1} + \l_@@_symbol_degree_tl {#2#3} + \@@_arc_print_auxi:nVn {#2} + \l_@@_symbol_minute_tl {#3} + \@@_arc_print_auxi:nVn {#3} + \l_@@_symbol_second_tl { } + } +\cs_generate_variant:Nn \@@_arc_print:nnn { VVV } +\cs_new_protected:Npn \@@_arc_print_auxi:nnn #1#2#3 + { + \tl_if_blank:nF {#1} + { + \bool_if:NTF \l_@@_astronomy_bool + { \@@_arc_print_auxii:nw {#2} #1 \q_stop } + { + \@@_arc_print_auxv:w #1 \q_stop + \@@_arc_print_auxvi:n {#2} + } + \tl_if_blank:nF {#3} + { + \nobreak + \l_@@_separator_tl + } + } + } +\cs_generate_variant:Nn \@@_arc_print_auxi:nnn { nV } +% \end{macrocode} +% To align the two parts of the astronomy-style marker, we need to allow +% for the |\scriptspace|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_arc_print_auxii:nw + #1#2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_nil #8 \q_stop + { + \mode_if_math:TF + { \bool_set_true:N \l_@@_tmp_bool } + { \bool_set_false:N \l_@@_tmp_bool } + \siunitx_print_number:n {#2#3#4} + \tl_if_blank:nTF {#6} + { \@@_arc_print_auxvi:n {#1} } + { + \hbox_set:Nn \l_@@_marker_box + { + \@@_arc_print_auxiii:n + { \siunitx_print_number:n {#5} } + } + \hbox_set:Nn \l_@@_unit_box + { + \@@_arc_print_auxiii:n + { + \siunitx_unit_format:nN {#1} \l_@@_tmp_tl + \siunitx_print_unit:V \l_@@_tmp_tl + \skip_horizontal:n { -\scriptspace } + } + } + \dim_compare:nNnTF { \box_wd:N \l_@@_marker_box } > + { \box_wd:N \l_@@_unit_box } + { + \@@_arc_print_auxiv:NN + \l_@@_marker_box + \l_@@_unit_box + } + { + \@@_arc_print_auxiv:NN + \l_@@_unit_box + \l_@@_marker_box + } + \hbox_set_to_wd:Nnn \l_@@_marker_box + \l_@@_tmp_dim + { + \hbox_overlap_right:n + { \box_use_drop:N \l_@@_marker_box } + \hbox_overlap_right:n + { \box_use_drop:N \l_@@_unit_box } + \tex_hfil:D + } + \box_use:N \l_@@_marker_box + \skip_horizontal:N \scriptspace + \siunitx_print_number:n {#6} + } + } +\cs_new_protected:Npn \@@_arc_print_auxiii:n #1 + { + \bool_if:NTF \l_@@_tmp_bool + { \ensuremath } + { \use:n } + {#1} + } +\cs_new_protected:Npn \@@_arc_print_auxiv:NN #1#2 + { + \dim_set:Nn \l_@@_tmp_dim { \box_wd:N #1 } + \hbox_set_to_wd:Nnn #2 + \l_@@_tmp_dim + { + \tex_hss:D + \hbox_unpack_drop:N #2 + \tex_hss:D + } + } +\cs_new_protected:Npn \@@_arc_print_auxv:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_stop + { \siunitx_print_number:n {#1#2#3#4#5} } +\cs_new_protected:Npn \@@_arc_print_auxvi:n #1 + { + \nobreak + \l_@@_product_tl + \siunitx_unit_format:nN {#1} \l_@@_tmp_tl + \siunitx_print_unit:V \l_@@_tmp_tl + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +\keys_set:nn { siunitx } + { + angle-mode = input , + angle-symbol-degree = \degree , + angle-symbol-minute = \arcminute , + angle-symbol-over-decimal = false , + angle-symbol-second = \arcsecond , + angle-separator = , + fill-angle-degrees = false , + fill-angle-minutes = false , + fill-angle-seconds = false , + number-angle-product = + } +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-binary.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-binary.dtx new file mode 100644 index 00000000000..f3e3afff3e5 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-binary.dtx @@ -0,0 +1,112 @@ +% \iffalse meta-comment +% +% File: siunitx-binary.dtx Copyright (C) 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} +% 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-binary} -- Binary units^^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 provides binary units and prefixes. These are not formally +% part of the \acro{SI} but are recommended by \acro{BIPM} as units of +% information. +% +% \begin{function}{\kibi, \mebi, \gibi, \tebi, \pebi, \exbi, \zebi, \yobi} +% Prefixes, all of which are integer powers of $2$: the powers are \emph{not} +% stored or available for conversion. +% \end{function} +% +% \begin{function}{\bit, \byte} +% Units for bits and bytes. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-binary} implementation} +% +% Start the \pkg{DocStrip} guards. +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \begin{macro}{\kibi, \mebi, \gibi, \tebi, \pebi, \exbi, \zebi, \yobi} +% All very simple. +% \begin{macrocode} +\siunitx_declare_prefix:Nn \kibi { Ki } +\siunitx_declare_prefix:Nn \mebi { Mi } +\siunitx_declare_prefix:Nn \gibi { Gi } +\siunitx_declare_prefix:Nn \tebi { Ti } +\siunitx_declare_prefix:Nn \pebi { Pi } +\siunitx_declare_prefix:Nn \exbi { Ei } +\siunitx_declare_prefix:Nn \zebi { Zi } +\siunitx_declare_prefix:Nn \yobi { Yi } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bit, \byte} +% \begin{macrocode} +\siunitx_declare_unit:Nn \bit { bit } +\siunitx_declare_unit:Nn \byte { B } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-code.tex b/Master/texmf-dist/source/latex/siunitx/siunitx-code.tex new file mode 100644 index 00000000000..7396975f445 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-code.tex @@ -0,0 +1,102 @@ +\iffalse meta-comment + +File: siunitx-code.tex Copyright (C) 2016-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. + +----------------------------------------------------------------------- + +\fi + +\documentclass{l3doc} + +% The next line is needed so that \GetFileInfo will be able to pick up +% version data. +\usepackage{siunitx} + +% Commands for this document +\ExplSyntaxOn +\cs_new_eq:NN \LowerCaseText \tl_lower_case:n +\ExplSyntaxOff +\NewDocumentCommand\acro{m}{\textsc{\LowerCaseText{#1}}} +\NewDocumentCommand\foreign{m}{\textit{#1}} + +\begin{document} + +\GetFileInfo{siunitx.sty} + +\title{% + \pkg{siunitx} -- A comprehensive (SI) units package% + \thanks{This file describes \fileversion, + last revised \filedate.}% +} + +\author{% + Joseph Wright% + \thanks{% + E-mail: + \href{mailto:joseph.wright@morningstar2.co.uk} + {joseph.wright@morningstar2.co.uk}% + }% +} + +\date{Released \filedate} + +\pagenumbering{roman} + +\maketitle +\tableofcontents +\clearpage +\pagenumbering{arabic} + +% Make the separate source files into a single whole, format-wise +\makeatletter +\RenewDocumentCommand\maketitle{}{% + \clearpage + \part{\@title}% +} +\makeatother +\renewcommand*\partname{Part} +\DeclareExpandableDocumentCommand\thanks{m}{} + +\let\DelayPrintIndex\PrintIndex +\RenewDocumentCommand\PrintIndex{}{} + +% Load the source files in order +\DocInput{siunitx.dtx} +\DocInput{siunitx-angle.dtx} +\DocInput{siunitx-compound.dtx} +\DocInput{siunitx-locale.dtx} +\DocInput{siunitx-number.dtx} +\DocInput{siunitx-print.dtx} +\DocInput{siunitx-quantity.dtx} +\DocInput{siunitx-symbol.dtx} +\DocInput{siunitx-table.dtx} +\DocInput{siunitx-unit.dtx} +\DocInput{siunitx-abbreviation.dtx} +\DocInput{siunitx-binary.dtx} +\DocInput{siunitx-command.dtx} +\DocInput{siunitx-emulation.dtx} +\clearpage + +\DelayPrintIndex + +\end{document} diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-command.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-command.dtx new file mode 100644 index 00000000000..20574f72523 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-command.dtx @@ -0,0 +1,298 @@ +% \iffalse meta-comment +% +% File: siunitx-command.dtx Copyright (C) 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-command} -- Units as document command^^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 provides support for creating free-standing document commands +% for unit macros. +% +% \section{Creating units as document commands} +% +% \begin{function}{\siunitx_command_create:} +% \begin{syntax} +% \cs{siunitx_command_create:} +% \end{syntax} +% Maps over the list of know unit commands and creates the appropriate +% document command to support them, as controlled by the options below. +% \end{function} +% +% \subsection{Key--value options} +% +% The options defined by this submodule are available within the \pkg{l3keys} +% |siunitx| tree. +% +% These options are all preamble-only. +% +% \begin{function}{free-standing-units} +% \begin{syntax} +% |free-standing-units| = |true|\verb"|"|false| +% \end{syntax} +% Switch to determine whether free standing document commands are created +% for symbolic units. This will include not only units themselves but also +% prefixes, \foreign{etc.} The standard setting is |false|. +% \end{function} +% +% \begin{function}{overwrite-commands} +% \begin{syntax} +% |overwrite-commands| = |true|\verb"|"|false| +% \end{syntax} +% Switch to determine whether when creating free standing document commands, +% any existing document commands are overwritten. The standard setting is +% |false|. +% \end{function} +% +% \begin{function}{space-before-unit} +% \begin{syntax} +% |space-before-unit| = |true|\verb"|"|false| +% \end{syntax} +% Switch to determine whether a space is inserted before free standing +% document commands. The standard setting is |false|. +% \end{function} +% +% \begin{function}{unit-optional-argument} +% \begin{syntax} +% |unit-optional-argument| = |true|\verb"|"|false| +% \end{syntax} +% Switch to determine whether free standing document commands take an +% optional argument (a number). The standard setting is |false|. +% \end{function} +% +% \begin{function}{use-xspace} +% \begin{syntax} +% |use-xspace| = |true|\verb"|"|false| +% \end{syntax} +% Switch to determine whether free standing document commands use the +% \pkg{xparse} package to insert space after the command names. The standard +% setting is |false|. When set |true|, the \pkg{xparse} package will be +% loaded at the start of the document if not already available. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-command} 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_command> +% \end{macrocode} +% +% \begin{macro}{\l_@@_tmp_tl} +% \begin{macrocode} +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{macro} +% +% \subsection{Options} +% +% \begin{variable} +% { +% \l_@@_create_bool , +% \l_@@_overwrite_bool , +% \l_@@_prespace_bool , +% \l_@@_optarg_bool , +% \l_@@_xspace_bool +% } +% \begin{macrocode} +\keys_define:nn { siunitx } + { + free-standing-units .bool_set:N = + \l_@@_create_bool , + overwrite-commands .bool_set:N = + \l_@@_overwrite_bool , + space-before-unit .bool_set:N = + \l_@@_prespace_bool , + unit-optional-argument .bool_set:N = + \l_@@_optarg_bool , + use-xspace .bool_set:N = + \l_@@_xspace_bool + } +% \end{macrocode} +% \end{variable} +% +% These preamble-only options are all disabled at the start of the document. +% \begin{macrocode} +\AtBeginDocument + { + \clist_map_inline:nn + { + free-standing-units , + overwrite-commands , + space-before-unit , + unit-optional-argument , + use-xspace + } + { + \keys_define:nn { siunitx } + { + #1 .code:n = + { \msg_warning:nnn { siunitx } { option-preamble-only } {#1} } + } + } + } +\msg_new:nnn { siunitx } { option-preamble-only } + { Option~'#1'~only~available~in~the~preamble. } +% \end{macrocode} +% +% \subsection{Creation of unit document commands} +% +% \begin{macro}{\siunitx_command_create:, \@@_create:} +% \begin{macro}{\@@_create:N} +% Creating document commands is all done by a single function which is +% set up using expansion: that way the tests are only run once. Other than +% that, this is all just a question of picking up all the various routes. +% Where the \pkg{soulpos} package is loaded \emph{after} \pkg{siunitx}, the +% commands \cs{hl} and \cs{ul} will be created only after the hook is used. +% The \pkg{soul} package creates those using \tn{newcommand}, so we have to +% avoid an issue. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_command_create: + { + \bool_if:NT \l_@@_create_bool + { + \@@_create: + \@ifpackageloaded { soulpos } + { + \@ifpackageloaded { soul } + { } + { + \cs_undefine:N \hl + \cs_undefine:N \ul + } + } + { } + } +% \end{macrocode} +% At the beginning of table cells and inside \texttt{x}-type expansion, +% all symbolic units need to have \emph{some} definition. +% \begin{macrocode} + \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq + { + \cs_if_free:NT ##1 + { \cs_set_protected:Npn ##1 { \ERROR } } + } + } +\AtBeginDocument { \siunitx_command_create: } +\cs_new_protected:Npn \@@_create: + { + \bool_if:NT \l_@@_xspace_bool + { \RequirePackage { xspace } } + \bool_if:NT \l_@@_overwrite_bool + { + \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq + { \cs_undefine:N ##1 } + } + \cs_set_protected:Npx \@@_create:N ##1 + { + \ProvideDocumentCommand ##1 { \bool_if:NT \l_@@_optarg_bool { o } } + { + \mode_leave_vertical: + \group_begin: + \bool_if:NTF \l_@@_optarg_bool + { \exp_not:N \IfNoValueTF {####1} } + { \use_i:nn } + { + \siunitx_unit_options_apply:n {##1} + \bool_if:NT \l_@@_prespace_bool { \exp_not:N \ } + \siunitx_unit_format:nN {##1} + \exp_not:N \l_@@_tmp_tl + \siunitx_print_unit:V + \exp_not:N \l_@@_tmp_tl + } + { \siunitx_quantity:nn {####1} {##1} } + \group_end: + \bool_if:NT \l_@@_xspace_bool { \exp_not:N \xspace } + } + } + \seq_map_function:NN \l_siunitx_unit_seq \@@_create:N + } +\cs_new_protected:Npn \@@_create:N #1 { } +% \end{macrocode} +% \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 } + { + free-standing-units = false , + overwrite-commands = false , + space-before-unit = false , + unit-optional-argument = false , + use-xspace = false + } +% \end{macrocode} +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-complex.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-complex.dtx new file mode 100644 index 00000000000..87c1b684ef8 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-complex.dtx @@ -0,0 +1,849 @@ +% \iffalse meta-comment +% +% File: siunitx-complex.dtx Copyright (C) 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-complex} -- Complex numbers^^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 concerned with formatting complex numbers. It augments the +% standard functions \cs{siunitx_number_format:nN} and \cs{siunitx_quantity:nn} +% by allowing parsing of numbers with a complex part. There are no additional +% assumptions concerning \LaTeXe{} commands in the submodule beyond those in the +% core number and unit submodules. +% +% \begin{function}{\siunitx_complex_number:n} +% \begin{syntax} +% \cs{siunitx_complex_number:n} \Arg{number} +% \end{syntax} +% Parses the \meta{number} and splits into real and complex parts, which are +% then formatted as described for \cs{siunitx_number_format:nN}. The results +% are combined and printed using the standard functions in the module. +% \end{function} +% +% \begin{function}{\siunitx_complex_quantity:nn} +% \begin{syntax} +% \cs{siunitx_complex_quantity:n} \Arg{number} \Arg{units} +% \end{syntax} +% Parses the \meta{number} and splits into real and complex parts, which are +% then formatted as described for \cs{siunitx_quantity:nn}. The results +% are combined and printed using the standard functions in the module. +% \end{function} +% +% \begin{function}{complex-root-position} +% \begin{syntax} +% |complex-root-position| = |after-number|\verb"|"|before-number| +% \end{syntax} +% Choice which determines where the complex root symbol is printed relative +% to the numbers. The standard setting is |after-number|. +% \end{function} +% +% \begin{function}{input-complex-root} +% \begin{syntax} +% |input-complex-root| = \meta{tokens} +% \end{syntax} +% The token(s) considered as complexes roots for number parsing. +% The standard setting is |ij|. +% \end{function} +% +% \begin{function}{output-complex-root} +% \begin{syntax} +% |output-complex-root| = \meta{tokens} +% \end{syntax} +% The token(s) used to show the complex root in output. The standard setting +% is |\mathrm{i}|. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% Start the \pkg{DocStrip} guards. +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \section{\pkg{siunitx-complex} implementation} +% +% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention): only +% internal material in this \emph{submodule} should be used directly. +% \begin{macrocode} +%<@@=siunitx_complex> +% \end{macrocode} +% +% \subsection{General setup} +% +% \begin{variable}{\l_@@_tmp_tl} +% \begin{macrocode} +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_input_tl} +% The numerical input exactly as given by the user. +% \begin{macrocode} +\tl_new:N \l_@@_input_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_comparator_tl} +% A comparator, if found, is held here. +% \begin{macrocode} +\tl_new:N \l_@@_comparator_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_exp_tl} +% The exponent part of a parsed number. +% \begin{macrocode} +\tl_new:N \l_@@_exp_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_real_tl, \l_@@_img_tl} +% The real and imaginary parts of the number, respectively. +% \begin{macrocode} +\tl_new:N \l_@@_real_tl +\tl_new:N \l_@@_img_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_join_tl, \l_@@_sign_tl} +% Staging posts for a joining and leading sign, respectively. +% \begin{macrocode} +\tl_new:N \l_@@_join_tl +\tl_new:N \l_@@_sign_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_input_root_tl, \l_@@_output_root_tl} +% \begin{macrocode} +\bool_new:N \l_@@_root_after_bool +\keys_define:nn { siunitx } + { + complex-root-position .choice: , + complex-root-position / after-number .code:n = + { \bool_set_true:N \l_@@_root_after_bool } , + complex-root-position / before-number .code:n = + { \bool_set_false:N \l_@@_root_after_bool } , + input-complex-root .tl_set:N = + \l_@@_input_root_tl , + output-complex-root .tl_set:N = + \l_@@_output_root_tl + } +% \end{macrocode} +% \end{variable} +% +% \subsection{Parsing} +% +% \begin{macro}{\@@_parse:nNN} +% \begin{macro}{\@@_parse_end:} +% \begin{macro}{\@@_parse_clear:} +% Parsing for complex numbers needs some of the same approaches as the +% general parser. However, as the aim here is to do only enough to split +% the real and imaginary parts before handing off the the usual code, +% it's not a full repeat. Instead, we shortcut where we can. The |clear| +% function here is not only there to make this function shorter: it +% also allows a single way to zap any stored data if a parse error occurs. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse:nNN #1#2#3 + { + \group_begin: + \@@_parse_clear: + \protected@edef \l_@@_arg_tl {#1} + \tl_set_eq:NN \l_@@_input_tl \l_@@_arg_tl + \siunitx_number_normalize_symbols:N \l_@@_arg_tl + \tl_if_empty:NF \l_@@_arg_tl + { \@@_parse_comparator: } + \@@_parse_check: + \cs_set_protected:Npx \@@_parse_end: + { + \tl_set:Nn \exp_not:N #2 { \exp_not:V \l_@@_real_tl } + \tl_set:Nn \exp_not:N #3 { \exp_not:V \l_@@_img_tl } + } + \exp_after:wN \group_end: + \@@_parse_end: + } +\cs_new_protected:Npn \@@_parse_end: { } +\cs_new_protected:Npn \@@_parse_clear: + { + \tl_clear:N \l_@@_real_tl + \tl_clear:N \l_@@_img_tl + \tl_clear:N \l_@@_exp_tl + \tl_clear:N \l_@@_sign_tl + \tl_clear:N \l_@@_join_tl + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_check:, \@@_parse_finalise:} +% \begin{macro}{\@@_parse_finalise:N} +% Now we tidy up and do the main work: passing to the standard formatter for +% final parsing. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_check: + { + \bool_lazy_all:nTF + { + { \tl_if_empty_p:N \l_@@_real_tl } + { \tl_if_empty_p:N \l_@@_img_tl } + { \tl_if_empty_p:N \l_@@_exp_tl } + } + { + \msg_error:nnx { siunitx } { invalid-complex-number } + { \exp_not:V \l_@@_input_tl } + } + { \@@_parse_finalise: } + } +\cs_new_protected:Npn \@@_parse_finalise: + { + \tl_if_empty:NTF \l_@@_img_tl + { \@@_parse_finalise:N \l_@@_real_tl } + { + \tl_if_empty:NTF \l_@@_real_tl + { \@@_parse_finalise:N \l_@@_img_tl } + { + \@@_parse_finalise:N \l_@@_real_tl + \tl_set_eq:NN \l_@@_sign_tl \l_@@_join_tl + \@@_parse_finalise:N \l_@@_img_tl + } + } + } +\cs_new_protected:Npn \@@_parse_finalise:N #1 + { + \tl_set:Nx #1 + { + \exp_not:V \l_@@_comparator_tl + \exp_not:V \l_@@_sign_tl + \exp_not:V #1 + \exp_not:V \l_@@_exp_tl + } + \tl_clear:N \l_@@_comparator_tl + \tl_clear:N \l_@@_sign_tl + \siunitx_number_parse:VN #1 #1 + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_comparator:} +% \begin{macro}{\@@_parse_comparator_aux:Nw} +% The first step is to extract any comparator: this is the same as +% for a full number parse. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_comparator: + { + \exp_after:wN \@@_parse_comparator_aux:Nw + \l_@@_arg_tl \q_stop + } +\cs_new_protected:Npn \@@_parse_comparator_aux:Nw #1#2 \q_stop + { + \tl_if_in:NnTF \l_siunitx_number_input_comparator_tl {#1} + { + \tl_set:Nn \l_@@_comparator_tl {#1} + \tl_set:Nn \l_@@_arg_tl {#2} + } + { \tl_clear:N \l_@@_comparator_tl } + \tl_if_empty:NF \l_@@_arg_tl + { \@@_parse_sign: } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_exponent:} +% \begin{macro}{\@@_parse_exponent_auxi:w} +% \begin{macro}{\@@_parse_exponent_auxii:nn} +% An exponent part of a number has to come at the end and can only occur +% once. Thus it is relatively easy to parse. The code here is a simplified +% version of that in \pkg{siunitx-number}: we only need to find \emph{some} +% exponent, not check on the detail. Notice that we need to retain the +% exponent marker here: that is done using the short-lived temporary +% variable. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_exponent: + { + \tl_if_empty:NTF \l_siunitx_number_input_exponent_tl + { \@@_parse_root: } + { + \tl_set:Nx \l_@@_tmp_tl + { \tl_head:V \l_siunitx_number_input_exponent_tl } + \tl_map_inline:Nn \l_siunitx_number_input_exponent_tl + { + \tl_replace_all:NnV \l_@@_arg_tl + {##1} \l_@@_tmp_tl + } + \use:x + { + \cs_set_protected:Npn + \exp_not:N \@@_parse_exponent_auxi:w + ####1 \exp_not:V \l_@@_tmp_tl + ####2 \exp_not:V \l_@@_tmp_tl + ####3 \exp_not:N \q_stop + } + { \@@_parse_exponent_auxii:nn {##1} {##2} } + \use:x + { + \@@_parse_exponent_auxi:w + \exp_not:V \l_@@_arg_tl + \exp_not:V \l_@@_tmp_tl \exp_not:N \q_nil + \exp_not:V \l_@@_tmp_tl \exp_not:N \q_stop + } + } + } +\cs_new_protected:Npn \@@_parse_exponent_auxi:w { } +\cs_new_protected:Npn \@@_parse_exponent_auxii:nn #1#2 + { + \quark_if_nil:nF {#2} + { + \tl_set:Nn \l_@@_arg_tl {#1} + \tl_set:Nx \l_@@_exp_tl + { \exp_not:V \l_@@_tmp_tl \exp_not:n {#2} } + } + \@@_parse_root: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_root:} +% \begin{macro}{\@@_parse_root_auxi:w} +% \begin{macro}{\@@_parse_root_auxii:nn} +% Splitting at the complex root is much like splitting the exponent. +% After dealing with the case where there is no complex root allowed, +% use the first possible symbol to do the work. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_root: + { + \tl_if_empty:NTF \l_@@_input_root_tl + { \tl_set_eq:NN \l_@@_real_tl \l_@@_arg_tl } + { + \tl_set:Nx \l_@@_tmp_tl + { \tl_head:V \l_@@_input_root_tl } + \tl_map_inline:Nn \l_@@_input_root_tl + { + \tl_replace_all:NnV \l_@@_arg_tl + {##1} \l_@@_tmp_tl + } + \use:x + { + \cs_set_protected:Npn + \exp_not:N \@@_parse_root_auxi:w + ####1 \exp_not:V \l_@@_tmp_tl + ####2 \exp_not:V \l_@@_tmp_tl + ####3 \exp_not:N \q_stop + } + { \@@_parse_root_auxii:nn {##1} {##2} } + \use:x + { + \@@_parse_root_auxi:w + \exp_not:V \l_@@_arg_tl + \exp_not:V \l_@@_tmp_tl \exp_not:N \q_nil + \exp_not:V \l_@@_tmp_tl \exp_not:N \q_stop + } + } + } +\cs_new_protected:Npn \@@_parse_root_auxi:w { } +% \end{macrocode} +% This is where the business end lies. We have four possibilities: +% \begin{itemize} +% \item There was no complex root at all: |#2| will be |\q_nil| +% \item All of the number is in the complex part with a leading +% root: |#1| will be empty. This includes the case where +% the input was \emph{just} a root symbol (plus possibly sign, +% exponent): we need to cover that. +% \item All of the number was before the complex root: |#2| will +% be empty and we need to check |#1| fully to split out the two +% parts +% \item The input has a a real part with the complex part starting +% with the root symbol: just the last token needs to be separated. +% \end{itemize} +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_root_auxii:nn #1#2 + { + \quark_if_nil:nTF {#2} + { \tl_set:Nn \l_@@_real_tl {#1} } + { + \tl_set:Nn \l_@@_img_tl {#2} + \tl_if_blank:nTF {#1} + { + \tl_if_blank:nT {#2} + { \tl_set:Nn \l_@@_img_tl { 1 } } + } + { + \tl_if_blank:nTF {#2} + { \@@_parse_split:n {#1} } + { \@@_parse_sign_check:n {#1} } + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_sign:} +% \begin{macro}{\@@_parse_sign_aux:Nw} +% The first token of a number after a comparator could be a sign. A quick +% check is made and if found stored. There is no need to worry about the +% nature of the sign: we keep them regardless. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_sign: + { + \exp_after:wN \@@_parse_sign_aux:Nw + \l_@@_arg_tl \q_stop + } +\cs_new_protected:Npn \@@_parse_sign_aux:Nw #1#2 \q_stop + { + \tl_if_in:NnT \l_siunitx_number_input_sign_tl {#1} + { + \tl_set:Nn \l_@@_sign_tl {#1} + \tl_set:Nn \l_@@_arg_tl {#2} + } + \tl_if_empty:NF \l_@@_arg_tl + { \@@_parse_exponent: } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_sign_check:n} +% \begin{macro}{\@@_parse_sign_check:nN} +% \begin{macro}{\@@_parse_sign_check:nNw} +% Here, we want to check that the last token in the input is a sign. +% There cannot be anything after the sign, and there has to be at one +% token before the sign: we can therefore signal a parsing error if we +% need to. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_sign_check:n #1 + { + \@@_parse_sign_check:nN { } #1 \q_recursion_tail \q_recursion_stop + } +\cs_new_protected:Npn \@@_parse_sign_check:nN #1#2 + { + \quark_if_recursion_tail_stop_do:Nn #2 + { \@@_parse_clear: } + \tl_if_in:NnTF \l_siunitx_number_input_sign_tl {#2} + { \@@_parse_sign_check:nNw {#1} #2 } + { \@@_parse_sign_check:nN {#1#2} } + } +\cs_new_protected:Npn \@@_parse_sign_check:nNw + #1#2 #3 \q_recursion_tail \q_recursion_stop + { + \tl_if_blank:nTF {#3} + { + \tl_if_blank:nTF {#1} + { \@@_parse_clear: } + { + \tl_set:Nn \l_@@_real_tl {#1} + \tl_set:Nn \l_@@_join_tl {#2} + } + } + { \@@_parse_clear: } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_split:n} +% \begin{macro}{\@@_parse_split:nN} +% \begin{macro}{\@@_parse_split:w} +% Checking for a sign inside the leading part of the number is a simple loop. +% There is the possibility that there is no number in the imaginary part +% needs to be allowed for. Notice that we do a check that there is some +% real part: this covers for example an original input |++1i|, which +% otherwise would not be trapped. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_split:n #1 + { + \@@_parse_split:nN { } #1 \q_recursion_tail \q_recursion_stop + } +\cs_new_protected:Npn \@@_parse_split:nN #1#2 + { + \quark_if_recursion_tail_stop_do:Nn #2 + { \tl_set:Nn \l_@@_img_tl {#1} } + \tl_if_in:NnTF \l_siunitx_number_input_sign_tl {#2} + { + \tl_set:Nn \l_@@_real_tl {#1} + \tl_set:Nn \l_@@_join_tl {#2} + \@@_parse_split:w + } + { \@@_parse_split:nN {#1#2} } + } +\cs_new_protected:Npn \@@_parse_split:w #1 \q_recursion_tail \q_recursion_stop + { + \tl_set:Nx \l_@@_img_tl + { + \tl_if_blank:nTF {#1} + { 1 } + { \exp_not:n {#1} } + } + \tl_if_empty:NT \l_@@_real_tl + { \@@_parse_clear: } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \section{Formatting} +% +% \begin{variable}{\l_@@_bracket_close_tl, \l_@@_bracket_open_tl} +% Purely internal for the present. +% \begin{macrocode} +\tl_new:N \l_@@_bracket_close_tl +\tl_new:N \l_@@_bracket_open_tl +\tl_set:Nn \l_@@_bracket_open_tl { ( } +\tl_set:Nn \l_@@_bracket_close_tl { ) } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_unit_tl} +% \begin{macrocode} +\tl_new:N \l_@@_unit_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_complex_number:n} +% \begin{macro}{\siunitx_complex_quantity:nn} +% The work here is pretty trivial. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_complex_number:n #1 + { + \group_begin: + \bool_if:NTF \l_siunitx_number_parse_bool + { + \@@_parse:nNN {#1} \l_@@_real_tl \l_@@_img_tl + \@@_format:n { } + } + { + \siunitx_number_format:nN {#1} \l_@@_tmp_tl + \siunitx_print_number:V \l_@@_tmp_tl + } + \group_end: + } +\cs_new_protected:Npn \siunitx_complex_quantity:nn #1#2 + { + \group_begin: + \bool_if:NTF \l_siunitx_number_parse_bool + { + \@@_parse:nNN {#1} \l_@@_real_tl \l_@@_img_tl + \@@_format:n {#2} + } + { \siunitx_quantity:nn {#1} {#2} } + \group_end: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_format:n} +% \begin{macro}{\@@_format_auxi:n} +% \begin{macro}{\@@_format_unary:nnnnnnn} +% \begin{macro}{\@@_format_auxii:n} +% \begin{macro}{\@@_drop_exponent:nnnnnnn} +% \begin{macro}{\@@_format_sign:nnnnnnn} +% \begin{macro}{\@@_extract_exponent:nw} +% \begin{macro}{\@@_extract_exponent_aux:w} +% \begin{macro}[EXP]{\@@_format_bracket:n} +% We start here checking that there is something to do. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format:n #1 + { + \bool_lazy_and:nnF + { \tl_if_empty_p:N \l_@@_real_tl } + { \tl_if_empty_p:N \l_@@_img_tl } + { \@@_format_auxi:n {#1} } + } +% \end{macrocode} +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_auxi:n #1 + { + \tl_clear:N \l_@@_tmp_tl + \tl_if_empty:NTF \l_@@_real_tl + { + \@@_format_units:n {#1} + \exp_after:wN \@@_format_unary:nnnnnnn \l_@@_img_tl + \tl_set:Nx \l_@@_tmp_tl + { + \siunitx_number_output:N \l_@@_img_tl + \exp_not:V \l_@@_output_root_tl + } + } + { + \tl_if_empty:NTF \l_@@_img_tl + { + \siunitx_number_process:NN \l_@@_real_tl \l_@@_real_tl + \tl_set:Nx \l_@@_tmp_tl + { \siunitx_number_output:N \l_@@_real_tl } + } + { \@@_format_auxii:n {#1} } + } + \tl_if_blank:nTF {#1} + { \siunitx_print_number:V \l_@@_tmp_tl } + { \siunitx_quantity_print:VV \l_@@_tmp_tl \l_@@_unit_tl } + } +% \end{macrocode} +% An imaginary part that is exactly $1$ is omitted, with only the complex +% root printed. That means checking and removing a lone $1$ here. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_unary:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_set:Nx \l_@@_img_tl + { + \exp_not:n { {#1} {#2} } + \tl_if_blank:nTF {#4} + { + \str_if_eq:nnTF {#3} { 1 } + { { } { } } + { \exp_not:n { {#3} {#4} } } + } + { \exp_not:n { {#3} {#4} } } + \exp_not:n { {#5} {#6} {#7} } + } + } +% \end{macrocode} +% If we get to this stage we have both parts to a complex number. We +% need to process both and do some massaging, then it's just a question +% of reassembly with the right parts in the right places. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_auxii:n #1 + { + \@@_format_units:n {#1} + \exp_after:wN \@@_drop_exponent:nnnnnnn \l_@@_real_tl + \exp_after:wN \@@_format_sign:nnnnnnn \l_@@_img_tl + \tl_set:Nx \l_@@_tmp_tl + { \siunitx_number_output:NN \l_@@_img_tl \q_nil } + \exp_after:wN \@@_extract_exponent:w \l_@@_tmp_tl \q_stop + \tl_set:Nx \l_@@_tmp_tl + { + \bool_lazy_and:nnTF + { \l_siunitx_number_bracket_ambiguous_bool } + { ! \tl_if_empty_p:N \l_@@_exp_tl } + { \@@_format_bracket:n } + { \use:n } + { + \siunitx_number_output:N \l_@@_real_tl + \exp_not:V \l_@@_sign_tl + \bool_if:NF \l_@@_root_after_bool + { \exp_not:V \l_@@_output_root_tl } + \exp_not:V \l_@@_tmp_tl + \bool_if:NT \l_@@_root_after_bool + { \exp_not:V \l_@@_output_root_tl } + } + \exp_not:V \l_@@_exp_tl + } + } +% \end{macrocode} +% No exponent for the real part. +% \begin{macrocode} +\cs_new_protected:Npn \@@_drop_exponent:nnnnnnn #1#2#3#4#5#6#7 + { \tl_set:Nn \l_@@_real_tl { {#1} {#2} {#3} {#4} {#5} { } { 0 } } } +% \end{macrocode} +% Ensure the imaginary part has a sign, and also deal with the case +% where there is no mantissa to print (as it is $1$). +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_sign:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_set:Nx \l_@@_img_tl + { + { } + { \tl_if_blank:nTF {#2} { + } { \exp_not:n {#2} } } + \tl_if_blank:nTF {#4} + { + \str_if_eq:nnTF {#3} { 1 } + { { } { } } + { \exp_not:n { {#3} {#4} } } + } + { \exp_not:n { {#3} {#4} } } + \exp_not:n { {#5} {#6} {#7} } + } + } +% \end{macrocode} +% Pull out the formatted exponent: we also need the sign. +% \begin{macrocode} +\cs_new_protected:Npn \@@_extract_exponent:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_nil #8 + \q_nil #9 \q_stop + { + \tl_set:Nn \l_@@_sign_tl {#1#2} + \@@_extract_exponent_aux:nw {#3#4#5#6#7#8} #9 \q_stop + } +\cs_new:Npn \@@_extract_exponent_aux:nw + #1#2 \q_nil #3 \q_nil #4 \q_stop + { + \tl_set:Nn \l_@@_tmp_tl {#1#2} + \tl_set:Nn \l_@@_exp_tl {#3#4} + } +\cs_new_protected:Npn \@@_format_bracket:n #1 + { + \exp_not:V \l_@@_bracket_open_tl + #1 + \exp_not:V \l_@@_bracket_close_tl + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_format_units:n} +% \begin{macro} +% { +% \@@_format_combine-exponent:n , +% \@@_format_extract-exponent:n , +% \@@_format_input:n +% } +% \begin{macro}{\@@_format_extract-exponent:N} +% \begin{macro}[EXP]{\@@_extract_exp:nnnnnnn} +% Formatting units needs to know the settings from the main module, and +% the flow is then much the same as in \pkg{siunitx-compound}. We only +% have to watch the fact there are two numbers to format. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_units:n #1 + { + \tl_if_blank:nTF {#1} + { + \siunitx_number_process:NN \l_@@_real_tl \l_@@_real_tl + \siunitx_number_process:NN \l_@@_img_tl \l_@@_img_tl + } + { + \use:c { @@_format_ \l_siunitx_quantity_prefix_mode_tl :n } {#1} + } + } +\cs_new_protected:cpn { @@_format_combine-exponent:n } #1 + { + \tl_if_empty:NF \l_@@_real_tl + { \siunitx_number_process:NN \l_@@_real_tl \l_@@_real_tl } + \siunitx_number_process:NN \l_@@_img_tl \l_@@_img_tl + \fp_set:Nn \l_@@_tmp_fp + { \exp_after:wN \@@_extract_exp:nnnnnnn \l_@@_img_tl } + \siunitx_unit_format_combine_exponent:nnN {#1} + \l_@@_tmp_fp \l_@@_unit_tl + } +\cs_new_protected:cpx { @@_format_extract-exponent:n } #1 + { + \exp_not:N \siunitx_unit_format_extract_prefixes:nNN {#1} + \exp_not:N \l_@@_unit_tl \exp_not:N \l_@@_tmp_fp + \exp_not:c { @@_format_extract-exponent:N } + \exp_not:N \l_@@_img_tl + \exp_not:N \tl_if_empty:NF \exp_not:N \l_@@_real_tl + { + \exp_not:c { @@_format_extract-exponent:N } + \exp_not:N \l_@@_real_tl + } + } +\cs_new_protected:cpn { @@_format_extract-exponent:N } #1 + { + \tl_set:Nx #1 + { \siunitx_number_adjust_exponent:Nn #1 \l_@@_tmp_fp } + \siunitx_number_process:NN #1 #1 + } +\cs_new_protected:Npn \@@_format_input:n #1 + { + \siunitx_number_process:NN \l_@@_real_tl \l_@@_real_tl + \siunitx_number_process:NN \l_@@_img_tl \l_@@_img_tl + \siunitx_unit_format:nN {#1} \l_@@_unit_tl + } +\cs_new:Npn \@@_extract_exp:nnnnnnn #1#2#3#4#5#6#7 { #6#7 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macrocode} +\msg_new:nnnn { siunitx } { invalid-complex-number } + { Invalid~complex-number~'#1'. } + { + The~input~'#1'~could~not~be~parsed~as~a~complex|number~following~the~ + format~defined~in~module~documentation. + } +% \end{macrocode} +% +% \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 } + { + complex-root-position = after-number , + input-complex-root = ij , + output-complex-root = \mathrm { i } + } +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-compound.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-compound.dtx new file mode 100644 index 00000000000..83da873e6c0 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-compound.dtx @@ -0,0 +1,1081 @@ +% \iffalse meta-comment +% +% File: siunitx-compound.dtx Copyright (C) 2018-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-compound} -- Compound numbers and quantities^^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} +% +% \begin{function}{\siunitx_compound_number:n} +% \begin{syntax} +% \cs{siunitx_compound_number:n} \Arg{entries} +% \end{syntax} +% Prints a set of numbers in the \meta{entries}, each of which should +% be given as a \meta{balanced text}. Unlike \cs{siunitx_number_list:nn}, this +% function may semantically take any form +% \end{function} +% +% \begin{function}{\siunitx_compound_quantity:nn} +% \begin{syntax} +% \cs{siunitx_compound_quantity:nn} \Arg{entries} \Arg{unit} +% \end{syntax} +% Prints a set of quantities in the \meta{entries}, each of which should +% be given as a \meta{balanced text}. Unlike \cs{siunitx_quantity_list:nn}, this +% function may semantically take any form +% \end{function} +% +% \begin{function}{\siunitx_number_list:nn} +% \begin{syntax} +% \cs{siunitx_number_list:nn} \Arg{entries} +% \end{syntax} +% Prints the list of numbers in the \meta{entries}, each of which should +% be given as a \meta{balanced text}. +% \end{function} +% +% \begin{function}{\siunitx_quantity_list:nn} +% \begin{syntax} +% \cs{siunitx_quantity_list:nn} \Arg{entries} \Arg{unit} +% \end{syntax} +% Prints the list of quantities in the \meta{entries}, each of which should +% be given as a \meta{balanced text}. +% \end{function} +% +% \begin{function}{\siunitx_number_product:n} +% \begin{syntax} +% \cs{siunitx_number_product:n} \Arg{entries} +% \end{syntax} +% Prints the series of numbers in the \meta{entries}, each of which should +% be given as a \meta{balanced text}. +% \end{function} +% +% \begin{function}{\siunitx_quantity_product:nn} +% \begin{syntax} +% \cs{siunitx_number_product:n} \Arg{entries} \Arg{unit} +% \end{syntax} +% Prints the series of quantities in the \meta{entries}, each of which should +% be given as a \meta{balanced text}. +% \end{function} +% +% \begin{function}{\siunitx_number_range:nn} +% \begin{syntax} +% \cs{siunitx_number_range:nn} \Arg{start} \Arg{end} +% \end{syntax} +% Prints the range of numbers from the \meta{start} to the \meta{end}. +% \end{function} +% +% \begin{function}{\siunitx_quantity_range:nnn} +% \begin{syntax} +% \cs{siunitx_number_range:nn} \Arg{start} \Arg{end} \Arg{unit} +% \end{syntax} +% Prints the range of quantities from the \meta{start} to the \meta{end}. +% \end{function} +% +% \begin{variable} +% { +% \l_siunitx_list_separator_pair_tl, +% \l_siunitx_list_separator_tl, +% \l_siunitx_list_separator_final_tl +% } +% Separators for lists of numbers and quantities. +% \end{variable} +% +% \begin{variable}{\l_siunitx_range_phrase_tl} +% Phrase (or similar) used between limits of a range. +% \end{variable} +% +% \begin{function}{compound-exponents} +% \begin{syntax} +% |compound-exponents| = |combine|\verb"|"|combine-bracket|\verb"|"|individual| +% \end{syntax} +% \end{function} +% +% \begin{function}{compound-final-separator} +% \begin{syntax} +% |compound-final-separator| = \meta{text} +% \end{syntax} +% \end{function} +% +% \begin{function}{compound-pair-separator} +% \begin{syntax} +% |compound-pair-separator| = \meta{text} +% \end{syntax} +% \end{function} +% +% \begin{function}{compound-separator} +% \begin{syntax} +% |compound-separator| = \meta{text} +% \end{syntax} +% \end{function} +% +% \begin{function}{compound-separator-mode} +% \begin{syntax} +% |compound-separator-mode| = |number|\verb"|"|text| +% \end{syntax} +% \end{function} +% +% \begin{function}{compound-units} +% \begin{syntax} +% |compound-units| = |bracket|\verb"|"|repeat|\verb"|"|single| +% \end{syntax} +% \end{function} +% +% \begin{function}{list-exponents} +% \begin{syntax} +% |list-exponents| = |combine|\verb"|"|combine-bracket|\verb"|"|individual| +% \end{syntax} +% \end{function} +% +% \begin{function}{list-final-separator} +% \begin{syntax} +% |list-final-separator| = \meta{text} +% \end{syntax} +% \end{function} +% +% \begin{function}{list-pair-separator} +% \begin{syntax} +% |list-pair-separator| = \meta{text} +% \end{syntax} +% \end{function} +% +% \begin{function}{list-separator} +% \begin{syntax} +% |list-separator| = \meta{text} +% \end{syntax} +% \end{function} +% +% \begin{function}{list-units} +% \begin{syntax} +% |list-units| = |bracket|\verb"|"|repeat|\verb"|"|single| +% \end{syntax} +% \end{function} +% +% \begin{function}{product-exponents} +% \begin{syntax} +% |product-exponents| = |combine|\verb"|"|combine-bracket|\verb"|"|individual| +% \end{syntax} +% \end{function} +% +% \begin{function}{product-mode} +% \begin{syntax} +% |product-mode| = |phrase|\verb"|"|choice| +% \end{syntax} +% \end{function} +% +% \begin{function}{product-phrase} +% \begin{syntax} +% |product-phrase| = \meta{text} +% \end{syntax} +% \end{function} +% +% \begin{function}{product-symbol} +% \begin{syntax} +% |product-symbol| = \meta{symbol} +% \end{syntax} +% \end{function} +% +% \begin{function}{range-exponents} +% \begin{syntax} +% |range-exponents| = |combine|\verb"|"|combine-bracket|\verb"|"|individual| +% \end{syntax} +% \end{function} +% +% \begin{function}{range-phrase} +% \begin{syntax} +% |range-phrase| = \meta{text} +% \end{syntax} +% \end{function} +% +% \begin{function}{range-units} +% \begin{syntax} +% |range-units| = |bracket|\verb"|"|repeat|\verb"|"|single| +% \end{syntax} +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% Start the \pkg{DocStrip} guards. +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \section{\pkg{siunitx-compound} implementation} +% +% \begin{macrocode} +\cs_generate_variant:Nn \keys_set:nn { nx } +% \end{macrocode} +% +% \subsection{General mechanism} +% +% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention): only +% internal material in this \emph{submodule} should be used directly. +% \begin{macrocode} +%<@@=siunitx_compound> +% \end{macrocode} +% +% Typesetting lists, ranges and products of numbers or quantities has shared +% features which mean they are best handled using a common mechanism. The aim +% therefore is to abstract out enough of the process such that output-specific +% aspects can be left to separate processes. +% +% \begin{variable}{\l_@@_tmp_fp, \l_@@_tmp_seq, \l_@@_tmp_tl} +% Scratch space. +% \begin{macrocode} +\fp_new:N \l_@@_tmp_fp +\seq_new:N \l_@@_tmp_seq +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_first_tl} +% The first number in the list in internal format. +% \begin{macrocode} +\tl_new:N \l_@@_first_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_exp_tl} +% For storing the combined exponent, if present. +% \begin{macrocode} +\tl_new:N \l_@@_exp_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_start_tl, \l_@@_end_tl} +% Data on the end-of-list. +% \begin{macrocode} +\tl_new:N \l_@@_start_tl +\tl_new:N \l_@@_end_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_count_int} +% Data on the length-of-list. +% \begin{macrocode} +\int_new:N \l_@@_count_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_unit_tl} +% \begin{macrocode} +\tl_new:N \l_@@_unit_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_bracket_close_tl, \l_@@_bracket_open_tl} +% Purely internal for the present. +% \begin{macrocode} +\tl_new:N \l_@@_bracket_close_tl +\tl_new:N \l_@@_bracket_open_tl +\tl_set:Nn \l_@@_bracket_open_tl { ( } +\tl_set:Nn \l_@@_bracket_close_tl { ) } +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_@@_separator_final_tl , +% \l_@@_separator_pair_tl , +% \l_@@_separator_tl , +% \l_@@_separator_text_bool , +% \l_@@_exp_bracket_bool , +% \l_@@_exp_combine_bool , +% \l_@@_unit_bracket_bool , +% \l_@@_unit_repeat_bool , +% \l_@@_unit_repeat_bool +% } +% List options. +% \begin{macrocode} +\bool_new:N \l_@@_exp_bracket_bool +\bool_new:N \l_@@_exp_combine_bool +\bool_new:N \l_@@_separator_text_bool +\bool_new:N \l_@@_unit_bracket_bool +\bool_new:N \l_@@_unit_power_bool +\bool_new:N \l_@@_unit_repeat_bool +\keys_define:nn { siunitx } + { + compound-exponents .choice: , + compound-exponents / combine .code:n = + { + \bool_set_false:N \l_@@_exp_bracket_bool + \bool_set_true:N \l_@@_exp_combine_bool + } , + compound-exponents / combine-bracket .code:n = + { + \bool_set_true:N \l_@@_exp_bracket_bool + \bool_set_true:N \l_@@_exp_combine_bool + } , + compound-exponents / individual .code:n = + { + \bool_set_false:N \l_@@_exp_bracket_bool + \bool_set_false:N \l_@@_exp_combine_bool + } , + compound-final-separator .tl_set:N = + \l_@@_separator_final_tl , + compound-pair-separator .tl_set:N = + \l_@@_separator_pair_tl , + compound-separator .tl_set:N = + \l_@@_separator_tl , + compound-separator-mode .choice: , + compound-separator-mode / number .code:n = + { \bool_set_false:N \l_@@_separator_text_bool } , + compound-separator-mode / text .code:n = + { \bool_set_true:N \l_@@_separator_text_bool } , + compound-units .choice: , + compound-units / bracket .code:n = + { + \bool_set_true:N \l_@@_unit_bracket_bool + \bool_set_false:N \l_@@_unit_power_bool + \bool_set_false:N \l_@@_unit_repeat_bool + } , + compound-units / bracket-power .code:n = + { + \bool_set_true:N \l_@@_unit_bracket_bool + \bool_set_true:N \l_@@_unit_power_bool + \bool_set_false:N \l_@@_unit_repeat_bool + } , + compound-units / power .code:n = + { + \bool_set_false:N \l_@@_unit_bracket_bool + \bool_set_true:N \l_@@_unit_power_bool + \bool_set_false:N \l_@@_unit_repeat_bool + } , + compound-units / repeat .code:n = + { + \bool_set_false:N \l_@@_unit_bracket_bool + \bool_set_false:N \l_@@_unit_power_bool + \bool_set_true:N \l_@@_unit_repeat_bool + } , + compound-units / single .code:n = + { + \bool_set_false:N \l_@@_unit_bracket_bool + \bool_set_false:N \l_@@_unit_power_bool + \bool_set_false:N \l_@@_unit_repeat_bool + } + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_compound_number:n} +% \begin{macro}{\@@_format:n} +% \begin{macro}{\@@_format:nnn} +% Printing a generic set starts with the question of whether we want to +% extract exponents. If we do, then there is the work to do with extraction. +% Either way, the printing is handed off to a common function. We do a quick +% count up-front to avoid excess work when there is not actually a list. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_compound_number:n #1 + { + \group_begin: + \@@_format:nn {#1} { } + \@@_print:N \siunitx_print_number:x + \group_end: + } +\cs_new_protected:Npn \@@_format:nn #1#2 + { + \seq_clear:N \l_@@_tmp_seq + \bool_if:NTF \l_siunitx_number_parse_bool + { + \exp_args:Nxx \@@_format:nnn + { \tl_head:n {#1} } + { \tl_tail:n {#1} } + {#2} + } + { \tl_map_function:nN {#1} \@@_unparsed:n } + } +% \end{macrocode} +% Formatting at a low level needs to know about units and numbers: we have to +% exchange data between the two. Most of the business of handling the units +% is left to a dedicated auxiliary. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format:nnn #1#2#3 + { + \siunitx_number_parse:nN {#1} \l_@@_tmp_tl + \tl_if_blank:nTF {#3} + { \siunitx_number_process:NN \l_@@_tmp_tl \l_@@_first_tl } + { \@@_format_units:nn {#2} {#3} } + \bool_lazy_and:nnTF + { \l_@@_exp_combine_bool } + { \int_compare_p:nNn { \tl_count:n {#2} } > 0 } + { \@@_extract_exponents: } + { + \tl_set:Nx \l_@@_tmp_tl + { \siunitx_number_output:N \l_@@_first_tl } + \seq_put_right:NV \l_@@_tmp_seq \l_@@_tmp_tl + } + \tl_map_function:nN {#2} \@@_parsed:n + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_extract_exponents:N} +% \begin{macro}{\@@_extract_exponents_auxi:w} +% \begin{macro}{\@@_extract_exponents_auxii:nw} +% \begin{macro}{\@@_extract_exponents_auxiii:nnnnnnn} +% Extracting exponents means dealing with the first entry as a special case. +% After that, apply fixed processing to all other entries, tidying up using +% the number formatter. +% \begin{macrocode} +\cs_new_protected:Npn \@@_extract_exponents: + { + \tl_set:Nx \l_@@_tmp_tl + { \siunitx_number_output:NN \l_@@_first_tl \q_nil } + \exp_after:wN \@@_extract_exponents_auxi:w + \l_@@_tmp_tl \q_stop + } +\cs_new_protected:Npn \@@_extract_exponents_auxi:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_nil #8 + \q_nil #9 \q_stop + { + \@@_extract_exponents_auxii:nw {#1#2#3#4#5#6#7#8} #9 \q_stop + } +\cs_new_protected:Npn \@@_extract_exponents_auxii:nw + #1#2 \q_nil #3 \q_nil #4 \q_stop + { + \seq_put_right:Nn \l_@@_tmp_seq { #1#2 } + \tl_set:Nn \l_@@_exp_tl { #3#4 } + \exp_after:wN \@@_extract_exponents_auxiii:nnnnnnn + \l_@@_first_tl + } +\cs_new_protected:Npn \@@_extract_exponents_auxiii:nnnnnnn + #1#2#3#4#5#6#7 + { + \keys_set:nn { siunitx } + { + drop-exponent = true , + exponent-mode = fixed , + fixed-exponent = #6#7 + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parsed:n, \@@_unparsed:n} +% The simple cases for parsing (or not) all entries. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parsed:n #1 + { + \siunitx_number_format:nN {#1} \l_@@_tmp_tl + \seq_put_right:NV \l_@@_tmp_seq \l_@@_tmp_tl + } +\cs_new_protected:Npn \@@_unparsed:n #1 + { + \seq_put_right:Nn \l_@@_tmp_seq { \ensuremath {#1} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_format_units:nn} +% \begin{macro} +% { +% \@@_format_combine-exponent:n , +% \@@_format_extract-exponent:n , +% \@@_format_input:n +% } +% \begin{macro} +% { +% \@@_format_combine-exponent:nn , +% \@@_format_extract-exponent:nn +% } +% \begin{macro} +% { +% \@@_format_combine-exponent_aux:n , +% \@@_format_extract-exponent_aux:n +% } +% \begin{macro}{\@@_extract_exp:nN} +% \begin{macro}{\@@_extract_exp:nnnnnnnN} +% Actually formatting the units is much the same as is done in +% the quantities module, except that we have to cover the multiplication +% cases too: gets a bit repetitive. Notice that when combining exponents, +% there is no adjustment to the original exponent: we purely need to +% extract it. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_units:nn #1#2 + { + \bool_if:NTF \l_@@_unit_power_bool + { + \use:c { @@_format_ \l_siunitx_quantity_prefix_mode_tl :nn } + {#2} { \tl_count:n {#1} + 1 } + } + { + \use:c { @@_format_ \l_siunitx_quantity_prefix_mode_tl :n } {#2} + } + } +\cs_new_protected:cpx { @@_format_combine-exponent:n } #1 + { + \exp_not:c { @@_format_combine-exponent_aux:n } + { + \exp_not:N \siunitx_unit_format_combine_exponent:nnN + {#1} + } + } +\cs_new_protected:cpx { @@_format_combine-exponent:nn } #1#2 + { + \exp_not:c { @@_format_combine-exponent_aux:n } + { + \exp_not:N \siunitx_unit_format_multiply_combine_exponent:nnnN + {#1} {#2} + } + } +\cs_new_protected:cpn { @@_format_combine-exponent_aux:n } #1 + { + \bool_set_true:N \l_@@_exp_combine_bool + \siunitx_number_process:NN \l_@@_tmp_tl \l_@@_first_tl + \exp_args:NV \@@_extract_exp:nN + \l_@@_first_tl \l_@@_tmp_fp + #1 \l_@@_tmp_fp \l_@@_unit_tl + } +\cs_new_protected:cpx { @@_format_extract-exponent:n } #1 + { + \exp_not:c { @@_format_extract-exponent_aux:n } + { \exp_not:N \siunitx_unit_format_extract_prefixes:nNN {#1} } + } +\cs_new_protected:cpx { @@_format_extract-exponent:nn } #1#2 + { + \exp_not:c { @@_format_extract-exponent_aux:n } + { + \exp_not:N \siunitx_unit_format_multiply_extract_prefixes:nnNN + {#1} {#2} + } + } +\cs_new_protected:cpn { @@_format_extract-exponent_aux:n } #1 + { + #1 \l_@@_unit_tl \l_@@_tmp_fp + \tl_set:Nx \l_@@_tmp_tl + { \siunitx_number_adjust_exponent:Nn \l_@@_tmp_tl \l_@@_tmp_fp } + \siunitx_number_process:NN \l_@@_tmp_tl \l_@@_first_tl + \bool_set_true:N \l_@@_exp_combine_bool + } +\cs_new_protected:Npn \@@_format_input:n #1 + { + \siunitx_number_process:NN \l_@@_tmp_tl \l_@@_first_tl + \siunitx_unit_format:nN {#1} \l_@@_unit_tl + } +\cs_new_protected:Npn \@@_format_input:nn #1#2 + { + \siunitx_number_process:NN \l_@@_tmp_tl \l_@@_first_tl + \siunitx_unit_format_multiply:nnN {#1} {#2} \l_@@_unit_tl + } +\cs_new_protected:Npn \@@_extract_exp:nN #1#2 + { \@@_extract_exp:nnnnnnnN #1 #2 } +\cs_new_protected:Npn \@@_extract_exp:nnnnnnnN #1#2#3#4#5#6#7#8 + { \fp_set:Nn #8 {#6#7} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\siunitx_compound_quantity:nn} +% For quantities, life is more complex as there are interactions between the +% options for exponents and units. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_compound_quantity:nn #1#2 + { + \group_begin: + \bool_if:NT \l_@@_unit_bracket_bool + { \bool_set_true:N \l_@@_exp_bracket_bool } + \bool_if:NT \l_@@_unit_repeat_bool + { \bool_set_false:N \l_@@_exp_combine_bool } + \bool_lazy_or:nnT + { \l_@@_unit_bracket_bool } + { ! \l_@@_unit_repeat_bool } + { \bool_set_false:N \l_siunitx_number_bracket_ambiguous_bool } + \@@_format:nn {#1} {#2} + \str_if_eq:VnT \l_siunitx_quantity_prefix_mode_tl { combine-exponent } + { \tl_clear:N \l_@@_exp_tl } + \bool_if:NTF \l_@@_unit_repeat_bool + { \@@_print:N \@@_print_quantity:n } + { + \bool_lazy_and:nnTF + { \l_@@_unit_bracket_bool } + { \tl_if_empty_p:N \l_@@_exp_tl } + { + \siunitx_print_number:V \l_@@_bracket_open_tl + \@@_print:N \siunitx_print_number:x + \siunitx_print_number:V \l_@@_bracket_close_tl + } + { \@@_print:N \siunitx_print_number:x } + \@@_print_quantity:n { } + } + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_print:N} +% \begin{macro}{\@@_print:nnN, \@@_print:xxN} +% \begin{macro}{\@@_print:nnnN} +% \begin{macro}{\@@_print_aux:n} +% \begin{macro}{\@@_print_aux:nn} +% We now need to know how many entries there are: the reason we don't use +% \cs{seq_use:Nnnn} is that we want to be able to insert +% \cs{siunitx_print_\dots:n} in a controlled way. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print:N #1 + { + \bool_lazy_and:nnTF + { \l_@@_exp_bracket_bool } + { ! \tl_if_empty_p:N \l_@@_exp_tl } + { + \@@_print:xxN + { \exp_not:V \l_@@_bracket_open_tl } + { + \exp_not:V \l_@@_bracket_close_tl + \exp_not:V \l_@@_exp_tl + } + #1 + } + { \@@_print:xxN { } { \exp_not:V \l_@@_exp_tl } #1 } + } +\cs_new_protected:Npn \@@_print:nnN #1#2#3 + { + \exp_args:Nx \@@_print:nnnN + { \seq_count:N \l_@@_tmp_seq } {#1} {#2} #3 + } +\cs_generate_variant:Nn \@@_print:nnN { xx } +% \end{macrocode} +% A rather long auxiliary as we want a way to have the brackets/exponent +% available. The actual flow is simple enough: see how many entries there are +% and print as required. To keep everything generic, we have some slightly +% tricky saving of data to allow everything to go to the mapping. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print:nnnN #1#2#3#4 + { + \int_case:nnF {#1} + { + { 0 } { } + { 1 } + { + #4 + { \seq_item:Nn \l_@@_tmp_seq { 1 } } + } + { 2 } + { + #4 + { + \exp_not:n {#2} + \seq_item:Nn \l_@@_tmp_seq { 1 } + } + \@@_print_separator:V \l_@@_separator_pair_tl + #4 + { + \seq_item:Nn \l_@@_tmp_seq { 2 } + \exp_not:n {#3} + } + } + } + { + \int_set:Nn \l_@@_count_int {#1} + \tl_set:Nn \l_@@_start_tl {#2} + \tl_set:Nn \l_@@_end_tl {#3} + \cs_set_eq:NN \@@_print_aux:n #4 + \seq_map_indexed_function:NN + \l_@@_tmp_seq + \@@_print_aux:nn + } + } +\cs_new_protected:Npn \@@_print_aux:n #1 { } +\cs_new_protected:Npn \@@_print_aux:nn #1#2 + { + \int_case:nnF {#1} + { + { 1 } + { + \@@_print_aux:n + { + \exp_not:V \l_@@_start_tl + \exp_not:n {#2} + } + \@@_print_separator:V \l_@@_separator_tl + } + { \l_@@_count_int - 1 } + { + \@@_print_aux:n { \exp_not:n {#2} } + \@@_print_separator:V \l_@@_separator_final_tl + } + { \l_@@_count_int } + { + \@@_print_aux:n + { + \exp_not:n {#2} + \exp_not:V \l_@@_end_tl + } + } + } + { + \@@_print_aux:n { \exp_not:n {#2} } + \@@_print_separator:V \l_@@_separator_tl + } + } +\cs_new_protected:Npn \@@_print_quantity:n #1 + { \siunitx_quantity_print:nV {#1} \l_@@_unit_tl } +\cs_new_protected:Npn \@@_print_separator:n #1 + { + \bool_if:NTF \l_@@_separator_text_bool + { #1 } + { \siunitx_print_number:n {#1} } + } +\cs_generate_variant:Nn \@@_print_separator:n { V } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Lists} +% +% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention): only +% internal material in this \emph{submodule} should be used directly. +% \begin{macrocode} +%<@@=siunitx_list> +% \end{macrocode} +% +% \begin{variable} +% { +% \l_siunitx_list_separator_tl , +% \l_siunitx_list_separator_final_tl , +% \l_siunitx_list_separator_pair_tl , +% \l_@@_exp_tl , +% \l_@@_units_tl +% } +% Options for products. +% \begin{macrocode} +\tl_new:N \l_@@_exp_tl +\tl_new:N \l_@@_units_tl +\keys_define:nn { siunitx } + { + list-exponents .choices:nn = + { combine , combine-bracket , individual } + { \tl_set_eq:NN \l_@@_exp_tl \l_keys_choice_tl } , + list-final-separator .tl_set:N = \l_siunitx_list_separator_final_tl , + list-pair-separator .tl_set:N = \l_siunitx_list_separator_pair_tl , + list-separator .tl_set:N = \l_siunitx_list_separator_tl , + list-units .choices:nn = + { bracket , repeat , single } + { \tl_set_eq:NN \l_@@_units_tl \l_keys_choice_tl } + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_number_list:nn} +% \begin{macro}{\siunitx_quantity_list:nn} +% \begin{macro}{\@@_aux:} +% Simply recover the settings and use as a list. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_number_list:nn #1 + { + \group_begin: + \@@_aux: + \siunitx_compound_number:n {#1} + \group_end: + } +\cs_new_protected:Npn \siunitx_quantity_list:nn #1#2 + { + \group_begin: + \@@_aux: + \siunitx_compound_quantity:nn {#1} {#2} + \group_end: + } +\cs_new_protected:Npn \@@_aux: + { + \keys_set:nx { siunitx } + { + compound-exponents = \l_@@_exp_tl , + compound-final-separator = + { \exp_not:V \l_siunitx_list_separator_final_tl } , + compound-pair-separator = + { \exp_not:V \l_siunitx_list_separator_pair_tl } , + compound-separator = + { \exp_not:V \l_siunitx_list_separator_tl } , + compound-separator-mode = text , + compound-units = \l_@@_units_tl + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Products} +% +% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention): only +% internal material in this \emph{submodule} should be used directly. +% \begin{macrocode} +%<@@=siunitx_product> +% \end{macrocode} +% +% \begin{variable} +% { +% \l_@@_exp_tl , +% \l_@@_phrase_bool , +% \l_@@_phrase_tl , +% \l_@@_symbol_tl , +% \l_@@_units_tl +% } +% Options for products. +% \begin{macrocode} +\tl_new:N \l_@@_exp_tl +\bool_new:N \l_@@_phrase_bool +\tl_new:N \l_@@_units_tl +\keys_define:nn { siunitx } + { + product-exponents .choices:nn = + { combine , combine-bracket , individual } + { \tl_set_eq:NN \l_@@_exp_tl \l_keys_choice_tl } , + product-mode .choice: , + product-mode / phrase .code:n = + { \bool_set_true:N \l_@@_phrase_bool } , + product-mode / symbol .code:n = + { \bool_set_false:N \l_@@_phrase_bool } , + product-phrase .tl_set:N = \l_@@_phrase_tl , + product-symbol .tl_set:N = \l_@@_symbol_tl , + product-units .choices:nn = + { bracket , bracket-power , power , repeat , single } + { \tl_set_eq:NN \l_@@_units_tl \l_keys_choice_tl } + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_number_product:n} +% \begin{macro}{\siunitx_quantity_product:nn} +% \begin{macro}{\@@_aux:} +% \begin{macro}{\@@_aux:n, \@@_aux:x} +% Simply recover the settings and use as a list. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_number_product:n #1 + { + \group_begin: + \@@_aux: + \siunitx_compound_number:n {#1} + \group_end: + } +\cs_new_protected:Npn \siunitx_quantity_product:nn #1#2 + { + \group_begin: + \@@_aux: + \siunitx_compound_quantity:nn {#1} {#2} + \group_end: + } +\cs_new_protected:Npn \@@_aux: + { + \bool_if:NTF \l_@@_phrase_bool + { \@@_aux:x { \exp_not:V \l_@@_phrase_tl } } + { \@@_aux:x { { } \exp_not:V \l_@@_symbol_tl { } } } + } +\cs_new_protected:Npn \@@_aux:n #1 + { + \keys_set:nx { siunitx } + { + compound-exponents = \l_@@_exp_tl , + compound-final-separator = { \exp_not:n {#1} } , + compound-pair-separator = { \exp_not:n {#1} } , + compound-separator = { \exp_not:n {#1} } , + compound-separator-mode = + \bool_if:NTF \l_@@_phrase_bool { text } { number } , + compound-units = \l_@@_units_tl + } + } +\cs_generate_variant:Nn \@@_aux:n { x } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Ranges} +% +% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention): only +% internal material in this \emph{submodule} should be used directly. +% \begin{macrocode} +%<@@=siunitx_range> +% \end{macrocode} +% +% \begin{variable} +% { +% \l_@@_exp_tl , +% \l_siunitx_range_phrase_tl , +% \l_@@_units_tl +% } +% Options for products. +% \begin{macrocode} +\tl_new:N \l_@@_exp_tl +\tl_new:N \l_@@_units_tl +\keys_define:nn { siunitx } + { + range-exponents .choices:nn = + { combine , combine-bracket , individual } + { \tl_set_eq:NN \l_@@_exp_tl \l_keys_choice_tl } , + range-phrase .tl_set:N = \l_siunitx_range_phrase_tl , + range-units .choices:nn = + { bracket , repeat , single } + { \tl_set_eq:NN \l_@@_units_tl \l_keys_choice_tl } + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_number_range:nn} +% \begin{macro}{\siunitx_quantity_range:nnn} +% \begin{macro}{\@@_aux:} +% Simply recover the settings and use as a list. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_number_range:nn #1#2 + { + \group_begin: + \@@_aux: + \siunitx_compound_number:n { {#1} {#2} } + \group_end: + } +\cs_new_protected:Npn \siunitx_quantity_range:nnn #1#2#3 + { + \group_begin: + \@@_aux: + \siunitx_compound_quantity:nn { {#1} {#2} } {#3} + \group_end: + } +\cs_new_protected:Npn \@@_aux: + { + \keys_set:nx { siunitx } + { + compound-exponents = \l_@@_exp_tl , + compound-pair-separator = { \exp_not:V \l_siunitx_range_phrase_tl } , + compound-separator-mode = text , + compound-units = \l_@@_units_tl + } + } +% \end{macrocode} +% \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 } + { + compound-exponents = individual , + compound-final-separator = + { + \ifmmode \ \else \space \fi + \text { and } + \ifmmode \ \else \space \fi + } , + compound-pair-separator = + { + \ifmmode \ \else \space \fi + \text { and } + \ifmmode \ \else \space \fi + } , + compound-separator = + { , \ifmmode \ \else \space \fi } , + compound-separator-mode = text , + compound-units = repeat , + list-exponents = individual , + list-final-separator = + { + \ifmmode \ \else \space \fi + \text { and } + \ifmmode \ \else \space \fi + } , + list-pair-separator = + { + \ifmmode \ \else \space \fi + \text { and } + \ifmmode \ \else \space \fi + } , + list-separator = + { , \ifmmode \ \else \space \fi } , + list-units = repeat , + product-exponents = individual , + product-mode = symbol , + product-phrase = + { + \ifmmode \ \else \space \fi + \text { by } + \ifmmode \ \else \space \fi + } , + product-symbol = \times , + product-units = repeat , + range-exponents = individual , + range-phrase = + { + \ifmmode \ \else \space \fi + \text { to } + \ifmmode \ \else \space \fi + } , + range-units = repeat + } +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-emulation.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-emulation.dtx new file mode 100644 index 00000000000..40f145a6c68 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-emulation.dtx @@ -0,0 +1,978 @@ +% \iffalse meta-comment +% +% File: siunitx-emulation.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} +% 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-emulation} -- Emulation^^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} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-emulation} implementation} +% +% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention). In contrast +% to other parts of the bundle, the functions here may need to redefine those +% from various submodules. +% \begin{macrocode} +%<@@=siunitx> +% \end{macrocode} +% +% Start the \pkg{DocStrip} guards. +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \begin{macrocode} +%<*options> +% \end{macrocode} +% +% Some messages. +% \begin{macrocode} +\msg_new:nnn { siunitx } { option-deprecated } + { + Option~"#1"~has~been~deprecated~in~this~release.\\ \\ + Use~"#2"~as~a~replacement. + } +\msg_new:nnn { siunitx } { option-removed } + { Option~"#1"~has~been~removed~in~this~release. } +% \end{macrocode} +% +% \begin{macro}{\@@_option_deprecated:nn} +% \begin{macro}{\@@_option_deprecated:nnn, \@@_option_deprecated:nnV} +% Abstract out a simple wrapper. +% \begin{macrocode} +\cs_new_protected:Npn \@@_option_deprecated:nn #1#2 + { + \msg_info:nnnn { siunitx } { option-deprecated } {#1} {#2} + \keys_set:nn { siunitx } {#2} + } +\cs_new_protected:Npn \@@_option_deprecated:nnn #1#2#3 + { + \msg_info:nnnn { siunitx } { option-deprecated } {#1} {#2} + \keys_set:nn { siunitx } { #2 = #3 } + } +\cs_generate_variant:Nn \@@_option_deprecated:nnn { nnV } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_option_removed:n, \@@_option_removed:V} +% Abstract out a simple wrapper. +% \begin{macrocode} +\cs_new_protected:Npn \@@_option_removed:n #1 + { + \msg_warning:nnx { siunitx } { option-removed } + {#1} + } +\cs_generate_variant:Nn \@@_option_removed:n { V } +% \end{macrocode} +% \end{macro} +% +% \subsection{Load-time option} +% +% \begin{macrocode} +\clist_map_inline:nn { abbreviations , binary-units , version-1-compatibility } + { + \keys_define:nn { siunitx } { #1 .code:n = \@@_option_removed:n {#1} } + } +% \end{macrocode} +% +% \subsection{Angle options} +% +% All straight-forward emulation. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + add-arc-degree-zero .code:n = + { + \@@_option_deprecated:nnV + { add-arc-degree-zero } + { fill-angle-degrees } + \l_keys_value_tl + } , + add-arc-degree-zero .default:n = true , + add-arc-minute-zero .code:n = + { + \@@_option_deprecated:nnV + { add-arc-minute-zero } + { fill-angle-minutes } + \l_keys_value_tl + } , + add-arc-minute-zero .default:n = true , + add-arc-second-zero .code:n = + { + \@@_option_deprecated:nnV + { add-arc-second-zero } + { fill-angle-seconds } + \l_keys_value_tl + } , + add-arc-second-zero .default:n = true , + arc-separator .code:n = + { + \@@_option_deprecated:nnV + { arc-separator } + { angle-separator } + \l_keys_value_tl + } + } +% \end{macrocode} +% +% \subsection{Combination functions options} +% +% \begin{macrocode} +\keys_define:nn { siunitx } + { + list-units / brackets .code:n = + { + \@@_option_deprecated:nn + { list-units~=~brackets } + { list-units~=~bracket } + } , + range-units / brackets .code:n = + { + \@@_option_deprecated:nn + { range-units~=~brackets } + { range-units~=~bracket } + } , + product-units / brackets .code:n = + { + \@@_option_deprecated:nn + { product-units~=~brackets } + { product-units~=~bracket } + } + } +% \end{macrocode} +% +% \subsection{Command options} +% +% \begin{macrocode} +\keys_define:nn { siunitx } + { + overwrite-functions .code:n = + { + \@@_option_deprecated:nnV + { overwrite-functions } + { overwrite-commands } + \l_keys_value_tl + } , + overwrite-functions .default:n = true + } +% \end{macrocode} +% +% \subsection{Print options} +% +% \begin{macrocode} +\keys_define:nn { siunitx } + { + detect-all .code:n = + { + \@@_option_deprecated:nn + { detect-all } + { + mode~=~match , ~ + propagate-math-font~=~true , ~ + reset-math-version~=~false , ~ + reset-text-family~=~false , ~ + reset-text-series~=~false , ~ + text-family-to-math~=~true , ~ + text-series-to-math~=~true + } + } , + detect-family .code:n = + { + \@@_option_deprecated:nn + { detect-family } + { + reset-text-family~=~false , ~ + text-family-to-math~=~true + } + } , + detect-mode .code:n = + { + \@@_option_deprecated:nn + { detect-mode } + { mode~=~match } + } , + detect-none .code:n = + { + \@@_option_deprecated:nn + { detect-none } + { + mode~=~math , ~ + propagate-math-font~=~false , ~ + reset-math-version~=~true , ~ + reset-text-family~=~true , ~ + reset-text-series~=~true , ~ + text-family-to-math~=~false , ~ + text-series-to-math~=~false + } + } , + detect-shape .code:n = + { + \@@_option_deprecated:nn + { detect-shape } + { reset-text-shape~=~false } + } , + detect-weight .code:n = + { + \@@_option_deprecated:nn + { detect-weight } + { + reset-text-series~=~false , ~ + text-series-to-math~=~true + } + } + } +\clist_map_inline:nn + { + detect-display-math , + detect-inline-family , + detect-inline-weight + } + { + \keys_define:nn { siunitx } { #1 .code:n = \@@_option_removed:n {#1} } + } +% \end{macrocode} +% +% The old font insertion options. +% \begin{macrocode} +\clist_map_inline:nn + { + math-rm , + math-sf , + math-tt , + number-math-rm , + number-math-sf , + number-math-tt , + number-text-rm , + number-text-sf , + number-text-tt , + text-rm , + text-sf , + text-tt , + unit-math-rm , + unit-math-sf , + unit-math-tt , + unit-text-rm , + unit-text-sf , + unit-text-tt + } + { + \keys_define:nn { siunitx } { #1 .code:n = \@@_option_removed:n {#1} } + } +% \end{macrocode} +% +% \subsection{Symbol options} +% +% \begin{macrocode} +\clist_map_inline:nn + { + math-angstrom , + math-arcminute , + math-arcsecond , + math-celsius , + math-degree , + math-micro , + math-ohm , + text-angstrom , + text-arcminute , + text-arcsecond , + text-celsius , + text-degree , + text-micro , + text-ohm , + } + { + \keys_define:nn { siunitx } { #1 .code:n = \@@_option_removed:n {#1} } + } +% \end{macrocode} +% +% \subsection{Number options} +% +% \begin{macrocode} +\keys_define:nn { siunitx } + { + separate-uncertainty .choice: , + separate-uncertainty / false .code:n = + { + \@@_option_deprecated:nn + { separate-uncertainty } + { uncertainty-mode~=~compact } + } , + separate-uncertainty / true .code:n = + { + \@@_option_deprecated:nn + { separate-uncertainty } + { uncertainty-mode~=~separate } + } , + separate-uncertainty .default:n = true + } +% \end{macrocode} +% +% A small number of removed options. +% \begin{macrocode} +\clist_map_inline:nn + { + input-protect-tokens , + input-quotient , + quotient-mode + } + { + \keys_define:nn { siunitx } { #1 .code:n = \@@_option_removed:n {#1} } + } +% \end{macrocode} +% +% Options for number processing: largely removals. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + add-decimal-zero .choice: , + add-decimal-zero / false .code:n = + { + \@@_option_deprecated:nn + { add-decimal-zero } + { minimum-decimal-digits~=~0 } + } , + add-decimal-zero / true .code:n = + { + \@@_option_deprecated:nn + { add-decimal-zero } + { minimum-decimal-digits~=~1 } + } , + add-decimal-zero .default:n = true , + add-integer-zero .code:n = + { \@@_option_removed:V \l_keys_key_tl } , + close-bracket .code:n = + { \@@_option_removed:V \l_keys_key_tl } , + bracket-numbers .choice: , + bracket-numbers / false .code:n = + { + \@@_option_deprecated:nn + { bracket-numbers } + { bracket-ambiguous-numbers~=~false } + } , + bracket-numbers / true .code:n = + { + \@@_option_deprecated:nn + { bracket-numbers } + { bracket-ambiguous-numbers~=~true } + } , + bracket-numbers .default:n = true , + explicit-sign .code:n = + { + \str_if_eq:nnTF {#1} { + } + { + \@@_option_deprecated:nn + { explicit-sign } + { print-implicit-plus~=~true } + } + { \@@_option_removed:V \l_keys_key_tl } + } , + omit-uncertainty .code:n = + { + \@@_option_deprecated:nnV + { omit-uncertainty } + { drop-uncertainty } + \l_keys_value_tl + } , + omit-uncertainty .default:n = true , + open-bracket .code:n = + { \@@_option_removed:V \l_keys_key_tl } , + retain-unity-mantissa .code:n = + { + \@@_option_deprecated:nnV + { retain-unity-mantissa } + { print-unity-mantissa } + \l_keys_value_tl + } , + retain-unity-mantisa .default:n = true , + retain-zero-exponent .code:n = + { + \@@_option_deprecated:nnV + { retain-zero-exponent } + { print-zero-exponent } + \l_keys_value_tl + } , + retain-zero-exponent .default:n = true , + round-integer-to-decimal .code:n = + { \@@_option_removed:V \l_keys_key_tl } , + scientific-notation .choice: , + scientific-notation / engineering .code:n = + { + \@@_option_deprecated:nn + { scientific-notation~=~engineering } + { exponent-mode~=~engineering } + } , + scientific-notation / fixed .code:n = + { + \@@_option_deprecated:nn + { scientific-notation~=~fixed } + { exponent-mode~=~fixed } + } , + scientific-notation / false .code:n = + { + \@@_option_deprecated:nn + { scientific-notation~=~false } + { exponent-mode~=~input } + } , + scientific-notation / true .code:n = + { + \@@_option_deprecated:nn + { scientific-notation~=~true } + { exponent-mode~=~scientific } + } , + scientific-notation .default:n = true , + zero-decimal-to-integer .code:n = + { + \@@_option_deprecated:nnV + { zero-decimal-to-integer } + { drop-zero-decimal } + \l_keys_value_tl + } , + zero-decimal-to-integer .default:n = true + } +% \end{macrocode} +% +% \subsubsection{Table options} +% +% All straight-forward emulation. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + table-align-text-post .code:n = + { + \@@_option_deprecated:nnV + { table-align-text-post } + { table-align-text-after } + \l_keys_value_tl + } , + table-align-text-post .default:n = true , + table-align-text-pre .code:n = + { + \@@_option_deprecated:nnV + { table-align-text-pre } + { table-align-text-before } + \l_keys_value_tl + } , + table-align-text-pre .default:n = true , + table-number-alignment / center-decimal-marker .code:n = + { + \msg_info:nnnn { siunitx } { option-deprecated } + { table-number-alignment~=~center-decimal-marker } + { table-alignment-mode~=~marker } + \keys_set:nn + { siunitx } + { table-alignment-mode = marker } + } , + table-omit-exponent .code:n = + { + \@@_option_deprecated:nnV + { table-omit-exponent } + { drop-exponent } + \l_keys_value_tl + } , + table-omit-exponent .default:n = true , + table-parse-only .code:n = + { + \msg_info:nnnn { siunitx } { option-deprecated } + { table-parse-only } + { table-alignment-mode~=~none } + \str_if_eq:VnTF \l_keys_value_tl { false } + { + \keys_set:nn + { siunitx } + { table-alignment-mode = marker } + } + { + \keys_set:nn + { siunitx } + { table-alignment-mode = none } + } + } , + table-space-text-post .code:n = + { + \msg_info:nnnn { siunitx } { option-deprecated } + { table-space-text-post } + { table-format } + \tl_set:Nn \l_@@_table_after_model_tl {#1} + } , + table-space-text-pre .code:n = + { + \msg_info:nnnn { siunitx } { option-deprecated } + { table-space-text-post } + { table-format } + \tl_set:Nn \l_@@_table_before_model_tl {#1} + } + } +% \end{macrocode} +% +% \begin{macro}{\@@_option_table_format:n} +% \begin{macro} +% { +% \@@_option_table_comparator:nnnnnnn , +% \@@_option_table_figures-decimal:nnnnnnnn , +% \@@_option_table_figures-exponent:nnnnnnnn , +% \@@_option_table_figures-integer:nnnnnnnn , +% \@@_option_table_figures-uncertainty:nnnnnnnn , +% \@@_option_table_sign-exponent:nnnnnnnn , +% \@@_option_table_sign-mantissa:nnnnnnnn +% } +% \begin{macrocode} +\cs_new_protected:Npn \@@_option_table_format:n #1 + { + \msg_info:nnnn { siunitx } { option-deprecated } + { table- #1 } + { table-format } + \tl_set:Nx \l_@@_table_format_tl + { + \cs:w @@_option_table_ #1 :nnnnnnnn + \exp_after:wN \exp_after:wN \exp_after:wN \cs_end: + \exp_after:wN \l_@@_table_format_tl + \exp_after:wN { \l_keys_value_tl } + } + \exp_after:wN \@@_table_generate_model:nnnnnnn + \l_@@_table_format_tl + } +\cs_new:Npn \@@_option_table_comparator:nnnnnnnn #1#2#3#4#5#6#7#8 + { \exp_not:n { {#8} {#2} {#3} {#4} {#5} {#6} {#7} } } +\cs_new:cpn { @@_option_table_figures-decimal:nnnnnnnn } + #1#2#3#4#5#6#7#8 + { \exp_not:n { {#1} {#2} {#3} {#8} {#5} {#6} {#7} } } +\cs_new:cpn { @@_option_table_figures-exponent:nnnnnnnn } + #1#2#3#4#5#6#7#8 + { \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#8} } } +\cs_new:cpn { @@_option_table_figures-integer:nnnnnnnn } + #1#2#3#4#5#6#7#8 + { \exp_not:n { {#1} {#2} {#8} {#4} {#5} {#6} {#7} } } +\cs_new:cpn { @@_option_table_figures-uncertainty:nnnnnnnn } + #1#2#3#4#5#6#7#8 + { \exp_not:n { {#1} {#2} {#3} {#4} { { S } {#8} } {#6} {#7} } } +\cs_new:cpn { @@_option_table_sign-exponent:nnnnnnnn } + #1#2#3#4#5#6#7#8 + { \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#8} {#7} } } +\cs_new:cpn { @@_option_table_sign-mantissa:nnnnnnnn } + #1#2#3#4#5#6#7#8 + { \exp_not:n { {#1} {#8} {#3} {#4} {#5} {#6} {#7} } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% Options which all use the same emulation set up. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + table-comparator .code:n = + { \@@_option_table_format:n { comparator } } , + table-figures-decimal .code:n = + { \@@_option_table_format:n { figures-decimal } } , + table-figures-exponent .code:n = + { \@@_option_table_format:n { figures-exponent } } , + table-figures-integer .code:n = + { \@@_option_table_format:n { figures-integer } } , + table-figures-uncertainty .code:n = + { \@@_option_table_format:n { figures-uncertainty } } , + table-sign-exponent .code:n = + { \@@_option_table_format:n { sign-exponent } } , + table-sign-mantissa .code:n = + { \@@_option_table_format:n { sign-mantissa } } + } +% \end{macrocode} +% +% \subsection{Unit options} +% +% \begin{macrocode} +\keys_define:nn { siunitx } + { + fraction-function .code:n = + { + \@@_option_deprecated:nnV + { fraction-function } + { fraction-command } + \l_keys_value_tl + } , + literal-superscript-as-power .code:n = + { \@@_option_removed:V \l_keys_key_tl } , + per-mode / reciprocal .code:n = + { + \@@_option_deprecated:nn + { per-mode~=~reciprocal } + { per-mode~=~power } + } , + per-mode / reciprocal-positive-first .code:n = + { + \@@_option_deprecated:nn + { per-mode~=~reciprocal-positive-first } + { per-mode~=~power-positive-first } + } , + power-font .code:n = + { \@@_option_removed:V \l_keys_key_tl } , + qualifier-mode / brackets .code:n = + { + \@@_option_deprecated:nn + { qualifier-mode~=~brackets } + { qualifier-mode~=~bracket } + } , + qualifier-mode / space .code:n = + { + \msg_info:nnnn { siunitx } { option-deprecated } + { qualifier-mode~=~space } + { qualifier-mode~=~phrase"~plus~"qualifier-phrase=\ } + \keys_set:nn + { siunitx } + { qualifier-mode = phrase, qualifier-phrase = \ } + } , + qualifier-mode / text .code:n = + { + \@@_option_deprecated:nn + { qualifier-mode~=~text } + { qualifier-mode~=~combine } + } + } +% \end{macrocode} +% +% \subsection{Quantity units} +% +% \begin{macrocode} +\keys_define:nn { siunitx } + { + allow-number-unit-breaks .code:n = + { + \@@_option_deprecated:nnV + { allow-number-unit-breaks } + { allow-quantity-breaks } + \l_keys_value_tl + } , + allow-number-unit-breaks .default:n = true , + exponent-to-prefix .choice: , + exponent-to-prefix / false .code:n = + { + \@@_option_deprecated:nn + { exponent-to-prefix~=~false } + { prefix-mode~=~input } + } , + exponent-to-prefix / true .code:n = + { + \@@_option_deprecated:nn + { exponent-to-prefix~=~true } + { prefix-mode~=~combine-exponent } + } , + exponent-to-prefix .default:n = true , + multi-part-units .choice: , + multi-part-units / brackets . code:n = + { + \@@_option_deprecated:nn + { multi-part-units~=~brackets } + { separate-uncertainty-units~=~bracket } + } , + multi-part-units / repeat . code:n = + { + \@@_option_deprecated:nn + { multi-part-units~=~repeat } + { separate-uncertainty-units~=~repeat } + } , + multi-part-units / single . code:n = + { + \@@_option_deprecated:nn + { multi-part-units~=~single } + { separate-uncertainty-units~=~single } + } , + number-unit-product .code:n = + { + \@@_option_deprecated:nnV + { number-unit-product } + { quantity-product } + \l_keys_value_tl + } , + prefixes-as-symbols .choice: , + prefixes-as-symbols / false . code:n = + { + \@@_option_deprecated:nn + { prefixes-as-symbols~=~false } + { prefix-mode~=~extract-exponent } + } , + prefixes-as-symbols / true . code:n = + { + \@@_option_deprecated:nn + { prefixes-as-symbols~=~true } + { prefix-mode~=~input } + } , + prefixes-as-symbols .default:n = true + } +% \end{macrocode} +% +% \begin{macrocode} +%</options> +% \end{macrocode} +% +% \subsection{Preamble commands} +% +% \begin{macrocode} +%<*interfaces> +% \end{macrocode} +% +% \begin{macro}{\DeclareBinaryPrefix} +% We simply drop |#3|. +% \begin{macrocode} +\NewDocumentCommand \DeclareBinaryPrefix { +m m m } + { + \siunitx_declare_prefix:Nn #1 {#2} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareSIPrePower, \DeclareSIPostPower} +% Simply use a throw-away command for the part we do not need: this can +% be followed by some clean-up. +% \begin{macrocode} +\NewDocumentCommand \DeclareSIPrePower { +m m } + { + \siunitx_declare_power:NNn #1 \@@_tmp:w {#2} + \seq_remove_all:Nn \l_siunitx_unit_symbolic_seq { \@@_tmp:w } + } +\NewDocumentCommand \DeclareSIPostPower { +m m } + { + \siunitx_declare_power:NNn \@@_tmp:w #1 {#2} + \seq_remove_all:Nn \l_siunitx_unit_symbolic_seq { \@@_tmp:w } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Document commands} +% +% \begin{macro}{\si} +% A straight copy of \cs{unit}. +% \begin{macrocode} +\NewDocumentCommand \si { O { } m } + { + \mode_leave_vertical: + \group_begin: + \keys_set:nn { siunitx } {#1} + \siunitx_unit_format:nN {#2} \l_@@_tmp_tl + \siunitx_print_unit:V \l_@@_tmp_tl + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\SI} +% Almost the same as \cs{qty}, but with the addition pre-unit. +% \begin{macrocode} +\NewDocumentCommand \SI { O { } m o m } + { + \mode_leave_vertical: + \group_begin: + \keys_set:nn { siunitx } {#1} + \IfNoValueF {#3} + { + \siunitx_unit_format:nN {#3} \l_@@_tmp_tl + \siunitx_print_unit:V \l_@@_tmp_tl + \nobreak + } + \siunitx_quantity:nn {#2} {#4} + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\SIlist, \SIrange} +% Straight copies. +% \begin{macrocode} +\NewDocumentCommand \SIlist + { O { } > { \SplitList { ; } } m > { \TrimSpaces } m } + { + \mode_leave_vertical: + \group_begin: + \siunitx_unit_options_apply:n {#3} + \keys_set:nn { siunitx } {#1} + \siunitx_quantity_list:nn {#2} {#3} + \group_end: + } +\NewDocumentCommand \SIrange { O { } m m > { \TrimSpaces } m } + { + \mode_leave_vertical: + \group_begin: + \siunitx_unit_options_apply:n {#4} + \keys_set:nn { siunitx } {#1} + \siunitx_quantity_range:nnn {#2} {#3} {#4} + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Symbol commands} +% +% \begin{macrocode} +%<@@=siunitx_emulation> +% \end{macrocode} +% +% \begin{macro}{\@@_non_latin:n} +% \begin{macro}{\@@_non_latin:nnnn} +% As in \pkg{siunitx-unit}, but internal in both cases as it's rather +% specialised. +% \begin{macrocode} +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_non_latin:n #1 + { \char_generate:nn {#1} { \char_value_catcode:n {#1} } } + } + { + \cs_new:Npn \@@_non_latin:n #1 + { + \exp_last_unbraced:Nf \@@_non_latin:nnnn + { \char_to_utfviii_bytes:n {#1} } + } + \cs_new:Npn \@@_non_latin:nnnn #1#2#3#4 + { + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#1} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#2} { 13 } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% { +% \SIUnitSymbolAngstrom , +% \SIUnitSymbolArcminute , +% \SIUnitSymbolArcsecond , +% \SIUnitSymbolCelsius , +% \SIUnitSymbolDegree , +% \SIUnitSymbolMicro , +% \SIUnitSymbolOhm +% } +% The same setup as elsewhere but localised to the emulation module +% \begin{macrocode} +\AtBeginDocument + { + \cs_new_protected:Npn \SIUnitSymbolArcminute + { \ensuremath { { } ' } } + \cs_new_protected:Npn \SIUnitSymbolArcsecond + { \ensuremath { { } '' } } + \@ifpackageloaded { fontspec } + { + \cs_new_protected:Npx \SIUnitSymbolAngstrom + { \@@_non_latin:n { "00C5 } } + \cs_new_protected:Npx \SIUnitSymbolDegree + { \@@_non_latin:n { "00B0 } } + \cs_new_protected:Npx \SIUnitSymbolCelsius + { \@@_non_latin:n { "00B0 } C } + } + { + \cs_new_protected:Npx \SIUnitSymbolAngstrom + { + \siunitx_print_text:n + { \@@_non_latin:n { "00C5 } } + } + \cs_new_protected:Npx \SIUnitSymbolCelsius + { + \siunitx_print_text:n + { \@@_non_latin:n { "00B0 } } C + } + \cs_new_protected:Npx \SIUnitSymbolDegree + { + \siunitx_print_text:n + { \@@_non_latin:n { "00B0 } } + } + } + \cs_new_protected:Npx \SIUnitSymbolMicro + { + \siunitx_print_text:n + { + \bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { \@@_non_latin:n { "00B5 } } + { \exp_not:N \textmu } + } + } + \cs_new_protected:Npx \SIUnitSymbolOhm + { + \exp_not:N \ifmmode + \cs_if_exist:NTF \upOmega + { \exp_not:N \upOmega } + { \exp_not:N \Omega } + \exp_not:N \else + \siunitx_print_text:n + { + \bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { \@@_non_latin:n { "03A9 } } + { \exp_not:N \textohm } + } + \exp_not:N \fi + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</interfaces> +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-locale.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-locale.dtx new file mode 100644 index 00000000000..07a934b2fe7 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-locale.dtx @@ -0,0 +1,169 @@ +% \iffalse meta-comment +% +% File: siunitx-locale.dtx Copyright (C) 2020,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} +% 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-locale} -- Localisation^^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 concerned with localisation of \pkg{siunitx} output +% based on the locale. If the \pkg{translations} package is available, this +% is loaded here and used to provide various fixed strings for output. +% +% \begin{function}{locale} +% \begin{syntax} +% |locale| = \meta{locale} +% \end{syntax} +% Selects the \meta{locale} used to apply standard settings for other +% keys, principally |exponent-product|, |inter-unit-product| +% and |output-decimal-marker|. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-locale} 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_locale> +% \end{macrocode} +% +% \subsection{Locales} +% +% The basics for defining locales are easy: these are just meta keys. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + locale .choice: , + locale / DE .meta:n = + { + exponent-product = \cdot , + inter-unit-product = \, , + output-decimal-marker = { , } + } , + locale / FR .meta:n = + { + exponent-product = \times , + inter-unit-product = \, , + output-decimal-marker = { , } + } , + locale / UK .meta:n = + { + exponent-product = \times , + inter-unit-product = \, , + output-decimal-marker = . + }, + locale / US .meta:n = + { + exponent-product = \times , + inter-unit-product = \, , + output-decimal-marker = . + } , + locale / ZA .meta:n = + { + exponent-product = \times , + inter-unit-product = \cdot , + output-decimal-marker = { , } + } + } +% \end{macrocode} +% +% \subsection{Localisation} +% +% Localisation makes use of the \pkg{translator} package. This only happens +% if it is available, and is transparent to the user. +% \begin{macrocode} +\file_if_exist:nT { translations.sty } + { + \RequirePackage { translations } + \DeclareTranslation { English } { to~(numerical~range) } { to } + \DeclareTranslation { French } { to~(numerical~range) } { á } + \DeclareTranslation { German } { to~(numerical~range) } { bis } + \DeclareTranslation { Spanish } { to~(numerical~range) } { a } + \keys_set:nn { siunitx } + { + list-final-separator = + { + \ifmmode \ \else \space \fi + \text { \GetTranslation { and } } + \ifmmode \ \else \space \fi + } , + list-pair-separator = + { + \ifmmode \ \else \space \fi + \text { \GetTranslation { and } } + \ifmmode \ \else \space \fi + } , + range-phrase = + { + \ifmmode \ \else \space \fi + \text { \GetTranslation { to~(numerical~range) } } + \ifmmode \ \else \space \fi + } + } + } +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx new file mode 100644 index 00000000000..adc798fb2ca --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx @@ -0,0 +1,3549 @@ +% \iffalse meta-comment +% +% File: siunitx-number.dtx Copyright (C) 2014-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-number} -- Parsing and formatting numbers^^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{Formatting numbers} +% +% \begin{function}{\siunitx_number_parse:nN, \siunitx_number_parse:VN} +% \begin{syntax} +% \cs{siunitx_number_parse:nN} \Arg{number} \meta{tl~var} +% \end{syntax} +% Parses the \emph{number} and stores the resulting internal representation +% in the \meta{tl~var}. The parsing is influenced by the various key--value +% settings for numerical input. The \meta{number} should comprise a single +% real value, possibly with comparator, uncertainty and exponent parts. +% If the number is invalid, or if number parsing is disabled, the result will +% be an entirely empty \meta{tl~var}. +% +% The structure of a valid number is: +% \begin{quote} +% \marg{comparator}\marg{sign}\marg{integer}\marg{decimal} +% \marg{uncertainty}\\ +% \marg{exponent sign}\marg{exponent} +% \end{quote} +% where the two sign parts must be single tokens if present, +% and all other components +% must be given in braces. The number will have at least one digit for both the +% \meta{integer} and \meta{exponent} parts: these are required. The +% \meta{uncertainty} part should either be blank or contain an +% \meta{identifier} (as a brace group), followed by one or more data entries. +% Valid \meta{identifiers} currently are +% \begin{itemize} +% \item[\texttt{S}] A single symmetrical uncertainty (\foreign{e.g.}~a +% statistical standard uncertainty) +% \end{itemize} +% \end{function} +% +% \begin{function}{\siunitx_number_process:NN} +% \begin{syntax} +% \cs{siunitx_number_process:N} \meta{tl~var1} \meta{tl~var2} +% \end{syntax} +% Applies a set of number processing operations to the \meta{internal +% number} stored in the \meta{tl~var1}, \foreign{viz.}~in order +% \begin{enumerate} +% \item Dropping uncertainty +% \item Converting to scientific mode (or similar) +% \item Rounding +% \item Dropping zero decimal part +% \item Forcing a minimum number of digits +% \end{enumerate} +% with the result stored in \meta{tl~var2}. +% \end{function} +% +% \begin{function}[rEXP] +% { +% \siunitx_number_output:N, \siunitx_number_output:n, +% \siunitx_number_output:NN, \siunitx_number_output:nN +% } +% \begin{syntax} +% \cs{siunitx_number_output:N} \meta{number} +% \cs{siunitx_number_output:NN} \meta{number} \meta{marker} +% \end{syntax} +% Formats the \meta{number} (in the \pkg{siunitx} internal format), +% producing the result in a form suitable for typesetting in math mode. +% The details for the formatting are controlled by a number of key--value +% options. Note that \emph{formatting} does not apply any manipulation +% (processing) to the number. This function is usable in an \texttt{e}- +% or \texttt{x}-type expansion, and further uncontrolled expansion is +% prevented by appropriate use of |\exp_not:n| internally. +% +% In the \texttt{NN} version, the \meta{marker} token is inserted at each +% possible alignment position in the output, \foreign{viz.} +% \begin{itemize} +% \item Between the comparator and the integer (\emph{before} any +% sign for the integer) +% \item Between the sign and the first digit of the integer +% \item Both sides of the decimal marker +% \item Both sides of the separated uncertainty sign (\foreign{i.e.}~after +% the decimal part and before any integer uncertainty part) +% \item Both sides of the decimal marker for a separated uncertainty +% \item Both sides of the multiplication symbol for the exponent part. +% \end{itemize} +% +% The \texttt{n} and \texttt{nN} version take a token list, which should +% be in the internal \pkg{siunitx} format. +% \end{function} +% +% \begin{function}{\siunitx_number_format:nN} +% \begin{syntax} +% \cs{siunitx_number_format:nN} \Arg{number} \meta{tl~var} +% \end{syntax} +% Carries out a combination of \cs{siunitx_number_parse:nN}, +% \cs{siunitx_number_process:NN} and \cs{siunitx_number_output:N} using +% \texttt{x}-type expansion to place the result in the \meta{tl~var}. If +% \cs{l_siunitx_number_parse_bool} if \texttt{false}, the input is simply +% stored inside the \meta{tl~var} inside \cs{ensuremath}. +% \end{function} +% +% \begin{function}[EXP] +% { +% \siunitx_number_adjust_exponent:Nn , +% \siunitx_number_adjust_exponent:nn +% } +% \begin{syntax} +% \cs{siunitx_number_adjust_exponent:Nn} \meta{number} \Arg{fp~expr} +% \end{syntax} +% Adjusts the exponent of the \meta{number} (in internal format) by the +% \meta{fp~expr} and leaves the result in the input stream. +% \end{function} +% +% \begin{function}{\siunitx_number_normalize_symbols:N} +% \begin{syntax} +% \cs{siunitx_number_normalize_symbols:N} \meta{tl~var} +% \end{syntax} +% Replaces all multi-token signs and comparators in the \meta{tl~var} +% with their single-token equivalents. Replaces any active hyphen tokens +% with non-active versions. +% \end{function} +% +% \begin{function}[pTF, EXP]{\siunitx_if_number:n} +% \begin{syntax} +% \cs{siunitx_if_number_token:NTF} \Arg{tokens} +% \Arg{true code} \Arg{false code} +% \end{syntax} +% Determines if the \meta{tokens} form a valid number which can be fully +% parsed by \pkg{siunitx}. +% \end{function} +% +% \begin{function}[TF]{\siunitx_if_number_token:N} +% \begin{syntax} +% \cs{siunitx_if_number_token:NTF} \Arg{token} +% \Arg{true code} \Arg{false code} +% \end{syntax} +% Determines if the \meta{token} is valid in a number based on those +% tokens currently set up for detection in a number. +% \end{function} +% +% \begin{variable}{\l_siunitx_bracket_ambiguous_bool} +% A switch to control whether ambiguous numbers are bracketed: this can +% also be covered in quantity formatting by a setting there. +% \end{variable} +% +% \begin{variable}{\l_siunitx_number_parse_bool} +% A switch to control whether any parsing is attempted for numbers. +% \end{variable} +% +% \begin{variable} +% { +% \l_siunitx_number_comparator_tl , +% \l_siunitx_number_exponent_tl , +% \l_siunitx_number_sign_tl +% } +% The list of possible input comparators, exponent markers and signs. +% \end{variable} +% +% \begin{variable} +% {\l_siunitx_number_input_decimal_tl, \l_siunitx_number_output_decimal_tl} +% The list of possible input decimal marker(s), and the output marker. +% \end{variable} +% +% \subsection{Key--value options} +% +% The options defined by this submodule are available within the \pkg{l3keys} +% |siunitx| tree. +% +% \begin{function}{bracket-ambiguous-numbers} +% \begin{syntax} +% |bracket-ambiguous-numbers| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{bracket-negative-numbers} +% \begin{syntax} +% |bracket-negative-numbers| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{drop-exponent} +% \begin{syntax} +% |drop-exponent| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{drop-uncertainty} +% \begin{syntax} +% |drop-uncertainty| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{drop-zero-decimal} +% \begin{syntax} +% |drop-zero-decimal| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{evaluate-expression} +% \begin{syntax} +% |evaluate-expression| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{exponent-base} +% \begin{syntax} +% |exponent-base| = \meta{base} +% \end{syntax} +% \end{function} +% +% \begin{function}{exponent-mode} +% \begin{syntax} +% |exponent-mode| = |engineering|\verb"|"|fixed|\verb"|"|input|\verb"|"|scientific| +% \end{syntax} +% \end{function} +% +% \begin{function}{exponent-product} +% \begin{syntax} +% |exponent-product| = \meta{symbol} +% \end{syntax} +% \end{function} +% +% \begin{function}{expression} +% \begin{syntax} +% |expression| = \meta{expression} +% \end{syntax} +% \end{function} +% +% \begin{function}{fixed-exponent} +% \begin{syntax} +% |fixed-exponent| = \meta{exponent} +% \end{syntax} +% \end{function} +% +% \begin{function}{group-digits} +% \begin{syntax} +% |group-digits| = |all|\verb"|"|decimal|\verb"|"|integer|\verb"|"|none| +% \end{syntax} +% \end{function} +% +% \begin{function}{group-minimum-digits} +% \begin{syntax} +% |group-minimum-digits| = \meta{value} +% \end{syntax} +% \end{function} +% +% \begin{function}{group-separator} +% \begin{syntax} +% |group-separator| = \meta{symbol} +% \end{syntax} +% \end{function} +% +% \begin{function}{input-close-uncertainty} +% \begin{syntax} +% |input-close-uncertainty| = \meta{tokens} +% \end{syntax} +% \end{function} +% +% \begin{function}{input-comparators} +% \begin{syntax} +% |input-comparators| = \meta{tokens} +% \end{syntax} +% \end{function} +% +% \begin{function}{input-close-uncertainty} +% \begin{syntax} +% |input-close-uncertainty| = \meta{tokens} +% \end{syntax} +% \end{function} +% +% \begin{function}{input-decimal-markers} +% \begin{syntax} +% |input-decimal-markers| = \meta{tokens} +% \end{syntax} +% \end{function} +% +% \begin{function}{input-digits} +% \begin{syntax} +% |input-digits| = \meta{tokens} +% \end{syntax} +% \end{function} +% +% \begin{function}{input-exponent-markers} +% \begin{syntax} +% |input-exponent-markers| = \meta{tokens} +% \end{syntax} +% \end{function} +% +% \begin{function}{input-open-uncertainty} +% \begin{syntax} +% |input-open-uncertainty| = \meta{tokens} +% \end{syntax} +% \end{function} +% +% \begin{function}{input-signs} +% \begin{syntax} +% |input-signs| = \meta{tokens} +% \end{syntax} +% \end{function} +% +% \begin{function}{input-uncertainty-signs} +% \begin{syntax} +% |input-uncertainty-signs| = \meta{tokens} +% \end{syntax} +% \end{function} +% +% \begin{function}{minimum-decimal-digits} +% \begin{syntax} +% |minimum-decimal-digits| = \meta{min} +% \end{syntax} +% \end{function} +% +% \begin{function}{minimum-integer-digits} +% \begin{syntax} +% |minimum-integer-digits| = \meta{min} +% \end{syntax} +% \end{function} +% +% \begin{function}{negative-color} +% \begin{syntax} +% |negative-color| = \meta{color} +% \end{syntax} +% \end{function} +% +% \begin{function}{output-close-uncertainty} +% \begin{syntax} +% |output-close-uncertainty| = \meta{symbol} +% \end{syntax} +% \end{function} +% +% \begin{function}{output-decimal-marker} +% \begin{syntax} +% |output-decimal-marker| = \meta{symbol} +% \end{syntax} +% \end{function} +% +% \begin{function}{output-open-uncertainty} +% \begin{syntax} +% |output-open-uncertainty| = \meta{symbol} +% \end{syntax} +% \end{function} +% +% \begin{function}{parse-numbers} +% \begin{syntax} +% |parse-numbers| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{print-implicit-plus} +% \begin{syntax} +% |print-implicit-plus| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{print-unity-mantissa} +% \begin{syntax} +% |print-unity-mantissa| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{print-zero-exponent} +% \begin{syntax} +% |print-zero-exponent| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{retain-explicit-plus} +% \begin{syntax} +% |retain-explicit-plus| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{retain-zero-uncertainty} +% \begin{syntax} +% |retain-zero-uncertainty| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{round-half} +% \begin{syntax} +% |round-half| = |even|\verb"|"|up| +% \end{syntax} +% \end{function} +% +% \begin{function}{round-minimum} +% \begin{syntax} +% |round-minimum| = \meta{min} +% \end{syntax} +% \end{function} +% +% \begin{function}{round-mode} +% \begin{syntax} +% |round-mode| = |figures|\verb"|"|none|\verb"|"|places|\verb"|"|uncertainty| +% \end{syntax} +% \end{function} +% +% \begin{function}{round-pad} +% \begin{syntax} +% |round-pad| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{round-precision} +% \begin{syntax} +% |round-precision| = \meta{precision} +% \end{syntax} +% \end{function} +% +% \begin{function}{separate-uncertainty} +% \begin{syntax} +% |separate-uncertainty| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{tight-spacing} +% \begin{syntax} +% |tight-spacing| = |true|\verb"|"|false| +% \end{syntax} +% \end{function} +% +% \begin{function}{uncertainty-mode} +% \begin{syntax} +% |uncertainty-mode| = |compact|\verb"|"|compact-marker|\verb"|"|full|\verb"|"|separate| +% \end{syntax} +% \end{function} +% +% \begin{function}{uncertainty-separator} +% \begin{syntax} +% |uncertainty-separator| = \meta{separator} +% \end{syntax} +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-number} 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_number> +% \end{macrocode} +% +% \subsection{Initial set-up} +% +% Variants not provided by \pkg{expl3}. +% \begin{macrocode} +\cs_generate_variant:Nn \tl_if_blank:nTF { f } +\cs_generate_variant:Nn \tl_if_blank_p:n { f } +\cs_generate_variant:Nn \tl_if_in:NnTF { NV } +\cs_generate_variant:Nn \tl_replace_all:Nnn { NnV } +% \end{macrocode} +% +% \begin{variable}{\l_@@_tmp_tl} +% Scratch space. +% \begin{macrocode} +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{variable} +% +% \subsection{Main formatting routine} +% +% \begin{variable}{\l_@@_outputted_tl} +% A token list for the final formatted result: may or may not be generated +% by the parser, depending on settings which are active. +% \begin{macrocode} +\tl_new:N \l_@@_outputted_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_siunitx_number_parse_bool} +% Tracks whether to parse numbers: public as this may affect other +% behaviors. +% \begin{macrocode} +\tl_new:N \l_siunitx_number_parse_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_siunitx_number_parse_bool} +% Top-level options. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + parse-numbers .bool_set:N = \l_siunitx_number_parse_bool + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_number_format:nN} +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_number_format:nN #1#2 + { + \group_begin: + \bool_if:NTF \l_siunitx_number_parse_bool + { + \siunitx_number_parse:nN {#1} \l_@@_parsed_tl + \siunitx_number_process:NN \l_@@_parsed_tl \l_@@_parsed_tl + \tl_set:Nx \l_@@_outputted_tl + { \siunitx_number_output:N \l_@@_parsed_tl } + } + { \tl_set:Nn \l_@@_outputted_tl { \ensuremath {#1} } } + \exp_args:NNNV \group_end: + \tl_set:Nn #2 \l_@@_outputted_tl + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Parsing numbers} +% +% Before numbers can be manipulated or formatted they need to be parsed into +% an internal form. In particular, if multiple code paths are to be avoided, +% it is necessary to do such parsing even for relatively simple cases such +% as converting |1e10| to |1 \times 10^{10}|. +% +% Storing the result of such parsing can be done in a number of ways. In the +% first version of \pkg{siunitx} a series of separate data stores were used. +% This is potentially quite fast (as recovery of items relies only on \TeX{}'s +% hash table) but makes managing the various data entries somewhat tedious and +% error-prone. For version two of the package, a single data structure +% (property list) was used for each part of the parsed number. Whilst this is +% easy to manage and extend, it is somewhat slower as at a \TeX{} level there +% are repeated pack--unpack steps. In particular, the fact that there are a +% limited number of items to track for a \enquote{number} means that a more +% efficient approach is desirable (contrast parsing units, which is open-ended +% and therefore fits well with using a property list). +% +% In this release, the structure of a valid number is: +% \begin{quote} +% \marg{comparator}\meta{sign}\marg{integer}\marg{decimal} +% \marg{uncertainty}\\ +% \meta{exponent sign}\marg{exponent} +% \end{quote} +% where all components must be given in braces. \emph{All} of the components +% must be present in a stored number (\foreign{i.e.}~at the end of parsing). +% The number must have at least one digit for both the \meta{integer} and +% \meta{exponent} parts. +% +% A non-empty \meta{uncertainty} must contain one leading brace group +% containing an identifier, then zero or more brace groups which contain +% the uncertainty data. In this release, the known uncertainty types are +% \begin{itemize} +% \item \texttt{S}: A symmetrical statistical uncertainty made up of +% a single value. These are stored as uncertainty in significant digits, +% with no radix point in the stored value. +% \end{itemize} +% +% \begin{variable}{\l_siunitx_number_input_decimal_tl} +% The input decimal markers(s). +% \begin{macrocode} +\tl_new:N \l_siunitx_number_input_decimal_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_@@_expression_bool , +% \l_@@_input_uncert_close_tl , +% \l_siunitx_number_input_comparator_tl , +% \l_@@_input_digit_tl , +% \l_siunitx_number_input_exponent_tl , +% \l_@@_input_ignore_tl , +% \l_@@_input_uncert_open_tl , +% \l_siunitx_number_input_sign_tl , +% \l_@@_input_uncert_sign_tl , +% \l_@@_explicit_plus_bool , +% \l_@@_zero_uncert_bool +% } +% \begin{macro}[EXP]{\@@_expression:n} +% Options which determine the various valid parts of a parsed number. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + evaluate-expression .bool_set:N = + \l_@@_expression_bool , + expression .code:n = + \cs_set:Npn \@@_expression:n ##1 {#1} , + input-close-uncertainty .tl_set:N = + \l_@@_input_uncert_close_tl , + input-comparators .tl_set:N = + \l_siunitx_number_input_comparator_tl , + input-decimal-markers .tl_set:N = + \l_siunitx_number_input_decimal_tl , + input-digits .tl_set:N = + \l_@@_input_digit_tl , + input-exponent-markers .tl_set:N = + \l_siunitx_number_input_exponent_tl , + input-ignore .tl_set:N = + \l_@@_input_ignore_tl , + input-open-uncertainty .tl_set:N = + \l_@@_input_uncert_open_tl , + input-signs .tl_set:N = + \l_siunitx_number_input_sign_tl , + input-uncertainty-signs .code:n = + { + \tl_set:Nn \l_@@_input_uncert_sign_tl {#1} + \tl_map_inline:nn {#1} + { + \tl_if_in:NnF \l_siunitx_number_input_sign_tl {##1} + { \tl_put_right:Nn \l_siunitx_number_input_sign_tl {##1} } + } + } , + parse-numbers .bool_set:N = + \l_siunitx_number_parse_bool , + retain-explicit-plus .bool_set:N = + \l_@@_explicit_plus_bool , + retain-zero-uncertainty .bool_set:N = + \l_@@_zero_uncert_bool + } +\cs_new:Npn \@@_expression:n #1 { } +\tl_new:N \l_@@_input_uncert_sign_tl +% \end{macrocode} +% \end{macro} +% \end{variable} +% +% \begin{variable}{\l_@@_arg_tl} +% The input argument or a part thereof, depending on the position in +% the parsing routine. +% \begin{macrocode} +\tl_new:N \l_@@_arg_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_comparator_tl} +% A comparator, if found, is held here. +% \begin{macrocode} +\tl_new:N \l_@@_comparator_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_exponent_tl} +% The exponent part of a parsed number. It is easiest to find this +% relatively early in the parsing process, but as it needs to go at +% the end of the internal format is held separately until required. +% \begin{macrocode} +\tl_new:N \l_@@_exponent_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_flex_tl} +% In a number with an uncertainty, the exact meaning of a second part is +% not fully resolved until parsing is complete. That is handled using +% this \enquote{flexible} store. +% \begin{macrocode} +\tl_new:N \l_@@_flex_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_parsed_tl} +% The number parsed into internal format. +% \begin{macrocode} +\tl_new:N \l_@@_parsed_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_input_tl} +% The numerical input exactly as given by the user. +% \begin{macrocode} +\tl_new:N \l_@@_input_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_partial_tl} +% To avoid needing to worry about the fact that the final data stores are +% somewhat tricky to add to token-by-token, a simple store is used to build +% up the parsed part of a number before transferring in one go. +% \begin{macrocode} +\tl_new:N \l_@@_partial_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_validate_bool} +% Used to set up for validation with no error production. +% \begin{macrocode} +\bool_new:N \l_@@_validate_bool +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_number_normalize_symbols:N} +% \begin{macro}{\@@_normalize_aux:nN} +% \begin{macro}{\@@_normalize_sign:N} +% \begin{variable}{\c_@@_normalize_tl} +% There are two parts to the replacement code. First, any active +% hyphens signs are normalised: these can come up with some packages and +% cause issues. Multi-token signs then are converted to the single token +% equivalents so that everything else can work on a one token basis. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_number_normalize_symbols:N #1 + { + \@@_normalize_minus:N #1 + \exp_after:wN \@@_normalize_aux:NnN \exp_after:wN #1 + \c_@@_normalize_tl + { ? } \q_recursion_tail + \q_recursion_stop + } +\cs_set_protected:Npn \@@_normalize_aux:NnN #1#2#3 + { + \quark_if_recursion_tail_stop:N #3 + \tl_replace_all:Nnn #1 {#2} {#3} + \@@_normalize_aux:NnN #1 + } +\tl_const:Nn \c_@@_normalize_tl + { + { -+ } \mp + { +- } \pm + { << } \ll + { <= } \le + { >> } \gg + { >= } \ge + } +\group_begin: + \char_set_catcode_active:N \- + \cs_new_protected:Npx \@@_normalize_minus:N #1 + { + \tl_replace_all:Nnn #1 + { \exp_not:N - } { \token_to_str:N - } + } +\group_end: +% \end{macrocode} +% \end{variable} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\siunitx_number_parse:nN, \siunitx_number_parse:VN} +% \begin{macro}{\@@_parse:nN} +% After some initial set up, the parser expands the input and then replaces +% as far as possible tricky tokens with ones that can be handled using +% delimited arguments. To avoid multiple conditionals here, the parser is +% set up as a chain of commands initially, with a loop only later. This +% avoids more conditionals than are necessary. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_number_parse:nN #1#2 + { + \bool_if:NTF \l_siunitx_number_parse_bool + { \@@_parse:nN {#1} #2 } + { \tl_clear:N #2 } + } +\cs_generate_variant:Nn \siunitx_number_parse:nN { V } +\cs_new_protected:Npn \@@_parse:nN #1#2 + { + \group_begin: + \tl_clear:N \l_@@_parsed_tl + \protected@edef \l_@@_arg_tl + { + \bool_if:NTF \l_@@_expression_bool + { \fp_eval:n { \@@_expression:n {#1} } } + {#1} + } + \tl_set_eq:NN \l_@@_input_tl \l_@@_arg_tl + \siunitx_number_normalize_symbols:N \l_@@_arg_tl + \tl_if_empty:NF \l_@@_arg_tl + { \@@_parse_comparator: } + \@@_parse_check: + \exp_args:NNNV \group_end: + \tl_set:Nn #2 \l_@@_parsed_tl + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_check:} +% After the loop there is one case that might need tidying up. If a +% separated uncertainty was found it will be currently in \cs{l_@@_flex_tl} +% and needs moving. A series of tests pick up that case, then the check is +% made that some content was found +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_check: + { + \tl_if_empty:NF \l_@@_flex_tl + { + \bool_lazy_and:nnTF + { + \tl_if_blank_p:f + { \exp_after:wN \use_iv:nnnn \l_@@_parsed_tl } + } + { + \tl_if_blank_p:f + { \exp_after:wN \use_iv:nnnn \l_@@_flex_tl } + } + { + \tl_set:Nx \l_@@_tmp_tl + { \exp_after:wN \use_i:nnnn \l_@@_flex_tl } + \tl_if_in:NVTF \l_@@_input_uncert_sign_tl + \l_@@_tmp_tl + { \@@_parse_combine_uncert: } + { \tl_clear:N \l_@@_parsed_tl } + } + { \tl_clear:N \l_@@_parsed_tl } + } + \tl_if_empty:NTF \l_@@_parsed_tl + { + \bool_if:NF \l_@@_validate_bool + { + \msg_error:nnx { siunitx } { invalid-number } + { \exp_not:V \l_@@_input_tl } + } + } + { \@@_parse_finalise: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_combine_uncert:} +% \begin{macro}{\@@_parse_combine_uncert_auxi:nnnnnnnn} +% \begin{macro} +% { +% \@@_parse_combine_uncert_auxii:nnnnn, +% \@@_parse_combine_uncert_auxii:fnnnn +% } +% \begin{macro} +% { +% \@@_parse_combine_uncert_auxiii:nnnnnn, +% \@@_parse_combine_uncert_auxiii:fnnnnn +% } +% \begin{macro}{\@@_parse_combine_uncert_auxiv:nnnn} +% \begin{macro}[EXP]{\@@_parse_combine_uncert_auxv:w} +% \begin{macro}[EXP]{\@@_parse_combine_uncert_auxvi:w} +% Conversion of a second numerical part to an uncertainty needs a bit of +% work. The first step is to extract the useful information from the two +% stores: the sign, integer and decimal parts from the real number and the +% integer and decimal parts from the second number. That is done using the +% input stack to avoid lots of assignments. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_combine_uncert: + { + \exp_after:wN \exp_after:wN \exp_after:wN + \@@_parse_combine_uncert_auxi:nnnnnnnn + \exp_after:wN \l_@@_parsed_tl \l_@@_flex_tl + } +% \end{macrocode} +% Here, |#4|, |#5| and |#8| are all junk arguments simply there to mop up +% tokens, while |#1| will be recovered later from \cs{l_@@_parsed_tl} so does +% not need to be passed about. The difference in places between the two +% decimal parts is now found: this is done just once to avoid having to +% parse token lists twice. The value is then used to generate a number of +% filler |0| tokens, and these are added to the appropriate part of the +% number. Finally, everything is recombined: the integer part only needs +% a test to avoid an empty main number. +% \begin{macrocode} +\cs_new_protected:Npn + \@@_parse_combine_uncert_auxi:nnnnnnnn #1#2#3#4#5#6#7#8 + { + \int_compare:nNnTF { \tl_count:n {#6} } > { \tl_count:n {#2} } + { + \tl_clear:N \l_@@_parsed_tl + \tl_clear:N \l_@@_flex_tl + } + { + \@@_parse_combine_uncert_auxii:fnnnn + { \int_eval:n { \tl_count:n {#3} - \tl_count:n {#7} } } + {#2} {#3} {#6} {#7} + } + } +\cs_new_protected:Npn + \@@_parse_combine_uncert_auxii:nnnnn #1 + { + \@@_parse_combine_uncert_auxiii:fnnnnn + { \prg_replicate:nn { \int_abs:n {#1} } { 0 } } + {#1} + } +\cs_generate_variant:Nn \@@_parse_combine_uncert_auxii:nnnnn { f } +\cs_new_protected:Npn + \@@_parse_combine_uncert_auxiii:nnnnnn #1#2#3#4#5#6 + { + \int_compare:nNnTF {#2} > 0 + { + \@@_parse_combine_uncert_auxiv:nnnn + {#3} {#4} {#5} { #6 #1 } + } + { + \@@_parse_combine_uncert_auxiv:nnnn + {#3} { #4 #1 } {#5} {#6} + } + } +\cs_generate_variant:Nn + \@@_parse_combine_uncert_auxiii:nnnnnn { f } +\cs_new_protected:Npn + \@@_parse_combine_uncert_auxiv:nnnn #1#2#3#4 + { + \tl_set:Nx \l_@@_parsed_tl + { + { \tl_head:V \l_@@_parsed_tl } + { \exp_not:n {#1} } + { + \bool_lazy_and:nnTF + { \tl_if_blank_p:n {#2} } + { ! \tl_if_blank_p:n {#4} } + { 0 } + { \exp_not:n {#2} } + } + { + \@@_parse_combine_uncert_auxv:w #3#4 + \q_recursion_tail \q_recursion_stop + } + } + } +% \end{macrocode} +% A short routine to remove any leading zeros in the uncertainty part, +% which are not needed for the compact representation used by the module. +% \begin{macrocode} +\cs_new:Npn \@@_parse_combine_uncert_auxv:w #1 + { + \quark_if_recursion_tail_stop_do:Nn #1 + { + \bool_if:NT \l_@@_zero_uncert_bool + { { S } { 0 } } + } + \str_if_eq:nnTF {#1} { 0 } + { \@@_parse_combine_uncert_auxv:w } + { \@@_parse_combine_uncert_auxvi:w #1 } + } +\cs_new:Npn \@@_parse_combine_uncert_auxvi:w + #1 \q_recursion_tail \q_recursion_stop + { { S } { \exp_not:n {#1} } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_comparator:} +% \begin{macro}{\@@_parse_comparator_aux:Nw} +% A comparator has to be the very first token in the input. A such, the +% test for this can be very fast: grab the first token, do a check and +% if appropriate store the result. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_comparator: + { + \exp_after:wN \@@_parse_comparator_aux:Nw + \l_@@_arg_tl \q_stop + } +\cs_new_protected:Npn \@@_parse_comparator_aux:Nw #1#2 \q_stop + { + \tl_if_in:NnTF \l_siunitx_number_input_comparator_tl {#1} + { + \tl_set:Nn \l_@@_comparator_tl {#1} + \tl_set:Nn \l_@@_arg_tl {#2} + } + { \tl_clear:N \l_@@_comparator_tl } + \tl_if_empty:NF \l_@@_arg_tl + { \@@_parse_sign: } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_exponent:} +% \begin{macro}{\@@_parse_exponent_auxi:w} +% \begin{macro}{\@@_parse_exponent_auxii:nn} +% \begin{macro}{\@@_parse_exponent_auxiii:Nw} +% \begin{macro}{\@@_parse_exponent_auxiv:nn} +% \begin{macro} +% {\@@_parse_exponent_zero_test:N, \@@_parse_exponent_check:N} +% \begin{macro}{\@@_parse_exponent_cleanup:N} +% An exponent part of a number has to come at the end and can only occur +% once. Thus it is relatively easy to parse. First, there is a check that +% an exponent part is allowed, and if so a split is made (the previous +% part of the chain checks that there is some content in \cs{l_@@_arg_tl} +% before calling this function). After splitting, if there is no exponent +% then simply save a default. Otherwise, check for a sign and then store +% either this or an implicit plus, and the digits after a check that nothing +% else is present after the~|e|. The only slight complication to all of +% this is allowing an arbitrary token in the input to represent the exponent: +% this is done by setting any exponent tokens to the first of the allowed +% list, then using that in a delimited argument set up. Once an exponent +% part is found, there is a loop to check that each of the tokens is a digit +% then a tidy up step to remove any leading zeros. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_exponent: + { + \tl_if_empty:NTF \l_siunitx_number_input_exponent_tl + { + \tl_set:Nn \l_@@_exponent_tl { { } 0 } + \tl_if_empty:NF \l_@@_parsed_tl + { \@@_parse_loop: } + } + { + \tl_set:Nx \l_@@_tmp_tl + { \tl_head:V \l_siunitx_number_input_exponent_tl } + \tl_map_inline:Nn \l_siunitx_number_input_exponent_tl + { + \tl_replace_all:NnV \l_@@_arg_tl + {##1} \l_@@_tmp_tl + } + \use:x + { + \cs_set_protected:Npn + \exp_not:N \@@_parse_exponent_auxi:w + ####1 \exp_not:V \l_@@_tmp_tl + ####2 \exp_not:V \l_@@_tmp_tl + ####3 \exp_not:N \q_stop + } + { \@@_parse_exponent_auxii:nn {##1} {##2} } + \use:x + { + \@@_parse_exponent_auxi:w + \exp_not:V \l_@@_arg_tl + \exp_not:V \l_@@_tmp_tl \exp_not:N \q_nil + \exp_not:V \l_@@_tmp_tl \exp_not:N \q_stop + } + } + } +\cs_new_protected:Npn \@@_parse_exponent_auxi:w { } +\cs_new_protected:Npn \@@_parse_exponent_auxii:nn #1#2 + { + \quark_if_nil:nTF {#2} + { \tl_set:Nn \l_@@_exponent_tl { { } 0 } } + { + \tl_set:Nn \l_@@_arg_tl {#1} + \tl_if_blank:nTF {#2} + { \tl_clear:N \l_@@_parsed_tl } + { \@@_parse_exponent_auxiii:Nw #2 \q_stop } + } + \tl_if_empty:NF \l_@@_parsed_tl + { \@@_parse_loop: } + } +\cs_new_protected:Npn \@@_parse_exponent_auxiii:Nw #1#2 \q_stop + { + \tl_if_in:NnTF \l_siunitx_number_input_sign_tl {#1} + { \@@_parse_exponent_auxiv:nn {#1} {#2} } + { \@@_parse_exponent_auxiv:nn { } {#1#2} } + \tl_if_empty:NT \l_@@_exponent_tl + { \tl_clear:N \l_@@_parsed_tl } + } +\cs_new_protected:Npn \@@_parse_exponent_auxiv:nn #1#2 + { + \bool_lazy_or:nnTF + { \l_@@_explicit_plus_bool } + { ! \str_if_eq_p:nn {#1} { + } } + { \tl_set:Nn \l_@@_exponent_tl { {#1} } } + { \tl_set:Nn \l_@@_exponent_tl { { } } } + \tl_if_blank:nTF {#2} + { \tl_clear:N \l_@@_parsed_tl } + { + \@@_parse_exponent_zero_test:N #2 + \q_recursion_tail \q_recursion_stop + } + } +\cs_new_protected:Npn \@@_parse_exponent_zero_test:N #1 + { + \quark_if_recursion_tail_stop_do:Nn #1 + { \tl_set:Nn \l_@@_exponent_tl { { } 0 } } + \str_if_eq:nnTF {#1} { 0 } + { \@@_parse_exponent_zero_test:N } + { \@@_parse_exponent_check:N #1 } + } +\cs_new_protected:Npn \@@_parse_exponent_check:N #1 + { + \quark_if_recursion_tail_stop:N #1 + \tl_if_in:NnTF \l_@@_input_digit_tl {#1} + { + \tl_put_right:Nn \l_@@_exponent_tl {#1} + \@@_parse_exponent_check:N + } + { \@@_parse_exponent_cleanup:wN } + } +\cs_new_protected:Npn \@@_parse_exponent_cleanup:wN + #1 \q_recursion_stop + { \tl_clear:N \l_@@_parsed_tl } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_finalise:} +% \begin{macro}{\@@_parse_finalise:nw} +% Combine all of the bits of a number together: both the real and +% imaginary parts contain all of the data. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_finalise: + { + \tl_if_empty:NF \l_@@_parsed_tl + { + \tl_set:Nx \l_@@_parsed_tl + { + { \exp_not:V \l_@@_comparator_tl } + \exp_not:V \l_@@_parsed_tl + \exp_after:wN \@@_parse_finalise:nw + \l_@@_exponent_tl \q_stop + } + } + } +\cs_new:Npn \@@_parse_finalise:nw #1#2 \q_stop + { + { \exp_not:n {#1} } + { \exp_not:n {#2} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_loop:} +% \begin{macro}{\@@_parse_loop_first:N} +% \begin{macro}{\@@_parse_loop_main:NNNNN} +% \begin{macro}{\@@_parse_loop_main_end:NN} +% \begin{macro}{\@@_parse_loop_main_digit:NNNNN} +% \begin{macro}{\@@_parse_loop_main_decimal:NN} +% \begin{macro}{\@@_parse_loop_main_uncert:NNN} +% \begin{macro}{\@@_parse_loop_main_sign:NNN} +% \begin{macro}{\@@_parse_loop_main_store:NNN} +% \begin{macro}{\@@_parse_loop_after_decimal:NNN} +% \begin{macro}{\@@_parse_loop_root_swap:NNwNN} +% \begin{macro}{\@@_parse_loop_break:wN} +% At this stage, the partial input \cs{l_@@_arg_tl} will contain any +% mantissa, which may contain an uncertainty or complex part. Parsing this +% and allowing for all of the different formats possible is best done using +% a token-by-token approach. However, as at each stage only a subset of +% tokens are valid, the approach take is to use a set of semi-dedicated +% functions to parse different components along with switches to allow a +% sensible amount of code sharing. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop: + { + \tl_clear:N \l_@@_partial_tl + \exp_after:wN \@@_parse_loop_first:NNN + \exp_after:wN \l_@@_parsed_tl \exp_after:wN \c_true_bool + \l_@@_arg_tl + \q_recursion_tail \q_recursion_stop + } +% \end{macrocode} +% The very first token of the input is handled with a dedicated function. +% Valid cases here are +% \begin{itemize} +% \item Entirely blank if the original input was for example |+e10|: +% simply clean up if in the integer part of issue an error if in +% a second part (complex number, \foreign{etc.}). +% \item An integer part digit: pass through to the main collection +% routine. +% \item A decimal marker: store an empty integer part and move to +% the main collection routine for a decimal part. +% \end{itemize} +% Anything else is invalid and sends the code to the abort function. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_first:NNN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #3 + { + \bool_if:NTF #2 + { \tl_put_right:Nn #1 { { 1 } { } { } } } + { \@@_parse_loop_break:wN \q_recursion_stop } + } + \tl_if_in:NnTF \l_@@_input_digit_tl {#3} + { + \@@_parse_loop_main:NNNNN + #1 \c_true_bool \c_false_bool #2 #3 + } + { + \tl_if_in:NnTF \l_siunitx_number_input_decimal_tl {#3} + { + \tl_put_right:Nn #1 { { 0 } } + \@@_parse_loop_after_decimal:NNN #1 #2 + } + { \@@_parse_loop_break:wN } + } + } +% \end{macrocode} +% A single function is used to cover the \enquote{main} part of numbers: +% finding real, complex or separated uncertainty parts and covering both +% the integer and decimal components. This works because these elements +% share a lot of concepts: a small number of switches can be used to +% differentiate between them. To keep the code at least somewhat readable, +% this main function deals with the validity testing but hands off other +% tasks to dedicated auxiliaries for each case. +% +% The possibilities are +% \begin{itemize} +% \item The number terminates, meaning that some digits were collected +% and everything is simply tidied up (as far as the loop is concerned). +% \item A digit is found: this is the common case and leads to a storage +% auxiliary (which handles non-significant zeros). +% \item A decimal marker is found: only valid in the integer part and +% there leading to a store-and-switch situation. +% \item An open-uncertainty token: switch to the dedicated collector +% for uncertainties. +% \item A sign token (if allowed): stop collecting this number and +% restart collection for the second part. +% \end{itemize} +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_main:NNNNN #1#2#3#4#5 + { + \quark_if_recursion_tail_stop_do:Nn #5 + { \@@_parse_loop_main_end:NN #1#2 } + \tl_if_in:NnTF \l_@@_input_digit_tl {#5} + { \@@_parse_loop_main_digit:NNNNN #1#2#3#4#5 } + { + \tl_if_in:NnTF \l_siunitx_number_input_decimal_tl {#5} + { + \bool_if:NTF #2 + { \@@_parse_loop_main_decimal:NN #1 #4 } + { \@@_parse_loop_break:wN } + } + { + \tl_if_in:NnTF \l_@@_input_uncert_open_tl {#5} + { \@@_parse_loop_main_uncert:NNN #1#2 #4 } + { + \bool_if:NTF #4 + { + \tl_if_in:NnTF \l_siunitx_number_input_sign_tl {#5} + { + \@@_parse_loop_main_sign:NNN + #1#2 #5 + } + { \@@_parse_loop_break:wN } + } + { \@@_parse_loop_break:wN } + } + } + } + } +% \end{macrocode} +% If the main loop finds the end marker then there is a tidy up phase. +% The current partial number is stored either as the integer or decimal, +% depending on the setting for the indicator switch. For the integer +% part, if no number has been collected then one or more non-significant +% zeros have been dropped. Exactly one zero is therefore needed to make +% sure the parsed result is correct. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_main_end:NN #1#2 + { + \bool_lazy_and:nnT + {#2} { \tl_if_empty_p:N \l_@@_partial_tl } + { \tl_set:Nn \l_@@_partial_tl { 0 } } + \tl_put_right:Nx #1 + { + { \exp_not:V \l_@@_partial_tl } + \bool_if:NT #2 { { } } + { } + } + } +% \end{macrocode} +% The most common case for the main loop collector is to find a digit. +% Here, in the integer part it is possible that zeros are non-significant: +% that is handled using a combination of a switch and a string test. Other +% than that, the situation here is simple: store the input and loop. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_main_digit:NNNNN #1#2#3#4#5 + { + \bool_lazy_or:nnTF + {#3} { ! \str_if_eq_p:nn {#5} { 0 } } + { + \tl_put_right:Nn \l_@@_partial_tl {#5} + \@@_parse_loop_main:NNNNN #1 #2 \c_true_bool #4 + } + { \@@_parse_loop_main:NNNNN #1 #2 \c_false_bool #4 } + } +% \end{macrocode} +% When a decimal marker was found, move the integer part to the +% store and then go back to the loop with the flags set correctly. +% There is the case of non-significant zeros to cover before that, of course. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_main_decimal:NN #1#2 + { + \@@_parse_loop_main_store:NNN #1 \c_false_bool \c_false_bool + \@@_parse_loop_after_decimal:NNN #1 #2 + } +% \end{macrocode} +% Starting an uncertainty part means storing the number to date as in other +% cases, with the possibility of a blank decimal part allowed for. The +% uncertainty itself is collected by a dedicated function as it is extremely +% restricted. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_main_uncert:NNN #1#2#3 + { + \@@_parse_loop_main_store:NNN #1 #2 \c_false_bool + \@@_parse_uncert:NN #1 + } +% \end{macrocode} +% If a sign is found, terminate the current number, store the sign as the +% first token of the second part and go back to do the dedicated first-token +% function. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_main_sign:NNN #1#2#3 + { + \@@_parse_loop_main_store:NNN #1 #2 \c_true_bool + \tl_set:Nn \l_@@_flex_tl { {#3} } + \@@_parse_loop_first:NNN + \l_@@_flex_tl \c_false_bool + } +% \end{macrocode} +% A common auxiliary for the various non-digit token functions: tidy up the +% integer and decimal parts of a number. Here, the two flags are used to +% indicate if empty decimal and uncertainty parts should be included in +% the storage cycle. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_main_store:NNN #1#2#3 + { + \tl_if_empty:NT \l_@@_partial_tl + { \tl_set:Nn \l_@@_partial_tl { 0 } } + \tl_put_right:Nx #1 + { + { \exp_not:V \l_@@_partial_tl } + \bool_if:NT #2 { { } } + \bool_if:NT #3 { { } } + } + \tl_clear:N \l_@@_partial_tl + } +% \end{macrocode} +% After a decimal marker there has to be a digit if there wasn't one before +% it. That is handled by using a dedicated function, which checks for +% an empty integer part first then either simply hands off or looks for +% a digit. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_after_decimal:NNN #1#2#3 + { + \tl_if_blank:fTF { \exp_after:wN \use_none:n #1 } + { + \quark_if_recursion_tail_stop_do:Nn #3 + { \@@_parse_loop_break:wN \q_recursion_stop } + \tl_if_in:NnTF \l_@@_input_digit_tl {#1} + { + \tl_put_right:Nn \l_@@_partial_tl {#3} + \@@_parse_loop_main:NNNNN + #1 \c_false_bool \c_true_bool #2 + } + { \@@_parse_loop_break:wN } + } + { + \@@_parse_loop_main:NNNNN + #1 \c_false_bool \c_true_bool #2 #3 + } + } +% \end{macrocode} +% Something is not right: remove all of the remaining tokens from the +% number and clear the storage areas as a signal for the next part of the +% code. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_loop_break:wN + #1 \q_recursion_stop + { + \tl_clear:N \l_@@_flex_tl + \tl_clear:N \l_@@_parsed_tl + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_sign:} +% \begin{macro}{\@@_parse_sign_aux:Nw} +% The first token of a number after a comparator could be a sign. A quick +% check is made and if found stored. For the number to be valid it has to be +% more than just a sign, so the next part of the chain is only called if that +% is the case. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_sign: + { + \exp_after:wN \@@_parse_sign_aux:Nw + \l_@@_arg_tl \q_stop + } +\cs_new_protected:Npn \@@_parse_sign_aux:Nw #1#2 \q_stop + { + \tl_if_in:NnTF \l_siunitx_number_input_sign_tl {#1} + { + \tl_set:Nn \l_@@_arg_tl {#2} + \bool_lazy_and:nnTF + { \token_if_eq_charcode_p:NN #1 + } + { ! \l_@@_explicit_plus_bool } + { \tl_set:Nn \l_@@_parsed_tl { { } } } + { \tl_set:Nn \l_@@_parsed_tl { {#1} } } + } + { \tl_set:Nn \l_@@_parsed_tl { { } } } + \tl_if_empty:NTF \l_@@_arg_tl + { \tl_clear:N \l_@@_parsed_tl } + { \@@_parse_exponent: } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_uncert:NN} +% \begin{macro}{\@@_parse_uncert:NNNN} +% \begin{macro}{\@@_parse_uncert_auxi:NN, \@@_parse_uncert_auxii:NN} +% \begin{macro} +% { +% \@@_parse_uncert_auxii:N , +% \@@_parse_uncert_marker:N , +% \@@_parse_uncert_after:N +% } +% Parsing a combined uncertainty has a very restricted range of allowed +% tokens. A closing uncertainty token in the first place is an error, +% so we filter that out explicitly. After that, we check for digits, +% which require checking for significant digits. The non-digit function +% is separate to make the flow clearer. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_uncert:NN #1#2 + { + \quark_if_recursion_tail_stop_do:Nn #2 + { \@@_parse_loop_break:wN \q_recursion_stop } + \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#2} + { \@@_parse_loop_break:wN } + { + \@@_parse_uncert:NNNN + #1 \c_false_bool \@@_parse_uncert_auxi:NN #2 + } + } +% \end{macrocode} +% Deal with digits: a simple question of whether they are significant. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_uncert:NNNN #1#2#3#4 + { + \quark_if_recursion_tail_stop_do:Nn #4 + { \@@_parse_loop_break:wN \q_recursion_stop } + \tl_if_in:NnTF \l_@@_input_digit_tl {#4} + { + \bool_lazy_or:nnTF + {#2} { ! \str_if_eq_p:nn {#4} { 0 } } + { + \tl_put_right:Nn \l_@@_partial_tl {#4} + \@@_parse_uncert:NNNN #1 \c_true_bool #3 + } + { \@@_parse_uncert:NNNN #1 \c_false_bool #3 } + } + { #3 #1#4 } + } +% \end{macrocode} +% For the two auxiliaries, the difference is the handling of a +% decimal marker: one may be present, but only exactly one. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_uncert_auxi:NN #1#2 + { + \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#2} + { + \@@_parse_uncert_auxiii:N #1 + \@@_parse_uncert_after:N + } + { + \tl_if_in:NnTF \l_siunitx_number_input_decimal_tl {#2} + { \@@_parse_uncert_marker:N #1 } + { \@@_parse_loop_break:wN } + } + } +\cs_new_protected:Npn \@@_parse_uncert_auxii:NN #1#2 + { + \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#2} + { + \@@_parse_uncert_auxiii:N #1 + \@@_parse_uncert_after:N + } + { \@@_parse_loop_break:wN } + } +% \end{macrocode} +% Deal with the closing bracket, which might leave us with nothing if there +% were no significant digits. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_uncert_auxiii:N #1 + { + \tl_if_empty:NTF \l_@@_partial_tl + { + \tl_put_right:Nx #1 + { + { + \bool_if:NT \l_@@_zero_uncert_bool + { { S } { 0 } } + } + } + } + { + \tl_set:Nx \l_@@_partial_tl + { { S } { \exp_not:V \l_@@_partial_tl } } + \@@_parse_loop_main_store:NNN #1 + \c_false_bool \c_false_bool + } + } +% \end{macrocode} +% Handling a decimal marker in the uncertainty is a bit tricky: we need to make +% sure it's valid. First, we need to be sure that the integer part of the captured +% uncertainty is not too long. Then we need to check that the decimal part is +% not too long. Both of these require data from the collected partial number, +% so we extract that first. Checking the decimal part needs the length of the +% not-yet-collected uncertainty. Handily, we know that it should be a set of +% digits then a closing marker. So we can use that as a length: if it's +% too long we can stop. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_uncert_marker:N #1 + { \exp_after:wN \@@_parse_uncert_marker:nnnN #1 #1 } +\cs_new_protected:Npn \@@_parse_uncert_marker:nnnN #1#2#3#4 + { + \int_compare:nNnTF + { \tl_count:N \l_@@_partial_tl } > { \tl_count:n {#2} } + { \@@_parse_loop_break:wN } + { \@@_parse_uncert_marker:nNw {#3} #4 } + } +\cs_new_protected:Npn \@@_parse_uncert_marker:nNw + #1#2#3 \q_recursion_tail \q_recursion_stop + { + \int_compare:nNnTF + { \tl_count:n {#3} - 1 } = { \tl_count:n {#1} } + { + \str_if_eq:eeTF + { \exp_not:V \l_@@_partial_tl } + { \prg_replicate:nn { \tl_count:N \l_@@_partial_tl } { 0 } } + { + \@@_parse_uncert:NNNN + #2 \c_false_bool + } + { + \@@_parse_uncert:NNNN + #2 \c_true_bool + } + \@@_parse_uncert_auxii:NN + } + { \@@_parse_loop_break:wN } + #3 \q_recursion_tail \q_recursion_stop + } +% \end{macrocode} +% No further tokens are allowed after an uncertainty in parenthesis. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_uncert_after:N #1 + { + \quark_if_recursion_tail_stop:N #1 + \@@_parse_loop_break:wN + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Processing numbers} +% +% \begin{variable} +% { +% \l_@@_drop_exponent_bool , +% \l_@@_drop_uncertainty_bool , +% \l_@@_drop_zero_decimal_bool , +% \l_@@_exponent_mode_tl , +% \l_@@_exponent_fixed_int , +% \l_@@_min_decimal_int , +% \l_@@_min_integer_int , +% \l_@@_round_half_even_bool , +% \l_@@_round_mode_tl , +% \l_@@_round_pad_bool , +% \l_@@_round_precision_int +% } +% \begin{macrocode} +\keys_define:nn { siunitx } + { + drop-exponent .bool_set:N = + \l_@@_drop_exponent_bool , + drop-uncertainty .bool_set:N = + \l_@@_drop_uncertainty_bool , + drop-zero-decimal .bool_set:N = + \l_@@_drop_zero_decimal_bool , + exponent-mode .choices:nn = + { engineering , fixed , input , scientific } + { \tl_set_eq:NN \l_@@_exponent_mode_tl \l_keys_choice_tl } , + fixed-exponent .int_set:N = + \l_@@_exponent_fixed_int , + minimum-decimal-digits .int_set:N = + \l_@@_min_decimal_int , + minimum-integer-digits .int_set:N = + \l_@@_min_integer_int , + round-half .choice: , + round-half / even .code:n = + { \bool_set_true:N \l_@@_round_half_even_bool } , + round-half / up .code:n = + { \bool_set_false:N \l_@@_round_half_even_bool } , + round-minimum .code:n = + { \@@_set_round_min:n {#1} } , + round-mode .choices:nn = + { figures , none , places, uncertainty } + { \tl_set_eq:NN \l_@@_round_mode_tl \l_keys_choice_tl } , + round-pad .bool_set:N = + \l_@@_round_pad_bool , + round-precision .int_set:N = + \l_@@_round_precision_int , + } +\bool_new:N \l_@@_round_half_even_bool +\tl_new:N \l_@@_exponent_mode_tl +\tl_new:N \l_@@_round_mode_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_round_min_tl} +% For storing the minimum for rounding. +% \begin{macrocode} +\tl_new:N \l_@@_round_min_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_set_round_min:n} +% \begin{macro}[EXP]{\@@_set_round_min:nnnnnnn} +% For setting the rounding minimum, the aim is to do as much of the work +% now as possible. That's mainly a question of checking if there are any +% significant digits in the mantissa given. +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_round_min:n #1 + { + \siunitx_number_parse:nN {#1} \l_@@_tmp_tl + \exp_after:wN \@@_set_round_min:nnnnnnn \l_@@_tmp_tl + } +\cs_new:Npn \@@_set_round_min:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_set:Nx \l_@@_round_min_tl + { + \bool_lazy_and:nnF + { \str_if_eq_p:nn {#3} { 0 } } + { + \str_if_eq_p:ee + { \exp_not:n {#4} } + { \prg_replicate:nn { \tl_count:n {#4} } { 0 } } + } + { \exp_not:n { {#3} {#4} } } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\siunitx_number_process:NN} +% \begin{macro}{\@@_process:nnnnnnnNN} +% A top-level interface for the processing tools. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_number_process:NN #1#2 + { + \tl_if_empty:NTF #1 + { \tl_clear:N #2 } + { + \@@_drop_uncertainty:NN #1 #2 + \exp_after:wN \@@_process:nnnnnnnNN #2 #2 #2 + \@@_drop_exponent:NN #2 #2 + \@@_zero_decimal:NN #2 #2 + \@@_digits:NN #2 #2 + } + } +\cs_new_protected:Npn \@@_process:nnnnnnnNN #1#2#3#4#5#6#7#8#9 + { + \bool_lazy_and:nnF + { \str_if_eq_p:nn {#3} { 0 } } + { + \str_if_eq_p:ee + { \exp_not:n {#4} } { \prg_replicate:nn { \tl_count:n {#4} } { 0 } } + } + { + \@@_exponent:NN #8 #9 + \@@_round:NN #9 #9 + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_exponent:NN} +% \begin{macro}[EXP] +% { +% \@@_exponent_engineering:nnnnnnn , +% \@@_exponent_fixed:nnnnnnn , +% \@@_exponent_input:nnnnnnn , +% \@@_exponent_scientific:nnnnnnn +% } +% \begin{macro}[EXP] +% { +% \@@_exponent_fixed:nnnnnnnn , +% \@@_exponent_scientific:nnnnnnnn +% } +% \begin{macro}[EXP]{\@@_exponent_scientific:nnnw} +% \begin{macro}[EXP]{\@@_exponent_shift:nnn,\@@_exponent_shift:nnf} +% \begin{macro}[EXP]{\@@_exponent_shift_down:nnnw} +% \begin{macro}[EXP]{\@@_exponent_shift_down:nnn} +% \begin{macro}[EXP]{\@@_exponent_shift_down:nw} +% \begin{macro}[EXP]{\@@_exponent_shift_up:nnn} +% \begin{macro}[EXP]{\@@_exponent_shift_up:nnw} +% \begin{macro}[EXP] +% { +% \@@_exponent_shift_up_aux:nnn , +% \@@_exponent_shift_up_aux:fnn , +% \@@_exponent_shift_up_aux:ffn +% } +% \begin{macro}[EXP]{\@@_exponent_shift_uncert:nw} +% \begin{macro}[EXP] +% {\@@_exponent_shift_uncert_S:nnnn, \@@_exponent_shift_uncert_S:fnnn} +% \begin{macro}[EXP]{\@@_exponent_uncert:n} +% \begin{macro}[EXP]{\@@_exponent_finalise:n} +% \begin{macro}[EXP]{\@@_exponent_engineering_aux:nnnnnnn} +% \begin{macro}[EXP] +% { +% \@@_exponent_engineering_0:nnnn , +% \@@_exponent_engineering_1:nnnn , +% \@@_exponent_engineering_2:nnnn +% } +% \begin{macro}[EXP]{\@@_exponent_engineering:nnNw} +% \begin{macro}[EXP]{\@@_exponent_engineering_uncert:nn} +% \begin{macro}[EXP]{\@@_exponent_engineering_uncert_S:nnn} +% Manipulating an exponent is done using a single expansion function +% \emph{unless} dealing with engineering-style output. The latter is easier +% to handle by first converting to scientific output, then post-processing. +% (Once \texttt{e}-type expansion is generally available, this will be +% handling using a single \cs{tl_set:Nx}.) +% \begin{macrocode} +\cs_new_protected:Npn \@@_exponent:NN #1#2 + { + \tl_set:Nx #2 + { + \cs:w + @@_exponent_ \l_@@_exponent_mode_tl :nnnnnnn + \exp_after:wN + \cs_end: #1 + } + \str_if_eq:VnT \l_@@_exponent_mode_tl { engineering } + { + \tl_set:Nx #2 + { \exp_after:wN \@@_exponent_engineering_aux:nnnnnnn #2 } + } + } +\cs_new:Npn \@@_exponent_fixed:nnnnnnn #1#2#3#4#5#6#7 + { + \exp_args:Nf \@@_exponent_fixed:nnnnnnnn + { \int_eval:n { \l_@@_exponent_fixed_int - (#6#7) } } + {#1} {#2} {#3} {#4} {#5} {#6} {#7} + } +\cs_new:Npn \@@_exponent_fixed:nnnnnnnn #1#2#3#4#5#6#7#8 + { + \exp_not:n { {#2} {#3} } + \@@_exponent_shift:nnn {#1} {#4} {#5} + \@@_exponent_uncert:n {#6} + \exp_not:n { {#7} } { \int_use:N \l_@@_exponent_fixed_int } + } +\cs_new:Npn \@@_exponent_input:nnnnnnn #1#2#3#4#5#6#7 + { \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#7} } } +% \end{macrocode} +% To convert to scientific notation, the key question is to find the number +% of significant places. That is easy enough if the number has a non-zero +% integer component. For a pure decimal, we have to trim off leading +% zeros in a loop. +% \begin{macrocode} +\cs_new:Npn \@@_exponent_scientific:nnnnnnn #1#2#3#4#5#6#7 + { + \exp_args:Nf \@@_exponent_scientific:nnnnnnnn + { \int_eval:n { \tl_count:n {#3} } } + {#1} {#2} {#3} {#4} {#5} {#6} {#7} + } +\cs_new:Npn \@@_exponent_scientific:nnnnnnnn #1#2#3#4#5#6#7#8 + { + \exp_not:n { {#2} {#3} } + \int_compare:nNnTF {#1} = 1 + { + \str_if_eq:nnTF {#4} { 0 } + { + \@@_exponent_scientific:nnnw + { 0 } {#6} { #7#8 } #5 \q_stop + } + { \exp_not:n { {#4} {#5} {#6} {#7} {#8} } } + } + { + \@@_exponent_shift:nnn { #1 - 1 } {#4} {#5} + \@@_exponent_uncert:n {#6} + \@@_exponent_finalise:n { #1 + #7#8 - 1 } + } + } +\cs_new_eq:NN \@@_exponent_engineering:nnnnnnn + \@@_exponent_scientific:nnnnnnn +\cs_new:Npn \@@_exponent_scientific:nnnw #1#2#3#4#5 \q_stop + { + \str_if_eq:nnTF {#4} { 0 } + { + \@@_exponent_scientific:nnnw + { #1 - 1 } {#2} {#3} #5 \q_stop + } + { + \exp_not:n { {#4} {#5} {#2} } + \@@_exponent_finalise:n { #1 + #3 - 1 } + } + } +% \end{macrocode} +% When adjusting the exponent position, there are two paths depending on +% which way the shift takes place. +% \begin{macrocode} +\cs_new:Npn \@@_exponent_shift:nnn #1#2#3 + { + \int_compare:nNnTF {#1} > 0 + { \@@_exponent_shift_down:nnnw {#1} {#3} { } #2 \q_stop } + { + \int_compare:nNnTF {#1} < 0 + { \@@_exponent_shift_up:nnn {#1} {#2} {#3} } + { {#2} {#3} } + } + } +\cs_generate_variant:Nn \@@_exponent_shift:nnn { nnf } +% \end{macrocode} +% For shifting the exponent down, there is first a loop to reserve the +% integer part before doing the work: that of course has to be undone +% for any remainder at he end of the process. +% \begin{macrocode} +\cs_new:Npn \@@_exponent_shift_down:nnnw #1#2#3#4#5 \q_stop + { + \tl_if_blank:nTF {#5} + { \@@_exponent_shift_down:nnn {#1} { #4 #3 } {#2} } + { \@@_exponent_shift_down:nnnw {#1} {#2} { #4 #3 } #5 \q_stop } + } +\cs_new:Npn \@@_exponent_shift_down:nnn #1#2#3 + { + \int_compare:nNnTF {#1} = 0 + { { \tl_reverse:n {#2} } \exp_not:n { {#3} } } + { \@@_exponent_shift_down:nw {#1} #2 \q_stop {#3} } + } +\cs_new:Npn \@@_exponent_shift_down:nw #1#2#3 \q_stop #4 + { + \tl_if_blank:nTF {#3} + { \@@_exponent_shift_down:nnn { #1 - 1 } { 0 } { #2#4 } } + { \@@_exponent_shift_down:nnn { #1 - 1 } {#3} { #2#4 } } + } +% \end{macrocode} +% For shifting the exponent up, we can run out of decimal digits, at which +% point filling is easy. Other than that a simple loop as we are picking +% input off the front of the decimal part. We also need to deal with leading +% zeros: these cannot accumulate. +% \begin{macrocode} +\cs_new:Npn \@@_exponent_shift_up:nnn #1#2#3 + { + \tl_if_blank:nTF {#3} + { + \@@_exponent_shift_up_aux:ffn + { \int_eval:n { #1 + 1 } } + { \str_if_eq:nnF {#2} { 0 } {#2} 0 } + { } + \@@_exponent_shift_uncert:nw { 1 } + } + { \@@_exponent_shift_up:nnw {#1} {#2} #3 \q_stop } + } +\cs_new:Npn \@@_exponent_shift_up:nnw #1#2#3#4 \q_stop + { + \@@_exponent_shift_up_aux:ffn + { \int_eval:n { #1 + 1 } } + { \str_if_eq:nnF {#2} { 0 } {#2} #3 } + {#4} + } +\cs_new:Npn \@@_exponent_shift_up_aux:nnn #1#2#3 + { + \int_compare:nNnTF {#1} = 0 + { \exp_not:n { {#2} {#3} } } + { + \tl_if_blank:nTF {#3} + { + { + \exp_not:n {#2} + \prg_replicate:nn { \int_abs:n {#1} } { 0 } + } + { } + \@@_exponent_shift_uncert:nw { \int_abs:n {#1} } + } + { \@@_exponent_shift_up:nnn {#1} {#2} {#3} } + } + } +\cs_generate_variant:Nn \@@_exponent_shift_up_aux:nnn { f , ff } +% \end{macrocode} +% If the shift has put digits into the integer part, we have to adjust the +% uncertainty accordingly. First, we grab the data, then adjust by the +% number of places that have been transferred. +% \begin{macrocode} +\cs_new:Npn \@@_exponent_shift_uncert:nw + #1#2 \@@_exponent_uncert:n #3 + { + \tl_if_blank:nTF {#3} + { + #2 + \@@_exponent_uncert:n { } + } + { + \str_if_eq:nnTF {#3} { 0 } + { + #2 + \@@_exponent_uncert:n { { S } { 0 } } + } + { + \use:c { @@_exponent_shift_uncert_ \use_i:nn #3 :fnnn } + { \prg_replicate:nn {#1} { 0 } } + {#2} + #3 + } + } + } +\cs_new:Npn \@@_exponent_shift_uncert_S:nnnn #1#2#3#4 + { + #2 + \@@_exponent_uncert:n { { S } { #4#1 } } + } +\cs_generate_variant:Nn \@@_exponent_shift_uncert_S:nnnn { f } +\cs_new:Npn \@@_exponent_uncert:n #1 { { \exp_not:n {#1} } } +% \end{macrocode} +% Tidy up the exponent to put the sign in the right place. +% \begin{macrocode} +\cs_new:Npn \@@_exponent_finalise:n #1 + { + \int_compare:nNnTF {#1} < 0 + { { - } } + { { } } + { \int_abs:n {#1} } + } +% \end{macrocode} +% This could (and eventually will) be combined with the main function above: +% that will need \texttt{e}-type expansion. The input has already been +% normalised such that the integer part is in the range $1 \le n < 10$. +% Thus there are only three cases to deal with, depending on the required +% adjustment to the exponent. +% \begin{macrocode} +\cs_new:Npn \@@_exponent_engineering_aux:nnnnnnn #1#2#3#4#5#6#7 + { + \exp_not:n { {#1} {#2} } + \use:c + { + @@_exponent_engineering_ + \int_compare:nNnTF {#6#7} < 0 + { + \int_case:nnF { \int_mod:nn { #7 } { 3 } } + { + { 1 } { 2 } + { 2 } { 1 } + } + { 0 } + } + { \int_mod:nn {#7} { 3 } } + :nnnn + } + {#3} {#4} {#5} {#6#7} + } +\cs_new:cpn { @@_exponent_engineering_0:nnnn } #1#2#3#4 + { + \exp_not:n { {#1} {#2} {#3} } + \@@_exponent_finalise:n {#4} + } +\cs_new:cpn { @@_exponent_engineering_1:nnnn } #1#2#3#4 + { + \tl_if_blank:nTF {#2} + { + { \exp_not:n { #1 0 } } { } + { \@@_exponent_engineering_uncert:nn {#3} { 0 } } + } + { + { \exp_not:n {#1} \exp_not:o { \tl_head:w #2 \q_stop } } + { \exp_not:f { \tl_tail:n {#2} } } + { \exp_not:n {#3} } + } + \@@_exponent_finalise:n { #4 - 1 } + } +\cs_new:cpn { @@_exponent_engineering_2:nnnn } #1#2#3#4 + { + \tl_if_blank:nTF {#2} + { + { \exp_not:n { #1 00 } } { } + { \@@_exponent_engineering_uncert:nn {#3} { 00 } } + } + {\@@_exponent_engineering:nnNw {#1} {#3} #2 \q_stop } + \@@_exponent_finalise:n { #4 - 2 } + } +\cs_new:Npn \@@_exponent_engineering:nnNw #1#2#3#4 \q_stop + { + \tl_if_blank:nTF {#4} + { + { \exp_not:n { #1#3 0 } } { } + { { \@@_exponent_engineering_uncert:nn {#2} { 0 } } } + } + { + { \exp_not:n {#1#3} \exp_not:o { \tl_head:w #4 \q_stop } } + { \exp_not:f { \tl_tail:n {#4} } } + { \exp_not:n {#2} } + } + } +\cs_new:Npn \@@_exponent_engineering_uncert:nn #1#2 + { + \tl_if_blank:nF {#1} + { + \use:c { @@_exponent_engineering_uncert_ \use_i:nn #1 :nnn } + #1 {#2} + } + } +\cs_new:Npn \@@_exponent_engineering_uncert_S:nnn #1#2#3 + { + { S } + { + \exp_not:n {#2} + \str_if_eq:nnF {#2} { 0 } {#3} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_digits:NN} +% \begin{macro}[EXP]{\@@_digits:nnnnnnn} +% \begin{macro}[EXP]{\@@_digits:Nn} +% \begin{macro}[EXP]{\@@_digits:nn} +% \begin{macro}[EXP]{\@@_digits_S:n} +% Forcing a minimum number of digits in each part is quite easy. As +% the common case is that we don't do anything here, there is no real need +% to optimise the calculation (normally also numbers have only a few digits). +% \begin{macrocode} +\cs_new_protected:Npn \@@_digits:NN #1#2 + { + \tl_set:Nx #2 + { \exp_after:wN \@@_digits:nnnnnnn #1 } + } +\cs_new:Npn \@@_digits:nnnnnnn #1#2#3#4#5#6#7 + { + \exp_not:n { {#1} {#2} } + { + \@@_digits:Nn \l_@@_min_integer_int {#3} + \exp_not:n {#3} + } + { + \exp_not:n {#4} + \@@_digits:Nn \l_@@_min_decimal_int {#4} + } + { \tl_if_blank:nF {#5} { \@@_digits_uncert:nn #5 } } + \exp_not:n { {#6} {#7} } + } +\cs_new:Npn \@@_digits:Nn #1#2 + { + \int_compare:nNnT + { #1 - \tl_count:n {#2} } > 0 + { \prg_replicate:nn { #1 - \tl_count:n {#2} } { 0 } } + } +\cs_new:Npn \@@_digits_uncert:nn #1#2 + { + { #1 } + { \use:c { @@_digits_uncert_ #1 :n } {#2} } + } +\cs_new:Npn \@@_digits_uncert_S:n #1 + { + \exp_not:n {#1} + \@@_digits:Nn \l_@@_min_decimal_int {#1} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_drop_exponent:NN} +% \begin{macro}[EXP]{\@@_drop_exponent:nnnnnnn} +% Simple stripping of the exponent. +% \begin{macrocode} +\cs_new_protected:Npn \@@_drop_exponent:NN #1#2 + { + \bool_if:NT \l_@@_drop_exponent_bool + { + \tl_set:Nx #2 + { \exp_after:wN \@@_drop_exponent:nnnnnnn #1 } + } + } +\cs_new:Npn \@@_drop_exponent:nnnnnnn #1#2#3#4#5#6#7 + { \exp_not:n { {#1} {#2} {#3} {#4} {#5} { } { 0 } } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_drop_uncertainty:NN} +% \begin{macro}[EXP]{\@@_drop_uncertainty:nnnnnnn} +% Simple stripping of the uncertainty. +% \begin{macrocode} +\cs_new_protected:Npn \@@_drop_uncertainty:NN #1#2 + { + \bool_if:NTF \l_@@_drop_uncertainty_bool + { + \tl_set:Nx #2 + { \exp_after:wN \@@_drop_uncertainty:nnnnnnn #1 } + } + { \tl_set_eq:NN #2 #1 } + + } +\cs_new:Npn \@@_drop_uncertainty:nnnnnnn #1#2#3#4#5#6#7 + { \exp_not:n { {#1} {#2} {#3} {#4} { } {#6} {#7} } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_round:NN} +% \begin{macro}[EXP]{\@@_round_none:nnnnnnn} +% Rounding is at the top level simple enough: fire off the expandable +% set up which does the work. +% \begin{macrocode} +\cs_new_protected:Npn \@@_round:NN #1#2 + { + \tl_set:Nx #2 + { + \cs:w + @@_round_ \l_@@_round_mode_tl :nnnnnnn + \exp_after:wN + \cs_end: #1 + } + } +\cs_new:Npn \@@_round_none:nnnnnnn #1#2#3#4#5#6#7 + { \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#7} } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_round:nnn, \@@_round:fnn} +% \begin{macro}[EXP] +% { +% \@@_round_auxi:nnnN , +% \@@_round_auxii:nnnN , +% \@@_round_auxiii:nnnN +% } +% \begin{macro}[EXP]{\@@_round_auxiv:nnN, \@@_round_auxv:nnN} +% \begin{macro}[EXP]{\@@_round_auxvi:nN} +% \begin{macro}[EXP]{\@@_round_auxvii:nnN, \@@_round_auxviii:nnN} +% \begin{macro}[EXP]{\@@_round_final_integer:nnw, \@@_round_final_decimal:nnw} +% \begin{macro}[EXP]{\@@_round_final_output:nn, \@@_round_final_output:ff} +% \begin{macro}[EXP]{\@@_round_final:nn, \@@_round_final:fn} +% \begin{macro}[EXP]{\@@_round_final_shift:nn, \@@_round_final_shift:ff} +% \begin{macro}[EXP]{\@@_round_final_shift:Nw} +% \begin{macro}[EXP] +% { +% \@@_round_engineering:nn , +% \@@_round_fixed:nn , +% \@@_round_input:nn , +% \@@_round_scientifitc:nn +% } +% \begin{macro}[EXP]{\@@_round_engineering:NNNNn} +% \begin{macro}[EXP]{\@@_round_engineering:nnN} +% \begin{macro}[EXP]{\@@_round_truncate:n, \@@_round_truncate_direct:n} +% \begin{macro}[EXP]{\@@_round_truncate:nnN} +% Actually doing the rounding needs us to work from the least significant +% digit, so we start by reversing the input. We \emph{could} also drop +% digits in this phase, but tracking everything would be horrible, so +% we go slightly slower but clearer and split the steps. First we reverse +% the decimal part, then the integer. +% \begin{macrocode} +\cs_new:Npn \@@_round:nnn #1#2#3 + { + \@@_round_auxi:nnnN {#1} {#2} { } + #3 \q_recursion_tail \q_recursion_stop + } +\cs_generate_variant:Nn \@@_round:nnn { f } +\cs_new:Npn \@@_round_auxi:nnnN #1#2#3#4 + { + \quark_if_recursion_tail_stop_do:Nn #4 + { + \@@_round_auxii:nnnN {#1} {#3} { } #2 + \q_recursion_tail \q_recursion_stop + } + \@@_round_auxi:nnnN {#1} {#2} {#4#3} + } +\cs_new:Npn \@@_round_auxii:nnnN #1#2#3#4 + { + \quark_if_recursion_tail_stop_do:Nn #4 + { + \tl_if_blank:nTF {#2} + { + \@@_round_auxiv:nnnN {#1} { } { } #3 + \q_recursion_tail \q_recursion_stop + } + { + \@@_round_auxiii:nnnN {#1} {#3} { } #2 + \q_recursion_tail \q_recursion_stop + } + } + \@@_round_auxii:nnnN {#1} {#2} {#4#3} + } +% \end{macrocode} +% We now have the input reversed plus how many digits we need to discard +% (|#1|). We have two functions, one which deals with the decimal part, +% one of which deals with the integer. In the latter, we should never hit +% the end before we've dropped all the digits: the fixed-zero is a +% fall-back in case something weird happens. For the integer case, we need +% to collect up zeros to pad the length back out correctly later. +% \begin{macrocode} +\cs_new:Npn \@@_round_auxiii:nnnN #1#2#3#4 + { + \quark_if_recursion_tail_stop_do:Nn #4 + { + \@@_round_auxiv:nnnN {#1} { } {#3} #2 + \q_recursion_tail \q_recursion_stop + } + \int_compare:nNnTF {#1} > 0 + { + \exp_args:Nf \@@_round_auxiii:nnnN + { \int_eval:n { #1 - 1 } } {#2} { #4#3 } + } + { \@@_round_auxv:nnN {#3} {#2} #4 } + } +\cs_new:Npn \@@_round_auxiv:nnnN #1#2#3#4 + { + \quark_if_recursion_tail_stop_do:Nn #4 + { { 0 } { } } + \int_compare:nNnTF {#1} > 0 + { + \exp_args:Nf \@@_round_auxiv:nnnN + { \int_eval:n { #1 - 1 } } { #2 0 } { #4#3 } + } + { \@@_round_auxvi:nnnN {#3} {#2} #4 } + } +% \end{macrocode} +% The lead off to rounding proper needs to deal with the half-even rule: +% it can only apply at this stage, when the \emph{discarded} value can +% be exactly half. +% \begin{macrocode} +\cs_new:Npn \@@_round_auxv:nnN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #3 + { + \@@_round_auxvi:nnN + {#1} { } #2 \q_recursion_tail \q_recursion_stop + } + \bool_lazy_or:nnTF + { \int_compare_p:nNn { 0 \tl_head:n {#1} } < 5 } + { + \bool_lazy_all_p:n + { + { \l_@@_round_half_even_bool } + { \int_if_odd_p:n {#3} } + { \@@_round_if_half_p:n {#1} } + } + } + { \@@_round_final_decimal:nnw } + { \@@_round_auxvii:nnN } + {#2} { } #3 + } +\cs_new:Npn \@@_round_auxvi:nnnN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #3 + { { 0 } { } } + \bool_lazy_or:nnTF + { \int_compare_p:nNn { 0 \tl_head:n {#1} } < 5 } + { + \bool_lazy_all_p:n + { + { \l_@@_round_half_even_bool } + { \int_if_odd_p:n {#3} } + { \@@_round_if_half_p:n {#1} } + } + } + { \@@_round_final_integer:nnw } + { \@@_round_auxviii:nnN } + { } {#2} #3 + } +% \end{macrocode} +% The main rounding routines. These are only every called when there is +% rounding to do, so there is no need to carry a flag forward. Thus the +% question to ask is simple: is the next value a $9$ or not (as that +% continues the sequence). There is a general need to handle the case +% where a zero is rounded up: that automatically means a need to trim +% the other end. +% \begin{macrocode} +\cs_new:Npn \@@_round_auxvii:nnN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #3 + { + \str_if_eq:nnTF {#1} { 0 } + { + \@@_round_final_output:ff + { 1 } + { \@@_round_truncate:n {#2} } + } + { + \@@_round_auxviii:nnN {#2} { } #1 + \q_recursion_tail \q_recursion_stop + } + } + \int_compare:nNnTF {#3} = 9 + { \@@_round_auxvii:nnN {#1} { 0 #2 } } + { + \int_compare:nNnTF {#3} = 0 + { + \@@_round_final_decimal:nnw + {#1} { 1 \@@_round_truncate:n {#2} } + } + { + \@@_round_final:fn + { \int_eval:n { #3 + 1 } } + { \@@_round_final_decimal:nnw {#1} {#2} } + } + } + } +\cs_new:Npn \@@_round_auxviii:nnN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #3 + { + \tl_if_blank:nTF {#1} + { + \@@_round_final_shift:ff + { + \exp_last_unbraced:Nf 1 + { \@@_round_truncate_direct:n {#2} } 0 + } + { } + } + { + \@@_round_final_shift:ff + { 1 #2 } + { \@@_round_truncate:n {#1} } + } + } + \int_compare:nNnTF {#3} = 9 + { \@@_round_auxviii:nnN {#1} { 0 #2 } } + { + \@@_round_final:fn + { \int_eval:n { #3 + 1 } } + { \@@_round_final_integer:nnw {#1} {#2} } + } + } +% \end{macrocode} +% Tidying up means grabbing the remaining digits and undoing the reversal. +% \begin{macrocode} +\cs_new:Npn \@@_round_final_decimal:nnw + #1#2#3 \q_recursion_tail \q_recursion_stop + { + \@@_round_final_output:ff + { \tl_reverse:n {#1} } + { \tl_reverse:n {#3} #2 } + } +\cs_new:Npn \@@_round_final_integer:nnw + #1#2#3 \q_recursion_tail \q_recursion_stop + { + \@@_round_final_output:ff + { \tl_reverse:n {#3} #2 } + {#1} + } +\cs_new:Npn \@@_round_final_output:nn #1#2 { {#1} {#2} } +\cs_generate_variant:Nn \@@_round_final_output:nn { ff } +\cs_new:Npn \@@_round_final:nn #1#2 + { #2 #1 } +\cs_generate_variant:Nn \@@_round_final:nn { f } +% \end{macrocode} +% Here we deal with the case where rounding applies along with an +% exponent set based on number of places. We can only get here if an +% additional integer digit has been added, so there is no need to test for +% that. There are two cases for action: when using |scientific| mode, where +% we always need to shift by one, and when using |engineering| mode if +% we now have four digits. The latter is a bit more work: we need to trim +% digits off as required. +% \begin{macrocode} +\cs_new:Npn \@@_round_final_shift:nn #1#2 + { + \str_if_eq:VnTF \l_@@_round_mode_tl { places } + { + \use:c + { @@_round_ \l_@@_exponent_mode_tl :nn } + {#1} {#2} + } + { {#1} {#2} } + } +\cs_generate_variant:Nn \@@_round_final_shift:nn { ff } +\cs_new:Npn \@@_round_engineering:nn #1#2 + { + \int_compare:nNnTF { \tl_count:n {#1} } = 4 + { + \@@_round_engineering:NNNNn #1 {#2} + { } + \@@_round_final_shift:Nw 3 + } + { {#1} {#2} } + } +\cs_new:Npn \@@_round_engineering:NNNNn #1#2#3#4#5 + { + {#1} + \exp_args:NV \@@_round_engineering:nnN + { \l_@@_round_precision_int } { } + #2#3#4#5 \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \@@_round_engineering:nnN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #3 { {#2} } + \int_compare:nNnTF {#1} = { 0 } + { \use_i_delimit_by_q_recursion_stop:nw { {#2} } } + { \@@_round_engineering:nnN { #1 - 1 } { #2#3 } } + } +\cs_new:Npn \@@_round_fixed:nn #1#2 { {#1} {#2} } +\cs_new:Npn \@@_round_input:nn #1#2 { {#1} {#2} } +\cs_new:Npn \@@_round_scientific:nn #1#2 + { + \@@_exponent_shift:nnf + { 1 } {#1} { \@@_round_truncate_direct:n {#2} } + { } + \@@_round_final_shift:Nw 1 + } +\cs_new:Npn \@@_round_final_shift:Nw #1#2 \@@_round_places_end:nn #3#4 + { \@@_exponent_finalise:n { #3#4 + #1 } } +% \end{macrocode} +% When we have rounded up to the next power of ten, we need to go back and +% remove one more digit. That only happens when rounding to a number of +% figures or when dealing with an integer part. +% \begin{macrocode} +\cs_new:Npn \@@_round_truncate:n #1 + { + \str_if_eq:VnTF \l_@@_round_mode_tl { figures } + { \@@_round_truncate_direct:n {#1} } + {#1} + } +\cs_new:Npn \@@_round_truncate_direct:n #1 + { + \@@_round_truncate:nnN { } { } + #1 \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \@@_round_truncate:nnN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #3 { #1 } + \@@_round_truncate:nnN {#1#2} {#3} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_round_if_half_p:n} +% \begin{macro}[EXP]{\@@_round_if_half:N} +% A simple test for a valuing being exactly half: we can only test +% digit-by-digit as there is no limit on the size of the value given. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_round_if_half:n #1 { p } + { + \int_compare:nNnTF { \tl_head:n { #1 0 } } = 5 + { + \exp_after:wN \@@_round_if_half:N \use_none:n #1 0 + \q_recursion_tail \q_recursion_stop + } + { \prg_return_false: } + } +\cs_new:Npn \@@_round_if_half:N #1 + { + \quark_if_recursion_tail_stop_do:Nn #1 + { \prg_return_true: } + \int_compare:nNnTF {#1} = 0 + { \@@_round_if_half:N } + { \use_i_delimit_by_q_recursion_stop:nw { \prg_return_false: } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_round_pad:nnn} +% The case where we are short of digits is easy enough to handle: +% generate zeros to pad it out. +% \begin{macrocode} +\cs_new:Npn \@@_round_pad:nnn #1#2#3 + { + {#2} + { + #3 + \bool_if:NT \l_@@_round_pad_bool + { \prg_replicate:nn {#1} { 0 } } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_round_figures:nnnnnnn} +% \begin{macro}[EXP]{\@@_round_figures_count:nnN} +% \begin{macro}[EXP]{\@@_round_figures_count:nnnN} +% Rounding to a fixed number of significant figures starts by checking that +% there is no uncertainty, and that the number of figures requested is +% positive: if not, the result is always fixed at zero. +% \begin{macrocode} +\cs_new:Npn \@@_round_figures:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_if_blank:nTF {#5} + { + \int_compare:nNnTF \l_@@_round_precision_int > 0 + { + \exp_not:n { {#1} {#2} } + \@@_round_figures_count:nnN {#3} {#4} #3#4 + \q_recursion_tail \q_recursion_stop + \exp_not:n { { } {#6} {#7} } + } + { { } { } { 0 } { } { } { } { 0 } } + } + { \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#7} } } + } +% \end{macrocode} +% The first real step is to count up the number of significant figures. +% The only tricky issue here is dealing with leading zeros. +% \begin{macrocode} +\cs_new:Npn \@@_round_figures_count:nnN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #3 + { { } { } { 0 } { } { } { } { 0 } } + \int_compare:nNnTF {#3} = 0 + { \@@_round_figures_count:nnN {#1} {#2} } + { \@@_round_figures_count:nnnN { 1 } {#1} {#2} } + } +\cs_new:Npn \@@_round_figures_count:nnnN #1#2#3#4 + { + \quark_if_recursion_tail_stop_do:Nn #4 + { + \int_compare:nNnTF {#1} > \l_@@_round_precision_int + { + \@@_round:fnn + { \int_eval:n { #1 - \l_@@_round_precision_int } } + {#2} {#3} + } + { + \@@_round_pad:nnn + { \l_@@_round_precision_int - (#1) } {#2} {#3} + } + } + \exp_args:Nf \@@_round_figures_count:nnnN + { \int_eval:n { #1 + 1 } } {#2} {#3} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_round_places:nnnnnnn} +% \begin{macro}[EXP]{\@@_round_places_end:nn} +% \begin{macro}[EXP]{\@@_round_places_decimal:nn, \@@_round_places_integer:nn} +% \begin{macro}[EXP]{\@@_round_places_finalise:n} +% \begin{macro}[EXP]{\@@_round_places_finalise:nnnnnnn} +% \begin{macro}[EXP]{\@@_round_places_finalise:nnnnn} +% The first step when rounding to a fixed number of places is to establish +% if this is in the decimal or integer parts. The two require different +% calculations for how many digits to drop from the input. The no-op end +% function here is to allow tidying up in some cases: see the finalisation +% of rounding. +% \begin{macrocode} +\cs_new:Npn \@@_round_places:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_if_blank:nTF {#5} + { + \exp_args:Ne \@@_round_places_finalise:n + { + \exp_not:n { {#1} {#2} } + \int_compare:nNnTF \l_@@_round_precision_int > 0 + { \@@_round_places_decimal:nn } + { \@@_round_places_integer:nn } + {#3} {#4} + \@@_round_places_end:nn {#6} {#7} + } + } + { \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#7} } } + } +\cs_new:Npn \@@_round_places_end:nn #1#2 { { } \exp_not:n { {#1} {#2} } } +\cs_new:Npn \@@_round_places_decimal:nn #1#2 + { + \int_compare:nNnTF + { \l_@@_round_precision_int - 0 \tl_count:n {#2} } > 0 + { + \@@_round_pad:nnn + { \l_@@_round_precision_int - 0 \tl_count:n {#2} } + {#1} {#2} + } + { + \@@_round:fnn + { + \int_eval:n + { 0 \tl_count:n {#2} - \l_@@_round_precision_int } + } + {#1} {#2} + } + } +\cs_new:Npn \@@_round_places_integer:nn #1#2 + { + \@@_round:fnn + { + \int_eval:n + { 0 \tl_count:n {#2} - \l_@@_round_precision_int } + } + {#1} {#2} + } +% \end{macrocode} +% To finalise rounding to places, we have to worry about a minimum value: +% that is basically a case of looking for value of zero and rearranging. We +% also need to worry about a \enquote{negative zero} arising. +% \begin{macrocode} +\cs_new:Npn \@@_round_places_finalise:n #1 + { \@@_round_places_finalise:nnnnnnn #1 } +\cs_new:Npn \@@_round_places_finalise:nnnnnnn #1#2#3#4#5#6#7 + { + \bool_lazy_and:nnTF + { \str_if_eq_p:nn {#3} { 0 } } + { + \str_if_eq_p:ee + { \exp_not:n {#4} } { \prg_replicate:nn { \tl_count:n {#4} } { 0 } } + } + { + \tl_if_empty:NTF \l_@@_round_min_tl + { + \exp_not:n { {#1} } + { \str_if_eq:nnF {#2} { - } { \exp_not:n {#2} } } + \exp_not:n { {#3} {#4} {#5} {#6} {#7} } + } + { + \exp_after:wN \@@_round_places_finalise:nnnnn + \l_@@_round_min_tl {#2} {#6} {#7} + } + } + { \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#7} } } + } +\cs_new:Npn \@@_round_places_finalise:nnnnn #1#2#3#4#5 + { + { + \str_if_eq:nnTF {#3} { - } + { > } + { < } + } + \exp_not:n { {#3} {#1} {#2} { } {#4} {#5} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_round_uncertainty:nnnnnnn} +% \begin{macro}[EXP]{\@@_round_uncertainty:nnn} +% \begin{macro}[EXP]{\@@_round_uncertainty:nnnnn} +% Rounding to an uncertainty can only happen where the result will have some +% uncertainty left: otherwise we simply drop the uncertainty entirely. Only +% |S|-type uncertainties can be used for rounding. +% \begin{macrocode} +\cs_new:Npn \@@_round_uncertainty:nnnnnnn #1#2#3#4#5#6#7 + { + \bool_lazy_or:nnTF + { \tl_if_blank_p:n {#5} } + { ! \int_compare_p:nNn \l_@@_round_precision_int > 0 } + { \exp_not:n { {#1} #2 {#3} {#4} { } #6 {#7} } } + { + \str_if_eq:eeTF { \tl_head:n {#5} } { S } + { + \exp_not:n { {#1} {#2} } + \exp_args:Nnno \@@_round_uncertainty:nnn + {#3} {#4} { \use_ii:nn #5 } + \exp_not:n { {#6} {#7} } + } + { \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#7} } } + } + } +% \end{macrocode} +% Round the uncertainty first: this is needed to get the number of places +% correct (for the case where the uncertainty rounds up to |1...|). Once that +% is done, it's just a question of working out the digits in the main part. +% \begin{macrocode} +\cs_new:Npn \@@_round_uncertainty:nnn #1#2#3 + { + \exp_last_unbraced:Nf \@@_round_uncertainty:nnnnn + { + \@@_round:fnn + { \tl_count:n {#3} - \l_@@_round_precision_int } { } {#3} + } + {#1} {#2} {#3} + } +\cs_new:Npn \@@_round_uncertainty:nnnnn #1#2#3#4#5 + { + \tl_if_blank:nTF {#1} + { + \@@_round:fnn + { \tl_count:n {#5} - \tl_count:n {#2} } {#3} {#4} + { { S } {#2} } + } + { + \@@_round:fnn + { \tl_count:n {#5} - \tl_count:n {#2} + 1 } {#3} {#4} + { { S } { #1 \@@_round_truncate_direct:n {#2} } } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_zero_decimal:NN} +% \begin{macro}[EXP]{\@@_zero_decimal:nnnnnnn} +% Simple stripping of the decimal part if zero. +% \begin{macrocode} +\cs_new_protected:Npn \@@_zero_decimal:NN #1#2 + { + \bool_if:NT \l_@@_drop_zero_decimal_bool + { + \tl_set:Nx #2 + { \exp_after:wN \@@_zero_decimal:nnnnnnn #1 } + } + } +\cs_new:Npn \@@_zero_decimal:nnnnnnn #1#2#3#4#5#6#7 + { + \exp_not:n { {#1} {#2} {#3} } + \str_if_eq:eeTF + { \exp_not:n {#4} } + { \prg_replicate:nn { \tl_count:n {#4} } { 0 } } + { { } } + { \exp_not:n { {#4} } } + \exp_not:n { {#5} {#6} {#7} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Number modification} +% +% \begin{macro}[rEXP]{\siunitx_number_adjust_exponent:nn} +% \begin{macro}[rEXP]{\siunitx_number_adjust_exponent:Nn} +% \begin{macro}[rEXP]{\@@_adjust_exp:nnnnnnnn} +% \begin{macro}[rEXP]{\@@_adjust_exp:nn} +% \begin{macro}[rEXP]{\@@_adjust_exp:nNw} +% A simply case of breaking down and rebuilding the number. +% \begin{macrocode} +\cs_new:Npn \siunitx_number_adjust_exponent:nn #1#2 + { \@@_adjust_exp:nnnnnnnn #1 {#2} } +\cs_new:Npn \siunitx_number_adjust_exponent:Nn #1#2 + { + \tl_if_empty:NF #1 + { \exp_args:NV \siunitx_number_adjust_exponent:nn #1 {#2} } + } +\cs_new:Npn \@@_adjust_exp:nnnnnnnn #1#2#3#4#5#6#7#8 + { + \exp_not:n { {#1} {#2} {#3} {#4} {#5} } + \exp_args:Ne \@@_adjust_exp:nn { \fp_eval:n { #6#7 + #8 } } {#6} + } +\cs_new:Npn \@@_adjust_exp:nn #1#2 + { \@@_adjust_exp:nNw {#2} #1 \q_stop } +\cs_new:Npn \@@_adjust_exp:nNw #1#2#3 \q_stop + { + \token_if_eq_meaning:NNTF #2 - + { { - } { \exp_not:n {#3} } } + { { \str_if_eq:nnT {#1} { + } { + } } { \exp_not:n {#2#3} } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Outputting parsed numbers} +% +% \begin{variable}{\l_@@_bracket_close_tl, \l_@@_bracket_open_tl} +% Purely internal for the present. +% \begin{macrocode} +\tl_new:N \l_@@_bracket_close_tl +\tl_new:N \l_@@_bracket_open_tl +\tl_set:Nn \l_@@_bracket_open_tl { ( } +\tl_set:Nn \l_@@_bracket_close_tl { ) } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_siunitx_number_bracket_ambiguous_bool} +% \begin{macrocode} +\bool_new:N \l_siunitx_number_bracket_ambiguous_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_siunitx_number_output_decimal_tl} +% \begin{macrocode} +\tl_new:N \l_siunitx_number_output_decimal_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_@@_bracket_negative_bool , +% \l_@@_implicit_plus_bool , +% \l_@@_exponent_base_tl , +% \l_@@_exponent_product_tl , +% \l_@@_group_decimal_bool , +% \l_@@_group_integer_bool , +% \l_@@_group_minimum_int , +% \l_@@_group_separator_tl , +% \l_@@_negative_color_tl , +% \l_@@_output_uncert_close_tl , +% \l_@@_output_uncert_open_tl , +% \l_@@_uncert_mode_tl , +% \l_@@_uncert_separator_tl , +% \l_@@_tight_bool , +% \l_@@_unity_mantissa_bool , +% \l_@@_zero_exponent_bool +% } +% Keys producing tokens in the output. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + bracket-ambiguous-numbers .bool_set:N = + \l_siunitx_number_bracket_ambiguous_bool , + bracket-negative-numbers .bool_set:N = + \l_@@_bracket_negative_bool , + exponent-base .tl_set:N = + \l_@@_exponent_base_tl , + exponent-product .tl_set:N = + \l_@@_exponent_product_tl , + group-digits .choice: , + group-digits / all .code:n = + { + \bool_set_true:N \l_@@_group_decimal_bool + \bool_set_true:N \l_@@_group_integer_bool + } , + group-digits / decimal .code:n = + { + \bool_set_true:N \l_@@_group_decimal_bool + \bool_set_false:N \l_@@_group_integer_bool + } , + group-digits / integer .code:n = + { + \bool_set_false:N \l_@@_group_decimal_bool + \bool_set_true:N \l_@@_group_integer_bool + } , + group-digits / none .code:n = + { + \bool_set_false:N \l_@@_group_decimal_bool + \bool_set_false:N \l_@@_group_integer_bool + } , + group-digits .default:n = all , + group-minimum-digits .int_set:N = + \l_@@_group_minimum_int , + group-separator .tl_set:N = + \l_@@_group_separator_tl , + negative-color .tl_set:N = + \l_@@_negative_color_tl , + output-close-uncertainty .tl_set:N = + \l_@@_output_uncert_close_tl , + output-decimal-marker .tl_set:N = + \l_siunitx_number_output_decimal_tl , + output-open-uncertainty .tl_set:N = + \l_@@_output_uncert_open_tl , + print-implicit-plus .bool_set:N = + \l_@@_implicit_plus_bool , + print-unity-mantissa .bool_set:N = + \l_@@_unity_mantissa_bool , + print-zero-exponent .bool_set:N = + \l_@@_zero_exponent_bool , + tight-spacing .bool_set:N = + \l_@@_tight_bool , + uncertainty-mode .choices:nn = + { compact , compact-marker , full , separate } + { \tl_set_eq:NN \l_@@_uncert_mode_tl \l_keys_choice_tl } , + uncertainty-separator .tl_set:N = + \l_@@_uncert_separator_tl + } +\bool_new:N \l_@@_group_decimal_bool +\bool_new:N \l_@@_group_integer_bool +\tl_new:N \l_@@_uncert_mode_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[rEXP]{\siunitx_number_output:N} +% \begin{macro}[rEXP]{\siunitx_number_output:n} +% \begin{macro}[rEXP]{\siunitx_number_output:NN} +% \begin{macro}[rEXP]{\siunitx_number_output:nN} +% \begin{macro}[rEXP]{\@@_output:Nn} +% \begin{macro}[rEXP]{\@@_output:nn} +% \begin{macro}[rEXP]{\@@_output:nnnnnnn} +% \begin{macro}[rEXP]{\@@_output_bracket:nn} +% \begin{macro}[rEXP]{\@@_output_bracket:w} +% \begin{macro}[rEXP]{\@@_output_comparator:nn} +% \begin{macro}[rEXP]{\@@_output_sign:nnn} +% \begin{macro}[rEXP]{\@@_output_sign:nN} +% \begin{macro}[rEXP]{\@@_output_sign:N} +% \begin{macro}[rEXP] +% {\@@_output_sign_color:w, \@@_output_sign_brackets:w} +% \begin{macro}[rEXP]{\@@_output_integer:nnn} +% \begin{macro}[rEXP]{\@@_output_decimal:nn, \@@_output_decimal:fn} +% \begin{macro}[rEXP]{\@@_output_digits:nn} +% \begin{macro}[rEXP]{\@@_output_integer_aux:n} +% \begin{macro}[rEXP] +% { +% \@@_output_integer_aux_0:n, +% \@@_output_integer_aux_1:n, +% \@@_output_integer_aux_2:n +% } +% \begin{macro}[rEXP]{\@@_output_decimal_aux:n} +% \begin{macro}[rEXP]{\@@_output_decimal_loop:NNNN} +% \begin{macro}[rEXP]{\@@_output_integer_first:nnNN} +% \begin{macro}[rEXP]{\@@_output_integer_loop:NNNN} +% \begin{macro}[rEXP]{\@@_output_uncertainty:nnn} +% \begin{macro}[rEXP]{\@@_output_uncertainty_unaligned:n} +% \begin{macro}[rEXP]{\@@_output_uncert_S:nnnw} +% \begin{macro}[rEXP] +% {\@@_output_uncert_S_aux:nnn, \@@_output_uncert_S_aux:fnn} +% \begin{macro}[rEXP] +% {\@@_output_uncert_S:nnnw, \@@_output_uncert_S:fnw} +% \begin{macro}[rEXP]{\@@_output_uncert_S:nnw} +% \begin{macro}[rEXP] +% { +% \@@_output_uncert_S_compact:nn , +% \@@_output_uncert_S_compact-marker:nn , +% \@@_output_uncert_S_full:nn +% } +% \begin{macro}[rEXP]{\@@_output_exponent:nnnn} +% \begin{macro}[rEXP]{\@@_output_end:} +% The approach to formatting a single number is to split into +% the constituent parts. All of the parts are assembled including +% inserting tabular alignment markers (which may be empty) for each +% separate unit. +% \begin{macrocode} +\cs_new:Npn \siunitx_number_output:N #1 + { \@@_output:Nn #1 { } } +\cs_new:Npn \siunitx_number_output:n #1 + { \@@_output:nn #1 { } } +\cs_new:Npn \siunitx_number_output:NN #1#2 + { \@@_output:Nn #1 {#2} } +\cs_new:Npn \siunitx_number_output:nN #1#2 + { \@@_output:nn #1 {#2} } +\cs_new:Npn \@@_output:Nn #1#2 + { + \tl_if_empty:NF #1 + { \exp_after:wN \@@_output:nnnnnnn #1 {#2} } + } +\cs_new:Npn \@@_output:nn #1#2 + { + \tl_if_empty:nF {#1} + { \@@_output:nnnnnnn #1 {#2} } + } +\cs_new:Npn \@@_output:nnnnnnn #1#2#3#4#5#6#7#8 + { + \@@_output_comparator:nn {#1} {#8} + \@@_output_bracket:nn {#5} {#7} + \@@_output_sign:nnn {#1} {#2} {#8} + \@@_output_integer:nnn {#3} {#4} {#7} + \@@_output_decimal:nn {#4} {#8} + \@@_output_uncertainty:nnn {#5} {#4} {#8} + \@@_output_exponent:nnnn {#6} {#7} { #3 . #4 } {#8} + \@@_output_end: + } +% \end{macrocode} +% Adding brackets for the combination of a separate uncertainty with an +% exponent may need brackets. This needs testing up-front, so has to come +% before the main formatting routines. +% \begin{macrocode} +\cs_new:Npn \@@_output_bracket:nn #1#2 + { + \bool_lazy_all:nT + { + { \str_if_eq_p:Vn \l_@@_uncert_mode_tl { separate } } + { \l_siunitx_number_bracket_ambiguous_bool } + { ! \tl_if_blank_p:n {#1} } + { + \bool_lazy_or_p:nn + { \l_@@_zero_exponent_bool } + { ! \str_if_eq_p:nn {#2} { 0 } } + } + } + \@@_output_bracket:w + } +\cs_new:Npn \@@_output_bracket:w #1 \@@_output_exponent:nnnn + { + \exp_not:V \l_@@_bracket_open_tl + #1 + \exp_not:V \l_@@_bracket_close_tl + \@@_output_exponent:nnnn + } +% \end{macrocode} +% To get the spacing correct this needs to be an ordinary math character. +% \begin{macrocode} +\cs_new:Npn \@@_output_comparator:nn #1#2 + { + \tl_if_blank:nF {#1} + { \exp_not:n { \mathord {#1} } } + \exp_not:n {#2} + } +% \end{macrocode} +% Formatting signs has to deal with some additional formatting requirements +% for negative numbers. Both making such numbers a fixed color and bracketing +% them needs some rearrangement of the order of tokens, which is set up in +% the main formatting macro by the dedicated do-nothing end function. We +% also have the comparator passed here: if it is present, we need to deal +% with tighter spacing. +% \begin{macrocode} +\cs_new:Npn \@@_output_sign:nnn #1#2#3 + { + \tl_if_blank:nTF {#2} + { + \bool_if:NT \l_@@_implicit_plus_bool + { \@@_output_sign:nN {#1} + } + } + { + \str_if_eq:nnTF {#2} { - } + { + \tl_if_empty:NF \l_@@_negative_color_tl + { \@@_output_sign_color:w } + \bool_if:NTF \l_@@_bracket_negative_bool + { \@@_output_sign_brackets:w } + { \@@_output_sign:nN {#1} #2 } + } + { \@@_output_sign:nN {#1} #2 } + } + \exp_not:n {#3} + } +\cs_new:Npn \@@_output_sign:nN #1#2 + { + \tl_if_blank:nTF {#1} + { \@@_output_sign:N #2 } + { \exp_not:n { \mathord {#2} } } + } +\cs_new:Npn \@@_output_sign:N #1 + { + \bool_if:NTF \l_@@_tight_bool + { \exp_not:n { \mathord {#1} } } + { \exp_not:n {#1} } + } +\cs_new:Npn + \@@_output_sign_color:w #1 \@@_output_end: + { + \exp_not:N \textcolor { \exp_not:V \l_@@_negative_color_tl } + { + #1 + \@@_output_end: + } + } +\cs_new:Npn + \@@_output_sign_brackets:w #1 \@@_output_end: + { + \exp_not:V \l_@@_bracket_open_tl + #1 + \exp_not:V \l_@@_bracket_close_tl + \@@_output_end: + } +% \end{macrocode} +% Digit formatting leads off with separate functions to allow for a few +% \enquote{up front} items before using a common set of tests for some common +% cases. The code then splits again as the two types of grouping need +% different strategies. +% \begin{macrocode} +\cs_new:Npn \@@_output_integer:nnn #1#2#3 + { + \bool_lazy_all:nF + { + { \str_if_eq_p:nn {#1} { 1 } } + { \tl_if_blank_p:n {#2} } + { ! \str_if_eq_p:nn {#3} { 0 } } + { ! \l_@@_unity_mantissa_bool } + } + { \@@_output_digits:nn { integer } {#1} } + } +\cs_new:Npn \@@_output_decimal:nn #1#2 + { + \exp_not:n {#2} + \tl_if_blank:nF {#1} + { + \str_if_eq:VnTF \l_siunitx_number_output_decimal_tl { , } + { \exp_not:N \mathord } + { \use:n } + { \exp_not:V \l_siunitx_number_output_decimal_tl } + } + \exp_not:n {#2} + \@@_output_digits:nn { decimal } {#1} + } +\cs_generate_variant:Nn \@@_output_decimal:nn { f } +\cs_new:Npn \@@_output_digits:nn #1#2 + { + \bool_if:cTF { l_@@_group_ #1 _ bool } + { + \int_compare:nNnTF + { \tl_count:n {#2} } < \l_@@_group_minimum_int + { \exp_not:n {#2} } + { \use:c { @@_output_ #1 _aux:n } {#2} } + } + { \exp_not:n {#2} } + } +% \end{macrocode} +% For integers, we need to know how many digits there are to allow for the +% correct insertion of separators. That is done using a two-part set up such +% that there is no separator on the first pass. +% \begin{macrocode} +\cs_new:Npn \@@_output_integer_aux:n #1 + { + \use:c + { + @@_output_integer_aux_ + \int_eval:n { \int_mod:nn { \tl_count:n {#1} } { 3 } } + :n + } {#1} + } +\cs_new:cpn { @@_output_integer_aux_0:n } #1 + { \@@_output_integer_first:nnNN #1 \q_nil } +\cs_new:cpn { @@_output_integer_aux_1:n } #1 + { \@@_output_integer_first:nnNN { } { } #1 \q_nil } +\cs_new:cpn { @@_output_integer_aux_2:n } #1 + { \@@_output_integer_first:nnNN { } #1 \q_nil } +\cs_new:Npn \@@_output_integer_first:nnNN #1#2#3#4 + { + \exp_not:n {#1#2#3} + \quark_if_nil:NF #4 + { \@@_output_integer_loop:NNNN #4 } + } +\cs_new:Npn \@@_output_integer_loop:NNNN #1#2#3#4 + { + \str_if_eq:VnTF \l_@@_group_separator_tl { , } + { \exp_not:N \mathord } + { \use:n } + { \exp_not:V \l_@@_group_separator_tl } + \exp_not:n {#1#2#3} + \quark_if_nil:NF #4 + { \@@_output_integer_loop:NNNN #4 } + } +% \end{macrocode} +% For decimals, no need to do any counting, just loop using enough markers to +% find the end of the list. By passing the decimal marker, it is possible not +% to have to use a check on the content of the rest of the number. The +% |\use_none:n(n)| mop up the remaining |\q_nil| tokens. +% \begin{macrocode} +\cs_new:Npn \@@_output_decimal_aux:n #1 + { + \@@_output_decimal_loop:NNNN \c_empty_tl + #1 \q_nil \q_nil \q_nil + } +\cs_new:Npn \@@_output_decimal_loop:NNNN #1#2#3#4 + { + \quark_if_nil:NF #2 + { + \exp_not:V #1 + \exp_not:n {#2} + \quark_if_nil:NTF #3 + { \use_none:n } + { + \exp_not:n {#3} + \quark_if_nil:NTF #4 + { \use_none:nn } + { + \exp_not:n {#4} + \@@_output_decimal_loop:NNNN + \l_@@_group_separator_tl + } + } + } + } +% \end{macrocode} +% Uncertainties which are directly attached are easy to deal with. For those +% that are separated, the first step is to find if they are entirely +% contained within the decimal part, and to pad if they are. For the case +% where the boundary is crossed to the integer part, the correct number of +% digit tokens need to be removed from the start of the uncertainty and +% the split result sent to the appropriate auxiliaries. +% \begin{macrocode} +\cs_new:Npn \@@_output_uncertainty:nnn #1#2#3 + { + \tl_if_blank:nTF {#1} + { \@@_output_uncertainty_unaligned:n {#3} } + { + \use:c { @@_output_uncert_ \tl_head:n {#1} :nnnw } + {#2} {#3} #1 + } + } +\cs_new:Npn \@@_output_uncertainty_unaligned:n #1 + { \exp_not:n { #1 #1 #1 #1 } } +\cs_new:Npn \@@_output_uncert_S:nnnw #1#2#3#4 + { + \str_if_eq:VnTF \l_@@_uncert_mode_tl { separate } + { + \exp_not:n {#2} + \@@_output_sign:N \pm + \exp_not:n {#2} + \@@_output_uncert_S_aux:nnn + { \int_eval:n { \tl_count:n {#4} - \tl_count:n {#1} } } + {#4} {#2} + } + { + \exp_not:V \l_@@_uncert_separator_tl + \exp_not:V \l_@@_output_uncert_open_tl + \use:c { @@_output_uncert_S_ \l_@@_uncert_mode_tl :nn } {#1} {#4} + \exp_not:V \l_@@_output_uncert_close_tl + \@@_output_uncertainty_unaligned:n {#2} + } + } +\cs_new:Npn \@@_output_uncert_S_aux:nnn #1#2#3 + { + \int_compare:nNnTF {#1} > 0 + { + \@@_output_uncert_S_aux:fnnw + { \int_eval:n { #1 - 1 } } + {#3} + { } + #2 \q_nil + } + { + 0 + \@@_output_decimal:fn + { + \prg_replicate:nn { \int_abs:n {#1} } { 0 } + #2 + } + {#3} + } + } +\cs_generate_variant:Nn \@@_output_uncert_S_aux:nnn { f } +\cs_new:Npn \@@_output_uncert_S_aux:nnnw #1#2#3#4 + { + \quark_if_nil:NF #4 + { + \int_compare:nNnTF {#1} = 0 + { \@@_output_uncert_S_aux:nnw {#3#4} {#2} } + { + \@@_output_uncert_S_aux:fnnw + { \int_eval:n { #1 - 1 } } + {#2} + {#3#4} + } + } + } +\cs_generate_variant:Nn \@@_output_uncert_S_aux:nnnw { f } +\cs_new:Npn \@@_output_uncert_S_aux:nnw #1#2#3 \q_nil + { + \@@_output_digits:nn { integer } {#1} + \@@_output_decimal:nn {#3} {#2} + } +% \end{macrocode} +% Handle the content of brackets: the only complex case is the +% mixed situation. +% \begin{macrocode} +\cs_new:Npn \@@_output_uncert_S_compact:nn #1#2 + { \exp_not:n {#2} } +\cs_new:cpn { @@_output_uncert_S_compact-marker:nn } #1#2 + { + \bool_lazy_or:nnTF + { \tl_if_blank_p:n {#1} } + { ! \int_compare_p:nNn { \tl_count:n {#2} } > { \tl_count:n {#1} } } + { \@@_output_uncert_S_compact:nn } + { \@@_output_uncert_S_full:nn } + {#1} {#2} + } +\cs_new:Npn \@@_output_uncert_S_full:nn #1#2 + { + \@@_output_uncert_S_aux:fnn + { \int_eval:n { \tl_count:n {#2} - \tl_count:n {#1} } } + {#2} { } + } +% \end{macrocode} +% Setting the exponent part requires some information about the mantissa: +% was it there or not. This means that whilst only the sign and value for +% the exponent are typeset here, there is a need to also have access to the +% combined mantissa part (with a decimal marker). The rest of the work is +% about picking up the various options and getting the combinations right. +% For signs, the auxiliary from the main sign routine can be used, but not +% the main function: negative exponents don't have special handling. +% \begin{macrocode} +\cs_new:Npn \@@_output_exponent:nnnn #1#2#3#4 + { + \exp_not:n {#4} + \bool_lazy_or:nnTF + { \l_@@_zero_exponent_bool } + { ! \str_if_eq_p:nn {#2} { 0 } } + { + \bool_lazy_and:nnTF + { \str_if_eq_p:nn {#3} { 1. } } + { ! \l_@@_unity_mantissa_bool } + { \exp_not:n {#4} } + { + \bool_if:NTF \l_@@_tight_bool + { \exp_not:N \mathord } + { \use:n } + { \exp_not:V \l_@@_exponent_product_tl } + \exp_not:n {#4} + } + \exp_not:V \l_@@_exponent_base_tl + ^ + { + \tl_if_blank:nTF {#1} + { + \bool_if:NT \l_@@_implicit_plus_bool + { \@@_output_sign:N + } + } + { \@@_output_sign:N #1 } + \@@_output_digits:nn { integer } {#2} + } + } + { \exp_not:n {#4} } + } +% \end{macrocode} +% A do-nothing marker used to allow shuffling of the output and so expandable +% operations for formatting. +% \begin{macrocode} +\cs_new:Npn \@@_output_end: { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Miscellaneous tools} +% +% \begin{variable}{\l_@@_valid_tl} +% The list of valid tokens. +% \begin{macrocode} +\tl_new:N \l_@@_valid_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[TF]{\siunitx_if_number:n} +% Test if an entire number is valid: this means parsing the number but not +% returning anything. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \siunitx_if_number:n #1 + { T , F , TF } + { + \group_begin: + \bool_set_true:N \l_@@_validate_bool + \bool_set_true:N \l_siunitx_number_parse_bool + \siunitx_number_parse:nN {#1} \l_@@_parsed_tl + \tl_if_empty:NTF \l_@@_parsed_tl + { + \group_end: + \prg_return_false: + } + { + \group_end: + \prg_return_true: + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF, EXP]{\siunitx_if_number_token:N} +% \begin{macro}[EXP] +% { +% \@@_if_token_auxi:NN , +% \@@_if_token_auxii:NN , +% \@@_if_token_auxiii:NN +% } +% A simple conditional to answer the question of whether a specific token is +% possibly valid in a number. +% \begin{macrocode} +\prg_new_conditional:Npnn \siunitx_if_number_token:N #1 + { p , T , F , TF } + { + \@@_token_auxi:NN #1 + \l_siunitx_number_input_decimal_tl + \l_@@_input_uncert_close_tl + \l_siunitx_number_input_comparator_tl + \l_@@_input_digit_tl + \l_siunitx_number_input_exponent_tl + \l_@@_input_ignore_tl + \l_@@_input_uncert_open_tl + \l_siunitx_number_input_sign_tl + \l_@@_input_uncert_sign_tl + \q_recursion_tail + \q_recursion_stop + } +\cs_new:Npn \@@_token_auxi:NN #1#2 + { + \quark_if_recursion_tail_stop_do:Nn #2 { \prg_return_false: } + \@@_token_auxii:NN #1 #2 + \@@_token_auxi:NN #1 + } +\cs_new:Npn \@@_token_auxii:NN #1#2 + { + \exp_after:wN \@@_token_auxiii:NN \exp_after:wN #1 + #2 \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \@@_token_auxiii:NN #1#2 + { + \quark_if_recursion_tail_stop:N #2 + \str_if_eq:nnT {#1} {#2} + { + \use_i_delimit_by_q_recursion_stop:nw + { + \use_i_delimit_by_q_recursion_stop:nw + { \prg_return_true: } + } + } + \@@_token_auxiii:NN #1 + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macrocode} +\msg_new:nnnn { siunitx } { invalid-number } + { Invalid~number~'#1'. } + { + The~input~'#1'~could~not~be~parsed~as~a~number~following~the~ + format~defined~in~module~documentation. + } +% \end{macrocode} +% +% \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 } + { + bracket-ambiguous-numbers = true , + bracket-negative-numbers = false , + drop-exponent = false , + drop-uncertainty = false , + drop-zero-decimal = false , + evaluate-expression = false , + exponent-base = 10 , + exponent-mode = input , + exponent-product = \times , + expression = #1 , + fixed-exponent = 0 , + group-digits = all , + group-minimum-digits = 4 , + group-separator = \, , % ( + input-close-uncertainty = ) , + input-comparators = { <=>\approx\ge\geq\gg\le\leq\ll\sim } , + input-decimal-markers = { ., } , + input-digits = 0123456789 , + input-exponent-markers = dDeE , + input-ignore = \, , + input-open-uncertainty = ( , % ) + input-signs = +-\mp\pm , + input-uncertainty-signs = \pm , + minimum-decimal-digits = 0 , + minimum-integer-digits = 0 , + negative-color = , % ( + output-close-uncertainty = ) , + output-decimal-marker = . , + output-open-uncertainty = ( , % ) + parse-numbers = true , + print-implicit-plus = false , + print-unity-mantissa = true , + print-zero-exponent = false , + retain-explicit-plus = false , + retain-zero-uncertainty = false , + round-half = up , + round-minimum = 0 , + round-mode = none , + round-pad = true , + round-precision = 2 , + tight-spacing = false , + uncertainty-mode = compact , + uncertainty-separator = + } +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex 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 diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-quantity.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-quantity.dtx new file mode 100644 index 00000000000..930f75c5fc5 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-quantity.dtx @@ -0,0 +1,445 @@ +% \iffalse meta-comment +% +% File: siunitx-quantity.dtx Copyright (C) 2018-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-quantity} -- Quantities^^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 quantities: +% the combination of a number and a unit. It largely builds on the submodules +% \pkg{siunitx-number} and \pkg{siunitx-unit}. A small number of adjustments +% are made to standard set up in the latter to reflect additional functionality +% added here. +% +% \begin{function}{\siunitx_quantity:nn} +% \begin{syntax} +% \cs{siunitx_quantity:nn} \Arg{number} \Arg{unit} +% \end{syntax} +% Parses the \meta{number} and the \meta{unit} as detailed for +% \cs{siunitx_number_parse:nN} and \cs{siunitx_unit_format:nN}, +% the prints the results using \cs{siunitx_print_unit:n}. +% \end{function} +% +% \begin{function} +% { +% \siunitx_quantity_print:nn, \siunitx_quantity_print:nV, +% \siunitx_quantity_print:VV, \siunitx_quantity_print:xV +% } +% \begin{syntax} +% \cs{siunitx_quantity_print:nn} \Arg{number} \Arg{unit} +% \end{syntax} +% A low-level function which prints the quantity directly: there is +% no processing applied to either the \meta{number} or \meta{unit}. The +% two parts are printed using \cs{siunitx_print_unit:n} and appropriate +% spacing and break-prevention is applied. +% \end{function} +% +% \begin{function}{allow-quantity-breaks} +% \begin{syntax} +% |allow-quantity-breaks| = |true|\verb"|"|false| +% \end{syntax} +% Specifies whether breaks are permitted between units. The standard setting +% is |false|. +% \end{function} +% +% \begin{function}{prefix-mode} +% \begin{syntax} +% |prefix-mode| = |combine-exponent|\verb"|"|extract-exponent|\verb"|"|input| +% \end{syntax} +% Selects the method used for producing prefixes: a choice from the options +% |combine-exponent|, |extract-exponent| and |input|. The option +% |combine-exponent| combines any exponent from the number with the prefix +% of the first unit, and prints the updated prefix. The option +% |extract-exponent| removes all prefixes from the unit, and combines them +% with the exponent of number. The option |input| prints prefixes and +% exponent as given in the source. The standard setting is |input|. +% \end{function} +% +% \begin{function}{quantity-product} +% \begin{syntax} +% |quantity-product| = \meta{tokens} +% \end{syntax} +% The product marker used between a number and the unit. The standard setting +% is~\cs{,}. +% \end{function} +% +% \begin{function}{separate-uncertainty-units} +% \begin{syntax} +% |separate-uncertainty-units| = |bracket|\verb"|"|repeat|\verb"|"|single| +% \end{syntax} +% Specifies how units are applied when a separated uncertainty is present: +% a choice from |bracket|, |repeat| and |single|. The option |bracket| places +% brackets around the number, with the unit given after these. The option +% |repeat| means that the unit it printed with the main value and with the +% uncertainty. When |single| is set, the unit is printed only once and no +% brackets are applied. The standard setting is |bracket|. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-quantity} 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_quantity> +% \end{macrocode} +% +% \subsection{Initial set-up} +% +% \begin{variable}{\l_@@_tmp_fp, \l_@@_tmp_tl} +% Scratch space. +% \begin{macrocode} +\tl_new:N \l_@@_tmp_fp +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{variable} +% +% \subsection{Main formatting routine} +% +% \begin{variable}{\l_@@_bracket_close_tl, \l_@@_bracket_open_tl} +% Purely internal for the present. +% \begin{macrocode} +\tl_new:N \l_@@_bracket_close_tl +\tl_new:N \l_@@_bracket_open_tl +\tl_set:Nn \l_@@_bracket_open_tl { ( } +\tl_set:Nn \l_@@_bracket_close_tl { ) } +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_siunitx_quantity_prefix_mode_tl , +% \l_@@_break_bool , +% \l_@@_product_tl , +% \l_@@_uncert_bracket_bool , +% \l_@@_uncert_repeat_bool +% } +% \begin{macrocode} +\tl_new:N \l_siunitx_quantity_prefix_mode_tl +\bool_new:N \l_@@_uncert_bracket_bool +\bool_new:N \l_@@_uncert_repeat_bool +\keys_define:nn { siunitx } + { + allow-quantity-breaks .bool_set:N = + \l_@@_break_bool , + prefix-mode .choices:nn = + { combine-exponent , extract-exponent , input } + { \tl_set_eq:NN \l_siunitx_quantity_prefix_mode_tl \l_keys_choice_tl } , + quantity-product .tl_set:N = + \l_@@_product_tl , + separate-uncertainty-units .choice: , + separate-uncertainty-units / bracket .code:n = + { + \bool_set_true:N \l_@@_uncert_bracket_bool + \bool_set_false:N \l_@@_uncert_repeat_bool + } , + separate-uncertainty-units / repeat .code:n = + { + \bool_set_false:N \l_@@_uncert_bracket_bool + \bool_set_true:N \l_@@_uncert_repeat_bool + } , + separate-uncertainty-units / single .code:n = + { + \bool_set_false:N \l_@@_uncert_bracket_bool + \bool_set_false:N \l_@@_uncert_repeat_bool + } + } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_number_tl, \l_@@_unit_tl} +% \begin{macrocode} +\tl_new:N \l_@@_number_tl +\tl_new:N \l_@@_unit_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_quantity:nn, \@@_parsed:nn} +% \begin{macro}{\@@_parsed_combine-exponent:n, \@@_parsed_combine-exponent:n, \@@_parsed_input:n} +% \begin{macro}{\@@_parsed_aux:w} +% \begin{macro}{\@@_parsed_aux:nnnw} +% \begin{macro}{\@@_parsed_aux:nnnn} +% For quantities, there is bit to do to combine things. The first question is +% whether we are parsing at all: if not, things are quite short. Notice that +% within this group we turn off bracketing in the number formatter: we +% have to deal with quantity-based brackets instead. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_quantity:nn #1#2 + { + \group_begin: + \siunitx_unit_options_apply:n {#2} + \tl_if_blank:nTF {#1} + { + \siunitx_unit_format:nN {#2} \l_@@_unit_tl + \siunitx_print_unit:V \l_@@_unit_tl + } + { + \bool_if:NTF \l_siunitx_number_parse_bool + { \@@_parsed:nn {#1} {#2} } + { + \tl_set:Nn \l_@@_number_tl { \ensuremath {#1} } + \siunitx_unit_format:nN {#2} \l_@@_unit_tl + \siunitx_quantity_print:VV + \l_@@_number_tl \l_@@_unit_tl + } + } + \group_end: + } +% \end{macrocode} +% For parsed numbers, we have two major questions to think about: whether we +% are combining prefixes, and whether we have a multi-part numbers to handle. +% Number processing has to be delayed it needs to come after any extracted +% exponent is combined. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parsed:nn #1#2 + { + \bool_set_false:N \l_siunitx_number_bracket_ambiguous_bool + \siunitx_number_parse:nN {#1} \l_@@_number_tl + \use:c { @@_parsed_ \l_siunitx_quantity_prefix_mode_tl :n } {#2} + \tl_set:Nx \l_@@_number_tl + { \siunitx_number_output:NN \l_@@_number_tl \q_nil } + \exp_after:wN \@@_parsed_aux:w \l_@@_number_tl \q_stop + } +\cs_new_protected:cpn { @@_parsed_combine-exponent:n } #1 + { + \siunitx_number_process:NN \l_@@_number_tl \l_@@_number_tl + \exp_args:NV \@@_extract_exp:nNN + \l_@@_number_tl \l_@@_tmp_fp \l_@@_number_tl + \siunitx_unit_format_combine_exponent:nnN {#1} + \l_@@_tmp_fp \l_@@_unit_tl + } +\cs_new_protected:cpn { @@_parsed_extract-exponent:n } #1 + { + \siunitx_unit_format_extract_prefixes:nNN {#1} + \l_@@_unit_tl \l_@@_tmp_fp + \tl_set:Nx \l_@@_number_tl + { + \siunitx_number_adjust_exponent:Nn + \l_@@_number_tl \l_@@_tmp_fp + } + \siunitx_number_process:NN \l_@@_number_tl \l_@@_number_tl + } +\cs_new_protected:Npn \@@_parsed_input:n #1 + { + \siunitx_number_process:NN \l_@@_number_tl \l_@@_number_tl + \siunitx_unit_format:nN {#1} \l_@@_unit_tl + } +% \end{macrocode} +% To find out if we need to work harder, we first need to split the formatted +% number into the constituent parts. That is done using the table-like +% approach: that avoids needing to both check the settings and break down +% the input separately. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parsed_aux:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_nil + #8 \q_nil #9 \q_stop + { \@@_parsed_aux:nnnw {#1} {#2#3#4#5} {#6#7#8} #9 \q_stop } +\cs_new_protected:Npn \@@_parsed_aux:nnnw + #1#2#3 #4 \q_nil #5 \q_nil #6 \q_stop + { \@@_parsed_aux:nnnn {#1} {#2} {#3#4} {#5#6} } +\cs_new_protected:Npn \@@_parsed_aux:nnnn #1#2#3#4 + { + \tl_if_blank:nTF {#3} + { \siunitx_quantity_print:nV {#1#2#4} \l_@@_unit_tl } + { + \bool_if:NTF \l_@@_uncert_bracket_bool + { + \siunitx_quantity_print:xV + { + \exp_not:n {#1} + \exp_not:V \l_@@_bracket_open_tl + \exp_not:n {#2#3} + \exp_not:V \l_@@_bracket_close_tl + \exp_not:n {#4} + } + \l_@@_unit_tl + } + { + \bool_if:NTF \l_@@_uncert_repeat_bool + { + \siunitx_quantity_print:nV {#1#2} + \l_@@_unit_tl + \siunitx_quantity_print:nV { { } #3 } + \l_@@_unit_tl + \siunitx_print_number:n { { } #4 } + } + { \siunitx_quantity_print:nV {#1#2#3#4} \l_@@_unit_tl } + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_extract_exp:nNN} +% \begin{macro}{\@@_extract_exp:nnnnnnnNN} +% To extract the exponent part for a combined prefix, we decompose the value +% and remove it. +% \begin{macrocode} +\cs_new_protected:Npn \@@_extract_exp:nNN #1#2#3 + { \@@_extract_exp:nnnnnnnNN #1 #2 #3 } +\cs_new_protected:Npn \@@_extract_exp:nnnnnnnNN #1#2#3#4#5#6#7#8#9 + { + \fp_set:Nn #8 {#6#7} + \tl_set:Nx #9 + { {#1} {#2} {#3} {#4} {#5} { } { 0 } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% { +% \siunitx_quanity_print:nn, \siunitx_quanity_print:nV, +% \siunitx_quanity_print:VV, \siunitx_quanity_print:xV +% } +% For printing a single part of a quantity. This is needed for compound +% quantities and so is public: that's also the reason for passing both +% argument explicitly. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_quantity_print:nn #1#2 + { + \siunitx_print_number:n {#1} + \tl_if_blank:nF {#2} + { + \tl_use:N \l_@@_product_tl + \bool_if:NTF \l_@@_break_bool + { \penalty \binoppenalty } + { \nobreak } + \siunitx_print_unit:n {#2} + } + } +\cs_generate_variant:Nn \siunitx_quantity_print:nn { nV , VV , xV } +% \end{macrocode} +% \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 } + { + allow-quantity-breaks = false , + prefix-mode = input , + quantity-product = \, , + separate-uncertainty-units = bracket + } +% \end{macrocode} +% +% \subsection{Adjustments to units} +% +% \begin{macro}{\@@_non_latin:n} +% \begin{macro}{\@@_non_latin:nnnn} +% As in \pkg{siunitx-unit}, but internal in both cases as it's rather +% specialised. +% \begin{macrocode} +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_non_latin:n #1 + { \char_generate:nn {#1} { \char_value_catcode:n {#1} } } + } + { + \cs_new:Npn \@@_non_latin:n #1 + { + \exp_last_unbraced:Nf \@@_non_latin:nnnn + { \char_to_utfviii_bytes:n {#1} } + } + \cs_new:Npn \@@_non_latin:nnnn #1#2#3#4 + { + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#1} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#2} { 13 } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\degree} +% The \cs{degree} unit is re-declared here: this is needed for using it +% in quantities. This is done here as it avoids a dependency in +% \pkg{siunitx-unit} on options it does not contain. +% \begin{macrocode} +\siunitx_declare_unit:Nxn \degree + { \@@_non_latin:n { "00B0 } } + { quantity-product = { } } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-symbol.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-symbol.dtx new file mode 100644 index 00000000000..6d67c5a29d1 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-symbol.dtx @@ -0,0 +1,313 @@ +% \iffalse meta-comment +% +% File: siunitx-symbol.dtx Copyright (C) 2018-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} +% 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-symbol} -- Symbol-related settings^^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} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-symbol} 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_symbol> +% \end{macrocode} +% +% \begin{variable}{\l_@@_tmpa_tl, \l_@@_tmpb_tl} +% Scratch space. +% \begin{macrocode} +\tl_new:N \l_@@_tmpa_tl +\tl_new:N \l_@@_tmpb_tl +% \end{macrocode} +% \end{variable} +% +% A small number of commands are needed from the companion fonts when working +% with $8$-bit engines. These are loaded by modern \LaTeXe{} kernel, so for +% older ones, force loading them using \pkg{textcomp}. +% \begin{macrocode} +\AtBeginDocument + { + \cs_if_free:cT { T@TS1 } + { \RequirePackage { textcomp } } + } +% \end{macrocode} +% +% \begin{macro}{\@@_non_latin:n} +% \begin{macro}{\@@_non_latin:nnnn} +% As in \pkg{siunitx-unit}, but internal in both cases as it's rather +% specialised. +% \begin{macrocode} +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_non_latin:n #1 + { \char_generate:nn {#1} { \char_value_catcode:n {#1} } } + } + { + \cs_new:Npn \@@_non_latin:n #1 + { + \exp_last_unbraced:Nf \@@_non_latin:nnnn + { \char_to_utfviii_bytes:n {#1} } + } + \cs_new:Npn \@@_non_latin:nnnn #1#2#3#4 + { + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#1} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#2} { 13 } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_if_replace:NnT} +% A test to see if the unit definition which applies is still one we expect: +% here that means it is just using a (Unicode) codepoint. The comparison +% is string-based as \pkg{unicode-math} (at least) can alter some of them. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \@@_if_replace:Nn #1#2 { T , TF } + { + \group_begin: + \tl_set:Nx \l_@@_tmpa_tl { \@@_non_latin:n {#2} } + \protected@edef \l_@@_tmpa_tl + { \exp_not:N \mathrm { \l_@@_tmpa_tl } } + \keys_set:nn { siunitx } { parse-units = false } + \siunitx_unit_format:nN {#1} \l_@@_tmpb_tl + \str_if_eq:VVTF \l_@@_tmpa_tl \l_@@_tmpb_tl + { + \group_end: + \prg_return_true: + } + { + \group_end: + \prg_return_false: + } + } +% \end{macrocode} +% \end{macro} +% +% At the start of the document, fonts are fixed and the user may have +% altered unit set up. If things are unchanged, we can alter the settings +% such that they use something \enquote{more sensible}. +% \begin{macrocode} +\AtBeginDocument + { + \@@_if_replace:NnT \arcminute { "02B9 } + { + \siunitx_declare_unit:Nn \arcminute + { \exp_not:N \ensuremath { { } ' } } + } + \@@_if_replace:NnT \arcsecond { "02BA } + { + \siunitx_declare_unit:Nn \arcsecond + { \exp_not:N \ensuremath { { } '' } } + } +% \end{macrocode} +% For |\degree|, direct input works in text mode so there is +% only a need to tidy up for math mode. If \pkg{fontspec} is loaded then that +% problem goes away, so nothing needs to be done. +% \begin{macrocode} + \@@_if_replace:NnT \degree { "00B0 } + { + \@ifpackageloaded { fontspec } + { } + { + \siunitx_declare_unit:Nxn \degree + { + \siunitx_print_text:n + { \@@_non_latin:n { "00B0 } } + } + { quantity-product = { } } + } + } +% \end{macrocode} +% For |\degreeCelsius|, much the same to think about but the comparison +% must be done by hand. +% \begin{macrocode} + \group_begin: + \tl_set:Nx \l_@@_tmpa_tl { \@@_non_latin:n { "00B0 } C } + \protected@edef \l_@@_tmpa_tl + { \exp_not:N \mathrm { \l_@@_tmpa_tl } } + \keys_set:nn { siunitx } { parse-units = false } + \siunitx_unit_format:nN { \degreeCelsius } \l_@@_tmpb_tl + \str_if_eq:VVTF \l_@@_tmpa_tl \l_@@_tmpb_tl + { + \group_end: + \@ifpackageloaded { fontspec } + { } + { + \siunitx_declare_unit:Nx \degreeCelsius + { + \siunitx_print_text:n + { \@@_non_latin:n { "00B0 } } C + } + } + } + { \group_end: } +% \end{macrocode} +% For |\ohm|, there is a math mode symbol we can use, so there has to be +% a mode-dependent definition. +% \begin{macrocode} + \@@_if_replace:NnT \ohm { "03A9 } + { + \siunitx_declare_unit:Nx \ohm + { + \exp_not:N \ifmmode + \cs_if_exist:NTF \upOmega + { \exp_not:N \upOmega } + { \exp_not:N \Omega } + \exp_not:N \else + \siunitx_print_text:n + { + \bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { \@@_non_latin:n { "03A9 } } + { \exp_not:N \textohm } + } + \exp_not:N \fi + } + } +% \end{macrocode} +% Only a text mode command is available for |\micro| in the standard +% set up. +% \begin{macrocode} + \@@_if_replace:NnT \micro { "03BC } + { + \siunitx_declare_prefix:Nnx \micro { -6 } + { + \siunitx_print_text:n + { + \bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { \@@_non_latin:n { "00B5 } } + { \exp_not:N \textmu } + } + } + } + } +% \end{macrocode} +% +% For the times symbol, only \LuaTeX{} allows us to use the math mode symbol +% directly. However, that likely won't follow the surrounding font appearance, +% so in all cases we use the |TS1| version for text. Otherwise much the +% same as |\textmu| support. It's hard to check for the product symbol, so +% we just go with it an hope for the best! +% \begin{macrocode} +\AtBeginDocument + { + \group_begin: + \tl_set:Nn \l_@@_tmpa_tl + { { } { } { 2 } { } { } { } { 1 } } + \tl_set:Nx \l_@@_tmpa_tl + { \siunitx_number_output:N \l_@@_tmpa_tl } + \tl_set:Nn \l_@@_tmpb_tl { 2 \times 10 ^ { 1 } } + \tl_if_eq:NNTF \l_@@_tmpa_tl \l_@@_tmpb_tl + { + \group_end: + \keys_set:nn { siunitx } + { + exponent-product = + \ifmmode \times \else \texttimes \fi , + product-symbol = + \ifmmode \times \else \texttimes \fi + } + } + { \group_end: } + } +% \end{macrocode} +% +% \subsection{Bookmark definitions} +% +% Inside PDF strings we disable the text printing function. The definition of +% |\ohm| is also reset as otherwise engine-dependent strings are generated +% (\XeTeX{} and \LuaTeX{} give different outcomes using for example +% |\textohm|). +% \begin{macrocode} +\AtBeginDocument + { + \@ifpackageloaded { hyperref } + { + \exp_args:Nx \pdfstringdefDisableCommands + { + \cs_set_eq:NN \siunitx_print_text:n \exp_not:N \use:n + \siunitx_declare_unit:Nn \exp_not:N \ohm + { \@@_non_latin:n { "03A9 } } + } + } + { } + } +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx new file mode 100644 index 00000000000..d16d2d7780f --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx @@ -0,0 +1,1445 @@ +% \iffalse meta-comment +% +% File: siunitx-table.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-table} -- Formatting numbers in tables^^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{Numbers in tables} +% +% This submodule is concerned with formatting numbers in table cells or +% similar fixed-width contexts. The main function, \cs{siunitx_cell_begin:w}, +% is designed to work with the normal \LaTeXe{} tablular cell construct +% featuring \cs{ignorespaces}. Therefore, if used outside of a \LaTeXe{} +% tabular, it is necessary to provide this token. +% +% \begin{function}{\siunitx_cell_begin:w, \siunitx_cell_end:} +% \begin{syntax} +% \cs{siunitx_cell_begin:w} \meta{preamble} \cs{ignorespaces} +% \meta{content} +% \cs{siunitx_cell_end:} +% \end{syntax} +% Collects the \meta{preamble} and \meta{content} tokens, and determines +% if it is text or a number (as parsed by \cs{siunitx_number_parse:nN}). +% It produces output of a fixed width suitable for alignment in a table, +% although it is not \emph{required} that the code is used within a cell. +% Note that |\ignorespaces| must occur in the \enquote{cell}: it marks +% the end of the \TeX{} |\halign| template. +% \end{function} +% +% \subsection{Key--value options} +% +% The options defined by this submodule are available within the \pkg{l3keys} +% |siunitx| tree. +% +% \begin{function}{table-align-comparator} +% \begin{syntax} +% |table-align-comparator| = |true|\verb"|"|false| +% \end{syntax} +% Switch which determines whether alignment of comparators is attempted +% within table cells. The standard setting is |true|. +% \end{function} +% +% \begin{function}{table-align-exponent} +% \begin{syntax} +% |table-align-exponent| = |true|\verb"|"|false| +% \end{syntax} +% Switch which determines whether alignment of exponents is attempted +% within table cells. The standard setting is |true|. +% \end{function} +% +% \begin{function}{table-align-text-after} +% \begin{syntax} +% |table-align-text-after| = |true|\verb"|"|false| +% \end{syntax} +% Switch which determines whether alignment of text falling after a number +% is attempted within table cells. The standard setting is |true|. +% \end{function} +% +% \begin{function}{table-align-text-before} +% \begin{syntax} +% |table-align-text-before| = |true|\verb"|"|false| +% \end{syntax} +% Switch which determines whether alignment of text falling before a number +% is attempted within table cells. The standard setting is |true|. +% \end{function} +% +% \begin{function}{table-align-uncertainty} +% \begin{syntax} +% |table-align-uncertainty| = |true|\verb"|"|false| +% \end{syntax} +% Switch which determines whether alignment of separated uncertainty values +% is attempted within table cells. The standard setting is |true|. +% \end{function} +% +% \begin{function}{table-alignment} +% \begin{syntax} +% |table-alignment| = |center|\verb"|"|left|\verb"|"|right| +% \end{syntax} +% Selects the alignment of all tabular content with the margins of the table +% cell (or other boundary). See also |table-number-alignment| and +% |table-text-alignment|. The standard setting is |center|. +% \end{function} +% +% \begin{function}{table-alignment-mode} +% \begin{syntax} +% |table-alignment-mode| = |format|\verb"|"|marker|\verb"|"|none| +% \end{syntax} +% Selects the method used to align numbers with the desired position in the +% cell (set by |table-alignment|). When set to |format|, a dedicated +% amount of space is calculated from the |table-format|. When |marker| +% is selected, alignment is carried out symmetrically around the decimal +% marker. Finally, |none| switches off all alignment: numbers are parsed +% and formatted but with no attempt at placement within the cell. The +% standard setting is |marker|. +% \end{function} +% +% \begin{function}{table-auto-round} +% \begin{syntax} +% |table-auto-round| = |true|\verb"|"|false| +% \end{syntax} +% Switch which determines whether numbers are rounded to fit within +% the |table-format| specification (if possible). The standard +% setting is |false|. +% \end{function} +% +% \begin{function}{table-column-width} +% \begin{syntax} +% |table-column-width| = \meta{width} +% \end{syntax} +% Sets the width of the table column used for numbers. This is only used +% when |table-fixed-width| is |true|. +% \end{function} +% +% \begin{function}{table-fixed-width} +% \begin{syntax} +% |table-fixed-width| = |true|\verb"|"|false| +% \end{syntax} +% Switch which determines whether a fixed-width column is used for numbers +% in tables. When |true|, the width is taken from |table-column-width|. The +% standard setting is |false|. +% \end{function} +% +% \begin{function}{table-format} +% \begin{syntax} +% |table-format| = \meta{format} +% \end{syntax} +% Describes the amount of space that should be reserved when +% |table-alignment-mode| is set to |format|. The \meta{format} takes the +% same general form as input for a table cell, with the numerical parts +% describing how many digits to reserve space for. For example, |1.2e3| +% would allow space for one digit in the integer part, two in the decimal +% part and three in the exponent part. Signs can be allowed for using any +% valid input sign, so for example |+1.2 \pm 1.2| would allow for a sign, +% a number with one integer and two decimal digits and a uncertainty of +% the same size. +% \end{function} +% +% \begin{function}{table-number-alignment} +% \begin{syntax} +% |table-number-alignment| = |center|\verb"|"|left|\verb"|"|right| +% \end{syntax} +% Selects the alignment of numerical content with the margins of the table +% cell (or other boundary). See also |table-alignment| and +% |table-text-alignment|. The standard setting is |center|. +% \end{function} +% +% \begin{function}{table-text-alignment} +% \begin{syntax} +% |table-text-alignment| = |center|\verb"|"|left|\verb"|"|right| +% \end{syntax} +% Selects the alignment of non-numerical content with the margins of the +% table cell (or other boundary). See also |table-alignment| and +% |table-number-alignment|. The standard setting is |center|. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-table} 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_table> +% \end{macrocode} +% +% \begin{variable}{\l_@@_tmp_box, \l_@@_tmp_dim, \l_@@_tmp_tl} +% Scratch space. +% \begin{macrocode} +\box_new:N \l_@@_tmp_box +\dim_new:N \l_@@_tmp_dim +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{variable} +% +% \subsection{Interface functions} +% +% \begin{variable}{\l_@@_text_bool} +% Used to track that a cell is purely text. +% \begin{macrocode} +\bool_new:N \l_@@_text_bool +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_cell_begin:w} +% \begin{macro}{\siunitx_cell_end:} +% The start and end of the cell need to deal with the possibility of +% a cell containing only text. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_cell_begin:w + { + \bool_set_false:N \l_@@_text_bool + \bool_if:NTF \l_siunitx_number_parse_bool + { \@@_collect_begin: } + { \@@_direct_begin: } + } +\cs_new_protected:Npn \siunitx_cell_end: + { + \bool_if:NF \l_@@_text_bool + { + \bool_if:NTF \l_siunitx_number_parse_bool + { \@@_collect_end: } + { \@@_direct_end: } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Collecting tokens} +% +% \begin{variable}{\l_@@_collect_tl} +% Space for tokens. +% \begin{macrocode} +\tl_new:N \l_@@_collect_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_collect_begin:} +% \begin{macro}{\@@_collect_begin:w} +% Collecting a tabular cell means doing a token-by-token collection. +% In previous versions of \pkg{siunitx} that was done along with picking +% out the numerical part, but the code flow ends up very tricky. Here, +% therefore, we just collect up the unchanged tokens first. The definition of +% \cs{cr} is used to allow collection of any tokens +% inserted after the main content when dealing with the last cell of a row: +% the \enquote{group} around it is needed to avoid issues with the underlying +% |\halign|. (The approach is based on that in \pkg{collcell}.) Whilst the +% group formed by a cell will normally tidy up |\cr|, we add an extra one as +% the collected material could be a tabular in itself. We use an auxiliary to +% fish out the |\ignorespaces| from the template: that has to go to avoid +% issues with the peek-ahead code (everything before the |#| needs to be +% read \emph{before} the Appendix~D trick gets applied). Some packages +% add additional tokens before the |\ignorespaces|, which are dealt with by +% the delimited argument. +% \begin{macrocode} +\cs_new_protected:Npn \@@_collect_begin: + { + \group_begin: + \tl_clear:N \l_@@_collect_tl + \if_false: { \fi: + \cs_set_protected:Npn \cr + { + \@@_collect_loop: + \tex_cr:D + } + \if_false: } \fi: + \@@_collect_begin:w + } +\cs_new_protected:Npn \@@_collect_begin:w #1 \ignorespaces + { \@@_collect_loop: #1 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_collect_loop:} +% \begin{macro}{\@@_collect_group:n} +% \begin{macro}{\@@_collect_token:N} +% \begin{macro}{\@@_collect_search:NnF} +% \begin{macro}{\@@_collect_search_aux:NNn} +% Collecting up the cell content needs a loop: this is done using +% a |peek| approach as it's most natural. (A slower approach is possible +% using something like the |\text_lowercase:n| loop code.) The set of +% possible tokens is somewhat limited compared to an arbitrary cell +% (\foreign{cf.}~the approach in \pkg{collcell}): the special cases are +% pulled out for manual handling. The flexible lookup approach is more-or-less +% the same idea as in the kernel |case| functions. The |\relax| special case +% covers the case where |\\| has been expanded in an empty cell. +% \begin{macrocode} +\cs_new_protected:Npn \@@_collect_loop: + { + \peek_catcode_ignore_spaces:NTF \c_group_begin_token + { \@@_collect_group:n } + { \@@_collect_token:N } + } +\cs_new_protected:Npn \@@_collect_group:n #1 + { + \tl_put_right:Nn \l_@@_collect_tl { {#1} } + \@@_collect_loop: + } +\cs_new_protected:Npn \@@_collect_token:N #1 + { + \@@_collect_search:NnF #1 + { + \unskip { \@@_collect_loop: } + \end { \tabularnewline \end } + \relax { \relax } + \tabularnewline { \tabularnewline } + \siunitx_cell_end: { \siunitx_cell_end: } + } + { + \tl_put_right:Nn \l_@@_collect_tl {#1} + \@@_collect_loop: + } + } +\AtBeginDocument + { + \@ifpackageloaded { mdwtab } + { + \cs_set_protected:Npn \@@_collect_token:N #1 + { + \@@_collect_search:NnF #1 + { + \@maybe@unskip { \@@_collect_loop: } + \tab@setcr { \@@_collect_loop: } + \unskip { \@@_collect_loop: } + \end { \tabularnewline \end } + \relax { \relax } + \tabularnewline { \tabularnewline } + \siunitx_cell_end: { \siunitx_cell_end: } + } + { + \tl_put_right:Nn \l_@@_collect_tl {#1} + \@@_collect_loop: + } + } + } + { } + } +\cs_new_protected:Npn \@@_collect_search:NnF #1#2#3 + { + \@@_collect_search_aux:NNn #1 + #2 + #1 {#3} + \q_stop + } +\cs_new_protected:Npn \@@_collect_search_aux:NNn #1#2#3 + { + \token_if_eq_meaning:NNTF #1 #2 + { \use_i_delimit_by_q_stop:nw {#3} } + { \@@_collect_search_aux:NNn #1 } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Separating collected material} +% +% The input needs to be divided into numerical tokens and those which appear +% before and after them. This needs a second loop and validation. +% +% \begin{variable}{\l_@@_before_tl, \l_@@_number_tl, \l_@@_after_tl} +% Space for tokens. +% \begin{macrocode} +\tl_new:N \l_@@_before_tl +\tl_new:N \l_@@_number_tl +\tl_new:N \l_@@_after_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_collect_end:} +% \begin{macro}{\@@_collect_end:n} +% \begin{macro}[EXP]{\@@_collect_end_aux:n} +% \begin{macro}[EXP]{\@@_collect_end:w} +% At the end of the cell, escape the group and check for expansion. We +% only do that if the entire content is not a brace group: there is more +% likely to be problematic content in the case of a header. +% \begin{macrocode} +\cs_new_protected:Npn \@@_collect_end: + { + \exp_args:NNV \group_end: + \@@_collect_end:n \l_@@_collect_tl + \exp_args:NV \@@_split:nNNN + \l_@@_collect_tl + \l_@@_before_tl + \l_@@_number_tl + \l_@@_after_tl + \tl_if_empty:NTF \l_@@_number_tl + { \@@_print_text:V \l_@@_before_tl } + { + \@@_print:VVV + \l_@@_before_tl + \l_@@_number_tl + \l_@@_after_tl + } + } +\cs_new_protected:Npn \@@_collect_end:n #1 + { + \str_if_eq:eeTF { \exp_not:n {#1} } + { { \@@_collect_end_aux:n {#1} } } + { \tl_set:Nn } + { \protected@edef } + \l_@@_collect_tl {#1} + } +\cs_new:Npn \@@_collect_end_aux:n #1 + { \exp_after:wN \@@_collect_end:w #1 \q_stop } +\cs_new:Npn \@@_collect_end:w #1 \q_stop + { \exp_not:n {#1} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_split:nNNN} +% \begin{macro}{\@@_split_loop:NNN} +% \begin{macro}{\@@_split_group:NNNn} +% \begin{macro}{\@@_split_token:NNNN} +% Splitting into parts uses the fact that numbers cannot contain groups +% and that we can track where we are up to based on the content of the +% token lists. +% \begin{macrocode} +\cs_new_protected:Npn \@@_split:nNNN #1#2#3#4 + { + \tl_clear:N #2 + \tl_clear:N #3 + \tl_clear:N #4 + \@@_split_loop:NNN #2#3#4 #1 \q_recursion_tail \q_recursion_stop + \@@_split_tidy:N #2 + \@@_split_tidy:N #4 + } +\cs_new_protected:Npn \@@_split_loop:NNN #1#2#3 + { + \peek_catcode_ignore_spaces:NTF \c_group_begin_token + { \@@_split_group:NNNn #1#2#3 } + { \@@_split_token:NNNN #1#2#3 } + } +\cs_new_protected:Npn \@@_split_group:NNNn #1#2#3#4 + { + \tl_if_empty:NTF #2 + { \tl_put_right:Nn #1 { {#4} } } + { \tl_put_right:Nn #3 { {#4} } } + \@@_split_loop:NNN #1#2#3 + } +\cs_new_protected:Npn \@@_split_token:NNNN #1#2#3#4 + { + \quark_if_recursion_tail_stop:N #4 + \tl_if_empty:NTF \l_@@_after_tl + { + \siunitx_if_number_token:NTF #4 + { \tl_put_right:Nn #2 {#4} } + { + \tl_if_empty:NTF #2 + { \tl_put_right:Nn #1 {#4} } + { \tl_put_right:Nn #3 {#4} } + } + } + { \tl_put_right:Nn #3 {#4} } + \@@_split_loop:NNN #1#2#3 + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_split_tidy:N} +% \begin{macro}{\@@_split_tidy:Nn, \@@_split_tidy:NV} +% A quick test for the entire content being surrounded by a set of braces: +% rather than look explicitly, use the fact that a string comparison can +% detect the same thing. The auxiliary is needed to avoid having to go +% \foreign{via} a |:D| function (for the expansion behaviour). +% \begin{macrocode} +\cs_new_protected:Npn \@@_split_tidy:N #1 + { + \tl_if_empty:NF #1 + { \@@_split_tidy:NV #1 #1 } + } +\cs_new_protected:Npn \@@_split_tidy:Nn #1#2 + { + \str_if_eq:onT { \exp_after:wN { \use:n #2 } } {#2} + { \tl_set:No #1 { \use:n #2 } } + } +\cs_generate_variant:Nn \@@_split_tidy:Nn { NV } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Printing numbers in cells: spacing} +% +% Getting the general alignment correct in tables is made more complex than one +% would like by the \pkg{colortbl} package. In the original \LaTeXe{} +% definition, cell material is centred by a construction of the (primitive) +% form +% \begin{verbatim} +% \hfil +% # +% \hfil +% \end{verbatim} +% which only uses \texttt{fil} stretch. That is altered by \pkg{colortbl} to +% broadly +% \begin{verbatim} +% \hskip 0pt plus 0.5fill +% \kern 0pt +% # +% \hskip 0pt plus 0.5fill +% \end{verbatim} +% which means there is \texttt{fill} stretch to worry about and the kern as +% well. +% +% \begin{macro}{\@@_skip:n} +% To prevent combination of skips, a kern is inserted after each one. +% This is best handled as a short auxiliary. +% \begin{macrocode} +\cs_new_protected:Npn \@@_skip:n #1 + { + \skip_horizontal:n {#1} + \tex_kern:D \c_zero_skip + } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\l_@@_column_width_dim, \l_@@_fixed_width_bool} +% Settings which apply to aligned columns in general. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + table-column-width .dim_set:N = + \l_@@_column_width_dim , + table-fixed-width .bool_set:N = + \l_@@_fixed_width_bool + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_align_center:n, \@@_align_left:n, \@@_align_right:n} +% \begin{macro}{\@@_align_auxi:nn, \@@_align_auxii:nn} +% The beginning and end of each table cell have to adjust the position of +% the content using glue. When \pkg{colortbl} is loaded the glue is done in +% two parts: one for our positioning and one to explicitly override that from +% the package. Using a two-step auxiliary chain avoids needing to repeat any +% code and the impact of the extra expansion should be trivial. +% \begin{macrocode} +\cs_new_protected:Npn \@@_align_center:n #1 + { \@@_align_auxi:nn {#1} { 0pt~plus~0.5fill } } +\cs_new_protected:Npn \@@_align_left:n #1 + { \@@_align_auxi:nn {#1} { 0pt } } +\cs_new_protected:Npn \@@_align_right:n #1 + { \@@_align_auxi:nn {#1} { 0pt~plus~1fill } } +\cs_new_protected:Npn \@@_align_auxi:nn #1#2 + { + \bool_if:NTF \l_@@_fixed_width_bool + { \hbox_to_wd:nn \l_@@_column_width_dim } + { \use:n } + { + \@@_skip:n {#2} + #1 + \@@_skip:n { 0pt~plus~1fill - #2 } + } + } +\AtBeginDocument + { + \@ifpackageloaded { colortbl } + { + \cs_new_eq:NN + \@@_align_auxii:nn + \@@_align_auxi:nn + \cs_set_protected:Npn \@@_align_auxi:nn #1#2 + { + \@@_skip:n{ 0pt~plus~-0.5fill } + \@@_align_auxii:nn {#1} {#2} + \@@_skip:n { 0pt~plus~-0.5fill } + } + } + { } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Printing just text} +% +% In cases where there is no numerical part, \pkg{siunitx} allows alignment +% of the \enquote{escaped} text independent of the underlying column type. +% +% \begin{variable}{\l_@@_align_text_tl} +% Alignment is handled using a |tl| as this allows a fast lookup at the +% point of use. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + table-text-alignment .choices:nn = + { center , left , right } + { \tl_set:Nn \l_@@_align_text_tl {#1} } , + } +\tl_new:N \l_@@_align_text_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_print_text:n, \@@_print_text:V} +% Printing escaped text is easy: just place it in correctly in the +% column. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_text:n #1 + { + \bool_set_true:N \l_@@_text_bool + \use:c { @@_align_ \l_@@_align_text_tl :n } {#1} + } +\cs_generate_variant:Nn \@@_print_text:n { V } +% \end{macrocode} +% \end{macro} +% +% \subsection{Number alignment: core ideas} +% +% \begin{variable}{\l_@@_integer_box, \l_@@_decimal_box} +% Boxes for the content before and after the decimal marker. +% \begin{macrocode} +\box_new:N \l_@@_integer_box +\box_new:N \l_@@_decimal_box +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_fil:} +% A primitive renamed. +% \begin{macrocode} +\cs_new_eq:NN \@@_fil: \tex_hfil:D +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_cleanup_decimal:w} +% To remove the excess marker tokens in a decimal part. +% \begin{macrocode} +\cs_new:Npn \@@_cleanup_decimal:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_nil + { #1#2#3#4#5#6#7 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_center_marker:} +% When centering on the decimal marker, the easiest approach is to simply +% re-box the two parts. That is needed whether or not we are parsing numbers, +% so is best as a short auxiliary. +% \begin{macrocode} +\cs_new_protected:Npn \@@_center_marker: + { + \dim_compare:nNnTF + { \box_wd:N \l_@@_integer_box } + > { \box_wd:N \l_@@_decimal_box } + { + \hbox_set_to_wd:Nnn \l_@@_decimal_box + { \box_wd:N \l_@@_integer_box } + { + \hbox_unpack:N \l_@@_decimal_box + \@@_fil: + } + } + { + \hbox_set_to_wd:Nnn \l_@@_integer_box + { \box_wd:N \l_@@_decimal_box } + { + \@@_fil: + \hbox_unpack:N \l_@@_integer_box + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{variable} +% {\l_@@_auto_round_bool, \l_@@_align_mode_tl, \l_@@_align_number_tl} +% Options for tables with defined space. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + table-alignment .meta:n = + { table-number-alignment = #1 , table-text-alignment = #1 }, + table-alignment-mode .choices:nn = + { none , format , marker } + { \tl_set_eq:NN \l_@@_align_mode_tl \l_keys_choice_tl } , + table-auto-round .bool_set:N = + \l_@@_auto_round_bool , + table-format .code:n = + { + \@@_split:nNNN {#1} + \l_@@_before_model_tl + \l_@@_model_tl + \l_@@_after_model_tl + \exp_args:NV \@@_generate_model:n \l_@@_model_tl + \tl_set:Nn \l_@@_align_mode_tl { format } + } , + table-number-alignment .choices:nn = + { center , left , right } + { \tl_set_eq:NN \l_@@_align_number_tl \l_keys_choice_tl } + } +\tl_new:N \l_@@_align_mode_tl +\tl_new:N \l_@@_align_number_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_format_tl, \l_@@_model_tl} +% The input and output versions of the model entry in a table. +% \begin{macrocode} +\tl_new:N \l_@@_format_tl +\tl_new:N \l_@@_before_model_tl +\tl_new:N \l_@@_model_tl +\tl_new:N \l_@@_after_model_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_generate_model:n} +% \begin{macro}{\@@_generate_model:nnnnnnn} +% \begin{macro}[EXP]{\@@_generate_model_S:nnw} +% \begin{macro}[EXP]{\@@_generate_model_S:nnn} +% Creating a model for a table at this stage means parsing the format and +% converting that to an appropriate model. Things are quite straight-forward +% other than the uncertainty part. At this stage there is no point in +% formatting the model: that has to happen at point-of-use. Notice that +% the uncertainty part needs to allow for the case where we cross the +% decimal. +% \begin{macrocode} +\cs_new_protected:Npn \@@_generate_model:n #1 + { + \group_begin: + \bool_set_true:N \l_siunitx_number_parse_bool + \keys_set:nn { siunitx } { retain-explicit-plus = true } + \siunitx_number_parse:nN {#1} \l_@@_format_tl + \exp_args:NNNV \group_end: + \tl_set:Nn \l_@@_format_tl \l_@@_format_tl + \tl_if_empty:NF \l_@@_format_tl + { + \exp_after:wN \@@_generate_model:nnnnnnn + \l_@@_format_tl + } + } +\cs_new_protected:Npn \@@_generate_model:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_set:Nx \l_@@_model_tl + { + \exp_not:n { {#1} {#2} } + { \prg_replicate:nn {#3} { 8 } } + { \prg_replicate:nn { 0 #4 } { 8 } } + { + \tl_if_blank:nF {#5} + { + \use:c { @@_generate_model_ \tl_head:n {#5} :nnw } + {#4} #5 + } + } + \exp_not:n { {#6} } + { + \int_compare:nNnTF {#7} = 0 + { 0 } + { \prg_replicate:nn {#7} { 8 } } + } + } + } +\cs_new:Npn \@@_generate_model_S:nnw #1#2#3 + { + { S } + { + \exp_args:Nff \@@_generate_model_S:nnn + { \tl_count:n {#1} } { \tl_count:n {#3} } + {#3} + } + } +\cs_new:Npn \@@_generate_model_S:nnn #1#2#3 + { + \prg_replicate:nn + { + \int_compare:nNnTF {#2} > {#1} + { + \str_range:nnn {#3} { 1 } {#1} + + + \str_range:nnn {#3} { 1 + #1 } {#2} + } + {#3} + } + { 8 } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Directly printing without collection} +% +% Collecting the number allows for various effects but is not as fast +% as simply aligning on the first token that is a decimal marker. The +% strategy here is that used by \pkg{dcolumn}. +% +% \begin{macro}{\@@_direct_begin:} +% \begin{macro}{\@@_direct_begin:w} +% \begin{macro}{\@@_direct_end:} +% \begin{macro} +% { +% \@@_direct_marker: , +% \@@_direct_marker_switch: , +% \@@_direct_marker_end: +% } +% \begin{macro}{\@@_direct_format:} +% \begin{macro}[EXP]{\@@_direct_format:nnnnnnn} +% \begin{macro}{\@@_direct_format:w} +% \begin{macro} +% { +% \@@_direct_format_switch: , +% \@@_direct_format_end: +% } +% \begin{macro}{\@@_direct_none:, \@@_direct_none_end:} +% After removing the |\ignorespaces| at the start of the cell (see comments +% for \cs{@@_collect_begin:N}), check to see if there is a |{| and branch +% as appropriate. +% \begin{macrocode} +\cs_new_protected:Npn \@@_direct_begin: + { \@@_direct_begin:w } +\cs_new_protected:Npn \@@_direct_begin:w #1 \ignorespaces + { + #1 + \peek_catcode_ignore_spaces:NTF \c_group_begin_token + { \@@_print_text:n } + { + \m@th + \use:c { @@_direct_ \l_@@_align_mode_tl : } + } + } +\cs_new_protected:Npn \@@_direct_end: + { \use:c { @@_direct_ \l_@@_align_mode_tl _end: } } +% \end{macrocode} +% When centring the content about a decimal marker, the trick is +% to collect everything into two boxes and then compare the sizes. +% As we are always in math mode, we can use a math active token +% to make the switch. The up-front setting of the |decimal| box deals +% with the case where there is no decimal part. +% \begin{macrocode} +\cs_new_protected:Npn \@@_direct_marker: + { + \hbox_set:Nn \l_@@_tmp_box + { \ensuremath { \mathord { \l_siunitx_number_output_decimal_tl } } } + \hbox_set_to_wd:Nnn \l_@@_decimal_box + { \box_wd:N \l_@@_tmp_box } + { \@@_fil: } + \hbox_set:Nw \l_@@_integer_box + \c_math_toggle_token + \tl_map_inline:Nn \l_siunitx_number_input_decimal_tl + { + \char_set_active_eq:NN ##1 \@@_direct_marker_switch: + \char_set_mathcode:nn { `##1 } { "8000 } + } + } +\cs_new_protected:Npn \@@_direct_marker_switch: + { + \c_math_toggle_token + \hbox_set_end: + \hbox_set:Nw \l_@@_decimal_box + \c_math_toggle_token + \l_siunitx_number_output_decimal_tl + } +\cs_new_protected:Npn \@@_direct_marker_end: + { + \c_math_toggle_token + \hbox_set_end: + \@@_center_marker: + \box_use_drop:N \l_@@_integer_box + \box_use_drop:N \l_@@_decimal_box + } +% \end{macrocode} +% For the version where there is space reserved, first format and decompose +% that, then create appropriately-sized boxes. +% \begin{macrocode} +\cs_new_protected:Npn \@@_direct_format: + { + \tl_set:Nx \l_@@_tmp_tl + { \siunitx_number_output:NN \l_@@_model_tl \q_nil } + \exp_after:wN \@@_direct_format_aux:w + \l_@@_tmp_tl \q_stop + } +\cs_new_protected:Npn \@@_direct_format_aux:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_stop + { + \hbox_set:Nn \l_@@_tmp_box + { \ensuremath { \@@_cleanup_decimal:w #4 } } + \hbox_set_to_wd:Nnn \l_@@_decimal_box + { \box_wd:N \l_@@_tmp_box } + { \@@_fil: } + \hbox_set:Nn \l_@@_tmp_box { \ensuremath { #1#2#3 } } + \hbox_set_to_wd:Nnw \l_@@_integer_box + { \box_wd:N \l_@@_tmp_box } + \c_math_toggle_token + \tl_map_inline:Nn \l_siunitx_number_input_decimal_tl + { + \char_set_active_eq:NN ##1 \@@_direct_format_switch: + \char_set_mathcode:nn { `##1 } { "8000 } + } + \@@_fil: + } +\cs_new_protected:Npn \@@_direct_format_switch: + { + \c_math_toggle_token + \hbox_set_end: + \hbox_set_to_wd:Nnw \l_@@_decimal_box + { \box_wd:N \l_@@_decimal_box } + \c_math_toggle_token + \mathord { \l_siunitx_number_output_decimal_tl } + } +\cs_new_protected:Npn \@@_direct_format_end: + { + \c_math_toggle_token + \@@_fil: + \hbox_set_end: + \use:c { @@_align_ \l_@@_align_number_tl :n } + { + \box_use_drop:N \l_@@_integer_box + \box_use_drop:N \l_@@_decimal_box + } + } +% \end{macrocode} +% No parsing and no alignment is easy. +% \begin{macrocode} +\cs_new_protected:Npn \@@_direct_none: { \c_math_toggle_token } +\cs_new_protected:Npn \@@_direct_none_end: { \c_math_toggle_token } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Printing numbers in cells: main functions} +% +% \begin{variable}{\l_@@_before_box, \l_@@_after_box} +% For alignment of text outside of a number. +% \begin{macrocode} +\box_new:N \l_@@_before_box +\box_new:N \l_@@_after_box +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_carry_dim} +% Used to \enquote{carry forward} the amount of white space which needs to +% be inserted after the decimal marker. +% \begin{macrocode} +\dim_new:N \l_@@_carry_dim +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_@@_align_comparator_bool , +% \l_@@_align_exponent_bool , +% \l_@@_align_after_bool , +% \l_@@_align_before_bool , +% \l_@@_align_uncertainty_bool +% } +% Alignment is handled using a |tl| as this allows a fast lookup at the +% point of use. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + table-align-comparator .bool_set:N = + \l_@@_align_comparator_bool , + table-align-exponent .bool_set:N = + \l_@@_align_exponent_bool , + table-align-text-after .bool_set:N = + \l_@@_align_after_bool , + table-align-text-before .bool_set:N = + \l_@@_align_before_bool , + table-align-uncertainty .bool_set:N = + \l_@@_align_uncertainty_bool + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_print:nnn, \@@_print:VVV} +% \begin{macro}{\@@_print_marker:nnn} +% \begin{macro}{\@@_print_marker:w} +% \begin{macro}[EXP]{\@@_print_marker_aux:w} +% \begin{macro}{\@@_print_format:nnn} +% \begin{macro} +% { +% \@@_print_marker_auxi:w, +% \@@_print_marker_auxii:w, +% \@@_print_marker_auxiii:w +% } +% \begin{macro}{\@@_print_format_after:N} +% \begin{macro}{\@@_print_format_box:Nn} +% \begin{macro}{\@@_print_none:nnn} +% \begin{macrocode} +\cs_new_protected:Npn \@@_print:nnn #1#2#3 + { \use:c { @@_print_ \l_@@_align_mode_tl :nnn } {#1} {#2} {#3} } +\cs_generate_variant:Nn \@@_print:nnn { VVV } +% \end{macrocode} +% When centering on the decimal marker, alignment is relatively simple, and +% close in concept to that used without parsing. First we need to deal with any +% text before or after the number. For text \emph{before}, there's the case +% where is has no width and might be a font or color change: that has to be +% filtered out first. Then we can adjust the size of this material and that +% after the number such that they are equal. The number itself can then be +% formatted, splitting at he decimal marker. A bit more size adjustment, then +% the number itself and any text at the end can be inserted. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_marker:nnn #1#2#3 + { + \hbox_set:Nn \l_@@_before_box {#1} + \dim_compare:nNnT { \box_wd:N \l_@@_before_box } = { 0pt } + { + \box_clear:N \l_@@_before_box + #1 + } + \hbox_set:Nn \l_@@_after_box {#3} + \dim_compare:nNnTF + { \box_wd:N \l_@@_after_box } + > { \box_wd:N \l_@@_before_box } + { + \hbox_set_to_wd:Nnn \l_@@_before_box + { \box_wd:N \l_@@_after_box } + { + \@@_fil: + \hbox_unpack:N \l_@@_before_box + } + } + { + \hbox_set_to_wd:Nnn \l_@@_after_box + { \box_wd:N \l_@@_before_box } + { + \hbox_unpack:N \l_@@_after_box + \@@_fil: + } + } + \box_use_drop:N \l_@@_before_box + \siunitx_number_parse:nN {#2} \l_@@_tmp_tl + \siunitx_number_process:NN \l_@@_tmp_tl \l_@@_tmp_tl + \tl_set:Nx \l_@@_tmp_tl + { \siunitx_number_output:NN \l_@@_tmp_tl \q_nil } + \exp_after:wN \@@_print_marker:w + \l_@@_tmp_tl \q_stop + \box_use_drop:N \l_@@_after_box + } +\cs_new_protected:Npn \@@_print_marker:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_stop + { + \hbox_set:Nn \l_@@_integer_box + { \siunitx_print_number:n { #1#2#3 } } + \hbox_set:Nn \l_@@_decimal_box + { + \siunitx_print_number:x + { \@@_print_marker_aux:w #4 } + } + \@@_center_marker: + \box_use_drop:N \l_@@_integer_box + \box_use_drop:N \l_@@_decimal_box + } +\cs_new:Npn \@@_print_marker_aux:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_nil + { + \exp_not:n {#1#2#3#4#5} + \tl_if_blank:nT {#1#2#3#4#5} { { } } + \exp_not:n {#6#7} + } +% \end{macrocode} +% For positioning based on a format, we have to work part-by-part as there +% are a number of alignment points to get right. As for the |marker| approach, +% first we check if the material before the numerical content is of zero +% width. Next we need to format the model and content numbers, before +% starting an auxiliary chain to pick out the various parts in order. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_format:nnn #1#2#3 + { + \hbox_set:Nn \l_@@_tmp_box { \l_@@_before_model_tl } + \hbox_set:Nn \l_@@_before_box {#1} + \dim_compare:nNnT { \box_wd:N \l_@@_before_box } = { 0pt } + { + \box_clear:N \l_@@_before_box + #1 + } + \hbox_set_to_wd:Nnn \l_@@_before_box + { \box_wd:N \l_@@_tmp_box } + { + \@@_fil: + \hbox_unpack:N \l_@@_before_box + } + \siunitx_number_parse:nN {#2} \l_@@_tmp_tl + \group_begin: + \bool_if:NT \l_@@_auto_round_bool + { + \exp_args:Nx \keys_set:nn { siunitx } + { + round-mode = places , + round-pad = true , + round-precision = + \exp_after:wN \@@_print_format:nnnnnn + \l_@@_format_tl + } + } + \siunitx_number_process:NN \l_@@_tmp_tl \l_@@_tmp_tl + \exp_args:NNNV \group_end: + \tl_set:Nn \l_@@_tmp_tl \l_@@_tmp_tl + \tl_set:Nx \l_@@_tmp_tl + { + \siunitx_number_output:NN \l_@@_model_tl \q_nil + \exp_not:N \q_mark + \siunitx_number_output:NN \l_@@_tmp_tl \q_nil + } + \exp_after:wN \@@_print_format_auxi:w + \l_@@_tmp_tl \q_stop + \hbox_set:Nn \l_@@_tmp_box { \l_@@_after_model_tl } + \hbox_set_to_wd:Nnn \l_@@_after_box + { \box_wd:N \l_@@_tmp_box + \l_@@_carry_dim } + { + \bool_if:NT \l_@@_align_after_bool + { \skip_horizontal:n { \l_@@_carry_dim } } + #3 + \@@_fil: + } + \use:c { @@_align_ \l_@@_align_number_tl :n } + { + \box_use_drop:N \l_@@_before_box + \box_use_drop:N \l_@@_integer_box + \box_use_drop:N \l_@@_decimal_box + \box_use_drop:N \l_@@_after_box + } + } +\cs_new:Npn \@@_print_format:nnnnnn #1#2#3#4#5#6#7 + { 0 #4 } +% \end{macrocode} +% The first numerical part to handle is the comparator. Any white space we +% need to add goes into the text part \emph{if} alignment is not active +% (\foreign{i.e.}~we are looking \enquote{backwards} to place this filler). +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_format_auxi:w + #1 \q_nil #2 \q_mark #3 \q_nil #4 \q_stop + { + \@@_print_format_box:Nn \l_@@_tmp_box {#1} + \bool_if:NTF \l_@@_align_before_bool + { + \hbox_set_to_wd:Nnn \l_@@_integer_box + { \box_wd:N \l_@@_tmp_box } + { + \@@_fil: + \tl_if_blank:nF {#3} + { \siunitx_print_number:n {#3} } + } + } + { + \@@_print_format_box:Nn \l_@@_integer_box {#3} + \hbox_set_to_wd:Nnn \l_@@_before_box + { + \box_wd:N \l_@@_before_box + + \box_wd:N \l_@@_tmp_box + - \box_wd:N \l_@@_integer_box + } + { + \@@_fil: + \hbox_unpack:N \l_@@_before_box + } + } + \@@_print_format_auxii:w #2 \q_mark #4 \q_stop + } +% \end{macrocode} +% The integer part follows much the same pattern, except now it is control +% of the comparator alignment that determines where the white space goes. +% As we already have content in the |integer| box, we need to measure how +% much \emph{extra} material has been added. To avoid using more boxes +% or re-setting, we do that by recording sizes before and after the change. +% (In effect, \cs{l_@@_tmp_dim} is here \enquote{l_@@_comparator_dim}.) +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_format_auxii:w + #1 \q_nil #2 \q_nil #3 \q_mark #4 \q_nil #5 \q_nil #6 \q_stop + { + \@@_print_format_box:Nn \l_@@_tmp_box {#1#2} + \bool_lazy_and:nnTF + { \l_@@_align_comparator_bool } + { \dim_compare_p:nNn { \box_wd:N \l_@@_integer_box } > { 0pt } } + { + \hbox_set_to_wd:Nnn \l_@@_integer_box + { + \box_wd:N \l_@@_integer_box + + \box_wd:N \l_@@_tmp_box + } + { + \hbox_unpack:N \l_@@_integer_box + \@@_fil: + \siunitx_print_number:n {#4#5} + } + } + { + \bool_if:NTF \l_@@_align_before_bool + { + \hbox_set_to_wd:Nnn \l_@@_integer_box + { + \box_wd:N \l_@@_integer_box + + \box_wd:N \l_@@_tmp_box + } + { + \@@_fil: + \hbox_unpack:N \l_@@_integer_box + \siunitx_print_number:n {#4#5} + } + } + { + \dim_set:Nn \l_@@_tmp_dim + { \box_wd:N \l_@@_integer_box } + \hbox_set:Nn \l_@@_integer_box + { + \hbox_unpack:N \l_@@_integer_box + \siunitx_print_number:n {#4#5} + } + \hbox_set_to_wd:Nnn \l_@@_before_box + { + \box_wd:N \l_@@_before_box + + \box_wd:N \l_@@_tmp_box + + \l_@@_tmp_dim + - \box_wd:N \l_@@_integer_box + } + { + \@@_fil: + \hbox_unpack:N \l_@@_before_box + } + } + } + \@@_print_format_auxiii:w #3 \q_mark #6 \q_stop + } +% \end{macrocode} +% We now deal with the decimal part: there is nothing already in the +% |decimal| box, so the basics are easy. We need to \enquote{carry forward} +% any white space, as where it gets inserted depends on the options for +% subsequent parts. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_format_auxiii:w + #1 \q_nil #2 \q_nil #3 \q_mark #4 \q_nil #5 \q_nil #6 \q_stop + { + \@@_print_format_box:Nn \l_@@_tmp_box {#1#2} + \@@_print_format_box:Nn \l_@@_decimal_box {#4#5} + \dim_set:Nn \l_@@_carry_dim + { + \box_wd:N \l_@@_tmp_box + - \box_wd:N \l_@@_decimal_box + } + \@@_print_format_auxiv:w #3 \q_mark #6 \q_stop + } +% \end{macrocode} +% Any separated uncertainty is now picked up. That has a number of parts, so +% the first step is to look for a sign (which will be |#1|). We then split, +% either simply tidying up the markers if there is no uncertainty, or +% setting it. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_format_auxiv:w + #1 \q_nil #2 \q_mark #3 \q_nil #4 \q_stop + { + \tl_if_blank:nTF {#1} + { \@@_print_format_auxv:w } + { \@@_print_format_auxvi:w } + #1#2 \q_mark #3#4 \q_stop + } +\cs_new_protected:Npn \@@_print_format_auxv:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_mark + #5 \q_nil #6 \q_nil #7 \q_nil #8 \q_stop + { \@@_print_format_auxvii:w #4 \q_mark #8 \q_stop } +% \end{macrocode} +% Sorting out the placement of the uncertainty requires both the model and +% real data widths, so we store the former to avoiding needing more boxes. +% It's then just a case of putting the carry-over white space in the right +% place. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_format_auxvi:w + #1 \q_nil #2 \q_nil #3 \q_nil #4 \q_mark + #5 \q_nil #6 \q_nil #7 \q_nil #8 \q_stop + { + \@@_print_format_box:Nn \l_@@_tmp_box { { } #1#2#3 } + \dim_set:Nn \l_@@_tmp_dim { \box_wd:N \l_@@_tmp_box } + \@@_print_format_box:Nn \l_@@_tmp_box { { } #5#6#7 } + \@@_print_format_after:N \l_@@_align_uncertainty_bool + \@@_print_format_auxvii:w #4 \q_mark #8 \q_stop + } +% \end{macrocode} +% Finally, we get to the exponent part: the multiplication symbol is +% |#1| and the number itself is |#2|. The code is almost the same as for +% uncertainties, which allows a shared auxiliary to be used. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_format_auxvii:w + #1 \q_nil #2 \q_mark #3 \q_nil #4 \q_stop + { + \tl_if_blank:nF {#2} + { + \@@_print_format_box:Nn \l_@@_tmp_box { { } #1#2 } + \dim_set:Nn \l_@@_tmp_dim { \box_wd:N \l_@@_tmp_box } + \@@_print_format_box:Nn \l_@@_tmp_box { { } #3#4 } + \@@_print_format_after:N \l_@@_align_exponent_bool + } + } +% \end{macrocode} +% A simple auxiliary to avoid relatively expensive use of the print routine +% for empty parts. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_format_box:Nn #1#2 + { + \hbox_set:Nn #1 + { + \tl_if_blank:nF {#2} + { \siunitx_print_number:n {#2} } + } + } +% \end{macrocode} +% A common routine for placing material after the decimal marker and +% \enquote{shuffling}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_format_after:N #1 + { + \bool_if:NTF #1 + { + \hbox_set_to_wd:Nnn \l_@@_decimal_box + { + \box_wd:N \l_@@_decimal_box + + \l_@@_carry_dim + + \box_wd:N \l_@@_tmp_box + } + { + \hbox_unpack:N \l_@@_decimal_box + \@@_fil: + \hbox_unpack:N \l_@@_tmp_box + } + \dim_set:Nn \l_@@_carry_dim + { + \l_@@_tmp_dim + - \box_wd:N \l_@@_tmp_box + } + } + { + \hbox_set:Nn \l_@@_decimal_box + { + \hbox_unpack:N \l_@@_decimal_box + \hbox_unpack:N \l_@@_tmp_box + } + \dim_add:Nn \l_@@_carry_dim + { + \l_@@_tmp_dim + - \box_wd:N \l_@@_tmp_box + } + } + } +% \end{macrocode} +% With no alignment, everything supplied is treated more-or-less the +% same as \cs{num} (but without the \pkg{xparse} wrapper). +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_none:nnn #1#2#3 + { + \use:c { @@_align_ \l_@@_align_number_tl :n } + { + #1 + \siunitx_number_format:nN {#2} \l_@@_tmp_tl + \siunitx_print_number:V \l_@@_tmp_tl + #3 + } + } +% \end{macrocode} +% \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 } + { + table-align-comparator = true , + table-align-exponent = true , + table-align-text-after = true , + table-align-text-before = true , + table-align-uncertainty = true , + table-alignment = center , + table-auto-round = false , + table-column-width = 0pt , + table-fixed-width = false , + table-format = 2.2 , + table-number-alignment = center , + table-text-alignment = center , +% \end{macrocode} +% Out of order as |table-format| sets this implicitly too. +% \begin{macrocode} + table-alignment-mode = marker + } +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-unit.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-unit.dtx new file mode 100644 index 00000000000..8eaf45c5ace --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx-unit.dtx @@ -0,0 +1,2795 @@ +% \iffalse meta-comment +% +% File: siunitx-unit.dtx Copyright (C) 2014-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} +\ExplSyntaxOn +\makeatletter +\NewDocumentCommand \acro { m } + { + \textsc + { + \exp_args:NV \tl_if_head_eq_charcode:nNTF \f@series { m } + { \tl_lower_case:n } + { \use:n } + {#1} + } + } +\makeatother +\ExplSyntaxOff +\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-unit} -- Parsing and formatting units^^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 dedicated to formatting physical units. The main function, +% \cs{siunitx_unit_format:nN}, takes user input specify physical units and +% converts it into a formatted token list suitable for typesetting in math +% mode. While the formatter will deal correctly with \enquote{literal} user +% input, the key strength of the module is providing a method to describe +% physical units in a \enquote{symbolic} manner. The output format of these +% symbolic units can then be controlled by a number of key--value options +% made available by the module. +% +% A small number of \LaTeXe{} math mode commands are assumed to be available +% as part of the formatted output. The \cs{mathchoice} command +% (normally the \TeX{} primitive) is needed when using +% |per-mode = symbol-or-fraction|. The commands \cs{frac}, \cs{mathrm}, +% \cs{mbox}, \verb*|\ | and \cs{,} are used by the standard module settings. +% For the display of colored (highlighted) and cancelled units, the commands +% \cs{textcolor} and \cs{cancel} are assumed to be available. +% +% \section{Formatting units} +% +% \begin{function}{\siunitx_unit_format:nN, \siunitx_unit_format:xN} +% \begin{syntax} +% \cs{siunitx_unit_format:nN} \Arg{units} \meta{tl~var} +% \end{syntax} +% This function converts the input \meta{units} into a processed +% \meta{tl~var} which can then be inserted in math mode to typeset the +% material. Where the \meta{units} are given in symbolic form, described +% elsewhere, this formatting process takes place in two stages: the +% \meta{units} are parsed into a structured form before the generation +% of the appropriate output form based on the active settings. When the +% \meta{units} are given as literals, processing is minimal: the +% characters |.| and |~| are converted to unit products (boundaries). +% In both cases, the result is a series of tokens intended to be typeset +% in math mode with appropriate choice of font for typesetting of the +% textual parts. +% +% For example, +% \begin{verbatim} +% \siunitx_unit_format:nN { \kilo \metre \per \second } \l_tmpa_tl +% \end{verbatim} +% will, with standard settings, result in \cs{l_tmpa_tl} being set to +% \begin{verbatim} +% \mathrm{km}\,\mathrm{s}^{-1} +% \end{verbatim} +% \end{function} +% +% \begin{function}{\siunitx_unit_format_extract_prefixes:nNN} +% \begin{syntax} +% \cs{siunitx_unit_format_extract_prefixes:nNN} \Arg{units} \meta{tl~var} \meta{fp~var} +% \end{syntax} +% This function formats the \meta{units} in the same way as described for +% \cs{siunitx_unit_format:nN}. When the input is given in symbolic form, +% any decimal unit prefixes will be extracted and the overall power of +% ten that these represent will be stored in the \meta{fp~var}. +% +% For example, +% \begin{verbatim} +% \siunitx_unit_format_extract_prefixes:nNN { \kilo \metre \per \second } +% \l_tmpa_tl \l_tmpa_fp +% \end{verbatim} +% will, with standard settings, result in \cs{l_tmpa_tl} being set to +% \begin{verbatim} +% \mathrm{m}\,\mathrm{s}^{-1} +% \end{verbatim} +% with \cs{l_tmpa_fp} taking value~$3$. Note that the latter is a floating +% point variable: it is possible for non-integer values to be obtained here. +% \end{function} +% +% \begin{function}{\siunitx_unit_format_combine_exponent:nnN} +% \begin{syntax} +% \cs{siunitx_unit_format_combine_exponent:nnN} \Arg{units} \Arg{exponent} \meta{tl~var} +% \end{syntax} +% This function formats the \meta{units} in the same way as described for +% \cs{siunitx_unit_format:nN}. The \meta{exponent} is combined with any +% prefix for the \emph{first} unit of the \meta{units}, and an updated +% prefix is introduced. +% +% For example, +% \begin{verbatim} +% \siunitx_unit_format_combine_exponent:nnN { \metre \per \second } +% { 3 } \l_tmpa_tl +% \end{verbatim} +% will, with standard settings, result in \cs{l_tmpa_tl} being set to +% \begin{verbatim} +% \mathrm{km}\,\mathrm{s}^{-1} +% \end{verbatim} +% \end{function} +% +% \begin{function} +% { +% \siunitx_unit_format_multiply:nnN , +% \siunitx_unit_format_multiply_extract_prefixes:nnNN , +% \siunitx_unit_format_multiply_combine_exponent:nnnN +% } +% \begin{syntax} +% \cs{siunitx_unit_format_multiply:nnN} \Arg{units} \Arg{factor} \meta{tl~var} +% \cs{siunitx_unit_format_multiply_extract_prefixes:nnNN} +% \Arg{units} \Arg{factor} \meta{tl~var} \meta{fp~var} +% \cs{siunitx_unit_format_multiply_combine_exponent:nnnN} +% \Arg{units} \Arg{factor} \Arg{exponent} \meta{tl~var} +% \end{syntax} +% These function formats the \meta{units} in the same way as described for +% \cs{siunitx_unit_format:nN}. The units are multiplied by the \meta{factor}, +% and further processing takes place as previously described. +% +% For example, +% \begin{verbatim} +% \siunitx_unit_format_multiply:nnN { \metre \per \second } +% { 3 } \l_tmpa_tl +% \end{verbatim} +% will, with standard settings, result in \cs{l_tmpa_tl} being set to +% \begin{verbatim} +% \mathrm{km}^{3}\,\mathrm{s}^{-3} +% \end{verbatim} +% \end{function} +% +% \section{Defining symbolic units} +% +% \begin{function}{\siunitx_declare_prefix:Nnn, \siunitx_declare_prefix:Nnx} +% \begin{syntax} +% \cs{siunitx_declare_prefix:Nnn} \meta{prefix} \Arg{power} \Arg{symbol} +% \end{syntax} +% Defines a symbolic \meta{prefix} (which should be a control sequence +% such as |\kilo|) to be converted by the parser to the \meta{symbol}. +% The latter should consist of literal content (\foreign{e.g.}~|k|). +% In literal mode the \meta{symbol} will be typeset directly. The prefix +% should represent an integer \meta{power} of $10$, and this information +% may be used to convert from one or more \meta{prefix} symbols to an +% overall power applying to a unit. See also +% \cs{siunitx_declare_prefix:Nn}. +% \end{function} +% +% \begin{function}{\siunitx_declare_prefix:Nn} +% \begin{syntax} +% \cs{siunitx_declare_prefix:Nn} \meta{prefix} \Arg{symbol} +% \end{syntax} +% Defines a symbolic \meta{prefix} (which should be a control sequence +% such as |\kilo|) to be converted by the parser to the \meta{symbol}. +% The latter should consist of literal content (\foreign{e.g.}~|k|). +% In literal mode the \meta{symbol} will be typeset directly. In contrast +% to \cs{siunitx_declare_prefix:Nnn}, there is no assumption about the +% mathematical nature of the \meta{prefix}, \foreign{i.e.}~the prefix may +% represent a power of any base. As a result, no conversion of the +% \meta{prefix} to a numerical power will be possible. +% \end{function} +% +% \begin{function}{\siunitx_declare_power:NNn} +% \begin{syntax} +% \cs{siunitx_declare_power:NnN} \meta{pre-power} \meta{post-power} \Arg{value} +% \end{syntax} +% Defines \emph{two} symbolic \meta{powers} (which should be control +% sequences such as |\squared|) to be converted by the parser to the +% \meta{value}. The latter should be an integer or floating point number in +% the format defined for \pkg{l3fp}. Powers may precede a unit or be give +% after it: both forms are declared at once, as indicated by the argument +% naming. In literal mode, the \meta{value} will be applied as +% a superscript to either the next token in the input (for the +% \meta{pre-power}) or appended to the previously-typeset material +% (for the \meta{post-power}). +% \end{function} +% +% \begin{function}{\siunitx_declare_qualifier:Nn} +% \begin{syntax} +% \cs{siunitx_declare_qualifier:Nn} \meta{qualifier} \Arg{meaning} +% \end{syntax} +% Defines a symbolic \meta{qualifier} (which should be a control sequence +% such as |\catalyst|) to be converted by the parser to the \meta{meaning}. +% The latter should consist of literal content (\foreign{e.g.}~|cat|). In +% literal mode the \meta{meaning} will be typeset following a space after +% the unit to which it applies. +% \end{function} +% +% \begin{function} +% { +% \siunitx_declare_unit:Nn, +% \siunitx_declare_unit:Nx, +% \siunitx_declare_unit:Nnn, +% \siunitx_declare_unit:Nxn +% } +% \begin{syntax} +% \cs{siunitx_declare_unit:Nn} \meta{unit} \Arg{meaning} +% \cs{siunitx_declare_unit:Nnn} \meta{unit} \Arg{meaning} \Arg{options} +% \end{syntax} +% Defines a symbolic \meta{unit} (which should be a control sequence +% such as |\kilogram|) to be converted by the parser to the \meta{meaning}. +% The latter may consist of literal content (\foreign{e.g.}~|kg|), other +% symbolic unit commands (\foreign{e.g.}~|\kilo\gram|) or a mixture of the two. +% In literal mode the \meta{meaning} will be typeset directly. The version +% taking an \meta{options} argument may be used to support per-unit +% options: these are applied at the top level or using +% \cs{siunitx_unit_options_apply:n}. +% \end{function} +% +% \begin{variable}{\l_siunitx_unit_font_tl} +% The font function which is applied to the text of units when constructing +% formatted units: set by |font-command|. +% \end{variable} +% +% \begin{variable}{\l_siunitx_unit_symbolic_seq} +% This sequence contains all of the symbolic names defined: +% these will be in the form of control sequences such as |\kilogram|. +% The order of the sequence is unimportant. This includes prefixes and +% powers as well as units themselves. +% \end{variable} +% +% \begin{variable}{\l_siunitx_unit_seq} +% This sequence contains all of the symbolic \emph{unit} names defined: +% these will be in the form of control sequences such as |\kilogram|. +% In contrast to \cs{l_siunitx_unit_symbolic_seq}, it \emph{only} holds +% units themselves +% \end{variable} +% +% \section{Per-unit options} +% +% \begin{function}{\siunitx_unit_options_apply:n} +% \begin{syntax} +% \cs{siunitx_unit_options_apply:n} \meta{unit(s)} +% \end{syntax} +% Applies any unit-specific options set up using +% \cs{siunitx_declare_unit:Nnn}. This allows there use outside of unit +% formatting, for example to influence spacing in quantities. The options +% are applied only once at a given group level, which allows for user +% over-ride \foreign{via} |\keys_set:nn { siunitx } { ... }|. +% \end{function} +% +% \section{Units in (PDF) strings} +% +% \begin{function}{\siunitx_unit_pdfstring_context:} +% \begin{syntax} +% \cs{group_begin:} +% \cs{siunitx_unit_pdfstring_context:} +% \meta{Expansion context} \meta{units} +% \cs{group_end:} +% \end{syntax} +% Sets symbol unit macros to generate text directly. This is needed in +% expansion contexts where units must be converted to simple text. This +% function is itself not expandable, so must be using within a +% surrounding group as show in the example. +% \end{function} +% +% \section{Pre-defined symbolic unit components} +% +% The unit parser is defined to recognise a number of pre-defined units, +% prefixes and powers, and also interpret a small selection of +% \enquote{generic} symbolic parts. +% +% Broadly, the pre-defined units are those defined by the \textsc{bipm} in the +% documentation for the \emph{International System of Units} +% (\acro{SI})~\cite{BIPM}. As far as possible, the names given to the command +% names for units are those used by the \acro{bipm}, omitting spaces and using +% only \acro{ASCII} characters. The standard symbols are also taken from the +% same documentation. In the following documentation, the order of the +% description of units broadly follows the \acro{SI}~Brochure. +% +% \begin{function} +% { +% \kilogram , +% \metre , +% \meter , +% \mole , +% \kelvin , +% \candela , +% \second , +% \ampere +% } +% The base units as defined in the \acro{SI} Brochure~\cite{base-units}. +% Notice that \cs{meter} is defined as an alias for \cs{metre} as the former +% spelling is common in the US (although the latter is the official spelling). +% \end{function} +% +% \begin{function}{\gram} +% The base unit \cs{kilogram} is defined using an \acro{SI} prefix: as such +% the (derived) unit \cs{gram} is required by the module to correctly produce +% output for the \cs{kilogram}. +% \end{function} +% +% \begin{function} +% { +% \yocto , +% \zepto , +% \atto , +% \femto , +% \pico , +% \nano , +% \micro , +% \milli , +% \centi , +% \deci , +% \deca , +% \deka , +% \hecto , +% \kilo , +% \mega , +% \giga , +% \tera , +% \peta , +% \exa , +% \zetta , +% \yotta +% } +% Prefixes, all of which are integer powers of $10$: the powers are stored +% internally by the module and can be used for conversion from prefixes to +% their numerical equivalent. These prefixes are documented in Section~3.1 +% of the \acro{SI}~Brochure. +% +% Note that the \cs{kilo} prefix is required to +% define the base \cs{kilogram} unit. Also note the two spellings available +% for \cs{deca}/\cs{deka}. +% \end{function} +% +% \begin{function} +% { +% \becquerel , +% \degreeCelsius , +% \coulomb , +% \farad , +% \gray , +% \hertz , +% \henry , +% \joule , +% \katal , +% \lumen , +% \lux , +% \newton , +% \ohm , +% \pascal , +% \radian , +% \siemens , +% \sievert , +% \steradian , +% \tesla , +% \volt , +% \watt , +% \weber +% } +% The defined \acro{SI}~units with defined names and symbols, as given in +% Table~4 of the \acro{SI}~Brochure. Notice that the names +% of the units are lower case with the exception of \cs{degreeCelsius}, and +% that this unit name includes \enquote{degree}. +% \end{function} +% +% \begin{function} +% { +% \astronomicalunit , +% \bel , +% \dalton , +% \day , +% \decibel , +% \electronvolt , +% \hectare , +% \hour , +% \litre , +% \liter , +% \neper , +% \minute , +% \tonne +% } +% Units accepted for use with the \acro{SI}: here \cs{minute} is a unit of +% time not of plane angle. These units are taken from Table~8 of the +% \acro{SI}~Brochure. +% +% For the unit \cs{litre}, both |l| and |L| are listed +% as acceptable symbols: the latter is the standard setting of the module. +% The alternative spelling \cs{liter} is also given for this unit for US +% users (as with \cs{metre}, the official spelling is \enquote{re}). +% \end{function} +% +% \begin{function} +% { +% \arcminute , +% \arcsecond , +% \degree +% } +% Units for plane angles accepted for use with the \acro{SI}: to avoid a +% clash with units for time, here \cs{arcminute} and \cs{arcsecond} are +% used in place of \cs{minute} and \cs{second}. These units are taken from +% Table~8 of the \acro{SI}~Brochure. +% \end{function} +% +% \begin{function}{\percent} +% The mathematical concept of percent, usable with the \acro{SI} as detailed +% in Section~5.4.7 of the \acro{SI}~Brochure. +% \end{function} +% +% \begin{function}{\square, \cubic} +% \begin{syntax} +% \cs{square} \meta{prefix} \meta{unit} +% \cs{cubic} \meta{prefix} \meta{unit} +% \end{syntax} +% Pre-defined unit powers which apply to the next \meta{prefix}/\meta{unit} +% combination. +% \end{function} +% +% \begin{function}{\squared, \cubed} +% \begin{syntax} +% \meta{prefix} \meta{unit} \cs{squared} +% \meta{prefix} \meta{unit} \cs{cubed} +% \end{syntax} +% Pre-defined unit powers which apply to the preceding +% \meta{prefix}/\meta{unit} combination. +% \end{function} +% +% \begin{function}{\per} +% \begin{syntax} +% \cs{per} \meta{prefix} \meta{unit} \meta{power} +% \end{syntax} +% Indicates that the next \meta{prefix}/\meta{unit}/\meta{power} combination +% is reciprocal, \foreign{i.e.}~raises it to the power $-1$. This symbolic +% representation may be applied in addition to a \cs{power}, and will work +% correctly if the \cs{power} itself is negative. In literal mode \cs{per} +% will print a slash (\enquote{$/$}). +% \end{function} +% +% \begin{function}{\cancel} +% \begin{syntax} +% \cs{cancel} \meta{prefix} \meta{unit} \meta{power} +% \end{syntax} +% Indicates that the next \meta{prefix}/\meta{unit}/\meta{power} combination +% should be \enquote{cancelled out}. In the parsed output, the entire unit +% combination will be given as the argument to a function \cs{cancel}, which +% is assumed to be available at a higher level. In literal mode, the same +% higher-level \cs{cancel} will be applied to the next token. It is the +% responsibility of the calling code to provide an appropriate definition +% for \cs{cancel} outside of the scope of the unit parser. +% \end{function} +% +% \begin{function}{\highlight} +% \begin{syntax} +% \cs{highlight} \Arg{color} \meta{prefix} \meta{unit} \meta{power} +% \end{syntax} +% Indicates that the next \meta{prefix}/\meta{unit}/\meta{power} combination +% should be highlighted in the specified \meta{color}. In the parsed output, +% the entire unit combination will be given as the argument to a function +% \cs{textcolor}, which is assumed to be available at a higher level. In +% literal mode, the same higher-level \cs{textcolor} will be applied to the +% next token. It is the responsibility of the calling code to provide an +% appropriate definition for \cs{textcolor} outside of the scope of the unit +% parser. +% \end{function} +% +% \begin{function}{\of} +% \begin{syntax} +% \meta{prefix} \meta{unit} \meta{power} \cs{of} \Arg{qualifier} +% \end{syntax} +% Indicates that the \meta{qualifier} applies to the current +% \meta{prefix}/\meta{unit}/\meta{power} combination. In parsed mode, the +% display of the result will depend upon module options. In literal mode, +% the \meta{qualifier} will be printed in parentheses following the preceding +% \meta{unit} and a full-width space. +% \end{function} +% +% \begin{function}{\raiseto, \tothe} +% \begin{syntax} +% \cs{raiseto} \Arg{power} \meta{prefix} \meta{unit} +% \meta{prefix} \meta{unit} \cs{tothe} \Arg{power} +% \end{syntax} +% Indicates that the \meta{power} applies to the current +% \meta{prefix}/\meta{unit} combination. As shown, \cs{raiseto} applies to +% the next \meta{unit} whereas \cs{tothe} applies to the preceding unit. In +% literal mode the \cs{power} will be printed as a superscript attached to +% the next token (\cs{raiseto}) or preceding token (\cs{tothe}) as +% appropriate. +% \end{function} +% +% \subsection{Key--value options} +% +% The options defined by this submodule are available within the \pkg{l3keys} +% |siunitx| tree. +% +% \begin{function}{bracket-unit-denominator} +% \begin{syntax} +% |bracket-unit-denominator| = |true|\verb"|"|false| +% \end{syntax} +% Switch to determine whether brackets are added to the denominator part of +% a unit when printed using inline fractional form (with |per-mode| as +% |repeated-symbol|, |symbol| or |symbol-or-fraction|). The standard setting +% is |true|. +% \end{function} +% +% \begin{function}{extract-mass-in-kilograms} +% \begin{syntax} +% |extract-mass-in-kilograms| = |true|\verb"|"|false| +% \end{syntax} +% Determines whether prefix extraction treats kilograms as a base unit; when +% set |false|, grams are used. The standard setting is |true|. +% \end{function} +% +% \begin{function}{forbid-literal-units} +% \begin{syntax} +% |forbid-literal-units| = |true|\verb"|"|false| +% \end{syntax} +% Switch which determines if literal units are allowed when parsing is +% active; does not apply when |parse-units| is |false|. +% \end{function} +% +% \begin{function}{fraction-command} +% \begin{syntax} +% |fraction-command| = \meta{command} +% \end{syntax} +% Command used to create fractional output when |per-mode| is set to +% |fraction|. The standard setting is |\frac|. +% \end{function} +% +% \begin{function}{inter-unit-product} +% \begin{syntax} +% |inter-unit-product| = \meta{separator} +% \end{syntax} +% Inserted between unit combinations in parsed mode, and used to replace +% |.| and |~| in literal mode. The standard setting is |\,|. +% \end{function} +% +% \begin{function}{parse-units} +% \begin{syntax} +% |parse-units| = |true|\verb"|"|false| +% \end{syntax} +% Determines whether parsing of unit symbols is attempted or literal +% mode is used directly. The standard setting is |true|. +% \end{function} +% +% \begin{function}{per-mode} +% \begin{syntax} +% |per-mode| = |fraction|\verb"|"|power|\verb"|"|power-positive-first|\verb"|"|repeated-symbol|\verb"|"|symbol|\verb"|"|symbol-or-fraction| +% \end{syntax} +% Selects how the negative powers (\cs{per}) are formatted: a choice from +% the options |fraction|, |power|, |power-positive-first|, |repeated-symbol|, +% |symbol| and |symbol-or-fraction|. The option |fraction| generates +% fractional output when appropriate using the command specified by +% the |fraction-command| option. The setting |power| uses reciprocal powers +% leaving the units in the order of input, while |power-positive-first| uses +% the same display format but sorts units such that the positive powers +% come before negative ones. The |symbol| setting uses a symbol (specified +% by |per-symbol|) between positive and negative powers, while +% |repeated-symbol| uses the same symbol but places it before \emph{every} +% unit with a negative power (this is mathematically \enquote{wrong} but +% often seen in real work). Finally, |symbol-or-fraction| acts like +% |symbol| for inline output and like |fraction| when the output is used +% in a display math environment. The standard setting is |power|. +% \end{function} +% +% \begin{function}{per-symbol} +% \begin{syntax} +% |per-symbol| = \meta{symbol} +% \end{syntax} +% Specifies the symbol to be used to denote negative powers when the option +% |per-mode| is set to |repeated-symbol|, |symbol| or |symbol-or-fraction|. +% The standard setting is |/|. +% \end{function} +% +% \begin{function}{qualifier-mode} +% \begin{syntax} +% |qualifier-mode| = |bracket|\verb"|"|combine|\verb"|"|phrase|\verb"|"|subscript| +% \end{syntax} +% Selects how qualifiers are formatted: a choice from the options |bracket|, +% |combine|, |phrase| and |subscript|. The option |bracket| wraps the qualifier +% in parenthesis, |combine| joins the qualifier with the unit directly, |phrase| +% joins the material using |qualifier-phrase| as a link, and +% |subscript| formats the qualifier as a subscript. The standard setting is +% |subscript|. +% \end{function} +% +% \begin{function}{qualifier-phrase} +% \begin{syntax} +% |qualifier-phrase| = \meta{phrase} +% \end{syntax} +% Defines the \meta{phrase} used when |qualifier-mode| is set to |phrase|. +% \end{function} +% +% \begin{function}{sticky-per} +% \begin{syntax} +% |sticky-per| = |true|\verb"|"|false| +% \end{syntax} +% Used to determine whether \cs{per} should be applied one a unit-by-unit +% basis (when |false|) or should apply to all following units +% (when |true|). The latter mode is somewhat akin conceptually to the +% \TeX{} \cs{over} primitive. The standard setting is |false|. +% \end{function} +% +% \begin{function}{unit-font-command} +% \begin{syntax} +% |unit-font-command| = \meta{command} +% \end{syntax} +% Command applied to text during output of units: should be command usable +% in math mode for font selection. Notice that in a typical unit this does +% not (necessarily) apply to all output, for example powers or brackets. +% The standard setting is |\mathrm|. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{siunitx-unit} 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_unit> +% \end{macrocode} +% +% \subsection{Initial set up} +% +% The mechanisms defined here need a few variables to exist and to be +% correctly set: these don't belong to one subsection and so are created +% in a small general block. +% +% Variants not provided by \pkg{expl3}. +% \begin{macrocode} +\cs_generate_variant:Nn \tl_replace_all:Nnn { NnV } +% \end{macrocode} +% +% \begin{variable}{\l_@@_tmp_fp} +% \begin{variable}{\l_@@_tmp_int} +% \begin{variable}{\l_@@_tmp_tl} +% Scratch space. +% \begin{macrocode} +\fp_new:N \l_@@_tmp_fp +\int_new:N \l_@@_tmp_int +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\c_@@_math_subscript_tl} +% Useful tokens with awkward category codes. +% \begin{macrocode} +\tl_const:Nx \c_@@_math_subscript_tl + { \char_generate:nn { `\_ } { 8 } } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_parsing_bool} +% A boolean is used to indicate when the symbolic unit functions should +% produce symbolic or literal output. This is used when the symbolic names +% are used along with literal input, and ensures that there is a sensible +% fall-back for these cases. +% \begin{macrocode} +\bool_new:N \l_@@_parsing_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_test_bool} +% A switch used to indicate that the code is testing the input to find +% if there is any typeset output from individual unit macros. This is needed +% to allow the \enquote{base} macros to be found, and also to pick up the +% difference between symbolic and literal unit input. +% \begin{macrocode} +\bool_new:N \l_@@_test_bool +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_if_symbolic:nTF} +% The test for symbolic units is needed in two places. First, there is the +% case of \enquote{pre-parsing} input to check if it can be parsed. Second, +% when parsing there is a need to check if the current unit is built up +% from others (symbolic) or is defined in terms of some literals. To do this, +% the approach used is to set all of the symbolic unit commands expandable +% and to do nothing, with the few special cases handled manually. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \@@_if_symbolic:n #1 { TF } + { + \group_begin: + \bool_set_true:N \l_@@_test_bool + \protected@edef \l_@@_tmp_tl {#1} + \exp_args:NNV \group_end: + \tl_if_blank:nTF \l_@@_tmp_tl + { \prg_return_true: } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Defining symbolic unit} +% +% Unit macros and related support are created here. These exist only within +% the scope of the unit processor code, thus not polluting document-level +% namespace and allowing overlap with other areas in the case of useful short +% names (for example \cs{pm}). Setting up the mechanisms to allow this requires +% a few additional steps on top of simply saving the data given by the user +% in creating the unit. +% +% \begin{variable}{\l_siunitx_unit_symbolic_seq} +% A list of all of the symbolic units, \foreign{etc.}, set up. This is needed +% to allow the symbolic names to be defined within the scope of the unit +% parser but not elsewhere using simple mappings. +% \begin{macrocode} +\seq_new:N \l_siunitx_unit_symbolic_seq +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_siunitx_unit_seq} +% A second list featuring only the units themselves. +% \begin{macrocode} +\seq_new:N \l_siunitx_unit_seq +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_set_symbolic:Nnn} +% \begin{macro}{\@@_set_symbolic:Npnn} +% \begin{macro}{\@@_set_symbolic:Nnnn} +% The majority of the work for saving each symbolic definition is the same +% irrespective of the item being defined (unit, prefix, power, qualifier). +% This is therefore all carried out in a single internal function which +% does the common tasks. The three arguments here are the symbolic macro +% name, the literal output and the code to insert when doing full unit +% parsing. To allow for the \enquote{special cases} (where arguments are +% required) the entire mechanism is set up in a two-part fashion allowing +% for flexibility at the slight cost of additional functions. +% +% Importantly, notice that the unit macros are declared as expandable. This +% is required so that literals can be correctly converted into a token list +% of material which does not depend on local redefinitions for the unit +% macros. That is required so that the unit formatting system can be grouped. +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_symbolic:Nnn #1 + { \@@_set_symbolic:Nnnn #1 { } } +\cs_new_protected:Npn \@@_set_symbolic:Npnn #1#2# + { \@@_set_symbolic:Nnnn #1 {#2} } +\cs_new_protected:Npn \@@_set_symbolic:Nnnn #1#2#3#4 + { + \seq_put_right:Nn \l_siunitx_unit_symbolic_seq {#1} + \cs_set:cpn { @@_ \token_to_str:N #1 :w } #2 + { + \bool_if:NF \l_@@_test_bool + { + \bool_if:NTF \l_@@_parsing_bool + {#4} + {#3} + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\siunitx_declare_power:NNn} +% Powers can come either before or after the unit. As they always come +% (logically) in matching, we handle this by declaring two commands, +% and setting each up separately. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_declare_power:NNn #1#2#3 + { + \@@_set_symbolic:Nnn #1 + { \@@_literal_power:nn {#3} } + { \@@_parse_power:nnN {#1} {#3} \c_true_bool } + \@@_set_symbolic:Nnn #2 + { ^ {#3} } + { \@@_parse_power:nnN {#2} {#3} \c_false_bool } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\siunitx_declare_prefix:Nn} +% \begin{macro}{\siunitx_declare_prefix:Nnn, \siunitx_declare_prefix:Nnx} +% \begin{variable} +% {\l_@@_prefixes_forward_prop, \l_@@_prefixes_reverse_prop} +% For prefixes there are a couple of options. In all cases, the basic +% requirement is to set up to parse the prefix using the appropriate +% internal function. For prefixes which are powers of $10$, there is also +% the need to be able to do conversion to/from the numerical equivalent. +% That is handled using two properly lists which can be used to supply +% the conversion data later. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_declare_prefix:Nn #1#2 + { + \@@_set_symbolic:Nnn #1 + {#2} + { \@@_parse_prefix:Nn #1 {#2} } + } +\cs_new_protected:Npn \siunitx_declare_prefix:Nnn #1#2#3 + { + \siunitx_declare_prefix:Nn #1 {#3} + \prop_put:Nnn \l_@@_prefixes_forward_prop {#3} {#2} + \prop_put:Nnn \l_@@_prefixes_reverse_prop {#2} {#3} + } +\cs_generate_variant:Nn \siunitx_declare_prefix:Nnn { Nnx } +\prop_new:N \l_@@_prefixes_forward_prop +\prop_new:N \l_@@_prefixes_reverse_prop +% \end{macrocode} +% \end{variable} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\siunitx_declare_qualifier:Nn} +% Qualifiers are relatively easy to handle: nothing to do other than save +% the input appropriately. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_declare_qualifier:Nn #1#2 + { + \@@_set_symbolic:Nnn #1 + { ~ ( #2 ) } + { \@@_parse_qualifier:nn {#1} {#2} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\siunitx_declare_unit:Nn, \siunitx_declare_unit:Nx} +% \begin{macro}{\siunitx_declare_unit:Nnn, \siunitx_declare_unit:Nxn} +% For the unit parsing, allowing for variations in definition order requires +% that a test is made for the output of each unit at point of use. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_declare_unit:Nn #1#2 + { \siunitx_declare_unit:Nnn #1 {#2} { } } +\cs_generate_variant:Nn \siunitx_declare_unit:Nn { Nx } +\cs_new_protected:Npn \siunitx_declare_unit:Nnn #1#2#3 + { + \seq_put_right:Nn \l_siunitx_unit_seq {#1} + \@@_set_symbolic:Nnn #1 + {#2} + { + \@@_if_symbolic:nTF {#2} + {#2} + { \@@_parse_unit:Nn #1 {#2} } + } + \tl_clear_new:c { l_@@_options_ \token_to_str:N #1 _tl } + \tl_if_empty:nF {#3} + { \tl_set:cn { l_@@_options_ \token_to_str:N #1 _tl } {#3} } + } +\cs_generate_variant:Nn \siunitx_declare_unit:Nnn { Nx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Applying unit options} +% +% \begin{variable}{\l_@@_options_bool} +% \begin{macrocode} +\bool_new:N \l_@@_options_bool +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_unit_options_apply:n} +% Options apply only if they have not already been set at this group +% level. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_unit_options_apply:n #1 + { + \bool_if:NF \l_@@_options_bool + { + \tl_if_single_token:nT {#1} + { + \tl_if_exist:cT { l_@@_options_ \token_to_str:N #1 _tl } + { + \keys_set:nv { siunitx } + { l_@@_options_ \token_to_str:N #1 _tl } + } + } + } + \bool_set_true:N \l_@@_options_bool + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Non-standard symbolic units} +% +% A few of the symbolic units require non-standard definitions: these are +% created here. They all use parts of the more general code but have particular +% requirements which can only be addressed by hand. Some of these could in +% principle be used in place of the dedicated definitions above, but at point +% of use that would then require additional expansions for each unit parsed: +% as the macro names would still be needed, this does not offer any real +% benefits. +% +% \begin{macro}{\per} +% The \cs{per} symbolic unit is a bit special: it has a mechanism entirely +% different from everything else, so has to be set up by hand. In literal +% mode it is represented by a very simple symbol! +% \begin{macrocode} +\@@_set_symbolic:Nnn \per + { / } + { \@@_parse_per: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cancel} +% \begin{macro}{\highlight} +% The two special cases, \cs{cancel} and \cs{highlight}, are easy to deal +% with when parsing. When not parsing, a precaution is taken to ensure that +% the user level equivalents always get a braced argument. +% \begin{macrocode} +\@@_set_symbolic:Npnn \cancel + { } + { \@@_parse_special:n { \cancel } } +\@@_set_symbolic:Npnn \highlight #1 + { \@@_literal_special:nN { \textcolor {#1} } } + { \@@_parse_special:n { \textcolor {#1} } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\of} +% The generic qualifier is simply the same as the dedicated ones except for +% needing to grab an argument. +% \begin{macrocode} +\@@_set_symbolic:Npnn \of #1 + { \ ( #1 ) } + { \@@_parse_qualifier:nn { \of {#1} } {#1} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\raiseto, \tothe} +% Generic versions of the pre-defined power macros. These require an +% argument and so cannot be handled using the general approach. Other than +% that, the code here is very similar to that in +% \cs{siunitx_unit_power_set:NnN}. +% \begin{macrocode} +\@@_set_symbolic:Npnn \raiseto #1 + { \@@_literal_power:nn {#1} } + { \@@_parse_power:nnN { \raiseto {#1} } {#1} \c_true_bool } +\@@_set_symbolic:Npnn \tothe #1 + { ^ {#1} } + { \@@_parse_power:nnN { \tothe {#1} } {#1} \c_false_bool } +% \end{macrocode} +% \end{macro} +% +% \subsection{Main formatting routine} +% +% Unit input can take two forms, \enquote{literal} units (material to be +% typeset directly) or \enquote{symbolic} units (macro-based). Before any +% parsing or typesetting is carried out, a small amount of pre-parsing has to +% be carried out to decide which of these cases applies. +% +% \begin{variable} +% {\l_siunitx_unit_font_tl, \l_@@_product_tl, \l_@@_mass_kilogram_bool} +% Options which apply to the main formatting routine, and so are not tied +% to either symbolic or literal input. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + extract-mass-in-kilograms .bool_set:N = + \l_@@_mass_kilogram_bool , + inter-unit-product .tl_set:N = + \l_@@_product_tl , + unit-font-command .tl_set:N = + \l_siunitx_unit_font_tl + } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_formatted_tl} +% A token list for the final formatted result: may or may not be generated +% by the parser, depending on the nature of the input. +% \begin{macrocode} +\tl_new:N \l_@@_formatted_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\siunitx_unit_format:nN} +% \begin{macro}{\siunitx_unit_format_extract_prefixes:nNN} +% \begin{macro}{\siunitx_unit_format_combine_exponent:nnN} +% \begin{macro}{\siunitx_unit_format_multiply:nnN} +% \begin{macro}{\siunitx_unit_format_multiply_extract_prefixes:nnNN} +% \begin{macro}{\siunitx_unit_format_multiply_combine_exponent:nnnN} +% \begin{macro}{\@@_format:nNN} +% \begin{macro}{\@@_format_aux:} +% Formatting parsed units can take place either with the prefixes printed or +% separated out into a power of ten. This variation is handled using two +% separate functions: as this submodule does not really deal with numbers, +% formatting the numeral part here would be tricky and it is better therefore +% to have a mechanism to return a simple numerical power. At the same time, +% most uses will no want this more complex return format and so a version of +% the code which does not do this is also provided. +% +% The main unit formatting routine groups all of the parsing/formatting, so +% that the only value altered will be the return token list. As definitions +% for the various unit macros are not globally created, the first step is to +% map over the list of names and active the unit definitions: these do +% different things depending on the switches set. There is then a decision to +% be made: is the unit input one that can be parsed (\enquote{symbolic}), or +% is is one containing one or more literals. In the latter case, there is a +% still the need to convert the input into an expanded token list as some +% parts of the input could still be using unit macros. +% +% Notice that for \cs{siunitx_unit_format:nN} a second return value from the +% auxiliary has to be allowed for, but is simply discarded. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_unit_format:nN #1#2 + { + \bool_set_false:N \l_@@_prefix_exp_bool + \fp_zero:N \l_@@_combine_exp_fp + \fp_set:Nn \l_@@_multiple_fp { \c_one_fp } + \@@_format:nNN {#1} #2 \l_@@_tmp_fp + } +\cs_new_protected:Npn \siunitx_unit_format_extract_prefixes:nNN #1#2#3 + { + \bool_set_true:N \l_@@_prefix_exp_bool + \fp_zero:N \l_@@_combine_exp_fp + \fp_set:Nn \l_@@_multiple_fp { \c_one_fp } + \@@_format:nNN {#1} #2 #3 + } +\cs_new_protected:Npn \siunitx_unit_format_combine_exponent:nnN #1#2#3 + { + \bool_set_false:N \l_@@_prefix_exp_bool + \fp_set:Nn \l_@@_combine_exp_fp {#2} + \fp_set:Nn \l_@@_multiple_fp { \c_one_fp } + \@@_format:nNN {#1} #3 \l_@@_tmp_fp + } +\cs_new_protected:Npn \siunitx_unit_format_multiply:nnN #1#2#3 + { + \bool_set_false:N \l_@@_prefix_exp_bool + \fp_zero:N \l_@@_combine_exp_fp + \fp_set:Nn \l_@@_multiple_fp {#2} + \@@_format:nNN {#1} #3 \l_@@_tmp_fp + } +\cs_new_protected:Npn \siunitx_unit_format_multiply_extract_prefixes:nnNN + #1#2#3#4 + { + \bool_set_true:N \l_@@_prefix_exp_bool + \fp_zero:N \l_@@_combine_exp_fp + \fp_set:Nn \l_@@_multiple_fp {#2} + \@@_format:nNN {#1} #3 #4 + } +\cs_new_protected:Npn \siunitx_unit_format_multiply_combine_exponent:nnnN + #1#2#3#4 + { + \bool_set_false:N \l_@@_prefix_exp_bool + \fp_set:Nn \l_@@_combine_exp_fp {#3} + \fp_set:Nn \l_@@_multiple_fp {#2} + \@@_format:nNN {#1} #4 \l_@@_tmp_fp + } +\cs_new_protected:Npn \@@_format:nNN #1#2#3 + { + \group_begin: + \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq + { \cs_set_eq:Nc ##1 { @@_ \token_to_str:N ##1 :w } } + \tl_clear:N \l_@@_formatted_tl + \fp_zero:N \l_@@_prefix_fp + \bool_if:NTF \l_@@_parse_bool + { + \@@_if_symbolic:nTF {#1} + { + \@@_parse:n {#1} + \prop_if_empty:NF \l_@@_parsed_prop + { \@@_format_parsed: } + } + { + \bool_if:NTF \l_@@_forbid_literal_bool + { \msg_error:nnn { siunitx } { unit / literal } {#1} } + { \@@_format_literal:n {#1} } + } + } + { \@@_format_literal:n {#1} } + \cs_set_protected:Npx \@@_format_aux: + { + \tl_set:Nn \exp_not:N #2 + { \exp_not:V \l_@@_formatted_tl } + \fp_set:Nn \exp_not:N #3 + { \fp_use:N \l_@@_prefix_fp } + } + \exp_after:wN \group_end: + \@@_format_aux: + } +\cs_new_protected:Npn \@@_format_aux: { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Formatting literal units} +% +% While in literal mode no parsing occurs, there is a need to provide a few +% auxiliary functions to handle one or two special cases. +% +% \begin{macro}[EXP]{\@@_literal_power:nn} +% For printing literal units which are given before the unit they apply to, +% there is a slight rearrangement. This is ex[EXP]pandable to cover the case of +% creation of a PDF string. +% \begin{macrocode} +\cs_new:Npn \@@_literal_power:nn #1#2 { #2 ^ {#1} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_literal_special:nN} +% When dealing with the special cases, there is an argument to absorb. This +% should be braced to be passed up to the user level, which is dealt with +% here. +% \begin{macrocode} +\cs_new:Npn \@@_literal_special:nN #1#2 { #1 {#2} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_format_literal:n} +% \begin{macro} +% { +% \@@_format_literal_tilde: , +% \@@_format_literal_subscript: , +% \@@_format_literal_superscript: +% } +% \begin{macro}{\@@_format_literal_auxi:w} +% \begin{macro}{\@@_format_literal_auxii:w} +% \begin{macro}{\@@_format_literal_auxiii:w} +% \begin{macro}{\@@_format_literal_auxiv:w} +% \begin{macro}{\@@_format_literal_auxv:w} +% \begin{variable}{\l_@@_separator_tl} +% To format literal units, there are two tasks to do. The input is +% \texttt{x}-type expanded to force any symbolic units to be converted into +% their literal representation: this requires setting the appropriate +% switch. In the resulting token list, all |.| and |~| tokens are then +% replaced by the current unit product token list. To enable this to happen +% correctly with a normal (active) |~|, a small amount of +% \enquote{protection} is needed first. To cover active sub- and superscript +% tokens, appropriate definitions are provided at this stage. Those have +% to be expandable macros rather than implicit character tokens. +% +% As with other code dealing with user input, \cs{protected@edef} is used +% here rather than \cs{tl_set:Nx} as \LaTeXe{} robust commands may be +% present. +% \begin{macrocode} +\group_begin: + \char_set_catcode_active:n { `\~ } + \cs_new_protected:Npx \@@_format_literal:n #1 + { + \group_begin: + \exp_not:n { \bool_set_false:N \l_@@_parsing_bool } + \tl_set:Nn \exp_not:N \l_@@_tmp_tl {#1} + \tl_replace_all:Nnn \exp_not:N \l_@@_tmp_tl + { \token_to_str:N ^ } { ^ } + \tl_replace_all:Nnn \exp_not:N \l_@@_tmp_tl + { \token_to_str:N _ } { \c_@@_math_subscript_tl } + \char_set_active_eq:NN ^ + \exp_not:N \@@_format_literal_superscript: + \char_set_active_eq:NN _ + \exp_not:N \@@_format_literal_subscript: + \char_set_active_eq:NN \exp_not:N ~ + \exp_not:N \@@_format_literal_tilde: + \exp_not:n + { + \protected@edef \l_@@_tmp_tl + { \l_@@_tmp_tl } + \tl_clear:N \l_@@_formatted_tl + \tl_if_empty:NF \l_@@_tmp_tl + { + \exp_after:wN \@@_format_literal_auxi:w + \l_@@_tmp_tl . + \q_recursion_tail . \q_recursion_stop + } + \exp_args:NNNV \group_end: + \tl_set:Nn \l_@@_formatted_tl + \l_@@_formatted_tl + } + } +\group_end: +\cs_new:Npx \@@_format_literal_subscript: { \c_@@_math_subscript_tl } +\cs_new:Npn \@@_format_literal_superscript: { ^ } +\cs_new:Npn \@@_format_literal_tilde: { . } +% \end{macrocode} +% To introduce the font changing commands while still allowing for line +% breaks in literal units, a loop is needed to replace one |.| at a time. +% To also allow for division, a second loop is used within that to handle +% |/|: as a result, the separator between parts has to be tracked. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_literal_auxi:w #1 . + { + \quark_if_recursion_tail_stop:n {#1} + \@@_format_literal_auxii:n {#1} + \tl_set_eq:NN \l_@@_separator_tl \l_@@_product_tl + \@@_format_literal_auxi:w + } +\cs_set_protected:Npn \@@_format_literal_auxii:n #1 + { + \@@_format_literal_auxiii:w + #1 / \q_recursion_tail / \q_recursion_stop + } +\cs_new_protected:Npn \@@_format_literal_auxiii:w #1 / + { + \quark_if_recursion_tail_stop:n {#1} + \@@_format_literal_auxiv:w #1 ^ ^ \q_stop + \tl_set:Nn \l_@@_separator_tl { / } + \@@_format_literal_auxiii:w + } +% \end{macrocode} +% Within each unit any sub- and superscript parts need to be separated out: +% wrapping everything in the font command is incorrect. The superscript part +% is relatively easy as there is no catcode issue or font command to add, +% while the subscript part needs a bit more work. As the user might have the +% two parts in either order, picking up the subscript needs to look in two +% places. We assume that only one is given: odd input here is simply accepted. +% \begin{macrocode} +\use:x + { + \cs_new_protected:Npn \exp_not:N \@@_format_literal_auxiv:w + ##1 ^ ##2 ^ ##3 \exp_not:N \q_stop + { + \exp_not:N \@@_format_literal_auxv:w + ##1 + \c_@@_math_subscript_tl + \c_@@_math_subscript_tl + \exp_not:N \q_mark + ##2 + \c_@@_math_subscript_tl + \c_@@_math_subscript_tl + \exp_not:N \q_stop + } + \cs_new_protected:Npn \exp_not:N \@@_format_literal_auxv:w + ##1 \c_@@_math_subscript_tl + ##2 \c_@@_math_subscript_tl ##3 + \exp_not:N \q_mark + ##4 \c_@@_math_subscript_tl + ##5 \c_@@_math_subscript_tl ##6 + \exp_not:N \q_stop + { + \tl_set:Nx \exp_not:N \l_@@_formatted_tl + { + \exp_not:N \exp_not:V + \exp_not:N \l_@@_formatted_tl + \exp_not:N \tl_if_empty:NF + \exp_not:N \l_@@_formatted_tl + { + \exp_not:N \exp_not:V + \exp_not:N \l_@@_separator_tl + } + \exp_not:N \tl_if_blank:nF {##1} + { + \exp_not:N \exp_not:V + \exp_not:N \l_siunitx_unit_font_tl + { \exp_not:N \exp_not:n {##1} } + } + \exp_not:N \tl_if_blank:nF {##4} + { ^ { \exp_not:N \exp_not:n {##4} } } + \exp_not:N \tl_if_blank:nF {##2##5} + { + \c_@@_math_subscript_tl + { + \exp_not:N \exp_not:V + \exp_not:N \l_siunitx_unit_font_tl + { \exp_not:N \exp_not:n {##2##5} } + } + } + } + } + } +\tl_new:N \l_@@_separator_tl +% \end{macrocode} +% \end{variable} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{(PDF) String creation} +% +% \begin{macro}{\siunitx_unit_pdfstring_context:} +% A simple function that sets up to make units equal to their text +% representation. +% \begin{macrocode} +\cs_new_protected:Npn \siunitx_unit_pdfstring_context: + { + \bool_set_false:N \l_@@_parsing_bool + \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq + { \cs_set_eq:Nc ##1 { @@_ \token_to_str:N ##1 :w } } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Parsing symbolic units} +% +% Parsing units takes place by storing information about each unit in a +% \texttt{prop}. As well as the unit itself, there are various other optional +% data points, for example a prefix or a power. Some of these can come before +% the unit, others only after. The parser therefore tracks the number of units +% read and uses the current position to allocate data to individual units. +% +% The result of parsing is a property list (\cs{l_@@_parsed_prop}) which +% contains one or more entries for each unit: +% \begin{itemize} +% \item \texttt{prefix-$n$} The symbol for the prefix which applies to this +% unit, \foreign{e.g.} for \cs{kilo} with (almost certainly) would be +% |k|. +% \item \texttt{unit-$n$} The symbol for the unit itself, \foreign{e.g.}~for +% \cs{metre} with (almost certainly) would be |m|. +% \item \texttt{power-$n$} The power which a unit is raised to. During +% initial parsing this will (almost certainly) be positive, but is combined +% with \texttt{per-$n$} to give a \enquote{fully qualified} power before +% any formatting takes place +% \item \texttt{per-$n$} Indicates that \texttt{per} applies to the current +% unit: stored during initial parsing then combined with \texttt{power-$n$} +% (and removed from the list) before further work. +% \item \texttt{qualifier-$n$} Any qualifier which applies to the current +% unit. +% \item \texttt{special-$n$} Any \enquote{special effect} to apply to the +% current unit. +% \item \texttt{command-$1$} The command corresponding to \texttt{unit-$n$}: +% needed to track base units; used for \cs{gram} only. +% \end{itemize} +% +% \begin{variable}{\l_@@_sticky_per_bool} +% There is one option when \emph{parsing} the input (as opposed to +% \emph{formatting} for output): how to deal with \cs{per}. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + sticky-per .bool_set:N = \l_@@_sticky_per_bool + } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_parsed_prop} +% \begin{variable}{\l_@@_per_bool} +% \begin{variable}{\l_@@_position_int} +% Parsing units requires a small number of variables are available: a +% \texttt{prop} for the parsed units themselves, a \texttt{bool} to +% indicate if \cs{per} is active and an \texttt{int} to track how many units +% have be parsed. +% \begin{macrocode} +\prop_new:N \l_@@_parsed_prop +\bool_new:N \l_@@_per_bool +\int_new:N \l_@@_position_int +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{macro}{\@@_parse:n} +% The main parsing function is quite simple. After initialising the variables, +% each symbolic unit is set up. The input is then simply inserted into the +% input stream: the symbolic units themselves then do the real work of +% placing data into the parsing system. There is then a bit of tidying up to +% ensure that later stages can rely on the nature of the data here. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse:n #1 + { + \prop_clear:N \l_@@_parsed_prop + \bool_set_true:N \l_@@_parsing_bool + \bool_set_false:N \l_@@_per_bool + \bool_set_false:N \l_@@_test_bool + \int_zero:N \l_@@_position_int + \siunitx_unit_options_apply:n {#1} + #1 + \int_step_inline:nn \l_@@_position_int + { \@@_parse_finalise:n {##1} } + \@@_parse_finalise: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_add:nnnn} +% In all cases, storing a data item requires setting a temporary \texttt{tl} +% which will be used as the key, then using this to store the value. The +% \texttt{tl} is set using \texttt{x}-type expansion as this will expand the +% unit index and any additional calculations made for this. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_add:nnnn #1#2#3#4 + { + \tl_set:Nx \l_@@_tmp_tl { #1 - #2 } + \prop_if_in:NVTF \l_@@_parsed_prop + \l_@@_tmp_tl + { + \msg_error:nnxx { siunitx } { unit / duplicate-part } + { \exp_not:n {#1} } { \token_to_str:N #3 } + } + { + \prop_put:NVn \l_@@_parsed_prop + \l_@@_tmp_tl {#4} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_prefix:Nn} +% \begin{macro}{\@@_parse_power:nnN} +% \begin{macro}{\@@_parse_qualifier:nn} +% \begin{macro}{\@@_parse_special:n} +% Storage of the various optional items follows broadly the same pattern +% in each case. The data to be stored is passed along with an appropriate +% key name to the underlying storage system. The details for each type of +% item should be relatively clear. For example, prefixes have to come before +% their \enquote{parent} unit and so there is some adjustment to do to add +% them to the correct unit. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_prefix:Nn #1#2 + { + \int_set:Nn \l_@@_tmp_int { \l_@@_position_int + 1 } + \@@_parse_add:nnnn { prefix } + { \int_use:N \l_@@_tmp_int } {#1} {#2} + } +\cs_new_protected:Npn \@@_parse_power:nnN #1#2#3 + { + \tl_set:Nx \l_@@_tmp_tl + { unit- \int_use:N \l_@@_position_int } + \bool_lazy_or:nnTF + {#3} + { + \prop_if_in_p:NV + \l_@@_parsed_prop \l_@@_tmp_tl + } + { + \@@_parse_add:nnnn { power } + { + \int_eval:n + { \l_@@_position_int \bool_if:NT #3 { + 1 } } + } + {#1} {#2} + } + { + \msg_error:nnxx { siunitx } + { unit / part-before-unit } { power } { \token_to_str:N #1 } + } + } +\cs_new_protected:Npn \@@_parse_qualifier:nn #1#2 + { + \tl_set:Nx \l_@@_tmp_tl + { unit- \int_use:N \l_@@_position_int } + \prop_if_in:NVTF \l_@@_parsed_prop \l_@@_tmp_tl + { + \@@_parse_add:nnnn { qualifier } + { \int_use:N \l_@@_position_int } {#1} {#2} + } + { + \msg_error:nnnn { siunitx } + { unit / part-before-unit } { qualifier } { \token_to_str:N #1 } + } + } +% \end{macrocode} +% Special (exceptional) items should always come before the relevant units. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_special:n #1 + { + \@@_parse_add:nnnn { special } + { \int_eval:n { \l_@@_position_int + 1 } } + {#1} {#1} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_unit:Nn} +% Parsing units is slightly more involved than the other cases: this is the +% one place where the tracking value is incremented. If the switch +% \cs{l_@@_per_bool} is set true then the current unit is also +% reciprocal: this can only happen if \cs{l_@@_sticky_per_bool} is also +% true, so only one test is required. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_unit:Nn #1#2 + { + \int_incr:N \l_@@_position_int + \tl_if_eq:nnT {#1} { \gram } + { + \@@_parse_add:nnnn { command } + { \int_use:N \l_@@_position_int } + {#1} {#1} + } + \@@_parse_add:nnnn { unit } + { \int_use:N \l_@@_position_int } + {#1} {#2} + \bool_if:NT \l_@@_per_bool + { + \@@_parse_add:nnnn { per } + { \int_use:N \l_@@_position_int } + { \per } { true } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_per:} +% Storing the \cs{per} command requires adding a data item separate from +% the power which applies: this makes later formatting much more +% straight-forward. This data could in principle be combined with the +% \texttt{power}, but depending on the output format required that may make +% life more complex. Thus this information is stored separately for later +% retrieval. If \cs{per} is set to be \enquote{sticky} then after parsing +% the first occurrence, any further uses are in error. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_per: + { + \bool_if:NTF \l_@@_sticky_per_bool + { + \bool_set_true:N \l_@@_per_bool + \cs_set_protected:Npn \per + { \msg_error:nn { siunitx } { unit / duplicate-sticky-per } } + } + { + \@@_parse_add:nnnn + { per } { \int_eval:n { \l_@@_position_int + 1 } } + { \per } { true } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_finalise:n} +% If \cs{per} applies to the current unit, the power needs to be multiplied +% by $-1$. That is done using an \texttt{fp} operation so that non-integer +% powers are supported. The flag for \cs{per} is also removed as this means +% we don't have to check that the original power was positive. To be on +% the safe side, there is a check for a trivial power at this stage. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_finalise:n #1 + { + \tl_set:Nx \l_@@_tmp_tl { per- #1 } + \prop_if_in:NVT \l_@@_parsed_prop \l_@@_tmp_tl + { + \prop_remove:NV \l_@@_parsed_prop + \l_@@_tmp_tl + \tl_set:Nx \l_@@_tmp_tl { power- #1 } + \prop_get:NVNTF + \l_@@_parsed_prop + \l_@@_tmp_tl + \l_@@_part_tl + { + \tl_set:Nx \l_@@_part_tl + { \fp_eval:n { \l_@@_part_tl * -1 } } + \fp_compare:nNnTF \l_@@_part_tl = 1 + { + \prop_remove:NV \l_@@_parsed_prop + \l_@@_tmp_tl + } + { + \prop_put:NVV \l_@@_parsed_prop + \l_@@_tmp_tl \l_@@_part_tl + } + } + { + \prop_put:NVn \l_@@_parsed_prop + \l_@@_tmp_tl { -1 } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_finalise:} +% The final task is to check that there is not a \enquote{dangling} power +% or prefix: these are added to the \enquote{next} unit so are easy to +% test for. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_finalise: + { + \clist_map_inline:nn { per , power , prefix } + { + \tl_set:Nx \l_@@_tmp_tl + { ##1 - \int_eval:n { \l_@@_position_int + 1 } } + \prop_if_in:NVT \l_@@_parsed_prop \l_@@_tmp_tl + { \msg_error:nnn { siunitx } { unit / dangling-part } { ##1 } } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Formatting parsed units} +% +% \begin{variable} +% { +% \l_@@_denominator_bracket_bool , +% \l_@@_forbid_literal_bool , +% \l_@@_fraction_function_tl , +% \l_@@_parse_bool , +% \l_@@_per_symbol_tl , +% \l_@@_qualifier_mode_tl , +% \l_@@_qualifier_phrase_tl +% } +% Set up the options which apply to formatting. +% \begin{macrocode} +\keys_define:nn { siunitx } + { + bracket-unit-denominator .bool_set:N = + \l_@@_denominator_bracket_bool , + forbid-literal-units .bool_set:N = + \l_@@_forbid_literal_bool , + fraction-command .tl_set:N = + \l_@@_fraction_function_tl , + parse-units .bool_set:N = + \l_@@_parse_bool , + per-mode .choice: , + per-mode / fraction .code:n = + { + \bool_set_false:N \l_@@_autofrac_bool + \bool_set_false:N \l_@@_per_symbol_bool + \bool_set_true:N \l_@@_powers_positive_bool + \bool_set_true:N \l_@@_two_part_bool + } , + per-mode / power .code:n = + { + \bool_set_false:N \l_@@_autofrac_bool + \bool_set_false:N \l_@@_per_symbol_bool + \bool_set_false:N \l_@@_powers_positive_bool + \bool_set_false:N \l_@@_two_part_bool + } , + per-mode / power-positive-first .code:n = + { + \bool_set_false:N \l_@@_autofrac_bool + \bool_set_false:N \l_@@_per_symbol_bool + \bool_set_false:N \l_@@_powers_positive_bool + \bool_set_true:N \l_@@_two_part_bool + } , + per-mode / repeated-symbol .code:n = + { + \bool_set_false:N \l_@@_autofrac_bool + \bool_set_true:N \l_@@_per_symbol_bool + \bool_set_true:N \l_@@_powers_positive_bool + \bool_set_false:N \l_@@_two_part_bool + } , + per-mode / symbol .code:n = + { + \bool_set_false:N \l_@@_autofrac_bool + \bool_set_true:N \l_@@_per_symbol_bool + \bool_set_true:N \l_@@_powers_positive_bool + \bool_set_true:N \l_@@_two_part_bool + } , + per-mode / symbol-or-fraction .code:n = + { + \bool_set_true:N \l_@@_autofrac_bool + \bool_set_true:N \l_@@_per_symbol_bool + \bool_set_true:N \l_@@_powers_positive_bool + \bool_set_true:N \l_@@_two_part_bool + } , + per-symbol .tl_set:N = + \l_@@_per_symbol_tl , + qualifier-mode .choices:nn = + { bracket , combine , phrase , subscript } + { \tl_set_eq:NN \l_@@_qualifier_mode_tl \l_keys_choice_tl } , + qualifier-phrase .tl_set:N = + \l_@@_qualifier_phrase_tl + } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_bracket_bool} +% A flag to indicate that the unit currently under construction will require +% brackets if a power is added. +% \begin{macrocode} +\bool_new:N \l_@@_bracket_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_bracket_open_tl, \l_@@_bracket_close_tl} +% Abstracted out but currently purely internal. +% \begin{macrocode} +\tl_new:N \l_@@_bracket_open_tl +\tl_new:N \l_@@_bracket_close_tl +\tl_set:Nn \l_@@_bracket_open_tl { ( } +\tl_set:Nn \l_@@_bracket_close_tl { ) } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_font_bool} +% A flag to control when font wrapping is applied to the output. +% \begin{macrocode} +\bool_new:N \l_@@_font_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_@@_autofrac_bool , +% \l_@@_powers_positive_bool , +% \l_@@_per_symbol_bool , +% \l_@@_two_part_bool +% } +% Dealing with the various ways that reciprocal (\cs{per}) can be handled +% requires a few different switches. +% \begin{macrocode} +\bool_new:N \l_@@_autofrac_bool +\bool_new:N \l_@@_per_symbol_bool +\bool_new:N \l_@@_powers_positive_bool +\bool_new:N \l_@@_two_part_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_numerator_bool} +% Indicates that the current unit should go into the numerator when splitting +% into two parts (fractions or other \enquote{sorted} styles). +% \begin{macrocode} +\bool_new:N \l_@@_numerator_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_qualifier_mode_tl} +% For storing the text of options which are best handled by picking +% function names. +% \begin{macrocode} +\tl_new:N \l_@@_qualifier_mode_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_combine_exp_fp} +% For combining an exponent with the first unit. +% \begin{macrocode} +\fp_new:N \l_@@_combine_exp_fp +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_prefix_exp_bool} +% Used to determine if prefixes are converted into powers. Note that +% while this may be set as an option \enquote{higher up}, at this point it +% is handled as an internal switch (see the two formatting interfaces for +% reasons). +% \begin{macrocode} +\bool_new:N \l_@@_prefix_exp_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_prefix_fp} +% When converting prefixes to powers, the calculations are done as an +% \texttt{fp}. +% \begin{macrocode} +\fp_new:N \l_@@_prefix_fp +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_multiple_fp} +% For multiplying units. +% \begin{macrocode} +\fp_new:N \l_@@_multiple_fp +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_current_tl, \l_@@_part_tl} +% Building up the (partial) formatted unit requires some token list storage. +% Each part of the unit combination that is recovered also has to be +% placed in a token list: this is a dedicated one to leave the scratch +% variables available. +% \begin{macrocode} +\tl_new:N \l_@@_current_tl +\tl_new:N \l_@@_part_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_denominator_tl} +% For fraction-like units, space is needed for the denominator as well as +% the numerator (which is handled using \cs{l_@@_formatted_tl}). +% \begin{macrocode} +\tl_new:N \l_@@_denominator_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_total_int} +% The formatting routine needs to know both the total number of units and +% the current unit. Thus an \texttt{int} is required in addition to +% \cs{l_@@_position_int}. +% \begin{macrocode} +\int_new:N \l_@@_total_int +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_format_parsed:} +% \begin{macro}{\@@_format_parsed_aux:n} +% The main formatting routine is essentially a loop over each position, +% reading the various parts of the unit to build up complete unit +% combination. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_parsed: + { + \int_set_eq:NN \l_@@_total_int \l_@@_position_int + \tl_clear:N \l_@@_denominator_tl + \tl_clear:N \l_@@_formatted_tl + \fp_zero:N \l_@@_prefix_fp + \int_zero:N \l_@@_position_int + \fp_compare:nNnF \l_@@_combine_exp_fp = \c_zero_fp + { \@@_format_combine_exp: } + \fp_compare:nNnF \l_@@_multiple_fp = \c_one_fp + { \@@_format_multiply: } + \bool_lazy_and:nnT + { \l_@@_prefix_exp_bool } + { \l_@@_mass_kilogram_bool } + { \@@_format_mass_to_kilogram: } + \int_do_while:nNnn + \l_@@_position_int < \l_@@_total_int + { + \bool_set_false:N \l_@@_bracket_bool + \tl_clear:N \l_@@_current_tl + \bool_set_false:N \l_@@_font_bool + \bool_set_true:N \l_@@_numerator_bool + \int_incr:N \l_@@_position_int + \clist_map_inline:nn { prefix , unit , qualifier , power , special } + { \@@_format_parsed_aux:n {##1} } + \@@_format_output: + } + \@@_format_finalise: + } +\cs_new_protected:Npn \@@_format_parsed_aux:n #1 + { + \tl_set:Nx \l_@@_tmp_tl + { #1 - \int_use:N \l_@@_position_int } + \prop_get:NVNT \l_@@_parsed_prop + \l_@@_tmp_tl \l_@@_part_tl + { \use:c { @@_format_ #1 : } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_format_combine_exp:} +% To combine an exponent into the first prefix, we first adjust for any +% power, then deal with any existing prefix, before looking up the +% final result. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_combine_exp: + { + \prop_get:NnNF \l_@@_parsed_prop { power-1 } \l_@@_tmp_tl + { \tl_set:Nn \l_@@_tmp_tl { 1 } } + \fp_set:Nn \l_@@_tmp_fp + { \l_@@_combine_exp_fp / \l_@@_tmp_tl } + \prop_get:NnNTF \l_@@_parsed_prop { prefix-1 } \l_@@_tmp_tl + { + \prop_get:NVNF \l_@@_prefixes_forward_prop + \l_@@_tmp_tl \l_@@_tmp_tl + { + \prop_get:NnN \l_@@_parsed_prop { prefix-1 } \l_@@_tmp_tl + \msg_error:nnx { siunitx } { unit / non-numeric-exponent } + { \l_@@_tmp_tl } + \tl_set:Nn \l_@@_tmp_tl { 0 } + } + } + { \tl_set:Nn \l_@@_tmp_tl { 0 } } + \tl_set:Nx \l_@@_tmp_tl + { \fp_eval:n { \l_@@_tmp_fp + \l_@@_tmp_tl } } + \fp_compare:nNnTF \l_@@_tmp_tl = \c_zero_fp + { \prop_remove:Nn \l_@@_parsed_prop { prefix-1 } } + { + \prop_get:NVNTF \l_@@_prefixes_reverse_prop + \l_@@_tmp_tl \l_@@_tmp_tl + { \prop_put:NnV \l_@@_parsed_prop { prefix-1 } \l_@@_tmp_tl } + { + \msg_error:nnx { siunitx } { unit / non-convertible-exponent } + { \l_@@_tmp_tl } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_format_multiply:} +% A simple mapping. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_multiply: + { + \int_step_inline:nn { \prop_count:N \l_@@_parsed_prop } + { + \prop_get:NnNF \l_@@_parsed_prop { power- ##1 } \l_@@_tmp_tl + { \tl_set:Nn \l_@@_tmp_tl { 1 } } + \fp_set:Nn \l_@@_tmp_fp + { \l_@@_tmp_tl * \l_@@_multiple_fp } + \fp_compare:nNnTF \l_@@_tmp_fp = \c_one_fp + { \prop_remove:N \l_@@_parsed_prop { power- ##1 } } + { + \prop_put:Nnx \l_@@_parsed_prop { power- ##1 } + { \fp_use:N \l_@@_tmp_fp } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_format_mass_to_kilogram:} +% To deal correctly with prefix extraction in combination with kilograms, we +% need to coerce the prefix for grams. Currently, only this one special case +% is recorded in the property list, so we do not actually need to check the +% value. If there is then no prefix we do a bit of gymnastics to create one +% and then shift the starting point for the prefix extraction. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_mass_to_kilogram: + { + \int_step_inline:nn \l_@@_total_int + { + \prop_if_in:NnT \l_@@_parsed_prop { command- ##1 } + { + \prop_if_in:NnF \l_@@_parsed_prop { prefix- ##1 } + { + \group_begin: + \bool_set_false:N \l_@@_parsing_bool + \tl_set:Nx \l_@@_tmp_tl { \kilo } + \exp_args:NNNV \group_end: + \tl_set:Nn \l_@@_tmp_tl \l_@@_tmp_tl + \prop_put:NnV \l_@@_parsed_prop { prefix- ##1 } + \l_@@_tmp_tl + \prop_get:NnNF \l_@@_parsed_prop { power- ##1 } + \l_@@_tmp_tl + { \tl_set:Nn \l_@@_tmp_tl { 1 } } + \fp_set:Nn \l_@@_prefix_fp + { \l_@@_prefix_fp - 3 * \l_@@_tmp_tl } + } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_format_bracket:N} +% A quick utility function which wraps up a token list variable in brackets +% if they are required. +% \begin{macrocode} +\cs_new:Npn \@@_format_bracket:N #1 + { + \bool_if:NTF \l_@@_bracket_bool + { + \exp_not:V \l_@@_bracket_open_tl + \exp_not:V #1 + \exp_not:V \l_@@_bracket_close_tl + } + { \exp_not:V #1 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_format_power:} +% \begin{macro}[EXP]{\@@_format_power_aux:wTF} +% \begin{macro} +% { +% \@@_format_power_positive: , +% \@@_format_power_negative: +% } +% \begin{macro}[EXP]{\@@_format_power_negative_aux:w} +% \begin{macro}{\@@_format_power_superscript:} +% Formatting powers requires a test for negative numbers and depending on +% output format requests some adjustment to the stored value. This could be +% done using an \texttt{fp} function, but that would be slow compared to +% a dedicated if lower-level approach based on delimited arguments. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_power: + { + \@@_format_font: + \exp_after:wN \@@_format_power_aux:wTF + \l_@@_part_tl - \q_stop + { \@@_format_power_negative: } + { \@@_format_power_positive: } + } +\cs_new:Npn \@@_format_power_aux:wTF #1 - #2 \q_stop + { \tl_if_empty:nTF {#1} } +% \end{macrocode} +% In the case of positive powers, there is little to do: add the power +% as a subscript (must be required as the parser ensures it's $\neq 1$). +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_power_positive: + { \@@_format_power_superscript: } +% \end{macrocode} +% Dealing with negative powers starts by flipping the switch used to track +% where in the final output the current part should get added to. For the +% case where the output is fraction-like, strip off the |~| then ensure that +% the result is not the trivial power~$1$. Assuming all is well, addition +% to the current unit combination goes ahead. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_power_negative: + { + \bool_set_false:N \l_@@_numerator_bool + \bool_if:NTF \l_@@_powers_positive_bool + { + \tl_set:Nx \l_@@_part_tl + { + \exp_after:wN \@@_format_power_negative_aux:w + \l_@@_part_tl \q_stop + } + \str_if_eq:VnF \l_@@_part_tl { 1 } + { \@@_format_power_superscript: } + } + { \@@_format_power_superscript: } + } +\cs_new:Npn \@@_format_power_negative_aux:w - #1 \q_stop + { \exp_not:n {#1} } +% \end{macrocode} +% Adding the power as a superscript has the slight complication that there +% is the possibility of needing some brackets. The superscript itself uses +% \cs{sp} as that avoids any category code issues and also allows redirection +% at a higher level more readily. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_power_superscript: + { + \exp_after:wN \@@_format_power_superscipt:w + \l_@@_part_tl . . \q_stop + } +\cs_new_protected:Npn \@@_format_power_superscipt:w #1 . #2 . #3 \q_stop + { + \tl_if_blank:nTF {#2} + { + \tl_set:Nx \l_@@_current_tl + { + \@@_format_bracket:N \l_@@_current_tl + ^ { \exp_not:n {#1} } + } + } + { + \tl_set:Nx \l_@@_tmp_tl + { + { } + \tl_if_head_eq_charcode:nNTF {#1} - + { { - } { \exp_not:o { \use_none:n #1 } } } + { { } { \exp_not:n {#1} } } + {#2} + { } + { } + { 0 } + } + \tl_set:Nx \l_@@_current_tl + { + \@@_format_bracket:N \l_@@_current_tl + ^ { \siunitx_number_output:N \l_@@_tmp_tl } + } + } + \bool_set_false:N \l_@@_bracket_bool + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_format_prefix:} +% \begin{macro} +% { +% \@@_format_prefix_exp: , +% \@@_format_prefix_gram: , +% \@@_format_prefix_symbol: +% } +% Formatting for prefixes depends on whether they are to be expressed as +% symbols or collected up to be returned as a power of $10$. The latter +% case requires a bit of processing, which includes checking that the +% conversion is possible and allowing for any power that applies to the +% current unit. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_prefix: + { + \bool_if:NTF \l_@@_prefix_exp_bool + { \@@_format_prefix_exp: } + { \@@_format_prefix_symbol: } + } +\cs_new_protected:Npn \@@_format_prefix_exp: + { + \prop_get:NVNTF \l_@@_prefixes_forward_prop + \l_@@_part_tl \l_@@_part_tl + { + \bool_if:NT \l_@@_mass_kilogram_bool + { + \tl_set:Nx \l_@@_tmp_tl + { command- \int_use:N \l_@@_position_int } + \prop_if_in:NVT \l_@@_parsed_prop \l_@@_tmp_tl + { \@@_format_prefix_gram: } + } + \tl_set:Nx \l_@@_tmp_tl + { power- \int_use:N \l_@@_position_int } + \prop_get:NVNF \l_@@_parsed_prop + \l_@@_tmp_tl \l_@@_tmp_tl + { \tl_set:Nn \l_@@_tmp_tl { 1 } } + \fp_add:Nn \l_@@_prefix_fp + { \l_@@_tmp_tl * \l_@@_part_tl } + } + { \@@_format_prefix_symbol: } + } +% \end{macrocode} +% When the units in use are grams, we may need to deal with conversion to +% kilograms. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_prefix_gram: + { + \tl_set:Nx \l_@@_part_tl + { \int_eval:n { \l_@@_part_tl - 3 } } + \group_begin: + \bool_set_false:N \l_@@_parsing_bool + \tl_set:Nx \l_@@_current_tl { \kilo } + \exp_args:NNNV \group_end: + \tl_set:Nn \l_@@_current_tl \l_@@_current_tl + } +\cs_new_protected:Npn \@@_format_prefix_symbol: + { \tl_set_eq:NN \l_@@_current_tl \l_@@_part_tl } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_format_qualifier:} +% \begin{macro} +% { +% \@@_format_qualifier_bracket: , +% \@@_format_qualifier_combine: , +% \@@_format_qualifier_phrase: , +% \@@_format_qualifier_subscript: +% } +% There are various ways that a qualifier can be added to the output. The +% idea here is to modify the \enquote{base} text appropriately and then add +% to the current unit. Notice that when the qualifier is just treated as +% \enquote{text}, the auxiliary is actually a no-op. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_qualifier: + { + \use:c + { + @@_format_qualifier_ + \l_@@_qualifier_mode_tl : + } + \tl_put_right:NV \l_@@_current_tl \l_@@_part_tl + } +\cs_new_protected:Npn \@@_format_qualifier_bracket: + { + \@@_format_font: + \tl_set:Nx \l_@@_part_tl + { + \exp_not:V \l_@@_bracket_open_tl + \exp_not:V \l_siunitx_unit_font_tl + { \exp_not:V \l_@@_part_tl } + \exp_not:V \l_@@_bracket_close_tl + } + } +\cs_new_protected:Npn \@@_format_qualifier_combine: { } +\cs_new_protected:Npn \@@_format_qualifier_phrase: + { + \@@_format_font: + \tl_set:Nx \l_@@_part_tl + { + \exp_not:V \l_@@_qualifier_phrase_tl + \exp_not:V \l_siunitx_unit_font_tl + { \exp_not:V \l_@@_part_tl } + } + } +\cs_new_protected:Npn \@@_format_qualifier_subscript: + { + \@@_format_font: + \tl_set:Nx \l_@@_part_tl + { + \c_@@_math_subscript_tl + { + \exp_not:V \l_siunitx_unit_font_tl + { \exp_not:V \l_@@_part_tl } + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_format_special:} +% Any special odds and ends are handled by simply making the current +% combination into an argument for the recovered code. Font control +% needs to be \emph{inside} the special formatting here. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_special: + { + \tl_set:Nx \l_@@_current_tl + { + \exp_not:V \l_@@_part_tl + { + \bool_if:NTF \l_@@_font_bool + { \use:n } + { \exp_not:V \l_siunitx_unit_font_tl } + { \exp_not:V \l_@@_current_tl } + } + } + \bool_set_true:N \l_@@_font_bool + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_format_unit:} +% A very simple task: add the unit to the output currently being +% constructed. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_unit: + { + \tl_put_right:NV + \l_@@_current_tl \l_@@_part_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_format_output:} +% \begin{macro} +% {\@@_format_output_aux:, \@@_format_output_denominator:} +% \begin{macro} +% { +% \@@_format_output_aux:nn , +% \@@_format_output_aux:nV , +% \@@_format_output_aux:nv +% } +% The first step here is to make a choice based on whether the current +% part should be stored as part of the numerator or denominator of a +% fraction. In all cases, if the switch \cs{l_@@_numerator_bool} is +% true then life is simple: add the current part to the numerator with +% a standard separator +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_output: + { + \@@_format_font: + \bool_set_false:N \l_@@_bracket_bool + \use:c + { + @@_format_output_ + \bool_if:NTF \l_@@_numerator_bool + { aux: } + { denominator: } + } + } +\cs_new_protected:Npn \@@_format_output_aux: + { + \@@_format_output_aux:nV { formatted } + \l_@@_product_tl + } +% \end{macrocode} +% There are a few things to worry about at this stage if the current part +% is in the denominator. Powers have already been dealt with and some +% formatting outcomes only need a branch at the final point of building +% the entire unit. That means that there are three possible outcomes here: +% if collecting two separate parts, add to the denominator with a product +% separator, or if only building one token list there may be a need to use +% a symbol separator. When the |repeated-symbol| option is in use there may +% be a need to add a leading |1| to the output in the case where the +% first unit is in the denominator: that can be picked up by looking for +% empty output in combination with the flag for using a symbol in the output +% but not a two-part strategy. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_output_denominator: + { + \bool_if:NTF \l_@@_two_part_bool + { + \bool_lazy_and:nnT + { \l_@@_denominator_bracket_bool } + { ! \tl_if_empty_p:N \l_@@_denominator_tl } + { \bool_set_true:N \l_@@_bracket_bool } + \@@_format_output_aux:nV { denominator } + \l_@@_product_tl + } + { + \bool_lazy_and:nnT + { \l_@@_per_symbol_bool } + { \tl_if_empty_p:N \l_@@_formatted_tl } + { \tl_set:Nn \l_@@_formatted_tl { 1 } } + \@@_format_output_aux:nv { formatted } + { + l_@@_ + \bool_if:NTF \l_@@_per_symbol_bool + { per_symbol } + { product } + _tl + } + } + } +\cs_new_protected:Npn \@@_format_output_aux:nn #1#2 + { + \tl_set:cx { l_@@_ #1 _tl } + { + \exp_not:v { l_@@_ #1 _tl } + \tl_if_empty:cF { l_@@_ #1 _tl } + { \exp_not:n {#2} } + \exp_not:V \l_@@_current_tl + } + } +\cs_generate_variant:Nn \@@_format_output_aux:nn { nV , nv } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_format_font:} +% A short auxiliary which checks if the font has been applied to the +% main part of the output: if not, add it and set the flag. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_font: + { + \bool_if:NF \l_@@_font_bool + { + \tl_set:Nx \l_@@_current_tl + { + \exp_not:V \l_siunitx_unit_font_tl + { \exp_not:V \l_@@_current_tl } + } + \bool_set_true:N \l_@@_font_bool + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_format_finalise:} +% \begin{macro} +% { +% \@@_format_finalise_autofrac: , +% \@@_format_finalise_fractional: , +% \@@_format_finalise_power: +% } +% Finalising the unit format is really about picking up the cases involving +% fractions: these require assembly of the parts with the need to add +% additional material in some cases +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_finalise: + { + \tl_if_empty:NF \l_@@_denominator_tl + { + \bool_if:NTF \l_@@_powers_positive_bool + { \@@_format_finalise_fractional: } + { \@@_format_finalise_power: } + } + } +% \end{macrocode} +% For fraction-like output, there are three possible choices and two +% actual styles. In all cases, if the numerator is empty then it is set +% here to |1|. To deal with the \enquote{auto-format} case, the two +% styles (fraction and symbol) are handled in auxiliaries: this allows both +% to be used at the same time! Beyond that, the key here is to use a +% single \cs{tl_set:Nx} to keep down the number of assignments. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_finalise_fractional: + { + \tl_if_empty:NT \l_@@_formatted_tl + { \tl_set:Nn \l_@@_formatted_tl { 1 } } + \bool_if:NTF \l_@@_autofrac_bool + { \@@_format_finalise_autofrac: } + { + \bool_if:NTF \l_@@_per_symbol_bool + { \@@_format_finalise_symbol: } + { \@@_format_finalise_fraction: } + } + } +% \end{macrocode} +% For the \enquote{auto-selected} fraction method, the two other auxiliary +% functions are used to do both forms of formatting. So that everything +% required is available, this needs one group so that the second auxiliary +% receives the correct input. After that it is just a case of applying +% \cs{mathchoice} to the formatted output. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_finalise_autofrac: + { + \group_begin: + \@@_format_finalise_fraction: + \exp_args:NNNV \group_end: + \tl_set:Nn \l_@@_tmp_tl \l_@@_formatted_tl + \@@_format_finalise_symbol: + \tl_set:Nx \l_@@_formatted_tl + { + \mathchoice + { \exp_not:V \l_@@_tmp_tl } + { \exp_not:V \l_@@_formatted_tl } + { \exp_not:V \l_@@_formatted_tl } + { \exp_not:V \l_@@_formatted_tl } + } + } +% \end{macrocode} +% When using a fraction function the two parts are now assembled. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_finalise_fraction: + { + \tl_set:Nx \l_@@_formatted_tl + { + \exp_not:V \l_@@_fraction_function_tl + { \exp_not:V \l_@@_formatted_tl } + { \exp_not:V \l_@@_denominator_tl } + } + } +\cs_new_protected:Npn \@@_format_finalise_symbol: + { + \tl_set:Nx \l_@@_formatted_tl + { + \exp_not:V \l_@@_formatted_tl + \exp_not:V \l_@@_per_symbol_tl + \@@_format_bracket:N \l_@@_denominator_tl + } + } +% \end{macrocode} +% In the case of sorted powers, there is a test to make sure there was +% at least one positive power, and if so a simple join of the two parts +% with the appropriate product. +% \begin{macrocode} +\cs_new_protected:Npn \@@_format_finalise_power: + { + \tl_if_empty:NTF \l_@@_formatted_tl + { + \tl_set_eq:NN + \l_@@_formatted_tl + \l_@@_denominator_tl + } + { + \tl_set:Nx \l_@@_formatted_tl + { + \exp_not:V \l_@@_formatted_tl + \exp_not:V \l_@@_product_tl + \exp_not:V \l_@@_denominator_tl + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Non-Latin character support} +% +% \begin{macro}{\@@_non_latin:n} +% \begin{macro}{\@@_non_latin:nnnn} +% A small amount of code to make it convenient to include non-Latin +% characters in units without having to directly include them in the +% sources directly. +% \begin{macrocode} +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_non_latin:n #1 + { \char_generate:nn {#1} { \char_value_catcode:n {#1} } } + } + { + \cs_new:Npn \@@_non_latin:n #1 + { + \exp_last_unbraced:Nf \@@_non_latin:nnnn + { \char_to_utfviii_bytes:n {#1} } + } + \cs_new:Npn \@@_non_latin:nnnn #1#2#3#4 + { + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#1} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#2} { 13 } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Pre-defined unit components} +% +% Quite a number of units can be predefined: while this is a code-level module, +% there is little point having a unit parser which does not start off able to +% parse any units! +% +% \begin{macro} +% { +% \kilogram , +% \metre , +% \meter , +% \mole , +% \kelvin , +% \candela , +% \second , +% \ampere +% } +% The basic \acro{SI} units: technically the correct spelling is \cs{metre} +% but US users tend to use \cs{meter}. +% \begin{macrocode} +\siunitx_declare_unit:Nn \kilogram { \kilo \gram } +\siunitx_declare_unit:Nn \metre { m } +\siunitx_declare_unit:Nn \meter { \metre } +\siunitx_declare_unit:Nn \mole { mol } +\siunitx_declare_unit:Nn \second { s } +\siunitx_declare_unit:Nn \ampere { A } +\siunitx_declare_unit:Nn \kelvin { K } +\siunitx_declare_unit:Nn \candela { cd } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\gram} +% The gram is an odd unit as it is needed for the base unit kilogram. +% \begin{macrocode} +\siunitx_declare_unit:Nn \gram { g } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \yocto , +% \zepto , +% \atto , +% \femto , +% \pico , +% \nano , +% \micro , +% \milli , +% \centi , +% \deci +% } +% The various \acro{SI} multiple prefixes are defined here: first the small +% ones. +% \begin{macrocode} +\siunitx_declare_prefix:Nnn \yocto { -24 } { y } +\siunitx_declare_prefix:Nnn \zepto { -21 } { z } +\siunitx_declare_prefix:Nnn \atto { -18 } { a } +\siunitx_declare_prefix:Nnn \femto { -15 } { f } +\siunitx_declare_prefix:Nnn \pico { -12 } { p } +\siunitx_declare_prefix:Nnn \nano { -9 } { n } +\siunitx_declare_prefix:Nnx \micro { -6 } { \@@_non_latin:n { "03BC } } +\siunitx_declare_prefix:Nnn \milli { -3 } { m } +\siunitx_declare_prefix:Nnn \centi { -2 } { c } +\siunitx_declare_prefix:Nnn \deci { -1 } { d } +% \end{macrocode} +% \end{macro} +% \begin{macro} +% { +% \deca , +% \deka , +% \hecto , +% \kilo , +% \mega , +% \giga , +% \tera , +% \peta , +% \exa , +% \zetta , +% \yotta +% } +% Now the large ones. +% \begin{macrocode} +\siunitx_declare_prefix:Nnn \deca { 1 } { da } +\siunitx_declare_prefix:Nnn \deka { 1 } { da } +\siunitx_declare_prefix:Nnn \hecto { 2 } { h } +\siunitx_declare_prefix:Nnn \kilo { 3 } { k } +\siunitx_declare_prefix:Nnn \mega { 6 } { M } +\siunitx_declare_prefix:Nnn \giga { 9 } { G } +\siunitx_declare_prefix:Nnn \tera { 12 } { T } +\siunitx_declare_prefix:Nnn \peta { 15 } { P } +\siunitx_declare_prefix:Nnn \exa { 18 } { E } +\siunitx_declare_prefix:Nnn \zetta { 21 } { Z } +\siunitx_declare_prefix:Nnn \yotta { 24 } { Y } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \becquerel , +% \degreeCelsius , +% \coulomb , +% \farad , +% \gray , +% \hertz , +% \henry , +% \joule , +% \katal , +% \lumen , +% \lux +% } +% Named derived units: first half of alphabet. +% \begin{macrocode} +\siunitx_declare_unit:Nn \becquerel { Bq } +\siunitx_declare_unit:Nx \degreeCelsius { \@@_non_latin:n { "00B0 } C } +\siunitx_declare_unit:Nn \coulomb { C } +\siunitx_declare_unit:Nn \farad { F } +\siunitx_declare_unit:Nn \gray { Gy } +\siunitx_declare_unit:Nn \hertz { Hz } +\siunitx_declare_unit:Nn \henry { H } +\siunitx_declare_unit:Nn \joule { J } +\siunitx_declare_unit:Nn \katal { kat } +\siunitx_declare_unit:Nn \lumen { lm } +\siunitx_declare_unit:Nn \lux { lx } +% \end{macrocode} +% \end{macro} +% \begin{macro} +% { +% \newton , +% \ohm , +% \pascal , +% \radian , +% \siemens , +% \sievert , +% \steradian , +% \tesla , +% \volt , +% \watt , +% \weber +% } +% Named derived units: second half of alphabet. +% \begin{macrocode} +\siunitx_declare_unit:Nn \newton { N } +\siunitx_declare_unit:Nx \ohm { \@@_non_latin:n { "03A9 } } +\siunitx_declare_unit:Nn \pascal { Pa } +\siunitx_declare_unit:Nn \radian { rad } +\siunitx_declare_unit:Nn \siemens { S } +\siunitx_declare_unit:Nn \sievert { Sv } +\siunitx_declare_unit:Nn \steradian { sr } +\siunitx_declare_unit:Nn \tesla { T } +\siunitx_declare_unit:Nn \volt { V } +\siunitx_declare_unit:Nn \watt { W } +\siunitx_declare_unit:Nn \weber { Wb } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \astronomicalunit , +% \bel , +% \dalton , +% \day , +% \decibel , +% \electronvolt , +% \hectare , +% \hour , +% \litre , +% \liter , +% \minute , +% \neper , +% \tonne +% } +% Non-\acro{SI}, but accepted for general use. Once again there are two +% spellings, here for litre and with different output in this case. +% \begin{macrocode} +\siunitx_declare_unit:Nn \astronomicalunit { au } +\siunitx_declare_unit:Nn \bel { B } +\siunitx_declare_unit:Nn \decibel { \deci \bel } +\siunitx_declare_unit:Nn \dalton { Da } +\siunitx_declare_unit:Nn \day { d } +\siunitx_declare_unit:Nn \electronvolt { eV } +\siunitx_declare_unit:Nn \hectare { ha } +\siunitx_declare_unit:Nn \hour { h } +\siunitx_declare_unit:Nn \litre { L } +\siunitx_declare_unit:Nn \liter { \litre } +\siunitx_declare_unit:Nn \minute { min } +\siunitx_declare_unit:Nn \neper { Np } +\siunitx_declare_unit:Nn \tonne { t } +% \end{macrocode} +% \end{macro} +% \begin{macro} +% { +% \arcminute , +% \arcsecond , +% \degree +% } +% Arc units: again, non-\acro{SI}, but accepted for general use. +% \begin{macrocode} +\siunitx_declare_unit:Nx \arcminute { \@@_non_latin:n { "02B9 } } +\siunitx_declare_unit:Nx \arcsecond { \@@_non_latin:n { "02BA } } +\siunitx_declare_unit:Nx \degree { \@@_non_latin:n { "00B0 } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\percent} +% For percent, the raw character is the most flexible way of handling output. +% \begin{macrocode} +\siunitx_declare_unit:Nx \percent { \cs_to_str:N \% } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\square, \squared, \cubic, \cubed} +% Basic powers. +% \begin{macrocode} +\siunitx_declare_power:NNn \square \squared { 2 } +\siunitx_declare_power:NNn \cubic \cubed { 3 } +% \end{macrocode} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macrocode} +\msg_new:nnnn { siunitx } { unit / dangling-part } + { Found~#1~part~with~no~unit. } + { + Each~#1~part~must~be~associated~with~a~unit:~a~#1~part~was~found~ + but~no~following~unit~was~given. + } +\msg_new:nnnn { siunitx } { unit / duplicate-part } + { Duplicate~#1~part:~#2. } + { + Each~unit~may~have~only~one~#1:\\ + the~additional~#1~part~'#2'~will~be~ignored. + } +\msg_new:nnnn { siunitx } { unit / duplicate-sticky-per } + { Duplicate~\token_to_str:N \per. } + { + When~the~'sticky-per'~option~is~active,~only~one~ + \token_to_str:N \per \ may~appear~in~a~unit. + } +\msg_new:nnnn { siunitx } { unit / literal } + { Literal~units~disabled. } + { + You~gave~the~literal~input~'#1'~ + but~literal~unit~output~is~disabled. + } +\msg_new:nnnn { siunitx } { unit / non-convertible-exponent } + { Exponent~'#1'~cannot~be~converted~into~a~symbolic~prefix. } + { + The~exponent~'#1'~does~not~match~with~any~of~the~symbolic~prefixes~ + set~up. + } +\msg_new:nnnn { siunitx } { unit / non-numeric-exponent } + { Prefix~'#1'~does~not~have~a~numerical~value. } + { + The~prefix~'#1'~needs~to~be~combined~with~a~number,~but~it~has~no + numerical~value. + } +\msg_new:nnnn { siunitx } { unit / part-before-unit } + { Found~#1~part~before~first~unit:~#2. } + { + The~#1~part~'#2'~must~follow~after~a~unit:~ + it~cannot~appear~before~any~units~and~will~therefore~be~ignored. + } +% \end{macrocode} +% +% \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 } + { + bracket-unit-denominator = true , + forbid-literal-units = false , + fraction-command = \frac , + inter-unit-product = \, , + extract-mass-in-kilograms = true , + parse-units = true , + per-mode = power , + per-symbol = / , + qualifier-mode = subscript , + qualifier-phrase = , + sticky-per = false , + unit-font-command = \mathrm + } +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \begin{thebibliography}{1} +% \bibitem{BIPM} +% \emph{The International System of Units (\acro{SI})}, +% \url{https://www.bipm.org/en/measurement-units/}. +% \bibitem{base-units} +% \emph{SI base units}, +% \url{https://www.bipm.org/en/measurement-units/si-base-units}. +% \end{thebibliography} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx.dtx index 0125c295691..887d0c03118 100644 --- a/Master/texmf-dist/source/latex/siunitx/siunitx.dtx +++ b/Master/texmf-dist/source/latex/siunitx/siunitx.dtx @@ -1,17892 +1,720 @@ % \iffalse meta-comment -%<*internal> -\iffalse -%</internal> -%<*readme> -siunitx - A comprehensive (SI) units package -============================================== - -Physical quantities have both numbers and units, and each -physical quantity should be expressed as the product of a number -and a unit. Typesetting physical quantities requires care to -ensure that the combined mathematical meaning of the number-unit -combination is clear. In particular, the SI units system lays -down a consistent set of units with rules on how these are to be -used. However, different countries and publishers have differing -conventions on the exact appearance of numbers (and units). The -`siunitx` package provides a set of tools for authors to typeset -quantities in a consistent way. The package has an extended set -of configuration options which make it possible to follow -varying typographic conventions with the same input syntax. The -package includes automated processing of numbers and units, and -the ability to control tabular alignment of numbers. - -Installation ------------- - -The package is supplied in `dtx` format and as a pre-extracted -zip file, `siunitx.tds.zip`. The later is most convenient for -most users: simply unzip this in your local texmf directory . If -you want to unpack the `.dtx` yourself, running `tex -siunitx.dtx` will extract the package whereas `latex -siunitx.dtx` will extract it and also typeset the documentation. - -The package requires LaTeX3 support as provided in the -`l3kernel` and `l3packages` bundles. Both of these are available -on [CTAN](http://www.ctan.org/) as ready-to-install zip files. -Suitable versions are available in MiKTeX 2.9 and TeX Live 2015 -(updating the relevant packages online may be necessary). -LaTeX3, and so `siunitx`, requires the e-TeX extensions: these -are available on all modern TeX systems. - -Typesetting the documentation requires a number of packages in -addition to those needed to use the package. This is mainly -because of the number of demonstration items included in the -text. To compile the documentation without error, you will -need the packages: - - `amsmath` - - `booktabs` - - `cancel` - - `caption` - - `cleveref` - - `colortbl` - - `csquotes` - - `datatool` - - `helvet` - - `mathpazo` - - `multirow` - - `listings` - - `pgfplots` - - `xcolor` -%</readme> -%<*internal> -\fi -\def\nameofplainTeX{plain} -\ifx\fmtname\nameofplainTeX\else - \expandafter\begingroup -\fi -%</internal> -%<*install> -\input l3docstrip.tex -\keepsilent -\askforoverwritefalse -\preamble ---------------------------------------------------------------- -The siunitx package --- A comprehensive (SI) units package -Maintained by Joseph Wright -E-mail: joseph.wright@morningstar2.co.uk -Released under the LaTeX Project Public License v1.3c or later -See http://www.latex-project.org/lppl.txt ---------------------------------------------------------------- - -\endpreamble -\postamble -Copyright (C) 2008-2021 by - Joseph Wright <joseph.wright@morningstar2.co.uk> - -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: - http://www.latex-project.org/lppl.txt - -This work is "maintained" (as per LPPL maintenance status) by - Joseph Wright. - -This work consists of the file siunitx.dtx - and the derived files siunitx.pdf, - siunitx.sty and - siunitx.ins. -\endpostamble -\usedir{tex/latex/siunitx} -\generate{ - \file{\jobname.sty}{\from{\jobname.dtx}{package}} - \file{siunitx-abbreviations.cfg} - {\from{\jobname.dtx}{config,abbreviations}} - \file{siunitx-binary.cfg}{\from{\jobname.dtx}{config,binary}} - \file{siunitx-version-1.cfg}{\from{\jobname.dtx}{config,version-1}} -} -%</install> -%<install>\endbatchfile -%<*internal> -\usedir{source/latex/siunitx} -\generate{ - \file{\jobname.ins}{\from{\jobname.dtx}{install}} -} -\nopreamble\nopostamble -\usedir{doc/latex/siunitx} -\generate{ - \file{README.md}{\from{\jobname.dtx}{readme}} -} -\ifx\fmtname\nameofplainTeX - \expandafter\endbatchfile -\else - \expandafter\endgroup -\fi -%</internal> -%<*driver|package> -\RequirePackage{expl3}[2020/01/12] -\RequirePackage{xparse} -%</driver|package> -%<*driver> -\documentclass{l3doc} -\usepackage[german,french,spanish,UKenglish]{babel} -\usepackage[table]{xcolor} -\usepackage{amsmath,booktabs,cancel,caption,colortbl,csquotes} -\usepackage{datatool,helvet,multirow,pgfplots,siunitx,xfrac,xtab} -\usepackage[capitalise]{cleveref} -\usepackage[final]{listings} -\usepackage[osf]{mathpazo} -\AtBeginDocument{\shorthandoff{<>}} -\crefformat{section}{#2Section~#1#3} -\Crefformat{section}{#2Section~#1#3} -\crefformat{subsection}{#2Section~#1#3} -\Crefformat{subsection}{#2Section~#1#3} -\crefformat{figure}{#2Figure~#1#3} -\Crefformat{figure}{#2Figure~#1#3} -\crefformat{table}{#2Table~#1#3} -\Crefformat{table}{#2Table~#1#3} -\crefrangeformat{table}{#3Tables~#1#4 to~#5#2#6} -\Crefrangeformat{table}{#3Tables~#1#4 to~#5#2#6} -\crefmultiformat{table}{#2Tables~#1#3}{ and~#2#1#3}{, #2#1#3}{, and~#2#1#3} -\Crefmultiformat{table}{#2Tables~#1#3}{ and~#2#1#3}{, #2#1#3}{, and~#2#1#3} -% Silence annoying fp package messages -\FPmessagesfalse -\pgfplotsset{compat = newest} -\sisetup{binary-units} -\DeclareSIUnit{\KWH}{kWh} -\DeclareSIPrePower\quartic{4} -\DeclareSIPostPower\tothefourth{4} -\DeclareSIQualifier\catalyst{cat} -\DeclareSIQualifier\isotropic{i} -\DeclareSIQualifier\polymer{pol} -\newlength\mylength -%\DisableImplementation -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -%</driver> -% \fi -% -%\makeatletter -% -%^^A Some short cuts for the tables -%\NewDocumentCommand\DescribePrefix{m}{^^A -% \expandafter\SpecialUsageIndex\expandafter{\csname #1\endcsname}^^A -% #1 & \cs{#1} & \expandafter\si\expandafter{\csname #1\endcsname} -%} -%\NewDocumentCommand\DescribeUnit{m}{^^A -% \expandafter\SpecialUsageIndex\expandafter{\csname #1\endcsname}^^A -% #1 & -% \cs{#1} & -% \expandafter\si\expandafter{\csname #1\endcsname} -%} -%\NewDocumentCommand\DescribeNamedUnit{mm}{^^A -% \expandafter\SpecialUsageIndex\expandafter{\csname #2\endcsname}^^A -% #1 & -% \cs{#2} & -% \expandafter\si\expandafter{\csname #2\endcsname} -%} -% -%^^A For creating examples with nice highlighting of code, and so -%^^A on; based on the system used in the listings source (lstsample). -%\lst@RequireAspects{writefile} -%\newsavebox{\LaTeXdemo@box} -%\lstnewenvironment{LaTeXdemo}[1][code and example] -% {^^A -% \global\let\lst@intname\@empty -% \expandafter\let\expandafter\LaTeXdemo@end -% \csname LaTeXdemo@#1@end\endcsname -% \@nameuse{LaTeXdemo@#1}^^A -% } -% {\LaTeXdemo@end} -%\newcommand*\LaTeXdemo@new[3]{^^A -% \expandafter\newcommand\expandafter*\expandafter -% {\csname LaTeXdemo@#1\endcsname}{#2}^^A -% \expandafter\newcommand\expandafter*\expandafter -% {\csname LaTeXdemo@#1@end\endcsname}{#3}^^A -%} -%\newcommand*\LaTeXdemo@common{^^A -% \setkeys{lst} -% { -% basicstyle = \small\ttfamily, -% basewidth = 0.51em, -% gobble = 3, -% keywordstyle = \color{blue}, -% language = [LaTeX]{TeX}, -% moretexcs = -% { -% addto, -% ampere, -% ang, -% angstrom, -% becquerel, -% bel, -% bit, -% bottomrule, -% byte, -% cancel, -% candela, -% centi, -% color, -% coulomb, -% cubed, -% cubic, -% deci, -% decibel, -% degree, -% degreeCelsius, -% DeclareBinaryPrefix, -% DeclareRobustCommand, -% DeclareSIPostPower, -% DeclareSIPrefix, -% DeclareSIPrePower, -% DeclareSIQualifier, -% DeclareSIUnit, -% DTLdisplaydb, -% DTLforeach, -% DTLiffirstrow, -% DTLmul, -% DTLnewdb, -% DTLnewdbentry, -% DTLnewrow, -% farad, -% fontspec, -% gram, -% gray, -% henry, -% highlight, -% hour, -% Hz, -% joule, -% kelvin, -% kibi, -% kilo, -% kilogram, -% kWh, -% litre, -% lumen, -% lux, -% mathnormal, -% metre, -% mebi, -% micro, -% midrule, -% milli, -% mm, -% mole, -% multirow, -% num, -% numlist, -% numrange, -% of, -% pascal, -% per, -% percent, -% protected, -% radian, -% raiseto, -% robustify, -% rowcolor, -% second, -% selectlanguage, -% SendSettingsToPgf, -% si, -% SI, -% SIlist, -% SIrange, -% sievert, -% sisetup, -% SIUnitSymbolDegree, -% square, -% squared, -% tablenum, -% tesla, -% texorpdfstring, -% text, -% textmu, -% toprule, -% tothe, -% translate, -% unit, -% volt, -% watt -% } -% }^^A -%} -%\newcommand*\LaTeXdemo@input{^^A -% \MakePercentComment -% \catcode`\^^M=10\relax -% \small -% \begingroup -% \setkeys{lst} -% { -% SelectCharTable=\lst@ReplaceInput{\^\^I}{\lst@ProcessTabulator} -% }^^A -% \leavevmode -% \input{\jobname.tmp}^^A -% \endgroup -% \MakePercentIgnore -%} -%\LaTeXdemo@new{code and example} -% {^^A -% \setbox\LaTeXdemo@box=\hbox\bgroup -% \lst@BeginAlsoWriteFile{\jobname.tmp}^^A -% \LaTeXdemo@common -% } -% {^^A -% \lst@EndWriteFile -% \egroup -% \begin{center} -% \ifdim\wd\LaTeXdemo@box>0.48\linewidth\relax -% \hbox to\linewidth{\box\LaTeXdemo@box\hss}^^A -% \begin{minipage}{\linewidth} -% \LaTeXdemo@input -% \end{minipage} -% \else -% \begin{minipage}{0.48\linewidth} -% \LaTeXdemo@input -% \end{minipage} -% \hfill -% \begin{minipage}{0.48\linewidth} -% \hbox to\linewidth{\box\LaTeXdemo@box\hss}^^A -% \end{minipage} -% \fi -% \end{center} -% } -%\LaTeXdemo@new{code and float}{^^A -% \lst@BeginAlsoWriteFile{siunitx.tmp}^^A -% \LaTeXdemo@common -%}{^^A -% \lst@EndWriteFile -% \LaTeXdemo@input -%} -%\LaTeXdemo@new{code only} -% {\LaTeXdemo@common}{} -% -%^^A Turning of the marginpar warnings is a bit awkward. -%^^A It is achieved by temporarily disabling \@latex@warning@no@line -%\let\latex@addmarginpar\@addmarginpar -%\let\latex@warning@no@line\@latex@warning@no@line -%\def\@addmarginpar{^^A -% \let\@latex@warning@no@line\@gobble -% \latex@addmarginpar -% \let\@latex@warning@no@line\latex@warning@no@line -%} -% -%\ProvideDocumentCommand\opt{m}{\texttt{#1}} -% -%\makeatother -% -%\GetFileInfo{\jobname.sty} -% -%\title{^^A -% \textsf{siunitx} --- A comprehensive (SI) units package\thanks{^^A -% This file describes \fileversion, last revised \filedate.^^A -% }^^A -%} -%\author{^^A -% Joseph Wright\thanks -% {^^A -% E-mail: \href{mailto:joseph.wright@morningstar2.co.uk} -% {\texttt{joseph.wright@morningstar2.co.uk}}^^A -% }^^A -%} -%\date{Released \filedate} -% -%\maketitle -% -%\changes{v0.6}{2008/02/18}{First public testing release (as \pkg{si})} -%\changes{v1.0}{2008/06/15}{First official release} -%\changes{v1.1}{2008/09/28}{Package extended to a greater range of unit -% types} -%\changes{v1.2}{2009/01/22}{Correct handling for ranges of numbers -% added} -%\changes{v1.3}{2009/09/20}{Better definition for micro symbol} -%\changes{v1.4}{2010/01/16}{Detect entire document in non-serif font} -%\changes{v2.0}{2010/05/23}{Complete re-write of package to add many new -% features} -%\changes{v2.0c}{2010/06/07}{Mixed literal and macro units now print -% more reliably} -%\changes{v2.0d}{2010/06/10}{Fix error in \opt{table-format} option -% concerning exponent signs} -%\changes{v2.0e}{2010/06/20}{Correct behaviour of \cs{pm} in numbers -% when \texttt{abbreviations} configuration is loaded: problem -% introduced in v2.0c} -%\changes{v2.0f}{2010/06/27}{Fix issue with spacing of multiplication -% sign in text mode} -%\changes{v2.0g}{2010/06/28}{Fix issue with complex numbers in -% quotients} -%\changes{v2.0g}{2010/06/28}{Repair broken \opt{bracket-numbers} -% option} -%\changes{v2.0g}{2010/06/28}{Improve handling of complex root token} -%\changes{v2.0g}{2010/06/28}{Introduce localisation for text values} -%\changes{v2.0h}{2010/06/29}{Actually get localisation into the -% code} -%\changes{v2.0j}{2010/06/30}{Ensure symbols specified in -% \opt{input-symbols} are always printed in math mode} -%\changes{v2.0k}{2010/07/04}{Fix for \pkg{babel} French settings with -% \cs{fg} in tabular material} -%\changes{v2.0l}{2010/07/07}{Further adjustments to \pkg{babel} support} -%\changes{v2.0p}{2010/07/28}{Actually get change from v2.0o working} -%\changes{v2.0q}{2010/07/29}{Errors with free-standing unit code fixed} -%\changes{v2.0q}{2010/07/29}{Deal with bad definition of \cs{color} -% by \pkg{textpos} package} -%\changes{v2.0s}{2010/08/08}{Correct errors in rounding code when -% precision requested is zero decimal places} -%\changes{v2.0t}{2010/08/24}{Replace \cs{exp_afer:wN} in code for -% \cs{per} with \cs{exp_after:wN}} -%\changes{v2.0u}{2010/09/14}{Fix second possible issue with -% \pkg{textpos} package and \cs{color}} -%\changes{v2.0u}{2010/09/14}{Prevent infinite loop if \cs{SI} function -% is used with an empty number} -%\changes{v2.0v}{2010/09/26}{Internal changes reflecting \pkg{expl3} -% updates} -%\changes{v2.0w}{2010/09/29}{Deal with internal function used by -% REV\TeX{} in tables} -%\changes{v2.0x}{2010/10/05}{Fix bug when detecting single prefixes -% and converting prefixes to numbers} -%\changes{v2.1a}{2010/11/05}{Ensure that output of list separators is -% in text mode} -%\changes{v2.1a}{2010/11/05}{Print prefixes correctly in text mode -% when converting to numerical value} -%\changes{v2.1b}{2010/11/05}{Bug in printing code for complex part with -% no number fixed} -%\changes{v2.1b}{2010/11/05}{Bug in hyphen printing when detecting mode -% sorted} -%\changes{v2.1c}{2010/11/11}{Discourage line break between number and -% unit even when it is permitted} -%\changes{v2.1c}{2010/11/14}{After reviewing internals, \cs{numlist}, -% \cs{numrange}, \cs{SIlist} and \cs{SIrange} are documented as -% requiring text mode due to issues with spacing and line breaks} -%\changes{v2.1c}{2010/11/14}{Auto-detect math mode in tables and -% correct output accordingly} -%\changes{v2.1e}{2010/11/22}{Fix issues with text mode symbols and -% \pkg{fontspec} package} -%\changes{v2.1g}{2010/12/21}{Checks on the versions of \pkg{expl3} and -% \pkg{xparse} installed} -%\changes{v2.1h}{2011/01/18}{Detect AMS display-like environments} -%\changes{v2.1j}{2011/02/01}{Allow for loading of \pkg{inputenc} package -% with no options} -%\changes{v2.1k}{2011/02/09}{Bug fix when printing superscript minus -% signs and using \pkg{fontspec} package} -%\changes{v2.1m}{2011/03/18}{Avoid expansion of erroneous literal -% units when these are forbidden} -%\changes{v2.1m}{2011/03/20}{Ensure some output occurs in all cases -% when \opt{round-precision} is set to \opt{0} and \opt{round-mode} -% is set to \opt{places}} -%\changes{v2.1n}{2011/03/31}{Consistent behaviour for -% \opt{round-integer-to-decimal} when \opt{round-precision} is 0} -%\changes{v2.1o}{2011/04/03}{Fix incorrect font choice when -% \pkg{arev} package is loaded} -%\changes{v2.1o}{2011/04/03}{Account for negative exponents -% when using \opt{fixed-exponent} system} -%\changes{v2.1p}{2011/04/04}{Bad table alignment when some rows -% contain comparators fixed} -%\changes{v2.1p}{2011/04/04}{Poor position of comparators in -% numbers fixed} -%\changes{v2.2a}{2011/04/15}{Fix issue with \texttt{*} tokens in -% tabular preambles} -%\changes{v2.2a}{2011/04/15}{Expand macros with arguments correctly -% in tables} -%\changes{v2.2a}{2011/04/16}{Group digits for input containing symbolic -% entries} -%\changes{v2.2a}{2011/04/16}{Insert tokens correctly when last tabular cell -% does not end \texttt{\textbackslash\textbackslash}} -%\changes{v2.2a}{2011/04/16}{Fix bug with literal units and auto-insertion -% of \num{1} when \opt{per-mode} is \opt{symbol}} -%\changes{v2.2b}{2011/04/17}{Make \cs{of} work in hyper-linked sections} -%\changes{v2.2b}{2011/04/17}{Fix bug with \cs{highlight} macro when -% no colour support is loaded} -%\changes{v2.2b}{2011/04/19}{Fix bad formatting of negative exponents when -% using the \opt{output-exponent-marker} option} -%\changes{v2.2c}{2011/04/20}{Fix bad interaction with \pkg{cellspace} package} -%\changes{v2.2d}{2011/04/28}{Fix the \opt{strict} option} -%\changes{v2.2e}{2011/05/23}{Fix incorrect interpretation of complex numbers -% with no real part} -%\changes{v2.2g}{2011/06/02}{Correctly space \cs{degree} and similar units -% in lists and ranges when only a single unit is given} -%\changes{v2.2h}{2011/06/03}{Fix bug in significant figures rounding code -% for some integer part values} -%\changes{v2.2i}{2011/06/15}{Fix \opt{detect-mode} option inside -% table cells} -%\changes{v2.2j}{2011/06/26}{Fix incorrect line breaking in \cs{SIrange}} -%\changes{v2.2k}{2011/06/27}{Fix behaviour of subscripts inside alignments -% when printing in text mode} -%\changes{v2.2l}{2011/06/30}{Fix loss of main unit when \opt{per-mode} is set -% to \opt{symbol} and a pre-unit is used} -%\changes{v2.3}{2011/06/19}{New implementation for alignment in \texttt{S} -% column} -%\changes{v2.3a}{2011/07/09}{Restore fix in v2.2l missing in v2.3} -%\changes{v2.3b}{2011/08/08}{Adjust internal load order so that -% \opt{free-standing-units} works correctly for abbreviations} -%\changes{v2.3c}{2011/07/12}{Fix display of \( \pm \) in numbers when -% \opt{separate-uncertainty} is \opt{true} and literal units are used} -%\changes{v2.3d}{2011/08/18}{Fix broken superscript display in literal unit -% mode} -%\changes{v2.3e}{2011/09/09}{Internal changes to work with \LaTeX3 -% updates} -%\changes{v2.3f}{2011/09/03}{Fix processing of numbers in tables when entire -% number is invalid} -%\changes{v2.3g}{2011/10/06}{Deal with erroneous leading zero in some -% fixed exponent cases} -%\changes{v2.3h}{2011/10/14}{Ensure math mode for exponent products in all -% circumstances} -%\changes{v2.3h}{2011/10/14}{Improvements to output when using \pkg{tex4ht}} -%\changes{v2.4}{2011/11/03}{Reduce number of math mode options, improving -% consistency of output} -%\changes{v2.4a}{2011/11/28}{Extend search-and-replace code for UTF-8 -% characters} -%\changes{v2.4a}{2011/12/04}{Use a more cautious approach to changing -% settings at the start of the document} -%\changes{v2.4b}{2011/12/06}{Erroneous doubled \texttt{\#} corrected} -%\changes{v2.4c}{2011/12/09}{Erroneous check for text mode sanserif font fixed} -%\changes{v2.4d}{2011/12/09}{Fix for edge-case user commands in captions -% where the command clashes with a unit name} -%\changes{v2.4e}{2011/12/11}{Fix issue with \pkg{inputenc} package and -% some of the recent special symbol changes} -%\changes{v2.4f}{2011/12/21}{Allow easier use of headings when not parsing -% numbers in tables} -%\changes{v2.4f}{2011/12/23}{Fix bug with detection of bold font in table -% cells} -%\changes{v2.4g}{2012/01/06}{Update internals to match changes in \pkg{expl3} -% which caused issues with some tokens in numerical arguments} -%\changes{v2.4h}{2012/01/15}{Bug fix for implementation of -% \opt{reciprocal-positive-first}} -%\changes{v2.4i}{2012/01/19}{Bug fix for rounding with large numbers of -% decimal places} -%\changes{v2.4j}{2012/01/26}{Leave vertical mode before any document-level -% commands} -%\changes{v2.4k}{2012/03/22}{Internal changes to allow for \pkg{breqn} -% package tricks} -%\changes{v2.4l}{2012/03/23}{Fix a load-order issue with \pkg{soulpos} -% package} -%\changes{v2.4m}{2012/04/03}{Correct bug in \cs{SIlist} when only a single -% number is given} -%\changes{v2.4n}{2012/04/04}{Allow conversion of numbers with more than -% nine digits to scientific notation} -% \changes{v2.5}{2012/04/07}{Fixed table code to give fewer underfull -% boxes when comparators are used} -% \changes{v2.5}{2015/04/07}{Added \opt{zero-decimal-to-integer} option} -% \changes{v2.5}{2012/04/07}{Added \opt{omit-uncertainty} option} -% \changes{v2.5}{2012/04/08}{Modified \opt{fixed-exponent} such that it can -% remove an exponent part} -% \changes{v2.5}{2012/04/08}{Modified number of intrinsically-mathematical -% options} -% \changes{v2.5a}{2012/04/19}{Fixed support for \enquote{dynamic} nature of spacing -% in free standing units (bug introduced in v2.5)} -% \changes{v2.5b}{2012/04/20}{Fixed treatement \texttt{\^} and \texttt{\_} -% in literal units when \pkg{breqn} package is loaded} -% \changes{v2.5b}{2012/04/20}{Added support for \pkg{eulervm} package} -% \changes{v2.5c}{2012/04/03}{Fixed conversion of numbers with more than -% nine digits when using fixed exponents} -% \changes{v2.5c}{2012/05/03}{Modified treatment entirely empty cells in -% \texttt{s} columns} -% \changes{v2.5d}{2012/06/11}{Extend range of settings automatically altered -% to use UTF-8 values is appropriate} -% \changes{v2.5d}{2012/06/11}{Added \opt{qualifier-phrase} option} -% \changes{v2.5d}{2012/06/11}{Added \opt{phrase} choice for \opt{qualifier-mode} -% option} -% \changes{v2.5e}{2012/06/13}{Fixed an internal error in unit expansion -% introduced in v2.4f} -% \changes{v2.5f}{2012/07/16}{Modified internals to track \pkg{expl3} changes} -% \changes{v2.5g}{2012/07/22}{Fixed \opt{binary-units} option} -% \changes{v2.5h}{2012/08/28}{Modified literal unit test to allow spaces in -% units to be ignored} -% \changes{v2.5i}{2012/09/11}{Fixed alignment of values without uncertainties in -% columns where space is reserved for uncertainties} -% \changes{v2.5j}{2012/09/18}{Fixed rounding when uncertainties are present} -% \changes{v2.5k}{2012/09/20}{Fixed a warning with \pkg{amsmath} related to fraction -% functions} -% \changes{v2.5k}{2012/11/13}{Fixed handling spaces correctly after start of document} -% \changes{v2.5l}{2012/11/21}{Modified internals to track \pkg{expl3} changes} -% \changes{v2.5m}{2012/11/27}{Fixed bug with UTF-8 engines and literal units} -% \changes{v2.5m}{2012/11/27}{Fixed \cs{highlight} behavior in bookmarks} -% \changes{v2.5m}{2012/11/27}{Modified loading of \opt{binary-units}} -% \changes{v2.5m}{2012/11/27}{Fixed right-to-left mode with \pkg{bidi} -% package} -% \changes{v2.5n}{2012/12/29}{Fixed transmission of grouping information by -% \cs{SendSettingsToPgf}} -% \changes{v2.5o}{2013/01/09}{Modified internals to track \pkg{expl3} changes} -% \changes{v2.5p}{2013/02/01}{Fixed printing of \cs{pm} and \cs{mp} when used -% as signs in text mode} -% \changes{v2.5q}{2013/03/10}{Fixed use active \texttt{-} in numbersn} -% \changes{v2.5q}{2013/03/10}{Fixed binary units in tables} -% \changes{v2.5r}{2013/07/11}{Modified internals to track \pkg{expl3} changes} -% \changes{v2.5s}{2013/07/31}{Modified internals to track \pkg{expl3} changes} -% \changes{v2.6}{2013/11/19}{Fixed loading when \pkg{mdwtab} is in use} -% \changes{v2.6}{2014/09/03}{Fixed minus sign when \pkg{tex4ht} is in use} -% \changes{v2.6}{2014/09/03}{Fixed spacing when printing comparators} -% \changes{v2.6}{2014/09/03}{Modified treatment of hard spaces (\texttt{\~}) in -% argument of \cs{num}} -% \changes{v2.6}{2014/09/03}{Modified standard setting for \opt{mode} option -% to \opt{math}} -% \changes{v2.6}{2014/09/04}{Fixed printing of uncertainties when the -% input is an integer and the uncertainty is given as a separate part} -% \changes{v2.6}{2014/09/04}{Fixed definition \cs{fg} in -% bookmarks when \pkg{babel} is loaded with the \opt{french} option} -% \changes{v2.6}{2014/09/05}{Fixed printing exponent in tables when -% \opt{output-exponent-marker} is active} -% \changes{v2.6a}{2014/09/15}{Modified glyph selection when \pkg{fontspec} -% is detected} -% \changes{v2.6b}{2014/09/27}{Modified range of font shapes which can be -% detected} -% \changes{v2.6c}{2014/10/01}{Fixed use of \cs{micro} when \pkg{fontspec} -% is loaded but \pkg{unicode-math} is not} -% \changes{v2.6d}{2014/10/07}{Fixed conversion of \enquote{long} to -% \enquote{short} uncertainty values with integer mantissas} -% \changes{v2.6e}{2015/01/21}{Modified symbol selection where \pkg{fontspec} -% and certain other packages are in use} -% \changes{v2.6f}{2015/04/01}{Fixed \opt{table-sign-exponent} and -% \opt{table-sign-mantissa} options when set \opt{false}} -% \changes{v2.6f}{2015/04/04}{Modified detection of \pkg{mathspec}} -% \changes{v2.6g}{2015/06/24}{Fixed issue with empty table cells} -% \changes{v2.6h}{2015/07/17}{Modified internals to track \pkg{expl3} changes} -% \changes{v2.6i}{2015/08/18}{Fixed rounding of numbers with large numbers of -% digits} -% \changes{v2.6i}{2015/08/18}{Fixed behaviour of \cs{cancel} when printing -% in math mode} -% \changes{v2.6j}{2015/09/01}{Fixed printing of all units when -% \opt{exponent-to-prefix} is set} -% \changes{v2.6j}{2015/09/01}{Fixed appearance of $\pm$ when -% \opt{exponent-to-prefix} is set} -% \changes{v2.6k}{2015/09/12}{Modified internals to track \pkg{expl3} changes} -% \changes{v2.6l}{2015/09/14}{Fixed an internal error} -% \changes{v2.6m}{2015/10/15}{Fixed an issue with \pkg{mwtab}} -% \changes{v2.6n}{2015/12/31}{Modified definition for degree Celsius} -% \changes{v2.6n}{2015/12/31}{Fixed {\aa}ngstr{\"o}m symbol with \LuaTeX{}} -% \changes{v2.6o}{2016/01/05}{Added support for unit powers when converting exponents -% to prefixes} -% \changes{v2.6p}{2016/01/13}{Added support for reciprocal powers when converting -% exponents to prefixes} -% \changes{v2.6p}{2016/01/19}{Modified definition for degree Celsius} -% \changes{v2.6q}{2016/03/01}{Fixed font selection when document commands are -% used inside table cells in \texttt{S} columns} -% \changes{v2.6r}{2016/06/06}{Fixed color safety issue} -% \changes{v2.6r}{2016/08/14}{Fixed internal \pkg{expl3} usage issues} -% \changes{v2.6r}{2016/08/21}{Fixed handling \texttt{e0}} -% \changes{v2.6r}{2016/08/21}{Added a warning when color support is not available} -% \changes{v2.6s}{2016/09/02}{Removed one excess warning} -% \changes{v2.7}{2016/11/11}{Added first documented code level interfaces} -% \changes{v2.7}{2016/11/23}{Fixed behavior when \pkg{cellspace} is applied to -% math mode material} -% \changes{v2.7b}{2017/01/28}{Fixed large numbers in scientific mode} -% \changes{v2.7c}{2017/02/01}{Fixed spacing of integers in tables when -% aligning decimal marker to center} -% \changes{v2.7d}{2017/02/19}{Fixed doubled pre-number tokens in tables} -% \changes{v2.7e}{2017/03/06}{Modified treatment of \texttt{+} } -% \changes{v2.7f}{2017/03/23}{Fixed spacing with \opt{reciprocal-positive-first} -% setting} -% \changes{v2.7g}{2017/05/19}{Fixed an issue with recent \pkg{expl3} update} -% \changes{v2.7h}{2017/06/12}{Modified code internals} -% \changes{v2.7i}{2017/07/23}{Fixed an incorrect variable name} -% \changes{v2.7k}{2017/11/01}{Fixed formatting of units when not parsed} -% \changes{v2.7l}{2018/03/11}{Modified \pkg{unicode-math} support} -% \changes{v2.7m}{2018/03/20}{Modified definition of \cs{astronomicalunit} unit} -% \changes{v2.7n}{2018/04/27}{Fixed symbolic input and digit grouping} -% \changes{v2.7q}{2018/05/11}{Fixed patching of \pkg{cellspace} columns} -% \changes{v2.7r}{2018/05/16}{Fixed issue in tabulars when REV\TeX{} is in use} -% \changes{v2.7s}{2018/05/17}{Modified package date format} -% \changes{v2.7t}{2018/06/08}{Fix inclusion of sign in astronomy-style -% angles} -% \changes{v2.7t}{2019/10/10}{Fix \opt{round-half} when \opt{even} at zero precision} -% \changes{v2.7u}{2020/01/15}{Modified internals to track \pkg{expl3} changes} -% \changes{v2.7v}{2020/02/17}{Fix appearance of superscript decimals with -% comma decimal marker} -% \changes{v2.8}{2020/02/20}{Use companion font symbols (now always loaded by -% the kernel)} -% \changes{v2.8}{2020/02/20}{Allow \cs{ohm} to appear correctly in PDF -% bookmarks} -% \changes{v2.8a}{2020/02/23}{Correct appearance of ohm when -% \pkg{unicode-math} is loaded} -% \changes{v2.8b}{2020/02/25}{Correct appearance of ohm when -% \pkg{newtxmath} is loaded} -% -%\begin{abstract} -% Physical quantities have both numbers and units, and each physical -% quantity should be expressed as the product of a number and a unit. -% Typesetting physical quantities requires care to ensure that the -% combined mathematical meaning of the number--unit combination is -% clear. In particular, the SI units system lays down a consistent -% set of units with rules on how these are to be used. However, -% different countries and publishers have differing conventions on -% the exact appearance of numbers (and units). -% -% The \pkg{siunitx} package provides a set of tools for authors -% to typeset quantities in a consistent way. The package has an -% extended set of configuration options which make it possible to -% follow varying typographic conventions with the same input syntax. -% The package includes automated processing of numbers and units, and -% the ability to control tabular alignment of numbers. -%\end{abstract} -% -%\tableofcontents -% -%\begin{documentation} -% -%\section{Introduction} -% -% The correct application of units of measurement is very important -% in technical applications. For this reason, carefully-crafted -% definitions of a coherent units system have been laid down by the -% \emph{Conf\'erence G\'en\'erale des Poids et -% Mesures} (CGPM): this has resulted in the \emph{Syst\`eme -% International d'Unit\'es} (SI). At the same time, typographic -% conventions for correctly displaying both numbers and units exist to -% ensure that no loss of meaning occurs in printed matter. -% -% \pkg{siunitx} aims to provide a unified method for \LaTeX{} users to -% typeset numbers and units correctly and easily. The design -% philosophy of \pkg{siunitx} is to follow the agreed rules by -% default, but to allow variation through option settings. In this way, -% users can use \pkg{siunitx} to follow the requirements of -% publishers, co-authors, universities, \emph{etc}.~without needing to -% alter the input at all. -% -%\section{Installation} -% -% The package is supplied in \file{dtx} format and as a pre-extracted -% zip file, \file{\jobname.tds.zip}. The later is most convenient for -% most users: simply unzip this in your local texmf directory and -% run \texttt{texhash} to update the database of file locations. If -% you want to unpack the \file{dtx} yourself, running -% \texttt{tex \jobname.dtx} will extract the package whereas -% \texttt{latex \jobname.dtx} will extract it and also typeset the -% documentation. -% -% The package requires \LaTeX3 support as provided in the -% \pkg{l3kernel} and \pkg{l3packages} bundles. Both of these are available -% on \href{http://www.ctan.org}{\textsc{ctan}} as ready-to-install -% zip files. Suitable versions are available in MiK\TeX{}~2.9 and -% \TeX{}~Live 2015 (updating the relevant packages online may be -% necessary). \LaTeX3, and so \pkg{siunitx}, requires the \eTeX{} -% extensions: these are available on all modern \TeX{} systems. -% -% Typesetting the documentation requires a number of packages in -% addition to those needed to use the package. This is mainly -% because of the number of demonstration items included in the text. To -% compile the documentation without error, you will need the packages: -%\begin{itemize} -% \item \pkg{amsmath} -% \item \pkg{booktabs} -% \item \pkg{cancel} -% \item \pkg{caption} -% \item \pkg{cleveref} -% \item \pkg{colortbl} -% \item \pkg{csquotes} -% \item \pkg{helvet} -% \item \pkg{mathpazo} -% \item \pkg{multirow} -% \item \pkg{listings} -% \item \pkg{pgfplots} -% \item \pkg{xcolor} -%\end{itemize} -% -%\section{\pkg{siunitx} for the impatient} -% -% The package provides the user macros: -%\begin{itemize} -% \item \cs{ang}\oarg{options}\marg{angle} -% \item \cs{num}\oarg{options}\marg{number} -% \item \cs{si}\oarg{options}\marg{unit} -% \item \cs{SI}\oarg{options}\marg{number}\oarg{pre-unit}\marg{unit} -% \item \cs{numlist}\oarg{options}\marg{numbers} -% \item \cs{numrange}\oarg{options}\marg{numbers}\marg{number2} -% \item \cs{SIlist}\oarg{options}\marg{numbers}\marg{unit} -% \item \cs{SIrange}\oarg{options}\marg{number1}\marg{number2}^^A -% \marg{unit} -% \item \cs{sisetup}\marg{options} -% \item \cs{tablenum}\oarg{options}\marg{number} -%\end{itemize} -% plus the \texttt{S} and \texttt{s} column types for decimal -% alignments and units in tabular environments. These user macros and -% column types are designed for -% typesetting numbers and units with control of appearance and with -% intelligent processing. -% -% Numbers are processed with understanding of exponents, complex numbers -% and multiplication. -%\begin{LaTeXdemo} -% \num{12345,67890} \\ -% \num{1+-2i} \\ -% \num{.3e45} \\ -% \num{1.654 x 2.34 x 3.430} -%\end{LaTeXdemo} -% -% The unit system can interpret units given as text to be used directly -% or as macro-based units. In the latter case, different formatting is -% possible. -%\begin{LaTeXdemo} -% \si{kg.m.s^{-1}} \\ -% \si{\kilogram\metre\per\second} \\ -% \si[per-mode=symbol] -% {\kilogram\metre\per\second} \\ -% \si[per-mode=symbol] -% {\kilogram\metre\per\ampere\per\second} -%\end{LaTeXdemo} -% -% Simple lists and ranges of numbers can be handled. -%\begin{LaTeXdemo} -% \numlist{10;20;30} \\ -% \SIlist{0.13;0.67;0.80}{\milli\metre} \\ -% \numrange{10}{20} \\ -% \SIrange{0.13}{0.67}{\milli\metre} -%\end{LaTeXdemo} -% -% By default, all text is typeset in the current upright math -% font. This can be changed by setting the appropriate options: -% "\sisetup{detect-all}" will use the current font for typesetting. -% -%\section{Using the \pkg{siunitx} package} -% -%\subsection{Loading the package} -% -% The package should be loaded in the usual \LaTeXe{} way. -%\begin{LaTeXdemo}[code only] -% \usepackage{siunitx} -%\end{LaTeXdemo} -% The key--value options described later in this document can be used -% when loading the package, for example -%\begin{LaTeXdemo}[code only] -% \usepackage[version-1-compatibility]{siunitx} -%\end{LaTeXdemo} -% to use options from version 1 of the package. -% -%\subsection{Numbers} -% -%\begin{function}{\num} -% \begin{syntax} -% \cs{num}\oarg{options}\marg{number} -% \end{syntax} -%\end{function} -% Numbers are automatically formatted by the \cs{num} macro. This -% takes one optional argument, \meta{options}, and one mandatory one, -% \meta{number}. The contents of \meta{number} are automatically -% formatted. The formatter removes both \enquote{soft} (\verb*" ") and -% \enquote{hard} spaces (\cs{,} and "~"), automatically identifies -% exponents (by default -% marked using \texttt{e}, \texttt{E}, \texttt{d} or \texttt{D}) and -% adds the appropriate spacing of large numbers. With the standard -% settings a leading zero is added before a decimal marker, if needed: -% both \enquote{\texttt{.}} and \enquote{\texttt{,}} are recognised as -% decimal markers. -%\begin{LaTeXdemo} -% \num{123} \\ -% \num{1234} \\ -% \num{12345} \\ -% \num{0.123} \\ -% \num{0,1234} \\ -% \num{.12345} \\ -% \num{3.45d-4} \\ -% \num{-e10} -%\end{LaTeXdemo} -% Note that numbers are parsed before typesetting, which does -% have a performance overhead (only obvious with very large amounts -% of numerical input). The parser understands a range of input syntaxes, -% as demonstrated above. -% -%\begin{function}{\numlist} -% \begin{syntax} -% \cs{numlist}\oarg{options}\marg{numbers} -% \end{syntax} -%\end{function} -%\changes{v2.0}{2010/05/23}{Introduced \cs{numlist} and \cs{SIlist} -% functions} -% Lists of numbers may be processed using the \cs{numlist} function. -% Each \meta{number} is given within the list of \meta{numbers} within -% a brace pair, as the list can have a flexible length. This function -% should be used in text mode, a common feature of all of the list and -% range functions provided by \pkg{siunitx}.\footnote{The reason for -% this restriction is that the separators between items may involve -% text-mode spaces which must be able to vanish at line breaks. It is -% not possible to achieve this effect from inside math mode.} -%\begin{LaTeXdemo} -% \numlist{10;30;50;70} -%\end{LaTeXdemo} -% -%\begin{function}{\numrange} -% \begin{syntax} -% \cs{numrange}\oarg{options}\marg{number1}\marg{number2} -% \end{syntax} -%\end{function} -% Simple ranges of numbers can be handled using the \cs{numrange} -% function. This acts in the same way as \cs{num}, but inserts a -% phrase or other text between the two entries. This function should -% be used in text mode. -%\begin{LaTeXdemo} -% \numrange{10}{30} -%\end{LaTeXdemo} -% -%\begin{function}{\ang} -% \begin{syntax} -% \cs{ang}\oarg{options}\marg{angle} -% \end{syntax} -%\end{function} -% Angles can be typeset using the \cs{ang} command. The -% \meta{angle} can be given either as a decimal number or as a -% semi-colon separated list of degrees, minutes and seconds, which -% is called \enquote{arc format} in this document. The numbers which -% make up an angle are processed using the same system as other numbers. -%\begin{LaTeXdemo} -% \ang{10} \\ -% \ang{12.3} \\ -% \ang{4,5} \\ -% \ang{1;2;3} \\ -% \ang{;;1} \\ -% \ang{+10;;} \\ -% \ang{-0;1;} -%\end{LaTeXdemo} -% -%\subsection{Units} -% -%\begin{function}{\si} -% \begin{syntax} -% \cs{si}\oarg{options}\marg{unit} -% \end{syntax} -%\end{function} -% The symbol for a unit can be typeset using the \cs{si} macro: this -% provides full control over output format for the unit. Like the -% \cs{num} macro, \cs{si} takes one optional and one mandatory -% argument. The unit formatting system can accept two types of input. -% When the \meta{si} contains literal items (for example letters or -% numbers) then \pkg{siunitx} converts \texttt{.} and "~" into -% inter-unit product and correctly positions sub- and superscripts -% specified using "_" and "^". The formatting methods will work with -% both math and text mode. -%\begin{LaTeXdemo} -% \si{kg.m/s^2} \\ -% \si{g_{polymer}~mol_{cat}.s^{-1}} -%\end{LaTeXdemo} -% The second operation mode for the \cs{si} macro is an -% \enquote{interpreted} system, Here, each unit, SI multiple prefix and -% power is given a macro name. These are entered in a method very -% similar to the reading of the unit name in English. -%\begin{LaTeXdemo} -% \si{\kilo\gram\metre\per\square\second} \\ -% \si{\gram\per\cubic\centi\metre} \\ -% \si{\square\volt\cubic\lumen\per\farad} \\ -% \si{\metre\squared\per\gray\cubic\lux} \\ -% \si{\henry\second} -%\end{LaTeXdemo} -% On its own, this is less convenient than the direct method, although -% it does use meaning rather than appearance for input. However, the -% package allows you to define new unit macros; a large number of -% pre-defined abbreviations are also supplied. More importantly, by -% defining macros for units, instead of literal input, new -% functionality is made available. By altering the settings used by the -% package, the same input can yield a variety of different output -% formats. For example, the \cs{per} macro can give reciprocal powers, -% slashes or be used to construct units as fractions. -% -%\begin{function}{\SI} -% \begin{syntax} -% \cs{SI}\oarg{options}\marg{number}\oarg{preunit}\marg{unit} -% \end{syntax} -%\end{function} -% Very often, numbers and units are given together. Formally, the -% value of a quantity is the product of the number and the unit, the -% space being regarded as a multiplication sign \cite{SI:5.3.3}. The -% \cs{SI} macro combines the functionality of \cs{num} and -% \cs{si}, and makes this both possible and easy. The \meta{number} -% and \meta{si} arguments work exactly like those for the \cs{num} and -% \cs{si} macros, respectively. \meta{preunit} is a unit to be typeset -% \emph{before} the numerical value (most likely to be a currency). -%\begin{LaTeXdemo} -% \SI[mode=text]{1.23}{J.mol^{-1}.K^{-1}} \\ -% \SI{.23e7}{\candela} \\ -% \SI[per-mode=symbol]{1.99}[\$]{\per\kilogram} \\ -% \SI[per-mode=fraction]{1,345}{\coulomb\per\mole} -%\end{LaTeXdemo} -% -% It is possible to set up the unit macros to be available outside of -% the \cs{SI} and \cs{si} functions. This is not the standard -% behaviour as there is the risk of name clashes (for example, \cs{bar} -% is used by other packages, and several packages define \cs{degree}). -% Full details of using \enquote{stand alone} units are found in -% \cref{sec:units:creating}. -% -%\begin{function}{\SIlist} -% \begin{syntax} -% \cs{SIlist}\oarg{options}\marg{numbers}\marg{unit} -% \end{syntax} -%\end{function} -% Lists of numbers with units can be handled using the \cs{SIlist} -% function. The behaviour of this function is similar to \cs{numlist}, -% but with the addition of a unit to each number. This function should -% be used in text mode. -%\begin{LaTeXdemo} -% \SIlist{10;30;45}{\metre} -%\end{LaTeXdemo} -% -%\begin{function}{\SIrange} -% \begin{syntax} -% \cs{SIrange}\oarg{options}\marg{number1}\marg{number2}\marg{unit} -% \end{syntax} -%\end{function} -% Ranges of numbers with units can be handled using the \cs{SIrange} -% function. The behaviour of this function is similar to \cs{numrange}, -% but with the addition of a unit to each number. This function should -% be used in text mode. -%\begin{LaTeXdemo} -% \SIrange{10}{30}{\metre} -%\end{LaTeXdemo} -% -%\subsection{The unit macros} -% -% The package always defines the basic set of SI units with macro names. -% This includes the base SI units, the derived units with special names -% and the prefixes. A small number of powers are also given pre-defined -% names. Full details of units in the SI are available -% on-line~\cite{BIPM}. -% -% The seven base SI units are always defined -% (\cref{tab:unit:base}). In addition, the macro \cs{meter} is -% available as an alias for \cs{metre}, for users of US spellings. -% The full details of the base units are given in the SI -% Brochure~\cite{SI:2.1}. -%\begin{table} -% \caption{SI base units.} -% \label{tab:unit:base} -% \centering -% \begin{tabular}{lll} -% \toprule -% Unit & Macro & Symbol \\ -% \midrule -% \DescribeUnit{ampere} \\ -% \DescribeUnit{candela} \\ -% \DescribeUnit{kelvin} \\ -% \DescribeUnit{kilogram} \\ -% \DescribeUnit{metre} \\ -% \DescribeUnit{mole} \\ -% \DescribeUnit{second} \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -% The SI also lists a number of units which have special names and -% symbols \cite{SI:2.2.2}: these are listed in -% \cref{tab:unit:derived}. As a short-cut for the degree Celsius, -% the unit \cs{celsius} is defined equivalent to \cs{degreeCelsius} . -%\begin{table} -% \caption{Coherent derived units in the SI with special names and -% symbols.} -% \label{tab:unit:derived} -% \centering -% \begin{tabular}{lll>{\qquad}lll} -% \toprule -% Unit & Macro & Symbol & Unit & Macro & Symbol \\ -% \midrule -% \DescribeUnit{becquerel} & -% \DescribeUnit{newton} \\ -% \DescribeNamedUnit{degree Celsius}{degreeCelsius} & -% \DescribeUnit{ohm} \\ -% \DescribeUnit{coulomb} & -% \DescribeUnit{pascal} \\ -% \DescribeUnit{farad} & -% \DescribeUnit{radian} \\ -% \DescribeUnit{gray} & -% \DescribeUnit{siemens} \\ -% \DescribeUnit{hertz} & -% \DescribeUnit{sievert} \\ -% \DescribeUnit{henry} & -% \DescribeUnit{steradian} \\ -% \DescribeUnit{joule} & -% \DescribeUnit{tesla} \\ -% \DescribeUnit{katal} & -% \DescribeUnit{volt} \\ -% \DescribeUnit{lumen} & -% \DescribeUnit{watt} \\ -% \DescribeUnit{lux} & -% \DescribeUnit{weber} \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -% In addition to the official SI units, \pkg{siunitx} also provides -% macros for a number of units which are accepted for use in the SI -% although they are not SI units. \cref{tab:unit:accepted} lists -% the \enquote{accepted} units \cite{SI:4.1.T6}. Some units are -% fundamental physical quantities, and these are non-SI but can be used -% within the SI (\cref{tab:unit:physical}, \cite{SI:4.1.T7}). -% There are also a set of non-SI units which are used in certain -% defined circumstances (\cref{tab:unit:other}), although they are -% not necessarily officially sanctioned \cite{SI:4.1.T8}. -% \DescribeMacro{\percent} -% The package also predefines the \cs{percent} macro. While this is not a -% unit, it is used in the same way in many cases and is therefore provided -% on the grounds of realism. -%\begin{table} -% \caption{Non-SI units accepted for use with the -% International System of Units.} -% \label{tab:unit:accepted} -% \centering -% \begin{tabular}{lll} -% \toprule -% Unit & Macro & Symbol \\ -% \midrule -% \DescribeUnit{day} \\ -% \DescribeUnit{degree} \\ -% \DescribeUnit{hectare} \\ -% \DescribeUnit{hour} \\ -% \DescribeUnit{litre} \\ -% \SpecialUsageIndex{\liter}^^A -% & \cs{liter} & \si{\liter} \\ -% \DescribeNamedUnit{minute (plane angle)}{arcminute} \\ -% \DescribeNamedUnit{minute (time)}{minute} \\ -% \DescribeNamedUnit{second (plane angle)}{arcsecond} \\ -% \DescribeUnit{tonne} \\ -% \bottomrule -% \end{tabular} -%\end{table} -%\begin{table} -% \changes{v2.0j}{2010/06/30}{Correct \cs{hartree} unit appearance} -% \caption{Non-SI units whose values in SI units must be obtained -% experimentally.} -% \label{tab:unit:physical} -% \centering -% \begin{tabular}{lll} -% \toprule -% Unit & Macro & Symbol \\ -% \midrule -% \DescribeNamedUnit{astronomical unit}{astronomicalunit} \\ -% \DescribeNamedUnit{atomic mass unit}{atomicmassunit} \\ -% \DescribeUnit{bohr} \\ -% \DescribeNamedUnit{speed of light}{clight} \\ -% \DescribeUnit{dalton} \\ -% \DescribeNamedUnit{electron mass}{electronmass} \\ -% \DescribeUnit{electronvolt} \\ -% \DescribeNamedUnit{elementary charge}{elementarycharge} \\ -% \DescribeUnit{hartree} \\ -% \DescribeNamedUnit{reduced Planck constant}{planckbar} \\ -% \bottomrule -% \end{tabular} -%\end{table} -%\begin{table} -% \caption{Other non-SI units.} -% \label{tab:unit:other} -% \centering -% \begin{tabular}{lll} -% \toprule -% Unit & Macro & Symbol \\ -% \midrule -% \DescribeNamedUnit{{\aa}ngstr{\"o}m}{angstrom} \\ -% \DescribeUnit{bar} \\ -% \DescribeUnit{barn} \\ -% \DescribeUnit{bel} \\ -% \DescribeUnit{decibel} \\ -% \DescribeUnit{knot} \\ -% \DescribeNamedUnit{millimetre of mercury}{mmHg} \\ -% \DescribeNamedUnit{nautical mile}{nauticalmile} \\ -% \DescribeUnit{neper} \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -% In addition to the units themselves, \pkg{siunitx} provides -% pre-defined macros for all of the SI prefixes -% (\cref{tab:unit:prefix}, \cite{SI:3.1}). The spelling -% \enquote{\cs{deka}} is provided for US users as an alternative to -% \cs{deca}. -%\begin{table} -% \caption{SI prefixes.} -% \label{tab:unit:prefix} -% \centering -% \begin{tabular}{llc>{$}l<{$}>{\qquad}llc>{$}l<{$}} -% \toprule -% Prefix & Macro & Symbol & \multicolumn{1}{l}{Power} & -% Prefix & Macro & Symbol & \multicolumn{1}{l}{Power} \\ -% \midrule -% \DescribePrefix{yocto} & -24 & -% \DescribePrefix{deca} & 1 \\ -% \DescribePrefix{zepto} & -21 & -% \DescribePrefix{hecto} & 2 \\ -% \DescribePrefix{atto} & -18 & -% \DescribePrefix{kilo} & 3 \\ -% \DescribePrefix{femto} & -15 & -% \DescribePrefix{mega} & 6 \\ -% \DescribePrefix{pico} & -12 & -% \DescribePrefix{giga} & 9 \\ -% \DescribePrefix{nano} & -9 & -% \DescribePrefix{tera} & 12 \\ -% \DescribePrefix{micro} & -6 & -% \DescribePrefix{peta} & 15 \\ -% \DescribePrefix{milli} & -3 & -% \DescribePrefix{exa} & 18 \\ -% \DescribePrefix{centi} & -2 & -% \DescribePrefix{zetta} & 21 \\ -% \DescribePrefix{deci} & -1 & -% \DescribePrefix{yotta} & 24 \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -% A small number of pre-defined powers are provided as macros. -% \cs{square} and \cs{cubic} are intended for use before units, with -% \cs{squared} and \cs{cubed} going after the unit. -%\begin{LaTeXdemo} -% \si{\square\becquerel} \\ -% \si{\joule\squared\per\lumen} \\ -% \si{\cubic\lux\volt\tesla\cubed} -%\end{LaTeXdemo} -% Generic powers can be inserted on a one-off basis using the \cs{tothe} -% and \cs{raiseto} macros. These are the only macros for units which -% take an argument: -%\begin{LaTeXdemo} -% \si{\henry\tothe{5}} \\ -% \si{\raiseto{4.5}\radian} -%\end{LaTeXdemo} -% Reciprocal powers are indicated using the \cs{per} macro. This applies -% to the next unit only, unless the \opt{sticky-per} option -% is turned on. -%\begin{LaTeXdemo} -% \si{\joule\per\mole\per\kelvin} \\ -% \si{\joule\per\mole\kelvin} \\ -% \si{\per\henry\tothe{5}} \\ -% \si{\per\square\becquerel} -%\end{LaTeXdemo} -%\changes{v2.0i}{2010/06/29}{Correct behaviour of \cs{of} function -% so it actually works (bug introduced in v2.0d)} -% As for generic powers, generic qualifiers are also available using -% the \cs{of} function: -%\begin{LaTeXdemo} -% \si{\kilogram\of{metal}} \\ -% \SI[qualifier-mode = brackets] -% {0.1}{\milli\mole\of{cat}\per\kilogram\of{prod}} -%\end{LaTeXdemo} -% -%\changes{v2.2}{2011/04/05}{Support use of \cs{cancel} macro in units} -%\changes{v2.2}{2011/04/06}{New \cs{highlight} macro for selective -% colour in units} -% If the \pkg{cancel} package is loaded, it is possible to -% \enquote{cancel out} units using the \cs{cancel} macro. This applies -% to the next unit, in a similar manner to a prefix. The \cs{highlight} -% macro is also available to selectively colour units. Both \cs{cancel} -% and \cs{highlight} are of course outside of the normal semantic -% meaning of units, but are provided as they may be useful in some -% cases. -%\begin{LaTeXdemo} -% \si[per-mode = fraction] -% {\cancel\kilogram\metre\per\cancel\kilogram\per\second} \\ -% \si{\highlight{red}\kilogram\metre\per\second} \\ -% \si[unit-color = purple] -% {\highlight{red}\kilogram\metre\per\second} -%\end{LaTeXdemo} -% -% When using the unit macros, the package is able to validate the -% input given. As part of this, stand-alone unit prefixes can be used -% with the \cs{si} macro -%\begin{LaTeXdemo} -% \si{\kilo} \\ -% \si{\micro} \\ -% \si[prefixes-as-symbols = false]{\kilo} -%\end{LaTeXdemo} -% However, the package only allows a single prefix to be used in this -% way: multiple prefixes will give an error, as will trying to give -% a number without a unit. So the following will raise errors: -%\begin{LaTeXdemo}[code only] -% \si{\kilo\gram\micro} \\ -% \SI{10}{\micro} -%\end{LaTeXdemo} -% -%\subsection{Creating new macros} -% -% The various macro components of a unit have to be defined before -% they can be used. The package supplies a number of common definitions, -% but new definitions are also possible. As the definition of a logical -% unit should remain the same in a single document, these creation -% functions are all preamble-only. -% -%\DescribeMacro{\DeclareSIUnit} -%\changes{v2.2}{2011/04/01}{Extend \cs{DeclareSIUnit} to take -% optional argument} -%\begin{syntax} -% \cs{DeclareSIUnit}\oarg{options}\marg{unit}\marg{symbol} -%\end{syntax} -% New units are produced using the \cs{DeclareSIUnit} macro. -% \meta{symbol} can contain literal input, other units, multiple -% prefixes, powers and \cs{per}, although literal text should not be -% intermixed with unit macros. Units can be created with \meta{options} -% from the usual list understood by \pkg{siunitx}, and apply the -% specific unit macro only. The (first) optional argument to \cs{SI} -% and \cs{si} can be used to override the settings for the unit. A -% typical example is the \cs{degree} unit. -%\begin{LaTeXdemo} -% \SI{3.1415}{\degree} -%\end{LaTeXdemo} -% This is declared in the package as: -%\begin{LaTeXdemo}[code only] -% \DeclareSIUnit[number-unit-product = {}] -% \degree{\SIUnitSymbolDegree} -%\end{LaTeXdemo} -% The spacing can still be altered at point of use: -%\begin{LaTeXdemo} -% \SI{67890}{\degree} \\ -% \SI[number-unit-product = \,]{67890}{\degree} -%\end{LaTeXdemo} -% The meaning of a pre-defined unit can be altered by using -% \cs{DeclareSIUnit} after loading \pkg{siunitx}. This will overwrite -% the original definition with the newer version. -% -%\DescribeMacro{\DeclareSIPrefix} -%\DescribeMacro{\DeclareBinaryPrefix} -%\begin{syntax} -% \cs{DeclareSIPrefix}\marg{prefix}\marg{symbol}\marg{powers-ten} -% \cs{DeclareBinaryPrefix}\marg{prefix}\marg{symbol}\marg{powers-two} -%\end{syntax} -% The standard SI powers of ten are defined by the package, and are -% described above. However, the user can define new prefixes with -% \cs{DeclareSIPrefix}. The \cs{DeclareBinaryPrefix} function is also -% available for creating binary prefixes, with the same syntax -% (\meta{powers-ten} being replaced by \meta{powers-two}). For -% example, \cs{kilo} and \cs{kibi} are defined: -%\begin{LaTeXdemo}[code only] -% \DeclareSIPrefix\kilo{k}{3} -% \DeclareBinaryPrefix\kibi{Ki}{10} -%\end{LaTeXdemo} -% -%\DescribeMacro{\DeclareSIPostPower} -%\DescribeMacro{\DeclareSIPrePower} -%\begin{syntax} -% \cs{DeclareSIPostPower}\marg{power}\marg{num} -% \cs{DeclareSIPrePower}\marg{power}\marg{num} -%\end{syntax} -% These create power macros to appear before or after the unit they -% apply to. For example, the preamble to a document might contain: -%\begin{LaTeXdemo}[code only] -% \DeclareSIPrePower\quartic{4} -% \DeclareSIPostPower\tothefourth{4} -%\end{LaTeXdemo} -% with the functions then used in the document as: -%\begin{LaTeXdemo} -% \si{\kilogram\tothefourth}\\ -% \si{\quartic\metre} -%\end{LaTeXdemo} -% -%\DescribeMacro{\DeclareSIQualifier} -% Following the syntax of the other macros, qualifiers are created -% with the syntax \cs{DeclareSIQualifier}\marg{qualifier}\marg{symbol}. -% In contrast to the other parts of a unit, there are no pre-defined -% qualifiers. It is therefore entirely up to the user to create these. -% For example, to identify the mass of a product created when using -% a particular catalyst, the preamble could contain: -%\begin{LaTeXdemo}[code only] -% \DeclareSIQualifier\polymer{pol} -% \DeclareSIQualifier\catalyst{cat} -%\end{LaTeXdemo} -% and then in the body the document could read: -%\begin{LaTeXdemo} -% \SI{1.234}{\gram\polymer\per\mole\catalyst\per\hour} -%\end{LaTeXdemo} -% -%\subsection{Tabular material} -% -% Aligning numbers in tabular content is handled by a new column -% type, the \texttt{S} column. This new column type can align material -% using a number of different strategies, with the aim of flexibility -% of output without needing to alter the input. The method used -% as standard is to place the decimal marker in the number at the -% centre of the cell and to align the material appropriately -% (\cref{tab:S:standard}). -% -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Standard behaviour of the \texttt{S} column type.} -% \label{tab:S:standard} -% \centering -% \begin{tabular}{S} -% \toprule -% {Some Values} \\ -% \midrule -% 2.3456 \\ -% 34.2345 \\ -% -6.7835 \\ -% 90.473 \\ -% 5642.5 \\ -% 1.2e3 \\ -% e4 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -% The \texttt{S} column will attempt to automatically detect -% material which should be placed before or after a number, and will -% maintain the alignment of the numerical data -% (\cref{tab:S:extras}). If the material could be mistaken for -% part of a number, it should be protected by braces. The use of -% \cs{color} in a table cell will also be detected and will override any -% general colour applied by \pkg{siunitx}. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Detection of surrounding material in an \texttt{S} -% column.} -% \label{tab:S:extras} -% \centering -% \begin{tabular}{S[color=orange]} -% \toprule -% {Some Values} \\ -% \midrule -% 12.34 \\ -% \color{purple} 975,31 \\ -% 44.268 \textsuperscript{\emph{a}} \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\begin{function}{\tablenum} -% \begin{syntax} -% \cs{tablenum}\oarg{options}\marg{number} -% \end{syntax} -%\end{function} -%\changes{v2.2}{2011/03/20}{Add new \cs{tablenum} macro to allow -% complex table alignments} -%\changes{v2.2g}{2011/06/02}{Ensure \cs{tablenum} works correctly when -% \opt{parse-numbers} is set \opt{false}} -% Within more complex tables, aligned numbers may be desirable within -% the argument of \cs{multicolumn} or -% \cs{multirow}.\footnote{Provided by the \pkg{multirow} package} The -% \cs{tablenum} function is available to achieve alignment in these -% situations: this is, in effect, a macro version of the \texttt{S} macro -% (\cref{tab:tablenum}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Controlling complex alignment with the \cs{tablenum} -% macro.} -% \label{tab:tablenum} -% \centering -% \begin{tabular}{lr} -% \toprule -% Heading & Heading \\ -% \midrule -% Info & More info \\ -% Info & More info \\ -% \multicolumn{2}{c}{\tablenum[table-format = 4.4]{12,34}} \\ -% \multicolumn{2}{c}{\tablenum[table-format = 4.4]{333.5567}} \\ -% \multicolumn{2}{c}{\tablenum[table-format = 4.4]{4563.21}} \\ -% \bottomrule -% \end{tabular} -% \hfil -% \begin{tabular}{lr} -% \toprule -% Heading & Heading \\ -% \midrule -% \multirow{2}*{\tablenum{88,999}} & aaa \\ -% & bbb \\ -% \multirow{2}*{\tablenum{33,435}} & ccc \\ -% & ddd \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -% As a complement to the \texttt{S} column type, \pkg{siunitx} also provides -% a second column type, \texttt{s}. This is intended for producing -% columns of units. This allows both macro-based and explicit units to -% be printed easily (\cref{tab:s:demo}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{Units in tables.} -% \label{tab:s:demo} -% \begin{tabular}{s} -% \toprule -% \multicolumn{1}{c}{Unit} \\ -% \midrule -% \metre\squared\per\second \\ -% \pascal \\ -% m.s^{-1} \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -% As the \cs{si} macro can take literal or macro input, the \texttt{s} -% column cannot validate the input. \emph{Everything} in an \texttt{s} -% column is therefore passed to the \cs{si} macro for processing. To -% prevent this, you have to use \cs{multicolumn}, as is shown in -% \cref{tab:s:processing}. Notice that braces alone do not prevent -% processing and colouring of the cell contents. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{The \texttt{s} column processes everything.} -% \label{tab:s:processing} -% \sisetup{color = orange} -% \begin{tabular}{ss} -% \toprule -% {Unit} & \multicolumn{1}{c}{Unit}\\ -% \midrule -% {\si{m^3}} & \multicolumn{1}{c}{\si{m^3}} \\ -% \kilogram & \kilogram \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\section{Comprehensive details of package control options} -% -%\subsection{The key--value control system} -% -%\DescribeMacro{\sisetup} -% The behaviour of the \pkg{siunitx} package is controlled by a -% number of key--value options. These can be given globally using -% the \cs{sisetup} function or locally as the optional argument to the -% user macros. -% -% The package uses a range of different key types: -%\begin{description} -% \item[\texttt{Choice}] Takes a limited number of choices, which -% are described separately for each key. -% \item[\texttt{Integer}] Requires a number as the argument. -% \item[\texttt{Length}] Requires a length, either as a literal -% value such as "2.0 cm", or stored as a \LaTeX{} length, or -% \TeX{} dimension. -% \item[\texttt{Literal}] A key which uses the value(s) given directly, -% either to check input (for example the \texttt{input-digits} key) -% or in output. -% \item[\texttt{Macro}] Requires a macro, which may need a single -% argument. -% \item[\texttt{Math}] Similar to a \texttt{literal} option, but the -% input is always used in math mode, irrespective of other -% \pkg{siunitx} settings. Thus to text-mode only input must be -% placed inside the argument of a \cs{text} macro. -% \item[\texttt{Meta}] These are options which actually apply -% a number of other options. As such, they do not take any -% value at all. -% \item[\texttt{Switch}] These are on--off switches, and recognise -% \opt{true} and \opt{false}. Giving just the key name also -% turns the key on. -%\end{description} -% The tables of option names use these descriptions to indicate how the -% keys should be used. -% -%\subsection{Detecting fonts} -% -% The \pkg{siunitx} package controls the font used to print output -% independently of the surrounding material. The standard method is to -% ignore the surroundings entirely, and to use the current body fonts. -% However, the package can detect and follow surrounding bold, italic -% and font family changes. The font detection options are summarised in -% \cref{tab:opt:font:det}. -%\begin{table} -% \centering -% \caption{Font detection options.} -% \label{tab:opt:font:det} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule -% detect-all & Meta & \meta{none} \\ -% detect-display-math & Switch & false \\ -% detect-family & Switch & false \\ -% detect-inline-family & Choice & text \\ -% detect-inline-weight & Choice & text \\ -% detect-mode & Switch & false \\ -% detect-none & Meta & \meta{none} \\ -% detect-shape & Switch & false \\ -% detect-weight & Switch & false \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{detect-weight} -%\DescribeOption{detect-family} -%\DescribeOption{detect-shape} -%\DescribeOption{detect-mode} -%\changes{v2.0o}{2010/07/21}{Extend \opt{detect-italic} option -% to other shapes, renaming as \opt{detect-shape} as a result} -% The options \opt{detect-weight} and \opt{detect-shape} set detection -% of the prevailing font weight and font shape states, respectively. The -% font shape state is only checked if the surrounding material is not in -% math mode (as math text is always italic). The \opt{detect-shape} -% option is an extension of the older \opt{detect-italic} option, which -% is retained for backward compatibility. Detecting the current -% family (roman, sans serif or monospaced) is controlled by the -% \opt{detect-family} setting, while the current mode (text or math) -% is detected using the \opt{detect-mode} switch. -%\DescribeOption{detect-all} -%\DescribeOption{detect-none} -% For convenience, all of the preceding options can be turned on or -% off in one go using the \opt{detect-all} and \opt{detect-none} -% options. As the names indicate, \opt{detect-all} sets all -% of \opt{detect-weight}, \opt{detect-family}, \opt{detect-shape} -% and \opt{detect-mode} to \texttt{true}, while \opt{detect-none} -% sets all of them to \texttt{false}. -% -%\DescribeOption{detect-inline-family} -%\DescribeOption{detect-inline-weight} -%\changes{v2.1k}{2011/02/09}{Remove \opt{combined} choice for option -% \opt{detect-inline-weight}} -%\changes{v2.1k}{2011/02/09}{New option \opt{detect-inline-family}} -%\changes{v2.1l}{2011/02/10}{Error in font family detection introduced -% in v2.1k corrected} -% When \pkg{siunitx} macros are used in in-line math, the detection -% of font weight and font family can be tuned using the -% \opt{detect-inline-family} and \opt{detect-inline-weight} options. -% Both of these take the choices \opt{text} and \opt{math}. -%\begin{LaTeXdemo} -% \sisetup{ -% detect-family = true, -% detect-inline-family = math -% }% -% $\num{1234}$ \\ -% { \sffamily $\num{1234}$ } \\ -% $ \mathsf { \num{1234}} $ \\ -% \sisetup{detect-inline-family = text} -% { \sffamily $\num{1234}$ } \\ -% $ \mathsf { \num{1234} } $ \\ -% \sisetup{ -% detect-weight = true, -% detect-inline-weight = math -% }% -% $\num{5678}$ \\ -% { \boldmath $\num{5678}$ } \\ -% { \bfseries $\num{5678}$ } \\ -% \sisetup{detect-inline-weight = text} -% { \boldmath $\num{5678}$ } \\ -% { \bfseries $\num{5678}$ } -%\end{LaTeXdemo} -% -%\DescribeOption{detect-display-math} -% The font detection system can treat displayed mathematical content -% in two ways. This is controlled by the \opt{detect-display-math} -% option. When set \opt{true}, display mathematics is treated -% independently from the body of the document. Thus the local -% \emph{math} font is checked for matching. In contrast, when set -% \opt{false}, display material is treated with the current running -% text font.\footnote{Here, \enquote{display} math means either typeset -% in \TeX's display math mode or using the AMS display-like -% environments. Simply using \cs{displaystyle} will not make otherwise -% in line math be detected as display math.} -%\begin{LaTeXdemo} -% \sffamily -% Some text -% \sisetup{ -% detect-family, -% detect-display-math = true -% } -% \[ x = \SI{1.2e3}{\kilogram\kelvin\candela} \] -% More text -% \sisetup{detect-display-math = false} -% \[ y = \SI{3}{\metre\second\mole} \] -%\end{LaTeXdemo} -% -%\subsection{Font settings} -% -% The relationship between font family detected and font family used -% for output is not fixed. The font detected by the package in the -% surrounding material does not have to match that used for -% output (\cref{tab:opt:font:set}). -% -%\begin{table} -% \centering -% \caption{^^A -% Font options (also available as \opt{number-\ldots} and -% \opt{unit-\ldots} versions). -% } -% \label{tab:opt:font:set} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule -% color & Literal & \meta{none} \\ -% math-rm & Macro & \cs{mathrm} \\ -% math-sf & Macro & \cs{mathsf} \\ -% math-tt & Macro & \cs{mathtt} \\ -% mode & Choice & math \\ -% text-rm & Macro & \cs{rmfamily} \\ -% text-sf & Macro & \cs{sffamily} \\ -% text-tt & Macro & \cs{ttfamily} \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{mode} -% The \opt{mode} option determines whether \pkg{siunitx} uses -% math or text mode when printing output. The choices are \opt{math} and -% \opt{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 -% manual uses old style (lower-case) figures in text mode to highlight -% the differences. This option has no effect if the \opt{detect-mode} -% switch is \opt{true}. -% -%\DescribeOption{math-rm} -%\DescribeOption{math-sf} -%\DescribeOption{math-tt} -%\DescribeOption{text-rm} -%\DescribeOption{text-sf} -%\DescribeOption{text-tt} -% If font family detection is inactive, \pkg{siunitx} uses the font -% family stored in either \opt{math-rm} or \opt{text-rm} for -% output. The choice of \opt{math} or \opt{text} depends on the -% \opt{mode} setting. If font family detection is active, -% \pkg{siunitx} may be using a sans serif or monospaced font for -% output. In math mode, these are stored in \opt{math-sf} and -% \opt{math-tt}, and for text mode in \opt{text-sf} and \opt{text-tt}. -% Notice that the detected and output font families can differ. -%\begin{LaTeXdemo} -% \sisetup{detect-family}% -% \num{1234} \\ -% { \sffamily \num{1234} } \\ -% \SI{99}{\metre} \\ -% \sisetup{math-rm = \mathtt}% -% \SI{99}{\metre} -%\end{LaTeXdemo} -% -%\DescribeOption{color} -% The colour of printed output can be set using the \opt{color} -% option. When no colour is given, printing follows the surrounding -% text. In contrast, when a specific colour is given, it is used -% irrespective of the surroundings. As there are a number of different -% colour models available, it is left to user to load \pkg{color} or -% a more powerful colour package such as \pkg{xcolor}. -%\begin{LaTeXdemo} -% \color{red} -% Some text \\ -% \SI{4}{\metre\per\sievert} \\ -% More text \\ -% \SI[color = blue]{4}{\metre\per\sievert} \\ -% Still red here! -%\end{LaTeXdemo} -% -% Every one of the font options can be given independently for units -% and number, with the prefixes \opt{unit-} and \opt{number-}, -% respectively. This allows fine control of output. -%\begin{LaTeXdemo} -% \SI{4}{\angstrom} \\ -% \SI[number-color = green]{4}{\angstrom} \\ -% \SI[unit-color = green]{4}{\angstrom} -%\end{LaTeXdemo} -% -%\subsection{Parsing numbers} -% -% The package uses a sophisticated parsing system to understand -% numbers. This allows \pkg{siunitx} to carry out a range of -% formatting, as described later. All of the input options take lists of -% literal tokens, and are summarised in \cref{tab:opt:num:in}. -% -%\begin{table} -% \centering -% \caption{Options for number parsing.} -% \label{tab:opt:num:in} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule ^^A ( -% input-close-uncertainty & Literal & ) \\ -% input-comparators & Literal & -% <=>\cs{approx}\cs{ge}\cs{geq} \\ -% & & \cs{gg}\cs{le}\cs{leq}\cs{ll} \cs{sim} \\ -% input-complex-roots & Literal & ij \\ -% input-decimal-markers & Literal & ., \\ -% input-digits & Literal & 0123456789 \\ -% input-exponent-markers & Literal & dDeE \\ -% input-ignore & Literal & \meta{none} \\ -% input-open-uncertainty & Literal & ( \\ ^^A ) -% input-protect-tokens & Literal & -% \cs{approx}\cs{dots}\cs{ge}\cs{geq}\cs{gg}\cs{le} \\ -% & & \cs{leq}\cs{ll}\cs{mp}\cs{pi}\cs{pm}\cs{sim} \\ -% input-signs & Literal & +-\cs{pm}\cs{mp} \\ -% input-uncertainty-signs & Literal & \cs{pm} \\ -% input-symbols & Literal & \cs{pi}\cs{dots} \\ -% parse-numbers & Switch & true \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{input-digits} -%\DescribeOption{input-decimal-markers} -%\DescribeOption{input-signs} -%\DescribeOption{input-exponent-markers} -% The basic parts of a number are the digits, any sign and a separator -% between the integer and decimal parts. These are stored in the input -% options \opt{input-digits}, \opt{input-decimal-markers} and -% \opt{input-signs}, respectively. More than one input decimal marker -% can be used: it will be converted by the package to the appropriate -% output marker. Numbers which include an exponent part also require -% a marker for the exponent: this again is taken from the range of -% tokens in the \opt{input-exponent-markers} option. -% -%\DescribeOption{input-symbols} -%\DescribeOption{input-ignore} -% As well as \enquote{normal} digits, the package will interpret -% symbolic \enquote{numbers} (such as \cs{pi}) correctly if they are -% included in the \opt{input-symbols} list. Symbols are always -% printed in math mode. Tokens given in the \opt{input-ignore} list -% are totally passed over by \pkg{siunitx}: they will be removed from -% the input with no further processing. -% -%\DescribeOption{input-comparators} -%\changes{v2.1}{2010/10/26}{New \opt{input-comparators} option -% for numbers greater than, less than and so on} -% In addition to signs, \pkg{siunitx} can recognise comparators, such -% as \texttt{<}. The package will automatically carry out conversions -% for "<<", ">>", "<=" and ">=" to \cs{ll}, \cs{gg}, \cs{le} and -% \cs{ge}, respectively: -%\begin{LaTeXdemo} -% \num{< 10} \\ -% \SI{>> 5}{\metre} \\ -% \num{\le 0.12} -%\end{LaTeXdemo} -% -%\DescribeOption{input-open-uncertainty} -%\DescribeOption{input-close-uncertainty} -% In some fields, it is common to give the uncertainty in a number -% in brackets after the main part of the number, for example -% \enquote{\num{1.234(5)}}. The opening and closing symbols used for -% this type of input are set as \opt{input-open-uncertainty} and -% \opt{input-close-uncertainty}. -%\DescribeOption{input-uncertainty-signs} -%\changes{v2.2}{2011/04/03}{New \opt{input-uncertainty-signs} -% option} -% Alternatively, the uncertainty may be given as a separate part -% following a sign. Which signs are valid for this operation is -% determined by the \opt{input-uncertainty-signs} option. As with -% other signs, the combination \texttt{+-} will automatically be -% converted to \cs{pm} internally. -%\begin{LaTeXdemo} -% \num{9.99(9)} \\ -% \num{9.99 +- 0.09} \\ -% \num{9.99 \pm 0.09} \\ -% \num{123 +- 4.5} \\ -% \num{12.3 +- 6} -%\end{LaTeXdemo} -% -%\DescribeOption{input-complex-roots} -% When using complex numbers in input, the complex root -% \( ( \mathrm{i} = \sqrt{-1} \, ) \) is indicated by one of the tokens stored -% in \opt{input-complex-roots}. The parser understands complex root -% symbols given either before or after the associated number (but will -% detect any invalid arrangement): -%\begin{LaTeXdemo} -% \num{9.99 + 88.8i} \\ -% \num{9.99 + i88.8} -%\end{LaTeXdemo} -% -%\DescribeOption{input-protect-tokens} -% Some symbols can be problematic under expansion in \LaTeXe. To allow -% these to be used in input without issue, the package can protect these -% tokens while expanding input. Symbols to be protected in this way -% should be listed in \opt{input-protect-tokens}. -% -%\DescribeOption{parse-numbers} -% The \opt{parse-numbers} option turns the entire parsing system on -% and off. The option is made available for two reasons. First, if -% all of the numbers in a document are to be reproduced \enquote{as -% given}, turning off the parser will represent a significant saving in -% processing required. Second, it allows the use of arbitrary \TeX{} -% code in numbers. If the parser is turned off, the input will be -% printed in math mode (requiring \cs{text} to protect any text -% in the number). -%\begin{LaTeXdemo} -% \num[parse-numbers = false]{\sqrt{2}} \\ -% \SI[parse-numbers = false]{\sqrt{3}}{\metre} -%\end{LaTeXdemo} -% -%\subsection{Post-processing numbers} -% -% Before typesetting numbers, various post-processing steps can be -% carried out. These involve adding or removing information from the -% number in a systematic way; the options are summarised in -% \cref{tab:opt:num:post}. -% -%\begin{table} -% \centering -% \caption{Number post-processing options.} -% \label{tab:opt:num:post} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule -% add-decimal-zero & Switch & true \\ -% add-integer-zero & Switch & true \\ -% explicit-sign & Literal & \meta{none} \\ -% fixed-exponent & Integer & 0 \\ -% minimum-integer-digits & Integer & 0 \\ -% omit-uncertainty & Switch & false \\ -% retain-explicit-plus & Switch & false \\ -% retain-unity-mantissa & Switch & true \\ -% retain-zero-exponent & Switch & false \\ -% round-half & Choice & up \\ -% round-integer-to-decimal & Switch & false \\ -% round-minimum & Literal & 0 \\ -% round-mode & Choice & off \\ -% round-precision & Integer & 2 \\ -% scientific-notation & Switch & false \\ -% zero-decimal-to-integer & Switch & false \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{round-mode} -%\DescribeOption{round-precision} -%\changes{v2.1n}{2011/03/31}{Set output to 0 when \opt{round-mode} -% is \opt{figures} and \opt{round-precision} is 0} -% The \pkg{siunitx} package can round numerical input to a fixed -% number of significant figures or decimal places. This is controlled by -% the \opt{round-mode} option, which takes the choices \opt{off}, -% \opt{figures} and \opt{places}. When rounding is turned on, the -% number of digits used (either decimal places or significant figures in -% the mantissa) is set using the \opt{round-precision} option. No rounding will -% take place if the number contains an uncertainty component. -%\begin{LaTeXdemo} -% \num{1.23456} \\ -% \num{14.23} \\ -% \num{0.12345(9)} \\ -% \sisetup{ -% round-mode = places, -% round-precision = 3 -% }% -% \num{1.23456} \\ -% \num{14.23} \\ -% \num{0.12345(9)} \\ -% \sisetup{ -% round-mode = figures, -% round-precision = 3 -% }% -% \num{1.23456} \\ -% \num{14.23} \\ -% \num{0.12345(9)} -%\end{LaTeXdemo} -%\DescribeOption{round-integer-to-decimal} -%\changes{v2.1}{2010/10/25}{New \opt{zero-integer-to-decimal} option -% to convert integers to decimals on rounding} -% The standard settings for \pkg{siunitx} do not add a decimal part -% if none was given in the input. The \opt{round-integer-to-decimal} -% option can be used to allow this conversion as part of the rounding -% process. -%\begin{LaTeXdemo} -% \num[round-mode = figures]{1} \\ -% \num[round-mode = places]{1} \\ -% \sisetup{round-integer-to-decimal} -% \num[round-mode = figures]{1} \\ -% \num[round-mode = places]{1} -%\end{LaTeXdemo} -% \DescribeOption{zero-decimal-to-integer} -% It may be desirable to convert decimals to integers if the decimal part is -% zero. This is set up using the \opt{zero-decimal-to-integer} option. -%\begin{LaTeXdemo} -% \num{2.0} \\ -% \num{2.1} \\ -% \sisetup{zero-decimal-to-integer} -% \num{2.0} \\ -% \num{2.1} -%\end{LaTeXdemo} -%\DescribeOption{round-minimum} -%\changes{v2.1}{2010/10/27}{New \opt{round-minimum} option -% to set a floor for rounding numbers downward} -% There are cases in which rounding will result in the number reaching -% zero. It may be desirable to show such results as below a threshold -% value. This can be achieved by setting \opt{round-minimum} to the -% threshold value. There will be no effect when rounding to a number of -% significant figures as it is not possible to obtain the value zero in -% these cases. -%\begin{LaTeXdemo} -% \sisetup{round-mode = places}% -% \num{0.0055} \\ -% \num{0.0045} \\ -% \sisetup{round-minimum = 0.01}% -% \num{0.0055} \\ -% \num{0.0045} -%\end{LaTeXdemo} -% \DescribeOption{round-half} -% \changes{v2.4}{2011/1/04}{New \opt{round-half} option} -% In cases where the rounded part of a number is exactly half, there are -% two common methods for \enquote{breaking the tie}. The choice of method -% is determined by the option \opt{round-half}, which recognises the -% choices \opt{up} and \opt{even}. -%\begin{LaTeXdemo} -% \sisetup{round-mode = places, round-half = up}% -% \num{0.055} \\ -% \num{0.045} \\ -% \sisetup{round-half = even}% -% \num{0.055} \\ -% \num{0.045} -%\end{LaTeXdemo} -% -%\DescribeOption{add-decimal-zero} -%\DescribeOption{add-integer-zero} -% It is possible to give real (floating point) numbers as input omitting -% the decimal or the integer parts of the number (for example \num{.123} -% or \num{123.}). The options \opt{add-decimal-zero} and -% \opt{add-integer-zero} allow the package to \enquote{fill in} the -% missing zero. -%\begin{LaTeXdemo} -% \num{123.} \\ -% \num{456} \\ -% \num{.789} \\ -% \sisetup{ -% add-decimal-zero = false, -% add-integer-zero = false, -% }% -% \num{123.} \\ -% \num{456} \\ -% \num{.789} -%\end{LaTeXdemo} -%\DescribeOption{minimum-integer-digits} -%\changes{v2.2}{2011/04/04}{New \opt{minimum-integer-digits} option} -% Related is the \opt{minimum-integer-digits} option. This applies -% only to the integer part of the mantissa, and ensures that it will -% contain at least the specified number of digits. This is achieved -% by padding with zeros if needed. -%\begin{LaTeXdemo} -% \num{123} \\ -% \num[minimum-integer-digits = 1]{123} \\ -% \num[minimum-integer-digits = 2]{123} \\ -% \num[minimum-integer-digits = 3]{123} \\ -% \num[minimum-integer-digits = 4]{123} -%\end{LaTeXdemo} -% -%\DescribeOption{explicit-sign} -%\DescribeOption{retain-explicit-plus} -% The inclusion of a leading plus sign is usually unnecessary for -% positive numbers, and so the \opt{retain-explicit-plus} option is -% available to control whether these are printed. At the same time, it -% may be useful to force all numbers to have a sign. This behaviour -% is controlled by the \opt{explicit-sign} option: this is used if -% given and if no sign was present in the input. -%\begin{LaTeXdemo} -% \num{+345} \\ -% \num[retain-explicit-plus]{+345} \\ -% \num[explicit-sign = -]{345} \\ -% \num[explicit-sign = -]{+345} -%\end{LaTeXdemo} -% -%\DescribeOption{retain-unity-mantissa} -%\DescribeOption{retain-zero-exponent} -% The retention of a zero exponent is controlled by the -% \opt{retain-zero-exponent} option. The retention of a mantissa of one -% is likewise controlled by the \opt{retain-unity-mantissa} option. -%\begin{LaTeXdemo} -% \num{1e4} \\ -% \num[retain-unity-mantissa = false]{1e4} \\ -% \num{444e0} \\ -% \num[retain-zero-exponent = true]{444e0} -%\end{LaTeXdemo} -% -%\DescribeOption{scientific-notation} -%\changes{v2.1}{2010/10/13}{New \opt{scientific-notation} option -% for to use exponent form for numbers in all cases} -%\changes{v2.2}{2011/04/04}{Extend \opt{scientific-notation} option -% to include \opt{engineering} mode} -%\DescribeOption{fixed-exponent} -% Numbers can be converted to scientific notation by the package. This -% is controlled by the \opt{scientific-notation} option, which takes -% choices \opt{false}, \opt{true}, \opt{fixed} and -% \opt{engineering}. The \opt{fixed} setting will use the exponent value -% by the \opt{fixed-exponent} option. When \opt{engineering} is set, -% the exponent is always a power of three. -%\begin{LaTeXdemo} -% \num{0.001} \\ -% \num{0.0100} \\ -% \num{1200} \\ -% \sisetup{scientific-notation = true}% -% \num{0.001} \\ -% \num{0.0100} \\ -% \num{1200} \\ -% \sisetup{scientific-notation = engineering}% -% \num{0.001} \\ -% \num{0.0100} \\ -% \num{1200} \\ -% \sisetup{ -% fixed-exponent = 2, -% scientific-notation = fixed, -% }% -% \num{0.001} \\ -% \num{0.0100} \\ -% \num{1200} -%\end{LaTeXdemo} -% When used with a \opt{fixed-exponent} of zero, this may be used to remove -% scientific notation from the input -%\begin{LaTeXdemo} -% \num{1.23e4} \\ -% \num[scientific-notation = fixed, fixed-exponent = 0]{1.23e4} -%\end{LaTeXdemo} -% Note that these options apply after any removal of unit mantissa, -% zero exponent, \emph{etc.} -% -% \DescribeOption{omit-uncertainty} -% The printing of an uncertainty can be suppressed entirely using the -% \opt{omit-uncertainty} option. -%\begin{LaTeXdemo} -% \num{0.01(2)} \\ -% \num[omit-uncertainty]{0.01(2)} -%\end{LaTeXdemo} -% -%\subsection{Printing numbers} -% -% Actually printing numbers is controlled by a number of settings, -% which apply ideas such as differing decimal markers, digit -% grouping and so on. All of these options are concerned with the -% appearance of output, rather than the data it conveys. The options are -% summarised in \cref{tab:opt:num:out}. -% -%\begin{table} -% \centering -% \caption{Output options for numbers.} -% \label{tab:opt:num:out} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule -% bracket-negative-numbers & Switch & false \\ -% bracket-numbers & Switch & true \\ ^^A ( -% close-bracket & Literal & ) \\ -% complex-root-position & Choice & after-number \\ -% copy-complex-root & Choice & false \\ -% copy-decimal-marker & Choice & false \\ -% exponent-base & Literal & 10 \\ -% exponent-product & Math & \verb=\times= \\ -% group-digits & Choice & true \\ -% group-minimum-digits & integer & 5 \\ -% group-separator & Literal & \cs{,} \\ -% negative-color & Literal & \meta{none} \\ -% open-bracket & Literal & ( -% \\ ^^A ) ( -% output-close-uncertainty & Literal & ) \\ -% output-complex-root & Literal & \verb=\ensuremath{\mathrm{i}}= \\ -% output-decimal-marker & Literal & . \\ -% output-exponent-marker & Literal & \meta{none} \\ -% output-open-uncertainty & Literal & ( \\ ^^A ) -% separate-uncertainty & Switch & false \\ -% tight-spacing & Switch & false \\ -% uncertainty-separator & Literal & \meta{none} \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{group-digits} -%\changes{v2.2a}{2011/04/15}{Add missing default for \opt{group-digits} option} -% \changes{v2.3}{2011/06/06}{Extend \opt{group-digits} option, deprecating -% \opt{group-decimal-digits} and \opt{group-integer-digits}} -%\DescribeOption{group-four-digits} -%\DescribeOption{group-separator} -% Grouping digits into blocks of three is a common method to increase -% the ease of reading of numbers. The \opt{group-digits} choice controls -% whether this behaviour applies, and takes the values \opt{true}, \opt{false}, -% \opt{decimal} and \opt{integer}. Grouping can be activated separately for -% the integer and decimal parts of a number using the appropriately-named -% values. -%\begin{LaTeXdemo} -% \num{12345.67890} \\ -% \num[group-digits = false]{12345.67890} \\ -% \num[group-digits = decimal]{12345.67890} \\ -% \num[group-digits = integer]{12345.67890} -%\end{LaTeXdemo} -% The separator used between groups of digits is stored by the -% \opt{group-separator} option. This takes literal input and may be -% used in math mode: for a text-mode full space use |\text{~}|. -%\begin{LaTeXdemo} -% \num{12345} \\ -% \num[group-separator = {,}]{12345} \\ -% \num[group-separator = \text{~}]{12345} -%\end{LaTeXdemo} -% \DescribeOption{group-minimum-digits} -% \changes{v2.3}{2011/06/06}{New \opt{group-minimum-digits} option to -% replace \opt{group-four-digits}} -% Grouping is not always applied to smaller numbers, and the option -% \opt{group-minimum-digits} is available to specify how many digits must -% be present before grouping is applied. The number of digits is considered -% separately for the integer and decimal parts of the number: grouping -% does not \enquote{cross the boundary}. -%\begin{LaTeXdemo} -% \num{1234} \\ -% \num[group-minimum-digits = 4]{1234} \\ -% \num{1234.5678} \\ -% \num[group-minimum-digits = 4]{1234.5678} -%\end{LaTeXdemo} -% -%\DescribeOption{output-complex-root} -%\DescribeOption{output-decimal-marker} -%\DescribeOption{copy-complex-root} -%\changes{v2.1}{2010/10/02}{New \opt{copy-complex-root} option for -% moving input complex root to output} -%\DescribeOption{copy-decimal-marker} -% The decimal marker used in output is set using the -% \opt{output-decimal-marker} option. This can differ from the input -% marker, as can the root of $\sqrt{-1}$, which is stored in the -% \opt{output-complex-root} option. The standard setting uses \cs{mathrm} -% in math mode to give an upright -% \enquote{i}: this can easily be altered. The complex root or decimal -% marker from the input can be used in the output by setting the -% \opt{copy-complex-root} and \opt{copy-decimal-marker} options, -% respectively. -%\begin{LaTeXdemo} -% \num{1.23} \\ -% \num[output-decimal-marker = {,}]{1.23} \\ -% \num{1+2i} \\ -% \num[output-complex-root = \text{\ensuremath{i}}]{1+2i} \\ -% \num[output-complex-root = j]{1+2i} \\ -% \num[copy-complex-root]{1+2j} \\ -% \num[copy-decimal-marker]{555,555} -%\end{LaTeXdemo} -% -%\DescribeOption{complex-root-position} -% The position of the complex root can be adjusted to place it -% either before or after the associated numeral in a complex number -% using the \opt{complex-root-position} option. -%\begin{LaTeXdemo} -% \num{67-0.9i} \\ -% \num[complex-root-position = before-number]{67-0.9i} \\ -% \num[complex-root-position = after-number]{67-0.9i} -%\end{LaTeXdemo} -% -%\DescribeOption{exponent-base} -%\DescribeOption{exponent-product} -% When exponents are present in the input, the -% \opt{exponent-base} and \opt{exponent-product} options set the obvious -% parts of the output. Notice that the base is in the current mode, but -% the product sign is always in math mode. -%\begin{LaTeXdemo} -% \num[exponent-product = \times]{1e2} \\ -% \num[exponent-product = \cdot]{1e2} \\ -% \num[exponent-base = 2]{1e2} -%\end{LaTeXdemo} -%\DescribeOption{output-exponent-marker} -%\changes{v2.2}{2011/04/03}{New \opt{output-exponent-marker} option} -% Alternatively, if the \opt{output-exponent-marker} option is -% set then the value stored will be used in place of the normal -% product and base combination. This will normally be set up to -% ensure math or text mode. -%\begin{LaTeXdemo} -% \num[output-exponent-marker = \text{e}]{1e2} \\ -% \num[output-exponent-marker = \ensuremath{\mathrm{E}}]{1e2} -%\end{LaTeXdemo} -% -%\DescribeOption{separate-uncertainty} -%\DescribeOption{uncertainty-separator} -%\DescribeOption{output-open-uncertainty} -%\DescribeOption{output-close-uncertainty} -% When input is given including an uncertainty in a number, it can be -% printed either with the uncertainty in brackets or as a separate -% number. This behaviour is controlled by the -% \opt{separate-uncertainty} choice. If the uncertainty is given in -% brackets, a space may be added between the main number and the -% uncertainty: this is stored using the \opt{uncertainty-separator} -% option. The opening and closing brackets used are stored in -% \opt{output-open-uncertainty} and -% \opt{output-close-uncertainty}, respectively. -%\begin{LaTeXdemo} -% \num{1.234(5)} \\ -% \num[separate-uncertainty = true]{1.234(5)} \\ -% \sisetup{ -% output-open-uncertainty = [, -% output-close-uncertainty = ], -% uncertainty-separator = {\,} -% } -% \num{1.234(5)} -%\end{LaTeXdemo} -% Notice that \pkg{siunitx} correctly interprets uncertainties which -% cross the decimal marker position whether these are separated out -% or not. -%\begin{LaTeXdemo} -% \num{8.2(13)} \\ -% \num[separate-uncertainty]{8.2(13)} -%\end{LaTeXdemo} -% -%\DescribeOption{bracket-numbers} -%\DescribeOption{open-bracket} -%\DescribeOption{close-bracket} -% There are certain combinations of numerical input which can be -% ambiguous. This can be corrected by adding brackets in the appropriate -% place, and is controlled by the \opt{bracket-numbers} switch. The -% opening and closing brackets used are stored in \opt{open-bracket} and -% \opt{close-bracket}, respectively. Note that \opt{bracket-numbers} -% only applies to numbers without units: for numbers with units -% see the \opt{multi-part-units} option. -%\begin{LaTeXdemo} -% \num{1+2i e10} \\ -% \num[bracket-numbers = false]{1+2i e10} \\ -% \sisetup{ -% open-bracket = \{, -% close-bracket = \}, -% } -% \num{1+2i e10} -%\end{LaTeXdemo} -% -%\DescribeOption{negative-color} -% \pkg{siunitx} can detect negative mantissa values and alter print -% colour accordingly. This is disabled by setting the option to an empty -% value. -%\begin{LaTeXdemo} -% \num{-15673} \\ -% \num[negative-color = red]{-15673} -%\end{LaTeXdemo} -% -%\DescribeOption{bracket-negative-numbers} -%\changes{v2.2}{2011/04/02}{New \opt{bracket-negative-numbers} option} -% A common means to display negative numbers in financial situations -% is to place them in brackets. This can be carried out automatically -% using the \opt{bracket-negative-numbers} option. -%\begin{LaTeXdemo} -% \num{-15673} \\ -% \num[bracket-negative-numbers]{-15673} \\ -% \SI{-10}{\metre} \\ -% \SI[bracket-negative-numbers]{-10}{\metre} -%\end{LaTeXdemo} -% -%\DescribeOption{tight-spacing} -%\changes{v2.0y}{2010/10/09}{Error with \opt{tight-spacing} option -% and exponents corrected} -% Under some circumstances is may be desirable to \enquote{squeeze} -% the output spacing. This is turned on using the \opt{tight-spacing} -% switch, which compresses spacing where possible. -%\begin{LaTeXdemo} -% \num{1 \pm 2i e3} \\ -% \num[tight-spacing = true]{1 \pm 2i e3} -%\end{LaTeXdemo} -% -%\subsection{Multi-part numbers} -% -% \pkg{siunitx} recognises the idea of products and quotients in -% numbers, both with and without units. These multi-part numbers have -% a number of options affecting how they are processed. The options are -% summarised in \cref{tab:opt:num:multi}. -% -%\begin{table} -% \centering -% \caption{Multi-part number options.} -% \label{tab:opt:num:multi} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule ^^A ( -% fraction-function & Macro & \cs{frac} \\ -% input-product & Literal & x \\ -% input-quotient & Literal & / \\ -% output-product & Math & \verb=\times= \\ -% output-quotient & Literal & / \\ -% quotient-mode & Choice & symbol \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{input-product} -%\DescribeOption{input-quotient} -% The options \opt{input-product} and \opt{input-quotient} contain the -% tokens used to determine if a number contains multiple parts. -%\begin{LaTeXdemo} -% \num{1 x 2 x 3} \\ -% \num{1e4 x 2(3) x 3/4} \\ -% \num[input-product=*]{4 * 5 * 6} \\ -% \num{ 1 / 2e4 } \\ -% \num{ 1e2 / 3e4 } -%\end{LaTeXdemo} -%\DescribeOption{output-product} -%\DescribeOption{output-quotient} -% The symbols used for printing products and quotients are stored using -% the options \opt{output-product} and \opt{output-quotient}. -%\begin{LaTeXdemo} -% \num[output-product = \cdot]{4.87 x 5.321 x 6.90545} \\ -% \num[output-quotient = \text{ div }]{1 / 2} -%\end{LaTeXdemo} -% -%\DescribeOption{quotient-mode} -% For quotients, there is the possibility to print output either using -% a slash, or using the \cs{frac} macro. This is controlled by the -% \opt{quotient} choice option, which takes values \opt{symbol} and -% \opt{fraction}. -%\begin{LaTeXdemo} -% \num{1 / 2e4} \\ -% \num[quotient-mode = fraction]{1 / 2e4} -%\end{LaTeXdemo} -% -%\DescribeOption{fraction-function} -% The function used when \opt{quotient-mode = fraction} is set is -% determined by the \opt{fraction-function} option. This should -% be set to a function which takes two arguments, and presumably -% creates some type of fraction. Most alternatives to the standard -% \cs{frac} function will involve loading additional packages: the -% demonstrations here need \pkg{amsmath} and -% \pkg{xfrac}. -%\begin{LaTeXdemo} -% \sisetup{quotient-mode = fraction} -% \num{1 / 1} -% \num[fraction-function = \dfrac]{1 / 2} -% \num[fraction-function = \sfrac]{1 / 3} -% \num[fraction-function = \tfrac]{1 / 4} -%\end{LaTeXdemo} -% -%\subsection{Lists and ranges of numbers} -% -% Lists and ranges of numbers have a small number of specialised -% options, which apply to these more unusual input forms -% (\cref{tab:opt:num:list}). -% -%\begin{table} -% \centering -% \caption{Output options for lists and ranges of numbers.} -% \label{tab:opt:num:list} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule -% list-final-separator & Literal & \verb*= and = \\ -% list-pair-separator & Literal & \verb*= and = \\ -% list-separator & Literal & \verb*=, = \\ -% range-phrase & Literal & \verb*= to = \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -% \DescribeOption{list-final-separator} -% \DescribeOption{list-pair-separator} -% \changes{v2.4}{2011/11/02}{New \opt{list-pair-separator} option} -% \DescribeOption{list-separator} -% Lists of numbers are printed with a separator between each item, -% which is stored using the \opt{list-separator} option. The -% separator before the last item of a list may be different, and -% is therefore set using the \opt{list-final-separator} option. -% The separator used for exactly two items is set using the -% \opt{list-pair-separator} option. Any -% spaces needed should be included in the option settings: none are -% added within the code. These items are printed in text mode. -%\begin{LaTeXdemo} -% \numlist{0.1;0.2;0.3} \\ -% \numlist[list-separator = {; }]{0.1;0.2;0.3} \\ -% \numlist[list-final-separator = {, }]{0.1;0.2;0.3} \\ -% \numlist[ -% list-separator = { and }, -% list-final-separator = { and finally } -% ]{0.1;0.2;0.3} \\ -% \numlist{0.1;0.2} \\ -% \numlist[list-pair-separator = {, and }]{0.1;0.2} -%\end{LaTeXdemo} -% -%\DescribeOption{range-phrase} -% Ranges of numbers can be given as input. These will have an -% appropriate word or symbol inserted between the two entries: this -% is stored using the \opt{range-phrase} option. The phrase should -% include any necessary spaces: no extra space is added. -%\begin{LaTeXdemo} -% \numrange{5}{100} \\ -% \numrange[range-phrase = --]{5}{100} -%\end{LaTeXdemo} -% -% \changes{v2.4}{2011/11/04}{Automatically compress exponents for lists and -% ranges when fixed exponents are active} -% For lists and ranges when a single unit is given, \pkg{siunitx} will -% automatically \enquote{compress} exponents when a fixed exponent is in -% use. -%\begin{LaTeXdemo} -% \sisetup{ -% fixed-exponent = 3 , -% list-units = brackets , -% range-units = brackets , -% scientific-notation = fixed -% }% -% \SIrange{1e3}{7e3}{\metre} \\ -% \SIlist{1e3;2e3;3e3}{\kg} -%\end{LaTeXdemo} -% -%\subsection{Angles} -% -% Angle processing provided by the \cs{ang} function has a set of -% options which apply in addition to the general ones set up for number -% processing (\cref{tab:opt:ang}). -% -%\begin{table} -% \centering -% \caption{Angle options.} -% \label{tab:opt:ang} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule -% add-arc-degree-zero & Switch & false \\ -% add-arc-minute-zero & Switch & false \\ -% add-arc-second-zero & Switch & false \\ -% angle-symbol-over-decimal & Switch & false \\ -% arc-separator & Literal & \meta{empty} \\ -% number-angle-product & Literal & \meta{empty} \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{number-angle-product} -% The separator between the number and angle symbol (degrees, minutes -% or seconds) can be set using the \opt{number-angle-product} -% option, independent of the related \opt{number-unit-product} -% option used by the \cs{SI} function. -%\begin{LaTeXdemo} -% \ang{2.67} \\ -% \ang[number-angle-product = \,]{2.67} -%\end{LaTeXdemo} -% -%\DescribeOption{arc-separator} -% When angles are printed in arc format, the separation of the different -% parts is set up using the \opt{arc-separator} option. -%\begin{LaTeXdemo} -% \ang{6;7;6.5} \\ -% \ang[arc-separator = \,]{6;7;6.5} -%\end{LaTeXdemo} -% -%\DescribeOption{add-arc-degree-zero} -%\DescribeOption{add-arc-minute-zero} -%\DescribeOption{add-arc-second-zero} -% Zero-filling for the degree, minute or second parts of an arc is -% controlled using the \opt{add-arc-degree-zero}, -% \opt{add-arc-minute-zero} and \opt{add-arc-second-zero} options. -% All are off as standard. -%\begin{LaTeXdemo} -% \ang{-1;;} \\ -% \ang{;-2;} \\ -% \ang{;;-3} \\ -% \sisetup{add-arc-degree-zero} -% \ang{-1;;} \\ -% \ang{;-2;} \\ -% \ang{;;-3} \\ -% \sisetup{add-arc-minute-zero} -% \ang{-1;;} \\ -% \ang{;-2;} \\ -% \ang{;;-3} \\ -% \sisetup{add-arc-second-zero} -% \ang{-1;;} \\ -% \ang{;-2;} \\ -% \ang{;;-3} -%\end{LaTeXdemo} -% -%\DescribeOption{angle-symbol-over-decimal} -% In some subject areas, most notably astronomy, the angle symbols -% are given over the decimal marker, rather than at the end of the -% number. This behaviour is available using the -% \opt{angle-symbol-over-decimal} option. -%\begin{LaTeXdemo} -% \ang{45.697} \\ -% \ang{6;7;6.5} \\ -% \ang[angle-symbol-over-decimal]{45.697} \\ -% \ang[angle-symbol-over-decimal]{6;7;6.5} -%\end{LaTeXdemo} -% -%\subsection{Creating units} -%\label{sec:units:creating} -% -% The various macro units are created at the start of the document. -% \pkg{siunitx} can define these such that they are only available for -% use within the \cs{si} and \cs{SI} functions, or can make the unit -% macros available throughout the document body. There are a number of -% settings which control this creation process -% (\cref{tab:opt:units:def}). As a result, these options all apply -% in the preamble only. -% -%\begin{table} -% \centering -% \caption{Unit creation options.} -% \label{tab:opt:units:def} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule ^^A ( -% free-standing-units & Switch & false \\ -% overwrite-functions & Switch & false \\ -% space-before-unit & Switch & false \\ -% unit-optional-argument & Switch & false \\ -% use-xspace & Switch & false \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{free-standing-units} -%\changes{v2.1d}{2010/11/14}{Apply unit options when -% \opt{free-standing-units} is active} -%\changes{v2.1e}{2010/11/22}{Further corrections when applying unit -% options when \opt{free-standing-units} is active} -%\DescribeOption{overwrite-functions} -% The \opt{free-standing-units} option controls whether the unit macros -% exist outside of the \cs{si} and \cs{SI} arguments. When this option -% is \opt{true}, \pkg{siunitx} creates the macros for general use. -% The standard method to achieve this does not overwrite any existing -% macros: this behaviour can be altered using the -% \opt{overwrite-functions} switch. -% -%\DescribeOption{space-before-unit} -%\DescribeOption{unit-optional-argument} -%\changes{v2.1f}{2010/11/24}{Typo in definition for -% \opt{unit-optional-argument} implementation corrected} -%\DescribeOption{use-xspace} -% When \enquote{free standing} unit macros are created, their behaviour -% can be adjusted by a number of options. These are mainly intended for -% emulating the input syntax of older packages. The option -% \opt{unit-optional-argument} gives the same behaviour for the -% inputs -%\begin{LaTeXdemo}[code only] -% \SI{10}{\metre} -%\end{LaTeXdemo} -% and -%\begin{LaTeXdemo}[code only] -% \metre[10]. -%\end{LaTeXdemo} -% The \opt{space-before-unit} and \opt{use-xspace} options control -% the behaviour at the \enquote{ends} of the unit macros. Activating -% \opt{space-before-unit} inserts the number--unit space before the -% unit is printed. This is suitable for the input syntax -%\begin{LaTeXdemo}[code only] -% 30\metre -%\end{LaTeXdemo} -% but does mean that the unit macros are incorrectly spaced in running -% text. On the other hand, the \opt{use-xspace} option attempts to -% correctly space input such as -%\begin{LaTeXdemo}[code only] -% \metre is the symbol for metres. -%\end{LaTeXdemo} -% -%\subsection{Loading additional units} -% -% \DescribeOption{abbreviations} -% As standard, \pkg{siunitx} loads a set of abbreviated versions of the -% SI units (\cref{tab:unit:abbr}). The standard \pkg{siunitx} settings only -% create these abbreviations within the scope of the \cs{si} and \cs{SI} -% functions, meaning that no clashes should occur (for example with the -% standard \cs{pm} symbol). Loading of these abbreviations can be prevented -% by setting the option \opt{abbreviations = false} in the preamble. -% -%\begin{center} -% \changes{v2.0n}{2010/07/15}{More abbreviated units} -% \changes{v2.3b}{2011/07/27}{More abbreviated units} -% \tablecaption{Abbreviated units.} -% \label{tab:unit:abbr} -% \tablefirsthead{^^A -% \toprule -% \multicolumn{1}{l}{Unit} & -% \multicolumn{1}{l}{Abbreviation} & -% \multicolumn{1}{l}{Symbol} \\ -% \midrule -% } -% \tablehead{^^A -% \multicolumn{3}{l}{\emph{Continued from previous page}} \\ -% \toprule -% \multicolumn{1}{l}{Unit} & -% \multicolumn{1}{l}{Abbreviation} & -% \multicolumn{1}{l}{Symbol} \\ -% \midrule -% } -% \tabletail{^^A -% \bottomrule -% \multicolumn{3}{r}{\emph{Continued on next page}} \\ -% } -% \tablelasttail{\bottomrule} -% \begin{xtabular}{lcc} -% \DescribeNamedUnit{femtogram}{fg} \\ -% \DescribeNamedUnit{picogram}{pg} \\ -% \DescribeNamedUnit{nanogram}{ng} \\ -% \DescribeNamedUnit{microgram}{ug} \\ -% \DescribeNamedUnit{milligram}{mg} \\ -% \DescribeNamedUnit{gram}{g} \\ -% \DescribeNamedUnit{kilogram}{kg} \\ -% \DescribeNamedUnit{atomic mass unit}{amu} \\ -% -% \midrule -% -% \DescribeNamedUnit{picometre}{pm} \\ -% \DescribeNamedUnit{nanometre}{nm} \\ -% \DescribeNamedUnit{micrometre}{um} \\ -% \DescribeNamedUnit{millimetre}{mm} \\ -% \DescribeNamedUnit{centimetre}{cm} \\ -% \DescribeNamedUnit{decimetre}{dm} \\ -% \DescribeNamedUnit{metre}{m} \\ -% \DescribeNamedUnit{kilometre}{km} \\ -% -% \midrule -% -% \DescribeNamedUnit{attosecond}{as} \\ -% \DescribeNamedUnit{femtosecond}{fs} \\ -% \DescribeNamedUnit{picosecond}{ps} \\ -% \DescribeNamedUnit{nanosecond}{ns} \\ -% \DescribeNamedUnit{microsecond}{us} \\ -% \DescribeNamedUnit{millisecond}{ms} \\ -% \DescribeNamedUnit{second}{s} \\ -% -% \midrule -% -% \DescribeNamedUnit{femtomole}{fmol} \\ -% \DescribeNamedUnit{picomole}{pmol} \\ -% \DescribeNamedUnit{nanomole}{nmol} \\ -% \DescribeNamedUnit{micromole}{umol} \\ -% \DescribeNamedUnit{millimole}{mmol} \\ -% \DescribeNamedUnit{mole}{mol} \\ -% \DescribeNamedUnit{kilomole}{kmol} \\ -% -% \midrule -% -% \DescribeNamedUnit{picoampere}{pA} \\ -% \DescribeNamedUnit{nanoampere}{nA} \\ -% \DescribeNamedUnit{microampere}{uA} \\ -% \DescribeNamedUnit{milliampere}{mA} \\ -% \DescribeNamedUnit{ampere}{A} \\ -% \DescribeNamedUnit{kiloampere}{kA} \\ -% -% \midrule -% -% \DescribeNamedUnit{microlitre}{ul} \\ -% \DescribeNamedUnit{millilitre}{ml} \\ -% \DescribeNamedUnit{litre}{l} \\ -% \DescribeNamedUnit{hectolitre}{hl} \\ -% \DescribeNamedUnit{microliter}{uL} \\ -% \DescribeNamedUnit{milliliter}{mL} \\ -% \DescribeNamedUnit{liter}{L} \\ -% \DescribeNamedUnit{hectoliter}{hL} \\ -% -% \midrule -% -% \DescribeNamedUnit{millihertz}{mHz} \\ -% \DescribeNamedUnit{hertz}{Hz} \\ -% \DescribeNamedUnit{kilohertz}{kHz} \\ -% \DescribeNamedUnit{megahertz}{MHz} \\ -% \DescribeNamedUnit{gigahertz}{GHz} \\ -% \DescribeNamedUnit{terahertz}{THz} \\ -% -% \midrule -% -% \DescribeNamedUnit{millinewton}{mN} \\ -% \DescribeNamedUnit{newton}{N} \\ -% \DescribeNamedUnit{kilonewton}{kN} \\ -% \DescribeNamedUnit{meganewton}{MN} \\ -% -% \midrule -% -% \DescribeNamedUnit{pascal}{Pa} \\ -% \DescribeNamedUnit{kilopascal}{kPa} \\ -% \DescribeNamedUnit{megapacal}{MPa} \\ -% \DescribeNamedUnit{gigapascal}{GPa} \\ -% -% \midrule -% -% \DescribeNamedUnit{milliohm}{mohm} \\ -% \DescribeNamedUnit{kilohm}{kohm} \\ -% \DescribeNamedUnit{megohm}{Mohm} \\ -% -% \midrule -% -% \DescribeNamedUnit{picovolt}{pV} \\ -% \DescribeNamedUnit{nanovolt}{nV} \\ -% \DescribeNamedUnit{microvolt}{uV} \\ -% \DescribeNamedUnit{millivolt}{mV} \\ -% \DescribeNamedUnit{volt}{V} \\ -% \DescribeNamedUnit{kilovolt}{kV} \\ -% -% \midrule -% -% \DescribeNamedUnit{watt}{W} \\ -% \DescribeNamedUnit{microwatt}{uW} \\ -% \DescribeNamedUnit{milliwatt}{mW} \\ -% \DescribeNamedUnit{kilowatt}{kW} \\ -% \DescribeNamedUnit{megawatt}{MW} \\ -% \DescribeNamedUnit{gigawatt}{GW} \\ -% \DescribeNamedUnit{joule}{J} \\ -% \DescribeNamedUnit{microjoule}{uJ} \\ -% \DescribeNamedUnit{millijoule}{mJ} \\ -% \DescribeNamedUnit{kilojoule}{kJ} \\ -% \DescribeNamedUnit{electronvolt}{eV} \\ -% \DescribeNamedUnit{millielectronvolt}{meV} \\ -% \DescribeNamedUnit{kiloelectronvolt}{keV} \\ -% \DescribeNamedUnit{megaelectronvolt}{MeV} \\ -% \DescribeNamedUnit{gigaelectronvolt}{GeV} \\ -% \DescribeNamedUnit{teraelectronvolt}{TeV} \\ -% \DescribeNamedUnit{kilowatt hour}{kWh} \\ -% -% \midrule -% -% \DescribeNamedUnit{farad}{F} \\ -% \DescribeNamedUnit{femtofarad}{fF} \\ -% \DescribeNamedUnit{picofarad}{pF} \\ -% -% \midrule -% -% \DescribeNamedUnit{kelvin}{K} \\ -% -% \midrule -% -% \DescribeNamedUnit{decibel}{dB} \\ -% -% \end{xtabular} -%\end{center} -% -% \DescribeOption{binary-units} -% \DescribeMacro{\bit} -% \DescribeMacro{\byte} -% Binary data is expressed in units of bits and bytes. These are -% normally given prefixes which use powers of two, rather than the -% powers of ten used by the SI prefixes. As these binary prefixes are -% closely related to the SI prefixes, they are defined by \pkg{siunitx} -% but do have to be loaded using \opt{binary-units = true} (or -% simply \opt{binary-units}) -% (\cref{tab:unit:binary}). The units \cs{bit} and \cs{byte} are -% then also available. -%\begin{LaTeXdemo} -% \SI{100}{\mebi\byte} \\ -% \SI[prefixes-as-symbols=false]{30}{\kibi\bit} -%\end{LaTeXdemo} -% -%\begin{table} -% \caption{Binary prefixes.} -% \label{tab:unit:binary} -% \centering -% \begin{tabular}{llc>{$}l<{$}} -% \toprule -% Prefix & Macro & Symbol & \multicolumn{1}{l}{Power} \\ -% \midrule -% \DescribePrefix{kibi} & 10 \\ -% \DescribePrefix{mebi} & 20 \\ -% \DescribePrefix{gibi} & 30 \\ -% \DescribePrefix{tebi} & 40 \\ -% \DescribePrefix{pebi} & 50 \\ -% \DescribePrefix{exbi} & 60 \\ -% \DescribePrefix{zebi} & 70 \\ -% \DescribePrefix{yobi} & 80 \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -% \DescribeOption{version-1-compatibility} -% A configuration file is also included which will use settings -% and define macros as defined by version 1 of \pkg{siunitx}: this -% can be accessed with the option \opt{version-1-compatibility}. -% This is intended to allow easy transition to version 2: users -% should update their source to use the new interfaces and functions. -% -% Users upgrading from version 1 of \pkg{siunitx} will notice that -% the various \enquote{specialist} units available in version 1 are -% no longer provided as loadable options.\footnote{They are included -% in the loaded configuration file \opt{version-1}, but this is intended -% purely to ease transition to version 2.} These are not included in -% version 2 as the criteria for inclusion of such units are far from -% clear, and it is difficult to justify providing clearly non-SI -% units in the package. For reference, appropriate definitions for -% the units which where provided in version 1 are as follows. -%\begin{LaTeXdemo}[code only] -% % Astronomy -% \DeclareSIUnit\parsec{pc} -% \DeclareSIUnit\lightyear{ly} -% -% % Chemical engineering -% \DeclareSIUnit\gmol{g\text{-}mol} -% \DeclareSIUnit\kgmol{kg\text{-}mol} -% \DeclareSIUnit\lbmol{lb\text{-}mol} -% -% % Chemistry -% \DeclareSIUnit\molar{\mole\per\cubic\deci\metre} -% \DeclareSIUnit\Molar{\textsc{m}} -% \DeclareSIUnit\torr{torr} -% -% % Geophysics -% \DeclareSIUnit\gon{gon} -% -% % High energy physics -% \DeclareSIUnit\micron{\micro\metre} -% \DeclareSIUnit\mrad{\milli\rad} -% \DeclareSIUnit\gauss{G} -% \DeclareSIUnit\eVperc{\eV\per\clight} -% \DeclareSIUnit\nanobarn{\nano\barn} -% \DeclareSIUnit\picobarn{\pico\barn} -% \DeclareSIUnit\femtobarn{\femto\barn} -% \DeclareSIUnit\attobarn{\atto\barn} -% \DeclareSIUnit\zeptobarn{\zepto\barn} -% \DeclareSIUnit\yoctobarn{\yocto\barn} -% \DeclareSIUnit\nb{\nano\barn} -% \DeclareSIUnit\pb{\pico\barn} -% \DeclareSIUnit\fb{\femto\barn} -% \DeclareSIUnit\ab{\atto\barn} -% \DeclareSIUnit\zb{\zepto\barn} -% \DeclareSIUnit\yb{\yocto\barn} -%\end{LaTeXdemo} -% Users can use a local configuration file to make additional units -% available on a local basis, as described in \cref{sec:config:local}. -% -%\subsection{Using units} -% -% Part of the power of \pkg{siunitx} is the ability to alter the output -% format for units without changing the input. The behaviour of units -% is therefore controlled by a number of options which alter either the -% processing of units or the output directly -% (\cref{tab:opt:units:out}). -% -%\begin{table} -% \centering -% \caption{Unit output options.} -% \label{tab:opt:units:out} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule -% bracket-unit-denominator & Switch & true \\ -% forbid-literal-units & Switch & false \\ -% literal-superscript-as-power & Switch & true \\ -% inter-unit-product & Literal & \cs{,} \\ -% parse-units & Switch & true \\ -% per-mode & Choice & reciprocal \\ -% per-symbol & Literal & / \\ -% power-font & Choice & number \\ -% prefixes-as-symbols & Switch & true \\ -% qualifier-mode & Choice & subscript \\ -% sticky-per & Switch & false \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{forbid-literal-units} -% Some users may prefer to completely disable the use of literal input -% in units, for example to enforce consistency. This can be -% accomplished by setting the \opt{forbid-literal-units} switch. With -% this option enabled, only macro-based units can be used in a document. -% -%\DescribeOption{inter-unit-product} -% The separator between each unit is stored using the -% \opt{inter-unit-product} option. The standard setting is a thin -% space: another common choice is a centred dot. To get the correct -% spacing it is necessary to use |\ensuremath{{}\cdot{}}| in the latter case. -%\begin{LaTeXdemo} -% \si{\farad\squared\lumen\candela} \\ -% \si[inter-unit-product = \ensuremath{{}\cdot{}}] -% {\farad\squared\lumen\candela} -%\end{LaTeXdemo} -% -%\DescribeOption{per-mode} -%\changes{v2.1i}{2011/01/27}{Improved logic for \opt{per-mode} setting -% \opt{symbol-or-fraction}} -%\changes{v2.2}{2011/04/05}{Include leading \( 1 \) when \opt{per-mode} -% is set to \opt{symbol} and there are no numerator units in \cs{si} -% arguments} -%\DescribeOption{per-symbol} -%\DescribeOption{bracket-unit-denominator} -% The handling of \cs{per} is altered using the \opt{per-mode} choice -% option. The standard setting is \opt{reciprocal}, meaning that -% \cs{per} generates reciprocal powers for units. Setting the option -% to \opt{fraction} uses the \cs{frac} function to typeset the positive -% and negative powers of a unit separately. -%\begin{LaTeXdemo} -% \si{\joule\per\mole\per\kelvin} \\ -% \si{\metre\per\second\squared} \\ -% \si[per-mode=fraction]{\joule\per\mole\per\kelvin} \\ -% \si[per-mode=fraction]{\metre\per\second\squared} -%\end{LaTeXdemo} -% The closely-related \opt{reciprocal-positive-first} setting acts in -% the same way but places all of the positive powers before any negative -% ones. -%\begin{LaTeXdemo} -% \si{\ampere\per\mole\second} \\ -% \si[per-mode = reciprocal-positive-first] -% {\ampere\per\mole\second} -%\end{LaTeXdemo} -% It is possible to use a symbol (usually \texttt{/}) to separate the -% two parts of a unit by setting \opt{per-mode} to \opt{symbol}; the -% symbol used is stored using the setting \opt{per-symbol}. This method -% for displaying units can be ambiguous, and so brackets are added -% unless \opt{bracket-unit-denominator} is set to \opt{false}. -% Notice that \opt{bracket-unit-denominator} only applies when -% \opt{per-mode} is set to \opt{symbol} or \opt{symbol-or-fraction}. -%\begin{LaTeXdemo} -% \sisetup{per-mode = symbol}% -% \si{\joule\per\mole\per\kelvin} \\ -% \si{\metre\per\second\squared} \\ -% \si[per-symbol = \text{~div~}]{\joule\per\mole\per\kelvin} \\ -% \si[bracket-unit-denominator = false]{\joule\per\mole\per\kelvin} -%\end{LaTeXdemo} -% The often-requested (but mathematically invalid) -% \opt{repeated-symbol} option is also available to repeat the symbol -% for each \cs{per}. -%\begin{LaTeXdemo} -% \si[per-mode=repeated-symbol]{\joule\per\mole\per\kelvin} -%\end{LaTeXdemo} -% Finally, it is possible for the behaviour of the \cs{per} function -% to depend on the prevailing math style. Setting \opt{per-mode} to -% \opt{symbol-or-fraction} will use the \opt{symbol} setting for -% in line math, and the \opt{fraction} setting when used in -% \cs{displaystyle} math. -%\begin{LaTeXdemo} -% \sisetup{per-mode = symbol-or-fraction}% -% \( \si{\joule\per\mole\per\kelvin} \) -% \[ \si{\joule\per\mole\per\kelvin} \] -% \si{\joule\per\mole\per\kelvin} \\ -% \( -% \displaystyle -% \si{\joule\per\mole\per\kelvin} -% \) -% \[ -% \textstyle -% \si{\joule\per\mole\per\kelvin} -% \] -%\end{LaTeXdemo} -% -%\DescribeOption{sticky-per} -% By default, \cs{per} applies only to the next unit -% given.\footnote{This is the standard method of reading units in -% English: for example, \si{\joule\per\mole\per\kelvin} is pronounced -% \enquote{joules per mole per kelvin}.} By setting the -% \opt{sticky-per} flag, this behaviour is changed so that \cs{per} -% applies to all subsequent units. -%\begin{LaTeXdemo} -% \si{\pascal\per\gray\henry} \\ -% \si[sticky-per]{\pascal\per\gray\henry} -%\end{LaTeXdemo} -% -%\DescribeOption{power-font} -%\changes{v2.1}{2010/10/12}{New \opt{power-font} option for controlling -% whether superscript powers are treated as numbers or units} -% The font used for the powers in units can be typeset using the -% current number or unit font. This may be of use when the font used -% for numbers and units are very different, for example when the -% \pkg{euler} package is loaded. Note that this setting applies to all -% printing options for numbers, including the color used for displaying -% the number. -%\begin{LaTeXdemo} -% \si{\metre\per\second\squared} \\ -% \si[power-font = unit]{\metre\per\second\squared} -%\end{LaTeXdemo} -% \DescribeOption{literal-superscript-as-power} -% \changes{v2.3}{2011/06/08}{New \opt{literal-superscript-as-power} option for -% controlling how literal units superscripts behave} -% When printing units in \enquote{literal} mode, it is possible that simply -% printing superscripts \enquote{as is} may lead to poor appearance for the -% numbers. This is most likely if the text font of the document uses -% old style (lower case) numerals, but the math font uses lining (upper -% case) numerals. It is therefore possible to treat superscripts within -% literal units as powers, and thus for the \opt{power-font} option to -% apply within these literal units. This behaviour is controlled using the -% \opt{literal-superscript-as-power} switch. -%\begin{LaTeXdemo} -% \si{m.s^{2}} \\ -% \si[literal-superscript-as-power = false]{m.s^{2}} -%\end{LaTeXdemo} -% -%\DescribeOption{qualifier-mode} -%\changes{v2.1c}{2010/11/13}{New \opt{text} choice for -% \opt{qualifier-mode} option} -% \DescribeOption{qualifier-phrase} -% Unit qualifiers can be printed in three different formats, set by the -% \opt{qualifier-mode} option. The standard setting is \opt{subscript}, -% while the options \opt{brackets}, \opt{phrase}, \opt{space} and \opt{text} -% are also possible. With the last settings, powers can lead to ambiguity and -% are automatically detected and brackets added as appropriate. -%\begin{LaTeXdemo} -% \si{\kilogram\polymer\squared\per\mole\catalyst\per\hour} \\ -% \si[qualifier-mode = brackets] -% {\kilogram\polymer\squared\per\mole\catalyst\per\hour} \\ -% \si[qualifier-mode = subscript] -% {\kilogram\polymer\squared\per\mole\catalyst\per\hour} \\ -% \si[qualifier-mode = space] -% {\kilogram\polymer\squared\per\mole\catalyst\per\hour} \\ -% \si[qualifier-mode = text] -% {\deci\bel\isotropic} -%\end{LaTeXdemo} -% The \opt{phrase} setting for \opt{qualifier-mode} uses the text stored using -% \opt{qualifier-phrase} to separate the qualifier. -%\begin{LaTeXdemo} -% \si[qualifier-mode = phrase] -% {\kilogram\polymer\squared\per\mole\catalyst\per\hour} \\ -% \si[qualifier-mode = phrase, qualifier-phrase = { by }] -% {\kilogram\polymer\squared\per\mole\catalyst\per\hour} \\ -%\end{LaTeXdemo} -% -%\DescribeOption{prefixes-as-symbols} -% The unit prefixes (\cs{kilo}, \emph{etc}.) are normally given as -% letters. However, the package can convert these into numerical powers. -% This is controlled by the \opt{prefixes-as-symbols} switch option. -% This correctly deals with the kilogram, which is a base unit even -% though it involves a prefix. -%\begin{LaTeXdemo} -% \si{\milli\litre\per\mole\deci\ampere} \\ -% \SI{10}{\kilo\gram\squared\deci\second} \\ -% \si[prefixes-as-symbols=false]{\milli\litre\per\mole\deci\ampere}\\ -% \SI[prefixes-as-symbols=false]{10}{\kilo\gram\squared\deci\second} -%\end{LaTeXdemo} % -%\DescribeOption{parse-units} -% Normally, \pkg{siunitx} is used with the unit parse enabled, and -% only prints units directly if there is literal input. However, if -% the input is known to be essentially consistent and high performance -% is desired, then the parser can be turned off using the -% \opt{parse-units} switch. -%\begin{LaTeXdemo} -% \SI{300}{\MHz} \\ -% \SI[parse-units = false]{300}{\MHz} -%\end{LaTeXdemo} +% File: siunitx.dtx Copyright (C) 2008-2019,2021 Joseph Wright % -%\subsection{Numbers with units} +% 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 % -% Some options apply to the combination of units and numbers, rather -% than to units or numbers alone (\cref{tab:opt:units:numbers}). +% https://www.latex-project.org/lppl.txt % -%\begin{table} -% \centering -% \caption{Options for numbers with units.} -% \label{tab:opt:units:numbers} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule ^^A ( -% allow-number-unit-breaks & Switch & false \\ -% exponent-to-prefix & Switch & false \\ -% list-units & Choice & repeat \\ -% multi-part-units & Choice & brackets \\ -% number-unit-product & Literal & \cs{,} \\ -% product-units & Choice & repeat \\ -% range-units & Choice & repeat \\ -% \bottomrule -% \end{tabular} -%\end{table} +% This file is part of the "siunitx bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. % -%\DescribeOption{allow-number-unit-breaks} -% Usually, the combination of a number and unit is regarded as a single -% mathematical entity which should not be split across lines. However, -% there are cases (very long units, narrow columns, \emph{etc}.) where -% breaks may be needed. This can be turned on using the -% \opt{allow-number-unit-breaks} option. -%\begin{LaTeXdemo} -% \begin{minipage}{2.55 cm} -% % Gives an underfull hbox -% Some filler text \SI{10}{\metre} \\ -% \sisetup{allow-number-unit-breaks} -% Some filler text \SI{10}{\metre} -% \end{minipage} -%\end{LaTeXdemo} +% The released version of this bundle is available from CTAN. % -%\DescribeOption{number-unit-product} -% The product symbol between the number and unit is set using the -% \opt{number-unit-product} option. -%\begin{LaTeXdemo} -% \SI{2.67}{\farad} \\ -% \SI[number-unit-product = \ ]{2.67}{\farad} \\ -% \SI[number-unit-product = ]{2.67}{\farad} -%\end{LaTeXdemo} +% ----------------------------------------------------------------------- % -%\DescribeOption{multi-part-units} -% When a number has multiple parts (such as a separate uncertainty) then -% the unit must apply to all parts of the number. How this is shown is -% controlled using the \opt{multi-part-units} options. The standard -% setting is \opt{brackets}, which will place the entire numerical part -% in brackets and use a single unit symbol. Alternative options are -% \opt{repeat} (print the unit for each part of the number) and -% \opt{single} (print only one unit symbol: mathematically incorrect). -%\begin{LaTeXdemo} -% \sisetup{separate-uncertainty}% -% \SI{12.3(4)}{\kilo\gram} \\ -% \SI[multi-part-units = brackets]{12.3(4)}{\kilo\gram} \\ -% \SI[multi-part-units = repeat]{12.3(4)}{\kilo\gram} \\ -% \SI[multi-part-units = single]{12.3(4)}{\kilo\gram} -%\end{LaTeXdemo} -% It is important to notice that numbers with units are not affected by -% the setting of \opt{bracket-numbers}, which applies to \enquote{pure} -% numbers only. For example: -%\begin{LaTeXdemo} -% \sisetup{separate-uncertainty,bracket-numbers = false}% -% \num{1.234(5)e-4} \\ -% \SI{1.234(5)e-4}{\metre} -%\end{LaTeXdemo} -% The reason is that the requirements to bracket values with units are -% fundamentally different from those for numbers alone. Some -% combinations which are mathematically valid in the absence of a unit -% become invalid when a unit is present. +% The development version of the bundle can be found at % -%\DescribeOption{product-units} -% When a product of quantities is given, the resulting units can be -% displayed in a number of ways, set using the \opt{product-units} -% option. The standard setting is \opt{repeat}, which prints one -% unit symbol for each numbers. Alternatives are \opt{brackets}, -% \opt{brackets-power}, \opt{power}, \opt{repeat} and \opt{single}. -% This option does not affect the application of brackets for each -% number within the product list: it only sets those around the -% entire list. -%\begin{LaTeXdemo} -% \SI{2 x 3 x 4}{\metre} \\ -% \SI[product-units = brackets]{2 x 3 x 4}{\metre} \\ -% \SI[product-units = brackets-power]{2 x 3 x 4}{\metre} \\ -% \SI[product-units = power]{2 x 3 x 4}{\metre} \\ -% \SI[product-units = repeat]{2 x 3 x 4}{\metre} \\ -% \SI[product-units = single]{2 x 3 x 4}{\metre} -%\end{LaTeXdemo} +% https://github.com/josephwright/siunitx % -%\DescribeOption{list-units} -%\DescribeOption{range-units} -% The \opt{list-units} and \opt{range-units} options determine how -% the \cs{SIlist} and \cs{SIrange} functions display units, -% respectively. The standard setting for both is \opt{repeat}, where -% each number will be printed with a unit. Alternatives are -% \opt{brackets} and \opt{single}. Any brackets needed on individual -% numbers within a product are controlled by the \opt{brackets-numbers} -% option (\emph{i.e}.~they are treated as pure numbers). -% These options do not affect the application of brackets for each -% number within the list or range: they only set those around the -% entire group. -%\begin{LaTeXdemo} -% \SIlist{2;4;6;8}{\tesla} \\ -% \SIlist[list-units = brackets]{2;4;6;8}{\tesla} \\ -% \SIlist[list-units = repeat]{2;4;6;8}{\tesla} \\ -% \SIlist[list-units = single]{2;4;6;8}{\tesla} \\ -% \SIrange{2}{4}{\degreeCelsius} \\ -% \SIrange[range-units = brackets]{2}{4}{\degreeCelsius} \\ -% \SIrange[range-units = repeat]{2}{4}{\degreeCelsius} \\ -% \SIrange[range-units = single]{2}{4}{\degreeCelsius} -%\end{LaTeXdemo} +% for those people who are interested. % -% \DescribeOption{exponent-to-prefix} -% \changes{v2.4}{2011/11/06}{New \opt{exponent-to-prefix} option} -% When the \opt{exponent-to-prefix} option is set \opt{true}, the package -% will attempt to convert any exponents in quantities into unit prefixes, -% and will attach these to the first unit given. This process is only -% possible if the exponent is one for which a prefix is available, and -% retains the number of significant figures in the input. -%\begin{LaTeXdemo} -% \SI{1700}{\g} \\ -% \SI{1.7e3}{\g} \\ -% \sisetup{exponent-to-prefix}% -% \SI{1700}{\g} \\ -% \SI{1.7e3}{\g} \\ -% \sisetup{fixed-exponent = 3, scientific-notation = fixed}% -% \SI{1700}{\g} \\ -% \SI{1.7e3}{\g} -%\end{LaTeXdemo} +% ----------------------------------------------------------------------- % -%\subsection{Tabular material} -% -% Processing of material in tables obeys the same settings as described -% for the functions already described. However, there are some settings -% which apply only to the layout of tabular material -% (\cref{tab:opt:tables}). -% -%\begin{table} -% \centering -% \caption{Options for tabular material.} -% \label{tab:opt:tables} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule ^^A ( -% table-align-comparator & Switch & true \\ -% table-align-exponent & Switch & true \\ -% table-align-text-pre & Switch & true \\ -% table-align-text-post & Switch & true \\ -% table-align-uncertainty & Switch & true \\ -% table-alignment & Choice & \meta{none} \\ -% table-auto-round & Switch & false \\ -% table-column-width & Length & 0 pt \\ -% table-comparator & Switch & false \\ -% table-figures-decimal & Integer & 2 \\ -% table-figures-exponent & Integer & 0 \\ -% table-figures-integer & Integer & 3 \\ -% table-figures-uncertainty & Integer & 0 \\ -% table-format & Special & \meta{none} \\ -% table-number-alignment & Choice & -% center-decimal-marker \\ -% table-parse-only & Switch & false \\ -% table-omit-exponent & Switch & true \\ -% table-space-text-pre & Literal & \meta{empty} \\ -% table-space-text-post & Literal & \meta{empty} \\ -% table-sign-exponent & Switch & false \\ -% table-sign-mantissa & Switch & false \\ -% table-text-alignment & Choice & center \\ -% table-unit-alignment & Choice & center \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeOption{table-parse-only} -% The main use of the \texttt{S} column is to control the alignment of -% the resulting output. However, it is possible to turn off alignment -% entirely and only use the number parser of \pkg{siunitx}. This is -% achieved using the \opt{table-parse-only} switch, as illustrated -% in \cref{tab:S:parse}. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{Parsing without aligning in an \texttt{S} column.} -% \label{tab:S:parse} -% \begin{tabular} -% { -% S -% S[table-parse-only] -% } -% \toprule -% {Decimal-centred} & -% {Simple centring} \\ -% \midrule -% 12.345 & 12.345 \\ -% 6,78 & 6,78 \\ -% -88.8(9) & -88.8(9) \\ -% 4.5e3 & 4.5e3 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{table-number-alignment} -% The alignment of numbers with the boundaries of the \texttt{S} -% column is controlled using the \opt{table-number-alignment} option, -% which takes the values \opt{center-decimal-marker}, \opt{center}, -% \opt{left} and \opt{right}. The \opt{center-decimal-marker} places the -% decimal marker for the number at the centre of the column. This does -% not need any information in advance, and so is the standard setting. -% It works best for approximately symmetrical input (equal numbers of -% digits before and after the decimal). On the other hand, the -% \opt{center}, \opt{left} and \opt{right} options require space to be -% reserved for the numbers, and then use this fixed space to align with -% the edges of the column. The different alignment choices are -% illustrated in \cref{tab:S:align}, which uses somewhat -% exaggerated column headings to show the relative position of the -% cell contents. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Aligning the \texttt{S} column.} -% \label{tab:S:align} -% \centering -% \sisetup{ -% table-figures-integer = 2, -% table-figures-decimal = 4 -% } -% \begin{tabular}{ -% S -% S[table-number-alignment = center] -% S[table-number-alignment = left] -% S[table-number-alignment = right] -% } -% \toprule -% {Some Values} & {Some Values} & {Some Values} & {Some Values} \\ -% \midrule -% 2.3456 & 2.3456 & 2.3456 & 2.3456 \\ -% 34.2345 & 34.2345 & 34.2345 & 34.2345 \\ -% 56.7835 & 56.7835 & 56.7835 & 56.7835 \\ -% 90.473 & 90.473 & 90.473 & 90.473 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% Many of the other table options do not apply when -% \opt{table-number-alignment = center-decimal-marker} is set, as this -% mode always centres the marker at the expense of any other -% choices. -% -%\DescribeOption{table-figures-decimal} -%\DescribeOption{table-figures-exponent} -%\DescribeOption{table-figures-integer} -%\DescribeOption{table-figures-uncertainty} -% The space reserved by \pkg{siunitx} for a number is controlled by -% two families of options. The first family cover the number of digits -% allowed for in different parts of the number, for example -% \opt{table-figures-integer} controls the space for integer digits in -% the mantissa. If the number of figures is set to \num{0}, then no -% space is reserved and some output will either be out of position -% or not printed at all (although a warning will result). Reserving -% space for a given part of number will automatically include space -% for any associated items (for example the \enquote{\( \times \)} -% symbol for exponents). -%\DescribeOption{table-sign-exponent} -%\DescribeOption{table-sign-mantissa} -% The second family of options are switches which govern whether -% space is reserved for a sign: \opt{table-sign-exponent} and -% \opt{table-sign-mantissa}. The effect of altering some of these -% settings is shown in \cref{tab:S:space}. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Reserving space in \texttt{S} columns.} -% \label{tab:S:space} -% \sisetup{ -% table-number-alignment = center, -% table-figures-integer = 2 -% } -% \centering -% \begin{tabular}{ -% S -% S[table-number-alignment = right] -% S[table-figures-uncertainty = 1] -% S[ -% separate-uncertainty, -% table-figures-uncertainty = 1 -% ] -% S[table-sign-mantissa] -% S[table-figures-exponent = 1] -% } -% \toprule -% {Values} -% & {Values} -% & {Values} -% & {Values} -% & {Values} -% & {Values} \\ -% \midrule -% 2.3 & 2.3 & 2.3(5) & 2.3(5) & 2.3 & 2.3e8 \\ -% 34.23 & 34.23 & 34.23(4) & 34.23(4) & 34.23 & 34.23 \\ -% 56.78 & 56.78 & 56.78(3) & 56.78(3) & -56.78 & 56.78e3 \\ -% 3,76 & 3,76 & 3,76(2) & 3.76(2) & +-3.76 & e6 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -%\DescribeOption{table-comparator} -%\changes{v2.1}{2010/10/26}{New \opt{table-comparator} option -% for reserving space for comparators in tables} -% Space can also be reserved in a table for a comparator (greater than, -% less than, and so forth). This is activated using the -% \opt{table-comparator} switch (\cref{tab:S:comparators}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Reserving space for comparators in \texttt{S} columns.} -% \label{tab:S:comparators} -% \sisetup{ -% table-number-alignment = center, -% table-figures-integer = 2, -% table-figures-decimal = 2, -% table-figures-exponent = 2, -% } -% \centering -% \begin{tabular}{ -% S -% S[table-comparator = true] -% } -% \toprule -% {Values} -% & {Values} \\ -% \midrule -% 2.3 & < 2.3e8 \\ -% 34.23 & = 34.23 \\ -% 56.78 & >= 56.78e3 \\ -% 3,76 & \gg e6 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% The table-printing code will omit any part of a number which has no -% space reserved, placing a warning in the \LaTeX{} log. This means that -% uncertainties and exponents will not be printed if no space is -% reserved for them. -% -%\DescribeOption{table-format} -% As a short cut for the preceding options, \pkg{siunitx} also -% provides the \opt{table-format} option. This can be used to give the -% same information about the space to reserve for a number in a -% \enquote{compressed} manner. The input to \opt{table-format} should -% consist of a number showing how many figures to reserve in each part -% of the input. Thus -%\begin{LaTeXdemo}[code only] -% \sisetup{ -% table-format = 3.2 -% } -%\end{LaTeXdemo} -% is equivalent to -%\begin{LaTeXdemo}[code only] -% \sisetup{ -% table-figures-integer = 3, -% table-figures-decimal = 2 -% } -%\end{LaTeXdemo} -% The \opt{table-format} option will also correctly interpret the -% presence of a sign, so that -%\begin{LaTeXdemo}[code only] -% \sisetup{ -% table-format = +3.2e+4 -% } -%\end{LaTeXdemo} -% will have the same effect as -%\begin{LaTeXdemo}[code only] -% \sisetup{ -% table-figures-integer = 3, -% table-figures-decimal = 2, -% table-figures-exponent = 4, -% table-sign-mantissa, -% table-sign-exponent -% } -%\end{LaTeXdemo} -% It is important to note that any parts of a number \emph{not} -% specified in the table format argument are set to be absent (the -% number of figures is set to zero). Setting the \opt{table-format} -% option also resets \opt{table-number-alignment} to \opt{center} -% (\cref{tab:S:format}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Using the \opt{table-format} option.} -% \label{tab:S:format} -% \centering -% \begin{tabular}{ -% S -% S[table-format = 2.2] -% S[table-format = 2.2(1)] -% S[table-format = +2.2] -% S[table-format = 2.2e1] -% } -% \toprule -% {Values} -% & {Values} -% & {Values} -% & {Values} -% & {Values} \\ -% \midrule -% 2.3 & 2.3 & 2.3(5) & 2.3 & 2.3e8 \\ -% 34.23 & 34.23 & 34.23(4) & 34.23 & 34.23 \\ -% 56.78 & 56.78 & 56.78(3) & -56.78 & 56.78e3 \\ -% 3,76 & 3,76 & 3.76(2) & +-3.76 & e6 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{table-space-text-pre} -%\DescribeOption{table-space-text-post} -% Space for material before and after the \texttt{S} column can -% be reserved by giving model text for the options -% \opt{table-space-text-pre} and \opt{\ldots -post}. -% This is then used to provide the necessary gap while maintaining -% alignment (\cref{tab:S:ends}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Text before and after numbers.} -% \label{tab:S:ends} -% \centering -% \sisetup{ -% table-number-alignment = center, -% table-figures-integer = 2, -% table-figures-decimal = 4, -% table-space-text-pre = now~, -% table-space-text-post = -% \textsuperscript{\emph{a}} -% } -% \begin{tabular}{S} -% \toprule -% {Values} \\ -% \midrule -% 2.3456 \\ -% 34.2345 \textsuperscript{\emph{a}}\\ -% 56.7835 \\ -% now~ 90.473 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{table-align-comparator} -%\changes{v2.2}{2010/04/04}{New \opt{table-align-comparator} -% option for more control of table formatting} -%\DescribeOption{table-align-exponent} -%\DescribeOption{table-align-uncertainty} -%\changes{v2.1}{2010/10/12}{New \opt{table-align-exponent} and -% \opt{table-align-uncertainty} options for additional choices of -% table formatting} -% When printing exponents in tables, there is a choice of aligning -% the exponent parts or having these close up to the mantissa. This -% is controlled by the \opt{table-align-exponent} option -% (\cref{tab:align:exp}). Similarly, uncertainty parts which are printed -% separately from the mantissa can be aligned or closed up. This is -% set by the \opt{table-align-uncertainty} option -% (\cref{tab:align:uncert}). Finally, the same approach is available -% for the comparator with the \opt{table-align-comparator} option -% (\cref{tab:align:comp}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{The \opt{table-align-exponent} option} -% \label{tab:align:exp} -% \sisetup{table-format = 1.3e2, table-number-alignment = center} -% \begin{tabular}{SS[table-align-exponent = false]} -% \toprule -% {Header} & {Header} \\ -% \midrule -% 1.2e3 & 1.2e3 \\ -% 1.234e56 & 1.234e56 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{The \opt{table-align-uncertainty} option} -% \label{tab:align:uncert} -% \sisetup{ -% separate-uncertainty, -% table-format = 1.3(1), -% } -% \begin{tabular}{SS[table-align-uncertainty = false]} -% \toprule -% {Header} & {Header} \\ -% \midrule -% 1.2(1) & 1.2(3) \\ -% 1.234(5) & 1.234(5) \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{The \opt{table-align-comparator} option} -% \label{tab:align:comp} -% \sisetup{table-format = >2.2} -% \begin{tabular}{SS[table-align-comparator = false]} -% \toprule -% {Header} & {Header} \\ -% \midrule -% > 1.2 & > 1.2 \\ -% < 12.34 & < 12.34 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{table-omit-exponent} -%\changes{v2.1}{2010/10/13}{New \opt{table-omit-exponent} option -% for simplifying tables} -% In cases where data cover a range of values, printing using a fixed -% exponent in a table may make presentation clearer. In these cases, -% omitting the exponent value from the table is useful. The package -% offers the \opt{table-omit-exponent} option to do this -% (\cref{tab:exp:omit}); this automatically sets -% \opt{scientific-notation = fixed} for the table column. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{The \opt{table-omit-exponent} option} -% \label{tab:exp:omit} -% \begin{tabular}{ -% S[table-format = 1.1e1] -% S[ -% fixed-exponent = 3, -% table-format = 2.1, -% table-omit-exponent -% ] -% } -% \toprule -% {Header} & {Header / \num{e3}} \\ -% \midrule -% 1.2e3 & 1.2e3 \\ -% 3e2 & 3e2 \\ -% 1.0e4 & 1.0e4 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{table-align-text-pre} -% \changes{v2.3}{2011/06/19}{New \opt{table-align-text-pre} option} -%\DescribeOption{table-align-text-post} -% Note markers are often given in tables after the numerical content. It -% may be desirable for these to close up to the numbers. Whether this -% takes place is controlled by the \opt{table-align-text-pre} -% and \opt{\ldots-post} -% option (\cref{tab:S:notes}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Closing notes up to text.} -% \label{tab:S:notes} -% \newrobustcmd\NoteMark[1]{% -% \textsuperscript{\emph{#1}}% -% } -% \centering -% \sisetup{ -% table-number-alignment = center, -% table-figures-integer = 2, -% table-figures-decimal = 4, -% table-space-text-pre = \NoteMark{a} -% } -% \begin{tabular}{ -% S -% S[table-align-text-pre = false] -% } -% \toprule -% {Values} & {Values} \\ -% \midrule -% 2.3456 & 2.3456 \\ -% \NoteMark{a} 4.234 & \NoteMark{a} 4.234 \\ -% \NoteMark{b} .78 & \NoteMark{b} .78 \\ -% \NoteMark{d} 88 & \NoteMark{d} 88 \\ -% \bottomrule -% \end{tabular} -% \hfil -% \sisetup{table-space-text-post = \NoteMark{a}} -% \begin{tabular}{ -% S -% S[table-align-text-post = false] -% } -% \toprule -% {Values} & {Values} \\ -% \midrule -% 2.3456 & 2.3456 \\ -% 34.234 \NoteMark{a} & 34.234 \NoteMark{a} \\ -% 56.78 \NoteMark{b} & 56.78 \NoteMark{b} \\ -% 90.4 \NoteMark{c} & 90.4 \NoteMark{c} \\ -% 88 \NoteMark{d} & 88 \NoteMark{d} \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{table-auto-round} -% The contents of table cells can automatically be rounded or -% zero-filled to the number of decimal digits given for the -% \opt{table-figures-decimal} option. This mode is activated using -% the \opt{table-auto-round} switch, as illustrated in -% \cref{tab:S:auto}. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{The \opt{table-auto-round} option.} -% \label{tab:S:auto} -% \sisetup{ -% table-number-alignment = center, -% table-figures-integer = 1, -% table-figures-decimal = 3 -% } -% % Notice the overfull hbox which results with -% % the first column -% \begin{tabular}{ -% S -% S[table-auto-round] -% } -% \toprule -% {Header} & {Header} \\ -% \midrule -% 1.2 & 1.2 \\ -% 1.2345 & 1.2345 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{parse-numbers} -% When the \opt{parse-numbers} option is set to \opt{false}, then -% the alignment code for tables takes a different approach. The -% output is always set in math mode, and alignment takes place -% at the first decimal marker. This is achieved by making it -% active in math mode. When reserving space for content only -% the integer and decimal values for the mantissa are considered -% (\cref{tab:S:nonparsed}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Aligning without parsing.} -% \label{tab:S:nonparsed} -% \sisetup{ -% parse-numbers = false, -% table-figures-integer = 2, -% table-figures-decimal = 3 -% } -% \centering -% \begin{tabular}{ -% S -% S[table-number-alignment = center] -% S[table-number-alignment = right] -% S[table-number-alignment = left] -% } -% \toprule -% {Some values} -% & {Some values} -% & {Some values} -% & {Some values} \\ -% \midrule -% 2.35 & 2.35 & 2.35 & 2.35 \\ -% 34.234 & 34.234 & 34.234 & 34.234 \\ -% 56.783 & 56.783 & 56.783 & 56.783 \\ -% 3,762 & 3,762 & 3,762 & 3.762 \\ -% \sqrt{2} & \sqrt{2} & \sqrt{2} & \sqrt{2} \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{table-text-alignment} -% Cell contents which are not part of a number can be protected -% using braces, as illustrated. Cells which contain no numerical data -% at all are aligned using the setting specified by the -% \opt{table-text-alignment} option, which recognises the values -% \opt{center}, \opt{left} and \opt{right} (\cref{tab:S:text}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Aligning text in \texttt{S} columns.} -% \label{tab:S:text} -% \sisetup{ -% table-number-alignment = center, -% table-figures-integer = 4, -% table-figures-decimal = 4 -% } -% \centering -% \begin{tabular}{ -% S -% S[table-text-alignment = left] -% S[table-text-alignment = right] -% } -% \toprule -% {Values} -% & {Values} -% & {Values} \\ -% \midrule -% 992.435 & 992.435 & 992.435 \\ -% 7734.2344 & 7734.2344 & 7734.2344 \\ -% 56.7834 & 56.7834 & 56.7834 \\ -% 3,7462 & 3,7462 & 3,7462 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{table-unit-alignment} -% The contents of \texttt{s} columns can be centred or aligned to the -% left or right using the \opt{table-unit-alignment} option. As for the -% other alignment options, this recognises the choices \opt{center}, -% \opt{left} and \opt{right}. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{Alignment options in \texttt{s} columns.} -% \label{tab:s:align} -% \begin{tabular} -% { -% s[table-unit-alignment = right] -% s -% s[table-unit-alignment = left] -% } -% \toprule -% {Right-aligned} & -% {Centred text} & -% {Left-aligned} \\ -% \midrule -% \metre\per\second & \metre\per\second & \metre\per\second \\ -% \kilogram & \kilogram & \kilogram \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\DescribeOption{table-alignment} -% The three table alignment options (\opt{table-number-alignment}, -% \opt{table-text-alignment} and \opt{table-unit-alignment}) can be set -% to the same value using the \opt{table-alignment} option. This will -% set all three alignment options to the same value (one of -% \opt{center}, \opt{right} or \opt{left}). -% -%\DescribeOption{table-column-width} -%\changes{v2.2}{2011/04/02}{New \opt{table-column-width} option} -%\changes{v2.2f}{2011/05/25}{Fix setting \opt{table-column-width} to -% \opt{0 pt} to restore auto-sizing} -% Usually, the width of the \texttt{S} and \texttt{s} columns is allowed -% to vary depending on the content. However, there are cases where a -% strictly fixed width is desirable. For these cases, the -% \opt{table-column-width} option is available. The standard -% setting, "0 pt", indicates that no fixing takes place. If a value -% is set for this option then the tabular material is typeset to -% the specified width (\cref{tab:width:fixed}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{Fixed-width columns.} -% \label{tab:width:fixed} -% \begin{tabular} -% { -% s -% s[table-column-width = 2 cm] -% S -% S[table-column-width = 2 cm] -% } -% \toprule -% {Flexible} & -% {Fixed} & -% {Flexible} & -% {Fixed} \\ -% \midrule -% \metre\per\second & \metre\per\second & 1.23 & 1.23 \\ -% \kilogram\candela & \kilogram\candela & 45.6 & 45.6 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -% The \opt{table-column-width} option can also be used to achieve -% special effects. One example is centring a column of numbers under -% a wide heading, with the numbers themselves right-aligned -% (\cref{tab:width:special}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{Right-aligning under a heading.} -% \label{tab:width:special} -% \settowidth\mylength{Long header} -% \sisetup{ -% table-format = 4 , -% table-number-alignment = center , -% table-column-width = \mylength , -% input-decimal-markers = , -% input-symbols = . , -% } -% \begin{tabular}{S} -% \toprule -% {Long header} \\ -% \midrule -% 12.33 \\ -% 2 \\ -% 1234 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\subsection{Symbols} -% -% Most units use letters as the symbol for the unit, and these are all -% very easy to control. However, a small number of units use other -% symbols, and matching these to the body text requires more work. -% \pkg{siunitx} provides appropriate symbols for commonly-used units, -% but the definitions may need adjustment depending on the body font -% used in a document. -% -%\DescribeOption{redefine-symbols} -% The package provides one general option for the handling of symbols. -% If the packages \pkg{textcomp} or \pkg{upgreek} are loaded, symbols -% can be taken from these for units, rather than using the -% \pkg{siunitx} default values. The switch \opt{redefine-symbols} -% can be used to turn this behaviour on or off: the standard setting -% is \opt{true}. -% -% The individual symbols are set up independently for math and text -% output, and are summarised in \cref{tab:opt:symbols}. Many of -% the definitions are variations using \cs{text} or \cs{ensuremath} to -% produce the correct output, as the symbols available in the document -% may vary considerably. In the case of the micro symbol -% (\SIUnitSymbolMicro), \pkg{siunitx} provides a suitable low-level -% definition for the symbol. Depending on the fonts available, this -% may need to be replaced by an alternative by the user. The -% ohm symbol (\SIUnitSymbolOhm) is usually set to \cs{Omega}, but -% will check that this has not been redefined as a slanted letter. If -% \cs{Omega} has been redefined, an alternative definition is used. -% -%\begin{table} -% \centering -% \caption{Symbol options.} -% \label{tab:opt:symbols} -% \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} -% \toprule -% \multicolumn{1}{l}{Option name} & -% Type & -% \multicolumn{1}{l}{Default} \\ -% \midrule ^^A ( -% math-angstrom & Literal & \verb=\text{\AA}= \\ -% math-arcminute & Literal & \verb={}^{\prime}= \\ -% math-arcsecond & Literal & \verb={}^{\prime\prime}= \\ -% math-celsius & Literal & \meta{see text} \\ -% math-degree & Literal & \verb=\text{\textdegree}= \\ -% math-micro & Literal & \verb=\text{\textmu}= \\ -% math-ohm & Literal & \verb=\text{\ensuremath{\Omega}}= \\ -% redefine-symbols & Switch & true \\ -% text-angstrom & Literal & \cs{AA} \\ -% text-arcminute & Literal & \verb=\ensuremath{{}^{\prime}}= \\ -% text-arcsecond & Literal & -% \verb=\ensuremath{{}^{\prime\prime}}= \\ -% text-celsius & Literal & \verb=\textdegree C= \\ -% text-degree & Literal & \verb=\textdegree= \\ -% text-micro & Literal & \verb=\textmu= \\ -% text-ohm & Literal & \verb=\textohm= \\ -% \bottomrule -% \end{tabular} -%\end{table} -% -%\DescribeMacro{\SIUnitSymbolAngstrom} -%\DescribeMacro{\SIUnitSymbolArcminute} -%\DescribeMacro{\SIUnitSymbolArcsecond} -%\DescribeMacro{\SIUnitSymbolCelsius} -%\DescribeMacro{\SIUnitSymbolDegree} -%\DescribeMacro{\SIUnitSymbolMicro} -%\DescribeMacro{\SIUnitSymbolOhm} -% The math and text symbols defined above are wrapped up into mode -% independent functions with user names. These are then used in the -% definitions of the appropriate units. For example, the micro -% symbol can be accessed using the macro \cs{SIUnitSymbolMicro}. -% Notice that these names capitalise the unit name (to make reading -% the macro name easier!).\footnote{The function -% \cs{SIUnitSymbolAngstrom} uses the name without accents.} -% -%\subsection{Other options} -% -%\DescribeOption{locale} -%\changes{v2.0m}{2010/07/09}{Re-introduce \opt{locale} option} -% \pkg{siunitx} allows the user to switch between the typographic -% conventions of different (geographical) areas by using locales. -% Currently, the package is supplied with configurations for locales -% \opt{UK}, \opt{US}, \opt{DE} (Germany), \opt{FR} (French) and \opt{ZA} -% (South Africa). The \opt{locale} option is used to switch to a -% particular locale. -%\begin{LaTeXdemo} -% \SI{1.234}{\metre}\\ -% \SI[locale = DE]{6.789}{\metre} -%\end{LaTeXdemo} -% -%\DescribeOption{strict} -% Some users will want to stick closely to the official rules for -% typesetting units. This could be made complicated if the options -% for non-standards behaviour could not be turned off. The -% preamble-only option \opt{strict} resets package behaviour to -% follow the rules closely, and disables options which deviate from -% this. If the package is loaded with the \opt{strict} option, all -% output is made using the upright (serif) font. -% -%\subsection{Local configurations} -%\label{sec:config:local} -% -% The \pkg{siunitx} package will check for a local configuration file -% \file{siunitx.cfg} during package loading. This occurs before -% applying any setting given in the optional argument to -% \cs{usepackage}. A typical configuration file may include -% settings (using \cs{sisetup}) and locally-defined units, for -% example -%\begin{LaTeXdemo}[code only] -% \ProvidesFile{siunitx.cfg} -% \sisetup{ -% output-decimal-marker = {,}, -% per-mode = symbol, -% } -% \DeclareSIUnit\torr{torr} -%\end{LaTeXdemo} -% As units are always declared, overwriting any existing definition, -% units may safely be created in the configuration file even when also -% included in individual \LaTeX{} document headers. -% -% Installing a local configuration file on your system is very much like doing -% a local installation of a package. The exact method depends on the \TeX{} -% system in use. For advice on this, a good start is the -% \href{http://tex.stackexchange.com/questions/1137/} -% {TeX.SX question on local installation}. -% -%\section{Localisation} -% -% The \pkg{translator} package provides a structured framework for -% localisation of words and phrases, and is part of the larger -% \pkg{beamer} bundle. The \pkg{translator} package provides the -% \cs{translate} macro, which will provide appropriate translations -% based on the current \pkg{babel} or \pkg{polyglossia} language -% setting. -% -% If \pkg{translator} is available, \pkg{siunitx} will load it and alter -% the standard settings for the \opt{list-final-separator} and -% \opt{range-phrase} options to read: -%\begin{LaTeXdemo}[code only] -% \sisetup{ -% list-final-separator = { \translate{and} }, -% list-pair-separator = { \translate{and} }, -% range-phrase = { \translate{to (numerical range)} }, -% } -%\end{LaTeXdemo} -% If the current language is known to the \pkg{translator} package -% then the result will be localised text. The preamble for this manual -% loads English, French, German and Spanish as options, and also loads the -% \pkg{babel} package: -%\begin{LaTeXdemo} -% % In English by default -% \SIlist{1;2;3}{\metre} \\ -% \SIrange{1}{10}{\degreeCelsius} \\ -% \selectlanguage{french}% -% \SIlist{1;2;3}{\metre} \\ -% \SIrange{1}{10}{\degreeCelsius} \\ -% \selectlanguage{german}% -% \SIlist{1;2;3}{\metre} \\ -% \SIrange{1}{10}{\degreeCelsius} \\ -% \selectlanguage{spanish}% -% \SIlist{1;2;3}{\metre} \\ -% \SIrange{1}{10}{\degreeCelsius} \\ -%\end{LaTeXdemo} -% -% Note that the in order for this to work correctly, languages should -% be given as global (class) options rather than as package options -% for \pkg{babel}. -% -%\section{Hints for using \pkg{siunitx}} -% -%\subsection{Ensuring text or math output} -% -% The macros \cs{ensuremath} and \cs{text} should be used to ensure that -% a particular item is always printed in the desired mode. Some -% mathematical output does not work well in \cs{mathrm} (the standard -% font used by \pkg{siunitx} for printing). The easiest way to solve -% this is to use the construction "\text{\ensuremath{...}}", which will -% print the material in the standard mathematics font without affecting -% the rest of the output. In some cases, simply forcing \cs{mathnormal} -% will suffice, but this is less reliable with non-Latin characters. -% -%\subsection{Expanding content in tables} -%\label{sec:expanding} -% -% When processing tables, \pkg{siunitx} will expand anything stored -% inside a macro, unless it is long or protected. \LaTeXe{} robust -% commands are also detected and are not expanded -% (\cref{tab:xmpl:macro}). Values which would otherwise be expanded -% can be protected by wrapping them in a set of braces. As \TeX{} itself -% will expand the first token in a table cell before \pkg{siunitx} -% can act on it, using the \eTeX{} protected mechanism is the -% recommended course of action to prevent expansion of macros in -% table cells. (As is shown in the table, \TeX's expansion of -% \LaTeXe{} robust commands can lead to unexpected results.) -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{Values as macros in \texttt{S} columns.} -% \label{tab:xmpl:macro} -% \newcommand*\myvaluea{1234} -% \newcommand\myvalueb{1234} -% \DeclareRobustCommand*\myvaluec{1234} -% \protected\def\myvalued{1234} -% \begin{tabular}{S} -% \toprule -% {Some Values} \\ -% \midrule -% \myvaluea 8.8 \myvaluea \\ % Both expanded -% \myvalueb 8.8 \myvalueb \\ % First expanded by TeX -% % to numbers -% \myvaluec 8.8 \myvaluec \\ % First expanded by TeX -% % but not to numbers! -% \myvalued 8.8 \myvalued \\ % Neither expanded -% {\myvaluea\ 8.8 \myvaluea} \\ % Neither expanded -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -% It is possible to use calculated values in tables. For this to -% work, the calculation must take place before attempting to parse -% the number. An added complication is that \TeX{} itself will -% expand the first macro in a table cell until it finds -% something unexpandable. The \eTeX{} protected mechanism can be -% used to prevent this; using the \pkg{etoolbox} package provides -% a convenient way to apply this protection to existing functions. -% The general approach is illustrated in \cref{tab:xmpl:calc}. -% The macro \cs{DTLmul} is made robust inside the table using -% the \cs{robustify} command from \pkg{etoolbox}, before -% constructing the table using an extra column to contain the -% calculation. -%\begin{LaTeXdemo}[code and float] -% \DTLnewdb{data} -% \DTLnewrow{data}\DTLnewdbentry{data}{value}{66.7012} -% \DTLnewrow{data}\DTLnewdbentry{data}{value}{66.0212} -% \DTLnewrow{data}\DTLnewdbentry{data}{value}{64.9026} -% \begin{table} -% \caption{Calculated values.} -% \label{tab:xmpl:calc} -% \centering -% \robustify\DTLmul -% \sisetup{ -% table-number-alignment = center, -% table-figures-integer = 2, -% table-figures-decimal = 4 -% } -% \begin{tabular}{ -% S -% S[table-figures-integer = 3] -% @{}l -% } -% \toprule -% {Value} & {Doubled} & -% \DTLforeach{data}{\myvalue=value}{% -% \DTLiffirstrow {\\ \midrule}{\\}% -% \myvalue & % First column -% \DTLmul{\myvalue}{\myvalue}{2} \myvalue % second column -% & }\\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\subsection{Using \pkg{siunitx} with \pkg{datatool}} -% -% As illustrated in \cref{tab:xmpl:calc}, \pkg{siunitx} can be used -% to typeset data stored using \pkg{datatool}. For quickly displaying -% the contents of tables, \pkg{datatool} offers the \cs{DTLshowtable} -% macro. This will only work with \texttt{S} columns if number parsing -% is turned off (\cref{tab:xmpl:datatool}). -%\begin{LaTeXdemo}[code and float] -% \DTLnewdb{moredata} -% \DTLnewrow{moredata}\DTLnewdbentry{moredata}{value}{ 6.7012} -% \DTLnewrow{moredata}\DTLnewdbentry{moredata}{value}{66.0212} -% \DTLnewrow{moredata}\DTLnewdbentry{moredata}{value}{64.902 } -% \begin{table} -% \caption{Displaying a \textsf{datatool} table.} -% \label{tab:xmpl:datatool} -% \centering -% \sisetup{ -% parse-numbers = false, -% table-number-alignment = center, -% table-figures-integer = 2, -% table-figures-decimal = 4 -% } -% \renewcommand*\dtlrealalign{S} -% \DTLdisplaydb{moredata} -% \end{table} -%\end{LaTeXdemo} -% -%\subsection{Using units such as \si{\micro\metre\per\second} in -% headings} -% -% The \pkg{siunitx} code is designed to work correctly with functions -% in headings. They will print correctly in headings and in the table -% of contents. As illustrated here, the standard behaviour is to ignore -% font changes. When the \pkg{hyperref} package is loaded, the -% functions automatically \enquote{degrade gracefully} to produce -% useful information in PDF bookmarks. If you want more control over -% the bookmark text, use the \cs{texorpdfstring} function from -% \pkg{hyperref}, for example: -%\begin{LaTeXdemo}[code only] -% \section{Some text -% \texorpdfstring -% {\si{\joule\per\mole\per\kelvin}} -% {J mol-1 K-1}% -% } -%\end{LaTeXdemo} -% -% \subsection{A left-aligned column visually centred under a heading} -% -% When you have a column of non-related numbers, the usual advice is to -% make these left-aligned and then centre the resulting column under the -% heading. With the \pkg{dcolumn} package, that would be done with -% something like |D{x}{}{5.0}|. This is something of an abuse of the -% nature of a number, but can also be done using \pkg{siunitx} -% (\ref{tbl:xmpl:unrel}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Formatting unrelated numbers} -% \label{tbl:xmpl:unrel} -% \centering -% \begin{tabular} -% { -% S[ -% table-format = 5.0, -% parse-numbers = false, -% input-symbols=., -% input-decimal-markers = x -% ] -% } -% \toprule -% \multicolumn{1}{c}{Header} \\ -% \midrule -% 120 \\ -% 12.3 \\ -% 12340 \\ -% 12.02 \\ -% 123 \\ -% 1 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\subsection{Symbols and \texorpdfstring{\XeTeX}{XeTeX}} -% -% A small number of non-Latin symbols are needed by \pkg{siunitx}, -% notably \SIUnitSymbolOhm\ and \SIUnitSymbolMicro. The package picks -% glyphs for these which are correct in the sense that they are upright -% (not italic) symbols, and match the \LaTeX{} standard Computer Modern -% font. However, this does not make them the best choice if other -% fonts are in use, which is particularly common when \XeTeX{} is -% being used. -% -% \XeTeX{} users will probably need to choose appropriate symbols -% themselves. The correct choice depends on the fonts in use, but many -% system fonts include Greek letters and other symbols (which is not -% the case with most \TeX-specific fonts). An appropriate setting -% could then be to use the text \SIUnitSymbolMicro\ symbol in all -% cases: -%^^A This document cannot be UTF-8, as it has to work correctly with -%^^A pdfLaTeX. So there is a bit of work to do here to get the right -%^^A output. -%\begin{flushleft} -% \ttfamily -% \textbackslash \textcolor{blue}{sisetup}\{\\ -% \ \ math-micro = \textbackslash -% \textcolor{blue}{text}\{\SIUnitSymbolMicro\}, \\ -% \ \ text-micro \ = \SIUnitSymbolMicro \\ -% \} -%\end{flushleft} -% It may also be desirable in these cases to select a fixed font -% using the \pkg{fontspec} package, for example -%\begin{LaTeXdemo}[code only] -% \sisetup{ -% math-micro = \fontspec{Minion Pro} \textmu, -% text-micro = \fontspec{Minion Pro} \textmu -% } -%\end{LaTeXdemo} -% -%\subsection{Scaled document fonts with \texorpdfstring{\XeTeX}{XeTeX}} -% -% The \pkg{fontspec} package makes it possible to scale the document -% body font. This can lead to unexpected problems with printing -% for \pkg{siunitx}, as some symbols will not scale while numbers -% and text will. The problem is best avoided by forcing \pkg{siunitx} -% to use the default math font for all output: -%\begin{LaTeXdemo}[code only] -% \sisetup{ -% mode = math, -% math-rm = \ensuremath -% } -%\end{LaTeXdemo} -% This will cause all \pkg{siunitx} output \emph{not} to scale at all, -% consistent with other mathematical content. -% -% \subsection{Interaction with \pkg{tex4ht}} -% -% \pkg{siunitx} will detect when \pkg{tex4ht} is in use, and makes -% some changes to the way output is printed. Text mode printing is -% automatically selected, and certain items (such as spaces) are -% printed in text mode rather than as math. This is designed to -% reduce the likelihood of spurious formulae appearing in, for -% example, output converted to OpenOffice format. -% -%\subsection{Maximising performance} -% -% Both the number and unit parsers require significant effort in -% terms of \TeX{} programming. For input that does not require -% such processing, the maximum performance for \pkg{siunitx} can -% therefore be obtained by turning off both systems: -%\begin{LaTeXdemo} -% \SI{7.3}{\Hz} \\ -% \SI[parse-units = false]{7.3}{\Hz} \\ -% \SI[ -% parse-numbers = false, -% parse-units = false -% ]{7.3}{\Hz} -%\end{LaTeXdemo} -% -%\subsection{Transferring settings to \pkg{pgf}} -% -%\DescribeMacro{\SendSettingsToPgf} -%\changes{v2.0a}{2010/05/28}{Make \cs{SendSettingsToPgf} available -% in document body} -% The numerical engine in the \pkg{pgf} package has settings similar -% to those in \pkg{siunitx}. To enable working with both packages -% easily, the macro \cs{SendSettingsToPgf} is available. It will -% set some commonly-used numerical formatting options in \pkg{pgf} -% to the current values used by \pkg{siunitx} to make using the -% two packages together more convenient for end users. This -% function can be used at any point after loading both the -% \pkg{pgf} and \pkg{siunitx} packages. -%\begin{LaTeXdemo}[code only] -% \documentclass{article} -% \usepackage{pgf,siunitx} -% \sisetup{...} -% \SendSettingsToPgf -% ... -%\end{LaTeXdemo} -% -%\subsection{Using \pkg{siunitx} with the \pkg{cellspace} package} -% -% Both \pkg{siunitx} and \pkg{cellspace} use the letter \texttt{S} for a -% new column type as standard. If \pkg{cellspace} loaded and is using the -% \texttt{S} column specifier, \pkg{siunitx} will move the -% functionality of \pkg{cellspace} to the letter \texttt{C}, and \texttt{S} -% will be used by \pkg{siunitx}. This -% allows the normal use of \pkg{cellspace} with standard column types: -% it does \emph{not} work with the \pkg{siunitx} \texttt{S} or -% \texttt{s} columns. Note that \pkg{cellspace} can be loaded with a -% user-selectable identifier, for example -%\begin{LaTeXdemo}[code only] -% \usepackage[column=Q]{cellspace} -%\end{LaTeXdemo} -% -%\subsection{Special considerations for the \cs{kWh} unit} -% -% The \file{abbreviations} configuration file provides the unit -% \cs{kWh}, which is set up with no spacing between the -% \enquote{\si{\kilo\watt}} and the \enquote{\si{\hour}} unit to -% give \enquote{\si{\kWh}}. However, this only applies when the unit -% is given on its own: combinations will follow the normal rules -%\begin{LaTeXdemo} -% \si{\kWh} \\ -% \si{\kWh\per\metre} -%\end{LaTeXdemo} -% This is because the unit \cs{kWh} is defined so that it can still be -% varied by altering \cs{kilo}, \cs{watt} and \cs{hour}, and so that -% the prefix can still be turned into a number. However, some users -% may prefer to have a non-flexible macro which never adds a space. -% This can be achieved by redefining \cs{kWh} with \cs{DeclareSIUnit}, -% by added an alternative definition -%\begin{LaTeXdemo}[code only] -% \DeclareSIUnit\kWh{kWh} -% \DeclareSIUnit\KWH{kWh} -%\end{LaTeXdemo} -% or of course by using literal unit input. -%\begin{LaTeXdemo} -% \si{\KWH\per\metre}\\ -% \si{kWh.m^{-1}} -%\end{LaTeXdemo} -% -% Another point to notice is that the \cs{per} macro applies to -% the next unit, and not an entire unit combination. Thus in -%\begin{LaTeXdemo} -% \si{\candela\per\kWh} -%\end{LaTeXdemo} -% \cs{per} applies to the watts but not to the hours. In this case, -% the units need to be written out in full or the \opt{sticky-per} -% option should be used. -%\begin{LaTeXdemo} -% \si{\candela\per\kilo\watt\per\hour} \\ -% \si[sticky-per]{\candela\per\kWh} -%\end{LaTeXdemo} -% -%\subsection{Adding items after the last column of a tabular} -%\changes{v2.0d}{2010/06/10}{Document special case situations for last -% cell in table row} -% -% When using the \pkg{array} package \enquote{\texttt{<}} construct -% to insert material after an \texttt{S} or \texttt{s} column, the -% alignment of the final column may be wrong if the standard tabular row -% terminator |\\| is used. -% This is due to the way that \LaTeX{} constructs -% tables at a low level. The incorrect spacing can be avoided by using -% the \TeX{} \cs{cr} primitive to end the table rows (\cref{tab:cr}). -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Correcting spacing in last \texttt{S} column} -% \label{tab:cr} -% \hfil -% \begin{tabular}{S<{\,\si{\kg}}S<{\,\si{\kg}}} -% \toprule -% \multicolumn{1}{c}{Long header} & -% \multicolumn{1}{c}{Long header} \\ -% \midrule -% 1.23 & 1.23 \\ -% 4.56 & 4.56 \\ -% 7.8 & 7.8 \\ -% \bottomrule -% \end{tabular} -% \hfil -% \begin{tabular}{S<{\,\si{\kg}}S<{\,\si{\kg}}} -% \toprule -% \multicolumn{1}{c}{Long header} & -% \multicolumn{1}{c}{Long header} \\ -% \midrule -% 1.23 & 1.23 \cr -% 4.56 & 4.56 \cr -% 7.8 & 7.8 \cr -% \bottomrule -% \end{tabular} -% \hfil -% \end{table} -%\end{LaTeXdemo} -% -%\subsection{Creating a column with numbers and units} -% -% Usually, numbers in a table should be given with the units in the -% column heading. However, there are cases where a series of data are -% best presented in a table but have different units. There are two -% ways to do this (\cref{tab:xmpl:mixed}). The first is to place the -% units in the first column of the table, which makes sense if there -% are several related items in the table. The second method is to -% generate two columns, one for numbers and a second for units, and then -% to format these to give the visual effect of a single column. The -% later effect is most appropriate when only one set of numbers are -% presented in a table. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Tables where numbers have different units} -% \label{tab:xmpl:mixed} -% \hfil -% \begin{tabular} -% { -% >{$}l<{$} -% S[table-format = 2.3(1)] -% S[table-format = 3.3(1)] -% } -% \toprule -% & {One} & {Two} \\ -% \midrule -% a / \si{\angstrom} & 1.234(2) & 5.678(4) \\ -% \beta / \si{\degree} & 90.34(4) & 104.45(5) \\ -% \mu / \si{\per\mm} & 0.532 & 0.894 \\ -% \bottomrule -% \end{tabular} -% \hfil -% \begin{tabular} -% {S[table-format=1.3]@{\,}s[table-unit-alignment = left]} -% \toprule -% \multicolumn{2}{c}{Heading} \\ -% \midrule -% 1.234 & \metre \\ -% 0.835 & \candela \\ -% 4.23 & \joule\per\mole \\ -% \bottomrule -% \end{tabular} -% \hfil -% \end{table} -%\end{LaTeXdemo} -% -%\subsection{Tables with heading rows} -%\changes{v2.0s}{2010/08/12}{Document how to do mixed bold and normal -% numbers in tables} -% -% A common format for tables is to make the heading row visually -% distinct using a background colour and bold text. If numbers appear -% in such a heading row within an \texttt{S} column then getting the -% appearance right can be challenging. The best approach is to -% make the \cs{bfseries} macro \enquote{robust} (as demonstrated in -% \cref{sec:expanding}), then to use this macro to make the heading -% cells bold. This approach is illustrated in \cref{tab:xmpl:headers}, -% along with the use of \cs{rowcolor} to provide a background colour. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \caption{Header row in a table} -% \label{tab:xmpl:headers} -% \robustify\bfseries -% \centering -% \begin{tabular} -% {S[detect-weight,table-format = 3.3]} -% \rowcolor[gray]{0.9} -% \bfseries 123.456 \\ -% 23.45 \\ -% 123.4 \\ -% 3.456 \\ -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\subsection{Associating a locale with a \pkg{babel} language} -% -% It is possible to instruct the \pkg{babel} package to switch -% to a particular \pkg{siunitx} locale when changing language. This -% can be done using the \pkg{babel} \cs{extras\meta{language}} -% system. For example, to associate the \texttt{DE} locale with -% the \texttt{german} \pkg{babel} language, the appropriate -% code would be -%\begin{LaTeXdemo}[code only] -% \addto\extrasgerman{\sisetup{locale = DE}} -%\end{LaTeXdemo} -% -%\section{Information for those upgrading} -% -%\subsection{Upgrading from version 1} -%\changes{v2.0a}{2010/05/28}{Fix various errors in \file{version-1} -% configuration file} -%\changes{v2.0a}{2010/05/28}{Detect use of version 1 options and -% automatically load appropriate configuration file} -%\changes{v2.0a}{2010/05/28}{Include high energy physics units in -% discussion of old configurations and in \file{version-1} -% configuration file} -%\changes{v2.0b}{2010/06/01}{Further improvements to \file{version-1} -% configuration file} -%\changes{v2.0r}{2010/08/02}{Error in definition for old -% \opt{decimalsymbol} option corrected} -%\changes{v2.1d}{2010/11/14}{Error with definition of version 1 option -% \opt{xspace} corrected} -% -% The key--value control system of \pkg{siunitx} has been completely -% rewritten for version 2, and at the same time some of the macros -% provided by the package have been renamed and reworked. The package -% can be loaded with a configuration file to provide most of the -% same options and defaults as in version 1: -%\begin{LaTeXdemo}[code only] -% \usepackage[version-1-compatibility]{siunitx} -%\end{LaTeXdemo} -% Many of the options from version 1 map to similar ones in version 2 -% (\cref{tab:opt:map}). The correspondence often includes a syntax -% change: consult details of the new options for the correct syntax for -% the new options. In some cases, the new approach is different to the -% older one, and in these cases the most appropriate option new has been -% listed in the table. -%\begin{center} -% \tablecaption{Mapping of version 1 options to version 2.} -% \label{tab:opt:map} -% \tablefirsthead{^^A -% \toprule -% \multicolumn{1}{l}{Version 1} & -% \multicolumn{1}{l}{See in version 2} \\ -% \midrule -% } -% \tablehead{^^A -% \multicolumn{2}{l}{\emph{Continued from previous page}} \\ -% \toprule -% \multicolumn{1}{l}{Version 1} & -% \multicolumn{1}{l}{See in version 2} \\ -% \midrule -% } -% \tabletail{^^A -% \bottomrule -% \multicolumn{2}{r}{\emph{Continued on next page}} \\ -% } -% \tablelasttail{\bottomrule} -% -% \begin{xtabular}{>{\ttfamily}l>{\ttfamily}l} -% addsign & explicit-sign \\ -% allowlitunits & free-standing-units \\ -% allowoptarg & unit-optional-argument \\ -% allowzeroexp & retain-zero-exponent \\ -% anglesep & arc-separator \\ -% astroang & angle-symbol-over-decimal \\ -% closeerr & close-bracket \\ -% closefrac & close-bracket \\ -% closerange & close-bracket \\ -% colour & color \\ -% colorall & color \\ -% colourall & color \\ -% colorunits & unit-color \\ -% colorneg & negative-color \\ -% colourneg & negative-color \\ -% colourunits & unit-color \\ -% colorvalues & number-color \\ -% colourvalues & number-color \\ -% decimalsymbol & output-decimal-marker \\ -% detectdisplay & detect-display-math \\ -% digitsep & group-separator \\ -% dp & round-mode \\ -% & round-precision \\ -% errspace & uncertainty-separator \\ -% expbase & exponent-base \\ -% expproduct & exponent-product \\ -% fixdp & round-mode \\ -% fixsf & round-mode \\ -% fraction & fraction-function \\ -% inlinebold & detect-inline-weight \\ -% locale & locale \\ -% mathOmega & math-ohm \\ -% mathcelsius & math-celsius \\ -% mathdegree & math-degree \\ -% mathminute & math-arcminute \\ -% mathmu & math-micro \\ -% mathringA & math-angstrom \\ -% mathrm & math-rm \\ -% mathsOmega & math-ohm \\ -% mathscelsius & math-celsius \\ -% mathsdegree & math-degree \\ -% mathsecond & math-arcsecond \\ -% mathsf & math-sf \\ -% mathsminute & math-arcminute \\ -% mathsmu & math-micro \\ -% mathsringA & math-angstrom \\ -% mathsrm & math-rm \\ -% mathssecond & math-arcsecond \\ -% mathssf & math-sf \\ -% mathstt & math-tt \\ -% mathtt & math-tt \\ -% mode & mode \\ -% negcolor & negative-color \\ -% negcolour & negative-color \\ -% numaddn & input-symbols \\ -% numcloseerr & input-close-uncertainty \\ -% numdecimal & input-decimal-markers \\ -% numdigits & input-digits \\ -% numdiv & input-quotient \\ -% numexp & input-exponent-markers \\ -% numgobble & input-ignore \\ -% numopenerr & input-open-uncertainty \\ -% numprod & input-product \\ -% numsign & input-signs \\ -% obeyall & detect-all \\ -% obeybold & detect-weight \\ -% obeyfamily & detect-family \\ -% obeyitalic & detect-shape \\ -% obeymode & detect-mode \\ -% openerr & open-bracket \\ -% openfrac & open-bracket \\ -% openrange & open-bracket \\ -% padangle & add-arc-degree-zero \\ -% & add-arc-minute-zero \\ -% & add-arc-second-zero \\ -% padnumber & add-decimal-zero \\ -% & add-integer-zero \\ -% per & per-mode \\ -% prefixsymbolic & prefixes-as-symbols \\ -% prespace & space-before-unit \\ -% redefsymbols & redefine-symbols \\ -% repeatunits & multi-part-units \\ -% & product-units \\ -% & range-units \\ -% retainplus & retain-explicit-plus \\ -% seperr & separate-uncertainty \\ -% sepfour & group-four-digits \\ -% sf & round-mode \\ -% & round-precision \\ -% sign & explicit-sign \\ -% slash & per-symbol \\ -% stickyper & sticky-per \\ -% strict & strict \\ -% tabalign & table-alignment \\ -% tabalignexp & table-align-exponent \\ -% tabautofit & table-auto-round \\ -% tabformat & table-format \\ -% tabnumalign & table-number-alignment \\ -% tabparseonly & table-parse-only \\ -% tabexpalign & table-align-exponent \\ -% tabtextalign & table-text-alignment \\ -% tabunitalign & table-unit-alignment \\ -% textcelsius & text-celsius \\ -% textdegree & text-degree \\ -% textminute & text-arcminute \\ -% textmode & mode \\ -% textmu & text-micro \\ -% textOmega & text-ohm \\ -% textringA & text-angstrom \\ -% textrm & text-rm \\ -% textsecond & text-arcsecond \\ -% textsf & text-sf \\ -% texttt & text-tt \\ -% tightpm & tight-spacing \\ -% tophrase & range-phrase \\ -% trapambigerr & multi-part-units \\ -% trapambigfrac & bracket-numbers \\ -% trapambigrange & range-units \\ -% unitcolor & unit-color \\ -% unitcolour & unit-color \\ -% unitmathrm & unit-math-rm \\ -% unitmathsf & unit-math-sf \\ -% unitmathsrm & unit-math-rm \\ -% unitmathssf & unit-math-sf \\ -% unitmathstt & unit-math-tt \\ -% unitmathtt & unit-math-tt \\ -% unitmode & unit-mode \\ -% unitsep & inter-unit-product \\ -% unitspace & inter-unit-product \\ -% valuecolor & number-color \\ -% valuecolour & number-color \\ -% valuemathrm & number-math-rm \\ -% valuemathsf & number-math-sf \\ -% valuemathsrm & number-math-rm \\ -% valuemathssf & number-math-sf \\ -% valuemathstt & number-math-tt \\ -% valuemathtt & number-math-tt \\ -% valuemode & value-mode \\ -% valuesep & number-unit-product \\ -% xspace & use-xspace \\ -% \end{xtabular} -%\end{center} -% A small number of the options from version 1 are used unchanged in -% version 2, for example the \opt{mode} setting. These are listed above -% but require no action on the part of the user. There are also a -% few options which are no longer used at all, and are therefore ignored -% by the current code. -% -% Loading configuration files has been completely changed, and this -% means that the options \opt{alsoload}, \opt{load} and \opt{noload} are -% ignored by version 2. In the same way the options \opt{debug} and -% \opt{log} are not used by the current release of \pkg{siunitx}, as -% this information is usually only needed by the package author. -% Emulation of older packages is no longer offered (it was intended -% to help with the transition form earlier packages), and so the -% \opt{emulate} option no longer applies. -% -%\subsection{Upgrading from version 2.0 or 2.1} -% -% User feedback on \pkg{siunitx} means that over time some renaming -% takes place. The following functions and options have been deprecated -% in version 2.2. They are therefore available in version 2.2, but -% should be replaced in new or updated documents with the successor -% names. -% -%\DescribeOption{angle-unit-separator} -%\DescribeOption{inter-unit-separator} -%\DescribeOption{number-unit-separator} -%\changes{v2.2}{2011/03/20}{Renamed \opt{angle-unit-separator} option -% to \opt{angle-unit-product}} -%\changes{v2.2}{2011/03/20}{Renamed \opt{inter-unit-separator} option -% to \opt{inter-unit-product}} -%\changes{v2.2}{2011/03/20}{Renamed \opt{number-unit-separator} option -% to \opt{number-unit-product}} -% These options have been replaced by the options -%\begin{itemize} -% \item \opt{angle-unit-product} -% \item \opt{inter-unit-product} -% \item \opt{number-unit-product} -%\end{itemize} -% as these items are formally products, and the new option names -% emphasise this. -% -%\DescribeMacro{\DeclareSIUnitWithOptions} -%\changes{v2.2}{2011/04/01}{Depreciate \cs{DeclareSIUnitWithOptions}} -% The \cs{DeclareSIUnit} function has been extended to take a -% first optional argument, which removes the need for -% \cs{DeclareSIUnitWithOptions}. This function is therefore depreciated -% but retained for compatibility. -% -% \subsection{Upgrading from version 2.2} -% -% \DescribeOption{load-configurations} -% \changes{v2.3}{2011/03/20}{Load abbreviations as standard} -% \changes{v2.3}{2011/03/20}{Replace \opt{load-configurations} option -% with separate \opt{abbreviations}, \opt{binary-units} and -% \opt{version-1-compatibility} options} -% The option \opt{load-configurations} has been deprecated in favour of the -% three options \opt{abbreviations}, \opt{binary-units} and -% \opt{version-1-compatibility}. At the same time, loading of the abbreviations -% is now the standard behaviour, and so in most cases no -% explicit configuration file loading will be needed. -% -% \DescribeOption{group-decimal-digits} -% \DescribeOption{group-integer-digits} -% The digit grouping options have been revised, and the options -% \opt{group-decimal-digits} and \opt{group-integer-digits} are now -% integrated into \opt{group-digits}. -% \DescribeOption{group-four-digits} -% At the same time, the \opt{group-four-digits} option has been extended -% to the new option \opt{group-minimum-digits}. -% -% \DescribeOption{literal-superscript-as-power} -% The new {literal-superscript-as-power} option means that the standard -% behaviour now uses the current math font for superscripts, even when -% units are printed literally. This will only be obvious in documents such -% as this manual, where the text and math mode numerals are (deliberately) -% different. To restore the previous behaviour, set -% \opt{literal-superscript-as-power = false}. -% -% \subsection{Upgrading from version 2.3} -% -% The number of options which assume that the input is given in math mode -% has been significantly reduced. As most material can be typeset in either -% math or text mode, the \enquote{intrinsic} math mode options could lead to -% inconsistent output. The only options which now force math mode are those -% for products, which will almost always require the use of math mode. -% -% \subsection{Upgrading from version 2.4} -% -% The process of removing options which assume math mode, begun with -% version~2.4, has been taken further, and only \opt{output-product} -% and \opt{exponent-product} now do not require \cs{ensuremath} for material -% which must be in math mode. The standard settings have been altered to take -% account of this, but user-set options for products may need to be updated -% accordingly. -% -% \subsection{Upgrading from version 2.5} -% -% All printing now takes place in math mode (\emph{i.e.}~\opt{mode = math} -% is set). This may alter the appearance of some units, and users may want -% to verify the output is correct. -% -%\section{Correct application of (SI) units} -% -% Consistent and logical units are a necessity for scientific work, -% and have applicability everywhere. Historically, a number of -% systems have been used for physical units. SI units were -% introduced by the \emph{Conf{\'e}rence G{\'e}n{\'e}rale des Poids et -% Mesures} (CGPM) in 1960. SI units are a coherent system based on -% seven base units, from which all other units may be derived. -% -% At the same time, physical quantities with units are mathematical -% entities, and as such way that they are typeset is important. In -% mathematics, changes of type (such as using bold, italic, sans -% serif typeface and so on) convey information. This means that -% rules exist not only for the type of units to be used under the SI -% system, but also the way they should appear in print. Advice on -% best practice has been made available by the \emph{National -% Institute of Standards and Technology} (NIST) \cite{NIST}. -% -% As befits an agreed international standard, the full rules are -% detailed. It is not appropriate to reproduce these in totality -% here; instead, a useful summary of the key points is provided. The -% full details are available from the \emph{Bureau International des -% Poids et Mesures} \cite{BIPM}. -% -% \pkg{siunitx} takes account of the information given here, so far as -% is possible. Thus the package defaults follow the recommendations -% made for typesetting numbers and units. Spacing and so forth is -% handled in such a way as to make implementing the rules -% (relatively) easy. -% -%\subsection{Units} -% -% There are seven base SI units, listed in \cref{tab:unit:base}. -% Apart from the kilogram, these are defined in terms of a measurable -% physical quantity needing the definition alone.\footnote{Some base -% units need others defined first; there is therefore a required -% order of definition.} The base units have been chosen such that -% all physical quantities can be expressed using an appropriative -% combination of these units, needing no others and with no -% redundancy. The kilogram is slightly different from the other base -% units as it is still defined in terms of a \enquote{prototype} held in -% Paris. -% -% All other units within the SI system are regarded as \enquote{derived} -% from the seven base units. At the most basic, all other SI units -% can be expressed as combinations of the base units. However, many -% units (listed in \cref{tab:unit:derived,tab:unit:accepted}) have a -% special name and symbol. Most of these units are simple combinations -% of one or more base units (raised to powers as appropriate). A small -% number of units derived from experimental data are allowed as SI -% units (\cref{tab:unit:physical}). -% -% A series of SI prefixes for decimal multiples and sub-multiples are -% provided, and can be used as modifiers for any SI unit (either base -% or derived units) with the exception of the kilogram. The prefixes -% are listed in \cref{tab:unit:prefix}. No space should be used -% between a prefix and the unit, and only a single prefix should be -% used. Even the degree Celsius can be given a prefix, for example -% \SI{1}{\milli\degreeCelsius}. -% -% It is important to note that the kilogram is the only SI unit with -% a prefix as part of its name and symbol. Only single prefix may -% be used, and so in the case of the kilogram prefix names are used -% with the unit name \enquote{gram} and the prefix symbols are used with -% the unit symbol \si{\gram}. For example -% \( \SI[prefixes-as-symbols = false]{1}{\milli\gram} = -% \SI{1}{\milli\gram} \). -% -% The application of SI units is meant to provide a single set of -% units which ensure consistency and clarity across all areas. -% However, other units are common is many areas, and are not without -% merit. The units provided by \pkg{siunitx} by default do not include -% any of these; only units which are part of the SI set or are -% accepted for use with SI units are defined. However, several other -% sets of units can be loaded as optional modules. The binary -% prefixes and units (\cref{tab:unit:binary}) are the most obvious -% example. These are \emph{not} part of the SI specifications, but the -% prefix names are derived from those in \cref{tab:unit:prefix}. -% -% Other units are normally to be avoided where possible. SI units -% should, in the main, be preferred due to the advantages of clear -% definition and self-consistency this brings. However, there will -% probably always be a place for specialist or non-standard units. -% This is particularly true of units derived from basic physical -% constants. -% -% There are also many areas where non-standard units are used so -% commonly that to do otherwise is difficult or impossible. For -% example, most synthetic chemists measure the pressure inside vacuum -% apparatus in \si{\mmHg}, partly because the most common gauge for -% the task still uses a column of mercury metal. For these reasons, -% \pkg{siunitx} does define non-SI units. -% -%\subsection{Mathematical meaning} -% -% As explained earlier, a number--unit combination is a single -% mathematical entity. This has implications for how both the number -% and the unit should be printed. Firstly, the two parts should not -% be separated: a quantity is a product of the number and the unit. -% With the exception of the symbols for plane angles (\si{\degree}, -% \si{\arcminute} and \si{\arcsecond}), the \textsc{bipm} -% specifies either a space or half-height (centred) dot should be -% used \cite{BIPM}. -%\begin{LaTeXdemo} -% A space for \SI{10}{\percent}\\ -% and also for \SI{100}{\degreeCelsius}\\ -% but not for \ang{1.23}. -%\end{LaTeXdemo} -% -% The mathematical meaning of units also means that the shape, weight -% and family are important. Units are supposed to be typeset in an -% upright, medium weight font. Italic, bold and sans serif are -% all used mathematically to convey other meanings. (In an all -% sans serif document, using sans serif for units is reasonable.) -% The \pkg{siunitx} -% package defaults again follow this convention: any local settings are -% ignored, and uses the current upright math font. However, -% there are occasions where this may not be the most desirable -% behaviour. A classic example would be in an all-bold section -% heading. As the surrounding text is bold, some people feel that -% any units should follow this. -%\begin{LaTeXdemo} -% Units should \textbf{not be bold: \SI{54}{\farad}}\\ -% \textbf{But perhaps in a running block,\\ -% it might look better: \SI[detect-weight]{54}{\farad}} -%\end{LaTeXdemo} -% -% Symbols for units formed from other units by multiplication are -% indicated by means of either a half-height (that is, centred) dot -% or a (thin) space. -%\begin{LaTeXdemo} -% \( \si{\metre\second} = \text{metre second} \) \\ -% \( \si{\milli\second} = \text{millisecond} \) \\ -% \sisetup{inter-unit-product = \ensuremath { { } \cdot { } } } -% \( \si{\metre\second} = \text{metre second} \) \\ -% \( \si{\milli\second} = \text{millisecond} \) -%\end{LaTeXdemo} -% There are some circumstances under which it is common practice to omit -% any spaces. The classic example is \si{\kWh}, where -% \enquote{\si[inter-unit-product = \,]{\kWh}} does not add any -% useful information. If using such a unit repeatedly, users of -% \pkg{siunitx} are advised to create a custom unit to ensure -% consistency. It is important to note that while this is common -% practice, it is \emph{not} allowed by the \textsc{bipm} -% \cite{BIPM}. -% -% Symbols for units formed from other units by division are indicated -% by means of a virgule (oblique stroke, slash, "/"), a horizontal -% line, or negative exponents.\footnote{Notice that a virgule and a -% solidus are not the same symbol.} However, to avoid ambiguity, the -% virgule must not be repeated on the same line unless parentheses -% are used. This is ensured when using named unit macros in -% \pkg{siunitx}, which will \enquote{trap} repeated division and format -% it correctly. In complicated cases, negative exponents are to be -% preferred over other formats. -%\begin{LaTeXdemo} -% \si{\joule\per\mole\per\kelvin}\\ -% \si[per-mode = fraction]{\joule\per\mole\per\kelvin}\\ -% \si[per-mode = symbol]{\joule\per\mole\per\kelvin} -%\end{LaTeXdemo} -% -% Products and errors should show what unit applies to each number -% given. Thus \SI[product-units = brackets]{2x3}{\metre} is an -% ordered set of lengths of a geometric area, whereas -% \SI[product-units = single]{2x3}{\metre} is a length (and equal -% to \SI{6}{\metre}). Thus, \(\times\) is not a product but is a -% mathematical operator; in the same way, a \(2 \times 3\) matrix is not -% a \(6\) matrix! In some areas, areas and volumes are given with -% separated units but a unit raised to the appropriate power: -% \SI[product-units = power]{2 x 3}{\metre}. Although this does -% display the correct overall units, it is potentially-confusing and is -% not encouraged. -% -% Care must be taken when writing ranges of numbers. For purely -% numerical values, it is common to use a en-dash to show a range, for -% example \enquote{see pages 1--5}. On the other hand, physical -% quantities could be misinterpret as negative values if written in this -% way. As the unit--number combination is a single mathematical entity, -% writing the values with an en-dash followed by a single unit is also -% incorrect. As a result, using the word \enquote{to} is strongly -% recommended. -%\begin{LaTeXdemo} -% \SIrange{1}{5}{\metre} long. -%\end{LaTeXdemo} -% -%\subsection{Graphs and tables} -% -% In graphs and tables, repetition of the units following each entry -% or axis mark is confusing and repetitive. It is therefore best to -% place the unit in the label part of the information. Placing the -% unit in square brackets is common but mathematically -% poor.\footnote{For example, for an acceleration \(a\), the expression -% \([a]\) is the dimensions of \(a\), \emph{i.e.}~length per time -% squared in this case.} Much better is to show division of all -% quantities by the unit, which leaves the entries as unitless ratios. -% This is illustrated in \cref{tab:xmpl:unitless} and -% \cref{fig:xmpl:unitless}. -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{An example of table labelling.} -% \label{tab:xmpl:unitless} -% \sisetup{ -% table-number-alignment = center, -% table-figures-integer = 1, -% table-figures-decimal = 4 -% } -% \begin{tabular}{cS} -% \toprule -% Entry & {Length/\si{\metre}} \\ -% \midrule -% 1 & 1.1234 \\ -% 2 & 1.1425 \\ -% 3 & 1.7578 \\ -% 4 & 1.9560 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -%\begin{LaTeXdemo}[code and float] -% \begin{figure} -% \centering -% \begin{tikzpicture} -% \begin{axis}[ -% xlabel = \( t/\si{\second} \), -% xmax = 6, -% xmin = 0, -% ylabel = \( d/\si{\metre} \), -% ymin = 0 -% ] -% \addplot[smooth,mark=*] -% plot coordinates { -% (0,0) -% (1,5) -% (2,8) -% (3,9) -% (4,8) -% (5,5) -% (6,0) -% }; -% \end{axis} -% \end{tikzpicture} -% \caption{An example of graph labelling.} -% \label{fig:xmpl:unitless} -% \end{figure} -%\end{LaTeXdemo} -% -% In most cases, adding exponent values in the body of a table is -% less desirable than adding a fixed exponent to column headers. An -% example is shown in \cref{tab:good}. The use of \cs{multicolumn} is -% needed here due to the \enquote{\texttt{<}}; without \cs{multicolumn}, -% the titles are followed by \enquote{\si{\kilo\gram}}! -%\begin{LaTeXdemo}[code and float] -% \begin{table} -% \centering -% \caption{Good and bad columns.} -% \label{tab:good} -% \sisetup{table-number-alignment = center} -% \begin{tabular}{ -% c -% S[ -% table-figures-integer = 1, -% table-figures-decimal = 3, -% table-figures-exponent = 1 -% ] -% @{\,\si{\kilogram}} -% S[ -% table-figures-integer = 2, -% table-figures-decimal = 2 -% ] -% } -% \toprule -% Entry & \multicolumn{1}{c}{Mass} & -% {Mass/\SI{e3}{\kilogram}} \\ -% \midrule -% 1 & 4.56e3 & 4.56 \\ -% 2 & 2.40e3 & 2.40 \\ -% 3 & 1.345e4 & 13.45 \\ -% 4 & 4.5e2 & 0.45 \\ -% \bottomrule -% \end{tabular} -% \end{table} -%\end{LaTeXdemo} -% -%\section{Making suggestions and reporting bugs} -% -% Feedback on \pkg{siunitx} is always welcome, either to make -% suggestions or to report problems. When sending feedback, it is -% always useful if a small example file is included, showing the -% bug being reported or illustrating the desired output. It is -% helpful if a \enquote{reference rendering} is included, showing what -% the output should look like. A typical example file might read -%\begin{LaTeXdemo}[code only] -% \listfiles -% % Use the article class unless the problem is class-dependent -% \documentclass{article} -% \usepackage{siunitx} -% % Other packages loaded as required -% \begin{document} -% Reference output: $ 1.23\,\mathrm{m} $ -% -% siunitx output: \SI{1.23}{\metre} -% \end{document} -%\end{LaTeXdemo} -% As illustrated, it is usually best to use the \texttt{article} -% class and to only load packages which are needed to show the issue. -% It is also useful to include a copy of the log file generate by -% \TeX{} when reporting a bug (as the versions of packages can be -% important to solving the issue). +%<*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 % -% Feedback can be sent in a range of ways. The development code -% is hosted by -% \href{https://github.com/josephwright/siunitx/}{GitHub}, -% and the site includes an issue tracker. Adding feedback directly -% to the database means that other users can see it, and also -% ensures that it does not get forgotten. E-mailing directly -% will also definitely get attention: -% \href{mailto:joseph.wright@morningstar2.co.uk} -% {\texttt{joseph.wright@morningstar2.co.uk}}. +% \GetFileInfo{siunitx.sty} % -% \section{Code level interfaces} +% \title{^^A +% \pkg{siunitx} -- Overall set up^^A +% \thanks{This file describes \fileversion, +% last revised \filedate.}^^A +% } % -% At present, most interfaces in \pkg{siunitx} at the code level are internal. -% This largely reflects the parallel between \pkg{siunitx} and core \pkg{expl3} -% development: much of the code here was written whilst the \LaTeX{} team were -% defining how best to handle this area. Development work on the next major -% release of \pkg{siunitx} includes a full set of documented code level -% interfaces. Some of these will be added to this (release) version of the -% package over time, where this is appropriate. +% \author{^^A +% Joseph Wright^^A +% \thanks{^^A +% E-mail: +% \href{mailto:joseph.wright@morningstar2.co.uk} +% {joseph.wright@morningstar2.co.uk}^^A +% }^^A +% } % -% \begin{variable}{\l_siunitx_unit_symbolic_seq} -% This sequence contains all of the symbolic \meta{unit} names defined: -% these will be in the form of control sequences such as |\kilogram|. -% The order of the sequence is unimportant. -% \end{variable} +% \date{Released \filedate} % -%\section{Thanks} +% \maketitle % -% Many users have provided feedback, bug reports and ideas for new -% features for \pkg{siunitx}: thanks to all of them. Particular thanks -% to Stefan Pinnow, who has taken the lead role as beta tester for -% \pkg{siunitx}, finding incorrect output, bad documentation and the -% odd spelling mistake in the documentation. Thanks also to -% Danie Els and Marcel Heldoorn for the \pkg{SIstyle} and \pkg{SIunits} -% packages, respectively, which provided the starting point for the -% development of \pkg{siunitx}. +% \begin{documentation} % -%\end{documentation} +% \end{documentation} % -%\begin{implementation} +% \begin{implementation} % -%\section{Implementation} +% \section{\pkg{siunitx} implementation} % +% Start the \pkg{DocStrip} guards. % \begin{macrocode} %<*package> % \end{macrocode} % +% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention). % \begin{macrocode} %<@@=siunitx> % \end{macrocode} % -%\subsection{Preliminaries} -% -% The usual preliminaries. -% \begin{macrocode} -\ProvidesExplPackage {siunitx} {2021-04-17} {2.8e} - {A comprehensive (SI) units package} -% \end{macrocode} +% \subsection{Initial set up} % -% Make sure that the version of \pkg{l3kernel} in use is sufficiently new. -% This will also trap any problems with \pkg{l3packages} (as the two are now -% tied together, version-wise). % \begin{macrocode} -\@ifpackagelater { expl3 } { 2020/01/12 } - { } - { - \PackageError { siunitx } { Support~package~expl3~too~old } - { - You~need~to~update~your~installation~of~the~bundles~'l3kernel'~and~ - 'l3packages'.\MessageBreak - Loading~siunitx~will~abort! - } - \tex_endinput:D - } +%<*init> % \end{macrocode} % -%\begin{macro}{\@@_load_check:} -% There are also a number of packages that are incompatible with -% \pkg{siunitx}. These are all checked for next. Some of the -% incompatible packages will not raise an error if loaded after -% \pkg{siunitx}. So a test is made at the beginning of the -% document as well. The message for this may be needed immediately, so -% it is created here not with the other messages. +% Set up a couple of commands in recent-ish \LaTeXe{} releases. % \begin{macrocode} -\msg_new:nnnn { siunitx } { incompatible-package } - { Package~'#1'~incompatible. } - { The~#1~package~and~siunitx~are~incompatible. } -\cs_new_protected:Npn \@@_load_check:n #1 { - \group_begin: - \@ifpackageloaded {#1} - { \msg_error:nnx { siunitx } { incompatible-package } {#1} } - { } - \group_end: -} -\clist_map_function:nN - { SIunits , sistyle , siunits , SIstyle , unitsdef , fancyunits } - \@@_load_check:n -\AtBeginDocument { - \clist_map_function:nN { SIunits , sistyle , siunits , SIstyle } - \@@_load_check:n -} -% \end{macrocode} -%\end{macro} -% -% Now load the support packages. -% \begin{macrocode} -\RequirePackage{ amstext , array , l3keys2e } -% \end{macrocode} -% -% \begin{macro}{@@_if_hooks:TF} -% To work with updated hooks if available. -% \begin{macrocode} -\@ifl@t@r \fmtversion { 2020-10-01 } - { \cs_new_eq:NN \@@_if_hooks:TF \use_i:nn } - { \cs_new_eq:NN \@@_if_hooks:TF \use_ii:nn } -% \end{macrocode} -% \end{macro} -% -%\begin{macro}{\@@_tmp:w} -% A scratch function. -% \begin{macrocode} -\cs_new:Npn \@@_tmp:w { } -% \end{macrocode} -%\end{macro} -% -% Add some variants. -% \begin{macrocode} -\cs_generate_variant:Nn \clist_map_function:nN { nc } -\cs_generate_variant:Nn \tl_if_blank:nTF { V } -\cs_generate_variant:Nn \tl_replace_all:Nnn { No, NV , Nx } -% \end{macrocode} -% -%\begin{macro}{ -% \l_@@_tmp_bool , -% \l_@@_tmp_box , -% \l_@@_tmp_dim , -% \l_@@_tmp_int , -% \l_@@_tmpa_tl , -% \l_@@_tmpb_tl -%} -% Scratch variables. -% \begin{macrocode} -\bool_new:N \l_@@_tmp_bool -\box_new:N \l_@@_tmp_box -\dim_new:N \l_@@_tmp_dim -\int_new:N \l_@@_tmp_int -\tl_new:N \l_@@_tmpa_tl -\tl_new:N \l_@@_tmpb_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_error:nxx , -% \@@_error:nx , -% \@@_error:n -%} -%\begin{macro}{\l_@@_error_bool} -% General-purpose functions for throwing errors. -% \begin{macrocode} -\cs_new_protected:Npn \@@_error:nxx #1#2#3 { - \bool_set_true:N \l_@@_error_bool - \msg_error:nnxx { siunitx } {#1} {#2} {#3} -} -\cs_new_protected:Npn \@@_error:nx #1#2 { - \@@_error:nxx {#1} {#2} { } -} -\cs_new_protected:Npn \@@_error:n #1 { - \@@_error:nxx {#1} { } { } -} -\bool_new:N \l_@@_error_bool -% \end{macrocode} -%\end{macro} -%\end{macro} -% -% Ensure that the companion font is loaded. -% \begin{macrocode} -\AtBeginDocument { - \cs_if_free:cT { T@TS1 } - { \RequirePackage { textcomp } } -} -% \end{macrocode} -% -% \begin{macro} -% { -% \@@_tl_put_left_math:Nn , -% \@@_tl_put_left_math:NV , -% } -% To add stuff in math mode. -% \begin{macrocode} -\cs_new_protected:Npn \@@_tl_put_left_math:Nn #1#2 - { \tl_put_left:Nn #1 { \ensuremath {#2} } } -\cs_generate_variant:Nn \@@_tl_put_left_math:Nn { NV } -% \end{macrocode} -% \end{macro} -% -%\begin{macro}{\c_@@_old_options_seq} -% To pick up old options, all of the names need to be known. -% \begin{macrocode} -\exp_args:NNx \seq_const_from_clist:Nn \c_@@_old_options_seq - { - \tl_to_str:n - { - addsign , - allowlitunits , - allowoptarg , - allowzeroexp , - alsoload , - angformat , - anglesep , - astroang , - closeerr , - closrfrac , - closerange , - colour , - colorall , - colourall , - colorneg , - colourneg , - colourunits , - colourunits , - colorvalues , - colourvalues , - decimalsymbol , - debug , - detectdisplay , - digitsep , - dp , - emulate , - errspace , - eVcorra , - eVcorrb , - expbase , - expproduct , - fixdp , - fixsf , - fraction , - inlinebold , - loctolang , - log , - load , - mathOmega , - mathcelsius , - mathdegree , - mathminute , - mathmu , - mathringA , - mathrm , - mathsOmega , - mathscelsius , - mathsdegree , - mathsecond , - mathsf , - mathsminute , - mathsmu , - mathsringA , - mathsrm , - mathssecond , - mathssf , - mathstt , - mathtt , - negcolor , - negcolour , - noload , - numaddn , - numcloseerr , - numdecimal , - numdigits , - numdiv , - numexp , - numgobble , - numopenerr , - numprod , - numsign , - obeyall , - obeybold , - obeyfamily , - obeymode , - obeyitalic , - openerr , - openfrac , - openrange , - padangle , - padnumber , - per , - prefixbase , - prefixproduct , - prefixsymbolic , - prespace , - redefsymbols , - repeatunits , - retainplus , - seperr , - sepfour , - sf , - sign , - slash , - stickyper , - strictarc , - tabalign , - tabalignexp , - tabautofit , - tabexpalign , - tabformat , - tabnumalign , - tabparseonly , - tabtextalign , - textOmega , - textcelsius , - textdegree , - textminute , - textmode , - textmu , - textringA , - textrm , - textsecond , - textsf , - texttt , - tightpm , - tophrase , - trapamigerr , - trapambigfrac , - trapambigrange , - unitcolor , - unitcolour , - unitmathrm , - unitmathsf , - unitmathsrm , - unitmathssf , - unitmathstt , - unitmathtt , - unitmode , - unitsep , - unitspace , - valuecolor , - valuecolour , - valuemathrm , - valuemathsf , - valuemathsrm , - valuemathssf , - valuemathstt , - valuemathtt , - valuemode , - valuesep , - xspace - } - } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_key_tl} -% Unknown options should raise an \pkg{siunitx}-specific error message. -% \begin{macrocode} -\tl_new:N \l_@@_key_tl -\keys_define:nn { siunitx } { - unknown .code:n = - { - \seq_if_in:NVTF \c_@@_old_options_seq \l_keys_key_tl - { - \msg_warning:nnx { siunitx } { version-1-option } - { \exp_not:V \l_keys_key_tl } - \tl_set:Nx \l_@@_key_tl - { - \keys_set:nn { siunitx } - { - \exp_not:V \l_keys_key_tl - \tl_if_blank:nF {#1} { = \exp_not:n {#1} } - } - } - \keys_set:nn { siunitx } { version-1-compatibility } - \tl_use:N \l_@@_key_tl - } - { - \msg_error:nnx { siunitx } { unknown-option } - { \exp_not:V \l_keys_key_tl } - } - } -} -\AtBeginDocument { - \keys_define:nn { siunitx } { - unknown .code:n = - { - \seq_if_in:NVTF \c_@@_old_options_seq \l_keys_key_tl - { - \msg_error:nnx { siunitx } { version-1-option } - { \exp_not:V \l_keys_key_tl } - } - { - \msg_error:nnx { siunitx } { unknown-option } - { \exp_not:V \l_keys_key_tl } - } - } -} -} +\providecommand\DeclareRelease[3]{} +\providecommand\DeclareCurrentRelease[2]{} % \end{macrocode} -%\end{macro} % -%\begin{macro}{\@@_option_deactivate:n} -%\begin{macro}{\@@_option_deactivate_aux:n} -%\begin{macro}{\l_@@_option_deactivate_clist} -% Some options need to be deactivated at the start of the document. +% Allow rollback to version~$2$: if we need to, version~$1$ could eventually +% be added here too. % \begin{macrocode} -\cs_new_protected:Npn \@@_option_deactivate:n #1 { - \clist_put_right:Nn \l_@@_option_deactivate_clist {#1} -} -\cs_new_protected:Npn \@@_option_deactivate_aux:n #1 { - \keys_define:nn { siunitx } - { - #1 .code:n = - { \msg_warning:nnx { siunitx } { option-preamble-only } {#1} } - } -} -\AtBeginDocument { - \clist_map_function:NN \l_@@_option_deactivate_clist - \@@_option_deactivate_aux:n -} -\clist_new:N \l_@@_option_deactivate_clist +\DeclareRelease{2}{2010-05-23}{siunitx-v2.sty} +\DeclareRelease{v2}{2010-05-23}{siunitx-v2.sty} +\DeclareCurrentRelease{}{2021-05-17} % \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} % -% \begin{macro}{\@@_option_unchanged:Nnn} -% Needed to allow for altering of options at the start of the document -% only if they are unchanged. This needs to use the low-level implementation -% detail, hence the use of variable name directly. +% Load only the essential support (\pkg{expl3}) \enquote{up-front}, and +% only if required. % \begin{macrocode} -\cs_new_protected:Npn \@@_option_unchanged:Nnn #1#2#3 - { - \str_if_eq:VnT #1 {#2} - { \tl_set:Nn #1 {#3} } - } +\@ifundefined{ExplFileDate} + {\RequirePackage{expl3}} + {} % \end{macrocode} -% \end{macro} % -% Variants needed which are not in \pkg{expl3}. -% \begin{macrocode} -\cs_generate_variant:Nn \tl_if_empty_p:n { f } -\cs_generate_variant:Nn \tl_if_empty:nT { f } -\cs_generate_variant:Nn \tl_if_in:NnTF { NV } -\cs_generate_variant:Nn \tl_replace_all:Nnn { NnV } +% Make sure that the version of \pkg{l3kernel} in use is sufficiently new. +% We use \cs{ExplFileDate} as \cs{@ifpackagelater} doesn't work for pre-loaded +% \pkg{expl3} in the absence of the package. +% \begin{macrocode} +\@ifl@t@r\ExplFileDate{2018-06-01} + {} + {% + \PackageError{siunitx}{Support package expl3 too old} + {% + You need to update your installation of the bundles 'l3kernel' and + 'l3packages'.\MessageBreak + Loading~siunitx~will~abort!% + }% + \endinput + }% % \end{macrocode} % -% \begin{macro}[pTF]{\@@_cs_if_tl:N} -% A test for token lists (more or less). +% Identify the package and give the over all version information. % \begin{macrocode} -\prg_new_conditional:Npnn \@@_cs_if_tl:N #1 { T, F , TF , p } - { - \bool_lazy_and:nnTF - { - \tl_if_empty_p:f - { - \cs_prefix_spec:N #1 - \cs_argument_spec:N #1 - } - } - { \bool_not_p:n { \cs_if_exist_p:c { \cs_to_str:N #1 ~ } } } - { \prg_return_true: } - { \prg_return_false: } - } +\ProvidesExplPackage {siunitx} {2021-05-17} {3.0.0} + {A comprehensive (SI) units package} % \end{macrocode} -% \end{macro} % -% \begin{macro}[EXP] -% {\@@_number_if_zero:nTF, \@@_number_if_zero_p:n \@@_number_if_zero_p:V} -% \begin{macro}[EXP, aux]{\@@_number_if_zero_aux:n} -% A test for all of the input to a function being made up of zeros: -% needed to avoid overflowing \TeX{}'s integer range. -% \begin{macrocode} -\prg_new_conditional:Npnn \@@_number_if_zero:n #1 { p , TF } - { - \tl_map_function:nN {#1} \@@_number_if_zero_aux:n - \prg_return_true: - } -\cs_generate_variant:Nn \@@_number_if_zero_p:n { V } -\cs_new:Npn \@@_number_if_zero_aux:n #1 - { - \token_if_eq_charcode:NNF #1 0 - { \tl_map_break:n { \prg_return_false: \use_none:n } } - } -% \end{macrocode} -% \end{macro} -% \end{macro} +% \subsection{Safety checks} % -% If \pkg{tex4ht} is in use, make a few changes to give nicer looking -% conversion to other formats. +% \begin{macro}{\@@_load_check:} +% There are a number of packages that are incompatible with \pkg{siunitx} +% as they cover the same concepts and in some cases define the same command +% names. These are all tested at the point of loading to try to trap +% issues, and a couple are also tested later as it's possible for them to +% load without an obvious error if \pkg{siunitx} was loaded first. % \begin{macrocode} -\AtBeginDocument +\msg_new:nnnn { siunitx } { incompatible-package } + { Package~'#1'~incompatible. } + { The~#1~package~and~siunitx~are~incompatible. } +\cs_new_protected:Npn \@@_load_check:n #1 { - \@ifpackageloaded { tex4ht } - { - \cs_set_eq:NN \@@_print_text_super:n \textsuperscript - \@@_option_unchanged:Nnn \l_@@_qualifier_mode_tl - { subscript } { brackets } - \keys_set:nn { siunitx } { mode = text } - } + \@ifpackageloaded {#1} + { \msg_error:nnx { siunitx } { incompatible-package } {#1} } { } } -% \end{macrocode} -% -% \begin{macro}{\@@_ensure_ltr:n} -% When the \pkg{bidi} package is loaded with \XeTeX{} we need to make sure -% that \cs{text} is doing the correct thing. The \pkg{bidi} package seems to -% lead to a slightly broken \cs{text}, so this is something of a hack. -% \begin{macrocode} -\cs_new_eq:NN \@@_ensure_ltr:n \use:n +\clist_map_function:nN + { SIunits , sistyle , unitsdef , fancyunits } + \@@_load_check:n \AtBeginDocument { - \@ifpackageloaded { bidi } - { - \sys_if_engine_xetex:T - { \cs_set_protected:Npn \@@_ensure_ltr:n #1 { \LRE {#1} } } - } - { } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_textsuperscript:n} -% This function is set up here so that it can be redefined -% elsewhere as expandable. That is used in the bookmark system so -% that \pkg{hyperref} does not raise any unnecessary warnings. With -% \pkg{fontspec} loaded the kernel defintion for \cs{textsuperscript} -% may get altered so a private copy of the orignal code is used. (Yes, -% this really should be done like Con\TeX{}t -% \begin{macrocode} -\cs_new_protected:Npn \@@_textsuperscript:n #1 - { - \m@th - \ensuremath { ^ { \mbox { \fontsize \sf@size \z@ \selectfont #1 } } } - } -% \end{macrocode} -% \end{macro} -% -%\begin{macro}{\l_@@_display_math_bool} -% To test for display math, a flag is added to the start of every -% display environment. -% \begin{macrocode} -\bool_new:N \l_@@_display_math_bool -\tex_everydisplay:D \exp_after:wN - { - \tex_the:D \tex_everydisplay:D - \bool_set_true:N \l_@@_display_math_bool - } -% \end{macrocode} -%\end{macro} -% -% \begin{macro}[TF]{\prop_get:NVN} -% Missing from \pkg{expl3} at the moment. -% \begin{macrocode} -\cs_generate_variant:Nn \prop_get:NnNT { NV } -\cs_generate_variant:Nn \prop_get:NnNF { NV } -\cs_generate_variant:Nn \prop_get:NnNTF { NV } -% \end{macrocode} -% \end{macro} -% -%\subsection{Font detection} -% -% A number of controls and tests are needed to control the font used -% for output. The detection routines set up various functions which can -% then be used inside the \cs{text} macro from the \pkg{amstext} -% package. By carrying out the changes outside math mode, bold can -% reliably be applied to math output. -% -%\begin{macro}{\@@_set_math_fam:n} -%\begin{macro}{ -% \c_@@_mathsf_int , -% \c_@@_mathtt_int -%} -% The detection routine needs some basic data about the sans serif and -% monospaced fonts in use. This is collected up at the start of the -% document. The families used can change between here and the start of -% the document. This is run as a hook onto \cs{document}, rather than -% using \cs{AtBeginDocument} as it has to come after anything that -% \pkg{fontspec} does (nasty errors arise otherwise). -% \begin{macrocode} -\cs_new_protected:Npn \@@_set_math_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: -} -\@@_if_hooks:TF - { - \AddToHook { begindocument / end } [ siunitx ] - { - \@@_set_math_fam:n { sf } - \@@_set_math_fam:n { tt } - } - } - { - \tl_put_right:Nn \document - { - \@@_set_math_fam:n { sf } - \@@_set_math_fam:n { tt } - \ignorespaces - } + \clist_map_function:nN { SIunits , sistyle } + \@@_load_check:n } % \end{macrocode} %\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_font_set_text_fam:n} -%\begin{macro}{ -% \c_@@_textsf_tl , -% \c_@@_texttt_tl -%} -% The text families are done in a somewhat different manner: there are -% no issues with \cs{AtBeginDocument}, luckily. The need to define -% new macros here arises as \cs{sfdefault} and \cs{ttdefault} are -% \cs{long}, whereas \cs{f@family} is not. -% \begin{macrocode} -\cs_new_protected:Npn \@@_set_text_fam:n #1 { - \tl_const:cx { c_@@_text #1 _tl } { \use:c { #1 default } } -} -\AtBeginDocument { - \@@_set_text_fam:n { sf } - \@@_set_text_fam:n { tt } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\l_@@_detect_inline_weight_tl} -% Used by the keys, but needs to be created here. -% \begin{macrocode} -\tl_new:N \l_@@_detect_inline_weight_tl -% \end{macrocode} -%\end{macro} -% -% \begin{variable}{\l_@@_detect_inline_family_tl} -% This one is not generated by the keys system. -% \begin{macrocode} -\tl_new:N \l_@@_detect_inline_family_tl -% \end{macrocode} -% \end{variable} % -%\begin{macro}{ -% \l_@@_detect_display_math_bool , -% \l_@@_detect_family_bool , -% \l_@@_detect_inline_family_tl , -% \l_@@_detect_shape_bool , -% \l_@@_detect_mode_bool , -% \l_@@_detect_weight_bool -%} -% Font detection is all about creating switches, with just a little -% gloss for \texttt{detect-all} and \texttt{detect-none}. -% \begin{macrocode} -\keys_define:nn { siunitx } { - detect-all .choice:, - detect-all .default:n = true, - detect-all / false .meta:n = - { - detect-family = false , - detect-mode = false , - detect-shape = false , - detect-weight = false , - }, - detect-all / true .meta:n = - { - detect-family = true , - detect-mode = true , - detect-shape = true , - detect-weight = true , - }, - detect-display-math .bool_set:N = - \l_@@_detect_display_math_bool, - detect-family .bool_set:N = \l_@@_detect_family_bool, - detect-inline-family .choice:, - detect-inline-family .value_required:n = true, - detect-inline-family / - math .code:n = - { \tl_set:Nn \l_@@_detect_inline_family_tl { math } }, - detect-inline-family / - text .code:n = - { \tl_set:Nn \l_@@_detect_inline_family_tl { text } }, - detect-inline-weight .choice:, - detect-inline-weight .value_required:n = true, - detect-inline-weight / - math .code:n = - { \tl_set:Nn \l_@@_detect_inline_weight_tl { math } }, - detect-inline-weight / - text .code:n = - { \tl_set:Nn \l_@@_detect_inline_weight_tl { text } }, - detect-italic .bool_set:N = \l_@@_detect_shape_bool, - detect-mode .bool_set:N = \l_@@_detect_mode_bool, - detect-none .choice:, - detect-none .default:n = true, - detect-none / false .meta:n = - { - detect-family = true, - detect-mode = true, - detect-shape = true, - detect-weight = true - }, - detect-none / true .meta:n = - { - detect-family = false, - detect-mode = false, - detect-shape = false, - detect-weight = false - }, - detect-shape .bool_set:N = \l_@@_detect_shape_bool, - detect-weight .bool_set:N = \l_@@_detect_weight_bool -} -\keys_set:nn { siunitx } { - detect-inline-family = text , - detect-inline-weight = text , -} -% \end{macrocode} -%\end{macro} +% \subsection{Provide a kernel command} % -%\begin{macro}{ -% \l_@@_font_set_bool , -% \l_@@_font_math_mode_bool -%} -% The internals of the package need a number of switches to track what -% is happening. +% \begin{macro}{\IfFormatAtLeastTF} +% Not present in older kernels: use the \LaTeXe{} mechanism as this is correct +% for this case. % \begin{macrocode} -\bool_new:N \l_@@_font_set_bool -\bool_new:N \l_@@_font_math_mode_bool +\providecommand \IfFormatAtLeastTF { \@ifl@t@r \fmtversion } % \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_font_family_tl} -% Also some token storage. -% \begin{macrocode} -\tl_new:N \l_@@_font_family_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_font_shape: , -% \@@_font_weight: -%} -% These could be token lists or functions! -% \begin{macrocode} -\cs_new:Npn \@@_font_shape: { } -\cs_new:Npn \@@_font_weight: { } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_detect_font:} -% The main font-setting macro is a control point for the other -% functions. Nesting font-control should not happen, so the first -% test is to ensure this is not happening. -% \begin{macrocode} -\cs_new_protected:Npn \@@_detect_font: { - \bool_if:NF \l_@@_font_set_bool - { - \@@_detect_font_init: - \bool_if:NT \l_@@_detect_weight_bool - { \@@_detect_font_weight: } - \bool_if:NT \l_@@_detect_family_bool - { \@@_detect_font_family: } - \bool_if:NT \l_@@_detect_shape_bool - { \@@_detect_font_shape: } - \bool_if:NT \l_@@_detect_mode_bool - { \@@_detect_font_mode: } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_detect_font_init:} -% Set up the basic macros on the assumption nothing happens. -% \begin{macrocode} -\cs_new_protected:Npn \@@_detect_font_init: { - \bool_set_true:N \l_@@_font_set_bool - \cs_set:Npn \@@_font_weight: - { - \unboldmath - \mdseries - } - \cs_set:Npn \@@_font_shape: { \upshape } - \tl_set:Nn \l_@@_font_family_tl { rm } - \bool_set_true:N \l_@@_font_math_mode_bool -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_detect_font_weight:} -% The font weight detection code depends on whether the current text is -% math or text, and also the type of math (if appropriate). For -% inline math, there is a choice of what test to apply. -% \begin{macrocode} -\cs_new_protected:Npn \@@_detect_font_weight: { - \mode_if_math:TF - { - \bool_if:NTF \l_@@_display_math_bool - { - \bool_if:NTF \l_@@_detect_display_math_bool - { \@@_detect_font_weight_math: } - { \@@_detect_font_weight_text: } - } - { - \use:c - { - @@_detect_font_weight_ - \l_@@_detect_inline_weight_tl - : - } - } - } - { \@@_detect_font_weight_text: } -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{ -% \@@_detect_font_weight_math: , -% \@@_detect_font_weight_text: -%} -% The tests for font weight depend on whether the module is testing -% text or math content. -% \begin{macrocode} -\cs_new_protected:Npn \@@_detect_font_weight_math: { - \str_if_eq:VnT \math@version { bold } - { - \cs_set:Npn \@@_font_weight: - { - \boldmath - \bfseries - } - } - \str_if_eq:VnT \math@version { light } - { \cs_set:Npn \@@_font_weight: { \lseries } } -} -\cs_new_protected:Npn \@@_detect_font_weight_text: { - \tl_set:Nx \l_@@_tmpa_tl { \tl_head:N \f@series } - \str_if_eq:VnT \l_@@_tmpa_tl { b } - { - \cs_set:Npn \@@_font_weight: - { - \boldmath - \bfseries - } - } - \str_if_eq:VnT \l_@@_tmpa_tl { l } - { \cs_set:Npn \@@_font_weight: { \lseries } } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_detect_font_family:} -% Family detection usually picks up the surrounding text. However, for -% display math there are two options, and so a second test may be made. -% \begin{macrocode} -\cs_new_protected:Npn \@@_detect_font_family: { - \mode_if_math:TF - { - \bool_if:NTF \l_@@_display_math_bool - { - \bool_if:NTF \l_@@_detect_display_math_bool - { \@@_detect_font_family_math: } - { \@@_detect_font_family_text: } - } - { - \use:c - { - @@_detect_font_family_ - \l_@@_detect_inline_family_tl - : - } - } - } - { \@@_detect_font_family_text: } -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{ -% \@@_detect_font_family_math: , -% \@@_detect_font_family_text: -%} -% The two detections routines check if the current font is sans serif or -% monospaced. The method used depends on whether the current math or -% text font is of interest. The math detection routine re-applies the -% default (\texttt{rm}), as the text function is always called and may -% have changed things. -% \begin{macrocode} -\cs_new_protected:Npn \@@_detect_font_family_math: { - \tl_set:Nn \l_@@_font_family_tl { rm } - \int_compare:nNnT { \fam } = { \c_@@_mathsf_int } - { \tl_set:Nn \l_@@_font_family_tl { sf } } - \int_compare:nNnT { \fam } = { \c_@@_mathtt_int } - { \tl_set:Nn \l_@@_font_family_tl { tt } } -} -\cs_new_protected:Npn \@@_detect_font_family_text: { - \tl_if_eq:NNT \f@family \c_@@_textsf_tl - { \tl_set:Nn \l_@@_font_family_tl { sf } } - \tl_if_eq:NNT \f@family \c_@@_texttt_tl - { \tl_set:Nn \l_@@_font_family_tl { tt } } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_detect_font_shape:} -% The shape test uses \cs{f@shape} as a handy indicator. -% \begin{macrocode} -\cs_new_protected:Npn \@@_detect_font_shape: - { - \cs_if_exist:cT { \f@shape shape } - { - \cs_set:Npx \@@_font_shape: { \exp_not:c { \f@shape shape } } - } - } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_detect_font_mode:} -% The mode switch works from the fact that math mode output it the -% standard. -% \begin{macrocode} -\cs_new_protected:Npn \@@_detect_font_mode: { - \mode_if_math:F - { - \bool_set_false:N \l_@@_font_math_mode_bool - \bool_set_false:N \l_@@_number_math_mode_bool - \bool_set_false:N \l_@@_unit_math_mode_bool - } -} -% \end{macrocode} -%\end{macro} -% -%\subsection{Font macros} -% -% With the detection routines in place, the module can apply the result -% to control the font used for output. This requires a series of font -% names to be available. The appropriate storage areas will be selected -% by name, based on output type (\texttt{unit} or \texttt{value}) and -% the family selected by the detector. -% -%\begin{macro}{ -% \l_@@_number_math_mode_bool , -% \l_@@_unit_math_mode_bool -%} -% Most of the variables are created by the keys system: these are not. -% \begin{macrocode} -\bool_new:N \l_@@_number_math_mode_bool -\bool_new:N \l_@@_unit_math_mode_bool -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_mathrm:n , -% \@@_number_mathsf:n , -% \@@_number_mathtt:n , -% \@@_number_textrm: , -% \@@_number_textsf: , -% \@@_number_texttt: -%} -% Functions for number-mode fonts. -% \begin{macrocode} -\cs_new:Npn \@@_number_mathrm:n #1 { } -\cs_new:Npn \@@_number_mathsf:n #1 { } -\cs_new:Npn \@@_number_mathtt:n #1 { } -\cs_new:Npn \@@_number_textrm: { } -\cs_new:Npn \@@_number_textsf: { } -\cs_new:Npn \@@_number_texttt: { } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_number_color_tl} -% The settings are actually created separately for numbers and units: -% numbers first. -% \begin{macrocode} -\keys_define:nn { siunitx } { - number-color .tl_set:N = \l_@@_number_color_tl, - number-math-rm .code:n = - { \cs_set:Npn \@@_number_mathrm:n ##1 { #1 {##1} } }, - number-math-sf .code:n = - { \cs_set:Npn \@@_number_mathsf:n ##1 { #1 {##1} } }, - number-math-tt .code:n = - { \cs_set:Npn \@@_number_mathtt:n ##1 { #1 {##1} } }, - number-mode .choice:, - number-mode / math .code:n = - { \bool_set_true:N \l_@@_number_math_mode_bool }, - number-mode / text .code:n = - { \bool_set_false:N \l_@@_number_math_mode_bool }, - number-text-rm .code:n = - { \cs_set:Npn \@@_number_textrm: {#1} }, - number-text-sf .code:n = - { \cs_set:Npn \@@_number_textsf: {#1} }, - number-text-tt .code:n = - { \cs_set:Npn \@@_number_texttt: {#1} } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_unit_mathrm:n , -% \@@_unit_mathsf:n , -% \@@_unit_mathtt:n , -% \@@_unit_textrm: , -% \@@_unit_textsf: , -% \@@_unit_texttt: -%} -% The same storage for unit-mode fonts. -% \begin{macrocode} -\cs_new:Npn \@@_unit_mathrm: { } -\cs_new:Npn \@@_unit_mathsf: { } -\cs_new:Npn \@@_unit_mathtt: { } -\cs_new:Npn \@@_unit_textrm: { } -\cs_new:Npn \@@_unit_textsf: { } -\cs_new:Npn \@@_unit_texttt: { } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_unit_color_tl} -% Units look exactly the same. -% \begin{macrocode} -\keys_define:nn { siunitx } { - unit-color .tl_set:N = \l_@@_unit_color_tl, - unit-math-rm .code:n = - { \cs_set:Npn \@@_unit_mathrm:n ##1 { #1 {##1} } }, - unit-math-sf .code:n = - { \cs_set:Npn \@@_unit_mathsf:n ##1 { #1 {##1} } }, - unit-math-tt .code:n = - { \cs_set:Npn \@@_unit_mathtt:n ##1 { #1 {##1} } }, - unit-mode .choice:, - unit-mode / math .code:n = - { \bool_set_true:N \l_@@_unit_math_mode_bool }, - unit-mode / text .code:n = - { \bool_set_false:N \l_@@_unit_math_mode_bool }, - unit-text-rm .code:n = - { \cs_set:Npn \@@_unit_textrm: {#1} }, - unit-text-sf .code:n = - { \cs_set:Npn \@@_unit_textsf: {#1} }, - unit-text-tt .code:n = - { \cs_set:Npn \@@_unit_texttt: {#1} } -} -% \end{macrocode} -%\end{macro} -% -% The general settings are all meta-keys. A few initial values are set -% here as they are needed for everything to work. -% \begin{macrocode} -\keys_define:nn { siunitx } { - color .meta:n = - { - number-color = #1, - unit-color = #1 - }, - math-rm .meta:n = - { - number-math-rm = #1, - unit-math-rm = #1 - }, - math-sf .meta:n = - { - number-math-sf = #1, - unit-math-sf = #1 - }, - math-tt .meta:n = - { - number-math-tt = #1, - unit-math-tt = #1 - }, - mode .choice:, - mode / math .meta:n = - { - number-mode = math, - unit-mode = math - }, - mode / text .meta:n = - { - number-mode = text, - unit-mode = text - }, - text-rm .meta:n = - { - number-text-rm = #1, - unit-text-rm = #1 - }, - text-sf .meta:n = - { - number-text-sf = #1, - unit-text-sf = #1 - }, - text-tt .meta:n = - { - number-text-tt = #1, - unit-text-tt = #1 - } -} -\keys_set:nn { siunitx } { - math-rm = \mathrm, - math-sf = \mathsf, - math-tt = \mathtt, - mode = math, - text-rm = \rmfamily, - text-sf = \sffamily, - text-tt = \ttfamily, -} -% \end{macrocode} -% -% Some packages and classes (for example \pkg{beamer}) set the default -% family to be something other than serif family. A one-off detection -% will make life easier -% all round. -% \begin{macrocode} -\AtBeginDocument { - \tl_set:Nx \l_@@_tmpa_tl { \familydefault } - \@ifpackageloaded { eulervm } - { - \cs_set:Npn \@@_tmp:w #1 { \mathrm {#1} } - \cs_if_eq:NNT \@@_number_mathrm:n \@@_tmp:w - { \keys_set:nn { siunitx } { number-math-rm = \mathnormal } } - \cs_if_eq:NNT \@@_unit_mathrm:n \@@_tmp:w - { \keys_set:nn { siunitx } { unit-math-rm = \mathnormal } } - } - { } - \tl_if_eq:NNT \l_@@_tmpa_tl \c_@@_textsf_tl - { - \@ifpackageloaded { arev } - { } - { - \@ifpackageloaded { cmbright } - { } - { - \cs_set:Npn \@@_tmp:w #1 { \mathrm {#1} } - \cs_if_eq:NNT \@@_number_mathrm:n \@@_tmp:w - { \keys_set:nn { siunitx } { number-math-rm = \mathsf } } - \cs_if_eq:NNT \@@_unit_mathrm:n \@@_tmp:w - { \keys_set:nn { siunitx } { unit-math-rm = \mathsf } } - } - } - \cs_set:Npn \@@_tmp:w { \rmfamily } - \cs_if_eq:NNT \@@_number_textrm: \@@_tmp:w - { \keys_set:nn { siunitx } { number-text-rm = \sffamily } } - \cs_if_eq:NNT \@@_unit_textrm: \@@_tmp:w - { \keys_set:nn { siunitx } { unit-text-rm = \sffamily } } - } - \tl_if_eq:NNT \l_@@_tmpa_tl \c_@@_texttt_tl - { - \cs_set:Npn \@@_tmp:w #1 { \mathrm {#1} } - \cs_if_eq:NNT \@@_number_mathrm:n \@@_tmp:w - { \keys_set:nn { siunitx } { number-math-rm = \mathtt } } - \cs_if_eq:NNT \@@_unit_mathrm:n \@@_tmp:w - { \keys_set:nn { siunitx } { unit-math-rm = \mathtt } } - \cs_set:Npn \@@_tmp:w { \rmfamily } - \cs_if_eq:NNT \@@_number_textrm: \@@_tmp:w - { \keys_set:nn { siunitx } { number-text-rm = \ttfamily } } - \cs_if_eq:NNT \@@_unit_textrm: \@@_tmp:w - { \keys_set:nn { siunitx } { unit-text-rm = \ttfamily } } - } -} -% \end{macrocode} -% -%\subsection{Output control} -% -% The \pkg{siunitx} output routine uses all of the font information -% gathered earlier to print the text given in whatever font is required. -% The low-level stuff is done here, with the calling routines expected -% to have taken some steps first (this is to allow line breaks in the -% appropriate places). -% -%\begin{macro}{\l_@@_print_arg_tl} -% The text to print. -% \begin{macrocode} -\tl_new:N \l_@@_print_arg_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_print_type_tl} -% The type of output (\texttt{number} or \texttt{unit}) is always -% needed. -% \begin{macrocode} -\tl_new:N \l_@@_print_type_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_print:nn , -% \@@_print:nV -%} -%\begin{macro}{\@@_print_aux:} -% The main printing function does everything inside a group, as -% there are category code and definition changes to make. First, set -% the fonts. Then move on to printing mode, before moving to actual -% printing. -% \begin{macrocode} -\cs_new_protected:Npn \@@_print:nn #1#2 { - \group_begin: - \tl_set:Nn \l_@@_print_type_tl {#1} - \tl_set:Nn \l_@@_print_arg_tl {#2} - \@@_detect_font: - \bool_if:NF \l_@@_detect_mode_bool - { - \bool_if:cTF { l_@@_ #1 _math_mode_bool } - { \bool_set_true:N \l_@@_font_math_mode_bool } - { \bool_set_false:N \l_@@_font_math_mode_bool } - } - \@@_print_aux: - \group_end: -} -\cs_generate_variant:Nn \@@_print:nn { nV } -% \end{macrocode} -% The various font changes are set up, then the correct printing -% function is called. Everything is inside \cs{text} as this allows -% proper setting of the various mode settings. -% \begin{macrocode} -\cs_new_protected:Npn \@@_print_aux: - { - \text - { - \@@_ensure_ltr:n - { - \color@begingroup - \@@_print_color: - \@@_font_shape: - \@@_font_weight: - \use:c - { - @@_ \l_@@_print_type_tl _ - text \l_@@_font_family_tl : - } - \bool_if:NTF \l_@@_font_math_mode_bool - { \@@_print_math: } - { \@@_print_text: } - \color@endgroup - } - } - } -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{ -% \@@_print_color: , -% \@@_textcolor:n -%} -% The colour system checks if \pkg{color} is loaded, and only does -% anything if it is. This will change when \LaTeX3 proper is available: -% there will be colour out of the box! -% \begin{macrocode} -\cs_new_protected:Npn \@@_print_color: { - \tl_if_empty:cF { l_@@_ \l_@@_print_type_tl _color_tl } - { - \color - { - \tl_use:c { l_@@_ \l_@@_print_type_tl _color_tl } - } - } -} -\AtBeginDocument { - \@ifpackageloaded { color } - { \cs_new_eq:NN \@@_textcolor:n \textcolor } - { - \cs_set_protected:Npn \@@_print_color: - { - \tl_if_empty:cF { l_@@_ \l_@@_print_type_tl _color_tl } - { - \cs_gset_eq:NN \@@_print_color: \scan_stop: - \msg_warning:nn { siunitx } { color-not-loaded } - } - } - \cs_new_protected:Npn \@@_textcolor:n #1 - { - \cs_gset_eq:NN \@@_textcolor:n \use_none:n - \msg_warning:nn { siunitx } { color-not-loaded } - } - } -} -% \end{macrocode} -%\end{macro} -% -% \begin{macro}{\@@_print_math:, \@@_print_text:} -% \begin{macro}{\@@_print_text_aux:} -% \begin{macro}{\@@_print_text_aux:NnN} -% Printing the text means replacing any awkward characters, which is -% dependent on the output mode. The rest of the package uses "_" and -% "^" to represent sub- and superscripts, respectively. In this way, -% mode decisions can be delayed as long as possible. The -% \pkg{underscore} package may make "_" active, or more likely -% it will be a superscript character. Both are tested for here. -% \begin{macrocode} -\cs_new_protected:Npn \@@_print_math: - { - \cs_set_eq:NN \PrintSubscript \sb - \cs_set_eq:NN \PrintSuperscript \sp - \ensuremath - { - \use:c - { - @@_ \l_@@_print_type_tl _ - math \l_@@_font_family_tl :n - } - { \l_@@_print_arg_tl } - } - } -\cs_new_protected:Npn \@@_print_text: - { - \tl_replace_all:Nnn \l_@@_print_arg_tl { - } - { \textminus } - \@@_print_text_aux: - \tl_replace_all:Nnn \l_@@_print_arg_tl { \mp } - { \ensuremath { \mp } } - \tl_remove_all:Nn \l_@@_print_arg_tl { \mathord } - \cs_set_eq:NN \PrintSubscript \@@_print_text_sub:n - \cs_set_eq:NN \PrintSuperscript \@@_print_text_super:n - \__siunitx_print_text_aux:NnN - _ { math_subscript } \@@_print_text_sub:n - _ { active } \@@_print_text_sub:n - ^ { math_superscript } \@@_print_text_super:n - ^ { active } \@@_print_text_super:n - \q_recursion_tail ? ? - \q_recursion_stop - \l_@@_print_arg_tl - } -\cs_new_protected:Npn \@@_print_text_aux: - { - \tl_replace_all:Nnn \l_@@_print_arg_tl { \pm } - { \ensuremath { \pm } } - } -\cs_new_protected:Npn \@@_print_text_aux:NnN #1#2#3 - { - \quark_if_recursion_tail_stop:N #1 - \tl_set_rescan:Nnn \l_@@_tmpa_tl - { \use:c { char_set_catcode_ #2 :N } #1 } - {#1} - \tl_replace_all:NVn \l_@@_print_arg_tl \l_@@_tmpa_tl {#3} - \_@@_print_text_aux:NnN - } -\AtBeginDocument - { - \@ifpackageloaded { textcomp } - { - \cs_set_protected:Npn \@@_print_text_aux: - { - \tl_replace_all:Nnn \l_@@_print_arg_tl { \pm } - { \textpm } - } - } - { } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -%\begin{macro}{ -% \@@_print_text_sub:n , -% \@@_print_text_super:n -%} -%\begin{macro}{\@@_print_text_sub_super:n} -% \begin{macro}{\@@_print_text_sub_peek:} -% \begin{macro}{\@@_peek_true:, \@@_peek_false:} -% The appropriate macros for sub- and superscript in text mode ensure -% the appearance is the same as math mode. The search and replace -% code for superscripts deals with the case where a literal number has -% been given with text mode printing. There is currently an issue with -% \pkg{expl3}'s \cs{peek_\ldots} functions, which means that the peek -% code is written out here in full. -% \begin{macrocode} -\cs_new_protected:Npn \@@_print_text_sub:n #1 - { - \cs_set:Npn \@@_print_text_sub_super:n ##1 - { - \ensuremath - { - \sb { \text {#1} } - \sp { \text {##1} } - } - } - \cs_set_protected:Npn \@@_peek_true: - { - \tex_afterassignment:D \@@_print_text_sub_super:n - \cs_set_eq:NN \@@_tmp:w - } - \cs_set_protected:Npn \@@_peek_false: - { \ensuremath { \sb { \text {#1} } } } - \peek_after:Nw \@@_print_text_sub_peek: - } -\cs_new_protected:Npn \@@_print_text_sub_peek: - { - \if_meaning:w \l_peek_token \@@_print_text_super:n - \exp_after:wN \@@_peek_true: - \else: - \exp_after:wN \@@_peek_false: - \fi: - } -\cs_new_protected:Npn \@@_peek_true: { } -\cs_new_protected:Npn \@@_peek_false: { } -\cs_new_protected:Npn \@@_print_text_sub_super:n { } -\cs_new_protected:Npn \@@_print_text_super:n #1 { - \tl_set:Nn \l_@@_tmpa_tl {#1} - \tl_replace_all:Nnn \l_@@_tmpa_tl { - } - { \textminus } - \tl_set:Nx \l_@@_tmpa_tl - { - \exp_not:N \ensuremath - { \sp { \exp_not:N \text { \exp_not:V \l_@@_tmpa_tl } } } - } - \l_@@_tmpa_tl -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% \end{macro} % \end{macro} % -%\begin{macro}{ -% \PrintSubscript , -% \PrintSuperscript -%} -% In the unit-construction code, there are places where it cannot -% be guarenteed that the search-and-replace approach will work. -% Instead, two user-space functions are needed. These are only -% defined within the above code: the names are not needed elsewhere. -%\end{macro} -% -%\subsection{Pre-processing numbers} -% -% Before the main parsing routine can be called, there is a need to -% pre-process the input. The possibility that the data in can contain -% more than one number needs to be handled. -% -%\begin{macro}{\l_@@_input_product_tl} -%\begin{macro}{\l_@@_input_quotient_tl} -% There are a couple of settings which are created here as they are used -% only for pre-processing. -% \begin{macrocode} -\keys_define:nn { siunitx } { - input-product .tl_set:N = \l_@@_input_product_tl, - input-quotient .tl_set:N = \l_@@_input_quotient_tl, -} -\keys_set:nn { siunitx } { - input-product = x, - input-quotient = / -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_number_arg_tl , -% \l_@@_number_next_tl -%} -% Storage for the pre-parsed material. The \texttt{arg} variable -% contains the current argument, the \texttt{next} variable contains -% anything held-over for the next round. -% \begin{macrocode} -\tl_new:N \l_@@_number_arg_tl -\tl_new:N \l_@@_number_next_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_number_multi_tl} -% For products and quotients, a way of feeding information back. -% \begin{macrocode} -\tl_new:N \l_@@_number_multi_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_number_denominator_tl , -% \l_@@_number_numerator_tl -%} -% When searching for quotients, some more storage is needed. -% \begin{macrocode} -\tl_new:N \l_@@_number_denominator_tl -\tl_new:N \l_@@_number_numerator_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_preprocess:n , -% \@@_number_preprocess:V -%} -% The pre-processor starts with the obvious: the most likely outcome is -% that all of the argument is passed through unchanged. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_preprocess:n #1 { - \@@_number_preprocess_init: - \tl_set:Nn \l_@@_number_arg_tl {#1} - \@@_number_preprocess_product: - \tl_if_empty:NT \l_@@_number_multi_tl - { \@@_number_preprocess_quotient: } -} -\cs_generate_variant:Nn \@@_number_preprocess:n { V } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_preprocess_init:} -% A little initialisation as normal. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_preprocess_init: { - \bool_set_false:N \l_@@_error_bool - \tl_clear:N \l_@@_number_multi_tl -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_preprocess_product:} -%\begin{macro}{\@@_number_preprocess_product_aux:N} -% Rather than search through the entire argument, we use the -% delimited-argument trick. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_preprocess_product: { - \tl_map_function:NN \l_@@_input_product_tl - \@@_number_preprocess_product_aux:N -} -\cs_new_protected:Npn \@@_number_preprocess_product_aux:N #1 { - \tl_if_in:NnT \l_@@_number_arg_tl {#1} - { - \cs_set:Npn \@@_tmp:w ##1 #1 ##2 \q_stop - { - \tl_set:Nn \l_@@_number_arg_tl {##1} - \tl_set:Nn \l_@@_number_next_tl {##2} - \tl_set:Nn \l_@@_number_multi_tl { product } - } - \exp_after:wN \@@_tmp:w \l_@@_number_arg_tl \q_stop - \tl_if_empty:NT \l_@@_number_arg_tl - { \@@_error:n { starting-product-token } } - \tl_if_empty:NT \l_@@_number_next_tl - { \@@_error:n { ending-product-token } } - \tl_map_break: - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_preprocess_quotient:} -%\begin{macro}{\@@_number_preprocess_quotient_aux:N} -% For the quotient, only one token can appear in each part. So there -% is an additional error check. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_preprocess_quotient: { - \tl_map_function:NN \l_@@_input_quotient_tl - \@@_number_preprocess_quotient_aux:N -} -\cs_new_protected:Npn \@@_number_preprocess_quotient_aux:N #1 { - \tl_if_in:NnT \l_@@_number_arg_tl {#1} - { - \cs_set:Npn \@@_tmp:w ##1 #1 ##2 \q_stop - { - \tl_set:Nn \l_@@_number_numerator_tl {##1} - \tl_set:Nn \l_@@_number_denominator_tl {##2} - \tl_set:Nn \l_@@_number_multi_tl { quotient } - } - \exp_after:wN \@@_tmp:w \l_@@_number_arg_tl \q_stop - \tl_if_empty:NT \l_@@_number_numerator_tl - { \@@_error:n { starting-quotient-token } } - \tl_if_empty:NT \l_@@_number_denominator_tl - { \@@_error:n { ending-quotient-token } } - \tl_if_in:NnT \l_@@_number_denominator_tl {#1} - { \@@_error:n { duplicate-quotient-token } } - \tl_map_break: - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Parsing numbers} -% -% The parser is designed to be relativity fast, which means some code is -% more or less duplicated to gain more speed. It is also loaded so -% that simple numbers (such as \num{-1.23}) are parsed particularly -% quickly. For most documents, this gain more than offsets any slight -% losses with more complicated numbers. -% -%\begin{macro}{\c_@@_number_part_complex_tl} -% A couple of the comparisons needed for checking complex numbers -% are done using stored text. To make them a little quicker, a -% pre-stored version of the text is stored here. -% \begin{macrocode} -\tl_const:Nn \c_@@_number_part_complex_tl { complex } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_number_in_complex_bool , -% \l_@@_number_in_complex_root_bool , -% \l_@@_number_in_decimal_bool , -% \l_@@_number_in_exponent_bool , -% \l_@@_number_in_first_bool , -% \l_@@_number_in_sign_bool , -% \l_@@_number_in_uncert_bool , -% \l_@@_number_in_value_bool -%} -% \begin{macrocode} -\bool_new:N \l_@@_number_in_complex_bool -\bool_new:N \l_@@_number_in_complex_root_bool -\bool_new:N \l_@@_number_in_decimal_bool -\bool_new:N \l_@@_number_in_exponent_bool -\bool_new:N \l_@@_number_in_first_bool -\bool_new:N \l_@@_number_in_sign_bool -\bool_new:N \l_@@_number_in_uncert_bool -\bool_new:N \l_@@_number_in_value_bool -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_number_in_prop} -% The parsed number is stored in a property list as its constituent -% parts. -% \begin{macrocode} -\prop_new:N \l_@@_number_in_prop -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_number_parsed_tl} -% Each part of the number parsed has to be built up in a token list. -% \begin{macrocode} -\tl_new:N \l_@@_number_parsed_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_number_part_tl , -% \l_@@_number_part_decimal_tl , -% \l_@@_number_part_decimal_marker_tl , -% \l_@@_number_part_integer_tl , -% \l_@@_number_part_sign_tl , -% \l_@@_number_part_uncert_tl -%} -% The names of various parts of a number are set up as stored values. -% This lets some code be used for different parts of a number, while -% pre-storing everything brings a performance (and clarity) benefit. -% \begin{macrocode} -\tl_new:N \l_@@_number_part_tl -\tl_new:N \l_@@_number_part_decimal_tl -\tl_new:N \l_@@_number_part_decimal_marker_tl -\tl_new:N \l_@@_number_part_integer_tl -\tl_new:N \l_@@_number_part_sign_tl -\tl_new:N \l_@@_number_part_uncert_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_number_mantissa_length_int -% \l_@@_number_uncert_tl -% \l_@@_number_uncert_length_int -%} -% Conversion of uncertainty forms requires some storage, mainly for -% performance reasons. -% \begin{macrocode} -\int_new:N \l_@@_number_mantissa_length_int -\tl_new:N \l_@@_number_uncert_tl -\int_new:N \l_@@_number_uncert_length_int -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_input_uncert_sign_tl} -% This one is stored by some low-level code, so is declared explicitly. -% \begin{macrocode} -\tl_new:N \l_@@_input_uncert_sign_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_input_uncert_close_tl , -% \l_@@_input_complex_tl , -% \l_@@_input_comparator_tl , -% \l_@@_input_decimal_tl , -% \l_@@_input_digit_tl , -% \l_@@_input_exponent_tl , -% \l_@@_input_ignore_tl , -% \l_@@_input_uncert_open_tl , -% \l_@@_input_protect_tl , -% \l_@@_input_sign_tl , -% \l_@@_input_symbol_tl , -% \l_@@_input_uncert_sign_tl -%} -% The various tokens to check against when parsing are all set up here. -% These are valid inside a single number: the pre-processor has already -% set up the appropriate things for products and quotients. -% \begin{macrocode} -\keys_define:nn { siunitx } { - input-close-uncertainty .tl_set:N = \l_@@_input_uncert_close_tl , - input-complex-roots .tl_set:N = \l_@@_input_complex_tl , - input-comparators .tl_set:N = \l_@@_input_comparator_tl , - input-decimal-markers .tl_set:N = \l_@@_input_decimal_tl , - input-digits .tl_set:N = \l_@@_input_digit_tl , - input-exponent-markers .tl_set:N = \l_@@_input_exponent_tl , - input-ignore .tl_set:N = \l_@@_input_ignore_tl , - input-open-uncertainty .tl_set:N = \l_@@_input_uncert_open_tl , - input-protect-tokens .tl_set:N = \l_@@_input_protect_tl , - input-signs .tl_set:N = \l_@@_input_sign_tl , - input-symbols .tl_set:N = \l_@@_input_symbol_tl , - input-uncertainty-signs .code:n = - { - \tl_set:Nn \l_@@_input_uncert_sign_tl {#1} - \tl_map_inline:nn {#1} - { - \tl_if_in:NnF \l_@@_input_sign_tl {##1} - { \tl_put_right:Nn \l_@@_input_sign_tl {##1} } - } - } , -} -\keys_set:nn { siunitx } { % ( - input-close-uncertainty = ), - input-complex-roots = ij, - input-comparators = {<=>\approx\ge\geq\gg\le\leq\ll\sim}, - input-decimal-markers = {.,}, - input-digits = 0123456789, - input-exponent-markers = dDeE, - input-open-uncertainty = (, % ) - input-protect-tokens = \approx\dots\ge\geq\gg\le\leq\ll\mp\pi\pm\sim, - input-signs = +-\mp\pm, - input-symbols = \dots\pi, - input-uncertainty-signs = \pm, -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_in_parse:n , -% \@@_number_in_parse:V -%} -%\begin{macro}{\@@_number_in_parse_aux:n} -% The parsing routine starts by replacing any formatting in the input -% using \cs{tl_set_rescan:Nnx}. Next, there is a quick routine to -% ensure that all signs are single tokens. The main loop then takes -% place, which will parse the input into the property list and also -% set up the flags. There are then some checks and possible corrections. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse:n #1 { - \tl_if_empty:nF {#1} - { - \@@_number_in_init: - \cs_set_eq:NN \@@_number_in_parse_more:N - \@@_number_in_parse_mantissa_aux:N - \@@_number_in_parse_aux:n {#1} - } -} -\cs_generate_variant:Nn \@@_number_in_parse:n { V } -\group_begin: - \char_set_catcode_active:N \~ - \char_set_catcode_space:N \ % - \cs_new_protected:Npn \@@_number_in_parse_aux:n#1% - {% - \group_begin: - \@@_number_in_protect: - \cs_set_eq:NN\,\prg_do_nothing: - \cs_set_eq:NN~\prg_do_nothing: - \tl_set_rescan:Nnx\l_@@_number_arg_tl - {% - \char_set_catcode_ignore:N\ % - \char_set_catcode_other:N\,% - \char_set_catcode_other:N\.% - }% - {#1}% - \exp_args:NNNV\group_end: - \tl_set:Nn\l_@@_number_arg_tl\l_@@_number_arg_tl - \@@_number_in_sign_replace:N\l_@@_number_arg_tl - \@@_number_in_parse_relation:N\l_@@_number_arg_tl - \tl_map_function:NN\l_@@_number_arg_tl - \@@_number_in_parse_loop:N - \tl_if_empty:NF\l_@@_number_parsed_tl - {% - \bool_if:NTF\l_@@_number_in_uncert_bool - {\@@_error:nx{invalid-number}{#1}}% - {% - \prop_put:NVn \l_@@_number_in_prop - \l_@@_number_part_tl {true}% - \bool_if:NTF\l_@@_number_in_decimal_bool - {% - \prop_put:NVV\l_@@_number_in_prop - \l_@@_number_part_decimal_tl - \l_@@_number_parsed_tl - }% - {% - \prop_put:NVV\l_@@_number_in_prop - \l_@@_number_part_integer_tl - \l_@@_number_parsed_tl - }% - }% - }% - \@@_number_in_check:n {#1}% - } -\group_end: -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_in_init: , -% \@@_number_in_init_part:n -%} -% The set up code is divided into to parts. First, code only needed -% once to start the entire parser. Then a second group, which is -% carried out at the start of each part of a number, and so is called -% from a few places. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_init: { - \cs_set_eq:NN \@@_number_in_parse_loop:N - \@@_number_in_parse_mantissa:N - \cs_set_eq:NN \@@_number_in_check:n - \@@_number_in_check_short:n - \tl_clear:N \l_@@_number_parsed_tl - \prop_clear:N \l_@@_number_in_prop - \bool_set_false:N \l_@@_error_bool - \bool_set_false:N \l_@@_number_in_complex_bool - \bool_set_false:N \l_@@_number_in_complex_root_bool - \bool_set_false:N \l_@@_number_in_exponent_bool - \bool_set_false:N \l_@@_number_in_uncert_bool - \@@_number_in_init_part:n { mantissa } -} -\cs_new_protected:Npn \@@_number_in_init_part:n #1 { - \bool_set_false:N \l_@@_number_in_decimal_bool - \bool_set_true:N \l_@@_number_in_first_bool - \bool_set_false:N \l_@@_number_in_sign_bool - \bool_set_false:N \l_@@_number_in_value_bool - \tl_set:Nn \l_@@_number_part_tl {#1} - \tl_set:Nn \l_@@_number_part_decimal_tl { #1 -decimal } - \tl_set:Nn \l_@@_number_part_decimal_marker_tl - { #1 -decimal-marker } - \tl_set:Nn \l_@@_number_part_integer_tl { #1 -integer } - \tl_set:Nn \l_@@_number_part_sign_tl { #1 -sign } - \tl_set:Nn \l_@@_number_part_uncert_tl { #1 -uncertainty } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_in_protect:} -%\begin{macro}{\@@_number_in_protect_aux:N} -% Under some circumstances (for example when loading \pkg{breqn}) -% some tokens do not behave safely under \texttt{x} expansion (at the -% moment). To get round this, they are redefined here. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_protect: { - \tl_map_function:NN \l_@@_input_protect_tl - \@@_number_in_protect_aux:N -} -\cs_new_protected:Npn \@@_number_in_protect_aux:N #1 { - \cs_set_eq:NN #1 \scan_stop: -} -% \end{macrocode} -%\end{macro} -%\end{macro} +% \subsection{Top-level scratch space} % -% \begin{macro}[int]{\@@_number_in_sign_replace:N} -% \begin{macro}{\@@_number_in_sign_replace_aux:N} -% \begin{macro}{\@@_number_in_sign_replace_aux:NnN} -% A short spin-out to keep the replacement of tokens clear. -% The case where |-| is active needs special treatment and -% needs to come first. +% \begin{macro}{\l_@@_tmp_tl} +% Scratch space for the interfaces. % \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_sign_replace:N #1 - { - \@@_number_in_sign_replace_aux:N #1 - \@@_number_in_sign_replace_aux:NnN #1 - { -+ } \mp - { +- } \pm - { << } \ll - { <= } \le - { >> } \gg - { >= } \ge - { ?? } \q_recursion_tail - \q_recursion_stop - } -\group_begin: - \char_set_catcode_active:N - - \cs_new_protected:Npx \_@@_number_in_sign_replace_aux:N #1 - { \tl_replace_all:Nnn #1 { \exp_not:N - } { \token_to_str:N - } } -\group_end: -\cs_new_protected:Npn \@@_number_in_sign_replace_aux:NnN #1#2#3 - { - \quark_if_recursion_tail_stop:N #3 - \tl_replace_all:Nnn #1 {#2} {#3} - \@@_number_in_sign_replace_aux:NnN #1 - } +\tl_new:N \l_@@_tmp_tl % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} % -%\begin{macro}{ -% \@@_number_in_parse_error:nn , -% \@@_number_in_parse_error:nV -%} -% There are lots of rather similar errors in the parser, all of which -% require a \cs{tl_map_break:}. To keep life simple, this is set up -% here. % \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse_error:nn #1#2 { - \@@_error:nx {#1} { \exp_not:n {#2} } - \tl_map_break: -} -\cs_generate_variant:Nn \@@_number_in_parse_error:nn { nV } +%</init> % \end{macrocode} -%\end{macro} % -%\begin{macro}{ -% \@@_number_in_parse_loop:N , -% \@@_number_in_parse_more:N -%} -% The main loop is set up as a place holder, as the definition is -% varied to keep things fast. There is also a place holder for the -% extended routing for normal mantissas. % \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse_loop:N #1 { } -\cs_new_protected:Npn \@@_number_in_parse_more:N #1 { } +%<*options> % \end{macrocode} -%\end{macro} % -%\begin{macro}{\@@_number_in_parse_relation:N} -%\begin{macro}{\@@_number_in_parse_relation:w} -% The idea here is that a relation with be the very first token in the -% input, or it is not valid. So the test for a relation can be very -% simple and hopefully efficient. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse_relation:N #1 { - \exp_after:wN \@@_number_in_parse_relation:w #1 \q_stop #1 -} -\cs_new_protected:Npn \@@_number_in_parse_relation:w - #1#2 \q_stop #3 { - \tl_if_in:NnT \l_@@_input_comparator_tl {#1} - { - \prop_put:Nnn \l_@@_number_in_prop { comparator } {#1} - \tl_set:Nn #3 {#2} - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_in_parse_restricted:N} -% When parsing numbers for the \cs{ang} function, no extended input -% is permitted at all. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse_restricted:N #1 { - \tl_if_in:NnTF \l_@@_input_exponent_tl {#1} - { - \@@_number_in_parse_error:nn - { restricted-number } {#1} - } - { - \tl_if_in:NnTF \l_@@_input_uncert_open_tl {#1} - { - \@@_number_in_parse_error:nV - { restricted-number } \l_@@_number_arg_tl - } - { - \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#1} - { - \@@_number_in_parse_error:nV - { restricted-number } \l_@@_number_arg_tl - } - { - \tl_if_in:NnTF \l_@@_input_complex_tl {#1} - { - \@@_number_in_parse_error:nV - { restricted-number } \l_@@_number_arg_tl - } - { - \@@_number_in_parse_error:nn - { restricted-number } {#1} - } - } - } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_in_parse_complex:N} -% After a complex root when the root is \emph{after} the number, there -% are a very limited range of legitimate tokens. Thus most cases can be -% trapped with a modified parser. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse_complex:N #1 { - \tl_if_in:NnTF \l_@@_input_exponent_tl {#1} - { - \cs_set_eq:NN \@@_number_in_parse_loop:N - \@@_number_in_parse_mantissa:N - \@@_number_in_exponent:N #1 - } - { - \tl_if_in:NnF \l_@@_input_ignore_tl {#1} - { - \@@_number_in_parse_error:nV - { misplaced-complex-root-token } - \l_@@_number_arg_tl - } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_in_parse_exponent:N} -% When processing an exponent, the \enquote{extended} part of the -% number which is valid in a mantissa is no longer needed. So the -% auxiliary function is pointed to a series of errors instead. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse_exponent:N #1 { - \tl_if_in:NnTF \l_@@_input_exponent_tl {#1} - { - \@@_number_in_parse_error:nn - { duplicate-exponent-token } { \token_to_str:N #1 } - } - { - \tl_if_in:NnTF \l_@@_input_uncert_open_tl {#1} - { - \@@_number_in_parse_error:nV - { invalid-token-in-exponent } \l_@@_number_arg_tl - } - { - \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#1} - { - \@@_number_in_parse_error:nV - { invalid-token-in-exponent } \l_@@_number_arg_tl - } - { - \tl_if_in:NnTF \l_@@_input_complex_tl {#1} - { - \@@_number_in_parse_error:nV - { invalid-token-in-exponent } - \l_@@_number_arg_tl - } - { - \@@_number_in_parse_error:nn - { invalid-token-in-number } {#1} - } - } - } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_in_parse_mantissa:N} -%\begin{macro}{\@@_number_in_parse_mantissa_aux:N} -% For the mantissa, most things are valid. The procedure is split -% into two parts, with the simple symbols handled here and the more -% complex ones in a second part(which needs to be varied). Essentially -% everything here is a comparison, done so that the code is a fast as -% possible. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse_mantissa:N #1 { - \tl_if_in:NnTF \l_@@_input_digit_tl {#1} - { \@@_number_in_digit:n {#1} } - { - \tl_if_in:NnTF \l_@@_input_decimal_tl {#1} - { \@@_number_in_decimal:N #1 } - { - \tl_if_in:NnTF \l_@@_input_sign_tl {#1} - { \@@_number_in_sign:N #1 } - { - \tl_if_in:NnTF \l_@@_input_symbol_tl {#1} - { - \prop_put:Nnn \l_@@_number_in_prop { symbolic } - { true } - \@@_number_in_digit:n {#1} - } - { - \tl_if_in:NnF \l_@@_input_ignore_tl {#1} - { \@@_number_in_parse_more:N #1 } - } - } - } - } -} -\cs_new_protected:Npn \@@_number_in_parse_mantissa_aux:N #1 { - \tl_if_in:NnTF \l_@@_input_exponent_tl {#1} - { \@@_number_in_exponent:N #1 } - { - \tl_if_in:NnTF \l_@@_input_uncert_open_tl {#1} - { \@@_number_in_uncert_open:N #1 } - { - \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#1} - { - \@@_number_in_parse_error:nn - { misplaced-uncertainty-token } {#1} - } - { - \tl_if_in:NnTF \l_@@_input_complex_tl {#1} - { \@@_number_in_complex:N #1 } - { - \@@_number_in_parse_error:nn - { invalid-token-in-number } {#1} - } - } - } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_in_parse_uncert:N} -% Within uncertainties, the range of tokens is limited. An alternative -% parsing system can therefore be used. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse_uncert:N #1 { - \tl_if_in:NnTF \l_@@_input_digit_tl {#1} - { \@@_number_in_digit:n {#1} } - { - \tl_if_in:NnTF \l_@@_input_decimal_tl {#1} - { - \@@_number_in_parse_error:nV - { invalid-token-in-uncertainty } - \l_@@_number_arg_tl - } - { - \tl_if_in:NnTF \l_@@_input_sign_tl {#1} - { - \@@_number_in_parse_error:nV - { invalid-token-in-uncertainty } - \l_@@_number_arg_tl - } - { - \tl_if_in:NnTF \l_@@_input_symbol_tl {#1} - { - \prop_put:Nnn \l_@@_number_in_prop { symbolic } - { true } - \@@_number_in_digit:n {#1} - } - { - \tl_if_in:NnF \l_@@_input_ignore_tl {#1} - { - \tl_if_in:NnTF \l_@@_input_uncert_close_tl - {#1} - { \@@_number_in_uncert_close:N #1 } - { - \@@_number_in_parse_error:nV - { invalid-token-in-uncertainty } - \l_@@_number_arg_tl - } - } - } - } - } - } -} -% \end{macrocode} -%\end{macro} +% \subsection{Load time options} % -%\begin{macro}{\@@_number_in_parse_uncert_after:N} -% After an uncertainty, there is once again a very limited range of -% tokens that can be present in a valid number. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_parse_uncert_after:N #1 { - \tl_if_in:NnTF \l_@@_input_exponent_tl {#1} - { - \cs_set_eq:NN \@@_number_in_parse_loop:N - \@@_number_in_parse_mantissa:N - \@@_number_in_exponent:N #1 - } - { - \tl_if_in:NnTF \l_@@_input_sign_tl {#1} - { - \cs_set_eq:NN \@@_number_in_parse_loop:N - \@@_number_in_parse_mantissa:N - \@@_number_in_sign:N #1 - } - { - \tl_if_in:NnF \l_@@_input_ignore_tl {#1} - { - \tl_if_in:NnTF \l_@@_input_complex_tl {#1} - { - \cs_set_eq:NN \@@_number_in_parse_loop:N - \@@_number_in_parse_mantissa:N - \@@_number_in_complex:N #1 - } - { - \@@_number_in_parse_error:nV { invalid-number } - \l_@@_number_arg_tl - } - } - } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_in_complex:N} -%\begin{macro}{\@@_number_in_complex_aux:nn} -% Only one complex root token can be give, hence the initial test. -% More tests are needed for complex numbers than other systems, so -% the additional ones are turned on, followed by some flag setting. -% The complex root is stored, then there is a check to see if the -% root is at the end of the number: if it is, prevent any more tokens -% being added. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_complex:N #1 { - \bool_set_false:N \l_@@_number_in_first_bool - \bool_if:NTF \l_@@_number_in_complex_root_bool - { - \@@_number_in_parse_error:nn - { duplicate-complex-root-token } { \token_to_str:N #1 } - } - { - \cs_set_eq:NN \@@_number_in_check:n - \@@_number_in_check_full:n - \bool_set_true:N \l_@@_number_in_complex_root_bool - \prop_put:Nnn \l_@@_number_in_prop { complex-root } {#1} - \tl_if_empty:NF \l_@@_number_parsed_tl - { - \cs_set_eq:NN \@@_number_in_parse_loop:N - \@@_number_in_parse_complex:N - } - \bool_if:NT \l_@@_number_in_decimal_bool - { - \bool_if:NF \l_@@_number_in_complex_bool - { - \prop_if_in:NnT \l_@@_number_in_prop - { mantissa-uncertainty } - { - \@@_number_in_complex_aux:nn - { mantissa-decimal } { complex-decimal } - \@@_number_in_complex_aux:nn - { mantissa-uncertainty } { complex-uncertainty } - } - \@@_number_in_complex_aux:nn { mantissa-integer } - { complex-integer } - \@@_number_in_complex_aux:nn - { mantissa-decimal-marker } { complex-decimal-marker } - \prop_remove:Nn \l_@@_number_in_prop { mantissa } - \prop_put:Nnn \l_@@_number_in_prop { complex } - { true } - } - } - \prop_if_in:NnF \l_@@_number_in_prop { mantissa } - { - \prop_if_in:NnT \l_@@_number_in_prop { mantissa-sign } - { - \@@_number_in_complex_aux:nn { mantissa-sign } - { complex-sign } - } - } - \bool_set_true:N \l_@@_number_in_complex_bool - \bool_set_false:N \l_@@_number_in_first_bool - \@@_number_in_init_part:n { complex } - \prop_if_in:NnT \l_@@_number_in_prop - { complex-decimal-marker } - { \bool_set_true:N \l_@@_number_in_decimal_bool } - \prop_if_in:NnTF \l_@@_number_in_prop - { complex-sign } - { \bool_set_true:N \l_@@_number_in_sign_bool } - { \prop_remove:Nn \l_@@_number_in_prop { mantissa } } - } -} -\cs_new_protected:Npn \@@_number_in_complex_aux:nn #1#2 { - \prop_get:NnNT \l_@@_number_in_prop {#1} \l_@@_tmpa_tl - { - \prop_remove:Nn \l_@@_number_in_prop {#1} - \prop_put:NnV \l_@@_number_in_prop {#2} \l_@@_tmpa_tl - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_in_decimal:N} -% Only one decimal marker allowed, so a test for this. If an integer -% part has been found, it is saved. The flag for the number being -% found is not set unless there is an integer, to watch for the case -% of invalid numbers. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_decimal:N #1 { - \bool_set_false:N \l_@@_number_in_first_bool - \bool_if:NTF \l_@@_number_in_decimal_bool - { - \@@_number_in_parse_error:nn { duplicate-decimal-token } - {#1} - } - { - \bool_set_true:N \l_@@_number_in_decimal_bool - \tl_if_empty:NF \l_@@_number_parsed_tl - { - \prop_put:NVn \l_@@_number_in_prop - \l_@@_number_part_tl { true } - \prop_put:NVV \l_@@_number_in_prop - \l_@@_number_part_integer_tl - \l_@@_number_parsed_tl - \tl_clear:N \l_@@_number_parsed_tl - } - \prop_put:NVn \l_@@_number_in_prop - \l_@@_number_part_decimal_marker_tl {#1} - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_in_digit:n} -% For digits, only in an uncertainty can the value be stored -% directly. Otherwise, there is a need to see if the value is non-zero. -% This is used to drop leading zeros and to validate any sign (as zero -% is unsigned). -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_digit:n #1 { - \bool_set_false:N \l_@@_number_in_first_bool - \bool_if:NTF \l_@@_number_in_uncert_bool - { \tl_put_right:Nn \l_@@_number_parsed_tl {#1} } - { - \bool_if:NTF \l_@@_number_in_decimal_bool - { - \tl_put_right:Nn \l_@@_number_parsed_tl {#1} - \str_if_eq:nnF {#1} { 0 } - { \bool_set_true:N \l_@@_number_in_value_bool } - } - { - \str_if_eq:nnTF {#1} { 0 } - { - \prop_put:NVn \l_@@_number_in_prop - \l_@@_number_part_tl { true } - \prop_put:NVn \l_@@_number_in_prop - \l_@@_number_part_integer_tl { 0 } - } - { \bool_set_true:N \l_@@_number_in_value_bool } - \bool_if:NT \l_@@_number_in_value_bool - { \tl_put_right:Nn \l_@@_number_parsed_tl {#1} } - } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_in_exponent:N} -% A duplicate token test starts off the code, which if passed -% leads to some simple storage manipulation. As exponents are -% more simple than the mantissa, the extra processing is swapped for -% some that only raises errors. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_exponent:N #1 { - \bool_if:NTF \l_@@_number_in_exponent_bool - { - \@@_number_in_parse_error:nn { duplicate-exponent-token } - { \token_to_str:N #1 } - } - { - \cs_set_eq:NN \@@_number_in_parse_more:N - \@@_number_in_parse_exponent:N - \tl_if_empty:NF \l_@@_number_parsed_tl - { \@@_number_in_store: } - \bool_set_true:N \l_@@_number_in_exponent_bool - \@@_number_in_init_part:n { exponent } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_in_sign:N} -% The code for signs is complicated by complex numbers. A sign token -% must be the fist thing in a number, but after the real part of the -% mantissa a second sign token can appear to start a complex number. -% So most of the code here is to detect that case. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_sign:N #1 { - \bool_if:NTF \l_@@_number_in_first_bool - { - \bool_set_false:N \l_@@_number_in_first_bool - \bool_set_true:N \l_@@_number_in_sign_bool - \prop_put:NVn \l_@@_number_in_prop - \l_@@_number_part_sign_tl {#1} - } - { - \bool_if:NTF \l_@@_number_in_exponent_bool - { - \@@_number_in_parse_error:nn { misplaced-sign-token } - {#1} - } - { - \bool_if:NTF \l_@@_number_in_complex_bool - { - \@@_number_in_parse_error:nn - { misplaced-sign-token } {#1} - } - { - \tl_if_empty:NF \l_@@_number_parsed_tl - { \@@_number_in_store: } - \cs_set_eq:NN \@@_number_in_check:n - \@@_number_in_check_full:n - \@@_number_in_init_part:n { complex } - \prop_put:Nnn \l_@@_number_in_prop - { complex-sign } {#1} - \bool_set_true:N \l_@@_number_in_complex_bool - } - } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_in_uncert_open:N , -% \@@_number_in_uncert_close:N -%} -% Opening and closing uncertainty tokens are handled separately. For -% opening tokens, a check is made that there is something else to the -% number before collecting material up. For the closing token, the -% uncertainty must contain some numbers. A special loop function is then -% set up to prevent any additional digits after the closing token. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_uncert_open:N #1 { - \bool_set_false:N \l_@@_number_in_first_bool - \cs_set_eq:NN \@@_number_in_parse_loop:N - \@@_number_in_parse_uncert:N - \bool_set_true:N \l_@@_number_in_uncert_bool - \tl_if_empty:NTF \l_@@_number_parsed_tl - { - \prop_if_in:NVF \l_@@_number_in_prop - \l_@@_number_part_integer_tl - { - \@@_number_in_parse_error:nV { invalid-number } - \l_@@_number_arg_tl - } - } - { \@@_number_in_store: } -} -\cs_new_protected:Npn \@@_number_in_uncert_close:N #1 { - \bool_set_false:N \l_@@_number_in_uncert_bool - \tl_if_empty:NTF \l_@@_number_parsed_tl - { - \@@_number_in_parse_error:nV { empty-uncertainty } - \l_@@_number_arg_tl - } - { - \prop_put:NVV \l_@@_number_in_prop - \l_@@_number_part_uncert_tl \l_@@_number_parsed_tl - \prop_put:Nnn \l_@@_number_in_prop - { uncertainty } { true } - \tl_clear:N \l_@@_number_parsed_tl - \cs_set_eq:NN \@@_number_in_parse_loop:N - \@@_number_in_parse_uncert_after:N - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_in_store:} -% A short auxiliary function needed in various places for storing -% either the integer or decimal part of a number, as appropriate. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_store: { - \prop_put:NVn \l_@@_number_in_prop \l_@@_number_part_tl - { true } - \bool_if:NTF \l_@@_number_in_decimal_bool - { - \prop_put:NVV \l_@@_number_in_prop - \l_@@_number_part_decimal_tl \l_@@_number_parsed_tl - } - { - \prop_put:NVV \l_@@_number_in_prop - \l_@@_number_part_integer_tl \l_@@_number_parsed_tl - } - \tl_clear:N \l_@@_number_parsed_tl -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_in_check:n , -% \@@_number_in_check_short:n , -% \@@_number_in_check_full:n -%} -% The checks needed for a number depend on whether there is a complex -% part. In all cases, there must be some digits, as well as a sign or -% decimal marker. There is also a check for a zero-valued input, which -% has any sign deleted. For complex numbers, the check is needed in -% case there was no real part. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_check:n #1 { } -\cs_new_protected:Npn \@@_number_in_check_short:n #1 { - \prop_if_in:NVF \l_@@_number_in_prop - \l_@@_number_part_integer_tl - { - \prop_if_in:NVF \l_@@_number_in_prop - \l_@@_number_part_decimal_tl - { \@@_error:nx { invalid-number } {#1} } - } - \bool_if:NF \l_@@_number_in_value_bool - { - \tl_if_eq:NNF \l_@@_number_part_tl - \c_@@_number_part_complex_tl - { - \prop_get:NVNT \l_@@_number_in_prop - \l_@@_number_part_sign_tl \l_@@_tmpa_tl - { - \tl_set:Nx \l_@@_tmpb_tl - { \l_@@_number_part_sign_tl -deleted } - \prop_put:NVV \l_@@_number_in_prop - \l_@@_tmpb_tl \l_@@_tmpa_tl - } - \prop_remove:NV \l_@@_number_in_prop - \l_@@_number_part_sign_tl - } - } -} -\cs_new_protected:Npn \@@_number_in_check_full:n #1 { - \tl_if_eq:NNF \l_@@_number_part_tl - \c_@@_number_part_complex_tl - { \@@_number_in_check_short:n {#1} } - \bool_if:NF \l_@@_number_in_complex_root_bool - { - \prop_get:NnN \l_@@_number_in_prop { complex-sign } - \l_@@_tmpa_tl - \tl_if_in:NVTF \l_@@_input_uncert_sign_tl \l_@@_tmpa_tl - { - \prop_if_in:NnTF \l_@@_number_in_prop { uncertainty } - { - \@@_error:nx { misplaced-sign-token } - { \exp_not:n {#1} } - } - { \@@_number_in_complex_to_uncert:n {#1} } - } - { - \@@_error:nx { misplaced-sign-token } - { \exp_not:n {#1} } - } - } - \prop_get:NnNT \l_@@_number_in_prop { mantissa-sign } - \l_@@_tmpa_tl - { - \prop_if_in:NnF \l_@@_number_in_prop { mantissa } - { - \prop_remove:Nn \l_@@_number_in_prop { mantissa-sign } - \prop_put:NnV \l_@@_number_in_prop { complex-sign } - \l_@@_tmpa_tl - } - } -} -% \end{macrocode} -%\end{macro} -% -% -%\begin{macro}{\@@_number_in_complex_to_uncert:n} -%\begin{macro}{ -% \@@_number_in_complex_to_uncert_int: , -% \@@_number_in_complex_to_uncert_dec: -%} -% Internally, uncertainties are stored in \enquote{compact} form. -% The code here takes a putative complex part and converts it to -% a compact uncertainty, with checks for the cases where things look -% wrong. The method needed depends on whether there is an integer -% part. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_complex_to_uncert:n #1 { - \prop_remove:Nn \l_@@_number_in_prop { complex } - \prop_remove:Nn \l_@@_number_in_prop { complex-decimal-marker } - \prop_remove:Nn \l_@@_number_in_prop { complex-sign } - \prop_put:Nnn \l_@@_number_in_prop { uncertainty } { true } - \prop_get:NnNTF \l_@@_number_in_prop { complex-integer } - \l_@@_number_uncert_tl - { - \tl_if_single:NTF \l_@@_number_uncert_tl - { - \int_compare:nNnTF \l_@@_number_uncert_tl = 0 - { \@@_number_in_complex_to_uncert_dec:n {#1} } - { \@@_number_in_complex_to_uncert_int: } - } - { \@@_number_in_complex_to_uncert_int: } - } - { \@@_number_in_complex_to_uncert_dec:n {#1} } - \prop_remove:Nn \l_@@_number_in_prop { complex-integer } - \prop_remove:Nn \l_@@_number_in_prop { complex-decimal } -} -% \end{macrocode} -% When the input has an integer part to the uncertainty, the -% conversion is easy as all of the decimal part can be copied -% across. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_complex_to_uncert_int: { - \prop_get:NnNF \l_@@_number_in_prop { complex-decimal } - \l_@@_tmpa_tl - { \tl_clear:N \l_@@_tmpa_tl } - \prop_get:NnNF \l_@@_number_in_prop { mantissa-decimal } - \l_@@_tmpb_tl - { \tl_clear:N \l_@@_tmpb_tl } - \@@_number_in_complex_to_uncert_pad: -} -% \end{macrocode} -% For a number in which all of the uncertainty is in the decimal part, -% only the significant digits are needed. This means that a loop is -% needed to drop non-significant ones. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_complex_to_uncert_dec:n - #1 - { - \tl_clear:N \l_@@_number_uncert_tl - \prop_get:NnNTF \l_@@_number_in_prop { complex-decimal } - \l_@@_tmpa_tl - { - \prop_get:NnN \l_@@_number_in_prop { mantissa-decimal } - \l_@@_tmpb_tl - \quark_if_no_value:NT \l_@@_tmpb_tl - { \tl_clear:N \l_@@_tmpb_tl } - \tl_map_function:NN - \l_@@_tmpa_tl - \@@_number_in_complex_to_uncert_dec_loop:N - \@@_number_in_complex_to_uncert_pad: - } - { \@@_error:nx { misplaced-sign-token } { \exp_not:n {#1} } } - } -\cs_new_protected:Npn - \@@_number_in_complex_to_uncert_dec_loop:N #1 +% \begin{variable}{\l_@@_column_type_tl} +% \begin{macrocode} +\keys_define:nn { siunitx } { - \str_if_eq:nnTF {#1} { 0 } - { - \tl_set:Nx \l_@@_tmpa_tl - { \tl_tail:N \l_@@_tmpa_tl } - \tl_if_empty:NF \l_@@_tmpb_tl - { - \tl_set:Nx \l_@@_tmpb_tl - { \tl_tail:N \l_@@_tmpb_tl } - } - } - { \tl_map_break: } + table-column-type .tl_set:N = + \l_@@_column_type_tl } -% \end{macrocode} -% In all cases, there is a need to pad out either the uncertainty or -% the decimal part so the places agree. To allow the two branches to -% share code, some of the order here is slightly odd. The code -% also re-obtains the decimal part from the mantissa, as the stored -% value may have been trimmed to drop non-significant zeros. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_in_complex_to_uncert_pad: +\keys_set:nn { siunitx } { - \int_set:Nn \l_@@_number_uncert_length_int - { \tl_count:N \l_@@_tmpa_tl } - \int_set:Nn \l_@@_number_mantissa_length_int - { \tl_count:N \l_@@_tmpb_tl } - \int_compare:nNnTF - { \l_@@_number_mantissa_length_int } - > { \l_@@_number_uncert_length_int } - { - \tl_set:Nx \l_@@_tmpa_tl - { - \exp_not:V \l_@@_tmpa_tl - \prg_replicate:nn - { - \l_@@_number_mantissa_length_int - - \l_@@_number_uncert_length_int - } - { 0 } - } - } - { - \prop_get:NnNF \l_@@_number_in_prop { mantissa-decimal } - \l_@@_tmpb_tl - { \tl_clear:N \l_@@_tmpb_tl } - \tl_set:Nx \l_@@_tmpb_tl - { - \exp_not:V \l_@@_tmpb_tl - \prg_replicate:nn - { - \l_@@_number_uncert_length_int - - \l_@@_number_mantissa_length_int - } - { 0 } - } - \tl_if_empty:NF \l_@@_tmpb_tl - { - \prop_put:NnV \l_@@_number_in_prop { mantissa-decimal } - \l_@@_tmpb_tl - \prop_if_in:NnF \l_@@_number_in_prop - { mantissa-decimal-marker } - { - \prop_put:Nnn \l_@@_number_in_prop - { mantissa-decimal-marker } { . } - } - } - } - \tl_put_right:NV \l_@@_number_uncert_tl \l_@@_tmpa_tl - \prop_put:NnV \l_@@_number_in_prop { mantissa-uncertainty } - \l_@@_number_uncert_tl + table-column-type = S } % \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Post-processing numbers} -% -% After finding the basic number in the code above, there may be some -% manipulation to do. This covers things such as tidying up excess -% information and rounding numbers. Nothing is added here that is -% for \enquote{formatting}: this is left for the output part of the -% system. -% -% \begin{variable} -% { -% \l_@@_round_int , -% \l_@@_round_tl , -% \l_@@_round_bool , -% \l_@@_round_decimal_in_tl , -% \l_@@_round_decimal_out_tl , -% \l_@@_round_discard_tl , -% \l_@@_round_even_bool , -% \l_@@_round_integer_in_tl , -% \l_@@_round_integer_out_tl , -% \l_@@_round_half_up_bool -% } -% The rounding system needs a number of variables. -% \begin{macrocode} -\int_new:N \l_@@_round_int -\tl_new:N \l_@@_round_tl -\bool_new:N \l_@@_round_bool -\tl_new:N \l_@@_round_decimal_in_tl -\tl_new:N \l_@@_round_decimal_out_tl -\tl_new:N \l_@@_round_discard_tl -\tl_new:N \l_@@_round_even_bool -\tl_new:N \l_@@_round_integer_in_tl -\tl_new:N \l_@@_round_integer_out_tl -\bool_new:N \l_@@_round_half_up_bool -% \end{macrocode} % \end{variable} % -%\begin{macro}{ -% \l_@@_process_decimal_int , -% \l_@@_process_uncertainty_int , -% \l_@@_uncertainty_decimal_tl , -% \l_@@_uncertainty_integer_tl -%} -% The code to expand uncertainties needs to know numbers of digits, and -% to store various data. -% \begin{macrocode} -\int_new:N \l_@@_process_decimal_int -\int_new:N \l_@@_process_uncertainty_int -\tl_new:N \l_@@_uncertainty_decimal_tl -\tl_new:N \l_@@_uncertainty_integer_tl -% \end{macrocode} -%\end{macro} +% \subsection{Option handling} % -%\begin{macro}{ -% \l_@@_process_fixed_bool , -% \l_@@_process_engineering_bool , -% \l_@@_process_scientific_bool -%} -% Settings for the scientific notation system. -% \begin{macrocode} -\bool_new:N \l_@@_process_fixed_bool -\bool_new:N \l_@@_process_engineering_bool -\bool_new:N \l_@@_process_scientific_bool +% \begin{macrocode} +\RequirePackage { l3keys2e } % \end{macrocode} -%\end{macro} % -% \begin{variable}{\l_@@_process_drop_exponent_bool} -% Used to drop the exponent when this is necessary. -% \begin{macrocode} -\bool_new:N \l_@@_process_drop_exponent_bool +% \begin{macrocode} +\ProcessKeysOptions { siunitx } % \end{macrocode} -% \end{variable} % -% \begin{variable} -% { -% \l_@@_process_decimal_zero_bool , -% \l_@@_process_integer_zero_bool , -% \l_@@_process_sign_tl , -% \l_@@_process_fixed_int , -% \l_@@_process_integer_min_int , -% \l_@@_process_plus_bool , -% \l_@@_omit_uncert_bool , -% \l_@@_process_unity_mantissa_tl , -% \l_@@_process_zero_exponent_bool , -% \l_@@_process_int_to_dec_bool , -% \l_@@_process_round_min_tl , -% \l_@@_process_precision_int , -% \l_@@_zero_decimal_to_integer_bool -% } -% First, the options are set up. % \begin{macrocode} -\keys_define:nn { siunitx } - { - add-decimal-zero .bool_set:N = \l_@@_process_decimal_zero_bool, - add-integer-zero .bool_set:N = \l_@@_process_integer_zero_bool, - explicit-sign .tl_set:N = \l_@@_process_sign_tl, - fixed-exponent .int_set:N = \l_@@_process_fixed_int, - minimum-integer-digits .int_set:N = - \l_@@_process_integer_min_int, - retain-explicit-plus .bool_set:N = \l_@@_process_plus_bool, - omit-uncertainty .bool_set:N = \l_@@_omit_uncert_bool, - retain-unity-mantissa .bool_set:N = - \l_@@_process_unity_mantissa_bool, - retain-zero-exponent .bool_set:N = - \l_@@_process_zero_exponent_bool, - round-half .choice:, - round-half / even .code:n = - { \bool_set_false:N \l_@@_round_half_up_bool }, - round-half / up .code:n = - { \bool_set_true:N \l_@@_round_half_up_bool }, - round-integer-to-decimal .bool_set:N = - \l_@@_process_int_to_dec_bool, - round-minimum .tl_set:N = \l_@@_process_round_min_tl, - round-mode .choice: , - round-mode / figures .code:n = - { \tl_set:Nn \l_@@_round_tl { figures } }, - round-mode / off .code:n = { \tl_clear:N \l_@@_round_tl }, - round-mode / places .code:n = - { \tl_set:Nn \l_@@_round_tl { places } }, - round-precision .int_set:N = \l_@@_process_precision_int, - scientific-notation .choice: , - scientific-notation - / false .code:n = - { - \bool_set_false:N \l_@@_process_fixed_bool - \bool_set_false:N \l_@@_process_engineering_bool - \bool_set_false:N \l_@@_process_scientific_bool - }, - scientific-notation - / engineering .code:n = - { - \bool_set_false:N \l_@@_process_fixed_bool - \bool_set_true:N \l_@@_process_engineering_bool - \bool_set_true:N \l_@@_process_scientific_bool - }, - scientific-notation - / fixed .code:n = - { - \bool_set_true:N \l_@@_process_fixed_bool - \bool_set_false:N \l_@@_process_engineering_bool - \bool_set_false:N \l_@@_process_scientific_bool - }, - scientific-notation - / true .code:n = - { - \bool_set_false:N \l_@@_process_fixed_bool - \bool_set_false:N \l_@@_process_engineering_bool - \bool_set_true:N \l_@@_process_scientific_bool - }, - zero-decimal-to-integer .bool_set:N = - \l_@@_zero_decimal_to_integer_bool - } -\keys_set:nn { siunitx } - { - add-decimal-zero = true, - add-integer-zero = true, - retain-unity-mantissa = true, - round-half = up, - round-minimum = 0, - round-precision = 2 - } +%</options> % \end{macrocode} -% \end{variable} % -% \begin{macro}{\@@_number_process:} -% Post-processing is a series of small tasks. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process: - { - \@@_number_process_sign: - \@@_number_process_zero_fill: - \@@_number_process_mantissa: - \prop_if_in:NnF \l_@@_number_in_prop { symbolic } - { - \bool_if:NTF \l_@@_process_fixed_bool - { \@@_number_process_fixed: } - { - \bool_if:NT \l_@@_process_scientific_bool - { \@@_number_process_scientific: } - } - \@@_number_process_exponent: - \@@_number_process_uncertainty: - \bool_if:NT \l_@@_exp_to_prefix_bool - { - \tl_if_empty:NF \l_@@_unit_tl - { \@@_number_exp_to_prefix: } - } - \prop_if_in:NnTF \l_@@_number_in_prop { uncertainty } - { - \bool_if:NT \l_@@_omit_uncert_bool - { - \prop_remove:Nn \l_@@_number_in_prop { uncertainty } - \prop_remove:Nn \l_@@_number_in_prop { mantissa-uncertainty } - } - } - { \@@_number_process_round: } - } - \@@_number_process_zero_to_integer: - \@@_number_process_integer_digits: - \bool_if:NT \l_@@_process_drop_exponent_bool - { - \prop_remove:Nn \l_@@_number_in_prop { exponent } - \prop_remove:Nn \l_@@_number_in_prop { exponent-integer } - } - } -% \end{macrocode} -% \end{macro} +% \subsection{User interfaces} % -%\begin{macro}{\@@_number_process_exponent:} -%\begin{macro}{\@@_number_process_exponent_aux:n} -% To check for a totally zero exponent, the possibility that one or more -% of the exponent storage areas is zero needs to be considered. % \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_exponent: { - \bool_if:NF \l_@@_process_zero_exponent_bool - { - \prop_if_in:NnT \l_@@_number_in_prop { exponent } - { - \bool_set_false:N \l_@@_tmp_bool - \@@_number_process_exponent_aux:n { integer } - \bool_if:NF \l_@@_tmp_bool - { \@@_number_process_exponent_aux:n { decimal } } - \bool_if:NF \l_@@_tmp_bool - { - \prop_remove:Nn \l_@@_number_in_prop { exponent } - \prop_remove:Nn \l_@@_number_in_prop - { exponent-integer } - \prop_remove:Nn \l_@@_number_in_prop - { exponent-decimal } - \prop_if_in:NnF \l_@@_number_in_prop { mantissa } - { - \prop_put:Nnn \l_@@_number_in_prop { mantissa } { true } - \prop_put:Nnn \l_@@_number_in_prop { mantissa-integer } { 1 } - } - } - } - } -} -\cs_new_protected:Npn \@@_number_process_exponent_aux:n #1 { - \prop_get:NnNT \l_@@_number_in_prop { exponent- #1 } - \l_@@_tmpa_tl - { - \int_compare:nNnF { \l_@@_tmpa_tl } = { 0 } - { \bool_set_true:N \l_@@_tmp_bool } - } -} +%<*interfaces> % \end{macrocode} -%\end{macro} -%\end{macro} % -% \begin{macro}{\@@_number_process_figures:n} -% \begin{macro} -% { -% \@@_number_process_figures_aux:n , -% \@@_number_process_figures_init:n -% } -% The approach here is to find how many digits there are in each part -% of the number, working out which are significant. The next stage is -% reconstruction of the number. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_figures:n #1 - { - \int_compare:nNnTF \l_@@_process_precision_int > 0 - { - \prop_if_in:NnT \l_@@_number_in_prop {#1} - { \@@_number_process_figures_aux:n {#1} } - } - { - \prop_remove:Nn \l_@@_number_in_prop { #1 -sign } - \prop_put:Nnn \l_@@_number_in_prop { #1 -integer } { 0 } - \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal } - \bool_if:NF \l_@@_process_int_to_dec_bool - { \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal-marker } } - } - } -\cs_new_protected:Npn \@@_number_process_figures_aux:n #1 - { - \@@_number_process_figures_init:n {#1} - \@@_number_process_figures_count:n { integer } - \@@_number_process_figures_count:n { decimal } - \bool_if:NTF \l_@@_round_bool - { - \bool_set_false:N \l_@@_round_bool - \int_compare:nNnTF - \l_@@_round_int > \l_@@_process_precision_int - { - \@@_number_process_figures_round: - \@@_number_process_round_tidy:n {#1} - } - { \@@_number_process_figures_pad:n {#1} } - } - { - \prop_put:Nnn \l_@@_number_in_prop { #1 -integer } { 0 } - \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal } - } - } -\cs_new_protected:Npn \@@_number_process_figures_init:n #1 - { - \int_zero:N \l_@@_round_int - \bool_set_false:N \l_@@_round_bool - \bool_set_false:N \l_@@_round_even_bool - \prop_get:NnNF \l_@@_number_in_prop { #1 -decimal } - \l_@@_round_decimal_in_tl - { \tl_clear:N \l_@@_round_decimal_in_tl } - \prop_get:NnNF \l_@@_number_in_prop { #1 -integer } - \l_@@_round_integer_in_tl - { \tl_clear:N \l_@@_round_integer_in_tl } - \tl_clear:N \l_@@_round_decimal_out_tl - \tl_clear:N \l_@@_round_integer_out_tl - \tl_clear:N \l_@@_round_discard_tl - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \begin{macro}{\@@_number_process_figures_count:n} -% \begin{macro}{\@@_number_process_figures_count_aux:n} -% The counting code has to check that characters are actually -% significant. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_figures_count:n #1 - { - \tl_if_empty:cF { l_@@_round_ #1 _in_tl } - { - \prop_if_in:NnF \l_@@_number_in_prop { #1 -uncertainty } - { \@@_number_process_figures_count_aux:n {#1} } - } - } -\cs_new_protected:Npn \@@_number_process_figures_count_aux:n #1 - { - \int_set:Nn \l_@@_tmp_int - { \tl_head:v { l_@@_round_ #1 _in_tl } } - \tl_set:cx { l_@@_round_ #1 _in_tl } - { \tl_tail:v { l_@@_round_ #1 _in_tl } } - \tl_put_left:cV { l_@@_round_ #1 _out_tl } \l_@@_tmp_int - \bool_if:NF \l_@@_round_bool - { - \int_compare:nNnF \l_@@_tmp_int = 0 - { \bool_set_true:N \l_@@_round_bool } - } - \bool_if:NT \l_@@_round_bool - { \int_incr:N \l_@@_round_int } - \tl_if_empty:cTF { l_@@_round_ #1 _in_tl } - { - \tl_set_eq:cc { l_@@_round_ #1 _in_tl } - { l_@@_round_ #1 _out_tl } - \tl_clear:c { l_@@_round_ #1 _out_tl } - } - { \@@_number_process_figures_count_aux:n {#1} } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \begin{macro}{\@@_number_process_figures_round:} -% \begin{macro}{\@@_number_process_figures_round_loop:} -% The control macro for rounding to figures does the decimal part -% then the integer part as loops. There is then some tidying up if a -% digit is carried at the end. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_figures_round: - { - \int_set:Nn \l_@@_round_int - { \l_@@_round_int - \l_@@_process_precision_int } - \tl_if_empty:NF \l_@@_round_decimal_in_tl - { \@@_number_process_figures_round_loop: } - \tl_if_empty:NF \l_@@_round_integer_in_tl - { \@@_number_process_figures_integer: } - \bool_if:NT \l_@@_round_bool - { \tl_put_left:Nn \l_@@_round_integer_out_tl { 1 } } - } -\cs_new_protected:Npn \@@_number_process_figures_round_loop: - { - \@@_number_process_round_decimal: - \tl_if_empty:NF \l_@@_round_decimal_in_tl - { \@@_number_process_figures_round_loop: } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \begin{macro}{\@@_number_process_figures_integer:} -% For figures, the integer part is a little complicated as zeros need -% to be included. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_figures_integer: - { - \int_compare:nNnT \l_@@_round_int > 0 - { \tl_put_left:Nn \l_@@_round_integer_out_tl { 0 } } - \int_compare:nNnF \l_@@_round_int > 1 - { - \int_set:Nn \l_@@_tmp_int - { \tl_head:N \l_@@_round_integer_in_tl } - \@@_number_process_round_up: - \int_compare:nNnTF \l_@@_round_int = 1 - { - \int_compare:nNnT \l_@@_tmp_int > 4 - { \bool_set_true:N \l_@@_round_bool } - } - { - \int_compare:nNnT \l_@@_tmp_int = { 10 } - { - \bool_set_true:N \l_@@_round_bool - \int_zero:N \l_@@_tmp_int - } - \tl_put_left:NV \l_@@_round_integer_out_tl - \l_@@_tmp_int - } - } - \int_decr:N \l_@@_round_int - \tl_set:Nx \l_@@_round_integer_in_tl - { \tl_tail:N \l_@@_round_integer_in_tl } - \tl_if_empty:NF \l_@@_round_integer_in_tl - { \@@_number_process_figures_integer: } - } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_number_process_figures_pad:n} -% If the number is too short, then the reversal is undone and the -% padding routine is called. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_figures_pad:n #1 { - \prop_get:NnN \l_@@_number_in_prop { #1 -integer } - \l_@@_round_integer_in_tl - \prop_get:NnN \l_@@_number_in_prop { #1 -decimal } - \l_@@_round_decimal_in_tl - \int_set:Nn \l_@@_round_int - { \l_@@_process_precision_int - \l_@@_round_int } - \@@_number_process_pad:n {#1} -} -% \end{macrocode} -%\end{macro} +% The user interfaces are defined in terms of documented code-level ones. +% This is all done here, and will appear in the \file{.sty} file before the +% relevant code. Things could be re-arranged by \pkg{DocStrip} but there is no +% advantage. % -%\begin{macro}{\@@_number_process_fixed:} -%\begin{macro}{ -% \@@_number_process_fixed_aux_i:nnn , -% \@@_number_process_fixed_aux_ii:nnn , -% \@@_number_process_fixed_aux_iii:nnn , -% \@@_number_process_fixed_large:nnn , -% \@@_number_process_fixed_large_aux:w , -% \@@_number_process_fixed_small:nnn , -% \@@_number_process_fixed_small_aux:w -%} -% When working to a fixed exponent value, the idea is to use the stack -% to do the work. First, there is some set up to do. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_fixed: { - \prop_if_in:NnF \l_@@_number_in_prop { complex } - { - \prop_get:NnNF \l_@@_number_in_prop { mantissa-integer } - \l_@@_tmpa_tl - { \tl_set:Nn \l_@@_tmpa_tl { 0 } } - \prop_get:NnNF \l_@@_number_in_prop { mantissa-decimal } - \l_@@_tmpb_tl - { \tl_clear:N \l_@@_tmpb_tl } - \tl_set:Nx \l_@@_tmpa_tl - { { \l_@@_tmpa_tl } { \l_@@_tmpb_tl } } - \prop_get:NnNF \l_@@_number_in_prop { exponent-integer } - \l_@@_tmpb_tl - { \tl_set:Nn \l_@@_tmpb_tl { 0 } } - \group_begin: - \prop_get:NnNT \l_@@_number_in_prop { exponent-sign } - \l_@@_tmpa_tl - { - \tl_put_left:NV \l_@@_tmpb_tl \l_@@_tmpa_tl - } - \exp_args:NNNV \group_end: - \tl_set:Nn \l_@@_tmpb_tl \l_@@_tmpb_tl - \tl_set:Nx \l_@@_tmpa_tl - { \l_@@_tmpa_tl { \l_@@_tmpb_tl } } - \exp_after:wN \@@_number_process_fixed_aux_i:nnn - \l_@@_tmpa_tl - } -} -% \end{macrocode} -% The main loop checks to see which way to adjust the exponent then -% does the work. +% User level interfaces are all created by \pkg{xparse} % \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_fixed_aux_i:nnn #1#2#3 - { - \prop_put:Nnn \l_@@_number_in_prop { exponent } { true } - \int_compare:nNnTF \l_@@_process_fixed_int > 0 - { - \prop_put:NnV \l_@@_number_in_prop { exponent-integer } - \l_@@_process_fixed_int - \prop_remove:Nn \l_@@_number_in_prop { exponent-sign } - } - { - \prop_put:Nnx \l_@@_number_in_prop { exponent-integer } - { \int_eval:n { - \l_@@_process_fixed_int } } - \prop_put:Nnn \l_@@_number_in_prop { exponent-sign } { - } - } - \@@_number_process_fixed_aux_ii:nnn {#1} {#2} {#3} - } -\cs_new_protected:Npn \@@_number_process_fixed_aux_ii:nnn #1#2#3 - { - \bool_set_true:N \l_@@_tmp_bool - \tl_map_inline:nn {#1#2} - { - \str_if_eq:nnF {##1} { 0 } - { - \bool_set_false:N \l_@@_tmp_bool - \tl_map_break: - } - } - \bool_if:NF \l_@@_tmp_bool - { \@@_number_process_fixed_aux_iii:nnn {#1} {#2} {#3} } - } -\cs_new_protected:Npn - \@@_number_process_fixed_aux_iii:nnn #1#2#3 { - \int_compare:nNnTF {#3} > { \l_@@_process_fixed_int } - { \@@_number_process_fixed_large:nnn {#1} {#2} {#3} } - { - \int_compare:nNnTF {#3} < { \l_@@_process_fixed_int } - { \@@_number_process_fixed_small:nnn {#1} {#2} {#3} } - { - \prop_put:Nnn \l_@@_number_in_prop - { mantissa-integer } {#1} - \tl_if_empty:nTF {#2} - { - \prop_remove:Nn \l_@@_number_in_prop - { mantissa-decimal } - \prop_remove:Nn \l_@@_number_in_prop - { mantissa-decimal-marker } - } - { - \prop_put:Nnn \l_@@_number_in_prop - { mantissa-decimal } {#2} - \prop_if_in:NnF \l_@@_number_in_prop - { mantissa-decimal-marker } - { - \prop_put:Nnn \l_@@_number_in_prop - { mantissa-decimal-marker } { . } - } - } - } - } -} -% \end{macrocode} -% Simple stack-based manipulation of the input for number which are -% either too big or too small. There are a couple of checks needed to -% deal with cases where there is no decimal part and where there are -% leading zeros to dispose of. There is also a check to avoid adding -% an additional zero to the decimal part of the number. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_fixed_large:nnn #1 - { - \@@_number_if_zero:nTF {#1} - { \@@_number_process_fixed_large_aux:nnn { } } - { \@@_number_process_fixed_large_aux:nnn {#1} } - } -\cs_new_protected:Npn \@@_number_process_fixed_large_aux:nnn #1#2#3 - { - \cs_set_protected:Npn - \@@_number_process_fixed_large_aux:w ##1##2 \q_stop - { - \tl_if_empty:nTF {##2} - { - \int_compare:nNnTF - { #3 - 1 } = { \l_@@_process_fixed_int } - { - \@@_number_process_fixed_aux_ii:nnn { #1 ##1 } - { } { #3 - 1 } - } - { - \@@_number_process_fixed_aux_ii:nnn { #1 ##1 } - { 0 } { #3 - 1 } - } - } - { - \@@_number_if_zero:nTF {#1} - { - \@@_number_process_fixed_aux_ii:nnn {##1} {##2} - { #3 - 1 } - } - { - \@@_number_process_fixed_aux_ii:nnn { #1 ##1 } - {##2} { #3 - 1 } - } - } - } - \tl_if_empty:nTF {#2} - { \@@_number_process_fixed_aux_ii:nnn { #1 0 } { } { #3 - 1 } } - { \@@_number_process_fixed_large_aux:w #2 \q_stop } -} -\cs_new_protected:Npn \@@_number_process_fixed_large_aux:w +\IfFormatAtLeastTF { 2020-10-01 } { } -\cs_new_protected:Npn - \@@_number_process_fixed_small:nnn #1#2#3 { - \cs_set_protected:Npn - \@@_number_process_fixed_small_aux:w ##1##2 \q_stop ##3 - { - \tl_if_empty:nTF {##2} - { - \tl_if_empty:nTF {##3} - { - \@@_number_process_fixed_aux_ii:nnn { 0 } - { ##1 #2 } { #3 + 1 } - } - { - \@@_number_process_fixed_aux_ii:nnn {##3} - { ##1 #2 } { #3 + 1 } - } - } - { - \@@_number_process_fixed_small_aux:w ##2 \q_stop - { ##3 ##1 } - } - } - \@@_number_process_fixed_small_aux:w #1 \q_stop { } -} -\cs_new_protected:Npn \@@_number_process_fixed_small_aux:w - { } -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_process_integer_digits:} -% Producing extra digits for the integer part is a simple process -% once the target is known. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_integer_digits: { - \int_compare:nNnT \l_@@_process_integer_min_int > 0 - { - \prop_get:NnNT \l_@@_number_in_prop { mantissa-integer } - \l_@@_tmpa_tl - { - \int_set:Nn \l_@@_tmp_int - { - \l_@@_process_integer_min_int - - \tl_count:N \l_@@_tmpa_tl - } - \int_compare:nNnT \l_@@_tmp_int > 0 - { - \tl_set:Nx \l_@@_tmpa_tl - { - \prg_replicate:nn { \l_@@_tmp_int } { 0 } - \exp_not:V \l_@@_tmpa_tl - } - \prop_put:NnV \l_@@_number_in_prop - { mantissa-integer } \l_@@_tmpa_tl - } - } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_process_mantissa:} -%\begin{macro}{\c_@@_unity_tl} -% A check for the mantissa consisting only of the token \texttt{1}, when -% an exponent is also available. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_mantissa: { - \bool_if:NF \l_@@_process_unity_mantissa_bool - { - \prop_if_in:NnT \l_@@_number_in_prop { exponent } - { - \prop_get:NnNT \l_@@_number_in_prop { mantissa-integer } - \l_@@_tmpa_tl - { - \tl_if_eq:NNT \c_@@_unity_tl \l_@@_tmpa_tl - { - \prop_if_in:NnF \l_@@_number_in_prop - { mantissa-decimal-marker } - { - \prop_remove:Nn \l_@@_number_in_prop - { mantissa } - \prop_remove:Nn \l_@@_number_in_prop - { mantissa-integer } - } - } - } - } - } -} -\tl_const:Nn \c_@@_unity_tl { 1 } + { \RequirePackage { xparse } } % \end{macrocode} -%\end{macro} -%\end{macro} % -%\begin{macro}{\@@_number_process_pad:n} -% For padding a number by adding zero to the end repeatedly. This can -% happen if the input was zero or if the number is too short. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_pad:n #1 { - \prop_get:NnNT \l_@@_number_in_prop { #1 -decimal } - \l_@@_tmpa_tl - { - \int_while_do:nNnn { \l_@@_round_int } > { 0 } - { - \tl_put_right:Nn \l_@@_tmpa_tl { 0 } - \int_decr:N \l_@@_round_int - } - \prop_put:NnV \l_@@_number_in_prop { #1 -decimal } - \l_@@_tmpa_tl - } -} -% \end{macrocode} -%\end{macro} +% \subsubsection{Preamble commands} % -% \begin{macro}{\@@_number_process_places:n} % \begin{macro} % { -% \@@_number_process_places_init:n , -% \@@_number_process_places_aux_i:n , -% \@@_number_process_places_aux_i:TF , -% \@@_number_process_places_none: , -% \@@_number_process_places_aux_ii:n , -% \@@_number_process_places_loop:n , -% \@@_number_process_places_integer:n -% } -% For rounding to a fixed number of places, a check is made to see if -% the decimal part is exactly zero. If it is, just create the -% appropriate number of zeros in the padding routine. Otherwise, do the -% real work. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_places:n #1 - { - \prop_if_in:NnT \l_@@_number_in_prop {#1} - { - \prop_if_in:NnF \l_@@_number_in_prop { #1 -uncertainty } - { \@@_number_process_places_aux_i:n {#1} } - } - } -\cs_new_protected:Npn \@@_number_process_places_aux_i:n #1 - { - \int_compare:nNnTF \l_@@_process_precision_int = 0 - { \@@_number_process_places_none:n {#1} } - { - \prop_get:NnNT \l_@@_number_in_prop { #1 -decimal } - \l_@@_tmpa_tl - { - \tl_if_empty:NT \l_@@_tmpa_tl - { \tl_set:Nn \l_@@_tmpa_tl { 0 } } - \@@_number_process_places_aux_i:TF - { - \prop_put:Nnn \l_@@_number_in_prop { #1 -decimal } { } - \int_set:Nn \l_@@_round_int - { \l_@@_process_precision_int } - \@@_number_process_pad:n {#1} - } - { - \int_set:Nn \l_@@_round_int - { \tl_count:N \l_@@_tmpa_tl } - \@@_number_process_places_aux_ii:n {#1} - } - } - } - } -% \end{macrocode} -% The number of digits in the decimal part could be more that \TeX{} can -% handle, so a slow loop is used to see if we need to round. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_places_aux_i:TF - { - \bool_set_true:N \l_@@_tmp_bool - \tl_map_inline:Nn \l_@@_tmpa_tl - { - \int_compare:nNnF {##1} = 0 - { - \bool_set_false:N \l_@@_tmp_bool - \tl_map_break: - } - } - \bool_if:NTF \l_@@_tmp_bool - } -% \end{macrocode} -% Rounding to no places at all requires a few checks to see if there is any -% work to do. That includes a check for rounding half to even, where if -% the decimal part is exactly half then special action is required. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_places_none:n #1 - { - \prop_get:NnNT \l_@@_number_in_prop { #1 -decimal } \l_@@_tmpa_tl - { - \int_compare:nNnTF { \tl_head:N \l_@@_tmpa_tl } > 4 - { - \prop_get:NnNTF \l_@@_number_in_prop { #1 -integer } - \l_@@_tmpb_tl - { - \tl_set:Nx \l_@@_tmpb_tl - { \int_eval:n { \l_@@_tmpb_tl + 1 } } - \bool_if:NF \l_@@_round_half_up_bool - { - \bool_lazy_and:nnT - { - \int_compare_p:nNn - { 0 \tl_head:N \l_@@_tmpa_tl } = 5 - } - { - \int_compare_p:nNn - { 0 \tl_tail:N \l_@@_tmpa_tl } = 0 - } - { - \int_if_odd:nT \l_@@_tmpb_tl - { - \tl_set:Nx \l_@@_tmpb_tl - { \int_eval:n { \l_@@_tmpb_tl - 1 } } - } - } - } - } - { \tl_set:Nn \l_@@_tmpb_tl { 1 } } - \prop_put:NnV \l_@@_number_in_prop - { #1 -integer } \l_@@_tmpb_tl - } - { - \prop_if_in:NnF \l_@@_number_in_prop { #1 -integer } - { - \prop_put:Nnn \l_@@_number_in_prop - { #1 -integer } { 0 } - } - } - } - \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal } - \bool_if:NF \l_@@_process_int_to_dec_bool - { \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal-marker } } - } -% \end{macrocode} -% For rounding to a fixed number of places, the package finds the -% difference in length between what is present and what is required. -% If the number is too short, there is some simple padding to do. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_places_aux_ii:n #1 - { - \int_sub:Nn \l_@@_round_int - { \l_@@_process_precision_int } - \int_compare:nNnTF \l_@@_round_int < 0 - { - \int_set:Nn \l_@@_round_int { - \l_@@_round_int } - \@@_number_process_pad:n {#1} - } - { - \@@_number_process_places_init:n {#1} - \@@_number_process_places_loop:n {#1} - \@@_number_process_round_tidy:n {#1} - } - } -% \end{macrocode} -% To keep the code a little clearer. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_places_init:n #1 - { - \prop_get:NnNF \l_@@_number_in_prop { #1 -integer } - \l_@@_round_integer_in_tl - { \tl_clear:N \l_@@_round_integer_in_tl } - \prop_get:NnN \l_@@_number_in_prop { #1 -decimal } - \l_@@_round_decimal_in_tl - \tl_reverse:N \l_@@_round_integer_in_tl - \tl_reverse:N \l_@@_round_decimal_in_tl - \tl_clear:N \l_@@_round_integer_out_tl - \tl_clear:N \l_@@_round_decimal_out_tl - \tl_clear:N \l_@@_round_discard_tl - \bool_set_false:N \l_@@_round_bool - \bool_set_false:N \l_@@_round_even_bool - } -% \end{macrocode} -% If there is a decimal, do the decimal processing then come back here. -% If there is an integer, do the same. Only if both are empty does the -% loop stop. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_places_loop:n #1 - { - \tl_if_empty:NTF \l_@@_round_decimal_in_tl - { - \tl_if_empty:NF \l_@@_round_integer_in_tl - { - \@@_number_process_places_integer:n {#1} - \@@_number_process_places_loop:n {#1} - } - \bool_if:NT \l_@@_round_bool - { - \tl_put_left:Nn \l_@@_round_integer_out_tl { 1 } - \bool_set_false:N \l_@@_round_bool - } - } - { - \@@_number_process_round_decimal: - \@@_number_process_places_loop:n {#1} - } - } -% \end{macrocode} -% Rounding for integers is just a case of carrying digits. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_places_integer:n #1 - { - \int_set:Nn \l_@@_tmp_int - { \tl_head:N \l_@@_round_integer_in_tl } - \tl_set:Nx \l_@@_round_integer_in_tl - { \tl_tail:N \l_@@_round_integer_in_tl } - \@@_number_process_round_up: - \bool_set_false:N \l_@@_round_bool - \int_compare:nNnT \l_@@_tmp_int = { 10 } - { - \int_zero:N \l_@@_tmp_int - \bool_set_true:N \l_@@_round_bool - } - \tl_put_left:NV \l_@@_round_integer_out_tl \l_@@_tmp_int - } -% \end{macrocode} -%\end{macro} -%\end{macro} -% -% \begin{macro}{\@@_number_process_round:} -% The lead-off for rounding is the same for decimal places and -% significant figures. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_round: - { - \tl_if_empty:NF \l_@@_round_tl - { - \bool_if:NT \l_@@_process_int_to_dec_bool - { - \prop_if_in:NnF \l_@@_number_in_prop { mantissa-decimal } - { - \prop_put:Nnn \l_@@_number_in_prop { mantissa-decimal } - { 0 } - } - \prop_if_in:NnF \l_@@_number_in_prop - { mantissa-decimal-marker } - { - \prop_put:Nnn \l_@@_number_in_prop - { mantissa-decimal-marker } { . } - } - } - \clist_map_function:nc { mantissa , complex } - { @@_number_process_ \l_@@_round_tl :n } - } - } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\@@_number_process_round_decimal:} -% \begin{macro}{\@@_number_process_round_decimal_aux:} -% The rounding routine for decimals is the same for figures and places, -% so there is a generalised function here. Unfortunately, it is also -% complicated! +% \DeclareSIPower , +% \DeclareSIPrefix , +% \DeclareSIQualifier , +% \DeclareSIUnit +% } +% Pass data to the code layer. % \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_round_decimal: +\NewDocumentCommand \DeclareSIPower { +m +m m } { - \int_compare:nNnF \l_@@_round_int > 1 - { \@@_number_process_round_decimal_aux: } - \tl_put_right:Nx \l_@@_round_discard_tl - { \tl_head:N \l_@@_round_decimal_in_tl } - \tl_set:Nx \l_@@_round_decimal_in_tl - { \tl_tail:N \l_@@_round_decimal_in_tl } - \int_decr:N \l_@@_round_int + \siunitx_declare_power:NNn #1 #2 {#3} } -% \end{macrocode} -% The logic here has to deal with the (simpler) rounding up method and the -% case where there is a need to check for rounding to an even number. The -% later is only required when the discarded part is exactly equal to -% half of the least-significant digit. So there is a somewhat complex check -% for that, along with a somewhat simpler check when carrying out the -% rounding. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_round_decimal_aux: +\NewDocumentCommand \DeclareSIPrefix { +m m m } { - \int_set:Nn \l_@@_tmp_int - { \tl_head:N \l_@@_round_decimal_in_tl } - \@@_number_process_round_up: - \int_compare:nNnTF \l_@@_round_int = 1 - { - \int_compare:nNnT \l_@@_tmp_int > 4 - { - \bool_set_true:N \l_@@_round_bool - \bool_if:NF \l_@@_round_half_up_bool - { - \int_compare:nNnT - { \l_@@_round_discard_tl \int_use:N \l_@@_tmp_int } = 5 - { \bool_set_true:N \l_@@_round_even_bool } - } - } - } - { - \int_compare:nNnT \l_@@_tmp_int = { 10 } - { - \bool_set_true:N \l_@@_round_bool - \int_zero:N \l_@@_tmp_int - } - \tl_put_left:NV \l_@@_round_decimal_out_tl - \l_@@_tmp_int - } + \siunitx_declare_prefix:Nnn #1 {#2} {#3} } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \begin{macro}{\@@_number_process_round_up:} -% This is needed a few times, to round up the current digit unless -% it is even and \enquote{half to even} is active. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_round_up: +\NewDocumentCommand \DeclareSIQualifier { +m m } { - \bool_if:NT \l_@@_round_bool - { - \bool_if:NTF \l_@@_round_even_bool - { - \bool_set_false:N \l_@@_round_even_bool - \int_if_even:nF \l_@@_tmp_int - { \int_incr:N \l_@@_tmp_int } - } - { \int_incr:N \l_@@_tmp_int } - } - \bool_set_false:N \l_@@_round_bool + \siunitx_declare_qualifier:Nn #1 {#2} } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\@@_number_process_round_tidy:n} -% \begin{macro}{\@@_number_process_round_tidy_aux:w} -% To put data back again: there is a check to see if the number has been -% r ounded to zero and a minimal value has been requested. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_round_tidy:n #1 +\NewDocumentCommand \DeclareSIUnit { o +m m } { - \bool_lazy_and:nnTF - { \@@_number_if_zero_p:V \l_@@_round_integer_out_tl } - { \@@_number_if_zero_p:V \l_@@_round_decimal_out_tl } - { - \str_if_eq:VnTF \l_@@_process_round_min_tl { 0 } - { - \prop_put:Nnn \l_@@_number_in_prop { #1 -integer } { 0 } - \prop_put:NnV \l_@@_number_in_prop { #1 -decimal } - \l_@@_round_decimal_out_tl - } - { - \exp_after:wN \@@_number_process_round_tidy_aux:w - \l_@@_process_round_min_tl . . \q_stop {#1} - } - } - { - \prop_put:NnV \l_@@_number_in_prop { #1 -integer } - \l_@@_round_integer_out_tl - \tl_if_empty:NTF \l_@@_round_decimal_out_tl - { - \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal } - \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal-marker } - } - { - \prop_put:NnV \l_@@_number_in_prop { #1 -decimal } - \l_@@_round_decimal_out_tl - } - } - } -\cs_new_protected:Npn \@@_number_process_round_tidy_aux:w - #1 . #2 . #3 \q_stop #4 - { - \prop_put:Nnn \l_@@_number_in_prop { comparator } { < } - \prop_put:Nnn \l_@@_number_in_prop { #4 -integer } {#1} - \tl_if_empty:nTF {#2} - { \prop_remove:Nn \l_@@_number_in_prop { #4 -decimal } } - { \prop_put:Nnn \l_@@_number_in_prop { #4 -decimal } {#2} } + \IfNoValueTF {#1} + { \siunitx_declare_unit:Nn #2 {#3} } + { \siunitx_declare_unit:Nnn #2 {#3} {#1} } } % \end{macrocode} % \end{macro} -% \end{macro} % -%\begin{macro}{\@@_number_process_scientific:} -%\begin{macro}{ -% \@@_number_process_scientific_aux_i:nnn , -% \@@_number_process_scientific_aux_ii:nnn , -% \@@_number_process_scientific_large:nnn , -% \@@_number_process_scientific_large_loop:nNN , -% \@@_number_process_scientific_small:wn , -% \@@_number_process_scientific_store:nnn , -% \@@_number_process_scientific_engineering:nnn , -% \@@_number_process_scientific_engineering_0:nnn , -% \@@_number_process_scientific_engineering_1:nnn , -% \@@_number_process_scientific_engineering_1:nw , -% \@@_number_process_scientific_engineering_2:nnn , -% \@@_number_process_scientific_engineering_2_i:nw , -% \@@_number_process_scientific_engineering_2_ii:nw -%} -% Converting a number to scientific form is done such that the number -% of places involved is unchanged. The first step is to skip any -% complex-number containing input and to recover the stored data. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_scientific: { - \prop_if_in:NnF \l_@@_number_in_prop { complex } - { - \prop_get:NnNF \l_@@_number_in_prop { mantissa-integer } - \l_@@_tmpa_tl - { \tl_set:Nn \l_@@_tmpa_tl { 0 } } - \prop_get:NnNF \l_@@_number_in_prop { mantissa-decimal } - \l_@@_tmpb_tl - { \tl_clear:N \l_@@_tmpb_tl } - \tl_set:Nx \l_@@_tmpa_tl - { { \l_@@_tmpa_tl } { \l_@@_tmpb_tl } } - \prop_get:NnNF \l_@@_number_in_prop { exponent-integer } - \l_@@_tmpb_tl - { \tl_set:Nn \l_@@_tmpb_tl { 0 } } - \group_begin: - \prop_get:NnNT \l_@@_number_in_prop { exponent-sign } - \l_@@_tmpa_tl - { \tl_put_left:NV \l_@@_tmpb_tl \l_@@_tmpa_tl } - \exp_args:NNNV \group_end: - \tl_set:Nn \l_@@_tmpb_tl \l_@@_tmpb_tl - \tl_set:Nx \l_@@_tmpa_tl - { \l_@@_tmpa_tl { \l_@@_tmpb_tl } } - \exp_after:wN \@@_number_process_scientific_aux_i:nnn - \l_@@_tmpa_tl - } -} -\cs_new_protected:Npn \@@_number_process_scientific_aux_i:nnn #1#2#3 - { - \bool_set_true:N \l_@@_tmp_bool - \tl_map_inline:nn {#1#2} - { - \str_if_eq:nnF {##1} { 0 } - { - \bool_set_false:N \l_@@_tmp_bool - \tl_map_break: - } - } - \bool_if:NF \l_@@_tmp_bool - { \@@_number_process_scientific_aux_ii:nnn {#1} {#2} {#3} } - } -% \end{macrocode} -% The code here works on a loop, standardising the mantissa into the -% range \( 1 \le x < 10 \). -% \begin{macrocode} -\cs_new_protected:Npn - \@@_number_process_scientific_aux_ii:nnn #1#2#3 { - \int_compare:nNnTF { \tl_count:n {#1} } > 1 - { \@@_number_process_scientific_large:nnn {#1} {#2} {#3} } - { - \@@_number_if_zero:nTF {#1} - { - \@@_number_process_scientific_small:wn - #2 \q_stop {#3} - } - { - \bool_if:NTF \l_@@_process_engineering_bool - { \@@_number_process_scientific_engineering:nnn } - { \@@_number_process_scientific_store:nnn } - {#1} {#2} {#3} - } - - } -} -% \end{macrocode} -% A faster approach here is to use integer maths to do the digit move, -% but that runs into problems with the range available for the input. -% Instead, we use a loop to find the last digit. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_scientific_large:nnn #1#2#3 - { - \cs_set_protected:Npn \@@_number_process_scientific_large_loop:nNN - ##1##2##3 - { - \quark_if_recursion_tail_stop_do:Nn ##3 - { - \@@_number_process_scientific_aux_ii:nnn {##1} { ##2 #2 } - { #3 + 1 } - } - \@@_number_process_scientific_large_loop:nNN { ##1 ##2 } ##3 - } - \@@_number_process_scientific_large_loop:nNN { } #1 - \q_recursion_tail \q_recursion_stop - } -% \end{macrocode} -% For small numbers, the important digit is easy to find. -% \begin{macrocode} -\cs_new_protected:Npn - \@@_number_process_scientific_small:wn #1#2 \q_stop #3 - { \@@_number_process_scientific_aux_ii:nnn {#1} {#2} { #3 - 1 } } -% \end{macrocode} -% A tidy-up and store routine. -% \begin{macrocode} -\cs_new_protected:Npn - \@@_number_process_scientific_store:nnn #1#2#3 - { - \prop_put:Nnn \l_@@_number_in_prop { mantissa-integer } {#1} - \tl_if_empty:nTF {#2} - { - \prop_remove:Nn \l_@@_number_in_prop { mantissa-decimal } - \prop_remove:Nn \l_@@_number_in_prop - { mantissa-decimal-marker } - } - { - \prop_put:Nnn \l_@@_number_in_prop - { mantissa-decimal } {#2} - \prop_if_in:NnF \l_@@_number_in_prop - { mantissa-decimal-marker } - { - \prop_put:Nnn \l_@@_number_in_prop - { mantissa-decimal-marker } { . } - } - } - \int_compare:nNnTF {#3} = { 0 } - { - \prop_remove:Nn \l_@@_number_in_prop { exponent } - \prop_remove:Nn \l_@@_number_in_prop { exponent-sign } - \prop_remove:Nn \l_@@_number_in_prop { exponent-integer } - } - { - \prop_put:Nnn \l_@@_number_in_prop { exponent } { true } - \int_compare:nNnTF {#3} > { 0 } - { - \int_set:Nn \l_@@_tmp_int {#3} - \prop_put:NnV \l_@@_number_in_prop - { exponent-integer } \l_@@_tmp_int - \prop_remove:Nn \l_@@_number_in_prop { exponent-sign } - } - { - \int_set:Nn \l_@@_tmp_int { 0 - (#3) } - \prop_put:NnV \l_@@_number_in_prop - { exponent-integer } \l_@@_tmp_int - \prop_put:Nnn \l_@@_number_in_prop { exponent-sign } - { - } - } - } - } -% \end{macrocode} -% For engineering style, the exponent has to be a power of three. -% The fastest way to do this is by expansion, as the number of tokens -% is known. -% \begin{macrocode} -\cs_new_protected:Npn - \@@_number_process_scientific_engineering:nnn #1#2#3 - { - \use:c - { - @@_number_process_scientific_engineering_ - \int_compare:nNnTF {#3} < { 0 } - { - \int_case:nnF { \int_mod:nn { 0 - (#3) } { 3 } } - { - { 1 } { 2 } - { 2 } { 1 } - } - { 0 } - } - { \int_mod:nn {#3} { 3 } } - :nnn - } - {#1} {#2} {#3} - } -\cs_new_eq:cN - { @@_number_process_scientific_engineering_0:nnn } - \@@_number_process_scientific_store:nnn -\cs_new_protected:cpn - { @@_number_process_scientific_engineering_1:nnn } #1#2#3 - { - \tl_if_empty:nTF {#2} - { - \@@_number_process_scientific_store:nnn { #1 0 } { } - { #3 - 1 } - } - { - \use:c - { @@_number_process_scientific_engineering_1:nw } - {#1} #2 \q_stop {#3} - } - } -\cs_new_protected:cpn - { @@_number_process_scientific_engineering_1:nw } - #1#2#3 \q_stop #4 - { - \@@_number_process_scientific_store:nnn - {#1#2} {#3} { #4 - 1 } - } -\cs_new_protected:cpn - { @@_number_process_scientific_engineering_2:nnn } #1#2#3 - { - \tl_if_empty:nTF {#2} - { - \@@_number_process_scientific_store:nnn { #1 00 } { } - { #3 - 2 } - } - { - \use:c - { @@_number_process_scientific_engineering_2_i:nw } - {#1} #2 \q_stop {#3} - } - } -\cs_new_protected:cpn - { @@_number_process_scientific_engineering_2_i:nw } - #1#2#3 \q_stop #4 - { - \tl_if_empty:nTF {#3} - { - \@@_number_process_scientific_store:nnn { #1#2 0 } { } - { #4 - 2 } - } - { - \use:c - { @@_number_process_scientific_engineering_2_ii:nw } - {#1#2} #3 \q_stop {#4} - } - } -\cs_new_protected:cpn - { @@_number_process_scientific_engineering_2_ii:nw } - #1#2#3 \q_stop #4 - { - \@@_number_process_scientific_store:nnn { #1#2 } {#3} - { #4 - 2 } - } -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_process_sign:} -%\begin{macro}{ -% \@@_number_process_sign_add:n , -% \@@_number_process_sign_plus:n -%} -%\begin{macro}{\c_@@_plus_tl} -% Sorting out signs consists of two parts: retaining a plus if necessary -% and adding an explicit sign. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_sign: { - \bool_if:NF \l_@@_process_plus_bool - { - \prop_if_in:NnTF \l_@@_number_in_prop { mantissa-sign } - { \@@_number_process_sign_plus:n { mantissa } } - { - \prop_if_in:NnT \l_@@_number_in_prop { complex-sign } - { - \prop_if_in:NnF \l_@@_number_in_prop { mantissa } - { \@@_number_process_sign_plus:n { complex } } - } - } - \prop_if_in:NnT \l_@@_number_in_prop { exponent-sign } - { \@@_number_process_sign_plus:n { exponent } } - } - \tl_if_empty:NF \l_@@_process_sign_tl - { - \@@_number_process_sign_add:n { mantissa } - \prop_if_in:NnTF \l_@@_number_in_prop { complex } - { \@@_number_process_sign_add:n { complex } } - } -} -% \end{macrocode} -% Adding a sign to an existing number needs a couple of to make sure -% there is a number to add to, and to see if there is a sign already. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_sign_add:n #1 { - \prop_if_in:NnF \l_@@_number_in_prop { #1 -sign } - { - \prop_if_in:NnF \l_@@_number_in_prop { #1 -had-sign } - { - \prop_get:NnN \l_@@_number_in_prop {#1} - \l_@@_tmpa_tl - \tl_if_empty:NTF \l_@@_tmpa_tl - { - \prop_put:NnV \l_@@_number_in_prop { sign } - \l_@@_process_sign_tl - } - { - \prop_put:NnV \l_@@_number_in_prop { #1 -sign } - \l_@@_process_sign_tl - } - } - } -} -% \end{macrocode} -% Holding onto a plus works very much in the same way as adding a sign: -% some quick tests and an assignment. Using a pre-defined token list is -% a speed-related choice: very slightly faster comparison. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_sign_plus:n #1 { - \prop_get:NnN \l_@@_number_in_prop { #1 -sign } - \l_@@_tmpa_tl - \tl_if_eq:NNT \c_@@_plus_tl \l_@@_tmpa_tl - { - \prop_remove:Nn \l_@@_number_in_prop { #1 -sign } - \prop_put:Nnn \l_@@_number_in_prop { #1 -had-sign } { true } - } -} -\tl_const:Nn \c_@@_plus_tl { + } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} +% \subsubsection{Document commands} % -%\begin{macro}{\@@_number_process_uncertainty:} -%\begin{macro}{\@@_number_process_uncertainty_aux:n} -% There may be a need to expand uncertainties into a decimal and integer -% part. This is done here so that the core \texttt{in} code is faster. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_uncertainty: { - \clist_map_function:nN { mantissa , complex } - \@@_number_process_uncertainty_aux:n -} -\cs_new_protected:Npn - \@@_number_process_uncertainty_aux:n #1 { - \prop_if_in:NnT \l_@@_number_in_prop { #1 -uncertainty } - { - \prop_if_in:NnTF \l_@@_number_in_prop { #1 -decimal-marker } - { \@@_number_process_uncertainty_decimal:n {#1} } - { \@@_number_process_uncertainty_integer:n {#1} } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\begin{macro}{\@@_number_process_uncertainty_decimal:n} -%\begin{macro}{\@@_number_process_uncertainty_count:nn} -% To deal with an error in the decimal part, care needs to be taken to -% correctly pad with zeros and also to allow for the possibility that -% the error crosses the decimal--integer boundary. -% \begin{macrocode} -\cs_new_protected:Npn - \@@_number_process_uncertainty_decimal:n #1 { - \@@_number_process_uncertainty_count:nn {#1} { decimal } - \@@_number_process_uncertainty_count:nn {#1} { uncertainty } - \tl_clear:N \l_@@_uncertainty_decimal_tl - \tl_clear:N \l_@@_uncertainty_integer_tl - \int_compare:nNnTF - { \l_@@_process_uncertainty_int } > - { \l_@@_process_decimal_int } - { \@@_number_process_uncertainty_separate: } - { \@@_number_process_uncertainty_pad: } - \tl_if_empty:NF \l_@@_uncertainty_integer_tl - { - \prop_put:NnV \l_@@_number_in_prop - { #1 -uncertainty-integer } - \l_@@_uncertainty_integer_tl - } - \prop_put:NnV \l_@@_number_in_prop { #1 -uncertainty-decimal } - \l_@@_uncertainty_decimal_tl - \prop_get:NnN \l_@@_number_in_prop { #1 -decimal-marker } - \l_@@_tmpa_tl - \prop_put:NnV \l_@@_number_in_prop - { #1 -uncertainty-decimal-marker } \l_@@_tmpa_tl -} -\cs_new_protected:Npn - \@@_number_process_uncertainty_count:nn #1#2 { - \prop_get:NnN \l_@@_number_in_prop { #1 - #2 } - \l_@@_tmpa_tl - \int_set:cn { l_@@_process_ #2 _int } - { \tl_count:N \l_@@_tmpa_tl } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\begin{macro}{\@@_number_process_uncertainty_pad:} -% Uncertainty is short: add zeros. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_uncertainty_pad: { - \int_while_do:nNnn - { \l_@@_process_uncertainty_int } < - { \l_@@_process_decimal_int } - { - \tl_put_right:Nn \l_@@_uncertainty_decimal_tl {0} - \int_incr:N \l_@@_process_uncertainty_int - } - \tl_put_right:NV \l_@@_uncertainty_decimal_tl - \l_@@_tmpa_tl -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_number_process_uncertainty_separate:} -%\begin{macro}{\@@_number_process_uncertainty_separate_aux:N} -% Find the integer--decimal boundary and work appropriately. +% \begin{macro}{\qty} % \begin{macrocode} -\cs_new_protected:Npn - \@@_number_process_uncertainty_separate: { - \tl_map_function:NN \l_@@_tmpa_tl - \@@_number_process_uncertainty_separate_aux:N -} -\cs_new_protected:Npn - \@@_number_process_uncertainty_separate_aux:N #1 { - \int_compare:nNnTF - { \l_@@_process_uncertainty_int } > - { \l_@@_process_decimal_int } - { \tl_put_right:Nn \l_@@_uncertainty_integer_tl {#1} } - { \tl_put_right:Nn \l_@@_uncertainty_decimal_tl {#1} } - \int_decr:N \l_@@_process_uncertainty_int -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\begin{macro}{\@@_number_process_uncertainty_integer:n} -% Relatively easy: the uncertainty is in the integer part of the number, -% and so there is no need to generate zeros. -% \begin{macrocode} -\cs_new_protected:Npn - \@@_number_process_uncertainty_integer:n #1 { - \prop_get:NnN \l_@@_number_in_prop { #1 -uncertainty } - \l_@@_tmpa_tl - \prop_put:NnV \l_@@_number_in_prop { #1 -uncertainty-integer } - \l_@@_tmpa_tl -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_process_zero_fill:} -%\begin{macro}{ -% \@@_number_process_zero_fill_aux:n , -% \@@_number_process_zero_fill_aux:nn -%} -% Checks for adding zeros to each component are carried out. The nesting -% here makes checking the appropriate flag a little more efficient. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_zero_fill: { - \@@_number_process_zero_fill_aux:n { integer } - \@@_number_process_zero_fill_aux:n { decimal } -} -\cs_new:Npn \@@_number_process_zero_fill_aux:n #1 { - \bool_if:cT { l_@@_process_ #1 _zero_bool } - { - \@@_number_process_zero_fill_aux:nn { mantissa } {#1} - \@@_number_process_zero_fill_aux:nn { complex } {#1} - \@@_number_process_zero_fill_aux:nn { exponent } {#1} - } -} -\cs_new_protected:Npn - \@@_number_process_zero_fill_aux:nn #1#2 { - \prop_if_in:NnT \l_@@_number_in_prop { #1 -decimal-marker } - { - \prop_if_in:NnF \l_@@_number_in_prop { #1 - #2 } - { \prop_put:Nnn \l_@@_number_in_prop { #1 - #2 } { 0 } } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -% \begin{macro}{\@@_number_process_zero_to_integer:} -% \begin{macro}{\@@_number_process_zero_to_integer_aux:n} -% Look for a decimal part which is simply zero, and if found delete it. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_process_zero_to_integer: - { - \bool_if:NT \l_@@_zero_decimal_to_integer_bool - { - \@@_number_process_zero_to_integer_aux:n { mantissa } - \@@_number_process_zero_to_integer_aux:n { complex } - } - } -\cs_new_protected:Npn \@@_number_process_zero_to_integer_aux:n #1 +\@ifpackageloaded { physics } { - \prop_get:NnNT \l_@@_number_in_prop { #1 -decimal } \l_@@_tmpa_tl + \msg_new:nnn { siunitx } { physics-pkg } { - \bool_set_true:N \l_@@_tmp_bool - \tl_map_inline:Nn \l_@@_tmpa_tl - { - \str_if_eq:nnF {##1} { 0 } - { - \bool_set_false:N \l_@@_tmp_bool - \tl_map_break: - } - } - \bool_if:NT \l_@@_tmp_bool - { - \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal } - \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal-marker } - } + Detected~the~"physics"~package: \\ + Omitting~definition~of~\token_to_str:N \qty. } + \msg_warning:nn { siunitx } { physics-pkg } + \use_none:nnnn } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_number_exp_to_prefix:} -% This function is a bit awkward, as it essentially cuts across the -% unit processor. The idea here is first to recover the numerical exponent, -% and sign if there is one. The earlier formatting run will have reset the -% total number of units to zero, so that has to be recovered before -% doing the format a second time. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_exp_to_prefix: - { - \prop_set_eq:NN \l_@@_unit_prop \l_@@_unit_saved_prop - \prop_get:NnNT \l_@@_number_in_prop { exponent-integer } - \l_@@_tmpa_tl - { - \prop_get:NnNT \l_@@_number_in_prop { exponent-sign } - \l_@@_tmpb_tl - { \tl_put_left:NV \l_@@_tmpa_tl \l_@@_tmpb_tl } - \prop_if_in:NnT \l_@@_unit_prop { per-1 } - { - \tl_set:Nx \l_@@_tmpa_tl - { \int_eval:n { - \l_@@_tmpa_tl } } - } - \prop_get:NnNT \l_@@_unit_prop { prefix-1 } \l_@@_tmpb_tl - { - \prop_remove:Nn \l_@@_unit_prop { prefix-1 } - \prop_remove:Nn \l_@@_unit_prop { prefix-symbol-1 } - \prop_get:NVN \l_@@_prefix_forward_prop \l_@@_tmpb_tl - \l_@@_tmpb_tl - \tl_set:Nx \l_@@_tmpa_tl - { \int_eval:n { \l_@@_tmpa_tl + \l_@@_tmpb_tl } } - } - \prop_get:NnNT \l_@@_unit_prop { power-1 } \l_@@_tmpb_tl - { - \tl_set:Nx \l_@@_tmpa_tl - { \int_eval:n { \l_@@_tmpa_tl / \l_@@_tmpb_tl } } - } - \prop_get:NVNTF \l_@@_prefix_reverse_prop \l_@@_tmpa_tl - \l_@@_tmpb_tl - { - \prop_remove:Nn \l_@@_number_in_prop { exponent } - \use:c - { - @@_ \exp_after:wN \token_to_str:N \l_@@_tmpb_tl - _function:w - } - \prop_get:NnN \l_@@_unit_prop { total-units } \l_@@_tmpa_tl - \int_set:Nn \l_@@_unit_int \l_@@_tmpa_tl - \cs_set_eq:NN \@@_pm: \pm - \@@_unit_format: - \cs_set_eq:NN \pm \@@_pm: - } - { - \msg_error:nnx { siunitx } { non-convertible-exponent } - { \l_@@_tmpa_tl } - } - } - } -% \end{macrocode} -% \end{macro} -% -%\subsection{Formatting numbers for output} -% -% Getting numbers ready for printing requires the reconstruction of the -% number from the various parts processed earlier. Spaces and brackets -% are added back into the main numbers, as the various parts are also -% correctly formatted. The difference between the \texttt{in} and -% \texttt{out} store is that the later can include formatting such as -% hard spaces. -% -%\begin{macro}{\l_@@_number_out_prop} -% Like the \texttt{in} version! -% \begin{macrocode} -\prop_new:N \l_@@_number_out_prop -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_group_sep_tl , -% \l_@@_output_decimal_tl -%} -% A couple of variables are declared here, as they need a little more -% work than just storage. -% \begin{macrocode} -\tl_new:N \l_@@_group_sep_tl -\tl_new:N \l_@@_output_decimal_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_complex_after_bool} -% A setting for where complex numbers go. -% \begin{macrocode} -\bool_new:N \l_@@_complex_after_bool -% \end{macrocode} -%\end{macro} -% -% \begin{variable} -% {\l_@@_group_decimal_bool, \l_@@_group_integer_bool} -% Used for grouping digits. -% \begin{macrocode} -\bool_new:N \l_@@_group_decimal_bool -\bool_new:N \l_@@_group_integer_bool -% \end{macrocode} -% \end{variable} -% -%\begin{macro}{ -% \l_@@_negative_bracket_bool , -% \l_@@_brackets_bool , -% \l_@@_bracket_close_tl , -% \l_@@_output_complex_copy_bool , -% \l_@@_output_decimal_copy_bool , -% \l_@@_exponent_base_tl , -% \l_@@_exponent_product_tl , -% \l_@@_group_min_int , -% \l_@@_negative_color_tl , -% \l_@@_bracket_open_tl , -% \l_@@_output_uncert_close_tl , -% \l_@@_output_complex_tl , -% \l_@@_output_exponent_tl , -% \l_@@_output_uncert_open_tl , -% \l_@@_uncert_sep_bool , -% \l_@@_tight_bool , -% \l_@@_uncert_sep_tl -%} -% Lots of settings, some used only for numbers, some more widely. -% \begin{macrocode} -\keys_define:nn { siunitx } { - bracket-negative-numbers .bool_set:N = - \l_@@_negative_bracket_bool , - bracket-numbers .bool_set:N = \l_@@_brackets_bool, - close-bracket .tl_set:N = \l_@@_bracket_close_tl, - complex-root-position .choice:, - complex-root-position - / after-number .code:n = - { \bool_set_true:N \l_@@_complex_after_bool } , - complex-root-position - / before-number .code:n = - { \bool_set_false:N \l_@@_complex_after_bool } , - copy-complex-root .bool_set:N = - \l_@@_output_complex_copy_bool, - copy-decimal-marker .bool_set:N = - \l_@@_output_decimal_copy_bool, - exponent-base .tl_set:N = \l_@@_exponent_base_tl, - exponent-product .tl_set:N = - \l_@@_exponent_product_tl, - group-decimal-digits .meta:n = { group-digits = decimal }, - group-digits .choice: , - group-digits / - decimal .code:n = - { - \bool_set_true:N \l_@@_group_decimal_bool - \bool_set_false:N \l_@@_group_integer_bool - }, - group-digits / - false .code:n = - { - \bool_set_false:N \l_@@_group_decimal_bool - \bool_set_false:N \l_@@_group_integer_bool - }, - group-digits / - integer .code:n = - { - \bool_set_false:N \l_@@_group_decimal_bool - \bool_set_true:N \l_@@_group_integer_bool - }, - group-digits / - true .code:n = - { - \bool_set_true:N \l_@@_group_decimal_bool - \bool_set_true:N \l_@@_group_integer_bool - }, - group-digits .default:n = true , - group-four-digits .choice:, - group-four-digits / - false .meta:n = { group-minimum-digits = 5 }, - group-four-digits / - true .meta:n = { group-minimum-digits = 4 }, - group-four-digits .default:n = true, - group-integer-digits .meta:n = { group-digits = integer }, - group-minimum-digits .int_set:N = \l_@@_group_min_int, - group-separator .code:n = - { \tl_set:Nn \l_@@_group_sep_tl { {#1} } }, - negative-color .tl_set:N = \l_@@_negative_color_tl, - open-bracket .tl_set:N = \l_@@_bracket_open_tl, - output-close-uncertainty .tl_set:N = - \l_@@_output_uncert_close_tl, - output-complex-root .tl_set:N = \l_@@_output_complex_tl , - output-decimal-marker .code:n = - { \tl_set:Nn \l_@@_output_decimal_tl { {#1} } }, - output-exponent-marker .tl_set:N = \l_@@_output_exponent_tl, - output-open-uncertainty .tl_set:N = - \l_@@_output_uncert_open_tl, - separate-uncertainty .bool_set:N = \l_@@_uncert_sep_bool, - tight-spacing .bool_set:N = \l_@@_tight_bool, - uncertainty-separator .tl_set:N = \l_@@_uncert_sep_tl, -} -\keys_set:nn { siunitx } - { - bracket-numbers = true , % ( - close-bracket = ) , - complex-root-position = after-number , - copy-decimal-marker = false , - exponent-base = 10 , - exponent-product = \times , - group-digits = true , - group-minimum-digits = 5 , - group-separator = \, , - open-bracket = ( , % ) ( - output-close-uncertainty = ) , - output-complex-root = \ensuremath { \mathrm { i } } , - output-decimal-marker = . , - output-open-uncertainty = ( % ) - } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_format:} -% The master control function for formatting output: the usual set up. -% The number is put back together in stages. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format: { - \prop_if_empty:NF \l_@@_number_in_prop - { - \prop_clear:N \l_@@_number_out_prop - \@@_number_format_reassemble: - \@@_number_format_complex: - \@@_number_format_sign:n { mantissa } - \@@_number_format_sign:n { exponent } - \@@_number_format_relation: - \@@_number_format_color: - \@@_number_format_final: - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_format_brackets:n} -%\begin{macro}{\@@_number_format_brackets_aux:n} -% There are various points at which brackets might be added to -% avoid ambiguity. The function here adds the appropriate tokens -% around whatever is in the supplied named store. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_brackets:n #1 { - \bool_if:NT \l_@@_brackets_bool - { - \prop_if_in:NnT \l_@@_number_out_prop { #1 -bracket } - { - \@@_number_format_brackets_aux:n {#1} - \prop_remove:Nn \l_@@_number_out_prop { #1 -bracket } - } - } -} -\cs_new_protected:Npn \@@_number_format_brackets_aux:n #1 { - \prop_get:NnNF \l_@@_number_out_prop { #1 -result } - \l_@@_tmpa_tl - { - \prop_get:NnN \l_@@_number_out_prop {#1} \l_@@_tmpa_tl - } - \tl_put_left:NV \l_@@_tmpa_tl \l_@@_bracket_open_tl - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_bracket_close_tl - \str_if_eq:nnTF {#1} { result } - { \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpa_tl } - { - \prop_put:NnV \l_@@_number_out_prop { #1 -result } - \l_@@_tmpa_tl - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_format_color:} -%\begin{macro}{\@@_number_format_color_aux:n} -% If the mantissa is negative, then any colour for output might change. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_color: { - \tl_if_empty:NF \l_@@_negative_color_tl - { - \@@_number_format_color_aux:n { mantissa-sign } - \@@_number_format_color_aux:n { sign } - } -} -\cs_new_protected:Npn \@@_number_format_color_aux:n #1 { - \prop_get:NnNT \l_@@_number_in_prop {#1} \l_@@_tmpa_tl - { - \str_if_eq:VnT \l_@@_tmpa_tl { - } - { - \prop_put:NnV \l_@@_number_out_prop { color } - \l_@@_negative_color_tl - } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_format_complex:} -%\begin{macro}{ -% \@@_number_format_complex_aux:n , -% \@@_number_format_complex_aux: -%} -% The real and complex parts of each number are reassembled, with -% brackets if needed. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_complex: { - \prop_if_in:NnT \l_@@_number_in_prop { complex-root } - { - \prop_if_in:NnTF \l_@@_number_out_prop { complex } - { - \@@_number_format_brackets:n { complex } - \@@_number_format_complex_aux:n { complex } - \@@_number_format_complex_aux:n { complex-result } - \prop_if_in:NnT \l_@@_number_out_prop - { complex-uncertainty } - { - \@@_number_format_complex_aux:n - { complex-uncertainty } - } - } - { - \prop_put:NnV \l_@@_number_out_prop { complex } - \l_@@_output_complex_tl - } - \@@_number_format_join_complex: - } -} -\cs_new_protected:Npn \@@_number_format_complex_aux:n #1 { - \bool_if:NTF \l_@@_output_complex_copy_bool - { - \prop_get:NnN \l_@@_number_in_prop { complex-root } - \l_@@_tmpa_tl - } - { \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_output_complex_tl } - \prop_get:NnN \l_@@_number_out_prop {#1} \l_@@_tmpb_tl - \bool_if:NTF \l_@@_complex_after_bool - { \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpa_tl } - { \tl_put_left:NV \l_@@_tmpb_tl \l_@@_tmpa_tl } - \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpb_tl -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_format_copy:n , -% \@@_number_format_copy:nn -%} -% Just copy across. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_copy:n #1 { - \prop_get:NnN \l_@@_number_in_prop {#1} \l_@@_tmpa_tl - \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpa_tl -} -\cs_new_protected:Npn \@@_number_format_copy:nn #1#2 { - \prop_get:NnN \l_@@_number_out_prop {#1} \l_@@_tmpa_tl - \prop_put:NnV \l_@@_number_out_prop {#2} \l_@@_tmpa_tl -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_format_final:} -% For numbers which do not contain an exponent, the mantissa result is -% simply copied to the final output position. On the other hand, for -% exponents there are further checks, which are handed off to dedicated -% functions. There is also a check for complex numbers with no real -% part, which needs to be \enquote{copied} to the standard result -% slot. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_final: { - \prop_if_in:NnT \l_@@_number_out_prop { complex } - { - \prop_if_in:NnF \l_@@_number_out_prop { mantissa-result } - { - \@@_number_format_copy:nn { complex } - { mantissa-result } - } - } - \prop_if_in:NnTF \l_@@_number_out_prop { exponent } - { - \@@_number_format_final_exponent: - \prop_if_in:NnTF \l_@@_number_out_prop { mantissa-result } - { \@@_number_format_final_combined: } - { \@@_number_format_final_exponent_only: } - } - { \@@_number_format_copy:nn { mantissa-result } { result } } - \prop_if_in:NnT \l_@@_number_out_prop { mantissa-bracket } - { - \prop_put:Nnn \l_@@_number_out_prop { result-bracket } - { true } - \prop_remove:Nn \l_@@_number_out_prop { mantissa-bracket } - } - \prop_if_in:NnT \l_@@_number_out_prop { comparator } - { - \@@_number_format_brackets:n { result } - \prop_get:NnN \l_@@_number_out_prop { comparator } - \l_@@_tmpa_tl - \prop_get:NnN \l_@@_number_out_prop { result } - \l_@@_tmpb_tl - \tl_set:Nx \l_@@_tmpa_tl - { - \exp_not:N \mathord - \exp_not:V \l_@@_tmpa_tl - \exp_not:V \l_@@_tmpb_tl - } - \prop_put:NnV \l_@@_number_out_prop { result } - \l_@@_tmpa_tl - } -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_number_format_final_combined:} -% When there is both a mantissa and an exponent, the mantissa is -% combined with the product sign before adding the exponent part on. -% The combined result is then stored. The marker -% \texttt{result-bracket-exponent} indicates that the number needs -% brackets due to the exponent part, but not in other cases. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_final_combined: { - \@@_number_format_brackets:n { mantissa } - \prop_get:NnN \l_@@_number_out_prop { mantissa-result } - \l_@@_tmpa_tl - \tl_if_empty:NT \l_@@_output_exponent_tl - { - \tl_put_right:Nx \l_@@_tmpa_tl - { - \exp_not:N \ensuremath - { - \bool_if:NTF \l_@@_tight_bool - { { \exp_not:V \l_@@_exponent_product_tl } } - { { } \exp_not:V \l_@@_exponent_product_tl { } } - } - } - } - \prop_get:NnN \l_@@_number_out_prop { exponent-result } - \l_@@_tmpb_tl - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \prop_put:NnV \l_@@_number_out_prop { result } - \l_@@_tmpa_tl - \prop_put:Nnn \l_@@_number_out_prop - { result-bracket-exponent } { true } -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_number_format_final_exponent:} -% When there is an exponent, the base always needs to be added to the -% front of the number itself. The number must be superscripted, of -% course. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_final_exponent: { - \prop_get:NnN \l_@@_number_out_prop { exponent } - \l_@@_tmpa_tl - \tl_if_empty:NTF \l_@@_output_exponent_tl - { - \tl_set:Nx \l_@@_tmpa_tl - { ^ { \exp_not:V \l_@@_tmpa_tl } } - \tl_put_left:NV \l_@@_tmpa_tl \l_@@_exponent_base_tl - } - { - \tl_set:Nx \l_@@_tmpa_tl - { - \exp_not:V \l_@@_output_exponent_tl - \exp_not:N \mathord - \exp_not:V \l_@@_tmpa_tl - } - } - \prop_put:NnV \l_@@_number_out_prop { exponent-result } - \l_@@_tmpa_tl -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_number_format_final_exponent_only:} -% When there is only an exponent, a check must be made for a -% sign in the mantissa part. If there is one, it is copied across. -% \begin{macrocode} -\cs_new_protected:Npn - \@@_number_format_final_exponent_only: { - \prop_get:NnNT \l_@@_number_in_prop { mantissa-sign } - \l_@@_tmpa_tl - { - \prop_get:NnN \l_@@_number_out_prop { exponent-result } - \l_@@_tmpb_tl - \@@_tl_put_left_math:NV \l_@@_tmpb_tl - \l_@@_tmpa_tl - \prop_put:NnV \l_@@_number_out_prop { exponent-result } - \l_@@_tmpb_tl - } - \@@_number_format_copy:nn { exponent-result } { result } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_format_group:n} -%\begin{macro}{\@@_number_format_group_aux:nn} -% Grouping digits only happens if there are no symbols in the input, and -% of course if grouping has been requested. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_group:n #1 { - \@@_number_format_group_aux:nn {#1} { integer } - \@@_number_format_group_aux:nn {#1} { decimal } - \prop_if_in:NnTF \l_@@_number_out_prop { #1 -integer } - { \@@_number_format_copy:nn { #1 -integer } {#1} } - { \tl_clear:N \l_@@_tmpa_tl } - \prop_get:NnNT \l_@@_number_in_prop { #1 -decimal-marker } - \l_@@_tmpb_tl - { - \bool_if:NTF \l_@@_output_decimal_copy_bool - { \tl_set:Nx \l_@@_tmpb_tl { { \l_@@_tmpb_tl } } } - { - \tl_set_eq:NN \l_@@_tmpb_tl - \l_@@_output_decimal_tl - } - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \prop_put:NnV \l_@@_number_out_prop { #1 -decimal-marker } - \l_@@_tmpb_tl - \prop_get:NnNF \l_@@_number_out_prop { #1 -decimal } - \l_@@_tmpb_tl - { \tl_clear:N \l_@@_tmpb_tl } - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpa_tl - } -} -\cs_new_protected:Npn \@@_number_format_group_aux:nn #1#2 { - \prop_if_in:NnT \l_@@_number_in_prop { #1 - #2 } - { - \bool_if:cTF { l_@@_group_ #2 _bool } - { \@@_number_format_group:nn {#1} {#2} } - { \@@_number_format_copy:n { #1 - #2 } } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% \begin{macro}{\@@_number_format_group:nn} -% The idea here is that grouping is only needed for numbers with sufficient -% digits: this is done simply by counting up all of the digits. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_group:nn #1#2 + { } +\NewDocumentCommand \qty { O { } m > { \TrimSpaces } m } { - \prop_get:NnN \l_@@_number_in_prop { #1 - #2 } \l_@@_tmpa_tl - \int_compare:nNnTF - { \tl_count:N \l_@@_tmpa_tl } < \l_@@_group_min_int - { \@@_number_format_copy:n { #1 - #2 } } - { - \tl_clear:N \l_@@_tmpb_tl - \use:c { @@_number_format_group_ #2 : } - \prop_put:NnV \l_@@_number_out_prop { #1 - #2 } \l_@@_tmpb_tl - } + \mode_leave_vertical: + \group_begin: + \siunitx_unit_options_apply:n {#3} + \keys_set:nn { siunitx } {#1} + \siunitx_quantity:nn {#2} {#3} + \group_end: } % \end{macrocode} % \end{macro} -%\begin{macro}{\@@_number_format_group_decimal:} -%\begin{macro}{\@@_number_format_group_decimal_aux:} -% Using the \enquote{keep everything on the stack} approach, relatively -% simple recursion is needed. This trick is taken more or less directly -% from \pkg{numprint}. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_group_decimal: { - \tl_if_empty:NF \l_@@_tmpa_tl - { - \exp_after:wN \@@_number_format_group_decimal_aux:NNNN - \l_@@_tmpa_tl { } { } { } - } -} -\cs_new_protected:Npn \@@_number_format_group_decimal_aux:NNNN - #1#2#3#4 { - \tl_if_empty:nTF {#2} - { \tl_put_right:Nn \l_@@_tmpb_tl {#1} } - { - \tl_if_empty:nTF {#3} - { \tl_put_right:Nn \l_@@_tmpb_tl { #1 #2 } } - { - \tl_put_right:Nn \l_@@_tmpb_tl { #1 #2 #3 } - \tl_if_empty:nF {#4} - { - \tl_put_right:NV \l_@@_tmpb_tl \l_@@_group_sep_tl - \@@_number_format_group_decimal_aux:NNNN #4 - } - } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\begin{macro}{\@@_number_format_group_integer:} -%\begin{macro}{ -% \@@_number_format_group_integer_setup:n , -% \@@_number_format_group_integer_setup:V , -% \@@_number_format_group_integer_setup_aux:NNNN , -% \@@_number_format_group_integer_aux:NNNN -%} -% By keeping everything on the stack, recursion can occur quite -% efficiently here. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_group_integer: { - \tl_if_empty:NF \l_@@_tmpa_tl - { - \@@_number_format_group_integer_setup:V \l_@@_tmpa_tl - } -} -\cs_new_protected:Npn \@@_number_format_group_integer_setup:n #1 { - \@@_number_format_group_integer_setup_aux:NNNN - { } #1 { } { } { } -} -\cs_generate_variant:Nn \@@_number_format_group_integer_setup:n - { V } -\cs_new_protected:Npn - \@@_number_format_group_integer_setup_aux:NNNN #1#2#3#4 { - \tl_if_empty:nTF {#2} - { \@@_number_format_group_integer_aux:NNNN #1 \q_nil } - { - \tl_if_empty:nTF {#3} - { - \@@_number_format_group_integer_aux:NNNN { } { } #1#2 - \q_nil - } - { - \tl_if_empty:nTF {#4} - { - \@@_number_format_group_integer_aux:NNNN { } #1#2#3 - \q_nil - } - { - \@@_number_format_group_integer_setup_aux:NNNN - {#1#2#3#4} - } - } - } -} -\cs_new_protected:Npn - \@@_number_format_group_integer_aux:NNNN #1#2#3#4 { - \tl_put_right:Nn \l_@@_tmpb_tl {#1#2#3} - \quark_if_nil:nF {#4} - { - \tl_put_right:NV \l_@@_tmpb_tl \l_@@_group_sep_tl - \@@_number_format_group_integer_aux:NNNN #4 - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_format_join_complex:} -% For adding the complex part to the main part of a number. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_join_complex: { - \@@_number_format_sign_complex: - \prop_if_in:NnT \l_@@_number_out_prop { mantissa } - { - \@@_number_format_brackets:n { mantissa } - \prop_get:NnN \l_@@_number_out_prop { mantissa-result } - \l_@@_tmpa_tl - \prop_get:NnNF \l_@@_number_out_prop { complex-result } - \l_@@_tmpb_tl - { - \prop_get:NnN \l_@@_number_out_prop { complex } - \l_@@_tmpb_tl - } - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \prop_put:NnV \l_@@_number_out_prop { mantissa-result } - \l_@@_tmpa_tl - \prop_put:Nnn \l_@@_number_out_prop { mantissa-bracket } - { true } - } -} -% \end{macrocode} -%\end{macro} % -%\begin{macro}{ -% \@@_number_format_join_uncert: , -% \@@_number_format_join_uncert:n -%} -%\begin{macro}{\@@_number_format_join_uncert_pm:N} -% For adding separated uncertainties to the main part of a number. +% \begin{macro}{\ang, \num, \unit} +% All of a standard form: start a paragraph (if required), set local +% key values, do the formatting, print the result. % \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_join_uncert: { - \@@_number_format_join_uncert:n { mantissa } - \@@_number_format_join_uncert:n { complex } -} -\cs_new_protected:Npn \@@_number_format_join_uncert:n #1 { - \prop_get:NnNT \l_@@_number_out_prop {#1} - \l_@@_tmpa_tl - { - \prop_get:NnNTF \l_@@_number_out_prop { #1 -uncertainty } - \l_@@_tmpb_tl - { - \bool_if:NT \l_@@_uncert_sep_bool - { \@@_number_format_join_uncert_pm:N \l_@@_tmpb_tl } - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \prop_put:NnV \l_@@_number_out_prop { #1 -result } - \l_@@_tmpa_tl - \prop_put:Nnn \l_@@_number_out_prop { #1 -bracket } - { true } - } - { \@@_number_format_copy:nn {#1} { #1 -result } } - } -} -\cs_new_protected:Npn \@@_number_format_join_uncert_pm:N #1 +\NewDocumentCommand \ang { O { } > { \SplitArgument { 2 } { ; } } m } { - \bool_if:NTF \l_@@_tight_bool - { \tl_put_left:Nn #1 { \ensuremath { { \pm } } } } - { \tl_put_left:Nn #1 { \ensuremath { { } \pm { } } } } + \mode_leave_vertical: + \group_begin: + \keys_set:nn { siunitx } {#1} + \@@_angle:nnn #2 + \group_end: } -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_format_reassemble:} -% The integer, decimal and any non-separated uncertainty parts are -% put back together. This gives a \enquote{minimal} unit which cannot -% need any brackets or repeated units (if applicable). If the -% uncertainty is separate, it is stored at this stage pending later -% re-attachment. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_reassemble: { - \prop_if_in:NnT \l_@@_number_in_prop { mantissa } - { - \@@_number_format_group:n { mantissa } - \@@_number_format_uncertainty:n { mantissa } - } - \prop_if_in:NnT \l_@@_number_in_prop { complex } - { - \@@_number_format_group:n { complex } - \@@_number_format_uncertainty:n { complex } - } - \prop_if_in:NnT \l_@@_number_in_prop { exponent } - { \@@_number_format_group:n { exponent } } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_format_relation:} -% A simple check and copy operation for a relation: this will still need -% to be added to the result, of course. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_relation: { - \prop_get:NnNT \l_@@_number_in_prop { comparator } - \l_@@_tmpa_tl - { - \tl_set:Nx \l_@@_tmpa_tl - { - \exp_not:N \ensuremath - { \exp_not:V \l_@@_tmpa_tl } - } - \prop_put:NnV \l_@@_number_out_prop { comparator } - \l_@@_tmpa_tl - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_format_sign:n , -% \@@_number_format_sign_complex: -%} -%\begin{macro}{ -% \@@_number_format_sign_aux:n , -% \@@_number_format_sign_negative_brackets:n , -% \@@_number_format_sign_complex:n -%} -% Some simple sign manipulation: for tight signs, a little shuffling. -% In the complex number case, there is a need for a correction to get -% the right formatting in text mode. For speed reasons, this is done in -% a separate function. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_sign:n #1 { - \prop_if_in:NnT \l_@@_number_out_prop {#1} - { - \prop_get:NnNT \l_@@_number_in_prop { #1 -sign } - \l_@@_tmpa_tl - { - \bool_if:NTF \l_@@_negative_bracket_bool - { - \str_if_eq:VnTF \l_@@_tmpa_tl { - } - { \@@_number_format_sign_negative_brackets:n {#1} } - { \@@_number_format_sign_aux:n {#1} } - } - { \@@_number_format_sign_aux:n {#1} } - } - } -} -\cs_new_protected:Npn \@@_number_format_sign_aux:n #1 { - \tl_clear:N \l_@@_tmpb_tl - \tl_put_left:NV \l_@@_tmpb_tl \l_@@_tmpa_tl - \prop_put:NnV \l_@@_number_out_prop { #1 -sign } - \l_@@_tmpb_tl - \prop_get:NnN \l_@@_number_out_prop {#1} \l_@@_tmpa_tl - \tl_put_left:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpa_tl - \prop_get:NnNT \l_@@_number_out_prop { #1 -result } - \l_@@_tmpa_tl - { - \tl_put_left:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \prop_put:NnV \l_@@_number_out_prop { #1 -result } - \l_@@_tmpa_tl - } -} -\cs_new_protected:Npn - \@@_number_format_sign_negative_brackets:n #1 +\NewDocumentCommand \num { O { } m } { - \@@_number_format_brackets_aux:n {#1} - \prop_get:NnNT \l_@@_number_out_prop { #1 } - \l_@@_tmpa_tl - { - \tl_put_left:NV \l_@@_tmpa_tl \l_@@_bracket_open_tl - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_bracket_close_tl - \prop_put:NnV \l_@@_number_out_prop { #1 } - \l_@@_tmpa_tl - } + \mode_leave_vertical: + \group_begin: + \keys_set:nn { siunitx } {#1} + \siunitx_number_format:nN {#2} \l_@@_tmp_tl + \siunitx_print_number:V \l_@@_tmp_tl + \group_end: } -\cs_new_protected:Npn \@@_number_format_sign_complex: { - \@@_number_format_sign_complex:n { complex } - \@@_number_format_sign_complex:n { complex-result } -} -\cs_new_protected:Npn \@@_number_format_sign_complex:n #1 { - \prop_if_in:NnT \l_@@_number_out_prop {#1} - { - \prop_get:NnNT \l_@@_number_in_prop { complex-sign } - \l_@@_tmpa_tl - { - \bool_if:NTF \l_@@_tight_bool - { - \tl_set:Nx \l_@@_tmpa_tl - { \exp_not:N \mathord \exp_not:V \l_@@_tmpa_tl } - } - { - \prop_if_in:NnT \l_@@_number_out_prop { mantissa } - { - \tl_set:Nx \l_@@_tmpa_tl - { { } \exp_not:V \l_@@_tmpa_tl { } } - } - } - \tl_clear:N \l_@@_tmpb_tl - \tl_put_left:NV \l_@@_tmpb_tl \l_@@_tmpa_tl - \prop_put:NnV \l_@@_number_out_prop { complex-sign } - \l_@@_tmpb_tl - \prop_get:NnN \l_@@_number_out_prop {#1} - \l_@@_tmpa_tl - \tl_put_left:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \prop_put:NnV \l_@@_number_out_prop {#1} - \l_@@_tmpa_tl - } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_format_uncertainty:n} -%\begin{macro}{ -% \@@_number_format_uncertainty_joined:n , -% \@@_number_format_uncertainty_sep:n -%} -% Uncertainty output varies depending on whether there is a need to -% separate the error form the number in the output. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_format_uncertainty:n #1 { - \prop_if_in:NnTF \l_@@_number_in_prop { #1 -uncertainty } - { - \bool_if:NTF \l_@@_uncert_sep_bool - { \@@_number_format_uncertainty_sep:n {#1} } - { \@@_number_format_uncertainty_joined:n {#1} } - \@@_number_format_join_uncert: - } - { \@@_number_format_copy:nn {#1} { #1 -result } } -} -\cs_new_protected:Npn - \@@_number_format_uncertainty_joined:n #1 { - \prop_get:NnN \l_@@_number_in_prop { #1 -uncertainty } - \l_@@_tmpa_tl - \prop_remove:Nn \l_@@_number_in_prop { #1 -uncertainty } - \tl_put_left:NV \l_@@_tmpa_tl \l_@@_output_uncert_open_tl - \tl_put_left:NV \l_@@_tmpa_tl \l_@@_uncert_sep_tl - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_output_uncert_close_tl - \prop_get:NnN \l_@@_number_out_prop {#1} \l_@@_tmpb_tl - \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpa_tl - \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpb_tl -} -\cs_new_protected:Npn - \@@_number_format_uncertainty_sep:n #1 { - \prop_if_in:NnT \l_@@_number_out_prop { #1 -integer } - { - \prop_if_in:NnF \l_@@_number_out_prop - { #1 -uncertainty-integer } - { - \prop_put:Nnn \l_@@_number_out_prop - { #1 -uncertainty-integer } { 0 } - } - } - \@@_number_format_group:n { #1 -uncertainty } - \prop_put:NnV \l_@@_number_out_prop { #1 -uncertainty } - \l_@@_tmpa_tl -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Numerical output} -% -% The outer level of number processing for actually printing things. -% -%\begin{macro}{ -% \l_@@_number_out_tl , -% \l_@@_number_out_saved_tl -%} -% The final result, plus a version for loops. -% \begin{macrocode} -\tl_new:N \l_@@_number_out_tl -\tl_new:N \l_@@_number_out_saved_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_number_fraction_tl} -% Fractions need to be build separately, so that there is no problem -% with stack order. -% \begin{macrocode} -\tl_new:N \l_@@_number_fraction_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_number_compound_bool} -% To help with brackets. -% \begin{macrocode} -\bool_new:N \l_@@_number_compound_bool -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_quotient_mode_tl} -% The action for quotients is stored as a token list variable. -% \begin{macrocode} -\tl_new:N \l_@@_quotient_mode_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_fraction:nn} -% The function used for fractions should be stored here. -% \begin{macrocode} -\cs_new_protected:Npn \@@_fraction:nn { } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_output_quotient_tl , -% \l_siunix_number_parse_bool -%} -% Some options related to numbers at the output stage. -% \begin{macrocode} -\keys_define:nn { siunitx } { - fraction-function .code:n = - { \cs_set_protected:Npn \@@_fraction:nn {#1} }, - output-product .tl_set:N = \l_@@_output_product_tl, - output-quotient .tl_set:N = \l_@@_output_quotient_tl, - parse-numbers .bool_set:N = \l_@@_number_parse_bool, - quotient-mode .choice:, - quotient-mode / fraction .code:n = - { \tl_set:Nn \l_@@_quotient_mode_tl { fraction } }, - quotient-mode / symbol .code:n = - { \tl_set:Nn \l_@@_quotient_mode_tl { symbol } }, -} -\keys_set:nn { siunitx } { - fraction-function = \frac , - output-product = \times , - output-quotient = / , - parse-numbers = true , - quotient-mode = symbol -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_output:n , -% \@@_number_output:V -%} -% The number output system simply sets up for the combined number and -% unit system. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output:n #1 { - \tl_clear:N \l_@@_unit_tl - \tl_clear:N \l_@@_preunit_tl - \@@_combined_output:n {#1} -} -\cs_generate_variant:Nn \@@_number_output:n { V } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_output_bracket:} -% Compound numbers may need brackets adding. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_bracket: { - \bool_if:NF \l_@@_error_bool - { - \bool_if:NT \l_@@_number_compound_bool - { \@@_number_format_brackets:n { result } } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_output_color:} -% If a colour needs to be set, it is recovered here and put into the -% appropriate place. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_color: { - \prop_if_in:NnT \l_@@_number_out_prop { color } - { - \prop_get:NnN \l_@@_number_out_prop { color } - \l_@@_number_color_tl - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_number_output_parse:n , -% \@@_number_output_parse:V -%} -%\begin{macro}{\@@_number_output_parse_aux:} -% The parsing system just has to check if there are multiple parts to -% worry about. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_parse:n #1 { - \@@_number_preprocess:n {#1} - \bool_if:NF \l_@@_error_bool - { - \tl_if_empty:NTF \l_@@_number_multi_tl - { \@@_number_output_parse_aux: } - { - \use:c - { @@_number_output_ \l_@@_number_multi_tl : } - } - } -} -\cs_generate_variant:Nn \@@_number_output_parse:n { V } -% \end{macrocode} -% There are a few additional tests for printing partwise, as this is -% only needed if there are brackets to add and these are not due to -% an exponent. The test for an exponent is needed as this must force -% the units to come at the end of the number, and there then have to -% be brackets in the output if there are any separate parts. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_parse_aux: { - \@@_number_in_parse:V \l_@@_number_arg_tl - \bool_if:NF \l_@@_error_bool - { - \@@_number_process: - \@@_number_format: - \@@_number_output_color: - \bool_if:NTF \l_@@_brackets_bool - { \@@_number_output_single: } - { - \prop_if_in:NnTF \l_@@_number_out_prop - { result-bracket } - { \@@_number_output_parts: } - { \@@_number_output_single: } - } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_output_parts:} -%\begin{macro}{ -% \@@_number_output_parts_aux: , -% \@@_number_output_parts_aux:n , -% \@@_number_output_parts_print:n -%} -% Printing numbers by parts is necessary when there are units to -% repeat. That means doing things that have already been done by the -% number formatter again. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_parts: { - \bool_lazy_and:nnTF - { \tl_if_empty_p:N \l_@@_pre_unit_tl } - { \tl_if_empty_p:N \l_@@_unit_tl } - { \@@_number_output_single: } - { \@@_number_output_parts_aux: } -} -\cs_new_protected:Npn \@@_number_output_parts_aux: { - \bool_if:NTF \l_@@_multi_repeat_bool - { - \prop_if_in:NnT \l_@@_number_out_prop { mantissa-result } - { - \@@_number_output_parts_aux:n { mantissa } - \@@_number_output_parts_aux:n { complex } - } - \prop_get:NnNT \l_@@_number_out_prop { exponent-result } - \l_@@_tmpa_tl - { - \prop_if_in:NnT \l_@@_number_out_prop { mantissa-result } - { - \tl_put_left:Nx \l_@@_tmpa_tl - { - \exp_not:N \ensuremath - { - \bool_if:NTF \l_@@_tight_bool - { { \exp_not:V \l_@@_exponent_product_tl } } - { { } \exp_not:V \l_@@_exponent_product_tl { } } - } - } - \prop_put:NnV \l_@@_number_out_prop { exponent } - \l_@@_tmpa_tl - } - \@@_number_output_parts_print:n { exponent } - } - } - { \@@_number_output_single: } -} -\cs_new_protected:Npn \@@_number_output_parts_aux:n #1 { - \prop_if_in:NnT \l_@@_number_out_prop {#1} - { \@@_number_output_parts_print:n {#1} } - \prop_if_in:NnT \l_@@_number_out_prop { #1 -uncertainty } - { - \bool_if:NTF \l_@@_tight_bool - { \@@_print:nn { number } { \ensuremath { { \pm } } } } - { \@@_print:nn { number } { \ensuremath { { } \pm { } } } } - \@@_number_output_parts_print:n { #1 -uncertainty } - } -} -\cs_new_protected:Npn \@@_number_output_parts_print:n #1 { - \@@_unit_output_pre_print: - \prop_get:NnN \l_@@_number_out_prop {#1} \l_@@_tmpa_tl - \@@_print:nV { number } \l_@@_tmpa_tl - \@@_unit_output_print: -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_number_output_product:} -% For products, there may need to be the addition of brackets if there -% are units about. When not repeating units, some work has to be done to -% print everything correctly. The extra group here is necessary -% otherwise looping will delete the units entirely! -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_product: { - \bool_if:NTF \l_@@_product_brackets_bool - { - \bool_lazy_and:nnTF - { \tl_if_empty_p:N \l_@@_pre_unit_tl } - { \tl_if_empty_p:N \l_@@_unit_tl } - { \@@_number_output_product_aux: } - { \@@_number_output_product_brackets: } - } - { - \bool_if:NTF \l_@@_product_repeat_bool - { \@@_number_output_product_aux: } - { - \@@_unit_output_pre_print: - \tl_set_eq:NN \l_@@_unit_saved_tl \l_@@_unit_tl - \tl_clear:N \l_@@_pre_unit_tl - \tl_clear:N \l_@@_unit_tl - \group_begin: - \@@_number_output_product_aux: - \group_end: - \tl_set_eq:NN \l_@@_unit_tl \l_@@_unit_saved_tl - \@@_unit_output_print: - } - } -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_number_output_product_brackets:} -% When printing products that have to be bracketed, there is a need to -% shuffle the units about a bit. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_product_brackets: { - \@@_unit_output_pre_print: - \@@_print:nV { number } \l_@@_bracket_open_tl - \nobreak - \tl_set_eq:NN \l_@@_unit_saved_tl \l_@@_unit_tl - \tl_clear:N \l_@@_pre_unit_tl - \tl_clear:N \l_@@_unit_tl - \@@_number_output_product_aux: - \nobreak - \tl_set_eq:NN \l_@@_unit_tl \l_@@_unit_saved_tl - \@@_print:nV { number } \l_@@_bracket_close_tl - \@@_unit_output_print: -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_number_output_product_aux:} -% Printing the products needs a looping function. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_product_aux: { - \bool_set_true:N \l_@@_number_compound_bool - \@@_number_preprocess:V \l_@@_number_arg_tl - \bool_if:NF \l_@@_error_bool - { - \tl_if_empty:NTF \l_@@_number_multi_tl - { \@@_number_output_parse_aux: } - { \@@_number_output_quotient: } - \tl_if_empty:NF \l_@@_number_next_tl - { - \bool_if:NTF \l_@@_tight_bool - { - \@@_print:nn { number } - { \ensuremath { \l_@@_output_product_tl } } - } - { - \@@_print:nn { number } - { \ensuremath { { } \l_@@_output_product_tl { } } } - } - \@@_number_output_parse:V \l_@@_number_next_tl - } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_output_quotient:} -% For quotients, there are two options. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_quotient: { - \use:c - { @@_number_output_quotient_ \l_@@_quotient_mode_tl : } -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_number_output_quotient_fraction:} -% For fraction output, there are quite a lot of braces to construct, -% unfortunately. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_quotient_fraction: { - \bool_set_false:N \l_@@_number_compound_bool - \@@_number_output_quotient_aux_i: - \tl_set:Nx \l_@@_number_out_tl - { { \exp_not:V \l_@@_number_numerator_tl } } - \tl_set:Nx \l_@@_tmpa_tl - { { \exp_not:V \l_@@_number_denominator_tl } } - \tl_put_right:NV \l_@@_number_out_tl \l_@@_tmpa_tl - \tl_put_left:Nn \l_@@_number_out_tl { \@@_fraction:nn } - \tl_set:Nx \l_@@_number_out_tl - { - \exp_not:N \ensuremath - { \exp_not:V \l_@@_number_out_tl } - } - \@@_number_output_single_aux: -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_number_output_quotient_symbol:} -% If a symbol is used for the division, the build process is less -% complex. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_quotient_symbol: { - \bool_set_true:N \l_@@_number_compound_bool - \@@_number_output_quotient_aux_i: - \tl_set_eq:NN \l_@@_number_out_tl - \l_@@_number_numerator_tl - \tl_put_right:NV \l_@@_number_out_tl \l_@@_output_quotient_tl - \tl_put_right:NV \l_@@_number_out_tl - \l_@@_number_denominator_tl - \@@_number_output_single_aux: -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{ -% \@@_number_output_quotient_aux_i: , -% \@@_number_output_quotient_aux_ii: -%} -% The two parts of the number are parsed and formatted. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_quotient_aux_i: { - \@@_number_in_parse:V \l_@@_number_numerator_tl - \@@_number_output_quotient_aux_ii: - \@@_number_output_color: - \prop_if_in:NnT \l_@@_number_out_prop { complex } - { - \prop_if_in:NnT \l_@@_number_out_prop { mantissa } - { - \prop_put:Nnn \l_@@_number_out_prop - { result-bracket } { true } - \@@_number_format_brackets:n { result } - } - } - \prop_get:NnN \l_@@_number_out_prop { result } - \l_@@_number_numerator_tl - \@@_number_in_parse:V \l_@@_number_denominator_tl - \@@_number_output_quotient_aux_ii: - \prop_if_in:NnT \l_@@_number_out_prop - { result-bracket-exponent } - { - \prop_put:Nnn \l_@@_number_out_prop { result-bracket } - { true } - } - \@@_number_output_bracket: - \prop_get:NnN \l_@@_number_out_prop { result } - \l_@@_number_denominator_tl -} -\cs_new_protected:Npn \@@_number_output_quotient_aux_ii: { - \@@_number_process: - \@@_number_format: -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_number_output_single:} -%\begin{macro}{\@@_number_output_single_aux:} -% Printing a number with no multiple parts is easy. There is a check for -% any units, which if present may force the number to have brackets -% added. there is then simply a short run to print the units and number. -% The test for bracketing numbers does not happen if there is an -% exponent: if there is, any other parts will already be bracketed and -% mathematically there is no need for brackets at this point. -% \begin{macrocode} -\cs_new_protected:Npn \@@_number_output_single: { - \bool_lazy_and:nnF - { \tl_if_empty_p:N \l_@@_pre_unit_tl } - { \tl_if_empty_p:N \l_@@_unit_tl } - { - \prop_if_in:NnF \l_@@_number_out_prop { exponent } - { \@@_number_format_brackets:n { result } } - } - \@@_number_output_bracket: - \prop_get:NnN \l_@@_number_out_prop { result } - \l_@@_number_out_tl - \@@_number_output_single_aux: -} -\cs_new_protected:Npn \@@_number_output_single_aux: { - \@@_unit_output_pre_print: - \quark_if_no_value:NTF \l_@@_number_out_tl - { \tl_clear:N \l_@@_number_unit_product_tl } - { \@@_print:nV { number } \l_@@_number_out_tl } - \@@_unit_output_print: -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Angles} -% -% Angles are a special case of numbers for two reasons. First, there -% is always a unit, which is known in advance. Second, there are two -% possible input syntaxes, "\ang{1.23}" and "\ang{1;2;3}". Both need -% to be handled correctly. -% -%\begin{macro}{ -% \l_@@_angle_degree_space_bool , -% \l_@@_angle_minute_space_bool -%} -% The need for spaces between parts of an arc needs to be accommodated: -% this is achieved by flagging up the need for such spaces using two -% switches. -% \begin{macrocode} -\bool_new:N \l_@@_angle_degree_space_bool -\bool_new:N \l_@@_angle_minute_space_bool -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_angle_marker_box , -% \l_@@_angle_unit_box , -% \l_@@_angle_marker_dim , -% \l_@@_angle_unit_dim -%} -% When creating astronomy-style angles, the decimal marker and angle -% symbol have to be boxed up and measured. -% \begin{macrocode} -\box_new:N \l_@@_angle_marker_box -\box_new:N \l_@@_angle_unit_box -\dim_new:N \l_@@_angle_marker_dim -\dim_new:N \l_@@_angle_unit_dim -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_angle_degree_prop , -% \l_@@_angle_minute_prop , -% \l_@@_angle_second_prop -%} -% As there are potentially three numbers to parse, three properly lists -% are made available to hold the results. This allows the code to be -% generalised, with only the name of the storage area varying. -% \begin{macrocode} -\prop_new:N \l_@@_angle_degree_prop -\prop_new:N \l_@@_angle_minute_prop -\prop_new:N \l_@@_angle_second_prop -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_angle_degree_zero_bool , -% \l_@@_angle_minute_zero_bool , -% \l_@@_angle_second_zero_bool , -% \l_@@_angle_arc_separator_tl , -% \l_@@_angle_astronomy_bool , -% \l_@@_angle_unit_product_tl -%} -% The angle-specific options are created here. -% \begin{macrocode} -\keys_define:nn { siunitx } { - add-arc-degree-zero .bool_set:N = - \l_@@_angle_degree_zero_bool , - add-arc-minute-zero .bool_set:N = - \l_@@_angle_minute_zero_bool , - add-arc-second-zero .bool_set:N = - \l_@@_angle_second_zero_bool , - angle-symbol-over-decimal .bool_set:N = - \l_@@_angle_astronomy_bool , - arc-separator .tl_set:N = - \l_@@_angle_arc_separator_tl , - number-angle-product .tl_set:N = - \l_@@_angle_unit_product_tl , - number-angle-separator .tl_set:N = - \l_@@_angle_unit_product_tl , -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_angle_output:nnn} -%\begin{macro}{\@@_angle_output_aux:nnn} -% The input will have been split up by \pkg{xparse}, and so the various -% possible inputs can be picked up. To keep to a minimal route through -% the code, a decimal angle is simply treated like an arc, but with -% any zero-filling disabled. -% \begin{macrocode} -\cs_new_protected:Npn \@@_angle_output:nnn #1#2#3 { - \@@_angle_init: - \IfNoValueTF {#2} - { - \bool_set_false:N \l_@@_angle_minute_zero_bool - \bool_set_false:N \l_@@_angle_second_zero_bool - \@@_angle_output_aux:nnn {#1} { } { } - } - { - \IfNoValueTF {#3} - { \@@_error:nx { invalid-arc-format } { #1 ; #2 } } - { \@@_angle_output_aux:nnn {#1} {#2} {#3} } - } -} -\cs_new_protected:Npn \@@_angle_output_aux:nnn #1#2#3 { - \tl_if_empty:nTF { #1#2#3 } - { \@@_error:n { empty-arc } } - { - \bool_if:NTF \l_@@_number_parse_bool - { \@@_angle_parse:nnn {#1} {#2} {#3} } - { \@@_angle_direct:nnn {#1} {#2} {#3} } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_angle_init:} -% The usual separation of initial storage resets. -% \begin{macrocode} -\cs_new_protected:Npn \@@_angle_init: { - \bool_set_false:N \l_@@_angle_degree_space_bool - \bool_set_false:N \l_@@_angle_minute_space_bool - \prop_clear:N \l_@@_angle_degree_prop - \prop_clear:N \l_@@_angle_minute_prop - \prop_clear:N \l_@@_angle_second_prop - \tl_clear:N \l_@@_preunit_tl - \tl_set_eq:NN \l_@@_number_unit_product_tl - \l_@@_angle_unit_product_tl - \cs_set_eq:NN \@@_number_in_parse_more:N - \@@_number_in_parse_restricted:N -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_angle_direct:nnn} -%\begin{macro}{ -% \@@_angle_direct_aux_i:nnn , -% \@@_angle_direct_aux_ii:nnn , -% \@@_angle_direct_aux_iii:nnn -%} -% When printing an arc directly, there is still the need to fill in -% any zero values required and to check the spacing is correct. That -% is done using a chain approach, which is easy to implement and -% reasonably clear. -% \begin{macrocode} -\cs_new_protected:Npn \@@_angle_direct:nnn #1 { - \tl_if_empty:nTF {#1} - { - \bool_if:NTF \l_@@_angle_degree_zero_bool - { \@@_angle_direct_aux_i:nnn { 0 } } - { \@@_angle_direct_aux_i:nnn { } } - } - { \@@_angle_direct_aux_i:nnn {#1} } -} -\cs_new_protected:Npn \@@_angle_direct_aux_i:nnn #1#2 { - \tl_if_empty:nTF {#2} - { - \bool_if:NTF \l_@@_angle_minute_zero_bool - { \@@_angle_direct_aux_ii:nnn {#1} { 0 } } - { \@@_angle_direct_aux_ii:nnn {#1} { } } - } - { \@@_angle_direct_aux_ii:nnn {#1} {#2} } -} -\cs_new_protected:Npn \@@_angle_direct_aux_ii:nnn #1#2#3 { - \tl_if_empty:nTF {#3} - { - \bool_if:NTF \l_@@_angle_second_zero_bool - { \@@_angle_direct_aux_iii:nnn {#1} {#2} { 0 } } - { \@@_angle_direct_aux_iii:nnn {#1} {#2} { } } - } - { \@@_angle_direct_aux_iii:nnn {#1} {#2} {#3} } -} -\cs_new_protected:Npn \@@_angle_direct_aux_iii:nnn #1#2#3 { - \tl_if_empty:nF {#1} - { - \tl_if_empty:nF {#2#3} - { \bool_set_true:N \l_@@_angle_degree_space_bool } - } - \tl_if_empty:nF {#2} - { - \tl_if_empty:nF {#3} - { \bool_set_true:N \l_@@_angle_minute_space_bool } - } - \@@_angle_print_direct:nnn {#1} {#2} {#3} -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{ -% \@@_angle_parse:nnn , -% \@@_angle_check_sign: , -% \@@_angle_zero_fill: , -% \@@_angle_sign_shuffle:nn -%} -%\begin{macro}{ -% \@@_angle_parse_aux:nnn , -% \@@_angle_check_sign:n , -% \@@_angle_sign_shuffle_aux:nnn -%} -% Parsing an arc requires a number of stages. First, there is the -% basic conversion of the input numbers into three property lists, -% which will contain the data required. There is then a zero-filling -% step, done here so that signs can be shuffled into the correct places. -% After that, a check to make sure there is only one sign for an arc -% before setting up the inter-part spacing and actually printing. -% \begin{macrocode} -\cs_new_protected:Npn \@@_angle_parse:nnn #1#2#3 { - \@@_angle_parse_aux:nn {#1} { degree } - \@@_angle_parse_aux:nn {#2} { minute } - \@@_angle_parse_aux:nn {#3} { second } - \@@_angle_check_sign: - \@@_angle_zero_fill: - \prop_if_empty:NF \l_@@_angle_degree_prop - { - \prop_if_empty:NF \l_@@_angle_minute_prop - { \bool_set_true:N \l_@@_angle_degree_space_bool } - \prop_if_empty:NF \l_@@_angle_second_prop - { \bool_set_true:N \l_@@_angle_degree_space_bool } - } - \prop_if_empty:NF \l_@@_angle_minute_prop - { - \prop_if_empty:NF \l_@@_angle_second_prop - { \bool_set_true:N \l_@@_angle_minute_space_bool } - } - \@@_angle_print: -} -\cs_new_protected:Npn \@@_angle_parse_aux:nn #1#2 { - \prop_clear:N \l_@@_number_in_prop - \tl_if_empty:nF {#1} - { - \@@_number_in_init: - \@@_number_in_parse_aux:n {#1} - } - \prop_get:NnNT \l_@@_number_in_prop { mantissa-sign-deleted } - \l_@@_tmpa_tl - { - \prop_put:NnV \l_@@_number_in_prop { mantissa-sign } - \l_@@_tmpa_tl - } - \@@_number_process: - \prop_set_eq:cN { l_@@_angle_ #2 _prop } - \l_@@_number_in_prop -} -% \end{macrocode} -% Only the highest-order part of an arc can have a sign. This is checked -% now so that the shuffling code is easier to write. -% \begin{macrocode} -\cs_new_protected:Npn \@@_angle_check_sign: { - \prop_if_empty:NTF \l_@@_angle_degree_prop - { - \prop_if_empty:NF \l_@@_angle_minute_prop - { \@@_angle_check_sign_aux:n { second } } - } - { - \@@_angle_check_sign_aux:n { minute } - \@@_angle_check_sign_aux:n { second } - } -} -\cs_new_protected:Npn \@@_angle_check_sign_aux:n #1 { - \prop_if_in:cnTF { l_@@_angle_ #1 _prop } - { mantissa-sign } - { \msg_error:nn { siunitx } { bad-arc-sign } } - { - \prop_if_in:cnT { l_@@_angle_ #1 _prop } - { mantissa-sign-deleted } - { \msg_error:nn { siunitx } { bad-arc-sign } } - } -} -% \end{macrocode} -% Filling in the zero values is rather awkward as there are signs -% to worry about. There is therefore a shuffle to move them into the -% correct places. -% \begin{macrocode} -\cs_new_protected:Npn \@@_angle_zero_fill: { - \bool_lazy_and:nnT - { \l_@@_angle_second_zero_bool } - { \prop_if_empty_p:N \l_@@_angle_second_prop } - { - \prop_put:Nnn \l_@@_angle_second_prop { mantissa } - { true } - \prop_put:Nnn \l_@@_angle_second_prop { mantissa-integer } - { 0 } - } - \bool_lazy_and:nnT - { \l_@@_angle_minute_zero_bool } - { \prop_if_empty_p:N \l_@@_angle_minute_prop } - { - \prop_put:Nnn \l_@@_angle_minute_prop { mantissa } - { true } - \prop_put:Nnn \l_@@_angle_minute_prop { mantissa-integer } - { 0 } - \@@_angle_sign_shuffle:nn { second } { minute } - } - \bool_lazy_and:nnT - { \l_@@_angle_degree_zero_bool } - { \prop_if_empty_p:N \l_@@_angle_degree_prop } - { - \prop_put:Nnn \l_@@_angle_degree_prop { mantissa } - { true } - \prop_put:Nnn \l_@@_angle_degree_prop { mantissa-integer } - { 0 } - \@@_angle_sign_shuffle:nn { second } { degree } - \@@_angle_sign_shuffle:nn { minute } { degree } - } -} -\cs_new_protected:Npn \@@_angle_sign_shuffle:nn #1#2 { - \@@_angle_sign_shuffle_aux:nnn {#1} {#2} { } - \@@_angle_sign_shuffle_aux:nnn {#1} {#2} { -deleted } -} -\cs_new_protected:Npn \@@_angle_sign_shuffle_aux:nnn - #1#2#3 { - \prop_get:cnN { l_@@_angle_ #1 _prop } { mantissa-sign #3 } - \l_@@_tmpa_tl - \prop_remove:cn { l_@@_angle_ #1 _prop } { mantissa-sign #3 } - \quark_if_no_value:NF \l_@@_tmpa_tl - { - \prop_put:cnV { l_@@_angle_ #2 _prop } { mantissa-sign #3 } - \l_@@_tmpa_tl - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_angle_print:} -%\begin{macro}{\@@_angle_print:nn} -% The standard printing routine examines each part of the arc in turn -% and either does a standard format or calls the special astronomy-style -% routine. There may also be some spaces to add. -% \begin{macrocode} -\cs_new_protected:Npn \@@_angle_print: { - \@@_angle_print_aux:nn { degree } { \SIUnitSymbolDegree } - \bool_if:NT \l_@@_angle_degree_space_bool - { - \nobreak - \l_@@_angle_arc_separator_tl - } - \@@_angle_print_aux:nn { minute } { \SIUnitSymbolArcminute } - \bool_if:NT \l_@@_angle_minute_space_bool - { - \nobreak - \l_@@_angle_arc_separator_tl - } - \@@_angle_print_aux:nn { second } { \SIUnitSymbolArcsecond } -} -\cs_new_protected:Npn \@@_angle_print_aux:nn #1#2 { - \prop_if_empty:cF { l_@@_angle_ #1 _prop } - { - \prop_set_eq:Nc \l_@@_number_in_prop - { l_@@_angle_ #1 _prop } - \tl_set:Nn \l_@@_unit_tl {#2} - \tl_clear:N \l_@@_number_out_tl - \@@_number_format: - \@@_number_output_color: - \bool_if:NTF \l_@@_angle_astronomy_bool - { \@@_angle_print_astronomy: } - { \@@_number_output_single: } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_angle_print_astronomy:} -%\begin{macro}{ -% \@@_angle_print_astronomy_aux: , -% \@@_angle_print_astronomy_aux:n , -% \@@_angle_print_astronomy_marker: , -% \@@_angle_print_astronomy_unit: -%} -% The first check for astronomy-style angles is that there is a decimal -% marker in the current input: if not, the standard method can be used. -% The method for the astronomy-style angle is not straight-forward, so -% needs a little explanation. The integer and decimal parts of the -% number are printed at each end of the function. In the middle is a -% method to centre the unit symbol on the decimal marker. This is done -% by typesetting the two symbols and measuring their respective widths. -% The two are then put into zero-width boxes, which allows them to be -% aligned horizontally centred with no vertical change. The larger -% dimension is then used to reconstruct the appropriate width for the -% final output. There is also a need to allow for the \cs{scriptspace} -% added in after superscripts, which otherwise messes up the -% calculation. -% \begin{macrocode} -\cs_new_protected:Npn \@@_angle_print_astronomy: { - \prop_if_in:NnTF \l_@@_number_in_prop - { mantissa-decimal-marker } - { \@@_angle_print_astronomy_aux: } - { \@@_number_output_single: } -} -\cs_new_protected:Npn \@@_angle_print_astronomy_aux: { - \prop_get:NnNF \l_@@_number_out_prop { mantissa-sign } - \l_@@_tmpa_tl - { \tl_clear:N \l_@@_tmpa_tl } - \prop_get:NnNT \l_@@_number_out_prop { mantissa-integer } - \l_@@_tmpb_tl - { - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \@@_print:nV { number } \l_@@_tmpa_tl - } - \hbox_set:Nn \l_@@_angle_marker_box - { - \@@_print:nn { number } { { \l_@@_output_decimal_tl } } - } - \hbox_set:Nn \l_@@_angle_unit_box - { - \@@_print:nV { unit } \l_@@_unit_tl - \skip_horizontal:n { -\scriptspace } - } - \@@_angle_print_astronomy_aux:n { marker } - \@@_angle_print_astronomy_aux:n { unit } - \hbox_set:Nn \l_@@_angle_marker_box - { - \box_use:N \l_@@_angle_marker_box - \box_use:N \l_@@_angle_unit_box - } - \dim_compare:nNnTF - { \l_@@_angle_marker_dim } > { \l_@@_angle_unit_dim } - { \@@_angle_print_astronomy_marker: } - { \@@_angle_print_astronomy_unit: } - \prop_get:NnNT \l_@@_number_out_prop { mantissa-decimal } - \l_@@_tmpa_tl - { \@@_print:nV { number } \l_@@_tmpa_tl } -} -\cs_new_protected:Npn \@@_angle_print_astronomy_aux:n #1 { - \dim_set:cn { l_@@_angle_ #1 _dim } - { \box_wd:c { l_@@_angle_ #1 _box } } - \hbox_set_to_wd:cnn { l_@@_angle_ #1 _box } { \c_zero_skip } - { - \tex_hss:D - \hbox_unpack:c { l_@@_angle_ #1_box } - \tex_hss:D - } -} -\cs_new_protected:Npn \@@_angle_print_astronomy_marker: { - \hbox_set_to_wd:Nnn \l_@@_angle_marker_box - { \l_@@_angle_marker_dim } - { - \tex_hss:D - \hbox_unpack:N \l_@@_angle_marker_box - \tex_hss:D - } - \box_use:N \l_@@_angle_marker_box -} -\cs_new_protected:Npn \@@_angle_print_astronomy_unit: { - \hbox_set_to_wd:Nnn \l_@@_angle_marker_box - { \l_@@_angle_unit_dim } - { - \tex_hss:D - \hbox_unpack:N \l_@@_angle_marker_box - \tex_hss:D - } - \box_use:N \l_@@_angle_marker_box - \skip_horizontal:N \scriptspace -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_angle_print_direct:nnn} -%\begin{macro}{\@@_angle_print_direct_aux:nn} -% The direct printing routine is rather similar to the standard -% one, with just a modified final step. -% \begin{macrocode} -\cs_new_protected:Npn \@@_angle_print_direct:nnn #1#2#3 { - \@@_angle_print_direct_aux:nn {#1} { \SIUnitSymbolDegree } - \bool_if:NT \l_@@_angle_degree_space_bool - { - \nobreak - \l_@@_angle_arc_separator_tl - } - \@@_angle_print_direct_aux:nn {#2} { \SIUnitSymbolArcminute } - \bool_if:NT \l_@@_angle_minute_space_bool - { - \nobreak - \l_@@_angle_arc_separator_tl - } - \@@_angle_print_direct_aux:nn {#3} { \SIUnitSymbolArcsecond } -} -\cs_new_protected:Npn \@@_angle_print_direct_aux:nn #1#2 { - \tl_if_empty:nF {#1} - { - \tl_set:Nn \l_@@_unit_tl {#2} - \@@_print:nn { number } { \ensuremath {#1} } - \@@_unit_output_print: - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Creating unit macros} -% -% Unit macros and related support are created here. To avoid cluttering -% up the user name-space with a lot of short macro names, the standard -% method only makes these available inside the unit-processing functions -% (\cs{SI}, \cs{si} and the \texttt{S} column). -% -%\begin{macro}{\l_siunitx_unit_symbolic_seq} -% A list of all unit and related functions. -% \begin{macrocode} -\seq_new:N \l_siunitx_unit_symbolic_seq -\seq_put_right:Nn \l_siunitx_unit_symbolic_seq { \of } -\seq_put_right:Nn \l_siunitx_unit_symbolic_seq { \highlight } -\seq_put_right:Nn \l_siunitx_unit_symbolic_seq { \per } -\seq_put_right:Nn \l_siunitx_unit_symbolic_seq { \raiseto } -\seq_put_right:Nn \l_siunitx_unit_symbolic_seq { \tothe } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_declare_power_after:Nn , -% \@@_declare_power_before:Nn -%} -% Creating powers is all about storing values. -% \begin{macrocode} -\cs_new_protected:Npn \@@_declare_power_after:Nn #1#2 { - \seq_put_right:Nn \l_siunitx_unit_symbolic_seq {#1} - \cs_set:cpn { @@_ \token_to_str:N #1 _literal:w } - { \@@_textsuperscript:n {#2} } - \cs_set:cpn { @@_ \token_to_str:N #1 _function:w } - { \@@_unit_parse_power_after:n {#2} } -} -\cs_new_protected:Npn \@@_declare_power_before:Nn #1#2 { - \seq_put_right:Nn \l_siunitx_unit_symbolic_seq {#1} - \cs_set:cpn { @@_ \token_to_str:N #1 _literal:w } ##1 - { ##1 \@@_textsuperscript:n {#2} } - \cs_set:cpn { @@_ \token_to_str:N #1 _function:w } - { \@@_unit_parse_power_before:n {#2} } -} -% \end{macrocode} -%\end{macro} -% -% \begin{macro}{\@@_declare_prefix:Nnnn} -% \begin{variable} -% {\l_@@_prefix_forward_prop, \l_@@_prefix_reverse_prop} -% Prefixes need to store both the symbol and the power they represent. -% A reverse system is also set up, to allow powers to be converted to -% prefixes. -% \begin{macrocode} -\cs_new_protected:Npn \@@_declare_prefix:Nnnn #1#2#3#4 +\NewDocumentCommand \unit { O { } > { \TrimSpaces } m } { - \seq_put_right:Nn \l_siunitx_unit_symbolic_seq {#1} - \prop_put:Nnn \l_@@_prefix_forward_prop {#1} {#4} - \prop_put:Nnn \l_@@_prefix_reverse_prop {#4} {#1} - \cs_set:cpn { @@_ \token_to_str:N #1 _literal:w } {#2} - \cs_set:cpn { @@_ \token_to_str:N #1 _function:w } - { - \bool_if:NTF \l_@@_prefix_symbols_bool - { \@@_unit_parse_prefix:Nn #1 {#2} } - { \@@_unit_parse_prefix:nn {#3} {#4} } - } + \mode_leave_vertical: + \group_begin: + \siunitx_unit_options_apply:n {#2} + \keys_set:nn { siunitx } {#1} + \siunitx_unit_format:nN {#2} \l_@@_tmp_tl + \siunitx_print_unit:V \l_@@_tmp_tl + \group_end: } -\prop_new:N \l_@@_prefix_forward_prop -\prop_new:N \l_@@_prefix_reverse_prop % \end{macrocode} -% \end{variable} % \end{macro} % -%\begin{macro}{\@@_declare_qualifier:Nn} -% Qualifiers just need storing. -% \begin{macrocode} -\cs_new_protected:Npn \@@_declare_qualifier:Nn #1#2 { - \seq_put_right:Nn \l_siunitx_unit_symbolic_seq {#1} - \cs_set:cpn { @@_ \token_to_str:N #1 _literal:w } - { \text { ~ } ( #2 ) } - \cs_set:cpn { @@_ \token_to_str:N #1 _function:w } - { \@@_unit_parse_qualifier:n {#2} } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_declare_unit:Nnn} -%\begin{macro}{\@@_unit_first_token:n} -% Creating units requires various things to be stored. This is done -% with several storage bins to keep the code clear. For the -% \texttt{macro} definition, the test occurs at use so that there is no -% problem with the creation order for units. -% \begin{macrocode} -\cs_new_protected:Npn \@@_declare_unit:Nnn #1#2#3 { - \seq_put_right:Nn \l_siunitx_unit_symbolic_seq {#1} - \cs_set:cpn { @@_ \token_to_str:N #1 _literal:w } {#2} - \cs_set_protected:cpn { @@_ \token_to_str:N #1 _function:w } - { - \@@_unit_if_literal:nTF {#2} - { \@@_unit_parse_unit:Nn #1 {#2} } - {#2} - } - \tl_if_empty:nTF {#3} - { \cs_undefine:c { l_@@_ \token_to_str:N #1 _options_tl } } - { - \tl_clear_new:c { l_@@_ \token_to_str:N #1 _options_tl } - \tl_set:cn { l_@@_ \token_to_str:N #1 _options_tl } {#3} - } -} -\cs_new_protected:Npn \@@_unit_first_token:n #1 { - \exp_last_unbraced:No \token_to_str:N { \tl_head:w #1 \q_stop } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\per} -% The \cs{per} function is pretty simple. -% \begin{macrocode} -\cs_new:cpn { @@_ \token_to_str:N \per _literal:w } { / } -\cs_new_protected:cpn { @@_ \token_to_str:N \per _function:w } { - \bool_set_true:N \l_@@_per_bool - \@@_unit_parse_per: -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \raiseto , -% \tothe -%} -% Generic versions of the pre-set powers. -% \begin{macrocode} -\cs_new:cpn { @@_ \token_to_str:N \raiseto _literal:w } #1#2 { - #2 - \@@_textsuperscript:n {#1} -} -\cs_new_protected:cpn { @@_ \token_to_str:N \raiseto _function:w } - #1 { - \@@_unit_parse_power_before:n {#1} -} -\cs_new:cpn { @@_ \token_to_str:N \tothe _literal:w } #1 { - \@@_textsuperscript:n {#1} -} -\cs_new_protected:cpn { @@_ \token_to_str:N \tothe _function:w } - #1 { - \@@_unit_parse_power_after:n {#1} -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\of} -% A flexible qualifier as well. -% \begin{macrocode} -\cs_new:cpn { @@_ \token_to_str:N \of _literal:w } #1 { - \text { ~ } ( #1 ) -} -\cs_new_protected:cpn { @@_ \token_to_str:N \of _function:w } #1 { - \@@_unit_parse_qualifier:n {#1} -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\cancel} -%\begin{macro}{\@@_real_cancel:n} -%\begin{macro}{\@@_cancel:n} -% The \cs{cancel} macro is odd as it is only defined if the appropriate -% package is loaded. -% \begin{macrocode} -\AtBeginDocument { - \cs_if_exist:NT \cancel - { - \cs_set_protected:Npn \@@_cancel:n #1 - { \@@__real_cancel:n { \@@_print:nn { unit } {#1} } } - \cs_set_eq:NN \@@__real_cancel:n \cancel - \seq_put_right:Nn \l_siunitx_unit_symbolic_seq { \cancel } - \cs_new_protected:cpn - { @@_ \token_to_str:N \cancel _function:w } - { \@@_unit_parse_special:n { \@@_cancel:n } } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\highlight} -% Another special function: selective colour. -% \begin{macrocode} -\cs_new:cpn - { @@_ \token_to_str:N \highlight _literal:w } #1 - { \@@_textcolor:n {#1} } -\cs_new_protected:cpn - { @@_ \token_to_str:N \highlight _function:w } #1 - { \@@_unit_parse_special:n { \@@_textcolor:n {#1} } } -% \end{macrocode} -%\end{macro} -% -%\subsection{Creating body unit macros} -% -% The user might have asked for the unit macros to be available in the -% document body. If so, then these are created at the start of the -% document body. -% -%\begin{macro}{ -% \l_@@_create_free_bool , -% \l_@@_create_overwrite_bool , -% \l_@@_create_prespace_bool , -% \l_@@_create_optional_bool , -% \l_@@_create_xspace_bool -%} -% There are a few options which control this behaviour: these are all -% preamble-only. -% \begin{macrocode} -\keys_define:nn { siunitx } { - free-standing-units .bool_set:N = \l_@@_create_free_bool , - overwrite-functions .bool_set:N = \l_@@_create_overwrite_bool, - space-before-unit .bool_set:N = \l_@@_create_prespace_bool , - unit-optional-argument .bool_set:N = \l_@@_create_optional_bool , - use-xspace .bool_set:N = \l_@@_create_xspace_bool , -} -\@@_option_deactivate:n { - free-standing-units , - overwrite-functions , - space-before-unit , - unit-optional-argument , - use-xspace , -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_unit_create_empty_functions:} -%\begin{macro}{\@@_unit_create_empty_functions_aux:N} -% Without this, horrible things happen with \pkg{memoir} and -% \pkg{hyperref}. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_create_empty_functions: - { - \@@_unit_create_functions_aux_i: - \seq_map_function:NN \l_siunitx_unit_symbolic_seq - \@@_unit_create_empty_functions_aux:N - \@@_unit_create_functions_aux_ii: - } -\cs_new_protected:Npn \@@_unit_create_empty_functions_aux:N #1 - { - \cs_if_free:NT #1 - { \cs_set_protected:Npn #1 { \ERROR } } - } -% \end{macrocode} -%\end{macro} -%\end{macro} -% -% \begin{macro}{\@@_unit_create_functions:} % \begin{macro} -% { -% \@@_unit_create_functions_aux_i:, -% \@@_unit_create_functions_aux_ii: -% } -% Creation of macros essentially involves picking up a couple of loops. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_create_functions: - { - \@@_unit_create_functions_aux_i: - \bool_if:NT \l_@@_create_overwrite_bool - { \seq_map_function:NN \l_siunitx_unit_symbolic_seq \cs_undefine:N } - \bool_if:NTF \l_@@_create_optional_bool - { - \seq_map_function:NN \l_siunitx_unit_symbolic_seq - \@@_unit_create_with_arg:N - } - { - \seq_map_function:NN \l_siunitx_unit_symbolic_seq - \@@_unit_create:N - } - \@@_unit_create_functions_aux_ii: - \bool_if:NT \l_@@_create_xspace_bool - { \RequirePackage { xspace } } - } -\cs_new_protected:Npn \@@_unit_create_functions_aux_i: - { - \@ifpackageloaded { soulpos } - { - \@ifpackageloaded { soul } - { } - { - \cs_set_protected:Npn \@@_unit_create_functions_aux_ii: - { - \cs_undefine:N \hl - \cs_undefine:N \ul - } - } - } - { } - } -\cs_new_protected:Npn \@@_unit_create_functions_aux_ii: { } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -%\begin{macro}{ -% \@@_unit_create:N , -% \@@_unit_create_with_arg:N -%} -% The creation functions expand everything as far as possible so that -% there is less to do in the document. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_create:N #1 { - \cs_if_free:NT #1 - { - \cs_set:Npx \@@_tmp:w - { - \ProvideDocumentCommand \exp_not:N #1 { } - { - \group_begin: - \exp_not:N \cs_if_free:NF - \exp_not:c - { l_@@_ \token_to_str:N #1 _options_tl } - { - \keys_set:nV { siunitx } - \exp_not:c - { l_@@_ \token_to_str:N #1 _options_tl } - } - \bool_if:NT \l_@@_create_prespace_bool - { \exp_not:N \l_@@_number_unit_product_tl } - \exp_not:n { \@@_unit_output:nn {#1} { } } - \group_end: - \bool_if:NT \l_@@_create_xspace_bool - { \exp_not:N \xspace } - } - } - \@@_tmp:w - } -} -\cs_new_protected:Npn \@@_unit_create_with_arg:N #1 { - \cs_if_free:NT #1 - { - \cs_set:Npx \@@_tmp:w - { - \ProvideDocumentCommand \exp_not:N #1 { o } - { - \group_begin: - \exp_not:N \cs_if_free:NF - \exp_not:c - { l_@@_ \token_to_str:N #1 _options_tl } - { - \keys_set:nV { siunitx } - \exp_not:c - { - l_@@_ \token_to_str:N #1 _options_tl - } - } - \exp_not:N \IfNoValueTF {####1} - { - \bool_if:NT \l_@@_create_prespace_bool - { \exp_not:N \l_@@_number_unit_product_tl } - \exp_not:n { \@@_unit_output:nn {#1} { } } - } - { \SI {####1} { \exp_not:N #1 } } - \group_end: - \bool_if:NT \l_@@_create_xspace_bool - { \exp_not:N \xspace } - } - } - \@@_tmp:w - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_protect_symbols:N} -% There are a few unit names which may be defined by other parts of -% \LaTeX. They need to be unexpandable, as in an \texttt{S} column -% \TeX{} will look for \cs{omit} \emph{before} starting the internal -% version of \cs{si} and doing a redefinition. The same is true -% for the \cs{color} function, which may well be the first thing in -% a table cell. The same is true for \cs{array@row@rst}, from REV\TeX, -% which otherwise gives an error. -% \begin{macrocode} -\AtBeginDocument { - \cs_if_eq:NNT \color \use_none:n - { \cs_set_protected:Npn \color #1 { } } - \cs_set:Npn \@@_tmp:w #1 { } - \cs_if_eq:NNT \color \@@_tmp:w - { \cs_set_protected:Npn \color #1 { } } - \tl_map_function:nN { \bar \color \ng \pm \array@row@rst } - \@@_protect_symbols:N -} -\@@_if_hooks:TF - { - \AddToHook { begindocument / end } [ siunitx ] - { \@@_protect_symbols:N \fg } - } - { - \tl_put_right:Nn \document - { - \@@_protect_symbols:N \fg - \ignorespaces - } - } -\cs_new_protected:Npn \@@_protect_symbols:N #1 { - \cs_if_exist:NT #1 - { - \tl_if_empty:fT { \cs_prefix_spec:N #1 } - { \cs_set_protected:Npx #1 { \exp_not:V #1 } } - } -} -% \end{macrocode} -%\end{macro} -% -%\subsection{Initial unit processing} -% -% The unit processor has to convert the input (which may be all macros -% or may contain literal input) into formatted text for output. The -% input part of the process is used to sort out parsed or literal units. -% -%\begin{macro}{ -% \l_@@_unit_forbid_literal_bool , -% \l_@@_unit_parse_bool -%} -% One option is related to how units are pre-processed. -% \begin{macrocode} -\keys_define:nn { siunitx } { - forbid-literal-units .bool_set:N = - \l_@@_unit_forbid_literal_bool, - parse-units .bool_set:N = \l_@@_unit_parse_bool -} -\keys_set:nn { siunitx } { - forbid-literal-units = false, - parse-units = true -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_unit_in:nn , -% \@@_unit_in:Vn , -% \@@_pm: -%} -% The master function does a very simple checks then hands off. -% The definition of \cs{pm} needs to be saved here so that it can -% safely be used as an abbreviation for picometre and also in numbers -% for \( \pm \). -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_in:nn #1#2 { - \bool_if:NTF \l_@@_unit_parse_bool - { - \tl_if_empty:nF {#1} - { - \@@_unit_if_literal:nTF {#1} - { - \tl_clear:N \l_@@_per_mode_tl - \bool_if:NTF \l_@@_unit_forbid_literal_bool - { - \msg_error:nnx { siunitx } { literal-unit } - { \exp_not:n {#1} } - } - { - \cs_set_eq:NN \@@_pm: \pm - \@@_unit_format_literal:n {#1} - \cs_set_eq:NN \pm \@@_pm: - } - } - { - \cs_set_eq:NN \@@_pm: \pm - \@@_unit_parse:nn {#1} {#2} - \@@_unit_format: - \prop_set_eq:NN \l_@@_unit_saved_prop \l_@@_unit_prop - \cs_set_eq:NN \pm \@@_pm: - } - } - } - { \@@_unit_format_literal:n {#1} } -} -\cs_generate_variant:Nn \@@_unit_in:nn { V } -\cs_new:Npn \@@_pm: { } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_unit_if_literal:nTF} -%\begin{macro}{\@@_unit_if_literal_aux:N} -% A test is needed to see if the input only contains unit macros. This -% is done by altering setting all of the unit macros to expand to -% nothing at all. Thus there will only be anything left if there is -% a literal in the unit. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_if_literal:nTF #1#2#3 { - \group_begin: - \seq_map_function:NN \l_siunitx_unit_symbolic_seq - \@@_unit_if_literal_aux:N - \cs_set_eq:NN \of \use_none:n - \cs_set_eq:NN \highlight \use_none:n - \cs_set_eq:NN \raiseto \use_none:n - \cs_set_eq:NN \tothe \use_none:n - \protected@edef \l_@@_tmpa_tl {#1} - \exp_args:NNNV \group_end: - \tl_set:Nn \l_@@_tmpa_tl \l_@@_tmpa_tl - \tl_if_blank:VTF \l_@@_tmpa_tl {#3} {#2} -} -\cs_new_protected:Npn \@@_unit_if_literal_aux:N #1 { - \cs_set_eq:NN #1 \prg_do_nothing: -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Parsing macro units} -% -% For macro-based units, the macros are converted into literal text, -% which is then passed on for printing. The code reads through the -% input to collect up the units, before re-combining everything into -% a single block at the end of the process. -% -% \begin{variable} -% { -% \l_@@_unit_int , -% \l_@@_unit_prop , -% \l_@@_unit_saved_prop -% } -% Parsed units are stored in a property list, to keep things compact. -% An integer is also needed to count up units. -% \begin{macrocode} -\int_new:N \l_@@_unit_int -\prop_new:N \l_@@_unit_prop -\prop_new:N \l_@@_unit_saved_prop -% \end{macrocode} -% \end{variable} -% -%\begin{macro}{\l_@@_per_bool} -% To allow \cs{per} to be \enquote{sticky}. -% \begin{macrocode} -\bool_new:N \l_@@_per_bool -% \end{macrocode} -%\end{macro} -% -% \begin{variable} -% { -% \l_@@_exp_to_prefix_bool , -% \l_@@_prefix_symbols_bool , -% \l_@@_sticky_per_bool -% } -% Some options are directly related to how units are handled at this -% stage, so need be created before the reconstruction part of the code. +% {\qtylist, \numlist, \qtyproduct, \numproduct, \qtyrange, \numproduct} +% Interfaces for compound values. % \begin{macrocode} -\keys_define:nn { siunitx } +\NewDocumentCommand \qtylist + { O { } > { \SplitList { ; } } m > { \TrimSpaces } m } { - exponent-to-prefix .bool_set:N = \l_@@_exp_to_prefix_bool , - prefixes-as-symbols .bool_set:N = \l_@@_prefix_symbols_bool , - sticky-per .bool_set:N = \l_@@_sticky_per_bool + \mode_leave_vertical: + \group_begin: + \siunitx_unit_options_apply:n {#3} + \keys_set:nn { siunitx } {#1} + \siunitx_quantity_list:nn {#2} {#3} + \group_end: } -\keys_set:nn { siunitx } { prefixes-as-symbols = true } -% \end{macrocode} -% \end{variable} -% -%\begin{macro}{\@@_unit_parse:nn} -% The unit to be parsed is received here along with any options given. -% The later are needed so that the user can override any saved options -% on a one-off basis. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_parse:nn #1#2 { - \@@_unit_parse_init: - \@@_unit_parse_options:nn {#1} {#2} - #1 -} -% \end{macrocode} -%\end{macro} -% -% \begin{macro}{\@@_unit_parse_init:} -% As always, the initialisation is a separate routine to make life a -% little clearer. The definition of \cs{pm} is saved here as it -% is used by units and numbers. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_parse_init: +\NewDocumentCommand \numlist { O { } > { \SplitList { ; } } m } { - \prop_clear:N \l_@@_unit_prop - \int_zero:N \l_@@_unit_int - \bool_set_false:N \l_@@_per_bool - \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq - { \cs_set_eq:Nc ##1 { @@_ \token_to_str:N ##1 _function:w } } - } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_unit_parse_options:n} -% Any unit-specific options are loaded, followed by re-applying any -% options given for this particular macro. The second call to -% \cs{keys_set:nn} is needed to allow the local overriding of settings. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_parse_options:nn #1#2 { - \tl_if_single:nT {#1} - { - \cs_if_free:cF - { l_@@_ \@@_unit_first_token:n {#1} _options_tl } - { - \keys_set:nv { siunitx } - { l_@@_ \@@_unit_first_token:n {#1} _options_tl } - \keys_set:nn { siunitx } {#2} - } + \mode_leave_vertical: + \group_begin: + \keys_set:nn { siunitx } {#1} + \siunitx_number_list:nn {#2} + \group_end: } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_unit_parse_power_before:n , -% \@@_unit_parse_power_after:n -%} -% Storing powers depends on whether they are given before or after -% the unit. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_parse_power_before:n #1 { - \tl_set:Nx \l_@@_tmpa_tl - { power- \int_eval:n { \l_@@_unit_int + 1 } } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl {#1} -} -\cs_new_protected:Npn \@@_unit_parse_power_after:n #1 { - \tl_set:Nx \l_@@_tmpa_tl - { power- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl {#1} -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \@@_unit_parse_prefix:Nn , -% \@@_unit_parse_prefix:nn -%} -% Saving prefixes always increments the counter. For non-symbolic -% mode, the base needs to be saved along with the power. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_parse_prefix:Nn #1#2 +\NewDocumentCommand \qtyproduct + { O { } > { \SplitList { x } } m > { \TrimSpaces } m } { - \int_incr:N \l_@@_unit_int - \tl_set:Nx \l_@@_tmpa_tl - { prefix- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl {#1} - \tl_set:Nx \l_@@_tmpa_tl - { prefix-symbol- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl {#2} + \mode_leave_vertical: + \group_begin: + \siunitx_unit_options_apply:n {#3} + \keys_set:nn { siunitx } {#1} + \siunitx_quantity_product:nn {#2} {#3} + \group_end: } -\cs_new_protected:Npn \@@_unit_parse_prefix:nn #1#2 +\NewDocumentCommand \numproduct + { O { } > { \SplitList { x } } > { \TrimSpaces } m } { - \@@_unit_parse_prefix:Nn \ERROR {#2} - \tl_set:Nx \l_@@_tmpa_tl - { prefix-base- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl {#1} + \mode_leave_vertical: + \group_begin: + \keys_set:nn { siunitx } {#1} + \siunitx_number_product:n {#2} + \group_end: } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_unit_parse_per:} -% The \cs{per} function always applies to the next unit seen, so -% the counter has to be advanced by one. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_parse_per: { - \tl_set:Nx \l_@@_tmpa_tl - { per- \int_eval:n { \l_@@_unit_int + 1 } } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl { true } - \bool_if:NT \l_@@_sticky_per_bool - { \cs_set_eq:NN \per \@@_unit_parse_per_error: } -} -\cs_new_protected:Npn \@@_unit_parse_per_error: { - \msg_error:nn { siunitx } { duplicate-sticky-per } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_unit_parse_qualifier:n} -% Qualifiers never alter the number of units. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_parse_qualifier:n #1 { - \tl_set:Nx \l_@@_tmpa_tl - { symbol- \int_use:N \l_@@_unit_int } - \prop_if_in:NVF \l_@@_unit_prop \l_@@_tmpa_tl - { \msg_error:nn { siunitx } { qualifier-before-unit } } - \tl_set:Nx \l_@@_tmpa_tl - { qualifier- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl {#1} -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_unit_parse_special:n} -% Special effects are possible by adding code to the unit property -% list here: this is pretty much arbitrary, so there is no real -% processing done. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_parse_special:n #1 { - \tl_set:Nx \l_@@_tmpa_tl - { special- \int_eval:n { \l_@@_unit_int + 1 } } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl {#1} -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_unit_parse_unit:Nn} -%\begin{macro}{\@@_unit_parse_unit_per:} -% For units, there is a check in case a prefix is present (which will -% have incremented the counter). With the counter correct, simply add -% the literal to the property list. There is also a check to see if -% there is a \enquote{sticky} \cs{per} to think about. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_parse_unit:Nn #1#2 { - \tl_set:Nx \l_@@_tmpa_tl - { prefix-symbol- \int_use:N \l_@@_unit_int } - \prop_if_in:NVTF \l_@@_unit_prop \l_@@_tmpa_tl - { - \tl_set:Nx \l_@@_tmpa_tl - { symbol- \int_use:N \l_@@_unit_int } - \prop_if_in:NVT \l_@@_unit_prop \l_@@_tmpa_tl - { \int_incr:N \l_@@_unit_int } - } - { \int_incr:N \l_@@_unit_int } - \tl_set:Nx \l_@@_tmpa_tl - { unit- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl {#1} - \tl_set:Nx \l_@@_tmpa_tl - { symbol- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl {#2} - \@@_unit_parse_unit_per: -} -\cs_new_protected:Npn \@@_unit_parse_unit_per: { - \bool_if:NT \l_@@_sticky_per_bool - { - \bool_if:NT \l_@@_per_bool - { - \tl_set:Nx \l_@@_tmpa_tl - { per- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl - { true } - } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Unit formatting} -% -%\begin{macro}{ -% \l_@@_preunit_tl , -% \l_@@_unit_tl , -% \l_@@_unit_current_tl , -% \l_@@_unit_denominator_tl , -% \l_@@_unit_numerator_tl , -% \l_@@_unit_saved_tl -%} -% Storage space for creating unit output. -% \begin{macrocode} -\tl_new:N \l_@@_preunit_tl -\tl_new:N \l_@@_unit_tl -\tl_new:N \l_@@_unit_current_tl -\tl_new:N \l_@@_unit_denominator_tl -\tl_new:N \l_@@_unit_numerator_tl -\tl_new:N \l_@@_unit_saved_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_unit_denominator_int , -% \l_@@_unit_numerator_int -%} -% For tracking in case brackets are needed. -% \begin{macrocode} -\int_new:N \l_@@_unit_denominator_int -\int_new:N \l_@@_unit_numerator_int -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_unit_prefix_int , -% \l_@@_unit_prefix_base_int , -% \l_@@_unit_prefix_current_tl -%} -% Used to calculate the overall prefix value. -% \begin{macrocode} -\int_new:N \l_@@_unit_prefix_int -\int_new:N \l_@@_unit_prefix_base_int -\tl_new:N \l_@@_unit_prefix_current_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_unit_prefix_gram_int} -% Formatting units is complicated by the fact that the kilogram is a -% base unit, making conversions a little more awkward. -% \begin{macrocode} -\int_new:N \l_@@_unit_prefix_gram_int -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_omit_unit_space_bool} -% Needed to omit the space between a number an a unit when printing -% symbols and when there is no numerator unit. -% \begin{macrocode} -\bool_new:N \l_@@_omit_unit_space_bool -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_per_auto_bool , -% \l_@@_per_fraction_bool , -% \l_@@_per_mode_tl , -% \l_@@_power_number_bool , -% \l_@@_qualifier_mode_tl , -% \l_@@_per_two_parts_bool -%} -% For saving settings. -% \begin{macrocode} -\bool_new:N \l_@@_per_auto_bool -\bool_new:N \l_@@_per_fraction_bool -\tl_new:N \l_@@_per_mode_tl -\bool_new:N \l_@@_power_number_bool -\bool_new:N \l_@@_per_two_parts_bool -\tl_new:N \l_@@_qualifier_mode_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \l_@@_unit_denominator_bracket_bool , -% \l_@@_unit_product_tl , -% \l_@@_literal_power_bool , -% \l_@@_per_symbol_tl , -% \l_@@_qualifier_phrase_tl -%} -% At this stage, output formatting options are created. -% \begin{macrocode} -\keys_define:nn { siunitx } { - bracket-unit-denominator .bool_set:N - = \l_@@_unit_denominator_bracket_bool, - inter-unit-product .tl_set:N = \l_@@_unit_product_tl , - inter-unit-separator .tl_set:N = \l_@@_unit_product_tl , - literal-superscript-as-power - .bool_set:N = \l_@@_literal_power_bool, - per-mode .choice:, - per-mode / fraction .code:n = - { - \bool_set_false:N \l_@@_per_auto_bool - \bool_set_true:N \l_@@_per_fraction_bool - \bool_set_true:N \l_@@_per_two_parts_bool - \tl_set:Nn \l_@@_per_mode_tl { fraction } - }, - per-mode / power .meta:n = { per-mode = reciprocal } , - per-mode / power-positive-first .meta:n = - { per-mode = reciprocal-positive-first } , - per-mode / reciprocal .code:n = - { - \bool_set_false:N \l_@@_per_auto_bool - \bool_set_false:N \l_@@_per_fraction_bool - \bool_set_false:N \l_@@_per_two_parts_bool - \tl_clear:N \l_@@_per_mode_tl - }, - per-mode / reciprocal-positive-first .code:n = - { - \bool_set_false:N \l_@@_per_auto_bool - \bool_set_false:N \l_@@_per_fraction_bool - \bool_set_true:N \l_@@_per_two_parts_bool - \tl_clear:N \l_@@_per_mode_tl - }, - per-mode / repeated-symbol .code:n = - { - \bool_set_false:N \l_@@_per_auto_bool - \bool_set_false:N \l_@@_per_fraction_bool - \bool_set_false:N \l_@@_per_two_parts_bool - \tl_set:Nn \l_@@_per_mode_tl { repeat } - }, - per-mode / symbol .code:n = - { - \bool_set_false:N \l_@@_per_auto_bool - \bool_set_true:N \l_@@_per_fraction_bool - \bool_set_true:N \l_@@_per_two_parts_bool - \tl_set:Nn \l_@@_per_mode_tl { symbol } - }, - per-mode / symbol-or-fraction .code:n = - { - \bool_set_true:N \l_@@_per_auto_bool - \bool_set_true:N \l_@@_per_fraction_bool - \bool_set_true:N \l_@@_per_two_parts_bool - \tl_set:Nn \l_@@_per_mode_tl { symbol } - }, - per-symbol .tl_set:N = \l_@@_per_symbol_tl, - power-font .choice:, - power-font / number .code:n = - { \bool_set_true:N \l_@@_power_number_bool }, - power-font / unit .code:n = - { \bool_set_false:N \l_@@_power_number_bool }, - qualifier-mode .choice:, - qualifier-mode / brackets .code:n = - { \tl_set:Nn \l_@@_qualifier_mode_tl { brackets } }, - qualifier-mode / phrase .code:n = - { \tl_set:Nn \l_@@_qualifier_mode_tl { phrase } }, - qualifier-mode / space .code:n = - { \tl_set:Nn \l_@@_qualifier_mode_tl { space } }, - qualifier-mode / subscript .code:n = - { \tl_set:Nn \l_@@_qualifier_mode_tl { subscript } }, - qualifier-mode / text .code:n = - { \tl_set:Nn \l_@@_qualifier_mode_tl { text } }, - qualifier-phrase .tl_set:N = \l_@@_qualifier_phrase_tl -} -\keys_set:nn { siunitx } { - bracket-unit-denominator = true, - inter-unit-product = \,, - literal-superscript-as-power = true, - per-mode = reciprocal, - per-symbol = /, - power-font = number, - qualifier-mode = subscript, - qualifier-phrase = { ~ of ~ } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_unit_format:} -% Most of the work is done by the loop, with a little tidying up for -% fraction-like output. Before starting the loop, there is a check for -% the case of a single reciprocal unit when per is set up to create a -% symbol. In that special case, the space between a number and a unit -% has to be removed. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format: { - \prop_put:Nnx \l_@@_unit_prop { total-units } - { \int_use:N \l_@@_unit_int } - \@@_unit_format_init: - \int_while_do:nNnn { \l_@@_unit_int } > { 0 } - { - \@@_unit_format_prefix: - \@@_unit_format_symbol: - \@@_unit_format_qualifier: - \@@_unit_format_power: - \@@_unit_format_add: - \int_decr:N \l_@@_unit_int - } - \bool_if:NT \l_@@_per_two_parts_bool - { - \bool_if:NTF \l_@@_per_fraction_bool - { \@@_unit_format_fraction: } - { \@@_unit_format_sorted: } - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_unit_format_add:} -%\begin{macro}{\@@_unit_format_add_aux:n} -% Adding the current unit to the output means checking where it goes. -% The odd code when adding a space is to pick up repeated per symbols, -% which need to suppress the space. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_add: { - \bool_if:NTF \l_@@_per_two_parts_bool - { - \tl_set:Nx \l_@@_tmpb_tl - { per- \int_use:N \l_@@_unit_int } - \prop_if_in:NVTF \l_@@_unit_prop \l_@@_tmpb_tl - { - \@@_unit_format_add_aux:n { _denominator } - \int_incr:N \l_@@_unit_denominator_int - } - { - \@@_unit_format_add_aux:n { _numerator } - \int_incr:N \l_@@_unit_numerator_int - } - } - { \@@_unit_format_add_aux:n { } } - \tl_clear:N \l_@@_unit_current_tl -} -\cs_new_protected:Npn \@@_unit_format_add_aux:n #1 { - \tl_if_empty:cF { l_@@_unit #1 _tl } - { - \str_if_eq:VnTF \l_@@_per_mode_tl { repeat } - { - \tl_set:Nx \l_@@_tmpa_tl - { per- \int_eval:n { \l_@@_unit_int + 1 } } - \prop_if_in:NVF \l_@@_unit_prop \l_@@_tmpa_tl - { - \tl_put_right:NV \l_@@_unit_current_tl - \l_@@_unit_product_tl - } - } - { - \tl_put_right:NV \l_@@_unit_current_tl - \l_@@_unit_product_tl - } - } - \tl_set:Nx \l_@@_tmpa_tl - { special- \int_use:N \l_@@_unit_int } - \prop_get:NVNTF \l_@@_unit_prop \l_@@_tmpa_tl - \l_@@_tmpa_tl +\NewDocumentCommand \qtyrange { O { } m m > { \TrimSpaces } m } { - \tl_put_left:cx { l_@@_unit #1 _tl } - { - \exp_not:V \l_@@_tmpa_tl - { \exp_not:V \l_@@_unit_current_tl } - } + \mode_leave_vertical: + \group_begin: + \siunitx_unit_options_apply:n {#4} + \keys_set:nn { siunitx } {#1} + \siunitx_quantity_range:nnn {#2} {#3} {#4} + \group_end: } +\NewDocumentCommand \numrange { O { } m m } { - \tl_put_left:cV { l_@@_unit #1 _tl } - \l_@@_unit_current_tl + \mode_leave_vertical: + \group_begin: + \keys_set:nn { siunitx } {#1} + \siunitx_number_range:nn {#2} {#3} + \group_end: } -} % \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_unit_format_fraction:} -%\begin{macro}{ -% \@@_unit_format_fraction: , -% \@@_unit_format_auto: , -% \@@_unit_format_symbol: , -% \@@_unit_format_symbol_aux: , -% \@@_unit_format_symbol_aux_alt: -%} -% When making (\emph{psuedo}-)fractions there is a check to place a -% \( 1 \) in the numerator is it's blank. For symbol mode, this is -% only done if there is no number. Then some construction work. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_fraction: { - \int_compare:nNnT { \l_@@_unit_numerator_int } = { 0 } - { - \str_if_eq:VnT \l_@@_per_mode_tl { symbol } - { \bool_set_true:N \l_@@_omit_unit_space_bool } - } - \int_compare:nNnTF { \l_@@_unit_denominator_int } > { 0 } - { - \bool_if:NTF \l_@@_per_auto_bool - { \@@_unit_format_fraction_auto: } - { - \use:c - { @@_unit_format_fraction_ \l_@@_per_mode_tl : } - } - } - { \tl_set_eq:NN \l_@@_unit_tl \l_@@_unit_numerator_tl } -} -\cs_new_protected:Npn \@@_unit_format_fraction_fraction: { - \tl_if_empty:NT \l_@@_unit_numerator_tl - { \tl_set:Nn \l_@@_unit_numerator_tl { 1 } } - \tl_set:Nx \l_@@_unit_numerator_tl - { { \exp_not:V \l_@@_unit_numerator_tl } } - \tl_put_left:Nn \l_@@_unit_numerator_tl - { \@@_print:nn { unit } } - \tl_set:Nx \l_@@_unit_numerator_tl - { { \exp_not:V \l_@@_unit_numerator_tl } } - \tl_set:Nx \l_@@_unit_denominator_tl - { { \exp_not:V \l_@@_unit_denominator_tl } } - \tl_put_left:Nn \l_@@_unit_denominator_tl - { \@@_print:nn { unit } } - \tl_set:Nx \l_@@_unit_denominator_tl - { { \exp_not:V \l_@@_unit_denominator_tl } } - \tl_set:Nn \l_@@_unit_tl { \@@_fraction:nn } - \tl_put_right:NV \l_@@_unit_tl \l_@@_unit_numerator_tl - \tl_put_right:NV \l_@@_unit_tl \l_@@_unit_denominator_tl - \tl_set:Nx \l_@@_unit_tl - { \exp_not:N \ensuremath { \exp_not:V \l_@@_unit_tl } } -} -% \end{macrocode} -% For the \opt{symbol} setting, there is a need to deal with the -% possible \opt{symbol-or-fraction} choice. That is achieved by -% setting up both the \opt{fraction} and \opt{symbol} output. -% In the automatic mode, both cases are combined inside a -% \cs{tex_mathchoice:D}, with appropriate protection, before sending -% everything through for printing. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_fraction_auto: { - \mode_if_math:TF - { - \group_begin: - \@@_unit_format_fraction_fraction: - \exp_args:NNNV \group_end: - \tl_set:Nn \l_@@_tmpa_tl \l_@@_unit_tl - \group_begin: - \@@_unit_format_fraction_symbol: - \exp_args:NNNV \group_end: - \tl_set:Nn \l_@@_tmpb_tl \l_@@_unit_tl - \tl_set:Nx \l_@@_tmpb_tl - { - \@@_print:nn { unit } - { \exp_not:V \l_@@_tmpb_tl } - } - \tl_set:Nx \l_@@_unit_tl - { - \exp_not:N \ensuremath { - \tex_mathchoice:D - { \exp_not:V \l_@@_tmpa_tl } - { \exp_not:V \l_@@_tmpb_tl } - { \exp_not:V \l_@@_tmpb_tl } - { \exp_not:V \l_@@_tmpb_tl } - } - } - } - { \@@_unit_format_fraction_symbol: } -} -% \end{macrocode} -% For a normal symbol, the two parts of the input are arranged either -% side of the symbol itself in math mode. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_fraction_symbol: { - \@@_unit_format_fraction_symbol_aux: - \int_compare:nNnT { \l_@@_unit_denominator_int } > { 1 } - { - \bool_if:NT \l_@@_unit_denominator_bracket_bool - { - \tl_put_left:NV \l_@@_unit_denominator_tl \l_@@_bracket_open_tl - \tl_put_right:NV \l_@@_unit_denominator_tl \l_@@_bracket_close_tl - } - } - \tl_set_eq:NN \l_@@_unit_tl \l_@@_unit_numerator_tl - \tl_put_right:NV \l_@@_unit_tl \l_@@_per_symbol_tl - \tl_put_right:NV \l_@@_unit_tl \l_@@_unit_denominator_tl -} -\cs_new_protected:Npn - \@@_unit_format_fraction_symbol_aux: { } -\cs_new_protected:Npn - \@@_unit_format_fraction_symbol_aux_alt: { - \tl_if_empty:NT \l_@@_unit_numerator_tl - { \tl_set:Nn \l_@@_unit_numerator_tl { 1 } } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_unit_format_init:} -% The normal initialisation stuff. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_init: { - \bool_set_false:N \l_@@_omit_unit_space_bool - \tl_clear:N \l_@@_unit_tl - \tl_clear:N \l_@@_unit_current_tl - \tl_clear:N \l_@@_unit_denominator_tl - \int_zero:N \l_@@_unit_prefix_gram_int - \tl_clear:N \l_@@_unit_numerator_tl - \int_zero:N \l_@@_unit_prefix_base_int - \int_zero:N \l_@@_unit_prefix_int - \int_zero:N \l_@@_unit_denominator_int - \int_zero:N \l_@@_unit_numerator_int - \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq - { \@@_unit_print_literal_aux:N ##1 } -} -% \end{macrocode} -%\end{macro} -% -% \begin{macro}{\@@_unit_format_literal:n} -% \begin{macro}{\@@_unit_format_literal_aux:N} -% \begin{macro}{\@@_unit_format_literal_power:n} -% If the unit given contains anything which is not a unit macro, then -% any unit macros that are there simply dump literal meanings. There is -% then a little work to do sorting out |~| and |.| characters at -% the outer level. -% \begin{macrocode} -\group_begin: - \char_set_catcode_active:N \~ - \cs_new_protected:Npn \@@_unit_format_literal:n #1 - { - \int_zero:N \l_@@_unit_prefix_int - \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq - { \@@_unit_print_literal_aux:N ##1 } - \tl_set:Nn \l_@@_unit_tl {#1} - \tl_replace_all:NnV \l_@@_unit_tl { . } - \l_@@_unit_product_tl - \tl_replace_all:NnV \l_@@_unit_tl { ~ } - \l_@@_unit_product_tl - \bool_if:NT \l_@@_literal_power_bool - { - \tl_replace_all:Nnn \l_@@_unit_tl { ^ } - { \@@_unit_format_literal_power:n } - \tl_replace_all:Non \l_@@_unit_tl { \token_to_str:N ^ } - { \@@_unit_format_literal_power:n } - } - \@@_unit_format_literal_extras: - } -\group_end: -\cs_new_protected:Npn \@@_unit_print_literal_aux:N #1 - { \cs_set_eq:Nc #1 { @@_ \token_to_str:N #1 _literal:w } } -\cs_new_protected:Npn \@@_unit_format_literal_power:n #1 - { \PrintSuperscript { \@@_unit_format_power_aux:n {#1} } } -% \end{macrocode} -% \end{macro} % \end{macro} - %\end{macro} -% -%\begin{macro}{\@@_unit_format_literal_extras:} -%\begin{macro}{\@@_unit_format_literal_extras_aux:nN} -% The code here deals with characters outside the normal range that -% can appear in units in UTF-8 and related encodings. The idea is to -% do a search and replace, thus avoiding any active characters. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_literal_extras: - { - \@@_unit_format_literal_extras_aux:nN { 176 } - \SIUnitSymbolDegree - \@@_unit_format_literal_extras_aux:nN { 181 } - \SIUnitSymbolMicro - \@@_unit_format_literal_extras_aux:nN { 197 } - \SIUnitSymbolAngstrom - } -\cs_new_protected:Npn \@@_unit_format_literal_extras_aux:nN #1#2 - { - \tl_replace_all:Nxn \l_@@_unit_tl - { \char_generate:nn { #1 } { 12 } } - {#2} - } -\bool_lazy_or:nnF { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: } - { - \AtBeginDocument - { - \cs_if_exist:NTF \inputencodingname - { - \tl_set:Nn \l_@@_tmpa_tl { latin1 , latin5 , latin9 } - \clist_if_in:NVF \l_@@_tmpa_tl \inputencodingname - { - \cs_set_eq:NN \@@_unit_format_literal_extras: - \scan_stop: - } - } - { - \cs_set_eq:NN \@@_unit_format_literal_extras: - \scan_stop: - } - } - } -% \end{macrocode} -%\end{macro} -%\end{macro} % -%\begin{macro}{\@@_unit_format_power:} -%\begin{macro}{ -% \@@_unit_format_power_aux: , -% \@@_unit_format_power_aux:n , -% \@@_unit_format_power_aux:nn , -% \@@_unit_format_power_aux:w , -% \@@_unit_format_power_brackets: , -% \@@_unit_format_power_per: , -% \@@_unit_format_power_repeat: -%} -% To format powers, there are a few issues: are brackets needed, is -% the power reciprocal and is fraction-formatting in operation. Repeated -% per symbols make life a little more complex, as they have to be -% handled here as well. +% \begin{macro}{\complexnum, \complexqty} +% Interfaces for complex numbers. % \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_power: { - \tl_set:Nx \l_@@_tmpa_tl - { power- \int_use:N \l_@@_unit_int } - \prop_get:NVNTF \l_@@_unit_prop \l_@@_tmpa_tl - \l_@@_tmpa_tl - { \@@_unit_format_power_aux: } - { - \tl_set:Nx \l_@@_tmpa_tl - { per- \int_use:N \l_@@_unit_int } - \prop_if_in:NVT \l_@@_unit_prop \l_@@_tmpa_tl - { - \tl_set:Nn \l_@@_tmpa_tl { 1 } - \@@_unit_format_power_aux: - } - } -} -% \end{macrocode} -% The auxiliary function needs to make sure that the printing routine -% prints the power as a number, not as text: the two modes may be -% different. A search and replace function is needed for superscripts -% in text mode so that negative signs get printed correctly. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_power_aux: { - \str_if_eq:VnTF \l_@@_per_mode_tl { repeat } - { \@@_unit_format_power_repeat: } - { \@@_unit_format_power_per: } - \str_if_eq:VnF \l_@@_tmpa_tl { 1 } - { - \@@_unit_format_power_brackets: - \tl_put_right:Nx \l_@@_unit_current_tl - { - \exp_not:N \PrintSuperscript - { - \@@_unit_format_power_aux:n - { - \exp_after:wN \@@_unit_format_power:w - \l_@@_tmpa_tl . . \q_stop - } - } - } - } -} -\cs_new_protected:Npn \@@_unit_format_power_aux:n #1 { - \bool_if:NTF \l_@@_power_number_bool - { \@@_unit_format_power_aux:nn { number } {#1} } - { \@@_unit_format_power_aux:nn { unit } {#1} } -} -\cs_new_protected:Npn \@@_unit_format_power_aux:nn #1#2 { - \bool_if:cTF { l_@@_ #1 _math_mode_bool } - { \@@_print:nn {#1} {#2} } - { - \tl_set:Nn \l_@@_tmpa_tl {#2} - \tl_replace_all:Nnn \l_@@_tmpa_tl { - } - { \text { \textminus } } - \@@_print:nV {#1} \l_@@_tmpa_tl - } -} -\cs_new:Npn \@@_unit_format_power:w #1 . #2 . #3 \q_stop +\NewDocumentCommand \complexnum { O { } m } { - \exp_not:n {#1} - \tl_if_blank:nF {#2} - { - \exp_not:V \l_@@_output_decimal_tl - \exp_not:n {#2} - } + \mode_leave_vertical: + \group_begin: + \keys_set:nn { siunitx } {#1} + \siunitx_complex_number:n {#2} \l_@@_tmp_tl + \group_end: } -% \end{macrocode} -% A check is made for a qualifier with a space, which needs brackets -% if there is also a power. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_power_brackets: { - \tl_set:Nx \l_@@_tmpb_tl - { bracket- \int_use:N \l_@@_unit_int } - \prop_if_in:NVT \l_@@_unit_prop \l_@@_tmpb_tl - { - \tl_put_left:NV \l_@@_unit_current_tl \l_@@_bracket_open_tl - \tl_put_right:NV \l_@@_unit_current_tl \l_@@_bracket_close_tl - } -} -% \end{macrocode} -% For dealing with \cs{per} and repeated \cs{per} symbols. The sign -% change does not use any numbers, as this makes life easier with -% non-integer values. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_power_per: { - \tl_set:Nx \l_@@_tmpb_tl - { per- \int_use:N \l_@@_unit_int } - \prop_if_in:NVT \l_@@_unit_prop \l_@@_tmpb_tl - { - \bool_if:NF \l_@@_per_fraction_bool - { - \tl_if_in:NnTF \l_@@_tmpa_tl { - } - { - \cs_set:Npn \@@_tmp:w ##1 - ##2 \q_stop - { \tl_set:Nn \l_@@_tmpa_tl {##2} } - \exp_after:wN \@@_tmp:w \l_@@_tmpa_tl \q_stop - } - { \tl_put_left:Nn \l_@@_tmpa_tl { - } } - } - } -} -\cs_new_protected:Npn \@@_unit_format_power_repeat: { - \tl_set:Nx \l_@@_tmpb_tl - { per- \int_use:N \l_@@_unit_int } - \prop_if_in:NVT \l_@@_unit_prop \l_@@_tmpb_tl - { - \tl_put_left:NV \l_@@_unit_current_tl \l_@@_per_symbol_tl - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_unit_format_prefix:} -%\begin{macro}{ -% \@@_unit_format_prefix_number: , -% \@@_unit_format_prefix_number_calc: , -% \@@_unit_format_prefix_symbol: -%} -% If there is a prefix, it is added to the output. When using numerical -% output, some conversion is needed instead. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_prefix: { - \tl_set:Nx \l_@@_tmpa_tl - { prefix-symbol- \int_use:N \l_@@_unit_int } - \prop_if_in:NVT \l_@@_unit_prop \l_@@_tmpa_tl - { - \prop_get:NVN \l_@@_unit_prop \l_@@_tmpa_tl - \l_@@_unit_prefix_current_tl - \bool_if:NTF \l_@@_prefix_symbols_bool - { \@@_unit_format_prefix_symbol: } - { \@@_unit_format_prefix_number: } - } -} -\cs_new_protected:Npn \@@_unit_format_prefix_number: { - \tl_set:Nx \l_@@_tmpa_tl - { prefix-base- \int_use:N \l_@@_unit_int } - \prop_get:NVN \l_@@_unit_prop \l_@@_tmpa_tl - \l_@@_tmpa_tl - \int_compare:nNnT { \l_@@_unit_prefix_base_int } = { 0 } - { - \int_set:Nn \l_@@_unit_prefix_base_int - { \l_@@_tmpa_tl } - } - \int_compare:nNnTF - { \l_@@_unit_prefix_base_int } = { \l_@@_tmpa_tl } - { \@@_unit_format_prefix_number_calc: } - { \msg_error:nn { siunitx } { prefix-base-mismatch } } -} -% \end{macrocode} -% The calculation for converting a unit prefix into a number is -% simple unless there are grammes involved. In that case, the base unit -% is the kilogram and so there is some code to convert the number -% back correctly. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_prefix_number_calc: { - \tl_set:Nx \l_@@_tmpa_tl - { power- \int_use:N \l_@@_unit_int } - \prop_get:NVNF \l_@@_unit_prop \l_@@_tmpa_tl - \l_@@_tmpa_tl - { \tl_set:Nn \l_@@_tmpa_tl { 1 } } - \tl_set:Nx \l_@@_tmpb_tl - { unit- \int_use:N \l_@@_unit_int } - \prop_get:NVN \l_@@_unit_prop \l_@@_tmpb_tl - \l_@@_tmpb_tl - \str_if_eq:VnT \l_@@_tmpb_tl { \gram } - { - \tl_set:Nx \l_@@_unit_prefix_current_tl - { \int_eval:n { \l_@@_unit_prefix_current_tl - 3 } } - \tl_set:Nx \l_@@_tmpb_tl - { symbol- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpb_tl { kg } - } - \tl_set:Nx \l_@@_unit_prefix_current_tl - { - \int_eval:n - { \l_@@_unit_prefix_current_tl * \l_@@_tmpa_tl } - } - \tl_set:Nx \l_@@_tmpa_tl - { per- \int_use:N \l_@@_unit_int } - \prop_if_in:NVTF \l_@@_unit_prop \l_@@_tmpa_tl - { - \int_set:Nn \l_@@_unit_prefix_int - { - \l_@@_unit_prefix_int - - \l_@@_unit_prefix_current_tl - } - } - { - \int_set:Nn \l_@@_unit_prefix_int - { - \l_@@_unit_prefix_int - + \l_@@_unit_prefix_current_tl - } - } -} -\cs_new_protected:Npn \@@_unit_format_prefix_symbol: { - \tl_set_eq:NN \l_@@_unit_current_tl - \l_@@_unit_prefix_current_tl -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_unit_format_qualifier:} -%\begin{macro}{ -% \@@_unit_format_qualifier_brackets: , -% \@@_unit_format_qualifier_phrase: , -% \@@_unit_format_qualifier_space: , -% \@@_unit_format_qualifier_subscript: , -% \@@_unit_format_qualifier_text: -%} -% Four methods for showing qualifiers, each with its own sub-function. -% For the \texttt{space} methods, a warning is set in the property list -% as if there is a power then some brackets will be needed. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_qualifier: { - \tl_set:Nx \l_@@_tmpa_tl - { qualifier- \int_use:N \l_@@_unit_int } - \prop_get:NVNT \l_@@_unit_prop \l_@@_tmpa_tl - \l_@@_tmpa_tl - { - \use:c - { - @@_unit_format_qualifier_ - \l_@@_qualifier_mode_tl : - } - } -} -\cs_new_protected:Npn \@@_unit_format_qualifier_brackets: { - \tl_put_right:NV \l_@@_unit_current_tl \l_@@_bracket_open_tl - \tl_put_right:NV \l_@@_unit_current_tl \l_@@_tmpa_tl - \tl_put_right:NV \l_@@_unit_current_tl \l_@@_bracket_close_tl -} -\cs_new_protected:Npn \@@_unit_format_qualifier_phrase: +\NewDocumentCommand \complexqty { O { } m m } { - \tl_put_right:NV \l_@@_unit_current_tl \l_@@_qualifier_phrase_tl - \tl_put_right:NV \l_@@_unit_current_tl \l_@@_tmpa_tl - \tl_set:Nx \l_@@_tmpa_tl - { bracket- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl { true } - } -\char_set_catcode_active:N \~ -\cs_new_protected:Npn \@@_unit_format_qualifier_space: { - \tl_put_right:Nn \l_@@_unit_current_tl { \text { ~ } } - \tl_put_right:NV \l_@@_unit_current_tl \l_@@_tmpa_tl - \tl_set:Nx \l_@@_tmpa_tl - { bracket- \int_use:N \l_@@_unit_int } - \prop_put:NVn \l_@@_unit_prop \l_@@_tmpa_tl { true } -} -\char_set_catcode_space:N \~ -\cs_new_protected:Npn \@@_unit_format_qualifier_subscript: { - \tl_put_right:Nx \l_@@_unit_current_tl - { \exp_not:N \PrintSubscript { \exp_not:V \l_@@_tmpa_tl } } -} -\cs_new_protected:Npn \@@_unit_format_qualifier_text: { - \tl_put_right:NV \l_@@_unit_current_tl \l_@@_tmpa_tl -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -% \begin{macro}{\@@_unit_format_sorted:} -% For when the powers are sorted with the positive ones first. The only -% slight issue is making sure that the additional space is included -% between the two units, if needed. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_sorted: - { - \tl_set:Nx \l_@@_unit_tl - { - \exp_not:V \l_@@_unit_numerator_tl - \bool_lazy_or:nnF - { \tl_if_empty_p:N \l_@@_unit_numerator_tl } - { \tl_if_empty_p:N \l_@@_unit_denominator_tl } - { - \exp_not:N \l_@@_unit_product_tl - } - \exp_not:V \l_@@_unit_denominator_tl - } + \mode_leave_vertical: + \group_begin: + \siunitx_unit_options_apply:n {#3} + \keys_set:nn { siunitx } {#1} + \siunitx_complex_quantity:nn {#2} {#3} + \group_end: } % \end{macrocode} % \end{macro} % -%\begin{macro}{\@@_unit_format_symbol:} -%\begin{macro}{ -% \@@_unit_format_symbol_aux: , -% \@@_unit_format_symbol_aux_alt: -%} -% If there is no symbol, something is wrong! The only exception is -% when the code is inside the \cs{si} function (or similar) and there -% is only a prefix with nothing else present at all. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_format_symbol: { - \tl_set:Nx \l_@@_tmpa_tl - { symbol- \int_use:N \l_@@_unit_int } - \prop_get:NVNTF \l_@@_unit_prop \l_@@_tmpa_tl - \l_@@_tmpa_tl - { - \tl_put_right:NV \l_@@_unit_current_tl \l_@@_tmpa_tl - } - { \@@_unit_format_symbol_aux: } -} -\cs_new_protected:Npn \@@_unit_format_symbol_aux: { - \msg_error:nn { siunitx } { prefix-only } -} -\cs_new_protected:Npn \@@_unit_format_symbol_aux_alt: { - \int_compare:nNnTF { \l_@@_unit_int } = { 1 } - { - \prop_remove:Nn \l_@@_unit_prop { prefix-1 } - \prop_remove:Nn \l_@@_unit_prop { prefix-symbol-1 } - \prop_remove:Nn \l_@@_unit_prop { prefix-base-1 } - \prop_remove:Nn \l_@@_unit_prop { total-units } - \prop_if_empty:NF \l_@@_unit_prop - { \msg_error:nn { siunitx } { prefix-only } } - } - { \msg_error:nn { siunitx } { prefix-only } } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Unit output} -% -% A collection of the internal parts of various user functions. -% -%\begin{macro}{\l_@@_multi_brackets_bool} -%\begin{macro}{\l_@@_multi_repeat_bool} -% Flags for multi-part numbers. -% \begin{macrocode} -\bool_new:N \l_@@_multi_brackets_bool -\bool_new:N \l_@@_multi_repeat_bool -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\l_@@_product_brackets_bool} -%\begin{macro}{\l_@@_product_power_bool} -%\begin{macro}{\l_@@_number_unit_repeat_bool} -% Flags for product units. -% \begin{macrocode} -\bool_new:N \l_@@_product_brackets_bool -\bool_new:N \l_@@_product_power_bool -\bool_new:N \l_@@_product_repeat_bool -\bool_new:N \l_@@_number_unit_repeat_bool -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\l_@@_number_unit_breaks_bool} -%\begin{macro}{\l_@@_number_unit_product_tl} -% Options for printing units or units with numbers. -% \begin{macrocode} -\keys_define:nn { siunitx } { - allow-number-unit-breaks .bool_set:N = - \l_@@_number_unit_breaks_bool, - multi-part-units .choice:, - multi-part-units - / brackets .code:n = - { - \bool_set_true:N \l_@@_multi_brackets_bool - \bool_set_false:N \l_@@_multi_repeat_bool - }, - multi-part-units - / repeat .code:n = - { - \bool_set_false:N \l_@@_multi_brackets_bool - \bool_set_true:N \l_@@_multi_repeat_bool - }, - multi-part-units - / single .code:n = - { - \bool_set_false:N \l_@@_multi_brackets_bool - \bool_set_false:N \l_@@_multi_repeat_bool - }, - number-unit-product .tl_set:N = - \l_@@_number_unit_product_tl, - number-unit-separator .tl_set:N = - \l_@@_number_unit_product_tl, - product-units .choice:, - product-units - / brackets .code:n = - { - \bool_set_true:N \l_@@_product_brackets_bool - \bool_set_false:N \l_@@_product_power_bool - \bool_set_false:N \l_@@_product_repeat_bool - }, - product-units - / brackets-power .code:n = - { - \bool_set_true:N \l_@@_product_brackets_bool - \bool_set_true:N \l_@@_product_power_bool - \bool_set_false:N \l_@@_product_repeat_bool - }, - product-units - / power .code:n = - { - \bool_set_false:N \l_@@_product_brackets_bool - \bool_set_true:N \l_@@_product_power_bool - \bool_set_false:N \l_@@_product_repeat_bool - }, - product-units - / repeat .code:n = - { - \bool_set_false:N \l_@@_product_brackets_bool - \bool_set_false:N \l_@@_product_power_bool - \bool_set_true:N \l_@@_product_repeat_bool - }, - product-units - / single .code:n = - { - \bool_set_false:N \l_@@_product_brackets_bool - \bool_set_false:N \l_@@_product_power_bool - \bool_set_false:N \l_@@_product_repeat_bool - }, -} -\keys_set:nn { siunitx } { - multi-part-units = brackets, - number-unit-product = \, , - product-units = repeat -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_unit_output:nn} -%\begin{macro}{\@@_unit_output:Vn} -% For typesetting a unit directly: used by \cs{si} and the \texttt{s} -% column. The second argument is any options to set locally. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_output:nn #1#2 { - \cs_set_eq:NN \@@_unit_format_symbol_aux: - \@@_unit_format_symbol_aux_alt: - \cs_set_eq:NN \@@_unit_format_fraction_symbol_aux_ii: - \@@_unit_format_fraction_symbol_aux_alt: - \@@_unit_in:nn {#1} {#2} - \int_compare:nNnTF { \l_@@_unit_prefix_int } = { 0 } - { - \str_if_eq:VnT \l_@@_per_mode_tl { symbol } - { - \int_compare:nNnT { \l_@@_unit_numerator_int } = { 0 } - { - \bool_if:NT \l_@@_unit_parse_bool - { \@@_print:nn { unit } { 1 } } - } - } - } - { - \tl_set:Nx \l_@@_tmpa_tl - { - \int_use:N \l_@@_unit_prefix_base_int - \exp_not:N \PrintSuperscript - { \int_use:N \l_@@_unit_prefix_int } - } - \@@_print:nV { number } \l_@@_tmpa_tl - \@@_unit_output_number_sep: - } - \@@_print:nV { unit } \l_@@_unit_tl -} -\cs_generate_variant:Nn \@@_unit_output:nn { V } -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_unit_output_number_sep:} -%\begin{macro}{\@@_unit_output_number_sep_aux:} -% For printing the number separator. The \cs{tex_mathchoice:D} code -% deals with the \opt{symbol-or-fraction} setting for \opt{per-mode}, -% as in that case omission of the space between a number and unit -% depends on the current math style. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_output_number_sep: { - \bool_if:NTF \l_@@_number_unit_breaks_bool - { \penalty \binoppenalty } { \nobreak } - \bool_if:NTF \l_@@_per_auto_bool - { - \mode_if_math:TF - { - \tex_mathchoice:D - { \l_@@_number_unit_product_tl } - { \@@_unit_output_number_sep_aux: } - { \@@_unit_output_number_sep_aux: } - { \@@_unit_output_number_sep_aux: } - } - { \@@_unit_output_number_sep_aux: } - } - { \@@_unit_output_number_sep_aux: } -} -\cs_new_protected:Npn \@@_unit_output_number_sep_aux: { - \bool_if:NF \l_@@_omit_unit_space_bool - { \l_@@_number_unit_product_tl } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_unit_output_pre_print:} -%\begin{macro}{\@@_unit_output_print:} -% The printing functions for units do some simple tests then -% actually print there output. -% \begin{macrocode} -\cs_new_protected:Npn \@@_unit_output_pre_print: { - \tl_if_empty:NF \l_@@_pre_unit_tl - { - \nobreak - \@@_print:nV { unit } \l_@@_pre_unit_tl - } -} -\cs_new_protected:Npn \@@_unit_output_print: { - \int_compare:nNnF { \l_@@_unit_prefix_int } = { 0 } - { - \tl_set:Nx \l_@@_tmpa_tl - { - \bool_if:NTF \l_@@_tight_bool - { - \exp_not:N \ensuremath - { { \exp_not:V \l_@@_exponent_product_tl } } - } - { - \exp_not:N \ensuremath - { { } \exp_not:V \l_@@_exponent_product_tl { } } - } - \int_use:N \l_@@_unit_prefix_base_int - ^ { \int_use:N \l_@@_unit_prefix_int } - } - \@@_print:nV { number } \l_@@_tmpa_tl - } - \tl_if_empty:NF \l_@@_unit_tl - { - \@@_unit_output_number_sep: - \@@_print:nV { unit } \l_@@_unit_tl - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Numbers with units} -% -% Numbers with units have to be formatted in a more complex way than -% simply sticking the two together. -% -%\begin{macro}{\l_@@_preunit_tl} -% A pre-unit is optional, so can be handled using the setting system. -% \begin{macrocode} -\keys_define:nn { siunitx } { - preunit .tl_set:N = \l_@@_preunit_tl , -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_pre_unit_tl} -% When there is a pre-unit, it gets stored here. -% \begin{macrocode} -\tl_new:N \l_@@_pre_unit_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_number_product_int} -% Used to count up the number of product tokens in a number. -% \begin{macrocode} -\int_new:N \l_@@_number_product_int -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_combined:nnnn} -% Printing numbers and units means first processing the units, then -% handing off this information to the combined number and unit -% processor. -% \begin{macrocode} -\cs_new_protected:Npn \@@_combined:nnnn #1#2#3#4 { - \IfNoValueTF {#3} - { \tl_clear:N \l_@@_pre_unit_tl } - { - \group_begin: - \@@_unit_in:nn {#3} {#1} - \cs_set_eq:NN \l_@@_pre_unit_tl \l_@@_unit_tl - \exp_args:NNNo \group_end: - \tl_set:Nn \l_@@_pre_unit_tl { \l_@@_unit_tl } - } - \cs_set_eq:NN \l_@@_brackets_bool - \l_@@_multi_brackets_bool - \@@_combined_unit:nnn {#2} {#4} {#1} - \@@_combined_output:n {#2} -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_combined_output:n} -% Printing the combination of a number and a unit means checking for -% parsing then parsing the number part. +% \begin{macro}{\tablenum} +% Slightly odd set up at present: we have to have the |\ignorespaces|. % \begin{macrocode} -\cs_new_protected:Npn \@@_combined_output:n #1 { - \bool_if:NTF \l_@@_number_parse_bool - { - \tl_clear:N \l_@@_number_out_tl - \bool_set_false:N \l_@@_number_compound_bool - \@@_number_output_parse:n {#1} - } - { - \@@_unit_output_pre_print: - \@@_print:nn { number } { \ensuremath {#1} } - \@@_unit_output_print: - } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_combined_unit:nnn} -% In most cases, sorting out the main unit is easy: simply set up for -% printing using \cs{@@_unit_in:nn}. However, if there are multiple -% parts to the number, and they are to be combined into the unit, then -% there is more work to do. In either case, the result is the -% correctly-prepared unit stored in \cs{l_@@_unit_tl}. -% \begin{macrocode} -\cs_new_protected:Npn \@@_combined_unit:nnn #1#2#3 { - \bool_if:NTF \l_@@_product_power_bool - { - \@@_combined_product_count:n {#1} - \int_compare:nNnTF { \l_@@_number_product_int } > { 0 } - { - \int_incr:N \l_@@_number_product_int - \tl_set:Nn \l_@@_tmpa_tl {#2} - \tl_set:Nx \l_@@_tmpb_tl - { \tothe { \exp_not:V \l_@@_number_product_int } } - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \@@_unit_in:Vn \l_@@_tmpa_tl {#3} - } - { \@@_unit_in:nn {#2} {#3} } - } - { \@@_unit_in:nn {#2} {#3} } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_combined_product_count:n} -%\begin{macro}{\@@_combined_product_count_aux:n} -% For counting how many products are in a number, so that the unit -% can be adjusted if needed. -% \begin{macrocode} -\cs_new_protected:Npn \@@_combined_product_count:n #1 { - \int_zero:N \l_@@_number_product_int - \tl_set:Nn \l_@@_tmpa_tl {#1} - \tl_map_function:NN \l_@@_input_product_tl - \@@_combined_product_count_aux:N -} -\cs_new_protected:Npn \@@_combined_product_count_aux:N #1 { - \tl_if_in:NnT \l_@@_tmpa_tl {#1} - { - \int_incr:N \l_@@_number_product_int - \tl_remove_once:Nn \l_@@_tmpa_tl {#1} - \@@_combined_product_count_aux:N #1 - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Lists of numbers} -% -%\begin{macro}{\l_@@_list_brackets_bool} -%\begin{macro}{\l_@@_list_repeat_bool} -% For storing the behaviour of list items with respect to units. -% \begin{macrocode} -\bool_new:N \l_@@_list_brackets_bool -\bool_new:N \l_@@_list_repeat_bool -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\l_@@_list_current_tl} -%\begin{macro}{\l_@@_list_tl} -% Two token list variables used to store the list for output. -% \begin{macrocode} -\tl_new:N \l_@@_list_current_tl -\tl_new:N \l_@@_list_tl -% \end{macrocode} -%\end{macro} -%\end{macro} -% -% \begin{variable} -% { -% \l_@@_list_separator_pair_tl , -% \l_@@_list_separator_final_tl , -% \l_@@_list_separator_tl, -% } -% Settings for lists. -% \begin{macrocode} -\keys_define:nn { siunitx } +\NewDocumentCommand \tablenum { O { } m } { - list-final-separator .tl_set:N = \l_@@_list_separator_final_tl , - list-pair-separator .tl_set:N = \l_@@_list_separator_pair_tl , - list-separator .tl_set:N = \l_@@_list_separator_tl , - list-units .choice:, - list-units - / brackets .code:n = - { - \bool_set_true:N \l_@@_list_brackets_bool - \bool_set_false:N \l_@@_list_repeat_bool - }, - list-units - / repeat .code:n = - { - \bool_set_false:N \l_@@_list_brackets_bool - \bool_set_true:N \l_@@_list_repeat_bool - }, - list-units - / single .code:n = - { - \bool_set_false:N \l_@@_list_brackets_bool - \bool_set_false:N \l_@@_list_repeat_bool - } + \mode_leave_vertical: + \group_begin: + \keys_set:nn { siunitx } {#1} + \siunitx_cell_begin:w + \ignorespaces #2 + \siunitx_cell_end: + \group_end: } -\keys_set:nn { siunitx } - { - list-final-separator = { ~ and ~ } , - list-pair-separator = { ~ and ~ } , - list-separator = { , ~ } , - list-units = repeat -} % \end{macrocode} -% \end{variable} +% \end{macro} % -% \begin{macro}{\@@_list_numbers:n} -% \begin{macro} -% {\@@_list_numbers_aux_i:n, \@@_list_numbers_aux_ii:n} -% \begin{macro}{\@@_list_numbers_aux:nn} -% Setting up lists is made slightly complicated by the need to handle the -% case of exactly two items and the case of the very last separator -% differently from everything else. Beyond that, there is not too much -% to any of this code. +% \begin{macro}{\sisetup} +% A very thin wrapper. % \begin{macrocode} -\cs_new_protected:Npn \@@_list_numbers:n #1 - { - \tl_clear:N \l_@@_unit_tl - \tl_clear:N \l_@@_preunit_tl - \@@_list_numbers_aux_i:n {#1} - } -\cs_new_protected:Npn \@@_list_numbers_aux_i:n #1 - { - \bool_set_true:N \l_@@_list_first_bool - \tl_clear:N \l_@@_list_current_tl - \int_compare:nNnTF { \tl_count:n {#1} } > 2 - { - \tl_map_function:nN {#1} \@@_list_numbers_aux_ii:n - \l_@@_list_tl - \l_@@_list_separator_final_tl - \l_@@_list_current_tl - } - { - \int_compare:nNnTF { \tl_count:n {#1} } = 2 - { \@@_list_numbers_aux:nn #1 } - { \@@_combined_output:n #1 } - } - } -\cs_new_protected:Npn \@@_list_numbers_aux_ii:n #1 - { - \tl_if_empty:NTF \l_@@_list_tl - { \tl_set_eq:NN \l_@@_list_tl \l_@@_list_current_tl } - { - \tl_put_right:NV \l_@@_list_tl \l_@@_list_separator_tl - \tl_put_right:NV \l_@@_list_tl \l_@@_list_current_tl - } - \tl_set:Nn \l_@@_list_current_tl { \@@_combined_output:n {#1} } - } -\cs_new_protected:Npn \@@_list_numbers_aux:nn #1#2 - { - \@@_combined_output:n {#1} - \l_@@_list_separator_pair_tl - \@@_combined_output:n {#2} - } +\NewDocumentCommand \sisetup { m } + { \keys_set:nn { siunitx } {#1} } % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\@@_list_units:nnn} -% For a list of items with units, the method is to first parse the -% unit when repeating (to save time), then to use the number loop above -% for the actual work. On the other hand, when the unit is only printed -% once life is easier as the normal unit printer can operate. +% \subsection{\enquote{Glue} commands} +% +% \begin{macro}{\@@_angle:nnn} +% The document level interface for \cs{ang} needs some \enquote{glue} to +% work with the code-level API. % \begin{macrocode} -\cs_new_protected:Npn \@@_list_units:nnn #1#2#3 +\cs_new_protected:Npn \@@_angle:nnn #1#2#3 { - \@@_unit_parse_options:nn {#2} {#3} - \bool_if:NTF \l_@@_list_repeat_bool - { - \@@_unit_in:nn {#2} {#3} - \@@_list_numbers_aux_i:n {#1} - } + \tl_if_novalue:nTF {#2} + { \siunitx_angle:n {#1} } { - \bool_if:NT \l_@@_process_fixed_bool - { \bool_set_true:N \l_@@_process_drop_exponent_bool } - \bool_if:NT \l_@@_list_brackets_bool - { \@@_print:nV { number } \l_@@_bracket_open_tl } - \@@_list_numbers:n {#1} - \bool_if:NT \l_@@_list_brackets_bool - { \@@_print:nV { number } \l_@@_bracket_close_tl } - \@@_range_exponent: - \@@_unit_output_number_sep: - \@@_unit_output:nn {#2} {#3} + \tl_if_novalue:nTF {#3} + { \siunitx_angle:nnn {#1} {#2} { } } + { \siunitx_angle:nnn {#1} {#2} {#3} } } } % \end{macrocode} % \end{macro} % -%\subsection{Ranges} +% \subsection{Table column} % -%\begin{macro}{\l_@@_range_brackets_bool} -%\begin{macro}{\l_@@_range_repeat_bool} -% Settings for ranges with units. +% User interfaces in tabular constructs are provided using the mechanisms from +% the \pkg{array} package. % \begin{macrocode} -\bool_new:N \l_@@_range_brackets_bool -\bool_new:N \l_@@_range_repeat_bool +\RequirePackage { array } % \end{macrocode} -%\end{macro} -%\end{macro} % -%\begin{macro}{\l_@@_range_phrase_tl} -% Simple settings for ranges. +% \begin{macro}{\@@_declare_column:Nnn} +% Creating numerical columns requires that these are declared before anything +% else in \cs{NC@list}: this is necessary to work with optional arguments. +% This means a bit of manual effort after the simple declaration of a new +% column type. The token assigned to the column type is not fixed as this +% allows the same code to be used in compatibility with version~$2$. % \begin{macrocode} -\keys_define:nn { siunitx } { - range-phrase .tl_set:N = \l_@@_range_phrase_tl, - range-units .choice:, - range-units - / brackets .code:n = - { - \bool_set_true:N \l_@@_range_brackets_bool - \bool_set_false:N \l_@@_range_repeat_bool - }, - range-units - / repeat .code:n = - { - \bool_set_false:N \l_@@_range_brackets_bool - \bool_set_true:N \l_@@_range_repeat_bool - }, - range-units - / single .code:n = - { - \bool_set_false:N \l_@@_range_brackets_bool - \bool_set_false:N \l_@@_range_repeat_bool - }, -} -\keys_set:nn { siunitx } { - range-phrase = { ~ to ~ }, - range-units = repeat, -} -% \end{macrocode} -%\end{macro} -% -% \begin{macro}{\@@_range_numbers:nn} -% \begin{macro}{\@@_range_numbers_core:nn} -% \begin{macro}{\@@_range_numbers_aux:n} -% A range of numbers. This is more restrictive than the \cs{num} -% function: nothing compound. -% \begin{macrocode} -\cs_new_protected:Npn \@@_range_numbers:nn #1#2 - { - \@@_range_numbers_aux:n {#1} - \l_@@_range_phrase_tl - \@@_range_numbers_aux:n {#2} - } -\cs_new_protected:Npn \@@_range_numbers_aux:n #1 +\cs_new_protected:Npn \@@_declare_column:Nnn #1#2#3 { - \bool_if:NTF \l_@@_number_parse_bool + \cs_if_exist:cT { NC@find@ #1 } { - \tl_clear:N \l_@@_number_out_tl - \tl_clear:N \l_@@_number_out_saved_tl - \bool_set_false:N \l_@@_number_compound_bool - \@@_number_output_parse:n {#1} - \bool_if:NT \l_@@_number_compound_bool - { \msg_error:nnx { siunitx } { multi-part-range } {#1} } + \cs_undefine:c { NC@find@ #1 } + \msg_warning:nnn { siunitx } { column-overwritten } {#1} } + \newcolumntype {#1} { } + \cs_set_protected:Npn \@@_tmp:w \NC@do ##1##2 \NC@do #1 + { \NC@list { \NC@do ##1 \NC@do #1 ##2 } } + \exp_after:wN \@@_tmp:w \the \NC@list + \exp_args:NNc \renewcommand * { NC@rewrite@ #1 } [ 1 ] [ ] { - \@@_unit_output_pre_print: - \@@_print:nn { number } {#1} - \@@_unit_output_print: - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -%\begin{macro}{\@@_range_unit:nnnn} -% Unit printing is also simple: basically a past-up job. The only compl -% \begin{macrocode} -\cs_new_protected:Npn \@@_range_unit:nnnn #1#2#3#4 { - \@@_unit_parse_options:nn {#1} {#2} - \bool_if:NTF \l_@@_range_repeat_bool - { - \@@_unit_in:nn {#1} {#2} - \@@_range_numbers_aux:n {#3} - \l_@@_range_phrase_tl - \@@_range_numbers_aux:n {#4} - } - { - \bool_if:NT \l_@@_process_fixed_bool - { \bool_set_true:N \l_@@_process_drop_exponent_bool } - \bool_if:NT \l_@@_range_brackets_bool - { \@@_print:nV { number } \l_@@_bracket_open_tl } - \@@_range_numbers:nn {#3} {#4} - \bool_if:NT \l_@@_range_brackets_bool - { \@@_print:nV { number } \l_@@_bracket_close_tl } - \@@_range_exponent: - \@@_unit_output_number_sep: - \@@_unit_output:nn {#1} {#2} - } -} -% \end{macrocode} -%\end{macro} -% -% \begin{macro}{\@@_range_exponent:} -% The idea here is to construct and print an exponent if this is fixed, -% and thus removed from the range. This function is also used by the -% related list concept. -% \begin{macrocode} -\cs_new_protected:Npn \@@_range_exponent: - { - \bool_if:NT \l_@@_process_fixed_bool - { - \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_exponent_product_tl - \bool_if:NT \l_@@_tight_bool + \@temptokena \expandafter { - \tl_set:Nx \l_@@_tmpa_tl - { \exp_not:N \mathord \exp_not:o \l_@@_tmpa_tl } + \the \@temptokena + > {#2} c < {#3} } - \tl_set:Nx \l_@@_tmpa_tl - { - \exp_not:N \ensuremath { { } \exp_not:o \l_@@_tmpa_tl { } } - 10 \exp_not:N \PrintSuperscript - { \int_use:N \l_@@_process_fixed_int } - } - \@@_print:nV { number } \l_@@_tmpa_tl + \NC@find } } +\msg_new:nnn { siunitx } { column-overwritten } + { Tabular~column~type~"#1"~overwritten~with~siunitx~definition. } % \end{macrocode} -% \end{macro} -% -%\subsection{Setting up tables} -% -% There is a slight problem with the \pkg{cellspace} package: it also -% uses \texttt{S} for a column type Here, \texttt{S} seems to make -% more sense for \pkg{siunitx}, with \texttt{C} used for -% \pkg{cellspace}. To enable this to work well, the column -% rewriting code happens \cs{AtBeginDocument}. The \texttt{S} column -% is deleted from \cs{NC@list} so that no warning appears. -% \begin{macrocode} -\AtBeginDocument { - \@ifpackageloaded { cellspace } - { - \cs_if_exist:NT \NC@find@S - { - \newcolumntype { C } [1] - { > { \bcolumn #1 \@nil } #1 < { \ecolumn } } - \cs_set:Npn \@@_tmp:w #1 \NC@do S #2 \q_stop - { \NC@list { #1 #2 } } - \exp_after:wN \@@_tmp:w \tex_the:D \NC@list \q_stop - \cs_undefine:N \NC@find@S - \msg_new:nnn { siunitx } { moved-cellspace-column } - { Column~type~for~cellspace~package~moved~to~'#1'. } - \msg_warning:nnn { siunitx } { moved-cellspace-column } { C } - \ifcellspace@m - \def \env@matrix - { - \hskip -\arraycolsep - \let \@ifnextchar \new@ifnextchar - \array - { - * { \c@MaxMatrixCols } - { > { \bcolumn c \@nil $ } c < { $ \ecolumn } } @ { } - } - } - \fi - } - } - { } -} -% \end{macrocode} -% -%\begin{macro}{\@@_table_rewrite_create:N} -%\begin{macro}{\@@_table_rewrite_create_aux:w} -% The \texttt{s} and \texttt{S} column types are both created using -% the \pkg{array} package, but with the internal macros redefined -% to work with optional argument. First, there is a need to do a -% quick shuffle with the \cs{NC@list} macro. The \pkg{siunitx} -% columns have to be listed first, as otherwise the optional -% arguments do not work correctly. So they are added \enquote{by hand} -% to the appropriate macro. +% When \pkg{mdwtab} is loaded the syntax required is slightly different. % \begin{macrocode} -\cs_new_protected:Npn \@@_table_rewrite_create:N #1 { - \newcolumntype {#1} { } - \cs_set_protected:Npn - \@@_table_rewrite_create_aux:w \NC@do ##1##2 \NC@do #1 - { \NC@list { \NC@do ##1 \NC@do #1 ##2 } } - \exp_after:wN \@@_table_rewrite_create_aux:w \tex_the:D \NC@list - \exp_args:NNc \renewcommand * { NC@rewrite@ #1 } [1] [ ] - { - \@temptokena \exp_after:wN - { - \tex_the:D \@temptokena - > { \@@_table_collect_begin:Nn #1 {##1} } - c - < { \@@_table_print: } - } - \NC@find - } -} \AtBeginDocument { \@ifpackageloaded { mdwtab } { - \cs_set_protected:Npn \@@_table_rewrite_create:N #1 + \cs_set_protected:Npn \@@_declare_column:Nnn #1#2#3 { - \newcolumntype {#1} [1] [] - { - > { \@@_table_collect_begin:Nn #1 {##1} } - c - < { \@@_table_print: } - } + \cs_if_exist:cT { NC@find@ #1 } + { + \cs_undefine:c { NC@find@ #1 } + \msg_warning:nnn { siunitx } { column-overwritten } {#1} + } + \newcolumntype {#1} [ 1 ] [ ] + { > {#2} c < {#3} } } } { } - } -\cs_new_protected:Npn \@@_table_rewrite_create_aux:w { } -\AtBeginDocument { \@@_table_rewrite_create:N s } -\AtBeginDocument { \@@_table_rewrite_create:N S } -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Collecting tokens in tables} -% -% The table system is in two parts, collecting tokens and typesetting -% the result. The collection routine tries to ensure that the -% typesetting part only receives real cell contents. -% -%\begin{macro}{\l_@@_table_collect_tl} -%\begin{macro}{\l_@@_table_collect_pre_tl} -%\begin{macro}{\l_@@_table_collect_post_tl} -% Three storage areas. -% \begin{macrocode} -\tl_new:N \l_@@_table_collect_tl -\tl_new:N \l_@@_table_collect_pre_tl -\tl_new:N \l_@@_table_collect_post_tl -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\l_@@_number_valid_tl} -% As the \texttt{S} column has to make a judgement about tokens which -% can be part of a number, there is a need to have a list of valid -% tokens. -% \begin{macrocode} -\tl_new:N \l_@@_number_valid_tl -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_table_math_bool} -% A flag used inside the table cell to track math mode: there is -% a need to do things by hand as otherwise the grouping goes -% wrong. -% \begin{macrocode} -\bool_new:N \l_@@_table_math_bool -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\l_@@_table_collect_pre_bool} -%\begin{macro}{\l_@@_table_collect_post_bool} -% Flags for having found a number in an \texttt{S} column. -% \begin{macrocode} -\bool_new:N \l_@@_table_collect_pre_bool -\bool_new:N \l_@@_table_collect_post_bool -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_begin:Nn} -%\begin{macro}{\@@_table_collect_begin:Nw} -%\begin{macro}{\@@_table_collect_begin_s:} -%\begin{macro}{\@@_table_collect_begin_S:} -% The collector starts by setting up local options, then clears and -% initialises the storage and testing system. Font detection for the -% \texttt{S} column happens here as this ensures that it is not inside -% a box, which will give the wrong result for \opt{detect-mode}. The -% |\use_i:nn| removes the |\ignorespaces| from the cell preamble. -% In the basic \LaTeXe{} template there is only an |\ignorespaces| -% before the content, but to deal with any other material we use -% a delimited approach. It's important to grab everything up to the -% end of the template-before-|#| to allow the Appendix~D trick to work -% inside the |peek| code. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_begin:Nn #1#2 - { - \keys_set:nn { siunitx } {#2} - \@@_table_collect_begin:Nw #1 - } -\cs_new_protected:Npn \@@_table_collect_begin:Nw #1#2 \ignorespaces - { \use:c { @@_table_collect_begin_ #1 : } #2 } -\cs_new_protected:Npn \@@_table_collect_begin_s: { - \cs_set_eq:NN \@@_table_collect_token:N - \@@_table_collect_token_s:N - \cs_set_eq:NN \@@_table_print: \@@_table_print_s: - \@@_table_collect_init_s: - \@@_table_collect_get: -} -\cs_new_protected:Npn \@@_table_collect_begin_S: { - \cs_set_eq:NN \@@_table_collect_token:N - \@@_table_collect_token_S:N - \cs_set_eq:NN \@@_table_print: \@@_table_print_S: - \@@_table_collect_init_S: - \@@_detect_font: - \bool_if:NTF \l_@@_number_parse_bool - { \@@_table_collect_get: } - { \@@_table_print_S_direct: } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_braced:n} -% The collection of braced items depends on the column type. So we -% start of with an empty definition. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_braced:n #1 { } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_expand:N} -%\begin{macro}{\@@_table_collect_expand_math:N} -% The idea here is to expand content if possible. There are a few -% things to note. Only macros which are not long or protected are -% expanded. There is the possibility that the macro may need the -% contents of the pre-numeral part to be executed, for example see -% \cref{tab:xmpl:calc} in the user part of the documentation. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_expand:N #1 { - \cs_if_eq:NNTF #1 \color - { - \bool_if:NTF \l_@@_table_collect_pre_bool - { - \tl_clear:N \l_@@_number_color_tl - \tl_clear:N \l_@@_unit_color_tl - \tl_put_right:Nn \l_@@_table_collect_pre_tl {#1} - } - { - \bool_set_true:N \l_@@_table_collect_post_bool - \tl_put_right:Nn \l_@@_table_collect_post_tl {#1} - } - } - { - \@@_cs_if_tl:NTF #1 - { - \tl_use:N \l_@@_table_collect_pre_tl - \tl_clear:N \l_@@_table_collect_pre_tl - \cs_set:Npn \@@_table_collect_next: - { \exp_after:wN \@@_table_collect_get: #1 } - } - { - \bool_if:NTF \l_@@_table_collect_pre_bool - { - \tl_put_right:Nn \l_@@_table_collect_pre_tl {#1} - \@@_table_collect_expand_math:N #1 - } - { - \bool_set_true:N \l_@@_table_collect_post_bool - \tl_put_right:Nn \l_@@_table_collect_post_tl {#1} - } - } - } -} -% \end{macrocode} -% There is a need to keep a track of math mode, so that there are no -% disasters when the tokens are boxed up later. The ideal is to know -% the math state of the collected tokens so that appropriate -% steps can be taken to insert math shift tokens later. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_expand_math:N #1 { - \token_if_math_toggle:NTF #1 - { - \bool_if:NTF \l_@@_table_math_bool - { \bool_set_false:N \l_@@_table_math_bool } - { \bool_set_true:N \l_@@_table_math_bool } - } - { - \cs_if_eq:NNTF #1 \( % \) - { \bool_set_true:N \l_@@_table_math_bool } - { % \( - \cs_if_eq:NNT #1 \) - { \bool_set_false:N \l_@@_table_math_bool } - } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_get:} -% The token collection system first has to check that the next argument -% does not start with an opening-brace character. If it does, the -% testing is skipped and the braced token is stored. Otherwise, a check -% is made against various ignored tokens. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_get: - { - \cs_set_eq:NN \@@_table_collect_next: - \@@_table_collect_get: - \peek_catcode_ignore_spaces:NTF \c_group_begin_token - { \@@_table_collect_braced:n } - { \@@_table_collect_not_braced:N } - } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_init:} -% The usual spin-out of basics. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_init: { - \tl_clear:N \l_@@_table_collect_tl - \tl_clear:N \l_@@_table_collect_pre_tl - \tl_clear:N \l_@@_table_collect_post_tl - \bool_set_false:N \l_@@_table_collect_post_bool - \bool_set_false:N \l_@@_table_math_bool -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@_table_collect_init_s:} -%\begin{macro}{\@@_table_collect_init_S:} -% Some type-specific definitions. In the \texttt{S} case, the -% initialisation function for numbers is used to set -% \cs{l_@@_number_valid_tl} correctly. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_init_s: { - \@@_table_collect_init: - \bool_set_false:N \l_@@_table_collect_pre_bool - \cs_set_protected:Npn \@@_table_collect_braced:n ##1 - { - \tl_put_right:Nn \l_@@_table_collect_tl { {##1} } - \@@_table_collect_next: - } -} -\cs_new_protected:Npn \@@_table_collect_init_S: { - \@@_number_in_init: - \tl_set:Nx \l_@@_number_valid_tl - { - \exp_not:V \l_@@_input_complex_tl - \exp_not:V \l_@@_input_decimal_tl - \exp_not:V \l_@@_input_digit_tl - \exp_not:V \l_@@_input_exponent_tl - \exp_not:V \l_@@_input_ignore_tl - \exp_not:V \l_@@_input_comparator_tl - \exp_not:V \l_@@_input_uncert_close_tl - \exp_not:V \l_@@_input_uncert_open_tl - \exp_not:V \l_@@_input_sign_tl - \exp_not:V \l_@@_input_symbol_tl - } - \bool_set_true:N \l_@@_table_collect_pre_bool - \cs_set_protected:Npn \@@_table_collect_braced:n ##1 - { - \bool_if:NTF \l_@@_table_collect_pre_bool - { \tl_put_right:Nn \l_@@_table_collect_pre_tl { {##1} } } - { - \bool_set_true:N \l_@@_table_collect_post_bool - \tl_put_right:Nn \l_@@_table_collect_post_tl { {##1} } - } - \@@_table_collect_next: - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_next:} -% A holder for the next thing to do. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_next: { } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_newline:} -% The end macro needs to come before the new line is called. The -% print function is redefined so that it only actually does stuff once. -% As each cell is a group anyway, there is no need to save the -% definition of \cs{@@_table_print:}, as it will re-appear on its -% own. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_newline: { - \@@_table_print: - \cs_set_eq:NN \@@_table_print: \prg_do_nothing: - \tabularnewline -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_end:} -% The same concept applies to the \cs{end} macro. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_end: { - \@@_table_print: - \cs_set_eq:NN \@@_table_print: \prg_do_nothing: - \end -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_not_braced:N} -%\begin{macro}{\@@_table_collect_not_braced_aux_i:N} -%\begin{macro}{\@@_table_collect_not_braced_aux_ii:N} -% A few macros are simply passed through to be executed; this is mainly -% so that the table actually works. The newline function needs its own -% function, which is picked up by hand. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_not_braced:N #1 - { - \token_if_eq_meaning:NNF #1 \tex_ignorespaces:D - { - \token_if_eq_meaning:NNF #1 \tex_unskip:D - { \@@_table_collect_not_braced_aux_i:N #1 } - } - \@@_table_collect_next: - } -\AtBeginDocument - { - \@ifpackageloaded { mdwtab } + \tl_map_inline:Nn \l_@@_column_type_tl { - \cs_set_protected:Npn \@@_table_collect_not_braced:N #1 + \@@_declare_column:Nnn #1 { - \token_if_eq_meaning:NNF #1 \tex_ignorespaces:D - { - \token_if_eq_meaning:NNF #1 \tex_unskip:D - { - \token_if_eq_meaning:NNF #1 \tab@setcr - { - \token_if_eq_meaning:NNF #1 \@maybe@unskip - { \@@_table_collect_not_braced_aux_i:N #1 } - } - } - } - \@@_table_collect_next: + \keys_set:nn { siunitx } {##1} + \siunitx_cell_begin:w } + { \siunitx_cell_end: } } - { } } -\cs_new_protected:Npn \@@_table_collect_not_braced_aux_i:N #1 { - \cs_set:Npn \@@_table_collect_not_braced_aux_ii:N ##1 - { - \token_if_eq_meaning:NNT #1 ##1 - { \cs_set_eq:NN \@@_table_collect_next: ##1 } - } - \tl_map_function:nN - { \cs:w \scan_stop: \@@_table_print: } - \@@_table_collect_not_braced_aux_ii:N - \token_if_eq_meaning:NNT \@@_table_collect_next: - \@@_table_collect_get: - { - \token_if_eq_meaning:NNTF #1 \tabularnewline - { - \cs_set_eq:NN \@@_table_collect_next: - \@@_table_collect_newline: - } - { - \token_if_eq_meaning:NNTF #1 \end - { - \cs_set_eq:NN \@@_table_collect_next: - \@@_table_collect_end: - } - { \@@_table_collect_token:N #1 } - } - } -} -\cs_new_protected:Npn \@@_table_collect_not_braced_aux_ii:N #1 { } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\@@_table_collect_token:N} -%\begin{macro}{\@@_table_collect_token_s:N} -% For the \texttt{s} column, every token is added to the same storage -% area, so life is simple. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_token:N #1 { } -\cs_new_protected:Npn \@@_table_collect_token_s:N #1 { - \tl_put_right:Nn \l_@@_table_collect_tl {#1} -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\begin{macro}{\@@_table_collect_token_S:N} -% Not so easy for the \texttt{S} column type. If the content is after -% a number, things are easy. On the other hand, if the token might be -% a number, then a check is made. It the token is still unmatched, then -% it is passed on to the expansion handler. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_collect_token_S:N #1 { - \bool_if:NTF \l_@@_table_collect_post_bool - { \tl_put_right:Nn \l_@@_table_collect_post_tl {#1} } - { - \tl_if_in:NnTF \l_@@_number_valid_tl {#1} - { - \bool_set_false:N \l_@@_table_collect_pre_bool - \tl_put_right:Nn \l_@@_table_collect_tl {#1} - } - { \@@_table_collect_expand:N #1 } - } -} % \end{macrocode} -%\end{macro} -% -% \subsection{Table printing: general code} +% \end{macro} % -% Getting the general alignment correct in tables is made more -% complex than one would like by the \pkg{colortbl} package. In the -% original \LaTeXe{} definition, cell material is centred by a -% construction of the (primitive) form -% \begin{verbatim} -% \hfil -% # -% \hfil -% \end{verbatim} -% which only uses \texttt{fil} stretch. That is altered by -% \pkg{colortbl} to broadly -% \begin{verbatim} -% \hskip 0 pt plus 0.5 fill -% \kern 0 pt -% # -% \hskip 0 pt plus 0.5 fill -% \end{verbatim} -% which means there is \texttt{fill} stretch to worry about and -% the kern as well. +% \subsection{Document commands in bookmarks} % -% \begin{variable}{\c_@@_one_fill_skip} -% A fixed skip of one \texttt{fill}. -% \begin{macrocode} -\skip_const:Nn \c_@@_one_fill_skip { 0pt plus 1fill } -% \end{macrocode} -% \end{variable} +% In bookmarks, the \pkg{siunitx} document commands need to produce simple +% strings that represent their input as far a possible. % -% \begin{macro}{\@@_table_colortbl_correction:} -% If the package \pkg{colortbl} is loaded, there is a need to allow -% that it changes how centring is carried out. +% \begin{macro}{\@@_bookmark_cmd:Nn} +% To keep things fast, expandable versions of the document command are +% created only once. As here we are at the top-level for internal names, +% we can use the various parts of \pkg{siunitx-compound} that would otherwise +% be inaccessible. % \begin{macrocode} -\AtBeginDocument +\cs_new_protected:Npn \@@_bookmark_cmd:Nnn #1#2#3 { - \@ifpackageloaded { colortbl } - { - \cs_new_protected:Npn \@@_table_colortbl_correction: - { - \skip_horizontal:n { 0pt plus -0.5fill } - \tex_kern:D \c_zero_skip - } - } - { \cs_new_protected:Npn \@@_table_colortbl_correction: { } } + \exp_args:Nc \DeclareExpandableDocumentCommand + { \cs_to_str:N #1 \c_space_tl ( pdfstring ~ context ) } + {#2} {#3} } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_align_left:n} -% \begin{macro}{\@@_table_align_right:n} -% These are simple shortcuts to keep life clearer in the rest of the -% code. The idea is that the kern acts as a \enquote{stop} for the -% horizontal skip. The correction for \pkg{colortbl} is separate as the -% spacing needs to be explicitly deleted. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_align_left:n #1 +\@@_bookmark_cmd:Nnn \qty { o m m } { #2 ~ #3 } +\@@_bookmark_cmd:Nnn \ang { m } { \@@_angle:n {#1} } +\@@_bookmark_cmd:Nnn \num { o m } { #2 } +\@@_bookmark_cmd:Nnn \unit { o m } { #2 } +\@@_bookmark_cmd:Nnn \numlist { o m } { - \@@_table_colortbl_correction: - \skip_horizontal:n {#1} - \tex_kern:D \c_zero_skip + \@@_list_use:nnVVV {#2} { } + \l_siunitx_list_separator_pair_tl + \l_siunitx_list_separator_tl + \l_siunitx_list_separator_final_tl } -\cs_new_protected:Npn \@@_table_align_right:n #1 +\@@_bookmark_cmd:Nnn \qtylist { o m m } { - \skip_horizontal:n { \c_@@_one_fill_skip - #1 } - \tex_kern:D \c_zero_skip - \@@_table_colortbl_correction: + \@@_list_use:nnVVV {#2} {#3} + \l_siunitx_list_separator_pair_tl + \l_siunitx_list_separator_tl + \l_siunitx_list_separator_final_tl } +\@@_bookmark_cmd:Nnn \numproduct { o m } { } +\@@_bookmark_cmd:Nnn \qtyproduct { o m m } { } +\@@_bookmark_cmd:Nnn \numrange { o m m } + { #2 \tl_use:N \l_siunitx_range_phrase_tl #3 } +\@@_bookmark_cmd:Nnn \qtyrange { o m m m } + { #2 ~ #4 \tl_use:N \l_siunitx_range_phrase_tl #3 ~ #4 } % \end{macrocode} % \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_table_column_begin:} -% \begin{macro}{\@@_table_column_end:} -% \begin{macrocode} -\cs_new_eq:NN \@@_table_column_begin:n \@@_table_align_left:n -\cs_new_eq:NN \@@_table_column_end:n \@@_table_align_right:n -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% Setting up for a fixed column width is done so that the check is -% made at the key-setting stage. In that way, there will be some -% speed gained if the key is set before the table, as the comparison -% is not made for every cell. +% We also need the v2 names. % \begin{macrocode} -\keys_define:nn { siunitx } +\@@_bookmark_cmd:Nnn \si { o m } { #2 } +\@@_bookmark_cmd:Nnn \SI { o m O { } m } { #3 #2 ~ #4 } +\@@_bookmark_cmd:Nnn \SIlist { o m m } { - table-column-width .code:n = - { - \dim_compare:nNnTF {#1} = { \c_zero_dim } - { - \cs_set_eq:NN \@@_table_column_begin:n - \@@_table_align_left:n - \cs_set_eq:NN \@@_table_column_end:n - \@@_table_align_right:n - } - { - \cs_set_protected:Npn \@@_table_column_begin:n ##1 - { - \@@_table_colortbl_correction: - \tex_hbox:D to \dim_eval:n {#1} - \c_group_begin_token - \skip_horizontal:n {##1} - \tex_kern:D \c_zero_skip - } - \cs_set_protected:Npn \@@_table_column_end:n ##1 - { - \skip_horizontal:n { \c_@@_one_fill_skip - ##1 } - \tex_kern:D \c_zero_skip - \c_group_end_token - \@@_table_colortbl_correction: - } - } - } - } -% \end{macrocode} -% -% \subsection{Printing units in \texttt{s} columns} -% -% The easiest type of printing is the \texttt{s} column. Here, there is -% no real problem with alignment. All that has to happen is to print the -% collected input as the argument to the internal part of an \cs{si} -% function. -% -% \begin{variable}{\l_@@_table_unit_align_skip} -% The spacing used is stored as a skip, which needs to be set up first. -% \begin{macrocode} -\skip_new:N \l_@@_table_unit_align_skip -% \end{macrocode} -% \end{variable} -% -% \begin{macrocode} -\keys_define:nn { siunitx } - { - table-unit-alignment .choice:, - table-unit-alignment / - center .code:n = - { - \skip_set:Nn \l_@@_table_unit_align_skip - { 0pt plus 0.5fill } - }, - table-unit-alignment / - left .code:n = - { \skip_set:Nn \l_@@_table_unit_align_skip { \c_zero_skip } }, - table-unit-alignment / - right .code:n = - { - \skip_set:Nn \l_@@_table_unit_align_skip - { 0pt plus 1fill } - } + \@@_list_use:nnVVV {#2} {#3} + \l_siunitx_list_separator_pair_tl + \l_siunitx_list_separator_tl + \l_siunitx_list_separator_final_tl } -\keys_set:nn { siunitx } { table-unit-alignment = center } +\@@_bookmark_cmd:Nnn \SIrange { o m m m } + { #2 ~ #4 \tl_use:N \l_siunitx_range_phrase_tl #3 ~ #4 } % \end{macrocode} % -% \begin{macro}{\@@_table_print_s:} -% Actually printing an \texttt{s} column is not very complex. There is -% some spacing to do at each side, with the main part of the job being -% to print the material using the internal version of \cs{si}. +% \begin{variable}{\c_@@_bookmark_seq} +% Commands usable in bookmarks % \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_s: +\seq_const_from_clist:Nn \c_@@_bookmark_seq { - \@@_table_column_begin:n { \l_@@_table_unit_align_skip } - \tl_if_empty:NF \l_@@_table_collect_tl - { \@@_unit_output:Vn \l_@@_table_collect_tl { } } - \@@_table_column_end:n { \l_@@_table_unit_align_skip } + \ang , \qty , \num , \unit , + \numlist , \qtylist , + \numrange , \qtyrange , + \si , \SI , \SIlist , \SIrange } % \end{macrocode} -% \end{macro} -% -% \subsection{Formatting and printing in tables} -% -% With the content grabbed, the next stage is to turn it into formatted -% output then print it. Most of the formatting is done elsewhere, so -% most of the work here is in printing. -% -% \begin{variable}{\l_@@_table_model_prop} -% A place to store the model for reserved-space table columns. -% \begin{macrocode} -\prop_new:N \l_@@_table_model_prop -% \end{macrocode} -% \end{variable} -% -% \begin{variable} -% { -% \l_@@_table_exponent_dim , -% \l_@@_table_integer_dim , -% \l_@@_table_mantissa_dim , -% \l_@@_table_marker_dim , -% \l_@@_table_result_dim , -% \l_@@_table_uncert_dim -% } -% Dimensions to track the various spaces needed. -% \begin{macrocode} -\dim_new:N \l_@@_table_exponent_dim -\dim_new:N \l_@@_table_integer_dim -\dim_new:N \l_@@_table_mantissa_dim -\dim_new:N \l_@@_table_marker_dim -\dim_new:N \l_@@_table_result_dim -\dim_new:N \l_@@_table_uncert_dim -% \end{macrocode} -%\end{variable} -% -% \begin{variable} -% {\l_@@_table_fill_pre_dim, \l_@@_table_fill_post_dim} -% Calculating the fill needed can be a bit complicated, so is best -% done using a dedicated dimension. There is a second one for cases dealing -% with fill at the end of a number, where there may be some rearrangement. -% \begin{macrocode} -\dim_new:N \l_@@_table_fill_pre_dim -\dim_new:N \l_@@_table_fill_post_dim -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_table_fill_mid_dim} -% For the reserved space approach there is also the need for a third -% piece of fill, which may or may not be used. -% \begin{macrocode} -\dim_new:N \l_@@_table_fill_mid_dim -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_table_pre_box, \l_@@_table_post_box} -% Boxes for the content before and after the numerical part. -% \begin{macrocode} -\box_new:N \l_@@_table_pre_box -\box_new:N \l_@@_table_post_box -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_table_mantissa_box} -% When printing with space reserved, the mantissa needs to hang around -% for a while. This is best done by storing the typeset result in a box. -% \begin{macrocode} -\box_new:N \l_@@_table_mantissa_box -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_table_result_box} -% The box which is actually needed for printing. -% \begin{macrocode} -\box_new:N \l_@@_table_result_box -% \end{macrocode} -% \end{variable} -% -% \begin{variable} -% {\l_@@_table_number_align_skip, \l_@@_table_text_align_skip} -% Skips for aligning text and numbers. -% \begin{macrocode} -\skip_new:N \l_@@_table_number_align_skip -\skip_new:N \l_@@_table_text_align_skip -% \end{macrocode} % \end{variable} % -% \begin{macro} -% { -% \@@_table_print_S_direct_main: , -% \@@_table_print_S_parsed: -% } -% \begin{macro}{\@@_table_print_S_reserved_store_fill:n} -% Various functions which are set up by the option system, and so are -% reserved here first for completeness. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_direct_main: { } -\cs_new_protected:Npn \@@_table_print_S_parsed: { } -\cs_new_protected:Npn \@@_table_print_S_reserved_store_fill:n #1 { } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{variable} -% { -% \l_@@_table_align_exponent_bool, -% \l_@@_table_align_text_pre_bool, -% \l_@@_table_align_text_post_bool, -% \l_@@_table_align_uncert_bool, -% \l_@@_table_auto_round_bool, -% \l_@@_table_omit_exponent_bool, -% \l_@@_table_parse_only_bool, -% \l_@@_table_pre_tl, -% \l_@@_table_post_tl -% } +% Activate the document commands here: the unit macros are handled in +% \pkg{siunitx-final}. % \begin{macrocode} -\keys_define:nn { siunitx } +\AtBeginDocument { - table-align-comparator .choice:, - table-align-comparator / - false .code:n = - { - \cs_set_eq:NN \@@_table_print_S_reserved_store_fill:n - \@@_table_print_S_reserved_store_fill_pre:n - }, - table-align-comparator / - true .code:n = - { - \cs_set_eq:NN \@@_table_print_S_reserved_store_fill:n - \@@_table_print_S_reserved_store_fill_mid:n - }, - table-align-comparator .default:n = true, - table-align-exponent .bool_set:N = - \l_@@_table_align_exponent_bool, - table-align-text-pre .bool_set:N = - \l_@@_table_align_text_pre_bool, - table-align-text-post .bool_set:N = - \l_@@_table_align_text_post_bool, - table-align-uncertainty .bool_set:N = \l_@@_table_align_uncert_bool, - table-auto-round .bool_set:N = \l_@@_table_auto_round_bool, - table-number-alignment .choice:, - table-number-alignment / - center .code:n = - { - \skip_set:Nn \l_@@_table_number_align_skip - { 0pt plus 0.5fill } - \cs_set_eq:NN \@@_table_print_S_direct_main: - \@@_table_print_S_direct_reserved: - \cs_set_eq:NN \@@_table_print_S_parsed: - \@@_table_print_S_reserved: - }, - table-number-alignment / - center-decimal-marker .code:n = - { - \skip_set:Nn \l_@@_table_number_align_skip - { 0pt plus 0.5fill } - \cs_set_eq:NN \@@_table_print_S_direct_main: - \@@_table_print_S_direct_centered: - \cs_set_eq:NN \@@_table_print_S_parsed: - \@@_table_print_S_centered: - }, - table-number-alignment / - left .code:n = - { - \skip_zero:N \l_@@_table_number_align_skip - \cs_set_eq:NN \@@_table_print_S_direct_main: - \@@_table_print_S_direct_reserved: - \cs_set_eq:NN \@@_table_print_S_parsed: - \@@_table_print_S_reserved: - }, - table-number-alignment / - right .code:n = - { - \skip_set:Nn \l_@@_table_number_align_skip - { 0pt plus 1fill } - \cs_set_eq:NN \@@_table_print_S_direct_main: - \@@_table_print_S_direct_reserved: - \cs_set_eq:NN \@@_table_print_S_parsed: - \@@_table_print_S_reserved: - }, - table-omit-exponent .bool_set:N = - \l_@@_table_omit_exponent_bool, - table-text-alignment .choice:, - table-text-alignment / - center .code:n = - { - \skip_set:Nn \l_@@_table_text_align_skip - { 0pt plus 0.5fill } - }, - table-text-alignment / - left .code:n = - { \skip_zero:N \l_@@_table_text_align_skip }, - table-text-alignment / - right .code:n = - { - \skip_set:Nn \l_@@_table_text_align_skip - { 0pt plus 1fill } - }, - table-comparator .choice:, - table-comparator / - false .code:n = - { \prop_remove:Nn \l_@@_table_model_prop { comparator } }, - table-comparator / - true .code:n = - { \prop_put:Nnn \l_@@_table_model_prop { comparator } { > } }, - table-comparator .default:n = true, - table-figures-decimal .code:n = + \@ifpackageloaded { hyperref } { - \int_compare:nNnTF {#1} = 0 + \pdfstringdefDisableCommands { - \prop_remove:Nn \l_@@_table_model_prop { mantissa-decimal } - \prop_remove:Nn \l_@@_table_model_prop { mantissa-decimal-raw } - \prop_remove:Nn \l_@@_table_model_prop - { mantissa-decimal-marker } - \prop_if_in:NnTF \l_@@_table_model_prop { mantissa-integer } + \seq_map_inline:Nn \c_@@_bookmark_seq { - \prop_put:Nnn \l_@@_table_model_prop { mantissa } - { true } + \cs_set_eq:Nc #1 + { \cs_to_str:N #1 \c_space_tl ( pdfstring ~ context ) } } - { \prop_remove:Nn \l_@@_table_model_prop { mantissa } } - } - { - \prop_put:Nnx \l_@@_table_model_prop { mantissa-decimal } - { \prg_replicate:nn {#1} { 8 } } - \prop_put:Nnn \l_@@_table_model_prop { mantissa-decimal-raw } - {#1} - \prop_put:Nnn \l_@@_table_model_prop { mantissa } { true } - \prop_put:NnV \l_@@_table_model_prop - { mantissa-decimal-marker } \l_@@_output_decimal_tl - } - }, - table-figures-exponent .code:n = - { - \int_compare:nNnTF {#1} = 0 - { \prop_remove:Nn \l_@@_table_model_prop { exponent-integer } } - { - \prop_put:Nnx \l_@@_table_model_prop { exponent-integer } - { \prg_replicate:nn {#1} { 8 } } - \prop_put:Nnn \l_@@_table_model_prop { exponent } { true } } - }, - table-figures-integer .code:n = - { - \int_compare:nNnTF {#1} = 0 + \pdfstringdefDisableCommands { - \prop_remove:Nn \l_@@_table_model_prop { mantissa-integer } - \prop_if_in:NnTF \l_@@_table_model_prop { mantissa-decimal } + \siunitx_unit_pdfstring_context: + \cs_if_exist:NT \FB@fg { \def \fg { \FB@fg } } + \edef \H { - \prop_put:Nnn \l_@@_table_model_prop { mantissa } - { true } + \exp_not:c { PU-cmd } + \exp_not:N \H + \exp_not:c { PU \token_to_str:N \H } } - { \prop_remove:Nn \l_@@_table_model_prop { mantissa } } - } - { - \prop_put:Nnx \l_@@_table_model_prop { mantissa-integer } - { \prg_replicate:nn {#1} { 8 } } - \prop_put:Nnn \l_@@_table_model_prop { mantissa } { true } - } - }, - table-figures-uncertainty .code:n = - { - \int_compare:nNnTF {#1} = 0 - { \prop_remove:Nn \l_@@_table_model_prop { mantissa-uncertainty } } - { - \prop_put:Nnx \l_@@_table_model_prop { mantissa-uncertainty } - { \prg_replicate:nn {#1} { 8 } } - } - }, - table-parse-only .bool_set:N = \l_@@_table_parse_only_bool, - table-space-text-pre .tl_set:N = \l_@@_table_pre_tl, - table-space-text-post .tl_set:N = \l_@@_table_post_tl, - table-sign-exponent .choice:, - table-sign-exponent / true .code:n = - { \prop_put:Nnn \l_@@_table_model_prop { exponent-sign } { - } }, - table-sign-exponent / false .code:n = - { \prop_remove:Nn \l_@@_table_model_prop { exponent-sign } }, - table-sign-exponent .default:n = true, - table-sign-mantissa .choice:, - table-sign-mantissa / true .code:n = - { \prop_put:Nnn \l_@@_table_model_prop { mantissa-sign } { - } }, - table-sign-mantissa / false .code:n = - { \prop_remove:Nn \l_@@_table_model_prop { mantissa-sign } }, - table-sign-mantissa .default:n = true, - } -% \end{macrocode} -% \end{variable} -% -% A meta-choice for all table alignment is also provided. -% \begin{macrocode} -\keys_define:nn { siunitx } - { - table-alignment .meta:n = - { - table-number-alignment = #1, - table-text-alignment = #1, - table-unit-alignment = #1 - } - } -% \end{macrocode} -% -% Another special option. This converts a number format in compacted -% form into the various internal settings needed. -% \begin{macrocode} -\keys_define:nn { siunitx } - { - table-format .code:n = - { - \bool_set_eq:NN \l_@@_process_plus_saved_bool \l_@@_process_plus_bool - \bool_set_true:N \l_@@_process_plus_bool - \@@_number_in_parse:n {#1} - \prop_set_eq:NN \l_@@_table_model_prop \l_@@_number_in_prop - \tl_clear:N \l_@@_tmpa_tl - \prop_get:NnNT \l_@@_number_in_prop { mantissa-integer } - \l_@@_tmpb_tl - { - \tl_set:Nx \l_@@_tmpa_tl - { table-figures-integer = \l_@@_tmpb_tl } - } - \prop_get:NnNT \l_@@_number_in_prop { mantissa-decimal } - \l_@@_tmpb_tl - { - \clist_put_right:Nx \l_@@_tmpa_tl - { table-figures-decimal = \l_@@_tmpb_tl } - } - \prop_get:NnNT \l_@@_number_in_prop { mantissa-uncertainty } - \l_@@_tmpb_tl - { - \clist_put_right:Nx \l_@@_tmpa_tl - { table-figures-uncertainty = \l_@@_tmpb_tl } - } - \prop_if_in:NnTF \l_@@_number_in_prop { mantissa-sign } - { - \clist_put_right:Nn \l_@@_tmpa_tl - { table-sign-mantissa =true } - } - { - \clist_put_right:Nn \l_@@_tmpa_tl - { table-sign-mantissa =false } - } - \prop_get:NnNT \l_@@_number_in_prop { exponent-integer } - \l_@@_tmpb_tl - { - \clist_put_right:Nx \l_@@_tmpa_tl - { table-figures-exponent = \l_@@_tmpb_tl } - } - \prop_if_in:NnTF \l_@@_number_in_prop { exponent-sign } - { - \clist_put_right:Nn \l_@@_tmpa_tl - { table-sign-exponent =true } - } - { - \clist_put_right:Nn \l_@@_tmpa_tl - { table-sign-exponent =false } - } - \clist_put_right:Nn \l_@@_tmpa_tl - { table-number-alignment = center } - \keys_set:nV { siunitx } \l_@@_tmpa_tl - \bool_set_eq:NN \l_@@_process_plus_bool \l_@@_process_plus_saved_bool - } - } -\bool_new:N \l_@@_process_plus_saved_bool -% \end{macrocode} -% -% \begin{macro}{\@@_table_print_S:} -% The main printing function makes a choice depending on whether there is -% any numerical part to print at all. This affects which set of skips to -% insert. Font detection for the \texttt{S} column is included here as -% this is needed to do this work outside of an \cs{hbox}. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S: - { - \bool_if:NTF \l_@@_table_collect_pre_bool - { - \@@_table_column_begin:n { \l_@@_table_text_align_skip } - \l_@@_table_collect_pre_tl - \@@_table_column_end:n { \l_@@_table_text_align_skip } - } - { - \@@_table_column_begin:n { \l_@@_table_number_align_skip } - \bool_if:NTF \l_@@_table_parse_only_bool - { \@@_table_print_S_no_alignment: } - { \@@_table_print_S_alignment: } - \bool_if:NTF \l_@@_table_align_text_pre_bool - { \@@_table_print_S_pre_aligned: } - { \@@_table_print_S_pre_not_aligned: } - \box_use:N \l_@@_table_result_box - \bool_if:NTF \l_@@_table_align_text_post_bool - { \@@_table_print_S_post_aligned: } - { \@@_table_print_S_post_not_aligned: } - \@@_table_column_end:n { \l_@@_table_number_align_skip } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_no_alignment:} -% With no alignment to do, the code can be pretty simple. The collected -% number is simply printed between the two non-numerical parts. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_no_alignment: - { - \l_@@_table_collect_pre_tl - \@@_number_output:V \l_@@_table_collect_tl - \l_@@_table_collect_post_tl - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_alignment:} -% This is a pass-through, so that the appropriate alignment mode is -% retained without needing to retest on each use. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_alignment: - { \@@_table_print_S_parsed: } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_parse:} -% A modified version of the number parser for tables. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_parse: - { - \bool_set_false:N \l_@@_error_bool - \@@_number_in_parse:V \l_@@_table_collect_tl - \bool_if:NF \l_@@_error_bool - { - \bool_if:NTF \l_@@_table_omit_exponent_bool - { - \bool_set_true:N \l_@@_process_fixed_bool - \@@_number_process: - \prop_remove:Nn \l_@@_number_in_prop { exponent } - \prop_remove:Nn \l_@@_number_in_prop { exponent-integer } - } - { \@@_number_process: } - \@@_number_format: - \@@_number_output_color: - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_measure:NN} -% A short routine to measure up whatever has been extracted from the -% storage system. Boxing up is avoided for the empty cases, as this saves -% a little time(the print routine is relatively slow). -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_measure:NN #1#2 - { - \tl_if_empty:NTF #1 - { \dim_zero:N #2 } - { - \group_begin: - \hbox_set:Nn \l_@@_tmp_box - { \@@_print:nV { number } #1 } - \exp_args:NNNo \group_end: - \dim_set:Nn #2 { \dim_use:N \box_wd:N \l_@@_tmp_box } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% { -% \@@_table_print_S_pre_aligned: , -% \@@_table_print_S_pre_not_aligned: , -% \@@_table_print_S_post_aligned: , -% \@@_table_print_S_post_not_aligned: -% } -% The non-numerical material is inserted along with the filler needed -% to maintain alignment. The order in which the two are inserted depends -% on whether those parts are also aligned. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_pre_aligned: - { - \box_use:N \l_@@_table_pre_box - \hbox_to_wd:nn { \l_@@_table_fill_pre_dim } { \tex_hfil:D } - } -\cs_new_protected:Npn \@@_table_print_S_pre_not_aligned: - { - \hbox_to_wd:nn { \l_@@_table_fill_pre_dim } { \tex_hfil:D } - \box_use:N \l_@@_table_pre_box - } -\cs_new_protected:Npn \@@_table_print_S_post_aligned: - { - \hbox_to_wd:nn { \l_@@_table_fill_post_dim } { \tex_hfil:D } - \box_use:N \l_@@_table_post_box - } -\cs_new_protected:Npn \@@_table_print_S_post_not_aligned: - { - \box_use:N \l_@@_table_post_box - \hbox_to_wd:nn { \l_@@_table_fill_post_dim } { \tex_hfil:D } - } -% \end{macrocode} -% \end{macro} -% -% \subsection{Printing the \texttt{S} column with the decimal marker centred} -% -% \begin{macro}{\@@_table_print_S_centered:} -% The main routine for decimal-centred alignment works by boxing up the -% entire output, the integer part and the decimal marker. It then works -% out which part is bigger and calculates the fill correction accordingly. -% Once all of that is done, the various boxes and fill can be inserted. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_centered: - { - \@@_table_print_S_centered_ends: - \bool_if:NT \l_@@_table_math_bool { \c_math_toggle_token } - \@@_table_print_S_parse: - \bool_if:NF \l_@@_error_bool - { - \@@_table_print_S_centered_measure: - \bool_if:NT \l_@@_table_math_bool { \c_math_toggle_token } - \dim_set:Nn \l_@@_table_fill_pre_dim - { - \l_@@_table_result_dim - - \l_@@_table_integer_dim - - \l_@@_table_marker_dim - } - \dim_compare:nNnTF \l_@@_table_integer_dim > - \l_@@_table_fill_pre_dim - { \@@_table_print_S_centered_integer: } - { \@@_table_print_S_centered_decimal: } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_centered_ends:} -% To deal with the material outside of the number, the first step is to -% box up both parts. If the pre-numeral part has no width, the tokens are -% inserted into the input stream to cover cases where they make a change -% to the colour, font or so forth. After that, the narrower of the two -% boxes is made the same size as the wider: this maintains the alignment. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_centered_ends: - { - \hbox_set:Nn \l_@@_table_pre_box - { - { - \l_@@_table_collect_pre_tl - \bool_if:NT \l_@@_table_math_bool - { - \scan_stop: - \c_math_toggle_token - } - } - } - \dim_compare:nNnT - { \box_wd:N \l_@@_table_pre_box } = \c_zero_dim - { - \box_clear:N \l_@@_table_pre_box - \l_@@_table_collect_pre_tl - \bool_set_false:N \l_@@_font_set_bool - } - \hbox_set:Nn \l_@@_table_post_box - { - \bool_if:NT \l_@@_table_math_bool - { - \c_math_toggle_token - \scan_stop: - } - \l_@@_table_collect_post_tl - } - \dim_compare:nNnTF - { \box_wd:N \l_@@_table_pre_box } > - { \box_wd:N \l_@@_table_post_box } - { - \hbox_set_to_wd:Nnn \l_@@_table_post_box - { \box_wd:N \l_@@_table_pre_box } - { - \hbox_unpack:N \l_@@_table_post_box - \tex_hfil:D - } - } - { - \hbox_set_to_wd:Nnn \l_@@_table_pre_box - { \box_wd:N \l_@@_table_post_box } - { - \tex_hfil:D - \hbox_unpack:N \l_@@_table_pre_box - } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_centered_measure:} -% \begin{macro} -% { -% \@@_table_print_S_centered_measure_int_part: , -% \@@_table_print_S_centered_measure_marker: , -% \@@_table_print_S_centered_measure_result: -% } -% Here, there are three parts of the number to measure: the integer part, -% the decimal marker and the entire number. Most of the work consists -% of collecting up parts of the number. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_centered_measure: - { - \@@_table_print_S_centered_measure_int_part: - \@@_table_print_S_centered_measure_marker: - \@@_table_print_S_centered_measure_result: - } -\cs_new_protected:Npn \@@_table_print_S_centered_measure_int_part: - { - \prop_get:NnNF \l_@@_number_out_prop { comparator } \l_@@_tmpa_tl - { \tl_clear:N \l_@@_tmpa_tl } - \prop_get:NnNT \l_@@_number_out_prop { mantissa-sign } - \l_@@_tmpb_tl - { \tl_put_right:No \l_@@_tmpa_tl \l_@@_tmpb_tl } - \prop_get:NnNT \l_@@_number_out_prop { mantissa-integer } - \l_@@_tmpb_tl - { \tl_put_right:No \l_@@_tmpa_tl \l_@@_tmpb_tl } - \@@_table_print_S_measure:NN \l_@@_tmpa_tl - \l_@@_table_integer_dim - } -\cs_new_protected:Npn \@@_table_print_S_centered_measure_marker: - { - \@@_table_print_S_measure:NN \l_@@_output_decimal_tl - \l_@@_table_marker_dim - } -% \end{macrocode} -% As the overall result will be needed later, the boxing up here is done -% using a named box that will be retained. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_centered_measure_result: - { - \prop_get:NnN \l_@@_number_out_prop { result } \l_@@_tmpa_tl - \hbox_set:Nn \l_@@_table_result_box - { \@@_print:nV { number } \l_@@_tmpa_tl } - \dim_set:Nn \l_@@_table_result_dim - { \box_wd:N \l_@@_table_result_box } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro} -% { -% \@@_table_print_S_centered_integer: , -% \@@_table_print_S_centered_decimal: -% } -% The appropriate place to insert the fill is determined by whether the -% integer or decimal part of the number is bigger. Two dimensions are -% therefore set, for fill before the number and after it. One of these -% will always be zero. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_centered_integer: - { - \dim_set:Nn \l_@@_table_fill_post_dim - { \l_@@_table_integer_dim - \l_@@_table_fill_pre_dim } - \dim_zero:N \l_@@_table_fill_pre_dim - } -\cs_new_protected:Npn \@@_table_print_S_centered_decimal: - { - \dim_sub:Nn \l_@@_table_fill_pre_dim - { \l_@@_table_integer_dim } - \dim_zero:N \l_@@_table_fill_post_dim - } -% \end{macrocode} -% \end{macro} -% -% \subsection{Printing the \texttt{S} column with space reserved} -% -% \begin{macro}{\@@_table_print_S_reserved:} -% The procedure for inserting a number with space reserved requires a model -% for each part of the number. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved: - { - \@@_table_print_S_reserved_init: - \@@_table_print_S_reserved_ends: - \bool_if:NT \l_@@_table_auto_round_bool - { \@@_table_print_S_reserved_round_auto: } - \@@_table_print_S_parse: - \bool_if:NF \l_@@_error_bool - { - \bool_if:NT \l_@@_table_math_bool { \c_math_toggle_token } - \@@_table_print_S_reserved_comparator: - \@@_table_print_S_reserved_mantissa: - \@@_table_print_S_reserved_exponent: - \bool_if:NT \l_@@_table_math_bool { \c_math_toggle_token } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_reserved_init:} -% The creation of a model for the cell to follow. Creation of the finalised -% model is done here so that all of the other options will apply without -% needing complex internal tracking. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_init: - { - \dim_zero:N \l_@@_table_fill_mid_dim - \dim_zero:N \l_@@_table_fill_post_dim - \prop_set_eq:NN \l_@@_number_in_prop \l_@@_table_model_prop - \@@_number_process_sign: - \@@_number_process_zero_fill: - \@@_number_process_mantissa: - \prop_if_in:NnF \l_@@_number_in_prop { symbolic } - { \@@_number_process_uncertainty: } - \@@_number_format: - \prop_get:NnNT \l_@@_table_model_prop { mantissa-decimal-raw } - \l_@@_tmpa_tl - { - \prop_put:NnV \l_@@_number_out_prop { mantissa-decimal-raw } - \l_@@_tmpa_tl - } - \prop_set_eq:NN \l_@@_table_model_prop \l_@@_number_out_prop - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_reserved_ends:} -% The end material here is boxed up into the space already reserved. -% That means doing two boxing ups: one for the model, and one for the -% real thing. As in the centred case, if the pre-numeral part has no -% width then the tokens are inserted \enquote{as is}. To avoid any issues -% with people forgetting to reserve space for the pre-numeral part, it is -% boxed up first at natural width so that the measurement is accurate. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_ends: - { - \hbox_set:Nn \l_@@_table_pre_box - { - { - \l_@@_table_collect_pre_tl - \bool_if:NT \l_@@_table_math_bool - { - \scan_stop: - \c_math_toggle_token - } - } - } - \dim_compare:nNnT - { \box_wd:N \l_@@_table_pre_box } = \c_zero_dim - { - \box_clear:N \l_@@_table_pre_box - \l_@@_table_collect_pre_tl - \bool_set_false:N \l_@@_font_set_bool - } - \hbox_set:Nn \l_@@_tmp_box { { \l_@@_table_pre_tl } } - \hbox_set_to_wd:Nnn \l_@@_table_pre_box - { \box_wd:N \l_@@_tmp_box } - { - \tex_hfil:D - \hbox_unpack:N \l_@@_table_pre_box - } - \hbox_set:Nn \l_@@_tmp_box { \l_@@_table_post_tl } - \hbox_set_to_wd:Nnn \l_@@_table_post_box - { \box_wd:N \l_@@_tmp_box } - { - { - \bool_if:NT \l_@@_table_math_bool - { - \c_math_toggle_token - \scan_stop: - } - \l_@@_table_collect_post_tl - } - \tex_hfil:D - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_reserved_round_auto:} -% For auto-rounding, the approach is to find how many decimal digits are -% allowed for, and if there are none to simply set the rounding value to -% zero. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_round_auto: - { - \prop_get:NnNTF \l_@@_table_model_prop { mantissa-decimal-raw } - \l_@@_tmpa_tl - { \int_set:Nn \l_@@_process_precision_int { \l_@@_tmpa_tl } } - { \int_zero:N \l_@@_process_precision_int } - \tl_set:Nn \l_@@_round_tl { places } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_table_print_S_reserved_comparator:} -% The comparator is quite simple to deal with. Assuming that there is a -% comparator in the model, this is measured for the reserved width. The -% real comparator can then simply be typeset in a box of the same size. -% If there is no comparator in the real case, then the space added to -% that for filling: this is needed so that any pre-note can be aligned -% freely. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_comparator: - { - \prop_get:NnNTF \l_@@_table_model_prop { comparator } - \l_@@_tmpa_tl - { - \hbox_set:Nn \l_@@_tmp_box - { \@@_print:nV { number } \l_@@_tmpa_tl } - \prop_get:NnNTF \l_@@_number_out_prop { comparator } - \l_@@_tmpa_tl - { - \hbox_set_to_wd:Nnn \l_@@_table_result_box - { \box_wd:N \l_@@_tmp_box } - { \@@_print:nV { number } \l_@@_tmpa_tl } - } - { - \dim_add:Nn \l_@@_table_fill_pre_dim - { \box_wd:N \l_@@_tmp_box } - \cs_set_eq:NN \@@_table_print_S_reserved_store_fill:n - \@@_table_print_S_reserved_store_fill_pre:n - } - } - { - \cs_set_eq:NN \@@_table_print_S_reserved_store_fill:n - \@@_table_print_S_reserved_store_fill_pre:n - \prop_if_in:NnT \l_@@_number_out_prop { comparator } - { - \msg_error:nnx { siunitx } { table-partial-number } - { a~comparator } } } + { } } % \end{macrocode} -% \end{macro} -% -% \begin{macro} -% { -% \@@_table_print_S_reserved_store_fill_pre:n , -% \@@_table_print_S_reserved_store_fill_mid:n -% } -% To allow for the various alignment options, fill is stored in a -% flexible way. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_store_fill_pre:n - { \dim_add:Nn \l_@@_table_fill_pre_dim } -\cs_new_protected:Npn \@@_table_print_S_reserved_store_fill_mid:n - { \dim_add:Nn \l_@@_table_fill_mid_dim } -% \end{macrocode} -% \end{macro} % -% \begin{macro}{\@@_table_print_S_reserved_mantissa:} -% \begin{macro} -% { -% \@@_table_print_S_reserved_mantissa_parts: , -% \@@_table_print_S_reserved_mantissa_integer: -% } -% The mantissa of a number may contain a sign, an integer part, a -% decimal marker, a decimal part and a non-separated uncertainty. That -% means that there are two ways to deal with the alignment. Each part -% could be done separately, or a correction can be made after setting -% the combined mantissa. Here, the later approach is taken. The first -% step is to deal with the mantissa as a whole: work out show much space -% to reserve, and see if there is anything at all to put in it. The -% complexity only starts if there is a mantissa in the current cell. +% \begin{macro}[EXP]{\@@_angle:n} +% \begin{macro}[EXP]{\@@_angle:w} +% Expandable splitting of the angle: simply enough, also outputs the % \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_mantissa: +\cs_new:Npn \@@_angle:n #1 + { \@@_angle:w #1 ; ; ; \q_stop } +\cs_new:Npn \@@_angle:w #1 ; #2 ; #3 ; #4 \q_stop { - \prop_get:NnNTF \l_@@_table_model_prop { mantissa } - \l_@@_tmpa_tl - { - \hbox_set:Nn \l_@@_tmp_box - { \@@_print:nV { number } \l_@@_tmpa_tl } - \prop_get:NnNTF \l_@@_number_out_prop { mantissa } - \l_@@_tmpa_tl - { - \dim_set:Nn \l_@@_table_mantissa_dim - { \box_wd:N \l_@@_tmp_box } - \hbox_set:Nn \l_@@_table_mantissa_box - { \@@_print:nV { number } \l_@@_tmpa_tl } - \@@_table_print_S_reserved_mantissa_parts: - } - { - \@@_table_print_S_reserved_store_fill:n - { \box_wd:N \l_@@_tmp_box } - } - } - { - \prop_if_in:NnT \l_@@_number_out_prop { mantissa } - { - \msg_error:nnx { siunitx } { table-partial-number } - { a~mantissa } - } - } - } -% \end{macrocode} -% The aim here is to deal with the mantissa with as few measurements as -% possible. The integer part is therefore measured, with the real and model -% versions compared. This allows appropriate fill to be calculated to -% add the mantissa to the result box, after any comparator and with -% the appropriate width. Once that is done, the amount of filler needed -% \emph{after} the integer can be calculated: this is the size of the -% model mantissa, minus the size of the real mantissa and the amount of -% filler needed in the integer part. That is stored in the intermediate -% dimension for the present, although it may get moved. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_mantissa_parts: - { - \@@_table_print_S_reserved_mantissa_integer: - \hbox_set:Nn \l_@@_table_result_box - { - \hbox_unpack:N \l_@@_table_result_box - \hbox_to_wd:nn { \l_@@_table_fill_mid_dim } { \tex_hfil:D } - \hbox_unpack:N \l_@@_table_mantissa_box - } - \dim_set:Nn \l_@@_table_fill_mid_dim - { - \l_@@_table_mantissa_dim - - \box_wd:N \l_@@_table_mantissa_box - - \l_@@_table_integer_dim - } - \@@_table_print_S_reserved_mantissa_uncert: - } -% \end{macrocode} -% For the integer part, there is a need to measure both the sign and -% the integer itself in the model and in the real number. If there is -% no integer part in the real number, then fill is stored to add either -% before or after any comparator. If there is an integer part, the -% size is measured and the any fill needed is stored for re-insertion. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_mantissa_integer: - { - \prop_get:NnNF \l_@@_table_model_prop { mantissa-sign } - \l_@@_tmpa_tl - { \tl_clear:N \l_@@_tmpa_tl } - \prop_get:NnNT \l_@@_table_model_prop { mantissa-integer } - \l_@@_tmpb_tl - { \tl_put_right:No \l_@@_tmpa_tl \l_@@_tmpb_tl } - \@@_table_print_S_measure:NN \l_@@_tmpa_tl - \l_@@_table_integer_dim - \prop_get:NnNF \l_@@_number_out_prop { mantissa-sign } - \l_@@_tmpa_tl - { \tl_clear:N \l_@@_tmpa_tl } - \prop_get:NnNT \l_@@_number_out_prop { mantissa-integer } - \l_@@_tmpb_tl - { \tl_put_right:No \l_@@_tmpa_tl \l_@@_tmpb_tl } - \tl_if_empty:NF \l_@@_tmpa_tl - { - \@@_table_print_S_measure:NN \l_@@_tmpa_tl - \l_@@_tmp_dim - \dim_sub:Nn \l_@@_table_integer_dim { \l_@@_tmp_dim } - } - \@@_table_print_S_reserved_store_fill:n - { \l_@@_table_integer_dim } - } -% \end{macrocode} -% Here, a separated uncertainty is handled. If there is one, then there must -% be a \cs{pm} part to add. Once the space calculation is done, a flexible -% auxiliary does the spacing and pasting up. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_mantissa_uncert: - { - \prop_get:NnNT \l_@@_table_model_prop { mantissa-uncertainty } - \l_@@_tmpa_tl - { - \@@_number_format_join_uncert_pm:N \l_@@_tmpa_tl - \hbox_set:Nn \l_@@_tmp_box - { \@@_print:nV { number } \l_@@_tmpa_tl } - \prop_get:NnNTF \l_@@_number_out_prop { mantissa-uncertainty } - \l_@@_tmpa_tl - { - \dim_set:Nn \l_@@_table_uncert_dim - { \box_wd:N \l_@@_tmp_box } - \@@_number_format_join_uncert_pm:N \l_@@_tmpa_tl - \hbox_set:Nn \l_@@_tmp_box - { \@@_print:nV { number } \l_@@_tmpa_tl } - \bool_if:NTF \l_@@_table_align_uncert_bool - { \@@_table_print_S_reserved_mantissa_uncert_aligned: } - { \@@_table_print_S_reserved_mantissa_uncert_not_aligned: } - } - { - \cs_set_eq:NN \@@_table_print_S_reserved_store_fill:n - \@@_table_print_S_reserved_store_fill_mid:n - \@@_table_print_S_reserved_store_fill:n - { \box_wd:N \l_@@_tmp_box } - } - } - } -% \end{macrocode} -% Two auxiliaries, one to place the uncertainty directly next to the rest -% of the mantissa, one to maintain alignment. In both cases, any fill ends -% up in the middle fill store, but in the alignment case this also removes -% any previous fill. The temporary box here contains the uncertainty part. -% \begin{macrocode} -\cs_new_protected:Npn - \@@_table_print_S_reserved_mantissa_uncert_aligned: - { - \hbox_set:Nn \l_@@_table_result_box - { - \hbox_unpack:N \l_@@_table_result_box - \hbox_to_wd:nn { \l_@@_table_fill_mid_dim } { \tex_hfil:D } - \hbox_unpack:N \l_@@_tmp_box - } - \dim_set:Nn \l_@@_table_fill_mid_dim - { \l_@@_table_uncert_dim - \box_wd:N \l_@@_tmp_box } - } -\cs_new_protected:Npn - \@@_table_print_S_reserved_mantissa_uncert_not_aligned: - { - \hbox_set:Nn \l_@@_table_result_box + \tl_if_blank:nF {#1} + { #1 \degree } + \tl_if_blank:nF {#2} { - \hbox_unpack:N \l_@@_table_result_box - \hbox_unpack:N \l_@@_tmp_box + \tl_if_blank:nF {#1} { \c_space_tl } + #2 \arcminute } - \dim_add:Nn \l_@@_table_fill_mid_dim + \tl_if_blank:nF {#3} { - \l_@@_table_uncert_dim - - \box_wd:N \l_@@_tmp_box + \tl_if_blank:nF {#1#2} { \c_space_tl } + #3 \arcsecond } } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\@@_table_print_S_reserved_exponent:} -% \begin{macro} -% { -% \@@_table_print_S_reserved_exponent_product: , -% \@@_table_print_S_reserved_exponent_product_correction: , -% \@@_table_print_S_reserved_exponent_aligned: , -% \@@_table_print_S_reserved_exponent_not_aligned: -% } -% Printing the exponent needs to deal with the exponent product. This -% is easiest to do by simply re-checking for a mantissa. If there is no -% exponent, then any space which needs to be added must be moved from -% the mid space to the post space at this stage. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_exponent: - { - \prop_get:NnNTF \l_@@_table_model_prop { exponent-result } - \l_@@_tmpa_tl - { - \prop_if_in:NnT \l_@@_table_model_prop { mantissa } - { \@@_table_print_S_reserved_exponent_product: } - \hbox_set:Nn \l_@@_tmp_box - { \@@_print:nV { number } \l_@@_tmpa_tl } - \prop_get:NnNTF \l_@@_number_out_prop { exponent-result } - \l_@@_tmpa_tl - { - \dim_set:Nn \l_@@_table_exponent_dim - { \box_wd:N \l_@@_tmp_box } - \tl_if_empty:NT \l_@@_output_exponent_tl - { - \prop_if_in:NnTF \l_@@_number_out_prop { mantissa } - { \@@_table_print_S_reserved_exponent_product: } - { \@@_table_print_S_reserved_exponent_product_correction: } - } - \hbox_set:Nn \l_@@_tmp_box - { \@@_print:nV { number } \l_@@_tmpa_tl } - \bool_if:NTF \l_@@_table_align_exponent_bool - { \@@_table_print_S_reserved_exponent_aligned: } - { \@@_table_print_S_reserved_exponent_not_aligned: } - } - { - \dim_set:Nn \l_@@_table_fill_post_dim - { \l_@@_table_fill_mid_dim + \box_wd:N \l_@@_tmp_box } - } - } - { - \prop_if_in:NnT \l_@@_number_out_prop { exponent-result } - { - \msg_error:nnx { siunitx } { table-partial-number } - { an~exponent } - } - \dim_set_eq:NN \l_@@_table_fill_post_dim - \l_@@_table_fill_mid_dim - } - } -% \end{macrocode} -% A short sub-function to deal with the appearance of the exponent product -% for both the real number and the model. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_exponent_product: - { - \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_exponent_product_tl - \bool_if:NT \l_@@_tight_bool - { - \tl_set:Nx \l_@@_tmpb_tl - { \exp_not:N \mathord \exp_not:o \l_@@_tmpb_tl } - } - \tl_set:Nx \l_@@_tmpa_tl - { - \exp_not:N \ensuremath { { } \exp_not:o \l_@@_tmpb_tl { } } - \exp_not:o \l_@@_tmpa_tl - } - } -% \end{macrocode} -% If there is no mantissa, then some additional space is needed for the -% location where the product symbol would have been. +% \begin{macro}[EXP] +% {\@@_list_use:nnnnn, \@@_list_use:nnVVV, \@@_list_use_aux:nnnnn} +% \begin{macro}[EXP]{\@@_list_use_auxi:w} +% \begin{macro}[EXP]{\@@_list_use_auxii:nnw, \@@_list_use_auxiii:nnw} +% \begin{macro}[EXP]{\@@_list_count:n} +% \begin{macro}[EXP]{\@@_list_count:w} +% Copies of the ideas in the \pkg{l3clist} module but using |;| as a list +% separator. The functions have to be extended to allow for a unit argument. % \begin{macrocode} -\cs_new_protected:Npn - \@@_table_print_S_reserved_exponent_product_correction: +\cs_new:Npn \@@_list_use:nnnnn #1#2#3#4#5 { - \group_begin: - \tl_clear:N \l_@@_tmpa_tl - \@@_table_print_S_reserved_exponent_product: - \tl_set:Nx \l_@@_tmpa_tl - { { } \exp_not:o \l_@@_tmpa_tl { } } - \@@_table_print_S_measure:NN \l_@@_tmpa_tl \l_@@_tmp_dim - \exp_args:NNNo \group_end: - \dim_set:Nn \l_@@_tmp_dim { \dim_use:N \l_@@_tmp_dim } - \@@_table_print_S_reserved_store_fill:n { \l_@@_tmp_dim } - \dim_sub:Nn \l_@@_table_exponent_dim { \l_@@_tmp_dim } + \tl_if_blank:nTF {#2} + { \@@_list_use_aux:nnnnn {#1} { } } + { \@@_list_use_aux:nnnnn {#1} { ~ #2 } } + {#3} {#4} {#5} } -% \end{macrocode} -% There are two cases for adding the exponent to the result box, one -% with additional space to maintain alignment, and one with no space. -% The space needed after the exponent then can be set to either include -% or exclude the mid fill space. Doing that here avoids one extra assignment -% (to clear the mid fill in the aligned case). -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_reserved_exponent_aligned: +\cs_generate_variant:Nn \@@_list_use:nnnnn { nnVVV } +\cs_new:Npn \@@_list_use_aux:nnnnn #1#2#3#4#5 { - \hbox_set:Nn \l_@@_table_result_box + \int_case:nnF { \@@_list_count:n {#1} } { - \hbox_unpack:N \l_@@_table_result_box - \hbox_to_wd:nn { \l_@@_table_fill_mid_dim } { \tex_hfil:D } - \hbox_unpack:N \l_@@_tmp_box + { 0 } { } + { 1 } { \@@_list_use_auxi:nw {#2} #1 ; ; { } } + { 2 } { \@@_list_use_auxi:nw {#2} #1 ; {#3} } } - \dim_set:Nn \l_@@_table_fill_post_dim { - \l_@@_table_exponent_dim - - \box_wd:N \l_@@_tmp_box + \@@_list_use_auxii:nnw {#2} { } #1 ; + \q_mark ; { \@@_list_use_auxii:nnw {#2} {#4} } + \q_mark ; { \@@_list_use_auxiii:nnw {#2} {#5} } + \q_stop { } } } -\cs_new_protected:Npn - \@@_table_print_S_reserved_exponent_not_aligned: +\cs_new:Npn \@@_list_use_auxi:nw #1#2 ; #3 ; #4 + { #2 #1 #4 #3 \tl_if_blank:nF {#3} {#1} } +\cs_new:Npn \@@_list_use_auxii:nnw + #1#2#3 ; #4 ; #5 ; #6 \q_mark ; #7#8 \q_stop #9 + { #7 {#4} ; {#5} ; #6 \q_mark ; {#7} #8 \q_stop { #9 #2 #3 #1 } } +\cs_new:Npn \@@_list_use_auxiii:nnw #1#2#3 ; #4 \q_stop #5 + { #5 #2 #3 #1 } +\cs_new:Npx \@@_list_count:n #1 { - \hbox_set:Nn \l_@@_table_result_box - { - \hbox_unpack:N \l_@@_table_result_box - \hbox_unpack:N \l_@@_tmp_box - } - \dim_set:Nn \l_@@_table_fill_post_dim + \exp_not:N \int_eval:n { - \l_@@_table_fill_mid_dim - + \l_@@_table_exponent_dim - - \box_wd:N \l_@@_tmp_box + 0 + \exp_not:N \@@_list_count:w \c_space_tl + #1 \exp_not:n { ; \q_recursion_tail ; \q_recursion_stop } } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \subsection{Direct printing in \texttt{S} columns} -% -% When number parsing is turned off the usual approach to printing -% tabular material is not suitable. Instead, the strategy used by -% \pkg{dcolumn} can be applied, which requires the decimal marker to -% be made active in math mode. -% -% \begin{macro}{\@@_table_print_S_direct:} -% \begin{macro}{\@@_table_print_S_direct_text:n} -% Test to see if the very first item -% in the cell is a |{|. If it is, then we use the same approach as for -% parsed columns and set the material as text. Otherwise, switch to math -% mode and hand off to the main routine. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_direct: - { - \peek_catcode_ignore_spaces:NTF \c_group_begin_token - { \@@_table_print_S_direct_text:n } - { \@@_table_print_S_direct_main: } - } -\cs_new_protected:Npn \@@_table_print_S_direct_text:n #1 +\cs_new:Npx \@@_list_count:w #1 ; { - \@@_table_column_begin:n { \l_@@_table_text_align_skip } - #1 - \@@_table_column_end:n { \l_@@_table_text_align_skip } + \exp_not:n { \exp_args:Nf \quark_if_recursion_tail_stop:n } {#1} + \exp_not:N \tl_if_blank:nF {#1} { + 1 } + \exp_not:N \@@_list_count:w \c_space_tl } % \end{macrocode} % \end{macro} % \end{macro} -% -% \begin{macro} -% { -% \@@_table_print_S_direct_centered: , -% @@_table_print_S_direct_centered_begin:, -% \@@_table_print_S_direct_centered_end: -% } -% \begin{macro}{\@@_table_print_S_direct_centered_aux:N} -% When centring the content about a decimal marker, the trick is -% to collect everything into two boxes and then compare the sizes. -% In that sense this is very similar to the normal method, except that -% it will work with non-numerical input. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_direct_centered: - { - \cs_set_eq:NN \@@_table_print: - \@@_table_print_S_direct_centered_end: - \hbox_set:Nn \l_@@_tmp_box - { \ensuremath { \l_@@_output_decimal_tl } } - \hbox_set_to_wd:Nnn \l_@@_table_post_box - { \box_wd:N \l_@@_tmp_box } - { \tex_hfil:D } - \hbox_set:Nw \l_@@_table_pre_box - \c_math_toggle_token - \tl_map_function:NN \l_@@_input_decimal_tl - \@@_table_print_S_direct_centered_aux:N - } -\cs_new_protected:Npn \@@_table_print_S_direct_centered_aux:N #1 - { - \char_set_active_eq:NN #1 \@@_table_print_S_direct_centered_begin: - \char_set_mathcode:nn { `#1 } { "8000 } - } -\cs_new_protected:Npn \@@_table_print_S_direct_centered_begin: - { - \c_math_toggle_token - \hbox_set_end: - \hbox_set:Nw \l_@@_table_post_box - \c_math_toggle_token - \l_@@_output_decimal_tl - } -\cs_new_protected:Npn \@@_table_print_S_direct_centered_end: - { - \c_math_toggle_token - \hbox_set_end: - \dim_compare:nNnTF - { \box_wd:N \l_@@_table_pre_box } > - { \box_wd:N \l_@@_table_post_box } - { - \hbox_set_to_wd:Nnn \l_@@_table_post_box - { \box_wd:N \l_@@_table_pre_box } - { - \hbox_unpack:N \l_@@_table_post_box - \tex_hfil:D - } - } - { - \hbox_set_to_wd:Nnn \l_@@_table_pre_box - { \box_wd:N \l_@@_table_post_box } - { - \tex_hfil:D - \hbox_unpack:N \l_@@_table_pre_box - } - } - \box_use:N \l_@@_table_pre_box - \box_use:N \l_@@_table_post_box - } -% \end{macrocode} % \end{macro} % \end{macro} -% -% \begin{macro} -% { -% \@@_table_print_S_direct_reserved: , -% \@@_table_print_S_direct_reserved_begin:, -% \@@_table_print_S_direct_reserved_end: -% } -% \begin{macro}{\@@_table_print_S_direct_reserved_aux:N} -% The plan here is to box up the entire number using the information -% available about the size of the two parts. Relatively easy, -% but needs a bit of measuring. The first box here does need to use -% \cs{tex_hill:D} as \texttt{fil} glue will not work. -% \begin{macrocode} -\cs_new_protected:Npn \@@_table_print_S_direct_reserved: - { - \cs_set_eq:NN \@@_table_print: - \@@_table_print_S_direct_reserved_end: - \prop_get:NnNF \l_@@_table_model_prop { mantissa-integer } - \l_@@_tmpa_tl - { \tl_clear:N \l_@@_tmpa_tl } - \hbox_set:Nn \l_@@_tmp_box - { - \ensuremath - { - \prop_get:NnNT \l_@@_table_model_prop { mantissa-sign } - \l_@@_tmpb_tl - { \l_@@_tmpb_tl } - \l_@@_tmpa_tl - } - } - \dim_set:Nn \l_@@_table_integer_dim - { \box_wd:N \l_@@_tmp_box } - \prop_get:NnNF \l_@@_table_model_prop { mantissa-decimal } - \l_@@_tmpa_tl - { \tl_clear:N \l_@@_tmpa_tl } - \hbox_set:Nn \l_@@_tmp_box - { - \ensuremath - { - \l_@@_output_decimal_tl - \l_@@_tmpa_tl - } - } - \hbox_set_to_wd:Nnn \l_@@_table_post_box - { \box_wd:N \l_@@_tmp_box } - { \tex_hfil:D } - \tex_setbox:D \l_@@_table_pre_box \tex_hbox:D to \l_@@_table_integer_dim - \c_group_begin_token - \c_math_toggle_token - \tl_map_function:NN \l_@@_input_decimal_tl - \@@_table_print_S_direct_reserved_aux:N - \tex_hfill:D - } -\cs_new_protected:Npn \@@_table_print_S_direct_reserved_aux:N #1 - { - \char_set_active_eq:NN #1 \@@_table_print_S_direct_reserved_begin: - \char_set_mathcode:nn { `#1 } { "8000 } - } -\cs_new_protected:Npn \@@_table_print_S_direct_reserved_begin: - { - \c_math_toggle_token - \c_group_end_token - \tex_setbox:D \l_@@_table_post_box \tex_hbox:D to \box_wd:N \l_@@_tmp_box - \c_group_begin_token - \c_math_toggle_token - \l_@@_output_decimal_tl - } -\cs_new_protected:Npn \@@_table_print_S_direct_reserved_end: - { - \c_math_toggle_token - \tex_hfil:D - \c_group_end_token - \@@_table_align_left:n { \l_@@_table_number_align_skip } - \box_use:N \l_@@_table_pre_box - \box_use:N \l_@@_table_post_box - \@@_table_align_right:n { \l_@@_table_number_align_skip } - } -% \end{macrocode} % \end{macro} -% \end{macro} -% -% \subsection{Table settings} -% -% To allow for the construction above, the table settings are given here. % % \begin{macrocode} -\keys_set:nn { siunitx } - { - table-align-comparator = true, - table-align-exponent = true, - table-align-text-pre = true, - table-align-text-post = true, - table-align-uncertainty = true, - table-omit-exponent = false, - table-parse-only = false, - table-number-alignment = center-decimal-marker, - table-text-alignment = center, - table-figures-decimal = 2, - table-figures-integer = 3 - } -% \end{macrocode} -% -%\subsection{Symbols} -% -% Not all units use letters alone for their symbol. This raises two -% problems. First, the symbols need to work in math and in text mode. -% Second, the user needs to be able to adjust each symbol. -% -%\begin{macro}{\l_@@_redefine_symbols_bool} -% Only one setting applies here! -% \begin{macrocode} -\keys_define:nn { siunitx } - { redefine-symbols .bool_set:N = \l_@@_redefine_symbols_bool } -\keys_set:nn { siunitx } { redefine-symbols = true } -% \end{macrocode} -%\end{macro} -% -% The redefinition of symbols has to do a number of checks to ensure -% that there are no clashes. -% \begin{macrocode} -\AtBeginDocument - { - \bool_if:NT \l_@@_redefine_symbols_bool - { - \@ifpackageloaded { fourier } - { - \@@_option_unchanged:Nnn \l_@@_ohm_text_tl - { \textohm } - { \text { \ensuremath { \l_@@_ohm_math_tl } } } - } - { } - \@ifpackageloaded { mathptmx } - { - \@@_option_unchanged:Nnn \l_@@_ohm_text_tl - { \textohm } - { \text { \ensuremath { \l_@@_ohm_math_tl } } } - } - { } - \str_if_eq:VnT \encodingdefault { OT1 } - { - \@@_option_unchanged:Nnn \l_@@_angstrom_math_tl - { \text { \AA } } - { \text { \capitalring { A } } } - \@@_option_unchanged:Nnn \l_@@_angstrom_text_tl - { \AA } - { \capitalring { A } } - } - \@ifpackageloaded { unicode-math } - { - \exp_args:NNnx - \@@_option_unchanged:Nnn \l_@@_ohm_math_tl - { \text { \ensuremath { \Omega } } } - { \char_generate:nn { "03A9 } { 12 } } - } - { } - \@ifpackageloaded { upgreek } - { - \@@_option_unchanged:Nnn \l_@@_ohm_math_tl - { \text { \ensuremath { \Omega } } } - { \text { \ensuremath { \Upomega } } } - } - { - \cs_if_exist:NT \upOmega - { - \@@_option_unchanged:Nnn \l_@@_ohm_math_tl - { \text { \ensuremath { \Omega } } } - { \text { \ensuremath { \upOmega } } } - } - } - } - } -% \end{macrocode} -% -%\begin{macro}{\l_@@_angstrom_math_tl} -%\begin{macro}{\l_@@_arcminute_math_tl} -%\begin{macro}{\l_@@_arcsecond_math_tl} -%\begin{macro}{\l_@@_celsius_math_tl} -%\begin{macro}{\l_@@_degree_math_tl} -%\begin{macro}{\l_@@_micro_math_tl} -%\begin{macro}{\l_@@_ohm_math_tl} -% The symbol storage macros are created separately for math and text -% mode, although this is all pretty similar. The default definitions use -% what is generally available, except for those for micro, where -% Computer Modern does not have the appropriate symbol at all. For the -% math mode omega option, the "\text{\ensuremath{...}}" construction -% deals with the case where \cs{mathnormal} has the wrong symbol. -% \begin{macrocode} -\keys_define:nn { siunitx } { - math-angstrom .tl_set:N = \l_@@_angstrom_math_tl, - math-arcminute .tl_set:N = \l_@@_arcminute_math_tl, - math-arcsecond .tl_set:N = \l_@@_arcsecond_math_tl, - math-celsius .tl_set:N = \l_@@_celsius_math_tl, - math-degree .tl_set:N = \l_@@_degree_math_tl, - math-micro .tl_set:N = \l_@@_micro_math_tl, - math-ohm .tl_set:N = \l_@@_ohm_math_tl -} -\keys_set:nn { siunitx } { - math-angstrom = \text { \AA }, - math-arcminute = { } ^ { \prime }, - math-arcsecond = { } ^ { \prime \prime }, - math-celsius = \text { \textdegree } \@@_unit_mathrm:n { C } , - math-degree = \text { \textdegree }, - math-micro = \text { \textmu }, - math-ohm = \text { \ensuremath { \Omega } }, -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\begin{macro}{\l_@@_angstrom_text_tl} -%\begin{macro}{\l_@@_arcminute_text_tl} -%\begin{macro}{\l_@@_arcsecond_text_tl} -%\begin{macro}{\l_@@_celsius_text_tl} -%\begin{macro}{\l_@@_degree_text_tl} -%\begin{macro}{\l_@@_micro_text_tl} -%\begin{macro}{\l_@@_ohm_text_tl} -% Text versions are similar. -% \begin{macrocode} -\keys_define:nn { siunitx } { - text-angstrom .tl_set:N = \l_@@_angstrom_text_tl, - text-arcminute .tl_set:N = \l_@@_arcminute_text_tl, - text-arcsecond .tl_set:N = \l_@@_arcsecond_text_tl, - text-celsius .tl_set:N = \l_@@_celsius_text_tl, - text-degree .tl_set:N = \l_@@_degree_text_tl, - text-micro .tl_set:N = \l_@@_micro_text_tl, - text-ohm .tl_set:N = \l_@@_ohm_text_tl, -} -\keys_set:nn { siunitx } { - text-angstrom = \AA, - text-arcminute = \ensuremath { { } ^ { \prime } }, - text-arcsecond = \ensuremath { { } ^ { \prime \prime } }, - text-celsius = \text { \textdegree } C, - text-degree = \text { \textdegree }, - text-micro = \textmu , - text-ohm = \textohm -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -% \begin{macro}{\@@_symbol_new:n} -% For creating the outer symbol macro. -% \begin{macrocode} -\cs_new_protected:Npn \@@_symbol_new:n #1 - { - \cs_set_protected:cpn { SIUnitSymbol #1 } - { - \use:c - { - l__@@_ - \str_foldcase:n {#1} - _ - \mode_if_math:TF { math } { text } - _tl - } - } - } -% \end{macrocode} -% \end{macro} -% -%\begin{macro}{\SIUnitSymbolAngstrom} -%\begin{macro}{\SIUnitSymbolArcminute} -%\begin{macro}{\SIUnitSymbolArcsecond} -%\begin{macro}{\SIUnitSymbolCelsius} -%\begin{macro}{\SIUnitSymbolDegree} -%\begin{macro}{\SIUnitSymbolMicro} -%\begin{macro}{\SIUnitSymbolOhm} -% The wrapper macros are created. -% \begin{macrocode} -\@@_symbol_new:n { Angstrom } -\@@_symbol_new:n { Arcminute } -\@@_symbol_new:n { Arcsecond } -\@@_symbol_new:n { Celsius } -\@@_symbol_new:n { Degree } -\@@_symbol_new:n { Micro } -\@@_symbol_new:n { Ohm } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\subsection{Working with other packages} -% -%\begin{macro}{\l_@@_pgf_link_clist} -%\begin{macro}{\@@_pgf_link:} -% Here, the settings used by \pkg{siunitx} are translated into those for -% \pkg{pgf}. Things could be done more efficiently, but the logic would -% be more difficult to follow. -% \begin{macrocode} -\clist_new:N \l_@@_pgf_link_clist -\cs_new_protected:Npn \@@_pgf_link: { - \clist_clear:N \l_@@_pgf_link_clist - \str_if_eq:VnT \l_@@_round_tl { figure } - { - \clist_put_right:Nn \l_@@_pgf_link_clist { fixed } - \clist_put_right:Nn \l_@@_pgf_link_clist - { fixed~zerofill = true } - } - \clist_put_right:Nx \l_@@_pgf_link_clist - { precision = \int_use:N \l_@@_process_precision_int } - \clist_put_right:Nx \l_@@_pgf_link_clist - { - set~decimal~separator = - { { \exp_not:V \l_@@_output_decimal_tl } } - } - \clist_put_right:Nx \l_@@_pgf_link_clist - { set~thousands~separator = { \exp_not:V \l_@@_group_sep_tl } } - \clist_put_right:Nx \l_@@_pgf_link_clist - { - min~exponent~for~1000~sep = \int_eval:n { \l_@@_group_min_int - 1 } - } - \bool_lazy_or:nnF - { \l_@@_group_decimal_bool } { \l_@@_group_integer_bool } - { - \clist_put_right:Nn \l_@@_pgf_link_clist - { min~exponent~for~1000~sep = 999 } - } - \bool_if:NTF \l_@@_process_integer_zero_bool - { - \clist_put_right:Nn \l_@@_pgf_link_clist - { skip~0. = false } - } - { - \clist_put_right:Nn \l_@@_pgf_link_clist - { skip~0. = true } - } - \str_if_eq:VnTF \l_@@_process_sign_tl { + } - { - \clist_put_right:Nn \l_@@_pgf_link_clist - { showpos = true } - } - { - \clist_put_right:Nn \l_@@_pgf_link_clist - { showpos = false } - } - \use:x - { - \exp_not:N \pgfqkeys - { /pgf/number~format } - { \exp_not:V \l_@@_pgf_link_clist } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Messages} -% -% Lots of messages, all of them together in one block to make life -% easier. -% \begin{macrocode} -\msg_new:nnnn { siunitx } { bad-arc-sign } - { Incorrect~use~of~sign~in~degree-minute-second~angle. } - { Only~the~highest~value~part~of~an~angle~can~have~a~sign. } -\msg_new:nnnn { siunitx } { color-not-loaded } - { Package~"color"~not~loaded. } - { The~command~\token_to_str:N \color \ is~not~available. } -\msg_new:nnnn { siunitx } { duplicate-complex-root-token } - { Duplicate~complex~root~token~'#1'~in~input. } - { Only~one~complex~root~token~can~appear~in~a~single~number. } -\msg_new:nnnn { siunitx } { duplicate-decimal-token } - { Duplicate~decimal~marker~token~'#1'~in~input. } - { Only~one~decimal~marker~token~can~appear~in~a~single~number. } -\msg_new:nnnn { siunitx } { duplicate-exponent-token } - { Duplicate~exponent~marker~token~'#1'~in~input. } - { Only~one~exponent~marker~token~can~appear~in~a~single~number. } -\msg_new:nnnn { siunitx } { duplicate-quotient-token } - { Duplicate~quotient~token. } - { Only~one~quotient~token~can~appear~in~a~single~number. } -\msg_new:nnnn { siunitx } { duplicate-sticky-per } - { Duplicate~\token_to_str:N \per. } - { - When~the~'sticky-per'~option~is~active,~only~one - \token_to_str:N \per may~appear~in~a~unit. - } -\msg_new:nnnn { siunitx } { empty-arc } - { Empty~degree-minute-second~angle. } - { The~angle~given~does~not~contain~any~numbers. } -\msg_new:nnnn { siunitx } { empty-uncertainty } - { Empty~uncertainty~given~in~'#1'. } - { The~number~given~contains~an~empty~uncertainty. } -\msg_new:nnnn { siunitx } { ending-product-token } - { Misplaced~product~token. } - { A~number~cannot~end~with~a~product~token. } -\msg_new:nnnn { siunitx } { ending-quotient-token } - { Misplaced~quotient~token. } - { A~number~cannot~end~with~a~quotient~token. } -\msg_new:nnnn { siunitx } { invalid-arc-format } - { Invalid~degree-minute-second angle~'#1'. } - { - Angles~given~in~degree-minute-second~format~should~contain~two~';' - symbols~to~divide~up~the~parts~of~the~input. - } -\msg_new:nnnn { siunitx } { invalid-number } - { Invalid~numerical~input~'#1'. } - { - The~input~given~as~a~number~does~not~make~logical~sense.~ - This~happens,~for~example,~if~a~number~only~contains~a~sign. - } -\msg_new:nnnn { siunitx } { invalid-token-in-exponent } - { Invalid~exponent~in~numerical~input~'#1'. } - { - The~exponent~part~of~a~number~cannot~contain~an~uncertainty~or~ - complex~part: \\ - the~input~given~appears~to~contain~one~of~these~in~the~exponent. - } -\msg_new:nnnn { siunitx } { invalid-token-in-number } - { Invalid~token~'#1'~in~numerical~input. } - { - Numbers~can~only~contain~tokens~defined~using~the~ - 'input-...'~options:\\ - the~token~'#1'~is~not~set~up~as~a~valid~part~of~a~number. - } -\msg_new:nnnn { siunitx } { invalid-token-in-uncertainty } - { Invalid~uncertainty~in~numerical~input~'#1'. } - { - The~uncertainty~part~of~a~number~may~only~contain~digits~or~ - symbols. - } -\msg_new:nnnn { siunitx } { literal-unit } - { Literal~units~disabled. } - { - You~gave~the~literal~input~'#1'~ - but~literal~unit~output~is~disabled. - } -\msg_new:nnnn { siunitx } { misplaced-sign-token } - { Misplaced~sign~token~'#1'. } - { Sign~tokens~can~only~come~at~the~beginning~of~a~number. } -\msg_new:nnnn { siunitx } { misplaced-complex-root-token } - { Misplaced~complex~token~in~numerical~input~'#1'. } - { - The~root~token~must~come~either~before~or~after~the~real~digits~ - of~the~complex~part. - } -\msg_new:nnnn { siunitx } { misplaced-uncertainty-token } - { Misplaced~uncertainty~token~'#1'. } - { - The~uncertainty~in~a~number~must~be~given~between~a~set~of~ - delimiters~as~defined~by~the\\ - \ \ 'input-open-uncertainty'~and~'input-close-uncertainty'~ - options. - } -\msg_new:nnnn { siunitx } { multi-part-range } - { Numerical~range~with~multiple~parts. } - { - The~input~'#1'~is~a~number~which~has~more~than~one~part: \\ - ranges~can~only~contain~one~number~in~each~part. - } -\msg_new:nnn { siunitx } { non-convertible-exponent } - { Exponent~'#1'~cannot~be~converted~into~a~symbolic~prefix. } -\msg_new:nnn { siunitx } { option-not-available } - { Option~'#1'~not~available~in~strict~mode. } -\msg_new:nnn { siunitx } { option-preamble-only } - { Option~'#1'~only~available~in~the~preamble. } -\msg_new:nnnn { siunitx } { prefix-base-mismatch } - { Prefix~bases~do~not~match. } - { - You~have~asked~for~prefixes~to~be~converted~into~a~power,~ - but~the~bases~do~not~match. - } -\msg_new:nnn { siunitx } { prefix-only } - { Prefix~with~no~unit. } -\msg_new:nnnn { siunitx } { qualifier-before-unit } - { Qualifier~before~unit. } - { Unit~qualifiers~have~to~follow~after~units,~not~before~them. } -\msg_new:nnnn { siunitx } { restricted-number } - { Token~'#1'~forbidden~in~restricted~numerical~input. } - { - The~current~input~must~be~a~real~number~and~cannot~contain: \\ - \ -~an~exponent; \\ - \ -~an~uncertainty; \\ - \ -~a~complex~part. - } -\msg_new:nnnn { siunitx } { starting-product-token } - { Misplaced~product~token. } - { A~number~cannot~begin~with~a~product~token. } -\msg_new:nnnn { siunitx } { starting-quotient-token } - { Misplaced~quotient~token. } - { A~number~cannot~begin~with~a~quotient~token. } -\msg_new:nnnn { siunitx } { table-partial-number } - { No~space~reserved~for~#1~\msg_line_context:. } - { - The~number~in~the~current~table~cell~contains~#1~part, - but~you~did~not~reserve~any~space~to~print~it: \\ - it~will~be~missing~in~the~output. - } -\msg_new:nnnn { siunitx } { unknown-option } - { Unknown~option~'#1'. } - { - The~option~file~'#1'~is~not~known~by~siunitx: - perhaps~it~is~spelled~incorrectly. - } -\msg_new:nnnn { siunitx } { version-1-option } - { Version~1~option~'#1'~detected. } - { - Use: \\ - \ \ \token_to_str:N \usepackage [ version-1-compatibility ] - \iow_char:N \{ siunitx \token_to_str:N \iow_char:N \} \\ - in~the~preamble~to~load~the~appropriate~code. - } -% \end{macrocode} -% -%\subsection{Design-level macros} -% -%\begin{macro}{\DeclareBinaryPrefix} -%\begin{macro}{\DeclareSIPostPower} -%\begin{macro}{\DeclareSIPrefix} -%\begin{macro}{\DeclareSIPrePower} -%\begin{macro}{\DeclareSIQualifier} -%\begin{macro}{\DeclareSIUnit} -%\begin{macro}{\DeclareSIUnitWithOptions} -% The macros for creating units and so on are in design name space. -% Basically, a set of shuffles for arguments. -% \begin{macrocode} -\NewDocumentCommand \DeclareBinaryPrefix { m m m } { - \@@_declare_prefix:Nnnn #1 {#2} { 2 } {#3} -} -\NewDocumentCommand \DeclareSIPostPower { m m } { - \@@_declare_power_after:Nn #1 {#2} -} -\NewDocumentCommand \DeclareSIPrefix { m m m } { - \@@_declare_prefix:Nnnn #1 {#2} { 10 } {#3} -} -\NewDocumentCommand \DeclareSIPrePower { m m } { - \@@_declare_power_before:Nn #1 {#2} -} -\NewDocumentCommand \DeclareSIQualifier { m m } { - \@@_declare_qualifier:Nn #1 {#2} -} -\NewDocumentCommand \DeclareSIUnit { O { } m m } { - \@@_declare_unit:Nnn #2 {#3} {#1} -} -\NewDocumentCommand \DeclareSIUnitWithOptions { m m m } { - \@@_declare_unit:Nnn #1 {#2} {#3} -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -% None of this should be done after the preamble. -% \begin{macrocode} -\@onlypreamble \DeclareBinaryPrefix -\@onlypreamble \DeclareSIPostPower -\@onlypreamble \DeclareSIPrefix -\@onlypreamble \DeclareSIPrePower -\@onlypreamble \DeclareSIQualifier -\@onlypreamble \DeclareSIUnit -\@onlypreamble \DeclareSIUnitWithOptions -% \end{macrocode} -% -%\begin{macro}{\SendSettingsToPgf} -% A settings transfer function. -% \begin{macrocode} -\cs_new_protected:Npn \SendSettingsToPgf { \@@_pgf_link: } -% \end{macrocode} -%\end{macro} -% -%\subsection{Document macros} -% -% The user document macros are all collected together here for ease. -% -%\begin{macro}{\ang} -% The \cs{ang} function does very little beyond setting the local -% keys and passing on the input. -% \begin{macrocode} -\NewDocumentCommand \ang { o > { \SplitArgument { 2 } { ; } } m } { - \group_begin: - \IfNoValueF {#1} - { \keys_set:nn { siunitx } {#1} } - \@@_angle_output:nnn #2 - \group_end: -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\num} -% The \cs{num} macro is quite simple: read the number, check it is -% correct then print it. -% \begin{macrocode} -\NewDocumentCommand \num { o m } { - \leavevmode - \group_begin: - \bool_set_false:N \l_@@_font_set_bool - \IfNoValueF {#1} - { \keys_set:nn { siunitx } {#1} } - \@@_number_output:n {#2} - \group_end: -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\numlist} -% Lists of numbers are trivially easy to work with. -% \begin{macrocode} -\NewDocumentCommand \numlist { o > { \SplitList { ; } } m } { - \leavevmode - \group_begin: - \bool_set_false:N \l_@@_font_set_bool - \IfNoValueF {#1} - { \keys_set:nn { siunitx } {#1} } - \@@_list_numbers:n {#2} - \group_end: -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\numrange} -% A very simple approach is taken here: this is not intended for -% anything complicated. -% \begin{macrocode} -\NewDocumentCommand \numrange { o m m } { - \leavevmode - \group_begin: - \bool_set_false:N \l_@@_font_set_bool - \IfNoValueF {#1} - { \keys_set:nn { siunitx } {#1} } - \@@_range_numbers:nn {#2} {#3} - \group_end: -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \SIlist , -% \SIrange -%} -% Lists and range of values are handled in a very similar way. -% Everything is kept relatively simple, and so there is not too much -% complexity. In theory the two could be combined together, but -% the differences between the two make this less desirable. -% \begin{macrocode} -\NewDocumentCommand \SIlist { o > { \SplitList { ; } } m m } { - \leavevmode - \group_begin: - \bool_set_false:N \l_@@_font_set_bool - \IfNoValueTF {#1} - { \@@_list_units:nnn {#2} {#3} { } } - { - \keys_set:nn { siunitx } {#1} - \@@_list_units:nnn {#2} {#3} {#1} - } - \group_end: -} -\NewDocumentCommand \SIrange { o m m m } { - \leavevmode - \group_begin: - \bool_set_false:N \l_@@_font_set_bool - \IfNoValueTF {#1} - { \@@_range_unit:nnnn {#4} { } {#2} {#3} } - { - \keys_set:nn { siunitx } {#1} - \@@_range_unit:nnnn {#4} {#1} {#2} {#3} - } - \group_end: -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\SI} -% The main \cs{SI} function follows the same pattern as the previous -% ones. -% \begin{macrocode} -\NewDocumentCommand \SI { o m o m } { - \leavevmode - \group_begin: - \bool_set_false:N \l_@@_font_set_bool - \IfNoValueTF {#1} - { \@@_combined:nnnn { } {#2} {#3} {#4} } - { - \keys_set:nn { siunitx } {#1} - \@@_combined:nnnn {#1} {#2} {#3} {#4} - } - \group_end: -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\sisetup} -% The set up macro simply moves to the correct path and executes -% whatever has been passed. -% \begin{macrocode} -\NewDocumentCommand \sisetup { m } { - \keys_set:nn { siunitx } {#1} -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\tablenum} -% A variation on the \cs{num} macro that will retain alignment within -% \cs{multicolumn} and \cs{multirow} situations. The slightly odd code -% for the non-parsed case is needed to reinsert the appropriate tokens -% after \enquote{collection}. -% \begin{macrocode} -\NewDocumentCommand \tablenum { o m } { - \leavevmode - \group_begin: - \bool_set_false:N \l_@@_font_set_bool - \IfNoValueF {#1} - { \keys_set:nn { siunitx } {#1} } - \bool_if:NTF \l_@@_number_parse_bool - { - \tl_set:Nn \l_@@_table_collect_tl {#2} - \bool_set_false:N \l_@@_table_collect_pre_bool - \@@_table_print_S: - } - { \@@_table_print_S_direct: #2 \@@_table_print: } - \group_end: -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\si} -% The \cs{si} macro needs to pass options through to the internal -% function as well as setting them here. This is used so that options -% set for a unit can be overridden on a one-off basis. -% \begin{macrocode} -\NewDocumentCommand \si { o m } { - \leavevmode - \group_begin: - \bool_set_false:N \l_@@_font_set_bool - \IfNoValueTF {#1} - { \@@_unit_output:nn {#2} { } } - { - \keys_set:nn { siunitx } {#1} - \@@_unit_output:nn {#2} {#1} - } - \group_end: -} -% \end{macrocode} -%\end{macro} -% -%\subsection{Precautions for section headings} -% -% There are two issues to be handled for section headings, \emph{etc}. -% First, within the \cs{addcontentline} macro the various unit functions -% need to be \cs{protected}. Secondly, there is a need to worry about -% \pkg{hyperref}, and ensure that everything works cleanly and with -% no unnecessary warnings. -% -% \begin{macro}{\@@_contents_bookmarks:} -% The idea here is two-fold. First, all of the unit macros are set -% up to simply print their literal interpretation: this is hopefully -% good enough for most bookmark situations. Secondly, the document -% commands are made expandable. This allows a bit of re-arrangement -% of the input, removes any set up options (which are being ignored) -% and stops \pkg{hyperref} issuing a warning. -% \begin{macrocode} -\cs_new_protected:Npn \@@_contents_bookmarks: - { - \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq - { \@@_unit_print_literal_aux:N ##1 } - \cs_if_exist:NT \FB@fg - { \cs_set_eq:NN \fg \FB@fg } - \msg_redirect_name:nnn { xparse } { redefine-command } { none } - \cs_set_eq:NN \num \numInBookmark - \cs_set_eq:NN \numrange \numrangeInBookmark - \cs_set_eq:NN \si \siInBookmark - \cs_set_eq:NN \SI \SIInBookmark - \cs_set_eq:NN \SIrange \SIrangeInBookmark - \cs_set_eq:NN \si \siInBookmark - \cs_set_eq:NN \highlight \use_ii:nn - \cs_set_eq:NN \@@_textsuperscript:n \use:n - \cs_set:Npn \SIUnitSymbolAngstrom { \AA } - \cs_set:Npn \SIUnitSymbolArcminute { ' } - \cs_set:Npn \SIUnitSymbolArcsecond { '' } - \cs_set:Npn \SIUnitSymbolCelsius { \textcelsius } - \cs_set:Npn \SIUnitSymbolDegree { \textdegree } - \cs_set:Npn \SIUnitSymbolMicro { \textmu } - \cs_set:Npn \SIUnitSymbolOhm { \textohm } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% { -% \numInBookmark , -% \numrangeInBookmark , -% \SIlistInBookmark , -% \SIrangeInBookmark , -% \SIInBookmark , -% \siInBookmark -% } -% To keep things fast, expandable versions of the document commands -% are created only once. These are then used if necessary to remove -% and re-order arguments in an expandable fashion. -% \begin{macrocode} -\DeclareExpandableDocumentCommand \numInBookmark { o m } {#2} -\DeclareExpandableDocumentCommand \numrangeInBookmark { o m m } - { #2 \l_@@_range_phrase_tl #3 } -\DeclareExpandableDocumentCommand \SIInBookmark { o m o m } - { \IfNoValueF {#3} {#3} #2 ~ #4 } -\DeclareExpandableDocumentCommand \SIlistInBookmark - { o m m } { \@@_bookmark_SIlist_map:nn {#1} {#2} } -\DeclareExpandableDocumentCommand \SIrangeInBookmark - { o m m m } { #2 ~ #4 \l_@@_range_phrase_tl #3 ~ #4 } -\DeclareExpandableDocumentCommand \siInBookmark { o m } {#2} -% \end{macrocode} -% \end{macro} -% -%\begin{macro}{\@@_bookmark_SIlist_map:nn} -%\begin{macro}{\@@_bookmark_SIlist_map_aux:nw} -% An expandable mapping to replace the list separator in the -% input by appropriate output version. -% \begin{macrocode} -\cs_new:Npn \@@_bookmark_SIlist_map:nn #1#2 { - \@@_bookmark_SIlist_map_aux:nw {#2} #1 ; \q_recursion_tail ; - \q_recursion_tail ; \q_recursion_stop -} -\cs_new:Npn \@@_bookmark_SIlist_map_aux:nw #1#2 ; #3 ; #4 { - #2 ~ #1 - \quark_if_recursion_tail_stop:n {#3} - \quark_if_recursion_tail_stop_do:nn {#4} - { - \l_@@_list_separator_final_tl - #3 ~ #1 - } - \l_@@_list_separator_tl - \@@_bookmark_SIlist_map_aux:nw {#1} #3 ; #4 -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -% A short check to get things working. -% \begin{macrocode} -\AtBeginDocument { - \@ifpackageloaded { hyperref } - { \pdfstringdefDisableCommands { \@@_contents_bookmarks: } } - { } -} -% \end{macrocode} -% -%\subsection{Physical units} -% -%\begin{macro}{\kilogram} -%\begin{macro}{\metre} -%\begin{macro}{\meter} -%\begin{macro}{\mole} -%\begin{macro}{\kelvin} -%\begin{macro}{\candela} -%\begin{macro}{\second} -%\begin{macro}{\ampere} -% The basic SI units are always defined, including both variants for -% metre. -% \begin{macrocode} -\DeclareSIUnit \kilogram { \kilo \gram } -\DeclareSIUnit \metre { m } -\DeclareSIUnit \meter { \metre } -\DeclareSIUnit \mole { mol } -\DeclareSIUnit \second { s } -\DeclareSIUnit \ampere { A } -\DeclareSIUnit \kelvin { K } -\DeclareSIUnit \candela { cd } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\gram} -% The gram is an odd unit as it is needed for the base unit kilogram. -% \begin{macrocode} -\DeclareSIUnit \gram { g } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\yocto} -%\begin{macro}{\zepto} -%\begin{macro}{\atto} -%\begin{macro}{\femto} -%\begin{macro}{\pico} -%\begin{macro}{\nano} -%\begin{macro}{\micro} -%\begin{macro}{\milli} -%\begin{macro}{\centi} -%\begin{macro}{\deci} -% The various SI multiple prefixes are defined here: first the small -% ones. -% \begin{macrocode} -\DeclareSIPrefix \yocto { y } { -24 } -\DeclareSIPrefix \zepto { z } { -21 } -\DeclareSIPrefix \atto { a } { -18 } -\DeclareSIPrefix \femto { f } { -15 } -\DeclareSIPrefix \pico { p } { -12 } -\DeclareSIPrefix \nano { n } { -9 } -\DeclareSIPrefix \micro { \SIUnitSymbolMicro } { -6 } -\DeclareSIPrefix \milli { m } { -3 } -\DeclareSIPrefix \centi { c } { -2 } -\DeclareSIPrefix \deci { d } { -1 } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\begin{macro}{\deca} -%\begin{macro}{\deka} -%\begin{macro}{\hecto} -%\begin{macro}{\kilo} -%\begin{macro}{\mega} -%\begin{macro}{\giga} -%\begin{macro}{\tera} -%\begin{macro}{\peta} -%\begin{macro}{\exa} -%\begin{macro}{\zetta} -%\begin{macro}{\yotta} -% Now the large ones. -% \begin{macrocode} -\DeclareSIPrefix \deca { da } { 1 } -\DeclareSIPrefix \deka { da } { 1 } -\DeclareSIPrefix \hecto { h } { 2 } -\DeclareSIPrefix \kilo { k } { 3 } -\DeclareSIPrefix \mega { M } { 6 } -\DeclareSIPrefix \giga { G } { 9 } -\DeclareSIPrefix \tera { T } { 12 } -\DeclareSIPrefix \peta { P } { 15 } -\DeclareSIPrefix \exa { E } { 18 } -\DeclareSIPrefix \zetta { Z } { 21 } -\DeclareSIPrefix \yotta { Y } { 24 } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\becquerel} -%\begin{macro}{\celsius} -%\begin{macro}{\degreeCelsius} -%\begin{macro}{\coulomb} -%\begin{macro}{\farad} -%\begin{macro}{\gray} -%\begin{macro}{\hertz} -%\begin{macro}{\henry} -%\begin{macro}{\joule} -%\begin{macro}{\katal} -%\begin{macro}{\lumen} -%\begin{macro}{\lux} -% A number of derived units with defined names and symbols. -% \begin{macrocode} -\DeclareSIUnit \becquerel { Bq } -\DeclareSIUnit \celsius { \SIUnitSymbolCelsius } -\DeclareSIUnit \degreeCelsius { \SIUnitSymbolCelsius } -\DeclareSIUnit \coulomb { C } -\DeclareSIUnit \farad { F } -\DeclareSIUnit \gray { Gy } -\DeclareSIUnit \hertz { Hz } -\DeclareSIUnit \henry { H } -\DeclareSIUnit \joule { J } -\DeclareSIUnit \katal { kat } -\DeclareSIUnit \lumen { lm } -\DeclareSIUnit \lux { lx } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\begin{macro}{\newton} -%\begin{macro}{\ohm} -%\begin{macro}{\pascal} -%\begin{macro}{\radian} -%\begin{macro}{\siemens} -%\begin{macro}{\sievert} -%\begin{macro}{\steradian} -%\begin{macro}{\tesla} -%\begin{macro}{\volt} -%\begin{macro}{\watt} -%\begin{macro}{\weber} -% More units. -% \begin{macrocode} -\DeclareSIUnit \newton { N } -\DeclareSIUnit \ohm { \SIUnitSymbolOhm } -\DeclareSIUnit \pascal { Pa } -\DeclareSIUnit \radian { rad } -\DeclareSIUnit \siemens { S } -\DeclareSIUnit \sievert { Sv } -\DeclareSIUnit \steradian { sr } -\DeclareSIUnit \tesla { T } -\DeclareSIUnit \volt { V } -\DeclareSIUnit \watt { W } -\DeclareSIUnit \weber { Wb } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\arcminute} -%\begin{macro}{\arcsecond} -%\begin{macro}{\day} -%\begin{macro}{\degree} -%\begin{macro}{\hectare} -%\begin{macro}{\hour} -%\begin{macro}{\litre} -%\begin{macro}{\liter} -%\begin{macro}{\minute} -%\begin{macro}{\percent} -%\begin{macro}{\tonne} -% Non-SI, but accepted for general use. -% \begin{macrocode} -\DeclareSIUnit [ number-unit-product = ] \arcmin { \arcminute } -\DeclareSIUnit [ number-unit-product = ] - \arcminute { \SIUnitSymbolArcminute } -\DeclareSIUnit [ number-unit-product = ] - \arcsecond { \SIUnitSymbolArcsecond } -\DeclareSIUnit \day { d } -\DeclareSIUnit[ number-unit-product = ] \degree { \SIUnitSymbolDegree } -\DeclareSIUnit \hectare { ha } -\DeclareSIUnit \hour { h } -\DeclareSIUnit \litre { l } -\DeclareSIUnit \liter { L } -\DeclareSIUnit \minute { min } -\DeclareSIUnit \percent { \char 37 } -\DeclareSIUnit \tonne { t } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\astronomicalunit} -%\begin{macro}{\atomicmassunit} -%\begin{macro}{\electronvolt} -%\begin{macro}{\dalton} -% A few units based on physical measurements exist. -% \begin{macrocode} -\DeclareSIUnit \astronomicalunit { au } -\DeclareSIUnit \atomicmassunit { u } -\DeclareSIUnit \electronvolt { eV } -\DeclareSIUnit \dalton { Da } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\begin{macro}{\clight} -%\begin{macro}{\electronmass} -%\begin{macro}{\planckbar} -% A set of \enquote{natural units}. -% \begin{macrocode} -\group_begin: -\cs_set_eq:NN \endgroup \group_end: -\char_set_catcode_math_subscript:N \_ -\use:n - { - \endgroup - \DeclareSIUnit \clight { \text { \ensuremath { c _ { 0 } } } } - \DeclareSIUnit \electronmass - { \text { \ensuremath { m _ { \textup { e } } } } } - } -\DeclareSIUnit \planckbar { \text { \ensuremath { \hbar } } } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\begin{macro}{\elementarycharge} -%\begin{macro}{\bohr} -%\begin{macro}{\hartree} -% A set of \enquote{atomic units}. -% \begin{macrocode} -\DeclareSIUnit \elementarycharge { \text { \ensuremath { e } } } -\group_begin: -\cs_set_eq:NN \endgroup \group_end: -\char_set_catcode_math_subscript:N \_ -\use:n - { - \endgroup - \DeclareSIUnit \bohr { \text { \ensuremath { a _ { 0 } } } } - \DeclareSIUnit \hartree - { \text { \ensuremath { E _ { \textup { h } } } } } - } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\angstrom} -%\begin{macro}{\bar} -%\begin{macro}{\barn} -%\begin{macro}{\bel} -%\begin{macro}{\decibel} -%\begin{macro}{\knot} -%\begin{macro}{\mmHg} -%\begin{macro}{\nauticalmile} -%\begin{macro}{\neper} -% There are then some day-to-day units which are accepted for use -% with SI, but are not part of the official specification. -% \begin{macrocode} -\DeclareSIUnit \angstrom { \SIUnitSymbolAngstrom } -\DeclareSIUnit \bar { bar } -\DeclareSIUnit \barn { b } -\DeclareSIUnit \bel { B } -\DeclareSIUnit \decibel { \deci \bel } -\DeclareSIUnit \knot { kn } -\DeclareSIUnit \mmHg { mmHg } -\DeclareSIUnit \nauticalmile { M } -\DeclareSIUnit \neper { Np } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\square} -%\begin{macro}{\squared} -%\begin{macro}{\cubic} -%\begin{macro}{\cubed} -% The basic powers are also defined. -% \begin{macrocode} -\DeclareSIPrePower \square { 2 } -\DeclareSIPostPower \squared { 2 } -\DeclareSIPrePower \cubic { 3 } -\DeclareSIPostPower \cubed { 3 } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\subsection{Strict application of the rules} -% -%\begin{macro}{\@@_strict_option:n} -%\begin{macro}{\@@_strict_option_aux:n} -% When sticking to the rules closely, a few options are not available. -% \begin{macrocode} -\keys_define:nn { siunitx } { - strict .code:n = - { - \keys_set:nn { siunitx } - { - bracket-numbers = true, - detect-family = false, - detect-mode = false, - detect-shape = false, - detect-weight = false, - multi-part-units = brackets, - parse-numbers = true, - parse-units = true, - product-units = repeat - } - \@@_strict_option:n - { - bracket-numbers , - detect-family , - detect-italic , - detect-mode , - detect-shape , - detect-weight , - multi-part-units , - parse-numbers , - parse-units , - product-units - } - \keys_define:nn { siunitx } - { - per-mode / repeated-symbol .code:n = - { - \msg_warning:nnx { siunitx } { option-not-available } - { per-mode~=~repeated-symbol } - } - } - } -} -\@@_option_deactivate:n { strict } -\cs_new_protected:Npn \@@_strict_option:n #1 { - \clist_map_function:nN {#1} \@@_strict_option_aux:n -} -\cs_new_protected:Npn \@@_strict_option_aux:n #1 { - \keys_define:nn { siunitx } - { #1 .code:n = - { \msg_warning:nnx { siunitx } { option-not-available } {#1} } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -% -%\subsection{Locales} -% -% The basics for defining locales are easy: these are just meta keys. -% The US locale is simply an alias for the UK one, which is the default. -% \begin{macrocode} -\keys_define:nn { siunitx } { - locale .choice:, - locale / - DE .meta:n = - { - exponent-product = \ensuremath { \cdot } , - inter-unit-product = \, , - output-decimal-marker = { , } - }, - locale / - FR .meta:n = - { - exponent-product = \ensuremath { \times } , - inter-unit-product = \, , - output-decimal-marker = { , } - }, - locale / - UK .meta:n = - { - exponent-product = \ensuremath { \times } , - inter-unit-product = \, , - output-decimal-marker = . - }, - locale / - US .meta:n = { locale = UK }, - locale / - USA .meta:n = { locale = UK }, - locale / - ZA .meta:n = - { - exponent-product = \ensuremath { \times } , - inter-unit-product = \ensuremath { \cdot } , - output-decimal-marker = { , } - }, -} -% \end{macrocode} -% -%\subsection{Localisation} -% -% Localisation makes use of the \pkg{translator} package. This only -% happens if it is available, and is transparent to the user. -% \begin{macrocode} -\file_if_exist:nT { translator.sty } - { - \RequirePackage { translator } - \usedictionary { translator-basic-dictionary } - \providetranslation [ to = English ] - { to~(numerical~range) } { to } - \providetranslation [ to = French ] - { to~(numerical~range) } { \`a } - \providetranslation [ to = German ] - { to~(numerical~range) } { bis } - \providetranslation [ to = Spanish ] - { to~(numerical~range) } { a } - \sisetup - { - list-final-separator = { ~ \translate { and } ~ }, - list-pair-separator = { ~ \translate { and } ~ }, - range-phrase = { ~ \translate { to~(numerical~range) } ~ } - } - } -% \end{macrocode} -% -% \subsection{Loading additional configurations} -% -% \begin{variable}{\c_@@_configuration_ext_tl} -% Logical mark-up for the file extension. -% \begin{macrocode} -\tl_const:Nn \c_@@_configuration_ext_tl { cfg } -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\@@_load_abbreviations:} -% \begin{macro}{\@@_load_binary:} -% Loading abbreviations is on by default, which therefore requires a bit -% of juggling. The idea here is that the abbreviations will be loaded unless -% specifically turned off. This can occur anywhere in the preamble. -% \begin{macrocode} -\keys_define:nn { siunitx } - { - abbreviations .choice:, - abbreviations / - true .code:n = { \@@_load_abbreviations: }, - abbreviations / - false .code:n = - { \cs_set_eq:NN \@@_load_abbreviations: \prg_do_nothing: } , - abbreviations .default:n = true , - binary-units .choice:, - binary-units / - true .code:n = { \AtBeginDocument { \@@_load_binary: } }, - binary-units / - false .code:n = - { \cs_set_eq:NN \@@_load_binary: \prg_do_nothing: } , - binary-units .default:n = true - } -\cs_new_protected:Npn \@@_load_abbreviations: - { - \@onefilewithoptions { siunitx-abbreviations } [ ] [ ] - \c_@@_configuration_ext_tl - } -\cs_new_protected:Npn \@@_load_binary: - { - \@onefilewithoptions { siunitx-binary } [ ] [ ] - \c_@@_configuration_ext_tl - } -\AtBeginDocument { \@@_load_abbreviations: } -\@@_option_deactivate:n { abbreviations , binary } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% The version 1 options are not loaded as standard. -% \begin{macrocode} -\keys_define:nn { siunitx } - { - version-1-compatibility .choice: , - version-1-compatibility / - true .code:n = - { - \@onefilewithoptions { siunitx-version-1 } [ ] [ ] - \c_@@_configuration_ext_tl - }, - version-1-compatibility / - false .code:n = { } , - version-1-compatibility .default:n = true - } -\@@_option_deactivate:n { version-1-compatibility } -% \end{macrocode} -% -% Dealing with the old \opt{load-configurations} option is pretty easy, as -% only one choice is important. -% \begin{macrocode} -\keys_define:nn { siunitx } { - load-configurations .code:n = - { - \clist_if_in:nnT {#1} { version-1 } - { - \@onefilewithoptions { siunitx-version-1 } [ ] [ ] - \c_@@_configuration_ext_tl - } - } -} -\@@_option_deactivate:n { load-configurations } -% \end{macrocode} -% -% Load any local configuration file. -% \begin{macrocode} -\file_if_exist:nT { siunitx . \c_@@_configuration_ext_tl } - { - \@onefilewithoptions { siunitx } [ ] [ ] - \c_@@_configuration_ext_tl - } -% \end{macrocode} -% -% Finally apply the settings given at load time. -% \begin{macrocode} -\ProcessKeysOptions { siunitx } -% \end{macrocode} -% -% Creating document commands has to happen here so it is after any load-time -% changes to the units available. -% \begin{macrocode} -\AtBeginDocument { - \bool_if:NTF \l_@@_create_free_bool - { \@@_unit_create_functions: } - { \@@_unit_create_empty_functions: } -} +%</interfaces> % \end{macrocode} % % \begin{macrocode} %</package> % \end{macrocode} % -%\subsection{Support for version one} -% -% \begin{macrocode} -%<*version-1> -% \end{macrocode} -% -% \begin{macrocode} -\ProvidesExplFile {siunitx-version-1.cfg} {2021-04-17} {2.8e} - {siunitx: Version 1 settings} -% \end{macrocode} -% -% The re-arrangements made to the code in version two, and in particular -% the new option names, mean that support for version one needs to be -% included explicitly. -% -% \begin{macrocode} -\keys_define:nn { siunitx } { - addsign .choice: , - addsign / - all .meta:n = { explicit-sign = + }, - addsign / - exp .meta:n = { explicit-sign = + }, - addsign / - false .meta:n = { explicit-sign = }, - addsign / - mant .meta:n = { explicit-sign = + }, - addsign / - none .meta:n = { explicit-sign = }, - addsign / - true .meta:n = { explicit-sign = + }, - addsign .default:n = { true }, - allowlitunits .meta:n = { free-standing-units = #1 }, - allowlitunits .default:n = { true }, - allowoptarg .meta:n = { unit-optional-argument = #1 }, - allowoptargs .default:n = { true }, - allowzeroexp .meta:n = { retain-zero-exponent = #1 }, - allowzeroexp .default:n = { true }, - alsoload .code:n = , - angformat .code:n = , - anglesep .choice: , - anglesep / - cdot .meta:n = - { arc-separator = \ensuremath { { } \cdot { } } }, - anglesep / - comma .meta:n = { arc-separator = \ensuremath { { {,} } } }, - anglesep / - fullstop .meta:n = { arc-separator = \ensuremath { { { . } } } }, - anglesep / - med .meta:n = { arc-separator = \ensuremath { \: } }, - anglesep / - medium .meta:n = { arc-separator = \ensuremath { \: } }, - anglesep / - none .meta:n = { arc-separator = }, - anglesep / - period .meta:n = { arc-separator = \ensuremath { { { . } } } }, - anglesep / - space .meta:n = { arc-separator = \text { ~ } }, - anglesep / - stop .meta:n = { arc-separator = \ensuremath { { { . } } } }, - anglesep / - thick .meta:n = { arc-separator = \ensuremath { \; } }, - anglesep / - thin .meta:n = { arc-separator = \ensuremath { \, } }, - anglesep / - tightcdot .meta:n = - { arc-separator = \ensuremath { \bgroup \cdot \egroup } }, - anglesep / - tighttimes .meta:n = - { arc-separator = \ensuremath { \bgroup \times \egroup } }, - anglesep / - times .meta:n = { arc-separator = \ensuremath { \times } }, - anglesep / - unknown .meta:n = { arc-separator = \ensuremath {#1} }, - astroang .meta:n = - { angle-symbol-over-decimal = #1 }, - astroang .default:n = { true }, - closeerr .meta:n = { close-bracket = \ensuremath {#1} }, - closefrac .meta:n = { close-bracket = \ensuremath {#1} }, - closerange .meta:n = { close-bracket = \ensuremath {#1} }, - colour .code:n = { color = #1 }, - colorall .code:n = , - colourall .code:n = , - colorneg .code:n = , - colourneg .code:n = , - colorunits .meta:n = , - colourunits .meta:n = , - colorvalues .meta:n = , - colourvalues .meta:n = , - decimalsymbol .choice: , - decimalsymbol / - cdot .meta:n = - { output-decimal-marker = \ensuremath { { } \cdot { } } }, - decimalsymbol / - comma .meta:n = { output-decimal-marker = { \ensuremath { { , } } } }, - decimalsymbol / - fullstop .meta:n = { output-decimal-marker = { \ensuremath { { . } } } }, - decimalsymbol / - period .meta:n = { output-decimal-marker = { \ensuremath { { . } } } }, - decimalsymbol / - stop .meta:n = { output-decimal-marker = { \ensuremath { { . } } } }, - decimalsymbol / - tightcdot .code:n = - { output-decimal-marker = \ensuremath { \bgroup \cdot \egroup } }, - decimalsymbol / - unknown .meta:n = { output-decimal-marker = \ensuremath {#1} }, - debug .code:n = , - detectdisplay .meta:n = { detect-display-math = #1 }, - detectdisplay .default:n = { true }, - digitsep .choice: , - digitsep / - cdot .meta:n = - { group-separator = \ensuremath { { } \cdot { } } }, - digitsep / - comma .meta:n = { group-separator = \ensuremath { { , } } }, - digitsep / - fullstop .meta:n = { group-separator = \ensuremath { . } }, - digitsep / - med .meta:n = { group-separator = \ensuremath { \: } }, - digitsep / - medium .meta:n = { group-separator = \ensuremath { \: } }, - digitsep / - none .meta:n = { group-separator = }, - digitsep / - period .meta:n = { group-separator = \ensuremath { . } }, - digitsep / - space .meta:n = { group-separator = \text { ~ } }, - digitsep / - stop .meta:n = { group-separator = \ensuremath { . } }, - digitsep / - thick .meta:n = { group-separator = \ensuremath { \; } }, - digitsep / - thin .meta:n = { group-separator = \ensuremath { \, } }, - digitsep / - tightcdot .meta:n = - { group-separator = \ensuremath { \bgroup \cdot \egroup } }, - digitsep / - tighttimes .meta:n = - { group-separator = \ensuremath { \bgroup \times \egroup } }, - digitsep / - times .meta:n = { group-separator = \ensuremath { \times } }, - digitsep / - unknown .meta:n = { group-separator = \ensuremath {#1} }, - dp .meta:n = - { - round-mode = places, - round-precision = #1, - }, - emulate .code:n = , - errspace .choice: , - errspace / - med .meta:n = { uncertainty-separator = \ensuremath { \: } }, - errspace / - medium .meta:n = { uncertainty-separator = \ensuremath { \: } }, - errspace / - none .meta:n = { uncertainty-separator = }, - errspace / - space .meta:n = { uncertainty-separator = \text { ~ } }, - errspace / - thick .meta:n = { uncertainty-separator = \ensuremath { \; } }, - errspace / - thin .meta:n = { uncertainty-separator = \ensuremath { \, } }, - errspace / - unknown .meta:n = { uncertainty-separator = \ensuremath {#1} }, - eVcorra .code:n = , - eVcorrb .code:n = , - expbase .choice: , - expbase / - ten .meta:n = { exponent-base = 10 }, - expbase / - two .meta:n = { exponent-base = 2 }, - expbase / - unknown .meta:n = { exponent-base = #1 }, - expproduct .choice: , - expproduct / - cdot .meta:n = - { exponent-product = \ensuremath { { } \cdot { } } }, - expproduct / - tightcdot .meta:n = - { exponent-product = \ensuremath { \bgroup \cdot \egroup } }, - expproduct / - tighttimes .meta:n = - { exponent-product = \ensuremath { \bgroup \times \egroup } }, - expproduct / - times .meta:n = { exponent-product = \ensuremath { \times } }, - expproduct / - unknown .meta:n = { exponent-product = \ensuremath {#1} }, - fixdp .choice:, - fixdp / - false .meta:n = { round-mode = none }, - fixdp / - true .meta:n = { round-mode = places }, - fixdp .default:n = { true }, - fixsf .choice: , - fixsf / - false .meta:n = { round-mode = none }, - fixsf / - true .meta:n = { round-mode = figures }, - fixsf .default:n = { true }, - fraction .choice: , - fraction / - frac .meta:n = { fraction-function = \frac }, - fraction / - nice .meta:n = { fraction-function = \frac }, - fraction / - sfrac .meta:n = { fraction-function = \sfrac }, - fraction / - ugly .meta:n = - { - fraction-function = \frac , - per-mode = symbol-or-fraction - }, - inlinebold .meta:n = { detect-inline-weight = #1 }, - log .code:n = , - load .code:n = , - loctolang .code:n = , - mathOmega .meta:n = { math-ohm = #1 }, - mathcelsius .meta:n = { math-celsius = #1 }, - mathdegree .meta:n = { math-degree = #1 }, - mathminute .meta:n = { math-arcminute = #1 }, - mathmu .meta:n = { math-micro = #1 }, - mathringA .meta:n = { math-angstrom = #1 }, - mathrm .code:n = - { \use:x { \keys_set:nn { siunitx } { math-rm = \exp_not:c {#1} } } }, - mathsOmega .meta:n = { math-ohm = #1 }, - mathscelsius .meta:n = { math-celsius = #1 }, - mathsdegree .meta:n = { math-degree = #1 }, - mathsecond .meta:n = { math-arcsecond = #1 }, - mathsf .code:n = - { \use:x { \keys_set:nn { siunitx } { math-sf = \exp_not:c {#1} } } }, - mathsminute .meta:n = { math-arcminute = #1 }, - mathsmu .meta:n = { math-micro = #1 }, - mathsringA .meta:n = { math-angstrom = #1 }, - mathsrm .code:n = - { \use:x { \keys_set:nn { siunitx } { math-rm= \exp_not:c {#1} } } }, - mathssecond .meta:n = { math-arcsecond = #1 }, - mathssf .code:n = - { \use:x { \keys_set:nn { siunitx } { math-sf = \exp_not:c {#1} } } }, - mathstt .code:n = - { \use:x { \keys_set:nn { siunitx } { math-tt = \exp_not:c {#1} } } }, - mathtt .code:n = - { \use:x { \keys_set:nn { siunitx } { math-tt = \exp_not:c {#1} } } }, - negcolor .meta:n = { negative-color = #1 }, - negcolour .meta:n = { negative-color = #1 }, - noload .code:n = , - numaddn .meta:n = { input-symbols = #1 }, - numcloseerr .meta:n = { input-close-uncertainty = #1 }, - numdecimal .meta:n = { input-decimal-markers = #1 }, - numdigits .meta:n = { input-digits = #1 }, - numdiv .meta:n = { input-quotient = #1 }, - numexp .meta:n = { input-exponent-markers = #1 }, - numgobble .meta:n = { input-ignore = #1 }, - numopenerr .meta:n = { input-open-uncertainty = #1 }, - numprod .meta:n = { input-product = #1 }, - numsign .meta:n = { input-signs = #1 }, - obeyall .meta:n = { detect-all = #1 }, - obeyall .default:n = { true }, - obeybold .meta:n = { detect-weight = #1 }, - obeybold .default:n = { true }, - obeyfamily .meta:n = { detect-family = #1 }, - obeyfamily .default:n = { true }, - obeyitalic .meta:n = { detect-shape = #1 }, - obeyitalic .default:n = { true }, - obeymode .meta:n = { detect-mode = #1 }, - obeymode .default:n = { true }, - openerr .meta:n = { open-bracket = \ensuremath {#1} }, - openfrac .meta:n = { open-bracket = \ensuremath {#1} }, - openrange .meta:n = { open-bracket = \ensuremath {#1} }, - padangle .choice: , - padangle / - all .meta:n = - { - add-arc-degree-zero = true, - add-arc-minute-zero = true, - add-arc-second-zero = true - }, - padangle / - both .meta:n = - { - add-arc-degree-zero = true, - add-arc-minute-zero = true, - add-arc-second-zero = true - }, - padangle / - false .meta:n = - { - add-arc-degree-zero = false, - add-arc-minute-zero = false, - add-arc-second-zero = false - }, - padangle / - large .meta:n = - { - add-arc-degree-zero = true, - add-arc-minute-zero = true, - add-arc-second-zero = false - }, - padangle / - none .meta:n = - { - add-arc-degree-zero = false, - add-arc-minute-zero = false, - add-arc-second-zero = false - }, - padangle / - small .meta:n = - { - add-arc-degree-zero = false, - add-arc-minute-zero = true, - add-arc-second-zero = true - }, - true .meta:n = - { - add-arc-degree-zero = true, - add-arc-minute-zero = true, - add-arc-second-zero = true - }, - padnumber .choice: , - padnumber / - all .meta:n = - { - add-decimal-zero = true, - add-integer-zero = true - }, - padnumber / - both .meta:n = - { - add-decimal-zero = true, - add-integer-zero = true - }, - padnumber / - false .meta:n = - { - add-decimal-zero = false, - add-integer-zero = false - }, - padnumber / - leading .meta:n = - { - add-decimal-zero = true, - add-integer-zero = false - }, - padnumber / - none .meta:n = - { - add-decimal-zero = false, - add-integer-zero = false - }, - padnumber / - trailing .meta:n = - { - add-decimal-zero = false, - add-integer-zero = true - }, - padnumber / - true .meta:n = - { - add-decimal-zero = true, - add-integer-zero = true - }, - per .choice: , - per / - frac .meta:n = { per-mode = fraction }, - per / - fraction .meta:n = { per-mode = fraction }, - per / - reciprocal .meta:n = { per-mode = reciprocal }, - per / - slash .meta:n = { per-mode = symbol }, - prefixbase .code:n = , - prefixproduct .code:n = , - prefixsymbolic .meta:n = { prefixes-as-symbols = #1 }, - prefixsymbolic .default:n = { true }, - prespace .meta:n = { space-before-unit = #1 }, - prespace .default:n = { true }, - redefsymbols .meta:n = { redefine-symbols = #1 }, - redefsymbols .default:n = { true }, - repeatunits .choice: , - repeatunits / - false .meta:n = - { - multi-part-units = single, - product-units = single, - range-units = single - }, - repeatunits / - power .meta:n = - { - multi-part-units = repeat, - product-units = power, - range-units = repeat - }, - repeatunits / - true .meta:n = - { - multi-part-units = repeat, - product-units = repeat, - range-units = repeat - }, - repeatunits .default:n = { true }, - retainplus .meta:n = { retain-explicit-plus = #1 }, - retainplus .default:n = { true }, - seperr .meta:n = { separate-uncertainty = #1 }, - seperr .default:n = { true }, - sepfour .meta:n = { group-four-digits = true }, - sepfour .default:n = { true }, - sf .meta:n = - { - round-mode = figures, - round-precision = #1, - }, - sign .meta:n = { explicit-sign = #1 }, - slash .choice: , - slash / - slash .meta:n = { per-symbol = \ensuremath { / } }, - slash / - unknown .meta:n = { per-symbol = \ensuremath {#1} }, - stickyper .meta:n = { sticky-per = #1 }, - stickyper .default:n = { true }, - strictarc .code:n = , - tabalign .code:n = - { - \str_if_eq:nnTF {#1} { centre } - { \keys_set:nn { siunitx } { table-alignment = center } } - { \keys_set:nn { siunitx } { table-alignment = #1 } } - }, - tabalignexp .code:n = { table-align-exponent = #1 }, - tabautofit .meta:n = { table-auto-round = #1 }, - tabautofit .default:n = { true }, - tabexpalign .code:n = { table-align-exponent = #1 }, - tabformat .meta:n = { table-format = #1 }, - tabnumalign .code:n = - { - \str_if_eq:nnTF {#1} { centre } - { \keys_set:nn { siunitx } { table-number-alignment = center } } - { - \str_if_eq:nnTF {#1} { centredecimal } - { - \keys_set:nn { siunitx } - { table-number-alignment = center-decimal-marker } - } - { - \str_if_eq:nnTF {#1} { centerdecimal } - { - \keys_set:nn { siunitx } - { table-number-alignment = center-decimal-marker } - } - { - \keys_set:nn { siunitx } - { table-number-alignment = #1 } - } - } - } - }, - tabparseonly .meta:n = { table-parse-only = #1 }, - tabparseonly .default:n = { true }, - tabtextalign .code:n = - { - \str_if_eq:nnTF {#1} { centre } - { \keys_set:nn { siunitx } { table-text-alignment = center } } - { \keys_set:nn { siunitx } { table-text-alignment = #1 } } - }, - tabunitalign .code:n = - { - \str_if_eq:nnTF {#1} { centre } - { \keys_set:nn { siunitx } { table-unit-alignment = center } } - { \keys_set:nn { siunitx } { table-unit-alignment = #1 } } - }, - textOmega .meta:n = { text-ohm = #1 }, - textcelsius .meta:n = { text-celsius = #1 }, - textdegree .meta:n = { text-degree = #1 }, - textminute .meta:n = { text-arcminute = #1 }, - textmode .choice: , - textmode / - true .meta:n = { mode = text }, - textmode / - false .meta:n = { mode = math }, - textmode .default:n = { true }, - textmu .meta:n = { text-micro = #1 }, - textringA .meta:n = { text-angstrom = #1 }, - textrm .code:n = - { \use:x { \keys_set:nn { siunitx } { text-rm = \exp_not:c {#1} } } }, - textsecond .meta:n = { text-arcsecond = #1 }, - textsf .code:n = - { \use:x { \keys_set:nn { siunitx } { text-sf = \exp_not:c {#1} } } }, - texttt .code:n = - { \use:x { \keys_set:nn { siunitx } { text-tt = \exp_not:c {#1} } } }, - tightpm .meta:n = { tight-spacing = #1 }, - tightpm .default:n = { true }, - tophrase .meta:n = { range-phrase = #1 }, - trapambigerr .choice: , - trapambigerr - / false .meta:n = { multi-part-units = single }, - trapambigerr - / true .meta:n = { multi-part-units = brackets }, - trapambigerr .default:n = { true }, - trapambigfrac .meta:n = { bracket-numbers = #1 }, - trapambigfrac .default:n = { true }, - trapambigrange .choice: , - trapambigrange - / false .meta:n = { range-units = single }, - trapambigrange - / true .meta:n = { range-units = brackets }, - trapambigrange .default:n = { true }, - unitcolor .meta:n = { unit-color = #1 }, - unitcolour .meta:n = { unit-color = #1 }, - unitmathrm .code:n = - { \use:x { \keys_set:nn { siunitx } { unit-math-rm = \exp_not:c {#1} } } }, - unitmathsf .code:n = - { \use:x { \keys_set:nn { siunitx } { unit-math-sf = \exp_not:c {#1} } } }, - unitmathsrm .code:n = - { \use:x { \keys_set:nn { siunitx } { unit-math-rm = \exp_not:c {#1} } } }, - unitmathssf .code:n = - { \use:x { \keys_set:nn { siunitx } { unit-math-sf = \exp_not:c {#1} } } }, - unitmathstt .code:n = - { \use:x { \keys_set:nn { siunitx } { unit-math-tt = \exp_not:c {#1} } } }, - unitmathtt .code:n = - { \use:x { \keys_set:nn { siunitx } { unit-math-tt = \exp_not:c {#1} } } }, - unitmode .meta:n = { unit-mode = #1 }, - unitsep .choice: , - unitsep / - cdot .meta:n = - { inter-unit-product = \ensuremath { { } \cdot { } } }, - unitsep / - comma .meta:n = { inter-unit-product = { {,} } }, - unitsep / - fullstop .meta:n = { inter-unit-product = { { . } } }, - unitsep / - med .meta:n = { inter-unit-product = \ensuremath { \: } }, - unitsep / - medium .meta:n = { inter-unit-product = \ensuremath { \: } }, - unitsep / - none .meta:n = { inter-unit-product = }, - unitsep / - period .meta:n = { inter-unit-product = { { . } } }, - unitsep / - space .meta:n = { inter-unit-product = \text { ~ } }, - unitsep / - stop .meta:n = { inter-unit-product = { { . } } }, - unitsep / - thick .meta:n = { inter-unit-product = \ensuremath { \; } }, - unitsep / - thin .meta:n = { inter-unit-product = \, }, - unitsep / - tightcdot .meta:n = - { inter-unit-product = \ensuremath { \bgroup \cdot \egroup } }, - unitsep / - tighttimes .meta:n = - { inter-unit-product = \ensuremath { \bgroup \times \egroup } }, - unitsep / - times .meta:n = { inter-unit-product = \ensuremath { \times } }, - unitsep / - unknown .meta:n = { inter-unit-product = \ensuremath {#1} }, - unitspace .choice: , - unitspace / - med .meta:n = { inter-unit-product = \ensuremath { \: } }, - unitspace / - medium .meta:n = { inter-unit-product = \ensuremath { \: } }, - unitspace / - none .meta:n = { inter-unit-product = }, - unitspace / - space .meta:n = { inter-unit-product = \text { ~ } }, - unitspace / - thick .meta:n = { inter-unit-product = \ensuremath { \; } }, - unitspace / - thin .meta:n = { inter-unit-product = \, }, - unitspace / - unknown .meta:n = { inter-unit-product = \ensuremath {#1} }, - valuecolor .meta:n = { number-color = #1 }, - valuecolour .meta:n = { number-color = #1 }, - valuemathrm .code:n = - { \use:x { \keys_set:nn { siunitx } { number-math-rm = \exp_not:c {#1} } } }, - valuemathsf .code:n = - { \use:x { \keys_set:nn { siunitx } { number-math-sf = \exp_not:c {#1} } } }, - valuemathsrm .code:n = - { \use:x { \keys_set:nn { siunitx } { number-math-rm = \exp_not:c {#1} } } }, - valuemathssf .code:n = - { \use:x { \keys_set:nn { siunitx } { number-math-sf = \exp_not:c {#1} } } }, - valuemathstt .code:n = - { \use:x { \keys_set:nn { siunitx } { number-math-tt = \exp_not:c {#1} } } }, - valuemathtt .code:n = - { \use:x { \keys_set:nn { siunitx } { number-math-tt = \exp_not:c {#1} } } }, - valuemode .meta:n = { number-mode = #1 }, - valuesep .choice: , - valuesep / - cdot .meta:n = - { number-unit-product = \ensuremath { { } \cdot { } } }, - valuesep / - comma .meta:n = { number-unit-product = { {,} } }, - valuesep / - fullstop .meta:n = { number-unit-product = { { . } } }, - valuesep / - med .meta:n = { number-unit-product = \ensuremath { \: } }, - valuesep / - medium .meta:n = { number-unit-product = \ensuremath { \: } }, - valuesep / - none .meta:n = { number-unit-product = }, - valuesep / - period .meta:n = { number-unit-product = { { . } } }, - valuesep / - space .meta:n = { number-unit-product = \text { ~ } }, - valuesep / - stop .meta:n = { number-unit-product = { { . } } }, - valuesep / - thick .meta:n = { number-unit-product = \ensuremath { \; } }, - valuesep / - thin .meta:n = { number-unit-product = \, }, - valuesep / - tightcdot .meta:n = - { number-unit-product = \ensuremath { \bgroup \cdot \egroup } }, - valuesep / - tighttimes .meta:n = - { number-unit-product = \ensuremath { \bgroup \times \egroup } }, - valuesep / - times .meta:n = { number-unit-product = \ensuremath { \times } }, - valuesep / - unknown .meta:n = { number-unit-product = \ensuremath {#1} }, - xspace .meta:n = { use-xspace = #1 }, - xspace .default:n = { true }, -} -% \end{macrocode} -% -% The error can be simplified here: if the option is not known, then -% it really is an error. -% \begin{macrocode} -\keys_define:nn { siunitx } { - unknown .code:n = - { - \msg_error:nnx { siunitx } { unknown-option } - { \exp_not:V \l_keys_key_tl } - } -} -% \end{macrocode} -% -% A couple of settings which are slightly different by default in -% version 1. -% \begin{macrocode} -\keys_set:nn { siunitx } {free-standing-units = true} -% \end{macrocode} -% -%\begin{macro}{ -% \newunit , -% \renewunit , -% \provideunit -%} -% The functions for creating units from version one are easy to create. -% \begin{macrocode} -\cs_new_eq:NN \newunit \DeclareSIUnit -\cs_new_eq:NN \renewunit \DeclareSIUnit -\cs_new_eq:NN \provideunit \DeclareSIUnit -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \newpower , -% \renewpower , -% \providepower -%} -% Slightly more complex: an optional argument to check. A simple -% assumption is made that it will be \texttt{post}: anything else -% would not make sense anyway. -% \begin{macrocode} -\NewDocumentCommand \newpower { o m m } { - \IfNoValueTF {#1} - { \DeclareSIPrePower #2 {#3} } - { \DeclareSIPostPower #2 {#3} } -} -\NewDocumentCommand \renewpower { o m m } { - \IfNoValueTF {#1} - { \DeclareSIPrePower #2 {#3} } - { \DeclareSIPostPower #2 {#3} } -} -\NewDocumentCommand \providepower { o m m } { - \IfNoValueTF {#1} - { \DeclareSIPrePower #2 {#3} } - { \DeclareSIPostPower #2 {#3} } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \newprefix , -% \renewprefix , -% \provideprefix -%} -% Slightly more complex: an optional argument to check. A simple -% assumption is made that it will be \texttt{post}: anything else -% would not make sense anyway. -% \begin{macrocode} -\NewDocumentCommand \newprefix { o m m m } { - \IfNoValueTF {#1} - { \DeclareSIPrefix #2 {#3} {#4} } - { \DeclareBinaryPrefix #2 {#3} {#4} } -} -\NewDocumentCommand \renewprefix { o m m m } { - \IfNoValueTF {#1} - { \DeclareSIPrefix #2 {#3} {#4} } - { \DeclareBinaryPrefix #2 {#3} {#4} } -} -\NewDocumentCommand \provideprefix { o m m m } { - \IfNoValueTF {#1} - { \DeclareSIPrefix #2 {#3} {#4} } - { \DeclareBinaryPrefix #2 {#3} {#4} } -} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \newqualifier , -% \renewqualifier , -% \providequalifier -%} -% The functions for creating qualifiers are easy to create again. -% \begin{macrocode} -\NewDocumentCommand \newqualifier { m m } { - \@@_declare_qualifier:Nn #1 {#2} -} -\cs_new_eq:NN \renewqualifier \newqualifier -\cs_new_eq:NN \providequalifier \newqualifier -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \Square , -% \ssquare -%} -% In version 1, \cs{square} is not used with these two alternatives -% preferred. -% \begin{macrocode} -\DeclareSIPrePower \Square { 2 } -\DeclareSIPrePower \ssquare { 2 } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \BAR , -% \bbar , -% \Day , -% \dday , -% \Gray , -% \ggray -%} -% Units which are given awkward names in version one. -% \begin{macrocode} -\DeclareSIUnit \BAR { \bar } -\DeclareSIUnit \bbar { \bar } -\DeclareSIUnit \Day { \day } -\DeclareSIUnit \dday { \day } -\DeclareSIUnit \Gray { \gray } -\DeclareSIUnit \ggray { \gray } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \atomicmass , -% \arcmin , -% \arcsec -%} -% Slightly different: given more complete names in version two. -% \begin{macrocode} -\DeclareSIUnit \atomicmass { \atomicmassunit } -\DeclareSIUnit \arcmin { \arcminute } -\DeclareSIUnit \arcsec { \arcsecond } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \are , -% \curie , -% \gal , -% \millibar , -% \rad , -% \rem , -% \roentgen -%} -% Units which were defined in version one but are no longer listed -% by the \textsc{bipm} as acceptable. -% \begin{macrocode} -\DeclareSIUnit \are { a } -\DeclareSIUnit \curie { Ci } -\DeclareSIUnit \gal { Gal } -\DeclareSIUnit \millibar { \milli \bar } -\DeclareSIUnit \rad { rad } -\DeclareSIUnit \rem { rem } -\DeclareSIUnit \roentgen { R } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \micA , -% \micmol , -% \micl , -% \micL , -% \nanog , -% \micg , -% \picm , -% \micm , -% \Sec , -% \mics , -% \cmc , -% \dmc , -% \cms -%} -% A few abbreviations which have been renamed. -% \begin{macrocode} -\DeclareSIUnit \micA { \micro \ampere } -\DeclareSIUnit \micmol { \micro \mole } -\DeclareSIUnit \micl { \micro \litre } -\DeclareSIUnit \micL { \micro \liter } -\DeclareSIUnit \nanog { \nano \gram } -\DeclareSIUnit \micg { \micro \gram } -\DeclareSIUnit \picm { \pico \metre } -\DeclareSIUnit \micm { \micro \metre } -\DeclareSIUnit \Sec { \second } -\DeclareSIUnit \mics { \micro \second } -\DeclareSIUnit \cmc { \centi \metre \cubed } -\DeclareSIUnit \dmc { \deci \metre \cubed } -\DeclareSIUnit \cms { \centi \metre \squared } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \centimetrecubed , -% \centimetresquared , -% \cubiccentimetre , -% \cubicdecimetre , -% \squarecentimetre , -% \squaremetre , -% \squarekilometre -%} -% Units from version one that did not seem like a good idea to retain. -% \begin{macrocode} -\DeclareSIUnit \centimetrecubed { \centi \metre \cubed } -\DeclareSIUnit \centimetresquared { \centi \metre \squared } -\DeclareSIUnit \cubiccentimetre { \centi \metre \cubed } -\DeclareSIUnit \cubicdecimetre { \deci \metre \cubed } -\DeclareSIUnit \squarecentimetre { \centi \metre \squared } -\DeclareSIUnit \squaremetre { \metre \squared } -\DeclareSIUnit \squarekilometre { \kilo \metre \squared } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \parsec , -% \lightyear -%} -% A few units for astronomy that version 1 provided. -% \begin{macrocode} -\DeclareSIUnit \parsec { pc } -\DeclareSIUnit \lightyear { ly } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \gmol , -% \kgmol , -% \lbmol -%} -% Slightly odd chemical engineering units, again provided in version 1. -% \begin{macrocode} -\DeclareSIUnit \gmol { g \text { - } mol } -\DeclareSIUnit \kgmol { kg \text { - } mol } -\DeclareSIUnit \lbmol { lb \text { - } mol } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \molar , -% \Molar , -% \torr -%} -% A few common units for chemistry from version 1. \cs{molar} is -% simply a handy abbreviation: \cs{Molar} is common but rather -% questionable. -% \begin{macrocode} -\DeclareSIUnit \molar { \mole \per \cubic \deci \metre } -\DeclareSIUnit \Molar { \textsc { m } } -\DeclareSIUnit \torr { Torr } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\gon} -% A single unit for geophysics that version 1 included. -% \begin{macrocode} -\DeclareSIUnit \gon { gon } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\clight} -% Version one had a different definition for \cs{clight}. -% \begin{macrocode} -\DeclareSIUnit \clight { \text { \ensuremath { c } } } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{ -% \micron , -% \mrad , -% \gauss , -% \eVperc , -% \nanobarn , -% \picobarn , -% \femptobarn , -% \attobarn , -% \zeptobarn , -% \yoctobarn , -% \nb , -% \pb , -% \fb , -% \ab , -% \zb -%} -% High-energy physics units from version one. -% \begin{macrocode} -\DeclareSIUnit \micron { \micro \metre } -\DeclareSIUnit \mrad { \milli \rad } -\DeclareSIUnit \gauss { G } -\DeclareSIUnit \eVperc { \eV \per \clight } -\DeclareSIUnit \nanobarn { \nano \barn } -\DeclareSIUnit \picobarn { \pico \barn } -\DeclareSIUnit \femtobarn { \femto \barn } -\DeclareSIUnit \attobarn { \atto \barn } -\DeclareSIUnit \zeptobarn { \zepto \barn } -\DeclareSIUnit \yoctobarn { \yocto \barn } -\DeclareSIUnit \nb { \nano \barn } -\DeclareSIUnit \pb { \pico \barn } -\DeclareSIUnit \fb { \femto \barn } -\DeclareSIUnit \ab { \atto \barn } -\DeclareSIUnit \zb { \zepto \barn } -\DeclareSIUnit \yb { \yocto \barn } -% \end{macrocode} -%\end{macro} -% -% \begin{macro}{\requiresiconfigs} -% Version one provides this, and it might pop up so should not -% cause errors. -% \begin{macrocode} -\NewDocumentCommand \requiresiconfigs { m } - { \keys_set:nn { siunitx } { version-1-compatibility } } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</version-1> -% \end{macrocode} -% -% \subsection{Abbreviated units} -% -% \begin{macrocode} -%<*abbreviations> -% \end{macrocode} -% -% \begin{macrocode} -\ProvidesExplFile {siunitx-abbreviations.cfg} {2021-04-17} {2.8e} - {siunitx: Abbreviated units} -% \end{macrocode} -% -% The abbreviation file contains a number of short (mainly two or -% three letter) versions of the usual long names. They are divided up -% into related groups, mainly to avoid an overly long list in one -% place. -% -% \begin{macro}{\A, \pA, \nA, \uA, \mA, \kA} -% Currents. -% \begin{macrocode} -\DeclareSIUnit \A { \ampere } -\DeclareSIUnit \pA { \pico \ampere } -\DeclareSIUnit \nA { \nano \ampere } -\DeclareSIUnit \uA { \micro \ampere } -\DeclareSIUnit \mA { \milli \ampere } -\DeclareSIUnit \kA { \kilo \ampere } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\Hz, \mHz, \kHz, \MHz, \GHz, \THz} -% Then frequencies. -% \begin{macrocode} -\DeclareSIUnit \Hz { \hertz } -\DeclareSIUnit \mHz { \milli \hertz } -\DeclareSIUnit \kHz { \kilo \hertz } -\DeclareSIUnit \MHz { \mega \hertz } -\DeclareSIUnit \GHz { \giga \hertz } -\DeclareSIUnit \THz { \tera \hertz } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\mol, \fmol, \pmol, \nmol, \umol, \mmol, \kmol} -% Amounts of substance (moles). -% \begin{macrocode} -\DeclareSIUnit \mol { \mole } -\DeclareSIUnit \fmol { \femto \mole } -\DeclareSIUnit \pmol { \pico \mole } -\DeclareSIUnit \nmol { \nano \mole } -\DeclareSIUnit \umol { \micro \mole } -\DeclareSIUnit \mmol { \milli \mole } -\DeclareSIUnit \kmol { \kilo \mole } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\V, \pV, \nV, \uV, \mV, \kV} -% Potentials. -% \begin{macrocode} -\DeclareSIUnit \V { \volt } -\DeclareSIUnit \pV { \pico \volt } -\DeclareSIUnit \nV { \nano \volt } -\DeclareSIUnit \uV { \micro \volt } -\DeclareSIUnit \mV { \milli \volt } -\DeclareSIUnit \kV { \kilo \volt } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\hl, \l, \ml, \ul, \hL, \L, \mL, \uL} -% Volumes. -% \begin{macrocode} -\DeclareSIUnit \hl { \hecto \litre } -\DeclareSIUnit \l { \litre } -\DeclareSIUnit \ml { \milli \litre } -\DeclareSIUnit \ul { \micro \litre } -\DeclareSIUnit \hL { \hecto \liter } -\DeclareSIUnit \L { \liter } -\DeclareSIUnit \mL { \milli \liter } -\DeclareSIUnit \uL { \micro \liter } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\fg, \pg, \ng, \ug, \mg, \g, \kg, \amu} -% Masses. -% \begin{macrocode} -\DeclareSIUnit \fg { \femto \gram } -\DeclareSIUnit \pg { \pico \gram } -\DeclareSIUnit \ng { \nano \gram } -\DeclareSIUnit \ug { \micro \gram } -\DeclareSIUnit \mg { \milli \gram } -\DeclareSIUnit \g { \gram } -\DeclareSIUnit \kg { \kilo \gram } -\DeclareSIUnit \amu { \atomicmassunit } -% \end{macrocode} -% \end{macro} -% \begin{macro} -% {\W, \uW, \mW, \kW, \MW, \GW, \kJ, \J, \mJ, \uJ, \eV, \meV, \keV, \MeV, \GeV, \TeV, \kWh} -% Energies. -% \begin{macrocode} -\DeclareSIUnit \W { \watt } -\DeclareSIUnit \uW { \micro \watt } -\DeclareSIUnit \mW { \milli \watt } -\DeclareSIUnit \kW { \kilo \watt } -\DeclareSIUnit \MW { \mega \watt } -\DeclareSIUnit \GW { \giga \watt } -\DeclareSIUnit \J { \joule } -\DeclareSIUnit \uJ { \micro \joule } -\DeclareSIUnit \mJ { \milli \joule } -\DeclareSIUnit \kJ { \kilo \joule } -\DeclareSIUnit \eV { \electronvolt } -\DeclareSIUnit \meV { \milli \electronvolt } -\DeclareSIUnit \keV { \kilo \electronvolt } -\DeclareSIUnit \MeV { \mega \electronvolt } -\DeclareSIUnit \GeV { \giga \electronvolt } -\DeclareSIUnit \TeV { \tera \electronvolt } -\DeclareSIUnit [ inter-unit-product = ] \kWh { \kilo \watt \hour } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\m, \pm, \nm, \um, \mm, \cm, \dm, \km} -% Lengths. -% \begin{macrocode} -\DeclareSIUnit \m { \metre } -\DeclareSIUnit \pm { \pico \metre } -\DeclareSIUnit \nm { \nano \metre } -\DeclareSIUnit \um { \micro \metre } -\DeclareSIUnit \mm { \milli \metre } -\DeclareSIUnit \cm { \centi \metre } -\DeclareSIUnit \dm { \deci \metre } -\DeclareSIUnit \km { \kilo \metre } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\K} -% Temperatures. -% \begin{macrocode} -\DeclareSIUnit \K { \kelvin } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\dB} -% \begin{macrocode} -\DeclareSIUnit \dB { \deci \bel } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\F, \fF, \pF} -% \begin{macrocode} -\DeclareSIUnit \F { \farad } -\DeclareSIUnit \fF { \femto \farad } -\DeclareSIUnit \pF { \pico \farad } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\N, \mN, \kN, \MN} -% Forces. -% \begin{macrocode} -\DeclareSIUnit \N { \newton } -\DeclareSIUnit \mN { \milli \newton } -\DeclareSIUnit \kN { \kilo \newton } -\DeclareSIUnit \MN { \mega \newton } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\Pa, \kPa, \MPa, \GPa} -% Pressures. -% \begin{macrocode} -\DeclareSIUnit \Pa { \pascal } -\DeclareSIUnit \kPa { \kilo \pascal } -\DeclareSIUnit \MPa { \mega \pascal } -\DeclareSIUnit \GPa { \giga \pascal } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\mohm, \kohm, \Mohm} -% Resistances. -% \begin{macrocode} -\DeclareSIUnit \mohm { \milli \ohm } -\DeclareSIUnit \kohm { \kilo \ohm } -\DeclareSIUnit \Mohm { \mega \ohm } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\s, \as, \fs, \ps, \ns, \us, \ms} -% Finally, times. -% \begin{macrocode} -\DeclareSIUnit \s { \second } -\DeclareSIUnit \as { \atto \second } -\DeclareSIUnit \fs { \femto \second } -\DeclareSIUnit \ps { \pico \second } -\DeclareSIUnit \ns { \nano \second } -\DeclareSIUnit \us { \micro \second } -\DeclareSIUnit \ms { \milli \second } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</abbreviations> -% \end{macrocode} -% -% \subsection{Binary units} -% -% \begin{macrocode} -%<*binary> -% \end{macrocode} -% -% \begin{macrocode} -\ProvidesExplFile {siunitx-binary.cfg} {2021-04-17} {2.8e} - {siunitx: Binary units} -% \end{macrocode} -% -% \begin{macro}{\kibi, \mebi, \gibi, \tebi, \pebi, \exbi, \zebi, \yobi} -% The binary units as specified by the IEC. -% \begin{macrocode} -\DeclareBinaryPrefix \kibi { Ki } { 10 } -\DeclareBinaryPrefix \mebi { Mi } { 20 } -\DeclareBinaryPrefix \gibi { Gi } { 30 } -\DeclareBinaryPrefix \tebi { Ti } { 40 } -\DeclareBinaryPrefix \pebi { Pi } { 50 } -\DeclareBinaryPrefix \exbi { Ei } { 60 } -\DeclareBinaryPrefix \zebi { Zi } { 70 } -\DeclareBinaryPrefix \yobi { Yi } { 80 } -% \end{macrocode} -% \end{macro} -% \begin{macro}{\bit, \byte} -% Now the units. -% \begin{macrocode} -\DeclareSIUnit \bit { bit } -\DeclareSIUnit \byte { B } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</binary> -% \end{macrocode} -% % \end{implementation} % -% \begin{thebibliography}{1} -% -% \bibitem{BIPM} -% \emph{The International System of Units (SI)}, -% \url{http://www.bipm.org/en/measurement-units/}. -% -% \bibitem{NIST} -% \emph{International System of Units from NIST}, -% \url{http://physics.nist.gov/cuu/Units/index.html}. -% -% \bibitem{SI:2.1} -% \emph{SI base units}, -% \url{http://www.bipm.org/en/publications/si-brochure/section2-1.html}. -% -% \bibitem{SI:2.2.2} -% \emph{Units with special names and symbols; units that -% incorporate special names and symbols}, -% \url{http://www.bipm.org/en/publications/si-brochure/section2-2-2.html}. -% -% \bibitem{SI:3.1} -% \emph{SI Prefixes}, -% \url{http://www.bipm.org/en/publications/si-brochure/chapter3.html}. -% -% \bibitem{SI:4.1.T6} -% \emph{Non-SI units accepted for use with the International -% System of Units}, -% \url{http://www.bipm.org/en/publications/si-brochure/table6.html}. -% -% \bibitem{SI:4.1.T7} -% \emph{Non-SI units whose values in SI units must be obtained -% experimentally}, -% \url{http://www.bipm.org/en/publications/si-brochure/table7.html}. -% -% \bibitem{SI:4.1.T8} -% \emph{Other non-SI units}, -% \url{http://www.bipm.org/en/publications/si-brochure/table8.html}. -% -% \bibitem{SI:5.3.3} -% \emph{Formatting the value of a quantity}, -% \url{http://www.bipm.org/en/publications/si-brochure/section5-3-3.html}. -% -% \end{thebibliography} -% -% \PrintChanges -% -% \newpage -% % \PrintIndex diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx.ins b/Master/texmf-dist/source/latex/siunitx/siunitx.ins new file mode 100644 index 00000000000..18e3a127361 --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx.ins @@ -0,0 +1,104 @@ +\iffalse meta-comment + +File: siunitx.ins Copyright (C) 2014-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. + +----------------------------------------------------------------------- + +\fi + +\input l3docstrip.tex +\askforoverwritefalse + +% stop DocStrip adding rather wordy text +\preamble +\endpreamble +\postamble +Copyright (C) 2008-2021 by + Joseph Wright <joseph.wright@morningstar2.co.uk> + +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 work is "maintained" (as per LPPL maintenance status) by + Joseph Wright. + +This work consists of the files siunitx.dtx, + siunitx.ins, + siunitx.tex, + siunitx-abbreviation.cfg, + siunitx-abbreviation.dtx, + siunitx-angle.dtx, + siunitx-binary.cfg, + siunitx-binary.dtx, + siunitx-code.tex, + siunitx-command.dtx, + siunix-complex.dtx, + siunitx-compound.dtx, + siunitx-emulation.dtx, + siunitx-locale.dtx, + siunitx-number.dtx, + siunitx-print.dtx, + siunitx-quantity.dtx, + siunitx-symbol.dtx, + siunitx-table.dtx, + siunitx-unit.dtx, + siunitx-v2.sty and + siunitx-version-1.cfg, + and the derived files siunitx.pdf, + siunitx.sty and + siunitx-code.pdf. + +\endpostamble + +\keepsilent + +\generate + {% + \file{siunitx.sty} + {% + \from{siunitx.dtx} {package,init} + \from{siunitx-angle.dtx} {package} + \from{siunitx-complex.dtx} {package} + \from{siunitx-compound.dtx} {package} + \from{siunitx-locale.dtx} {package} + \from{siunitx-number.dtx} {package} + \from{siunitx-print.dtx} {package} + \from{siunitx-table.dtx} {package} + \from{siunitx-unit.dtx} {package} + \from{siunitx-quantity.dtx} {package} + \from{siunitx-symbol.dtx} {package} + \from{siunitx-abbreviation.dtx}{package} + \from{siunitx-binary.dtx} {package} + \from{siunitx-command.dtx} {package} + \from{siunitx-emulation.dtx} {package,options} + \from{siunitx.dtx} {package,options} + \from{siunitx-emulation.dtx} {package,interfaces} + \from{siunitx.dtx} {package,interfaces} + }% + } + +\endbatchfile diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx.tex b/Master/texmf-dist/source/latex/siunitx/siunitx.tex new file mode 100644 index 00000000000..2637236df4a --- /dev/null +++ b/Master/texmf-dist/source/latex/siunitx/siunitx.tex @@ -0,0 +1,3621 @@ +\iffalse meta-comment + +File: siunitx.tex Copyright (C) 2014-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. + +----------------------------------------------------------------------- + +\fi + +\documentclass{l3doc} + +% The next line is needed so that \GetFileInfo will be able to pick up +% version data (quite apart from making the demos work). +\usepackage{siunitx} +\DeclareSIUnit\noop{\relax} % For printing prefixes +\DeclareSIPower\quartic\tothefourth{4} % For demos +\DeclareSIUnit\KWH{kWh} +\DeclareSIQualifier\polymer{pol} +\DeclareSIQualifier\catalyst{cat} +\DeclareSIUnit\millimetremercury{mmHg} + +% Commands for this document +\ExplSyntaxOn +\makeatletter +\NewDocumentCommand \acro { m } + { + \textsc + { + \exp_args:NV \tl_if_head_eq_charcode:nNTF \f@series { m } + { \tl_lower_case:n } + { \use:n } + {#1} + } + } +\makeatother +\ExplSyntaxOff +\NewDocumentCommand\email{m}{\href{mailto:#1}{\nolinkurl{#1}}} +\NewDocumentCommand\ext{m}{\texttt{.#1}} +\NewDocumentCommand\foreign{m}{\textit{#1}} +\NewDocumentCommand\opt{m}{\texttt{#1}} +% Tidy up the above in bookmarks +\makeatletter +\pdfstringdefDisableCommands{% + \let\acro\@firstofone + \let\ext\@firstofone + \let\foreign\@firstofone + \let\opt\@firstofone +} +\makeatother + +\NewDocumentCommand\DescribePrefix{m}{% + #1 & + \cs{#1} & + \unit{\csname #1\endcsname\noop} +} +\NewDocumentCommand\DescribeUnit{O{#2}m}{% + #1 & + \cs{#2} & + \unit{\csname #2\endcsname} +} + +% For demos +\usepackage[french,german,spanish,UKenglish]{babel} +\AtBeginDocument{\shorthandoff{:<>}} +\usepackage{translations} +\usepackage{cancel} +\usepackage{collcell} +\usepackage{sansmath} +\newlength{\mylength} + +% For creating code demonstrations +% This needs access to some code-level interfaces in listings +\usepackage{listings} +\makeatletter +\lst@RequireAspects{writefile} +\newsavebox\LaTeXdemo@box +\lstnewenvironment{LaTeXdemo}[1][code and example] + {% + \global\let\lst@intname\@empty + \edef\LaTeXdemo@end{% + \expandafter\noexpand\csname LaTeXdemo@@#1@end\endcsname + }% + \@nameuse{LaTeXdemo@@#1}% + } + {\LaTeXdemo@end} +\newcommand\LaTeXdemo@new[3]{% + \@namedef{LaTeXdemo@@#1}{#2}% + \@namedef{LaTeXdemo@@#1@end}{#3}% +} +\newcommand*\LaTeXdemo@common{% + \setkeys{lst} + {% + basicstyle = \small\ttfamily, + basewidth = 0.51em, + gobble = 2, + language = [LaTeX]{TeX}, + }% +} +\newcount\LaTeXdemo@count +\newcommand*\LaTeXdemo@input{% + \catcode`\^^M = 10\relax + \input{\jobname-\number\LaTeXdemo@count.tmp}% +} +\LaTeXdemo@new{code and example}{% + \setbox\LaTeXdemo@box=\hbox\bgroup + \global\advance\LaTeXdemo@count by 1 % + \lst@BeginAlsoWriteFile{\jobname-\number\LaTeXdemo@count.tmp}% + \LaTeXdemo@common +}{% + \lst@EndWriteFile + \egroup + \begin{center} + \ifdim\wd\LaTeXdemo@box > 0.48\linewidth + \begin{minipage}{\linewidth} + \usebox\LaTeXdemo@box + \end{minipage}% + \par + \begin{minipage}{\linewidth} + \LaTeXdemo@input + \end{minipage} + \else + \begin{minipage}{0.48\linewidth} + \LaTeXdemo@input + \end{minipage}% + \hfil + \begin{minipage}{0.48\linewidth} + \usebox\LaTeXdemo@box + \end{minipage}% + \fi + \end{center} +} +\LaTeXdemo@new{code and float}{% + \global\advance\LaTeXdemo@count by 1 % + \lst@BeginAlsoWriteFile{\jobname-\number\LaTeXdemo@count.tmp}% + \LaTeXdemo@common +}{% + \lst@EndWriteFile + \LaTeXdemo@input +} +\LaTeXdemo@new{code only}{\LaTeXdemo@common}{} +\makeatother + +% For table demos +\usepackage{datatool} +\usepackage{multirow} +\usepackage[table]{xcolor} +% Has to come after xcolor +\usepackage{pgfplots} +\pgfplotsset{compat = 1.16, compat/show suggested version = false} +\usepackage{xfp} + +% For the extra-long tables +\usepackage{xtab} + +% For the table notes +\usepackage{threeparttable} + +% Design changes +\usepackage{caption} +\makeatletter +\edef\@floatboxreset{% + \unexpanded\expandafter{\@floatboxreset}% + \noexpand\centering +} +\makeatother +\usepackage[osf]{mathpazo} + +\hypersetup{hidelinks} + +\begin{document} + +\GetFileInfo{siunitx.sty} + +\title{% + \pkg{siunitx} -- A comprehensive (\acro{SI}) units package% + \thanks{This file describes \fileversion, + last revised \filedate.}% +} + +\author{% + Joseph Wright% + \thanks{% + E-mail: + \href{mailto:joseph.wright@morningstar2.co.uk} + {joseph.wright@morningstar2.co.uk}% + }% +} + +\date{Released \filedate} + +\maketitle + +\tableofcontents + +\begin{abstract} + Physical quantities have both numbers and units, and each physical quantity + should be expressed as the product of a number and a unit. Typesetting + physical quantities requires care to ensure that the combined mathematical + meaning of the number--unit combination is clear. In particular, the + \acro{SI} units system lays down a consistent set of units with rules on how + these are to be used. However, different countries and publishers have + differing conventions on the exact appearance of numbers (and units). The + \pkg{siunitx} package provides a set of tools for authors to typeset + quantities in a consistent way. The package has an extended set of + configuration options which make it possible to follow varying typographic + conventions with the same input syntax. The package includes automated + processing of numbers and units, and the ability to control tabular alignment + of numbers. +\end{abstract} + +\begin{documentation} + +\section{Introduction} + +The correct application of units of measurement is very important in technical +applications. For this reason, carefully-crafted definitions of a coherent +units system have been laid down by the \foreign{Conférence Génrale des Poids +et Mesures} (\acro{CGPM}): this has resulted in the \foreign{Système +International d'Unités}~(\acro{SI}). At the same time, typographic conventions +for correctly displaying both numbers and units exist to ensure that no loss of +meaning occurs in printed matter. + +The \pkg{siunitx} package aims to provide a unified method for \LaTeX{} users +to typeset numbers and units correctly and easily. The design philosophy of +\pkg{siunitx} is to follow the agreed rules by default, but to allow variation +through option settings. In this way, users can use \pkg{siunitx} to follow the +requirements of publishers, co-authors, universities, \foreign{etc}.\ without +needing to alter the input at all. + +\section{\pkg{siunitx} for the impatient} + +The package provides the user macros: +\begin{itemize} + \item \cs{ang}\oarg{options}\marg{angle} + \item \cs{num}\oarg{options}\marg{number} + \item \cs{unit}\oarg{options}\marg{unit} + \item \cs{qty}\oarg{options}\marg{number}\marg{unit} + \item \cs{numlist}\oarg{options}\marg{numbers} + \item \cs{numproduct}\oarg{options}\marg{numbers} + \item \cs{numrange}\oarg{options}\marg{numbers}\marg{number2} + \item \cs{qtylist}\oarg{options}\marg{numbers}\marg{unit} + \item \cs{qtyproduct}\oarg{options}\marg{numbers}\marg{unit} + \item \cs{qtyrange}\oarg{options}\marg{number1}\marg{number2}\marg{unit} + \item \cs{complexnum}\oarg{options}\marg{number} + \item \cs{complexqty}\oarg{options}\marg{number}\marg{unit} + \item \cs{sisetup}\marg{options} + \item \cs{tablenum}\oarg{options}\marg{number} +\end{itemize} +plus the \texttt{S} column type for decimal alignments and units in tabular +environments. These user macros and column types are designed for typesetting +numbers and units with control of appearance and with intelligent processing. + +Numbers are processed with understanding of exponents, or using additional +commands for products and complex numbers. +\begin{LaTeXdemo} + \num{12345,67890} \\ + \num{.3e45} \\ + \complexnum{1+-2i} \\ + \numproduct{1.654 x 2.34 x 3.430} +\end{LaTeXdemo} + +The unit system can interpret units given as text to be used directly or as +macro-based units. In the latter case, different formatting is possible. +\begin{LaTeXdemo} + \unit{kg.m.s^{-1}} \\ + \unit{\kilogram\metre\per\second} \\ + \unit[per-mode = symbol] + {\kilogram\metre\per\second} \\ + \unit[per-mode = symbol] + {\kilogram\metre\per\ampere\per\second} +\end{LaTeXdemo} + +Simple lists and ranges of numbers can be handled. +\begin{LaTeXdemo} + \numlist{10;20;30} \\ + \qtylist{0.13;0.67;0.80}{\milli\metre} \\ + \numrange{10}{20} \\ + \qtyrange{0.13}{0.67}{\milli\metre} +\end{LaTeXdemo} + +By default, all text is typeset in the current upright math font. This can be +changed by setting the appropriate options. + +\section{Using the \pkg{siunitx} package} + +\subsection{Numbers} + +\begin{function}{\num} + \begin{syntax} + \cs{num}\oarg{options}\marg{number} + \end{syntax} +\end{function} +Numbers are automatically formatted by the \cs{num} macro. This takes one +optional argument, \meta{options}, and one mandatory one, \meta{number}. The +contents of \meta{number} are automatically formatted. The formatter removes +both \enquote{soft} (\verb*| |) and \enquote{hard} spaces (|\,| and |~|), +automatically identifies exponents (as standard marked using |e|, |E|, |d| or +|D|) and adds the appropriate spacing of large numbers. With the standard +settings a leading zero is added before a decimal marker, if needed: both |.| +and "," are recognised as decimal markers. +\begin{LaTeXdemo} + \num{123} \\ + \num{1234} \\ + \num{12345} \\ + \num{0.123} \\ + \num{0,1234} \\ + \num{.12345} \\ + \num{3.45d-4} \\ + \num{-e10} +\end{LaTeXdemo} + +Note that numbers are parsed before typesetting, which does have a performance +overhead (only obvious with very large amounts of numerical input). The parser +understands a range of input syntaxes, as demonstrated above. + +\begin{function}{\numlist} + \begin{syntax} + \cs{numlist}\oarg{options}\marg{numbers} + \end{syntax} +\end{function} +Lists of numbers may be processed using the \cs{numlist} function. Each +\meta{number} is given within the list of \meta{numbers} within a brace pair, +as the list can have a flexible length. +\begin{LaTeXdemo} + \numlist{10;30;50;70} +\end{LaTeXdemo} + +\begin{function}{\numproduct} + \begin{syntax} + \cs{numproduct}\oarg{options}\marg{numbers} + \end{syntax} +\end{function} +Runs of products of numbers may be inserted using the \cs{numproduct} function. +This acts in the same way as \cs{num}, but inserts either a symbol or phrase +between the entries. The latter should be separated by |x| tokens. +\begin{LaTeXdemo} + \numproduct{10 x 30} +\end{LaTeXdemo} + +\begin{function}{\numrange} + \begin{syntax} + \cs{numrange}\oarg{options}\marg{number1}\marg{number2} + \end{syntax} +\end{function} +Simple ranges of numbers can be handled using the \cs{numrange} function. This +acts in the same way as \cs{num}, but inserts a phrase or other text between +the two entries. +\begin{LaTeXdemo} + \numrange{10}{30} +\end{LaTeXdemo} + +\subsection{Angles} + +\begin{function}{\ang} + \begin{syntax} + \cs{ang}\oarg{options}\marg{angle} + \end{syntax} +\end{function} +Angles can be typeset using the \cs{ang} command. The \meta{angle} can be given +either as a decimal number or as a semi-colon separated list of degrees, +minutes and seconds, which is called \enquote{arc format} in this document. The +numbers which make up an angle are processed using the same system as other +numbers. +\begin{LaTeXdemo} + \ang{10} \\ + \ang{12.3} \\ + \ang{4,5} \\ + \ang{1;2;3} \\ + \ang{;;1} \\ + \ang{+10;;} \\ + \ang{-0;1;} +\end{LaTeXdemo} + +\subsection{Units} + +\begin{function}{\unit} + \begin{syntax} + \cs{unit}\oarg{options}\marg{unit} + \end{syntax} +\end{function} +The symbol for a unit can be typeset using the \cs{unit} macro: this provides +full control over output format for the unit. Like the \cs{num} macro, +\cs{unit} takes one optional and one mandatory argument. The unit formatting +system can accept two types of input. When the \meta{unit} contains literal +items (for example letters or numbers) then \pkg{siunitx} converts |.| and |~| +into inter-unit product and correctly positions sub- and superscripts specified +using |_| and |^|. The formatting methods will work with both math and text +mode. +\begin{LaTeXdemo} + \unit{kg.m/s^2} \\ + \unit{g_{polymer}~mol_{cat}.s^{-1}} +\end{LaTeXdemo} + +The second operation mode for the \cs{unit} macro is an \enquote{interpreted} +system, Here, each unit, \acro{SI} multiple prefix and power is given a macro +name. These are entered in a method very similar to the reading of the unit +name in English. +\begin{LaTeXdemo} + \unit{\kilo\gram\metre\per\square\second} \\ + \unit{\gram\per\cubic\centi\metre} \\ + \unit{\square\volt\cubic\lumen\per\farad} \\ + \unit{\metre\squared\per\gray\cubic\lux} \\ + \unit{\henry\second} +\end{LaTeXdemo} + +On its own, this is less convenient than the direct method, although it does +use meaning rather than appearance for input. However, the package allows you +to define new unit macros; a large number of pre-defined abbreviations are also +supplied. More importantly, by defining macros for units, instead of literal +input, new functionality is made available. By altering the settings used by +the package, the same input can yield a variety of different output formats. +For example, the \cs{per} macro can give reciprocal powers, slashes or be used +to construct units as fractions. + +\begin{function}{\qty} + \begin{syntax} + \cs{qty}\oarg{options}\marg{number}\marg{unit} + \end{syntax} +\end{function} +Very often, numbers and units are given together. Formally, the value of a +quantity is the product of the number and the unit, the space being regarded as +a multiplication sign. The \cs{qty} macro combines the +functionality of \cs{num} and \cs{unit}, and makes this both possible and easy. +The \meta{number} and \meta{unit} arguments work exactly like those for the +\cs{num} and \cs{unit} macros, respectively. +\begin{LaTeXdemo} + \qty[mode = text]{1.23}{J.mol^{-1}.K^{-1}} \\ + \qty{.23e7}{\candela} \\ + \qty[per-mode = symbol]{1.99}{\per\kilogram} \\ + \qty[per-mode = fraction]{1,345}{\coulomb\per\mole} +\end{LaTeXdemo} + +It is possible to set up the unit macros to be available outside of the +\cs{qty} and \cs{unit} functions. This is not the standard behaviour as there +is the risk of name clashes (for example, \cs{bar} is used by other packages, +and several packages define \cs{degree}). Full details of using \enquote{stand +alone} units are found in \ref{sec:units:creating}. + +\begin{function}{\qtylist} + \begin{syntax} + \cs{qtylist}\oarg{options}\marg{numbers}\marg{unit} + \end{syntax} +\end{function} +Lists of numbers with units can be handled using the \cs{qtylist} function. The +behaviour of this function is similar to \cs{numlist}, but with the addition of +the unit to each number. +\begin{LaTeXdemo} + \qtylist{10;30;45}{\metre} +\end{LaTeXdemo} + +\begin{function}{\qtyproduct} + \begin{syntax} + \cs{qtyproduct}\oarg{options}\marg{numbers}\marg{unit} + \end{syntax} +\end{function} +Runs of products of of numbers with units can be handled using the +\cs{qtyproduct} function. The behaviour of this function is similar to +\cs{numproduct}, but with the addition of a unit to each number. +\begin{LaTeXdemo} + \qtyproduct{10 x 30 x 45}{\metre} +\end{LaTeXdemo} + +\begin{function}{\qtyrange} + \begin{syntax} + \cs{qtyrange}\oarg{options}\marg{number1}\meta{number2}\marg{unit} + \end{syntax} +\end{function} +Products of numbers with units can be handled using the \cs{qtyrange} +function. The behaviour of this function is similar to \cs{numrange}, but +with the addition of a unit to each number. +\begin{LaTeXdemo} + \qtyrange{10}{30}{\metre} +\end{LaTeXdemo} + +The input of lists, products and ranges of quantities using a single command +allows them to be adjusted together. These commands are intended to allow +consistent formatting of related values: as such, they apply a a single +unit to all of the values. This is particularly notable when using +adjustment of the numerical values. + +\subsection{Complex numbers and quantities} + +\begin{function}{\complexnum} + \begin{syntax} + \cs{complexnum}\oarg{options}\marg{number} + \end{syntax} +\end{function} +Typesets the complex number, which must be given in the form $a + b\mathrm{i}$ +or $a + \mathrm{i}b$. Processing of the numerical parts is otherwise identical +to the standard \cs{num} command. + +\begin{function}{\complexqty} + \begin{syntax} + \cs{complexqty}\oarg{options}\marg{number}\marg{unit} + \end{syntax} +\end{function} +Typesets the complex quantity, which must be given in the form $a + b\mathrm{i}$ +or $a + \mathrm{i}b$. Processing of the numerical parts is otherwise identical +to the standard \cs{qty} command. + +\subsection{The unit macros} + +The package always defines the basic set of \acro{SI} units with macro names. +This includes the base \acro{SI} units, the derived units with special names +and the prefixes. A small number of powers are also given pre-defined names. +Full details of units in the \acro{SI} are available on-line~\cite{BIPM}. + +The seven base \acro{SI} units are always defined (Table~\ref{tab:unit:base}). +In addition, the macro \cs{meter} is available as an alias for \cs{metre}, for +users of US spellings. The full details of the base units are given in the +\acro{SI} Brochure. +\begin{table} + \caption{\acro{SI} base units.% + \label{tab:unit:base}} + \begin{tabular}{@{}lll@{}} + \toprule + Unit & Command & Symbol \\ + \midrule + \DescribeUnit{ampere} \\ + \DescribeUnit{candela} \\ + \DescribeUnit{kelvin} \\ + \DescribeUnit{kilogram} \\ + \DescribeUnit{metre} \\ + \DescribeUnit{mole} \\ + \DescribeUnit{second} \\ + \bottomrule + \end{tabular} +\end{table} + +The \acro{SI} also lists a number of units which have special names and +symbols: these are listed in Table~\ref{tab:unit:derived}. +\begin{table} + \caption{Coherent derived units in the \acro{SI} with special names and + symbols.% + \label{tab:unit:derived}} + \begin{tabular}{@{}lll>{\qquad}lll@{}} + \toprule + Unit & Command & Symbol & Unit & Command & Symbol \\ + \midrule + \DescribeUnit{becquerel} & + \DescribeUnit{newton} \\ + \DescribeUnit[degree Celsius]{degreeCelsius} & + \DescribeUnit{ohm} \\ + \DescribeUnit{coulomb} & + \DescribeUnit{pascal} \\ + \DescribeUnit{farad} & + \DescribeUnit{radian} \\ + \DescribeUnit{gray} & + \DescribeUnit{siemens} \\ + \DescribeUnit{hertz} & + \DescribeUnit{sievert} \\ + \DescribeUnit{henry} & + \DescribeUnit{steradian} \\ + \DescribeUnit{joule} & + \DescribeUnit{tesla} \\ + \DescribeUnit{lumen} & + \DescribeUnit{volt} \\ + \DescribeUnit{katal} & + \DescribeUnit{watt} \\ + \DescribeUnit{lux} & + \DescribeUnit{weber} \\ + \bottomrule + \end{tabular} +\end{table} + +In addition to the official \acro{SI} units, \pkg{siunitx} also provides macros +for a number of units which are accepted for use in the \acro{SI} although they +are not \acro{SI} units. Table~\ref{tab:unit:accepted} lists the +\enquote{accepted} units. The command \cs{percent} is also provided for use in +units: this is accepted with the \acro{SI} as detailed in Section~5.3.7 of the +Brochure. +\begin{table} + \caption{Non-\acro{SI} units accepted for use with the International System of + Units.% + \label{tab:unit:accepted}} + \begin{tabular}{@{}lll@{}} + \toprule + Unit & Command & Symbol \\ + \midrule + \DescribeUnit{astronomicalunit} \\ + \DescribeUnit{bel} \\ + \DescribeUnit{dalton} \\ + \DescribeUnit{day} \\ + \DescribeUnit{decibel} \\ + \DescribeUnit{degree} \\ + \DescribeUnit{electronvolt} \\ + \DescribeUnit{hectare} \\ + \DescribeUnit{hour} \\ + \DescribeUnit{litre} \\ + & \cs{liter} & \unit{\liter} \\ + \DescribeUnit[minute (plane angle)]{arcminute} \\ + \DescribeUnit[minute (time)]{minute} \\ + \DescribeUnit[second (plane angle)]{arcsecond} \\ + \DescribeUnit{neper} \\ + \DescribeUnit{tonne} \\ + \bottomrule + \end{tabular} +\end{table} + +In addition to the units themselves, \pkg{siunitx} provides pre-defined macros +for all of the \acro{SI} prefixes (Table~\ref{tab:unit:prefix}). +The spelling \enquote{\cs{deka}} is provided for US users as an alternative to +\cs{deca}. +\begin{table} + \caption{SI prefixes.% + \label{tab:unit:prefix}} + \sisetup{table-number-alignment = right, table-format = 2} + \begin{tabular}{@{}llcS[table-format = -2]>{\qquad}llcS@{}} + \toprule + Prefix & Command & Symbol & \multicolumn{1}{l}{Power} & + Prefix & Command & Symbol & \multicolumn{1}{l@{}}{Power} \\ + \midrule + \DescribePrefix{yocto} & -24 & + \DescribePrefix{deca} & 1 \\ + \DescribePrefix{zepto} & -21 & + \DescribePrefix{hecto} & 2 \\ + \DescribePrefix{atto} & -18 & + \DescribePrefix{kilo} & 3 \\ + \DescribePrefix{femto} & -15 & + \DescribePrefix{mega} & 6 \\ + \DescribePrefix{pico} & -12 & + \DescribePrefix{giga} & 9 \\ + \DescribePrefix{nano} & -9 & + \DescribePrefix{tera} & 12 \\ + \DescribePrefix{micro} & -6 & + \DescribePrefix{peta} & 15 \\ + \DescribePrefix{milli} & -3 & + \DescribePrefix{exa} & 18 \\ + \DescribePrefix{centi} & -2 & + \DescribePrefix{zetta} & 21 \\ + \DescribePrefix{deci} & -1 & + \DescribePrefix{yotta} & 24 \\ + \bottomrule + \end{tabular} +\end{table} + +A small number of pre-defined powers are provided as macros. \cs{square} and +\cs{cubic} are intended for use before units, with \cs{squared} and \cs{cubed} +going after the unit. +\begin{LaTeXdemo} + \unit{\square\becquerel} \\ + \unit{\joule\squared\per\lumen} \\ + \unit{\cubic\lux\volt\tesla\cubed} +\end{LaTeXdemo} +Generic powers can be inserted on a one-off basis using the \cs{tothe} and +\cs{raiseto} macros. These are the only macros for units which take an +argument: +\begin{LaTeXdemo} + \unit{\henry\tothe{5}} \\ + \unit{\raiseto{4.5}\radian} +\end{LaTeXdemo} +Reciprocal powers are indicated using the \cs{per} macro. This applies to the +next unit only, unless the \opt{sticky-per} option is turned on. +\begin{LaTeXdemo} + \unit{\joule\per\mole\per\kelvin} \\ + \unit{\joule\per\mole\kelvin} \\ + \unit{\per\henry\tothe{5}} \\ + \unit{\per\square\becquerel} +\end{LaTeXdemo} +As for generic powers, generic qualifiers are also available using the \cs{of} +function: +\begin{LaTeXdemo} + \unit{\kilogram\of{metal}} \\ + \qty[qualifier-mode = bracket] + {0.1}{\milli\mole\of{cat}\per\kilogram\of{prod}} +\end{LaTeXdemo} + +When the \pkg{cancel} package is loaded, it is possible to \enquote{cancel out} +units using the \cs{cancel} macro. This applies to the next unit, in a similar +manner to a prefix. The \cs{highlight} macro is also available to selectively +color units. Both \cs{cancel} and \cs{highlight} are outside of the normal +semantic meaning of units, but are provided as they may be useful in some +cases. +\begin{LaTeXdemo} + \unit[per-mode = fraction] + {\cancel\kilogram\metre\per\cancel\kilogram\per\second} \\ + \unit{\highlight{red}\kilogram\metre\per\second} \\ + \unit[unit-color = purple] + {\highlight{blue}\kilogram\metre\per\second} +\end{LaTeXdemo} + +\subsection{Unit abbreviations} + +In addition to the \enquote{full} names, \pkg{siunitx} loads a set of +abbreviated versions of the \acro{SI} units (Table~\ref{tab:unit:abbr}). The +standard \pkg{siunitx} settings only create these abbreviations within the +scope of the \cs{unit} and \cs{qty} functions, meaning that no clashes should +occur (for example with the standard \cs{pm} symbol). +\begin{center} + \label{tab:unit:abbr} + \tablefirsthead{% + \toprule + \multicolumn{1}{@{}l}{Unit} & + \multicolumn{1}{l}{Abbreviation} & + \multicolumn{1}{l@{}}{Symbol} \\ + \midrule + } + \tablehead{% + \multicolumn{3}{@{}l@{}}{\emph{Continued from previous page}} \\ + \toprule + \multicolumn{1}{@{}l}{Unit} & + \multicolumn{1}{l}{Abbreviation} & + \multicolumn{1}{l@{}}{Symbol} \\ + \midrule + } + \tabletail{% + \bottomrule + \multicolumn{3}{@{}r@{}}{\emph{Continued on next page}} \\ + } + \tablelasttail{\bottomrule} + \begin{xtabular}{@{}lcc@{}} + \DescribeUnit[femtogram]{fg} \\ + \DescribeUnit[picogram]{pg} \\ + \DescribeUnit[nanogram]{ng} \\ + \DescribeUnit[microgram]{ug} \\ + \DescribeUnit[milligram]{mg} \\ + \DescribeUnit[gram]{g} \\ + \DescribeUnit[kilogram]{kg} \\ + + \midrule + + \DescribeUnit[picometre]{pm} \\ + \DescribeUnit[nanometre]{nm} \\ + \DescribeUnit[micrometre]{um} \\ + \DescribeUnit[millimetre]{mm} \\ + \DescribeUnit[centimetre]{cm} \\ + \DescribeUnit[decimetre]{dm} \\ + \DescribeUnit[metre]{m} \\ + \DescribeUnit[kilometre]{km} \\ + + \midrule + + \DescribeUnit[attosecond]{as} \\ + \DescribeUnit[femtosecond]{fs} \\ + \DescribeUnit[picosecond]{ps} \\ + \DescribeUnit[nanosecond]{ns} \\ + \DescribeUnit[microsecond]{us} \\ + \DescribeUnit[millisecond]{ms} \\ + \DescribeUnit[second]{s} \\ + + \midrule + + \DescribeUnit[femtomole]{fmol} \\ + \DescribeUnit[picomole]{pmol} \\ + \DescribeUnit[nanomole]{nmol} \\ + \DescribeUnit[micromole]{umol} \\ + \DescribeUnit[millimole]{mmol} \\ + \DescribeUnit[mole]{mol} \\ + \DescribeUnit[kilomole]{kmol} \\ + + \midrule + + \DescribeUnit[picoampere]{pA} \\ + \DescribeUnit[nanoampere]{nA} \\ + \DescribeUnit[microampere]{uA} \\ + \DescribeUnit[milliampere]{mA} \\ + \DescribeUnit[ampere]{A} \\ + \DescribeUnit[kiloampere]{kA} \\ + + \midrule + + \DescribeUnit[microlitre]{ul} \\ + \DescribeUnit[millilitre]{ml} \\ + \DescribeUnit[litre]{l} \\ + \DescribeUnit[hectolitre]{hl} \\ + \DescribeUnit[microliter]{uL} \\ + \DescribeUnit[milliliter]{mL} \\ + \DescribeUnit[liter]{L} \\ + \DescribeUnit[hectoliter]{hL} \\ + + \midrule + + \DescribeUnit[millihertz]{mHz} \\ + \DescribeUnit[hertz]{Hz} \\ + \DescribeUnit[kilohertz]{kHz} \\ + \DescribeUnit[megahertz]{MHz} \\ + \DescribeUnit[gigahertz]{GHz} \\ + \DescribeUnit[terahertz]{THz} \\ + + \midrule + + \DescribeUnit[millinewton]{mN} \\ + \DescribeUnit[newton]{N} \\ + \DescribeUnit[kilonewton]{kN} \\ + \DescribeUnit[meganewton]{MN} \\ + + \midrule + + \DescribeUnit[pascal]{Pa} \\ + \DescribeUnit[kilopascal]{kPa} \\ + \DescribeUnit[megapacal]{MPa} \\ + \DescribeUnit[gigapascal]{GPa} \\ + + \midrule + + \DescribeUnit[milliohm]{mohm} \\ + \DescribeUnit[kilohm]{kohm} \\ + \DescribeUnit[megohm]{Mohm} \\ + + \midrule + + \DescribeUnit[picovolt]{pV} \\ + \DescribeUnit[nanovolt]{nV} \\ + \DescribeUnit[microvolt]{uV} \\ + \DescribeUnit[millivolt]{mV} \\ + \DescribeUnit[volt]{V} \\ + \DescribeUnit[kilovolt]{kV} \\ + + \midrule + + \DescribeUnit[watt]{W} \\ + \DescribeUnit[microwatt]{uW} \\ + \DescribeUnit[milliwatt]{mW} \\ + \DescribeUnit[kilowatt]{kW} \\ + \DescribeUnit[megawatt]{MW} \\ + \DescribeUnit[gigawatt]{GW} \\ + \DescribeUnit[joule]{J} \\ + \DescribeUnit[microjoule]{uJ} \\ + \DescribeUnit[millijoule]{mJ} \\ + \DescribeUnit[kilojoule]{kJ} \\ + \DescribeUnit[electronvolt]{eV} \\ + \DescribeUnit[millielectronvolt]{meV} \\ + \DescribeUnit[kiloelectronvolt]{keV} \\ + \DescribeUnit[megaelectronvolt]{MeV} \\ + \DescribeUnit[gigaelectronvolt]{GeV} \\ + \DescribeUnit[teraelectronvolt]{TeV} \\ + \DescribeUnit[kilowatt hour]{kWh} \\ + + \midrule + + \DescribeUnit[farad]{F} \\ + \DescribeUnit[femtofarad]{fF} \\ + \DescribeUnit[picofarad]{pF} \\ + \DescribeUnit[nanofarad]{nF} \\ + \DescribeUnit[microfarad]{uF} \\ + + \midrule + + \DescribeUnit[henry]{H} \\ + \DescribeUnit[millihenry]{mH} \\ + \DescribeUnit[microhenry]{uH} \\ + + \midrule + + \DescribeUnit[kelvin]{K} \\ + + \midrule + + \DescribeUnit[decibel]{dB} \\ + + \end{xtabular} +\end{center} + +\DescribeMacro{bit} +\DescribeMacro{byte} +Binary data is expressed in units of bits and bytes. These are normally given +prefixes which use powers of two, rather than the powers of ten used by the +\acro{SI} prefixes. As these binary prefixes are closely related to the +\acro{SI} prefixes, they are defined by \pkg{siunitx}. +\begin{table} + \caption{Binary prefixes.% + \label{tab:unit:binary}} + \sisetup{table-number-alignment = right, table-format = 2} + \begin{tabular}{@{}llcS@{}} + \toprule + Prefix & Command & Symbol & \multicolumn{1}{l@{}}{Power} \\ \\ + \midrule + \DescribePrefix{kibi} & 10 \\ + \DescribePrefix{mebi} & 20 \\ + \DescribePrefix{gibi} & 30 \\ + \DescribePrefix{tebi} & 40 \\ + \DescribePrefix{pebi} & 50 \\ + \DescribePrefix{exbi} & 60 \\ + \DescribePrefix{zebi} & 70 \\ + \DescribePrefix{yobi} & 80 \\ + \bottomrule + \end{tabular} +\end{table} + +\subsection{Creating new macros} + +The various macro components of a unit have to be defined before they can be +used. The package supplies a number of common definitions, but new definitions +are also possible. As the definition of a logical unit should remain the same +in a single document, these creation functions are all preamble-only. + +\begin{function}{\DeclareSIUnit} + \begin{syntax} + \cs{DeclareSIUnit}\oarg{options}\marg{unit}\marg{symbol} + \end{syntax} +\end{function} +New units are produced using the \cs{DeclareSIUnit} macro. The \meta{symbol} +can contain literal input, other units, multiple prefixes, powers and \cs{per}, +although literal text should not be intermixed with unit macros. Units can be +created with \meta{options} from the usual list understood by \pkg{siunitx}, +and apply the specific unit macro only. The (first) optional argument to +\cs{qty} and \cs{unit} can be used to override the settings for the unit: an +example is the \cs{degree} unit. +\begin{LaTeXdemo} + \qty{3.1415}{\degree} +\end{LaTeXdemo} + This is declared in the package (effectively) as +\begin{LaTeXdemo}[code only] + \DeclareSIUnit[quantity-product = {}] + \degree{\text{\textdegree}} +\end{LaTeXdemo} + The spacing can still be altered at point of use: +\begin{LaTeXdemo} + \qty{67890}{\degree} \\ + \qty[quantity-product = \,]{67890}{\degree} +\end{LaTeXdemo} +The meaning of a pre-defined unit can be altered by using \cs{DeclareSIUnit} +after loading \pkg{siunitx}. This will overwrite the original definition with +the newer version. + +\begin{function}{\DeclareSIPrefix} + \begin{syntax} + \cs{DeclareSIPrefix}\marg{prefix}\marg{symbol}\marg{powers-ten} + \end{syntax} +\end{function} +The standard \acro{SI} powers of ten are defined by the package, and are +described above. However, the user can define new prefixes with +\cs{DeclareSIPrefix}. For example, \cs{kilo} is defined +\begin{LaTeXdemo}[code only] + \DeclareSIPrefix\kilo{k}{3} +\end{LaTeXdemo} + +\begin{function}{\DeclareSIPower} + \begin{syntax} + \cs{DeclareSIPower}\marg{symbol-before}\marg{symbol-after}\marg{power} + \end{syntax} +\end{function} +This function creates two symbols, one for use before a unit, the second +for use after a unit, both of which are equivalent to the \meta{power}. +For example, one might use +\begin{LaTeXdemo}[code only] + \DeclareSIPower\quartic\tothefourth{4} +\end{LaTeXdemo} + with the functions then used in the document as +\begin{LaTeXdemo} + \unit{\kilogram\tothefourth}\\ + \unit{\quartic\metre} +\end{LaTeXdemo} + +\begin{function}{\DeclareSIQualifier} + \begin{syntax} + \cs{DeclareSIQualifier}\marg{qualifier}\marg{symbol} + \end{syntax} +\end{function} +Following the syntax of the other macros, qualifiers may be created using the +\cs{DeclareSIQualifier} command. In contrast to the other parts of a unit, +there are no pre-defined qualifiers. It is therefore entirely up to the user to +create these. For example, to identify the mass of a product created when using +a particular catalyst, the preamble could contain: +\begin{LaTeXdemo}[code only] + \DeclareSIQualifier\polymer{pol} + \DeclareSIQualifier\catalyst{cat} +\end{LaTeXdemo} + and then in the body the document could read +\begin{LaTeXdemo} + \qty{1.234}{\gram\polymer\per\mole\catalyst\per\hour} +\end{LaTeXdemo} + +\subsection{Tabular material} + +Aligning numbers in tabular content is handled by a new column type, the +\texttt{S} column. This new column type can align material using a number of +different strategies, with the aim of flexibility of output without needing to +alter the input. The method used as standard is to place the decimal marker in +the number at the centre of the cell and to align the material appropriately +(Table~\ref{tab:S:standard}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Standard behaviour of the \texttt{S} column type.% + \label{tab:S:standard}} + \begin{tabular}{@{}S@{}} + \toprule + {Some Values} \\ + \midrule + 2.3456 \\ + 34.2345 \\ + -6.7835 \\ + 90.473 \\ + 5642.5 \\ + 1.2e3 \\ + e4 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +The \texttt{S} column will attempt to automatically detect material which +should be placed before or after a number, and will maintain the alignment of +the numerical data (Table~\ref{tab:S:extras}). If the material could be +mistaken for part of a number, it should be protected by braces. The use of +\cs{color} in a table cell will also be detected and will override any general +color applied by \pkg{siunitx}. +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Detection of surrounding material in an \texttt{S} column.% + \label{tab:S:extras}} + \begin{tabular}{@{}S[color = orange]@{}} + \toprule + {Some Values} \\ + \midrule + 12.34 \\ + \color{purple} 975,31 \\ + 44.268 \textsuperscript{\emph{a}} \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\begin{function}{\tablenum} + \begin{syntax} + \cs{tablenum}\oarg{options}\marg{number} + \end{syntax} +\end{function} +Within more complex tables, aligned numbers may be desirable within the +argument of \cs{multicolumn} or \cs{multirow}.\footnote{Provided by the +\pkg{multirow} package} The \cs{tablenum} function is available to achieve +alignment in these situations: this is, in effect, a macro version of the +\texttt{S} column (Table~\ref{tab:tablenum}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Controlling complex alignment with the \cs{tablenum} macro.% + \label{tab:tablenum}} + \begin{tabular}{@{}lr@{}} + \toprule + Heading & Heading \\ + \midrule + Info & More info \\ + Info & More info \\ + \multicolumn{2}{c}{\tablenum[table-format = 4.4]{12,34}} \\ + \multicolumn{2}{c}{\tablenum[table-format = 4.4]{333.5567}} \\ + \multicolumn{2}{c}{\tablenum[table-format = 4.4]{4563.21}} \\ + \bottomrule + \end{tabular} + \hfil + \begin{tabular}{@{}lr@{}} + \toprule + Heading & Heading \\ + \midrule + \multirow{2}*{\tablenum{88,999}} & aaa \\ + & bbb \\ + \multirow{2}*{\tablenum{33,435}} & ccc \\ + & ddd \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\section{Package control options} + +\subsection{The key--value control system} + + The package uses a range of different key types: +\begin{description} + \item[\texttt{Choice}] Takes a limited number of choices, which are described + separately for each key. + \item[\texttt{Integer}] Requires a number as the argument. + \item[\texttt{Length}] Requires a length, either as a literal + value such as \texttt{2.0cm}, or stored as a \LaTeX{} length. + \item[\texttt{Literal}] A key which uses the value(s) given directly, + either to check input or in output. + \item[\texttt{Macro}] Requires a macro, which may need a single argument. + \item[\texttt{Math}] Similar to a \texttt{literal} option, but the input is + always used in math mode, irrespective of other \pkg{siunitx} settings. + Thus to text-mode only input must be placed inside the argument of a + \cs{text} macro. + \item[\texttt{Meta}] These are options which actually apply a number of + other options. + \item[\texttt{Switch}] These are on--off switches, and recognise \opt{true} + and \opt{false}. Giving just the key name also turns the key on. +\end{description} +The tables of option names use these descriptions to indicate how the keys +should be used. + +\subsection{Printing% + \label{sec:print}} + +The \pkg{siunitx} package can control the font used to print output +independently of the surrounding material. Which aspects of the font follow +those of the surroundings is influenced by a range of setting as detailed in +Table~\ref{tab:opt:print}. +\begin{table} + \caption{Print options.% + \label{tab:opt:print}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{@{}l}{Option name} & + Type & + \multicolumn{1}{l@{}}{Default} \\ + \midrule + color & Literal & \meta{none} \\ + mode & Choice & math \\ + number-color & Literal & \meta{none} \\ + number-mode & Choice & math \\ + propagate-math-font & Switch & false \\ + reset-math-version & Switch & true \\ + reset-text-family & Switch & true \\ + reset-text-series & Switch & true \\ + reset-text-shape & Switch & true \\ + text-family-to-math & Switch & false \\ + text-font-command & Literal & \meta{none} \\ + text-series-to-math & Switch & false \\ + unit-color & Literal & \meta{none} \\ + unit-mode & Choice & math \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{mode} +\DescribeOption{number-mode} +\DescribeOption{unit-mode} +The \opt{mode} option determines whether \pkg{siunitx} uses math or text mode +when printing output. The choices are \opt{match}, \opt{math}, \opt{text}. The +\opt{match} setting means that printing uses the prevailing mode unchanged +whereas \opt{math} and \opt{text} select the appropriate \TeX{} mode. It is +possible to have different fonts in math and text modes, which will highlight +the difference. The font settings which apply are also different depending on +the mode. As well as the overall setting, it is possible to apply mode +to numbers and units separately using the \opt{number-mode} and \opt{unit-mode} +options. + +\DescribeOption{reset-text-family} +\DescribeOption{reset-text-series} +\DescribeOption{reset-text-shape} +When printing in text mode, the options \opt{reset-text-family}, +\opt{reset-text-series} and \opt{reset-text-shape} apply. When these are +active, \pkg{siunitx} resets the relevant font selection axis property +when printing: the standard font setting is upright mid-weight roman +(|\upshape| |\mdseries| |\rmfamily|). +\begin{LaTeXdemo} + \sisetup{mode = text} + {\itshape \num{1234}}\\ + {\bfseries \num{1234}}\\ + {\sffamily \num{1234}}\\ + \sisetup{ + reset-text-family = false , + reset-text-series = false , + reset-text-shape = false + } + {\itshape \num{1234}}\\ + {\bfseries \num{1234}}\\ + {\sffamily \num{1234}}\\ +\end{LaTeXdemo} + +\DescribeOption{propagate-math-font} +\DescribeOption{reset-math-version} +In math mode, the font used by \LaTeX{} is \enquote{invariant}, and this is +reflected in the options available. With the standard settings, in math mode +printing uses the standard math font and version (weight). The option +\opt{propagate-math-font} may be used to apply the a prevailing math font +to the printed material. The setting \opt{reset-math-version} controls +whether the math version is reset or not. Note that math version is typically +used to set \enquote{bold math} but may also be used for other effects, for +example all sanserif math. +\begin{LaTeXdemo} + {\boldmath \unit{\kilogram}}\\ + {\sansmath $\unit{\kilogram}$}\\ + {$\mathsf{\unit{\kilogram}}$}\\ + \sisetup{ + propagate-math-font = true , + reset-math-version = false + } + {\boldmath \unit{\kilogram}}\\ + {\sansmath $\unit{\kilogram}$}\\ + {$\mathsf{\unit{\kilogram}}$} +\end{LaTeXdemo} + +\DescribeOption{text-family-to-math} +\DescribeOption{text-series-to-math} +The options \opt{text-family-to-math} and \opt{text-family-to-math} can be +used to match (as far as possible) math mode output to the surrounding text. +These options work by detecting the current text settings and making the +appropriate choice in math mode. +\begin{LaTeXdemo} + {\sffamily \unit{\kilogram}}\\ + {\bfseries $\unit{\kilogram}$}\\ + \sisetup{ + text-family-to-math = true , + text-series-to-math = true + } + {\sffamily \unit{\kilogram}}\\ + {\bfseries $\unit{\kilogram}$} +\end{LaTeXdemo} + +\DescribeOption{text-font-command} +In some circumstances, it may be desirable to use a non-standard font command +when printing in text mode. This might be used for example to switch from +old-style to lining numbers whilst still using text mode. This may be achieved +by setting \opt{text-font-command}. For example, this document uses old-style +numbers in text mode as-standard, which can be over-ridden by selecting the +font variant which does not feature them. +\begin{LaTeXdemo} + \sisetup{number-mode = text} + \qty{123456789}{\kilo\volt\per\centi\metre} \\ + \sisetup{text-font-command = \fontfamily{pplx}\selectfont} + \qty{123456789}{\kilo\volt\per\centi\metre} +\end{LaTeXdemo} + +\DescribeOption{color} +\DescribeOption{number-color} +\DescribeOption{unit-color} +The color of printed output can be set using the \opt{color} option. When no +color is given, printing follows the surrounding text. In contrast, when a +specific color is given, it is used irrespective of the surroundings. As with +\opt{mode}, the \opt{color} setting may also be applied to numbers and units +independently. +\begin{LaTeXdemo} + \color{red}% + Some text \\ + \qty{4}{\kilogram} \\ + More text \\ + \qty[color = blue]{4}{\kilogram} \\ + Still red here! +\end{LaTeXdemo} + +\subsection{Parsing numbers} + +The package uses a sophisticated parsing system to understand numbers. This +allows \pkg{siunitx} to carry out a range of formatting, as described later. +All of the input options take lists of literal tokens, and are summarised in +Table~\ref{tab:opt:num:in}. +\begin{table} + \caption{Options for number parsing.% + \label{tab:opt:num:in}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{@{}l}{Option name} & + Type & + \multicolumn{1}{l@{}}{Default} \\ + \midrule + evaluate-expression & Switch & false \\ + expression & Literal & |#1| \\^^A ( + input-close-uncertainty & Literal & ) \\ + input-comparators & Literal & + <=>\cs{approx}\cs{ge}\cs{geq} \\ + & & \cs{gg}\cs{le}\cs{leq}\cs{ll} \cs{sim} \\ + input-decimal-markers & Literal & ., \\ + input-digits & Literal & 0123456789 \\ + input-exponent-markers & Literal & dDeE \\ + input-ignore & Literal & \meta{none} \\ + input-open-uncertainty & Literal & ( \\ ^^A ) + input-signs & Literal & +-\cs{pm}\cs{mp} \\ + input-uncertainty-signs & Literal & \cs{pm} \\ + parse-numbers & Switch & true \\ + retain-explicit-plus & Switch & false \\ + retain-zero-uncertainty & Switch & false \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{input-digits} +\DescribeOption{input-decimal-markers} +\DescribeOption{input-signs} +\DescribeOption{input-exponent-markers} +The basic parts of a number are the digits, any sign and a separator between +the integer and decimal parts. These are stored in the input options +\opt{input-digits}, \opt{input-decimal-markers} and \opt{input-signs}, +respectively. More than one input decimal marker can be used: it will be +converted by the package to the appropriate output marker. Numbers which +include an exponent part also require a marker for the exponent: this again is +taken from the range of tokens in the \opt{input-exponent-markers} option. + +\DescribeOption{input-ignore} +Tokens given in the \opt{input-ignore} list are totally passed over by +\pkg{siunitx}: they will be removed from the input with no further processing. + +\DescribeOption{input-comparators} +In addition to signs, \pkg{siunitx} can recognise comparators, such as |<|. The +package will automatically carry out conversions for |<<|, |>>|, |<=| and |>=| +to |\ll|, |\gg|, |\le| and |\ge|, respectively. +\begin{LaTeXdemo} + \num{< 10} \\ + \qty{>> 5}{\metre} \\ + \num{\le 0.12} +\end{LaTeXdemo} + +\DescribeOption{input-open-uncertainty} +\DescribeOption{input-close-uncertainty} +\DescribeOption{input-uncertainty-signs} +In some fields, it is common to give the uncertainty in a number in brackets +after the main part of the number, for example \enquote{\num{1.234(5)}}. The +opening and closing symbols used for this type of input are set as +\opt{input-open-uncertainty} and \opt{input-close-uncertainty}. Alternatively, +the uncertainty may be given as a separate part following a sign. Which signs +are valid for this operation is determined by the \opt{input-uncertainty-signs} +option. As with other signs, the combination |+-| will automatically be +converted to |\pm| internally. +\begin{LaTeXdemo} + \num{9.99(9)} \\ + \num{9.99 +- 0.09} \\ + \num{9.99 \pm 0.09} \\ + \num{123 +- 4.5} \\ + \num{12.3 +- 6} +\end{LaTeXdemo} + +Uncertainties which cross the decimal marker may be given with or without a +decimal marker in \enquote{compact} form. These are treated as equivalent by +the code.\footnote{The package author favors the form without a decimal marker, +and formal guidance is ambiguous on which is correct. The form with a decimal +marker is seen in for example some \acro{NIST} publications.} +\begin{LaTeXdemo} + \num{123.4(12)} \\ + \num{123.4(1.2)} +\end{LaTeXdemo} + +\DescribeOption{parse-numbers} +The \opt{parse-numbers} option turns the entire parsing system on and off. The +option is made available for two reasons. First, if all of the numbers in a +document are to be reproduced \enquote{as given}, turning off the parser will +represent a significant saving in processing required. Second, it allows the +use of arbitrary \TeX{} code in numbers. If the parser is turned off, the input +will be printed in math mode (requiring |\text| to protect any text in the +number). +\begin{LaTeXdemo} + \num[parse-numbers = false]{\sqrt{2}} \\ + \qty[parse-numbers = false]{\sqrt{3}}{\metre} +\end{LaTeXdemo} + +\DescribeOption{evaluate-expression} +\DescribeOption{expression} +With the standard settings, numerical input is parsed \enquote{as is} with no +attempt to interpret it mathematically. By enabling the +\opt{evaluate-expression} option, the input can be processed by the standard +\LaTeX3 \acro{FPU} (see package \pkg{xfp} for more). The nature of the +expression itself can be adjusted using the \opt{expression} setting: as +standard, the entire input is simply parsed with no change, but this setting +may be used to add additional steps. The \emph{input} in such an expression is +represented by |#1|. Note that the \acro{FPU} uses its own syntax for numbers, +most notably in that a decimal marker must be |.|. +\begin{LaTeXdemo} + \sisetup{evaluate-expression}% + \qty{2 + 4 * 3}{\joule} \\ + \qty[expression = 10 * (#1)]{2 + 4 * 3}{\joule} +\end{LaTeXdemo} + +\DescribeOption{retain-explicit-plus} +\DescribeOption{retain-zero-uncertainty} +The inclusion of a leading plus sign is usually unnecessary for positive +numbers, and so they are not retained as-standard when parsing. The +\opt{retain-explicit-plus} option is available to control this behaviour. +Similarly, an uncertainty of zero is normally not meaningful, and so is +ignored by the parser. This can be controlled using the +\opt{retain-zero-uncertainty} option. +\begin{LaTeXdemo} + \num{+345} \\ + \num[retain-explicit-plus]{+345} \\ + \num{12.3(0)} \\ + \num[retain-zero-uncertainty]{12.3(0)} +\end{LaTeXdemo} + +\subsection{Post-processing numbers} + +Before typesetting numbers, various post-processing steps can be carried out. +These involve adding or removing information from the number in a systematic +way; the options are summarised in Table~\ref{tab:opt:num:post}. +\begin{table} + \caption{Number post-processing options.% + \label{tab:opt:num:post}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{@{}l}{Option name} & + Type & + \multicolumn{1}{l@{}}{Default} \\ + \midrule + drop-exponent & Switch & false \\ + drop-uncertainty & Switch & false \\ + drop-zero-decimal & Switch & false \\ + exponent-mode & Switch & input \\ + fixed-exponent & Integer & 0 \\ + minimum-integer-digits & Integer & 0 \\ + minimum-decimal-digits & Integer & 0 \\ + round-half & Choice & up \\ + round-minimum & Literal & 0 \\ + round-mode & Choice & none \\ + round-pad & Switch & true \\ + round-precision & Integer & 2 \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{exponent-mode} +\DescribeOption{fixed-exponent} +Numbers can be converted to scientific notation by the package. This is +controlled by the \opt{exponent-mode} option, which takes choices \opt{input}, +\opt{fixed}, \opt{engineering} and \opt{scientific}. The \opt{fixed} setting +will use the exponent value by the \opt{fixed-exponent} option. When +\opt{engineering} is set, the exponent is always a power of three. +\begin{LaTeXdemo} + \num{0.001} \\ + \num{0.0100} \\ + \num{1200} \\ + \sisetup{exponent-mode = scientific}% + \num{0.001} \\ + \num{0.0100} \\ + \num{1200} \\ + \sisetup{exponent-mode = engineering}% + \num{0.001} \\ + \num{0.0100} \\ + \num{1200} \\ + \sisetup{ + exponent-mode = fixed, + fixed-exponent = 2, + }% + \num{0.001} \\ + \num{0.0100} \\ + \num{1200} +\end{LaTeXdemo} +When used with a \opt{fixed-exponent} of zero, this may be used to remove +scientific notation from the input +\begin{LaTeXdemo} + \num{1.23e4} \\ + \num[exponent-mode = fixed, fixed-exponent = 0]{1.23e4} +\end{LaTeXdemo} +Exponent mode applies \emph{after} rounding, such that the number of decimal +places for rounding is those which appear in the output. + +\DescribeOption{drop-exponent} +\DescribeOption{drop-uncertainty} +The use of an uncertainty can be suppressed entirely using the +\opt{drop-uncertainty} option: this applies \emph{before} rounding is +attempted. Similarly, exponents can be dropped using \opt{drop-exponent} can be +used to suppress the exponent part (\emph{after} conversion to a fixed +exponent). +\begin{LaTeXdemo} + \num{0.01(2)} \\ + \num[drop-uncertainty]{0.01(2)} \\ + \num{0.01e3} \\ + \num[drop-exponent]{0.01e3} +\end{LaTeXdemo} + +\DescribeOption{round-mode} +\DescribeOption{round-precision} +\DescribeOption{round-pad} +The package can round numerical input to a fixed number of significant figures +or decimal places. This is controlled by the \opt{round-mode} option, which +takes the choices \opt{none}, \opt{figures}, \opt{places} and +\opt{uncertainty}. When rounding is turned on, the number of digits used +(either decimal places or significant figures in the mantissa) is set using the +\opt{round-precision} option. Rounding numbers with uncertainties may be +carried out using the \opt{uncertainty} setting to \opt{round-mode}. In this +case the precision is used first to round the uncertainty itself (to a number +of figures), before rounding the main value to follow. +\begin{LaTeXdemo} + \num{1.23456} \\ + \num{14.23} \\ + \num{0.12345(9)} \\ + \sisetup{ + round-mode = places, + round-precision = 3 + }% + \num{1.23456} \\ + \num{14.23} \\ + \num{0.12345(9)} \\ + \sisetup{ + round-mode = figures, + round-precision = 3 + }% + \num{1.23456} \\ + \num{14.23} \\ + \num{0.12345(9)} \\ + \sisetup{ + round-mode = uncertainty, + round-precision = 1 + }% + \num{0.12345(9)} \\ + \num{0.12345(23)} \\ + \num{0.12345(234)} +\end{LaTeXdemo} +Rounding my \enquote{extend} a short number to more digits (or figures): this +is controlled by the switch \opt{round-pad}, which is \opt{true} as standard. +\begin{LaTeXdemo} + \sisetup{round-mode = figures, round-precision = 4}% + \num{12.3} \\ + \num[round-pad = false]{12.3} +\end{LaTeXdemo} + +\DescribeOption{round-half} +In cases where the rounded part of a number is exactly half, there are two +common methods for \enquote{breaking the tie}. The choice of method is +determined by the option \opt{round-half}, which recognises the choices +\opt{up} and \opt{even}. +\begin{LaTeXdemo} + \sisetup{ + round-mode = figures, + round-precision = 1, + round-half = up + }% + \num{0.055} \\ + \num{0.045} \\ + \sisetup{round-half = even}% + \num{0.055} \\ + \num{0.045} +\end{LaTeXdemo} + +\DescribeOption{round-minimum} +There are cases in which rounding will result in the number reaching zero. It +may be desirable to show such results as below a threshold value. This can be +achieved by setting \opt{round-minimum} to the threshold value. There will be +no effect when rounding to a number of significant figures as it is not +possible to obtain the value zero in these cases. +\begin{LaTeXdemo} + \sisetup{round-mode = places}% + \num{0.0055} \\ + \num{0.0045} \\ + \sisetup{round-minimum = 0.01}% + \num{0.0055} \\ + \num{0.0045} +\end{LaTeXdemo} + +\DescribeOption{drop-zero-decimal} +It may be desirable to convert decimals to integers when the decimal part is +zero. This is set up using the \opt{drop-zero-decimal} option, which applies +after rounding but before setting minimum numbers of digits. +\begin{LaTeXdemo} + \num{2.0} \\ + \num{2.1} \\ + \sisetup{drop-zero-decimal}% + \num{2.0} \\ + \num{2.1} +\end{LaTeXdemo} + +\DescribeOption{minimum-decimal-digits} +\DescribeOption{minimum-integer-digits} +The \opt{minimum-decimal-digits} and \opt{minimum-integer-digits} option may be +used to pad numbers to a given size. This applies independent of any rounding. +\begin{LaTeXdemo} + \num{123} \\ + \num[minimum-integer-digits = 2]{123} \\ + \num[minimum-integer-digits = 4]{123} \\ + \num{0.123} \\ + \num[minimum-decimal-digits = 2]{0.123} \\ + \num[minimum-decimal-digits = 4]{0.123} \\ +\end{LaTeXdemo} + +\subsection{Printing numbers} + +Actually printing numbers is controlled by a number of settings, which apply +ideas such as differing decimal markers, digit grouping and so on. All of these +options are concerned with the appearance of output, rather than the data it +conveys. The options are summarised in Table~\ref{tab:opt:num:out}. +\begin{table} + \caption{Output options for numbers.% + \label{tab:opt:num:out}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{l}{Option name} & + Type & + \multicolumn{1}{l}{Default} \\ + \midrule + bracket-negative-numbers & Switch & false \\ + exponent-base & Literal & 10 \\ + exponent-product & Math & \verb=\times= \\ + group-digits & Choice & all \\ + group-minimum-digits & integer & 5 \\ + group-separator & Literal & \cs{,} \\ + negative-color & Literal & \meta{none} \\ ^^A ( + output-close-uncertainty & Literal & ) \\ + output-decimal-marker & Literal & . \\ + output-open-uncertainty & Literal & ( \\ ^^A ) + print-implicit-plus & Switch & false \\ + print-unity-mantissa & Switch & true \\ + print-zero-exponent & Switch & false \\ + tight-spacing & Switch & false \\ + uncertainty-mode & Choice & compact \\ + uncertainty-separator & Literal & \meta{none} \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{group-digits} +\DescribeOption{group-four-digits} +\DescribeOption{group-separator} +Grouping digits into blocks of three is a common method to increase the ease of +reading of numbers. The \opt{group-digits} choice controls whether this +behaviour applies, and takes the values \opt{all}, \opt{none}, \opt{decimal} +and \opt{integer}. Grouping can be activated separately for the integer and +decimal parts of a number using the appropriately-named values. +\begin{LaTeXdemo} + \num{12345.67890} \\ + \num[group-digits = none]{12345.67890} \\ + \num[group-digits = decimal]{12345.67890} \\ + \num[group-digits = integer]{12345.67890} +\end{LaTeXdemo} +The separator used between groups of digits is stored by the +\opt{group-separator} option. This takes literal input and may be used in math +mode: for a text-mode full space use \verb*|\ |. +\begin{LaTeXdemo} + \num{12345} \\ + \num[group-separator = {,}]{12345} \\ + \num[group-separator = \ ]{12345} +\end{LaTeXdemo} + +\DescribeOption{group-minimum-digits} +Grouping is not always applied to smaller numbers; this can be controlled using +the option \opt{group-minimum-digits}, which specifies how many digits must be +present before grouping is applied. The number of digits is considered +separately for the integer and decimal parts of the number: grouping does not +\enquote{cross the boundary}. +\begin{LaTeXdemo} + \num{1234} \\ + \num{12345} \\ + \num[group-minimum-digits = 5]{1234} \\ + \num[group-minimum-digits = 5]{12345} \\ + \num{1234.5678} \\ + \num{12345.67890} \\ + \num[group-minimum-digits = 5]{1234.5678} \\ + \num[group-minimum-digits = 5]{12345.67890} +\end{LaTeXdemo} + +\DescribeOption{output-decimal-marker} +The decimal marker used in output is set using the \opt{output-decimal-marker} +option; this can differ from the input marker. +\begin{LaTeXdemo} + \num{1.23} \\ + \num[output-decimal-marker = {,}]{1.23} \\ +\end{LaTeXdemo} + +\DescribeOption{exponent-base} +\DescribeOption{exponent-product} +When exponents are present in the input, the \opt{exponent-base} and +\opt{exponent-product} options set the obvious parts of the output. +\begin{LaTeXdemo} + \num[exponent-product = \times]{1e2} \\ + \num[exponent-product = \cdot]{1e2} \\ + \num[exponent-base = 2]{1e2} +\end{LaTeXdemo} + +\DescribeOption{uncertainty-separator} +\DescribeOption{output-open-uncertainty} +\DescribeOption{output-close-uncertainty} +\DescribeOption{uncertainty-separator} +When input is given including an uncertainty in a number, it can be printed +either with the uncertainty in brackets or as a separate number. This behaviour +is controlled by the \opt{uncertainty-mode} choice.When this is set to +\opt{separate}, the uncertainty is printed as an entirely separate number +preceded by \cs{pm}. Other settings all place the uncertainty in brackets +directly attached to the main value. The standard setting of \opt{compact} +prints digits of uncertainty in the least-significant digits. It does +\emph{not} print a decimal marker if the uncertainty crosses the decimal. The +setting \opt{full} prints the full value of the uncertainty. Finally, +\opt{compact-marker} is available to print in the \opt{compact} style except +where the uncertainty crosses the decimal, in which case the \opt{full} style +is used. When the uncertainty is given in brackets, a space may be added +between the main number and the uncertainty: this is stored using the +\opt{uncertainty-separator} option. The opening and closing brackets used are +stored in \opt{output-open-uncertainty} and \opt{output-close-uncertainty}, +respectively. Tokens may be inserted before the opening bracket using +\opt{uncertainty-separator}. +\begin{LaTeXdemo} + \num{123.45(120)} \\ + \num{0.035(14)} \\ + \sisetup{uncertainty-mode = full} + \num{123.45(120)} \\ + \num{0.035(14)} \\ + \sisetup{uncertainty-mode = compact-marker} + \num{123.45(120)} \\ + \num{0.035(14)} \\ + \sisetup{uncertainty-mode = separate} + \sisetup{ + output-open-uncertainty = [, + output-close-uncertainty = ], + uncertainty-separator = \, + }% + \num{1.234(5)} +\end{LaTeXdemo} + +\DescribeOption{bracket-ambiguous-numbers} +There are certain combinations of numerical input which can be ambiguous. This +can be corrected by adding brackets in the appropriate place, and is controlled +by the \opt{bracket-ambiguous-numbers} switch. This option only applies to pure +numbers: when formatting quantities, the need for brackets also depends on the +placement of units, so is controlled by \opt{seperate-uncertainty-units}. +\begin{LaTeXdemo} + \sisetup{separate-uncertainty} + \num{1.2(3)e4} \\ + \num[bracket-ambiguous-numbers = false]{1.2(3)e4} +\end{LaTeXdemo} + +\DescribeOption{negative-color} +The package can detect negative mantissa values and alter print color +accordingly. This is disabled by setting the option to an empty value. +\begin{LaTeXdemo} + \num{-15673} \\ + \num[negative-color = red]{-15673} +\end{LaTeXdemo} + +\DescribeOption{bracket-negative-numbers} +A common means to display negative numbers in financial situations is to place +them in brackets. This can be carried out automatically using the +\opt{bracket-negative-numbers} option. +\begin{LaTeXdemo} + \num{-15673} \\ + \num[bracket-negative-numbers]{-15673} \\ + \qty{-10}{\metre} \\ + \qty[bracket-negative-numbers]{-10}{\metre} +\end{LaTeXdemo} + +\DescribeOption{tight-spacing} +Under some circumstances is may be desirable to \enquote{squeeze} the output +spacing. This is turned on using the \opt{tight-spacing} switch, which +compresses spacing where possible. +\begin{LaTeXdemo} + \num{2e3} \\ + \num[tight-spacing = true]{2e3} +\end{LaTeXdemo} + +\DescribeOption{print-implicit-plus} +It may be useful to force all numbers to have a sign. This behaviour is +controlled by the \opt{print-implicit-plus} option: this is used if given and +if no sign was present in the input. +\begin{LaTeXdemo} + \num{345} \\ + \num[print-implicit-plus]{345} +\end{LaTeXdemo} + +\DescribeOption{print-unity-mantissa} +\DescribeOption{print-zero-exponent} +Printing of a mantissa of $1$ and an exponent of $0$ is controllable by the +options \opt{print-unity-mantissa} and \opt{print-zero-exponent}. The standard +settings print a mantissa of $1$ but omit an exponent of $0$. +\begin{LaTeXdemo} + \num{1e4} \\ + \num[print-unity-mantissa = false]{1e4} \\ + \num{444e0} \\ + \num[print-zero-exponent = true]{444e0} +\end{LaTeXdemo} + +\subsection{Lists, products and ranges} + +Lists, products and ranges of numbers and quantities have a small number of +specialised options, which apply to these more unusual input forms +(Table~\ref{tab:opt:num:list}). +\begin{table} + \begin{threeparttable} + \caption{Output options for lists, products and ranges of numbers and + quantities.% + \label{tab:opt:num:list}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{l}{Option name} & + Type & + \multicolumn{1}{l}{Default\tnote{*}} \\ + \midrule + list-exponents & Choice & individual \\ + list-final-separator & Literal & \verb*= \text{and} = \\ + list-pair-separator & Literal & \verb*= \text{and} = \\ + list-separator & Literal & \verb*=\text{,} = \\ + list-units & Choice & repeat \\ + product-exponents & Choice & individual \\ + product-mode & Choice & symbol \\ + product-phrase & Literal & \verb*= \text{by} = \\ + product-symbol & Literal & \cs{times} \\ + product-units & Choice & repeat \\ + range-exponents & Choice & individual \\ + range-phrase & Literal & \verb*= \text{to} = \\ + range-units & Choice & repeat \\ + \bottomrule + \end{tabular} + \footnotesize + \begin{tablenotes} + \item[*] The default values are actually more complex for two + reasons: allowing spaces to work in both math and text modes, + and localization of strings. + \end{tablenotes} + \end{threeparttable} +\end{table} + +\DescribeOption{list-final-separator} +\DescribeOption{list-pair-separator} +\DescribeOption{list-separator} +Lists of numbers are printed with a separator between each item, which is +stored using the \opt{list-separator} option. The separator before the last +item of a list may be different, and is therefore set using the +\opt{list-final-separator} option. The separator used for exactly two items is +set using the \opt{list-pair-separator} option. Any spaces needed should be +included in the option settings: none are added within the code. The separators +are always printed in text mode. +\begin{LaTeXdemo} + \numlist{0.1;0.2;0.3} \\ + \numlist[list-separator = {; }]{0.1;0.2;0.3} \\ + \numlist[list-final-separator = {, }]{0.1;0.2;0.3} \\ + \numlist[ + list-separator = { and }, + list-final-separator = { and finally } + ]{0.1;0.2;0.3} \\ + \numlist{0.1;0.2} \\ + \numlist[list-pair-separator = {, and }]{0.1;0.2} +\end{LaTeXdemo} + +\DescribeOption{product-mode} +\DescribeOption{product-phrase} +\DescribeOption{product-symbol} +Products of numbers can be output using either a product symbol or phrase: +this is controlled by the \opt{product-mode} setting. When \opt{symbol} is +set, the appropriate symbol is stored in \opt{product-symbol}. When using +\opt{phrase-mode}, the information is stored in \opt{product-phrase}. Phrases +are always printed in text mode; symbols are printed using the same routine +as for numbers. +\begin{LaTeXdemo} + \numproduct{5 x 100 x 2} \\ + \numproduct[product-symbol = \ensuremath{\cdot}]{5 x 100 x 2} \\ + \sisetup{product-mode = phrase}% + \numproduct{5 x 100 x 2}\\ + \numproduct[product-phrase = { BY }]{5 x 100 x 2} \\ +\end{LaTeXdemo} + +\DescribeOption{range-phrase} +Ranges of numbers can be given as input. These will have an appropriate word or +symbol inserted between the two entries: this is stored using the +\opt{range-phrase} option. The phrase should include any necessary spaces: no +extra space is added. The phrase is always printed in text mode. +\begin{LaTeXdemo} + \numrange{5}{100} \\ + \numrange[range-phrase = --]{5}{100} +\end{LaTeXdemo} + +\DescribeOption{list-exponents} +\DescribeOption{product-exponents} +\DescribeOption{range-exponents} +Lists, products and ranges can be \enquote{compressed} by combining the +exponent parts. This is controlled by the options \opt{list-exponents}, +\opt{product-exponents} and \opt{range-exponents}, all of which take the +choices \opt{individual}, \opt{combine-bracket} and \opt{combine}. The standard +setting, \opt{individual}, leaves the exponent with the matching value. Both +\opt{combine} and \opt{combine-bracket} take the exponent of the first entry +and apply to to all other entries, with the exponent itself places at the end. +\begin{LaTeXdemo} + \numlist{5e3;7e3;9e3;1e4} \\ + \numproduct{5e3 x 7e3 x 9e3 x 1e4} \\ + \numrange{5e3}{7e3} \\ + \sisetup + { + list-exponents = combine-bracket , + product-exponents = combine-bracket , + range-exponents = combine-bracket + } + \numlist{5e3;7e3;9e3;1e4} \\ + \numproduct{5e3 x 7e3 x 9e3 x 1e4} \\ + \numrange{5e3}{7e3} \\ + \sisetup + { + list-exponents = combine , + product-exponents = combine , + range-exponents = combine + } + \numlist{5e3;7e3;9e3;1e4} \\ + \numproduct{5e3 x 7e3 x 9e3 x 1e4} \\ + \numrange{5e3}{7e3} +\end{LaTeXdemo} + +\DescribeOption{list-units} +\DescribeOption{product-units} +\DescribeOption{range-units} +The \opt{list-units}, \opt{product-units} and \opt{range-units} options +determine how \cs{qtylist}, \cs{qtyproduct} and \cs{qtyrange} command print +units, respectively. The standard setting for these is \opt{repeat}, where each +number will be printed with a unit. Alternatives are \opt{bracket} and +\opt{single}. If set to \opt{single}, this will override collection of +exponents. +\begin{LaTeXdemo} + \qtylist{2;4;6;8}{\tesla} \\ + \qtylist[list-units = bracket]{2;4;6;8}{\tesla} \\ + \qtylist[list-units = repeat]{2;4;6;8}{\tesla} \\ + \qtylist[list-units = single]{2;4;6;8}{\tesla} \\ + \qtyrange{2}{4}{\degreeCelsius} \\ + \qtyrange[range-units = bracket]{2}{4}{\degreeCelsius} \\ + \qtyrange[range-units = repeat]{2}{4}{\degreeCelsius} \\ + \qtyrange[range-units = single]{2}{4}{\degreeCelsius} +\end{LaTeXdemo} + +\subsection{Complex numbers} + +A small number of options apply specifically to the handling of complex +numbers; these are summarised in Table~\ref{tab:opt:num:complex}. +\begin{table} + \caption{Options for complex numbers.% + \label{tab:opt:num:complex}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{@{}l}{Option name} & + Type & + \multicolumn{1}{l@{}}{Default} \\ + \midrule + complex-root-position & Choice & after-number \\ + input-complex-root & Literal & ij \\ + output-complex-root & Literal & \verb=\mathrm{i}= \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{input-complex-root} +When using complex numbers in input, the complex root $(\mathrm{i} = +\sqrt{-1}\,)$ is indicated by one of the tokens stored in +\opt{input-complex-roots}. The parser understands complex root symbols given +either before or after the associated number (but will detect any invalid +arrangement): +\begin{LaTeXdemo} + \complexnum{9.99 + 88.8i} \\ + \complexnum{9.99 + i88.8} +\end{LaTeXdemo} + +\DescribeOption{output-complex-root} +The output complex root symbol is independent of the input and can be changed +using the \opt{output-complex-root} setting. +\begin{LaTeXdemo} + \complexnum[output-complex-root = i]{1+2i} \\ + \complexnum[output-complex-root = j]{1+2i} +\end{LaTeXdemo} + +\DescribeOption{complex-root-position} + The position of the complex root can be adjusted to place it + either before or after the associated numeral in a complex number + using the \opt{complex-root-position} option. +\begin{LaTeXdemo} + \complexnum{67-0.9i} \\ + \complexnum[complex-root-position = before-number]{67-0.9i} \\ + \complexnum[complex-root-position = after-number]{67-0.9i} +\end{LaTeXdemo} + +\subsection{Angles} + +Angle processing provided by the \cs{ang} function has a set of options which +apply in addition to the general ones set up for number processing. +\begin{table} + \caption{Angle options.% + \label{tab:opt:ang}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{@{}l}{Option name} & + Type & + \multicolumn{1}{l@{}}{Default} \\ + \midrule + angle-mode & Choice & input \\ + angle-symbol-degree & Literal & \cs{degree} \\ + angle-symbol-minute & Literal & \cs{arcminute} \\ + angle-symbol-over-decimal & Switch & false \\ + angle-symbol-second & Literal & \cs{arcsecond} \\ + angle-separator & Literal & \meta{empty} \\ + fill-angle-degrees & Switch & false \\ + fill-angle-minutes & Switch & false \\ + fill-angle-seconds & Switch & false \\ + number-angle-product & Literal & \meta{empty} \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{angle-mode} +The format in which angles are printed can be set using the \opt{angle-mode} +option. With the standard setting (\opt{input}), the angle is printed as-given. +By setting the option to \opt{arc} or \opt{decimal}, the output format can +be set to an arc (degrees/minutes/seconds) or decimal value. Conversion uses +the \LaTeX3 floating-point unit, so is limited to $16$ decimal places. +\begin{LaTeXdemo} + \ang{2.67} \\ + \ang{2;3;4} \\ + \ang[angle-mode = arc]{2.67} \\ + \ang[angle-mode = arc]{2;3;4} \\ + \ang[angle-mode = decimal]{2.67} \\ + \ang[angle-mode = decimal]{2;3;4} \\ +\end{LaTeXdemo} + +\DescribeOption{number-angle-product} +The separator between the number and angle symbol (degrees, minutes or seconds) +can be set using the \opt{number-angle-product} option, independent of the +related \opt{number-unit-product} option used by the \cs{qty} command. +\begin{LaTeXdemo} + \ang{2.67} \\ + \ang[number-angle-product = \,]{2.67} +\end{LaTeXdemo} + +\DescribeOption{angle-separator} +When angles are printed in arc format, the separation of the different parts is +set up using the \opt{arc-separator} option. +\begin{LaTeXdemo} + \ang{6;7;6.5} \\ + \ang[angle-separator = \,]{6;7;6.5} +\end{LaTeXdemo} + +\DescribeOption{fill-angle-degrees} +\DescribeOption{fill-angle-minutes} +\DescribeOption{fill-angle-seconds} +Zero-filling for the degree, minute or second parts of an arc is controlled +using the \opt{fill-angle-degrees}, \opt{fill-angle-minutes} and +\opt{fill-angle-seconds} options. All are off as standard. +\begin{LaTeXdemo} + \ang{-1;;} \\ + \ang{;-2;} \\ + \ang{;;-3} \\ + { + \sisetup{fill-angle-degrees} + \ang{-1;;} \\ + \ang{;-2;} \\ + \ang{;;-3} \\ + } + { + \sisetup{fill-angle-minutes} + \ang{-1;;} \\ + \ang{;-2;} \\ + \ang{;;-3} \\ + } + { + \sisetup{fill-angle-seconds} + \ang{-1;;} \\ + \ang{;-2;} \\ + \ang{;;-3} + } +\end{LaTeXdemo} + +\DescribeOption{angle-symbol-degree} +\DescribeOption{angle-symbol-minute} +\DescribeOption{angle-symbol-second} +With the standard settings, the symbols used for arc angles are the unit +commands \cs{degree}, \cs{arcminute} and \cs{arcsecond}. These can be altered +using \opt{angle-symbol-degree}, \opt{angle-symbol-minute} and +\opt{angle-symbol-second}. This is most likely to be used when the definition +of the unit macros is altered, for example to set \cs{arcsecond} as +\texttt{as}. +\begin{LaTeXdemo} + \ang{6;7;6.5} \\ + \sisetup{ + angle-symbol-degree = d , + angle-symbol-minute = m , + angle-symbol-second = s + } + \ang{6;7;6.5} +\end{LaTeXdemo} + +\DescribeOption{angle-symbol-over-decimal} +In some subject areas, most notably astronomy, the angle symbols are given over +the decimal marker, rather than at the end of the number. This behaviour is +available using the \opt{angle-symbol-over-decimal} option. +\begin{LaTeXdemo} + \ang{45.697} \\ + \ang{6;7;6.5} \\ + \ang[angle-symbol-over-decimal]{45.697} \\ + \ang[angle-symbol-over-decimal]{6;7;6.5} +\end{LaTeXdemo} + +\subsection{Creating units% + \label{sec:units:creating}} + +The various macro units are created at the start of the document. \pkg{siunitx} +can define these such that they are only available for use within the \cs{unit} +and \cs{qty} functions, or can make the unit macros available throughout the +document body. There are a number of settings which control this creation +process (Table~\ref{tab:opt:units:def}). As a result, these options all apply +in the preamble only. +\begin{table} + \caption{Unit creation options.% + \label{tab:opt:units:def}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{@{}l}{Option name} & + Type & + \multicolumn{1}{l@{}}{Default} \\ + \midrule + free-standing-units & Switch & false \\ + overwrite-command & Switch & false \\ + space-before-unit & Switch & false \\ + unit-optional-argument & Switch & false \\ + use-xspace & Switch & false \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{free-standing-units} +\DescribeOption{overwrite-functions} +The \opt{free-standing-units} option controls whether the unit macros exist +outside of the \cs{unit} and \cs{qty} arguments. When this option is +\opt{true}, \pkg{siunitx} creates the macros for general use. The standard +method to achieve this does not overwrite any existing macros: this behaviour +can be altered using the \opt{overwrite-commands} switch. + +\DescribeOption{space-before-unit} +\DescribeOption{unit-optional-argument} +\DescribeOption{use-xspace} +When \enquote{free standing} unit macros are created, their behaviour can be +adjusted by a number of options. These are mainly intended for emulating the +input syntax of older packages. The option \opt{unit-optional-argument} gives +the same behaviour for the inputs +\begin{LaTeXdemo}[code only] + \qty{10}{\metre} +\end{LaTeXdemo} +and +\begin{LaTeXdemo}[code only] + \metre[10]. +\end{LaTeXdemo} +The \opt{space-before-unit} and \opt{use-xspace} options control the behaviour +at the \enquote{ends} of the unit macros. Activating \opt{space-before-unit} +inserts the number--unit space before the unit is printed. This is suitable for +the input syntax +\begin{LaTeXdemo}[code only] + 30\metre +\end{LaTeXdemo} +but does mean that the unit macros are incorrectly spaced in running text. On +the other hand, the \opt{use-xspace} option attempts to correctly space input +such as +\begin{LaTeXdemo}[code only] + \metre is the symbol for metres. +\end{LaTeXdemo} + +\subsection{Using units} + +Part of the power of \pkg{siunitx} is the ability to alter the output format +for units without changing the input. The behaviour of units is therefore +controlled by a number of options which alter either the processing of units or +the output directly (Table~\ref{tab:opt:units:out}). +\begin{table} + \centering + \caption{Unit output options.% + \label{tab:opt:units:out}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{@{}l}{Option name} & + Type & + \multicolumn{1}{l@{}}{Default} \\ + \midrule + bracket-unit-denominator & Switch & true \\ + forbid-literal-units & Switch & false \\ + inter-unit-product & Literal & \cs{,} \\ + parse-units & Switch & true \\ + per-mode & Choice & power \\ + per-symbol & Literal & / \\ + qualifier-mode & Choice & subscript \\ + qualifier-phrase & Literal & \meta{empty} \\ + sticky-per & Switch & false \\ + unit-font-command & Literal & \cs{mathrm} \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{inter-unit-product} +The separator between each unit is stored using the \opt{inter-unit-product} +option. The standard setting is a thin space: another common choice is a +centred dot. To get the correct spacing it is necessary to use +|\ensuremath{{}\cdot{}}| in the latter case. +\begin{LaTeXdemo} + \unit{\farad\squared\lumen\candela} \\ + \unit[inter-unit-product = \ensuremath{{}\cdot{}}] + {\farad\squared\lumen\candela} +\end{LaTeXdemo} + +\DescribeOption{per-mode} +\DescribeOption{per-symbol} +\DescribeOption{bracket-unit-denominator} +The handling of \cs{per} is altered using the \opt{per-mode} choice option. The +standard setting is \opt{power}, meaning that \cs{per} generates reciprocal +powers for units. Setting the option to \opt{fraction} uses the |\frac| +function to typeset the positive and negative powers of a unit separately. +\begin{LaTeXdemo} + \unit{\joule\per\mole\per\kelvin} \\ + \unit{\metre\per\second\squared} \\ + \unit[per-mode = fraction]{\joule\per\mole\per\kelvin} \\ + \unit[per-mode = fraction]{\metre\per\second\squared} +\end{LaTeXdemo} +The closely-related \opt{power-positive-first} setting acts in the same way but +places all of the positive powers before any negative ones. +\begin{LaTeXdemo} + \unit{\ampere\per\mole\second} \\ + \unit[per-mode = power-positive-first] + {\ampere\per\mole\second} +\end{LaTeXdemo} +It is possible to use a symbol (usually |/|) to separate the two parts of a +unit by setting \opt{per-mode} to \opt{symbol}; the symbol used is stored using +the setting \opt{per-symbol}. This method for displaying units can be +ambiguous, and so brackets are added unless \opt{bracket-unit-denominator} is +set to \opt{false}. Notice that \opt{bracket-unit-denominator} only applies +when \opt{per-mode} is set to \opt{symbol} or \opt{symbol-or-fraction}. +\begin{LaTeXdemo} + \sisetup{per-mode = symbol}% + \unit{\joule\per\mole\per\kelvin} \\ + \unit{\metre\per\second\squared} \\ + \unit[per-symbol = \ \text{div}\ ]{\joule\per\mole\per\kelvin} \\ + \unit[bracket-unit-denominator = false]{\joule\per\mole\per\kelvin} +\end{LaTeXdemo} +The often-requested (but mathematically invalid) \opt{repeated-symbol} option +is also available to repeat the symbol for each \cs{per}. +\begin{LaTeXdemo} + \unit[per-mode = repeated-symbol]{\joule\per\mole\per\kelvin} +\end{LaTeXdemo} +Finally, it is possible for the behaviour of the \cs{per} function to depend on +the prevailing math style. Setting \opt{per-mode} to \opt{symbol-or-fraction} +will use the \opt{symbol} setting for in line math, and the \opt{fraction} +setting when used in display math. +\begin{LaTeXdemo} + \sisetup{per-mode = symbol-or-fraction}% + $ \unit{\joule\per\mole\per\kelvin} $ + \[ \unit{\joule\per\mole\per\kelvin} \] + \unit{\joule\per\mole\per\kelvin} \\ + $ + \displaystyle + \unit{\joule\per\mole\per\kelvin} + $ + \[ + \textstyle + \unit{\joule\per\mole\per\kelvin} + \] +\end{LaTeXdemo} + +\DescribeOption{sticky-per} +By default, \cs{per} applies only to the next unit given.\footnote{This is the +standard method of reading units in English: for example, +\unit{\joule\per\mole\per\kelvin} is pronounced \enquote{joules per mole per +kelvin}.} By setting the \opt{sticky-per} flag, this behaviour is changed so +that \cs{per} applies to all subsequent units. +\begin{LaTeXdemo} + \unit{\pascal\per\gray\henry} \\ + \unit[sticky-per]{\pascal\per\gray\henry} +\end{LaTeXdemo} + +\DescribeOption{qualifier-mode} +\DescribeOption{qualifier-phrase} +Unit qualifiers can be printed in three different formats, set by the +\opt{qualifier-mode} option. The standard setting is \opt{subscript}, while the +options \opt{bracket}, \opt{combine} and \opt{phrase} are also possible. With +the last settings, powers can lead to ambiguity and are automatically detected +and brackets added as appropriate. +\begin{LaTeXdemo} + \unit{\kilogram\of{pol}\squared\per\mole\of{cat}\per\hour} \\ + \unit[qualifier-mode = bracket] + {\kilogram\of{pol}\squared\per\mole\of{cat}\per\hour} \\ + \unit[qualifier-mode = combine] + {\deci\bel\of{i}} +\end{LaTeXdemo} +The \opt{phrase} option is used with \opt{qualifier-phrase}, which allows for +example a space or other linking text to be inserted. +\begin{LaTeXdemo} + \sisetup{qualifier-mode = phrase, qualifier-phrase = \ }% + \unit{\kilogram\of{pol}\squared\per\mole\of{cat}\per\hour} \\ + \sisetup{qualifier-phrase = \ \mbox{of}\ }% + \unit{\kilogram\of{pol}\squared\per\mole\of{cat}\per\hour} +\end{LaTeXdemo} + +\DescribeOption{parse-units} +Normally, \pkg{siunitx} is used with the unit parse enabled, and only prints +units directly if there is literal input. However, if the input is known to be +essentially consistent and high performance is desired, then the parser can be +turned off using the \opt{parse-units} switch. +\begin{LaTeXdemo} + \qty{300}{\MHz} \\ + \qty[parse-units = false]{300}{\MHz} +\end{LaTeXdemo} + +\DescribeOption{forbid-literal-units} +Some users may prefer to completely disable the use of literal input in units, +for example to enforce consistency. This can be accomplished by setting the +\opt{forbid-literal-units} switch. With this option enabled, only macro-based +units can be used in a document. This only applies when \opt{parse-units} is +\opt{true}. + +\DescribeOption{unit-font-command} +The command used to set unit themselves may be adjusted using the +\opt{unit-font-command} option. This is typically set to |\mathrm|. +\begin{LaTeXdemo} + \unit{\lumen} \\ + \unit[unit-font-command = \mathit]{\lumen} +\end{LaTeXdemo} + +\subsection{Quantities} + +Some options apply to quantities (the combination of a number and a unit), +rather than to the numbers or units alone (Table~\ref{tab:opt:quantities}). +\begin{table} + \centering + \caption{Options for quantities.% + \label{tab:opt:quantities}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{@{}l}{Option name} & + Type & + \multicolumn{1}{@{}l}{Default} \\ + \midrule + allow-quantity-breaks & Switch & false \\ + extract-mass-in-kilograms & Switch & true \\ + prefix-mode & Choice & input \\ + quantity-product & Literal & \cs{,} \\ + separate-uncertainty-units & Choice & bracket \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{allow-quantity-breaks} +Usually, the combination of a number and unit is regarded as a single +mathematical entity which should not be split across lines. However, there are +cases (very long units, narrow columns, \foreign{etc}.) where breaks may be +needed. This can be turned on using the \opt{allow-quantity-breaks} option. +\begin{LaTeXdemo} + \begin{minipage}{2.55cm} + % Gives an underfull hbox + Some filler text \qty{10}{\metre} \\ + \sisetup{allow-quantity-breaks} + Some filler text \qty{10}{\metre} + \end{minipage} +\end{LaTeXdemo} + +\DescribeOption{number-unit-product} +The product symbol between the number and unit is set using the +\opt{quantity-product} option. +\begin{LaTeXdemo} + \qty{2.67}{\farad} \\ + \qty[quantity-product = \ ]{2.67}{\farad} \\ + \qty[quantity-product = ]{2.67}{\farad} +\end{LaTeXdemo} + +\DescribeOption{prefix-mode} +\DescribeOption{extract-mass-in-kilograms} +The unit prefixes (\cs{kilo}, \foreign{etc}.) are normally given as letters. +However, the package can convert these into numerical powers. This is +controlled by the \opt{prefix-mode} option, which takes the values \opt{input}, +\opt{combine-exponent} and \opt{extract-exponent}. The \opt{input} setting +leaves the prefixes unchanged. Using \opt{combine-exponent} will add any +exponent amount from the number to the first unit: this will modify any +existing prefix. Finally, using \opt{extract-exponent} will remove all prefixes +and express them as an exponent. The treatment of kilograms in this case can be +set using \opt{extract-mass-in-kilograms}: when \opt{true}, the \emph{kilo} +prefix is retained as part of the unit. This will mean that all grams are +converted to kilograms. +\begin{LaTeXdemo} + \qty{1e3}{\metre\second} \\ + \qty[prefix-mode = combine-exponent]{1e3}{\metre\second} \\ + \qty{10}{\kilo\gram\squared\deci\second} \\ + \qty[prefix-mode = extract-exponent]{10}{\kilo\gram\squared\deci\second}\\ + \qty[prefix-mode = extract-exponent]{7.5}{\gram} \\ + \sisetup{extract-mass-in-kilograms = false} + \qty{10}{\kilo\gram\squared\deci\second} \\ + \qty[prefix-mode = extract-exponent]{10}{\kilo\gram\squared\deci\second} \\ + \qty[prefix-mode = extract-exponent]{7.5}{\gram} \\ +\end{LaTeXdemo} + +\DescribeOption{separate-uncertainty-units} +When a number has multiple parts (such as a separate uncertainty) then the unit +must apply to all parts of the number. How this is shown is controlled using +the \opt{separate-uncertainty-units} options. The standard setting is +\opt{brackets}, which will place the entire numerical part in brackets and use +a single unit symbol. Alternative options are \opt{repeat} (print the unit for +each part of the number) and \opt{single} (print only one unit symbol: +mathematically incorrect). +\begin{LaTeXdemo} + \sisetup{separate-uncertainty} + \qty{12.3(4)}{\kilo\gram} \\ + \qty[separate-uncertainty-units = bracket]{12.3(4)}{\kilo\gram} \\ + \qty[separate-uncertainty-units = repeat]{12.3(4)}{\kilo\gram} \\ + \qty[separate-uncertainty-units = single]{12.3(4)}{\kilo\gram} +\end{LaTeXdemo} + +\subsection{Tabular material} + +Processing of material in tables obeys the same settings as described for the +functions already described. However, there are some settings which apply only +to the layout of tabular material (Table~\ref{tab:opt:tables}). +\begin{table} + \caption{Options for tabular material.% + \label{tab:opt:tables}} + \begin{tabular}{@{}>{\ttfamily}ll>{\ttfamily}l@{}} + \toprule + \multicolumn{1}{@{}l}{Option name} & + Type & + \multicolumn{1}{l@{}}{Default} \\ + \midrule + table-align-comparator & Switch & true \\ + table-align-exponent & Switch & true \\ + table-align-text-after & Switch & true \\ + table-align-text-before & Switch & true \\ + table-align-uncertainty & Switch & true \\ + table-alignment & Meta & center \\ + table-alignment-mode & Choice & marker \\ + table-auto-round & Switch & false \\ + table-column-width & Length & 0pt \\ + table-fixed-width & Switch & false \\ + table-format & Special & 2.2 \\ + table-number-alignment & Choice & center \\ + table-text-alignment & Choice & center \\ + \bottomrule + \end{tabular} +\end{table} + +\DescribeOption{table-mode} +The method used by \pkg{siunitx} to align numbers is selected using the +\opt{table-mode} option, which may be one of \opt{marker}, \opt{format} or +\meta{none}. With the standard setting, \meta{marker}, the package centers the +decimal marker in a tabular column, potentially leaving white space at the +shorter end of a number. The \meta{format} mode uses information from the +\meta{table-format} key to construct a model: this is then used to define the +space available to a number. For asymmetrical numbers, this method is strongly +preferable. Finally, \opt{none} disables alignment entirely: numbers are simply +parsed. + +\DescribeOption{table-number-alignment} +When \opt{table-mode} is set to \meta{format} or \meta{none}, the placement of +the number \enquote{block} within the cell as a whole is set by the +\meta{table-number-alignment} option, which may be one of \meta{left}, +\meta{center} or \meta{right}. (When \opt{table-mode} is set to \meta{marker}, +the decimal marker is always centered in the cell.) The different alignment +choices are illustrated in Table~\ref{tab:S:align}, which uses somewhat +exaggerated column headings to show the relative position of the cell contents. +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Aligning the \texttt{S} column.% + \label{tab:S:align}} + \centering + \sisetup{table-format = 2.4, table-alignment-mode = format} + \begin{tabular}{@{} + S[table-alignment-mode = marker] + S[table-number-alignment = center] + S[table-number-alignment = left] + S[table-number-alignment = right] + @{}} + \toprule + {Some Values} & {Some Values} & {Some Values} & {Some Values} \\ + \midrule + 2.3456 & 2.3456 & 2.3456 & 2.3456 \\ + 34.2345 & 34.2345 & 34.2345 & 34.2345 \\ + 56.7835 & 56.7835 & 56.7835 & 56.7835 \\ + 90.473 & 90.473 & 90.473 & 90.473 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} +When the alignment mode is set to \opt{none}, number are simply collected and +parsed without any further processing, as illustrated in +Table~\ref{tab:S:parse}. +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Parsing without aligning in an \texttt{S} column.% + \label{tab:S:parse}} + \begin{tabular} + {@{} + S + S[table-alignment-mode = none] + @{}} + \toprule + {Decimal-centred} & + {Simple centring} \\ + \midrule + 12.345 & 12.345 \\ + 6,78 & 6,78 \\ + -88.8(9) & -88.8(9) \\ + 4.5e3 & 4.5e3 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\DescribeOption{table-format} +When the \opt{table-alignment-mode} is set to \opt{format}, \pkg{siunitx} uses +the information set in \meta{table-format} to construct a \enquote{model} which +defines the space to reserve for a number. The \opt{table-format} key is +interpreted in much the same way as a table cell. The numerical part should +consist of a number showing how many figures to reserve in each part of the +input, plus any comparators, signs, \foreign{etc.} A variety of examples are +given in Table~\ref{tab:S:format}. +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Reserving space in \texttt{S} columns.% + \label{tab:S:format}} + \sisetup{ + table-alignment-mode = format, + table-number-alignment = center, + } + \begin{tabular}{@{} + S[table-format = 2.2] + S[table-format = 2.2, table-number-alignment = right] + S[table-format = 2.2(1)] + S[table-format = 2.2(1), separate-uncertainty] + S[table-format = +2.2] + S[table-format = 2.2e1] + @{}} + \toprule + {Values} + & {Values} + & {Values} + & {Values} + & {Values} + & {Values} \\ + \midrule + 2.3 & 2.3 & 2.3(5) & 2.3(5) & 2.3 & 2.3e8 \\ + 34.23 & 34.23 & 34.23(4) & 34.23(4) & 34.23 & 34.23 \\ + 56.78 & 56.78 & 56.78(3) & 56.78(3) & -56.78 & 56.78e3 \\ + 3,76 & 3,76 & 3,76(2) & 3.76(2) & +-3.76 & e6 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} +It is important to note that any parts of a number \emph{not} specified in the +table format argument are set to be absent (the number of figures is set to +zero). Setting the \opt{table-format} option also resets +\opt{table-alignment-mode} to \opt{format}. + +Space for material before and after the \texttt{S} column can be reserved by +giving model text as part of the \opt{table-format} key. This is then used to +provide the necessary gap while maintaining alignment (Table~\ref{tab:S:ends}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Text before and after numbers.% + \label{tab:S:ends}} + \sisetup{table-format = {now }2.4{\textsuperscript{\emph{a}}}} + \begin{tabular}{@{}S@{}} + \toprule + {Values} \\ + \midrule + 2.3456 \\ + 34.2345 \textsuperscript{\emph{a}}\\ + 56.7835 \\ + now~ 90.473 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\DescribeOption{table-align-exponent} +\DescribeOption{table-align-uncertainty} +When printing exponents in tables, there is a choice of aligning the exponent +parts or having these close up to the mantissa. This is controlled by the +\opt{table-align-exponent} option (Table~\ref{tab:align:exp}). Similarly, +uncertainty parts which are printed separately from the mantissa can be aligned +or closed up. This is set by the \opt{table-align-uncertainty} option +(Table~\ref{tab:align:uncert}). Finally, the same approach is available for the +comparator with the \opt{table-align-comparator} option +(Table~\ref{tab:align:comp}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{The \opt{table-align-exponent} option.% + \label{tab:align:exp}} + \sisetup{table-format = 1.3e2} + \begin{tabular}{@{}SS[table-align-exponent = false]@{}} + \toprule + {Header} & {Header} \\ + \midrule + 1.2e3 & 1.2e3 \\ + 1.234e56 & 1.234e56 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{The \opt{table-align-uncertainty} option.% + \label{tab:align:uncert}} + \sisetup{ + separate-uncertainty, + table-format = 1.3(1), + } + \begin{tabular}{@{}SS[table-align-uncertainty = false]@{}} + \toprule + {Header} & {Header} \\ + \midrule + 1.2(1) & 1.2(3) \\ + 1.234(5) & 1.234(5) \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{The \opt{table-align-comparator} option.% + \label{tab:align:comp}} + \sisetup{table-format = >2.2} + \begin{tabular}{@{}SS[table-align-comparator = false]@{}} + \toprule + {Header} & {Header} \\ + \midrule + > 1.2 & > 1.2 \\ + < 12.34 & < 12.34 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\DescribeOption{table-align-text-before} +\DescribeOption{table-align-text-after} +Note markers are often given in tables after the numerical content. It may be +desirable for these to close up to the numbers. Whether this takes place is +controlled by the \opt{table-align-text-before} and \opt{\ldots-after} + option (Table~\ref{tab:S:notes}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Closing notes up to text.% + \label{tab:S:notes}} + \newrobustcmd\NoteMark[1]{% + \textsuperscript{\emph{#1}}% + } + \sisetup{table-format = {\NoteMark{a}}2.4} + \begin{tabular}{@{} + S + S[table-align-text-before = false] + @{}} + \toprule + {Values} & {Values} \\ + \midrule + 2.3456 & 2.3456 \\ + \NoteMark{a} 4.234 & \NoteMark{a} 4.234 \\ + \NoteMark{b} .78 & \NoteMark{b} .78 \\ + \NoteMark{d} 88 & \NoteMark{d} 88 \\ + \bottomrule + \end{tabular} + \hfil + \sisetup{table-format = 2.4\NoteMark{a}} + \begin{tabular}{@{} + S + S[table-align-text-after = false] + @{}} + \toprule + {Values} & {Values} \\ + \midrule + 2.3456 & 2.3456 \\ + 34.234 \NoteMark{a} & 34.234 \NoteMark{a} \\ + 56.78 \NoteMark{b} & 56.78 \NoteMark{b} \\ + 90.4 \NoteMark{c} & 90.4 \NoteMark{c} \\ + 88 \NoteMark{d} & 88 \NoteMark{d} \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\DescribeOption{table-auto-round} +The contents of table cells can automatically be rounded or zero-filled to the +number of decimal digits given for the decimal part of the \opt{table-format} +option. This mode is activated using the \opt{table-auto-round} switch, as +illustrated in Table~\ref{tab:S:auto}. +\begin{LaTeXdemo}[code and float] + \begin{table} + \centering + \caption{The \opt{table-auto-round} option.% + \label{tab:S:auto}} + \sisetup{table-format = 1.3} + \begin{tabular}{@{}SS[table-auto-round]@{}} + \toprule + {Header} & {Header} \\ + \midrule + 1.2 & 1.2 \\ + 1.2345 & 1.2345 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\DescribeOption{parse-numbers} +When the \opt{parse-numbers} option is set to \opt{false}, then the alignment +code for tables takes a different approach. The output is always set in math +mode, and alignment takes place at the first decimal marker. This is achieved +by making it active in math mode. When reserving space for content only the +integer and decimal values for the mantissa are considered +(Table~\ref{tab:S:nonparsed}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Aligning without parsing.% + \label{tab:S:nonparsed}} + \sisetup{ + parse-numbers = false, + table-format = 3.3 + } + \centering + \begin{tabular}{@{} + S + S[table-number-alignment = center] + S[table-number-alignment = right] + S[table-number-alignment = left] + @{}} + \toprule + {Some values} + & {Some values} + & {Some values} + & {Some values} \\ + \midrule + 2.35 & 2.35 & 2.35 & 2.35 \\ + 34.234 & 34.234 & 34.234 & 34.234 \\ + 56.783 & 56.783 & 56.783 & 56.783 \\ + 3,762 & 3,762 & 3,762 & 3.762 \\ + \sqrt{2} & \sqrt{2} & \sqrt{2} & \sqrt{2} \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\DescribeOption{drop-exponent} +In cases where data cover a range of values, printing using a fixed exponent in +a table may make presentation clearer. In these cases, dropping the exponent +value from the table is useful. The general numerical options \opt{drop-exponent} +combined with \opt{exponent-mode = fixed} can be used to achieve this +(Table~\ref{tab:exp:omit}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{The \opt{table-omit-exponent} option.% + \label{tab:exp:omit}} + \begin{tabular}{@{} + S[table-format = 1.1e1] + S[ + drop-exponent = true, + exponent-mode = fixed, + fixed-exponent = 3, + table-format = 2.1, + ] + @{}} + \toprule + {Header} & + \multicolumn{1}{c@{}}{Header / \num[print-unity-mantissa = false]{e3}} \\ + \midrule + 1.2e3 & 1.2e3 \\ + 3e2 & 3e2 \\ + 1.0e4 & 1.0e4 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\DescribeOption{table-column-width} +\DescribeOption{table-fixed-width} +Usually, the width of the numerical column is allowed to vary depending on the +content. However, there are cases where a strictly fixed width is desirable. +For these cases, the \opt{table-fixed-width} and \opt{table-column-width} +options are available. The \opt{table-fixed-width} option activates fixed-width +columns, whilst \opt{table-column-width} defines the target width +(Table~\ref{tab:width:fixed}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Fixed-width columns.% + \label{tab:width:fixed}} + \begin{tabular} + {@{} + S + S[table-column-width = 2cm] + @{}} + \toprule + {Flexible} & + {Fixed} \\ + \midrule + 1.23 & 1.23 \\ + 45.6 & 45.6 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +The \opt{table-column-width} option can also be used to achieve special +effects. One example is centring a column of numbers under a wide heading, with +the numbers themselves right-aligned (Table~\ref{tab:width:special}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \centering + \caption{Right-aligning under a heading.% + \label{tab:width:special}} + \settowidth{\mylength}{Long header} + \sisetup{ + table-alignment-mode = none , + table-column-width = \mylength , + table-number-alignment = right + } + \begin{tabular}{@{}S@{}} + \toprule + {Long header} \\ + \midrule + 12.33 \\ + 2 \\ + 1234 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\DescribeOption{table-text-alignment} +\DescribeOption{table-alignment} +Cell contents which are not part of a number can be protected using braces, as +illustrated. Cells which contain no numerical data at all are aligned using the +setting specified by the \opt{table-text-alignment} option, which recognises +the values \opt{center}, \opt{left} and \opt{right} (Table~\ref{tab:S:text}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Aligning text in \texttt{S} columns.% + \label{tab:S:text}} + \sisetup{table-format = 4.4} + \centering + \begin{tabular}{@{} + S + S[table-text-alignment = left] + S[table-text-alignment = right] + @{}} + \toprule + {Values} + & {Values} + & {Values} \\ + \midrule + 992.435 & 992.435 & 992.435 \\ + 7734.2344 & 7734.2344 & 7734.2344 \\ + 56.7834 & 56.7834 & 56.7834 \\ + 3,7462 & 3,7462 & 3,7462 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\DescribeOption{table-alignment} +The table alignment options \opt{table-number-alignment} and +\opt{table-text-alignment} can be set to the same value using the +\opt{table-alignment} option. This will set all three alignment options to the +same value (one of \opt{center}, \opt{right} or \opt{left}). + +\subsection{Locale options} + +\DescribeOption{locale} +\pkg{siunitx} allows the user to switch between the typographic conventions of +different (geographical) areas by using locales. Currently, the package is +supplied with configurations for locales \opt{UK}, \opt{US}, \opt{DE} +(Germany), \opt{FR} (French) and \opt{ZA} (South Africa). The \opt{locale} +option is used to switch to a particular locale. +\begin{LaTeXdemo} + \qty{1.234}{\metre}\\ + \qty[locale = DE]{6.789}{\metre} +\end{LaTeXdemo} + +\subsection{Preamble-only options} + +\DescribeOption{table-column-type} +The letter(s) used to create table columns can be adjusted using the +\opt{table-column-type} option. The standard setting is |S|, but one or more +letters may be used: these must be single tokens. For example, provided the +\pkg{numprint} package has not been loaded, the letter |n| could be used as +this would suggest a numerical column. + +\section{Upgrading from version~\texorpdfstring{$2$}{2}} + +The package has been largely re-written internally between versions $2$ and +$3$. A significant number of key--value settings have new, more descriptive, +names. Where possible, older names are mapped to newer ones internally: you +will be warned in the log if this is the case. + +It is possible to use the \LaTeXe{} kernel mechanism to load the last +version~$2$ release for documents that cannot be successfully processed using +version~$3$. This can be achieved using +\begin{LaTeXdemo}[code only] + \usepackage{siunitx}[=2021-04-09] +\end{LaTeXdemo} +or +\begin{LaTeXdemo}[code only] + \usepackage{siunitx}[=v2] +\end{LaTeXdemo} + +\begin{function}{\SI, \SIlist, \SIrange, \si} + In version~$3$, the document commands have been revised to be more + descriptive. As such, the commands \cs{SI}, \cs{SIlist}, \cs{SIrange} + and \cs{si} remain available but are not recommended for use in new + documents. +\end{function} + +Some changes have been made to the semantics of commands or options. Most +notably +\begin{itemize} + \item prefixes cannot now be given without units; + \item prefixes can only be interconverted with numbers as part + of a quantity, not as stand-alone units. +\end{itemize} + +The font control system has been completely re-written for version~$3$. The +method used in entirely different from version~$2$. Emulation is therefore not +provided for all outcomes: if you need non-standard font settings, you will +need to adjust your source. See Section~\ref{sec:print} for more details on the +options available in this area. + +The input approach for version~$3$ is slightly more structured and restricted +than for version~$2$. As well as the updated names for document commands, +this means that +\begin{itemize} + \item Products of numbers must now be given using the dedicated + \cs{numproduct} and \cs{qtyproduct} commands; + \item Quotients of numbers are only supported as literals; + \item Complex values need to be given using the dedicated command + \cs{complexnum}. +\end{itemize} + +A new approach has been taken to providing non-Latin symbols for use in +units: these are now handled directly where needed, for example in the +definition of the \cs{micro} prefix. + +The letter used for a numerical tabular column can now be selected by the +user: the letter |S| has been retained as the standard interface. The unit +column (|s|) has been removed from this release. It can be emulated using +the \pkg{collcell} package, for example +\begin{LaTeXdemo}[code only] + \usepackage{collcell} + \newcolumntype{s}{>{\collectcell\unit}c<{\endcollectcell}} +\end{LaTeXdemo} +or +\begin{LaTeXdemo}[code only] + \usepackage{collcell} + \newcolumntype{s}{>{\collectcell\si}c<{\endcollectcell}} +\end{LaTeXdemo} + +If you are using \opt{table-column-width} to have fixed-width columns, you +also now need \opt{table-fixed-width} to set this option active. + +\section{Localisation} + +The \pkg{translations} package provides a structured framework for localisation +of words and phrases, and is part of the larger \pkg{beamer} bundle. The +\pkg{translations} package provides the \cs{translate} macro, which will provide +appropriate translations based on the current \pkg{babel} or \pkg{polyglossia} +language setting. + +If \pkg{translations} is available, \pkg{siunitx} will load it and alter the +standard settings for the \opt{list-final-separator} and \opt{range-phrase} +options to read: +\begin{LaTeXdemo}[code only] + \sisetup{ + list-final-separator = { \GetTranslation{and} }, + list-pair-separator = { \GetTranslation{and} }, + range-phrase = { \GetTranslation{to (numerical range)} }, + } +\end{LaTeXdemo} +If the current language is known to the \pkg{translator} package then the +result will be localised text. The preamble for this manual loads English, +French, German and Spanish as options, and also loads the \pkg{babel} package: +\begin{LaTeXdemo} + % In English by default + \numlist{1;2;3} \\ + \numrange{1}{10} \\ + \selectlanguage{french}% + \numlist{1;2;3} \\ + \numrange{1}{10} \\ + \selectlanguage{german}% + \numlist{1;2;3} \\ + \numrange{1}{10} \\ + \selectlanguage{spanish}% + \numlist{1;2;3} \\ + \numrange{1}{10} +\end{LaTeXdemo} + +\section{Compatibility with other packages} + +In general, \pkg{siunitx} should be usable with other packages without +interference. + +When the \pkg{physics} package is loaded before \pkg{siunitx}, the command +\cs{qty} is not defined: users will need to use the version~$2$ command +\cs{SI}. + +\section{Hints for using \pkg{siunitx}} + +\subsection{Ensuring text or math output% + \label{sec:hint:text-math}} + +The macros \cs{ensuremath} and \cs{text} should be used to ensure that a +particular item is always printed in the desired mode. Some mathematical output +does not work well in \cs{mathrm} (the font setting used by \pkg{siunitx} for +printing units). The easiest way to solve this is to use the construction +"\text{\ensuremath{...}}", which will print the material in the standard +mathematics font without affecting the rest of the output. In some cases, +simply forcing \cs{mathnormal} will suffice, but this is less reliable with +non-Latin characters. + +\subsection{Expanding content in tables% + \label{sec:hint:expanding}} + +When processing tables, \pkg{siunitx} will expand anything stored inside a +macro, unless it is long or protected. \LaTeXe{} robust commands are also +detected and are not expanded (Table~\ref{tab:xmpl:macro}). Values which would +otherwise be expanded can be protected by wrapping them in a set of braces. As +\TeX{} itself will expand the first token in a table cell before \pkg{siunitx} +can act on it, using the \eTeX{} protected mechanism is the recommended course +of action to prevent expansion of macros in table cells. (As is shown in the +table, \TeX's expansion of \LaTeXe{} robust commands can lead to unexpected +results.) +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Values as macros in \texttt{S} columns.% + \label{tab:xmpl:macro}} + \newcommand*\myvaluea{1234} + \newcommand\myvalueb{1234} + \DeclareRobustCommand*\myvaluec{1234} + \protected\def\myvalued{1234} + \begin{tabular}{@{}S@{}} + \toprule + {Some Values} \\ + \midrule + \myvaluea 8.8 \myvaluea \\ % Both expanded + \myvalueb 8.8 \myvalueb \\ % First expanded by TeX + % to numbers + \myvaluec 8.8 \myvaluec \\ % First expanded by TeX + % but not to numbers! + \myvalued 8.8 \myvalued \\ % Neither expanded + {\myvaluea\ 8.8 \myvaluea} \\ % Neither expanded + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +It is possible to use calculated values in tables. For this to work, the +calculation must take place before attempting to parse the number (the parser +cannot \enquote{know} all of the possible values inside an expression). This is +most conveniently handled using the \pkg{xfp} package, which is distributed as +part of the required support for \pkg{siunitx}. The general approach is +illustrated in Table~\ref{tab:xmpl:calc} +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Calculated values.% + \label{tab:xmpl:calc}} + \newcommand{\valuea}{66.7012} + \newcommand{\valueb}{66.0212} + \newcommand{\valuec}{64.9026} + \begin{tabular}{ + @{} + S[table-format = 2.4] + S[table-format = 3.4] + @{} + } + \toprule + {Value} & {Doubled} \\ + \midrule + \valuea & \fpeval{\valuea * 2} \\ + \valueb & \fpeval{\valueb * 2} \\ + \valuec & \fpeval{\valuec * 2} \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +A more sophisticated approach is to generate the rows themselves from a +database: this is illustrated in Section~\ref{sec:hint:datatool}. + +\subsection{Using \pkg{siunitx} with \pkg{datatool}% + \label{sec:hint:datatool}} + +As illustrated in Table~\ref{tab:xmpl:calc}, \pkg{siunitx} can be used to +typeset data stored using \pkg{datatool}. For quickly displaying the contents +of tables, \pkg{datatool} offers the \cs{DTLshowtable} macro. This will only +work with \texttt{S} columns if number parsing is turned off +(Table~\ref{tab:xmpl:datatool}). +\begin{LaTeXdemo}[code and float] + \DTLnewdb{moredata} + \DTLnewrow{moredata}\DTLnewdbentry{moredata}{value}{ 6.7012} + \DTLnewrow{moredata}\DTLnewdbentry{moredata}{value}{66.0212} + \DTLnewrow{moredata}\DTLnewdbentry{moredata}{value}{64.902 } + \begin{table} + \caption{Displaying a \textsf{datatool} table.% + \label{tab:xmpl:datatool}} + \sisetup{parse-numbers= false, table-format = 2.4} + \renewcommand*\dtlrealalign{S} + \DTLdisplaydb{moredata} + \end{table} +\end{LaTeXdemo} + +The \pkg{datatool} package may also be used to create on-the-fly tables using +calculations. For example, the demonstration in Table~\ref{tab:xmpl:calc} may +be achieved without needing to write out each row, as shown in +Table~\ref{tab:xmpl:datatool-calc}. An extra column is used to contain the +calculations in this case. +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Calculated values using \pkg{datatool}.% + \label{tab:xmpl:datatool-calc}} + \DTLnewdb{data} + \DTLnewrow{data}\DTLnewdbentry{data}{value}{66.7012} + \DTLnewrow{data}\DTLnewdbentry{data}{value}{66.0212} + \DTLnewrow{data}\DTLnewdbentry{data}{value}{64.9026} + \begin{tabular}{ + @{} + S[table-format = 2.4] + S[table-format = 3.4] + @{}l + @{} + } + \toprule + {Value} & {Doubled} & + \DTLforeach{data}{\myvalue=value}{% + \DTLiffirstrow {\\ \midrule}{\\}% + \myvalue & % First column + \fpeval{\myvalue * 2} % second column + & }\\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\subsection{Using units in section headings and bookmarks% + \label{sec:hint:bookmarks}} + +The \pkg{siunitx} code is designed to work correctly with functions in +headings. They will print correctly in headings and in the table of contents. +As illustrated here, the standard behaviour is to ignore font changes. When the +\pkg{hyperref} package is loaded, the functions automatically \enquote{degrade +gracefully} to produce useful information in \acro{pdf} bookmarks. If you want +more control over the bookmark text, use the \cs{texorpdfstring} function from +\pkg{hyperref}, for example: +\begin{LaTeXdemo}[code only] + \section{Some text + \texorpdfstring + {\unit{\joule\per\mole\per\kelvin}} + {J mol-1 K-1}% + } +\end{LaTeXdemo} + +You may find it useful to load \pkg{hyperref} with the \opt{unicode} option, +as this will allow \unit{\ohm} to appear in bookmarks. Without the option, +the encoding used by \pkg{hyperref} does not support this symbol. + +\subsection{A left-aligned column visually centred under a heading% + \label{sec:hint:left-column}} + +When you have a column of non-related numbers, the usual advice is to make +these left-aligned and then centre the resulting column under the heading. With +the \pkg{dcolumn} package, that would be done with something like +|D{x}{}{5.0}|. This is something of an abuse of the nature of a number, but can +also be done using \pkg{siunitx} (Table~\ref{tbl:xmpl:unrel}). +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Formatting unrelated numbers.% + \label{tbl:xmpl:unrel}} + \centering + \begin{tabular} + { + @{} + S[ + table-format = 5.0, + parse-numbers = false, + input-digits = .0123456789, + input-decimal-markers = x + ] + @{} + } + \toprule + \multicolumn{1}{@{}c@{}}{Header} \\ + \midrule + 120 \\ + 12.3 \\ + 12340 \\ + 12.02 \\ + 123 \\ + 1 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\subsection{Maximising performance% + \label{sec:hint:performance}} + +Both the number and unit parsers require significant effort in terms of \TeX{} +programming. For input that does not require such processing, the maximum +performance for \pkg{siunitx} can therefore be obtained by turning off both +systems: +\begin{LaTeXdemo} + \qty{7.3}{\Hz} \\ + \qty[parse-units = false]{7.3}{\Hz} \\ + \qty[ + parse-numbers = false, + parse-units = false + ]{7.3}{\Hz} +\end{LaTeXdemo} + +\subsection{Special considerations for the \cs{kWh} unit% + \label{sec:hint:kWh}} + +The standard settings provide the \cs{kWh} unit set up with no spacing between +the \enquote{\unit{\kilo\watt}} and the \enquote{\unit{\hour}} unit to give +\enquote{\unit{\kWh}}. However, this only applies when the unit is given on its +own: combinations will follow the normal rules +\begin{LaTeXdemo} + \unit{\kWh} \\ + \unit{\kWh\per\metre} +\end{LaTeXdemo} +This is because the unit \cs{kWh} is defined so that it can still be varied by +altering \cs{kilo}, \cs{watt} and \cs{hour}, and so that the prefix can still +be turned into a number. However, some users may prefer to have a non-flexible +macro which never adds a space. This can be achieved by redefining \cs{kWh} +with \cs{DeclareSIUnit}, by added an alternative definition +\begin{LaTeXdemo}[code only] + \DeclareSIUnit\kWh{kWh} + \DeclareSIUnit\KWH{kWh} +\end{LaTeXdemo} + or of course by using literal unit input. +\begin{LaTeXdemo} + \unit{\KWH\per\metre}\\ + \unit{kWh.m^{-1}} +\end{LaTeXdemo} + +Another point to notice is that the \cs{per} macro applies to the next unit, +and not an entire unit combination. Thus in +\begin{LaTeXdemo} + \unit{\candela\per\kWh} +\end{LaTeXdemo} +\cs{per} applies to the watts but not to the hours. In this case, the units +need to be written out in full or the \opt{sticky-per} option should be used. +\begin{LaTeXdemo} + \unit{\candela\per\kilo\watt\per\hour} \\ + \unit[sticky-per]{\candela\per\kWh} +\end{LaTeXdemo} + +\subsection{Creating a column with numbers and units% + \label{sec:hint:mixed}} + +Usually, numbers in a table should be given with the units in the column +heading. However, there are cases where a series of data are best presented in +a table but have different units. There are two ways to do this +(Table~\ref{tab:xmpl:mixed}). The first is to place the units in the first +column of the table, which makes sense if there are several related items in +the table. The second method is to generate two columns, one for numbers and a +second for units, and then to format these to give the visual effect of a +single column. The later effect is most appropriate when only one set of +numbers are presented in a table. This method requires cell content is +collected, easiest to do using the \pkg{collcell} package. +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Tables where numbers have different units.% + \label{tab:xmpl:mixed}} + \hfil + \begin{tabular} + { + @{} + >{$}l<{$} + S[table-format = 3.3(1)] + S[table-format = 3.3(1)] + @{} + } + \toprule + & {One} & {Two} \\ + \midrule + a / \unit{\pm} & 123.4(2) & 567.8(4) \\ + \beta / \unit{\degree} & 90.34(4) & 104.45(5) \\ + \mu / \unit{\per\mm} & 0.532 & 0.894 \\ + \bottomrule + \end{tabular} + \hfil + \begin{tabular} + { + @{} + S[table-format=1.3]@{\,} + >{\collectcell\unit}l<{\endcollectcell} + @{} + } + \toprule + \multicolumn{2}{@{}c}{Heading} \\ + \midrule + 1.234 & \metre \\ + 0.835 & \candela \\ + 4.23 & \joule\per\mole \\ + \bottomrule + \end{tabular} + \hfil + \end{table} +\end{LaTeXdemo} + +\subsection{Tables with heading rows% + \label{sec:hint:heading}} + +A common format for tables is to make the heading row visually distinct using a +background color and bold text. If numbers appear in such a heading row within +an \texttt{S} column then getting the appearance right can be challenging. The +best approach is to make the \cs{bfseries} macro \enquote{robust} (as +demonstrated in Section~\ref{sec:hint:expanding}), then to use this macro to +make the heading cells bold. This approach is illustrated in +Table~\ref{tab:xmpl:headers}, along with the use of \cs{rowcolor} to provide a +background color. +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Header row in a table.% + \label{tab:xmpl:headers}} + \robustify\bfseries + \centering + \begin{tabular} + {@{}S[text-series-to-math, table-format = 3.3]@{}} + \rowcolor[gray]{0.9} + \bfseries 123.456 \\ + 23.45 \\ + 123.4 \\ + 3.456 \\ + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\subsection{Associating a locale with a \pkg{babel} language% + \label{sec:hint:babel}} + +It is possible to instruct the \pkg{babel} package to switch to a particular +\pkg{siunitx} locale when changing language. This can be done using the +\pkg{babel} \cs{extras\meta{language}} system. For example, to associate the +\texttt{DE} locale with the \texttt{german} \pkg{babel} language, the +appropriate code would be +\begin{LaTeXdemo}[code only] + \addto\extrasgerman{\sisetup{locale = DE}} +\end{LaTeXdemo} + +\section{Using (\acro{SI}) units} + +Consistent and logical units are a necessity for scientific work, and have +applicability everywhere. Historically, a number of systems have been used for +physical units. \acro{SI} units were introduced by the \foreign{Conférence +Générale des Poids et Mesures} (\acro{CGPM}) in 1960. \acro{SI} units are a +coherent system based on seven base units, from which all other units may be +derived. + +At the same time, physical quantities with units are mathematical entities, and +as such way that they are typeset is important. In mathematics, changes of type +(such as using bold, italic, sans serif typeface and so on) convey information. +This means that rules exist not only for the type of units to be used under the +\acro{SI} system, but also the way they should appear in print. Advice on best +practice has been made available by the \emph{National Institute of Standards +and Technology} (\acro{NIST})~\cite{NIST}. + +As befits an agreed international standard, the full rules are detailed. It is +not appropriate to reproduce these in totality here; instead, a useful summary +of the key points is provided. The full details are available from the +\foreign{Bureau International des Poids et Mesures}~\cite{BIPM}. + +The \pkg{siunitx} package takes account of the information given here, so far +as is possible. Thus the package defaults follow the recommendations made for +typesetting numbers and units. Spacing and so forth is handled in such a way as +to make implementing the rules (relatively) easy. + +\subsection{Units} + +There are seven base \acro{SI} units, listed in Table~\ref{tab:unit:base}.% +\footnote{Some base units need others defined first; there is therefore a +required order of definition.} The base units have been chosen such that all +physical quantities can be expressed using an appropriative combination of +these units, needing no others and with no redundancy. + +All other units within the \acro{SI} system are regarded as \enquote{derived} +from the seven base units. At the most basic, all other \acro{SI} units can be +expressed as combinations of the base units. However, many units (listed in +Tables~\ref{tab:unit:derived} and~\ref{tab:unit:accepted}) have a special name +and symbol. Most of these units are simple combinations of one or more base +units (raised to powers as appropriate). + +A series of \acro{SI} prefixes for decimal multiples and sub-multiples are +provided, and can be used as modifiers for any \acro{SI} unit (either base or +derived units) with the exception of the kilogram. The prefixes are listed in +Table~\ref{tab:unit:prefix}. No space should be used between a prefix and the +unit, and only a single prefix should be used. Even the degree Celsius can be +given a prefix, for example \qty{1}{\milli\degreeCelsius}. + +It is important to note that the kilogram is the only \acro{SI} unit with a +prefix as part of its name and symbol. Only single prefix may be used, and so +in the case of the kilogram prefix names are used with the unit name +\enquote{gram} and the prefix symbols are used with the unit symbol +\unit{\gram}. For example $\qty{1e-6}{\kilo\gram} = \qty{1e-3}{\gram} = +\qty{1}{\milli\gram}$. + +The application of \acro{SI} units is meant to provide a single set of units +which ensure consistency and clarity across all areas. However, other units are +common is many areas, and are not without merit. The units provided by +\pkg{siunitx} by default do not include any of these; only units which are part +of the \acro{SI} set or are accepted for use with \acro{SI} units are defined. +However, several other sets of units can be loaded as optional modules. The +binary prefixes and units (Table~\ref{tab:unit:binary}) are the most obvious +example. These are \emph{not} part of the \acro{SI} specifications, but the +prefix names are derived from those in Table~\ref{tab:unit:prefix}. + +Other units are normally to be avoided where possible. \acro{SI} units should, +in the main, be preferred due to the advantages of clear definition and +self-consistency this brings. However, there will probably always be a place +for specialist or non-standard units. This is particularly true of units +derived from basic physical constants. + +There are also many areas where non-standard units are used so commonly that to +do otherwise is difficult or impossible. For example, most synthetic chemists +measure the pressure inside vacuum apparatus in \unit{\millimetremercury}, +partly because the most common gauge for the task still uses a column of +mercury metal. For these reasons, \pkg{siunitx} allows definition of such +units. + +\subsection{Mathematical meaning} + +As explained earlier, a quantity combination is a single mathematical entity. +This has implications for how both the number and the unit should be printed. +Firstly, the two parts should not be separated: a quantity is a product of the +number and the unit. With the exception of the symbols for plane angles +(\unit{\degree}, \unit{\arcminute} and \unit{\arcsecond}), the \acro{BIPM} +specifies either a space or half-height (centred) dot should be +used~\cite{BIPM}. +\begin{LaTeXdemo} + A space for \qty{10}{\percent}\\ + and also for \qty{100}{\degreeCelsius}\\ + but not for \ang{1.23}. +\end{LaTeXdemo} + +The mathematical meaning of units also means that the shape, weight and family +are important. Units are supposed to be typeset in an upright, medium weight +font. Italic, bold and sans serif are all used mathematically to convey other +meanings. (In an all sanserif document, using sans serif for units is +reasonable.) The \pkg{siunitx} package defaults again follow this convention: +any local settings are ignored, and uses the current upright math font. +However, there are occasions where this may not be the most desirable +behaviour. A classic example would be in an all-bold section heading. As the +surrounding text is bold, some people feel that any units should follow this. +\begin{LaTeXdemo} + Units should \textbf{not be bold: \qty{54}{\farad}}\\ + \textbf{But perhaps in a running block,\\ + it might look better: + \qty[text-series-to-math]{54}{\farad}} +\end{LaTeXdemo} + +Symbols for units formed from other units by multiplication are indicated by +means of either a half-height (that is, centred) dot or a (thin) space. +\begin{LaTeXdemo} + $\unit{\metre\second} = \text{metre second}$ \\ + $\unit{\milli\second} = \text{millisecond}$ \\ + \sisetup{inter-unit-product = \ensuremath { { } \cdot { } } } + $\unit{\metre\second} = \text{metre second}$ \\ + $\unit{\milli\second} = \text{millisecond}$ +\end{LaTeXdemo} +There are some circumstances under which it is common practice to omit any +spaces. The classic example is \unit{\kWh}, where +\enquote{\unit[inter-unit-product = \,]{\kWh}} does not add any useful +information. If using such a unit repeatedly, users of \pkg{siunitx} are +advised to create a custom unit to ensure consistency. It is important to note +that while this is common practice, it is \emph{not} allowed by the +\acro{BIPM}~\cite{BIPM}. + +Symbols for units formed from other units by division are indicated by means of +a virgule (oblique stroke, slash, "/"), a horizontal line, or negative +exponents.\footnote{Notice that a virgule and a solidus are not the same +symbol.} However, to avoid ambiguity, the virgule must not be repeated on the +same line unless parentheses are used. This is ensured when using named unit +macros in \pkg{siunitx}, which will \enquote{trap} repeated division and format +it correctly. In complicated cases, negative exponents are to be preferred over +other formats. +\begin{LaTeXdemo} + \unit{\joule\per\mole\per\kelvin} \\ + \unit[per-mode = fraction]{\joule\per\mole\per\kelvin} \\ + \unit[per-mode = symbol]{\joule\per\mole\per\kelvin} +\end{LaTeXdemo} + +Products and errors should show what unit applies to each number given. Thus +\qtyproduct[product-units = bracket]{2x3}{\metre} is an ordered set of lengths +of a geometric area, whereas \qtyproduct[product-units = single]{2x3}{\metre} +is a length (and equal to \qty{6}{\metre}). Thus, $\times$ is not a product but +is a mathematical operator; in the same way, a $2 \times 3$ matrix is not a $6$ +matrix! In some areas, areas and volumes are given with separated units but a +unit raised to the appropriate power: \qtyproduct[product-units = power]{2 x +3}{\metre}. Although this does display the correct overall units, it is +potentially-confusing and is not encouraged. + +Care must be taken when writing ranges of numbers. For purely numerical values, +it is common to use a en-dash to show a range, for example \enquote{see pages +1--5}. On the other hand, physical quantities could be misinterpret as negative +values if written in this way. As the quantity is a single mathematical entity, +writing the values with an en-dash followed by a single unit is also incorrect. +As a result, using the word \enquote{to} is strongly recommended. +\begin{LaTeXdemo} + \qtyrange{1}{5}{\metre} long. +\end{LaTeXdemo} + +\subsection{Graphs and tables} + +In graphs and tables, repetition of the units following each entry or axis mark +is confusing and repetitive. It is therefore best to place the unit in the +label part of the information. Placing the unit in square brackets is common +but mathematically poor.\footnote{For example, for an acceleration \(a\), the +expression $[a]$ is the dimensions of $a$, \foreign{i.e.}~length per time +squared in this case.} Much better is to show division of all quantities by the +unit, which leaves the entries as unitless ratios. This is illustrated in +Tables~\ref{tab:xmpl:unitless} and~\ref{fig:xmpl:unitless}. +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{An example of table labelling.% + \label{tab:xmpl:unitless}} + \sisetup{ + table-number-alignment = center, + table-format = 1.4 + } + \begin{tabular}{@{}cS@{}} + \toprule + Entry & {Length/\unit{\metre}} \\ + \midrule + 1 & 1.1234 \\ + 2 & 1.1425 \\ + 3 & 1.7578 \\ + 4 & 1.9560 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} +\begin{LaTeXdemo}[code and float] + \begin{figure} + \begin{tikzpicture} + \begin{axis}[ + xlabel = $t/\unit{\second}$, + xmax = 6, + xmin = 0, + ylabel = $d/\unit{\metre}$, + ymin = 0 + ] + \addplot[smooth,mark=*] + plot coordinates { + (0,0) + (1,5) + (2,8) + (3,9) + (4,8) + (5,5) + (6,0) + }; + \end{axis} + \end{tikzpicture} + \caption{An example of graph labelling.% + \label{fig:xmpl:unitless}} + \end{figure} +\end{LaTeXdemo} + + In most cases, adding exponent values in the body of a table is + less desirable than adding a fixed exponent to column headers. An + example is shown in Table~\ref{tab:good}. The use of \cs{multicolumn} is + needed here due to the \enquote{\texttt{<}}; without \cs{multicolumn}, + the titles are followed by \enquote{\unit{\kilo\gram}}! +\begin{LaTeXdemo}[code and float] + \begin{table} + \caption{Good and bad columns.% + \label{tab:good}} + \sisetup{table-number-alignment = center} + \begin{tabular}{ + @{} + c + S[table-format = 1.3e1] + @{\,\unit{\kilogram}} + S[table-format = 2.2] + @{} + } + \toprule + Entry & \multicolumn{1}{c}{Mass} & + {Mass/\qty[print-unity-mantissa = false]{e3}{\kilogram}} \\ + \midrule + 1 & 4.56e3 & 4.56 \\ + 2 & 2.40e3 & 2.40 \\ + 3 & 1.345e4 & 13.45 \\ + 4 & 4.5e2 & 0.45 \\ + \bottomrule + \end{tabular} + \end{table} +\end{LaTeXdemo} + +\section{Installation} + +For most users, there will be no need to explicitly install \pkg{siunitx}: +it is available from the package management system in current \TeX{} Live +and MiK\TeX{} systems. + +For manual installation, the package is available from +\href{http://ctan.org/pkg/siunitx}{\acro{CTAN}}. As well as the raw source +files, \acro{CTAN} hold the package as a pre-extracted zip file, +\file{siunitx.tds.zip}. The later is most convenient for most users: simply +unzip this in your local \path{texmf} directory. + +The package requires \LaTeX3 support as provided in the \pkg{l3kernel} and +\pkg{l3packages} bundles. Both of these are included in \TeX{} Live and +MiK\TeX{}, or are again available in ready-to-install form from \acro{CTAN}. + +\section{Thanks} + +Many users have provided feedback, bug reports and ideas for new features for +\pkg{siunitx}: thanks to all of them. Particular thanks to Stefan Pinnow, who +has taken the lead role as beta tester for \pkg{siunitx}, finding incorrect +output, bad documentation and the odd spelling mistake in the documentation. +Thanks also to Enrico Gregorio for encouraging me to complete a fully +\pkg{expl3}-compliant version of the package. Thanks also to Danie Els and +Marcel Heldoorn for the \pkg{SIstyle} and \pkg{SIunits} packages, respectively, +which provided the starting point for the development of \pkg{siunitx}. + +\section{Making suggestions and reporting bugs} + +Feedback on \pkg{siunitx} is always welcome, either to make suggestions or to +report problems. When sending feedback, it is always useful if a small example +file is included, showing the bug being reported or illustrating the desired +output. It is helpful if a \enquote{reference rendering} is included, showing +what the output should look like. A typical example file might read +\begin{verbatim} + \listfiles + % Use the article class unless the problem is class-dependent + \documentclass{article} + \usepackage{siunitx} + % Other packages loaded as required + \begin{document} + Reference output: $1.23\,\mathrm{m}$ + + \textsf{siunitx} output: \qty{1.23}{\metre} + \end{document} +\end{verbatim} +As illustrated, it is usually best to use the \cls{article} class and to only +load packages which are needed to show the issue. It is also useful to include +a copy of the log file generate by \LaTeX{} when reporting a bug (as the +versions of packages can be important to solving the issue). + +Feedback can be sent in a range of ways. The development code and issue tracker +are hosted on \href{https://github.com/josephwright/siunitx/}{GitHub}. Issues +opened there are visible to other users and makes sure that they cannot be +forgotten. + +\end{documentation} + +\begin{thebibliography}{10} + \bibitem{BIPM} + \emph{The International System of Units (\acro{SI})}, + \url{https://www.bipm.org/en/measurement-units/}. + \bibitem{NIST} + \emph{International System of Units from \acro{NIST}}, + \url{http://physics.nist.gov/cuu/Units/index.html}. +\end{thebibliography} + +\PrintIndex + +\end{document} |