summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/siunitx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/siunitx')
-rw-r--r--macros/latex/contrib/siunitx/CHANGELOG.md46
-rw-r--r--macros/latex/contrib/siunitx/siunitx-abbreviation.dtx12
-rw-r--r--macros/latex/contrib/siunitx/siunitx-angle.dtx35
-rw-r--r--macros/latex/contrib/siunitx/siunitx-code.pdfbin643547 -> 649679 bytes
-rw-r--r--macros/latex/contrib/siunitx/siunitx-compound.dtx418
-rw-r--r--macros/latex/contrib/siunitx/siunitx-locale.dtx8
-rw-r--r--macros/latex/contrib/siunitx/siunitx-number.dtx326
-rw-r--r--macros/latex/contrib/siunitx/siunitx-table.dtx66
-rw-r--r--macros/latex/contrib/siunitx/siunitx.dtx61
-rw-r--r--macros/latex/contrib/siunitx/siunitx.ins2
-rw-r--r--macros/latex/contrib/siunitx/siunitx.pdfbin691117 -> 705584 bytes
-rw-r--r--macros/latex/contrib/siunitx/siunitx.tex316
12 files changed, 1024 insertions, 266 deletions
diff --git a/macros/latex/contrib/siunitx/CHANGELOG.md b/macros/latex/contrib/siunitx/CHANGELOG.md
index 003c810d2b..235ce5fbfa 100644
--- a/macros/latex/contrib/siunitx/CHANGELOG.md
+++ b/macros/latex/contrib/siunitx/CHANGELOG.md
@@ -7,6 +7,49 @@ Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to
## [Unreleased]
+## [v3.3.0] - 2023-07-31
+
+### Added
+- Support for Italian (see issue
+ [\#650](https://github.com/josephwright/siunitx/issues/650))
+- Abbreviations `\T`, `\mT`, `\uT` (see issue
+ [\#670](https://github.com/josephwright/siunitx/issues/670))
+- Option `range-open-phrase`
+- Option `round-direction` to allow 'truncation' of rounded
+ values (see issue
+ [\#664](https://github.com/josephwright/siunitx/issues/664))
+- Option `uncertainty-round-direction` (see issue
+ [\#628](https://github.com/josephwright/siunitx/issues/628))
+- Support for asymmetrical uncertainties, including new option
+ `input-uncertainty-divider` (see issue
+ [\#675](https://github.com/josephwright/siunitx/issues/675))
+- Options for bracket control:
+ - `compound-close-bracket`
+ - `compound-open-bracket`
+ - `list-close-bracket`
+ - `list-open-bracket`
+ - `product-close-bracket`
+ - `product-open-bracket`
+ - `range-close-bracket`
+ - `range-open-bracket`
+ (see issue
+ [\#262](https://github.com/josephwright/siunitx/issues/262))
+- Option `table-model-setup` (see issue
+ [\#659](https://github.com/josephwright/siunitx/issues/659))
+- Options `list-input-separator` and `product-input-separator` (see issue
+ [\#603](https://github.com/josephwright/siunitx/issues/603))
+- Options `compound-independent-prefix`, `list-independent-prefix`,
+ `product-independent-prefix` and `range-independent-prefix` (see issue
+ [\#554](https://github.com/josephwright/siunitx/issues/554))
+- Hint for overloading `\num` and `\qty` (see issue
+ [\#648](https://github.com/josephwright/siunitx/issues/648))
+
+### Changed
+
+- Support bracing of decimal marker in tables as an alternative
+ to `\mathord` (see issue
+ [\#527](https://github.com/josephwright/siunitx/issues/527))
+
## [v3.2.9] - 2023-07-26
### Fixed
@@ -1928,7 +1971,8 @@ Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to
### Added
- First public testing release (as `si`)
-[Unreleased]: https://github.com/josephwright/siunitx/compare/v3.2.9...HEAD
+[Unreleased]: https://github.com/josephwright/siunitx/compare/v3.3.0...HEAD
+[v3.3.0]: https://github.com/josephwright/siunitx/compare/v3.2.9...v3.3.0
[v3.2.9]: https://github.com/josephwright/siunitx/compare/v3.2.8...v3.2.9
[v3.2.8]: https://github.com/josephwright/siunitx/compare/v3.2.7...v3.2.8
[v3.2.7]: https://github.com/josephwright/siunitx/compare/v3.2.6...v3.2.7
diff --git a/macros/latex/contrib/siunitx/siunitx-abbreviation.dtx b/macros/latex/contrib/siunitx/siunitx-abbreviation.dtx
index 152f56608a..2d4e60e1d4 100644
--- a/macros/latex/contrib/siunitx/siunitx-abbreviation.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-abbreviation.dtx
@@ -127,6 +127,10 @@
% Abbreviations for charge.
% \end{function}
%
+% \begin{function}{\T, \mT \uT}
+% Abbreviations for magneticc field.
+% \end{function}
+%
% \begin{function}{\dB}
% Abbreviation for decibel.
% \end{function}
@@ -306,6 +310,14 @@
\siunitx_declare_unit:Nn \mC { \milli \coulomb }
% \end{macrocode}
% \end{macro}
+% \begin{macro}{\T, \uT, \mT}
+% Magnetic field.
+% \begin{macrocode}
+\siunitx_declare_unit:Nn \T { \tesla }
+\siunitx_declare_unit:Nn \uT { \micro \tesla }
+\siunitx_declare_unit:Nn \mT { \milli \tesla }
+% \end{macrocode}
+% \end{macro}
% \begin{macro}{\N, \mN, \kN, \MN}
% Forces.
% \begin{macrocode}
diff --git a/macros/latex/contrib/siunitx/siunitx-angle.dtx b/macros/latex/contrib/siunitx/siunitx-angle.dtx
index a2335a2c9b..69bb9a53fb 100644
--- a/macros/latex/contrib/siunitx/siunitx-angle.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-angle.dtx
@@ -337,6 +337,30 @@
% \end{macrocode}
% \end{variable}
%
+% \begin{macro}{\@@_suppress_exp_uncert:, \@@_suppress_comp_sign:}
+% Pre-compilation of keys to suppress uncertainties and exponents,
+% and
+% \begin{macrocode}
+\keys_precompile:nnN
+ { siunitx }
+ {
+ input-close-uncertainty = ,
+ input-exponent-markers = ,
+ input-open-uncertainty = ,
+ input-uncertainty-signs =
+ }
+ \l_@@_tmp_tl
+\cs_set_protected:Npx \@@_suppress_exp_uncert:
+ { \exp_not:V \l_@@_tmp_tl }
+\keys_precompile:nnN
+ { siunitx }
+ { input-comparators = , input-signs = }
+ \l_@@_tmp_tl
+\cs_set_protected:Npx \@@_suppress_comp_sign:
+ { \exp_not:V \l_@@_tmp_tl }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\@@_arc_sign:nnn}
% \begin{macro}{\@@_arc_sign:nn}
% \begin{macro}{\@@_extract_sign:nnnnnnnn}
@@ -348,13 +372,7 @@
\cs_new_protected:Npn \@@_arc_sign:nnn #1#2#3
{
\group_begin:
- \keys_set:nn { siunitx }
- {
- input-close-uncertainty = ,
- input-exponent-markers = ,
- input-open-uncertainty = ,
- input-uncertainty-signs =
- }
+ \@@_suppress_exp_uncert:
\tl_clear:N \l_@@_sign_tl
\@@_arc_sign:nn {#1} { degrees }
\@@_arc_sign:nn {#2} { minutes }
@@ -420,8 +438,7 @@
\tl_set:cn { l_@@_ #8 _tl }
{ {#1} { } {#3} {#4} {#5} {#6} {#7} }
\tl_set:Nn \l_@@_sign_tl {#2}
- \keys_set:nn { siunitx }
- { input-comparators = , input-signs = }
+ \@@_suppress_comp_sign:
}
}
\cs_new:Npn \@@_sign:nnnnnnn #1#2#3#4#5#6#7
diff --git a/macros/latex/contrib/siunitx/siunitx-code.pdf b/macros/latex/contrib/siunitx/siunitx-code.pdf
index 8a2b8e5992..fdc1658a42 100644
--- a/macros/latex/contrib/siunitx/siunitx-code.pdf
+++ b/macros/latex/contrib/siunitx/siunitx-code.pdf
Binary files differ
diff --git a/macros/latex/contrib/siunitx/siunitx-compound.dtx b/macros/latex/contrib/siunitx/siunitx-compound.dtx
index 51701c6915..b16aa63f30 100644
--- a/macros/latex/contrib/siunitx/siunitx-compound.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-compound.dtx
@@ -137,6 +137,35 @@
% Phrase (or similar) used between limits of a range.
% \end{variable}
%
+% \begin{function}{compound-boundary-mode}
+% \begin{syntax}
+% |compound-boundary-mode| = |number|\verb"|"|text|
+% \end{syntax}
+% Choice which determines whether the material at the start and
+% end of a compound quantity are typeset a |number| or as |text|;
+% the latter is the standard setting.
+% \end{function}
+%
+% \begin{function}{compound-close-boundary, compound-open-boundary}
+% \begin{syntax}
+% |compound-close-boundary| = \meta{tokens}\\
+% |compound-open-boundary| = \meta{tokens}
+% \end{syntax}
+% Literals which are inserted at the opening and closing boundary of a compound
+% quantity; they are not used when the number of items is one.
+% The standard settings set these empty.
+% \end{function}
+%
+% \begin{function}{compound-close-bracket, compound-open-bracket}
+% \begin{syntax}
+% |compound-close-bracket| = \meta{token} \\
+% |compound-open-bracket| = \meta{token}
+% \end{syntax}
+% Literals containing the tokens inserted at the start and end of a compound
+% value when |compounds-units| is set to |bracket|. The standard settings are
+% |(| and |)|.
+% \end{function}
+%
% \begin{function}{compound-exponents}
% \begin{syntax}
% |compound-exponents| = |combine|\verb"|"|combine-bracket|\verb"|"|individual|
@@ -149,6 +178,15 @@
% \end{syntax}
% \end{function}
%
+% \begin{function}{compound-independent-prefix}
+% \begin{syntax}
+% |compound-independent-prefix| = |true|\verb"|"|false|
+% \end{syntax}
+% Switch which determines whether unit prefixes are calculated
+% independently when units are repeated. The standard setting is
+% |false|.
+% \end{function}
+%
% \begin{function}{compound-pair-separator}
% \begin{syntax}
% |compound-pair-separator| = \meta{text}
@@ -165,6 +203,9 @@
% \begin{syntax}
% |compound-separator-mode| = |number|\verb"|"|text|
% \end{syntax}
+% Choice which determines whether the separators between components
+% of compound quantity are typeset a |number| or as |text|;
+% the latter is the standard setting.
% \end{function}
%
% \begin{function}{compound-units}
@@ -173,6 +214,15 @@
% \end{syntax}
% \end{function}
%
+% \begin{function}{list-close-bracket, list-open-bracket}
+% \begin{syntax}
+% |list-close-bracket| = \meta{token} \\
+% |list-open-bracket| = \meta{token}
+% \end{syntax}
+% Literals containing the tokens inserted at the start and end of a list when
+% |list-units| is set to |bracket|. The standard settings are |(| and |)|.
+% \end{function}
+%
% \begin{function}{list-exponents}
% \begin{syntax}
% |list-exponents| = |combine|\verb"|"|combine-bracket|\verb"|"|individual|
@@ -185,6 +235,15 @@
% \end{syntax}
% \end{function}
%
+% \begin{function}{list-independent-prefix}
+% \begin{syntax}
+% |list-independent-prefix| = |true|\verb"|"|false|
+% \end{syntax}
+% Switch which determines whether unit prefixes are calculated
+% independently when units are repeated. The standard setting is
+% |false|.
+% \end{function}
+%
% \begin{function}{list-pair-separator}
% \begin{syntax}
% |list-pair-separator| = \meta{text}
@@ -203,12 +262,31 @@
% \end{syntax}
% \end{function}
%
+% \begin{function}{product-close-bracket, product-open-bracket}
+% \begin{syntax}
+% |product-close-bracket| = \meta{token} \\
+% |product-open-bracket| = \meta{token}
+% \end{syntax}
+% Literals containing the tokens inserted at the start and end of a product
+% when |product-units| is set to |bracket|. The standard settings are |(|
+% and |)|.
+% \end{function}
+%
% \begin{function}{product-exponents}
% \begin{syntax}
% |product-exponents| = |combine|\verb"|"|combine-bracket|\verb"|"|individual|
% \end{syntax}
% \end{function}
%
+% \begin{function}{product-independent-prefix}
+% \begin{syntax}
+% |product-independent-prefix| = |true|\verb"|"|false|
+% \end{syntax}
+% Switch which determines whether unit prefixes are calculated
+% independently when units are repeated. The standard setting is
+% |false|.
+% \end{function}
+%
% \begin{function}{product-mode}
% \begin{syntax}
% |product-mode| = |phrase|\verb"|"|choice|
@@ -233,10 +311,40 @@
% \end{syntax}
% \end{function}
%
+% \begin{function}{range-close-bracket, range-open-bracket}
+% \begin{syntax}
+% |range-close-bracket| = \meta{token} \\
+% |range-open-bracket| = \meta{token}
+% \end{syntax}
+% Literals containing the tokens inserted at the start and end of a range when
+% |range-units| is set to |bracket|. The standard settings are |(| and |)|.
+% \end{function}
+%
+% \begin{function}{range-independent-prefix}
+% \begin{syntax}
+% |range-independent-prefix| = |true|\verb"|"|false|
+% \end{syntax}
+% Switch which determines whether unit prefixes are calculated
+% independently when units are repeated. The standard setting is
+% |false|.
+% \end{function}
+%
+% \begin{function}{range-open-phrase}
+% \begin{syntax}
+% |range-open-phrase| = \meta{text}
+% \end{syntax}
+% Literal containing the material to be inserted at the start of a range.
+% The standard setting is empty.
+% \end{function}
+%
% \begin{function}{range-phrase}
% \begin{syntax}
% |range-phrase| = \meta{text}
% \end{syntax}
+% Literal containing the material to be inserted between the start and end
+% of a range. The standard setting contains the word \texttt{to} inside the
+% \cs{text} command, along with appropriate spacing commands to allow this
+% material to work in both math and text typesetting modes.
% \end{function}
%
% \begin{function}{range-units}
@@ -258,6 +366,7 @@
%
% \begin{macrocode}
\cs_generate_variant:Nn \keys_set:nn { nx }
+\cs_generate_variant:Nn \seq_use:Nnnn { NVVV }
% \end{macrocode}
%
% \subsection{General mechanism}
@@ -318,29 +427,26 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\l_@@_bracket_close_tl, \l_@@_bracket_open_tl}
-% Purely internal for the present.
-% \begin{macrocode}
-\tl_new:N \l_@@_bracket_close_tl
-\tl_new:N \l_@@_bracket_open_tl
-\tl_set:Nn \l_@@_bracket_open_tl { ( }
-\tl_set:Nn \l_@@_bracket_close_tl { ) }
-% \end{macrocode}
-% \end{variable}
-%
% \begin{variable}
% {
+% \l_@@_boundary_close_tl ,
+% \l_@@_bracket_close_tl ,
+% \l_@@_independent_bool ,
% \l_@@_separator_final_tl ,
% \l_@@_separator_pair_tl ,
+% \l_@@_boundary_open_tl ,
+% \l_@@_bracket_open_tl ,
% \l_@@_separator_tl ,
% \l_@@_separator_text_bool ,
% \l_@@_exp_bracket_bool ,
% \l_@@_exp_combine_bool ,
% \l_@@_unit_bracket_bool ,
-% \l_@@_unit_repeat_bool
+% \l_@@_unit_power_bool ,
+% \l_@@_unit_repeat_bool ,
% }
% List options.
% \begin{macrocode}
+\bool_new:N \l_@@_boundary_text_bool
\bool_new:N \l_@@_exp_bracket_bool
\bool_new:N \l_@@_exp_combine_bool
\bool_new:N \l_@@_separator_text_bool
@@ -349,6 +455,15 @@
\bool_new:N \l_@@_unit_repeat_bool
\keys_define:nn { siunitx }
{
+ compound-boundary-mode .choice: ,
+ compound-boundary-mode / number .code:n =
+ { \bool_set_false:N \l_@@_delim_text_bool } ,
+ compound-boundary-mode / text .code:n =
+ { \bool_set_true:N \l_@@_delim_text_bool } ,
+ compound-close-boundary .tl_set:N =
+ \l_@@_boundary_close_tl ,
+ compound-close-bracket .tl_set:N =
+ \l_@@_bracket_close_tl ,
compound-exponents .choice: ,
compound-exponents / combine .code:n =
{
@@ -367,8 +482,14 @@
} ,
compound-final-separator .tl_set:N =
\l_@@_separator_final_tl ,
+ compound-independent-prefix .bool_set:N =
+ \l_@@_independent_bool ,
compound-pair-separator .tl_set:N =
\l_@@_separator_pair_tl ,
+ compound-open-boundary .tl_set:N =
+ \l_@@_boundary_open_tl ,
+ compound-open-bracket .tl_set:N =
+ \l_@@_bracket_open_tl ,
compound-separator .tl_set:N =
\l_@@_separator_tl ,
compound-separator-mode .choice: ,
@@ -406,7 +527,7 @@
\bool_set_false:N \l_@@_unit_bracket_bool
\bool_set_false:N \l_@@_unit_power_bool
\bool_set_false:N \l_@@_unit_repeat_bool
- }
+ }
}
% \end{macrocode}
% \end{variable}
@@ -664,7 +785,12 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\siunitx_compound_quantity:nn}
+% \begin{macro}
+% {
+% \siunitx_compound_quantity:nn ,
+% \@@_quantity_auxi:nn ,
+% \@@_quantity_auxii:nn
+% }
% For quantities, life is more complex as there are interactions between the
% options for exponents and units. The \cs{c_empty_tl} suppresses any
% leading \texttt{1} if the unit starts \cs{per}; the \pkg{siunitx-print}
@@ -673,37 +799,76 @@
\cs_new_protected:Npn \siunitx_compound_quantity:nn #1#2
{
\group_begin:
- \bool_if:NT \l_@@_unit_bracket_bool
- { \bool_set_true:N \l_@@_exp_bracket_bool }
- \bool_if:NT \l_@@_unit_repeat_bool
- { \bool_set_false:N \l_@@_exp_combine_bool }
- \bool_lazy_or:nnT
- { \l_@@_unit_bracket_bool }
- { ! \l_@@_unit_repeat_bool }
- { \bool_set_false:N \l_siunitx_number_bracket_ambiguous_bool }
- \bool_set_true:N \l_@@_unit_bool
- \@@_format:nn {#1} {#2}
- \bool_if:NF \l_siunitx_number_parse_bool
- { \siunitx_unit_format:nN {#2} \l_@@_unit_tl }
- \str_if_eq:VnT \l_siunitx_quantity_prefix_mode_tl { combine-exponent }
- { \tl_clear:N \l_@@_exp_tl }
- \bool_if:NTF \l_@@_unit_repeat_bool
- { \@@_print:N \@@_print_quantity:x }
+ \bool_lazy_all:nTF
{
- \bool_lazy_and:nnTF
- { \l_@@_unit_bracket_bool }
- { \tl_if_empty_p:N \l_@@_exp_tl }
- {
- \siunitx_print_number:V \l_@@_bracket_open_tl
- \@@_print:N \siunitx_print_number:x
- \siunitx_print_number:V \l_@@_bracket_close_tl
- }
- { \@@_print:N \siunitx_print_number:x }
- \@@_print_quantity:n { \c_empty_tl }
+ { \l_@@_independent_bool }
+ {
+ \str_if_eq_p:Vn
+ \l_siunitx_quantity_prefix_mode_tl
+ { combine-exponent }
+ }
+ { \int_compare_p:nNn { \tl_count:n {#1} } > 1 }
}
+ { \@@_quantity_auxi:nn }
+ { \@@_quantity_auxii:nn }
+ {#1} {#2}
\group_end:
}
% \end{macrocode}
+% The rather special case where all units are printed independently:
+% we just convert to a simple sequence then print.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_quantity_auxi:nn #1#2
+ {
+ \@@_print_boundary:V \l_@@_boundary_close_tl
+ \seq_clear:N \l_@@_tmp_seq
+ \tl_map_inline:nn {#1}
+ {
+ \seq_put_right:Nn \l_@@_tmp_seq
+ { \siunitx_quantity:nn {##1} {#2} }
+ }
+ \seq_use:NVVV \l_@@_tmp_seq
+ \l_@@_separator_pair_tl
+ \l_@@_separator_tl
+ \l_@@_separator_final_tl
+ \@@_print_boundary:V \l_@@_boundary_close_tl
+ }
+% \end{macrocode}
+% The business end for all other cases.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_quantity_auxii:nn #1#2
+ {
+ \bool_if:NT \l_@@_unit_bracket_bool
+ { \bool_set_true:N \l_@@_exp_bracket_bool }
+ \bool_if:NT \l_@@_unit_repeat_bool
+ { \bool_set_false:N \l_@@_exp_combine_bool }
+ \bool_lazy_or:nnT
+ { \l_@@_unit_bracket_bool }
+ { ! \l_@@_unit_repeat_bool }
+ { \bool_set_false:N \l_siunitx_number_bracket_ambiguous_bool }
+ \bool_set_true:N \l_@@_unit_bool
+ \@@_format:nn {#1} {#2}
+ \bool_if:NF \l_siunitx_number_parse_bool
+ { \siunitx_unit_format:nN {#2} \l_@@_unit_tl }
+ \str_if_eq:VnT \l_siunitx_quantity_prefix_mode_tl { combine-exponent }
+ { \tl_clear:N \l_@@_exp_tl }
+ \bool_if:NTF \l_@@_unit_repeat_bool
+ { \@@_print:N \@@_print_quantity:x }
+ {
+ \bool_lazy_and:nnTF
+ { \l_@@_unit_bracket_bool }
+ { \tl_if_empty_p:N \l_@@_exp_tl }
+ {
+ \siunitx_print_number:V \l_@@_bracket_open_tl
+ \@@_print:N \siunitx_print_number:x
+ \siunitx_print_number:V \l_@@_bracket_close_tl
+ }
+ { \@@_print:N \siunitx_print_number:x }
+ \@@_print_quantity:n { \c_empty_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
% \end{macro}
%
% \begin{macro}{\@@_print:N}
@@ -712,7 +877,11 @@
% \begin{macro}{\@@_print_aux:n}
% \begin{macro}{\@@_print_aux:nn}
% \begin{macro}{\@@_print_quantity:n, \@@_print_quantity:x}
-% \begin{macro}{\@@_print_separator:n, \@@_print_separator:V}
+% \begin{macro}
+% {
+% \@@_print_boundary:n, \@@_print_boundary:V,
+% \@@_print_separator:n, \@@_print_separator:V
+% }
% We now need to know how many entries there are: the reason we don't use
% \cs{seq_use:Nnnn} is that we want to be able to insert
% \cs{siunitx_print_\dots:n} in a controlled way.
@@ -757,6 +926,7 @@
}
{ 2 }
{
+ \@@_print_boundary:V \l_@@_boundary_open_tl
#4
{
\exp_not:n {#2}
@@ -768,6 +938,7 @@
\seq_item:Nn \l_@@_tmp_seq { 2 }
\exp_not:n {#3}
}
+ \@@_print_boundary:V \l_@@_boundary_open_tl
}
}
{
@@ -775,9 +946,11 @@
\tl_set:Nn \l_@@_start_tl {#2}
\tl_set:Nn \l_@@_end_tl {#3}
\cs_set_eq:NN \@@_print_aux:n #4
+ \@@_print_boundary:V \l_@@_boundary_open_tl
\seq_map_indexed_function:NN
\l_@@_tmp_seq
\@@_print_aux:nn
+ \@@_print_boundary:V \l_@@_boundary_close_tl
}
}
\cs_new_protected:Npn \@@_print_aux:n #1 { }
@@ -816,6 +989,16 @@
\cs_new_protected:Npn \@@_print_quantity:n #1
{ \siunitx_quantity_print:nV {#1} \l_@@_unit_tl }
\cs_generate_variant:Nn \@@_print_quantity:n { x }
+\cs_new_protected:Npn \@@_print_boundary:n #1
+ {
+ \tl_if_blank:nF {#1}
+ {
+ \bool_if:NTF \l_@@_boundary_text_bool
+ { #1 }
+ { \siunitx_print_number:n {#1} }
+ }
+ }
+\cs_generate_variant:Nn \@@_print_boundary:n { V }
\cs_new_protected:Npn \@@_print_separator:n #1
{
\bool_if:NTF \l_@@_separator_text_bool
@@ -872,8 +1055,11 @@
%
% \begin{variable}
% {
+% \l_@@_bracket_close_tl ,
+% \l_@@_independent_bool ,
% \l_siunitx_list_separator_tl ,
% \l_siunitx_list_separator_final_tl ,
+% \l_@@_bracket_open_tl ,
% \l_siunitx_list_separator_pair_tl ,
% \l_@@_exp_tl ,
% \l_@@_units_tl
@@ -884,14 +1070,20 @@
\tl_new:N \l_@@_units_tl
\keys_define:nn { siunitx }
{
+ list-close-bracket .tl_set:N =
+ \l_@@_bracket_close_tl ,
list-exponents .choices:nn =
{ combine , combine-bracket , individual }
{ \tl_set_eq:NN \l_@@_exp_tl \l_keys_choice_tl } ,
list-final-separator .tl_set:N = \l_siunitx_list_separator_final_tl ,
+ list-independent-prefix .bool_set:N =
+ \l_@@_independent_bool ,
+ list-open-bracket .tl_set:N =
+ \l_@@_bracket_open_tl ,
list-pair-separator .tl_set:N = \l_siunitx_list_separator_pair_tl ,
list-separator .tl_set:N = \l_siunitx_list_separator_tl ,
list-units .choices:nn =
- { bracket , repeat , single }
+ { bracket , independent , repeat , single }
{ \tl_set_eq:NN \l_@@_units_tl \l_keys_choice_tl }
}
% \end{macrocode}
@@ -920,15 +1112,23 @@
{
\keys_set:nx { siunitx }
{
- compound-exponents = \l_@@_exp_tl ,
- compound-final-separator =
+ compound-close-bracket =
+ { \exp_not:V \l_@@_bracket_close_tl } ,
+ compound-close-boundary = ,
+ compound-exponents = \l_@@_exp_tl ,
+ compound-final-separator =
{ \exp_not:V \l_siunitx_list_separator_final_tl } ,
- compound-pair-separator =
+ compound-independent-prefix =
+ \bool_if:NTF \l_@@_independent_bool { true } { false } ,
+ compound-open-boundary = ,
+ compound-open-bracket =
+ { \exp_not:V \l_@@_bracket_open_tl } ,
+ compound-pair-separator =
{ \exp_not:V \l_siunitx_list_separator_pair_tl } ,
- compound-separator =
+ compound-separator =
{ \exp_not:V \l_siunitx_list_separator_tl } ,
- compound-separator-mode = text ,
- compound-units = \l_@@_units_tl
+ compound-separator-mode = text ,
+ compound-units = \l_@@_units_tl
}
}
% \end{macrocode}
@@ -946,10 +1146,13 @@
%
% \begin{variable}
% {
-% \l_@@_exp_tl ,
-% \l_@@_phrase_bool ,
-% \l_@@_phrase_tl ,
-% \l_@@_symbol_tl ,
+% \l_@@_bracket_close_tl ,
+% \l_@@_exp_tl ,
+% \l_@@_independent_bool ,
+% \l_@@_bracket_open_tl ,
+% \l_@@_phrase_bool ,
+% \l_@@_phrase_tl ,
+% \l_@@_symbol_tl ,
% \l_@@_units_tl
% }
% Options for products.
@@ -959,18 +1162,24 @@
\tl_new:N \l_@@_units_tl
\keys_define:nn { siunitx }
{
+ product-close-bracket .tl_set:N =
+ \l_@@_bracket_close_tl ,
product-exponents .choices:nn =
{ combine , combine-bracket , individual }
{ \tl_set_eq:NN \l_@@_exp_tl \l_keys_choice_tl } ,
+ product-independent-prefix .bool_set:N =
+ \l_@@_independent_bool ,
product-mode .choice: ,
product-mode / phrase .code:n =
{ \bool_set_true:N \l_@@_phrase_bool } ,
product-mode / symbol .code:n =
{ \bool_set_false:N \l_@@_phrase_bool } ,
+ product-open-bracket .tl_set:N =
+ \l_@@_bracket_open_tl ,
product-phrase .tl_set:N = \l_@@_phrase_tl ,
product-symbol .tl_set:N = \l_@@_symbol_tl ,
product-units .choices:nn =
- { bracket , bracket-power , power , repeat , single }
+ { bracket , bracket-power , independent , power , repeat , single }
{ \tl_set_eq:NN \l_@@_units_tl \l_keys_choice_tl }
}
% \end{macrocode}
@@ -1006,13 +1215,21 @@
{
\keys_set:nx { siunitx }
{
- compound-exponents = \l_@@_exp_tl ,
- compound-final-separator = { \exp_not:n {#1} } ,
- compound-pair-separator = { \exp_not:n {#1} } ,
- compound-separator = { \exp_not:n {#1} } ,
- compound-separator-mode =
+ compound-close-boundary = ,
+ compound-close-bracket =
+ { \exp_not:V \l_@@_bracket_close_tl } ,
+ compound-exponents = \l_@@_exp_tl ,
+ compound-final-separator = { \exp_not:n {#1} } ,
+ compound-independent-prefix =
+ \bool_if:NTF \l_@@_independent_bool { true } { false } ,
+ compound-open-boundary = ,
+ compound-open-bracket =
+ { \exp_not:V \l_@@_bracket_open_tl } ,
+ compound-pair-separator = { \exp_not:n {#1} } ,
+ compound-separator = { \exp_not:n {#1} } ,
+ compound-separator-mode =
\bool_if:NTF \l_@@_phrase_bool { text } { number } ,
- compound-units = \l_@@_units_tl
+ compound-units = \l_@@_units_tl
}
}
\cs_generate_variant:Nn \@@_aux:n { x }
@@ -1032,7 +1249,11 @@
%
% \begin{variable}
% {
+% \l_@@_bracket_close_tl ,
% \l_@@_exp_tl ,
+% \l_@@_independent_bool ,
+% \l_@@_bracket_open_tl ,
+% \l_@@_open_tl ,
% \l_siunitx_range_phrase_tl ,
% \l_@@_units_tl
% }
@@ -1042,12 +1263,19 @@
\tl_new:N \l_@@_units_tl
\keys_define:nn { siunitx }
{
+ range-close-bracket .tl_set:N =
+ \l_@@_bracket_close_tl ,
range-exponents .choices:nn =
{ combine , combine-bracket , individual }
{ \tl_set_eq:NN \l_@@_exp_tl \l_keys_choice_tl } ,
+ range-independent-prefix .bool_set:N =
+ \l_@@_independent_bool ,
+ range-open-bracket .tl_set:N =
+ \l_@@_bracket_open_tl ,
+ range-open-phrase .tl_set:N = \l_@@_open_tl ,
range-phrase .tl_set:N = \l_siunitx_range_phrase_tl ,
range-units .choices:nn =
- { bracket , repeat , single }
+ { bracket , independent , repeat , single }
{ \tl_set_eq:NN \l_@@_units_tl \l_keys_choice_tl }
}
% \end{macrocode}
@@ -1076,10 +1304,20 @@
{
\keys_set:nx { siunitx }
{
- compound-exponents = \l_@@_exp_tl ,
- compound-pair-separator = { \exp_not:V \l_siunitx_range_phrase_tl } ,
- compound-separator-mode = text ,
- compound-units = \l_@@_units_tl
+ compound-boundary-mode = text ,
+ compound-close-boundary = ,
+ compound-close-bracket =
+ { \exp_not:V \l_@@_bracket_close_tl } ,
+ compound-exponents = \l_@@_exp_tl ,
+ compound-independent-prefix =
+ \bool_if:NTF \l_@@_independent_bool { true } { false } ,
+ compound-open-boundary = { \exp_not:V \l_@@_open_tl } ,
+ compound-open-bracket =
+ { \exp_not:V \l_@@_bracket_open_tl } ,
+ compound-pair-separator =
+ { \exp_not:V \l_siunitx_range_phrase_tl } ,
+ compound-separator-mode = text ,
+ compound-units = \l_@@_units_tl
}
}
% \end{macrocode}
@@ -1095,57 +1333,73 @@
% \begin{macrocode}
\keys_set:nn { siunitx }
{
- compound-exponents = individual ,
- compound-final-separator =
+ compound-boundary-mode = text ,
+ compound-close-boundary = , % (
+ compound-close-bracket = ) ,
+ compound-exponents = individual ,
+ compound-final-separator =
{
\ifmmode \ \else \space \fi
\text { and }
\ifmmode \ \else \space \fi
} ,
- compound-pair-separator =
+ compound-independent-prefix = false ,
+ compound-open-boundary = ,
+ compound-open-bracket = ( , % )
+ compound-pair-separator =
{
\ifmmode \ \else \space \fi
\text { and }
\ifmmode \ \else \space \fi
} ,
- compound-separator =
+ compound-separator =
{ , \ifmmode \ \else \space \fi } ,
- compound-separator-mode = text ,
- compound-units = repeat ,
- list-exponents = individual ,
- list-final-separator =
+ compound-separator-mode = text ,
+ compound-units = repeat , % (
+ list-close-bracket = ) ,
+ list-exponents = individual ,
+ list-final-separator =
{
\ifmmode \ \else \space \fi
\text { and }
\ifmmode \ \else \space \fi
} ,
- list-pair-separator =
+ list-independent-prefix = false ,
+ list-open-bracket = ( , % )
+ list-pair-separator =
{
\ifmmode \ \else \space \fi
\text { and }
\ifmmode \ \else \space \fi
} ,
- list-separator =
+ list-separator =
{ , \ifmmode \ \else \space \fi } ,
- list-units = repeat ,
- product-exponents = individual ,
- product-mode = symbol ,
- product-phrase =
+ list-units = repeat , % (
+ product-close-bracket = ) ,
+ product-exponents = individual ,
+ product-independent-prefix = false ,
+ product-mode = symbol ,
+ product-open-bracket = ( , % )
+ product-phrase =
{
\ifmmode \ \else \space \fi
\text { by }
\ifmmode \ \else \space \fi
} ,
- product-symbol = \times ,
- product-units = repeat ,
- range-exponents = individual ,
- range-phrase =
+ product-symbol = \times ,
+ product-units = repeat , % (
+ range-close-bracket = ) ,
+ range-exponents = individual ,
+ range-independent-prefix = false ,
+ range-open-bracket = ( , % )
+ range-open-phrase = ,
+ range-phrase =
{
\ifmmode \ \else \space \fi
\text { to }
\ifmmode \ \else \space \fi
} ,
- range-units = repeat
+ range-units = repeat
}
% \end{macrocode}
%
diff --git a/macros/latex/contrib/siunitx/siunitx-locale.dtx b/macros/latex/contrib/siunitx/siunitx-locale.dtx
index 43f432733a..da12029bc9 100644
--- a/macros/latex/contrib/siunitx/siunitx-locale.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-locale.dtx
@@ -108,6 +108,12 @@
inter-unit-product = \, ,
output-decimal-marker = { , }
} ,
+ locale / IT .meta:n =
+ {
+ exponent-product = \times ,
+ inter-unit-product = \, ,
+ output-decimal-marker = { , }
+ } ,
locale / PL .meta:n =
{
exponent-product = \cdot ,
@@ -150,6 +156,7 @@
{
\RequirePackage { translations }
\DeclareTranslation { Catalan } { and } { i }
+ \DeclareTranslation { Italian } { and } { e }
\DeclareTranslation { Portuguese } { and } { e }
\DeclareTranslation { Slovene } { and } { in }
\DeclareTranslation { Brazilian } { to~(numerical~range) } { a }
@@ -157,6 +164,7 @@
\DeclareTranslation { English } { to~(numerical~range) } { to }
\DeclareTranslation { French } { to~(numerical~range) } { à }
\DeclareTranslation { German } { to~(numerical~range) } { bis }
+ \DeclareTranslation { Italian } { to~(numerical~range) } { a }
\DeclareTranslation { Polish } { to~(numerical~range) } { do }
\DeclareTranslation { Portuguese } { to~(numerical~range) } { a }
\DeclareTranslation { Slovene } { to~(numerical~range) } { do }
diff --git a/macros/latex/contrib/siunitx/siunitx-number.dtx b/macros/latex/contrib/siunitx/siunitx-number.dtx
index 8bc0a2dd71..faf216ac67 100644
--- a/macros/latex/contrib/siunitx/siunitx-number.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-number.dtx
@@ -411,6 +411,12 @@
% \end{syntax}
% \end{function}
%
+% \begin{function}{input-uncertainty-divider}
+% \begin{syntax}
+% |input-uncertainty-divider| = \meta{tokens}
+% \end{syntax}
+% \end{function}
+%
% \begin{function}{minimum-decimal-digits}
% \begin{syntax}
% |minimum-decimal-digits| = \meta{min}
@@ -522,6 +528,18 @@
% The standard setting is |false|.
% \end{function}
%
+% \begin{function}{round-direction}
+% \begin{syntax}
+% |round-direction| = |down|\verb"|"|nearest|\verb"|"|up|
+% \end{syntax}
+% Choice which determines how values values are rounded. The setting
+% |up| means that the value is always rounded away from zero, whereas the
+% setting |down| means that the value will be rounded toward zero. The
+% setting |nearest| means that the value will be rounded to the nearest
+% (either up or down), taking account of the setting of |round-half|.
+% The standard setting is |nearest|
+% \end{function}
+%
% \begin{function}{round-half}
% \begin{syntax}
% |round-half| = |even|\verb"|"|up|
@@ -636,6 +654,18 @@
% |full| style is used. The standard setting is |compact|.
% \end{function}
%
+% \begin{function}{uncertainty-round-direction}
+% \begin{syntax}
+% |uncertainty-round-direction| = |down|\verb"|"|nearest|\verb"|"|up|
+% \end{syntax}
+% Choice which determines how uncertainty values are rounded. The setting
+% |up| means that the uncertainty is always rounded away from zero, whereas
+% the setting |down| means that the uncertainty will be rounded toward zero.
+% The setting |nearest| means that the uncertainty will be rounded to the
+% nearest (either up or down), taking account of the setting of |round-half|.
+% The standard setting is |nearest|
+% \end{function}
+%
% \begin{function}{uncertainty-separator}
% \begin{syntax}
% |uncertainty-separator| = \meta{separator}
@@ -776,6 +806,12 @@
% containing an identifier, then zero or more brace groups which contain
% the uncertainty data. In this release, the known uncertainty types are
% \begin{itemize}
+% \item \texttt{A}: An unsymmetrical uncertainty made up of two values.
+% Each is stored as uncertainty in significant digits, with no radix point
+% in the stored value. The two parts are stored within one brace group,
+% within which are two brace groups: the first contains the positive
+% component, the second the negative component. Neither component has a
+% sign.
% \item \texttt{S}: A symmetrical statistical uncertainty made up of
% a single value. These are stored as uncertainty in significant digits,
% with no radix point in the stored value.
@@ -797,6 +833,7 @@
% \l_siunitx_number_input_exponent_tl ,
% \l_@@_input_ignore_tl ,
% \l_@@_input_uncert_open_tl ,
+% \l_@@_input_uncert_divide_tl ,
% \l_siunitx_number_input_sign_tl ,
% \l_@@_input_uncert_sign_tl ,
% \l_@@_explicit_decimal_bool ,
@@ -838,6 +875,8 @@
{ \tl_put_right:Nn \l_siunitx_number_input_sign_tl {##1} }
}
} ,
+ input-uncertainty-divider .tl_set:N =
+ \l_@@_input_uncert_divide_tl ,
parse-numbers .bool_set:N =
\l_siunitx_number_parse_bool ,
retain-explicit-decimal-marker .bool_set:N =
@@ -911,11 +950,21 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\l_@@_uncert_tl}
+% \begin{variable}
+% {
+% \l_@@_tolerance_tl ,
+% \l_@@_uncert_tl ,
+% \l_@@_uncert_offset_int,
+% \l_@@_uncert_types_tl
+% }
% To allow multiple uncertainties, we want to build this up as possibly
-% multiple entries.
+% multiple entries. For asymmetrical uncertainties/tolerances, we need
+% an additional store.
% \begin{macrocode}
+\tl_new:N \l_@@_tolerance_tl
\tl_new:N \l_@@_uncert_tl
+\int_new:N \l_@@_uncert_offset_int
+\tl_new:N \l_@@_uncert_types_tl
% \end{macrocode}
% \end{variable}
%
@@ -992,6 +1041,7 @@
\group_begin:
\tl_clear:N \l_@@_parsed_tl
\tl_clear:N \l_@@_uncert_tl
+ \tl_clear:N \l_@@_uncert_types_tl
\tl_map_inline:Nn \l_@@_input_ignore_tl
{
\token_if_macro:NT ##1
@@ -1576,7 +1626,6 @@
\cs_new_protected:Npn \@@_parse_loop_main_uncert:NN #1#2
{
\@@_parse_loop_main_store:NNN #1 #2 \c_false_bool
- \tl_clear:N \l_@@_uncert_tl
\@@_parse_uncert:N
}
% \end{macrocode}
@@ -1647,6 +1696,7 @@
{
\tl_clear:N \l_@@_flex_tl
\tl_clear:N \l_@@_parsed_tl
+ \tl_clear:N \l_@@_uncert_tl
}
% \end{macrocode}
% \end{macro}
@@ -1695,14 +1745,21 @@
%
% \begin{macro}{\@@_parse_uncert:N}
% \begin{macro}{\@@_parse_uncert:NNN}
-% \begin{macro}{\@@_parse_uncert_auxi:N, \@@_parse_uncert_auxii:N}
-% \begin{macro}{\@@_parse_uncert_auxii:}
+% \begin{macro}
+% {
+% \@@_parse_uncert_auxi:N ,
+% \@@_parse_uncert_auxii:N ,
+% \@@_parse_uncert_auxiv:N
+% }
+% \begin{macro}{\@@_parse_uncert_auxiv:}
% \begin{macro}{\@@_parse_uncert_marker:}
% \begin{macro}{\@@_parse_uncert_marker:nnn}
% \begin{macro}{\@@_parse_uncert_marker:nnnw}
% \begin{macro}{\@@_parse_uncert_marker:Nnnn}
% \begin{macro}{\@@_parse_uncert_marker:w}
% \begin{macro}{\@@_parse_uncert_marker:nnnnN}
+% \begin{macro}{\@@_parse_uncert_marker:nnnnnN}
+% \begin{macro}{\@@_parse_uncert_marker:nnnnnnN}
% \begin{macro}{\@@_parse_uncert_after:N}
% Parsing a combined uncertainty has a very restricted range of allowed
% tokens. A closing uncertainty token in the first place is an error,
@@ -1754,7 +1811,7 @@
{
\tl_if_in:NnTF \l_siunitx_number_input_decimal_tl {#1}
{ \@@_parse_uncert_marker: }
- { \@@_parse_loop_break:w }
+ { \@@_parse_uncert_auxiv:N #1 }
}
}
\cs_new_protected:Npn \@@_parse_uncert_auxii:N #1
@@ -1764,7 +1821,7 @@
\@@_parse_uncert_auxiii:
\@@_parse_uncert_after:N
}
- { \@@_parse_loop_break:w }
+ { \@@_parse_uncert_auxiv:N #1 }
}
% \end{macrocode}
% Deal with the closing bracket, which might leave us with nothing if there
@@ -1778,6 +1835,24 @@
{ \tl_set:Nn \l_@@_partial_tl { 0 } }
}
% \end{macrocode}
+% A common auxiliary for the case where the token is not a digit, a
+% decimal mark or a closing parenthesis.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parse_uncert_auxiv:N #1
+ {
+ \tl_if_empty:NTF \l_@@_tolerance_tl
+ {
+ \tl_if_in:NnTF \l_@@_input_uncert_divide_tl {#1}
+ {
+ \cs_set_eq:NN \l_@@_tolerance_tl \l_@@_partial_tl
+ \tl_clear:N \l_@@_partial_tl
+ \@@_parse_uncert:N
+ }
+ { \@@_parse_loop_break:w }
+ }
+ { \@@_parse_loop_break:w }
+ }
+% \end{macrocode}
% Handling a decimal marker in the uncertainty is a bit tricky: we need to make
% sure it's valid. First, we need to be sure that the integer part of the captured
% uncertainty is not too long. Then we need to check that the decimal part is
@@ -1785,7 +1860,7 @@
% Both of these require data from the collected partial number,
% so we extract that first. Checking the decimal part needs the length of the
% not-yet-collected uncertainty. There may be one or more parts to that, so
-% we have to grab p to the \emph{first} closing token to count the length:
+% we have to grab up to the \emph{first} closing token to count the length:
% just grabbing everything only works if there is only a single uncertainty.
% We take protective steps against an entirely-missing closing token so that
% there is not an uncontrolled error.
@@ -1826,22 +1901,62 @@
% With the separated out main part and the current uncertainty part
% available, we can pad the main part if required then restart the
% collection of the uncertainty having thrown away the decimal marker
-% and with the lengths lined up.
+% and with the lengths lined up. To account for asymmetrical
+% uncertainties, there is a bit of work in tracking.
% \begin{macrocode}
\cs_new_protected:Npn \@@_parse_uncert_marker:nnnnN #1#2#3#4#5
{
+ \tl_set:Nx \l_@@_tmp_tl { \tl_head:V \l_@@_input_uncert_divide_tl }
+ \tl_if_empty:NTF \l_@@_tmp_tl
+ { \@@_parse_uncert_marker:nnnnnN {#1} {#2} {#3} {#4} { } #5 }
+ {
+ \use:x
+ {
+ \cs_set_protected:Npn \exp_not:N \@@_parse_uncert_marker:w
+ ####1 \l_@@_tmp_tl ####2 \l_@@_tmp_tl ####3 \exp_not:N \q_stop
+ {
+ \exp_not:N \tl_if_blank:nTF {####2}
+ {
+ \@@_parse_uncert_marker:nnnnnN
+ \exp_not:n { {#1} {#2} {#3} }
+ {####1} { }
+ }
+ {
+ \@@_parse_uncert_marker:nnnnnN
+ \exp_not:n { {#1} {#2} {#3} }
+ {####1} { \l_@@_tmp_tl ####2 }
+ }
+ \exp_not:N #5
+ }
+ \exp_not:N \@@_parse_uncert_marker:w #4
+ \l_@@_tmp_tl \l_@@_tmp_tl \exp_not:N \q_stop
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_parse_uncert_marker:nnnnnN #1#2#3#4#5#6
+ {
+ \exp_args:Ne \@@_parse_uncert_marker:nnnnnnN
+ { \int_eval:n { \tl_count:n {#4} } }
+ {#1} {#2} {#3} {#4} {#5} #6
+ }
+\cs_new_protected:Npn \@@_parse_uncert_marker:nnnnnnN #1#2#3#4#5#6#7
+ {
+ \bool_lazy_and:nnF
+ { \tl_if_empty_p:N \l_@@_tolerance_tl }
+ { \tl_if_empty_p:N \l_@@_uncert_types_tl }
+ {
+ \int_compare:nNnF {#1} = \l_@@_uncert_offset_int
+ { \@@_parse_loop_break:w }
+ }
+ \int_set:Nn \l_@@_uncert_offset_int {#1}
\tl_set:Nx \l_@@_parsed_tl
{
- {#1}
{#2}
+ {#3}
{
- #3
+ #4
\prg_replicate:nn
- {
- \int_max:nn
- { 0 }
- { \tl_count:n {#4} - \tl_count:n {#3} }
- }
+ { \int_max:nn { 0 } { #1 - \tl_count:n {#4} } }
{ 0 }
}
}
@@ -1854,7 +1969,7 @@
\@@_parse_uncert:NNN \c_true_bool
\@@_parse_uncert_auxii:N
}
- #4#5
+ #5#6#7
}
% \end{macrocode}
% At the end of collection, we can either start another one or be done:
@@ -1866,9 +1981,26 @@
{
\exp_not:V \l_@@_uncert_tl
\tl_if_empty:NF \l_@@_partial_tl
- { { \exp_not:V \l_@@_partial_tl } }
+ {
+ {
+ \tl_if_empty:NTF \l_@@_tolerance_tl
+ { \exp_not:V \l_@@_partial_tl }
+ {
+ { \exp_not:V \l_@@_tolerance_tl }
+ { \exp_not:V \l_@@_partial_tl }
+ }
+ }
+ }
+ }
+ \tl_set:Nx \l_@@_uncert_types_tl
+ {
+ \l_@@_uncert_types_tl
+ \tl_if_empty:NTF \l_@@_tolerance_tl
+ { S }
+ { A }
}
\tl_clear:N \l_@@_partial_tl
+ \tl_clear:N \l_@@_tolerance_tl
\quark_if_recursion_tail_stop_do:Nn #1
{
\tl_set:Nx \l_@@_parsed_tl
@@ -1877,17 +2009,14 @@
{
\tl_if_empty:NF \l_@@_uncert_tl
{
- {
- \prg_replicate:nn
- { \tl_count:N \l_@@_uncert_tl }
- { S }
- }
+ { \l_@@_uncert_types_tl }
\exp_not:V \l_@@_uncert_tl
}
}
}
\tl_clear:N \l_@@_partial_tl
\tl_clear:N \l_@@_uncert_tl
+ \int_zero:N \l_@@_uncert_offset_int
}
\tl_if_in:NnTF \l_@@_input_uncert_open_tl {#1}
{ \@@_parse_uncert:N }
@@ -1905,6 +2034,8 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \subsection{Processing numbers}
%
@@ -1917,11 +2048,13 @@
% \l_@@_exponent_fixed_int ,
% \l_@@_min_decimal_int ,
% \l_@@_min_integer_int ,
+% \l_@@_round_dir_tl ,
% \l_@@_round_half_even_bool ,
% \l_@@_round_mode_tl ,
% \l_@@_round_pad_bool ,
% \l_@@_round_precision_int ,
-% \l_@@_round_positive_bool
+% \l_@@_round_positive_bool ,
+% \l_@@_round_uncert_dir_tl
% }
% \begin{macrocode}
\keys_define:nn { siunitx }
@@ -1943,6 +2076,9 @@
\l_@@_min_decimal_int ,
minimum-integer-digits .int_set:N =
\l_@@_min_integer_int ,
+ round-direction .choices:nn =
+ { down , nearest , up }
+ { \tl_set_eq:NN \l_@@_round_dir_tl \l_keys_choice_tl } ,
round-half .choice: ,
round-half / even .code:n =
{ \bool_set_true:N \l_@@_round_half_even_bool } ,
@@ -1958,11 +2094,16 @@
round-precision .int_set:N =
\l_@@_round_precision_int ,
round-zero-positive .bool_set:N =
- \l_@@_round_positive_bool
+ \l_@@_round_positive_bool ,
+ uncertainty-round-direction .choices:nn =
+ { down , nearest , up }
+ { \tl_set_eq:NN \l_@@_round_uncert_dir_tl \l_keys_choice_tl } ,
}
\bool_new:N \l_@@_round_half_even_bool
\tl_new:N \l_@@_exponent_mode_tl
+\tl_new:N \l_@@_round_dir_tl
\tl_new:N \l_@@_round_mode_tl
+\tl_new:N \l_@@_round_uncert_dir_tl
% \end{macrocode}
% \end{variable}
%
@@ -2611,15 +2752,16 @@
% \end{macro}
%
% \begin{macro}[EXP]{\@@_round:nnn, \@@_round:fnn}
+% \begin{macro}[EXP]{\@@_round:nnnn, \@@_round:Vnnn}
% \begin{macro}[EXP]
% {
-% \@@_round_auxi:nnnN ,
-% \@@_round_auxii:nnnN ,
-% \@@_round_auxiii:nnnN
+% \@@_round_auxi:nnnnN ,
+% \@@_round_auxii:nnnnN ,
+% \@@_round_auxiii:nnnnN ,
+% \@@_round_auxiv:nnnnN
% }
-% \begin{macro}[EXP]{\@@_round_auxiv:nnN, \@@_round_auxv:nnN}
-% \begin{macro}[EXP]{\@@_round_auxvi:nN}
-% \begin{macro}[EXP]{\@@_round_auxvii:nnTF}
+% \begin{macro}[EXP]{\@@_round_auxv:nnnN, \@@_round_auxvi:nnnN}
+% \begin{macro}[EXP]{\@@_round_auxvii:nnnTF}
% \begin{macro}[EXP]{\@@_round_auxviii:nnN, \@@_round_auxix:nnN}
% \begin{macro}[EXP]{\@@_round_final_integer:nnw, \@@_round_final_decimal:nnw}
% \begin{macro}[EXP]{\@@_round_final_signicant:n}
@@ -2648,34 +2790,40 @@
% \begin{macrocode}
\cs_new:Npn \@@_round:nnn #1#2#3
{
- \@@_round_auxi:nnnN {#1} {#2} { }
- #3 \q_recursion_tail \q_recursion_stop
+ \@@_round:Vnnn \l_@@_round_dir_tl
+ {#1} {#2} {#3}
}
\cs_generate_variant:Nn \@@_round:nnn { f }
-\cs_new:Npn \@@_round_auxi:nnnN #1#2#3#4
+\cs_new:Npn \@@_round:nnnn #1#2#3#4
{
- \quark_if_recursion_tail_stop_do:Nn #4
+ \@@_round_auxi:nnnnN {#1} {#2} {#3} { }
+ #4 \q_recursion_tail \q_recursion_stop
+ }
+\cs_generate_variant:Nn \@@_round:nnnn { V }
+\cs_new:Npn \@@_round_auxi:nnnnN #1#2#3#4#5
+ {
+ \quark_if_recursion_tail_stop_do:Nn #5
{
- \@@_round_auxii:nnnN {#1} {#3} { } #2
+ \@@_round_auxii:nnnnN {#1} {#2} {#4} { } #3
\q_recursion_tail \q_recursion_stop
}
- \@@_round_auxi:nnnN {#1} {#2} {#4#3}
+ \@@_round_auxi:nnnnN {#1} {#2} {#3} {#5#4}
}
-\cs_new:Npn \@@_round_auxii:nnnN #1#2#3#4
+\cs_new:Npn \@@_round_auxii:nnnnN #1#2#3#4#5
{
- \quark_if_recursion_tail_stop_do:Nn #4
+ \quark_if_recursion_tail_stop_do:Nn #5
{
- \tl_if_blank:nTF {#2}
+ \tl_if_blank:nTF {#3}
{
- \@@_round_auxiv:nnnN {#1} { } { } #3
+ \@@_round_auxiv:nnnnN {#2} {#1} { } { } #4
\q_recursion_tail \q_recursion_stop
}
{
- \@@_round_auxiii:nnnN {#1} {#3} { } #2
+ \@@_round_auxiii:nnnnN {#2} {#1} {#4} { } #3
\q_recursion_tail \q_recursion_stop
}
}
- \@@_round_auxii:nnnN {#1} {#2} {#4#3}
+ \@@_round_auxii:nnnnN {#1} {#2} {#3} {#5#4}
}
% \end{macrocode}
% We now have the input reversed plus how many digits we need to discard
@@ -2688,74 +2836,87 @@
% of the integer: that may product a value of $1\dots$: we tidy up the
% case where it comes out as $0$ later.
% \begin{macrocode}
-\cs_new:Npn \@@_round_auxiii:nnnN #1#2#3#4
+\cs_new:Npn \@@_round_auxiii:nnnnN #1#2#3#4#5
{
- \quark_if_recursion_tail_stop_do:Nn #4
+ \quark_if_recursion_tail_stop_do:Nn #5
{
- \@@_round_auxiv:nnnN {#1} { } {#3} #2
+ \@@_round_auxiv:nnnnN {#1} {#2} { } {#4} #3
\q_recursion_tail \q_recursion_stop
}
\int_compare:nNnTF {#1} > 0
{
- \exp_args:Nf \@@_round_auxiii:nnnN
- { \int_eval:n { #1 - 1 } } {#2} { #4#3 }
+ \exp_args:Nf \@@_round_auxiii:nnnnN
+ { \int_eval:n { #1 - 1 } } {#2} {#3} { #5#4 }
}
- { \@@_round_auxv:nnN {#3} {#2} #4 }
+ { \@@_round_auxv:nnnN {#2} {#4} {#3} #5 }
}
-\cs_new:Npn \@@_round_auxiv:nnnN #1#2#3#4
+\cs_new:Npn \@@_round_auxiv:nnnnN #1#2#3#4#5
{
- \quark_if_recursion_tail_stop_do:Nn #4
+ \quark_if_recursion_tail_stop_do:Nn #5
{
\int_compare:nNnTF {#1} = 0
{
- \@@_round_auxvi:nnN {#3} {#2}
+ \@@_round_auxvi:nnnN {#2} {#4} {#3}
0 \q_recursion_tail \q_recursion_stop
}
{ { 0 } { } }
}
\int_compare:nNnTF {#1} > 0
{
- \exp_args:Nf \@@_round_auxiv:nnnN
- { \int_eval:n { #1 - 1 } } { #2 0 } { #4#3 }
+ \exp_args:Nf \@@_round_auxiv:nnnnN
+ { \int_eval:n { #1 - 1 } } {#2} { #3 0 } { #5#4 }
}
- { \@@_round_auxvi:nnN {#3} {#2} #4 }
+ { \@@_round_auxvi:nnnN {#2} {#4} {#3} #5 }
}
% \end{macrocode}
-% The lead off to rounding proper needs to deal with the half-even rule:
-% it can only apply at this stage, when the \emph{discarded} value can
-% be exactly half.
+% We now have the discarded digits, the matching filler and the
+% next digit. So we can make the decision on rounding: that
+% is handled by a common auxiliary.
% \begin{macrocode}
-\cs_new:Npn \@@_round_auxv:nnN #1#2#3
+\cs_new:Npn \@@_round_auxv:nnnN #1#2#3#4
{
- \quark_if_recursion_tail_stop_do:Nn #3
+ \quark_if_recursion_tail_stop_do:Nn #4
{
- \@@_round_auxvi:nnN
- {#1} { } #2 \q_recursion_tail \q_recursion_stop
+ \@@_round_auxvi:nnnN
+ {#1} {#2} { } #3 \q_recursion_tail \q_recursion_stop
}
- \@@_round_auxvii:nnTF {#1} {#3}
+ \@@_round_auxvii:nnnTF {#1} {#2} {#4}
{ \@@_round_final_decimal:nnw }
{ \@@_round_auxviii:nnN }
- {#2} { } #3
+ {#3} { } #4
}
-\cs_new:Npn \@@_round_auxvi:nnN #1#2#3
+\cs_new:Npn \@@_round_auxvi:nnnN #1#2#3#4
{
- \quark_if_recursion_tail_stop_do:Nn #3
+ \quark_if_recursion_tail_stop_do:Nn #4
{ { 0 } { } }
- \@@_round_auxvii:nnTF {#1} {#3}
+ \@@_round_auxvii:nnnTF {#1} {#2} {#4}
{ \@@_round_final_integer:nnw }
{ \@@_round_auxix:nnN }
- { } {#2} #3
+ { } {#3} #4
}
-\cs_new:Npn \@@_round_auxvii:nnTF #1#2
+% \end{macrocode}
+% For rounding up or down, the decision here is easy: pick the appropriate
+% branch. For rounding to nearest, we need to deal with the half-even rule:
+% it can only apply at this stage, when the \emph{discarded} value can
+% be exactly half.
+% \begin{macrocode}
+\cs_new:Npn \@@_round_auxvii:nnnTF #1#2#3
{
- \bool_lazy_or:nnTF
- { \int_compare_p:nNn { 0 \tl_head:n {#1} } < 5 }
+ \str_case:nnF {#1}
+ {
+ { down } { \use_i:nn }
+ { up } { \use_ii:nn }
+ }
{
- \bool_lazy_all_p:n
+ \bool_lazy_or:nnTF
+ { \int_compare_p:nNn { 0 \tl_head:n {#2} } < 5 }
{
- { \l_@@_round_half_even_bool }
- { ! \int_if_odd_p:n {#2} }
- { \@@_round_if_half_p:n {#1} }
+ \bool_lazy_all_p:n
+ {
+ { \l_@@_round_half_even_bool }
+ { ! \int_if_odd_p:n {#3} }
+ { \@@_round_if_half_p:n {#2} }
+ }
}
}
}
@@ -3271,8 +3432,9 @@
\use:e
{
\exp_not:N \@@_round_uncertainty:nnnnnn
- \@@_round:nnn {#1} { } {#4}
- {#2} {#3} {#1} {#4}
+ \@@_round:Vnnn
+ \l_@@_round_uncert_dir_tl {#1} { } {#4}
+ {#2} {#3} {#1} {#4}
}
}
% \end{macrocode}
@@ -4240,6 +4402,7 @@
\@@_output_uncert_A:nnnn
\cs_new:Npx \@@_output_uncert_A:nnnnn #1#2#3#4#5
{
+ { }
^
{
+
@@ -4631,6 +4794,7 @@
retain-explicit-plus = false ,
retain-negative-zero = false ,
retain-zero-uncertainty = false ,
+ round-direction = nearest ,
round-half = up ,
round-minimum = 0 ,
round-mode = none ,
@@ -4642,15 +4806,19 @@
uncertainty-descriptor-separator = \ ,
uncertainty-descriptors = ,
uncertainty-mode = compact ,
+ uncertainty-round-direction = nearest ,
uncertainty-separator = ,
zero-decimal-as-symbol = false ,
zero-symbol = \mbox { --- }
}
% \end{macrocode}
-% One awkward setting.
+% Two awkward settings.
% \begin{macrocode}
\keys_set:nx { siunitx }
- { exponent-thresholds = -3 \c_colon_str 3 }
+ {
+ exponent-thresholds = -3 \c_colon_str 3 ,
+ input-uncertainty-divider = \c_colon_str
+ }
% \end{macrocode}
%
% \begin{macrocode}
diff --git a/macros/latex/contrib/siunitx/siunitx-table.dtx b/macros/latex/contrib/siunitx/siunitx-table.dtx
index 823a20edef..3fe8d34a5d 100644
--- a/macros/latex/contrib/siunitx/siunitx-table.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-table.dtx
@@ -190,6 +190,15 @@
% the same size.
% \end{function}
%
+% \begin{function}{table-model-setup}
+% \begin{syntax}
+% |table-model-setup| = \meta{commands}
+% \end{syntax}
+% Additional commands to be inserted when using the |table-format| to
+% create a model for alignment of cells. Typically this will be used to
+% handle variable-width fonts in columns. The standard setting is empty.
+% \end{function}
+%
% \begin{function}{table-number-alignment}
% \begin{syntax}
% |table-number-alignment| = |center|\verb"|"|left|\verb"|"|right|
@@ -818,7 +827,12 @@
% \end{macro}
%
% \begin{variable}
-% {\l_@@_auto_round_bool, \l_@@_align_mode_tl, \l_@@_align_number_tl}
+% {
+% \l_@@_auto_round_bool,
+% \l_@@_model_setup_tl ,
+% \l_@@_align_mode_tl ,
+% \l_@@_align_number_tl
+% }
% Options for tables with defined space.
% \begin{macrocode}
\keys_define:nn { siunitx }
@@ -842,6 +856,8 @@
\exp_args:NV \@@_generate_model:n \l_@@_model_tl
\tl_set:Nn \l_@@_align_mode_tl { format }
} ,
+ table-model-setup .tl_set:N =
+ \l_@@_model_setup_tl ,
table-number-alignment .choices:nn =
{ center , left , right }
{ \tl_set_eq:NN \l_@@_align_number_tl \l_keys_choice_tl }
@@ -1174,7 +1190,12 @@
% \@@_print_format_auxxii:w ,
% \@@_print_format_auxxiii:w
% }
-% \begin{macro}{\@@_print_format_box:Nn}
+% \begin{macro}
+% {
+% \@@_print_format_box:Nn, \@@_print_format_box:No ,
+% \@@_print_model_box:Nn, \@@_print_model_box:No
+% }
+% \begin{macro}{\@@_print_format_box:nNn, \@@_print_format_box:VNn}
% \begin{macro}{\@@_print_format_after:N}
% \begin{macro}{\@@_print_none:nnn}
% \begin{macrocode}
@@ -1325,7 +1346,7 @@
#1 \q_nil #2 \q_mark #3 \q_nil #4 \q_stop
{
\@@_color_check:w #3 \q_nil \q_stop
- \@@_print_format_box:Nn \l_@@_tmp_box {#1}
+ \@@_print_model_box:Nn \l_@@_tmp_box {#1}
\bool_if:NTF \l_@@_align_before_bool
{
\hbox_set_to_wd:Nnn \l_@@_integer_box
@@ -1365,7 +1386,7 @@
\cs_new_protected:Npn \@@_print_format_auxii:w
#1 \q_nil #2 \q_nil #3 \q_mark #4 \q_nil #5 \q_nil #6 \q_stop
{
- \@@_print_format_box:Nn \l_@@_tmp_box {#1#2}
+ \@@_print_model_box:Nn \l_@@_tmp_box {#1#2}
\dim_set:Nn \l_@@_tmp_dim { \box_wd:N \l_@@_tmp_box }
\@@_print_format_box:Nn \l_@@_tmp_box {#4#5}
\dim_compare:nNnT { \box_wd:N \l_@@_tmp_box } > \l_@@_tmp_dim
@@ -1425,19 +1446,20 @@
\@@_fil:
\hbox_unpack:N \l_@@_before_box
}
- \@@_print_format_auxiii:w #3 \q_mark #6 \q_stop
+ \@@_print_format_auxiii:w ? #3 \q_mark ? #6 \q_stop
}
% \end{macrocode}
% We now deal with the decimal part: there is nothing already in the
% |decimal| box, so the basics are easy. We need to \enquote{carry forward}
% any white space, as where it gets inserted depends on the options for
-% subsequent parts.
+% subsequent parts. The \cs{use_none:n} here remove the two |?| above:
+% those are added to preserve braces around the decimal marker.
% \begin{macrocode}
\cs_new_protected:Npn \@@_print_format_auxiii:w
#1 \q_nil #2 \q_nil #3 \q_mark #4 \q_nil #5 \q_nil #6 \q_stop
{
- \@@_print_format_box:Nn \l_@@_tmp_box {#1#2}
- \@@_print_format_box:Nn \l_@@_decimal_box {#4#5}
+ \@@_print_model_box:No \l_@@_tmp_box { \use_none:n #1#2 }
+ \@@_print_format_box:No \l_@@_decimal_box { \use_none:n #4#5 }
\dim_set:Nn \l_@@_carry_dim
{
\box_wd:N \l_@@_tmp_box
@@ -1505,7 +1527,7 @@
#1 \q_nil #2 \q_nil #3 \q_mark
#4 \q_nil #5 \q_nil #6 \q_stop
{
- \@@_print_format_box:Nn \l_@@_tmp_box {#1#2}
+ \@@_print_model_box:Nn \l_@@_tmp_box {#1#2}
\hbox_set_to_wd:Nnn \l_@@_tmp_box
{
\box_wd:N \l_@@_uncert_box
@@ -1535,7 +1557,7 @@
#1 \q_nil #2 \q_mark
#3 \q_nil #4 \q_stop
{
- \@@_print_format_box:Nn \l_@@_tmp_box { { } #1 }
+ \@@_print_model_box:Nn \l_@@_tmp_box { { } #1 }
\dim_set:Nn \l_@@_tmp_dim { \box_wd:N \l_@@_tmp_box }
\@@_print_format_box:Nn \l_@@_tmp_box { { } #3 }
\@@_print_format_auxxii:w #2 \q_mark #4 \q_stop
@@ -1562,7 +1584,7 @@
{
\tl_if_blank:nF {#2}
{
- \@@_print_format_box:Nn \l_@@_tmp_box { { } #1#2 }
+ \@@_print_model_box:Nn \l_@@_tmp_box { { } #1#2 }
\dim_set:Nn \l_@@_tmp_dim { \box_wd:N \l_@@_tmp_box }
\@@_print_format_box:Nn \l_@@_tmp_box
{
@@ -1570,7 +1592,7 @@
{ \l_@@_align_exponent_bool }
{ \tl_if_blank_p:n {#3} }
{
- \@@_print_format_box:Nn \l_@@_tmp_box { { } #1 { } }
+ \@@_print_model_box:Nn \l_@@_tmp_box { { } #1 { } }
\@@_skip:n { \box_wd:N \l_@@_tmp_box }
}
{ } #3#4
@@ -1580,16 +1602,27 @@
}
% \end{macrocode}
% A simple auxiliary to avoid relatively expensive use of the print routine
-% for empty parts.
+% for empty parts. There is a separate function for the model as this allows
+% for the case where different font widths are in use.
% \begin{macrocode}
\cs_new_protected:Npn \@@_print_format_box:Nn #1#2
+ { \@@_print_format_box:nNn { } #1 {#2} }
+\cs_generate_variant:Nn \@@_print_format_box:Nn { No }
+\cs_new_protected:Npn \@@_print_model_box:Nn #1#2
+ { \@@_print_format_box:VNn \l_@@_model_setup_tl #1 {#2} }
+\cs_generate_variant:Nn \@@_print_model_box:Nn { No }
+\cs_new_protected:Npn \@@_print_format_box:nNn #1#2#3
{
- \hbox_set:Nn #1
+ \hbox_set:Nn #2
{
- \tl_if_blank:nF {#2}
- { \siunitx_print_number:n {#2} }
+ \tl_if_blank:nF {#3}
+ {
+ #1
+ \siunitx_print_number:n {#3}
+ }
}
}
+\cs_generate_variant:Nn \@@_print_format_box:nNn { V }
% \end{macrocode}
% A common routine for placing material after the decimal marker and
% \enquote{shuffling}.
@@ -1653,6 +1686,7 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \subsection{Standard settings for module options}
%
diff --git a/macros/latex/contrib/siunitx/siunitx.dtx b/macros/latex/contrib/siunitx/siunitx.dtx
index d33a8c24b2..52dacc5c54 100644
--- a/macros/latex/contrib/siunitx/siunitx.dtx
+++ b/macros/latex/contrib/siunitx/siunitx.dtx
@@ -122,7 +122,7 @@
%
% Identify the package and give the over all version information.
% \begin{macrocode}
-\ProvidesExplPackage {siunitx} {2023-07-26} {3.2.9}
+\ProvidesExplPackage {siunitx} {2023-07-31} {3.3.0}
{A comprehensive (SI) units package}
% \end{macrocode}
%
@@ -184,16 +184,22 @@
%
% \subsection{Load time options}
%
-% \begin{variable}{\l_@@_column_type_tl}
+% \begin{variable}{\l_@@_list_tl, \l_@@_product_tl, \l_@@_column_type_tl}
% \begin{macrocode}
\keys_define:nn { siunitx }
{
+ list-input-separator .tl_set:N =
+ \l_@@_list_tl ,
+ product-input-separator .tl_set:N =
+ \l_@@_product_tl ,
table-column-type .tl_set:N =
\l_@@_column_type_tl
}
\keys_set:nn { siunitx }
{
- table-column-type = S
+ list-input-separator = ; ,
+ product-input-separator = x ,
+ table-column-type = S
}
% \end{macrocode}
% \end{variable}
@@ -257,7 +263,11 @@
% \begin{macrocode}
\IfFormatAtLeastTF { 2020-10-01 }
{ }
- { \RequirePackage { xparse } }
+ {
+ \RequirePackage { xparse }
+ \providecommand \ExpandArgs [1]
+ { \cs_if_exist_use:c { exp_args:N #1 } }
+ }
% \end{macrocode}
%
% \subsubsection{Preamble commands}
@@ -375,8 +385,12 @@
% {\qtylist, \numlist, \qtyproduct, \numproduct, \qtyrange, \numproduct}
% Interfaces for compound values.
% \begin{macrocode}
-\NewDocumentCommand \qtylist
- { O { } > { \SplitList { ; } } m > { \TrimSpaces } m }
+\ExpandArgs { Ne } \NewDocumentCommand \qtylist
+ {
+ O { }
+ > { \SplitList { \exp_not:V \l_@@_list_tl } } m
+ > { \TrimSpaces } m
+ }
{
\mode_leave_vertical:
\group_begin:
@@ -385,7 +399,11 @@
\siunitx_quantity_list:nn {#2} {#3}
\group_end:
}
-\NewDocumentCommand \numlist { O { } > { \SplitList { ; } } m }
+\ExpandArgs { Ne } \NewDocumentCommand \numlist
+ {
+ O { }
+ > { \SplitList { \exp_not:V \l_@@_list_tl } } m
+ }
{
\mode_leave_vertical:
\group_begin:
@@ -393,8 +411,12 @@
\siunitx_number_list:nn {#2}
\group_end:
}
-\NewDocumentCommand \qtyproduct
- { O { } > { \SplitList { x } } m > { \TrimSpaces } m }
+\ExpandArgs { Ne } \NewDocumentCommand \qtyproduct
+ {
+ O { }
+ > { \SplitList { \exp_not:V \l_@@_product_tl } } m
+ > { \TrimSpaces } m
+ }
{
\mode_leave_vertical:
\group_begin:
@@ -403,8 +425,11 @@
\siunitx_quantity_product:nn {#2} {#3}
\group_end:
}
-\NewDocumentCommand \numproduct
- { O { } > { \SplitList { x } } > { \TrimSpaces } m }
+\ExpandArgs { Ne } \NewDocumentCommand \numproduct
+ {
+ O { }
+ > { \SplitList { \exp_not:V \l_@@_product_tl } } m
+ }
{
\mode_leave_vertical:
\group_begin:
@@ -435,11 +460,8 @@
% \begin{macro}{\complexnum, \complexqty}
% Interfaces for complex numbers.
% \begin{macrocode}
-\use:e
- {
- \NewDocumentCommand \exp_not:N \complexnum
- { O { } > { \SplitArgument { 1 } { \c_colon_str } } m }
- }
+\ExpandArgs { Ne } \NewDocumentCommand \complexnum
+ { O { } > { \SplitArgument { 1 } { \c_colon_str } } m }
{
\mode_leave_vertical:
\group_begin:
@@ -447,11 +469,8 @@
\@@_complex_number_aux:nn #2
\group_end:
}
-\use:e
- {
- \NewDocumentCommand \exp_not:N \complexqty
- { O { } > { \SplitArgument { 1 } { \c_colon_str } } m m }
- }
+\ExpandArgs { Ne } \NewDocumentCommand \complexqty
+ { O { } > { \SplitArgument { 1 } { \c_colon_str } } m m }
{
\mode_leave_vertical:
\group_begin:
diff --git a/macros/latex/contrib/siunitx/siunitx.ins b/macros/latex/contrib/siunitx/siunitx.ins
index 6250eed33a..b2a35b2d4e 100644
--- a/macros/latex/contrib/siunitx/siunitx.ins
+++ b/macros/latex/contrib/siunitx/siunitx.ins
@@ -81,11 +81,11 @@ This work consists of the files siunitx.dtx,
\file{siunitx.sty}
{%
\from{siunitx.dtx} {package,init}
+ \from{siunitx-number.dtx} {package}
\from{siunitx-angle.dtx} {package}
\from{siunitx-complex.dtx} {package}
\from{siunitx-compound.dtx} {package}
\from{siunitx-locale.dtx} {package}
- \from{siunitx-number.dtx} {package}
\from{siunitx-print.dtx} {package}
\from{siunitx-table.dtx} {package}
\from{siunitx-unit.dtx} {package}
diff --git a/macros/latex/contrib/siunitx/siunitx.pdf b/macros/latex/contrib/siunitx/siunitx.pdf
index 5b832eb7e1..299ec6f781 100644
--- a/macros/latex/contrib/siunitx/siunitx.pdf
+++ b/macros/latex/contrib/siunitx/siunitx.pdf
Binary files differ
diff --git a/macros/latex/contrib/siunitx/siunitx.tex b/macros/latex/contrib/siunitx/siunitx.tex
index c3fad6bbc7..7b7221f66a 100644
--- a/macros/latex/contrib/siunitx/siunitx.tex
+++ b/macros/latex/contrib/siunitx/siunitx.tex
@@ -1,6 +1,6 @@
\iffalse meta-comment
-File: siunitx.tex Copyright (C) 2014-2022 Joseph Wright
+File: siunitx.tex Copyright (C) 2014-2023 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
@@ -640,9 +640,9 @@ The spelling \enquote{\cs{deka}} is provided for US users as an alternative to
\DescribePrefix{hecto} & 2 \\
\DescribePrefix{yocto} & -24 &
\DescribePrefix{kilo} & 3 \\
- \DescribePrefix{atto} & -18 &
- \DescribePrefix{mega} & 6 \\
\DescribePrefix{zepto} & -21 &
+ \DescribePrefix{mega} & 6 \\
+ \DescribePrefix{atto} & -18 &
\DescribePrefix{giga} & 9 \\
\DescribePrefix{femto} & -15 &
\DescribePrefix{tera} & 12 \\
@@ -883,6 +883,12 @@ occur (for example with the standard \cs{pm} symbol).
\midrule
+ \DescribeUnit[tesla]{T} \\
+ \DescribeUnit[millitesla]{mT} \\
+ \DescribeUnit[microtesla]{uT} \\
+
+ \midrule
+
\DescribeUnit[kelvin]{K} \\
\midrule
@@ -1305,6 +1311,7 @@ Table~\ref{tab:opt:num:in}.
input-ignore & Literal & \meta{none} \\
input-open-uncertainty & Literal & ( \\ ^^A )
input-signs & Literal & +-\cs{pm}\cs{mp} \\
+ input-uncertainty-divider & Literal & : \\
input-uncertainty-signs & Literal & \cs{pm} \\
parse-numbers & Switch & true \\
retain-explicit-decimal-marker & Switch & false \\
@@ -1364,18 +1371,38 @@ Uncertainties which cross the decimal marker may be given with or without a
decimal marker in \enquote{compact} form. These are treated as equivalent by
the code.\footnote{The package author favors the form without a decimal marker,
and formal guidance is ambiguous on which is correct. The form with a decimal
-marker is seen in for example some \acro{NIST} publications.}
+marker is seen in for example some \acro{NIST} publications.} Where multiple
+uncertainty values cross the decimal marker, they should all have the same
+number of digits.
\begin{LaTeXdemo}
\num{123.4(12)} \\
\num{123.4(1.2)}
\end{LaTeXdemo}
-Multiple uncertainties may also be given: these must all either be in the short
-or the long form.
+Multiple symmetrical uncertainties may also be given: these must all either be
+in the short or the long form.
\begin{LaTeXdemo}
\num{123.4(12)(45)} \\
\num{123.4 \pm 1.2 \pm 4.5}
\end{LaTeXdemo}
+\DescribeOption{input-uncertainty-divider}
+In some areas, uncertainties (or tolerances) are given in an asymmetric format.
+This is supported in the \enquote{compact} input form in \pkg{siunitx}, with
+the positive and negative parts of the uncertainty divided by a symbol listed
+in \opt{input-uncertainty-divider}. When given in this divided form, the
+two parts are interpreted as first the positive and then the negative
+component. Asymmetric uncertainties which cross the decimal marker are
+supported provided both components have the same number of digits.
+\begin{LaTeXdemo}
+ \num{10.56(12:34)} \\
+ \num{123.4(4.6:7.8)}
+\end{LaTeXdemo}
+Symmetrical and asymmetrical uncertainties may be intermixed.
+\begin{LaTeXdemo}
+ \num{10.56(1:2)(3)} \\
+ \num{6.45(2)(3:4)}
+\end{LaTeXdemo}
+
\DescribeOption{parse-numbers}
The \opt{parse-numbers} option turns the entire parsing system on and off. The
option is made available for two reasons. First, if all of the numbers in a
@@ -1445,20 +1472,22 @@ way; the options are summarised in Table~\ref{tab:opt:num:post}.
Type &
\multicolumn{1}{l@{}}{Default} \\
\midrule
- drop-exponent & Switch & false \\
- drop-uncertainty & Switch & false \\
- drop-zero-decimal & Switch & false \\
- exponent-mode & Switch & input \\
- exponent-thresholds & Literal & -3:3 \\
- fixed-exponent & Integer & 0 \\
- minimum-integer-digits & Integer & 0 \\
- minimum-decimal-digits & Integer & 0 \\
- round-half & Choice & up \\
- round-minimum & Literal & 0 \\
- round-mode & Choice & none \\
- round-pad & Switch & true \\
- round-precision & Integer & 2 \\
- round-zero-positive & Switch & true \\
+ drop-exponent & Switch & false \\
+ drop-uncertainty & Switch & false \\
+ drop-zero-decimal & Switch & false \\
+ exponent-mode & Switch & input \\
+ exponent-thresholds & Literal & -3:3 \\
+ fixed-exponent & Integer & 0 \\
+ minimum-integer-digits & Integer & 0 \\
+ minimum-decimal-digits & Integer & 0 \\
+ round-direction & Choice & nearest \\
+ round-half & Choice & up \\
+ round-minimum & Literal & 0 \\
+ round-mode & Choice & none \\
+ round-pad & Switch & true \\
+ round-precision & Integer & 2 \\
+ round-zero-positive & Switch & true \\
+ uncertainty-round-direction & Choice & nearest \\
\bottomrule
\end{tabular}
\end{table}
@@ -1593,11 +1622,31 @@ is controlled by the switch \opt{round-pad}, which is \opt{true} as standard.
\num[round-pad = false]{12.3}
\end{LaTeXdemo}
+\DescribeOption{round-direction}
\DescribeOption{round-half}
-In cases where the rounded part of a number is exactly half, there are two
-common methods for \enquote{breaking the tie}. The choice of method is
-determined by the option \opt{round-half}, which recognises the choices
-\opt{up} and \opt{even}.
+The detail of which approach to use for rounding may be adjusted using the
+options \opt{round-direction} and \opt{round-half}. The option
+\opt{round-direction} determines which direction a value is rounded toward: a
+choice of \opt{nearest}, \opt{up} or \opt{down}. The standard setting,
+\opt{nearest}, gives the common outcome that values round depending on whether
+the preceding digit is greater or less than \num{5}. The options \opt{up} and
+\opt{down} mean that values are always rounded in one direction: the \opt{down}
+option may be thought of as \enquote{truncation}.
+\begin{LaTeXdemo}
+ \sisetup{round-mode = places}
+ \num{0.054} \\
+ \num{0.046} \\
+ \sisetup{round-direction = down}%
+ \num{0.054} \\
+ \num{0.046} \\
+ \sisetup{round-direction = up}%
+ \num{0.054} \\
+ \num{0.046}
+\end{LaTeXdemo}
+For rounding to \opt{nearest}, where the rounded part of a number is exactly
+half, there are two common methods for \enquote{breaking the tie}. The choice
+of method is determined by the option \opt{round-half}, which recognises the
+choices \opt{up} and \opt{even}.
\begin{LaTeXdemo}
\sisetup{
round-mode = figures,
@@ -1611,6 +1660,17 @@ determined by the option \opt{round-half}, which recognises the choices
\num{0.045}
\end{LaTeXdemo}
+\DescribeOption{uncertainty-round-direction}
+When rounding with uncertainties, the direction to round the uncertainty part
+may be set independently of the main number: this is typically used to round
+the uncertainty strictly upward.
+\begin{LaTeXdemo}
+ \sisetup{round-mode = uncertainty}
+ \num{0.123(41)} \\
+ \sisetup{uncertainty-round-direction = up}%
+ \num{0.123(41)}
+\end{LaTeXdemo}
+
\DescribeOption{round-minimum}
There are cases in which rounding will result in the number reaching zero. It
may be desirable to show such results as below a threshold value. This can be
@@ -1944,20 +2004,30 @@ specialised options, which apply to these more unusual input forms
\multicolumn{1}{l}{Option name} &
Type &
\multicolumn{1}{l}{Default\tnote{*}} \\
- \midrule
- list-exponents & Choice & individual \\
- list-final-separator & Literal & \verb*= \text{and} = \\
- list-pair-separator & Literal & \verb*= \text{and} = \\
- list-separator & Literal & \verb*=\text{,} = \\
- list-units & Choice & repeat \\
- product-exponents & Choice & individual \\
- product-mode & Choice & symbol \\
- product-phrase & Literal & \verb*= \text{by} = \\
- product-symbol & Literal & \cs{times} \\
- product-units & Choice & repeat \\
- range-exponents & Choice & individual \\
- range-phrase & Literal & \verb*= \text{to} = \\
- range-units & Choice & repeat \\
+ \midrule % (
+ list-close-bracket & Literal & ) \\
+ list-exponents & Choice & individual \\
+ list-final-separator & Literal & \verb*= \text{and} = \\
+ list-independent-prefix & Switch & false \\
+ list-open-bracket & Literal & ( \\ % )
+ list-pair-separator & Literal & \verb*= \text{and} = \\
+ list-separator & Literal & \verb*=\text{,} = \\
+ list-units & Choice & repeat \\ % (
+ product-close-bracket & Literal & ) \\
+ product-exponents & Choice & individual \\
+ product-independent-prefix & Switch & false \\
+ product-mode & Choice & symbol \\
+ product-open-bracket & Literal & ( \\ % )
+ product-phrase & Literal & \verb*= \text{by} = \\
+ product-symbol & Literal & \cs{times} \\
+ product-units & Choice & repeat \\ % (
+ range-close-bracket & Literal & ) \\
+ range-exponents & Choice & individual \\
+ range-independent-prefix & Switch & false \\
+ range-open-bracket & Literal & ( \\ % )
+ range-open-phrase & Literal & \meta{empty} \\
+ range-phrase & Literal & \verb*= \text{to} = \\
+ range-units & Choice & repeat \\
\bottomrule
\end{tabular}
\footnotesize
@@ -2008,6 +2078,7 @@ as for numbers.
\numproduct[product-phrase = { BY }]{5 x 100 x 2} \\
\end{LaTeXdemo}
+\DescribeOption{range-open-phrase}
\DescribeOption{range-phrase}
Ranges of numbers can be given as input. These will have an appropriate word or
symbol inserted between the two entries: this is stored using the
@@ -2017,6 +2088,12 @@ extra space is added. The phrase is always printed in text mode.
\numrange{5}{100} \\
\numrange[range-phrase = --]{5}{100}
\end{LaTeXdemo}
+In some languages, an opening phrase is \emph{required}; this is supported
+using the \opt{range-open-phrase} key.
+\begin{LaTeXdemo}
+ \numrange{10}{12} \\
+ \numrange[range-open-phrase = {\text{from} }]{5}{100}
+\end{LaTeXdemo}
\DescribeOption{list-exponents}
\DescribeOption{product-exponents}
@@ -2078,6 +2155,48 @@ The option \opt{product-units} also offers the settings \opt{bracket-power} and
\qtyproduct[product-units = bracket-power]{2 x 4}{\metre} \\
\qtyproduct[product-units = power]{2 x 4}{\metre}
\end{LaTeXdemo}
+\DescribeOption{list-close-bracket}
+\DescribeOption{list-open-bracket}
+\DescribeOption{product-close-bracket}
+\DescribeOption{product-open-bracket}
+\DescribeOption{range-close-bracket}
+\DescribeOption{range-open-bracket}
+The brackets used can be customised using the relevant \texttt{\dots-close-bracket}
+and \texttt{\dots-open-bracket} options.
+\begin{LaTeXdemo}
+ \sisetup{
+ list-units = bracket ,
+ list-open-bracket = ( ,
+ list-close-bracket = )
+ }
+ \numlist{5e3;7e3;9e3;1e4} \\
+ \sisetup{
+ product-units = bracket ,
+ product-open-bracket = ( ,
+ product-close-bracket = )
+ }
+ \numproduct{5e3 x 7e3 x 9e3 x 1e4} \\
+ \sisetup{
+ range-units = bracket ,
+ range-open-bracket = ( ,
+ range-close-bracket = )
+ }
+ \qtyrange{2}{4}{\degreeCelsius}
+\end{LaTeXdemo}
+
+\DescribeOption{list-independent-prefix}
+\DescribeOption{product-independent-prefix}
+\DescribeOption{range-independent-prefix}
+When converting exponents to prefixes, there are two possible approaches to the
+case where units are repeated. They can all be converted to use the same
+(initial) prefix, or they can be processed separately. The
+\texttt{\dots-independent-prefix} options are used to control this outcome.
+\begin{LaTeXdemo}
+ \sisetup{exponent-to-prefix = true}%
+ \qtyrange{1e3}{1e9}{\watt}\\
+ \sisetup{range-independent-prefix = true}%
+ \qtyrange{1e3}{1e9}{\watt}
+\end{LaTeXdemo}
\subsection{Complex numbers}
@@ -2664,19 +2783,20 @@ to the layout of tabular material (Table~\ref{tab:opt:tables}).
Type &
\multicolumn{1}{l@{}}{Default} \\
\midrule
- table-align-comparator & Switch & true \\
- table-align-exponent & Switch & true \\
- table-align-text-after & Switch & true \\
- table-align-text-before & Switch & true \\
- table-align-uncertainty & Switch & true \\
- table-alignment & Meta & center \\
- table-alignment-mode & Choice & marker \\
- table-auto-round & Switch & false \\
- table-column-width & Length & 0pt \\
- table-fixed-width & Switch & false \\
- table-format & Special & 2.2 \\
- table-number-alignment & Choice & center \\
- table-text-alignment & Choice & center \\
+ table-align-comparator & Switch & true \\
+ table-align-exponent & Switch & true \\
+ table-align-text-after & Switch & true \\
+ table-align-text-before & Switch & true \\
+ table-align-uncertainty & Switch & true \\
+ table-alignment & Meta & center \\
+ table-alignment-mode & Choice & marker \\
+ table-auto-round & Switch & false \\
+ table-column-width & Length & 0pt \\
+ table-fixed-width & Switch & false \\
+ table-format & Special & 2.2 \\
+ table-model-setup & Literal & \meta{empty} \\
+ table-number-alignment & Choice & center \\
+ table-text-alignment & Choice & center \\
\bottomrule
\end{tabular}
\end{table}
@@ -2794,6 +2914,12 @@ table format argument are set to be absent (the number of figures is set to
zero). Setting the \opt{table-format} option also resets
\opt{table-alignment-mode} to \opt{format}.
+\DescribeOption{table-model-setup}
+In some tables (particularly those using bold extended fonts), it may be
+necessary to insert additional information when creating the \enquote{model}.
+This is handled using the \opt{table-model-setup} key. An example of the use of
+this key is given in Section~\ref{sec:hint:heading}.
+
Space for material before and after the \texttt{S} column can be reserved by
giving model text as part of the \opt{table-format} key. This is then used to
provide the necessary gap while maintaining alignment (Table~\ref{tab:S:ends}).
@@ -3122,6 +3248,15 @@ option is used to switch to a particular locale.
\subsection{Preamble-only options}
+\DescribeOption{list-input-separator}
+\DescribeOption{product-input-separator}
+The separator between \emph{input} elements of lists (\cs{numlist},
+\cs{qtylist}) and products (\cs{numproduct}, \cs{qtyproduct}) can be adjusted
+using the options \opt{list-input-separator} and \opt{product-input-separator},
+respectively. These are load-time only options as the separator here is part of
+the \enquote{document interface} rather than part of the individual number(s).
+The supplied value should be a \emph{single} marker.
+
\DescribeOption{table-column-type}
The letter(s) used to create table columns can be adjusted using the
\opt{table-column-type} option. The standard setting is |S|, but one or more
@@ -3753,20 +3888,30 @@ best approach is to make the \cs{bfseries} macro \enquote{robust} (as
demonstrated in Section~\ref{sec:hint:expanding}), then to use this macro to
make the heading cells bold. This approach is illustrated in
Table~\ref{tab:xmpl:headers}, along with the use of \cs{rowcolor} to provide a
-background color.
+background color. Some typical \LaTeX{} font arrangements use a wider
+(extended) width for the bold font compared with the normal font. This will
+disturb the alignment if the \opt{table-format} is not symmetrical. For these
+cases, the \opt{table-model-setup} key may be used to apply the wider font to
+the \enquote{model} used in ensuring alignment.
\begin{LaTeXdemo}[code and float]
\begin{table}
\caption{Header row in a table.%
\label{tab:xmpl:headers}}
\robustify\bfseries
\centering
+ \sisetup{text-series-to-math}
\begin{tabular}
- {@{}S[text-series-to-math, table-format = 3.3]@{}}
+ {
+ @{}
+ S[table-format = 3.3]
+ S[table-format = 3.6, table-model-setup = \bfseries]
+ @{}
+ }
\rowcolor[gray]{0.9}
- \bfseries 123.456 \\
- 23.45 \\
- 123.4 \\
- 3.456 \\
+ \bfseries 123.456 & \bfseries 123.456789 \\
+ 23.45 & 23.45 \\
+ 123.4 & 123.4 \\
+ 3.456 & 3.456 \\
\end{tabular}
\end{table}
\end{LaTeXdemo}
@@ -3852,6 +3997,63 @@ be loaded in the preamble using
\input{siunitx-local-units}
\end{LaTeXdemo}
+\subsection{Overloading the standard interfaces%
+ \label{sec:hint:overload}}
+
+The interfaces in \pkg{siunitx} deliberately split up different types of
+numerical input (ranges, products, etc.) for semantic reasons. This also means
+that there is less chance of confusion in parsing input. However, some users
+would prefer to overload the \cs{num} and \cs{qty} commands such that they
+accept multiple different types of input. There is a code-level interface that
+could be used for this, but most end-users will likely want to avoid this. A
+possible approach that covers most of the common cases is.
+\begin{LaTeXdemo}[code only]
+ \ExplSyntaxOn
+ \cs_gset_eq:NN \ifstrpresent \tl_if_in:nnTF
+ \ExplSyntaxOff
+ \NewCommandCopy\oldnum\num
+ \NewCommandCopy\oldnumrange\numrange
+ \RenewDocumentCommand\num{O{}m}{%
+ \ifstrpresent{#2}{x}
+ {\numproduct[#1]{#2}}
+ {%
+ \ifstrpresent{#2}{;}
+ {\numlist[#1]{#2}}
+ {%
+ \ifstrpresent{#2}{:}
+ {\numrange[#1]{#2}}
+ {\oldnum[#1]{#2}}%
+ }%
+ }%
+ }
+ \RenewDocumentCommand\numrange{O{}>{\SplitList{:}}m}
+ {\oldnumrange[#1]#2}
+\end{LaTeXdemo}
+for the \cs{num} command and
+\begin{LaTeXdemo}[code only]
+ \ExplSyntaxOn
+ \cs_gset_eq:NN \ifstrpresent \tl_if_in:nnTF
+ \ExplSyntaxOff
+ \NewCommandCopy\oldqty\qty
+ \NewCommandCopy\oldqtyrange\qtyrange
+ \RenewDocumentCommand\qty{O{}mm}{%
+ \ifstrpresent{#2}{x}
+ {\qtyproduct[#1]{#2}{#3}}
+ {%
+ \ifstrpresent{#2}{;}
+ {\qtylist[#1]{#2}{#3}}
+ {%
+ \ifstrpresent{#2}{:}
+ {\qtyrange[#1]{#2}{#3}}
+ {\oldqty[#1]{#2}{#3}}%
+ }%
+ }%
+ }
+ \RenewDocumentCommand\qtyrange{O{}>{\SplitList{:}}mm}
+ {\oldqtyrange[#1]#2{#3}}
+\end{LaTeXdemo}
+for \cs{qty}.
+
\section{Using (\acro{SI}) units}
Consistent and logical units are a necessity for scientific work, and have