texlive[59239] Master/texmf-dist: siunitx (17may21)

commits+karl at tug.org commits+karl at tug.org
Mon May 17 22:38:22 CEST 2021


Revision: 59239
          http://tug.org/svn/texlive?view=revision&revision=59239
Author:   karl
Date:     2021-05-17 22:38:21 +0200 (Mon, 17 May 2021)
Log Message:
-----------
siunitx (17may21)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/siunitx/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/siunitx/README.md
    trunk/Master/texmf-dist/doc/latex/siunitx/siunitx.pdf
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx.dtx
    trunk/Master/texmf-dist/tex/latex/siunitx/siunitx-binary.cfg
    trunk/Master/texmf-dist/tex/latex/siunitx/siunitx-version-1.cfg
    trunk/Master/texmf-dist/tex/latex/siunitx/siunitx.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/latex/siunitx/siunitx-code.pdf
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-abbreviation.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-angle.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-binary.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-code.tex
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-command.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-complex.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-compound.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-emulation.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-locale.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-quantity.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-symbol.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx-unit.dtx
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx.ins
    trunk/Master/texmf-dist/source/latex/siunitx/siunitx.tex
    trunk/Master/texmf-dist/tex/latex/siunitx/siunitx-v2.sty

Removed Paths:
-------------
    trunk/Master/texmf-dist/tex/latex/siunitx/siunitx-abbreviations.cfg

Modified: trunk/Master/texmf-dist/doc/latex/siunitx/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/siunitx/CHANGELOG.md	2021-05-17 20:37:11 UTC (rev 59238)
+++ trunk/Master/texmf-dist/doc/latex/siunitx/CHANGELOG.md	2021-05-17 20:38:21 UTC (rev 59239)
@@ -7,16 +7,197 @@
 
 ## [Unreleased]
 
+## [v3.0.0]
+
+### Added
+- `\complexnum`
+- `\complexqty`
+- `\qty`
+- `\qtylist`
+- `\qtypower`
+- `\qtylist`
+- Option `allow-quantity-breaks`
+- Option `angle-mode`
+- Option `angle-separator`
+- Option `angle-symbol-degree`
+- Option `angle-symbol-minute`
+- Option `angle-symbol-second`
+- Option `drop-exponent`
+- Option `drop-uncertainty`
+- Option `drop-zero-decimal`
+- Option `evaluate-expression`
+- Option `exponent-mode`
+- Option `expression`
+- Option `fill-angle-degrees`
+- Option `fill-angle-minutes`
+- Option `fill-angle-seconds`
+- Option `fraction-command`
+- Option `list-exponents`
+- Option `minimum-decimal-digits`
+- Option `minimum-integer-digits`
+- Option `overwrite-commands`
+- Option `prefix-mode`
+- Option `print-implicit-plus`
+- Option `print-unity-mantissa`
+- Option `print-zero-exponent`
+- Option `product-exponents`
+- Option `product-mode`
+- Option `product-phrase`
+- Option `product-symbol`
+- Option `qualifier-phrase`
+- Option `quantity-product`
+- Option `range-exponents`
+- Option `round-pad`
+- Option `number-angle-product`
+- Option `propagate-math-font`
+- Option `reset-math-version`
+- Option `reset-text-family`
+- Option `reset-text-series`
+- Option `reset-text-shape`
+- Option `separate-uncertainty-units`
+- Option `series-version-mapping`
+- Option `table-align-text-after`
+- Option `table-align-text-before`
+- Option `table-alignment-mode`
+- Option `table-column-type`
+- Option `text-family-to-math`
+- Option `text-series-to-math`
+- Option `uncertainty-mode`
+- Option `unit-font-command`
+- Option setting `list-mode = bracket`
+- Option setting `mode = match`
+- Option setting `number-mode = match`
+- Option setting `per-mode = power-positive-first`
+- Option setting `qualifier-mode = bracket`
+- Option setting `qualifier-mode = phrase`
+- Option setting `qualifier-mode = combine`
+- Option setting `product-mode = bracket`
+- Option setting `range-mode = bracket`
+- Option setting `text-mode = match`
+- Option setting `unit-mode = match`
+
+### Changed
+- Modular re-write to provide code-level API
+- Update unit support to 9th edition of SI Brochure
+
+### Deprecated
+- `\DeclareSIPrePower`
+- `\DeclareSIPostPower`
+- `\SIUnitSymbolAngstrom`
+- `\SIUnitSymbolArcminute`
+- `\SIUnitSymbolArcsecond`
+- `\SIUnitSymbolCelsius`
+- `\SIUnitSymbolDegree`
+- `\SIUnitSymbolMicro`
+- `\SIUnitSymbolOhm`
+- Option `add-decimal-zero`
+- Option `allow-number-unit-break`
+- Option `add-arc-degree-zero`
+- Option `add-arc-minute-zero`
+- Option `add-arc-second-zero`
+- Option `arc-separator`
+- Option `explicit-sign`
+- Option `extract-mass-in-kilograms`
+- Option `fraction-function`
+- Option `omit-uncertainty`
+- Option `overwrite-functions`
+- Option `multi-part-units`
+- Option `number-angle-product`
+- Option `number-unit-product`
+- Option `prefixes-as-symbols`
+- Option `retain-unity-mantissa`
+- Option `retain-zero-uncertainty`
+- Option `retain-zero-exponent`
+- Option `scientific-notation`
+- Option `separate-uncertainty`
+- Option `table-align-text-post`
+- Option `table-align-text-pre`
+- Option `table-comparator`
+- Option `table-figures-decimal`
+- Option `table-figures-exponent`
+- Option `table-figures-integer`
+- Option `table-figures-uncertainty`
+- Option `table-omit-exponent`
+- Option `table-parse-only`
+- Option `table-sign-exponent`
+- Option `table-sign-mantissa`
+- Option `table-space-text-post`
+- Option `table-space-text-pre`
+- Option `text-font-command`
+- Option `zero-decimal-to-integer`
+- Option setting `list-units = brackets`
+- Option setting `per-mode = reciprocal`
+- Option setting `per-mode = reciprocal-positive-first`
+- Option setting `qualifier-mode = brackets`
+- Option setting `qualifier-mode = space`
+- Option setting `qualifier-mode = text`
+- Option setting `product-mode = brackets`
+- Option setting `range-units = brackets`
+- Option setting `table-number-alignment = center-decimal-marker`
+
+### Removed
+- Option `abbreviations`
+- Option `add-integer-zero`
+- Option `binary-units`
+- Option `close-bracket`
+- Option `detect-all`
+- Option `detect-display-math`
+- Option `detect-family`
+- Option `detect-inline-family`
+- Option `detect-inline-weight`
+- Option `detect-mode`
+- Option `detect-none`
+- Option `detect-shape`
+- Option `detect-weight`
+- Option `input-protect-tokens`
+- Option `input-quotient`
+- Option `literal-superscript-as-power`
+- Option `open-bracket`
+- Option `quotient-mode`
+- Option `math-angstrom`
+- Option `math-arcminute`
+- Option `math-arcsecond`
+- Option `math-celsius`
+- Option `math-degree`
+- Option `math-micro`
+- Option `math-ohm`
+- Option `math-rm`
+- Option `math-sf`
+- Option `math-tt`
+- Option `redefine-symbols`
+- Option `number-math-rm`
+- Option `number-math-sf`
+- Option `number-math-tt`
+- Option `number-text-rm`
+- Option `number-text-sf`
+- Option `number-text-tt`
+- Option `table-unit-alignment`
+- Option `text-angstrom`
+- Option `text-arcminute`
+- Option `text-arcsecond`
+- Option `text-celsius`
+- Option `text-degree`
+- Option `text-micro`
+- Option `text-ohm`
+- Option `text-rm`
+- Option `text-sf`
+- Option `text-tt`
+- Option `unit-math-rm`
+- Option `unit-math-sf`
+- Option `unit-math-tt`
+- Option `unit-text-rm`
+- Option `unit-text-sf`
+- Option `unit-text-tt`
+- Option `version-1-compatibility`
+
 ## [v2.8e] - 2021-04-17
 
 ### Fixed
