% \iffalse meta-comment % % Copyright (C) 2008 by % Joseph Wright % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either % version 1.3c of this license or (at your option) any later % version. The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of % LaTeX version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained.' % % The current maintainer of this work is Joseph Wright. % % This work consists of the source file si.dtx % and the derived files si.ins, % si.sty, % si.pdf, % si-SIunits.cfg, % si-sistyle.cfg, % si-unitsdef.cfg, % si-units.cfg, % si-prefix.cfg, % si-named.cfg, % si-prefixed.cfg, % si-addn.cfg, % si-abbr.cfg and % si-accepted.cfg % % % Unpacking: % (a) If si.ins is present: % tex si.ins % (b) Without si.ins: % tex si.dtx % (c) If you use LaTeX to generate files: % latex \let\install=y\input{si.dtx} % % Documentation: % (a) Without write18 enabled: % pdflatex si.dtx % bibtex8 --wolfgang si % makeindex -s gind.ist si.idx % makeindex -s gglo.ist -o si.gls si.glo % pdflatex si.dtx % makeindex -s gind.ist si.idx % makeindex -s gglo.ist -o si.gls si.glo % pdflatex si.dtx % (b) With write18 enabled: % pdflatex si.dtx % bibtex8 --wolfgang si % pdflatex si.dtx % pdflatex si.dtx % % Installation: % Copy si.sty and the various .cfg files to a location % searched by TeX, and if required by your TeX installation, % run the appropriate command to build a hash of files % (texhash, mpm --update-db, etc.) % % Note: % The jawltxdoc.sty file is not needed for installation, % only for building the documentation; it may be deleted % after producing the documentation (if necessary). % %<*ignore> % This is all taken verbatim from Heiko Oberdiek's packages \begingroup \def\x{LaTeX2e}% \expandafter\endgroup \ifcase 0\ifx\install y1\fi\expandafter \ifx\csname processbatchFile\endcsname\relax\else1\fi \ifx\fmtname\x\else 1\fi\relax \else\csname fi\endcsname % %<*install> \input docstrip.tex \keepsilent \askforoverwritefalse \preamble ---------------------------------------------------------------- The si 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 \Msg{Generating si files:} \usedir{tex/latex/contib/si} \generate{\file{\jobname.ins}{\from{\jobname.dtx}{install}} \file{\jobname.sty}{\from{\jobname.dtx}{package}} \file{jawltxdoc.sty}{\from{\jobname.dtx}{jawltxdoc}} } \usedir{tex/latex/contib/config} \generate{\file{si-SIunits.cfg}{\from{\jobname.dtx}{SIunits}} \file{si-sistyle.cfg}{\from{\jobname.dtx}{sistyle}} \file{si-unitsdef.cfg}{\from{\jobname.dtx}{unitsdef}} \file{si-units.cfg}{\from{\jobname.dtx}{units}} } \generate{\file{si-prefix.cfg}{\from{\jobname.dtx}{prefix}} \file{si-named.cfg}{\from{\jobname.dtx}{named}} \file{si-prefixed.cfg}{\from{\jobname.dtx}{prefixed}} \file{si-addn.cfg}{\from{\jobname.dtx}{addn}} \file{si-accepted.cfg}{\from{\jobname.dtx}{accepted}} \file{si-physical.cfg}{\from{\jobname.dtx}{physical}} \file{si-abbr.cfg}{\from{\jobname.dtx}{abbr}} } \generate{\file{si-synchem.cfg}{\from{\jobname.dtx}{synchem}} \file{si-hep.cfg}{\from{\jobname.dtx}{hep}} \file{si-binary.cfg}{\from{\jobname.dtx}{binary}} } \generate{\file{si-UK.cfg}{\from{\jobname.dtx}{UK}} \file{si-USA.cfg}{\from{\jobname.dtx}{USA}} \file{si-germany.cfg}{\from{\jobname.dtx}{germany}} \file{si-south-africa.cfg}{\from{\jobname.dtx} {south-africa}} } \nopreamble \usedir{doc/latex/contib/si} \generate{\file{\jobname.bib}{\from{\jobname.dtx}{refs}} } \endbatchfile % %<*ignore> \fi % Will Robertson's trick \immediate\write18{makeindex -s gind.ist -o \jobname.ind \jobname.idx} \immediate\write18{makeindex -s gglo.ist -o \jobname.gls \jobname.glo} % %<*driver> \PassOptionsToClass{a4paper}{article} \documentclass{ltxdoc} \EnableCrossrefs \CodelineIndex \RecordChanges %\OnlyDescription % The various formatting commands used in this file are collected % together in |jawltxdoc|. \usepackage{jawltxdoc,textcomp} \usepackage[latin1]{inputenc} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % %\CheckSum{6764} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % %\GetFileInfo{\jobname.sty} % %\DoNotIndex{\@car,\@eha,\@ehc,\@empty,\@firstofone,\@firstoftwo} %\DoNotIndex{\@for,\@gobble,\@gobbletwo,\@ifl@aded,\@ifnextchar} %\DoNotIndex{\@ifpackagelater,\@ifpackageloaded,\@ifstar} %\DoNotIndex{\@ifundefined,\@makeother,\@namedef,\@nameuse,\@ne} %\DoNotIndex{\@nil,\@secondoftwo,\@temptokena,\@undefined,\AA} %\DoNotIndex{\active,\addto,\addtolength,\advance,\afterassignment} %\DoNotIndex{\aftergroup,\AtBeginDocument,\AtEndOfPackage} %\DoNotIndex{\begingroup,\bfseries,\bgroup,\boldmath,\box} %\DoNotIndex{\capitalring,\catcode,\cdot,\chardef,\check@mathfonts} %\DoNotIndex{\circ,\csname,\DeclareFontEncoding,\DeclareFontFamily} %\DoNotIndex{\DeclareFontShape,\DeclareFontSubstitution} %\DoNotIndex{\DeclareMathSymbol,\DeclareRobustCommand} %\DoNotIndex{\DeclareSymbolFont,\DeclareTextSymbol} %\DoNotIndex{\DeclareTextSymbolDefault,\def,\define@boolkey} %\DoNotIndex{\define@choicekey,\define@cmdkey,\define@cmdkeys} %\DoNotIndex{\define@key,\displaystyle,\displaywidth,\divide,\do} %\DoNotIndex{\edef,\egroup,\else,\encodingdefault,\end,\endcsname} %\DoNotIndex{\endgroup,\endinput,\endtabular,\ensuremath} %\DoNotIndex{\expandafter,\f@family,\f@series,\fam,\fi,\font} %\DoNotIndex{\fontsize,\frac,\gdef,\global,\hbox,\hfil,\hfill,\hskip} %\DoNotIndex{\hspace,\hss,\ifcsname,\ifdim,\iffalse,\IfFileExists} %\DoNotIndex{\ifmmode,\ifnum,\ifx,\ignorespaces,\inputencodingname} %\DoNotIndex{\InputIfFileExists,\key@ifundefine,\let,\long,\m@ne} %\DoNotIndex{\makeatletter,\math@version,\mathchoice,\mathnormal} %\DoNotIndex{\mathord,\mathrm,\mathsf,\mathtt,\mdseries} %\DoNotIndex{\MessageBreak,\mkern,\mp,\NC@find,\NeedsTeXFormat} %\DoNotIndex{\newbox,\newcolumntype,\newcommand,\newcount,\newdimen} %\DoNotIndex{\newif,\newlength,\newtoks,\nobreak,\noexpand,\p@} %\DoNotIndex{\PackageError,\PackageInfo,\PackageWarning,\phantom} %\DoNotIndex{\ProcessOptionsX,\protect,\protected@edef,\ProvidesFile} %\DoNotIndex{\ProvidesPackage,\Q,\raisebox,\relax,\renewcommand} %\DoNotIndex{\RequirePackage,\rlap,\sbox,\scantokens} %\DoNotIndex{\scriptscriptstyle,\scriptstyle,\selectfont,\setbox} %\DoNotIndex{\setkeys,\setlength,\settoheight,\sf@size,\sfdefault} %\DoNotIndex{\sfrac,\skewchar,\sp,\space,\string,\strip@pt} %\DoNotIndex{\tabularnewline,\text,\textdegree,\textmu,\textohm} %\DoNotIndex{\textsc,\textstyle,\textsuperscript,\the,\thr@@,\times} %\DoNotIndex{\ttdefault,\uccode,\unboldmath,\unhbox,\upmu,\Upomega} %\DoNotIndex{\uppercase,\upshape,\wd,\xdef,\xspace,\z@} % %\changes{0.6}{2008/02/18}{First public release} % %\setkeys{lst}{language=[LaTeX]{TeX},moretexcs={sisetup,num,ang,SI, % unitsym,newunit,newpower,newprefix,metre,candela,kelvin,ampere, % second,mole,per,kilogram,Square,squared,cubed,cubic,kilo,centi, % gram,tothe,toprule,midrule,bottomrule}} % %\title{\currpkg\ --- A comprehensive (SI) units package^^A % \thanks{This file describes version \fileversion, last revised % \filedate.}} %\author{Joseph Wright^^A % \thanks{E-mail: joseph.wright@morningstar2.co.uk}} %\date{Released \filedate} % %\maketitle % %\newcommand*{\SIunits}{\pkg{SIunits}\xspace} %\newcommand*{\sistyle}{\pkg{sistyle}\xspace} %\newcommand*{\unitsdef}{\pkg{unitsdef}\xspace} %\newcommand*{\unitspkg}{\pkg{units}\xspace} %\newcommand*{\numprint}{\pkg{numprint}\xspace} %\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). A number of \LaTeX\ % packages have been developed to provide consistent application of % the various rules: \SIunits, \sistyle, \unitsdef and \unitspkg are % the leading examples. The \numprint package provides a large number % of number-related functions, while \pkg{dcolumn} and \pkg{rccol} % provide tools for typesetting tabular numbers. % % The \currpkg package takes the best from the existing packages, and % adds new features and a consistent interface. A number of new % ideas have been incorporated, to fill gaps in the existing % provision. The package also provides backward-compatibility with % \SIunits, \sistyle, \unitsdef and \unitspkg. The aim is to have one % package to handle all of the possible unit-related needs of \LaTeX\ % users. %\end{abstract} % %\begin{multicols}{2} % \tableofcontents %\end{multicols} % %\part{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 % \latin{Conf\'erence G\'en\'erale des Poids et % Mesures}\footnote{General Conference on Weights and Measures.} % (CGPM); this has resulted in the \latin{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. % % \LaTeX\ support typesetting numbers and units is currently provided % by a number of packages: \SIunits, \sistyle, \unitspkg, \unitsdef % and \numprint. Each package has advantages, and no single package % has so far displaced use of the others. The aim of the \currpkg % package is to learn from the existing implementations to provide a % coherent and extendable approach to the problem. The original aim % of developing \currpkg was to produce a ``version 2'' successor to % \SIunits or \sistyle. However, as the package has been developed a % number of inconsistencies in the interfaces of the existing % packages have been noted. Thus by default \currpkg does not follow % any one of the existing packages; the interface is intended to be % self-consistent and logical. As a result, \currpkg is now intended % as a new package. The author hopes that by providing a % comprehensive package here, the other ``unit'' packages will be % superseded. % % 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. In % emulation mode, \currpkg tries hard to work in exactly the same % manner as the emulated package. However, in certain places % inconsistencies exist due to changes in the underlying mechanisms % used. These are noted where they are known to the package author. % %\section{Existing packages} % Both the \SIunits an \sistyle package are designed to % allow typesetting of SI units, with consistent typography and % following the rules laid down by \textsc{nist} % \cite{NIST}.\footnote{\sistyle also allows the use of German % and South African rules ``out of the box''.} The \sistyle % package concentrates on typography, whereas the \SIunits % package is focussed on careful application of SI units in place of % other systems. The key strengths of the two packages can be % summarised as follows:\footnote{Thanks to Stefan Pinnow for the % excellent summary on \texttt{comp.text.tex}, on which this is % based.} %\begin{itemize} % \item \sistyle % \begin{itemize} % \item Easy input for numbers, for example typing % |\num{5.8e-7}| and getting ``\num{5.8e-7}'' as output. % \item Input of numbers can be with comma or dot as decimal % sign and is independent of output. % \item Output style can follow particular regional conventions % (\latin{via} \cs{sistyle}) or even be dependent on the % document language (implemented by \cs{sistyleToLang}). % \end{itemize} % \item \SIunits % \begin{itemize} % \item The look of units can be easily be changed in the whole % document by redefining the commands. % \item New units can be added on a document-specific basis % (\cs{addunit}), for example to match journal requirements ( % \eg\ ``wt.-\%" \latin{versus} ``wt\%''). % \item Package aims to enforce use of SI units as far as % possible. % \end{itemize} %\end{itemize} % % At the same time, the \unitsdef package allows ``trailing'' units, % so for example |10\metre| to yield ``10\metre'' with a non-breaking % and definable space. However, this does not allow control of the % format of the number. The \unitsdef package is built on top of % \unitspkg, which is an even more general. The \numprint package % provides fine control for printing numbers, with features beyond % those in \sistyle. Finally, the \pkg{hepunits} package adds % various physics units to \SIunits. % %\section{The wish-list} %\newcommand*{\WishlistStatus}[1]{\textbf{#1}} %\newcommand*{\Todo}{\WishlistStatus{To do}} %\newcommand*{\Ongoing}{\WishlistStatus{Ongoing}} %\newcommand*{\Completed}{\WishlistStatus{Completed}} % The wish-list for the new package has developed as ideas have % suggested themselves. This has been both from the package author % and various contributors on \texttt{comp.text.tex}. Anything on % the list is likely to be looked at: nothing is ruled out. Items % marked \Todo\ are definitely going to be looked at, those marked % \Ongoing\ have at least some code written. Items marked % \Completed\ seem to work properly, and at this stage seem to be % finished (in the sense that changes are not planned). However, % that does not mean they are finalised or bug free! %\begin{itemize} % \item \pkg{keyval} package interface, with modification of % settings in document using this system (like \pkg{hyperref}). % \Completed % \item Remove need for \cs{usk} separator between unit names when % using \SIunits-style setup. \Completed % \item ``Prefix'' units, such as currency, possibly as an optional % argument to \cs{SI}: % |\SI[per=slash]{10}[\pounds]{\per\kilo\gram}| $\Rightarrow$ % ``\SI[per=slash]{10}[\pounds]{\per\kilo\gram}'' (suggested by % Allan Ristow). \Completed % \item Stand-alone setting of units, for example % |\unitsym{kg.m/s^2}| to give ``\unitsym{kg.m/s^2}'', for use in % table headings, \etc\ (suggested by Allan Ristow). \Completed % \item \numprint-like handling of numbers (suggested by Allan % Ristow). \Completed % \item Ability to handle crystallography-style estimated standard % deviations, \eg\ |\SI{1.550(2)}{\angstrom}| $\Rightarrow$ % ``\SI{1.550(2)}{\angstrom}''.\footnote{$(1.550 \pm 0.002) \times % 10^{-10}$\,m.} \Completed % \item Ability to understand and alter negative powers/fractions, % and typeset these flexibly; thus |\unitsym{\metre\per\second}| % could give ``\unitsym{\metre\per\second}'', % ``\unitsym[per=slash]{\metre\per\second}'', % ``\unitsym[per=frac]{\metre\per\second}'' or % ``\unitsym[per=frac,fraction=nice]{\metre\per\second}'' % depending on a package setting (suggested by Stefan Pinnow). % \Completed % \item More logical handling of powers; for example |\deci\cubic\metre| % or |\deci\metre\cubed| give ``\unitsym{\deci\metre\cubed}'', but % |\deci\cubed\metre| does not even though \cs{deci} \emph{cannot} % be cubed (adapted suggestion from Stefan Pinnow). \Completed % \item Use of trailing units (as in \unitsdef package, so for % example |10\metre| to give ``10\metre'' (suggestion from Lan % Thuy Pham). \Completed % \item Support use of non-Latin characters where appropriate, % for example µ in units as in |\unitsym{µm}| to give % ``\unitsym{µm}'' (suggested by Martin Heller). \Completed % \item Integrate the core functionality of the % \SIunits and \sistyle packages (suggested by Danie % Els,\footnote{Current maintainer of \sistyle.} as well as a % key point of the review). \Completed % \item Modular design, with loadable definitions for different % areas and typographic conventions. \Completed % \item Emulation of existing packages [\unitspkg (\Completed), % \unitsdef (\Completed), \sistyle (\Completed), \SIunits % (\Completed)] to allow easy upgrading. \Completed % \item Typesetting angles in ``astronomy'' style, for example % |\ang[astroang]{30;5;3.2}| to give \ang[astroang]{30;5;3.2} % (suggested by Alok Singhal). \Completed %\end{itemize} % %\section{Road map} % The existing units packages provide valuable information on the % problems and pitfalls of designing a package in this area. They % have also shown how to solve many of the issues arising. However, % in writing a new package, consistent interface design has been % important. This is logical to the package author, but may not be % to anyone else. The functionality provided also aims to cover % everything from the existing packages and the suggestions % contributed at \texttt{comp.text.tex}, but omissions are likely to % exist. The current release of \currpkg is therefore regarded as a % development version, to gain feedback from users and to find % errors. The current ``road map'' for future releases is (broadly) % given here. %\begin{itemize} % \item[v0.6] Seek feedback on implementation to date (current % release); % \item[v0.7] Add or modify functionality based on feedback, % implement new suggestions for wish list; % \item[v0.8] Fix bugs from 0.7 release, interface freeze; % \item[v0.9] Release-candidate: fix remaining bugs from v0.8, % complete remaining documentation; % \item[v1.0] First release of completed package. %\end{itemize} % Depending on user feedback, the gap between these releases will % vary. However, to finalise all of the potential issues will take % some months (to allow time for proper testing). % %\part{Using the \currpkg package} %\section{Requirements} % \currpkg requires a reasonably up to date \TeX\ system. The % package requires \eTeX-extensions, which should be available on % most systems.\footnote{If you have an old \LaTeX\, try % ``\texttt{elatex}'' rather than ``\texttt{latex}''.} The following % packages are also needed: %\begin{itemize} % \item \pkg{array} and \pkg{xspace} from the \pkg{tools} bundle, % which should be available to everyone; % \item \pkg{xkeyval} This processes the option handling, and needs % to be at least v2.5; % \item \pkg{amstext} From the \AMS\TeX\ support bundle --- the % \AMS\ fonts are also needed to provide the default upright % \unitsym{\micro}; %\end{itemize} % Hopefully most people using the package will have access to all of % those items. % % To use the \opt{fraction=sfrac} option, the \pkg{xfrac} package is % needed. This needs various experimental \LaTeX3 packages. As a % result, \currpkg does not load \pkg{xfrac}. If you want to use % \opt{fraction=sfrac}, \emph{you} need to load \pkg{xfrac} in your % preamble. If the package is not loaded, \opt{fraction=sfrac} falls % back on a \pkg{nicefrac}-like method. The interested user should % look at the \pkg{xfrac} documentation for reasons this might not be % ideal.\footnote{On the other hand, some fractional units will look % really bad with \cs{sfrac}. Use this option with caution.} % %\section{Loading the package} % \currpkg is loaded by the usual \LaTeX\ method. %\begin{LaTeXexample}[\typesetcodeonly] % \usepackage{si}\\ % \usepackage[key=option]{si} %\end{LaTeXexample} % As is shown in the example, the package can be loaded with one or % more options, using the \pkg{keyval} system. The full range of % package options are described in Section~\ref{sec:options}; some % options are described in the along with the appropriate user % macros. Most of the user macros accept the same \pkg{keyval} % settings as an optional argument. % %\section{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 \meta{number} % are automatically formatted, in a similar method to that used by % \numprint. The formatter removes ``hard'' spaces (\cs{,} and |~|), % automatically identifies exponents (by default marked using |e| or % |d|) and adds the appropriate spacing of large numbers. A leading % zero is added before a decimal marker, if needed; both |.| and |,| % are recognised as decimal marker. %\begin{LaTeXexample} % \num{1} \num{123} \num{12345} \num{123456}\\ % \num{0.1} \num{0.123} \num{0,1234} \num{.12345}\\ % \num{1e10} \num{3.45d-4} \num{-e10}\\ %\end{LaTeXexample} % Various error-checking systems are built into the package, so % that if \meta{number} does not contain any numeric characters, a % warning is issued. Isolated signs are also detected. The package % recognises |(| and |)| as ``extra'' characters, which can be used to % indicate the error in a number.\footnote{This is common in chemical % crystallography.} %\begin{LaTeXexample} % $\num{1.234(5)} = \num{1.234} \pm \num{0.005}$ %\end{LaTeXexample} % % A number of effects are available as options. These are fully % explained in Section~\ref{sec:options}. Some of the more useful % options are illustrated here. By default, the output of the % package is typeset in maths mode. However, the use of the current % text font can be forced.\footnote{This document is typeset using % lowercase numbers in text mode, which emphasises the effect here.} %\begin{LaTeXexample} % \num{1234567890} \num[mode=text]{1234567890} %\end{LaTeXexample} % \currpkg can automatically add zeros and signs to numbers. This % can be altered as desired. %\begin{LaTeXexample} % \num{1.} \num[padnumber=all]{1.}\\ % \num{2} \num[addsign=all]{2}\\ % \num{3e4} \num[addsign=mant]{3e4} \num[addsign=all]{3e4}\\ % \num{.5} \num[padnumber=none]{.5} %\end{LaTeXexample} % The separation of digits can be turned on and off, and the output % changed. %\begin{LaTeXexample} % \num{1234} \num[sepfour=true]{1234}\\ % \num{12345} \num[digitsep=comma]{12345}\\ % \num[digitsep=none]{12345} %\end{LaTeXexample} % The formatting of exponents is also customisable. %\begin{LaTeXexample} % \num{1e10} \num[expproduct=cdot]{1e10}\\ % \num{2e20} \num[exppower=5]{1e10} %\end{LaTeXexample} % %\section{Tabular material} % Centring numbers in tabular content is handled by a new column % type, the |s| column. This is based closely on the \pkg{dcolumn} % method for centring numbers in columns, but adds the functionality % of the \cs{num} macro.\footnote{The approach used is actually a % combination of \pkg{dcolumn} for centring the material and % \numprint for processing it. It will therefore give rather % different results than the \texttt{n} and \texttt{N} column types % in \numprint.} % % By default, the decimal marker of the contents is placed at the % centre of the column (Table~\ref{tbl:default}). This is achieved % by having a negative value for the key \opt{tabformat}. The second % method for centring content is to specify a number of digits before % and after the decimal sign to be reserved by the package. Thus in % the example, \opt{tabformat=2.4} provides space for two digits % before the decimal marker and four after.\footnote{The separator % for the number of digits before and after the decimal mark may be % essentially any non-numeric character. Thus \opt{tabformat=2.4}, % \opt{tabformat=2,4} and \opt{tabformat=2a4} all give the same % result.} If an integer is given as the argument of % \opt{tabformat}, equal space is reserved before and after the % decimal marker for numerals, and the column is typeset flush right. % As is shown in the fourth column, any other options may also be set % on a column-by-column basis. %\begin{LaTeXexample}[\typesetfloatexample] % \begin{table} % \caption{Behaviour of \texttt{s} column type % \label{tbl:default}} % \centering % \begin{tabular}{ss[tabformat=2.4]s[tabformat=4]% % s[tabformat=2.4,decimalsign=comma]} % \toprule % {Some Values} & {Some Values} & {Some Values} & {Some Values} \\ % \midrule % 2.3456 & 2.3456 & 2.3456 & 2.3456 \\ % 34.2345 & 34.2345 & 34.2345 & 34.2345 \\ % 56.7835 & 56.7835 & 56.7835 & 56.7835 \\ % 90.473 & 90.473 & 90.473 & 90.473 \\ % \bottomrule % \end{tabular} % \end{table} %\end{LaTeXexample} % % Data not to be processed as a number should be protected by % wrapping it in braces; this is most likely to be true for column % headers (again as illustrated). The contents of non-numeric cells % are centred; this can be altered by using the standard % \cs{multicolumn} macro. The use of digit separators in table % columns is accounted for: extra space is reserved if digit % separators will be added. % % The use of exponents in the body of tables is not recommended; % unlike \numprint, \currpkg does not provide additional alignment of % exponents. Certain strange effects can also result from the % exponent marker letters (by default |dDeE|) being picked up by the % package in text in columns. For example, using |<{after}| after a % |s| column will add ``aftr'' at the end of each value. To avoid % this, wrap any problematic text in \emph{two} sets of braces (so % for example, put |<{{after}}|). Alternatively, as part of the % beginning of the table issue the command %\begin{LaTeXexample}[\typesetcodeonly] % \sisetup{numexp={}} %\end{LaTeXexample} % after \cs{begin}|{table}|. % %\section{Angles} %\DescribeMacro{\ang} % Angles can be typeset using the \cs{ang} command. This takes two % arguments, \cs{ang}\oarg{options}\marg{angle}, where \meta{options} % can be any of the package options to apply only to this value. % \meta{angle} can be given either as a decimal number or as a % semi-colon separated list of degrees, minutes and seconds, \ie\ % \cs{ang}\marg{decimal angle} or % \cs{ang}|{|\meta{degrees}|;|\meta{minutes}|;|\meta{seconds}|}|. By % default, no space is introduced between angles and the degrees, % minutes and seconds markers. %\begin{LaTeXexample} % \ang{10} \ang{12.3} \ang{4,5}\\ % \ang{1;2;3} \ang{;;1}\\ % \ang{+10;;} \ang{-0;1;} %\end{LaTeXexample} % % By default, angles with no degrees (or minutes) are zero-filled; % angles with degrees but no minutes or seconds are not filled. This % behaviour can be altered using the package options. %\begin{LaTeXexample} % \ang{;;1} \ang[padangle=none]{;;1}\\ % \ang{2;;} \ang[padangle=all]{2;;}\\ % \sisetup{padangle=all} \ang{;3;} \ang{4;;} \ang{;;5} %\end{LaTeXexample} % The \cs{num} macro is used to typeset each number of the angle, so % the options for \cs{num} also apply here. The \opt{anglesep} value % can be used to separate degrees, minutes and seconds. %\begin{LaTeXexample} % \ang{1.05} \ang[decimalsign=comma]{1.05}\\ % \ang{3.6789} \ang[digitsep=comma]{3.6789}\\ % \ang{9;8;7} \ang[anglesep=thin]{9;8;7} %\end{LaTeXexample} % The degrees, minutes and seconds signs can be placed over the % decimal sign using the \opt{astroang} option. This is designed on % the assumption that only the last number given has a decimal % part.\footnote{The exact positioning of the symbols over the % decimal marker is currently something of a guess. Some feedback on % the ``correct'' result would be very welcome.} %\begin{LaTeXexample} % \ang{1;2;3.4}\\ % \ang[astroang]{1;2;3.4} %\end{LaTeXexample} % %\section{Units and values} %\DescribeMacro{\SI} % The core aim of \currpkg is correctly typesetting values which have % units. The main output macro here is \cs{SI}, which has the same % syntax as the equivalent macro in \sistyle and \unitsdef. 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 % \meta{number} argument operates in exactly the same manner as the % equivalent argument of the \cs{num} macro. \meta{unit} will be % typeset with a non-breakable space between it and the preceding % number, with font control as outlined earlier. Finally, % \meta{preunit} is a unit to be typeset \emph{before} the numerical % value (most likely to be a currency). Some examples illustrate the % general power of the macro. %\begin{LaTeXexample} % \SI[mode=text]{1.23}{J.mol^{-1}.K^{-1}}\\ % \SI{.23e7}{\candela}\\ % \SI[per=slash]{1.99}[\pounds]{\per\kilogram}\\ % \SI{70}{\metre\per\second}\\ % \SI[per=frac,fraction=nice]{1,345}{\ampere\per\mole}\\ %\end{LaTeXexample} % The use of unit macros outside of the \cs{SI} macro is described later % %\subsection{Literal units} % Units can be input in two ways, inspired by \sistyle and \SIunits. % The \sistyle-like method uses literal input. Four characters have % a special meaning: %\begin{itemize} % \item |^| The superscript character is used without the usual % need for surrounding maths characters (|$|); % \item |.| and |,| The fullstop (point) symbol and comma are made % active, and produce the current contents of the \opt{unitsep} % option; % \item |~| The contents of the \opt{unitspace} option are typeset % by a tilde. %\end{itemize} % This allows ready input of units. %\begin{LaTeXexample} % \SI{10}{kg.m.s^{-2}}\\ % \SI{1.453}{g/cm^3}\\ % \SI{33.562}{cd~s}\\ % \SI[unitsep=cdot]{100}{m.s^{-2}} %\end{LaTeXexample} % %\subsection{The unit interpreter} % The second operation mode for the \cs{SI} macro is based on the % behaviour of \SIunits. Here, each unit, SI multiple prefixes 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{LaTeXexample} % \SI{10}{\kilo\gram\metre\per\second\squared}\\ % \SI{1.453}{\gram\per\cubic\centi\metre}\\ % \SI{33.562}{\candela\second}\\ % \SI[unitsep=cdot]{100}{\metre\per\Square\second}\\ % \SI[prefix=power]{4.56}{\kilo\metre\per\second} %\end{LaTeXexample} % On its own, this is very similar to \SIunits, and is less % convenient than the direct input method.\footnote{Users of \SIunits % should note the lack of need for a \cs{usk}-type macro.} However, % the package allows you to define new unit macros; a large number of % pre-defined abbreviations are also supplied. More importantly, by % defining macros for units, instead of literal values, new % functionality is made available. Units may be re-defined to give % different output, and handling of reciprocal values can be altered. %\begin{LaTeXexample} % \SI[per=frac,fraction=frac]{10}{\gram\metre\per\second\squared}\\ % \SI[per=slash]{1.453}{\gram\per\cubic\centi\metre}\\ % \SI{33.562}{\candela\second}\\ % \SI[per=frac,fraction=nice]{100}{\metre\per\Square\second} %\end{LaTeXexample} % The unit processor will trap \emph{some} errors in the input and % give the ``best guess'' result. However, it is down to the user to % check the output. % %\subsection{Powers of units} %\DescribeMacro{\Square} %\DescribeMacro{\squared} %\DescribeMacro{\cubic} %\DescribeMacro{cubed} % Including powers in units is handled using a ``natural language'' % method. Thus preceding a unit by \cs{Square} or \cs{cubic} with % raise the unit to the appropriate power, while \cs{squared} or % \cs{cubed} follow the unit they apply to.\footnote{The \cs{Square} % macro is capitalised to avoid a name clash with \pkg{pstricks}.} %\begin{LaTeXexample} % \SI{10}{\metre\squared}\\ % \SI{20}{\Square\metre}\\ % \SI{30}{\metre\cubed}\\ % \SI{40}{\cubic\metre} %\end{LaTeXexample} % %\DescribeMacro{\per} % The \cs{per} macro intelligently creates reciprocal powers, and % also adds the power $-1$ when appropriate. %\begin{LaTeXexample} % \SI{10}{\per\second\squared}\\ % \SI{20}{\per\Square\second}\\ % \SI[per=frac,fraction=nice]{30}{\per\second\cubed}\\ % \SI[per=slash]{40}{\per\cubic\second}\\ % \SI{50}{\per\second} %\end{LaTeXexample} % %\DescribeMacro{\tothe} % For powers not defined above or with \cs{newpower}, the \cs{tothe} % macro can be used ``in line'' to produce a power. As follows from % standard English usage, this comes after the % unit.\footnote{Suggestions for a macro name for before the unit for % the same job are welcome!} %\begin{LaTeXexample} % \SI{16.86}{\metre\tothe{4}}\\ % \SI{7.895}{\candela\tothe{0.5}}\\ % \SI{7.895}{\newton\tothe{-6}}\\ % \SI{1.34}{\per\kelvin\tothe{7}} %\end{LaTeXexample} % % %\subsection{Units with no values} %\DescribeMacro{\unitsym} % For typesetting the symbol for a unit on its own, with the full % font control and without extra spaces, the \cs{unitsym} macro is % provided.\footnote{The same effect can be achieved using the % \cs{SI} macro with an empty numerical argument.} The macro name % avoids a clash with the functionality of the earlier packages, but % is similar to \cs{ilu} from the \unitsdef package. %\begin{LaTeXexample} % \SI{}{kg.m/s^2}\\ % \unitsym{kg.m/s^2}\\ % \unitsym[mode=text,unitsep=cdot]{\mole\per\cubic\deci\metre} %\end{LaTeXexample} % %\subsection{Free-standing units} % Users of the \unitsdef package will be a accustomed to using unit % macros on their own (following a value) or with an optional % argument containing a number. In both cases, only a single unit % macro could be used. \currpkg supports both operation modes, with % the limitation that units trailing values loose font control of the % value. %\begin{LaTeXexample} % 123\metre\\ % \kelvin[123]\\ % \sisetup{mode=text} \ampere[234]\\ % 6\second %\end{LaTeXexample} % When used in this way, the units \emph{do not} take an optional % \pkg{keyval} argument. % %\subsection{Pre-defined units, prefixes and powers} %\newcommand*{\csindex}[1]{% % \cs{#1}% % \expandafter\SpecialUsageIndex\csname#1\endcsname} %\newcommand{\unitinfo}[1]{% % #1 & \csindex{#1} & % \expandafter\unitsym\expandafter{\csname#1\endcsname}} %\begin{table} % \centering % \begin{tabular}{lll} % \toprule % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} \\ % \midrule % \unitinfo{kilogram}\\ % \unitinfo{metre}\\ % \unitinfo{second}\\ % \unitinfo{mole}\\ % \unitinfo{kelvin}\\ % \unitinfo{ampere}\\ % \unitinfo{candela}\\ % \bottomrule % \end{tabular} % \caption{The seven base SI units} % \label{tbl:baseunits} %\end{table} % The package always defines the seven base SI units, irrespective of % any package options given (Table~\ref{tbl:baseunits}). The kilogram % is notable as by default it is a \emph{base} unit with a prefix. % Thus, when the package is loaded with the option \opt{load=\{\}}, % \cs{kilo} and \cs{gram} \emph{are not defined}. % % By default, a number of additional definitions are created by the % package. These are controlled by the \opt{load} and \opt{noload} % options. Unless specifically requested with the option % \opt{noload=prefix}, \currpkg also defines the standard prefixes % for powers of ten (Table~\ref{tbl:prefix}). This leads to the % redefinition of \cs{kilogram} as \cs{kilo}\cs{gram}. The macro % \cs{deka} is provided, as this is used as an alias for \cs{deca} % in some places. %\newcommand*{\prefixunitsym}[1]{\unitsym[prefix=number]{#1}} %\newcommand*{\prefixinfo}[1]{% % #1 & \csindex{#1} & % \expandafter\prefixunitsym\expandafter{\csname#1\endcsname} & % \expandafter\unitsym\expandafter{\csname#1\endcsname}} %\begin{table} % \centering % \begin{tabular}{lllclllc} % \toprule % \multicolumn{1}{c}{Prefix} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Power} & % Symbol & % \multicolumn{1}{c}{Prefix} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Power} & % Symbol \\ % \midrule % \prefixinfo{yocto}& % \prefixinfo{atto}\\ % \prefixinfo{femto}& % \prefixinfo{pico}\\ % \prefixinfo{nano}& % \prefixinfo{micro}\\ % \prefixinfo{milli}& % \prefixinfo{centi}\\ % \prefixinfo{deci}& % \prefixinfo{deca}\\ % \prefixinfo{hecto}& % \prefixinfo{kilo}\\ % \prefixinfo{mega}& % \prefixinfo{giga}\\ % \prefixinfo{tera}& % \prefixinfo{peta}\\ % \prefixinfo{exa}& % \prefixinfo{zetta}\\ % \prefixinfo{yotta}\\ % \bottomrule % \end{tabular} % \caption{The SI prefixes (\opt{load=prefix})} % \label{tbl:prefix} %\end{table} % The package also defines a number of derived SI units which have % assigned names and symbols (Table~\ref{tbl:derived}). Note that % \cs{Gray} is capitalised to avoid a name clash with the % \pkg{pstricks} package.\footnote{The macros \cs{ohm} and % \cs{celsius} are not defined by \currpkg if the \pkg{gensymb} % package is loaded.} %\begin{table} % \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 % \unitinfo{becquerel} & % \unitinfo{celsius} \\ % \unitinfo{coulomb} & % \unitinfo{farad} \\ % \unitinfo{Gray} & % \unitinfo{hertz} \\ % \unitinfo{henry} & % \unitinfo{joule} \\ % \unitinfo{katal} & % \unitinfo{lumen} \\ % \unitinfo{lux} & % \unitinfo{newton} \\ % \unitinfo{ohm} & % \unitinfo{pascal} \\ % \unitinfo{radian} & % \unitinfo{siemens} \\ % \unitinfo{sievert} & % \unitinfo{steradian}\\ % \unitinfo{tesla} & % \unitinfo{volt} \\ % \unitinfo{watt} & % \unitinfo{weber} \\ % \bottomrule % \end{tabular} % \caption{The derived SI units with defined names % (\opt{load=derived})} % \label{tbl:derived} %\end{table} % In addition to these units, there are three other groups of units % for use with the SI system which do not fit into the above. These % are those derived from physical measurements % (Table~\ref{tbl:experimental}), those considered ``accepted'' % (Table~\ref{tbl:accepted}), and those accepted temporarily % (Table~\ref{tbl:addn}).\footnote{These are supposed to be replaced % over time by SI units.} %\begin{table} % \centering % \begin{tabular}{lll} % \toprule % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} \\ % \midrule % electron volt & \csindex{electronvolt} & \electronvolt \\ % atomic mass unit % & \csindex{atomicmassunit} & \atomicmassunit \\ % & \csindex{atomicmass} & \atomicmass \\ % \unitinfo{dalton} \\ % \bottomrule % \end{tabular} % \caption{Units derived from experiments % (\opt{load=physical})}. % \label{tbl:experimental} %\end{table} %\begin{table} % \centering % \begin{tabular}{lll} % \toprule % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} \\ % \midrule % \unitinfo{minute} \\ % \unitinfo{hour} \\ % day & \csindex{Day} & \Day \\ % \unitinfo{degree} \\ % minute (arc) & \csindex{arcmin} & \arcmin \\ % second (arc) & \csindex{arcsec} & \arcsec \\ % \unitinfo{litre} \\ % \unitinfo{tonne} \\ % \unitinfo{neper} \\ % \unitinfo{bel} \\ % \unitinfo{percent} \\ % \bottomrule % \end{tabular} % \caption{Units accepted for use with SI % (\opt{load=accepted})}. % \label{tbl:accepted} %\end{table} %\begin{table} % \centering % \begin{tabular}{lll} % \toprule % \multicolumn{1}{c}{Unit} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Symbol} \\ % \midrule % {\aa}nstr{\"o}m & \csindex{angstrom} & \angstrom \\ % \unitinfo{are} \\ % \unitinfo{hectare} \\ % \unitinfo{barn} \\ % bar & \csindex{BAR} & \BAR \\ % \unitinfo{millibar} \\ % \unitinfo{gal} \\ % \unitinfo{curie} \\ % \unitinfo{roentgen} \\ % \unitinfo{rad} \\ % \unitinfo{rem} \\ % \bottomrule % \end{tabular} % \caption{Additional (temporary) SI units % (\opt{load=addn})} % \label{tbl:addn} %\end{table} % %\subsection{Prefixed and abbreviated units} % Many basic units have prefixes which are commonly used with the % unit, such as centimetre or megahertz. The package therefore % defines a number of common prefixed units (\opt{load=prefixed}). % Several of these also have obvious abbreviations (such as \cs{MHz} % for \cs{megahertz}). These are available by loading the % \file{si-abbr.cfg} file (\ie\ \opt{load=abbr}). In common with the % units discussed above, the prefixed and abbreviated unit % definitions are loaded by default. %\begin{longtable}{llll} % \caption{Prefixed (\opt{load=prefixed}) and abbreviated % (\opt{load=abbr}) units\label{tbl:abbr} }\\ % \toprule % Unit & Macro & Symbol & Abbreviation \\ % \midrule % \endfirsthead % \toprule % Unit & Macro & Symbol & Abbreviation \\ % \midrule % \endhead % \bottomrule % \multicolumn{4}{r}{\emph{Continued on next page}} % \endfoot % \bottomrule % \endlastfoot % \emph{Masses} \\ % \unitinfo{kilogram} & \csindex{kg} \\ % \unitinfo{femtogram} & \csindex{fg} \\ % \unitinfo{picogram} & \csindex{pg} \\ % \unitinfo{nanogram} & \csindex{nanog} \\ % \unitinfo{microgram} & \csindex{micg} \\ % \unitinfo{milligram} & \csindex{mg} \\ % atomic mass & \csindex{atomicmass} & \amu & \csindex{amu} \\ % \\ \emph{Lengths} \\ % \unitinfo{picometre} & \csindex{picom} \\ % \unitinfo{nanometre} & \csindex{nm} \\ % \unitinfo{micrometre} & \csindex{micm} \\ % \unitinfo{millimetre} & \csindex{mm} \\ % \unitinfo{centimetre} & \csindex{cm} \\ % \unitinfo{decimetre} & \csindex{dm} \\ % \unitinfo{kilometre} & \csindex{km} \\ % \\ \emph{Times} \\ % \unitinfo{second} & \csindex{Sec} \\ % \unitinfo{attosecond} & \csindex{as} \\ % \unitinfo{femtosecond} & \csindex{fs} \\ % \unitinfo{picosecond} & \csindex{ps} \\ % \unitinfo{nanosecond} & \csindex{ns} \\ % \unitinfo{microsecond} & \csindex{mics} \\ % \unitinfo{millisecond} & \csindex{ms} \\ % \\ \emph{Moles} \\ % \unitinfo{femtomole} & \csindex{fmol} \\ % \unitinfo{picomole} & \csindex{pmol} \\ % \unitinfo{nanomole} & \csindex{nmol} \\ % \unitinfo{micromole} & \csindex{micmol} \\ % \unitinfo{millimole} & \csindex{mmol} \\ % \\ \emph{Currents} \\ % \unitinfo{picoampere} & \csindex{pA} \\ % \unitinfo{nanoampere} & \csindex{nA} \\ % \unitinfo{microampere} & \csindex{micA} \\ % \unitinfo{milliampere} & \csindex{mA} \\ % \unitinfo{kiloampere} & \csindex{kA} \\ % \\ \emph{Areas} \\ % \unitinfo{squaremetre} \\ % \unitinfo{squarecentimetre} \\ % \unitinfo{squarekilometre} \\ % \\ \emph{Volumes} \\ % \unitinfo{millilitre} & \csindex{ml} \\ % \unitinfo{microlitre} & \csindex{micl} \\ % \unitinfo{centimetrecubed} & \csindex{cmc} \\ % & \csindex{centimetrecubed} & \cmc & \csindex{cmc} \\ % \unitinfo{cubicdecimetre} & \csindex{dmc} \\ % \\ \emph{Frequencies} \\ % \unitinfo{hertz} & \csindex{Hz} \\ % \unitinfo{millihertz} & \csindex{mHz} \\ % \unitinfo{kilohertz} & \csindex{kHz} \\ % \unitinfo{megahertz} & \csindex{MHz} \\ % \unitinfo{gigahertz} & \csindex{GHz} \\ % \unitinfo{terahertz} & \csindex{THz} \\ % \\ \emph{Potentials} \\ % \unitinfo{millivolt} & \csindex{mV} \\ % \unitinfo{kilovolt} & \csindex{kV} \\ % \\ \emph{Energies} \\ % \unitinfo{kilojoule} & \csindex{kJ}\\ % \unitinfo{electronvolt} & \csindex{eV} \\ % \unitinfo{millielectronvolt} & \csindex{meV} \\ % \unitinfo{kiloelectronvolt} & \csindex{keV} \\ % \unitinfo{megaelectronvolt} & \csindex{MeV} \\ % \unitinfo{gigaelectronvolt} & \csindex{GeV} \\ % \unitinfo{teraelectronvolt} & \csindex{TeV} \\ % \\ \emph{Powers} \\ % \unitinfo{milliwatt} \\ % \unitinfo{kilowatt} \\ % \unitinfo{megawatt} \\ % \\ \emph{Capacitance} \\ % \unitinfo{femtofarad} \\ % \unitinfo{picofarad} \\ % \unitinfo{nanofarad} \\ % \unitinfo{microfarad} \\ % \unitinfo{millifarad} \\ % \\ \emph{Resistance} \\ % \unitinfo{kiloohm} \\ % \unitinfo{megaohm} \\ % \unitinfo{gigaohm} \\ % \unitinfo{millisiemens} \\ % \\ \emph{Forces} \\ % \unitinfo{millinewton} \\ % \unitinfo{kilonewton} \\ % \\ \emph{Other units} \\ % \unitinfo{hectopascal} \\ % \unitinfo{megabecquerel} \\ % \unitinfo{millisievert} \\ %\end{longtable} % %\subsection{Specialist units} %\DescribeMacro{\mmHg} %\DescribeMacro{\molar} %\DescribeMacro{\molar} % In some subject area, there are units which are in common use even % though they are outside of the SI system. Unlike the units % discussed earlier, these specialist units are not loaded by default. % \currpkg comes with the predefined files \opt{alsoload=chemistry} % and \opt{alsoload=hep}. The later defines the units from the % \pkg{hepunits} package not provided elsewhere here. The former % adds the common chemistry units \cs{mmHg}, \cs{molar} and % \cs{Molar}. The \cs{Molar} macro is somewhat awkward, as it can be % given as either ``\textsc{m}'' or ``M''. The later is obviously % easily confused with the sign for the prefix mega. % %\DescribeMacro{\bit} %\DescribeMacro{\byte} % The package also comes with equipped for \opt{alsoload=binary}. % This provides the binary units and prefixes. The extra units % are \cs{bit} and \cs{byte}, with the new prefixes listed in % Table~\ref{tbl:binary}. %\begin{table} % \centering % \begin{tabular}{ll>{$}c<{$}} % \toprule % \multicolumn{1}{c}{Prefix} & % \multicolumn{1}{c}{Macro} & % \multicolumn{1}{c}{Power} \\ % \midrule % kibi & \csindex{kibi} & 2^{10} \\ % mebi & \csindex{mebi} & 2^{20} \\ % gibi & \csindex{gibi} & 2^{30} \\ % tebi & \csindex{tebi} & 2^{40} \\ % pebi & \csindex{pebi} & 2^{50} \\ % exbi & \csindex{exbi} & 2^{60} \\ % \bottomrule % \end{tabular} % \caption{Binary prefixes % (\opt{alsoload=binary})}. % \label{tbl:binary} %\end{table} % %\subsection{Defining new units} %\DescribeMacro{\newunit} %\DescribeMacro{\renewunit} %\DescribeMacro{\provideunit} % New units are produced using the \cs{newunit} macro. This works as % might be expected: % \cs{newunit}\oarg{options}\marg{unit}\marg{symbol}, where % \meta{symbol} can contain literal values, other units, multiple % prefixes, powers and \cs{per}. The \meta{options} argument can be % any suitable options, and applies to this unit only The most % obvious example for using this macro is the \cs{degree} % unit.\footnote{Although the \cs{ang} macro is preferred for this % job.} The (first) optional argument to \cs{SI} and \cs{unitsym} % can be used to override the settings for the unit. %\begin{LaTeXexample} % \SI{3.1415}{\degree}\\ % \newunit[valuesep=none]{\oddunit}{XXX}\\ % \SI{12345}{\oddunit} % \SI[valuesep=thick]{67890}{\oddunit} %\end{LaTeXexample} % % Output that is only safe in maths mode should be protected with % \cs{ensuremath}; text-only input requires \cs{text}. In the % example below, \cs{mathnormal} is used to force the font choice % only for the single character.\footnote{The \cs{mathrm} font used % for this document has an ``\ss'' at the $\pi$ position.} %\begin{LaTeXexample} % \newunit{\SIpi}{\ensuremath{\mathnormal{\pi}}} % \SI{10}{\metre\per\SIpi\squared} %\end{LaTeXexample} % %\DescribeMacro{\newpower} %\DescribeMacro{\renewpower} %\DescribeMacro{\providepower} % Powers are defined: \cs{newpower}\oarg{post}\marg{power}\marg{num}. % \meta{power} is the name of the power macro, an \meta{num} is the % (positive) number it represents. The later argument is always % processed internally by \cs{num}, but \emph{must} be a number. % Giving the optional argument \opt{post} indicates to the package % that the power will come after the unit it applies to; by default % it is assumed that it will come before. %\begin{LaTeXexample} % \newpower{\quartic}{4} % \newpower[post]{\totheforth}{4}\\ % \unitsym{\kilogram\totheforth}\\ % \unitsym{\quartic\metre} %\end{LaTeXexample} % %\DescribeMacro{\newprefix} %\DescribeMacro{\renewprefix} %\DescribeMacro{\provideprefix} % The standard SI powers of ten are defined by the package, and are % described above. However, the user can define new prefixes with % \cs{newprefix}. This has syntax % \cs{newunit}\marg{prefix}\marg{symbol}\marg{powers-ten}, where % \meta{powers-ten} is the number of powers of ten the prefix % represents. For example, \cs{kilo} is defined: %\begin{LaTeXexample}[\typesetcodeonly] % \newprefix{\kilo}{k}{3} %\end{LaTeXexample} % %\section{Font control} % Following the lead of \sistyle, \currpkg provides control over the % font used to typeset output. By default, all text is typeset using % the current upright serif maths font, whether the macros are given % in text or maths mode. Some examples will show the effect. %\begin{LaTeXexample} % \num{10} $\num{10}$ \\ % \sffamily \ang{20} $\ang{20}$ \\ % \textbf{\SI{30}{\kilo\gram}}\\ % \boldmath $\SI{30}{\kilo\gram}$ \\ % \[ \num{50} \] %\end{LaTeXexample} % % By giving the \opt{obeyfamily} option, the surrounding font family % (serif, sans serif, fixed width) is used for inline materials. % Inside the display maths environments, the currently active maths % font is used. The \opt{obeybold} option causes the bold setting to % be obeyed in the same way. %\begin{LaTeXexample} % \sisetup{obeyfamily,obeybold,obeyitalic} \\ % \ang{1;1;1} $\ang{1;1;1}$ \\ % \sffamily \ang{2;2;2} $\ang{2;2;2}$ \\ % \textbf{\ang{3;3;3}} \boldmath $\ang{3;3;3}$ \\ % \sisetup{mode=text} \emph{\ang{4;4;4}} $\ang{4;4;4}$ \\ % \[ \ang{5;5;5} \] %\end{LaTeXexample} % %\section{Package options\label{sec:options}} %\DescribeMacro{\sisetup} % The ``native'' options for the package are all given using the % \pkg{keyval} methods. Most of the package options can be given both % when loading the package and at any point in the document. This is % achieved using the \cs{sisetup} macro. % %\newcommand*{\choiceopt}[1][option]{\opt{#1=\meta{choice}}\xspace} %\newcommand*{\boolopt}[1][option]{\opt{#1=\meta{bool}}\xspace} %\newcommand*{\litopt}[1][option]{\opt{#1=\meta{literal}}\xspace} %\newcommand*{\choicelitopt}[1][option] % {\opt{#1=\meta{choice,literal}}\xspace} %\newcommand*{\macopt}[1][option]{\opt{#1=\meta{macro}}\xspace} %\newcommand*{\numopt}[1][option]{\opt{#1=\meta{number}}\xspace} %\newcommand*{\listopt}[1][option]{\opt{#1=\meta{list}}\xspace} %\newcommand*{\lenopt}[1][option]{\opt{#1=\meta{length}}\xspace} % The package options take a number of different forms. %\begin{itemize} % \item \boolopt Simple true/false values. These macros all default % to \opt{true}, so giving the option name alone sets the flag to % true. % \item \choiceopt Take a single item from a pre-determined list. % Depending on the value, one or more internal states will be % altered. Values not on the list are ignored. The default value % is given in bold. % \item \choicelitopt If the given value is a \meta{choice}, then % the internal settings for that choice are used. Any other value % is used directly. As with simple choice options, the default is % given in bold. % \item \litopt The given value is used as a literal by the package. % \item \macopt These options expect a macro name as a value; the % macro name is then used by the package. Note that the name does % \emph{not} include the leading \textbackslash. % \item \lenopt Requires a \TeX\ lengths, for example % \opt{0.5ex}. % \item \listopt Takes a list of one or more items, which are not % determined in advance. %\end{itemize} % % The package has a large range of options, to allow full control of % the various features of the package. These control differing % aspects of the package, and are given below in groups based on % function. % %\subsection{Font family and style} % The font used when typesetting material can be tightly controlled % using \currpkg. A number of options affect how the package matches % the surrounding font, and the font families used to achieve this. %\begin{itemize} % \item \boolopt[obeyfamily] By default, the font family used for % typesetting does \emph{not} match the surroundings. This is % altered using the \opt{obeyfamily} switch; when active, serif % (Roman), sans serif and typewriter fonts are detected. % \item \choiceopt[mode] The output of \currpkg can be typeset % using either text or maths fonts. By default, maths mode is % used, but this can be altered setting the \opt{mode} option % to \opt{text}. % \item \boolopt[textmode] A shortcut for \opt[mode=text]. % \item \boolopt[obeymode] The package can detect and use the % surrounding maths or text mode, if requested. Default is % \opt{false}. % \item \boolopt[obeybold] If the typeset text should obey the local % value of the bold setting, then this option should be set: the % default is false. % \item \choiceopt[inlinebold] For inline maths, the package % can check either the surrounding maths or the surrounding text. % The options here are \textbf{\opt{text}} and\opt{maths} (or % \opt{math}). % \item \boolopt[obeyitalic] Italic \latin{versus} upright shape % is handled slightly differently to bold. The option works in % text mode, but has no effect in maths mode. This is because % font changes plus italic is not possible in maths mode (for % example, see the result of |$\mathit{\mathrr{10}}$|. % \item \macopt[mathdefault] The default shape used for text printed % in maths mode. The default is the value stored in \opt{mathrm}. % \item \macopt[textdefault] The default shape used for text printed % in text mode. The default is the value stored in \opt{mathrm}. % \item \macopt[mathnumdefault] The default shape used for numbers % printed in maths mode. The default is the value stored in % \opt{mathrm}. % \item \macopt[textnumdefault] The default shape used for numbers % printed in text mode. The default is the value stored in % \opt{mathrm}. % \item \macopt[mathrm] The font command used in maths mode when % the surrounding text is serif. The default is \opt{mathrm}; the % other maths font defaults follow the same pattern. % \item \macopt[mathsf] The font command used in maths mode when % the surrounding text is sans serif. % \item \macopt[mathrm] The font command used in maths mode when % the surrounding text is fixed width. % \item \macopt[textrm] The font command used in text mode when % the surrounding text is serif. The default is \opt{rmfamily}; % the other text font defaults follow the same pattern. % \item \macopt[textsf] The font command used in text mode when % the surrounding text is sans serif. % \item \macopt[texttt] The font command used in text mode when % the surrounding text is fixed width. %\end{itemize} % %\subsection{Spacing and separators} % The spacings used between items are all user-definable. This is % also true for the separators used for decimals, \etc. %\begin{itemize} % \item \choicelitopt[unitsep] This defines the separation of % different unit symbols. The \meta{list} takes values % \opt{\textbf{thin}}, \opt{medium} (alias \opt{med}), \opt{thick} % (all maths spacings), \opt{space} (a full space), \opt{cdot} (a % centred dot) and \opt{times}. \meta{literal} values are typeset % in maths mode. % \item \choicelitopt[unitspace] The spacing represented by an % explicit hard space (|~|) inside a unit macro. Takes the same % list as \opt{valuesep}. % \item \choicelitopt[valuesep] Defines the separation between a % value and the associated unit. Valid \meta{list} values are % \opt{\textbf{thin}}, \opt{medium} (alias \opt{med}), % \opt{thick}, \opt{space} and \opt{none}. % \item \choicelitopt[digitsep] The separation (if any) between % groups of digits in large numbers. Valid \meta{list} values are % \opt{\textbf{thin}}, \opt{medium} (alias \opt{med}), % \opt{thick}, \opt{space}, \opt{comma}, \opt{fullstop} (aliases % \opt{stop} and \opt{period}) and \opt{none}. % \item \choicelitopt[decimalsign] The decimal sign, either % \opt{comma} or \opt{\textbf{fullstop}} (also aliased as % \opt{stop} and \opt{period}). % \item \choicelitopt[anglesep] The separator between degrees, % minutes and seconds in an angle. The options are \opt{thin}, % \opt{medium} (alias \opt{med}), \opt{thick} and % \opt{\textbf{none}}. %\end{itemize} % %\subsection{Number formatting} % There are two types of option for numbers. The first set are % concerned with parsing numbers, and are very similar to the % settings in \numprint. These all begin \opt{num}, and take literal % values. Notice that the literals are \emph{not} separated in any % way in the input. %\begin{itemize} % \item \litopt[numlist] The characters which are numbers: % \opt{\textbf{01234567890}}. % \item \litopt[numdecimal] Decimal markers: \opt{\textbf{.,}} % \item \litopt[numexp] Exponent markers: \opt{\textbf{edED}} % \item \litopt[numgobble] Characters to be gobbled when processing % numbers: no default % \item \litopt[numsign] Signs (which must be at the start of a % number): \opt{\textbf{+-\cs{pm}\cs{mp}}} % \item \litopt[numextra] ``Extra'' characters, to be carried % through directly to the output: \opt{\textbf{()}} %\end{itemize} % % The second type of option for numbers controls the output. %\begin{itemize} % \item \choiceopt[addsign] Sets whether a sign is added to numbers % without an explicit sign given. Valid choices are % \opt{mantissa} (or \opt{mant}), \opt{exponent} (or \opt{exp}), % \opt{both} (or \opt{all}) and \opt{\textbf{none}}.The option % will also act as a Boolean, taking \opt{true} and opt{false}, % with \opt{addsign} alone equal to giving the \opt{true} (= % \opt{all}) value. % \item \choicelitopt[sign] The sign used by the above. Choices are % \opt{\textbf{plus}}, \opt{minus}, \opt{pm} and \opt {mp} ($\pm$ % and $\mp$, respectively). The sign will always be typeset in % maths mode. % \item \boolopt[sepfour] When separating out numbers (using % \opt{digitsep}), four-digit numbers can be skipped. This is % the default. % \item \choicelitopt[expproduct] The symbol used to indicate a % product for exponents (\ie\ the $\times$ in \num{2e2}). The % choices are \opt{\textbf{times}} and \opt{cdot}. % \item \choicelitopt[exppower] Slightly esoterically, the power % used for exponents can be altered. The ``choice'' list here % only recognises \opt{ten}; anything else is used literally. % \item \choiceopt[padnumber] This sets where zeros are added. The % choices are \opt{\textbf{leading}} (a leading zero added to % |.1|), \opt{trailing} (converts |1.| to \num{1.0}), \opt{all} % (\opt{leading} and \opt{trailing}, also available as \opt{both}) % and \opt{none} (no zeros added). The option will also act as a % Boolean, taking \opt{true} and opt{false}, with \opt{padnumber} % alone equal to giving the \opt{true} (= \opt{all}) value. %\end{itemize} % %\subsection{Angle formatting} % The angle formatter uses \cs{num} to format numbers; any options % for numbers are therefore applicable here. When typesetting an % angle using \cs{ang}, the following extra option is also relevant. %\begin{itemize} % \item \choiceopt[padangle] Determines whether small and large % angles are padded. The choices are \opt{none} (no additional % zeros are added), \opt{\textbf{small}} (angles with no degrees % have \ang{0;;} added), \opt{large} (angles with no seconds have % \ang[padangle=none]{;;0} added) and \opt{all} (\opt{small} and % \opt{large} combined). The option also recognises \opt{true} % and \opt{false} as choices, which are equal to \opt{all} and % \opt{none}, respectively. If no value is given, \opt{padangle} % acts a Boolean choice. % \item \boolopt[astroang] Astronomers place the signs for angles % over decimal signs; this is handled here. %\end{itemize} % %\subsection{Tabular material} % The formatting of data in |s| columns is controlled by a single % package option. %\begin{itemize} % \item \numopt[tabformat] The number here determines how to centre % decimal numbers in a column. If \opt{number} is zero or % negative, then the decimal marker is placed at the centre of the % column with the number symmetrically placed around it. If % \opt{number} is positive, it is interpreted % |\meta{pre}.\meta{post}|, where \meta{pre} is the number of % digits before the decimal marker and \meta{post} is the number % after. Appropriate space is reserved to centre a number of % total length \meta{pre} $+$ \meta{post} (plus the decimal % marker). If the digits supplied are too long, overfull boxes % will result. If only \meta{pre} is given, an equal amount of % space is reserved before and after the decimal marker, and the % number is typeset flush right. %\end{itemize} % %\subsection{Units} % The output of units (as opposed to the numerical argument of the % unit) takes only a few options. %\begin{itemize} % \item \boolopt[xspace] Determines whether to use \pkg{xspace} at % the end of unit macros when not given inside \cs{SI}, for % example |10\metre away| will give \sisetup{xspace} ``10\metre % away'' with \opt{xspace} turned on, but \sisetup{xspace=false} % ``10\metre away'' with it turned off.\sisetup{xspace} % \item \choiceopt[per] Affects how \cs{per} is interpreted in % units. The options available are \textbf{\opt{reciprocal}} % (also available as \opt{rp} and \opt{power}), \opt{slash} and % \opt{fraction} (or \opt{frac}). % \item \choiceopt[fraction] When using \opt{per=frac}, further control % of the appearance of the fraction is provided. The options % available are \opt{frac} (uses \LaTeX\ \cs{frac} operation), % \opt{nice} (also available as \opt{nicefrac}; uses a % \pkg{nicefrac}-like system), \opt{ugly} (also \opt{uglyfrac}; % the same as loading \pkg{nicefrac} with the \opt{ugly} option: % uses \cs{frac} for material in maths mode and a slash for % material in text mode) and \opt{sfrac} (uses the \cs{sfrac} % macro from the \pkg{xfrac} package.\footnote{\pkg{xfrac} is part % of the experimental system for \LaTeX3. As it requires a number % of additional packages to work, \currpkg does not load % \pkg{xfrac}. If it is unavailable, the \opt{sfrac} setting will % fall back to using \cs{nicefrac}. See the \pkg{xfrac} % documentation for reasons to prefer \cs{sfrac} to % \cs{nicefrac}.} % \item \litopt[denlbrac] and \litopt[denrbrac] When using % \opt{per=slash}, using two or more units in the denominator % gives an ambiguous fraction. The package therefore adds % \opt{denlbrac} and \opt{denrbrac} in such cases. % \item \choiceopt[prefix] Controls how prefixes to units % are handled, with options \textbf{\opt{symbol}} (or % \opt{letter}) and \opt{number} (or \opt{power}). % \item \choicelitopt[prefixpower] and \choiceopt[prefixproduct] % Works in the same way as the general exponent equivalents, but % only for prefix modifiers. %\end{itemize} % %\subsection{Symbols} % User access to control the symbols used for \unitsym{\micro}, % \unitsym{\ohm}, \unitsym{\angstrom}, \unitsym{\degree} and % \unitsym{\celsius} is provided here. These are all literal options, % which are available in text and maths mode variants. For example, % \opt{textmicro} is the code used for the \unitsym{\micro} symbol in % text mode. The text mode macros should be safe when forced into % text, and the maths ones when forced into maths. %\begin{itemize} % \item \opt{textOmega} % \item \opt{mathsOmega} % \item \opt{textmu} % \item \opt{mathsmu} % \item \opt{textdegree} % \item \opt{mathsdegree} % \item \opt{textminute} % \item \opt{mathsminute} % \item \opt{textsecond} % \item \opt{mathssecond} % \item \opt{textringA} % \item \opt{mathsringA} % \item \opt{textcelsius} % \item \opt{mathscelsius} %\end{itemize} % % When \currpkg is loaded, it can check for the presence of the % \pkg{textcomp} and \pkg{upgreek} packages, to provide better % symbols for certain items. To prevent this, us the % \opt{redefsymbols=false} option. % % The \unitsym{\electronvolt} symbol requires some fine-tuning, and % so has two options of its own. %\begin{itemize} % \item \lenopt[eVcorra] The correction applied to the gap between % ``e'' and ``V'' of the unit. The default is \opt{0.3ex}. % \item \lenopt[eVcorrb] The correction applied to the gap between % ``V'' of the unit and whatever follows. The default is % \opt{0ex}; a change is needed for example in % |\unitsym[per=slash]{\electronvolt\per\metre}|, which gives % \unitsym[per=slash]{\electronvolt\per\metre} by default, but % \unitsym[per=slash,eVcorrb=0.7ex]{\electronvolt\per\metre} by % setting \opt{eVcorrb=0.7ex}. The value needed will depend % on the use of the unit and the font metrics used. %\end{itemize} % %\subsection{Package control} % These macros alter the overall behaviour of the package. %\begin{itemize} % \item \listopt[load] Sets which additional configuration files are % loaded. These all have names of the form % \file{si-\meta{option}.cfg}, where \meta{option} should be given % in the \opt{load} list. The package recognises the % \opt{load=default} option, which is expanded to the standard list % of loaded files. This is to allow easy addition of one or more % files without needing to know the default list. % \item \listopt[noload] Excludes files from the above from being % loaded, so that a single file can be omitted without needing to % type a long list of those to be used. % \item \listopt[alsoload] Adds an item to the list to be loaded, % without needing to specify all of the existing list. % \item \choiceopt[log] Sets the amount of information written to % the log by \currpkg. The \meta{list} is \opt{none}, % \opt{errors}, \textbf{\opt{normal}} and \opt{debug}. The last % option is also available as a Boolean, and gives \emph{lots} of % information in the log. % \item \choiceopt[emulate] Causes \currpkg to emulate the % given package. The \meta{list} takes values \opt{SIunits}, % \opt{sistyle}, \opt{units} and \opt{unitsdef}. % This option can only be used when loading the package. %\end{itemize} % %\subsection{Back-compatibility options} % As well as the options outlined above, at load time a number of % options are available to allow \currpkg to be used as a direct % replacement for other unit-management packages. These are the same % options as are available in \SIunits, \sistyle, \unitspkg, and % \unitsdef. Using a legacy option will cause the package to load the % appropriate emulation code % %\section{Emulation of other packages} % \currpkg has been designed as a replacement for \SIunits, \sistyle, % \unitspkg and \unitsdef. It therefore provides options a hooks to % reproduce the functions of all of these packages. In this way, % \currpkg should be usable as a straight replacement for the older % packages. All of the user macros of \meta{package} are (hopefully) % available when using the % \opt{emulate=\meta{package}}.\footnote{User macros means that they % are described in the package documentation; simply not containing % an \texttt{@} does not mean they will have been emulated.} This % means for example that the \cs{num} macro takes an optional star % when emulating \sistyle. However, there are some points that % should be remembered. In particular, \currpkg validates numerical % input, meaning that places where a number is expected in the older % packages \emph{require} a number when emulated by \currpkg. % % The \numprint package has provided many useful ideas for the code % used here for number formatting. The basic use of the \cs{numprint} % (or \cs{np}) macro can be reproduced using \currpkg. However, % \numprint is large and complex, with its own backward-compatibility % options. As a result, emulation of \numprint is not provided here. % To use an \numprint document with \currpkg, the cs{numprint} macro % could be provided using the following code. %^^A Need to deal with \cs{numprint} being defined. %\let\numprint\relax %\begin{LaTeXexample} % \newcommand*{\numprint}[2][]{\SI[obeymode]{#2}{#1}}\\ % \numprint{-123456} \numprint[N/mm^2]{-123456} %\end{LaTeXexample} %^^A Back to the normal - with \cs{newcommand} %\newcommand*{\numprint}{\pkg{numprint}\xspace} % % \currpkg can be used more-or-less directly to replace both % \pkg{dcolumn} and \pkg{rccol}. As is explained in the code % section, much of the column-alignment system here is taken from % \pkg{dcolumn}, while \pkg{rccol} provided a model for an % customisable system. However, neither package has been directly % emulated here. The |s| column type can be used to replace both |D| % and |R| columns by setting the appropriate package options. % %\section{Tricks and known issues} % % Due to the possibility of output in either maths or text mode, any % input which requires a particular mode needs to be protected. You % cannot use |$|\ldots|$|, as this can get ``caught out'', but also % as it may give hard-to-follow errors. Always use \cs{ensuremath} % to force maths processing, and \cs{text} (from the \AMS\TeX\ % bundle) to ensure text mode. % % The package uses the \cs{mathrm} font family by default to typeset % output in maths mode. This however has a few side-effects. For % example, the Greek alphabet can give odd results.\footnote{This % depends on your font setup; this document uses T1 encoding, which % shows the issue, whereas using OT1 does not.} The use of the % \cs{mathnormal} font may get around this issue. %\begin{LaTeXexample} % \num[numextra=\pi]{4\pi e-7}\\ % \num[numextra=\pi,mathnumdefault=mathnormal]{4\pi e-7}\\ %\end{LaTeXexample} % On the other hand, you may want to use text mode. There, % \cs{ensuremath} is needed. %\begin{LaTeXexample} % \newcommand*{\numpi}{\ensuremath{\pi}} % \num[numextra=\numpi,mode=text]{4\numpi e-7} %\end{LaTeXexample} % There are several potential pitfalls in this area; experimentation % may well be needed.\footnote{Any suggestions for the code that runs % this are welcome; the issue is how to deal with active characters % in the input while not expanding macros.} % %\section{Reporting a problem} % \currpkg is quite long and complicated, and works hard to cover all % possible eventualities. However, there will be bugs in the code % and unexpected interactions with other packages. If you think you % have found a bug, please report it. A short test-case % demonstrating the problem would be very welcome. The following is % a suitable template, and is available as \file{si-bug.ltx}, by % running \file{si.dtx} through (pdf)\LaTeX. %^^A Change the output file name for the temporary file, so that %^^A this one is available to readers. %\edef\LaTeXexamplefile{si-bug.ltx} %\begin{LaTeXexample}[\typesetcodeonly] % \listfiles % \documentclass{article} % % Add other packages here. % % Add options need for si package, retain the debug option. % \usepackage[debug]{si} % \begin{document} % This is the bug test-case document for the \textsf{si} % package.\\ % Please put your demonstration here, and e-mail to the % package author. % \begin{center} % \texttt{joseph.wright@morningtar2.co.uk} % \end{center} % \end{document} %\end{LaTeXexample} %^^A Back to normal, so that this is not forgotten %\edef\LaTeXexamplefile{\jobname.tmp} % %\section{Acknowledgements} % The package author has learned \LaTeX\ tricks from far too many % people to thank all of them. However, for this package specific % thanks must go to the authors of the existing ``unit'' packages: % Danie Els (\sistyle), Marcel Heldoorn (\SIunits), Patrick % Happel (\unitsdef), Axel Reichert (\unitspkg) and Harald % Harders (\numprint). Philip Lehmann, Will Robertson and Heiko % Oberdiek deserve much credit for demonstrating \LaTeX\ coding best % practice. Thanks to the various contributors of ideas for the % package: Donald Arseneau, Michele Dondi, Paul Gans, Ben Morrow, Lan % Thuy Pham, Stefan Pinnow, Allan Ristow and Patrick Steegstra. % %\part{Correct application of (SI) units} %TO DO! % %\bibliographystyle{unsrt} %\StopEventually{% % \part{Notes} % \PrintChanges % \PrintIndex % \bibliography{si}} % % \iffalse %<*package> % \fi % %\part{Implementation} %\section{Main package} % Much of the code here is taken, with little or no modification, % from the existing packages. These are all released under the LPPL, % and so this use is entirely allowed. Rather than confuse the % source here with repeated references, note that code here could be % copied from \sistyle, \SIunits, \numprint, \unitsdef or \unitspkg. % Some ideas have also been borrowed from \pkg{biblatex}; again these % will not be specifically noted. Code from other packages will be % marked when used. % % User-space commands (those not containing |@|) defined here should % give the same result as macros with the same name in the older % packages. However, internal package macros may behave differently; % if the user has redefined internal macros, then compatibility may % be impaired. % % The code used here uses \LaTeX\ rather than \TeX\ commands where % possible.\footnote{This applies to \LaTeX\ kernel commands only; % for example, \pkg{ifthenelse} is not used.} For example, % \cs{newcommand*} is used in place of \cs{def}, unless custom % parameters are needed. Hopefully, this will aid future % maintenance. Grouping is used where possible to limit the scope of % temporary assignments. % %\subsection{Setup code} % As always, the package starts with identification. A warning is then % printed about possible changes. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{si}% [2008/02/20 v.06a A comprehensive (SI) units package] \PackageInfo{si} {This package is experimental. \MessageBreak The interface and functionality is subject to review \MessageBreak and may be changed in later releases} % \end{macrocode} % The package requires \eTeX, so the usual test is made. % \begin{macrocode} \begingroup \@ifundefined{eTeXversion} {\PackageError{si} {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} % Packages needed for functionality are loaded. \pkg{xkeyval} % handles the package options, while \pkg{amstext} from the \AMS\ % bundle is needed for \cs{text}. \pkg{array} is needed for the new % column type for tabular material. \pkg{xspace} provides ``magic'' % spacing after macros, if requested. \pkg{xkeyval} has to be at % least v2.5, as earlier versions do not have the correct macros % available. As this will lead to serious errors later, \currpkg % aborts if \pkg{xkeyval} is too old. % \begin{macrocode} \RequirePackage{xkeyval} \@ifpackagelater{xkeyval}{2005/05/07} {} {\PackageError{si} {xkeyval >= 2.5 required} {si requires the `xkeyval' package, version 2.5 or later.\MessageBreak The version loaded is: `\@nameuse{ver@xkeyval.sty}'.\MessageBreak This is a fatal error; the package will abort.}% \endinput} \RequirePackage{amstext,array,xspace} % \end{macrocode} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} %\begin{macro}{\si@tempc} % Some scratch commands are defined; apart from where a known value % is carried through, these could contain anything. % \begin{macrocode} \newcommand*{\si@tempa}{} \newcommand*{\si@tempb}{} \newcommand*{\si@tempc}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@switch} % Various items will need a switch. To avoid name pollution, a % single switch is defined here; grouping will keep the definition % local. % \begin{macrocode} \newif\ifsi@switch % \end{macrocode} %\end{macro} %\begin{macro}{\si@packagecheck} %\begin{macro}{\si@tempa} % As \currpkg is intended to replace the other unit-management % packages, these are tested for before any further processing. If % any are loaded, the package halts compilation; name clashes or % unexpected results could occur if this is not tested. Notice that % \SIunits and \sistyle could be loaded with variable capitalisation % (at least on Windows); both possibilities are tested. Also notice % that \unitsdef must be tested before \unitspkg, so that users of % the former get an intelligible message. % \begin{macrocode} \newcommand*{\si@packagecheck}{% \begingroup \@for\si@tempa:=SIunits,siunits,sistyle,SIstyle,unitsdef\do{% \@ifpackageloaded{\si@tempa} {\PackageError{si} {Package `\si@tempa' incompatible} {The `\si@tempa' package and `si' are incompatible.\MessageBreak Use the `emulate=\si@tempa' package option when loading si.}} {}} % \end{macrocode} % Some packages should not cause a clash, but are emulated and would % be better handled that way. % \begin{macrocode} \@for\si@tempa:=units\do{% \@ifpackageloaded{\si@tempa} {\PackageWarning{si} {Consider loading the si package with\MessageBreak option `emulate=\si@tempa', rather than\MessageBreak loading both \si@tempa and si}} {}} \endgroup} % \end{macrocode} %\end{macro} % The check is carried out on loading and at the beginning of the % document, so that packages loaded both before and after % \currpkg are caught. % \begin{macrocode} \si@packagecheck \AtBeginDocument{\si@packagecheck} % \end{macrocode} %\end{macro} %\begin{macro}{\si@ifdefinable} % Using \cs{@ifdefinable} to check macro definitions gives a generic % error. To give something more helpful, \cs{@ifundefined} is used, % but this needs some \cs{expandafter} work. This way it can also be % used as a form of \cs{@ifundefined} for macro names.\\ %\cs{si@ifdefinable}\marg{macro} % \begin{macrocode} \newcommand*{\si@ifdefinable}[1]{% \expandafter\expandafter\expandafter\@ifundefined% \expandafter\expandafter\expandafter% {\expandafter\@gobble\string#1}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@addtolist} % It is quite useful to be able to add to a comma-separated list % of expandable items.\\ %\cs{si@addtolist}\marg{macro}\marg{items} % \begin{macrocode} \newcommand*{\si@addtolist}[2]{% \ifx\@empty#1\@empty \edef#1{#2}% \else \edef#1{#1,#2}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@addtocsname} %\begin{macro}{\si@temptoks} % A second item to add to a is macro.\\ %\cs{si@addtomacro}\marg{macro}\marg{tokens}\\ %\cs{si@addtocsname}\marg{csname}\marg{tokens} % \begin{macrocode} \newtoks{\si@temptoks} \newcommand*{\si@addtocsname}[2]{% \@ifundefined{#1} {\@namedef{#1}{#2}} {\si@temptoks\expandafter\expandafter\expandafter{% \csname #1\endcsname#2}% \expandafter\edef\csname #1\endcsname{\the\si@temptoks}}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@xifmtarg} %\begin{macro}{\si@ifnotmtarg} % To keep down dependance on other packages, the very short code % block from \pkg{ifmtarg} is copied here with an internal name. % \begin{macrocode} \begingroup \catcode`\Q=3 \long\gdef\si@xifmtarg#1#2Q#3#4#5\@nil{#4} \long\gdef\si@ifnotmtarg#1{% \si@xifmtarg#1QQ\@firstofone\@gobble\@nil} \endgroup % \end{macrocode} %\end{macro} %\end{macro} % %\subsection{Logging} %\begin{macro}{\ifsi@debug} %\begin{macro}{\ifsi@logmin} %\begin{macro}{\ifsi@lognone} % To control logging, some new switches are declared. % \begin{macrocode} \newif\ifsi@debug \newif\ifsi@logmin \newif\ifsi@lognone % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@log@err} %\begin{macro}{\si@log@warn} %\begin{macro}{\si@log@inf} % Some handy re-usable macros are defined here. These all take names % beginning These pop up in various places. First errors, warnings % and information are handled. Package options are used to control % how much output is given.\\ %\cs{si@log@err}\marg{error}\marg{explanation}\\ %\cs{si@log@warn}\marg{warning}\\ %\cs{si@log@inf}\marg{information} % \begin{macrocode} \newcommand*{\si@log@err}[2]{% \ifsi@lognone\else \ifsi@logmin \PackageWarning{si}{#1}% \else \PackageError{si}{#1}{#2}% \fi \fi} \newcommand*{\si@log@warn}[1]{% \ifsi@lognone\else \ifsi@logmin\else \PackageWarning{si}{#1}% \fi \fi} \newcommand*{\si@log@inf}[1]{% \ifsi@lognone\else \ifsi@logmin\else \PackageInfo{si}{#1}% \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@log@debug} % The debug macro only gives output if the appropriate package option % is set.\\ %\cs{si@log@debug}\marg{debug-information} % \begin{macrocode} \newcommand*{\si@log@debug}[1]{% \ifsi@lognone\else \ifsi@debug \PackageInfo{si}{#1}% \fi \fi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\subsection{Option handling} %\begin{macro}{\sisetup} % To allow modification of options at run time, a setup macro is % provided. The run of strange tests are to prevent problems in % arrays and the like.\\ %\cs{sisetup}\marg{keyval-options} % \begin{macrocode} \newcommand*{\sisetup}[1]{% \iffalse{\fi\ifnum0=`}\fi \setkeys[si]{opt}{#1}% \ifnum0=`{\fi\iffalse}\fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@opt@key} % To aid maintenance, some shortcuts are defined for generating keys. % These also allow the debugging messages to be added automatically % to every key. First of all the basic key definition.\\ %\cs{si@opt@key}\marg{keyname}\marg{code} % \begin{macrocode} \newcommand*{\si@opt@key}[2]{% \define@key[si]{opt}{#1} {#2\si@log@debug{Option #1 set to ##1}}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@opt@cmdkey} %\begin{macro}{\si@opt@cmdkeys} % The command versions of the above.\\ %\cs{si@opt@cmdkey}\oarg{default}\marg{keyname}\marg{function}\\ %\cs{si@opt@cmdkeys}\oarg{default}\marg{keynames} % \begin{macrocode} \newcommand*{\si@opt@cmdkey}[3][]{% \define@cmdkey[si]{opt}[si@]{#2}[#1]{#3}} \newcommand*{\si@opt@cmdkeys}[2][]{% \define@cmdkeys[si]{opt}[si@]{#2}[#1]} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@opt@boolkey} % Keys which only take switch values; anything other than \opt{true} % or \opt{false} will generate a warning from \pkg{xkeyval}. %\cs{si@opt@boolkey}\oarg{optional-processing}\marg{keyname} % \begin{macrocode} \newcommand*{\si@opt@boolkey}[2][]{% \define@boolkey[si]{opt}[si@]{#2}[true] {#1\si@log@debug{Option #2 set to ##1}}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@opt@choicekey} % A ``fill in the blanks'' choice key. In all cases, \cs{si@tempa} % is used to hold the value given to the key, so that \cs{ifx} % testing can occur.\\ %\cs{si@opt@choicekey}\oarg{default}\marg{keyname}\marg{choices}^^A %\marg{in-list}\marg{not-in-list} % \begin{macrocode} \newcommand*{\si@opt@choicekey}[5][]{% \define@choicekey*+[si]{opt}{#2}[\si@tempa]{#3}[#1] {#4\si@log@debug{Option #2 set to ##1}} {#5\si@log@debug{Option #2 set to ##1}}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@opt@xchoicekey} % Several of the package options can take either a choice from a list % of known options, or a value to be interpreted literally. To aid % maintenance, the necessary code can be set up here. These keys all % define a new macro, which must exist. The \cs{si@opt@xchoicekey} % macro therefore ensures that this is defined, as well as setting up % the \pkg{xkeyval} key.\\ %\cs{si@opt@xchoicekey}\marg{keyname}\marg{choices}\marg{initial} % \begin{macrocode} \newcommand*{\si@opt@xchoicekey}[3]{% \si@opt@choicekey[#3]{#1}{#2} % \end{macrocode} % This code will execute if the option is on the list. There will be % a ``fixed'' macro with a matching name, which is used for this. % \begin{macrocode} {\expandafter\renewcommand\expandafter*% \csname si@#1\endcsname{\@nameuse{si@fix@##1}}} % \end{macrocode} % The user has given something that is not on the list as an % argument. It is used literally. % \begin{macrocode} {\expandafter\renewcommand\expandafter*% \csname si@#1\endcsname{##1}} % \end{macrocode} % Finally, the initial value of the macro is set up. % \begin{macrocode} \expandafter\newcommand\expandafter*\csname si@#1\endcsname% {\@nameuse{si@fix@#3}}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@opt@compatkey} % An all-in-one definition for a back-compatibility key. These % should only be used at load time, so are automatically disabled % once the package is loaded. Emulation is also automatically turned % on.\\ %\cs{si@opt@compatkey}\marg{package}\marg{keyname}. % \begin{macrocode} \newcommand*{\si@opt@compatkey}[2]{% \define@boolkey[si]{opt}[si@old@]{#2}[true] {\si@log@debug{Emulating #1 package option\MessageBreak #2}% \sisetup{emulate=#1}% \si@log@debug{Option #2 set to ##1}} \AtEndOfPackage{\si@opt@disablekey{#2} {Compatibility option #2 only\MessageBreak available when loading si package}}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@opt@disablekey} % The ability to disable a key with a meaningful message is a must; % the warning will come from \currpkg, and not from \pkg{xkeyval}\\ %\cs{si@opt@disablekey}\marg{keyname}\marg{warning} % \begin{macrocode} \newcommand*{\si@opt@disablekey}[2]{% \key@ifundefined[si]{opt}{#1} {} {\si@log@debug{Disabling key #1}% \si@opt@key{#1}{\si@log@warn{#2}}}} % \end{macrocode} %\end{macro} % % The \pkg{xkeyval} package option for logging is declared. This is % then processed to set the switches correctly. % \begin{macrocode} \si@opt@choicekey[normal]{log}{debug,verbose,normal,errors,none} % \end{macrocode} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % A series of comparisons are made to assign the logging mode. The % \opt{normal} option is not tested, as executing the option sets the % switches appropriately. % \begin{macrocode} {\si@debugfalse \si@logminfalse \si@lognonefalse \renewcommand*{\si@tempb}{none}% \ifx\si@tempa\si@tempb \si@lognonetrue \fi \renewcommand*{\si@tempb}{minimal}% \ifx\si@tempa\si@tempb \si@logmintrue \fi \renewcommand*{\si@tempb}{debug}% \ifx\si@tempa\si@tempb \si@debugtrue \fi \renewcommand*{\si@tempb}{verbose}% \ifx\si@tempa\si@tempb \si@debugtrue \fi} % \end{macrocode} % The option has not been recognised: give a warning (if % appropriate). % \begin{macrocode} {\si@log@warn{Unrecognised value `#1' for option log}} % \end{macrocode} %\end{macro} %\end{macro} % A quick method to set \opt{log=debug}. % \begin{macrocode} \si@opt@boolkey{debug} % \end{macrocode} %\begin{macro}{\si@emulate} % The \opt{emulate} option is used for back-compatibility mode; if % the keyword is given with no value, emulation of \SIunits is % assumed. % \begin{macrocode} \newcommand*{\si@emulate}{} \si@opt@choicekey[SIunits]{emulate} {SIunits,sistyle,numprint,units,unitsdef} {\si@log@debug{Found emulation request for #1 package}% \si@addtolist{\si@emulate}{#1}} {\si@log@warn{Unknown value `#1' for option emulate \MessageBreak No emulation will occur}} % \end{macrocode} %\end{macro} % The \opt{emulate} option is no longer valid once the package has % been loaded. % \begin{macrocode} \AtEndOfPackage{% \si@opt@disablekey{emulate} {emulate option only available when\MessageBreak loading package}} % \end{macrocode} %\begin{macro}{\si@unitsep} %\begin{macro}{\si@unitspace} %\begin{macro}{\si@valuesep} % The two \opt{\dots space} options control the size of spaces % between the number and the unit (\cs{si@valuesep}), and that used % to represent a product (\cs{si@unitsep}). Known values here are % \opt{thin}, \opt{med}, \opt{medium}, \opt{thick}, % \opt{cdot}\footnote{only valid for \opt{unitsep}.} and % \opt{none};\footnote{Only valid for \opt{valuesep.}} other entries % will be treated as custom spaces. % \begin{macrocode} \si@opt@xchoicekey{unitsep}{thin,med,medium,thick,space,none,cdot, times}{thin} \si@opt@xchoicekey{unitspace}{space,thin,med,medium,thick,none} {thin} \si@opt@xchoicekey{valuesep}{space,thin,med,medium,thick,none} {thin} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@digitsep} % Separation of digits in large numbers is controlled by the % \opt{digitsep} option. As with the other \opt{sep} values, this % one has a choice of possible values. The list is quite long, so % that a range of options are handled automatically. Notice that % \opt{digitsep=none} will be used for no separation at all. % \begin{macrocode} \si@opt@xchoicekey{digitsep} {thin,med,medium,thick,none,comma,stop,fullstop,period}{thin} % \end{macrocode} %\end{macro} %\begin{macro}{\si@decimalsign} % The symbol used for the decimal position is varied here. There are % only two real options, but options are given for the name of a full % stop. % \begin{macrocode} \si@opt@xchoicekey{decimalsign}{comma,stop,fullstop,period,cdot} {fullstop} % \end{macrocode} %\end{macro} %\begin{macro}{\si@anglesep} % The separator between degrees and minutes, and between minutes and % seconds, when using \cs{ang}. % \begin{macrocode} \si@opt@xchoicekey{anglesep}{thin,med,medium,thick,none}{none} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@obeymode} % The first test for the font control is whether to respect the % surrounding maths or text mode. % \begin{macrocode} \si@opt@boolkey{obeymode} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@textmode} % The output of the package can be typeset using either text or maths % mode fonts. This is controlled using the \opt{mode} option and the % \cs{ifsi@textmode} switch. % \begin{macrocode} \newif\ifsi@textmode \si@opt@boolkey{textmode} \si@opt@choicekey{mode}{math,maths,text} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % \cs{si@tempb} used to for the expansion tests. The default is % \opt{none}, as the choice key will not allow other values to get % here. % \begin{macrocode} {\si@textmodefalse \renewcommand*{\si@tempb}{text}% \ifx\si@tempa\si@tempb \si@textmodetrue \fi} {\si@log@warn{Unknown value `#1' for option mode}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@obeyfamily} % The package can work to match the font family (serif, sans serif, % typewriter) of the surrounding text. This is controlled by a % Boolean option. % \begin{macrocode} \si@opt@boolkey{obeyfamily} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@obeybold} % The package can attempt to respect bold, or may ignore it. % \begin{macrocode} \si@opt@boolkey{obeybold} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@inlinebtext} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % For inline maths, two options for checking what is bold are % available, the maths environment (\ie \cs{boldmath}) and the % surrounding text (\cs{textbf} or \cs{bffamily}). % \begin{macrocode} \newif\ifsi@inlinebtext \si@opt@choicekey{inlinebold}{text,maths,math} {\si@inlinebtextfalse \renewcommand*{\si@tempb}{text}% \ifx\si@tempa\si@tempb \si@inlinebtexttrue \fi} {\si@log@warn{Unknown value `#1' for option inlinebold}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@obeyitalic} % Italic is slightly different to bold, as there is no convenient % switch for maths. % \begin{macrocode} \si@opt@boolkey{obeyitalic} % \end{macrocode} %\end{macro} %\begin{macro}{\si@mathsdefault} %\begin{macro}{\si@mathsrm} %\begin{macro}{\si@mathssf} %\begin{macro}{\si@mathstt} % The fonts used by the package default to the obvious \LaTeX\ ones; % however, this needs to be exposed to user modification. First the % maths mode fonts are sorted out. % \begin{macrocode} \si@opt@cmdkeys{mathsdefault,mathsrm,mathssf,mathstt} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % To make life easier for the user, UK spellings are provided for the % maths keys. % \begin{macrocode} \si@opt@key{mathdefault}{\sisetup{mathsdefault=#1}} \si@opt@key{mathrm}{\sisetup{mathsrm=#1}} \si@opt@key{mathsf}{\sisetup{mathssf=#1}} \si@opt@key{mathtt}{\sisetup{mathstt=#1}} % \end{macrocode} %\begin{macro}{\si@textdefault} %\begin{macro}{\si@textrm} %\begin{macro}{\si@textsf} %\begin{macro}{\si@texttt} % The same thing for text mode fonts. Once again the default values % are pretty obvious. % \begin{macrocode} \si@opt@cmdkeys{textdefault,textrm,textsf,texttt} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@mathnumdefault} %\begin{macro}{\si@textnumdefault} % To allow numbers to be set in a different font to text, additional % options are set up. % \begin{macrocode} \si@opt@cmdkeys{mathnumdefault,textnumdefault} \si@opt@key{mathsnumdefault}{\sisetup{mathnumdefault=#1}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@numlist} %\begin{macro}{\si@numdecimal} %\begin{macro}{\si@numexp} %\begin{macro}{\si@numgobble} %\begin{macro}{\si@numsign} %\begin{macro}{\si@numextra} % The list of possible valid characters for parsing numbers is set % up. This is similar to \numprint, but with the \opt{extra} class, % and with characters ignored with no output renamed as \opt{gobble}. % \begin{macrocode} \si@opt@cmdkeys{numlist,numdecimal,numexp,numgobble,numsign,numextra} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@numvalid} % The various valid characters are collected together in a single % macro for later. In common with the above macros, this one starts % \cs{si@num\ldots}. The order here is the order the values are % tested later on. % \begin{macrocode} \newcommand*{\si@numvalid}{\si@numgobble\si@numexp\si@numsign% \si@numdecimal\si@numlist\si@numextra} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@sepfour} % With four digits in a number, separating may or may not be desired. % Note that this option is the same as one for \numprint. % \begin{macrocode} \si@opt@boolkey{sepfour} % \end{macrocode} %\end{macro} %\begin{macro}{\si@expproduct} % The marker for multiplication in exponential numbers is set up. % \begin{macrocode} \si@opt@xchoicekey{expproduct}{times,cdot}{times} % \end{macrocode} %\end{macro} %\begin{macro}{\si@exppower} % In the same area, the power for exponents is variable. Only one % choice is given. % \begin{macrocode} \si@opt@xchoicekey{exppower}{ten}{ten} % \end{macrocode} %\end{macro} %\begin{macro}{\si@prefixproduct} % The marker for multiplication in prefixes. % \begin{macrocode} \si@opt@xchoicekey{prefixproduct}{times,cdot,none}{times} % \end{macrocode} %\end{macro} %\begin{macro}{\si@prefixpower} % In the same area, the power for prefixes is variable. Here, two % choices ar needed. % \begin{macrocode} \si@opt@xchoicekey{prefixpower}{ten,two}{ten} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@prefixnum} % Unit prefixes can be given as either symbols or numerically. % \begin{macrocode} \newif\ifsi@prefixnum \si@opt@choicekey{prefix}{symbol,letter,power,number} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % \cs{si@tempb} used to for the expansion tests. The default is % \opt{none}, as the choice key will not allow other values to get % here. % \begin{macrocode} {\si@prefixnumfalse \renewcommand*{\si@tempb}{power}% \ifx\si@tempa\si@tempb \si@prefixnumtrue \fi \renewcommand*{\si@tempb}{number}% \ifx\si@tempa\si@tempb \si@prefixnumtrue \fi} {\si@log@warn{Unknown value `#1' for option prefix}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@num@padlead} %\begin{macro}{\ifsi@num@padtrail} % A setting is needed to indicate when to add zeros to decimal % numbers, either before the decimal marker (|.1| giving % ``\num[padnumber=all]{.1}'') or after (|1.| giving % ``\num[padnumber=all]{1.}''). % \begin{macrocode} \newif\ifsi@num@padlead \newif\ifsi@num@padtrail \si@opt@choicekey[all]{padnumber} {leading,lead,trailing,trail,all,both,true,none,false} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % \cs{si@tempb} is used to for the expansion tests. The default is % \opt{none}, as the choice key will not allow other values to get % here. % \begin{macrocode} {\si@num@padleadfalse \si@num@padtrailfalse \renewcommand*{\si@tempb}{leading}% \ifx\si@tempa\si@tempb \si@num@padleadtrue \fi \renewcommand*{\si@tempb}{lead}% \ifx\si@tempa\si@tempb \si@num@padleadtrue \fi \renewcommand*{\si@tempb}{trailing}% \ifx\si@tempa\si@tempb \si@num@padtrailtrue \fi \renewcommand*{\si@tempb}{trail}% \ifx\si@tempa\si@tempb \si@num@padtrailtrue \fi \renewcommand*{\si@tempb}{all}% \ifx\si@tempa\si@tempb \si@num@padleadtrue \si@num@padtrailtrue \fi \renewcommand*{\si@tempb}{true}% \ifx\si@tempa\si@tempb \si@num@padleadtrue \si@num@padtrailtrue \fi \renewcommand*{\si@tempb}{both}% \ifx\si@tempa\si@tempb \si@num@padleadtrue \si@num@padtrailtrue \fi} {\si@log@warn{Unknown value `#1' for option padnumber}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@sign} %\begin{macro}{\ifsi@num@signmant} %\begin{macro}{\ifsi@num@signexp} % Some new switches for adding signs to numbers % \begin{macrocode} \newif\ifsi@num@signmant \newif\ifsi@num@signexp % \end{macrocode} %\end{macro} %\end{macro} % Signs can be added to numbers by default. Two options are needed % here; whether to add a sign by default, and what the sign is. % \begin{macrocode} \si@opt@xchoicekey{sign}{plus,minus,pm,mp}{plus} \si@opt@choicekey[all]{addsign} {mantissa,exponent,mant,exp,all,both,true,none,false} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % The option is now processed. % \begin{macrocode} {\si@num@signmantfalse \si@num@signexpfalse \renewcommand*{\si@tempb}{mantissa}% \ifx\si@tempa\si@tempb \si@num@signmanttrue \fi \renewcommand*{\si@tempb}{mant}% \ifx\si@tempa\si@tempb \si@num@signmanttrue \fi \renewcommand*{\si@tempb}{exponent}% \ifx\si@tempa\si@tempb \si@num@signexptrue \fi \renewcommand*{\si@tempb}{exp}% \ifx\si@tempa\si@tempb \si@num@signexptrue \fi \renewcommand*{\si@tempb}{all}% \ifx\si@tempa\si@tempb \si@num@signmanttrue \si@num@signexptrue \fi \renewcommand*{\si@tempb}{true}% \ifx\si@tempa\si@tempb \si@num@signmanttrue \si@num@signexptrue \fi \renewcommand*{\si@tempb}{both}% \ifx\si@tempa\si@tempb \si@num@signmanttrue \si@num@signexptrue \fi} {\si@log@warn{Unknown value `#1' for option addsign}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@ang@padsmall} %\begin{macro}{\ifsi@ang@padlarge} % A switch for determining whether to typeset |\ang{;;1}| as % \ang[padangle=both]{;;1} or \ang[padangle=none]{;;1}. First, two % new Boolean switches are needed to indicate padding. % \begin{macrocode} \newif\ifsi@ang@padsmall \newif\ifsi@ang@padlarge \si@opt@choicekey[all]{padangle} {small,large,all,both,true,none,false} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % \cs{si@tempb} is used to for the expansion tests. The default is % \opt{none}, as the choice key will not allow other values to get % here. % \begin{macrocode} {\si@ang@padsmallfalse \si@ang@padlargefalse \renewcommand*{\si@tempb}{small}% \ifx\si@tempa\si@tempb \si@ang@padsmalltrue \fi \renewcommand*{\si@tempb}{large}% \ifx\si@tempa\si@tempb \si@ang@padlargetrue \fi \renewcommand*{\si@tempb}{all}% \ifx\si@tempa\si@tempb \si@ang@padsmalltrue \si@ang@padlargetrue \fi \renewcommand*{\si@tempb}{true}% \ifx\si@tempa\si@tempb \si@ang@padsmalltrue \si@ang@padlargetrue \fi \renewcommand*{\si@tempb}{both}% \ifx\si@tempa\si@tempb \si@ang@padsmalltrue \si@ang@padlargetrue \fi} {\si@log@warn{Unknown value `#1' for option padangle}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@astroang} % A slightly odd option to allow the method used by astronomers for % angles. % \begin{macrocode} \si@opt@boolkey{astroang} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tabformat} % The formatting of numbers in tables is handled by a % \pkg{dcolumn}-like system. For that, a single option is needed to % control the centring of data in the table. % \begin{macrocode} \si@opt@cmdkey[-1]{tabformat}{} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@xspace} % Unit macros on their own may need \pkg{xpsace}. % \begin{macrocode} \si@opt@boolkey{xspace} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@frac} %\begin{macro}{\ifsi@slash} % The option processing for formatting units with \cs{per} in them % needs two switches. % \begin{macrocode} \newif\ifsi@slash \newif\ifsi@frac \si@opt@choicekey[reciprocal]{per} {reciprocal,rp,power,slash,frac,fraction} % \end{macrocode} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % The usual value testing, with a default to use reciprocal powers. % \begin{macrocode} {\si@slashfalse \si@fracfalse \renewcommand*{\si@tempb}{slash}% \ifx\si@tempa\si@tempb \si@fractrue \si@slashtrue \let\si@frac\si@frc@slash \fi \renewcommand*{\si@tempb}{frac}% \ifx\si@tempa\si@tempb \si@fractrue \fi \renewcommand*{\si@tempb}{fraction}% \ifx\si@tempa\si@tempb \si@fractrue \fi} {\si@log@warn{Unknown value `#1' for option per}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@slash} % For the \opt{slash} option, the separator can be customised. % \begin{macrocode} \si@opt@xchoicekey{slash}{slash}{slash} % \end{macrocode} %\end{macro} %\begin{macro}{\si@denrbrac} %\begin{macro}{\si@denlbrac} % Macros for the right and left brackets added to % potentially-ambiguous denominators. % \begin{macrocode} \si@opt@cmdkeys{denrbrac,denlbrac} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % In the case of fractional handling of the \cs{per} operator, % further refinement is available. % \begin{macrocode} \si@opt@choicekey[frac]{fraction} {frac,nicefrac,nice,sfrac,xfrac,uglyfrac,ugly} {\let\si@frac\si@frc@frac \renewcommand*{\si@tempb}{nicefrac}% \ifx\si@tempa\si@tempb \let\si@frac\si@frc@nice \fi \renewcommand*{\si@tempb}{uglyfrac}% \ifx\si@tempa\si@tempb \let\si@frac\si@frc@ugly \fi \renewcommand*{\si@tempb}{nice}% \ifx\si@tempa\si@tempb \let\si@frac\si@frc@nice \fi \renewcommand*{\si@tempb}{sfrac}% \ifx\si@tempa\si@tempb \let\si@frac\si@frc@sfrac \fi \renewcommand*{\si@tempb}{xfrac}% \ifx\si@tempa\si@tempb \let\si@frac\si@frc@sfrac \fi \renewcommand*{\si@tempb}{ugly}% \ifx\si@tempa\si@tempb \let\si@frac\si@frc@ugly \fi} {\si@log@warn{Unknown value `#1' for option fraction}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@load} %\begin{macro}{\si@noload} % Loading of support files is controlled by two keys. The first % defines a list of files that may be loaded, the second a list that % will not. This makes it easy to exclude a single file from a long % list. % \begin{macrocode} \si@opt@cmdkeys{load,noload} \si@opt@key{alsoload}{\si@addtolist{\si@load}{#1}} \AtEndOfPackage{% \si@opt@disablekey{load} {Configuration files can only be used\MessageBreak when loading si} \si@opt@disablekey{also} {Configuration files can only be used\MessageBreak when loading si} \si@opt@disablekey{noload} {Configuration files can only be used\MessageBreak when loading si}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@textOmega} %\begin{macro}{\si@mathsOmega} % The various non-Latin symbols need to be handled, and given user interfaces. % Some definitions are more complex than others; for \unitsym{\ohm} % things are easy. % \begin{macrocode} \si@opt@cmdkeys{textOmega,mathsOmega} \si@opt@key{mathOmega}{\sisetup{mathsOmega=#1}} \newcommand*{\si@mathsOmega}{\text{\ensuremath{\Omega}}} \newcommand*{\si@textOmega}{\ensuremath{\Omega}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@textmu} %\begin{macro}{\si@mathsmu} % For the \unitsym{\micro} symbol, some direct loading of symbols is % needed as the maths mu sign ($\mu$) is wrong. % \begin{macrocode} \si@opt@cmdkeys{textmu,mathsmu} \si@opt@key{mathmu}{\sisetup{mathsmu=#1}} \DeclareFontEncoding{TS1}{}{} \DeclareFontSubstitution{TS1}{cmr}{m}{n} \DeclareTextSymbol{\si@textmu}{TS1}{181} \DeclareTextSymbolDefault{\si@textmu}{TS1} \DeclareFontFamily{OML}{eur}{\skewchar\font127} \DeclareFontShape{OML}{eur}{m}{n}% {<5> <6> <7> <8> <9> gen * eurm % <10><10.95><12><14.4><17.28><20.74><24.88>eurm10}{} \DeclareSymbolFont{greek}{OML}{eur}{m}{n} \DeclareMathSymbol{\si@mathsmu}{\mathord}{greek}{"16} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@textdegree} %\begin{macro}{\si@mathsdegree} %\begin{macro}{\si@textminute} %\begin{macro}{\si@mathsminute} %\begin{macro}{\si@textsecond} %\begin{macro}{\si@mathssecond} % The angle signs. % \begin{macrocode} \si@opt@cmdkeys{textdegree,mathsdegree,textminute,mathsminute, textsecond,mathssecond} \si@opt@key{mathdegree}{\sisetup{mathsdegree=#1}} \si@opt@key{mathminute}{\sisetup{mathsminute=#1}} \si@opt@key{mathsecond}{\sisetup{mathssecond=#1}} \newcommand*{\si@textdegree}{\ensuremath{{}^{\circ}}} \newcommand*{\si@mathsdegree}{{}^{\circ}} \newcommand*{\si@textminute}{\ensuremath{{}^{\prime}}} \newcommand*{\si@mathsminute}{{}^{\prime}} \newcommand*{\si@textsecond}{\ensuremath{{}^{\prime\prime}}} \newcommand*{\si@mathssecond}{{}^{\prime\prime}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@textcelsius} %\begin{macro}{\si@mathscelsius} % Finally, degrees Celsius, which may need the degree symbol. % \begin{macrocode} \si@opt@cmdkeys{textcelsius,mathscelsius} \si@opt@key{mathcelsius}{\sisetup{mathscelsius=#1}} \newcommand*{\si@textcelsius}{\si@textdegree C} \newcommand*{\si@mathscelsius}{\si@mathsdegree\mathrm{C}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@textringA} %\begin{macro}{\si@mathsringA} % The \unitsym{\angstrom} sign. % \begin{macrocode} \si@opt@cmdkeys{textringA,mathsringA} \si@opt@key{mathringA}{\sisetup{mathsringA=#1}} \newcommand*{\si@textringA}{\AA} \newcommand*{\si@mathsringA}{\text{\AA}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@redefsymbols} % A flag for using \pkg{textcomp} and \pkg{upgreek} to provide better % symbols. % \begin{macrocode} \si@opt@boolkey{redefsymbols} \AtBeginDocument{% \si@opt@disablekey{redefsymbols} {Symbols can only be redefined\MessageBreak when loading si}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@eVcorra} %\begin{macro}{\si@eVcorrb} % \begin{macrocode} \newlength\si@eVcorra \newlength\si@eVcorrb \si@opt@key{eVcorra}{\setlength\si@eVcorra{#1}} \si@opt@key{eVcorrb}{\setlength\si@eVcorrb{#1}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@locale} %\begin{macro}{\si@loadlocales} %\begin{macro}{\si@loctolang} % Handling typographic conventions needs three keys. \opt{locale} is % used to set the locale, whereas \cs{loadlocales} reads in the % definitions at package load time. % \begin{macrocode} \si@opt@cmdkeys{loadlocales,loctolang} \si@opt@cmdkey{locale}{% \sisetup{loadlocales={#1}}% \AtEndOfPackage{\si@loc@set{#1}}} \AtBeginDocument{% \si@opt@disablekey{loadlocales} {Locale files can only be loaded\MessageBreak in the preamble} \si@opt@disablekey{loctolang} {Locale files can only be loaded\MessageBreak in the preamble} \si@opt@cmdkey{locale}{\si@loc@set{#1}}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\subsection{Compatibility options} %\begin{macro}{\ifsi@old@ugly} %\begin{macro}{\ifsi@old@nice} %\begin{macro}{\ifsi@old@loose} %\begin{macro}{\ifsi@old@tight} % With the options for the package set up, the next stage is to % provide support for users of the older packages. These all set up % switches, but do not do anything. That is left to the emulation % files, loaded at the end of the package. First of all, the % \unitspkg options are dealt with; there are not many. % \begin{macrocode} \si@opt@compatkey{units}{ugly} \si@opt@compatkey{units}{nice} \si@opt@compatkey{units}{loose} \si@opt@compatkey{units}{tight} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@old@OHM} %\begin{macro}{\ifsi@old@ohm} %\begin{macro}{\ifsi@old@redef-gensymb} %\begin{macro}{\ifsi@gensymb} % The \unitsdef package is unfortunately much more profligate with % options. The first set are to do with support for \pkg{gensymb}. % \begin{macrocode} \si@opt@compatkey{unitsdef}{OHM} \si@opt@compatkey{unitsdef}{ohm} \si@opt@compatkey{unitsdef}{redef-gensymb} \newif\ifsi@gensymb % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@old@LITER} %\begin{macro}{\ifsi@old@liter} %\begin{macro}{\ifsi@old@noxspace} %\begin{macro}{\ifsi@old@noconfig} % The second set are more general functionality. % \begin{macrocode} \si@opt@compatkey{unitsdef}{LITER} \si@opt@compatkey{unitsdef}{liter} \si@opt@compatkey{unitsdef}{noxspace} \si@opt@compatkey{unitsdef}{noconfig} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@old@noabbr} %\begin{macro}{\ifsi@old@noamperageabbr} %\begin{macro}{\ifsi@old@nofrequncyabbr} %\begin{macro}{\ifsi@old@nomolabbr} %\begin{macro}{\ifsi@old@novoltageabbr} %\begin{macro}{\ifsi@old@novolumeabbr} %\begin{macro}{\ifsi@old@noweightabbr} %\begin{macro}{\ifsi@old@noenergyabbr} %\begin{macro}{\ifsi@old@nolengthabbr} %\begin{macro}{\ifsi@old@notimeabbr} % The final set are for control of abbreviations, and are a good % demonstration of why to use \pkg{xkeyval}! % \begin{macrocode} \si@opt@compatkey{unitsdef}{noabbr} \si@opt@compatkey{unitsdef}{noampereageabbr} \si@opt@compatkey{unitsdef}{nofrequncyabbr} \si@opt@compatkey{unitsdef}{nomolabbr} \si@opt@compatkey{unitsdef}{novoltageabbr} \si@opt@compatkey{unitsdef}{novolumeabbr} \si@opt@compatkey{unitsdef}{noweightabbr} \si@opt@compatkey{unitsdef}{noenergyabbr} \si@opt@compatkey{unitsdef}{nolengthabbr} \si@opt@compatkey{unitsdef}{notimeabbr} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@old@cdot} %\begin{macro}{\ifsi@old@thickspace} %\begin{macro}{\ifsi@old@mediumspace} %\begin{macro}{\ifsi@old@thinspace} %\begin{macro}{\ifsi@old@thickqspace} %\begin{macro}{\ifsi@old@mediumqspace} %\begin{macro}{\ifsi@old@thinqspace} % The \SIunits package has lots of options. These ones are all % related to spacing. % \begin{macrocode} \si@opt@compatkey{SIunits}{cdot} \si@opt@compatkey{SIunits}{thickspace} \si@opt@compatkey{SIunits}{mediumspace} \si@opt@compatkey{SIunits}{thinspace} \si@opt@compatkey{SIunits}{thickqspace} \si@opt@compatkey{SIunits}{mediumqspace} \si@opt@compatkey{SIunits}{thinqspace} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@old@amssymb} %\begin{macro}{\ifsi@old@squaren} %\begin{macro}{\ifsi@old@pstricks} %\begin{macro}{\ifsi@old@Gray} %\begin{macro}{\ifsi@old@italian} % These options are used by \SIunits to control clashes with other % packages. % \begin{macrocode} \si@opt@compatkey{SIunits}{amssymb} \si@opt@compatkey{SIunits}{squaren} \si@opt@compatkey{SIunits}{pstricks} \si@opt@compatkey{SIunits}{Gray} \si@opt@compatkey{SIunits}{italian} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@old@textstyle} %\begin{macro}{\ifsi@old@binary} %\begin{macro}{\ifsi@old@noams} %\begin{macro}{\ifsi@old@derivedinbase} %\begin{macro}{\ifsi@old@derived} % The miscellaneous options. % \begin{macrocode} \si@opt@compatkey{SIunits}{textstyle} \si@opt@compatkey{SIunits}{binary} \si@opt@compatkey{SIunits}{noams} \si@opt@compatkey{SIunits}{derivedinbase} \si@opt@compatkey{SIunits}{derived} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\subsection{Constants} % A number of macros are needed by the package that provide a % non-changing output. These are defined here; the intention is that % these should not be macros that the user is likely to need to % alter. All of these macros have preface \cs{si@fix@}, to flag that % that are intended as constants. The package may rely on the % contents of these macros for functionality. % %\begin{macro}{\si@fix@thin} %\begin{macro}{\si@fix@med} %\begin{macro}{\si@fix@medium} %\begin{macro}{\si@fix@thick} %\begin{macro}{\si@fix@space} % First, there are the various space macros. To allow both \opt{med} % and \opt{medium} to be used as a space description, two macros are % needed for the same output. % \begin{macrocode} \newcommand*{\si@fix@thin}{\,} \newcommand*{\si@fix@med}{\:} \newcommand*{\si@fix@medium}{\:} \newcommand*{\si@fix@thick}{\;} \newcommand*{\si@fix@space}{\text{~}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@fix@cdot} %\begin{macro}{\si@fix@comma} %\begin{macro}{\si@fix@stop} %\begin{macro}{\si@fix@fullstop} %\begin{macro}{\si@fix@period} %\begin{macro}{\si@fix@times} % Next there are macros for material that is not simply whitespace. % To allow several options, the full-stop gets lots of names. % \begin{macrocode} \newcommand*{\si@fix@cdot}{\cdot} \newcommand*{\si@fix@comma}{{,}} \newcommand*{\si@fix@stop}{{.}} \newcommand*{\si@fix@fullstop}{{.}} \newcommand*{\si@fix@period}{{.}} \newcommand*{\si@fix@times}{\times} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@fix@plus} %\begin{macro}{\si@fix@minus} %\begin{macro}{\si@fix@pm} %\begin{macro}{\si@fix@mp} % Signs for numbers are needed. % \begin{macrocode} \newcommand*{\si@fix@plus}{+} \newcommand*{\si@fix@minus}{-} \newcommand*{\si@fix@pm}{\pm} \newcommand*{\si@fix@mp}{\mp} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@fix@two} %\begin{macro}{\si@fix@ten} % The literals ``2'' and ``10'' are needed for exponents. % \begin{macrocode} \newcommand*{\si@fix@two}{2} \newcommand*{\si@fix@ten}{10} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@fix@slash} % Another optional component that will probably not be used by many % people. % \begin{macrocode} \newcommand*{\si@fix@slash}{/} % \end{macrocode} %\end{macro} %\begin{macro}{\si@fix@none} % Finally for spacing, there is the possibility of nothing at all % \begin{macrocode} \newcommand*{\si@fix@none}{} % \end{macrocode} %\end{macro} % %\subsection{Symbols} %\begin{macro}{\si@symbol} % Each of the symbol macros needs to be set up; the options give a % maths and text mode sign, but internally a single macro is needed % for each. % \begin{macrocode} \newcommand*{\si@symbol}[1]{% \expandafter\DeclareRobustCommand\expandafter*\expandafter{% \csname si@sym@#1\endcsname}{% \ifmmode \expandafter\csname si@maths#1\expandafter\endcsname% \else \expandafter\csname si@text#1\expandafter\endcsname% \fi}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@sym@Omega} %\begin{macro}{\si@sym@ringA} %\begin{macro}{\si@sym@mu} %\begin{macro}{\si@sym@degree} %\begin{macro}{\si@sym@minute} %\begin{macro}{\si@sym@second} %\begin{macro}{\si@sym@celsius} % The various symbols are now declared. % \begin{macrocode} \si@symbol{Omega} \si@symbol{ringA} \si@symbol{mu} \si@symbol{degree} \si@symbol{minute} \si@symbol{second} \si@symbol{celsius} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{si@tempa} % The issue of redefinition of symbols now arises. \currpkg can % check for the loading of a number of support package, and can then % redefine the appropriate symbols. % \begin{macrocode} \AtBeginDocument{% \ifsi@redefsymbols \@ifpackageloaded{textcomp} {\si@log@debug{Redefining symbols using textcomp}% \renewcommand*{\si@textdegree}{\textdegree}% \renewcommand*{\si@mathsdegree}{\text{\textdegree}}% % \end{macrocode} % \pkg{mathptmx} will give issues with \pkg{textcomp} and the % \unitsym{\ohm} sign. % \begin{macrocode} \@ifpackageloaded{mathptmx}{} {\renewcommand*{\si@textmu}{\textmu}% \renewcommand*{\si@textOmega}{\textohm}}% % \end{macrocode} % The \unitsym{\angstrom} symbol is only redefined if the encoding is % OT1; other encodings should have a proper glyph used for \cs{AA}. % The \cs{encodingdefault} macro is \cs{long} for some reason. % \begin{macrocode} \long\def\si@tempa{OT1}% \ifx\si@tempa\encodingdefault \renewcommand*{\si@mathsringA}{\text{\capitalring{A}}}% \renewcommand*{\si@textringA}{\capitalring{A}} \fi}{} \@ifpackageloaded{upgreek} {\si@log@debug{Redefining symbols using upgreek}% \renewcommand*{\si@mathsmu}{\upmu}% \renewcommand*{\si@mathsOmega}{\Upomega}}{} \fi} % \end{macrocode} %\end{macro} % %\subsection{Handling fractions} %\begin{macro}{\si@frac} %\begin{macro}{\si@frc@frac} %\begin{macro}{\si@frc@slash} %\begin{macro}{\si@frc@nice} %\begin{macro}{\si@frc@sfrac} % Various methods of handling fractions are provided. % \begin{macrocode} \newcommand*{\si@frc@frac}[2]{% \ensuremath{\frac{\expandafter\si@unt@out\expandafter{#1}}% {\expandafter\si@unt@out\expandafter{#2}}}} \let\si@frac\si@frc@frac \newcommand*{\si@frc@slash}[2]{% \expandafter\si@unt@out\expandafter{#1}% \si@out@text{\ensuremath{\si@slash}}% \expandafter\si@unt@out\expandafter{#2}} \newcommand*{\si@frc@nice}[2]{% \ensuremath{\si@frc@nicefrac{\expandafter\si@unt@out% \expandafter{#1}}{\expandafter\si@unt@out\expandafter{#2}}}} \newcommand*{\si@frc@sfrac}[2]{% \sfrac{\expandafter\si@unt@out\expandafter{#1}}% {\expandafter\si@unt@out\expandafter{#2}}} \AtBeginDocument{% \@ifpackageloaded{xfrac} {} {\si@log@inf{xfrac package unavailable\MessageBreak using `fraction=sfrac' will fall back on\MessageBreak nicefrac-like method}% \renewcommand*{\si@frc@sfrac}[2]{% \si@log@warn{xfrac package unavailable}% \si@frc@nice{#1}{#2}}}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@frc@nicefrac} %\begin{macro}{\si@frc@displen} %\begin{macro}{\si@frc@textlen} %\begin{macro}{\si@frc@suplen} %\begin{macro}{\si@frc@ssuplen} % To avoid needing \unitspkg installed, the \cs{nicefrac} macro needs % to be emulated here. The code is taken (with permission) from % \kg{nicefrac}.\footnote{The original is licensed under the GPL; % thanks to the author Axel Reichert for permission to copy the code % here.} % \begin{macrocode} \newlength\si@frc@displen \newlength\si@frc@textlen \newlength\si@frc@suplen \newlength\si@frc@ssuplen \newcommand*{\si@frc@nicefrac}{% \ifmmode \expandafter\si@frc@mathsnf% \else \expandafter\si@frc@textnf% \fi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@frc@mathsnf} % The maths mode system.\\ %\cs{si@frc@mathsnf}\marg{numerator}\marg{denominator} % \begin{macrocode} \newcommand*{\si@frc@mathsnf}[2]{% \begingroup \settoheight{\si@frc@displen}{\ensuremath{\displaystyle{M}}}% \settoheight{\si@frc@textlen}{\ensuremath{\textstyle{M}}}% \settoheight{\si@frc@suplen}{\ensuremath{\scriptstyle{M}}}% \settoheight{\si@frc@ssuplen}{\ensuremath{\scriptscriptstyle{M}}}% \addtolength{\si@frc@displen}{-\si@frc@ssuplen}% \addtolength{\si@frc@textlen}{-\si@frc@ssuplen}% \addtolength{\si@frc@suplen}{-\si@frc@ssuplen}% \mathchoice {\raisebox{\si@frc@displen}{\ensuremath{\scriptstyle{#1}}}}% {\raisebox{\si@frc@textlen}{\ensuremath{\scriptstyle{#1}}}}% {\raisebox{\si@frc@suplen}% {\ensuremath{\scriptscriptstyle{#1}}}}% {\raisebox{\si@frc@ssuplen}% {\ensuremath{\scriptscriptstyle{#1}}}}% \mkern-2mu/\mkern-1mu% \bgroup \mathchoice {\scriptstyle}% {\scriptstyle}% {\scriptscriptstyle}% {\scriptscriptstyle}% {#2}% \egroup \endgroup} % \end{macrocode} %\end{macro} %\begin{macro}{\si@frc@textnf} % A stripped down version of the \pkg{nicefrac} system for text mode.\\ %\cs{si@frc@textnf}\marg{numerator}\marg{denominator} % \begin{macrocode} \newcommand*{\si@frc@textnf}[2]{% \begingroup \settoheight{\si@frc@textlen}{M}% \settoheight{\si@frc@ssuplen}{\fontsize\sf@size\z@% \selectfont{M}}% \addtolength{\si@frc@textlen}{-\si@frc@ssuplen}% \raisebox{\si@frc@textlen}{\fontsize\sf@size\z@% \selectfont{#1}}% \hspace{-0.25ex}/\hspace{-0.25ex}% \hbox{\fontsize\sf@size\z@\selectfont{#2}}% \endgroup} % \end{macrocode} %\end{macro} %\begin{macro}{\si@frc@ugly} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % The \cs{si@frc@ugly} macro is needed to emulate the \opt{ugly} % option in \unitspkg, where output depends on the current mode.\\ %\cs{si@frc@ugly}\marg{numerator} % \begin{macrocode} \newcommand*{\si@frc@ugly}[1]{% \def\si@tempa{#1}% \ifmmode \expandafter\si@frc@frac% \else \def\si@tempb{1}% \ifx\si@tempa\si@tempb % \end{macrocode} % The slash switch cannot be used, so the possibility of the % numerator being one is handled here. % \begin{macrocode} \setbox\si@tempbox=\hbox{\ensuremath{\si@valuesep}}% \hskip-\wd\si@tempbox% \def\si@tempa{}% \fi \expandafter\si@frc@slash% \fi {\si@tempa}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\subsection{Font control} % A number of controls and tests are needed to control the font used % for output. Underlying all of this is the \AMS\ package % \pkg{amstext} package, providing the \cs{text} command. Much of % the font control system here is taken more or less verbatim from % \sistyle; modifications have been made to fit the \currpkg % interface. % %\begin{macro}{\si@fam@getmfam} %\begin{macro}{\si@fam@sf} %\begin{macro}{\si@fam@tt} % The font families in use in the document are needed. % \begin{macrocode} \newcommand*{\si@fam@getmfam}{% \sbox{0}{$% \@ifundefined{mathsf} {\si@log@debug{No mathsf family found}% \global\chardef\si@fam@sf=99}% {\mathsf{\global\chardef\si@fam@sf=\fam}}% \@ifundefined{mathtt} {\si@log@debug{No mathtt family found}% \global\chardef\si@fam@tt=99}% {\mathtt{\global\chardef\si@fam@tt=\fam}}% $}} \AtBeginDocument{\si@fam@getmfam} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@fam@ifbtext} %\begin{macro}{\si@fam@ifbmaths} %\begin{macro}{\si@tempa} % These tests check for bold in text and maths mode, respectively.\\ %\cs{si@fam@ifbtext}\marg{code}\\ %\cs{si@fam@ifbmaths}\marg{code}\\ % \begin{macrocode} \newcommand*{\si@fam@ifbtext}[1]{% \if b\expandafter\@car\f@series\@nil #1\fi} \newcommand{\si@fam@ifbmaths}[1]{% \def\si@tempa{bold}% \ifx\math@version\si@tempa #1\fi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@fam@ifbinline} % For compatibility with \unitspkg, a method to change the behaviour % when in inline maths is needed for the bold detector. % \begin{macrocode} \newcommand*{\si@fam@ifbinline}{% \ifsi@inlinebtext \expandafter\si@fam@ifbtext% \else \expandafter\si@fam@ifbmaths% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@fam@ifitext} %\begin{macro}{\si@tempa} % This test check for italic or slanted text in text mode, by % negation (upright text is |n|).\\ %\cs{si@fam@ifitext}\marg{code}\\ % \begin{macrocode} \newcommand*{\si@fam@ifitext}[1]{% \if n\expandafter\@car\f@series\@nil\else #1\fi} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@fam@mode} % Detection of the current mode needs to happen``early'' (before any % change of \cs{ensuremath}). So a short macro is provided to do the % job. % \begin{macrocode} \newcommand*{\si@fam@mode}{% \ifsi@obeymode \ifmmode \sisetup{mode=maths}% \else \sisetup{mode=text}% \fi \fi} % \end{macrocode} %\end{macro} % %\begin{macro}{\ifsi@fam@set} % A marker is set up to check if font-matching has been taken place. % \begin{macrocode} \newif\ifsi@fam@set % \end{macrocode} %\end{macro} %\begin{macro}{\si@fam@set} % Using the code from \sistyle as a base, a set of tests are used to % set the current font families and weights. % \begin{macrocode} \newcommand*{\si@fam@set}{% \si@fam@settrue % \end{macrocode} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % The temporary macros are needed for the \cs{ifx} tests. % \begin{macrocode} \edef\si@tempa{\sfdefault}% \edef\si@tempb{\ttdefault}% % \end{macrocode} %\end{macro} %\end{macro} % The surrounding font family is only tested if matching is % requested. % \begin{macrocode} \ifsi@obeyfamily \si@log@debug{Font detection: checking font}% % \end{macrocode} %\begin{macro}{\si@fam@maths} %\begin{macro}{\si@fam@text} % Next, checks are needed for maths \latin{versus} text mode, and if % in maths mode, whether this is inline or display. Once that is % done, font families can be tested. % \begin{macrocode} \ifmmode \ifdim\displaywidth>0pt\relax \si@log@debug{Font detection: display maths}% \ifnum\the\fam=\si@fam@sf \si@log@debug{Font detection: sf}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathssf\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@textsf\endcsname \else \ifnum\the\fam=\si@fam@tt \si@log@debug{Font detection: tt}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathstt\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@texttt\endcsname \else \si@log@debug{Font detection: rm}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathsdefault\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@textdefault\endcsname \fi \fi % \end{macrocode} % Inline maths is now handled. % \begin{macrocode} \else \si@log@debug{Font detection: inline maths}% \ifx\f@family\si@tempa \si@log@debug{Font detection: sf}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathssf\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@textsf\endcsname \else \ifx\f@family\si@tempb \si@log@debug{Font detection: tt}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathstt\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@texttt\endcsname \else \si@log@debug{Font detection: rm}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathsdefault\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@textdefault\endcsname \fi \fi \fi % \end{macrocode} % Not in maths mode, so the text mode checks are carried out. % \begin{macrocode} \else \si@log@debug{Font detection: text}% \ifx\f@family\si@tempa \si@log@debug{Font detection: sf}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathssf\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@textsf\endcsname \else \ifx\f@family\si@tempb \si@log@debug{Font detection: tt}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathstt\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@texttt\endcsname \else \si@log@debug{Font detection: rm}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathsdefault\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@textdefault\endcsname \fi \fi \fi % \end{macrocode} % If the local font is not to be matched, setting the fonts is % rather less complex. % \begin{macrocode} \else \si@log@debug{Font detection: inactive}% \expandafter\let\expandafter\si@fam@maths \csname\si@mathsdefault\endcsname \expandafter\let\expandafter\si@fam@text \csname\si@textdefault\endcsname \fi % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@fam@bold} %\begin{macro}{\si@fam@setbold} % With the font family set, the next check is for bold text. This % again needs to examine the current mode. Things are a bit more % complex than in \sistyle as it is possible to be typesetting in % either text or maths mode. The bold commands are set up with % \cs{def}, as nested calls can occur. % \begin{macrocode} \def\si@fam@bold{\unboldmath\mdseries}% \def\si@fam@setbold{\boldmath\bfseries}% \ifsi@obeybold \si@log@debug{Weight detection: checking weight}% \ifmmode % \end{macrocode} %\end{macro} % Display maths. % \begin{macrocode} \ifdim\displaywidth>0pt\relax \si@fam@ifbmaths {\let\si@fam@bold\si@fam@setbold \si@log@debug{Weight detection: bold weight}}% % \end{macrocode} % Inline maths. % \begin{macrocode} \else \si@fam@ifbinline {\let\si@fam@bold\si@fam@setbold \si@log@debug{Weight detection: bold weight}}% \fi % \end{macrocode} % Text mode. % \begin{macrocode} \else \si@fam@ifbtext% {\let\si@fam@bold\si@fam@setbold \si@log@debug{Weight detection: bold weight}}% \fi \fi % \end{macrocode} %\end{macro} %\begin{macro}{\si@fam@italic} % The value of \opt{obeyitalic} is now tested; as this does nothing % in maths mode, a reminder is added to the log. % \begin{macrocode} \let\si@fam@italic\upshape \ifsi@obeyitalic \si@log@debug{Italic detection: checking italic}% \si@fam@ifitext {\let\si@fam@italic\relax \si@log@debug{Italic detection: italic}}% \ifsi@textmode\else \si@log@inf{maths mode - obeyitalic inactive}% \fi \fi} % \end{macrocode} %\end{macro} %\end{macro} % %\subsection{Formatting numbers} %\begin{macro}{\num} % The system used here is modelled on that in \numprint; the % input is broken down into single tokens, each one is examined and % the result is re-assembled into an output number. However, various % changes have been made to the system used, and so the macros here % are not simply renamed copies of those in \numprint. The user % macro \cs{num} sets any local keys, then calls the number % formatting macro on the processed number.\\ %\cs{num}\oarg{options}\marg{num} % \begin{macrocode} \DeclareRobustCommand*{\num}[2][]{% \begingroup% \sisetup{#1}% \si@fam@mode% \si@log@debug{Processing \string\num\space input `#2'}% \expandafter\si@out@num\expandafter{\si@num{#2}}% \endgroup} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num} % This is the main processing macro. Unlike the related macro in % \numprint, the output of this macro is not subjected to any font % changes. That is left to one of the \cs{si@out@\ldots} macros. No % grouping is applied here; any call to \cs{si@num} (or any of the % sub-macros) must be within a group as the definitions used rely on % this. Grouping is not applied here so that other macros can get % the various separated parts of the input.\\ %\cs{si@num}\marg{num} % \begin{macrocode} \newcommand*{\si@num}[1]{% % \end{macrocode} %\begin{macro}{\si@tempa} % The argument of the macro is fully expanded before any processing. % By using \cs{scantokens}, any odd problems from packages with % active characters can be avoided. A bit of trickery is needed to % avoid getting an extraneous space introduced here by % \cs{scantokens}, hence the use of \cs{@empty}. % \begin{macrocode} \begingroup \makeatletter% \@makeother{\,}% \@makeother{\.}% \@makeother{\+}% \@makeother{\-}% \def~{}% \def\,{}% \catcode`\~=\active\relax \catcode`\^=\active\relax \scantokens{\si@num@xdef\si@tempa{#1}\@empty}% \endgroup % \end{macrocode} % Processing only takes place if there is actually something in the % argument. This is tested once ``hard'' spaces have been stripped % out. If there is no argument, nothing happens; everything else in % the \cs{si@num} macro occurs only if the argument is filled. % \begin{macrocode} \si@ifnotmtarg{\si@tempa}{% % \end{macrocode} % The input is now validated. Further processing takes place a little % later. % \begin{macrocode} \expandafter\si@num@valid\si@tempa\@empty\@empty% % \end{macrocode} %\end{macro} % If the input is valid, the input is passed to the number formatter. % \begin{macrocode} \ifsi@switch \expandafter\si@num@format\expandafter\si@tempa% \else % \end{macrocode} % The parser must have bailed-out, and so no further processing of % the input is done. Instead, whatever was passed to the macro is % returned as supplied. % \begin{macrocode} {#1}% \fi}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@xdef} % When carrying out the \cs{edef} used to fully-expand a number, % \cs{,} and |~| are deactivated, so that macros do not end up in the % number. By using a separate macro, \cs{scantokens} is easier. % \cs{protected@xdef} is not used here, as the argument given should % only contain single (processable) characters or macros that expand % to the same, not other macros or characters.\\ %\cs{si@num@xdef}\meta{macro}\meta{num}\cs{@empty} % \begin{macrocode} \def\si@num@xdef#1#2\@empty{\xdef#1{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@valid} % Assuming that there is a non-space argument to \cs{si@num}, every % character is checked to ensure it is valid in the context, so that % further processing can occur without sanity checks. If the % character is valid, recursion occurs.\\ %\cs{si@num@valid}\meta{char}\meta{chars}\cs{@empty} % \begin{macrocode} \def\si@num@valid#1#2\@empty{% \si@num@ifchr{#1}{\si@numvalid}{% \ifx\@empty#2\@empty\else \si@num@valid#2\@empty\@empty\@empty% \fi \si@switchtrue}% % \end{macrocode} % If an invalid character has been picked up, the whole parsing % system has to bail out. % \begin{macrocode} {\si@log@err{Invalid character `#1' in numerical input}% {Only characters from the list `\si@numvalid'\MessageBreak should be present in the argument of the \string\num macro\MessageBreak (or derivative such as an `s' column)}% \si@switchfalse}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@ifchr} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % A test is needed to check one string only contains characters from % a second. The main macro sets up for the recursion system below.\\ %\cs{si@num@ifchr}\marg{test-chars}\marg{valid-chars} % \begin{macrocode} \newcommand*{\si@num@ifchr}[2]{% \begingroup \si@switchfalse \def\si@tempa{#1}% \edef\si@tempb{#2}% % \end{macrocode} %\end{macro} %\end{macro} % Now the test can occur for the initial comparison string. % \begin{macrocode} \expandafter\si@num@chrstr\si@tempb\@empty\@empty% % \end{macrocode} % By ending the group inside the \cs{if}, \cs{global} is avoided, and % the switch can be used for other jobs. % \begin{macrocode} \ifsi@switch% \endgroup\expandafter\@firstoftwo% \else \endgroup\expandafter\@secondoftwo% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@chrstr} % The second part of the comparison macro does the actual work. This % takes one character of the string of valid input at a time, and % compares it to the single character in \cs{si@tempa}.\\ %\cs{si@num@chrstr}\meta{char}\meta{chars}\cs{@empty} % \begin{macrocode} \def\si@num@chrstr#1#2\@empty{% % \end{macrocode} %\begin{macro}{\si@tempb} %\begin{macro}{\si@tempc} % \cs{si@tempc} is used to hold the single character to check against % \cs{si@tempa}, while \cs{si@tempb} stores the remaining characters % to be compared. % \begin{macrocode} \def\si@tempc{#1}% \edef\si@tempb{#2}% \ifx\si@tempa\si@tempc \si@switchtrue \else % \end{macrocode} %\end{macro} %\end{macro} % If \cs{si@tempb} is \cs{@empty}, then the recursion has % bottomed-out, and all of the comparisons are done. If not, go % round again. % \begin{macrocode} \ifx\@empty\si@tempb\@empty\else \si@num@chrstr#2\@empty% \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@exp} %\begin{macro}{\si@num@mant} %\begin{macro}{\si@num@expout} %\begin{macro}{\si@num@mantout} %\begin{macro}{\si@num@out} % Various storage macros are needed. % \begin{macrocode} \newcommand*{\si@num@exp}{} \newcommand*{\si@num@mant}{} \newcommand*{\si@num@expout}{} \newcommand*{\si@num@mantout}{} \newcommand*{\si@num@out}{} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@format} %\begin{macro}{\si@num@arg} % The number processor starts by saving |#1| (odd things happen % otherwise), and locally clearing the stacks.\\ %\cs{si@num@format}\marg{num} % \begin{macrocode} \newcommand*{\si@num@format}[1]{% \protected@edef\si@num@arg{#1}% \def\si@num@exp{}% \def\si@num@mant{}% \def\si@num@expout{}% \def\si@num@mantout{}% \si@log@debug{Formatting number `\si@num@arg'}% % \end{macrocode} %\end{macro} % \begin{macrocode} \si@switchfalse % \end{macrocode} % The input is split into an mantissa and an exponent. % \begin{macrocode} \expandafter\si@num@mantexp\si@num@arg\@empty\@empty% % \end{macrocode} % The mantissa and exponent are now processed separately. Firstly, a % sign is tested for. If there is one, it is added to % \cs{si@num@out}, while the rest of the number is returned ``as is'' % in \cs{si@num@\ldots}. % \begin{macrocode} \si@num@sign{mant}% % \end{macrocode} %\begin{macro}{\si@num@out} % To allow for the case where the mantissa is only a sign, but the % exponent contains a number, the output is initially defined to % whatever is in \cs{si@num@mantout}. This will change if there is a % number in \cs{si@num@mant}. % \begin{macrocode} \protected@edef\si@num@out{\si@num@mantout}% \ifx\@empty\si@num@mant\@empty\else \si@num@digits{mant}% \protected@edef\si@num@out{\si@num@mantout}% \fi \si@num@sign{exp}% \ifx\@empty\si@num@exp\@empty\else \si@num@digits{exp}% % \end{macrocode} % Allowance is made for the possibility of negative exponential-only % numbers. Precautions are taken for the multiply sign (which is % always in maths mode), and superscripts. \cs{textsuperscript} is % used here, as this will work in text or maths mode in the output % routine. % \begin{macrocode} \ifx\@empty\si@num@mant\@empty\else \protected@edef\si@num@out% {\si@num@out\noexpand\ensuremath{{}\noexpand\si@expproduct{}}}% \fi \protected@edef\si@num@out% {\si@num@out\si@exppower% \noexpand\textsuperscript{\si@num@expout}}% \fi % \end{macrocode} % If there is nothing in either number macro, then something is % wrong. % \begin{macrocode} \ifx\@empty\si@num@mant\@empty \ifx\@empty\si@num@exp\@empty \si@log@err{Invalid number format `\si@num@arg'}% {Something is wrong with the number format; does it contain \MessageBreak any numbers (from the list % `\si@numlist')?}% \renewcommand*\si@num@out{}% \fi \fi% % \end{macrocode} %\end{macro} % With everything done, the result is output. % \begin{macrocode} \si@num@out} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@mantexp} % Splitting the mantissa and exponent first checks for characters to % gobble, which are simply thrown away. For any other input, there % are two possibilities. If the character is an exponent marker, % then the package switches from collecting the mantissa to % collecting the exponent (after a sanity check). All other % characters are added to either the mantissa or the exponent, as % appropriate.\\ %\cs{si@num@mantexp}\meta{char}\meta{chars}\cs{@empty} % \begin{macrocode} \def\si@num@mantexp#1#2\@empty{% \si@num@ifchr{#1}{\si@numgobble}{}{% \si@num@ifchr{#1}{\si@numexp}% {\ifsi@switch \si@log@err{Duplicate exponent marker found}% {Only a single exponent character (from the list `\si@numexp')\MessageBreak may occur in a numerical argument}% \fi \si@switchtrue \si@log@debug{Exponent marker `#1' found in `\si@num@arg'}}% % \end{macrocode} % When building up the mantissa and exponent, everything must be % expandable, so \cs{edef} can be used rather than % \cs{g@addto@macro}. % \begin{macrocode} {\ifsi@switch \si@log@debug{Adding `#1' to exponent for `\si@num@arg'}% \protected@edef\si@num@exp{\si@num@exp#1}% \else \si@log@debug{Adding `#1' to mantissa for `\si@num@arg'}% \protected@edef\si@num@mant{\si@num@mant#1}% \fi}}% % \end{macrocode} % If the recursion has not bottomed out, another loop occurs. % \begin{macrocode} \ifx\@empty#2\@empty\else \si@num@mantexp#2\@empty\@empty\@empty% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@sign} % The digit processor does several things to convert the run of % digits, plus potentially a sign and a decimal point into the % correct format for output.\\ %\cs{si@num@sign}\marg{mant/exp} % \begin{macrocode} \newcommand*{\si@num@sign}[1]{% \expandafter\ifx\expandafter\@empty\csname si@num@#1\endcsname% \@empty\else % \end{macrocode} % If the whole argument is not empty, then the sign-testing macro is % run. This will return the sign in \cs{si@tempa} and the digits in % \cs{si@tempb}. % \begin{macrocode} \expandafter\expandafter\expandafter\si@num@gensign% \csname si@num@#1\endcsname\@empty\@empty\@empty% % \end{macrocode} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempc} % If a sign has to be added to unsigned numbers, this is % done here. % \begin{macrocode} \edef\si@tempc{#1}% \ifx\@empty\si@tempa\@empty \def\si@tempa{mant}% \ifx\si@tempa\si@tempc \ifsi@num@signmant \si@log@debug{Adding sign \si@sign\space to mantissa for `\si@num@arg'}% \protected@edef\si@tempa{\si@sign}% \else \def\si@tempa{}% \fi \else \ifsi@num@signexp \si@log@debug{Adding sign \si@sign\space to exponent for `\si@num@arg'}% \protected@edef\si@tempa{\si@sign}% \else \def\si@tempa{}% \fi \fi \fi % \end{macrocode} %\end{macro} %\end{macro} % If there is no sign, then the original macro contains a pure % number, and nothing happens (an empty number has already been % tested for). % \begin{macrocode} \ifx\@empty\si@tempa\@empty \def\si@tempa{mant}% \ifx\si@tempa\si@tempc \si@log@debug{Unsigned mantissa for `\si@num@arg'}% \else \si@log@debug{Unsigned exponent for `\si@num@arg'}% \fi \else % \end{macrocode} % There is a sign, so it is added to the output stack. % \begin{macrocode} \expandafter\protected@edef\csname si@num@#1out\endcsname% {\noexpand\ensuremath{\si@tempa}}% % \end{macrocode} % A sign but no number can only be correct if the input is something % like |-e10| to give \num{-e10}. % \begin{macrocode} \ifx\@empty\si@tempb\@empty \expandafter\def\csname si@num@#1\endcsname{}% % \end{macrocode} %\begin{macro}{\si@tempa} % \cs{si@tempa} is no longer needed, so can be reused. % \begin{macrocode} \def\si@tempa{mant}% % \end{macrocode} %\end{macro} % Checks to see if this is a mantissa, and that there is an exponent. % \begin{macrocode} \ifx\si@tempa\si@tempc \ifx\@empty\si@num@exp\@empty \si@log@warn{Sign but no number for `\si@num@arg'}% \fi \else \si@log@warn{Sign but no number for `\si@num@arg'}% \fi \else \expandafter\protected@edef\csname si@num@#1\endcsname% {\si@tempb}% \fi \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@gensign} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % The first one or two characters of the mantissa or exponent may % contain a sign. To test for this, the first two characters of the % number are split off, and examined. Two characters are used so % that \cs{pm} and \cs{mp} can be represented by |+-| and |-+|, % respectively. To allow the user to alter the valid signs, but % retain this conversion, the generic character test is used before % checking specific matches.\\ %\cs{si@num@gensign}\meta{char}\meta{char}\meta{chars}\cs{@empty} % \begin{macrocode} \def\si@num@gensign#1#2#3\@empty{% \si@num@ifchr{#1}{\si@numsign}{% \si@num@ifchr{#2}{\si@numsign}{% \if +#1 \if -#2 \si@log@debug{Found sign combination +- for `\si@num@arg'}% \def\si@tempa{\pm}% \else \si@log@warn{Unknown sign combination `#1#2'}% \def\si@tempa{#1#2}% \fi \else \if -#1 \if +#2 \si@log@debug{Found sign combination -+ for `\si@num@arg'}% \def\si@tempa{\mp}% \else \si@log@warn{Unknown sign combination `#1#2'}% \def\si@tempa{#1#2}% \fi \else \si@log@warn{Unknown sign combination `#1#2'}% \def\si@tempa{#1#2}% \fi \fi \edef\si@tempb{#3}}% % \end{macrocode} % Only one valid sign character. % \begin{macrocode} {\si@log@debug{Found single sign character `#1' for `\si@num@arg'}% \def\si@tempa{#1}% \edef\si@tempb{#2#3}}}% % \end{macrocode} % No valid sign, so \cs{@empty} is returned for the sign . % \begin{macrocode} {\si@log@debug{No sign found for `\si@num@arg'}% \def\si@tempa{}% \edef\si@tempb{#1#2#3}}}% % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@digits} %\begin{macro}{\si@tempb} %\begin{macro}{\si@tempc} % The core digit processor divides the number into the parts before % and after the decimal point marker.\\ %\cs{si@num@digits}\marg{mant/exp} % \begin{macrocode} \newcommand*{\si@num@digits}[1]{% \def\si@tempa{}% \def\si@tempb{}% % \end{macrocode} % The package switch is used to indicate finding a decimal marker. % \begin{macrocode} \si@switchfalse \expandafter\expandafter\expandafter\si@num@split% \csname si@num@#1\endcsname\@empty\@empty% % \end{macrocode} % The pre-decimal part of the number is now in \cs{si@tempa}, and the % post-decimal part in \cs{si@tempb}. A quick check is made on the % pre-decimal part of the number. % \begin{macrocode} \ifx\@empty\si@tempa\@empty \ifsi@num@padlead \si@log@debug{Adding leading zero for `\si@num@arg'}% \def\si@tempa{0}% \fi \fi % \end{macrocode} % A second test is needed, in case a zero should be added when a % decimal marker is followed by nothing at all. Here, the fact that % a decimal marker was found is needed; the test is done now so % \cs{ifsi@switch} can be reused. % \begin{macrocode} \ifx\@empty\si@tempb\@empty \ifsi@num@padtrail \ifsi@switch \si@log@debug{Adding trailing zero for `\si@num@arg'}% \def\si@tempb{0}% \fi \fi \fi % \end{macrocode} % The contents of \cs{si@tempa} and \cs{si@tempb} are now completed. % Some error checking is done, in case an odd argument has been % given. % \begin{macrocode} \ifx\@empty\si@tempa\@empty \ifx\@empty\si@tempb\@empty\else \si@num@sepdigits{#1}% \fi \else \si@num@sepdigits{#1}% \fi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@num@split} % The \cs{si@num@split} macro compares each character in the input % against the list of characters valid at this stage: numbers, % decimal markers and ``extra'' characters. Before finding a decimal % marker, numbers and extra characters are added to \cs{si@tempa}; % after a decimal is found, characters are added to \cs{si@tempb}.\\ %\cs{si@num@split}\meta{char}\meta{chars}\cs{@empty} % \begin{macrocode} \def\si@num@split#1#2\@empty{% \si@num@ifchr{#1}{\si@numdecimal}{% \ifsi@switch \si@log@err{Duplicate decimal marker in `\si@num@arg'} {Only a single decimal marker (from the list `\si@numdecimal')\MessageBreak may occur in a numerical argument}% \else \si@log@debug{Found decimal marker `#1' in `\si@num@arg'}% \si@switchtrue \fi}{% % \end{macrocode} % The earlier code only checks for a sign at the start of the text. A % check is therefore needed for a sign after the first two % characters; if one is found, it is ignored. % \begin{macrocode} \si@num@ifchr{#1}{\si@numsign}{% \si@log@err{Misplaced sign in `\si@num@arg'} {Sign characters `\si@numsign' can only occur\MessageBreak at the start of a number}}{% % \end{macrocode} % The current character is added to the appropriate stack. % \begin{macrocode} \ifsi@switch \si@log@debug{Adding `#1' to decimal part for `\si@num@arg'}% \protected@edef\si@tempb{\si@tempb#1}% \else \si@log@debug{Adding `#1' to integer part for `\si@num@arg'}% \protected@edef\si@tempa{\si@tempa#1}% \fi}}% % \end{macrocode} % Unless the recursion has bottomed, loop round again. % \begin{macrocode} \ifx\@empty#2\@empty\else \si@num@split#2\@empty\@empty% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@decimalhook} % A hook is needed to attach things inside the group to happen % afterwards, if the number is a decimal. % \begin{macrocode} \newcommand*{\si@num@decimalhook}{} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@sepdigits} % The \cs{si@num@sepdigits} macro is only called if at least one of % the mantissa and exponent contain something to output. The integer % and decimal parts of the number are processed separately. First, a % check is made to see if each part contains ``extra'' characters; if % it does, no digit-separating is even attempted.\\ %\cs{si@num@sepdigits}\marg{mant/exp} % \begin{macrocode} \newcommand*{\si@num@sepdigits}[1]{% \si@num@ifextra{\si@tempa}{} % \end{macrocode} %\begin{macro}{\si@tempc} % If the input is a pure number, then separation is attempted. % \begin{macrocode} {\expandafter\si@num@int\expandafter{\si@tempa}}% \def\si@tempc{}% \ifx\@empty\si@tempb\@empty\else \protected@edef\si@tempc{\noexpand\ensuremath{{\noexpand% \si@decimalsign}}}% \si@num@decimalhook% \si@num@ifextra{\si@tempb}{}% {\expandafter\si@num@dec\expandafter{\si@tempb}}% \fi % \end{macrocode} %\end{macro} % The construction is finalised by re-combining the number. % \begin{macrocode} \expandafter\protected@edef\csname si@num@#1out\endcsname% {\csname si@num@#1out\endcsname\si@tempa\si@tempc\si@tempb}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@ifextra} %\begin{macro}{\si@num@extra} % A relatively simple test for ``extra'' characters. Once again, a % bit of group trickery is used.\\ %\cs{si@num@ifextra}\marg{integer}\\ %\cs{si@num@extra}\meta{char}\meta{chars}\cs{@empty} % \begin{macrocode} \newcommand*{\si@num@ifextra}[1]{% \begingroup \si@switchfalse \expandafter\si@num@extra#1\@empty\@empty% \ifsi@switch \si@log@debug{Found `extra' characters in `#1'}% \endgroup\expandafter\@firstoftwo% \else \endgroup\expandafter\@secondoftwo% \fi} \def\si@num@extra#1#2\@empty{% \ifx\@empty#1\@empty\else \si@num@ifchr{#1}{\si@numextra}{\si@switchtrue}{}% \ifx\@empty#2\@empty\else \si@num@extra#2\@empty\@empty% \fi \fi} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@int} %\begin{macro}{\si@tempa} % The formatting code for separating thousands is taken more-or-less % directly from \sistyle. A few changes are made to fit the various % conventions here. Following on from the code above, \cs{si@tempa} % is used to store the integer part of the number, and \cs{si@tempb} % is used for the decimal part.\\ %\cs{si@num@int}\marg{integer-part} % \begin{macrocode} \newcommand*{\si@num@int}[1]{% \def\si@tempa{}% \ifsi@sepfour \si@num@intfmt{}#1\@empty\@empty\@empty% \else \si@num@iffive{#1} {\si@num@intfmt{}#1\@empty\@empty\@empty} {\def\si@tempa{#1}}% \fi} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@iffive} %\begin{macro}{\si@num@five} % A test is needed for the presence of more than four characters.\\ %\cs{si@num@iffive}\marg{num}\\ %\cs{si@num@five}\meta{char}\meta{char}\meta{char}\meta{char}^^A %\meta{chars}\cs{end}\\ % \begin{macrocode} \newcommand*{\si@num@iffive}[1]{% \si@num@five#1\@empty\@empty\@empty\@empty\@empty\end} \def\si@num@five#1#2#3#4#5\end{% \ifx\@empty#5\@empty \expandafter\@secondoftwo% \else \expandafter\@firstoftwo% \fi} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@intfmt} %\begin{macro}{\si@num@fiint} % The business end of the integer formatter. %\cs{si@num@intfmt}\marg{char}\marg{char}\marg{char}\marg{char}\\ %\cs{si@num@fiint}\meta{chars}\cs{fi}\cs{fi}\cs{fi} % \begin{macrocode} \newcommand*{\si@num@intfmt}[4]{% \ifx\@empty#2\@empty \si@num@intsep#1\relax \else \ifx\@empty#3\@empty \si@num@intsep\@empty\@empty#1#2\relax \else \ifx\@empty#4\@empty \si@num@intsep\@empty#1#2#3\relax \else \si@num@fiint{#1#2#3#4}% \fi \fi \fi} \def\si@num@fiint#1\fi\fi\fi{\fi\fi\fi\si@num@intfmt{#1}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@intsep} %\begin{macro}{\si@tempa} % For adding separation to integers, an extra function is needed.\\ %\cs{si@num@intsep}\marg{char}\marg{char}\marg{char}\marg{char} % \begin{macrocode} \newcommand*{\si@num@intsep}[4]{% \protected@edef\si@tempa{\si@tempa#1#2#3}% \if\relax#4\relax \else \protected@edef\si@tempa{\si@tempa\noexpand\ensuremath{\noexpand% \si@digitsep}}% \expandafter\si@num@intsep\expandafter#4% \fi} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@num@dec} %\begin{macro}{\si@num@decfmt} %\begin{macro}{\si@tempb} % Formatting a decimal uses a similar mechanism, but with a few % alterations needed.\\ %\cs{si@num@dec}\marg{decimal-part}\\ %\cs{si@num@decfmt}\marg{char}\marg{char}\marg{char}\marg{char}\\ % \begin{macrocode} \newcommand*{\si@num@dec}[1]{% \def\si@tempb{}% \ifsi@sepfour \si@num@decfmt#1\@empty\@empty\@empty\@empty% \else \si@num@iffive{#1} {\si@num@decfmt#1\@empty\@empty\@empty\@empty} {\protected@edef\si@tempb{\si@tempb#1}}% \fi } \newcommand*{\si@num@decfmt}[4]{% \protected@edef\si@tempb{\si@tempb#1#2#3}% \ifx\@empty#4\@empty% \else \protected@edef\si@tempb{\si@tempb\noexpand\ensuremath{\noexpand% \si@digitsep}}% \expandafter\si@num@decfmt\expandafter#4% \fi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\subsection{Formatting angles} %\begin{macro}{\ang} % The approach used here is similar to that in \sistyle, but has been % modified in a few ways.\\ %\cs{ang}\oarg{options}\marg{decimal-angle}\\ %\cs{ang}\oarg{options}|{|\meta{deg};\meta{min};\meta{sec}|}| % \begin{macrocode} \DeclareRobustCommand*{\ang}[2][]{% \begingroup \sisetup{#1}% \si@fam@mode% \si@log@debug{Processing \string\ang\space input `#2'}% \@makeother{\;}% \makeatletter% \scantokens{\si@ang@parse#2;;;\@nil}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@ang@parse} % With the correct catcodes in place, processing can take place strip % out the semi-colons.\\ %\cs{si@ang@parse}\meta{num}|;|\meta{num}|;|\meta{num}|;|^^A %\meta{chars}\cs{@nil} % \begin{macrocode} \def\si@ang@parse#1;#2;#3;#4\@nil{\si@ang@set{#1}{#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@ang@killdegree} %\begin{macro}{\si@ang@killminute} %\begin{macro}{\si@ang@killsecond} %\begin{macro}{\si@ang@astrosign} %\begin{macro}{\si@ang@decimalsign} % A mechanism is needed to handle moving the angle unit sings for the % \opt{astroang} option. This requires two steps, producing the sign % over the decimal sign and preventing duplicate symbols appearing.\\ %\cs{si@ang@astrosign}\marg{degree/minute/second} % \begin{macrocode} \newcommand*{\si@ang@killdegree}{\let\si@sym@degree\relax} \newcommand*{\si@ang@killminute}{\let\si@sym@minute\relax} \newcommand*{\si@ang@killsecond}{\let\si@sym@second\relax} \newcommand*{\si@ang@astrosign}[1]{% \renewcommand*{\si@decimalsign}{% \rlap{\si@ang@decimalsign}% \expandafter\csname si@sym@#1\endcsname}% \def\si@num@decimalhook{\expandafter\aftergroup% \csname si@ang@kill#1\endcsname}}% % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@ang@set} % The \cs{si@ang@set} macro does the work of assigning the degrees, % minutes and seconds, and actually typesetting the result.\\ %\cs{si@ang@set}\marg{num}\marg{num}\marg{num} % \begin{macrocode} \newcommand*{\si@ang@set}[3]{% % \end{macrocode} %\begin{macro}{\si@ang@degs} %\begin{macro}{\si@ang@mins} %\begin{macro}{\si@ang@secs} % First, the three macros that will contain the measures must exist. % \begin{macrocode} \ifsi@ang@padlarge \newcommand*{\si@ang@degs}{0\si@sym@degree}% \newcommand*{\si@ang@mins}{0\si@sym@minute}% \newcommand*{\si@ang@secs}{0\si@sym@second}% \else \newcommand*{\si@ang@degs}{}% \newcommand*{\si@ang@mins}{}% \newcommand*{\si@ang@secs}{}% \fi \protected@edef\si@ang@decimalsign{\si@decimalsign}% % \end{macrocode} %\begin{macro}{\si@ang@movesign} % Either the signs need to be moved, or this needs to be killed off. % \begin{macrocode} \ifsi@astroang \let\si@ang@movesign\si@ang@astrosign \else \let\si@ang@movesign\@gobble \fi % \end{macrocode} %\end{macro} %\begin{macro}{\si@ang@secnum} %\begin{macro}{\si@ang@minnum} % The arguments are now examined in reverse order. If they are % empty, then nothing is done. Otherwise, the larger measures are % zero-filled, if this has been requested. Some steps are needed % to allow for addition of signs to numbers. % \begin{macrocode} \newcommand*{\si@ang@secnum}{\si@ang@num{second}}% \newcommand*{\si@ang@minnum}{\si@ang@num{minute}}% \si@ifnotmtarg{#3} {\si@log@debug{Found seconds `#3'}% \renewcommand*{\si@ang@secs} {\si@ang@secnum{#3}\si@sym@second}% \renewcommand*{\si@ang@mins} {\si@ang@pad{0\si@sym@minute}}% \renewcommand*{\si@ang@degs} {\si@ang@pad{0\si@sym@degree}}}% \si@ifnotmtarg{#2} {\si@log@debug{Found minutes `#2'}% \renewcommand*{\si@ang@secnum}{\si@ang@signlessnum{second}}% \renewcommand*{\si@ang@mins} {\si@ang@minnum{#2}\si@sym@minute}% \renewcommand*{\si@ang@degs} {\si@ang@pad{0\si@sym@degree}}}% \si@ifnotmtarg{#1} {\si@log@debug{Found degrees `#1'}% \renewcommand*{\si@ang@secnum}{\si@ang@signlessnum{second}}% \renewcommand*{\si@ang@minnum}{\si@ang@signlessnum{minute}}% \renewcommand*{\si@ang@degs} % \end{macrocode} % The group here is needed to get the mechanism to move the symbol to % work properly. % \begin{macrocode} {\si@ang@num{degree}{#1}% \si@sym@degree}}% \si@out@num% {\si@ang@degs\si@anglesep\si@ang@mins\si@anglesep\si@ang@secs}% % \end{macrocode} %\end{macro} %\end{macro} % The group opened by \cs{ang} is closed. % \begin{macrocode} \endgroup} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@ang@pad} % Padding is only added if requested; the zero is a literal.\\ %\cs{si@ang@pad}\marg{num} % \begin{macrocode} \newcommand*{\si@ang@pad}[1]{% \ifsi@ang@padsmall #1% \else \relax% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@ang@num} %\begin{macro}{\si@ang@signlessnum} % Modified versions of \cs{num}, one to typeset angles without a % leading sign and the other with.\\ %\cs{si@ang@num}\marg{degree/minute/second}\marg{num}\\ %\cs{si@ang@signlessnum}\marg{degree/minute/second}\marg{num} % \begin{macrocode} \newcommand{\si@ang@num}[2]{% \begingroup% \si@ang@movesign{#1}% \si@num{#2}% \endgroup} \newcommand{\si@ang@signlessnum}[2]{% \begingroup% \si@ang@movesign{#1}% \sisetup{addsign=none}% \si@num{#2}% \endgroup} % \end{macrocode} %\end{macro} %\end{macro} % %\subsection{New column types} % The automatic formatting and alignment of numerical data in columns % is handled here. The various other packages that work in this area % are basically ripped-off here. The first part of the job is to % make a new column type. The letters |D|, |N| and |R| are taken by % other packages, so |s| (for \currpkg) is chosen. As in \pkg{rccol} % and \numprint, initially no definition is given as lots of code needs % to be added. % \begin{macrocode} \newcolumntype{s}{} % \end{macrocode} %\begin{macro}{\NC@rewrite@s} % Following the \numprint approach, the \cs{NC@rewrite@S} macro is now % changed to provide a hook for the collection of the tabular % material. This means messing with the internal macros of another % package, but there is no other way to do this. As \pkg{array} is a % standard package from the \pkg{tools} bundle, this should be % reasonably safe. After resetting the storage token registers, the % internal macro which handles optional arguments is called. % \begin{macrocode} \renewcommand*{\NC@rewrite@s}{% \@ifnextchar[%] {\si@tab@rewrite} {\si@tab@rewrite[]} } % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@rewrite} %\begin{macro}{\si@tempa} % An optional argument can now be picked up (this does not work using % the optional argument to \cs{renewcommand} for \cs{NC@rewrite@S}). % Here the begin and end code needed is added to the existing list if % \cs{@temptokena}, with the start and end macros unexpanded. % Argument |#1| contains any user setup options for this column.\\ %\cs{si@tab@rewrite}\oarg{options} % \begin{macrocode} \def\si@tab@rewrite[#1]{% \edef\si@tempa{\the\@temptokena >{\noexpand\si@tab@begin[#1]\noexpand\ignorespaces}c% <{\noexpand\si@tab@end}}% \@temptokena\expandafter{\si@tempa}% % \end{macrocode} % With the assignment done, the normal action of the \pkg{array} % package is continued. % \begin{macrocode} \NC@find} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@tab@numtoks} %\begin{macro}{\si@tab@pretoks} %\begin{macro}{\si@tab@posttoks} % Some storage is needed for the data to build up. In common with % \pkg{rccol} and \numprint, token registers are used for this (thus leaving % problematic input to be handled later). % \begin{macrocode} \newtoks\si@tab@numtoks \newtoks\si@tab@pretoks \newtoks\si@tab@posttoks % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@tab@begin} % The lead-off macro starts by setting any local values for % \cs{sisetup}. Although this is an internal macro, square brackets % for the option list are retained to make the option that this % argument may be empty.\\ %\cs{si@tab@begin}\oarg{options} % \begin{macrocode} \newcommand*{\si@tab@begin}[1][]{% \begingroup \sisetup{#1}% \si@tab@numtoks{}% \si@tab@pretoks{}% \si@tab@posttoks{}% \si@switchfalse \si@log@debug{Processing s column cell contents}% \si@tab@gettok} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@gettok} %\begin{macro}{\si@tab@next} % The iteration macro for collecting up tokens in the input. This is % a pretty much direct copy from \numprint. First |#1| is checked % against various special values.\\ %\cs{si@tab@gettok}\marg{cell-contents} % \begin{macrocode} \newcommand*{\si@tab@gettok}[1]{% % \end{macrocode} % The current cell could be the end of a line. % \begin{macrocode} \ifx\tabularnewline#1 \let\si@tab@next\tabularnewline \else % \end{macrocode} % If the table is in the usual \cs{begin}\texttt{\ldots}\cs{end} % construct, the \cs{end} might appear. % \begin{macrocode} \ifx\end#1 \let\si@tab@next\end \else % \end{macrocode} % The check for \cs{si@tab@end} deals with the likely situation that % the current cell is not the last of the line; the result will be % that the end-of-cell macro will be present. % \begin{macrocode} \ifx\si@tab@end#1 \let\si@tab@next\si@tab@end \else % \end{macrocode} % If \cs{begin}\texttt{\ldots}\cs{end} has not been used for the % table, then \cs{endtabular} might crop up. % \begin{macrocode} \ifx\endtabular#1 \let\si@tab@next\endtabular \else % \end{macrocode} % Apparently, \texttt{tabularx} might have a \cs{csname} at the end % of the cell. % \begin{macrocode} \ifx\csname#1 \let\si@tab@next\csname \else % \end{macrocode} % \cs{relax} is always a possibility. % \begin{macrocode} \ifx\relax#1\relax \let\si@tab@next\relax \else % \end{macrocode} % If the macro gets here, then the input should be stored, either as % part of a number or to be appended to the number. This is checked % by using \cs{si@numvalid}; initially this will hold the valid % characters defined before, but will be altered to \cs{@empty} if % collection of items after a number is in operation. The system is % set to recur, and the input is saved to the appropriate token % register. % \begin{macrocode} \let\si@tab@next\si@tab@gettok \si@num@ifchr{#1}{\si@numvalid} {\si@switchtrue \si@log@debug{Found valid cell contents `#1'}% \si@tab@numtoks=\expandafter{\the\si@tab@numtoks#1}} {\si@log@debug{Found other cell contents \string#1}% \si@tab@othertok{#1}}% \fi \fi \fi \fi \fi \fi % \end{macrocode} % Finally, execute whatever should be the next step. % \begin{macrocode} \si@tab@next} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@tab@othertok} % Unrecognised input is added to a token register, either before or % after the number.\\ %\cs{si@tab@othertok}\marg{chars} % \begin{macrocode} \newcommand*{\si@tab@othertok}[1]{% \ifsi@switch % \end{macrocode} % If working after a number has been found, it is necessary to % prevent any more input being added to the number. % \begin{macrocode} \si@tab@posttoks=\expandafter{\the\si@tab@posttoks#1}% \else \si@tab@pretoks=\expandafter{\the\si@tab@pretoks#1}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@end} % At the end of the cell, the actual output has to occur. % \begin{macrocode} \newcommand{\si@tab@end}{% \hfil% \the\si@tab@pretoks% % \end{macrocode} % If no number was found, then output is skipped. % \begin{macrocode} \ifsi@switch \expandafter\si@tab@numout% \fi \the\si@tab@posttoks% \hfil% \endgroup} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tempcnta} %\begin{macro}{\si@tempcntb} % Counters are needed for the digit-counting system. % \begin{macrocode} \newcount\si@tempcnta \newcount\si@tempcntb % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@tab@numout} % If a number is found, then some secondary processing is needed to % format it correctly. % \begin{macrocode} \newcommand*{\si@tab@numout}{% \let\si@num@format\si@tab@num@format % \end{macrocode} % Using the modified form of \cs{si@num}, the input (in % \cs{si@tab@numtoks} is parsed. This results in the mantissa before % the decimal place in \cs{si@num@mantout} and the rest of the % mantissa, plus any exponent part, in \cs{si@num@out}. The part of % the mantissa after the decimal marker (if any) is stored in % \cs{si@tab@mantout}, which can therefore be used as a flag for the % inclusion of a decimal sign. % \begin{macrocode} \expandafter\si@num\expandafter{\the\si@tab@numtoks}% \afterassignment\si@tab@format\expandafter\si@tempcnta% \si@tabformat\relax} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@mantout} % A storage macro is needed. % \begin{macrocode} \newcommand*{\si@tab@mantout}{} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@num@format} % A modified version of \cs{si@num@format} is needed, as the % ``decomposed'' number is needed directly by the table formatting % system.\\ %\cs{si@tab@num@format}\marg{num} % \begin{macrocode} \newcommand*{\si@tab@num@format}[1]{% % \end{macrocode} %\begin{macro}{\si@tab@org@sepdigits} % The crucial sub-macro is redirected. % \begin{macrocode} \let\si@tab@org@sepdigits\si@num@sepdigits \let\si@num@sepdigits\si@tab@num@sepdigits % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@arg} % With that done, things continue as in the original. % \begin{macrocode} \edef\si@num@arg{#1}% \si@switchfalse \expandafter\si@num@mantexp\si@num@arg\@empty\@empty% \si@num@sign{mant}% \ifx\@empty\si@num@mant\@empty\else \si@num@digits{mant}% % \end{macrocode} %\end{macro} %\begin{macro}{\si@num@out} % The pre-decimal part of the the number is in \cs{si@num@mantout}, % with the post-decimal part in \cs{si@tab@mantout}. This ensures % that there is no need to shuffle the location of any sign. The macro % now continues to build up everything after the decimal sign in % \cs{si@num@out}. % \begin{macrocode} \protected@edef\si@num@out{\si@tab@mantout}% \fi % \end{macrocode} % For the exponent, processing is back to normal. % \begin{macrocode} \let\si@num@sepdigits\si@tab@org@sepdigits \si@num@sign{exp}% \ifx\@empty\si@num@exp\@empty\else \si@num@digits{exp}% \ifx\@empty\si@num@mant\@empty\else \protected@edef\si@num@out% {\si@num@out\noexpand\ensuremath{\noexpand\si@expproduct}}% \fi \protected@edef\si@num@out% {\si@num@out\si@exppower% \noexpand\textsuperscript{\si@num@expout}}% \fi \ifx\@empty\si@num@mant\@empty \ifx\@empty\si@num@exp\@empty \si@log@err{Invalid number format `\si@num@arg'}% {Something is wrong with the number format; does it contain \MessageBreak any numbers (from the list % `\si@numlist')?}% % \end{macrocode} %\begin{macro}{\si@tab@mantout} % Need to clear both storage areas. % \begin{macrocode} \renewcommand*\si@num@out{}% \renewcommand*\si@tab@mantout{}% \fi \fi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@tab@num@sepdigits} % An altered version of \cs{si@num@sepdigits} is needed, so that the % division of the data is made before and after the decimal sign for % the mantissa.\\ %\cs{si@tab@num@sepdigits}\marg{num} % \begin{macrocode} \newcommand*{\si@tab@num@sepdigits}[1]{% \si@num@ifextra{\si@tempa}{} {\expandafter\si@num@int\expandafter{\si@tempa}}% \def\si@tempc{}% \ifx\@empty\si@tempb\@empty\else \si@num@ifextra{\si@tempb}{}% {\expandafter\si@num@dec\expandafter{\si@tempb}}% \fi % \end{macrocode} % The storage of the results is different to the original version. % The pre-decimal part (plus any sign) is stored in the % \cs{si@num@}|#1out| macro, while the post-decimal part ends up in % \cs{si@tab@}|#1out|. No decimal sign is added in at all. % \begin{macrocode} \expandafter\protected@edef\csname si@num@#1out\endcsname% {\csname si@num@#1out\endcsname\si@tempa}% \expandafter\protected@edef\csname si@tab@#1out\endcsname% {\si@tempb}}% % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@prebox} %\begin{macro}{\si@tab@postbox} %\begin{macro}{\si@tempbox} % The various boxes needed for the column centring are declared % Unlike the \pkg{dcolumn} original, private boxes are used here. % \cs{si@tempbox} is used when a space to measure one of the % constituents is needed; it is never used for output. % \begin{macrocode} \newbox\si@tab@prebox \newbox\si@tab@postbox \newbox\si@tempbox % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@tab@format} % The formatting set up is taken from \pkg{dcolumn}, with a few minor % changes to fit the scheme used here. There is only one argument % here, as the appearance of the decimal sign is handled by the % \pkg{keyval} system. The numerical test here has been changed, % compared to \pkg{dcolumn}, so that a value of zero gives a column % centred on the decimal marker.\\ %\cs{si@tab@format}\marg{num}\cs{relax} % \begin{macrocode} \def\si@tab@format#1\relax{% \ifnum\z@<\si@tempcnta \expandafter\si@tab@right% \else \expandafter\si@tab@centre% \fi {#1}% % \end{macrocode} % Output of the formatted data occurs here; both positioning macros % produce formatted data in boxes zero and two. % \begin{macrocode} \box\si@tab@prebox\box\si@tab@postbox} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@centre} % This macro is executed if the decimal marker is at the centre of % the column. The argument is needed here to throw away anything % left on the input stack by \cs{si@tab@format}. Unlike % \pkg{dcolumn}, only a single macro is needed here, as the (divided) % number is already available.\\ %\cs{si@tab@centre}\marg{gobble} % \begin{macrocode} \newcommand*\si@tab@centre[1]{% % \end{macrocode} % Box zero is used to hold the pre-decimal part, with box two holding % the post-decimal part \emph{if} it is needed. % \begin{macrocode} \setbox\si@tab@prebox=\hbox% {\expandafter\si@out@num\expandafter{\si@num@mantout}}% \ifx\@empty\si@tab@mantout\@empty \ifx\@empty\si@num@out\@empty \setbox\si@tab@postbox=\hbox% {\phantom{\ensuremath{{\si@decimalsign}}}}% \else \setbox\si@tab@postbox=\hbox% {\expandafter\si@out@num\expandafter{\si@num@out}}% \fi \else \setbox\si@tab@postbox=\hbox% {\ensuremath{{\si@decimalsign}}% \expandafter\si@out@num\expandafter{\si@num@out}}% \fi % \end{macrocode} % Which of the two boxes is wider is now checked, and the smaller is % padded out. % \begin{macrocode} \ifdim \wd\si@tab@prebox>\wd\si@tab@postbox \setbox\si@tab@postbox=\hbox to\wd\si@tab@prebox% {\unhbox\si@tab@postbox\hfill}% \else \setbox\si@tab@prebox=\hbox to\wd\si@tab@postbox% {\hfill\unhbox\si@tab@prebox}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@predim} %\begin{macro}{\si@tab@postdim} %\begin{macro}{\si@tempdima} %\begin{macro}{\si@tempdimb} % Some storage dimensions are declared. % \begin{macrocode} \newdimen\si@tab@predim \newdimen\si@tab@postdim \newdimen\si@tempdima \newdimen\si@tempdimb % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@tab@right} % The column is not centred on the decimal marker; the user specifies % how many characters on each side are allowed for.\\ %\cs{si@tab@right}\marg{num} % \begin{macrocode} \newcommand*\si@tab@right[1]{% % \end{macrocode} % The width of a character is measured, and stored. % \begin{macrocode} \setbox\si@tempbox=\hbox{\si@out@num{1}} \si@tempdima\wd\si@tempbox % \end{macrocode} %\begin{macro}{\si@tab@prea} %\begin{macro}{\si@tab@preb} % If |#1| is empty, then no special processing is needed for box two. % On the other hand, if there is something in |#1| then a bit of % re-arranging is done. In particular notice that \cs{si@tempcnta} % is used with the pre-decimal value, before the post-decimal setting % is saved. % \begin{macrocode} \ifx\relax#1\relax \hfill \let\si@tab@prea\relax \let\si@tab@preb\relax \else \si@tab@predim\the\si@tempcnta\si@tempdima \si@tab@sepcorr{pre}% \edef\si@tab@prea{to\si@tab@predim}% \edef\si@tab@preb{\hss\hfill}% \si@tempcnta\@gobble#1\relax \fi % \end{macrocode} %\end{macro} %\end{macro} % The width of the box needed is calculated by multiplying the width % of a character (in \cs{si@tempdima} by the number of characters % requested (in \cs{si@tempcnta}. The width of the decimal sign is % also allowed for and added on. % \begin{macrocode} \si@tab@postdim\si@tempcnta\si@tempdima \setbox\si@tempbox=\hbox{\ensuremath{{\si@decimalsign}}}% \advance\si@tab@postdim\wd\si@tempbox \si@tab@sepcorr{post}% % \end{macrocode} % The pre-decimal part of the number is now added to box zero, with % the post decimal part in box two if needed. % \begin{macrocode} \setbox\si@tab@prebox=\hbox\si@tab@prea{\si@tab@preb% \expandafter\si@out@num\expandafter{\si@num@mantout}}% \ifx\@empty\si@tab@mantout\@empty \setbox\si@tab@postbox=\hbox to\si@tab@postdim% {\expandafter\si@out@num\expandafter{\si@num@out}\hfil}% \else \setbox\si@tab@postbox=\hbox to\si@tab@postdim% {\ensuremath{{\si@decimalsign}}\expandafter\si@out@num% \expandafter{\si@num@out}\hfil}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tab@sepcorr} % A spacing correction is needed \emph{if} the number of digits to be % allowed for will lead to the introduction of a separator. A counter % and dimension are needed for the testing.\\ %\cs{si@tab@sepcorr}\marg{num} % \begin{macrocode} \newcommand*{\si@tab@sepcorr}[1]{% \si@tempcntb\the\si@tempcnta\relax % \end{macrocode} % Calculate how many groups of three there are, then allow for not % separating four characters if \cs{ifsi@sepfour} is false. % \begin{macrocode} \divide\si@tempcntb\thr@@ \ifsi@sepfour\else \ifnum\the\si@tempcnta=4 \si@tempcntb\z@ \fi \fi % \end{macrocode} % The width of the separators is measured, and the correct number of % separator widths are added to the box dimension. % \begin{macrocode} \setbox\si@tempbox=\hbox{\ensuremath{\si@digitsep}}% \expandafter\advance\csname si@tab@#1dim\endcsname% \si@tempcntb\wd\si@tempbox}% % \end{macrocode} %\end{macro} % %\subsection{Units} %\begin{macro}{\SI} %\begin{macro}{\unitsym} % There are two types of user macros for the units system; those for % defining new units, prefixes and powers, and those for using them. % There are two macros for using units, \cs{SI} and \cs{unitsym}, % which work in very similar ways. \cs{unitsym} is just an alias for % \cs{SI} with no number; everything is handed off into an internal % macro. The internal macro also handles the optional prefix % argument to \cs{SI}\\ %\cs{SI}\oarg{options}\marg{num} %\cs{unitsym}\oarg{options}\marg{unit} % \begin{macrocode} \DeclareRobustCommand*{\SI}[2][]{% \@ifnextchar[%] {\si@SI[#1]{#2}} {\si@SI[#1]{#2}[]}} \DeclareRobustCommand*{\unitsym}[2][]{\si@SI[#1]{}[]{#2}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\newunit} %\begin{macro}{\renewunit} %\begin{macro}{\provideunit} % The \cs{newunit} and \cs{renewunit} macros create the new unit % macros. To allow a mechanism for checking an existing definition, % these macros simply carry out the appropriate tests, before handing % off to the internal macro. \cs{@ifdefinable} is not used here as a % customised error is desirable. Other than that, the code here gives % very similar results to \cs{newcommand} and \cs{renewcommand}. % Finally, \cs{provideunit} adds the unit definition only if it does % not already exist.\\ %\cs{newunit}\oarg{valuesep=none}\marg{unit}\marg{symbol}\\ %\cs{renewunit}\oarg{valuesep=none}\marg{unit}\marg{symbol}\\ %\cs{provideunit}\oarg{valuesep=none}\marg{unit}\marg{symbol} % \begin{macrocode} \newcommand*{\newunit}[3][]{% \si@ifdefinable{#2} {\si@unt@defunit[#1]{#2}{#3}} {\si@log@err{Unit \string#2 already defined!}\@eha}} \newcommand*{\renewunit}[3][]{% \si@ifdefinable{#2} {\si@log@err{Unit \string#2 undefined}\@ehc \si@unt@defunit[#1]{#2}{#3}} {\si@unt@defunit[#1]{#2}{#3}}} \newcommand*{\provideunit}[3][]{% \si@ifdefinable{#2} {\si@unt@defunit[#1]{#2}{#3}} {}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\newprefix} %\begin{macro}{\renewprefix} %\begin{macro}{\provideprefix} % The multiples of units are defined here; very similar code is used % to the \cs{newunit}, \etc., macros. The multiple prefixes cannot take % an optional argument, and must represent some power. Hence the arguments % required are different. %\cs{newprefix}\marg{multiple}\marg{powers-ten}\marg{symbol}\\ %\cs{renewprefix}\marg{multiple}\marg{powers-ten}\marg{symbol}\\ %\cs{provideprefix}\marg{multiple}\marg{powers-ten}\marg{symbol} % \begin{macrocode} \newcommand*{\newprefix}[3]{% \si@ifdefinable{#1} {\si@unt@defprefix{#1}{#2}{#3}} {\si@log@err{Prefix \string#1 already defined!}\@eha}} \newcommand*{\renewprefix}[3]{% \si@ifdefinable{#1} {\si@log@err{Prefix \string#1 undefined}\@ehc \si@unt@defprefix{#1}{#2}{#3}} {\si@unt@defprefix{#1}{#2}{#3}}} \newcommand*{\provideprefix}[3]{% \si@ifdefinable{#1} {\si@unt@defprefix{#1}{#2}{#3}} {}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\newpower} %\begin{macro}{\renewpower} %\begin{macro}{\providepower} % Here power multiples for units are set up. As with units and % multiples, a layered approach is used to keep things easy to % maintain. The optional argument here is \emph{not} a \pkg{keyval} % one: only \opt{post} is a valid value.\\ %\cs{newpower}\oarg{post}\marg{num}\marg{power}\\ %\cs{renewpower}\oarg{post}\marg{num}\marg{power}\\ %\cs{providepower}\oarg{post}\marg{num}\marg{power} % \begin{macrocode} \newcommand*{\newpower}[3][]{% \si@ifdefinable{#2} {\si@unt@defpower[#1]{#2}{#3}} {\si@log@err{Power \string#2 already defined!}\@eha}} \newcommand*{\renewpower}[3][]{% \si@ifdefinable{#2} {\si@log@err{Power \string#2 undefined}\@ehc \si@unt@defpower[#1]{#2}{#3}} {\si@unt@defpower[#1]{#2}{#3}}} \newcommand*{\providepower}[3][]{% \si@ifdefinable{#2} {\si@unt@defpower[#1]{#2}{#3}} {}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\ifsi@unt@num} % A flag is needed to tell the processor whether there is a number, % to get the correct spacing. The flag is true outside of the % processor % \begin{macrocode} \newif\ifsi@unt@num\si@unt@numtrue % \end{macrocode} %\end{macro} %\begin{macro}{\si@SI} %\begin{macro}{\si@unt@SIopts} % The internal processing starts with \cs{si@SI}, which processes the % second optional argument to \cs{SI} (which is empty for % \cs{unitsym}). Everything is set up in a group, and processing % begins by handling the options.\\ %\cs{si@SI}\oarg{options}\marg{unit}\oarg{preunit}\marg{unit} % \begin{macrocode} \def\si@SI[#1]#2[#3]#4{% \begingroup \si@ifnotmtarg{#1} {\sisetup{#1}% \edef\si@unt@SIopts{#1}}% % \end{macrocode} %\end{macro} % The prefix unit is handled before any processing of the number; the % flags are set to get spacing correct. % \begin{macrocode} \si@unt@numfalse \si@xspacefalse \si@ifnotmtarg{#3} {\si@log@debug{Prefix unit found}% \si@unt@printunit{#3}}% % \end{macrocode} % The numerical argument may be empty, in which case no extra space % should be produced. % \begin{macrocode} \si@ifnotmtarg{#2} {\si@log@debug{Number found in \string\SI\space argument}% \num{#2}% \si@unt@numtrue}% \si@ifnotmtarg{#4} {\si@unt@printunit{#4}}% \endgroup} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@ifliteral} %\begin{macro}{\ifsi@unt@littest} % The next stage of the processor is to determine whether or not the % argument of the unit macro is processable. For literal arguments, % this is not the case, and the argument is typeset ``as is''. On % the other hand, any units, \etc., declared by the package will work % with the processor, and so need to be executed before typesetting % the result.\\ %\cs{si@unt@ifliteral}\marg{text} % \begin{macrocode} \newif\ifsi@unt@littest \newcommand*{\si@unt@ifliteral}[1]{% \begingroup \si@unt@littesttrue % \end{macrocode} % The test relies on any non-processable test having some width; % hopefully, this should be the case. % \begin{macrocode} \setbox\si@tempbox=\hbox{\si@unt@out{#1}}% \ifdim\wd\si@tempbox>\z@\relax \endgroup\expandafter\@firstoftwo% \else \endgroup\expandafter\@secondoftwo% \fi} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\ifsi@unt@litout} %\begin{macro}{\si@unt@printunit} % The printing macro uses the above test to determine how to act. It % then carries out the appropriate action: either typesetting or % executing. A flag is also provided so that any macro units inside % a partially-literal argument will work (this is also needed to % emulate \unitsdef).\\ %\cs{si@unt@printunit}\marg{unit} % \begin{macrocode} \newif\ifsi@unt@litout \newcommand{\si@unt@printunit}[1]{% \si@unt@ifliteral{#1} % \end{macrocode} % The unit includes one or more literal items; typeset using the % unit typesetting macro. % \begin{macrocode} {\si@log@debug{Literal items found in unit argument:\MessageBreak outputting without further processing}% \si@unt@litouttrue \si@unt@addvaluesep% \si@unt@out{#1}} % \end{macrocode} % For processable output, the argument is executed; the macros are % all designed for this. % \begin{macrocode} {\si@log@debug{Macro unit found:\MessageBreak processing to format output}% \si@unt@init% \advance\si@unt@depthcnt\@ne\relax #1% \si@unt@final}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@addvaluesep} %\begin{macro}{\si@unt@addvalsep} %\begin{macro}{\si@unt@litvalsep} %\begin{macro}{\si@unt@stackvalsep} % To ensure no problems pop up with expansion, adding the value--unit % space is handled by a macro. % \begin{macrocode} \newcommand*{\si@unt@addvaluesep}{% \ifsi@unt@num \expandafter\si@unt@addvalsep% \fi} \newcommand*{\si@unt@addvalsep}{% \ifsi@unt@litout \expandafter\si@unt@litvalsep% \else \expandafter\si@unt@stackvalsep% \fi} \newcommand*{\si@unt@stackvalsep}{% \protected@edef\si@unt@spstack{\si@valuesep}} \newcommand*{\si@unt@litvalsep}{% \nobreak\ensuremath{\si@valuesep}\nobreak} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@spstack} %\begin{macro}{\si@unt@stacka} %\begin{macro}{\si@unt@stackb} %\begin{macro}{\si@unt@unitcnta} %\begin{macro}{\si@unt@unitcntb} %\begin{macro}{\si@unt@depthcnt} %\begin{macro}{\ifsi@unt@first} %\begin{macro}{\si@unt@init} % The initialisation macro sets up the various switches, and clears % the storage areas for the formatted output. There are two stacks, % as when typesetting as fractions, the two parts of the number have % to be stored separately. The depth counter is used to tell when % recursion ends in the processor. The ``first'' switch is needed as % the depth counter will not be at one for items processed by % \cs{SI}. % \begin{macrocode} \newcommand*{\si@unt@spstack}{} \newcommand*{\si@unt@stacka}{} \newcommand*{\si@unt@stackb}{} \newcount\si@unt@unitcnta \newcount\si@unt@unitcntb \newcount\si@unt@depthcnt \newif\ifsi@unt@first \si@unt@depthcnt\m@ne\relax \newcommand*{\si@unt@init}{% \begingroup \si@unt@litoutfalse \si@unt@firsttrue \si@unt@perfalse \si@unt@perseenfalse \si@unt@prepowerfalse \si@unt@depthcnt\z@\relax \si@unt@powerdim\z@\relax \si@unt@unitcnta\z@\relax \si@unt@unitcntb\z@\relax \si@unt@prefixcnt\z@\relax \renewcommand*{\si@unt@spstack}{}% \renewcommand*{\si@unt@stacka}{}% \renewcommand*{\si@unt@stackb}{}% \renewcommand*{\si@unt@holdstacka}{}% \renewcommand*{\si@unt@holdstackb}{}% \renewcommand*{\si@unt@lastadda}{space}% \renewcommand*{\si@unt@lastaddb}{space}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@final} % The finalisation macro finishes off the output and resets the flags. % \begin{macrocode} \newcommand*{\si@unt@final}{% \si@unt@third% \si@unt@stackout% \endgroup \ifsi@xspace \expandafter\expandafter\expandafter\xspace% \fi} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unt@defunit} % The internal macro for defining a unit does not check for % redefinition; that is done by the user macros. %\cs{si@unt@defunit}\oarg{valuesep=none}\marg{unit}\marg{symbol} % \begin{macrocode} \newcommand*{\si@unt@defunit}[3][]{% \si@log@debug{Declaring unit \string#2 with \MessageBreak meaning \string#3}% % \end{macrocode} % The optional argument can only have the value \opt{valuesep=none}, % which is used to prevent a space occurring between a number and the % units (for example, with \cs{degree}). The optional argument needs % to be saved; \cs{edef} is used so there is no issue with % redefinition. The macro name is effectively ``reversed'' so that % life is easier with the expansions here. % \begin{macrocode} \si@ifnotmtarg{#1} {\expandafter\expandafter\expandafter\def\expandafter% \csname\expandafter\@gobble\string#2@opt@unt@si\endcsname{#1}}% % \end{macrocode} % The unit macro itself is now defined. The definition simply % selects the correct path for the rest of the processing to go down. % To avoid needing specialised gobbling macros, the optional nature % of the first argument is dropped. % \begin{macrocode} \DeclareRobustCommand*{#2}[1][]{% \ifsi@unt@littest \expandafter\si@gobblethree \else % \end{macrocode} % For literal output, the third argument is all that is needed. % \begin{macrocode} \ifsi@unt@litout \expandafter\expandafter\expandafter\@gobbletwo \else \expandafter\expandafter\expandafter\si@unt@unit% \fi \fi {##1}{#2}{#3}}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@gobblethree} % \LaTeX\ does not have a \cs{@gobblethree} macro, but one is needed. % \begin{macrocode} \long\def \si@gobblethree #1#2#3{} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@defprefix} % As with units, multiples are defined by an internal macro. %\cs{si@unt@defprefix}\marg{multiple}\marg{powers-ten}\marg{symbol}\\ % \begin{macrocode} \newcommand*{\si@unt@defprefix}[3]{% \si@log@debug{Declaring multiple \string#1 with \MessageBreak meaning \string#3}% \DeclareRobustCommand{#1}{% \ifsi@unt@littest \expandafter\si@gobblethree \else \ifsi@unt@litout \expandafter\expandafter\expandafter\@gobbletwo \else \expandafter\expandafter\expandafter\si@unt@prefix% \fi \fi {#1}{#2}{#3}}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@defpower} % The definition of powers is complicated by the need to handle both % those given before units (such as \cs{cubic}) and those given after % (\eg~\cs{cubed}). This means that an optional argument is % needed.\\ %\cs{si@unt@defpower}\oarg{post}\marg{power}\marg{num} % \begin{macrocode} \newcommand*{\si@unt@defpower}[3][]{% \si@log@debug{Declaring power \string#2 with \MessageBreak meaning \string#3}% % \end{macrocode} % Once again the optional argument is saved. % \begin{macrocode} \expandafter\expandafter\expandafter\edef\expandafter% \csname\expandafter\@gobble\string#2@opt@si\endcsname{#1}% \DeclareRobustCommand{#2}{% \ifsi@unt@littest \expandafter\@gobbletwo \else % \end{macrocode} % The literal output here does not need to gobble anything, but uses % \cs{textsuperscript} to get the correct effect. This will of % course give very odd results for prefix powers. % \begin{macrocode} \ifsi@unt@litout \expandafter\expandafter\expandafter\si@unt@litpower% \else \expandafter\expandafter\expandafter\si@unt@power% \fi \fi {#2}{#3}}} % \end{macrocode} %\end{macro} % %\begin{macro}{\si@unt@unithook} %\begin{macro}{\si@unt@unit} % The macro for units is actually a processor, rather than % typesetting anything, which is handled elsewhere. The first % argument to the macro is optional, but does not have square % brackets to keep things simple with gobbling.\\ %\cs{si@unt@unit}\marg{num}\marg{unit}\marg{symbol} % \begin{macrocode} \newcommand*{\si@unt@unithook}{} \newcommand*{\si@unt@unit}[3]{% % \end{macrocode} % When the count is minus one at the start of the processor, then the % unit is begin used on its own: initialisation occurs. % \begin{macrocode} \ifnum\si@unt@depthcnt=\m@ne\relax \expandafter\si@unt@init% \fi \advance\si@unt@depthcnt\@ne\relax \si@log@debug{Unit processing: level \the\si@unt@depthcnt, \MessageBreak unit \string#2}% \si@unt@firstorsecond{#1}{#2}% % \end{macrocode} % The core of the \cs{si@unt@unit} macro is testing if the symbol for % the unit is a literal value or another macro. Depending on the % result, the symbol is either used as a literal or executed. % \begin{macrocode} \si@unt@ifliteral{#3} {\si@unt@addtostack{unit}{#3}% \ifsi@unt@prepower \expandafter\si@unt@stkpower% \fi} {#3}% % \end{macrocode} % The counter is now stepped down, before checking if this is % the end of a compound unit. % \begin{macrocode} \advance\si@unt@depthcnt\m@ne\relax \ifnum\si@unt@depthcnt=\z@\relax \expandafter\si@unt@final% \fi} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@firstorsecond} % At this stage, the flag will be set for the first item to be % processed whichever route the unit has been called by.\\ %\cs{si@unt@firstorsecond}\marg{num}\marg{macro} % \begin{macrocode} \newcommand{\si@unt@firstorsecond}[2]{% \ifsi@unt@first \expandafter\si@unt@first% \else \expandafter\si@unt@second% \fi {#1}{#2}}% % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@first} % For the first unit in the input, some extra tasks are needed. % First, the optional argument for the unit macro needs to be % tested.\\ %\cs{si@unt@first}\marg{num}\marg{unit} % \begin{macrocode} \newcommand*{\si@unt@first}[2]{% \si@ifnotmtarg{#1} {\num{#1}}% \si@unt@unithook% % \end{macrocode} % To avoid filling up the macro list with useless values, the \eTeX\ % primitive \cs{ifcsname} is employed here (it also avoids complex % expansion issues). If some options exist, they are set. % \begin{macrocode} \ifcsname\expandafter\@gobble\string#2@opt@unt@si\endcsname \expandafter\si@unt@setopts% \else \expandafter\@gobble \fi {#2}% \si@unt@addvaluesep% \si@unt@firstfalse} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@setopts} %\begin{macro}{\si@unt@setSIopts} % A rather long set of \cs{expandafter} commands to get the options % to set safely.\\ %\cs{si@unt@setopts}\marg{unit} % \begin{macrocode} \newcommand*{\si@unt@setopts}[1]{% \expandafter\expandafter\expandafter\expandafter\expandafter% \expandafter\expandafter\si@temptoks\expandafter\expandafter% \expandafter\expandafter\expandafter\expandafter\expandafter{% \expandafter\csname\expandafter\@gobble\string#1@opt@unt@si% \endcsname}% \expandafter\sisetup\expandafter{\the\si@temptoks}% \si@log@debug{Applying options ``\the\si@temptoks'' for\MessageBreak unit \string#1}% % \end{macrocode} % The user options are reloaded, if defined, to ensure that they % still work as expected. % \begin{macrocode} \@ifundefined{si@unt@SIopts}{} {\ifx\@empty\si@unt@SIopts\@empty\else \expandafter\expandafter\si@unt@setSIopts% \fi}} \newcommand*{\si@unt@setSIopts}{% \expandafter\si@temptoks\expandafter{\si@unt@SIopts}% \expandafter\sisetup\expandafter{\the\si@temptoks}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@second} %\begin{macro}{\si@unt@third} % For everything apart from the first item to be processed, spacing % may need to be added to separated different units. The macro is % divided into two, so that everything except the space can be added % in finalisation.\\ %\cs{si@unt@second}\marg{num}\marg{unit} % \begin{macrocode} \newcommand{\si@unt@second}[2]{% \si@ifnotmtarg{#1} {\si@log@warn{Optional argument to unit macro\MessageBreak allowed only for outer unit}}% \si@unt@third% \si@unt@addtostack{space}{\ensuremath{\si@unitsep}}} \newcommand*{\si@unt@third}{% \ifsi@unt@prepower\else \expandafter\si@unt@stkpower% \fi % \end{macrocode} %\begin{macro}{\si@tempa} % A check is made to avoid adding $-1$ to prefixes. If \opt{frac} is % active, then the |b| stack will be in use, otherwise it will be % |a|. % \begin{macrocode} \def\si@tempa{prefix}% \expandafter\ifx\csname si@unt@lastadd\si@unt@checkstack% \endcsname\si@tempa\else \expandafter\si@unt@spacecheck% \fi \ifsi@unt@per \expandafter\si@unt@perseentrue \fi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@spacecheck} % A check to prevent adding $-1$ at the very beginning of the unit, where % there is a space on the stack. % \begin{macrocode} \newcommand*{\si@unt@spacecheck}{% \def\si@tempa{space}% \expandafter\ifx\csname si@unt@lastadd\si@unt@checkstack% \endcsname\si@tempa\else \expandafter\si@unt@reciptest% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@prefix} % Actual output of the prefixes.\\ %\cs{si@unt@prefix}\marg{multiple}\marg{powers-ten}\marg{symbol} % \begin{macrocode} \newcommand*{\si@unt@prefix}[3]{% \si@unt@firstorsecond{}{#1}% \ifsi@prefixnum \expandafter\si@unt@countprefix% \else \expandafter\si@unt@addprefix% \fi {#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@addprefix} % To add the prefix, a little translation is needed.\\ %\cs{si@unt@countprefix}\marg{gobble}\marg{symbol} % \begin{macrocode} \newcommand*{\si@unt@addprefix}[2]{\si@unt@addtostack{prefix}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@prefixcnt} %\begin{macro}{\si@unt@countprefix} %\begin{macro}{\si@unt@invprefix} % On the other hand, to count the prefix numeral, the symbol is % thrown away. %\cs{si@unt@countprefix}\marg{powers-ten}\marg{gobble} % \begin{macrocode} \newcount\si@unt@prefixcnt \newcommand*{\si@unt@countprefix}[2]{% \si@tempcnta#1\relax \ifsi@unt@per \si@unt@invprefix% \fi \advance\si@unt@prefixcnt\si@tempcnta\relax} \newcommand*{\si@unt@invprefix}{% \si@tempcntb\si@tempcnta\relax \si@tempcnta -\si@tempcntb\relax} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@litpower} % For literal power output, the number can't simply be dumped, so % a macro is needed.\\ %\cs{si@unt@litpower}\marg{gobble}\marg{num} % \begin{macrocode} \newcommand*{\si@unt@litpower}[2]{\textsuperscript{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@unt@prepower} %\begin{macro}{\si@unt@power} % The handling of powers starts by checking if the number needs to be % reversed. %\cs{si@unt@power}\marg{power}\marg{num} % \begin{macrocode} \newif\ifsi@unt@prepower \newcommand*{\si@unt@power}[2]{% \si@unt@powerdim #2 pt\relax \ifsi@frac\else \ifsi@unt@per \expandafter\expandafter\expandafter\si@unt@invpower% \fi \fi \def\si@tempa{post}% \si@unt@prepowertrue \expandafter\expandafter\expandafter\ifx\expandafter% \csname\expandafter\@gobble\string#1@opt@si\endcsname\si@tempa \expandafter\si@unt@stackpower% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@powerdim} % To do sign-inversion on the power, a dimension is used (this allows % non-integer values to be handled). % \begin{macrocode} \newdimen\si@unt@powerdim % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@stackpower} %\begin{macro}{\si@unt@stkpower} %\begin{macro}{\si@unt@stkpwr} % Adding powers to the stack should also clear the power list. If % the number is already zero, then of course nothing happens. % \begin{macrocode} \newcommand*{\si@unt@stackpower}{% \si@unt@prepowerfalse % \end{macrocode} % A trap is used for $-1$ added to the denominator of a fraction. % \begin{macrocode} \si@unt@stkpower% \si@unt@perfalse \si@unt@perseenfalse} % \end{macrocode} % The \cs{si@unt@stkpower} macro needs to be called from a few % places, so is spun out from the above. % \begin{macrocode} \newcommand*{\si@unt@stkpower}{% \ifdim\si@unt@powerdim=\m@ne pt\relax \ifsi@frac\else \expandafter\expandafter\expandafter\si@unt@stkpwr% \fi \else \expandafter\si@unt@stkpwr% \fi} % \end{macrocode} % Finally, the actual adding (set up to avoid problems with the % \cs{if} above). % \begin{macrocode} \newcommand*{\si@unt@stkpwr}{% \ifdim\si@unt@powerdim=\z@\relax\else \edef\si@tempa{unit}% \expandafter\ifx\csname si@unt@lastadd\si@unt@checkstack% \endcsname\si@tempa \si@unt@addtostack{power}{^{\num{\strip@pt\si@unt@powerdim}}}% \fi \fi \si@unt@powerdim\z@\relax} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@invpower} % A macro to change the sign of the current power. % \begin{macrocode} \newcommand*{\si@unt@invpower}{% \si@tempdima\si@unt@powerdim\relax \si@unt@powerdim -\si@tempdima\relax % \end{macrocode} % The power might end up as ``1'', which is not wanted. So it is % chucked away. % \begin{macrocode} \ifdim\si@unt@powerdim=\p@\relax \si@unt@powerdim\z@\relax \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\ifsi@unt@per} %\begin{macro}{\ifsi@unt@perseen} %\begin{macro}{\per} %\begin{macro}{\si@per} % The \cs{per} macro sets the correct flags; almost everything else % is done elsewhere. There is always the case of two \cs{per} % instructions; so the flag is flipped rather than set arbitrarily. % The second flag is needed so that \cs{per} can give powers of $-1$ % properly. % \begin{macrocode} \newif\ifsi@unt@per \newif\ifsi@unt@perseen \DeclareRobustCommand*{\per}{\si@per} \newcommand*{\si@per}{% \si@unt@firstorsecond{}{\per}% \ifsi@unt@per \expandafter\si@unt@perfalse \else \expandafter\si@unt@pertrue \fi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@reciptest} %\begin{macro}{\si@unt@recip} % A test is needed for adding $-1$ when needed. The second macro is % fired only if the power should be reciprocal. % \begin{macrocode} \newcommand*{\si@unt@reciptest}{% \ifsi@unt@per \ifsi@unt@perseen \expandafter\expandafter\expandafter\si@unt@recip% \fi \fi} \newcommand*{\si@unt@recip}{% \si@unt@powerdim\m@ne pt\relax \si@unt@stackpower} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@lastadda} %\begin{macro}{\si@unt@lastaddb} %\begin{macro}{\si@unt@addtostack} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % Items cannot be added directly to the stacks (except the spacing % stack, a) as the fractional handling may need to add the item to % either storage area. By indicating the type of data to be added to % the stack, problems can be avoided.\\ %\cs{si@unt@addtostack}\marg{type}\marg{token} % \begin{macrocode} \newcommand*{\si@unt@lastadda}{} \newcommand*{\si@unt@lastaddb}{} \newcommand*{\si@unt@addtostack}[2]{% \edef\si@tempa{#1}% % \end{macrocode} % Two consecutive items cannot be of the same type; there must be spaces % between units, units between prefixes, \etc. % \begin{macrocode} \expandafter\ifx\csname si@unt@lastadd\si@unt@checkstack\endcsname% \si@tempa \expandafter\@gobbletwo \else \expandafter\si@unt@preplussp% \fi {#1}{#2}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@preplussp} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % The space added after a prefix needs to be ignored. %\cs{si@unt@prespace}\marg{type}\marg{stack}\marg{token}\marg{gobble} % \begin{macrocode} \newcommand*{\si@unt@preplussp}[2]{% \def\si@tempa{prefix+space}% \edef\si@tempb{\csname si@unt@lastadd\si@unt@checkstack% \endcsname+#1}% \ifx\si@tempa\si@tempb \expandafter\@gobbletwo \else \expandafter\si@unt@stack% \fi {#1}{#2}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@stack} % The macro for actually doing the stacking up.\\ %\cs{si@unt@stack}\marg{type}\marg{tokens} % \begin{macrocode} \newcommand*{\si@unt@stack}[2]{% \expandafter\edef\csname si@unt@lastadd\si@unt@checkstack% \endcsname{#1}% % \end{macrocode} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % A count is kept of the number of \emph{units} added to each stack. % \begin{macrocode} \edef\si@tempa{#1}% \def\si@tempb{unit}% \ifx\si@tempa\si@tempb \expandafter\si@unt@inccnt% \fi % \end{macrocode} % If a space is added, it is actually held until the next add. % \begin{macrocode} \def\si@tempb{space}% \ifx\si@tempa\si@tempb \expandafter\si@unt@holdspace% \else \expandafter\si@unt@addstack% \fi {#2}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@inccnt} % The appropriate counter is added to. % \begin{macrocode} \newcommand*{\si@unt@inccnt}{% \expandafter\advance\csname si@unt@unitcnt\si@unt@checkstack% \endcsname\@ne\relax} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@holdspace} %\begin{macro}{\si@unt@addstack} %\begin{macro}{\si@unt@holdstacka} %\begin{macro}{\si@unt@holdstackb} % Depending on the nature of the addition, it is either held or added % to the stack.\\ %\cs{si@unt@holdspace}\marg{tokens}\\ %\cs{si@unt@addstack}\marg{tokens}\\ % \begin{macrocode} \newcommand*{\si@unt@holdstacka}{} \newcommand*{\si@unt@holdstackb}{} \newcommand*{\si@unt@holdspace}[1]{% \expandafter\protected@edef\csname si@unt@holdstack% \si@unt@checkstack\endcsname{#1}} \newcommand*{\si@unt@addstack}[1]{% \expandafter\protected@edef\csname si@unt@stack% \si@unt@checkstack\endcsname% {\csname si@unt@stack\si@unt@checkstack\endcsname% \csname si@unt@holdstack\si@unt@checkstack\endcsname#1}% \expandafter\renewcommand\expandafter*\expandafter{% \csname si@unt@holdstack\si@unt@checkstack\endcsname}{}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@stackout} % The stack contents are actually typeset here. First the spacing % between units and values is added. % \begin{macrocode} \newcommand*{\si@unt@stackout}{% \ifsi@frac \expandafter\si@unt@fracout% \else \expandafter\si@unt@normout% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@checkstack} % Which stack is in use needs to be tested. % \begin{macrocode} \newcommand*{\si@unt@checkstack}{% \ifsi@frac \ifsi@unt@per \expandafter\expandafter\expandafter b% \else \expandafter\expandafter\expandafter a% \fi \else \expandafter a% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@spaceout} % The space before a unit might not be needed, so it crops up a few % times in the output routine. % \begin{macrocode} \newcommand*{\si@unt@spaceout}{% \ensuremath{\si@unt@spstack}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@prefixout} % If the prefix counter is not zero, then there is something to % typeset. % \begin{macrocode} \newcommand*{\si@unt@prefixout}{% \ifnum\si@unt@prefixcnt=\z@\relax\else \ifsi@unt@num \si@out@text{\ensuremath{{}\si@prefixproduct{}}}% \fi \let\si@exppower\si@prefixpower \num{e\the\si@unt@prefixcnt}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@normout} % The normal output mode is set up here; nothing much needs to be % done as there is no need for complex checks. % \begin{macrocode} \newcommand*{\si@unt@normout}{% \si@unt@prefixout% \si@unt@spaceout% \expandafter\si@unt@out\expandafter{\si@unt@stacka}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@fracout} % For fractions, some checks are needed. % \begin{macrocode} \newcommand*{\si@unt@fracout}{% \si@unt@notambig% \ifx\@empty\si@unt@stacka\@empty \ifx\@empty\si@unt@stackb\@empty \ifsi@unt@litout\else \si@log@err{Empty fractional unit}{The unit argument\MessageBreak given does not contain any symbols}% \fi \else % \end{macrocode} % With an empty numerator, no space is added % \begin{macrocode} \ifsi@slash \si@unt@prefixout% \si@frac{}{\si@unt@stackb}% \else \si@unt@prefixout% \si@unt@spaceout% \si@frac{1}{\si@unt@stackb}% \fi \fi \else % \end{macrocode} % If the denominator is empty, then the usual output system can be % used. % \begin{macrocode} \ifx\@empty\si@unt@stackb\@empty \si@unt@normout% \else \si@unt@prefixout% \si@unt@spaceout% \si@frac{\si@unt@stacka}{\si@unt@stackb}% \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@notambig} %\begin{macro}{\si@unt@notabg} % A trap is set for adding brackets to units using a slash, when more % than one unit is in the denominator. % \begin{macrocode} \newcommand*{\si@unt@notambig}{% \ifnum\si@unt@unitcntb>\@ne\relax \ifsi@slash \expandafter\expandafter\expandafter\si@unt@notabg% \fi \fi} \newcommand*{\si@unt@notabg}{% \protected@edef\si@unt@stackb{\si@denlbrac\si@unt@stackb% \si@denrbrac}} % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\si@unt@out} % The final part of the units system is the output routine. This has % to cope with units not only as macros but also as direct input % (\sistyle-type input). Non-Latin characters are also handled % cleanly. As usual, \cs{scantokens} is used to make life easier.\\ %\cs{si@unt@out}\marg{unit} % \begin{macrocode} \begingroup \catcode`\~=\active \catcode`\.=\active \gdef\si@unt@out#1{% \begingroup \si@unt@nonlatin% \makeatletter% \catcode`\~=\active \catcode`\.=\active \def~{\ensuremath{\si@unitspace}}% \def.{\ensuremath{\si@unitsep}}% \scantokens{\si@out@text{#1}\@empty}% \endgroup} \endgroup % \end{macrocode} %\end{macro} %\begin{macro}{\si@unt@nonlatin} % To handle non-Latin symbols in the input, a single macro is % provided. Initially, it does nothing % \begin{macrocode} \newcommand*{\si@unt@nonlatin}{\relax} % \end{macrocode} % The meaning of different characters depends on the encoding used. % Thus a test is made for the presence of a suitable package % \emph{and} the encoding in use. The various characters can then be % handled. %\begin{macro}{\si@tempa} % \begin{macrocode} \AtBeginDocument{% \@ifpackageloaded{inputenc} {\def\si@tempa{latin1}% \ifx\inputencodingname\si@tempa % \end{macrocode} % The degree symbol is character 176 and the micro symbol is % character 181 in latin1. % \begin{macrocode} \si@unt@sym{176}{\si@sym@degree}% \si@unt@sym{181}{\si@sym@mu}% \si@unt@sym{229}{\si@sym@ringA}% \fi} % \end{macrocode} % No \pkg{inputenc} available. % \begin{macrocode} {}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@unt@sym} % A macro for declaring symbols: a copy of \cs{DeclareInputMath} from % \pkg{inputenc}.\\ %\cs{si@unt@sym}\marg{charcode} % \begin{macrocode} \newcommand*{\si@unt@sym}[1]{% \bgroup \uccode`\~#1% \uppercase{% \egroup \def~}} % \end{macrocode} %\end{macro} % %\begin{macro}{\kilogram} %\begin{macro}{\metre} %\begin{macro}{\mole} %\begin{macro}{\kelvin} %\begin{macro}{\candela} %\begin{macro}{\second} %\begin{macro}{\ampere} % With the system set up, the basic unit macros are implemented. The % only units defined whatever options are given are the base SI % units. % \begin{macrocode} \newunit{\kilogram}{kg} \newunit{\metre}{m} \newunit{\mole}{mol} \newunit{\second}{s} \newunit{\ampere}{A} \newunit{\kelvin}{K} \newunit{\candela}{cd} % \end{macrocode} %\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} % Unlike multiples (which can be skipped if needed), the basic powers % are also always defined. % \begin{macrocode} \newpower{\Square}{2} \newpower[post]{\squared}{2} \newpower{\cubic}{3} \newpower[post]{\cubed}{3} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\tothe} %\begin{macro}{\tothe@opt@si} % A macro for arbitrary powers, which comes after the unit and so % needs to be marked as such.\\ %\cs{tothe}\marg{num} % \begin{macrocode} \newcommand*{\tothe}[1]{% \ifsi@unt@littest \expandafter\@gobbletwo \else \ifsi@unt@litout \expandafter\expandafter\expandafter\si@unt@litpower% \else \expandafter\expandafter\expandafter\si@unt@power% \fi \fi {\tothe}{#1}} \newcommand*{\tothe@opt@si}{post} % \end{macrocode} %\end{macro} %\end{macro} % %\subsection{Locales} %\begin{macro}{\si@loc@load} %\begin{macro}{\si@loc@sisetup} % When loading a locale, the setup is saved rather than applied. % Anything other than simple settings should be inside % \cs{addtolocale}, which is already defined.\\ %\cs{si@loc@load}\marg{locale} % \begin{macrocode} \newcommand*{\si@loc@load}[1]{% \let\si@loc@sisetup\sisetup \renewcommand*{\sisetup}[1]{% \expandafter\def\csname si@loc@#1\endcsname{##1}} \si@loadfile{#1}% \let\sisetup\si@loc@sisetup} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@loc@set} % Setting the locale transfers the settings to \cs{sisetup}, and runs % any extra macros.\\ %\cs{si@loc@set}\marg{locale} % \begin{macrocode} \newcommand*{\si@loc@set}[1]{% \ifcsname si@loc@#1\endcsname \si@log@inf{Setting locale to `#1'}% \expandafter\expandafter\expandafter\expandafter\expandafter% \expandafter\expandafter\si@temptoks\expandafter\expandafter% \expandafter\expandafter\expandafter\expandafter\expandafter{% \expandafter\csname si@loc@#1\endcsname}% \expandafter\sisetup\expandafter{\the\si@temptoks}% \ifcsname si@loc@#1@extra\endcsname \csname si@loc@#1@extra\endcsname% \fi \else \ifcsname si@loc@#1@extra\endcsname \si@log@inf{Setting locale to `#1'}% \csname si@loc@#1@extra\endcsname% \else \si@log@warn{Unknown locale `#1'}% \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\addtolocale} % Arbitrary macros may need to be added to the locale.\\ %\cs{addtolocale}\marg{locale}\marg{commands} % \begin{macrocode} \newcommand*{\addtolocale}[2]{\si@addtocsname{si@loc@#1@extra}{#2}} % \end{macrocode} %\end{macro} % %\subsection{Output routine} %\begin{macro}{\si@out@text} % With all of the setup done, the text can finally be typeset. This % is done inside a \cs{text} block, which takes care of % \cs{ensuremath}, \etc. First of all, the various catcode settings % needed to get maths-in-text mode are made. \cs{makeatletter} is % needed so that \cs{scantokens} still allows internal macros to % work.\\ %\cs{si@out@text}\marg{text} % \begin{macrocode} \begingroup \catcode`\^=\active\relax \catcode`\-=\active\relax \gdef\si@out@text#1{% \begingroup \catcode`\^=\active\relax% \makeatletter% % \end{macrocode} % The various font families can now be set up. First a check is made % in case there are nested calls to \cs{si@out@text}. % \begin{macrocode} \ifsi@fam@set\else \expandafter\si@fam@set% \fi \text{\si@fam@italic\si@fam@bold\si@fam@text% % \end{macrocode} % In text mode, |^| will execute \cs{textsuperscript}, whereas in % maths mode it will be converted to \cs{sp}, which the kernel % defines as |^| with catcode 7. \cs{scantokens} is used to set the % catcodes here, plus any others that have been set by other pars of % the package. % \begin{macrocode} \ifsi@textmode \let^\textsuperscript \catcode`\-=\active\relax% \let-\si@out@minus % \end{macrocode} % The \cs{@empty} is needed here to mop up any extra space. % \begin{macrocode} \scantokens{#1\@empty}% \else \let^\sp \let\textsuperscript\sp $\si@fam@maths{\scantokens{#1}}$% \fi}% % \end{macrocode} % Everything is done; a bit of tidying up is needed. % \begin{macrocode} \endgroup \check@mathfonts} \endgroup % \end{macrocode} %\end{macro} %\begin{macro}{\si@out@minus} % An active minus sign is needed. % \begin{macrocode} \newcommand*{\si@out@minus}{\ensuremath{-}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@out@num} % For numerical output, the default fonts are controlled slightly % differently to text output.\\ %\cs{si@out@num}\marg{num} % \begin{macrocode} \newcommand*{\si@out@num}[1]{% \begingroup \sisetup{% textdefault=\si@textnumdefault,% mathdefault=\si@mathnumdefault}% \si@out@text{#1}% \endgroup} % \end{macrocode} %\end{macro} % %\subsection{Finalisation} % With the \currpkg kernel macros defined, the package can now run % through finalisation. First, the default key values are set. The % user options are then processed. % \begin{macrocode} \sisetup{ unitsep=thin, valuesep=thin, decimalsign=fullstop, digitsep=thin, obeybold=false, inlinebold=text, obeyitalic=false, sign=plus, addsign=none, obeymode=false, mode=maths, padangle=small, padnumber=lead, sepfour=false, tabformat=-1, xspace=false, per=reciprocal, slash=slash, mathsdefault=\si@mathsrm, mathsrm=mathrm, mathssf=mathsf, mathstt=mathtt, textdefault=\si@textrm, textrm=rmfamily, textsf=sffamily, texttt=ttfamily, mathsnumdefault=\si@mathsrm, textnumdefault=\si@textrm, numlist=0123456789, numdecimal={.,}, numexp=eEdD, numgobble={}, numsign=+-\pm\mp, numextra=(), redefsymbols=true, load=default, noload={}, eVcorra={0.3ex}, eVcorrb={0ex}, denlbrac=(, denrbrac=), astroang=false, loadlocales={}, loctolang={}, prefix=symbol, prefixpower=ten, prefixproduct=times} \ProcessOptionsX[si] % \end{macrocode} %\begin{macro}{\si@extension} %\begin{macro}{\si@fileprefix} % To keep the code easy to maintain, the reusable filename components % are macros rather than literals. % \begin{macrocode} \newcommand*{\si@extension}{cfg} \newcommand*{\si@fileprefix}{si-} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@ifloaded} % A bit of borrowing from the \LaTeX\ kernel.\\ %\cs{si@ifloaded}\marg{package} % \begin{macrocode} \newcommand*{\si@ifloaded}[1]{% \@ifl@aded\si@extension{\si@fileprefix#1}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@loadfile} % Loading configuration files is handled here.\\ %\cs{si@loadfile}\marg{file} % \begin{macrocode} \newcommand*{\si@loadfile}[1]{% \si@ifloaded{#1}{} {\InputIfFileExists{\si@fileprefix#1.\si@extension} {} {\si@log@err{Failed to load file \si@fileprefix#1.\si@extension} {The configuration file requested could not be found}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@requirecfgs} %\changes{v0.6a}{2008/02/20}{Changed temporary macro used to fix % bug with \pkg{memoir} and \textsc{koma}-script} %\begin{macro}{\si@tempb} % The configuration files depend on each other.\\ %\cs{si@requirecfgs}\marg{cfg-file} % \begin{macrocode} \newcommand*{\si@requirecfgs}[1]{% \@for\si@tempb:=#1\do{\si@loadfile{\si@tempb}}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\si@loademfile} % For emulation files, an additional check is made.\\ %\cs{si@loademfile}\marg{file} % \begin{macrocode} \newcommand*{\si@loademfile}[1]{% \@ifpackageloaded{#1} {\si@log@err{Emulation clash for package `#1'} {You have asked for emulation of package `#1'\MessageBreak (perhaps by giving si a back-compatibility option)\MessageBreak but the package is already loaded!}} {\si@loadfile{#1}}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@emclash} % A macro for emulation clashes. % \begin{macrocode} \newcommand*{\si@emclash}[2]{% \si@log@err{Emulation clash: `#1' and `#2'} {You have asked for emulation of package `#1'\MessageBreak but have already loaded emulation of `#2'}} % \end{macrocode} %\end{macro} %\begin{macro}{\si@tempa} % A check is now made so that emulation takes place one file at a % time, and that each file is loaded only once. % \begin{macrocode} \ifx\@empty\si@emulate\@empty\else \@for\si@tempa:=\si@emulate\do{% \si@loademfile{\si@tempa}} \fi % \end{macrocode} %\end{macro} %\begin{macro}{\si@expanddefault} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} %\begin{macro}{\si@tempc} % For turning the list of default choices into a loadable list. % \begin{macrocode} \newcommand*{\si@expanddefault}[2]{% \expandafter\ifx\expandafter\@empty\csname si@#1\endcsname\@empty \else \def\si@tempb{default} \def\si@tempc{} \expandafter\@for\expandafter\si@tempa\expandafter:\expandafter =\csname si@#1\endcsname\do{% \ifx\si@tempa\si@tempb \si@addtolist{\si@tempc}{#2} \else \si@addtolist{\si@tempc}{\si@tempa} \fi} \expandafter\edef\csname si@#1\endcsname{\si@tempc} \expandafter\si@addtolist\expandafter{\csname si@no#1\endcsname} {default} \def\si@tempc{} \expandafter\@for\expandafter\si@tempa\expandafter:\expandafter =\csname si@#1\endcsname\do{% \si@switchfalse \expandafter\@for\expandafter\si@tempb\expandafter:\expandafter =\csname si@no#1\endcsname\do{% \ifx\si@tempa\si@tempb \si@switchtrue \fi \ifsi@switch\else \si@addtolist{\si@tempc}{\si@tempa} \fi}} \@for\si@tempa:=\si@tempc\do{% \si@loadfile{\si@tempa}} \fi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % The configuration and abbreviation files are loaded. % \begin{macrocode} \si@expanddefault{load}{prefix,named,addn,prefixed,accepted,% physical,abbr} % \end{macrocode} %\begin{macro}{\si@tempa} %\begin{macro}{\si@tempb} % The locale files are loaded; here there is a need to check on both % \opt{loadlocales} and \opt{loctolang}. % \begin{macrocode} \ifx\@empty\si@loadlocales\@empty\else \@for\si@tempa:=\si@loadlocales\do{% \si@loc@load{\si@tempa}} \fi % \end{macrocode} % For \opt{loctolang}. % \begin{macrocode} \ifx\@empty\si@loctolang\@empty\else \def\si@tempa#1:#2\@nil{\si@loc@load{#1}} \@for\si@tempb:=\si@loctolang\do{% \expandafter\si@tempa\si@tempb:\@nil} \AtBeginDocument{% \@ifpackageloaded{babel} {\def\si@tempa#1:#2:#3\@nil{% \expandafter\addto\expandafter{\csname extras#2\endcsname}% {\si@loc@set{#1}}}% \@for\si@tempb:=\si@loctolang\do{% \expandafter\si@tempa\si@tempb::\@nil}} {\si@log@warn{babel not loaded - option\MessageBreak loctolang ignored}}} \fi % \end{macrocode} %\end{macro} %\end{macro} % The very last job is to load a local configuration file, if one % exists. % \begin{macrocode} \IfFileExists{si.cfg} {\si@log@inf{Local configuration file found}% \InputIfFileExists{si.cfg}{}{}} {} % \end{macrocode} % %\iffalse % %\fi % %\section{Loadable modules} % To keep the package relatively clear, and to make maintenance % easier, the only units defined in the package itself are the base % units. Everything else is a loadable module (similar to the % approach in \unitsdef). % %\iffalse %<*prefix> %\fi %\subsection{Multiple prefixes} %\begin{macro}{\yocto} %\begin{macro}{\zepto} %\begin{macro}{\atto} %\begin{macro}{\femto} %\begin{macro}{\pico} %\begin{macro}{\nano} %\begin{macro}{\micro} %\begin{macro}{\Micro} %\begin{macro}{\milli} %\begin{macro}{\centi} %\begin{macro}{\deci} % The various SI multiple prefixes are defined here. First the small % powers. % \begin{macrocode} \ProvidesFile{si-prefix.cfg} [2008/02/20 v.06a SI Multiple prefixes] \newprefix{\yocto}{-24}{y} \newprefix{\zepto}{-21}{z} \newprefix{\atto}{-18}{a} \newprefix{\femto}{-15}{f} \newprefix{\pico}{-12}{p} \newprefix{\nano}{-9}{n} % \end{macrocode} % Some testing is needed for \unitsdef compatibility. % \begin{macrocode} \ifsi@old@OHM \newprefix{\Micro}{-6}{\si@sym@mu} \else \ifsi@gensymb\else \newprefix{\micro}{-6}{\si@sym@mu} \fi \fi \newprefix{\milli}{-3}{m} \newprefix{\centi}{-2}{c} \newprefix{\deci}{-1}{d} % \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}{\deca} %\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} \newprefix{\deca}{1}{da} \newprefix{\hecto}{2}{h} \newprefix{\kilo}{3}{k} \newprefix{\mega}{6}{M} \newprefix{\giga}{9}{G} \newprefix{\tera}{12}{T} \newprefix{\peta}{15}{P} \newprefix{\exa}{18}{E} \newprefix{\zetta}{21}{Z} \newprefix{\yotta}{24}{Y} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\deka} % Apparently, ``deka'' is common in the US for deca. % \begin{macrocode} \newprefix{\deka}{1}{da} % \end{macrocode} %\end{macro} %\begin{macro}{\gram} %\begin{macro}{\kilogram} % As the base unit of mass is the kilogram, rather than the gram, a % bit of extra work is needed; by default the package only defines % \cs{kilogram}, but with the prefixes available, this is altered to % be \cs{kilo}\cs{gram}. For that, the \cs{gram} must be defined first. % \begin{macrocode} \newunit{\gram}{g} \renewunit{\kilogram}{\kilo\gram} % \end{macrocode} %\end{macro} %\end{macro} %\iffalse % %<*named> %\fi %\subsection{Derived units with specific names} %\begin{macro}{\becquerel} %\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} % Derived units with specific names and symbols are defined. Litre % is an awkward one, but here the UK standard is used. % \begin{macrocode} \ProvidesFile{si-named.cfg} [2008/02/20 v.06a SI Named units] \newunit{\becquerel}{Bq} \newunit{\coulomb}{C} \newunit{\farad}{F} \newunit{\Gray}{Gy} \newunit{\hertz}{Hz} \newunit{\henry}{H} \newunit{\joule}{J} \newunit{\katal}{kat} \newunit{\lumen}{lm} \newunit{\lux}{lx} \newunit{\newton}{N} % \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}{\ohm} %\begin{macro}{\Ohm} %\begin{macro}{\pascal} %\begin{macro}{\siemens} %\begin{macro}{\sievert} %\begin{macro}{\tesla} %\begin{macro}{\volt} %\begin{macro}{\watt} %\begin{macro}{\weber} % Some testing is needed for \unitsdef compatibility. % \begin{macrocode} \ifsi@old@OHM \newunit{\Ohm}{\si@sym@Omega} \else \ifsi@gensymb\else % \end{macrocode} % To be on the safe side, use \cs{provideunit}. % \begin{macrocode} \provideunit{\ohm}{\si@sym@Omega} \fi \fi \newunit{\pascal}{Pa} \newunit{\siemens}{S} \newunit{\sievert}{Sv} \newunit{\tesla}{T} \newunit{\volt}{V} \newunit{\watt}{W} \newunit{\weber}{Wb} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\celsius} %\begin{macro}{\Celsius} % The degree celsius is a named unit. % \begin{macrocode} \ifsi@old@OHM \newunit{\Celsius}{\si@sym@celsius} \else \ifsi@gensymb\else \newunit{\celsius}{\si@sym@celsius} \fi \fi % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\radian} %\begin{macro}{\steradian} % The radian and steradian are officially derived units. % \begin{macrocode} \newunit{\radian}{rad} \newunit{\steradian}{sr} % \end{macrocode} %\end{macro} %\end{macro} %\iffalse % %<*prefixed> %\fi %\subsection{Units with prefixes} % As in \unitsdef, some commonly used prefixed units are set up. % This requires \file{si-prefix.cfg} and \file{si-named.cfg}. % \begin{macrocode} \ProvidesFile{si-prefixed.cfg} [2008/02/20 v.06a SI Prefixed units] \si@requirecfgs{prefix,named,accepted,physical} % \end{macrocode} %\begin{macro}{\picometre} %\begin{macro}{\nanometre} %\begin{macro}{\micrometre} %\begin{macro}{\millimetre} %\begin{macro}{\centimetre} %\begin{macro}{\decimetre} %\begin{macro}{\kilometre} % Extra distances. % \begin{macrocode} \newunit{\picometre}{\pico\metre} \newunit{\nanometre}{\nano\metre} \newunit{\micrometre}{\micro\metre} \newunit{\millimetre}{\milli\metre} \newunit{\centimetre}{\centi\metre} \newunit{\decimetre}{\deci\metre} \newunit{\kilometre}{\kilo\metre} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\femtogram} %\begin{macro}{\picogram} %\begin{macro}{\nanogram} %\begin{macro}{\microgram} %\begin{macro}{\milligram} % Extra masses. % \begin{macrocode} \newunit{\femtogram}{\femto\gram} \newunit{\picogram}{\pico\gram} \newunit{\nanogram}{\nano\gram} \newunit{\microgram}{\micro\gram} \newunit{\milligram}{\milli\gram} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\femtomole} %\begin{macro}{\picomole} %\begin{macro}{\nanomole} %\begin{macro}{\micromole} %\begin{macro}{\millimole} % Now some moles. % \begin{macrocode} \newunit{\femtomole}{\femto\mole} \newunit{\picomole}{\pico\mole} \newunit{\nanomole}{\nano\mole} \newunit{\micromole}{\micro\mole} \newunit{\millimole}{\milli\mole} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\attosecond} %\begin{macro}{\femtosecond} %\begin{macro}{\picosecond} %\begin{macro}{\nanosecond} %\begin{macro}{\microsecond} %\begin{macro}{\millisecond} % Prefixed seconds. % \begin{macrocode} \newunit{\attosecond}{\atto\second} \newunit{\femtosecond}{\femto\second} \newunit{\picosecond}{\pico\second} \newunit{\nanosecond}{\nano\second} \newunit{\microsecond}{\micro\second} \newunit{\millisecond}{\milli\second} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\picoampere} %\begin{macro}{\nanoampere} %\begin{macro}{\microampere} %\begin{macro}{\milliampere} %\begin{macro}{\kiloampere} % The last prefixed base units are amperes. % \begin{macrocode} \newunit{\picoampere}{\pico\ampere} \newunit{\nanoampere}{\nano\ampere} \newunit{\microampere}{\micro\ampere} \newunit{\milliampere}{\milli\ampere} \newunit{\kiloampere}{\kilo\ampere} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\millivolt} %\begin{macro}{\kilovolt} %\begin{macro}{\milliwatt} %\begin{macro}{\kilowatt} %\begin{macro}{\megawatt} %\begin{macro}{\femtofarad} %\begin{macro}{\picofarad} %\begin{macro}{\nanofarad} %\begin{macro}{\microfarad} %\begin{macro}{\millifarad} %\begin{macro}{\millisiemens} % More electricity-related units. % \begin{macrocode} \newunit{\millivolt}{\milli\volt} \newunit{\kilovolt}{\nano\volt} \newunit{\milliwatt}{\milli\watt} \newunit{\kilowatt}{\kilo\watt} \newunit{\megawatt}{\mega\watt} \newunit{\femtofarad}{\femto\farad} \newunit{\picofarad}{\pico\farad} \newunit{\nanofarad}{\nano\farad} \newunit{\microfarad}{\micro\farad} \newunit{\millifarad}{\milli\farad} \newunit{\millisiemens}{\milli\siemens} % \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}{\kiloohm} %\begin{macro}{\megaohm} %\begin{macro}{\gigaohm} % For resistance, checks are needed again for the definition of % \cs{ohm}. % \begin{macrocode} \ifsi@old@OHM \newunit{\kiloohm}{\kilo\Ohm} \newunit{\megaohm}{\mega\Ohm} \newunit{\gigaohm}{\giga\Ohm} \else \ifsi@gensymb\else \newunit{\kiloohm}{\kilo\ohm} \newunit{\megaohm}{\mega\ohm} \newunit{\gigaohm}{\giga\ohm} \fi \fi % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\microlitre} %\begin{macro}{\millilitre} %\begin{macro}{\cubicmetre} %\begin{macro}{\cubiccentimetre} %\begin{macro}{\centimetrecubed} %\begin{macro}{\cubicmicrometre} %\begin{macro}{\cubicmillimetre} %\begin{macro}{\cubicdecimetre} % Volumes (unlike \unitsdef, with litre and metre spelled % correctly). Only \cs{millilitre} and \cs{microlitre} are defined % as they are the two officially-sanctioned prefixes for the litre. % \begin{macrocode} \newunit{\microlitre}{\micro\litre} \newunit{\millilitre}{\milli\litre} \newunit{\cubicmetre}{\metre\cubed} \newunit{\cubiccentimetre}{\centi\metre\cubed} \newunit{\centimetrecubed}{\centi\metre\cubed} \newunit{\cubicmicrometre}{\micro\metre\cubed} \newunit{\cubicmillimetre}{\milli\metre\cubed} \newunit{\cubicdecimetre}{\cubic\deci\metre} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\squaremetre} %\begin{macro}{\squarecentimetre} %\begin{macro}{\squarekilometre} % Areas, with metre spelled corrected; \cs{are} and \cs{hectare} are % in the ``temporarily accepted'' file. % \begin{macrocode} \newunit{\squaremetre}{\Square\metre} \newunit{\squarecentimetre}{\Square\centi\metre} \newunit{\squarekilometre}{\Square\kilo\metre} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\millijoule} %\begin{macro}{\kilojoule} %\begin{macro}{\megajoule} %\begin{macro}{\millielectronvolt} %\begin{macro}{\kiloelectronvolt} %\begin{macro}{\megaelectronvolt} %\begin{macro}{\gigaelectronvolt} %\begin{macro}{\teraelectronvolt} % Some energy is needed by now! % \begin{macrocode} \newunit{\millijoule}{\milli\joule} \newunit{\kilojoule}{\kilo\joule} \newunit{\megajoule}{\mega\joule} \newunit{\millielectronvolt}{\milli\electronvolt} \newunit{\kiloelectronvolt}{\kilo\electronvolt} \newunit{\megaelectronvolt}{\mega\electronvolt} \newunit{\gigaelectronvolt}{\giga\electronvolt} \newunit{\teraelectronvolt}{\tera\electronvolt} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\millihertz} %\begin{macro}{\kilohertz} %\begin{macro}{\megahertz} %\begin{macro}{\gigahertz} %\begin{macro}{\terahertz} % Frequencies. % \begin{macrocode} \newunit{\millihertz}{\milli\hertz} \newunit{\kilohertz}{\kilo\hertz} \newunit{\megahertz}{\mega\hertz} \newunit{\gigahertz}{\giga\hertz} \newunit{\terahertz}{\tera\hertz} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\millinewton} %\begin{macro}{\kilonewton} %\begin{macro}{\hectopascal} %\begin{macro}{\megabecquerel} %\begin{macro}{\millisievert} % A few more from various areas. % \begin{macrocode} \newunit{\millinewton}{\milli\newton} \newunit{\kilonewton}{\kilo\newton} \newunit{\hectopascal}{\hecto\pascal} \newunit{\megabecquerel}{\mega\becquerel} \newunit{\millisievert}{\milli\sievert} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\iffalse % %<*abbr> %\fi %\subsection{Abbreviated units} %\begin{macro}{\pA} %\begin{macro}{\nA} %\begin{macro}{\micA} %\begin{macro}{\mA} %\begin{macro}{\kA} % The abbreviated units are sorted in one file. To allow % back-compatibility with \unitsdef, each one is inside an \cs{if} % block for the appropriate option. First currents. % \begin{macrocode} \ProvidesFile{si-abbr.cfg} [2008/02/20 v.06a Abbreviated units] \si@requirecfgs{prefix,named,accepted,physical} \newunit{\pA}{\pico\ampere} \newunit{\nA}{\nano\ampere} \newunit{\micA}{\micro\ampere} \newunit{\mA}{\milli\ampere} \newunit{\kA}{\kilo\ampere} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\Hz} %\begin{macro}{\mHz} %\begin{macro}{\kHz} %\begin{macro}{\MHz} %\begin{macro}{\GHz} %\begin{macro}{\THz} % Then frequencies. % \begin{macrocode} \newunit{\Hz}{\hertz} \newunit{\mHz}{\milli\hertz} \newunit{\kHz}{\kilo\hertz} \newunit{\MHz}{\mega\hertz} \newunit{\GHz}{\giga\hertz} \newunit{\THz}{\tera\hertz} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\fmol} %\begin{macro}{\pmol} %\begin{macro}{\nmol} %\begin{macro}{\micmol} %\begin{macro}{\mmol} % Amounts of substance. % \begin{macrocode} \newunit{\fmol}{\femto\mole} \newunit{\pmol}{\pico\mole} \newunit{\nmol}{\nano\mole} \newunit{\micmol}{\micro\mole} \newunit{\mmol}{\milli\mole} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\kV} %\begin{macro}{\mV} % Potentials. % \begin{macrocode} \newunit{\kV}{\kilo\volt} \newunit{\mV}{\milli\volt} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\ml} %\begin{macro}{\micl} %\begin{macro}{\cmc} %\begin{macro}{\dmc} % Volumes. % \begin{macrocode} \newunit{\ml}{\milli\litre} \newunit{\micl}{\micro\litre} \newunit{\cmc}{\centi\metre\cubed} \newunit{\dmc}{\deci\metre\cubed} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\kg} %\begin{macro}{\fg} %\begin{macro}{\pg} %\begin{macro}{\nanog} %\begin{macro}{\micg} %\begin{macro}{\mg} %\begin{macro}{\amu} % Masses. % \begin{macrocode} \newunit{\kg}{\kilo\gram} % \end{macrocode} % There is a name clash with \pkg{babel} here in French; hopefully % there will not be too many complaints. % \begin{macrocode} \provideunit{\fg}{\femto\gram} \newunit{\pg}{\pico\gram} \newunit{\nanog}{\nano\gram} \newunit{\micg}{\micro\gram} \newunit{\mg}{\milli\gram} \newunit{\amu}{\atomicmass} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\kJ} %\begin{macro}{\eV} %\begin{macro}{\meV} %\begin{macro}{\keV} %\begin{macro}{\MeV} %\begin{macro}{\GeV} %\begin{macro}{\TeV} % Energies. % \begin{macrocode} \newunit{\kJ}{\kilo\joule} \newunit{\eV}{\electronvolt} \newunit{\meV}{\milli\electronvolt} \newunit{\keV}{\kilo\electronvolt} \newunit{\MeV}{\mega\electronvolt} \newunit{\GeV}{\giga\electronvolt} \newunit{\TeV}{\tera\electronvolt} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\picom} %\begin{macro}{\nm} %\begin{macro}{\micm} %\begin{macro}{\mm} %\begin{macro}{\cm} %\begin{macro}{\dm} %\begin{macro}{\km} % Lengths. % \begin{macrocode} \newunit{\picom}{\pico\metre} \newunit{\nm}{\nano\metre} \newunit{\micm}{\micro\metre} \newunit{\mm}{\milli\metre} \newunit{\cm}{\centi\metre} \newunit{\dm}{\deci\metre} \newunit{\km}{\kilo\metre} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\Sec} %\begin{macro}{\as} %\begin{macro}{\fs} %\begin{macro}{\ps} %\begin{macro}{\ns} %\begin{macro}{\mics} %\begin{macro}{\ms} % Finally, times. % \begin{macrocode} \newunit{\Sec}{\second} \newunit{\as}{\atto\second} \newunit{\fs}{\femto\second} % \end{macrocode} % The letter class (and others) define \cs{ps} for postscripts, so % \cs{provideunit} is best here. % \begin{macrocode} \provideunit{\ps}{\pico\second} \newunit{\ns}{\nano\second} \newunit{\mics}{\micro\second} \newunit{\ms}{\milli\second} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\iffalse % %<*addn> %\fi %\subsection{Additional (temporary) SI units} %\begin{macro}{\angstrom} %\begin{macro}{\are} %\begin{macro}{\hectare} %\begin{macro}{\barn} %\begin{macro}{\BAR} %\begin{macro}{\millibar} %\begin{macro}{\gal} %\begin{macro}{\curie} %\begin{macro}{\roentgen} %\begin{macro}{\rad} %\begin{macro}{\rem} % Some units are ``temporarily'' acceptable for use in the SI system. % These are defined here, although some are in very general use. % \begin{macrocode} \ProvidesFile{si-addn.cfg} [2008/02/20 v.06a SI Additional units] \newunit{\angstrom}{\si@sym@ringA} \newunit{\are}{a} \newunit{\hectare}{\hecto\are} \newunit{\barn}{b} \newunit{\BAR}{bar} \newunit{\millibar}{\milli\BAR} \newunit{\gal}{Gal} \newunit{\curie}{Ci} \newunit{\roentgen}{R} \newunit{\rad}{rad} \newunit{\rem}{rem} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\iffalse % %<*accepted> %\fi %\subsection{Units accepted for use with SI} % The units which are accepted but do not fit in the above, plus % \cs{percent} which seems to fit into this category. %\begin{macro}{\minute} %\begin{macro}{\hour} %\begin{macro}{\Day} %\begin{macro}{\degree} %\begin{macro}{\Degree} %\begin{macro}{\arcmin} %\begin{macro}{\arcsec} %\begin{macro}{\litre} %\begin{macro}{\tonne} %\begin{macro}{\neper} %\begin{macro}{\bel} %\begin{macro}{\percent} % \begin{macrocode} \ProvidesFile{si-accepted.cfg} [2008/02/20 v.06a SI accepted units] \newunit{\minute}{min} \newunit{\hour}{h} \newunit{\Day}{d} \ifsi@old@OHM \newunit[valuesep=none]{\Degree}{\si@sym@degree} \else \ifsi@gensymb\else \newunit[valuesep=none]{\degree}{\si@sym@degree} \fi \fi \newunit[valuesep=none]{\arcmin}{\si@sym@minute} \newunit[valuesep=none]{\arcsec}{\si@sym@second} \newunit{\litre}{l} \newunit{\tonne}{t} \newunit{\neper}{Np} \newunit{\bel}{B} \newunit{\percent}{\%} % \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} %\iffalse % %<*physical> %\fi %\subsection{Units based on physical measurements} %\begin{macro}{\si@eVspacea} %\begin{macro}{\si@eVspaceb} %\begin{macro}{\electronvolt} %\begin{macro}{\atomicmassunit} %\begin{macro}{\atomicmass} %\begin{macro}{\dalton} % A few units based on physical measurements exist. For \cs{eV}, the need % for a negative kern does make things a bit complicated. % \begin{macrocode} \ProvidesFile{si-physical.cfg} [2008/02/20 v.06a SI physically-measured units] \newcommand*{\si@eVspacea}{\text{\kern-\si@eVcorra}}% \newcommand*{\si@eVspaceb}{\text{\kern-\si@eVcorrb}}% \newunit{\electronvolt}{e\protect\si@eVspacea V\protect\si@eVspaceb} \newunit{\atomicmass}{u} \newunit{\atomicmassunit}{u} \newunit{\dalton}{Da} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\iffalse % %\fi % %\section{Additional configurations} % To provide flexibility for people in specific areas, specialised % units can be set up. These are then stored separately to ease use. % %\iffalse %<*synchem> %\fi %\subsection{Synthetic chemistry} %\begin{macro}{\mmHg} %\begin{macro}{\molar} %\begin{macro}{\Molar} %\begin{macro}{\torr} % Some useful units for synthetic chemists; although \cs{mmHg} and % \cs{Molar} are outside of the SI system, they are used a lot. % These are set up using \cs{provideunit} as people may have their % own definitions. % \begin{macrocode} \ProvidesFile{si-synchem.cfg} [2008/02/20 v.06a Units for synthetic chemists] \si@requirecfgs{prefix} \newunit{\mmHg}{mmHg} \newunit{\molar}{\mole\per\cubic\deci\metre} \newunit{\Molar}{\textsc{m}} \newunit{\torr}{Torr} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\iffalse % %<*hep> %\fi %\subsection{High-energy physics} % The units here basically add the units from the \cs{hepunits} % package which are not defined elsewhere here. It is not entirely % clear if \cs{mrad} refers to radians or rad: feedback would be % welcome. This set of commands is not in the emulation block as it % does \emph{not} seek to emulate \pkg{hepunits}: that package is a % blot-on to \SIunits. The units here have the same name as those in % \pkg{hepunits} but stick with the new package interface. % \begin{macrocode} \ProvidesFile{si-hep.cfg} [2008/02/20 v.06a Units for high-energy physics] \si@requirecfgs{prefix,named} % \end{macrocode} %\begin{macro}{\micron} %\begin{macro}{\mrad} %\begin{macro}{\gauss} % The first units are not specific to high-energy physics, but are % not defined elsewhere in \currpkg. % \begin{macrocode} \newunit{\micron}{\micro\metre} \newunit{\mrad}{\milli\radian} \newunit{\gauss}{G} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\nanobarn} %\begin{macro}{\picobarn} %\begin{macro}{\femtobarn} %\begin{macro}{\attobarn} %\begin{macro}{\zeptobarn} %\begin{macro}{\yoctobarn} % Various prefixed barns % \begin{macrocode} \newunit{\nanobarn}{\nano\barn} \newunit{\picobarn}{\pico\barn} \newunit{\femtobarn}{\femto\barn} \newunit{\attobarn}{\atto\barn} \newunit{\zeptobarn}{\zepto\barn} \newunit{\yoctobarn}{\yocto\barn} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\invbarn} %\begin{macro}{\invnanobarn} %\begin{macro}{\invpicobarn} %\begin{macro}{\invfemtobarn} %\begin{macro}{\invattobarn} %\begin{macro}{\invzeptobarn} %\begin{macro}{\invyoctobarn} % Inverses barn units. % \begin{macrocode} \newunit{\invbarn}{\per\barn} \newunit{\invnanobarn}{\per\nano\barn} \newunit{\invpicobarn}{\per\pico\barn} \newunit{\invfemtobarn}{\per\femto\barn} \newunit{\invattobarn}{\per\atto\barn} \newunit{\invzeptobarn}{\per\zepto\barn} \newunit{\invyoctobarn}{\per\yocto\barn} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\invnb} %\begin{macro}{\invpb} %\begin{macro}{\invfb} %\begin{macro}{\invab} %\begin{macro}{\invzb} %\begin{macro}{\invyb} % Also available abbreviated. % \begin{macrocode} \newunit{\invnb}{\per\nano\barn} \newunit{\invpb}{\per\pico\barn} \newunit{\invfb}{\per\femto\barn} \newunit{\invab}{\per\atto\barn} \newunit{\invzb}{\per\zepto\barn} \newunit{\invyb}{\per\yocto\barn} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\invcmsqpersecond} %\begin{macro}{\invcmsqpersec} %\begin{macro}{\lumiunits} % Luminosity. % \begin{macrocode} \newunit{\invcmsqpersecond}{\per\Square\centi\metre\per\second} \newunit{\invcmsqpersec}{\per\Square\centi\metre\per\second} \newunit{\lumiunits}{\per\Square\centi\metre\per\second} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\clight} % The speed of light is used in units for the area, although of course % it is not strictly a unit. % \begin{macrocode} \newunit{\clight}{\ensuremath{\mathnormal{c}}} % \end{macrocode} %\end{macro} %\begin{macro}{\inveV} %\begin{macro}{\minveV} %\begin{macro}{\minveV} %\begin{macro}{\kinveV} %\begin{macro}{\MinveV} %\begin{macro}{\GinveV} %\begin{macro}{\TinveV} % The inverse of an electron-volt, plus prefixes. % \begin{macrocode} \newunit{\inveV}{\per\electronvolt} \newunit{\minveV}{\milli\per\electronvolt} \newunit{\kinveV}{\kilo\per\electronvolt} \newunit{\MinveV}{\mega\per\electronvolt} \newunit{\GinveV}{\giga\per\electronvolt} \newunit{\TinveV}{\tera\per\electronvolt} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\eVoverc} %\begin{macro}{\eVovercsq} % Some combinations of electron-volts and the speed of light. As % these are called |over|, they are set with a slash. The % \opt{eVcorrb} values have been set for Computer Modern. % \begin{macrocode} \newunit[per=slash,eVcorrb=0.6ex]{\eVoverc} {\electronvolt\per\clight} \newunit[per=slash,eVcorrb=0.6ex]{\eVovercsq} {\electronvolt\per\Square\clight} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\meVoverc} %\begin{macro}{\keVoverc} %\begin{macro}{\MeVoverc} %\begin{macro}{\GeVoverc} %\begin{macro}{\TeVoverc} % Prefixed combinations, first of the speed of light. % \begin{macrocode} \newunit[per=slash,eVcorrb=0.6ex]{\meVoverc} {\milli\electronvolt\per\clight} \newunit[per=slash,eVcorrb=0.6ex]{\keVoverc} {\kilo\electronvolt\per\clight} \newunit[per=slash,eVcorrb=0.6ex]{\MeVoverc} {\mega\electronvolt\per\clight} \newunit[per=slash,eVcorrb=0.6ex]{\GeVoverc} {\giga\electronvolt\per\clight} \newunit[per=slash,eVcorrb=0.6ex]{\TeVoverc} {\tera\electronvolt\per\clight} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\meVovercsq} %\begin{macro}{\keVovercsq} %\begin{macro}{\MeVovercsq} %\begin{macro}{\GeVovercsq} %\begin{macro}{\TeVovercsq} % Then of the square. % \begin{macrocode} \newunit[per=slash,eVcorrb=0.6ex]{\meVovercsq} {\milli\electronvolt\per\Square\clight} \newunit[per=slash,eVcorrb=0.6ex]{\keVovercsq} {\kilo\electronvolt\per\Square\clight} \newunit[per=slash,eVcorrb=0.6ex]{\MeVovercsq} {\mega\electronvolt\per\Square\clight} \newunit[per=slash,eVcorrb=0.6ex]{\GeVovercsq} {\giga\electronvolt\per\Square\clight} \newunit[per=slash,eVcorrb=0.6ex]{\TeVovercsq} {\tera\electronvolt\per\Square\clight} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\iffalse % %<*binary> %\fi %\subsection{Binary units} %\begin{macro}{\kibi} %\begin{macro}{\mebi} %\begin{macro}{\gibi} %\begin{macro}{\tebi} %\begin{macro}{\pebi} %\begin{macro}{\exbi} % The binary units, as specified by the IEC and made available by % \SIunits. First, the binary prefixes. % \begin{macrocode} \ProvidesFile{si-binary.cfg} [2008/02/20 v.06a Binary units] \newprefix{\kibi}{10}{Ki} \newprefix{\mebi}{20}{Mi} \newprefix{\gibi}{30}{Gi} \newprefix{\tebi}{40}{Ti} \newprefix{\pebi}{50}{Pi} \newprefix{\exbi}{60}{Ei} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\bit} %\begin{macro}{\byte} % Now the units. % \begin{macrocode} \newunit{\bit}{bit} \newunit{\byte}{B} % \end{macrocode} %\end{macro} %\end{macro} % %\iffalse % %\fi % %\section{Loadable locales} % Some short files to provide the correct settings for various places. % %\iffalse %<*UK> %\fi %\subsection{United Kingdom} % This is also used for the USA, and is the default. % \begin{macrocode} \ProvidesFile{si-UK.cfg} [2008/02/20 v.06a UK locale] \sisetup{ unitsep=thin, expproduct=times, valuesep=thin, decimalsign=fullstop, digitsep=thin, sepfour=false} % \end{macrocode} %\iffalse % %<*USA> %\fi %\subsection{United States} % The same as for the UK. % \begin{macrocode} \ProvidesFile{si-USA.cfg} [2008/02/20 v.06a USA locale] \sisetup{ unitsep=thin, expproduct=times, valuesep=thin, decimalsign=fullstop, digitsep=thin, sepfour=false} % \end{macrocode} %\iffalse % %\fi %\iffalse %<*germany> %\fi %\subsection{Germany} % Germany, hopefully. % \begin{macrocode} \ProvidesFile{si-germany.cfg} [2008/02/20 v.06a Germany locale] \sisetup{ unitsep=cdot, valuesep=thin, decimalsign=comma, expproduct=cdot, digitsep=thin, sepfour=false} % \end{macrocode} %\iffalse % %\fi %\iffalse %<*south-africa> %\fi %\subsection{South Africa} % Taken from \sistyle. % \begin{macrocode} \ProvidesFile{si-south-africa.loc} [2008/02/20 v.06a UK Locale] \sisetup{ unitsep=cdot, valuesep=thin, expproduct=times, decimalsign=comma, digitsep=thin, sepfour=false} % \end{macrocode} %\iffalse % %\fi %\section{Emulation code} % Each emulation mode loads an appropriate definition file. This % then alters the package defaults, and defines new macros provided % by the emulated package. % %\iffalse %<*units> %\fi %\subsection{\unitspkg} % The very first thing to do here is a reload check, as things % could go wrong with \unitsdef emulation. % \begin{macrocode} \si@ifloaded{units}{\endinput}{} % \end{macrocode} % The \unitspkg package is quite easy to emulate, as it only has a % few options and macros. There is also no error checking in % \unitspkg for conflicting options, so users probably expect none. % \begin{macrocode} \ProvidesFile{si-units.cfg} [2008/02/20 v.06a Emulation of units] \si@ifloaded{SIunits} {\si@emclash{units}{SIunits}\endinput}{} \si@ifloaded{sistyle} {\si@emclash{units}{sistyle}\endinput}{} % \end{macrocode} % To emulate \unitspkg, \cs{per} must give fractions. % \begin{macrocode} \sisetup{per=fraction,fraction=nice,obeybold,inlinebold=maths, ,obeymode} \ifsi@old@tight \sisetup{valuesep=thin} \fi \ifsi@old@loose \sisetup{valuesep=space} \fi \ifsi@old@ugly \sisetup{fraction=ugly} \fi % \end{macrocode} %\begin{macro}{\unit} % The \unitspkg version of \cs{unit} is similar to \cs{SI}. Here and % in \cs{unitfrac} the \cs{num} macro is used; thus the number given % really has to be a number. However, if users are using \currpkg % rather than \unitspkg they should expect more checking of input. As % the \unitspkg package uses the current mode, this has to be % detected.\\ %\cs{unit}\oarg{num}\marg{unit} % \begin{macrocode} \DeclareRobustCommand*{\unit}[2][]{% \ifmmode \SI{#1}{#2}% \else \SI[obeyfamily,obeyitalic]{#1}{#2}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\unitfrac} % \cs{unitfrac} is a bit more of a hack.\\ %\cs{unitfrac}\oarg{num}\marg{numerator}\marg{denominator} % \begin{macrocode} \DeclareRobustCommand*{\unitfrac}[3][]{% \begingroup \si@fam@mode% \ifmmode\else \sisetup{obeyfamily,obeyitalic}% \fi \si@ifnotmtarg{#1} {\num{#1}\ensuremath{\si@valuesep}}% \si@frac{#2}{#3} \endgroup} % \end{macrocode} %\end{macro} %\iffalse % %\fi %\iffalse %<*unitsdef> %\fi %\subsection{\unitsdef} % The package begins with the usual identification of what is % happening. Although \file{si-units.cfg} makes the same checks, % the error will make more sense if it comes here, in the event of a % clash. % \begin{macrocode} \ProvidesFile{si-unitsdef.cfg} [2008/02/20 v.06a Emulation of unitsdef] \si@ifloaded{SIunits} {\si@emclash{unitsdef}{SIunits}\endinput}{} \si@ifloaded{sistyle} {\si@emclash{unitsdef}{sistyle}\endinput}{} % \end{macrocode} % Emulation of \unitspkg is needed for \unitsdef to work. % \begin{macrocode} \si@ifloaded{units}{} {\InputIfFileExists{\si@fileprefix units.\si@cfgextension} {} {\si@log@err{Could not load \si@fileprefix units.\si@cfgextension} {The file \si@fileprefix units.\si@cfgextension is required to emulate\MessageBreak unitsdef, but cannot be found\MessageBreak Is the si package properly installed?} \endinput}} % \end{macrocode} % The \unitsdef package loads some packages that \currpkg does not. % In particular, it loads \pkg{textcomp} and \pkg{fontenc}. This % could be important for output, and so the same is done here. % \begin{macrocode} \RequirePackage{textcomp} \RequirePackage[T1]{fontenc} % \end{macrocode} % The multitude of package options for \unitsdef need to be handled. % \begin{macrocode} \sisetup{mode=text} \ifsi@old@noxspace \sisetup{xspace=false} \fi % \end{macrocode} % The various options for loading unit abbreviations have to be % handled. Here, any request to avoid abbreviations prevents any % loading. % \begin{macrocode} \ifsi@old@noabbr \sisetup{noload=abbr} \fi \ifsi@old@nofrequncyabbr \sisetup{noload=abbr} \fi \ifsi@old@nomolabbr \sisetup{noload=abbr} \fi \ifsi@old@novoltageabbr \sisetup{noload=abbr} \fi \ifsi@old@novolumeabbr \sisetup{noload=abbr} \fi \ifsi@old@noweightabbr \sisetup{noload=abbr} \fi \ifsi@old@noenergyabbr \sisetup{noload=abbr} \fi \ifsi@old@nolengthabbr \sisetup{noload=abbr} \fi \ifsi@old@notimeabbr \sisetup{noload=abbr} \fi % \end{macrocode} %\begin{macro}{\unitvaluesep} % To emulate the \cs{unitvaluesep} macro, a hack is needed of the original % \pkg{xkeyval} macro for \opt{valuesep}, as well of course as a definition % of the macro itself. % \begin{macrocode} \newcommand*{\unitvaluesep}{\,} \renewcommand*{\si@valuesep}{\text{\unitvaluesep}} \si@opt@choicekey{valuesep}{space,thin,med,medium,thick,none} {\renewcommand*\unitvaluesep\@nameuse{si@fix@##1}} {\renewcommand*\unitvaluesep{##1}} % \end{macrocode} %\end{macro} %\begin{macro}{\unitsignonly} %\begin{macro}{\ilu} %\begin{macro}{\arc} % Some rather straight-forward definitions, with just a bit of fun to % get the spacing correct. % \begin{macrocode} \DeclareRobustCommand*{\unitsignonly}{\unitsym} \DeclareRobustCommand*{\ilu}[2][]{% \begingroup #1\unitvaluesep% \unit{#2}% \endgroup} \DeclareRobustCommand*{\arc}{\ang} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\unitSIdef} %\begin{macro}{\si@unitSIdef} % The \unitsdef package uses a different approach to setting the font % inside its version of \cs{SI}. The problem is the same as for % \cs{unitvaluesep}, but with the added problem that \currpkg uses % \cs{csname} \ldots \cs{endcsname}. % \begin{macrocode} \newcommand*{\unitSIdef}{\upshape} \newcommand*{\si@unitSIdef}{\unitSIdef\selectfont} \sisetup{textdefault=si@unitSIdef,textnumdefault=si@unitSIdef} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\per} % Rather awkwardly, \unitsdef uses \cs{per} in a different way to % \currpkg. % \begin{macrocode} \DeclareRobustCommand*{\per}[2]{% \begingroup \si@xspacefalse \renewcommand*{\unitvaluesep}{}% \unitfrac{#1}{#2}% \endgroup} % \end{macrocode} %\end{macro} %\begin{macro}{\unittimes} %\begin{macro}{\unitsep} %\begin{macro}{\unitsuperscript} % Some pretty straight-forward stuff again; notice that the automatic % analyser for units has to be turned off for this to work. % \begin{macrocode} \newcommand*{\unittimes}{\ensuremath{\cdot}} \newcommand*{\unitsep}{\,} \renewcommand*{\si@unt@unithook}{\si@unt@litouttrue} \sisetup{unitsep=none} \newcommand*{\unitsuperscript}{\tothe} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\newnosepunit} %\begin{macro}{\renewnosepunit} % Simple aliases. % \begin{macrocode} \newcommand*{\newnosepunit}{\newunit[valuesep=none]} \newcommand*{\renewnosepunit}{\renewunit[valuesep=none]} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\setTextOmega} %\begin{macro}{\setMathOmega} %\begin{macro}{\setTextmu} %\begin{macro}{\setMathmu} %\begin{macro}{\setTextCelsius} %\begin{macro}{\setMathCelsius} %\begin{macro}{\setMathDegree} %\begin{macro}{\setTextDegree} % Controlling symbols is a simple translation job; as only one % setting is used by \currpkg in text mode, a bit of extra work is % needed. % \begin{macrocode} \newcommand*{\setTextOmega}[2]{% \renewcommand*{\si@textOmega}{% \begingroup \edef\si@tempa{\sfdefault}% \ifx\f@family\si@tempa \expandafter#2% \else \expandafter#1% \fi \endgroup}} \newcommand*{\setMathOmega}[1]{\sisetup{mathsOmega=#1}} \newcommand*{\setTextmu}[2]{% \renewcommand*{\si@textmu}{% \begingroup \edef\si@tempa{\sfdefault}% \ifx\f@family\si@tempa \expandafter#2% \else \expandafter#1% \fi \endgroup}} \newcommand*{\setMathmu}[1]{\sisetup{mathsmu=#1}} \newcommand*{\setTextCelsius}[2]{% \renewcommand*{\si@textcelsius}{% \begingroup \edef\si@tempa{\sfdefault}% \ifx\f@family\si@tempa \expandafter#2% \else \expandafter#1% \fi \endgroup}} \newcommand*{\setMathCelsius}[1]{\sisetup{mathscelsius=#1}} \newcommand*{\setMathDegree}[2]{% \renewcommand*{\si@textdegree}{% \begingroup% \edef\si@tempa{\sfdefault}% \ifx\f@family\si@tempa \expandafter#2% \else \expandafter#1% \fi \endgroup}} \newcommand*{\setTextDegree}[1]{\sisetup{textdegree=#1}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % The \opt{ohm} and \opt{OHM} options are checked, and some sanity is % ensured. This needs to happen before loading the configuration % files. % \begin{macrocode} \ifsi@old@OHM \ifsi@old@ohm \si@log@inf{Both `ohm' and `OHM' options given\MessageBreak Using default behaviour for unitsdef} \expandafter\expandafter\expandafter\si@old@OHMfalse \fi \fi % \end{macrocode} %\begin{macro}{\meter} %\begin{macro}{\liter} %\begin{macro}{\ton} %\begin{macro}{\days} % For some reason, \unitsdef spells metre and litre incorrectly (the % names have an official spelling). Tonne is also spelled as ``ton'', % which is wrong in the UK at least (1\,ton = 40\,cwt =\,2240 lb!) % \begin{macrocode} \newunit{\meter}{\metre} \newunit{\liter}{L} \ifsi@old@liter \ifsi@old@LITER \si@log@inf{Both `liter' and `LITER' options given\MessageBreak Using default behaviour for unitsdef} \else \renewunit{\liter}{l} \fi \fi \newunit{\ton}{t} \newunit{\days}{d} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\picometer} %\begin{macro}{\nanometer} %\begin{macro}{\micrometer} %\begin{macro}{\millimeter} %\begin{macro}{\centimeter} %\begin{macro}{\decimeter} %\begin{macro}{\kilometer} % Extra distances. % \begin{macrocode} \newunit{\picometer}{\pico\meter} \newunit{\nanometer}{\nano\meter} \newunit{\micrometer}{\micro\meter} \newunit{\millimeter}{\milli\meter} \newunit{\centimeter}{\centi\meter} \newunit{\decimeter}{\deci\meter} \newunit{\kilometer}{\kilo\meter} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\femtoliter} %\begin{macro}{\picoliter} %\begin{macro}{\nanoliter} %\begin{macro}{\microliter} %\begin{macro}{\milliliter} %\begin{macro}{\centiliter} %\begin{macro}{\deciliter} %\begin{macro}{\hectoliter} %\begin{macro}{\cubicmeter} %\begin{macro}{\cubicmicrometer} %\begin{macro}{\cubicmillimeter} % Volumes with US spellings. % \begin{macrocode} \newunit{\femtoliter}{\femto\liter} \newunit{\picoliter}{\pico\liter} \newunit{\nanoliter}{\nano\liter} \newunit{\microliter}{\micro\liter} \newunit{\milliliter}{\milli\liter} \newunit{\centiliter}{\centi\liter} \newunit{\deciliter}{\deci\liter} \newunit{\hectoliter}{\hecto\liter} \newunit{\cubicmeter}{\meter\cubed} \newunit{\cubicmicrometer}{\micro\meter\cubed} \newunit{\cubicmillimeter}{\milli\meter\cubed} % \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}{\squaremeter} %\begin{macro}{\squarecentimeter} %\begin{macro}{\squarekilometer} %\begin{macro}{\ar} %\begin{macro}{\hectar} % Areas, including the mis-spellings for \cs{are} and % \cs{hectare}. % \begin{macrocode} \newunit{\squaremeter}{\Square\meter} \newunit{\squarecentimeter}{\Square\centi\meter} \newunit{\squarekilometer}{\Square\kilo\meter} \newunit{\ar}{a} \newunit{\hectar}{\hecto\ar} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\kv} %\begin{macro}{\mv} % The code for \unitsdef has the capitalisation wrong for \cs{kV} and % \cs{mV}. % \begin{macrocode} \ifsi@old@noabbr \else \ifsi@old@novoltageabbr\else \newunit{\kv}{\kilo\volt} \newunit{\mv}{\milli\volt} \fi \fi % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\sek} %\begin{macro}{\fg} %\begin{macro}{\fl} %\begin{macro}{\pl} %\begin{macro}{\nl} %\begin{macro}{\micl} %\begin{macro}{\ml} %\begin{macro}{\cl} %\begin{macro}{\dl} %\begin{macro}{\hl} % There are some slightly different abbreviations, plus some which % are not officially allowed. % \begin{macrocode} \ifsi@old@noabbr\else \ifsi@old@notimeabbr\else \newunit{\sek}{\second} \fi \ifsi@old@noweightabbr\else \newunit{\fg}{\femto\gram} \fi \ifsi@old@novolumeabbr\else \newunit{\fl}{\femto\liter} \newunit{\pl}{\pico\liter} \newunit{\nl}{\nano\liter} \renewunit{\micl}{\micro\liter} \renewunit{\ml}{\milli\liter} \newunit{\cl}{\centi\liter} \newunit{\dl}{\deci\liter} \newunit{\hl}{\hecto\liter} \fi \fi % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\calory} %\begin{macro}{\kilocalory} % \unitsdef spells calorie incorrectly, and it is also not an SI unit. % \begin{macrocode} \newunit{\calory}{cal} \newunit{\kilocalory}{\kilo\calory} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\uBar} % \unitsdef uses \cs{ubar} for bar. % \begin{macrocode} \newunit{\uBar}{ba} % \end{macrocode} %\end{macro} %\begin{macro}{\gensymbohm} %\begin{macro}{\gensymbcelsius} %\begin{macro}{\gensymbmicro} %\begin{macro}{\gensymbdegree} % If the options relating to \pkg{gensymb} are given, then the % package \emph{has} to be loaded. The definitions are then renamed; % a slight awkward feature is that the hyphen character needs to be a % letter. To avoid needing to worry about this again, a second % switch is set up. % \begin{macrocode} \catcode`\-=11\relax \ifsi@old@redef-gensymb \expandafter\si@gensymbtrue \fi \catcode`\-=12\relax \ifsi@gensymb \RequirePackage{gensymb} \AtBeginDocument{ \let\gensymbohm\ohm \let\gensymbcelsius\celsius \let\gensymbmicro\micro \let\gensymbdegree\degree \let\ohm\@undefined \let\celsius\@undefined \let\micro\@undefined \let\degree\@undefined \ifsi@old@OHM\else \newunit{\ohm}{\si@sym@Omega} \newunit{\celsius}{\si@sym@celsius} \newprefix{\micro}{\si@sym@mu}{-6} \newunit{\degree}{\si@sym@degree} \fi} \fi % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % The configuration files can now be loaded. % \begin{macrocode} \si@requirecfgs{prefix,named,addn,accepted} % \end{macrocode} % The \opt{noconfig} option could be ignored, but it costs little to % let is be used. % \begin{macrocode} \ifsi@old@noconfig\else \InputIfFileExists{unitsdef.cfg} {\si@log@inf{unitsdef config file loaded}} {\si@log@inf{unitsdef config file not found}} \fi % \end{macrocode} % %\iffalse % %<*sistyle> %\fi %\subsection{\sistyle} % After setting the necessary defaults, the emulation code defines % the macros in \sistyle as given in the manual for that package. % \begin{macrocode} \ProvidesFile{si-sistyle.cfg} [2008/02/20 v.06a Emulation of sistyle] \sisetup{% sepfour=true, obeyfamily, obeyitalic=true, numsign=+-, numextra={}, unitsep=cdot} % \end{macrocode} %\begin{macro}{\SIobeyboldtrue} %\begin{macro}{\SIobeyboldfalse} % Some simple switches, but not using \cs{newif}. % \begin{macrocode} \newcommand*{\SIobeyboldtrue}{\sisetup{obeybold=true}} \newcommand*{\SIobeyboldfalse}{\sisetup{obeybold=false}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\num} %\begin{macro}{\si@sis@num} %\begin{macro}{\si@sis@numstar} % To get the correct behaviour for \cs{num}, some redefinitions are % needed to handle to optional |*|. % \begin{macrocode} \DeclareRobustCommand{\num}{% \@ifstar {\si@sis@numstar} {\si@sis@num}} \newcommand*{\si@sis@num}[2][]{% \begingroup% \sisetup{#1}% \expandafter\si@out@num\expandafter{\si@num{#2}}% \endgroup} \newcommand*{\si@sis@numstar}[2][]{% \begingroup% \sisetup{mode=text,obeybold}% \sisetup{#1}% \expandafter\si@out@num\expandafter{\si@num{#2}}% \endgroup} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\pnt} % The \cs{pnt} macro is needed as |.| is active inside \cs{SI}. The % name is exactly the same as in \sistyle, but the implementation is % different. This is not defined by the main package as there are % better ways of including numbers in the output than this. % \begin{macrocode} \newcommand*{\pnt}{\ensuremath{\si@decimalsign}} % \end{macrocode} %\end{macro} %\begin{macro}{\SIgroupfourtrue} %\begin{macro}{\SIgroupfourfalse} % Switches for grouping four characters. % \begin{macrocode} \newcommand*{\SIgroupfourtrue}{\sisetup{sepfour=true}} \newcommand*{\SIgroupfourfalse}{\sisetup{sepfour=false}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\SIunitsep} %\begin{macro}{\SIunitspace} %\begin{macro}{\SIunitdot} % Whatever is given here is passed through to \cs{sisetup}. % \begin{macrocode} \newcommand*{\SIunitsep}[1]{\sisetup{valuesep={#1}}} \newcommand*{\SIunitspace}[1]{\sisetup{unitspace={#1}}} \newcommand*{\SIunitdot}[1]{\sisetup{unitsep={#1}}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\SIdecimalsign} %\begin{macro}{\SIthousandsep} %\begin{macro}{\SIproductsign} % The same is true here, with the appropriate translation. % \begin{macrocode} \newcommand*{\SIdecimalsign}[1]{\sisetup{decimalsign={#1}}} \newcommand*{\SIthousandsep}[1]{\sisetup{digitsep={#1}}} \newcommand*{\SIproductsign}[1]{\sisetup{expproduct={#1}}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\si@sis@savefont} % The font definitions need a bit of extra work doing. As both % settings here have |@| as a letter, all should be fine.\\ %\cs{si@sis@savefont}\marg{setting}\marg{argument} % \begin{macrocode} \newcommand{\si@sis@savefont}[2]{% \@namedef{si@sis@#1}{#2}% \sisetup{#1=si@sis@#1}} % \end{macrocode} %\end{macro} %\begin{macro}{\SImathrm} %\begin{macro}{\SImathsf} %\begin{macro}{\SImathtt} % The font control macros have to ensure that a macro name is passed % to \cs{sisetup}. % \begin{macrocode} \newcommand*{\SImathrm}[1]{\si@sis@savefont{mathrm}{#1}} \newcommand*{\SImathsf}[1]{\si@sis@savefont{mathsf}{#1}} \newcommand*{\SImathtt}[1]{\si@sis@savefont{mathtt}{#1}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\SIdefaultMfam} %\begin{macro}{\SIdefaultNfam} %\begin{macro}{\SIdefaultTfam} % The same for the default keys. % \begin{macrocode} \newcommand*{\SIdefaultMfam}[1]{\si@sis@savefont{mathdefault}{#1}} \newcommand*{\SIdefaultNfam}[1]{\si@sis@savefont{mathnumdefault}{#1}} \newcommand*{\SIdefaultTfam}[1]{\si@sis@savefont{textdefault}{#1}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\ensureupmath} % The \cs{ensureupmath} command guarantees processing by the % font-matching system. The argument cannot be processed here, so % care is needed. % \begin{macrocode} \DeclareRobustCommand*{\ensureupmath}[1]{% \begingroup \sisetup{mode=maths,obeyitalic=false}% \si@out@text{#1}% \endgroup} % \end{macrocode} %\end{macro} %\begin{macro}{\degC} %\begin{macro}{\degF} %\begin{macro}{\arcdeg} % A few extra symbol names are needed. % \begin{macrocode} \newcommand*{\degC}{\si@sym@celsius} \newcommand*{\arcdeg}{\si@sym@degree} \newcommand*{\degF}{\si@sym@degree F} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\AddToSIstyle} %\begin{macro}{\SIstyle} %\begin{macro}{\SIstyleToLang} %\begin{macro}{\si@sis@addtolocale} % Finally, the locale control. % \begin{macrocode} \newcommand*{\SIstyle}[1]{\sisetup{locale=#1}} \newcommand*{\SIstyleToLang}[2]{\sisetup{loctolang=#1:#2}} \newcommand*{\AddToSIstyle}{% \si@switchfalse \@ifstar {\si@switchtrue \si@sis@addtolocale} {\si@sis@addtolocale}} \newcommand*{\si@sis@addtolocale}[2]{% \ifsi@switch \expandafter\let\csname si@loc@#1@extra\endcsname\relax \fi \addtolocale{#1}{#2}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\iffalse % %<*SIunits> %\fi %\subsection{\SIunits} % \SIunits emulation starts in much the same way. % \begin{macrocode} \ProvidesFile{si-SIunits.cfg} [2008/02/20 v.06a Emulation of SIunits] \sisetup{ unitsep=thick, valuesep=thick, prefixproduct=\si@valuesep} \si@requirecfgs{prefix,named,accepted,physical} % \end{macrocode} %\begin{macro}{\reciprocal} %\begin{macro}{\rp} %\begin{macro}{\per} %\begin{macro}{\usk} %\begin{macro}{\power} %\begin{macro}{\rpsquare} %\begin{macro}{\rpcubic} %\begin{macro}{\fourth} %\begin{macro}{\rpfourth} % A few very simple translations, using the internal version of % \cs{per} to allow changes of output style. % \begin{macrocode} \newcommand*{\reciprocal}{\sisetup{per=reciprocal}\si@per} \let\rp\reciprocal \renewcommand*{\per}{\sisetup{per=slash}\si@per} \newcommand*{\usk}{} \newcommand*{\power}[1]{#1\tothe} \newcommand*{\rpsquare}{\sisetup{per=reciprocal}\si@per\Square} \newcommand*{\rpcubic}{\sisetup{per=reciprocal}\si@per\cubic} \newpower{\fourth}{4} \newcommand*{\rpfourth}{\sisetup{per=reciprocal}\si@per\fourth} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\rpsquared} %\begin{macro}{\rpcubed} % Here, some low-level switch changing is needed. % \begin{macrocode} \newcommand*{\rpsquared}{% \sisetup{per=reciprocal}\si@unt@pertrue\si@unt@perseentrue\squared} \newcommand*{\rpcubed}{\sisetup{per=reciprocal}\si@unt@pertrue\cubed} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\SIsetup} %\begin{macro}{\si@tempa} %\begin{macro}{\si@siu@setup} % The various package spacing options are processed. They also have % to be correctly handled by the \cs{SIsetup} macro. % \begin{macrocode} \newcommand*{\SIsetup}[1]{% \@for\si@tempa:=#1\do{% \@ifundefined{ifsi@old@#1} {\si@log@warn{Unknown SIunits option `#1'}} {\csname si@old@#1true\endcsname}} \si@siu@setup} \newcommand*{\si@siu@setup}{% \ifsi@old@cdot \sisetup{unitsep=cdot}% \fi \ifsi@old@thickspace \sisetup{unitsep=thick}% \fi \ifsi@old@mediumspace \sisetup{unitsep=medium}% \fi \ifsi@old@thinspace \sisetup{unitsep=thin}% \fi \ifsi@old@thickqspace \sisetup{valuesep=thick}% \fi \ifsi@old@mediumqspace \sisetup{valuesep=medium}% \fi \ifsi@old@thinqspace \sisetup{valuesep=thin}% \fi} \si@siu@setup % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\square} %\begin{macro}{\squaren} % \SIunits does slightly different things about the clash with % \cs{square}, and either redefines this macro or provides % \cs{squaren}. % \begin{macrocode} \ifsi@old@squaren \newpower{\squaren}{2} \fi \AtBeginDocument{% \@ifundefined{square} {\newpower{\square}{2}} {\ifsi@old@amssymb \renewpower{\square}{2} \else \ifsi@old@squaren\else \si@log@warn{\string\square\space already defined\MessageBreak SIunits mode may cause errors}% \fi \fi}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\gray} % The potential clash with \pkg{PStricks} is also handled % differently; here, \cs{Gray} will already be defined by the % \currpkg kernel. % \begin{macrocode} \AtBeginDocument{% \@ifundefined{gray} {\newunit{\gray}{Gy}} {\ifsi@old@pstricks \renewunit{\gray}{Gy} \else \ifsi@old@Gray\else \si@log@warn{\string\gray\space already defined\MessageBreak SIunits mode may cause errors}% \fi \fi}} % \end{macrocode} %\end{macro} %\begin{macro}{\unit} %\begin{macro}{\unita} % The \cs{unit} macro is defined. % \begin{macrocode} \ifsi@old@italian \let\unita\SI \else \let\unit\SI \fi % \end{macrocode} %\end{macro} %\end{macro} % The miscellaneous options are moped up. % \begin{macrocode} \ifsi@old@textstyle \sisetup{mode=text} \fi \ifsi@old@binary \sisetup{alsoload=binary} \fi \ifsi@old@noams \AtBeginDocument{% \renewcommand*{\si@textmu}{\ensuremath\si@mathsmu}} \fi % \end{macrocode} %\begin{macro}{\arcminute} %\begin{macro}{\arcsecond} %\begin{macro}{\bbar} %\begin{macro}{\dday} %\begin{macro}{\liter} %\begin{macro}{\rperminute} %\begin{macro}{\ton} %\begin{macro}{\degreecelsius} % The unit macros defined by \SIunits that are not defined by % \currpkg (by default). % \begin{macrocode} \newunit[valuesep=none]{\arcminute}{\si@sym@minute} \newunit[valuesep=none]{\arcsecond}{\si@sym@second} \newunit{\bbar}{bar} \newunit{\dday}{day} \newunit{\liter}{L} \newunit{\rperminute}{r/min} \newunit{\ton}{t} \newunit{\degreecelsius}{\celsius} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\addunit} % This is an alias for \cs{newunit}. % \begin{macrocode} \let\addunit\newunit % \end{macrocode} %\end{macro} %\begin{macro}{\addprefix} % A little more work for \cs{addprefix}. % \begin{macrocode} \newcommand*{\addprefix}[2]{\newprefix{#1}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\graypersecond} %\begin{macro}{\graypersecondnp} %\begin{macro}{\metrepersquaresecond} %\begin{macro}{\metrepersquaresecondnp} %\begin{macro}{\joulepermole} %\begin{macro}{\joulepermolenp} %\begin{macro}{\molepercubicmetre} %\begin{macro}{\molepercubicmetrenp} %\begin{macro}{\radianpersquaresecond} %\begin{macro}{\radianpersquaresecondnp} %\begin{macro}{\kilogramsquaremetrepersecond} % \SIunits provides lots of macros with rather long names, which are % not really needed with \currpkg. However, they have to be defined % somewhere. There are a lot of them, so a few are tackled at a % time. % \begin{macrocode} \addunit{\graypersecond}{\gray\per\second} \addunit{\graypersecondnp}{\gray\reciprocal\second} \addunit{\metrepersquaresecond}{\metre\per\second\squared} \addunit{\metrepersquaresecondnp}{\metre\second\rpsquared} \addunit{\joulepermole}{\joule\per\mole} \addunit{\joulepermolenp}{\joule\reciprocal\mole} \addunit{\molepercubicmetre}{\mole\per\cubic\metre} \addunit{\molepercubicmetrenp}{\mole\rpcubic\metre} \addunit{\radianpersquaresecond}{\radian\per\second\squared} \addunit{\radianpersquaresecondnp}{\radian\second\rpsquared} \addunit{\kilogramsquaremetrepersecond} {\kilogram\usk\squaremetre\per\second} % \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}{\kilogramsquaremetrepersecondnp} %\begin{macro}{\radianpersecond} %\begin{macro}{\radianpersecondnp} %\begin{macro}{\squaremetrepercubicmetre} %\begin{macro}{\squaremetrepercubicmetrenp} %\begin{macro}{\katalpercubicmetre} %\begin{macro}{\katalpercubicmetrenp} %\begin{macro}{\coulombpermol} %\begin{macro}{\coulombpermolnp} %\begin{macro}{\amperepersquaremetre} %\begin{macro}{\amperepersquaremetrenp} % Some more. % \begin{macrocode} \addunit{\kilogramsquaremetrepersecondnp} {\kilogram\usk\squaremetre\reciprocal\second} \addunit{\radianpersecond}{\radian\per\second} \addunit{\radianpersecondnp}{\radian\reciprocal\second} \addunit{\squaremetrepercubicmetre}{\squaremetre\per\cubic\metre} \addunit{\squaremetrepercubicmetrenp}{\squaremetre\rpcubic\metre} \addunit{\katalpercubicmetre}{\katal\per\cubic\metre} \addunit{\katalpercubicmetrenp}{\katal\rpcubic\metre} \addunit{\coulombpermol}{\coulomb\per\mole} \addunit{\coulombpermolnp}{\coulomb\reciprocal\mole} \addunit{\amperepersquaremetre}{\ampere\per\squaremetre} \addunit{\amperepersquaremetrenp}{\ampere\rpsquare\metre} % \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}{\kilogrampercubicmetre} %\begin{macro}{\kilogrampercubicmetrenp} %\begin{macro}{\squaremetrepernewtonsecond} %\begin{macro}{\squaremetrepernewtonsecondnp} %\begin{macro}{\pascalsecond} %\begin{macro}{\coulombpercubicmetre} %\begin{macro}{\coulombpercubicmetrenp} %\begin{macro}{\amperemetresecond} %\begin{macro}{\voltpermetre} %\begin{macro}{\voltpermetrenp} %\begin{macro}{\coulombpersquaremetre} % Some more. % \begin{macrocode} \addunit{\kilogrampercubicmetre}{\kilogram\per\cubic\metre} \addunit{\kilogrampercubicmetrenp}{\kilogram\rpcubic\metre} \addunit{\squaremetrepernewtonsecond} {\squaremetre\per\newton\second} \addunit{\squaremetrepernewtonsecondnp} {\squaremetre\reciprocal\newton\reciprocal\second} \addunit{\pascalsecond}{\pascal\second} \addunit{\coulombpercubicmetre}{\coulomb\per\cubic\metre} \addunit{\coulombpercubicmetrenp}{\coulomb\rpcubic\metre} \addunit{\amperemetresecond}{\ampere\metre\second} \addunit{\voltpermetre}{\volt\per\metre} \addunit{\voltpermetrenp}{\volt\reciprocal\metre} \addunit{\coulombpersquaremetre}{\coulomb\per\squaremetre} % \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}{\coulombpersquaremetrenp} %\begin{macro}{\faradpermetre} %\begin{macro}{\faradpermetrenp} %\begin{macro}{\ohmmetre} %\begin{macro}{\kilowatthour} %\begin{macro}{\wattpersquaremetre} %\begin{macro}{\wattpersquaremetrenp} %\begin{macro}{\joulepersquaremetre} %\begin{macro}{\joulepersquaremetrenp} %\begin{macro}{\newtonpercubicmetre} %\begin{macro}{\newtonpercubicmetrenp} % Some more. % \begin{macrocode} \addunit{\coulombpersquaremetrenp}{\coulomb\rpsquare\metre} \addunit{\faradpermetre}{\farad\per\metre} \addunit{\faradpermetrenp}{\farad\reciprocal\metre} \addunit{\ohmmetre}{\ohm\metre} \addunit{\kilowatthour}{\kilo\watt\hour} \addunit{\wattpersquaremetre}{\watt\per\squaremetre} \addunit{\wattpersquaremetrenp}{\watt\rpsquare\metre} \addunit{\joulepersquaremetre}{\joule\per\squaremetre} \addunit{\joulepersquaremetrenp}{\joule\rpsquare\metre} \addunit{\newtonpercubicmetre}{\newton\per\cubic\metre} \addunit{\newtonpercubicmetrenp}{\newton\rpcubic\metre} % \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}{\newtonperkilogram} %\begin{macro}{\newtonperkilogramnp} %\begin{macro}{\jouleperkelvin} %\begin{macro}{\jouleperkelvinnp} %\begin{macro}{\jouleperkilogram} %\begin{macro}{\jouleperkilogramnp} %\begin{macro}{\coulombperkilogram} %\begin{macro}{\coulombperkilogramnp} %\begin{macro}{\squaremetrepersecond} %\begin{macro}{\squaremetrepersecondnp} %\begin{macro}{\squaremetrepersquaresecond} % Some more. % \begin{macrocode} \addunit{\newtonperkilogram}{\newton\per\kilogram} \addunit{\newtonperkilogramnp}{\newton\reciprocal\kilogram} \addunit{\jouleperkelvin}{\joule\per\kelvin} \addunit{\jouleperkelvinnp}{\joule\reciprocal\kelvin} \addunit{\jouleperkilogram}{\joule\per\kilogram} \addunit{\jouleperkilogramnp}{\joule\reciprocal\kilogram} \addunit{\coulombperkilogram}{\coulomb\per\kilogram} \addunit{\coulombperkilogramnp}{\coulomb\reciprocal\kilogram} \addunit{\squaremetrepersecond}{\squaremetre\per\second} \addunit{\squaremetrepersecondnp}{\squaremetre\reciprocal\second} \addunit{\squaremetrepersquaresecond} {\squaremetre\per\second\squared} % \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}{\squaremetrepersquaresecondnp} %\begin{macro}{\kilogrammetrepersecond} %\begin{macro}{\kilogrammetrepersecondnp} %\begin{macro}{\candelapersquaremetre} %\begin{macro}{\candelapersquaremetrenp} %\begin{macro}{\amperepermetre} %\begin{macro}{\amperepermetrenp} %\begin{macro}{\joulepertesla} %\begin{macro}{\jouleperteslanp} %\begin{macro}{\henrypermetre} %\begin{macro}{\henrypermetrenp} % Some more. % \begin{macrocode} \addunit{\squaremetrepersquaresecondnp} {\squaremetre\second\rpsquared} \addunit{\kilogrammetrepersecond}{\kilogram\metre\per\second} \addunit{\kilogrammetrepersecondnp} {\kilogram\metre\reciprocal\second} \addunit{\candelapersquaremetre}{\candela\per\squaremetre} \addunit{\candelapersquaremetrenp}{\candela\rpsquare\metre} \addunit{\amperepermetre}{\ampere\per\metre} \addunit{\amperepermetrenp}{\ampere\reciprocal\metre} \addunit{\joulepertesla}{\joule\per\tesla} \addunit{\jouleperteslanp}{\joule\reciprocal\tesla} \addunit{\henrypermetre}{\henry\per\metre} \addunit{\henrypermetrenp}{\henry\reciprocal\metre} % \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}{\kilogrampersecond} %\begin{macro}{\kilogrampersecondnp} %\begin{macro}{\kilogrampersquaremetresecond} %\begin{macro}{\kilogrampersquaremetresecondnp} %\begin{macro}{\kilogrampersquaremetre} %\begin{macro}{\kilogrampersquaremetrenp} %\begin{macro}{\kilogrampermetre} %\begin{macro}{\kilogrampermetrenp} %\begin{macro}{\joulepermolekelvin} %\begin{macro}{\joulepermolekelvinnp} %\begin{macro}{\kilogramperkilomole} % Some more. % \begin{macrocode} \addunit{\kilogrampersecond}{\kilogram\per\second} \addunit{\kilogrampersecondnp}{\kilogram\reciprocal\second} \addunit{\kilogrampersquaremetresecond} {\kilogram\per\squaremetre\second} \addunit{\kilogrampersquaremetresecondnp} {\kilogram\rpsquare\metre\reciprocal\second} \addunit{\kilogrampersquaremetre}{\kilogram\per\squaremetre} \addunit{\kilogrampersquaremetrenp}{\kilogram\rpsquare\metre} \addunit{\kilogrampermetre}{\kilogram\per\metre} \addunit{\kilogrampermetrenp}{\kilogram\reciprocal\metre} \addunit{\joulepermolekelvin}{\joule\per\mole\kelvin} \addunit{\joulepermolekelvinnp} {\joule\reciprocal\mole\reciprocal\kelvin} \addunit{\kilogramperkilomole}{\kilogram\per\kilo\mole} % \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}{\kilogramperkilomolenp} %\begin{macro}{\kilogramsquaremetre} %\begin{macro}{\kilogramsquaremetrenp} %\begin{macro}{\kilogrammetrepersquaresecond} %\begin{macro}{\kilogrammetrepersquaresecondnp} %\begin{macro}{\newtonpersquaremetre} %\begin{macro}{\newtonpersquaremetrenp} %\begin{macro}{\persquaremetresecond} %\begin{macro}{\persquaremetresecondnp} %\begin{macro}{\wattperkilogram} %\begin{macro}{\wattperkilogramnp} % Some more. % \begin{macrocode} \addunit{\kilogramperkilomolenp}{\kilogram\kilo\reciprocal\mole} \addunit{\kilogramsquaremetre}{\kilogram\squaremetre} \addunit{\kilogramsquaremetrenp}{\kilogramsquaremetre} \addunit{\kilogrammetrepersquaresecond} {\kilogram\metre\per\second\squared} \addunit{\kilogrammetrepersquaresecondnp} {\kilogram\metre\second\rpsquared} \addunit{\newtonpersquaremetre}{\newton\per\squaremetre} \addunit{\newtonpersquaremetrenp}{\newton\rpsquare\metre} \addunit{\persquaremetresecond}{1\per\squaremetre\second} \addunit{\persquaremetresecondnp}{\rpsquare\metre\reciprocal\second} \addunit{\wattperkilogram}{\watt\per\kilogram} \addunit{\wattperkilogramnp}{\watt\reciprocal\kilogram} % \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}{\wattpercubicmetre} %\begin{macro}{\wattpercubicmetrenp} %\begin{macro}{\wattpersquaremetresteradian} %\begin{macro}{\wattpersquaremetresteradiannp} %\begin{macro}{\jouleperkilogramkelvin} %\begin{macro}{\jouleperkilogramkelvinnp} %\begin{macro}{\squaremetreperkilogram} %\begin{macro}{\rpsquaremetreperkilogram} %\begin{macro}{\cubicmetreperkilogram} %\begin{macro}{\rpcubicmetreperkilogram} %\begin{macro}{\newtonpermetre} % Some more. % \begin{macrocode} \addunit{\wattpercubicmetre}{\watt\per\cubic\metre} \addunit{\wattpercubicmetrenp}{\watt\rpcubic\metre} \addunit{\wattpersquaremetresteradian}{\watt\per\squaremetre\steradian} \addunit{\wattpersquaremetresteradiannp} {\watt\rpsquare\metre\rp\steradian} \addunit{\jouleperkilogramkelvin}{\joule\per\kilogram\kelvin} \addunit{\jouleperkilogramkelvinnp} {\joule\reciprocal\kilogram\reciprocal\kelvin} \addunit{\squaremetreperkilogram}{\squaremetre\per\kilogram} \addunit{\rpsquaremetreperkilogram} {\squaremetre\reciprocal\kilogram} \addunit{\cubicmetreperkilogram}{\cubic\metre\per\kilogram} \addunit{\rpcubicmetreperkilogram} {\cubic\metre\reciprocal\kilogram} \addunit{\newtonpermetre}{\newton\per\metre} % \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}{\newtonpermetrenp} %\begin{macro}{\wattpermetrekelvin} %\begin{macro}{\wattpermetrekelvinnp} %\begin{macro}{\newtonmetre} %\begin{macro}{\newtonmetrenp} %\begin{macro}{\squaremetrepercubicsecond} %\begin{macro}{\squaremetrepercubicsecondnp} %\begin{macro}{\metrepersecond} %\begin{macro}{\metrepersecondnp} %\begin{macro}{\joulepercubicmetre} %\begin{macro}{\joulepercubicmetrenp} % Some more. % \begin{macrocode} \addunit{\newtonpermetrenp}{\newton\reciprocal\metre} \addunit{\wattpermetrekelvin}{\watt\per\metre\kelvin} \addunit{\wattpermetrekelvinnp} {\watt\reciprocal\metre\reciprocal\kelvin} \addunit{\newtonmetre}{\newton\metre} \addunit{\newtonmetrenp}{\newtonmetre} \addunit{\squaremetrepercubicsecond}{\squaremetre\per\cubic\second} \addunit{\squaremetrepercubicsecondnp} {\squaremetre\rpcubic\second} \addunit{\metrepersecond}{\metre\per\second} \addunit{\metrepersecondnp}{\metre\reciprocal\second} \addunit{\joulepercubicmetre}{\joule\per\cubicmetre} \addunit{\joulepercubicmetrenp}{\joule\rpcubic\metre} % \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}{\kilogrampercubicmetrecoulomb} %\begin{macro}{\kilogrampercubicmetrecoulombnp} %\begin{macro}{\cubicmetrepersecond} %\begin{macro}{\rpcubicmetrepersecond} %\begin{macro}{\kilogrampersecondcubicmetre} %\begin{macro}{\kilogrampersecondcubicmetrenp} % Last block. % \begin{macrocode} \addunit{\kilogrampercubicmetrecoulomb} {\kilogram\per\cubic\metre\coulomb} \addunit{\kilogrampercubicmetrecoulombnp} {\kilogram\rpcubic\metre\reciprocal\coulomb} \addunit{\cubicmetrepersecond}{\cubicmetre\per\second} \addunit{\rpcubicmetrepersecond}{\cubicmetre\reciprocal\second} \addunit{\kilogrampersecondcubicmetre} {\kilogram\per\second\cubicmetre} \addunit{\kilogrampersecondcubicmetrenp} {\kilogram\reciprocal\second\rpcubic\metre} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\yoctod} %\begin{macro}{\zeptod} %\begin{macro}{\attod} %\begin{macro}{\femtod} %\begin{macro}{\picod} %\begin{macro}{\nanod} %\begin{macro}{\microd} %\begin{macro}{\millid} %\begin{macro}{\centid} % The prefixes giving numerical output need a trick. First the small % values. % \begin{macrocode} \newunit{\yoctod}{\si@prefixnumtrue\yocto} \newunit{\zeptod}{\si@prefixnumtrue\zepto} \newunit{\attod}{\si@prefixnumtrue\atto} \newunit{\femtod}{\si@prefixnumtrue\femto} \newunit{\picod}{\si@prefixnumtrue\pico} \newunit{\nanod}{\si@prefixnumtrue\nano} \newunit{\microd}{\si@prefixnumtrue\micro} \newunit{\millid}{\si@prefixnumtrue\milli} \newunit{\centid}{\si@prefixnumtrue\centi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\decad} %\begin{macro}{\dekad} %\begin{macro}{\hectod} %\begin{macro}{\kilod} %\begin{macro}{\megad} %\begin{macro}{\gigad} %\begin{macro}{\terad} %\begin{macro}{\petad} %\begin{macro}{\exad} %\begin{macro}{\zettad} %\begin{macro}{\yottad} % The the larger ones. % \begin{macrocode} \newunit{\decad}{\si@prefixnumtrue\deca} \newunit{\dekad}{\si@prefixnumtrue\deka} \newunit{\hectod}{\si@prefixnumtrue\hecto} \newunit{\kilod}{\si@prefixnumtrue\kilo} \newunit{\megad}{\si@prefixnumtrue\mega} \newunit{\gigad}{\si@prefixnumtrue\giga} \newunit{\terad}{\si@prefixnumtrue\tera} \newunit{\petad}{\si@prefixnumtrue\peta} \newunit{\exad}{\si@prefixnumtrue\exa} \newunit{\zettad}{\si@prefixnumtrue\zetta} \newunit{\yottad}{\si@prefixnumtrue\yotta} % \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}{\kibid} %\begin{macro}{\mebid} %\begin{macro}{\gibid} %\begin{macro}{\tebid} %\begin{macro}{\pebid} %\begin{macro}{\exbid} % The binary versions need a little more work. % \begin{macrocode} \newunit{\kibid}{% \si@prefixnumtrue\let\si@prefixpower\si@fix@two\kibi} \newunit{\mebid}{% \si@prefixnumtrue\let\si@prefixpower\si@fix@two\mebi} \newunit{\gibid}{% \si@prefixnumtrue\let\si@prefixpower\si@fix@two\gibi} \newunit{\tebid}{% \si@prefixnumtrue\let\si@prefixpower\si@fix@two\tebi} \newunit{\pebid}{% \si@prefixnumtrue\let\si@prefixpower\si@fix@two\pebi} \newunit{\exbid}{% \si@prefixnumtrue\let\si@prefixpower\si@fix@two\exbi} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\begin{macro}{\derradian} %\begin{macro}{\dersteradian} %\begin{macro}{\derhertz} %\begin{macro}{\dernewton} %\begin{macro}{\derpascal} %\begin{macro}{\derjoule} %\begin{macro}{\derwatt} %\begin{macro}{\dercoulomb} %\begin{macro}{\dervolt} %\begin{macro}{\derfarad} %\begin{macro}{\derohm} % The derived units may need to be defined. % \begin{macrocode} \ifsi@old@derived \newunit{\derradian}{\metre\reciprocal\metre} \newunit{\dersteradian}{\squaremetre\rpsquare\metre} \newunit{\derhertz}{\reciprocal\second} \newunit{\dernewton}{\metre\kilogram\second\rpsquared} \newunit{\derpascal}{\newton\rpsquare\metre} \newunit{\derjoule}{\newton\metre} \newunit{\derwatt}{\joule\reciprocal\second} \newunit{\dercoulomb}{\ampere\second} \newunit{\dervolt}{\watt\reciprocal\ampere} \newunit{\derfarad}{\coulomb\reciprocal\volt} \newunit{\derohm}{\volt\reciprocal\ampere} % \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}{\dersiemens} %\begin{macro}{\derweber} %\begin{macro}{\dertesla} %\begin{macro}{\derhenry} %\begin{macro}{\dercelsius} %\begin{macro}{\derlumen} %\begin{macro}{\derlux} %\begin{macro}{\derbecquerel} %\begin{macro}{\dergray} %\begin{macro}{\dersievert} %\begin{macro}{\derkatal} % In two blocks! % \begin{macrocode} \newunit{\dersiemens}{\ampere\reciprocal\volt} \newunit{\derweber} {\squaremetre\kilogram\second\rpsquared\reciprocal\ampere} \newunit{\dertesla}{\weber\rpsquare\metre} \newunit{\derhenry}{\weber\reciprocal\ampere} \newunit{\dercelsius}{\kelvin} \newunit{\derlumen}{\candela\steradian} \newunit{\derlux}{\lumen\rpsquare\metre} \newunit{\derbecquerel}{\derhertz} \newunit{\dergray}{\joule\reciprocal\kilogram} \newunit{\dersievert}{\dergray} \newunit{\derkatal}{\rp\second\usk\mole} \fi % \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}{\radianbase} %\begin{macro}{\steradianbase} %\begin{macro}{\hertzbase} %\begin{macro}{\newtonbase} %\begin{macro}{\pascalbase} %\begin{macro}{\joulebase} %\begin{macro}{\wattbase} %\begin{macro}{\coulombbase} %\begin{macro}{\voltbase} %\begin{macro}{\faradbase} %\begin{macro}{\ohmbase} % Also the ``derived-in-base''. % \begin{macrocode} \ifsi@old@derivedinbase \newunit{\radianbase}{\metre\reciprocal\metre} \newunit{\steradianbase}{\squaremetre\rpsquare\metre} \newunit{\hertzbase}{\reciprocal\second} \newunit{\newtonbase}{\metre\kilogram\second\rpsquared} \newunit{\pascalbase}{\reciprocal\metre\kilogram\second\rpsquared} \newunit{\joulebase}{\squaremetre\kilogram\second\rpsquared} \newunit{\wattbase}{\squaremetre\kilogram\rpcubic\second} \newunit{\coulombbase}{\ampere\second} \newunit{\voltbase} {\squaremetre\kilogram\rpcubic\second\reciprocal\ampere} \newunit{\faradbase} {\rpsquare\metre\reciprocal\kilogram\fourth\second\ampere% \squared} \newunit{\ohmbase} {\squaremetre\kilogram\rpcubic\second\rpsquare\ampere} % \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}{\siemensbase} %\begin{macro}{\weberbase} %\begin{macro}{\teslabase} %\begin{macro}{\henrybase} %\begin{macro}{\celsiusbase} %\begin{macro}{\lumenbase} %\begin{macro}{\luxbase} %\begin{macro}{\becquerelbase} %\begin{macro}{\graybase} %\begin{macro}{\sievertbase} %\begin{macro}{\katalbase} % Also in two blocks. % \begin{macrocode} \newunit{\siemensbase} {\rpsquare\metre\reciprocal\kilogram\cubic\second\ampere\squared} \newunit{\weberbase} {\squaremetre\kilogram\second\rpsquared\reciprocal\ampere} \newunit{\teslabase}{\kilogram\second\rpsquared\reciprocal\ampere} \newunit{\henrybase} {\squaremetre\kilogram\second\rpsquared\rpsquare\ampere} \newunit{\celsiusbase}{\kelvin} \newunit{\lumenbase}{\candela\squaremetre\rpsquare\metre} \newunit{\luxbase}{\candela\squaremetre\rpfourth\metre} \newunit{\becquerelbase}{\hertzbase} \newunit{\graybase}{\squaremetre\second\rpsquared} \newunit{\sievertbase}{\graybase} \newunit{\katalbase}{\rp\second\mole} \fi % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % Any configuration file is used if found. % \begin{macrocode} \InputIfFileExists{SIunits.cfg} {\si@log@inf{SIunits config file loaded}} {\si@log@inf{SIunits config file not found}} % \end{macrocode} %\iffalse % %\fi % %\Finale %\iffalse %<*refs> @misc{NIST, note = {\url{http://physics.nist.gov/cuu/Units/rules.html}}, } % %<*jawltxdoc> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{jawltxdoc} \usepackage[T1]{fontenc} \usepackage[english,UKenglish]{babel} \usepackage[scaled=0.95]{helvet} \usepackage[version=3]{mhchem} \usepackage[final]{microtype} \usepackage[osf]{mathpazo} \usepackage{booktabs,array,url,graphicx,courier,xspace} \usepackage{upgreek,ifpdf,listings,float,caption,longtable} \floatstyle{plaintop} \restylefloat{table} \ifpdf \usepackage{embedfile} \embedfile[% stringmethod=escape,% mimetype=plain/text,% desc={LaTeX docstrip source archive for package `\jobname'}% ]{\jobname.dtx} \fi \IfFileExists{\jobname.sty} {\usepackage{\jobname}}{} \usepackage[numbered]{hypdoc} \newlength\LaTeXwidth \newlength\LaTeXoutdent \newlength\LaTeXgap \setlength\LaTeXgap{1em} \setlength\LaTeXoutdent{-0.15\textwidth} \newcommand*{\typesetexampleandcode}{% \begin{list}{}{% \setlength\itemindent{0pt} \setlength\leftmargin\LaTeXoutdent \setlength\rightmargin{0pt} } \item \setlength\LaTeXoutdent{-0.15\textwidth} \begin{minipage}[c]{\textwidth-\LaTeXwidth-\LaTeXoutdent-\LaTeXgap} \lst@sampleInput \end{minipage}% \hfill% \begin{minipage}[c]{\LaTeXwidth}% \hbox to\linewidth{\box\lst@samplebox\hss}% \end{minipage}% \end{list} } \newcommand*{\typesetcodeandexample}{% \begin{list}{}{% \setlength\itemindent{0pt} \setlength\leftmargin{0pt} \setlength\rightmargin{0pt} } \item \begin{minipage}[c]{\LaTeXwidth}% \hbox to\linewidth{\box\lst@samplebox\hss}% \end{minipage}% \lst@sampleInput \end{list} } \newcommand*{\typesetfloatexample}{% \begin{list}{}{% \setlength\itemindent{0pt} \setlength\leftmargin{0pt} \setlength\rightmargin{0pt} } \item \lst@sampleInput \begin{minipage}[c]{\LaTeXwidth}% \hbox to\linewidth{\box\lst@samplebox\hss}% \end{minipage}% \end{list} } \newcommand*{\typesetcodeonly}{% \begin{list}{}{% \setlength\itemindent{0pt} \setlength\leftmargin{0pt} \setlength\rightmargin{0pt} } \item \begin{minipage}[c]{\LaTeXwidth}% \hbox to\linewidth{\box\lst@samplebox\hss}% \end{minipage}% \end{list} } \edef\LaTeXexamplefile{\jobname.tmp} \lst@RequireAspects{writefile} \newbox\lst@samplebox \lstnewenvironment{LaTeXexample}[1][\typesetexampleandcode]{% \let\typesetexample#1 \global\let\lst@intname\@empty \setbox\lst@samplebox=\hbox\bgroup \setkeys{lst}{tabsize=4,gobble=3,breakindent=0pt,% basicstyle=\small\ttfamily,basewidth=0.51em,% keywordstyle=\color{blue}} \lst@BeginAlsoWriteFile{\LaTeXexamplefile} }{% \lst@EndWriteFile\egroup \setlength\LaTeXwidth{\wd\lst@samplebox} \typesetexample% } \newcommand*{\lst@sampleInput}{% \MakePercentComment\catcode`\^^M=10\relax \small% {\setkeys{lst}{SelectCharTable=\lst@ReplaceInput{\^\^I}% {\lst@ProcessTabulator}}% \leavevmode \input{\LaTeXexamplefile}}% \MakePercentIgnore% } \newcommand*{\pkg}[1]{\textsf{#1}} \newcommand*{\currpkg}{\pkg{\jobname}\xspace} \newcommand*{\opt}[1]{\texttt{#1}} \newcommand*{\file}[1]{\texttt{#1}} \newcommand*{\ext}[1]{\file{.#1}} \newcommand*{\latin}[1]{\emph{#1}} \newcommand*{\etc}{% \@ifnextchar. {\latin{etc}} {\latin{etc.}} \xspace} \newcommand*{\eg}{% \@ifnextchar. {\latin{e.g}} {\latin{e.g.}} \xspace} \newcommand*{\ie}{% \@ifnextchar. {\latin{i.e}} {\latin{i.e.}} \xspace} \newcommand*{\AMS}{{\protect\usefont{OMS}{cmsy}{m}{n}% A\kern-.1667em\lower.5ex\hbox{M}\kern-.125emS}} \providecommand*{\eTeX}{\ensuremath{\varepsilon}-\TeX} \newcommand*{\XeTeX} {X\kern-.125em\lower.5ex\hbox{\reflectbox{E}}\kern-.1667em\TeX} % %\fi