% \iffalse meta-comment % %% File: l3deprecation.dtx % % Copyright (C) 2017-2020 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} % % \fi % % \title{^^A % The \pkg{l3deprecation} package\\ Deprecation errors^^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 2020-06-18} % % \maketitle % % \begin{documentation} % % \section{\pkg{l3deprecation} documentation} % % A few commands have had to be deprecated over the years. This module % defines deprecated and deleted commands to produce an error. % % The life of a deprecated command has several stages. % \begin{itemize} % \item When we decide it should be eventually removed the command's % definition is put in this file \pkg{l3deprecation.dtx} and the name % of the command is added to the list in \pkg{l3obsolete.txt}. The % command remains defined by default for $12$ or more months, % typically until the end of a year. During that time, if \pkg{expl3} % is loaded with any of the options \texttt{check-declarations} or % \texttt{log-functions} or \texttt{enable-debug} typically used in % package test files, the command will produce a warning. % \item Then by default the command produces an error for all users, % which can be suppressed for $6$ months through the option % \texttt{undo-recent-deprecations}. % \item After this $6$-month grace period, the command irreversibly % produces an error. Its original definition can then be removed from % the sources, leaving only the error definition. In % \pkg{l3obsolete.txt} its name is moved from the \enquote{Deprecated % functions and variables} list to the \enquote{Removed functions and % variables} list. % \end{itemize} % Package authors are encouraged to have a test file with % \cs{debug_on:n} |{deprecation}|, which makes commands at all stages of % this list into errors. This helps detect uses of deprecated commands % before user complain. % % \end{documentation} % % \begin{implementation} % % \section{\pkg{l3deprecation} implementation} % % \begin{macrocode} %<*initex|package> % \end{macrocode} % % \begin{macrocode} %<*kernel> % \end{macrocode} % % \begin{macrocode} %<@@=deprecation> % \end{macrocode} % % \subsection{Helpers and variables} % % \begin{variable}{\l_@@_grace_period_bool} % This is set to \texttt{true} when the deprecated command that is % being defined is in its grace period, meaning between the time it % becomes an error by default and the time $6$~months later where even % \texttt{undo-recent-deprecations} stops restoring it. % \begin{macrocode} \bool_new:N \l_@@_grace_period_bool % \end{macrocode} % \end{variable} % % \begin{variable}{\s_@@_mark,\s_@@_stop} % Internal scan marks. % \begin{macrocode} \scan_new:N \s_@@_mark \scan_new:N \s_@@_stop % \end{macrocode} % \end{variable} % % \begin{macro}[EXP]{\@@_date_compare:nNnTF, \@@_date_compare_aux:w} % Expects |#1| and |#3| to be dates in the format YYYY-MM-DD (but % accepts YYYY or YYYY-MM too, filling in zeros for the missing data). % Compares them using |#2| (one of |<|, |=|, |>|). % \begin{macrocode} \cs_new:Npn \@@_date_compare:nNnTF #1#2#3 { \@@_date_compare_aux:w #1 -0-0- \s_@@_mark #2 #3 -0-0- \s_@@_stop } \cs_new:Npn \@@_date_compare_aux:w #1 - #2 - #3 - #4 \s_@@_mark #5 #6 - #7 - #8 - #9 \s_@@_stop { \int_compare:nNnTF {#1} = {#6} { \int_compare:nNnTF {#2} = {#7} { \int_compare:nNnTF {#3} #5 {#8} } { \int_compare:nNnTF {#2} #5 {#7} } } { \int_compare:nNnTF {#1} #5 {#6} } } % \end{macrocode} % \end{macro} % % \begin{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) % than \meta{date}. If \texttt{undo-recent-deprecations} is used we % subtract $6$ months to the \pkg{expl3} date (equivalently add $6$ % months to the \meta{date}). In addition, if the \pkg{expl3} date is % between \meta{date} and \meta{date} plus $6$ months, % \cs{l_@@_grace_period_bool} is set to \texttt{true}, otherwise % \texttt{false}. % \begin{macrocode} \cs_new_protected:Npn \@@_not_yet_deprecated:nTF #1 { \bool_set_false:N \l_@@_grace_period_bool \exp_args:No \@@_date_compare:nNnTF { \ExplLoaderFileDate } < {#1} { \use_i:nn } { \exp_args:Nf \@@_date_compare:nNnTF { \exp_after:wN \@@_minus_six_months:w \ExplLoaderFileDate -0-0- \s_@@_stop } < {#1} { \bool_set_true:N \l_@@_grace_period_bool \bool_if:NTF \g__kernel_deprecation_undo_recent_bool } { \use_ii:nn } } } \cs_new:Npn \@@_minus_six_months:w #1 - #2 - #3 - #4 \s_@@_stop { \int_compare:nNnTF {#2} > 6 { #1 - \int_eval:n { #2 - 6 } - #3 } { \int_eval:n { #1 - 1 } - \int_eval:n { #2 + 6 } - #3 } } % \end{macrocode} % \end{macro} % % \subsection{Patching definitions to deprecate} % % \begin{quote} % \cs{__kernel_patch_deprecation:nnNNpn} \Arg{date} \Arg{replacement} % \meta{definition} \meta{function} \meta{parameters} \Arg{code} % \end{quote} % defines the \meta{function} to produce a warning and run its % \meta{code}, or to produce an error and not run any \meta{code}, % depending on the \pkg{expl3} date. % \begin{itemize} % \item If the \pkg{expl3} date is less than the \meta{date} (plus % $6$~months in case \texttt{undo-recent-deprecations} is used) then % we define the \meta{function} to produce a warning and run its code. % The warning is actually suppressed in two cases: % \begin{itemize} % \item if neither \texttt{undo-recent-deprecations} nor % \texttt{enable-debug} are in effect we may be in an end-user's % document so it is suppressed; % \item if the command is expandable then we cannot produce a warning. % \end{itemize} % \item Otherwise, we define the \meta{function} to produce an error. % \end{itemize} % In both cases we additionally make \cs{debug_on:n} |{deprecation}| % turn the \meta{function} into an \tn{outer} error, and % \cs{debug_off:n} |{deprecation}| restore whatever the behaviour was % without \cs{debug_on:n} |{deprecation}|. % % In later sections we use the \pkg{l3doc} key \texttt{deprecated} with % a date equal to that \meta{date} plus $6$~months, so that \pkg{l3doc} % will complain if we forget to remove the stale \meta{parameters} and % \Arg{code}. % % In the explanations below, \meta{definition} \meta{function} % \meta{parameters} \Arg{code} or assignments that only differ in the % scope of the \meta{definition} will be called \enquote{the standard % definition}. % % \begin{macro} % { % \__kernel_patch_deprecation:nnNNpn, \@@_patch_aux:nnNNnn, % \@@_warn_once:nnNnn, % \@@_patch_aux:Nn, % \@@_just_error:nnNN % } % (The parameter text is grabbed using |#5#|.) The arguments of % \cs{__kernel_deprecation_code:nn} are run upon \cs{debug_on:n} % |{deprecation}| and \cs{debug_off:n} |{deprecation}|, respectively. % In both scenarios we the \meta{function} may be \tn{outer} so we % undefine it with \cs{tex_let:D} before redefining it, with % \cs{__kernel_deprecation_error:Nnn} or with some code added shortly. % % Then check the date (taking into account % \texttt{undo-recent-deprecations}) to see if the command should be % deprecated right away (\texttt{false} branch of % \cs{@@_not_yet_deprecated:nTF}), in which case % \cs{@@_just_error:nnNN} makes \meta{function} into an error (not % \tn{outer}), ignoring its \meta{parameters} and \meta{code} % completely. % % Otherwise distinguish cases where we should give a warning from % those where we shouldn't: warnings can only happen for protected % commands, and we only want them if either % \texttt{undo-recent-deprecations} or \texttt{enable-debug} is in % force, not for standard users. % \begin{macrocode} \cs_new_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2#3#4#5# { \@@_patch_aux:nnNNnn {#1} {#2} #3 #4 {#5} } \cs_new_protected:Npn \@@_patch_aux:nnNNnn #1#2#3#4#5#6 { \__kernel_deprecation_code:nn { \tex_let:D #4 \scan_stop: \__kernel_deprecation_error:Nnn #4 {#2} {#1} } { \tex_let:D #4 \scan_stop: } \@@_not_yet_deprecated:nTF {#1} { \bool_if:nTF { \cs_if_eq_p:NN #3 \cs_gset_protected:Npn && \__kernel_if_debug:TF { \c_true_bool } { \g__kernel_deprecation_undo_recent_bool } } { \@@_warn_once:nnNnn {#1} {#2} #4 {#5} {#6} } { \@@_patch_aux:Nn #3 { #4 #5 {#6} } } } { \@@_just_error:nnNN {#1} {#2} #3 #4 } } % \end{macrocode} % In case we want a warning, the \meta{function} is defined to produce % such a warning without grabbing any argument, then redefine itself % to the standard definition that the \meta{function} should have, % with arguments, and call that definition. The \texttt{x}-type % expansion and \cs{exp_not:n} avoid needing to double the~|#|, which % we could not do anyways. We then deal with the code for % \cs{debug_off:n} |{deprecation}|: presumably someone doing that does % not need the warning so we simply do the standard definition. % \begin{macrocode} \cs_new_protected:Npn \@@_warn_once:nnNnn #1#2#3#4#5 { \cs_gset_protected:Npx #3 { \__kernel_if_debug:TF { \exp_not:N \__kernel_msg_warning:nnxxx { kernel } { deprecated-command } {#1} { \token_to_str:N #3 } { \tl_to_str:n {#2} } } { } \exp_not:n { \cs_gset_protected:Npn #3 #4 {#5} } \exp_not:N #3 } \__kernel_deprecation_code:nn { } { \cs_set_protected:Npn #3 #4 {#5} } } % \end{macrocode} % In case we want neither warning nor error, the \meta{function} is % given its standard definition. Here |#1| is \cs{cs_new:Npn} or % \cs{cs_new_protected:Npn}) and |#2| is \meta{function} % \meta{parameters} \Arg{code}, so |#1#2| performs the assignment. % For \cs{debug_off:n} |{deprecation}| we want to use the same % assignment but with a different scope, hence the \cs{cs_if_eq:NNTF} % test. % \begin{macrocode} \cs_new_protected:Npn \@@_patch_aux:Nn #1#2 { #1 #2 \cs_if_eq:NNTF #1 \cs_gset_protected:Npn { \__kernel_deprecation_code:nn { } { \cs_set_protected:Npn #2 } } { \__kernel_deprecation_code:nn { } { \cs_set:Npn #2 } } } % \end{macrocode} % Finally, if we want an error we reuse the same \cs{@@_patch_aux:Nn} % as the previous case. Indeed, we want \cs{debug_off:n} % |{deprecation}| to make the \meta{function} into an error, just like % it is by default. The error is expandable or not, and the last % argument of the error message is empty or is \texttt{grace} to % denote the case where we are in the $6$~month grace period, in which % case the error message is more detailed. % \begin{macrocode} \cs_new_protected:Npn \@@_just_error:nnNN #1#2#3#4 { \exp_args:NNx \@@_patch_aux:Nn #3 { \exp_not:N #4 { \cs_if_eq:NNTF #3 \cs_gset_protected:Npn { \exp_not:N \__kernel_msg_error:nnnnnn } { \exp_not:N \__kernel_msg_expandable_error:nnnnnn } { kernel } { deprecated-command } {#1} { \token_to_str:N #4 } { \tl_to_str:n {#2} } { \bool_if:NT \l_@@_grace_period_bool { grace } } } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\__kernel_deprecation_error:Nnn} % The \tn{outer} definition here ensures the command cannot appear % in an argument. Use this auxiliary on all commands that have been % removed since 2015. % \begin{macrocode} \cs_new_protected:Npn \__kernel_deprecation_error:Nnn #1#2#3 { \tex_protected:D \tex_outer:D \tex_edef:D #1 { \exp_not:N \__kernel_msg_expandable_error:nnnnn { kernel } { deprecated-command } { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} } \exp_not:N \__kernel_msg_error:nnxxx { kernel } { deprecated-command } { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} } } } % \end{macrocode} % \end{macro} % % \begin{macrocode} \__kernel_msg_new:nnn { kernel } { deprecated-command } { \tl_if_blank:nF {#3} { Use~ \tl_trim_spaces:n {#3} ~not~ } #2~deprecated~on~#1. \str_if_eq:nnT {#4} { grace } { \c_space_tl For~6~months~after~that~date~one~can~restore~a~deprecated~ command~by~loading~the~expl3~package~with~the~option~ 'undo-recent-deprecations'. } } % \end{macrocode} % % \subsection{Removed functions} % % \begin{macro}{\@@_old_protected:Nnn, \@@_old:Nnn} % Short-hands for old commands whose definition does not matter % anymore, i.e., commands past the grace period. % \begin{macrocode} \cs_new_protected:Npn \@@_old_protected:Nnn #1#2#3 { \__kernel_patch_deprecation:nnNNpn {#3} {#2} \cs_gset_protected:Npn #1 { } } \cs_new_protected:Npn \@@_old:Nnn #1#2#3 { \__kernel_patch_deprecation:nnNNpn {#3} {#2} \cs_gset:Npn #1 { } } \@@_old:Nnn \box_resize:Nnn { \box_resize_to_wd_and_ht_plus_dp:Nnn } { 2019-01-01 } \@@_old:Nnn \box_use_clear:N { \box_use_drop:N } { 2019-01-01 } \@@_old:Nnn \c_job_name_tl { \c_sys_jobname_str } { 2017-01-01 } \@@_old:Nnn \c_minus_one { -1 } { 2019-01-01 } \@@_old:Nnn \dim_case:nnn { \dim_case:nnF } { 2015-07-14 } \@@_old:Nnn \file_add_path:nN { \file_get_full_name:nN } { 2019-01-01 } \@@_old_protected:Nnn \file_if_exist_input:nT { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 } \@@_old_protected:Nnn \file_if_exist_input:nTF { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 } \@@_old:Nnn \file_list: { \file_log_list: } { 2019-01-01 } \@@_old:Nnn \file_path_include:n { \seq_put_right:Nn \l_file_search_path_seq } { 2019-01-01 } \@@_old:Nnn \file_path_remove:n { \seq_remove_all:Nn \l_file_search_path_seq } { 2019-01-01 } \@@_old:Nnn \g_file_current_name_tl { \g_file_curr_name_str } { 2019-01-01 } \@@_old:Nnn \int_case:nnn { \int_case:nnF } { 2015-07-14 } \@@_old:Nnn \int_from_binary:n { \int_from_bin:n } { 2016-01-05 } \@@_old:Nnn \int_from_hexadecimal:n { \int_from_hex:n } { 2016-01-05 } \@@_old:Nnn \int_from_octal:n { \int_from_oct:n } { 2016-01-05 } \@@_old:Nnn \int_to_binary:n { \int_to_bin:n } { 2016-01-05 } \@@_old:Nnn \int_to_hexadecimal:n { \int_to_hex:n } { 2016-01-05 } \@@_old:Nnn \int_to_octal:n { \int_to_oct:n } { 2016-01-05 } \@@_old_protected:Nnn \ior_get_str:NN { \ior_str_get:NN } { 2018-03-05 } \@@_old:Nnn \ior_list_streams: { \ior_show_list: } { 2019-01-01 } \@@_old:Nnn \ior_log_streams: { \ior_log_list: } { 2019-01-01 } \@@_old:Nnn \iow_list_streams: { \iow_show_list: } { 2019-01-01 } \@@_old:Nnn \iow_log_streams: { \iow_log_list: } { 2019-01-01 } \@@_old:Nnn \luatex_if_engine_p: { \sys_if_engine_luatex_p: } { 2017-01-01 } \@@_old:Nnn \luatex_if_engine:F { \sys_if_engine_luatex:F } { 2017-01-01 } \@@_old:Nnn \luatex_if_engine:T { \sys_if_engine_luatex:T } { 2017-01-01 } \@@_old:Nnn \luatex_if_engine:TF { \sys_if_engine_luatex:TF } { 2017-01-01 } \@@_old:Nnn \pdftex_if_engine_p: { \sys_if_engine_pdftex_p: } { 2017-01-01 } \@@_old:Nnn \pdftex_if_engine:F { \sys_if_engine_pdftex:F } { 2017-01-01 } \@@_old:Nnn \pdftex_if_engine:T { \sys_if_engine_pdftex:T } { 2017-01-01 } \@@_old:Nnn \pdftex_if_engine:TF { \sys_if_engine_pdftex:TF } { 2017-01-01 } \@@_old:Nnn \prop_get:cn { \prop_item:cn } { 2016-01-05 } \@@_old:Nnn \prop_get:Nn { \prop_item:Nn } { 2016-01-05 } \@@_old:Nnn \quark_if_recursion_tail_break:N { } { 2015-07-14 } \@@_old:Nnn \quark_if_recursion_tail_break:n { } { 2015-07-14 } \@@_old:Nnn \scan_align_safe_stop: { protected~commands } { 2017-01-01 } \@@_old:Nnn \sort_ordered: { \sort_return_same: } { 2019-01-01 } \@@_old:Nnn \sort_reversed: { \sort_return_swapped: } { 2019-01-01 } \@@_old:Nnn \str_case:nnn { \str_case:nnF } { 2015-07-14 } \@@_old:Nnn \str_case:onn { \str_case:onF } { 2015-07-14 } \@@_old:Nnn \str_case_x:nnn { \str_case_e:nnF } { 2015-07-14 } \@@_old:Nnn \tl_case:cnn { \tl_case:cnF } { 2015-07-14 } \@@_old:Nnn \tl_case:Nnn { \tl_case:NnF } { 2015-07-14 } \@@_old_protected:Nnn \tl_to_lowercase:n { \tex_lowercase:D } { 2018-03-05 } \@@_old_protected:Nnn \tl_to_uppercase:n { \tex_uppercase:D } { 2018-03-05 } \@@_old:Nnn \token_new:Nn { \cs_new_eq:NN } { 2019-01-01 } \@@_old:Nnn \xetex_if_engine_p: { \sys_if_engine_xetex_p: } { 2017-01-01 } \@@_old:Nnn \xetex_if_engine:F { \sys_if_engine_xetex:F } { 2017-01-01 } \@@_old:Nnn \xetex_if_engine:T { \sys_if_engine_xetex:T } { 2017-01-01 } \@@_old:Nnn \xetex_if_engine:TF { \sys_if_engine_xetex:TF } { 2017-01-01 } % \end{macrocode} % \end{macro} % % \subsection{Deprecated primitives} % % \begin{macro}[deprecated = 2020-07-01]{\etex_beginL:D} % \begin{macro}{\@@_primitive:NN, \@@_primitive:w} % We renamed all primitives to \cs[no-index]{tex_\ldots{}:D} so all % others are deprecated. In \pkg{l3names}, \cs{__kernel_primitives:} % is defined to contain \cs{__kernel_primitive:NN} \cs{beginL} % \cs{etex_beginL:D} and so on, one for each deprecated primitive. We % apply \cs{exp_not:N} to the second argument of % \cs{__kernel_primitive:NN} because it may be outer (both when doing % and undoing deprecation actually), then \cs{@@_primitive:NN} uses % \cs{tex_let:D} to change the meaning of this potentially outer % token. Then, either turn it into an error or make it equal to the % primitive~|#1|. To be more precise, |#1| may not be defined, so try % a \cs[no-index]{tex_\ldots{}:D} command as well. % \begin{macrocode} \cs_new_protected:Npn \@@_primitive:NN #1#2 { } \exp_last_unbraced:NNNNo \cs_new:Npn \@@_primitive:w #1 { \token_to_str:N _ } { } \__kernel_deprecation_code:nn { \cs_set_protected:Npn \__kernel_primitive:NN #1 { \exp_after:wN \@@_primitive:NN \exp_after:wN #1 \exp_not:N } \cs_set_protected:Npn \@@_primitive:NN #1#2 { \tex_let:D #2 \scan_stop: \exp_args:NNx \__kernel_deprecation_error:Nnn #2 { \iow_char:N \\ \cs_if_exist:NTF #1 { \cs_to_str:N #1 } { tex_ \exp_last_unbraced:Nf \@@_primitive:w { \cs_to_str:N #2 } } } { 2020-01-01 } } \__kernel_primitives: } { \cs_set_protected:Npn \__kernel_primitive:NN #1 { \exp_after:wN \@@_primitive:NN \exp_after:wN #1 \exp_not:N } \cs_set_protected:Npn \@@_primitive:NN #1#2 { \tex_let:D #2 #1 \cs_if_exist:cT { tex_ \cs_to_str:N #1 :D } { \cs_set_eq:Nc #2 { tex_ \cs_to_str:N #1 :D } } } \__kernel_primitives: } % \end{macrocode} % \end{macro} % \end{macro} % % \subsection{Loading the patches} % % When loaded first, the patches are simply read here. % Here the deprecation code is loaded with the lower-level |\__kernel_...| % macro because we don't want it to flip the \cs{g__sys_deprecation_bool} % boolean, so that the deprecation code can be re-loaded later (when using % \texttt{undo-recent-deprecations}). % % \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 } } } \cs_gset_protected:Npn \__kernel_sys_configuration_load:n #1 { \file_input:n { #1 .def } } \__kernel_sys_configuration_load:n { l3deprecation } % \end{macrocode} % % \begin{macrocode} % % \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] % { % \box_set_eq_clear:NN, \box_set_eq_clear:cN, % \box_set_eq_clear:Nc, \box_set_eq_clear:cc % } % \begin{macro}[deprecated = 2021-07-01] % { % \box_gset_eq_clear:NN, \box_gset_eq_clear:cN, % \box_gset_eq_clear:Nc, \box_gset_eq_clear:cc % } % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \box_set_eq_drop:N } \cs_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_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 } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}[deprecated = 2021-07-01]{\hbox_unpack_clear:N, \hbox_unpack_clear:c} % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \hbox_unpack_drop:N } \cs_gset_protected:Npn \hbox_unpack_clear:N { \hbox_unpack_drop:N } \cs_generate_variant:Nn \hbox_unpack_clear:N { c } % \end{macrocode} % \end{macro} % % \begin{macro}[deprecated = 2021-07-01]{\vbox_unpack_clear:N, \vbox_unpack_clear:c} % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \vbox_unpack_drop:N } \cs_gset_protected:Npn \vbox_unpack_clear:N { \vbox_unpack_drop:N } \cs_generate_variant:Nn \vbox_unpack_clear:N { c } % \end{macrocode} % \end{macro} % % \subsection{Deprecated \pkg{l3int} functions} % % \begin{macrocode} %<@@=int> % \end{macrocode} % % \begin{variable}[deprecated = 2020-07-01] % { % \c_zero, \c_one, \c_two, \c_three, \c_four, \c_five, \c_six, % \c_seven, \c_eight, \c_nine, \c_ten, \c_eleven, \c_twelve, % \c_thirteen, \c_fourteen, \c_fifteen, \c_sixteen, \c_thirty_two, % \c_one_hundred, \c_two_hundred_fifty_five, % \c_two_hundred_fifty_six, \c_one_thousand, \c_ten_thousand, % } % \begin{macro}{\@@_deprecated_constants:nn} % Constants that are now deprecated. By default define them with % \cs{int_const:Nn}. To deprecate them call for instance % \cs{__kernel_deprecation_error:Nnn} \cs{c_zero} |{0}| % |{2020-01-01}|. To redefine them (locally), use % \cs{@@_constdef:Nw}, with an \cs{exp_not:N} construction because the % constants themselves are outer at that point. % \begin{macrocode} \cs_gset_protected:Npn \@@_deprecated_constants:nn #1#2 { #1 \c_zero { 0 } #2 #1 \c_one { 1 } #2 #1 \c_two { 2 } #2 #1 \c_three { 3 } #2 #1 \c_four { 4 } #2 #1 \c_five { 5 } #2 #1 \c_six { 6 } #2 #1 \c_seven { 7 } #2 #1 \c_eight { 8 } #2 #1 \c_nine { 9 } #2 #1 \c_ten { 10 } #2 #1 \c_eleven { 11 } #2 #1 \c_twelve { 12 } #2 #1 \c_thirteen { 13 } #2 #1 \c_fourteen { 14 } #2 #1 \c_fifteen { 15 } #2 #1 \c_sixteen { 16 } #2 #1 \c_thirty_two { 32 } #2 #1 \c_one_hundred { 100 } #2 #1 \c_two_hundred_fifty_five { 255 } #2 #1 \c_two_hundred_fifty_six { 256 } #2 #1 \c_one_thousand { 1000 } #2 #1 \c_ten_thousand { 10000 } #2 } \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 { \exp_after:wN \__kernel_deprecation_error:Nnn \exp_not:N } { { 2020-01-01 } } } { \@@_deprecated_constants:nn { \exp_after:wN \use:nnn \exp_after:wN \@@_constdef:Nw \exp_not:N } { \exp_stop_f: } } % \end{macrocode} % \end{macro} % \end{variable} % % \begin{macro}[deprecated = 2020-07-01]{\@@_value:w} % Made public. % \begin{macrocode} \cs_gset_eq:NN \@@_value:w \int_value:w % \end{macrocode} % \end{macro} % % \subsection{Deprecated \pkg{l3luatex} functions} % % \begin{macrocode} %<@@=lua> % \end{macrocode} % % \begin{macro}[EXP, deprecated = 2020-07-01]{\lua_now_x:n, \lua_escape_x:n} % \begin{macro}[deprecated = 2020-07-01]{\lua_shipout_x:n} % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_now:e } \cs_gset:Npn \lua_now_x:n #1 { \@@_now:n {#1} } \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_escape:e } \cs_gset:Npn \lua_escape_x:n #1 { \@@_escape:n {#1} } \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_shipout_e:n } \cs_gset_protected:Npn \lua_shipout_x:n #1 { \@@_shipout:n {#1} } % \end{macrocode} % \end{macro} % \end{macro} % % \subsection{Deprecated \pkg{l3msg} functions} % % \begin{macrocode} %<@@=msg> % \end{macrocode} % % \begin{macro}[deprecated = 2020-07-01]{\msg_log:n, \msg_term:n} % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \iow_log:n } \cs_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_gset_protected:Npn \msg_term:n #1 { \iow_term:n { ************************************************* } \iow_wrap:nnnN { * ~ #1} { * ~ } { } \iow_term:n \iow_term:n { ************************************************* } } % \end{macrocode} % \end{macro} % % \begin{macro}[deprecated = 2020-07-01]{\msg_interrupt:nnn} % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { [Defined~error~message] } \cs_gset_protected:Npn \msg_interrupt:nnn #1#2#3 { \tl_if_empty:nTF {#3} { \@@_old_interrupt_wrap:nn { \\ \c_@@_no_info_text_tl } {#1 \\\\ #2 \\\\ \c_@@_continue_text_tl } } { \@@_old_interrupt_wrap:nn { \\ #3 } {#1 \\\\ #2 \\\\ \c_@@_help_text_tl } } } \cs_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_gset_protected:Npn \@@_old_interrupt_more_text:n #1 { \exp_args:Nx \tex_errhelp:D { |''''''''''''''''''''''''''''''''''''''''''''''' #1 \iow_newline: |............................................... } } \group_begin: \char_set_lccode:nn {`\{} {`\ } \char_set_lccode:nn {`\}} {`\ } \char_set_lccode:nn {`\&} {`\!} \char_set_catcode_active:N \& \tex_lowercase:D { \group_end: \cs_gset_protected:Npn \@@_old_interrupt_text:n #1 { \iow_term:x { \iow_newline: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \iow_newline: ! } \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J } { \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 } { \group_begin: \cs_set_protected:Npn & { \tex_errmessage:D { #1 \use_none:n { ............................................ } } } \exp_after:wN \group_end: & } } } } % \end{macrocode} % \end{macro} % % \subsection{Deprecated \pkg{l3prg} functions} % % \begin{macrocode} %<@@=prg> % \end{macrocode} % % \begin{macro}[deprecated = 2020-07-01] % { % \@@_break_point:Nn, % \@@_break_point:, % \@@_map_break:Nn, % \@@_break:, % \@@_break:n % } % Made public, but used by a few third-parties. It's not possible to % perfectly support a mixture of \cs{@@_map_break:Nn} and % \cs{prg_map_break:Nn} because they use different delimiters. The % following code only breaks if someone tries to break from two % \enquote{old-style} \cs{@@_map_break:Nn} \ldots{} % \cs{@@_break_point:Nn} mappings in one go. Basically, the % \cs{@@_map_break:Nn} converts a single \cs{@@_break_point:Nn} to % \cs{prg_break_point:Nn}, and that delimiter had better be the right % one. Then we call \cs{prg_map_break:Nn} which may end up breaking % intermediate looks in the (unbraced) argument |#1|. It is essential % to define the |break_point| functions before the corresponding % |break| functions: otherwise \cs{debug_on:n} |{deprecation}| % \cs{debug_off:n} |{deprecation}| would break when trying to restore % the definitions because they would involve deprecated commands whose % definition has not yet been restored. % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break_point:Nn } \cs_gset:Npn \@@_break_point:Nn { \prg_break_point:Nn } \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break_point: } \cs_gset:Npn \@@_break_point: { \prg_break_point: } \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_map_break: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_gset:Npn \@@_break: #1 \@@_break_point: { } \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break:n } \cs_gset:Npn \@@_break:n #1#2 \@@_break_point: {#1} % \end{macrocode} % \end{macro} % % \subsection{Deprecated \pkg{l3str} functions} % % \begin{macro}[EXP, deprecated = 2022-07-01] % { % \str_lower_case:n, \str_lower_case:f, % \str_upper_case:n, \str_upper_case:f, % \str_fold_case:n, \str_fold_case:V % } % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \str_lowercase:n } \cs_gset:Npn \str_lower_case:n { \str_lowercase:n } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \str_lowercase:f } \cs_gset:Npn \str_lower_case:f { \str_lowercase:f } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \str_uppercase:n } \cs_gset:Npn \str_upper_case:n { \str_uppercase:n } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \str_uppercase:f } \cs_gset:Npn \str_upper_case:f { \str_uppercase:f } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \str_foldcase:n } \cs_gset:Npn \str_fold_case:n { \str_foldcase:n } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \str_foldcase:V } \cs_gset:Npn \str_fold_case:V { \str_foldcase:V } % \end{macrocode} % \end{macro} % % \begin{macro}[EXP, deprecated = 2020-07-01, noTF]{\str_case_x:nn} % \begin{macro}[EXP, deprecated = 2020-07-01, pTF]{\str_if_eq_x:nn} % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nn } \cs_gset:Npn \str_case_x:nn { \str_case_e:nn } \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \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_gset:Npn \str_case_x:nnF { \str_case_e:nnF } \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \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_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_gset:Npn \str_if_eq_x:nnT { \str_if_eq:eeT } \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \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_gset:Npn \str_if_eq_x:nnTF { \str_if_eq:eeTF } % \end{macrocode} % \end{macro} % \end{macro} % % \subsection{Deprecated \pkg{l3seq} functions} % % \begin{macro}[EXP, deprecated = 2023-01-01] % { % \seq_indexed_map_inline:Nn, \seq_indexed_map_function:NN % } % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2022-07-01 } { \seq_map_indexed_inline:Nn } \cs_gset:Npn \seq_indexed_map_inline:Nn { \seq_map_indexed_inline:Nn } \__kernel_patch_deprecation:nnNNpn { 2022-07-01 } { \seq_map_indexed_function:NN } \cs_gset:Npn \seq_indexed_map_function:NN { \seq_map_indexed_function:NN } % \end{macrocode} % \end{macro} % % \subsubsection{Deprecated \pkg{l3tl} functions} % % \begin{macrocode} %<@@=tl> % \end{macrocode} % % \begin{macro}[deprecated = 2021-07-01] % { % \tl_set_from_file:Nnn, \tl_set_from_file:cnn, % \tl_gset_from_file:Nnn, \tl_gset_from_file:cnn, % \tl_set_from_file_x:Nnn, \tl_set_from_file_x:cnn, % \tl_gset_from_file_x:Nnn, \tl_gset_from_file_x:cnn % } % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN } \cs_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_gset_protected:Npn \tl_gset_from_file:Nnn #1#2#3 { \group_begin: \file_get:nnN {#3} {#2} \l_@@_internal_a_tl \tl_gset_eq:NN #1 \l_@@_internal_a_tl \group_end: } \cs_generate_variant:Nn \tl_gset_from_file:Nnn { c } \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN } \cs_gset_protected:Npn \tl_set_from_file_x:Nnn #1#2#3 { \group_begin: \file_get:nnN {#3} {#2} \l_@@_internal_a_tl #2 \scan_stop: \tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl } \exp_args:NNNo \group_end: \tl_set:Nn #1 \l_@@_internal_a_tl } \cs_generate_variant:Nn \tl_set_from_file_x:Nnn { c } \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN } \cs_gset_protected:Npn \tl_gset_from_file_x:Nnn #1#2#3 { \group_begin: \file_get:nnN {#3} {#2} \l_@@_internal_a_tl #2 \scan_stop: \tl_gset:Nx #1 { \l_@@_internal_a_tl } \group_end: } \cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c } % \end{macrocode} % \end{macro} % % \begin{macro}[deprecated = 2022-07-01] % { % \tl_lower_case:n, \tl_lower_case:nn, % \tl_upper_case:n, \tl_upper_case:nn, % \tl_mixed_case:n, \tl_mixed_case:nn, % } % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_lowercase:n } \cs_gset:Npn \tl_lower_case:n #1 { \text_lowercase:n {#1} } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_lowercase:nn } \cs_gset:Npn \tl_lower_case:nn #1#2 { \text_lowercase:nn {#1} {#2} } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_uppercase:n } \cs_gset:Npn \tl_upper_case:n #1 { \text_uppercase:n {#1} } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_uppercase:nn } \cs_gset:Npn \tl_upper_case:nn #1#2 { \text_uppercase:nn {#1} {#2} } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_titlecase:n } \cs_gset:Npn \tl_mixed_case:n #1 { \text_titlecase:n {#1} } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_titlecase:nn } \cs_gset:Npn \tl_mixed_case:nn #1#2 { \text_titlecase:nn {#1} {#2} } % \end{macrocode} % \end{macro} % % \subsection{Deprecated \pkg{l3tl-analysis} functions} % % \begin{macro}[deprecated = 2020-07-01] % {\tl_show_analysis:N, \tl_show_analysis:n} % Simple renames. % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \tl_analysis_show:N } \cs_gset_protected:Npn \tl_show_analysis:N { \tl_analysis_show:N } \__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \tl_analysis_show:n } \cs_gset_protected:Npn \tl_show_analysis:n { \tl_analysis_show:n } % \end{macrocode} % \end{macro} % % \subsection{Deprecated \pkg{l3token} functions} % % \begin{macro}[EXP, deprecated = 2021-07-01] % { % \token_get_prefix_spec:N, % \token_get_arg_spec:N, % \token_get_replacement_spec:N % } % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_prefix_spec:N } \cs_gset:Npn \token_get_prefix_spec:N { \cs_prefix_spec:N } \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \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_gset:Npn \token_get_replacement_spec:N { \cs_replacement_spec:N } % \end{macrocode} % \end{macro} % % \begin{macro}[EXP, deprecated = 2022-07-01] % { % \char_lower_case:N, \char_upper_case:N, % \char_mixed_case:Nn, \char_fold_case:N, % \char_str_lower_case:N, \char_str_upper_case:N, % \char_str_mixed_case:Nn, \char_str_fold_case:N, % } % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \char_lowercase:N } \cs_gset:Npn \char_lower_case:N { \char_lowercase:N } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \char_uppercase:N } \cs_gset:Npn \char_upper_case:N { \char_uppercase:N } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \char_titlecase:N } \cs_gset:Npn \char_mixed_case:N { \char_titlecase:N } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \char_foldcase:N } \cs_gset:Npn \char_fold_case:N { \char_foldcase:N } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \char_str_lowercase:N } \cs_gset:Npn \char_str_lower_case:N { \char_str_lowercase:N } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \char_str_uppercase:N } \cs_gset:Npn \char_str_upper_case:N { \char_str_uppercase:N } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \char_str_titlecase:N } \cs_gset:Npn \char_str_mixed_case:N { \char_str_titlecase:N } \__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \char_str_foldcase:N } \cs_gset:Npn \char_str_fold_case:N { \char_str_foldcase:N } % \end{macrocode} % \end{macro} % % \subsection{Deprecated \pkg{l3file} functions} % % \begin{macro}[EXP, deprecated = 2021-07-01]{\c_term_ior} % \begin{macrocode} \__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { -1 } \cs_gset_protected:Npn \c_term_ior { -1 \scan_stop: } % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % % \PrintIndex