-
 - Missing setting in emulation of v1 option `repeatunits`
 
 ## [v2.8d] - 2021-04-09
 
 ### Changed
-
 - Correct file dates for configuration files
 
 ## [v2.8c] - 2021-03-27
@@ -326,7 +507,7 @@
 - Option name wrong in v1 table (issue #240)
 - Use `\textpm` in text mode if `textcomp` package is loaded (issue #249)
 - Ignore hard spaces in `\num` (issue #256)
-- Use `\mathord for tight spacing on 'in line' exponent (issue #257)
+- Use `\mathord` for tight spacing on 'in line' exponent (issue #257)
 
 ## [v2.5s] - 2013-07-31
 
@@ -479,7 +660,7 @@
 ## [v2.4k] - 2012-03-22
 
 ### Fixed
-- Interaction of `^` and `_` with `brenw (issue #191)
+- Interaction of `^` and `_` with `breqn` (issue #191)
 - Adapted `list-pair-separator` for `translator` package (issue #190)
 - Check for `round-minimum` with large values
 
@@ -1058,7 +1239,9 @@
 ### Added
 - First public testing release (as `si`)
 
-[Unreleased]: https://github.com/josephwright/siunitx/compare/v2.8d...stable
+[Unreleased]: https://github.com/josephwright/siunitx/compare/v3.0.0...HEAD
+[v3.0.0]: https://github.com/josephwright/siunitx/compare/v2.8e...v3.0.0
+[v2.8e]: https://github.com/josephwright/siunitx/compare/v2.8d...v2.8e
 [v2.8d]: https://github.com/josephwright/siunitx/compare/v2.8c...v2.8d
 [v2.8c]: https://github.com/josephwright/siunitx/compare/v2.8b...v2.8c
 [v2.8b]: https://github.com/josephwright/siunitx/compare/v2.8a...v2.8b

Modified: trunk/Master/texmf-dist/doc/latex/siunitx/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/siunitx/README.md	2021-05-17 20:37:11 UTC (rev 59238)
+++ trunk/Master/texmf-dist/doc/latex/siunitx/README.md	2021-05-17 20:38:21 UTC (rev 59239)
@@ -1,5 +1,5 @@
 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
@@ -15,41 +15,3 @@
 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`
\ No newline at end of file

Added: trunk/Master/texmf-dist/doc/latex/siunitx/siunitx-code.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/siunitx/siunitx-code.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/siunitx/siunitx-code.pdf	2021-05-17 20:37:11 UTC (rev 59238)
+++ trunk/Master/texmf-dist/doc/latex/siunitx/siunitx-code.pdf	2021-05-17 20:38:21 UTC (rev 59239)

Property changes on: trunk/Master/texmf-dist/doc/latex/siunitx/siunitx-code.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/latex/siunitx/siunitx.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-abbreviation.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-abbreviation.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-abbreviation.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-abbreviation.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-angle.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-angle.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-angle.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-angle.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-binary.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-binary.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-binary.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-binary.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-code.tex
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-code.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-code.tex	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+      {joseph.wright at 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}


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-code.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-command.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-command.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-command.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-command.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-complex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-complex.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-complex.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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 at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-complex.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-compound.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-compound.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-compound.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-compound.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-emulation.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-emulation.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-emulation.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-emulation.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-locale.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-locale.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-locale.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-locale.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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 at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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 at 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 at 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 at 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 at 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 at 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 at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-print.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-quantity.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-quantity.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-quantity.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-quantity.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-symbol.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-symbol.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-symbol.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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 at 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 at 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 at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-symbol.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at morningstar2.co.uk}
+%      {joseph.wright at 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 at unskip     { \@@_collect_loop: }
+                \tab at 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 at 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 at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-unit.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx-unit.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx-unit.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at 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 at morningstar2.co.uk}
+%      {joseph.wright at 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 at 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 at 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 at 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


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx-unit.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/siunitx/siunitx.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx.dtx	2021-05-17 20:37:11 UTC (rev 59238)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx.dtx	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at 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 at 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
+% File: siunitx.dtx Copyright (C) 2008-2019,2021 Joseph Wright
 %
-%^^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}
-%}
+% 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
 %
-%^^A For creating examples with nice highlighting of code, and so
-%^^A on; based on the system used in the listings source (lstsample).
-%\lst at RequireAspects{writefile}
-%\newsavebox{\LaTeXdemo at box}
-%\lstnewenvironment{LaTeXdemo}[1][code and example]
-%  {^^A
-%    \global\let\lst at intname\@empty
-%    \expandafter\let\expandafter\LaTeXdemo at end
-%      \csname LaTeXdemo@#1 at end\endcsname
-%    \@nameuse{LaTeXdemo@#1}^^A
-%  }
-%  {\LaTeXdemo at end}
-%\newcommand*\LaTeXdemo at new[3]{^^A
-%  \expandafter\newcommand\expandafter*\expandafter
-%    {\csname LaTeXdemo@#1\endcsname}{#2}^^A
-%  \expandafter\newcommand\expandafter*\expandafter
-%    {\csname LaTeXdemo@#1 at end\endcsname}{#3}^^A
-%}
-%\newcommand*\LaTeXdemo at 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 at input{^^A
-%  \MakePercentComment
-%  \catcode`\^^M=10\relax
-%  \small
-%  \begingroup
-%    \setkeys{lst}
-%      {
-%        SelectCharTable=\lst at ReplaceInput{\^\^I}{\lst at ProcessTabulator}
-%      }^^A
-%    \leavevmode
-%      \input{\jobname.tmp}^^A
-%  \endgroup
-%  \MakePercentIgnore
-%}
-%\LaTeXdemo at new{code and example}
-%  {^^A
-%    \setbox\LaTeXdemo at box=\hbox\bgroup
-%      \lst at BeginAlsoWriteFile{\jobname.tmp}^^A
-%      \LaTeXdemo at common
-%  }
-%  {^^A
-%      \lst at EndWriteFile
-%    \egroup
-%    \begin{center}
-%      \ifdim\wd\LaTeXdemo at box>0.48\linewidth\relax
-%        \hbox to\linewidth{\box\LaTeXdemo at box\hss}^^A
-%          \begin{minipage}{\linewidth}
-%            \LaTeXdemo at input
-%          \end{minipage}
-%      \else
-%        \begin{minipage}{0.48\linewidth}
-%          \LaTeXdemo at input
-%        \end{minipage}
-%        \hfill
-%        \begin{minipage}{0.48\linewidth}
-%          \hbox to\linewidth{\box\LaTeXdemo at box\hss}^^A
-%        \end{minipage}
-%      \fi
-%    \end{center}
-%  }
-%\LaTeXdemo at new{code and float}{^^A
-%  \lst at BeginAlsoWriteFile{siunitx.tmp}^^A
-%  \LaTeXdemo at common
-%}{^^A
-%  \lst at EndWriteFile
-%  \LaTeXdemo at input
-%}
-%\LaTeXdemo at new{code only}
-%  {\LaTeXdemo at common}{}
+%    https://www.latex-project.org/lppl.txt
 %
-%^^A Turning of the marginpar warnings is a bit awkward.
-%^^A It is achieved by temporarily disabling \@latex at warning@no at line
-%\let\latex at addmarginpar\@addmarginpar
-%\let\latex at warning@no at line\@latex at warning@no at line
-%\def\@addmarginpar{^^A
-%  \let\@latex at warning@no at line\@gobble
-%  \latex at addmarginpar
-%  \let\@latex at warning@no at line\latex at warning@no at line
-%}
+% This file is part of the "siunitx bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
 %
-%\ProvideDocumentCommand\opt{m}{\texttt{#1}}
+% The released version of this bundle is available from CTAN.
 %
-%\makeatother
+% -----------------------------------------------------------------------
 %
-%\GetFileInfo{\jobname.sty}
+% The development version of the bundle can be found at
 %
-%\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 at morningstar2.co.uk}
-%      {\texttt{joseph.wright at morningstar2.co.uk}}^^A
-%    }^^A
-%}
-%\date{Released \filedate}
+%    https://github.com/josephwright/siunitx
 %
-%\maketitle
+% for those people who are interested.
 %
-%\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).
+%<*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
 %
-% 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}
+% \GetFileInfo{siunitx.sty}
 %
-%\tableofcontents
+% \title{^^A
+%   \pkg{siunitx} -- Overall set up^^A
+%   \thanks{This file describes \fileversion,
+%     last revised \filedate.}^^A
+% }
 %
-%\begin{documentation}
+% \author{^^A
+%  Joseph Wright^^A
+%  \thanks{^^A
+%    E-mail:
+%    \href{mailto:joseph.wright at morningstar2.co.uk}
+%      {joseph.wright at morningstar2.co.uk}^^A
+%   }^^A
+% }
 %
-%\section{Introduction}
+% \date{Released \filedate}
 %
-% 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.
+% \maketitle
 %
-% \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.
+% \begin{documentation}
 %
-%\section{Installation}
+% \end{documentation}
 %
-% 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.
+% \begin{implementation}
 %
-% 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.
+% \section{\pkg{siunitx} implementation}
 %
-% 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}
-%
-%\subsection{Numbers with units}
-%
-% Some options apply to the combination of units and numbers, rather
-% than to units or numbers alone (\cref{tab:opt:units:numbers}).
-%
-%\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}
-%
-%\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}
-%
-%\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.
-%
-%\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}
-%
-%\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}
-%
-% \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).
-%
-% 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 at morningstar2.co.uk}
-% {\texttt{joseph.wright at morningstar2.co.uk}}.
-%
-% \section{Code level interfaces}
-%
-% 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.
-%
-% \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}
-%
-%\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
-% 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}.
-%
-%\end{documentation}
-%
-%\begin{implementation}
-%
-%\section{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}
+% \subsection{Initial set up}
 %
