summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx371
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 }