summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/siunitx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/siunitx
Initial commit
Diffstat (limited to 'macros/latex/contrib/siunitx')
-rw-r--r--macros/latex/contrib/siunitx/README.md55
-rw-r--r--macros/latex/contrib/siunitx/siunitx.dtx18021
-rw-r--r--macros/latex/contrib/siunitx/siunitx.pdfbin0 -> 612110 bytes
3 files changed, 18076 insertions, 0 deletions
diff --git a/macros/latex/contrib/siunitx/README.md b/macros/latex/contrib/siunitx/README.md
new file mode 100644
index 0000000000..93244686b6
--- /dev/null
+++ b/macros/latex/contrib/siunitx/README.md
@@ -0,0 +1,55 @@
+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` \ No newline at end of file
diff --git a/macros/latex/contrib/siunitx/siunitx.dtx b/macros/latex/contrib/siunitx/siunitx.dtx
new file mode 100644
index 0000000000..9fc30aa992
--- /dev/null
+++ b/macros/latex/contrib/siunitx/siunitx.dtx
@@ -0,0 +1,18021 @@
+% \iffalse meta-comment
+%<*internal>
+\iffalse
+%</internal>
+%<*readme>
+siunitx - A comprehensive (SI) units package
+==============================================
+
+Physical quantities have both numbers and units, and each
+physical quantity should be expressed as the product of a number
+and a unit. Typesetting physical quantities requires care to
+ensure that the combined mathematical meaning of the number-unit
+combination is clear. In particular, the SI units system lays
+down a consistent set of units with rules on how these are to be
+used. However, different countries and publishers have differing
+conventions on the exact appearance of numbers (and units). The
+`siunitx` package provides a set of tools for authors to typeset
+quantities in a consistent way. The package has an extended set
+of configuration options which make it possible to follow
+varying typographic conventions with the same input syntax. The
+package includes automated processing of numbers and units, and
+the ability to control tabular alignment of numbers.
+
+Installation
+------------
+
+The package is supplied in `dtx` format and as a pre-extracted
+zip file, `siunitx.tds.zip`. The later is most convenient for
+most users: simply unzip this in your local texmf directory . If
+you want to unpack the `.dtx` yourself, running `tex
+siunitx.dtx` will extract the package whereas `latex
+siunitx.dtx` will extract it and also typeset the documentation.
+
+The package requires LaTeX3 support as provided in the
+`l3kernel` and `l3packages` bundles. Both of these are available
+on [CTAN](http://www.ctan.org/) as ready-to-install zip files.
+Suitable versions are available in MiKTeX 2.9 and TeX Live 2015
+(updating the relevant packages online may be necessary).
+LaTeX3, and so `siunitx`, requires the e-TeX extensions: these
+are available on all modern TeX systems.
+
+Typesetting the documentation requires a number of packages in
+addition to those needed to use the package. This is mainly
+because of the number of demonstration items included in the
+text. To compile the documentation without error, you will
+need the packages:
+ - `amsmath`
+ - `booktabs`
+ - `cancel`
+ - `caption`
+ - `cleveref`
+ - `colortbl`
+ - `csquotes`
+ - `datatool`
+ - `helvet`
+ - `mathpazo`
+ - `multirow`
+ - `listings`
+ - `pgfplots`
+ - `xcolor`
+%</readme>
+%<*internal>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+%</internal>
+%<*install>
+\input l3docstrip.tex
+\keepsilent
+\askforoverwritefalse
+\preamble
+---------------------------------------------------------------
+The siunitx package --- A comprehensive (SI) units package
+Maintained by Joseph Wright
+E-mail: joseph.wright@morningstar2.co.uk
+Released under the LaTeX Project Public License v1.3c or later
+See http://www.latex-project.org/lppl.txt
+---------------------------------------------------------------
+
+\endpreamble
+\postamble
+Copyright (C) 2008-2018 by
+ Joseph Wright <joseph.wright@morningstar2.co.uk>
+
+It may be distributed and/or modified under the conditions of
+the LaTeX Project Public License (LPPL), either version 1.3c of
+this license or (at your option) any later version. The latest
+version of this license is in the file:
+ http://www.latex-project.org/lppl.txt
+
+This work is "maintained" (as per LPPL maintenance status) by
+ Joseph Wright.
+
+This work consists of the file siunitx.dtx
+ and the derived files siunitx.pdf,
+ siunitx.sty and
+ siunitx.ins.
+\endpostamble
+\usedir{tex/latex/siunitx}
+\generate{
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+ \file{siunitx-abbreviations.cfg}
+ {\from{\jobname.dtx}{config,abbreviations}}
+ \file{siunitx-binary.cfg}{\from{\jobname.dtx}{config,binary}}
+ \file{siunitx-version-1.cfg}{\from{\jobname.dtx}{config,version-1}}
+}
+%</install>
+%<install>\endbatchfile
+%<*internal>
+\usedir{source/latex/siunitx}
+\generate{
+ \file{\jobname.ins}{\from{\jobname.dtx}{install}}
+}
+\nopreamble\nopostamble
+\usedir{doc/latex/siunitx}
+\generate{
+ \file{README.md}{\from{\jobname.dtx}{readme}}
+}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</internal>
+%<*driver|package>
+\RequirePackage{expl3}[2015/09/11]
+\RequirePackage{xparse}
+%</driver|package>
+%<*driver>
+\documentclass{l3doc}
+\usepackage[german,french,spanish,UKenglish]{babel}
+\usepackage[table]{xcolor}
+\usepackage{amsmath,booktabs,cancel,caption,colortbl,csquotes}
+\usepackage{datatool,helvet,multirow,pgfplots,siunitx,xfrac,xtab}
+\usepackage[capitalise]{cleveref}
+\usepackage[final]{listings}
+\usepackage[osf]{mathpazo}
+\AtBeginDocument{\shorthandoff{<>}}
+\crefformat{section}{#2Section~#1#3}
+\Crefformat{section}{#2Section~#1#3}
+\crefformat{subsection}{#2Section~#1#3}
+\Crefformat{subsection}{#2Section~#1#3}
+\crefformat{figure}{#2Figure~#1#3}
+\Crefformat{figure}{#2Figure~#1#3}
+\crefformat{table}{#2Table~#1#3}
+\Crefformat{table}{#2Table~#1#3}
+\crefrangeformat{table}{#3Tables~#1#4 to~#5#2#6}
+\Crefrangeformat{table}{#3Tables~#1#4 to~#5#2#6}
+\crefmultiformat{table}{#2Tables~#1#3}{ and~#2#1#3}{, #2#1#3}{, and~#2#1#3}
+\Crefmultiformat{table}{#2Tables~#1#3}{ and~#2#1#3}{, #2#1#3}{, and~#2#1#3}
+% Silence annoying fp package messages
+\FPmessagesfalse
+\pgfplotsset{compat = newest}
+\sisetup{binary-units}
+\DeclareSIUnit{\KWH}{kWh}
+\DeclareSIPrePower\quartic{4}
+\DeclareSIPostPower\tothefourth{4}
+\DeclareSIQualifier\catalyst{cat}
+\DeclareSIQualifier\isotropic{i}
+\DeclareSIQualifier\polymer{pol}
+\newlength\mylength
+%\DisableImplementation
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%\makeatletter
+%
+%^^A Some short cuts for the tables
+%\NewDocumentCommand\DescribePrefix{m}{^^A
+% \expandafter\SpecialUsageIndex\expandafter{\csname #1\endcsname}^^A
+% #1 & \cs{#1} & \expandafter\si\expandafter{\csname #1\endcsname}
+%}
+%\NewDocumentCommand\DescribeUnit{m}{^^A
+% \expandafter\SpecialUsageIndex\expandafter{\csname #1\endcsname}^^A
+% #1 &
+% \cs{#1} &
+% \expandafter\si\expandafter{\csname #1\endcsname}
+%}
+%\NewDocumentCommand\DescribeNamedUnit{mm}{^^A
+% \expandafter\SpecialUsageIndex\expandafter{\csname #2\endcsname}^^A
+% #1 &
+% \cs{#2} &
+% \expandafter\si\expandafter{\csname #2\endcsname}
+%}
+%
+%^^A For creating examples with nice highlighting of code, and so
+%^^A on; based on the system used in the listings source (lstsample).
+%\lst@RequireAspects{writefile}
+%\newsavebox{\LaTeXdemo@box}
+%\lstnewenvironment{LaTeXdemo}[1][code and example]
+% {^^A
+% \global\let\lst@intname\@empty
+% \expandafter\let\expandafter\LaTeXdemo@end
+% \csname LaTeXdemo@#1@end\endcsname
+% \@nameuse{LaTeXdemo@#1}^^A
+% }
+% {\LaTeXdemo@end}
+%\newcommand*\LaTeXdemo@new[3]{^^A
+% \expandafter\newcommand\expandafter*\expandafter
+% {\csname LaTeXdemo@#1\endcsname}{#2}^^A
+% \expandafter\newcommand\expandafter*\expandafter
+% {\csname LaTeXdemo@#1@end\endcsname}{#3}^^A
+%}
+%\newcommand*\LaTeXdemo@common{^^A
+% \setkeys{lst}
+% {
+% basicstyle = \small\ttfamily,
+% basewidth = 0.51em,
+% gobble = 3,
+% keywordstyle = \color{blue},
+% language = [LaTeX]{TeX},
+% moretexcs =
+% {
+% addto,
+% ampere,
+% ang,
+% angstrom,
+% becquerel,
+% bel,
+% bit,
+% bottomrule,
+% byte,
+% cancel,
+% candela,
+% centi,
+% color,
+% coulomb,
+% cubed,
+% cubic,
+% deci,
+% decibel,
+% degree,
+% degreeCelsius,
+% DeclareBinaryPrefix,
+% DeclareRobustCommand,
+% DeclareSIPostPower,
+% DeclareSIPrefix,
+% DeclareSIPrePower,
+% DeclareSIQualifier,
+% DeclareSIUnit,
+% DTLdisplaydb,
+% DTLforeach,
+% DTLiffirstrow,
+% DTLmul,
+% DTLnewdb,
+% DTLnewdbentry,
+% DTLnewrow,
+% farad,
+% fontspec,
+% gram,
+% gray,
+% henry,
+% highlight,
+% hour,
+% Hz,
+% joule,
+% kelvin,
+% kibi,
+% kilo,
+% kilogram,
+% kWh,
+% litre,
+% lumen,
+% lux,
+% mathnormal,
+% metre,
+% mebi,
+% micro,
+% midrule,
+% milli,
+% mm,
+% mole,
+% multirow,
+% num,
+% numlist,
+% numrange,
+% of,
+% pascal,
+% per,
+% percent,
+% protected,
+% radian,
+% raiseto,
+% robustify,
+% rowcolor,
+% second,
+% selectlanguage,
+% SendSettingsToPgf,
+% si,
+% SI,
+% SIlist,
+% SIrange,
+% sievert,
+% sisetup,
+% SIUnitSymbolDegree,
+% square,
+% squared,
+% tablenum,
+% tesla,
+% texorpdfstring,
+% text,
+% textmu,
+% toprule,
+% tothe,
+% translate,
+% unit,
+% volt,
+% watt
+% }
+% }^^A
+%}
+%\newcommand*\LaTeXdemo@input{^^A
+% \MakePercentComment
+% \catcode`\^^M=10\relax
+% \small
+% \begingroup
+% \setkeys{lst}
+% {
+% SelectCharTable=\lst@ReplaceInput{\^\^I}{\lst@ProcessTabulator}
+% }^^A
+% \leavevmode
+% \input{\jobname.tmp}^^A
+% \endgroup
+% \MakePercentIgnore
+%}
+%\LaTeXdemo@new{code and example}
+% {^^A
+% \setbox\LaTeXdemo@box=\hbox\bgroup
+% \lst@BeginAlsoWriteFile{\jobname.tmp}^^A
+% \LaTeXdemo@common
+% }
+% {^^A
+% \lst@EndWriteFile
+% \egroup
+% \begin{center}
+% \ifdim\wd\LaTeXdemo@box>0.48\linewidth\relax
+% \hbox to\linewidth{\box\LaTeXdemo@box\hss}^^A
+% \begin{minipage}{\linewidth}
+% \LaTeXdemo@input
+% \end{minipage}
+% \else
+% \begin{minipage}{0.48\linewidth}
+% \LaTeXdemo@input
+% \end{minipage}
+% \hfill
+% \begin{minipage}{0.48\linewidth}
+% \hbox to\linewidth{\box\LaTeXdemo@box\hss}^^A
+% \end{minipage}
+% \fi
+% \end{center}
+% }
+%\LaTeXdemo@new{code and float}{^^A
+% \lst@BeginAlsoWriteFile{siunitx.tmp}^^A
+% \LaTeXdemo@common
+%}{^^A
+% \lst@EndWriteFile
+% \LaTeXdemo@input
+%}
+%\LaTeXdemo@new{code only}
+% {\LaTeXdemo@common}{}
+%
+%^^A Turning of the marginpar warnings is a bit awkward.
+%^^A It is achieved by temporarily disabling \@latex@warning@no@line
+%\let\latex@addmarginpar\@addmarginpar
+%\let\latex@warning@no@line\@latex@warning@no@line
+%\def\@addmarginpar{^^A
+% \let\@latex@warning@no@line\@gobble
+% \latex@addmarginpar
+% \let\@latex@warning@no@line\latex@warning@no@line
+%}
+%
+%\ProvideDocumentCommand\opt{m}{\texttt{#1}}
+%
+%\makeatother
+%
+%\GetFileInfo{\jobname.sty}
+%
+%\title{^^A
+% \textsf{siunitx} --- A comprehensive (SI) units package\thanks{^^A
+% This file describes \fileversion, last revised \filedate.^^A
+% }^^A
+%}
+%\author{^^A
+% Joseph Wright\thanks
+% {^^A
+% E-mail: \href{mailto:joseph.wright@morningstar2.co.uk}
+% {\texttt{joseph.wright@morningstar2.co.uk}}^^A
+% }^^A
+%}
+%\date{Released \filedate}
+%
+%\maketitle
+%
+%\changes{v0.6}{2008/02/18}{First public testing release (as \pkg{si})}
+%\changes{v1.0}{2008/06/15}{First official release}
+%\changes{v1.1}{2008/09/28}{Package extended to a greater range of unit
+% types}
+%\changes{v1.2}{2009/01/22}{Correct handling for ranges of numbers
+% added}
+%\changes{v1.3}{2009/09/20}{Better definition for micro symbol}
+%\changes{v1.4}{2010/01/16}{Detect entire document in non-serif font}
+%\changes{v2.0}{2010/05/23}{Complete re-write of package to add many new
+% features}
+%\changes{v2.0c}{2010/06/07}{Mixed literal and macro units now print
+% more reliably}
+%\changes{v2.0d}{2010/06/10}{Fix error in \opt{table-format} option
+% concerning exponent signs}
+%\changes{v2.0e}{2010/06/20}{Correct behaviour of \cs{pm} in numbers
+% when \texttt{abbreviations} configuration is loaded: problem
+% introduced in v2.0c}
+%\changes{v2.0f}{2010/06/27}{Fix issue with spacing of multiplication
+% sign in text mode}
+%\changes{v2.0g}{2010/06/28}{Fix issue with complex numbers in
+% quotients}
+%\changes{v2.0g}{2010/06/28}{Repair broken \opt{bracket-numbers}
+% option}
+%\changes{v2.0g}{2010/06/28}{Improve handling of complex root token}
+%\changes{v2.0g}{2010/06/28}{Introduce localisation for text values}
+%\changes{v2.0h}{2010/06/29}{Actually get localisation into the
+% code}
+%\changes{v2.0j}{2010/06/30}{Ensure symbols specified in
+% \opt{input-symbols} are always printed in math mode}
+%\changes{v2.0k}{2010/07/04}{Fix for \pkg{babel} French settings with
+% \cs{fg} in tabular material}
+%\changes{v2.0l}{2010/07/07}{Further adjustments to \pkg{babel} support}
+%\changes{v2.0p}{2010/07/28}{Actually get change from v2.0o working}
+%\changes{v2.0q}{2010/07/29}{Errors with free-standing unit code fixed}
+%\changes{v2.0q}{2010/07/29}{Deal with bad definition of \cs{color}
+% by \pkg{textpos} package}
+%\changes{v2.0s}{2010/08/08}{Correct errors in rounding code when
+% precision requested is zero decimal places}
+%\changes{v2.0t}{2010/08/24}{Replace \cs{exp_afer:wN} in code for
+% \cs{per} with \cs{exp_after:wN}}
+%\changes{v2.0u}{2010/09/14}{Fix second possible issue with
+% \pkg{textpos} package and \cs{color}}
+%\changes{v2.0u}{2010/09/14}{Prevent infinite loop if \cs{SI} function
+% is used with an empty number}
+%\changes{v2.0v}{2010/09/26}{Internal changes reflecting \pkg{expl3}
+% updates}
+%\changes{v2.0w}{2010/09/29}{Deal with internal function used by
+% REV\TeX{} in tables}
+%\changes{v2.0x}{2010/10/05}{Fix bug when detecting single prefixes
+% and converting prefixes to numbers}
+%\changes{v2.1a}{2010/11/05}{Ensure that output of list separators is
+% in text mode}
+%\changes{v2.1a}{2010/11/05}{Print prefixes correctly in text mode
+% when converting to numerical value}
+%\changes{v2.1b}{2010/11/05}{Bug in printing code for complex part with
+% no number fixed}
+%\changes{v2.1b}{2010/11/05}{Bug in hyphen printing when detecting mode
+% sorted}
+%\changes{v2.1c}{2010/11/11}{Discourage line break between number and
+% unit even when it is permitted}
+%\changes{v2.1c}{2010/11/14}{After reviewing internals, \cs{numlist},
+% \cs{numrange}, \cs{SIlist} and \cs{SIrange} are documented as
+% requiring text mode due to issues with spacing and line breaks}
+%\changes{v2.1c}{2010/11/14}{Auto-detect math mode in tables and
+% correct output accordingly}
+%\changes{v2.1e}{2010/11/22}{Fix issues with text mode symbols and
+% \pkg{fontspec} package}
+%\changes{v2.1g}{2010/12/21}{Checks on the versions of \pkg{expl3} and
+% \pkg{xparse} installed}
+%\changes{v2.1h}{2011/01/18}{Detect AMS display-like environments}
+%\changes{v2.1j}{2011/02/01}{Allow for loading of \pkg{inputenc} package
+% with no options}
+%\changes{v2.1k}{2011/02/09}{Bug fix when printing superscript minus
+% signs and using \pkg{fontspec} package}
+%\changes{v2.1m}{2011/03/18}{Avoid expansion of erroneous literal
+% units when these are forbidden}
+%\changes{v2.1m}{2011/03/20}{Ensure some output occurs in all cases
+% when \opt{round-precision} is set to \opt{0} and \opt{round-mode}
+% is set to \opt{places}}
+%\changes{v2.1n}{2011/03/31}{Consistent behaviour for
+% \opt{round-integer-to-decimal} when \opt{round-precision} is 0}
+%\changes{v2.1o}{2011/04/03}{Fix incorrect font choice when
+% \pkg{arev} package is loaded}
+%\changes{v2.1o}{2011/04/03}{Account for negative exponents
+% when using \opt{fixed-exponent} system}
+%\changes{v2.1p}{2011/04/04}{Bad table alignment when some rows
+% contain comparators fixed}
+%\changes{v2.1p}{2011/04/04}{Poor position of comparators in
+% numbers fixed}
+%\changes{v2.2a}{2011/04/15}{Fix issue with \texttt{*} tokens in
+% tabular preambles}
+%\changes{v2.2a}{2011/04/15}{Expand macros with arguments correctly
+% in tables}
+%\changes{v2.2a}{2011/04/16}{Group digits for input containing symbolic
+% entries}
+%\changes{v2.2a}{2011/04/16}{Insert tokens correctly when last tabular cell
+% does not end \texttt{\textbackslash\textbackslash}}
+%\changes{v2.2a}{2011/04/16}{Fix bug with literal units and auto-insertion
+% of \num{1} when \opt{per-mode} is \opt{symbol}}
+%\changes{v2.2b}{2011/04/17}{Make \cs{of} work in hyper-linked sections}
+%\changes{v2.2b}{2011/04/17}{Fix bug with \cs{highlight} macro when
+% no colour support is loaded}
+%\changes{v2.2b}{2011/04/19}{Fix bad formatting of negative exponents when
+% using the \opt{output-exponent-marker} option}
+%\changes{v2.2c}{2011/04/20}{Fix bad interaction with \pkg{cellspace} package}
+%\changes{v2.2d}{2011/04/28}{Fix the \opt{strict} option}
+%\changes{v2.2e}{2011/05/23}{Fix incorrect interpretation of complex numbers
+% with no real part}
+%\changes{v2.2g}{2011/06/02}{Correctly space \cs{degree} and similar units
+% in lists and ranges when only a single unit is given}
+%\changes{v2.2h}{2011/06/03}{Fix bug in significant figures rounding code
+% for some integer part values}
+%\changes{v2.2i}{2011/06/15}{Fix \opt{detect-mode} option inside
+% table cells}
+%\changes{v2.2j}{2011/06/26}{Fix incorrect line breaking in \cs{SIrange}}
+%\changes{v2.2k}{2011/06/27}{Fix behaviour of subscripts inside alignments
+% when printing in text mode}
+%\changes{v2.2l}{2011/06/30}{Fix loss of main unit when \opt{per-mode} is set
+% to \opt{symbol} and a pre-unit is used}
+%\changes{v2.3}{2011/06/19}{New implementation for alignment in \texttt{S}
+% column}
+%\changes{v2.3a}{2011/07/09}{Restore fix in v2.2l missing in v2.3}
+%\changes{v2.3b}{2011/08/08}{Adjust internal load order so that
+% \opt{free-standing-units} works correctly for abbreviations}
+%\changes{v2.3c}{2011/07/12}{Fix display of \( \pm \) in numbers when
+% \opt{separate-uncertainty} is \opt{true} and literal units are used}
+%\changes{v2.3d}{2011/08/18}{Fix broken superscript display in literal unit
+% mode}
+%\changes{v2.3e}{2011/09/09}{Internal changes to work with \LaTeX3
+% updates}
+%\changes{v2.3f}{2011/09/03}{Fix processing of numbers in tables when entire
+% number is invalid}
+%\changes{v2.3g}{2011/10/06}{Deal with erroneous leading zero in some
+% fixed exponent cases}
+%\changes{v2.3h}{2011/10/14}{Ensure math mode for exponent products in all
+% circumstances}
+%\changes{v2.3h}{2011/10/14}{Improvements to output when using \pkg{tex4ht}}
+%\changes{v2.4}{2011/11/03}{Reduce number of math mode options, improving
+% consistency of output}
+%\changes{v2.4a}{2011/11/28}{Extend search-and-replace code for UTF-8
+% characters}
+%\changes{v2.4a}{2011/12/04}{Use a more cautious approach to changing
+% settings at the start of the document}
+%\changes{v2.4b}{2011/12/06}{Erroneous doubled \texttt{\#} corrected}
+%\changes{v2.4c}{2011/12/09}{Erroneous check for text mode sanserif font fixed}
+%\changes{v2.4d}{2011/12/09}{Fix for edge-case user commands in captions
+% where the command clashes with a unit name}
+%\changes{v2.4e}{2011/12/11}{Fix issue with \pkg{inputenc} package and
+% some of the recent special symbol changes}
+%\changes{v2.4f}{2011/12/21}{Allow easier use of headings when not parsing
+% numbers in tables}
+%\changes{v2.4f}{2011/12/23}{Fix bug with detection of bold font in table
+% cells}
+%\changes{v2.4g}{2012/01/06}{Update internals to match changes in \pkg{expl3}
+% which caused issues with some tokens in numerical arguments}
+%\changes{v2.4h}{2012/01/15}{Bug fix for implementation of
+% \opt{reciprocal-positive-first}}
+%\changes{v2.4i}{2012/01/19}{Bug fix for rounding with large numbers of
+% decimal places}
+%\changes{v2.4j}{2012/01/26}{Leave vertical mode before any document-level
+% commands}
+%\changes{v2.4k}{2012/03/22}{Internal changes to allow for \pkg{breqn}
+% package tricks}
+%\changes{v2.4l}{2012/03/23}{Fix a load-order issue with \pkg{soulpos}
+% package}
+%\changes{v2.4m}{2012/04/03}{Correct bug in \cs{SIlist} when only a single
+% number is given}
+%\changes{v2.4n}{2012/04/04}{Allow conversion of numbers with more than
+% nine digits to scientific notation}
+% \changes{v2.5}{2012/04/07}{Fixed table code to give fewer underfull
+% boxes when comparators are used}
+% \changes{v2.5}{2015/04/07}{Added \opt{zero-decimal-to-integer} option}
+% \changes{v2.5}{2012/04/07}{Added \opt{omit-uncertainty} option}
+% \changes{v2.5}{2012/04/08}{Modified \opt{fixed-exponent} such that it can
+% remove an exponent part}
+% \changes{v2.5}{2012/04/08}{Modified number of intrinsically-mathematical
+% options}
+% \changes{v2.5a}{2012/04/19}{Fixed support for \enquote{dynamic} nature of spacing
+% in free standing units (bug introduced in v2.5)}
+% \changes{v2.5b}{2012/04/20}{Fixed treatement \texttt{\^} and \texttt{\_}
+% in literal units when \pkg{breqn} package is loaded}
+% \changes{v2.5b}{2012/04/20}{Added support for \pkg{eulervm} package}
+% \changes{v2.5c}{2012/04/03}{Fixed conversion of numbers with more than
+% nine digits when using fixed exponents}
+% \changes{v2.5c}{2012/05/03}{Modified treatment entirely empty cells in
+% \texttt{s} columns}
+% \changes{v2.5d}{2012/06/11}{Extend range of settings automatically altered
+% to use UTF-8 values is appropriate}
+% \changes{v2.5d}{2012/06/11}{Added \opt{qualifier-phrase} option}
+% \changes{v2.5d}{2012/06/11}{Added \opt{phrase} choice for \opt{qualifier-mode}
+% option}
+% \changes{v2.5e}{2012/06/13}{Fixed an internal error in unit expansion
+% introduced in v2.4f}
+% \changes{v2.5f}{2012/07/16}{Modified internals to track \pkg{expl3} changes}
+% \changes{v2.5g}{2012/07/22}{Fixed \opt{binary-units} option}
+% \changes{v2.5h}{2012/08/28}{Modified literal unit test to allow spaces in
+% units to be ignored}
+% \changes{v2.5i}{2012/09/11}{Fixed alignment of values without uncertainties in
+% columns where space is reserved for uncertainties}
+% \changes{v2.5j}{2012/09/18}{Fixed rounding when uncertainties are present}
+% \changes{v2.5k}{2012/09/20}{Fixed a warning with \pkg{amsmath} related to fraction
+% functions}
+% \changes{v2.5k}{2012/11/13}{Fixed handling spaces correctly after start of document}
+% \changes{v2.5l}{2012/11/21}{Modified internals to track \pkg{expl3} changes}
+% \changes{v2.5m}{2012/11/27}{Fixed bug with UTF-8 engines and literal units}
+% \changes{v2.5m}{2012/11/27}{Fixed \cs{highlight} behavior in bookmarks}
+% \changes{v2.5m}{2012/11/27}{Modified loading of \opt{binary-units}}
+% \changes{v2.5m}{2012/11/27}{Fixed right-to-left mode with \pkg{bidi}
+% package}
+% \changes{v2.5n}{2012/12/29}{Fixed transmission of grouping information by
+% \cs{SendSettingsToPgf}}
+% \changes{v2.5o}{2013/01/09}{Modified internals to track \pkg{expl3} changes}
+% \changes{v2.5p}{2013/02/01}{Fixed printing of \cs{pm} and \cs{mp} when used
+% as signs in text mode}
+% \changes{v2.5q}{2013/03/10}{Fixed use active \texttt{-} in numbersn}
+% \changes{v2.5q}{2013/03/10}{Fixed binary units in tables}
+% \changes{v2.5r}{2013/07/11}{Modified internals to track \pkg{expl3} changes}
+% \changes{v2.5s}{2013/07/31}{Modified internals to track \pkg{expl3} changes}
+% \changes{v2.6}{2013/11/19}{Fixed loading when \pkg{mdwtab} is in use}
+% \changes{v2.6}{2014/09/03}{Fixed minus sign when \pkg{tex4ht} is in use}
+% \changes{v2.6}{2014/09/03}{Fixed spacing when printing comparators}
+% \changes{v2.6}{2014/09/03}{Modified treatment of hard spaces (\texttt{\~}) in
+% argument of \cs{num}}
+% \changes{v2.6}{2014/09/03}{Modified standard setting for \opt{mode} option
+% to \opt{math}}
+% \changes{v2.6}{2014/09/04}{Fixed printing of uncertainties when the
+% input is an integer and the uncertainty is given as a separate part}
+% \changes{v2.6}{2014/09/04}{Fixed definition \cs{fg} in
+% bookmarks when \pkg{babel} is loaded with the \opt{french} option}
+% \changes{v2.6}{2014/09/05}{Fixed printing exponent in tables when
+% \opt{output-exponent-marker} is active}
+% \changes{v2.6a}{2014/09/15}{Modified glyph selection when \pkg{fontspec}
+% is detected}
+% \changes{v2.6b}{2014/09/27}{Modified range of font shapes which can be
+% detected}
+% \changes{v2.6c}{2014/10/01}{Fixed use of \cs{micro} when \pkg{fontspec}
+% is loaded but \pkg{unicode-math} is not}
+% \changes{v2.6d}{2014/10/07}{Fixed conversion of \enquote{long} to
+% \enquote{short} uncertainty values with integer mantissas}
+% \changes{v2.6e}{2015/01/21}{Modified symbol selection where \pkg{fontspec}
+% and certain other packages are in use}
+% \changes{v2.6f}{2015/04/01}{Fixed \opt{table-sign-exponent} and
+% \opt{table-sign-mantissa} options when set \opt{false}}
+% \changes{v2.6f}{2015/04/04}{Modified detection of \pkg{mathspec}}
+% \changes{v2.6g}{2015/06/24}{Fixed issue with empty table cells}
+% \changes{v2.6h}{2015/07/17}{Modified internals to track \pkg{expl3} changes}
+% \changes{v2.6i}{2015/08/18}{Fixed rounding of numbers with large numbers of
+% digits}
+% \changes{v2.6i}{2015/08/18}{Fixed behaviour of \cs{cancel} when printing
+% in math mode}
+% \changes{v2.6j}{2015/09/01}{Fixed printing of all units when
+% \opt{exponent-to-prefix} is set}
+% \changes{v2.6j}{2015/09/01}{Fixed appearance of $\pm$ when
+% \opt{exponent-to-prefix} is set}
+% \changes{v2.6k}{2015/09/12}{Modified internals to track \pkg{expl3} changes}
+% \changes{v2.6l}{2015/09/14}{Fixed an internal error}
+% \changes{v2.6m}{2015/10/15}{Fixed an issue with \pkg{mwtab}}
+% \changes{v2.6n}{2015/12/31}{Modified definition for degree Celsius}
+% \changes{v2.6n}{2015/12/31}{Fixed {\aa}ngstr{\"o}m symbol with \LuaTeX{}}
+% \changes{v2.6o}{2016/01/05}{Added support for unit powers when converting exponents
+% to prefixes}
+% \changes{v2.6p}{2016/01/13}{Added support for reciprocal powers when converting
+% exponents to prefixes}
+% \changes{v2.6p}{2016/01/19}{Modified definition for degree Celsius}
+% \changes{v2.6q}{2016/03/01}{Fixed font selection when document commands are
+% used inside table cells in \texttt{S} columns}
+% \changes{v2.6r}{2016/06/06}{Fixed color safety issue}
+% \changes{v2.6r}{2016/08/14}{Fixed internal \pkg{expl3} usage issues}
+% \changes{v2.6r}{2016/08/21}{Fixed handling \texttt{e0}}
+% \changes{v2.6r}{2016/08/21}{Added a warning when color support is not available}
+% \changes{v2.6s}{2016/09/02}{Removed one excess warning}
+% \changes{v2.7}{2016/11/11}{Added first documented code level interfaces}
+% \changes{v2.7}{2016/11/23}{Fixed behavior when \pkg{cellspace} is applied to
+% math mode material}
+% \changes{v2.7b}{2017/01/28}{Fixed large numbers in scientific mode}
+% \changes{v2.7c}{2017/02/01}{Fixed spacing of integers in tables when
+% aligning decimal marker to center}
+% \changes{v2.7d}{2017/02/19}{Fixed doubled pre-number tokens in tables}
+% \changes{v2.7e}{2017/03/06}{Modified treatment of \texttt{+} }
+% \changes{v2.7f}{2017/03/23}{Fixed spacing with \opt{reciprocal-positive-first}
+% setting}
+% \changes{v2.7g}{2017/05/19}{Fixed an issue with recent \pkg{expl3} update}
+% \changes{v2.7h}{2017/06/12}{Modified code internals}
+% \changes{v2.7i}{2017/07/23}{Fixed an incorrect variable name}
+% \changes{v2.7k}{2017/11/01}{Fixed formatting of units when not parsed}
+% \changes{v2.7l}{2018/03/11}{Modified \pkg{unicode-math} support}
+% \changes{v2.7m}{2018/03/20}{Modified definition of \cs{astronomicalunit} unit}
+% \changes{v2.7n}{2018/04/27}{Fixed symbolic input and digit grouping}
+% \changes{v2.7q}{2018/05/11}{Fixed patching of \pkg{cellspace} columns}
+% \changes{v2.7r}{2018/05/16}{Fixed issue in tabulars when REV\TeX{} is in use}
+% \changes{v2.7s}{2018/05/17}{Modified package date format}
+%
+%\begin{abstract}
+% Physical quantities have both numbers and units, and each physical
+% quantity should be expressed as the product of a number and a unit.
+% Typesetting physical quantities requires care to ensure that the
+% combined mathematical meaning of the number--unit combination is
+% clear. In particular, the SI units system lays down a consistent
+% set of units with rules on how these are to be used. However,
+% different countries and publishers have differing conventions on
+% the exact appearance of numbers (and units).
+%
+% The \pkg{siunitx} package provides a set of tools for authors
+% to typeset quantities in a consistent way. The package has an
+% extended set of configuration options which make it possible to
+% follow varying typographic conventions with the same input syntax.
+% The package includes automated processing of numbers and units, and
+% the ability to control tabular alignment of numbers.
+%\end{abstract}
+%
+%\tableofcontents
+%
+%\begin{documentation}
+%
+%\section{Introduction}
+%
+% The correct application of units of measurement is very important
+% in technical applications. For this reason, carefully-crafted
+% definitions of a coherent units system have been laid down by the
+% \emph{Conf\'erence G\'en\'erale des Poids et
+% Mesures} (CGPM): this has resulted in the \emph{Syst\`eme
+% International d'Unit\'es} (SI). At the same time, typographic
+% conventions for correctly displaying both numbers and units exist to
+% ensure that no loss of meaning occurs in printed matter.
+%
+% \pkg{siunitx} aims to provide a unified method for \LaTeX{} users to
+% typeset numbers and units correctly and easily. The design
+% philosophy of \pkg{siunitx} is to follow the agreed rules by
+% default, but to allow variation through option settings. In this way,
+% users can use \pkg{siunitx} to follow the requirements of
+% publishers, co-authors, universities, \emph{etc}.~without needing to
+% alter the input at all.
+%
+%\section{Installation}
+%
+% The package is supplied in \file{dtx} format and as a pre-extracted
+% zip file, \file{\jobname.tds.zip}. The later is most convenient for
+% most users: simply unzip this in your local texmf directory and
+% run \texttt{texhash} to update the database of file locations. If
+% you want to unpack the \file{dtx} yourself, running
+% \texttt{tex \jobname.dtx} will extract the package whereas
+% \texttt{latex \jobname.dtx} will extract it and also typeset the
+% documentation.
+%
+% The package requires \LaTeX3 support as provided in the
+% \pkg{l3kernel} and \pkg{l3packages} bundles. Both of these are available
+% on \href{http://www.ctan.org}{\textsc{ctan}} as ready-to-install
+% zip files. Suitable versions are available in MiK\TeX{}~2.9 and
+% \TeX{}~Live 2015 (updating the relevant packages online may be
+% necessary). \LaTeX3, and so \pkg{siunitx}, requires the \eTeX{}
+% extensions: these are available on all modern \TeX{} systems.
+%
+% Typesetting the documentation requires a number of packages in
+% addition to those needed to use the package. This is mainly
+% because of the number of demonstration items included in the text. To
+% compile the documentation without error, you will need the packages:
+%\begin{itemize}
+% \item \pkg{amsmath}
+% \item \pkg{booktabs}
+% \item \pkg{cancel}
+% \item \pkg{caption}
+% \item \pkg{cleveref}
+% \item \pkg{colortbl}
+% \item \pkg{csquotes}
+% \item \pkg{helvet}
+% \item \pkg{mathpazo}
+% \item \pkg{multirow}
+% \item \pkg{listings}
+% \item \pkg{pgfplots}
+% \item \pkg{xcolor}
+%\end{itemize}
+%
+%\section{\pkg{siunitx} for the impatient}
+%
+% The package provides the user macros:
+%\begin{itemize}
+% \item \cs{ang}\oarg{options}\marg{angle}
+% \item \cs{num}\oarg{options}\marg{number}
+% \item \cs{si}\oarg{options}\marg{unit}
+% \item \cs{SI}\oarg{options}\marg{number}\oarg{pre-unit}\marg{unit}
+% \item \cs{numlist}\oarg{options}\marg{numbers}
+% \item \cs{numrange}\oarg{options}\marg{numbers}\marg{number2}
+% \item \cs{SIlist}\oarg{options}\marg{numbers}\marg{unit}
+% \item \cs{SIrange}\oarg{options}\marg{number1}\marg{number2}^^A
+% \marg{unit}
+% \item \cs{sisetup}\marg{options}
+% \item \cs{tablenum}\oarg{options}\marg{number}
+%\end{itemize}
+% plus the \texttt{S} and \texttt{s} column types for decimal
+% alignments and units in tabular environments. These user macros and
+% column types are designed for
+% typesetting numbers and units with control of appearance and with
+% intelligent processing.
+%
+% Numbers are processed with understanding of exponents, complex numbers
+% and multiplication.
+%\begin{LaTeXdemo}
+% \num{12345,67890} \\
+% \num{1+-2i} \\
+% \num{.3e45} \\
+% \num{1.654 x 2.34 x 3.430}
+%\end{LaTeXdemo}
+%
+% The unit system can interpret units given as text to be used directly
+% or as macro-based units. In the latter case, different formatting is
+% possible.
+%\begin{LaTeXdemo}
+% \si{kg.m.s^{-1}} \\
+% \si{\kilogram\metre\per\second} \\
+% \si[per-mode=symbol]
+% {\kilogram\metre\per\second} \\
+% \si[per-mode=symbol]
+% {\kilogram\metre\per\ampere\per\second}
+%\end{LaTeXdemo}
+%
+% Simple lists and ranges of numbers can be handled.
+%\begin{LaTeXdemo}
+% \numlist{10;20;30} \\
+% \SIlist{0.13;0.67;0.80}{\milli\metre} \\
+% \numrange{10}{20} \\
+% \SIrange{0.13}{0.67}{\milli\metre}
+%\end{LaTeXdemo}
+%
+% By default, all text is typeset in the current upright math
+% font. This can be changed by setting the appropriate options:
+% "\sisetup{detect-all}" will use the current font for typesetting.
+%
+%\section{Using the \pkg{siunitx} package}
+%
+%\subsection{Loading the package}
+%
+% The package should be loaded in the usual \LaTeXe{} way.
+%\begin{LaTeXdemo}[code only]
+% \usepackage{siunitx}
+%\end{LaTeXdemo}
+% The key--value options described later in this document can be used
+% when loading the package, for example
+%\begin{LaTeXdemo}[code only]
+% \usepackage[version-1-compatibility]{siunitx}
+%\end{LaTeXdemo}
+% to use options from version 1 of the package.
+%
+%\subsection{Numbers}
+%
+%\DescribeMacro{\num}
+%\begin{syntax}
+% \cs{num}\oarg{options}\marg{number}
+%\end{syntax}
+% 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.
+%
+%\DescribeMacro{\numlist}
+%\begin{syntax}
+% \cs{numlist}\oarg{options}\marg{numbers}
+%\end{syntax}
+%\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}
+%
+%\DescribeMacro{\numrange}
+%\begin{syntax}
+% \cs{numrange}\oarg{options}\marg{number1}\marg{number2}
+%\end{syntax}
+% 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}
+%
+%\DescribeMacro{\ang}
+%\begin{syntax}
+% \cs{ang}\oarg{options}\marg{angle}
+%\end{syntax}
+% 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}
+%
+%\DescribeMacro{\si}
+%\begin{syntax}
+% \cs{si}\oarg{options}\marg{unit}
+%\end{syntax}
+% 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.
+%
+%\DescribeMacro{\SI}
+%\begin{syntax}
+% \cs{SI}\oarg{options}\marg{number}\oarg{preunit}\marg{unit}
+%\end{syntax}
+% 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}.
+%
+%\DescribeMacro{\SIlist}
+%\begin{syntax}
+% \cs{SIlist}\oarg{options}\marg{numbers}\marg{unit}
+%\end{syntax}
+% 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}
+%
+%\DescribeMacro{\SIrange}
+%\begin{syntax}
+% \cs{SIrange}\oarg{options}\marg{number1}\marg{number2}\marg{unit}
+%\end{syntax}
+% 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}.
+%
+%\DescribeMacro{\meter}
+% 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}
+%
+%\DescribeMacro{\celsius}
+% 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}
+%
+%\DescribeMacro{\deka}
+% 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}
+%
+%\DescribeMacro{\square}
+%\DescribeMacro{\squared}
+%\DescribeMacro{\cubic}
+%\DescribeMacro{\cubed}
+% 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}
+%\DescribeMacro{\tothe}
+%\DescribeMacro{\raiseto}
+% 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}
+%\DescribeMacro{\per}
+% 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}
+%\DescribeMacro{\of}
+%\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}
+%
+%\DescribeMacro{\cancel}
+%\DescribeMacro{\highlight}
+%\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}
+%
+%\DescribeMacro{\tablenum}
+%\begin{syntax}
+% \cs{tablenum}\oarg{options}\marg{number}
+%\end{syntax}
+%\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={}^{\circ}= \\
+% math-micro & Literal & \meta{see text} \\
+% math-ohm & Literal & \cs{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=\ensuremath{{}^{\circ}}= \\
+% & & \verb=\kern -\scriptspace C= \\
+% text-degree & Literal & \verb=\ensuremath{{}^{\circ}}= \\
+% text-micro & Literal & \meta{see text} \\
+% text-ohm & Literal & \verb=\ensuremath{\Omega}= \\
+% \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.}
+%
+% \changes{v2.4a}{2011/12/04}{Use UTF-8 symbols with \XeTeX{} and \LuaTeX{}
+% if \pkg{fontspec} is loaded}
+% When using \XeTeX{} or \LuaTeX{}, if \pkg{fontspec} is loaded these options
+% are redefined to use UTF-8 characters directly.
+%
+%\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@morningstar2.co.uk}
+% {\texttt{joseph.wright@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}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=siunitx>
+% \end{macrocode}
+%
+%\subsection{Preliminaries}
+%
+% The usual preliminaries.
+% \begin{macrocode}
+\ProvidesExplPackage {siunitx} {2018/05/17} {2.7s}
+ {A comprehensive (SI) units package}
+% \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).
+% \begin{macrocode}
+\@ifpackagelater { expl3 } { 2015/11/15 }
+ { }
+ {
+ \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
+ }
+% \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.
+% \begin{macrocode}
+\msg_new:nnnn { siunitx } { incompatible-package }
+ { Package~'#1'~incompatible. }
+ { The~#1~package~and~siunitx~are~incompatible. }
+\cs_new_protected:Npn \@@_load_check:n #1 {
+ \group_begin:
+ \@ifpackageloaded {#1}
+ { \msg_error:nnx { siunitx } { incompatible-package } {#1} }
+ { }
+ \group_end:
+}
+\clist_map_function:nN
+ { SIunits , sistyle , siunits , SIstyle , unitsdef , fancyunits }
+ \@@_load_check:n
+\AtBeginDocument {
+ \clist_map_function:nN { SIunits , sistyle , siunits , SIstyle }
+ \@@_load_check:n
+}
+% \end{macrocode}
+%\end{macro}
+%
+% Now load the support packages.
+% \begin{macrocode}
+\RequirePackage{ amstext , array , l3keys2e }
+% \end{macrocode}
+%
+%\begin{macro}{\@@_tmp:w}
+% A scratch function.
+% \begin{macrocode}
+\cs_new:Npn \@@_tmp:w { }
+% \end{macrocode}
+%\end{macro}
+%
+% Add some variants.
+% \begin{macrocode}
+\cs_generate_variant:Nn \clist_map_function:nN { nc }
+\cs_generate_variant:Nn \tl_if_blank:nTF { V }
+\cs_generate_variant:Nn \tl_replace_all:Nnn { No, NV , Nx }
+% \end{macrocode}
+%
+%\begin{macro}{
+% \l_@@_tmp_bool ,
+% \l_@@_tmp_box ,
+% \l_@@_tmp_dim ,
+% \l_@@_tmp_int ,
+% \l_@@_tmpa_tl ,
+% \l_@@_tmpb_tl
+%}
+% Scratch variables.
+% \begin{macrocode}
+\bool_new:N \l_@@_tmp_bool
+\box_new:N \l_@@_tmp_box
+\dim_new:N \l_@@_tmp_dim
+\int_new:N \l_@@_tmp_int
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_error:nxx ,
+% \@@_error:nx ,
+% \@@_error:n
+%}
+%\begin{macro}{\l_@@_error_bool}
+% General-purpose functions for throwing errors.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_error:nxx #1#2#3 {
+ \bool_set_true:N \l_@@_error_bool
+ \msg_error:nnxx { siunitx } {#1} {#2} {#3}
+}
+\cs_new_protected:Npn \@@_error:nx #1#2 {
+ \@@_error:nxx {#1} {#2} { }
+}
+\cs_new_protected:Npn \@@_error:n #1 {
+ \@@_error:nxx {#1} { } { }
+}
+\bool_new:N \l_@@_error_bool
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+% Some of the \texttt{TS1} encoding is needed to provide symbols in
+% text mode. If the user has not loaded the encoding themselves, it is
+% done here.
+% \begin{macrocode}
+\AtBeginDocument {
+ \cs_if_free:cT { T@TS1 }
+ {
+ \DeclareFontEncoding { TS1 } { } { }
+ \DeclareFontSubstitution { TS1 } { cmr } { m } { n }
+ }
+}
+% \end{macrocode}
+%
+%\begin{macro}{
+% \c_@@_minus_tl ,
+% \c_@@_minus_int
+%}
+% To allow the correct symbol to appear in text mode: this is the same
+% as \cs{textminus} from \pkg{textcomp}. If \pkg{fontspec} is loaded
+% then the real character can be used unless there's a good reason
+% to suspect
+% \begin{macrocode}
+\DeclareTextSymbolDefault \c_@@_minus_tl { TS1 }
+\DeclareTextSymbol \c_@@_minus_tl { TS1 } { 61 }
+\AtBeginDocument {
+ \@ifpackageloaded { fontspec }
+ {
+ \@ifpackageloaded { eulervm }
+ { }
+ {
+ \int_const:Nn \c_@@_minus_int { 8722 }
+ \tl_set:Nn \c_@@_minus_tl
+ { \tex_char:D \c_@@_minus_int }
+ }
+ }
+ { }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \c_@@_mu_tl ,
+% \c_@@_mu_int
+%}
+% The lack of an upright mu has to be sorted out. The same consideration
+% for \pkg{fontspec} as above.
+% \begin{macrocode}
+\DeclareTextSymbol \c_@@_mu_tl { TS1 } { 181 }
+\DeclareTextSymbolDefault \c_@@_mu_tl { TS1 }
+\AtBeginDocument {
+ \@ifpackageloaded { fontspec }
+ {
+ \int_const:Nn \c_@@_mu_int { 181 }
+ \tl_set:Nn \c_@@_mu_tl { \tex_char:D \c_@@_mu_int }
+ }
+ { }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\g_@@_omega_tl}
+% Some package redefine \cs{Omega} to be slanted and move the original
+% symbol to \cs{upOmega}. This is handled here.
+% \begin{macrocode}
+\tl_new:N \g_@@_omega_tl
+\tl_gset:Nn \g_@@_omega_tl { \Omega }
+\AtBeginDocument {
+ \cs_if_exist:NT \upOmega
+ { \tl_set:Nn \g_@@_omega_tl { \upOmega } }
+}
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}
+% {
+% \@@_tl_put_left_math:Nn ,
+% \@@_tl_put_left_math:NV ,
+% }
+% To add stuff in math mode.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_tl_put_left_math:Nn #1#2
+ { \tl_put_left:Nn #1 { \ensuremath {#2} } }
+\cs_generate_variant:Nn \@@_tl_put_left_math:Nn { NV }
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{\c_@@_old_options_seq}
+% To pick up old options, all of the names need to be known.
+% \begin{macrocode}
+\exp_args:NNx \seq_const_from_clist:Nn \c_@@_old_options_seq
+ {
+ \tl_to_str:n
+ {
+ addsign ,
+ allowlitunits ,
+ allowoptarg ,
+ allowzeroexp ,
+ alsoload ,
+ angformat ,
+ anglesep ,
+ astroang ,
+ closeerr ,
+ closrfrac ,
+ closerange ,
+ colour ,
+ colorall ,
+ colourall ,
+ colorneg ,
+ colourneg ,
+ colourunits ,
+ colourunits ,
+ colorvalues ,
+ colourvalues ,
+ decimalsymbol ,
+ debug ,
+ detectdisplay ,
+ digitsep ,
+ dp ,
+ emulate ,
+ errspace ,
+ eVcorra ,
+ eVcorrb ,
+ expbase ,
+ expproduct ,
+ fixdp ,
+ fixsf ,
+ fraction ,
+ inlinebold ,
+ loctolang ,
+ log ,
+ load ,
+ mathOmega ,
+ mathcelsius ,
+ mathdegree ,
+ mathminute ,
+ mathmu ,
+ mathringA ,
+ mathrm ,
+ mathsOmega ,
+ mathscelsius ,
+ mathsdegree ,
+ mathsecond ,
+ mathsf ,
+ mathsminute ,
+ mathsmu ,
+ mathsringA ,
+ mathsrm ,
+ mathssecond ,
+ mathssf ,
+ mathstt ,
+ mathtt ,
+ negcolor ,
+ negcolour ,
+ noload ,
+ numaddn ,
+ numcloseerr ,
+ numdecimal ,
+ numdigits ,
+ numdiv ,
+ numexp ,
+ numgobble ,
+ numopenerr ,
+ numprod ,
+ numsign ,
+ obeyall ,
+ obeybold ,
+ obeyfamily ,
+ obeymode ,
+ obeyitalic ,
+ openerr ,
+ openfrac ,
+ openrange ,
+ padangle ,
+ padnumber ,
+ per ,
+ prefixbase ,
+ prefixproduct ,
+ prefixsymbolic ,
+ prespace ,
+ redefsymbols ,
+ repeatunits ,
+ retainplus ,
+ seperr ,
+ sepfour ,
+ sf ,
+ sign ,
+ slash ,
+ stickyper ,
+ strictarc ,
+ tabalign ,
+ tabalignexp ,
+ tabautofit ,
+ tabexpalign ,
+ tabformat ,
+ tabnumalign ,
+ tabparseonly ,
+ tabtextalign ,
+ textOmega ,
+ textcelsius ,
+ textdegree ,
+ textminute ,
+ textmode ,
+ textmu ,
+ textringA ,
+ textrm ,
+ textsecond ,
+ textsf ,
+ texttt ,
+ tightpm ,
+ tophrase ,
+ trapamigerr ,
+ trapambigfrac ,
+ trapambigrange ,
+ unitcolor ,
+ unitcolour ,
+ unitmathrm ,
+ unitmathsf ,
+ unitmathsrm ,
+ unitmathssf ,
+ unitmathstt ,
+ unitmathtt ,
+ unitmode ,
+ unitsep ,
+ unitspace ,
+ valuecolor ,
+ valuecolour ,
+ valuemathrm ,
+ valuemathsf ,
+ valuemathsrm ,
+ valuemathssf ,
+ valuemathstt ,
+ valuemathtt ,
+ valuemode ,
+ valuesep ,
+ xspace
+ }
+ }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_key_tl}
+% Unknown options should raise an \pkg{siunitx}-specific error message.
+% \begin{macrocode}
+\tl_new:N \l_@@_key_tl
+\keys_define:nn { siunitx } {
+ unknown .code:n =
+ {
+ \seq_if_in:NVTF \c_@@_old_options_seq \l_keys_key_tl
+ {
+ \msg_warning:nnx { siunitx } { version-1-option }
+ { \exp_not:V \l_keys_key_tl }
+ \tl_set:Nx \l_@@_key_tl
+ {
+ \keys_set:nn { siunitx }
+ {
+ \exp_not:V \l_keys_key_tl
+ \tl_if_blank:nF {#1} { = \exp_not:n {#1} }
+ }
+ }
+ \keys_set:nn { siunitx } { version-1-compatibility }
+ \tl_use:N \l_@@_key_tl
+ }
+ {
+ \msg_error:nnx { siunitx } { unknown-option }
+ { \exp_not:V \l_keys_key_tl }
+ }
+ }
+}
+\AtBeginDocument {
+ \keys_define:nn { siunitx } {
+ unknown .code:n =
+ {
+ \seq_if_in:NVTF \c_@@_old_options_seq \l_keys_key_tl
+ {
+ \msg_error:nnx { siunitx } { version-1-option }
+ { \exp_not:V \l_keys_key_tl }
+ }
+ {
+ \msg_error:nnx { siunitx } { unknown-option }
+ { \exp_not:V \l_keys_key_tl }
+ }
+ }
+}
+}
+% \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
+ {
+ \token_get_prefix_spec:N #1
+ \token_get_arg_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 }
+ \tl_set:Nn \c_@@_minus_tl { \HCode { &\#x2212; } }
+ }
+ { }
+ }
+% \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
+\AtBeginDocument
+ {
+ \@ifpackageloaded { bidi }
+ {
+ \sys_if_engine_xetex:T
+ { \cs_set_protected:Npn \@@_ensure_ltr:n #1 { \LRE {#1} } }
+ }
+ { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_textsuperscript:n}
+% This function is set up here so that it can be redefined
+% elsewhere as expandable. That is used in the bookmark system so
+% that \pkg{hyperref} does not raise any unnecessary warnings. With
+% \pkg{fontspec} loaded the kernel defintion for \cs{textsuperscript}
+% may get altered so a private copy of the orignal code is used. (Yes,
+% this really should be done like Con\TeX{}t
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_textsuperscript:n #1
+ {
+ \m@th
+ \ensuremath { ^ { \mbox { \fontsize \sf@size \z@ \selectfont #1 } } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{\l_@@_display_math_bool}
+% To test for display math, a flag is added to the start of every
+% display environment.
+% \begin{macrocode}
+\bool_new:N \l_@@_display_math_bool
+\tex_everydisplay:D \exp_after:wN
+ {
+ \tex_the:D \tex_everydisplay:D
+ \bool_set_true:N \l_@@_display_math_bool
+ }
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}[TF]{\prop_get:NVN}
+% Missing from \pkg{expl3} at the moment.
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_get:NnNT { NV }
+\cs_generate_variant:Nn \prop_get:NnNF { NV }
+\cs_generate_variant:Nn \prop_get:NnNTF { NV }
+% \end{macrocode}
+% \end{macro}
+%
+%\subsection{Font detection}
+%
+% A number of controls and tests are needed to control the font used
+% for output. The detection routines set up various functions which can
+% then be used inside the \cs{text} macro from the \pkg{amstext}
+% package. By carrying out the changes outside math mode, bold can
+% reliably be applied to math output.
+%
+%\begin{macro}{\@@_set_math_fam:n}
+%\begin{macro}{
+% \c_@@_mathsf_int ,
+% \c_@@_mathtt_int
+%}
+% The detection routine needs some basic data about the sans serif and
+% monospaced fonts in use. This is collected up at the start of the
+% document. The families used can change between here and the start of
+% the document. This is run as a hook onto \cs{document}, rather than
+% using \cs{AtBeginDocument} as it has to come after anything that
+% \pkg{fontspec} does (nasty errors arise otherwise).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_math_fam:n #1 {
+ \group_begin:
+ \hbox_set:Nn \l_@@_tmp_box
+ {
+ \ensuremath
+ {
+ \use:c { math #1 }
+ {
+ \int_const:cn { c_@@_math #1 _int } { \fam }
+ }
+ }
+ }
+ \group_end:
+}
+\tl_put_right:Nn \document
+ {
+ \@@_set_math_fam:n { sf }
+ \@@_set_math_fam:n { tt }
+ \ignorespaces
+ }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_font_set_text_fam:n}
+%\begin{macro}{
+% \c_@@_textsf_tl ,
+% \c_@@_texttt_tl
+%}
+% The text families are done in a somewhat different manner: there are
+% no issues with \cs{AtBeginDocument}, luckily. The need to define
+% new macros here arises as \cs{sfdefault} and \cs{ttdefault} are
+% \cs{long}, whereas \cs{f@family} is not.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_text_fam:n #1 {
+ \tl_const:cx { c_@@_text #1 _tl } { \use:c { #1 default } }
+}
+\AtBeginDocument {
+ \@@_set_text_fam:n { sf }
+ \@@_set_text_fam:n { tt }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_detect_inline_weight_tl}
+% Used by the keys, but needs to be created here.
+% \begin{macrocode}
+\tl_new:N \l_@@_detect_inline_weight_tl
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{variable}{\l_@@_detect_inline_family_tl}
+% This one is not generated by the keys system.
+% \begin{macrocode}
+\tl_new:N \l_@@_detect_inline_family_tl
+% \end{macrocode}
+% \end{variable}
+%
+%\begin{macro}{
+% \l_@@_detect_display_math_bool ,
+% \l_@@_detect_family_bool ,
+% \l_@@_detect_inline_family_tl ,
+% \l_@@_detect_shape_bool ,
+% \l_@@_detect_mode_bool ,
+% \l_@@_detect_weight_bool
+%}
+% Font detection is all about creating switches, with just a little
+% gloss for \texttt{detect-all} and \texttt{detect-none}.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ detect-all .choice:,
+ detect-all .default:n = true,
+ detect-all / false .meta:n =
+ {
+ detect-family = false ,
+ detect-mode = false ,
+ detect-shape = false ,
+ detect-weight = false ,
+ },
+ detect-all / true .meta:n =
+ {
+ detect-family = true ,
+ detect-mode = true ,
+ detect-shape = true ,
+ detect-weight = true ,
+ },
+ detect-display-math .bool_set:N =
+ \l_@@_detect_display_math_bool,
+ detect-family .bool_set:N = \l_@@_detect_family_bool,
+ detect-inline-family .choice:,
+ detect-inline-family .value_required:n = true,
+ detect-inline-family /
+ math .code:n =
+ { \tl_set:Nn \l_@@_detect_inline_family_tl { math } },
+ detect-inline-family /
+ text .code:n =
+ { \tl_set:Nn \l_@@_detect_inline_family_tl { text } },
+ detect-inline-weight .choice:,
+ detect-inline-weight .value_required:n = true,
+ detect-inline-weight /
+ math .code:n =
+ { \tl_set:Nn \l_@@_detect_inline_weight_tl { math } },
+ detect-inline-weight /
+ text .code:n =
+ { \tl_set:Nn \l_@@_detect_inline_weight_tl { text } },
+ detect-italic .bool_set:N = \l_@@_detect_shape_bool,
+ detect-mode .bool_set:N = \l_@@_detect_mode_bool,
+ detect-none .choice:,
+ detect-none .default:n = true,
+ detect-none / false .meta:n =
+ {
+ detect-family = true,
+ detect-mode = true,
+ detect-shape = true,
+ detect-weight = true
+ },
+ detect-none / true .meta:n =
+ {
+ detect-family = false,
+ detect-mode = false,
+ detect-shape = false,
+ detect-weight = false
+ },
+ detect-shape .bool_set:N = \l_@@_detect_shape_bool,
+ detect-weight .bool_set:N = \l_@@_detect_weight_bool
+}
+\keys_set:nn { siunitx } {
+ detect-inline-family = text ,
+ detect-inline-weight = text ,
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\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@version { bold }
+ {
+ \cs_set:Npn \@@_font_weight:
+ {
+ \boldmath
+ \bfseries
+ }
+ }
+ \str_if_eq:VnT \math@version { light }
+ { \cs_set:Npn \@@_font_weight: { \lseries } }
+}
+\cs_new_protected:Npn \@@_detect_font_weight_text: {
+ \tl_set:Nx \l_@@_tmpa_tl { \tl_head:N \f@series }
+ \str_if_eq:VnT \l_@@_tmpa_tl { b }
+ {
+ \cs_set:Npn \@@_font_weight:
+ {
+ \boldmath
+ \bfseries
+ }
+ }
+ \str_if_eq:VnT \l_@@_tmpa_tl { l }
+ { \cs_set:Npn \@@_font_weight: { \lseries } }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_detect_font_family:}
+% Family detection usually picks up the surrounding text. However, for
+% display math there are two options, and so a second test may be made.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_detect_font_family: {
+ \mode_if_math:TF
+ {
+ \bool_if:NTF \l_@@_display_math_bool
+ {
+ \bool_if:NTF \l_@@_detect_display_math_bool
+ { \@@_detect_font_family_math: }
+ { \@@_detect_font_family_text: }
+ }
+ {
+ \use:c
+ {
+ @@_detect_font_family_
+ \l_@@_detect_inline_family_tl
+ :
+ }
+ }
+ }
+ { \@@_detect_font_family_text: }
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{
+% \@@_detect_font_family_math: ,
+% \@@_detect_font_family_text:
+%}
+% The two detections routines check if the current font is sans serif or
+% monospaced. The method used depends on whether the current math or
+% text font is of interest. The math detection routine re-applies the
+% default (\texttt{rm}), as the text function is always called and may
+% have changed things.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_detect_font_family_math: {
+ \tl_set:Nn \l_@@_font_family_tl { rm }
+ \int_compare:nNnT { \fam } = { \c_@@_mathsf_int }
+ { \tl_set:Nn \l_@@_font_family_tl { sf } }
+ \int_compare:nNnT { \fam } = { \c_@@_mathtt_int }
+ { \tl_set:Nn \l_@@_font_family_tl { tt } }
+}
+\cs_new_protected:Npn \@@_detect_font_family_text: {
+ \tl_if_eq:NNT \f@family \c_@@_textsf_tl
+ { \tl_set:Nn \l_@@_font_family_tl { sf } }
+ \tl_if_eq:NNT \f@family \c_@@_texttt_tl
+ { \tl_set:Nn \l_@@_font_family_tl { tt } }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_detect_font_shape:}
+% The shape test uses \cs{f@shape} as a handy indicator.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_detect_font_shape:
+ {
+ \cs_if_exist:cT { \f@shape shape }
+ {
+ \cs_set:Npx \@@_font_shape: { \exp_not:c { \f@shape shape } }
+ }
+ }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_detect_font_mode:}
+% The mode switch works from the fact that math mode output it the
+% standard.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_detect_font_mode: {
+ \mode_if_math:F
+ {
+ \bool_set_false:N \l_@@_font_math_mode_bool
+ \bool_set_false:N \l_@@_number_math_mode_bool
+ \bool_set_false:N \l_@@_unit_math_mode_bool
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\subsection{Font macros}
+%
+% With the detection routines in place, the module can apply the result
+% to control the font used for output. This requires a series of font
+% names to be available. The appropriate storage areas will be selected
+% by name, based on output type (\texttt{unit} or \texttt{value}) and
+% the family selected by the detector.
+%
+%\begin{macro}{
+% \l_@@_number_math_mode_bool ,
+% \l_@@_unit_math_mode_bool
+%}
+% Most of the variables are created by the keys system: these are not.
+% \begin{macrocode}
+\bool_new:N \l_@@_number_math_mode_bool
+\bool_new:N \l_@@_unit_math_mode_bool
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_number_mathrm:n ,
+% \@@_number_mathsf:n ,
+% \@@_number_mathtt:n ,
+% \@@_number_textrm: ,
+% \@@_number_textsf: ,
+% \@@_number_texttt:
+%}
+% Functions for number-mode fonts.
+% \begin{macrocode}
+\cs_new:Npn \@@_number_mathrm:n #1 { }
+\cs_new:Npn \@@_number_mathsf:n #1 { }
+\cs_new:Npn \@@_number_mathtt:n #1 { }
+\cs_new:Npn \@@_number_textrm: { }
+\cs_new:Npn \@@_number_textsf: { }
+\cs_new:Npn \@@_number_texttt: { }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_number_color_tl}
+% The settings are actually created separately for numbers and units:
+% numbers first.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ number-color .tl_set:N = \l_@@_number_color_tl,
+ number-math-rm .code:n =
+ { \cs_set:Npn \@@_number_mathrm:n ##1 { #1 {##1} } },
+ number-math-sf .code:n =
+ { \cs_set:Npn \@@_number_mathsf:n ##1 { #1 {##1} } },
+ number-math-tt .code:n =
+ { \cs_set:Npn \@@_number_mathtt:n ##1 { #1 {##1} } },
+ number-mode .choice:,
+ number-mode / math .code:n =
+ { \bool_set_true:N \l_@@_number_math_mode_bool },
+ number-mode / text .code:n =
+ { \bool_set_false:N \l_@@_number_math_mode_bool },
+ number-text-rm .code:n =
+ { \cs_set:Npn \@@_number_textrm: {#1} },
+ number-text-sf .code:n =
+ { \cs_set:Npn \@@_number_textsf: {#1} },
+ number-text-tt .code:n =
+ { \cs_set:Npn \@@_number_texttt: {#1} }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_unit_mathrm:n ,
+% \@@_unit_mathsf:n ,
+% \@@_unit_mathtt:n ,
+% \@@_unit_textrm: ,
+% \@@_unit_textsf: ,
+% \@@_unit_texttt:
+%}
+% The same storage for unit-mode fonts.
+% \begin{macrocode}
+\cs_new:Npn \@@_unit_mathrm: { }
+\cs_new:Npn \@@_unit_mathsf: { }
+\cs_new:Npn \@@_unit_mathtt: { }
+\cs_new:Npn \@@_unit_textrm: { }
+\cs_new:Npn \@@_unit_textsf: { }
+\cs_new:Npn \@@_unit_texttt: { }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_unit_color_tl}
+% Units look exactly the same.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ unit-color .tl_set:N = \l_@@_unit_color_tl,
+ unit-math-rm .code:n =
+ { \cs_set:Npn \@@_unit_mathrm:n ##1 { #1 {##1} } },
+ unit-math-sf .code:n =
+ { \cs_set:Npn \@@_unit_mathsf:n ##1 { #1 {##1} } },
+ unit-math-tt .code:n =
+ { \cs_set:Npn \@@_unit_mathtt:n ##1 { #1 {##1} } },
+ unit-mode .choice:,
+ unit-mode / math .code:n =
+ { \bool_set_true:N \l_@@_unit_math_mode_bool },
+ unit-mode / text .code:n =
+ { \bool_set_false:N \l_@@_unit_math_mode_bool },
+ unit-text-rm .code:n =
+ { \cs_set:Npn \@@_unit_textrm: {#1} },
+ unit-text-sf .code:n =
+ { \cs_set:Npn \@@_unit_textsf: {#1} },
+ unit-text-tt .code:n =
+ { \cs_set:Npn \@@_unit_texttt: {#1} }
+}
+% \end{macrocode}
+%\end{macro}
+%
+% The general settings are all meta-keys. A few initial values are set
+% here as they are needed for everything to work.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ color .meta:n =
+ {
+ number-color = #1,
+ unit-color = #1
+ },
+ math-rm .meta:n =
+ {
+ number-math-rm = #1,
+ unit-math-rm = #1
+ },
+ math-sf .meta:n =
+ {
+ number-math-sf = #1,
+ unit-math-sf = #1
+ },
+ math-tt .meta:n =
+ {
+ number-math-tt = #1,
+ unit-math-tt = #1
+ },
+ mode .choice:,
+ mode / math .meta:n =
+ {
+ number-mode = math,
+ unit-mode = math
+ },
+ mode / text .meta:n =
+ {
+ number-mode = text,
+ unit-mode = text
+ },
+ text-rm .meta:n =
+ {
+ number-text-rm = #1,
+ unit-text-rm = #1
+ },
+ text-sf .meta:n =
+ {
+ number-text-sf = #1,
+ unit-text-sf = #1
+ },
+ text-tt .meta:n =
+ {
+ number-text-tt = #1,
+ unit-text-tt = #1
+ }
+}
+\keys_set:nn { siunitx } {
+ math-rm = \mathrm,
+ math-sf = \mathsf,
+ math-tt = \mathtt,
+ mode = math,
+ text-rm = \rmfamily,
+ text-sf = \sffamily,
+ text-tt = \ttfamily,
+}
+% \end{macrocode}
+%
+% Some packages and classes (for example \pkg{beamer}) set the default
+% family to be something other than serif family. A one-off detection
+% will make life easier
+% all round.
+% \begin{macrocode}
+\AtBeginDocument {
+ \tl_set:Nx \l_@@_tmpa_tl { \familydefault }
+ \@ifpackageloaded { eulervm }
+ {
+ \cs_set:Npn \@@_tmp:w #1 { \mathrm {#1} }
+ \cs_if_eq:NNT \@@_number_mathrm:n \@@_tmp:w
+ { \keys_set:nn { siunitx } { number-math-rm = \mathnormal } }
+ \cs_if_eq:NNT \@@_unit_mathrm:n \@@_tmp:w
+ { \keys_set:nn { siunitx } { unit-math-rm = \mathnormal } }
+ }
+ { }
+ \tl_if_eq:NNT \l_@@_tmpa_tl \c_@@_textsf_tl
+ {
+ \@ifpackageloaded { arev }
+ { }
+ {
+ \@ifpackageloaded { cmbright }
+ { }
+ {
+ \cs_set:Npn \@@_tmp:w #1 { \mathrm {#1} }
+ \cs_if_eq:NNT \@@_number_mathrm:n \@@_tmp:w
+ { \keys_set:nn { siunitx } { number-math-rm = \mathsf } }
+ \cs_if_eq:NNT \@@_unit_mathrm:n \@@_tmp:w
+ { \keys_set:nn { siunitx } { unit-math-rm = \mathsf } }
+ }
+ }
+ \cs_set:Npn \@@_tmp:w { \rmfamily }
+ \cs_if_eq:NNT \@@_number_textrm: \@@_tmp:w
+ { \keys_set:nn { siunitx } { number-text-rm = \sffamily } }
+ \cs_if_eq:NNT \@@_unit_textrm: \@@_tmp:w
+ { \keys_set:nn { siunitx } { unit-text-rm = \sffamily } }
+ }
+ \tl_if_eq:NNT \l_@@_tmpa_tl \c_@@_texttt_tl
+ {
+ \cs_set:Npn \@@_tmp:w #1 { \mathrm {#1} }
+ \cs_if_eq:NNT \@@_number_mathrm:n \@@_tmp:w
+ { \keys_set:nn { siunitx } { number-math-rm = \mathtt } }
+ \cs_if_eq:NNT \@@_unit_mathrm:n \@@_tmp:w
+ { \keys_set:nn { siunitx } { unit-math-rm = \mathtt } }
+ \cs_set:Npn \@@_tmp:w { \rmfamily }
+ \cs_if_eq:NNT \@@_number_textrm: \@@_tmp:w
+ { \keys_set:nn { siunitx } { number-text-rm = \ttfamily } }
+ \cs_if_eq:NNT \@@_unit_textrm: \@@_tmp:w
+ { \keys_set:nn { siunitx } { unit-text-rm = \ttfamily } }
+ }
+}
+% \end{macrocode}
+%
+%\subsection{Output control}
+%
+% The \pkg{siunitx} output routine uses all of the font information
+% gathered earlier to print the text given in whatever font is required.
+% The low-level stuff is done here, with the calling routines expected
+% to have taken some steps first (this is to allow line breaks in the
+% appropriate places).
+%
+%\begin{macro}{\l_@@_print_arg_tl}
+% The text to print.
+% \begin{macrocode}
+\tl_new:N \l_@@_print_arg_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_print_type_tl}
+% The type of output (\texttt{number} or \texttt{unit}) is always
+% needed.
+% \begin{macrocode}
+\tl_new:N \l_@@_print_type_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_print:nn ,
+% \@@_print:nV
+%}
+%\begin{macro}{\@@_print_aux:}
+% The main printing function does everything inside a group, as
+% there are category code and definition changes to make. First, set
+% the fonts. Then move on to printing mode, before moving to actual
+% printing.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print:nn #1#2 {
+ \group_begin:
+ \tl_set:Nn \l_@@_print_type_tl {#1}
+ \tl_set:Nn \l_@@_print_arg_tl {#2}
+ \@@_detect_font:
+ \bool_if:NF \l_@@_detect_mode_bool
+ {
+ \bool_if:cTF { l_@@_ #1 _math_mode_bool }
+ { \bool_set_true:N \l_@@_font_math_mode_bool }
+ { \bool_set_false:N \l_@@_font_math_mode_bool }
+ }
+ \@@_print_aux:
+ \group_end:
+}
+\cs_generate_variant:Nn \@@_print:nn { nV }
+% \end{macrocode}
+% The various font changes are set up, then the correct printing
+% function is called. Everything is inside \cs{text} as this allows
+% proper setting of the various mode settings.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_aux:
+ {
+ \text
+ {
+ \@@_ensure_ltr:n
+ {
+ \color@begingroup
+ \@@_print_color:
+ \@@_font_shape:
+ \@@_font_weight:
+ \use:c
+ {
+ @@_ \l_@@_print_type_tl _
+ text \l_@@_font_family_tl :
+ }
+ \bool_if:NTF \l_@@_font_math_mode_bool
+ { \@@_print_math: }
+ { \@@_print_text: }
+ \color@endgroup
+ }
+ }
+ }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_print_color: ,
+% \@@_textcolor:n
+%}
+% The colour system checks if \pkg{color} is loaded, and only does
+% anything if it is. This will change when \LaTeX3 proper is available:
+% there will be colour out of the box!
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_color: {
+ \tl_if_empty:cF { l_@@_ \l_@@_print_type_tl _color_tl }
+ {
+ \color
+ {
+ \tl_use:c { l_@@_ \l_@@_print_type_tl _color_tl }
+ }
+ }
+}
+\AtBeginDocument {
+ \@ifpackageloaded { color }
+ { \cs_new_eq:NN \@@_textcolor:n \textcolor }
+ {
+ \cs_set_protected:Npn \@@_print_color:
+ {
+ \tl_if_empty:cF { l_@@_ \l_@@_print_type_tl _color_tl }
+ {
+ \cs_gset_eq:NN \@@_print_color: \scan_stop:
+ \msg_warning:nn { siunitx } { color-not-loaded }
+ }
+ }
+ \cs_new_protected:Npn \@@_textcolor:n #1
+ {
+ \cs_gset_eq:NN \@@_textcolor:n \use_none:n
+ \msg_warning:nn { siunitx } { color-not-loaded }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\@@_print_math:, \@@_print_text:}
+% \begin{macro}{\@@_print_text_aux:}
+% \begin{macro}{\@@_print_text_aux:NnN}
+% Printing the text means replacing any awkward characters, which is
+% dependent on the output mode. The rest of the package uses "_" and
+% "^" to represent sub- and superscripts, respectively. In this way,
+% mode decisions can be delayed as long as possible. The
+% \pkg{underscore} package may make "_" active, or more likely
+% it will be a superscript character. Both are tested for here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_math:
+ {
+ \cs_set_eq:NN \PrintSubscript \sb
+ \cs_set_eq:NN \PrintSuperscript \sp
+ \ensuremath
+ {
+ \use:c
+ {
+ @@_ \l_@@_print_type_tl _
+ math \l_@@_font_family_tl :n
+ }
+ { \l_@@_print_arg_tl }
+ }
+ }
+\cs_new_protected:Npn \@@_print_text:
+ {
+ \tl_replace_all:Nnn \l_@@_print_arg_tl { - }
+ { \c_@@_minus_tl }
+ \@@_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 { - }
+ { \c_@@_minus_tl }
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \exp_not:N \ensuremath
+ { \sp { \exp_not:N \text { \exp_not:V \l_@@_tmpa_tl } } }
+ }
+ \l_@@_tmpa_tl
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+% \end{macro}
+% \end{macro}
+%
+%\begin{macro}{
+% \PrintSubscript ,
+% \PrintSuperscript
+%}
+% In the unit-construction code, there are places where it cannot
+% be guarenteed that the search-and-replace approach will work.
+% Instead, two user-space functions are needed. These are only
+% defined within the above code: the names are not needed elsewhere.
+%\end{macro}
+%
+%\subsection{Pre-processing numbers}
+%
+% Before the main parsing routine can be called, there is a need to
+% pre-process the input. The possibility that the data in can contain
+% more than one number needs to be handled.
+%
+%\begin{macro}{\l_@@_input_product_tl}
+%\begin{macro}{\l_@@_input_quotient_tl}
+% There are a couple of settings which are created here as they are used
+% only for pre-processing.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ input-product .tl_set:N = \l_@@_input_product_tl,
+ input-quotient .tl_set:N = \l_@@_input_quotient_tl,
+}
+\keys_set:nn { siunitx } {
+ input-product = x,
+ input-quotient = /
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{
+% \l_@@_number_arg_tl ,
+% \l_@@_number_next_tl
+%}
+% Storage for the pre-parsed material. The \texttt{arg} variable
+% contains the current argument, the \texttt{next} variable contains
+% anything held-over for the next round.
+% \begin{macrocode}
+\tl_new:N \l_@@_number_arg_tl
+\tl_new:N \l_@@_number_next_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_number_multi_tl}
+% For products and quotients, a way of feeding information back.
+% \begin{macrocode}
+\tl_new:N \l_@@_number_multi_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \l_@@_number_denominator_tl ,
+% \l_@@_number_numerator_tl
+%}
+% When searching for quotients, some more storage is needed.
+% \begin{macrocode}
+\tl_new:N \l_@@_number_denominator_tl
+\tl_new:N \l_@@_number_numerator_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_number_preprocess:n ,
+% \@@_number_preprocess:V
+%}
+% The pre-processor starts with the obvious: the most likely outcome is
+% that all of the argument is passed through unchanged.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_preprocess:n #1 {
+ \@@_number_preprocess_init:
+ \tl_set:Nn \l_@@_number_arg_tl {#1}
+ \@@_number_preprocess_product:
+ \tl_if_empty:NT \l_@@_number_multi_tl
+ { \@@_number_preprocess_quotient: }
+}
+\cs_generate_variant:Nn \@@_number_preprocess:n { V }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_preprocess_init:}
+% A little initialisation as normal.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_preprocess_init: {
+ \bool_set_false:N \l_@@_error_bool
+ \tl_clear:N \l_@@_number_multi_tl
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_preprocess_product:}
+%\begin{macro}{\@@_number_preprocess_product_aux:N}
+% Rather than search through the entire argument, we use the
+% delimited-argument trick.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_preprocess_product: {
+ \tl_map_function:NN \l_@@_input_product_tl
+ \@@_number_preprocess_product_aux:N
+}
+\cs_new_protected:Npn \@@_number_preprocess_product_aux:N #1 {
+ \tl_if_in:NnT \l_@@_number_arg_tl {#1}
+ {
+ \cs_set:Npn \@@_tmp:w ##1 #1 ##2 \q_stop
+ {
+ \tl_set:Nn \l_@@_number_arg_tl {##1}
+ \tl_set:Nn \l_@@_number_next_tl {##2}
+ \tl_set:Nn \l_@@_number_multi_tl { product }
+ }
+ \exp_after:wN \@@_tmp:w \l_@@_number_arg_tl \q_stop
+ \tl_if_empty:NT \l_@@_number_arg_tl
+ { \@@_error:n { starting-product-token } }
+ \tl_if_empty:NT \l_@@_number_next_tl
+ { \@@_error:n { ending-product-token } }
+ \tl_map_break:
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_preprocess_quotient:}
+%\begin{macro}{\@@_number_preprocess_quotient_aux:N}
+% For the quotient, only one token can appear in each part. So there
+% is an additional error check.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_preprocess_quotient: {
+ \tl_map_function:NN \l_@@_input_quotient_tl
+ \@@_number_preprocess_quotient_aux:N
+}
+\cs_new_protected:Npn \@@_number_preprocess_quotient_aux:N #1 {
+ \tl_if_in:NnT \l_@@_number_arg_tl {#1}
+ {
+ \cs_set:Npn \@@_tmp:w ##1 #1 ##2 \q_stop
+ {
+ \tl_set:Nn \l_@@_number_numerator_tl {##1}
+ \tl_set:Nn \l_@@_number_denominator_tl {##2}
+ \tl_set:Nn \l_@@_number_multi_tl { quotient }
+ }
+ \exp_after:wN \@@_tmp:w \l_@@_number_arg_tl \q_stop
+ \tl_if_empty:NT \l_@@_number_numerator_tl
+ { \@@_error:n { starting-quotient-token } }
+ \tl_if_empty:NT \l_@@_number_denominator_tl
+ { \@@_error:n { ending-quotient-token } }
+ \tl_if_in:NnT \l_@@_number_denominator_tl {#1}
+ { \@@_error:n { duplicate-quotient-token } }
+ \tl_map_break:
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\subsection{Parsing numbers}
+%
+% The parser is designed to be relativity fast, which means some code is
+% more or less duplicated to gain more speed. It is also loaded so
+% that simple numbers (such as \num{-1.23}) are parsed particularly
+% quickly. For most documents, this gain more than offsets any slight
+% losses with more complicated numbers.
+%
+%\begin{macro}{\c_@@_number_part_complex_tl}
+% A couple of the comparisons needed for checking complex numbers
+% are done using stored text. To make them a little quicker, a
+% pre-stored version of the text is stored here.
+% \begin{macrocode}
+\tl_const:Nn \c_@@_number_part_complex_tl { complex }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \l_@@_number_in_complex_bool ,
+% \l_@@_number_in_complex_root_bool ,
+% \l_@@_number_in_decimal_bool ,
+% \l_@@_number_in_exponent_bool ,
+% \l_@@_number_in_first_bool ,
+% \l_@@_number_in_sign_bool ,
+% \l_@@_number_in_uncert_bool ,
+% \l_@@_number_in_value_bool
+%}
+% \begin{macrocode}
+\bool_new:N \l_@@_number_in_complex_bool
+\bool_new:N \l_@@_number_in_complex_root_bool
+\bool_new:N \l_@@_number_in_decimal_bool
+\bool_new:N \l_@@_number_in_exponent_bool
+\bool_new:N \l_@@_number_in_first_bool
+\bool_new:N \l_@@_number_in_sign_bool
+\bool_new:N \l_@@_number_in_uncert_bool
+\bool_new:N \l_@@_number_in_value_bool
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_number_in_prop}
+% The parsed number is stored in a property list as its constituent
+% parts.
+% \begin{macrocode}
+\prop_new:N \l_@@_number_in_prop
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_number_parsed_tl}
+% Each part of the number parsed has to be built up in a token list.
+% \begin{macrocode}
+\tl_new:N \l_@@_number_parsed_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \l_@@_number_part_tl ,
+% \l_@@_number_part_decimal_tl ,
+% \l_@@_number_part_decimal_marker_tl ,
+% \l_@@_number_part_integer_tl ,
+% \l_@@_number_part_sign_tl ,
+% \l_@@_number_part_uncert_tl
+%}
+% The names of various parts of a number are set up as stored values.
+% This lets some code be used for different parts of a number, while
+% pre-storing everything brings a performance (and clarity) benefit.
+% \begin{macrocode}
+\tl_new:N \l_@@_number_part_tl
+\tl_new:N \l_@@_number_part_decimal_tl
+\tl_new:N \l_@@_number_part_decimal_marker_tl
+\tl_new:N \l_@@_number_part_integer_tl
+\tl_new:N \l_@@_number_part_sign_tl
+\tl_new:N \l_@@_number_part_uncert_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \l_@@_number_mantissa_length_int
+% \l_@@_number_uncert_tl
+% \l_@@_number_uncert_length_int
+%}
+% Conversion of uncertainty forms requires some storage, mainly for
+% performance reasons.
+% \begin{macrocode}
+\int_new:N \l_@@_number_mantissa_length_int
+\tl_new:N \l_@@_number_uncert_tl
+\int_new:N \l_@@_number_uncert_length_int
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_input_uncert_sign_tl}
+% This one is stored by some low-level code, so is declared explicitly.
+% \begin{macrocode}
+\tl_new:N \l_@@_input_uncert_sign_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \l_@@_input_uncert_close_tl ,
+% \l_@@_input_complex_tl ,
+% \l_@@_input_comparator_tl ,
+% \l_@@_input_decimal_tl ,
+% \l_@@_input_digit_tl ,
+% \l_@@_input_exponent_tl ,
+% \l_@@_input_ignore_tl ,
+% \l_@@_input_uncert_open_tl ,
+% \l_@@_input_protect_tl ,
+% \l_@@_input_sign_tl ,
+% \l_@@_input_symbol_tl ,
+% \l_@@_input_uncert_sign_tl
+%}
+% The various tokens to check against when parsing are all set up here.
+% These are valid inside a single number: the pre-processor has already
+% set up the appropriate things for products and quotients.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ input-close-uncertainty .tl_set:N = \l_@@_input_uncert_close_tl ,
+ input-complex-roots .tl_set:N = \l_@@_input_complex_tl ,
+ input-comparators .tl_set:N = \l_@@_input_comparator_tl ,
+ input-decimal-markers .tl_set:N = \l_@@_input_decimal_tl ,
+ input-digits .tl_set:N = \l_@@_input_digit_tl ,
+ input-exponent-markers .tl_set:N = \l_@@_input_exponent_tl ,
+ input-ignore .tl_set:N = \l_@@_input_ignore_tl ,
+ input-open-uncertainty .tl_set:N = \l_@@_input_uncert_open_tl ,
+ input-protect-tokens .tl_set:N = \l_@@_input_protect_tl ,
+ input-signs .tl_set:N = \l_@@_input_sign_tl ,
+ input-symbols .tl_set:N = \l_@@_input_symbol_tl ,
+ input-uncertainty-signs .code:n =
+ {
+ \tl_set:Nn \l_@@_input_uncert_sign_tl {#1}
+ \tl_map_inline:nn {#1}
+ {
+ \tl_if_in:NnF \l_@@_input_sign_tl {##1}
+ { \tl_put_right:Nn \l_@@_input_sign_tl {##1} }
+ }
+ } ,
+}
+\keys_set:nn { siunitx } { % (
+ input-close-uncertainty = ),
+ input-complex-roots = ij,
+ input-comparators = {<=>\approx\ge\geq\gg\le\leq\ll\sim},
+ input-decimal-markers = {.,},
+ input-digits = 0123456789,
+ input-exponent-markers = dDeE,
+ input-open-uncertainty = (, % )
+ input-protect-tokens = \approx\dots\ge\geq\gg\le\leq\ll\mp\pi\pm\sim,
+ input-signs = +-\mp\pm,
+ input-symbols = \dots\pi,
+ input-uncertainty-signs = \pm,
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_number_in_parse:n ,
+% \@@_number_in_parse:V
+%}
+%\begin{macro}{\@@_number_in_parse_aux:n}
+% The parsing routine starts by replacing any formatting in the input
+% using \cs{tl_set_rescan:Nnx}. Next, there is a quick routine to
+% ensure that all signs are single tokens. The main loop then takes
+% place, which will parse the input into the property list and also
+% set up the flags. There are then some checks and possible corrections.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_parse:n #1 {
+ \tl_if_empty:nF {#1}
+ {
+ \@@_number_in_init:
+ \cs_set_eq:NN \@@_number_in_parse_more:N
+ \@@_number_in_parse_mantissa_aux:N
+ \@@_number_in_parse_aux:n {#1}
+ }
+}
+\cs_generate_variant:Nn \@@_number_in_parse:n { V }
+\group_begin:
+ \char_set_catcode_active:N \~
+ \char_set_catcode_space:N \ %
+ \cs_new_protected:Npn \@@_number_in_parse_aux:n#1%
+ {%
+ \group_begin:
+ \@@_number_in_protect:
+ \cs_set_eq:NN\,\prg_do_nothing:
+ \cs_set_eq:NN~\prg_do_nothing:
+ \tl_set_rescan:Nnx\l_@@_number_arg_tl
+ {%
+ \char_set_catcode_ignore:N\ %
+ \char_set_catcode_other:N\,%
+ \char_set_catcode_other:N\.%
+ }%
+ {#1}%
+ \exp_args:NNNV\group_end:
+ \tl_set:Nn\l_@@_number_arg_tl\l_@@_number_arg_tl
+ \@@_number_in_sign_replace:N\l_@@_number_arg_tl
+ \@@_number_in_parse_relation:N\l_@@_number_arg_tl
+ \tl_map_function:NN\l_@@_number_arg_tl
+ \@@_number_in_parse_loop:N
+ \tl_if_empty:NF\l_@@_number_parsed_tl
+ {%
+ \bool_if:NTF\l_@@_number_in_uncert_bool
+ {\@@_error:nx{invalid-number}{#1}}%
+ {%
+ \prop_put:NVn \l_@@_number_in_prop
+ \l_@@_number_part_tl {true}%
+ \bool_if:NTF\l_@@_number_in_decimal_bool
+ {%
+ \prop_put:NVV\l_@@_number_in_prop
+ \l_@@_number_part_decimal_tl
+ \l_@@_number_parsed_tl
+ }%
+ {%
+ \prop_put:NVV\l_@@_number_in_prop
+ \l_@@_number_part_integer_tl
+ \l_@@_number_parsed_tl
+ }%
+ }%
+ }%
+ \@@_number_in_check:n {#1}%
+ }
+\group_end:
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_number_in_init: ,
+% \@@_number_in_init_part:n
+%}
+% The set up code is divided into to parts. First, code only needed
+% once to start the entire parser. Then a second group, which is
+% carried out at the start of each part of a number, and so is called
+% from a few places.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_init: {
+ \cs_set_eq:NN \@@_number_in_parse_loop:N
+ \@@_number_in_parse_mantissa:N
+ \cs_set_eq:NN \@@_number_in_check:n
+ \@@_number_in_check_short:n
+ \tl_clear:N \l_@@_number_parsed_tl
+ \prop_clear:N \l_@@_number_in_prop
+ \bool_set_false:N \l_@@_error_bool
+ \bool_set_false:N \l_@@_number_in_complex_bool
+ \bool_set_false:N \l_@@_number_in_complex_root_bool
+ \bool_set_false:N \l_@@_number_in_exponent_bool
+ \bool_set_false:N \l_@@_number_in_uncert_bool
+ \@@_number_in_init_part:n { mantissa }
+}
+\cs_new_protected:Npn \@@_number_in_init_part:n #1 {
+ \bool_set_false:N \l_@@_number_in_decimal_bool
+ \bool_set_true:N \l_@@_number_in_first_bool
+ \bool_set_false:N \l_@@_number_in_sign_bool
+ \bool_set_false:N \l_@@_number_in_value_bool
+ \tl_set:Nn \l_@@_number_part_tl {#1}
+ \tl_set:Nn \l_@@_number_part_decimal_tl { #1 -decimal }
+ \tl_set:Nn \l_@@_number_part_decimal_marker_tl
+ { #1 -decimal-marker }
+ \tl_set:Nn \l_@@_number_part_integer_tl { #1 -integer }
+ \tl_set:Nn \l_@@_number_part_sign_tl { #1 -sign }
+ \tl_set:Nn \l_@@_number_part_uncert_tl { #1 -uncertainty }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_protect:}
+%\begin{macro}{\@@_number_in_protect_aux:N}
+% Under some circumstances (for example when loading \pkg{breqn})
+% some tokens do not behave safely under \texttt{x} expansion (at the
+% moment). To get round this, they are redefined here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_protect: {
+ \tl_map_function:NN \l_@@_input_protect_tl
+ \@@_number_in_protect_aux:N
+}
+\cs_new_protected:Npn \@@_number_in_protect_aux:N #1 {
+ \cs_set_eq:NN #1 \scan_stop:
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+% \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 }
+% \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 { }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_parse_relation:N}
+%\begin{macro}{\@@_number_in_parse_relation:w}
+% The idea here is that a relation with be the very first token in the
+% input, or it is not valid. So the test for a relation can be very
+% simple and hopefully efficient.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_parse_relation:N #1 {
+ \exp_after:wN \@@_number_in_parse_relation:w #1 \q_stop #1
+}
+\cs_new_protected:Npn \@@_number_in_parse_relation:w
+ #1#2 \q_stop #3 {
+ \tl_if_in:NnT \l_@@_input_comparator_tl {#1}
+ {
+ \prop_put:Nnn \l_@@_number_in_prop { comparator } {#1}
+ \tl_set:Nn #3 {#2}
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_parse_restricted:N}
+% When parsing numbers for the \cs{ang} function, no extended input
+% is permitted at all.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_parse_restricted:N #1 {
+ \tl_if_in:NnTF \l_@@_input_exponent_tl {#1}
+ {
+ \@@_number_in_parse_error:nn
+ { restricted-number } {#1}
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_uncert_open_tl {#1}
+ {
+ \@@_number_in_parse_error:nV
+ { restricted-number } \l_@@_number_arg_tl
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#1}
+ {
+ \@@_number_in_parse_error:nV
+ { restricted-number } \l_@@_number_arg_tl
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_complex_tl {#1}
+ {
+ \@@_number_in_parse_error:nV
+ { restricted-number } \l_@@_number_arg_tl
+ }
+ {
+ \@@_number_in_parse_error:nn
+ { restricted-number } {#1}
+ }
+ }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_parse_complex:N}
+% After a complex root when the root is \emph{after} the number, there
+% are a very limited range of legitimate tokens. Thus most cases can be
+% trapped with a modified parser.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_parse_complex:N #1 {
+ \tl_if_in:NnTF \l_@@_input_exponent_tl {#1}
+ {
+ \cs_set_eq:NN \@@_number_in_parse_loop:N
+ \@@_number_in_parse_mantissa:N
+ \@@_number_in_exponent:N #1
+ }
+ {
+ \tl_if_in:NnF \l_@@_input_ignore_tl {#1}
+ {
+ \@@_number_in_parse_error:nV
+ { misplaced-complex-root-token }
+ \l_@@_number_arg_tl
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_parse_exponent:N}
+% When processing an exponent, the \enquote{extended} part of the
+% number which is valid in a mantissa is no longer needed. So the
+% auxiliary function is pointed to a series of errors instead.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_parse_exponent:N #1 {
+ \tl_if_in:NnTF \l_@@_input_exponent_tl {#1}
+ {
+ \@@_number_in_parse_error:nn
+ { duplicate-exponent-token } { \token_to_str:N #1 }
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_uncert_open_tl {#1}
+ {
+ \@@_number_in_parse_error:nV
+ { invalid-token-in-exponent } \l_@@_number_arg_tl
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#1}
+ {
+ \@@_number_in_parse_error:nV
+ { invalid-token-in-exponent } \l_@@_number_arg_tl
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_complex_tl {#1}
+ {
+ \@@_number_in_parse_error:nV
+ { invalid-token-in-exponent }
+ \l_@@_number_arg_tl
+ }
+ {
+ \@@_number_in_parse_error:nn
+ { invalid-token-in-number } {#1}
+ }
+ }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_parse_mantissa:N}
+%\begin{macro}{\@@_number_in_parse_mantissa_aux:N}
+% For the mantissa, most things are valid. The procedure is split
+% into two parts, with the simple symbols handled here and the more
+% complex ones in a second part(which needs to be varied). Essentially
+% everything here is a comparison, done so that the code is a fast as
+% possible.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_parse_mantissa:N #1 {
+ \tl_if_in:NnTF \l_@@_input_digit_tl {#1}
+ { \@@_number_in_digit:n {#1} }
+ {
+ \tl_if_in:NnTF \l_@@_input_decimal_tl {#1}
+ { \@@_number_in_decimal:N #1 }
+ {
+ \tl_if_in:NnTF \l_@@_input_sign_tl {#1}
+ { \@@_number_in_sign:N #1 }
+ {
+ \tl_if_in:NnTF \l_@@_input_symbol_tl {#1}
+ {
+ \prop_put:Nnn \l_@@_number_in_prop { symbolic }
+ { true }
+ \@@_number_in_digit:n {#1}
+ }
+ {
+ \tl_if_in:NnF \l_@@_input_ignore_tl {#1}
+ { \@@_number_in_parse_more:N #1 }
+ }
+ }
+ }
+ }
+}
+\cs_new_protected:Npn \@@_number_in_parse_mantissa_aux:N #1 {
+ \tl_if_in:NnTF \l_@@_input_exponent_tl {#1}
+ { \@@_number_in_exponent:N #1 }
+ {
+ \tl_if_in:NnTF \l_@@_input_uncert_open_tl {#1}
+ { \@@_number_in_uncert_open:N #1 }
+ {
+ \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#1}
+ {
+ \@@_number_in_parse_error:nn
+ { misplaced-uncertainty-token } {#1}
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_complex_tl {#1}
+ { \@@_number_in_complex:N #1 }
+ {
+ \@@_number_in_parse_error:nn
+ { invalid-token-in-number } {#1}
+ }
+ }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_parse_uncert:N}
+% Within uncertainties, the range of tokens is limited. An alternative
+% parsing system can therefore be used.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_parse_uncert:N #1 {
+ \tl_if_in:NnTF \l_@@_input_digit_tl {#1}
+ { \@@_number_in_digit:n {#1} }
+ {
+ \tl_if_in:NnTF \l_@@_input_decimal_tl {#1}
+ {
+ \@@_number_in_parse_error:nV
+ { invalid-token-in-uncertainty }
+ \l_@@_number_arg_tl
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_sign_tl {#1}
+ {
+ \@@_number_in_parse_error:nV
+ { invalid-token-in-uncertainty }
+ \l_@@_number_arg_tl
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_symbol_tl {#1}
+ {
+ \prop_put:Nnn \l_@@_number_in_prop { symbolic }
+ { true }
+ \@@_number_in_digit:n {#1}
+ }
+ {
+ \tl_if_in:NnF \l_@@_input_ignore_tl {#1}
+ {
+ \tl_if_in:NnTF \l_@@_input_uncert_close_tl
+ {#1}
+ { \@@_number_in_uncert_close:N #1 }
+ {
+ \@@_number_in_parse_error:nV
+ { invalid-token-in-uncertainty }
+ \l_@@_number_arg_tl
+ }
+ }
+ }
+ }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_parse_uncert_after:N}
+% After an uncertainty, there is once again a very limited range of
+% tokens that can be present in a valid number.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_parse_uncert_after:N #1 {
+ \tl_if_in:NnTF \l_@@_input_exponent_tl {#1}
+ {
+ \cs_set_eq:NN \@@_number_in_parse_loop:N
+ \@@_number_in_parse_mantissa:N
+ \@@_number_in_exponent:N #1
+ }
+ {
+ \tl_if_in:NnTF \l_@@_input_sign_tl {#1}
+ {
+ \cs_set_eq:NN \@@_number_in_parse_loop:N
+ \@@_number_in_parse_mantissa:N
+ \@@_number_in_sign:N #1
+ }
+ {
+ \tl_if_in:NnF \l_@@_input_ignore_tl {#1}
+ {
+ \tl_if_in:NnTF \l_@@_input_complex_tl {#1}
+ {
+ \cs_set_eq:NN \@@_number_in_parse_loop:N
+ \@@_number_in_parse_mantissa:N
+ \@@_number_in_complex:N #1
+ }
+ {
+ \@@_number_in_parse_error:nV { invalid-number }
+ \l_@@_number_arg_tl
+ }
+ }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_complex:N}
+%\begin{macro}{\@@_number_in_complex_aux:nn}
+% Only one complex root token can be give, hence the initial test.
+% More tests are needed for complex numbers than other systems, so
+% the additional ones are turned on, followed by some flag setting.
+% The complex root is stored, then there is a check to see if the
+% root is at the end of the number: if it is, prevent any more tokens
+% being added.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_complex:N #1 {
+ \bool_set_false:N \l_@@_number_in_first_bool
+ \bool_if:NTF \l_@@_number_in_complex_root_bool
+ {
+ \@@_number_in_parse_error:nn
+ { duplicate-complex-root-token } { \token_to_str:N #1 }
+ }
+ {
+ \cs_set_eq:NN \@@_number_in_check:n
+ \@@_number_in_check_full:n
+ \bool_set_true:N \l_@@_number_in_complex_root_bool
+ \prop_put:Nnn \l_@@_number_in_prop { complex-root } {#1}
+ \tl_if_empty:NF \l_@@_number_parsed_tl
+ {
+ \cs_set_eq:NN \@@_number_in_parse_loop:N
+ \@@_number_in_parse_complex:N
+ }
+ \bool_if:NT \l_@@_number_in_decimal_bool
+ {
+ \bool_if:NF \l_@@_number_in_complex_bool
+ {
+ \prop_if_in:NnT \l_@@_number_in_prop
+ { mantissa-uncertainty }
+ {
+ \@@_number_in_complex_aux:nn
+ { mantissa-decimal } { complex-decimal }
+ \@@_number_in_complex_aux:nn
+ { mantissa-uncertainty } { complex-uncertainty }
+ }
+ \@@_number_in_complex_aux:nn { mantissa-integer }
+ { complex-integer }
+ \@@_number_in_complex_aux:nn
+ { mantissa-decimal-marker } { complex-decimal-marker }
+ \prop_remove:Nn \l_@@_number_in_prop { mantissa }
+ \prop_put:Nnn \l_@@_number_in_prop { complex }
+ { true }
+ }
+ }
+ \prop_if_in:NnF \l_@@_number_in_prop { mantissa }
+ {
+ \prop_if_in:NnT \l_@@_number_in_prop { mantissa-sign }
+ {
+ \@@_number_in_complex_aux:nn { mantissa-sign }
+ { complex-sign }
+ }
+ }
+ \bool_set_true:N \l_@@_number_in_complex_bool
+ \bool_set_false:N \l_@@_number_in_first_bool
+ \@@_number_in_init_part:n { complex }
+ \prop_if_in:NnT \l_@@_number_in_prop
+ { complex-decimal-marker }
+ { \bool_set_true:N \l_@@_number_in_decimal_bool }
+ \prop_if_in:NnTF \l_@@_number_in_prop
+ { complex-sign }
+ { \bool_set_true:N \l_@@_number_in_sign_bool }
+ { \prop_remove:Nn \l_@@_number_in_prop { mantissa } }
+ }
+}
+\cs_new_protected:Npn \@@_number_in_complex_aux:nn #1#2 {
+ \prop_get:NnNT \l_@@_number_in_prop {#1} \l_@@_tmpa_tl
+ {
+ \prop_remove:Nn \l_@@_number_in_prop {#1}
+ \prop_put:NnV \l_@@_number_in_prop {#2} \l_@@_tmpa_tl
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_decimal:N}
+% Only one decimal marker allowed, so a test for this. If an integer
+% part has been found, it is saved. The flag for the number being
+% found is not set unless there is an integer, to watch for the case
+% of invalid numbers.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_decimal:N #1 {
+ \bool_set_false:N \l_@@_number_in_first_bool
+ \bool_if:NTF \l_@@_number_in_decimal_bool
+ {
+ \@@_number_in_parse_error:nn { duplicate-decimal-token }
+ {#1}
+ }
+ {
+ \bool_set_true:N \l_@@_number_in_decimal_bool
+ \tl_if_empty:NF \l_@@_number_parsed_tl
+ {
+ \prop_put:NVn \l_@@_number_in_prop
+ \l_@@_number_part_tl { true }
+ \prop_put:NVV \l_@@_number_in_prop
+ \l_@@_number_part_integer_tl
+ \l_@@_number_parsed_tl
+ \tl_clear:N \l_@@_number_parsed_tl
+ }
+ \prop_put:NVn \l_@@_number_in_prop
+ \l_@@_number_part_decimal_marker_tl {#1}
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_digit:n}
+% For digits, only in an uncertainty can the value be stored
+% directly. Otherwise, there is a need to see if the value is non-zero.
+% This is used to drop leading zeros and to validate any sign (as zero
+% is unsigned).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_digit:n #1 {
+ \bool_set_false:N \l_@@_number_in_first_bool
+ \bool_if:NTF \l_@@_number_in_uncert_bool
+ { \tl_put_right:Nn \l_@@_number_parsed_tl {#1} }
+ {
+ \bool_if:NTF \l_@@_number_in_decimal_bool
+ {
+ \tl_put_right:Nn \l_@@_number_parsed_tl {#1}
+ \str_if_eq:nnF {#1} { 0 }
+ { \bool_set_true:N \l_@@_number_in_value_bool }
+ }
+ {
+ \str_if_eq:nnTF {#1} { 0 }
+ {
+ \prop_put:NVn \l_@@_number_in_prop
+ \l_@@_number_part_tl { true }
+ \prop_put:NVn \l_@@_number_in_prop
+ \l_@@_number_part_integer_tl { 0 }
+ }
+ { \bool_set_true:N \l_@@_number_in_value_bool }
+ \bool_if:NT \l_@@_number_in_value_bool
+ { \tl_put_right:Nn \l_@@_number_parsed_tl {#1} }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_exponent:N}
+% A duplicate token test starts off the code, which if passed
+% leads to some simple storage manipulation. As exponents are
+% more simple than the mantissa, the extra processing is swapped for
+% some that only raises errors.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_exponent:N #1 {
+ \bool_if:NTF \l_@@_number_in_exponent_bool
+ {
+ \@@_number_in_parse_error:nn { duplicate-exponent-token }
+ { \token_to_str:N #1 }
+ }
+ {
+ \cs_set_eq:NN \@@_number_in_parse_more:N
+ \@@_number_in_parse_exponent:N
+ \tl_if_empty:NF \l_@@_number_parsed_tl
+ { \@@_number_in_store: }
+ \bool_set_true:N \l_@@_number_in_exponent_bool
+ \@@_number_in_init_part:n { exponent }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_sign:N}
+% The code for signs is complicated by complex numbers. A sign token
+% must be the fist thing in a number, but after the real part of the
+% mantissa a second sign token can appear to start a complex number.
+% So most of the code here is to detect that case.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_sign:N #1 {
+ \bool_if:NTF \l_@@_number_in_first_bool
+ {
+ \bool_set_false:N \l_@@_number_in_first_bool
+ \bool_set_true:N \l_@@_number_in_sign_bool
+ \prop_put:NVn \l_@@_number_in_prop
+ \l_@@_number_part_sign_tl {#1}
+ }
+ {
+ \bool_if:NTF \l_@@_number_in_exponent_bool
+ {
+ \@@_number_in_parse_error:nn { misplaced-sign-token }
+ {#1}
+ }
+ {
+ \bool_if:NTF \l_@@_number_in_complex_bool
+ {
+ \@@_number_in_parse_error:nn
+ { misplaced-sign-token } {#1}
+ }
+ {
+ \tl_if_empty:NF \l_@@_number_parsed_tl
+ { \@@_number_in_store: }
+ \cs_set_eq:NN \@@_number_in_check:n
+ \@@_number_in_check_full:n
+ \@@_number_in_init_part:n { complex }
+ \prop_put:Nnn \l_@@_number_in_prop
+ { complex-sign } {#1}
+ \bool_set_true:N \l_@@_number_in_complex_bool
+ }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_number_in_uncert_open:N ,
+% \@@_number_in_uncert_close:N
+%}
+% Opening and closing uncertainty tokens are handled separately. For
+% opening tokens, a check is made that there is something else to the
+% number before collecting material up. For the closing token, the
+% uncertainty must contain some numbers. A special loop function is then
+% set up to prevent any additional digits after the closing token.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_uncert_open:N #1 {
+ \bool_set_false:N \l_@@_number_in_first_bool
+ \cs_set_eq:NN \@@_number_in_parse_loop:N
+ \@@_number_in_parse_uncert:N
+ \bool_set_true:N \l_@@_number_in_uncert_bool
+ \tl_if_empty:NTF \l_@@_number_parsed_tl
+ {
+ \prop_if_in:NVF \l_@@_number_in_prop
+ \l_@@_number_part_integer_tl
+ {
+ \@@_number_in_parse_error:nV { invalid-number }
+ \l_@@_number_arg_tl
+ }
+ }
+ { \@@_number_in_store: }
+}
+\cs_new_protected:Npn \@@_number_in_uncert_close:N #1 {
+ \bool_set_false:N \l_@@_number_in_uncert_bool
+ \tl_if_empty:NTF \l_@@_number_parsed_tl
+ {
+ \@@_number_in_parse_error:nV { empty-uncertainty }
+ \l_@@_number_arg_tl
+ }
+ {
+ \prop_put:NVV \l_@@_number_in_prop
+ \l_@@_number_part_uncert_tl \l_@@_number_parsed_tl
+ \prop_put:Nnn \l_@@_number_in_prop
+ { uncertainty } { true }
+ \tl_clear:N \l_@@_number_parsed_tl
+ \cs_set_eq:NN \@@_number_in_parse_loop:N
+ \@@_number_in_parse_uncert_after:N
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_in_store:}
+% A short auxiliary function needed in various places for storing
+% either the integer or decimal part of a number, as appropriate.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_store: {
+ \prop_put:NVn \l_@@_number_in_prop \l_@@_number_part_tl
+ { true }
+ \bool_if:NTF \l_@@_number_in_decimal_bool
+ {
+ \prop_put:NVV \l_@@_number_in_prop
+ \l_@@_number_part_decimal_tl \l_@@_number_parsed_tl
+ }
+ {
+ \prop_put:NVV \l_@@_number_in_prop
+ \l_@@_number_part_integer_tl \l_@@_number_parsed_tl
+ }
+ \tl_clear:N \l_@@_number_parsed_tl
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_number_in_check:n ,
+% \@@_number_in_check_short:n ,
+% \@@_number_in_check_full:n
+%}
+% The checks needed for a number depend on whether there is a complex
+% part. In all cases, there must be some digits, as well as a sign or
+% decimal marker. There is also a check for a zero-valued input, which
+% has any sign deleted. For complex numbers, the check is needed in
+% case there was no real part.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_check:n #1 { }
+\cs_new_protected:Npn \@@_number_in_check_short:n #1 {
+ \prop_if_in:NVF \l_@@_number_in_prop
+ \l_@@_number_part_integer_tl
+ {
+ \prop_if_in:NVF \l_@@_number_in_prop
+ \l_@@_number_part_decimal_tl
+ { \@@_error:nx { invalid-number } {#1} }
+ }
+ \bool_if:NF \l_@@_number_in_value_bool
+ {
+ \tl_if_eq:NNF \l_@@_number_part_tl
+ \c_@@_number_part_complex_tl
+ {
+ \prop_get:NVNT \l_@@_number_in_prop
+ \l_@@_number_part_sign_tl \l_@@_tmpa_tl
+ {
+ \tl_set:Nx \l_@@_tmpb_tl
+ { \l_@@_number_part_sign_tl -deleted }
+ \prop_put:NVV \l_@@_number_in_prop
+ \l_@@_tmpb_tl \l_@@_tmpa_tl
+ }
+ \prop_remove:NV \l_@@_number_in_prop
+ \l_@@_number_part_sign_tl
+ }
+ }
+}
+\cs_new_protected:Npn \@@_number_in_check_full:n #1 {
+ \tl_if_eq:NNF \l_@@_number_part_tl
+ \c_@@_number_part_complex_tl
+ { \@@_number_in_check_short:n {#1} }
+ \bool_if:NF \l_@@_number_in_complex_root_bool
+ {
+ \prop_get:NnN \l_@@_number_in_prop { complex-sign }
+ \l_@@_tmpa_tl
+ \tl_if_in:NVTF \l_@@_input_uncert_sign_tl \l_@@_tmpa_tl
+ {
+ \prop_if_in:NnTF \l_@@_number_in_prop { uncertainty }
+ {
+ \@@_error:nx { misplaced-sign-token }
+ { \exp_not:n {#1} }
+ }
+ { \@@_number_in_complex_to_uncert:n {#1} }
+ }
+ {
+ \@@_error:nx { misplaced-sign-token }
+ { \exp_not:n {#1} }
+ }
+ }
+ \prop_get:NnNT \l_@@_number_in_prop { mantissa-sign }
+ \l_@@_tmpa_tl
+ {
+ \prop_if_in:NnF \l_@@_number_in_prop { mantissa }
+ {
+ \prop_remove:Nn \l_@@_number_in_prop { mantissa-sign }
+ \prop_put:NnV \l_@@_number_in_prop { complex-sign }
+ \l_@@_tmpa_tl
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\@@_number_in_complex_to_uncert:n}
+%\begin{macro}{
+% \@@_number_in_complex_to_uncert_int: ,
+% \@@_number_in_complex_to_uncert_dec:
+%}
+% Internally, uncertainties are stored in \enquote{compact} form.
+% The code here takes a putative complex part and converts it to
+% a compact uncertainty, with checks for the cases where things look
+% wrong. The method needed depends on whether there is an integer
+% part.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_complex_to_uncert:n #1 {
+ \prop_remove:Nn \l_@@_number_in_prop { complex }
+ \prop_remove:Nn \l_@@_number_in_prop { complex-decimal-marker }
+ \prop_remove:Nn \l_@@_number_in_prop { complex-sign }
+ \prop_put:Nnn \l_@@_number_in_prop { uncertainty } { true }
+ \prop_get:NnNTF \l_@@_number_in_prop { complex-integer }
+ \l_@@_number_uncert_tl
+ {
+ \tl_if_single:NTF \l_@@_number_uncert_tl
+ {
+ \int_compare:nNnTF \l_@@_number_uncert_tl = 0
+ { \@@_number_in_complex_to_uncert_dec:n {#1} }
+ { \@@_number_in_complex_to_uncert_int: }
+ }
+ { \@@_number_in_complex_to_uncert_int: }
+ }
+ { \@@_number_in_complex_to_uncert_dec:n {#1} }
+ \prop_remove:Nn \l_@@_number_in_prop { complex-integer }
+ \prop_remove:Nn \l_@@_number_in_prop { complex-decimal }
+}
+% \end{macrocode}
+% When the input has an integer part to the uncertainty, the
+% conversion is easy as all of the decimal part can be copied
+% across.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_complex_to_uncert_int: {
+ \prop_get:NnNF \l_@@_number_in_prop { complex-decimal }
+ \l_@@_tmpa_tl
+ { \tl_clear:N \l_@@_tmpa_tl }
+ \prop_get:NnNF \l_@@_number_in_prop { mantissa-decimal }
+ \l_@@_tmpb_tl
+ { \tl_clear:N \l_@@_tmpb_tl }
+ \@@_number_in_complex_to_uncert_pad:
+}
+% \end{macrocode}
+% For a number in which all of the uncertainty is in the decimal part,
+% only the significant digits are needed. This means that a loop is
+% needed to drop non-significant ones.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_in_complex_to_uncert_dec:n
+ #1
+ {
+ \tl_clear:N \l_@@_number_uncert_tl
+ \prop_get:NnNTF \l_@@_number_in_prop { complex-decimal }
+ \l_@@_tmpa_tl
+ {
+ \prop_get:NnN \l_@@_number_in_prop { mantissa-decimal }
+ \l_@@_tmpb_tl
+ \quark_if_no_value:NT \l_@@_tmpb_tl
+ { \tl_clear:N \l_@@_tmpb_tl }
+ \tl_map_function:NN
+ \l_@@_tmpa_tl
+ \@@_number_in_complex_to_uncert_dec_loop:N
+ \@@_number_in_complex_to_uncert_pad:
+ }
+ { \@@_error:nx { misplaced-sign-token } { \exp_not:n {#1} } }
+ }
+\cs_new_protected:Npn
+ \@@_number_in_complex_to_uncert_dec_loop:N #1
+ {
+ \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: }
+ }
+% \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}
+%
+%\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
+% \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
+% \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
+ }
+% \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}
+%
+%\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 }
+ }
+}
+% \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}
+%
+%\begin{macro}{\@@_number_process_fixed:}
+%\begin{macro}{
+% \@@_number_process_fixed_aux_i:nnn ,
+% \@@_number_process_fixed_aux_ii:nnn ,
+% \@@_number_process_fixed_aux_iii:nnn ,
+% \@@_number_process_fixed_large:nnn ,
+% \@@_number_process_fixed_large_aux:w ,
+% \@@_number_process_fixed_small:nnn ,
+% \@@_number_process_fixed_small_aux:w
+%}
+% When working to a fixed exponent value, the idea is to use the stack
+% to do the work. First, there is some set up to do.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_fixed: {
+ \prop_if_in:NnF \l_@@_number_in_prop { complex }
+ {
+ \prop_get:NnNF \l_@@_number_in_prop { mantissa-integer }
+ \l_@@_tmpa_tl
+ { \tl_set:Nn \l_@@_tmpa_tl { 0 } }
+ \prop_get:NnNF \l_@@_number_in_prop { mantissa-decimal }
+ \l_@@_tmpb_tl
+ { \tl_clear:N \l_@@_tmpb_tl }
+ \tl_set:Nx \l_@@_tmpa_tl
+ { { \l_@@_tmpa_tl } { \l_@@_tmpb_tl } }
+ \prop_get:NnNF \l_@@_number_in_prop { exponent-integer }
+ \l_@@_tmpb_tl
+ { \tl_set:Nn \l_@@_tmpb_tl { 0 } }
+ \group_begin:
+ \prop_get:NnNT \l_@@_number_in_prop { exponent-sign }
+ \l_@@_tmpa_tl
+ {
+ \tl_put_left:NV \l_@@_tmpb_tl \l_@@_tmpa_tl
+ }
+ \exp_args:NNNV \group_end:
+ \tl_set:Nn \l_@@_tmpb_tl \l_@@_tmpb_tl
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \l_@@_tmpa_tl { \l_@@_tmpb_tl } }
+ \exp_after:wN \@@_number_process_fixed_aux_i:nnn
+ \l_@@_tmpa_tl
+ }
+}
+% \end{macrocode}
+% The main loop checks to see which way to adjust the exponent then
+% does the work.
+% \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
+ { }
+\cs_new_protected:Npn
+ \@@_number_process_fixed_small:nnn #1#2#3 {
+ \cs_set_protected:Npn
+ \@@_number_process_fixed_small_aux:w ##1##2 \q_stop ##3
+ {
+ \tl_if_empty:nTF {##2}
+ {
+ \tl_if_empty:nTF {##3}
+ {
+ \@@_number_process_fixed_aux_ii:nnn { 0 }
+ { ##1 #2 } { #3 + 1 }
+ }
+ {
+ \@@_number_process_fixed_aux_ii:nnn {##3}
+ { ##1 #2 } { #3 + 1 }
+ }
+ }
+ {
+ \@@_number_process_fixed_small_aux:w ##2 \q_stop
+ { ##3 ##1 }
+ }
+ }
+ \@@_number_process_fixed_small_aux:w #1 \q_stop { }
+}
+\cs_new_protected:Npn \@@_number_process_fixed_small_aux:w
+ { }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_process_integer_digits:}
+% Producing extra digits for the integer part is a simple process
+% once the target is known.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_integer_digits: {
+ \int_compare:nNnT \l_@@_process_integer_min_int > 0
+ {
+ \prop_get:NnNT \l_@@_number_in_prop { mantissa-integer }
+ \l_@@_tmpa_tl
+ {
+ \int_set:Nn \l_@@_tmp_int
+ {
+ \l_@@_process_integer_min_int
+ - \tl_count:N \l_@@_tmpa_tl
+ }
+ \int_compare:nNnT \l_@@_tmp_int > 0
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \prg_replicate:nn { \l_@@_tmp_int } { 0 }
+ \exp_not:V \l_@@_tmpa_tl
+ }
+ \prop_put:NnV \l_@@_number_in_prop
+ { mantissa-integer } \l_@@_tmpa_tl
+ }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_process_mantissa:}
+%\begin{macro}{\c_@@_unity_tl}
+% A check for the mantissa consisting only of the token \texttt{1}, when
+% an exponent is also available.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_mantissa: {
+ \bool_if:NF \l_@@_process_unity_mantissa_bool
+ {
+ \prop_if_in:NnT \l_@@_number_in_prop { exponent }
+ {
+ \prop_get:NnNT \l_@@_number_in_prop { mantissa-integer }
+ \l_@@_tmpa_tl
+ {
+ \tl_if_eq:NNT \c_@@_unity_tl \l_@@_tmpa_tl
+ {
+ \prop_if_in:NnF \l_@@_number_in_prop
+ { mantissa-decimal-marker }
+ {
+ \prop_remove:Nn \l_@@_number_in_prop
+ { mantissa }
+ \prop_remove:Nn \l_@@_number_in_prop
+ { mantissa-integer }
+ }
+ }
+ }
+ }
+ }
+}
+\tl_const:Nn \c_@@_unity_tl { 1 }
+% \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.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_places:n #1
+ {
+ \prop_if_in:NnT \l_@@_number_in_prop {#1}
+ {
+ \prop_if_in:NnF \l_@@_number_in_prop { #1 -uncertainty }
+ { \@@_number_process_places_aux_i:n {#1} }
+ }
+ }
+\cs_new_protected:Npn \@@_number_process_places_aux_i:n #1
+ {
+ \int_compare:nNnTF \l_@@_process_precision_int = 0
+ { \@@_number_process_places_none:n {#1} }
+ {
+ \prop_get:NnNT \l_@@_number_in_prop { #1 -decimal }
+ \l_@@_tmpa_tl
+ {
+ \tl_if_empty:NT \l_@@_tmpa_tl
+ { \tl_set:Nn \l_@@_tmpa_tl { 0 } }
+ \@@_number_process_places_aux_i:TF
+ {
+ \prop_put:Nnn \l_@@_number_in_prop { #1 -decimal } { }
+ \int_set:Nn \l_@@_round_int
+ { \l_@@_process_precision_int }
+ \@@_number_process_pad:n {#1}
+ }
+ {
+ \int_set:Nn \l_@@_round_int
+ { \tl_count:N \l_@@_tmpa_tl }
+ \@@_number_process_places_aux_ii:n {#1}
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% The number of digits in the decimal part could be more that \TeX{} can
+% handle, so a slow loop is used to see if we need to round.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_places_aux_i:TF
+ {
+ \bool_set_true:N \l_@@_tmp_bool
+ \tl_map_inline:Nn \l_@@_tmpa_tl
+ {
+ \int_compare:nNnF {##1} = 0
+ {
+ \bool_set_false:N \l_@@_tmp_bool
+ \tl_map_break:
+ }
+ }
+ \bool_if:NTF \l_@@_tmp_bool
+ }
+% \end{macrocode}
+% Rounding to no places at all requires a few checks to see if there is any
+% work to do. That includes a check for rounding half to even, where if
+% the decimal part is exactly half then special action is required.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_places_none:n #1
+ {
+ \prop_get:NnNT \l_@@_number_in_prop { #1 -decimal } \l_@@_tmpa_tl
+ {
+ \int_compare:nNnTF { \tl_head:N \l_@@_tmpa_tl } > 4
+ {
+ \prop_get:NnNTF \l_@@_number_in_prop { #1 -integer }
+ \l_@@_tmpb_tl
+ {
+ \tl_set:Nx \l_@@_tmpb_tl
+ { \int_eval:n { \l_@@_tmpb_tl + 1 } }
+ \bool_if:NF \l_@@_round_half_up_bool
+ {
+ \int_compare:nNnT
+ { 0 \tl_tail:N \l_@@_tmpa_tl } = 0
+ {
+ \int_if_odd:nT \l_@@_tmpb_tl
+ {
+ \tl_set:Nx \l_@@_tmpb_tl
+ { \int_eval:n { \l_@@_tmpb_tl - 1 } }
+ }
+ }
+ }
+ }
+ { \tl_set:Nn \l_@@_tmpb_tl { 1 } }
+ \prop_put:NnV \l_@@_number_in_prop
+ { #1 -integer } \l_@@_tmpb_tl
+ }
+ {
+ \prop_if_in:NnF \l_@@_number_in_prop { #1 -integer }
+ {
+ \prop_put:Nnn \l_@@_number_in_prop
+ { #1 -integer } { 0 }
+ }
+ }
+ }
+ \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal }
+ \bool_if:NF \l_@@_process_int_to_dec_bool
+ { \prop_remove:Nn \l_@@_number_in_prop { #1 -decimal-marker } }
+ }
+% \end{macrocode}
+% For rounding to a fixed number of places, the package finds the
+% difference in length between what is present and what is required.
+% If the number is too short, there is some simple padding to do.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_places_aux_ii:n #1
+ {
+ \int_sub:Nn \l_@@_round_int
+ { \l_@@_process_precision_int }
+ \int_compare:nNnTF \l_@@_round_int < 0
+ {
+ \int_set:Nn \l_@@_round_int { - \l_@@_round_int }
+ \@@_number_process_pad:n {#1}
+ }
+ {
+ \@@_number_process_places_init:n {#1}
+ \@@_number_process_places_loop:n {#1}
+ \@@_number_process_round_tidy:n {#1}
+ }
+ }
+% \end{macrocode}
+% To keep the code a little clearer.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_places_init:n #1
+ {
+ \prop_get:NnNF \l_@@_number_in_prop { #1 -integer }
+ \l_@@_round_integer_in_tl
+ { \tl_clear:N \l_@@_round_integer_in_tl }
+ \prop_get:NnN \l_@@_number_in_prop { #1 -decimal }
+ \l_@@_round_decimal_in_tl
+ \tl_reverse:N \l_@@_round_integer_in_tl
+ \tl_reverse:N \l_@@_round_decimal_in_tl
+ \tl_clear:N \l_@@_round_integer_out_tl
+ \tl_clear:N \l_@@_round_decimal_out_tl
+ \tl_clear:N \l_@@_round_discard_tl
+ \bool_set_false:N \l_@@_round_bool
+ \bool_set_false:N \l_@@_round_even_bool
+ }
+% \end{macrocode}
+% If there is a decimal, do the decimal processing then come back here.
+% If there is an integer, do the same. Only if both are empty does the
+% loop stop.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_places_loop:n #1
+ {
+ \tl_if_empty:NTF \l_@@_round_decimal_in_tl
+ {
+ \tl_if_empty:NF \l_@@_round_integer_in_tl
+ {
+ \@@_number_process_places_integer:n {#1}
+ \@@_number_process_places_loop:n {#1}
+ }
+ \bool_if:NT \l_@@_round_bool
+ {
+ \tl_put_left:Nn \l_@@_round_integer_out_tl { 1 }
+ \bool_set_false:N \l_@@_round_bool
+ }
+ }
+ {
+ \@@_number_process_round_decimal:
+ \@@_number_process_places_loop:n {#1}
+ }
+ }
+% \end{macrocode}
+% Rounding for integers is just a case of carrying digits.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_places_integer:n #1
+ {
+ \int_set:Nn \l_@@_tmp_int
+ { \tl_head:N \l_@@_round_integer_in_tl }
+ \tl_set:Nx \l_@@_round_integer_in_tl
+ { \tl_tail:N \l_@@_round_integer_in_tl }
+ \@@_number_process_round_up:
+ \bool_set_false:N \l_@@_round_bool
+ \int_compare:nNnT \l_@@_tmp_int = { 10 }
+ {
+ \int_zero:N \l_@@_tmp_int
+ \bool_set_true:N \l_@@_round_bool
+ }
+ \tl_put_left:NV \l_@@_round_integer_out_tl \l_@@_tmp_int
+ }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+% \begin{macro}{\@@_number_process_round:}
+% The lead-off for rounding is the same for decimal places and
+% significant figures.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_round:
+ {
+ \tl_if_empty:NF \l_@@_round_tl
+ {
+ \bool_if:NT \l_@@_process_int_to_dec_bool
+ {
+ \prop_if_in:NnF \l_@@_number_in_prop { mantissa-decimal }
+ {
+ \prop_put:Nnn \l_@@_number_in_prop { mantissa-decimal }
+ { 0 }
+ }
+ \prop_if_in:NnF \l_@@_number_in_prop
+ { mantissa-decimal-marker }
+ {
+ \prop_put:Nnn \l_@@_number_in_prop
+ { mantissa-decimal-marker } { . }
+ }
+ }
+ \clist_map_function:nc { mantissa , complex }
+ { @@_number_process_ \l_@@_round_tl :n }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_number_process_round_decimal:}
+% \begin{macro}{\@@_number_process_round_decimal_aux:}
+% The rounding routine for decimals is the same for figures and places,
+% so there is a generalised function here. Unfortunately, it is also
+% complicated!
+% \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}
+%
+%\begin{macro}{\@@_number_process_sign:}
+%\begin{macro}{
+% \@@_number_process_sign_add:n ,
+% \@@_number_process_sign_plus:n
+%}
+%\begin{macro}{\c_@@_plus_tl}
+% Sorting out signs consists of two parts: retaining a plus if necessary
+% and adding an explicit sign.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_sign: {
+ \bool_if:NF \l_@@_process_plus_bool
+ {
+ \prop_if_in:NnTF \l_@@_number_in_prop { mantissa-sign }
+ { \@@_number_process_sign_plus:n { mantissa } }
+ {
+ \prop_if_in:NnT \l_@@_number_in_prop { complex-sign }
+ {
+ \prop_if_in:NnF \l_@@_number_in_prop { mantissa }
+ { \@@_number_process_sign_plus:n { complex } }
+ }
+ }
+ \prop_if_in:NnT \l_@@_number_in_prop { exponent-sign }
+ { \@@_number_process_sign_plus:n { exponent } }
+ }
+ \tl_if_empty:NF \l_@@_process_sign_tl
+ {
+ \@@_number_process_sign_add:n { mantissa }
+ \prop_if_in:NnTF \l_@@_number_in_prop { complex }
+ { \@@_number_process_sign_add:n { complex } }
+ }
+}
+% \end{macrocode}
+% Adding a sign to an existing number needs a couple of to make sure
+% there is a number to add to, and to see if there is a sign already.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_sign_add:n #1 {
+ \prop_if_in:NnF \l_@@_number_in_prop { #1 -sign }
+ {
+ \prop_if_in:NnF \l_@@_number_in_prop { #1 -had-sign }
+ {
+ \prop_get:NnN \l_@@_number_in_prop {#1}
+ \l_@@_tmpa_tl
+ \tl_if_empty:NTF \l_@@_tmpa_tl
+ {
+ \prop_put:NnV \l_@@_number_in_prop { sign }
+ \l_@@_process_sign_tl
+ }
+ {
+ \prop_put:NnV \l_@@_number_in_prop { #1 -sign }
+ \l_@@_process_sign_tl
+ }
+ }
+ }
+}
+% \end{macrocode}
+% Holding onto a plus works very much in the same way as adding a sign:
+% some quick tests and an assignment. Using a pre-defined token list is
+% a speed-related choice: very slightly faster comparison.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_process_sign_plus:n #1 {
+ \prop_get:NnN \l_@@_number_in_prop { #1 -sign }
+ \l_@@_tmpa_tl
+ \tl_if_eq:NNT \c_@@_plus_tl \l_@@_tmpa_tl
+ {
+ \prop_remove:Nn \l_@@_number_in_prop { #1 -sign }
+ \prop_put:Nnn \l_@@_number_in_prop { #1 -had-sign } { true }
+ }
+}
+\tl_const:Nn \c_@@_plus_tl { + }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\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:
+ {
+ \bool_if:NT \l_@@_zero_decimal_to_integer_bool
+ {
+ \@@_number_process_zero_to_integer_aux:n { mantissa }
+ \@@_number_process_zero_to_integer_aux:n { complex }
+ }
+ }
+\cs_new_protected:Npn \@@_number_process_zero_to_integer_aux:n #1
+ {
+ \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 }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_number_exp_to_prefix:}
+% This function is a bit awkward, as it essentially cuts across the
+% unit processor. The idea here is first to recover the numerical exponent,
+% and sign if there is one. The earlier formatting run will have reset the
+% total number of units to zero, so that has to be recovered before
+% doing the format a second time.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_exp_to_prefix:
+ {
+ \prop_set_eq:NN \l_@@_unit_prop \l_@@_unit_saved_prop
+ \prop_get:NnNT \l_@@_number_in_prop { exponent-integer }
+ \l_@@_tmpa_tl
+ {
+ \prop_get:NnNT \l_@@_number_in_prop { exponent-sign }
+ \l_@@_tmpb_tl
+ { \tl_put_left:NV \l_@@_tmpa_tl \l_@@_tmpb_tl }
+ \prop_if_in:NnT \l_@@_unit_prop { per-1 }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \int_eval:n { - \l_@@_tmpa_tl } }
+ }
+ \prop_get:NnNT \l_@@_unit_prop { prefix-1 } \l_@@_tmpb_tl
+ {
+ \prop_remove:Nn \l_@@_unit_prop { prefix-1 }
+ \prop_remove:Nn \l_@@_unit_prop { prefix-symbol-1 }
+ \prop_get:NVN \l_@@_prefix_forward_prop \l_@@_tmpb_tl
+ \l_@@_tmpb_tl
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \int_eval:n { \l_@@_tmpa_tl + \l_@@_tmpb_tl } }
+ }
+ \prop_get:NnNT \l_@@_unit_prop { power-1 } \l_@@_tmpb_tl
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \int_eval:n { \l_@@_tmpa_tl / \l_@@_tmpb_tl } }
+ }
+ \prop_get:NVNTF \l_@@_prefix_reverse_prop \l_@@_tmpa_tl
+ \l_@@_tmpb_tl
+ {
+ \prop_remove:Nn \l_@@_number_in_prop { exponent }
+ \use:c
+ {
+ @@_ \exp_after:wN \token_to_str:N \l_@@_tmpb_tl
+ _function:w
+ }
+ \prop_get:NnN \l_@@_unit_prop { total-units } \l_@@_tmpa_tl
+ \int_set:Nn \l_@@_unit_int \l_@@_tmpa_tl
+ \cs_set_eq:NN \@@_pm: \pm
+ \@@_unit_format:
+ \cs_set_eq:NN \pm \@@_pm:
+ }
+ {
+ \msg_error:nnx { siunitx } { non-convertible-exponent }
+ { \l_@@_tmpa_tl }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%\subsection{Formatting numbers for output}
+%
+% Getting numbers ready for printing requires the reconstruction of the
+% number from the various parts processed earlier. Spaces and brackets
+% are added back into the main numbers, as the various parts are also
+% correctly formatted. The difference between the \texttt{in} and
+% \texttt{out} store is that the later can include formatting such as
+% hard spaces.
+%
+%\begin{macro}{\l_@@_number_out_prop}
+% Like the \texttt{in} version!
+% \begin{macrocode}
+\prop_new:N \l_@@_number_out_prop
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \l_@@_group_sep_tl ,
+% \l_@@_output_decimal_tl
+%}
+% A couple of variables are declared here, as they need a little more
+% work than just storage.
+% \begin{macrocode}
+\tl_new:N \l_@@_group_sep_tl
+\tl_new:N \l_@@_output_decimal_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_complex_after_bool}
+% A setting for where complex numbers go.
+% \begin{macrocode}
+\bool_new:N \l_@@_complex_after_bool
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{variable}
+% {\l_@@_group_decimal_bool, \l_@@_group_integer_bool}
+% Used for grouping digits.
+% \begin{macrocode}
+\bool_new:N \l_@@_group_decimal_bool
+\bool_new:N \l_@@_group_integer_bool
+% \end{macrocode}
+% \end{variable}
+%
+%\begin{macro}{
+% \l_@@_negative_bracket_bool ,
+% \l_@@_brackets_bool ,
+% \l_@@_bracket_close_tl ,
+% \l_@@_output_complex_copy_bool ,
+% \l_@@_output_decimal_copy_bool ,
+% \l_@@_exponent_base_tl ,
+% \l_@@_exponent_product_tl ,
+% \l_@@_group_min_int ,
+% \l_@@_negative_color_tl ,
+% \l_@@_bracket_open_tl ,
+% \l_@@_output_uncert_close_tl ,
+% \l_@@_output_complex_tl ,
+% \l_@@_output_exponent_tl ,
+% \l_@@_output_uncert_open_tl ,
+% \l_@@_uncert_sep_bool ,
+% \l_@@_tight_bool ,
+% \l_@@_uncert_sep_tl
+%}
+% Lots of settings, some used only for numbers, some more widely.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ bracket-negative-numbers .bool_set:N =
+ \l_@@_negative_bracket_bool ,
+ bracket-numbers .bool_set:N = \l_@@_brackets_bool,
+ close-bracket .tl_set:N = \l_@@_bracket_close_tl,
+ complex-root-position .choice:,
+ complex-root-position
+ / after-number .code:n =
+ { \bool_set_true:N \l_@@_complex_after_bool } ,
+ complex-root-position
+ / before-number .code:n =
+ { \bool_set_false:N \l_@@_complex_after_bool } ,
+ copy-complex-root .bool_set:N =
+ \l_@@_output_complex_copy_bool,
+ copy-decimal-marker .bool_set:N =
+ \l_@@_output_decimal_copy_bool,
+ exponent-base .tl_set:N = \l_@@_exponent_base_tl,
+ exponent-product .tl_set:N =
+ \l_@@_exponent_product_tl,
+ group-decimal-digits .meta:n = { group-digits = decimal },
+ group-digits .choice: ,
+ group-digits /
+ decimal .code:n =
+ {
+ \bool_set_true:N \l_@@_group_decimal_bool
+ \bool_set_false:N \l_@@_group_integer_bool
+ },
+ group-digits /
+ false .code:n =
+ {
+ \bool_set_false:N \l_@@_group_decimal_bool
+ \bool_set_false:N \l_@@_group_integer_bool
+ },
+ group-digits /
+ integer .code:n =
+ {
+ \bool_set_false:N \l_@@_group_decimal_bool
+ \bool_set_true:N \l_@@_group_integer_bool
+ },
+ group-digits /
+ true .code:n =
+ {
+ \bool_set_true:N \l_@@_group_decimal_bool
+ \bool_set_true:N \l_@@_group_integer_bool
+ },
+ group-digits .default:n = true ,
+ group-four-digits .choice:,
+ group-four-digits /
+ false .meta:n = { group-minimum-digits = 5 },
+ group-four-digits /
+ true .meta:n = { group-minimum-digits = 4 },
+ group-four-digits .default:n = true,
+ group-integer-digits .meta:n = { group-digits = integer },
+ group-minimum-digits .int_set:N = \l_@@_group_min_int,
+ group-separator .code:n =
+ { \tl_set:Nn \l_@@_group_sep_tl { {#1} } },
+ negative-color .tl_set:N = \l_@@_negative_color_tl,
+ open-bracket .tl_set:N = \l_@@_bracket_open_tl,
+ output-close-uncertainty .tl_set:N =
+ \l_@@_output_uncert_close_tl,
+ output-complex-root .tl_set:N = \l_@@_output_complex_tl ,
+ output-decimal-marker .code:n =
+ { \tl_set:Nn \l_@@_output_decimal_tl { {#1} } },
+ output-exponent-marker .tl_set:N = \l_@@_output_exponent_tl,
+ output-open-uncertainty .tl_set:N =
+ \l_@@_output_uncert_open_tl,
+ separate-uncertainty .bool_set:N = \l_@@_uncert_sep_bool,
+ tight-spacing .bool_set:N = \l_@@_tight_bool,
+ uncertainty-separator .tl_set:N = \l_@@_uncert_sep_tl,
+}
+\keys_set:nn { siunitx }
+ {
+ bracket-numbers = true , % (
+ close-bracket = ) ,
+ complex-root-position = after-number ,
+ copy-decimal-marker = false ,
+ exponent-base = 10 ,
+ exponent-product = \times ,
+ group-digits = true ,
+ group-minimum-digits = 5 ,
+ group-separator = \, ,
+ open-bracket = ( , % ) (
+ output-close-uncertainty = ) ,
+ output-complex-root = \ensuremath { \mathrm { i } } ,
+ output-decimal-marker = . ,
+ output-open-uncertainty = ( % )
+ }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_format:}
+% The master control function for formatting output: the usual set up.
+% The number is put back together in stages.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format: {
+ \prop_if_empty:NF \l_@@_number_in_prop
+ {
+ \prop_clear:N \l_@@_number_out_prop
+ \@@_number_format_reassemble:
+ \@@_number_format_complex:
+ \@@_number_format_sign:n { mantissa }
+ \@@_number_format_sign:n { exponent }
+ \@@_number_format_relation:
+ \@@_number_format_color:
+ \@@_number_format_final:
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_format_brackets:n}
+%\begin{macro}{\@@_number_format_brackets_aux:n}
+% There are various points at which brackets might be added to
+% avoid ambiguity. The function here adds the appropriate tokens
+% around whatever is in the supplied named store.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_brackets:n #1 {
+ \bool_if:NT \l_@@_brackets_bool
+ {
+ \prop_if_in:NnT \l_@@_number_out_prop { #1 -bracket }
+ {
+ \@@_number_format_brackets_aux:n {#1}
+ \prop_remove:Nn \l_@@_number_out_prop { #1 -bracket }
+ }
+ }
+}
+\cs_new_protected:Npn \@@_number_format_brackets_aux:n #1 {
+ \prop_get:NnNF \l_@@_number_out_prop { #1 -result }
+ \l_@@_tmpa_tl
+ {
+ \prop_get:NnN \l_@@_number_out_prop {#1} \l_@@_tmpa_tl
+ }
+ \tl_put_left:NV \l_@@_tmpa_tl \l_@@_bracket_open_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_bracket_close_tl
+ \str_if_eq:nnTF {#1} { result }
+ { \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpa_tl }
+ {
+ \prop_put:NnV \l_@@_number_out_prop { #1 -result }
+ \l_@@_tmpa_tl
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_format_color:}
+%\begin{macro}{\@@_number_format_color_aux:n}
+% If the mantissa is negative, then any colour for output might change.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_color: {
+ \tl_if_empty:NF \l_@@_negative_color_tl
+ {
+ \@@_number_format_color_aux:n { mantissa-sign }
+ \@@_number_format_color_aux:n { sign }
+ }
+}
+\cs_new_protected:Npn \@@_number_format_color_aux:n #1 {
+ \prop_get:NnNT \l_@@_number_in_prop {#1} \l_@@_tmpa_tl
+ {
+ \str_if_eq:VnT \l_@@_tmpa_tl { - }
+ {
+ \prop_put:NnV \l_@@_number_out_prop { color }
+ \l_@@_negative_color_tl
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_format_complex:}
+%\begin{macro}{
+% \@@_number_format_complex_aux:n ,
+% \@@_number_format_complex_aux:
+%}
+% The real and complex parts of each number are reassembled, with
+% brackets if needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_complex: {
+ \prop_if_in:NnT \l_@@_number_in_prop { complex-root }
+ {
+ \prop_if_in:NnTF \l_@@_number_out_prop { complex }
+ {
+ \@@_number_format_brackets:n { complex }
+ \@@_number_format_complex_aux:n { complex }
+ \@@_number_format_complex_aux:n { complex-result }
+ \prop_if_in:NnT \l_@@_number_out_prop
+ { complex-uncertainty }
+ {
+ \@@_number_format_complex_aux:n
+ { complex-uncertainty }
+ }
+ }
+ {
+ \prop_put:NnV \l_@@_number_out_prop { complex }
+ \l_@@_output_complex_tl
+ }
+ \@@_number_format_join_complex:
+ }
+}
+\cs_new_protected:Npn \@@_number_format_complex_aux:n #1 {
+ \bool_if:NTF \l_@@_output_complex_copy_bool
+ {
+ \prop_get:NnN \l_@@_number_in_prop { complex-root }
+ \l_@@_tmpa_tl
+ }
+ { \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_output_complex_tl }
+ \prop_get:NnN \l_@@_number_out_prop {#1} \l_@@_tmpb_tl
+ \bool_if:NTF \l_@@_complex_after_bool
+ { \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpa_tl }
+ { \tl_put_left:NV \l_@@_tmpb_tl \l_@@_tmpa_tl }
+ \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpb_tl
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_number_format_copy:n ,
+% \@@_number_format_copy:nn
+%}
+% Just copy across.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_copy:n #1 {
+ \prop_get:NnN \l_@@_number_in_prop {#1} \l_@@_tmpa_tl
+ \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpa_tl
+}
+\cs_new_protected:Npn \@@_number_format_copy:nn #1#2 {
+ \prop_get:NnN \l_@@_number_out_prop {#1} \l_@@_tmpa_tl
+ \prop_put:NnV \l_@@_number_out_prop {#2} \l_@@_tmpa_tl
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_format_final:}
+% For numbers which do not contain an exponent, the mantissa result is
+% simply copied to the final output position. On the other hand, for
+% exponents there are further checks, which are handed off to dedicated
+% functions. There is also a check for complex numbers with no real
+% part, which needs to be \enquote{copied} to the standard result
+% slot.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_final: {
+ \prop_if_in:NnT \l_@@_number_out_prop { complex }
+ {
+ \prop_if_in:NnF \l_@@_number_out_prop { mantissa-result }
+ {
+ \@@_number_format_copy:nn { complex }
+ { mantissa-result }
+ }
+ }
+ \prop_if_in:NnTF \l_@@_number_out_prop { exponent }
+ {
+ \@@_number_format_final_exponent:
+ \prop_if_in:NnTF \l_@@_number_out_prop { mantissa-result }
+ { \@@_number_format_final_combined: }
+ { \@@_number_format_final_exponent_only: }
+ }
+ { \@@_number_format_copy:nn { mantissa-result } { result } }
+ \prop_if_in:NnT \l_@@_number_out_prop { mantissa-bracket }
+ {
+ \prop_put:Nnn \l_@@_number_out_prop { result-bracket }
+ { true }
+ \prop_remove:Nn \l_@@_number_out_prop { mantissa-bracket }
+ }
+ \prop_if_in:NnT \l_@@_number_out_prop { comparator }
+ {
+ \@@_number_format_brackets:n { result }
+ \prop_get:NnN \l_@@_number_out_prop { comparator }
+ \l_@@_tmpa_tl
+ \prop_get:NnN \l_@@_number_out_prop { result }
+ \l_@@_tmpb_tl
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \exp_not:N \mathord
+ \exp_not:V \l_@@_tmpa_tl
+ \exp_not:V \l_@@_tmpb_tl
+ }
+ \prop_put:NnV \l_@@_number_out_prop { result }
+ \l_@@_tmpa_tl
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@@_number_format_final_combined:}
+% When there is both a mantissa and an exponent, the mantissa is
+% combined with the product sign before adding the exponent part on.
+% The combined result is then stored. The marker
+% \texttt{result-bracket-exponent} indicates that the number needs
+% brackets due to the exponent part, but not in other cases.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_final_combined: {
+ \@@_number_format_brackets:n { mantissa }
+ \prop_get:NnN \l_@@_number_out_prop { mantissa-result }
+ \l_@@_tmpa_tl
+ \tl_if_empty:NT \l_@@_output_exponent_tl
+ {
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ \exp_not:N \ensuremath
+ {
+ \bool_if:NTF \l_@@_tight_bool
+ { { \exp_not:V \l_@@_exponent_product_tl } }
+ { { } \exp_not:V \l_@@_exponent_product_tl { } }
+ }
+ }
+ }
+ \prop_get:NnN \l_@@_number_out_prop { exponent-result }
+ \l_@@_tmpb_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \prop_put:NnV \l_@@_number_out_prop { result }
+ \l_@@_tmpa_tl
+ \prop_put:Nnn \l_@@_number_out_prop
+ { result-bracket-exponent } { true }
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@@_number_format_final_exponent:}
+% When there is an exponent, the base always needs to be added to the
+% front of the number itself. The number must be superscripted, of
+% course.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_final_exponent: {
+ \prop_get:NnN \l_@@_number_out_prop { exponent }
+ \l_@@_tmpa_tl
+ \tl_if_empty:NTF \l_@@_output_exponent_tl
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ { ^ { \exp_not:V \l_@@_tmpa_tl } }
+ \tl_put_left:NV \l_@@_tmpa_tl \l_@@_exponent_base_tl
+ }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \exp_not:V \l_@@_output_exponent_tl
+ \exp_not:N \mathord
+ \exp_not:V \l_@@_tmpa_tl
+ }
+ }
+ \prop_put:NnV \l_@@_number_out_prop { exponent-result }
+ \l_@@_tmpa_tl
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@@_number_format_final_exponent_only:}
+% When there is only an exponent, a check must be made for a
+% sign in the mantissa part. If there is one, it is copied across.
+% \begin{macrocode}
+\cs_new_protected:Npn
+ \@@_number_format_final_exponent_only: {
+ \prop_get:NnNT \l_@@_number_in_prop { mantissa-sign }
+ \l_@@_tmpa_tl
+ {
+ \prop_get:NnN \l_@@_number_out_prop { exponent-result }
+ \l_@@_tmpb_tl
+ \@@_tl_put_left_math:NV \l_@@_tmpb_tl
+ \l_@@_tmpa_tl
+ \prop_put:NnV \l_@@_number_out_prop { exponent-result }
+ \l_@@_tmpb_tl
+ }
+ \@@_number_format_copy:nn { exponent-result } { result }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_format_group:n}
+%\begin{macro}{\@@_number_format_group_aux:nn}
+% Grouping digits only happens if there are no symbols in the input, and
+% of course if grouping has been requested.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_group:n #1 {
+ \@@_number_format_group_aux:nn {#1} { integer }
+ \@@_number_format_group_aux:nn {#1} { decimal }
+ \prop_if_in:NnTF \l_@@_number_out_prop { #1 -integer }
+ { \@@_number_format_copy:nn { #1 -integer } {#1} }
+ { \tl_clear:N \l_@@_tmpa_tl }
+ \prop_get:NnNT \l_@@_number_in_prop { #1 -decimal-marker }
+ \l_@@_tmpb_tl
+ {
+ \bool_if:NTF \l_@@_output_decimal_copy_bool
+ { \tl_set:Nx \l_@@_tmpb_tl { { \l_@@_tmpb_tl } } }
+ {
+ \tl_set_eq:NN \l_@@_tmpb_tl
+ \l_@@_output_decimal_tl
+ }
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \prop_put:NnV \l_@@_number_out_prop { #1 -decimal-marker }
+ \l_@@_tmpb_tl
+ \prop_get:NnNF \l_@@_number_out_prop { #1 -decimal }
+ \l_@@_tmpb_tl
+ { \tl_clear:N \l_@@_tmpb_tl }
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \prop_put:NnV \l_@@_number_out_prop {#1} \l_@@_tmpa_tl
+ }
+}
+\cs_new_protected:Npn \@@_number_format_group_aux:nn #1#2 {
+ \prop_if_in:NnT \l_@@_number_in_prop { #1 - #2 }
+ {
+ \bool_if:cTF { l_@@_group_ #2 _bool }
+ { \@@_number_format_group:nn {#1} {#2} }
+ { \@@_number_format_copy:n { #1 - #2 } }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+% \begin{macro}{\@@_number_format_group:nn}
+% The idea here is that grouping is only needed for numbers with sufficient
+% digits: this is done simply by counting up all of the digits.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_group:nn #1#2
+ {
+ \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
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%\begin{macro}{\@@_number_format_group_decimal:}
+%\begin{macro}{\@@_number_format_group_decimal_aux:}
+% Using the \enquote{keep everything on the stack} approach, relatively
+% simple recursion is needed. This trick is taken more or less directly
+% from \pkg{numprint}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_group_decimal: {
+ \tl_if_empty:NF \l_@@_tmpa_tl
+ {
+ \exp_after:wN \@@_number_format_group_decimal_aux:NNNN
+ \l_@@_tmpa_tl { } { } { }
+ }
+}
+\cs_new_protected:Npn \@@_number_format_group_decimal_aux:NNNN
+ #1#2#3#4 {
+ \tl_if_empty:nTF {#2}
+ { \tl_put_right:Nn \l_@@_tmpb_tl {#1} }
+ {
+ \tl_if_empty:nTF {#3}
+ { \tl_put_right:Nn \l_@@_tmpb_tl { #1 #2 } }
+ {
+ \tl_put_right:Nn \l_@@_tmpb_tl { #1 #2 #3 }
+ \tl_if_empty:nF {#4}
+ {
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_group_sep_tl
+ \@@_number_format_group_decimal_aux:NNNN #4
+ }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\begin{macro}{\@@_number_format_group_integer:}
+%\begin{macro}{
+% \@@_number_format_group_integer_setup:n ,
+% \@@_number_format_group_integer_setup:V ,
+% \@@_number_format_group_integer_setup_aux:NNNN ,
+% \@@_number_format_group_integer_aux:NNNN
+%}
+% By keeping everything on the stack, recursion can occur quite
+% efficiently here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_group_integer: {
+ \tl_if_empty:NF \l_@@_tmpa_tl
+ {
+ \@@_number_format_group_integer_setup:V \l_@@_tmpa_tl
+ }
+}
+\cs_new_protected:Npn \@@_number_format_group_integer_setup:n #1 {
+ \@@_number_format_group_integer_setup_aux:NNNN
+ { } #1 { } { } { }
+}
+\cs_generate_variant:Nn \@@_number_format_group_integer_setup:n
+ { V }
+\cs_new_protected:Npn
+ \@@_number_format_group_integer_setup_aux:NNNN #1#2#3#4 {
+ \tl_if_empty:nTF {#2}
+ { \@@_number_format_group_integer_aux:NNNN #1 \q_nil }
+ {
+ \tl_if_empty:nTF {#3}
+ {
+ \@@_number_format_group_integer_aux:NNNN { } { } #1#2
+ \q_nil
+ }
+ {
+ \tl_if_empty:nTF {#4}
+ {
+ \@@_number_format_group_integer_aux:NNNN { } #1#2#3
+ \q_nil
+ }
+ {
+ \@@_number_format_group_integer_setup_aux:NNNN
+ {#1#2#3#4}
+ }
+ }
+ }
+}
+\cs_new_protected:Npn
+ \@@_number_format_group_integer_aux:NNNN #1#2#3#4 {
+ \tl_put_right:Nn \l_@@_tmpb_tl {#1#2#3}
+ \quark_if_nil:nF {#4}
+ {
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_group_sep_tl
+ \@@_number_format_group_integer_aux:NNNN #4
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_number_format_join_complex:}
+% For adding the complex part to the main part of a number.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_number_format_join_complex: {
+ \@@_number_format_sign_complex:
+ \prop_if_in:NnT \l_@@_number_out_prop { mantissa }
+ {
+ \@@_number_format_brackets:n { mantissa }
+ \prop_get:NnN \l_@@_number_out_prop { mantissa-result }
+ \l_@@_tmpa_tl
+ \prop_get:NnNF \l_@@_number_out_prop { complex-result }
+ \l_@@_tmpb_tl
+ {
+ \prop_get:NnN \l_@@_number_out_prop { complex }
+ \l_@@_tmpb_tl
+ }
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \prop_put:NnV \l_@@_number_out_prop { mantissa-result }
+ \l_@@_tmpa_tl
+ \prop_put:Nnn \l_@@_number_out_prop { mantissa-bracket }
+ { true }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_number_format_join_uncert: ,
+% \@@_number_format_join_uncert:n
+%}
+%\begin{macro}{\@@_number_format_join_uncert_pm:N}
+% For adding separated uncertainties to the main part of a number.
+% \begin{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
+ {
+ \bool_if:NTF \l_@@_tight_bool
+ { \tl_put_left:Nn #1 { \ensuremath { { \pm } } } }
+ { \tl_put_left:Nn #1 { \ensuremath { { } \pm { } } } }
+ }
+% \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
+ {
+ \@@_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
+ }
+ }
+\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:NnNT \l_@@_number_out_prop { mantissa-integer }
+ \l_@@_tmpa_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
+ {
+ \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} }
+ }
+ }
+\prop_new:N \l_@@_prefix_forward_prop
+\prop_new:N \l_@@_prefix_reverse_prop
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+%\begin{macro}{\@@_declare_qualifier:Nn}
+% Qualifiers just need storing.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_qualifier:Nn #1#2 {
+ \seq_put_right:Nn \l_siunitx_unit_symbolic_seq {#1}
+ \cs_set:cpn { @@_ \token_to_str:N #1 _literal:w }
+ { \text { ~ } ( #2 ) }
+ \cs_set:cpn { @@_ \token_to_str:N #1 _function:w }
+ { \@@_unit_parse_qualifier:n {#2} }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_declare_unit:Nnn}
+%\begin{macro}{\@@_unit_first_token:n}
+% Creating units requires various things to be stored. This is done
+% with several storage bins to keep the code clear. For the
+% \texttt{macro} definition, the test occurs at use so that there is no
+% problem with the creation order for units.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_unit:Nnn #1#2#3 {
+ \seq_put_right:Nn \l_siunitx_unit_symbolic_seq {#1}
+ \cs_set:cpn { @@_ \token_to_str:N #1 _literal:w } {#2}
+ \cs_set_protected:cpn { @@_ \token_to_str:N #1 _function:w }
+ {
+ \@@_unit_if_literal:nTF {#2}
+ { \@@_unit_parse_unit:Nn #1 {#2} }
+ {#2}
+ }
+ \tl_if_empty:nTF {#3}
+ { \cs_undefine:c { l_@@_ \token_to_str:N #1 _options_tl } }
+ {
+ \tl_clear_new:c { l_@@_ \token_to_str:N #1 _options_tl }
+ \tl_set:cn { l_@@_ \token_to_str:N #1 _options_tl } {#3}
+ }
+}
+\cs_new_protected:Npn \@@_unit_first_token:n #1 {
+ \exp_last_unbraced:No \token_to_str:N { \tl_head:w #1 \q_stop }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\per}
+% The \cs{per} function is pretty simple.
+% \begin{macrocode}
+\cs_new:cpn { @@_ \token_to_str:N \per _literal:w } { / }
+\cs_new_protected:cpn { @@_ \token_to_str:N \per _function:w } {
+ \bool_set_true:N \l_@@_per_bool
+ \@@_unit_parse_per:
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \raiseto ,
+% \tothe
+%}
+% Generic versions of the pre-set powers.
+% \begin{macrocode}
+\cs_new:cpn { @@_ \token_to_str:N \raiseto _literal:w } #1#2 {
+ #2
+ \@@_textsuperscript:n {#1}
+}
+\cs_new_protected:cpn { @@_ \token_to_str:N \raiseto _function:w }
+ #1 {
+ \@@_unit_parse_power_before:n {#1}
+}
+\cs_new:cpn { @@_ \token_to_str:N \tothe _literal:w } #1 {
+ \@@_textsuperscript:n {#1}
+}
+\cs_new_protected:cpn { @@_ \token_to_str:N \tothe _function:w }
+ #1 {
+ \@@_unit_parse_power_after:n {#1}
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\of}
+% A flexible qualifier as well.
+% \begin{macrocode}
+\cs_new:cpn { @@_ \token_to_str:N \of _literal:w } #1 {
+ \text { ~ } ( #1 )
+}
+\cs_new_protected:cpn { @@_ \token_to_str:N \of _function:w } #1 {
+ \@@_unit_parse_qualifier:n {#1}
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\cancel}
+%\begin{macro}{\@@_real_cancel:n}
+%\begin{macro}{\@@_cancel:n}
+% The \cs{cancel} macro is odd as it is only defined if the appropriate
+% package is loaded.
+% \begin{macrocode}
+\AtBeginDocument {
+ \cs_if_exist:NT \cancel
+ {
+ \cs_set_protected:Npn \@@_cancel:n #1
+ { \@@__real_cancel:n { \@@_print:nn { unit } {#1} } }
+ \cs_set_eq:NN \@@__real_cancel:n \cancel
+ \seq_put_right:Nn \l_siunitx_unit_symbolic_seq { \cancel }
+ \cs_new_protected:cpn
+ { @@_ \token_to_str:N \cancel _function:w }
+ { \@@_unit_parse_special:n { \@@_cancel:n } }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\highlight}
+% Another special function: selective colour.
+% \begin{macrocode}
+\cs_new:cpn
+ { @@_ \token_to_str:N \highlight _literal:w } #1
+ { \@@_textcolor:n {#1} }
+\cs_new_protected:cpn
+ { @@_ \token_to_str:N \highlight _function:w } #1
+ { \@@_unit_parse_special:n { \@@_textcolor:n {#1} } }
+% \end{macrocode}
+%\end{macro}
+%
+%\subsection{Creating body unit macros}
+%
+% The user might have asked for the unit macros to be available in the
+% document body. If so, then these are created at the start of the
+% document body.
+%
+%\begin{macro}{
+% \l_@@_create_free_bool ,
+% \l_@@_create_overwrite_bool ,
+% \l_@@_create_prespace_bool ,
+% \l_@@_create_optional_bool ,
+% \l_@@_create_xspace_bool
+%}
+% There are a few options which control this behaviour: these are all
+% preamble-only.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ free-standing-units .bool_set:N = \l_@@_create_free_bool ,
+ overwrite-functions .bool_set:N = \l_@@_create_overwrite_bool,
+ space-before-unit .bool_set:N = \l_@@_create_prespace_bool ,
+ unit-optional-argument .bool_set:N = \l_@@_create_optional_bool ,
+ use-xspace .bool_set:N = \l_@@_create_xspace_bool ,
+}
+\@@_option_deactivate:n {
+ free-standing-units ,
+ overwrite-functions ,
+ space-before-unit ,
+ unit-optional-argument ,
+ use-xspace ,
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_unit_create_empty_functions:}
+%\begin{macro}{\@@_unit_create_empty_functions_aux:N}
+% Without this, horrible things happen with \pkg{memoir} and
+% \pkg{hyperref}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_unit_create_empty_functions:
+ {
+ \@@_unit_create_functions_aux_i:
+ \seq_map_function:NN \l_siunitx_unit_symbolic_seq
+ \@@_unit_create_empty_functions_aux:N
+ \@@_unit_create_functions_aux_ii:
+ }
+\cs_new_protected:Npn \@@_unit_create_empty_functions_aux:N #1
+ {
+ \cs_if_free:NT #1
+ { \cs_set_protected:Npn #1 { \ERROR } }
+ }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+% \begin{macro}{\@@_unit_create_functions:}
+% \begin{macro}
+% {
+% \@@_unit_create_functions_aux_i:,
+% \@@_unit_create_functions_aux_ii:
+% }
+% Creation of macros essentially involves picking up a couple of loops.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_unit_create_functions:
+ {
+ \@@_unit_create_functions_aux_i:
+ \bool_if:NT \l_@@_create_overwrite_bool
+ { \seq_map_function:NN \l_siunitx_unit_symbolic_seq \cs_undefine:N }
+ \bool_if:NTF \l_@@_create_optional_bool
+ {
+ \seq_map_function:NN \l_siunitx_unit_symbolic_seq
+ \@@_unit_create_with_arg:N
+ }
+ {
+ \seq_map_function:NN \l_siunitx_unit_symbolic_seq
+ \@@_unit_create:N
+ }
+ \@@_unit_create_functions_aux_ii:
+ \bool_if:NT \l_@@_create_xspace_bool
+ { \RequirePackage { xspace } }
+ }
+\cs_new_protected:Npn \@@_unit_create_functions_aux_i:
+ {
+ \@ifpackageloaded { soulpos }
+ {
+ \@ifpackageloaded { soul }
+ { }
+ {
+ \cs_set_protected:Npn \@@_unit_create_functions_aux_ii:
+ {
+ \cs_undefine:N \hl
+ \cs_undefine:N \ul
+ }
+ }
+ }
+ { }
+ }
+\cs_new_protected:Npn \@@_unit_create_functions_aux_ii: { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%\begin{macro}{
+% \@@_unit_create:N ,
+% \@@_unit_create_with_arg:N
+%}
+% The creation functions expand everything as far as possible so that
+% there is less to do in the document.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_unit_create:N #1 {
+ \cs_if_free:NT #1
+ {
+ \cs_set:Npx \@@_tmp:w
+ {
+ \ProvideDocumentCommand \exp_not:N #1 { }
+ {
+ \group_begin:
+ \exp_not:N \cs_if_free:NF
+ \exp_not:c
+ { l_@@_ \token_to_str:N #1 _options_tl }
+ {
+ \keys_set:nV { siunitx }
+ \exp_not:c
+ { l_@@_ \token_to_str:N #1 _options_tl }
+ }
+ \bool_if:NT \l_@@_create_prespace_bool
+ { \exp_not:N \l_@@_number_unit_product_tl }
+ \exp_not:n { \@@_unit_output:nn {#1} { } }
+ \group_end:
+ \bool_if:NT \l_@@_create_xspace_bool
+ { \exp_not:N \xspace }
+ }
+ }
+ \@@_tmp:w
+ }
+}
+\cs_new_protected:Npn \@@_unit_create_with_arg:N #1 {
+ \cs_if_free:NT #1
+ {
+ \cs_set:Npx \@@_tmp:w
+ {
+ \ProvideDocumentCommand \exp_not:N #1 { o }
+ {
+ \group_begin:
+ \exp_not:N \cs_if_free:NF
+ \exp_not:c
+ { l_@@_ \token_to_str:N #1 _options_tl }
+ {
+ \keys_set:nV { siunitx }
+ \exp_not:c
+ {
+ l_@@_ \token_to_str:N #1 _options_tl
+ }
+ }
+ \exp_not:N \IfNoValueTF {####1}
+ {
+ \bool_if:NT \l_@@_create_prespace_bool
+ { \exp_not:N \l_@@_number_unit_product_tl }
+ \exp_not:n { \@@_unit_output:nn {#1} { } }
+ }
+ { \SI {####1} { \exp_not:N #1 } }
+ \group_end:
+ \bool_if:NT \l_@@_create_xspace_bool
+ { \exp_not:N \xspace }
+ }
+ }
+ \@@_tmp:w
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_protect_symbols:N}
+% There are a few unit names which may be defined by other parts of
+% \LaTeX. They need to be unexpandable, as in an \texttt{S} column
+% \TeX{} will look for \cs{omit} \emph{before} starting the internal
+% version of \cs{si} and doing a redefinition. The same is true
+% for the \cs{color} function, which may well be the first thing in
+% a table cell. The same is true for \cs{array@row@rst}, from REV\TeX,
+% which otherwise gives an error.
+% \begin{macrocode}
+\AtBeginDocument {
+ \cs_if_eq:NNT \color \use_none:n
+ { \cs_set_protected:Npn \color #1 { } }
+ \cs_set:Npn \@@_tmp:w #1 { }
+ \cs_if_eq:NNT \color \@@_tmp:w
+ { \cs_set_protected:Npn \color #1 { } }
+ \tl_map_function:nN { \bar \color \ng \pm \array@row@rst }
+ \@@_protect_symbols:N
+}
+\tl_put_right:Nn \document { \@@_protect_symbols:N \fg }
+\cs_new_protected:Npn \@@_protect_symbols:N #1 {
+ \cs_if_exist:NT #1
+ {
+ \tl_if_empty:fT { \token_get_prefix_spec:N #1 }
+ { \cs_set_protected:Npx #1 { \exp_not:V #1 } }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\subsection{Initial unit processing}
+%
+% The unit processor has to convert the input (which may be all macros
+% or may contain literal input) into formatted text for output. The
+% input part of the process is used to sort out parsed or literal units.
+%
+%\begin{macro}{
+% \l_@@_unit_forbid_literal_bool ,
+% \l_@@_unit_parse_bool
+%}
+% One option is related to how units are pre-processed.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ forbid-literal-units .bool_set:N =
+ \l_@@_unit_forbid_literal_bool,
+ parse-units .bool_set:N = \l_@@_unit_parse_bool
+}
+\keys_set:nn { siunitx } {
+ forbid-literal-units = false,
+ parse-units = true
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{
+% \@@_unit_in:nn ,
+% \@@_unit_in:Vn ,
+% \@@_pm:
+%}
+% The master function does a very simple checks then hands off.
+% The definition of \cs{pm} needs to be saved here so that it can
+% safely be used as an abbreviation for picometre and also in numbers
+% for \( \pm \).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_unit_in:nn #1#2 {
+ \bool_if:NTF \l_@@_unit_parse_bool
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \@@_unit_if_literal:nTF {#1}
+ {
+ \tl_clear:N \l_@@_per_mode_tl
+ \bool_if:NTF \l_@@_unit_forbid_literal_bool
+ {
+ \msg_error:nnx { siunitx } { literal-unit }
+ { \exp_not:n {#1} }
+ }
+ {
+ \cs_set_eq:NN \@@_pm: \pm
+ \@@_unit_format_literal:n {#1}
+ \cs_set_eq:NN \pm \@@_pm:
+ }
+ }
+ {
+ \cs_set_eq:NN \@@_pm: \pm
+ \@@_unit_parse:nn {#1} {#2}
+ \@@_unit_format:
+ \prop_set_eq:NN \l_@@_unit_saved_prop \l_@@_unit_prop
+ \cs_set_eq:NN \pm \@@_pm:
+ }
+ }
+ }
+ { \@@_unit_format_literal:n {#1} }
+}
+\cs_generate_variant:Nn \@@_unit_in:nn { V }
+\cs_new:Npn \@@_pm: { }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_unit_if_literal:nTF}
+%\begin{macro}{\@@_unit_if_literal_aux:N}
+% A test is needed to see if the input only contains unit macros. This
+% is done by altering setting all of the unit macros to expand to
+% nothing at all. Thus there will only be anything left if there is
+% a literal in the unit.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_unit_if_literal:nTF #1#2#3 {
+ \group_begin:
+ \seq_map_function:NN \l_siunitx_unit_symbolic_seq
+ \@@_unit_if_literal_aux:N
+ \cs_set_eq:NN \of \use_none:n
+ \cs_set_eq:NN \highlight \use_none:n
+ \cs_set_eq:NN \raiseto \use_none:n
+ \cs_set_eq:NN \tothe \use_none:n
+ \protected@edef \l_@@_tmpa_tl {#1}
+ \exp_args:NNNV \group_end:
+ \tl_set:Nn \l_@@_tmpa_tl \l_@@_tmpa_tl
+ \tl_if_blank:VTF \l_@@_tmpa_tl {#3} {#2}
+}
+\cs_new_protected:Npn \@@_unit_if_literal_aux:N #1 {
+ \cs_set_eq:NN #1 \prg_do_nothing:
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\subsection{Parsing macro units}
+%
+% For macro-based units, the macros are converted into literal text,
+% which is then passed on for printing. The code reads through the
+% input to collect up the units, before re-combining everything into
+% a single block at the end of the process.
+%
+% \begin{variable}
+% {
+% \l_@@_unit_int ,
+% \l_@@_unit_prop ,
+% \l_@@_unit_saved_prop
+% }
+% Parsed units are stored in a property list, to keep things compact.
+% An integer is also needed to count up units.
+% \begin{macrocode}
+\int_new:N \l_@@_unit_int
+\prop_new:N \l_@@_unit_prop
+\prop_new:N \l_@@_unit_saved_prop
+% \end{macrocode}
+% \end{variable}
+%
+%\begin{macro}{\l_@@_per_bool}
+% To allow \cs{per} to be \enquote{sticky}.
+% \begin{macrocode}
+\bool_new:N \l_@@_per_bool
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{variable}
+% {
+% \l_@@_exp_to_prefix_bool ,
+% \l_@@_prefix_symbols_bool ,
+% \l_@@_sticky_per_bool
+% }
+% Some options are directly related to how units are handled at this
+% stage, so need be created before the reconstruction part of the code.
+% \begin{macrocode}
+\keys_define:nn { siunitx }
+ {
+ 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
+ }
+\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{macrocode}
+\cs_new_protected:Npn \@@_unit_format_literal_extras:
+ {
+ \@@_unit_format_literal_extras_aux:nN { 176 }
+ \SIUnitSymbolDegree
+ \@@_unit_format_literal_extras_aux:nN { 181 }
+ \SIUnitSymbolMicro
+ \@@_unit_format_literal_extras_aux:nN { 197 }
+ \SIUnitSymbolAngstrom
+ }
+\cs_new_protected:Npn \@@_unit_format_literal_extras_aux:nN #1#2
+ {
+ \tl_replace_all:Nxn \l_@@_unit_tl
+ { \char_generate:nn { #1 } { 12 } }
+ {#2}
+ }
+\bool_lazy_or:nnF { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: }
+ {
+ \AtBeginDocument
+ {
+ \cs_if_exist:NTF \inputencodingname
+ {
+ \tl_set:Nn \l_@@_tmpa_tl { latin1 , latin5 , latin9 }
+ \clist_if_in:NVF \l_@@_tmpa_tl \inputencodingname
+ {
+ \cs_set_eq:NN \@@_unit_format_literal_extras:
+ \scan_stop:
+ }
+ }
+ {
+ \cs_set_eq:NN \@@_unit_format_literal_extras:
+ \scan_stop:
+ }
+ }
+ }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_unit_format_power:}
+%\begin{macro}{
+% \@@_unit_format_power_aux: ,
+% \@@_unit_format_power_aux:n ,
+% \@@_unit_format_power_aux:nn ,
+% \@@_unit_format_power_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_not:V \l_@@_tmpa_tl }
+ }
+ }
+ }
+}
+\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 { \c_@@_minus_tl } }
+ \@@_print:nV {#1} \l_@@_tmpa_tl
+ }
+}
+% \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{Unit output}
+%
+% A collection of the internal parts of various user functions.
+%
+%\begin{macro}{\l_@@_multi_brackets_bool}
+%\begin{macro}{\l_@@_multi_repeat_bool}
+% Flags for multi-part numbers.
+% \begin{macrocode}
+\bool_new:N \l_@@_multi_brackets_bool
+\bool_new:N \l_@@_multi_repeat_bool
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_product_brackets_bool}
+%\begin{macro}{\l_@@_product_power_bool}
+%\begin{macro}{\l_@@_number_unit_repeat_bool}
+% Flags for product units.
+% \begin{macrocode}
+\bool_new:N \l_@@_product_brackets_bool
+\bool_new:N \l_@@_product_power_bool
+\bool_new:N \l_@@_product_repeat_bool
+\bool_new:N \l_@@_number_unit_repeat_bool
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_number_unit_breaks_bool}
+%\begin{macro}{\l_@@_number_unit_product_tl}
+% Options for printing units or units with numbers.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ allow-number-unit-breaks .bool_set:N =
+ \l_@@_number_unit_breaks_bool,
+ multi-part-units .choice:,
+ multi-part-units
+ / brackets .code:n =
+ {
+ \bool_set_true:N \l_@@_multi_brackets_bool
+ \bool_set_false:N \l_@@_multi_repeat_bool
+ },
+ multi-part-units
+ / repeat .code:n =
+ {
+ \bool_set_false:N \l_@@_multi_brackets_bool
+ \bool_set_true:N \l_@@_multi_repeat_bool
+ },
+ multi-part-units
+ / single .code:n =
+ {
+ \bool_set_false:N \l_@@_multi_brackets_bool
+ \bool_set_false:N \l_@@_multi_repeat_bool
+ },
+ number-unit-product .tl_set:N =
+ \l_@@_number_unit_product_tl,
+ number-unit-separator .tl_set:N =
+ \l_@@_number_unit_product_tl,
+ product-units .choice:,
+ product-units
+ / brackets .code:n =
+ {
+ \bool_set_true:N \l_@@_product_brackets_bool
+ \bool_set_false:N \l_@@_product_power_bool
+ \bool_set_false:N \l_@@_product_repeat_bool
+ },
+ product-units
+ / brackets-power .code:n =
+ {
+ \bool_set_true:N \l_@@_product_brackets_bool
+ \bool_set_true:N \l_@@_product_power_bool
+ \bool_set_false:N \l_@@_product_repeat_bool
+ },
+ product-units
+ / power .code:n =
+ {
+ \bool_set_false:N \l_@@_product_brackets_bool
+ \bool_set_true:N \l_@@_product_power_bool
+ \bool_set_false:N \l_@@_product_repeat_bool
+ },
+ product-units
+ / repeat .code:n =
+ {
+ \bool_set_false:N \l_@@_product_brackets_bool
+ \bool_set_false:N \l_@@_product_power_bool
+ \bool_set_true:N \l_@@_product_repeat_bool
+ },
+ product-units
+ / single .code:n =
+ {
+ \bool_set_false:N \l_@@_product_brackets_bool
+ \bool_set_false:N \l_@@_product_power_bool
+ \bool_set_false:N \l_@@_product_repeat_bool
+ },
+}
+\keys_set:nn { siunitx } {
+ multi-part-units = brackets,
+ number-unit-product = \, ,
+ product-units = repeat
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_unit_output:nn}
+%\begin{macro}{\@@_unit_output:Vn}
+% For typesetting a unit directly: used by \cs{si} and the \texttt{s}
+% column. The second argument is any options to set locally.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_unit_output:nn #1#2 {
+ \cs_set_eq:NN \@@_unit_format_symbol_aux:
+ \@@_unit_format_symbol_aux_alt:
+ \cs_set_eq:NN \@@_unit_format_fraction_symbol_aux_ii:
+ \@@_unit_format_fraction_symbol_aux_alt:
+ \@@_unit_in:nn {#1} {#2}
+ \int_compare:nNnTF { \l_@@_unit_prefix_int } = { 0 }
+ {
+ \str_if_eq:VnT \l_@@_per_mode_tl { symbol }
+ {
+ \int_compare:nNnT { \l_@@_unit_numerator_int } = { 0 }
+ {
+ \bool_if:NT \l_@@_unit_parse_bool
+ { \@@_print:nn { unit } { 1 } }
+ }
+ }
+ }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \int_use:N \l_@@_unit_prefix_base_int
+ \exp_not:N \PrintSuperscript
+ { \int_use:N \l_@@_unit_prefix_int }
+ }
+ \@@_print:nV { number } \l_@@_tmpa_tl
+ \@@_unit_output_number_sep:
+ }
+ \@@_print:nV { unit } \l_@@_unit_tl
+}
+\cs_generate_variant:Nn \@@_unit_output:nn { V }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_unit_output_number_sep:}
+%\begin{macro}{\@@_unit_output_number_sep_aux:}
+% For printing the number separator. The \cs{tex_mathchoice:D} code
+% deals with the \opt{symbol-or-fraction} setting for \opt{per-mode},
+% as in that case omission of the space between a number and unit
+% depends on the current math style.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_unit_output_number_sep: {
+ \bool_if:NTF \l_@@_number_unit_breaks_bool
+ { \penalty \binoppenalty } { \nobreak }
+ \bool_if:NTF \l_@@_per_auto_bool
+ {
+ \mode_if_math:TF
+ {
+ \tex_mathchoice:D
+ { \l_@@_number_unit_product_tl }
+ { \@@_unit_output_number_sep_aux: }
+ { \@@_unit_output_number_sep_aux: }
+ { \@@_unit_output_number_sep_aux: }
+ }
+ { \@@_unit_output_number_sep_aux: }
+ }
+ { \@@_unit_output_number_sep_aux: }
+}
+\cs_new_protected:Npn \@@_unit_output_number_sep_aux: {
+ \bool_if:NF \l_@@_omit_unit_space_bool
+ { \l_@@_number_unit_product_tl }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_unit_output_pre_print:}
+%\begin{macro}{\@@_unit_output_print:}
+% The printing functions for units do some simple tests then
+% actually print there output.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_unit_output_pre_print: {
+ \tl_if_empty:NF \l_@@_pre_unit_tl
+ {
+ \nobreak
+ \@@_print:nV { unit } \l_@@_pre_unit_tl
+ }
+}
+\cs_new_protected:Npn \@@_unit_output_print: {
+ \int_compare:nNnF { \l_@@_unit_prefix_int } = { 0 }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \bool_if:NTF \l_@@_tight_bool
+ {
+ \exp_not:N \ensuremath
+ { { \exp_not:V \l_@@_exponent_product_tl } }
+ }
+ {
+ \exp_not:N \ensuremath
+ { { } \exp_not:V \l_@@_exponent_product_tl { } }
+ }
+ \int_use:N \l_@@_unit_prefix_base_int
+ ^ { \int_use:N \l_@@_unit_prefix_int }
+ }
+ \@@_print:nV { number } \l_@@_tmpa_tl
+ }
+ \tl_if_empty:NF \l_@@_unit_tl
+ {
+ \@@_unit_output_number_sep:
+ \@@_print:nV { unit } \l_@@_unit_tl
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\subsection{Numbers with units}
+%
+% Numbers with units have to be formatted in a more complex way than
+% simply sticking the two together.
+%
+%\begin{macro}{\l_@@_preunit_tl}
+% A pre-unit is optional, so can be handled using the setting system.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ preunit .tl_set:N = \l_@@_preunit_tl ,
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_pre_unit_tl}
+% When there is a pre-unit, it gets stored here.
+% \begin{macrocode}
+\tl_new:N \l_@@_pre_unit_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_number_product_int}
+% Used to count up the number of product tokens in a number.
+% \begin{macrocode}
+\int_new:N \l_@@_number_product_int
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_combined:nnnn}
+% Printing numbers and units means first processing the units, then
+% handing off this information to the combined number and unit
+% processor.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_combined:nnnn #1#2#3#4 {
+ \IfNoValueTF {#3}
+ { \tl_clear:N \l_@@_pre_unit_tl }
+ {
+ \group_begin:
+ \@@_unit_in:nn {#3} {#1}
+ \cs_set_eq:NN \l_@@_pre_unit_tl \l_@@_unit_tl
+ \exp_args:NNNo \group_end:
+ \tl_set:Nn \l_@@_pre_unit_tl { \l_@@_unit_tl }
+ }
+ \cs_set_eq:NN \l_@@_brackets_bool
+ \l_@@_multi_brackets_bool
+ \@@_combined_unit:nnn {#2} {#4} {#1}
+ \@@_combined_output:n {#2}
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_combined_output:n}
+% Printing the combination of a number and a unit means checking for
+% parsing then parsing the number part.
+% \begin{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 }
+ {
+ 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_map_function:nN {#1} \@@_list_numbers_aux_ii:n
+ \l_@@_list_tl
+ \l_@@_list_separator_final_tl
+ \l_@@_list_current_tl
+ }
+ {
+ \int_compare:nNnTF { \tl_count:n {#1} } = 2
+ { \@@_list_numbers_aux:nn #1 }
+ { \@@_combined_output:n #1 }
+ }
+ }
+\cs_new_protected:Npn \@@_list_numbers_aux_ii:n #1
+ {
+ \tl_if_empty:NTF \l_@@_list_tl
+ { \tl_set_eq:NN \l_@@_list_tl \l_@@_list_current_tl }
+ {
+ \tl_put_right:NV \l_@@_list_tl \l_@@_list_separator_tl
+ \tl_put_right:NV \l_@@_list_tl \l_@@_list_current_tl
+ }
+ \tl_set:Nn \l_@@_list_current_tl { \@@_combined_output:n {#1} }
+ }
+\cs_new_protected:Npn \@@_list_numbers_aux:nn #1#2
+ {
+ \@@_combined_output:n {#1}
+ \l_@@_list_separator_pair_tl
+ \@@_combined_output:n {#2}
+ }
+% \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{Ranges}
+%
+%\begin{macro}{\l_@@_range_brackets_bool}
+%\begin{macro}{\l_@@_range_repeat_bool}
+% Settings for ranges with units.
+% \begin{macrocode}
+\bool_new:N \l_@@_range_brackets_bool
+\bool_new:N \l_@@_range_repeat_bool
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_range_phrase_tl}
+% Simple settings for ranges.
+% \begin{macrocode}
+\keys_define:nn { siunitx } {
+ range-phrase .tl_set:N = \l_@@_range_phrase_tl,
+ range-units .choice:,
+ range-units
+ / brackets .code:n =
+ {
+ \bool_set_true:N \l_@@_range_brackets_bool
+ \bool_set_false:N \l_@@_range_repeat_bool
+ },
+ range-units
+ / repeat .code:n =
+ {
+ \bool_set_false:N \l_@@_range_brackets_bool
+ \bool_set_true:N \l_@@_range_repeat_bool
+ },
+ range-units
+ / single .code:n =
+ {
+ \bool_set_false:N \l_@@_range_brackets_bool
+ \bool_set_false:N \l_@@_range_repeat_bool
+ },
+}
+\keys_set:nn { siunitx } {
+ range-phrase = { ~ to ~ },
+ range-units = repeat,
+}
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\@@_range_numbers:nn}
+% \begin{macro}{\@@_range_numbers_core:nn}
+% \begin{macro}{\@@_range_numbers_aux:n}
+% A range of numbers. This is more restrictive than the \cs{num}
+% function: nothing compound.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_range_numbers:nn #1#2
+ {
+ \@@_range_numbers_aux:n {#1}
+ \l_@@_range_phrase_tl
+ \@@_range_numbers_aux:n {#2}
+ }
+\cs_new_protected:Npn \@@_range_numbers_aux:n #1
+ {
+ \bool_if:NTF \l_@@_number_parse_bool
+ {
+ \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} }
+ }
+ {
+ \@@_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
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ { \exp_not:N \mathord \exp_not:o \l_@@_tmpa_tl }
+ }
+ \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
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%\subsection{Setting up tables}
+%
+% There is a slight problem with the \pkg{cellspace} package: it also
+% uses \texttt{S} for a column type Here, \texttt{S} seems to make
+% more sense for \pkg{siunitx}, with \texttt{C} used for
+% \pkg{cellspace}. To enable this to work well, the column
+% rewriting code happens \cs{AtBeginDocument}. The \texttt{S} column
+% is deleted from \cs{NC@list} so that no warning appears.
+% \begin{macrocode}
+\AtBeginDocument {
+ \@ifpackageloaded { cellspace }
+ {
+ \cs_if_exist:NT \NC@find@S
+ {
+ \newcolumntype { C } [1]
+ { > { \bcolumn #1 \@nil } #1 < { \ecolumn } }
+ \cs_set:Npn \@@_tmp:w #1 \NC@do S #2 \q_stop
+ { \NC@list { #1 #2 } }
+ \exp_after:wN \@@_tmp:w \tex_the:D \NC@list \q_stop
+ \cs_undefine:N \NC@find@S
+ \msg_new:nnn { siunitx } { moved-cellspace-column }
+ { Column~type~for~cellspace~package~moved~to~'#1'. }
+ \msg_warning:nnn { siunitx } { moved-cellspace-column } { C }
+ \ifcellspace@m
+ \def \env@matrix
+ {
+ \hskip -\arraycolsep
+ \let \@ifnextchar \new@ifnextchar
+ \array
+ {
+ * { \c@MaxMatrixCols }
+ { > { \bcolumn c \@nil $ } c < { $ \ecolumn } } @ { }
+ }
+ }
+ \fi
+ }
+ }
+ { }
+}
+% \end{macrocode}
+%
+%\begin{macro}{\@@_table_rewrite_create:N}
+%\begin{macro}{\@@_table_rewrite_create_aux:w}
+% The \texttt{s} and \texttt{S} column types are both created using
+% the \pkg{array} package, but with the internal macros redefined
+% to work with optional argument. First, there is a need to do a
+% quick shuffle with the \cs{NC@list} macro. The \pkg{siunitx}
+% columns have to be listed first, as otherwise the optional
+% arguments do not work correctly. So they are added \enquote{by hand}
+% to the appropriate macro.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_rewrite_create:N #1 {
+ \newcolumntype {#1} { }
+ \cs_set_protected:Npn
+ \@@_table_rewrite_create_aux:w \NC@do ##1##2 \NC@do #1
+ { \NC@list { \NC@do ##1 \NC@do #1 ##2 } }
+ \exp_after:wN \@@_table_rewrite_create_aux:w \tex_the:D \NC@list
+ \exp_args:NNc \renewcommand * { NC@rewrite@ #1 } [1] [ ]
+ {
+ \@temptokena \exp_after:wN
+ {
+ \tex_the:D \@temptokena
+ > { \@@_table_collect_begin:Nn #1 {##1} }
+ c
+ < { \@@_table_print: }
+ }
+ \NC@find
+ }
+}
+\AtBeginDocument
+ {
+ \@ifpackageloaded { mdwtab }
+ {
+ \cs_set_protected:Npn \@@_table_rewrite_create:N #1
+ {
+ \newcolumntype {#1} [1] []
+ {
+ > { \@@_table_collect_begin:Nn #1 {##1} }
+ c
+ < { \@@_table_print: }
+ }
+ }
+ }
+ { }
+ }
+\cs_new_protected:Npn \@@_table_rewrite_create_aux:w { }
+\AtBeginDocument { \@@_table_rewrite_create:N s }
+\AtBeginDocument { \@@_table_rewrite_create:N S }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\subsection{Collecting tokens in tables}
+%
+% The table system is in two parts, collecting tokens and typesetting
+% the result. The collection routine tries to ensure that the
+% typesetting part only receives real cell contents.
+%
+%\begin{macro}{\l_@@_table_collect_tl}
+%\begin{macro}{\l_@@_table_collect_pre_tl}
+%\begin{macro}{\l_@@_table_collect_post_tl}
+% Three storage areas.
+% \begin{macrocode}
+\tl_new:N \l_@@_table_collect_tl
+\tl_new:N \l_@@_table_collect_pre_tl
+\tl_new:N \l_@@_table_collect_post_tl
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_number_valid_tl}
+% As the \texttt{S} column has to make a judgement about tokens which
+% can be part of a number, there is a need to have a list of valid
+% tokens.
+% \begin{macrocode}
+\tl_new:N \l_@@_number_valid_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_table_math_bool}
+% A flag used inside the table cell to track math mode: there is
+% a need to do things by hand as otherwise the grouping goes
+% wrong.
+% \begin{macrocode}
+\bool_new:N \l_@@_table_math_bool
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_@@_table_collect_pre_bool}
+%\begin{macro}{\l_@@_table_collect_post_bool}
+% Flags for having found a number in an \texttt{S} column.
+% \begin{macrocode}
+\bool_new:N \l_@@_table_collect_pre_bool
+\bool_new:N \l_@@_table_collect_post_bool
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_begin:Nn}
+%\begin{macro}{\@@_table_collect_begin:Nw}
+%\begin{macro}{\@@_table_collect_begin_s:}
+%\begin{macro}{\@@_table_collect_begin_S:}
+% The collector starts by setting up local options, then clears and
+% initialises the storage and testing system. Font detection for the
+% \texttt{S} column happens here as this ensures that it is not inside
+% a box, which will give the wrong result for \opt{detect-mode}. The
+% |\use_i:nn| removes the |\ignorespaces| from the cell preamble.
+% In the basic \LaTeXe{} template there is only an |\ignorespaces|
+% before the content, but to deal with any other material we use
+% a delimited approach. It's important to grab everything up to the
+% end of the template-before-|#| to allow the Appendix~D trick to work
+% inside the |peek| code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_begin:Nn #1#2
+ {
+ \keys_set:nn { siunitx } {#2}
+ \@@_table_collect_begin:Nw #1
+ }
+\cs_new_protected:Npn \@@_table_collect_begin:Nw #1#2 \ignorespaces
+ { \use:c { @@_table_collect_begin_ #1 : } #2 }
+\cs_new_protected:Npn \@@_table_collect_begin_s: {
+ \cs_set_eq:NN \@@_table_collect_token:N
+ \@@_table_collect_token_s:N
+ \cs_set_eq:NN \@@_table_print: \@@_table_print_s:
+ \@@_table_collect_init_s:
+ \@@_table_collect_get:
+}
+\cs_new_protected:Npn \@@_table_collect_begin_S: {
+ \cs_set_eq:NN \@@_table_collect_token:N
+ \@@_table_collect_token_S:N
+ \cs_set_eq:NN \@@_table_print: \@@_table_print_S:
+ \@@_table_collect_init_S:
+ \@@_detect_font:
+ \bool_if:NTF \l_@@_number_parse_bool
+ { \@@_table_collect_get: }
+ { \@@_table_print_S_direct: }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_braced:n}
+% The collection of braced items depends on the column type. So we
+% start of with an empty definition.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_braced:n #1 { }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_expand:N}
+%\begin{macro}{\@@_table_collect_expand_math:N}
+% The idea here is to expand content if possible. There are a few
+% things to note. Only macros which are not long or protected are
+% expanded. There is the possibility that the macro may need the
+% contents of the pre-numeral part to be executed, for example see
+% \cref{tab:xmpl:calc} in the user part of the documentation.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_expand:N #1 {
+ \cs_if_eq:NNTF #1 \color
+ {
+ \bool_if:NTF \l_@@_table_collect_pre_bool
+ {
+ \tl_clear:N \l_@@_number_color_tl
+ \tl_clear:N \l_@@_unit_color_tl
+ \tl_put_right:Nn \l_@@_table_collect_pre_tl {#1}
+ }
+ {
+ \bool_set_true:N \l_@@_table_collect_post_bool
+ \tl_put_right:Nn \l_@@_table_collect_post_tl {#1}
+ }
+ }
+ {
+ \@@_cs_if_tl:NTF #1
+ {
+ \tl_use:N \l_@@_table_collect_pre_tl
+ \tl_clear:N \l_@@_table_collect_pre_tl
+ \cs_set:Npn \@@_table_collect_next:
+ { \exp_after:wN \@@_table_collect_get: #1 }
+ }
+ {
+ \bool_if:NTF \l_@@_table_collect_pre_bool
+ {
+ \tl_put_right:Nn \l_@@_table_collect_pre_tl {#1}
+ \@@_table_collect_expand_math:N #1
+ }
+ {
+ \bool_set_true:N \l_@@_table_collect_post_bool
+ \tl_put_right:Nn \l_@@_table_collect_post_tl {#1}
+ }
+ }
+ }
+}
+% \end{macrocode}
+% There is a need to keep a track of math mode, so that there are no
+% disasters when the tokens are boxed up later. The ideal is to know
+% the math state of the collected tokens so that appropriate
+% steps can be taken to insert math shift tokens later.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_expand_math:N #1 {
+ \token_if_math_toggle:NTF #1
+ {
+ \bool_if:NTF \l_@@_table_math_bool
+ { \bool_set_false:N \l_@@_table_math_bool }
+ { \bool_set_true:N \l_@@_table_math_bool }
+ }
+ {
+ \cs_if_eq:NNTF #1 \( % \)
+ { \bool_set_true:N \l_@@_table_math_bool }
+ { % \(
+ \cs_if_eq:NNT #1 \)
+ { \bool_set_false:N \l_@@_table_math_bool }
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_get:}
+% The token collection system first has to check that the next argument
+% does not start with an opening-brace character. If it does, the
+% testing is skipped and the braced token is stored. Otherwise, a check
+% is made against various ignored tokens.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_get:
+ {
+ \cs_set_eq:NN \@@_table_collect_next:
+ \@@_table_collect_get:
+ \peek_catcode_ignore_spaces:NTF \c_group_begin_token
+ { \@@_table_collect_braced:n }
+ { \@@_table_collect_not_braced:N }
+ }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_init:}
+% The usual spin-out of basics.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_init: {
+ \tl_clear:N \l_@@_table_collect_tl
+ \tl_clear:N \l_@@_table_collect_pre_tl
+ \tl_clear:N \l_@@_table_collect_post_tl
+ \bool_set_false:N \l_@@_table_collect_post_bool
+ \bool_set_false:N \l_@@_table_math_bool
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@@_table_collect_init_s:}
+%\begin{macro}{\@@_table_collect_init_S:}
+% Some type-specific definitions. In the \texttt{S} case, the
+% initialisation function for numbers is used to set
+% \cs{l_@@_number_valid_tl} correctly.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_init_s: {
+ \@@_table_collect_init:
+ \bool_set_false:N \l_@@_table_collect_pre_bool
+ \cs_set_protected:Npn \@@_table_collect_braced:n ##1
+ {
+ \tl_put_right:Nn \l_@@_table_collect_tl { {##1} }
+ \@@_table_collect_next:
+ }
+}
+\cs_new_protected:Npn \@@_table_collect_init_S: {
+ \@@_number_in_init:
+ \tl_set:Nx \l_@@_number_valid_tl
+ {
+ \exp_not:V \l_@@_input_complex_tl
+ \exp_not:V \l_@@_input_decimal_tl
+ \exp_not:V \l_@@_input_digit_tl
+ \exp_not:V \l_@@_input_exponent_tl
+ \exp_not:V \l_@@_input_ignore_tl
+ \exp_not:V \l_@@_input_comparator_tl
+ \exp_not:V \l_@@_input_uncert_close_tl
+ \exp_not:V \l_@@_input_uncert_open_tl
+ \exp_not:V \l_@@_input_sign_tl
+ \exp_not:V \l_@@_input_symbol_tl
+ }
+ \bool_set_true:N \l_@@_table_collect_pre_bool
+ \cs_set_protected:Npn \@@_table_collect_braced:n ##1
+ {
+ \bool_if:NTF \l_@@_table_collect_pre_bool
+ { \tl_put_right:Nn \l_@@_table_collect_pre_tl { {##1} } }
+ {
+ \bool_set_true:N \l_@@_table_collect_post_bool
+ \tl_put_right:Nn \l_@@_table_collect_post_tl { {##1} }
+ }
+ \@@_table_collect_next:
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_next:}
+% A holder for the next thing to do.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_next: { }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_newline:}
+% The end macro needs to come before the new line is called. The
+% print function is redefined so that it only actually does stuff once.
+% As each cell is a group anyway, there is no need to save the
+% definition of \cs{@@_table_print:}, as it will re-appear on its
+% own.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_newline: {
+ \@@_table_print:
+ \cs_set_eq:NN \@@_table_print: \prg_do_nothing:
+ \tabularnewline
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_end:}
+% The same concept applies to the \cs{end} macro.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_end: {
+ \@@_table_print:
+ \cs_set_eq:NN \@@_table_print: \prg_do_nothing:
+ \end
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_not_braced:N}
+%\begin{macro}{\@@_table_collect_not_braced_aux_i:N}
+%\begin{macro}{\@@_table_collect_not_braced_aux_ii:N}
+% A few macros are simply passed through to be executed; this is mainly
+% so that the table actually works. The newline function needs its own
+% function, which is picked up by hand.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_not_braced:N #1
+ {
+ \token_if_eq_meaning:NNF #1 \tex_ignorespaces:D
+ {
+ \token_if_eq_meaning:NNF #1 \tex_unskip:D
+ { \@@_table_collect_not_braced_aux_i:N #1 }
+ }
+ \@@_table_collect_next:
+ }
+\AtBeginDocument
+ {
+ \@ifpackageloaded { mdwtab }
+ {
+ \cs_set_protected:Npn \@@_table_collect_not_braced:N #1
+ {
+ \token_if_eq_meaning:NNF #1 \tex_ignorespaces:D
+ {
+ \token_if_eq_meaning:NNF #1 \tex_unskip:D
+ {
+ \token_if_eq_meaning:NNF #1 \tab@setcr
+ {
+ \token_if_eq_meaning:NNF #1 \@maybe@unskip
+ { \@@_table_collect_not_braced_aux_i:N #1 }
+ }
+ }
+ }
+ \@@_table_collect_next:
+ }
+ }
+ { }
+ }
+\cs_new_protected:Npn \@@_table_collect_not_braced_aux_i:N #1 {
+ \cs_set:Npn \@@_table_collect_not_braced_aux_ii:N ##1
+ {
+ \token_if_eq_meaning:NNT #1 ##1
+ { \cs_set_eq:NN \@@_table_collect_next: ##1 }
+ }
+ \tl_map_function:nN
+ { \cs:w \scan_stop: \@@_table_print: }
+ \@@_table_collect_not_braced_aux_ii:N
+ \token_if_eq_meaning:NNT \@@_table_collect_next:
+ \@@_table_collect_get:
+ {
+ \token_if_eq_meaning:NNTF #1 \tabularnewline
+ {
+ \cs_set_eq:NN \@@_table_collect_next:
+ \@@_table_collect_newline:
+ }
+ {
+ \token_if_eq_meaning:NNTF #1 \end
+ {
+ \cs_set_eq:NN \@@_table_collect_next:
+ \@@_table_collect_end:
+ }
+ { \@@_table_collect_token:N #1 }
+ }
+ }
+}
+\cs_new_protected:Npn \@@_table_collect_not_braced_aux_ii:N #1 { }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\@@_table_collect_token:N}
+%\begin{macro}{\@@_table_collect_token_s:N}
+% For the \texttt{s} column, every token is added to the same storage
+% area, so life is simple.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_token:N #1 { }
+\cs_new_protected:Npn \@@_table_collect_token_s:N #1 {
+ \tl_put_right:Nn \l_@@_table_collect_tl {#1}
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\begin{macro}{\@@_table_collect_token_S:N}
+% Not so easy for the \texttt{S} column type. If the content is after
+% a number, things are easy. On the other hand, if the token might be
+% a number, then a check is made. It the token is still unmatched, then
+% it is passed on to the expansion handler.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_collect_token_S:N #1 {
+ \bool_if:NTF \l_@@_table_collect_post_bool
+ { \tl_put_right:Nn \l_@@_table_collect_post_tl {#1} }
+ {
+ \tl_if_in:NnTF \l_@@_number_valid_tl {#1}
+ {
+ \bool_set_false:N \l_@@_table_collect_pre_bool
+ \tl_put_right:Nn \l_@@_table_collect_tl {#1}
+ }
+ { \@@_table_collect_expand:N #1 }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+% \subsection{Table printing: general code}
+%
+% 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{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
+ {
+ \@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: { } }
+ }
+% \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
+ {
+ \@@_table_colortbl_correction:
+ \skip_horizontal:n {#1}
+ \tex_kern:D \c_zero_skip
+ }
+\cs_new_protected:Npn \@@_table_align_right:n #1
+ {
+ \skip_horizontal:n { \c_@@_one_fill_skip - #1 }
+ \tex_kern:D \c_zero_skip
+ \@@_table_colortbl_correction:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_column_begin:}
+% \begin{macro}{\@@_table_column_end:}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_table_column_begin:n \@@_table_align_left:n
+\cs_new_eq:NN \@@_table_column_end:n \@@_table_align_right:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Setting up for a fixed column width is done so that the check is
+% made at the key-setting stage. In that way, there will be some
+% speed gained if the key is set before the table, as the comparison
+% is not made for every cell.
+% \begin{macrocode}
+\keys_define:nn { siunitx }
+ {
+ table-column-width .code:n =
+ {
+ \dim_compare:nNnTF {#1} = { \c_zero_dim }
+ {
+ \cs_set_eq:NN \@@_table_column_begin:n
+ \@@_table_align_left:n
+ \cs_set_eq:NN \@@_table_column_end:n
+ \@@_table_align_right:n
+ }
+ {
+ \cs_set_protected:Npn \@@_table_column_begin:n ##1
+ {
+ \@@_table_colortbl_correction:
+ \tex_hbox:D to \dim_eval:n {#1}
+ \c_group_begin_token
+ \skip_horizontal:n {##1}
+ \tex_kern:D \c_zero_skip
+ }
+ \cs_set_protected:Npn \@@_table_column_end:n ##1
+ {
+ \skip_horizontal:n { \c_@@_one_fill_skip - ##1 }
+ \tex_kern:D \c_zero_skip
+ \c_group_end_token
+ \@@_table_colortbl_correction:
+ }
+ }
+ }
+ }
+% \end{macrocode}
+%
+% \subsection{Printing units in \texttt{s} columns}
+%
+% The easiest type of printing is the \texttt{s} column. Here, there is
+% no real problem with alignment. All that has to happen is to print the
+% collected input as the argument to the internal part of an \cs{si}
+% function.
+%
+% \begin{variable}{\l_@@_table_unit_align_skip}
+% The spacing used is stored as a skip, which needs to be set up first.
+% \begin{macrocode}
+\skip_new:N \l_@@_table_unit_align_skip
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+\keys_define:nn { siunitx }
+ {
+ table-unit-alignment .choice:,
+ table-unit-alignment /
+ center .code:n =
+ {
+ \skip_set:Nn \l_@@_table_unit_align_skip
+ { 0pt plus 0.5fill }
+ },
+ table-unit-alignment /
+ left .code:n =
+ { \skip_set:Nn \l_@@_table_unit_align_skip { \c_zero_skip } },
+ table-unit-alignment /
+ right .code:n =
+ {
+ \skip_set:Nn \l_@@_table_unit_align_skip
+ { 0pt plus 1fill }
+ }
+ }
+\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.
+% \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 }
+ {
+ 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 =
+ {
+ \int_compare:nNnTF {#1} = 0
+ {
+ \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 }
+ {
+ \prop_put:Nnn \l_@@_table_model_prop { mantissa }
+ { true }
+ }
+ { \prop_remove:Nn \l_@@_table_model_prop { mantissa } }
+ }
+ {
+ \prop_put:Nnx \l_@@_table_model_prop { mantissa-decimal }
+ { \prg_replicate:nn {#1} { 8 } }
+ \prop_put:Nnn \l_@@_table_model_prop { mantissa-decimal-raw }
+ {#1}
+ \prop_put:Nnn \l_@@_table_model_prop { mantissa } { true }
+ \prop_put:NnV \l_@@_table_model_prop
+ { mantissa-decimal-marker } \l_@@_output_decimal_tl
+ }
+ },
+ table-figures-exponent .code:n =
+ {
+ \int_compare:nNnTF {#1} = 0
+ { \prop_remove:Nn \l_@@_table_model_prop { exponent-integer } }
+ {
+ \prop_put:Nnx \l_@@_table_model_prop { exponent-integer }
+ { \prg_replicate:nn {#1} { 8 } }
+ \prop_put:Nnn \l_@@_table_model_prop { exponent } { true }
+ }
+ },
+ table-figures-integer .code:n =
+ {
+ \int_compare:nNnTF {#1} = 0
+ {
+ \prop_remove:Nn \l_@@_table_model_prop { mantissa-integer }
+ \prop_if_in:NnTF \l_@@_table_model_prop { mantissa-decimal }
+ {
+ \prop_put:Nnn \l_@@_table_model_prop { mantissa }
+ { true }
+ }
+ { \prop_remove:Nn \l_@@_table_model_prop { mantissa } }
+ }
+ {
+ \prop_put:Nnx \l_@@_table_model_prop { mantissa-integer }
+ { \prg_replicate:nn {#1} { 8 } }
+ \prop_put:Nnn \l_@@_table_model_prop { mantissa } { true }
+ }
+ },
+ table-figures-uncertainty .code:n =
+ {
+ \int_compare:nNnTF {#1} = 0
+ { \prop_remove:Nn \l_@@_table_model_prop { mantissa-uncertainty } }
+ {
+ \prop_put:Nnx \l_@@_table_model_prop { mantissa-uncertainty }
+ { \prg_replicate:nn {#1} { 8 } }
+ }
+ },
+ table-parse-only .bool_set:N = \l_@@_table_parse_only_bool,
+ table-space-text-pre .tl_set:N = \l_@@_table_pre_tl,
+ table-space-text-post .tl_set:N = \l_@@_table_post_tl,
+ table-sign-exponent .choice:,
+ table-sign-exponent / true .code:n =
+ { \prop_put:Nnn \l_@@_table_model_prop { exponent-sign } { - } },
+ table-sign-exponent / false .code:n =
+ { \prop_remove:Nn \l_@@_table_model_prop { exponent-sign } },
+ table-sign-exponent .default:n = true,
+ table-sign-mantissa .choice:,
+ table-sign-mantissa / true .code:n =
+ { \prop_put:Nnn \l_@@_table_model_prop { mantissa-sign } { - } },
+ table-sign-mantissa / false .code:n =
+ { \prop_remove:Nn \l_@@_table_model_prop { mantissa-sign } },
+ table-sign-mantissa .default:n = true,
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% A meta-choice for all table alignment is also provided.
+% \begin{macrocode}
+\keys_define:nn { siunitx }
+ {
+ table-alignment .meta:n =
+ {
+ table-number-alignment = #1,
+ table-text-alignment = #1,
+ table-unit-alignment = #1
+ }
+ }
+% \end{macrocode}
+%
+% Another special option. This converts a number format in compacted
+% form into the various internal settings needed.
+% \begin{macrocode}
+\keys_define:nn { siunitx }
+ {
+ table-format .code:n =
+ {
+ \bool_set_eq:NN \l_@@_process_plus_saved_bool \l_@@_process_plus_bool
+ \bool_set_true:N \l_@@_process_plus_bool
+ \@@_number_in_parse:n {#1}
+ \prop_set_eq:NN \l_@@_table_model_prop \l_@@_number_in_prop
+ \tl_clear:N \l_@@_tmpa_tl
+ \prop_get:NnNT \l_@@_number_in_prop { mantissa-integer }
+ \l_@@_tmpb_tl
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ { table-figures-integer = \l_@@_tmpb_tl }
+ }
+ \prop_get:NnNT \l_@@_number_in_prop { mantissa-decimal }
+ \l_@@_tmpb_tl
+ {
+ \clist_put_right:Nx \l_@@_tmpa_tl
+ { table-figures-decimal = \l_@@_tmpb_tl }
+ }
+ \prop_get:NnNT \l_@@_number_in_prop { mantissa-uncertainty }
+ \l_@@_tmpb_tl
+ {
+ \clist_put_right:Nx \l_@@_tmpa_tl
+ { table-figures-uncertainty = \l_@@_tmpb_tl }
+ }
+ \prop_if_in:NnTF \l_@@_number_in_prop { mantissa-sign }
+ {
+ \clist_put_right:Nn \l_@@_tmpa_tl
+ { table-sign-mantissa =true }
+ }
+ {
+ \clist_put_right:Nn \l_@@_tmpa_tl
+ { table-sign-mantissa =false }
+ }
+ \prop_get:NnNT \l_@@_number_in_prop { exponent-integer }
+ \l_@@_tmpb_tl
+ {
+ \clist_put_right:Nx \l_@@_tmpa_tl
+ { table-figures-exponent = \l_@@_tmpb_tl }
+ }
+ \prop_if_in:NnTF \l_@@_number_in_prop { exponent-sign }
+ {
+ \clist_put_right:Nn \l_@@_tmpa_tl
+ { table-sign-exponent =true }
+ }
+ {
+ \clist_put_right:Nn \l_@@_tmpa_tl
+ { table-sign-exponent =false }
+ }
+ \clist_put_right:Nn \l_@@_tmpa_tl
+ { table-number-alignment = center }
+ \keys_set:nV { siunitx } \l_@@_tmpa_tl
+ \bool_set_eq:NN \l_@@_process_plus_bool \l_@@_process_plus_saved_bool
+ }
+ }
+\bool_new:N \l_@@_process_plus_saved_bool
+% \end{macrocode}
+%
+% \begin{macro}{\@@_table_print_S:}
+% The main printing function makes a choice depending on whether there is
+% any numerical part to print at all. This affects which set of skips to
+% insert. Font detection for the \texttt{S} column is included here as
+% this is needed to do this work outside of an \cs{hbox}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S:
+ {
+ \bool_if:NTF \l_@@_table_collect_pre_bool
+ {
+ \@@_table_column_begin:n { \l_@@_table_text_align_skip }
+ \l_@@_table_collect_pre_tl
+ \@@_table_column_end:n { \l_@@_table_text_align_skip }
+ }
+ {
+ \@@_table_column_begin:n { \l_@@_table_number_align_skip }
+ \bool_if:NTF \l_@@_table_parse_only_bool
+ { \@@_table_print_S_no_alignment: }
+ { \@@_table_print_S_alignment: }
+ \bool_if:NTF \l_@@_table_align_text_pre_bool
+ { \@@_table_print_S_pre_aligned: }
+ { \@@_table_print_S_pre_not_aligned: }
+ \box_use:N \l_@@_table_result_box
+ \bool_if:NTF \l_@@_table_align_text_post_bool
+ { \@@_table_print_S_post_aligned: }
+ { \@@_table_print_S_post_not_aligned: }
+ \@@_table_column_end:n { \l_@@_table_number_align_skip }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_no_alignment:}
+% With no alignment to do, the code can be pretty simple. The collected
+% number is simply printed between the two non-numerical parts.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_no_alignment:
+ {
+ \l_@@_table_collect_pre_tl
+ \@@_number_output:V \l_@@_table_collect_tl
+ \l_@@_table_collect_post_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_alignment:}
+% This is a pass-through, so that the appropriate alignment mode is
+% retained without needing to retest on each use.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_alignment:
+ { \@@_table_print_S_parsed: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_parse:}
+% A modified version of the number parser for tables.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_parse:
+ {
+ \bool_set_false:N \l_@@_error_bool
+ \@@_number_in_parse:V \l_@@_table_collect_tl
+ \bool_if:NF \l_@@_error_bool
+ {
+ \bool_if:NTF \l_@@_table_omit_exponent_bool
+ {
+ \bool_set_true:N \l_@@_process_fixed_bool
+ \@@_number_process:
+ \prop_remove:Nn \l_@@_number_in_prop { exponent }
+ \prop_remove:Nn \l_@@_number_in_prop { exponent-integer }
+ }
+ { \@@_number_process: }
+ \@@_number_format:
+ \@@_number_output_color:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_measure:NN}
+% A short routine to measure up whatever has been extracted from the
+% storage system. Boxing up is avoided for the empty cases, as this saves
+% a little time(the print routine is relatively slow).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_measure:NN #1#2
+ {
+ \tl_if_empty:NTF #1
+ { \dim_zero:N #2 }
+ {
+ \group_begin:
+ \hbox_set:Nn \l_@@_tmp_box
+ { \@@_print:nV { number } #1 }
+ \exp_args:NNNo \group_end:
+ \dim_set:Nn #2 { \dim_use:N \box_wd:N \l_@@_tmp_box }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_table_print_S_pre_aligned: ,
+% \@@_table_print_S_pre_not_aligned: ,
+% \@@_table_print_S_post_aligned: ,
+% \@@_table_print_S_post_not_aligned:
+% }
+% The non-numerical material is inserted along with the filler needed
+% to maintain alignment. The order in which the two are inserted depends
+% on whether those parts are also aligned.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_pre_aligned:
+ {
+ \box_use:N \l_@@_table_pre_box
+ \hbox_to_wd:nn { \l_@@_table_fill_pre_dim } { \tex_hfil:D }
+ }
+\cs_new_protected:Npn \@@_table_print_S_pre_not_aligned:
+ {
+ \hbox_to_wd:nn { \l_@@_table_fill_pre_dim } { \tex_hfil:D }
+ \box_use:N \l_@@_table_pre_box
+ }
+\cs_new_protected:Npn \@@_table_print_S_post_aligned:
+ {
+ \hbox_to_wd:nn { \l_@@_table_fill_post_dim } { \tex_hfil:D }
+ \box_use:N \l_@@_table_post_box
+ }
+\cs_new_protected:Npn \@@_table_print_S_post_not_aligned:
+ {
+ \box_use:N \l_@@_table_post_box
+ \hbox_to_wd:nn { \l_@@_table_fill_post_dim } { \tex_hfil:D }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Printing the \texttt{S} column with the decimal marker centred}
+%
+% \begin{macro}{\@@_table_print_S_centered:}
+% The main routine for decimal-centred alignment works by boxing up the
+% entire output, the integer part and the decimal marker. It then works
+% out which part is bigger and calculates the fill correction accordingly.
+% Once all of that is done, the various boxes and fill can be inserted.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_centered:
+ {
+ \@@_table_print_S_centered_ends:
+ \bool_if:NT \l_@@_table_math_bool { \c_math_toggle_token }
+ \@@_table_print_S_parse:
+ \bool_if:NF \l_@@_error_bool
+ {
+ \@@_table_print_S_centered_measure:
+ \bool_if:NT \l_@@_table_math_bool { \c_math_toggle_token }
+ \dim_set:Nn \l_@@_table_fill_pre_dim
+ {
+ \l_@@_table_result_dim
+ - \l_@@_table_integer_dim
+ - \l_@@_table_marker_dim
+ }
+ \dim_compare:nNnTF \l_@@_table_integer_dim >
+ \l_@@_table_fill_pre_dim
+ { \@@_table_print_S_centered_integer: }
+ { \@@_table_print_S_centered_decimal: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_centered_ends:}
+% To deal with the material outside of the number, the first step is to
+% box up both parts. If the pre-numeral part has no width, the tokens are
+% inserted into the input stream to cover cases where they make a change
+% to the colour, font or so forth. After that, the narrower of the two
+% boxes is made the same size as the wider: this maintains the alignment.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_centered_ends:
+ {
+ \hbox_set:Nn \l_@@_table_pre_box
+ {
+ {
+ \l_@@_table_collect_pre_tl
+ \bool_if:NT \l_@@_table_math_bool
+ {
+ \scan_stop:
+ \c_math_toggle_token
+ }
+ }
+ }
+ \dim_compare:nNnT
+ { \box_wd:N \l_@@_table_pre_box } = \c_zero_dim
+ {
+ \box_clear:N \l_@@_table_pre_box
+ \l_@@_table_collect_pre_tl
+ \bool_set_false:N \l_@@_font_set_bool
+ }
+ \hbox_set:Nn \l_@@_table_post_box
+ {
+ \bool_if:NT \l_@@_table_math_bool
+ {
+ \c_math_toggle_token
+ \scan_stop:
+ }
+ \l_@@_table_collect_post_tl
+ }
+ \dim_compare:nNnTF
+ { \box_wd:N \l_@@_table_pre_box } >
+ { \box_wd:N \l_@@_table_post_box }
+ {
+ \hbox_set_to_wd:Nnn \l_@@_table_post_box
+ { \box_wd:N \l_@@_table_pre_box }
+ {
+ \hbox_unpack:N \l_@@_table_post_box
+ \tex_hfil:D
+ }
+ }
+ {
+ \hbox_set_to_wd:Nnn \l_@@_table_pre_box
+ { \box_wd:N \l_@@_table_post_box }
+ {
+ \tex_hfil:D
+ \hbox_unpack:N \l_@@_table_pre_box
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_centered_measure:}
+% \begin{macro}
+% {
+% \@@_table_print_S_centered_measure_int_part: ,
+% \@@_table_print_S_centered_measure_marker: ,
+% \@@_table_print_S_centered_measure_result:
+% }
+% Here, there are three parts of the number to measure: the integer part,
+% the decimal marker and the entire number. Most of the work consists
+% of collecting up parts of the number.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_centered_measure:
+ {
+ \@@_table_print_S_centered_measure_int_part:
+ \@@_table_print_S_centered_measure_marker:
+ \@@_table_print_S_centered_measure_result:
+ }
+\cs_new_protected:Npn \@@_table_print_S_centered_measure_int_part:
+ {
+ \prop_get:NnNF \l_@@_number_out_prop { comparator } \l_@@_tmpa_tl
+ { \tl_clear:N \l_@@_tmpa_tl }
+ \prop_get:NnNT \l_@@_number_out_prop { mantissa-sign }
+ \l_@@_tmpb_tl
+ { \tl_put_right:No \l_@@_tmpa_tl \l_@@_tmpb_tl }
+ \prop_get:NnNT \l_@@_number_out_prop { mantissa-integer }
+ \l_@@_tmpb_tl
+ { \tl_put_right:No \l_@@_tmpa_tl \l_@@_tmpb_tl }
+ \@@_table_print_S_measure:NN \l_@@_tmpa_tl
+ \l_@@_table_integer_dim
+ }
+\cs_new_protected:Npn \@@_table_print_S_centered_measure_marker:
+ {
+ \@@_table_print_S_measure:NN \l_@@_output_decimal_tl
+ \l_@@_table_marker_dim
+ }
+% \end{macrocode}
+% As the overall result will be needed later, the boxing up here is done
+% using a named box that will be retained.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_centered_measure_result:
+ {
+ \prop_get:NnN \l_@@_number_out_prop { result } \l_@@_tmpa_tl
+ \hbox_set:Nn \l_@@_table_result_box
+ { \@@_print:nV { number } \l_@@_tmpa_tl }
+ \dim_set:Nn \l_@@_table_result_dim
+ { \box_wd:N \l_@@_table_result_box }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_table_print_S_centered_integer: ,
+% \@@_table_print_S_centered_decimal:
+% }
+% The appropriate place to insert the fill is determined by whether the
+% integer or decimal part of the number is bigger. Two dimensions are
+% therefore set, for fill before the number and after it. One of these
+% will always be zero.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_centered_integer:
+ {
+ \dim_set:Nn \l_@@_table_fill_post_dim
+ { \l_@@_table_integer_dim - \l_@@_table_fill_pre_dim }
+ \dim_zero:N \l_@@_table_fill_pre_dim
+ }
+\cs_new_protected:Npn \@@_table_print_S_centered_decimal:
+ {
+ \dim_sub:Nn \l_@@_table_fill_pre_dim
+ { \l_@@_table_integer_dim }
+ \dim_zero:N \l_@@_table_fill_post_dim
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Printing the \texttt{S} column with space reserved}
+%
+% \begin{macro}{\@@_table_print_S_reserved:}
+% The procedure for inserting a number with space reserved requires a model
+% for each part of the number.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_reserved:
+ {
+ \@@_table_print_S_reserved_init:
+ \@@_table_print_S_reserved_ends:
+ \bool_if:NT \l_@@_table_auto_round_bool
+ { \@@_table_print_S_reserved_round_auto: }
+ \@@_table_print_S_parse:
+ \bool_if:NF \l_@@_error_bool
+ {
+ \bool_if:NT \l_@@_table_math_bool { \c_math_toggle_token }
+ \@@_table_print_S_reserved_comparator:
+ \@@_table_print_S_reserved_mantissa:
+ \@@_table_print_S_reserved_exponent:
+ \bool_if:NT \l_@@_table_math_bool { \c_math_toggle_token }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_reserved_init:}
+% The creation of a model for the cell to follow. Creation of the finalised
+% model is done here so that all of the other options will apply without
+% needing complex internal tracking.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_reserved_init:
+ {
+ \dim_zero:N \l_@@_table_fill_mid_dim
+ \dim_zero:N \l_@@_table_fill_post_dim
+ \prop_set_eq:NN \l_@@_number_in_prop \l_@@_table_model_prop
+ \@@_number_process_sign:
+ \@@_number_process_zero_fill:
+ \@@_number_process_mantissa:
+ \prop_if_in:NnF \l_@@_number_in_prop { symbolic }
+ { \@@_number_process_uncertainty: }
+ \@@_number_format:
+ \prop_get:NnNT \l_@@_table_model_prop { mantissa-decimal-raw }
+ \l_@@_tmpa_tl
+ {
+ \prop_put:NnV \l_@@_number_out_prop { mantissa-decimal-raw }
+ \l_@@_tmpa_tl
+ }
+ \prop_set_eq:NN \l_@@_table_model_prop \l_@@_number_out_prop
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_reserved_ends:}
+% The end material here is boxed up into the space already reserved.
+% That means doing two boxing ups: one for the model, and one for the
+% real thing. As in the centred case, if the pre-numeral part has no
+% width then the tokens are inserted \enquote{as is}. To avoid any issues
+% with people forgetting to reserve space for the pre-numeral part, it is
+% boxed up first at natural width so that the measurement is accurate.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_reserved_ends:
+ {
+ \hbox_set:Nn \l_@@_table_pre_box
+ {
+ {
+ \l_@@_table_collect_pre_tl
+ \bool_if:NT \l_@@_table_math_bool
+ {
+ \scan_stop:
+ \c_math_toggle_token
+ }
+ }
+ }
+ \dim_compare:nNnT
+ { \box_wd:N \l_@@_table_pre_box } = \c_zero_dim
+ {
+ \box_clear:N \l_@@_table_pre_box
+ \l_@@_table_collect_pre_tl
+ \bool_set_false:N \l_@@_font_set_bool
+ }
+ \hbox_set:Nn \l_@@_tmp_box { { \l_@@_table_pre_tl } }
+ \hbox_set_to_wd:Nnn \l_@@_table_pre_box
+ { \box_wd:N \l_@@_tmp_box }
+ {
+ \tex_hfil:D
+ \hbox_unpack:N \l_@@_table_pre_box
+ }
+ \hbox_set:Nn \l_@@_tmp_box { \l_@@_table_post_tl }
+ \hbox_set_to_wd:Nnn \l_@@_table_post_box
+ { \box_wd:N \l_@@_tmp_box }
+ {
+ {
+ \bool_if:NT \l_@@_table_math_bool
+ {
+ \c_math_toggle_token
+ \scan_stop:
+ }
+ \l_@@_table_collect_post_tl
+ }
+ \tex_hfil:D
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_reserved_round_auto:}
+% For auto-rounding, the approach is to find how many decimal digits are
+% allowed for, and if there are none to simply set the rounding value to
+% zero.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_reserved_round_auto:
+ {
+ \prop_get:NnNTF \l_@@_table_model_prop { mantissa-decimal-raw }
+ \l_@@_tmpa_tl
+ { \int_set:Nn \l_@@_process_precision_int { \l_@@_tmpa_tl } }
+ { \int_zero:N \l_@@_process_precision_int }
+ \tl_set:Nn \l_@@_round_tl { places }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_reserved_comparator:}
+% The comparator is quite simple to deal with. Assuming that there is a
+% comparator in the model, this is measured for the reserved width. The
+% real comparator can then simply be typeset in a box of the same size.
+% If there is no comparator in the real case, then the space added to
+% that for filling: this is needed so that any pre-note can be aligned
+% freely.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_reserved_comparator:
+ {
+ \prop_get:NnNTF \l_@@_table_model_prop { comparator }
+ \l_@@_tmpa_tl
+ {
+ \hbox_set:Nn \l_@@_tmp_box
+ { \@@_print:nV { number } \l_@@_tmpa_tl }
+ \prop_get:NnNTF \l_@@_number_out_prop { comparator }
+ \l_@@_tmpa_tl
+ {
+ \hbox_set_to_wd:Nnn \l_@@_table_result_box
+ { \box_wd:N \l_@@_tmp_box }
+ { \@@_print:nV { number } \l_@@_tmpa_tl }
+ }
+ {
+ \dim_add:Nn \l_@@_table_fill_pre_dim
+ { \box_wd:N \l_@@_tmp_box }
+ \cs_set_eq:NN \@@_table_print_S_reserved_store_fill:n
+ \@@_table_print_S_reserved_store_fill_pre:n
+ }
+ }
+ {
+ \cs_set_eq:NN \@@_table_print_S_reserved_store_fill:n
+ \@@_table_print_S_reserved_store_fill_pre:n
+ \prop_if_in:NnT \l_@@_number_out_prop { comparator }
+ {
+ \msg_error:nnx { siunitx } { table-partial-number }
+ { a~comparator }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_table_print_S_reserved_store_fill_pre:n ,
+% \@@_table_print_S_reserved_store_fill_mid:n
+% }
+% To allow for the various alignment options, fill is stored in a
+% flexible way.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_table_print_S_reserved_store_fill_pre:n
+ { \dim_add:Nn \l_@@_table_fill_pre_dim }
+\cs_new_protected:Npn \@@_table_print_S_reserved_store_fill_mid:n
+ { \dim_add:Nn \l_@@_table_fill_mid_dim }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_table_print_S_reserved_mantissa:}
+% \begin{macro}
+% {
+% \@@_table_print_S_reserved_mantissa_parts: ,
+% \@@_table_print_S_reserved_mantissa_integer:
+% }
+% The mantissa of a number may contain a sign, an integer part, a
+% decimal marker, a decimal part and a non-separated uncertainty. That
+% means that there are two ways to deal with the alignment. Each part
+% could be done separately, or a correction can be made after setting
+% the combined mantissa. Here, the later approach is taken. The first
+% step is to deal with the mantissa as a whole: work out show much space
+% to reserve, and see if there is anything at all to put in it. The
+% complexity only starts if there is a mantissa in the current cell.
+% \begin{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 }
+ }
+ }
+ }
+% \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 { textcomp }
+ {
+ \@@_option_unchanged:Nnn \l_@@_degree_math_tl
+ { { } ^ { \circ } }
+ { \text { \textdegree } }
+ \@@_option_unchanged:Nnn \l_@@_degree_text_tl
+ { \ensuremath { { } ^ { \circ } } }
+ { \textdegree }
+ \@ifpackageloaded { mathptmx }
+ { }
+ {
+ \@@_option_unchanged:Nnn \l_@@_micro_text_tl
+ { \c_@@_mu_tl }
+ { \textmu }
+ \@ifpackageloaded { fourier }
+ { }
+ {
+ \@@_option_unchanged:Nnn \l_@@_ohm_text_tl
+ { \ensuremath { \g_@@_omega_tl } }
+ { \textohm }
+ }
+ }
+ \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 { upgreek }
+ {
+ \@@_option_unchanged:Nnn \l_@@_ohm_math_tl
+ { \text { \ensuremath { \g_@@_omega_tl } } }
+ { \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 = { } ^ { \circ } \kern - \scriptspace \@@_unit_mathrm:n { C } ,
+ math-degree = { } ^ { \circ },
+ math-micro = \text { \c_@@_mu_tl },
+ math-ohm = \text { \ensuremath { \g_@@_omega_tl } },
+}
+% \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 =
+ \ensuremath { { } ^ { \circ } } \kern -\scriptspace C ,
+ text-degree = \ensuremath { { } ^ { \circ } },
+ text-micro = \c_@@_mu_tl ,
+ text-ohm = \ensuremath { \g_@@_omega_tl },
+}
+% \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_fold_case: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}
+%
+% \begin{variable}
+% {
+% \c_@@_degree_int ,
+% \c_@@_micro_int ,
+% \c_@@_angstrom_int ,
+% \c_@@_ohm_int ,
+% \c_@@_arcminute_int,
+% \c_@@_arcsecond_int
+% }
+% For UTF-8 engines, it may be possible to use better symbols than those set
+% up as standard. Unicode normalises both the ohm and {\aa}ngstr{\"{o}}m
+% symbols to the appropriate letters, so these are used directly.
+% Technically, we should hae a different slot for micro than for a mu, but
+% for the broadest compatibility we go with the latter.
+% The single degree Celsius symbol is a compatibility character, and so
+% the two separate glyphs \enquote{degree} and \enquote{C} are used.
+% \begin{macrocode}
+\AtBeginDocument
+ {
+ \@ifpackageloaded { fontspec }
+ {
+ \int_const:Nn \c_@@_degree_int { 176 }
+ \int_const:Nn \c_@@_micro_int { "000B5 }
+ \int_const:Nn \c_@@_angstrom_int { "0212B }
+ \int_const:Nn \c_@@_ohm_int { "003A9 }
+ \sys_if_engine_xetex:T
+ {
+ \@@_option_unchanged:Nnn \l_@@_angstrom_math_tl
+ { \text { \AA } }
+ { \tex_char:D \c_@@_angstrom_int }
+ }
+ \@@_option_unchanged:Nnn \l_@@_celsius_math_tl
+ { { } ^ { \circ } \kern - \scriptspace C }
+ {
+ \tex_char:D \c_@@_degree_int
+ C
+ }
+ \@@_option_unchanged:Nnn \l_@@_degree_math_tl
+ { { } ^ { \circ } }
+ { \tex_char:D \c_@@_degree_int }
+ \@@_option_unchanged:Nnn \l_@@_micro_math_tl
+ { \text { \c_@@_mu_tl } }
+ { \tex_char:D \c_@@_micro_int }
+ \@@_option_unchanged:Nnn \l_@@_ohm_math_tl
+ { \text { \ensuremath { \g_@@_omega_tl } } }
+ { \tex_char:D \c_@@_ohm_int }
+ \sys_if_engine_xetex:T
+ {
+ \@@_option_unchanged:Nnn \l_@@_angstrom_text_tl
+ { \AA }
+ { \tex_char:D \c_@@_angstrom_int }
+ }
+ \@@_option_unchanged:Nnn \l_@@_celsius_text_tl
+ {
+ \ensuremath
+ { { } ^ { \circ } \kern - \scriptspace C }
+ }
+ {
+ \tex_char:D \c_@@_degree_int
+ C
+ }
+ \@@_option_unchanged:Nnn \l_@@_degree_text_tl
+ { \ensuremath { { } ^ { \circ } } }
+ { \tex_char:D \c_@@_degree_int }
+ \@@_option_unchanged:Nnn \l_@@_micro_text_tl
+ { \c_@@_mu_tl }
+ { \tex_char:D \c_@@_micro_int }
+ \@@_option_unchanged:Nnn \l_@@_ohm_text_tl
+ { \ensuremath { \g_@@_omega_tl } }
+ { \tex_char:D \c_@@_ohm_int }
+ }
+ { }
+% \end{macrocode}
+% Slightly more specialised: these only work in math mode with
+% \pkg{unicode-math}.
+% \begin{macrocode}
+ \@ifpackageloaded { unicode-math }
+ {
+ \int_const:Nn \c_@@_arcminute_int { 8242 }
+ \int_const:Nn \c_@@_arcsecond_int { 8243 }
+ \@@_option_unchanged:Nnn \l_@@_arcminute_math_tl
+ { { } ^ { \prime } }
+ { \ensuremath { \tex_char:D \c_@@_arcminute_int } }
+ \@@_option_unchanged:Nnn \l_@@_arcsecond_math_tl
+ { { } ^ { \prime \prime } }
+ { \ensuremath { \tex_char:D \c_@@_arcsecond_int } }
+ \@@_option_unchanged:Nnn \l_@@_arcminute_text_tl
+ { \ensuremath { { } ^ { \prime } } }
+ { \ensuremath { \tex_char:D \c_@@_arcminute_int } }
+ \@@_option_unchanged:Nnn \l_@@_arcsecond_text_tl
+ { \ensuremath { { } ^ { \prime \prime } } }
+ { \ensuremath { \tex_char:D \c_@@_arcsecond_int } }
+ }
+ { }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+%\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_add:N}
+% An updated version of \cs{addtocontents} which will ensure that
+% everything works properly. Using \cs{token_to_str:N} means that
+% there is no problem with the asynchronous nature of \TeX{}'s writing
+% mechanism.
+% \begin{macrocode}
+\AtBeginDocument
+ {
+ \cs_set:Npn \addtocontents #1#2
+ {
+ \protected@write \@auxout
+ {
+ \cs_set_eq:NN \label \use_none:n
+ \cs_set_eq:NN \index \use_none:n
+ \cs_set_eq:NN \glossary \use_none:n
+ \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq
+ { \@@_contents_add:N ##1 }
+ }
+ { \token_to_str:N \@writefile {#1} {#2} }
+ }
+ }
+\cs_new_protected:Npn \@@_contents_add:N #1
+ {
+ \cs_set:Npn #1
+ {
+ \token_to_str:N #1
+ \c_space_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_contents_bookmarks:}
+% The idea here is two-fold. First, all of the unit macros are set
+% up to simply print their literal interpretation: this is hopefully
+% good enough for most bookmark situations. Secondly, the document
+% commands are made expandable. This allows a bit of re-arrangement
+% of the input, removes any set up options (which are being ignored)
+% and stops \pkg{hyperref} issuing a warning.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_contents_bookmarks:
+ {
+ \seq_map_inline:Nn \l_siunitx_unit_symbolic_seq
+ { \@@_unit_print_literal_aux:N ##1 }
+ \cs_if_exist:NT \FB@fg
+ { \cs_set_eq:NN \fg \FB@fg }
+ \msg_redirect_name:nnn { xparse } { redefine-command } { none }
+ \cs_set_eq:NN \num \numInBookmark
+ \cs_set_eq:NN \numrange \numrangeInBookmark
+ \cs_set_eq:NN \si \siInBookmark
+ \cs_set_eq:NN \SI \SIInBookmark
+ \cs_set_eq:NN \SIrange \SIrangeInBookmark
+ \cs_set_eq:NN \si \siInBookmark
+ \cs_set_eq:NN \highlight \use_ii:nn
+ \cs_set_eq:NN \@@_textsuperscript:n \use:n
+ \cs_set:Npn \SIUnitSymbolAngstrom { \AA }
+ \cs_set:Npn \SIUnitSymbolArcminute { ' }
+ \cs_set:Npn \SIUnitSymbolArcsecond { '' }
+ \cs_set:Npn \SIUnitSymbolCelsius { \textcelsius }
+ \cs_set:Npn \SIUnitSymbolDegree { \textdegree }
+ \cs_set:Npn \SIUnitSymbolMicro { \textmu }
+ \cs_set:Npn \SIUnitSymbolOhm { [ohm] }
+ }
+% \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} {2017/11/26} {2.7k}
+ {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,
+ },
+ repeatunits /
+ power .meta:n =
+ {
+ multi-part-units = repeat,
+ product-units = power,
+ },
+ repeatunits /
+ true .meta:n =
+ {
+ multi-part-units = repeat,
+ product-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} {2017/11/26} {2.7k}
+ {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} {2017/11/26} {2.7k}
+ {siunitx: Binary units}
+% \end{macrocode}
+%
+% \begin{macro}{\kibi, \mebi, \gibi, \tebi, \pebi, \exbi, \zebi, \yobi}
+% The binary units as specified by the IEC.
+% \begin{macrocode}
+\DeclareBinaryPrefix \kibi { Ki } { 10 }
+\DeclareBinaryPrefix \mebi { Mi } { 20 }
+\DeclareBinaryPrefix \gibi { Gi } { 30 }
+\DeclareBinaryPrefix \tebi { Ti } { 40 }
+\DeclareBinaryPrefix \pebi { Pi } { 50 }
+\DeclareBinaryPrefix \exbi { Ei } { 60 }
+\DeclareBinaryPrefix \zebi { Zi } { 70 }
+\DeclareBinaryPrefix \yobi { Yi } { 80 }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\bit, \byte}
+% Now the units.
+% \begin{macrocode}
+\DeclareSIUnit \bit { bit }
+\DeclareSIUnit \byte { B }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</binary>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \begin{thebibliography}{1}
+%
+% \bibitem{BIPM}
+% \emph{The International System of Units (SI)},
+% \url{http://www.bipm.org/en/measurement-units/}.
+%
+% \bibitem{NIST}
+% \emph{International System of Units from NIST},
+% \url{http://physics.nist.gov/cuu/Units/index.html}.
+%
+% \bibitem{SI:2.1}
+% \emph{SI base units},
+% \url{http://www.bipm.org/en/publications/si-brochure/section2-1.html}.
+%
+% \bibitem{SI:2.2.2}
+% \emph{Units with special names and symbols; units that
+% incorporate special names and symbols},
+% \url{http://www.bipm.org/en/publications/si-brochure/section2-2-2.html}.
+%
+% \bibitem{SI:3.1}
+% \emph{SI Prefixes},
+% \url{http://www.bipm.org/en/publications/si-brochure/chapter3.html}.
+%
+% \bibitem{SI:4.1.T6}
+% \emph{Non-SI units accepted for use with the International
+% System of Units},
+% \url{http://www.bipm.org/en/publications/si-brochure/table6.html}.
+%
+% \bibitem{SI:4.1.T7}
+% \emph{Non-SI units whose values in SI units must be obtained
+% experimentally},
+% \url{http://www.bipm.org/en/publications/si-brochure/table7.html}.
+%
+% \bibitem{SI:4.1.T8}
+% \emph{Other non-SI units},
+% \url{http://www.bipm.org/en/publications/si-brochure/table8.html}.
+%
+% \bibitem{SI:5.3.3}
+% \emph{Formatting the value of a quantity},
+% \url{http://www.bipm.org/en/publications/si-brochure/section5-3-3.html}.
+%
+% \end{thebibliography}
+%
+% \PrintChanges
+%
+% \newpage
+%
+% \PrintIndex
diff --git a/macros/latex/contrib/siunitx/siunitx.pdf b/macros/latex/contrib/siunitx/siunitx.pdf
new file mode 100644
index 0000000000..6bd27ee216
--- /dev/null
+++ b/macros/latex/contrib/siunitx/siunitx.pdf
Binary files differ