-% The usual preliminaries.
 %    \begin{macrocode}
-\ProvidesExplPackage {siunitx} {2021-04-17} {2.8e}
-  {A comprehensive (SI) units package}
+%<*init>
 %    \end{macrocode}
 %
-% 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).
+% Set up a couple of commands in recent-ish \LaTeXe{} releases.
 %    \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
-  }
+\providecommand\DeclareRelease[3]{}
+\providecommand\DeclareCurrentRelease[2]{}
 %    \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.
+% Allow rollback to version~$2$: if we need to, version~$1$ could eventually
+% be added here too.
 %    \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
-}
+\DeclareRelease{2}{2010-05-23}{siunitx-v2.sty}
+\DeclareRelease{v2}{2010-05-23}{siunitx-v2.sty}
+\DeclareCurrentRelease{}{2021-05-17}
 %    \end{macrocode}
-%\end{macro}
 %
-% Now load the support packages.
+% Load only the essential support (\pkg{expl3}) \enquote{up-front}, and
+% only if required.
 %    \begin{macrocode}
-\RequirePackage{ amstext , array , l3keys2e }
+\@ifundefined{ExplFileDate}
+  {\RequirePackage{expl3}}
+  {}
 %    \end{macrocode}
 %
-% \begin{macro}{@@_if_hooks:TF}
-%   To work with updated hooks if available.
+% 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 at 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 }
+\@ifl at 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}
-% \end{macro}
 %
