diff options
author | Karl Berry <karl@freefriends.org> | 2019-09-29 21:16:44 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-09-29 21:16:44 +0000 |
commit | cde95caf86c78ec9b7641198abfd0a7768f5100e (patch) | |
tree | dd771c114615e169fe3bde469f39dcac3a7ce074 /Master/texmf-dist/source | |
parent | 35c007d48195f11757c61c71a9a0eb88420dc9d0 (diff) |
l3 (29sep19)
git-svn-id: svn://tug.org/texlive/trunk@52214 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
75 files changed, 3131 insertions, 2616 deletions
diff --git a/Master/texmf-dist/source/latex/l3build/l3build.dtx b/Master/texmf-dist/source/latex/l3build/l3build.dtx index 05979335570..dfaca411872 100644 --- a/Master/texmf-dist/source/latex/l3build/l3build.dtx +++ b/Master/texmf-dist/source/latex/l3build/l3build.dtx @@ -230,7 +230,7 @@ % }^^A % } % -% \date{Released 2019-09-25} +% \date{Released 2019-09-29} % % \maketitle % \tableofcontents diff --git a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx index 0df034cae80..f90bd2f1c46 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -130,7 +130,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3benchmark}{2019-09-19}{} +\ProvidesExplPackage{l3benchmark}{2019-09-28}{} {L3 Experimental benchmarking} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx b/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx index a56585c1ffc..64266fe7816 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -171,7 +171,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3cctab}{2019-09-19}{} +\ProvidesExplPackage{l3cctab}{2019-09-28}{} {L3 Experimental category code tables} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx index 0abd8322126..d6dd271ee25 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -265,7 +265,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3color}{2019-09-19}{} +\ProvidesExplPackage{l3color}{2019-09-28}{} {L3 Experimental color support} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx index 9799c3238ff..30b49526571 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx index f0b7afb1b40..c46f2489e3f 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx index f4bb5eb0224..b6291a32800 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx index 87fda4bf68c..b05e29afe92 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx index f98947f09a9..bbd5c83c66d 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx index 12072fa6786..ee228be271e 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx index 91c0d486448..1137c9d1798 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx index 2a34520ff35..17a225f597c 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx index 0a93ec16ed9..5813b7edf7a 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx @@ -110,7 +110,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -1146,7 +1146,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3draw}{2019-09-19}{} +\ProvidesExplPackage{l3draw}{2019-09-28}{} {L3 Experimental core drawing support} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx index c9e3020084e..08d5ae4f63f 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -241,7 +241,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3graphics}{2019-09-19}{} +\ProvidesExplPackage{l3graphics}{2019-09-28}{} {L3 Experimental graphics inclusion support} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx index a8801c7e469..d3784bb4e2f 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -185,7 +185,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3pdf}{2019-09-19}{} +\ProvidesExplPackage{l3pdf}{2019-09-28}{} {L3 Experimental core PDF support} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx index ab962675930..eb06238f1c0 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx @@ -48,7 +48,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -167,7 +167,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3str-format}{2019-09-19}{} +\ProvidesExplPackage{l3str-format}{2019-09-28}{} {L3 Experimental string formatting} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx index 2663bce59d3..18310b65848 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -100,9 +100,9 @@ % attempted. % \end{function} % -% \begin{function}[added = 2018-07-28]{\sys_shell_get_pwd:N} +% \begin{function}[added = 2018-07-28]{\sys_get_shell_pwd:N} % \begin{syntax} -% \cs{sys_shell_get_pwd:N} \meta{str var} +% \cs{sys_get_shell_pwd:N} \meta{str var} % \end{syntax} % Sets the \meta{str var} to the present working directory (the output of % |pwd| on Unix or |cd| on Windows). Note that on Windows this will contain @@ -136,7 +136,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3sys-shell}{2019-09-19}{} +\ProvidesExplPackage{l3sys-shell}{2019-09-28}{} {L3 Experimental system shell functions} %</package> % \end{macrocode} @@ -300,17 +300,17 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}{\sys_shell_get_pwd:N} +% \begin{macro}{\sys_get_shell_pwd:N} % Getting the path is easy: the main work is avoiding loosing any % information. (This information can be obtained using the recorder file: % that does not require shell escape. However, it's hard to see how it might % be useful without the other file functions.) % \begin{macrocode} -\cs_new_protected:Npx \sys_shell_get_pwd:N #1 +\cs_new_protected:Npx \sys_get_shell_pwd:N #1 { \sys_if_shell_unrestricted:T { - \exp_not:N \sys_shell_get:nnN + \exp_not:N \sys_get_shell:nnN { \sys_if_platform_unix:T { pwd } \sys_if_platform_windows:T { cd } @@ -340,7 +340,7 @@ { \sys_if_shell_unrestricted:T { - \exp_not:N \sys_shell_get:nnN + \exp_not:N \sys_get_shell:nnN { \sys_if_platform_unix:T { ls~-1~ #1 } \sys_if_platform_windows:T { dir~/b~ #1 } diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx index c3d5739f822..b4d0ce465a7 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx @@ -56,7 +56,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -675,7 +675,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xcoffins}{2019-09-19}{} +\ProvidesExplPackage{xcoffins}{2019-09-28}{} {L3 Experimental design level coffins} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx index bdbbe9d4766..06ffe81ab0d 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx @@ -61,7 +61,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -687,7 +687,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3galley}{2019-09-19}{} +\ProvidesExplPackage{l3galley}{2019-09-28}{} {L3 Experimental galley code} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx index 25c393a76ce..cc6da75e0fb 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx @@ -47,7 +47,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -734,7 +734,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xgalley}{2019-09-19}{} +\ProvidesExplPackage{xgalley}{2019-09-28}{} {L3 Experimental galley} \RequirePackage{xparse,xtemplate,l3galley} % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index 9aa2421de31..64cb3935853 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-09-19}% +\def\ExplFileDate{2019-09-28}% %</driver|generic|package> %<*driver> \documentclass[full]{l3doc} @@ -51,7 +51,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -622,6 +622,16 @@ % text of an~\tn{edef}, and the expansion is passed to the function as % a braced token list. Expansion takes place until only unexpandable % tokens are left. |x|-type arguments cannot be nested. +% \item[e] Fully-expanded token or braced token list which does +% not require doubled |#| tokens. This expansions is very similar +% to |x|-type but may be nested and does not require that |#| +% tokens are doubled. +% \item[f] Expanding the first token recursively in a braced token +% list.\\ Almost the same as the |x| type except here the token list +% is expanded fully until the first unexpandable token is found and +% the rest is left unchanged. Note that if this function finds a +% space at the beginning of the argument it gobbles it and does not +% expand the next token. % \item[o] One-level-expanded token or braced token list.\\ % This means that the argument is expanded one level, as by % \tn{expandafter}, and the expansion is passed to the function as a @@ -629,12 +639,6 @@ % token list then only the first token in that list is expanded. % In general, using \texttt{V} should be preferred to using % \texttt{o} for simple variable retrieval. -% \item[f] Expanding the first token recursively in a braced token -% list.\\ Almost the same as the |x| type except here the token list -% is expanded fully until the first unexpandable token is found and -% the rest is left unchanged. Note that if this function finds a -% space at the beginning of the argument it gobbles it and does not -% expand the next token. % \end{description} % % \subsection{Simpler means better} @@ -948,15 +952,10 @@ % These functions can only be used if \pkg{expl3} is loaded with the % \texttt{enable-debug} option. % -% \DescribeOption{driver} -% Selects the driver to be used for color, graphics and related operations that -% are driver-dependent. Options available are +% \DescribeOption{backend} +% Selects the backend to be used for color, graphics and related operations that +% are backend-dependent. Options available are % \begin{itemize}[font = \texttt] -% \item[auto] Let \LaTeX3 determine the correct driver. With DVI output, this -% selects the \texttt{dvips} back-end for \pdfTeX{} and \LuaTeX{}, and -% \texttt{dvipdfmx} for \pTeX{} and \upTeX{}. This is the standard setting. -% \item[latex2e] Use the \pkg{graphics} package to select the driver, rather -% than \LaTeX3 code. % \item[dvips] Use the \texttt{dvips} driver. % \item[dvipdfmx] Use the \texttt{dvipdfmx} driver. % \item[dvisvgm] Use the \texttt{dvisvgm} driver. @@ -1172,64 +1171,6 @@ ]% % \end{macrocode} % -% \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 -% } -% \begin{variable}[int]{\l@expl@options@clist} -% Options to be set up. These have to be done by hand as there is no -% \pkg{expl3} yet: the logging option is needed before loading -% \pkg{l3basics}! Only a minimal set of options are handled here: -% others are left for a proper key--value approach once the kernel is -% loaded. After processing the options we set the -% \texttt{enable-debug} boolean so that the options -% \texttt{check-declarations} and \texttt{log-functions} imply -% \texttt{enable-debug}: otherwise the necessary debugging code would -% not be set up properly. -% \begin{macrocode} -\newcommand\expl@create@bool@option[2]% - {% - \DeclareOption{#1}{\chardef #2=1 }% - \DeclareOption{#1=true}{\chardef #2=1 }% - \DeclareOption{#1=false}{\chardef #2=0 }% - \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 -\let\expl@create@bool@option\@undefined -\chardef\l@expl@enable@debug@bool=0 % -\newcommand*\l@expl@options@clist{}% -\DeclareOption* - {% - \ifx\l@expl@options@clist\@empty - \let\l@expl@options@clist\CurrentOption - \else - \expandafter\expandafter\expandafter\def - \expandafter\expandafter\expandafter\l@expl@options@clist - \expandafter\expandafter\expandafter - {\expandafter\l@expl@options@clist\expandafter,\CurrentOption} - \fi - }% -\ProcessOptions\relax -\ifodd\l@expl@check@declarations@bool - \chardef\l@expl@enable@debug@bool=1 % -\fi -\ifodd\l@expl@log@functions@bool - \chardef\l@expl@enable@debug@bool=1 % -\fi -% \end{macrocode} -% \end{variable} -% \end{variable} -% \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. @@ -1266,245 +1207,86 @@ \fi % \end{macrocode} % -% \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 -% interpreter. The \enquote{faked} options are also included so that any -% erroneous input is mopped up (\emph{e.g.}~\texttt{log-function = -% foo}). The checks on driver choice are set up here, so when actually -% the driver it's a straight forward operation. % \begin{macrocode} -\__kernel_msg_new:nnnn { expl } { wrong-driver } - { Driver~request~inconsistent~with~engine:~using~'#2'~driver. } - { - You~have~requested~driver~'#1',~but~this~is~not~suitable~for~use~with~the~ - active~engine.~LaTeX3~will~use~the~'#2'~driver~instead. - } -\tl_new:N \l__expl_driver_tl -\keys_define:nn { expl } - { - driver .choice:, - driver / auto .code:n = - { - \tl_set:Nx \l__expl_driver_tl - { - \sys_if_engine_xetex:TF - { xdvipdfmx } - { - \sys_if_output_pdf:TF - { pdfmode } - { - \bool_lazy_or:nnTF - { \sys_if_engine_pdftex_p: } - { \sys_if_engine_luatex_p: } - { dvips } - { dvipdfmx } - } - } - } - }, - driver / dvipdfmx .code:n = - { - \tl_set:Nn \l__expl_driver_tl { dvipdfmx } - \sys_if_engine_xetex:TF - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { dvipdfmx } { xdvipdfmx } - \tl_set:Nn \l__expl_driver_tl { xdvipdfmx } - } - { - \sys_if_output_pdf:T - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { dvipdfmx } { pdfmode } - \tl_set:Nn \l__expl_driver_tl { pdfmode } - } - } - }, - driver / dvips .code:n = - { - \tl_set:Nn \l__expl_driver_tl { dvips } - \sys_if_engine_xetex:TF - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { dvips } { xdvipdfmx } - \tl_set:Nn \l__expl_driver_tl { xdvipdfmx } - } - { - \sys_if_output_pdf:T - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { dvips } { pdfmode } - \tl_set:Nn \l__expl_driver_tl { pdfmode } - } - } - }, - driver / dvisvgm .code:n = - { - \tl_set:Nn \l__expl_driver_tl { dvisvgm } - \sys_if_engine_xetex:TF - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { dvips } { xdvipdfmx } - \tl_set:Nn \l__expl_driver_tl { xdvipdfmx } - } - { - \sys_if_output_pdf:T - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { dvips } { pdfmode } - \tl_set:Nn \l__expl_driver_tl { pdfmode } - } - } - }, - driver / latex2e .code:n = - { \tl_set:Nn \l__expl_driver_tl { latex2e } }, - driver / pdfmode .code:n = - { - \tl_set:Nn \l__expl_driver_tl { pdfmode } - \sys_if_engine_xetex:TF - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { pdfmode } { xdvipdfmx } - \tl_set:Nn \l__expl_driver_tl { xdvipdfmx } - } - { - \sys_if_output_pdf:F - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { pdfmode } { dvips } - \tl_set:Nn \l__expl_driver_tl { dvips } - } - } - }, - driver / xdvipdfmx .code:n = - { - \tl_set:Nn \l__expl_driver_tl { xdvipdfmx } - \sys_if_engine_xetex:F - { - \sys_if_output_pdf:TF - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { xdvipdfmx } { pdfmode } - \tl_set:Nn \l__expl_driver_tl { pdfmode } - } - { - \__kernel_msg_error:nnnn { expl } { wrong-driver } - { xdvipdfmx } { dvips } - \tl_set:Nn \l__expl_driver_tl { dvips } - } - } - }, - driver .initial:n = { auto } , - native-drivers .choice:, - native-drivers .default:n = { true }, - native-drivers / false .meta:n = { driver = latex2e }, - native-drivers / true .meta:n = { driver = auto } - } +%<@@=expl> % \end{macrocode} -% Mop up any incorrect settings for the other options. +% +% \begin{variable}{\c_@@_def_ext_tl} +% Needed by \LaTeXe{}. % \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 - } -\keys_set:nV { expl } \l@expl@options@clist +\tl_const:Nn \c_@@_def_ext_tl { def } % \end{macrocode} % \end{variable} -% \end{variable} % -% \begin{macro} -% { -% \box_rotate:Nn, -% \box_resize_to_wd_and_ht_plus_dp:Nnn, -% \box_resize_to_ht_plus_dp:Nn, -% \box_resize_to_wd:Nn, -% \box_scale:Nnn -% } -% For the \LaTeXe{} drivers, -% alter various definitions to use the \pkg{graphics} package -% instead. The package is loaded right at the start of the hook -% as there is otherwise a potential issue with \pkg{(x)color}: see -% \url{http://groups.google.com/group/comp.text.tex/msg/c9de8913c756ef4c}. +% \begin{macro}{\__kernel_sys_configuration_load:n} +% For \LaTeXe{}, option loading uses the built-in functionality: as this +% may be a reload we have to force the issue. % \begin{macrocode} -\str_if_eq:VnTF \l__expl_driver_tl { latex2e } +\cs_new_protected:Npn \__kernel_sys_configuration_load:n #1 { - \tl_gput_left:Nn \@begindocumenthook { \RequirePackage { graphics } } - \__kernel_msg_new:nnnn { box } { clipping-not-available } - { Box~clipping~not~available. } - { - The~\box_clip:N~function~is~only~available~when~loading~expl3~ - with~the~"native-drivers"~option. - } - \cs_set_protected:Npn \box_clip:N #1 - { - \hbox_set:Nn #1 { \box_use:N #1 } - \__kernel_msg_error:nn { box } { clipping-not-available } - } - \cs_set_protected:Npn \box_rotate:Nn #1#2 - { \hbox_set:Nn #1 { \rotatebox {#2} { \box_use:N #1 } } } - \cs_set_protected:Npn \box_resize_to_wd_and_ht_plus_dp:Nnn #1#2#3 - { - \hbox_set:Nn #1 - { - \resizebox * - { \dim_eval:n {#2} } - { \dim_eval:n {#3} } - { \box_use:N #1 } - } - } - \cs_set_protected:Npn \box_resize_to_ht_plus_dp:Nn #1#2 - { - \hbox_set:Nn #1 - { - \resizebox * { ! } { \dim_eval:n {#2} } - { \box_use:N #1 } - } - } - \cs_set_protected:Npn \box_resize_to_wd:Nn #1#2 + \group_begin: + \cs_set_protected:Npn \ProvidesExplFile { - \hbox_set:Nn #1 - { - \resizebox * { \dim_eval:n {#2} } { ! } - { \box_use:N #1 } - } + \char_set_catcode_space:n { `\ } + \ProvidesExplFileAux } - \cs_set_protected:Npn \__box_scale_aux:N #1 + \cs_set_protected:Npn \ProvidesExplFileAux ##1##2##3##4 { - \exp_last_unbraced:Nx \scalebox - { { \fp_use:N \l__box_scale_x_fp } [ \fp_use:N \l__box_scale_y_fp ] } - { \box_use:N #1 } + \group_end: + \ProvidesFile {##1} [ ##2~v##3~##4 ] } - \cs_set_protected:Npn \color_ensure_current: { \set@color } + \cs_undefine:c { ver@ #1 .def } + \@onefilewithoptions {#1} [ ] [ ] + \c_@@_def_ext_tl } % \end{macrocode} % \end{macro} -% For native drivers, just load the appropriate file. As \cs{expl3} syntax -% is already on and the full mechanism is only engaged at the end of the -% loader, \cs{ProvidesExplFile} is temporarily redefined here. +% +% \begin{variable}{\l_@@_options_clist} % \begin{macrocode} +\clist_new:N \l_@@_options_clist +\DeclareOption* + { \clist_put_right:NV \l_@@_options_clist \CurrentOption } +\ProcessOptions \relax +% \end{macrocode} +% \end{variable} +% +% Pretty standard setting creation. +% \begin{macrocode} +\keys_define:nn { sys } { - \group_begin: - \cs_set_protected:Npn \ProvidesExplFile + backend .choices:nn = + { dvipdfmx , dvips , dvisvgm , pdfmode , xdvipdfmx } + { \sys_load_backend:n {#1} } , + check-declarations .code:n = { - \char_set_catcode_space:n { `\ } - \ProvidesExplFileAux - } - \cs_set_protected:Npn \ProvidesExplFileAux #1#2#3#4 + \sys_load_debug: + \debug_on:n { check-declarations } + } , + driver .meta:n = { backend = #1 } , + enable-debug .code:n = + \sys_load_debug: , + log-functions .code:n = { - \group_end: - \ProvidesFile {#1} [ #2~v#3~#4 ] + \sys_load_debug: + \debug_on:n { log-functions } + } , + undo-recent-deprecations .code:n = + { + \sys_load_deprecation: + \bool_gset_true:N \g__kernel_deprecation_undo_recent_bool } - \tl_const:Nn \c__expl_def_ext_tl { def } - \@onefilewithoptions { l3backend- \l__expl_driver_tl } [ ] [ ] - \c__expl_def_ext_tl } % \end{macrocode} % +% \begin{macrocode} +\keys_set:nV { sys } \l_@@_options_clist +\str_if_exist:NF \c_sys_backend_str + { \sys_load_backend:n { } } +% \end{macrocode} +% % \begin{macro}{\@pushfilename, \@popfilename} -% \begin{macro}{\__expl_status_pop:w} +% \begin{macro}{\@@_status_pop:w} % The idea here is to use \LaTeXe{}'s \tn{@pushfilename} and % \tn{@popfilename} to track the current syntax status. This can be % achieved by saving the current status flag at each push to a stack, @@ -1541,14 +1323,14 @@ \__kernel_file_input_pop: \tl_if_empty:NTF \l__expl_status_stack_tl { \ExplSyntaxOff } - { \exp_after:wN \__expl_status_pop:w \l__expl_status_stack_tl \q_stop } + { \exp_after:wN \@@_status_pop:w \l__expl_status_stack_tl \q_stop } } % \end{macrocode} % The pop auxiliary function removes the first item from the stack, % saves the rest of the stack and then does the test. The flag here % is not a proper \texttt{bool}, so a low-level test is used. % \begin{macrocode} -\cs_new_protected:Npn \__expl_status_pop:w #1#2 \q_stop +\cs_new_protected:Npn \@@_status_pop:w #1#2 \q_stop { \tl_set:Nn \l__expl_status_stack_tl {#2} \int_if_odd:nTF {#1} @@ -1639,24 +1421,6 @@ % \end{macrocode} % \end{variable} % -% \begin{variable}[int] -% { -% \l@expl@undo@recent@deprecations@bool , -% \l@expl@check@declarations@bool , -% \l@expl@log@functions@bool , -% \l@expl@enable@debug@bool -% } -% In generic mode, there is no convenient option handling and so instead -% 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 % -% \end{macrocode} -% \end{variable} -% % \begin{macro}{\AtBeginDocument} % \begin{macro}[int]{\expl@AtBeginDocument} % There are a few uses of \cs{AtBeginDocument} in the package code: the @@ -1690,35 +1454,30 @@ \fi % \end{macrocode} % -% For driver loading in generic mode, there are no options: pick the most -% appropriate case! To allow this loading to take place a temporary -% definition of \cs{ProvidesExplFile} is provided +% \begin{macro}{\__kernel_sys_configuration_load:n} +% Very basic. % \begin{macrocode} -\cs_set_protected:Npn \ProvidesExplFile +\cs_new_protected:Npn \__kernel_sys_configuration_load:n #1 { \group_begin: - \char_set_catcode_space:n { `\ } - \ProvidesExplFileAux - } -\cs_set_protected:Npn \ProvidesExplFileAux #1#2#3#4 - { - \group_end: - \iow_log:x { File:~#1~#2~v#3~#4 } + \cs_set_protected:Npn \ProvidesExplFile + { + \char_set_catcode_space:n { `\ } + \ProvidesExplFileAux + } + \cs_set_protected:Npn \ProvidesExplFileAux ##1##2##3##4 + { + \group_end: + \iow_log:x { File:~##1~##2~v##3~##4 } + } + \tex_input:D #1 .def \scan_stop: } -\tex_input:D - l3backend- - \sys_if_engine_xetex:TF - { xdvipdfmx } - { - \bool_lazy_and:nnTF - { \cs_if_exist_p:N \tex_pdfoutput:D } - { \int_compare_p:nNn \tex_pdfoutput:D > 0 } - { pdfmode } - { dvips } - } - .def \scan_stop: -\cs_undefine:N \ProvidesExplFile -\cs_undefine:N \ProvidesExplFileAux +% \end{macrocode} +% \end{macro} +% +% Load the standard back-end. +% \begin{macrocode} +\sys_load_backend:n { } % \end{macrocode} % % For the generic loader, a few final steps to take. Turn of \cs{expl3} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3.ins b/Master/texmf-dist/source/latex/l3kernel/l3.ins index 8affab2c2d5..343d8d7f186 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3.ins +++ b/Master/texmf-dist/source/latex/l3kernel/l3.ins @@ -106,7 +106,7 @@ and all files in that bundle must be distributed together. \from{l3unicode.dtx} {package} \from{l3candidates.dtx} {package} \from{l3legacy.dtx} {package} - \from{l3deprecation.dtx}{package} + \from{l3deprecation.dtx}{package,kernel} } } @@ -136,6 +136,9 @@ and all files in that bundle must be distributed together. \file{l3str-enc-iso885916.def} {\from{l3str-convert.dtx}{iso885916}}% } +\generate{\file{l3debug.def} {\from{l3debug.dtx} {package}}} +\generate{\file{l3deprecation.def}{\from{l3deprecation.dtx}{package,patches}}} + \generate{\file{l3docstrip.tex} {\from{l3docstrip.dtx} {program}}} \generate{\file{l3names.def} {\from{l3names.dtx} {names}}} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx index ea738865357..30f1859170a 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index 19014478169..002e524aa8a 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -1275,6 +1275,24 @@ % execute <false code>. Similar for the other functions. % \end{function} % +% \section{Starting a paragraph} +% +% \begin{function}[added = 2017-07-04]{\mode_leave_vertical:} +% \begin{syntax} +% \cs{mode_leave_vertical:} +% \end{syntax} +% Ensures that \TeX{} is not in vertical (inter-paragraph) mode. In +% horizontal or math mode this command has no effect, in vertical mode it +% switches to horizontal mode, and inserts a box of width +% \tn{parindent}, followed by the \tn{everypar} token list. +% \begin{texnote} +% This results in the contents of the \tn{everypar} token register being +% inserted, after \cs{mode_leave_vertical:} is complete. Notice that in +% contrast to the \LaTeXe{} \tn{leavevmode} approach, no box is used +% by the method implemented here. +% \end{texnote} +% \end{function} +% % \end{documentation} % % \begin{implementation} @@ -1690,447 +1708,51 @@ % \begin{macro}{\__kernel_if_debug:TF} % A more meaningful test of whether debugging is enabled than messing % up with guards. We can also more easily change the logic in one -% place then. At present, debugging is disabled in the format and in -% generic mode, while in \LaTeXe{} mode it is enabled if one of the -% options \texttt{enable-debug}, \texttt{log-functions} or -% \texttt{check-declarations} was given. +% place then. This is needed primarily for deprecations. % \begin{macrocode} \cs_set_protected:Npn \__kernel_if_debug:TF #1#2 {#2} -%<*package> -\tex_ifodd:D \l@expl@enable@debug@bool - \cs_set_protected:Npn \__kernel_if_debug:TF #1#2 {#1} -\fi: -%</package> % \end{macrocode} % \end{macro} % -% \begin{macro}{\debug_on:n, \debug_off:n, \@@_all_on:, \@@_all_off:} -% +% \begin{macro}{\debug_on:n, \debug_off:n} +% Stubs. % \begin{macrocode} -\__kernel_if_debug:TF +\cs_set_protected:Npn \debug_on:n #1 { - \cs_set_protected:Npn \debug_on:n #1 - { - \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } - { - \cs_if_exist_use:cF { @@_ ##1 _on: } - { \__kernel_msg_error:nnn { kernel } { debug } {##1} } - } - } - \cs_set_protected:Npn \debug_off:n #1 - { - \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } - { - \cs_if_exist_use:cF { @@_ ##1 _off: } - { \__kernel_msg_error:nnn { kernel } { debug } {##1} } - } - } - \cs_set_protected:Npn \@@_all_on: - { - \debug_on:n - { - check-declarations , - check-expressions , - deprecation , - log-functions , - } - } - \cs_set_protected:Npn \@@_all_off: - { - \debug_off:n - { - check-declarations , - check-expressions , - deprecation , - log-functions , - } - } + \__kernel_msg_error:nnx { kernel } { enable-debug } + { \tl_to_str:n { \debug_on:n {#1} } } } +\cs_set_protected:Npn \debug_off:n #1 { - \cs_set_protected:Npn \debug_on:n #1 - { - \__kernel_msg_error:nnx { kernel } { enable-debug } - { \tl_to_str:n { \debug_on:n {#1} } } - } - \cs_set_protected:Npn \debug_off:n #1 - { - \__kernel_msg_error:nnx { kernel } { enable-debug } - { \tl_to_str:n { \debug_off:n {#1} } } - } + \__kernel_msg_error:nnx { kernel } { enable-debug } + { \tl_to_str:n { \debug_off:n {#1} } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\debug_suspend:, \debug_resume:} -% \begin{macro}{\@@_suspended:T} -% \begin{macro}{\l_@@_suspended_tl} -% Suspend and resume locally all debug-related errors and logging -% except deprecation errors. The \cs{debug_suspend:} and \cs{debug_resume:} -% pairs can be nested. We keep track of nesting in a token list -% containing a number of periods. At first begin with the -% \enquote{non-suspended} version of \cs{@@_suspended:T}. -% \begin{macrocode} -\__kernel_if_debug:TF - { - \cs_set_nopar:Npn \l_@@_suspended_tl { } - \cs_set_protected:Npn \debug_suspend: - { - \tl_put_right:Nn \l_@@_suspended_tl { . } - \cs_set_eq:NN \@@_suspended:T \use:n - } - \cs_set_protected:Npn \debug_resume: - { - \tl_set:Nx \l_@@_suspended_tl - { \tl_tail:N \l_@@_suspended_tl } - \tl_if_empty:NT \l_@@_suspended_tl - { - \cs_set_eq:NN \@@_suspended:T \use_none:n - } - } - \cs_set:Npn \@@_suspended:T #1 { } - } - { - \cs_set_protected:Npn \debug_suspend: { } - \cs_set_protected:Npn \debug_resume: { } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro} -% {\@@_check-declarations_on:, \@@_check-declarations_off:} -% \begin{macro}{\__kernel_chk_var_exist:N} -% \begin{macro}{\__kernel_chk_cs_exist:N, \__kernel_chk_cs_exist:c} -% \begin{macro}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N} -% \begin{macro}{\__kernel_chk_var_scope:NN} -% When debugging is enabled these two functions set up functions that -% test their argument (when \texttt{check-declarations} is active) -% \begin{itemize} -% \item \cs{__kernel_chk_var_exist:N} and \cs{__kernel_chk_cs_exist:N}, two -% functions that test that their argument is defined; -% \item \cs{__kernel_chk_var_scope:NN} that checks that its argument |#2| -% has scope |#1|. -% \item \cs{__kernel_chk_var_local:N} and \cs{__kernel_chk_var_global:N} that -% perform both checks. -% \end{itemize} -% \begin{macrocode} -\__kernel_if_debug:TF - { - \exp_args:Nc \cs_set_protected:Npn { @@_check-declarations_on: } - { - \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1 - { - \@@_suspended:T \use_none:nnn - \cs_if_exist:NF ##1 - { - \__kernel_msg_error:nnx { kernel } { non-declared-variable } - { \token_to_str:N ##1 } - } - } - \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1 - { - \@@_suspended:T \use_none:nnn - \cs_if_exist:NF ##1 - { - \__kernel_msg_error:nnx { kernel } { command-not-defined } - { \token_to_str:N ##1 } - } - } - \cs_set_protected:Npn \__kernel_chk_var_scope:NN - { - \@@_suspended:T \use_none:nnn - \@@_chk_var_scope_aux:NN - } - \cs_set_protected:Npn \__kernel_chk_var_local:N ##1 - { - \@@_suspended:T \use_none:nnnnn - \__kernel_chk_var_exist:N ##1 - \@@_chk_var_scope_aux:NN l ##1 - } - \cs_set_protected:Npn \__kernel_chk_var_global:N ##1 - { - \@@_suspended:T \use_none:nnnnn - \__kernel_chk_var_exist:N ##1 - \@@_chk_var_scope_aux:NN g ##1 - } - } - \exp_args:Nc \cs_set_protected:Npn { @@_check-declarations_off: } - { - \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1 { } - \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1 { } - \cs_set_protected:Npn \__kernel_chk_var_local:N ##1 { } - \cs_set_protected:Npn \__kernel_chk_var_global:N ##1 { } - \cs_set_protected:Npn \__kernel_chk_var_scope:NN ##1##2 { } - } - \cs_set_protected:Npn \__kernel_chk_cs_exist:c - { \exp_args:Nc \__kernel_chk_cs_exist:N } - \tex_ifodd:D \l@expl@check@declarations@bool - \use:c { @@_check-declarations_on: } - \else: - \use:c { @@_check-declarations_off: } - \fi: - } - { } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_chk_var_scope_aux:NN} -% \begin{macro}{\@@_chk_var_scope_aux:Nn} -% \begin{macro}{\@@_chk_var_scope_aux:NNn} -% First check whether the name of the variable |#2| starts with -% \meta{letter}|_|. If it does then pass that letter, the -% \meta{scope}, and the variable name to -% \cs{@@_chk_var_scope_aux:NNn}. That function compares the two -% letters and triggers an error if they differ (the \cs{scan_stop:} -% case is not reachable here). If the second character was not |_| -% then pass the same data to the same auxiliary, except for its first -% argument which is now a control sequence. That control sequence is -% actually a token list (but to avoid triggering the checking code we -% manipulate it using \cs{cs_set_nopar:Npn}) containing a single -% letter \meta{scope} according to what the first assignment to the -% given variable was. -% \begin{macrocode} -\__kernel_if_debug:TF - { - \cs_set_protected:Npn \@@_chk_var_scope_aux:NN #1#2 - { \exp_args:NNf \@@_chk_var_scope_aux:Nn #1 { \cs_to_str:N #2 } } - \cs_set_protected:Npn \@@_chk_var_scope_aux:Nn #1#2 - { - \if:w _ \use_i:nn \use_i_delimit_by_q_stop:nw #2 ? ? \q_stop - \exp_after:wN \@@_chk_var_scope_aux:NNn - \use_i_delimit_by_q_stop:nw #2 ? \q_stop - #1 {#2} - \else: - \exp_args:Nc \@@_chk_var_scope_aux:NNn - { @@_chk_/ #2 } - #1 {#2} - \fi: - } - \cs_set_protected:Npn \@@_chk_var_scope_aux:NNn #1#2#3 - { - \if:w #1 #2 - \else: - \if:w #1 \scan_stop: - \cs_gset_nopar:Npn #1 {#2} - \else: - \__kernel_msg_error:nnxxx { kernel } { local-global } - {#1} {#2} { \iow_char:N \\ #3 } - \fi: - \fi: - } - } - { } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro} -% {\@@_check-expressions_on:, \@@_check-expressions_off:} -% \begin{macro}{\__kernel_chk_expr:nNnN} -% \begin{macro}{\@@_chk_expr_aux:nNnN} -% When debugging is enabled these two functions set -% \cs{__kernel_chk_expr:nNnN} to test or not whether the given -% expression is valid. The idea is to evaluate the expression within -% a brace group (to catch trailing \cs{use_none:nn} or similar), then -% test that the result is what we expect. This is done by turning it -% to an integer and hitting that with \cs{tex_romannumeral:D} after -% replacing the first character by |-0|. If all goes well, that -% primitive finds a non-positive integer and gives an empty output. -% If the original expression evaluation stopped early it leaves a -% trailing \cs{tex_relax:D}, which stops the second evaluation (used -% to convert to integer) before it encounters the final -% \cs{tex_relax:D}. Since \cs{tex_romannumeral:D} does not absorb -% \cs{tex_relax:D} the output will be nonempty. Note that |#3| is -% empty except for mu expressions for which it is \cs{tex_mutoglue:D} -% to avoid an \enquote{incompatible glue units} error. Note also that -% if we had omitted the first \cs{tex_relax:D} then for instance -% |1+2\relax+3| would incorrectly be accepted as a valid integer -% expression. -% \begin{macrocode} -\__kernel_if_debug:TF - { - \exp_args:Nc \cs_set_protected:Npn { @@_check-expressions_on: } - { - \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2 - { - \@@_suspended:T { ##1 \use_none:nnnnnnn } - \exp_after:wN \@@_chk_expr_aux:nNnN - \exp_after:wN { \tex_the:D ##2 ##1 \scan_stop: } - ##2 - } - } - \exp_args:Nc \cs_set_protected:Npn { @@_check-expressions_off: } - { \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2##3##4 {##1} } - \use:c { @@_check-expressions_off: } - \cs_set:Npn \@@_chk_expr_aux:nNnN #1#2#3#4 - { - \tl_if_empty:oF - { - \tex_romannumeral:D - 0 - \exp_after:wN \use_none:n - \int_value:w #3 #2 #1 \scan_stop: - } - { - \__kernel_msg_expandable_error:nnnn - { kernel } { expr } {#4} {#1} - } - #1 - } - } - { } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_log-functions_on:, \@@_log-functions_off:} -% \begin{macro}{\__kernel_debug_log:x} -% These two functions (corresponding to the \pkg{expl3} option -% \texttt{log-functions}) control whether \cs{__kernel_debug_log:x} writes to the -% log file or not. Since \cs{iow_log:x} does not yet have its final -% definition we do not use \cs{cs_set_eq:NN} (not defined yet anyway). -% Once everything is defined, turn logging on or off depending on what -% option was given. When debugging is not enabled, simply produce an -% error. % \begin{macrocode} -\__kernel_if_debug:TF - { - \exp_args:Nc \cs_set_protected:Npn { @@_log-functions_on: } - { - \cs_set_protected:Npn \__kernel_debug_log:x - { \@@_suspended:T \use_none:nn \iow_log:x } - } - \exp_args:Nc \cs_set_protected:Npn { @@_log-functions_off: } - { \cs_set_protected:Npn \__kernel_debug_log:x { \use_none:n } } - \tex_ifodd:D \l@expl@log@functions@bool - \use:c { @@_log-functions_on: } - \else: - \use:c { @@_log-functions_off: } - \fi: - } - { } +\cs_set_protected:Npn \debug_suspend: { } +\cs_set_protected:Npn \debug_resume: { } % \end{macrocode} % \end{macro} -% \end{macro} % -% \begin{macro}{\@@_deprecation_on:, \@@_deprecation_off:} % \begin{macro}{\__kernel_deprecation_code:nn} % \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, filled up in \pkg{l3deprecation}. % \begin{macrocode} -\__kernel_if_debug:TF - { - \cs_set_protected:Npn \@@_deprecation_on: - { \g_@@_deprecation_on_tl } - \cs_set_protected:Npn \@@_deprecation_off: - { \g_@@_deprecation_off_tl } - \cs_set_nopar:Npn \g_@@_deprecation_on_tl { } - \cs_set_nopar:Npn \g_@@_deprecation_off_tl { } - \cs_set_protected:Npn \__kernel_deprecation_code:nn #1#2 - { - \tl_gput_right:Nn \g_@@_deprecation_on_tl {#1} - \tl_gput_right:Nn \g_@@_deprecation_off_tl {#2} - } - } +\cs_set_nopar:Npn \g_@@_deprecation_on_tl { } +\cs_set_nopar:Npn \g_@@_deprecation_off_tl { } +\cs_set_protected:Npn \__kernel_deprecation_code:nn #1#2 { - \cs_set_protected:Npn \__kernel_deprecation_code:nn #1#2 { } + \tl_gput_right:Nn \g_@@_deprecation_on_tl {#1} + \tl_gput_right:Nn \g_@@_deprecation_off_tl {#2} } % \end{macrocode} % \end{variable} % \end{macro} -% \end{macro} -% -% \begin{macro} -% {\__kernel_patch:nnNNpn, \__kernel_patch_conditional:nNNpnn} -% \begin{macro} -% {\@@_patch_aux:nnnn, \@@_patch_auxii:nnnn} -% When debugging is not enabled, \cs{__kernel_patch:nnNNpn} and -% \cs{__kernel_patch_conditional:nNNpnn} throw the patch away. -% Otherwise they can be followed by \cs{cs_new:Npn} (or similar), and -% \cs{prg_new_conditional:Npnn} (or similar), respectively. In each -% case, grab the name of the function to be defined and its parameters -% then insert tokens before and/or after the definition. -% \begin{macrocode} -\__kernel_if_debug:TF - { - \cs_set_protected:Npn \__kernel_patch:nnNNpn #1#2#3#4#5# - { \@@_patch_aux:nnnn {#1} {#2} { #3 #4 #5 } } - \cs_set_protected:Npn \__kernel_patch_conditional:nNNpnn #1#2#3#4# - { \@@_patch_auxii:nnnn {#1} { #2 #3 #4 } } - \cs_set_protected:Npn \@@_patch_aux:nnnn #1#2#3#4 - { #3 { #1 #4 #2 } } - \cs_set_protected:Npn \@@_patch_auxii:nnnn #1#2#3#4 - { #2 {#3} { #1 #4 } } - } - { - \cs_set_protected:Npn \__kernel_patch:nnNNpn #1#2 { } - \cs_set_protected:Npn \__kernel_patch_conditional:nNNpnn #1 { } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro} -% {\__kernel_patch_args:nNNpn, \__kernel_patch_conditional_args:nNNpnn} -% \begin{macro} -% {\__kernel_patch_args:nnnNNpn, \__kernel_patch_conditional_args:nnnNNpnn} -% \begin{macro} -% { -% \@@_tmp:w, -% \@@_patch_args_aux:nnnNNnn, -% \@@_patch_args_aux:nnnNNnnn, -% \@@_patch_args_aux:nnnn -% } -% See \cs{__kernel_patch:nnNNpn}. The first argument is something like -% |{#1}{(#2)}|. Define a temporary macro using the \meta{parameters} -% and \meta{code} of the definition that follows, then expand that -% temporary macro in front of the first argument to obtain new -% \meta{code}. Then perform the definition as if that new \meta{code} -% was directly typed in the file. -% \begin{macrocode} -\cs_set_protected:Npn \__kernel_patch_args:nNNpn - { \__kernel_patch_args:nnnNNpn { } { } } -\cs_set_protected:Npn \__kernel_patch_conditional_args:nNNpnn - { \__kernel_patch_conditional_args:nnnNNpnn { } { } } -\__kernel_if_debug:TF - { - \cs_set_protected:Npn \__kernel_patch_args:nnnNNpn #1#2#3#4#5#6# - { \@@_patch_args_aux:nnnNNnn {#1} {#2} {#3} #4 #5 {#6} } - \cs_set_protected:Npn \__kernel_patch_conditional_args:nnnNNpnn - #1#2#3#4#5#6# - { \@@_patch_args_aux:nnnNNnnn {#1} {#2} {#3} #4 #5 {#6} } - \cs_set_protected:Npn \@@_patch_args_aux:nnnNNnn #1#2#3#4#5#6#7 - { - \cs_set:Npn \@@_tmp:w #6 {#7} - \exp_after:wN \@@_patch_args_aux:nnnn \exp_after:wN - { \@@_tmp:w #3 } { #4 #5 #6 } {#1} {#2} - } - \cs_set_protected:Npn \@@_patch_args_aux:nnnNNnnn #1#2#3#4#5#6#7#8 - { - \cs_set:Npn \@@_tmp:w #6 {#8} - \exp_after:wN \@@_patch_args_aux:nnnn \exp_after:wN - { \@@_tmp:w #3 } { #4 #5 #6 {#7} } {#1} {#2} - } - \cs_set_protected:Npn \@@_patch_args_aux:nnnn #1#2#3#4 - { #2 { #3 #1 #4 } } - } - { - \cs_set_protected:Npn \__kernel_patch_args:nnnNNpn #1#2#3 { } - \cs_set_protected:Npn \__kernel_patch_conditional_args:nnnNNpnn - #1#2#3 { } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} % % \subsection{Conditional processing and definitions} % @@ -2515,20 +2137,12 @@ #5 {#1} {#2} {#3} {#4} \@@_set_eq_conditional_loop:nnnnNw {#1} {#2} {#3} {#4} #5 } -\__kernel_patch:nnNNpn - { \__kernel_chk_cs_exist:c { #5 _p : #6 } } { } \cs_set:Npn \@@_set_eq_conditional_p_form:wNnnnn #1 \q_stop #2#3#4#5#6 { #2 { #3 _p : #4 } { #5 _p : #6 } } -\__kernel_patch:nnNNpn - { \__kernel_chk_cs_exist:c { #5 : #6 TF } } { } \cs_set:Npn \@@_set_eq_conditional_TF_form:wNnnnn #1 \q_stop #2#3#4#5#6 { #2 { #3 : #4 TF } { #5 : #6 TF } } -\__kernel_patch:nnNNpn - { \__kernel_chk_cs_exist:c { #5 : #6 T } } { } \cs_set:Npn \@@_set_eq_conditional_T_form:wNnnnn #1 \q_stop #2#3#4#5#6 { #2 { #3 : #4 T } { #5 : #6 T } } -\__kernel_patch:nnNNpn - { \__kernel_chk_cs_exist:c { #5 : #6 F } } { } \cs_set:Npn \@@_set_eq_conditional_F_form:wNnnnn #1 \q_stop #2#3#4#5#6 { #2 { #3 : #4 F } { #5 : #6 F } } % \end{macrocode} @@ -2889,11 +2503,6 @@ % issued. We have to make sure we don't put the argument into the % conditional processing since it may be an |\if...| type function! % \begin{macrocode} -\__kernel_patch:nnNNpn { } - { - \__kernel_debug_log:x - { Defining~\token_to_str:N #1~ \msg_line_context: } - } \cs_set_protected:Npn \__kernel_chk_if_free_cs:N #1 { \cs_if_free:NF #1 @@ -3591,6 +3200,28 @@ % \end{macro} % \end{macro} % +% \subsection{Starting a paragraph} +% +% \begin{macro}{\mode_leave_vertical:} +% The approach here is different to that used by \LaTeXe{} or plain \TeX{}, +% which unbox a void box to force horizontal mode. That inserts the +% \tn{everypar} tokens \emph{before} the re-inserted unboxing tokens. The +% approach here uses either the \tn{quitvmode} primitive or the equivalent +% protected macro. In vertical mode, the \tn{indent} primitive is inserted: +% this will switch to horizontal mode and insert \tn{everypar} tokens and +% nothing else. Unlike the \LaTeXe{} version, the availability of \eTeX{} +% means using a mode test can be done at for example the start of an +% \tn{halign}. +% \begin{macrocode} +\cs_new_protected:Npn \mode_leave_vertical: + { + \if_mode_vertical: + \exp_after:wN \tex_indent:D + \fi: + } +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx index d694a67540a..8dd79bc523a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx index c72206a2b2b..815f0ca6df4 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -903,13 +903,6 @@ % produce an internal dimension rather than expand it into characters. % \begin{macrocode} \cs_new_eq:NN \@@_dim_eval:w \tex_dimexpr:D -\__kernel_patch_args:nNNpn - { - { - \__kernel_chk_expr:nNnN {#1} - \@@_dim_eval:w { } \@@_dim_eval:n - } - } \cs_new:Npn \@@_dim_eval:n #1 { \@@_dim_eval:w #1 \scan_stop: } % \end{macrocode} @@ -972,10 +965,8 @@ % \testfile* % Assigning the contents of a box to be another box. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \box_set_eq:NN #1#2 { \tex_setbox:D #1 \tex_copy:D #2 } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \box_gset_eq:NN #1#2 { \tex_global:D \tex_setbox:D #1 \tex_copy:D #2 } \cs_generate_variant:Nn \box_set_eq:NN { c , Nc , cc } @@ -997,10 +988,8 @@ % Assigning the contents of a box to be another box, then drops the % original box. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \box_set_eq_drop:NN #1#2 { \tex_setbox:D #1 \tex_box:D #2 } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \box_gset_eq_drop:NN #1#2 { \tex_global:D \tex_setbox:D #1 \tex_box:D #2 } \cs_generate_variant:Nn \box_set_eq_drop:NN { c , Nc , cc } @@ -1165,10 +1154,8 @@ % \testfile* % Set a box to the previous box. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \box_set_to_last:N #1 { \tex_setbox:D #1 \tex_lastbox:D } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \box_gset_to_last:N #1 { \tex_global:D \tex_setbox:D #1 \tex_lastbox:D } \cs_generate_variant:Nn \box_set_to_last:N { c } @@ -1285,13 +1272,11 @@ % \begin{macro}{\hbox_gset:Nn, \hbox_gset:cn} % \testfile* % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \hbox_set:Nn #1#2 { \tex_setbox:D #1 \tex_hbox:D { \color_group_begin: #2 \color_group_end: } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \hbox_gset:Nn #1#2 { \tex_global:D \tex_setbox:D #1 \tex_hbox:D @@ -1309,13 +1294,11 @@ % Storing material in a horizontal box with a specified width. % Again, put the dimension expression in parentheses when debugging. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \hbox_set_to_wd:Nnn #1#2#3 { \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2} { \color_group_begin: #3 \color_group_end: } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \hbox_gset_to_wd:Nnn #1#2#3 { \tex_global:D \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2} @@ -1334,14 +1317,12 @@ % Storing material in a horizontal box. This type is useful in % environment definitions. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \hbox_set:Nw #1 { \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token \color_group_begin: } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \hbox_gset:Nw #1 { \tex_global:D \tex_setbox:D #1 \tex_hbox:D @@ -1365,14 +1346,12 @@ % \begin{macro}{\hbox_gset_to_wd:Nnw, \hbox_gset_to_wd:cnw} % Combining the above ideas. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \hbox_set_to_wd:Nnw #1#2 { \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2} \c_group_begin_token \color_group_begin: } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \hbox_gset_to_wd:Nnw #1#2 { \tex_global:D \tex_setbox:D #1 \tex_hbox:D to \@@_dim_eval:n {#2} @@ -1473,13 +1452,11 @@ % \testfile* % Storing material in a vertical box with a natural height. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \vbox_set:Nn #1#2 { \tex_setbox:D #1 \tex_vbox:D { \color_group_begin: #2 \par \color_group_end: } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \vbox_gset:Nn #1#2 { \tex_global:D \tex_setbox:D #1 \tex_vbox:D @@ -1497,13 +1474,11 @@ % Storing material in a vertical box with a natural height and reference % point at the baseline of the first object in the box. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \vbox_set_top:Nn #1#2 { \tex_setbox:D #1 \tex_vtop:D { \color_group_begin: #2 \par \color_group_end: } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \vbox_gset_top:Nn #1#2 { \tex_global:D \tex_setbox:D #1 \tex_vtop:D @@ -1520,13 +1495,11 @@ % \testfile* % Storing material in a vertical box with a specified height. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \vbox_set_to_ht:Nnn #1#2#3 { \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2} { \color_group_begin: #3 \par \color_group_end: } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \vbox_gset_to_ht:Nnn #1#2#3 { \tex_global:D \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2} @@ -1545,14 +1518,12 @@ % Storing material in a vertical box. This type is useful in % environment definitions. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \vbox_set:Nw #1 { \tex_setbox:D #1 \tex_vbox:D \c_group_begin_token \color_group_begin: } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \vbox_gset:Nw #1 { \tex_global:D \tex_setbox:D #1 \tex_vbox:D @@ -1577,14 +1548,12 @@ % \begin{macro}{\vbox_gset_to_ht:Nnw, \vbox_gset_to_ht:cnw} % A combination of the above ideas. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \vbox_set_to_ht:Nnw #1#2 { \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2} \c_group_begin_token \color_group_begin: } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \vbox_gset_to_ht:Nnw #1#2 { \tex_global:D \tex_setbox:D #1 \tex_vbox:D to \@@_dim_eval:n {#2} @@ -1620,11 +1589,9 @@ % \testfile* % Splitting a vertical box in two. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \vbox_set_split_to_ht:NNn #1#2#3 { \tex_setbox:D #1 \tex_vsplit:D #2 to \@@_dim_eval:n {#3} } \cs_generate_variant:Nn \vbox_set_split_to_ht:NNn { c , Nc , cc } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \vbox_gset_split_to_ht:NNn #1#2#3 { \tex_global:D \tex_setbox:D #1 diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx index 96dbdc5c789..d726722ad17 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -123,22 +123,6 @@ % See for instance \pkg{l3coffins}. % \end{function} % -% \begin{function}[added = 2017-07-04]{\mode_leave_vertical:} -% \begin{syntax} -% \cs{mode_leave_vertical:} -% \end{syntax} -% Ensures that \TeX{} is not in vertical (inter-paragraph) mode. In -% horizontal or math mode this command has no effect, in vertical mode it -% switches to horizontal mode, and inserts a box of width -% \tn{parindent}, followed by the \tn{everypar} token list. -% \begin{texnote} -% This results in the contents of the \tn{everypar} token register being -% inserted, after \cs{mode_leave_vertical:} is complete. Notice that in -% contrast to the \LaTeXe{} \tn{leavevmode} approach, no box is used -% by the method implemented here. -% \end{texnote} -% \end{function} -% % \section{Additions to \pkg{l3box}} % % \subsection{Viewing part of a box} @@ -221,31 +205,6 @@ % % \section{Additions to \pkg{l3fp}} % -% \begin{function}[EXP, added = 2018-11-03]{logb} -% \begin{syntax} -% \cs{fp_eval:n} \{ |logb(| \meta{fpexpr} |)| \} -% \end{syntax} -% Determines the exponent of the \meta{fpexpr}, namely the floor of -% the base-$10$ logarithm of its absolute value. \enquote{Division by -% zero} occurs when evaluating $\operatorname{logb}(\pm 0) = -\infty$. -% Other special values are $\operatorname{logb}(\pm\infty)=+\infty$ -% and $\operatorname{logb}(\nan{})=\nan{}$. If the operand is a tuple -% or is \nan{}, then \enquote{invalid operation} occurs and the result -% is \nan{}. -% \end{function} -% -% \begin{function}[EXP, added = 2018-11-03]{\fp_sign:n} -% \begin{syntax} -% \cs{fp_sign:n} \Arg{fpexpr} -% \end{syntax} -% Evaluates the \meta{fpexpr} and leaves its sign in the input stream -% using \cs{fp_eval:n} |{sign(|\meta{result}|)}|: $+1$ for positive -% numbers and for $+\infty$, $-1$ for negative numbers and for -% $-\infty$, $\pm 0$ for $\pm 0$. If the operand is a tuple or is -% \nan{}, then \enquote{invalid operation} occurs and the result -% is~$0$. -% \end{function} -% % \begin{function}[pTF, added = 2019-08-25]{\fp_if_nan:n} % \begin{syntax} % \cs{fp_if_nan:n} \Arg{fpexpr} @@ -255,112 +214,8 @@ % a tuple containing \nan{}. % \end{function} % -% \section{Additions to \pkg{l3fparray}} -% -% \begin{function}[added = 2018-05-05]{\fparray_new:Nn} -% \begin{syntax} -% \cs{fparray_new:Nn} \meta{fparray~var} \Arg{size} -% \end{syntax} -% Evaluates the integer expression \meta{size} and allocates an -% \meta{floating point array variable} with that number of (zero) -% entries. The variable name should start with |\g_| because -% assignments are always global. -% \end{function} -% -% \begin{function}[EXP, added = 2018-05-05]{\fparray_count:N} -% \begin{syntax} -% \cs{fparray_count:N} \meta{fparray~var} -% \end{syntax} -% Expands to the number of entries in the \meta{floating point array -% variable}. This is performed in constant time. -% \end{function} -% -% \begin{function}[added = 2018-05-05]{\fparray_gset:Nnn} -% \begin{syntax} -% \cs{fparray_gset:Nnn} \meta{fparray~var} \Arg{position} \Arg{value} -% \end{syntax} -% Stores the result of evaluating the floating point expression -% \meta{value} into the \meta{floating point array variable} at the -% (integer expression) \meta{position}. If the \meta{position} is not -% between $1$ and the \cs{fparray_count:N}, an error occurs. -% Assignments are always global. -% \end{function} -% -% \begin{function}[added = 2018-05-05]{\fparray_gzero:N} -% \begin{syntax} -% \cs{fparray_gzero:N} \meta{fparray~var} -% \end{syntax} -% Sets all entries of the \meta{floating point array variable} to -% $+0$. Assignments are always global. -% \end{function} -% -% \begin{function}[EXP, added = 2018-05-05] -% {\fparray_item:Nn, \fparray_item_to_tl:Nn} -% \begin{syntax} -% \cs{fparray_item:Nn} \meta{fparray~var} \Arg{position} -% \end{syntax} -% Applies \cs{fp_use:N} or \cs{fp_to_tl:N} (respectively) to the -% floating point entry stored at the (integer expression) -% \meta{position} in the \meta{floating point array variable}. If the -% \meta{position} is not between $1$ and the \cs{fparray_count:N}, an -% error occurs. -% \end{function} -% % \section{Additions to \pkg{l3file}} % -% \begin{function}[added = 2019-05-13, TF]{\file_compare_timestamp:nNn} -% \begin{syntax} -% \cs{file_compare_timestamp:nNn} \Arg{file-1} \meta{comparator} \Arg{file-2} \Arg{true code} \Arg{false code} -% \end{syntax} -% Compares the file stamps on the two \meta{files} as indicated by -% the \meta{comparator}, and inserts either the \meta{true code} -% or \meta{false case} as required. A file which is not found -% is treated as older than any file which is found.This allows for -% example the construct -% \begin{verbatim} -% \file_compare_timestamp:nNnT { source-file } > { derived-file } -% { -% % Code to regenerate derived file -% } -% \end{verbatim} -% to work when the derived file is entirely absent. The timestamp -% of two absent files is regarded as different. -% \end{function} -% -% \begin{function}[added = 2019-01-13]{\ior_map_variable:NNn} -% \begin{syntax} -% \cs{ior_map_variable:NNn} \meta{stream} \meta{tl~var} \Arg{code} -% \end{syntax} -% For each set of \meta{lines} obtained by calling \cs{ior_get:NN} -% until reaching the end of the file, stores the \meta{lines} in the -% \meta{tl~var} then applies the \meta{code}. The \meta{code} will -% usually make use of the \meta{variable}, but this is not enforced. -% The assignments to the \meta{variable} are local. -% Its value after the loop is the last set of \meta{lines}, or its -% original value if the \meta{stream} is empty. \TeX{} ignores -% any trailing new-line marker from the file it reads. -% This function is typically faster than \cs{ior_map_inline:Nn}. -% \end{function} -% -% \begin{function}[added = 2019-01-13]{\ior_str_map_variable:NNn} -% \begin{syntax} -% \cs{ior_str_map_variable:NNn} \meta{stream} \meta{variable} \Arg{code} -% \end{syntax} -% For each \meta{line} in the \meta{stream}, stores the \meta{line} in -% the \meta{variable} then applies the \meta{code}. The material is -% read from the \meta{stream} as a series of tokens with category code -% $12$ (other), with the exception of space characters which are given -% category code $10$ (space). The \meta{code} will usually make use -% of the \meta{variable}, but this is not enforced. The assignments -% to the \meta{variable} are local. Its value after the loop is the -% last \meta{line}, or its original value if the \meta{stream} is -% empty. Note that \TeX{} removes trailing -% space and tab characters (character codes 32 and 9) from every line -% upon input. \TeX{} also ignores any trailing new-line marker from -% the file it reads. -% This function is typically faster than \cs{ior_str_map_inline:Nn}. -% \end{function} -% % \begin{function}[added = 2018-12-29]{\iow_allow_break:} % \begin{syntax} % \cs{iow_allow_break:} @@ -402,7 +257,7 @@ % If piped system calls are disabled an error is raised. % % For details of handling of the \meta{shell command}, see -% \cs{sys_shell_get:nnN(TF)}. +% \cs{sys_get_shell:nnN(TF)}. % \end{function} % % \section{Additions to \pkg{l3flag}} @@ -415,19 +270,13 @@ % locally. % \end{function} % -% \section{Additions to \pkg{l3int}} -% -% \begin{function}[EXP, added = 2018-11-03]{\int_sign:n} -% \begin{syntax} -% \cs{int_sign:n} \Arg{intexpr} -% \end{syntax} -% Evaluates the \meta{integer expression} then leaves $1$ or $0$ or -% $-1$ in the input stream according to the sign of the result. -% \end{function} -% % \section{Additions to \pkg{l3intarray}} % -% \begin{function}[added = 2018-05-05]{\intarray_gset_rand:Nnn, \intarray_gset_rand:Nn} +% \begin{function}[added = 2018-05-05] +% { +% \intarray_gset_rand:Nnn, \intarray_gset_rand:cnn, +% \intarray_gset_rand:Nn, \intarray_gset_rand:cn +% } % \begin{syntax} % \cs{intarray_gset_rand:Nnn} \meta{intarray~var} \Arg{minimum} \Arg{maximum} % \cs{intarray_gset_rand:Nn} \meta{intarray~var} \Arg{maximum} @@ -446,16 +295,6 @@ % % \subsection{Working with contents of integer arrays} % -% \begin{function}[added = 2018-05-04, rEXP]{\intarray_const_from_clist:Nn} -% \begin{syntax} -% \cs{intarray_const_from_clist:Nn} \meta{intarray~var} \meta{intexpr clist} -% \end{syntax} -% Creates a new constant \meta{integer array variable} or raises an -% error if the name is already taken. The \meta{integer array -% variable} is set (globally) to contain as its items the results of -% evaluating each \meta{integer expression} in the \meta{comma list}. -% \end{function} -% % \begin{function}[added = 2018-05-04, rEXP]{\intarray_to_clist:N} % \begin{syntax} % \cs{intarray_to_clist:N} \meta{intarray~var} @@ -466,15 +305,6 @@ % result has one fewer comma than the number of items. % \end{function} % -% \begin{function}[added = 2018-05-04]{\intarray_show:N, \intarray_log:N} -% \begin{syntax} -% \cs{intarray_show:N} \meta{intarray~var} -% \cs{intarray_log:N} \meta{intarray~var} -% \end{syntax} -% Displays the items in the \meta{integer array variable} in the -% terminal or writes them in the log file. -% \end{function} -% % \section{Additions to \pkg{l3msg}} % % In very rare cases it may be necessary to produce errors in an @@ -566,15 +396,6 @@ % % \section{Additions to \pkg{l3prg}} % -% \begin{function}[added = 2017-11-28]{\bool_const:Nn, \bool_const:cn} -% \begin{syntax} -% \cs{bool_const:Nn} \meta{boolean} \Arg{boolexpr} -% \end{syntax} -% Creates a new constant \meta{boolean} or raises an error if the name -% is already taken. The value of the \meta{boolean} is set globally to -% the result of evaluating the \meta{boolexpr}. -% \end{function} -% % \begin{function}[added = 2018-05-10] % { % \bool_set_inverse:N , \bool_set_inverse:c , @@ -606,37 +427,6 @@ % \end{texnote} % \end{function} % -% \begin{function}[added = 2017-11-28, updated = 2019-08-25] -% { -% \prop_set_from_keyval:Nn, \prop_set_from_keyval:cn, -% \prop_gset_from_keyval:Nn, \prop_gset_from_keyval:cn, -% } -% \begin{syntax} -% \cs{prop_set_from_keyval:Nn} \meta{prop~var} -% \{ -% \meta{key1} |=| \meta{value1} |,| -% \meta{key2} |=| \meta{value2} |,| \ldots{} -% \} -% \end{syntax} -% Sets \meta{prop~var} to contain key--value pairs given in the second -% argument. If duplicate keys appear only one of the values is kept. -% \end{function} -% -% \begin{function}[added = 2017-11-28, updated = 2019-08-25] -% {\prop_const_from_keyval:Nn, \prop_const_from_keyval:cn} -% \begin{syntax} -% \cs{prop_const_from_keyval:Nn} \meta{prop~var} -% \{ -% \meta{key1} |=| \meta{value1} |,| -% \meta{key2} |=| \meta{value2} |,| \ldots{} -% \} -% \end{syntax} -% Creates a new constant \meta{prop~var} or raises an error if the -% name is already taken. The \meta{prop~var} is set globally to -% contain key--value pairs given in the second argument. -% If duplicate keys appear only one of the values is kept. -% \end{function} -% % \section{Additions to \pkg{l3seq}} % % \begin{function}[rEXP] @@ -690,16 +480,6 @@ % \end{texnote} % \end{function} % -% \begin{function}[added = 2017-11-28] -% {\seq_const_from_clist:Nn, \seq_const_from_clist:cn} -% \begin{syntax} -% \cs{seq_const_from_clist:Nn} \meta{seq~var} \Arg{comma-list} -% \end{syntax} -% Creates a new constant \meta{seq~var} or raises an error if the name -% is already taken. The \meta{seq~var} is set globally to contain the -% items in the \meta{comma list}. -% \end{function} -% % \begin{function}[added = 2018-04-06] % {\seq_set_from_function:NnN, \seq_gset_from_function:NnN} % \begin{syntax} @@ -738,23 +518,6 @@ % mappings. % \end{function} % -% \begin{function}[added = 2018-04-29]{\seq_shuffle:N, \seq_gshuffle:N} -% \begin{syntax} -% \cs{seq_shuffle:N} \meta{seq~var} -% \end{syntax} -% Sets the \meta{seq~var} to the result of placing the items of the -% \meta{seq~var} in a random order. Each item is (roughly) as likely -% to end up in any given position. -% \begin{texnote} -% For sequences with more than $13$ items or so, only a small -% proportion of all possible permutations can be reached, because -% the random seed \cs{sys_rand_seed:} only has $28$-bits. The use -% of \tn{toks} internally means that sequences with more than -% $32767$ or $65535$ items (depending on the engine) cannot be -% shuffled. -% \end{texnote} -% \end{function} -% % \begin{function}[added = 2018-05-03]{\seq_indexed_map_function:NN} % \begin{syntax} % \cs{seq_indexed_map_function:NN} \meta{seq~var} \meta{function} @@ -775,37 +538,8 @@ % and so on) as~|#1| and the \meta{item} as~|#2|. % \end{function} % -% \section{Additions to \pkg{l3skip}} -% -% \begin{function}[EXP, added = 2018-11-03]{\dim_sign:n} -% \begin{syntax} -% \cs{dim_sign:n} \Arg{dimexpr} -% \end{syntax} -% Evaluates the \meta{dimexpr} then leaves $1$ or $0$ or $-1$ in the -% input stream according to the sign of the result. -% \end{function} -% % \section{Additions to \pkg{l3sys}} % -% \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} -% \end{syntax} -% Defines \meta{tl} to the text returned by the \meta{shell command}. -% The \meta{shell command} is converted to a string using -% \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 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} -% % \begin{variable}[added = 2018-05-02]{\c_sys_engine_version_str} % The version string of the current engine, in the same form as % given in the banner issued when running a job. For \pdfTeX{} @@ -836,106 +570,6 @@ % this is the case in \pdfTeX{}, \LuaTeX{}, \pTeX{} and \upTeX{}. % \end{function} % -% \begin{function}[added = 2017-05-27, EXP]{\sys_rand_seed:} -% \begin{syntax} -% \cs{sys_rand_seed:} -% \end{syntax} -% Expands to the current value of the engine's random seed, a -% non-negative integer. In engines without random number support this -% expands to $0$. -% \end{function} -% -% \begin{function}[added = 2017-05-27]{\sys_gset_rand_seed:n} -% \begin{syntax} -% \cs{sys_gset_rand_seed:n} \Arg{intexpr} -% \end{syntax} -% Globally sets the seed for the engine's pseudo-random number -% generator to the \meta{integer expression}. This random seed -% affects all \cs[no-index]{\ldots{}_rand} functions (such as -% \cs{int_rand:nn} or \cs{clist_rand_item:n}) as well as other -% packages relying on the engine's random number generator. In -% engines without random number support this produces an error. -% \begin{texnote} -% While a $32$-bit (signed) integer can be given as a seed, only the -% absolute value is used and any number beyond $2^{28}$ is divided -% by an appropriate power of~$2$. We recommend using an integer in -% $[0,2^{28}-1]$. -% \end{texnote} -% \end{function} -% -% \begin{function}[added = 2018-07-27, EXP, pTF] -% { -% \sys_if_platform_unix:, -% \sys_if_platform_windows: -% } -% \begin{syntax} -% \cs{sys_if_platform_unix:TF} \Arg{true code} \Arg{false code} -% \end{syntax} -% Conditionals which allow platform-specific code to be used. The names -% follow the \Lua{} |os.type()| function, \emph{i.e.}~all Unix-like systems -% are |unix| (including Linux and MacOS). -% \end{function} -% -% \begin{variable}[added = 2018-07-27]{\c_sys_platform_str} -% The current platform given as a lower case string: one of -% |unix|, |windows| or |unknown|. -% \end{variable} -% -% \begin{variable}[added = 2017-05-27]{\c_sys_shell_escape_int} -% This variable exposes the internal triple of the shell escape -% status. The possible values are -% \begin{description} -% \item[0] Shell escape is disabled -% \item[1] Unrestricted shell escape is enabled -% \item[2] Restricted shell escape is enabled -% \end{description} -% \end{variable} -% -% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell:} -% \begin{syntax} -% \cs{sys_if_shell_p:} -% \cs{sys_if_shell:TF} \Arg{true code} \Arg{false code} -% \end{syntax} -% Performs a check for whether shell escape is enabled. This -% returns true if either of restricted or unrestricted shell escape -% is enabled. -% \end{function} -% -% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_unrestricted:} -% \begin{syntax} -% \cs{sys_if_shell_unrestricted_p:} -% \cs{sys_if_shell_unrestricted:TF} \Arg{true code} \Arg{false code} -% \end{syntax} -% Performs a check for whether \emph{unrestricted} shell escape is -% enabled. -% \end{function} -% -% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_restricted:} -% \begin{syntax} -% \cs{sys_if_shell_restricted_p:} -% \cs{sys_if_shell_restricted:TF} \Arg{true code} \Arg{false code} -% \end{syntax} -% Performs a check for whether \emph{restricted} shell escape is -% enabled. This returns false if unrestricted shell escape is -% enabled. Unrestricted shell escape is not considered a superset -% of restricted shell escape in this case. To find whether any -% shell escape is enabled use \cs{sys_if_shell:}. -% \end{function} -% -% \begin{function}[added = 2017-05-27]{\sys_shell_now:n, \sys_shell_now:x} -% \begin{syntax} -% \cs{sys_shell_now:n} \Arg{tokens} -% \end{syntax} -% Execute \meta{tokens} through shell escape immediately. -% \end{function} -% -% \begin{function}[added = 2017-05-27]{\sys_shell_shipout:n, \sys_shell_shipout:x} -% \begin{syntax} -% \cs{sys_shell_shipout:n} \Arg{tokens} -% \end{syntax} -% Execute \meta{tokens} through shell escape at shipout. -% \end{function} -% % \section{Additions to \pkg{l3tl}} % % \begin{function}[EXP, added = 2014-06-30, updated = 2016-01-12] @@ -1335,28 +969,6 @@ %<*initex|package> % \end{macrocode} % -% \subsection{Additions to \pkg{l3basics}} -% -% \begin{macro}{\mode_leave_vertical:} -% The approach here is different to that used by \LaTeXe{} or plain \TeX{}, -% which unbox a void box to force horizontal mode. That inserts the -% \tn{everypar} tokens \emph{before} the re-inserted unboxing tokens. The -% approach here uses either the \tn{quitvmode} primitive or the equivalent -% protected macro. In vertical mode, the \tn{indent} primitive is inserted: -% this will switch to horizontal mode and insert \tn{everypar} tokens and -% nothing else. Unlike the \LaTeXe{} version, the availability of \eTeX{} -% means using a mode test can be done at for example the start of an -% \tn{halign}. -% \begin{macrocode} -\cs_new_protected:Npn \mode_leave_vertical: - { - \if_mode_vertical: - \exp_after:wN \tex_indent:D - \fi: - } -% \end{macrocode} -% \end{macro} -% % \subsection{Additions to \pkg{l3box}} % % \begin{macrocode} @@ -1519,22 +1131,6 @@ % \end{macro} % \end{macro} % -% \subsection{Additions to \pkg{l3fp-convert}} -% -% \begin{macrocode} -%<@@=fp> -% \end{macrocode} -% -% \begin{macro}{\fp_sign:n} -% Trivial but useful. See the implementation of \cs{fp_add:Nn} for an -% explanation of why to use \cs{@@_parse:n}, namely, for better error -% reporting. -% \begin{macrocode} -\cs_new:Npn \fp_sign:n #1 - { \fp_to_decimal:n { sign \@@_parse:n {#1} } } -% \end{macrocode} -% \end{macro} -% % \subsection{Additions to \pkg{l3flag}} % % \begin{macrocode} @@ -1547,7 +1143,6 @@ % it if the flag is zero in case the \enquote{trap} made customizable % in the future. % \begin{macrocode} -\__kernel_patch:nnNNpn { \@@_chk_exist:n {#1} } { } \cs_new:Npn \flag_raise_if_clear:n #1 { \if_cs_exist:w flag~#1~0 \cs_end: @@ -1558,39 +1153,6 @@ % \end{macrocode} % \end{macro} % -% \subsection{Additions to \pkg{l3int}} -% -% \begin{macrocode} -%<@@=int> -% \end{macrocode} -% -% \begin{macro}[EXP]{\int_sign:n, \@@_sign:Nw} -% See \cs{int_abs:n}. Evaluate the expression once (and when -% debugging is enabled, check that the expression is well-formed), -% then test the first character to determine the sign. This is -% wrapped in \cs{int_value:w} \ldots{} \cs{exp_stop_f:} to ensure a -% fixed number of expansions and to avoid dealing with closing the -% conditionals. -% \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_sign:n } } -\cs_new:Npn \int_sign:n #1 - { - \int_value:w \exp_after:wN \@@_sign:Nw - \int_value:w \@@_eval:w #1 \@@_eval_end: ; - \exp_stop_f: - } -\cs_new:Npn \@@_sign:Nw #1#2 ; - { - \if_meaning:w 0 #1 - 0 - \else: - \if_meaning:w - #1 - \fi: 1 - \fi: - } -% \end{macrocode} -% \end{macro} -% % \subsection{Additions to \pkg{l3msg}} % % \begin{macrocode} @@ -1701,19 +1263,6 @@ % % \subsection{Additions to \pkg{l3prg}} % -% \begin{macro}[added = 2017-11-28]{\bool_const:Nn, \bool_const:cn} -% A merger between \cs{tl_const:Nn} and \cs{bool_set:Nn}. -% \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } -\cs_new_protected:Npn \bool_const:Nn #1#2 - { - \__kernel_chk_if_free_cs:N #1 - \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2} - } -\cs_generate_variant:Nn \bool_const:Nn { c } -% \end{macrocode} -% \end{macro} -% % \begin{macro}[added = 2018-05-10] % {\bool_set_inverse:N, \bool_set_inverse:c, \bool_gset_inverse:N, \bool_gset_inverse:c} % Set to \texttt{false} or \texttt{true} locally or globally. @@ -1888,85 +1437,6 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\seq_const_from_clist:Nn, \seq_const_from_clist:cn} -% Almost identical to \cs{seq_set_from_clist:Nn}. -% \begin{macrocode} -\cs_new_protected:Npn \seq_const_from_clist:Nn #1#2 - { - \tl_const:Nx #1 - { \s_@@ \clist_map_function:nN {#2} \@@_wrap_item:n } - } -\cs_generate_variant:Nn \seq_const_from_clist:Nn { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\seq_shuffle:N, \seq_gshuffle:N, \@@_shuffle:NN, \@@_shuffle_item:n} -% \begin{variable}{\g_@@_internal_seq, \l_@@_internal_a_int, \l_@@_internal_b_int} -% We apply the Fisher–Yates shuffle, storing items in \tn{toks} -% registers. We use the primitive \cs{tex_uniformdeviate:D} for -% speed reasons. Its non-uniformity is of order its argument divided -% by $2^{28}$, not too bad for small lists. For sequences with more -% than $13$ elements there are more possible permutations than -% possible seeds ($13!>2^{28}$) so the question of uniformity is -% somewhat moot. -% \begin{macrocode} -\cs_if_exist:NTF \tex_uniformdeviate:D - { - \int_new:N \l_@@_internal_a_int - \int_new:N \l_@@_internal_b_int - \seq_new:N \g_@@_internal_seq - \cs_new_protected:Npn \seq_shuffle:N { \@@_shuffle:NN \seq_set_eq:NN } - \cs_new_protected:Npn \seq_gshuffle:N { \@@_shuffle:NN \seq_gset_eq:NN } - \cs_new_protected:Npn \@@_shuffle:NN #1#2 - { - \int_compare:nNnTF { \seq_count:N #2 } > \c_max_register_int - { - \__kernel_msg_error:nnx { kernel } { shuffle-too-large } - { \token_to_str:N #2 } - } - { - \group_begin: - \cs_set_eq:NN \@@_item:n \@@_shuffle_item:n - \int_zero:N \l_@@_internal_a_int - #2 - \seq_gset_from_inline_x:Nnn \g_@@_internal_seq - { \int_step_function:nN { \l_@@_internal_a_int } } - { \tex_the:D \tex_toks:D ##1 } - \group_end: - #1 #2 \g_@@_internal_seq - \seq_gclear:N \g_@@_internal_seq - } - } - \cs_new_protected:Npn \@@_shuffle_item:n - { - \int_incr:N \l_@@_internal_a_int - \int_set:Nn \l_@@_internal_b_int - { 1 + \tex_uniformdeviate:D \l_@@_internal_a_int } - \tex_toks:D \l_@@_internal_a_int - = \tex_toks:D \l_@@_internal_b_int - \tex_toks:D \l_@@_internal_b_int - } - \__kernel_msg_new:nnnn { kernel } { shuffle-too-large } - { The~sequence~#1~is~too~long~to~be~shuffled~by~TeX. } - { - TeX~has~ \int_eval:n { \c_max_register_int + 1 } ~ - toks~registers:~this~only~allows~to~shuffle~up~to~ - \int_use:N \c_max_register_int \ items.~ - The~list~will~not~be~shuffled. - } - } - { - \cs_new_protected:Npn \seq_shuffle:N #1 - { - \__kernel_msg_error:nnn { kernel } { fp-no-random } - { \seq_shuffle:N #1 } - } - \cs_new_eq:NN \seq_gshuffle:N \seq_shuffle:N - } -% \end{macrocode} -% \end{variable} -% \end{macro} -% % \begin{macro} % { % \seq_indexed_map_function:NN, \seq_indexed_map_inline:Nn, @@ -2011,42 +1481,6 @@ % \end{macrocode} % \end{macro} % -% \subsection{Additions to \pkg{l3skip}} -% -% \begin{macrocode} -%<@@=dim> -% \end{macrocode} -% -% \begin{macro}[EXP]{\dim_sign:n, \@@_sign:Nw} -% See \cs{dim_abs:n}. Contrarily to \cs{int_sign:n} the case of a -% zero dimension cannot be distinguished from a positive dimension by -% looking only at the first character, since |0.2pt| and |0pt| start -% the same way. We need explicit comparisons. We start by -% distinguishing the most common case of a positive dimension. -% \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_sign:n } } -\cs_new:Npn \dim_sign:n #1 - { - \int_value:w \exp_after:wN \@@_sign:Nw - \dim_use:N \@@_eval:w #1 \@@_eval_end: ; - \exp_stop_f: - } -\cs_new:Npn \@@_sign:Nw #1#2 ; - { - \if_dim:w #1#2 > \c_zero_dim - 1 - \else: - \if_meaning:w - #1 - -1 - \else: - 0 - \fi: - \fi: - } -% \end{macrocode} -% \end{macro} -% % \subsection{Additions to \pkg{l3sys}} % % \begin{macrocode} @@ -2073,6 +1507,7 @@ { p \int_use:N \tex_ptexversion:D + . \int_use:N \tex_ptexminorversion:D \tex_ptexrevision:D - @@ -2091,6 +1526,7 @@ { p \int_use:N \tex_ptexversion:D + . \int_use:N \tex_ptexminorversion:D \tex_ptexrevision:D - @@ -2111,327 +1547,9 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}[EXP]{\sys_rand_seed:} -% Unpack the primitive. When random numbers are not available, we -% return zero after an error (and incidentally make sure the number of -% expansions needed is the same as with random numbers available). -% \begin{macrocode} -\sys_if_rand_exist:TF - { \cs_new:Npn \sys_rand_seed: { \tex_the:D \tex_randomseed:D } } - { - \cs_new:Npn \sys_rand_seed: - { - \int_value:w - \__kernel_msg_expandable_error:nnn { kernel } { fp-no-random } - { \sys_rand_seed: } - \c_zero_int - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\sys_gset_rand_seed:n} -% The primitive always assigns the seed globally. -% \begin{macrocode} -\sys_if_rand_exist:TF - { - \cs_new_protected:Npn \sys_gset_rand_seed:n #1 - { \tex_setrandomseed:D \int_eval:n {#1} \exp_stop_f: } - } - { - \cs_new_protected:Npn \sys_gset_rand_seed:n #1 - { - \__kernel_msg_error:nnn { kernel } { fp-no-random } - { \sys_gset_rand_seed:n {#1} } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{variable}{\c_sys_shell_escape_int} -% Expose the engine's shell escape status to the user. -% \begin{macrocode} -\int_const:Nn \c_sys_shell_escape_int - { - \sys_if_engine_luatex:TF - { - \tex_directlua:D - { tex.sprint(status.shell_escape~or~os.execute()) } - } - { - \tex_shellescape:D - } - } -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_internal_tl} -% \begin{macrocode} -\tl_new:N \l_@@_internal_tl -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\c_@@_marker_tl} -% The same idea as the marker for rescanning token lists. -% \begin{macrocode} -\tl_const:Nx \c_@@_marker_tl { : \token_to_str:N : } -% \end{macrocode} -% \end{variable} -% -% \begin{macro}[TF]{\sys_shell_get:nnN} -% \begin{macro}{\sys_shell_get:nnN,\@@_get:nnN,\@@_get_do:Nw} -% Setting using a shell is at this level just a slightly specialised file -% operation, with an additional check for quotes, as these are not supported. -% \begin{macrocode} -\cs_new_protected:Npn \sys_shell_get:nnN #1#2#3 - { - \sys_shell_get:nnNF {#1} {#2} #3 - { \tl_set:Nn #3 { \q_no_value } } - } -\prg_new_protected_conditional:Npnn \sys_shell_get:nnN #1#2#3 { T , F , TF } - { - \sys_if_shell:TF - { \exp_args:No \@@_get:nnN { \tl_to_str:n {#1} } {#2} #3 } - { \prg_return_false: } - } -\cs_new_protected:Npn \@@_get:nnN #1#2#3 - { - \tl_if_in:nnTF {#1} { " } - { - \__kernel_msg_error:nnx - { kernel } { quote-in-shell } {#1} - \prg_return_false: - } - { - \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: - \exp_after:wN \@@_get_do:Nw - \exp_after:wN #3 - \exp_after:wN \prg_do_nothing: - \tex_input:D | "#1" \scan_stop: - \if_false: } \fi: - \prg_return_true: - } - } -\exp_args:Nno \use:nn - { \cs_new_protected:Npn \@@_get_do:Nw #1#2 } - { \c_@@_marker_tl } - { - \group_end: - \tl_set:No #1 {#2} - } -\__kernel_msg_new:nnnn { kernel } { quote-in-shell } - { Quotes~in~shell~command~'#1'. } - { Shell~commands~cannot~contain~quotes~("). } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{variable}{\c_sys_platform_str} -% Detecting the platform on \LuaTeX{} is easy: for other engines, we use -% the fact that the two common cases have special null files. It is possible -% to probe further (see package \pkg{platform}), but that requires shell -% escape and seems unlikely to be useful. -% \begin{macrocode} -\sys_if_engine_luatex:TF - { - \str_const:Nx \c_sys_platform_str - { \lua_now:n { tex.print(os.type) } } - } - { - \file_if_exist:nTF { nul: } - { - \file_if_exist:nF { /dev/null } - { \str_const:Nn \c_sys_platform_str { windows } } - } - { - \file_if_exist:nT { /dev/null } - { \str_const:Nn \c_sys_platform_str { unix } } - } - } -\cs_if_exist:NF \c_sys_platform_str - { \str_const:Nn \c_sys_platform_str { unknown } } -% \end{macrocode} -% \end{variable} -% \begin{macro}[pTF]{\sys_if_platform_unix:} -% \begin{macro}[pTF]{\sys_if_platform_windows:} -% We can now set up the tests. -% \begin{macrocode} -\clist_map_inline:nn { unix , windows } - { - \@@_const:nn { sys_if_platform_ #1 } - { \str_if_eq_p:Vn \c_sys_platform_str { #1 } } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP, pTF]{\sys_if_shell:, \sys_if_shell_unrestricted:, \sys_if_shell_restricted:} -% Performs a check for whether shell escape is enabled. The first set -% of functions returns true if either of restricted or unrestricted -% shell escape is enabled, while the other two sets of functions -% return true in only one of these two cases. -% \begin{macrocode} -\@@_const:nn { sys_if_shell } - { \int_compare_p:nNn \c_sys_shell_escape_int > 0 } -\@@_const:nn { sys_if_shell_unrestricted } - { \int_compare_p:nNn \c_sys_shell_escape_int = 1 } -\@@_const:nn { sys_if_shell_restricted } - { \int_compare_p:nNn \c_sys_shell_escape_int = 2 } -% \end{macrocode} -% \end{macro} -% -% \begin{variable}{\c_@@_shell_stream_int} -% This is not needed for \LuaTeX{}: shell escape there isn't done using -% a \TeX{} interface. -% \begin{macrocode} -\sys_if_engine_luatex:F - { \int_const:Nn \c_@@_shell_stream_int { 18 } } -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\sys_shell_now:n} -% Execute commands through shell escape immediately. -% \begin{macrocode} -\sys_if_engine_luatex:TF - { - \cs_new_protected:Npn \sys_shell_now:n #1 - { - \lua_now:e - { os.execute(" \lua_escape:e { \tl_to_str:n {#1} } ") } - } - } - { - \cs_new_protected:Npn \sys_shell_now:n #1 - { \iow_now:Nn \c_@@_shell_stream_int {#1} } - } -\cs_generate_variant:Nn \sys_shell_now:n { x } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\sys_shell_shipout:n} -% Execute commands through shell escape at shipout. -% \begin{macrocode} -\sys_if_engine_luatex:TF - { - \cs_new_protected:Npn \sys_shell_shipout:n #1 - { - \lua_shipout_e:n - { os.execute(" \lua_escape:e { \tl_to_str:n {#1} } ") } - } - } - { - \cs_new_protected:Npn \sys_shell_shipout:n #1 - { \iow_shipout:Nn \c_@@_shell_stream_int {#1} } - } -\cs_generate_variant:Nn \sys_shell_shipout:n { x } -% \end{macrocode} -% \end{macro} -% % \subsection{Additions to \pkg{l3file}} % % \begin{macrocode} -%<@@=file> -% \end{macrocode} -% -% \begin{macro}[EXP]{\@@_str_cmp:nn} -% \begin{macro}[EXP]{\@@_str_escape:n} -% As we are doing a fixed-length \enquote{big} integer comparison, it -% is easiest to use the low-level behavior of string comparisons. -% \begin{macrocode} -\cs_new:Npn \@@_str_cmp:nn #1#2 { \tex_strcmp:D {#1} {#2} } -\sys_if_engine_luatex:T - { - \cs_set:Npn \@@_str_cmp:nn #1#2 - { - \lua_now:e - { - l3kernel.strcmp - ( - " \@@_str_escape:n {#1}", - " \@@_str_escape:n {#2}" - ) - } - } - \cs_new:Npn \@@_str_escape:n #1 - { - \lua_escape:e - { \__kernel_tl_to_str:w \use:e { {#1} } } - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{variable}{\l_@@_first_tl, \l_@@_second_tl} -% \begin{macrocode} -\tl_new:N \l_@@_first_tl -\tl_new:N \l_@@_second_tl -% \end{macrocode} -% \end{variable} -% -% \begin{macro}[TF]{\file_compare_timestamp:nNn} -% \begin{macro}[EXP]{\@@_timestamp:n} -% Comparison of file date can be done by using the low-level nature of the -% string comparison functions. This could be expandable but that would -% skip any file look-up: to stay consistent we retain that at the cost of -% expansion. -% \begin{macrocode} -\prg_new_protected_conditional:Npnn \file_compare_timestamp:nNn #1#2#3 - { T , F , TF } - { - \group_begin: - \file_get_full_name:nNTF {#1} \l_@@_first_tl - { - \file_get_full_name:nNTF {#3} \l_@@_second_tl - { - \if_int_compare:w - \@@_str_cmp:nn - { \@@_timestamp:n \exp_after:wN { \l_@@_first_tl } } - { \@@_timestamp:n \exp_after:wN { \l_@@_second_tl } } - #2 0 \exp_stop_f: - \group_end: - \prg_return_true: - \else: - \group_end: - \prg_return_false: - \fi: - } - { - \group_end: - \if_charcode:w #2 > - \prg_return_true: - \else: - \prg_return_false: - \fi: - } - } - { - \group_end: - \if_charcode:w #2 < - \prg_return_true: - \else: - \prg_return_false: - \fi: - } - } -\sys_if_engine_luatex:TF - { - \cs_new:Npn \@@_timestamp:n #1 - { - \lua_now:e - { l3kernel.filemoddate ( " \lua_escape:e {#1} " ) } - } - } - { \cs_new_eq:NN \@@_timestamp:n \tex_filemoddate:D } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macrocode} %<@@=ior> % \end{macrocode} % @@ -2760,14 +1878,6 @@ %<@@=tl> % \end{macrocode} % -% \begin{macro}[EXP, documented-as=\tl_if_head_eq_catcode:nNTF] -% {\tl_if_head_eq_catcode:oNTF} -% Extra variants. -% \begin{macrocode} -\cs_generate_variant:Nn \tl_if_head_eq_catcode:nNTF { o } -% \end{macrocode} -% \end{macro} -% % \begin{macro}[EXP]{\tl_lower_case:n, \tl_upper_case:n, \tl_mixed_case:n} % \begin{macro}[EXP]{\tl_lower_case:nn, \tl_upper_case:nn, \tl_mixed_case:nn} % The user level functions here are all wrappers around the internal @@ -4112,10 +3222,8 @@ % definition does not seem useful so we just do |#3| |#1| |{}| to % clear it locally or globally as appropriate. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_build_begin:N #1 { \@@_build_begin:NN \cs_set_nopar:Npx #1 } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_build_gbegin:N #1 { \@@_build_begin:NN \cs_gset_nopar:Npx #1 } \cs_new_protected:Npn \@@_build_begin:NN #1#2 @@ -4170,25 +3278,21 @@ % implies that the assignment does not simply set the token list to an % |x|-expansion of the second argument. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_build_put_right:Nn #1#2 { \cs_set_nopar:Npx #1 { \exp_after:wN \exp_not:n \exp_after:wN { \exp:w #1 #2 } } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_build_put_right:Nx #1#2 { \cs_set_nopar:Npx #1 { \exp_after:wN \exp_not:n \exp_after:wN { \exp:w #1 } #2 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_build_gput_right:Nn #1#2 { \cs_gset_nopar:Npx #1 { \exp_after:wN \exp_not:n \exp_after:wN { \exp:w #1 #2 } } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_build_gput_right:Nx #1#2 { \cs_gset_nopar:Npx #1 @@ -4227,11 +3331,9 @@ % add the \meta{right} material after the \Arg{left} in the % |x|-expanding assignment. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_build_put_left:Nn #1 { \@@_build_put_left:NNn \cs_set_nopar:Npx #1 } \cs_generate_variant:Nn \tl_build_put_left:Nn { Nx } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_build_gput_left:Nn #1 { \@@_build_put_left:NNn \cs_gset_nopar:Npx #1 } \cs_generate_variant:Nn \tl_build_gput_left:Nn { Nx } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index f2664fa77f1..3b3b8041aba 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index 6c084d19d94..92ee2175862 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx index 93dae477973..3b58b7e2807 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx b/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx new file mode 100644 index 00000000000..55b16ec0e21 --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx @@ -0,0 +1,1447 @@ +% \iffalse meta-comment +% +%% File: l3debug.dtx +% +% Copyright (C) 2019 The LaTeX3 Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% This file is part of the "l3kernel bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/latex3 +% +% for those people who are interested. +% +%<*driver> +\documentclass[full,kernel]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{^^A +% The \textsf{l3debug} package\\ Debugging support^^A +% } +% +% \author{^^A +% The \LaTeX3 Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Released 2019-09-28} +% +% \maketitle +% +% \begin{documentation} +% +% \begin{function}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N} +% \begin{syntax} +% \cs{__kernel_chk_var_local:N} \meta{var} +% \cs{__kernel_chk_var_global:N} \meta{var} +% \end{syntax} +% Applies \cs{__kernel_chk_var_exist:N} \meta{var} as well as +% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var}, where +% \meta{scope} is |l| or~|g|. +% \end{function} +% +% \begin{function}{\__kernel_chk_var_scope:NN} +% \begin{syntax} +% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var} +% \end{syntax} +% Checks the \meta{var} has the correct \meta{scope}, and if not +% raises a kernel-level error. This function is only created if +% debugging is enabled. The \meta{scope} is a single letter |l|, |g|, +% |c| denoting local variables, global variables, or constants. More +% precisely, if the variable name starts with a letter and an +% underscore (normal \pkg{expl3} convention) the function checks that +% this single letter matches the \meta{scope}. Otherwise the function +% cannot know the scope \meta{var} the first time: instead, it defines +% |\__debug_chk_/|\meta{var name} to store that information for the +% next call. Thus, if a given \meta{var} is subject to assignments of +% different scopes a kernel error will result. +% \end{function} +% +% \begin{function} +% { +% \__kernel_chk_cs_exist:N, +% \__kernel_chk_cs_exist:c, +% \__kernel_chk_var_exist:N +% } +% \begin{syntax} +% \cs{__kernel_chk_cs_exist:N} \meta{cs} +% \cs{__kernel_chk_var_exist:N} \meta{var} +% \end{syntax} +% These functions are only created if debugging is enabled. They +% check that their argument is defined according to the criteria for +% \cs{cs_if_exist_p:N}, +% and if not raises a kernel-level error. Error messages are +% different. +% \end{function} +% +% \begin{function}[EXP]{\__kernel_chk_flag_exist:n} +% \begin{syntax} +% \cs{__kernel_chk_flag_exist:n} \Arg{flag} +% \end{syntax} +% This function is only created if debugging is enabled. It checks +% that the \meta{flag} is defined according to the criterion for +% \cs{flag_if_exist_p:n}, and if not raises a kernel-level error. +% \end{function} +% +% \begin{function}{\__kernel_debug_log:x} +% \begin{syntax} +% \cs{__kernel_debug_log:x} \Arg{message text} +% \end{syntax} +% If the \texttt{log-functions} option is active, this function writes +% the \meta{message text} to the log file using \cs{iow_log:x}. +% Otherwise, the \meta{message text} is ignored using \cs{use_none:n}. +% This function is only created if debugging is enabled. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3debug} Implementation} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=debug> +% \end{macrocode} +% +% Standard file identification. +% \begin{macrocode} +\ProvidesExplFile{l3debug.def}{2019-04-06}{}{L3 Debugging support} +% \end{macrocode} +% +% \begin{macro}{\debug_on:n, \debug_off:n, \@@_all_on:, \@@_all_off:} +% \begin{macrocode} +\cs_set_protected:Npn \debug_on:n #1 + { + \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } + { + \cs_if_exist_use:cF { @@_ ##1 _on: } + { \__kernel_msg_error:nnn { kernel } { debug } {##1} } + } + } +\cs_set_protected:Npn \debug_off:n #1 + { + \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } + { + \cs_if_exist_use:cF { @@_ ##1 _off: } + { \__kernel_msg_error:nnn { kernel } { debug } {##1} } + } + } +\cs_new_protected:Npn \@@_all_on: + { + \debug_on:n + { + check-declarations , + check-expressions , + deprecation , + log-functions , + } + } +\cs_new_protected:Npn \@@_all_off: + { + \debug_off:n + { + check-declarations , + check-expressions , + deprecation , + log-functions , + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\debug_suspend:, \debug_resume:} +% \begin{macro}{\@@_suspended:T} +% \begin{macro}{\l_@@_suspended_tl} +% Suspend and resume locally all debug-related errors and logging +% except deprecation errors. The \cs{debug_suspend:} and \cs{debug_resume:} +% pairs can be nested. We keep track of nesting in a token list +% containing a number of periods. At first begin with the +% \enquote{non-suspended} version of \cs{@@_suspended:T}. +% \begin{macrocode} +\tl_new:N \l_@@_suspended_tl { } +\cs_set_protected:Npn \debug_suspend: + { + \tl_put_right:Nn \l_@@_suspended_tl { . } + \cs_set_eq:NN \@@_suspended:T \use:n + } +\cs_set_protected:Npn \debug_resume: + { + \tl_set:Nx \l_@@_suspended_tl + { \tl_tail:N \l_@@_suspended_tl } + \tl_if_empty:NT \l_@@_suspended_tl + { + \cs_set_eq:NN \@@_suspended:T \use_none:n + } + } +\cs_new_eq:NN \@@_suspended:T \use_none:n +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% {\@@_check-declarations_on:, \@@_check-declarations_off:} +% \begin{macro} +% { +% \__kernel_chk_var_exist:N, +% \__kernel_chk_cs_exist:N, +% \__kernel_chk_cs_exist:c +% } +% \begin{macro}[EXP]{\__kernel_chk_flag_exist:n} +% \begin{macro}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N} +% \begin{macro}{\__kernel_chk_var_scope:NN} +% When debugging is enabled these two functions set up functions that +% test their argument (when \texttt{check-declarations} is active) +% \begin{itemize} +% \item \cs{__kernel_chk_var_exist:N} and \cs{__kernel_chk_cs_exist:N}, two +% functions that test that their argument is defined; +% \item \cs{__kernel_chk_var_scope:NN} that checks that its argument |#2| +% has scope |#1|. +% \item \cs{__kernel_chk_var_local:N} and \cs{__kernel_chk_var_global:N} that +% perform both checks. +% \end{itemize} +% \begin{macrocode} +\cs_new_protected:Npn \__kernel_chk_var_exist:N #1 { } +\cs_new_protected:Npn \__kernel_chk_cs_exist:N #1 { } +\cs_generate_variant:Nn \__kernel_chk_cs_exist:N { c } +\cs_new:Npn \__kernel_chk_flag_exist:n #1 { } +\cs_new_protected:Npn \__kernel_chk_var_local:N #1 { } +\cs_new_protected:Npn \__kernel_chk_var_global:N #1 { } +\cs_new_protected:Npn \__kernel_chk_var_scope:NN #1#2 { } +\cs_new_protected:cpn { @@_check-declarations_on: } + { + \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1 + { + \@@_suspended:T \use_none:nnn + \cs_if_exist:NF ##1 + { + \__kernel_msg_error:nnx { kernel } { non-declared-variable } + { \token_to_str:N ##1 } + } + } + \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1 + { + \@@_suspended:T \use_none:nnn + \cs_if_exist:NF ##1 + { + \__kernel_msg_error:nnx { kernel } { command-not-defined } + { \token_to_str:N ##1 } + } + } + \cs_set:Npn \__kernel_chk_flag_exist:n ##1 + { + \@@_suspended:T \use_none:nnn + \flag_if_exist:nF {##1} + { + \__kernel_msg_expandable_error:nnn + { kernel } { bad-variable } { flag~##1~ } + } + } + \cs_set_protected:Npn \__kernel_chk_var_scope:NN + { + \@@_suspended:T \use_none:nnn + \@@_chk_var_scope_aux:NN + } + \cs_set_protected:Npn \__kernel_chk_var_local:N ##1 + { + \@@_suspended:T \use_none:nnnnn + \__kernel_chk_var_exist:N ##1 + \@@_chk_var_scope_aux:NN l ##1 + } + \cs_set_protected:Npn \__kernel_chk_var_global:N ##1 + { + \@@_suspended:T \use_none:nnnnn + \__kernel_chk_var_exist:N ##1 + \@@_chk_var_scope_aux:NN g ##1 + } + } +\cs_new_protected:cpn { @@_check-declarations_off: } + { + \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1 { } + \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1 { } + \cs_set:Npn \__kernel_chk_flag_exist:N ##1 { } + \cs_set_protected:Npn \__kernel_chk_var_local:N ##1 { } + \cs_set_protected:Npn \__kernel_chk_var_global:N ##1 { } + \cs_set_protected:Npn \__kernel_chk_var_scope:NN ##1##2 { } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_chk_var_scope_aux:NN} +% \begin{macro}{\@@_chk_var_scope_aux:Nn} +% \begin{macro}{\@@_chk_var_scope_aux:NNn} +% First check whether the name of the variable |#2| starts with +% \meta{letter}|_|. If it does then pass that letter, the +% \meta{scope}, and the variable name to +% \cs{@@_chk_var_scope_aux:NNn}. That function compares the two +% letters and triggers an error if they differ (the \cs{scan_stop:} +% case is not reachable here). If the second character was not |_| +% then pass the same data to the same auxiliary, except for its first +% argument which is now a control sequence. That control sequence is +% actually a token list (but to avoid triggering the checking code we +% manipulate it using \cs{cs_set_nopar:Npn}) containing a single +% letter \meta{scope} according to what the first assignment to the +% given variable was. +% \begin{macrocode} +\cs_new_protected:Npn \@@_chk_var_scope_aux:NN #1#2 + { \exp_args:NNf \@@_chk_var_scope_aux:Nn #1 { \cs_to_str:N #2 } } +\cs_new_protected:Npn \@@_chk_var_scope_aux:Nn #1#2 + { + \if:w _ \use_i:nn \use_i_delimit_by_q_stop:nw #2 ? ? \q_stop + \exp_after:wN \@@_chk_var_scope_aux:NNn + \use_i_delimit_by_q_stop:nw #2 ? \q_stop + #1 {#2} + \else: + \exp_args:Nc \@@_chk_var_scope_aux:NNn + { @@_chk_/ #2 } + #1 {#2} + \fi: + } +\cs_new_protected:Npn \@@_chk_var_scope_aux:NNn #1#2#3 + { + \if:w #1 #2 + \else: + \if:w #1 \scan_stop: + \cs_gset_nopar:Npn #1 {#2} + \else: + \__kernel_msg_error:nnxxx { kernel } { local-global } + {#1} {#2} { \iow_char:N \\ #3 } + \fi: + \fi: + } +\use:c { @@_check-declarations_off: } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_log-functions_on:, \@@_log-functions_off:} +% \begin{macro}{\__kernel_debug_log:x} +% These two functions (corresponding to the \pkg{expl3} option +% \texttt{log-functions}) control whether \cs{__kernel_debug_log:x} +% writes to the log file or not. By default, logging is off. +% \begin{macrocode} +\cs_new_protected:cpn { @@_log-functions_on: } + { + \cs_set_protected:Npn \__kernel_debug_log:x + { \@@_suspended:T \use_none:nn \iow_log:x } + } +\cs_new_protected:cpn { @@_log-functions_off: } + { \cs_set_protected:Npn \__kernel_debug_log:x { \use_none:n } } +\cs_new_protected:Npn \__kernel_debug_log:x { \use_none:n } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% {\@@_check-expressions_on:, \@@_check-expressions_off:} +% \begin{macro}{\__kernel_chk_expr:nNnN} +% \begin{macro}{\@@_chk_expr_aux:nNnN} +% When debugging is enabled these two functions set +% \cs{__kernel_chk_expr:nNnN} to test or not whether the given +% expression is valid. The idea is to evaluate the expression within +% a brace group (to catch trailing \cs{use_none:nn} or similar), then +% test that the result is what we expect. This is done by turning it +% to an integer and hitting that with \cs{tex_romannumeral:D} after +% replacing the first character by |-0|. If all goes well, that +% primitive finds a non-positive integer and gives an empty output. +% If the original expression evaluation stopped early it leaves a +% trailing \cs{tex_relax:D}, which stops the second evaluation (used +% to convert to integer) before it encounters the final +% \cs{tex_relax:D}. Since \cs{tex_romannumeral:D} does not absorb +% \cs{tex_relax:D} the output will be nonempty. Note that |#3| is +% empty except for mu expressions for which it is \cs{tex_mutoglue:D} +% to avoid an \enquote{incompatible glue units} error. Note also that +% if we had omitted the first \cs{tex_relax:D} then for instance +% |1+2\relax+3| would incorrectly be accepted as a valid integer +% expression. +% \begin{macrocode} +\cs_new_protected:cpn { @@_check-expressions_on: } + { + \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2 + { + \@@_suspended:T { ##1 \use_none:nnnnnnn } + \exp_after:wN \@@_chk_expr_aux:nNnN + \exp_after:wN { \tex_the:D ##2 ##1 \scan_stop: } + ##2 + } + } +\cs_new_protected:cpn { @@_check-expressions_off: } + { \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2##3##4 {##1} } +\cs_new:Npn \__kernel_chk_expr:nNnN #1#2#3#4 {#1} +\cs_new:Npn \@@_chk_expr_aux:nNnN #1#2#3#4 + { + \tl_if_empty:oF + { + \tex_romannumeral:D - 0 + \exp_after:wN \use_none:n + \int_value:w #3 #2 #1 \scan_stop: + } + { + \__kernel_msg_expandable_error:nnnn + { kernel } { expr } {#4} {#1} + } + #1 + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_deprecation_on:, \@@_deprecation_off:} +% 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, filled up in \pkg{l3deprecation} by calls to +% \cs{__kernel_deprecation_code:nn}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_deprecation_on: + { \g_@@_deprecation_on_tl } +\cs_new_protected:Npn \@@_deprecation_off: + { \g_@@_deprecation_off_tl } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{ +% \l_@@_internal_tl, +% \l_@@_tmpa_tl, +% \l_@@_tmpb_tl, +% } +% For patching. +% \begin{macrocode} +\tl_new:N \l_@@_internal_tl +\tl_new:N \l_@@_tmpa_tl +\tl_new:N \l_@@_tmpb_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{ +% \@@_generate_parameter_list:NNN, +% \@@_build_parm_text:n, +% \@@_build_arg_list:n, +% \@@_arg_list_from_signature:nNN, +% \@@_arg_check_invalid:N, +% \@@_parm_terminate:w, +% \@@_arg_if_braced:n, +% \@@_get_base_form:N, +% \@@_arg_return:N, +% } +% \begin{macro}[TF]{\@@_arg_if_braced:N} +% Some functions don't take the arguments their signature indicates. +% For instance, \cs{clist_concat:NNN} doesn't take (directly) any +% argument, so patching it with something that uses |#1|, |#2|, or +% |#3| results in ``Illegal parameter number in definition of +% \cs{clist_concat:NNN}''. +% +% Instead of changing \emph{the} definition of the macros, we'll +% create a copy of such macros, say, |__debug_clist_concat:NNN| which +% will be defined as +% |<debug code with #1, #2 and #3>\clist_concat:NNN#1#2#3|. For that +% we need to identify the signature of every function and build the +% appropriate parameter list. +% +% \cs{@@_generate_parameter_list:NNN} takes a function in |#1| and +% returns teo parameter lists: |#2| contains the simple |#1#2#3| as +% would be used in the \meta{parameter~text} of the definition and +% |#3| contains the same parameters but with braces where necessary. +% +% With the current implementation the resulting |#3| is, for example +% for |\some_function:NnNn|, |#1{#2}#3{#4}|. While this is correct, +% it might be unnecessary. Bracing everything will usually have the +% same outcome (unless the function was misused in the first place). +% What should be done? +% \begin{macrocode} +\cs_new_protected:Npn \@@_generate_parameter_list:NNN #1#2#3 + { + \tl_set:Nx \l_@@_internal_tl + { \exp_last_unbraced:Nf \use_ii:nnn \cs_split_function:N #1 } + \tl_set:Nx #2 + { \exp_args:NV \@@_build_parm_text:n \l_@@_internal_tl } + \tl_set:Nx #3 + { \exp_args:NV \@@_build_arg_list:n \l_@@_internal_tl } + } +\cs_new:Npn \@@_build_parm_text:n #1 + { + \@@_arg_list_from_signature:nNN { 1 } \c_false_bool #1 + \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \@@_build_arg_list:n #1 + { + \@@_arg_list_from_signature:nNN { 1 } \c_true_bool #1 + \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \@@_arg_list_from_signature:nNN #1 #2 #3 + { + \quark_if_recursion_tail_stop:N #3 + \@@_arg_check_invalid:N #3 + \bool_if:NT #2 { \@@_arg_if_braced:NT #3 { \use_none:n } } + \use:n { \c_hash_str \int_eval:n {#1} } + \exp_args:Nf \@@_arg_list_from_signature:nNN + { \int_eval:n {#1+1} } #2 + } +% \end{macrocode} +% Argument types |w|, |p|, |T|, and |F| shouldn't be included in the +% parameter lists, so we abort the loop if either is found. +% \begin{macrocode} +\cs_new:Npn \@@_arg_check_invalid:N #1 + { + \if:w w #1 \@@_parm_terminate:w \else: + \if:w p #1 \@@_parm_terminate:w \else: + \if:w T #1 \@@_parm_terminate:w \else: + \if:w F #1 \@@_parm_terminate:w \else: + \exp:w + \fi: + \fi: + \fi: + \fi: + \exp_end: + } +\cs_new:Npn \@@_parm_terminate:w + { \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \exp:w } +\prg_new_conditional:Npnn \@@_arg_if_braced:N #1 { T } + { \exp_args:Nf \@@_arg_if_braced:n { \@@_get_base_form:N #1 } } +\cs_new:Npn \@@_arg_if_braced:n #1 + { + \if:w n #1 \prg_return_true: \else: + \if:w N #1 \prg_return_false: \else: + \__kernel_msg_expandable_error:nnn + { kernel } { bad-arg-type } {#1} + \fi: + \fi: + } +\__kernel_msg_new:nnn { kernel } { bad-arg-type } + { Wrong~argument~type~#1. } +% \end{macrocode} +% The macro below is a modifiec copy of +% |\__cs_generate_variant_loop_base:N| to get the base form of an +% argument type given a variant. It serves only to differentiate +% arguments which should be braced from ones which shouldn't. If all +% were to be braced this would be unnecessary. I moved the |n| and |N| +% variants to the beginning of the test as the are much more common +% here. +% \begin{macrocode} +\cs_new:Npn \@@_get_base_form:N #1 + { + \if:w n #1 \@@_arg_return:N n \else: + \if:w N #1 \@@_arg_return:N N \else: + \if:w c #1 \@@_arg_return:N N \else: + \if:w o #1 \@@_arg_return:N n \else: + \if:w V #1 \@@_arg_return:N n \else: + \if:w v #1 \@@_arg_return:N n \else: + \if:w f #1 \@@_arg_return:N n \else: + \if:w e #1 \@@_arg_return:N n \else: + \if:w x #1 \@@_arg_return:N n \else: + \@@_arg_return:N \scan_stop: + \fi: + \fi: + \fi: + \fi: + \fi: + \fi: + \fi: + \fi: + \fi: + \exp_stop_f: + } +\cs_new:Npn \@@_arg_return:N #1 + { \exp_after:wN #1 \exp:w \exp_end_continue_f:w } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{ +% \__kernel_patch:nnn, +% \__kernel_patch_aux:nnn, +% \@@_setup_debug_code:Nnn, +% \@@_add_to_debug_code:Nnn, +% \@@_insert_debug_code:Nnn, +% \__kernel_patch_weird:nnn, +% \__kernel_patch_weird_aux:nnn, +% \@@_patch_weird:Nnn, +% } +% Simple patching by adding material at the start and end of (a +% collection of) functions is straight-forward as we know the catcode +% set up. The approach is essentially that in \pkg{etoolbox}. Notice +% the need to worry about spaces: those are otherwise lost as normally +% in \pkg{expl3} code they would be~|~|. +% +% As discussed above, some functions don't take arguments, so we can't +% patch something that uses an argument in them. For these functions +% \cs{__kernel_patch:nnn} is used. It starts by creating a copy of the +% function (say, \cs{clist_concat:NNN}) with a |__debug_| prefix in +% the name. This copy won't be changed. The code redefines the +% original function to take the exact same arguments as advertised in +% its signature (see \cs{@@_generate_parameter_list:NNN} above). +% The redefined function also contains the debug code in the proper +% position. If a function with the same name and the |__debug_| prefix +% was already defined, then the macro patches that definition by +% adding more debug code to it. +% \begin{macrocode} +\group_begin: + \cs_set_protected:Npn \__kernel_patch:nnn + { + \group_begin: + \char_set_catcode_other:N \# + \__kernel_patch_aux:nnn + } + \cs_set_protected:Npn \__kernel_patch_aux:nnn #1#2#3 + { + \char_set_catcode_parameter:N \# + \char_set_catcode_space:N \ % + \tex_endlinechar:D -1 \scan_stop: + \tl_map_inline:nn {#3} + { + \cs_if_exist:cTF { __debug_ \cs_to_str:N ##1 } + { \@@_add_to_debug_code:Nnn } + { \@@_setup_debug_code:Nnn } + ##1 {#1} {#2} + } + \group_end: + } + \cs_set_protected:Npn \@@_setup_debug_code:Nnn #1#2#3 + { + \cs_gset_eq:cN { __debug_ \cs_to_str:N #1 } #1 + \@@_generate_parameter_list:NNN #1 \l_@@_tmpa_tl \l_@@_tmpb_tl + \exp_args:Nx \tex_scantokens:D + { + \tex_global:D \cs_prefix_spec:N #1 + \tex_def:D \exp_not:N #1 + \tl_use:N \l_@@_tmpa_tl + { + \tl_to_str:n {#2} + \exp_not:c { __debug_ \cs_to_str:N #1 } + \tl_use:N \l_@@_tmpb_tl + \tl_to_str:n {#3} + } + } + } + \cs_set_protected:Npn \@@_add_to_debug_code:Nnn #1#2#3 + { + \use:x + { + \cs_set:Npn \exp_not:N \@@_tmp:w + ####1 \tl_to_str:n { macro: } + ####2 \tl_to_str:n { -> } + ####3 \c_backslash_str \tl_to_str:n { __debug_ } + \cs_to_str:N #1 + ####4 \exp_not:N \q_mark + { + \exp_not:N \exp_args:Nx \exp_not:N \tex_scantokens:D + { + \tex_global:D ####1 + \tex_def:D \exp_not:N #1 ####2 + { + ####3 \tl_to_str:n {#2} + \c_backslash_str __debug_ \cs_to_str:N #1 + ####4 \tl_to_str:n {#3} + } + } + } + } + \exp_after:wN \@@_tmp:w \cs_meaning:N #1 \q_mark + } +% \end{macrocode} +% Some functions, however, won't work with the signature reading setup +% above because their signature contains |w|eird arguments. These +% functions need to be patched using \cs{__kernel_patch_weird:nnn}, +% which won't make a copy of the function, rather it will patch the +% debug code directly into it. This means that whatever argument the +% debug code uses must be actually used by the patched function. +% \begin{macrocode} + \cs_set_protected:Npn \__kernel_patch_weird:nnn + { + \group_begin: + \char_set_catcode_other:N \# + \__kernel_patch_weird_aux:nnn + } + \cs_set_protected:Npn \__kernel_patch_weird_aux:nnn #1#2#3 + { + \char_set_catcode_parameter:N \# + \char_set_catcode_space:N \ % + \tex_endlinechar:D -1 \scan_stop: + \tl_map_inline:nn {#3} + { \@@_patch_weird:Nnn ##1 {#1} {#2} } + \group_end: + } + \cs_set_protected:Npn \@@_patch_weird:Nnn #1#2#3 + { + \use:x + { + \tex_endlinechar:D -1 \scan_stop: + \exp_not:N \tex_scantokens:D + { + \tex_global:D \cs_prefix_spec:N #1 + \tex_def:D \exp_not:N #1 + \cs_argument_spec:N #1 + { + \tl_to_str:n {#2} + \cs_replacement_spec:N #1 + \tl_to_str:n {#3} + } + } + } + } +% \end{macrocode} +% \end{macro} +% +% Patching the second argument to ensure it exists. This happens before +% we alter |#1| so the ordering is correct. For many variable types +% such as \texttt{int} a low-level error occurs when |#2| is unknown, so +% adding a check is not needed. +% \begin{macrocode} + \__kernel_patch:nnn + { \__kernel_chk_var_exist:N #2 } + { } + { + \bool_set_eq:NN + \bool_gset_eq:NN + \clist_set_eq:NN + \clist_gset_eq:NN + \fp_set_eq:NN + \fp_gset_eq:NN + \prop_set_eq:NN + \prop_gset_eq:NN + \seq_set_eq:NN + \seq_gset_eq:NN + \str_set_eq:NN + \str_gset_eq:NN + \tl_set_eq:NN + \tl_gset_eq:NN + } +% \end{macrocode} +% +% Patching both second and third arguments. +% \begin{macrocode} +% \tracingall + \__kernel_patch:nnn + { + \__kernel_chk_var_exist:N #2 + \__kernel_chk_var_exist:N #3 + } + { } + { + \clist_concat:NNN + \clist_gconcat:NNN + \seq_concat:NNN + \seq_gconcat:NNN + \str_concat:NNN + \str_gconcat:NNN + \tl_concat:NNN + \tl_gconcat:NNN + } +% \tracingnone +% \end{macrocode} +% +% Patching where the first argument to a function needs scope-checking: +% either local or global (so two lists). +% \begin{macrocode} + \__kernel_patch:nnn + { \__kernel_chk_var_local:N #1 } + { } + { + \bool_set:Nn + \bool_set_eq:NN + \bool_set_true:N + \bool_set_false:N + \box_set_eq:NN + \box_set_eq_drop:NN + \box_set_to_last:N + \clist_set_eq:NN + \dim_zero:N + \dim_set:Nn + \dim_set_eq:NN + \dim_add:Nn + \dim_sub:Nn + \fp_set_eq:NN + \int_zero:N + \int_set_eq:NN + \int_add:Nn + \int_sub:Nn + \int_incr:N + \int_decr:N + \int_set:Nn + \hbox_set:Nn + \hbox_set_to_wd:Nnn + \hbox_set:Nw + \hbox_set_to_wd:Nnw + \muskip_zero:N + \muskip_set:Nn + \muskip_add:Nn + \muskip_sub:Nn + \muskip_set_eq:NN + \seq_set_eq:NN + \skip_zero:N + \skip_set:Nn + \skip_set_eq:NN + \skip_add:Nn + \skip_sub:Nn + \tl_set:Nn + \tl_set:No + \tl_set:Nx + \tl_set_eq:NN + \tl_put_left:Nn + \tl_put_left:NV + \tl_put_left:No + \tl_put_left:Nx + \tl_put_right:Nn + \tl_put_right:NV + \tl_put_right:No + \tl_put_right:Nx + \tl_build_begin:N + \tl_build_put_right:Nn + \tl_build_put_right:Nx + \tl_build_put_left:Nn + \vbox_set:Nn + \vbox_set_top:Nn + \vbox_set_to_ht:Nnn + \vbox_set:Nw + \vbox_set_to_ht:Nnw + \vbox_set_split_to_ht:NNn + } + \__kernel_patch:nnn + { \__kernel_chk_var_global:N #1 } + { } + { + \bool_gset:Nn + \bool_gset_eq:NN + \bool_gset_true:N + \bool_gset_false:N + \box_gset_eq:NN + \box_gset_eq_drop:NN + \box_gset_to_last:N + \clist_gset_eq:NN + \dim_gset_eq:NN + \dim_gzero:N + \dim_gset:Nn + \dim_gadd:Nn + \dim_gsub:Nn + \fp_gset_eq:NN + \int_gzero:N + \int_gset_eq:NN + \int_gadd:Nn + \int_gsub:Nn + \int_gincr:N + \int_gdecr:N + \int_gset:Nn + \hbox_gset:Nn + \hbox_gset_to_wd:Nnn + \hbox_gset:Nw + \hbox_gset_to_wd:Nnw + \muskip_gzero:N + \muskip_gset:Nn + \muskip_gadd:Nn + \muskip_gsub:Nn + \muskip_gset_eq:NN + \seq_gset_eq:NN + \skip_gzero:N + \skip_gset:Nn + \skip_gset_eq:NN + \skip_gadd:Nn + \skip_gsub:Nn + \tl_gset:Nn + \tl_gset:No + \tl_gset:Nx + \tl_gset_eq:NN + \tl_gput_left:Nn + \tl_gput_left:NV + \tl_gput_left:No + \tl_gput_left:Nx + \tl_gput_right:Nn + \tl_gput_right:NV + \tl_gput_right:No + \tl_gput_right:Nx + \tl_build_gbegin:N + \tl_build_gput_right:Nn + \tl_build_gput_right:Nx + \tl_build_gput_left:Nn + \vbox_gset:Nn + \vbox_gset_top:Nn + \vbox_gset_to_ht:Nnn + \vbox_gset:Nw + \vbox_gset_to_ht:Nnw + \vbox_gset_split_to_ht:NNn + } +% \end{macrocode} +% +% Scoping for constants. +% \begin{macrocode} + \__kernel_patch:nnn + { \__kernel_chk_var_scope:NN c #1 } + { } + { + \bool_const:Nn + \dim_const:Nn + \int_const:Nn + \intarray_const_from_clist:Nn + \muskip_const:Nn + \skip_const:Nn + \tl_const:Nn + \tl_const:Nx + } +% \end{macrocode} +% +% Flag functions. +% \begin{macrocode} + \__kernel_patch:nnn + { \__kernel_chk_flag_exist:n {#1} } + { } + { + \flag_if_raised:nT + \flag_if_raised:nF + \flag_if_raised:nTF + \flag_if_raised_p:n + \flag_height:n + \flag_raise_if_clear:n + \flag_clear:n + } +% \end{macrocode} +% +% Various one-offs. +% \begin{macrocode} + \__kernel_patch:nnn + { \__kernel_chk_cs_exist:N #1 } + { } + { \cs_generate_variant:Nn } + \__kernel_patch:nnn + { \__kernel_chk_var_scope:NN g #1 } + { } + { \intarray_new:Nn } + \__kernel_patch:nnn + { \__kernel_chk_var_scope:NN q #1 } + { } + { \quark_new:N } + \__kernel_patch:nnn + { \__kernel_chk_var_scope:NN s #1 } + { } + { \scan_new:N } +% \end{macrocode} +% +% Patch various internal commands to log definitions of functions. +% First, a kernel internal. Then internals from the \pkg{cs}, +% \pkg{keys} and \pkg{msg} modules. +% \begin{macrocode} + \__kernel_patch:nnn + { } + { + \__kernel_debug_log:x + { Defining~\token_to_str:N #1~ \msg_line_context: } + } + { \__kernel_chk_if_free_cs:N } +%<@@=cs> + \__kernel_patch_weird:nnn + { + \cs_if_free:NF #4 + { + \__kernel_debug_log:x + { + Variant~\token_to_str:N #4~% + already~defined;~ not~ changing~ it~ \msg_line_context: + } + } + } + { } + { \@@_generate_variant:wwNN } +%<@@=keys> + \__kernel_patch:nnn + { + \cs_if_exist:cF { \c_@@_code_root_tl #1 } + { \__kernel_debug_log:x { Defining~key~#1~\msg_line_context: } } + } + { } + { \@@_cmd_set:nn } +%<@@=msg> + \__kernel_patch:nnn + { } + { + \__kernel_debug_log:x + { Defining~message~ #1 / #2 ~\msg_line_context: } + } + { \@@_chk_free:nn } +% \end{macrocode} +% +% \begin{macrocode} +%<@@=prg> +% \end{macrocode} +% Internal functions from \pkg{prg} module. +% \begin{macrocode} + \__kernel_patch_weird:nnn + { \__kernel_chk_cs_exist:c { #5 _p : #6 } } + { } + { \@@_set_eq_conditional_p_form:wNnnnn } + \__kernel_patch_weird:nnn + { \__kernel_chk_cs_exist:c { #5 : #6 TF } } + { } + { \@@_set_eq_conditional_TF_form:wNnnnn } + \__kernel_patch_weird:nnn + { \__kernel_chk_cs_exist:c { #5 : #6 T } } + { } + { \@@_set_eq_conditional_T_form:wNnnnn } + \__kernel_patch_weird:nnn + { \__kernel_chk_cs_exist:c { #5 : #6 F } } + { } + { \@@_set_eq_conditional_F_form:wNnnnn } +% \end{macrocode} +% +% \begin{macrocode} +%<@@=regex> +% \end{macrocode} +% Internal functions from \pkg{regex} module. +% \begin{macrocode} + \__kernel_patch:nnn + { + \@@_trace_push:nnN { regex } { 1 } \@@_escape_use:nnnn + \group_begin: + \tl_set:Nx \l_@@_internal_a_tl + { \@@_trace_pop:nnN { regex } { 1 } \@@_escape_use:nnnn } + \use_none:nnn + } + { } + { \@@_escape_use:nnn } + \__kernel_patch:nnn + { \@@_trace_push:nnN { regex } { 1 } \@@_build:N } + { + \@@_trace_states:n { 2 } + \@@_trace_pop:nnN { regex } { 1 } \@@_build:N + } + { \@@_build:N } + \__kernel_patch:nnn + { \@@_trace_push:nnN { regex } { 1 } \@@_build_for_cs:n } + { + \@@_trace_states:n { 2 } + \@@_trace_pop:nnN { regex } { 1 } \@@_build_for_cs:n + } + { \@@_build_for_cs:n } + \__kernel_patch:nnn + { + \@@_trace:nnx { regex } { 2 } + { + regex~new~state~ + L=\int_use:N \l_@@_left_state_int ~ -> ~ + R=\int_use:N \l_@@_right_state_int ~ -> ~ + M=\int_use:N \l_@@_max_state_int ~ -> ~ + \int_eval:n { \l_@@_max_state_int + 1 } + } + } + { } + { \@@_build_new_state: } + \__kernel_patch:nnn + { \@@_trace_push:nnN { regex } { 1 } \@@_group_aux:nnnnN } + { \@@_trace_pop:nnN { regex } { 1 } \@@_group_aux:nnnnN } + { \@@_group_aux:nnnnN } + \__kernel_patch:nnn + { \@@_trace_push:nnN { regex } { 1 } \@@_branch:n } + { \@@_trace_pop:nnN { regex } { 1 } \@@_branch:n } + { \@@_branch:n } + \__kernel_patch:nnn + { + \@@_trace_push:nnN { regex } { 1 } \@@_match:n + \@@_trace:nnx { regex } { 1 } { analyzing~query~token~list } + } + { \@@_trace_pop:nnN { regex } { 1 } \@@_match:n } + { \@@_match:n } + \__kernel_patch:nnn + { + \@@_trace_push:nnN { regex } { 1 } \@@_match_cs:n + \@@_trace:nnx { regex } { 1 } { analyzing~query~token~list } + } + { \@@_trace_pop:nnN { regex } { 1 } \@@_match_cs:n } + { \@@_match_cs:n } + \__kernel_patch:nnn + { \@@_trace:nnx { regex } { 1 } { initializing } } + { } + { \@@_match_init: } + \__kernel_patch:nnn + { + \@@_trace:nnx { regex } { 2 } + { state~\int_use:N \l_@@_curr_state_int } + } + { } + { \@@_use_state: } + \__kernel_patch:nnn + { \@@_trace_push:nnN { regex } { 1 } \@@_replacement:n } + { \@@_trace_pop:nnN { regex } { 1 } \@@_replacement:n } + { \@@_replacement:n } +% \end{macrocode} +% +% \begin{macrocode} +\group_end: +% \end{macrocode} +% +% \begin{macrocode} +%<@@=debug> +% \end{macrocode} +% +% Patching arguments is a bit more involved: we do these one at a time. +% The basic idea is the same, using a |#| token that is a string. +% \begin{macrocode} +\group_begin: + \cs_set_protected:Npn \__kernel_patch:Nn #1 + { + \group_begin: + \char_set_catcode_other:N \# + \__kernel_patch_aux:Nn #1 + } + \cs_set_protected:Npn \__kernel_patch_aux:Nn #1#2 + { + \char_set_catcode_parameter:N \# + \tex_endlinechar:D -1 \scan_stop: + \exp_args:Nx \tex_scantokens:D + { + \tex_global:D \cs_prefix_spec:N #1 \tex_def:D \exp_not:N #1 + \cs_argument_spec:N #1 + { \exp_args:No \tl_to_str:n { #1 #2 } } + } + \group_end: + } +% \end{macrocode} +% +% The functions here can get a bit repetitive, so we define a helper +% which can re-use the same patch code repeatedly. The main part of the +% patch is the same, so we just have to deal with the part which varies +% depending on the type of expression. +% \begin{macrocode} + \cs_set_protected:Npn \__kernel_patch_eval:nn #1#2 + { + \tl_map_inline:nn {#1} + { + \exp_args:NNx \__kernel_patch:Nn ##1 + { + { \c_hash_str 1 } + { + \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 2 } + \exp_not:n {#2} + \exp_not:N ##1 + } + } + } + } +%<@@=dim> + \__kernel_patch_eval:nn + { + \dim_set:Nn + \dim_gset:Nn + \dim_add:Nn + \dim_gadd:Nn + \dim_sub:Nn + \dim_gsub:Nn + \dim_const:Nn + } + { \@@_eval:w { } } +%<@@=int> + \__kernel_patch_eval:nn + { + \int_set:Nn + \int_gset:Nn + \int_add:Nn + \int_gadd:Nn + \int_sub:Nn + \int_gsub:Nn + \int_const:Nn + } + { \@@_eval:w { } } + \__kernel_patch_eval:nn + { + \muskip_set:Nn + \muskip_gset:Nn + \muskip_add:Nn + \muskip_gadd:Nn + \muskip_sub:Nn + \muskip_gsub:Nn + \muskip_const:Nn + } + { \tex_muexpr:D { \tex_mutoglue:D } } + \__kernel_patch_eval:nn + { + \skip_set:Nn + \skip_gset:Nn + \skip_add:Nn + \skip_gadd:Nn + \skip_sub:Nn + \skip_gsub:Nn + \skip_const:Nn + } + { \tex_glueexpr:D { } } +% \end{macrocode} +% +% Patching expandable expressions, first the one-argument versions, +% then the two-argument ones. +% \begin{macrocode} + \cs_set_protected:Npn \__kernel_patch_eval:nn #1#2 + { + \tl_map_inline:nn {#1} + { + \exp_args:NNx \__kernel_patch:Nn ##1 + { + { + \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 1 } + \exp_not:n {#2} + \exp_not:N ##1 + } + } + } + } +%<@@=box> + \__kernel_patch_eval:nn + { \@@_dim_eval:n } + { \@@_eval:w { } } +%<@@=dim> + \__kernel_patch_eval:nn + { + \dim_eval:n + \dim_to_decimal:n + \dim_to_decimal_in_sp:n + \dim_abs:n + \dim_sign:n + } + { \@@_eval:w { } } +%<@@=int> + \__kernel_patch_eval:nn + { + \int_eval:n + \int_abs:n + \int_sign:n + } + { \@@_eval:w { } } + \__kernel_patch_eval:nn + { + \skip_eval:n + \skip_horizontal:n + \skip_vertical:n + } + { \tex_glueexpr:D { } } + \__kernel_patch_eval:nn + { + \muskip_eval:n + } + { \tex_muexpr:D { \tex_mutoglue:D } } + \cs_set_protected:Npn \__kernel_patch_eval:nn #1#2 + { + \tl_map_inline:nn {#1} + { + \exp_args:NNx \__kernel_patch:Nn ##1 + { + { + \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 1 } + \exp_not:n {#2} + \exp_not:N ##1 + } + { + \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 2 } + \exp_not:n {#2} + \exp_not:N ##1 + } + } + } + } +%<@@=dim> + \__kernel_patch_eval:nn + { + \dim_max:nn + \dim_min:nn + } + { \@@_eval:w { } } +%<@@=int> + \__kernel_patch_eval:nn + { + \int_max:nn + \int_min:nn + \int_div_truncate:nn + \int_mod:nn + } + { \@@_eval:w { } } +% \end{macrocode} +% +% Conditionals: three argument ones then one argument ones +% \begin{macrocode} + \cs_set_protected:Npn \__kernel_patch_cond:nn #1#2 + { + \clist_map_inline:nn { :nNnT , :nNnF , :nNnTF , _p:nNn } + { + \exp_args:Ncx \__kernel_patch:Nn { #1 ##1 } + { + { + \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 1 } + \exp_not:n {#2} + \exp_not:c { #1 ##1 } + } + { \c_hash_str 2 } + { + \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 3 } + \exp_not:n {#2} + \exp_not:c { #1 ##1 } + } + } + } + } +%<@@=dim> + \__kernel_patch_cond:nn { dim_compare } { \@@_eval:w { } } +%<@@=int> + \__kernel_patch_cond:nn { int_compare } { \@@_eval:w { } } + \cs_set_protected:Npn \__kernel_patch_cond:nn #1#2 + { + \clist_map_inline:nn { :nT , :nF , :nTF , _p:n } + { + \exp_args:Ncx \__kernel_patch:Nn { #1 ##1 } + { + { + \exp_not:N \__kernel_chk_expr:nNnN { \c_hash_str 1 } + \exp_not:n {#2} + \exp_not:c { #1 ##1 } + } + } + } + } +%<@@=int> + \__kernel_patch_cond:nn { int_if_even } { \@@_eval:w { } } + \__kernel_patch_cond:nn { int_if_odd } { \@@_eval:w { } } +% \end{macrocode} +% +% Step functions. +% \begin{macrocode} +%<@@=dim> + \__kernel_patch:Nn \dim_step_function:nnnN + { + { + \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } + \dim_step_function:nnnN + } + { + \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } + \dim_step_function:nnnN + } + { + \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } + \dim_step_function:nnnN + } + } +%<@@=int> + \__kernel_patch:Nn \int_step_function:nnnN + { + { + \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } + \int_step_function:nnnN + } + { + \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } + \int_step_function:nnnN + } + { + \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } + \int_step_function:nnnN + } + } +% \end{macrocode} +% +% Odds and ends +% \begin{macrocode} + \__kernel_patch:Nn \dim_to_fp:n { { (#1) } } +% \end{macrocode} +% +% \begin{macrocode} +\group_end: +% \end{macrocode} +% +% \begin{macrocode} +%<@@=skip> +% \end{macrocode} +% This one has catcode changes so must be done by hand. +% \begin{macrocode} +\cs_set_protected:Npn \@@_tmp:w #1 + { + \prg_set_conditional:Npnn \skip_if_finite:n ##1 { p , T , F , TF } + { + \exp_after:wN \@@_if_finite:wwNw + \skip_use:N \tex_glueexpr:D + \__kernel_chk_expr:nNnN + {##1} \tex_glueexpr:D { } \skip_if_finite:n + ; \prg_return_false: + #1 ; \prg_return_true: \q_stop + } + } +\exp_args:No \@@_tmp:w { \tl_to_str:n { fil } } +% \end{macrocode} +% +% \begin{macrocode} +%<@@=msg> +% \end{macrocode} +% +% Messages. +% \begin{macrocode} +\__kernel_msg_new:nnnn { kernel } { debug } + { The~debugging~option~'#1'~does~not~exist~\msg_line_context:. } + { + The~functions~'\iow_char:N\\debug_on:n'~and~ + '\iow_char:N\\debug_off:n'~only~accept~the~arguments~ + 'all',~'check-declarations',~'check-expressions',~ + 'deprecation',~'log-functions',~not~'#1'. + } +\__kernel_msg_new:nnn { kernel } { expr } { '#2'~in~#1 } +\__kernel_msg_new:nnnn { kernel } { local-global } + { Inconsistent~local/global~assignment } + { + \c_@@_coding_error_text_tl + \if:w l #2 Local + \else: + \if:w g #2 Global \else: Constant \fi: + \fi: + \ % + assignment~to~a~ + \if:w l #1 local + \else: + \if:w g #1 global \else: constant \fi: + \fi: + \ % + variable~'#3'. + } +\__kernel_msg_new:nnnn { kernel } { non-declared-variable } + { The~variable~#1~has~not~been~declared~\msg_line_context:. } + { + \c_@@_coding_error_text_tl + Checking~is~active,~and~you~have~tried~do~so~something~like: \\ + \ \ \tl_set:Nn ~ #1 ~ \{ ~ ... ~ \} \\ + without~first~having: \\ + \ \ \tl_new:N ~ #1 \\ + \\ + LaTeX~will~create~the~variable~and~continue. + } +% \end{macrocode} +% +% \begin{macro}{\__kernel_if_debug:TF} +% Flip the switch for deprecated code. +% \begin{macrocode} +\cs_set_protected:Npn \__kernel_if_debug:TF #1#2 {#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx index 41a8bed1a26..82a770ad80a 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -90,6 +90,10 @@ % \end{macrocode} % % \begin{macrocode} +%<*kernel> +% \end{macrocode} +% +% \begin{macrocode} %<@@=deprecation> % \end{macrocode} % @@ -126,6 +130,12 @@ % \end{macrocode} % \end{macro} % +% \begin{variable}{\g__kernel_deprecation_undo_recent_bool} +% \begin{macrocode} +\bool_new:N \g__kernel_deprecation_undo_recent_bool +% \end{macrocode} +% \end{variable} +% % \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) @@ -149,7 +159,7 @@ } < {#1} { \bool_set_true:N \l_@@_grace_period_bool - \bool_if:NTF \l@expl@undo@recent@deprecations@bool + \bool_if:NTF \g__kernel_deprecation_undo_recent_bool } { \use_ii:nn } } @@ -242,9 +252,9 @@ { \bool_if:nTF { - \cs_if_eq_p:NN #3 \cs_new_protected:Npn && + \cs_if_eq_p:NN #3 \cs_gset_protected:Npn && \__kernel_if_debug:TF - { \c_true_bool } { \l@expl@undo@recent@deprecations@bool } + { \c_true_bool } { \g__kernel_deprecation_undo_recent_bool } } { \@@_warn_once:nnNnn {#1} {#2} #4 {#5} {#6} } { \@@_patch_aux:Nn #3 { #4 #5 {#6} } } @@ -263,7 +273,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_warn_once:nnNnn #1#2#3#4#5 { - \cs_new_protected:Npx #3 + \cs_gset_protected:Npx #3 { \__kernel_if_debug:TF { @@ -292,7 +302,7 @@ \cs_new_protected:Npn \@@_patch_aux:Nn #1#2 { #1 #2 - \cs_if_eq:NNTF #1 \cs_new_protected:Npn + \cs_if_eq:NNTF #1 \cs_gset_protected:Npn { \__kernel_deprecation_code:nn { } { \cs_set_protected:Npn #2 } } { \__kernel_deprecation_code:nn { } { \cs_set:Npn #2 } } } @@ -311,7 +321,7 @@ { \exp_not:N #4 { - \cs_if_eq:NNTF #3 \cs_new_protected:Npn + \cs_if_eq:NNTF #3 \cs_gset_protected:Npn { \exp_not:N \__kernel_msg_error:nnnnnn } { \exp_not:N \__kernel_msg_expandable_error:nnnnnn } { kernel } { deprecated-command } @@ -369,12 +379,12 @@ \cs_new_protected:Npn \@@_old_protected:Nnn #1#2#3 { \__kernel_patch_deprecation:nnNNpn {#3} {#2} - \cs_new_protected:Npn #1 { } + \cs_gset_protected:Npn #1 { } } \cs_new_protected:Npn \@@_old:Nnn #1#2#3 { \__kernel_patch_deprecation:nnNNpn {#3} {#2} - \cs_new:Npn #1 { } + \cs_gset:Npn #1 { } } \@@_old:Nnn \box_resize:Nnn { \box_resize_to_wd_and_ht_plus_dp:Nnn } { 2019-01-01 } @@ -545,6 +555,40 @@ % \end{macro} % \end{macro} % +% \subsection{Loading the patches} +% +% When loaded first, the patches are simply read here. +% +% \begin{macrocode} +\group_begin: +\cs_set_protected:Npn \ProvidesExplFile + { + \char_set_catcode_space:n { `\ } + \ProvidesExplFileAux + } +\cs_set_protected:Npx \ProvidesExplFileAux #1#2#3#4 + { + \group_end: + \cs_if_exist:NTF \ProvidesFile + { \exp_not:N \ProvidesFile {#1} [ #2~v#3~#4 ] } + { \iow_log:x { File:~#1~#2~v#3~#4 } } + } +\file_input:n { l3deprecation.def } +% \end{macrocode} +% +% \begin{macrocode} +%</kernel> +% \end{macrocode} +% +% \begin{macrocode} +%<*patches> +% \end{macrocode} +% +% Standard file identification. +% \begin{macrocode} +\ProvidesExplFile{l3deprecation.def}{2019-04-06}{}{L3 Deprecated functions} +% \end{macrocode} +% % \subsection{Deprecated \pkg{l3box} functions} % % \begin{macro}[deprecated = 2021-07-01] @@ -559,10 +603,10 @@ % } % \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 +\cs_gset_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 +\cs_gset_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 } @@ -573,7 +617,7 @@ % \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 +\cs_gset_protected:Npn \hbox_unpack_clear:N { \hbox_unpack_drop:N } \cs_generate_variant:Nn \hbox_unpack_clear:N { c } % \end{macrocode} @@ -582,7 +626,7 @@ % \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 +\cs_gset_protected:Npn \vbox_unpack_clear:N { \vbox_unpack_drop:N } \cs_generate_variant:Nn \vbox_unpack_clear:N { c } % \end{macrocode} @@ -610,7 +654,7 @@ % \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 +\cs_gset_protected:Npn \@@_deprecated_constants:nn #1#2 { #1 \c_zero { 0 } #2 #1 \c_one { 1 } #2 @@ -636,7 +680,12 @@ #1 \c_one_thousand { 1000 } #2 #1 \c_ten_thousand { 10000 } #2 } -\@@_deprecated_constants:nn { \int_const:Nn } { } +\cs_set_protected:Npn \@@_deprecated_constants:Nn #1#2 + { + \cs_if_free:NT #1 + { \int_const:Nn #1 {#2} } + } +\@@_deprecated_constants:nn { \@@_deprecated_constants:Nn } { } \__kernel_deprecation_code:nn { \@@_deprecated_constants:nn @@ -658,7 +707,7 @@ % \begin{macro}[deprecated = 2020-07-01]{\@@_value:w} % Made public. % \begin{macrocode} -\cs_new_eq:NN \@@_value:w \int_value:w +\cs_gset_eq:NN \@@_value:w \int_value:w % \end{macrocode} % \end{macro} % @@ -672,11 +721,11 @@ % \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} } +\cs_gset: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} } +\cs_gset: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} } +\cs_gset_protected:Npn \lua_shipout_x:n #1 { \@@_shipout:n {#1} } % \end{macrocode} % \end{macro} % \end{macro} @@ -690,14 +739,14 @@ % \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 +\cs_gset_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 +\cs_gset_protected:Npn \msg_term:n #1 { \iow_term:n { ************************************************* } \iow_wrap:nnnN { * ~ #1} { * ~ } { } \iow_term:n @@ -709,7 +758,7 @@ % \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 +\cs_gset_protected:Npn \msg_interrupt:nnn #1#2#3 { \tl_if_empty:nTF {#3} { @@ -721,12 +770,12 @@ {#1 \\\\ #2 \\\\ \c_@@_help_text_tl } } } -\cs_new_protected:Npn \@@_old_interrupt_wrap:nn #1#2 +\cs_gset_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 +\cs_gset_protected:Npn \@@_old_interrupt_more_text:n #1 { \exp_args:Nx \tex_errhelp:D { @@ -743,7 +792,7 @@ \tex_lowercase:D { \group_end: - \cs_new_protected:Npn \@@_old_interrupt_text:n #1 + \cs_gset_protected:Npn \@@_old_interrupt_text:n #1 { \iow_term:x { @@ -807,16 +856,16 @@ % 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 } +\cs_gset: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: } +\cs_gset: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 +\cs_gset: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: { } +\cs_gset: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} +\cs_gset:Npn \@@_break:n #1#2 \@@_break_point: {#1} % \end{macrocode} % \end{macro} % @@ -826,21 +875,21 @@ % \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 } +\cs_gset: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 } +\cs_gset: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 } +\cs_gset: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 } +\cs_gset: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 } +\cs_gset: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 } +\cs_gset: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 } +\cs_gset: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 } +\cs_gset:Npn \str_if_eq_x:nnTF { \str_if_eq:eeTF } % \end{macrocode} % \end{macro} % \end{macro} @@ -860,11 +909,11 @@ % } % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN } -\cs_new_protected:Npn \tl_set_from_file:Nnn #1#2#3 +\cs_gset_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 +\cs_gset_protected:Npn \tl_gset_from_file:Nnn #1#2#3 { \group_begin: \file_get:nnN {#3} {#2} \l_@@_internal_a_tl @@ -873,7 +922,7 @@ } \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 +\cs_gset_protected:Npn \tl_set_from_file_x:Nnn #1#2#3 { \group_begin: \file_get:nnN {#3} {#2} \l_@@_internal_a_tl @@ -884,7 +933,7 @@ } \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 +\cs_gset_protected:Npn \tl_gset_from_file_x:Nnn #1#2#3 { \group_begin: \file_get:nnN {#3} {#2} \l_@@_internal_a_tl @@ -903,9 +952,9 @@ % 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 } +\cs_gset_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 } +\cs_gset_protected:Npn \tl_show_analysis:n { \tl_analysis_show:n } % \end{macrocode} % \end{macro} % @@ -919,11 +968,11 @@ % } % \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 } +\cs_gset: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 } +\cs_gset: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 } +\cs_gset:Npn \token_get_replacement_spec:N { \cs_replacement_spec:N } % \end{macrocode} % \end{macro} % @@ -937,6 +986,10 @@ % \end{macro} % % \begin{macrocode} +%</patches> +% \end{macrocode} +% +% \begin{macrocode} %</initex|package> % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index 30270adf8a8..6932483f93f 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-09-19} +% \date{Released 2019-09-28} % \maketitle % \tableofcontents % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx index fbb65b543d9..0c0980060e1 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx index ab6ec3271b6..ab726868654 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -1128,7 +1128,7 @@ \exp_after:wN { \exp:w \@@_eval_register:N #3 } {#1} {#2} } -\cs_new:Npn \::v # 1\::: #2#3 +\cs_new:Npn \::v #1 \::: #2#3 { \exp_after:wN \@@_arg_next:nnn \exp_after:wN { \exp:w \@@_eval_register:c {#3} } @@ -1400,99 +1400,13 @@ % \end{macrocode} % \end{macro} % -% \subsection{Definitions with the automated technique} -% \label{sec:l3expan:gendef} -% -% Some of these could be done more efficiently, but the complexity of -% coding then becomes an issue. Notice that the auto-generated functions -% actually take no arguments themselves. -% % \begin{macro}{\exp_args:Nx} % \begin{macrocode} -\cs_new_protected:Npn \exp_args:Nx { \::x \::: } +\cs_new_protected:Npn \exp_args:Nx #1#2 + { \use:x { \exp_not:N #1 {#2} } } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP] -% { -% \exp_args:Nnc, \exp_args:Nno, \exp_args:NnV, \exp_args:Nnv, \exp_args:Nne, \exp_args:Nnf, -% \exp_args:Noc, \exp_args:Noo, \exp_args:Nof, -% \exp_args:NVo, \exp_args:Nfo, \exp_args:Nff, -% } -% \begin{macro} -% { -% \exp_args:NNx, \exp_args:Ncx, \exp_args:Nnx, -% \exp_args:Nox, \exp_args:Nxo, \exp_args:Nxx, -% } -% Here are the actual function definitions, using the helper functions -% above. -% \begin{macrocode} -\cs_new:Npn \exp_args:Nnc { \::n \::c \::: } -\cs_new:Npn \exp_args:Nno { \::n \::o \::: } -\cs_new:Npn \exp_args:NnV { \::n \::V \::: } -\cs_new:Npn \exp_args:Nnv { \::n \::v \::: } -\cs_new:Npn \exp_args:Nne { \::n \::e \::: } -\cs_new:Npn \exp_args:Nnf { \::n \::f \::: } -\cs_new:Npn \exp_args:Noc { \::o \::c \::: } -\cs_new:Npn \exp_args:Noo { \::o \::o \::: } -\cs_new:Npn \exp_args:Nof { \::o \::f \::: } -\cs_new:Npn \exp_args:NVo { \::V \::o \::: } -\cs_new:Npn \exp_args:Nfo { \::f \::o \::: } -\cs_new:Npn \exp_args:Nff { \::f \::f \::: } -\cs_new_protected:Npn \exp_args:NNx { \::N \::x \::: } -\cs_new_protected:Npn \exp_args:Ncx { \::c \::x \::: } -\cs_new_protected:Npn \exp_args:Nnx { \::n \::x \::: } -\cs_new_protected:Npn \exp_args:Nox { \::o \::x \::: } -\cs_new_protected:Npn \exp_args:Nxo { \::x \::o \::: } -\cs_new_protected:Npn \exp_args:Nxx { \::x \::x \::: } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP] -% { -% \exp_args:NNNv, \exp_args:NNcf, -% \exp_args:NNno, \exp_args:NNnV, \exp_args:NNoo, \exp_args:NNVV, -% \exp_args:Ncno, \exp_args:NcnV, \exp_args:Ncoo, \exp_args:NcVV, -% \exp_args:Nnnc, \exp_args:Nnno, \exp_args:Nnnf, \exp_args:Nnff, -% \exp_args:Nooo, \exp_args:Noof, \exp_args:Nffo, -% } -% \begin{macro} -% { -% \exp_args:NNNx, \exp_args:NNnx, \exp_args:NNox, -% \exp_args:Nccx, \exp_args:Ncnx, -% \exp_args:Nnnx, \exp_args:Nnox, \exp_args:Noox, -% } -% \begin{macrocode} -\cs_new:Npn \exp_args:NNNv { \::N \::N \::v \::: } -\cs_new:Npn \exp_args:NNcf { \::N \::c \::f \::: } -\cs_new:Npn \exp_args:NNno { \::N \::n \::o \::: } -\cs_new:Npn \exp_args:NNnV { \::N \::n \::V \::: } -\cs_new:Npn \exp_args:NNoo { \::N \::o \::o \::: } -\cs_new:Npn \exp_args:NNVV { \::N \::V \::V \::: } -\cs_new:Npn \exp_args:Ncno { \::c \::n \::o \::: } -\cs_new:Npn \exp_args:NcnV { \::c \::n \::V \::: } -\cs_new:Npn \exp_args:Ncoo { \::c \::o \::o \::: } -\cs_new:Npn \exp_args:NcVV { \::c \::V \::V \::: } -\cs_new:Npn \exp_args:Nnnc { \::n \::n \::c \::: } -\cs_new:Npn \exp_args:Nnno { \::n \::n \::o \::: } -\cs_new:Npn \exp_args:Nnnf { \::n \::n \::f \::: } -\cs_new:Npn \exp_args:Nnff { \::n \::f \::f \::: } -\cs_new:Npn \exp_args:Nooo { \::o \::o \::o \::: } -\cs_new:Npn \exp_args:Noof { \::o \::o \::f \::: } -\cs_new:Npn \exp_args:Nffo { \::f \::f \::o \::: } -\cs_new_protected:Npn \exp_args:NNNx { \::N \::N \::x \::: } -\cs_new_protected:Npn \exp_args:NNnx { \::N \::n \::x \::: } -\cs_new_protected:Npn \exp_args:NNox { \::N \::o \::x \::: } -\cs_new_protected:Npn \exp_args:Nnnx { \::n \::n \::x \::: } -\cs_new_protected:Npn \exp_args:Nnox { \::n \::o \::x \::: } -\cs_new_protected:Npn \exp_args:Nccx { \::c \::c \::x \::: } -\cs_new_protected:Npn \exp_args:Ncnx { \::c \::n \::x \::: } -\cs_new_protected:Npn \exp_args:Noox { \::o \::o \::x \::: } -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \subsection{Last-unbraced versions} % % \begin{macro}[EXP]{\@@_arg_last_unbraced:nn} @@ -2263,7 +2177,6 @@ % iterate through the comma list of variant argument specifiers, which % we first convert to a string: the reason is explained later. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_cs_exist:N #1 } { } \cs_new_protected:Npn \cs_generate_variant:Nn #1#2 { \@@_generate_variant:N #1 @@ -2598,9 +2511,9 @@ % \begin{macrocode} \cs_new:Npn \@@_generate_variant_same:N #1 { - \if:w N #1 N \else: - \if:w p #1 p \else: - n + \if:w N #1 #1 \else: + \if:w p #1 #1 \else: + \token_to_str:N n \if:w n #1 \else: \@@_generate_variant_loop_special:NNwNNnn #1#1 \fi: @@ -2618,18 +2531,6 @@ % \cs{cs_new_protected:Npx}. Then define the variant by % combining the |\exp_args:N #3| variant and the base function. % \begin{macrocode} -\__kernel_patch:nnNNpn - { - \cs_if_free:NF #4 - { - \__kernel_debug_log:x - { - Variant~\token_to_str:N #4~% - already~defined;~ not~ changing~ it~ \msg_line_context: - } - } - } - { } \cs_new_protected:Npn \@@_generate_variant:wwNN #1 \q_mark #2 \q_stop #3#4 { @@ -2646,38 +2547,129 @@ % \end{macro} % % \begin{macro}{\@@_generate_internal_variant:n} -% \begin{macro}{\@@_generate_internal_variant:wwnw} % \begin{macro}[rEXP]{\@@_generate_internal_variant_loop:n} -% Test if |\exp_args:N #1| is already defined and if not define it via -% the |\::| commands using the chars in |#1|. If |#1| contains an |x| -% (this is the place where having converted the original comma-list -% argument to a string is very important), the result should be -% protected, and the next variant to be defined using that internal -% variant should be protected. +% First test for the presence of |x| (this is where working with +% strings makes our lives easier), as the result should be protected, +% and the next variant to be defined using that internal variant +% should be protected (done by setting \cs{@@_tmp:w}). Then call +% \cs{@@_generate_internal_variant:NNn} with arguments +% \cs{cs_new_protected:cpn} \cs{use:x} (for protected) or +% \cs{cs_new:cpn} \cs{tex_expanded:D} (expandable) and the signature. If |p| +% appears in the signature, or if the function to be defined is +% expandable and the primitive \tn{expanded} is not available, call +% some fall-back code that just puts the appropriate |\::| commands. +% Otherwise, call \cs{@@_generate_internal_one_go:NNn} to construct +% the \cs[no-index]{exp_args:N\dots} function as a macro taking up to +% $9$~arguments and expanding them using \cs{use:x} or \cs{tex_expanded:D}. % \begin{macrocode} \cs_new_protected:Npx \@@_generate_internal_variant:n #1 { - \exp_not:N \@@_generate_internal_variant:wwnNwnn + \exp_not:N \@@_generate_internal_variant:wwnNwn #1 \exp_not:N \q_mark { \cs_set_eq:NN \exp_not:N \@@_tmp:w \cs_new_protected:Npx } - \cs_new_protected:cpx + \cs_new_protected:cpn + \use:x \token_to_str:N x \exp_not:N \q_mark { } - \cs_new:cpx + \cs_new:cpn + \exp_not:N \tex_expanded:D \exp_not:N \q_stop - { exp_args:N #1 } - { - \exp_not:N \@@_generate_internal_variant_loop:n #1 - { : \exp_not:N \use_i:nn } - } + {#1} } \exp_last_unbraced:NNNNo - \cs_new_protected:Npn \@@_generate_internal_variant:wwnNwnn #1 - { \token_to_str:N x } #2 \q_mark #3#4#5 \q_stop #6#7 + \cs_new_protected:Npn \@@_generate_internal_variant:wwnNwn #1 + { \token_to_str:N x } #2 \q_mark #3#4#5#6 \q_stop #7 { #3 - \cs_if_free:cT {#6} { #4 {#6} {#7} } + \cs_if_free:cT { exp_args:N #7 } + { \@@_generate_internal_variant:NNn #4 #5 {#7} } } +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new_protected:Npn \@@_generate_internal_variant:NNn ##1##2##3 + { + \@@_generate_internal_test:Nw ##2 ##3 + \q_mark + { + \use:x + { + ##1 { exp_args:N ##3 } + { \@@_generate_internal_variant_loop:n ##3 { : \use_i:nn } } + } + } + #1 + \q_mark + { \exp_not:n { \@@_generate_internal_one_go:NNn ##1 ##2 {##3} } } + \q_stop + } + \cs_new_protected:Npn \@@_generate_internal_test_aux:w + ##1 #1 ##2 \q_mark ##3 ##4 \q_stop {##3} + \cs_if_exist:NTF \tex_expanded:D + { + \cs_new_eq:NN \@@_generate_internal_test:Nw + \@@_generate_internal_test_aux:w + } + { + \cs_new_protected:Npn \@@_generate_internal_test:Nw ##1 + { + \if_meaning:w \tex_expanded:D ##1 + \exp_after:wN \@@_generate_internal_test_aux:w + \exp_after:wN #1 + \else: + \exp_after:wN \@@_generate_internal_test_aux:w + \fi: + } + } + } +\exp_args:No \@@_tmp:w { \token_to_str:N p } +\cs_new_protected:Npn \@@_generate_internal_one_go:NNn #1#2#3 + { + \@@_generate_internal_loop:nwnnw + { \exp_not:N ##1 } 1 . { } { } + #3 { ? \@@_generate_internal_end:w } X ; + 23456789 { ? \@@_generate_internal_long:w } ; + #1 #2 {#3} + } +\cs_new_protected:Npn \@@_generate_internal_loop:nwnnw #1#2 . #3#4#5#6 ; #7 + { + \use_none:n #5 + \use_none:n #7 + \cs_if_exist_use:cF { @@_generate_internal_#5:NN } + { \@@_generate_internal_other:NN } + #5 #7 + #7 . + { #3 #1 } { #4 ## #2 } + #6 ; + } +\cs_new_protected:Npn \@@_generate_internal_N:NN #1#2 + { \@@_generate_internal_loop:nwnnw { \exp_not:N ###2 } } +\cs_new_protected:Npn \@@_generate_internal_c:NN #1#2 + { \exp_args:No \@@_generate_internal_loop:nwnnw { \exp_not:c {###2} } } +\cs_new_protected:Npn \@@_generate_internal_n:NN #1#2 + { \@@_generate_internal_loop:nwnnw { { \exp_not:n {###2} } } } +\cs_new_protected:Npn \@@_generate_internal_x:NN #1#2 + { \@@_generate_internal_loop:nwnnw { {###2} } } +\cs_new_protected:Npn \@@_generate_internal_other:NN #1#2 + { + \exp_args:No \@@_generate_internal_loop:nwnnw + { + \exp_after:wN + { + \exp:w \exp_args:NNc \exp_after:wN \exp_end: + { exp_not:#1 } {###2} + } + } + } +\cs_new_protected:Npn \@@_generate_internal_end:w #1 . #2#3#4 ; #5 ; #6#7#8 + { #6 { exp_args:N #8 } #3 { #7 {#2} } } +\cs_new_protected:Npn \@@_generate_internal_long:w #1 N #2#3 . #4#5#6# + { + \exp_args:Nx \@@_generate_internal_long:nnnNNn + { \@@_generate_internal_variant_loop:n #2 #6 { : \use_i:nn } } + {#4} {#5} + } +\cs_new:Npn \@@_generate_internal_long:nnnNNn #1#2#3#4 ; ; #5#6#7 + { #5 { exp_args:N #7 } #3 { #6 { \exp_not:n {#1} {#2} } } } % \end{macrocode} % This command grabs char by char outputting |\::#1| (not expanded % further). We avoid tests by putting a trailing |: \use_i:nn|, which @@ -2693,7 +2685,6 @@ % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro} % { @@ -2756,15 +2747,12 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\exp_args_generate:n, \@@_args_generate:Nn} -% \begin{macro}[EXP]{\@@_args_generate:n} +% \begin{macro}{\exp_args_generate:n} % This function is not used in the kernel hence we can use functions % that are defined in later modules. It also does not need to be fast % so use inline mappings. For each requested variant we check that % there are no characters besides |NnpcofVvx|, in particular that -% there are no spaces. Then we loop through the variant specifier and -% convert each letter to \cs[no-index]{::\meta{variant letter}}, with a -% trailing \cs{:::}. +% there are no spaces. Then we just call the internal function. % \begin{macrocode} \cs_new_protected:Npn \exp_args_generate:n #1 { @@ -2776,21 +2764,105 @@ { \__kernel_msg_error:nnnn { kernel } { invalid-exp-args } {####1} {##1} - \str_map_break:n { \use_none:nnnn } + \str_map_break:n { \use_none:nn } } } - \exp_args:Nc \@@_args_generate:Nn { exp_args:N ##1 } {##1} + \@@_generate_internal_variant:n {##1} } } -\cs_new_protected:Npn \@@_args_generate:Nn #1#2 - { - \cs_if_exist:NF #1 - { - \str_if_in:nnTF {#2} { x } { \cs_new_protected:Npx } { \cs_new:Npx } - #1 { \tl_map_function:nN { #2 : } \@@_args_generate:n } - } - } -\cs_new:Npn \@@_args_generate:n #1 { \exp_not:c { :: #1 } } +% \end{macrocode} +% \end{macro} +% +% \subsection{Definitions with the automated technique} +% \label{sec:l3expan:gendef} +% +% Some of these could be done more efficiently, but the complexity of +% coding then becomes an issue. Notice that the auto-generated functions +% actually take no arguments themselves. +% +% \begin{macro}[EXP] +% { +% \exp_args:Nnc, \exp_args:Nno, \exp_args:NnV, \exp_args:Nnv, \exp_args:Nne, \exp_args:Nnf, +% \exp_args:Noc, \exp_args:Noo, \exp_args:Nof, +% \exp_args:NVo, \exp_args:Nfo, \exp_args:Nff, +% } +% \begin{macro} +% { +% \exp_args:NNx, \exp_args:Ncx, \exp_args:Nnx, +% \exp_args:Nox, \exp_args:Nxo, \exp_args:Nxx, +% } +% Here are the actual function definitions, using the helper +% functions above. The group is used because +% \cs{@@_generate_internal_variant:n} redefines \cs{@@_tmp:w} locally. +% \begin{macrocode} +\cs_set_protected:Npn \@@_tmp:w #1 + { + \group_begin: + \exp_args:No \@@_generate_internal_variant:n + { \tl_to_str:n {#1} } + \group_end: + } +\@@_tmp:w { nc } +\@@_tmp:w { no } +\@@_tmp:w { nV } +\@@_tmp:w { nv } +\@@_tmp:w { ne } +\@@_tmp:w { nf } +\@@_tmp:w { oc } +\@@_tmp:w { oo } +\@@_tmp:w { of } +\@@_tmp:w { Vo } +\@@_tmp:w { fo } +\@@_tmp:w { ff } +\@@_tmp:w { Nx } +\@@_tmp:w { cx } +\@@_tmp:w { nx } +\@@_tmp:w { ox } +\@@_tmp:w { xo } +\@@_tmp:w { xx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP] +% { +% \exp_args:NNcf, +% \exp_args:NNno, \exp_args:NNnV, \exp_args:NNoo, \exp_args:NNVV, +% \exp_args:Ncno, \exp_args:NcnV, \exp_args:Ncoo, \exp_args:NcVV, +% \exp_args:Nnnc, \exp_args:Nnno, \exp_args:Nnnf, \exp_args:Nnff, +% \exp_args:Nooo, \exp_args:Noof, \exp_args:Nffo, +% } +% \begin{macro} +% { +% \exp_args:NNNx, \exp_args:NNnx, \exp_args:NNox, +% \exp_args:Nccx, \exp_args:Ncnx, +% \exp_args:Nnnx, \exp_args:Nnox, \exp_args:Noox, +% } +% \begin{macrocode} +\@@_tmp:w { Ncf } +\@@_tmp:w { Nno } +\@@_tmp:w { NnV } +\@@_tmp:w { Noo } +\@@_tmp:w { NVV } +\@@_tmp:w { cno } +\@@_tmp:w { cnV } +\@@_tmp:w { coo } +\@@_tmp:w { cVV } +\@@_tmp:w { nnc } +\@@_tmp:w { nno } +\@@_tmp:w { nnf } +\@@_tmp:w { nff } +\@@_tmp:w { ooo } +\@@_tmp:w { oof } +\@@_tmp:w { ffo } +\@@_tmp:w { NNx } +\@@_tmp:w { Nnx } +\@@_tmp:w { Nox } +\@@_tmp:w { nnx } +\@@_tmp:w { nox } +\@@_tmp:w { ccx } +\@@_tmp:w { cnx } +\@@_tmp:w { oox } % \end{macrocode} % \end{macro} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index c40f61acbdf..cea19957dfa 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -271,6 +271,40 @@ % ignores any trailing new-line marker from the file it reads. % \end{function} % +% \begin{function}[added = 2019-01-13]{\ior_map_variable:NNn} +% \begin{syntax} +% \cs{ior_map_variable:NNn} \meta{stream} \meta{tl~var} \Arg{code} +% \end{syntax} +% For each set of \meta{lines} obtained by calling \cs{ior_get:NN} +% until reaching the end of the file, stores the \meta{lines} in the +% \meta{tl~var} then applies the \meta{code}. The \meta{code} will +% usually make use of the \meta{variable}, but this is not enforced. +% The assignments to the \meta{variable} are local. +% Its value after the loop is the last set of \meta{lines}, or its +% original value if the \meta{stream} is empty. \TeX{} ignores +% any trailing new-line marker from the file it reads. +% This function is typically faster than \cs{ior_map_inline:Nn}. +% \end{function} +% +% \begin{function}[added = 2019-01-13]{\ior_str_map_variable:NNn} +% \begin{syntax} +% \cs{ior_str_map_variable:NNn} \meta{stream} \meta{variable} \Arg{code} +% \end{syntax} +% For each \meta{line} in the \meta{stream}, stores the \meta{line} in +% the \meta{variable} then applies the \meta{code}. The material is +% read from the \meta{stream} as a series of tokens with category code +% $12$ (other), with the exception of space characters which are given +% category code $10$ (space). The \meta{code} will usually make use +% of the \meta{variable}, but this is not enforced. The assignments +% to the \meta{variable} are local. Its value after the loop is the +% last \meta{line}, or its original value if the \meta{stream} is +% empty. Note that \TeX{} removes trailing +% space and tab characters (character codes 32 and 9) from every line +% upon input. \TeX{} also ignores any trailing new-line marker from +% the file it reads. +% This function is typically faster than \cs{ior_str_map_inline:Nn}. +% \end{function} +% % \begin{function}[added = 2012-06-29]{\ior_map_break:} % \begin{syntax} % \cs{ior_map_break:} @@ -735,6 +769,28 @@ % This is not available in older versions of \XeTeX{}. % \end{function} % +% \begin{function}[added = 2019-05-13, updated = 2019-09-20, pTF, EXP] +% {\file_compare_timestamp:nNn} +% \begin{syntax} +% \cs{file_compare_timestamp:nNn} \Arg{file-1} \meta{comparator} \Arg{file-2} \Arg{true code} \Arg{false code} +% \end{syntax} +% Compares the file stamps on the two \meta{files} as indicated by +% the \meta{comparator}, and inserts either the \meta{true code} +% or \meta{false case} as required. A file which is not found +% is treated as older than any file which is found. This allows for +% example the construct +% \begin{verbatim} +% \file_compare_timestamp:nNnT { source-file } > { derived-file } +% { +% % Code to regenerate derived file +% } +% \end{verbatim} +% to work when the derived file is entirely absent. The timestamp +% of two absent files is regarded as different. +% This is not available in older versions of \XeTeX{}. +% \end{function} +% +% % \begin{function}[updated = 2017-06-26]{\file_input:n} % \begin{syntax} % \cs{file_input:n} \Arg{file name} @@ -2815,6 +2871,106 @@ % \end{macro} % \end{macro} % +% \begin{macro}[EXP]{\@@_str_cmp:nn} +% \begin{macro}[EXP]{\@@_str_escape:n} +% As we are doing a fixed-length \enquote{big} integer comparison, it +% is easiest to use the low-level behavior of string comparisons. +% \begin{macrocode} +\cs_new:Npn \@@_str_cmp:nn #1#2 { \tex_strcmp:D {#1} {#2} } +\sys_if_engine_luatex:T + { + \cs_set:Npn \@@_str_cmp:nn #1#2 + { + \lua_now:e + { + l3kernel.strcmp + ( + " \@@_str_escape:n {#1}", + " \@@_str_escape:n {#2}" + ) + } + } + \cs_new:Npn \@@_str_escape:n #1 + { + \lua_escape:e + { \__kernel_tl_to_str:w \use:e { {#1} } } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP, pTF]{\file_compare_timestamp:nNn} +% \begin{macro}[EXP]{\@@_compare_timestamp:nnN} +% \begin{macro}[EXP]{\@@_timestamp:n} +% Comparison of file date can be done by using the low-level nature of the +% string comparison functions. +% \begin{macrocode} +\prg_new_conditional:Npnn \file_compare_timestamp:nNn #1#2#3 + { p , T , F , TF } + { + \exp_args:Nee \@@_compare_timestamp:nnN + { \file_full_name:n {#1} } + { \file_full_name:n {#3} } + #2 + } +\cs_new:Npn \@@_compare_timestamp:nnN #1#2#3 + { + \tl_if_blank:nTF {#1} + { + \if_charcode:w #3 < + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + { + \tl_if_blank:nTF {#2} + { + \if_charcode:w #3 > + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + { + \if_int_compare:w + \@@_str_cmp:nn + { \@@_timestamp:n {#1} } + { \@@_timestamp:n {#2} } + #3 0 \exp_stop_f: + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + } + } +\sys_if_engine_luatex:TF + { + \cs_new:Npn \@@_timestamp:n #1 + { + \lua_now:e + { l3kernel.filemoddate ( " \lua_escape:e {#1} " ) } + } + } + { \cs_new_eq:NN \@@_timestamp:n \tex_filemoddate:D } +\cs_if_exist:NF \tex_filemoddate:D + { + \prg_set_conditional:Npnn \file_compare_timestamp:nNn #1#2#3 + { p , T , F , TF } + { + \__kernel_msg_expandable_error:nnn + { kernel } { primitive-not-available } + { \(pdf)filemoddate } + \prg_return_false: + } + } +% \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 % add a path to a file. If the file was found, the path contains @@ -3164,6 +3320,50 @@ } % \end{macrocode} % +% \subsection{Functions delayed from earlier modules} +% +%<@@=sys> +% +% \begin{variable}{\c_sys_platform_str} +% Detecting the platform on \LuaTeX{} is easy: for other engines, we use +% the fact that the two common cases have special null files. It is possible +% to probe further (see package \pkg{platform}), but that requires shell +% escape and seems unlikely to be useful. This is set up here as it requires +% file searching. +% \begin{macrocode} +\sys_if_engine_luatex:TF + { + \str_const:Nx \c_sys_platform_str + { \tex_directlua:D { tex.print(os.type) } } + } + { + \file_if_exist:nTF { nul: } + { + \file_if_exist:nF { /dev/null } + { \str_const:Nn \c_sys_platform_str { windows } } + } + { + \file_if_exist:nT { /dev/null } + { \str_const:Nn \c_sys_platform_str { unix } } + } + } +\cs_if_exist:NF \c_sys_platform_str + { \str_const:Nn \c_sys_platform_str { unknown } } +% \end{macrocode} +% \end{variable} +% \begin{macro}[pTF]{\sys_if_platform_unix:} +% \begin{macro}[pTF]{\sys_if_platform_windows:} +% We can now set up the tests. +% \begin{macrocode} +\clist_map_inline:nn { unix , windows } + { + \@@_const:nn { sys_if_platform_ #1 } + { \str_if_eq_p:Vn \c_sys_platform_str { #1 } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx index 4519a4639b3..21534789e3d 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx index 90e5a012bc6..6f86d193c12 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -198,8 +198,6 @@ % When the option \texttt{check-declarations} is used, check for the % function defined by \cs{flag_new:n}. % \begin{macrocode} -\__kernel_patch:nnNNpn - { \exp_args:Nc \__kernel_chk_var_exist:N { flag~#1 } } { } \cs_new_protected:Npn \flag_clear:n #1 { \@@_clear:wn 0 ; {#1} } \cs_new_protected:Npn \@@_clear:wn #1 ; #2 { @@ -244,29 +242,6 @@ % % \subsection{Expandable flag commands} % -% \begin{macro}[EXP]{\@@_chk_exist:n} -% Analogue of \cs{__kernel_chk_var_exist:N} for flags, and with an -% expandable error. We need to add checks by hand because flags are -% not implemented in terms of other variables. Not all functions need -% to be patched since some are defined in terms of others. -% \begin{macrocode} -%<*package> -\__kernel_if_debug:TF - { - \cs_new:Npn \@@_chk_exist:n #1 - { - \flag_if_exist:nF {#1} - { - \__kernel_msg_expandable_error:nnn - { kernel } { bad-variable } { flag~#1~ } - } - } - } - { } -%</package> -% \end{macrocode} -% \end{macro} -% % \begin{macro}[EXP, pTF]{\flag_if_exist:n} % A flag exist if the corresponding trap \cs[no-index]{flag \meta{flag % name}:n} is defined. @@ -282,7 +257,6 @@ % \begin{macro}[EXP, pTF]{\flag_if_raised:n} % Test if the flag has a non-zero height, by checking the |0| control sequence. % \begin{macrocode} -\__kernel_patch_conditional:nNNpnn { \@@_chk_exist:n {#1} } \prg_new_conditional:Npnn \flag_if_raised:n #1 { p , T , F , TF } { \if_cs_exist:w flag~#1~0 \cs_end: @@ -299,7 +273,6 @@ % Extract the value of the flag by going through all of the % control sequences starting from |0|. % \begin{macrocode} -\__kernel_patch:nnNNpn { \@@_chk_exist:n {#1} } { } \cs_new:Npn \flag_height:n #1 { \@@_height_loop:wn 0; {#1} } \cs_new:Npn \@@_height_loop:wn #1 ; #2 { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3format.ins b/Master/texmf-dist/source/latex/l3kernel/l3format.ins index 35279ca592b..bdc5516701f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3format.ins +++ b/Master/texmf-dist/source/latex/l3kernel/l3format.ins @@ -105,7 +105,7 @@ and all files in that bundle must be distributed together. \from{l3luatex.dtx} {initex,tex} \from{l3unicode.dtx} {initex} \from{l3candidates.dtx} {initex} - \from{l3deprecation.dtx}{initex} + \from{l3deprecation.dtx}{initex,kernel} % ======== FORMAT ONLY ========= \from{l3final.dtx} {initex} % ============================== @@ -131,6 +131,9 @@ and all files in that bundle must be distributed together. \file{l3str-enc-iso885916.def} {\from{l3str-convert.dtx}{iso885916}}% } +\generate{\file{l3debug.def}{\from{l3debug.dtx}{initex}}} +\generate{\file{l3deprecation.def}{\from{l3deprecation.dtx}{initex,patches}}} + \generate{\file{l3docstrip.tex}{\from{l3docstrip.dtx}{program}}} % Lua code (currently identical to the package-mode version) diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx index 93ea9dedc8a..6f65566c3e4 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-09-19} +% \date{Released 2019-09-28} % \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 3402c4ed9b4..a7cc9a2e950 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx index 1d88df67361..03d127cc241 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx index dfd052b8434..cdf2868c818 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -499,7 +499,6 @@ % performed by \cs{@@_mul_npos_o:Nww}, and cancelled by % \cs{prg_do_nothing:} here. % \begin{macrocode} -\__kernel_patch_args:nNNpn { { (#1) } } \cs_new:Npn \dim_to_fp:n #1 { \exp_after:wN \@@_from_dim_test:ww @@ -550,6 +549,16 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\fp_sign:n} +% Trivial but useful. See the implementation of \cs{fp_add:Nn} for an +% explanation of why to use \cs{@@_parse:n}, namely, for better error +% reporting. +% \begin{macrocode} +\cs_new:Npn \fp_sign:n #1 + { \fp_to_decimal:n { sign \@@_parse:n {#1} } } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[EXP]{\fp_abs:n} % Trivial but useful. See the implementation of \cs{fp_add:Nn} for an % explanation of why to use \cs{@@_parse:n}, namely, for better error diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx index 81bb592dc00..eb764de3b8a 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx index a8e2dffa12f..b716765b48b 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx index 9b63aec53b4..7414c7d31c9 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index aed0a3ada21..71258ad48ce 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx index 069b0cf3607..64dc995c04f 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx index 9437f8e3990..1ef386ad6e7 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx index 91b645d0ae9..7e0cf605ee0 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-09-19} +% \date{Released 2019-09-28} % \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 8927ab89787..f490649563f 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx index fe501411192..4c0451d7261 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -72,7 +72,7 @@ % negation $\mathop{!}x$, conjunction % $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 Exponentials: $\exp x$, $\ln x$, $x^y$, $\operatorname{logb} x$. % \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 @@ -260,6 +260,18 @@ % This function is identical to \cs{fp_to_decimal:n}. % \end{function} % +% \begin{function}[EXP, added = 2018-11-03]{\fp_sign:n} +% \begin{syntax} +% \cs{fp_sign:n} \Arg{fpexpr} +% \end{syntax} +% Evaluates the \meta{fpexpr} and leaves its sign in the input stream +% using \cs{fp_eval:n} |{sign(|\meta{result}|)}|: $+1$ for positive +% numbers and for $+\infty$, $-1$ for negative numbers and for +% $-\infty$, $\pm 0$ for $\pm 0$. If the operand is a tuple or is +% \nan{}, then \enquote{invalid operation} occurs and the result +% is~$0$. +% \end{function} +% % \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08] % {\fp_to_decimal:N, \fp_to_decimal:c, \fp_to_decimal:n} % \begin{syntax} @@ -1065,6 +1077,19 @@ % operation} occurs. % \end{function} % +% \begin{function}[EXP, added = 2018-11-03]{logb} +% \begin{syntax} +% \cs{fp_eval:n} \{ |logb(| \meta{fpexpr} |)| \} +% \end{syntax} +% Determines the exponent of the \meta{fpexpr}, namely the floor of +% the base-$10$ logarithm of its absolute value. \enquote{Division by +% zero} occurs when evaluating $\operatorname{logb}(\pm 0) = -\infty$. +% Other special values are $\operatorname{logb}(\pm\infty)=+\infty$ +% and $\operatorname{logb}(\nan{})=\nan{}$. If the operand is a tuple +% or is \nan{}, then \enquote{invalid operation} occurs and the result +% is \nan{}. +% \end{function} +% % \begin{function}[tested = m3fp-logic002]{max, min} % \begin{syntax} % \cs{fp_eval:n} \{ |max(| \meta{fpexpr_1} |,| \meta{fpexpr_2} |,| \ldots{} |)| \} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx index 6238ad6ddd7..4dcf58decfb 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -58,8 +58,55 @@ % close to that of \pkg{l3intarray}. The size of the array is fixed and % must be given at point of initialisation % -% Currently \emph{all} functions in this module are candidates. Their -% documentation can be found in \pkg{l3candidates}. +% \begin{function}[added = 2018-05-05]{\fparray_new:Nn} +% \begin{syntax} +% \cs{fparray_new:Nn} \meta{fparray~var} \Arg{size} +% \end{syntax} +% Evaluates the integer expression \meta{size} and allocates an +% \meta{floating point array variable} with that number of (zero) +% entries. The variable name should start with |\g_| because +% assignments are always global. +% \end{function} +% +% \begin{function}[EXP, added = 2018-05-05]{\fparray_count:N} +% \begin{syntax} +% \cs{fparray_count:N} \meta{fparray~var} +% \end{syntax} +% Expands to the number of entries in the \meta{floating point array +% variable}. This is performed in constant time. +% \end{function} +% +% \begin{function}[added = 2018-05-05]{\fparray_gset:Nnn} +% \begin{syntax} +% \cs{fparray_gset:Nnn} \meta{fparray~var} \Arg{position} \Arg{value} +% \end{syntax} +% Stores the result of evaluating the floating point expression +% \meta{value} into the \meta{floating point array variable} at the +% (integer expression) \meta{position}. If the \meta{position} is not +% between $1$ and the \cs{fparray_count:N}, an error occurs. +% Assignments are always global. +% \end{function} +% +% \begin{function}[added = 2018-05-05]{\fparray_gzero:N} +% \begin{syntax} +% \cs{fparray_gzero:N} \meta{fparray~var} +% \end{syntax} +% Sets all entries of the \meta{floating point array variable} to +% $+0$. Assignments are always global. +% \end{function} +% +% \begin{function}[EXP, added = 2018-05-05] +% {\fparray_item:Nn, \fparray_item_to_tl:Nn} +% \begin{syntax} +% \cs{fparray_item:Nn} \meta{fparray~var} \Arg{position} +% \end{syntax} +% Applies \cs{fp_use:N} or \cs{fp_to_tl:N} (respectively) to the +% floating point entry stored at the (integer expression) +% \meta{position} in the \meta{floating point array variable}. If the +% \meta{position} is not between $1$ and the \cs{fparray_count:N}, an +% error occurs. +% \end{function} + % % \end{documentation} % @@ -102,7 +149,8 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}{\fparray_new:Nn, \@@_array_new:nNNN} +% \begin{macro}{\fparray_new:Nn, \fparray_new:cn} +% \begin{macro}{\@@_array_new:nNNN} % Build a three token token list, then define all three tokens to be % integer arrays of the same size. No need to initialize the data: % the integer arrays start with zeros, and three zeros denote @@ -120,6 +168,7 @@ \exp_last_unbraced:Nfo \@@_array_new:nNNNN { \int_eval:n {#2} } #1 #1 } +\cs_generate_variant:Nn \fparray_new:Nn { c } \cs_new_protected:Npn \@@_array_new:nNNNN #1#2#3#4#5 { \int_compare:nNnTF {#1} < 0 @@ -136,8 +185,9 @@ } % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}[EXP]{\fparray_count:N} +% \begin{macro}[EXP]{\fparray_count:N, \fparray_count:c} % Size of any of the intarrays, here we pick the third. % \begin{macrocode} \cs_new:Npn \fparray_count:N #1 @@ -145,6 +195,7 @@ \exp_after:wN \use_i:nnn \exp_after:wN \intarray_count:N #1 } +\cs_generate_variant:Nn \fparray_count:N { c } % \end{macrocode} % \end{macro} % @@ -178,9 +229,10 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\fparray_gset:Nnn, \fparray_gset:cnn} % \begin{macro} % { -% \fparray_gset:Nnn, \@@_array_gset:NNNNww, \@@_array_gset:w, +% \@@_array_gset:NNNNww, \@@_array_gset:w, % \@@_array_gset_recover:Nw, \@@_array_gset_special:nnNNN, % \@@_array_gset_normal:w % } @@ -196,6 +248,7 @@ \int_value:w \int_eval:n {#2} \exp_after:wN ; \exp:w \exp_end_continue_f:w \@@_parse:n {#3} } +\cs_generate_variant:Nn \fparray_gset:Nnn { c } \cs_new_protected:Npn \@@_array_gset:NNNNww #1#2#3#4#5 ; #6 ; { \@@_array_bounds:NNnTF \__kernel_msg_error:nnxxx #4 {#5} @@ -239,8 +292,9 @@ } % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}{\fparray_gzero:N} +% \begin{macro}{\fparray_gzero:N, \fparray_gzero:c} % \begin{macrocode} \cs_new_protected:Npn \fparray_gzero:N #1 { @@ -254,13 +308,19 @@ #1 } } +\cs_generate_variant:Nn \fparray_gzero:N { c } % \end{macrocode} % \end{macro} % % \begin{macro}[EXP] % { % \fparray_item:Nn, +% \fparray_item:cn, % \fparray_item_to_tl:Nn, +% \fparray_item_to_tl:cn, +% } +% \begin{macro}[EXP] +% { % \@@_array_item:NwN, % \@@_array_item:NNNnN, % \@@_array_item:N, @@ -276,6 +336,7 @@ \int_value:w \int_eval:n {#2} ; \@@_to_decimal:w } +\cs_generate_variant:Nn \fparray_item:Nn { c } \cs_new:Npn \fparray_item_to_tl:Nn #1#2 { \exp_after:wN \@@_array_item:NwN @@ -283,6 +344,7 @@ \int_value:w \int_eval:n {#2} ; \@@_to_tl:w } +\cs_generate_variant:Nn \fparray_item_to_tl:Nn { c } \cs_new:Npn \@@_array_item:NwN #1#2 ; #3 { \@@_array_bounds:NNnTF \__kernel_msg_expandable_error:nnfff #1 {#2} @@ -323,6 +385,7 @@ { #9 \s_@@ \@@_chk:w 1 #1 {#8} #7 {#2#3#4#5} {#6} ; } % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macrocode} %</initex|package> diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index 1cd7e62c93d..042f4d656cf 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -134,6 +134,14 @@ % since the digit~\texttt{9} is not part of the expression. % \end{function} % +% \begin{function}[EXP, added = 2018-11-03]{\int_sign:n} +% \begin{syntax} +% \cs{int_sign:n} \Arg{intexpr} +% \end{syntax} +% Evaluates the \meta{integer expression} then leaves $1$ or $0$ or +% $-1$ in the input stream according to the sign of the result. +% \end{function} +% % \begin{function}[EXP, updated = 2012-09-26]{\int_abs:n} % \begin{syntax} % \cs{int_abs:n} \Arg{integer expression} @@ -1053,8 +1061,6 @@ % or directly in the input stream. % When debugging, use parentheses to catch early termination. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_eval:n } } \cs_new:Npn \int_eval:n #1 { \int_value:w \@@_eval:w #1 \@@_eval_end: } \cs_new:Npn \int_eval:w { \int_value:w \@@_eval:w } @@ -1062,6 +1068,31 @@ % \end{macro} % \end{macro} % +% \begin{macro}[EXP]{\int_sign:n, \@@_sign:Nw} +% See \cs{int_abs:n}. Evaluate the expression once (and when +% debugging is enabled, check that the expression is well-formed), +% then test the first character to determine the sign. This is +% wrapped in \cs{int_value:w} \ldots{} \cs{exp_stop_f:} to ensure a +% fixed number of expansions and to avoid dealing with closing the +% conditionals. +% \begin{macrocode} +\cs_new:Npn \int_sign:n #1 + { + \int_value:w \exp_after:wN \@@_sign:Nw + \int_value:w \@@_eval:w #1 \@@_eval_end: ; + \exp_stop_f: + } +\cs_new:Npn \@@_sign:Nw #1#2 ; + { + \if_meaning:w 0 #1 + 0 + \else: + \if_meaning:w - #1 - \fi: 1 + \fi: + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[EXP]{\int_abs:n} % \begin{macro}[EXP]{\@@_abs:N} % \UnitTested @@ -1074,8 +1105,6 @@ % evaluation. The absolute value is obtained by removing a leading % sign if any. All three functions expand in two steps. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_abs:n } } \cs_new:Npn \int_abs:n #1 { \int_value:w \exp_after:wN \@@_abs:N @@ -1084,11 +1113,6 @@ } \cs_new:Npn \@@_abs:N #1 { \if_meaning:w - #1 \else: \exp_after:wN #1 \fi: } -\__kernel_patch_args:nNNpn - { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_max:nn } - { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \int_max:nn } - } \cs_set:Npn \int_max:nn #1#2 { \int_value:w \exp_after:wN \@@_maxmin:wwN @@ -1097,11 +1121,6 @@ > \exp_stop_f: } -\__kernel_patch_args:nNNpn - { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_min:nn } - { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \int_min:nn } - } \cs_set:Npn \int_min:nn #1#2 { \int_value:w \exp_after:wN \@@_maxmin:wwN @@ -1146,11 +1165,6 @@ % truncating behaviour that we want. The details are thanks to Heiko % Oberdiek: getting things right in all cases is not so easy. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_div_truncate:nn } - { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \int_div_truncate:nn } - } \cs_new:Npn \int_div_truncate:nn #1#2 { \int_value:w \@@_eval:w @@ -1180,11 +1194,6 @@ % \end{macrocode} % Finally there's the modulus operation. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_mod:nn } - { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \int_mod:nn } - } \cs_new:Npn \int_mod:nn #1#2 { \int_value:w \@@_eval:w \exp_after:wN \@@_mod:ww @@ -1254,10 +1263,6 @@ % We cannot use \cs{int_gset:Nn} because (when |check-declarations| is % enabled) this runs some checks that constants would fail. % \begin{macrocode} -\__kernel_patch_args:nnnNNpn - { \__kernel_chk_var_scope:NN c #1 } - { } - { {#1} { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \int_const:Nn } } \cs_new_protected:Npn \int_const:Nn #1#2 { \int_compare:nNnTF {#2} < \c_zero_int @@ -1303,9 +1308,7 @@ % \UnitTested % Functions that reset an \meta{integer} register to zero. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \int_zero:N #1 { #1 = \c_zero_int } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \int_gzero:N #1 { \tex_global:D #1 = \c_zero_int } \cs_generate_variant:Nn \int_zero:N { c } \cs_generate_variant:Nn \int_gzero:N { c } @@ -1335,10 +1338,8 @@ % another. Check that assigned integer is local/global. No need to % check that the other one is defined as \TeX{} does it for us. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \int_set_eq:NN #1#2 { #1 = #2 } \cs_generate_variant:Nn \int_set_eq:NN { c , Nc , cc } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \int_gset_eq:NN #1#2 { \tex_global:D #1 = #2 } \cs_generate_variant:Nn \int_gset_eq:NN { c , Nc , cc } % \end{macrocode} @@ -1357,22 +1358,6 @@ % % \subsection{Setting and incrementing integers} % -% Several functions here have a signature |:Nn| and are such that when -% debugging, the first argument should be checked to be a local/global -% variable and the second should be wrapped in code for an expression. -% The temporary function \cs{@@_tmp:w} finds the name |#3| of the -% function being redefined and writes the appropriate patch. -% \begin{macrocode} -\cs_set_protected:Npn \@@_tmp:w #1#2#3 - { - \__kernel_patch_args:nnnNNpn - { #1 ##1 } - { } - { {##1} { \__kernel_chk_expr:nNnN {##2} \@@_eval:w { } #3 } } - #2 #3 - } -% \end{macrocode} -% % \begin{macro}{\int_add:Nn, \int_add:cn} % \UnitTested % \begin{macro}{\int_gadd:Nn, \int_gadd:cn} @@ -1381,21 +1366,14 @@ % \UnitTested % \begin{macro}{\int_gsub:Nn, \int_gsub:cn} % \UnitTested -% Adding and subtracting to and from a counter. For each function, -% the debugging code produced by \cs{@@_tmp:w} checks that the -% assigned variable is correctly local/global and wraps the -% expression in some checking code. +% Adding and subtracting to and from a counter. % \begin{macrocode} -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \int_add:Nn #1#2 { \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: } -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \int_sub:Nn #1#2 { \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \int_gadd:Nn #1#2 { \tex_global:D \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \int_gsub:Nn #1#2 { \tex_global:D \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: } \cs_generate_variant:Nn \int_add:Nn { c } @@ -1419,16 +1397,12 @@ % Incrementing and decrementing of integer registers is done with % the following functions. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \int_incr:N #1 { \tex_advance:D #1 \c_one_int } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \int_decr:N #1 { \tex_advance:D #1 - \c_one_int } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \int_gincr:N #1 { \tex_global:D \tex_advance:D #1 \c_one_int } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \int_gdecr:N #1 { \tex_global:D \tex_advance:D #1 - \c_one_int } \cs_generate_variant:Nn \int_incr:N { c } @@ -1446,14 +1420,10 @@ % \begin{macro}{\int_gset:Nn, \int_gset:cn} % \UnitTested % As integers are register-based \TeX{} issues an error -% if they are not defined. Thus there is no need to check their -% existence as for token list variables. However, the code that -% checks whether the assignment is local or global is still needed. +% if they are not defined. % \begin{macrocode} -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \int_set:Nn #1#2 { #1 ~ \@@_eval:w #2 \@@_eval_end: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \int_gset:Nn #1#2 { \tex_global:D #1 ~ \@@_eval:w #2 \@@_eval_end: } \cs_generate_variant:Nn \int_set:Nn { c } @@ -1657,12 +1627,6 @@ % \UnitTested % More efficient but less natural in typing. % \begin{macrocode} -\__kernel_patch_conditional_args:nNNpnn - { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_compare:nNn } - { \@@_eval_end: #2 } - { \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } \int_compare:nNn } - } \prg_new_conditional:Npnn \int_compare:nNn #1#2#3 { p , T , F , TF } { \if_int_compare:w \@@_eval:w #1 #2 \@@_eval:w #3 \@@_eval_end: @@ -1722,8 +1686,6 @@ % \UnitTested % A predicate function. % \begin{macrocode} -\__kernel_patch_conditional_args:nNNpnn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_if_odd:n } } \prg_new_conditional:Npnn \int_if_odd:n #1 { p , T , F , TF} { \if_int_odd:w \@@_eval:w #1 \@@_eval_end: @@ -1732,8 +1694,6 @@ \prg_return_false: \fi: } -\__kernel_patch_conditional_args:nNNpnn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \int_if_even:n } } \prg_new_conditional:Npnn \int_if_even:n #1 { p , T , F , TF} { \reverse_if:N \if_int_odd:w \@@_eval:w #1 \@@_eval_end: @@ -1851,21 +1811,6 @@ % step size of zero before checking the sign, but we optimize for the % most frequent case (positive step). % \begin{macrocode} -\__kernel_patch_args:nNNpn - { - { - \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } - \int_step_function:nnnN - } - { - \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } - \int_step_function:nnnN - } - { - \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } - \int_step_function:nnnN - } - } \cs_new:Npn \int_step_function:nnnN #1#2#3 { \exp_after:wN \@@_step:wwwN @@ -2594,6 +2539,17 @@ % \end{variable} % \end{variable} % +% \subsection{Integers for earlier modules} +% +%<@@=seq> +% +% \begin{variable}{\l_@@_internal_a_int, \l_@@_internal_b_int} +% \begin{macrocode} +\int_new:N \l_@@_internal_a_int +\int_new:N \l_@@_internal_b_int +% \end{macrocode} +% \end{variable} +% % \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 7365c9e0b8d..8b998f6e0ea 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -66,7 +66,7 @@ % The use of \texttt{intarray} data is therefore recommended for cases where % the need for fast access is of paramount importance. % -% \begin{function}[added = 2018-03-29]{\intarray_new:Nn} +% \begin{function}[added = 2018-03-29]{\intarray_new:Nn, \intarray_new:cn} % \begin{syntax} % \cs{intarray_new:Nn} \meta{intarray~var} \Arg{size} % \end{syntax} @@ -76,7 +76,7 @@ % always global. % \end{function} % -% \begin{function}[EXP, added = 2018-03-29]{\intarray_count:N} +% \begin{function}[EXP, added = 2018-03-29]{\intarray_count:N, \intarray_count:c} % \begin{syntax} % \cs{intarray_count:N} \meta{intarray~var} % \end{syntax} @@ -84,7 +84,7 @@ % Contrarily to \cs{seq_count:N} this is performed in constant time. % \end{function} % -% \begin{function}[added = 2018-03-29]{\intarray_gset:Nnn} +% \begin{function}[added = 2018-03-29]{\intarray_gset:Nnn, \intarray_gset:cnn} % \begin{syntax} % \cs{intarray_gset:Nnn} \meta{intarray~var} \Arg{position} \Arg{value} % \end{syntax} @@ -96,7 +96,18 @@ % global. % \end{function} % -% \begin{function}[added = 2018-05-04]{\intarray_gzero:N} +% \begin{function}[added = 2018-05-04] +% {\intarray_const_from_clist:Nn, \intarray_const_from_clist:cn} +% \begin{syntax} +% \cs{intarray_const_from_clist:Nn} \meta{intarray~var} \meta{intexpr clist} +% \end{syntax} +% Creates a new constant \meta{integer array variable} or raises an +% error if the name is already taken. The \meta{integer array +% variable} is set (globally) to contain as its items the results of +% evaluating each \meta{integer expression} in the \meta{comma list}. +% \end{function} +% +% \begin{function}[added = 2018-05-04]{\intarray_gzero:N, \intarray_gzero:c} % \begin{syntax} % \cs{intarray_gzero:N} \meta{intarray~var} % \end{syntax} @@ -104,7 +115,7 @@ % Assignments are always global. % \end{function} % -% \begin{function}[EXP, added = 2018-03-29]{\intarray_item:Nn} +% \begin{function}[EXP, added = 2018-03-29]{\intarray_item:Nn, \intarray_item:cn} % \begin{syntax} % \cs{intarray_item:Nn} \meta{intarray~var} \Arg{position} % \end{syntax} @@ -114,7 +125,8 @@ % error occurs. % \end{function} % -% \begin{function}[EXP, added = 2018-05-05]{\intarray_rand_item:N} +% \begin{function}[EXP, added = 2018-05-05] +% {\intarray_rand_item:N, \intarray_rand_item:c} % \begin{syntax} % \cs{intarray_rand_item:N} \meta{intarray~var} % \end{syntax} @@ -122,6 +134,16 @@ % \meta{integer array} is empty, produce an error. % \end{function} % +% \begin{function}[added = 2018-05-04] +% {\intarray_show:N, \intarray_show:c, \intarray_log:N, \intarray_log:c} +% \begin{syntax} +% \cs{intarray_show:N} \meta{intarray~var} +% \cs{intarray_log:N} \meta{intarray~var} +% \end{syntax} +% Displays the items in the \meta{integer array variable} in the +% terminal or writes them in the log file. +% \end{function} +% % \subsection{Implementation notes} % % It is a wrapper around the \tn{fontdimen} primitive, used to store @@ -187,7 +209,8 @@ { Size~of~array~may~not~be~negative:~#1 } % \end{macrocode} % -% \begin{macro}{\intarray_new:Nn, \@@_new:N} +% \begin{macro}{\intarray_new:Nn, \intarray_new:cn} +% \begin{macro}{\@@_new:N} % Declare |#1| to be a font (arbitrarily |cmr10| at a never-used % size). Store the array's size as the \tn{hyphenchar} of that font % and make sure enough \tn{fontdimen} are allocated, by setting the @@ -207,7 +230,6 @@ \int_step_inline:nn { 8 } { \__kernel_intarray_gset:Nnn #1 {##1} \c_zero_int } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN g #1 } { } \cs_new_protected:Npn \intarray_new:Nn #1#2 { \@@_new:N #1 @@ -220,13 +242,16 @@ \int_compare:nNnT { \intarray_count:N #1 } > 0 { \__kernel_intarray_gset:Nnn #1 { \intarray_count:N #1 } { 0 } } } +\cs_generate_variant:Nn \intarray_new:Nn { c } % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}[EXP]{\intarray_count:N} +% \begin{macro}[EXP]{\intarray_count:N, \intarray_count:c} % Size of an array. % \begin{macrocode} \cs_new:Npn \intarray_count:N #1 { \int_value:w \@@_count:w #1 } +\cs_generate_variant:Nn \intarray_count:N { c } % \end{macrocode} % \end{macro} % @@ -268,7 +293,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\intarray_gset:Nnn, \__kernel_intarray_gset:Nnn} +% \begin{macro}{\intarray_gset:Nnn, \intarray_gset:cnn, \__kernel_intarray_gset:Nnn} % \begin{macro}{\@@_gset:Nnn, \@@_gset_overflow:Nnn} % Set the appropriate \tn{fontdimen}. The % \cs{__kernel_intarray_gset:Nnn} function does not use @@ -285,6 +310,7 @@ \int_value:w \int_eval:n {#2} \exp_after:wN ; \int_value:w \int_eval:n {#3} ; } +\cs_generate_variant:Nn \intarray_gset:Nnn { c } \cs_new_protected:Npn \@@_gset:Nww #1#2 ; #3 ; { \@@_bounds:NNnTF \__kernel_msg_error:nnxxx #1 {#2} @@ -321,7 +347,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\intarray_gzero:N} +% \begin{macro}{\intarray_gzero:N, \intarray_gzero:c} % Set the appropriate \tn{fontdimen} to zero. No bound checking % needed. The \cs{prg_replicate:nn} possibly uses quite a lot of % memory, but this is somewhat comparable to the size of the array, @@ -336,10 +362,11 @@ \@@_entry:w \l_@@_loop_int #1 \c_zero_dim } } +\cs_generate_variant:Nn \intarray_gzero:N { c } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\intarray_item:Nn, \__kernel_intarray_item:Nn} +% \begin{macro}[EXP]{\intarray_item:Nn, \intarray_item:cn, \__kernel_intarray_item:Nn} % \begin{macro}{\@@_item:Nn} % Get the appropriate \tn{fontdimen} and perform bound checks. The % \cs{__kernel_intarray_item:Nn} function omits bound checks and omits @@ -354,6 +381,7 @@ \exp_after:wN #1 \int_value:w \int_eval:n {#2} ; } +\cs_generate_variant:Nn \intarray_item:Nn { c } \cs_new:Npn \@@_item:Nw #1#2 ; { \@@_bounds:NNnTF \__kernel_msg_expandable_error:nnfff #1 {#2} @@ -364,21 +392,19 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\intarray_rand_item:N} +% \begin{macro}{\intarray_rand_item:N, \intarray_rand_item:c} % Importantly, \cs{intarray_item:Nn} only evaluates its argument once. % \begin{macrocode} \cs_new:Npn \intarray_rand_item:N #1 { \intarray_item:Nn #1 { \int_rand:n { \intarray_count:N #1 } } } +\cs_generate_variant:Nn \intarray_rand_item:N { c } % \end{macrocode} % \end{macro} % % \subsection{Working with contents of integer arrays} % -% At the time of writing these are candidates, but we need at least -% \cs{intarray_const_from_clist:Nn} in \pkg{l3fp} so before -% \pkg{l3candidates}. -% -% \begin{macro}{\intarray_const_from_clist:Nn, \@@_const_from_clist:nN} +% \begin{macro}{\intarray_const_from_clist:Nn, \intarray_const_from_clist:cn} +% \begin{macro}{\@@_const_from_clist:nN} % Similar to \cs{intarray_new:Nn} (which we don't use because when % debugging is enabled that function checks the variable name starts % with |g_|). We make use of the fact that \TeX{} allows allocation @@ -388,7 +414,6 @@ % big, namely \cs{@@_gset_overflow_test:nw}, but not the code that % checks bounds. At the end, set the size of the intarray. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } \cs_new_protected:Npn \intarray_const_from_clist:Nn #1#2 { \@@_new:N #1 @@ -397,6 +422,7 @@ { \exp_args:Nf \@@_const_from_clist:nN { \int_eval:n {##1} } #1 } \@@_count:w #1 \l_@@_loop_int } +\cs_generate_variant:Nn \intarray_const_from_clist:Nn { c } \cs_new_protected:Npn \@@_const_from_clist:nN #1#2 { \int_incr:N \l_@@_loop_int @@ -405,13 +431,16 @@ } % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}[rEXP]{\intarray_to_clist:N, \@@_to_clist:Nn, \@@_to_clist:w} +% \begin{macro}[rEXP]{\intarray_to_clist:N, \intarray_to_clist:c} +% \begin{macro}[rEXP]{\@@_to_clist:Nn, \@@_to_clist:w} % Loop through the array, putting a comma before each item. Remove % the leading comma with |f|-expansion. We also use the auxiliary in % \cs{intarray_show:N} with argument comma, space. % \begin{macrocode} \cs_new:Npn \intarray_to_clist:N #1 { \@@_to_clist:Nn #1 { , } } +\cs_generate_variant:Nn \intarray_to_clist:N { c } \cs_new:Npn \@@_to_clist:Nn #1#2 { \int_compare:nNnF { \intarray_count:N #1 } = \c_zero_int @@ -431,8 +460,9 @@ } % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}{\intarray_show:N, \intarray_log:N} +% \begin{macro}{\intarray_show:N, \intarray_show:c, \intarray_log:c, \intarray_log:N} % Convert the list to a comma list (with spaces after each comma) % \begin{macrocode} \cs_new_protected:Npn \intarray_show:N { \@@_show:NN \msg_show:nnxxxx } @@ -455,10 +485,10 @@ % % \subsection{Random arrays} % +% \begin{macro}{\intarray_gset_rand:Nn, \intarray_gset_rand:cn} +% \begin{macro}{\intarray_gset_rand:Nnn, \intarray_gset_rand:cnn} % \begin{macro} % { -% \intarray_gset_rand:Nn, -% \intarray_gset_rand:Nnn, % \@@_gset_rand:Nnn, % \@@_gset_rand:Nff, % \@@_gset_rand_auxi:Nnnn, @@ -479,6 +509,7 @@ % \begin{macrocode} \cs_new_protected:Npn \intarray_gset_rand:Nn #1 { \intarray_gset_rand:Nnn #1 { 1 } } +\cs_generate_variant:Nn \intarray_gset_rand:Nn { c } \sys_if_rand_exist:TF { \cs_new_protected:Npn \intarray_gset_rand:Nnn #1#2#3 @@ -542,8 +573,11 @@ { \intarray_gset_rand:Nnn #1 {#2} {#3} } } } +\cs_generate_variant:Nn \intarray_gset_rand:Nnn { c } % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} % % \begin{macrocode} %</initex|package> diff --git a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx index 507546fa2dc..e5b0ce80cd7 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -90,43 +90,6 @@ % purposes. % \end{function} % -% \begin{function}{\__kernel_chk_var_exist:N} -% \begin{syntax} -% \cs{__kernel_chk_var_exist:N} \meta{var} -% \end{syntax} -% This function is only created if debugging is enabled. It checks -% that \meta{var} is defined according to the criteria for -% \cs{cs_if_exist_p:N}, and if not raises a kernel-level error. -% \end{function} -% -% \begin{function}{\__kernel_chk_var_scope:NN} -% \begin{syntax} -% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var} -% \end{syntax} -% Checks the \meta{var} has the correct \meta{scope}, and if not -% raises a kernel-level error. This function is only created if -% debugging is enabled. The \meta{scope} is a single letter |l|, |g|, -% |c| denoting local variables, global variables, or constants. More -% precisely, if the variable name starts with a letter and an -% underscore (normal \pkg{expl3} convention) the function checks that -% this single letter matches the \meta{scope}. Otherwise the function -% cannot know the scope \meta{var} the first time: instead, it defines -% |\__debug_chk_/|\meta{var name} to store that information for the -% next call. Thus, if a given \meta{var} is subject to assignments of -% different scopes a kernel error will result. -% \end{function} -% -% \begin{function}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N} -% \begin{syntax} -% \cs{__kernel_chk_var_local:N} \meta{var} -% \cs{__kernel_chk_var_global:N} \meta{var} -% \end{syntax} -% Applies \cs{__kernel_chk_var_exist:N} \meta{var}, and assuming that is -% true applies -% \cs{__kernel_chk_var_scope:NN} \meta{scope} \meta{var}, where -% \meta{scope} is |l| or~|g|. -% \end{function} -% % \begin{function}{\__kernel_cs_parm_from_arg_count:nnF} % \begin{syntax} % \cs{__kernel_cs_parm_from_arg_count:nnF} \Arg{follow-on} \Arg{args} \Arg{false code} @@ -146,28 +109,6 @@ % such that they can be exchanged by \cs{debug_on:} and \cs{debug_off:}. % \end{function} % -% \begin{function}{\__kernel_if_debug:TF} -% \begin{syntax} -% \cs{__kernel_if_debug:TF} \Arg{true code} \Arg{false code} -% \end{syntax} -% Runs the \meta{true code} if debugging is enabled, namely only in -% \LaTeXe{} package mode with one of the options -% \texttt{check-declarations}, \texttt{enable-debug}, or -% \texttt{log-functions}. Otherwise runs the \meta{false code}. The -% |T| and |F| variants are not provided for this low-level -% conditional. -% \end{function} -% -% \begin{function}{\__kernel_debug_log:x} -% \begin{syntax} -% \cs{__kernel_debug_log:x} \Arg{message text} -% \end{syntax} -% If the \texttt{log-functions} option is active, this function writes -% the \meta{message text} to the log file using \cs{iow_log:x}. -% Otherwise, the \meta{message text} is ignored using \cs{use_none:n}. -% This function is only created if debugging is enabled. -% \end{function} -% % \begin{function}[EXP]{\__kernel_exp_not:w} % \begin{syntax} % \cs{__kernel_exp_not:w} \meta{expandable tokens} \Arg{content} @@ -378,69 +319,6 @@ % be much shorter than a line, otherwise it is cropped. % \end{function} % -% \begin{function}{\__kernel_patch:nnNNpn} -% \begin{syntax} -% \cs{__kernel_patch:nnNNpn} \Arg{before} \Arg{after} -% \meta{definition} \meta{function} \meta{parameters} \Arg{code} -% \end{syntax} -% If debugging is not enabled, this function ignores the \meta{before} -% and \meta{after} code and performs the \meta{definition} with no -% patching. Otherwise it replaces \meta{code} by \meta{before} -% \meta{code} \meta{after} (which can involve |#1| and so on) in the -% \meta{definition} that follows. The \meta{definition} must start -% with \cs{cs_new:Npn} or \cs{cs_set:Npn} or \cs{cs_gset:Npn} or their -% \texttt{_protected} counterparts. Other cases can be added as -% needed. -% \end{function} -% -% \begin{function}{\__kernel_patch_conditional:nNNpnn} -% \begin{syntax} -% \cs{__kernel_patch_conditional:nNNpnn} \Arg{before} -% \meta{definition} \meta{conditional} \meta{parameters} \Arg{type} \Arg{code} -% \end{syntax} -% Similar to \cs{__kernel_patch:nnNNpn} for conditionals, namely -% \meta{definition} must be \cs{prg_new_conditional:Npnn} or its -% \texttt{_protected} counterpart. There is no \meta{after} code -% because that would interfere with the action of the conditional. -% \end{function} -% -% \begin{function} -% {\__kernel_patch_args:nNNpn, \__kernel_patch_conditional_args:nNNpnn} -% \begin{syntax} -% \cs{__kernel_patch_args:nNNpn} \Arg{arguments} -% \meta{definition} \meta{function} \meta{parameters} \Arg{code} -% \end{syntax} -% Like \cs{__kernel_patch:nnNNpn}, this tweaks the following -% definition, but from the \enquote{inside out} (and if debugging is -% not enabled, the \meta{arguments} are ignored). It replaces |#1|, -% |#2| and so on in the \meta{code} of the definition as indicated by -% the \meta{arguments}. More precisely, a temporary function is -% defined using the \meta{definition} with the \meta{parameters} and -% \meta{code}, then the result of expanding that function once in -% front of the \meta{arguments} is used instead of the \meta{code} -% when defining the actual function. For instance, -% \begin{quote} -% \cs{__kernel_patch_args:nNNpn} |{ { (#1) } }| \\ -% \cs{cs_new:Npn} \cs{int_eval:n} |#1| \\ -% ~~|{ \int_value:w \__int_eval:w #1 \__int_eval_end: }| -% \end{quote} -% would replace |#1| by |(#1)| in the definition of \cs{int_eval:n} when -% debugging is enabled. This fails if the \meta{code} contains~|##|. -% The \cs{__kernel_patch_conditional_args:nNNpnn} function is for use -% before \cs{prg_new_conditional:Npnn} or its \texttt{_protected} -% counterpart. -% \end{function} -% -% \begin{function} -% {\__kernel_patch_args:nnnNNpn, \__kernel_patch_conditional_args:nnnNNpnn} -% \begin{syntax} -% \cs{__kernel_patch_args:nnnNNpn} \Arg{before} \Arg{after} \Arg{arguments} -% \meta{definition} \meta{function} \meta{parameters} \Arg{code} -% \end{syntax} -% A combination of \cs{__kernel_patch:nnNNpn} and -% \cs{__kernel_patch_args:nNNpn}. -% \end{function} -% % \begin{variable}{\g__kernel_prg_map_int} % This integer is used by non-expandable mapping functions to track % the level of nesting in force. The functions diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index f2ddc9f2c14..a7097c3d5b7 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -1569,12 +1569,6 @@ % Setting the code for a key first logs if appropriate that we are % defining a new key, then saves the code. % \begin{macrocode} -\__kernel_patch:nnNNpn - { - \cs_if_exist:cF { \c_@@_code_root_tl #1 } - { \__kernel_debug_log:x { Defining~key~#1~\msg_line_context: } } - } - { } \cs_new_protected:Npn \@@_cmd_set:nn #1#2 { \cs_set_protected:cpn { \c_@@_code_root_tl #1 } ##1 {#2} } \cs_generate_variant:Nn \@@_cmd_set:nn { nx , Vn , Vo } @@ -1642,7 +1636,13 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_initialise:n #1 { - \cs_if_exist_use:cT { \c_@@_code_root_tl \l_keys_path_tl } { {#1} } + \cs_if_exist:cTF + { \c_@@_inherit_root_tl \@@_parent:o \l_keys_path_tl } + { \@@_execute_inherit: } + { + \tl_clear:N \l_@@_inherit_tl + \cs_if_exist_use:cT { \c_@@_code_root_tl \l_keys_path_tl } { {#1} } + } } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx b/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx index 417723048a3..87695c76012 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx index b7f098649c2..f499317f98a 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx index bbb003888b2..717002aaca5 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -555,11 +555,6 @@ % This auxiliary is similar to \cs{__kernel_chk_if_free_cs:N}, and is used when % defining messages with \cs{msg_new:nnnn}. % \begin{macrocode} -\__kernel_patch:nnNNpn { } - { - \__kernel_debug_log:x - { Defining~message~ #1 / #2 ~\msg_line_context: } - } \cs_new_protected:Npn \@@_chk_free:nn #1#2 { \msg_if_exist:nnT {#1} {#2} @@ -1800,6 +1795,9 @@ LaTeX~has~been~asked~to~set~the~property~'#1'~for~key~'#2':~ this~property~is~not~defined. } +\__kernel_msg_new:nnnn { kernel } { quote-in-shell } + { Quotes~in~shell~command~'#1'. } + { Shell~commands~cannot~contain~quotes~("). } \__kernel_msg_new:nnnn { kernel } { scanmark-already-defined } { Scan~mark~#1~already~defined. } { @@ -1807,6 +1805,14 @@ LaTeX~has~been~asked~to~create~a~new~scan~mark~'#1'~ but~this~name~has~already~been~used~for~a~scan~mark. } +\__kernel_msg_new:nnnn { kernel } { shuffle-too-large } + { The~sequence~#1~is~too~long~to~be~shuffled~by~TeX. } + { + TeX~has~ \int_eval:n { \c_max_register_int + 1 } ~ + toks~registers:~this~only~allows~to~shuffle~up~to~ + \int_use:N \c_max_register_int \ items.~ + The~list~will~not~be~shuffled. + } \__kernel_msg_new:nnnn { kernel } { variable-not-defined } { Variable~#1~undefined. } { @@ -1857,55 +1863,14 @@ % In format mode the error is somewhat different. % \begin{macrocode} %<*package> -\__kernel_if_debug:TF - { - \__kernel_msg_new:nnnn { kernel } { debug } - { The~debugging~option~'#1'~does~not~exist~\msg_line_context:. } - { - The~functions~'\iow_char:N\\debug_on:n'~and~ - '\iow_char:N\\debug_off:n'~only~accept~the~arguments~ - 'check-declarations',~'deprecation',~'log-functions',~not~'#1'. - } - \__kernel_msg_new:nnn { kernel } { expr } { '#2'~in~#1 } - \__kernel_msg_new:nnnn { kernel } { local-global } - { Inconsistent~local/global~assignment } - { - \c_@@_coding_error_text_tl - \if:w l #2 Local - \else: - \if:w g #2 Global \else: Constant \fi: - \fi: - \ % - assignment~to~a~ - \if:w l #1 local - \else: - \if:w g #1 global \else: constant \fi: - \fi: - \ % - variable~'#3'. - } - \__kernel_msg_new:nnnn { kernel } { non-declared-variable } - { The~variable~#1~has~not~been~declared~\msg_line_context:. } - { - \c_@@_coding_error_text_tl - Checking~is~active,~and~you~have~tried~do~so~something~like: \\ - \ \ \tl_set:Nn ~ #1 ~ \{ ~ ... ~ \} \\ - without~first~having: \\ - \ \ \tl_new:N ~ #1 \\ - \\ - LaTeX~will~create~the~variable~and~continue. - } - } +\__kernel_msg_new:nnnn { kernel } { enable-debug } + { To~use~'#1'~load~expl3~with~the~'enable-debug'~option. } { - \__kernel_msg_new:nnnn { kernel } { enable-debug } - { To~use~'#1'~load~expl3~with~the~'enable-debug'~option. } - { - The~function~'#1'~will~be~ignored~because~it~can~only~work~if~ - some~internal~functions~in~expl3~have~been~appropriately~ - defined.~This~only~happens~if~one~of~the~options~ - 'enable-debug',~'check-declarations'~or~'log-functions'~was~ - given~when~loading~expl3. - } + The~function~'#1'~will~be~ignored~because~it~can~only~work~if~ + some~internal~functions~in~expl3~have~been~appropriately~ + defined.~This~only~happens~if~one~of~the~options~ + 'enable-debug',~'check-declarations'~or~'log-functions'~was~ + given~when~loading~expl3. } %</package> %<*initex> @@ -1985,6 +1950,22 @@ } % \end{macrocode} % +% System layer messages +% \begin{macrocode} +\__kernel_msg_new:nnnn { sys } { backend-set } + { Backend~configuration~already~set. } + { + Run-time~backend~selection~may~only~be~carried~out~once~during~a~run.~ + This~second~attempt~to~set~them~will~be~ignored. + } +\__kernel_msg_new:nnnn { sys } { wrong-backend } + { Backend~request~inconsistent~with~engine:~using~'#2'~backend. } + { + You~have~requested~backend~'#1',~but~this~is~not~suitable~for~use~with~the~ + active~engine.~LaTeX3~will~use~the~'#2'~backend~instead. + } +% \end{macrocode} +% % \subsection{Expandable errors} % % \begin{macro}{\@@_expandable_error:n} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx index 3167e104a5e..674f69815ef 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index 29e41e5aa06..14a9a789b6c 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -252,6 +252,15 @@ % \meta{boolean} is initially \texttt{false}. % \end{function} % +% \begin{function}[added = 2017-11-28]{\bool_const:Nn, \bool_const:cn} +% \begin{syntax} +% \cs{bool_const:Nn} \meta{boolean} \Arg{boolexpr} +% \end{syntax} +% Creates a new constant \meta{boolean} or raises an error if the name +% is already taken. The value of the \meta{boolean} is set globally to +% the result of evaluating the \meta{boolexpr}. +% \end{function} +% % \begin{function} % { % \bool_set_false:N , \bool_set_false:c , @@ -823,6 +832,18 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[added = 2017-11-28]{\bool_const:Nn, \bool_const:cn} +% A merger between \cs{tl_const:Nn} and \cs{bool_set:Nn}. +% \begin{macrocode} +\cs_new_protected:Npn \bool_const:Nn #1#2 + { + \__kernel_chk_if_free_cs:N #1 + \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2} + } +\cs_generate_variant:Nn \bool_const:Nn { c } +% \end{macrocode} +% \end{macro} +% % \begin{macro} % { % \bool_set_true:N, \bool_set_true:c, @@ -836,16 +857,12 @@ % make sure the boolean exists. This is needed because booleans are % not based on token lists nor on \TeX{} registers. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \bool_set_true:N #1 { \cs_set_eq:NN #1 \c_true_bool } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \bool_set_false:N #1 { \cs_set_eq:NN #1 \c_false_bool } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \bool_gset_true:N #1 { \cs_gset_eq:NN #1 \c_true_bool } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \bool_gset_false:N #1 { \cs_gset_eq:NN #1 \c_false_bool } \cs_generate_variant:Nn \bool_set_true:N { c } @@ -883,13 +900,11 @@ % primitive sets the left-hand side to \cs{scan_stop:} before looking % for the right-hand side. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \bool_set:Nn #1#2 { \exp_last_unbraced:NNNf \tex_chardef:D #1 = { \bool_if_p:n {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \bool_gset:Nn #1#2 { \exp_last_unbraced:NNNNf diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index 44fd4a82ce5..a49e0060898 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -110,6 +110,37 @@ % \meta{property list_2}. % \end{function} % +% \begin{function}[added = 2017-11-28, updated = 2019-08-25] +% { +% \prop_set_from_keyval:Nn, \prop_set_from_keyval:cn, +% \prop_gset_from_keyval:Nn, \prop_gset_from_keyval:cn, +% } +% \begin{syntax} +% \cs{prop_set_from_keyval:Nn} \meta{prop~var} +% \{ +% \meta{key1} |=| \meta{value1} |,| +% \meta{key2} |=| \meta{value2} |,| \ldots{} +% \} +% \end{syntax} +% Sets \meta{prop~var} to contain key--value pairs given in the second +% argument. If duplicate keys appear only one of the values is kept. +% \end{function} +% +% \begin{function}[added = 2017-11-28, updated = 2019-08-25] +% {\prop_const_from_keyval:Nn, \prop_const_from_keyval:cn} +% \begin{syntax} +% \cs{prop_const_from_keyval:Nn} \meta{prop~var} +% \{ +% \meta{key1} |=| \meta{value1} |,| +% \meta{key2} |=| \meta{value2} |,| \ldots{} +% \} +% \end{syntax} +% Creates a new constant \meta{prop~var} or raises an error if the +% name is already taken. The \meta{prop~var} is set globally to +% contain key--value pairs given in the second argument. +% If duplicate keys appear only one of the values is kept. +% \end{function} +% % \section{Adding entries to property lists} % % \begin{function}[updated = 2012-07-09] diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx index dda51fd74f4..bbeac9461bd 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -367,7 +367,6 @@ % \UnitTested % Allocate a new quark. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN q #1 } { } \cs_new_protected:Npn \quark_new:N #1 { \__kernel_chk_if_free_cs:N #1 @@ -594,7 +593,6 @@ % Check whether the variable is already a scan mark, % then declare it to be equal to \cs{scan_stop:} globally. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN s #1 } { } \cs_new_protected:Npn \scan_new:N #1 { \tl_if_in:NnTF \g_@@_marks_tl { #1 } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx index 88c06cf6606..13faf8fc865 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -1472,15 +1472,6 @@ % |#2|, or |#3| as relevant to each character (after de-escaping % it). % \begin{macrocode} -\__kernel_patch:nnNNpn - { - \@@_trace_push:nnN { regex } { 1 } \@@_escape_use:nnnn - \group_begin: - \tl_set:Nx \l_@@_internal_a_tl - { \@@_trace_pop:nnN { regex } { 1 } \@@_escape_use:nnnn } - \use_none:nnn - } - { } \cs_new_protected:Npn \@@_escape_use:nnnn #1#2#3#4 { \group_begin: @@ -3779,12 +3770,6 @@ \@@_compile:n {#1} \@@_build:N \l_@@_internal_regex } -\__kernel_patch:nnNNpn - { \@@_trace_push:nnN { regex } { 1 } \@@_build:N } - { - \@@_trace_states:n { 2 } - \@@_trace_pop:nnN { regex } { 1 } \@@_build:N - } \cs_new_protected:Npn \@@_build:N #1 { \@@_standard_escapechar: @@ -3825,12 +3810,6 @@ % work properly at the outer level, we need to put the appropriate % \texttt{left} and \texttt{right} states in their sequence. % \begin{macrocode} -\__kernel_patch:nnNNpn - { \@@_trace_push:nnN { regex } { 1 } \@@_build_for_cs:n } - { - \@@_trace_states:n { 2 } - \@@_trace_pop:nnN { regex } { 1 } \@@_build_for_cs:n - } \cs_new_protected:Npn \@@_build_for_cs:n #1 { \int_set_eq:NN \l_@@_min_state_int \l_@@_max_active_int @@ -3898,18 +3877,6 @@ % \texttt{right} state is the new empty state, and the \texttt{left} % state points to the previously \enquote{current} state. % \begin{macrocode} -\__kernel_patch:nnNNpn - { - \@@_trace:nnx { regex } { 2 } - { - regex~new~state~ - L=\int_use:N \l_@@_left_state_int ~ -> ~ - R=\int_use:N \l_@@_right_state_int ~ -> ~ - M=\int_use:N \l_@@_max_state_int ~ -> ~ - \int_eval:n { \l_@@_max_state_int + 1 } - } - } - { } \cs_new_protected:Npn \@@_build_new_state: { \@@_toks_clear:N \l_@@_max_state_int @@ -4064,9 +4031,6 @@ % auxiliaries expects \texttt{left_state} and \texttt{right_state} to % be set properly. % \begin{macrocode} -\__kernel_patch:nnNNpn - { \@@_trace_push:nnN { regex } { 1 } \@@_group_aux:nnnnN } - { \@@_trace_pop:nnN { regex } { 1 } \@@_group_aux:nnnnN } \cs_new_protected:Npn \@@_group_aux:nnnnN #1#2#3#4#5 { \if_int_compare:w #3 = 0 \exp_stop_f: @@ -4147,9 +4111,6 @@ % the group. The left and right states of the group are extracted from % the relevant sequences. % \begin{macrocode} -\__kernel_patch:nnNNpn - { \@@_trace_push:nnN { regex } { 1 } \@@_branch:n } - { \@@_trace_pop:nnN { regex } { 1 } \@@_branch:n } \cs_new_protected:Npn \@@_branch:n #1 { \@@_build_new_state: @@ -4648,12 +4609,6 @@ % smothering an empty match at the start). Once all this is set up, we % are ready for the ride. Find the first match. % \begin{macrocode} -\__kernel_patch:nnNNpn - { - \@@_trace_push:nnN { regex } { 1 } \@@_match:n - \@@_trace:nnx { regex } { 1 } { analyzing~query~token~list } - } - { \@@_trace_pop:nnN { regex } { 1 } \@@_match:n } \cs_new_protected:Npn \@@_match:n #1 { \int_zero:N \l_@@_balance_int @@ -4667,12 +4622,6 @@ \@@_match_init: \@@_match_once: } -\__kernel_patch:nnNNpn - { - \@@_trace_push:nnN { regex } { 1 } \@@_match_cs:n - \@@_trace:nnx { regex } { 1 } { analyzing~query~token~list } - } - { \@@_trace_pop:nnN { regex } { 1 } \@@_match_cs:n } \cs_new_protected:Npn \@@_match_cs:n #1 { \int_zero:N \l_@@_balance_int @@ -4695,9 +4644,6 @@ \@@_match_init: \@@_match_once: } -\__kernel_patch:nnNNpn - { \@@_trace:nnx { regex } { 1 } { initializing } } - { } \cs_new_protected:Npn \@@_match_init: { \bool_gset_false:N \g_@@_success_bool @@ -4885,12 +4831,6 @@ % state is marked as $\texttt{step}+1$: any thread hitting it at that % point will be terminated. % \begin{macrocode} -\__kernel_patch:nnNNpn - { - \@@_trace:nnx { regex } { 2 } - { state~\int_use:N \l_@@_curr_state_int } - } - { } \cs_new_protected:Npn \@@_use_state: { \__kernel_intarray_gset:Nnn \g_@@_state_active_intarray @@ -5267,9 +5207,6 @@ % parsed, make sure that there is no open csname. Finally, define the % \texttt{balance_one_match} and \texttt{do_one_match} functions. % \begin{macrocode} -\__kernel_patch:nnNNpn - { \@@_trace_push:nnN { regex } { 1 } \@@_replacement:n } - { \@@_trace_pop:nnN { regex } { 1 } \@@_replacement:n } \cs_new_protected:Npn \@@_replacement:n #1 { \group_begin: @@ -6704,20 +6641,16 @@ % typically~1. If the module's current tracing level is less than % |#2| show nothing, otherwise write |#3| to the terminal. % \begin{macrocode} -\__kernel_if_debug:TF +\cs_new_protected:Npn \@@_trace_push:nnN #1#2#3 + { \@@_trace:nnx {#1} {#2} { entering~ \token_to_str:N #3 } } +\cs_new_protected:Npn \@@_trace_pop:nnN #1#2#3 + { \@@_trace:nnx {#1} {#2} { leaving~ \token_to_str:N #3 } } +\cs_new_protected:Npn \@@_trace:nnx #1#2#3 { - \cs_new_protected:Npn \@@_trace_push:nnN #1#2#3 - { \@@_trace:nnx {#1} {#2} { entering~ \token_to_str:N #3 } } - \cs_new_protected:Npn \@@_trace_pop:nnN #1#2#3 - { \@@_trace:nnx {#1} {#2} { leaving~ \token_to_str:N #3 } } - \cs_new_protected:Npn \@@_trace:nnx #1#2#3 - { - \int_compare:nNnF - { \int_use:c { g_@@_trace_#1_int } } < {#2} - { \iow_term:x { Trace:~#3 } } - } + \int_compare:nNnF + { \int_use:c { g_@@_trace_#1_int } } < {#2} + { \iow_term:x { Trace:~#3 } } } - { } % \end{macrocode} % \end{macro} % @@ -6733,20 +6666,16 @@ % stored in \tn{toks} from $0$ to \cs{l_@@_max_state_int} % (excluded). % \begin{macrocode} -\__kernel_if_debug:TF +\cs_new_protected:Npn \@@_trace_states:n #1 { - \cs_new_protected:Npn \@@_trace_states:n #1 + \int_step_inline:nnn + \l_@@_min_state_int + { \l_@@_max_state_int - 1 } { - \int_step_inline:nnn - \l_@@_min_state_int - { \l_@@_max_state_int - 1 } - { - \@@_trace:nnx { regex } {#1} - { \iow_char:N \\toks ##1 = { \@@_toks_use:w ##1 } } - } + \@@_trace:nnx { regex } {#1} + { \iow_char:N \\toks ##1 = { \@@_toks_use:w ##1 } } } } - { } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index 82c5b81ded3..7dfd5d3ba67 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -114,6 +114,16 @@ % the original \meta{comma list} is unchanged. % \end{function} % +% \begin{function}[added = 2017-11-28] +% {\seq_const_from_clist:Nn, \seq_const_from_clist:cn} +% \begin{syntax} +% \cs{seq_const_from_clist:Nn} \meta{seq~var} \Arg{comma-list} +% \end{syntax} +% Creates a new constant \meta{seq~var} or raises an error if the name +% is already taken. The \meta{seq~var} is set globally to contain the +% items in the \meta{comma list}. +% \end{function} +% % \begin{function}[added = 2011-08-15, updated = 2012-07-02] % { % \seq_set_split:Nnn , \seq_set_split:NnV , @@ -463,6 +473,24 @@ % described in Section~\ref{sec:l3sort:mech}. % \end{function} % +% \begin{function}[added = 2018-04-29] +% {\seq_shuffle:N, \seq_shuffle:c, \seq_gshuffle:N, \seq_gshuffle:c} +% \begin{syntax} +% \cs{seq_shuffle:N} \meta{seq~var} +% \end{syntax} +% Sets the \meta{seq~var} to the result of placing the items of the +% \meta{seq~var} in a random order. Each item is (roughly) as likely +% to end up in any given position. +% \begin{texnote} +% For sequences with more than $13$ items or so, only a small +% proportion of all possible permutations can be reached, because +% the random seed \cs{sys_rand_seed:} only has $28$-bits. The use +% of \tn{toks} internally means that sequences with more than +% $32767$ or $65535$ items (depending on the engine) cannot be +% shuffled. +% \end{texnote} +% \end{function} +% % \section{Sequence conditionals} % % \begin{function}[EXP,pTF]{\seq_if_empty:N, \seq_if_empty:c} @@ -1103,6 +1131,18 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\seq_const_from_clist:Nn, \seq_const_from_clist:cn} +% Almost identical to \cs{seq_set_from_clist:Nn}. +% \begin{macrocode} +\cs_new_protected:Npn \seq_const_from_clist:Nn #1#2 + { + \tl_const:Nx #1 + { \s_@@ \clist_map_function:nN {#2} \@@_wrap_item:n } + } +\cs_generate_variant:Nn \seq_const_from_clist:Nn { c } +% \end{macrocode} +% \end{macro} +% % \begin{macro} % { % \seq_set_split:Nnn , \seq_set_split:NnV , @@ -1458,6 +1498,70 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\seq_shuffle:N, \seq_shuffle:c, \seq_gshuffle:N, \seq_gshuffle:c} +% \begin{macro}{\@@_shuffle:NN} +% \begin{macro}{\@@_shuffle_item:n} +% \begin{variable}{\g_@@_internal_seq} +% We apply the Fisher--Yates shuffle, storing items in \tn{toks} +% registers. We use the primitive \cs{tex_uniformdeviate:D} for +% speed reasons. Its non-uniformity is of order its argument divided +% by $2^{28}$, not too bad for small lists. For sequences with more +% than $13$ elements there are more possible permutations than +% possible seeds ($13!>2^{28}$) so the question of uniformity is +% somewhat moot. The integer variables are declared in \pkg{l3int}: +% load-order issues. +% \begin{macrocode} +\cs_if_exist:NTF \tex_uniformdeviate:D + { + \seq_new:N \g_@@_internal_seq + \cs_new_protected:Npn \seq_shuffle:N { \@@_shuffle:NN \seq_set_eq:NN } + \cs_new_protected:Npn \seq_gshuffle:N { \@@_shuffle:NN \seq_gset_eq:NN } + \cs_new_protected:Npn \@@_shuffle:NN #1#2 + { + \int_compare:nNnTF { \seq_count:N #2 } > \c_max_register_int + { + \__kernel_msg_error:nnx { kernel } { shuffle-too-large } + { \token_to_str:N #2 } + } + { + \group_begin: + \cs_set_eq:NN \@@_item:n \@@_shuffle_item:n + \int_zero:N \l_@@_internal_a_int + #2 + \seq_gset_from_inline_x:Nnn \g_@@_internal_seq + { \int_step_function:nN { \l_@@_internal_a_int } } + { \tex_the:D \tex_toks:D ##1 } + \group_end: + #1 #2 \g_@@_internal_seq + \seq_gclear:N \g_@@_internal_seq + } + } + \cs_new_protected:Npn \@@_shuffle_item:n + { + \int_incr:N \l_@@_internal_a_int + \int_set:Nn \l_@@_internal_b_int + { 1 + \tex_uniformdeviate:D \l_@@_internal_a_int } + \tex_toks:D \l_@@_internal_a_int + = \tex_toks:D \l_@@_internal_b_int + \tex_toks:D \l_@@_internal_b_int + } + } + { + \cs_new_protected:Npn \seq_shuffle:N #1 + { + \__kernel_msg_error:nnn { kernel } { fp-no-random } + { \seq_shuffle:N #1 } + } + \cs_new_eq:NN \seq_gshuffle:N \seq_shuffle:N + } +\cs_generate_variant:Nn \seq_shuffle:N { c } +\cs_generate_variant:Nn \seq_gshuffle:N { c } +% \end{macrocode} +% \end{variable} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macro}[TF] % { % \seq_if_in:Nn, \seq_if_in:NV, \seq_if_in:Nv, \seq_if_in:No, \seq_if_in:Nx, diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index 108a54eb12f..da8a06f38bd 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -457,6 +457,14 @@ % an \meta{internal dimension}. % \end{function} % +% \begin{function}[EXP, added = 2018-11-03]{\dim_sign:n} +% \begin{syntax} +% \cs{dim_sign:n} \Arg{dimexpr} +% \end{syntax} +% Evaluates the \meta{dimexpr} then leaves $1$ or $0$ or $-1$ in the +% input stream according to the sign of the result. +% \end{function} +% % \begin{function}[EXP]{\dim_use:N, \dim_use:c} % \begin{syntax} % \cs{dim_use:N} \meta{dimension} @@ -1103,7 +1111,6 @@ % \cs{dim_eval:n} to avoid needing a debugging patch that wraps the % expression in checking code. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } \cs_new_protected:Npn \dim_const:Nn #1#2 { \dim_new:N #1 @@ -1119,9 +1126,7 @@ % case where the variable passed is incorrectly a skip (for example a % \LaTeXe{} length). % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \dim_zero:N #1 { #1 \c_zero_skip } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \dim_gzero:N #1 { \tex_global:D #1 \c_zero_skip } \cs_generate_variant:Nn \dim_zero:N { c } @@ -1155,22 +1160,6 @@ % % \subsection{Setting \texttt{dim} variables} % -% Several functions here have a signature |:Nn| and are such that when -% debugging, the first argument should be checked to be a local/global -% variable and the second should be wrapped in code for an expression. -% The temporary function \cs{@@_tmp:w} finds the name |#3| of the -% function being redefined and writes the appropriate patch. -% \begin{macrocode} -\cs_set_protected:Npn \@@_tmp:w #1#2#3 - { - \__kernel_patch_args:nnnNNpn - { #1 ##1 } - { } - { {##1} { \__kernel_chk_expr:nNnN {##2} \@@_eval:w { } #3 } } - #2 #3 - } -% \end{macrocode} -% % \begin{macro}{\dim_set:Nn, \dim_set:cn} % \begin{macro}{\dim_gset:Nn, \dim_gset:cn} % Setting dimensions is easy enough but when debugging we want both to @@ -1179,10 +1168,8 @@ % where the variable passed is a skip (for example a \LaTeXe{} % length). % \begin{macrocode} -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \dim_set:Nn #1#2 { #1 ~ \@@_eval:w #2 \@@_eval_end: \scan_stop: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \dim_gset:Nn #1#2 { \tex_global:D #1 ~ \@@_eval:w #2 \@@_eval_end: \scan_stop: } \cs_generate_variant:Nn \dim_set:Nn { c } @@ -1197,11 +1184,9 @@ % All straightforward, with a \cs{scan_stop:} to deal with the case % where |#1| is (incorrectly) a skip. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \dim_set_eq:NN #1#2 { #1 = #2 \scan_stop: } \cs_generate_variant:Nn \dim_set_eq:NN { c , Nc , cc } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \dim_gset_eq:NN #1#2 { \tex_global:D #1 = #2 \scan_stop: } \cs_generate_variant:Nn \dim_gset_eq:NN { c , Nc , cc } @@ -1220,10 +1205,8 @@ % the local versions. The debugging code is inserted by % \cs{@@_tmp:w}. % \begin{macrocode} -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \dim_add:Nn #1#2 { \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: \scan_stop: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \dim_gadd:Nn #1#2 { \tex_global:D \tex_advance:D #1 by @@ -1231,10 +1214,8 @@ } \cs_generate_variant:Nn \dim_add:Nn { c } \cs_generate_variant:Nn \dim_gadd:Nn { c } -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \dim_sub:Nn #1#2 { \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: \scan_stop: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \dim_gsub:Nn #1#2 { \tex_global:D \tex_advance:D #1 by @@ -1261,8 +1242,6 @@ % Functions for $\min$, $\max$, and absolute value with only one evaluation. % The absolute value is evaluated by removing a leading~|-| if present. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_abs:n } } \cs_new:Npn \dim_abs:n #1 { \exp_after:wN \@@_abs:N @@ -1270,11 +1249,6 @@ } \cs_new:Npn \@@_abs:N #1 { \if_meaning:w - #1 \else: \exp_after:wN #1 \fi: } -\__kernel_patch_args:nNNpn - { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_max:nn } - { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \dim_max:nn } - } \cs_new:Npn \dim_max:nn #1#2 { \dim_use:N \@@_eval:w \exp_after:wN \@@_maxmin:wwN @@ -1283,11 +1257,6 @@ > \@@_eval_end: } -\__kernel_patch_args:nNNpn - { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_min:nn } - { \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } \dim_min:nn } - } \cs_new:Npn \dim_min:nn #1#2 { \dim_use:N \@@_eval:w \exp_after:wN \@@_maxmin:wwN @@ -1331,12 +1300,6 @@ % \begin{macro}[pTF, EXP]{\dim_compare:nNn} % Simple comparison. % \begin{macrocode} -\__kernel_patch_conditional_args:nNNpnn - { - { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_compare:nNn } - { \@@_eval_end: #2 } - { \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } \dim_compare:nNn } - } \prg_new_conditional:Npnn \dim_compare:nNn #1#2#3 { p , T , F , TF } { \if_dim:w \@@_eval:w #1 #2 \@@_eval:w #3 \@@_eval_end: @@ -1549,21 +1512,6 @@ % step size of zero before checking the sign, but we optimize for the % most frequent case (positive step). % \begin{macrocode} -\__kernel_patch_args:nNNpn - { - { - \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } - \dim_step_function:nnnN - } - { - \__kernel_chk_expr:nNnN {#2} \@@_eval:w { } - \dim_step_function:nnnN - } - { - \__kernel_chk_expr:nNnN {#3} \@@_eval:w { } - \dim_step_function:nnnN - } - } \cs_new:Npn \dim_step_function:nnnN #1#2#3 { \exp_after:wN \@@_step:wwwN @@ -1645,13 +1593,39 @@ % \begin{macro}{\dim_eval:n} % Evaluating a dimension expression expandably. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_eval:n } } \cs_new:Npn \dim_eval:n #1 { \dim_use:N \@@_eval:w #1 \@@_eval_end: } % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP]{\dim_sign:n, \@@_sign:Nw} +% See \cs{dim_abs:n}. Contrarily to \cs{int_sign:n} the case of a +% zero dimension cannot be distinguished from a positive dimension by +% looking only at the first character, since |0.2pt| and |0pt| start +% the same way. We need explicit comparisons. We start by +% distinguishing the most common case of a positive dimension. +% \begin{macrocode} +\cs_new:Npn \dim_sign:n #1 + { + \int_value:w \exp_after:wN \@@_sign:Nw + \dim_use:N \@@_eval:w #1 \@@_eval_end: ; + \exp_stop_f: + } +\cs_new:Npn \@@_sign:Nw #1#2 ; + { + \if_dim:w #1#2 > \c_zero_dim + 1 + \else: + \if_meaning:w - #1 + -1 + \else: + 0 + \fi: + \fi: + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\dim_use:N, \dim_use:c} % Accessing a \meta{dim}. % \begin{macrocode} @@ -1673,8 +1647,6 @@ % terminating early and leaving extra tokens lying around. This is % used a lot by low-level manipulations. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_to_decimal:n } } \cs_new:Npn \dim_to_decimal:n #1 { \exp_after:wN @@ -1709,13 +1681,6 @@ % Another hard-coded conversion: this one is necessary to avoid things going % off-scale. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { - { - \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } - \dim_to_decimal_in_sp:n - } - } \cs_new:Npn \dim_to_decimal_in_sp:n #1 { \int_value:w \@@_eval:w #1 \@@_eval_end: } % \end{macrocode} @@ -1820,7 +1785,6 @@ % even for constants. See \cs{dim_const:Nn} for why we cannot use % \cs{skip_gset:Nn}. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } \cs_new_protected:Npn \skip_const:Nn #1#2 { \skip_new:N #1 @@ -1834,9 +1798,7 @@ % \begin{macro}{\skip_gzero:N, \skip_gzero:c} % Reset the register to zero. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \skip_zero:N #1 { #1 \c_zero_skip } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \skip_gzero:N #1 { \tex_global:D #1 \c_zero_skip } \cs_generate_variant:Nn \skip_zero:N { c } \cs_generate_variant:Nn \skip_gzero:N { c } @@ -1869,29 +1831,12 @@ % % \subsection{Setting \texttt{skip} variables} % -% Much as for \texttt{dim} variables, \cs{@@_tmp:w} prepares a patch -% for |:Nn| function definitions in which the first argument should be -% checked to be a local/global variable and the second should be wrapped -% in code for an expression. -% \begin{macrocode} -\cs_set_protected:Npn \@@_tmp:w #1#2#3 - { - \__kernel_patch_args:nnnNNpn - { #1 ##1 } - { } - { {##1} { \__kernel_chk_expr:nNnN {##2} \tex_glueexpr:D { } #3 } } - #2 #3 - } -% \end{macrocode} -% % \begin{macro}{\skip_set:Nn, \skip_set:cn} % \begin{macro}{\skip_gset:Nn, \skip_gset:cn} % Much the same as for dimensions. % \begin{macrocode} -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \skip_set:Nn #1#2 { #1 ~ \tex_glueexpr:D #2 \scan_stop: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \skip_gset:Nn #1#2 { \tex_global:D #1 ~ \tex_glueexpr:D #2 \scan_stop: } \cs_generate_variant:Nn \skip_set:Nn { c } @@ -1920,18 +1865,14 @@ % \begin{macro}{\skip_gsub:Nn, \skip_gsub:cn} % Using |by| here deals with the (incorrect) case |\skip123|. % \begin{macrocode} -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \skip_add:Nn #1#2 { \tex_advance:D #1 by \tex_glueexpr:D #2 \scan_stop: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \skip_gadd:Nn #1#2 { \tex_global:D \tex_advance:D #1 by \tex_glueexpr:D #2 \scan_stop: } \cs_generate_variant:Nn \skip_add:Nn { c } \cs_generate_variant:Nn \skip_gadd:Nn { c } -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \skip_sub:Nn #1#2 { \tex_advance:D #1 by - \tex_glueexpr:D #2 \scan_stop: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \skip_gsub:Nn #1#2 { \tex_global:D \tex_advance:D #1 by - \tex_glueexpr:D #2 \scan_stop: } \cs_generate_variant:Nn \skip_sub:Nn { c } @@ -1969,13 +1910,6 @@ % \begin{macrocode} \cs_set_protected:Npn \@@_tmp:w #1 { - \__kernel_patch_conditional_args:nNNpnn - { - { - \__kernel_chk_expr:nNnN - {##1} \tex_glueexpr:D { } \skip_if_finite:n - } - } \prg_new_conditional:Npnn \skip_if_finite:n ##1 { p , T , F , TF } { \exp_after:wN \@@_if_finite:wwNw @@ -1994,8 +1928,6 @@ % \begin{macro}{\skip_eval:n} % Evaluating a skip expression expandably. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { { \__kernel_chk_expr:nNnN {#1} \tex_glueexpr:D { } \skip_eval:n } } \cs_new:Npn \skip_eval:n #1 { \skip_use:N \tex_glueexpr:D #1 \scan_stop: } % \end{macrocode} @@ -2017,23 +1949,9 @@ % Inserting skips. % \begin{macrocode} \cs_new_eq:NN \skip_horizontal:N \tex_hskip:D -\__kernel_patch_args:nNNpn - { - { - \__kernel_chk_expr:nNnN {#1} \tex_glueexpr:D { } - \skip_horizontal:n - } - } \cs_new:Npn \skip_horizontal:n #1 { \skip_horizontal:N \tex_glueexpr:D #1 \scan_stop: } \cs_new_eq:NN \skip_vertical:N \tex_vskip:D -\__kernel_patch_args:nNNpn - { - { - \__kernel_chk_expr:nNnN {#1} \tex_glueexpr:D { } - \skip_vertical:n - } - } \cs_new:Npn \skip_vertical:n #1 { \skip_vertical:N \tex_glueexpr:D #1 \scan_stop: } \cs_generate_variant:Nn \skip_horizontal:N { c } @@ -2116,7 +2034,6 @@ % \begin{macro}{\muskip_const:Nn, \muskip_const:cn} % See \cs{skip_const:Nn}. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } \cs_new_protected:Npn \muskip_const:Nn #1#2 { \muskip_new:N #1 @@ -2130,10 +2047,8 @@ % \begin{macro}{\muskip_gzero:N, \muskip_gzero:c} % Reset the register to zero. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \muskip_zero:N #1 { #1 \c_zero_muskip } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \muskip_gzero:N #1 { \tex_global:D #1 \c_zero_muskip } \cs_generate_variant:Nn \muskip_zero:N { c } @@ -2170,32 +2085,12 @@ % % \subsection{Setting \texttt{muskip} variables} % -% See \texttt{skip} case. -% \begin{macrocode} -\cs_set_protected:Npn \@@_tmp:w #1#2#3 - { - \__kernel_patch_args:nnnNNpn - { #1 ##1 } - { } - { - {##1} - { - \__kernel_chk_expr:nNnN {##2} - \tex_muexpr:D { \tex_mutoglue:D } #3 - } - } - #2 #3 - } -% \end{macrocode} -% % \begin{macro}{\muskip_set:Nn, \muskip_set:cn} % \begin{macro}{\muskip_gset:Nn, \muskip_gset:cn} % This should be pretty familiar. % \begin{macrocode} -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \muskip_set:Nn #1#2 { #1 ~ \tex_muexpr:D #2 \scan_stop: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \muskip_gset:Nn #1#2 { \tex_global:D #1 ~ \tex_muexpr:D #2 \scan_stop: } \cs_generate_variant:Nn \muskip_set:Nn { c } @@ -2216,10 +2111,8 @@ % } % All straightforward. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \muskip_set_eq:NN #1#2 { #1 = #2 } \cs_generate_variant:Nn \muskip_set_eq:NN { c , Nc , cc } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \muskip_gset_eq:NN #1#2 { \tex_global:D #1 = #2 } \cs_generate_variant:Nn \muskip_gset_eq:NN { c , Nc , cc } % \end{macrocode} @@ -2232,18 +2125,14 @@ % \begin{macro}{\muskip_gsub:Nn, \muskip_gsub:cn} % Using |by| here deals with the (incorrect) case |\muskip123|. % \begin{macrocode} -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \muskip_add:Nn #1#2 { \tex_advance:D #1 by \tex_muexpr:D #2 \scan_stop: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \muskip_gadd:Nn #1#2 { \tex_global:D \tex_advance:D #1 by \tex_muexpr:D #2 \scan_stop: } \cs_generate_variant:Nn \muskip_add:Nn { c } \cs_generate_variant:Nn \muskip_gadd:Nn { c } -\@@_tmp:w \__kernel_chk_var_local:N \cs_new_protected:Npn \muskip_sub:Nn #1#2 { \tex_advance:D #1 by - \tex_muexpr:D #2 \scan_stop: } -\@@_tmp:w \__kernel_chk_var_global:N \cs_new_protected:Npn \muskip_gsub:Nn #1#2 { \tex_global:D \tex_advance:D #1 by - \tex_muexpr:D #2 \scan_stop: } \cs_generate_variant:Nn \muskip_sub:Nn { c } @@ -2259,13 +2148,6 @@ % \begin{macro}{\muskip_eval:n} % Evaluating a muskip expression expandably. % \begin{macrocode} -\__kernel_patch_args:nNNpn - { - { - \__kernel_chk_expr:nNnN {#1} \tex_muexpr:D - { \tex_mutoglue:D } \muskip_eval:n - } - } \cs_new:Npn \muskip_eval:n #1 { \muskip_use:N \tex_muexpr:D #1 \scan_stop: } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx index 9d166d50ff2..826117c512c 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx index af66ad469e4..289f57f144b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx index 3832fbeff6f..7754289843e 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -347,7 +347,7 @@ % \end{function} % % \begin{function}[added = 2013-07-24, updated = 2015-02-28, EXP, noTF] -% {\str_case:nn, \str_case:on, \str_case:nV, \str_case:nv} +% {\str_case:nn, \str_case:Vn, \str_case:on, \str_case:nV, \str_case:nv} % \begin{syntax} % \cs{str_case:nnTF} \Arg{test string} \\ % ~~|{| \\ @@ -1186,7 +1186,7 @@ % \end{macro} % % \begin{macro}[EXP, noTF] -% {\str_case:nn, \str_case:on, \str_case:nV, \str_case:nv, \str_case_e:nn} +% {\str_case:nn, \str_case:Vn, \str_case:on, \str_case:nV, \str_case:nv, \str_case_e:nn} % \begin{macro}[EXP]{\@@_case:nnTF, \@@_case_e:nnTF} % \begin{macro}[EXP] % {\@@_case:nw, \@@_case_e:nw, \@@_case_end:nw} @@ -1215,9 +1215,9 @@ } \cs_new:Npn \@@_case:nnTF #1#2#3#4 { \@@_case:nw {#1} #2 {#1} { } \q_mark {#3} \q_mark {#4} \q_stop } -\cs_generate_variant:Nn \str_case:nn { o , nV , nv } +\cs_generate_variant:Nn \str_case:nn { V , o , nV , nv } \prg_generate_conditional_variant:Nnn \str_case:nn - { o , nV , nv } { T , F , TF } + { V , o , nV , nv } { T , F , TF } \cs_new:Npn \@@_case:nw #1#2#3 { \str_if_eq:nnTF {#1} {#2} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx index 2d791425776..73d4e787f74 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -126,6 +126,156 @@ % |dvi| or |pdf|. % \end{variable} % +% \section{Platform} +% +% \begin{function}[added = 2018-07-27, EXP, pTF] +% { +% \sys_if_platform_unix:, +% \sys_if_platform_windows: +% } +% \begin{syntax} +% \cs{sys_if_platform_unix:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Conditionals which allow platform-specific code to be used. The names +% follow the \Lua{} |os.type()| function, \emph{i.e.}~all Unix-like systems +% are |unix| (including Linux and MacOS). +% \end{function} +% +% \begin{variable}[added = 2018-07-27]{\c_sys_platform_str} +% The current platform given as a lower case string: one of +% |unix|, |windows| or |unknown|. +% \end{variable} +% +% \section{Random numbers} +% +% \begin{function}[added = 2017-05-27, EXP]{\sys_rand_seed:} +% \begin{syntax} +% \cs{sys_rand_seed:} +% \end{syntax} +% Expands to the current value of the engine's random seed, a +% non-negative integer. In engines without random number support this +% expands to $0$. +% \end{function} +% +% \begin{function}[added = 2017-05-27]{\sys_gset_rand_seed:n} +% \begin{syntax} +% \cs{sys_gset_rand_seed:n} \Arg{intexpr} +% \end{syntax} +% Globally sets the seed for the engine's pseudo-random number +% generator to the \meta{integer expression}. This random seed +% affects all \cs[no-index]{\ldots{}_rand} functions (such as +% \cs{int_rand:nn} or \cs{clist_rand_item:n}) as well as other +% packages relying on the engine's random number generator. In +% engines without random number support this produces an error. +% \begin{texnote} +% While a $32$-bit (signed) integer can be given as a seed, only the +% absolute value is used and any number beyond $2^{28}$ is divided +% by an appropriate power of~$2$. We recommend using an integer in +% $[0,2^{28}-1]$. +% \end{texnote} +% \end{function} +% +% \section{Access to the shell} +% +% \begin{function}[noTF, added = 2019-09-20] +% {\sys_get_shell:nnN} +% \begin{syntax} +% \cs{sys_get_shell:nnN} \Arg{shell~command} \Arg{setup} \meta{tl~var} +% \cs{sys_get_shell:nnNTF} \Arg{shell~command} \Arg{setup} \meta{tl~var} \Arg{true code} \Arg{false code} +% \end{syntax} +% Defines \meta{tl} to the text returned by the \meta{shell command}. +% The \meta{shell command} is converted to a string using +% \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 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_get_shell:nnNTF} conditional +% returns \texttt{true} if the shell is available and no quote is +% detected, and \texttt{false} otherwise. +% \end{function} +% +% \begin{variable}[added = 2017-05-27]{\c_sys_shell_escape_int} +% This variable exposes the internal triple of the shell escape +% status. The possible values are +% \begin{description} +% \item[0] Shell escape is disabled +% \item[1] Unrestricted shell escape is enabled +% \item[2] Restricted shell escape is enabled +% \end{description} +% \end{variable} +% +% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell:} +% \begin{syntax} +% \cs{sys_if_shell_p:} +% \cs{sys_if_shell:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Performs a check for whether shell escape is enabled. This +% returns true if either of restricted or unrestricted shell escape +% is enabled. +% \end{function} +% +% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_unrestricted:} +% \begin{syntax} +% \cs{sys_if_shell_unrestricted_p:} +% \cs{sys_if_shell_unrestricted:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Performs a check for whether \emph{unrestricted} shell escape is +% enabled. +% \end{function} +% +% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_restricted:} +% \begin{syntax} +% \cs{sys_if_shell_restricted_p:} +% \cs{sys_if_shell_restricted:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Performs a check for whether \emph{restricted} shell escape is +% enabled. This returns false if unrestricted shell escape is +% enabled. Unrestricted shell escape is not considered a superset +% of restricted shell escape in this case. To find whether any +% shell escape is enabled use \cs{sys_if_shell:}. +% \end{function} +% +% \begin{function}[added = 2017-05-27]{\sys_shell_now:n, \sys_shell_now:x} +% \begin{syntax} +% \cs{sys_shell_now:n} \Arg{tokens} +% \end{syntax} +% Execute \meta{tokens} through shell escape immediately. +% \end{function} +% +% \begin{function}[added = 2017-05-27]{\sys_shell_shipout:n, \sys_shell_shipout:x} +% \begin{syntax} +% \cs{sys_shell_shipout:n} \Arg{tokens} +% \end{syntax} +% Execute \meta{tokens} through shell escape at shipout. +% \end{function} +% +% \subsection{Loading configuration data} +% +% \begin{function}[added = 2019-09-12]{\sys_load_backend:n} +% \begin{syntax} +% \cs{sys_load_backend:n} \Arg{backend} +% \end{syntax} +% Loads the additional configuration file needed for backend support. +% If the \meta{backend} is empty, the standard backend for the engine in +% use will be loaded. This command may only be used once. +% \end{function} +% +% \begin{variable}{\c_sys_backend_str} +% Set to the name of the backend in use by \cs{sys_load_backend:n} when +% issued. +% \end{variable} +% +% \begin{function}[added = 2019-09-12]{\sys_load_debug:, \sys_load_deprecation:} +% \begin{syntax} +% \cs{sys_load_debug:} +% \cs{sys_load_deprecation:} +% \end{syntax} +% Load the additional configuration files for debugging support and rolling +% back deprecations, respectively. +% \end{function} +% % \end{documentation} % % \begin{implementation} @@ -318,6 +468,308 @@ % \end{macrocode} % \end{macro} % +% \subsection{Platform} +% +% \begin{macro}[pTF]{\sys_if_platform_unix:, \sys_if_platform_windows:} +% \begin{variable}{\c_sys_platform_str} +% Setting these up requires the file module (file lookup), so is actually +% implemented there. +% \end{variable} +% \end{macro} +% +% \subsection{Random numbers} +% +% \begin{macro}[EXP]{\sys_rand_seed:} +% Unpack the primitive. When random numbers are not available, we +% return zero after an error (and incidentally make sure the number of +% expansions needed is the same as with random numbers available). +% \begin{macrocode} +\sys_if_rand_exist:TF + { \cs_new:Npn \sys_rand_seed: { \tex_the:D \tex_randomseed:D } } + { + \cs_new:Npn \sys_rand_seed: + { + \int_value:w + \__kernel_msg_expandable_error:nnn { kernel } { fp-no-random } + { \sys_rand_seed: } + \c_zero_int + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sys_gset_rand_seed:n} +% The primitive always assigns the seed globally. +% \begin{macrocode} +\sys_if_rand_exist:TF + { + \cs_new_protected:Npn \sys_gset_rand_seed:n #1 + { \tex_setrandomseed:D \int_eval:n {#1} \exp_stop_f: } + } + { + \cs_new_protected:Npn \sys_gset_rand_seed:n #1 + { + \__kernel_msg_error:nnn { kernel } { fp-no-random } + { \sys_gset_rand_seed:n {#1} } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Access to the shell} +% +% \begin{variable}{\c_sys_shell_escape_int} +% Expose the engine's shell escape status to the user. +% \begin{macrocode} +\int_const:Nn \c_sys_shell_escape_int + { + \sys_if_engine_luatex:TF + { + \tex_directlua:D + { tex.sprint(status.shell_escape~or~os.execute()) } + } + { + \tex_shellescape:D + } + } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_internal_tl} +% \begin{macrocode} +\tl_new:N \l_@@_internal_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_@@_marker_tl} +% The same idea as the marker for rescanning token lists. +% \begin{macrocode} +\tl_const:Nx \c_@@_marker_tl { : \token_to_str:N : } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[TF]{\sys_get_shell:nnN} +% \begin{macro}{\sys_get_shell:nnN,\@@_get:nnN,\@@_get_do:Nw} +% Setting using a shell is at this level just a slightly specialised file +% operation, with an additional check for quotes, as these are not supported. +% \begin{macrocode} +\cs_new_protected:Npn \sys_get_shell:nnN #1#2#3 + { + \sys_get_shell:nnNF {#1} {#2} #3 + { \tl_set:Nn #3 { \q_no_value } } + } +\prg_new_protected_conditional:Npnn \sys_get_shell:nnN #1#2#3 { T , F , TF } + { + \sys_if_shell:TF + { \exp_args:No \@@_get:nnN { \tl_to_str:n {#1} } {#2} #3 } + { \prg_return_false: } + } +\cs_new_protected:Npn \@@_get:nnN #1#2#3 + { + \tl_if_in:nnTF {#1} { " } + { + \__kernel_msg_error:nnx + { kernel } { quote-in-shell } {#1} + \prg_return_false: + } + { + \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: + \exp_after:wN \@@_get_do:Nw + \exp_after:wN #3 + \exp_after:wN \prg_do_nothing: + \tex_input:D | "#1" \scan_stop: + \if_false: } \fi: + \prg_return_true: + } + } +\exp_args:Nno \use:nn + { \cs_new_protected:Npn \@@_get_do:Nw #1#2 } + { \c_@@_marker_tl } + { + \group_end: + \tl_set:No #1 {#2} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP, pTF]{\sys_if_shell:, \sys_if_shell_unrestricted:, \sys_if_shell_restricted:} +% Performs a check for whether shell escape is enabled. The first set +% of functions returns true if either of restricted or unrestricted +% shell escape is enabled, while the other two sets of functions +% return true in only one of these two cases. +% \begin{macrocode} +\@@_const:nn { sys_if_shell } + { \int_compare_p:nNn \c_sys_shell_escape_int > 0 } +\@@_const:nn { sys_if_shell_unrestricted } + { \int_compare_p:nNn \c_sys_shell_escape_int = 1 } +\@@_const:nn { sys_if_shell_restricted } + { \int_compare_p:nNn \c_sys_shell_escape_int = 2 } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\c_@@_shell_stream_int} +% This is not needed for \LuaTeX{}: shell escape there isn't done using +% a \TeX{} interface. +% \begin{macrocode} +\sys_if_engine_luatex:F + { \int_const:Nn \c_@@_shell_stream_int { 18 } } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\sys_shell_now:n} +% Execute commands through shell escape immediately. +% \begin{macrocode} +\sys_if_engine_luatex:TF + { + \cs_new_protected:Npn \sys_shell_now:n #1 + { + \lua_now:e + { os.execute(" \lua_escape:e { \tl_to_str:n {#1} } ") } + } + } + { + \cs_new_protected:Npn \sys_shell_now:n #1 + { \iow_now:Nn \c_@@_shell_stream_int {#1} } + } +\cs_generate_variant:Nn \sys_shell_now:n { x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sys_shell_shipout:n} +% Execute commands through shell escape at shipout. +% \begin{macrocode} +\sys_if_engine_luatex:TF + { + \cs_new_protected:Npn \sys_shell_shipout:n #1 + { + \lua_shipout_e:n + { os.execute(" \lua_escape:e { \tl_to_str:n {#1} } ") } + } + } + { + \cs_new_protected:Npn \sys_shell_shipout:n #1 + { \iow_shipout:Nn \c_@@_shell_stream_int {#1} } + } +\cs_generate_variant:Nn \sys_shell_shipout:n { x } +% \end{macrocode} +% \end{macro} +% +% \subsection{Configurations} +% +% \begin{variable}{\g_@@_backend_tl} +% As the backend has to be checked and possibly adjusted, the approach here +% is to create a variable and use that in a one-shot to set a constant. +% \begin{macrocode} +\tl_new:N \g_@@_backend_tl +\tl_gset:Nx \g_@@_backend_tl + { + \sys_if_engine_xetex:TF + { xdvipdfmx } + { + \sys_if_output_pdf:TF + { pdfmode } + { + \bool_lazy_or:nnTF + { \sys_if_engine_ptex_p: } + { \sys_if_engine_uptex_p: } + { dvipdfmx } + { dvips } + } + } + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\sys_load_backend:n} +% \begin{macro}{\@@_load_backend_check:N} +% \begin{variable}{\c_sys_backend_str} +% Loading the backend code is pretty simply: check that the backend is valid, +% then load it up. +% \begin{macrocode} +\cs_new_protected:Npn \sys_load_backend:n #1 + { + \str_if_exist:NTF \c_sys_backend_str + { \__kernel_msg_error:nnxx { sys } { backend-set } } + { + \tl_if_blank:nF {#1} + { \tl_set:Nn \g_@@_backend_tl {#1} } + \@@_load_backend_check:N \g_@@_backend_tl + \str_const:Nx \c_sys_backend_str { \g_@@_backend_tl } + \__kernel_sys_configuration_load:n + { l3backend- \c_sys_backend_str } + } + } +\cs_new_protected:Npn \@@_load_backend_check:N #1 + { + \sys_if_engine_xetex:TF + { + \str_if_eq:VnF #1 { xdvipdfmx } + { + \__kernel_msg_error:nnxx { sys } { wrong-backend } + #1 { xdvipdfmx } + \tl_gset:Nn #1 { xdvipdfmx } + } + } + { + \sys_if_output_pdf:TF + { + \str_if_eq:VnF #1 { pdfmode } + { + \__kernel_msg_error:nnxx { sys } { wrong-backend } + #1 { pdfmode } + \tl_gset:Nn #1 { pdfmode } + } + } + { + \str_case:VnF #1 + { + { dvipdfmx } { } + { dvips } { } + { dvisvgm } { } + } + { + \__kernel_msg_error:nnxx { sys } { wrong-backend } + #1 { dvips } + \tl_gset:Nn #1 { dvips } + } + } + } + } +% \end{macrocode} +% \end{variable} +% \end{macro} +% \end{macro} +% +% \begin{variable}{\g_@@_debug_bool, \g_@@_deprecation_bool} +% \begin{macrocode} +\bool_new:N \g_@@_debug_bool +\bool_new:N \g_@@_deprecation_bool +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\sys_load_debug:, \sys_load_deprecation:} +% Simple. +% \begin{macrocode} +\cs_new_protected:Npn \sys_load_debug: + { + \bool_if:NF \g_@@_debug_bool + { \__kernel_sys_configuration_load:n { l3debug } } + \bool_gset_true:N \g_@@_debug_bool + } +\cs_new_protected:Npn \sys_load_deprecation: + { + \bool_if:NF \g_@@_deprecation_bool + { \__kernel_sys_configuration_load:n { l3deprecation } } + \bool_gset_true:N \g_@@_deprecation_bool + } +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx index f522435876d..07ed2c8f578 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index 96cfc1dfcf4..c7728a33f28 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -957,7 +957,8 @@ % \end{texnote} % \end{function} % -% \begin{function}[updated = 2012-07-09, EXP, pTF]{\tl_if_head_eq_catcode:nN} +% \begin{function}[updated = 2012-07-09, EXP, pTF] +% {\tl_if_head_eq_catcode:nN, \tl_if_head_eq_catcode:oN} % \begin{syntax} % \cs{tl_if_head_eq_catcode_p:nN} \Arg{token list} \meta{test token} % \cs{tl_if_head_eq_catcode:nNTF} \Arg{token list} \meta{test token} @@ -1267,13 +1268,11 @@ % \begin{macro}{\tl_const:Nn, \tl_const:Nx, \tl_const:cn, \tl_const:cx} % Constants are also easy to generate. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } \cs_new_protected:Npn \tl_const:Nn #1#2 { \__kernel_chk_if_free_cs:N #1 \cs_gset_nopar:Npx #1 { \exp_not:n {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN c #1 } { } \cs_new_protected:Npn \tl_const:Nx #1#2 { \__kernel_chk_if_free_cs:N #1 @@ -1316,28 +1315,11 @@ % % \begin{macro}{\tl_set_eq:NN, \tl_set_eq:Nc, \tl_set_eq:cN, \tl_set_eq:cc} % \begin{macro}{\tl_gset_eq:NN, \tl_gset_eq:Nc, \tl_gset_eq:cN, \tl_gset_eq:cc} -% For setting token list variables equal to each other. When checking -% is turned on, make sure both variables exist. +% For setting token list variables equal to each other. To allow for +% patching, the arguments have to be explicit. % \begin{macrocode} -\__kernel_if_debug:TF - { - \cs_new_protected:Npn \tl_set_eq:NN #1#2 - { - \__kernel_chk_var_local:N #1 - \__kernel_chk_var_exist:N #2 - \cs_set_eq:NN #1 #2 - } - \cs_new_protected:Npn \tl_gset_eq:NN #1#2 - { - \__kernel_chk_var_global:N #1 - \__kernel_chk_var_exist:N #2 - \cs_gset_eq:NN #1 #2 - } - } - { - \cs_new_eq:NN \tl_set_eq:NN \cs_set_eq:NN - \cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN - } +\cs_new_protected:Npn \tl_set_eq:NN #1#2 { \cs_set_eq:NN #1 #2 } +\cs_new_protected:Npn \tl_gset_eq:NN #1#2 { \cs_gset_eq:NN #1 #2 } \cs_generate_variant:Nn \tl_set_eq:NN { cN, Nc, cc } \cs_generate_variant:Nn \tl_gset_eq:NN { cN, Nc, cc } % \end{macrocode} @@ -1350,20 +1332,8 @@ % three arguments must be checked: a token list |#2| or |#3| equal to % \cs{scan_stop:} would lead to problems later on. % \begin{macrocode} -\__kernel_patch:nnNNpn - { - \__kernel_chk_var_exist:N #2 - \__kernel_chk_var_exist:N #3 - } - { } \cs_new_protected:Npn \tl_concat:NNN #1#2#3 { \tl_set:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } } -\__kernel_patch:nnNNpn - { - \__kernel_chk_var_exist:N #2 - \__kernel_chk_var_exist:N #3 - } - { } \cs_new_protected:Npn \tl_gconcat:NNN #1#2#3 { \tl_gset:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } } \cs_generate_variant:Nn \tl_concat:NNN { ccc } @@ -1429,26 +1399,18 @@ % By using \cs{exp_not:n} token list variables can contain |#| tokens, % which makes the token list registers provided by \TeX{} % more or less redundant. The \cs{tl_set:No} version is done -% \enquote{by hand} as it is used quite a lot. Each definition is -% prefixed by a call to \cs{__kernel_patch:nnNNpn} which adds an -% existence check to the definition. +% \enquote{by hand} as it is used quite a lot. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_set:Nn #1#2 { \cs_set_nopar:Npx #1 { \exp_not:n {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_set:No #1#2 { \cs_set_nopar:Npx #1 { \exp_not:o {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_set:Nx #1#2 { \cs_set_nopar:Npx #1 {#2} } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gset:Nn #1#2 { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gset:No #1#2 { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gset:Nx #1#2 { \cs_gset_nopar:Npx #1 {#2} } \cs_generate_variant:Nn \tl_set:Nn { NV , Nv , Nf } @@ -1473,28 +1435,20 @@ % } % Adding to the left is done directly to gain a little performance. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_put_left:Nn #1#2 { \cs_set_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_put_left:NV #1#2 { \cs_set_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_put_left:No #1#2 { \cs_set_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_put_left:Nx #1#2 { \cs_set_nopar:Npx #1 { #2 \exp_not:o #1 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gput_left:Nn #1#2 { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gput_left:NV #1#2 { \cs_gset_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gput_left:No #1#2 { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gput_left:Nx #1#2 { \cs_gset_nopar:Npx #1 { #2 \exp_not:o {#1} } } \cs_generate_variant:Nn \tl_put_left:Nn { c } @@ -1523,28 +1477,20 @@ % } % The same on the right. % \begin{macrocode} -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_put_right:Nn #1#2 { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_put_right:NV #1#2 { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_put_right:No #1#2 { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_local:N #1 } { } \cs_new_protected:Npn \tl_put_right:Nx #1#2 { \cs_set_nopar:Npx #1 { \exp_not:o #1 #2 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gput_right:Nn #1#2 { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gput_right:NV #1#2 { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gput_right:No #1#2 { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } } -\__kernel_patch:nnNNpn { \__kernel_chk_var_global:N #1 } { } \cs_new_protected:Npn \tl_gput_right:Nx #1#2 { \cs_gset_nopar:Npx #1 { \exp_not:o {#1} #2 } } \cs_generate_variant:Nn \tl_put_right:Nn { c } @@ -3016,6 +2962,8 @@ \prg_return_false: \fi: } +\prg_generate_conditional_variant:Nnn \tl_if_head_eq_catcode:nN + { o } { p , TF , T , F } % \end{macrocode} % For \cs{tl_if_head_eq_meaning:nN}, again, detect special cases. In % the normal case, use \cs{tl_head:w}, with no \cs{exp_not:N} this diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx index bc32b8813db..df41d89943a 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx index 7795efd6a88..c7e465576ab 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-09-19} +% \date{Released 2019-09-28} % % \maketitle % |