summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-05-03 21:02:51 +0000
committerKarl Berry <karl@freefriends.org>2018-05-03 21:02:51 +0000
commit3bdba37dd5619bcbc46b0e684507cbb0f661eb8b (patch)
treebadcc270fdf874e08aa0fe7a85048a5037cef25a /Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx
parent43cc6b933ec42794dc802aed3ef8ca8dbec6c70e (diff)
siunitx (3may18)
git-svn-id: svn://tug.org/texlive/trunk@47596 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx')
-rw-r--r--Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx1862
1 files changed, 0 insertions, 1862 deletions
diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx
deleted file mode 100644
index 63de999adce..00000000000
--- a/Master/texmf-dist/source/latex/siunitx/siunitx-number.dtx
+++ /dev/null
@@ -1,1862 +0,0 @@
-% \iffalse meta-comment
-%
-% File: siunitx-number.dtx Copyright (C) 2014-2017 Joseph Wright
-%
-% It may be distributed and/or modified under the conditions of the
-% LaTeX Project Public License (LPPL), either version 1.3c of this
-% license or (at your option) any later version. The latest version
-% of this license is in the file
-%
-% https://www.latex-project.org/lppl.txt
-%
-% This file is part of the "siunitx bundle" (The Work in LPPL)
-% and all files in that bundle must be distributed together.
-%
-% The released version of this bundle is available from CTAN.
-%
-% -----------------------------------------------------------------------
-%
-% The development version of the bundle can be found at
-%
-% https://github.com/josephwright/siunitx
-%
-% for those people who are interested.
-%
-% -----------------------------------------------------------------------
-%
-%<*driver>
-\documentclass{l3doc}
-% The next line is needed so that \GetFileInfo will be able to pick up
-% version data
-\usepackage{siunitx}
-\begin{document}
- \DocInput{\jobname.dtx}
-\end{document}
-%</driver>
-% \fi
-%
-% \GetFileInfo{siunitx.sty}
-%
-% \title{^^A
-% \pkg{siunitx-number} -- Parsing and formatting numbers^^A
-% \thanks{This file describes \fileversion,
-% last revised \filedate.}^^A
-% }
-%
-% \author{^^A
-% Joseph Wright^^A
-% \thanks{^^A
-% E-mail:
-% \href{mailto:joseph.wright@morningstar2.co.uk}
-% {joseph.wright@morningstar2.co.uk}^^A
-% }^^A
-% }
-%
-% \date{Released \filedate}
-%
-% \maketitle
-%
-% \begin{documentation}
-%
-% \begin{function}{\siunitx_number_format:nN, \siunitx_number_format:VN}
-% \begin{syntax}
-% \cs{siunitx_number_format:nN} \Arg{number} \meta{tl~var}
-% \end{syntax}
-% \end{function}
-%
-% \begin{function}{\siunitx_number_format:nNN}
-% \begin{syntax}
-% \cs{siunitx_number_format:nNN} \Arg{number} \meta{tl~var} \meta{marker}
-% \end{syntax}
-% \end{function}
-%
-% \begin{function}[TF]{\siunitx_if_number:n}
-% \begin{syntax}
-% \cs{siunitx_if_number_token:NTF} \Arg{tokens}
-% \Arg{true code} \Arg{false code}
-% \end{syntax}
-% Determines if the \meta{tokens} form a valid number which can be fully
-% parsed by \pkg{siunitx}.
-% \end{function}
-%
-% \begin{function}[TF]{\siunitx_if_number_token:N}
-% \begin{syntax}
-% \cs{siunitx_if_number_token:NTF} \Arg{token}
-% \Arg{true code} \Arg{false code}
-% \end{syntax}
-% Determines if the \meta{token} is valid in a number based on those
-% tokens currently set up for detection in a number.
-% \end{function}
-%
-% \end{documentation}
-%
-% \begin{implementation}
-%
-% \section{\pkg{siunitx-number} implementation}
-%
-% Start the \pkg{DocStrip} guards.
-% \begin{macrocode}
-%<*package>
-% \end{macrocode}
-%
-% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention): only
-% internal material in this \emph{submodule} should be used directly.
-% \begin{macrocode}
-%<@@=siunitx_number>
-% \end{macrocode}
-%
-% \subsection{Initial set-up}
-%
-% Variants not provided by \pkg{expl3}.
-% \begin{macrocode}
-\cs_generate_variant:Nn \tl_if_blank:nTF { f }
-\cs_generate_variant:Nn \tl_if_blank_p:n { f }
-\cs_generate_variant:Nn \tl_if_in:NnTF { NV }
-% \end{macrocode}
-%
-% \begin{variable}{\l_@@_tmp_tl}
-% Scratch space.
-% \begin{macrocode}
-\tl_new:N \l_@@_tmp_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \subsection{Main formatting routine}
-%
-% \begin{variable}{\l_@@_formatted_tl}
-% A token list for the final formatted result: may or may not be generated
-% by the parser, depending on settings which are active.
-% \begin{macrocode}
-\tl_new:N \l_@@_formatted_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_tab_tl}
-% A token list for marking the position of tabular alignments in formatted
-% output.
-% \begin{macrocode}
-\tl_new:N \l_@@_tab_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}{\siunitx_number_format:nN, \siunitx_number_format:VN}
-% \begin{macro}{\siunitx_number_format:nNN}
-% \begin{macro}{\@@_format:nN}
-% \begin{macrocode}
-\cs_new_protected:Npn \siunitx_number_format:nN #1#2
- {
- \tl_clear:N \l_@@_tab_tl
- \@@_format:nN {#1} #2
- }
-\cs_generate_variant:Nn \siunitx_number_format:nN { V }
-\cs_new_protected:Npn \siunitx_number_format:nNN #1#2#3
- {
- \tl_set:Nn \l_@@_tab_tl {#3}
- \@@_format:nN {#1} #2
- }
-\cs_new_protected:Npn \@@_format:nN #1#2
- {
- \group_begin:
- \@@_parse:n {#1}
- \@@_format:
- \exp_args:NNNV \group_end:
- \tl_set:Nn #2 \l_@@_formatted_tl
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \subsection{Parsing numbers}
-%
-% Before numbers can be manipulated or formatted they need to be parsed into
-% an internal form. In particular, if multiple code paths are to be avoided,
-% it is necessary to do such parsing even for relatively simple cases such
-% as converting |1e10| to |1 \times 10^{10}|.
-%
-% Storing the result of such parsing can be done in a number of ways. In the
-% first version of \pkg{siunitx} a series of separate data stores were used.
-% This is potentially quite fast (as recovery of items relies only on \TeX{}'s
-% hash table) but makes managing the various data entries somewhat tedious and
-% error-prone. For version two of the package, a single data structure
-% (property list) was used for each part of the parsed number. Whilst this is
-% easy to manage and extend, it is somewhat slower as at a \TeX{} level there
-% are repeated pack--unpack steps. In particular, the fact that there are a
-% limited number of items to track for a \enquote{number} means that a more
-% efficient approach is desirable (contrast parsing units, which is open-ended
-% and therefore fits well with using a property list).
-%
-% To allow for complex numbers, two parallel data structures are used, one for
-% the real part and one for the imaginary part. If the part is entirely absent
-% then the data structures are left empty. Within each part, the structure
-% is
-% \begin{quote}
-% \marg{comparator}\meta{sign}\marg{integer}\marg{decimal}
-% \marg{uncertainty}\\
-% \meta{exponent sign}\marg{exponent}
-% \end{quote}
-% where the two sign parts must be single tokens and all other components
-% must be given in braces. \emph{All} of the components must be present in
-% a stored number (\emph{i.e.}~at the end of parsing). The number must have
-% at least one digit for both the \meta{integer} and \meta{exponent} parts.
-%
-% \begin{variable}
-% {
-% \l_@@_expression_bool ,
-% \l_@@_input_uncert_close_tl ,
-% \l_@@_input_complex_tl ,
-% \l_@@_input_comparator_tl ,
-% \l_@@_input_decimal_tl ,
-% \l_@@_input_digit_tl ,
-% \l_@@_input_exponent_tl ,
-% \l_@@_input_ignore_tl ,
-% \l_@@_input_uncert_open_tl ,
-% \l_@@_input_sign_tl ,
-% \l_@@_input_uncert_sign_tl
-% }
-% \begin{macro}[EXP]{\@@_expression:n}
-% Options which determine the various valid parts of a parsed number.
-% \begin{macrocode}
-\keys_define:nn { siunitx }
- {
- evaluate-expression .bool_set:N =
- \l_@@_expression_bool ,
- expression .code:n =
- \cs_set:Npn \@@_expression:n ##1 {#1} ,
- input-close-uncertainty .tl_set:N =
- \l_@@_input_uncert_close_tl ,
- input-complex-roots .tl_set:N =
- \l_@@_input_complex_tl ,
- input-comparators .tl_set:N =
- \l_@@_input_comparator_tl ,
- input-decimal-markers .tl_set:N =
- \l_@@_input_decimal_tl ,
- input-digits .tl_set:N =
- \l_@@_input_digit_tl ,
- input-exponent-markers .tl_set:N =
- \l_@@_input_exponent_tl ,
- input-ignore .tl_set:N =
- \l_@@_input_ignore_tl ,
- input-open-uncertainty .tl_set:N =
- \l_@@_input_uncert_open_tl ,
- input-signs .tl_set:N =
- \l_@@_input_sign_tl ,
- input-uncertainty-signs .code:n =
- {
- \tl_set:Nn \l_@@_input_uncert_sign_tl {#1}
- \tl_map_inline:nn {#1}
- {
- \tl_if_in:NnF \l_@@_input_sign_tl {##1}
- { \tl_put_right:Nn \l_@@_input_sign_tl {##1} }
- }
- }
- }
-\cs_new:Npn \@@_expression:n #1 { }
-% \end{macrocode}
-% \end{macro}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_arg_tl}
-% The input argument or a part thereof, depending on the position in
-% the parsing routine.
-% \begin{macrocode}
-\tl_new:N \l_@@_arg_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_comparator_tl}
-% A comparator, if found, is held here.
-% \begin{macrocode}
-\tl_new:N \l_@@_comparator_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_exponent_tl}
-% The exponent part of a parsed number. It is easiest to find this
-% relatively early in the parsing process, but as it needs to go at
-% the end of the internal format is held separately until required.
-% \begin{macrocode}
-\tl_new:N \l_@@_exponent_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_flex_tl}
-% When parsing for a separate uncertainty or complex number, the nature
-% of the grabbed part cannot be determined until the end of the number.
-% To avoid abusing the storage areas, this dedicated one is used for
-% \enquote{flexible} cases.
-% \begin{macrocode}
-\tl_new:N \l_@@_flex_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_imaginary_tl, \l_@@_real_tl}
-% Used to hold the real and imaginary parts of a number in the standardised
-% format.
-% \begin{macrocode}
-\tl_new:N \l_@@_imaginary_tl
-\tl_new:N \l_@@_real_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_input_tl}
-% The numerical input exactly as given by the user.
-% \begin{macrocode}
-\tl_new:N \l_@@_input_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_partial_tl}
-% To avoid needing to worry about the fact that the final data stores are
-% somewhat tricky to add to token-by-token, a simple store is used to build
-% up the parsed part of a number before transferring in one go.
-% \begin{macrocode}
-\tl_new:N \l_@@_partial_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_validate_bool}
-% Used to set up for validation with no error production.
-% \begin{macrocode}
-\bool_new:N \l_@@_validate_bool
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}{\@@_parse:n}
-% After some initial set up, the parser expands the input and then replaces
-% as far as possible tricky tokens with ones that can be handled using
-% delimited arguments. The parser begins with the assumption that the input
-% is a real number. To avoid multiple conditionals here, the parser is
-% set up as a chain of commands initially, with a loop only later. This
-% avoids more conditionals than are necessary.
-% \begin{macrocode}q
-\cs_new_protected:Npn \@@_parse:n #1
- {
- \tl_clear:N \l_@@_imaginary_tl
- \tl_clear:N \l_@@_real_tl
- \protected@edef \l_@@_arg_tl
- {
- \bool_if:NTF \l_@@_expression_bool
- { \fp_eval:n { \@@_expression:n {#1} } }
- {#1}
- }
- \tl_set_eq:NN \l_@@_input_tl \l_@@_arg_tl
- \@@_parse_replace:
- \tl_if_empty:NF \l_@@_arg_tl
- { \@@_parse_comparator: }
- \@@_parse_check:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_parse_check:}
-% After the loop there is one case that might need tidying up. If a
-% separated uncertainty was found it will be currently in \cs{l_@@_flex_tl}
-% and needs moving. A series of tests pick up that case, then the check is
-% made that some content was found for at least one of the real or imaginary
-% parts of the number.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_check:
- {
- \tl_if_empty:NF \l_@@_flex_tl
- {
- \bool_lazy_and:nnTF
- {
- \tl_if_blank_p:f
- { \exp_after:wN \use_iv:nnnn \l_@@_real_tl }
- }
- {
- \tl_if_blank_p:f
- { \exp_after:wN \use_iv:nnnn \l_@@_flex_tl }
- }
- {
- \tl_set:Nx \l_@@_tmp_tl
- { \exp_after:wN \use_i:nnnn \l_@@_flex_tl }
- \tl_if_in:NVTF \l_@@_input_uncert_sign_tl
- \l_@@_tmp_tl
- { \@@_parse_combine_uncert: }
- { \tl_clear:N \l_@@_real_tl }
- }
- { \tl_clear:N \l_@@_real_tl }
- }
- \bool_lazy_and:nnTF
- { \tl_if_empty_p:N \l_@@_real_tl }
- { \tl_if_empty_p:N \l_@@_imaginary_tl }
- {
- \bool_if:NF \l_@@_validate_bool
- {
- \msg_error:nnx { siunitx } { number / invalid-input }
- { \exp_not:V \l_@@_input_tl }
- }
- }
- { \@@_parse_finalise: }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_parse_combine_uncert:}
-% \begin{macro}{\@@_parse_combine_uncert_auxi:NnnnNnnn}
-% \begin{macro}
-% {
-% \@@_parse_combine_uncert_auxii:nnnnn,
-% \@@_parse_combine_uncert_auxii:fnnnn
-% }
-% \begin{macro}
-% {
-% \@@_parse_combine_uncert_auxiii:nnnnnn,
-% \@@_parse_combine_uncert_auxiii:fnnnnn
-% }
-% \begin{macro}{\@@_parse_combine_uncert_auxiv:nnnn}
-% \begin{macro}[EXP]{\@@_parse_combine_uncert_auxv:w}
-% \begin{macro}[EXP]{\@@_parse_combine_uncert_auxvi:w}
-% Conversion of a second numerical part to an uncertainty needs a bit of
-% work. The first step is to extract the useful information from the two
-% stores: the sign, integer and decimal parts from the real number and the
-% integer and decimal parts from the second number. That is done using the
-% input stack to avoid lots of assignments.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_combine_uncert:
- {
- \exp_after:wN \exp_after:wN \exp_after:wN
- \@@_parse_combine_uncert_auxi:NnnnNnnn
- \exp_after:wN \l_@@_real_tl \l_@@_flex_tl
- }
-% \end{macrocode}
-% Here, |#4|, |#5| and |#8| are all junk arguments simply there to mop up
-% tokens, while |#1| will be recovered later from \cs{l_@@_real_tl} so does
-% not need to be passed about. The difference in places between the two
-% decimal parts is now found: this is done just once to avoid having to
-% parse token lists twice. The value is then used to generate a number of
-% filler |0| tokens, and these are added to the appropriate part of the
-% number. Finally, everything is recombined: the integer part only needs
-% a test to avoid an empty main number.
-% \begin{macrocode}
-\cs_new_protected:Npn
- \@@_parse_combine_uncert_auxi:NnnnNnnn #1#2#3#4#5#6#7#8
- {
- \int_compare:nNnTF { \tl_count:n {#6} } > { \tl_count:n {#2} }
- {
- \tl_clear:N \l_@@_real_tl
- \tl_clear:N \l_@@_flex_tl
- }
- {
- \@@_parse_combine_uncert_auxii:fnnnn
- { \int_eval:n { \tl_count:n {#3} - \tl_count:n {#7} } }
- {#2} {#3} {#6} {#7}
- }
- }
-\cs_new_protected:Npn
- \@@_parse_combine_uncert_auxii:nnnnn #1
- {
- \@@_parse_combine_uncert_auxiii:fnnnnn
- { \prg_replicate:nn { \int_abs:n {#1} } { 0 } }
- {#1}
- }
-\cs_generate_variant:Nn \@@_parse_combine_uncert_auxii:nnnnn { f }
-\cs_new_protected:Npn
- \@@_parse_combine_uncert_auxiii:nnnnnn #1#2#3#4#5#6
- {
- \int_compare:nNnTF {#2} > 0
- {
- \@@_parse_combine_uncert_auxiv:nnnn
- {#3} {#4} {#5} { #6 #1 }
- }
- {
- \@@_parse_combine_uncert_auxiv:nnnn
- {#3} { #4 #1 } {#5} {#6}
- }
- }
-\cs_generate_variant:Nn
- \@@_parse_combine_uncert_auxiii:nnnnnn { f }
-\cs_new_protected:Npn
- \@@_parse_combine_uncert_auxiv:nnnn #1#2#3#4
- {
- \tl_set:Nx \l_@@_real_tl
- {
- \tl_head:V \l_@@_real_tl
- { \exp_not:n {#1} }
- {
- \bool_lazy_and:nnTF
- { \tl_if_blank_p:n {#2} }
- { ! \tl_if_blank_p:n {#4} }
- { 0 }
- { \exp_not:n {#2} }
- }
- {
- \@@_parse_combine_uncert_auxv:w #3#4
- \q_recursion_tail \q_recursion_stop
- }
- }
- }
-% \end{macrocode}
-% A short routine to remove any leading zeros in the uncertainty part,
-% which are not needed for the compact representation used by the module.
-% \begin{macrocode}
-\cs_new:Npn \@@_parse_combine_uncert_auxv:w #1
- {
- \quark_if_recursion_tail_stop:N #1
- \str_if_eq:nnTF {#1} { 0 }
- { \@@_parse_combine_uncert_auxv:w }
- { \@@_parse_combine_uncert_auxvi:w #1 }
- }
-\cs_new:Npn \@@_parse_combine_uncert_auxvi:w
- #1 \q_recursion_tail \q_recursion_stop
- { \exp_not:n {#1} }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_parse_comparator:}
-% \begin{macro}{\@@_parse_comparator_aux:Nw}
-% A comparator has to be the very first token in the input. A such, the
-% test for this can be very fast: grab the first token, do a check and
-% if appropriate store the result.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_comparator:
- {
- \exp_after:wN \@@_parse_comparator_aux:Nw
- \l_@@_arg_tl \q_stop
- }
-\cs_new_protected:Npn \@@_parse_comparator_aux:Nw #1#2 \q_stop
- {
- \tl_if_in:NnTF \l_@@_input_comparator_tl {#1}
- {
- \tl_set:Nn \l_@@_comparator_tl {#1}
- \tl_set:Nn \l_@@_arg_tl {#2}
- }
- { \tl_clear:N \l_@@_comparator_tl }
- \tl_if_empty:NF \l_@@_arg_tl
- { \@@_parse_sign: }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_parse_exponent:}
-% \begin{macro}{\@@_parse_exponent_aux:w}
-% \begin{macro}{\@@_parse_exponent_aux:nn}
-% \begin{macro}{\@@_parse_exponent_aux:Nw}
-% \begin{macro}{\@@_parse_exponent_aux:Nn}
-% \begin{macro}
-% {\@@_parse_exponent_zero_test:N, \@@_parse_exponent_check:N}
-% \begin{macro}{\@@_parse_exponent_cleanup:N}
-% An exponent part of a number has to come at the end and can only occur
-% once. Thus it is relatively easy to parse. First, there is a check that
-% an exponent part is allowed, and if so a split is made (the previous
-% part of the chain checks that there is some content in \cs{l_@@_arg_tl}
-% before calling this function). After splitting, if there is no exponent
-% then simply save a default. Otherwise, check for a sign and then store
-% either this or an assumed |+| and the digits after a check that nothing
-% else is present after the~|e|. The only slight complication to all of
-% this is allowing an arbitrary token in the input to represent the exponent:
-% this is done by setting any exponent tokens to the first of the allowed
-% list, then using that in a delimited argument set up. Once an exponent
-% part is found, there is a loop to check that each of the tokens is a digit
-% then a tidy up step to remove any leading zeros.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_exponent:
- {
- \tl_if_empty:NTF \l_@@_input_exponent_tl
- { \tl_set:Nn \l_@@_exponent_tl { +0 } }
- {
- \tl_set:Nx \l_@@_tmp_tl
- { \tl_head:V \l_@@_input_exponent_tl }
- \tl_map_inline:Nn \l_@@_input_exponent_tl
- {
- \tl_replace_all:NnV \l_@@_arg_tl
- {##1} \l_@@_tmp_tl
- }
- \use:x
- {
- \cs_set_protected:Npn
- \exp_not:N \@@_parse_exponent_aux:w
- ####1 \exp_not:V \l_@@_tmp_tl
- ####2 \exp_not:V \l_@@_tmp_tl
- ####3 \exp_not:N \q_stop
- }
- { \@@_parse_exponent_aux:nn {##1} {##2} }
- \use:x
- {
- \@@_parse_exponent_aux:w
- \exp_not:V \l_@@_arg_tl
- \exp_not:V \l_@@_tmp_tl \exp_not:N \q_nil
- \exp_not:V \l_@@_tmp_tl \exp_not:N \q_stop
- }
- }
- }
-\cs_new_protected:Npn \@@_parse_exponent_aux:w { }
-\cs_new_protected:Npn \@@_parse_exponent_aux:nn #1#2
- {
- \quark_if_nil:nTF {#2}
- { \tl_set:Nn \l_@@_exponent_tl { +0 } }
- {
- \tl_set:Nn \l_@@_arg_tl {#1}
- \tl_if_blank:nTF {#2}
- { \tl_clear:N \l_@@_real_tl }
- { \@@_parse_exponent_aux:Nw #2 \q_stop }
- }
- \tl_if_empty:NF \l_@@_real_tl
- { \@@_parse_loop: }
- }
-\cs_new_protected:Npn \@@_parse_exponent_aux:Nw #1#2 \q_stop
- {
- \tl_if_in:NnTF \l_@@_input_sign_tl {#1}
- { \@@_parse_exponent_aux:Nn #1 {#2} }
- { \@@_parse_exponent_aux:Nn + {#1#2} }
- \tl_if_empty:NT \l_@@_exponent_tl
- { \tl_clear:N \l_@@_real_tl }
- }
-\cs_new_protected:Npn \@@_parse_exponent_aux:Nn #1#2
- {
- \tl_set:Nn \l_@@_exponent_tl { #1 }
- \tl_if_blank:nTF {#2}
- { \tl_clear:N \l_@@_real_tl }
- {
- \@@_parse_exponent_zero_test:N #2
- \q_recursion_tail \q_recursion_stop
- }
- }
-\cs_new_protected:Npn \@@_parse_exponent_zero_test:N #1
- {
- \quark_if_recursion_tail_stop_do:Nn #1
- { \tl_set:Nn \l_@@_exponent_tl { +0 } }
- \str_if_eq:nnTF {#1} { 0 }
- { \@@_parse_exponent_zero_test:N }
- { \@@_parse_exponent_check:N #1 }
- }
-\cs_new_protected:Npn \@@_parse_exponent_check:N #1
- {
- \quark_if_recursion_tail_stop:N #1
- \tl_if_in:NnTF \l_@@_input_digit_tl {#1}
- {
- \tl_put_right:Nn \l_@@_exponent_tl {#1}
- \@@_parse_exponent_check:N
- }
- { \@@_parse_exponent_cleanup:wN }
- }
-\cs_new_protected:Npn \@@_parse_exponent_cleanup:wN
- #1 \q_recursion_stop
- { \tl_clear:N \l_@@_real_tl }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_parse_replace:}
-% \begin{macro}{\@@_parse_replace_aux:nN}
-% \begin{macro}{\@@_parse_replace_sign:}
-% \begin{variable}{\c_@@_parse_sign_replacement_tl}
-% There are two parts to the replacement code. First, any active
-% hyphens signs are normalised: these can come up with some packages and
-% cause issues. Multi-token signs then are converted to the single token
-% equivalents so that everything else can work on a one token basis.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_replace:
- {
- \@@_parse_replace_minus:
- \exp_last_unbraced:NV \@@_parse_replace_aux:nN
- \c_@@_parse_sign_replacement_tl
- { ? } \q_recursion_tail
- \q_recursion_stop
- }
-\cs_set_protected:Npn \@@_parse_replace_aux:nN #1#2
- {
- \quark_if_recursion_tail_stop:N #2
- \tl_replace_all:Nnn \l_@@_arg_tl {#1} {#2}
- \@@_parse_replace_aux:nN
- }
-\tl_const:Nn \c_@@_parse_sign_replacement_tl
- {
- { -+ } \mp
- { +- } \pm
- { << } \ll
- { <= } \le
- { >> } \gg
- { >= } \ge
- }
-\group_begin:
- \char_set_catcode_active:N \-
- \cs_new_protected:Npx \@@_parse_replace_minus:
- {
- \tl_replace_all:Nnn \exp_not:N \l_@@_arg_tl
- { \exp_not:N - } { \token_to_str:N - }
- }
-\group_end:
-% \end{macrocode}
-% \end{variable}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_parse_finalise:}
-% \begin{macro}{\@@_parse_finalise_aux:N}
-% \begin{macro}{\@@_parse_finalise_aux:Nw}
-% Combine all of the bits of a number together: both the real and
-% imaginary parts contain all of the data.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_finalise:
- {
- \@@_parse_finalise_aux:N \l_@@_real_tl
- \@@_parse_finalise_aux:N \l_@@_imaginary_tl
- }
-\cs_new_protected:Npn \@@_parse_finalise_aux:N #1
- {
- \tl_if_empty:NF #1
- {
- \tl_set:Nx #1
- {
- { \exp_not:V \l_@@_comparator_tl }
- \exp_not:V #1
- \exp_after:wN \@@_parse_finalise_aux:Nw
- \l_@@_exponent_tl \q_stop
- }
- }
- }
-\cs_new:Npn \@@_parse_finalise_aux:Nw #1#2 \q_stop
- {
- \exp_not:N #1
- { \exp_not:n {#2} }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_parse_loop:}
-% \begin{macro}{\@@_parse_loop_first:N}
-% \begin{macro}{\@@_parse_loop_main:NNNNN}
-% \begin{macro}{\@@_parse_loop_main_end:NN}
-% \begin{macro}{\@@_parse_loop_main_digit:NNNNN}
-% \begin{macro}{\@@_parse_loop_main_decimal:NN}
-% \begin{macro}{\@@_parse_loop_main_uncert:NNN}
-% \begin{macro}{\@@_parse_loop_main_complex:N}
-% \begin{macro}{\@@_parse_loop_main_sign:NNN}
-% \begin{macro}{\@@_parse_loop_main_store:NNN}
-% \begin{macro}{\@@_parse_loop_after_decimal:NNN}
-% \begin{macro}{\@@_parse_loop_uncert:NNNNN}
-% \begin{macro}{\@@_parse_loop_after_uncert:NNN}
-% \begin{macro}{\@@_parse_loop_root_swap:NNwNN}
-% \begin{macro}{\@@_parse_loop_complex_cleanup:wN}
-% \begin{macro}{\@@_parse_loop_break:wN}
-% At this stage, the partial input \cs{l_@@_arg_tl} will contain any
-% mantissa, which may contain an uncertainty or complex part. Parsing this
-% and allowing for all of the different formats possible is best done using
-% a token-by-token approach. However, as at each stage only a subset of
-% tokens are valid, the approach take is to use a set of semi-dedicated
-% functions to parse different components along with switches to allow a
-% sensible amount of code sharing.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop:
- {
- \tl_clear:N \l_@@_partial_tl
- \exp_after:wN \@@_parse_loop_first:NNN
- \exp_after:wN \l_@@_real_tl \exp_after:wN \c_true_bool
- \l_@@_arg_tl
- \q_recursion_tail \q_recursion_stop
- }
-% \end{macrocode}
-% The very first token of the input is handled with a dedicated function.
-% Valid cases here are
-% \begin{itemize}
-% \item Entirely blank if the original input was for example |+e10|:
-% simply clean up if in the integer part of issue an error if in
-% a second part (complex number, \emph{etc.}).
-% \item An integer part digit: pass through to the main collection
-% routine.
-% \item A decimal marker: store an empty integer part and move to
-% the main collection routine for a decimal part.
-% \item A complex root token: shuffle to the end of the input.
-% \end{itemize}
-% Anything else is invalid and sends the code to the abort function.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_first:NNN #1#2#3
- {
- \quark_if_recursion_tail_stop_do:Nn #3
- {
- \bool_if:NTF #2
- { \tl_put_right:Nn #1 { { 1 } { } { } } }
- { \@@_parse_loop_break:wN \q_recursion_stop }
- }
- \tl_if_in:NnTF \l_@@_input_digit_tl {#3}
- {
- \@@_parse_loop_main:NNNNN
- #1 \c_true_bool \c_false_bool #2 #3
- }
- {
- \tl_if_in:NnTF \l_@@_input_decimal_tl {#3}
- {
- \tl_put_right:Nn #1 { { 0 } }
- \@@_parse_loop_after_decimal:NNN #1 #2
- }
- {
- \tl_if_in:NnTF \l_@@_input_complex_tl {#3}
- { \@@_parse_loop_root_swap:NNwNN #1 #3 }
- { \@@_parse_loop_break:wN }
- }
- }
- }
-% \end{macrocode}
-% A single function is used to cover the \enquote{main} part of numbers:
-% finding real, complex or separated uncertainty parts and covering both
-% the integer and decimal components. This works because these elements
-% share a lot of concepts: a small number of switches can be used to
-% differentiate between them. To keep the code at least somewhat readable,
-% this main function deals with the validity testing but hands off other
-% tasks to dedicated auxiliaries for each case.
-%
-% The possibilities are
-% \begin{itemize}
-% \item The number terminates, meaning that some digits were collected
-% and everything is simply tidied up (as far as the loop is concerned).
-% \item A digit is found: this is the common case and leads to a storage
-% auxiliary (which handles non-significant zeros).
-% \item A decimal marker is found: only valid in the integer part and
-% there leading to a store-and-switch situation.
-% \item An open-uncertainty token: switch to the dedicated collector
-% for uncertainties.
-% \item A complex root token: store the current number as an imaginary
-% part and terminate the loop.
-% \item A sign token (if allowed): stop collecting this number and
-% restart collection for the second part.
-% \end{itemize}
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_main:NNNNN #1#2#3#4#5
- {
- \quark_if_recursion_tail_stop_do:Nn #5
- { \@@_parse_loop_main_end:NN #1#2 }
- \tl_if_in:NnTF \l_@@_input_digit_tl {#5}
- { \@@_parse_loop_main_digit:NNNNN #1#2#3#4#5 }
- {
- \tl_if_in:NnTF \l_@@_input_decimal_tl {#5}
- {
- \bool_if:NTF #2
- { \@@_parse_loop_main_decimal:NN #1 #4 }
- { \@@_parse_loop_break:wN }
- }
- {
- \tl_if_in:NnTF \l_@@_input_uncert_open_tl {#5}
- { \@@_parse_loop_main_uncert:NNN #1#2 #4 }
- {
- \tl_if_in:NnTF \l_@@_input_complex_tl {#5}
- {
- \@@_parse_loop_main_store:NNN
- #1 #2 \c_true_bool
- \@@_parse_loop_main_complex:N #1
- }
- {
- \bool_if:NTF #4
- {
- \tl_if_in:NnTF \l_@@_input_sign_tl {#5}
- {
- \@@_parse_loop_main_sign:NNN
- #1#2 #5
- }
- { \@@_parse_loop_break:wN }
- }
- { \@@_parse_loop_break:wN }
- }
- }
- }
- }
- }
-% \end{macrocode}
-% If the main loop finds the end marker then there is a tidy up phase.
-% The current partial number is stored either as the integer or decimal,
-% depending on the setting for the indicator switch. For the integer
-% part, if no number has been collected then one or more non-significant
-% zeros have been dropped. Exactly one zero is therefore needed to make
-% sure the parsed result is correct.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_main_end:NN #1#2
- {
- \bool_lazy_and:nnT
- {#2} { \tl_if_empty_p:N \l_@@_partial_tl }
- { \tl_set:Nn \l_@@_partial_tl { 0 } }
- \tl_put_right:Nx #1
- {
- { \exp_not:V \l_@@_partial_tl }
- \bool_if:NT #2 { { } }
- { }
- }
- }
-% \end{macrocode}
-% The most common case for the main loop collector is to find a digit.
-% Here, in the integer part it is possible that zeros are non-significant:
-% that is handled using a combination of a switch and a string test. Other
-% than that, the situation here is simple: store the input and loop.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_main_digit:NNNNN #1#2#3#4#5
- {
- \bool_lazy_or:nnTF
- {#3} { ! \str_if_eq_p:nn {#5} { 0 } }
- {
- \tl_put_right:Nn \l_@@_partial_tl {#5}
- \@@_parse_loop_main:NNNNN #1 #2 \c_true_bool #4
- }
- { \@@_parse_loop_main:NNNNN #1 #2 \c_false_bool #4 }
- }
-% \end{macrocode}
-% When a decimal marker was found, move the integer part to the
-% store and then go back to the loop with the flags set correctly.
-% There is the case of non-significant zeros to cover before that, of course.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_main_decimal:NN #1#2
- {
- \@@_parse_loop_main_store:NNN #1 \c_false_bool \c_false_bool
- \@@_parse_loop_after_decimal:NNN #1 #2
- }
-% \end{macrocode}
-% Starting an uncertainty part means storing the number to date as in other
-% cases, with the possibility of a blank decimal part allowed for. The
-% uncertainty itself is collected by a dedicated function as it is extremely
-% restricted.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_main_uncert:NNN #1#2#3
- {
- \@@_parse_loop_main_store:NNN #1 #2 \c_false_bool
- \@@_parse_loop_uncert:NNNNN
- #1 \c_true_bool \c_false_bool #3
- }
-% \end{macrocode}
-% A complex root token has to be at the end of the input (leading ones
-% are dealt with specially). Thus after moving the data to the correct
-% place there is a hand-off to a cleanup function. The case where only the
-% complex root token was given is covered by
-% \cs{@@_parse_loop_root_swap:NNwNN}.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_main_complex:N #1
- {
- \tl_set_eq:NN \l_@@_imaginary_tl #1
- \tl_clear:N #1
- \@@_parse_loop_complex_cleanup:wN
- }
-% \end{macrocode}
-% If a sign is found, terminate the current number, store the sign as the
-% first token of the second part and go back to do the dedicated first-token
-% function.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_main_sign:NNN #1#2#3
- {
- \@@_parse_loop_main_store:NNN #1 #2 \c_true_bool
- \tl_set:Nn \l_@@_flex_tl {#3}
- \@@_parse_loop_first:NNN
- \l_@@_flex_tl \c_false_bool
- }
-% \end{macrocode}
-% A common auxiliary for the various non-digit token functions: tidy up the
-% integer and decimal parts of a number. Here, the two flags are used to
-% indicate if empty decimal and uncertainty parts should be included in
-% the storage cycle.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_main_store:NNN #1#2#3
- {
- \tl_if_empty:NT \l_@@_partial_tl
- { \tl_set:Nn \l_@@_partial_tl { 0 } }
- \tl_put_right:Nx #1
- {
- { \exp_not:V \l_@@_partial_tl }
- \bool_if:NT #2 { { } }
- \bool_if:NT #3 { { } }
- }
- \tl_clear:N \l_@@_partial_tl
- }
-% \end{macrocode}
-% After a decimal marker there has to be a digit if there wasn't one before
-% it. That is handled by using a dedicated function, which checks for
-% an empty integer part first then either simply hands off or looks for
-% a digit.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_after_decimal:NNN #1#2#3
- {
- \tl_if_blank:fTF { \exp_after:wN \use_none:n #1 }
- {
- \quark_if_recursion_tail_stop_do:Nn #3
- { \@@_parse_loop_break:wN \q_recursion_stop }
- \tl_if_in:NnTF \l_@@_input_digit_tl {#1}
- {
- \tl_put_right:Nn \l_@@_partial_tl {#3}
- \@@_parse_loop_main:NNNNN
- #1 \c_false_bool \c_true_bool #2
- }
- { \@@_parse_loop_break:wN }
- }
- {
- \@@_parse_loop_main:NNNNN
- #1 \c_false_bool \c_true_bool #2 #3
- }
- }
-% \end{macrocode}
-% Inside the brackets for an uncertainty the range of valid choices is
-% very limited. Either the token is a digit, in which case there is a
-% test to look for non-significant zeros, or it is a closing bracket. The
-% latter is not valid for the very first token, which is handled using a
-% switch (it's a simple enough difference).
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_uncert:NNNNN #1#2#3#4#5
- {
- \quark_if_recursion_tail_stop_do:Nn #5
- { \@@_parse_loop_break:wN \q_recursion_stop }
- \tl_if_in:NnTF \l_@@_input_digit_tl {#5}
- {
- \bool_lazy_or:nnTF
- {#3} { ! \str_if_eq_p:nn {#5} { 0 } }
- {
- \tl_put_right:Nn \l_@@_partial_tl {#5}
- \@@_parse_loop_uncert:NNNNN
- #1 \c_false_bool \c_true_bool #4
- }
- {
- \@@_parse_loop_uncert:NNNNN
- #1 \c_false_bool \c_false_bool #4
- }
- }
- {
- \tl_if_in:NnTF \l_@@_input_uncert_close_tl {#5}
- {
- \bool_if:NTF #2
- { \@@_parse_loop_break:wN }
- {
- \@@_parse_loop_main_store:NNN #1
- \c_false_bool \c_false_bool
- \@@_parse_loop_after_uncert:NNN #1 #3
- }
- }
- { \@@_parse_loop_break:wN }
- }
- }
-% \end{macrocode}
-% After a bracketed uncertainty there are only a very small number of
-% valid choices. The number can end, there can be a complex root token
-% or there can be a sign. The latter is only allowed if the part being
-% parsed at the moment was the first part of the number. The case where
-% there is no root symbol but there should have been is cleared up after
-% the loop code, so at this stage there is no check.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_after_uncert:NNN #1#2#3
- {
- \quark_if_recursion_tail_stop:N #3
- \tl_if_in:NnTF \l_@@_input_complex_tl {#3}
- { \@@_parse_loop_main_complex:N #1 }
- {
- \bool_if:NTF #2
- {
- \tl_if_in:NnTF \l_@@_input_sign_tl {#3}
- {
- \tl_set:Nn \l_@@_flex_tl {#3}
- \@@_parse_loop_first:NNN
- \l_@@_flex_tl \c_false_bool
- }
- { \@@_parse_loop_break:wN }
- }
- { \@@_parse_loop_break:wN }
- }
- }
-% \end{macrocode}
-% When the complex root symbol comes at the start of the number rather than
-% at the end, the easiest approach is to shuffle it to the \enquote{normal}
-% position. As the exponent has already been removed, this must be the last
-% token of the input and any duplication will be picked up. The case where
-% just a complex root token has to be covered: in that situation, there is
-% an implicit |1| to store after which the loop stops.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_root_swap:NNwNN #1#2#3
- \q_recursion_tail \q_recursion_stop
- {
- \tl_if_blank:nTF {#3}
- {
- \tl_set:Nx \l_@@_imaginary_tl
- {
- \exp_not:V #1
- { 1 } { } { }
- }
- \tl_clear:N #1
- }
- {
- \use:x
- {
- \tl_clear:N \exp_not:N #1
- \tl_set:Nn \exp_not:N \l_@@_flex_tl { \exp_not:V #1 }
- }
- \@@_parse_loop_first:NNN
- \l_@@_flex_tl \c_false_bool
- #3 #2 \q_recursion_tail \q_recursion_stop
- }
- }
-% \end{macrocode}
-% Nothing is allowed after a complex root token: check and if there is
-% kill the parsing.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_complex_cleanup:wN
- #1 \q_recursion_tail \q_recursion_stop
- {
- \tl_if_blank:nF {#1}
- { \@@_parse_loop_break:wN \q_recursion_stop }
- }
-% \end{macrocode}
-% Something is not right: remove all of the remaining tokens from the
-% number and clear the storage areas as a signal for the next part of the
-% code.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_loop_break:wN
- #1 \q_recursion_stop
- {
- \tl_clear:N \l_@@_imaginary_tl
- \tl_clear:N \l_@@_flex_tl
- \tl_clear:N \l_@@_real_tl
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_parse_sign:}
-% \begin{macro}{\@@_parse_sign_aux:Nw}
-% The first token of a number after a comparator could be a sign. A quick
-% check is made and if found stored; if there is no sign then the internal
-% format requires that |+| is used. For the number to be valid it has to be
-% more than just a sign, so the next part of the chain is only called if that
-% is the case.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_sign:
- {
- \exp_after:wN \@@_parse_sign_aux:Nw
- \l_@@_arg_tl \q_stop
- }
-\cs_new_protected:Npn \@@_parse_sign_aux:Nw #1#2 \q_stop
- {
- \tl_if_in:NnTF \l_@@_input_sign_tl {#1}
- {
- \tl_set:Nn \l_@@_arg_tl {#2}
- \tl_set:Nn \l_@@_real_tl {#1}
- }
- { \tl_set:Nn \l_@@_real_tl { + } }
- \tl_if_empty:NTF \l_@@_arg_tl
- { \tl_clear:N \l_@@_real_tl }
- { \@@_parse_exponent: }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \subsection{Processing numbers}
-%
-% \begin{variable}
-% {
-% \l_@@_round_half_up_bool ,
-% \l_@@_round_min_tl ,
-% \l_@@_round_mode_tl ,
-% \l_@@_round_precision_int
-% }
-% \begin{macrocode}
-\keys_define:nn { siunitx }
- {
- round-half .choice: ,
- round-half / even .code:n =
- { \bool_set_false:N \l_@@_round_half_up_bool } ,
- round-half / up .code:n =
- { \bool_set_true:N \l_@@_round_half_up_bool } ,
- round-minimum .tl_set:N =
- \l_@@_round_min_tl ,
- round-mode .choice: ,
- round-mode / figures .code:n =
- { \tl_set:Nn \_@@_round_mode_tl { figures } } ,
- round-mode / none .code:n =
- { \tl_set:Nn \_@@_round_mode_tl { none } } ,
- round-mode / places .code:n =
- { \tl_set:Nn \_@@_round_mode_tl { places } } ,
- round-mode / uncertainty .code:n =
- { \tl_set:Nn \_@@_round_mode_tl { uncertainty } } ,
- round-precision .int_set:N =
- \l_@@_round_precision_int ,
- }
-\bool_new:N \l_@@_round_half_up_bool
-\tl_new:N \_@@_round_mode_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}{\@@_round:}
-% \begin{macro}{\@@_round:N}
-% \begin{macro}{\@@_round_none:nNnnnNn}
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_round:
- {
- \@@_round:N \l_@@_real_tl
- \@@_round:N \l_@@_imaginary_tl
- }
-\cs_new_protected:Npn \@@_round:N #1
- {
- \tl_if_empty:NF #1
- {
- \tl_set:Nx #1
- {
- \cs:w
- @@_round_ \_@@_round_mode_tl :nNnnnNn
- \exp_after:wN
- \cs_end: #1
- }
- }
- }
-\cs_new:Npn \@@_round_none:nNnnnNn #1#2#3#4#5#6#7
- { \exp_not:n { {#1} #2 {#3} {#4} {#5} #6 {#7} } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_round_figures:nNnnnNn}
-% \begin{macrocode}
-\cs_new:Npn \@@_round_figures:nNnnnNn #1#2#3#4#5#6#7
- {
- \tl_if_blank:nTF {#5}
- {
- \int_compare:nNnTF \l_@@_round_precision_int > 0
- { }
- { { } + { 0 } { } { } + { 0 } }
- }
- { \exp_not:n { {#1} #2 {#3} {#4} {#5} #6 {#7} } }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_round_places:nNnnnNn}
-% \begin{macro}[EXP]
-% {\@@_round_places_decimal:nNnnNn, \@@_round_places_integer:nNnnNn}
-% The first step when rounding to a fixed number of places is to establish
-% if this is in the decimal or integer parts. The two require different
-% calculations for how many digits to drop from the input.
-% \begin{macrocode}
-\cs_new:Npn \@@_round_places:nNnnnNn #1#2#3#4#5#6#7
- {
- \tl_if_blank:nTF {#5}
- {
- \int_compare:nNnTF \l_@@_round_precision_int > 0
- { \@@_round_places_decimal:nNnnNn }
- { \@@_round_places_integer:nNnnNn }
- {#1} #2 {#3} {#4} #6 {#7}
- }
- { \exp_not:n { {#1} #2 {#3} {#4} {#5} #6 {#7} } }
- }
-\cs_new:Npn \@@_round_places_decimal:nNnnNn #1#2#3#4#5#6
- { }
-\cs_new:Npn \@@_round_places_integer:nNnnNn #1#2#3#4#5#6
- { }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_round_uncertainty:nNnnnNn}
-% \begin{macrocode}
-\cs_new:Npn \@@_round_uncertainty:nNnnnNn #1#2#3#4#5#6#7
- {
- \tl_if_blank:nTF {#5}
- { \exp_not:n { {#1} #2 {#3} {#4} { } #6 {#7} } }
- { }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Formatting parsed numbers}
-%
-% \begin{variable}
-% {
-% \l_@@_bracket_negative_bool ,
-% \l_@@_bracket_close_tl ,
-% \l_@@_explicit_plus_bool ,
-% \l_@@_exponent_base_tl ,
-% \l_@@_exponent_product_tl ,
-% \l_@@_group_decimal_bool ,
-% \l_@@_group_integer_bool ,
-% \l_@@_group_minimum_int ,
-% \l_@@_group_separator_tl ,
-% \l_@@_negative_color_tl ,
-% \l_@@_bracket_open_tl ,
-% \l_@@_output_uncert_close_tl ,
-% \l_@@_output_complex_tl ,
-% \l_@@_output_decimal_tl ,
-% \l_@@_output_uncert_open_tl ,
-% \l_@@_uncert_separate_bool ,
-% \l_@@_tight_bool ,
-% \l_@@_unity_mantissa_bool ,
-% \l_@@_zero_exponent_bool
-% }
-% Keys producing tokens in the output.
-% \begin{macrocode}
-\keys_define:nn { siunitx }
- {
- bracket-negative .bool_set:N =
- \l_@@_bracket_negative_bool ,
- explicit-plus .bool_set:N =
- \l_@@_explicit_plus_bool ,
- exponent-base .tl_set:N =
- \l_@@_exponent_base_tl ,
- exponent-product .tl_set:N =
- \l_@@_exponent_product_tl ,
- group-digits .choice: ,
- group-digits / all .code:n =
- {
- \bool_set_true:N \l_@@_group_decimal_bool
- \bool_set_true:N \l_@@_group_integer_bool
- } ,
- group-digits / decimal .code:n =
- {
- \bool_set_true:N \l_@@_group_decimal_bool
- \bool_set_false:N \l_@@_group_integer_bool
- } ,
- group-digits / integer .code:n =
- {
- \bool_set_false:N \l_@@_group_decimal_bool
- \bool_set_true:N \l_@@_group_integer_bool
- } ,
- group-digits / none .code:n =
- {
- \bool_set_false:N \l_@@_group_decimal_bool
- \bool_set_false:N \l_@@_group_integer_bool
- } ,
- group-digits .default:n = all ,
- group-minimum-digits .int_set:N =
- \l_@@_group_minimum_int ,
- group-separator .tl_set:N =
- \l_@@_group_separator_tl ,
- negative-color .tl_set:N =
- \l_@@_negative_color_tl ,
- number-close-bracket .tl_set:N =
- \l_@@_bracket_close_tl ,
- number-open-bracket .tl_set:N =
- \l_@@_bracket_open_tl ,
- output-close-uncertainty .tl_set:N =
- \l_@@_output_uncert_close_tl ,
- output-complex-root .tl_set:N =
- \l_@@_output_complex_tl ,
- output-decimal-marker .tl_set:N =
- \l_@@_output_decimal_tl ,
- output-open-uncertainty .tl_set:N =
- \l_@@_output_uncert_open_tl ,
- separate-uncertainty .bool_set:N =
- \l_@@_uncert_separate_bool ,
- tight-spacing .bool_set:N =
- \l_@@_tight_bool ,
- unity-mantissa .bool_set:N =
- \l_@@_unity_mantissa_bool ,
- zero-exponent .bool_set:N =
- \l_@@_zero_exponent_bool ,
- }
-\bool_new:N \l_@@_group_decimal_bool
-\bool_new:N \l_@@_group_integer_bool
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}{\@@_format:}
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_format:
- {
- \tl_set:Nx \l_@@_formatted_tl
- {
- \tl_if_empty:NTF \l_@@_real_tl
- {
- \tl_if_empty:NF \l_@@_imaginary_tl
- { \@@_format:N \l_@@_imaginary_tl }
- }
- {
- \tl_if_empty:NTF \l_@@_imaginary_tl
- { \@@_format:N \l_@@_real_tl }
- { ??? }
- }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_format:N}
-% \begin{macro}[EXP]{\@@_format:nNnnnNn}
-% \begin{macro}[EXP]{\@@_format_comparator:n}
-% \begin{macro}[EXP]{\@@_format_sign:N, \@@_format_sign_aux:N}
-% \begin{macro}[EXP]
-% {\@@_format_sign_color:w, \@@_format_sign_brackets:w}
-% \begin{macro}[EXP]{\@@_format_integer:nnn}
-% \begin{macro}[EXP]{\@@_format_decimal:n, \@@_format_decimal:f}
-% \begin{macro}[EXP]{\@@_format_digits:nn}
-% \begin{macro}[EXP]{\@@_format_integer_aux:n}
-% \begin{macro}[EXP]
-% {
-% \@@_format_integer_aux_0:n,
-% \@@_format_integer_aux_1:n,
-% \@@_format_integer_aux_2:n
-% }
-% \begin{macro}[EXP]{\@@_format_decimal_aux:n}
-% \begin{macro}[EXP]{\@@_format_decimal_loop:NNNN}
-% \begin{macro}[EXP]{\@@_format_integer_first:nnNN}
-% \begin{macro}[EXP]{\@@_format_integer_loop:NNNN}
-% \begin{macro}[EXP]{\@@_format_uncertainty:nn}
-% \begin{macro}[EXP]{\@@_format_uncertainty_unaligned:}
-% \begin{macro}[EXP]
-% {\@@_format_uncertainty_aux:nn, \@@_format_uncertainty_aux:fn}
-% \begin{macro}[EXP]
-% {\@@_format_uncertainty:nnw, \@@_format_uncertainty:fnw}
-% \begin{macro}[EXP]{\@@_format_uncertainty:nw}
-% \begin{macro}[EXP]{\@@_format_exponent:Nnn}
-% \begin{macro}[EXP]{\@@_format_end:}
-% The approach to formatting a single number is to split into
-% the constituent parts. All of the parts are assembled including
-% inserting tabular alignment markers (which may be empty) for each
-% separate unit.
-% \begin{macrocode}
-\cs_new:Npn \@@_format:N #1
- { \exp_after:wN \@@_format:nNnnnNn #1 }
-\cs_new:Npn \@@_format:nNnnnNn #1#2#3#4#5#6#7
- {
- \@@_format_comparator:n {#1}
- \@@_format_sign:N #2
- \@@_format_integer:nnn {#3} {#4} {#7}
- \@@_format_decimal:n {#4}
- \@@_format_uncertainty:nn {#5} {#4}
- \@@_format_exponent:Nnn #6 {#7} { #3 . #4 }
- \@@_format_end:
- }
-% \end{macrocode}
-% To get the spacing correct this needs to be an ordinary math character.
-% \begin{macrocode}
-\cs_new:Npn \@@_format_comparator:n #1
- {
- \tl_if_blank:nF {#1}
- { \exp_not:n { \mathord {#1} } }
- \exp_not:V \l_@@_tab_tl
- }
-% \end{macrocode}
-% Formatting signs has to deal with some additional formatting requirements
-% for negative numbers. Both making such numbers a fixed color and bracketing
-% them needs some rearrangement of the order of tokens, which is set up in
-% the main formatting macro by the dedicated do-nothing end function.
-% \begin{macrocode}
-\cs_new:Npn \@@_format_sign:N #1
- {
- \str_if_eq:nnTF {#1} { + }
- {
- \bool_if:NT \l_@@_explicit_plus_bool
- { \@@_format_sign_aux:N #1 }
- }
- {
- \str_if_eq:nnTF {#1} { - }
- {
- \tl_if_empty:NF \l_@@_negative_color_tl
- { \@@_format_sign_color:w }
- \bool_if:NTF \l_@@_bracket_negative_bool
- { \@@_format_sign_brackets:w }
- { \@@_format_sign_aux:N #1 }
- }
- { \@@_format_sign_aux:N #1 }
- }
- }
-\cs_new:Npn \@@_format_sign_aux:N #1
- {
- \bool_if:NTF \l_@@_tight_bool
- { \exp_not:n { \mathord {#1} } }
- { \exp_not:n {#1} }
- }
-\cs_new:Npn
- \@@_format_sign_color:w #1 \@@_format_end:
- {
- \exp_not:N \textcolor { \exp_not:V \l_@@_negative_color_tl }
- {
- #1
- \@@_format_end:
- }
- }
-\cs_new:Npn
- \@@_format_sign_brackets:w #1 \@@_format_end:
- {
- \exp_not:V \l_@@_bracket_open_tl
- #1
- \exp_not:V \l_@@_bracket_close_tl
- \@@_format_end:
- }
-% \end{macrocode}
-% Digit formatting leads off with separate functions to allow for a few
-% \enquote{up front} items before using a common set of tests for some common
-% cases. The code then splits again as the two types of grouping need
-% different strategies.
-% \begin{macrocode}
-\cs_new:Npn \@@_format_integer:nnn #1#2#3
- {
- \bool_lazy_all:nF
- {
- { \str_if_eq_p:nn {#1} { 1 } }
- { \tl_if_blank_p:n {#2} }
- { ! \str_if_eq_p:nn {#3} { 0 } }
- { ! \l_@@_unity_mantissa_bool }
- }
- { \@@_format_digits:nn { integer } {#1} }
- }
-\cs_new:Npn \@@_format_decimal:n #1
- {
- \exp_not:V \l_@@_tab_tl
- \tl_if_blank:nF {#1}
- { \exp_not:V \l_@@_output_decimal_tl }
- \exp_not:V \l_@@_tab_tl
- \@@_format_digits:nn { decimal } {#1}
- }
-\cs_generate_variant:Nn \@@_format_decimal:n { f }
-\cs_new:Npn \@@_format_digits:nn #1#2
- {
- \bool_if:cTF { l_@@_group_ #1 _ bool }
- {
- \int_compare:nNnTF
- { \tl_count:n {#2} } < \l_@@_group_minimum_int
- { \exp_not:n {#2} }
- { \use:c { @@_format_ #1 _aux:n } {#2} }
- }
- { \exp_not:n {#2} }
- }
-% \end{macrocode}
-% For integers, we need to know how many digits there are to allow for the
-% correct insertion of separators. That is done using a two-part set up such
-% that there is no separator on the first pass.
-% \begin{macrocode}
-\cs_new:Npn \@@_format_integer_aux:n #1
- {
- \use:c
- {
- @@_format_integer_aux_
- \int_eval:n { \int_mod:nn { \tl_count:n {#1} } { 3 } }
- :n
- } {#1}
- }
-\cs_new:cpn { @@_format_integer_aux_0:n } #1
- { \@@_format_integer_first:nnNN #1 \q_nil }
-\cs_new:cpn { @@_format_integer_aux_1:n } #1
- { \@@_format_integer_first:nnNN { } { } #1 \q_nil }
-\cs_new:cpn { @@_format_integer_aux_2:n } #1
- { \@@_format_integer_first:nnNN { } #1 \q_nil }
-\cs_new:Npn \@@_format_integer_first:nnNN #1#2#3#4
- {
- \exp_not:n {#1#2#3}
- \quark_if_nil:NF #4
- { \@@_format_integer_loop:NNNN #4 }
- }
-\cs_new:Npn \@@_format_integer_loop:NNNN #1#2#3#4
- {
- \exp_not:V \l_@@_group_separator_tl
- \exp_not:n {#1#2#3}
- \quark_if_nil:NF #4
- { \@@_format_integer_loop:NNNN #4 }
- }
-% \end{macrocode}
-% For decimals, no need to do any counting, just loop using enough markers to
-% find the end of the list. By passing the decimal marker, it is possible not
-% to have to use a check on the content of the rest of the number. The
-% |\use_none:n(n)| mop up the remaining |\q_nil| tokens.
-% \begin{macrocode}
-\cs_new:Npn \@@_format_decimal_aux:n #1
- {
- \@@_format_decimal_loop:NNNN \c_empty_tl
- #1 \q_nil \q_nil \q_nil
- }
-\cs_new:Npn \@@_format_decimal_loop:NNNN #1#2#3#4
- {
- \quark_if_nil:NF #2
- {
- \exp_not:V #1
- \exp_not:n {#2}
- \quark_if_nil:NTF #3
- { \use_none:n }
- {
- \exp_not:n {#3}
- \quark_if_nil:NTF #4
- { \use_none:nn }
- {
- \exp_not:n {#4}
- \@@_format_decimal_loop:NNNN
- \l_@@_group_separator_tl
- }
- }
- }
- }
-% \end{macrocode}
-% Uncertainties which are directly attached are easy to deal with. For those
-% that are separated, the first step is to find if they are entirely
-% contained within the decimal part, and to pad if they are. For the case
-% where the boundary is crossed to the integer part, the correct number of
-% digit tokens need to be removed from the start of the uncertainty and
-% the split result sent to the appropriate auxiliaries.
-% \begin{macrocode}
-\cs_new:Npn \@@_format_uncertainty:nn #1#2
- {
- \tl_if_blank:nTF {#1}
- { \@@_format_uncertainty_unaligned: }
- {
- \bool_if:NTF \l_@@_uncert_separate_bool
- {
- \exp_not:V \l_@@_tab_tl
- \@@_format_sign_aux:N \pm
- \exp_not:V \l_@@_tab_tl
- \@@_format_uncertainty_aux:fn
- { \int_eval:n { \tl_count:n {#1} - \tl_count:n {#2} } }
- {#1}
- }
- {
- \exp_not:V \l_@@_output_uncert_open_tl
- \exp_not:n {#1}
- \exp_not:V \l_@@_output_uncert_close_tl
- \@@_format_uncertainty_unaligned:
- }
- }
- }
-\cs_new:Npn \@@_format_uncertainty_unaligned:
- {
- \exp_not:V \l_@@_tab_tl
- \exp_not:V \l_@@_tab_tl
- \exp_not:V \l_@@_tab_tl
- \exp_not:V \l_@@_tab_tl
- }
-\cs_new:Npn \@@_format_uncertainty_aux:nn #1#2
- {
- \int_compare:nNnTF {#1} > 0
- {
- \@@_format_uncertainty_aux:fnw
- { \int_eval:n { #1 - 1 } }
- { }
- #2 \q_nil
- }
- {
- 0
- \@@_format_decimal:f
- {
- \prg_replicate:nn { \int_abs:n {#1} } { 0 }
- #2
- }
- }
- }
-\cs_generate_variant:Nn \@@_format_uncertainty_aux:nn { f }
-\cs_new:Npn \@@_format_uncertainty_aux:nnw #1#2#3
- {
- \quark_if_nil:NF #3
- {
- \int_compare:nNnTF {#1} = 0
- { \@@_format_uncertainty_aux:nw {#2#3} }
- {
- \@@_format_uncertainty_aux:fnw
- { \int_eval:n { #1 - 1 } }
- {#2#3}
- }
- }
- }
-\cs_generate_variant:Nn \@@_format_uncertainty_aux:nnw { f }
-\cs_new:Npn \@@_format_uncertainty_aux:nw #1#2 \q_nil
- {
- \@@_format_digits:nn { integer } {#1}
- \@@_format_decimal:n {#2}
- }
-% \end{macrocode}
-% Setting the exponent part requires some information about the mantissa:
-% was it there or not. This means that whilst only the sign and value for
-% the exponent are typeset here, there is a need to also have access to the
-% combined mantissa part (with a decimal marker). The rest of the work is
-% about picking up the various options and getting the combinations right.
-% For signs, the auxiliary from the main sign routine can be used, but not
-% the main function: negative exponents don't have special handling.
-% \begin{macrocode}
-\cs_new:Npn \@@_format_exponent:Nnn #1#2#3
- {
- \exp_not:V \l_@@_tab_tl
- \bool_lazy_or:nnTF
- { \l_@@_zero_exponent_bool }
- { ! \str_if_eq_p:nn {#2} { 0 } }
- {
- \bool_lazy_and:nnTF
- { \str_if_eq_p:nn {#3} { 1. } }
- { ! \l_@@_unity_mantissa_bool }
- { \exp_not:V \l_@@_tab_tl }
- {
- \bool_if:NTF \l_@@_tight_bool
- {
- \exp_not:N \mathord
- { \exp_not:V \l_@@_exponent_product_tl }
- }
- { \exp_not:V \l_@@_exponent_product_tl }
- \exp_not:V \l_@@_tab_tl
- }
- \exp_not:V \l_@@_exponent_base_tl
- ^
- {
- \bool_lazy_or:nnT
- { \l_@@_explicit_plus_bool }
- { ! \str_if_eq_p:nn {#1} { + } }
- { \@@_format_sign_aux:N #1 }
- \@@_format_digits:nn { integer } {#2}
- }
- }
- { \exp_not:V \l_@@_tab_tl }
- }
-% \end{macrocode}
-% A do-nothing marker used to allow shuffling of the output and so expandable
-% operations for formatting.
-% \begin{macrocode}
-\cs_new:Npn \@@_format_end: { }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \subsection{Miscellaneous tools}
-%
-% \begin{variable}{\l_@@_valid_tl}
-% The list of valid tokens.
-% \begin{macrocode}
-\tl_new:N \l_@@_valid_tl
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}[TF]{\siunitx_if_number:n}
-% Test if an entire number is valid: this means parsing the number but not
-% returning anything.
-% \begin{macrocode}
-\prg_new_protected_conditional:Npnn \siunitx_if_number:n #1
- { T , F , TF }
- {
- \group_begin:
- \bool_set_true:N \l_@@_validate_bool
- \@@_parse:n {#1}
- \bool_lazy_and:nnTF
- { \tl_if_empty_p:N \l_@@_real_tl }
- { \tl_if_empty_p:N \l_@@_imaginary_tl }
- {
- \group_end:
- \prg_return_false:
- }
- {
- \group_end:
- \prg_return_true:
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[TF]{\siunitx_if_number_token:N}
-% A simple conditional to answer the question of whether a specific token is
-% possibly valid in a number.
-% \begin{macrocode}
-\prg_new_protected_conditional:Npnn \siunitx_if_number_token:N #1
- { T , F , TF }
- {
- \tl_set:Nx \l_@@_valid_tl
- {
- \exp_not:V \l_@@_input_uncert_close_tl
- \exp_not:V \l_@@_input_complex_tl
- \exp_not:V \l_@@_input_comparator_tl
- \exp_not:V \l_@@_input_decimal_tl
- \exp_not:V \l_@@_input_digit_tl
- \exp_not:V \l_@@_input_exponent_tl
- \exp_not:V \l_@@_input_ignore_tl
- \exp_not:V \l_@@_input_uncert_open_tl
- \exp_not:V \l_@@_input_sign_tl
- \exp_not:V \l_@@_input_uncert_sign_tl
- }
- \tl_if_in:VnTF \l_@@_valid_tl {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Messages}
-%
-% \begin{macrocode}
-\msg_new:nnnn { siunitx } { number / invalid-input }
- { Invalid~number~'#1'. }
- {
- The~input~'#1'~could~not~be~parsed~as~a~number~following~the~
- format~defined~in~module~documentation.
- }
-% \end{macrocode}
-%
-% \subsection{Standard settings for module options}
-%
-% Some of these follow naturally from the point of definition
-% (\emph{e.g.}~boolean variables are always |false| to begin with),
-% but for clarity everything is set here.
-% \begin{macrocode}
-\keys_set:nn { siunitx }
- {
- bracket-negative = false ,
- evaluate-expression = false ,
- explicit-plus = false ,
- exponent-base = 10 ,
- exponent-product = \times ,
- expression = #1 ,
- group-digits = all ,
- group-minimum-digits = 4 ,
- group-separator = \, , % (
- input-close-uncertainty = ) ,
- input-complex-roots = ij ,
- input-comparators = { <=>\approx\ge\geq\gg\le\leq\ll\sim } ,
- input-decimal-markers = { ., } ,
- input-digits = 0123456789 ,
- input-exponent-markers = dDeE ,
- input-ignore = \, ,
- input-open-uncertainty = ( , % )
- input-signs = +-\mp\pm ,
- input-uncertainty-signs = \pm ,
- negative-color = , % (
- number-close-bracket = ) ,
- number-open-bracket = ( , % )
- output-close-uncertainty = ) ,
- output-complex-root = \mathrm { i } ,
- output-decimal-marker = . ,
- output-open-uncertainty = ( , % )
- round-half = up ,
- round-minimum = 0 ,
- round-mode = none ,
- round-precision = 2 ,
- separate-uncertainty = false ,
- tight-spacing = false ,
- unity-mantissa = false ,
- zero-exponent = false
- }
-% \end{macrocode}
-%
-% \begin{macrocode}
-%</package>
-% \end{macrocode}
-%
-% \end{implementation}
-%
-% \PrintIndex