-%\begin{macro}{\@@_tmp:w}
-% A scratch function.
+% Identify the package and give the over all version information.
 %    \begin{macrocode}
-\cs_new:Npn \@@_tmp:w { }
+\ProvidesExplPackage {siunitx} {2021-05-17} {3.0.0}
+  {A comprehensive (SI) units package}
 %    \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}
+% \subsection{Safety checks}
 %
-%\begin{macro}{
-%  \l_@@_tmp_bool ,
-%  \l_@@_tmp_box  ,
-%  \l_@@_tmp_dim  ,
-%  \l_@@_tmp_int  ,
-%  \l_@@_tmpa_tl  ,
-%  \l_@@_tmpb_tl
-%}
-% Scratch variables.
+% \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}
-\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 at 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
+\msg_new:nnnn { siunitx } { incompatible-package }
+  { Package~'#1'~incompatible. }
+  { The~#1~package~and~siunitx~are~incompatible. }
+\cs_new_protected:Npn \@@_load_check:n #1
   {
-    \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 }
-          }
-      }
-}
-}
-%    \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.
-%    \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
-%    \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.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_option_unchanged:Nnn #1#2#3
-  {
-    \str_if_eq:VnT #1 {#2}
-      { \tl_set:Nn #1 {#3} }
-  }
-%    \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 }
-%    \end{macrocode}
-%
-% \begin{macro}[pTF]{\@@_cs_if_tl:N}
-%   A test for token lists (more or less).
-%    \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: }
-  }
-%    \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}
-%
-% If \pkg{tex4ht} is in use, make a few changes to give nicer looking
-% conversion to other formats.
-%    \begin{macrocode}
-\AtBeginDocument
-  {
-    \@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} } }
-       }
-       { }
+    \clist_map_function:nN { SIunits , sistyle }
+      \@@_load_check:n
   }
 %    \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 at th
-    \ensuremath { ^ { \mbox { \fontsize \sf at 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{Provide a kernel command}
 %
-%\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{macro}{\IfFormatAtLeastTF}
+%   Not present in older kernels: use the \LaTeXe{} mechanism as this is correct
+%   for this case.
 %    \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
-      }
-  }
+\providecommand \IfFormatAtLeastTF { \@ifl at t@r \fmtversion }
 %    \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 at 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}
-%
-%\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{macrocode}
-\bool_new:N \l_@@_font_set_bool
-\bool_new:N \l_@@_font_math_mode_bool
-%    \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 at version { bold }
-    {
-      \cs_set:Npn \@@_font_weight:
-        {
-          \boldmath
-          \bfseries
-        }
-    }
-  \str_if_eq:VnT \math at 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 at 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 at family \c_@@_textsf_tl
-    { \tl_set:Nn \l_@@_font_family_tl { sf } }
-  \tl_if_eq:NNT \f at 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 at shape} as a handy indicator.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_detect_font_shape:
-  {
-    \cs_if_exist:cT { \f at shape shape }
-      {
-        \cs_set:Npx \@@_font_shape: { \exp_not:c { \f at 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 at 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 at 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}
+% \subsection{Top-level scratch space}
 %
-%\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{macro}{\l_@@_tmp_tl}
+%   Scratch space for the interfaces.
 %    \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 = /
-}
+\tl_new:N \l_@@_tmp_tl
 %    \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}
-%
-% \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{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
-  }
-%    \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}
+% \subsection{Load time options}
 %
-%\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}
-%
-%\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
+% \begin{variable}{\l_@@_column_type_tl}
+%   \begin{macrocode}
+\keys_define:nn { siunitx }
   {
-    \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} } }
+    table-column-type .tl_set:N =
+      \l_@@_column_type_tl
   }
-\cs_new_protected:Npn
-  \@@_number_in_complex_to_uncert_dec_loop:N #1
+\keys_set: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 = S
   }
 %    \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:
-  {
-    \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
-  }
-%    \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.
+% User level interfaces are all created by \pkg{xparse}
 %    \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.
-%    \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
-  { }
+  { \RequirePackage { xparse } }
 %    \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}
+% \subsubsection{Preamble commands}
 %
-%\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 }
-%    \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}
-%
-% \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.
+%     \DeclareSIPower     ,
+%     \DeclareSIPrefix    ,
+%     \DeclareSIQualifier ,
+%     \DeclareSIUnit
+%   }
+%   Pass data to the code layer.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_number_process_places:n #1
+\NewDocumentCommand \DeclareSIPower { +m +m m }
   {
-    \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} }
-      }
+    \siunitx_declare_power:NNn #1 #2 {#3}
   }
-\cs_new_protected:Npn \@@_number_process_places_aux_i:n #1
+\NewDocumentCommand \DeclareSIPrefix { +m m m }
   {
-    \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}
-              }
-          }
-      }
+    \siunitx_declare_prefix:Nnn #1 {#2} {#3}
   }
