% \iffalse meta-comment % !TEX program = pdflatex % !TEX encoding = ISO-8859-1 %<*internal> \iffalse % %<*readme> ---------------------------------------------------------------- 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 ---------------------------------------------------------------- Typesetting values with units requires care to ensure that the combined mathematical meaning of the value plus 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 numbers and units 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. A number of LaTeX packages have been developed in the past for formatting units: SIunits, sistyle, unitsdef, units, fancyunits and fancynum. Support for users of all of these packages is available as emulation modules in siunitx. In addition, siunitx can carry out many of the functions of the dcolumn, rccol and numprint packages % %<*internal> \fi \def\nameofplainTeX{plain} \ifx\fmtname\nameofplainTeX\else \expandafter\begingroup \fi % %<*install> \input docstrip.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-2009 by Joseph Wright It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this license or (at your option) any later version. The latest version of this license is in the file: 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}} } % %\endbatchfile %<*internal> \usedir{source/latex/siunitx} \generate{ \file{\jobname.ins}{\from{\jobname.dtx}{install}} } \nopreamble\nopostamble \usedir{doc/latex/siunitx} \generate{ \file{README.txt}{\from{\jobname.dtx}{readme}} } \ifx\fmtname\nameofplainTeX \expandafter\endbatchfile \else \expandafter\endgroup \fi \immediate\write18{makeindex -s gglo.ist -o siunitx.gls siunitx.glo} \immediate\write18{makeindex -s l3doc.ist -o siunitx.ind siunitx.idx} % %<*package> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{siunitx} [2009/03/29 v2.0alpha A comprehensive (SI) units package] % %<*driver> \documentclass[full]{l3doc} \usepackage[osf]{mathpazo} \usepackage[scaled=0.95]{helvet} \usepackage[final]{listings,microtype} \usepackage{booktabs,caption} \renewcommand*{\MakePrivateLetters}{% \makeatletter } \EnableCrossrefs \CodelineIndex \RecordChanges \usepackage{\jobname} \DeclareSIQualifier{\product}{prod} \DeclareSIQualifier{\catalyst}{cat} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % %\CheckSum{0} % %\GetFileInfo{\jobname.sty} % %\makeatletter % %^^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 %}{^^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 = { % DeclareSIPrefix, % DeclareSIPower, % DeclareSIQualifier, % DeclareSIUnit, % mathnormal, % num, % si, % SI, % sisetup, % text, % } % }^^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 only}{^^A % \LaTeXdemo@common %}{^^A %} % %^^A Some short cuts for the tables % %\newcommand*{\DescribeUnit}[1]{^^A % \expandafter\SpecialUsageIndex\expandafter{\csname #1\endcsname} ^^A % #1 & % \cs{#1} & % \expandafter\si\expandafter{\csname #1\endcsname} %} %\newcommand*{\DescribePrefix}[1]{^^A % \expandafter\SpecialUsageIndex\expandafter{\csname #1\endcsname} ^^A % #1 & % \cs{#1} & % \expandafter\csname si@unit@literal@\expandafter\string\csname % #1\endcsname\endcsname & % \num{e\expandafter\csname si@unit@number@\expandafter\string\csname % #1\endcsname\endcsname} %} % %\providecommand*{\pkg}{\textsf} %\providecommand*{\opt}{\texttt} % %\makeatother % %\title{^^A % \textsf{siunitx} --- A comprehensive (SI) units package\thanks{^^A % This file describes version \fileversion, last revised % \filedate.^^A % }^^A %} %\author{^^A % Joseph Wright\thanks{E-mail: joseph.wright@morningstar2.co.uk}^^A %} %\date{Released \filedate} % %\maketitle % %\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{v2.0}{2008/03/29}{Complete re-write of package to add many new % features} % %\begin{abstract} % Typesetting values with units requires care to ensure that the % combined mathematical meaning of the value plus 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 numbers and units 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. % % A number of \LaTeX\ packages have been developed in the past for % formatting units: \pkg{SIunits}, \pkg{SIstyle}, % \pkg{unitsdef}, \pkg{units}, \pkg{fancyunits} and % \pkg{fancynum}. Support for users of all of these packages is % available as emulation modules in \pkg{siunitx}. In addition, % \pkg{siunitx} can carry out many of the functions of the % \pkg{dcolumn}, \pkg{rccol} and \pkg{numprint} packages. %\end{abstract} % %\begin{multicols}{2} % \tableofcontents %\end{multicols} % %\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}\footnote{General Conference on Weights and Measures.} % (CGPM): this has resulted in the \emph{Syst\`eme International % d'Unit\'es}\footnote{International System of Units.} (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 units and values 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. % % \pkg{siunitx} is intended as a complete replacement for % \pkg{SIunits}, \pkg{SIstyle}, \pkg{unitsdef}, \pkg{units}, % \pkg{fancyunits} and \pkg{fancynum}. As such, emulation modes % are provided for all of these packages. Where possible, conventions % from the existing solutions have been used here. For example, the % macros \cs{num}, \cs{ang} and \cs{SI} act in a very similar fashion % to those in existing packages. % %\section{Installation} % % The entire bundle is supplied with the TDS-ready \texttt{zip} file, % \texttt{siunitx.tds.zip}. Simply unzip this into your local texmf % tree and run your hash program (\texttt{texhash} for \TeX{}Live or % \texttt{initextmf -u} for MiK\TeX). % % To extract the package \texttt{siunitx.sty} and the % configuration files from \texttt{siunitx.dtx}, two methods are % available. To extract the files using the \texttt{ins} file, % simply run (pdf)\TeX\ on \texttt{siunitx.ins}. This will produce all % of the package files, and also \texttt{README.txt}. To extract the % files and build the documentation, run (pdf)\LaTeX\ on % \texttt{siunitx.dtx}. Three (pdf)\LaTeX\ runs with \cs{write18} % enabled will also build the index and table of contents in the PDF. % % Compilation of the package documentation requires the \pkg{l3doc} % class, from the \pkg{expl3} bundle produced by the \LaTeX3 team. % To compile the package documentation, you will need to get a recent % version of \pkg{expl3} from the % \href{http://www.latex-project.org/code.html}{\LaTeX\ project % website}. % %\section{\pkg{siunitx} for the impatient} % % The package provides the user macros: %\begin{itemize} % \item \cs{SI}\oarg{options}\marg{value}\oarg{pre-unit}\marg{unit} % \item \cs{si}\oarg{options}\marg{unit} % \item \cs{num}\oarg{options}\marg{number} % \item \cs{ang}\oarg{options}\marg{angle} % \item \cs{sisetup}\marg{options} %\end{itemize} % plus the \texttt{S} and \texttt{s} column types for decimal % alignments and units in tables. These macros are designed for % typesetting units and values with control of appearance and with % intelligent processing. %\begin{LaTeXdemo} % \num{12345,67890} \\ % \num{1+-2i} \\ % \num{.3e45} %\end{LaTeXdemo} % % By default, all text is typeset in the current upright, serif maths % font. This can be changed by setting the appropriate options: % |\sisetup{font/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 package does not use load-time options, although it does % support those from version 1 of the package and predecessor packages. % %\subsection{Numbers} % %\DescribeMacro{\num} % Numbers are automatically formatted by the \cs{num} macro. This % takes one optional and one mandatory argument: % \cs{num}\oarg{options}\marg{number}. The contents of \m{number} % are automatically formatted. The formatter removes ``hard'' spaces % (\cs{,} and |~|), automatically identifies exponents (by default % marked using \texttt{e} or \texttt{d}) and adds the appropriate % spacing of large numbers. A leading zero is added before a decimal % marker, if needed: both ``\texttt{.}'' and ``\texttt{,}'' are % recognised as decimal marker. %\begin{LaTeXdemo} % \num{123} \\ % \num{1234} \\ % \num{12345} \\ % \num{0.123} \\ % \num{0,1234} \\ % \num{.12345} \\ % \num{3.45d-4} \\ % \num{-e10} %\end{LaTeXdemo} % %\subsection{Units: as arguments} % %\DescribeMacro{\si} % 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: \cs{si}\oarg{options}\marg{unit}. The unit formatting system % can accept two types of input. When \m{unit} contains one or more % literal items, the output is processed in the same manner as with the % \pkg{sistyle} package. Sub- and superscripts can be input without % concern over maths mode, and the tokens \texttt{.} and |~| are % converted into an inter-unit separator and inter-unit space, % respectively.\footnote{The standard package settings use the same % value for both of these: \cs{,}.} %\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 ``interpretted'' % 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 % 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 values, new % functionality is made available. Units may be re-defined to give % different output, and handling of reciprocal values can be altered. % %\DescribeMacro{\SI} % Very often, numbers and values are given together. Mathematically, % these form a single entity, and should be separated by a non-breaking % space. The \cs{SI} macro combines the functionality of \cs{num} and % \cs{si}, and makes this both possible and easy. The \cs{SI} macro takes % two mandatory arguments, in addition to the optional set up argument, % and a second optional argument: % \cs{SI}\oarg{options}\marg{number}\oarg{preunit}\marg{unit}. The % \m{number} and \m{unit} arguments work exactly like those for % the \cs{num} and \cs{si} macros, respectively. \m{preunit} is a unit % to be typeset \emph{before} the numerical value (most likely to be a % currency). %\begin{LaTeXdemo} % \SI[font/mode=text]{1.23}{J.mol^{-1}.K^{-1}} \\ % \SI{.23e7}{\candela} \\ % %\SI[per=slash]{1.99}[\$]{\per\kilogram} \\ % \SI{70}{\metre\per\second} \\ % %\SI[per=frac,fraction=nice]{1,345}{\ampere\per\mole} %\end{LaTeXdemo} % %\subsection{Units: free-standing} % %\section{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 % (Table~\ref{tab:unit:base}). In addition, the macro \cs{meter} is % available as an alias for \cs{metre}, for users of US spellings. % The full details of the base units are given in the SI % Brochure~\cite{SI:2.1}. The SI also lists a number of units which % have special names and symbols \cite{SI:2.2.2}: these are listed % in Table~\ref{tab:unit:derived}. %\begin{table} % \caption{SI base units} % \label{tab:unit:base} % \centering % \begin{tabular}{lll} % \toprule % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} \\ % \midrule % \DescribeUnit{ampere} \\ % \DescribeUnit{candela} \\ % \DescribeUnit{kelvin} \\ % \DescribeUnit{kilogram} \\ % \DescribeUnit{metre} \\ % \DescribeUnit{mole} \\ % \DescribeUnit{second} \\ % \bottomrule % \end{tabular} %\end{table} % %\begin{table} % \caption{Coherent derived units in the SI with special names and % symbols} % \label{tab:unit:derived} % \centering % \begin{tabular}{llllll} % \toprule % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} & % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} \\ % \midrule % \DescribeUnit{becquerel} & % \DescribeUnit{newton} \\ % \SpecialUsageIndex{\celsius}^^A % degree Celsius & \cs{celsius} & \si{\celsius} & % \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. Table~\ref{tab:unit:accepted} lists % the ``accepted'' units \cite{SI:4.1.T6}. Some units are fundamental % physical quantities, and these are non-SI but can be used with in the % SI (Table~\ref{tab:unit:physical}, \cite{SI:4.1.T7}). There are also a % set of non-SI units which are used in certain defined circumstances % (Table~\ref{tab:unit:other}), although they are not necessarily % official sanctioned \cite{SI:4.1.T8}. %\begin{table} % \caption{Non-SI units accepted for use with the % International System of Units} % \label{tab:unit:accepted} % \centering % \begin{tabular}{lll} % \toprule % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} \\ % \midrule % \DescribeUnit{day} \\ % \DescribeUnit{degree} \\ % \DescribeUnit{hectare} \\ % \DescribeUnit{hour} \\ % \DescribeUnit{litre} \\ % \SpecialUsageIndex{\liter}^^A % & \cs{liter} & \si{\liter} \\ % \SpecialUsageIndex{\arcminute}^^A % minute (plane angle) & \cs{arcminute} & \si{\arcminute} \\ % \SpecialUsageIndex{\minute}^^A % minute (time) & \cs{minute} & \si{\minute} \\ % \DescribeUnit{percent} \\ % \SpecialUsageIndex{\arcsecond}^^A % second (plane angle) & \cs{arcsecond} & \si{\arcsecond} \\ % \DescribeUnit{tonne} \\ % \bottomrule % \end{tabular} %\end{table} %\begin{table} % \caption{Non-SI units whose values in SI units must be obtained % experimentally} % \label{tab:unit:physical} % \centering % \begin{tabular}{lll} % \toprule % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} \\ % \midrule % \SpecialUsageIndex{\astronomicalunit}^^A % astronomical unit & \cs{astronomicalunit} % & \si{\astronomicalunit} \\ % \SpecialUsageIndex{\atomicmassunit}^^A % atomic mass unit & \cs{atomicmassunit} & % \si{\atomicmassunit} \\ % \DescribeUnit{bohr} \\ % \SpecialUsageIndex{\clight}^^A % speed of light & \cs{clight} & \si{\clight} \\ % \DescribeUnit{dalton} \\ % \SpecialUsageIndex{\electronmass}^^A % electron mass & \cs{electronmass} & \si{\electronmass} \\ % \DescribeUnit{electronvolt} \\ % \SpecialUsageIndex{\elementarycharge}^^A % elementary charge & \cs{elementarycharge} % & \si{\elementarycharge} \\ % \DescribeUnit{hartree} \\ % \SpecialUsageIndex{\planckbar}^^A % reduced Planck constant & \cs{planckbar} & \si{\planckbar} \\ % \bottomrule % \end{tabular} %\end{table} %\begin{table} % \caption{Other non-SI units} % \label{tab:unit:other} % \centering % \begin{tabular}{lll} % \toprule % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} \\ % \midrule % \SpecialUsageIndex{\angstrom}^^A % {\aa}ngstr{\"o}m & \cs{angstrom} & \si{\angstrom} \\ % \DescribeUnit{bar} \\ % \DescribeUnit{barn} \\ % \DescribeUnit{bel} \\ % \DescribeUnit{decibel} \\ % \DescribeUnit{knot} \\ % \SpecialUsageIndex{\mmHg}^^A % millimetre of mercury & \cs{mmHg} & \si{\mmHg} \\ % \SpecialUsageIndex{\nauticalmile}^^A % nautical mile & \cs{nauticalmile} & \si{\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 % (Table~\ref{tab:unit:prefix}, \cite{SI:3.1}). The spelling % ``\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}{llclllcl} % \toprule % \multicolumn{1}{c}{Prefix} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} & % \multicolumn{1}{c}{Power} & % \multicolumn{1}{c}{Prefix} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} & % \multicolumn{1}{c}{Power} \\ % \midrule % \DescribePrefix{yocto} & % \DescribePrefix{deca} \\ % \DescribePrefix{zepto} & % \DescribePrefix{hecto} \\ % \DescribePrefix{atto} & % \DescribePrefix{kilo} \\ % \DescribePrefix{femto} & % \DescribePrefix{mega} \\ % \DescribePrefix{pico} & % \DescribePrefix{giga} \\ % \DescribePrefix{nano} & % \DescribePrefix{tera} \\ % \DescribePrefix{micro} & % \DescribePrefix{peta} \\ % \DescribePrefix{milli} & % \DescribePrefix{exa} \\ % \DescribePrefix{centi} & % \DescribePrefix{zetta} \\ % \DescribePrefix{deci} & % \DescribePrefix{yotta} \\ % \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{units/output/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} % %\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} % New units are produced using the \cs{DeclareSIUnit} macro. This takes % two mandatory arguments, as well as one optional one: % \cs{DeclareSIUnit}\oarg{options}\marg{unit}\marg{symbol}. % \m{symbol} can contain literal values, other units, multiple % prefixes, powers and \cs{per}, although literal text should not be % intermixed with unit macros. The \m{options} argument can be % any suitable options, and applies 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[units/output/number-unit separator={}] % {\degree}{\SIUnitSymbolDegree} %\end{LaTeXdemo} % The spacing can still be altered at point of use: %\begin{LaTeXdemo} % \SI{67890}{\degree} \\ % \SI[units/output/number-unit separator = \;]{67890}{\degree} %\end{LaTeXdemo} % %\DescribeMacro{\DeclareSIPrefix} %\DescribeMacro{\DeclareSIPrefix*} % 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}. This has syntax % \cs{DeclareSIPrefix}\marg{prefix}\marg{symbol}\marg{powers-ten}. A % starred-version is also available for creating binary prefixes, with % the same syntax (\m{powers-ten} being replaced by % \m{powers-two}). For example, \cs{kilo} and \cs{kibi} are defined: %\begin{LaTeXdemo}[code only] % \DeclareSIPrefix{\kilo}{k}{3} % \DeclareSIPrefix*{\kibi}{Ki}{10} %\end{LaTeXdemo} % %\DescribeMacro{\DeclareSIPower} %\DescribeMacro{\DeclareSIPower*} % Descriptions for powers are created using \cs{DeclareSIPower}, with % syntax \cs{DeclareSIPower}\marg{power}\marg{num}. This creates a % power macro to appear before the unit it applies to. A starred version % of the macro creates powers to appear after the unit. %\begin{LaTeXdemo} % %\DeclareSIPower{\quartic}{4} % %\DeclareSIPower*{\totheforth}{4}\\ % %\si{\kilogram\totheforth}\\ % %\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{\product}{prod} % \DeclareSIQualifier*{\catalyst}{cat} %\end{LaTeXdemo} % and then in the body the document could read: %\begin{LaTeXdemo} % \SI{1.234}{\gram\product\per\mole\catalyst\per\hour} %\end{LaTeXdemo} % %\section{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. % % All of the keys are controlled using the \pkg{pgfkeys} approach to % organisation. This means that the keys are split into ``paths'' of % related keys. A single key is set by giving the path plus key name; if % you need to set several keys on the same path, you can ``change'' to % the appropriate path and give the key name alone. For example, valid % numerical input is controlled by keys in the \texttt{numbers/input/} % path: %\begin{LaTeXdemo}[code only] % \sisetup{ % numbers/input/signs = +-\pm\mp, % numbers/input/exponent markers = dDeE % } %\end{LaTeXdemo} % or %\begin{LaTeXdemo}[code only] % \sisetup{ % numbers/input/.cd, % signs = +-\pm\mp, % exponent markers = dDeE % } %\end{LaTeXdemo} % are both valid. % % 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{Literal}] A key which uses the value(s) given directly, % either to check input (for example the \opt{numbers/input} keys) % or in output. % \item[\texttt{Maths}] Similar to a \texttt{literal} option, but the % input is always used in maths 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{Macro}] Requires a macro, which may need a single % argument. % \item[\texttt{Style}] A key which contains a number of other keys to % set. Only the key name should be given: no value is required. This % type of key is user-definable, as described in % Section~\ref{sec:styles}. % \item[\texttt{Switch}] These are on--off switches, and recognise % \texttt{true}, \texttt{on} and \texttt{yes} to turn on, and % \texttt{false}, \texttt{off} and \texttt{no} to turn off. 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. % % In all cases, UK and US English spellings are available for both % option names and for settings. Thus \opt{centre} and % \opt{center} can be used for alignment options, and \opt{maths} % or \opt{math} is valid in the names of font options. In the rest of % this document, UK English spelling is 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 upright maths % font for all printing.\footnote{This will typically use \cs{mathrm}.} % However, the package can detect and follow surrounding bold, italic % and font family changes. The font detection options are available in % path \texttt{font/detect/} and are summarised in % Table~\ref{tab:opt:font:det}. %\begin{table} % \centering % \caption{\texttt{font/detect/} options} % \label{tab:opt:font:det} % \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} % \toprule % \multicolumn{1}{c}{Option name} & % \multicolumn{1}{c}{Type} & % \multicolumn{1}{c}{Default} \\ % \midrule % all & Style & \m{none} \\ % bold & Switch & false \\ % display maths & Switch & false \\ % family & Switch & false \\ % inline bold & Choice & text \\ % italic & Switch & false \\ % mode & Switch & false \\ % none & Style & \m{none} \\ % \bottomrule % \end{tabular} %\end{table} % %\DescribeOption{font/detect/bold} %\DescribeOption{font/detect/family} %\DescribeOption{font/detect/italic} %\DescribeOption{font/detect/mode} % The four basic options \opt{bold} and \opt{italic} set detection % of the prevailing bold and italic states, respectively. The italic % state is only checked if the surrounding material is not in maths mode % (as maths text is always italic). Detecting the current family (roman, % sans serif or monospaced) is controlled by the \opt{family} % setting, while the current mode (text or maths) is detected using the % \opt{mode} switch. % %\DescribeOption{font/detect/all} %\DescribeOption{font/detect/none} % The two style options \opt{all} and \opt{none} can be used to % turn on or off all of the detection functions in one go. These are % style options, and so need no value. %\begin{LaTeXdemo} % \sisetup{font/detect/none}% % $\num{1234}$ \\ % \num{1234} \\ % \emph{\num{1234}} \\ % \textbf{\num{1234}} \\ % \textbf{$\num{1234}$} \\ % \sisetup{font/detect/all}% % $\num{1234}$ \\ % \num{1234} \\ % \emph{\num{1234}} \\ % \textbf{\num{1234}} \\ % \textbf{$\num{1234}$} \\\ %\end{LaTeXdemo} % %\DescribeOption{font/detect/inline bold} % Bold detection is influenced by the value of \opt{inline bold}, % which takes values \opt{text} and \opt{maths}. The package % can detect the local value of bold for either the surrounding text, % or the surrounding inline (|$|\ldots|$|) maths. %\begin{LaTeXdemo} % \sisetup{ % font/detect/bold = on, % font/detect/inline bold = maths % }% % $\num{1234}$ \\ % { \boldmath $\num{1234}$ } \\ % { \bfseries $\num{1234}$ } \\ % \sisetup{ % font/detect/inline bold = text % } % { \boldmath $\num{1234}$ } \\ % { \bfseries $\num{1234}$ } %\end{LaTeXdemo} % %\DescribeOption{font/detect/display maths} % The font detection system can treat displayed mathematical content % in two ways. This is controlled by the \opt{display} option. % When set \opt{on}, display mathematics is treated independently % from the body of the document. Thus the local \emph{maths} font is % checked for matching. In contrast, when set \opt{off}, display % material is treated with the current running text font. %\begin{LaTeXdemo} % \sffamily % Some text % \sisetup{ % font/detect/all, % font/detect/display maths = true % } % \[ x = \SI{1.2e3}{\kilogram\kelvin\candela} \] % More text % \sisetup{font/detect/display maths = false} % \[ y = \SI{3}{\metre\second\mole} \] %\end{LaTeXdemo} % %\subsection{Output font families} % % 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. % This is controlled by the \opt{font/output} options. % %\begin{table} % \centering % \caption{^^A % \texttt{font/} options (all also apply in % \texttt{font/units/} and \texttt{font/numbers})^^A % } % \label{tab:opt:font:set} % \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} % \toprule % \multicolumn{1}{c}{Option name} & % \multicolumn{1}{c}{Type} & % \multicolumn{1}{c}{Default} \\ % \midrule % maths rm & Macro & \cs{mathrm} \\ % maths sf & Macro & \cs{mathsf} \\ % maths tt & Macro & \cs{mathtt} \\ % mode & Choice & maths \\ % text rm & Macro & \cs{rmfamily} \\ % text sf & Macro & \cs{sffamily} \\ % text tt & Macro & \cs{ttfamily} \\ % \bottomrule % \end{tabular} %\end{table} % %\DescribeOption{font/mode} % The \opt{mode} option determines whether \pkg{siunitx} uses % maths or text mode when printing output. The choices are % \opt{maths}, \opt{math} and \opt{text}. When using maths % mode, text is printed using a maths 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{font/detect/mode} switch is % \opt{on}. % %\DescribeOption{font/maths rm} %\DescribeOption{font/text rm} % If font family detection is inactive, \pkg{siunitx} uses the font % family stored in either \opt{maths rm} or \opt{text rm} for % output. The choice of \opt{maths} or \opt{text} depends on the % \opt{mode} setting. %\DescribeOption{font/maths sf} %\DescribeOption{font/maths tt} %\DescribeOption{font/text sf} %\DescribeOption{font/text tt} % If font family detection is active, \pkg{siunitx} may be using a % sans serif or monospaced font for output. In maths mode, these are % stored in \opt{maths sf} and \opt{maths 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{font/detect/family}% % \num{1234} \\ % { \sffamily \num{1234} } \\ % \SI{99}{\metre} \\ % \sisetup{font/maths rm = \mathtt}% % \SI{99}{\metre} %\end{LaTeXdemo} % This can be used to good effect to change all output from % \pkg{siunitx} without needing to detect the font. For example, % when creating \pkg{beamer} presentations the settings %\begin{LaTeXdemo}[code only] % \sisetup{ % font/maths rm = \mathsf, % font/text rm = \sffamily % } %\end{LaTeXdemo} % given all output in sans serif font without font detection. % % Every one of the font options can be given independently for units % and number, with the option paths \opt{font/units/} and % \opt{font/numbers/}, respectively. This allows fine control of % output. % %\subsection{Parsing numbers} % % The package uses a sophisticated parsing system to understand % numbers. This allows \pkg{siunitx} to carry out a range of % formatting, as described later. All of the input options take lists of % literal tokens, and are summarised in Table~\ref{tab:opt:num:in}. % %\begin{table} % \centering % \caption{\texttt{numbers/input/} options} % \label{tab:opt:num:in} % \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} % \toprule % \multicolumn{1}{c}{Option name} & % \multicolumn{1}{c}{Type} & % \multicolumn{1}{c}{Default} \\ % \midrule % complex roots & Literal & ij \\ ^^A ( % close uncertainty & Literal & ) \\ % decimal markers & Literal & ., \\ % digits & Literal & 0123456789 \\ % exponent markers & Literal & dDeE \\ % ignore & Literal & \m{none} \\ % open uncertainty & Literal & ( \\ ^^A ) % signs & Literal & +-\cs{pm}\cs{mp} \\ % symbols & Literal & \cs{pi} \\ % \bottomrule % \end{tabular} %\end{table} % %\DescribeOption{numbers/input/digits} %\DescribeOption{numbers/input/decimal markers} %\DescribeOption{numbers/input/signs} %\DescribeOption{numbers/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{digits}, \opt{decimal markers} and \opt{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{exponent % markers} option. % %\DescribeOption{numbers/input/ignore} %\DescribeOption{numbers/input/symbols} % As well as ``normal'' digits, the package will interpret symbolic % ``numbers'' (such as \cs{pi}) correctly if they are included in the % \opt{symbols} list. Tokens given in the \opt{ignore} list are % totally passed over by \pkg{siunitx}: they will be removed from the % input with no further processing. % %\DescribeOption{numbers/input/open uncertainty} %\DescribeOption{numbers/input/close uncertainty} % In some fields, it is common to give the uncertainty in a value % in brackets after the main part of the number, for example % ``\num{1.234(5)}''. The opening and closing symbols used for this type % of input are set as \opt{open uncertainty} and \opt{close % uncertainty}. % %\DescribeOption{numbers/input/complex roots} % When using complex numbers in input, the complex root ($\sqrt{-1}$) is % indicated by one of the tokens stored in \opt{complex roots}. % %\subsection{Post-processing numbers} % % Before typesetting numbers, various post-processing steps can be % carried out. These involve adding or removing information from the % number in a systematic way; the options are summarised in % Table~\ref{tab:opt:num:post}. % %\begin{table} % \centering % \caption{\texttt{numbers/process/} options} % \label{tab:opt:num:post} % \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} % \toprule % \multicolumn{1}{c}{Option name} & % \multicolumn{1}{c}{Type} & % \multicolumn{1}{c}{Default} \\ % \midrule % add zero decimal & Switch & false \\ % add zero integer & Switch & false \\ % explicit sign & Literal & + \\ % include explicit sign & Switch & false \\ % retain explicit plus & Switch & false \\ % retain zero exponent & Switch & false \\ % round mode & Choice & off \\ % round figures & Number & 2 \\ % round places & Number & 2 \\ % \bottomrule % \end{tabular} %\end{table} % %\DescribeOption{numbers/process/round mode} %\DescribeOption{numbers/process/round figures} %\DescribeOption{numbers/process/round places} % 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 figures to use is determined by the \opt{round figures} % and \opt{round places} option: both of these options require a % number. %\begin{LaTeXdemo} % \num{1.23456} \\ % \num{14.23} \\ % \sisetup{ % numbers/process/round mode = places, % numbers/process/round places = 3 % }% % \num{1.23456} \\ % \num{14.23} \\ % \sisetup{ % numbers/process/round mode = figures, % numbers/process/round figures = 3 % }% % \num{1.23456} \\ % \num{14.23} %\end{LaTeXdemo} % %\DescribeOption{numbers/process/add zero decimal} %\DescribeOption{numbers/process/add zero integer} % 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 zero decimal} and \opt{add % zero integer} allow the package to ``fill in'' the missing zero. %\begin{LaTeXdemo} % \num{123.} \\ % \num{.456} \\ % \sisetup{ % numbers/process/add zero decimal = no, % numbers/process/add zero integer = no, % }% % \num{123.} \\ % \num{.456} %\end{LaTeXdemo} % %\DescribeOption{numbers/process/explicit sign} %\DescribeOption{numbers/process/include explicit sign} %\DescribeOption{numbers/process/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. As the same time, it % may be useful to force all numbers to have a sign. This behaviour % is controlled by the \opt{include explicit sign} option, with the % sign to use stored by the \opt{explicit sign} option. %\begin{LaTeXdemo} % \num{+345} \\ % \num[numbers/process/retain explicit plus]{+345} \\ % \num[ % numbers/process/explicit sign = -, % numbers/process/include explicit sign, % ]{345} %\end{LaTeXdemo} % %\DescribeOption{numbers/process/retain zero exponent} % The retention of a zero exponent (\num[numbers/process/retain zero % exponent]{e0}) is controlled by the \opt{retain zero exponent} % option. %\begin{LaTeXdemo} % \num{444e0} \\ % \num[numbers/process/retain zero exponent = yes]{444e0} %\end{LaTeXdemo} % %\subsection{Printing numbers} % % Actually printing numbers is controlled by a number of settings, % which apply ideas such as differing decimal markers, digit % grouping and so on. All of these options are concerned with the % appearance of output, rather than the data it conveys. The options are % summarised in Table~\ref{tab:opt:num:out}. % %\begin{table} % \centering % \caption{\texttt{numbers/output/} options} % \label{tab:opt:num:out} % \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} % \toprule % \multicolumn{1}{c}{Option name} & % \multicolumn{1}{c}{Type} & % \multicolumn{1}{c}{Default} \\ % \midrule ^^A ( % close bracket & Literal & ) \\ ^^A ( % close uncertainty & Literal & ) \\ % complex root & Maths & i \\ % decimal marker & Maths & . \\ % exponent base & Literal & 10 \\ % exponent product & Maths & \cs{times} \\ % group digits & Switch & true \\ % group four digits & Switch & false \\ % group separator & Maths & \cs{,} \\ % open bracket & Literal & ( \\ ^^A ) % open uncertainty & Literal & ( \\ ^^A ) % separate uncertainty & Switch & false \\ % tight spacing & Switch & false \\ % use brackets & Switch & true \\ % uncertainty space & Maths & \m{none} \\ % \bottomrule % \end{tabular} %\end{table} % %\DescribeOption{numbers/output/group digits} %\DescribeOption{numbers/output/group four digits} %\DescribeOption{numbers/output/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 % turns this behaviour on and off, with grouping for numbers of exactly % four digits controlled by the \opt{group four digits} choice. Note % that the later only applies if \opt{group digits} is turned on. % The separator used between groups of digits is stored by the % \opt{group separator} option. This takes literal input and is % used in maths mode: for a text-mode full space use |\text{~}|. %\begin{LaTeXdemo} % \num{12345} \\ % \num[numbers/output/group digits = off]{12345} \\ % \num{1234} \\ % \num[numbers/output/group four digits = on]{1234} \\ % \num{12345} \\ % \num[numbers/output/group separator = {{{,}}}]{12345} \\ % \num[numbers/output/group separator = \text{~}]{12345} %\end{LaTeXdemo} % %\DescribeOption{numbers/output/complex root} %\DescribeOption{numbers/output/decimal marker} % The decimal marker used in output is set using the \opt{decimal % marker} option. This can differ from the input marker, as can the root % of $\sqrt{-1}$, which is stored in the \opt{complex root} option. % The later is always in maths mode, but notice that \pkg{siunitx} % uses \cs{mathrm} by default. To force standard \TeX\ maths output to % give $i$, the construction |\text{\ensuremath{i}}| can be used. %\begin{LaTeXdemo} % \num{1.23} \\ % \num[numbers/output/decimal marker = {{{,}}}]{1.23} \\ % \num[numbers/output/complex root = \text{\ensuremath{i}}]{1+2i} %\end{LaTeXdemo} % %\DescribeOption{numbers/output/exponent base} %\DescribeOption{numbers/output/exponent product} % When exponents are present in the input, the options \opt{exponent % base} and \opt{exponent product} set the obvious parts of the % output. Notice that the base is in the current mode, but the product % sign is always in maths mode. %\begin{LaTeXdemo} % \num[numbers/output/exponent product = \times]{1e2} \\ % \num[numbers/output/exponent product = \cdot]{1e2} \\ % \num[numbers/output/exponent base = 2]{1e2} %\end{LaTeXdemo} % %\DescribeOption{numbers/output/separate uncertainty} %\DescribeOption{numbers/output/uncertainty space} %\DescribeOption{numbers/output/open uncertainty} %\DescribeOption{numbers/output/close uncertainty} % When input is given including an uncertatinty in a value, 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 value and the uncertainty: this is % stored using the \opt{uncertainty space} option. The opening and % closing brackets used are stored \opt{open uncertainty} and % \opt{close uncertainty}, respectively. %\begin{LaTeXdemo} % \num{1.234(5)} \\ % \num[numbers/output/separate uncertainty = on]{1.234(5)} \\ % \sisetup{ % numbers/output, % open uncertainty = [, % close uncertainty = ], % uncertainty space = {\,} % } % \num{1.234(5)} %\end{LaTeXdemo} % %\DescribeOption{numbers/output/use brackets} %\DescribeOption{numbers/output/open bracket} %\DescribeOption{numbers/output/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{use brackets} switch. The % opening and closing brackets used are stored \opt{open bracket} and % \opt{close bracket}, respectively. %\begin{LaTeXdemo} % \num{1+2i e10} \\ % \num[numbers/output/use brackets = false]{1+2i e10} \\ % \sisetup{ % numbers/output, % open bracket = \{, % close bracket = \}, % } % \num{1+2i e10} %\end{LaTeXdemo} % %\DescribeOption{numbers/output/tight spacing} % Under some circumstances is may be desirable to ``squeeze'' the output % spacing. This is turned on using the \opt{tight spacing} switch, % which compresses spacing where possible. %\begin{LaTeXdemo} % \num{1\pm2i e3} \\ % \num[numbers/output/tight spacing = true]{1\pm2i e3} \\ %\end{LaTeXdemo} % %\subsection{Creating units} % % The various macro units are created at the start of the document. % These can be defined only inside the \cs{si} and \cs{SI} macros, or % can also be made available in the document body. There are a number of % settings which control this creation process % (Table~\ref{tab:opt:units:def}). As a result, these options all apply % in the preamble only. % %\begin{table} % \centering % \caption{\texttt{units/creation/} options} % \label{tab:opt:units:def} % \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} % \toprule % \multicolumn{1}{c}{Option name} & % \multicolumn{1}{c}{Type} & % \multicolumn{1}{c}{Default} \\ % \midrule ^^A ( % add leading space & Switch & false \\ % allow in body & Switch & false \\ % allow optional argument & Switch & false \\ % overwrite macros & Switch & false \\ % use xspace & Switch & false \\ % \bottomrule % \end{tabular} %\end{table} % %\DescribeOption{units/creation/allow in body} %\DescribeOption{units/creation/overwrite macros} % The \opt{allow in body} 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 % macros} switch. % %\DescribeOption{units/creation/add leading space} %\DescribeOption{units/creation/allow optional argument} %\DescribeOption{units/creation/use xspace} % When ``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{allow 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{add leading space} and \opt{use xspace} options control % the behaviour at the ``ends'' of the unit macros. Activating % \opt{add leading space} inserts the number--unit space before the % unit is printed. This is suitable for the input syntax %\begin{LaTeXdemo}[code only] % 30\metre %\end{LaTeXdemo} % but does mean that the unit macros are incorrectly spaced in running % text. On the other hand, the \opt{use xspace} option attempts to % correctly space input such as %\begin{LaTeXdemo}[code only] % \metre is the symbol for metres. %\end{LaTeXdemo} % %\subsection{Using units} % % Part of the power of \pkg{siunitx} is the ability to alter the output % format for units without changing the input. The behaviour of units % is therefore controlled by a number of options which alter either the % processing of units or the output directly. % %\begin{table} % \centering % \caption{\texttt{units/output} options} % \label{tab:opt:num:out} % \begin{tabular}{>{\ttfamily}ll>{\ttfamily}l} % \toprule % \multicolumn{1}{c}{Option name} & % \multicolumn{1}{c}{Type} & % \multicolumn{1}{c}{Default} \\ % \midrule ^^A ( % allow literal units & Switch & true \\ % allow number-unit breaks & Switch & false \\ % close bracket & Literal & ) \\ % inter-unit separator & Literal & \cs{,} \\ % inter-unit space & Literal & \cs{,} \\ % number-unit separator & Literal & \cs{,} \\ % open bracket & Literal & ( \\ ^^A ) % print as fraction & Switch & false \\ % qualifier format & Choice & subscript \\ % sticky per & Switch & false \\ % use brackets & Switch & true \\ % \bottomrule % \end{tabular} %\end{table} % %\DescribeOption{units/output/allow 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{allow literal units} switch. With % this option enabled, only macro-based units can be used in a document. % %\DescribeOption{units/output/allow unit-number breaks} % The standard method for printing units with a value prevents a break % occurring between the two parts. The \opt{allow unit-number breaks} % can be used to turn on breaking in this context, for example when % using narrow columns. %\begin{LaTeXdemo} % \begin{minipage}{4cm} % Some text to act as filler \SI{10}{\kilogram\cubic\metre} \\ % \sisetup{units/output/allow number-unit breaks}% % Some text to act as filler \SI{10}{\kilogram\cubic\metre} % \end{minipage} %\end{LaTeXdemo} % %\DescribeOption{units/output/inter-unit separator} %\DescribeOption{units/output/number-unit separator} % The separation between units, and between a number and the units % following it, can be adjusted. The options \opt{inter-unit % separator} and \opt{number-unit separator} are used to store an % appropriate spacing or separator value. The separators are always % printed in maths mode: a full text space is therefore given as % |\text{ }|. %\DescribeOption{units/output/inter-unit space} % When using literal unit input, the |~| symbol is converted into an % inter-unit space which can be different from that specified in % \opt{inter-unit separator}. % %\DescribeOption{units/output/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 % ``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[units/output/sticky per] % {\pascal\per\gray\henry} %\end{LaTeXdemo} % %\DescribeOption{units/output/use brackets} %\DescribeOption{units/output/open bracket} %\DescribeOption{units/output/close bracket} % As with numerical output, there are some occasions when units can % potentially be ambiguous. This can be corrected by adding brackets in % the appropriate place, and is controlled by the \opt{use brackets} % switch. The opening and closing brackets used are stored \opt{open % bracket} and \opt{close bracket}, respectively. %\begin{LaTeXdemo} % \sisetup{units/output/qualifier format = space}% % \SI{1.234}{\gram\product\cubed\per\mole} \\ % \SI[units/output/use brackets = false] % {1.234}{\gram\product\cubed\per\mole} \\ % \SI[units/output/open bracket = \{, % units/output/close bracket = \}] % {1.234}{\gram\product\cubed\per\mole} %\end{LaTeXdemo} % %\DescribeOption{units/output/qualifier format} % Unit qualifiers can appear in a number of output formats. The package % expects a choice from the list \opt{subscript}, \opt{space} % and \opt{brackets}. These work as might be expected. %\begin{LaTeXdemo} % \si[units/output/qualifier format = subscript]{\gram\product} \\ % \si[units/output/qualifier format = space]{\gram\product} \\ % \si[units/output/qualifier format = brackets]{\gram\product} %\end{LaTeXdemo} % When the qualifier is given as a subscript, no brackets will be % added if a power is given for the same unit. For other formats, % brackets are added if \opt{use brackets} is true. %\begin{LaTeXdemo} % \si[units/output/qualifier format = subscript] % {\gram\product\squared} \\ % \si[units/output/qualifier format = space] % {\gram\product\squared} %\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{symbols/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 used for a number of units are available as % package options in paths \texttt{symbols/maths} and % \texttt{symbols/text}. The option names are summarised in % Table~\ref{tab:opt:symbols}. The standard values can be somewhat % involved, and the interested reader is directed to the code for full % details. In many cases, the maths and text variations are created % from the same underlying macro using \cs{text} or \cs{ensuremath}. For % example, the standard definitions for \opt{angstrom} are: %\begin{LaTeXdemo}[code only] % \sisetup{ % symbols/maths/angstrom = \text{\AA}, % symbols/text/angstrom = \AA, % } %\end{LaTeXdemo} %\begin{table} % \centering % \caption{\texttt{symbols/maths} and \texttt{symbols/text} options} % \label{tab:opt:symbols} % \begin{tabular}{>{\ttfamily}ll} % \toprule % \multicolumn{1}{c}{Option name} & % \multicolumn{1}{c}{Type} \\ % \midrule ^^A ( % \SpecialOptionIndex{symbols/maths/angstrom}^^A % \SpecialOptionIndex{symbols/text/angstrom}^^A % \SpecialOptionIndex{symbols/maths/arcminute}^^A % \SpecialOptionIndex{symbols/text/arcminute}^^A % \SpecialOptionIndex{symbols/maths/arcsecond}^^A % \SpecialOptionIndex{symbols/text/arcsecond}^^A % \SpecialOptionIndex{symbols/maths/celsius}^^A % \SpecialOptionIndex{symbols/text/celsius}^^A % \SpecialOptionIndex{symbols/maths/degree}^^A % \SpecialOptionIndex{symbols/text/degree}^^A % \SpecialOptionIndex{symbols/maths/micro}^^A % \SpecialOptionIndex{symbols/text/micro}^^A % \SpecialOptionIndex{symbols/maths/ohm}^^A % \SpecialOptionIndex{symbols/text/ohm}^^A % angstrom & Literal \\ % arcminute & Literal \\ % arcsecond & Literal \\ % celsius & Literal \\ % degree & Literal \\ % micro & Literal \\ % ohm & Literal \\ % \bottomrule % \end{tabular} %\end{table} % %\DescribeMacro{\SIUnitSymbolAngstrom} %\DescribeMacro{\SIUnitSymbolArcminute} %\DescribeMacro{\SIUnitSymbolArcsecond} %\DescribeMacro{\SIUnitSymbolCelsius} %\DescribeMacro{\SIUnitSymbolDegree} %\DescribeMacro{\SIUnitSymbolMicro} %\DescribeMacro{\SIUnitSymbolOhm} % The maths 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 angstrom % symbol can be accessed using the macro \cs{SIUnitSymbolAngstrom}. % Notice that these names capitalise the unit name (to make reading % the macro name easier!). % %\section{Usage tips and known issues} % %\subsection{Ensuring text or maths 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. %\begin{LaTeXdemo} % \num[numbers/output/complex root = i]{1+2i} \\ % \num[numbers/output/complex root = \ensuremath{i}]{1+2i} \\ % \num[numbers/output/complex root = \text{\ensuremath{i}}]{1+2i} %\end{LaTeXdemo} % In some circumstances, forcing \cs{mathnormal} may suffice, but this % deals less well with non-Latin characters. % %\subsection{Using a comma as a separator} % % The use of a comma as a group separator or decimal marker is common in % many parts of the world. This is easily achieved in \pkg{siunitx}, but % does require three sets of braces in the option to give the normal % spacing. %\begin{LaTeXdemo} % \num[numbers/output/decimal marker = {,}]{1.23} \\ % Wrong % \num[numbers/output/decimal marker = {{,}}]{1.23} \\ % Wrong % \num[numbers/output/decimal marker = {{{,}}}]{1.23} \\ % Correct %\end{LaTeXdemo} % %\StopEventually{^^A % \PrintChanges % \PrintIndex % \begin{thebibliography}{1} % % \bibitem{BIPM} % \emph{The International System of Units (SI)}, % \url{http://www.bipm.org/en/si/}. % % \bibitem{SI:2.1} % \emph{SI base units}, % \url{http://www.bipm.org/en/si/si_brochure/chapter2/2-1/}. % % \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/si/si_brochure/chapter2/2-2/2-2-2.html}. % % \bibitem{SI:3.1} % \emph{SI Prefixes}, % \url{http://www.bipm.org/en/si/si_brochure/chapter3/prefixes.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/si/si_brochure/chapter4/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/si/si_brochure/chapter4/table7.html}. % % \bibitem{SI:4.1.T8} % \emph{Other non-SI units}, % \url{http://www.bipm.org/en/si/si_brochure/chapter4/table8.html}. % % \end{thebibliography} %} % %\section{Implementation} % %\subsection{Preliminaries} % % The package requires \eTeX, so this is the first check made. % \begin{macrocode} %<*package> \begingroup \@ifundefined{eTeXversion}{% \PackageError{siunitx}{Not running under e-TeX}{% This package requires e-TeX. Try compiling the document with \MessageBreak `elatex' instead of `latex'. When using pdfTeX, try `pdfelatex' \MessageBreak instead of `pdflatex'. }% \endgroup\endinput }{% \endgroup } % \end{macrocode} %\begin{macro}{\si@package@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. % \begin{macrocode} \begingroup \@for\@tempa:=SIunits,sistyle,siunits,SIstyle,unitsdef,fancyunits\do{% \@ifpackageloaded{\@tempa}{% \PackageError{siunitx}{Package `\@tempa' incompatible}{% The \@tempa\space package and siunitx are incompatible. \MessageBreak Use the `emulate=\@tempa' package option when loading siunitx. }% }{}% } \endgroup \newcommand*{\si@package@check}{% \begingroup \@for\@tempa:=SIunits,sistyle,siunits,SIstyle\do{ \@ifpackageloaded{\@tempa}{% \PackageError{siunitx}{Package `\@tempa' incompatible}{% The \@tempa\space package and siunitx are incompatible. \MessageBreak Use the `emulate=\@tempa' package option when loading siunitx. }% }{}% }% \endgroup } \AtBeginDocument{\si@package@check} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@catcode@restore} %\begin{macro}{\si@catcode@set} %\begin{macro}{\si@catcode@store} %\begin{macro}{\si@catcode@symbols} % The internals of the package are now protected from any strange % category codes in force. Some of these are used in a few places % and always take the same values: this set is made available as % the \cs{si@catcode@symbols} macro. % \begin{macrocode} \newcommand*{\si@catcode@restore}{} \newcommand*{\si@catcode@set}{} \newcommand*{\si@catcode@store}[2]{% \edef\si@catcode@restore{% \si@catcode@restore \catcode#1 \the\catcode#1\relax }% \catcode#1 #2\relax } \newcommand*{\si@catcode@symbols}{% \si@catcode@set{42}{12}% * \si@catcode@set{43}{12}% + \si@catcode@set{44}{12}% , \si@catcode@set{46}{12}% . \si@catcode@set{47}{12}% / \si@catcode@set{58}{12}% : \si@catcode@set{59}{12}% ; \si@catcode@set{60}{12}% < \si@catcode@set{61}{12}% = \si@catcode@set{62}{12}% > } \let\si@catcode@set\si@catcode@store \si@catcode@symbols \si@catcode@set{38}{4}% & \si@catcode@set{45}{12}% - \si@catcode@set{94}{7}% ^ \si@catcode@set{95}{8}% _ \si@catcode@set{126}{13}% ~ \renewcommand*{\si@catcode@set}[2]{% \catcode#1 #2\relax } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@lccode@restore} %\begin{macro}{\si@lccode@set} % Something similar for lower-case codes, but there are less to worry % about. % \begin{macrocode} \newcommand*{\si@lccode@restore}{} \edef\si@lccode@restore{% \lccode38 \the\lccode38\relax % & } \newcommand*{\si@lccode@set}[2]{% \lccode#1 #2\relax } % \end{macrocode} %\end{macro} %\end{macro} % % Supporting packages, including \pkg{etex} just to be safe. % \begin{macrocode} \RequirePackage{amstext,array,etex,pgfkeys} % \end{macrocode} % %\begin{macro}{\si@encoding@ts@one} % 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} \newcommand*{\si@encoding@ts@one}{% \@ifundefined{T@TS1}{% \DeclareFontEncoding{TS1}{}{}% \DeclareFontSubstitution{TS1}{cmr}{m}{n}% }{}% } \AtBeginDocument{% \si@encoding@ts@one } % \end{macrocode} %\end{macro} % %\subsection{Key--value basics} % % \pkg{pgfkeys} is set up with the basic settings for managing all of % the key--value options. % %\begin{macro}{\si@key@path} % A storage area. % \begin{macrocode} \newcommand*{\si@key@path}{} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@key@error} %\begin{macro}[aux]{\si@key@error@aux} % The basic structure for keys is created, and standardised errors % are defined. % \begin{macrocode} \newcommand*{\si@key@error}{% \expandafter\si@key@error@aux\pgfkeyscurrentkey\si@stop } \newcommand*{\si@key@error@aux}{} \def\si@key@error@aux/siunitx/#1\si@stop{% \si@log@error{Unknown option `#1'}{% The option `#1' is not known to siunitx. }% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@keys@family} % To create a new family; the base family is done by hand. % \begin{macrocode} \newcommand*{\si@keys@family}[1]{% \pgfkeys{ /siunitx/#1/.is family, /siunitx/#1/.unknown/.code = \si@key@error }% } \pgfkeys{ /siunitx/.is family, /siunitx/.unknown/.code = \si@key@error } % \end{macrocode} %\end{macro} % % A short-cut is provided for switches which take true/false and % related values. % \begin{macrocode} \pgfkeys{ /handlers/.is siunitx switch/.code = {% \edef\si@key@path{\pgfkeyscurrentpath}% \pgfkeys{ \si@key@path/.is choice, \si@key@path/.default = {true}, \si@key@path/true/.code = {\si@bool@cs@true{si@#1@bool}}, \si@key@path/false/.code = {\si@bool@cs@false{si@#1@bool}}, \si@key@path/yes/.code = {\si@bool@cs@true{si@#1@bool}}, \si@key@path/no/.code = {\si@bool@cs@false{si@#1@bool}}, \si@key@path/on/.code = {\si@bool@cs@true{si@#1@bool}}, \si@key@path/off/.code = {\si@bool@cs@false{si@#1@bool}}, }% } } % \end{macrocode} % %\subsection{Variables and constants} % % The scratch registers used internally are defined here. % %\begin{macro}{\si@false@bool} %\begin{macro}{\si@true@bool} % Two values inspired by \LaTeX3, to provide switches in place of % \cs{iftrue} and \cs{iffalse}. This makes life a lot easier in the % nested expansions. % \begin{macrocode} \newcommand*{\si@false@bool}{01} \newcommand*{\si@true@bool}{00} % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@tmp@bool} % A scratch switch % \begin{macrocode} \newcommand*{\si@tmp@bool}{} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % Some private scratch macros. % \begin{macrocode} \newcommand*{\si@tempa}{} \newcommand*{\si@tempb}{} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@tempcnt} % A counter. % \begin{macrocode} \newcount\si@tempcnt % \end{macrocode} %\end{macro} %\begin{macro}{\si@tempbox} % A private box. % \begin{macrocode} \newsavebox\si@tempbox % \end{macrocode} %\end{macro} %\begin{macro}{\si@temp@toks} % And a token registry. % \begin{macrocode} \newtoks\si@temp@toks % \end{macrocode} %\end{macro} % %\begin{macro}{\si@log@error} %\begin{macro}{\si@log@info} %\begin{macro}{\si@log@warning} % To save some typing, the obvious abbreviations. % \begin{macrocode} \newcommand*{\si@log@error}{% \PackageError{siunitx}% } \newcommand*{\si@log@info}{% \PackageInfo{siunitx}% } \newcommand*{\si@log@warning}{% \PackageWarning{siunitx}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\subsection{Utility macros} % % A series of tools which are used generally. A lot of this is inspired % by \LaTeX3: looping in particular is more reliable and efficient using % this system. % %\begin{macro}{\si@reserveda} %\begin{macro}{\si@reservedb} % Just for the utilities. % \begin{macrocode} \newcommand*{\si@reserveda}{} \newcommand*{\si@reservedb}{} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@reserved@toks} % Also a toks. % \begin{macrocode} \newtoks\si@reserved@toks % \end{macrocode} %\end{macro} % %\begin{macro}{\si@add@left@n} %\begin{macro}{\si@add@left@o} % To add to a macro reliably. % \begin{macrocode} \newcommand*{\si@add@left@n}[2]{% \def\si@reserveda{#2}% \edef#1{% \expandafter\unexpanded\expandafter{\si@reserveda}% \expandafter\unexpanded\expandafter{#1}% }% } \newcommand*{\si@add@left@o}[2]{% \expandafter\si@add@left@n\expandafter#1\expandafter{#2}% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@add@left@cs@n} %\begin{macro}{\si@add@left@cs@o} % Some name versions. % \begin{macrocode} \newcommand*{\si@add@left@cs@n}[1]{% \expandafter\si@add@left@n\csname #1\endcsname } \newcommand*{\si@add@left@cs@o}[1]{% \expandafter\si@add@left@o\csname #1\endcsname } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@add@right@n} %\begin{macro}{\si@add@right@o} % To add to a macro reliably. % \begin{macrocode} \newcommand*{\si@add@right@n}[2]{% \def\si@reserveda{#2}% \edef#1{% \expandafter\unexpanded\expandafter{#1}% \expandafter\unexpanded\expandafter{\si@reserveda}% }% } \newcommand*{\si@add@right@o}[2]{% \expandafter\si@add@right@n\expandafter#1\expandafter{#2}% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@add@right@cs@n} %\begin{macro}{\si@add@right@cs@o} % Some name versions. % \begin{macrocode} \newcommand*{\si@add@right@cs@n}[1]{% \expandafter\si@add@right@n\csname #1\endcsname } \newcommand*{\si@add@right@cs@o}[1]{% \expandafter\si@add@right@o\csname #1\endcsname } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@bool@false} %\begin{macro}{\si@bool@new} %\begin{macro}{\si@bool@true} % For creating and manipulating \LaTeX3-style switches. % \begin{macrocode} \newcommand*{\si@bool@false}[1]{% \let#1\si@false@bool } \newcommand*{\si@bool@new}[1]{% \newcommand*{#1}{}% \let#1\si@false@bool } \newcommand*{\si@bool@true}[1]{% \let#1\si@true@bool } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@bool@cs@false} %\begin{macro}{\si@bool@cs@new} %\begin{macro}{\si@bool@cs@true} % The same with names % \begin{macrocode} \newcommand*{\si@bool@cs@false}[1]{% \expandafter\si@bool@false\csname #1\endcsname } \newcommand*{\si@bool@cs@new}[1]{% \expandafter\si@bool@new\csname #1\endcsname } \newcommand*{\si@bool@cs@true}[1]{% \expandafter\si@bool@true\csname #1\endcsname } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@bool@if@F} %\begin{macro}{\si@bool@if@T} %\begin{macro}{\si@bool@if@TF} % To read and apply the \LaTeX3-style switches. % \begin{macrocode} \newcommand*{\si@bool@if@F}[1]{% \if#1% \expandafter\@gobble \else \expandafter\@firstofone \fi } \newcommand*{\si@bool@if@T}[1]{% \if#1% \expandafter\@firstofone \else \expandafter\@gobble \fi } \newcommand*{\si@bool@if@TF}[1]{% \if#1% \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@bool@cs@if@F} %\begin{macro}{\si@bool@cs@if@T} %\begin{macro}{\si@bool@cs@if@TF} % Also name versions % \begin{macrocode} \newcommand*{\si@bool@cs@if@F}[1]{% \expandafter\si@bool@if@F\csname #1\endcsname } \newcommand*{\si@bool@cs@if@T}[1]{% \expandafter\si@bool@if@T\csname #1\endcsname } \newcommand*{\si@bool@cs@if@TF}[1]{% \expandafter\si@bool@if@TF\csname #1\endcsname } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@clear@cs} %\begin{macro}{\si@clear@macro} % Quickly clear storage areas. % \begin{macrocode} \newcommand*{\si@clear@cs}[1]{% \si@let@cN{#1}\@empty } \newcommand*{\si@clear@macro}[1]{% \let#1\@empty } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@count@incr@cs} % Increase a counter by name: \LaTeX3 does this more carefully but that % should not be needed here. % \begin{macrocode} \newcommand*{\si@count@incr@cs}[1]{% \advance\@nameuse{#1}\@ne\relax } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@csname@if@F} %\begin{macro}{\si@csname@if@T} %\begin{macro}{\si@csname@if@TF} % Something to make \cs{ifcsname} less weird. % \begin{macrocode} \newcommand*{\si@csname@if@F}[1]{% \ifcsname #1\endcsname \expandafter\@gobble \else \expandafter\@firstofone \fi } \newcommand*{\si@csname@if@T}[1]{% \ifcsname #1\endcsname \expandafter\@firstofone \else \expandafter\@gobble \fi } \newcommand*{\si@csname@if@TF}[1]{% \ifcsname #1\endcsname \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@dowhile@bool@T} % A simple looping function. % \begin{macrocode} \newcommand*{\si@dowhile@bool@T}[2]{% #2% \si@bool@if@T#1{% \si@dowhile@bool@T#1{#2}% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@empty@cs@if@F} %\begin{macro}{\si@empty@cs@if@T} %\begin{macro}{\si@empty@cs@if@TF} % Tests for empty macros by name. % \begin{macrocode} \newcommand*{\si@empty@cs@if@F}[1]{% \expandafter\si@empty@if@F\csname #1\endcsname } \newcommand*{\si@empty@cs@if@T}[1]{% \expandafter\si@empty@if@T\csname #1\endcsname } \newcommand*{\si@empty@cs@if@TF}[1]{% \expandafter\si@empty@if@TF\csname #1\endcsname } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@empty@if@F} %\begin{macro}{\si@empty@if@T} %\begin{macro}{\si@empty@if@TF} % Or directly. % \begin{macrocode} \newcommand*{\si@empty@if@F}[1]{% \si@meaning@eq@if@F#1\@empty } \newcommand*{\si@empty@if@T}[1]{% \si@meaning@eq@if@T#1\@empty } \newcommand*{\si@empty@if@TF}[1]{% \si@meaning@eq@if@TF#1\@empty } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@empty@tlist@if@F} %\begin{macro}{\si@empty@tlist@if@T} %\begin{macro}{\si@empty@tlist@if@TF} % For lists of tokens, things are kept nice and cautious. % \begin{macrocode} \newcommand*{\si@empty@tlist@if@F}[1]{% \expandafter\ifx\expandafter\si@nil\detokenize{#1}\si@nil \expandafter\@gobble \else \expandafter\@firstofone \fi } \newcommand*{\si@empty@tlist@if@T}[1]{% \expandafter\ifx\expandafter\si@nil\detokenize{#1}\si@nil \expandafter\@firstofone \else \expandafter\@gobble \fi } \newcommand*{\si@empty@tlist@if@TF}[1]{% \expandafter\ifx\expandafter\si@nil\detokenize{#1}\si@nil \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@empty@toks@if@F} %\begin{macro}{\si@empty@toks@if@T} %\begin{macro}{\si@empty@toks@if@TF} % For testing token registers: somewhat simplified from the \LaTeX3 % version. % \begin{macrocode} \newcommand*{\si@empty@toks@if@F}[1]{% \expandafter\si@empty@tlist@if@F\expandafter{\the#1}% } \newcommand*{\si@empty@toks@if@T}[1]{% \expandafter\si@empty@tlist@if@T\expandafter{\the#1}% } \newcommand*{\si@empty@toks@if@TF}[1]{% \expandafter\si@empty@tlist@if@TF\expandafter{\the#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@elt@count} %\begin{macro}[aux]{\si@elt@count@aux} % To count the number of tokens in a macro quickly. % \begin{macrocode} \newcommand*{\si@elt@count}[1]{% \number\numexpr 0\si@loop@over@macro#1\si@elt@count@aux\relax } \newcommand*{\si@elt@count@aux}[1]{+1} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@elt@count@cs} % The name version. % \begin{macrocode} \newcommand*{\si@elt@count@cs}[1]{% \expandafter\si@elt@count\csname #1\endcsname } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@expand@tlist} %\begin{macro}{\si@expand@tlist@cs} % Constructs a list of tokens by expanding each token in |#1| once. % Here, \cs{si@reservedb} is used as the \cs{si@add@right@o} macro is % already using \cs{si@reserveda}. % \begin{macrocode} \newcommand*{\si@expand@tlist}[2]{% \si@clear@macro#1% \def\si@reservedb##1{% \si@add@right@o#1{##1}% }% \si@loop@over@macro@aux\si@reservedb#2\si@loop@end\si@loop@stop } \newcommand*{\si@expand@tlist@cs}[1]{% \expandafter\si@expand@tlist\csname #1\endcsname } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@in@if@F} %\begin{macro}{\si@in@if@T} %\begin{macro}{\si@in@if@TF} % To test if a character is in a given variable. % \begin{macrocode} \newcommand*{\si@in@if@F}[2]{% \def\si@reserveda##1#2##2\si@stop{% \si@no@value@if@T{##2}% }% \expandafter\si@reserveda#1#2\si@no@value\si@stop } \newcommand*{\si@in@if@T}[2]{% \def\si@reserveda##1#2##2\si@stop{% \si@no@value@if@F{##2}% }% \expandafter\si@reserveda#1#2\si@no@value\si@stop } \newcommand*{\si@in@if@TF}[2]{% \def\si@reserveda##1#2##2\si@stop{% \si@no@value@if@FT{##2}% }% \expandafter\si@reserveda#1#2\si@no@value\si@stop } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@in@tlist@if@F} %\begin{macro}{\si@in@tlist@if@T} %\begin{macro}{\si@in@tlist@if@TF} % The same for lists of tokens. % \begin{macrocode} \newcommand*{\si@in@tlist@if@F}[2]{% \def\si@reserveda##1#2##2\si@stop{% \si@no@value@if@T{##2}% }% \si@reserveda#1#2\si@no@value\si@stop } \newcommand*{\si@in@tlist@if@T}[2]{% \def\si@reserveda##1#2##2\si@stop{% \si@no@value@if@F{##2}% }% \si@reserveda#1#2\si@no@value\si@stop } \newcommand*{\si@in@tlist@if@TF}[2]{% \def\si@reserveda##1#2##2\si@stop{% \si@no@value@if@FT{##2}% }% \si@reserveda#1#2\si@no@value\si@stop } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@in@cs@if@F} %\begin{macro}{\si@in@cs@if@T} %\begin{macro}{\si@in@cs@if@TF} % Also a character in a variable by name. % \begin{macrocode} \newcommand*{\si@in@cs@if@F}[1]{% \expandafter\si@in@if@F\csname #1\endcsname } \newcommand*{\si@in@cs@if@T}[1]{% \expandafter\si@in@if@T\csname #1\endcsname } \newcommand*{\si@in@cs@if@TF}[1]{% \expandafter\si@in@if@TF\csname #1\endcsname } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@let@cc} %\begin{macro}{\si@let@cN} %\begin{macro}{\si@let@Nc} % Clearer versions for \cs{let}ting a name. % \begin{macrocode} \newcommand*{\si@let@cc}[2]{% \expandafter\si@let@cN\expandafter{\expandafter#1\expandafter}% \csname #2\endcsname } \newcommand*{\si@let@cN}[1]{% \expandafter\let\csname #1\endcsname } \newcommand*{\si@let@Nc}[2]{% \expandafter\let\expandafter#1\csname #2\endcsname } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@loop@over@cs} % To loop over the name of a macro. % \begin{macrocode} \newcommand*{\si@loop@over@cs}[1]{% \expandafter\si@loop@over@macro\csname #1\endcsname } % \end{macrocode} %\end{macro} %\begin{macro}{\si@loop@over@macro} %\begin{macro}[aux]{\si@loop@over@macro@aux} % To loop over ever token inside a storage macro, expansion tricks % from \LaTeX3 keep things more reliable. % \begin{macrocode} \newcommand*{\si@loop@over@macro}[2]{% \expandafter\si@loop@over@macro@aux \expandafter#2#1\si@loop@end\si@loop@stop } \newcommand*{\si@loop@over@macro@aux}[2]{% \si@loop@end@if{#2}% #1{#2}% \si@loop@over@macro@aux#1% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@loop@end@if} %\begin{macro}{\si@loop@exec@end@if} %\begin{macro}[aux]{\si@loop@end@if@aux} % To actually end the above loop. % \begin{macrocode} \newcommand*{\si@loop@end@if}[1]{% \expandafter\ifx\si@loop@end@if@aux#1?\si@nil\si@loop@end\si@loop@end \expandafter\si@loop@exit \fi } \newcommand*{\si@loop@exec@end@if}[2]{% \expandafter\ifx\si@loop@end@if@aux#1?\si@nil\si@loop@end\si@loop@end \expandafter\si@loop@exit@exec \else \expandafter\@gobble \fi {#2}% } \newcommand*{\si@loop@end@if@aux}{} \def\si@loop@end@if@aux#1#2\si@nil\si@loop@end{#1} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@loop@exit} %\begin{macro}{\si@loop@exit@exec} % To stop the looping above. % \begin{macrocode} \newcommand*{\si@loop@exit}{} \def\si@loop@exit#1\si@loop@stop{} \newcommand*{\si@loop@exit@exec}{} \def\si@loop@exit@exec#1#2\si@loop@stop{#1} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@loop@end} %\begin{macro}{\si@loop@stop} % The markers for the above. % \begin{macrocode} \newcommand*{\si@loop@end}{\si@loop@end} \newcommand*{\si@loop@stop}{\si@loop@stop} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@loop@over@three} %\begin{macro}[aux]{\si@loop@over@three@aux} %\begin{macro}{\si@loop@over@three@cs} % A special loop macro which uses three items at a time. % \begin{macrocode} \newcommand*{\si@loop@over@three}[2]{% \expandafter\si@loop@over@three@aux \expandafter#2#1\si@loop@end\si@loop@stop } \newcommand*{\si@loop@over@three@aux}[4]{% \si@loop@end@if{#2}% #1{#2#3#4}% \si@loop@over@three@aux#1% } \newcommand*{\si@loop@over@three@cs}[1]{% \expandafter\si@loop@over@three\csname #1\endcsname } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@meaning@eq@if@F} %\begin{macro}{\si@meaning@eq@if@T} %\begin{macro}{\si@meaning@eq@if@TF} % A wrapper around \cs{ifx}. % \begin{macrocode} \newcommand*{\si@meaning@eq@if@F}[2]{% \ifx#1#2% \expandafter\@gobble \else \expandafter\@firstofone \fi } \newcommand*{\si@meaning@eq@if@T}[2]{% \ifx#1#2% \expandafter\@firstofone \else \expandafter\@gobble \fi } \newcommand*{\si@meaning@eq@if@TF}[2]{% \ifx#1#2% \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@meaning@eq@cs@if@F} %\begin{macro}{\si@meaning@eq@cs@if@T} %\begin{macro}{\si@meaning@eq@cs@if@TF} % A wrapper around \cs{ifx}. % \begin{macrocode} \newcommand*{\si@meaning@eq@cs@if@F}[2]{% \expandafter\si@meaning@eq@if@F\csname #1\expandafter\endcsname \csname #2\endcsname } \newcommand*{\si@meaning@eq@cs@if@T}[2]{% \expandafter\si@meaning@eq@if@T\csname #1\expandafter\endcsname \csname #2\endcsname } \newcommand*{\si@meaning@eq@cs@if@TF}[2]{% \expandafter\si@meaning@eq@if@TF\csname #1\expandafter\endcsname \csname #2\endcsname } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@mode@maths@display@if@T} %\begin{macro}{\si@mode@maths@inline@if@T} %\begin{macro}{\si@mode@maths@if@F} %\begin{macro}{\si@mode@maths@if@TF} % \LaTeX\ wrappers on some \TeX\ tests, slightly altered to help with % the logical flow. % \begin{macrocode} \newcommand*{\si@mode@maths@display@if@T}{% \ifmmode \ifinner \expandafter\expandafter\expandafter\@gobble \else \expandafter\expandafter\expandafter\@firstofone \fi \else \expandafter\@gobble \fi } \newcommand*{\si@mode@maths@inline@if@T}{% \ifmmode \ifinner \expandafter\expandafter\expandafter\@firstofone \else \expandafter\expandafter\expandafter\@gobble \fi \else \expandafter\@gobble \fi } \newcommand*{\si@mode@maths@if@F}{% \ifmmode \expandafter\@gobble \else \expandafter\@firstofone \fi } \newcommand*{\si@mode@maths@if@TF}{% \ifmmode \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@edef@c} % Pretty simple. % \begin{macrocode} \newcommand*{\si@edef@c}[1]{% \expandafter\edef\csname #1\endcsname } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@newcommand} %\begin{macro}[aux]{\si@newcommand@aux@i} %\begin{macro}[aux]{\si@newcommand@aux@ii} %\begin{macro}[aux]{\si@newcommand@aux@iii} % To create new commands which are \cs{protected} but which take % optional arguments, as also done in \pkg{biblatex}. % \begin{macrocode} \newcommand*{\si@newcommand}{% \@ifstar{% \let\l@ngrel@x\protected \si@newcommand@aux@i }{% \def\l@ngrel@x{\protected\long}% \si@newcommand@aux@i }% } \newcommand*{\si@newcommand@aux@i}[1]{% \@testopt{\si@newcommand@aux@ii#1}0% } \newcommand*{\si@newcommand@aux@ii}{} \def\si@newcommand@aux@ii#1[#2]{% \@ifnextchar[{% \si@newcommand@aux@iii#1[#2]% }{% \@argdef#1[#2]% }%] } \newcommand*{\si@newcommand@aux@iii}{} \def\si@newcommand@aux@iii#1[#2][#3]#4{% \@ifdefinable#1{% \expandafter\protected\expandafter\def\expandafter#1\expandafter{% \expandafter\@testopt\csname\string#1\endcsname{#3}% }% \expandafter\@yargdef\csname\string#1\endcsname\tw@{#2}{#4}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@nil} %\begin{macro}{\si@stop} % Markers: do not \cs{edef}. % \begin{macrocode} \newcommand*{\si@nil}{\si@nil} \newcommand*{\si@stop}{\si@stop} % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@no@value} %\begin{macro}{\si@no@value@if@F} %\begin{macro}{\si@no@value@if@FT} %\begin{macro}{\si@no@value@if@T} %\begin{macro}{\si@no@value@if@TF} %\begin{macro}[aux]{\si@no@value@if@aux@i} %\begin{macro}[aux]{\si@no@value@if@aux@ii} %\begin{macro}[aux]{\si@no@value@if@aux@iii} %\begin{macro}[aux]{\si@no@value@if@aux@iv} % Empty value tests: a bit complicated. See \pkg{l3basics} for an % explanation of how this works (very clever). % \begin{macrocode} \newcommand*{\si@no@value}{\si@no@value} \newcommand*{\si@no@value@if@F}[1]{% \if\si@no@value@if@aux@i{#1}% \expandafter\@gobble \else \expandafter\@firstofone \fi } \newcommand*{\si@no@value@if@FT}[1]{% \if\si@no@value@if@aux@i{#1}% \expandafter\@secondoftwo \else \expandafter\@firstoftwo \fi } \newcommand*{\si@no@value@if@T}[1]{% \if\si@no@value@if@aux@i{#1}% \expandafter\@firstofone \else \expandafter\@gobble \fi } \newcommand*{\si@no@value@if@TF}[1]{% \if\si@no@value@if@aux@i{#1}% \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } \newcommand*{\si@no@value@if@aux@i}[1]{% \if\expandafter\si@no@value@if@aux@ii\expandafter {\string\si@no@value\space}{\detokenize{#1}}% \si@true@bool \else \si@false@bool \fi } \newcommand*{\si@no@value@if@aux@ii}[1]{% \if\number\si@no@value@if@aux@iii{}{}#1\relax } \newcommand*{\si@no@value@if@aux@iii}[3]{% \if#3\relax \expandafter\si@no@value@if@aux@iv \fi \si@no@value@if@aux@iii{\if#3#1}{#2\fi}% } \newcommand*{\si@no@value@if@aux@iv}{} \def\si@no@value@if@aux@iv\si@no@value@if@aux@iii#1#2#3{% #1#3\relax'#213 \si@true@bool \else \si@false@bool \fi } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@if@F} %\begin{macro}{\si@num@if@T} %\begin{macro}{\si@num@if@TF} % Wrapper macros so that expansion happens first in all cases. These are % more basic than the \LaTeX3 versions, so occasionally the raw % \cs{ifnum} primitive is used in the code. % \begin{macrocode} \newcommand*{\si@num@if@F}[1]{% \ifnum#1\relax \expandafter\@gobble \else \expandafter\@firstofone \fi } \newcommand*{\si@num@if@T}[1]{% \ifnum#1\relax \expandafter\@firstofone \else \expandafter\@gobble \fi } \newcommand*{\si@num@if@TF}[1]{% \ifnum#1\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@replace@all@in} %\begin{macro}[aux]{\si@replace@all@in@aux} %\begin{macro}{\si@replace@all@in@cs} % For searching and replacing. % \begin{macrocode} \newcommand*{\si@replace@all@in}[3]{% \si@reserved@toks{}% \def\si@tempa##1#2##2\si@stop{% \si@no@value@if@TF{##2}{% \si@replace@all@in@aux{##1}% }{% \si@replace@all@in@aux{##1#3}% \si@tempa\@empty##2\si@stop }% }% \@firstofone{\expandafter\si@tempa\expandafter\@empty}% #1#2\si@no@value\si@stop \edef#1{\the\si@reserved@toks}% } \newcommand*{\si@replace@all@in@aux}[1]{% \si@reserved@toks\expandafter\expandafter\expandafter{% \expandafter\the\expandafter\si@reserved@toks#1% }% } \newcommand*{\si@replace@all@in@cs}[1]{% \expandafter\si@replace@all@in\csname #1\endcsname } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@reverse@macro} %\begin{macro}{\si@reverse@cs} %\begin{macro}{\si@reverse@tlist} %\begin{macro}[aux]{\si@reverse@tlist@aux} % The tlist macro here is the same as in \LaTeX3, but the macro version % is simplified as \pkg{siunitx} does not expect to find % non-expandable content. % \begin{macrocode} \newcommand*{\si@reverse@macro}[1]{% \edef#1{% \expandafter\si@reverse@tlist\expandafter{#1}% }% } \newcommand*{\si@reverse@cs}[1]{% \expandafter\si@reverse@macro\csname #1\endcsname } \newcommand*{\si@reverse@tlist}[1]{% \si@reverse@tlist@aux{}#1\si@loop@end\si@loop@stop } \newcommand*{\si@reverse@tlist@aux}[2]{% \si@loop@exec@end@if{#2}{#1}% \si@reverse@tlist@aux{#2#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@stop@if@F} %\begin{macro}{\si@stop@if@T} %\begin{macro}{\si@stop@if@TF} % Some quick tests. % \begin{macrocode} \newcommand*{\si@stop@if@F}[1]{% \si@meaning@eq@if@F#1\si@stop } \newcommand*{\si@stop@if@T}[1]{% \si@meaning@eq@if@T#1\si@stop } \newcommand*{\si@stop@if@TF}[1]{% \si@meaning@eq@if@TF#1\si@stop } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@whiledo@num@T} % A simple looping function. % \begin{macrocode} \newcommand*{\si@whiledo@num@T}[2]{% \si@num@if@T{#1}{% #2\si@whiledo@num@T{#1}{#2}% }% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@whiledo@empty@F} %\begin{macro}{\si@whiledo@empty@T} % Similar for storage macros. % \begin{macrocode} \newcommand*{\si@whiledo@empty@F}[2]{% \si@empty@if@F#1{% #2\si@whiledo@empty@F#1{#2}% }% } \newcommand*{\si@whiledo@empty@T}[2]{% \si@empty@if@T#1{% #2\si@whiledo@empty@T#1{#2}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@whiledo@empty@cs@F} %\begin{macro}{\si@whiledo@empty@cs@T} % Name versions. % \begin{macrocode} \newcommand*{\si@whiledo@empty@cs@F}[2]{% \si@empty@cs@if@F{#1}{% #2\si@whiledo@empty@cs@F{#1}{#2}% }% } \newcommand*{\si@whiledo@empty@cs@T}[2]{% \si@empty@cs@if@T{#1}{% #2\si@whiledo@empty@cs@T{#1}{#2}% }% } % \end{macrocode} %\end{macro} %\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 maths mode, bold can % reliably be applied to maths output. % %\begin{macro}{\si@font@fam@mathsf} %\begin{macro}{\si@font@fam@mathtt} %\begin{macro}{\si@font@fam@detect@maths} % 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} \newcommand*{\si@font@fam@mathsf}{} \newcommand*{\si@font@fam@mathtt}{} \newcommand*{\si@font@fam@detect@maths}[1]{% \begingroup \setbox\@tempboxa\hbox{% \ensuremath{% \csname math#1\endcsname{% \expandafter\global\expandafter\chardef \csname si@font@fam@math#1\endcsname\fam\relax }% }% }% \endgroup } \g@addto@macro{\document}{% \si@font@fam@detect@maths{sf}% \si@font@fam@detect@maths{tt}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@font@fam@sfdefault} %\begin{macro}{\si@font@fam@ttdefault} %\begin{macro}{\si@font@fam@detect@text} % 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} \newcommand*{\si@font@fam@sfdefault}{} \newcommand*{\si@font@fam@ttfamily}{} \newcommand*{\si@font@fam@detect@text}[1]{% \si@edef@c{si@font@fam@#1default}{\@nameuse{#1default}}% } \AtBeginDocument{% \si@font@fam@detect@text{sf}% \si@font@fam@detect@text{tt}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@font@det@b@bool} %\begin{macro}{\si@font@det@family@bool} %\begin{macro}{\si@font@det@maths@display@bool} %\begin{macro}{\si@font@det@maths@inline@bool} %\begin{macro}{\si@font@det@it@bool} %\begin{macro}{\si@font@det@mode@bool} % All of the choices here set switches, which need to be created. % \begin{macrocode} \si@bool@new\si@font@det@b@bool \si@bool@new\si@font@det@family@bool \si@bool@new\si@font@det@maths@display@bool \si@bool@new\si@font@det@maths@inline@bool \si@bool@new\si@font@det@it@bool \si@bool@new\si@font@det@mode@bool % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % The key definitions are not very exciting: almost all are Boolean % with variations in the naming. % \begin{macrocode} \si@keys@family{font/detect} \pgfkeys{ /siunitx/font/detect, all/.style = { /siunitx/font/detect/bold = true, /siunitx/font/detect/family = true, /siunitx/font/detect/italic = true, /siunitx/font/detect/mode = true }, bold/.is siunitx switch = {font@det@b}, display math/.is siunitx switch = {font@det@maths@display}, display maths/.is siunitx switch = {font@det@maths@display}, family/.is siunitx switch = {font@det@family}, inline bold/.is choice, inline bold/.cd, maths/.code = {\si@bool@true\si@font@det@maths@inline@bool}, math/.code = {\si@bool@true\si@font@det@maths@inline@bool}, text/.code = {\si@bool@false\si@font@det@maths@inline@bool}, /siunitx/font/detect, italic/.is siunitx switch = {font@det@it}, mode/.is siunitx switch = {font@det@mode}, none/.style = { /siunitx/font/detect/bold = false, /siunitx/font/detect/family = false, /siunitx/font/detect/italic = false, /siunitx/font/detect/mode = false }, bold = false, display maths = true, inline bold = text, italic = false, mode = false } % \end{macrocode} % %\begin{macro}{\si@font@set@bool} % To avoid testing more than once within an output group, a flag is % needed to indicate that everything is already done. % \begin{macrocode} \si@bool@new\si@font@set@bool % \end{macrocode} %\end{macro} %\begin{macro}{\si@font@set@bold} %\begin{macro}{\si@font@set@family} %\begin{macro}{\si@font@set@italic} % The detection system needs some storage areas for results. % \begin{macrocode} \newcommand*{\si@font@set@bold}{} \newcommand*{\si@font@set@family}{} \newcommand*{\si@font@set@italic}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@font@set@text@bool} % A switch to show the mode. % \begin{macrocode} \si@bool@new\si@font@set@text@bool % \end{macrocode} %\end{macro} % %\begin{macro}{\si@font@det@set} % 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} \newcommand*{\si@font@det@set}{% \si@bool@if@F\si@font@set@bool{% \si@font@det@init \si@bool@if@T\si@font@det@b@bool{% \si@font@det@bold }% \si@bool@if@T\si@font@det@family@bool{% \si@font@det@family }% \si@bool@if@T\si@font@det@it@bool{% \si@font@det@italic }% \si@bool@if@T\si@font@det@mode@bool{% \si@font@det@mode }% }% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@font@det@init} % Set up the basic macros on the assumption nothing happens. % \begin{macrocode} \newcommand*{\si@font@det@init}{% \si@bool@true\si@font@set@bool \def\si@font@set@bold{\unboldmath\mdseries}% \def\si@font@set@family{rm}% \si@bool@false\si@font@set@text@bool \def\si@font@set@italic{\upshape}% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@font@det@bold} % The bold detection code depends on whether the current text is maths % or text, and also the type of maths (if appropriate). For inline % maths, there is a choice of what test to apply. % \begin{macrocode} \newcommand*{\si@font@det@bold}{% \si@mode@maths@display@if@T{% \si@bool@if@TF\si@font@det@maths@display@bool{% \si@font@det@bold@maths }{% \si@font@det@bold@text }% }% \si@mode@maths@inline@if@T{% \si@bool@if@TF\si@font@det@maths@inline@bool{% \si@font@det@bold@maths }{% \si@font@det@bold@text }% }% \si@mode@maths@if@F{% \si@font@det@bold@text }% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@font@det@bold@maths} %\begin{macro}{\si@font@det@bold@text} % The tests for bold depend on whether the module is testing text or % maths content. % \begin{macrocode} \newcommand*{\si@font@det@bold@maths}{% \def\si@tempa{bold}% \si@meaning@eq@if@T\si@tempa\math@version{% \def\si@font@set@bold{\boldmath\bfseries}% }% } \newcommand*{\si@font@det@bold@text}{% \def\si@tempa{b}% \edef\si@tempb{\expandafter\@car\f@series\@nil}% \si@meaning@eq@if@T\si@tempa\si@tempb{% \def\si@font@set@bold{\boldmath\bfseries}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@font@det@family} % Family detection usually picks up the surrounding text. However, for % display maths there are two options, and so a second test may be made. % \begin{macrocode} \newcommand*{\si@font@det@family}{% \si@font@det@fam@text \si@bool@if@T\si@font@det@maths@display@bool{% \si@mode@maths@display@if@T{% \si@font@det@fam@maths }% }% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@font@det@fam@maths} %\begin{macro}{\si@font@det@fam@text} % The two detections routines check if the current font is sans serif or % monospaced. The method used depends on whether the current maths or % text font is of interest. The maths detection routine re-applies the % default (\texttt{rm}), as the text function is always called and may % have changed things. % \begin{macrocode} \newcommand*{\si@font@det@fam@maths}{% \def\si@font@set@family{rm}% \si@num@if@TF{\the\fam=\si@font@fam@mathsf}{% \def\si@font@set@family{sf}% }{% \si@num@if@T{\the\fam=\si@font@fam@mathtt}{% \def\si@font@set@family{tt}% }% }% } \newcommand*{\si@font@det@fam@text}{% \si@meaning@eq@if@T\f@family\si@font@fam@sfdefault{% \def\si@font@set@family{sf}% }% \si@meaning@eq@if@T\f@family\si@font@fam@ttdefault{% \def\si@font@set@family{tt}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@font@det@italic} % The italic test uses \cs{f@shape} as a handy indicator. % \begin{macrocode} \newcommand*{\si@font@det@italic}{% \def\si@tempa{it}% \si@meaning@eq@if@T\si@tempa\f@shape{% \def\si@font@set@italic{\itshape}% }% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@font@det@mode} % The mode switch works from the fact that maths-mode output it the % standard. % \begin{macrocode} \newcommand*{\si@font@det@mode}{% \si@mode@maths@if@F{% \si@bool@true\si@font@set@text@bool }% } % \end{macrocode} %\end{macro} % %\subsection{Font macros} % %\begin{macro}{\si@font@unit@maths@rm} %\begin{macro}{\si@font@unit@maths@sf} %\begin{macro}{\si@font@unit@maths@tt} %\begin{macro}{\si@font@unit@text@rm} %\begin{macro}{\si@font@unit@text@sf} %\begin{macro}{\si@font@unit@text@tt} %\begin{macro}{\si@font@num@maths@rm} %\begin{macro}{\si@font@num@maths@sf} %\begin{macro}{\si@font@num@maths@tt} %\begin{macro}{\si@font@num@text@rm} %\begin{macro}{\si@font@num@text@sf} %\begin{macro}{\si@font@num@text@tt} % 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{macrocode} \newcommand*{\si@font@unit@maths@rm}{} \newcommand*{\si@font@unit@maths@sf}{} \newcommand*{\si@font@unit@maths@tt}{} \newcommand*{\si@font@unit@text@rm}{} \newcommand*{\si@font@unit@text@sf}{} \newcommand*{\si@font@unit@text@tt}{} \newcommand*{\si@font@num@maths@rm}{} \newcommand*{\si@font@num@maths@sf}{} \newcommand*{\si@font@num@maths@tt}{} \newcommand*{\si@font@num@text@rm}{} \newcommand*{\si@font@num@text@sf}{} \newcommand*{\si@font@num@text@tt}{} % \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}{\si@font@unit@textmode@bool} %\begin{macro}{\si@font@num@textmode@bool} % Two switches for mode selection. % \begin{macrocode} \si@bool@new\si@font@unit@textmode@bool \si@bool@new\si@font@num@textmode@bool % \end{macrocode} %\end{macro} %\end{macro} % The font control keys are now created, all as unit and value variants. % \begin{macrocode} \si@keys@family{font} \si@keys@family{font/units} \si@keys@family{font/numbers} \pgfkeys{ /siunitx/font, maths rm/.style = { /siunitx/font/units/maths rm = #1, /siunitx/font/numbers/maths rm = #1 }, maths sf/.style = { /siunitx/font/units/maths sf = #1, /siunitx/font/numbers/maths sf = #1 }, maths tt/.style = { /siunitx/font/units/maths tt = #1, /siunitx/font/numbers/maths tt = #1 }, maths rm/.style = { /siunitx/font/units/maths rm = #1, /siunitx/font/numbers/maths rm = #1 }, maths sf/.style = { /siunitx/font/units/maths sf = #1, /siunitx/font/numbers/maths sf = #1 }, maths tt/.style = { /siunitx/font/units/maths tt = #1, /siunitx/font/numbers/maths tt = #1 }, mode/.is choice, mode/.cd, maths/.style = { /siunitx/font/units/mode = maths, /siunitx/font/numbers/mode = maths }, math/.style = { /siunitx/font/units/mode = maths, /siunitx/font/numbers/mode = maths }, text/.style = { /siunitx/font/units/mode = text, /siunitx/font/numbers/mode = text }, /siunitx/font, text rm/.style = { /siunitx/font/units/text rm = #1, /siunitx/font/numbers/text rm = #1 }, text sf/.style = { /siunitx/font/units/text sf = #1, /siunitx/font/numbers/text sf = #1 }, text tt/.style = { /siunitx/font/units/text tt = #1, /siunitx/font/numbers/text tt = #1 }, /siunitx/font/units, maths rm/.store in = {\si@font@unit@maths@rm}, maths sf/.store in = {\si@font@unit@maths@sf}, maths tt/.store in = {\si@font@unit@maths@tt}, maths rm/.store in = {\si@font@unit@maths@rm}, maths sf/.store in = {\si@font@unit@maths@sf}, maths tt/.store in = {\si@font@unit@maths@tt}, mode/.is choice, mode/.cd, maths/.code = {\si@bool@false\si@font@unit@textmode@bool}, math/.code = {\si@bool@false\si@font@unit@textmode@bool}, text/.code = {\si@bool@true\si@font@unit@textmode@bool}, /siunitx/font/units, text rm/.store in = {\si@font@unit@text@rm}, text sf/.store in = {\si@font@unit@text@sf}, text tt/.store in = {\si@font@unit@text@tt}, /siunitx/font/numbers, maths rm/.store in = {\si@font@num@maths@rm}, maths sf/.store in = {\si@font@num@maths@sf}, maths tt/.store in = {\si@font@num@maths@tt}, maths rm/.store in = {\si@font@num@maths@rm}, maths sf/.store in = {\si@font@num@maths@sf}, maths tt/.store in = {\si@font@num@maths@tt}, mode/.is choice, mode/.cd, maths/.code = {\si@bool@false\si@font@num@textmode@bool}, math/.code = {\si@bool@false\si@font@num@textmode@bool}, text/.code = {\si@bool@true\si@font@num@textmode@bool}, /siunitx/font/numbers, text rm/.store in = {\si@font@num@text@rm}, text sf/.store in = {\si@font@num@text@sf}, text tt/.store in = {\si@font@num@text@tt}, /siunitx/font, maths rm = \mathrm, maths sf = \mathsf, maths tt = \mathtt, mode = maths, text rm = \rmfamily, text sf = \sffamily, text tt = \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}{\si@print@type} % The type of output (\texttt{num} or \texttt{unit}) is always needed. % \begin{macrocode} \newcommand*{\si@print@type}{} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@print} %\begin{macro}{\si@print@num} %\begin{macro}{\si@print@num@o} %\begin{macro}{\si@print@unit} %\begin{macro}{\si@print@unit@o} % The main printing function does everything inside a group, as % there are category code and definition changes to make. First, there % is a check to see if the fonts have already been set. If not, it's % done now. Things are then placed in text mode and sent on. % \begin{macrocode} \newcommand*{\si@print}[2]{% \begingroup \def\si@print@type{#1}% \si@bool@if@F\si@font@set@bool{% \si@font@det@set }% \si@bool@if@F\si@font@det@mode@bool{% \si@bool@cs@if@TF{si@font@#1@textmode@bool}{% \si@bool@true\si@font@set@text@bool }{% \si@bool@false\si@font@set@text@bool }% }% \si@print@codes \text{\si@print@print{#2}}% \endgroup \check@mathfonts } \newcommand*{\si@print@num}{% \si@print{num}% } \newcommand*{\si@print@num@o}[1]{% \expandafter\si@print@num\expandafter{#1}% } \newcommand*{\si@print@unit}{% \si@print{unit}% } \newcommand*{\si@print@unit@o}[1]{% \expandafter\si@print@unit\expandafter{#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@print@codes} % The various active characters for printing are set up and everything % is made safe for output. The definitions need the correct category % codes to apply for the \cs{let}, otherwise the dreaded % \cs{inaccessible} appears. The \cs{endlinechar} change is needed here % otherwise an extra space ends up in the output. % \begin{macrocode} \si@catcode@set{45}{13}% - \si@catcode@set{94}{13}% ^ \si@catcode@set{95}{13}% _ \newcommand*{\si@print@codes}{% \si@catcode@symbols \si@catcode@set{94}{13}% ^ \si@catcode@set{95}{13}% _ \everyeof{\noexpand}% \endlinechar\m@ne\relax \si@bool@if@TF\si@font@set@text@bool{% \si@catcode@set{45}{13}% - \let-\si@print@minus \let_\si@print@sb \let^\si@print@sp \let\textsubscript\si@print@sb \let\textsuperscript\si@print@sp }{% \si@catcode@set{45}{12}% - \let_\sb \let^\sp \let\textsubscript\sb \let\textsuperscript\sp }% } \si@catcode@set{45}{12}% - \si@catcode@set{94}{7}% ^ \si@catcode@set{95}{8}% _ % \end{macrocode} %\end{macro} % %\begin{macro}{\si@print@maths} %\begin{macro}{\si@print@text} % Actually printing is very easy for text, a little more involved for % maths. % \begin{macrocode} \newcommand*{\si@print@maths}[1]{% \ensuremath{% \@nameuse{si@font@\si@print@type @maths@\si@font@set@family}{#1}% }% } \newcommand*{\si@print@text}[1]{#1} % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@print@print} % The various font changes are set up, then the correct printing % function is called. The \cs{scantokens} primitive is here as this % avoids needing to re-\cs{edef} anything. % \begin{macrocode} \newcommand*{\si@print@print}[1]{% \si@font@set@bold \si@font@set@italic \@nameuse{si@font@\si@print@type @text@\si@font@set@family}% \si@bool@if@TF\si@font@set@text@bool{% \si@print@text{\scantokens{#1}}% }{% \si@print@maths{\scantokens{#1}}% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@print@minus} %\begin{macro}{\si@print@minus@symbol} % To allow the correct symbol to appear in text mode: this is the same % as \cs{textminus} from \pkg{textcomp}. % \begin{macrocode} \newcommand*{\si@print@minus}{% \text{\si@print@minus@symbol}% } \DeclareTextSymbolDefault{\si@print@minus@symbol}{TS1} \DeclareTextSymbol{\si@print@minus@symbol}{TS1}{61} % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@print@sb} %\begin{macro}{\si@print@sp} % The appropriate macros for sub- and superscript in text mode ensure % the appearance is the same as maths mode. % \begin{macrocode} \newcommand*{\si@print@sb}[1]{% \ensuremath{_{\text{#1}}}% } \newcommand*{\si@print@sp}[1]{% \ensuremath{^{\text{#1}}}% } % \end{macrocode} %\end{macro} %\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}{\si@num@pre@product} %\begin{macro}{\si@num@pre@quotient} %\begin{macro}{\si@num@pre@tokens} % Storage for the tokens that need to be checked for. % \begin{macrocode} \newcommand*{\si@num@pre@product}{} \newcommand*{\si@num@pre@quotient}{} \newcommand*{\si@num@pre@tokens}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % % The keys here are all considered as part of the input system. % \begin{macrocode} \si@keys@family{numbers/input} \pgfkeys{ /siunitx/numbers/input, product/.store in = {\si@num@pre@product}, quotient/.store in = {\si@num@pre@quotient}, protect tokens/.store in = {\si@num@pre@tokens}, product = x, quotient = /, protect tokens = \mp\pi\pm } % \end{macrocode} % %\begin{macro}{\si@num@pre@arg} %\begin{macro}{\si@num@pre@arg@den} %\begin{macro}{\si@num@pre@arg@held} %\begin{macro}{\si@num@pre@arg@num} % Storage areas for the various parts that may be found. % \begin{macrocode} \newcommand*{\si@num@pre@arg}{} \newcommand*{\si@num@pre@arg@den}{} \newcommand*{\si@num@pre@arg@held}{} \newcommand*{\si@num@pre@arg@num}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@pre@error@bool} % An error flag. % \begin{macrocode} \si@bool@new\si@num@pre@error@bool % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@pre@process} % The pre-processor starts with the obvious: the most likely outcome is % that all of the argument is passed through unchanged. % \begin{macrocode} \newcommand*{\si@num@pre@process}[1]{% \si@num@pre@init \begingroup \si@num@pre@protect@tokens \protected@edef\@tempa{#1}% \expandafter\endgroup\expandafter \def\expandafter\si@num@pre@arg\expandafter{\@tempa}% \si@num@pre@sep@prod \si@num@pre@sep@quot } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@pre@error} % For when something is wrong. % \begin{macrocode} \newcommand*{\si@num@pre@error}{% \si@bool@true\si@num@pre@error@bool \si@log@error } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@pre@init} % The usual storage clearing. % \begin{macrocode} \newcommand*{\si@num@pre@init}{% \si@clear@macro\si@num@pre@arg \si@clear@macro\si@num@pre@arg@den \si@clear@macro\si@num@pre@arg@held \si@clear@macro\si@num@pre@arg@num \si@bool@false\si@num@pre@error@bool } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@pre@protect@tokens} %\begin{macro}[aux]{\si@num@pre@protect@tokens@aux} % Under some circumstances (for example when loading \pkg{breqn}) % some tokens do not behave safely under \cs{protected@edef}. To get % round this, they are redefined here. % \begin{macrocode} \newcommand*{\si@num@pre@protect@tokens}{% \si@loop@over@macro\si@num@pre@tokens\si@num@pre@protect@tokens@aux } \newcommand*{\si@num@pre@protect@tokens@aux}[1]{% \let#1\relax } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@pre@sep@prod} %\begin{macro}[aux]{\si@num@pre@sep@prod@aux} % Rather than search through the entire argument, we use the % delimited-argument trick. No error checks here as there can be an % arbitrary number of products (\emph{quel dommage}). % \begin{macrocode} \newcommand*{\si@num@pre@sep@prod}{% \si@loop@over@macro\si@num@pre@product\si@num@pre@sep@prod@aux } \newcommand*{\si@num@pre@sep@prod@aux}[1]{% \si@in@if@T\si@num@pre@arg{#1}{% \def\si@tempa##1#1##2\si@stop{% \def\si@num@pre@arg{##1}% \def\si@num@pre@arg@held{##2}% }% \expandafter\si@tempa\si@num@pre@arg\si@stop \si@empty@if@T\si@num@pre@arg{% \si@num@pre@error{Misplaced product token}{% A number cannot begin with a product token. }% }% \si@empty@if@T\si@num@pre@arg@held{% \si@num@pre@error{Misplaced product token}{% A number cannot end with a product token. }% }% \si@loop@exit }% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@pre@sep@quot} %\begin{macro}[aux]{\si@num@pre@sep@quot@aux} % For the quotient, only one token can appear in each part. So there % is an error check. % \begin{macrocode} \newcommand*{\si@num@pre@sep@quot}{% \si@loop@over@macro\si@num@pre@quotient\si@num@pre@sep@quot@aux } \newcommand*{\si@num@pre@sep@quot@aux}[1]{% \si@in@if@T\si@num@pre@arg{#1}{% \def\si@tempa##1#1##2\si@stop{% \def\si@num@pre@arg@num{##1}% \def\si@num@pre@arg@den{##2}% }% \expandafter\si@tempa\si@num@pre@arg\si@stop \si@empty@if@T\si@num@pre@arg@num{% \si@num@pre@error{Misplaced quotient token}{% A number cannot begin with a quotient token. }% }% \si@empty@if@T\si@num@pre@arg@den{% \si@num@pre@error{Misplaced quotient token}{% A number cannot end with a quotient token. }% }% \si@in@if@T\si@num@pre@arg@den{#1}{% \si@num@pre@error{Duplicate quotient token}{% Only one quotient token can appear in a single number. }% }% \si@loop@exit }% } % \end{macrocode} %\end{macro} %\end{macro} % %\subsection{Parsing numbers} % % The number parser is designed to work with single numbers, which can % contain exponents, complex parts and uncertainties. In general, % looping over the input is avoided: instead, loops over the check % values are used as these will hopefully be shorter, on average. The % parser will report mathematically invalid numbers here: whether the % input is valid in the context required is left to the calling % function. % %\begin{macro}{\si@num@in@uncert@close} %\begin{macro}{\si@num@in@complex} %\begin{macro}{\si@num@in@decimal} %\begin{macro}{\si@num@in@digits} %\begin{macro}{\si@num@in@exponent} %\begin{macro}{\si@num@in@ignore} %\begin{macro}{\si@num@in@uncert@open} %\begin{macro}{\si@num@in@signs} %\begin{macro}{\si@num@in@symbols} % Storage areas for the various number components. % \begin{macrocode} \newcommand*{\si@num@in@uncert@close}{} \newcommand*{\si@num@in@complex}{} \newcommand*{\si@num@in@decimal}{} \newcommand*{\si@num@in@digits}{} \newcommand*{\si@num@in@exponent}{} \newcommand*{\si@num@in@signs}{} \newcommand*{\si@num@in@symbols}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % The keys which control the package are all concerned with different % tokens to check for. The names are all hopefully obvious. % \begin{macrocode} \pgfkeys{ /siunitx/numbers/input, close uncertainty/.store in = {\si@num@in@uncert@close}, complex roots/.store in = {\si@num@in@complex}, decimal markers/.store in = {\si@num@in@decimal}, digits/.store in = {\si@num@in@digits}, exponent markers/.store in = {\si@num@in@exponent}, ignore/.store in = {\si@num@in@ignore}, open uncertainty/.store in = {\si@num@in@uncert@open}, signs/.store in = {\si@num@in@signs}, symbols/.store in = {\si@num@in@symbols}, %( close uncertainty = ), complex roots = ij, decimal markers = {.,}, digits = 0123456789, exponent markers = dDeE, ignore = {}, open uncertainty = (, %) signs = +-\mp\pm, symbols = \pi } % \end{macrocode} %\begin{macro}{\si@num@in@mant} %\begin{macro}{\si@num@in@mant@sign} %\begin{macro}{\si@num@in@mant@int} %\begin{macro}{\si@num@in@mant@dec} %\begin{macro}{\si@num@in@mant@uncert} %\begin{macro}{\si@num@in@mant@uncert@int} %\begin{macro}{\si@num@in@mant@uncert@dec} %\begin{macro}{\si@num@in@mant@comp} %\begin{macro}{\si@num@in@mant@comp@sign} %\begin{macro}{\si@num@in@mant@comp@int} %\begin{macro}{\si@num@in@mant@comp@dec} %\begin{macro}{\si@num@in@mant@comp@uncert} %\begin{macro}{\si@num@in@mant@comp@uncert@int} %\begin{macro}{\si@num@in@mant@comp@uncert@dec} % Storage areas for the various parts of a mantissa. % \begin{macrocode} \newcommand*{\si@num@in@mant}{} \newcommand*{\si@num@in@mant@sign}{} \newcommand*{\si@num@in@mant@int}{} \newcommand*{\si@num@in@mant@dec}{} \newcommand*{\si@num@in@mant@uncert}{} \newcommand*{\si@num@in@mant@uncert@int}{} \newcommand*{\si@num@in@mant@uncert@dec}{} \newcommand*{\si@num@in@mant@comp}{} \newcommand*{\si@num@in@mant@comp@sign}{} \newcommand*{\si@num@in@mant@comp@int}{} \newcommand*{\si@num@in@mant@comp@dec}{} \newcommand*{\si@num@in@mant@comp@uncert}{} \newcommand*{\si@num@in@mant@comp@uncert@int}{} \newcommand*{\si@num@in@mant@comp@uncert@dec}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@in@exp} %\begin{macro}{\si@num@in@exp@sign} %\begin{macro}{\si@num@in@exp@int} %\begin{macro}{\si@num@in@exp@dec} %\begin{macro}{\si@num@in@exp@uncert} %\begin{macro}{\si@num@in@exp@uncert@int} %\begin{macro}{\si@num@in@exp@uncert@dec} %\begin{macro}{\si@num@in@exp@comp} %\begin{macro}{\si@num@in@exp@comp@sign} %\begin{macro}{\si@num@in@exp@comp@int} %\begin{macro}{\si@num@in@exp@comp@dec} %\begin{macro}{\si@num@in@exp@comp@uncert} %\begin{macro}{\si@num@in@exp@comp@uncert@int} %\begin{macro}{\si@num@in@exp@comp@uncert@dec} % The same for an exponent. % \begin{macrocode} \newcommand*{\si@num@in@exp}{} \newcommand*{\si@num@in@exp@sign}{} \newcommand*{\si@num@in@exp@int}{} \newcommand*{\si@num@in@exp@dec}{} \newcommand*{\si@num@in@exp@uncert}{} \newcommand*{\si@num@in@exp@uncert@int}{} \newcommand*{\si@num@in@exp@uncert@dec}{} \newcommand*{\si@num@in@exp@comp}{} \newcommand*{\si@num@in@exp@comp@sign}{} \newcommand*{\si@num@in@exp@comp@int}{} \newcommand*{\si@num@in@exp@comp@dec}{} \newcommand*{\si@num@in@exp@comp@uncert}{} \newcommand*{\si@num@in@exp@comp@uncert@int}{} \newcommand*{\si@num@in@exp@comp@uncert@dec}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@in@mant@bool} %\begin{macro}{\si@num@in@mant@dec@bool} %\begin{macro}{\si@num@in@mant@uncert@dec@bool} %\begin{macro}{\si@num@in@mant@comp@bool} %\begin{macro}{\si@num@in@mant@comp@dec@bool} %\begin{macro}{\si@num@in@mant@comp@uncert@dec@bool} %\begin{macro}{\si@num@in@exp@bool} %\begin{macro}{\si@num@in@exp@dec@bool} %\begin{macro}{\si@num@in@exp@uncert@dec@bool} %\begin{macro}{\si@num@in@exp@comp@bool} %\begin{macro}{\si@num@in@exp@comp@dec@bool} %\begin{macro}{\si@num@in@exp@comp@uncert@dec@bool} % Flags for quick detection of parts; for complex numbers, this is % essential as you can just have the complex root ($\mathrm{i}$). % The \texttt{@dec} switches are used as the package may need to know % the difference between \texttt{1} and \texttt{1.}, for example. % \begin{macrocode} \si@bool@new\si@num@in@mant@bool \si@bool@new\si@num@in@mant@dec@bool \si@bool@new\si@num@in@mant@uncert@dec@bool \si@bool@new\si@num@in@mant@comp@bool \si@bool@new\si@num@in@mant@comp@dec@bool \si@bool@new\si@num@in@mant@comp@uncert@dec@bool \si@bool@new\si@num@in@exp@bool \si@bool@new\si@num@in@exp@dec@bool \si@bool@new\si@num@in@exp@uncert@dec@bool \si@bool@new\si@num@in@exp@comp@bool \si@bool@new\si@num@in@exp@comp@dec@bool \si@bool@new\si@num@in@exp@comp@uncert@dec@bool % \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}{\si@num@in@symbols@bool} % A flag is set if the input given contains ``symbolic'' tokens: this % information is useful later on. % \begin{macrocode} \si@bool@new\si@num@in@symbols@bool % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@in@arg} % The argument given to the parser is stored and manipulated here. % \begin{macrocode} \newcommand*{\si@num@in@arg}{} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@in@error@bool} % A flag for errors. % \begin{macrocode} \si@bool@new\si@num@in@error@bool % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@in@parse} %\begin{macro}{\si@num@in@parse@o} % The master control for parsing numbers is mainly a list of functions % to carry out. Things are kept very simple here. A variant is also % provided for data which needs to be expanded once (\LaTeX3-inspired). % \begin{macrocode} \newcommand*{\si@num@in@parse}[1]{% \si@num@in@init \si@num@in@rescan{#1}% \si@empty@if@TF\si@num@in@arg{% \si@bool@true\si@num@in@error@bool }{% \si@num@in@arg@loop \si@num@in@try{\si@num@in@separate}% \si@num@in@try{\si@num@in@finalise}% }% } \newcommand*{\si@num@in@parse@o}[1]{% \expandafter\si@num@in@parse\expandafter{#1}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@in@add} % For adding a token to one of the storage areas. % \begin{macrocode} \newcommand*{\si@num@in@add}[1]{% \si@add@right@cs@n{si@num@in@#1}% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@in@arg@loop} %\begin{macro}[aux]{\si@num@in@arg@loop@aux} % The entire argument is looped over. Three tasks take place here, to % keep down the number of loops. First, a check is made that the input % token is valid. The input stream is re-written to remove ignored % tokens, and finally a check is made to see if ``symbolic'' tokens are % present in the input. % \begin{macrocode} \newcommand*{\si@num@in@arg@loop}{% \si@expand@tlist\si@tempa{% \si@num@in@signs \si@num@in@ignore \si@num@in@digits \si@num@in@decimal \si@num@in@exponent \si@num@in@complex \si@num@in@symbols \si@num@in@uncert@open \si@num@in@uncert@close }% \si@clear@macro\si@tempb \si@loop@over@macro\si@num@in@arg\si@num@in@arg@loop@aux \si@num@in@try{\let\si@num@in@arg\si@tempb}% } \newcommand*{\si@num@in@arg@loop@aux}[1]{% \si@in@if@F\si@tempa{#1}{% \si@num@in@throw{Invalid token `#1' in numerical input}{% Only the tokens: \MessageBreak \si@tempa \MessageBreak are valid for numerical input. }% \si@loop@exit }% \si@in@if@F\si@num@in@ignore{#1}{% \si@add@right@n\si@tempb{#1}% }% \si@in@if@T\si@num@in@symbols{#1}{% \si@bool@true\si@num@in@symbols@bool }% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@in@finalise} %\begin{macro}{\si@num@in@final@check} % The finalisation system starts with a series of error checks for % invalid numbers. If they all pass, there are a few bits of tidying up % to do. % \begin{macrocode} \newcommand*{\si@num@in@finalise}{% \si@num@in@final@check \si@num@in@try{\si@num@in@final@tidy}% } \newcommand*{\si@num@in@final@check}{% \si@bool@true\si@num@in@mant@bool \si@empty@if@T\si@num@in@mant@dec{% \si@empty@if@T\si@num@in@mant@int{% \si@bool@false\si@num@in@mant@bool \si@empty@if@F\si@num@in@mant@uncert{% \si@num@in@throw{Uncertainty but no number}{% The mantissa contains only an uncertainty. }% }% }% }% \si@bool@if@T\si@num@in@mant@comp@bool{% \si@empty@if@T\si@num@in@mant@comp@dec{% \si@empty@if@T\si@num@in@mant@comp@int{% \si@empty@if@F\si@num@in@mant@comp@uncert{% \si@num@in@throw{Uncertainty but no number}{% The complex mantissa contains only an uncertainty. }% }% }% }% }% \si@bool@true\si@num@in@exp@bool \si@empty@if@T\si@num@in@exp@dec{% \si@empty@if@T\si@num@in@exp@int{% \si@bool@false\si@num@in@exp@bool \si@empty@if@F\si@num@in@exp@uncert{% \si@num@in@throw{Uncertainty but no number}{% The exponent contains only an uncertainty. }% }% \si@empty@if@F\si@num@in@exp@sign{% \si@num@in@throw{Sign but no exponent}{% The exponent contains only a sign. }% }% }% }% \si@bool@if@T\si@num@in@exp@comp@bool{% \si@empty@if@T\si@num@in@exp@comp@dec{% \si@empty@if@T\si@num@in@exp@comp@int{% \si@empty@if@F\si@num@in@exp@comp@uncert{% \si@num@in@throw{Uncertainty but no number}{% The complex exponent contains only an uncertainty. }% }% }% }% }% \si@bool@if@F\si@num@in@mant@bool{% \si@bool@if@F\si@num@in@mant@comp@bool{% \si@bool@if@F\si@num@in@exp@bool{% \si@bool@if@F\si@num@in@exp@comp@bool{% \si@num@in@throw{Empty numerical argument}{% The given `number' contains no information. }% }% }% }% }% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@in@finalise@tidy} %\begin{macro}[aux]{\si@num@in@finalise@tidy@aux} % There are some minor bits of tidying up to do now. Two issues need to % be handled, both concerned with zero. % \begin{macrocode} \newcommand*{\si@num@in@final@tidy}{% \si@num@in@final@tidy@aux{mant}% \si@num@in@final@tidy@aux{exp}% } \newcommand*{\si@num@in@final@tidy@aux}[1]{% \si@num@in@remove@zeros{#1}% \si@num@in@remove@zeros{#1@comp}% \si@num@in@zero@sign{#1}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@in@init} %\begin{macro}[aux]{\si@num@in@init@aux} %\begin{macro}{\si@num@in@init@names} % The various storage areas are all cleared \emph{en masse}. % \begin{macrocode} \newcommand*{\si@num@in@init}{% \si@bool@false\si@num@in@error@bool \si@bool@false\si@num@in@symbols@bool \si@loop@over@macro\si@num@in@init@names\si@num@in@init@aux \si@bool@false\si@num@in@mant@bool \si@bool@false\si@num@in@mant@dec@bool \si@bool@false\si@num@in@mant@uncert@dec@bool \si@bool@false\si@num@in@mant@comp@bool \si@bool@false\si@num@in@mant@comp@dec@bool \si@bool@false\si@num@in@mant@comp@uncert@dec@bool \si@bool@false\si@num@in@exp@bool \si@bool@false\si@num@in@exp@dec@bool \si@bool@false\si@num@in@exp@uncert@dec@bool \si@bool@false\si@num@in@exp@comp@bool \si@bool@false\si@num@in@exp@comp@dec@bool \si@bool@false\si@num@in@exp@comp@uncert@dec@bool } \newcommand*{\si@num@in@init@aux}[1]{% \si@clear@cs{si@num@in@#1}% } \newcommand*{\si@num@in@init@names}{% {mant}% {mant@sign}% {mant@int}% {mant@dec}% {mant@uncert}% {mant@uncert@int}% {mant@uncert@dec}% {mant@comp}% {mant@comp@sign}% {mant@comp@int}% {mant@comp@dec}% {mant@comp@uncert}% {mant@comp@uncert@int}% {mant@comp@uncert@dec}% {exp}% {exp@sign}% {exp@int}% {exp@dec}% {exp@uncert}% {exp@uncert@int}% {exp@uncert@dec}% {exp@comp}% {exp@comp@sign}% {exp@comp@int}% {exp@comp@dec}% {exp@comp@uncert}% {exp@comp@uncert@int}% {exp@comp@uncert@dec}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@in@protect@tokens} % The same as for the \texttt{pre} section, so a simple \cs{let}. % \begin{macrocode} \newcommand*{\si@num@in@protect@tokens}{} \let\si@num@in@protect@tokens\si@num@pre@protect@tokens % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@in@remove@zeros} % Here, any leading zeros are found in the integer part of the number. % By constructing the loop in this way, every character in the input % does not have to be tested. % \begin{macrocode} \newcommand*{\si@num@in@remove@zeros}[1]{% \si@in@cs@if@T{si@num@in@#1@int}{0}{% \def\si@tempa##10##2\si@stop{% \si@empty@tlist@if@TF{##1}{% \si@in@tlist@if@TF{##2}{0}{% \si@tempa##2\si@stop }{% \@namedef{si@num@in@#1@int}{##2}% }% }{% \@namedef{si@num@in@#1@int}{##10##2}% }% }% \si@let@Nc\si@tempb{si@num@in@#1@int}% \expandafter\si@tempa\si@tempb\si@stop \si@empty@cs@if@T{si@num@in@#1@int}{% \@namedef{si@num@in@#1@int}{0}% }% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@in@rescan} % The user input is re-scanned to ensure the correct category codes % and to remove spaces. Everything is done in the usual group so that % the changes are local, with the result ending up in % \cs{si@num@in@arg}. % \begin{macrocode} \newcommand*{\si@num@in@rescan}[1]{% \begingroup \si@catcode@symbols \si@catcode@set{9}{9}% tab ignored \si@catcode@set{32}{9}% space ignored \si@catcode@set{126}{9}% tilde ignored \everyeof{\noexpand}% \si@clear@macro{\,}% \si@num@in@protect@tokens \protected@edef\@tempa{\scantokens{#1}}% \expandafter\endgroup\expandafter \def\expandafter\si@num@in@arg\expandafter{\@tempa}% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@in@separate} %\begin{macro}[aux]{\si@num@in@separate@aux} % The main separator macro divides the input into the various parts. % As everything is done for the mantissa and the exponent, an auxiliary % function is used to keep the code shorter. % \begin{macrocode} \newcommand*{\si@num@in@separate}{% \si@num@in@try{\si@num@in@sep@exp}% \si@num@in@separate@aux{mant}% \si@num@in@separate@aux{exp}% } \newcommand*{\si@num@in@separate@aux}[1]{% \si@num@in@try{\si@num@in@sep@sign{#1}}% \si@num@in@try{\si@num@in@sep@comp{#1}}% \si@num@in@try{\si@num@in@sep@dec{#1}}% \si@num@in@try{\si@num@in@sep@dec@comp{#1}}% \si@num@in@try{\si@num@in@sep@uncert{#1}}% \si@num@in@try{\si@num@in@sep@uncert{#1@comp}}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@in@sep@comp} %\begin{macro}[aux]{\si@num@in@sep@comp@aux@i} %\begin{macro}[aux]{\si@num@in@sep@comp@aux@ii} %\begin{macro}[aux]{\si@num@in@sep@comp@aux@iii} %\begin{macro}[aux]{\si@num@in@sep@comp@aux@iiv} % Finding a valid complex number is a two stage process. The first part % is to look for a complex root at the end of the number. If one is % found, look for a sign dividing the real and imaginary parts. If % the number is not complex, then any sign tokens are invalid. % \begin{macrocode} \newcommand*{\si@num@in@sep@comp}[1]{% \si@empty@cs@if@F{si@num@in@#1}{% \si@empty@if@F\si@num@in@complex{% \si@let@Nc\si@tempa{si@num@in@#1}% \si@bool@false\si@tmp@bool \si@loop@over@macro\si@num@in@complex\si@num@in@sep@comp@aux@i \si@num@in@try{\si@num@in@sep@comp@aux@ii{#1}}% \si@num@in@try{\si@num@in@sep@comp@aux@iii{#1}}% }% }% } % \end{macrocode} % To avoid needing to use a second loop to check for the last letter, % a bit of trickery. If |##2| is \cs{si@no@value}, then the number does % not contain the root at all. If the root has been found, then |##3| % will be \cs{si@no@value} only if there is a misplaced root sign. % \begin{macrocode} \newcommand*{\si@num@in@sep@comp@aux@i}[1]{% \def\si@tempb##1#1##2##3\si@stop{% \si@no@value@if@F{##2}{% \si@no@value@if@TF{##3}{% \si@bool@true\si@tmp@bool \def\si@tempa{##1}% \si@loop@exit }{% \si@num@in@throw{Misplaced complex root}{% The complex root token `#1' can only come at \MessageBreak the end of a number. }% \si@loop@exit }% }% }% \expandafter\si@tempb\si@tempa#1\si@no@value\si@stop } % \end{macrocode} % The second part of the system has to look for a sign, then do some % tidying up. It starts by moving the data from the test above back to % the correct place. The start-off tests are done against the temporary % variables, as this keeps down the name use. % \begin{macrocode} \newcommand*{\si@num@in@sep@comp@aux@ii}[1]{% \si@let@cN{si@num@in@#1@comp@bool}\si@tmp@bool \si@let@cN{si@num@in@#1}\si@tempa \si@bool@if@T\si@tmp@bool{% \si@empty@if@F\si@tempa{% \def\si@tempb##1{% \si@in@if@TF\si@num@in@signs{##1}{% \si@bool@if@TF\si@tmp@bool{% \si@num@in@throw{Duplicate sign found}{% Only a single sign can be given \MessageBreak in the complex part of a number. }% \si@loop@exit }{% \si@num@in@add{#1@comp@sign}{##1}% \si@bool@true\si@tmp@bool }% }{% \si@bool@if@TF\si@tmp@bool{% \si@num@in@add{#1@comp}{##1}% }{% \si@num@in@add{#1}{##1}% }% }% }% \si@bool@false\si@tmp@bool \si@clear@cs{si@num@in@#1}% \si@loop@over@macro\si@tempa\si@tempb }% }% } % \end{macrocode} % A macro to tidy up the various possible combinations. If there is % a complex part, then a search will have occurred for a sign. It is % possible that no sign was found, in which case the entire number % should be complex. On the other hand, if there was no complex part % then a check is made for duplicated signs. % \begin{macrocode} \newcommand*{\si@num@in@sep@comp@aux@iii}[1]{% \si@bool@cs@if@TF{si@num@in@#1@comp@bool}{% \si@bool@if@F\si@tmp@bool{% \si@let@cc{si@num@in@#1@comp@sign}{si@num@in@#1@sign}% \si@clear@cs{si@num@in@#1@sign}% \si@let@cc{si@num@in@#1@comp}{si@num@in@#1}% \si@clear@cs{si@num@in@#1}% }% }{% \expandafter\si@loop@over@macro\csname si@num@in@#1\endcsname \si@num@in@sep@aux@iv }% } \newcommand*{\si@num@in@sep@aux@iv}[1]{% \si@in@if@T\si@num@in@signs{#1}{% \si@num@in@throw{Duplicate sign found}{% Only a single sign can be given \MessageBreak in the real part of a number. }% \si@loop@exit }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@in@sep@dec} %\begin{macro}{\si@num@in@sep@dec@comp} %\begin{macro}[aux]{\si@num@in@sep@dec@aux@i} %\begin{macro}[aux]{\si@num@in@sep@dec@aux@ii} % The real and complex parts need a slightly different lead-off test % here. % \begin{macrocode} \newcommand*{\si@num@in@sep@dec}[1]{% \si@empty@cs@if@F{si@num@in@#1}{% \si@num@in@sep@dec@aux@i{#1}% }% } \newcommand*{\si@num@in@sep@dec@comp}[1]{% \si@bool@cs@if@T{si@num@in@#1@comp@bool}{% \si@empty@cs@if@TF{si@num@in@#1@comp}{% \si@let@cc{si@num@in@#1@comp@int}{si@num@in@#1@comp}% \si@let@cN{si@num@in@#1@comp}% }{% \si@num@in@sep@dec@aux@i{#1@comp}% }% }% } % \end{macrocode} % The main part of the integer--decimal separator avoids a loop. Only a % single token can be given, and this can be used to find the two parts % rapidly. If there is no marker, then \cs{si@tempb} is always empty and % so the decimal part ends up correct. % \begin{macrocode} \newcommand*{\si@num@in@sep@dec@aux@i}[1]{% \si@let@Nc\si@tempa{si@num@in@#1}% \si@clear@macro\si@tempb \si@bool@false\si@tmp@bool \si@clear@cs{si@num@in@#1}% \si@loop@over@macro\si@num@in@decimal\si@num@in@sep@dec@aux@ii \si@num@in@try{\si@let@cN{si@num@in@#1@int}\si@tempa}% \si@num@in@try{\si@let@cN{si@num@in@#1@dec}\si@tempb}% \si@num@in@try{\si@let@cN{si@num@in@#1@dec@bool}\si@tmp@bool}% } \newcommand*{\si@num@in@sep@dec@aux@ii}[1]{% \si@in@if@T\si@tempa{#1}{% \si@bool@true\si@tmp@bool \def\si@tempb##1#1##2\si@stop{% \def\si@tempa{##1}% \def\si@tempb{##2}% }% \expandafter\si@tempb\si@tempa\si@stop \si@in@if@T\si@tempb{#1}{% \si@num@in@throw{Duplicate decimal token found}{% Only a single decimal marker token can be given \MessageBreak in numerical input. }% }% \si@loop@exit }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@in@sep@exp} %\begin{macro}[aux]{\si@num@in@sep@exp@aux} % The separation here follows the same path as the integer--decimal % part, except that the macro names are known and so the temporary % variables are not needed. % \begin{macrocode} \newcommand*{\si@num@in@sep@exp}{% \let\si@num@in@mant\si@num@in@arg \si@loop@over@macro\si@num@in@exponent\si@num@in@sep@exp@aux } \newcommand*{\si@num@in@sep@exp@aux}[1]{% \si@in@if@T\si@num@in@arg{#1}{% \def\si@tempa##1#1##2\si@stop{% \def\si@num@in@mant{##1}% \def\si@num@in@exp{##2}% }% \expandafter\si@tempa\si@num@in@arg\si@stop \si@in@if@T\si@num@in@exp{#1}{% \si@num@in@throw{Duplicate exponent token found}{% Only a single exponent marker token can be given \MessageBreak in numerical input. }% }% \si@loop@exit }% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@in@sep@sign} %\begin{macro}[aux]{\si@num@in@sep@sign@aux} % Separating signs first converts ``\texttt{+-}'' to \cs{pm} and % ``\texttt{-+}'' to \cs{mp} before looking for a single-token sign. % This is done using the fact that only the very first token needs to be % examined. % \begin{macrocode} \newcommand*{\si@num@in@sep@sign}[1]{% \si@empty@cs@if@F{si@num@in@#1}{% \si@replace@all@in@cs{si@num@in@#1}{-+}{\mp}% \si@replace@all@in@cs{si@num@in@#1}{+-}{\pm}% \expandafter\expandafter\expandafter\si@num@in@sep@sign@aux \csname si@num@in@#1\endcsname\si@stop{#1}% }% } \newcommand*{\si@num@in@sep@sign@aux}{} \def\si@num@in@sep@sign@aux#1#2\si@stop#3{% \si@in@if@TF\si@num@in@signs{#1}{% \@namedef{si@num@in@#3@sign}{#1}% \@namedef{si@num@in@#3}{#2}% }{% \@namedef{si@num@in@#3}{#1#2}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@in@sep@uncert} %\begin{macro}[aux]{\si@num@in@sep@uncert@aux@i} %\begin{macro}[aux]{\si@num@in@sep@uncert@aux@ii} %\begin{macro}[aux]{\si@num@in@sep@uncert@aux@iii} %\begin{macro}[aux]{\si@num@in@sep@uncert@aux@iv} %\begin{macro}[aux]{\si@num@in@sep@uncert@aux@v} %\begin{macro}[aux]{\si@num@in@sep@uncert@aux@vi} % Finding any uncertainty depends on whether there is a decimal % part. % \begin{macrocode} \newcommand*{\si@num@in@sep@uncert}[1]{% \si@empty@cs@if@TF{si@num@in@#1@dec}{% \si@empty@cs@if@F{si@num@in@#1@int}{% \si@num@in@sep@uncert@aux@i{#1}{int}% }% }{% \si@num@in@sep@uncert@aux@i{#1}{dec}% \si@num@in@sep@uncert@check@int{#1}% }% } % \end{macrocode} % A check is made first for the closing symbol: it must be at the end of % the number, and so is relatively easy to find. % \begin{macrocode} \newcommand*{\si@num@in@sep@uncert@aux@i}[2]{% \si@let@Nc\si@tempa{si@num@in@#1@#2}% \si@loop@over@macro\si@num@in@uncert@close\si@num@in@sep@uncert@aux@ii \si@num@in@try{\si@num@in@sep@uncert@aux@iii{#1}{#2}}% } % \end{macrocode} % Here, |##2| will have a value if a marker has been found. Then, % |##3| will have no value if everything is correct. If |##3| has a % value, then the marker is misplaced (not at the end): this also % covers duplicated closing markers. % \begin{macrocode} \newcommand*{\si@num@in@sep@uncert@aux@ii}[1]{% \def\si@tempb##1#1##2##3\si@stop{% \si@no@value@if@F{##2}{% \si@no@value@if@TF{##3}{% \si@bool@true\si@tmp@bool \def\si@tempa{##1}% \si@loop@exit }{% \si@num@in@throw{Misplaced closing uncertainty token}{% The closing uncertainty token `#1' can only \MessageBreak come at the end of a number. }% \si@loop@exit }% }% }% \si@bool@false\si@tmp@bool \expandafter\si@tempb\si@tempa#1\si@no@value\si@stop \si@bool@if@T\si@tmp@bool{% \si@loop@exit }% } % \end{macrocode} % Now to look for the opening character, or perhaps make sure one is % not present. % \begin{macrocode} \newcommand*{\si@num@in@sep@uncert@aux@iii}[2]{% \si@bool@if@TF\si@tmp@bool{% \si@bool@false\si@tmp@bool \si@loop@over@macro\si@num@in@uncert@open \si@num@in@sep@uncert@aux@iv \si@num@in@try{\si@num@in@sep@uncert@aux@v{#1}{#2}}% }{% \si@loop@over@macro\si@num@in@uncert@open \si@num@in@sep@uncert@aux@vi }% } % \end{macrocode} % Here, |##1| contains the main part of the number, and |##2| should % contain the uncertainty. If there is a stray opening token, it will % appear in |##2|. % \begin{macrocode} \newcommand*{\si@num@in@sep@uncert@aux@iv}[1]{% \si@in@if@T\si@tempa{#1}{% \si@bool@true\si@tmp@bool \def\si@tempb##1#1##2\si@stop{% \def\si@tempa{##1}% \def\si@tempb{##2}% }% \expandafter\si@tempb\si@tempa\si@stop \si@in@if@T\si@tempb{#1}{% \si@num@in@throw{Duplicate opening uncertainty token found}{% Only a single opening uncertainty token can be \MessageBreak given in numerical input. }% }% \si@loop@exit }% } % \end{macrocode} % Two ``tidy up'' functions to make sure everything makes sense. % \begin{macrocode} \newcommand*{\si@num@in@sep@uncert@aux@v}[2]{% \si@bool@if@TF\si@tmp@bool{% \si@let@cN{si@num@in@#1@#2}\si@tempa \si@let@cN{si@num@in@#1@uncert}\si@tempb \si@empty@if@T\si@tempb{% \si@num@in@throw{Empty uncertainty given}{% The number given contains an empty uncertainty. }% }% }{% \si@num@in@throw{% Closing uncertainty token without matching opening% }{% The final token of a the number is a closing \MessageBreak uncertainty token, but no opening token was found \MessageBreak in this part of the number. }% }% } \newcommand*{\si@num@in@sep@uncert@aux@vi}[1]{% \si@in@if@T\si@tempa{#1}{% \si@num@in@throw{% Opening uncertainty token without matching closing% }{% The opening uncertainty token `#1' was found with no \MessageBreak matching closing token. }% \si@loop@exit }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@in@sep@uncert@check@int} %\begin{macro}[aux]{\si@num@in@sep@uncert@check@int@aux} % For a number containing a decimal part, there is a need to check that % the integer part does not contain any error. % \begin{macrocode} \newcommand*{\si@num@in@sep@uncert@check@int}[1]{% \def\si@num@in@sep@uncert@check@int@aux##1{% \si@in@cs@if@T{si@num@in@#1@int}{##1}{% \si@num@in@throw{Uncertainty in integer part}{% The opening uncertainty token `##1' was found in the \MessageBreak integer part of the input, but a decimal part was also given. }% \si@loop@exit }% }% \si@loop@over@macro\si@num@in@uncert@open \si@num@in@sep@uncert@check@int@aux \si@loop@over@macro\si@num@in@uncert@close \si@num@in@sep@uncert@check@int@aux } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@in@throw} % Throw an error. % \begin{macrocode} \newcommand*{\si@num@in@throw}{% \si@bool@true\si@num@in@error@bool \si@log@error } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@in@try} % So that the parser stops on the first error, a guard macro is used. % \begin{macrocode} \newcommand*{\si@num@in@try}{% \si@bool@if@F\si@num@in@error@bool } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@in@zero@sign} %\begin{macro}[aux]{\si@num@in@zero@sign@aux@i} %\begin{macro}[aux]{\si@num@in@zero@sign@aux@ii} % The number zero does not take a sign. The test is complicated by some % issues. First, the check for complex numbers needs to ensure that it % only fires if there is no real part. % \begin{macrocode} \newcommand*{\si@num@in@zero@sign}[1]{% \si@bool@cs@if@TF{si@num@in@#1@bool}{% \si@num@in@zero@sign@aux@i{#1}% }{% \si@num@in@zero@sign@aux@i{#1@comp}% }% } % \end{macrocode} % The integer part of the problem is easy: it will just be zero if there % is no value. However, the decimal part can be an arbitrary number of % zeros. % \begin{macrocode} \newcommand*{\si@num@in@zero@sign@aux@i}[1]{% \si@empty@cs@if@TF{si@num@in@#1@int}{% \si@num@in@zero@sign@aux@ii{#1}% }{% \def\si@tempa{0}% \si@meaning@eq@cs@if@T{si@tempa}{si@num@in@#1@int}{% \si@num@in@zero@sign@aux@ii{#1}% }% }% } \newcommand*{\si@num@in@zero@sign@aux@ii}[1]{% \si@empty@cs@if@TF{si@num@in@#1@dec}{% \si@clear@cs{si@num@in@#1@sign}% }{% \def\si@tempa{0}% \def\si@tempb##1{% \si@in@if@F\si@tempa{##1}{% \si@bool@false\si@tmp@bool }% }% \si@bool@true\si@tmp@bool \si@loop@over@cs{si@num@in@#1@dec}\si@tempb \si@bool@if@T\si@tmp@bool{% \si@clear@cs{si@num@in@#1@sign}% }% }% } % \end{macrocode} %\end{macro} %\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 ``formatting'': this is left for the output part of the system. % %\begin{macro}{\si@num@post@sign@token} % Storage for processing variables. % \begin{macrocode} \newcommand*{\si@num@post@sign@token}{} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@post@plus@bool} %\begin{macro}{\si@num@post@rnd@figures@bool} %\begin{macro}{\si@num@post@rnd@places@bool} %\begin{macro}{\si@num@post@sign@bool} %\begin{macro}{\si@num@post@zero@dec@bool} %\begin{macro}{\si@num@post@zero@exp@bool} %\begin{macro}{\si@num@post@zero@int@bool} % Flags for processing. % \begin{macrocode} \si@bool@new\si@num@post@plus@bool \si@bool@new\si@num@post@rnd@figures@bool \si@bool@new\si@num@post@rnd@places@bool \si@bool@new\si@num@post@sign@bool \si@bool@new\si@num@post@zero@dec@bool \si@bool@new\si@num@post@zero@exp@bool \si@bool@new\si@num@post@zero@int@bool % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@figures} %\begin{macro}{\si@num@post@places} % Rounding targets are stored as numbers. % \begin{macrocode} \newcount\si@num@post@figures \newcount\si@num@post@places % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@dec} %\begin{macro}{\si@num@rnd@int} % When carrying out the rounding procedures, a couple of storage % areas are needed. % \begin{macrocode} \newcommand*{\si@num@post@dec}{} \newcommand*{\si@num@post@int}{} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@carry@bool} %\begin{macro}{\si@num@post@sig@bool} % For the rounding system. % \begin{macrocode} \si@bool@new\si@num@post@carry@bool \si@bool@new\si@num@post@sig@bool % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@rnd@tens} %\begin{macro}{\si@num@post@rnd@cnt} % The rounding system needs various storage areas. % \begin{macrocode} \newcommand*{\si@num@post@rnd@tens}{} \newcount\si@num@post@rnd@cnt % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@dec@cnt} %\begin{macro}{\si@num@post@uncert@cnt} % When separating out uncertainties there is a need to store the lengths % of various items. % \begin{macrocode} \newcount\si@num@post@dec@cnt \newcount\si@num@post@uncert@cnt % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@rnd@check} % A short validation macro. % \begin{macrocode} \newcommand*{\si@num@post@rnd@check}[2]{% \@nameuse{si@num@post@#1}#2\relax \expandafter\ifnum\csname si@num@post@#1\endcsname<\z@\relax \si@log@error{Invalid input for rounding digits}{% The input for option 'numbers/process/round #1' \MessageBreak must be a positive integer. }% \fi } % \end{macrocode} %\end{macro} % The options are set up. % \begin{macrocode} \si@keys@family{numbers/process} \pgfkeys{ /siunitx/numbers/process, add zero decimal/.is siunitx switch = {num@post@zero@dec}, add zero integer/.is siunitx switch = {num@post@zero@int}, explicit sign/.store in = {\si@num@post@sign@token}, include explicit sign/.is siunitx switch = {num@post@sign}, retain explicit plus/.is siunitx switch = {num@post@plus}, retain zero exponent/.is siunitx switch = {num@post@zero@exp}, round mode/.is choice, round mode/.cd, figures/.code = {% \si@bool@true\si@num@post@rnd@figures@bool \si@bool@false\si@num@post@rnd@places@bool }, off/.code = {% \si@bool@false\si@num@post@rnd@figures@bool \si@bool@false\si@num@post@rnd@places@bool }, places/.code = {% \si@bool@false\si@num@post@rnd@figures@bool \si@bool@true\si@num@post@rnd@places@bool }, /siunitx/numbers/process, round figures/.code = {\si@num@post@rnd@check{figures}{#1}}, round places/.code = {\si@num@post@rnd@check{places}{#1}}, add zero decimal = true, add zero integer = true, explicit sign = +, include explicit sign = false, retain explicit plus = false, retain zero exponent = false, round mode = off, round figures = 2, round places = 2 } % \end{macrocode} % %\begin{macro}{\si@num@post@process} % Post-processing is a series of small tasks. % \begin{macrocode} \newcommand*{\si@num@post@process}{% \si@num@post@sign \si@num@post@zero@fill \si@num@post@exponent \si@bool@if@F\si@num@in@symbols@bool{% \si@num@post@round \si@bool@if@F\si@num@post@rnd@figures@bool{% \si@bool@if@F\si@num@post@rnd@places@bool{% \si@num@post@uncert }% }% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@post@add@sign} %\begin{macro}[aux]{\si@num@post@add@sign@aux} % Adding a sign to an existing number needs a couple of tests and % saves code with an auxiliary function. % \begin{macrocode} \newcommand*{\si@num@post@add@sign}[1]{% \si@bool@cs@if@TF{si@num@in@#1@bool}{% \si@num@post@add@sign@aux{#1}% }{% \si@bool@cs@if@T{si@num@in@#1@comp@bool}{% \si@num@post@add@sign@aux{#1@comp}% }% }% } \newcommand*{\si@num@post@add@sign@aux}[1]{% \si@empty@cs@if@T{si@num@in@#1@sign}{% \@namedef{si@num@in@#1@sign}{\si@num@post@sign@token}% }% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@post@exponent} % 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} \newcommand*{\si@num@post@exponent}{% \si@bool@if@F\si@num@post@zero@exp@bool{% \si@expand@tlist\si@tempa{% \si@num@in@exp@int \si@num@in@exp@dec \si@num@in@exp@comp@int \si@num@in@exp@comp@dec }% \si@in@if@T\si@tempa{0}{% \def\si@tempb##10000##2\si@stop{% \si@empty@tlist@if@T{##1}{% \def\si@num@in@exp@int{}% \def\si@num@in@exp@dec{}% \def\si@num@in@exp@comp@int{}% \def\si@num@in@exp@comp@dec{}% \si@bool@false\si@num@in@exp@bool \si@bool@false\si@num@in@exp@comp@bool }% }% \expandafter\si@tempb\si@tempa0000\si@stop }% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@post@plus} %\begin{macro}[aux]{\si@num@post@plus@aux} % Holding onto a plus works very much in the same way as adding a sign: % some quick tests and an assignment. % \begin{macrocode} \newcommand*{\si@num@post@plus}[1]{% \si@bool@cs@if@TF{si@num@in@#1@bool}{% \si@num@post@plus@aux{#1}% }{% \si@bool@cs@if@T{si@num@in@#1@comp@bool}{% \si@num@post@plus@aux{#1@comp}% }% }% } \newcommand*{\si@num@post@plus@aux}[1]{% \def\si@tempa{+}% \si@meaning@eq@cs@if@T{si@num@in@#1@sign}{si@tempa}{% \si@clear@cs{si@num@in@#1@sign}% }% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@post@sign} % Sorting out signs consists of two parts: retaining a plus if necessary % and adding an explicit sign. % \begin{macrocode} \newcommand*{\si@num@post@sign}{% \si@bool@if@F\si@num@post@plus@bool{% \si@num@post@plus{mant}% \si@num@post@plus{exp}% }% \si@bool@if@T\si@num@post@sign@bool{% \si@num@post@add@sign{mant}% \si@num@post@add@sign{exp}% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@post@round} %\begin{macro}[aux]{\si@num@post@round@aux} % The lead-off for rounding is the same for decimal places and % significant figures. % \begin{macrocode} \newcommand*{\si@num@post@round}{% \si@num@post@round@aux{figures}% \si@num@post@round@aux{places}% } \newcommand*{\si@num@post@round@aux}[1]{% \si@bool@cs@if@T{si@num@post@rnd@#1@bool}{% \@nameuse{si@num@post@rnd@#1}{mant}% \@nameuse{si@num@post@rnd@#1}{mant@comp}% \@nameuse{si@num@post@rnd@#1}{exp}% \@nameuse{si@num@post@rnd@#1}{exp@comp}% }% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@post@rnd@dec} % The rounding routine for decimals is the same for figures and places. % \begin{macrocode} \newcommand*{\si@num@post@rnd@dec}[1]{% \si@num@if@F{\si@num@post@rnd@cnt>\@ne}{% \si@tempcnt\expandafter\@car\si@num@post@dec\@nil\relax \si@bool@if@T\si@num@post@carry@bool{% \advance\si@tempcnt\@ne\relax }% \si@bool@false\si@num@post@carry@bool \si@num@if@TF{\si@num@post@rnd@cnt=\@ne}{% \si@num@if@T{\si@tempcnt>4}{% \si@bool@true\si@num@post@carry@bool }% }{% \si@num@if@T{\si@tempcnt=10}{% \si@bool@true\si@num@post@carry@bool \si@tempcnt\z@\relax }% \si@edef@c{si@num@in@#1@dec}{% \the\si@tempcnt \@nameuse{si@num@in@#1@dec}% }% }% }% \advance\si@num@post@rnd@cnt\m@ne\relax \edef\si@num@post@dec{\expandafter\@cdr\si@num@post@dec\@nil}% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@post@rnd@figures} %\begin{macro}[aux]{\si@num@post@rnd@figures@aux@i} %\begin{macro}[aux]{\si@num@post@rnd@figures@aux@ii} %\begin{macro}[aux]{\si@num@post@rnd@figures@aux@iii} % Rather than count figures to start with, a completely different % approach is used here. % \begin{macrocode} \newcommand*{\si@num@post@rnd@figures}[1]{% \si@num@post@rnd@cnt\z@\relax \si@bool@false\si@num@post@sig@bool \si@clear@macro\si@num@post@dec \si@clear@macro\si@num@post@int \si@whiledo@empty@cs@F{si@num@in@#1@int}{% \si@num@post@rnd@figures@aux@i{#1}{int}% }% \si@whiledo@empty@cs@F{si@num@in@#1@dec}{% \si@num@post@rnd@figures@aux@i{#1}{dec}% }% \si@bool@if@TF\si@num@post@sig@bool{% \si@num@if@TF{\si@num@post@rnd@cnt>\si@num@post@figures}{% \si@num@post@rnd@figures@aux@ii{#1}% }{% \si@num@post@rnd@figures@aux@iii{#1}% }% }{% \@namedef{si@num@in@#1@int}{0}% \si@clear@cs{si@num@in@#1@dec}% \si@bool@cs@false{si@num@in@#1@dec@bool}% }% } % \end{macrocode} % A counting macro so that the number of significant digits is known. % Reversal is done at the same time, to save needing another loop later. % \begin{macrocode} \newcommand*{\si@num@post@rnd@figures@aux@i}[2]{% \si@tempcnt\expandafter\expandafter\expandafter\@car \csname si@num@in@#1@#2\endcsname\@nil\relax \si@edef@c{si@num@post@#2}{% \the\si@tempcnt \@nameuse{si@num@post@#2}% }% \si@bool@if@F\si@num@post@sig@bool{% \si@num@if@F{\si@tempcnt=\z@}{% \si@bool@true\si@num@post@sig@bool }% }% \si@bool@if@T\si@num@post@sig@bool{% \advance\si@num@post@rnd@cnt\@ne\relax }% \si@edef@c{si@num@in@#1@#2}{% \expandafter\expandafter\expandafter\@cdr \csname si@num@in@#1@#2\endcsname\@nil }% } % \end{macrocode} % 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} \newcommand*{\si@num@post@rnd@figures@aux@ii}[1]{% \advance\si@num@post@rnd@cnt-\si@num@post@figures\relax \si@whiledo@empty@F\si@num@post@dec{% \si@num@post@rnd@dec{#1}% }% \si@whiledo@empty@F\si@num@post@int{% \si@num@post@rnd@figures@int{#1} }% \si@bool@if@T\si@num@post@carry@bool{% \si@edef@c{si@num@in@#1@int}{% 1% \@nameuse{si@num@in@#1@int}% }% \si@empty@cs@if@F{si@num@in@#1@dec}{% \si@reverse@cs{si@num@in@#1@dec}% \si@edef@c{si@num@in@#1@dec}{% \expandafter\expandafter\expandafter\@cdr \csname si@num@in@#1@dec\endcsname\@nil }% \si@reverse@cs{si@num@in@#1@dec}% }% }% } % \end{macrocode} % If the number is too short, then the reversal is undone and the % padding routine is called. % \begin{macrocode} \newcommand*{\si@num@post@rnd@figures@aux@iii}[1]{% \advance\si@num@post@rnd@cnt-\si@num@post@figures\relax \si@num@post@rnd@cnt-\si@num@post@rnd@cnt\relax \si@reverse@macro\si@num@post@dec \si@reverse@macro\si@num@post@int \si@let@cN{si@num@in@#1@dec}\si@num@post@dec \si@let@cN{si@num@in@#1@int}\si@num@post@int \si@num@post@rnd@pad{#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@rnd@figures@int} % For figures, the integer part is a little complicated as zeros need % to be included. % \begin{macrocode} \newcommand*{\si@num@post@rnd@figures@int}[1]{% \si@num@if@T{\si@num@post@rnd@cnt>\z@}{% \si@edef@c{si@num@in@#1@int}{% 0% \@nameuse{si@num@in@#1@int}% }% }% \si@num@if@F{\si@num@post@rnd@cnt>\@ne}{% \si@tempcnt\expandafter\@car\si@num@post@int\@nil\relax \si@bool@if@T\si@num@post@carry@bool{% \advance\si@tempcnt\@ne\relax }% \si@bool@false\si@num@post@carry@bool \si@num@if@TF{\si@num@post@rnd@cnt=\@ne}{% \si@num@if@T{\si@tempcnt>4}{% \si@bool@true\si@num@post@carry@bool }% }{% \si@num@if@T{\si@tempcnt=10}{% \si@bool@true\si@num@post@carry@bool \si@tempcnt\z@\relax }% \si@edef@c{si@num@in@#1@int}{% \the\si@tempcnt \@nameuse{si@num@in@#1@int}% }% }% }% \advance\si@num@post@rnd@cnt\m@ne\relax \edef\si@num@post@int{\expandafter\@cdr\si@num@post@int\@nil}% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@post@rnd@pad} % 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} \newcommand*{\si@num@post@rnd@pad}[1]{% \si@whiledo@num@T{\si@num@post@rnd@cnt>\z@}{% \si@edef@c{si@num@in@#1@dec}{% \@nameuse{si@num@in@#1@dec}% 0% }% \advance\si@num@post@rnd@cnt\m@ne\relax }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@post@rnd@places} %\begin{macro}[aux]{\si@num@post@rnd@places@aux@i} %\begin{macro}[aux]{\si@num@post@rnd@places@aux@ii} %\begin{macro}[aux]{\si@num@post@rnd@places@aux@iii} % When rounding to a number of places, the number of tokens in the % decimal parts is counted, as this is always needed. A check is then % made on the value of the number: if it is zero then a different % approach is used to that if there is a value. % \begin{macrocode} \newcommand*{\si@num@post@rnd@places}[1]{% \si@num@if@TF{\si@num@post@places=\z@}{% \si@clear@cs{si@num@in@#1@dec}% \si@bool@cs@false{si@num@in@#1@dec@bool}% }{% \si@num@post@rnd@places@aux@i{#1}% }% } \newcommand*{\si@num@post@rnd@places@aux@i}[1]{% \si@empty@cs@if@T{si@num@in@#1@dec}{% \@namedef{si@num@in@#1@dec}{0}% }% \si@num@post@rnd@cnt\si@elt@count@cs{si@num@in@#1@dec}\relax \expandafter\expandafter\expandafter\ifnum \csname si@num@in@#1@dec\endcsname=\z@\relax \si@num@post@rnd@cnt\si@num@post@places\relax \si@clear@cs{si@num@in@#1@dec}% \expandafter\si@num@post@rnd@pad \else \expandafter\si@num@post@rnd@places@aux@ii \fi {#1}% } % \end{macrocode} % For rounding to a fixed number of places, the package finds the % difference in length between what is present and what is required. % If the number is too short, there is some simple padding to do. % \begin{macrocode} \newcommand*{\si@num@post@rnd@places@aux@ii}[1]{% \advance\si@num@post@rnd@cnt-\si@num@post@places\relax \si@num@if@TF{\si@num@post@rnd@cnt<\z@}{% \si@num@post@rnd@cnt-\si@num@post@rnd@cnt\relax \si@num@post@rnd@pad{#1}% }{% \si@num@post@rnd@places@init{#1}% \si@num@post@rnd@places@aux@iii{#1}% }% } \newcommand*{\si@num@post@rnd@places@aux@iii}[1]{% \si@empty@if@TF\si@num@post@dec{% \si@whiledo@empty@F\si@num@post@int{% \si@num@post@rnd@places@int{#1}% }% \si@bool@if@T\si@num@post@carry@bool{% \si@edef@c{si@num@in@#1@int}{% 1% \@nameuse{si@num@in@#1@int}% }% }% }{% \si@num@post@rnd@dec{#1}% \si@num@post@rnd@places@aux@iii{#1}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@rnd@places@int} % Rounding for integers is just a case of carrying digits. % \begin{macrocode} \newcommand*{\si@num@post@rnd@places@int}[1]{% \si@tempcnt\expandafter\@car\si@num@post@int\@nil\relax \edef\si@num@post@int{\expandafter\@cdr\si@num@post@int\@nil}% \si@bool@if@T\si@num@post@carry@bool{% \advance\si@tempcnt\@ne\relax }% \si@bool@false\si@num@post@carry@bool \si@num@if@T{\si@tempcnt=10}{% \si@bool@true\si@num@post@carry@bool \si@tempcnt\z@\relax }% \si@edef@c{si@num@in@#1@int}{% \the\si@tempcnt \@nameuse{si@num@in@#1@int}% }% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@post@rnd@places@init} % To set up some rounding bits and pieces. % \begin{macrocode} \newcommand*{\si@num@post@rnd@places@init}[1]{% \si@let@Nc\si@num@post@dec{si@num@in@#1@dec}% \si@let@Nc\si@num@post@int{si@num@in@#1@int}% \si@reverse@macro\si@num@post@dec \si@reverse@macro\si@num@post@int \si@clear@cs{si@num@in@#1@dec}% \si@clear@cs{si@num@in@#1@int}% \si@bool@false\si@num@post@carry@bool } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@post@zero@fill} %\begin{macro}[aux]{\si@num@post@zero@fill@aux} % Checks for adding zeros to each component are carried out. % \begin{macrocode} \newcommand*{\si@num@post@zero@fill}{% \si@bool@if@T\si@num@post@zero@int@bool{% \si@num@post@zero@fill@aux{mant}{int}% \si@num@post@zero@fill@aux{mant@comp}{int}% \si@num@post@zero@fill@aux{exp}{int}% \si@num@post@zero@fill@aux{exp@comp}{int}% }% \si@bool@if@T\si@num@post@zero@dec@bool{% \si@num@post@zero@fill@aux{mant}{dec}% \si@num@post@zero@fill@aux{mant@comp}{dec}% \si@num@post@zero@fill@aux{exp}{dec}% \si@num@post@zero@fill@aux{exp@comp}{dec}% }% } \newcommand*{\si@num@post@zero@fill@aux}[2]{% \si@bool@cs@if@T{si@num@in@#1@dec@bool}{% \si@empty@cs@if@T{si@num@in@#1@#2}{% \@namedef{si@num@in@#1@#2}{0}% }% }% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@post@uncert} %\begin{macro}[aux]{\si@num@post@uncert@aux@i} %\begin{macro}[aux]{\si@num@post@uncert@aux@ii} % 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} \newcommand*{\si@num@post@uncert}{% \si@num@post@uncert@aux@i{mant}% \si@num@post@uncert@aux@i{exp}% } \newcommand*{\si@num@post@uncert@aux@i}[1]{% \si@num@post@uncert@aux@ii{#1}% \si@num@post@uncert@aux@ii{#1@comp}% } \newcommand*{\si@num@post@uncert@aux@ii}[1]{% \si@bool@cs@if@TF{si@num@in@#1@dec@bool}{% \si@num@post@uncert@dec{#1}% }{% \si@num@post@uncert@int{#1}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@uncert@dec} %\begin{macro}[aux]{\si@num@post@uncert@dec@aux@i} %\begin{macro}[aux]{\si@num@post@uncert@dec@aux@ii} % 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} \newcommand*{\si@num@post@uncert@dec}[1]{% \si@empty@cs@if@F{si@num@in@#1@uncert}{% \si@bool@cs@true{si@num@in@#1@uncert@dec@bool}% \si@num@post@dec@cnt\si@elt@count@cs{si@num@in@#1@dec}\relax \si@num@post@uncert@cnt\si@elt@count@cs{si@num@in@#1@uncert}\relax \si@num@if@TF{\si@num@post@uncert@cnt>\si@num@post@dec@cnt}{% \si@num@post@uncert@dec@aux@i{#1}% }{% \si@num@post@uncert@dec@aux@ii{#1}% }% }% } \newcommand*{\si@num@post@uncert@dec@aux@i}[1]{% \def\si@tempa##1{% \si@num@if@TF{\si@num@post@uncert@cnt>\si@num@post@dec@cnt}{% \si@add@right@cs@n{si@num@in@#1@uncert@int}{##1}% }{% \si@add@right@cs@n{si@num@in@#1@uncert@dec}{##1}% }% \advance\si@num@post@uncert@cnt\m@ne\relax }% \si@loop@over@cs{si@num@in@#1@uncert}\si@tempa } \newcommand*{\si@num@post@uncert@dec@aux@ii}[1]{% \def\si@tempa{% \si@add@right@cs@n{si@num@in@#1@uncert@dec}{0}% \advance\si@num@post@uncert@cnt\@ne\relax }% \si@whiledo@num@T{\si@num@post@uncert@cnt<\si@num@post@dec@cnt}{% \si@tempa }% \def\si@tempa##1{% \si@add@right@cs@o{si@num@in@#1@uncert@dec}{##1}% }% \expandafter\si@tempa\expandafter {\csname si@num@in@#1@uncert\endcsname}% \si@bool@if@T\si@num@post@zero@int@bool{% \@namedef{si@num@in@#1@uncert@int}{0}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@post@uncert@int} % Relatively easy: the uncertainty is in the integer part of the number, % and so there is no need to generate zeros. % \begin{macrocode} \newcommand*{\si@num@post@uncert@int}[1]{% \si@let@cc{si@num@in@#1@uncert@int}{si@num@in@#1@uncert}% } % \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{num@in} and % \texttt{num@out} storage areas is that the later can include % formatting such as hard spaces. % %\begin{macro}{\si@num@out@bracket@close} %\begin{macro}{\si@num@out@bracket@open} %\begin{macro}{\si@num@out@complex@root} %\begin{macro}{\si@num@out@decimal} %\begin{macro}{\si@num@out@exp@base} %\begin{macro}{\si@num@out@exp@prod} %\begin{macro}{\si@num@out@group@sep} %\begin{macro}{\si@num@out@uncert@close} %\begin{macro}{\si@num@out@uncert@open} %\begin{macro}{\si@num@out@uncert@space} % Storage areas for settings. % \begin{macrocode} \newcommand*{\si@num@out@bracket@close}{} \newcommand*{\si@num@out@bracket@open}{} \newcommand*{\si@num@out@complex@root}{} \newcommand*{\si@num@out@decimal}{} \newcommand*{\si@num@out@exp@base}{} \newcommand*{\si@num@out@exp@prod}{} \newcommand*{\si@num@out@group@sep}{} \newcommand*{\si@num@out@uncert@close}{} \newcommand*{\si@num@out@uncert@open}{} \newcommand*{\si@num@out@uncert@space}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@out@bracket@use@bool} %\begin{macro}{\si@num@out@group@digits@bool} %\begin{macro}{\si@num@out@group@four@bool} %\begin{macro}{\si@num@out@tight@bool} %\begin{macro}{\si@num@out@uncert@sep@bool} % Switch storage for options. % \begin{macrocode} \si@bool@new\si@num@out@bracket@use@bool \si@bool@new\si@num@out@group@digits@bool \si@bool@new\si@num@out@group@four@bool \si@bool@new\si@num@out@tight@bool \si@bool@new\si@num@out@uncert@sep@bool % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@out@mant} %\begin{macro}{\si@num@out@mant@sign} %\begin{macro}{\si@num@out@mant@int} %\begin{macro}{\si@num@out@mant@dec} %\begin{macro}{\si@num@out@mant@uncert} %\begin{macro}{\si@num@out@mant@uncert@dec} %\begin{macro}{\si@num@out@mant@uncert@int} %\begin{macro}{\si@num@out@mant@comp} %\begin{macro}{\si@num@out@mant@comp@sign} %\begin{macro}{\si@num@out@mant@comp@int} %\begin{macro}{\si@num@out@mant@comp@dec} %\begin{macro}{\si@num@out@mant@comp@uncert} %\begin{macro}{\si@num@out@mant@comp@uncert@dec} %\begin{macro}{\si@num@out@mant@comp@uncert@int} % Storage areas for output mantissa. % \begin{macrocode} \newcommand*{\si@num@out@mant}{} \newcommand*{\si@num@out@mant@sign}{} \newcommand*{\si@num@out@mant@int}{} \newcommand*{\si@num@out@mant@dec}{} \newcommand*{\si@num@out@mant@uncert}{} \newcommand*{\si@num@out@mant@uncert@dec}{} \newcommand*{\si@num@out@mant@uncert@int}{} \newcommand*{\si@num@out@mant@comp}{} \newcommand*{\si@num@out@mant@comp@sign}{} \newcommand*{\si@num@out@mant@comp@int}{} \newcommand*{\si@num@out@mant@comp@dec}{} \newcommand*{\si@num@out@mant@comp@uncert}{} \newcommand*{\si@num@out@mant@comp@uncert@dec}{} \newcommand*{\si@num@out@mant@comp@uncert@int}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@exp} %\begin{macro}{\si@num@out@exp@sign} %\begin{macro}{\si@num@out@exp@int} %\begin{macro}{\si@num@out@exp@dec} %\begin{macro}{\si@num@out@exp@uncert} %\begin{macro}{\si@num@out@exp@uncert@dec} %\begin{macro}{\si@num@out@exp@uncert@int} %\begin{macro}{\si@num@out@exp@comp} %\begin{macro}{\si@num@out@exp@comp@sign} %\begin{macro}{\si@num@out@exp@comp@int} %\begin{macro}{\si@num@out@exp@comp@dec} %\begin{macro}{\si@num@out@exp@comp@uncert} %\begin{macro}{\si@num@out@exp@comp@uncert@dec} %\begin{macro}{\si@num@out@exp@comp@uncert@int} % And for exponents. % \begin{macrocode} \newcommand*{\si@num@out@exp}{} \newcommand*{\si@num@out@exp@sign}{} \newcommand*{\si@num@out@exp@int}{} \newcommand*{\si@num@out@exp@dec}{} \newcommand*{\si@num@out@exp@uncert}{} \newcommand*{\si@num@out@exp@uncert@dec}{} \newcommand*{\si@num@out@exp@uncert@int}{} \newcommand*{\si@num@out@exp@comp}{} \newcommand*{\si@num@out@exp@comp@sign}{} \newcommand*{\si@num@out@exp@comp@int}{} \newcommand*{\si@num@out@exp@comp@dec}{} \newcommand*{\si@num@out@exp@comp@uncert}{} \newcommand*{\si@num@out@exp@comp@uncert@dec}{} \newcommand*{\si@num@out@exp@comp@uncert@int}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@result} % The overall number is stored here, although it might not be used in % this form. % \begin{macrocode} \newcommand*{\si@num@out@result}{} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@out@mant@parts@bool} %\begin{macro}{\si@num@out@mant@comp@parts@bool} %\begin{macro}{\si@num@out@exp@parts@bool} %\begin{macro}{\si@num@out@exp@comp@parts@bool} % Flags to indicate that the input is in parts which may need brackets. % \begin{macrocode} \si@bool@new\si@num@out@mant@parts@bool \si@bool@new\si@num@out@mant@comp@parts@bool \si@bool@new\si@num@out@exp@parts@bool \si@bool@new\si@num@out@exp@comp@parts@bool % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@mant@comp@bool} %\begin{macro}{\si@num@out@exp@comp@bool} % Also for a number consisting of a real and complex part. % \begin{macrocode} \si@bool@new\si@num@out@mant@comp@bool \si@bool@new\si@num@out@exp@comp@bool % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@mant@bool} % A flag is needed so that a sign in the mantissa with no value % is correctly detected. % \begin{macrocode} \si@bool@new\si@num@out@mant@bool % \end{macrocode} %\end{macro} % % % The usual keys are created for output (appearance-only) settings. % \begin{macrocode} \si@keys@family{numbers/output} \pgfkeys{ /siunitx/numbers/output, close bracket/.store in = {\si@num@out@bracket@close}, close uncertainty/.store in = {\si@num@out@uncert@close}, complex root/.store in = {\si@num@out@complex@root}, decimal marker/.store in = {\si@num@out@decimal}, exponent base/.store in = {\si@num@out@exp@base}, exponent product/.store in = {\si@num@out@exp@prod}, group digits/.is siunitx switch = {num@out@group@digits}, group four digits/.is siunitx switch = {num@out@group@four}, group separator/.store in = {\si@num@out@group@sep}, open bracket/.store in = {\si@num@out@bracket@open}, open uncertainty/.store in = {\si@num@out@uncert@open}, separate uncertainty/.is siunitx switch = {num@out@uncert@sep}, tight spacing/.is siunitx switch = {num@out@tight}, uncertainty space/.store in = {\si@num@out@uncert@space}, use brackets/.is siunitx switch = {num@out@bracket@use}, %( close bracket = ),% ( close uncertainty = ), complex root = i, decimal marker = ., exponent base = 10, exponent product = \times, group digits = true, group four digits = false, group separator = {\,}, open bracket = (, %) open uncertainty = (, %) separate uncertainty = false, tight spacing = false, use brackets = true, uncertainty space = {}, } % \end{macrocode} % %\begin{macro}{\si@num@out@process} % The master control function for formatting output: the usual set up. % The number is put back together in stages. % \begin{macrocode} \newcommand*{\si@num@out@process}{% \si@num@out@init \si@num@out@core \si@num@out@complex \si@empty@if@F\si@num@out@mant{% \si@bool@true\si@num@out@mant@bool }% \si@num@out@sign{mant}% \si@num@out@sign{exp}% \si@num@out@exponent } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@out@add} %\begin{macro}{\si@num@out@add@C} %\begin{macro}[aux]{\si@num@out@add@C@aux} % Adding to a store. % \begin{macrocode} \newcommand*{\si@num@out@add}[1]{% \si@add@right@cs@n{si@num@out@#1}% } \newcommand*{\si@num@out@add@C}[2]{% \expandafter\si@num@out@add@C@aux\expandafter {\csname si@num@out@#2\endcsname}{#1}% } \newcommand*{\si@num@out@add@C@aux}[2]{% \si@add@right@cs@o{si@num@out@#2}{#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@add@maths} %\begin{macro}[aux]{\si@num@out@add@maths@aux} % To add something which requires maths mode to an output macro by name. % Done this way, the output ends up with the literal text stored (makes % debugging easier). A quick reversal of the input makes expansion % easier. % \begin{macrocode} \newcommand*{\si@num@out@add@maths}[2]{% \si@empty@if@F#2{% \expandafter\si@num@out@add@maths@aux\expandafter{#2}{#1}% }% } \newcommand*{\si@num@out@add@maths@aux}[2]{% \si@num@out@add{#2}{\ensuremath{#1}}% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@add@pm} % To add \cs{pm}. % \begin{macrocode} \newcommand*{\si@num@out@add@pm}[1]{% \si@bool@if@TF\si@num@out@tight@bool{% \si@num@out@add@maths{#1}{{\pm}}% }{% \def\si@tempa{\pm}% \si@num@out@add@maths{#1}{\si@tempa}% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@out@bracket@comp} %\begin{macro}{\si@num@out@bracket@parts} %\begin{macro}[aux]{\si@num@out@bracket@aux@i} %\begin{macro}[aux]{\si@num@out@bracket@aux@ii} % 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} \newcommand*{\si@num@out@bracket@comp}[1]{% \si@bool@cs@if@T{si@num@out@#1@comp@bool}{% \si@bool@cs@false{si@num@out@#1@parts@bool}% \si@bool@cs@false{si@num@out@#1@comp@parts@bool}% }% \si@num@out@brackets@aux@i{#1}{comp}% } \newcommand*{\si@num@out@bracket@parts}[1]{% \si@num@out@brackets@aux@i{#1}{parts}% } \newcommand*{\si@num@out@brackets@aux@i}[2]{% \si@empty@cs@if@F{si@num@out@#1}{% \si@bool@if@T\si@num@out@bracket@use@bool{% \si@bool@cs@if@T{si@num@out@#1@#2@bool}{% \si@num@out@bracket@aux@ii{#1}% \si@bool@cs@false{si@num@out@#1@#2@bool}% }% }% }% } \newcommand*{\si@num@out@bracket@aux@ii}[1]{% \si@add@left@cs@o{si@num@out@#1}\si@num@out@bracket@open \si@add@right@cs@o{si@num@out@#1}\si@num@out@bracket@close } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@out@complex} %\begin{macro}[aux]{\si@num@out@complex@aux} % The real and complex parts of each number are reassembled, with % brackets if needed. % \begin{macrocode} \newcommand*{\si@num@out@complex}{% \si@num@out@complex@aux{mant}% \si@num@out@complex@aux{exp}% } \newcommand*{\si@num@out@complex@aux}[1]{% \si@num@out@bracket@parts{#1@comp}% \si@bool@cs@if@T{si@num@in@#1@comp@bool}{% \si@num@out@add@maths{#1@comp}{\si@num@out@complex@root}% \si@num@out@bracket@parts{#1}% \si@empty@cs@if@F{si@num@out@#1}{% \si@num@out@sign{#1@comp}% \si@bool@cs@true{si@num@out@#1@comp@bool}% }% }% \si@num@out@add@C{#1}{#1@comp}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@out@copy} %\begin{macro}[aux]{\si@num@out@copy@aux} % A short-cut, keeping down the need for \cs{edef}. % \begin{macrocode} \newcommand*{\si@num@out@copy}[1]{% \expandafter\si@num@out@copy@aux\csname si@num@in@#1\endcsname{#1}% } \newcommand*{\si@num@out@copy@aux}[2]{% \si@add@right@cs@o{si@num@out@#2}{#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@copy@maths} %\begin{macro}[aux]{\si@num@out@copy@maths@aux} % Similar but adding \cs{ensuremath}. % \begin{macrocode} \newcommand*{\si@num@out@copy@maths}[1]{% \expandafter\si@num@out@copy@maths@aux \csname si@num@in@#1\endcsname{#1}% } \newcommand*{\si@num@out@copy@maths@aux}[2]{% \si@num@out@add@maths{#2}#1% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@out@core} %\begin{macro}[aux]{\si@num@out@core@aux@i} %\begin{macro}[aux]{\si@num@out@core@aux@ii} % The integer, decimal and any uncertainty parts are put back together. % This gives a ``minimal'' unit which cannot need any brackets. % \begin{macrocode} \newcommand*{\si@num@out@core}{% \si@num@out@core@aux@i{mant}% \si@num@out@core@aux@i{exp}% } \newcommand*{\si@num@out@core@aux@i}[1]{% \si@num@out@core@aux@ii{#1}% \si@num@out@core@aux@ii{#1@comp}% } \newcommand*{\si@num@out@core@aux@ii}[1]{% \si@bool@cs@if@T{si@num@in@#1@bool}{% \si@num@out@group@digits{#1}% \si@empty@cs@if@F{si@num@in@#1@uncert}{% \si@num@out@uncert{#1}% }% }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@out@exponent} % The exponent system starts by making sure that the mantissa contains % brackets if needed. A sign is then added to the exponent part, before % creating the full output (including the mantissa sign if needed). % \begin{macrocode} \newcommand*{\si@num@out@exponent}{% \si@bool@if@T\si@num@out@mant@bool{% \si@empty@cs@if@F{si@num@out@exp}{% \si@num@out@bracket@comp{mant}% \si@num@out@bracket@parts{mant}% }% }% \si@num@out@add@C{result}{mant}% \si@bool@if@T\si@num@out@mant@bool{% \si@empty@cs@if@F{si@num@out@exp}{% \si@bool@if@TF\si@num@out@tight@bool{% \expandafter\def\expandafter\si@tempa\expandafter {\expandafter{\si@num@out@exp@prod}}% \si@num@out@add@maths{result}\si@tempa }{% \si@num@out@add@maths{result}{\si@num@out@exp@prod}% }% }% }% \si@empty@cs@if@F{si@num@out@exp}{% \si@num@out@add@C{result}{exp@base}% \edef\si@num@out@exp{% ^{\expandafter\unexpanded\expandafter{\si@num@out@exp}}% }% \si@num@out@add@C{result}{exp}% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@num@out@group@digits} %\begin{macro}[aux]{\si@num@out@group@digits@aux@i} %\begin{macro}[aux]{\si@num@out@group@digits@aux@ii} % Grouping digits only happens if there are no symbols in the input, and % of course if grouping has been requested. % \begin{macrocode} \newcommand*{\si@num@out@group@digits}[1]{% \si@num@out@copy{#1@dec}% \si@num@out@copy{#1@int}% \si@bool@if@T\si@num@out@group@digits@bool{% \si@bool@if@F\si@num@in@symbols@bool{% \si@num@out@group@digits@aux@i{#1}{dec}% \si@num@out@group@digits@aux@i{#1}{int}% }% }% \si@num@out@add@C{#1}{#1@int}% \si@bool@cs@if@T{si@num@in@#1@dec@bool}{% \si@num@out@add@maths{#1}{\si@num@out@decimal}% \si@num@out@add@C{#1}{#1@dec}% }% } \newcommand*{\si@num@out@group@digits@aux@i}[2]{% \si@empty@cs@if@F{si@num@in@#1@#2}{% \si@bool@if@TF\si@num@out@group@four@bool{% \si@num@out@group@digits@aux@ii{#1}{#2}% }{% \si@num@out@group@five@if@T{si@num@in@#1@#2}{% \si@num@out@group@digits@aux@ii{#1}{#2}% }% }% }% } % \end{macrocode} % The main formatter uses a loop to move through the input and convert % it to output. Branching for integer or decimal part is left until the % last possible moment. % \begin{macrocode} \newcommand*{\si@num@out@group@digits@aux@ii}[2]{% \si@clear@cs{si@num@out@#1@#2}% \@nameuse{si@num@out@group@#2}{#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@group@dec} %\begin{macro}[aux]{\si@num@out@group@dec@aux} % Using the ``keep everything on the stack'' approach, a relatively % simple recursion is needed. % \begin{macrocode} \newcommand*{\si@num@out@group@dec}[1]{% \def\si@num@out@group@dec@aux##1##2##3##4{% \si@empty@tlist@if@TF{##2}{% \si@num@out@add{#1@dec}{##1}% }{% \si@empty@tlist@if@TF{##3}{% \si@num@out@add{#1@dec}{##1##2}% }{% \si@num@out@add{#1@dec}{##1##2##3}% \si@empty@tlist@if@F{##4}{% \si@num@out@add@maths{#1@dec}{\si@num@out@group@sep}% \si@num@out@group@dec@aux##4% }% }% }% }% \expandafter\expandafter\expandafter\si@num@out@group@dec@aux \csname si@num@in@#1@dec\endcsname{}{}{}% } \newcommand*{\si@num@out@group@dec@aux}{} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@group@five@if@T} %\begin{macro}[aux]{\si@num@out@group@five@if@aux@i} % A check to see if there are five tokens in the input: this will always % be a name. The \cs{edef} in the auxiliary function here mops up the % \cs{@empty}s needed for the delimited argument. % \begin{macrocode} \newcommand*{\si@num@out@group@five@if@T}[1]{% \expandafter\expandafter\expandafter\si@num@out@group@five@if@aux \csname #1\endcsname\@empty\@empty\@empty\@empty\si@stop } \newcommand*{\si@num@out@group@five@if@aux}{} \def\si@num@out@group@five@if@aux#1#2#3#4#5\si@stop{% \edef\si@tempa{#5}% \si@empty@if@F\si@tempa } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@out@group@int} %\begin{macro}[aux]{\si@num@out@group@int@aux@i} %\begin{macro}[aux]{\si@num@out@group@int@aux@ii} %\begin{macro}[aux]{\si@num@out@group@int@aux@iii} % By keeping everything on the stack, recursion can occur quite % efficiently here. The rather odd order is needed because % \cs{si@num@out@group@int@aux@iii} needs |#1| to be available. % \begin{macrocode} \newcommand*{\si@num@out@group@int}[1]{% \def\si@num@out@group@int@aux@iii##1##2##3##4{% \si@num@out@add{#1@int}{##1##2##3}% \si@stop@if@F{##4}{% \si@num@out@add@maths{#1@int}{\si@num@out@group@sep}% \si@num@out@group@int@aux@iii##4% }% }% \expandafter\si@num@out@group@int@aux@i \csname si@num@in@#1@int\endcsname } \newcommand*{\si@num@out@group@int@aux@i}[1]{% \expandafter\si@num@out@group@int@aux@ii\expandafter {\expandafter}#1{}{}{}% } \newcommand*{\si@num@out@group@int@aux@ii}[4]{% \si@empty@tlist@if@TF{#2}{% \si@num@out@group@int@aux@iii#1\si@stop }{% \si@empty@tlist@if@TF{#3}{% \si@num@out@group@int@aux@iii{}{}#1#2\si@stop }{% \si@empty@tlist@if@TF{#4}{% \si@num@out@group@int@aux@iii{}#1#2#3\si@stop }{% \si@num@out@group@int@aux@ii{#1#2#3#4}% }% }% }% } \newcommand*{\si@num@out@group@int@aux@iii}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@out@init} %\begin{macro}[aux]{\si@num@out@init@aux} % Clear out the storage for printing. % \begin{macrocode} \newcommand*{\si@num@out@init}{% \si@loop@over@macro\si@num@in@init@names\si@num@out@init@aux \si@clear@macro\si@num@out@result \si@bool@false\si@num@out@mant@parts@bool \si@bool@false\si@num@out@mant@comp@parts@bool \si@bool@false\si@num@out@exp@parts@bool \si@bool@false\si@num@out@exp@comp@parts@bool \si@bool@false\si@num@out@mant@comp@bool \si@bool@false\si@num@out@exp@comp@bool \si@bool@false\si@num@out@mant@bool } \newcommand*{\si@num@out@init@aux}[1]{% \si@clear@cs{si@num@out@#1}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@out@sign} %\begin{macro}[aux]{\si@num@out@sign@aux} % Some simple sign manipulation: for tight signs, a little shuffling. % \begin{macrocode} \newcommand*{\si@num@out@sign}[1]{% \si@bool@if@TF\si@num@out@tight@bool{% \si@let@Nc\si@tempa{si@num@in@#1@sign}% \expandafter\def\expandafter\si@tempa\expandafter {\expandafter{\si@tempa}}% \si@num@out@add@maths{#1@sign}\si@tempa }{% \si@num@out@copy@maths{#1@sign}% }% \si@num@out@sign@aux@i{#1}% } \newcommand*{\si@num@out@sign@aux@i}[1]{% \expandafter\si@num@out@sign@aux@ii \csname si@num@out@#1@sign\endcsname{si@num@out@#1}% } \newcommand*{\si@num@out@sign@aux@ii}[2]{% \si@add@left@cs@o{#2}{#1}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@num@out@uncert} % Uncertainty output varies depending on whether there is a need to % separate the error form the number in the output. % \begin{macrocode} \newcommand*{\si@num@out@uncert}[1]{% \si@bool@if@TF\si@num@out@uncert@sep@bool{% \si@bool@cs@true{si@num@out@#1@parts@bool}% \si@num@out@group@digits{#1@uncert}% \si@num@out@add@pm{#1}% \si@num@out@add@C{#1}{#1@uncert}% }{% \si@num@out@add@maths{#1@uncert}{\si@num@out@uncert@open}% \si@num@out@copy{#1@uncert}% \si@num@out@add@maths{#1@uncert}{\si@num@out@uncert@close}% \si@num@out@add@maths{#1}{\si@num@out@uncert@space}% \si@num@out@add@C{#1}{#1@uncert}% }% } % \end{macrocode} %\end{macro} % %\subsection{Wrapper number macros} % % The \cs{num} macro needs some support macros to handle looping over % products and to handle quotients. % %\begin{macro}{\si@num@print} % \begin{macrocode} \newcommand*{\si@num@print}{% \si@print@num@o{\si@num@out@result}% \opt } % \end{macrocode} %\end{macro} % %\subsection{Setting up tables} % %\begin{macro}{\si@tab@rewrite@check@cellspace} % 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} \newcommand*{\si@tab@rewrite@check@cellspace}{% \@ifpackageloaded{cellspace}{% \si@log@info{Changing cellspace column letter to C}% \newcolumntype{C}[1]{>{\bcolumn##1\@nil}##1<{\ecolumn}}% \def\si@tempa##1\NC@do S##2\si@stop{% \NC@list{##1##2}% }% \expandafter\si@tempa\the\NC@list\si@stop \let\NC@find@S\@undefined }{}% } \AtBeginDocument{\si@tab@rewrite@check@cellspace} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@tab@rewrite@create} %\begin{macro}{\si@tab@rewrite@init} % 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 ``by hand'' to % the appropriate macro.\footnote{\cs{NC@list} is a toks, not a macro.} % \begin{macrocode} \newcommand*{\si@tab@rewrite@create}[1]{% \edef\si@tempa{\noexpand\NC@do #1\the\NC@list}% \newcolumntype{#1}{}% \NC@list\expandafter{\si@tempa}% \expandafter\renewcommand\expandafter*\expandafter{% \csname NC@rewrite@#1\endcsname }[1][]{% \edef\si@tempa{% \the\@temptokena >{\noexpand\si@tab@collect@begin[\unexpanded{##1}]{#1}}% c% <{\noexpand\si@tab@print@out}% }% \@temptokena\expandafter{\si@tempa}% \NC@find }% } \AtBeginDocument{% \si@tab@rewrite@create{S}% \si@tab@rewrite@create{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}{\si@tab@collect@after} %\begin{macro}{\si@tab@collect@before} %\begin{macro}{\si@tab@collect@body} % Three storage areas. % \begin{macrocode} \newcommand*{\si@tab@collect@after}{} \newcommand*{\si@tab@collect@before}{} \newcommand*{\si@tab@collect@body}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@tab@collect@num} % To store the list of what is valid in a number. % \begin{macrocode} \newcommand*{\si@tab@collect@num}{} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@collect@after@bool} %\begin{macro}{\si@tab@collect@before@bool} % Flags for having found a number in an \texttt{S} column. % \begin{macrocode} \si@bool@new\si@tab@collect@after@bool \si@bool@new\si@tab@collect@before@bool % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@tab@collect@begin} %\begin{macro}{\si@tab@collect@begin@s} %\begin{macro}{\si@tab@collect@begin@S} %\begin{macro}{\si@tab@collect@braced} % The collector starts by setting up local options, then clears and % initialises the storage and testing system. % \begin{macrocode} \newcommand*{\si@tab@collect@begin}[2][]{% \begingroup \sisetup{#1}% \def\si@tab@collect@body{}% \@nameuse{si@tab@collect@begin@#2}% \si@tab@collect@get } \newcommand*{\si@tab@collect@begin@s}{% \si@bool@false\si@tab@collect@before@bool \let\si@tab@collect@token\si@tab@collect@token@s \let\si@tab@print@out\si@tab@print@out@s \def\si@tab@collect@braced##1{% \si@add@right@n\si@tab@collect@body{{##1}}% \si@tab@collect@next }% } \newcommand*{\si@tab@collect@begin@S}{% \def\si@tab@collect@after{}% \def\si@tab@collect@before{}% \si@bool@true\si@tab@collect@before@bool \let\si@tab@collect@token\si@tab@collect@token@S \let\si@tab@print@out\si@tab@print@out@S \si@expand@tlist\si@tab@collect@num{% \si@num@in@ignore \si@num@in@signs \si@num@in@digits \si@num@in@decimal \si@num@in@exponent \si@num@in@complex \si@num@in@symbols \si@num@in@uncert@open \si@num@in@uncert@close }% \def\si@tab@collect@braced##1{% \si@bool@if@TF\si@tab@collect@before@bool{% \si@add@right@n\si@tab@collect@before{##1}% }{% \si@bool@false\si@tab@collect@before@bool \si@bool@true\si@tab@collect@after@bool \si@add@right@n\si@tab@collect@after{##1}% }% \si@tab@collect@next }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % For items in braces, direct addition to the appropriate store can % occur. The definitions are column-type dependent, so occur in the % appropriate \texttt{begin} function. % \begin{macrocode} \newcommand*{\si@tab@collect@braced}{} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@tab@collect@expand} %\begin{macro}[aux]{\si@tab@collect@expand@aux@i} %\begin{macro}[aux]{\si@tab@collect@expand@aux@ii} % The idea here is to expand content if possible. There are a few % things to note. Only macros which are not \cs{long} or \cs{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 % Table~\ref{tab:xmpl:calc} in the user part of the documentation. % \begin{macrocode} \newcommand*{\si@tab@collect@expand}[1]{% \edef\si@tempa{% \expandafter\si@tab@collect@expand@aux@i\meaning#1:->\si@stop }% \si@meaning@eq@if@TF\si@tempa\si@tab@collect@expand@aux@ii{% \si@tab@collect@before \def\si@tab@collect@before{}% \expandafter\def\expandafter\si@tab@collect@next\expandafter{% \expandafter\si@tab@collect@get#1% }% }{% \si@bool@if@TF\si@tab@collect@before@bool{% \si@add@right@n\si@tab@collect@before{#1}% }{% \si@bool@true\si@tab@collect@after@bool \si@bool@false\si@tab@collect@before@bool \si@add@right@n\si@tab@collect@after{#1}% }% }% } \newcommand*{\si@tab@collect@expand@aux@i}{} \def\si@tab@collect@expand@aux@i#1:->#2\si@stop{#1} \newcommand*{\si@tab@collect@expand@aux@ii}{} \edef\si@tab@collect@expand@aux@ii{% \expandafter\si@tab@collect@expand@aux@i\meaning \si@tab@collect@expand@aux@ii:->\si@stop }% % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@tab@collect@get} %\begin{macro}[aux]{\si@tab@collect@get@aux} % 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} \newcommand*{\si@tab@collect@get}{% \let\si@tab@collect@next\si@tab@collect@get \futurelet\si@tempa\si@tab@collect@get@aux } \newcommand*{\si@tab@collect@get@aux}{% \si@meaning@eq@if@TF\si@tempa\bgroup{% \si@tab@collect@braced }{% \si@tab@collect@unbraced }% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@tab@collect@newline} % The end macro needs to come before the new line is called. % \begin{macrocode} \newcommand*{\si@tab@collect@newline}{% \si@tab@print@out \tabularnewline } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@tab@collect@next} % The tail recursion system is initialised. % \begin{macrocode} \newcommand*{\si@tab@collect@next}{} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@tab@collect@token} %\begin{macro}{\si@tab@collect@token@s} %\begin{macro}{\si@tab@collect@token@S} % For the \texttt{s} column, every token is added to the same storage % area, so life is simple. % \begin{macrocode} \newcommand*{\si@tab@collect@token}{} \newcommand*{\si@tab@collect@token@s}[1]{% \si@add@right@n\si@tab@collect@body{#1}% } % \end{macrocode} % 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} \newcommand*{\si@tab@collect@token@S}[1]{% \si@bool@if@TF\si@tab@collect@after@bool{% \si@add@right@n\si@tab@collect@after{#1}% }{% \si@in@if@TF\si@tab@collect@num{#1}{% \si@bool@false\si@tab@collect@before@bool \si@add@right@n\si@tab@collect@body{#1}% }{% \si@tab@collect@expand{#1}% }% }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@tab@collect@unbraced} %\begin{macro}[aux]{\si@tab@collect@unbraced@aux} % A few macros are simply passed through to be executed; this is mainly % so that the table actually works. % \begin{macrocode} \newcommand*{\si@tab@collect@unbraced}[1]{% \si@meaning@eq@if@F{#1}\ignorespaces{% \si@meaning@eq@if@F{#1}\unskip{% \si@tab@collect@unbraced@aux{#1}% }% }% \si@tab@collect@next } \newcommand*{\si@tab@collect@unbraced@aux}[1]{% \def\si@tempa##1{% \si@meaning@eq@if@T{#1}##1{% \let\si@tab@collect@next##1% }% }% \si@tempa\csname \si@tempa\end \si@tempa\endtabular \si@tempa\si@tab@print@out \si@tempa\relax % \end{macrocode} % The newline function needs its own macro, which is picked up by hand. % \begin{macrocode} \si@meaning@eq@if@T\si@tab@collect@next\si@tab@collect@get{% \si@meaning@eq@if@TF{#1}\tabularnewline{% \let\si@tab@collect@next\si@tab@collect@newline }{% \si@tab@collect@token{#1}% }% }% } % \end{macrocode} %\end{macro} %\end{macro} % %\subsection{Printing tables} % % The second part of creating tables is to print the results. Here, the % various alignment methods are implemented. % % \begin{macrocode} \si@keys@family{tables} \pgfkeys{ /siunitx/tables, align exponents/.is siunitx switch = {}, align uncertainties/.is siunitx switch = {}, number position/.is choice, number position/.cd, center/.code = {}, centre/.code = {}, decimal centred/.code = {}, decimal centered/.code = {}, left/.code = {}, right/.code = {}, /siunitx/tables, number format/.code = {}, position/.is choice, position/.cd, center/.style = { /siunitx/tables/number position = center, /siunitx/tables/text position = center, /siunitx/tables/unit position = center, }, centre/.style = { /siunitx/tables/number position = centre, /siunitx/tables/text position = centre, /siunitx/tables/unit position = centre, }, left/.style = { /siunitx/tables/number position = left, /siunitx/tables/text position = left, /siunitx/tables/unit position = left, }, right/.style = { /siunitx/tables/number position = right, /siunitx/tables/text position = right, /siunitx/tables/unit position = right, }, /siunitx/tables, text position/.is choice, text position/.cd, center/.code = {}, centre/.code = {}, none/.code = {}, left/.code = {}, right/.code = {}, /siunitx/tables, unit position/.is choice, unit position/.cd, center/.code = {}, centre/.code = {}, none/.code = {}, left/.code = {}, right/.code = {}, /siunitx/tables, number position = centre, text position = centre, unit position = centre } % \end{macrocode} % %\begin{macro}{\si@tab@print@out} %\begin{macro}{\si@tab@print@out@s} %\begin{macro}{\si@tab@print@out@S} % \begin{macrocode} \newcommand*{\si@tab@print@out}{} \newcommand*{\si@tab@print@out@s}{% \si@tab@collect@body \endgroup } \newcommand*{\si@tab@print@out@S}{% \si@tab@collect@before \si@tab@collect@body \si@tab@collect@after \endgroup } % \end{macrocode} %\end{macro} %\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}{\si@unit@def@list} %\begin{macro}{\si@unit@def@prefix@list} %\begin{macro}{\si@unit@def@power@list} %\begin{macro}{\si@unit@def@qual@list} %\begin{macro}{\si@unit@def@unit@list} % Lists of each type of definition, and a master list. % \begin{macrocode} \newcommand*{\si@unit@def@list}{} \newcommand*{\si@unit@def@prefix@list}{} \newcommand*{\si@unit@def@power@list}{} \newcommand*{\si@unit@def@qual@list}{} \newcommand*{\si@unit@def@unit@list}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@unit@def@list@combine} % At the beginning of the document, the various lists can be combined. % This means that the conversion of internal to working names inside % the package macros only needs to loop over a single token list. % \begin{macrocode} \newcommand*{\si@unit@def@list@combine}{% \si@expand@tlist\si@unit@def@list{% \si@unit@def@power@list \si@unit@def@prefix@list \si@unit@def@qual@list \si@unit@def@unit@list }% \si@add@right@n\si@unit@def@list{% \per \raiseto \tothe }% } \AtBeginDocument{\si@unit@def@list@combine} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@def@power} %\begin{macro}{\si@unit@def@power@post} % Creating powers is all about manipulating stored values. This means % that the call to \cs{si@unit@parse@power} does not really need an % argument. % \begin{macrocode} \newcommand*{\si@unit@def@power}[2]{% \si@add@right@n\si@unit@def@power@list{#1}% \@namedef{si@unit@literal@\string#1}##1{##1\textsuperscript{#2}}% \@namedef{si@unit@macro@\string#1}{% \def\si@unit@parse@power@last{#2}% }% } \newcommand*{\si@unit@def@power@post}[2]{% \si@add@right@n\si@unit@def@power@list{#1}% \@namedef{si@unit@literal@\string#1}{\textsuperscript{#2}}% \@namedef{si@unit@macro@\string#1}{% \def\si@unit@parse@power@current{#2}% \si@unit@parse@store{power}{null}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@def@prefix} %\begin{macro}{\si@unit@def@prefix@binary} % \begin{macrocode} \newcommand*{\si@unit@def@prefix}[3]{% \si@add@right@n\si@unit@def@prefix@list{#1}% \@namedef{si@unit@literal@\string#1}{#2}% \@namedef{si@unit@number@\string#1}{#3}% \@namedef{si@unit@macro@\string#1}{% \si@unit@parse@store{prefix}{#2}% }% } \newcommand*{\si@unit@def@prefix@binary}[1]{% \si@unit@def@prefix{#1}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@unit@def@qual} % \begin{macrocode} \newcommand*{\si@unit@def@qual}[2]{% \si@add@right@n\si@unit@def@qual@list{#1}% \@namedef{si@unit@literal@\string#1}{\text{ }(#2)}% \@namedef{si@unit@macro@\string#1}{% \si@unit@parse@store{qual}{#2}% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@def@unit} % 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} \newcommand*{\si@unit@def@unit}[3]{% \si@add@right@n\si@unit@def@unit@list{#1}% \si@empty@tlist@if@TF{#2}{% \si@let@cN{si@unit@options@\string#1}\@undefined }{% \@namedef{si@unit@options@\string#1}{#2}% }% \@namedef{si@unit@literal@\string#1}{#3}% \@namedef{si@unit@macro@\string#1}{% \si@csname@if@TF{si@unit@macro@\expandafter\string\@car#3\@nil}{% #3% }{% \si@unit@parse@store{unit}{#3}% }% }% } % \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}{\si@unit@create@body@bool} %\begin{macro}{\si@unit@create@opt@bool} %\begin{macro}{\si@unit@create@overwrite@bool} %\begin{macro}{\si@unit@create@prespace@bool} %\begin{macro}{\si@unit@create@xspace@bool} % The options need to be stored. % \begin{macrocode} \si@bool@new\si@unit@create@body@bool \si@bool@new\si@unit@create@opt@bool \si@bool@new\si@unit@create@overwrite@bool \si@bool@new\si@unit@create@prespace@bool \si@bool@new\si@unit@create@xspace@bool % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % % There are a few options which control this behaviour. % \begin{macrocode} \si@keys@family{units/creation} \pgfkeys{ /siunitx/units/creation, add leading space/.is siunitx switch = {unit@create@prespace}, allow in body/.is siunitx switch = {unit@create@body}, allow optional argument/.is siunitx switch = {unit@create@opt}, overwrite macros/.is siunitx switch = {unit@create@overwrite}, use xspace/.is siunitx switch = {unit@create@xspace}, add leading space = false, allow in body = false, allow optional argument = false, overwrite macros = false, use xspace = false } % \end{macrocode} % %\begin{macro}{\si@unit@def@create} % The master control macro which occurs at the start of the document. % \begin{macrocode} \newcommand*{\si@unit@create@body}{% \si@bool@if@T\si@unit@create@body@bool{% \si@unit@create@macros }% } \AtBeginDocument{\si@unit@create@body} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@create@macros} % Creation of macros essentially involves picking up a couple of loops. % \begin{macrocode} \newcommand*{\si@unit@create@macros}{% \si@bool@if@T\si@unit@create@xspace@bool{% \RequirePackage{xspace}% }% \si@bool@if@T\si@unit@create@overwrite@bool{% \si@loop@over@macro\si@unit@def@list\si@unit@create@undefine }% \si@bool@if@TF\si@unit@create@opt@bool{% \si@loop@over@macro\si@unit@def@list\si@unit@create@optional }{% \si@loop@over@macro\si@unit@def@list\si@unit@create@plain }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@create@optional} % If the macros need to take an optional argument, everything can be % sent to the \cs{SI} macro. % \begin{macrocode} \newcommand*{\si@unit@create@optional}[1]{% \ifdefined#1\else \edef\si@tempa{% \unexpanded{\si@newcommand*{#1}[1][]}{% \si@bool@if@T\si@unit@create@prespace@bool{% \unexpanded{\si@empty@tlist@if@T{##1}}{% \unexpanded{\ensuremath{\si@unit@out@unit@sep}}% }% }% \unexpanded{\SI{##1}{#1}}% \si@bool@if@T\si@unit@create@xspace@bool{% \noexpand\xspace }% }% }% \expandafter\si@tempa \fi } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@create@plain} % Life is very easy if there is no optional argument. % \begin{macrocode} \newcommand*{\si@unit@create@plain}[1]{% \ifdefined#1\else \edef\si@tempa{% \unexpanded{\si@newcommand*{#1}}{% \si@bool@if@T\si@unit@create@prespace@bool{% \unexpanded{\ensuremath{\si@unit@out@unit@sep}}% }% \unexpanded{\si{#1}}% \si@bool@if@T\si@unit@create@xspace@bool{% \noexpand\xspace }% }% }% \expandafter\si@tempa \fi } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@create@undefine} % A pretty simple method to delete definitions. % \begin{macrocode} \newcommand*{\si@unit@create@undefine}[1]{% \let#1\@undefined } % \end{macrocode} %\end{macro} % %\subsection{Special definitions} % % A few unit-like macros need to be defined by hand as they do not fit % into a general category. % % The \cs{per} macro does not generate any direct output but does % set up the appropriate flags. % \begin{macrocode} \@namedef{si@unit@literal@\string\per}{/} \@namedef{si@unit@macro@\string\per}{% \si@bool@true\si@unit@parse@per@last@bool \def\si@unit@parse@power@last{1}% } % \end{macrocode} % \cs{raiseto} and \cs{tothe} work like other powers but with a flexible % value. % \begin{macrocode} \@namedef{si@unit@literal@\string\raiseto}#1#2{ #2\textsuperscript{#1}% } \@namedef{si@unit@macro@\string\raiseto}#1{% \def\si@unit@parse@power@last{#1}% } \@namedef{si@unit@literal@\string\tothe}#1{% \textsuperscript{#1}% } \@namedef{si@unit@macro@\string\tothe}#1{% \def\si@unit@parse@power@current{#1}% \si@unit@parse@store{power}{null}% } % \end{macrocode} % %\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}{\si@unit@in@parse} % The master function does a very simple checks then hands off. % \begin{macrocode} \newcommand*{\si@unit@in@parse}[1]{% \si@empty@tlist@if@F{#1}{% \si@unit@in@process@if@TF{#1}{% \si@unit@parse@unit{#1}% }{% \si@bool@if@TF\si@unit@out@lit@allow@bool{% \si@unit@out@literal{#1}% }{% \si@log@error{Literal units disabled}{% You gave the literal input `#1' for a unit\MessageBreak but literal unit output is disabled. }% }% }% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@in@process@if@TF} %\begin{macro}[aux]{\si@unit@in@process@aux} % A test is needed to see if the input only contains unit macros. This % is done by altering category codes and then re-scanning the input. All % of the unit macros are \cs{let} to \cs{@empty}, and the \cs{tothe} % macro is set to gobble one argument, so that only other macros can % give anything left in \cs{si@tempa}. % \begin{macrocode} \newcommand*{\si@unit@in@process@if@TF}[1]{% \begingroup \si@loop@over@macro\si@unit@def@list\si@unit@in@process@aux \let\raiseto\@gobble \let\tothe\@gobble \protected@edef\@tempa{#1}% \expandafter\endgroup \expandafter\def\expandafter\si@tempa\expandafter{\@tempa}% \si@empty@if@TF\si@tempa } \newcommand*{\si@unit@in@process@aux}[1]{% \si@clear@macro#1% } % \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. % %\begin{macro}{\si@unit@parse@block} %\begin{macro}{\si@unit@parse@block@den} % Storage for the current block. % \begin{macrocode} \newcommand*{\si@unit@parse@block}{} \newcommand*{\si@unit@parse@block@den}{} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@parse@block@cnt} %\begin{macro}{\si@unit@parse@block@den@cnt} % For ambiguity testing a track is needed of the number of blocks % added to each storage area. A block consists of a unit plus one or % more other elements. % \begin{macrocode} \newcount\si@unit@parse@block@cnt \newcount\si@unit@parse@block@den@cnt % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@parse@per@current@bool} %\begin{macro}{\si@unit@parse@per@last@bool} % The use of \cs{per} needs two flags as conceptually the \cs{per} for % block ``B'' is given during block ``A''. % \begin{macrocode} \si@bool@new\si@unit@parse@per@current@bool \si@bool@new\si@unit@parse@per@last@bool % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@parse@power@current} %\begin{macro}{\si@unit@parse@power@last} % Powers are stored. % \begin{macrocode} \newcommand*{\si@unit@parse@power@current}{} \newcommand*{\si@unit@parse@power@last}{} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@parse@qual@sub@bool} % For warning that qualifiers are subscripted. % \begin{macrocode} \si@bool@new\si@unit@parse@qual@sub@bool % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@parse@queue} %\begin{macro}{\si@unit@parse@queue@den} % Storage for the main list and any denominator. % \begin{macrocode} \newcommand*{\si@unit@parse@queue}{} \newcommand*{\si@unit@parse@queue@den}{} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@parse@sep} % The inter-block separator is held ``pre-built'' here. % \begin{macrocode} \newcommand*{\si@unit@parse@sep}{} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@parse@sticky@bool} % The \cs{per} macro can be ``sticky''. % \begin{macrocode} \si@bool@new\si@unit@parse@sticky@bool % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@parse@type@last} %\begin{macro}{\si@unit@parse@type@last@den} % The last item added to each queue needs to be tracked. % \begin{macrocode} \newcommand*{\si@unit@parse@type@last}{} \newcommand*{\si@unit@parse@type@last@den}{} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@parse@type@prefix} %\begin{macro}{\si@unit@parse@type@power} %\begin{macro}{\si@unit@parse@type@qual} %\begin{macro}{\si@unit@parse@type@unit} % The various possible queue items are given names. % \begin{macrocode} \newcommand*{\si@unit@parse@type@prefix}{prefix} \newcommand*{\si@unit@parse@type@power}{power} \newcommand*{\si@unit@parse@type@qual}{qual} \newcommand*{\si@unit@parse@type@unit}{unit} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@unit@parse@fraction@bool} % A flag for conversion to a fraction. % \begin{macrocode} \si@bool@new\si@unit@parse@fraction@bool % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@parse@qual@format} % The format for qualifiers has to be stored. % \begin{macrocode} \newcommand*{\si@unit@parse@qual@format}{} % \end{macrocode} %\end{macro} % % The unit options needed whilst parsing are set up. % \begin{macrocode} \si@keys@family{units/output} \pgfkeys{ /siunitx/units/output, print as fraction/.is siunitx switch = {unit@parse@fraction}, qualifier format/.is choice, qualifier format/.cd, brackets/.code = {% \def\si@unit@parse@qual@format##1{(##1)}% \si@bool@false\si@unit@parse@qual@sub@bool }, space/.code = {% \def\si@unit@parse@qual@format##1{\text{ }##1}% \si@bool@false\si@unit@parse@qual@sub@bool }, subscript/.code = {% \def\si@unit@parse@qual@format##1{_{##1}}% \si@bool@true\si@unit@parse@qual@sub@bool }, /siunitx/units/output, sticky per/.is siunitx switch = {unit@parse@sticky}, print as fraction = false, qualifier format = subscript, sticky per = false, } % \end{macrocode} % %\begin{macro}{\si@unit@parse@unit} % Parsing units is quite easy, the only trick being to add an extra % ``unit'' at the end to deal with the remaining powers. % \begin{macrocode} \newcommand*{\si@unit@parse@unit}[1]{% \si@unit@parse@init \si@unit@parse@options{#1}% \si@unit@out@sep@print #1% \si@unit@parse@store@unit{stop}% \si@print@unit@o{\si@unit@parse@queue}% TEMP } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@parse@block@new} % Creating a new block means moving the data from the current block to % the queue, adding a space at the start of the current block and then % adding data to the new block. A check is needed so that the first % block does not gain a space. % \begin{macrocode} \newcommand*{\si@unit@parse@block@new}[1]{% \si@empty@if@F\si@unit@parse@power@current{% \si@unit@parse@store@power{null}% }% \si@unit@parse@block@trans \let\si@unit@parse@per@current@bool\si@unit@parse@per@last@bool \let\si@unit@parse@power@current\si@unit@parse@power@last \si@clear@macro\si@unit@parse@power@last \si@bool@if@TF\si@unit@parse@sticky@bool{% \si@bool@if@T\si@unit@parse@per@last@bool{% \def\si@unit@parse@power@last{1}% }% }{% \si@bool@false\si@unit@parse@per@last@bool }% \@namedef{si@unit@parse@block\si@unit@parse@queue@use}{#1}% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@parse@block@trans} %\begin{macro}[aux]{\si@unit@parse@block@add@aux} % Some functions for transferring content from the current block to the % queue. An inter-block separator is added only if there is something % for it to follow. % \begin{macrocode} \newcommand*{\si@unit@parse@block@trans}{% \si@empty@cs@if@F{si@unit@parse@queue\si@unit@parse@queue@use}{% \si@add@right@cs@o{si@unit@parse@queue\si@unit@parse@queue@use}{% \si@unit@parse@sep }% }% \expandafter\si@unit@parse@block@add@aux\expandafter{% \csname si@unit@parse@block\si@unit@parse@queue@use\endcsname }% } \newcommand*{\si@unit@parse@block@add@aux}[1]{% \si@add@right@cs@o{si@unit@parse@queue\si@unit@parse@queue@use}{#1}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@unit@parse@bracket} % For adding brackets around a storage area. % \begin{macrocode} \newcommand*{\si@unit@parse@bracket}[1]{% \si@bool@if@T\si@unit@out@bracket@use@bool{% \si@add@left@cs@o{si@unit@parse@#1}\si@unit@out@bracket@open \si@add@right@cs@o{si@unit@parse@#1}\si@unit@out@bracket@close }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@parse@init} %\begin{macro}[aux]{\si@unit@parse@init@aux} % Initialisation starts by making all of the unit macros active. The % ``last'' addition to the queue is set to be a space, so that no space % is added at the very front. % \begin{macrocode} \newcommand*{\si@unit@parse@init}{% \si@loop@over@macro\si@unit@def@list\si@unit@parse@init@aux \si@clear@macro\si@unit@parse@current \si@clear@macro\si@unit@parse@current@den \si@clear@macro\si@unit@parse@power@current \si@clear@macro\si@unit@parse@power@last \si@clear@macro\si@unit@parse@queue \si@clear@macro\si@unit@parse@queue@den \def\si@unit@parse@type@last{start}% \def\si@unit@parse@type@last@den{start}% \expandafter\def\expandafter\si@unit@parse@sep\expandafter{% \expandafter\ensuremath\expandafter{\si@unit@out@unit@sep}% }% \si@unit@parse@block@cnt\z@\relax \si@unit@parse@block@den@cnt\z@\relax \si@bool@false\si@unit@parse@per@last@bool \si@bool@false\si@unit@parse@per@current@bool } \newcommand*{\si@unit@parse@init@aux}[1]{% \si@let@Nc#1{si@unit@macro@\string#1}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@unit@parse@last@if@F} %\begin{macro}{\si@unit@parse@last@if@T} %\begin{macro}{\si@unit@parse@last@if@TF} % Checks on the last addition are queue-dependent. % \begin{macrocode} \newcommand*{\si@unit@parse@last@if@F}[1]{% \si@meaning@eq@cs@if@F {si@unit@parse@type@last\si@unit@parse@queue@use}% {si@unit@parse@type@#1}% } \newcommand*{\si@unit@parse@last@if@T}[1]{% \si@meaning@eq@cs@if@T {si@unit@parse@type@last\si@unit@parse@queue@use}% {si@unit@parse@type@#1}% } \newcommand*{\si@unit@parse@last@if@TF}[1]{% \si@meaning@eq@cs@if@TF {si@unit@parse@type@last\si@unit@parse@queue@use}% {si@unit@parse@type@#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@unit@parse@options} % Any unit-specific options are loaded, followed by re-applying any % options given for this particular macro. All a bit complicated, as % there is probably more than one token in the input. % \begin{macrocode} \newcommand*{\si@unit@parse@options}[1]{% \si@csname@if@T{si@unit@options@\expandafter\string\@car#1\@nil}{% \edef\si@tempa{% \expandafter\expandafter\expandafter\unexpanded \expandafter\expandafter\expandafter{% \csname si@unit@options@\expandafter\string\@car#1\@nil \endcsname },% \expandafter\unexpanded\expandafter{\si@unit@internal@opts}% }% \expandafter\sisetup\expandafter{\si@tempa}% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@parse@queue@use} % Which queue is in use needs to be available: the main queue variables % have no ending, whereas the denominator ones do. % \begin{macrocode} \newcommand*{\si@unit@parse@queue@use}{% \si@bool@if@T\si@unit@parse@fraction@bool{% \si@bool@if@T\si@unit@parse@per@current@bool{@den}% }% } % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@parse@store} % The outer storage macro does nothing: the steps needed are left to the % dedicated procedures. % \begin{macrocode} \newcommand*{\si@unit@parse@store}[2]{% \@nameuse{si@unit@parse@store@#1}{#2}% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@parse@store@add@n} %\begin{macro}{\si@unit@parse@store@add@o} % A general addition function. % \begin{macrocode} \newcommand*{\si@unit@parse@store@add@n}[1]{% \si@add@right@cs@n{si@unit@parse@block\si@unit@parse@queue@use}{#1}% } \newcommand*{\si@unit@parse@store@add@o}[1]{% \si@add@right@cs@o{si@unit@parse@block\si@unit@parse@queue@use}{#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@parse@store@power} %\begin{macro}[aux]{\si@unit@parse@store@power@aux} %\begin{macro}{\si@unit@parse@store@power@inv} % Powers can follow qualifiers or units. If a qualifier comes first, % there may be a need to add brackets. The power has to be turned over % if there is a reciprocal. The argument here is only needed as the % calling function supplies one: the key is the value in % \cs{si@unit@parse@power@current}. % \begin{macrocode} \newcommand*{\si@unit@parse@store@power}[1]{% \si@unit@parse@last@if@T{qual}{% \si@bool@if@F\si@unit@parse@qual@sub@bool{% \si@unit@parse@bracket{block\si@unit@parse@queue@use}% }% \si@unit@parse@store@power@aux }% \si@unit@parse@last@if@T{unit}{% \si@unit@parse@store@power@aux }% \si@clear@macro\si@unit@parse@power@current } % \end{macrocode} % The auxiliary function checks for inversion then recovers the % numerical part of the power for typesetting. % \begin{macrocode} \newcommand*{\si@unit@parse@store@power@aux}{% \si@unit@parse@store@type{power}% \si@bool@if@T\si@unit@parse@per@current@bool{% \si@bool@if@F\si@unit@parse@fraction@bool{% \si@unit@parse@store@power@inv }% }% \def\si@tempa{1}% \si@meaning@eq@if@F\si@unit@parse@power@current\si@tempa{% \si@unit@parse@store@add@o{% \expandafter^\expandafter{\si@unit@parse@power@current}% }% }% } % \end{macrocode} % A quick inverse function which does not use \TeX\ numbers. % \begin{macrocode} \newcommand*{\si@unit@parse@store@power@inv}{% \si@in@if@TF\si@unit@parse@power@current{-}{% \def\si@tempa##1-##2\si@stop{% \def\si@unit@parse@power@current{##2}% }% }{% \si@add@left@n\si@unit@parse@power@current{-}% }% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@parse@store@prefix} % Unless the last addition was another prefix, all that has to happen % here is to start a new block. % \begin{macrocode} \newcommand*{\si@unit@parse@store@prefix}[1]{% \si@unit@parse@last@if@F{prefix}{% \si@unit@parse@store@type{prefix}% \si@unit@parse@block@new{#1}% }% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@parse@store@qual} % Qualifiers can only be added after units. % \begin{macrocode} \newcommand*{\si@unit@parse@store@qual}[1]{% \si@unit@parse@last@if@T{unit}{% \si@unit@parse@store@add@o{\si@unit@parse@qual@format{#1}}% \si@unit@parse@store@type{qual}% }% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@parse@store@type} % All of the type changes are the same. % \begin{macrocode} \newcommand*{\si@unit@parse@store@type}[1]{% \si@let@cc{si@unit@parse@type@last\si@unit@parse@queue@use}% {si@unit@parse@type@#1}% } % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@parse@store@unit} % When storing units, following anything other than a prefix means % starting a new block. A track is also kept of how many units have been % added to the queue as this may be needed later. % \begin{macrocode} \newcommand*{\si@unit@parse@store@unit}[1]{% \si@count@incr@cs{si@unit@parse@block\si@unit@parse@queue@use @cnt}% \si@unit@parse@last@if@TF{prefix}{% \si@unit@parse@store@type{unit}% \si@unit@parse@store@add@n{#1}% }{% \si@unit@parse@store@type{unit}% \si@unit@parse@block@new{#1}% }% } % \end{macrocode} %\end{macro} % %\subsection{Macro unit output} % %\begin{macro}{\si@unit@out@literal@unit} % A storage area used for literal printing. % \begin{macrocode} \newcommand*{\si@unit@out@literal@unit}{} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@out@bracket@close} %\begin{macro}{\si@unit@out@bracket@open} % For dealing with ambiguous output. % \begin{macrocode} \newcommand*{\si@unit@out@bracket@close}{} \newcommand*{\si@unit@out@bracket@open}{} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@out@bracket@use@bool} % A flag for using brackets. % \begin{macrocode} \si@bool@new\si@unit@out@bracket@use@bool % \end{macrocode} %\end{macro} %\begin{macro}{\si@unit@out@break@bool} %\begin{macro}{\si@unit@out@lit@allow@bool} %\begin{macro}{\si@unit@out@num@sep} %\begin{macro}{\si@unit@out@unit@sep} %\begin{macro}{\si@unit@out@unit@space} % Storage for various options. % \begin{macrocode} \si@bool@new\si@unit@out@break@bool \si@bool@new\si@unit@out@lit@allow@bool \newcommand*{\si@unit@out@num@sep}{} \newcommand*{\si@unit@out@unit@sep}{} \newcommand*{\si@unit@out@unit@space}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % % The unit options are set up. % \begin{macrocode} \pgfkeys{ /siunitx/units/output, allow literal units/.is siunitx switch = {unit@out@lit@allow}, allow number-unit breaks/.is siunitx switch = {unit@out@break}, close bracket/.store in = \si@unit@out@bracket@close, inter-unit separator/.store in = \si@unit@out@unit@sep, inter-unit space/.store in = \si@unit@out@unit@space, number-unit separator/.store in = \si@unit@out@num@sep, open bracket/.store in = \si@unit@out@bracket@open, use brackets/.is siunitx switch = {unit@out@bracket@use}, %( allow literal units = true, allow number-unit breaks = false, close bracket = ), inter-unit separator = \,, inter-unit space = \,, number-unit separator = \,, open bracket = (, % use brackets = true } % \end{macrocode} % %\begin{macro}{\si@unit@out@literal} %\begin{macro}[aux]{\si@unit@out@literal@aux} % If the unit given contains anything which is not a unit macro, then % any unit macros that are there simply dump literal meanings. % \begin{macrocode} \newcommand*{\si@unit@out@literal}[1]{% \si@loop@over@macro\si@unit@def@list\si@unit@out@literal@aux \si@unit@out@literal@print{#1}% } \newcommand*{\si@unit@out@literal@aux}[1]{% \si@let@Nc#1{si@unit@literal@\string#1}% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@unit@out@literal@print} % When printing literal units, there is a little work to do sorting out % |~| and |.| characters at the outer level. Once that is done, the % standard printing routine can take over. % \begin{macrocode} \si@catcode@set{46}{13}% . \si@catcode@set{38}{13}% & \newcommand*{\si@unit@out@literal@print}[1]{% \def\si@unit@out@literal@unit{#1}% \si@unit@out@replace@fullstops\si@unit@out@literal@unit \si@unit@out@replace@tildes\si@unit@out@literal@unit \begingroup \si@catcode@set{38}{13}% & \si@catcode@set{126}{13}% ~ \let.\si@unit@out@unit@sep \let&\si@unit@out@unit@space \protected@edef\si@unit@out@literal@unit{\si@unit@out@literal@unit}% \si@print@unit@o{\si@unit@out@literal@unit}% \endgroup } \si@catcode@set{46}{12}% . % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unit@out@replace@fullstops} %\begin{macro}{\si@unit@out@replace@tildes} % Two replacement jobs are needed. In the case of fullstops, things are % quite obvious. Non-grouped fullstops are made active, so that they can % be replaced by the appropriate macro. For tildes, things are slightly % different. They will be active anyway (under normal circumstances), % but the behaviour of the non-grouped ones should be different from any % within groups. So the outer level ones are replaced with an active |&|. % \begin{macrocode} \si@lccode@set{38}{46}% & -> . \lowercase{% \newcommand*{\si@unit@out@replace@fullstops}[1]{% \si@replace@all@in#1{.}{&}% } } \si@lccode@set{38}{0}% & -> & \newcommand*{\si@unit@out@replace@tildes}[1]{% \si@replace@all@in#1{~}{&}% } \si@catcode@set{38}{4}% & % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@unit@out@sep@print} % The number--unit separator is printed as part of the output routine. % So that it can be altered by units ``on the fly'', it is packaged up % here as a macro. % \begin{macrocode} \newcommand*{\si@unit@out@sep@print}{% \ensuremath{% \si@bool@if@TF\si@unit@out@break@bool{% \allowbreak }{% \nobreak }% \si@unit@out@num@sep }% } % \end{macrocode} %\end{macro} % %\subsection{Symbols} % % Not all units use letters alone for their symbol. This raises two % problems. First, the symbols need to work in maths and in text mode. % Second, the user needs to be able to adjust each symbol. % %\begin{macro}{\si@symbol@redefine@bool} % A flag for redefining symbols. % \begin{macrocode} \si@bool@new\si@symbol@redefine@bool % \end{macrocode} %\end{macro} % There is one option which apply to symbols in general. % \begin{macrocode} \si@keys@family{symbols} \pgfkeys{ /siunitx/symbols, redefine symbols/.is siunitx switch = {symbol@redefine}, redefine symbols = true } % \end{macrocode} % %\begin{macro}{\si@symbols@redefine} % The redefinition of symbols has to do a number of checks to ensure % that there are no clashes. % \begin{macrocode} \newcommand*{\si@symbol@redefine}{% \si@bool@if@T\si@symbol@redefine@bool{% \@ifpackageloaded{textcomp}{% \sisetup{ symbols/maths/degree = \text{\textdegree}, symbols/text/degree = \textdegree }% \@ifpackageloaded{mathptmx}{}{% \sisetup{ symbols/text/micro = \textmu, symbols/text/ohm = \textomega }% }% \def\si@tempa{OT1}% \si@meaning@eq@if@T\si@tempa\encodingdefault{% \sisetup{ symbols/maths/angstrom = \text{\capitalring{A}}, symbols/text/angstrom = \capitalring{A} }% }% }{}% \@ifpackageloaded{upgreek}{% \sisetup{ symbols/maths/ohm = \Upomega } }{}% }% } \AtBeginDocument{\si@symbol@redefine} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@symbol@maths@angstrom} %\begin{macro}{\si@symbol@maths@arcminute} %\begin{macro}{\si@symbol@maths@arcsecond} %\begin{macro}{\si@symbol@maths@celsius} %\begin{macro}{\si@symbol@maths@degree} %\begin{macro}{\si@symbol@maths@micro} %\begin{macro}{\si@symbol@maths@ohm} % The storage macros are created for symbols: first for maths mode. % \begin{macrocode} \newcommand*{\si@symbol@maths@angstrom}{} \newcommand*{\si@symbol@maths@arcminute}{} \newcommand*{\si@symbol@maths@arcsecond}{} \newcommand*{\si@symbol@maths@celsius}{} \newcommand*{\si@symbol@maths@degree}{} \newcommand*{\si@symbol@maths@micro}{} \newcommand*{\si@symbol@maths@ohm}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %%\begin{macro}{\si@symbol@text@angstrom} %\begin{macro}{\si@symbol@text@arcminute} %\begin{macro}{\si@symbol@text@arcsecond} %\begin{macro}{\si@symbol@text@celsius} %\begin{macro}{\si@symbol@text@degree} %\begin{macro}{\si@symbol@text@micro} %\begin{macro}{\si@symbol@text@ohm} % Then for text mode. % \begin{macrocode} \newcommand*{\si@symbol@text@angstrom}{} \newcommand*{\si@symbol@text@arcminute}{} \newcommand*{\si@symbol@text@arcsecond}{} \newcommand*{\si@symbol@text@celsius}{} \newcommand*{\si@symbol@text@degree}{} \newcommand*{\si@symbol@text@micro}{} \newcommand*{\si@symbol@text@ohm}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % % The symbol storage macros are created separately for maths 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 % maths mode omega option, the |\text{\ensuremath{...}}| construction % deals with the case where \cs{mathnormal} has the wrong symbol. % \begin{macrocode} \si@keys@family{symbols/maths} \pgfkeys{ /siunitx/symbols/maths, angstrom/.store in = \si@symbol@maths@angstrom, arcminute/.store in = \si@symbol@maths@arcminute, arcsecond/.store in = \si@symbol@maths@arcsecond, celsius/.store in = \si@symbol@maths@celsius, degree/.store in = \si@symbol@maths@degree, micro/.store in = \si@symbol@maths@micro, ohm/.store in = \si@symbol@maths@ohm, angstrom = \text{\AA}, arcminute = {}^{\prime}, arcsecond = {}^{\prime\prime}, celsius = {}^{\circ}\kern-\scriptspace C, degree = {}^{\circ}, micro = \si@symbol@maths@mu, ohm = \text{\ensuremath{\Omega}} } \si@keys@family{symbols/math} \pgfkeys{ /siunitx/symbols/math, angstrom/.store in = \si@symbol@maths@angstrom, arcminute/.store in = \si@symbol@maths@arcminute, arcsecond/.store in = \si@symbol@maths@arcsecond, celsius/.store in = \si@symbol@maths@celsius, degree/.store in = \si@symbol@maths@degree, micro/.store in = \si@symbol@maths@micro, ohm/.store in = \si@symbol@maths@ohm, } \si@keys@family{symbols/text} \pgfkeys{ /siunitx/symbols/text, angstrom/.store in = \si@symbol@text@angstrom, arcminute/.store in = \si@symbol@text@arcminute, arcsecond/.store in = \si@symbol@text@arcsecond, celsius/.store in = \si@symbol@text@celsius, degree/.store in = \si@symbol@text@degree, micro/.store in = \si@symbol@text@micro, ohm/.store in = \si@symbol@text@ohm, angstrom = \AA, arcminute = \ensuremath{{}^{\prime}}, arcsecond = \ensuremath{{}^{\prime\prime}}, celsius = \ensuremath{{}^{\circ}}\kern-\scriptspace C, degree = \ensuremath{{}^{\circ}}, micro = \si@symbol@text@mu, ohm = \ensuremath{\Omega} } % \end{macrocode} % %\begin{macro}{\si@symbol@new} % For creating the outer symbol macro. % \begin{macrocode} \newcommand*{\si@symbol@new}[1]{% \expandafter\si@newcommand\expandafter*\expandafter{% \csname SIUnitSymbol#1\endcsname }{% \si@mode@maths@if@TF{% \lowercase{\@nameuse{si@symbol@maths@#1}}% }{% \lowercase{\@nameuse{si@symbol@text@#1}}% }% }% } % \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} \si@symbol@new{Angstrom} \si@symbol@new{Arcminute} \si@symbol@new{Arcsecond} \si@symbol@new{Celsius} \si@symbol@new{Degree} \si@symbol@new{Micro} \si@symbol@new{Ohm} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\si@symbol@text@mu} % The lack of an upright mu has to be sorted out by hand: text mode is % relatively easy as there is no limit on the number of fonts. % \begin{macrocode} \DeclareFontEncoding{TS1}{}{} \DeclareFontSubstitution{TS1}{cmr}{m}{n} \DeclareTextSymbol{\si@symbol@text@mu}{TS1}{181} \DeclareTextSymbolDefault{\si@symbol@text@mu}{TS1} % \end{macrocode} %\end{macro} %\begin{macro}{\si@symbol@check@upgreek} %\begin{macro}{\si@symbol@maths@mu} % For maths mode, there is more work to do. The definition here is % taken from the \pkg{upgreek} package, but is only implemented if % the later is not loaded. % \begin{macrocode} \newcommand*{\si@symbol@check@upgreek}{% \@ifpackageloaded{upgreek}{% \let\si@symbol@maths@mu\upmu }{% \DeclareFontFamily{OML}{eur}{\skewchar\font127}% \DeclareFontShape{OML}{eur}{m}{n}% {<-6> eurm5 <6-8> eurm7 <8-> eurm10}{}% \DeclareSymbolFont{si@symbol}{OML}{eur}{m}{n}% \DeclareMathSymbol{\si@symbol@maths@mu}{\mathord}{si@symbol}{22}% }% } \AtBeginDocument{\si@symbol@check@upgreek} % \end{macrocode} %\end{macro} %\end{macro} % %\subsection{Design-level macros} % % The macros for creating units and so on are in ``design'' name-space. % These are therefore \emph{not} \cs{protected}. Much of this is simple % translation to the internal macro names, with perhaps some argument % re-arrangement. % %\begin{macro}{\DeclareSIPower} %\begin{macro}{\DeclareSIPrefix} %\begin{macro}{\DeclareSIQualifier} %\begin{macro}{\DeclareSIUnit} % For creating units and associated functions: only \cs{DeclarSIUnit} % takes arguments here as the optional and mandatory ones are % re-ordered. % \begin{macrocode} \newcommand*{\DeclareSIPower}{% \@ifstar{% \si@unit@def@power@post }{% \si@unit@def@power }% } \newcommand*{\DeclareSIPrefix}{% \@ifstar{% \si@unit@def@prefix@binary }{% \si@unit@def@prefix }% } \newcommand*{\DeclareSIQualifier}{% \si@unit@def@qual } \newcommand*{\DeclareSIUnit}[2][]{% \si@unit@def@unit{#2}{#1}% } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % % None of this should be done after the preamble. % \begin{macrocode} \@onlypreamble\DeclareSIPower \@onlypreamble\DeclareSIPrefix \@onlypreamble\DeclareSIQualifier \@onlypreamble\DeclareSIUnit % \end{macrocode} % %\subsection{Document macros} % % The user document macros are all collected together here for ease: all % of them are \cs{protected}. % %\begin{macro}{\sisetup} % The set up macro simply moves to the correct path and executes % whatever has been passed. % \begin{macrocode} \si@newcommand*{\sisetup}[1]{% \pgfqkeys{/siunitx}{#1}% } % \end{macrocode} %\end{macro} % %\begin{macro}{\num} %\begin{macro}{\si@num@internal} % The \cs{num} macro is quite simple: read the number, check it is % correct then print it. As the internal part is re-used by \cs{SI}, it % is made into a separate short macro. % \begin{macrocode} \si@newcommand*{\num}[2][]{% \begingroup \sisetup{#1}% \si@num@internal{#2}% \endgroup } \newcommand*{\si@num@internal}[1]{% \si@num@pre@process{#1}% \si@bool@if@F\si@num@pre@error@bool{% \si@num@in@parse@o{\si@num@pre@arg}% \si@bool@if@F\si@num@in@error@bool{% \si@num@post@process \si@num@out@process \si@num@print }% }% } % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\SI} %\begin{macro}{\si@unit@internal@i} % The main \cs{SI} macro has to do a bit of shuffling so that internally % there are exactly four arguments. This is done in two steps, first % collecting the first optional and mandatory arguments, then the % second set before handing off to the business end. % \begin{macrocode} \si@newcommand*{\SI}[2][]{% \begingroup \def\si@tempa{{#1}{#2}}% \si@unit@internal@i } \newcommand*{\si@unit@internal@i}[2][]{% \expandafter\si@unit@internal@ii\si@tempa{#1}{#2}% } % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unit@internal@ii} %\begin{macro}{\si@unit@internal@opts} % \begin{macrocode} \newcommand*{\si@unit@internal@ii}[4]{% TEMP \sisetup{#1}% \def\si@unit@internal@opts{#1}% \si@unit@in@parse{#3}% \si@num@internal{#2}% \si@bool@if@F\si@num@in@error@bool{% \si@empty@tlist@if@T{#4}{% \let\si@unit@out@sep@print\relax }% }% \si@unit@in@parse{#4}% \endgroup } \newcommand*{\si@unit@internal@opts}{} % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si} % The \cs{si} macro can be much less complex than \cs{SI}. Only two % steps are needed: applying local settings and parsing the unit. % \begin{macrocode} \si@newcommand*{\si}[2][]{% \begingroup \sisetup{#1}% \si@unit@in@parse{#2}% \endgroup } % \end{macrocode} %\end{macro} % %\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}{\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} %\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} % A number of derived units with defined names and symbols. % \begin{macrocode} \DeclareSIUnit{\becquerel}{Bq} \DeclareSIUnit{\celsius}{\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} \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} %\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[units/output/number-unit separator={}] {\arcmin}{\arcminute} \DeclareSIUnit[units/output/number-unit separator={}] {\arcminute}{\SIUnitSymbolArcminute} \DeclareSIUnit[units/output/number-unit separator={}] {\arcsecond}{\SIUnitSymbolArcsecond} \DeclareSIUnit{\day}{d} \DeclareSIUnit[units/output/number-unit separator={}] {\degree}{\SIUnitSymbolDegree} \DeclareSIUnit{\hectare}{ha} \DeclareSIUnit{\hour}{h} \DeclareSIUnit{\litre}{l} \DeclareSIUnit{\liter}{L} \DeclareSIUnit{\minute}{min} \DeclareSIUnit{\percent}{\char37} \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}{ua} \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 ``natural units''. % \begin{macrocode} \DeclareSIUnit{\clight}{\text{\ensuremath{c_{0}}}} \DeclareSIUnit{\electronmass}{\text{\ensuremath{m_{\text{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 ``atomic units''. % \begin{macrocode} \DeclareSIUnit{\elementarycharge}{\text{\ensuremath{e}}} \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}{\bel} %\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} \DeclareSIPower{\square}{2} \DeclareSIPower*{\squared}{2} \DeclareSIPower{\cubic}{3} \DeclareSIPower*{\cubed}{3} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\subsection{Finalisation} % % All done: any odd codes can be restored. % \begin{macrocode} \si@catcode@restore \si@lccode@restore % % \end{macrocode} % %\Finale