summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2019-03-05 22:35:14 +0000
committerKarl Berry <karl@freefriends.org>2019-03-05 22:35:14 +0000
commit68872ff6a2a91fa0e84763fc9316493d82075c95 (patch)
tree0546ec4c414553802e31a423aec44f74d252f645 /Master/texmf-dist/source/latex/l3kernel
parent541c4ddf7c5b402b9cfe8af5ef4e49ffa15d3e83 (diff)
l3 (5mar19)
git-svn-id: svn://tug.org/texlive/trunk@50246 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/expl3.dtx32
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3basics.dtx219
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx99
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3box.dtx45
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx910
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3clist.dtx26
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx592
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx952
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3doc.dtx103
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx12
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3expan.dtx138
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3file.dtx252
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3final.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3flag.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx41
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx21
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx123
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp.dtx15
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3int.dtx142
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx10
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3keys.dtx46
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx18
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3msg.dtx114
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3names.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3prg.dtx43
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3prop.dtx31
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3quark.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3regex.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3seq.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3skip.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3sort.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3str.dtx39
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3sys.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx19
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3tl.dtx69
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3token.dtx115
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx2
51 files changed, 2451 insertions, 1825 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
index 3d261943684..f99bca058f2 100644
--- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
@@ -23,7 +23,7 @@
% for those people who are interested.
%
%<*driver|generic|package>
-\def\ExplFileDate{2019-02-15}%
+\def\ExplFileDate{2019-03-05}%
%</driver|generic|package>
%<*driver>
\documentclass[full]{l3doc}
@@ -51,7 +51,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -917,6 +917,12 @@
% the option name alone is equivalent to using the option with the
% \texttt{true} value.
%
+% \DescribeOption{undo-recent-deprecations}
+% The \texttt{undo-recent-deprecations} option suppresses deprecation
+% errors for the first six months after a command is deprecated. It is
+% intended as a last resort measure for users of packages that were not
+% updated in time.
+%
% \DescribeOption{check-declarations}
% All variables used in \LaTeX3 code should be declared. This is enforced
% by \TeX{} for variable types based on \TeX{} registers, but not for those
@@ -1190,6 +1196,7 @@
% \begin{macro}[int]{\expl@create@bool@option}
% \begin{variable}[int]
% {
+% \l@expl@undo@recent@deprecations@bool ,
% \l@expl@check@declarations@bool ,
% \l@expl@log@functions@bool ,
% \l@expl@enable@debug@bool
@@ -1213,6 +1220,8 @@
\newcommand*#2{}%
\chardef #2=0 %
}%
+\expl@create@bool@option
+ {undo-recent-deprecations}\l@expl@undo@recent@deprecations@bool
\expl@create@bool@option{check-declarations}\l@expl@check@declarations@bool
\expl@create@bool@option{log-functions}\l@expl@log@functions@bool
\expl@create@bool@option{enable-debug}\l@expl@enable@debug@bool
@@ -1242,10 +1251,6 @@
% \end{variable}
% \end{macro}
%
-% \begin{macro}{\GetIdInfo}
-% This is implemented right at the start of \texttt{l3bootstrap.dtx}.
-% \end{macro}
-%
% \begin{macro}{\ProvidesExplPackage, \ProvidesExplClass, \ProvidesExplFile}
% For other packages and classes building on this one it is convenient
% not to need \cs{ExplSyntaxOn} each time.
@@ -1282,18 +1287,6 @@
\fi
% \end{macrocode}
%
-% \begin{macro}{\color}
-% The \cs{color} macro must be defined for showing coffin poles, so
-% a no-op version is provided here.
-% \begin{macrocode}
-\AtBeginDocument
- {
- \cs_if_exist:NF \color
- { \DeclareRobustCommand \color [2] [ ] { } }
- }
-% \end{macrocode}
-% \end{macro}
-%
% \begin{variable}{\l__expl_driver_tl}
% \begin{variable}{\l__expl_native_drivers_bool}
% With the code now loaded, options can be handled using a real key--value
@@ -1434,6 +1427,7 @@
% \begin{macrocode}
\keys_define:nn { expl }
{
+ undo-recent-deprecations .bool_set:N = \l@expl@undo@recent@deprecations@bool,
check-declarations .bool_set:N = \l@expl@check@declarations@bool,
log-functions .bool_set:N = \l@expl@log@functions@bool
}
@@ -1667,6 +1661,7 @@
%
% \begin{variable}[int]
% {
+% \l@expl@undo@recent@deprecations@bool ,
% \l@expl@check@declarations@bool ,
% \l@expl@log@functions@bool ,
% \l@expl@enable@debug@bool
@@ -1675,6 +1670,7 @@
% the two variables are defined to do nothing.
% Appropriate value before input of the loader.
% \begin{macrocode}
+\chardef \l@expl@undo@recent@deprecations@bool = 0 %
\chardef \l@expl@check@declarations@bool = 0 %
\chardef \l@expl@log@functions@bool = 0 %
\chardef \l@expl@enable@debug@bool = 0 %
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
index c7464dce77b..16e6a459943 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
index 7730ede1e34..06bb1880b17 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -163,7 +163,7 @@
% Create a new function with the \texttt{protected} restriction,
% such as \cs{cs_set_protected:Npn}. The parameter may contain
% \cs{par} tokens but the function will not expand within an
-% \texttt{x}-type expansion.
+% \texttt{x}-type or \texttt{e}-type expansion.
% \end{description}
%
% Finally, the functions in
@@ -244,7 +244,7 @@
% \emph{etc.}) will be replaced by those absorbed by the function.
% When the \meta{function} is used the \meta{parameters} absorbed
% cannot contain \cs{par} tokens. The \meta{function} will not
-% expand within an \texttt{x}-type argument. The definition is global
+% expand within an \texttt{x}-type or \texttt{e}-type argument. The definition is global
% and an error results if the \meta{function} is already defined.
% \end{function}
%
@@ -289,7 +289,7 @@
% \emph{etc.}) will be replaced by those absorbed by the function.
% The assignment of a meaning to the \meta{function} is restricted to
% the current \TeX{} group level. The \meta{function} will
-% not expand within an \texttt{x}-type argument.
+% not expand within an \texttt{x}-type or \texttt{e}-type argument.
% \end{function}
%
% \begin{function}
@@ -307,7 +307,7 @@
% cannot contain \cs{par} tokens. The assignment of a meaning
% to the \meta{function} is restricted to the current \TeX{} group
% level. The \meta{function} will not expand within an
-% \texttt{x}-type argument.
+% \texttt{x}-type or \texttt{e}-type argument.
% \end{function}
%
% \begin{function}{\cs_gset:Npn, \cs_gset:cpn, \cs_gset:Npx, \cs_gset:cpx}
@@ -353,7 +353,7 @@
% The assignment of a meaning to the \meta{function} is \emph{not}
% restricted to the current \TeX{} group level: the assignment is
% global. The \meta{function} will not expand within an
-% \texttt{x}-type argument.
+% \texttt{x}-type or \texttt{e}-type argument.
% \end{function}
%
% \begin{function}
@@ -441,7 +441,7 @@
% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
% function. When the \meta{function} is used the \meta{parameters}
% absorbed cannot contain \cs{par} tokens. The \meta{function} will not
-% expand within an \texttt{x}-type argument. The definition is global and
+% expand within an \texttt{x}-type or \texttt{e}-type argument. The definition is global and
% an error results if the \meta{function} is already defined.
% \end{function}
%
@@ -512,7 +512,7 @@
% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
% function. When the \meta{function} is used the \meta{parameters}
% absorbed cannot contain \cs{par} tokens. The \meta{function} will not
-% expand within an \texttt{x}-type argument.
+% expand within an \texttt{x}-type or \texttt{e}-type argument.
% The assignment of a meaning to the \meta{function} is restricted to
% the current \TeX{} group level.
% \end{function}
@@ -581,7 +581,7 @@
% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
% function. When the \meta{function} is used the \meta{parameters}
% absorbed cannot contain \cs{par} tokens. The \meta{function} will not
-% expand within an \texttt{x}-type argument.
+% expand within an \texttt{x}-type or \texttt{e}-type argument.
% The assignment of a meaning to the \meta{function} is global.
% \end{function}
%
@@ -794,7 +794,7 @@
% of category code $10$. The result does \emph{not} include
% the current escape token, contrarily to \cs{token_to_str:N}.
% Full expansion of this function requires exactly $2$ expansion
-% steps, and so an \texttt{x}-type expansion, or two
+% steps, and so an \texttt{x}-type or \texttt{e}-type expansion, or two
% \texttt{o}-type expansions are required to
% convert the \meta{control sequence} to a sequence of characters
% in the input stream. In most cases, an \texttt{f}-expansion
@@ -802,7 +802,7 @@
% of the result.
% \end{function}
%
-% \section{Analysing control sequence names}
+% \section{Analysing control sequences}
%
% \begin{function}[EXP, added = 2018-04-06]{\cs_split_function:N}
% \begin{syntax}
@@ -819,6 +819,70 @@
% (other).
% \end{function}
%
+% The next three functions decompose \TeX{} macros into their
+% constituent parts: if the \meta{token} passed is not a macro then no
+% decomposition can occur. In the latter case, all three functions leave
+% \cs{scan_stop:} in the input stream.
+%
+% \begin{function}[EXP, added = 2019-02-27]{\cs_prefix_spec:N}
+% \begin{syntax}
+% \cs{cs_prefix_spec:N} \meta{token}
+% \end{syntax}
+% If the \meta{token} is a macro, this function leaves the applicable
+% \TeX{} prefixes in input stream as a string of tokens of category
+% code $12$ (with spaces having category code $10$). Thus for example
+% \begin{verbatim}
+% \cs_set:Npn \next:nn #1#2 { x #1~y #2 }
+% \cs_prefix_spec:N \next:nn
+% \end{verbatim}
+% leaves |\long| in the input stream. If the \meta{token} is
+% not a macro then \cs{scan_stop:} is left in the input stream.
+% \begin{texnote}
+% The prefix can be empty, |\long|, |\protected| or
+% |\protected\long| with backslash replaced by the current escape
+% character.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2019-02-27]{\cs_argument_spec:N}
+% \begin{syntax}
+% \cs{cs_argument_spec:N} \meta{token}
+% \end{syntax}
+% If the \meta{token} is a macro, this function leaves the primitive
+% \TeX{} argument specification in input stream as a string of
+% character tokens of category code $12$ (with spaces having category
+% code $10$). Thus for example
+% \begin{verbatim}
+% \cs_set:Npn \next:nn #1#2 { x #1 y #2 }
+% \cs_argument_spec:N \next:nn
+% \end{verbatim}
+% leaves |#1#2| in the input stream. If the \meta{token} is
+% not a macro then \cs{scan_stop:} is left in the input stream.
+% \begin{texnote}
+% If the argument specification contains the string |->|, then the
+% function produces incorrect results.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2019-02-27]{\cs_replacement_spec:N}
+% \begin{syntax}
+% \cs{cs_replacement_spec:N} \meta{token}
+% \end{syntax}
+% If the \meta{token} is a macro, this function leaves the replacement
+% text in input stream as a string of character tokens of category
+% code $12$ (with spaces having category code $10$). Thus for example
+% \begin{verbatim}
+% \cs_set:Npn \next:nn #1#2 { x #1~y #2 }
+% \cs_replacement_spec:N \next:nn
+% \end{verbatim}
+% leaves \verb*|x#1 y#2| in the input stream. If the \meta{token} is
+% not a macro then \cs{scan_stop:} is left in the input stream.
+% \begin{texnote}
+% If the argument specification contains the string |->|, then the
+% function produces incorrect results.
+% \end{texnote}
+% \end{function}
+%
% \section{Using or removing tokens and arguments}
%
% Tokens in the input can be read and used or read and discarded.
@@ -1931,8 +1995,7 @@
% \begin{variable}{\g_@@_deprecation_on_tl, \g_@@_deprecation_off_tl}
% Some commands were more recently deprecated and not yet removed;
% only make these into errors if the user requests it. This relies on
-% two token lists, mostly filled up by calls to
-% \cs{__kernel_patch_deprecation:nnNNpn} in each module.
+% two token lists, filled up in \pkg{l3deprecation}.
% \begin{macrocode}
\__kernel_if_debug:TF
{
@@ -1956,82 +2019,6 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\__kernel_patch_deprecation:nnNNpn}
-% \begin{macro}{\@@_deprecation_aux:nnNnn}
-% Grab a definition (at present, must be \cs{cs_new_protected:Npn} or \cs{cs_new:Npn}).
-% Add to \cs{g_@@_deprecation_on_tl} some code that makes the
-% defined macro |#3| outer (and defines it as an error). Add to
-% \cs{g_@@_deprecation_off_tl} the definition itself. In both
-% cases we undefine the token with \cs{tex_let:D} to avoid taking a
-% potentially outer macro as the argument of some \pkg{expl3}
-% function. Finally, define the macro itself: if it is protected,
-% make it produce a warning then redefine and call itself. The macro
-% initially takes no parameters:
-% together with the \texttt{x}-expanding assignment and \cs{exp_not:n}
-% this gives a convenient way of storing the macro's definition in
-% itself in order to only produce the warning once for each macro.
-% If debugging is disabled, \cs{__kernel_patch_deprecation:nnNNpn} lets the
-% definition happen.
-% \begin{macrocode}
-\__kernel_if_debug:TF
- {
- \cs_set_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2#3#4#5#
- {
- \if_meaning:w \cs_new_protected:Npn #3
- \exp_after:wN \use_i:nn
- \else:
- \if_meaning:w \cs_new:Npn #3
- \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nn
- \else:
- \__kernel_msg_error:nnx { kernel } { debug-unpatchable }
- { \token_to_str:N #3 ~(for~deprecation) }
- \exp_after:wN \exp_after:wN \exp_after:wN \use_none:nn
- \fi:
- \fi:
- { \@@_deprecation_aux:nnNnn {#1} {#2} #4 {#5} }
- { \@@_deprecation_expandable:nnNnn {#1} {#2} #4 {#5} }
- }
- \cs_set_protected:Npn \@@_deprecation_aux:nnNnn #1#2#3#4#5
- {
- \tl_gput_right:Nn \g_@@_deprecation_on_tl
- {
- \tex_let:D #3 \scan_stop:
- \__kernel_deprecation_error:Nnn #3 {#2} {#1}
- }
- \tl_gput_right:Nn \g_@@_deprecation_off_tl
- {
- \tex_let:D #3 \scan_stop:
- \cs_set_protected:Npn #3 #4 {#5}
- }
- \cs_new_protected:Npx #3
- {
- \exp_not:N \__kernel_msg_warning:nnxxx
- { kernel } { deprecated-command }
- {#1} { \token_to_str:N #3 } { \tl_to_str:n {#2} }
- \exp_not:n { \cs_gset_protected:Npn #3 #4 {#5} }
- \exp_not:N #3
- }
- }
- \cs_set_protected:Npn \@@_deprecation_expandable:nnNnn #1#2#3#4#5
- {
- \tl_gput_right:Nn \g_@@_deprecation_on_tl
- {
- \tex_let:D #3 \scan_stop:
- \__kernel_deprecation_error:Nnn #3 {#2} {#1}
- }
- \tl_gput_right:Nn \g_@@_deprecation_off_tl
- {
- \tex_let:D #3 \scan_stop:
- \cs_set:Npn #3 #4 {#5}
- }
- \cs_new:Npn #3 #4 {#5}
- }
- }
- { \cs_set_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2 { } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
% \begin{macro}
% {\__kernel_patch:nnNNpn, \__kernel_patch_conditional:nNNpnn}
% \begin{macro}
@@ -3470,6 +3457,60 @@
% \end{macrocode}
% \end{macro}
%
+% \subsection{Decomposing a macro definition}
+%
+% \begin{macro}{\cs_prefix_spec:N}
+% \begin{macro}{\cs_argument_spec:N}
+% \begin{macro}{\cs_replacement_spec:N}
+% \begin{macro}{\@@_prefix_arg_replacement:wN}
+% We sometimes want to test if a control sequence can be expanded to
+% reveal a hidden value. However, we cannot just expand the macro
+% blindly as it may have arguments and none might be
+% present. Therefore we define these functions to pick either the
+% prefix(es), the argument specification, or the replacement text from
+% a macro. All of this information is returned as characters with
+% catcode~$12$. If the token in question isn't a macro, the token
+% \cs{scan_stop:} is returned instead.
+% \begin{macrocode}
+\use:x
+ {
+ \exp_not:n { \cs_new:Npn \@@_prefix_arg_replacement:wN #1 }
+ \tl_to_str:n { macro : } \exp_not:n { #2 -> #3 \q_stop #4 }
+ }
+ { #4 {#1} {#2} {#3} }
+\cs_new:Npn \cs_prefix_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \@@_prefix_arg_replacement:wN
+ \token_to_meaning:N #1 \q_stop \use_i:nnn
+ }
+ { \scan_stop: }
+ }
+\cs_new:Npn \cs_argument_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \@@_prefix_arg_replacement:wN
+ \token_to_meaning:N #1 \q_stop \use_ii:nnn
+ }
+ { \scan_stop: }
+ }
+\cs_new:Npn \cs_replacement_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \@@_prefix_arg_replacement:wN
+ \token_to_meaning:N #1 \q_stop \use_iii:nnn
+ }
+ { \scan_stop: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Doing nothing functions}
%
% \begin{macro}[EXP]{\prg_do_nothing:}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
index 053c73124ba..9c1fa385fdf 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
@@ -22,103 +22,6 @@
%
% for those people who are interested.
%
-%<*driver|package>
-% \begin{macro}{\GetIdInfo}
-% \begin{macro}{\GetIdInfoAuxI, \GetIdInfoAuxII, \GetIdInfoAuxIII}
-% The idea here is to extract out the information needed from a standard
-% \textsc{svn} \texttt{Id} line, but to avoid a line that would get
-% changed when the file is checked in. Hence the fact that none of the
-% lines here include both a dollar sign and the \texttt{Id} keyword!
-%
-% At this stage, no test has taken place for the \eTeX{} extensions, and
-% so using \tn{protected} could give an error. To avoid that, it is used
-% by csname: if it's not available, the bootstrap code will bail out at
-% the point of testing for the necessary primitives, while if it is available
-% then \cs{GetIdInfo} and so on will be properly protected. All of this is
-% then done in a group to avoid leaving \tn{protected} about as equivalent
-% to \tn{relax} if the extensions are unavailable.
-% \begin{macrocode}
-\begingroup
- \csname protected\endcsname\gdef\GetIdInfo
- {%
- \begingroup
- \catcode 32 = 10 %
- \GetIdInfoAuxI
- }%
-% \end{macrocode}
-% A first check for a completely empty \textsc{svn} field. If that is
-% not the case, there is a second case when a file created using
-% \texttt{svn cp} but has not been checked in. That leaves a special
-% marker \texttt{-1} version, which has no further data. Dealing correctly
-% with that is the reason for the space in the line to use
-% \cs{GetIdInforAuxII}.
-% \begin{macrocode}
- \csname protected\endcsname\gdef\GetIdInfoAuxI$#1$#2%
- {%
- \def\tempa{#1}%
- \def\tempb{Id}%
- \ifx\tempa\tempb
- \def\tempa
- {%
- \endgroup
- \def\ExplFileDate{0000/00/00}%
- \def\ExplFileDescription{#2}%
- \def\ExplFileName{[unknown]}%
- \def\ExplFileExtension{[unknown extension]}%
- \def\ExplFileVersion{-1}%
- }%
- \else
- \def\tempa
- {%
- \endgroup
- \def\ExplFileDescription{#2}%
- \GetIdInfoAuxII$#1 $%
- }%
- \fi
- \tempa
- }%
-% \end{macrocode}
-% Here, |#1| is |Id|, |#2| is the file name, |#3| is the extension,
-% |#4| is the version, |#5| is the check in date and |#6| is the check in
-% time and user, plus some trailing spaces. If |#4| is the marker |-1| value
-% then |#5| and |#6| are empty.
-% \begin{macrocode}
- \csname protected\endcsname\gdef\GetIdInfoAuxII$#1 #2.#3 #4 #5 #6$%
- {%
- \def\ExplFileName{#2}%
- \def\ExplFileExtension{#3}%
- \def\ExplFileVersion{#4}%
- \begingroup
- \def\tempa{#4}%
- \def\tempb{-1}%
- \ifx\tempa\tempb
- \def\tempa
- {%
- \endgroup
- \def\ExplFileDate{0000/00/00}%
- }%
- \else
- \def\tempa
- {%
- \endgroup
- \GetIdInfoAuxIII$#5$%
- }%
- \fi
- \tempa
- }%
-% \end{macrocode}
-% Convert an \textsc{svn}-style date into a \LaTeX{}-style one.
-% \begin{macrocode}
- \csname protected\endcsname\gdef\GetIdInfoAuxIII$#1-#2-#3$%
- {%
- \def\ExplFileDate{#1/#2/#3}%
- }%
-\endgroup
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%</driver|package>
%<*driver>
\documentclass[full,kernel]{l3doc}
\begin{document}
@@ -140,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
index e2a4222c916..594d6cf0388 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -2270,49 +2270,6 @@
% \end{macrocode}
% \end{macro}
%
-% \subsection{Deprecated functions}
-%
-% \begin{macro}
-% {
-% \box_set_eq_clear:NN, \box_set_eq_clear:cN,
-% \box_set_eq_clear:Nc, \box_set_eq_clear:cc
-% }
-% \begin{macro}
-% {
-% \box_gset_eq_clear:NN, \box_gset_eq_clear:cN,
-% \box_gset_eq_clear:Nc, \box_gset_eq_clear:cc
-% }
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \box_set_eq_drop:N }
-\cs_new_protected:Npn \box_set_eq_clear:NN #1#2
- { \tex_setbox:D #1 \tex_box:D #2 }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \box_gset_eq_drop:N }
-\cs_new_protected:Npn \box_gset_eq_clear:NN #1#2
- { \tex_global:D \tex_setbox:D #1 \tex_box:D #2 }
-\cs_generate_variant:Nn \box_set_eq_clear:NN { c , Nc , cc }
-\cs_generate_variant:Nn \box_gset_eq_clear:NN { c , Nc , cc }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\hbox_unpack_clear:N, \hbox_unpack_clear:c}
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \hbox_unpack_drop:N }
-\cs_new_protected:Npn \hbox_unpack_clear:N
- { \hbox_unpack_drop:N }
-\cs_generate_variant:Nn \hbox_unpack_clear:N { c }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\vbox_unpack_clear:N, \vbox_unpack_clear:c}
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \vbox_unpack_drop:N }
-\cs_new_protected:Npn \vbox_unpack_clear:N
- { \vbox_unpack_drop:N }
-\cs_generate_variant:Nn \vbox_unpack_clear:N { c }
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
index e0a2b218088..dae61ed7957 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -203,47 +203,6 @@
% operation is applied.
% \end{function}
%
-% \section{Additions to \pkg{l3coffins}}
-%
-% \begin{function}[updated = 2019-01-23]
-% {
-% \coffin_resize:Nnn, \coffin_resize:cnn,
-% \coffin_gresize:Nnn, \coffin_gresize:cnn
-% }
-% \begin{syntax}
-% \cs{coffin_resize:Nnn} \meta{coffin} \Arg{width} \Arg{total-height}
-% \end{syntax}
-% Resized the \meta{coffin} to \meta{width} and \meta{total-height},
-% both of which should be given as dimension expressions.
-% \end{function}
-%
-% \begin{function}
-% {
-% \coffin_rotate:Nn, \coffin_rotate:cn,
-% \coffin_grotate:Nn, \coffin_grotate:cn
-% }
-% \begin{syntax}
-% \cs{coffin_rotate:Nn} \meta{coffin} \Arg{angle}
-% \end{syntax}
-% Rotates the \meta{coffin} by the given \meta{angle} (given in
-% degrees counter-clockwise). This process rotates both the
-% coffin content and poles. Multiple rotations do not result in
-% the bounding box of the coffin growing unnecessarily.
-% \end{function}
-%
-% \begin{function}[updated = 2019-01-23]
-% {
-% \coffin_scale:Nnn, \coffin_scale:cnn,
-% \coffin_gscale:Nnn, \coffin_gscale:cnn
-% }
-% \begin{syntax}
-% \cs{coffin_scale:Nnn} \meta{coffin} \Arg{x-scale} \Arg{y-scale}
-% \end{syntax}
-% Scales the \meta{coffin} by a factors \meta{x-scale} and
-% \meta{y-scale} in the horizontal and vertical directions,
-% respectively. The two scale factors should be given as real numbers.
-% \end{function}
-%
% \section{Additions to \pkg{l3expan}}
%
% \begin{function}[added = 2018-04-04, updated = 2019-02-08]
@@ -340,9 +299,10 @@
%
% \section{Additions to \pkg{l3file}}
%
-% \begin{function}[added = 2017-07-11]{\file_get_mdfive_hash:nN}
+% \begin{function}[noTF, added = 2017-07-11, updated = 2019-02-16]
+% {\file_get_mdfive_hash:nN}
% \begin{syntax}
-% \cs{file_get_mdfive_hash:nN} \Arg{file name} \meta{str var}
+% \cs{file_get_mdfive_hash:nN} \Arg{file name} \meta{tl var}
% \end{syntax}
% Searches for \meta{file name} using the current \TeX{} search
% path and the additional paths controlled by \cs{file_path_include:n}.
@@ -355,9 +315,10 @@
% Where the file is not found, the \meta{str var} will be empty.
% \end{function}
%
-% \begin{function}[added = 2017-07-09]{\file_get_size:nN}
+% \begin{function}[noTF, added = 2017-07-09, updated = 2019-02-16]
+% {\file_get_size:nN}
% \begin{syntax}
-% \cs{file_get_size:nN} \Arg{file name} \meta{str var}
+% \cs{file_get_size:nN} \Arg{file name} \meta{tl var}
% \end{syntax}
% Searches for \meta{file name} using the current \TeX{} search
% path and the additional paths controlled by \cs{file_path_include:n}.
@@ -366,9 +327,10 @@
% This is not available in older versions of \XeTeX{}.
% \end{function}
%
-% \begin{function}[added = 2017-07-09]{\file_get_timestamp:nN}
+% \begin{function}[noTF, added = 2017-07-09, updated = 2019-02-16]
+% {\file_get_timestamp:nN}
% \begin{syntax}
-% \cs{file_get_timestamp:nN} \Arg{file name} \meta{str var}
+% \cs{file_get_timestamp:nN} \Arg{file name} \meta{tl var}
% \end{syntax}
% Searches for \meta{file name} using the current \TeX{} search
% path and the additional paths controlled by \cs{file_path_include:n}.
@@ -532,14 +494,15 @@
% having a similar interface as non-expandable messages, expandable
% errors must be handled internally very differently from normal error
% messages, as none of the tools to print to the terminal or the log
-% file are expandable. As a result, the message text and arguments are
-% not expanded, and messages must be very short (with default settings,
+% file are expandable. As a result, short-hands such as |\{| or |\\| do
+% not work, and messages must be very short (with default settings,
% they are truncated after approximately 50 characters). It is
% advisable to ensure that the message is understandable even when
-% truncated. Another particularity of expandable messages is that they
+% truncated, by putting the most important information up front.
+% Another particularity of expandable messages is that they
% cannot be redirected or turned off by the user.
%
-% \begin{function}[EXP, added = 2015-08-06]
+% \begin{function}[EXP, added = 2015-08-06, updated = 2019-02-28]
% {
% \msg_expandable_error:nnnnnn ,
% \msg_expandable_error:nnnnn ,
@@ -636,14 +599,6 @@
%
% \section{Additions to \pkg{l3prop}}
%
-% \begin{function}[EXP]{\prop_count:N, \prop_count:c}
-% \begin{syntax}
-% \cs{prop_count:N} \meta{property list}
-% \end{syntax}
-% Leaves the number of key--value pairs in the \meta{property list} in
-% the input stream as an \meta{integer denotation}.
-% \end{function}
-%
% \begin{function}[rEXP]
% {\prop_map_tokens:Nn, \prop_map_tokens:cn}
% \begin{syntax}
@@ -857,24 +812,10 @@
% input stream according to the sign of the result.
% \end{function}
%
-% \begin{function}{\skip_split_finite_else_action:nnNN}
-% \begin{syntax}
-% \cs{skip_split_finite_else_action:nnNN} \Arg{skipexpr} \Arg{action}
-% ~~\meta{dimen_1} \meta{dimen_2}
-% \end{syntax}
-% Checks if the \meta{skipexpr} contains finite glue. If it does then it
-% assigns
-% \meta{dimen_1} the stretch component and \meta{dimen_2} the shrink
-% component. If
-% it contains infinite glue set \meta{dimen_1} and \meta{dimen_2} to $0$\,pt
-% and place |#2| into the input stream: this is usually an error or
-% warning message of some sort.
-% \end{function}
-%
% \section{Additions to \pkg{l3sys}}
%
-% \begin{function}[added = 2019-01-16]{\sys_shell_get:nnN}
-% \begin{function}[TF,added = 2019-01-16]{\sys_shell_get:nnN}
+% \begin{function}[noTF, added = 2019-01-16, updated = 2019-02-16]
+% {\sys_shell_get:nnN}
% \begin{syntax}
% \cs{sys_shell_get:nnN} \Arg{shell~command} \Arg{setup} \meta{tl~var}
% \cs{sys_shell_get:nnNTF} \Arg{shell~command} \Arg{setup} \meta{tl~var} \Arg{true code} \Arg{false code}
@@ -884,13 +825,13 @@
% \cs{tl_to_str:n}. Category codes may need to be set appropriately
% via the \meta{setup} argument, which is run just before running the
% \meta{shell command} (in a group).
-% If shell escape is disabled, the \meta{tl~var} will be empty.
+% If shell escape is disabled, the \meta{tl~var} will be set to
+% \cs{q_no_value} in the non-branching version.
% Note that quote characters (|"|) \emph{cannot} be used inside the
% \meta{shell command}. The \cs{sys_shell_get:nnNTF} conditional
% returns \texttt{true} if the shell is available and no quote is
% detected, and \texttt{false} otherwise.
% \end{function}
-% \end{function}
%
% \begin{variable}[added = 2018-05-02]{\c_sys_engine_version_str}
% The version string of the current engine, in the same form as
@@ -1034,38 +975,6 @@
% Token groups (|{|\ldots|}|) are not single tokens.
% \end{function}
%
-% \begin{function}[EXP]{\tl_reverse_tokens:n}
-% \begin{syntax}
-% \cs{tl_reverse_tokens:n} \Arg{tokens}
-% \end{syntax}
-% This function, which works directly on \TeX{} tokens, reverses
-% the order of the \meta{tokens}: the first becomes the last and
-% the last becomes first. Spaces are preserved. The reversal
-% also operates within brace groups, but the braces themselves
-% are not exchanged, as this would lead to an unbalanced token
-% list. For instance, \cs{tl_reverse_tokens:n} |{a~{b()}}|
-% leaves |{)(b}~a| in the input stream. This function requires
-% two steps of expansion.
-% \begin{texnote}
-% The result is returned within the \tn{unexpanded}
-% primitive (\cs{exp_not:n}), which means that the token
-% list does not expand further when appearing in an \texttt{x}-type
-% argument expansion.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}[EXP]{\tl_count_tokens:n}
-% \begin{syntax}
-% \cs{tl_count_tokens:n} \Arg{tokens}
-% \end{syntax}
-% Counts the number of \TeX{} tokens in the \meta{tokens} and leaves
-% this information in the input stream. Every token, including spaces and
-% braces, contributes one to the total; thus for instance, the token count of
-% |a~{bc}| is $6$.
-% This function requires three expansions,
-% giving an \meta{integer denotation}.
-% \end{function}
-%
% \begin{function}[EXP, added = 2014-06-30, updated = 2016-01-12]
% {
% \tl_lower_case:n, \tl_upper_case:n, \tl_mixed_case:n,
@@ -1662,544 +1571,6 @@
% \end{macro}
% \end{macro}
%
-% \subsection{Additions to \pkg{l3coffins}}
-%
-% \begin{macrocode}
-%<@@=coffin>
-% \end{macrocode}
-%
-% \subsubsection{Rotating coffins}
-%
-% \begin{variable}{\l_@@_sin_fp}
-% \begin{variable}{\l_@@_cos_fp}
-% Used for rotations to get the sine and cosine values.
-% \begin{macrocode}
-\fp_new:N \l_@@_sin_fp
-\fp_new:N \l_@@_cos_fp
-% \end{macrocode}
-% \end{variable}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_bounding_prop}
-% A property list for the bounding box of a coffin. This is only needed
-% during the rotation, so there is just the one.
-% \begin{macrocode}
-\prop_new:N \l_@@_bounding_prop
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_corners_prop, \l_@@_poles_prop}
-% Used to avoid needing to track scope for intermediate steps.
-% \begin{macrocode}
-\prop_new:N \l_@@_corners_prop
-\prop_new:N \l_@@_poles_prop
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_bounding_shift_dim}
-% The shift of the bounding box of a coffin from the real content.
-% \begin{macrocode}
-\dim_new:N \l_@@_bounding_shift_dim
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_left_corner_dim}
-% \begin{variable}{\l_@@_right_corner_dim}
-% \begin{variable}{\l_@@_bottom_corner_dim}
-% \begin{variable}{\l_@@_top_corner_dim}
-% These are used to hold maxima for the various corner values: these
-% thus define the minimum size of the bounding box after rotation.
-% \begin{macrocode}
-\dim_new:N \l_@@_left_corner_dim
-\dim_new:N \l_@@_right_corner_dim
-\dim_new:N \l_@@_bottom_corner_dim
-\dim_new:N \l_@@_top_corner_dim
-% \end{macrocode}
-% \end{variable}
-% \end{variable}
-% \end{variable}
-% \end{variable}
-%
-% \begin{macro}
-% {
-% \coffin_rotate:Nn, \coffin_rotate:cn,
-% \coffin_grotate:Nn, \coffin_grotate:cn
-% }
-% \begin{macro}{\@@_rotate:NnNN}
-% Rotating a coffin requires several steps which can be conveniently
-% run together. The sine and cosine of the angle in degrees are
-% computed. This is then used to set \cs{l_@@_sin_fp} and
-% \cs{l_@@_cos_fp}, which are carried through unchanged for the rest
-% of the procedure.
-% \begin{macrocode}
-\cs_new_protected:Npn \coffin_rotate:Nn #1#2
- { \@@_rotate:NnNN #1 {#2} \box_rotate:Nn \prop_set_eq:cN }
-\cs_new_protected:Npn \coffin_grotate:Nn #1#2
- { \@@_rotate:NnNN #1 {#2} \box_grotate:Nn \prop_gset_eq:cN }
-\cs_new_protected:Npn \@@_rotate:NnNN #1#2#3#4
- {
- \fp_set:Nn \l_@@_sin_fp { sind ( #2 ) }
- \fp_set:Nn \l_@@_cos_fp { cosd ( #2 ) }
-% \end{macrocode}
-% Use a local copy of the property lists to avoid needing to pass the
-% name and scope around.
-% \begin{macrocode}
- \prop_set_eq:Nc \l_@@_corners_prop
- { coffin ~ \@@_to_value:N #1 ~ corners }
- \prop_set_eq:Nc \l_@@_poles_prop
- { coffin ~ \@@_to_value:N #1 ~ poles }
-% \end{macrocode}
-% The corners and poles of the coffin can now be rotated around the
-% origin. This is best achieved using mapping functions.
-% \begin{macrocode}
- \prop_map_inline:Nn \l_@@_corners_prop
- { \@@_rotate_corner:Nnnn #1 {##1} ##2 }
- \prop_map_inline:Nn \l_@@_poles_prop
- { \@@_rotate_pole:Nnnnnn #1 {##1} ##2 }
-% \end{macrocode}
-% The bounding box of the coffin needs to be rotated, and to do this
-% the corners have to be found first. They are then rotated in the same
-% way as the corners of the coffin material itself.
-% \begin{macrocode}
- \@@_set_bounding:N #1
- \prop_map_inline:Nn \l_@@_bounding_prop
- { \@@_rotate_bounding:nnn {##1} ##2 }
-% \end{macrocode}
-% At this stage, there needs to be a calculation to find where the
-% corners of the content and the box itself will end up.
-% \begin{macrocode}
- \@@_find_corner_maxima:N #1
- \@@_find_bounding_shift:
- #3 #1 {#2}
-% \end{macrocode}
-% The correction of the box position itself takes place here. The idea
-% is that the bounding box for a coffin is tight up to the content, and
-% has the reference point at the bottom-left. The $x$-direction is
-% handled by moving the content by the difference in the positions of
-% the bounding box and the content left edge. The $y$-direction is
-% dealt with by moving the box down by any depth it has acquired. The
-% internal box is used here to allow for the next step.
-% \begin{macrocode}
- \hbox_set:Nn \l_@@_internal_box
- {
- \tex_kern:D
- \dim_eval:n
- { \l_@@_bounding_shift_dim - \l_@@_left_corner_dim }
- \exp_stop_f:
- \box_move_down:nn { \l_@@_bottom_corner_dim }
- { \box_use:N #1 }
- }
-% \end{macrocode}
-% If there have been any previous rotations then the size of the
-% bounding box will be bigger than the contents. This can be corrected
-% easily by setting the size of the box to the height and width of the
-% content. As this operation requires setting box dimensions and these
-% transcend grouping, the safe way to do this is to use the internal box
-% and to reset the result into the target box.
-% \begin{macrocode}
- \box_set_ht:Nn \l_@@_internal_box
- { \l_@@_top_corner_dim - \l_@@_bottom_corner_dim }
- \box_set_dp:Nn \l_@@_internal_box { 0 pt }
- \box_set_wd:Nn \l_@@_internal_box
- { \l_@@_right_corner_dim - \l_@@_left_corner_dim }
- \hbox_set:Nn #1 { \box_use_drop:N \l_@@_internal_box }
-% \end{macrocode}
-% The final task is to move the poles and corners such that they are
-% back in alignment with the box reference point.
-% \begin{macrocode}
- \prop_map_inline:Nn \l_@@_corners_prop
- { \@@_shift_corner:Nnnn #1 {##1} ##2 }
- \prop_map_inline:Nn \l_@@_poles_prop
- { \@@_shift_pole:Nnnnnn #1 {##1} ##2 }
-% \end{macrocode}
-% Update the coffin data.
-% \begin{macrocode}
- #4 { coffin ~ \@@_to_value:N #1 ~ corners }
- \l_@@_corners_prop
- #4 { coffin ~ \@@_to_value:N #1 ~ poles }
- \l_@@_poles_prop
- }
-\cs_generate_variant:Nn \coffin_rotate:Nn { c }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_set_bounding:N}
-% The bounding box corners for a coffin are easy enough to find: this
-% is the same code as for the corners of the material itself, but
-% using a dedicated property list.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_set_bounding:N #1
- {
- \prop_put:Nnx \l_@@_bounding_prop { tl }
- { { 0 pt } { \dim_eval:n { \box_ht:N #1 } } }
- \prop_put:Nnx \l_@@_bounding_prop { tr }
- {
- { \dim_eval:n { \box_wd:N #1 } }
- { \dim_eval:n { \box_ht:N #1 } }
- }
- \dim_set:Nn \l_@@_internal_dim { -\box_dp:N #1 }
- \prop_put:Nnx \l_@@_bounding_prop { bl }
- { { 0 pt } { \dim_use:N \l_@@_internal_dim } }
- \prop_put:Nnx \l_@@_bounding_prop { br }
- {
- { \dim_eval:n { \box_wd:N #1 } }
- { \dim_use:N \l_@@_internal_dim }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_rotate_bounding:nnn}
-% \begin{macro}{\@@_rotate_corner:Nnnn}
-% Rotating the position of the corner of the coffin is just a case
-% of treating this as a vector from the reference point. The same
-% treatment is used for the corners of the material itself and the
-% bounding box.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_rotate_bounding:nnn #1#2#3
- {
- \@@_rotate_vector:nnNN {#2} {#3} \l_@@_x_dim \l_@@_y_dim
- \prop_put:Nnx \l_@@_bounding_prop {#1}
- { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
- }
-\cs_new_protected:Npn \@@_rotate_corner:Nnnn #1#2#3#4
- {
- \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
- \prop_put:Nnx \l_@@_corners_prop {#2}
- { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_rotate_pole:Nnnnnn}
-% Rotating a single pole simply means shifting the co-ordinate of
-% the pole and its direction. The rotation here is about the bottom-left
-% corner of the coffin.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_rotate_pole:Nnnnnn #1#2#3#4#5#6
- {
- \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
- \@@_rotate_vector:nnNN {#5} {#6}
- \l_@@_x_prime_dim \l_@@_y_prime_dim
- \prop_put:Nnx \l_@@_poles_prop {#2}
- {
- { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
- { \dim_use:N \l_@@_x_prime_dim }
- { \dim_use:N \l_@@_y_prime_dim }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_rotate_vector:nnNN}
-% A rotation function, which needs only an input vector (as dimensions)
-% and an output space. The values \cs{l_@@_cos_fp} and
-% \cs{l_@@_sin_fp} should previously have been set up correctly.
-% Working this way means that the floating point work is kept to a
-% minimum: for any given rotation the sin and cosine values do no
-% change, after all.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_rotate_vector:nnNN #1#2#3#4
- {
- \dim_set:Nn #3
- {
- \fp_to_dim:n
- {
- \dim_to_fp:n {#1} * \l_@@_cos_fp
- - \dim_to_fp:n {#2} * \l_@@_sin_fp
- }
- }
- \dim_set:Nn #4
- {
- \fp_to_dim:n
- {
- \dim_to_fp:n {#1} * \l_@@_sin_fp
- + \dim_to_fp:n {#2} * \l_@@_cos_fp
- }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_find_corner_maxima:N}
-% \begin{macro}{\@@_find_corner_maxima_aux:nn}
-% The idea here is to find the extremities of the content of the
-% coffin. This is done by looking for the smallest values for the bottom
-% and left corners, and the largest values for the top and right
-% corners. The values start at the maximum dimensions so that the
-% case where all are positive or all are negative works out correctly.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_find_corner_maxima:N #1
- {
- \dim_set:Nn \l_@@_top_corner_dim { -\c_max_dim }
- \dim_set:Nn \l_@@_right_corner_dim { -\c_max_dim }
- \dim_set:Nn \l_@@_bottom_corner_dim { \c_max_dim }
- \dim_set:Nn \l_@@_left_corner_dim { \c_max_dim }
- \prop_map_inline:Nn \l_@@_corners_prop
- { \@@_find_corner_maxima_aux:nn ##2 }
- }
-\cs_new_protected:Npn \@@_find_corner_maxima_aux:nn #1#2
- {
- \dim_set:Nn \l_@@_left_corner_dim
- { \dim_min:nn { \l_@@_left_corner_dim } {#1} }
- \dim_set:Nn \l_@@_right_corner_dim
- { \dim_max:nn { \l_@@_right_corner_dim } {#1} }
- \dim_set:Nn \l_@@_bottom_corner_dim
- { \dim_min:nn { \l_@@_bottom_corner_dim } {#2} }
- \dim_set:Nn \l_@@_top_corner_dim
- { \dim_max:nn { \l_@@_top_corner_dim } {#2} }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_find_bounding_shift:}
-% \begin{macro}{\@@_find_bounding_shift_aux:nn}
-% The approach to finding the shift for the bounding box is similar to
-% that for the corners. However, there is only one value needed here and
-% a fixed input property list, so things are a bit clearer.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_find_bounding_shift:
- {
- \dim_set:Nn \l_@@_bounding_shift_dim { \c_max_dim }
- \prop_map_inline:Nn \l_@@_bounding_prop
- { \@@_find_bounding_shift_aux:nn ##2 }
- }
-\cs_new_protected:Npn \@@_find_bounding_shift_aux:nn #1#2
- {
- \dim_set:Nn \l_@@_bounding_shift_dim
- { \dim_min:nn { \l_@@_bounding_shift_dim } {#1} }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_shift_corner:Nnnn}
-% \begin{macro}{\@@_shift_pole:Nnnnnn}
-% Shifting the corners and poles of a coffin means subtracting the
-% appropriate values from the $x$- and $y$-components. For
-% the poles, this means that the direction vector is unchanged.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_shift_corner:Nnnn #1#2#3#4
- {
- \prop_put:Nnx \l_@@_corners_prop {#2}
- {
- { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
- { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
- }
- }
-\cs_new_protected:Npn \@@_shift_pole:Nnnnnn #1#2#3#4#5#6
- {
- \prop_put:Nnx \l_@@_poles_prop {#2}
- {
- { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
- { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
- {#5} {#6}
- }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \subsubsection{Resizing coffins}
-%
-% \begin{variable}{\l_@@_scale_x_fp}
-% \begin{variable}{\l_@@_scale_y_fp}
-% Storage for the scaling factors in $x$ and $y$, respectively.
-% \begin{macrocode}
-\fp_new:N \l_@@_scale_x_fp
-\fp_new:N \l_@@_scale_y_fp
-% \end{macrocode}
-% \end{variable}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_scaled_total_height_dim}
-% \begin{variable}{\l_@@_scaled_width_dim}
-% When scaling, the values given have to be turned into absolute values.
-% \begin{macrocode}
-\dim_new:N \l_@@_scaled_total_height_dim
-\dim_new:N \l_@@_scaled_width_dim
-% \end{macrocode}
-% \end{variable}
-% \end{variable}
-%
-% \begin{macro}
-% {
-% \coffin_resize:Nnn, \coffin_resize:cnn,
-% \coffin_gresize:Nnn, \coffin_gresize:cnn
-% }
-% \begin{macro}{\@@_resize:NnnNN}
-% Resizing a coffin begins by setting up the user-friendly names for
-% the dimensions of the coffin box. The new sizes are then turned into
-% scale factor. This is the same operation as takes place for the
-% underlying box, but that operation is grouped and so the same
-% calculation is done here.
-% \begin{macrocode}
-\cs_new_protected:Npn \coffin_resize:Nnn #1#2#3
- {
- \@@_resize:NnnNN #1 {#2} {#3}
- \box_resize_to_wd_and_ht_plus_dp:Nnn
- \prop_set_eq:cN
- }
-\cs_generate_variant:Nn \coffin_resize:Nnn { c }
-\cs_new_protected:Npn \coffin_gresize:Nnn #1#2#3
- {
- \@@_resize:NnnNN #1 {#2} {#3}
- \box_gresize_to_wd_and_ht_plus_dp:Nnn
- \prop_gset_eq:cN
- }
-\cs_generate_variant:Nn \coffin_gresize:Nnn { c }
-\cs_new_protected:Npn \@@_resize:NnnNN #1#2#3#4#5
- {
- \fp_set:Nn \l_@@_scale_x_fp
- { \dim_to_fp:n {#2} / \dim_to_fp:n { \coffin_wd:N #1 } }
- \fp_set:Nn \l_@@_scale_y_fp
- {
- \dim_to_fp:n {#3}
- / \dim_to_fp:n { \coffin_ht:N #1 + \coffin_dp:N #1 }
- }
- #4 #1 {#2} {#3}
- \@@_resize_common:NnnN #1 {#2} {#3} #5
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_resize_common:NnnN}
-% The poles and corners of the coffin are scaled to the appropriate
-% places before actually resizing the underlying box.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_resize_common:NnnN #1#2#3#4
- {
- \prop_set_eq:Nc \l_@@_corners_prop
- { coffin ~ \@@_to_value:N #1 ~ corners }
- \prop_set_eq:Nc \l_@@_poles_prop
- { coffin ~ \@@_to_value:N #1 ~ poles }
- \prop_map_inline:Nn \l_@@_corners_prop
- { \@@_scale_corner:Nnnn #1 {##1} ##2 }
- \prop_map_inline:Nn \l_@@_poles_prop
- { \@@_scale_pole:Nnnnnn #1 {##1} ##2 }
-% \end{macrocode}
-% Negative $x$-scaling values place the poles in the wrong
-% location: this is corrected here.
-% \begin{macrocode}
- \fp_compare:nNnT \l_@@_scale_x_fp < \c_zero_fp
- {
- \prop_map_inline:Nn \l_@@_corners_prop
- { \@@_x_shift_corner:Nnnn #1 {##1} ##2 }
- \prop_map_inline:Nn \l_@@_poles_prop
- { \@@_x_shift_pole:Nnnnnn #1 {##1} ##2 }
- }
- #4 { coffin ~ \@@_to_value:N #1 ~ corners }
- \l_@@_corners_prop
- #4 { coffin ~ \@@_to_value:N #1 ~ poles }
- \l_@@_poles_prop
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}
-% {
-% \coffin_scale:Nnn, \coffin_scale:cnn,
-% \coffin_gscale:Nnn, \coffin_gscale:cnn
-% }
-% \begin{macro}{\coffin_scale:NnnNN}
-% For scaling, the opposite calculation is done to find the new
-% dimensions for the coffin. Only the total height is needed, as this
-% is the shift required for corners and poles. The scaling is done
-% the \TeX{} way as this works properly with floating point values
-% without needing to use the \texttt{fp} module.
-% \begin{macrocode}
-\cs_new_protected:Npn \coffin_scale:Nnn #1#2#3
- { \@@_scale:NnnNN #1 {#2} {#3} \box_scale:Nnn \prop_set_eq:cN }
-\cs_generate_variant:Nn \coffin_scale:Nnn { c }
-\cs_new_protected:Npn \coffin_gscale:Nnn #1#2#3
- { \@@_scale:NnnNN #1 {#2} {#3} \box_gscale:Nnn \prop_gset_eq:cN }
-\cs_generate_variant:Nn \coffin_gscale:Nnn { c }
-\cs_new_protected:Npn \@@_scale:NnnNN #1#2#3#4#5
- {
- \fp_set:Nn \l_@@_scale_x_fp {#2}
- \fp_set:Nn \l_@@_scale_y_fp {#3}
- #4 #1 { \l_@@_scale_x_fp } { \l_@@_scale_y_fp }
- \dim_set:Nn \l_@@_internal_dim
- { \coffin_ht:N #1 + \coffin_dp:N #1 }
- \dim_set:Nn \l_@@_scaled_total_height_dim
- { \fp_abs:n { \l_@@_scale_y_fp } \l_@@_internal_dim }
- \dim_set:Nn \l_@@_scaled_width_dim
- { -\fp_abs:n { \l_@@_scale_x_fp } \coffin_wd:N #1 }
- \@@_resize_common:NnnN #1
- { \l_@@_scaled_width_dim } { \l_@@_scaled_total_height_dim }
- #5
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_scale_vector:nnNN}
-% This functions scales a vector from the origin using the pre-set scale
-% factors in $x$ and $y$. This is a much less complex operation
-% than rotation, and as a result the code is a lot clearer.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_scale_vector:nnNN #1#2#3#4
- {
- \dim_set:Nn #3
- { \fp_to_dim:n { \dim_to_fp:n {#1} * \l_@@_scale_x_fp } }
- \dim_set:Nn #4
- { \fp_to_dim:n { \dim_to_fp:n {#2} * \l_@@_scale_y_fp } }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_scale_corner:Nnnn}
-% \begin{macro}{\@@_scale_pole:Nnnnnn}
-% Scaling both corners and poles is a simple calculation using the
-% preceding vector scaling.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_scale_corner:Nnnn #1#2#3#4
- {
- \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
- \prop_put:Nnx \l_@@_corners_prop {#2}
- { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
- }
-\cs_new_protected:Npn \@@_scale_pole:Nnnnnn #1#2#3#4#5#6
- {
- \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
- \prop_put:Nnx \l_@@_poles_prop {#2}
- {
- { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
- {#5} {#6}
- }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_x_shift_corner:Nnnn}
-% \begin{macro}{\@@_x_shift_pole:Nnnnnn}
-% These functions correct for the $x$ displacement that takes
-% place with a negative horizontal scaling.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_x_shift_corner:Nnnn #1#2#3#4
- {
- \prop_put:Nnx \l_@@_corners_prop {#2}
- {
- { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
- }
- }
-\cs_new_protected:Npn \@@_x_shift_pole:Nnnnnn #1#2#3#4#5#6
- {
- \prop_put:Nnx \l_@@_poles_prop {#2}
- {
- { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
- {#5} {#6}
- }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
% \subsection{Additions to \pkg{l3fp-convert}}
%
% \begin{macrocode}
@@ -2234,44 +1605,63 @@
% coverage varies in other engines.
% \begin{macrocode}
\cs_new_protected:Npn \file_get_mdfive_hash:nN #1#2
- { \@@_get_details:nnN {#1} { mdfivesum } {#2} }
+ { \file_get_mdfive_hash:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
\cs_new_protected:Npn \file_get_size:nN #1#2
- { \@@_get_details:nnN {#1} { size } {#2} }
+ { \file_get_size:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
\cs_new_protected:Npn \file_get_timestamp:nN #1#2
+ { \file_get_timestamp:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\prg_new_protected_conditional:Npnn \file_get_mdfive_hash:nN #1#2 { T , F , TF }
+ { \@@_get_details:nnN {#1} { mdfivesum } {#2} }
+\prg_new_protected_conditional:Npnn \file_get_size:nN #1#2 { T , F , TF }
+ { \@@_get_details:nnN {#1} { size } {#2} }
+\prg_new_protected_conditional:Npnn \file_get_timestamp:nN #1#2 { T , F , TF }
{ \@@_get_details:nnN {#1} { moddate } {#2} }
\cs_new_protected:Npn \@@_get_details:nnN #1#2#3
{
- \file_get_full_name:nN {#1} \l_@@_full_name_str
- \str_set:Nx #3
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
{
- \use:c { tex_file #2 :D } \exp_after:wN
- { \l_@@_full_name_str }
+ \tl_set:Nx #3
+ {
+ \use:c { tex_file #2 :D } \exp_after:wN
+ { \l_@@_full_name_tl }
+ }
+ \prg_return_true:
}
+ { \prg_return_false: }
}
\sys_if_engine_luatex:TF
{
\cs_set_protected:Npn \@@_get_details:nnN #1#2#3
{
- \file_get_full_name:nN {#1} \l_@@_full_name_str
- \str_set:Nx #3
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
{
- \lua_now:e
+ \tl_set:Nx #3
{
- l3kernel.file#2
- ( " \lua_escape:e { \l_@@_full_name_str } " )
+ \lua_now:e
+ {
+ l3kernel.file#2
+ ( " \lua_escape:e { \l_@@_full_name_tl } " )
+ }
}
+ \prg_return_true:
}
- }
+ { \prg_return_false: }
+ }
}
{
- \cs_set_protected:Npn \file_get_mdfive_hash:nN #1#2
+ \prg_set_protected_conditional:Npnn \file_get_mdfive_hash:nN #1#2
+ { T , F , TF }
{
- \file_get_full_name:nN {#1} \l_@@_full_name_str
- \tl_set:Nx #2
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
{
- \tex_mdfivesum:D file \exp_after:wN
- { \l_@@_full_name_str }
+ \tl_set:Nx #2
+ {
+ \tex_mdfivesum:D file \exp_after:wN
+ { \l_@@_full_name_tl }
+ }
+ \prg_return_true:
}
+ { \prg_return_false: }
}
\cs_if_exist:NF \tex_filesize:D
{
@@ -2281,6 +1671,7 @@
\__kernel_msg_error:nnx
{ kernel } { primitive-not-available }
{ \exp_not:c { (pdf)file #2 } }
+ \prg_return_false:
}
}
}
@@ -2301,16 +1692,14 @@
% \begin{macrocode}
\cs_new_protected:Npn \file_if_exist_input:n #1
{
- \file_get_full_name:nN {#1} \l_@@_full_name_str
- \str_if_empty:NF \l_@@_full_name_str
- { \@@_input:V \l_@@_full_name_str }
+ \file_get_full_name:nNT {#1} \l_@@_full_name_tl
+ { \@@_input:V \l_@@_full_name_tl }
}
\cs_new_protected:Npn \file_if_exist_input:nF #1#2
{
- \file_get_full_name:nN {#1} \l_@@_full_name_str
- \str_if_empty:NTF \l_@@_full_name_str
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
+ { \@@_input:V \l_@@_full_name_tl }
{#2}
- { \@@_input:V \l_@@_full_name_str }
}
% \end{macrocode}
% \end{macro}
@@ -2401,10 +1790,14 @@
% \begin{macrocode}
\cs_new:Npn \msg_expandable_error:nnnnnn #1#2#3#4#5#6
{
- \exp_args:Nf \@@_expandable_error_module:nn
+ \exp_args:Ne \@@_expandable_error_module:nn
{
- \exp_args:Nf \tl_to_str:n
- { \use:c { \c_@@_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ \exp_args:Nc \exp_args:Noooo
+ { \c_@@_text_prefix_tl #1 / #2 }
+ { \tl_to_str:n {#3} }
+ { \tl_to_str:n {#4} }
+ { \tl_to_str:n {#5} }
+ { \tl_to_str:n {#6} }
}
{#1}
}
@@ -2516,27 +1909,6 @@
%<@@=prop>
% \end{macrocode}
%
-% \begin{macro}[EXP]{\prop_count:N, \prop_count:c}
-% \begin{macro}[EXP]{\@@_count:nn}
-% Counting the key--value pairs in a property list is done using the
-% same approach as for other count functions: turn each entry into a
-% \texttt{+1} then use integer evaluation to actually do the
-% mathematics.
-% \begin{macrocode}
-\cs_new:Npn \prop_count:N #1
- {
- \int_eval:n
- {
- 0
- \prop_map_function:NN #1 \@@_count:nn
- }
- }
-\cs_new:Npn \@@_count:nn #1#2 { + 1 }
-\cs_generate_variant:Nn \prop_count:N { c }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
% \begin{macro}[rEXP]{\prop_map_tokens:Nn, \prop_map_tokens:cn}
% \begin{macro}{\@@_map_tokens:nwwn}
% The mapping is very similar to \cs{prop_map_function:NN}. The
@@ -2878,34 +2250,6 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macrocode}
-%<@@=skip>
-% \end{macrocode}
-%
-% \begin{macro}{\skip_split_finite_else_action:nnNN}
-% This macro is useful when performing error checking in certain
-% circumstances. If the \meta{skip} register holds finite glue it sets
-% |#3| and |#4| to the stretch and shrink component, resp. If it holds
-% infinite glue set |#3| and |#4| to zero and issue the special action
-% |#2| which is probably an error message.
-% Assignments are local.
-% \begin{macrocode}
-\cs_new:Npn \skip_split_finite_else_action:nnNN #1#2#3#4
- {
- \skip_if_finite:nTF {#1}
- {
- #3 = \tex_gluestretch:D #1 \scan_stop:
- #4 = \tex_glueshrink:D #1 \scan_stop:
- }
- {
- #3 = \c_zero_skip
- #4 = \c_zero_skip
- #2
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
% \subsection{Additions to \pkg{l3sys}}
%
% \begin{macrocode}
@@ -3045,7 +2389,7 @@
\cs_new_protected:Npn \sys_shell_get:nnN #1#2#3
{
\sys_shell_get:nnNF {#1} {#2} #3
- { \tl_clear:N #3 }
+ { \tl_set:Nn #3 { \q_no_value } }
}
\prg_new_protected_conditional:Npnn \sys_shell_get:nnN #1#2#3 { T , F , TF }
{
@@ -3062,8 +2406,8 @@
\prg_return_false:
}
{
- \if_false: { \fi:
\group_begin:
+ \if_false: { \fi:
\int_set_eq:NN \tex_tracingnesting:D \c_zero_int
\exp_args:No \tex_everyeof:D { \c_@@_marker_tl }
#2 \scan_stop:
@@ -3222,122 +2566,6 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP]{\tl_reverse_tokens:n}
-% \begin{macro}[EXP]{\@@_reverse_group:nn}
-% The same as \cs{tl_reverse:n} but with recursion within brace groups.
-% \begin{macrocode}
-\cs_new:Npn \tl_reverse_tokens:n #1
- {
- \__kernel_exp_not:w \exp_after:wN
- {
- \exp:w
- \@@_act:NNNnn
- \@@_reverse_normal:nN
- \@@_reverse_group:nn
- \@@_reverse_space:n
- { }
- {#1}
- }
- }
-\cs_new:Npn \@@_reverse_group:nn #1
- {
- \@@_act_group_recurse:Nnn
- \@@_act_reverse_output:n
- { \tl_reverse_tokens:n }
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}[EXP]{\@@_act_group_recurse:Nnn}
-% In many applications of \cs{@@_act:NNNnn}, we need to recursively
-% apply some transformation within brace groups, then output. In this
-% code, |#1| is the output function, |#2| is the transformation,
-% which should expand in two steps, and |#3| is the group.
-% \begin{macrocode}
-\cs_new:Npn \@@_act_group_recurse:Nnn #1#2#3
- {
- \exp_args:Nf #1
- { \exp_after:wN \exp_after:wN \exp_after:wN { #2 {#3} } }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\tl_count_tokens:n}
-% \begin{macro}[EXP]{\@@_act_count_normal:nN,
-% \@@_act_count_group:nn, \@@_act_count_space:n}
-% 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_int}).
-% Somewhat a hack!
-% \begin{macrocode}
-\cs_new:Npn \tl_count_tokens:n #1
- {
- \int_eval:n
- {
- \@@_act:NNNnn
- \@@_act_count_normal:nN
- \@@_act_count_group:nn
- \@@_act_count_space:n
- { }
- {#1}
- }
- }
-\cs_new:Npn \@@_act_count_normal:nN #1 #2 { 1 + }
-\cs_new:Npn \@@_act_count_space:n #1 { 1 + }
-\cs_new:Npn \@@_act_count_group:nn #1 #2
- { 2 + \tl_count_tokens:n {#2} + }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \subsubsection{Deprecated functions}
-%
-% \begin{macro}[deprecated = 2020-12-31]
-% {
-% \tl_set_from_file:Nnn, \tl_set_from_file:cnn,
-% \tl_gset_from_file:Nnn, \tl_gset_from_file:cnn,
-% \tl_set_from_file_x:Nnn, \tl_set_from_file_x:cnn,
-% \tl_gset_from_file_x:Nnn, \tl_gset_from_file_x:cnn
-% }
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_set_from_file:Nnn #1#2#3
- { \file_get:nnN {#3} {#2} #1 }
-\cs_generate_variant:Nn \tl_set_from_file:Nnn { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_gset_from_file:Nnn #1#2#3
- {
- \group_begin:
- \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
- \tl_gset_eq:NN #1 \l_@@_internal_a_tl
- \group_end:
- }
-\cs_generate_variant:Nn \tl_gset_from_file:Nnn { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_set_from_file_x:Nnn #1#2#3
- {
- \group_begin:
- \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
- #2 \scan_stop:
- \tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl }
- \exp_args:NNNo \group_end:
- \tl_set:Nn #1 \l_@@_internal_a_tl
- }
-\cs_generate_variant:Nn \tl_set_from_file_x:Nnn { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_gset_from_file_x:Nnn #1#2#3
- {
- \group_begin:
- \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
- #2 \scan_stop:
- \tl_gset:Nx #1 { \l_@@_internal_a_tl }
- \group_end:
- }
-\cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c }
-% \end{macrocode}
-% \end{macro}
-%
% \subsubsection{Unicode case changing}
%
% The mechanisms needed for case changing are somewhat involved, particularly
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
index 0fa08188cd9..17fc46306c8 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
@@ -1,7 +1,7 @@
% \iffalse meta-comment
%
%% File: l3clist.dtx
-%
+%
% Copyright (C) 2004-2011 Frank Mittelbach, The LaTeX3 Project
% (C) 2012-2019 The LaTeX3 Project
%
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -337,7 +337,7 @@
% \begin{texnote}
% The result is returned within \tn{unexpanded}, which means that the
% comma list does not expand further when appearing in an
-% \texttt{x}-type argument expansion.
+% \texttt{x}-type or \texttt{e}-type argument expansion.
% \end{texnote}
% \end{function}
%
@@ -584,28 +584,16 @@
% in the previous section: a comma list should either be used as an
% ordered data type or as a stack, but not in both ways.
%
-% \begin{function}[updated = 2012-05-14]{\clist_get:NN, \clist_get:cN}
+% \begin{function}[noTF, added = 2012-05-14, updated = 2019-02-16]
+% {\clist_get:NN, \clist_get:cN}
% \begin{syntax}
% \cs{clist_get:NN} \meta{comma list} \meta{token list variable}
% \end{syntax}
% Stores the left-most item from a \meta{comma list} in the
% \meta{token list variable} without removing it from the
% \meta{comma list}. The \meta{token list variable} is assigned locally.
-% If the \meta{comma list} is empty the \meta{token list variable}
-% is set to the marker value \cs{q_no_value}.
-% \end{function}
-%
-% \begin{function}[TF, added = 2012-05-14]{\clist_get:NN, \clist_get:cN}
-% \begin{syntax}
-% \cs{clist_get:NNTF} \meta{comma list} \meta{token list variable} \Arg{true code} \Arg{false code}
-% \end{syntax}
-% If the \meta{comma list} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
-% not defined in this case and should not be relied upon. If the
-% \meta{comma list} is non-empty, stores the top item from the
-% \meta{comma list} in the \meta{token list variable} without removing it
-% from the \meta{comma list}. The \meta{token list variable} is assigned
-% locally.
+% In the non-branching version, if the \meta{comma list} is empty the
+% \meta{token list variable} is set to the marker value \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2011-09-06]{\clist_pop:NN, \clist_pop:cN}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
index 88ae571c742..48f4edbc6a3 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -100,7 +100,7 @@
%
% \section{Setting coffin content and poles}
%
-% \begin{function}[added = 2011-08-17, updated = 2011-09-03]
+% \begin{function}[added = 2011-08-17, updated = 2019-01-21]
% {
% \hcoffin_set:Nn, \hcoffin_set:cn,
% \hcoffin_gset:Nn, \hcoffin_gset:cn
@@ -187,6 +187,47 @@
% \meta{offset} should be given as a dimension expression.
% \end{function}
%
+% \section{Coffin affine transformations}
+%
+% \begin{function}[updated = 2019-01-23]
+% {
+% \coffin_resize:Nnn, \coffin_resize:cnn,
+% \coffin_gresize:Nnn, \coffin_gresize:cnn
+% }
+% \begin{syntax}
+% \cs{coffin_resize:Nnn} \meta{coffin} \Arg{width} \Arg{total-height}
+% \end{syntax}
+% Resized the \meta{coffin} to \meta{width} and \meta{total-height},
+% both of which should be given as dimension expressions.
+% \end{function}
+%
+% \begin{function}
+% {
+% \coffin_rotate:Nn, \coffin_rotate:cn,
+% \coffin_grotate:Nn, \coffin_grotate:cn
+% }
+% \begin{syntax}
+% \cs{coffin_rotate:Nn} \meta{coffin} \Arg{angle}
+% \end{syntax}
+% Rotates the \meta{coffin} by the given \meta{angle} (given in
+% degrees counter-clockwise). This process rotates both the
+% coffin content and poles. Multiple rotations do not result in
+% the bounding box of the coffin growing unnecessarily.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-23]
+% {
+% \coffin_scale:Nnn, \coffin_scale:cnn,
+% \coffin_gscale:Nnn, \coffin_gscale:cnn
+% }
+% \begin{syntax}
+% \cs{coffin_scale:Nnn} \meta{coffin} \Arg{x-scale} \Arg{y-scale}
+% \end{syntax}
+% Scales the \meta{coffin} by a factors \meta{x-scale} and
+% \meta{y-scale} in the horizontal and vertical directions,
+% respectively. The two scale factors should be given as real numbers.
+% \end{function}
+%
% \section{Joining and using coffins}
%
% \begin{function}[updated = 2019-01-22]
@@ -1277,6 +1318,537 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Affine transformations}
+%
+% \begin{variable}{\l_@@_sin_fp}
+% \begin{variable}{\l_@@_cos_fp}
+% Used for rotations to get the sine and cosine values.
+% \begin{macrocode}
+\fp_new:N \l_@@_sin_fp
+\fp_new:N \l_@@_cos_fp
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_bounding_prop}
+% A property list for the bounding box of a coffin. This is only needed
+% during the rotation, so there is just the one.
+% \begin{macrocode}
+\prop_new:N \l_@@_bounding_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_corners_prop, \l_@@_poles_prop}
+% Used to avoid needing to track scope for intermediate steps.
+% \begin{macrocode}
+\prop_new:N \l_@@_corners_prop
+\prop_new:N \l_@@_poles_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_bounding_shift_dim}
+% The shift of the bounding box of a coffin from the real content.
+% \begin{macrocode}
+\dim_new:N \l_@@_bounding_shift_dim
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_left_corner_dim}
+% \begin{variable}{\l_@@_right_corner_dim}
+% \begin{variable}{\l_@@_bottom_corner_dim}
+% \begin{variable}{\l_@@_top_corner_dim}
+% These are used to hold maxima for the various corner values: these
+% thus define the minimum size of the bounding box after rotation.
+% \begin{macrocode}
+\dim_new:N \l_@@_left_corner_dim
+\dim_new:N \l_@@_right_corner_dim
+\dim_new:N \l_@@_bottom_corner_dim
+\dim_new:N \l_@@_top_corner_dim
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \coffin_rotate:Nn, \coffin_rotate:cn,
+% \coffin_grotate:Nn, \coffin_grotate:cn
+% }
+% \begin{macro}{\@@_rotate:NnNNN}
+% Rotating a coffin requires several steps which can be conveniently
+% run together. The sine and cosine of the angle in degrees are
+% computed. This is then used to set \cs{l_@@_sin_fp} and
+% \cs{l_@@_cos_fp}, which are carried through unchanged for the rest
+% of the procedure.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_rotate:Nn #1#2
+ { \@@_rotate:NnNNN #1 {#2} \box_rotate:Nn \prop_set_eq:cN \hbox_set:Nn }
+\cs_generate_variant:Nn \coffin_rotate:Nn { c }
+\cs_new_protected:Npn \coffin_grotate:Nn #1#2
+ { \@@_rotate:NnNNN #1 {#2} \box_grotate:Nn \prop_gset_eq:cN \hbox_gset:Nn }
+\cs_generate_variant:Nn \coffin_grotate:Nn { c }
+\cs_new_protected:Npn \@@_rotate:NnNNN #1#2#3#4#5
+ {
+ \fp_set:Nn \l_@@_sin_fp { sind ( #2 ) }
+ \fp_set:Nn \l_@@_cos_fp { cosd ( #2 ) }
+% \end{macrocode}
+% Use a local copy of the property lists to avoid needing to pass the
+% name and scope around.
+% \begin{macrocode}
+ \prop_set_eq:Nc \l_@@_corners_prop
+ { coffin ~ \@@_to_value:N #1 ~ corners }
+ \prop_set_eq:Nc \l_@@_poles_prop
+ { coffin ~ \@@_to_value:N #1 ~ poles }
+% \end{macrocode}
+% The corners and poles of the coffin can now be rotated around the
+% origin. This is best achieved using mapping functions.
+% \begin{macrocode}
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_rotate_corner:Nnnn #1 {##1} ##2 }
+ \prop_map_inline:Nn \l_@@_poles_prop
+ { \@@_rotate_pole:Nnnnnn #1 {##1} ##2 }
+% \end{macrocode}
+% The bounding box of the coffin needs to be rotated, and to do this
+% the corners have to be found first. They are then rotated in the same
+% way as the corners of the coffin material itself.
+% \begin{macrocode}
+ \@@_set_bounding:N #1
+ \prop_map_inline:Nn \l_@@_bounding_prop
+ { \@@_rotate_bounding:nnn {##1} ##2 }
+% \end{macrocode}
+% At this stage, there needs to be a calculation to find where the
+% corners of the content and the box itself will end up.
+% \begin{macrocode}
+ \@@_find_corner_maxima:N #1
+ \@@_find_bounding_shift:
+ #3 #1 {#2}
+% \end{macrocode}
+% The correction of the box position itself takes place here. The idea
+% is that the bounding box for a coffin is tight up to the content, and
+% has the reference point at the bottom-left. The $x$-direction is
+% handled by moving the content by the difference in the positions of
+% the bounding box and the content left edge. The $y$-direction is
+% dealt with by moving the box down by any depth it has acquired. The
+% internal box is used here to allow for the next step.
+% \begin{macrocode}
+ \hbox_set:Nn \l_@@_internal_box
+ {
+ \tex_kern:D
+ \dim_eval:n
+ { \l_@@_bounding_shift_dim - \l_@@_left_corner_dim }
+ \exp_stop_f:
+ \box_move_down:nn { \l_@@_bottom_corner_dim }
+ { \box_use:N #1 }
+ }
+% \end{macrocode}
+% If there have been any previous rotations then the size of the
+% bounding box will be bigger than the contents. This can be corrected
+% easily by setting the size of the box to the height and width of the
+% content. As this operation requires setting box dimensions and these
+% transcend grouping, the safe way to do this is to use the internal box
+% and to reset the result into the target box.
+% \begin{macrocode}
+ \box_set_ht:Nn \l_@@_internal_box
+ { \l_@@_top_corner_dim - \l_@@_bottom_corner_dim }
+ \box_set_dp:Nn \l_@@_internal_box { 0pt }
+ \box_set_wd:Nn \l_@@_internal_box
+ { \l_@@_right_corner_dim - \l_@@_left_corner_dim }
+ #5 #1 { \box_use_drop:N \l_@@_internal_box }
+% \end{macrocode}
+% The final task is to move the poles and corners such that they are
+% back in alignment with the box reference point.
+% \begin{macrocode}
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_shift_corner:Nnnn #1 {##1} ##2 }
+ \prop_map_inline:Nn \l_@@_poles_prop
+ { \@@_shift_pole:Nnnnnn #1 {##1} ##2 }
+% \end{macrocode}
+% Update the coffin data.
+% \begin{macrocode}
+ #4 { coffin ~ \@@_to_value:N #1 ~ corners }
+ \l_@@_corners_prop
+ #4 { coffin ~ \@@_to_value:N #1 ~ poles }
+ \l_@@_poles_prop
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_bounding:N}
+% The bounding box corners for a coffin are easy enough to find: this
+% is the same code as for the corners of the material itself, but
+% using a dedicated property list.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_bounding:N #1
+ {
+ \prop_put:Nnx \l_@@_bounding_prop { tl }
+ { { 0pt } { \dim_eval:n { \box_ht:N #1 } } }
+ \prop_put:Nnx \l_@@_bounding_prop { tr }
+ {
+ { \dim_eval:n { \box_wd:N #1 } }
+ { \dim_eval:n { \box_ht:N #1 } }
+ }
+ \dim_set:Nn \l_@@_internal_dim { -\box_dp:N #1 }
+ \prop_put:Nnx \l_@@_bounding_prop { bl }
+ { { 0pt } { \dim_use:N \l_@@_internal_dim } }
+ \prop_put:Nnx \l_@@_bounding_prop { br }
+ {
+ { \dim_eval:n { \box_wd:N #1 } }
+ { \dim_use:N \l_@@_internal_dim }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rotate_bounding:nnn}
+% \begin{macro}{\@@_rotate_corner:Nnnn}
+% Rotating the position of the corner of the coffin is just a case
+% of treating this as a vector from the reference point. The same
+% treatment is used for the corners of the material itself and the
+% bounding box.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_bounding:nnn #1#2#3
+ {
+ \@@_rotate_vector:nnNN {#2} {#3} \l_@@_x_dim \l_@@_y_dim
+ \prop_put:Nnx \l_@@_bounding_prop {#1}
+ { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
+ }
+\cs_new_protected:Npn \@@_rotate_corner:Nnnn #1#2#3#4
+ {
+ \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+ \prop_put:Nnx \l_@@_corners_prop {#2}
+ { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_rotate_pole:Nnnnnn}
+% Rotating a single pole simply means shifting the co-ordinate of
+% the pole and its direction. The rotation here is about the bottom-left
+% corner of the coffin.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_pole:Nnnnnn #1#2#3#4#5#6
+ {
+ \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+ \@@_rotate_vector:nnNN {#5} {#6}
+ \l_@@_x_prime_dim \l_@@_y_prime_dim
+ \prop_put:Nnx \l_@@_poles_prop {#2}
+ {
+ { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
+ { \dim_use:N \l_@@_x_prime_dim }
+ { \dim_use:N \l_@@_y_prime_dim }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rotate_vector:nnNN}
+% A rotation function, which needs only an input vector (as dimensions)
+% and an output space. The values \cs{l_@@_cos_fp} and
+% \cs{l_@@_sin_fp} should previously have been set up correctly.
+% Working this way means that the floating point work is kept to a
+% minimum: for any given rotation the sin and cosine values do no
+% change, after all.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_vector:nnNN #1#2#3#4
+ {
+ \dim_set:Nn #3
+ {
+ \fp_to_dim:n
+ {
+ \dim_to_fp:n {#1} * \l_@@_cos_fp
+ - \dim_to_fp:n {#2} * \l_@@_sin_fp
+ }
+ }
+ \dim_set:Nn #4
+ {
+ \fp_to_dim:n
+ {
+ \dim_to_fp:n {#1} * \l_@@_sin_fp
+ + \dim_to_fp:n {#2} * \l_@@_cos_fp
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_find_corner_maxima:N}
+% \begin{macro}{\@@_find_corner_maxima_aux:nn}
+% The idea here is to find the extremities of the content of the
+% coffin. This is done by looking for the smallest values for the bottom
+% and left corners, and the largest values for the top and right
+% corners. The values start at the maximum dimensions so that the
+% case where all are positive or all are negative works out correctly.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_find_corner_maxima:N #1
+ {
+ \dim_set:Nn \l_@@_top_corner_dim { -\c_max_dim }
+ \dim_set:Nn \l_@@_right_corner_dim { -\c_max_dim }
+ \dim_set:Nn \l_@@_bottom_corner_dim { \c_max_dim }
+ \dim_set:Nn \l_@@_left_corner_dim { \c_max_dim }
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_find_corner_maxima_aux:nn ##2 }
+ }
+\cs_new_protected:Npn \@@_find_corner_maxima_aux:nn #1#2
+ {
+ \dim_set:Nn \l_@@_left_corner_dim
+ { \dim_min:nn { \l_@@_left_corner_dim } {#1} }
+ \dim_set:Nn \l_@@_right_corner_dim
+ { \dim_max:nn { \l_@@_right_corner_dim } {#1} }
+ \dim_set:Nn \l_@@_bottom_corner_dim
+ { \dim_min:nn { \l_@@_bottom_corner_dim } {#2} }
+ \dim_set:Nn \l_@@_top_corner_dim
+ { \dim_max:nn { \l_@@_top_corner_dim } {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_find_bounding_shift:}
+% \begin{macro}{\@@_find_bounding_shift_aux:nn}
+% The approach to finding the shift for the bounding box is similar to
+% that for the corners. However, there is only one value needed here and
+% a fixed input property list, so things are a bit clearer.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_find_bounding_shift:
+ {
+ \dim_set:Nn \l_@@_bounding_shift_dim { \c_max_dim }
+ \prop_map_inline:Nn \l_@@_bounding_prop
+ { \@@_find_bounding_shift_aux:nn ##2 }
+ }
+\cs_new_protected:Npn \@@_find_bounding_shift_aux:nn #1#2
+ {
+ \dim_set:Nn \l_@@_bounding_shift_dim
+ { \dim_min:nn { \l_@@_bounding_shift_dim } {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_shift_corner:Nnnn}
+% \begin{macro}{\@@_shift_pole:Nnnnnn}
+% Shifting the corners and poles of a coffin means subtracting the
+% appropriate values from the $x$- and $y$-components. For
+% the poles, this means that the direction vector is unchanged.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_shift_corner:Nnnn #1#2#3#4
+ {
+ \prop_put:Nnx \l_@@_corners_prop {#2}
+ {
+ { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
+ { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
+ }
+ }
+\cs_new_protected:Npn \@@_shift_pole:Nnnnnn #1#2#3#4#5#6
+ {
+ \prop_put:Nnx \l_@@_poles_prop {#2}
+ {
+ { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
+ { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
+ {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_scale_x_fp}
+% \begin{variable}{\l_@@_scale_y_fp}
+% Storage for the scaling factors in $x$ and $y$, respectively.
+% \begin{macrocode}
+\fp_new:N \l_@@_scale_x_fp
+\fp_new:N \l_@@_scale_y_fp
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_scaled_total_height_dim}
+% \begin{variable}{\l_@@_scaled_width_dim}
+% When scaling, the values given have to be turned into absolute values.
+% \begin{macrocode}
+\dim_new:N \l_@@_scaled_total_height_dim
+\dim_new:N \l_@@_scaled_width_dim
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \coffin_resize:Nnn, \coffin_resize:cnn,
+% \coffin_gresize:Nnn, \coffin_gresize:cnn
+% }
+% \begin{macro}{\@@_resize:NnnNN}
+% Resizing a coffin begins by setting up the user-friendly names for
+% the dimensions of the coffin box. The new sizes are then turned into
+% scale factor. This is the same operation as takes place for the
+% underlying box, but that operation is grouped and so the same
+% calculation is done here.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_resize:Nnn #1#2#3
+ {
+ \@@_resize:NnnNN #1 {#2} {#3}
+ \box_resize_to_wd_and_ht_plus_dp:Nnn
+ \prop_set_eq:cN
+ }
+\cs_generate_variant:Nn \coffin_resize:Nnn { c }
+\cs_new_protected:Npn \coffin_gresize:Nnn #1#2#3
+ {
+ \@@_resize:NnnNN #1 {#2} {#3}
+ \box_gresize_to_wd_and_ht_plus_dp:Nnn
+ \prop_gset_eq:cN
+ }
+\cs_generate_variant:Nn \coffin_gresize:Nnn { c }
+\cs_new_protected:Npn \@@_resize:NnnNN #1#2#3#4#5
+ {
+ \fp_set:Nn \l_@@_scale_x_fp
+ { \dim_to_fp:n {#2} / \dim_to_fp:n { \coffin_wd:N #1 } }
+ \fp_set:Nn \l_@@_scale_y_fp
+ {
+ \dim_to_fp:n {#3}
+ / \dim_to_fp:n { \coffin_ht:N #1 + \coffin_dp:N #1 }
+ }
+ #4 #1 {#2} {#3}
+ \@@_resize_common:NnnN #1 {#2} {#3} #5
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_resize_common:NnnN}
+% The poles and corners of the coffin are scaled to the appropriate
+% places before actually resizing the underlying box.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_resize_common:NnnN #1#2#3#4
+ {
+ \prop_set_eq:Nc \l_@@_corners_prop
+ { coffin ~ \@@_to_value:N #1 ~ corners }
+ \prop_set_eq:Nc \l_@@_poles_prop
+ { coffin ~ \@@_to_value:N #1 ~ poles }
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_scale_corner:Nnnn #1 {##1} ##2 }
+ \prop_map_inline:Nn \l_@@_poles_prop
+ { \@@_scale_pole:Nnnnnn #1 {##1} ##2 }
+% \end{macrocode}
+% Negative $x$-scaling values place the poles in the wrong
+% location: this is corrected here.
+% \begin{macrocode}
+ \fp_compare:nNnT \l_@@_scale_x_fp < \c_zero_fp
+ {
+ \prop_map_inline:Nn \l_@@_corners_prop
+ { \@@_x_shift_corner:Nnnn #1 {##1} ##2 }
+ \prop_map_inline:Nn \l_@@_poles_prop
+ { \@@_x_shift_pole:Nnnnnn #1 {##1} ##2 }
+ }
+ #4 { coffin ~ \@@_to_value:N #1 ~ corners }
+ \l_@@_corners_prop
+ #4 { coffin ~ \@@_to_value:N #1 ~ poles }
+ \l_@@_poles_prop
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \coffin_scale:Nnn, \coffin_scale:cnn,
+% \coffin_gscale:Nnn, \coffin_gscale:cnn
+% }
+% \begin{macro}{\coffin_scale:NnnNN}
+% For scaling, the opposite calculation is done to find the new
+% dimensions for the coffin. Only the total height is needed, as this
+% is the shift required for corners and poles. The scaling is done
+% the \TeX{} way as this works properly with floating point values
+% without needing to use the \texttt{fp} module.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_scale:Nnn #1#2#3
+ { \@@_scale:NnnNN #1 {#2} {#3} \box_scale:Nnn \prop_set_eq:cN }
+\cs_generate_variant:Nn \coffin_scale:Nnn { c }
+\cs_new_protected:Npn \coffin_gscale:Nnn #1#2#3
+ { \@@_scale:NnnNN #1 {#2} {#3} \box_gscale:Nnn \prop_gset_eq:cN }
+\cs_generate_variant:Nn \coffin_gscale:Nnn { c }
+\cs_new_protected:Npn \@@_scale:NnnNN #1#2#3#4#5
+ {
+ \fp_set:Nn \l_@@_scale_x_fp {#2}
+ \fp_set:Nn \l_@@_scale_y_fp {#3}
+ #4 #1 { \l_@@_scale_x_fp } { \l_@@_scale_y_fp }
+ \dim_set:Nn \l_@@_internal_dim
+ { \coffin_ht:N #1 + \coffin_dp:N #1 }
+ \dim_set:Nn \l_@@_scaled_total_height_dim
+ { \fp_abs:n { \l_@@_scale_y_fp } \l_@@_internal_dim }
+ \dim_set:Nn \l_@@_scaled_width_dim
+ { -\fp_abs:n { \l_@@_scale_x_fp } \coffin_wd:N #1 }
+ \@@_resize_common:NnnN #1
+ { \l_@@_scaled_width_dim } { \l_@@_scaled_total_height_dim }
+ #5
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_scale_vector:nnNN}
+% This functions scales a vector from the origin using the pre-set scale
+% factors in $x$ and $y$. This is a much less complex operation
+% than rotation, and as a result the code is a lot clearer.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scale_vector:nnNN #1#2#3#4
+ {
+ \dim_set:Nn #3
+ { \fp_to_dim:n { \dim_to_fp:n {#1} * \l_@@_scale_x_fp } }
+ \dim_set:Nn #4
+ { \fp_to_dim:n { \dim_to_fp:n {#2} * \l_@@_scale_y_fp } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_scale_corner:Nnnn}
+% \begin{macro}{\@@_scale_pole:Nnnnnn}
+% Scaling both corners and poles is a simple calculation using the
+% preceding vector scaling.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scale_corner:Nnnn #1#2#3#4
+ {
+ \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+ \prop_put:Nnx \l_@@_corners_prop {#2}
+ { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
+ }
+\cs_new_protected:Npn \@@_scale_pole:Nnnnnn #1#2#3#4#5#6
+ {
+ \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+ \prop_put:Nnx \l_@@_poles_prop {#2}
+ {
+ { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
+ {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_x_shift_corner:Nnnn}
+% \begin{macro}{\@@_x_shift_pole:Nnnnnn}
+% These functions correct for the $x$ displacement that takes
+% place with a negative horizontal scaling.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_x_shift_corner:Nnnn #1#2#3#4
+ {
+ \prop_put:Nnx \l_@@_corners_prop {#2}
+ {
+ { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
+ }
+ }
+\cs_new_protected:Npn \@@_x_shift_pole:Nnnnnn #1#2#3#4#5#6
+ {
+ \prop_put:Nnx \l_@@_poles_prop {#2}
+ {
+ { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
+ {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Aligning and typesetting of coffins}
%
% \begin{macro}
@@ -1698,6 +2270,14 @@
% \end{macrocode}
% \end{variable}
%
+% \begin{macro}{\@@_color:n}
+% Calls \tn{color}, and otherwise does nothing if \tn{color} is not defined.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_color:n #1
+ { \cs_if_exist:NT \color { \color {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\coffin_mark_handle:Nnnn, \coffin_mark_handle:cnnn}
% \begin{macro}{\@@_mark_handle_aux:nnnnNnn}
% Marking a single handle is relatively easy. The standard attachment
@@ -1714,7 +2294,7 @@
\hbox:n { \tex_vrule:D width 1pt height 1pt \scan_stop: } % TODO
%</initex>
%<*package>
- \color {#4}
+ \@@_color:n {#4}
\rule { 1pt } { 1pt }
%</package>
}
@@ -1726,7 +2306,7 @@
% TODO
%</initex>
%<*package>
- \color {#4}
+ \@@_color:n {#4}
%</package>
\l_@@_display_font_tl
( \tl_to_str:n { #2 , #3 } )
@@ -1783,7 +2363,7 @@
\hbox:n { \tex_vrule:D width 1pt height 1pt \scan_stop: } % TODO
%</initex>
%<*package>
- \color {#2}
+ \@@_color:n {#2}
\rule { 1pt } { 1pt }
%</package>
}
@@ -1829,7 +2409,7 @@
% TODO
%</initex>
%<*package>
- \color {#6}
+ \@@_color:n {#6}
%</package>
\l_@@_display_font_tl
( \tl_to_str:n { #1 , ##1 } )
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx
index 738be5b26d6..42d6b15e1bb 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
index 23cf8f317f2..e0a930b68bd 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -54,6 +54,31 @@
% A few commands have had to be deprecated over the years. This module
% defines deprecated and deleted commands to produce an error.
%
+% The life of a deprecated command has several stages.
+% \begin{itemize}
+% \item When we decide it should be eventually removed the command's
+% definition is put in this file \pkg{l3deprecation.dtx} and the name
+% of the command is added to the list in \pkg{l3obsolete.txt}. The
+% command remains defined by default for $12$ or more months,
+% typically until the end of a year. During that time, if \pkg{expl3}
+% is loaded with any of the options \texttt{check-declarations} or
+% \texttt{log-functions} or \texttt{enable-debug} typically used in
+% package test files, the command will produce a warning.
+% \item Then by default the command produces an error for all users,
+% which can be suppressed for $6$ months through the option
+% \texttt{undo-recent-deprecations}.
+% \item After this $6$-month grace period, the command irreversibly
+% produces an error. Its original definition can then be removed from
+% the sources, leaving only the error definition. In
+% \pkg{l3obsolete.txt} its name is moved from the \enquote{Deprecated
+% functions and variables} list to the \enquote{Removed functions and
+% variables} list.
+% \end{itemize}
+% Package authors are encouraged to have a test file with
+% \cs{debug_on:n} |{deprecation}|, which makes commands at all stages of
+% this list into errors. This helps detect uses of deprecated commands
+% before user complain.
+%
% \end{documentation}
%
% \begin{implementation}
@@ -68,6 +93,238 @@
%<@@=deprecation>
% \end{macrocode}
%
+% \subsection{Helpers and variables}
+%
+% \begin{variable}{\l_@@_grace_period_bool}
+% This is set to \texttt{true} when the deprecated command that is
+% being defined is in its grace period, meaning between the time it
+% becomes an error by default and the time $6$~months later where even
+% \texttt{undo-recent-deprecations} stops restoring it.
+% \begin{macrocode}
+\bool_new:N \l_@@_grace_period_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_date_compare:nNnTF, \@@_date_compare_aux:w}
+% Expects |#1| and |#3| to be dates in the format YYYY-MM-DD (but
+% accepts YYYY or YYYY-MM too, filling in zeros for the missing data).
+% Compares them using |#2| (one of |<|, |=|, |>|).
+% \begin{macrocode}
+\cs_new:Npn \@@_date_compare:nNnTF #1#2#3
+ { \@@_date_compare_aux:w #1 -0-0- \q_mark #2 #3 -0-0- \q_stop }
+\cs_new:Npn \@@_date_compare_aux:w
+ #1 - #2 - #3 - #4 \q_mark #5 #6 - #7 - #8 - #9 \q_stop
+ {
+ \int_compare:nNnTF {#1} = {#6}
+ {
+ \int_compare:nNnTF {#2} = {#7}
+ { \int_compare:nNnTF {#3} #5 {#8} }
+ { \int_compare:nNnTF {#2} #5 {#7} }
+ }
+ { \int_compare:nNnTF {#1} #5 {#6} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_not_yet_deprecated:nTF, \@@_minus_six_months:w}
+% Receives a deprecation \meta{date} and runs the \texttt{true}
+% (\texttt{false}) branch if the \pkg{expl3} date is earlier (later)
+% than \meta{date}. If \texttt{undo-recent-deprecations} is used we
+% subtract $6$ months to the \pkg{expl3} date (equivalently add $6$
+% months to the \meta{date}). In addition, if the \pkg{expl3} date is
+% between \meta{date} and \meta{date} plus $6$ months,
+% \cs{l_@@_grace_period_bool} is set to \texttt{true}, otherwise
+% \texttt{false}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_not_yet_deprecated:nTF #1
+ {
+ \bool_set_false:N \l_@@_grace_period_bool
+ \exp_args:No \@@_date_compare:nNnTF { \ExplLoaderFileDate } < {#1}
+ { \use_i:nn }
+ {
+ \exp_args:Nf \@@_date_compare:nNnTF
+ {
+ \exp_after:wN \@@_minus_six_months:w
+ \ExplLoaderFileDate -0-0- \q_stop
+ } < {#1}
+ {
+ \bool_set_true:N \l_@@_grace_period_bool
+ \bool_if:NTF \l@expl@undo@recent@deprecations@bool
+ }
+ { \use_ii:nn }
+ }
+ }
+\cs_new:Npn \@@_minus_six_months:w #1 - #2 - #3 - #4 \q_stop
+ {
+ \int_compare:nNnTF {#2} > 6
+ { #1 - \int_eval:n { #2 - 6 } - #3 }
+ { \int_eval:n { #1 - 1 } - \int_eval:n { #2 + 6 } - #3 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Patching definitions to deprecate}
+%
+% \begin{quote}
+% \cs{__kernel_patch_deprecation:nnNNpn} \Arg{date} \Arg{replacement}
+% \meta{definition} \meta{function} \meta{parameters} \Arg{code}
+% \end{quote}
+% defines the \meta{function} to produce a warning and run its
+% \meta{code}, or to produce an error and not run any \meta{code},
+% depending on the \pkg{expl3} date.
+% \begin{itemize}
+% \item If the \pkg{expl3} date is less than the \meta{date} (plus
+% $6$~months in case \texttt{undo-recent-deprecations} is used) then
+% we define the \meta{function} to produce a warning and run its code.
+% The warning is actually suppressed in two cases:
+% \begin{itemize}
+% \item if neither \texttt{undo-recent-deprecations} nor
+% \texttt{enable-debug} are in effect we may be in an end-user's
+% document so it is suppressed;
+% \item if the command is expandable then we cannot produce a warning.
+% \end{itemize}
+% \item Otherwise, we define the \meta{function} to produce an error.
+% \end{itemize}
+% In both cases we additionally make \cs{debug_on:n} |{deprecation}|
+% turn the \meta{function} into an \tn{outer} error, and
+% \cs{debug_off:n} |{deprecation}| restore whatever the behaviour was
+% without \cs{debug_on:n} |{deprecation}|.
+%
+% In later sections we use the \pkg{l3doc} key \texttt{deprecated} with
+% a date equal to that \meta{date} plus $6$~months, so that \pkg{l3doc}
+% will complain if we forget to remove the stale \meta{parameters} and
+% \Arg{code}.
+%
+% In the explanations below, \meta{definition} \meta{function}
+% \meta{parameters} \Arg{code} or assignments that only differ in the
+% scope of the \meta{definition} will be called \enquote{the standard
+% definition}.
+%
+% \begin{macro}
+% {
+% \__kernel_patch_deprecation:nnNNpn, \@@_patch_aux:nnNNnn,
+% \@@_warn_once:nnNnn,
+% \@@_patch_aux:Nn,
+% \@@_just_error:nnNN
+% }
+% (The parameter text is grabbed using |#5#|.) The arguments of
+% \cs{__kernel_deprecation_code:nn} are run upon \cs{debug_on:n}
+% |{deprecation}| and \cs{debug_off:n} |{deprecation}|, respectively.
+% In both scenarios we the \meta{function} may be \tn{outer} so we
+% undefine it with \cs{tex_let:D} before redefining it, with
+% \cs{__kernel_deprecation_error:Nnn} or with some code added shortly.
+%
+% Then check the date (taking into account
+% \texttt{undo-recent-deprecations}) to see if the command should be
+% deprecated right away (\texttt{false} branch of
+% \cs{@@_not_yet_deprecated:nTF}), in which case
+% \cs{@@_just_error:nnNN} makes \meta{function} into an error (not
+% \tn{outer}), ignoring its \meta{parameters} and \meta{code}
+% completely.
+%
+% Otherwise distinguish cases where we should give a warning from
+% those where we shouldn't: warnings can only happen for protected
+% commands, and we only want them if either
+% \texttt{undo-recent-deprecations} or \texttt{enable-debug} is in
+% force, not for standard users.
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2#3#4#5#
+ { \@@_patch_aux:nnNNnn {#1} {#2} #3 #4 {#5} }
+\cs_new_protected:Npn \@@_patch_aux:nnNNnn #1#2#3#4#5#6
+ {
+ \__kernel_deprecation_code:nn
+ {
+ \tex_let:D #4 \scan_stop:
+ \__kernel_deprecation_error:Nnn #4 {#2} {#1}
+ }
+ { \tex_let:D #4 \scan_stop: }
+ \@@_not_yet_deprecated:nTF {#1}
+ {
+ \bool_if:nTF
+ {
+ \cs_if_eq_p:NN #3 \cs_new_protected:Npn &&
+ \__kernel_if_debug:TF
+ { \c_true_bool } { \l@expl@undo@recent@deprecations@bool }
+ }
+ { \@@_warn_once:nnNnn {#1} {#2} #4 {#5} {#6} }
+ { \@@_patch_aux:Nn #3 { #4 #5 {#6} } }
+ }
+ { \@@_just_error:nnNN {#1} {#2} #3 #4 }
+ }
+% \end{macrocode}
+% In case we want a warning, the \meta{function} is defined to produce
+% such a warning without grabbing any argument, then redefine itself
+% to the standard definition that the \meta{function} should have,
+% with arguments, and call that definition. The \texttt{x}-type
+% expansion and \cs{exp_not:n} avoid needing to double the~|#|, which
+% we could not do anyways. We then deal with the code for
+% \cs{debug_off:n} |{deprecation}|: presumably someone doing that does
+% not need the warning so we simply do the standard definition.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_warn_once:nnNnn #1#2#3#4#5
+ {
+ \cs_new_protected:Npx #3
+ {
+ \__kernel_if_debug:TF
+ {
+ \exp_not:N \__kernel_msg_warning:nnxxx
+ { kernel } { deprecated-command }
+ {#1}
+ { \token_to_str:N #3 }
+ { \tl_to_str:n {#2} }
+ }
+ { }
+ \exp_not:n { \cs_gset_protected:Npn #3 #4 {#5} }
+ \exp_not:N #3
+ }
+ \__kernel_deprecation_code:nn { }
+ { \cs_set_protected:Npn #3 #4 {#5} }
+ }
+% \end{macrocode}
+% In case we want neither warning nor error, the \meta{function} is
+% given its standard definition. Here |#1| is \cs{cs_new:Npn} or
+% \cs{cs_new_protected:Npn}) and |#2| is \meta{function}
+% \meta{parameters} \Arg{code}, so |#1#2| performs the assignment.
+% For \cs{debug_off:n} |{deprecation}| we want to use the same
+% assignment but with a different scope, hence the \cs{cs_if_eq:NNTF}
+% test.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_aux:Nn #1#2
+ {
+ #1 #2
+ \cs_if_eq:NNTF #1 \cs_new_protected:Npn
+ { \__kernel_deprecation_code:nn { } { \cs_set_protected:Npn #2 } }
+ { \__kernel_deprecation_code:nn { } { \cs_set:Npn #2 } }
+ }
+% \end{macrocode}
+% Finally, if we want an error we reuse the same \cs{@@_patch_aux:Nn}
+% as the previous case. Indeed, we want \cs{debug_off:n}
+% |{deprecation}| to make the \meta{function} into an error, just like
+% it is by default. The error is expandable or not, and the last
+% argument of the error message is empty or is \texttt{grace} to
+% denote the case where we are in the $6$~month grace period, in which
+% case the error message is more detailed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_just_error:nnNN #1#2#3#4
+ {
+ \exp_args:NNx \@@_patch_aux:Nn #3
+ {
+ \exp_not:N #4
+ {
+ \cs_if_eq:NNTF #3 \cs_new_protected:Npn
+ { \exp_not:N \__kernel_msg_error:nnnnnn }
+ { \exp_not:N \__kernel_msg_expandable_error:nnnnnn }
+ { kernel } { deprecated-command }
+ {#1}
+ { \token_to_str:N #4 }
+ { \tl_to_str:n {#2} }
+ { \bool_if:NT \l_@@_grace_period_bool { grace } }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\__kernel_deprecation_error:Nnn}
% The \tn{outer} definition here ensures the command cannot appear
% in an argument. Use this auxiliary on all commands that have been
@@ -85,112 +342,118 @@
{ \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} }
}
}
-\__kernel_deprecation_error:Nnn \box_resize:cnn
- { \box_resize_to_wd_and_ht_plus_dp:cnn } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \box_resize:Nnn
- { \box_resize_to_wd_and_ht_plus_dp:Nnn } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \box_use_clear:c
- { \box_use_drop:c } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \box_use_clear:N
- { \box_use_drop:N } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \c_job_name_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\__kernel_msg_new:nnn { kernel } { deprecated-command }
+ {
+ '#2'~deprecated~on~#1.
+ \tl_if_empty:nF {#3} { ~Use~'#3'. }
+ \str_if_eq:nnT {#4} { grace }
+ {
+ \c_space_tl
+ For~6~months~after~that~date~one~can~restore~a~deprecated~
+ command~by~loading~the~expl3~package~with~the~option~
+ 'undo-recent-deprecations'.
+ }
+ }
+% \end{macrocode}
+%
+% \subsection{Removed functions}
+%
+% \begin{macro}{\@@_old_protected:Nnn, \@@_old:Nnn}
+% Short-hands for old commands whose definition does not matter
+% anymore, i.e., commands past the grace period.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_old_protected:Nnn #1#2#3
+ {
+ \__kernel_patch_deprecation:nnNNpn {#3} {#2}
+ \cs_new_protected:Npn #1 { }
+ }
+\cs_new_protected:Npn \@@_old:Nnn #1#2#3
+ {
+ \__kernel_patch_deprecation:nnNNpn {#3} {#2}
+ \cs_new:Npn #1 { }
+ }
+\@@_old:Nnn \c_job_name_tl
{ \c_sys_jobname_str } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \c_minus_one
- { -1 } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \dim_case:nnn
+\@@_old:Nnn \dim_case:nnn
{ \dim_case:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \file_add_path:nN
- { \file_get_full_name:nN } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \file_if_exist_input:nT
+\@@_old_protected:Nnn \file_if_exist_input:nT
{ \file_if_exist:nT and~ \file_input:n } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \file_if_exist_input:nTF
+\@@_old_protected:Nnn \file_if_exist_input:nTF
{ \file_if_exist:nT and~ \file_input:n } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \file_list:
- { \file_log_list: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \file_path_include:n
- { \seq_put_right:Nn \l_file_search_path_seq } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \file_path_remove:n
- { \seq_remove_all:Nn \l_file_search_path_seq } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \g_file_current_name_tl
- { \g_file_current_name_str } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \int_case:nnn
+\@@_old:Nnn \int_case:nnn
{ \int_case:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \int_from_binary:n
+\@@_old:Nnn \int_from_binary:n
{ \int_from_bin:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_from_hexadecimal:n
+\@@_old:Nnn \int_from_hexadecimal:n
{ \int_from_hex:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_from_octal:n
+\@@_old:Nnn \int_from_octal:n
{ \int_from_oct:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_to_binary:n
+\@@_old:Nnn \int_to_binary:n
{ \int_to_bin:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_to_hexadecimal:n
+\@@_old:Nnn \int_to_hexadecimal:n
{ \int_to_hex:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_to_octal:n
+\@@_old:Nnn \int_to_octal:n
{ \int_to_oct:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \ior_get_str:NN
+\@@_old_protected:Nnn \ior_get_str:NN
{ \ior_str_get:NN } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \ior_list_streams:
- { \ior_show_list: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \ior_log_streams:
- { \ior_log_list: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine_p:
+\@@_old:Nnn \luatex_if_engine_p:
{ \sys_if_engine_luatex_p: } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine:F
+\@@_old:Nnn \luatex_if_engine:F
{ \sys_if_engine_luatex:F } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine:T
+\@@_old:Nnn \luatex_if_engine:T
{ \sys_if_engine_luatex:T } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine:TF
+\@@_old:Nnn \luatex_if_engine:TF
{ \sys_if_engine_luatex:TF } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine_p:
+\@@_old:Nnn \pdftex_if_engine_p:
{ \sys_if_engine_pdftex_p: } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine:F
+\@@_old:Nnn \pdftex_if_engine:F
{ \sys_if_engine_pdftex:F } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine:T
+\@@_old:Nnn \pdftex_if_engine:T
{ \sys_if_engine_pdftex:T } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine:TF
+\@@_old:Nnn \pdftex_if_engine:TF
{ \sys_if_engine_pdftex:TF } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \prop_get:cn
+\@@_old:Nnn \prop_get:cn
{ \prop_item:cn } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \prop_get:Nn
+\@@_old:Nnn \prop_get:Nn
{ \prop_item:Nn } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \quark_if_recursion_tail_break:N
+\@@_old:Nnn \quark_if_recursion_tail_break:N
{ } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \quark_if_recursion_tail_break:n
+\@@_old:Nnn \quark_if_recursion_tail_break:n
{ } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \scan_align_safe_stop:
+\@@_old:Nnn \scan_align_safe_stop:
{ protected~commands } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \sort_ordered:
- { \sort_return_same: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \sort_reversed:
- { \sort_return_swapped: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \str_case:nnn
+\@@_old:Nnn \str_case:nnn
{ \str_case:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \str_case:onn
+\@@_old:Nnn \str_case:onn
{ \str_case:onF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \str_case_x:nnn
+\@@_old:Nnn \str_case_x:nnn
{ \str_case_e:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \tl_case:cnn
+\@@_old:Nnn \tl_case:cnn
{ \tl_case:cnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \tl_case:Nnn
+\@@_old:Nnn \tl_case:Nnn
{ \tl_case:NnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \tl_to_lowercase:n
+\@@_old_protected:Nnn \tl_to_lowercase:n
{ \tex_lowercase:D } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \tl_to_uppercase:n
+\@@_old_protected:Nnn \tl_to_uppercase:n
{ \tex_uppercase:D } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \token_new:Nn
- { \cs_new_eq:NN } { 2018-12-29 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine_p:
+\@@_old:Nnn \xetex_if_engine_p:
{ \sys_if_engine_xetex_p: } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine:F
+\@@_old:Nnn \xetex_if_engine:F
{ \sys_if_engine_xetex:F } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine:T
+\@@_old:Nnn \xetex_if_engine:T
{ \sys_if_engine_xetex:T } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine:TF
+\@@_old:Nnn \xetex_if_engine:TF
{ \sys_if_engine_xetex:TF } { 2017-01-01 }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[deprecated = 2019-12-31]{\etex_beginL:D}
+% \subsection{Deprecated primitives}
+%
+% \begin{macro}[deprecated = 2020-07-01]{\etex_beginL:D}
% \begin{macro}{\@@_primitive:NN, \@@_primitive:w}
% We renamed all primitives to \cs[no-index]{tex_\ldots{}:D} so all
% others are deprecated. In \pkg{l3names}, \cs{__kernel_primitives:}
@@ -229,7 +492,7 @@
\@@_primitive:w { \cs_to_str:N #2 }
}
}
- { 2019-12-31 }
+ { 2020-01-01 }
}
\__kernel_primitives:
}
@@ -244,15 +507,560 @@
{
\tex_let:D #2 #1
\cs_if_exist:cT { tex_ \cs_to_str:N #1 :D }
+ { \cs_set_eq:Nc #2 { tex_ \cs_to_str:N #1 :D } }
+ }
+ \__kernel_primitives:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3box} functions}
+%
+% \begin{macro}[deprecated = 2019-07-01]
+% {\box_resize:Nnn, \box_resize:cnn, \box_use_clear:N, \box_use_clear:c}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn
+ { 2019-01-01 } { \box_resize_to_wd_and_ht_plus_dp:Nnn }
+\cs_new_protected:Npn \box_resize:Nnn
+ { \box_resize_to_wd_and_ht_plus_dp:Nnn }
+\__kernel_patch_deprecation:nnNNpn
+ { 2019-01-01 } { \box_resize_to_wd_and_ht_plus_dp:cnn }
+\cs_new_protected:Npn \box_resize:cnn
+ { \box_resize_to_wd_and_ht_plus_dp:cnn }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \box_use_drop:N }
+\cs_new_protected:Npn \box_use_clear:N { \box_use_drop:N }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \box_use_drop:c }
+\cs_new_protected:Npn \box_use_clear:c { \box_use_drop:c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2021-07-01]
+% {
+% \box_set_eq_clear:NN, \box_set_eq_clear:cN,
+% \box_set_eq_clear:Nc, \box_set_eq_clear:cc
+% }
+% \begin{macro}[deprecated = 2021-07-01]
+% {
+% \box_gset_eq_clear:NN, \box_gset_eq_clear:cN,
+% \box_gset_eq_clear:Nc, \box_gset_eq_clear:cc
+% }
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \box_set_eq_drop:N }
+\cs_new_protected:Npn \box_set_eq_clear:NN #1#2
+ { \tex_setbox:D #1 \tex_box:D #2 }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \box_gset_eq_drop:N }
+\cs_new_protected:Npn \box_gset_eq_clear:NN #1#2
+ { \tex_global:D \tex_setbox:D #1 \tex_box:D #2 }
+\cs_generate_variant:Nn \box_set_eq_clear:NN { c , Nc , cc }
+\cs_generate_variant:Nn \box_gset_eq_clear:NN { c , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2021-07-01]{\hbox_unpack_clear:N, \hbox_unpack_clear:c}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \hbox_unpack_drop:N }
+\cs_new_protected:Npn \hbox_unpack_clear:N
+ { \hbox_unpack_drop:N }
+\cs_generate_variant:Nn \hbox_unpack_clear:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2021-07-01]{\vbox_unpack_clear:N, \vbox_unpack_clear:c}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \vbox_unpack_drop:N }
+\cs_new_protected:Npn \vbox_unpack_clear:N
+ { \vbox_unpack_drop:N }
+\cs_generate_variant:Nn \vbox_unpack_clear:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3file} functions}
+%
+% \begin{macrocode}
+%<@@=deprecation>
+% \end{macrocode}
+%
+% \begin{variable}[deprecated = 2019-07-01]{\g_file_current_name_tl}
+% Contrarily to most other deprecated commands this is a token list so
+% we have to resort to lower-level code.
+%
+% so we need to put code by hand in two token lists. We use
+% \cs{tex_def:D} directly because \cs{g_file_current_name_tl} is made
+% outer by \cs{debug_on:n} \texttt{\{deprecation\}}.
+% \begin{macrocode}
+\__kernel_deprecation_code:nn
+ {
+ \tex_let:D \g_file_current_name_tl \scan_stop:
+ \__kernel_deprecation_error:Nnn \g_file_current_name_tl
+ { \g_file_curr_name_str } { 2019-01-01 }
+ }
+ {
+ \tex_let:D \g_file_current_name_tl \scan_stop:
+ \cs_set_nopar:Npn \g_file_current_name_tl { \g_file_curr_name_str }
+ }
+\@@_not_yet_deprecated:nTF { 2019-01-01 }
+ {
+ \tl_new:N \g_file_current_name_tl
+ \tl_gset:Nn \g_file_current_name_tl { \g_file_curr_name_str }
+ }
+ {
+ \cs_gset_nopar:Npn \g_file_current_name_tl
+ {
+ \__kernel_msg_expandable_error:nnnnn
+ { kernel } { deprecated-command }
+ { 2019-01-01 } { \g_file_current_name_tl } { \g_file_curr_name_str }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%<@@=file>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\file_path_include:n, \file_path_remove:n}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn
+ { 2019-01-01 } { \seq_put_right:Nn \l_file_search_path_seq }
+\cs_new_protected:Npn \file_path_include:n #1
+ {
+ \__kernel_file_name_sanitize:nN {#1} \l_@@_full_name_str
+ \seq_if_in:NVF \l_file_search_path_seq \l_@@_full_name_str
+ { \seq_put_right:NV \l_file_search_path_seq \l_@@_full_name_str }
+ }
+\__kernel_patch_deprecation:nnNNpn
+ { 2019-01-01 } { \seq_remove_all:Nn \l_file_search_path_seq }
+\cs_new_protected:Npn \file_path_remove:n #1
+ {
+ \__kernel_file_name_sanitize:nN {#1} \l_@@_full_name_str
+ \seq_remove_all:NV \l_file_search_path_seq \l_@@_full_name_str
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\file_add_path:nN}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \file_get_full_name:nN }
+\cs_new_protected:Npn \file_add_path:nN #1#2
+ {
+ \file_get_full_name:nN {#1} #2
+ \str_if_empty:NT #2
+ { \tl_set:Nn #2 { \q_no_value } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\file_list:}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \file_log_list: }
+\cs_new_protected:Npn \file_list: { \file_log_list: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[added = 2014-08-22, updated = 2015-08-01, deprecated = 2019-07-01]
+% {\ior_list_streams:, \ior_log_streams:, \iow_list_streams:, \iow_log_streams:}
+% These got a more consistent naming.
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \ior_show_list: }
+\cs_new_protected:Npn \ior_list_streams: { \ior_show_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \ior_log_list: }
+\cs_new_protected:Npn \ior_log_streams: { \ior_log_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \iow_show_list: }
+\cs_new_protected:Npn \iow_list_streams: { \iow_show_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \iow_log_list: }
+\cs_new_protected:Npn \iow_log_streams: { \iow_log_list: }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3int} functions}
+%
+% \begin{macrocode}
+%<@@=deprecation>
+% \end{macrocode}
+%
+% \begin{variable}[deprecated = 2019-07-01]{\c_minus_one, \c_@@_minus_one}
+% In order to toggle definitions on and off locally we declare an
+% internal constant integer and copy it into \cs{c_minus_one}.
+% \begin{macrocode}
+\int_const:Nn \c_@@_minus_one { -1 }
+\__kernel_deprecation_code:nn
+ {
+ \tex_let:D \c_minus_one \scan_stop:
+ \__kernel_deprecation_error:Nnn \c_minus_one { -1 } { 2019-01-01 }
+ }
+ {
+ \tex_let:D \c_minus_one \scan_stop:
+ \cs_set_eq:NN \c_minus_one \c_@@_minus_one
+ }
+\@@_not_yet_deprecated:nTF { 2019-01-01 }
+ { \cs_new_eq:NN \c_minus_one \c_@@_minus_one }
+ {
+ \cs_gset_nopar:Npn \c_minus_one
+ {
+ \__kernel_msg_expandable_error:nnnnn
+ { kernel } { deprecated-command }
+ { 2019-01-01 } { \c_minus_one } { -1 }
+ \c_@@_minus_one
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%<@@=int>
+% \end{macrocode}
+%
+% \begin{variable}[deprecated = 2020-07-01]
+% {
+% \c_zero, \c_one, \c_two, \c_three, \c_four, \c_five, \c_six,
+% \c_seven, \c_eight, \c_nine, \c_ten, \c_eleven, \c_twelve,
+% \c_thirteen, \c_fourteen, \c_fifteen, \c_sixteen, \c_thirty_two,
+% \c_one_hundred, \c_two_hundred_fifty_five,
+% \c_two_hundred_fifty_six, \c_one_thousand, \c_ten_thousand,
+% }
+% \begin{macro}{\@@_deprecated_constants:nn}
+% Constants that are now deprecated. By default define them with
+% \cs{int_const:Nn}. To deprecate them call for instance
+% \cs{__kernel_deprecation_error:Nnn} \cs{c_zero} |{0}|
+% |{2020-01-01}|. To redefine them (locally), use
+% \cs{@@_constdef:Nw}, with an \cs{exp_not:N} construction because the
+% constants themselves are outer at that point.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_deprecated_constants:nn #1#2
+ {
+ #1 \c_zero { 0 } #2
+ #1 \c_one { 1 } #2
+ #1 \c_two { 2 } #2
+ #1 \c_three { 3 } #2
+ #1 \c_four { 4 } #2
+ #1 \c_five { 5 } #2
+ #1 \c_six { 6 } #2
+ #1 \c_seven { 7 } #2
+ #1 \c_eight { 8 } #2
+ #1 \c_nine { 9 } #2
+ #1 \c_ten { 10 } #2
+ #1 \c_eleven { 11 } #2
+ #1 \c_twelve { 12 } #2
+ #1 \c_thirteen { 13 } #2
+ #1 \c_fourteen { 14 } #2
+ #1 \c_fifteen { 15 } #2
+ #1 \c_sixteen { 16 } #2
+ #1 \c_thirty_two { 32 } #2
+ #1 \c_one_hundred { 100 } #2
+ #1 \c_two_hundred_fifty_five { 255 } #2
+ #1 \c_two_hundred_fifty_six { 256 } #2
+ #1 \c_one_thousand { 1000 } #2
+ #1 \c_ten_thousand { 10000 } #2
+ }
+\@@_deprecated_constants:nn { \int_const:Nn } { }
+\__kernel_deprecation_code:nn
+ {
+ \@@_deprecated_constants:nn
+ { \exp_after:wN \__kernel_deprecation_error:Nnn \exp_not:N }
+ { { 2020-01-01 } }
+ }
+ {
+ \@@_deprecated_constants:nn
+ {
+ \exp_after:wN \use:nnn
+ \exp_after:wN \@@_constdef:Nw \exp_not:N
+ }
+ { \exp_stop_f: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{variable}
+%
+% \begin{macro}[deprecated = 2020-07-01]{\@@_value:w}
+% Made public.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_value:w \int_value:w
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3luatex} functions}
+%
+% \begin{macrocode}
+%<@@=lua>
+% \end{macrocode}
+%
+% \begin{macro}[EXP, deprecated = 2020-07-01]{\lua_now_x:n, \lua_escape_x:n}
+% \begin{macro}[deprecated = 2020-07-01]{\lua_shipout_x:n}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_now:e }
+\cs_new:Npn \lua_now_x:n #1 { \@@_now:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_escape:e }
+\cs_new:Npn \lua_escape_x:n #1 { \@@_escape:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_shipout_e:n }
+\cs_new_protected:Npn \lua_shipout_x:n #1 { \@@_shipout:n {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3msg} functions}
+%
+% \begin{macrocode}
+%<@@=msg>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated = 2020-07-01]{\msg_log:n, \msg_term:n}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \iow_log:n }
+\cs_new_protected:Npn \msg_log:n #1
+ {
+ \iow_log:n { ................................................. }
+ \iow_wrap:nnnN { . ~ #1} { . ~ } { } \iow_log:n
+ \iow_log:n { ................................................. }
+ }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \iow_term:n }
+\cs_new_protected:Npn \msg_term:n #1
+ {
+ \iow_term:n { ************************************************* }
+ \iow_wrap:nnnN { * ~ #1} { * ~ } { } \iow_term:n
+ \iow_term:n { ************************************************* }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2020-07-01]{\msg_interrupt:nnn}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { [Defined~error~message] }
+\cs_new_protected:Npn \msg_interrupt:nnn #1#2#3
+ {
+ \tl_if_empty:nTF {#3}
+ {
+ \@@_old_interrupt_wrap:nn { \\ \c_@@_no_info_text_tl }
+ {#1 \\\\ #2 \\\\ \c_@@_continue_text_tl }
+ }
+ {
+ \@@_old_interrupt_wrap:nn { \\ #3 }
+ {#1 \\\\ #2 \\\\ \c_@@_help_text_tl }
+ }
+ }
+\cs_new_protected:Npn \@@_old_interrupt_wrap:nn #1#2
+ {
+ \iow_wrap:nnnN {#1} { | ~ } { } \@@_old_interrupt_more_text:n
+ \iow_wrap:nnnN {#2} { ! ~ } { } \@@_old_interrupt_text:n
+ }
+\cs_new_protected:Npn \@@_old_interrupt_more_text:n #1
+ {
+ \exp_args:Nx \tex_errhelp:D
+ {
+ |'''''''''''''''''''''''''''''''''''''''''''''''
+ #1 \iow_newline:
+ |...............................................
+ }
+ }
+\group_begin:
+ \char_set_lccode:nn {`\{} {`\ }
+ \char_set_lccode:nn {`\}} {`\ }
+ \char_set_lccode:nn {`\&} {`\!}
+ \char_set_catcode_active:N \&
+\tex_lowercase:D
+ {
+ \group_end:
+ \cs_new_protected:Npn \@@_old_interrupt_text:n #1
+ {
+ \iow_term:x
{
- \exp_args:NNc \cs_set_eq:NN #2
- { tex_ \cs_to_str:N #1 :D }
+ \iow_newline:
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ \iow_newline:
+ !
+ }
+ \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J }
+ {
+ \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 }
+ {
+ \group_begin:
+ \cs_set_protected:Npn &
+ {
+ \tex_errmessage:D
+ {
+ #1
+ \use_none:n
+ { ............................................ }
+ }
+ }
+ \exp_after:wN
+ \group_end:
+ &
+ }
}
}
- \__kernel_primitives:
}
% \end{macrocode}
% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3prg} functions}
+%
+% \begin{macrocode}
+%<@@=prg>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated = 2020-07-01]
+% {
+% \@@_break_point:Nn,
+% \@@_break_point:,
+% \@@_map_break:Nn,
+% \@@_break:,
+% \@@_break:n
+% }
+% Made public, but used by a few third-parties. It's not possible to
+% perfectly support a mixture of \cs{@@_map_break:Nn} and
+% \cs{prg_map_break:Nn} because they use different delimiters. The
+% following code only breaks if someone tries to break from two
+% \enquote{old-style} \cs{@@_map_break:Nn} \ldots{}
+% \cs{@@_break_point:Nn} mappings in one go. Basically, the
+% \cs{@@_map_break:Nn} converts a single \cs{@@_break_point:Nn} to
+% \cs{prg_break_point:Nn}, and that delimiter had better be the right
+% one. Then we call \cs{prg_map_break:Nn} which may end up breaking
+% intermediate looks in the (unbraced) argument |#1|. It is essential
+% to define the |break_point| functions before the corresponding
+% |break| functions: otherwise \cs{debug_on:n} |{deprecation}|
+% \cs{debug_off:n} |{deprecation}| would break when trying to restore
+% the definitions because they would involve deprecated commands whose
+% definition has not yet been restored.
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break_point:Nn }
+\cs_new:Npn \@@_break_point:Nn { \prg_break_point:Nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break_point: }
+\cs_new:Npn \@@_break_point: { \prg_break_point: }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_map_break:Nn }
+\cs_new:Npn \@@_map_break:Nn #1 \@@_break_point:Nn
+ { \prg_map_break:Nn #1 \prg_break_point:Nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break: }
+\cs_new:Npn \@@_break: #1 \@@_break_point: { }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break:n }
+\cs_new:Npn \@@_break:n #1#2 \@@_break_point: {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3sort} functions}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\sort_ordered:, \sort_reversed:}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \sort_return_same: }
+\cs_new_protected:Npn \sort_ordered: { \sort_return_same: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \sort_return_swapped: }
+\cs_new_protected:Npn \sort_reversed: { \sort_return_swapped: }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3str} functions}
+%
+% \begin{macro}[EXP, deprecated = 2020-07-01, noTF]{\str_case_x:nn}
+% \begin{macro}[EXP, deprecated = 2020-07-01, pTF]{\str_if_eq_x:nn}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nn }
+\cs_new:Npn \str_case_x:nn { \str_case_e:nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nnT }
+\cs_new:Npn \str_case_x:nnT { \str_case_e:nnT }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nnF }
+\cs_new:Npn \str_case_x:nnF { \str_case_e:nnF }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nnTF }
+\cs_new:Npn \str_case_x:nnTF { \str_case_e:nnTF }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq_p:ee }
+\cs_new:Npn \str_if_eq_x_p:nn { \str_if_eq_p:ee }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq:eeT }
+\cs_new:Npn \str_if_eq_x:nnT { \str_if_eq:eeT }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq:eeF }
+\cs_new:Npn \str_if_eq_x:nnF { \str_if_eq:eeF }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq:eeTF }
+\cs_new:Npn \str_if_eq_x:nnTF { \str_if_eq:eeTF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Deprecated \pkg{l3tl} functions}
+%
+% \begin{macrocode}
+%<@@=tl>
+% \end{macrocode}
+%
+% \begin{macro}[deprecated = 2021-07-01]
+% {
+% \tl_set_from_file:Nnn, \tl_set_from_file:cnn,
+% \tl_gset_from_file:Nnn, \tl_gset_from_file:cnn,
+% \tl_set_from_file_x:Nnn, \tl_set_from_file_x:cnn,
+% \tl_gset_from_file_x:Nnn, \tl_gset_from_file_x:cnn
+% }
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_set_from_file:Nnn #1#2#3
+ { \file_get:nnN {#3} {#2} #1 }
+\cs_generate_variant:Nn \tl_set_from_file:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_gset_from_file:Nnn #1#2#3
+ {
+ \group_begin:
+ \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
+ \tl_gset_eq:NN #1 \l_@@_internal_a_tl
+ \group_end:
+ }
+\cs_generate_variant:Nn \tl_gset_from_file:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_set_from_file_x:Nnn #1#2#3
+ {
+ \group_begin:
+ \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
+ #2 \scan_stop:
+ \tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl }
+ \exp_args:NNNo \group_end:
+ \tl_set:Nn #1 \l_@@_internal_a_tl
+ }
+\cs_generate_variant:Nn \tl_set_from_file_x:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_gset_from_file_x:Nnn #1#2#3
+ {
+ \group_begin:
+ \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
+ #2 \scan_stop:
+ \tl_gset:Nx #1 { \l_@@_internal_a_tl }
+ \group_end:
+ }
+\cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3tl-analysis} functions}
+%
+% \begin{macro}[deprecated = 2020-07-01]
+% {\tl_show_analysis:N, \tl_show_analysis:n}
+% Simple renames.
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \tl_analysis_show:N }
+\cs_new_protected:Npn \tl_show_analysis:N { \tl_analysis_show:N }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \tl_analysis_show:n }
+\cs_new_protected:Npn \tl_show_analysis:n { \tl_analysis_show:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3token} functions}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\token_new:Nn}
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \cs_new_eq:NN }
+\cs_new_protected:Npn \token_new:Nn #1#2 { \cs_new_eq:NN #1 #2 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, deprecated = 2021-07-01]
+% {
+% \token_get_prefix_spec:N,
+% \token_get_arg_spec:N,
+% \token_get_replacement_spec:N
+% }
+% \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_prefix_spec:N }
+\cs_new:Npn \token_get_prefix_spec:N { \cs_prefix_spec:N }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_argument_spec:N }
+\cs_new:Npn \token_get_arg_spec:N { \cs_argument_spec:N }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_replacement_spec:N }
+\cs_new:Npn \token_get_replacement_spec:N { \cs_replacement_spec:N }
+% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
index 8cc7655d4dd..e6fdc679742 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
@@ -79,7 +79,7 @@ and all files in that bundle must be distributed together.
%
% \title{The \cls{l3doc} class}
% \author{\Team}
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
% \maketitle
% \tableofcontents
%
@@ -334,6 +334,17 @@ and all files in that bundle must be distributed together.
% class names, respectively.
% \end{function}
%
+% \begin{function}{\NB, \NOTE}
+% \begin{syntax}
+% \cs{NB} \marg{tag} \marg{comments}
+% \verb|\begin{NOTE}| \marg{tag}
+% \qquad\meta{comments}
+% \verb|\end{NOTE}|
+% \end{syntax}
+% Make notes in the source that are not typeset by default. When the \verb|show-notes|
+% class option is active, the comments are typeset in a detokenized and verbatim mode, respectively.
+% \end{function}
+%
% \subsection{Describing functions in the documentation}
%
% \DescribeEnv{function}
@@ -694,6 +705,7 @@ and all files in that bundle must be distributed together.
% \g_@@_checkfunc_bool,
% \g_@@_checktest_bool,
% \g_@@_cs_break_bool,
+% \g_@@_show_notes_bool,
% \g_@@_kernel_bool
% }
% Information about package options.
@@ -703,6 +715,7 @@ and all files in that bundle must be distributed together.
\bool_new:N \g_@@_checktest_bool
\bool_new:N \g_@@_kernel_bool
\bool_new:N \g_@@_cs_break_bool
+\bool_new:N \g_@@_show_notes_bool
\bool_gset_true:N \g_@@_cs_break_bool
% \end{macrocode}
% \end{variable}
@@ -1430,6 +1443,13 @@ and all files in that bundle must be distributed together.
% \end{macrocode}
%
% \begin{macrocode}
+\DeclareOption { show-notes }
+ { \bool_gset_true:N \g_@@_show_notes_bool }
+\DeclareOption { hide-notes }
+ { \bool_gset_false:N \g_@@_show_notes_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
\DeclareOption* { \PassOptionsToClass { \CurrentOption } { article } }
\ExecuteOptions { full, kernel, nocheck, nochecktest, lm-default }
\PassOptionsToClass { a4paper } { article }
@@ -1885,6 +1905,7 @@ and all files in that bundle must be distributed together.
\NewDocumentCommand { \CodedocExplainEXP } { }
{
\raisebox{\baselineskip}[0pt][0pt]{\hypertarget{expstar}{}}%
+ \write \@auxout { \def \string \Codedoc@expstar { } }
\@@_typeset_exp:\ indicates~fully~expandable~functions,~which~
can~be~used~within~an~\texttt{x}-type~argument~(in~plain~
\TeX{}~terms,~inside~an~\cs{edef}),~as~well~as~within~an~
@@ -1893,6 +1914,7 @@ and all files in that bundle must be distributed together.
\NewDocumentCommand { \CodedocExplainREXP } { }
{
\raisebox{\baselineskip}[0pt][0pt]{\hypertarget{rexpstar}{}}%
+ \write \@auxout { \def \string \Codedoc@rexpstar { } }
\@@_typeset_rexp:\ indicates~
restricted~expandable~functions,~which~can~be~used~within~an~
\texttt{x}-type~argument~but~cannot~be~fully~expanded~within~an~
@@ -1901,6 +1923,7 @@ and all files in that bundle must be distributed together.
\NewDocumentCommand { \CodedocExplainTF } { }
{
\raisebox{\baselineskip}[0pt][0pt]{\hypertarget{explTF}{}}%
+ \write \@auxout { \def \string \Codedoc@explTF { } }
\@@_typeset_TF:\ indicates~conditional~(\texttt{if})~functions~
whose~variants~with~\texttt{T},~\texttt{F}~and~\texttt{TF}~
argument~specifiers~expect~different~
@@ -2062,18 +2085,30 @@ and all files in that bundle must be distributed together.
% to typeset conditionals and auxiliary functions.
% \begin{macrocode}
\cs_new_protected:Npn \@@_typeset_exp:
- { \hyperlink{expstar} {$\star$} }
+ {
+ \cs_if_exist:NTF \Codedoc@expstar
+ { \hyperlink { expstar } }
+ { \mbox }
+ {$\star$}
+ }
\cs_new_protected:Npn \@@_typeset_rexp:
- { \hyperlink{rexpstar} {\ding{73}} } % hollow star
+ {
+ \cs_if_exist:NTF \Codedoc@rexpstar
+ { \hyperlink { rexpstar } }
+ { \mbox }
+ { \ding { 73 } } % hollow star
+ }
\cs_new_protected:Npn \@@_typeset_TF:
{
- \hyperlink{explTF}
+ \cs_if_exist:NTF \Codedoc@explTF
+ { \hyperlink { explTF } }
+ { \mbox }
{
\color{black}
\itshape TF
\makebox[0pt][r]
{
- \color{red}
+ \cs_if_exist:NT \Codedoc@explTF { \color{red} }
\underline { \phantom{\itshape TF} \kern-0.1em }
}
}
@@ -2409,7 +2444,7 @@ and all files in that bundle must be distributed together.
{
\@@_date_set:Nn #1 {#2}
\exp_args:No \@@_date_compare:nNnT
- {#1} > { \tex_year:D - \tex_month:D - \tex_day:D }
+ {#1} > { \c_sys_year_int - \c_sys_month_int - \c_sys_day_int }
{
\msg_error:nnxx { l3doc } { future-date }
{ \tl_to_str:N \l_@@_macro_argument_tl }
@@ -2430,7 +2465,7 @@ and all files in that bundle must be distributed together.
{
\@@_date_set:Nn \l_@@_tmpa_tl {#1}
\exp_args:No \@@_date_compare:nNnT
- { \l_@@_tmpa_tl } < { \tex_year:D - \tex_month:D - \tex_day:D }
+ { \l_@@_tmpa_tl } < { \c_sys_year_int - \c_sys_month_int - \c_sys_day_int }
{
\msg_error:nnxx { l3doc } { deprecated-function }
{ \tl_to_str:N \l_@@_macro_argument_tl }
@@ -2495,6 +2530,7 @@ and all files in that bundle must be distributed together.
\cs_new_protected:Npn \@@_function_typeset_stop:
{
\par
+ \dim_set:Nn \prevdepth { \box_dp:N \l_@@_descr_coffin }
\allowbreak
}
% \end{macrocode}
@@ -3435,6 +3471,57 @@ and all files in that bundle must be distributed together.
% \end{environment}
% \end{environment}
%
+% \subsubsection{NB and NOTE}
+%
+% These macros are intended for additional notes added to the source that are not typeset.
+%
+% \begin{macro}{\NB}
+% \NB{wspr}{this is what I think about this!}
+% \begin{verbatim}
+% \NB{wspr}{this is what I think about this!}
+% \end{verbatim}
+% \begin{macrocode}
+\bool_if:NTF \g_@@_show_notes_bool
+ {
+ \NewDocumentCommand\NB{mm}
+ {
+ (\emph{Note}\footnote{\ttfamily [#1]:~\detokenize{#2}})
+ }
+ }
+ {
+ \NewDocumentCommand\NB{mm}{}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{\NOTE}
+% \begin{NOTE}{wspr}
+% this is what I #$%& think about this!
+% \end{NOTE}
+% \begin{verbatim}
+% \begin{NOTE}{wspr}
+% this is what I #$%& think about this!
+% \end{NOTE}
+% \end{verbatim}
+% \begin{macrocode}
+\bool_if:NTF \g_@@_show_notes_bool
+ {
+ \NewDocumentEnvironment{NOTE}{m}
+ {
+ \par\noindent (\emph{Note}~[\texttt{#1}]:\par
+ \verbatim
+ }
+ {
+ \endverbatim
+ \par\noindent \emph{Note~end})\par
+ }
+ }
+ {
+ \NewDocumentEnvironment{NOTE}{m}{\comment}{\endcomment}
+ }
+% \end{macrocode}
+% \end{environment}
+%
% \subsection{Documenting templates}
%
% \begin{macrocode}
@@ -3742,7 +3829,7 @@ and all files in that bundle must be distributed together.
\@@_replace_at_at:N \l_@@_tmpa_tl
\tl_gset:Nn \g_@@_module_name_tl {#2}
- \tl_put_right:Nn \l_@@_tmpa_tl { < @ @ = #2 > }
+ \tl_put_right:Nn \l_@@_tmpa_tl { < \text { \verbatim@font @ @ = #2 } > }
\tl_set:Nn \l_@@_tmpb_tl {#3}
\@@_detect_internals:N \l_@@_tmpb_tl
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
index cdb9ece1da4..4ba471a549c 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
@@ -63,7 +63,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
index 05df8c01b28..33fa348aad9 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -556,23 +556,23 @@
%<*package>
\ProvidesExplFile
%<*dvipdfmx>
- {l3dvipdfmx.def}{2019-02-15}{}
+ {l3dvipdfmx.def}{2019-03-05}{}
{L3 Experimental driver: dvipdfmx}
%</dvipdfmx>
%<*dvips>
- {l3dvips.def}{2019-02-15}{}
+ {l3dvips.def}{2019-03-05}{}
{L3 Experimental driver: dvips}
%</dvips>
%<*dvisvgm>
- {l3dvisvgm.def}{2019-02-15}{}
+ {l3dvisvgm.def}{2019-03-05}{}
{L3 Experimental driver: dvisvgm}
%</dvisvgm>
%<*pdfmode>
- {l3pdfmode.def}{2019-02-15}{}
+ {l3pdfmode.def}{2019-03-05}{}
{L3 Experimental driver: PDF mode}
%</pdfmode>
%<*xdvipdfmx>
- {l3xdvipdfmx.def}{2019-02-15}{}
+ {l3xdvipdfmx.def}{2019-03-05}{}
{L3 Experimental driver: xdvipdfmx}
%</xdvipdfmx>
%</package>
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
index dd4d70f59d6..4748bf35aa3 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -713,7 +713,7 @@
% \cs{exp_not:o} \Arg{tokens}
% \end{syntax}
% Expands the \meta{tokens} once, then prevents any further expansion
-% in |x|-type arguments using \cs{exp_not:n}.
+% in |x|-type or \texttt{e}-type arguments using \cs{exp_not:n}.
% \end{function}
%
% \begin{function}[EXP]{\exp_not:V}
@@ -721,7 +721,7 @@
% \cs{exp_not:V} \meta{variable}
% \end{syntax}
% Recovers the content of the \meta{variable}, then prevents expansion
-% of this material in |x|-type arguments using \cs{exp_not:n}.
+% of this material in |x|-type or \texttt{e}-type arguments using \cs{exp_not:n}.
% \end{function}
%
% \begin{function}[EXP]{\exp_not:v}
@@ -732,7 +732,7 @@
% converts this into a control sequence which should be a \meta{variable}
% name.
% The content of the \meta{variable} is recovered, and further
-% expansion in |x|-type arguments is prevented using \cs{exp_not:n}.
+% expansion in |x|-type or \texttt{e}-type arguments is prevented using \cs{exp_not:n}.
% \begin{texnote}
% Protected macros that appear in a \texttt{v}-type argument are
% expanded despite being protected; \cs{exp_not:n} also has no
@@ -759,7 +759,7 @@
% Expands \meta{tokens} fully until the first unexpandable token is
% found (if it is a space it is removed). Expansion then stops, and
% the result of the expansion (including any tokens which were not
-% expanded) is protected from further expansion in |x|-type arguments
+% expanded) is protected from further expansion in |x|-type or \texttt{e}-type arguments
% using \cs{exp_not:n}.
% \end{function}
%
@@ -1783,13 +1783,18 @@
{
% \end{macrocode}
%
-% \begin{macro}[EXP]{\@@_e:nn}
+% \begin{macro}[EXP]{\@@_e:nn, \@@_e_end:nn}
% Repeatedly expand tokens, keeping track of fully-expanded tokens in
% the second argument to \cs{@@_e:nn}; this function eventually
% calls \cs{@@_e_end:nn} to leave \cs{exp_end:} in the input
% stream, followed by the result of the expansion. There are many
% special cases: spaces, brace groups, \tn{noexpand}, \tn{unexpanded},
% \tn{the}, \tn{primitive}.
+% While we use brace tricks \cs{if_false:} |{| \cs{fi:}, the expansion
+% of this function is always triggered by \cs{exp:w} so brace balance
+% is eventually restored after that is hit with a single step of
+% expansion. Otherwise we could not nest \texttt{e}-type expansions
+% within each other.
% \begin{macrocode}
\cs_new:Npn \@@_e:nn #1
{
@@ -1844,7 +1849,8 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP]{\@@_e:N}
+% \begin{macro}[EXP]
+% {\@@_e:N, \@@_e:Nnn, \@@_e_protected:Nnn, \@@_e_expandable:Nnn}
% For an \texttt{N}-type token, call \cs{@@_e:Nnn} with arguments the
% \meta{first token}, the remaining tokens to expand and what's
% already been expanded. If the \meta{first token} is non-expandable,
@@ -1887,14 +1893,74 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP]{\@@_e_primitive:Nnn}
-% Quite rare. Will be implemented later.
+% \begin{macro}[EXP]
+% {
+% \@@_e_primitive:Nnn,
+% \@@_e_primitive_aux:NNw,
+% \@@_e_primitive_aux:NNnn,
+% \@@_e_primitive_other:NNnn,
+% \@@_e_primitive_other_aux:nNNnn
+% }
+% We don't try hard to make sensible error recovery since the error
+% recovery of \cs{tex_primitive:D} when followed by something else
+% than a primitive depends on the engine. The only valid case is when
+% what follows is \texttt{N}-type. Then distinguish special
+% primitives \tn{unexpanded}, \tn{noexpand}, \tn{the}, \tn{primitive}
+% from other primitives. In the \enquote{other} case, the only
+% reasonable way to check if the primitive that follows
+% \cs{tex_primitive:D} is expandable is to expand and compare the
+% before-expansion and after-expansion results. If they coincide then
+% probably the primitive is non-expandable and should be put in the
+% output together with \cs{tex_primitive:D} (one can cook up contrived
+% counter-examples where the true \tn{expanded} would have an infinite
+% loop), and otherwise one should continue expanding.
% \begin{macrocode}
- \cs_new:Npn \@@_e_primitive:Nnn #1
+ \cs_new:Npn \@@_e_primitive:Nnn #1#2
{
- \__kernel_msg_expandable_error:nnn { kernel } { e-type }
- { \primitive not~implemented }
- \@@_e:nn
+ \if_false: { \fi:
+ \tl_if_head_is_N_type:nTF {#2}
+ { \@@_e_primitive_aux:NNw #1 }
+ {
+ \__kernel_msg_expandable_error:nnn { kernel } { e-type }
+ { Missing~primitive~name }
+ \@@_e_primitive_aux:NNw #1 \c_empty_tl
+ }
+ #2
+ }
+ }
+ \cs_new:Npn \@@_e_primitive_aux:NNw #1#2
+ {
+ \exp_after:wN \@@_e_primitive_aux:NNnn
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \if_false: } \fi:
+ }
+ \cs_new:Npn \@@_e_primitive_aux:NNnn #1#2
+ {
+ \exp_args:Nf \str_case_e:nnTF { \cs_to_str:N #2 }
+ {
+ { unexpanded } { \@@_e_unexpanded:Nnn \exp_not:n }
+ { noexpand } { \@@_e_noexpand:Nnn \exp_not:N }
+ { the } { \@@_e_the:Nnn \tex_the:D }
+ {
+ \sys_if_engine_xetex:T { pdf }
+ \sys_if_engine_luatex:T { pdf }
+ primitive
+ } { \@@_e_primitive:Nnn #1 }
+ }
+ { \@@_e_primitive_other:NNnn #1 #2 }
+ }
+ \cs_new:Npn \@@_e_primitive_other:NNnn #1#2#3
+ {
+ \exp_args:No \@@_e_primitive_other_aux:nNNnn
+ { #1 #2 #3 }
+ #1 #2 {#3}
+ }
+ \cs_new:Npn \@@_e_primitive_other_aux:nNNnn #1#2#3#4#5
+ {
+ \str_if_eq:nnTF {#1} { #2 #3 #4 }
+ { \@@_e:nn {#4} { #5 #2 #3 } }
+ { \@@_e:nn {#1} {#5} }
}
% \end{macrocode}
% \end{macro}
@@ -1937,10 +2003,10 @@
% braces), unless that \meta{token} is \cs{scan_stop:} or a space
% (recall that we don't implement the case of an implicit begin-group
% token). An expandable \meta{token} is instead expanded, unless it
-% is \tn{noexpand}. That primitive can be followed by an expandable
-% \texttt{N}-type token, to be removed, by a non-expandable one, kept
-% (and later causing an error), by a space, removed by
-% \texttt{f}-expansion, or by a brace group or nothing (later causing
+% is \tn{noexpand}. The latter primitive can be followed by an expandable
+% \texttt{N}-type token (removed), by a non-expandable one (kept
+% and later causing an error), by a space (removed by
+% \texttt{f}-expansion), or by a brace group or nothing (later causing
% an error).
% \begin{macrocode}
\cs_new:Npn \@@_e_unexpanded:Nnn #1 { \@@_e_unexpanded:nn }
@@ -2098,20 +2164,41 @@
{
#1
\exp_after:wN \@@_e_the_toks:n
+ \exp_after:wN { \if_false: } \fi:
+ }
+ {
+ \exp_after:wN ;
+ \exp_after:wN { \if_false: } \fi: #1
}
- { \exp_after:wN ; }
- \exp_after:wN { \if_false: } \fi:
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\@@_e_if_toks_register:NTF}
-% We need to detect both \tn{toks} registers like \tn{toks@} (in
-% \LaTeXe{}) and parameters such as \tn{everypar}, as the result of
-% unpacking the register should not expand further. The list of
-% parameters is finite so we just use a \cs{cs_if_exist:cTF} test to
-% look up in a table. Registers are found by
-% \cs{token_if_toks_register:NTF} by inspecting the meaning. We abuse
+% \begin{macro}[EXP]
+% {
+% \@@_e_the_XeTeXinterchartoks:,
+% \@@_e_the_errhelp:,
+% \@@_e_the_everycr:,
+% \@@_e_the_everydisplay:,
+% \@@_e_the_everyeof:,
+% \@@_e_the_everyhbox:,
+% \@@_e_the_everyjob:,
+% \@@_e_the_everymath:,
+% \@@_e_the_everypar:,
+% \@@_e_the_everyvbox:,
+% \@@_e_the_output:,
+% \@@_e_the_pdfpageattr:,
+% \@@_e_the_pdfpageresources:,
+% \@@_e_the_pdfpagesattr:,
+% \@@_e_the_pdfpkmode:
+% }
+% We need to detect both \tn{toks} registers like \tn{toks@} in
+% \LaTeXe{} and parameters such as \tn{everypar}, as the result of
+% unpacking the register should not expand further. Registers are
+% found by \cs{token_if_toks_register:NTF} by inspecting the meaning.
+% The list of parameters is finite so we just use a
+% \cs{cs_if_exist:cTF} test to look up in a table. We abuse
% \cs{cs_to_str:N}'s ability to remove a leading escape character
% whatever it is.
% \begin{macrocode}
@@ -2145,6 +2232,7 @@
\cs_new_eq:NN \@@_e_the_pdfpkmode: ?
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
% We are done emulating \texttt{e}-type argument expansion when
% \tn{expanded} is unavailable.
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
index a8262e75962..f81f3a488b5 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -164,9 +164,10 @@
%
% \subsection{Reading from files}
%
-% \begin{function}[added = 2012-06-24]{\ior_get:NN}
+% \begin{function}[noTF, added = 2012-06-24, updated = 2019-02-17]{\ior_get:NN}
% \begin{syntax}
% \cs{ior_get:NN} \meta{stream} \meta{token list variable}
+% \cs{ior_get:NNTF} \meta{stream} \meta{token list variable} \meta{true code} \meta{false code}
% \end{syntax}
% Function that reads one or more lines (until an equal number of left
% and right braces are found) from the input \meta{stream} and stores
@@ -191,6 +192,8 @@
% \end{verbatim}
% Also notice that if multiple lines are read to match braces
% then the resulting token list can contain \cs{par} tokens.
+% In the non-branching version, where the file is not found the \meta{tl var}
+% is set to \cs{q_no_value}.
% \begin{texnote}
% This protected macro is a wrapper around the \TeX{} primitive
% \tn{read}. Regardless of settings, \TeX{} replaces trailing space
@@ -203,9 +206,11 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}[added = 2016-12-04]{\ior_str_get:NN}
+% \begin{function}[noTF, added = 2016-12-04, updated = 2019-02-17]
+% {\ior_str_get:NN}
% \begin{syntax}
% \cs{ior_str_get:NN} \meta{stream} \meta{token list variable}
+% \cs{ior_str_get:NNTF} \meta{stream} \meta{token list variable} \meta{true code} \meta{false code}
% \end{syntax}
% Function that reads one line from the input \meta{stream} and stores
% the result locally in the \meta{token list} variable. If the
@@ -223,6 +228,8 @@
% \end{verbatim}
% results in a token list |a b c| with the letters |a|, |b|, and |c|
% having category code~12.
+% In the non-branching version, where the file is not found the \meta{tl var}
+% is set to \cs{q_no_value}.
% \begin{texnote}
% This protected macro is a wrapper around the \eTeX{} primitive
% \tn{readline}. Regardless of settings, \TeX{} removes trailing
@@ -313,17 +320,17 @@
% \end{texnote}
% \end{function}
%
-%\begin{function}[updated = 2012-02-10, EXP, pTF]{\ior_if_eof:N}
-% \begin{syntax}
-% \cs{ior_if_eof_p:N} \meta{stream} \\
-% \cs{ior_if_eof:NTF} \meta{stream} \Arg{true code} \Arg{false code}
-% \end{syntax}
-% Tests if the end of a \meta{stream} has been reached during a reading
-% operation. The test also returns a \texttt{true} value if
-% the \meta{stream} is not open.
-%\end{function}
+% \begin{function}[updated = 2012-02-10, EXP, pTF]{\ior_if_eof:N}
+% \begin{syntax}
+% \cs{ior_if_eof_p:N} \meta{stream} \\
+% \cs{ior_if_eof:NTF} \meta{stream} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the end of a \meta{stream} has been reached during a reading
+% operation. The test also returns a \texttt{true} value if
+% the \meta{stream} is not open.
+% \end{function}
%
-% \section{Writing to files}
+% \subsection{Writing to files}
%
% \begin{function}[updated = 2012-06-05]{\iow_now:Nn, \iow_now:Nx, \iow_now:cn, \iow_now:cx}
% \begin{syntax}
@@ -592,8 +599,7 @@
% \cs{l_file_search_path_seq}.
% \end{function}
%
-% \begin{function}[added = 2019-01-16]{\file_get:nnN}
-% \begin{function}[TF, added = 2019-01-16]{\file_get:nnN}
+% \begin{function}[noTF, added = 2019-01-16, updated = 2019-02-16]{\file_get:nnN}
% \begin{syntax}
% \cs{file_get:nnN} \Arg{filename} \Arg{setup} \meta{tl}
% \cs{file_get:nnNTF} \Arg{filename} \Arg{setup} \meta{tl} \Arg{true code} \Arg{false code}
@@ -601,23 +607,25 @@
% Defines \meta{tl} to the contents of \meta{filename}.
% Category codes may need to be set appropriately via the \meta{setup}
% argument.
-% While \cs{file_get:nnN} produces an error if the file is not found,
-% \cs{file_get:nnNTF} runs the \meta{true code} (after the assignment
-% to \meta{tl}) if the file is found and \meta{false code} otherwise.
-% \end{function}
+% The non-branching version sets the \meta{tl} to \cs{q_no_value} if the file is
+% not found. The branching version runs the \meta{true code} after the
+% assignment to \meta{tl} if the file is found, and \meta{false code}
+% otherwise.
% \end{function}
%
-% \begin{function}[updated = 2017-06-26]
+% \begin{function}[noTF, updated = 2019-02-16]
% {\file_get_full_name:nN, \file_get_full_name:VN}
% \begin{syntax}
-% \cs{file_get_full_name:nN} \Arg{file name} \meta{str var}
+% \cs{file_get_full_name:nN} \Arg{file name} \meta{tl}
+% \cs{file_get_full_name:nNTF} \Arg{file name} \meta{tl} \Arg{true code} \Arg{false code}
% \end{syntax}
% Searches for \meta{file name} in the path as detailed for
-% \cs{file_if_exist:nTF}, and if found sets the \meta{str var} the
+% \cs{file_if_exist:nTF}, and if found sets the \meta{tl var} the
% fully-qualified name of the file, \emph{i.e.}~the path and file name.
% This includes an extension |.tex| when the given \meta{file name}
% has no extension but the file found has that extension.
-% If the file is not found then the \meta{str var} is empty.
+% In the non-branching version, the \meta{tl var} will be set to
+% \cs{q_no_value} in the case that the file does not exist.
% \end{function}
%
% \begin{function}[added = 2017-06-23, updated = 2017-06-26]
@@ -782,10 +790,10 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{variable}{\l_@@_file_name_str}
+% \begin{variable}{\l_@@_file_name_tl}
% Data storage.
% \begin{macrocode}
-\str_new:N \l_@@_file_name_str
+\tl_new:N \l_@@_file_name_tl
% \end{macrocode}
% \end{variable}
%
@@ -797,13 +805,12 @@
% \begin{macrocode}
\prg_new_protected_conditional:Npnn \ior_open:Nn #1#2 { T , F , TF }
{
- \file_get_full_name:nN {#2} \l_@@_file_name_str
- \str_if_empty:NTF \l_@@_file_name_str
- { \prg_return_false: }
+ \file_get_full_name:nNTF {#2} \l_@@_file_name_tl
{
- \__kernel_ior_open:No #1 \l_@@_file_name_str
+ \__kernel_ior_open:No #1 \l_@@_file_name_tl
\prg_return_true:
}
+ { \prg_return_false: }
}
\prg_generate_conditional_variant:Nnn \ior_open:Nn { c } { T , F , TF }
% \end{macrocode}
@@ -955,19 +962,35 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\ior_get:NN}
+% \begin{macro}{\ior_get:NN, \@@_get:NN}
+% \begin{macro}[TF]{\ior_get:NN}
% And here we read from files.
% \begin{macrocode}
\cs_new_protected:Npn \ior_get:NN #1#2
+ { \ior_get:NNF #1 #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \@@_get:NN #1#2
{ \tex_read:D #1 to #2 }
+\prg_new_protected_conditional:Npnn \ior_get:NN #1#2 { T , F , TF }
+ {
+ \ior_if_eof:NTF #1
+ { \prg_return_false: }
+ {
+ \@@_get:NN #1 #2
+ \prg_return_true:
+ }
+ }
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\ior_str_get:NN}
+% \begin{macro}{\ior_str_get:NN, \@@_str_get:NN}
+% \begin{macro}[TF]{\ior_str_get:NN}
% Reading as strings is a more complicated wrapper, as we wish to
% remove the endline character and restore it afterwards.
% \begin{macrocode}
\cs_new_protected:Npn \ior_str_get:NN #1#2
+ { \ior_str_get:NNF #1 #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \@@_str_get:NN #1#2
{
\exp_args:Nno \use:n
{
@@ -976,8 +999,18 @@
\int_set:Nn \tex_endlinechar:D
} { \int_use:N \tex_endlinechar:D }
}
+\prg_new_protected_conditional:Npnn \ior_str_get:NN #1#2 { T , F , TF }
+ {
+ \ior_if_eof:NTF #1
+ { \prg_return_false: }
+ {
+ \@@_str_get:NN #1 #2
+ \prg_return_true:
+ }
+ }
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
% \begin{macro}[EXP]{\ior_map_break:, \ior_map_break:n}
% Usual map breaking functions.
@@ -1001,9 +1034,9 @@
% stream has only one \enquote{current line}.
% \begin{macrocode}
\cs_new_protected:Npn \ior_map_inline:Nn
- { \@@_map_inline:NNn \ior_get:NN }
+ { \@@_map_inline:NNn \@@_get:NN }
\cs_new_protected:Npn \ior_str_map_inline:Nn
- { \@@_map_inline:NNn \ior_str_get:NN }
+ { \@@_map_inline:NNn \@@_str_get:NN }
\cs_new_protected:Npn \@@_map_inline:NNn
{
\int_gincr:N \g__kernel_prg_map_int
@@ -1173,10 +1206,10 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{variable}{\l_@@_file_name_str}
+% \begin{variable}{\l_@@_file_name_tl}
% Data storage.
% \begin{macrocode}
-\str_new:N \l_@@_file_name_str
+\tl_new:N \l_@@_file_name_tl
% \end{macrocode}
% \end{variable}
%
@@ -1187,10 +1220,10 @@
% \begin{macrocode}
\cs_new_protected:Npn \iow_open:Nn #1#2
{
- \__kernel_file_name_sanitize:nN {#2} \l_@@_file_name_str
+ \__kernel_file_name_sanitize:nN {#2} \l_@@_file_name_tl
\iow_close:N #1
\seq_gpop:NNTF \g_@@_streams_seq \l_@@_stream_tl
- { \@@_open_stream:NV #1 \l_@@_file_name_str }
+ { \@@_open_stream:NV #1 \l_@@_file_name_tl }
%<*initex>
{ \__kernel_msg_fatal:nn { kernel } { output-streams-exhausted } }
%</initex>
@@ -1198,7 +1231,7 @@
{
\@@_new:N #1
\tl_set:Nx \l_@@_stream_tl { \int_eval:n {#1} }
- \@@_open_stream:NV #1 \l_@@_file_name_str
+ \@@_open_stream:NV #1 \l_@@_file_name_tl
}
%</package>
}
@@ -1332,8 +1365,8 @@
\cs_set_protected:Npn \iow_term:x { \iow_now:Nx \c_term_iow }
\cs_new_protected:Npn \iow_term:n { \iow_now:Nn \c_term_iow }
% \end{macrocode}
-%\end{macro}
-%\end{macro}
+% \end{macro}
+% \end{macro}
%
% \subsubsection{Special characters for writing}
%
@@ -2092,11 +2125,11 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\l_@@_base_name_str, \l_@@_full_name_str}
+% \begin{variable}{\l_@@_base_name_tl, \l_@@_full_name_tl}
% For storing the basename and full path whilst passing data internally.
% \begin{macrocode}
-\str_new:N \l_@@_base_name_str
-\str_new:N \l_@@_full_name_str
+\tl_new:N \l_@@_base_name_tl
+\tl_new:N \l_@@_full_name_tl
% \end{macrocode}
% \end{variable}
%
@@ -2144,8 +2177,6 @@
\char_set_active_eq:NN ##1 \l_@@_internal_tl
}
\tl_set:Nx \l_@@_internal_tl {#1}
- \tl_set:Nx \l_@@_internal_tl
- { \tl_to_str:N \l_@@_internal_tl }
\exp_args:NNNV \group_end:
\str_set:Nn #2 \l_@@_internal_tl
}
@@ -2190,19 +2221,18 @@
\cs_new_protected:Npn \file_get:nnN #1#2#3
{
\file_get:nnNF {#1} {#2} #3
- { \__kernel_file_missing:n {#1} }
+ { \tl_set:Nn #3 { \q_no_value } }
}
\prg_new_protected_conditional:Npnn \file_get:nnN #1#2#3 { T , F , TF }
{
- \file_get_full_name:nN {#1} \l_@@_full_name_str
- \str_if_empty:NTF \l_@@_full_name_str
- { \prg_return_false: }
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
{
\exp_args:NV \@@_get_aux:nnN
- \l_@@_full_name_str
+ \l_@@_full_name_tl
{#2} #3
\prg_return_true:
}
+ { \prg_return_false: }
}
\cs_new_protected:Npn \@@_get_aux:nnN #1#2#3
{
@@ -2229,6 +2259,7 @@
% \end{macro}
%
% \begin{macro}{\file_get_full_name:nN, \file_get_full_name:VN}
+% \begin{macro}[TF]{\file_get_full_name:nN, \file_get_full_name:VN}
% \begin{macro}{\@@_get_full_name_search:nN}
% The way to test if a file exists is to try to open it: if it does
% not exist then \TeX{} reports end-of-file. A search is made
@@ -2242,7 +2273,13 @@
% \begin{macrocode}
\cs_new_protected:Npn \file_get_full_name:nN #1#2
{
- \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_str
+ \file_get_full_name:nNF {#1} #2
+ { \tl_set:Nn #2 { \q_no_value } }
+ }
+\cs_generate_variant:Nn \file_get_full_name:nN { V }
+\prg_new_protected_conditional:Npnn \file_get_full_name:nN #1#2 { T , F , TF }
+ {
+ \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_tl
\@@_get_full_name_search:nN { } \use:n
\seq_map_inline:Nn \l_file_search_path_seq
{ \@@_get_full_name_search:nN { ##1 / } \seq_map_break:n }
@@ -2253,35 +2290,43 @@
{ \@@_get_full_name_search:nN { ##1 } \tl_map_break:n }
}
%</package>
- \str_clear:N \l_@@_full_name_str
+ \tl_set:Nn \l_@@_full_name_tl { \q_no_value }
\prg_break_point:
- \str_if_empty:NF \l_@@_full_name_str
+ \quark_if_no_value:NTF \l_@@_full_name_tl
+ {
+ \ior_close:N \g_@@_internal_ior
+ \prg_return_false:
+ }
{
- \exp_args:NV \file_parse_full_name:nNNN \l_@@_full_name_str
+ \exp_args:NV \file_parse_full_name:nNNN \l_@@_full_name_tl
\l_@@_dir_str \l_@@_name_str \l_@@_ext_str
\str_if_empty:NT \l_@@_ext_str
{
\__kernel_ior_open:No \g_@@_internal_ior
- { \l_@@_full_name_str .tex }
+ { \l_@@_full_name_tl .tex }
\ior_if_eof:NF \g_@@_internal_ior
- { \str_put_right:Nn \l_@@_full_name_str { .tex } }
+ { \tl_put_right:Nn \l_@@_full_name_tl { .tex } }
}
+ \ior_close:N \g_@@_internal_ior
+ \tl_set_eq:NN #2 \l_@@_full_name_tl
+ \prg_return_true:
}
- \str_set_eq:NN #2 \l_@@_full_name_str
- \ior_close:N \g_@@_internal_ior
}
-\cs_generate_variant:Nn \file_get_full_name:nN { V }
+\cs_generate_variant:Nn \file_get_full_name:nNT { V }
+\cs_generate_variant:Nn \file_get_full_name:nNF { V }
+\cs_generate_variant:Nn \file_get_full_name:nNTF { V }
\cs_new_protected:Npn \@@_get_full_name_search:nN #1#2
{
\@@_name_quote:nN
- { \tl_to_str:n {#1} \l_@@_base_name_str }
- \l_@@_full_name_str
- \__kernel_ior_open:No \g_@@_internal_ior \l_@@_full_name_str
+ { \tl_to_str:n {#1} \l_@@_base_name_tl }
+ \l_@@_full_name_tl
+ \__kernel_ior_open:No \g_@@_internal_ior \l_@@_full_name_tl
\ior_if_eof:NF \g_@@_internal_ior { #2 { \prg_break: } }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}[TF]{\file_if_exist:n}
% The test for the existence of a file is a wrapper around the function to
@@ -2291,10 +2336,9 @@
% \begin{macrocode}
\prg_new_protected_conditional:Npnn \file_if_exist:n #1 { T , F , TF }
{
- \file_get_full_name:nN {#1} \l_@@_full_name_str
- \str_if_empty:NTF \l_@@_full_name_str
- { \prg_return_false: }
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
{ \prg_return_true: }
+ { \prg_return_false: }
}
% \end{macrocode}
% \end{macro}
@@ -2304,9 +2348,9 @@
% \begin{macrocode}
\cs_new_protected:Npn \__kernel_file_missing:n #1
{
- \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_str
+ \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_tl
\__kernel_msg_error:nnx { kernel } { file-not-found }
- { \l_@@_base_name_str }
+ { \l_@@_base_name_tl }
}
% \end{macrocode}
% \end{macro}
@@ -2323,10 +2367,9 @@
% \begin{macrocode}
\cs_new_protected:Npn \file_input:n #1
{
- \file_get_full_name:nN {#1} \l_@@_full_name_str
- \str_if_empty:NTF \l_@@_full_name_str
+ \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
+ { \@@_input:V \l_@@_full_name_tl }
{ \__kernel_file_missing:n {#1} }
- { \@@_input:V \l_@@_full_name_str }
}
\cs_new_protected:Npn \@@_input:n #1
{
@@ -2491,6 +2534,75 @@
%</package>
% \end{macrocode}
%
+% \subsection{GetIfInfo}
+%
+% \begin{macro}{\GetIdInfo}
+% \begin{macro}{\@@_id_info_auxi:w, \@@_id_info_auxii:w, \@@_id_info_auxiii:w}
+% As documented in \pkg{expl3.dtx} this function extracts file name
+% etc from an \textsc{svn} \texttt{Id} line. This used to be how we
+% got version number and so on in all modules, so it had to be defined
+% in \pkg{l3bootstrap}. Now it's more convenient to define it after
+% we have set up quite a lot of tools, and \pkg{l3file} seems the
+% least unreasonable place for it.
+%
+% The idea here is to extract out the information needed from a standard
+% \textsc{svn} \texttt{Id} line, but to avoid a line that would get
+% changed when the file is checked in. Hence the fact that none of the
+% lines here include both a dollar sign and the \texttt{Id} keyword!
+% \begin{macrocode}
+\cs_new_protected:Npn \GetIdInfo
+ {
+ \group_begin:
+ \char_set_catcode_space:n { 32 }
+ \exp_after:wN
+ \group_end:
+ \@@_id_info_auxi:w
+ }
+% \end{macrocode}
+% A first check for a completely empty \textsc{svn} field. If that is
+% not the case, there is a second case when a file created using
+% \texttt{svn cp} but has not been checked in. That leaves a special
+% marker \texttt{-1} version, which has no further data. Dealing
+% correctly with that is the reason for the space in the line to use
+% \cs{@@_id_info_auxii:w}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_id_info_auxi:w $ #1 $ #2
+ {
+ \tl_set:Nn \ExplFileDescription {#2}
+ \str_if_eq:nnTF {#1} { Id }
+ {
+ \tl_set:Nn \ExplFileDate { 0000/00/00 }
+ \tl_set:Nn \ExplFileName { [unknown] }
+ \tl_set:Nn \ExplFileExtension { [unknown~extension] }
+ \tl_set:Nn \ExplFileVersion {-1}
+ }
+ { \@@_id_info_auxii:w #1 ~ \q_stop }
+ }
+% \end{macrocode}
+% Here, |#1| is |Id|, |#2| is the file name, |#3| is the extension,
+% |#4| is the version, |#5| is the check in date and |#6| is the check
+% in time and user, plus some trailing spaces. If |#4| is the marker
+% |-1| value then |#5| and |#6| are empty.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_id_info_auxii:w
+ #1 ~ #2.#3 ~ #4 ~ #5 ~ #6 \q_stop
+ {
+ \tl_set:Nn \ExplFileName {#2}
+ \tl_set:Nn \ExplFileExtension {#3}
+ \tl_set:Nn \ExplFileVersion {#4}
+ \str_if_eq:nnTF {#4} {-1}
+ { \tl_set:Nn \ExplFileDate { 0000/00/00 } }
+ { \@@_id_info_auxiii:w #5 - 0 - 0 - \q_stop }
+ }
+% \end{macrocode}
+% Convert an \textsc{svn}-style date into a \LaTeX{}-style one.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_id_info_auxiii:w #1 - #2 - #3 - #4 \q_stop
+ { \tl_set:Nn \ExplFileDate { #1/#2/#3 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Messages}
%
% \begin{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
index 9c385192b53..5422ccde49d 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
index 3c5e3486276..cdff9f98509 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
index 6e726d7f1c6..03d5e78cc8c 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
% \maketitle
%
% \begin{documentation}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
index 1a93847d1ce..e19ae3431f0 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -1156,7 +1156,7 @@
% \@@_small_int_test:NnnwNTF
% }
% Tests if the floating point argument is an integer or $\pm\infty$.
-% If so, it is converted to an integer in the range $[-10^{8},10^{8}]$
+% If so, it is clipped to an integer in the range $[-10^{8},10^{8}]$
% and fed as a braced argument to the \meta{true code}.
% Otherwise, the \meta{false code} is performed.
%
@@ -1207,37 +1207,6 @@
% \end{macro}
% \end{macro}
%
-% \subsection{\texttt{x}-like expansion expandably}
-%
-% \begin{macro}[EXP]{\@@_expand:n}
-% \begin{macro}[EXP]{\@@_expand_loop:nwnN}
-% This expandable function behaves in a way somewhat similar to
-% \cs{use:x}, but much less robust. The argument is
-% \texttt{f}-expanded, then the leading item (often a single character
-% token) is moved to a storage area after \cs{s_@@_mark}, and
-% \texttt{f}-expansion is applied again, repeating until the argument
-% is empty. The result built one piece at a time is then inserted in
-% the input stream. Note that spaces are ignored by this procedure,
-% unless surrounded with braces. Multiple tokens which do not need
-% expansion can be inserted within braces.
-% \begin{macrocode}
-\cs_new:Npn \@@_expand:n #1
- {
- \@@_expand_loop:nwnN { }
- #1 \prg_do_nothing:
- \s_@@_mark { } \@@_expand_loop:nwnN
- \s_@@_mark { } \@@_use_i_until_s:nw ;
- }
-\cs_new:Npn \@@_expand_loop:nwnN #1#2 \s_@@_mark #3 #4
- {
- \exp_after:wN #4 \exp:w \exp_end_continue_f:w
- #2
- \s_@@_mark { #3 #1 } #4
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
% \subsection{Fast string comparison}
%
% \begin{macro}{\@@_str_if_eq:nn}
@@ -1247,10 +1216,9 @@
% No \pkg{l3sys} or \pkg{l3luatex} just yet so we have to define in terms of
% primitives.
% \begin{macrocode}
-\cs_new:Npn \@@_str_if_eq:nn #1#2 { \tex_strcmp:D {#1} {#2} }
-\sys_if_engine_luatex:T
+\sys_if_engine_luatex:TF
{
- \cs_set:Npn \@@_str_if_eq:nn #1#2
+ \cs_new:Npn \@@_str_if_eq:nn #1#2
{
\tex_directlua:D
{
@@ -1262,6 +1230,7 @@
}
}
}
+ { \cs_new_eq:NN \@@_str_if_eq:nn \tex_strcmp:D }
% \end{macrocode}
% \end{macro}
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
index 77123e92b61..d4a81b3c8fb 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
index b7a76f0ce8c..af8c5d8a63a 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -592,26 +592,19 @@
{
\tl_if_empty:nF {#1}
{
- \@@_expand:n
+ \exp_last_unbraced:Ne \use_ii:nn
{
- { \use_ii:nn }
\@@_array_to_clist_loop:Nw #1 { ? \prg_break: } ;
\prg_break_point:
}
}
}
-\cs_new:Npx \@@_array_to_clist_loop:Nw #1#2;
+\cs_new:Npn \@@_array_to_clist_loop:Nw #1#2;
{
- \exp_not:N \use_none:n #1
- \exp_not:N \exp_after:wN
- {
- \exp_not:N \exp_after:wN ,
- \exp_not:N \exp_after:wN \c_space_tl
- \exp_not:N \exp:w
- \exp_not:N \exp_end_continue_f:w
- \exp_not:N \@@_to_tl_dispatch:w #1 #2 ;
- }
- \exp_not:N \@@_array_to_clist_loop:Nw
+ \use_none:n #1
+ , ~
+ \exp_not:f { \@@_to_tl_dispatch:w #1 #2 ; }
+ \@@_array_to_clist_loop:Nw
}
% \end{macrocode}
% \end{macro}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
index 1827c24b804..c4d2decc1df 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -64,6 +64,7 @@
% {
% \@@_parse_word_exp:N ,
% \@@_parse_word_ln:N ,
+% \@@_parse_word_fact:N,
% }
% Unary functions.
% \begin{macrocode}
@@ -71,6 +72,8 @@
{ \@@_parse_unary_function:NNN \@@_exp_o:w ? }
\cs_new:Npn \@@_parse_word_ln:N
{ \@@_parse_unary_function:NNN \@@_ln_o:w ? }
+\cs_new:Npn \@@_parse_word_fact:N
+ { \@@_parse_unary_function:NNN \@@_fact_o:w ? }
% \end{macrocode}
% \end{macro}
%
@@ -1247,6 +1250,124 @@
% \end{macrocode}
% \end{macro}
%
+% \subsection{Factorial}
+%
+% \begin{variable}{\c_@@_fact_max_arg_int}
+% The maximum integer whose factorial fits in the exponent range is
+% $3248$, as $3249!\sim 10^{10000.8}$
+% \begin{macrocode}
+\int_const:Nn \c_@@_fact_max_arg_int { 3248 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_fact_o:w}
+% First detect $\pm 0$ and $+\infty$ and \texttt{nan}. Then note that
+% factorial of anything with a negative sign (except $-0$) is
+% undefined. Then call \cs{@@_small_int:wTF} to get an integer as the
+% argument, and start a loop. This is not the most efficient way of
+% computing the factorial, but it works all right. Of course we work
+% with $24$ digits instead of~$16$. It is easy to check that
+% computing factorials with this precision is enough.
+% \begin{macrocode}
+\cs_new:Npn \@@_fact_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+ {
+ \if_case:w #2 \exp_stop_f:
+ \@@_case_return_o:Nw \c_one_fp
+ \or:
+ \or:
+ \if_meaning:w 0 #3
+ \exp_after:wN \@@_case_return_same_o:w
+ \fi:
+ \or:
+ \@@_case_return_same_o:w
+ \fi:
+ \if_meaning:w 2 #3
+ \@@_case_use:nw { \@@_invalid_operation_o:fw { fact } }
+ \fi:
+ \@@_fact_pos_o:w
+ \s_@@ \@@_chk:w #2 #3 #4 ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fact_pos_o:w, \@@_fact_int_o:w}
+% Then check the input is an integer, and call
+% \cs{@@_facorial_int_o:n} with that \texttt{int} as an argument. If
+% it's too big the factorial overflows. Otherwise call
+% \cs{@@_sanitize:Nw} with a positive sign marker~|0| and an integer
+% expression that will mop up any exponent in the calculation.
+% \begin{macrocode}
+\cs_new:Npn \@@_fact_pos_o:w #1;
+ {
+ \@@_small_int:wTF #1;
+ { \@@_fact_int_o:n }
+ { \@@_invalid_operation_o:fw { fact } #1; }
+ }
+\cs_new:Npn \@@_fact_int_o:n #1
+ {
+ \if_int_compare:w #1 > \c_@@_fact_max_arg_int
+ \@@_case_return:nw
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_overflow:w
+ \exp_after:wN \c_inf_fp
+ }
+ \fi:
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN 0
+ \int_value:w \@@_int_eval:w
+ \@@_fact_loop_o:w #1 . 4 , { 1 } { } { } { } { } { } ;
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fact_loop_o:w}
+% The loop receives an integer |#1| whose factorial we want to
+% compute, which we progressively decrement, and the result so far as
+% an extended-precision number |#2| in the form
+% \meta{exponent}|,|\meta{mantissa}|;|. The loop goes in steps of two
+% because we compute |#1*#1-1| as an integer expression (it must fit
+% since |#1| is at most $3248$), then multiply with the result so far.
+% We don't need to fill in most of the mantissa with zeros because
+% \cs{@@_ep_mul:wwwwn} first normalizes the extended precision number
+% to avoid loss of precision. When reaching a small enough number
+% simply use a table of factorials less than $10^8$. This limit is
+% chosen because the normalization step cannot deal with larger
+% integers.
+% \begin{macrocode}
+\cs_new:Npn \@@_fact_loop_o:w #1 . #2 ;
+ {
+ \if_int_compare:w #1 < 12 \exp_stop_f:
+ \@@_fact_small_o:w #1
+ \fi:
+ \exp_after:wN \@@_ep_mul:wwwwn
+ \exp_after:wN 4 \exp_after:wN ,
+ \exp_after:wN { \int_value:w \@@_int_eval:w #1 * (#1 - 1) }
+ { } { } { } { } { } ;
+ #2 ;
+ {
+ \exp_after:wN \@@_fact_loop_o:w
+ \int_value:w \@@_int_eval:w #1 - 2 .
+ }
+ }
+\cs_new:Npn \@@_fact_small_o:w #1 \fi: #2 ; #3 ; #4
+ {
+ \fi:
+ \exp_after:wN \@@_ep_mul:wwwwn
+ \exp_after:wN 4 \exp_after:wN ,
+ \exp_after:wN
+ {
+ \int_value:w
+ \if_case:w #1 \exp_stop_f:
+ 1 \or: 1 \or: 2 \or: 6 \or: 24 \or: 120 \or: 720 \or: 5040
+ \or: 40320 \or: 362880 \or: 3628800 \or: 39916800
+ \fi:
+ } { } { } { } { } { } ;
+ #3 ;
+ \@@_ep_to_float_o:wwN 0
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
index 63632006068..7fed9ae6b51 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
index 956680401fb..a5e5dcef8c2 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
index 1b2e99e6347..79ffd106299 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
index fd7689c8baf..da37a9e89c9 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
index 41ae37c9e0c..e2c70701c70 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
index 64999b90a29..b9810a08d63 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
% \maketitle
%
% \begin{documentation}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
index 19986a962cf..7c19482bb3c 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
index 82797003afb..aa3b0c81a12 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
@@ -49,7 +49,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -73,6 +73,7 @@
% $x\mathop{\&\&}y$, disjunction $x\mathop{\vert\vert}y$, ternary
% operator $x\mathop{?}y\mathop{:}z$.
% \item Exponentials: $\exp x$, $\ln x$, $x^y$.
+% \item Integer factorial: $\operatorname{fact} x$.
% \item Trigonometry: $\sin x$, $\cos x$, $\tan x$, $\cot x$, $\sec
% x$, $\csc x$ expecting their arguments in radians, and
% $\operatorname{sind} x$, $\operatorname{cosd} x$,
@@ -1028,6 +1029,18 @@
% If the operand is a tuple, \enquote{invalid operation} occurs.
% \end{function}
%
+% \begin{function}[tested = m3fp-expo001]{fact}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |fact(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the factorial of the \meta{fpexpr}. If the \meta{fpexpr}
+% is an integer between $-0$ and $3248$ included, the result is finite
+% and correctly rounded. Larger positive integers give $+\infty$ with
+% \enquote{overflow}, while $|fact(|{+\infty}|)|=+\infty$ and
+% $|fact(nan)|=|nan|$ with no exception. All other inputs give \nan{}
+% with the \enquote{invalid operation} exception.
+% \end{function}
+%
% \begin{function}[tested = m3fp-expo001]{ln}
% \begin{syntax}
% \cs{fp_eval:n} \{ |ln(| \meta{fpexpr} |)| \}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
index 2052e2010d2..16d8299ec8f 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
index 947a91fa8ab..577a66a44fc 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -63,10 +63,30 @@
% \begin{syntax}
% \cs{int_eval:n} \Arg{integer expression}
% \end{syntax}
-% Evaluates the \meta{integer expression}, expanding any
-% integer and token list variables within the \meta{expression}
-% to their content (without requiring \cs{int_use:N}/\cs{tl_use:N})
-% and applying the standard mathematical rules. For example both
+% Evaluates the \meta{integer expression} and leaves the result in the
+% input stream as an integer denotation: for positive results an
+% explicit sequence of decimal digits not starting with~\texttt{0},
+% for negative results \texttt{-}~followed by such a sequence, and
+% \texttt{0}~for zero. The \meta{integer expression} should consist,
+% after expansion, of \texttt{+}, \texttt{-}, \texttt{*}, \texttt{/},
+% \texttt{(}, \texttt{)} and of course integer operands. The result
+% is calculated by applying standard mathematical rules with the
+% following peculiarities:
+% \begin{itemize}
+% \item \texttt{/} denotes division rounded to the closest integer with
+% ties rounded away from zero;
+% \item there is an error and the overall expression evaluates to zero
+% whenever the absolute value of any intermediate result exceeds
+% $2^{31}-1$, except in the case of scaling operations
+% $a$\texttt{*}$b$\texttt{/}$c$, for which $a$\texttt{*}$b$ may be
+% arbitrarily large;
+% \item parentheses may not appear after unary \texttt{+} or
+% \texttt{-}, namely placing \texttt{+(} or \texttt{-(} at the start
+% of an expression or after \texttt{+}, \texttt{-}, \texttt{*},
+% \texttt{/} or~\texttt{(} leads to an error.
+% \end{itemize}
+% Each integer operand can be either an integer variable (with no need
+% for \cs{int_use:N}) or an integer denotation. For example both
% \begin{verbatim}
% \int_eval:n { 5 + 4 * 3 - ( 3 + 4 * 5 ) }
% \end{verbatim}
@@ -76,21 +96,27 @@
% \tl_set:Nn \l_my_tl { 5 }
% \int_new:N \l_my_int
% \int_set:Nn \l_my_int { 4 }
-% \int_eval:n { \l_my_tl + \l_my_int * 3 - ( 3 + 4 * 5 ) }
+% \int_eval:n { \l_my_tl + \l_my_int * 3 - ( 3 + 4 * 5 ) }
% \end{verbatim}
-% both evaluate to \( -6 \). The \Arg{integer expression} may
-% contain the operators \texttt{+}, \texttt{-}, \texttt{*} and
-% \texttt{/}, along with parenthesis \texttt{(} and \texttt{)}.
-% Any functions within the expressions should expand to an
-% \meta{integer denotation}: a sequence of a sign and digits matching
-% the regex |\-?[0-9]+|).
-% After expansion \cs{int_eval:n} yields an \meta{integer denotation}
-% which is left in the input stream.
+% evaluate to $-6$ because \cs[no-index]{l_my_tl} expands to the
+% integer denotation~|5|. As the \meta{integer expression} is fully
+% expanded from left to right during evaluation, fully expandable and
+% restricted-expandable functions can both be used, and \cs{exp_not:n}
+% and its variants have no effect while \cs{exp_not:N} may incorrectly
+% interrupt the expression.
% \begin{texnote}
% Exactly two expansions are needed to evaluate \cs{int_eval:n}.
% The result is \emph{not} an \meta{internal integer}, and therefore
% requires suitable termination if used in a \TeX{}-style integer
% assignment.
+%
+% As all \TeX{} integers, integer operands can also be dimension or
+% skip variables, converted to integers in~\texttt{sp}, or octal
+% numbers given as \texttt{'} followed by digits other than
+% \texttt{8} and \texttt{9}, or hexadecimal numbers given as
+% |"| followed by digits or upper case letters from
+% \texttt{A} to~\texttt{F}, or the character code of some character
+% or one-character control sequence, given as \texttt{`}\meta{char}.
% \end{texnote}
% \end{function}
%
@@ -100,9 +126,12 @@
% \end{syntax}
% Evaluates the \meta{integer expression} as described for
% \cs{int_eval:n}. The end of the expression is the first token
-% encountered that cannot form part of such an expression.
-% If that token is \cs{scan_stop:} it is removed, otherwise not.
-% Spaces do \emph{not} terminate the expression.
+% encountered that cannot form part of such an expression. If that
+% token is \cs{scan_stop:} it is removed, otherwise not. Spaces do
+% \emph{not} terminate the expression. However, spaces terminate
+% explict integers, and this may terminate the expression: for
+% instance, \cs{int_eval:w} \verb*|1 + 1 9| expands to \texttt{29}
+% since the digit~\texttt{9} is not part of the expression.
% \end{function}
%
% \begin{function}[EXP, updated = 2012-09-26]{\int_abs:n}
@@ -698,9 +727,13 @@
% \cs{int_to_roman:n} \Arg{integer expression}
% \end{syntax}
% Places the value of the \meta{integer expression} in the input
-% stream as Roman numerals, either lower case (\cs{int_to_roman:n})
-% or upper case (\cs{int_to_Roman:n}). The Roman numerals are letters
-% with category code $11$ (letter).
+% stream as Roman numerals, either lower case (\cs{int_to_roman:n}) or
+% upper case (\cs{int_to_Roman:n}). If the value is negative or zero,
+% the output is empty. The Roman numerals are letters with category
+% code $11$ (letter). The letters used are |mdclxvi|, repeated as
+% needed: the notation with bars (such as $\bar{\mbox{v}}$ for $5000$)
+% is \emph{not} used. For instance \cs{int_to_roman:n} |{| 8249 |}|
+% expands to |mmmmmmmmccxlix|.
% \end{function}
%
% \section{Converting from other formats to integers}
@@ -2557,75 +2590,6 @@
% \end{variable}
% \end{variable}
%
-% \subsection{Deprecated}
-%
-% \begin{variable}[deprecated = 2019-12-31]
-% {
-% \c_zero, \c_one, \c_two, \c_three, \c_four, \c_five, \c_six,
-% \c_seven, \c_eight, \c_nine, \c_ten, \c_eleven, \c_twelve,
-% \c_thirteen, \c_fourteen, \c_fifteen, \c_sixteen, \c_thirty_two,
-% \c_one_hundred, \c_two_hundred_fifty_five,
-% \c_two_hundred_fifty_six, \c_one_thousand, \c_ten_thousand,
-% }
-% \begin{macro}{\@@_deprecated_constants:nn}
-% Constants that are now deprecated. By default define them with
-% \cs{int_const:Nn}. To deprecate them call for instance
-% \cs{__kernel_deprecation_error:Nnn} \cs{c_zero} |{0}|
-% |{2019-12-31}|. To redefine them (locally), use
-% \cs{@@_constdef:Nw}, with an \cs{exp_not:N} construction because the
-% constants themselves are outer at that point.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_deprecated_constants:nn #1#2
- {
- #1 \c_zero { 0 } #2
- #1 \c_one { 1 } #2
- #1 \c_two { 2 } #2
- #1 \c_three { 3 } #2
- #1 \c_four { 4 } #2
- #1 \c_five { 5 } #2
- #1 \c_six { 6 } #2
- #1 \c_seven { 7 } #2
- #1 \c_eight { 8 } #2
- #1 \c_nine { 9 } #2
- #1 \c_ten { 10 } #2
- #1 \c_eleven { 11 } #2
- #1 \c_twelve { 12 } #2
- #1 \c_thirteen { 13 } #2
- #1 \c_fourteen { 14 } #2
- #1 \c_fifteen { 15 } #2
- #1 \c_sixteen { 16 } #2
- #1 \c_thirty_two { 32 } #2
- #1 \c_one_hundred { 100 } #2
- #1 \c_two_hundred_fifty_five { 255 } #2
- #1 \c_two_hundred_fifty_six { 256 } #2
- #1 \c_one_thousand { 1000 } #2
- #1 \c_ten_thousand { 10000 } #2
- }
-\@@_deprecated_constants:nn { \int_const:Nn } { }
-\__kernel_deprecation_code:nn
- {
- \@@_deprecated_constants:nn
- { \__kernel_deprecation_error:Nnn } { { 2019-12-31 } }
- }
- {
- \@@_deprecated_constants:nn
- {
- \exp_after:wN \use:nnn
- \exp_after:wN \@@_constdef:Nw \exp_not:N
- }
- { \exp_stop_f: }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{variable}
-%
-% \begin{macro}[deprecated = 2019-12-31]{\@@_value:w}
-% Made public.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_value:w \int_value:w
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
index 43074d8f92b..53abc1853c0 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
index 7499ddd923f..72834cf9bdf 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -404,14 +404,6 @@
% because that would interfere with the action of the conditional.
% \end{function}
%
-% \begin{function}{\__kernel_patch_deprecation:nnNNpn}
-% \begin{syntax}
-% \cs{__kernel_patch_deprecation:nnNNpn} \Arg{before} \Arg{after}
-% \meta{definition} \meta{function}\meta{parameters} \Arg{type} \Arg{code}
-% \end{syntax}
-% Similar to \cs{__kernel_patch:nnNNpn} for deprecated functions.
-% \end{function}
-%
% \begin{function}
% {\__kernel_patch_args:nNNpn, \__kernel_patch_conditional_args:nNNpnn}
% \begin{syntax}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
index 062880a45c4..cafd46ec777 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -305,16 +305,16 @@
% Specifies that the \meta{key} path should inherit the keys listed
% as \meta{parents}. For example, after setting
% \begin{verbatim}
-% \keys_define:n { foo } { test .code:n = \tl_show:n {#1} }
-% \keys_define:n { } { bar .inherit:n = foo }
+% \keys_define:nn { foo } { test .code:n = \tl_show:n {#1} }
+% \keys_define:nn { } { bar .inherit:n = foo }
% \end{verbatim}
% setting
% \begin{verbatim}
-% \keys_set:n { bar } { test = a }
+% \keys_set:nn { bar } { test = a }
% \end{verbatim}
% will be equivalent to
% \begin{verbatim}
-% \keys_set:n { foo } { test = a }
+% \keys_set:nn { foo } { test = a }
% \end{verbatim}
% \end{function}
%
@@ -2478,14 +2478,10 @@
\exp_after:wN { \l_keys_value_tl }
}
{
- \bool_if:NTF \l_@@_only_known_bool
- { \@@_store_unused: }
- {
- \cs_if_exist:cTF
- { \c_@@_inherit_root_tl \@@_parent:o \l_keys_path_tl }
- { \@@_execute_inherit: }
- { \@@_execute_unknown: }
- }
+ \cs_if_exist:cTF
+ { \c_@@_inherit_root_tl \@@_parent:o \l_keys_path_tl }
+ { \@@_execute_inherit: }
+ { \@@_execute_unknown: }
}
}
% \end{macrocode}
@@ -2512,15 +2508,19 @@
}
\cs_new_protected:Npn \@@_execute_unknown:
{
- \cs_if_exist:cTF
- { \c_@@_code_root_tl \l_@@_module_tl / unknown }
+ \bool_if:NTF \l_@@_only_known_bool
+ { \@@_store_unused: }
{
- \cs:w \c_@@_code_root_tl \l_@@_module_tl / unknown
- \exp_after:wN \cs_end: \exp_after:wN { \l_keys_value_tl }
- }
- {
- \__kernel_msg_error:nnxx { kernel } { key-unknown }
- { \l_keys_path_tl } { \l_@@_module_tl }
+ \cs_if_exist:cTF
+ { \c_@@_code_root_tl \l_@@_module_tl / unknown }
+ {
+ \cs:w \c_@@_code_root_tl \l_@@_module_tl / unknown
+ \exp_after:wN \cs_end: \exp_after:wN { \l_keys_value_tl }
+ }
+ {
+ \__kernel_msg_error:nnxx { kernel } { key-unknown }
+ { \l_keys_path_tl } { \l_@@_module_tl }
+ }
}
}
\cs_new:Npn \@@_execute:nn #1#2
@@ -2536,7 +2536,7 @@
% When there is no relative path, things here are easy: just save the key
% name and value. When we are working with a relative path, first we
% need to turn it into a string: that can't happen earlier as we need
-% to store |\q_no_value|. Then, use a standard delimited approach to fish
+% to store \cs{q_no_value}. Then, use a standard delimited approach to fish
% out the partial path.
% \begin{macrocode}
\cs_new_protected:Npn \@@_store_unused:
@@ -2706,7 +2706,7 @@
{
\exp_args:Nnf \msg_show_item_unbraced:nn { code }
{
- \exp_args:Nc \token_get_replacement_spec:N
+ \exp_args:Nc \cs_replacement_spec:N
{
\c_@@_code_root_tl
\@@_trim_spaces:n { #2 / #3 }
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
index a9a52583115..077c4f066c0 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -279,22 +279,6 @@
}
% \end{macrocode}
%
-% \subsection{Deprecated functions}
-%
-% \begin{macro}[EXP, deprecated = 2019-12-31]{\lua_now_x:n, \lua_escape_x:n}
-% \begin{macro}[deprecated = 2019-12-31]{\lua_shipout_x:n}
-% For removal after 2019-12-31.
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \lua_now:e }
-\cs_new:Npn \lua_now_x:n #1 { \@@_now:n {#1} }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \lua_escape:e }
-\cs_new:Npn \lua_escape_x:n #1 { \@@_escape:n {#1} }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \lua_shipout_e:n }
-\cs_new_protected:Npn \lua_shipout_x:n #1 { \@@_shipout:n {#1} }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
% \begin{macrocode}
%</tex>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
index 72bfd68be88..9eefca2a6f6 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -1699,11 +1699,6 @@
LaTeX~has~been~asked~to~use~a~control~sequence~'#1':\\
this~has~not~been~defined~yet.
}
-\__kernel_msg_new:nnn { kernel } { deprecated-command }
- {
- The~deprecated~command~'#2'~has~been~or~will~be~removed~on~#1.
- \tl_if_empty:nF {#3} { ~Use~instead~'#3'. }
- }
\__kernel_msg_new:nnnn { kernel } { empty-search-pattern }
{ Empty~search~pattern. }
{
@@ -1757,7 +1752,7 @@
Only~expandable~tests~can~have~a~predicate~version.
}
\__kernel_msg_new:nnn { kernel } { randint-backward-range }
- { Bounds~ordered~backwards~in~\int_rand:nn {#1}~{#2}. }
+ { Bounds~ordered~backwards~in~\iow_char:N\\int_rand:nn~{#1}~{#2}. }
\__kernel_msg_new:nnnn { kernel } { conditional-form-unknown }
{ Conditional~form~'#1'~for~function~'#2'~unknown. }
{
@@ -1923,7 +1918,7 @@
\__kernel_msg_new:nnn { kernel } { misused-prop }
{ A~property~list~was~misused. }
\__kernel_msg_new:nnn { kernel } { negative-replication }
- { Negative~argument~for~\prg_replicate:nn. }
+ { Negative~argument~for~\iow_char:N\\prg_replicate:nn. }
\__kernel_msg_new:nnn { kernel } { prop-keyval }
{ Missing/extra~'='~in~'#1'~(in~'..._keyval:Nn') }
\__kernel_msg_new:nnn { kernel } { unknown-comparison }
@@ -2034,15 +2029,21 @@
% The command built from the csname
% \cs{c_@@_text_prefix_tl} |LaTeX / #1 / #2|
% takes four arguments and builds the error text, which is fed to
-% \cs{@@_expandable_error:n}.
+% \cs{@@_expandable_error:n} with appropriate expansion: just as for
+% usual messages the arguments are first turned to strings, then the
+% message is fully expanded.
% \begin{macrocode}
+\exp_args_generate:n { oooo }
\cs_new:Npn \__kernel_msg_expandable_error:nnnnnn #1#2#3#4#5#6
{
- \exp_args:Nf \@@_expandable_error:n
+ \exp_args:Ne \@@_expandable_error:n
{
- \exp_args:NNc \exp_after:wN \exp_stop_f:
+ \exp_args:Nc \exp_args:Noooo
{ \c_@@_text_prefix_tl LaTeX / #1 / #2 }
- {#3} {#4} {#5} {#6}
+ { \tl_to_str:n {#3} }
+ { \tl_to_str:n {#4} }
+ { \tl_to_str:n {#5} }
+ { \tl_to_str:n {#6} }
}
}
\cs_new:Npn \__kernel_msg_expandable_error:nnnnn #1#2#3#4#5
@@ -2072,95 +2073,6 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[deprecated = 2019-12-31]{\msg_log:n, \msg_term:n}
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \iow_log:n }
-\cs_new_protected:Npn \msg_log:n #1
- {
- \iow_log:n { ................................................. }
- \iow_wrap:nnnN { . ~ #1} { . ~ } { } \iow_log:n
- \iow_log:n { ................................................. }
- }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \iow_term:n }
-\cs_new_protected:Npn \msg_term:n #1
- {
- \iow_term:n { ************************************************* }
- \iow_wrap:nnnN { * ~ #1} { * ~ } { } \iow_term:n
- \iow_term:n { ************************************************* }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[deprecated = 2019-12-31]{\msg_interrupt:nnn}
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { [Defined~error~message] }
-\cs_new_protected:Npn \msg_interrupt:nnn #1#2#3
- {
- \tl_if_empty:nTF {#3}
- {
- \@@_old_interrupt_wrap:nn { \\ \c_@@_no_info_text_tl }
- {#1 \\\\ #2 \\\\ \c_@@_continue_text_tl }
- }
- {
- \@@_old_interrupt_wrap:nn { \\ #3 }
- {#1 \\\\ #2 \\\\ \c_@@_help_text_tl }
- }
- }
-\cs_new_protected:Npn \@@_old_interrupt_wrap:nn #1#2
- {
- \iow_wrap:nnnN {#1} { | ~ } { } \@@_old_interrupt_more_text:n
- \iow_wrap:nnnN {#2} { ! ~ } { } \@@_old_interrupt_text:n
- }
-\cs_new_protected:Npn \@@_old_interrupt_more_text:n #1
- {
- \exp_args:Nx \tex_errhelp:D
- {
- |'''''''''''''''''''''''''''''''''''''''''''''''
- #1 \iow_newline:
- |...............................................
- }
- }
-\group_begin:
- \char_set_lccode:nn {`\{} {`\ }
- \char_set_lccode:nn {`\}} {`\ }
- \char_set_lccode:nn {`\&} {`\!}
- \char_set_catcode_active:N \&
-\tex_lowercase:D
- {
- \group_end:
- \cs_new_protected:Npn \@@_old_interrupt_text:n #1
- {
- \iow_term:x
- {
- \iow_newline:
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- \iow_newline:
- !
- }
- \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J }
- {
- \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 }
- {
- \group_begin:
- \cs_set_protected:Npn &
- {
- \tex_errmessage:D
- {
- #1
- \use_none:n
- { ............................................ }
- }
- }
- \exp_after:wN
- \group_end:
- &
- }
- }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
index 07c5a4e47a0..77a3a07df45 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
index c216c6dba78..5e74f2df7d6 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -1616,47 +1616,6 @@
% \end{macro}
% \end{macro}
%
-% \subsection{Deprecated functions}
-%
-% \begin{macro}[deprecated = 2019-12-31]{\@@_break_point:Nn}
-% \begin{macro}[deprecated = 2019-12-31]{\@@_break_point:}
-% \begin{macro}[deprecated = 2019-12-31]{\@@_map_break:Nn}
-% \begin{macro}[deprecated = 2019-12-31]{\@@_break:}
-% \begin{macro}[deprecated = 2019-12-31]{\@@_break:n}
-% Made public, but used by a few third-parties. It's not possible to
-% perfectly support a mixture of \cs{@@_map_break:Nn} and
-% \cs{prg_map_break:Nn} because they use different delimiters. The
-% following code only breaks if someone tries to break from two
-% \enquote{old-style} \cs{@@_map_break:Nn} \ldots{}
-% \cs{@@_break_point:Nn} mappings in one go. Basically, the
-% \cs{@@_map_break:Nn} converts a single \cs{@@_break_point:Nn} to
-% \cs{prg_break_point:Nn}, and that delimiter had better be the right
-% one. Then we call \cs{prg_map_break:Nn} which may end up breaking
-% intermediate looks in the (unbraced) argument |#1|. It is essential
-% to define the |break_point| functions before the corresponding
-% |break| functions: otherwise \cs{debug_on:n} |{deprecation}|
-% \cs{debug_off:n} |{deprecation}| would break when trying to restore
-% the definitions because they would involve deprecated commands whose
-% definition has not yet been restored.
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break_point:Nn }
-\cs_new:Npn \@@_break_point:Nn { \prg_break_point:Nn }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break_point: }
-\cs_new:Npn \@@_break_point: { \prg_break_point: }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_map_break:Nn }
-\cs_new:Npn \@@_map_break:Nn #1 \@@_break_point:Nn
- { \prg_map_break:Nn #1 \prg_break_point:Nn }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break: }
-\cs_new:Npn \@@_break: #1 \@@_break_point: { }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break:n }
-\cs_new:Npn \@@_break:n #1#2 \@@_break_point: {#1}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
index b3f70773c4c..d83ea0f4ce2 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -216,6 +216,14 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}[EXP]{\prop_count:N, \prop_count:c}
+% \begin{syntax}
+% \cs{prop_count:N} \meta{property list}
+% \end{syntax}
+% Leaves the number of key--value pairs in the \meta{property list} in
+% the input stream as an \meta{integer denotation}.
+% \end{function}
+%
% \section{Modifying property lists}
%
% \begin{function}[added = 2012-05-12]
@@ -872,6 +880,27 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}[EXP]{\prop_count:N, \prop_count:c}
+% \begin{macro}[EXP]{\@@_count:nn}
+% Counting the key--value pairs in a property list is done using the
+% same approach as for other count functions: turn each entry into a
+% \texttt{+1} then use integer evaluation to actually do the
+% mathematics.
+% \begin{macrocode}
+\cs_new:Npn \prop_count:N #1
+ {
+ \int_eval:n
+ {
+ 0
+ \prop_map_function:NN #1 \@@_count:nn
+ }
+ }
+\cs_new:Npn \@@_count:nn #1#2 { + 1 }
+\cs_generate_variant:Nn \prop_count:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}[TF, tested = m3prop004]
% {\prop_pop:NnN, \prop_pop:cnN, \prop_gpop:NnN, \prop_gpop:cnN}
% Popping an item from a property list, keeping track of whether
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
index c3c45583597..eb50637c9a0 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
index 5fab54fbcc7..cd8ecf7c4aa 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
index 75b815fcd2e..052213d3aef 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
index 12876daaa36..1f23ab65c23 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
index a41b30fda8a..d78f29d838d 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -742,7 +742,7 @@
% ~~~~~~\meta{extra arguments}\\
% ~~|}|\\
% \cs{@@_loop:wNn}~\ldots{}~\meta{prepared tokens}\\
-% ~~\meta{end-loop}~|{}|~|\q_stop|
+% ~~\meta{end-loop}~|{}|~\cs{q_stop}
% \end{quote}
% In this example, which matches the structure of
% \cs{@@_quick_split_i:NnnnnNn} and a few other functions below, the
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
index 028c89dce77..e97e0b190ec 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -791,6 +791,14 @@
% Displays the content of the \meta{str~var} on the terminal.
% \end{function}
%
+% \begin{function}[added = 2019-02-15]
+% {\str_log:N, \str_log:c, \str_log:n}
+% \begin{syntax}
+% \cs{str_log:N} \meta{str~var}
+% \end{syntax}
+% Writes the content of the \meta{str~var} in the log file.
+% \end{function}
+%
% \section{Constant token lists}
%
% \begin{variable}[added = 2015-09-19]
@@ -1942,36 +1950,15 @@
% \subsection{Viewing strings}
%
% \begin{macro}{\str_show:n, \str_show:N, \str_show:c}
+% \begin{macro}{\str_log:n, \str_log:N, \str_log:c}
% Displays a string on the terminal.
% \begin{macrocode}
\cs_new_eq:NN \str_show:n \tl_show:n
\cs_new_eq:NN \str_show:N \tl_show:N
\cs_generate_variant:Nn \str_show:N { c }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Deprecated functions}
-%
-% \begin{macro}[EXP, deprecated = 2019-12-31, noTF]{\str_case_x:nn}
-% \begin{macro}[EXP, deprecated = 2019-12-31, pTF]{\str_if_eq_x:nn}
-% For removal after 2019-12-31.
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nn }
-\cs_new:Npn \str_case_x:nn { \str_case_e:nn }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nnT }
-\cs_new:Npn \str_case_x:nnT { \str_case_e:nnT }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nnF }
-\cs_new:Npn \str_case_x:nnF { \str_case_e:nnF }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nnTF }
-\cs_new:Npn \str_case_x:nnTF { \str_case_e:nnTF }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq_p:ee }
-\cs_new:Npn \str_if_eq_x_p:nn { \str_if_eq_p:ee }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq:eeT }
-\cs_new:Npn \str_if_eq_x:nnT { \str_if_eq:eeT }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq:eeF }
-\cs_new:Npn \str_if_eq_x:nnF { \str_if_eq:eeF }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq:eeTF }
-\cs_new:Npn \str_if_eq_x:nnTF { \str_if_eq:eeTF }
+\cs_new_eq:NN \str_log:n \tl_log:n
+\cs_new_eq:NN \str_log:N \tl_log:N
+\cs_generate_variant:Nn \str_log:N { c }
% \end{macrocode}
% \end{macro}
% \end{macro}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
index c1d0fa59975..b2000f8f1b7 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
index 7938652595f..987b7b23d45 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -1094,23 +1094,6 @@
}
% \end{macrocode}
%
-% \subsection{Deprecated functions}
-%
-% \begin{macro}[deprecated = 2019-12-31]
-% {\tl_show_analysis:N, \tl_show_analysis:n}
-% Simple renames.
-% \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 }
- { \tl_analysis_show:N }
-\cs_new_protected:Npn \tl_show_analysis:N #1
- { \tl_analysis_show:N #1 }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 }
- { \tl_analysis_show:n }
-\cs_new_protected:Npn \tl_show_analysis:n #1
- { \tl_analysis_show:n {#1} }
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
index 1c8867340c2..ec82eca63f0 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -700,6 +700,16 @@
% giving an \meta{integer denotation}.
% \end{function}
%
+% \begin{function}[EXP, added = 2019-02-25]{\tl_count_tokens:n}
+% \begin{syntax}
+% \cs{tl_count_tokens:n} \Arg{tokens}
+% \end{syntax}
+% Counts the number of \TeX{} tokens in the \meta{tokens} and leaves
+% this information in the input stream. Every token, including spaces and
+% braces, contributes one to the total; thus for instance, the token count of
+% |a~{bc}| is $6$.
+% \end{function}
+%
% \begin{function}[updated = 2012-01-08, EXP]
% {\tl_reverse:n, \tl_reverse:V, \tl_reverse:o}
% \begin{syntax}
@@ -822,7 +832,7 @@
% \begin{texnote}
% The result is returned within \cs{exp_not:n}, which means that the
% token list does not expand further when appearing in an
-% \texttt{x}-type argument expansion.
+% \texttt{x}-type or \texttt{e}-type argument expansion.
% \end{texnote}
% \end{function}
%
@@ -1149,7 +1159,7 @@
%
% \begin{variable}[added = 2017-11-14]{\c_novalue_tl}
% A marker for the absence of an argument. This constant |tl| can safely
-% be typeset (\emph{cf.}~|\q_nil|), with the result being |-NoValue-|.
+% be typeset (\emph{cf.}~\cs{q_nil}), with the result being |-NoValue-|.
% It is important to note that \cs{c_novalue_tl} is constructed such that it
% will \emph{not} match the simple text input |-NoValue-|, \emph{i.e.}
% that
@@ -1571,6 +1581,10 @@
%
% The two \cs{if_false:} \ldots{} \cs{fi:} are there to prevent
% alignment tabs to cause a change of tabular cell while rescanning.
+% We put the \enquote{opening} one after \cs{group_begin:} so that if
+% one accidentally \texttt{f}-expands \cs{tl_set_rescan:Nnn} braces
+% remain balanced. This is essential in \texttt{e}-type arguments
+% when \tn{expanded} is not available.
% \begin{macrocode}
\cs_new_protected:Npn \tl_set_rescan:Nnn
{ \@@_set_rescan:NNnn \tl_set:No }
@@ -1584,8 +1598,8 @@
}
\cs_new_protected:Npn \@@_set_rescan:NNnn #1#2#3#4
{
- \if_false: { \fi:
\group_begin:
+ \if_false: { \fi:
\int_set_eq:NN \tex_tracingnesting:D \c_zero_int
\exp_args:No \tex_everyeof:D { \c_@@_rescan_marker_tl }
\int_compare:nNnT \tex_endlinechar:D = { 32 }
@@ -1804,7 +1818,7 @@
% \meta{pattern}~|#6| then we can use it as the \meta{delimiter}
% through \cs{@@_replace_auxii:nNNNnn} |{#1}|. Otherwise, we end up
% calling \cs{@@_replace:NnNNNnn} repeatedly with the first two
-% arguments |\q_mark| |{?}|, |\?| |{??}|, |\??| |{???}|, and so on,
+% arguments \cs{q_mark} |{?}|, |\?| |{??}|, |\??| |{???}|, and so on,
% until |#6|~does not contain the control sequence~|#1|, which we take
% as our~\meta{A}. The argument~|#2| only serves to collect~|?|
% characters for~|#1|. Note that the order of the tests means that
@@ -2126,9 +2140,12 @@
% groups makes the test work also for empty arguments.
% The \cs{if_false:} constructions are a faster way to do
% \cs{group_align_safe_begin:} and \cs{group_align_safe_end:}.
+% The \cs{scan_stop:} ensures that \texttt{f}-expanding
+% \cs{tl_if_in:nn} does not lead to unbalanced braces.
% \begin{macrocode}
\prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 { T , F , TF }
{
+ \scan_stop:
\if_false: { \fi:
\cs_set:Npn \@@_tmp:w ##1 #2 { }
\tl_if_empty:oTF { \@@_tmp:w #1 {} {} #2 }
@@ -2427,6 +2444,36 @@
% \end{macro}
% \end{macro}
%
+%
+% \begin{macro}[EXP]{\tl_count_tokens:n}
+% \begin{macro}[EXP]{\@@_act_count_normal:nN,
+% \@@_act_count_group:nn, \@@_act_count_space:n}
+% 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_int}).
+% Somewhat a hack!
+% \begin{macrocode}
+\cs_new:Npn \tl_count_tokens:n #1
+ {
+ \int_eval:n
+ {
+ \@@_act:NNNnn
+ \@@_act_count_normal:nN
+ \@@_act_count_group:nn
+ \@@_act_count_space:n
+ { }
+ {#1}
+ }
+ }
+\cs_new:Npn \@@_act_count_normal:nN #1 #2 { 1 + }
+\cs_new:Npn \@@_act_count_space:n #1 { 1 + }
+\cs_new:Npn \@@_act_count_group:nn #1 #2
+ { 2 + \tl_count_tokens:n {#2} + }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\tl_reverse_items:n}
% \begin{macro}{\@@_reverse_items:nwNwn}
% \begin{macro}{\@@_reverse_items:wn}
@@ -2945,13 +2992,11 @@
% \end{macro}
%
% \begin{macro}[EXP,pTF]{\tl_if_head_is_group:n}
-% Pass the first token of |#1| through \cs{token_to_str:N},
-% then check for the brace balance. The extra \texttt{?}
-% caters for an empty argument.\footnote{Bruno: this could
-% be made faster, but we don't: if we hope to ever have
-% an e-type argument, we need all brace \enquote{tricks}
-% to happen in one step of expansion, keeping the token
-% list brace balanced at all times.}
+% Pass the first token of |#1| through \cs{token_to_str:N}, then check
+% for the brace balance. The extra \texttt{?} caters for an empty
+% argument. This could be made faster, but we need all brace tricks
+% to happen in one step of expansion, keeping the token list brace
+% balanced at all times.
% \begin{macrocode}
\prg_new_conditional:Npnn \tl_if_head_is_group:n #1 { p , T , F , TF }
{
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
index f3338550ffb..49bdcfc632f 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -931,66 +931,6 @@
% (as appropriate to the result of the test).
% \end{function}
%
-% \section{Decomposing a macro definition}
-%
-% These functions decompose \TeX{} macros into their constituent
-% parts: if the \meta{token} passed is not a macro then no decomposition
-% can occur. In the latter case, all three functions leave \cs{scan_stop:}
-% in the input stream.
-%
-% \begin{function}[EXP]{\token_get_arg_spec:N}
-% \begin{syntax}
-% \cs{token_get_arg_spec:N} \meta{token}
-% \end{syntax}
-% If the \meta{token} is a macro, this function leaves
-% the primitive \TeX{} argument specification in input stream as
-% a string of tokens of category code $12$ (with spaces having category
-% code $10$). Thus for example for a token \cs{next} defined by
-% \begin{verbatim}
-% \cs_set:Npn \next #1#2 { x #1 y #2 }
-% \end{verbatim}
-% leaves |#1#2| in the input stream. If the \meta{token} is
-% not a macro then \cs{scan_stop:} is left in the input stream.
-% \begin{texnote}
-% If the arg~spec. contains the string |->|, then the |spec| function
-% produces incorrect results.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}[EXP]{\token_get_replacement_spec:N}
-% \begin{syntax}
-% \cs{token_get_replacement_spec:N} \meta{token}
-% \end{syntax}
-% If the \meta{token} is a macro, this function leaves
-% the replacement text in input stream as
-% a string of tokens of category code $12$ (with spaces having category
-% code $10$). Thus for example for a token \cs{next} defined by
-% \begin{verbatim}
-% \cs_set:Npn \next #1#2 { x #1~y #2 }
-% \end{verbatim}
-% leaves \verb|x#1 y#2| in the input stream. If the \meta{token} is
-% not a macro then \cs{scan_stop:} is left in the input stream.
-% \begin{texnote}
-% If the arg~spec. contains the string |->|, then the |spec| function
-% produces incorrect results.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}[EXP]{\token_get_prefix_spec:N}
-% \begin{syntax}
-% \cs{token_get_prefix_spec:N} \meta{token}
-% \end{syntax}
-% If the \meta{token} is a macro, this function leaves
-% the \TeX{} prefixes applicable in input stream as
-% a string of tokens of category code $12$ (with spaces having category
-% code $10$). Thus for example for a token \cs{next} defined by
-% \begin{verbatim}
-% \cs_set:Npn \next #1#2 { x #1~y #2 }
-% \end{verbatim}
-% leaves |\long| in the input stream. If the \meta{token} is
-% not a macro then \cs{scan_stop:} is left in the input stream
-% \end{function}
-%
% \section{Description of all possible tokens}
% \label{sec:l3token:all-tokens}
%
@@ -2465,59 +2405,6 @@
% \end{macrocode}
% \end{macro}
%
-% \subsection{Decomposing a macro definition}
-%
-% \begin{macro}{\token_get_prefix_spec:N}
-% \begin{macro}{\token_get_arg_spec:N}
-% \begin{macro}{\token_get_replacement_spec:N}
-% \begin{macro}{\@@_get_prefix_arg_replacement:wN}
-% We sometimes want to test if a
-% control sequence can be expanded to reveal a hidden
-% value. However, we cannot just expand the macro blindly as it may
-% have arguments and none might be present. Therefore we define
-% these functions to pick either the prefix(es), the argument
-% specification, or the replacement text from a macro. All of this
-% information is returned as characters with catcode~$12$. If the
-% token in question isn't a macro, the token \cs{scan_stop:} is
-% returned instead.
-% \begin{macrocode}
-\exp_args:Nno \use:nn
- { \cs_new:Npn \@@_get_prefix_arg_replacement:wN #1 }
- { \tl_to_str:n { macro : } #2 -> #3 \q_stop #4 }
- { #4 {#1} {#2} {#3} }
-\cs_new:Npn \token_get_prefix_spec:N #1
- {
- \token_if_macro:NTF #1
- {
- \exp_after:wN \@@_get_prefix_arg_replacement:wN
- \token_to_meaning:N #1 \q_stop \use_i:nnn
- }
- { \scan_stop: }
- }
-\cs_new:Npn \token_get_arg_spec:N #1
- {
- \token_if_macro:NTF #1
- {
- \exp_after:wN \@@_get_prefix_arg_replacement:wN
- \token_to_meaning:N #1 \q_stop \use_ii:nnn
- }
- { \scan_stop: }
- }
-\cs_new:Npn \token_get_replacement_spec:N #1
- {
- \token_if_macro:NTF #1
- {
- \exp_after:wN \@@_get_prefix_arg_replacement:wN
- \token_to_meaning:N #1 \q_stop \use_iii:nnn
- }
- { \scan_stop: }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
index 333caddbc60..ed6991d49e1 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%