-%    \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
+\NewDocumentCommand \DeclareSIQualifier { +m m }
   {
-    \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
+    \siunitx_declare_qualifier:Nn #1 {#2}
   }
-%    \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
+\NewDocumentCommand \DeclareSIUnit { o +m m }
   {
-    \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 } }
+    \IfNoValueTF {#1}
+      { \siunitx_declare_unit:Nn #2 {#3} }
+      { \siunitx_declare_unit:Nnn #2 {#3} {#1} }
   }
 %    \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!
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_number_process_round_decimal:
-  {
-    \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
-  }
-%    \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:
-  {
-    \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
-      }
-  }
-%    \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:
-  {
-    \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
-  }
-%    \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
-  {
-    \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} }
-  }
-%    \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}
+% \subsubsection{Document commands}
 %
-%\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{macro}{\qty}
 %    \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}
-%
-%\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{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:
+\@ifpackageloaded { physics }
   {
-    \bool_if:NT \l_@@_zero_decimal_to_integer_bool
+    \msg_new:nnn { siunitx } { physics-pkg }
       {
-        \@@_number_process_zero_to_integer_aux:n { mantissa }
-        \@@_number_process_zero_to_integer_aux:n { complex }
+        Detected~the~"physics"~package: \\
+        Omitting~definition~of~\token_to_str:N \qty.
       }
+    \msg_warning:nn { siunitx } { physics-pkg }
+    \use_none:nnnn
   }
-\cs_new_protected:Npn \@@_number_process_zero_to_integer_aux:n #1
+  { }
+\NewDocumentCommand \qty { O { } m > { \TrimSpaces } m }
   {
-    \prop_get:NnNT \l_@@_number_in_prop { #1 -decimal } \l_@@_tmpa_tl
-      {
-        \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 }
-          }
-      }
+    \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}
-% \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{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_exp_to_prefix:
+\NewDocumentCommand \ang { O { } > { \SplitArgument { 2 } { ; } } m }
   {
-    \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 }
-          }
-      }
+    \mode_leave_vertical:
+    \group_begin:
+      \keys_set:nn { siunitx } {#1}
+      \@@_angle:nnn #2
+    \group_end:
   }
-%    \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 }
+\NewDocumentCommand \num { O { } m }
   {
-    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   = ( % )
+    \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:
   }
