diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental/l3dt/l3dt.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3experimental/l3dt/l3dt.dtx | 528 |
1 files changed, 222 insertions, 306 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3dt/l3dt.dtx b/Master/texmf-dist/source/latex/l3experimental/l3dt/l3dt.dtx index 0fd090d9ef7..be3fc8eb1c1 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3dt/l3dt.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3dt/l3dt.dtx @@ -36,7 +36,7 @@ % %<*driver|package> \RequirePackage{expl3} -\GetIdInfo$Id: l3dt.dtx 3459 2012-02-26 08:58:53Z joseph $ +\GetIdInfo$Id: l3dt.dtx 3877 2012-06-30 22:24:42Z joseph $ {L3 Experimental data tables} %</driver|package> %<*driver> @@ -165,9 +165,9 @@ % % \section{Removing data} % -% \begin{function}{\dt_del:Nn, \dt_gdel:Nn} +% \begin{function}{\dt_remove:Nn, \dt_gremove:Nn} % \begin{syntax} -% \cs{dt_del:Nn} \meta{dt} \Arg{key} +% \cs{dt_remove:Nn} \meta{dt} \Arg{key} % \end{syntax} % Deletes any entry from the current row of the \meta{data table} with % the \meta{key}. The \meta{key} is compared after processing with @@ -175,9 +175,9 @@ % all entries from a row does not delete the row itself. % \end{function} % -% \begin{function}{\dt_del:Nnn, \dt_gdel:Nnn} +% \begin{function}{\dt_remove:Nnn, \dt_gremove:Nnn} % \begin{syntax} -% \cs{dt_del:Nnn} \meta{dt} \Arg{row} \Arg{key} +% \cs{dt_remove:Nnn} \meta{dt} \Arg{row} \Arg{key} % \end{syntax} % Deletes any entry from the \meta{row} of the \meta{data table} with % the \meta{key}. The \meta{key} is compared after processing with @@ -384,88 +384,6 @@ % Scratch data tables for general use: these are never used by the kernel. % \end{variable} % -% \section{Internal function} -% -% \begin{variable}{\q_dt, \q_dt_header, \q_dt_row} -% Quarks used to construct the data table format. -% \end{variable} -% -% \begin{function}[EXP]{\dt_split_header:NT} -% \begin{syntax} -% \cs{dt_split_header:Nn} \meta{dt} \Arg{code} -% \end{syntax} -% Splits the \meta{data table} into the header part (containing the total -% number of rows present and the key list) and the body (containing the -% rows). The \meta{code} is then inserted, and should absorb the two parts -% of the split table as arguments. -% \end{function} -% -% \begin{function}{\dt_split_key:nnTF} -% \begin{syntax} -% \cs{dt_split_key:nnTF} \Arg{row} \Arg{key} \Arg{true code} \Arg{false code} -% \end{syntax} -% Searches the \meta{row} for the \meta{key}, using the -% comparison method as described for \cs{str_if_eq:nn}. If the \meta{key} is -% present, the \meta{true code} is left in the input stream followed by -% three \meta{balanced text} arguments -% \begin{enumerate} -% \item the partial \meta{row} for all keys before the \meta{key}, -% \item the \meta{value} for the \meta{key} and -% \item the partial \meta{row} for all keys after the \meta{key}. -% \end{enumerate} -% Thus the \meta{true code} must absorb three arguments. -% The two partial tables are structured such they may be recombined directly -% to produce a valid row lacking the entry for the \meta{key}. -% -% If the \meta{key} is not found in the \meta{row}, then the \meta{false code} -% is left in the input stream with no arguments. -% \end{function} -% -% \begin{function}{\dt_split_key_list:NnTF} -% \begin{syntax} -% \cs{dt_split_key_list:NnTF} \meta{dt} \Arg{key} \Arg{true code} \Arg{false code} -% \end{syntax} -% Searches the key list of the \meta{dt} for the \meta{key}, using the -% comparison method as described for \cs{str_if_eq:nn}. If the \meta{key} is -% present, the \meta{true code} is left in the input stream followed by -% five \meta{balanced text} arguments -% \begin{enumerate} -% \item the partial table for all keys before the \meta{key}, -% \item the \meta{id} for the \meta{key}, -% \item the \meta{type} for the \meta{key}, -% \item the \meta{header} for the \meta{key} and -% \item the partial table for all keys after the \meta{key}. -% \end{enumerate} -% Thus the \meta{true code} must absorb five arguments. -% The two partial tables are structured such they may be recombined directly -% to produce a valid key table lacking the entry for the \meta{key}. -% -% If the \meta{key} is not found in the key table, then the \meta{false code} -% is left in the input stream with no arguments. -% \end{function} -% -% \begin{function}{\dt_split_row:NnTF} -% \begin{syntax} -% \cs{dt_split_row:NnTF} \meta{dt} \Arg{row} \Arg{true code} \Arg{false code} -% \end{syntax} -% Searches the key list of the \meta{dt} for the \meta{row} -% (an \meta{integer expression}). If the -% \meta{row} is present, the \meta{true code} is left in the input stream -% followed by three \meta{balanced text} arguments -% \begin{enumerate} -% \item the partial table before the \meta{row}, -% \item the content of the \meta{row}, starting and ending with the -% row number, -% \item the partial table after the \meta{row}. -% \end{enumerate} -% Thus the \meta{true code} must absorb three arguments. -% The two partial tables are structured such they may be recombined directly -% to produce a valid key table lacking the entry for the \meta{row}. -% -% If the \meta{row} is not found in the key table, then the \meta{false code} -% is left in the input stream with no arguments. -% \end{function} -% % \end{documentation} % % \begin{implementation} @@ -475,12 +393,15 @@ % \begin{macrocode} %<*initex|package> % \end{macrocode} +% +% \begin{macrocode} +%<@@=dt> +% \end{macrocode} % % \begin{macrocode} %<*package> \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} -\package_check_loaded_expl: %</package> % \end{macrocode} % @@ -495,34 +416,34 @@ % numbered: % \begin{quote} % \Arg{rows} \\ -% \cs{q_dt} \meta{key$_0$} \cs{q_dt} \meta{key$_1$} \cs{q_dt} \ldots \\ +% \cs{q_@@} \meta{key$_0$} \cs{q_@@} \meta{key$_1$} \cs{q_@@} \ldots \\ % \cs{q_nil} \\ -% \cs{q_dt_header} \\ -% \cs{q_dt_row} \\ +% \cs{q_@@_header} \\ +% \cs{q_@@_row} \\ % \meta{row$_0$} \\ -% \cs{q_dt} \meta{key$_0$} \cs{q_dt} \Arg{data$_{0,0}$} \\ -% \cs{q_dt} \meta{key$_1$} \cs{q_dt} \Arg{data$_{0,1}$} \\ +% \cs{q_@@} \meta{key$_0$} \cs{q_@@} \Arg{data$_{0,0}$} \\ +% \cs{q_@@} \meta{key$_1$} \cs{q_@@} \Arg{data$_{0,1}$} \\ % \ldots \\ -% \cs{q_dt} \\ +% \cs{q_@@} \\ % \cs{q_nil} \\ -% \cs{q_dt_row} \\ +% \cs{q_@@_row} \\ % \meta{row$_2$} \\ -% \cs{q_dt} \meta{key$_0$} \cs{q_dt} \Arg{data$_{1,0}$} \\ -% \cs{q_dt} \meta{key$_1$} \cs{q_dt} \Arg{data$_{1,1}$} \\ +% \cs{q_@@} \meta{key$_0$} \cs{q_@@} \Arg{data$_{1,0}$} \\ +% \cs{q_@@} \meta{key$_1$} \cs{q_@@} \Arg{data$_{1,1}$} \\ % \ldots \\ -% \cs{q_dt} \\ +% \cs{q_@@} \\ % \cs{q_nil} \\ -% \cs{q_dt_row} \\ +% \cs{q_@@_row} \\ % \ldots \\ -% \cs{q_dt_row} +% \cs{q_@@_row} % \end{quote} % -% \begin{variable}{\q_dt, \q_dt_row, \q_dt_header} +% \begin{variable}{\q_@@, \q_@@_row, \q_@@_header} % The quarks are set up. % \begin{macrocode} -\quark_new:N \q_dt -\quark_new:N \q_dt_row -\quark_new:N \q_dt_header +\quark_new:N \q_@@ +\quark_new:N \q_@@_row +\quark_new:N \q_@@_header % \end{macrocode} % \end{variable} % @@ -533,10 +454,10 @@ \tl_const:Nn \c_empty_dt { { 0 } - \q_dt + \q_@@ \q_nil - \q_dt_header - \q_dt_row + \q_@@_header + \q_@@_row } % \end{macrocode} % \end{variable} @@ -590,104 +511,104 @@ % % \subsection{Splitting functions} % -% \begin{macro}[aux]{\dt_split_aux:nnnn} -% \begin{macro}[aux]{\dt_split_aux:w} +% \begin{macro}[aux]{\@@_split:nnnn} +% \begin{macro}[aux]{\@@_split:w} % Two general auxiliaries. The \texttt{nnnn} function is used to apply the % \texttt{T} branch if a match is found and the \texttt{F} branch otherwise. % The \texttt{w} function is general purpose, and is used to define the % matching parameter set. % \begin{macrocode} -\cs_new_protected:Npn \dt_split_aux:nnnn #1#2#3#4 { #3 #2 } -\cs_new_protected:Npn \dt_split_aux:w { } +\cs_new_protected:Npn \@@_split:nnnn #1#2#3#4 { #3 #2 } +\cs_new_protected:Npn \@@_split:w { } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int,EXP]{\dt_split_header:NT} -% \begin{macro}[aux,EXP]{\dt_split_header_aux:wn} +% \begin{macro}[int,EXP]{\@@_split_header:NT} +% \begin{macro}[aux,EXP]{\@@_split_header:wn} % Splits the header from the table, inserting the code required to then % process the split table. The \cs{q_nil} is also removed from the end of the % header, as it is essentially a distraction here. % \begin{macrocode} -\cs_new:Npn \dt_split_header:NT #1#2 - { \exp_after:wN \dt_split_header_aux:wn #1 \q_stop {#2} } -\cs_new:Npn \dt_split_header_aux:wn #1 \q_nil \q_dt_header #2 \q_stop #3 - { #3 {#1} { \q_dt_header #2 } } +\cs_new:Npn \@@_split_header:NT #1#2 + { \exp_after:wN \@@_split_header:wn #1 \q_stop {#2} } +\cs_new:Npn \@@_split_header:wn #1 \q_nil \q_@@_header #2 \q_stop #3 + { #3 {#1} { \q_@@_header #2 } } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int]{\dt_split_key:nnTF} -% \begin{macro}[aux]{\dt_split_key_aux:nnTF} +% \begin{macro}[int]{\@@_split_key:nnTF} +% \begin{macro}[aux]{\@@_split_key_aux:nnTF} % Here, the split is made for a partial list within a row. The row is % basically the same as a property list, so the split here is almost % identical to that in \cs{prop_split_aux:NnTF}. The row-end data is set up % such that it will not interfere with this process. % \begin{macrocode} -\cs_new_protected:Npn \dt_split_key:nnTF #1#2 - { \exp_args:No \dt_split_key_aux:nnTF { \tl_to_str:n {#2} } {#1} } -\cs_new_protected:Npn \dt_split_key_aux:nnTF #1#2 +\cs_new_protected:Npn \@@_split_key:nnTF #1#2 + { \exp_args:No \@@_split_key_aux:nnTF { \tl_to_str:n {#2} } {#1} } +\cs_new_protected:Npn \@@_split_key_aux:nnTF #1#2 { - \cs_set_protected:Npn \dt_split_aux:w - ##1 \q_dt #1 \q_dt ##2##3##4 \q_mark ##5 \q_stop - { \dt_split_aux:nnnn ##3 { { ##1 \q_dt } {##2} {##4} } } - \dt_split_aux:w #2 \q_mark - \q_dt #1 \q_dt { } { ? \use_ii:nn { } } \q_mark \q_stop + \cs_set_protected:Npn \@@_split:w + ##1 \q_@@ #1 \q_@@ ##2##3##4 \q_mark ##5 \q_stop + { \@@_split:nnnn ##3 { { ##1 \q_@@ } {##2} {##4} } } + \@@_split:w #2 \q_mark + \q_@@ #1 \q_@@ { } { ? \use_ii:nn { } } \q_mark \q_stop } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int]{\dt_split_key_list:NnTF} -% \begin{macro}[aux]{\dt_split_key_list_aux:NnTF} +% \begin{macro}[int]{\@@_split_key_list:NnTF} +% \begin{macro}[aux]{\@@_split_key_list_aux:NnTF} % Finding a key in the header uses a similar approach to finding a key in % a property list. Here, if the key is found there will always be at least -% one token between \cs{q_dt} and \cs{q_dt_header} due to the \cs{q_nil} -% which is part of a new table. The use of |##1##2| in \cs{dt_split_aux:w} +% one token between \cs{q_@@} and \cs{q_@@_header} due to the \cs{q_nil} +% which is part of a new table. The use of |##1##2| in \cs{@@_split:w} % here is to deal with the overall number of rows. The set up here means % that this will always be unbraced then rebraced: simply grabbing |##1| % to include this and anything before the key of interest will give variable % results depending on whether the match is to the very first key or not. % \begin{macrocode} -\cs_new_protected:Npn \dt_split_key_list:NnTF #1#2 - { \exp_args:NNo \dt_split_key_list_aux:NnTF #1 { \tl_to_str:n {#2} } } -\cs_new_protected:Npn \dt_split_key_list_aux:NnTF #1#2 +\cs_new_protected:Npn \@@_split_key_list:NnTF #1#2 + { \exp_args:NNo \@@_split_key_list_aux:NnTF #1 { \tl_to_str:n {#2} } } +\cs_new_protected:Npn \@@_split_key_list_aux:NnTF #1#2 { - \cs_set_protected:Npn \dt_split_aux:w - ##1##2 \q_dt #2 \q_dt ##3##4 \q_dt_header ##5 \q_mark ##6 \q_stop + \cs_set_protected:Npn \@@_split:w + ##1##2 \q_@@ #2 \q_@@ ##3##4 \q_@@_header ##5 \q_mark ##6 \q_stop { - \dt_split_aux:nnnn ##3 - { { {##1} ##2 \q_dt } { ##3##4 \q_dt_header ##5 } } + \@@_split:nnnn ##3 + { { {##1} ##2 \q_@@ } { ##3##4 \q_@@_header ##5 } } } - \exp_after:wN \dt_split_aux:w #1 \q_mark - \q_dt #2 \q_dt { ? \use_ii:nn { } } \q_dt_header \q_mark \q_stop + \exp_after:wN \@@_split:w #1 \q_mark + \q_@@ #2 \q_@@ { ? \use_ii:nn { } } \q_@@_header \q_mark \q_stop } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int]{\dt_split_row:NnTF} -% \begin{macro}[aux]{\dt_split_row_aux:NnTF, \dt_split_row_aux:NfTF} +% \begin{macro}[int]{\@@_split_row:NnTF} +% \begin{macro}[aux]{\@@_split_row_aux:NnTF, \@@_split_row_aux:NfTF} % The usual approach, here using the fact that each row start with row number % and ends with \cs{q_nil} so there will always be at least one token to be % absorbed as |##2|. The only odd thing to watch here is that the row % number is evaluated so that higher-level functions in the main do not % need to have an \texttt{f}-type variant. % \begin{macrocode} -\cs_new_protected:Npn \dt_split_row:NnTF #1#2 - { \dt_split_row_aux:NfTF #1 { \int_eval:n {#2} } } -\cs_new_protected:Npn \dt_split_row_aux:NnTF #1#2 +\cs_new_protected:Npn \@@_split_row:NnTF #1#2 + { \@@_split_row_aux:NfTF #1 { \int_eval:n {#2} } } +\cs_new_protected:Npn \@@_split_row_aux:NnTF #1#2 { - \cs_set_protected:Npn \dt_split_aux:w - ##1 \q_dt_row #2 \q_dt ##2##3 \q_dt_row ##4 \q_mark ##5 \q_stop + \cs_set_protected:Npn \@@_split:w + ##1 \q_@@_row #2 \q_@@ ##2##3 \q_@@_row ##4 \q_mark ##5 \q_stop { - \dt_split_aux:nnnn ##2 - { { ##1 \q_dt_row } { #2 \q_dt ##2##3 } {##4} } + \@@_split:nnnn ##2 + { { ##1 \q_@@_row } { #2 \q_@@ ##2##3 } {##4} } } - \exp_after:wN \dt_split_aux:w #1 \q_mark - \q_dt_row #2 \q_dt { ? \use_ii:nn { } } \q_dt_row \q_mark \q_stop + \exp_after:wN \@@_split:w #1 \q_mark + \q_@@_row #2 \q_@@ { ? \use_ii:nn { } } \q_@@_row \q_mark \q_stop } -\cs_generate_variant:Nn \dt_split_row_aux:NnTF { Nf } +\cs_generate_variant:Nn \@@_split_row_aux:NnTF { Nf } % \end{macrocode} % \end{macro} % \end{macro} @@ -695,33 +616,33 @@ % \subsection{Adding and removing data} % % \begin{macro}{\dt_add_key:Nn, \dt_gadd_key:Nn} -% \begin{macro}[aux]{\dt_add_key_aux:NNn} -% \begin{macro}[aux]{\dt_add_key_aux:NNnnn} +% \begin{macro}[aux]{\@@_add_key:NNn} +% \begin{macro}[aux]{\@@_add_key:NNnnn} % Here, there are two stages. If the key is already present in the list of % known keys then no action is taken, and the split list is thrown away. % On the other hand, if the key is not present then the header and body % are separated and the key is added to the end of the list of known keys -% (hence keys are ordered). The \cs{dt_split_header:Nn} function will have +% (hence keys are ordered). The \cs{@@_split_header:Nn} function will have % removed the \cs{q_nil} from the header, and so it is put back in here. % \begin{macrocode} -\cs_new_protected_nopar:Npn \dt_add_key:Nn { \dt_add_key_aux:NNn \tl_set:Nx } -\cs_new_protected_nopar:Npn \dt_gadd_key:Nn { \dt_add_key_aux:NNn \tl_gset:Nx } -\cs_new_protected:Npn \dt_add_key_aux:NNn #1#2#3 +\cs_new_protected_nopar:Npn \dt_add_key:Nn { \@@_add_key:NNn \tl_set:Nx } +\cs_new_protected_nopar:Npn \dt_gadd_key:Nn { \@@_add_key:NNn \tl_gset:Nx } +\cs_new_protected:Npn \@@_add_key:NNn #1#2#3 { - \dt_split_key_list:NnTF #2 {#3} + \@@_split_key_list:NnTF #2 {#3} { \use_none:nn } { - \dt_split_header:NT #2 - { \dt_add_key_aux:NNnnn #1 #2 {#3} } + \@@_split_header:NT #2 + { \@@_add_key:NNnnn #1 #2 {#3} } } } -\cs_new_protected:Npn \dt_add_key_aux:NNnnn #1#2#3#4#5 +\cs_new_protected:Npn \@@_add_key:NNnnn #1#2#3#4#5 { #1 #2 { \exp_not:n {#4} \tl_to_str:n {#3} - \exp_not:n { \q_dt \q_nil #5 } + \exp_not:n { \q_@@ \q_nil #5 } } } % \end{macrocode} @@ -730,28 +651,28 @@ % \end{macro} % % \begin{macro}{\dt_add_row:N, \dt_gadd_row:N} -% \begin{macro}[aux]{\dt_add_row_aux:NN} -% \begin{macro}[aux]{\dt_add_row_aux:NnN} -% \begin{macro}[aux,EXP]{\dt_add_row_aux:nw} +% \begin{macro}[aux]{\@@_add_row:NN} +% \begin{macro}[aux]{\@@_add_row:NnN} +% \begin{macro}[aux,EXP]{\@@_add_row:nw} % Adding a row means incrementing the total number and adding the structure % of an empty row. As finding the rows will get slow for large tables, this % is only done once. % \begin{macrocode} -\cs_new_protected_nopar:Npn \dt_add_row:N { \dt_add_row_aux:NN \tl_set:Nx } -\cs_new_protected_nopar:Npn \dt_gadd_row:N { \dt_add_row_aux:NN \tl_gset:Nx } -\cs_new_protected:Npn \dt_add_row_aux:NN #1#2 - { \exp_args:NNf \dt_add_row_aux:NnN #1 { \dt_rows:N #2 } #2 } -\cs_new_protected:Npn \dt_add_row_aux:NnN #1#2#3 +\cs_new_protected_nopar:Npn \dt_add_row:N { \@@_add_row:NN \tl_set:Nx } +\cs_new_protected_nopar:Npn \dt_gadd_row:N { \@@_add_row:NN \tl_gset:Nx } +\cs_new_protected:Npn \@@_add_row:NN #1#2 + { \exp_args:NNf \@@_add_row:NnN #1 { \dt_rows:N #2 } #2 } +\cs_new_protected:Npn \@@_add_row:NnN #1#2#3 { #1 #3 { { \int_eval:n { #2 + \c_one } } - \exp_after:wN \dt_add_row_aux:nw #3 \q_stop + \exp_after:wN \@@_add_row:nw #3 \q_stop #2 - \exp_not:n { \q_dt \q_nil \q_dt_row } + \exp_not:n { \q_@@ \q_nil \q_@@_row } } } -\cs_new:Npn \dt_add_row_aux:nw #1#2 \q_stop { \exp_not:n {#2} } +\cs_new:Npn \@@_add_row:nw #1#2 \q_stop { \exp_not:n {#2} } % \end{macrocode} % \end{macro} % \end{macro} @@ -770,29 +691,29 @@ % \end{macro} % % \begin{macro}{\dt_put:Nnnn, \dt_gput:Nnnn} -% \begin{macro}[aux]{\dt_put_aux:NNNnnn} -% \begin{macro}[aux]{\dt_put_aux:NNnnnnn} -% \begin{macro}[aux]{\dt_put_update:NNnnnnnnn} -% \begin{macro}[aux]{\dt_put_add_to_row:NNnnnnn} -% \begin{macro}[aux, EXP]{\dt_put_add_to_row_aux:w} +% \begin{macro}[aux]{\@@_put:NNNnnn} +% \begin{macro}[aux]{\@@_put:NNnnnnn} +% \begin{macro}[aux]{\@@_put_update:NNnnnnnnn} +% \begin{macro}[aux]{\@@_put_add_to_row:NNnnnnn} +% \begin{macro}[aux, EXP]{\@@_put_add_to_row_aux:w} % Adding to a row is a slightly complex procedure. The lead-off is the % standard combination across the local and global routes. % \begin{macrocode} \cs_new_protected_nopar:Npn \dt_put:Nnnn - { \dt_put_aux:NNNnnn \dt_add_key:Nn \tl_set:Nx } + { \@@_put:NNNnnn \dt_add_key:Nn \tl_set:Nx } \cs_new_protected_nopar:Npn \dt_gput:Nnnn - { \dt_put_aux:NNNnnn \dt_gadd_key:Nn \tl_gset:Nx } + { \@@_put:NNNnnn \dt_gadd_key:Nn \tl_gset:Nx } % \end{macrocode} % Add the key to the list those known, if necessary, then check that the % row requested makes sense. % \begin{macrocode} -\cs_new_protected:Npn \dt_put_aux:NNNnnn #1#2#3#4#5#6 +\cs_new_protected:Npn \@@_put:NNNnnn #1#2#3#4#5#6 { #1 #3 {#5} - \dt_split_row:NnTF #3 {#4} - { \dt_put_aux:NNnnnnn #2 #3 {#5} {#6} } + \@@_split_row:NnTF #3 {#4} + { \@@_put:NNnnnnn #2 #3 {#5} {#6} } { - \msg_kernel_error:nnxxx { dt } { unknown-row } + \__msg_kernel_error:nnxxx { dt } { unknown-row } { \token_to_str:N #3 } { \int_eval:n {#4} } { \dt_rows:N #3 } } } @@ -811,11 +732,11 @@ % stack if the key is already present. So there is some care needed sending % the parameters forward without running out of \TeX{} arguments. % \begin{macrocode} -\cs_new_protected:Npn \dt_put_aux:NNnnnnn #1#2#3#4#5#6#7 +\cs_new_protected:Npn \@@_put:NNnnnnn #1#2#3#4#5#6#7 { - \dt_split_key:nnTF {#6} {#3} - { \dt_put_update:NNnnnnnnn #1 #2 {#3} {#4} {#5} {#7} } - { \dt_put_add_to_row:NNnnnnn #1 #2 {#3} {#4} {#5} {#6} {#7} } + \@@_split_key:nnTF {#6} {#3} + { \@@_put_update:NNnnnnnnn #1 #2 {#3} {#4} {#5} {#7} } + { \@@_put_add_to_row:NNnnnnn #1 #2 {#3} {#4} {#5} {#6} {#7} } } % \end{macrocode} % The arguments here are @@ -834,32 +755,32 @@ % |#8| is needed. To try to keep things clear, there are a few more % \cs{exp_not:n} here than formally required. % \begin{macrocode} -\cs_new_protected:Npn \dt_put_update:NNnnnnnnn #1#2#3#4#5#6#7#8#9 +\cs_new_protected:Npn \@@_put_update:NNnnnnnnn #1#2#3#4#5#6#7#8#9 { #1 #2 { \exp_not:n { #5 #7 } \tl_to_str:n {#3} - \exp_not:n { \q_dt {#4} \q_dt #9 \q_dt_row #6 } + \exp_not:n { \q_@@ {#4} \q_@@ #9 \q_@@_row #6 } } } % \end{macrocode} % A slightly more complex case when adding an item. The arguments here are -% identical to those for \cs{dt_put_aux:NNnnnnnn}. The row has not been +% identical to those for \cs{@@_put:NNnnnnnn}. The row has not been % split, so the \cs{q_nil} there is removed and re-added to come after the % new content. % \begin{macrocode} -\cs_new_protected:Npn \dt_put_add_to_row:NNnnnnn #1#2#3#4#5#6#7 +\cs_new_protected:Npn \@@_put_add_to_row:NNnnnnn #1#2#3#4#5#6#7 { #1 #2 { \exp_not:n {#5} - \exp_not:o { \dt_put_add_row_aux:w #6 } + \exp_not:o { \@@_put_add_to_row_aux:w #6 } \tl_to_str:n {#3} - \exp_not:n { \q_dt {#4} \q_dt \q_nil \q_dt_row #7 } + \exp_not:n { \q_@@ {#4} \q_@@ \q_nil \q_@@_row #7 } } } -\cs_new:Npn \dt_put_add_row_aux:w #1 \q_nil {#1} +\cs_new:Npn \@@_put_add_to_row_aux:w #1 \q_nil {#1} % \end{macrocode} % \end{macro} % \end{macro} @@ -869,31 +790,29 @@ % \end{macro} % % \begin{macro}[EXP]{\dt_keys:N} -% \begin{macro}[aux, EXP]{\dt_keys_aux:nn} -% \begin{macro}[aux, EXP]{\dt_keys_aux:wN} +% \begin{macro}[aux, EXP]{\@@_keys:nn} +% \begin{macro}[aux, EXP]{\@@_keys:wN} % A quick mapping is needed to count keys. The \cs{use_none:nn} here -% is used to remove the number of rows and initial \cs{q_dt}. This could +% is used to remove the number of rows and initial \cs{q_@@}. This could % also be handled by starting from $-1$ rather than $0$, but this makes % the logic hopefully slightly clearer. % \begin{macrocode} \cs_new:Npn \dt_keys:N #1 - { \dt_split_header:NT #1 { \dt_keys_aux:nn } } -\cs_new:Npn \dt_keys_aux:nn #1#2 + { \@@_split_header:NT #1 { \@@_keys:nn } } +\cs_new:Npn \@@_keys:nn #1#2 { \int_eval:n { 0 - \exp_after:wN \dt_keys_aux:wN \use_none:nn #1 \q_recursion_tail \q_dt - \prg_break_point:n { } + \exp_after:wN \@@_keys:wN \use_none:nn #1 \q_recursion_tail \q_@@ + \__prg_break_point:Nn \dt_map_break: { } } } -\cs_new:Npn \dt_keys_aux:wN #1 \q_dt +\cs_new:Npn \@@_keys:wN #1 \q_@@ { - \if_meaning:w \q_recursion_tail #1 - \exp_after:wN \prg_map_break: - \fi: + \__quark_if_recursion_tail_break:nN {#1} \dt_map_break: +1 - \dt_keys_aux:wN + \@@_keys:wN } % \end{macrocode} % \end{macro} @@ -910,40 +829,40 @@ % % \subsection{Removing data} % -% \begin{macro}{\dt_del:Nn,\dt_gdel:Nn} +% \begin{macro}{\dt_remove:Nn,\dt_gremove:Nn} % Deleting to the current row is simply a special case of deleting to an % arbitrary row. % \begin{macrocode} -\cs_new_protected:Npn \dt_del:Nn #1 { \dt_del:Nnn #1 +\cs_new_protected:Npn \dt_remove:Nn #1 { \dt_remove:Nnn #1 { \dt_rows:N #1 - \c_one } } -\cs_new_protected:Npn \dt_gdel:Nn #1 { \dt_gdel:Nnn #1 +\cs_new_protected:Npn \dt_gremove:Nn #1 { \dt_gremove:Nnn #1 { \dt_rows:N #1 - \c_one } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\dt_del:Nnn, \dt_gdel:Nnn} -% \begin{macro}[aux]{\dt_del_aux:NNnn} -% \begin{macro}[aux]{\dt_del_aux:NNnnnn} -% \begin{macro}[aux]{\dt_del_aux:NNnnnnn} +% \begin{macro}{\dt_remove:Nnn, \dt_gremove:Nnn} +% \begin{macro}[aux]{\dt_remove_aux:NNnn} +% \begin{macro}[aux]{\dt_remove_aux:NNnnnn} +% \begin{macro}[aux]{\dt_remove_aux:NNnnnnn} % Deleting a single entry from a single row means first splitting by row, % then splitting by key, and finally doing the assignment. If the row or the % key are not present then the entire function does nothing at all. % \begin{macrocode} -\cs_new_protected_nopar:Npn \dt_del:Nnn { \dt_del_aux:NNnn \tl_set:Nn } -\cs_new_protected_nopar:Npn \dt_gdel:Nnn { \dt_del_aux:NNnn \tl_gset:Nn } -\cs_new_protected:Npn \dt_del_aux:NNnn #1#2#3#4 +\cs_new_protected_nopar:Npn \dt_remove:Nnn { \dt_remove_aux:NNnn \tl_set:Nn } +\cs_new_protected_nopar:Npn \dt_gremove:Nnn { \dt_remove_aux:NNnn \tl_gset:Nn } +\cs_new_protected:Npn \dt_remove_aux:NNnn #1#2#3#4 { - \dt_split_row:NnTF #2 {#3} - { \dt_del_aux:NNnnnn #1 #2 {#4} } + \@@_split_row:NnTF #2 {#3} + { \dt_remove_aux:NNnnnn #1 #2 {#4} } { } } -\cs_new_protected:Npn \dt_del_aux:NNnnnn #1#2#3#4#5#6 +\cs_new_protected:Npn \dt_remove_aux:NNnnnn #1#2#3#4#5#6 { - \dt_split_key:nnTF {#5} {#3} - { \dt_del_aux:NNnnnnn #1 #2 {#4} {#6} } + \@@_split_key:nnTF {#5} {#3} + { \dt_remove_aux:NNnnnnn #1 #2 {#4} {#6} } { } } -\cs_new_protected:Npn \dt_del_aux:NNnnnnn #1#2#3#4#5#6#7 +\cs_new_protected:Npn \dt_remove_aux:NNnnnnn #1#2#3#4#5#6#7 { #1 #2 { #3 #5 #7 #4 } } % \end{macrocode} % \end{macro} @@ -968,25 +887,23 @@ { \dt_remove_key_aux:NNn \tl_gset:Nx } \cs_new_protected:Npn \dt_remove_key_aux:NNn #1#2#3 { - \dt_split_key_list:NnTF #2 {#3} + \@@_split_key_list:NnTF #2 {#3} { \exp_args:No \dt_remove_key_aux:nNNnn { \tl_to_str:n {#3} } #1 #2 } { } } \cs_new_protected:Npn \dt_remove_key_aux:nNNnn #1#2#3#4#5 { - \cs_set:Npn \dt_remove_key_aux:w ##1 \q_dt #1 \q_dt ##2 ##3 + \cs_set:Npn \dt_remove_key_aux:w ##1 \q_@@ #1 \q_@@ ##2 ##3 { \exp_not:n {##1} - \if_meaning:w \q_recursion_tail ##3 - \exp_after:wN \prg_map_break: - \fi: + \__quark_if_recursion_tail_break:nN {##3} \dt_map_break: \dt_remove_key_aux:w ##3 } #2 #3 { \exp_not:n {#4} - \dt_remove_key_aux:w #5 \q_dt #1 \q_dt { } \q_recursion_tail - \prg_break_point:n { } + \dt_remove_key_aux:w #5 \q_@@ #1 \q_@@ { } \q_recursion_tail + \__prg_break_point:Nn \dt_map_break: { } } } \cs_new:Npn \dt_remove_key_aux:w { } @@ -1011,7 +928,7 @@ { \dt_remove_row_aux:NNn \tl_gset:Nx } \cs_new_protected:Npn \dt_remove_row_aux:NNn #1#2#3 { - \dt_split_row:NnTF #2 {#3} + \@@_split_row:NnTF #2 {#3} { \dt_remove_row_aux:NNnnn #1 #2 } { } } @@ -1028,18 +945,16 @@ { { \int_eval:n { \dt_rows:N #2 - \c_one } } \dt_remove_row_aux:nw #3 \q_stop - \dt_remove_row_loop:nw #5 \q_recursion_tail \q_dt_row - \prg_break_point:n { } + \dt_remove_row_loop:nw #5 \q_recursion_tail \q_@@_row + \__prg_break_point:Nn \dt_map_break: { } } } -\cs_new_eq:NN \dt_remove_row_aux:nw \dt_add_row_aux:nw -\cs_new:Npn \dt_remove_row_loop:nw #1#2 \q_dt_row +\cs_new_eq:NN \dt_remove_row_aux:nw \@@_add_row:nw +\cs_new:Npn \dt_remove_row_loop:nw #1#2 \q_@@_row { - \if_meaning:w \q_recursion_tail #1 - \exp_after:wN \prg_map_break: - \fi: + \__quark_if_recursion_tail_break:nN {#1} \dt_map_break: \int_eval:n { #1 - \c_one } - \exp_not:n { #2 \q_dt_row } + \exp_not:n { #2 \q_@@_row } \dt_remove_row_loop:nw } % \end{macrocode} @@ -1060,13 +975,13 @@ % \begin{macrocode} \cs_new_protected:Npn \dt_get:NnnN #1#2#3#4 { - \dt_split_row:NnTF #1 {#2} + \@@_split_row:NnTF #1 {#2} { \dt_get_aux:nNnnn {#3} #4 } { \tl_set:Nn #4 { \q_no_value } } } \cs_new_protected:Npn \dt_get_aux:nNnnn #1#2#3#4#5 { - \dt_split_key:nnTF {#4} {#1} + \@@_split_key:nnTF {#4} {#1} { \dt_get_aux:Nnnn #2 } { \tl_set:Nn #2 { \q_no_value } } } @@ -1077,23 +992,23 @@ % \end{macro} % % \begin{macro}[TF]{\dt_get:NnnN} -% \begin{macro}[aux]{\dt_get_aux_true:nNnnn} -% \begin{macro}[aux]{\dt_get_aux_true:Nnnn} +% \begin{macro}[aux]{\@@_get_true:nNnnn} +% \begin{macro}[aux]{\@@_get_true:Nnnn} % The same idea as the standard method, but built as a conditional. % \begin{macrocode} \prg_new_protected_conditional:Npnn \dt_get:NnnN #1#2#3#4 { T , F , TF } { - \dt_split_row:NnTF #1 {#2} - { \dt_get_aux_true:nNnnn {#3} #4 } + \@@_split_row:NnTF #1 {#2} + { \@@_get_true:nNnnn {#3} #4 } { \prg_return_false: } } -\cs_new_protected:Npn \dt_get_aux_true:nNnnn #1#2#3#4#5 +\cs_new_protected:Npn \@@_get_true:nNnnn #1#2#3#4#5 { - \dt_split_key:nnTF {#4} {#1} - { \dt_get_aux_true:Nnnn #2 } + \@@_split_key:nnTF {#4} {#1} + { \@@_get_true:Nnnn #2 } { \prg_return_false: } } -\cs_new_protected:Npn \dt_get_aux_true:Nnnn #1#2#3#4 +\cs_new_protected:Npn \@@_get_true:Nnnn #1#2#3#4 { \tl_set:Nn #1 {#3} \prg_return_true: @@ -1130,10 +1045,10 @@ % \end{variable} % % \begin{macro}{\dt_map_variables:Nnn} -% \begin{macro}[aux]{\dt_map_variables_key:nn} -% \begin{macro}[aux]{\dt_map_variables_aux:nnn} -% \begin{macro}[aux]{\dt_map_variables_aux:nNNw} -% \begin{macro}[aux]{\dt_map_variables_aux:nnw} +% \begin{macro}[aux]{\@@_map_variables_key:nn} +% \begin{macro}[aux]{\@@_map_variables:nnn} +% \begin{macro}[aux]{\@@_map_variables:nNNw} +% \begin{macro}[aux]{\@@_map_variables:nnw} % Mapping across a data table is more complex than other cases as there % are two \enquote{dimensions} to worry about: the rows and the keys. % The first stage of the mapping is to convert the key--variable mapping @@ -1145,38 +1060,37 @@ { \int_gincr:N \g_dt_map_level_int \seq_gclear_new:c { g_dt_map_ \int_use:N \g_dt_map_level_int _seq } - \keyval_parse:NNn \use_none:n \dt_map_variables_key:nn {#2} - \dt_split_header:NT #1 { \dt_map_variables_aux:nnn {#3} } + \keyval_parse:NNn \use_none:n \@@_map_variables_key:nn {#2} + \@@_split_header:NT #1 { \@@_map_variables:nnn {#3} } } -\cs_new_protected:Npn \dt_map_variables_key:nn #1#2 +\cs_new_protected:Npn \@@_map_variables_key:nn #1#2 { \seq_gput_right:cn { g_dt_map_ \int_use:N \g_dt_map_level_int _seq } { {#1} #2 } } % \end{macrocode} -% As \cs{dt_split_header:NT} will leave a couple of tokens at the front +% As \cs{@@_split_header:NT} will leave a couple of tokens at the front % of the body part of the split, there is a quick piece of tidying up % to remove them. % \begin{macrocode} -\cs_new_protected:Npn \dt_map_variables_aux:nnn #1#2#3 - { \dt_map_variables_aux:nNNw {#1} #3 \q_stop } -\cs_new_protected:Npn \dt_map_variables_aux:nNNw - #1 \q_dt_header \q_dt_row #2 \q_stop +\cs_new_protected:Npn \@@_map_variables:nnn #1#2#3 + { \@@_map_variables:nNNw {#1} #3 \q_stop } +\cs_new_protected:Npn \@@_map_variables:nNNw + #1 \q_@@_header \q_@@_row #2 \q_stop { \int_zero_new:c { l_dt_map_ \int_use:N \g_dt_map_level_int _row_int } - \dt_map_variables_aux:nnw {#1} #2 { } \q_recursion_tail \q_dt_row - \prg_break_point:n { \int_gdecr:N \g_dt_map_level_int } + \@@_map_variables:nnw {#1} #2 { } \q_recursion_tail \q_@@_row + \__prg_break_point:Nn \dt_map_break: + { \int_gdecr:N \g_dt_map_level_int } } -\cs_new_protected:Npn \dt_map_variables_aux:nnw #1#2#3#4 \q_dt_row +\cs_new_protected:Npn \@@_map_variables:nnw #1#2#3#4 \q_@@_row { - \if_meaning:w \q_recursion_tail #3 - \exp_after:wN \dt_map_break: - \fi: + \__quark_if_recursion_tail_break:nN {#3} \dt_map_break: \seq_map_inline:cn { g_dt_map_ \int_use:N \g_dt_map_level_int _seq } { \dt_get_aux:nNnnn ##1 { } {#3#4} { } } #1 \int_incr:c { l_dt_map_ \int_use:N \g_dt_map_level_int _row_int } - \dt_map_variables_aux:nnw {#1} + \@@_map_variables:nnw {#1} } % \end{macrocode} % \end{macro} @@ -1187,10 +1101,12 @@ % % \begin{macro}[rEXP]{\dt_map_break:} % \begin{macro}[rEXP]{\dt_map_break:n} -% The break statements are simply copies. +% The break statements use the general \cs{__prg_map_break:Nn}. % \begin{macrocode} -\cs_new_eq:NN \dt_map_break: \prg_map_break: -\cs_new_eq:NN \dt_map_break:n \prg_map_break:n +\cs_new_nopar:Npn \dt_map_break: + { \__prg_map_break:Nn \dt_map_break: { } } +\cs_new_nopar:Npn \dt_map_break:n + { \__prg_map_break:Nn \dt_map_break: } % \end{macrocode} % \end{macro} % \end{macro} @@ -1213,33 +1129,33 @@ % \end{macro} % % \begin{macro}[pTF, EXP]{\dt_if_in:Nn} -% \begin{macro}[aux, EXP]{\dt_if_in_aux:nnn} -% \begin{macro}[aux, EXP]{\dt_if_in_aux:nwN} -% \begin{macro}[aux, EXP]{\dt_if_in_aux:n} +% \begin{macro}[aux, EXP]{\@@_if_in:nnn} +% \begin{macro}[aux, EXP]{\@@_if_in:nwN} +% \begin{macro}[aux, EXP]{\@@_if_in:n} % Expandably checking for the presence of a key in the table as a whole % requires a mapping to the header. The idea is the usual recursion set % up with a string-based comparison only after checking for the end of % the loop. % \begin{macrocode} \prg_new_conditional:Npnn \dt_if_in:Nn #1#2 { p , T , F , TF } - { \dt_split_header:NT #1 { \dt_if_in_aux:nnn {#2} } } -\cs_new:Npn \dt_if_in_aux:nnn #1#2#3 + { \@@_split_header:NT #1 { \@@_if_in:nnn {#2} } } +\cs_new:Npn \@@_if_in:nnn #1#2#3 { - \exp_last_unbraced:Nno \dt_if_in_aux:nwN {#1} { \use_none:nn #2 } - \q_recursion_tail \q_dt - \prg_break_point:n { } + \exp_last_unbraced:Nno \@@_if_in:nwN {#1} { \use_none:nn #2 } + \q_recursion_tail \q_@@ + \__prg_break_point: } -\cs_new:Npn \dt_if_in_aux:nwN #1#2 \q_dt +\cs_new:Npn \@@_if_in:nwN #1#2 \q_@@ { \if_meaning:w \q_recursion_tail #2 - \exp_after:wN \prg_map_break:n + \exp_after:wN \__prg_break:n \else: \exp_after:wN \use_none:n \fi: { \prg_return_false: } \str_if_eq:nnTF {#1} {#2} - { \prg_map_break:n { \prg_return_true: } } - { \dt_if_in_aux:nwN {#1} } + { \__prg_break:n { \prg_return_true: } } + { \@@_if_in:nwN {#1} } } % \end{macrocode} % \end{macro} @@ -1248,22 +1164,22 @@ % \end{macro} % % \begin{macro}[pTF, EXP]{\dt_if_in_row:Nnn} -% \begin{macro}[aux, EXP]{\dt_if_in_row_aux:nw} -% \begin{macro}[aux, EXP]{\dt_if_in_row_aux:nn} -% \begin{macro}[aux, EXP]{\dt_if_in_row_aux:nwn} -% \begin{macro}[aux, EXP]{\dt_if_in_row_aux:N} +% \begin{macro}[aux, EXP]{\@@_if_in_row:nw} +% \begin{macro}[aux, EXP]{\@@_if_in_row:nn} +% \begin{macro}[aux, EXP]{\@@_if_in_row:nwn} +% \begin{macro}[aux, EXP]{\@@_if_in_row:N} % Finding a key in a single row in an expandable way requires two mappings. % To start of with, there is a search for the row. This uses for termination -% the fact that each row starts \cs{q_dt_row} and ends \cs{q_nil}, and +% the fact that each row starts \cs{q_@@_row} and ends \cs{q_nil}, and % always contains at least the row number as the first \meta{balanced % text}. That can be replaced by the tail marker to terminate iteration: % all that is then needed is the correct placement of the clean-up code. % \begin{macrocode} \prg_new_conditional:Npnn \dt_if_in_row:Nnn #1#2#3 { p , T , F , TF } { - \exp_last_unbraced:Nno \dt_if_in_row_aux:nw {#2} #1 + \exp_last_unbraced:Nno \@@_if_in_row:nw {#2} #1 \q_recursion_tail \q_nil - \prg_break_point:n { } + \__prg_break_point: { \tl_to_str:n {#3} } } % \end{macrocode} @@ -1271,10 +1187,10 @@ % been found. That means that the row argument does not need to be converted % to a number earlier. % \begin{macrocode} -\cs_new:Npn \dt_if_in_row_aux:nw #1#2 \q_dt_row #3#4 \q_nil +\cs_new:Npn \@@_if_in_row:nw #1#2 \q_@@_row #3#4 \q_nil { \if_meaning:w \q_recursion_tail #3 - \exp_after:wN \prg_map_break:n + \exp_after:wN \__prg_break:n \else: \exp_after:wN \use_none:n \fi: @@ -1283,32 +1199,32 @@ \prg_return_false: } \int_compare:nNnTF {#1} = {#3} - { \prg_map_break:n { \exp_args:Nno \dt_if_in_row_aux:nn {#4} } } - { \dt_if_in_row_aux:nw {#1} } + { \__prg_break:n { \exp_args:Nno \@@_if_in_row:nn {#4} } } + { \@@_if_in_row:nw {#1} } } % \end{macrocode} % The second iteration is along the row. This is basically the same as -% \cs{prop_if_in:NnTF} with the \cs{q_dt} in place of \cs{q_prop}. +% \cs{prop_if_in:NnTF} with the \cs{q_@@} in place of \cs{q_prop}. % \begin{macrocode} -\cs_new:Npn \dt_if_in_row_aux:nn #1#2 +\cs_new:Npn \@@_if_in_row:nn #1#2 { - \dt_if_in_row_aux:nwn {#2} #1 {#2} \q_dt { } \q_recursion_tail - \prg_break_point:n { } + \@@_if_in_row:nwn {#2} #1 {#2} \q_@@ { } \q_recursion_tail + \__prg_break_point: } -\cs_new:Npn \dt_if_in_row_aux:nwn #1 \q_dt #2 \q_dt #3 +\cs_new:Npn \@@_if_in_row:nwn #1 \q_@@ #2 \q_@@ #3 { \str_if_eq:xxTF {#1} {#2} - { \dt_if_in_row_aux:N } - { \dt_if_in_row_aux:nwn {#1} } + { \@@_if_in_row:N } + { \@@_if_in_row:nwn {#1} } } -\cs_new:Npn \dt_if_in_row_aux:N #1 +\cs_new:Npn \@@_if_in_row:N #1 { - \if_meaning:w \q_dt #1 + \if_meaning:w \q_@@ #1 \prg_return_true: \else: \prg_return_false: \fi: - \prg_map_break: + \__prg_break: } % \end{macrocode} % \end{macro} @@ -1334,7 +1250,7 @@ % \subsection{Messages} % % \begin{macrocode} -\msg_kernel_new:nnnn { dt } { unknown-row } +\__msg_kernel_new:nnnn { dt } { unknown-row } { Data~table~#1~does~not~contain~a~row~'#2'. } { Data~table~#1~contains~#3~rows.~These~must~be~accessed~by~number:~row~ |