diff options
author | Norbert Preining <norbert@preining.info> | 2020-10-28 03:02:51 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2020-10-28 03:02:51 +0000 |
commit | 66f90f5ace150ea89b360d90788c6a3d63fa04f6 (patch) | |
tree | 0eb1a8688bb5221925d6c8c6027b9d3612f65028 /macros/latex/contrib/l3kernel | |
parent | 83aaf60600dc0b191bacbaacc786dbda33d7190a (diff) |
CTAN sync 202010280302
Diffstat (limited to 'macros/latex/contrib/l3kernel')
83 files changed, 1371 insertions, 642 deletions
diff --git a/macros/latex/contrib/l3kernel/CHANGELOG.md b/macros/latex/contrib/l3kernel/CHANGELOG.md index 3e416742d9..cfca3155d0 100644 --- a/macros/latex/contrib/l3kernel/CHANGELOG.md +++ b/macros/latex/contrib/l3kernel/CHANGELOG.md @@ -7,13 +7,26 @@ this project uses date-based 'snapshot' version identifiers. ## [Unreleased] +## [2020-10-27] + +### Added + +- `\token_if_font_selection:N(TF)` (see #806) + ### Fixed -- Correctly detect LaTeX when pre-loading expl3 and setting up - case changer +- Avoid relying on braced `\input` primitive syntax +- Correct expansion of environments in `\text_purify:n` +- Some aspects of `cctab` setup with 8-bit engines(issue #814) + +### Changed +- Improved performance for `tl` functions +- Extend case changer to cover all of Greek with pdfTeX ## [2020-10-05] ### Fixed +- Correctly detect LaTeX when pre-loading expl3 and setting up + case changer - Lua emulation of \strcmp (issue #813) ## [2020-09-24] @@ -780,7 +793,8 @@ this project uses date-based 'snapshot' version identifiers. - Step functions have been added for dim variables, e.g. `\dim_step_inline:nnnn` -[Unreleased]: https://github.com/latex3/latex3/compare/2020-10-05...HEAD +[Unreleased]: https://github.com/latex3/latex3/compare/2020-10-27...HEAD +[2020-10-27]: https://github.com/latex3/latex3/compare/2020-10-05...2020-10-27 [2020-10-05]: https://github.com/latex3/latex3/compare/2020-09-24...2020-10-05 [2020-09-24]: https://github.com/latex3/latex3/compare/2020-09-06...2020-09-24 [2020-09-06]: https://github.com/latex3/latex3/compare/2020-09-03...2020-09-06 diff --git a/macros/latex/contrib/l3kernel/README.md b/macros/latex/contrib/l3kernel/README.md index 8fabd3e167..2361e047a8 100644 --- a/macros/latex/contrib/l3kernel/README.md +++ b/macros/latex/contrib/l3kernel/README.md @@ -1,7 +1,7 @@ LaTeX3 Programming Conventions ============================== -Release 2020-10-05 +Release 2020-10-27 Overview -------- diff --git a/macros/latex/contrib/l3kernel/expl3.dtx b/macros/latex/contrib/l3kernel/expl3.dtx index c42fffb6b2..59b8cad3a7 100644 --- a/macros/latex/contrib/l3kernel/expl3.dtx +++ b/macros/latex/contrib/l3kernel/expl3.dtx @@ -24,7 +24,7 @@ % %<*driver|generic|package|2ekernel> %</driver|generic|package|2ekernel> -\def\ExplFileDate{2020-10-05}% +\def\ExplFileDate{2020-10-27}% %<*driver> \documentclass[full]{l3doc} \usepackage{graphicx} @@ -51,7 +51,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1242,7 +1242,7 @@ \else \expandafter\@gobble \fi - {\input{expl3-code.tex}}% + {\input expl3-code.tex }% % \end{macrocode} % % A check that the bootstrap code did not abort loading: if it did, diff --git a/macros/latex/contrib/l3kernel/expl3.pdf b/macros/latex/contrib/l3kernel/expl3.pdf Binary files differindex 9291487c4b..c249956331 100644 --- a/macros/latex/contrib/l3kernel/expl3.pdf +++ b/macros/latex/contrib/l3kernel/expl3.pdf diff --git a/macros/latex/contrib/l3kernel/interface3.pdf b/macros/latex/contrib/l3kernel/interface3.pdf Binary files differindex 36f3ab7387..b7b0dbf9a9 100644 --- a/macros/latex/contrib/l3kernel/interface3.pdf +++ b/macros/latex/contrib/l3kernel/interface3.pdf diff --git a/macros/latex/contrib/l3kernel/interface3.tex b/macros/latex/contrib/l3kernel/interface3.tex index 87fea02ba4..071ddd4bdf 100644 --- a/macros/latex/contrib/l3kernel/interface3.tex +++ b/macros/latex/contrib/l3kernel/interface3.tex @@ -54,7 +54,7 @@ for those people who are interested. {latex-team@latex-project.org}% }% } -\date{Released 2020-10-05} +\date{Released 2020-10-27} \pagenumbering{roman} \maketitle diff --git a/macros/latex/contrib/l3kernel/l3basics.dtx b/macros/latex/contrib/l3kernel/l3basics.dtx index 7f06398f70..e7f2c4fd63 100644 --- a/macros/latex/contrib/l3kernel/l3basics.dtx +++ b/macros/latex/contrib/l3kernel/l3basics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3bootstrap.dtx b/macros/latex/contrib/l3kernel/l3bootstrap.dtx index fd354ab438..eba03dca56 100644 --- a/macros/latex/contrib/l3kernel/l3bootstrap.dtx +++ b/macros/latex/contrib/l3kernel/l3bootstrap.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3box.dtx b/macros/latex/contrib/l3kernel/l3box.dtx index 5412fab14c..a866d6324b 100644 --- a/macros/latex/contrib/l3kernel/l3box.dtx +++ b/macros/latex/contrib/l3kernel/l3box.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3candidates.dtx b/macros/latex/contrib/l3kernel/l3candidates.dtx index dc33f6abca..17f7f33891 100644 --- a/macros/latex/contrib/l3kernel/l3candidates.dtx +++ b/macros/latex/contrib/l3kernel/l3candidates.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1115,9 +1115,9 @@ % hence in the \texttt{x}-expanding assignment. % \begin{macrocode} \cs_new_protected:Npn \seq_set_filter:NNn - { \@@_set_filter:NNNn \tl_set:Nx } + { \@@_set_filter:NNNn \__kernel_tl_set:Nx } \cs_new_protected:Npn \seq_gset_filter:NNn - { \@@_set_filter:NNNn \tl_gset:Nx } + { \@@_set_filter:NNNn \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_set_filter:NNNn #1#2#3#4 { \@@_push_item_def:n { \bool_if:nT {#4} { \@@_wrap_item:n {##1} } } @@ -1133,9 +1133,9 @@ % Set \cs{@@_item:n} then map it using the loop code. % \begin{macrocode} \cs_new_protected:Npn \seq_set_from_inline_x:Nnn - { \@@_set_from_inline_x:NNnn \tl_set:Nx } + { \@@_set_from_inline_x:NNnn \__kernel_tl_set:Nx } \cs_new_protected:Npn \seq_gset_from_inline_x:Nnn - { \@@_set_from_inline_x:NNnn \tl_gset:Nx } + { \@@_set_from_inline_x:NNnn \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_set_from_inline_x:NNnn #1#2#3#4 { \@@_push_item_def:n { \exp_not:N \@@_item:n {#4} } @@ -1438,7 +1438,7 @@ % trick to wrap all the \meta{right} parts together. % \begin{macrocode} \cs_new_protected:Npn \tl_build_get:NN - { \@@_build_get:NNN \tl_set:Nx } + { \@@_build_get:NNN \__kernel_tl_set:Nx } \cs_new_protected:Npn \@@_build_get:NNN #1#2#3 { #1 #3 { \if_false: { \fi: \exp_after:wN \@@_build_get:w #2 } } } \cs_new:Npn \@@_build_get:w #1 \@@_build_last:NNn #2#3#4 @@ -1463,12 +1463,12 @@ % \begin{macrocode} \cs_new_protected:Npn \tl_build_end:N #1 { - \@@_build_get:NNN \tl_set:Nx #1 #1 + \@@_build_get:NNN \__kernel_tl_set:Nx #1 #1 \exp_args:Nc \@@_build_end_loop:NN { \cs_to_str:N #1 ' } \tl_clear:N } \cs_new_protected:Npn \tl_build_gend:N #1 { - \@@_build_get:NNN \tl_gset:Nx #1 #1 + \@@_build_get:NNN \__kernel_tl_gset:Nx #1 #1 \exp_args:Nc \@@_build_end_loop:NN { \cs_to_str:N #1 ' } \tl_gclear:N } \cs_new_protected:Npn \@@_build_end_loop:NN #1#2 diff --git a/macros/latex/contrib/l3kernel/l3cctab.dtx b/macros/latex/contrib/l3kernel/l3cctab.dtx index 6807760193..6e57d4a1bf 100644 --- a/macros/latex/contrib/l3kernel/l3cctab.dtx +++ b/macros/latex/contrib/l3kernel/l3cctab.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -766,7 +766,7 @@ % \end{macrocode} % \end{variable} % -% \begin{variable}{\c_document_cctab, \c_other_cctab} +% \begin{variable}{\c_code_cctab, \c_document_cctab} % To pick up document-level category codes, we need to delay set up to the % end of the format, where that's possible. Also, as there are a \emph{lot} % of category codes to set, we avoid using the official interface and store the @@ -808,6 +808,9 @@ \char_set_catcode_group_end:n { 125 } % right brace \char_set_catcode_space:n { 126 } % tilde \char_set_catcode_invalid:n { 127 } % ^^? + \bool_lazy_or:nnF + { \sys_if_engine_xetex_p: } { \sys_if_engine_luatex_p: } + { \int_step_function:nnN { 128 } { 255 } \char_set_catcode_active:n } \@@_gset:n { \c_code_cctab } \group_end: \cctab_const:Nn \c_document_cctab diff --git a/macros/latex/contrib/l3kernel/l3clist.dtx b/macros/latex/contrib/l3kernel/l3clist.dtx index 622966bffb..779062a3cf 100644 --- a/macros/latex/contrib/l3kernel/l3clist.dtx +++ b/macros/latex/contrib/l3kernel/l3clist.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1026,9 +1026,9 @@ % in the case of an empty comma-list. % \begin{macrocode} \cs_new_protected:Npn \clist_set_from_seq:NN - { \@@_set_from_seq:NNNN \clist_clear:N \tl_set:Nx } + { \@@_set_from_seq:NNNN \clist_clear:N \__kernel_tl_set:Nx } \cs_new_protected:Npn \clist_gset_from_seq:NN - { \@@_set_from_seq:NNNN \clist_gclear:N \tl_gset:Nx } + { \@@_set_from_seq:NNNN \clist_gclear:N \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_set_from_seq:NNNN #1#2#3#4 { \seq_if_empty:NTF #4 @@ -1067,9 +1067,9 @@ % a little work to do. % \begin{macrocode} \cs_new_protected:Npn \clist_concat:NNN - { \@@_concat:NNNN \tl_set:Nx } + { \@@_concat:NNNN \__kernel_tl_set:Nx } \cs_new_protected:Npn \clist_gconcat:NNN - { \@@_concat:NNNN \tl_gset:Nx } + { \@@_concat:NNNN \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_concat:NNNN #1#2#3#4 { #1 #2 @@ -1114,9 +1114,9 @@ % } % \begin{macrocode} \cs_new_protected:Npn \clist_set:Nn #1#2 - { \tl_set:Nx #1 { \@@_sanitize:n {#2} } } + { \__kernel_tl_set:Nx #1 { \@@_sanitize:n {#2} } } \cs_new_protected:Npn \clist_gset:Nn #1#2 - { \tl_gset:Nx #1 { \@@_sanitize:n {#2} } } + { \__kernel_tl_gset:Nx #1 { \@@_sanitize:n {#2} } } \cs_generate_variant:Nn \clist_set:Nn { NV , No , Nx , c , cV , co , cx } \cs_generate_variant:Nn \clist_gset:Nn { NV , No , Nx , c , cV , co , cx } % \end{macrocode} @@ -1240,9 +1240,9 @@ % result can safely be an empty comma list. % \begin{macrocode} \cs_new_protected:Npn \clist_pop:NN - { \@@_pop:NNN \tl_set:Nx } + { \@@_pop:NNN \__kernel_tl_set:Nx } \cs_new_protected:Npn \clist_gpop:NN - { \@@_pop:NNN \tl_gset:Nx } + { \@@_pop:NNN \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_pop:NNN #1#2#3 { \if_meaning:w #2 \c_empty_clist @@ -1287,9 +1287,9 @@ } \prg_generate_conditional_variant:Nnn \clist_get:NN { c } { T , F , TF } \prg_new_protected_conditional:Npnn \clist_pop:NN #1#2 { T , F , TF } - { \@@_pop_TF:NNN \tl_set:Nx #1 #2 } + { \@@_pop_TF:NNN \__kernel_tl_set:Nx #1 #2 } \prg_new_protected_conditional:Npnn \clist_gpop:NN #1#2 { T , F , TF } - { \@@_pop_TF:NNN \tl_gset:Nx #1 #2 } + { \@@_pop_TF:NNN \__kernel_tl_gset:Nx #1 #2 } \cs_new_protected:Npn \@@_pop_TF:NNN #1#2#3 { \if_meaning:w #2 \c_empty_clist @@ -1416,9 +1416,9 @@ % the second step removes it. % \begin{macrocode} \cs_new_protected:Npn \clist_remove_all:Nn - { \@@_remove_all:NNNn \clist_set_from_seq:NN \tl_set:Nx } + { \@@_remove_all:NNNn \clist_set_from_seq:NN \__kernel_tl_set:Nx } \cs_new_protected:Npn \clist_gremove_all:Nn - { \@@_remove_all:NNNn \clist_gset_from_seq:NN \tl_gset:Nx } + { \@@_remove_all:NNNn \clist_gset_from_seq:NN \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_remove_all:NNNn #1#2#3#4 { \@@_if_wrap:nTF {#4} @@ -1472,9 +1472,9 @@ % \texttt{N}-type comma lists, but the slow-down is not too bad. % \begin{macrocode} \cs_new_protected:Npn \clist_reverse:N #1 - { \tl_set:Nx #1 { \exp_args:No \clist_reverse:n {#1} } } + { \__kernel_tl_set:Nx #1 { \exp_args:No \clist_reverse:n {#1} } } \cs_new_protected:Npn \clist_greverse:N #1 - { \tl_gset:Nx #1 { \exp_args:No \clist_reverse:n {#1} } } + { \__kernel_tl_gset:Nx #1 { \exp_args:No \clist_reverse:n {#1} } } \cs_generate_variant:Nn \clist_reverse:N { c } \cs_generate_variant:Nn \clist_greverse:N { c } % \end{macrocode} diff --git a/macros/latex/contrib/l3kernel/l3coffins.dtx b/macros/latex/contrib/l3kernel/l3coffins.dtx index a69d7b25e3..0c0c3c776c 100644 --- a/macros/latex/contrib/l3kernel/l3coffins.dtx +++ b/macros/latex/contrib/l3kernel/l3coffins.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -2240,7 +2240,7 @@ { \AtBeginDocument } { \use:n } { - \tl_set:Nx \l_@@_display_font_tl + \__kernel_tl_set:Nx \l_@@_display_font_tl { \cs_if_exist:NT \sffamily { \exp_not:N \sffamily } \cs_if_exist:NT \tiny { \exp_not:N \tiny } diff --git a/macros/latex/contrib/l3kernel/l3color-base.dtx b/macros/latex/contrib/l3kernel/l3color-base.dtx index fd517b1e2e..1d88e3d6ff 100644 --- a/macros/latex/contrib/l3kernel/l3color-base.dtx +++ b/macros/latex/contrib/l3kernel/l3color-base.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3debug.dtx b/macros/latex/contrib/l3kernel/l3debug.dtx index 1b98b61667..30f0f78b5e 100644 --- a/macros/latex/contrib/l3kernel/l3debug.dtx +++ b/macros/latex/contrib/l3kernel/l3debug.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -220,7 +220,7 @@ } \cs_set_protected:Npn \debug_resume: { - \tl_set:Nx \l_@@_suspended_tl + \__kernel_tl_set:Nx \l_@@_suspended_tl { \tl_tail:N \l_@@_suspended_tl } \tl_if_empty:NT \l_@@_suspended_tl { @@ -510,11 +510,11 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_generate_parameter_list:NNN #1#2#3 { - \tl_set:Nx \l_@@_internal_tl + \__kernel_tl_set:Nx \l_@@_internal_tl { \exp_last_unbraced:Nf \use_ii:nnn \cs_split_function:N #1 } - \tl_set:Nx #2 + \__kernel_tl_set:Nx #2 { \exp_args:NV \@@_build_parm_text:n \l_@@_internal_tl } - \tl_set:Nx #3 + \__kernel_tl_set:Nx #3 { \exp_args:NV \@@_build_arg_list:n \l_@@_internal_tl } } \cs_new:Npn \@@_build_parm_text:n #1 @@ -788,6 +788,12 @@ % \tracingnone % \end{macrocode} % +% +% \begin{macrocode} +\cs_gset_protected:Npn \__kernel_tl_set:Nx { \cs_set_nopar:Npx } +\cs_gset_protected:Npn \__kernel_tl_gset:Nx { \cs_gset_nopar:Npx } +% \end{macrocode} +% % Patching where the first argument to a function needs scope-checking: % either local or global (so two lists). % \begin{macrocode} @@ -831,9 +837,7 @@ \skip_set_eq:NN \skip_add:Nn \skip_sub:Nn - \tl_set:Nn - \tl_set:No - \tl_set:Nx + \__kernel_tl_set:Nx \tl_set_eq:NN \tl_put_left:Nn \tl_put_left:NV @@ -895,9 +899,7 @@ \skip_gset_eq:NN \skip_gadd:Nn \skip_gsub:Nn - \tl_gset:Nn - \tl_gset:No - \tl_gset:Nx + \__kernel_tl_gset:Nx \tl_gset_eq:NN \tl_gput_left:Nn \tl_gput_left:NV @@ -1053,7 +1055,7 @@ { \@@_trace_push:nnN { regex } { 1 } \@@_escape_use:nnnn \group_begin: - \tl_set:Nx \l_@@_internal_a_tl + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \@@_trace_pop:nnN { regex } { 1 } \@@_escape_use:nnnn } \use_none:nnn } diff --git a/macros/latex/contrib/l3kernel/l3deprecation.dtx b/macros/latex/contrib/l3kernel/l3deprecation.dtx index c7c4d91c44..6d13ae1b38 100644 --- a/macros/latex/contrib/l3kernel/l3deprecation.dtx +++ b/macros/latex/contrib/l3kernel/l3deprecation.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -747,7 +747,7 @@ \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 } + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl } \exp_args:NNNo \group_end: \tl_set:Nn #1 \l_@@_internal_a_tl } @@ -758,7 +758,7 @@ \group_begin: \file_get:nnN {#3} {#2} \l_@@_internal_a_tl #2 \scan_stop: - \tl_gset:Nx #1 { \l_@@_internal_a_tl } + \__kernel_tl_gset:Nx #1 { \l_@@_internal_a_tl } \group_end: } \cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c } diff --git a/macros/latex/contrib/l3kernel/l3doc.dtx b/macros/latex/contrib/l3kernel/l3doc.dtx index 0a4b2c4550..25ad20f7dd 100644 --- a/macros/latex/contrib/l3kernel/l3doc.dtx +++ b/macros/latex/contrib/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 2020-10-05} +% \date{Released 2020-10-27} % \maketitle % \tableofcontents % @@ -1008,7 +1008,7 @@ and all files in that bundle must be distributed together. \cs_new_protected:Npn \@@_trim_right:Nn #1#2 { \cs_set:Npn \@@_tmp:w ##1 #2 ##2 \q_stop { \exp_not:n {##1} } - \tl_set:Nx #1 { \exp_after:wN \@@_tmp:w #1 #2 \q_stop } + \__kernel_tl_set:Nx #1 { \exp_after:wN \@@_tmp:w #1 #2 \q_stop } } \cs_generate_variant:Nn \@@_trim_right:Nn { No } % \end{macrocode} @@ -1228,14 +1228,14 @@ and all files in that bundle must be distributed together. \@@_if_almost_str:nTF {#1} { \@@_key_get_base_TF:nN {#1} \l_@@_tmpa_tl - \tl_set:Nx #2 + \__kernel_tl_set:Nx #2 { \@@_split_function_do:on \l_@@_tmpa_tl { \@@_base_form_aux:nnN } } } { \tl_set:Nn #2 {#1} } } \cs_new:Npx \@@_key_get_base_TF:nN #1#2 { - \tl_set:Nx #2 { \exp_not:N \tl_to_str:n {#1} } + \__kernel_tl_set:Nx #2 { \exp_not:N \tl_to_str:n {#1} } \tl_if_in:NoF #2 { \tl_to_str:n {:} } { \exp_not:N \prg_break: } \tl_if_in:onT { #2 z } { \tl_to_str:n {TF} z } @@ -1992,7 +1992,7 @@ and all files in that bundle must be distributed together. \verbatim@font \@@_if_almost_str:VT \l_@@_cmd_tl { - \tl_set:Nx \l_@@_cmd_tl { \tl_to_str:N \l_@@_cmd_tl } + \__kernel_tl_set:Nx \l_@@_cmd_tl { \tl_to_str:N \l_@@_cmd_tl } \bool_if:NT \g_@@_cs_break_bool { \regex_replace_all:nnN @@ -2012,14 +2012,14 @@ and all files in that bundle must be distributed together. { \quark_if_no_value:NF \l_@@_cmd_index_tl { - \tl_set:Nx \l_@@_cmd_tl + \__kernel_tl_set:Nx \l_@@_cmd_tl { \c_backslash_str \exp_not:o { \l_@@_cmd_index_tl } } } \exp_args:No \@@_key_get:n { \l_@@_cmd_tl } \quark_if_no_value:NF \l_@@_cmd_module_tl { - \tl_set:Nx \l_@@_index_module_tl + \__kernel_tl_set:Nx \l_@@_index_module_tl { \tl_to_str:N \l_@@_cmd_module_tl } } \@@_special_index_module:ooonN @@ -2134,7 +2134,7 @@ and all files in that bundle must be distributed together. % \begin{macrocode} \cs_new_protected:Npn \@@_get_hyper_target:nN #1#2 { - \tl_set:Nx #2 { \tl_to_str:n {#1} } + \__kernel_tl_set:Nx #2 { \tl_to_str:n {#1} } \tl_replace_all:Nxn #2 { \c_underscore_str } { / } \tl_remove_all:Nx #2 { \c_backslash_str } \tl_put_left:Nn #2 { doc/function// } @@ -2157,7 +2157,7 @@ and all files in that bundle must be distributed together. % \begin{macrocode} \cs_new_protected:Npn \@@_names_get_seq:nN #1#2 { - \tl_set:Nx \l_@@_tmpa_tl { \tl_to_str:n {#1} } + \__kernel_tl_set:Nx \l_@@_tmpa_tl { \tl_to_str:n {#1} } \bool_if:NTF \l_@@_names_verb_bool { \seq_clear:N #2 @@ -3045,7 +3045,7 @@ and all files in that bundle must be distributed together. \l_@@_macro_do_not_index_tl \exp_args:NNV \seq_set_from_clist:Nn \l_@@_tmpa_seq \l_@@_macro_do_not_index_tl - \tl_set:Nx \l_@@_macro_do_not_index_tl + \__kernel_tl_set:Nx \l_@@_macro_do_not_index_tl { \seq_use:Nn \l_@@_tmpa_seq { , } } \exp_args:NV \DoNotIndex \l_@@_macro_do_not_index_tl } @@ -4228,7 +4228,7 @@ and all files in that bundle must be distributed together. % \begin{macrocode} \cs_new_protected:Npn \@@_special_index_set:Nn #1#2 { - \tl_set:Nx #1 { \tl_to_str:n {#2} } + \__kernel_tl_set:Nx #1 { \tl_to_str:n {#2} } \@@_if_almost_str:nTF {#2} { \tl_replace_all:Non #1 { \tl_to_str:n { __ } } @@ -4246,7 +4246,7 @@ and all files in that bundle must be distributed together. \token_to_str:N \verb * \verbatimchar } } - \tl_set:Nx #1 + \__kernel_tl_set:Nx #1 { \token_to_str:N \verb * \verbatimchar #1 \verbatimchar @@ -4297,7 +4297,7 @@ and all files in that bundle must be distributed together. \cs_new_protected:Npn \@@_key_get:n #1 { \@@_key_get_base:nN {#1} \l_@@_index_macro_tl - \tl_set:Nx \l_@@_index_key_tl + \__kernel_tl_set:Nx \l_@@_index_key_tl { \tl_to_str:N \l_@@_index_macro_tl } \tl_clear:N \l_@@_index_module_tl \tl_if_in:NoTF \l_@@_index_key_tl { \tl_to_str:n { __ } } @@ -4320,7 +4320,7 @@ and all files in that bundle must be distributed together. } \cs_new_protected:Npn \@@_key_pop: { - \tl_set:Nx \l_@@_index_key_tl + \__kernel_tl_set:Nx \l_@@_index_key_tl { \tl_tail:N \l_@@_index_key_tl } } % \end{macrocode} @@ -4335,7 +4335,7 @@ and all files in that bundle must be distributed together. { \cs_set:Npn \@@_tmpa:w ##1 #1 ##2 \q_stop { \exp_not:n {##1} } - \tl_set:Nx \l_@@_index_module_tl + \__kernel_tl_set:Nx \l_@@_index_module_tl { \exp_after:wN \@@_tmpa:w \l_@@_index_module_tl #1 \q_stop } } \cs_new_protected:Npn \@@_key_drop_underscores: @@ -4396,7 +4396,7 @@ and all files in that bundle must be distributed together. { \seq_set_split:NoV \l_@@_tmpa_seq { \token_to_str:N _ } \l_@@_index_key_tl - \tl_set:Nx \l_@@_index_module_tl + \__kernel_tl_set:Nx \l_@@_index_module_tl { \int_case:nnF { \seq_count:N \l_@@_tmpa_seq } { diff --git a/macros/latex/contrib/l3kernel/l3docstrip.dtx b/macros/latex/contrib/l3kernel/l3docstrip.dtx index c68ad1c17b..2e455845db 100644 --- a/macros/latex/contrib/l3kernel/l3docstrip.dtx +++ b/macros/latex/contrib/l3kernel/l3docstrip.dtx @@ -63,7 +63,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3docstrip.pdf b/macros/latex/contrib/l3kernel/l3docstrip.pdf Binary files differindex 55a73b9176..9a63be0ebe 100644 --- a/macros/latex/contrib/l3kernel/l3docstrip.pdf +++ b/macros/latex/contrib/l3kernel/l3docstrip.pdf diff --git a/macros/latex/contrib/l3kernel/l3expan.dtx b/macros/latex/contrib/l3kernel/l3expan.dtx index 2d950678a8..49fafac296 100644 --- a/macros/latex/contrib/l3kernel/l3expan.dtx +++ b/macros/latex/contrib/l3kernel/l3expan.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3file.dtx b/macros/latex/contrib/l3kernel/l3file.dtx index 844e4c8fca..fc6f7260a0 100644 --- a/macros/latex/contrib/l3kernel/l3file.dtx +++ b/macros/latex/contrib/l3kernel/l3file.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1074,7 +1074,7 @@ { \@@_open_stream:Nn #1 {#2} } { \@@_new:N #1 - \tl_set:Nx \l_@@_stream_tl { \int_eval:n {#1} } + \__kernel_tl_set:Nx \l_@@_stream_tl { \int_eval:n {#1} } \@@_open_stream:Nn #1 {#2} } } @@ -1475,14 +1475,14 @@ % \begin{macrocode} \cs_new_protected:Npn \iow_open:Nn #1#2 { - \tl_set:Nx \l_@@_file_name_tl + \__kernel_tl_set:Nx \l_@@_file_name_tl { \__kernel_file_name_sanitize:n {#2} } \iow_close:N #1 \seq_gpop:NNTF \g_@@_streams_seq \l_@@_stream_tl { \@@_open_stream:NV #1 \l_@@_file_name_tl } { \@@_new:N #1 - \tl_set:Nx \l_@@_stream_tl { \int_eval:n {#1} } + \__kernel_tl_set:Nx \l_@@_stream_tl { \int_eval:n {#1} } \@@_open_stream:NV #1 \l_@@_file_name_tl } } @@ -1684,7 +1684,7 @@ \cs_new:Npn \@@_unindent:w { } \cs_new_protected:Npn \@@_set_indent:n #1 { - \tl_set:Nx \l_@@_one_indent_tl + \__kernel_tl_set:Nx \l_@@_one_indent_tl { \exp_args:No \__kernel_str_to_other_fast:n { \tl_to_str:n {#1} } } \int_set:Nn \l_@@_one_indent_int { \str_count:N \l_@@_one_indent_tl } @@ -1861,7 +1861,7 @@ % \cs{iow_wrap:nnnN}. % \begin{macrocode} \cs_set_eq:NN \protect \token_to_str:N - \tl_set:Nx \l_@@_wrap_tl {#1} + \__kernel_tl_set:Nx \l_@@_wrap_tl {#1} \cs_set_eq:NN \iow_allow_break: \@@_allow_break_error: \cs_set_eq:NN \iow_indent:n \@@_indent_error:n % \end{macrocode} @@ -1869,8 +1869,8 @@ % then convert to a string) and initialize the target count for lines % (the first line has target count \cs{l_iow_line_count_int} instead). % \begin{macrocode} - \tl_set:Nx \l_@@_newline_tl { \iow_newline: #2 } - \tl_set:Nx \l_@@_newline_tl { \tl_to_str:N \l_@@_newline_tl } + \__kernel_tl_set:Nx \l_@@_newline_tl { \iow_newline: #2 } + \__kernel_tl_set:Nx \l_@@_newline_tl { \tl_to_str:N \l_@@_newline_tl } \int_set:Nn \l_@@_line_target_int { \l_iow_line_count_int - \str_count:N \l_@@_newline_tl + 1 } % \end{macrocode} @@ -1910,12 +1910,12 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_wrap_do: { - \tl_set:Nx \l_@@_wrap_tl + \__kernel_tl_set:Nx \l_@@_wrap_tl { \exp_args:No \__kernel_str_to_other_fast:n \l_@@_wrap_tl \c_@@_wrap_end_marker_tl } - \tl_set:Nx \l_@@_wrap_tl + \__kernel_tl_set:Nx \l_@@_wrap_tl { \exp_after:wN \@@_wrap_fix_newline:w \l_@@_wrap_tl ^^J \q_@@_nil ^^J \s_@@_stop @@ -2179,7 +2179,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_wrap_allow_break:n #1 { - \tl_set:Nx \l_@@_line_tl + \__kernel_tl_set:Nx \l_@@_line_tl { \l_@@_line_tl \@@_wrap_trim:N \l_@@_line_part_tl } \bool_set_false:N \l_@@_line_break_bool \tl_if_empty:NTF \l_@@_line_part_tl @@ -2210,7 +2210,7 @@ \tl_put_right:Nx \l_@@_line_tl { \l_@@_line_part_tl } \bool_set_false:N \l_@@_line_break_bool \int_sub:Nn \l_@@_indent_int { \l_@@_one_indent_int } - \tl_set:Nx \l_@@_indent_tl + \__kernel_tl_set:Nx \l_@@_indent_tl { \exp_after:wN \@@_unindent:w \l_@@_indent_tl } \@@_wrap_chunk:nw {#1} } @@ -2249,9 +2249,9 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_wrap_store_do:n #1 { - \tl_set:Nx \l_@@_line_tl + \__kernel_tl_set:Nx \l_@@_line_tl { \l_@@_line_tl \l_@@_line_part_tl } - \tl_set:Nx \l_@@_wrap_tl + \__kernel_tl_set:Nx \l_@@_wrap_tl { \l_@@_wrap_tl \l_@@_newline_tl @@ -2785,7 +2785,7 @@ \cs_generate_variant:Nn \file_get_full_name:nN { V } \prg_new_protected_conditional:Npnn \file_get_full_name:nN #1#2 { T , F , TF } { - \tl_set:Nx #2 + \__kernel_tl_set:Nx #2 { \file_full_name:n {#1} } \tl_if_empty:NTF #2 { \prg_return_false: } @@ -2810,7 +2810,7 @@ { \prg_set_protected_conditional:Npnn \file_get_full_name:nN #1#2 { T , F , TF } { - \tl_set:Nx \l_@@_base_name_tl + \__kernel_tl_set:Nx \l_@@_base_name_tl { \__kernel_file_name_sanitize:n {#1} } \@@_get_full_name_search:nN { } \use:n \seq_map_inline:Nn \l_file_search_path_seq @@ -2845,7 +2845,7 @@ } \cs_new_protected:Npn \@@_get_full_name_search:nN #1#2 { - \tl_set:Nx \l_@@_full_name_tl + \__kernel_tl_set:Nx \l_@@_full_name_tl { \tl_to_str:n {#1} \l_@@_base_name_tl } \__kernel_ior_open:No \g_@@_internal_ior \l_@@_full_name_tl \ior_if_eof:NF \g_@@_internal_ior { #2 { \prg_break: } } @@ -3000,7 +3000,7 @@ { \@@_get_details:nnN {#1} { timestamp } #2 } \cs_new_protected:Npn \@@_get_details:nnN #1#2#3 { - \tl_set:Nx #3 + \__kernel_tl_set:Nx #3 { \use:c { file_ #2 :n } {#1} } \tl_if_empty:NTF #3 { \prg_return_false: } @@ -3045,7 +3045,7 @@ \prg_new_protected_conditional:Npnn \file_get_hex_dump:nnnN #1#2#3#4 { T , F , TF } { - \tl_set:Nx #4 + \__kernel_tl_set:Nx #4 { \file_hex_dump:nnn {#1} {#2} {#3} } \tl_if_empty:NTF #4 { \prg_return_false: } diff --git a/macros/latex/contrib/l3kernel/l3flag.dtx b/macros/latex/contrib/l3kernel/l3flag.dtx index 5e4e998873..2475241f91 100644 --- a/macros/latex/contrib/l3kernel/l3flag.dtx +++ b/macros/latex/contrib/l3kernel/l3flag.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-assign.dtx b/macros/latex/contrib/l3kernel/l3fp-assign.dtx index e6360615a8..918c7b9941 100644 --- a/macros/latex/contrib/l3kernel/l3fp-assign.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-assign.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % \maketitle % % \begin{documentation} @@ -80,9 +80,9 @@ % assignments. % \begin{macrocode} \cs_new_protected:Npn \fp_set:Nn #1#2 - { \tl_set:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } } + { \__kernel_tl_set:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } } \cs_new_protected:Npn \fp_gset:Nn #1#2 - { \tl_gset:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } } + { \__kernel_tl_gset:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } } \cs_new_protected:Npn \fp_const:Nn #1#2 { \tl_const:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } } \cs_generate_variant:Nn \fp_set:Nn {c} diff --git a/macros/latex/contrib/l3kernel/l3fp-aux.dtx b/macros/latex/contrib/l3kernel/l3fp-aux.dtx index 103b75417c..60662e3560 100644 --- a/macros/latex/contrib/l3kernel/l3fp-aux.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-aux.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-basics.dtx b/macros/latex/contrib/l3kernel/l3fp-basics.dtx index 1dbebe5909..4fa89b6355 100644 --- a/macros/latex/contrib/l3kernel/l3fp-basics.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-basics.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-convert.dtx b/macros/latex/contrib/l3kernel/l3fp-convert.dtx index 5532e1e857..1b28754a82 100644 --- a/macros/latex/contrib/l3kernel/l3fp-convert.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-convert.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-expo.dtx b/macros/latex/contrib/l3kernel/l3fp-expo.dtx index 8581913752..b30fd883bd 100644 --- a/macros/latex/contrib/l3kernel/l3fp-expo.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-expo.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-extended.dtx b/macros/latex/contrib/l3kernel/l3fp-extended.dtx index 571d9b8d9c..2ff5305b4c 100644 --- a/macros/latex/contrib/l3kernel/l3fp-extended.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-extended.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-logic.dtx b/macros/latex/contrib/l3kernel/l3fp-logic.dtx index d879f37c4c..28ed6bba76 100644 --- a/macros/latex/contrib/l3kernel/l3fp-logic.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-logic.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-parse.dtx b/macros/latex/contrib/l3kernel/l3fp-parse.dtx index eec6d0e6fc..894cf439d9 100644 --- a/macros/latex/contrib/l3kernel/l3fp-parse.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-parse.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-random.dtx b/macros/latex/contrib/l3kernel/l3fp-random.dtx index 0fd6de01af..e8682c57a8 100644 --- a/macros/latex/contrib/l3kernel/l3fp-random.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-random.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-round.dtx b/macros/latex/contrib/l3kernel/l3fp-round.dtx index d2bb632e59..03de976829 100644 --- a/macros/latex/contrib/l3kernel/l3fp-round.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-round.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-traps.dtx b/macros/latex/contrib/l3kernel/l3fp-traps.dtx index 1f297f069a..377596fb59 100644 --- a/macros/latex/contrib/l3kernel/l3fp-traps.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-traps.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % \maketitle % % \begin{documentation} diff --git a/macros/latex/contrib/l3kernel/l3fp-trig.dtx b/macros/latex/contrib/l3kernel/l3fp-trig.dtx index 3cea7ebdb6..eefc4c7ccb 100644 --- a/macros/latex/contrib/l3kernel/l3fp-trig.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-trig.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp.dtx b/macros/latex/contrib/l3kernel/l3fp.dtx index 34d87040f0..51f1a30c18 100644 --- a/macros/latex/contrib/l3kernel/l3fp.dtx +++ b/macros/latex/contrib/l3kernel/l3fp.dtx @@ -49,7 +49,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1364,7 +1364,7 @@ % % \begin{variable}[tested = m3fp-parse001] % {em, ex, in, pt, pc, cm, mm, dd, cc, nd, nc, bp, sp} -% \newcommand{\unit}[1]{\text{\texttt{#1}}} +% \newcommand{\unit}[1]{\ifmmode\,\fi\text{\texttt{#1}}} % Those units of measurement are equal to their values in \unit{pt}, % namely % \begin{align*} @@ -1378,7 +1378,7 @@ % 1 \unit{nd} & = 0.375 \unit{mm} = 1.066978346456693 \unit{pt} \\ % 1 \unit{nc} & = 12 \unit{nd} = 12.80374015748031 \unit{pt} \\ % 1 \unit{bp} & = \frac{1}{72} \unit{in} = 1.00375 \unit{pt} \\ -% 1 \unit{sp} & = 2^{-16} \unit{pt} = 1.52587890625e-5 \unit{pt}. +% 1 \unit{sp} & = 2^{-16} \unit{pt} = 1.52587890625 \times 10^{-5} \unit{pt}. % \end{align*} % The values of the (font-dependent) units \unit{em} and \unit{ex} are % gathered from \TeX{} when the surrounding floating point expression diff --git a/macros/latex/contrib/l3kernel/l3fparray.dtx b/macros/latex/contrib/l3kernel/l3fparray.dtx index 4a521269bb..5d48154ae8 100644 --- a/macros/latex/contrib/l3kernel/l3fparray.dtx +++ b/macros/latex/contrib/l3kernel/l3fparray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3int.dtx b/macros/latex/contrib/l3kernel/l3int.dtx index b4624576be..f246d8400b 100644 --- a/macros/latex/contrib/l3kernel/l3int.dtx +++ b/macros/latex/contrib/l3kernel/l3int.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3intarray.dtx b/macros/latex/contrib/l3kernel/l3intarray.dtx index 022e084f53..7c9d2372d9 100644 --- a/macros/latex/contrib/l3kernel/l3intarray.dtx +++ b/macros/latex/contrib/l3kernel/l3intarray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3kernel-functions.dtx b/macros/latex/contrib/l3kernel/l3kernel-functions.dtx index 81c9ca1e05..b844c89385 100644 --- a/macros/latex/contrib/l3kernel/l3kernel-functions.dtx +++ b/macros/latex/contrib/l3kernel/l3kernel-functions.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -569,6 +569,15 @@ % only a single expansion. % \end{function} % +% \begin{function}{\__kernel_tl_set:Nx, \__kernel_tl_gset:Nx} +% \begin{syntax} +% \cs{__kernel_tl_set:Nx} \meta{tl~var} \Arg{tokens} +% \end{syntax} +% Fully expands \meta{tokens} and assigns the result to \meta{tl~var}. +% \meta{tokens} must be given in braces and there must be no token between +% \meta{tl~var} and \meta{tokens}. +% \end{function} +% % \section{Kernel backend functions} % % These functions are required to pass information to the backend. The nature diff --git a/macros/latex/contrib/l3kernel/l3keys.dtx b/macros/latex/contrib/l3kernel/l3keys.dtx index f512bd2517..ea9b1f9d04 100644 --- a/macros/latex/contrib/l3kernel/l3keys.dtx +++ b/macros/latex/contrib/l3kernel/l3keys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -2445,7 +2445,7 @@ { \clist_clear:N \l_@@_unused_clist \@@_set_known:nnn {#2} {#3} {#4} - \tl_set:Nx #5 { \exp_not:o \l_@@_unused_clist } + \__kernel_tl_set:Nx #5 { \exp_not:o \l_@@_unused_clist } \tl_set:Nn \l_@@_unused_clist {#1} } \cs_new_protected:Npn \keys_set_known:nn #1#2 @@ -2523,7 +2523,7 @@ { \clist_clear:N \l_@@_unused_clist \@@_set_filter:nnnn {#2} {#3} {#4} {#5} - \tl_set:Nx #6 { \exp_not:o \l_@@_unused_clist } + \__kernel_tl_set:Nx #6 { \exp_not:o \l_@@_unused_clist } \tl_set:Nn \l_@@_unused_clist {#1} } \cs_new_protected:Npn \keys_set_filter:nnn #1#2#3 @@ -2622,7 +2622,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_set_keyval:nnn #1#2#3 { - \tl_set:Nx \l_keys_path_str + \__kernel_tl_set:Nx \l_keys_path_str { \tl_if_blank:nF {#1} { #1 / } @@ -2887,7 +2887,7 @@ } \cs_new_protected:Npn \@@_store_unused_aux: { - \tl_set:Nx \l_@@_relative_tl + \__kernel_tl_set:Nx \l_@@_relative_tl { \exp_args:No \@@_trim_spaces:n \l_@@_relative_tl } \use:x { diff --git a/macros/latex/contrib/l3kernel/l3legacy.dtx b/macros/latex/contrib/l3kernel/l3legacy.dtx index 872d9b5aa4..041c39c333 100644 --- a/macros/latex/contrib/l3kernel/l3legacy.dtx +++ b/macros/latex/contrib/l3kernel/l3legacy.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3luatex.dtx b/macros/latex/contrib/l3kernel/l3luatex.dtx index 60fd7e22fb..880eb79f9e 100644 --- a/macros/latex/contrib/l3kernel/l3luatex.dtx +++ b/macros/latex/contrib/l3kernel/l3luatex.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3msg.dtx b/macros/latex/contrib/l3kernel/l3msg.dtx index 7e2c59a712..cde386e371 100644 --- a/macros/latex/contrib/l3kernel/l3msg.dtx +++ b/macros/latex/contrib/l3kernel/l3msg.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3names.dtx b/macros/latex/contrib/l3kernel/l3names.dtx index 0a4fe07d50..b75c20eb08 100644 --- a/macros/latex/contrib/l3kernel/l3names.dtx +++ b/macros/latex/contrib/l3kernel/l3names.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3news.pdf b/macros/latex/contrib/l3kernel/l3news.pdf Binary files differindex f9308d56e2..cd9eead890 100644 --- a/macros/latex/contrib/l3kernel/l3news.pdf +++ b/macros/latex/contrib/l3kernel/l3news.pdf diff --git a/macros/latex/contrib/l3kernel/l3news01.pdf b/macros/latex/contrib/l3kernel/l3news01.pdf Binary files differindex b03a1bb305..4919fac2b1 100644 --- a/macros/latex/contrib/l3kernel/l3news01.pdf +++ b/macros/latex/contrib/l3kernel/l3news01.pdf diff --git a/macros/latex/contrib/l3kernel/l3news02.pdf b/macros/latex/contrib/l3kernel/l3news02.pdf Binary files differindex dfa67fdf1f..f5a33f51b4 100644 --- a/macros/latex/contrib/l3kernel/l3news02.pdf +++ b/macros/latex/contrib/l3kernel/l3news02.pdf diff --git a/macros/latex/contrib/l3kernel/l3news03.pdf b/macros/latex/contrib/l3kernel/l3news03.pdf Binary files differindex bdb7487e3e..9ee630bddb 100644 --- a/macros/latex/contrib/l3kernel/l3news03.pdf +++ b/macros/latex/contrib/l3kernel/l3news03.pdf diff --git a/macros/latex/contrib/l3kernel/l3news04.pdf b/macros/latex/contrib/l3kernel/l3news04.pdf Binary files differindex 7c1df5cdbf..843b757d41 100644 --- a/macros/latex/contrib/l3kernel/l3news04.pdf +++ b/macros/latex/contrib/l3kernel/l3news04.pdf diff --git a/macros/latex/contrib/l3kernel/l3news05.pdf b/macros/latex/contrib/l3kernel/l3news05.pdf Binary files differindex 9987dcd1eb..b6e9ce58cf 100644 --- a/macros/latex/contrib/l3kernel/l3news05.pdf +++ b/macros/latex/contrib/l3kernel/l3news05.pdf diff --git a/macros/latex/contrib/l3kernel/l3news06.pdf b/macros/latex/contrib/l3kernel/l3news06.pdf Binary files differindex 82f432de52..0a9530e337 100644 --- a/macros/latex/contrib/l3kernel/l3news06.pdf +++ b/macros/latex/contrib/l3kernel/l3news06.pdf diff --git a/macros/latex/contrib/l3kernel/l3news07.pdf b/macros/latex/contrib/l3kernel/l3news07.pdf Binary files differindex fde7e247a0..2a946711ea 100644 --- a/macros/latex/contrib/l3kernel/l3news07.pdf +++ b/macros/latex/contrib/l3kernel/l3news07.pdf diff --git a/macros/latex/contrib/l3kernel/l3news08.pdf b/macros/latex/contrib/l3kernel/l3news08.pdf Binary files differindex aba29f06bf..b4e91f3196 100644 --- a/macros/latex/contrib/l3kernel/l3news08.pdf +++ b/macros/latex/contrib/l3kernel/l3news08.pdf diff --git a/macros/latex/contrib/l3kernel/l3news09.pdf b/macros/latex/contrib/l3kernel/l3news09.pdf Binary files differindex 9ab6e1c83a..43ee33b148 100644 --- a/macros/latex/contrib/l3kernel/l3news09.pdf +++ b/macros/latex/contrib/l3kernel/l3news09.pdf diff --git a/macros/latex/contrib/l3kernel/l3news10.pdf b/macros/latex/contrib/l3kernel/l3news10.pdf Binary files differindex 31d2e513d8..d8cbe38b33 100644 --- a/macros/latex/contrib/l3kernel/l3news10.pdf +++ b/macros/latex/contrib/l3kernel/l3news10.pdf diff --git a/macros/latex/contrib/l3kernel/l3news11.pdf b/macros/latex/contrib/l3kernel/l3news11.pdf Binary files differindex a5ba6e366b..65240af456 100644 --- a/macros/latex/contrib/l3kernel/l3news11.pdf +++ b/macros/latex/contrib/l3kernel/l3news11.pdf diff --git a/macros/latex/contrib/l3kernel/l3news12.pdf b/macros/latex/contrib/l3kernel/l3news12.pdf Binary files differindex 043c436177..37d8e10aa1 100644 --- a/macros/latex/contrib/l3kernel/l3news12.pdf +++ b/macros/latex/contrib/l3kernel/l3news12.pdf diff --git a/macros/latex/contrib/l3kernel/l3prefixes.pdf b/macros/latex/contrib/l3kernel/l3prefixes.pdf Binary files differindex 820a86d56f..50089cf13c 100644 --- a/macros/latex/contrib/l3kernel/l3prefixes.pdf +++ b/macros/latex/contrib/l3kernel/l3prefixes.pdf diff --git a/macros/latex/contrib/l3kernel/l3prg.dtx b/macros/latex/contrib/l3kernel/l3prg.dtx index 704612a0f9..3f1280f23e 100644 --- a/macros/latex/contrib/l3kernel/l3prg.dtx +++ b/macros/latex/contrib/l3kernel/l3prg.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3prop.dtx b/macros/latex/contrib/l3kernel/l3prop.dtx index 4d2c6cbe05..9419a5ce6c 100644 --- a/macros/latex/contrib/l3kernel/l3prop.dtx +++ b/macros/latex/contrib/l3kernel/l3prop.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1071,8 +1071,8 @@ % updated entry is placed at the same spot as the original \meta{key} % in the property list, preserving the order of entries. % \begin{macrocode} -\cs_new_protected:Npn \prop_put:Nnn { \@@_put:NNnn \tl_set:Nx } -\cs_new_protected:Npn \prop_gput:Nnn { \@@_put:NNnn \tl_gset:Nx } +\cs_new_protected:Npn \prop_put:Nnn { \@@_put:NNnn \__kernel_tl_set:Nx } +\cs_new_protected:Npn \prop_gput:Nnn { \@@_put:NNnn \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_put:NNnn #1#2#3#4 { \tl_set:Nn \l_@@_internal_tl @@ -1108,9 +1108,9 @@ % convert the key to a string using \cs{tl_to_str:n}. % \begin{macrocode} \cs_new_protected:Npn \prop_put_if_new:Nnn - { \@@_put_if_new:NNnn \tl_set:Nx } + { \@@_put_if_new:NNnn \__kernel_tl_set:Nx } \cs_new_protected:Npn \prop_gput_if_new:Nnn - { \@@_put_if_new:NNnn \tl_gset:Nx } + { \@@_put_if_new:NNnn \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_put_if_new:NNnn #1#2#3#4 { \tl_set:Nn \l_@@_internal_tl diff --git a/macros/latex/contrib/l3kernel/l3quark.dtx b/macros/latex/contrib/l3kernel/l3quark.dtx index 6827debe15..16a9b0c447 100644 --- a/macros/latex/contrib/l3kernel/l3quark.dtx +++ b/macros/latex/contrib/l3kernel/l3quark.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3regex.dtx b/macros/latex/contrib/l3kernel/l3regex.dtx index 62fd8c4e94..2086b5c3ec 100644 --- a/macros/latex/contrib/l3kernel/l3regex.dtx +++ b/macros/latex/contrib/l3kernel/l3regex.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1322,7 +1322,7 @@ { \int_compare:nNnTF \l_@@_curr_catcode_int = 0 { - \tl_set:Nx \l_@@_internal_a_tl + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \scan_stop: \@@_curr_cs_to_str: \scan_stop: } \tl_if_in:noTF { \scan_stop: #1 \scan_stop: } \l_@@_internal_a_tl @@ -1348,7 +1348,7 @@ \int_compare:nNnT \l_@@_curr_catcode_int = 0 { \group_begin: - \tl_set:Nx \l_@@_cs_name_tl { \@@_curr_cs_to_str: } + \__kernel_tl_set:Nx \l_@@_cs_name_tl { \@@_curr_cs_to_str: } \@@_single_match: \@@_disable_submatches: \@@_build_for_cs:n {#1} @@ -1515,7 +1515,7 @@ \cs_set:Npn \@@_escape_escaped:N ##1 { #2 } \cs_set:Npn \@@_escape_raw:N ##1 { #3 } \@@_standard_escapechar: - \tl_gset:Nx \g_@@_internal_tl + \__kernel_tl_gset:Nx \g_@@_internal_tl { \__kernel_str_to_other_fast:n {#4} } \tl_put_right:Nx \l_@@_internal_a_tl { @@ -2888,12 +2888,12 @@ \@@_two_if_eq:NNNNTF #5 #6 \@@_compile_special:N ^ { \bool_set_false:N \l_@@_internal_bool - \tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi: + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi: \@@_compile_class_posix_loop:w } { \bool_set_true:N \l_@@_internal_bool - \tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi: + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi: \@@_compile_class_posix_loop:w #5 #6 } } @@ -3274,7 +3274,7 @@ { \@@_compile_end: \flag_clear:n { @@_cs } - \tl_set:Nx \l_@@_internal_a_tl + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \exp_after:wN \@@_compile_cs_aux:Nn \l_@@_internal_regex \q_@@_nil \q_@@_nil \q_@@_recursion_stop @@ -3354,7 +3354,7 @@ { \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_special:N \c_left_brace_str { - \tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi: + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi: \@@_compile_u_loop:NN } { @@ -3411,7 +3411,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_compile_u_in_cs: { - \tl_gset:Nx \g_@@_internal_tl + \__kernel_tl_gset:Nx \g_@@_internal_tl { \exp_args:No \__kernel_str_to_other_fast:n { \l_@@_internal_a_tl } @@ -6225,7 +6225,7 @@ \@@_replacement_balance_one_match:n { \l_@@_zeroth_submatch_int } } - \tl_set:Nx \l_@@_internal_a_tl + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \@@_replacement_do_one_match:n { \l_@@_zeroth_submatch_int } @@ -6270,7 +6270,7 @@ { \l_@@_submatch_int - 1 } \@@_replacement_balance_one_match:n } - \tl_set:Nx \l_@@_internal_a_tl + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \int_step_function:nnnN { \l_@@_min_submatch_int } diff --git a/macros/latex/contrib/l3kernel/l3seq.dtx b/macros/latex/contrib/l3kernel/l3seq.dtx index 51c9ec07a1..737a4c776a 100644 --- a/macros/latex/contrib/l3kernel/l3seq.dtx +++ b/macros/latex/contrib/l3kernel/l3seq.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1165,22 +1165,22 @@ % \begin{macrocode} \cs_new_protected:Npn \seq_set_from_clist:NN #1#2 { - \tl_set:Nx #1 + \__kernel_tl_set:Nx #1 { \s_@@ \clist_map_function:NN #2 \@@_wrap_item:n } } \cs_new_protected:Npn \seq_set_from_clist:Nn #1#2 { - \tl_set:Nx #1 + \__kernel_tl_set:Nx #1 { \s_@@ \clist_map_function:nN {#2} \@@_wrap_item:n } } \cs_new_protected:Npn \seq_gset_from_clist:NN #1#2 { - \tl_gset:Nx #1 + \__kernel_tl_gset:Nx #1 { \s_@@ \clist_map_function:NN #2 \@@_wrap_item:n } } \cs_new_protected:Npn \seq_gset_from_clist:Nn #1#2 { - \tl_gset:Nx #1 + \__kernel_tl_gset:Nx #1 { \s_@@ \clist_map_function:nN {#2} \@@_wrap_item:n } } \cs_generate_variant:Nn \seq_set_from_clist:NN { Nc } @@ -1238,9 +1238,9 @@ % braces which are outermost after space trimming. % \begin{macrocode} \cs_new_protected:Npn \seq_set_split:Nnn - { \@@_set_split:NNnn \tl_set:Nx } + { \@@_set_split:NNnn \__kernel_tl_set:Nx } \cs_new_protected:Npn \seq_gset_split:Nnn - { \@@_set_split:NNnn \tl_gset:Nx } + { \@@_set_split:NNnn \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_set_split:NNnn #1#2#3#4 { \tl_if_empty:nTF {#3} @@ -1260,7 +1260,7 @@ \@@_set_split_end: \@@_set_split_auxi:w \prg_do_nothing: } - \tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl } + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl } } #1 #2 { \s_@@ \l_@@_internal_a_tl } } @@ -1329,7 +1329,7 @@ % \begin{macrocode} \cs_new_protected:Npn \seq_put_left:Nn #1#2 { - \tl_set:Nx #1 + \__kernel_tl_set:Nx #1 { \exp_not:n { \s_@@ \@@_item:n {#2} } \exp_not:f { \exp_after:wN \@@_put_left_aux:w #1 } @@ -1337,7 +1337,7 @@ } \cs_new_protected:Npn \seq_gput_left:Nn #1#2 { - \tl_gset:Nx #1 + \__kernel_tl_gset:Nx #1 { \exp_not:n { \s_@@ \@@_item:n {#2} } \exp_not:f { \exp_after:wN \@@_put_left_aux:w #1 } @@ -1448,9 +1448,9 @@ % \texttt{x}-type expansion (|#1 #2 {#2}|) ensures that nothing is lost. % \begin{macrocode} \cs_new_protected:Npn \seq_remove_all:Nn - { \@@_remove_all_aux:NNn \tl_set:Nx } + { \@@_remove_all_aux:NNn \__kernel_tl_set:Nx } \cs_new_protected:Npn \seq_gremove_all:Nn - { \@@_remove_all_aux:NNn \tl_gset:Nx } + { \@@_remove_all_aux:NNn \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_remove_all_aux:NNn #1#2#3 { \@@_push_item_def:n @@ -1515,9 +1515,9 @@ % from the stack, and the memory consumption becomes linear. % \begin{macrocode} \cs_new_protected:Npn \seq_reverse:N - { \@@_reverse:NN \tl_set:Nx } + { \@@_reverse:NN \__kernel_tl_set:Nx } \cs_new_protected:Npn \seq_greverse:N - { \@@_reverse:NN \tl_gset:Nx } + { \@@_reverse:NN \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_reverse:NN #1 #2 { \cs_set_eq:NN \@@_tmp:w \@@_item:n @@ -1704,7 +1704,7 @@ % \begin{macrocode} \cs_new_protected:Npn \seq_get_left:NN #1#2 { - \tl_set:Nx #2 + \__kernel_tl_set:Nx #2 { \exp_after:wN \@@_get_left:wnw #1 \@@_item:n { \q_no_value } \s_@@_stop @@ -1756,7 +1756,7 @@ % \begin{macrocode} \cs_new_protected:Npn \seq_get_right:NN #1#2 { - \tl_set:Nx #2 + \__kernel_tl_set:Nx #2 { \exp_after:wN \use_i_ii:nnn \exp_after:wN \@@_get_right_loop:nw @@ -1797,9 +1797,9 @@ % finally stops the loop. % \begin{macrocode} \cs_new_protected:Npn \seq_pop_right:NN - { \@@_pop:NNNN \@@_pop_right:NNN \tl_set:Nx } + { \@@_pop:NNNN \@@_pop_right:NNN \__kernel_tl_set:Nx } \cs_new_protected:Npn \seq_gpop_right:NN - { \@@_pop:NNNN \@@_pop_right:NNN \tl_gset:Nx } + { \@@_pop:NNNN \@@_pop_right:NNN \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_pop_right:NNN #1#2#3 { \cs_set_eq:NN \@@_tmp:w \@@_item:n @@ -1811,7 +1811,7 @@ #2 { \if_false: { \fi: } - \tl_set:Nx #3 + \__kernel_tl_set:Nx #3 } { } \use_none:nn \cs_set_eq:NN \@@_item:n \@@_tmp:w @@ -1859,10 +1859,10 @@ { \@@_pop_TF:NNNN \@@_pop_left:NNN \tl_gset:Nn #1 #2 } \prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2 { T , F , TF } - { \@@_pop_TF:NNNN \@@_pop_right:NNN \tl_set:Nx #1 #2 } + { \@@_pop_TF:NNNN \@@_pop_right:NNN \__kernel_tl_set:Nx #1 #2 } \prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2 { T , F , TF } - { \@@_pop_TF:NNNN \@@_pop_right:NNN \tl_gset:Nx #1 #2 } + { \@@_pop_TF:NNNN \@@_pop_right:NNN \__kernel_tl_gset:Nx #1 #2 } \prg_generate_conditional_variant:Nnn \seq_pop_left:NN { c } { T , F , TF } \prg_generate_conditional_variant:Nnn \seq_gpop_left:NN { c } @@ -2123,9 +2123,9 @@ % semantics. % \begin{macrocode} \cs_new_protected:Npn \seq_set_map_x:NNn - { \@@_set_map_x:NNNn \tl_set:Nx } + { \@@_set_map_x:NNNn \__kernel_tl_set:Nx } \cs_new_protected:Npn \seq_gset_map_x:NNn - { \@@_set_map_x:NNNn \tl_gset:Nx } + { \@@_set_map_x:NNNn \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_set_map_x:NNNn #1#2#3#4 { \@@_push_item_def:n { \exp_not:N \@@_item:n {#4} } @@ -2142,9 +2142,9 @@ % <inline function>. % \begin{macrocode} \cs_new_protected:Npn \seq_set_map:NNn - { \@@_set_map:NNNn \tl_set:Nx } + { \@@_set_map:NNNn \__kernel_tl_set:Nx } \cs_new_protected:Npn \seq_gset_map:NNn - { \@@_set_map:NNNn \tl_gset:Nx } + { \@@_set_map:NNNn \__kernel_tl_gset:Nx } \cs_new_protected:Npn \@@_set_map:NNNn #1#2#3#4 { \@@_push_item_def:n { \exp_not:n { \@@_item:n {#4} } } diff --git a/macros/latex/contrib/l3kernel/l3skip.dtx b/macros/latex/contrib/l3kernel/l3skip.dtx index 41ee426e40..aeef5ae45c 100644 --- a/macros/latex/contrib/l3kernel/l3skip.dtx +++ b/macros/latex/contrib/l3kernel/l3skip.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3sort.dtx b/macros/latex/contrib/l3kernel/l3sort.dtx index 58fa850b36..30d2b9737e 100644 --- a/macros/latex/contrib/l3kernel/l3sort.dtx +++ b/macros/latex/contrib/l3kernel/l3sort.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -376,7 +376,7 @@ { \group_begin: \@@_main:NNNn \tl_map_inline:Nn \tl_map_break:n #2 {#3} - \tl_gset:Nx \g_@@_internal_tl + \__kernel_tl_gset:Nx \g_@@_internal_tl { \@@_tl_toks:w \l_@@_min_int ; } \group_end: #1 #2 \g_@@_internal_tl diff --git a/macros/latex/contrib/l3kernel/l3str-convert.dtx b/macros/latex/contrib/l3kernel/l3str-convert.dtx index ee01d9e5b0..2acfdcf0aa 100644 --- a/macros/latex/contrib/l3kernel/l3str-convert.dtx +++ b/macros/latex/contrib/l3kernel/l3str-convert.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -455,7 +455,7 @@ % an empty result for the input $-1$. % \begin{macrocode} \group_begin: - \tl_set:Nx \l_@@_internal_tl { \tl_to_str:n { 0123456789ABCDEF } } + \__kernel_tl_set:Nx \l_@@_internal_tl { \tl_to_str:n { 0123456789ABCDEF } } \tl_map_inline:Nn \l_@@_internal_tl { \tl_map_inline:Nn \l_@@_internal_tl @@ -541,7 +541,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_convert_gmap:N #1 { - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_after:wN \@@_convert_gmap_loop:NN \exp_after:wN #1 @@ -566,7 +566,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_convert_gmap_internal:N #1 { - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_after:wN \@@_convert_gmap_internal_loop:Nww \exp_after:wN #1 @@ -690,7 +690,7 @@ { \group_begin: #1 - \tl_gset:Nx \g_@@_result_tl { \__kernel_str_to_other_fast:n {#4} } + \__kernel_tl_gset:Nx \g_@@_result_tl { \__kernel_str_to_other_fast:n {#4} } \exp_after:wN \@@_convert:wwwnn \tl_to_str:n {#5} /// \s_@@_stop { decode } { unescape } @@ -949,7 +949,7 @@ \cs_new_protected:Npn \@@_convert_unescape_: { \flag_clear:n { str_byte } - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_args:No \@@_filter_bytes:n \g_@@_result_tl } \@@_if_flag_error:nnx { str_byte } { non-byte } { bytes } } @@ -1045,7 +1045,7 @@ \cs_new_protected:Npn \@@_convert_decode_clist: { \clist_gset:No \g_@@_result_tl \g_@@_result_tl - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_args:No \clist_map_function:nN \g_@@_result_tl \@@_decode_clist_char:n @@ -1068,7 +1068,7 @@ \cs_new_protected:Npn \@@_convert_encode_clist: { \@@_convert_gmap_internal:N \@@_encode_clist_char:n - \tl_gset:Nx \g_@@_result_tl { \tl_tail:N \g_@@_result_tl } + \__kernel_tl_gset:Nx \g_@@_result_tl { \tl_tail:N \g_@@_result_tl } } \cs_new:Npn \@@_encode_clist_char:n #1 { , #1 } % \end{macrocode} @@ -1362,7 +1362,7 @@ \group_begin: \flag_clear:n { str_error } \int_set:Nn \tex_escapechar:D { 92 } - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \@@_output_byte:w " \exp_last_unbraced:Nf \@@_unescape_hex_auxi:N @@ -1441,7 +1441,7 @@ \flag_clear:n { str_byte } \flag_clear:n { str_error } \int_set:Nn \tex_escapechar:D { 92 } - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_after:wN #3 \g_@@_result_tl #1 ? { ? \prg_break: } @@ -1527,13 +1527,13 @@ \flag_clear:n { str_byte } \flag_clear:n { str_error } \int_set:Nn \tex_escapechar:D { 92 } - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_after:wN \@@_unescape_string_newlines:wN \g_@@_result_tl \prg_break: ^^M ? \prg_break_point: } - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_after:wN \@@_unescape_string_loop:wNNN \g_@@_result_tl #1 ?? { ? \prg_break: } @@ -1984,7 +1984,7 @@ \flag_clear:n { str_extra } \flag_clear:n { str_overlong } \flag_clear:n { str_overflow } - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_after:wN \@@_decode_utf_viii_start:N \g_@@_result_tl { \prg_break: \@@_decode_utf_viii_end: } @@ -2274,7 +2274,7 @@ \flag_clear:n { str_extra } \flag_clear:n { str_end } \cs_set:Npn \@@_tmp:w ##1 ##2 { ` ## #1 } - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_after:wN \@@_decode_utf_xvi_pair:NN #2 \q_@@_nil \q_@@_nil @@ -2562,7 +2562,7 @@ \flag_clear:n { str_end } \flag_clear:n { str_error } \cs_set:Npn \@@_tmp:w ##1 ##2 { ` ## #1 } - \tl_gset:Nx \g_@@_result_tl + \__kernel_tl_gset:Nx \g_@@_result_tl { \exp_after:wN \@@_decode_utf_xxxii_loop:NNNN #2 \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop diff --git a/macros/latex/contrib/l3kernel/l3str.dtx b/macros/latex/contrib/l3kernel/l3str.dtx index 7a992f4cff..bdde861655 100644 --- a/macros/latex/contrib/l3kernel/l3str.dtx +++ b/macros/latex/contrib/l3kernel/l3str.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1027,13 +1027,13 @@ % hide in braces. % \begin{macrocode} \cs_new_protected:Npn \str_replace_once:Nnn - { \@@_replace:NNNnn \prg_do_nothing: \tl_set:Nx } + { \@@_replace:NNNnn \prg_do_nothing: \__kernel_tl_set:Nx } \cs_new_protected:Npn \str_greplace_once:Nnn - { \@@_replace:NNNnn \prg_do_nothing: \tl_gset:Nx } + { \@@_replace:NNNnn \prg_do_nothing: \__kernel_tl_gset:Nx } \cs_new_protected:Npn \str_replace_all:Nnn - { \@@_replace:NNNnn \@@_replace_next:w \tl_set:Nx } + { \@@_replace:NNNnn \@@_replace_next:w \__kernel_tl_set:Nx } \cs_new_protected:Npn \str_greplace_all:Nnn - { \@@_replace:NNNnn \@@_replace_next:w \tl_gset:Nx } + { \@@_replace:NNNnn \@@_replace_next:w \__kernel_tl_gset:Nx } \cs_generate_variant:Nn \str_replace_once:Nnn { c } \cs_generate_variant:Nn \str_greplace_once:Nnn { c } \cs_generate_variant:Nn \str_replace_all:Nnn { c } diff --git a/macros/latex/contrib/l3kernel/l3styleguide.pdf b/macros/latex/contrib/l3kernel/l3styleguide.pdf Binary files differindex 500dc3de31..6969a153b8 100644 --- a/macros/latex/contrib/l3kernel/l3styleguide.pdf +++ b/macros/latex/contrib/l3kernel/l3styleguide.pdf diff --git a/macros/latex/contrib/l3kernel/l3styleguide.tex b/macros/latex/contrib/l3kernel/l3styleguide.tex index 05b109dd10..c94f8239f8 100644 --- a/macros/latex/contrib/l3kernel/l3styleguide.tex +++ b/macros/latex/contrib/l3kernel/l3styleguide.tex @@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN. {latex-team@latex-project.org}% }% } -\date{Released 2020-10-05} +\date{Released 2020-10-27} \begin{document} diff --git a/macros/latex/contrib/l3kernel/l3syntax-changes.pdf b/macros/latex/contrib/l3kernel/l3syntax-changes.pdf Binary files differindex 5198452397..f191cd2bdc 100644 --- a/macros/latex/contrib/l3kernel/l3syntax-changes.pdf +++ b/macros/latex/contrib/l3kernel/l3syntax-changes.pdf diff --git a/macros/latex/contrib/l3kernel/l3syntax-changes.tex b/macros/latex/contrib/l3kernel/l3syntax-changes.tex index da8657d584..d1ac214651 100644 --- a/macros/latex/contrib/l3kernel/l3syntax-changes.tex +++ b/macros/latex/contrib/l3kernel/l3syntax-changes.tex @@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN. {latex-team@latex-project.org}% }% } -\date{Released 2020-10-05} +\date{Released 2020-10-27} \newcommand{\TF}{\textit{(TF)}} diff --git a/macros/latex/contrib/l3kernel/l3sys.dtx b/macros/latex/contrib/l3kernel/l3sys.dtx index ff694adb60..4e5e3816c7 100644 --- a/macros/latex/contrib/l3kernel/l3sys.dtx +++ b/macros/latex/contrib/l3kernel/l3sys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -972,7 +972,7 @@ end \tl_new:N \g_@@_backend_tl \@@_finalise:n { - \tl_gset:Nx \g_@@_backend_tl + \__kernel_tl_gset:Nx \g_@@_backend_tl { \sys_if_engine_xetex:TF { xdvipdfmx } diff --git a/macros/latex/contrib/l3kernel/l3term-glossary.pdf b/macros/latex/contrib/l3kernel/l3term-glossary.pdf Binary files differindex 44bdf57b85..ce59abacbe 100644 --- a/macros/latex/contrib/l3kernel/l3term-glossary.pdf +++ b/macros/latex/contrib/l3kernel/l3term-glossary.pdf diff --git a/macros/latex/contrib/l3kernel/l3term-glossary.tex b/macros/latex/contrib/l3kernel/l3term-glossary.tex index 42efb4ad30..051c23c1bb 100644 --- a/macros/latex/contrib/l3kernel/l3term-glossary.tex +++ b/macros/latex/contrib/l3kernel/l3term-glossary.tex @@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN. {latex-team@latex-project.org}% }% } -\date{Released 2020-10-05} +\date{Released 2020-10-27} \newcommand{\TF}{\textit{(TF)}} diff --git a/macros/latex/contrib/l3kernel/l3text-case.dtx b/macros/latex/contrib/l3kernel/l3text-case.dtx index 3f8f381063..fd41c6bdd3 100644 --- a/macros/latex/contrib/l3kernel/l3text-case.dtx +++ b/macros/latex/contrib/l3kernel/l3text-case.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -155,6 +155,9 @@ % \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnnN} % \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnNw} % \begin{macro}[EXP]{\@@_change_case_lower_sigma:NnnN} +% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnnNN} +% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnw} +% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnN} % \begin{macro}[EXP] % {\@@_change_case_char_title:nnN, \@@_change_case_char_titleonly:nnN} % \begin{macro}[EXP] @@ -206,6 +209,7 @@ \cs_new:Npn \@@_change_case_aux:nnn #1#2#3 { \group_align_safe_begin: + \cs_if_exist_use:c { @@_change_case_boundary_ #2 _ #3 :Nnnw } \@@_change_case_loop:nnw {#2} {#3} #1 \q_@@_recursion_tail \q_@@_recursion_stop \@@_change_case_result:n { } @@ -296,6 +300,7 @@ } { \@@_change_case_store:n { ~ } + \cs_if_exist_use:c { @@_change_case_boundary_ #1 _ #2 :Nnnw } \@@_change_case_loop:nnw {#1} {#2} } % \end{macrocode} @@ -461,16 +466,10 @@ % is there the special case of a terminal sigma. If not, then we pass to % a simple character mapping. % \begin{macrocode} -\cs_new:Npx \@@_change_case_char_lower:nnN #1#2#3 +\cs_new:Npn \@@_change_case_char_lower:nnN #1#2#3 { - \exp_not:N \cs_if_exist_use:cF { @@_change_case_lower_ #2 :nnnN } - { - \bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { \exp_not:N \@@_change_case_lower_sigma:nnnN } - { \exp_not:N \@@_change_case_char:nnnN } - } + \cs_if_exist_use:cF { @@_change_case_lower_ #2 :nnnN } + { \@@_change_case_lower_sigma:nnnN } {#1} {#1} {#2} #3 } \cs_new:Npn \@@_change_case_char_upper:nnN #1#2#3 @@ -485,7 +484,7 @@ % then there is a look-ahead phase: the logic here is simply based on letters. % The one exception is Dutch: see below. % \begin{macrocode} -\bool_lazy_or:nnT +\bool_lazy_or:nnTF { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: } { @@ -518,6 +517,48 @@ } } % \end{macrocode} +% In the $8$-bit engines, we have to look ahead once we find the first byte of the +% possible hit. +% \begin{macrocode} + { + \cs_new:Npn \@@_change_case_lower_sigma:nnnN #1#2#3#4 + { + \int_compare:nNnTF { `#4 } = { "CE } + { \@@_change_case_lower_sigma:nnnNN } + { \@@_change_case_char:nnnN } + {#1} {#2} {#3} #4 + } + \cs_new:Npn \@@_change_case_lower_sigma:nnnNN #1#2#3#4#5 + { + \int_compare:nNnTF { `#5 } = { "A3 } + { \@@_change_case_lower_sigma:nnw {#2} {#3} } + { \@@_change_case_char:nnnN {#1} {#2} {#3} #4#5 } + } + \cs_new:Npn \@@_change_case_lower_sigma:nnw #1#2#3 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_lower_sigma:nnN } + { + \@@_change_case_store:V \c_@@_final_sigma_tl + \@@_change_case_loop:nnw + } + {#1} {#2} #3 \q_@@_recursion_stop + } + \cs_new:Npn \@@_change_case_lower_sigma:nnN #1#2#3 + { + \bool_lazy_or:nnTF + { \token_if_letter_p:N #3 } + { + \bool_lazy_and_p:nn + { \token_if_active_p:N #3 } + { \int_compare_p:nNn { `#3 } > { "80 } } + } + { \@@_change_case_store:V \c_@@_sigma_tl } + { \@@_change_case_store:V \c_@@_final_sigma_tl } + \@@_change_case_loop:nnw {#1} {#2} #3 + } + } +% \end{macrocode} % For titlecasing, we need to fully expand the new character to see if it % is a letter (or active) But that means looking ahead in the $8$-bit case, so % we have to grab the required tokens up-front. Life is a lot easier for Unicode @@ -664,6 +705,9 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}[EXP]{\@@_change_case_upper_de-alt:nnnN} % \begin{macro}[EXP]{\@@_change_case_upper_de-alt:nnnNN} @@ -710,16 +754,28 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_change_case_upper_el:nnnN} -% \begin{macro}[EXP]{\@@_change_case_upper_el:nnnn} -% \begin{macro}[EXP]{\@@_change_case_upper_el_aux:nnnN} -% \begin{macro}[EXP]{\@@_change_case_upper_el_loop:nnw} -% \begin{macro}[EXP]{\@@_change_case_upper_el:nnN} -% \begin{macro}[EXP]{\@@_change_case_if_greek:nTF} +% \begin{macro}[EXP]{\@@_change_case_upper_el:nnn} +% \begin{macro}[EXP]{\@@_change_case_upper_el:nnNw} +% \begin{macro}[EXP]{\@@_change_case_upper_el:NnnN} +% \begin{macro}[EXP]{\@@_change_case_upper_el_dialytika:nnN} +% \begin{macro}[EXP]{\@@_change_case_upper_el_dialytika:N} +% \begin{macro}[EXP]{\@@_change_case_upper_el_hiatus:nnNw} +% \begin{macro}[EXP]{\@@_change_case_upper_el_hiatus:nnN} +% \begin{macro}[EXP]{\@@_change_case_upper_el_gobble:nnw} +% \begin{macro}[EXP]{\@@_change_case_upper_el_gobble:nnN} +% \begin{macro}[EXP,TF]{\@@_change_case_if_greek:n} +% \begin{macro}[EXP,pTF]{\@@_change_case_if_greek:n} +% \begin{macro}[EXP,pTF]{\@@_change_case_if_greek_accent:n} +% \begin{macro}[EXP,pTF]{\@@_change_case_if_greek_diacritic:n} +% \begin{macro}[EXP,TF]{\@@_change_case_if_takes_dialytika:n} % For Greek uppercasing, we need to know if characters \emph{in the Greek % range} have accents. That means doing a \textsc{nfd} conversion first, then % starting a search. As described by the Unicode \textsc{cldr}, Greek accents % need to be found \emph{after} any U+0308 (diaeresis) and are done in two -% groups to allow for the canonical ordering. +% groups to allow for the canonical ordering. The implementation here follows +% the data and examples from ICU +% (\url{https://sites.google.com/site/icusite/design/case/greek-upper}), +% although necessarily the implementation is somewhat different. % \begin{macrocode} \bool_lazy_or:nnT { \sys_if_engine_luatex_p: } @@ -729,97 +785,233 @@ { \@@_change_case_if_greek:nTF { `#4 } { - \exp_args:Ne \@@_change_case_upper_el:nnnn - { \char_to_nfd:N #4 } {#1} {#2} {#3} + \exp_args:Ne \@@_change_case_upper_el:nnn + { \char_to_nfd:N #4 } {#2} {#3} } { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } } - \cs_new:Npn \@@_change_case_upper_el:nnnn #1#2#3#4 - { \@@_change_case_upper_el_aux:nnnN {#2} {#3} {#4} #1 } - \cs_new:Npn \@@_change_case_upper_el_aux:nnnN #1#2#3#4 - { - \@@_change_case_store:e { \use:c { char_ #1 case:N } #4 } - \@@_change_case_upper_el_loop:nnw {#2} {#3} - } - \cs_new:Npn \@@_change_case_upper_el_loop:nnw - #1#2#3 \q_@@_recursion_stop + \cs_new:Npn \@@_change_case_upper_el:nnn #1#2#3 + { \@@_change_case_upper_el:nnNw {#2} {#3} #1 } +% \end{macrocode} +% At this stage we have the first NFD codepoint as |#3|. What we need to know +% is whether after that we have another character token, either from the NFD or +% directly in the input. If not, we store the changed character at this stage. +% \begin{macrocode} + \cs_new:Npn \@@_change_case_upper_el:nnNw #1#2#3#4 \q_@@_recursion_stop { - \tl_if_head_is_N_type:nTF {#3} - { \@@_change_case_upper_el:nnN } - { \@@_change_case_loop:nnw } - {#1} {#2} #3 \q_@@_recursion_stop + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_upper_el:NnnN #3 } + { + \@@_change_case_store:e { \char_uppercase:N #3 } + \@@_change_case_loop:nnw + } + {#1} {#2} #4 \q_@@_recursion_stop } % \end{macrocode} -% In addition to the Greek accents, we list three cases here where an -% accent outside the Greek range has a \text{nfd} that would make it -% equivalent. That includes U+0344, which has to insert U+0308. +% Now, we check the detail of the next codepoint: again we filter out the +% not-a-char cases, before checking if it's an dialytika, accent or diacritic. +% (The latter do not have the same hiatus behavior as accents.) % \begin{macrocode} - \cs_new:Npn \@@_change_case_upper_el:nnN #1#2#3 + \cs_new:Npn \@@_change_case_upper_el:NnnN #1#2#3#4 { - \token_if_cs:NTF #3 - { \@@_change_case_loop:nnw {#1} {#2} #3 } + \token_if_cs:NTF #4 { - \int_compare:nNnTF { `#3 } = { "0308 } - { - \@@_change_case_store:n {#3} - \@@_change_case_upper_el_loop:nnw {#1} {#2} - } + \@@_change_case_store:e { \char_uppercase:N #1 } + \@@_change_case_loop:nnw {#2} {#3} #4 + } + { + \int_compare:nNnTF { `#4 } = { "0308 } + { \@@_change_case_upper_el_dialytika:nnN {#2} {#3} #1 } { - \bool_lazy_any:nTF + \@@_change_case_if_greek_accent:nTF { `#4 } + { \@@_change_case_upper_el_hiatus:nnNw {#2} {#3} #1 } { - { \int_compare_p:nNn { `#3 } = { "0300 } } - { \int_compare_p:nNn { `#3 } = { "0301 } } - { \int_compare_p:nNn { `#3 } = { "0304 } } - { \int_compare_p:nNn { `#3 } = { "0306 } } - { \int_compare_p:nNn { `#3 } = { "0308 } } - { \int_compare_p:nNn { `#3 } = { "0313 } } - { \int_compare_p:nNn { `#3 } = { "0314 } } - { \int_compare_p:nNn { `#3 } = { "0342 } } - { \int_compare_p:nNn { `#3 } = { "0340 } } - { \int_compare_p:nNn { `#3 } = { "0341 } } - { \int_compare_p:nNn { `#3 } = { "0343 } } - } - { \@@_change_case_upper_el_loop:nnw {#1} {#2} } - { - \int_compare:nNnTF { `#3 } = { "0344 } + \@@_change_case_if_greek_diacritic:nTF { `#4 } { - \@@_change_case_store:e - { - \char_generate:nn { "0308 } - { \@@_char_catcode:N #3 } - } - \@@_change_case_upper_el_loop:nnw {#1} {#2} + \@@_change_case_store:e { \char_uppercase:N #1 } + \@@_change_case_loop:nnw {#2} {#3} } { - \int_compare:nNnTF { `#3 } = { "0345 } - { \@@_change_case_loop:nnw {#1} {#2} } - { \@@_change_case_loop:nnw {#1} {#2} #3 } + \@@_change_case_store:e { \char_uppercase:N #1 } + \@@_change_case_loop:nnw {#2} {#3} #4 } } } } } - \prg_new_conditional:Npnn \@@_change_case_if_greek:n #1 { TF } +% \end{macrocode} +% We handle \emph{dialytika} in parts as it's also needed for the hiatus. +% We know only two letters take it, so we can shortcut here on the second +% part of the tests. +% \begin{macrocode} + \cs_new:Npn \@@_change_case_upper_el_dialytika:nnN #1#2#3 + { + \@@_change_case_if_takes_dialytika:nTF { `#3 } + { \@@_change_case_upper_el_dialytika:N #3 } + { \@@_change_case_store:e { \char_uppercase:N #3 } } + \@@_change_case_upper_el_gobble:nnw {#1} {#2} + } + \cs_new:Npn \@@_change_case_upper_el_dialytika:N #1 + { + \@@_change_case_store:e + { + \bool_lazy_or:nnTF + { \int_compare_p:nNn { `#1 } = { "0399 } } + { \int_compare_p:nNn { `#1 } = { "03B9 } } + { \char_generate:nn { "03AA } { \@@_char_catcode:N #1 } } + { \char_generate:nn { "03AB } { \@@_char_catcode:N #1 } } + } + } +% \end{macrocode} +% Adding a hiatus needs some of the same ideas, but if there is not one we +% skip this code point, hence needing a separate function. +% \begin{macrocode} + \cs_new:Npn \@@_change_case_upper_el_hiatus:nnNw + #1#2#3#4 \q_@@_recursion_stop + { + \@@_change_case_store:e { \char_uppercase:N #3 } + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_upper_el_hiatus:nnN } + { \@@_change_case_loop:nnw } + {#1} {#2} #4 \q_@@_recursion_stop + } + \cs_new:Npn \@@_change_case_upper_el_hiatus:nnN #1#2#3 + { + \token_if_cs:NTF #3 + { \@@_change_case_loop:nnw {#1} {#2} #3 } + { + \@@_change_case_if_takes_dialytika:nTF { `#3 } + { + \@@_change_case_upper_el_dialytika:N #3 + \@@_change_case_upper_el_gobble:nnw {#1} {#2} + } + { \@@_change_case_loop:nnw {#1} {#2} #3 } + } + } +% \end{macrocode} +% For clearing out trailing combining marks after we have dealt with +% the first one. +% \begin{macrocode} + \cs_new:Npn \@@_change_case_upper_el_gobble:nnw + #1#2#3 \q_@@_recursion_stop { - \if_int_compare:w #1 < "0370 \exp_stop_f: + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_upper_el_gobble:nnN } + { \@@_change_case_loop:nnw } + {#1} {#2} #3 \q_@@_recursion_stop + } + \cs_new:Npn \@@_change_case_upper_el_gobble:nnN #1#2#3 + { + \bool_lazy_or:nnTF + { \token_if_cs_p:N #3 } + { + ! \bool_lazy_or_p:nn + { \@@_change_case_if_greek_accent_p:n { `#3 } } + { \@@_change_case_if_greek_diacritic_p:n { `#3 } } + } + { \@@_change_case_loop:nnw {#1} {#2} #3 } + { \@@_change_case_upper_el_gobble:nnw {#1} {#2} } + } + } +% \end{macrocode} +% Luckily the Greek range is limited and clear. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_change_case_if_greek:n #1 { TF } + { + \if_int_compare:w #1 < "0370 \exp_stop_f: + \prg_return_false: + \else: + \if_int_compare:w #1 > "03FF \exp_stop_f: + \if_int_compare:w #1 < "1F00 \exp_stop_f: \prg_return_false: \else: - \if_int_compare:w #1 > "03FF \exp_stop_f: - \if_int_compare:w #1 < "1F00 \exp_stop_f: - \prg_return_false: + \if_int_compare:w #1 > "1FFF \exp_stop_f: + \prg_return_false: + \else: + \prg_return_true: + \fi: + \fi: + \else: + \prg_return_true: + \fi: + \fi: + } +% \end{macrocode} +% We follow ICU in adding a few extras to the accent list here. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_change_case_if_greek_accent:n #1 { TF , p } + { + \if_int_compare:w #1 = "0300 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0301 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0342 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0302 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0303 \exp_stop_f: + \prg_return_true: \else: - \if_int_compare:w #1 > "1FFF \exp_stop_f: - \prg_return_false: - \else: + \if_int_compare:w #1 = "0311 \exp_stop_f: \prg_return_true: + \else: + \prg_return_false: \fi: \fi: - \else: + \fi: + \fi: + \fi: + \fi: + } +\prg_new_conditional:Npnn \@@_change_case_if_greek_diacritic:n + #1 { TF , p } + { + \if_int_compare:w #1 = "0304 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0306 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0313 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0314 \exp_stop_f: \prg_return_true: + \else: + \if_int_compare:w #1 = "0343 \exp_stop_f: + \prg_return_true: + \else: + \prg_return_false: + \fi: \fi: \fi: - } + \fi: + \fi: } +\prg_new_conditional:Npnn \@@_change_case_if_takes_dialytika:n #1 { TF } + { + \if_int_compare:w #1 = "0399 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "03B9 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "03A5 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "03C5 \exp_stop_f: + \prg_return_true: + \else: + \prg_return_false: + \fi: + \fi: + \fi: + \fi: + } % \end{macrocode} % \end{macro} % \end{macro} @@ -827,6 +1019,76 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:Nnnw} +% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnN} +% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnNw} +% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:NnnN} +% There is one special case in Greek that needs to be picked up based on +% being an isolated letter. We do that using a test similar to final sigma, +% but it has to fire off from the space grabber. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_change_case_boundary_upper_el:Nnnw + #1#2#3#4 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_boundary_upper_el:nnN } + { \@@_change_case_loop:nnw } + {#2} {#3} #4 \q_@@_recursion_stop + } + \cs_new:Npn \@@_change_case_boundary_upper_el:nnN #1#2#3 + { + \bool_lazy_or:nnTF + { \token_if_cs_p:N #3 } + { + ! \bool_lazy_or_p:nn + { \int_compare_p:nNn { `#3 } = { "03AE } } + { \int_compare_p:nNn { `#3 } = { "1F22 } } + } + { \@@_change_case_loop:nnw } + { \@@_change_case_boundary_upper_el:nnNw } + {#1} {#2} #3 + } + \cs_new:Npn \@@_change_case_boundary_upper_el:nnNw + #1#2#3#4 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_boundary_upper_el:NnnN #3 } + { + \@@_change_case_store:e + { \char_generate:nn { "0389 } { \@@_char_catcode:N #3 } } + \@@_change_case_loop:nnw + } + {#1} {#2} #4 \q_@@_recursion_stop + } + \cs_new:Npn \@@_change_case_boundary_upper_el:NnnN #1#2#3#4 + { + \token_if_letter:NTF #4 + { \@@_change_case_loop:nnw {#2} {#3} #1#4 } + { + \@@_change_case_store:e + { \char_generate:nn { "0389 } { \@@_char_catcode:N #1 } } + \@@_change_case_loop:nnw {#2} {#3} #4 + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % \begin{macro}[EXP]{\@@_change_case_title_el:nnnN} % Titlecasing retains accents, but to prevent the uppercasing code % from kicking in, there has to be an explicit function here. @@ -1198,14 +1460,17 @@ % % \begin{variable} % { -% \c_@@_dotless_i_tl , -% \c_@@_dotted_I_tl , -% \c_@@_i_ogonek_tl , -% \c_@@_I_ogonek_tl , +% \c_@@_dotless_i_tl , +% \c_@@_dotted_I_tl , +% \c_@@_i_ogonek_tl , +% \c_@@_I_ogonek_tl , +% \c_@@_final_sigma_tl , +% \c_@@_sigma_tl , % \c_@@_grosses_Eszett_tl % } % For cases where there is an $8$-bit option in the |T1| font set up, -% a variant is provided in both cases. +% a variant is provided in both cases. There are also a few extras for +% |LGR|. % \begin{macrocode} \group_begin: \bool_lazy_or:nnF @@ -1238,6 +1503,8 @@ \@@_tmp:w \c_@@_dotted_I_tl { 0130 } \@@_tmp:w \c_@@_i_ogonek_tl { 012F } \@@_tmp:w \c_@@_I_ogonek_tl { 012E } + \@@_tmp:w \c_@@_final_sigma_tl { 03C2 } + \@@_tmp:w \c_@@_sigma_tl { 03C3 } \@@_tmp:w \c_@@_grosses_Eszett_tl { 1E9E } } \group_end: @@ -1245,7 +1512,9 @@ % \end{variable} % % For $8$-bit engines we now need to define the case-change data for -% the multi-octet mappings. These need a list of what code points are +% the multi-octet mappings. This data is here not in the \pkg{char} module +% as the multi-byte nature means they are never |N|-type. +% These need a list of what code points are % doable in |T1| so the list is hard coded (there's no saving in loading % the mappings dynamically). All of the straight-forward ones have two % octets, so that is taken as read. @@ -1454,9 +1723,18 @@ { 042E } { 044E } { 042F } { 044F } % \end{macrocode} -% Core Greek support: there may need to be a little more work here to -% deal completely with accents. +% Greek support: everything in the two-octet range. % \begin{macrocode} + { 0370 } { 0371 } + { 0372 } { 0373 } + { 0376 } { 0377 } + { 03FD } { 037B } + { 03FE } { 037C } + { 03FF } { 037D } + { 0386 } { 03AC } + { 0388 } { 03AD } + { 0389 } { 03AE } + { 038A } { 03AF } { 0391 } { 03B1 } { 0392 } { 03B2 } { 0393 } { 03B3 } @@ -1481,17 +1759,39 @@ { 03A7 } { 03C7 } { 03A8 } { 03C8 } { 03A9 } { 03C9 } + { 03AA } { 03CA } + { 03AB } { 03CB } + { 038C } { 03CC } + { 038E } { 03CD } + { 038F } { 03CE } + { 03CF } { 03D7 } { 03D8 } { 03D9 } { 03DA } { 03DB } { 03DC } { 03DD } { 03DE } { 03DF } { 03E0 } { 03E1 } + { 03E2 } { 03E3 } + { 03E4 } { 03E5 } + { 03E6 } { 03E7 } + { 03E8 } { 03E9 } + { 03EA } { 03EB } + { 03EC } { 03ED } + { 03EE } { 03EF } + { 03F9 } { 03F2 } + { 037F } { 03F3 } + { 03F7 } { 03F8 } + { 03FA } { 03FB } \q_recursion_tail ? \q_recursion_stop +% \end{macrocode} +% Odds and ends for Greek; mainly symbols that are for compatibility, +% but also things like the terminal sigma. Almost all are uppercase +% mappings, but there is one that is not! +% \begin{macrocode} \cs_set_protected:Npn \@@_tmp:w #1#2#3 { \group_begin: - \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4 + \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4##5##6##7##8 { \tl_const:cx { @@ -1500,6 +1800,47 @@ \char_generate:nn {##2} { 12 } _tl } + { + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {##5} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {##6} { 13 } + } + } + \use:x + { + \@@_tmp:w + \char_to_utfviii_bytes:n { "#1 } + \char_to_utfviii_bytes:n { "#2 } + } + \group_end: + } + \@@_tmp:w { 0345 } { 0399 } { upper } + \@@_tmp:w { 03C2 } { 03A3 } { upper } + \@@_tmp:w { 03D0 } { 0392 } { upper } + \@@_tmp:w { 03D1 } { 0398 } { upper } + \@@_tmp:w { 03D5 } { 03A6 } { upper } + \@@_tmp:w { 03D6 } { 03A0 } { upper } + \@@_tmp:w { 03F0 } { 039A } { upper } + \@@_tmp:w { 03F1 } { 03A1 } { upper } + \@@_tmp:w { 03F4 } { 03B8 } { lower } + \@@_tmp:w { 03F5 } { 0395 } { upper } +% \end{macrocode} +% Odds and ends that are not simple one-to-one mappings. These +% are still two-octet code points. +% \begin{macrocode} + \cs_set_protected:Npn \@@_tmp:w #1#2#3 + { + \group_begin: + \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4 + { + \tl_const:cn + { + c_@@_ #3 case_ + \char_generate:nn {##1} { 12 } + \char_generate:nn {##2} { 12 } + _tl + } {#2} } \use:x @@ -1509,8 +1850,182 @@ \@@_tmp:w { 00DF } { SS } { upper } \@@_tmp:w { 00DF } { Ss } { title } \@@_tmp:w { 0131 } { I } { upper } - } - \group_end: +% \end{macrocode} +% Greek support: the three-octet code points. +% \begin{macrocode} + \cs_set_protected:Npn \@@_tmp:nnnnnn #1#2#3#4#5#6#7 + { + \tl_const:cx + { + c_@@_ #1 case_ + \char_generate:nn {#2} { 12 } + \char_generate:nn {#3} { 12 } + \char_generate:nn {#4} { 12 } + _tl + } + { + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#5} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#6} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#7} { 13 } + } + } + \cs_set_protected:Npn \@@_tmp:w #1#2#3#4#5#6#7#8 + { + \tl_const:cx + { + c_@@_lowercase_ + \char_generate:nn {#1} { 12 } + \char_generate:nn {#2} { 12 } + \char_generate:nn {#3} { 12 } + _tl + } + { + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#5} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#6} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#7} { 13 } + } + \@@_tmp:nnnnnn { upper } {#5} {#6} {#7} {#1} {#2} {#3} + \@@_tmp:nnnnnn { title } {#5} {#6} {#7} {#1} {#2} {#3} + } + \@@_loop:nn + { 1F08 } { 1F00 } + { 1F09 } { 1F01 } + { 1F0A } { 1F02 } + { 1F0B } { 1F03 } + { 1F0C } { 1F04 } + { 1F0D } { 1F05 } + { 1F0E } { 1F06 } + { 1F0F } { 1F07 } + { 1F18 } { 1F10 } + { 1F19 } { 1F11 } + { 1F1A } { 1F12 } + { 1F1B } { 1F13 } + { 1F1C } { 1F14 } + { 1F1D } { 1F15 } + { 1F28 } { 1F20 } + { 1F29 } { 1F21 } + { 1F2A } { 1F22 } + { 1F2B } { 1F23 } + { 1F2C } { 1F24 } + { 1F2D } { 1F25 } + { 1F2E } { 1F26 } + { 1F2F } { 1F27 } + { 1F38 } { 1F30 } + { 1F39 } { 1F31 } + { 1F3A } { 1F32 } + { 1F3B } { 1F33 } + { 1F3C } { 1F34 } + { 1F3D } { 1F35 } + { 1F3E } { 1F36 } + { 1F3F } { 1F37 } + { 1F48 } { 1F40 } + { 1F49 } { 1F41 } + { 1F4A } { 1F42 } + { 1F4B } { 1F43 } + { 1F4C } { 1F44 } + { 1F4D } { 1F45 } + { 1F59 } { 1F51 } + { 1F5B } { 1F53 } + { 1F5D } { 1F55 } + { 1F5F } { 1F57 } + { 1F68 } { 1F60 } + { 1F69 } { 1F61 } + { 1F6A } { 1F62 } + { 1F6B } { 1F63 } + { 1F6C } { 1F64 } + { 1F6D } { 1F65 } + { 1F6E } { 1F66 } + { 1F6F } { 1F67 } + { 1FBA } { 1F70 } + { 1FBB } { 1F71 } + { 1FC8 } { 1F72 } + { 1FC9 } { 1F73 } + { 1FCA } { 1F74 } + { 1FCB } { 1F75 } + { 1FDA } { 1F76 } + { 1FDB } { 1F77 } + { 1FF8 } { 1F78 } + { 1FF9 } { 1F79 } + { 1FEA } { 1F7A } + { 1FEB } { 1F7B } + { 1FFA } { 1F7C } + { 1FFB } { 1F7D } + { 1F88 } { 1F80 } + { 1F89 } { 1F81 } + { 1F8A } { 1F82 } + { 1F8B } { 1F83 } + { 1F8C } { 1F84 } + { 1F8D } { 1F85 } + { 1F8E } { 1F86 } + { 1F8F } { 1F87 } + { 1F98 } { 1F90 } + { 1F99 } { 1F91 } + { 1F9A } { 1F92 } + { 1F9B } { 1F93 } + { 1F9C } { 1F94 } + { 1F9D } { 1F95 } + { 1F9E } { 1F96 } + { 1F9F } { 1F97 } + { 1FA8 } { 1FA0 } + { 1FA9 } { 1FA1 } + { 1FAA } { 1FA2 } + { 1FAB } { 1FA3 } + { 1FAC } { 1FA4 } + { 1FAD } { 1FA5 } + { 1FAE } { 1FA6 } + { 1FAF } { 1FA7 } + { 1FB8 } { 1FB0 } + { 1FB9 } { 1FB1 } + { 1FBC } { 1FB3 } + { 1FCC } { 1FC3 } + { 1FD8 } { 1FD0 } + { 1FD9 } { 1FD1 } + { 1FE8 } { 1FE0 } + { 1FE9 } { 1FE1 } + { 1FEC } { 1FE5 } + { 1FFC } { 1FF3 } + \q_recursion_tail ? + \q_recursion_stop +% \end{macrocode} +% One three-octet special case for Greek: it also moves to two-octets! +% \begin{macrocode} + \cs_set_protected:Npn \@@_tmp:w #1#2#3 + { + \group_begin: + \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4##5##6##7##8 + { + \tl_const:cx + { + c_@@_ #3 case_ + \char_generate:nn {##1} { 12 } + \char_generate:nn {##2} { 12 } + \char_generate:nn {##3} { 12 } + _tl + } + { + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {##5} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {##6} { 13 } + } + } + \use:x + { + \@@_tmp:w + \char_to_utfviii_bytes:n { "#1 } + \char_to_utfviii_bytes:n { "#2 } + } + \group_end: + } + \@@_tmp:w { 1FBE } { 0399 } { upper } + } +\group_end: % \end{macrocode} % % The (fixed) look-up mappings for letter-like control sequences. diff --git a/macros/latex/contrib/l3kernel/l3text-purify.dtx b/macros/latex/contrib/l3kernel/l3text-purify.dtx index b2f0b59fab..1bc377ed02 100644 --- a/macros/latex/contrib/l3kernel/l3text-purify.dtx +++ b/macros/latex/contrib/l3kernel/l3text-purify.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -398,10 +398,15 @@ { \text_declare_purify_equivalent:Nn #1 { } } % \end{macrocode} % Environments have to be handled by pure expansion. +% +% \begin{macro}{\@@_end_env:n} % \begin{macrocode} \text_declare_purify_equivalent:Nn \begin { \use:c } -\text_declare_purify_equivalent:Nn \end { \use:c } +\text_declare_purify_equivalent:Nn \end { \@@_end_env:n } +\cs_new:Npn \@@_end_env:n #1 { \cs:w end #1 \cs_end: } % \end{macrocode} +% \end{macro} +% % Some common symbols and similar ideas. % \begin{macrocode} \text_declare_purify_equivalent:Nn \\ { } diff --git a/macros/latex/contrib/l3kernel/l3text.dtx b/macros/latex/contrib/l3kernel/l3text.dtx index 3672f46177..893c43da59 100644 --- a/macros/latex/contrib/l3kernel/l3text.dtx +++ b/macros/latex/contrib/l3kernel/l3text.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -163,7 +163,8 @@ % Unicode \TeX{} engines. % \item Greek (\texttt{el}). % Removes accents from Greek letters when uppercasing; titlecasing -% leaves accents in place. +% leaves accents in place. (At present this is implemented only +% for Unicode engines.) % \item Lithuanian (\texttt{lt}). % The lowercase letters i and j should retain a dot above when the % accents grave, acute or tilde are present. This is implemented for diff --git a/macros/latex/contrib/l3kernel/l3tl-analysis.dtx b/macros/latex/contrib/l3kernel/l3tl-analysis.dtx index 3f87c17abb..be4bd2406e 100644 --- a/macros/latex/contrib/l3kernel/l3tl-analysis.dtx +++ b/macros/latex/contrib/l3kernel/l3tl-analysis.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -721,7 +721,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_analysis_b:n #1 { - \tl_gset:Nx \g_@@_analysis_result_tl + \__kernel_tl_gset:Nx \g_@@_analysis_result_tl { \@@_analysis_b_loop:w 0; #1 \prg_break_point: diff --git a/macros/latex/contrib/l3kernel/l3tl.dtx b/macros/latex/contrib/l3kernel/l3tl.dtx index 2ef110b383..b942e97703 100644 --- a/macros/latex/contrib/l3kernel/l3tl.dtx +++ b/macros/latex/contrib/l3kernel/l3tl.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -1269,6 +1269,15 @@ % % \subsection{Functions} % +% \begin{macro}{\__kernel_tl_set:Nx,\__kernel_tl_gset:Nx} +% These two are supplied to get better performance for macros which would +% otherwise use \cs{tl_set:Nx} or \cs{tl_gset:Nx} internally. +% \begin{macrocode} +\cs_new_eq:NN \__kernel_tl_set:Nx \cs_set_nopar:Npx +\cs_new_eq:NN \__kernel_tl_gset:Nx \cs_gset_nopar:Npx +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\tl_new:N, \tl_new:c} % Creating new token list variables is a case of checking for an % existing definition and doing the definition. @@ -1283,12 +1292,14 @@ % \end{macro} % % \begin{macro}{\tl_const:Nn, \tl_const:Nx, \tl_const:cn, \tl_const:cx} -% Constants are also easy to generate. +% Constants are also easy to generate. They use \cs{cs_gset_nopar:Npx} instead +% of \cs{__kernel_tl_gset:Nx} so that the correct scope checking is applied if +% \pkg{l3debug} is used. % \begin{macrocode} \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} } + \cs_gset_nopar:Npx #1 { \__kernel_exp_not:w {#2} } } \cs_new_protected:Npn \tl_const:Nx #1#2 { @@ -1350,9 +1361,21 @@ % \cs{scan_stop:} would lead to problems later on. % \begin{macrocode} \cs_new_protected:Npn \tl_concat:NNN #1#2#3 - { \tl_set:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } } + { + \__kernel_tl_set:Nx #1 + { + \__kernel_exp_not:w \exp_after:wN {#2} + \__kernel_exp_not:w \exp_after:wN {#3} + } + } \cs_new_protected:Npn \tl_gconcat:NNN #1#2#3 - { \tl_gset:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } } + { + \__kernel_tl_gset:Nx #1 + { + \__kernel_exp_not:w \exp_after:wN {#2} + \__kernel_exp_not:w \exp_after:wN {#3} + } + } \cs_generate_variant:Nn \tl_concat:NNN { ccc } \cs_generate_variant:Nn \tl_gconcat:NNN { ccc } % \end{macrocode} @@ -1419,17 +1442,17 @@ % \enquote{by hand} as it is used quite a lot. % \begin{macrocode} \cs_new_protected:Npn \tl_set:Nn #1#2 - { \cs_set_nopar:Npx #1 { \exp_not:n {#2} } } + { \__kernel_tl_set:Nx #1 { \__kernel_exp_not:w {#2} } } \cs_new_protected:Npn \tl_set:No #1#2 - { \cs_set_nopar:Npx #1 { \exp_not:o {#2} } } + { \__kernel_tl_set:Nx #1 { \__kernel_exp_not:w \exp_after:wN {#2} } } \cs_new_protected:Npn \tl_set:Nx #1#2 - { \cs_set_nopar:Npx #1 {#2} } + { \__kernel_tl_set:Nx #1 {#2} } \cs_new_protected:Npn \tl_gset:Nn #1#2 - { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} } } + { \__kernel_tl_gset:Nx #1 { \__kernel_exp_not:w {#2} } } \cs_new_protected:Npn \tl_gset:No #1#2 - { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} } } + { \__kernel_tl_gset:Nx #1 { \__kernel_exp_not:w \exp_after:wN {#2} } } \cs_new_protected:Npn \tl_gset:Nx #1#2 - { \cs_gset_nopar:Npx #1 {#2} } + { \__kernel_tl_gset:Nx #1 {#2} } \cs_generate_variant:Nn \tl_set:Nn { NV , Nv , Nf } \cs_generate_variant:Nn \tl_set:Nx { c } \cs_generate_variant:Nn \tl_set:Nn { c, co , cV , cv , cf } @@ -1453,21 +1476,45 @@ % Adding to the left is done directly to gain a little performance. % \begin{macrocode} \cs_new_protected:Npn \tl_put_left:Nn #1#2 - { \cs_set_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } } + { + \__kernel_tl_set:Nx #1 + { \__kernel_exp_not:w {#2} \__kernel_exp_not:w \exp_after:wN {#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_tl_set:Nx #1 + { \exp_not:V #2 \__kernel_exp_not:w \exp_after:wN {#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_tl_set:Nx #1 + { + \__kernel_exp_not:w \exp_after:wN {#2} + \__kernel_exp_not:w \exp_after:wN {#1} + } + } \cs_new_protected:Npn \tl_put_left:Nx #1#2 - { \cs_set_nopar:Npx #1 { #2 \exp_not:o #1 } } + { \__kernel_tl_set:Nx #1 { #2 \__kernel_exp_not:w \exp_after:wN {#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_tl_gset:Nx #1 + { \__kernel_exp_not:w {#2} \__kernel_exp_not:w \exp_after:wN {#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_tl_gset:Nx #1 + { \exp_not:V #2 \__kernel_exp_not:w \exp_after:wN {#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_tl_gset:Nx #1 + { + \__kernel_exp_not:w \exp_after:wN {#2} + \__kernel_exp_not:w \exp_after:wN {#1} + } + } \cs_new_protected:Npn \tl_gput_left:Nx #1#2 - { \cs_gset_nopar:Npx #1 { #2 \exp_not:o {#1} } } + { \__kernel_tl_gset:Nx #1 { #2 \__kernel_exp_not:w \exp_after:wN {#1} } } \cs_generate_variant:Nn \tl_put_left:Nn { c } \cs_generate_variant:Nn \tl_put_left:NV { c } \cs_generate_variant:Nn \tl_put_left:No { c } @@ -1495,21 +1542,39 @@ % The same on the right. % \begin{macrocode} \cs_new_protected:Npn \tl_put_right:Nn #1#2 - { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } } + { \__kernel_tl_set:Nx #1 { \__kernel_exp_not:w \exp_after:wN { #1 #2 } } } \cs_new_protected:Npn \tl_put_right:NV #1#2 - { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } } + { + \__kernel_tl_set:Nx #1 + { \__kernel_exp_not:w \exp_after:wN {#1} \exp_not:V #2 } + } \cs_new_protected:Npn \tl_put_right:No #1#2 - { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } } + { + \__kernel_tl_set:Nx #1 + { + \__kernel_exp_not:w \exp_after:wN {#1} + \__kernel_exp_not:w \exp_after:wN {#2} + } + } \cs_new_protected:Npn \tl_put_right:Nx #1#2 - { \cs_set_nopar:Npx #1 { \exp_not:o #1 #2 } } + { \__kernel_tl_set:Nx #1 { \__kernel_exp_not:w \exp_after:wN {#1} #2 } } \cs_new_protected:Npn \tl_gput_right:Nn #1#2 - { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } } + { \__kernel_tl_gset:Nx #1 { \__kernel_exp_not:w \exp_after:wN { #1 #2 } } } \cs_new_protected:Npn \tl_gput_right:NV #1#2 - { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } } + { + \__kernel_tl_gset:Nx #1 + { \__kernel_exp_not:w \exp_after:wN {#1} \exp_not:V #2 } + } \cs_new_protected:Npn \tl_gput_right:No #1#2 - { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } } + { + \__kernel_tl_gset:Nx #1 + { + \__kernel_exp_not:w \exp_after:wN {#1} + \__kernel_exp_not:w \exp_after:wN {#2} + } + } \cs_new_protected:Npn \tl_gput_right:Nx #1#2 - { \cs_gset_nopar:Npx #1 { \exp_not:o {#1} #2 } } + { \__kernel_tl_gset:Nx #1 { \__kernel_exp_not:w \exp_after:wN {#1} #2 } } \cs_generate_variant:Nn \tl_put_right:Nn { c } \cs_generate_variant:Nn \tl_put_right:NV { c } \cs_generate_variant:Nn \tl_put_right:No { c } @@ -1574,6 +1639,7 @@ % \tl_gset_rescan:cnn, \tl_gset_rescan:cno, \tl_gset_rescan:cnx % } % \begin{macro}{\tl_rescan:nn} +% \begin{macro}{\@@_rescan_aux:} % \begin{macro}{\@@_set_rescan:NNnn, \@@_set_rescan_multi:nNN} % \begin{macro}[EXP]{\@@_rescan:NNw} % In a group, after some initial setup explained below and the user @@ -1632,9 +1698,11 @@ \cs_new_protected:Npn \tl_rescan:nn #1#2 { \tl_set_rescan:Nnn \l_@@_internal_a_tl {#1} {#2} - \exp_after:wN \tl_clear:N \exp_after:wN \l_@@_internal_a_tl + \exp_after:wN \@@_rescan_aux: \l_@@_internal_a_tl } +\exp_args:NNo \cs_new_protected:Npn \@@_rescan_aux: + { \tl_clear:N \l_@@_internal_a_tl } \cs_new_protected:Npn \tl_set_rescan:Nnn { \@@_set_rescan:NNnn \tl_set:No } \cs_new_protected:Npn \tl_gset_rescan:Nnn @@ -1653,7 +1721,7 @@ } \cs_new_protected:Npn \@@_set_rescan_multi:nNN #1#2#3 { - \exp_args:No \tex_everyeof:D { \c_@@_rescan_marker_tl } + \tex_everyeof:D \exp_after:wN { \c_@@_rescan_marker_tl } \exp_after:wN \@@_rescan:NNw \exp_after:wN #2 \exp_after:wN #3 @@ -1676,6 +1744,7 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\@@_set_rescan:nNN} % \begin{macro}{\@@_set_rescan_single:nnNN, \@@_set_rescan_single_aux:nnnNN} @@ -1802,13 +1871,13 @@ % the \meta{tl~var} by \meta{token list}. % \begin{macrocode} \cs_new_protected:Npn \tl_replace_once:Nnn - { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_wrap:w \tl_set:Nx } + { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_wrap:w \__kernel_tl_set:Nx } \cs_new_protected:Npn \tl_greplace_once:Nnn - { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_wrap:w \tl_gset:Nx } + { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_wrap:w \__kernel_tl_gset:Nx } \cs_new_protected:Npn \tl_replace_all:Nnn - { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_next:w \tl_set:Nx } + { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_next:w \__kernel_tl_set:Nx } \cs_new_protected:Npn \tl_greplace_all:Nnn - { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_next:w \tl_gset:Nx } + { \@@_replace:NnNNNnn \q_@@_mark ? \@@_replace_next:w \__kernel_tl_gset:Nx } \cs_generate_variant:Nn \tl_replace_once:Nnn { c } \cs_generate_variant:Nn \tl_greplace_once:Nnn { c } \cs_generate_variant:Nn \tl_replace_all:Nnn { c } @@ -1825,6 +1894,7 @@ % \@@_replace_auxi:NnnNNNnn, % \@@_replace_auxii:nNNNnn, % \@@_replace_next:w, +% \@@_replace_next_aux:w, % \@@_replace_wrap:w, % } % To implement the actual replacement auxiliary @@ -1969,7 +2039,7 @@ { \group_align_safe_begin: \cs_set:Npn \@@_replace_wrap:w ##1 #1 ##2 - { \exp_not:o { \use_none:nn ##1 } ##2 } + { \__kernel_exp_not:w \exp_after:wN { \use_none:nn ##1 } ##2 } \cs_set:Npx \@@_replace_next:w ##1 #5 { \exp_not:N \@@_replace_wrap:w ##1 @@ -1979,9 +2049,7 @@ } #3 #4 { - \exp_after:wN \@@_replace_next:w - \exp_after:wN { \exp_after:wN } - \exp_after:wN { \exp_after:wN } + \exp_after:wN \@@_replace_next_aux:w #4 #1 { @@ -1992,6 +2060,7 @@ } \group_align_safe_end: } +\cs_new:Npn \@@_replace_next_aux:w { \@@_replace_next:w { } { } } \cs_new_eq:NN \@@_replace_wrap:w ? \cs_new_eq:NN \@@_replace_next:w ? % \end{macrocode} @@ -2027,29 +2096,6 @@ % % \subsection{Token list conditionals} % -% \begin{macro}[pTF]{\tl_if_blank:n, \tl_if_blank:V, \tl_if_blank:o} -% \begin{macro}{\@@_if_blank_p:NNw} -% \TeX{} skips spaces when reading a non-delimited arguments. Thus, -% a \meta{token list} is blank if and only if \cs{use_none:n} -% \meta{token list} |?| is empty after one expansion. The auxiliary -% \cs{@@_if_empty_if:o} is a fast emptyness test, converting its -% argument to a string (after one expansion) and using the test -% \cs{if_meaning:w} \cs{q_@@_nil} |...| \cs{q_@@_nil}. -% \begin{macrocode} -\prg_new_conditional:Npnn \tl_if_blank:n #1 { p , T , F , TF } - { - \@@_if_empty_if:o { \use_none:n #1 ? } - \prg_return_true: - \else: - \prg_return_false: - \fi: - } -\prg_generate_conditional_variant:Nnn \tl_if_blank:n - { e , V , o } { p , T , F , TF } -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \begin{macro}[pTF]{\tl_if_empty:N, \tl_if_empty:c} % These functions check whether the token list in the argument is % empty and execute the proper code from their argument(s). @@ -2068,23 +2114,17 @@ % \end{macro} % % \begin{macro}[pTF]{\tl_if_empty:n, \tl_if_empty:V} -% Convert the argument to a string: this is empty if and only if -% the argument is. Then |\if_meaning:w \q_@@_nil ... \q_@@_nil| is -% \texttt{true} if and only if the string |...| is empty. -% It could be tempting to use |\if_meaning:w \q_@@_nil #1 \q_@@_nil| directly. -% This fails on a token -% list starting with \cs{q_@@_nil} of course but more troubling is the -% case where argument is a complete conditional such as \cs{if_true:} -% a \cs{else:} b \cs{fi:} because then \cs{if_true:} is used by -% \cs{if_meaning:w}, the test turns out \texttt{false}, the \cs{else:} -% executes the \texttt{false} branch, the \cs{fi:} ends it and the -% \cs{q_@@_nil} at the end -% starts executing\dots{} +% The \cs{if:w} triggers the expansion of \cs{tl_to_str:n} which converts the +% argument to a string: this is empty if and only if the argument is. Then +% |\if:w \scan_stop: ... \scan_stop:| is \texttt{true} if and only if the +% string |...| is empty. +% It could be tempting to use |\if:w \scan_stop: #1 \scan_stop:| directly. +% But this fails on a token list expanding to anything starting with +% \cs{scan_stop:} leaving everything that follows in the input stream. % \begin{macrocode} \prg_new_conditional:Npnn \tl_if_empty:n #1 { p , TF , T , F } { - \exp_after:wN \if_meaning:w \exp_after:wN \q_@@_nil - \tl_to_str:n {#1} \q_@@_nil + \if:w \scan_stop: \tl_to_str:n {#1} \scan_stop: \prg_return_true: \else: \prg_return_false: @@ -2107,13 +2147,15 @@ % We don't put \cs{prg_return_true:} and so on in the definition of % the auxiliary, because that would prevent an optimization applied to % conditionals that end with this code. +% Also the |\@@_if_empty_if:o| is expanded once in |\tl_if_empty:oTF| for +% efficiency as well (and to reduce code doubling). % \begin{macrocode} \cs_new:Npn \@@_if_empty_if:o #1 { - \exp_after:wN \if_meaning:w \exp_after:wN \q_@@_nil - \__kernel_tl_to_str:w \exp_after:wN {#1} \q_@@_nil + \if:w \scan_stop: \__kernel_tl_to_str:w \exp_after:wN {#1} \scan_stop: } -\prg_new_conditional:Npnn \tl_if_empty:o #1 { p , TF , T , F } +\exp_args:Nno \use:n + { \prg_new_conditional:Npnn \tl_if_empty:o #1 { p , TF , T , F } } { \@@_if_empty_if:o {#1} \prg_return_true: @@ -2125,6 +2167,30 @@ % \end{macro} % \end{macro} % +% \begin{macro}[pTF]{\tl_if_blank:n, \tl_if_blank:V, \tl_if_blank:o} +% \begin{macro}{\@@_if_blank_p:NNw} +% \TeX{} skips spaces when reading a non-delimited arguments. Thus, +% a \meta{token list} is blank if and only if \cs{use_none:n} +% \meta{token list} |?| is empty after one expansion. The auxiliary +% \cs{@@_if_empty_if:o} is a fast emptyness test, converting its +% argument to a string (after one expansion) and using the test +% \cs{if:w} \cs{scan_stop:} |...| \cs{scan_stop:}. +% \begin{macrocode} +\exp_args:Nno \use:n + { \prg_new_conditional:Npnn \tl_if_blank:n #1 { p , T , F , TF } } + { + \@@_if_empty_if:o { \use_none:n #1 ? } + \prg_return_true: + \else: + \prg_return_false: + \fi: + } +\prg_generate_conditional_variant:Nnn \tl_if_blank:n + { e , V , o } { p , T , F , TF } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}[pTF]{\tl_if_eq:NN, \tl_if_eq:Nc, \tl_if_eq:cN, \tl_if_eq:cc} % Returns \cs{c_true_bool} if and only if the two token list variables are % equal. @@ -2269,28 +2335,28 @@ % \end{macro} % % \begin{macro}[EXP,pTF]{\tl_if_single:n} -% \begin{macro}[EXP,pTF]{\@@_if_single:n} +% \begin{macro}[EXP]{\@@_if_single:nnw} % This test is similar to \cs{tl_if_empty:nTF}. Expanding % \cs{use_none:nn} |#1| |??| once yields an empty result if |#1| is % blank, a single~|?| if |#1| has a single item, and otherwise yields -% some tokens ending with |??|. Then, \cs{tl_to_str:n} makes sure +% some tokens ending with |??|. Then, \cs{__kernel_tl_to_str:w} makes sure % there are no odd category codes. An earlier version would compare % the result to a single~|?| using string comparison, but the Lua call % is slow in \LuaTeX{}. Instead, \cs{@@_if_single:nnw} picks the % second token in front of it. If |#1| is empty, this token is -% the trailing~|?| and the catcode test yields \texttt{false}. If -% |#1| has a single item, the token is~|^| and the catcode test +% the trailing~|?| and the |\if:w| test yields \texttt{false}. If +% |#1| has a single item, the token is~|\scan_stop:| and the |\if:w| test % yields \texttt{true}. Otherwise, it is one of the characters -% resulting from \cs{tl_to_str:n}, and the catcode test yields -% \texttt{false}. Note that \cs{if_catcode:w} and +% resulting from \cs{tl_to_str:n}, and the |\if:w| test yields +% \texttt{false}. Note that \cs{if:w} and % \cs{__kernel_tl_to_str:w} are primitives that take care of % expansion. % \begin{macrocode} \prg_new_conditional:Npnn \tl_if_single:n #1 { p , T , F , TF } { - \if_catcode:w ^ \exp_after:wN \@@_if_single:nnw + \if:w \scan_stop: \exp_after:wN \@@_if_single:nnw \__kernel_tl_to_str:w - \exp_after:wN { \use_none:nn #1 ?? } ^ ? \s_@@_stop + \exp_after:wN { \use_none:nn #1 ?? } \scan_stop: ? \s_@@_stop \prg_return_true: \else: \prg_return_false: @@ -2587,18 +2653,16 @@ { \int_eval:n { - \@@_act:NNNnn - \@@_act_count_normal:nN - \@@_act_count_group:nn - \@@_act_count_space:n - { } + \@@_act:NNNn + \@@_act_count_normal:N + \@@_act_count_group:n + \@@_act_count_space: {#1} } } -\cs_new:Npn \@@_act_count_normal:nN #1 #2 { 1 + } -\cs_new:Npn \@@_act_count_space:n #1 { 1 + } -\cs_new:Npn \@@_act_count_group:nn #1 #2 - { 2 + \tl_count_tokens:n {#2} + } +\cs_new:Npn \@@_act_count_normal:N #1 { 1 + } +\cs_new:Npn \@@_act_count_space: { 1 + } +\cs_new:Npn \@@_act_count_group:n #1 { 2 + \tl_count_tokens:n {#1} + } % \end{macrocode} % \end{macro} % \end{macro} @@ -2624,7 +2688,7 @@ \s_@@_stop { {#1} #5 } } \cs_new:Npn \@@_reverse_items:wn #1 \s_@@_stop #2 - { \exp_not:o { \use_none:nn #2 } } + { \__kernel_exp_not:w \exp_after:wN { \use_none:nn #2 } } % \end{macrocode} % \end{macro} % \end{macro} @@ -2639,22 +2703,28 @@ % } % Trimming spaces from around the input is deferred to an internal % function whose first argument is the token list to trim, augmented -% by an initial \cs{s_@@_mark}, and whose second argument is a +% by an initial \cs{@@_trim_mark:}, and whose second argument is a % \meta{continuation}, which receives as a braced argument -% \cs{use_none:n} \cs{s_@@_mark} \meta{trimmed token list}. In the case -% at hand, we take \cs{exp_not:o} as our continuation, so that space -% trimming behaves correctly within an \texttt{x}-type expansion. +% \cs{@@_trim_mark:} \meta{trimmed token list}. The control sequence +% \cs{@@_trim_mark:} expands to nothing in a single expansion. In the case +% at hand, we take \cs{__kernel_exp_not:w} \cs{exp_after:wN} as our +% continuation, so that space trimming behaves correctly within an +% \texttt{x}-type expansion. % \begin{macrocode} \cs_new:Npn \tl_trim_spaces:n #1 - { \@@_trim_spaces:nn { \s_@@_mark #1 } \exp_not:o } + { + \@@_trim_spaces:nn + { \@@_trim_mark: #1 } + { \__kernel_exp_not:w \exp_after:wN } + } \cs_generate_variant:Nn \tl_trim_spaces:n { o } \cs_new:Npn \tl_trim_spaces_apply:nN #1#2 - { \@@_trim_spaces:nn { \s_@@_mark #1 } { \exp_args:No #2 } } + { \@@_trim_spaces:nn { \@@_trim_mark: #1 } { \exp_args:No #2 } } \cs_generate_variant:Nn \tl_trim_spaces_apply:nN { o } \cs_new_protected:Npn \tl_trim_spaces:N #1 - { \tl_set:Nx #1 { \exp_args:No \tl_trim_spaces:n {#1} } } + { \__kernel_tl_set:Nx #1 { \exp_args:No \tl_trim_spaces:n {#1} } } \cs_new_protected:Npn \tl_gtrim_spaces:N #1 - { \tl_gset:Nx #1 { \exp_args:No \tl_trim_spaces:n {#1} } } + { \__kernel_tl_gset:Nx #1 { \exp_args:No \tl_trim_spaces:n {#1} } } \cs_generate_variant:Nn \tl_trim_spaces:N { c } \cs_generate_variant:Nn \tl_gtrim_spaces:N { c } % \end{macrocode} @@ -2667,45 +2737,48 @@ % \@@_trim_spaces_auxi:w, \@@_trim_spaces_auxii:w, % \@@_trim_spaces_auxiii:w, \@@_trim_spaces_auxiv:w % } +% \begin{macro}{\@@_trim_mark:} % Trimming spaces from around the input is done using delimited % arguments and quarks, and to get spaces at odd places in the % definitions, we nest those in \cs{@@_tmp:w}, which then receives % a single space as its argument: |#1| is \verb*+ +. % Removing leading spaces is done with \cs{@@_trim_spaces_auxi:w}, -% which loops until \cs{s_@@_mark}\verb*+ + matches the end of the token +% which loops until \cs{@@_trim_mark:}\verb*+ + matches the end of the token % list: then |##1| is the token list and |##3| is % \cs{@@_trim_spaces_auxii:w}. This hands the relevant tokens to the % loop \cs{@@_trim_spaces_auxiii:w}, responsible for trimming % trailing spaces. The end is reached when \verb*+ + \cs{s_@@_nil} -% matches the one present in the definition of \cs{tl_trim_spacs:n}. +% matches the one present in the definition of \cs{tl_trim_spaces:n}. % Then \cs{@@_trim_spaces_auxiv:w} puts the token list into a group, -% with \cs{use_none:n} placed there to gobble a lingering \cs{s_@@_mark}, -% and feeds this to the \meta{continuation}. +% with a lingering \cs{@@_trim_mark:} at the start (which will expand to +% nothing in one step of expansion), and feeds this to the +% \meta{continuation}. % \begin{macrocode} -\cs_set:Npn \@@_tmp:w #1 +\cs_set_protected:Npn \@@_tmp:w #1 { \cs_new:Npn \@@_trim_spaces:nn ##1 { \@@_trim_spaces_auxi:w ##1 \s_@@_nil - \s_@@_mark #1 { } - \s_@@_mark \@@_trim_spaces_auxii:w + \@@_trim_mark: #1 { } + \@@_trim_mark: \@@_trim_spaces_auxii:w \@@_trim_spaces_auxiii:w #1 \s_@@_nil \@@_trim_spaces_auxiv:w \s_@@_stop } - \cs_new:Npn \@@_trim_spaces_auxi:w ##1 \s_@@_mark #1 ##2 \s_@@_mark ##3 + \cs_new:Npn + \@@_trim_spaces_auxi:w ##1 \@@_trim_mark: #1 ##2 \@@_trim_mark: ##3 { ##3 \@@_trim_spaces_auxi:w - \s_@@_mark + \@@_trim_mark: ##2 - \s_@@_mark #1 {##1} + \@@_trim_mark: #1 {##1} } \cs_new:Npn \@@_trim_spaces_auxii:w - \@@_trim_spaces_auxi:w \s_@@_mark \s_@@_mark ##1 + \@@_trim_spaces_auxi:w \@@_trim_mark: \@@_trim_mark: ##1 { \@@_trim_spaces_auxiii:w ##1 @@ -2717,172 +2790,21 @@ \@@_trim_spaces_auxiii:w } \cs_new:Npn \@@_trim_spaces_auxiv:w ##1 \s_@@_nil ##2 \s_@@_stop ##3 - { ##3 { \use_none:n ##1 } } + { ##3 { ##1 } } + \cs_new:Npn \@@_trim_mark: {} } \@@_tmp:w { ~ } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro} % {\tl_sort:Nn, \tl_sort:cn, \tl_gsort:Nn, \tl_gsort:cn, \tl_sort:nN} % Implemented in \pkg{l3sort}. % \end{macro} % -% \subsection{Token by token changes} -% -% \begin{variable}{\q_@@_act_mark, \q_@@_act_stop} -% The \cs[no-index]{@@_act_\ldots{}} functions may be applied to any token list. -% Hence, we use two private quarks, to allow any token, even quarks, -% in the token list. -% Only \cs{q_@@_act_mark} and \cs{q_@@_act_stop} may not appear -% in the token lists manipulated by \cs{@@_act:NNNnn} functions. -% \begin{macrocode} -\quark_new:N \q_@@_act_mark -\quark_new:N \q_@@_act_stop -% \end{macrocode} -% \end{variable} -% -% \begin{macro}[EXP]{\@@_act:NNNnn} -% \begin{macro}[EXP]{\@@_act_output:n, \@@_act_reverse_output:n} -% \begin{macro}[EXP]{\@@_act_loop:w} -% \begin{macro}[EXP]{\@@_act_normal:NwnNNN} -% \begin{macro}[EXP]{\@@_act_group:nwnNNN} -% \begin{macro}[EXP]{\@@_act_space:wwnNNN} -% \begin{macro}[EXP]{\@@_act_end:w} -% To help control the expansion, \cs{@@_act:NNNnn} should always -% be proceeded by \cs{exp:w} and ends by producing \cs{exp_end:} -% once the result has been obtained. Then loop over tokens, -% groups, and spaces in |#5|. The marker \cs{q_@@_act_mark} -% is used both to avoid losing outer braces and to detect the -% end of the token list more easily. The result is stored -% as an argument for the dummy function \cs{@@_act_result:n}. -% \begin{macrocode} -\cs_new:Npn \@@_act:NNNnn #1#2#3#4#5 - { - \group_align_safe_begin: - \@@_act_loop:w #5 \q_@@_act_mark \q_@@_act_stop - {#4} #1 #2 #3 - \@@_act_result:n { } - } -% \end{macrocode} -% In the loop, we check how the token list begins and act -% accordingly. In the \enquote{normal} case, we may have -% reached \cs{q_@@_act_mark}, the end of the list. Then -% leave \cs{exp_end:} and the result in the input stream, -% to terminate the expansion of \cs{exp:w}. -% Otherwise, apply the relevant function to the -% \enquote{arguments}, |#3| -% and to the head of the token list. Then repeat the loop. -% The scheme is the same if the token list starts with a -% group or with a space. Some extra work is needed to -% make \cs{@@_act_space:wwnNNN} gobble the space. -% \begin{macrocode} -\cs_new:Npn \@@_act_loop:w #1 \q_@@_act_stop - { - \tl_if_head_is_N_type:nTF {#1} - { \@@_act_normal:NwnNNN } - { - \tl_if_head_is_group:nTF {#1} - { \@@_act_group:nwnNNN } - { \@@_act_space:wwnNNN } - } - #1 \q_@@_act_stop - } -\cs_new:Npn \@@_act_normal:NwnNNN #1 #2 \q_@@_act_stop #3#4 - { - \if_meaning:w \q_@@_act_mark #1 - \exp_after:wN \@@_act_end:wn - \fi: - #4 {#3} #1 - \@@_act_loop:w #2 \q_@@_act_stop - {#3} #4 - } -\cs_new:Npn \@@_act_end:wn #1 \@@_act_result:n #2 - { \group_align_safe_end: \exp_end: #2 } -\cs_new:Npn \@@_act_group:nwnNNN #1 #2 \q_@@_act_stop #3#4#5 - { - #5 {#3} {#1} - \@@_act_loop:w #2 \q_@@_act_stop - {#3} #4 #5 - } -\exp_last_unbraced:NNo - \cs_new:Npn \@@_act_space:wwnNNN \c_space_tl #1 \q_@@_act_stop #2#3#4#5 - { - #5 {#2} - \@@_act_loop:w #1 \q_@@_act_stop - {#2} #3 #4 #5 - } -% \end{macrocode} -% Typically, the output is done to the right of what was already output, -% using \cs{@@_act_output:n}, but for the \cs{@@_act_reverse} functions, -% it should be done to the left. -% \begin{macrocode} -\cs_new:Npn \@@_act_output:n #1 #2 \@@_act_result:n #3 - { #2 \@@_act_result:n { #3 #1 } } -\cs_new:Npn \@@_act_reverse_output:n #1 #2 \@@_act_result:n #3 - { #2 \@@_act_result:n { #1 #3 } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\tl_reverse:n, \tl_reverse:o, \tl_reverse:V} -% \begin{macro}[EXP]{\@@_reverse_normal:nN} -% \begin{macro}[EXP]{\@@_reverse_group_preserve:nn} -% \begin{macro}[EXP]{\@@_reverse_space:n} -% The goal here is to reverse without losing spaces nor braces. -% This is done using the general internal function \cs{@@_act:NNNnn}. -% Spaces and \enquote{normal} tokens are output on the left of the current -% output. Grouped tokens are output to the left but without any reversal -% within the group. All of the internal functions here drop one argument: -% this is needed by \cs{@@_act:NNNnn} when changing case (to record -% which direction the change is in), but not when reversing the tokens. -% \begin{macrocode} -\cs_new:Npn \tl_reverse:n #1 - { - \__kernel_exp_not:w \exp_after:wN - { - \exp:w - \@@_act:NNNnn - \@@_reverse_normal:nN - \@@_reverse_group_preserve:nn - \@@_reverse_space:n - { } - {#1} - } - } -\cs_generate_variant:Nn \tl_reverse:n { o , V } -\cs_new:Npn \@@_reverse_normal:nN #1#2 - { \@@_act_reverse_output:n {#2} } -\cs_new:Npn \@@_reverse_group_preserve:nn #1#2 - { \@@_act_reverse_output:n { {#2} } } -\cs_new:Npn \@@_reverse_space:n #1 - { \@@_act_reverse_output:n { ~ } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tl_reverse:N, \tl_reverse:c, \tl_greverse:N, \tl_greverse:c} -% This reverses the list, leaving \cs{exp_stop_f:} in front, -% which stops the \texttt{f}-expansion. -% \begin{macrocode} -\cs_new_protected:Npn \tl_reverse:N #1 - { \tl_set:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } } -\cs_new_protected:Npn \tl_greverse:N #1 - { \tl_gset:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } } -\cs_generate_variant:Nn \tl_reverse:N { c } -\cs_generate_variant:Nn \tl_greverse:N { c } -% \end{macrocode} -% \end{macro} -% % \subsection{The first token from a token list} % % \begin{macro}{\tl_head:N, \tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f} @@ -2895,32 +2817,49 @@ % empty result. The result is returned within the \tn{unexpanded} primitive. % The approach here is to use \cs{if_false:} to allow us to use |}| as % the closing delimiter: this is the only safe choice, as any other token -% would not be able to parse it's own code. Using a marker, we can see if -% what we are grabbing is exactly the marker, or there is anything else to -% deal with. Is there is, there is a loop. If not, tidy up and leave the -% item in the output stream. More detail in +% would not be able to parse it's own code. If the \tn{expanded} primitive +% is available it is used to get a fast and safe code variant in which we +% don't have to ensure that the left-most token is an internal to not break +% in an |f|-type expansion. If \tn{expanded} isn't available, using a marker, +% we can see if what we are grabbing is exactly the marker, or there is +% anything else to deal with. If there is, there is a loop. If not, tidy up +% and leave the item in the output stream. More detail in % \url{http://tex.stackexchange.com/a/70168}. % \begin{macrocode} -\cs_new:Npn \tl_head:n #1 - { - \__kernel_exp_not:w - \if_false: { \fi: \@@_head_auxi:nw #1 { } \s_@@_stop } - } -\cs_new:Npn \@@_head_auxi:nw #1#2 \s_@@_stop +\cs_if_exist:NTF \tex_expanded:D { - \exp_after:wN \@@_head_auxii:n \exp_after:wN { - \if_false: } \fi: {#1} + \cs_new:Npn \tl_head:n #1 + { + \__kernel_exp_not:w \tex_expanded:D + { { \if_false: { \fi: \@@_head_aux:n #1 { } } } } + } + \cs_new:Npn \@@_head_aux:n #1 + { + \__kernel_exp_not:w {#1} + \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi: + } } -\cs_new:Npn \@@_head_auxii:n #1 { - \exp_after:wN \if_meaning:w \exp_after:wN \q_@@_nil - \__kernel_tl_to_str:w \exp_after:wN { \use_none:n #1 } \q_@@_nil - \exp_after:wN \use_i:nn - \else: - \exp_after:wN \use_ii:nn - \fi: - {#1} - { \if_false: { \fi: \@@_head_auxi:nw #1 } } + \cs_new:Npn \tl_head:n #1 + { + \__kernel_exp_not:w + \if_false: { \fi: \@@_head_auxi:nw #1 { } \s_@@_stop } + } + \cs_new:Npn \@@_head_auxi:nw #1#2 \s_@@_stop + { + \exp_after:wN \@@_head_auxii:n \exp_after:wN { + \if_false: } \fi: {#1} + } + \exp_args:Nno \use:n + { \cs_new:Npn \@@_head_auxii:n #1 } + { + \@@_if_empty_if:o { \use_none:n #1 } + \exp_after:wN \use_ii:nnn + \fi: + \use_ii:nn + {#1} + { \if_false: { \fi: \@@_head_auxi:nw #1 } } + } } \cs_generate_variant:Nn \tl_head:n { V , v , f } \cs_new:Npn \tl_head:w #1#2 \q_stop {#1} @@ -2942,9 +2881,9 @@ % While we could optimise the test here, this would leave some tokens % \enquote{banned} in the input, which we do not have with this definition. % \begin{macrocode} -\cs_new:Npn \tl_tail:n #1 +\exp_args:Nno \use:n { \cs_new:Npn \tl_tail:n #1 } { - \__kernel_exp_not:w + \exp_after:wN \__kernel_exp_not:w \tl_if_blank:nTF {#1} { { } } { \exp_after:wN { \use_none:n #1 } } @@ -2961,6 +2900,9 @@ % \begin{macro}[pTF]{\tl_if_head_eq_charcode:nN} % \begin{macro}[pTF]{\tl_if_head_eq_charcode:fN} % \begin{macro}[pTF]{\tl_if_head_eq_catcode:nN} +% \begin{macro}[pTF]{\tl_if_head_eq_catcode:oN} +% \begin{macro}[EXP]{\@@_head_exp_not:w} +% \begin{macro}[EXP]{\@@_if_head_eq_empty_arg:w} % Accessing the first token of a token list is tricky in three cases: % when it has category code $1$ (begin-group token), when it is an % explicit space, with category code $10$ and character code $32$, or @@ -2980,21 +2922,17 @@ % cases, the first token is a character, and since we only care about % its character code, we can use \cs{str_head:n} to access it (this % works even if it is a space character). An empty argument -% results in \cs{tl_head:w} leaving two tokens: |?| which is taken in -% the \cs{if_charcode:w} test, and \cs{use_none:nn}, which ensures -% that \cs{prg_return_false:} is returned regardless of whether the -% charcode test was \texttt{true} or \texttt{false}. +% results in \cs{tl_head:w} leaving two token: |^| and +% \cs{@@_if_head_eq_empty_arg:w} which will result in the \cs{if_charcode:w} +% test being false and remove \cs{exp_not:N} and |#2|. % \begin{macrocode} \prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 { p , T , F , TF } { \if_charcode:w - \exp_not:N #2 \tl_if_head_is_N_type:nTF { #1 ? } - { - \exp_after:wN \exp_not:N - \@@_tl_head:w #1 { ? \use_none:nn } \s_@@_stop - } + { \@@_head_exp_not:w #1 { ^ \@@_if_head_eq_empty_arg:w } \s_@@_stop } { \str_head:n {#1} } + \exp_not:N #2 \prg_return_true: \else: \prg_return_false: @@ -3008,24 +2946,20 @@ % first token is a begin-group token or an explicit space token, and % produce the relevant token, either \cs{c_group_begin_token} or % \cs{c_space_token}. Again, for an empty argument, a hack is used, -% removing \cs{prg_return_true:} and \cs{else:} with \cs{use_none:nn} -% in case the catcode test with the (arbitrarily chosen) |?| is -% \texttt{true}. +% removing the token given by the user and leaving two tokens in the input +% stream which will make the \cs{if_catcode:w} test return \texttt{false}. % \begin{macrocode} \prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1 #2 { p , T , F , TF } { \if_catcode:w - \exp_not:N #2 \tl_if_head_is_N_type:nTF { #1 ? } - { - \exp_after:wN \exp_not:N - \@@_tl_head:w #1 { ? \use_none:nn } \s_@@_stop - } + { \@@_head_exp_not:w #1 { ^ \@@_if_head_eq_empty_arg:w } \s_@@_stop } { \tl_if_head_is_group:nTF {#1} - { \c_group_begin_token } - { \c_space_token } + \c_group_begin_token + \c_space_token } + \exp_not:N #2 \prg_return_true: \else: \prg_return_false: @@ -3038,7 +2972,8 @@ % the normal case, use \cs{tl_head:w}, with no \cs{exp_not:N} this % time, since \cs{if_meaning:w} causes no expansion. With an empty % argument, the test is \texttt{true}, and \cs{use_none:nnn} removes -% |#2| and the usual \cs{prg_return_true:} and \cs{else:}. +% |#2| and \cs{prg_return_true:} and \cs{else:} (it is safe this way here as +% in this case \cs{prg_new_conditional:Npnn} didn't optimize these two away). % In the special cases, we know that the first token is a character, % hence \cs{if_charcode:w} and \cs{if_catcode:w} together are enough. % We combine them in some order, hopefully faster than the reverse. @@ -3048,8 +2983,8 @@ \prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 { p , T , F , TF } { \tl_if_head_is_N_type:nTF { #1 ? } - { \@@_if_head_eq_meaning_normal:nN } - { \@@_if_head_eq_meaning_special:nN } + \@@_if_head_eq_meaning_normal:nN + \@@_if_head_eq_meaning_special:nN {#1} #2 } \cs_new:Npn \@@_if_head_eq_meaning_normal:nN #1 #2 @@ -3064,11 +2999,11 @@ \cs_new:Npn \@@_if_head_eq_meaning_special:nN #1 #2 { \if_charcode:w \str_head:n {#1} \exp_not:N #2 - \exp_after:wN \use:n + \exp_after:wN \use_ii:nn \else: \prg_return_false: - \exp_after:wN \use_none:n \fi: + \use_none:n { \if_catcode:w \exp_not:N #2 \tl_if_head_is_group:nTF {#1} @@ -3081,48 +3016,79 @@ } } % \end{macrocode} +% +% Both \cs{tl_if_head_eq_charcode:nN} and \cs{tl_if_head_eq_catcode:nN} will +% need to get the first token of their argument and apply \cs{exp_not:N} to +% it. \cs{@@_head_exp_not:w} does exactly that. +% \begin{macrocode} +\cs_new:Npn \@@_head_exp_not:w #1 #2 \s_@@_stop + { \exp_not:N #1 } +% \end{macrocode} +% +% If the argument of \cs{tl_if_head_eq_charcode:nN} and +% \cs{tl_if_head_eq_catcode:nN} was empty \cs{@@_if_head_eq_empty_arg:w} will +% be left in the input stream. This macro has to remove \cs{exp_not:N} and +% the following token from the input stream to make sure no unbalanced +% if-construct is created and leave tokens there which make the two tests +% return \texttt{false}. +% \begin{macrocode} +\cs_new:Npn \@@_if_head_eq_empty_arg:w \exp_not:N #1 + { ? } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}[pTF]{\tl_if_head_is_N_type:n} -% \begin{macro}[EXP]{\@@_if_head_is_N_type:w} +% \begin{macro}[EXP] +% { +% \@@_if_head_is_N_type_auxi:w , +% \@@_if_head_is_N_type_auxii:nn , +% \@@_if_head_is_N_type_auxiii:n +% } % A token list can be empty, can start with an explicit space % character (catcode 10 and charcode 32), can start with a begin-group % token (catcode 1), or start with an \texttt{N}-type argument. In -% the first two cases, the line involving \cs{@@_if_head_is_N_type:w} -% produces~|^| (and otherwise nothing). In the third case -% (begin-group token), the lines involving \cs{exp_after:wN} produce a +% the first two cases, the line involving \cs{@@_if_head_is_N_type_auxi:w} +% produces~|f| (and otherwise nothing). In the third case +% (begin-group token), the lines involving \cs{token_to_str:N} produce a % single closing brace. The category code test is thus true exactly % in the fourth case, which is what we want. One cannot optimize by -% moving one of the |*| to the beginning: if |#1| contains primitive -% conditionals, all of its occurrences must be dealt with before the -% \cs{if_catcode:w} tries to skip the \texttt{true} branch of the +% moving one of the \cs{scan_stop:} to the beginning: if |#1| contains +% primitive conditionals, all of its occurrences must be dealt with before +% the \cs{if:w} tries to skip the \texttt{true} branch of the % conditional. % \begin{macrocode} \prg_new_conditional:Npnn \tl_if_head_is_N_type:n #1 { p , T , F , TF } { - \if_catcode:w - \if_false: { \fi: \@@_if_head_is_N_type:w ? #1 ~ } - \exp_after:wN \use_none:n - \exp_after:wN { \exp_after:wN { \token_to_str:N #1 ? } } - * * + \if:w + \if_false: { \fi: \@@_if_head_is_N_type_auxi:w \prg_do_nothing: #1 ~ } + { \exp_after:wN { \token_to_str:N #1 } } + \scan_stop: \scan_stop: \prg_return_true: \else: \prg_return_false: \fi: } -\cs_new:Npn \@@_if_head_is_N_type:w #1 ~ +\exp_args:Nno \use:n { \cs_new:Npn \@@_if_head_is_N_type_auxi:w #1 ~ } { - \tl_if_empty:oTF { \use_none:n #1 } { ^ } { } - \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi: + \tl_if_empty:oTF { #1 } + { f \exp_after:wN \use_none:nn } + { \exp_after:wN \@@_if_head_is_N_type_auxii:n } + \exp_after:wN { \if_false: } \fi: } +\cs_new:Npn \@@_if_head_is_N_type_auxii:n #1 + { \exp_after:wN \use_none:n \exp_after:wN } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}[EXP,pTF]{\tl_if_head_is_group:n} +% \begin{macro}[EXP]{\@@_if_head_is_group_fi_false:w} % Pass the first token of |#1| through \cs{token_to_str:N}, then check % for the brace balance. The extra \texttt{?} caters for an empty % argument. This could be made faster, but we need all brace tricks @@ -3131,47 +3097,236 @@ % \begin{macrocode} \prg_new_conditional:Npnn \tl_if_head_is_group:n #1 { p , T , F , TF } { - \if_catcode:w + \if:w \exp_after:wN \use_none:n \exp_after:wN { \exp_after:wN { \token_to_str:N #1 ? } } - * * - \prg_return_false: - \else: + \scan_stop: \scan_stop: + \@@_if_head_is_group_fi_false:w + \fi: + \if_true: \prg_return_true: + \else: + \prg_return_false: \fi: } +\cs_new:Npn \@@_if_head_is_group_fi_false:w \fi: \if_true: { \fi: \if_false: } % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}[EXP,pTF]{\tl_if_head_is_space:n} % \begin{macro}[EXP]{\@@_if_head_is_space:w} % The auxiliary's argument is all that is before the first explicit -% space in |?#1?~|. If that is a single~|?| the test yields -% \texttt{true}. Otherwise, that is more than one token, and the test -% yields \texttt{false}. The work is done within braces (with an +% space in |\prg_do_nothing:#1?~|. If that is a single~|\prg_do_nothing:| the +% test yields \texttt{true}. Otherwise, that is more than one token, and the +% test yields \texttt{false}. The work is done within braces (with an % |\if_false: { \fi: ... }| construction) both to hide potential % alignment tab characters from \TeX{} in a table, and to allow for -% removing what remains of the token list after its first space. The -% \cs{exp:w} and \cs{exp_end:} ensure that the result of a -% single step of expansion directly yields a balanced token list (no -% trailing closing brace). +% removing what remains of the token list after its first space. The use of +% \cs{if:w} ensures that the result of a single step of expansion directly +% yields a balanced token list (no trailing closing brace). % \begin{macrocode} \prg_new_conditional:Npnn \tl_if_head_is_space:n #1 { p , T , F , TF } { - \exp:w \if_false: { \fi: - \@@_if_head_is_space:w ? #1 ? ~ } + \if:w + \if_false: { \fi: \@@_if_head_is_space:w \prg_do_nothing: #1 ? ~ } + \scan_stop: \scan_stop: + \prg_return_true: + \else: + \prg_return_false: + \fi: } -\cs_new:Npn \@@_if_head_is_space:w #1 ~ +\exp_args:Nno \use:n { \cs_new:Npn \@@_if_head_is_space:w #1 ~ } { - \tl_if_empty:oTF { \use_none:n #1 } - { \exp_after:wN \exp_end: \exp_after:wN \prg_return_true: } - { \exp_after:wN \exp_end: \exp_after:wN \prg_return_false: } + \@@_if_empty_if:o {#1} \else: f \fi: \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi: } % \end{macrocode} % \end{macro} % \end{macro} % +% \subsection{Token by token changes} +% +% \begin{variable}{\s_@@_act_stop} +% The \cs[no-index]{@@_act_\ldots{}} functions may be applied to any token list. +% Hence, we use a private quark, to allow any token, even quarks, +% in the token list. +% Only \cs{s_@@_act_stop} may not appear in the token lists manipulated by +% \cs{@@_act:NNNn} functions. +% \begin{macrocode} +\scan_new:N \s_@@_act_stop +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[EXP]{\@@_act:NNNn} +% \begin{macro}[EXP]{\@@_act_output:n, \@@_act_reverse_output:n} +% \begin{macro}[EXP]{\@@_act_loop:w} +% \begin{macro}[EXP]{\@@_act_normal:NwNNN} +% \begin{macro}[EXP]{\@@_act_group:nwNNN} +% \begin{macro}[EXP]{\@@_act_space:wwNNN} +% \begin{macro}[EXP]{\@@_act_end:w} +% \begin{macro}[EXP] +% { +% \@@_act_if_head_is_space:nTF, +% \@@_act_if_head_is_space:w, +% \@@_act_if_head_is_space_true:w +% } +% \begin{macro}[EXP]{\@@_use_none_delimit_by_q_act_stop:w} +% To help control the expansion, \cs{@@_act:NNNn} should always +% be preceeded by \cs{exp:w} and ends by producing \cs{exp_end:} +% once the result has been obtained. This way no internal token of it can be +% accidentally end up in the input stream. +% Because \cs{s_@@_act_stop} can't appear without braces around it in the +% argument~|#1| of \cs{@@_act_loop:w}, we can use this marker to set up a fast +% test for leading spaces. +% \begin{macrocode} +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new:Npn \@@_act_if_head_is_space:nTF ##1 + { + \@@_act_if_head_is_space:w + \s_@@_act_stop ##1 \s_@@_act_stop \@@_act_if_head_is_space_true:w + \s_@@_act_stop #1 \s_@@_act_stop \use_ii:nn + } + \cs_new:Npn \@@_act_if_head_is_space:w + ##1 \s_@@_act_stop #1 ##2 \s_@@_act_stop + {} + \cs_new:Npn \@@_act_if_head_is_space_true:w + \s_@@_act_stop #1 \s_@@_act_stop \use_ii:nn ##1 ##2 + {##1} + } +\@@_tmp:w { ~ } +% \end{macrocode} +% (We expand the definition \cs{@@_act_if_head_is_space:nTF} when +% setting up \cs{@@_act_loop:w}, so we can then undefine the auxiliary.) +% In the loop, we check how the token list begins and act +% accordingly. In the \enquote{group} case, we may have +% reached \cs{s_@@_act_stop}, the end of the list. Then +% leave \cs{exp_end:} and the result in the input stream, +% to terminate the expansion of \cs{exp:w}. +% Otherwise, apply the relevant function to the +% \enquote{arguments}, |#3| +% and to the head of the token list. Then repeat the loop. +% The scheme is the same if the token list starts with an |N|-type +% or with a space, making sure that +% \cs{@@_act_space:wwNNN} gobbles the space. +% \begin{macrocode} +\exp_args:Nnx \use:n { \cs_new:Npn \@@_act_loop:w #1 \s_@@_act_stop } + { + \exp_not:o { \@@_act_if_head_is_space:nTF {#1} } + \exp_not:N \@@_act_space:wwNNN + { + \exp_not:o { \tl_if_head_is_group:nTF {#1} } + \exp_not:N \@@_act_group:nwNNN + \exp_not:N \@@_act_normal:NwNNN + } + \exp_not:n {#1} \s_@@_act_stop + } +\cs_undefine:N \@@_act_if_head_is_space:nTF +\cs_new:Npn \@@_act_normal:NwNNN #1 #2 \s_@@_act_stop #3 + { + #3 #1 + \@@_act_loop:w #2 \s_@@_act_stop + #3 + } +\cs_new:Npn \@@_use_none_delimit_by_s_act_stop:w #1 \s_@@_act_stop { } +\cs_new:Npn \@@_act_end:wn #1 \@@_act_result:n #2 + { \group_align_safe_end: \exp_end: #2 } +\cs_new:Npn \@@_act_group:nwNNN #1 #2 \s_@@_act_stop #3#4#5 + { + \@@_use_none_delimit_by_s_act_stop:w #1 \@@_act_end:wn \s_@@_act_stop + #5 {#1} + \@@_act_loop:w #2 \s_@@_act_stop + #3 #4 #5 + } +\exp_last_unbraced:NNo + \cs_new:Npn \@@_act_space:wwNNN \c_space_tl #1 \s_@@_act_stop #2#3 + { + #3 + \@@_act_loop:w #1 \s_@@_act_stop + #2 #3 + } +% \end{macrocode} +% \cs{@@_act:NNNn} loops over tokens, groups, and spaces in |#4|. +% |{\s_@@_act_stop}| serves as the end of token list marker, the |?| after it +% avoids losing outer braces. The result is stored as an argument for the +% dummy function \cs{@@_act_result:n}. +% \begin{macrocode} +\cs_new:Npn \@@_act:NNNn #1#2#3#4 + { + \group_align_safe_begin: + \@@_act_loop:w #4 { \s_@@_act_stop } ? \s_@@_act_stop + #1 #3 #2 + \@@_act_result:n { } + } +% \end{macrocode} +% Typically, the output is done to the right of what was already output, +% using \cs{@@_act_output:n}, but for the \cs{@@_act_reverse} functions, +% it should be done to the left. +% \begin{macrocode} +\cs_new:Npn \@@_act_output:n #1 #2 \@@_act_result:n #3 + { #2 \@@_act_result:n { #3 #1 } } +\cs_new:Npn \@@_act_reverse_output:n #1 #2 \@@_act_result:n #3 + { #2 \@@_act_result:n { #1 #3 } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\tl_reverse:n, \tl_reverse:o, \tl_reverse:V} +% \begin{macro}[EXP]{\@@_reverse_normal:nN} +% \begin{macro}[EXP]{\@@_reverse_group_preserve:nn} +% \begin{macro}[EXP]{\@@_reverse_space:n} +% The goal here is to reverse without losing spaces nor braces. +% This is done using the general internal function \cs{@@_act:NNNn}. +% Spaces and \enquote{normal} tokens are output on the left of the current +% output. Grouped tokens are output to the left but without any reversal +% within the group. +% \begin{macrocode} +\cs_new:Npn \tl_reverse:n #1 + { + \__kernel_exp_not:w \exp_after:wN + { + \exp:w + \@@_act:NNNn + \@@_reverse_normal:N + \@@_reverse_group_preserve:n + \@@_reverse_space: + {#1} + } + } +\cs_generate_variant:Nn \tl_reverse:n { o , V } +\cs_new:Npn \@@_reverse_normal:N + { \@@_act_reverse_output:n } +\cs_new:Npn \@@_reverse_group_preserve:n #1 + { \@@_act_reverse_output:n { {#1} } } +\cs_new:Npn \@@_reverse_space: + { \@@_act_reverse_output:n { ~ } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_reverse:N, \tl_reverse:c, \tl_greverse:N, \tl_greverse:c} +% This reverses the list, leaving \cs{exp_stop_f:} in front, +% which stops the \texttt{f}-expansion. +% \begin{macrocode} +\cs_new_protected:Npn \tl_reverse:N #1 + { \__kernel_tl_set:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } } +\cs_new_protected:Npn \tl_greverse:N #1 + { \__kernel_tl_gset:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } } +\cs_generate_variant:Nn \tl_reverse:N { c } +\cs_generate_variant:Nn \tl_greverse:N { c } +% \end{macrocode} +% \end{macro} +% % \subsection{Using a single item} % % \begin{macro}{\tl_item:nn, \tl_item:Nn, \tl_item:cn} @@ -3373,7 +3528,10 @@ \cs_new_protected:Npn \@@_show:NN #1#2 { \__kernel_chk_defined:NT #2 - { \exp_args:Nx #1 { \token_to_str:N #2 = \exp_not:o {#2} } } + { + \exp_args:Ne #1 + { \token_to_str:N #2 = \__kernel_exp_not:w \exp_after:wN {#2} } + } } % \end{macrocode} % \end{macro} @@ -3459,6 +3617,12 @@ % \end{macrocode} % \end{variable} % +% We finally clean up a temporary control sequence that we have used at +% various points to set up some definitions. +% \begin{macrocode} +\cs_undefine:N \@@_tmp:w +% \end{macrocode} +% % \begin{macrocode} %</package> % \end{macrocode} diff --git a/macros/latex/contrib/l3kernel/l3token.dtx b/macros/latex/contrib/l3kernel/l3token.dtx index dabd6ea6ac..676c55747a 100644 --- a/macros/latex/contrib/l3kernel/l3token.dtx +++ b/macros/latex/contrib/l3kernel/l3token.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -692,6 +692,14 @@ % Tests if the \meta{token} is defined to be a mathchardef. % \end{function} % +% \begin{function}[EXP,pTF, added=2020-10-27]{\token_if_font_selection:N} +% \begin{syntax} +% \cs{token_if_font_selection_p:N} \meta{token} \\ +% \cs{token_if_font_selection:NTF} \meta{token} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{token} is defined to be a font selection command. +% \end{function} +% % \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_dim_register:N} % \begin{syntax} % \cs{token_if_dim_register_p:N} \meta{token} \\ @@ -1496,7 +1504,7 @@ \tl_put_right:Nn \l_@@_tmp_tl { ^^@ \if_false: } } \char_set_catcode_group_end:n { 0 } \tl_put_right:Nn \l_@@_tmp_tl { { \fi: \exp_not:N \or: ^^@ } % } - \tl_set:Nx \l_@@_tmp_tl { \l_@@_tmp_tl } + \__kernel_tl_set:Nx \l_@@_tmp_tl { \l_@@_tmp_tl } \char_set_catcode_math_toggle:n { 0 } \tl_put_right:Nn \l_@@_tmp_tl { \or: ^^@ } \char_set_catcode_alignment:n { 0 } @@ -2222,6 +2230,7 @@ % \@@_delimit_by_char":w, % \@@_delimit_by_count:w, % \@@_delimit_by_dimen:w, +% \@@_delimit_by_ font:w, % \@@_delimit_by_macro:w, % \@@_delimit_by_muskip:w, % \@@_delimit_by_skip:w, @@ -2233,6 +2242,9 @@ % argument delimited by a string, a second one delimited by % \cs{s_@@_stop}, and returns the first one and its delimiter. % This result is eventually compared to another string. +% Note that the ``font'' auxiliary is delimited by a space followed by +% ``\texttt{font}''. This avoids an unnecessary check for the +% \tn{font} primitive below. % \begin{macrocode} \group_begin: \cs_set_protected:Npn \@@_tmp:w #1 @@ -2247,6 +2259,7 @@ \@@_tmp:w { char" } \@@_tmp:w { count } \@@_tmp:w { dimen } +\@@_tmp:w { ~ font } \@@_tmp:w { macro } \@@_tmp:w { muskip } \@@_tmp:w { skip } @@ -2260,6 +2273,7 @@ % \token_if_chardef:N, \token_if_mathchardef:N, % \token_if_long_macro:N, % \token_if_protected_macro:N, \token_if_protected_long_macro:N, +% \token_if_font_selection:N, % \token_if_dim_register:N, \token_if_int_register:N, % \token_if_muskip_register:N, % \token_if_skip_register:N, \token_if_toks_register:N, @@ -2292,8 +2306,9 @@ % space after |\protected| but a space after |\long|, hence the % mixture of \cs{token_to_str:N} and \cs{tl_to_str:n}. % -% For the first five conditionals, \cs{cs_if_exist:cT} turns out to -% be \texttt{false}, and the code boils down to a string comparison +% For the first six conditionals, \cs{cs_if_exist:cT} turns out to +% be \texttt{false} (thanks to the leading space for \texttt{font}), +% and the code boils down to a string comparison % between the result of the auxiliary on the \tn{meaning} of the % conditional's argument~|####1|, and~|#3|. Both are evaluated at % run-time, as this is important to get the correct escape character. @@ -2348,6 +2363,7 @@ { \tl_to_str:n { \protected } macro } \@@_tmp:w { protected_long_macro } { macro } { \token_to_str:N \protected \tl_to_str:n { \long } macro } +\@@_tmp:w { font_selection } { ~ font } { select ~ font } \@@_tmp:w { dim_register } { dimen } { \token_to_str:N \dimen } \@@_tmp:w { int_register } { count } { \token_to_str:N \count } \@@_tmp:w { muskip_register } { muskip } { \token_to_str:N \muskip } diff --git a/macros/latex/contrib/l3kernel/l3unicode.dtx b/macros/latex/contrib/l3kernel/l3unicode.dtx index 644d30f90f..14467d9617 100644 --- a/macros/latex/contrib/l3kernel/l3unicode.dtx +++ b/macros/latex/contrib/l3kernel/l3unicode.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/source3.pdf b/macros/latex/contrib/l3kernel/source3.pdf Binary files differindex 43709c4c56..43048251a4 100644 --- a/macros/latex/contrib/l3kernel/source3.pdf +++ b/macros/latex/contrib/l3kernel/source3.pdf diff --git a/macros/latex/contrib/l3kernel/source3.tex b/macros/latex/contrib/l3kernel/source3.tex index 2d31c20423..f47fbf0233 100644 --- a/macros/latex/contrib/l3kernel/source3.tex +++ b/macros/latex/contrib/l3kernel/source3.tex @@ -53,7 +53,7 @@ for those people who are interested. {latex-team@latex-project.org}% }% } -\date{Released 2020-10-05} +\date{Released 2020-10-27} \pagenumbering{roman} \maketitle |