-%    \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 \unit { O { } > { \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 {#2}
+      \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}{\@@_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{macro}
+%   {\qtylist, \numlist, \qtyproduct, \numproduct, \qtyrange, \numproduct}
+%   Interfaces for compound values.
 %    \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{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 \qtylist
+  { O { } > { \SplitList { ; } } m > { \TrimSpaces } 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:
+      \siunitx_unit_options_apply:n {#3}
+      \keys_set:nn { siunitx } {#1}
+      \siunitx_quantity_list:nn {#2} {#3}
+    \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 \numlist { O { } > { \SplitList { ; } } 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_list:nn {#2}
+    \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 \qtyproduct
+  { O { } > { \SplitList { x } } m > { \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 {#3}
+      \keys_set:nn { siunitx } {#1}
+      \siunitx_quantity_product:nn {#2} {#3}
+    \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:
+\NewDocumentCommand \numproduct
+  { O { } > { \SplitList { x } } > { \TrimSpaces } m }
   {
-    \@@_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:
+    \mode_leave_vertical:
+    \group_begin:
+      \keys_set:nn { siunitx } {#1}
+      \siunitx_number_product:n {#2}
+    \group_end:
   }
-\cs_new_protected:Npn \@@_unit_create_empty_functions_aux:N #1
+\NewDocumentCommand \qtyrange { O { } m m > { \TrimSpaces } m }
   {
-    \cs_if_free:NT #1
-      { \cs_set_protected:Npn #1 { \ERROR } }
+    \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}
-%\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:
+\NewDocumentCommand \numrange { O { } m m }
   {
-    \@@_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 } }
+    \mode_leave_vertical:
+    \group_begin:
+      \keys_set:nn { siunitx } {#1}
+      \siunitx_number_range:nn {#2} {#3}
+    \group_end:
   }
-\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{macro}{\complexnum, \complexqty}
+%   Interfaces for complex numbers.
 %    \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 at 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 at row@rst }
-    \@@_protect_symbols:N
-}
-\@@_if_hooks:TF
+\NewDocumentCommand \complexnum { O { } m }
   {
-    \AddToHook { begindocument / end } [ siunitx ]
-      { \@@_protect_symbols:N \fg }
+    \mode_leave_vertical:
+    \group_begin:
+      \keys_set:nn { siunitx } {#1}
+      \siunitx_complex_number:n {#2} \l_@@_tmp_tl
+    \group_end:
   }
+\NewDocumentCommand \complexqty { O { } m  m }
   {
-    \tl_put_right:Nn \document
-      {
-        \@@_protect_symbols:N \fg
-        \ignorespaces
-      }
+    \mode_leave_vertical:
+    \group_begin:
+      \siunitx_unit_options_apply:n {#3}
+      \keys_set:nn { siunitx } {#1}
+      \siunitx_complex_quantity:nn {#2} {#3}
+    \group_end:
   }
-\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}
+% \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{macro}{\tablenum}
+%   Slightly odd set up at present: we have to have the |\ignorespaces|.
 %    \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 at 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.
-%    \begin{macrocode}
-\keys_define:nn { siunitx }
+\NewDocumentCommand \tablenum { O { } 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:
+      \keys_set:nn { siunitx } {#1}
+      \siunitx_cell_begin:w
+        \ignorespaces #2
+      \siunitx_cell_end:
+    \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:
-  {
-    \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}
-        }
-  }
-}
-%    \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
-  {
-    \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}
-  }
-\cs_new_protected:Npn \@@_unit_parse_prefix:nn #1#2
-  {
-    \@@_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}
-  }
-%    \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
-  {
-    \tl_put_left:cx { l_@@_unit #1 _tl }
-      {
-        \exp_not:V \l_@@_tmpa_tl
-        { \exp_not:V \l_@@_unit_current_tl }
-      }
-  }
-  {
-    \tl_put_left:cV { l_@@_unit #1 _tl }
-      \l_@@_unit_current_tl
-  }
-}
-%    \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{macro}{\sisetup}
+%   A very thin wrapper.
 %    \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:
-          }
-      }
-  }
+\NewDocumentCommand \sisetup { m }
+  { \keys_set:nn { siunitx } {#1} }
 %    \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{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
-  {
-    \exp_not:n {#1}
-    \tl_if_blank:nF {#2}
-      {
-        \exp_not:V \l_@@_output_decimal_tl
-        \exp_not:n {#2}
-      }
-  }
-%    \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:
-  {
-    \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
-      }
-  }
-%    \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{\enquote{Glue} commands}
 %
-%\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{macro}{\@@_angle:nnn}
+%   The document level interface for \cs{ang} needs some \enquote{glue} to
+%   work with the code-level API.
 %    \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{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 }
+\cs_new_protected:Npn \@@_angle:nnn #1#2#3
   {
-    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
-        }
-  }
-\keys_set:nn { siunitx }
-  {
-    list-final-separator = { ~ and ~ } ,
-    list-pair-separator  = { ~ and ~ } ,
-    list-separator       = { , ~ }     ,
-    list-units           = repeat
-}
-%    \end{macrocode}
-% \end{variable}
-%
-% \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{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_if_novalue:nTF {#2}
+      { \siunitx_angle:n {#1} }
       {
-        \tl_map_function:nN {#1} \@@_list_numbers_aux_ii:n
-        \l_@@_list_tl
-        \l_@@_list_separator_final_tl
-        \l_@@_list_current_tl
+        \tl_if_novalue:nTF {#3}
+          { \siunitx_angle:nnn {#1} {#2} { } }
+          { \siunitx_angle:nnn {#1} {#2} {#3} }
       }
-      {
-        \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}
-  }
 %    \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.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_list_units: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}
-      }
-      {
-        \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}
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
+% \subsection{Table column}
 %
-%\subsection{Ranges}
-%
-%\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 at 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
+\cs_new_protected:Npn \@@_declare_column:Nnn #1#2#3
   {
-    \@@_range_numbers_aux:n {#1}
-    \l_@@_range_phrase_tl
-    \@@_range_numbers_aux:n {#2}
-  }
-\cs_new_protected:Npn \@@_range_numbers_aux:n #1
-  {
-    \bool_if:NTF \l_@@_number_parse_bool
+    \cs_if_exist:cT { NC at 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 at find@ #1 }
+        \msg_warning:nnn { siunitx } { column-overwritten } {#1}
       }
+    \newcolumntype {#1} { }
+    \cs_set_protected:Npn \@@_tmp:w \NC at do ##1##2 \NC at do #1
+      { \NC at list { \NC at do ##1 \NC at do #1 ##2 } }
+    \exp_after:wN \@@_tmp:w \the \NC at list
+    \exp_args:NNc \renewcommand * { NC at 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 at 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 at list} so that no warning appears.
+%   When \pkg{mdwtab} is loaded the syntax required is slightly different.
 %    \begin{macrocode}
-\AtBeginDocument {
-  \@ifpackageloaded { cellspace }
-      {
-        \cs_if_exist:NT \NC at find@S
-          {
-            \newcolumntype { C } [1]
-              { > { \bcolumn #1 \@nil } #1 < { \ecolumn } }
-            \cs_set:Npn \@@_tmp:w #1 \NC at do S #2 \q_stop
-              { \NC at list { #1 #2 } }
-            \exp_after:wN \@@_tmp:w \tex_the:D \NC at list \q_stop
-            \cs_undefine:N \NC at 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 at m
-              \def \env at matrix
-                {
-                  \hskip -\arraycolsep
-                  \let \@ifnextchar \new at ifnextchar
-                  \array
-                    {
-                      * { \c at 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 at 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.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_table_rewrite_create:N #1 {
-  \newcolumntype {#1} { }
-  \cs_set_protected:Npn
-    \@@_table_rewrite_create_aux:w \NC at do ##1##2 \NC at do #1
-    {  \NC at list { \NC at do ##1 \NC at do #1 ##2 } }
-  \exp_after:wN \@@_table_rewrite_create_aux:w \tex_the:D \NC at list
-  \exp_args:NNc \renewcommand * { NC at rewrite@ #1 } [1] [ ]
-    {
-      \@temptokena \exp_after:wN
-        {
-          \tex_the:D \@temptokena
-          > { \@@_table_collect_begin:Nn #1 {##1} }
-          c
-          < { \@@_table_print: }
-        }
-      \NC at 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 at find@ #1 }
+               {
+                 \cs_undefine:c { NC at 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
+    \tl_map_inline:Nn \l_@@_column_type_tl
       {
-        \token_if_eq_meaning:NNF #1 \tex_unskip:D
-          { \@@_table_collect_not_braced_aux_i:N #1 }
-      }
-    \@@_table_collect_next:
-  }
-\AtBeginDocument
-  {
-    \@ifpackageloaded { mdwtab }
-      {
-        \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 at setcr
-                      {
-                        \token_if_eq_meaning:NNF #1 \@maybe at 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}
+% \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{Document commands in bookmarks}
 %
-% \subsection{Table printing: general code}
+% In bookmarks, the \pkg{siunitx} document commands need to produce simple
+% strings that represent their input as far a possible.
 %
-% 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.
-%
-% \begin{variable}{\c_@@_one_fill_skip}
-%   A fixed skip of one \texttt{fill}.
+% \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}
-\skip_const:Nn \c_@@_one_fill_skip { 0pt plus 1fill }
-%    \end{macrocode}
-% \end{variable}
-%
-% \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{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:}
+% We also need the v2 names.
 %    \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.
-%    \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:
-              }
-          }
-      }
+    \@@_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 \SIrange { o m m m }
+  { #2 ~ #4 \tl_use:N \l_siunitx_range_phrase_tl #3 ~ #4 }
 %    \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{variable}{\c_@@_bookmark_seq}
+%   Commands usable in bookmarks
 %    \begin{macrocode}
-\skip_new:N \l_@@_table_unit_align_skip
-%    \end{macrocode}
-% \end{variable}
-%
-%    \begin{macrocode}
-\keys_define:nn { siunitx }
+\seq_const_from_clist:Nn \c_@@_bookmark_seq
   {
-    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 }
-          }
+    \ang , \qty , \num , \unit ,
+    \numlist , \qtylist ,
+    \numrange , \qtyrange ,
+    \si , \SI , \SIlist , \SIrange
   }
-\keys_set:nn { siunitx } { table-unit-alignment = center }
 %    \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{macrocode}
-\cs_new_protected:Npn \@@_table_print_s:
-  {
-    \@@_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 }
-  }
-%    \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.
+% Activate the document commands here: the unit macros are handled in
+% \pkg{siunitx-final}.
 %    \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
-%   }
-%    \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 } }
           }
+        \pdfstringdefDisableCommands
           {
-            \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
-          {
-            \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 at fg { \def \fg { \FB at 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{macro}[EXP]{\@@_angle:n}
+% \begin{macro}[EXP]{\@@_angle:w}
+%   Expandable splitting of the angle: simply enough, also outputs the
 %    \begin{macrocode}
-\keys_define:nn { siunitx }
+\cs_new:Npn \@@_angle:n #1
+  { \@@_angle:w #1 ; ; ; \q_stop }
+\cs_new:Npn \@@_angle:w #1 ; #2 ; #3 ; #4 \q_stop
   {
-    table-format .code:n    =
+    \tl_if_blank:nF {#1}
+      { #1 \degree }
+    \tl_if_blank:nF {#2}
       {
-        \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
+        \tl_if_blank:nF {#1} { \c_space_tl }
+        #2 \arcminute
       }
-  }
-\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
+    \tl_if_blank:nF {#3}
       {
-        \@@_table_column_begin:n { \l_@@_table_text_align_skip }
-          \l_@@_table_collect_pre_tl
-        \@@_table_column_end:n   { \l_@@_table_text_align_skip }
+        \tl_if_blank:nF {#1#2} { \c_space_tl }
+        #3 \arcsecond
       }
-      {
-        \@@_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{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_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:
+\cs_new:Npn \@@_list_use:nnnnn #1#2#3#4#5
   {
-    \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:
-      }
+    \tl_if_blank:nTF {#2}
+      { \@@_list_use_aux:nnnnn {#1} { } }
+      { \@@_list_use_aux:nnnnn {#1} { ~ #2 } }
+        {#3} {#4} {#5}
   }
-%    \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
+\cs_generate_variant:Nn \@@_list_use:nnnnn { nnVVV }
+\cs_new:Npn \@@_list_use_aux:nnnnn #1#2#3#4#5
   {
-    \tl_if_empty:NTF #1
-      { \dim_zero:N #2 }
+    \int_case:nnF { \@@_list_count:n {#1} }
       {
-        \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 }
+        { 0 } { }
+        { 1 } { \@@_list_use_auxi:nw {#2} #1 ; ; { } }
+        { 2 } { \@@_list_use_auxi:nw {#2} #1 ; {#3} }
       }
-  }
-%    \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
-            }
-        }
+        \@@_list_use_auxii:nnw {#2} { } #1 ;
+          \q_mark ; { \@@_list_use_auxii:nnw {#2} {#4} }
+          \q_mark ; { \@@_list_use_auxiii:nnw {#2} {#5} }
+          \q_stop { }
       }
-    \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:
+\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
   {
-    \@@_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
+    \exp_not:N \int_eval:n
       {
-        \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 }
+        0
+        \exp_not:N \@@_list_count:w \c_space_tl
+        #1 \exp_not:n { ; \q_recursion_tail ; \q_recursion_stop }
       }
   }
-%    \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:
+\cs_new:Npx \@@_list_count:w #1 ;
   {
-    \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
+    \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}
-%
-% \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{macrocode}
-\cs_new_protected:Npn \@@_table_print_S_reserved_mantissa:
-  {
-    \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 }
-          }
-      }
-  }
+%</interfaces>
 %    \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
-      {
-        \hbox_unpack:N \l_@@_table_result_box
-        \hbox_unpack:N \l_@@_tmp_box
-      }
-    \dim_add:Nn \l_@@_table_fill_mid_dim
-      {
-          \l_@@_table_uncert_dim
-        - \box_wd:N \l_@@_tmp_box
-      }
-  }
-%    \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{macrocode}
-\cs_new_protected:Npn
-  \@@_table_print_S_reserved_exponent_product_correction:
-  {
-    \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 }
-  }
-%    \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:
-  {
-    \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_post_dim
-      {
-          \l_@@_table_exponent_dim
-        - \box_wd:N \l_@@_tmp_box
-      }
-  }
-\cs_new_protected:Npn
-  \@@_table_print_S_reserved_exponent_not_aligned:
-  {
-    \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
-      {
-          \l_@@_table_fill_mid_dim
-        + \l_@@_table_exponent_dim
-        - \box_wd:N \l_@@_tmp_box
-      }
-  }
-%    \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
-  {
-    \@@_table_column_begin:n { \l_@@_table_text_align_skip }
-      #1
-    \@@_table_column_end:n   { \l_@@_table_text_align_skip }
-  }
-%    \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 at fg
-      { \cs_set_eq:NN \fg \FB at 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: }
-}
-%    \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

Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx.ins	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx.ins	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at 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

Added: trunk/Master/texmf-dist/source/latex/siunitx/siunitx.tex
===================================================================
--- trunk/Master/texmf-dist/source/latex/siunitx/siunitx.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/siunitx/siunitx.tex	2021-05-17 20:38:21 UTC (rev 59239)
@@ -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 at 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 at RequireAspects{writefile}
+\newsavebox\LaTeXdemo at box
+\lstnewenvironment{LaTeXdemo}[1][code and example]
+  {%
+    \global\let\lst at intname\@empty
+    \edef\LaTeXdemo at end{%
+      \expandafter\noexpand\csname LaTeXdemo@@#1 at end\endcsname
+    }%
+    \@nameuse{LaTeXdemo@@#1}%
+  }
+  {\LaTeXdemo at end}
+\newcommand\LaTeXdemo at new[3]{%
+  \@namedef{LaTeXdemo@@#1}{#2}%
+  \@namedef{LaTeXdemo@@#1 at end}{#3}%
+}
+\newcommand*\LaTeXdemo at common{%
+  \setkeys{lst}
+    {%
+       basicstyle   = \small\ttfamily,
+       basewidth    = 0.51em,
+       gobble       = 2,
+       language     = [LaTeX]{TeX},
+    }%
+}
+\newcount\LaTeXdemo at count
+\newcommand*\LaTeXdemo at input{%
+  \catcode`\^^M = 10\relax
+  \input{\jobname-\number\LaTeXdemo at count.tmp}%
+}
+\LaTeXdemo at new{code and example}{%
+  \setbox\LaTeXdemo at box=\hbox\bgroup
+    \global\advance\LaTeXdemo at count by 1 %
+    \lst at BeginAlsoWriteFile{\jobname-\number\LaTeXdemo at count.tmp}%
+    \LaTeXdemo at common
+}{%
+    \lst at EndWriteFile
+  \egroup
+  \begin{center}
+    \ifdim\wd\LaTeXdemo at box > 0.48\linewidth
+      \begin{minipage}{\linewidth}
+        \usebox\LaTeXdemo at box
+      \end{minipage}%
+      \par
+      \begin{minipage}{\linewidth}
+        \LaTeXdemo at input
+      \end{minipage}
+    \else
+      \begin{minipage}{0.48\linewidth}
+        \LaTeXdemo at input
+      \end{minipage}%
+      \hfil
+      \begin{minipage}{0.48\linewidth}
+        \usebox\LaTeXdemo at box
+      \end{minipage}%
+    \fi
+  \end{center}
+}
+\LaTeXdemo at new{code and float}{%
+  \global\advance\LaTeXdemo at count by 1 %
+  \lst at BeginAlsoWriteFile{\jobname-\number\LaTeXdemo at count.tmp}%
+  \LaTeXdemo at common
+}{%
+  \lst at EndWriteFile
+  \LaTeXdemo at input
+}
+\LaTeXdemo at new{code only}{\LaTeXdemo at 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 at morningstar2.co.uk}
+      {joseph.wright at 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}


Property changes on: trunk/Master/texmf-dist/source/latex/siunitx/siunitx.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/tex/latex/siunitx/siunitx-abbreviations.cfg
===================================================================
--- trunk/Master/texmf-dist/tex/latex/siunitx/siunitx-abbreviations.cfg	2021-05-17 20:37:11 UTC (rev 59238)
+++ trunk/Master/texmf-dist/tex/latex/siunitx/siunitx-abbreviations.cfg	2021-05-17 20:38:21 UTC (rev 59239)
@@ -1,124 +0,0 @@
-%%
-%% This is file `siunitx-abbreviations.cfg',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% siunitx.dtx  (with options: `config,abbreviations')
-%% ---------------------------------------------------------------
-%% The siunitx package --- A comprehensive (SI) units package
-%% Maintained by Joseph Wright
-%% E-mail: joseph.wright at morningstar2.co.uk
-%% Released under the LaTeX Project Public License v1.3c or later
-%% See http://www.latex-project.org/lppl.txt
-%% ---------------------------------------------------------------
-%% 
-\ProvidesExplFile {siunitx-abbreviations.cfg} {2021-04-17} {2.8e}
-  {siunitx: Abbreviated units}
-\DeclareSIUnit \A  {        \ampere }
-\DeclareSIUnit \pA { \pico  \ampere }
-\DeclareSIUnit \nA { \nano  \ampere }
-\DeclareSIUnit \uA { \micro \ampere }
-\DeclareSIUnit \mA { \milli \ampere }
-\DeclareSIUnit \kA { \kilo  \ampere }
-\DeclareSIUnit \Hz  {        \hertz }
-\DeclareSIUnit \mHz { \milli \hertz }
-\DeclareSIUnit \kHz { \kilo  \hertz }
-\DeclareSIUnit \MHz { \mega  \hertz }
-\DeclareSIUnit \GHz { \giga  \hertz }
-\DeclareSIUnit \THz { \tera  \hertz }
-\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 }
-\DeclareSIUnit \V  {        \volt }
-\DeclareSIUnit \pV { \pico  \volt }
-\DeclareSIUnit \nV { \nano  \volt }
-\DeclareSIUnit \uV { \micro \volt }
-\DeclareSIUnit \mV { \milli \volt }
-\DeclareSIUnit \kV { \kilo  \volt }
-\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 }
-\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 }
-\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 }
-\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 }
-\DeclareSIUnit \K { \kelvin }
-\DeclareSIUnit \dB { \deci \bel }
-\DeclareSIUnit \F  {        \farad }
-\DeclareSIUnit \fF { \femto \farad }
-\DeclareSIUnit \pF { \pico  \farad }
-\DeclareSIUnit \N  {        \newton }
-\DeclareSIUnit \mN { \milli \newton }
-\DeclareSIUnit \kN { \kilo  \newton }
-\DeclareSIUnit \MN { \mega  \newton }
-\DeclareSIUnit \Pa  {        \pascal }
-\DeclareSIUnit \kPa { \kilo  \pascal }
-\DeclareSIUnit \MPa { \mega  \pascal }
-\DeclareSIUnit \GPa { \giga  \pascal }
-\DeclareSIUnit \mohm { \milli \ohm }
-\DeclareSIUnit \kohm { \kilo  \ohm }
-\DeclareSIUnit \Mohm { \mega  \ohm }
-\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 }
-%% Copyright (C) 2008-2021 by
-%%   Joseph Wright <joseph.wright at 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.
-%%

@@ Diff output truncated at 1234567 characters. @@


More information about the tex-live-commits mailing list.