summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx')
-rw-r--r--Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx606
1 files changed, 606 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx b/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx
new file mode 100644
index 00000000000..1b22b33a469
--- /dev/null
+++ b/Master/texmf-dist/source/latex/siunitx/siunitx-table.dtx
@@ -0,0 +1,606 @@
+% \iffalse meta-comment
+%
+% File: siunitx-table.dtx Copyright (C) 2016-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-table} -- Formatting numbers in tables^^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}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{siunitx-table} 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_table>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_tmp_tl}
+% Scratch space.
+% \begin{macrocode}
+\tl_new:N \l_@@_tmp_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Interface functions}
+%
+% \begin{variable}{\l_@@_parse_bool}
+% One top-level setting applies to all number cells.
+% \begin{macrocode}
+\keys_define:nn { siunitx / table }
+ {
+ parse .bool_set:N = \l_@@_parse_bool
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\siunitx_cell_begin:, \siunitx_cell_end:}
+% \begin{macrocode}
+\cs_new_protected:Npn \siunitx_cell_begin:
+ {
+ \bool_if:NTF \l_@@_parse_bool
+ { \@@_collect_begin: }
+ { \@@_direct_begin: }
+ }
+\cs_new_protected:Npn \siunitx_cell_end:
+ {
+ \@@_collect_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Collecting tokens}
+%
+% \begin{variable}{\l_@@_collect_tl}
+% Space for tokens.
+% \begin{macrocode}
+\tl_new:N \l_@@_collect_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_collect_begin:}
+% Collecting a tabular cell means doing a token-by-token collection.
+% In previous versions of \pkg{siunitx} that was done along with picking
+% out the numerical part, but the code flow ends up very tricky. Here,
+% therefore, we just collect up the unchanged tokens first. Some issues
+% with the way that the \texttt{peek} functions are currently set up in
+% \pkg{expl3} mean that at present there is a need to do stuff by hand
+% here. The definition of \cs{cr} is used to allow collection of any tokens
+% inserted after the main content when dealing with the last cell of a row:
+% the \enquote{group} around it is needed to avoid issues with the underlying
+% |\halign|. (The approach is based on that in \pkg{collcell}.) Notice that
+% as each cell forms a group there is no need to reset the definition of
+% \cs{cr}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_collect_begin:
+ {
+ \tl_clear:N \l_@@_collect_tl
+ \cs_set_protected:Npn \__peek_execute_branches:
+ {
+ \if_catcode:w \exp_not:N \l_peek_token \c_group_begin_token
+ \exp_after:wN \@@_collect_group:n
+ \else:
+ \exp_after:wN \@@_collect_token:N
+ \fi:
+ }
+ \if_false: { \fi:
+ \cs_set_protected:Npn \cr
+ {
+ \@@_collect_loop:
+ \tex_cr:D
+ }
+ \if_false: } \fi:
+ \@@_collect_loop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_collect_loop:}
+% \begin{macro}{\@@_collect_group:n}
+% \begin{macro}{\@@_collect_token:N}
+% \begin{macro}{\@@_collect_search:NnF}
+% \begin{macro}{\@@_collect_search_aux:NNn}
+% Collecting up the cell content needs a loop: this is done using
+% a |peek| approach as it's most natural. (A slower approach is possible
+% using something like the |\tl_lower_case:n| loop code.) The set of
+% possible tokens is somewhat limited compared to an arbitrary cell
+% (\foreign{cf.}~the approach in \pkg{collcell}): the special cases are
+% pulled out for manual handling. The flexible lookup approach is more-or-less
+% the same idea as in the kernel |case| functions. The |\relax| special case
+% covers the case where |\\| has been expanded in an empty cell.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_collect_loop:
+ { \peek_after:Nw \__peek_ignore_spaces_execute_branches: }
+\cs_new_protected:Npn \@@_collect_group:n #1
+ {
+ \tl_put_right:Nn \l_@@_collect_tl { {#1} }
+ \@@_collect_loop:
+ }
+\cs_new_protected:Npn \@@_collect_token:N #1
+ {
+ \@@_collect_search:NnF #1
+ {
+ \ignorespaces { \@@_collect_loop: }
+ \unskip { \@@_collect_loop: }
+ \end { \tabularnewline \end }
+ \relax { \relax }
+ \tabularnewline { \tabularnewline }
+ \siunitx_cell_end: { \siunitx_cell_end: }
+ }
+ {
+ \tl_put_right:Nn \l_@@_collect_tl {#1}
+ \@@_collect_loop:
+ }
+ }
+\AtBeginDocument
+ {
+ \@ifpackageloaded { mdwtab }
+ {
+ \cs_set_protected:Npn \@@_collect_token:N #1
+ {
+ \@@_collect_search:NnF #1
+ {
+ \@maybe@unskip { \@@_collect_loop: }
+ \ignorespaces { \@@_collect_loop: }
+ \tab@setcr { \@@_collect_loop: }
+ \unskip { \@@_collect_loop: }
+ \end { \tabularnewline \end }
+ \relax { \relax }
+ \tabularnewline { \tabularnewline }
+ \siunitx_cell_end: { \siunitx_cell_end: }
+ }
+ {
+ \tl_put_right:Nn \l_@@_collect_tl {#1}
+ \@@_collect_loop:
+ }
+ }
+ }
+ { }
+ }
+\cs_new_protected:Npn \@@_collect_search:NnF #1#2#3
+ {
+ \@@_collect_search_aux:NNn #1
+ #2
+ #1 {#3}
+ \q_stop
+ }
+\cs_new_protected:Npn \@@_collect_search_aux:NNn #1#2#3
+ {
+ \token_if_eq_meaning:NNTF #1 #2
+ { \use_i_delimit_by_q_stop:nw {#3} }
+ { \@@_collect_search_aux:NNn #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Separating collected material}
+%
+% The input needs to be divided into numerical tokens and those which appear
+% before and after them. This needs a second loop and validation.
+%
+% \begin{variable}{\l_@@_pre_tl, \l_@@_number_tl, \l_@@_post_tl}
+% Space for tokens.
+% \begin{macrocode}
+\tl_new:N \l_@@_pre_tl
+\tl_new:N \l_@@_number_tl
+\tl_new:N \l_@@_post_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_collect_end:}
+% At the end of the cell, expand all of the content as far as possible then
+% split it up into numerical and non-numerical parts.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_collect_end:
+ {
+ \protected@edef \l_@@_collect_tl
+ { \l_@@_collect_tl }
+ \tl_clear:N \l_@@_pre_tl
+ \tl_clear:N \l_@@_number_tl
+ \tl_clear:N \l_@@_post_tl
+ \cs_set_protected:Npn \__peek_execute_branches:
+ {
+ \if_catcode:w \exp_not:N \l_peek_token \c_group_begin_token
+ \exp_after:wN \@@_split_group:n
+ \else:
+ \exp_after:wN \@@_split_token:N
+ \fi:
+ }
+ \exp_after:wN \@@_split_loop: \l_@@_collect_tl
+ \q_recursion_tail \q_recursion_stop
+ \@@_split_tidy:N \l_@@_pre_tl
+ \@@_split_tidy:N \l_@@_post_tl
+ \tl_if_empty:NTF \l_@@_number_tl
+ { \@@_print_text:V \l_@@_pre_tl }
+ {
+ \@@_print:VVV
+ \l_@@_pre_tl
+ \l_@@_number_tl
+ \l_@@_post_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_split_loop:}
+% \begin{macro}{\@@_split_group:n}
+% \begin{macro}{\@@_split_token:N}
+% Splitting into parts uses the fact that numbers cannot contain groups
+% and that we can track where we are up to based on the content of the
+% token lists.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_split_loop:
+ { \peek_after:Nw \__peek_ignore_spaces_execute_branches: }
+\cs_new_protected:Npn \@@_split_group:n #1
+ {
+ \tl_if_empty:NTF \l_@@_number_tl
+ { \tl_put_right:Nn \l_@@_pre_tl { {#1} } }
+ { \tl_put_right:Nn \l_@@_post_tl { {#1} } }
+ \@@_split_loop:
+ }
+\cs_new_protected:Npn \@@_split_token:N #1
+ {
+ \quark_if_recursion_tail_stop:N #1
+ \tl_if_empty:NTF \l_@@_post_tl
+ {
+ \siunitx_if_number_token:NTF #1
+ { \tl_put_right:Nn \l_@@_number_tl {#1} }
+ {
+ \tl_if_empty:NTF \l_@@_number_tl
+ { \tl_put_right \l_@@_pre_tl {#1} }
+ { \tl_put_right \l_@@_post_tl {#1} }
+ }
+ }
+ { \tl_put_right:Nn \l_@@_post_tl {#1} }
+ \@@_split_loop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_split_tidy:N}
+% \begin{macro}{\@@_split_tidy:Nn, \@@_split_tidy:NV}
+% A quick test for the entire content being surrounded by a set of braces:
+% rather than look explicitly, use the fact that a string comparison can
+% detect the same thing. The auxiliary is needed to avoid having to go
+% \foreign{via} a |:D| function (for the expansion behaviour).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_split_tidy:N #1
+ {
+ \tl_if_empty:NF #1
+ { \@@_split_tidy:NV #1 #1 }
+ }
+\cs_new_protected:Npn \@@_split_tidy:Nn #1#2
+ {
+ \str_if_eq_x:nnT
+ { \exp_not:n {#2} }
+ { { \exp_not:o { \use:n #2 } } }
+ { \tl_set:No #1 { \use:n #2 } }
+ }
+\cs_generate_variant:Nn \@@_split_tidy:Nn { NV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Printing numbers in cells: spacing}
+%
+% Getting the general alignment correct in tables is made more complex than one
+% would like by the \pkg{colortbl} package. In the original \LaTeXe{}
+% definition, cell material is centred by a construction of the (primitive)
+% form
+% \begin{verbatim}
+% \hfil
+% #
+% \hfil
+% \end{verbatim}
+% which only uses \texttt{fil} stretch. That is altered by \pkg{colortbl} to
+% broadly
+% \begin{verbatim}
+% \hskip 0pt plus 0.5fill
+% \kern 0pt
+% #
+% \hskip 0pt plus 0.5fill
+% \end{verbatim}
+% which means there is \texttt{fill} stretch to worry about and the kern as
+% well.
+%
+% \begin{macro}{\@@_skip:n}
+% To prevent combination of skips, a kern is inserted after each one.
+% This is best handled as a short auxiliary.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_skip:n #1
+ {
+ \skip_horizontal:n {#1}
+ \tex_kern:D \c_zero_skip
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_column_width_dim, \l_@@_fixed_width_bool}
+% Settings which apply to aligned columns in general.
+% \begin{macrocode}
+\keys_define:nn { siunitx / table }
+ {
+ column-width .dim_set:N =
+ \l_@@_column_width_dim ,
+ fixed-width .bool_set:N =
+ \l_@@_fixed_width_bool
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_align_center:n, \@@_align_left:n, \@@_align_right:n}
+% \begin{macro}{\@@_align_auxi:nn, \@@_align_auxii:nn}
+% The beginning and end of each table cell have to adjust the position of
+% the content using glue. When \pkg{colortbl} is loaded the glue is done in
+% two parts: one for our positioning and one to explicitly override that from
+% the package. Using a two-step auxiliary chain avoids needing to repeat any
+% code and the impact of the extra expansion should be trivial.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_align_center:n #1
+ { \@@_align_auxi:nn {#1} { 0pt plus 0.5fill } {#1} }
+\cs_new_protected:Npn \@@_align_left:n #1
+ { \@@_align_auxi:nn {#1} { 0pt } {#1} }
+\cs_new_protected:Npn \@@_align_right:n #1
+ { \@@_align_auxi:nn {#1} { 0pt plus 1fill } {#1} }
+\cs_new_protected:Npn \@@_align_auxi:nn #1#2
+ {
+ \bool_if:NTF \l_@@_fixed_width_bool
+ { \hbox_to_wd:nn \l_@@_column_width_dim }
+ { \use:n }
+ {
+ \@@_skip:n {#2}
+ #1
+ \@@_skip:n { 0pt plus 1fill - #2 }
+ }
+ }
+\AtBeginDocument
+ {
+ \@ifpackageloaded { colortbl }
+ {
+ \cs_new_eq:NN
+ \@@_align_auxii:nn
+ \@@_align_auxi:nn
+ \cs_set_protected:Npn \@@_align_auxi:nn #1#2
+ {
+ \@@_skip:n{ 0pt plus -0.5fill }
+ \@@_align_auxii:nn {#1} {#2}
+ \@@_skip:n { 0pt plus -0.5fill }
+ }
+ }
+ { }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Printing just text}
+%
+% In cases where there is no numerical part, \pkg{siunitx} allows alignment
+% of the \enquote{escaped} text independent of the underlying column type.
+%
+% \begin{variable}{\l_@@_align_text_tl}
+% Alignment is handled using a |tl| as this allows a fast lookup at the
+% point of use.
+% \begin{macrocode}
+\keys_define:nn { siunitx / table }
+ {
+ text-alignment .choices:nn =
+ { center , left , right }
+ { \tl_set:Nn \l_@@_align_text_tl {#1} } ,
+ }
+\tl_new:N \l_@@_align_text_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_print_text:n, \@@_print_text:V}
+% Printing escaped text is easy: just place it in correctly in the
+% column.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_text:n #1
+ {
+ \use:c { @@_align_ \l_@@_align_text_tl :n } {#1}
+ }
+\cs_generate_variant:Nn \@@_print_text:n { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Reserving space: the table format}
+%
+% \begin{variable}{\l_@@_format_tl}
+% \begin{macrocode}
+\keys_define:nn { siunitx / table }
+ {
+ format .tl_set:N = \l_@@_format_tl
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Directly printing without collection}
+%
+% Collecting the number allows for various effects but is not as fast
+% as simply aligning on the first token that is a decimal marker. The
+% strategy here is that used by \pkg{dcolumn}.
+%
+% \begin{macro}{\@@_direct_begin:}
+% \begin{macro}{\@@_direct_begin:w}
+% \begin{macro}{\@@_direct_begin_aux:}
+% After removing the |\ignorespaces| at the start of the cell, check to see
+% if there is a |{| and branch as appropriate.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_direct_begin:
+ { \@@_direct_begin:w }
+\cs_new_protected:Npn \@@_direct_begin:w \ignorespaces
+ {
+ \cs_set:Npn \__peek_execute_branches:
+ {
+ \if_catcode:w \exp_not:N \l_peek_token \c_group_begin_token
+ \exp_after:wN \@@_print_text:n
+ \else:
+ \m@th
+ \exp_after:wN \@@_direct_begin_aux:
+ \fi:
+ }
+ \peek_after:Nw \__peek_ignore_spaces_execute_branches:
+ }
+\cs_new_protected:Npn \@@_direct_begin_aux:
+ {
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Printing numbers in cells: main functions}
+%
+% \begin{variable}
+% {
+% \l_@@_align_comparator_bool ,
+% \l_@@_align_exponent_bool ,
+% \l_@@_align_uncertainty_bool ,
+% \l_@@_alignment_tl ,
+% \l_@@_parse_only_bool
+% }
+% Alignment is handled using a |tl| as this allows a fast lookup at the
+% point of use.
+% \begin{macrocode}
+\keys_define:nn { siunitx / table }
+ {
+ align-comparator .bool_set:N =
+ \l_@@_align_comparator_bool ,
+ align-exponent .bool_set:N =
+ \l_@@_align_exponent_bool ,
+ align-uncertainty .bool_set:N =
+ \l_@@_align_uncertainty_bool ,
+ alignment .choices:nn =
+ { center , left , right }
+ { \tl_set:Nn \l_@@_alignment_tl {#1} } ,
+ parse-only .bool_set:N =
+ \l_@@_parse_only_bool
+ }
+\tl_new:N \l_@@_alignment_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_print:nnn, \@@_print:VVV}
+% \begin{macro}{\@@_print_non_aligned:nnn, \@@_print_aligned:nnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print:nnn #1#2#3
+ {
+ \use:c { @@_align_ \l_@@_alignment_tl :n }
+ {
+ \bool_if:NTF \l_@@_parse_only_bool
+ { \@@_print_non_aligned:nnn }
+ { \@@_print_aligned:nnn }
+ {#1} {#2} {#3}
+ }
+ }
+\cs_generate_variant:Nn \@@_print:nnn { VVV }
+\cs_new_protected:Npn \@@_print_non_aligned:nnn #1#2#3
+ {
+ #1
+ \siunitx_number_format:nN {#2} \l_@@_tmp_tl
+ \siunitx_print:nV { number } \l_@@_tmp_tl
+ #3
+ }
+\cs_new_protected:Npn \@@_print_aligned:nnn #1#2#3
+ {
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Standard settings for module options}
+%
+% Some of these follow naturally from the point of definition
+% (\foreign{e.g.}~boolean variables are always |false| to begin with),
+% but for clarity everything is set here.
+% \begin{macrocode}
+\keys_set:nn { siunitx / table }
+ {
+ align-comparator = false ,
+ align-exponent = false ,
+ align-uncertainty = false ,
+ alignment = center ,
+ column-width = 0pt ,
+ fixed-width = false ,
+ format = ,
+ parse = true ,
+ parse-only = false ,
+ text-alignment = center
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file