diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx | 371 |
1 files changed, 340 insertions, 31 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx index cd1e06fd6c2..1463eba5ce8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx @@ -42,7 +42,7 @@ % }^^A % } % -% \date{Released 2018-04-30} +% \date{Released 2018-05-12} % % \maketitle % @@ -101,6 +101,7 @@ % skip, and muskip expressions are not terminated prematurely; % \item \texttt{deprecation} that makes soon-to-be-deprecated commands produce errors; % \item \texttt{log-functions} that logs function definitions; +% \item \texttt{all} that does all of the above. % \end{itemize} % Providing these as switches rather than options allows testing code % even if it relies on other packages: load all other packages, call @@ -281,6 +282,57 @@ % applicable. % \end{function} % +% \section{Additions to \pkg{l3fparray}} +% +% \begin{function}[added = 2018-05-05]{\fparray_new:Nn} +% \begin{syntax} +% \cs{fparray_new:Nn} \meta{fparray~var} \Arg{size} +% \end{syntax} +% Evaluates the integer expression \meta{size} and allocates an +% \meta{floating point array variable} with that number of (zero) +% entries. The variable name should start with |\g_| because +% assignments are always global. +% \end{function} +% +% \begin{function}[EXP, added = 2018-05-05]{\fparray_count:N} +% \begin{syntax} +% \cs{fparray_count:N} \meta{fparray~var} +% \end{syntax} +% Expands to the number of entries in the \meta{floating point array +% variable}. This is performed in constant time. +% \end{function} +% +% \begin{function}[added = 2018-05-05]{\fparray_gset:Nnn} +% \begin{syntax} +% \cs{fparray_gset:Nnn} \meta{fparray~var} \Arg{position} \Arg{value} +% \end{syntax} +% Stores the result of evaluating the floating point expression +% \meta{value} into the \meta{floating point array variable} at the +% (integer expression) \meta{position}. If the \meta{position} is not +% between $1$ and the \cs{fparray_count:N}, an error occurs. +% Assignments are always global. +% \end{function} +% +% \begin{function}[added = 2018-05-05]{\fparray_gzero:N} +% \begin{syntax} +% \cs{fparray_gzero:N} \meta{fparray~var} +% \end{syntax} +% Sets all entries of the \meta{floating point array variable} to +% $+0$. Assignments are always global. +% \end{function} +% +% \begin{function}[EXP, added = 2018-05-05] +% {\fparray_item:Nn, \fparray_item_to_tl:Nn} +% \begin{syntax} +% \cs{fparray_item:Nn} \meta{fparray~var} \Arg{position} +% \end{syntax} +% Applies \cs{fp_use:N} or \cs{fp_to_tl:N} (respectively) to the +% floating point entry stored at the (integer expression) +% \meta{position} in the \meta{floating point array variable}. If the +% \meta{position} is not between $1$ and the \cs{fparray_count:N}, an +% error occurs. +% \end{function} +% % \section{Additions to \pkg{l3file}} % % \begin{function}[added = 2017-07-11]{\file_get_mdfive_hash:nN} @@ -371,6 +423,75 @@ % locally. % \end{function} % +% \section{Additions to \pkg{l3int}} +% +% \begin{function}[EXP, added = 2018-05-05]{\int_rand:n} +% \begin{syntax} +% \cs{int_rand:n} \Arg{intexpr} +% \end{syntax} +% Evaluates the \meta{integer expression} then produces a +% pseudo-random number between $1$ and the \meta{intexpr} (included). +% This is not yet available in \XeTeX{}. +% \end{function} +% +% \section{Additions to \pkg{l3intarray}} +% +% \begin{function}[EXP, added = 2018-05-05]{\intarray_rand_item:N} +% \begin{syntax} +% \cs{intarray_rand_item:N} \meta{intarray~var} +% \end{syntax} +% Selects a pseudo-random item of the \meta{integer array}. If the +% \meta{integer array} is empty, produce an error. This is not yet +% available in \XeTeX{}. +% \end{function} +% +% \begin{function}[added = 2018-05-05]{\intarray_gset_rand:Nnn, \intarray_gset_rand:Nn} +% \begin{syntax} +% \cs{intarray_gset_rand:Nnn} \meta{intarray~var} \Arg{minimum} \Arg{maximum} +% \cs{intarray_gset_rand:Nn} \meta{intarray~var} \Arg{maximum} +% \end{syntax} +% Evaluates the integer expressions \meta{minimum} and \meta{maximum} +% then sets each entry (independently) of the \meta{integer array +% variable} to a pseudo-random number between the two (with bounds +% included). If the absolute value of either bound is bigger than +% $2^{30}-1$, an error occurs. Entries are generated in the same way +% as repeated calls to \cs{int_rand:nn} or \cs{int_rand:n} +% respectively, in particular for the second function the +% \meta{minimum} is $1$. This is not yet available in \XeTeX{}. +% Assignments are always global. +% \end{function} +% +% \subsection{Working with contents of integer arrays} +% +% \begin{function}[added = 2018-05-04, rEXP]{\intarray_const_from_clist:Nn} +% \begin{syntax} +% \cs{intarray_const_from_clist:Nn} \meta{intarray~var} \meta{intexpr clist} +% \end{syntax} +% Creates a new constant \meta{integer array variable} or raises an +% error if the name is already taken. The \meta{integer array +% variable} is set (globally) to contain as its items the results of +% evaluating each \meta{integer expression} in the \meta{comma list}. +% \end{function} +% +% \begin{function}[added = 2018-05-04, rEXP]{\intarray_to_clist:N} +% \begin{syntax} +% \cs{intarray_to_clist:N} \meta{intarray~var} +% \end{syntax} +% Converts the \meta{intarray} to integer denotations separated by +% commas. All tokens have category code other. If the +% \meta{intarray} has no entry the result is empty; otherwise the +% result has one fewer comma than the number of items. +% \end{function} +% +% \begin{function}[added = 2018-05-04]{\intarray_show:N, \intarray_log:N} +% \begin{syntax} +% \cs{intarray_show:N} \meta{intarray~var} +% \cs{intarray_log:N} \meta{intarray~var} +% \end{syntax} +% Displays the items in the \meta{integer array variable} in the +% terminal or writes them in the log file. +% \end{function} +% % \section{Additions to \pkg{l3msg}} % % In very rare cases it may be necessary to produce errors in an @@ -470,6 +591,18 @@ % the result of evaluating the \meta{boolexpr}. % \end{function} % +% \begin{function}[added = 2018-05-10] +% { +% \bool_set_inverse:N , \bool_set_inverse:c , +% \bool_gset_inverse:N, \bool_gset_inverse:c +% } +% \begin{syntax} +% \cs{bool_set_inverse:N} \meta{boolean} +% \end{syntax} +% Toggles the \meta{boolean} from \texttt{true} to \texttt{false} and +% conversely: sets it to the inverse of its current value. +% \end{function} +% % \section{Additions to \pkg{l3prop}} % % \begin{function}[EXP]{\prop_count:N, \prop_count:c} @@ -677,6 +810,26 @@ % \end{texnote} % \end{function} % +% \begin{function}[added = 2018-05-03]{\seq_indexed_map_function:NN} +% \begin{syntax} +% \cs{seq_indexed_map_function:NN} \meta{seq~var} \meta{function} +% \end{syntax} +% Applies \meta{function} to every entry in the \meta{sequence +% variable}. The \meta{function} should have signature |:nn|. It +% receives two arguments for each iteration: the \meta{index} (namely +% |1| for the first entry, then |2| and so on) and the \meta{item}. +% \end{function} +% +% \begin{function}[added = 2018-05-03]{\seq_indexed_map_inline:Nn} +% \begin{syntax} +% \cs{seq_indexed_map_inline:Nn} \meta{seq~var} \Arg{inline function} +% \end{syntax} +% Applies \meta{inline function} to every entry in the \meta{sequence +% variable}. The \meta{inline function} should consist of code which +% receives the \meta{index} (namely |1| for the first entry, then |2| +% and so on) as~|#1| and the \meta{item} as~|#2|. +% \end{function} +% % \section{Additions to \pkg{l3skip}} % % \begin{function}{\skip_split_finite_else_action:nnNN} @@ -695,6 +848,27 @@ % % \section{Additions to \pkg{l3sys}} % +% \begin{variable}[added = 2018-05-02]{\c_sys_engine_version_str} +% The version string of the current engine, in the same form as +% given in the banner issued when running a job. For \pdfTeX{} +% and \LuaTeX{} this is of the form +% \begin{quote} +% \meta{major}.\meta{minor}.\meta{revision} +% \end{quote} +% For \XeTeX{}, the form is +% \begin{quote} +% \meta{major}.\meta{minor} +% \end{quote} +% For \pTeX{} and \upTeX{}, only releases since \TeX{} Live 2018 +% make the data available, and the form is more complex, as it comprises +% the \pTeX{} version, the \upTeX{} version and the e-\pTeX{} version. +% \begin{quote} +% p\meta{major}.\meta{minor}.\meta{revision}-u\meta{major}.\meta{minor}^^A +% -\meta{epTeX} +% \end{quote} +% where the |u| part is only present for \upTeX{}. +% \end{variable} +% % \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_rand_exist:} % \begin{syntax} % \cs{sys_if_rand_exist_p:} @@ -1297,8 +1471,8 @@ % \begin{macrocode} \cs_new_protected:Npx \mode_leave_vertical: { - \cs_if_exist:NTF \pdftex_quitvmode:D - { \pdftex_quitvmode:D } + \cs_if_exist:NTF \tex_quitvmode:D + { \tex_quitvmode:D } { \exp_not:n { @@ -1963,7 +2137,7 @@ % using \cs{file_get_full_name:nN} and so are non-expandable \texttt{get} % functions. Much of the code is repetitive but we need to branch for % \LuaTeX{} (emulation in Lua), for the slightly different syntax -% needed for \tn{pdftex_mdfivesum:D} and for the fact that primitive +% needed for \tn{tex_mdfivesum:D} and for the fact that primitive % coverage varies in other engines. % \begin{macrocode} \cs_new_protected:Npn \file_get_mdfive_hash:nN #1#2 @@ -1977,7 +2151,7 @@ \file_get_full_name:nN {#1} \l_@@_full_name_str \str_set:Nx #3 { - \use:c { pdftex_file #2 :D } \exp_after:wN + \use:c { tex_file #2 :D } \exp_after:wN { \l_@@_full_name_str } } } @@ -2002,7 +2176,7 @@ \file_get_full_name:nN {#1} \l_@@_full_name_str \tl_set:Nx #2 { - \pdftex_mdfivesum:D file \exp_after:wN + \tex_mdfivesum:D file \exp_after:wN { \l_@@_full_name_str } } } @@ -2197,6 +2371,19 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[added = 2018-05-10] +% {\bool_set_inverse:N, \bool_set_inverse:c, \bool_gset_inverse:N, \bool_gset_inverse:c} +% Set to \texttt{false} or \texttt{true} locally or globally. +% \begin{macrocode} +\cs_new_protected:Npn \bool_set_inverse:N #1 + { \bool_if:NTF #1 { \bool_set_false:N } { \bool_set_true:N } #1 } +\cs_generate_variant:Nn \bool_set_inverse:N { c } +\cs_new_protected:Npn \bool_gset_inverse:N #1 + { \bool_if:NTF #1 { \bool_gset_false:N } { \bool_gset_true:N } #1 } +\cs_generate_variant:Nn \bool_gset_inverse:N { c } +% \end{macrocode} +% \end{macro} +% % \subsection{Additions to \pkg{l3prop}} % % \begin{macrocode} @@ -2433,14 +2620,14 @@ % \begin{macro}{\seq_shuffle:N, \seq_gshuffle:N, \@@_shuffle:NN, \@@_shuffle_item:n} % \begin{variable}{\g_@@_internal_seq, \l_@@_internal_a_int, \l_@@_internal_b_int} % We apply the Fisher–Yates shuffle, storing items in \tn{toks} -% registers. We use the primitive \cs{pdftex_uniformdeviate:D} for +% registers. We use the primitive \cs{tex_uniformdeviate:D} for % speed reasons. Its non-uniformity is of order its argument divided % by $2^{28}$, not too bad for small lists. For sequences with more % than $13$ elements there are more possible permutations than % possible seeds ($13!>2^{28}$) so the question of uniformity is % somewhat moot. % \begin{macrocode} -\cs_if_exist:NTF \pdftex_uniformdeviate:D +\cs_if_exist:NTF \tex_uniformdeviate:D { \int_new:N \l_@@_internal_a_int \int_new:N \l_@@_internal_b_int @@ -2471,7 +2658,7 @@ { \int_incr:N \l_@@_internal_a_int \int_set:Nn \l_@@_internal_b_int - { 1 + \pdftex_uniformdeviate:D \l_@@_internal_a_int } + { 1 + \tex_uniformdeviate:D \l_@@_internal_a_int } \tex_toks:D \l_@@_internal_a_int = \tex_toks:D \l_@@_internal_b_int \tex_toks:D \l_@@_internal_b_int @@ -2487,13 +2674,60 @@ } { \cs_new_protected:Npn \seq_shuffle:N #1 - { \__kernel_msg_error:nn { kernel } { fp-no-random } } + { + \__kernel_msg_error:nnn { kernel } { fp-no-random } + { \seq_shuffle:N #1 } + } \cs_new_eq:NN \seq_gshuffle:N \seq_shuffle:N } % \end{macrocode} % \end{variable} % \end{macro} % +% \begin{macro} +% { +% \seq_indexed_map_function:NN, \seq_indexed_map_inline:Nn, +% \@@_indexed_map:nNN, \@@_indexed_map:Nw +% } +% Similar to \cs{seq_map_function:NN} but we keep track of the item +% index as a |;|-delimited argument of \cs{@@_indexed_map:Nw}. +% \begin{macrocode} +\cs_new:Npn \seq_indexed_map_function:NN #1#2 + { + \@@_indexed_map:NN #1#2 + \prg_break_point:Nn \seq_map_break: { } + } +\cs_new_protected:Npn \seq_indexed_map_inline:Nn #1#2 + { + \int_gincr:N \g__kernel_prg_map_int + \cs_gset_protected:cpn + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1##2 {#2} + \exp_args:NNc \@@_indexed_map:NN #1 + { @@_map_ \int_use:N \g__kernel_prg_map_int :w } + \prg_break_point:Nn \seq_map_break: + { \int_gdecr:N \g__kernel_prg_map_int } + } +\cs_new:Npn \@@_indexed_map:NN #1#2 + { + \exp_after:wN \@@_indexed_map:Nw + \exp_after:wN #2 + \int_value:w 1 + \exp_after:wN \use_i:nn + \exp_after:wN ; + #1 + \prg_break: \@@_item:n { } \prg_break_point: + } +\cs_new:Npn \@@_indexed_map:Nw #1#2 ; #3 \@@_item:n #4 + { + #3 + #1 {#2} {#4} + \exp_after:wN \@@_indexed_map:Nw + \exp_after:wN #1 + \int_value:w \int_eval:w 1 + #2 ; + } +% \end{macrocode} +% \end{macro} +% % \subsection{Additions to \pkg{l3skip}} % % \begin{macrocode} @@ -2512,8 +2746,8 @@ { \skip_if_finite:nTF {#1} { - #3 = \etex_gluestretch:D #1 \scan_stop: - #4 = \etex_glueshrink:D #1 \scan_stop: + #3 = \tex_gluestretch:D #1 \scan_stop: + #4 = \tex_glueshrink:D #1 \scan_stop: } { #3 = \c_zero_skip @@ -2530,28 +2764,99 @@ %<@@=sys> % \end{macrocode} % -% \begin{macro}[EXP, pTF]{\sys_if_rand_exist:} -% Currently, randomness exists under \pdfTeX{}, \LuaTeX{}, \pTeX{} and \upTeX{}. +% \begin{variable}{\c_sys_engine_version_str} +% Various different engines, various different ways to extract the +% data! % \begin{macrocode} -\@@_const:nn { sys_if_rand_exist } - { \cs_if_exist_p:N \pdftex_uniformdeviate:D } +\str_const:Nx \c_sys_engine_version_str + { + \str_case:on \c_sys_engine_str + { + { pdftex } + { + \fp_eval:n { round(\int_use:N \tex_pdftexversion:D / 100 , 2) } + . + \tex_pdftexrevision:D + } + { ptex } + { + \cs_if_exist:NT \tex_ptexversion:D + { + p + \int_use:N \tex_ptexversion:D + \int_use:N \tex_ptexminorversion:D + \tex_ptexrevision:D + - + \int_use:N \tex_epTeXversion:D + } + } + { luatex } + { + \fp_eval:n { round(\int_use:N \tex_luatexversion:D / 100, 2) } + . + \tex_luatexrevision:D + } + { uptex } + { + \cs_if_exist:NT \tex_ptexversion:D + { + p + \int_use:N \tex_ptexversion:D + \int_use:N \tex_ptexminorversion:D + \tex_ptexrevision:D + - + u + \int_use:N \tex_uptexversion:D + \tex_uptexrevision:D + - + \int_use:N \tex_epTeXversion:D + } + } + { xetex } + { + \int_use:N \tex_XeTeXversion:D + . + \tex_XeTeXrevision:D + } + } + } % \end{macrocode} -% \end{macro} +% \end{variable} % % \begin{macro}[EXP]{\sys_rand_seed:} -% Unpack the primitive. +% Unpack the primitive. When random numbers are not available, we +% return zero after an error (and incidentally make sure the number of +% expansions needed is the same as with random numbers available). % \begin{macrocode} -\cs_new:Npn \sys_rand_seed: { \tex_the:D \pdftex_randomseed:D } -\cs_if_exist:NF \pdftex_randomseed:D - { \cs_set:Npn \sys_rand_seed: { 0 } } +\sys_if_rand_exist:TF + { \cs_new:Npn \sys_rand_seed: { \tex_the:D \tex_randomseed:D } } + { + \cs_new:Npn \sys_rand_seed: + { + \int_value:w + \__kernel_msg_expandable_error:nnn { kernel } { fp-no-random } + { \sys_rand_seed: } + \c_zero_int + } + } % \end{macrocode} % \end{macro} % % \begin{macro}{\sys_gset_rand_seed:n} % The primitive always assigns the seed globally. % \begin{macrocode} -\cs_new_protected:Npn \sys_gset_rand_seed:n #1 - { \pdftex_setrandomseed:D \int_eval:n {#1} \exp_stop_f: } +\sys_if_rand_exist:TF + { + \cs_new_protected:Npn \sys_gset_rand_seed:n #1 + { \tex_setrandomseed:D \int_eval:n {#1} \exp_stop_f: } + } + { + \cs_new_protected:Npn \sys_gset_rand_seed:n #1 + { + \__kernel_msg_error:nnn { kernel } { fp-no-random } + { \sys_gset_rand_seed:n {#1} } + } + } % \end{macrocode} % \end{macro} % @@ -2562,11 +2867,11 @@ { \sys_if_engine_luatex:TF { - \luatex_directlua:D + \tex_directlua:D { tex.sprint(status.shell_escape~or~os.execute()) } } { - \pdftex_shellescape:D + \tex_shellescape:D } } % \end{macrocode} @@ -2652,12 +2957,16 @@ \prg_new_conditional:Npnn \tl_if_single_token:n #1 { p , T , F , TF } { \tl_if_head_is_N_type:nTF {#1} - { \@@_if_empty_return:o { \use_none:n #1 } } + { \@@_if_empty_if:o { \use_none:n #1 } } { \tl_if_empty:nTF {#1} - { \prg_return_false: } - { \@@_if_empty_return:o { \exp:w \exp_end_continue_f:w #1 } } + { \if_false: } + { \@@_if_empty_if:o { \exp:w \exp_end_continue_f:w #1 } } } + \prg_return_true: + \else: + \prg_return_false: + \fi: } % \end{macrocode} % \end{macro} @@ -2708,7 +3017,7 @@ % The token count is computed through an \cs{int_eval:n} construction. % Each \texttt{1+} is output to the \emph{left}, into the integer % expression, and the sum is ended by the \cs{exp_end:} inserted by -% \cs{@@_act_end:wn} (which is technically implemented as \cs{c_zero}). +% \cs{@@_act_end:wn} (which is technically implemented as \cs{c_zero_int}). % Somewhat a hack! % \begin{macrocode} \cs_new:Npn \tl_count_tokens:n #1 @@ -2757,7 +3066,7 @@ { \__kernel_file_missing:n {#4} } { \group_begin: - \exp_args:No \etex_everyeof:D + \exp_args:No \tex_everyeof:D { \c_@@_rescan_marker_tl \exp_not:N } #3 \scan_stop: \exp_after:wN \@@_from_file_do:w @@ -2801,7 +3110,7 @@ { \__kernel_file_missing:n {#4} } { \group_begin: - \etex_everyeof:D { \exp_not:N } + \tex_everyeof:D { \exp_not:N } #3 \scan_stop: \tl_set:Nx \l_@@_internal_a_tl { \tex_input:D \l_@@_file_name_str \c_space_token } |