diff options
Diffstat (limited to 'Master/texmf-dist/source/latex')
96 files changed, 3364 insertions, 2186 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx index e66d06bdcbd..5383ac46247 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx @@ -2,7 +2,7 @@ % %% File: l3benchmark.dtx % -% Copyright (C) 2011,2012,2014-2019 The LaTeX3 Project +% Copyright (C) 2011,2012,2014-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -130,7 +130,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3benchmark}{2019-10-11}{} +\ProvidesExplPackage{l3benchmark}{2020-01-12}{} {L3 Experimental benchmarking} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.ins b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.ins index d925b01b148..ca4c280f820 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.ins +++ b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.ins @@ -2,7 +2,7 @@ File: l3benchmark.ins -Copyright (C) 2011,2018,2019 The LaTeX3 Project +Copyright (C) 2011,2018-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2018,2019 The LaTeX3 Project +Copyright (C) 2018-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx b/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx index 3d6aadc98da..f7418e117f6 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx @@ -2,7 +2,7 @@ % %% File: l3cctab.dtx % -% Copyright (C) 2018,2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -171,7 +171,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3cctab}{2019-10-11}{} +\ProvidesExplPackage{l3cctab}{2020-01-12}{} {L3 Experimental category code tables} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.ins b/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.ins index 3c7a9b05ae1..e968f1bf838 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.ins +++ b/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.ins @@ -2,7 +2,7 @@ File: l3cctab.ins -Copyright (C) 2018,2019 The LaTeX3 Project +Copyright (C) 2018-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2018,2019 The LaTeX3 Project +Copyright (C) 2018-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx index 16147a3fb2e..de6616acf3d 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx @@ -2,7 +2,7 @@ % %% File: l3color.dtx % -% Copyright (C) 2017-2019 The LaTeX3 Project +% Copyright (C) 2017-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -267,7 +267,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3color}{2019-10-11}{} +\ProvidesExplPackage{l3color}{2020-01-12}{} {L3 Experimental color support} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.ins b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.ins index ae12ed89b60..a2601a4fde1 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.ins +++ b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.ins @@ -2,7 +2,7 @@ File: l3color.ins -Copyright (C) 2017-2019 The LaTeX3 Project +Copyright (C) 2017-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2017-2019 The LaTeX3 Project +Copyright (C) 2017-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx index 6424fbe6a16..572b4f2192a 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx @@ -2,7 +2,7 @@ % %% File: l3draw-boxes.dtx % -% Copyright (C) 2018,2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx index e9b86fd30e0..53c221d69e2 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx @@ -2,7 +2,7 @@ % %% File: l3draw-layers.dtx % -% Copyright (C) 2019 The LaTeX3 Project +% Copyright (C) 2019,2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx index 442b158fbc0..846043faa45 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx @@ -2,7 +2,7 @@ % %% File: l3draw-paths.dtx % -% Copyright (C) 2018,2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -892,6 +892,7 @@ \bool_if:NT \l_@@_path_use_clip_bool { \@@_backend_clip: + \bool_set_false:N \l_draw_bb_update_bool \bool_lazy_or:nnF { \l_@@_path_use_fill_bool } { \l_@@_path_use_stroke_bool } diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx index 7c3749a956e..dccb1fb6772 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx @@ -2,7 +2,7 @@ % %% File: l3draw-points.dtx % -% Copyright (C) 2018,2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx index de1036ef526..704d80652ff 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx @@ -2,7 +2,7 @@ % %% File: l3draw-scopes.dtx % -% Copyright (C) 2018,2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx index 0b51687b9f5..ce3b8b1ac80 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx @@ -2,7 +2,7 @@ % %% File: l3draw-softpath.dtx % -% Copyright (C) 2018,2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx index 4bea6a4943c..658982a49b9 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx @@ -2,7 +2,7 @@ % %% File: l3draw-state.dtx % -% Copyright (C) 2018,2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx index 39873b59a22..bcfed707879 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx @@ -2,7 +2,7 @@ % %% File: l3draw-transforms.dtx % -% Copyright (C) 2018,2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx index 66b7b73f35e..0ce74688f42 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx @@ -2,7 +2,7 @@ % %% File: l3draw.dtx % -% Copyright(C) 2018,2019 The LaTeX3 Project +% Copyright(C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -110,7 +110,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -1146,7 +1146,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3draw}{2019-10-11}{} +\ProvidesExplPackage{l3draw}{2020-01-12}{} {L3 Experimental core drawing support} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins index 836d9a32d67..9b72ca17fd6 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins @@ -2,7 +2,7 @@ File: l3draw.ins -Copyright (C) 2018,2019 The LaTeX3 Project +Copyright (C) 2018-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2018,2019 The LaTeX3 Project +Copyright (C) 2018-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx index 8deb2335ed9..e877b69ca5f 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx @@ -2,7 +2,7 @@ % %% File: l3graphics.dtx % -% Copyright (C) 2017-2019 The LaTeX3 Project +% Copyright (C) 2017-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -241,7 +241,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3graphics}{2019-10-11}{} +\ProvidesExplPackage{l3graphics}{2020-01-12}{} {L3 Experimental graphics inclusion support} %</package> % \end{macrocode} @@ -577,7 +577,7 @@ \exp_args:Ne \@@_include_auxi:n { \exp_args:Ne \str_tail:n - { \str_fold_case:V \l_@@_ext_str } + { \str_foldcase:V \l_@@_ext_str } } } \cs_new_protected:Npn \graphics_include:nn #1#2 @@ -587,7 +587,7 @@ \file_get_full_name:nNTF {#1} \l_@@_name_tl { \exp_args:Ne \@@_include_auxi:n - { \str_fold_case:n {#1} } + { \str_foldcase:n {#1} } } { \__kernel_msg_error:nnn { graphics } { graphic-not-found } {#1} } \group_end: diff --git a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.ins b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.ins index 815535a352c..ef345b5969d 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.ins +++ b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.ins @@ -1,6 +1,6 @@ \iffalse meta-comment -File l3graphics.ins Copyright (C) 2017,2019 The LaTeX3 Project +File l3graphics.ins Copyright (C) 2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -32,7 +32,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2019 The LaTeX3 Project +Copyright (C) 2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx index 61ac10ef896..dc36f172faa 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx @@ -2,7 +2,7 @@ % %% File: l3pdf.dtx % -% Copyright(C) 2019 The LaTeX3 Project +% Copyright(C) 2019,2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -185,7 +185,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3pdf}{2019-10-11}{} +\ProvidesExplPackage{l3pdf}{2020-01-12}{} {L3 Experimental core PDF support} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.ins b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.ins index d39eefa1140..e325be4520a 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.ins +++ b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.ins @@ -2,7 +2,7 @@ File: l3pdf.ins -Copyright (C) 2019 The LaTeX3 Project +Copyright (C) 2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2019 The LaTeX3 Project +Copyright (C) 2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx index 03fd22c5ea7..af34128e5b7 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx @@ -2,7 +2,7 @@ % %% File: l3str-format.dtx % -% Copyright (C) 2012-2019 The LaTeX3 Project +% Copyright (C) 2012-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -48,7 +48,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -167,7 +167,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3str-format}{2019-10-11}{} +\ProvidesExplPackage{l3str-format}{2020-01-12}{} {L3 Experimental string formatting} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.ins b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.ins index d3f00364e1c..76fc36a116c 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.ins +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.ins @@ -2,7 +2,7 @@ File l3str.ins -Copyright (C) 2011-2017,2019 The LaTeX3 Project +Copyright (C) 2011-2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2011-2019 The LaTeX3 Project +Copyright (C) 2011-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx index f1aaa56c933..c166811e114 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx @@ -2,7 +2,7 @@ % %% File: l3sys-shell.dtx % -% Copyright (C) 2018,2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -136,7 +136,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3sys-shell}{2019-10-11}{} +\ProvidesExplPackage{l3sys-shell}{2020-01-12}{} {L3 Experimental system shell functions} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.ins b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.ins index acf3c1d7102..9ee35460cbd 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.ins +++ b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.ins @@ -2,7 +2,7 @@ File: l3sys-shell.ins -Copyright (C) 2018,2019 The LaTeX3 Project +Copyright (C) 2018-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2018,2019 The LaTeX3 Project +Copyright (C) 2018-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx index 7e3d89e7c2d..9f4aec0bcd9 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx @@ -2,7 +2,7 @@ % %% File: xcoffins.dtx % -% Copyright (C) 2010-2012,2014,2016-2019 The LaTeX3 Project +% Copyright (C) 2010-2012,2014,2016-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -56,7 +56,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -675,7 +675,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xcoffins}{2019-10-11}{} +\ProvidesExplPackage{xcoffins}{2020-01-12}{} {L3 Experimental design level coffins} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.ins b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.ins index 065cb5eae7f..52d5c24a449 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.ins +++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.ins @@ -2,7 +2,7 @@ File: xcoffins.ins -Copyright (C) 2010,2011,2012,2016,2017,2019 The LaTeX3 Project +Copyright (C) 2010,2011,2012,2016,2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2010-2019 The LaTeX3 Project +Copyright (C) 2010-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx index a4d768b05eb..14d9fc9e099 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx @@ -3,7 +3,7 @@ %% File: l3galley.dtx % % Copyright (C) 1999-2001,2004-2009 Frank Mittelbach -% (C) 2010-2019 The LaTeX3 Project +% (C) 2010-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -61,7 +61,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -687,7 +687,7 @@ % % \begin{macrocode} %<*package> -\ProvidesExplPackage{l3galley}{2019-10-11}{} +\ProvidesExplPackage{l3galley}{2020-01-12}{} {L3 Experimental galley code} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx index a0c9d83c802..5cd043a5e61 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx @@ -3,7 +3,7 @@ %% File: xgalley.dtx % % Copyright (C) 1999-2001,2004-2009 Frank Mittelbach -% (C) 2010-2012,2014,2016-2019 The LaTeX3 Project +% (C) 2010-2012,2014,2016-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -47,7 +47,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -734,7 +734,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xgalley}{2019-10-11}{} +\ProvidesExplPackage{xgalley}{2020-01-12}{} {L3 Experimental galley} \RequirePackage{xparse,xtemplate,l3galley} % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.ins b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.ins index 13388c46d8c..d0c89bcd2c9 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.ins +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.ins @@ -2,7 +2,7 @@ File: xgalley.ins -Copyright (C) 2010-2012,2016,2017,2019 The LaTeX3 Project +Copyright (C) 2010-2012,2016,2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2010-2019 The LaTeX3 Project +Copyright (C) 2010-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index 89d18df2987..7295b770db3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx @@ -2,7 +2,7 @@ % %% File: expl3.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -24,7 +24,7 @@ % %<*driver|generic|package|2ekernel> %</driver|generic|package|2ekernel> -\def\ExplFileDate{2019-11-07}% +\def\ExplFileDate{2020-01-12}% %<*driver> \documentclass[full]{l3doc} \usepackage{graphicx} @@ -51,7 +51,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -365,6 +365,23 @@ % distinguish variables from functions in the source when the |@@| % convention is used. % +% \subsubsection{Variables: declaration} +% +% In well-formed \pkg{expl3} code, variables should always be declared before +% assignment is attempted. This is true even for variable types where the +% underlying \TeX{} implementation will allow direct assignment. This applies +% both to setting directly (\cs{tl_set:Nn}, etc.) and to setting equal +% (\cs{tl_set_eq:NN}, etc.). +% +% To help programmers to adhere to this approach, the debugging option +% |check-declarations| may be given +% \begin{verbatim} +% \debug_on:n { check-declarations } +% \end{verbatim} +% and will issue an error whenever an assignment is made to a non-declared +% variable. There is a performance implication, so this option should only +% be used for testing. +% % \subsubsection{Variables: scope and type} % % The \meta{scope} part of the name describes how the variable can be @@ -774,9 +791,8 @@ % \section{The distribution} % % At present, the \pkg{expl3} modules are designed to be loaded on top -% of \LaTeXe{}. In time, a \LaTeX3 format will be produced based on this -% code. This allows the code to be used in \LaTeXe{} packages \emph{now} -% while a stand-alone \LaTeX3 is developed. +% of \LaTeXe{}. In time, a \LaTeX3 format may be produced based on this +% code. % % \begin{bfseries} % While \pkg{expl3} is still experimental, the bundle is now regarded @@ -786,87 +802,29 @@ % \pkg{expl3}. % \end{bfseries} % -% New modules will be added to the distributed version of \pkg{expl3} -% as they reach maturity. At present, the \pkg{expl3} bundle consists -% of a number of modules, most of which are loaded by including the -% line: +% The distribution of \pkg{expl3} is split up into three packages on +% CTAN: \pkg{l3kernel}, \pkg{l3packages} and \pkg{l3experimental}. +% For historical reasons, % \begin{verbatim} % \RequirePackage{expl3} % \end{verbatim} -% in a \LaTeXe{} package, class or other file. The \pkg{expl3} modules -% regarded as stable, and therefore suitable for basing real code on, -% are as follows: -% -% \begin{description} -% \providecommand\explpkg[2]{\item[#1]#2} -% \explpkg{l3basics}{ -% This contains the basic definition modules used -% by the other packages. -% } -% \explpkg{l3box}{ -% Primitives for dealing with boxes. -% } -% \explpkg{l3clist}{ -% Methods for manipulating comma-separated token lists. -% } -% \explpkg{l3coffins}{ -% Augmented box constructs for alignment operations. -% } -% \explpkg{l3expan}{ -% This is the argument expansion module discussed earlier in this -% document. -% } -% \explpkg{l3int}{ -% This implements the integer data-type \texttt{int}. -% } -% \explpkg{l3keys}{ -% For processing lists of the form -% \texttt{\{ key1=val1 , key2=val2 \}}, intended to work -% as a \LaTeX3 version of \pkg{xkeyval}/\pkg{kvoptions}, although -% with input syntax more like that of \pkg{pgfkeys}. -% } -% \explpkg{l3msg}{ -% Communicating with the user: includes low-level hooks to allow -% messages to be filtered (higher-level interface for filtering -% to be written!). -% } -% \explpkg{l3names}{ -% This sets up the basic naming scheme and renames all -% the \TeX{} primitives. -% } -% \explpkg{l3prg}{ -% Program control structures such as boolean data type |bool|, generic -% do-while loops, and conditional flow. -% } -% \explpkg{l3prop}{ -% This implements the data-type for \enquote{property lists} that are used, in -% particular, for storing key/value pairs. -% } -% \explpkg{l3quark}{ -% A \enquote{quark} is a command that is defined to expand to -% itself! Therefore they must never be expanded as this would generate an -% infinite recursion; they do however have many uses, \emph{e.g.}~as -% special markers and delimiters within code. -% } -% \explpkg{l3seq}{ -% This implements data-types such as queues and stacks. -% } -% \explpkg{l3skip}{ -% Implements the \enquote{rubber length} datatype \texttt{skip}, the -% \enquote{rigid length} datatype |dim|, and the math mode -% \enquote{rubber length} datatype \texttt{muskip}. -% } -% \explpkg{l3tl}{ -% This implements a basic data-type, called a \textit{token-list -% variable} (|tl var.|), used for storing named token lists: these are -% \TeX{} macros with no arguments. -% } -% \explpkg{l3token}{ -% Analysing token lists and token streams, including peeking ahead to -% see what's coming next and inspecting tokens to detect which kind -% they are. -% } -% \end{description} +% loads the code now distributed as \pkg{l3kernel}. This monolithic +% package contains all of the modules regarded by the team as stable, +% and any changes in this code are very limited. This material is +% therefore suitable for use in third-party packages without concern +% about changes in support. All of this code is documented in +% \texttt{interface3.pdf}. +% +% The material in \pkg{l3packages} is also stable, but is not always +% at a programming level: most notably, \pkg{xparse} is stable and +% suitable for wider use. +% +% Finally, \pkg{l3experimental} contains modules ready for public use +% but not yet integrated into \pkg{l3kernel}. These modules have to +% be loaded explicitly. The team anticipate that all of these modules +% will move to stable status over time, but they may be more flexible +% in terms of interface and functionality detail. Feedback on these +% modules is extremely valuable. % % \section{Moving from \LaTeXe{} to \LaTeX3} % @@ -1171,7 +1129,7 @@ % \begin{macrocode} %<*2ekernel> \everyjob\expandafter{\the\everyjob - \message{expl3 <\ExplFileDate> L3 programming layer}% + \message{L3 programming layer <\ExplFileDate>}% } %</2ekernel> %<*!2ekernel> @@ -1322,13 +1280,17 @@ } % \end{macrocode} % -% A backend has to be in place by the start of the document. +% A backend has to be in place by the start of the document: this has to be +% before global options are checked for use. The odd group stuff avoids +% needing to actually patch \tn{document}. % \begin{macrocode} %<*2ekernel> -\AtBeginDocument +\tl_put_left:Nn \document { + \endgroup \str_if_exist:NF \c_sys_backend_str { \sys_load_backend:n { } } + \begingroup } %</2ekernel> %<*!2ekernel> diff --git a/Master/texmf-dist/source/latex/l3kernel/l3.ins b/Master/texmf-dist/source/latex/l3kernel/l3.ins index d9c7f2e6cf2..b509a2478f3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3.ins +++ b/Master/texmf-dist/source/latex/l3kernel/l3.ins @@ -2,7 +2,7 @@ File l3.ins -Copyright (C) 2011,2012,2014-2019 The LaTeX3 Project +Copyright (C) 2011,2012,2014-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -35,7 +35,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 1990-2019 The LaTeX3 Project +Copyright (C) 1990-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of @@ -104,6 +104,8 @@ and all files in that bundle must be distributed together. \from{l3coffins.dtx} {package} \from{l3luatex.dtx} {package,tex} \from{l3unicode.dtx} {package} + \from{l3text.dtx} {package} + \from{l3text-case.dtx} {package} \from{l3candidates.dtx} {package} \from{l3legacy.dtx} {package} \from{l3deprecation.dtx}{package,kernel} @@ -149,7 +151,7 @@ and all files in that bundle must be distributed together. \def\MetaPrefix{--} \preamble -Copyright (C) 1990-2019 The LaTeX3 Project +Copyright (C) 1990-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx index 86076bb8f0b..e3f88dfc947 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx @@ -2,7 +2,7 @@ % %% File: l3alloc.dtx % -% Copyright (C) 1990-2012,2014-2019 The LaTeX3 Project +% Copyright (C) 1990-2012,2014-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index aea1d1fbadb..7814fd30898 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx index 7066d5132eb..c503774a49a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx index 55915ae8592..16f74edd990 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx @@ -2,7 +2,7 @@ % %% File: l3box.dtx % -% Copyright (C) 2005-2019 The LaTeX3 Project +% Copyright (C) 2005-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx index 4e859699e05..adb399f9da1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx @@ -2,7 +2,7 @@ % %% File: l3candidates.dtx % -% Copyright (C) 2012-2019 The LaTeX3 Project +% Copyright (C) 2012-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -369,6 +369,47 @@ % conversely: sets it to the inverse of its current value. % \end{function} % +% \begin{function}[added = 2019-02-10, EXP, noTF] +% {\bool_case_true:n, \bool_case_false:n} +% \begin{syntax} +% \cs{bool_case_true:nTF} \\ +% ~~|{| \\ +% ~~~~\Arg{boolexpr case_1} \Arg{code case_1} \\ +% ~~~~\Arg{boolexpr case_2} \Arg{code case_2} \\ +% ~~~~\ldots \\ +% ~~~~\Arg{boolexpr case_n} \Arg{code case_n} \\ +% ~~|}| \\ +% ~~\Arg{true code} +% ~~\Arg{false code} +% \end{syntax} +% Evaluates in turn each of the \meta{boolean expression cases} until +% the first one that evaluates to \texttt{true} or to \texttt{false}, +% for \cs{bool_case_true:n} and \cs{bool_case_false:n}, respectively. +% The \meta{code} associated to this first case is left in the input +% stream, followed by the \meta{true code}, and other cases are +% discarded. If none of the cases match then only the \meta{false +% code} is inserted. The functions \cs{bool_case_true:n} and +% \cs{bool_case_false:n}, which do nothing if there is no match, are +% also available. For example +% \begin{verbatim} +% \bool_case_true:nF +% { +% { \dim_compare_p:n { \l__mypkg_wd_dim <= 10pt } } +% { Fits } +% { \int_compare_p:n { \l__mypkg_total_int >= 10 } } +% { Many } +% { \l__mypkg_special_bool } +% { Special } +% } +% { No idea! } +% \end{verbatim} +% leaves \enquote{\texttt{Fits}} or \enquote{\texttt{Many}} or +% \enquote{\texttt{Special}} or \enquote{\texttt{No idea!}} in the +% input stream, in a way similar to some other language's +% \enquote{\texttt{if} \ldots\ \texttt{elseif} \ldots\ \texttt{elseif} \ldots\ +% \texttt{else} \ldots}. +% \end{function} +% % \section{Additions to \pkg{l3prop}} % % \begin{function}[EXP, added = 2016-12-06] @@ -534,200 +575,6 @@ % % \section{Additions to \pkg{l3tl}} % -% \begin{function}[EXP, added = 2014-06-30, updated = 2016-01-12] -% { -% \tl_lower_case:n, \tl_upper_case:n, \tl_mixed_case:n, -% \tl_lower_case:nn, \tl_upper_case:nn, \tl_mixed_case:nn -% } -% \begin{syntax} -% \cs{tl_upper_case:n} \Arg{tokens} -% \cs{tl_upper_case:nn} \Arg{language} \Arg{tokens} -% \end{syntax} -% These functions are intended to be applied to input which may be -% regarded broadly as \enquote{text}. They traverse the \meta{tokens} and -% change the case of characters as discussed below. The character code of -% the characters replaced may be arbitrary: the replacement characters -% have standard document-level category codes ($11$ for letters, $12$ for -% letter-like characters which can also be case-changed). Begin-group and -% end-group characters in the \meta{tokens} are normalized and become |{| -% and |}|, respectively. -% -% Importantly, notice that these functions are intended for working with -% user text for typesetting. For case changing programmatic data see the -% \pkg{l3str} module and discussion there of \cs{str_lower_case:n}, -% \cs{str_upper_case:n} and \cs{str_fold_case:n}. -% \end{function} -% -% The functions perform expansion on the input in most cases. In particular, -% input in the form of token lists or expandable functions is expanded -% \emph{unless} it falls within one of the special handling classes described -% below. This expansion approach means that in general the result of case -% changing matches the \enquote{natural} outcome expected from a -% \enquote{functional} approach to case modification. For example -% \begin{verbatim} -% \tl_set:Nn \l_tmpa_tl { hello } -% \tl_upper_case:n { \l_tmpa_tl \c_space_tl world } -% \end{verbatim} -% produces -% \begin{verbatim} -% HELLO WORLD -% \end{verbatim} -% The expansion approach taken means that in package mode any \LaTeXe{} -% \enquote{robust} commands which may appear in the input should be converted -% to engine-protected versions using for example the \tn{robustify} command -% from the \pkg{etoolbox} package. -% -% \begin{variable}{\l_tl_case_change_math_tl} -% Case changing does not take place within math mode material so for example -% \begin{verbatim} -% \tl_upper_case:n { Some~text~$y = mx + c$~with~{Braces} } -% \end{verbatim} -% becomes -% \begin{verbatim} -% SOME TEXT $y = mx + c$ WITH {BRACES} -% \end{verbatim} -% Material inside math mode is left entirely unchanged: in particular, no -% expansion is undertaken. -% -% Detection of math mode is controlled by the list of tokens in -% \cs{l_tl_case_change_math_tl}, which should be in open--close pairs. In -% package mode the standard settings is -% \begin{verbatim} -% $ $ \( \) -% \end{verbatim} -% -% Note that while expansion occurs when searching the text it does not -% apply to math mode material (which should be unaffected by case changing). -% As such, whilst the opening token for math mode may be \enquote{hidden} -% inside a command/macro, the closing one cannot be as this is being -% searched for in math mode. Typically, in the types of \enquote{text} -% the case changing functions are intended to apply to this should not be -% an issue. -% \end{variable} -% -% \begin{variable}{\l_tl_case_change_exclude_tl} -% Case changing can be prevented by using any command on the list -% \cs{l_tl_case_change_exclude_tl}. Each entry should be a function -% to be followed by one argument: the latter will be preserved as-is -% with no expansion. Thus for example following -% \begin{verbatim} -% \tl_put_right:Nn \l_tl_case_change_exclude_tl { \NoChangeCase } -% \end{verbatim} -% the input -% \begin{verbatim} -% \tl_upper_case:n -% { Some~text~$y = mx + c$~with~\NoChangeCase {Protection} } -% \end{verbatim} -% will result in -% \begin{verbatim} -% SOME TEXT $y = mx + c$ WITH \NoChangeCase {Protection} -% \end{verbatim} -% Notice that the case changing mapping preserves the inclusion of -% the escape functions: it is left to other code to provide suitable -% definitions (typically equivalent to \cs{use:n}). In particular, the -% result of case changing is returned protected by \cs{exp_not:n}. -% -% When used with \LaTeXe{} the commands |\cite|, |\ensuremath|, |\label| -% and |\ref| are automatically included in the list for exclusion from -% case changing. -% \end{variable} -% -% \begin{variable}{\l_tl_case_change_accents_tl} -% This list specifies accent commands which should be left unexpanded -% in the output. This allows for example -% \begin{verbatim} -% \tl_upper_case:n { \" { a } } -% \end{verbatim} -% to yield -% \begin{verbatim} -% \" { A } -% \end{verbatim} -% irrespective of the expandability of |\"|. -% -% The standard contents of this variable is |\"|, |\'|, |\.|, |\^|, |\`|, -% |\~|, |\c|, |\H|, |\k|, |\r|, |\t|, |\u| and |\v|. -% \end{variable} -% -% \enquote{Mixed} case conversion may be regarded informally as converting the -% first character of the \meta{tokens} to upper case and the rest to lower -% case. However, the process is more complex than this as there are some -% situations where a single lower case character maps to a special form, for -% example \texttt{ij} in Dutch which becomes \texttt{IJ}. As such, -% \cs[index=tl_mixed_case:n]{tl_mixed_case:n(n)} -% implement a more sophisticated mapping which accounts -% for this and for modifying accents on the first letter. Spaces at the start -% of the \meta{tokens} are ignored when finding the first \enquote{letter} for -% conversion. -% \begin{verbatim} -% \tl_mixed_case:n { hello~WORLD } % => "Hello world" -% \tl_mixed_case:n { ~hello~WORLD } % => " Hello world" -% \tl_mixed_case:n { {hello}~WORLD } % => "{Hello} world" -% \end{verbatim} -% When finding the first \enquote{letter} for this process, any content in -% math mode or covered by \cs{l_tl_case_change_exclude_tl} is ignored. -% -% (Note that the Unicode Consortium describe this as \enquote{title case}, but -% that in English title case applies on a word-by-word basis. The -% \enquote{mixed} case implemented here is a lower level concept needed for -% both \enquote{title} and \enquote{sentence} casing of text.) -% -% \begin{variable}{\l_tl_mixed_case_ignore_tl} -% The list of characters to ignore when searching for the first -% \enquote{letter} in mixed-casing is determined by -% \cs{l_tl_mixed_change_ignore_tl}. This has the standard setting -% \begin{verbatim} -% ( [ { ` - -% \end{verbatim} -% where comparisons are made on a character basis. -% \end{variable} -% -% As is generally true for \pkg{expl3}, these functions are designed to -% work with Unicode input only. As such, UTF-8 input is assumed for -% \emph{all} engines. When used with \XeTeX{} or \LuaTeX{} a full range of -% Unicode transformations are enabled. Specifically, the standard mappings -% here follow those defined by the \href{http://www.unicode.org}^^A -% {Unicode Consortium} in \texttt{UnicodeData.txt} and -% \texttt{SpecialCasing.txt}. In the case of $8$-bit engines, mappings -% are provided for characters which can be represented in output typeset -% using the |T1| font encoding. Thus for example |ä| can be case-changed -% using \pdfTeX{}. For \pTeX{} only the ASCII range is covered as the -% engine treats input outside of this range as east Asian. -% -% Context-sensitive mappings are enabled: language-dependent cases are -% discussed below. Context detection expands input but treats any -% unexpandable control sequences as \enquote{failures} to match a context. -% -% Language-sensitive conversions are enabled using the \meta{language} -% argument, and follow Unicode Consortium guidelines. Currently, the -% languages recognised for special handling are as follows. -% \begin{itemize} -% \item Azeri and Turkish (\texttt{az} and \texttt{tr}). -% The case pairs I/i-dotless and I-dot/i are activated for these -% languages. The combining dot mark is removed when lower -% casing I-dot and introduced when upper casing i-dotless. -% \item German (\texttt{de-alt}). -% An alternative mapping for German in which the lower case -% \emph{Eszett} maps to a \emph{gro\ss{}es Eszett}. -% \item Lithuanian (\texttt{lt}). -% The lower case letters i and j should retain a dot above when the -% accents grave, acute or tilde are present. This is implemented for -% lower casing of the relevant upper case letters both when input as -% single Unicode codepoints and when using combining accents. The -% combining dot is removed when upper casing in these cases. Note that -% \emph{only} the accents used in Lithuanian are covered: the behaviour -% of other accents are not modified. -% \item Dutch (\texttt{nl}). -% Capitalisation of \texttt{ij} at the beginning of mixed cased -% input produces \texttt{IJ} rather than \texttt{Ij}. The output -% retains two separate letters, thus this transformation \emph{is} -% available using \pdfTeX{}. -% \end{itemize} -% -% Creating additional context-sensitive mappings requires knowledge -% of the underlying mapping implementation used here. The team are happy -% to add these to the kernel where they are well-documented -% (\emph{e.g.}~in Unicode Consortium or relevant government publications). -% % \begin{function}[EXP, added = 2017-07-15] % { % \tl_range_braced:Nnn, \tl_range_braced:cnn, \tl_range_braced:nnn, @@ -848,38 +695,28 @@ % (\enquote{active}), and character code $32$ (space). % \end{variable} % -% \begin{function}[added = 2018-04-06, updated = 2019-05-03, EXP] -% { -% \char_lower_case:N, \char_upper_case:N, -% \char_mixed_case:N, \char_fold_case:N, -% \char_str_lower_case:N, \char_str_upper_case:N, -% \char_str_mixed_case:N, \char_str_fold_case:N, -% } +% \begin{function}[added = 2020-01-09, EXP]{\char_to_utfviii_bytes:n} % \begin{syntax} -% \cs{char_lower_case:N} \meta{char} -% \end{syntax} -% Converts the \meta{char} to the equivalent case-changed character -% as detailed by the function name (see \cs{str_fold_case:n} -% and \cs{tl_mixed_case:n} for details of these terms). The case mapping -% is carried out with no context-dependence (\emph{cf.}~\cs{tl_upper_case:n}, -% \emph{etc.}) The \texttt{str} versions always generate \enquote{other} -% (category code $12$) characters, whilst the standard versions generate -% characters with the currently-active category code (\emph{i.e.}~as if -% the character had been read directly here). -% \end{function} -% -% \begin{function}[added = 2018-06-01, EXP]{\char_codepoint_to_bytes:n} -% \begin{syntax} -% \cs{char_codepoint_to_bytes:n} \Arg{codepoint} +% \cs{char_to_utfviii_bytes:n} \Arg{codepoint} % \end{syntax} % Converts the (Unicode) \meta{codepoint} to UTF-8 bytes. The expansion % of this function comprises four brace groups, each of which will contain % a hexadecimal value: the appropriate byte. As UTF-8 is a variable-length, -% one or more of the grouos may be empty: the bytes read in the logical order, +% one or more of the groups may be empty: the bytes read in the logical order, % such that a two-byte codepoint will have groups |#1| and |#2| filled % and |#3| and |#4| empty. % \end{function} % +% \begin{function}[added = 2020-01-02, rEXP]{\char_to_nfd:N} +% \begin{syntax} +% \cs{char_to_nfd:N} \meta{char} +% \end{syntax} +% Converts the \meta{char} to the Unicode Normalization Form Canonical +% Decomposition. The category code of the generated character is the +% same as the \meta{char}. With $8$-bit engines, no change is made to the +% character. +% \end{function} +% % \begin{function}[added = 2018-09-23] % { % \peek_catcode_collect_inline:Nn, @@ -1238,6 +1075,52 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP, noTF]{\bool_case_true:n, \bool_case_false:n} +% \begin{macro}{\@@_case:NnTF} +% \begin{macro}{\@@_case_true:w, \@@_case_false:w, \@@_case_end:nw} +% For boolean cases the overall idea is the same as for +% \cs{tl_case:nn(TF)} as described in \pkg{l3tl}. +% \begin{macrocode} +\cs_new:Npn \bool_case_true:nTF + { \exp:w \@@_case:NnTF \c_true_bool } +\cs_new:Npn \bool_case_true:nT #1#2 + { \exp:w \@@_case:NnTF \c_true_bool {#1} {#2} { } } +\cs_new:Npn \bool_case_true:nF #1 + { \exp:w \@@_case:NnTF \c_true_bool {#1} { } } +\cs_new:Npn \bool_case_true:n #1 + { \exp:w \@@_case:NnTF \c_true_bool {#1} { } { } } +\cs_new:Npn \bool_case_false:nTF + { \exp:w \@@_case:NnTF \c_false_bool } +\cs_new:Npn \bool_case_false:nT #1#2 + { \exp:w \@@_case:NnTF \c_false_bool {#1} {#2} { } } +\cs_new:Npn \bool_case_false:nF #1 + { \exp:w \@@_case:NnTF \c_false_bool {#1} { } } +\cs_new:Npn \bool_case_false:n #1 + { \exp:w \@@_case:NnTF \c_false_bool {#1} { } { } } +\cs_new:Npn \@@_case:NnTF #1#2#3#4 + { + \bool_if:NTF #1 \@@_case_true:w \@@_case_false:w + #2 #1 { } \q_mark {#3} \q_mark {#4} \q_stop + } +\cs_new:Npn \@@_case_true:w #1#2 + { + \bool_if:nTF {#1} + { \@@_case_end:nw {#2} } + { \@@_case_true:w } + } +\cs_new:Npn \@@_case_false:w #1#2 + { + \bool_if:nTF {#1} + { \@@_case_false:w } + { \@@_case_end:nw {#2} } + } +\cs_new:Npn \@@_case_end:nw #1#2#3 \q_mark #4#5 \q_stop + { \exp_end: #1 #4 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Additions to \pkg{l3prop}} % % \begin{macrocode} @@ -1544,1616 +1427,12 @@ % \end{macro} % \end{macro} % -% \subsection{Additions to \pkg{l3tl}} -% -% \subsubsection{Unicode case changing} -% -% The mechanisms needed for case changing are somewhat involved, particularly -% to allow for all of the special cases. These functions also require the -% appropriate data extracted from the Unicode documentation (either manually -% or automatically). -% -% First, some code which \enquote{belongs} in \pkg{l3tokens} but has to come -% here. -% \begin{macrocode} -%<@@=char> -% \end{macrocode} -% -% \begin{macro}[EXP] -% { -% \char_lower_case:N, \char_upper_case:N, -% \char_mixed_case:N, \char_fold_case:N -% } -% \begin{macro}[EXP]{\@@_change_case:nNN} -% \begin{macro}[EXP]{\@@_change_case:nN} -% \begin{macro}[EXP]{\@@_change_case_multi:nN, \@@_change_case_multi:vN} -% \begin{macro}[EXP]{\@@_change_case_multi:NNNNw} -% \begin{macro}[EXP]{\@@_change_case:NNN} -% \begin{macro}[EXP]{\@@_change_case:NNNN} -% \begin{macro}[EXP]{\@@_change_case:NN} -% \begin{macro}[EXP]{\@@_change_case_catcode:N} -% \begin{macro}[EXP] -% { -% \char_str_lower_case:N, \char_str_upper_case:N, -% \char_str_mixed_case:N, \char_str_fold_case:N -% } -% \begin{macro}[EXP]{\@@_str_change_case:nNN} -% \begin{macro}[EXP]{\@@_str_change_case:nN} -% Expandable character generation is done using a two-part approach. -% First, see if the current character has a special mapping for the current -% transformation. If it does, insert that. Otherwise, use the \TeX{} data -% to look up the one-to-one mapping, and generate the appropriate character -% with the appropriate category code. Mixed case needs an extra step as it -% may be special-cased or might be a special upper case outcome. The internal -% when using non-Unicode engines has to be set up to only do anything -% with ASCII characters. -% -% To ensure that the category codes produced are predictable, every character -% is re-generated even if it is otherwise unchanged. This makes life a little -% interesting when we might have multiple output characters: we have to -% grab each of them and case change them in reverse order to maintain -% \texttt{f}-type expandability. -% \begin{macrocode} -\cs_new:Npn \char_lower_case:N #1 - { \@@_change_case:nNN { lower } \char_value_lccode:n #1 } -\cs_new:Npn \char_upper_case:N #1 - { \@@_change_case:nNN { upper } \char_value_uccode:n #1 } -\cs_new:Npn \char_mixed_case:N #1 - { - \tl_if_exist:cTF { c_@@_mixed_case_ \token_to_str:N #1 _tl } - { - \@@_change_case_multi:vN - { c_@@_mixed_case_ \token_to_str:N #1 _tl } #1 - } - { \char_upper_case:N #1 } - } -\cs_new:Npn \char_fold_case:N #1 - { \@@_change_case:nNN { fold } \char_value_lccode:n #1 } -\cs_new:Npn \@@_change_case:nNN #1#2#3 - { - \tl_if_exist:cTF { c_@@_ #1 _case_ \token_to_str:N #3 _tl } - { - \@@_change_case_multi:vN - { c_@@_ #1 _case_ \token_to_str:N #3 _tl } #3 - } - { \exp_args:Nf \@@_change_case:nN { #2 { `#3 } } #3 } - } -\cs_new:Npn \@@_change_case:nN #1#2 - { - \int_compare:nNnTF {#1} = 0 - { #2 } - { \char_generate:nn {#1} { \@@_change_case_catcode:N #2 } } - } -\cs_new:Npn \@@_change_case_multi:nN #1#2 - { \@@_change_case_multi:NNNNw #2 #1 \q_no_value \q_no_value \q_stop } -\cs_generate_variant:Nn \@@_change_case_multi:nN { v } -\cs_new:Npn \@@_change_case_multi:NNNNw #1#2#3#4#5 \q_stop - { - \quark_if_no_value:NTF #4 - { - \quark_if_no_value:NTF #3 - { \@@_change_case:NN #1 #2 } - { \@@_change_case:NNN #1 #2#3 } - } - { \@@_change_case:NNNN #1 #2#3#4 } - } -\cs_new:Npn \@@_change_case:NNN #1#2#3 - { - \exp_args:Nnf \use:nn - { \@@_change_case:NN #1 #2 } - { \@@_change_case:NN #1 #3 } - } -\cs_new:Npn \@@_change_case:NNNN #1#2#3#4 - { - \exp_args:Nnff \use:nnn - { \@@_change_case:NN #1 #2 } - { \@@_change_case:NN #1 #3 } - { \@@_change_case:NN #1 #4 } - } -\cs_new:Npn \@@_change_case:NN #1#2 - { \char_generate:nn { `#2 } { \@@_change_case_catcode:N #1 } } -\cs_new:Npn \@@_change_case_catcode:N #1 - { - \if_catcode:w \exp_not:N #1 \c_math_toggle_token - 3 - \else: - \if_catcode:w \exp_not:N #1 \c_alignment_token - 4 - \else: - \if_catcode:w \exp_not:N #1 \c_math_superscript_token - 7 - \else: - \if_catcode:w \exp_not:N #1 \c_math_subscript_token - 8 - \else: - \if_catcode:w \exp_not:N #1 \c_space_token - 10 - \else: - \if_catcode:w \exp_not:N #1 \c_catcode_letter_token - 11 - \else: - \if_catcode:w \exp_not:N #1 \c_catcode_other_token - 12 - \else: - 13 - \fi: - \fi: - \fi: - \fi: - \fi: - \fi: - \fi: - } -% \end{macrocode} -% Same story for the string version, except category code is easier -% to follow. This of course makes this version significantly faster. -% \begin{macrocode} -\cs_new:Npn \char_str_lower_case:N #1 - { \@@_str_change_case:nNN { lower } \char_value_lccode:n #1 } -\cs_new:Npn \char_str_upper_case:N #1 - { \@@_str_change_case:nNN { upper } \char_value_uccode:n #1 } -\cs_new:Npn \char_str_mixed_case:N #1 - { - \tl_if_exist:cTF { c_@@_mixed_case_ \token_to_str:N #1 _tl } - { \tl_to_str:c { c_@@_mixed_case_ \token_to_str:N #1 _tl } } - { \char_str_upper_case:N #1 } - } -\cs_new:Npn \char_str_fold_case:N #1 - { \@@_str_change_case:nNN { fold } \char_value_lccode:n #1 } -\cs_new:Npn \@@_str_change_case:nNN #1#2#3 - { - \tl_if_exist:cTF { c_@@_ #1 _case_ \token_to_str:N #3 _tl } - { \tl_to_str:c { c_@@_ #1 _case_ \token_to_str:N #3 _tl } } - { \exp_args:Nf \@@_str_change_case:nN { #2 { `#3 } } #3 } - } -\cs_new:Npn \@@_str_change_case:nN #1#2 - { - \int_compare:nNnTF {#1} = 0 - { \tl_to_str:n {#2} } - { \char_generate:nn {#1} { 12 } } - } -\cs_if_exist:NF \tex_Uchar:D - { - \cs_set:Npn \@@_str_change_case:nN #1#2 - { \tl_to_str:n {#2} } - } -% \end{macrocode} -% \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]{\char_codepoint_to_bytes:n} -% \begin{macro}[EXP]{\@@_codepoint_to_bytes_auxi:n} -% \begin{macro}[EXP]{\@@_codepoint_to_bytes_auxii:Nnn} -% \begin{macro}[EXP]{\@@_codepoint_to_bytes_auxiii:n} -% \begin{macro}[EXP] -% { -% \@@_codepoint_to_bytes_outputi:nw , -% \@@_codepoint_to_bytes_outputii:nw , -% \@@_codepoint_to_bytes_outputiii:nw , -% \@@_codepoint_to_bytes_outputiv:nw -% } -% \begin{macro}[EXP] -% {\@@_codepoint_to_bytes_output:nnn, \@@_codepoint_to_bytes_output:fnn} -% \begin{macro}[EXP]{\@@_codepoint_to_bytes_end:} -% This code converts a codepoint into the correct UTF-8 representation. -% In terms of the algorithm itself, see -% \url{https://en.wikipedia.org/wiki/UTF-8} for the octet pattern. -% \begin{macrocode} -\cs_new:Npn \char_codepoint_to_bytes:n #1 - { - \exp_args:Nf \@@_codepoint_to_bytes_auxi:n - { \int_eval:n {#1} } - } -\cs_new:Npn \@@_codepoint_to_bytes_auxi:n #1 - { - \if_int_compare:w #1 > "80 \exp_stop_f: - \if_int_compare:w #1 < "800 \exp_stop_f: - \@@_codepoint_to_bytes_outputi:nw - { \@@_codepoint_to_bytes_auxii:Nnn C {#1} { 64 } } - \@@_codepoint_to_bytes_outputii:nw - { \@@_codepoint_to_bytes_auxiii:n {#1} } - \else: - \if_int_compare:w #1 < "10000 \exp_stop_f: - \@@_codepoint_to_bytes_outputi:nw - { \@@_codepoint_to_bytes_auxii:Nnn E {#1} { 64 * 64 } } - \@@_codepoint_to_bytes_outputii:nw - { - \@@_codepoint_to_bytes_auxiii:n - { \int_div_truncate:nn {#1} { 64 } } - } - \@@_codepoint_to_bytes_outputiii:nw - { \@@_codepoint_to_bytes_auxiii:n {#1} } - \else: - \@@_codepoint_to_bytes_outputi:nw - { - \@@_codepoint_to_bytes_auxii:Nnn F - {#1} { 64 * 64 * 64 } - } - \@@_codepoint_to_bytes_outputii:nw - { - \@@_codepoint_to_bytes_auxiii:n - { \int_div_truncate:nn {#1} { 64 * 64 } } - } - \@@_codepoint_to_bytes_outputiii:nw - { - \@@_codepoint_to_bytes_auxiii:n - { \int_div_truncate:nn {#1} { 64 } } - } - \@@_codepoint_to_bytes_outputiv:nw - { \@@_codepoint_to_bytes_auxiii:n {#1} } - \fi: - \fi: - \else: - \@@_codepoint_to_bytes_outputi:nw {#1} - \fi: - \@@_codepoint_to_bytes_end: { } { } { } { } - } -\cs_new:Npn \@@_codepoint_to_bytes_auxii:Nnn #1#2#3 - { "#10 + \int_div_truncate:nn {#2} {#3} } -\cs_new:Npn \@@_codepoint_to_bytes_auxiii:n #1 - { \int_mod:nn {#1} { 64 } + 128 } -\cs_new:Npn \@@_codepoint_to_bytes_outputi:nw - #1 #2 \@@_codepoint_to_bytes_end: #3 - { \@@_codepoint_to_bytes_output:fnn { \int_eval:n {#1} } { } {#2} } -\cs_new:Npn \@@_codepoint_to_bytes_outputii:nw - #1 #2 \@@_codepoint_to_bytes_end: #3#4 - { \@@_codepoint_to_bytes_output:fnn { \int_eval:n {#1} } { {#3} } {#2} } -\cs_new:Npn \@@_codepoint_to_bytes_outputiii:nw - #1 #2 \@@_codepoint_to_bytes_end: #3#4#5 - { - \@@_codepoint_to_bytes_output:fnn - { \int_eval:n {#1} } { {#3} {#4} } {#2} - } -\cs_new:Npn \@@_codepoint_to_bytes_outputiv:nw - #1 #2 \@@_codepoint_to_bytes_end: #3#4#5#6 - { - \@@_codepoint_to_bytes_output:fnn - { \int_eval:n {#1} } { {#3} {#4} {#5} } {#2} - } -\cs_new:Npn \@@_codepoint_to_bytes_output:nnn #1#2#3 - { - #3 - \@@_codepoint_to_bytes_end: #2 {#1} - } -\cs_generate_variant:Nn \@@_codepoint_to_bytes_output:nnn { f } -\cs_new:Npn \@@_codepoint_to_bytes_end: { } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} +% \subsubsection{Building a token list} % % \begin{macrocode} %<@@=tl> % \end{macrocode} % -% \begin{macro}[EXP]{\tl_lower_case:n, \tl_upper_case:n, \tl_mixed_case:n} -% \begin{macro}[EXP]{\tl_lower_case:nn, \tl_upper_case:nn, \tl_mixed_case:nn} -% The user level functions here are all wrappers around the internal -% functions for case changing. -% \begin{macrocode} -\cs_new:Npn \tl_lower_case:n { \@@_change_case:nnn { lower } { } } -\cs_new:Npn \tl_upper_case:n { \@@_change_case:nnn { upper } { } } -\cs_new:Npn \tl_mixed_case:n { \@@_change_case:nnn { mixed } { } } -\cs_new:Npn \tl_lower_case:nn { \@@_change_case:nnn { lower } } -\cs_new:Npn \tl_upper_case:nn { \@@_change_case:nnn { upper } } -\cs_new:Npn \tl_mixed_case:nn { \@@_change_case:nnn { mixed } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\@@_change_case:nnn} -% \begin{macro}[EXP]{\@@_change_case_aux:nnn} -% \begin{macro}[EXP]{\@@_change_case_loop:wnn} -% \begin{macro}[EXP] -% { -% \@@_change_case_output:nwn , -% \@@_change_case_output:Vwn , -% \@@_change_case_output:own , -% \@@_change_case_output:vwn , -% \@@_change_case_output:fwn , -% } -% \begin{macro}[EXP]{\@@_change_case_end:wn} -% \begin{macro}[EXP]{\@@_change_case_group:nwnn} -% \begin{macro}[EXP] -% { -% \@@_change_case_group_lower:nnnn , -% \@@_change_case_group_upper:nnnn , -% \@@_change_case_group_mixed:nnnn -% } -% \begin{macro}[EXP]{\@@_change_case_space:wnn} -% \begin{macro}[EXP]{\@@_change_case_N_type:Nwnn} -% \begin{macro}[EXP]{\@@_change_case_N_type:NNNnnn} -% \begin{macro}[EXP]{\@@_change_case_math:NNNnnn} -% \begin{macro}[EXP]{\@@_change_case_math_loop:wNNnn} -% \begin{macro}[EXP]{\@@_change_case_math:NwNNnn} -% \begin{macro}[EXP]{\@@_change_case_math_group:nwNNnn} -% \begin{macro}[EXP]{\@@_change_case_math_space:wNNnn} -% \begin{macro}[EXP]{\@@_change_case_N_type:Nnnn} -% \begin{macro}[EXP] -% { -% \@@_change_case_char_lower:Nnn , -% \@@_change_case_char_upper:Nnn , -% \@@_change_case_char_mixed:Nnn -% } -% \begin{macro}[EXP]{\@@_change_case_char:nN} -% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nNN} -% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nNNN} -% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nNNNN} -% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nn} -% \begin{macro}[EXP]{\@@_change_case_cs_letterlike:Nn} -% \begin{macro}[EXP]{\@@_change_case_cs_letterlike:NnN} -% \begin{macro}[EXP]{\@@_change_case_cs_accents:NN} -% \begin{macro}[EXP]{\@@_change_case_cs:N} -% \begin{macro}[EXP]{\@@_change_case_cs:NN} -% \begin{macro}[EXP]{\@@_change_case_cs:NNn} -% \begin{macro}[EXP]{\@@_change_case_protect:wNN} -% \begin{macro}[EXP]{\@@_change_case_if_expandable:NTF} -% \begin{macro}[EXP]{\@@_change_case_cs_expand:Nnw} -% \begin{macro}[EXP]{\@@_change_case_cs_expand:NN} -% \begin{macro}[EXP]{\@@_change_case_mixed_skip:N} -% \begin{macro}[EXP]{\@@_change_case_mixed_skip:NN} -% \begin{macro}[EXP]{\@@_change_case_mixed_skip_tidy:Nwn} -% \begin{macro}[EXP]{\@@_change_case_mixed_switch:w} -% The mechanism for the core conversion of case is based on the idea that -% we can use a loop to grab the entire token list plus a quark: the latter is -% used as an end marker and to avoid any brace stripping. Depending on the -% nature of the first item in the grabbed argument, it can either processed -% as a single token, treated as a group or treated as a space. These -% different cases all work by re-reading |#1| in the appropriate way, hence -% the repetition of |#1 \q_recursion_stop|. -% \begin{macrocode} -\cs_new:Npn \@@_change_case:nnn #1#2#3 - { - \__kernel_exp_not:w \exp_after:wN - { - \exp:w - \@@_change_case_aux:nnn {#1} {#2} {#3} - } - } -\cs_new:Npn \@@_change_case_aux:nnn #1#2#3 - { - \group_align_safe_begin: - \@@_change_case_loop:wnn - #3 \q_recursion_tail \q_recursion_stop {#1} {#2} - \@@_change_case_result:n { } - } -\cs_new:Npn \@@_change_case_loop:wnn #1 \q_recursion_stop - { - \tl_if_head_is_N_type:nTF {#1} - { \@@_change_case_N_type:Nwnn } - { - \tl_if_head_is_group:nTF {#1} - { \@@_change_case_group:nwnn } - { \@@_change_case_space:wnn } - } - #1 \q_recursion_stop - } -% \end{macrocode} -% Earlier versions of the code where only \texttt{x}-type expandable rather -% than \texttt{f}-type: this causes issues with nesting and so the slight -% performance hit is taken for a better outcome in usability terms. Setting -% up for \texttt{f}-type expandability has two requirements: a marker -% token after the main loop (see above) and a mechanism to \enquote{load} -% and finalise the result. That is handled in the code below, which includes -% the necessary material to end the \cs{exp:w} expansion. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_output:nwn #1#2 \@@_change_case_result:n #3 - { #2 \@@_change_case_result:n { #3 #1 } } -\cs_generate_variant:Nn \@@_change_case_output:nwn { V , o , v , f } -\cs_new:Npn \@@_change_case_end:wn #1 \@@_change_case_result:n #2 - { - \group_align_safe_end: - \exp_end: - #2 - } -% \end{macrocode} -% Handling for the cases where the current argument is a brace group or -% a space is relatively easy. For the brace case, the routine works -% recursively, using the expandability of the mechanism to ensure that the -% result is finalised before storage. For the space case it is simply a -% question of removing the space in the input and storing it in the output. -% In both cases, and indeed for the \texttt{N}-type grabber, after removing -% the current item from the input \cs{@@_change_case_loop:wnn} is inserted -% in front of the remaining tokens. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_group:nwnn #1#2 \q_recursion_stop #3#4 - { - \use:c { @@_change_case_group_ #3 : nnnn } {#1} {#2} {#3} {#4} - } -\cs_new:Npn \@@_change_case_group_lower:nnnn #1#2#3#4 - { - \@@_change_case_output:own - { - \exp_after:wN - { - \exp:w - \@@_change_case_aux:nnn {#3} {#4} {#1} - } - } - \@@_change_case_loop:wnn #2 \q_recursion_stop {#3} {#4} - } -\cs_new_eq:NN \@@_change_case_group_upper:nnnn - \@@_change_case_group_lower:nnnn -% \end{macrocode} -% For the \enquote{mixed} case, a group is taken as forcing a switch to lower -% casing. That means we need a separate auxiliary. (Tracking whether we have -% found a first character inside a group and transferring the information out -% looks pretty horrible.) -% \begin{macrocode} -\cs_new:Npn \@@_change_case_group_mixed:nnnn #1#2#3#4 - { - \@@_change_case_output:own - { - \exp_after:wN - { - \exp:w - \@@_change_case_aux:nnn {#3} {#4} {#1} - } - } - \@@_change_case_loop:wnn #2 \q_recursion_stop { lower } {#4} - } -\exp_last_unbraced:NNo \cs_new:Npn \@@_change_case_space:wnn \c_space_tl - { - \@@_change_case_output:nwn { ~ } - \@@_change_case_loop:wnn - } -% \end{macrocode} -% For \texttt{N}-type arguments there are several stages to the approach. -% First, a simply check for the end-of-input marker, which if found triggers -% the final clean up and output step. Assuming that is not the case, the -% first check is for math-mode escaping: this test can encompass control -% sequences or other \texttt{N}-type tokens so is handled up front. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_N_type:Nwnn #1#2 \q_recursion_stop - { - \quark_if_recursion_tail_stop_do:Nn #1 - { \@@_change_case_end:wn } - \exp_after:wN \@@_change_case_N_type:NNNnnn - \exp_after:wN #1 \l_tl_case_change_math_tl - \q_recursion_tail ? \q_recursion_stop {#2} - } -% \end{macrocode} -% Looking for math mode escape first requires a loop over the possible -% token pairs to see if the current input (|#1|) matches an open-math case -% (|#2|). If if does then this test loop is ended and a new input-gathering -% one is begun. The latter simply transfers material from the input to the -% output without any expansion, testing each \texttt{N}-type token to see -% if it matches the close-math case required. If that is the situation then -% the \enquote{math loop} stops and resumes the main loop: as that might -% be either the standard case-changing one or the mixed-case alternative, -% it is not hard-coded into the math loop but is rather passed as argument -% |#3| to \cs{@@_change_case_math:NNNnnn}. If no close-math token is found -% then the final clean-up is forced (\emph{i.e.}~there is no assumption -% of \enquote{well-behaved} input in terms of math mode). -% \begin{macrocode} -\cs_new:Npn \@@_change_case_N_type:NNNnnn #1#2#3 - { - \quark_if_recursion_tail_stop_do:Nn #2 - { \@@_change_case_N_type:Nnnn #1 } - \token_if_eq_meaning:NNTF #1 #2 - { - \use_i_delimit_by_q_recursion_stop:nw - { - \@@_change_case_math:NNNnnn - #1 #3 \@@_change_case_loop:wnn - } - } - { \@@_change_case_N_type:NNNnnn #1 } - } -\cs_new:Npn \@@_change_case_math:NNNnnn #1#2#3#4 - { - \@@_change_case_output:nwn {#1} - \@@_change_case_math_loop:wNNnn #4 \q_recursion_stop #2 #3 - } -\cs_new:Npn \@@_change_case_math_loop:wNNnn #1 \q_recursion_stop - { - \tl_if_head_is_N_type:nTF {#1} - { \@@_change_case_math:NwNNnn } - { - \tl_if_head_is_group:nTF {#1} - { \@@_change_case_math_group:nwNNnn } - { \@@_change_case_math_space:wNNnn } - } - #1 \q_recursion_stop - } -\cs_new:Npn \@@_change_case_math:NwNNnn #1#2 \q_recursion_stop #3#4 - { - \token_if_eq_meaning:NNTF \q_recursion_tail #1 - { \@@_change_case_end:wn } - { - \@@_change_case_output:nwn {#1} - \token_if_eq_meaning:NNTF #1 #3 - { #4 #2 \q_recursion_stop } - { \@@_change_case_math_loop:wNNnn #2 \q_recursion_stop #3#4 } - } - } -\cs_new:Npn \@@_change_case_math_group:nwNNnn #1#2 \q_recursion_stop - { - \@@_change_case_output:nwn { {#1} } - \@@_change_case_math_loop:wNNnn #2 \q_recursion_stop - } -\exp_last_unbraced:NNo - \cs_new:Npn \@@_change_case_math_space:wNNnn \c_space_tl - { - \@@_change_case_output:nwn { ~ } - \@@_change_case_math_loop:wNNnn - } -% \end{macrocode} -% Once potential math-mode cases are filtered out the next stage is to -% test if the token grabbed is a control sequence: they cannot be used in -% the lookup table and also may require expansion. At this stage the loop -% code starting \cs{@@_change_case_loop:wnn} is inserted: all subsequent -% steps in the code which need a look-ahead are coded to rely on this and -% thus have \texttt{w}-type arguments if they may do a look-ahead. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_N_type:Nnnn #1#2#3#4 - { - \token_if_cs:NTF #1 - { \@@_change_case_cs_letterlike:Nn #1 {#3} } - { \use:c { @@_change_case_char_ #3 :Nnn } #1 {#3} {#4} } - \@@_change_case_loop:wnn #2 \q_recursion_stop {#3} {#4} - } -% \end{macrocode} -% For character tokens there are some special cases to deal with then -% the majority of changes are covered by using the \TeX{} data as a lookup -% along with expandable character generation. This avoids needing a very -% large number of macros or (as seen in earlier versions) a somewhat tricky -% split of the characters into various blocks. Notice that the special case -% code may do a look-ahead so requires a final \texttt{w}-type argument -% whereas the core lookup table does not and also guarantees an output so -% \texttt{f}-type expansion may be used to obtain the case-changed result. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_char_lower:Nnn #1#2#3 - { - \cs_if_exist_use:cF { @@_change_case_ #2 _ #3 :Nnw } - { \use_ii:nn } - #1 - { - \use:c { @@_change_case_ #2 _ sigma:Nnw } #1 - { \@@_change_case_char:nN {#2} #1 } - } - } -\cs_new_eq:NN \@@_change_case_char_upper:Nnn - \@@_change_case_char_lower:Nnn -% \end{macrocode} -% For mixed case, the code is somewhat different: there is a need to -% look up both mixed and upper case chars and we have to cover the -% situation where there is a character to skip over. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_char_mixed:Nnn #1#2#3 - { - \@@_change_case_mixed_switch:w - \cs_if_exist_use:cF { @@_change_case_mixed_ #3 :Nnw } - { - \cs_if_exist_use:cF { @@_change_case_upper_ #3 :Nnw } - { \use_ii:nn } - } - #1 - { \@@_change_case_mixed_skip:N #1 } - } -% \end{macrocode} -% For Unicode engines we can handle all characters directly. However, for -% the $8$-bit engines the aim is to deal with (a subset of) Unicode (UTF-8) -% input. They deal with that by making the upper half of the range active, -% so we look for that and if found work out how many UTF-8 octets there -% are to deal with. Those can then be grabbed to reconstruct the full -% Unicode character, which is then used in a lookup. (As will become -% obvious below, there is no intention here of covering all of Unicode.) -% \begin{macrocode} -\bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_new:Npn \@@_change_case_char:nN #1#2 - { - \@@_change_case_output:fwn - { \use:c { char_ #1 _case:N } #2 } - } - } - { - \cs_new:Npn \@@_change_case_char:nN #1#2 - { - \int_compare:nNnTF { `#2 } > { "80 } - { - \int_compare:nNnTF { `#2 } < { "E0 } - { \@@_change_case_char_UTFviii:nNNN {#1} #2 } - { - \int_compare:nNnTF { `#2 } < { "F0 } - { \@@_change_case_char_UTFviii:nNNNN {#1} #2 } - { \@@_change_case_char_UTFviii:nNNNNN {#1} #2 } - } - } - { - \@@_change_case_output:fwn - { \use:c { char_ #1 _case:N } #2 } - } - } - } -% \end{macrocode} -% To allow for the special case of mixed case, we insert here a -% action-dependent auxiliary. -% \begin{macrocode} -\bool_lazy_or:nnF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_new:Npn \@@_change_case_char_UTFviii:nNNN #1#2#3#4 - { \@@_change_case_char_UTFviii:nnN {#1} {#2#4} #3 } - \cs_new:Npn \@@_change_case_char_UTFviii:nNNNN #1#2#3#4#5 - { \@@_change_case_char_UTFviii:nnN {#1} {#2#4#5} #3 } - \cs_new:Npn \@@_change_case_char_UTFviii:nNNNNN #1#2#3#4#5#6 - { \@@_change_case_char_UTFviii:nnN {#1} {#2#4#5#6} #3 } - \cs_new:Npn \@@_change_case_char_UTFviii:nnN #1#2#3 - { - \cs_if_exist:cTF { c_@@_ #1 _case_ \tl_to_str:n {#2} _tl } - { - \@@_change_case_output:vwn - { c_@@_ #1 _case_ \tl_to_str:n {#2} _tl } - } - { \@@_change_case_output:nwn {#2} } - #3 - } - } -% \end{macrocode} -% Before dealing with general control sequences there are the special -% ones to deal with. Letter-like control sequences are a simple look-up, -% while for accents the loop is much as done elsewhere. Notice that -% we have a no-op test to make sure there is no unexpected expansion of -% letter-like input. The split into two parts here allows us to insert -% the \enquote{switch} code for mixed casing. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_cs_letterlike:Nn #1#2 - { - \str_if_eq:nnTF {#2} { mixed } - { - \@@_change_case_cs_letterlike:NnN #1 { upper } - \@@_change_case_mixed_switch:w - } - { \@@_change_case_cs_letterlike:NnN #1 {#2} \prg_do_nothing: } - } -\cs_new:Npn \@@_change_case_cs_letterlike:NnN #1#2#3 - { - \cs_if_exist:cTF { c_@@_change_case_ #2 _ \token_to_str:N #1 _tl } - { - \@@_change_case_output:vwn - { c_@@_change_case_ #2 _ \token_to_str:N #1 _tl } - #3 - } - { - \cs_if_exist:cTF - { - c_@@_change_case_ - \str_if_eq:nnTF {#2} { lower } { upper } { lower } - _ \token_to_str:N #1 _tl - } - { - \@@_change_case_output:nwn {#1} - #3 - } - { - \exp_after:wN \@@_change_case_cs_accents:NN - \exp_after:wN #1 \l_tl_case_change_accents_tl - \q_recursion_tail \q_recursion_stop - } - } - } -\cs_new:Npn \@@_change_case_cs_accents:NN #1#2 - { - \quark_if_recursion_tail_stop_do:Nn #2 - { \@@_change_case_cs:N #1 } - \str_if_eq:nnTF {#1} {#2} - { - \use_i_delimit_by_q_recursion_stop:nw - { \@@_change_case_output:nwn {#1} } - } - { \@@_change_case_cs_accents:NN #1 } - } -% \end{macrocode} -% To deal with a control sequence there is first a need to test if it is -% on the list which indicate that case changing should be skipped. That's -% done using a loop as for the other special cases. If a hit is found then -% the argument is grabbed: that comes \emph{after} the loop function which -% is therefore rearranged. In a \LaTeXe{} context, \tn{protect} needs -% to be treated specially, to prevent expansion of the next token but -% output it without braces. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_cs:N #1 - { -%<*package> - \str_if_eq:nnTF {#1} { \protect } { \@@_change_case_protect:wNN } -%</package> - \exp_after:wN \@@_change_case_cs:NN - \exp_after:wN #1 \l_tl_case_change_exclude_tl - \q_recursion_tail \q_recursion_stop - } -\cs_new:Npn \@@_change_case_cs:NN #1#2 - { - \quark_if_recursion_tail_stop_do:Nn #2 - { - \@@_change_case_cs_expand:Nnw #1 - { \@@_change_case_output:nwn {#1} } - } - \str_if_eq:nnTF {#1} {#2} - { - \use_i_delimit_by_q_recursion_stop:nw - { \@@_change_case_cs:NNn #1 } - } - { \@@_change_case_cs:NN #1 } - } -\cs_new:Npn \@@_change_case_cs:NNn #1#2#3 - { - \@@_change_case_output:nwn { #1 {#3} } - #2 - } -%<*package> -\cs_new:Npn \@@_change_case_protect:wNN #1 \q_recursion_stop #2 #3 - { \@@_change_case_output:nwn { \protect #3 } #2 } -%</package> -% \end{macrocode} -% When a control sequence is not on the exclude list the other test if -% to see if it is expandable. Once again, if there is a hit then the loop -% function is grabbed as part of the clean-up and reinserted before the -% now expanded material. The test for expandability has to check for -% end-of-recursion as it is needed by the look-ahead code which might hit -% the end of the input. The test is done in two parts as \cs{bool_if:nTF} -% would choke if |#1| was |(|! -% \begin{macrocode} -\cs_new:Npn \@@_change_case_if_expandable:NTF #1 - { - \token_if_expandable:NTF #1 - { - \bool_lazy_any:nTF - { - { \token_if_eq_meaning_p:NN \q_recursion_tail #1 } - { \token_if_protected_macro_p:N #1 } - { \token_if_protected_long_macro_p:N #1 } - } - { \use_ii:nn } - { \use_i:nn } - } - { \use_ii:nn } - } -\cs_new:Npn \@@_change_case_cs_expand:Nnw #1#2 - { - \@@_change_case_if_expandable:NTF #1 - { \@@_change_case_cs_expand:NN #1 } - { #2 } - } -\cs_new:Npn \@@_change_case_cs_expand:NN #1#2 - { \exp_after:wN #2 #1 } -% \end{macrocode} -% For mixed case, there is an additional list of exceptions to deal with: -% once that is sorted, we can move on back to the main loop. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_mixed_skip:N #1 - { - \exp_after:wN \@@_change_case_mixed_skip:NN - \exp_after:wN #1 \l_tl_mixed_case_ignore_tl - \q_recursion_tail \q_recursion_stop - } -\cs_new:Npn \@@_change_case_mixed_skip:NN #1#2 - { - \quark_if_recursion_tail_stop_do:nn {#2} - { \@@_change_case_char:nN { mixed } #1 } - \int_compare:nNnT { `#1 } = { `#2 } - { - \use_i_delimit_by_q_recursion_stop:nw - { - \@@_change_case_output:nwn {#1} - \@@_change_case_mixed_skip_tidy:Nwn - } - } - \@@_change_case_mixed_skip:NN #1 - } -\cs_new:Npn \@@_change_case_mixed_skip_tidy:Nwn #1#2 \q_recursion_stop #3 - { - \@@_change_case_loop:wnn #2 \q_recursion_stop { mixed } - } -% \end{macrocode} -% Needed to switch from mixed to lower casing when we have found a -% first character in the former mode. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_mixed_switch:w - #1 \@@_change_case_loop:wnn #2 \q_recursion_stop #3 - { - #1 - \@@_change_case_loop:wnn #2 \q_recursion_stop { lower } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \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_lower_sigma:Nnw} -% \begin{macro}[EXP]{\@@_change_case_lower_sigma:w} -% \begin{macro}[EXP]{\@@_change_case_lower_sigma:Nw} -% \begin{macro}[EXP]{\@@_change_case_upper_sigma:Nnw} -% If the current char is an upper case sigma, the a check is made on the next -% item in the input. If it is \texttt{N}-type and not a control sequence -% then there is a look-ahead phase. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_lower_sigma:Nnw #1#2#3#4 \q_recursion_stop - { - \int_compare:nNnTF { `#1 } = { "03A3 } - { - \@@_change_case_output:fwn - { \@@_change_case_lower_sigma:w #4 \q_recursion_stop } - } - {#2} - #3 #4 \q_recursion_stop - } -\cs_new:Npn \@@_change_case_lower_sigma:w #1 \q_recursion_stop - { - \tl_if_head_is_N_type:nTF {#1} - { \@@_change_case_lower_sigma:Nw #1 \q_recursion_stop } - { \c_@@_final_sigma_tl } - } -\cs_new:Npn \@@_change_case_lower_sigma:Nw #1#2 \q_recursion_stop - { - \@@_change_case_if_expandable:NTF #1 - { - \exp_after:wN \@@_change_case_lower_sigma:w #1 - #2 \q_recursion_stop - } - { - \token_if_letter:NTF #1 - { \c_@@_std_sigma_tl } - { \c_@@_final_sigma_tl } - } - } -% \end{macrocode} -% Simply skip to the final step for upper casing. -% \begin{macrocode} -\cs_new_eq:NN \@@_change_case_upper_sigma:Nnw \use_ii:nn -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\@@_change_case_lower_tr:Nnw} -% \begin{macro}[EXP]{\@@_change_case_lower_tr_auxi:Nw} -% \begin{macro}[EXP]{\@@_change_case_lower_tr_auxii:Nw} -% \begin{macro}[EXP]{\@@_change_case_upper_tr:Nnw} -% \begin{macro}[EXP]{\@@_change_case_lower_az:Nnw} -% \begin{macro}[EXP]{\@@_change_case_upper_az:Nnw} -% The Turkic languages need special treatment for dotted-i and dotless-i. -% The lower casing rule can be expressed in terms of searching first for -% either a dotless-I or a dotted-I. In the latter case the mapping is -% easy, but in the former there is a second stage search. -% \begin{macrocode} -\bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_new:Npn \@@_change_case_lower_tr:Nnw #1#2 - { - \int_compare:nNnTF { `#1 } = { "0049 } - { \@@_change_case_lower_tr_auxi:Nw } - { - \int_compare:nNnTF { `#1 } = { "0130 } - { \@@_change_case_output:nwn { i } } - {#2} - } - } -% \end{macrocode} -% After a dotless-I there may be a dot-above character. If there is then -% a dotted-i should be produced, otherwise output a dotless-i. When the -% combination is found both the dotless-I and the dot-above char have to -% be removed from the input, which is done by the \cs{use_i:nn} -% (it grabs \cs{@@_change_case_loop:wn} and the dot-above char and -% discards the latter). -% \begin{macrocode} - \cs_new:Npn \@@_change_case_lower_tr_auxi:Nw #1#2 \q_recursion_stop - { - \tl_if_head_is_N_type:nTF {#2} - { \@@_change_case_lower_tr_auxii:Nw #2 \q_recursion_stop } - { \@@_change_case_output:Vwn \c_@@_dotless_i_tl } - #1 #2 \q_recursion_stop - } - \cs_new:Npn \@@_change_case_lower_tr_auxii:Nw #1#2 \q_recursion_stop - { - \@@_change_case_if_expandable:NTF #1 - { - \exp_after:wN \@@_change_case_lower_tr_auxi:Nw #1 - #2 \q_recursion_stop - } - { - \bool_lazy_or:nnTF - { \token_if_cs_p:N #1 } - { ! \int_compare_p:nNn { `#1 } = { "0307 } } - { \@@_change_case_output:Vwn \c_@@_dotless_i_tl } - { - \@@_change_case_output:nwn { i } - \use_i:nn - } - } - } - } -% \end{macrocode} -% For $8$-bit engines, dot-above is not available so there is a simple -% test for an upper-case I. Then we can look for the UTF-8 representation of -% an upper case dotted-I without the combining char. If it's not there, -% preserve the UTF-8 sequence as-is. -% \begin{macrocode} - { - \cs_new:Npn \@@_change_case_lower_tr:Nnw #1#2 - { - \int_compare:nNnTF { `#1 } = { "0049 } - { \@@_change_case_output:Vwn \c_@@_dotless_i_tl } - { - \int_compare:nNnTF { `#1 } = { 196 } - { \@@_change_case_lower_tr_auxi:Nw #1 {#2} } - {#2} - } - } - \cs_new:Npn \@@_change_case_lower_tr_auxi:Nw #1#2#3#4 - { - \int_compare:nNnTF { `#4 } = { 176 } - { - \@@_change_case_output:nwn { i } - #3 - } - { - #2 - #3 #4 - } - } - } -% \end{macrocode} -% Upper casing is easier: just one exception with no context. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_upper_tr:Nnw #1#2 - { - \int_compare:nNnTF { `#1 } = { "0069 } - { \@@_change_case_output:Vwn \c_@@_dotted_I_tl } - {#2} - } -% \end{macrocode} -% Straight copies. -% \begin{macrocode} -\cs_new_eq:NN \@@_change_case_lower_az:Nnw \@@_change_case_lower_tr:Nnw -\cs_new_eq:NN \@@_change_case_upper_az:Nnw \@@_change_case_upper_tr:Nnw -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\@@_change_case_lower_lt:Nnw} -% \begin{macro}[EXP]{\@@_change_case_lower_lt:nNnw} -% \begin{macro}[EXP]{\@@_change_case_lower_lt:nnw} -% \begin{macro}[EXP]{\@@_change_case_lower_lt:Nw} -% \begin{macro}[EXP]{\@@_change_case_lower_lt:NNw} -% \begin{macro}[EXP]{\@@_change_case_upper_lt:Nnw} -% \begin{macro}[EXP]{\@@_change_case_upper_lt:nnw} -% \begin{macro}[EXP]{\@@_change_case_upper_lt:Nw} -% \begin{macro}[EXP]{\@@_change_case_upper_lt:NNw} -% For Lithuanian, the issue to be dealt with is dots over lower case -% letters: these should be present if there is another accent. That means -% that there is some work to do when lower casing I and J. The first step -% is a simple match attempt: \cs{c_@@_accents_lt_tl} contains -% accented upper case letters which should gain a dot-above char in their -% lower case form. This is done using \texttt{f}-type expansion so only one -% pass is needed to find if it works or not. If there was no hit, the second -% stage is to check for I, J and I-ogonek, and if the current char is a -% match to look for a following accent. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_lower_lt:Nnw #1 - { - \exp_args:Nf \@@_change_case_lower_lt:nNnw - { \str_case:nVF #1 \c_@@_accents_lt_tl \exp_stop_f: } - #1 - } -\cs_new:Npn \@@_change_case_lower_lt:nNnw #1#2 - { - \tl_if_blank:nTF {#1} - { - \exp_args:Nf \@@_change_case_lower_lt:nnw - { - \int_case:nnF {`#2} - { - { "0049 } i - { "004A } j - { "012E } \c_@@_i_ogonek_tl - } - \exp_stop_f: - } - } - { - \@@_change_case_output:nwn {#1} - \use_none:n - } - } -\cs_new:Npn \@@_change_case_lower_lt:nnw #1#2 - { - \tl_if_blank:nTF {#1} - {#2} - { - \@@_change_case_output:nwn {#1} - \@@_change_case_lower_lt:Nw - } - } -% \end{macrocode} -% Grab the next char and see if it is one of the accents used in Lithuanian: -% if it is, add the dot-above char into the output. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_lower_lt:Nw #1#2 \q_recursion_stop - { - \tl_if_head_is_N_type:nT {#2} - { \@@_change_case_lower_lt:NNw } - #1 #2 \q_recursion_stop - } -\cs_new:Npn \@@_change_case_lower_lt:NNw #1#2#3 \q_recursion_stop - { - \@@_change_case_if_expandable:NTF #2 - { - \exp_after:wN \@@_change_case_lower_lt:Nw \exp_after:wN #1 #2 - #3 \q_recursion_stop - } - { - \bool_lazy_and:nnT - { ! \token_if_cs_p:N #2 } - { - \bool_lazy_any_p:n - { - { \int_compare_p:nNn { `#2 } = { "0300 } } - { \int_compare_p:nNn { `#2 } = { "0301 } } - { \int_compare_p:nNn { `#2 } = { "0303 } } - } - } - { \@@_change_case_output:Vwn \c_@@_dot_above_tl } - #1 #2#3 \q_recursion_stop - } - } -% \end{macrocode} -% For upper casing, the test required is for a dot-above char after an I, -% J or I-ogonek. First a test for the appropriate letter, and if found a -% look-ahead and potentially one token dropped. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_upper_lt:Nnw #1 - { - \exp_args:Nf \@@_change_case_upper_lt:nnw - { - \int_case:nnF {`#1} - { - { "0069 } I - { "006A } J - { "012F } \c_@@_I_ogonek_tl - } - \exp_stop_f: - } - } -\cs_new:Npn \@@_change_case_upper_lt:nnw #1#2 - { - \tl_if_blank:nTF {#1} - {#2} - { - \@@_change_case_output:nwn {#1} - \@@_change_case_upper_lt:Nw - } - } -\cs_new:Npn \@@_change_case_upper_lt:Nw #1#2 \q_recursion_stop - { - \tl_if_head_is_N_type:nT {#2} - { \@@_change_case_upper_lt:NNw } - #1 #2 \q_recursion_stop - } -\cs_new:Npn \@@_change_case_upper_lt:NNw #1#2#3 \q_recursion_stop - { - \@@_change_case_if_expandable:NTF #2 - { - \exp_after:wN \@@_change_case_upper_lt:Nw \exp_after:wN #1 #2 - #3 \q_recursion_stop - } - { - \bool_lazy_and:nnTF - { ! \token_if_cs_p:N #2 } - { \int_compare_p:nNn { `#2 } = { "0307 } } - { #1 } - { #1 #2 } - #3 \q_recursion_stop - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_change_case_upper_de-alt:Nnw} -% A simple alternative version for German. -% \begin{macrocode} -\cs_new:cpn { @@_change_case_upper_de-alt:Nnw } #1#2 - { - \int_compare:nNnTF { `#1 } = { 223 } - { \@@_change_case_output:Vwn \c_@@_upper_Eszett_tl } - {#2} - } -% \end{macrocode} -% \end{macro} -% -% \begin{variable} -% { -% \c_@@_std_sigma_tl , -% \c_@@_final_sigma_tl , -% \c_@@_accents_lt_tl , -% \c_@@_dot_above_tl , -% \c_@@_upper_Eszett_tl -% } -% The above needs various special token lists containing pre-formed characters. -% This set are only available in Unicode engines, with no-op definitions -% for $8$-bit use. -% \begin{macrocode} -\bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \group_begin: - \cs_set:Npn \@@_tmp:n #1 - { - \exp_after:wN \exp_after:wN \exp_after:wN \exp_not:N - \char_generate:nn {#1} { \char_value_catcode:n {#1} } - } - \tl_const:Nx \c_@@_std_sigma_tl { \@@_tmp:n { "03C3 } } - \tl_const:Nx \c_@@_final_sigma_tl { \@@_tmp:n { "03C2 } } - \tl_const:Nx \c_@@_accents_lt_tl - { - \@@_tmp:n { "00CC } - { - \@@_tmp:n { "0069 } - \@@_tmp:n { "0307 } - \@@_tmp:n { "0300 } - } - \@@_tmp:n { "00CD } - { - \@@_tmp:n { "0069 } - \@@_tmp:n { "0307 } - \@@_tmp:n { "0301 } - } - \@@_tmp:n { "0128 } - { - \@@_tmp:n { "0069 } - \@@_tmp:n { "0307 } - \@@_tmp:n { "0303 } - } - } - \tl_const:Nx \c_@@_dot_above_tl { \@@_tmp:n { "0307 } } - \tl_const:Nx \c_@@_upper_Eszett_tl { \@@_tmp:n { "1E9E } } - \group_end: - } - { - \tl_const:Nn \c_@@_std_sigma_tl { } - \tl_const:Nn \c_@@_final_sigma_tl { } - \tl_const:Nn \c_@@_accents_lt_tl { } - \tl_const:Nn \c_@@_dot_above_tl { } - \tl_const:Nn \c_@@_upper_Eszett_tl { } - } -% \end{macrocode} -% \end{variable} -% \begin{variable} -% { -% \c_@@_dotless_i_tl , -% \c_@@_dotted_I_tl , -% \c_@@_i_ogonek_tl , -% \c_@@_I_ogonek_tl , -% } -% For cases where there is an $8$-bit option in the |T1| font set up, -% a variant is provided in both cases. -% \begin{macrocode} -\group_begin: - \bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_set_protected:Npn \@@_tmp:w #1#2 - { - \tl_const:Nx #1 - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn - {"#2} { \char_value_catcode:n {"#2} } - } - } - } - { - \cs_set_protected:Npn \@@_tmp:w #1#2 - { - \group_begin: - \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4 - { - \tl_const:Nx #1 - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {##1} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {##2} { 13 } - } - } - \tl_set:Nx \l_@@_internal_a_tl - { \char_codepoint_to_bytes:n {"#2} } - \exp_after:wN \@@_tmp:w \l_@@_internal_a_tl - \group_end: - } - } - \@@_tmp:w \c_@@_dotless_i_tl { 0131 } - \@@_tmp:w \c_@@_dotted_I_tl { 0130 } - \@@_tmp:w \c_@@_i_ogonek_tl { 012F } - \@@_tmp:w \c_@@_I_ogonek_tl { 012E } -\group_end: -% \end{macrocode} -% \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 -% 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. -% \begin{macrocode} -\group_begin: - \bool_lazy_or:nnF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_set_protected:Npn \@@_loop:nn #1#2 - { - \quark_if_recursion_tail_stop:n {#1} - \tl_set:Nx \l_@@_internal_a_tl - { - \char_codepoint_to_bytes:n {"#1} - \char_codepoint_to_bytes:n {"#2} - } - \exp_after:wN \@@_tmp:w \l_@@_internal_a_tl - \@@_loop:nn - } - \cs_set_protected:Npn \@@_tmp:nnnn #1#2#3#4#5 - { - \tl_const:cx - { - c_@@_ #1 _case_ - \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 {#4} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#5} { 13 } - } - } - \cs_set_protected:Npn \@@_tmp:w #1#2#3#4#5#6#7#8 - { - \tl_const:cx - { - c_@@_lower_case_ - \char_generate:nn {#1} { 12 } - \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 } - } - \@@_tmp:nnnn { upper } {#5} {#6} {#1} {#2} - \@@_tmp:nnnn { mixed } {#5} {#6} {#1} {#2} - } - \@@_loop:nn - { 00C0 } { 00E0 } - { 00C2 } { 00E2 } - { 00C3 } { 00E3 } - { 00C4 } { 00E4 } - { 00C5 } { 00E5 } - { 00C6 } { 00E6 } - { 00C7 } { 00E7 } - { 00C8 } { 00E8 } - { 00C9 } { 00E9 } - { 00CA } { 00EA } - { 00CB } { 00EB } - { 00CC } { 00EC } - { 00CD } { 00ED } - { 00CE } { 00EE } - { 00CF } { 00EF } - { 00D0 } { 00F0 } - { 00D1 } { 00F1 } - { 00D2 } { 00F2 } - { 00D3 } { 00F3 } - { 00D4 } { 00F4 } - { 00D5 } { 00F5 } - { 00D6 } { 00F6 } - { 00D8 } { 00F8 } - { 00D9 } { 00F9 } - { 00DA } { 00FA } - { 00DB } { 00FB } - { 00DC } { 00FC } - { 00DD } { 00FD } - { 00DE } { 00FE } - { 0100 } { 0101 } - { 0102 } { 0103 } - { 0104 } { 0105 } - { 0106 } { 0107 } - { 0108 } { 0109 } - { 010A } { 010B } - { 010C } { 010D } - { 010E } { 010F } - { 0110 } { 0111 } - { 0112 } { 0113 } - { 0114 } { 0115 } - { 0116 } { 0117 } - { 0118 } { 0119 } - { 011A } { 011B } - { 011C } { 011D } - { 011E } { 011F } - { 0120 } { 0121 } - { 0122 } { 0123 } - { 0124 } { 0125 } - { 0128 } { 0129 } - { 012A } { 012B } - { 012C } { 012D } - { 012E } { 012F } - { 0132 } { 0133 } - { 0134 } { 0135 } - { 0136 } { 0137 } - { 0139 } { 013A } - { 013B } { 013C } - { 013E } { 013F } - { 0141 } { 0142 } - { 0143 } { 0144 } - { 0145 } { 0146 } - { 0147 } { 0148 } - { 014A } { 014B } - { 014C } { 014D } - { 014E } { 014F } - { 0150 } { 0151 } - { 0152 } { 0153 } - { 0154 } { 0155 } - { 0156 } { 0157 } - { 0158 } { 0159 } - { 015A } { 015B } - { 015C } { 015D } - { 015E } { 015F } - { 0160 } { 0161 } - { 0162 } { 0163 } - { 0164 } { 0165 } - { 0168 } { 0169 } - { 016A } { 016B } - { 016C } { 016D } - { 016E } { 016F } - { 0170 } { 0171 } - { 0172 } { 0173 } - { 0174 } { 0175 } - { 0176 } { 0177 } - { 0178 } { 00FF } - { 0179 } { 017A } - { 017B } { 017C } - { 017D } { 017E } - { 01CD } { 01CE } - { 01CF } { 01D0 } - { 01D1 } { 01D2 } - { 01D3 } { 01D4 } - { 01E2 } { 01E3 } - { 01E6 } { 01E7 } - { 01E8 } { 01E9 } - { 01EA } { 01EB } - { 01F4 } { 01F5 } - { 0218 } { 0219 } - { 021A } { 021B } - \q_recursion_tail ? - \q_recursion_stop - \cs_set_protected:Npn \@@_tmp:w #1#2#3 - { - \group_begin: - \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4 - { - \tl_const:cx - { - c_@@_ #3 _case_ - \char_generate:nn {##1} { 12 } - \char_generate:nn {##2} { 12 } - _tl - } - {#2} - } - \tl_set:Nx \l_@@_internal_a_tl - { \char_codepoint_to_bytes:n { "#1 } } - \exp_after:wN \@@_tmp:w \l_@@_internal_a_tl - \group_end: - } - \@@_tmp:w { 00DF } { SS } { upper } - \@@_tmp:w { 00DF } { Ss } { mixed } - \@@_tmp:w { 0131 } { I } { upper } - } - \group_end: -% \end{macrocode} -% -% The (fixed) look-up mappings for letter-like control sequences. -% \begin{macrocode} -\group_begin: - \cs_set_protected:Npn \@@_change_case_setup:NN #1#2 - { - \quark_if_recursion_tail_stop:N #1 - \tl_const:cn { c_@@_change_case_lower_ \token_to_str:N #1 _tl } - { #2 } - \tl_const:cn { c_@@_change_case_upper_ \token_to_str:N #2 _tl } - { #1 } - \@@_change_case_setup:NN - } - \@@_change_case_setup:NN - \AA \aa - \AE \ae - \DH \dh - \DJ \dj - \IJ \ij - \L \l - \NG \ng - \O \o - \OE \oe - \SS \ss - \TH \th - \q_recursion_tail ? - \q_recursion_stop - \tl_const:cn { c_@@_change_case_upper_ \token_to_str:N \i _tl } { I } - \tl_const:cn { c_@@_change_case_upper_ \token_to_str:N \j _tl } { J } -\group_end: -% \end{macrocode} -% -% \begin{variable}{\l_tl_case_change_accents_tl} -% A list of accents to leave alone. -% \begin{macrocode} -\tl_new:N \l_tl_case_change_accents_tl -\tl_set:Nn \l_tl_case_change_accents_tl - { \" \' \. \^ \` \~ \c \H \k \r \t \u \v } -% \end{macrocode} -% \end{variable} -% -% \begin{macro}[EXP]{\@@_change_case_mixed_nl:Nnw} -% \begin{macro}[EXP]{\@@_change_case_mixed_nl:Nw} -% \begin{macro}[EXP]{\@@_change_case_mixed_nl:NNw} -% For Dutch, there is a single look-ahead test for \texttt{ij} when -% title casing. If the appropriate letters are found, produce \texttt{IJ} -% and gobble the \texttt{j}/\texttt{J}. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_mixed_nl:Nnw #1 - { - \bool_lazy_or:nnTF - { \int_compare_p:nNn { `#1 } = { `i } } - { \int_compare_p:nNn { `#1 } = { `I } } - { - \@@_change_case_output:nwn { I } - \@@_change_case_mixed_nl:Nw - } - } -\cs_new:Npn \@@_change_case_mixed_nl:Nw #1#2 \q_recursion_stop - { - \tl_if_head_is_N_type:nT {#2} - { \@@_change_case_mixed_nl:NNw } - #1 #2 \q_recursion_stop - } -\cs_new:Npn \@@_change_case_mixed_nl:NNw #1#2#3 \q_recursion_stop - { - \@@_change_case_if_expandable:NTF #2 - { - \exp_after:wN \@@_change_case_mixed_nl:Nw \exp_after:wN #1 #2 - #3 \q_recursion_stop - } - { - \bool_lazy_and:nnTF - { ! ( \token_if_cs_p:N #2 ) } - { - \bool_lazy_or_p:nn - { \int_compare_p:nNn { `#2 } = { `j } } - { \int_compare_p:nNn { `#2 } = { `J } } - } - { - \@@_change_case_output:nwn { J } - #1 - } - { #1 #2 } - #3 \q_recursion_stop - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{variable}{\l_tl_case_change_math_tl} -% The list of token pairs which are treated as math mode and so -% not case changed. -% \begin{macrocode} -\tl_new:N \l_tl_case_change_math_tl -%<*package> -\tl_set:Nn \l_tl_case_change_math_tl - { $ $ \( \) } -%</package> -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_tl_case_change_exclude_tl} -% The list of commands for which an argument is not case changed. -% \begin{macrocode} -\tl_new:N \l_tl_case_change_exclude_tl -%<*package> -\tl_set:Nn \l_tl_case_change_exclude_tl - { \cite \ensuremath \label \ref } -%</package> -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_tl_mixed_case_ignore_tl} -% Characters to skip over when finding the first letter in a word to be -% mixed cased. -% \begin{macrocode} -\tl_new:N \l_tl_mixed_case_ignore_tl -\tl_set:Nx \l_tl_mixed_case_ignore_tl - { - ( % ) - [ % ] - \cs_to_str:N \{ % \} - ` - - - } -% \end{macrocode} -% \end{variable} -% -% \subsubsection{Building a token list} -% % Between \cs{tl_build_begin:N} \meta{tl~var} and \cs{tl_build_end:N} % \meta{tl~var}, the \meta{tl~var} has the structure % \begin{quote} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index 9529c15070d..ab7cc6cca48 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -3,7 +3,7 @@ %% File: l3clist.dtx % % Copyright (C) 2004-2011 Frank Mittelbach, The LaTeX3 Project -% (C) 2012-2019 The LaTeX3 Project +% (C) 2012-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index 92203d5d8c9..0b27eddfdbd 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx @@ -2,7 +2,7 @@ % %% File: l3coffins.dtx % -% Copyright (C) 2010-2019 The LaTeX3 Project +% Copyright (C) 2010-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx index 9361db0b98f..f4fc3498f46 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx @@ -2,7 +2,7 @@ % %% File: l3color-base.dtx % -% Copyright (C) 2011,2012,2014,2016-2019 The LaTeX3 Project +% Copyright (C) 2011,2012,2014,2016-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx b/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx index cb1eb81fd8c..337fddffd7b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx @@ -2,7 +2,7 @@ % %% File: l3debug.dtx % -% Copyright (C) 2019 The LaTeX3 Project +% Copyright (C) 2019,2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx index 410f6891a97..32c5050d87e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx @@ -2,7 +2,7 @@ % %% File: l3deprecation.dtx % -% Copyright (C) 2017-2019 The LaTeX3 Project +% Copyright (C) 2017-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -873,6 +873,28 @@ % % \subsection{Deprecated \pkg{l3str} functions} % +% \begin{macro}[EXP, deprecated = 2021-07-01] +% { +% \str_lower_case:n, \str_lower_case:f, +% \str_upper_case:n, \str_upper_case:f, +% \str_fold_case:n, \str_fold_case:V +% } +% \begin{macrocode} +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \str_lower_case:n } +\cs_gset:Npn \str_lower_case:n { \str_lowercase:n } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \str_lower_case:f } +\cs_gset:Npn \str_lower_case:f { \str_lowercase:f } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \str_upper_case:n } +\cs_gset:Npn \str_upper_case:n { \str_uppercase:n } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \str_upper_case:f } +\cs_gset:Npn \str_upper_case:f { \str_uppercase:f } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \str_fold_case:n } +\cs_gset:Npn \str_fold_case:n { \str_foldcase:n } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \str_fold_case:V } +\cs_gset:Npn \str_fold_case:V { \str_foldcase:V } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[EXP, deprecated = 2020-07-01, noTF]{\str_case_x:nn} % \begin{macro}[EXP, deprecated = 2020-07-01, pTF]{\str_if_eq_x:nn} % \begin{macrocode} @@ -947,6 +969,34 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[deprecated = 2022-07-01] +% { +% \tl_lower_case:n, \tl_lower_case:nn, +% \tl_upper_case:n, \tl_upper_case:nn, +% \tl_mixed_case:n, \tl_mixed_case:nn, +% } +% \begin{macrocode} +\__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_lowercase:n } +\cs_gset:Npn \tl_lower_case:n #1 + { \text_lowercase:n {#1} } +\__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_lowercase:nn } +\cs_gset:Npn \tl_lower_case:nn #1#2 + { \text_lowercase:nn {#1} {#2} } +\__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_uppercase:n } +\cs_gset:Npn \tl_upper_case:n #1 + { \text_uppercase:n {#1} } +\__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_uppercase:nn } +\cs_gset:Npn \tl_upper_case:nn #1#2 + { \text_uppercase:nn {#1} {#2} } +\__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_titlecase:n } +\cs_gset:Npn \tl_mixed_case:n #1 + { \text_titlecase:n {#1} } +\__kernel_patch_deprecation:nnNNpn { 2022-01-01 } { \text_titlecase:nn } +\cs_gset:Npn \tl_mixed_case:nn #1#2 + { \text_titlecase:nn {#1} {#2} } +% \end{macrocode} +% \end{macro} +% % \subsection{Deprecated \pkg{l3tl-analysis} functions} % % \begin{macro}[deprecated = 2020-07-01] @@ -978,6 +1028,33 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP, deprecated = 2021-07-01] +% { +% \char_lower_case:N, \char_upper_case:N, +% \char_mixed_case:Nn, \char_fold_case:N, +% \char_str_lower_case:N, \char_str_upper_case:N, +% \char_str_mixed_case:Nn, \char_str_fold_case:N, +% } +% \begin{macrocode} +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \char_lower_case:N } +\cs_gset:Npn \char_lower_case:N { \char_lowercase:N } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \char_upper_case:N } +\cs_gset:Npn \char_upper_case:N { \char_uppercase:N } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \char_mixed_case:N } +\cs_gset:Npn \char_mixed_case:N { \char_titlecase:N } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \char_fold_case:N } +\cs_gset:Npn \char_fold_case:N { \char_foldcase:N } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \char_str_lower_case:N } +\cs_gset:Npn \char_str_lower_case:N { \char_str_lowercase:N } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \char_str_upper_case:N } +\cs_gset:Npn \char_str_upper_case:N { \char_str_uppercase:N } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \char_str_mixed_case:N } +\cs_gset:Npn \char_str_mixed_case:N { \char_str_titlecase:N } +\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \char_str_fold_case:N } +\cs_gset:Npn \char_str_fold_case:N { \char_str_foldcase:N } +% \end{macrocode} +% \end{macro} +% % \subsection{Deprecated \pkg{l3file} functions} % % \begin{macro}[EXP, deprecated = 2021-07-01]{\c_term_ior} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index 7ddc695d4d7..c2949444822 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx @@ -2,7 +2,7 @@ % %% File: l3doc.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -31,7 +31,7 @@ \askforoverwritefalse \preamble -Copyright (C) 1990-2017,2019 The LaTeX3 Project +Copyright (C) 1990-2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of @@ -79,7 +79,7 @@ and all files in that bundle must be distributed together. % % \title{The \cls{l3doc} class} % \author{\Team} -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % \maketitle % \tableofcontents % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx index 8c626f91f95..3f64b98edf6 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx @@ -2,7 +2,7 @@ % %% File l3dosctrip.dtx % -% Copyright (C) 2012,2014-2019 The LaTeX3 Project +% Copyright (C) 2012,2014-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -63,7 +63,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx index 7f3ea57e68d..a2767d96921 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx @@ -2,7 +2,7 @@ % %% File: l3expan.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -536,6 +536,7 @@ % \exp_args:Nooo, % \exp_args:Noof, % \exp_args:Nffo, +% \exp_args:Neee % } % \begin{syntax} % \cs{exp_args:NNoo} \meta{token_1} \meta{token_2} \Arg{token_3} \Arg{tokens} @@ -2841,7 +2842,7 @@ % \exp_args:NNno, \exp_args:NNnV, \exp_args:NNoo, \exp_args:NNVV, % \exp_args:Ncno, \exp_args:NcnV, \exp_args:Ncoo, \exp_args:NcVV, % \exp_args:Nnnc, \exp_args:Nnno, \exp_args:Nnnf, \exp_args:Nnff, -% \exp_args:Nooo, \exp_args:Noof, \exp_args:Nffo, +% \exp_args:Nooo, \exp_args:Noof, \exp_args:Nffo, \exp_args:Neee % } % \begin{macro} % { @@ -2866,6 +2867,7 @@ \@@_tmp:w { ooo } \@@_tmp:w { oof } \@@_tmp:w { ffo } +\@@_tmp:w { eee } \@@_tmp:w { NNx } \@@_tmp:w { Nnx } \@@_tmp:w { Nox } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index 2b6c86f8f89..274d5da8ecc 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx @@ -2,7 +2,7 @@ % %% File: l3file.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -702,6 +702,35 @@ % quote (|"|) characters or is surrounded by a pair of quotes. % \end{function} % +% \begin{function}[rEXP, added = 2019-11-19] +% {\file_hex_dump:n, \file_hex_dump:nnn} +% \begin{syntax} +% \cs{file_hex_dump:n} \Arg{file name} +% \cs{file_hex_dump:nnn} \Arg{file name} \Arg{start index} \Arg{end index} +% \end{syntax} +% Searches for \meta{file name} using the current \TeX{} search +% path and the additional paths controlled by \cs{l_file_search_path_seq}. +% It then expands to leave the hexadecimal dump of the file content in the +% input stream. The file is read as bytes, which means that in +% contrast to most \TeX{} behaviour there will be a difference in result +% depending on the line endings used in text files. The same file will +% produce the same result between different engines: the algorithm used +% is the same in all cases. When the file is not found, the result of +% expansion is empty. The \Arg{start index} and \Arg{end index} values +% work as described for \cs{str_range:nnn}. +% \end{function} +% +% \begin{function}[noTF, added = 2019-11-19] +% {\file_get_hex_dump:nN, \file_get_hex_dump:nnnN} +% \begin{syntax} +% \cs{file_get_hex_dump:nN} \Arg{file name} \meta{tl var} +% \cs{file_get_hex_dump:nnnN} \Arg{file name} \Arg{start index} \Arg{end index} \meta{tl var} +% \end{syntax} +% Sets the \meta{tl var} to the result of applying +% \cs{file_hex_dump:n}/\cs{file_hex_dump:nnn} to the \meta{file}. +% If the file is not found, the \meta{tl var} will be set to \cs{q_no_value}. +% \end{function} +% % \begin{function}[rEXP, added = 2019-09-03]{\file_mdfive_hash:n} % \begin{syntax} % \cs{file_mdfive_hash:n} \Arg{file name} @@ -2858,18 +2887,119 @@ % \end{macro} % \end{macro} % +% \begin{macro}[rEXP]{\file_hex_dump:nnn, \@@_hex_dump_auxi:nnn} +% \begin{macro}[rEXP]{\@@_hex_dump_auxii:nnnn, \@@_hex_dump_auxiii:nnnn} +% \begin{macro}[rEXP]{\@@_hex_dump_auxiiv:nnn} +% \begin{macro}[rEXP]{\file_hex_dump:n, \@@_hex_dump:n} +% These are separate as they need multiple arguments \emph{or} the +% file size. For \LuaTeX{}, the emulation does not need the file +% size so we save a little on expansion. +% \begin{macrocode} +\cs_new:Npn \file_hex_dump:nnn #1#2#3 + { + \exp_args:Neee \@@_hex_dump_auxi:nnn + { \file_full_name:n {#1} } + { \int_eval:n {#2} } + { \int_eval:n {#3} } + } +\cs_new:Npn \@@_hex_dump_auxi:nnn #1#2#3 + { + \bool_lazy_any:nF + { + { \tl_if_blank_p:n {#1} } + { \int_compare_p:nNn {#2} = 0 } + { \int_compare_p:nNn {#3} = 0 } + } + { + \exp_args:Ne \@@_hex_dump_auxii:nnnn + { \@@_details_aux:nn {#1} { size } } + {#1} {#2} {#3} + } + } +\cs_new:Npn \@@_hex_dump_auxii:nnnn #1#2#3#4 + { + \int_compare:nNnTF {#3} > 0 + { \@@_hex_dump_auxiii:nnnn {#3} } + { + \exp_args:Ne \@@_hex_dump_auxiii:nnnn + { \int_eval:n { #1 + #3 } } + } + {#1} {#2} {#4} + } +\cs_new:Npn \@@_hex_dump_auxiii:nnnn #1#2#3#4 + { + \int_compare:nNnTF {#4} > 0 + { \@@_hex_dump_auxiv:nnn {#4} } + { + \exp_args:Ne \@@_hex_dump_auxiv:nnn + { \int_eval:n { #2 + #4 } } + } + {#1} {#3} + } +\cs_new:Npn \@@_hex_dump_auxiv:nnn #1#2#3 + { + \tex_filedump:D + offset ~ \int_eval:n { #2 - 1 } ~ + length ~ \int_eval:n { #1 - #2 + 1 } + {#3} + } +\sys_if_engine_luatex:T + { + \cs_gset:Npn \@@_hex_dump_auxiv:nnn #1#2#3 + { + \lua_now:e + { + l3kernel.filedump + ( + " \lua_escape:e {#3} " , + \int_eval:n { #2 - 1 } , + \int_eval:n { #1 - #2 + 1 } + ) + } + } + } +\cs_new:Npn \file_hex_dump:n #1 + { \exp_args:Ne \@@_hex_dump:n { \file_full_name:n {#1} } } +\cs_new:Npn \@@_hex_dump:n #1 + { + \tl_if_blank:nF {#1} + { \tex_filedump:D length \tex_filesize:D {#1} {#1} } + } +\sys_if_engine_luatex:T + { + \cs_gset:Npn \@@_hex_dump:n #1 + { + \lua_now:e + { l3kernel.filedump ( " \lua_escape:e { #1 } " ) } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macro}[noTF] -% {\file_get_mdfive_hash:nN, \file_get_size:nN, \file_get_timestamp:nN} +% { +% \file_get_hex_dump:nN, +% \file_get_mdfive_hash:nN +% \file_get_size:nN, +% \file_get_timestamp:nN +% } % \begin{macro}{\@@_get_details:nnN} % Non-expandable wrappers around the above in the case where appropriate % primitive support exists. % \begin{macrocode} +\cs_new_protected:Npn \file_get_hex_dump:nN #1#2 + { \file_get_hex_dump:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } } \cs_new_protected:Npn \file_get_mdfive_hash:nN #1#2 { \file_get_mdfive_hash:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } } \cs_new_protected:Npn \file_get_size:nN #1#2 { \file_get_size:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } } \cs_new_protected:Npn \file_get_timestamp:nN #1#2 { \file_get_timestamp:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } } +\prg_new_protected_conditional:Npnn \file_get_hex_dump:nN #1#2 { T , F , TF } + { \@@_get_details:nnN {#1} { hex_dump } #2 } \prg_new_protected_conditional:Npnn \file_get_mdfive_hash:nN #1#2 { T , F , TF } { \@@_get_details:nnN {#1} { mdfive_hash } #2 } \prg_new_protected_conditional:Npnn \file_get_size:nN #1#2 { T , F , TF } @@ -2901,6 +3031,7 @@ \token_to_str:N \(pdf)file \str_case:nn {#2} { + { hex_dump } { dump } { mdfive_hash } { mdfivesum } { timestamp } { moddate } { size } { size } @@ -2913,6 +3044,26 @@ % \end{macro} % \end{macro} % +% \begin{macro}[noTF]{\file_get_hex_dump:nnnN} +% Custom code due to the additional arguments. +% \begin{macrocode} +\cs_new_protected:Npn \file_get_hex_dump:nnnN #1#2#3#4 + { + \file_get_hex_dump:nnnNF {#1} {#2} {#3} #4 + { \tl_set:Nn #4 { \q_no_value } } + } +\prg_new_protected_conditional:Npnn \file_get_hex_dump:nnnN #1#2#3#4 + { T , F , TF } + { + \tl_set:Nx #4 + { \file_hex_dump:nnn {#1} {#2} {#3} } + \tl_if_empty:NTF #4 + { \prg_return_false: } + { \prg_return_true: } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[EXP]{\@@_str_cmp:nn} % \begin{macro}[EXP]{\@@_str_escape:n} % As we are doing a fixed-length \enquote{big} integer comparison, it diff --git a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx index 853220d68a1..a8677aeb684 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx @@ -2,7 +2,7 @@ % %% File: l3final.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx index 742e3da3a44..2f8b6dcc770 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx @@ -2,7 +2,7 @@ % %% File: l3flag.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3format.ins b/Master/texmf-dist/source/latex/l3kernel/l3format.ins index bdc5516701f..6e0c98cb819 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3format.ins +++ b/Master/texmf-dist/source/latex/l3kernel/l3format.ins @@ -2,7 +2,7 @@ File l3format.ins -Copyright (C) 2011,2012,2014-2019 The LaTeX3 Project +Copyright (C) 2011,2012,2014-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -35,7 +35,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 1990-2019 The LaTeX3 Project +Copyright (C) 1990-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of @@ -104,8 +104,9 @@ and all files in that bundle must be distributed together. \from{l3coffins.dtx} {initex} \from{l3luatex.dtx} {initex,tex} \from{l3unicode.dtx} {initex} + \from{l3text.dtx} {initex} + \from{l3text-case.dtx} {initex} \from{l3candidates.dtx} {initex} - \from{l3deprecation.dtx}{initex,kernel} % ======== FORMAT ONLY ========= \from{l3final.dtx} {initex} % ============================== @@ -141,7 +142,7 @@ and all files in that bundle must be distributed together. \def\MetaPrefix{--} \preamble -Copyright (C) 1990-2019 The LaTeX3 Project +Copyright (C) 1990-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx index a09616c3079..ee6abd5f551 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % \maketitle % % \begin{documentation} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx index 1d3faad8431..f306cc12c1d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-aux.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx index 776192abc7c..bf0afbf7c4b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-basics.dtx % -% Copyright (C) 2011-2014,2016-2019 The LaTeX3 Project +% Copyright (C) 2011-2014,2016-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx index c1443a3eaf8..b6b9e0d7c9a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-convert.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx index 394fe63f4c4..d830b74036d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-expo.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx index 8c28335acc6..961655d05ad 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-extended.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx index 0b853df3ce9..e6aab8c3945 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-logic.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index a8641905355..4c4c31c95e1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-parse.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -1025,7 +1025,7 @@ \cs_if_exist_use:cF { @@_parse_word_#2:N } { \cs_if_exist_use:cF - { @@_parse_caseless_ \str_fold_case:n {#2} :N } + { @@_parse_caseless_ \str_foldcase:n {#2} :N } { \__kernel_msg_expandable_error:nnn { kernel } { unknown-fp-word } {#2} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx index 7c6d18bc3c5..e56642bd6d2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-random.dtx % -% Copyright (C) 2016-2019 The LaTeX3 Project +% Copyright (C) 2016-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx index 7c4e5b0b0fc..672bfd9c8a4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-round.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx index f4e047b462b..74809e63859 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-traps.dtx % -% Copyright (C) 2011-2014,2016-2019 The LaTeX3 Project +% Copyright (C) 2011-2014,2016-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % \maketitle % % \begin{documentation} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx index d89f0477517..fced52d7593 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx @@ -2,7 +2,7 @@ % %% File: l3fp-trig.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx index 85214140856..44530a1518b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx @@ -2,7 +2,7 @@ % %% File: l3fp.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -49,7 +49,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -887,7 +887,7 @@ % \mathtt{1/2pi(pi+pi)} & = (2\pi)^{-1}(\pi+\pi) \simeq 1, \\ % \mathtt{sin 2pi} & = \sin(2)\pi \neq 0, \\ % \mathtt{2\char`\^2max(3,5)} & = 2^2 \max(3,5) = 20, \\ -% \mathtt{1in/1cm} & = (1in)/(1cm) = 2.54 . +% \mathtt{1in/1cm} & = (1\mathrm{in})/(1\mathrm{cm}) = 2.54 . % \end{align*} % Functions are called on the value of their argument, contrarily to % \TeX{} macros. diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx index 35cdb6353c8..e7f0675fc95 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx @@ -2,7 +2,7 @@ % %% File: l3fparray.dtx % -% Copyright (C) 2018-2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index 4459cc56b1e..bc68230b3f2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx @@ -2,7 +2,7 @@ % %% File: l3int.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -420,8 +420,8 @@ % { -2 * 10 } { Negative } % } % { No idea! } -% \end{verbatim} -% leaves \enquote{\texttt{Medium}} in the input stream. +% \end{verbatim} +% leaves \enquote{\texttt{Medium}} in the input stream. % \end{function} % % \begin{function}[EXP,pTF]{\int_if_even:n, \int_if_odd:n} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx index f26e7416aa9..6fc43aad658 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx @@ -2,7 +2,7 @@ % %% File: l3intarray.dtx % -% Copyright (C) 2017-2019 The LaTeX3 Project +% Copyright (C) 2017-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx index 5ad373b5cc3..98f588a53e5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index c8d5f714318..54167b15c25 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx @@ -2,7 +2,7 @@ % %% File: l3keys.dtx % -% Copyright (C) 2006-2019 The LaTeX3 Project +% Copyright (C) 2006-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -2523,6 +2523,7 @@ { \c_@@_code_root_tl ##1 / \l_keys_key_tl } { \tl_set:Nn \l_@@_inherit_tl {##1} + \cs_if_exist_use:c { \c_@@_validate_root_tl ##1 / \l_keys_key_tl } \cs:w \c_@@_code_root_tl ##1 / \l_keys_key_tl \exp_after:wN \cs_end: \exp_after:wN { \l_keys_value_tl } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx b/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx index c49ac91e7f6..21d6fe5146b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx @@ -2,7 +2,7 @@ % %% File: l3legacy.dtx % -% Copyright (C) 2019 The LaTeX3 Project +% Copyright (C) 2019,2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx index 22780b77fd9..a9f1f0c0a3d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx @@ -2,7 +2,7 @@ % %% File: l3luatex.dtx % -% Copyright (C) 2010-2019 The LaTeX3 Project +% Copyright (C) 2010-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -143,6 +143,17 @@ % for user input. % \end{function} % +% \begin{function}{l3kernel.filedump} +% \begin{syntax} +% |l3kernel.filedump(|\meta{file}|,|\meta{offset}|,|\meta{length}|)| +% \end{syntax} +% Returns the uppercase hexadecimal representation of the content of the +% \meta{file} read as bytes. If the \meta{length} is given, only this part +% of the file is returned; similarly, one may specify the \meta{offset} from +% the start of the file. If the \meta{length} is not given, the entire file +% is read starting at the \meta{offset}. +% \end{function} +% % \begin{function}{l3kernel.filemdfivesum} % \begin{syntax} % |l3kernel.filemdfivesum(|\meta{file}|)| @@ -310,16 +321,17 @@ l3kernel = l3kernel or { } % % Local copies of global tables. % \begin{macrocode} -local io = io -local kpse = kpse -local lfs = lfs -local math = math -local md5 = md5 -local os = os -local string = string -local tex = tex -local texio = texio -local unicode = unicode +local io = io +local kpse = kpse +local lfs = lfs +local math = math +local md5 = md5 +local os = os +local string = string +local tex = tex +local texio = texio +local tonumber = tonumber +local unicode = unicode % \end{macrocode} % % Local copies of standard functions. @@ -395,6 +407,30 @@ l3kernel.resettimer = resettimer % \end{macrocode} % \end{macro} % +% \begin{macro}{l3kernel.filedump} +% Similar comments here to the next function: read the file in binary mode +% to avoid any line-end weirdness. +% \begin{macrocode} +local function filedump(name,offset,length) + local file = kpse_find(name,"tex",true) + if file then + local length = tonumber(length) or lfs_attr(file,"size") + local offset = tonumber(offset) or 0 + local f = open(file,"rb") + if f then + if offset > 0 then + f:seek("set",offset) + end + local data = f:read(length) + escapehex(data) + f:close() + end + end +end +l3kernel.filedump = filedump +% \end{macrocode} +% \end{macro} +% % \begin{macro}{l3kernel.filemdfivesum} % Read an entire file and hash it: the hash function itself is a built-in. % As Lua is byte-based there is no work needed here in terms of UTF-8 diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx index 969738d3aab..3b52246c27d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx @@ -2,7 +2,7 @@ % %% File: l3msg.dtx % -% Copyright (C) 2009-2019 The LaTeX3 Project +% Copyright (C) 2009-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx index b0edf9235dc..cce95b98661 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -1113,6 +1113,9 @@ % \begin{macrocode} \@@_primitive:NN \autospacing \tex_autospacing:D \@@_primitive:NN \autoxspacing \tex_autoxspacing:D + \@@_primitive:NN \currentcjktoken \tex_currentcjktoken:D + \@@_primitive:NN \currentspacingmode \tex_currentspacingmode:D + \@@_primitive:NN \currentxspacingmode \tex_currentxspacingmode:D \@@_primitive:NN \disinhibitglue \tex_disinhibitglue:D \@@_primitive:NN \dtou \tex_dtou:D \@@_primitive:NN \epTeXinputencoding \tex_epTeXinputencoding:D diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index 63b2f5845b8..6a503a97f6c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx @@ -2,7 +2,7 @@ % %% File: l3prg.dtx % -% Copyright (C) 2005-2019 The LaTeX3 Project +% Copyright (C) 2005-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index 62cd9ba7859..445695ac0f8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx @@ -2,7 +2,7 @@ % %% File: l3prop.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx index 401b66dfc13..d3ee404a2f8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx @@ -2,7 +2,7 @@ % %% File: l3quark.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx index bf7b19ccdef..f096c3e65de 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx @@ -2,7 +2,7 @@ % %% File: l3regex.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index 811ac0a7d74..bc21d02688a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx @@ -2,7 +2,7 @@ % %% File: l3seq.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index 901595ae0da..cbb2345e78f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx @@ -3,7 +3,7 @@ %% File: l3skip.dtx % % Copyright (C) 2004-2011 Frank Mittelbach, The LaTeX3 Project -% (C) 2012-2019 The LaTeX3 Project +% (C) 2012-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx index 49686a77ab6..1cb084742bb 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx @@ -2,7 +2,7 @@ % %% File l3sort.dtx % -% Copyright (C) 2012-2019 The LaTeX3 Project +% Copyright (C) 2012-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx index 05531a1e933..07343492cd0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx @@ -2,7 +2,7 @@ % %% File: l3str-convert.dtx % -% Copyright (C) 2013-2019 The LaTeX3 Project +% Copyright (C) 2013-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx index 09dde6a4eb6..9947592862c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx @@ -2,7 +2,7 @@ % %% File: l3str.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -690,14 +690,14 @@ % % \section{String manipulation} % -% \begin{function}[EXP, added = 2015-03-01] +% \begin{function}[EXP, added = 2019-11-26] % { -% \str_lower_case:n, \str_lower_case:f, -% \str_upper_case:n, \str_upper_case:f +% \str_lowercase:n, \str_lowercase:f, +% \str_uppercase:n, \str_uppercase:f % } % \begin{syntax} -% \cs{str_lower_case:n} \Arg{tokens} -% \cs{str_upper_case:n} \Arg{tokens} +% \cs{str_lowercase:n} \Arg{tokens} +% \cs{str_uppercase:n} \Arg{tokens} % \end{syntax} % Converts the input \meta{tokens} to their string representation, as % described for \cs{tl_to_str:n}, and then to the lower or upper @@ -716,8 +716,8 @@ % \cs_set_protected:cpn % { % user -% \str_upper_case:f { \tl_head:n {#1} } -% \str_lower_case:f { \tl_tail:n {#1} } +% \str_uppercase:f { \tl_head:n {#1} } +% \str_lowercase:f { \tl_tail:n {#1} } % } % { #2 } % } @@ -728,19 +728,19 @@ % % These functions should \emph{not} be used for % \begin{itemize} -% \item Caseless comparisons: use \cs{str_fold_case:n} for this +% \item Caseless comparisons: use \cs{str_foldcase:n} for this % situation (case folding is distinct from lower casing). % \item Case changing text for typesetting: see the -% \cs[index=tl_lower_case:n]{tl_lower_case:n(n)}, -% \cs[index=tl_upper_case:n]{tl_upper_case:n(n)} and -% \cs[index=tl_mixed_case:n]{tl_mixed_case:n(n)} functions which +% \cs[index=text_lowercase:n]{text_lowercase:n(n)}, +% \cs[index=text_uppercase:n]{text_uppercase:n(n)} and +% \cs[index=text_titlecase:n]{text_titlecase:n(n)} functions which % correctly deal with context-dependence and other factors appropriate % to text case changing. % \end{itemize} % % \begin{texnote} % As with all \pkg{expl3} functions, the input supported by -% \cs{str_fold_case:n} is \emph{engine-native} characters which are or +% \cs{str_foldcase:n} is \emph{engine-native} characters which are or % interoperate with \textsc{utf-8}. As such, when used with \pdfTeX{} % \emph{only} the Latin alphabet characters A--Z are case-folded % (\emph{i.e.}~the \textsc{ascii} range which coincides with @@ -749,10 +749,10 @@ % \end{texnote} % \end{function} % -% \begin{function}[EXP, added = 2014-06-19, updated = 2016-03-07] -% {\str_fold_case:n, \str_fold_case:V} +% \begin{function}[EXP, added = 2019-11-26] +% {\str_foldcase:n, \str_foldcase:V} % \begin{syntax} -% \cs{str_fold_case:n} \Arg{tokens} +% \cs{str_foldcase:n} \Arg{tokens} % \end{syntax} % Converts the input \meta{tokens} to their string representation, as % described for \cs{tl_to_str:n}, and then folds the case of the resulting @@ -760,7 +760,7 @@ % left in the input stream. % % String folding is a process used for material such as identifiers rather -% than for \enquote{text}. The folding provided by \cs{str_fold_case:n} +% than for \enquote{text}. The folding provided by \cs{str_foldcase:n} % follows the mappings provided by the \href{http://www.unicode.org}^^A % {Unicode Consortium}, who % \href{http://www.unicode.org/faq/casemap_charprop.html#2}{state}: @@ -773,7 +773,7 @@ % should be used solely for internal processing and generally should not be % stored or displayed to the end user. % \end{quote} -% The folding approach implemented by \cs{str_fold_case:n} follows the +% The folding approach implemented by \cs{str_foldcase:n} follows the % \enquote{full} scheme defined by the Unicode Consortium % (\emph{e.g.}~\SS folds to \texttt{SS}). As case-folding is % a language-insensitive process, there is no special treatment of @@ -782,7 +782,7 @@ % % \begin{texnote} % As with all \pkg{expl3} functions, the input supported by -% \cs{str_fold_case:n} is \emph{engine-native} characters which are or +% \cs{str_foldcase:n} is \emph{engine-native} characters which are or % interoperate with \textsc{utf-8}. As such, when used with \pdfTeX{} % \emph{only} the Latin alphabet characters A--Z are case-folded % (\emph{i.e.}~the \textsc{ascii} range which coincides with @@ -1850,9 +1850,9 @@ % % \begin{macro}[EXP] % { -% \str_fold_case:n, \str_fold_case:V, -% \str_lower_case:n, \str_lower_case:f, -% \str_upper_case:n, \str_upper_case:f +% \str_foldcase:n, \str_foldcase:V, +% \str_lowercase:n, \str_lowercase:f, +% \str_uppercase:n, \str_uppercase:f % } % \begin{macro}[EXP]{\@@_change_case:nn} % \begin{macro}[EXP]{\@@_change_case_aux:nn} @@ -1867,12 +1867,12 @@ % and everything else. The output is detokenized to allow data sharing % with text-based case changing. % \begin{macrocode} -\cs_new:Npn \str_fold_case:n #1 { \@@_change_case:nn {#1} { fold } } -\cs_new:Npn \str_lower_case:n #1 { \@@_change_case:nn {#1} { lower } } -\cs_new:Npn \str_upper_case:n #1 { \@@_change_case:nn {#1} { upper } } -\cs_generate_variant:Nn \str_fold_case:n { V } -\cs_generate_variant:Nn \str_lower_case:n { f } -\cs_generate_variant:Nn \str_upper_case:n { f } +\cs_new:Npn \str_foldcase:n #1 { \@@_change_case:nn {#1} { fold } } +\cs_new:Npn \str_lowercase:n #1 { \@@_change_case:nn {#1} { lower } } +\cs_new:Npn \str_uppercase:n #1 { \@@_change_case:nn {#1} { upper } } +\cs_generate_variant:Nn \str_foldcase:n { V } +\cs_generate_variant:Nn \str_lowercase:n { f } +\cs_generate_variant:Nn \str_uppercase:n { f } \cs_new:Npn \@@_change_case:nn #1 { \exp_after:wN \@@_change_case_aux:nn \exp_after:wN @@ -1906,7 +1906,7 @@ \quark_if_recursion_tail_stop_do:Nn #2 { \@@_change_case_end:wn } \@@_change_case_output:fw - { \use:c { char_str_ #1 _case:N } #2 } + { \use:c { char_str_ #1 case:N } #2 } \@@_change_case_loop:nw {#1} } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx index 24e79512c77..12ebc542a50 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx @@ -2,7 +2,7 @@ % %% File: l3sys.dtx % -% Copyright (C) 2015-2019 The LaTeX3 Project +% Copyright (C) 2015-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -837,7 +837,7 @@ } % \end{macrocode} % If there is a class option set, and recognised, we pick it up: these -% will over-ride anything set automatically but will themsevles be +% will over-ride anything set automatically but will themselves be % over-written if there is a package option. % \begin{macrocode} \@@_finalise:n diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx new file mode 100644 index 00000000000..3c608eacb9e --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx @@ -0,0 +1,1421 @@ +% \iffalse meta-comment +% +%% File: l3text-case.dtx +% +% Copyright (C) 2020 The LaTeX3 Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% This file is part of the "l3kernel bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/latex3 +% +% for those people who are interested. +% +%<*driver> +\documentclass[full,kernel]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{^^A +% The \textsf{l3text-case} package: text processing (case changing)^^A +% } +% +% \author{^^A +% The \LaTeX3 Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Released 2020-01-12} +% +% \maketitle +% +% \begin{documentation} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3text-case} implementation} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=text> +% \end{macrocode} +% +% \subsection{Case changing} +% +% \begin{macro}[EXP] +% { +% \text_lowercase:n, +% \text_uppercase:n, +% \text_titlecase:n, +% \text_titlecase_first:n +% } +% \begin{macro}[EXP] +% { +% \text_lowercase:nn, +% \text_uppercase:nn, +% \text_titlecase:nn, +% \text_titlecase_first:nn +% } +% The user level functions here are all wrappers around the internal +% functions for case changing. +% \begin{macrocode} +\cs_new:Npn \text_lowercase:n #1 + { \@@_change_case:nnn { lower } { } {#1} } +\cs_new:Npn \text_uppercase:n #1 + { \@@_change_case:nnn { upper } { } {#1} } +\cs_new:Npn \text_titlecase:n #1 + { \@@_change_case:nnn { title } { } {#1} } +\cs_new:Npn \text_titlecase_first:n #1 + { \@@_change_case:nnn { titleonly } { } {#1} } +\cs_new:Npn \text_lowercase:nn #1#2 + { \@@_change_case:nnn { lower } {#1} {#2} } +\cs_new:Npn \text_uppercase:nn #1#2 + { \@@_change_case:nnn { upper } {#1} {#2} } +\cs_new:Npn \text_titlecase:nn #1#2 + { \@@_change_case:nnn { title } {#1} {#2} } +\cs_new:Npn \text_titlecase_first:nn #1#2 + { \@@_change_case:nnn { titleonly } {#1} {#2} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_change_case:nnn, \@@_change_case_aux:nnn} +% \begin{macro}[EXP]{\@@_change_case_store:n} +% \begin{macro}[EXP]{\@@_change_case_store:nw} +% \begin{macro}[EXP]{\@@_change_case_result:n} +% \begin{macro}[EXP]{\@@_change_case_end:w} +% \begin{macro}[EXP]{\@@_change_case_loop:nnw} +% \begin{macro}[EXP]{\@@_change_case_break:w} +% \begin{macro}[EXP] +% { +% \@@_change_case_group_lower:nnn , +% \@@_change_case_group_upper:nnn , +% \@@_change_case_group_title:nnn , +% \@@_change_case_group_titleonly:nnn +% } +% \begin{macro}[EXP]{\@@_change_case_space:nnw} +% \begin{macro}[EXP]{\@@_change_case_N_type:nnN, \@@_change_case_N_type_aux:nnN} +% \begin{macro}[EXP]{\@@_change_case_N_type:nnnN} +% \begin{macro}[EXP]{\@@_change_case_math_search:nnNNN} +% \begin{macro}[EXP]{\@@_change_case_math_loop:nnNw} +% \begin{macro}[EXP]{\@@_change_case_math_N_type:nnNN} +% \begin{macro}[EXP]{\@@_change_case_math_group:nnNn} +% \begin{macro}[EXP]{\@@_change_case_math_space:nnNw} +% \begin{macro}[EXP]{\@@_change_case_cs_check:nnN} +% \begin{macro}[EXP]{\@@_change_case_exclude:nnN} +% \begin{macro}[EXP]{\@@_change_case_exclude:nnnN} +% \begin{macro}[EXP]{\@@_change_case_exclude:nnNN} +% \begin{macro}[EXP]{\@@_change_case_exclude:nnNn} +% \begin{macro}[EXP] +% { +% \@@_change_case_letterlike_lower:nnN , +% \@@_change_case_letterlike_upper:nnN , +% \@@_change_case_letterlike_title:nnN , +% \@@_change_case_letterlike_titleonly:nnN +% } +% \begin{macro}[EXP]{\@@_change_case_letterlike:nnnnN} +% \begin{macro}[EXP] +% {\@@_change_case_char_lower:nnN, \@@_change_case_char_upper:nnN} +% \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_char_title:nnN, \@@_change_case_char_titleonly:nnN} +% \begin{macro}[EXP] +% {\@@_change_case_char_title:nN, \@@_change_case_char_titleonly:nN} +% \begin{macro}[EXP]{\@@_change_case_char_title:nnnN} +% \begin{macro}[EXP]{\@@_change_case_char_char:nnnN} +% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nnnNN} +% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nnnNNN} +% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nnnNNNNN} +% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nnnn} +% \begin{macro}[EXP] +% { +% \@@_change_case_char_next_lower:nn , +% \@@_change_case_char_next_upper:nn , +% \@@_change_case_char_next_title:nn , +% \@@_change_case_char_next_titleonly:nn +% } +% \begin{macro}[EXP]{\@@_change_case_char_next_end:nn} +% As for the expansion code, the business end of case changing is the +% handling of \texttt{N}-type tokens. First, we expand the input fully +% (so the loops here don't need to worry about awkward look-aheads and the +% like). Then we split into the different paths. +% +% The code here needs to be \texttt{f}-type expandable to deal with the +% situation where case changing is applied in running text. There, we +% might have case changing as a document command and the text containing +% other non-expandable document commands. +% \begin{verbatim} +% \cs_set_eq:NN \MakeLowercase \text_lowercase +% ... +% \MakeLowercase{\enquote*{A} text} +% \end{verbatim} +% If we use an \texttt{e}-type expansion and wrap each token in +% \cs{exp_not:n}, that would explode: the document command grabs +% \cs{exp_not:n} as an argument, and things go badly wrong. So we have to +% wrap the entire result in exactly one \cs{exp_not:n}, or rather in the +% kernel version. +% \begin{macrocode} +\cs_new:Npn \@@_change_case:nnn #1#2#3 + { + \__kernel_exp_not:w \exp_after:wN + { + \exp:w + \exp_args:Ne \@@_change_case_aux:nnn + { \text_expand:n {#3} } + {#1} {#2} + } + } +\cs_new:Npn \@@_change_case_aux:nnn #1#2#3 + { + \group_align_safe_begin: + \@@_change_case_loop:nnw {#2} {#3} #1 + \q_recursion_tail \q_recursion_stop + \@@_change_case_result:n { } + } +% \end{macrocode} +% As for expansion, collect up the tokens for future use. +% \begin{macrocode} +\cs_new:Npn \@@_change_case_store:n #1 + { \@@_change_case_store:nw {#1} } +\cs_generate_variant:Nn \@@_change_case_store:n { o , e , V , v } +\cs_new:Npn \@@_change_case_store:nw #1#2 \@@_change_case_result:n #3 + { #2 \@@_change_case_result:n { #3 #1 } } +\cs_new:Npn \@@_change_case_end:w #1 \@@_change_case_result:n #2 + { + \group_align_safe_end: + \exp_end: + #2 + } +% \end{macrocode} +% The main loop is the standard \texttt{tl action} type. +% \begin{macrocode} +\cs_new:Npn \@@_change_case_loop:nnw #1#2#3 \q_recursion_stop + { + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_N_type:nnN } + { + \tl_if_head_is_group:nTF {#3} + { \use:c { @@_change_case_group_ #1 :nnn } } + { \@@_change_case_space:nnw } + } + {#1} {#2} #3 \q_recursion_stop + } +\cs_new:Npn \@@_change_case_break:w #1 \q_recursion_tail \q_recursion_stop + { + \@@_change_case_store:n {#1} + \@@_change_case_end:w + } +% \end{macrocode} +% For a group, we \emph{could} worry about whether this contains a character +% or not. However, that would make life very complex for little gain: exactly +% what a first character is is rather weakly-defined anyway. So if there is +% a group, we simply assume that a character has been seen, and for title +% case we switch to the \enquote{rest of the tokens} situation. To avoid +% having too much testing, we use a two-step process here to allow the +% titlecase functions to be separate. +% \begin{macrocode} +\cs_new:Npn \@@_change_case_group_lower:nnn #1#2#3 + { + \@@_change_case_store:o + { + \exp_after:wN + { + \exp:w + \@@_change_case_aux:nnn {#3} {#1} {#2} + } + } + \@@_change_case_loop:nnw {#1} {#2} + } +\cs_new_eq:NN \@@_change_case_group_upper:nnn + \@@_change_case_group_lower:nnn +\cs_new:Npn \@@_change_case_group_title:nnn #1#2#3 + { + \@@_change_case_store:o + { + \exp_after:wN + { + \exp:w + \@@_change_case_aux:nnn {#3} {#1} {#2} + } + } + \@@_change_case_loop:nnw { lower } {#2} + } +\cs_new:Npn \@@_change_case_group_titleonly:nnn #1#2#3 + { + \@@_change_case_store:o + { + \exp_after:wN + { + \exp:w + \@@_change_case_aux:nnn {#3} {#1} {#2} + } + } + \@@_change_case_break:w + } +\use:x + { + \cs_new:Npn \exp_not:N \@@_change_case_space:nnw ##1##2 \c_space_tl + } + { + \@@_change_case_store:n { ~ } + \@@_change_case_loop:nnw {#1} {#2} + } +% \end{macrocode} +% The first step of handling \texttt{N}-type tokens is to filter out the +% end-of-loop. That has to be done separately from the first real step +% as otherwise we pick up the wrong delimiter. The loop here is the same +% as the \texttt{expand} one, just passing the additional data long. If no +% close-math token is found then the final clean-up is forced +% (i.e.~there is no assumption of \enquote{well-behaved} input in terms of +% math mode). +% \begin{macrocode} +\cs_new:Npn \@@_change_case_N_type:nnN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #3 + { \@@_change_case_end:w } + \@@_change_case_N_type_aux:nnN {#1} {#2} #3 + } +\cs_new:Npn \@@_change_case_N_type_aux:nnN #1#2#3 + { + \exp_args:NV \@@_change_case_N_type:nnnN + \l_text_math_delims_tl {#1} {#2} #3 + } +\cs_new:Npn \@@_change_case_N_type:nnnN #1#2#3#4 + { + \@@_change_case_math_search:nnNNN {#2} {#3} #4 #1 + \q_recursion_tail \q_recursion_tail + \q_recursion_stop + } +\cs_new:Npn \@@_change_case_math_search:nnNNN #1#2#3#4#5 + { + \quark_if_recursion_tail_stop_do:Nn #4 + { \@@_change_case_cs_check:nnN {#1} {#2} #3 } + \token_if_eq_meaning:NNTF #3 #4 + { + \use_i_delimit_by_q_recursion_stop:nw + { + \@@_change_case_store:n {#3} + \@@_change_case_math_loop:nnNw {#1} {#2} #5 + } + } + { \@@_change_case_math_search:nnNNN {#1} {#2} #3 } + } +\cs_new:Npn \@@_change_case_math_loop:nnNw #1#2#3#4 \q_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_math_N_type:nnNN } + { + \tl_if_head_is_group:nTF {#4} + { \@@_change_case_math_group:nnNn } + { \@@_change_case_math_space:nnNw } + } + {#1} {#2} #3 #4 \q_recursion_stop + } +\cs_new:Npn \@@_change_case_math_N_type:nnNN #1#2#3#4 + { + \quark_if_recursion_tail_stop_do:Nn #4 + { \@@_change_case_end:w } + \@@_change_case_store:n {#4} + \token_if_eq_meaning:NNTF #4 #3 + { \@@_change_case_loop:nnw {#1} {#2} } + { \@@_change_case_math_loop:nnNw {#1} {#2} #3 } + } +\cs_new:Npn \@@_change_case_math_group:nnNn #1#2#3#4 + { + \@@_change_case_store:n { {#4} } + \@@_change_case_math_loop:nnNw {#1} {#2} #3 + } +\use:x + { + \cs_new:Npn \exp_not:N \@@_change_case_math_space:nnNw ##1##2##3 + \c_space_tl + } + { + \@@_change_case_store:n { ~ } + \@@_change_case_math_loop:nnNw {#1} {#2} #3 + } +% \end{macrocode} +% Once potential math-mode cases are filtered out the next stage is to +% test if the token grabbed is a control sequence: the two routes the code +% may take are then very different. +% \begin{macrocode} +\cs_new:Npn \@@_change_case_cs_check:nnN #1#2#3 + { + \token_if_cs:NTF #3 + { \@@_change_case_exclude:nnN } + { \use:c { @@_change_case_char_ #1 :nnN } } + {#1} {#2} #3 + } +% \end{macrocode} +% To deal with a control sequence there is first a need to test if it is +% on the list which indicate that case changing should be skipped. That's +% done using a loop as for the other special cases. If a hit is found then +% the argument is grabbed and passed through as-is. +% \begin{macrocode} +\cs_new:Npn \@@_change_case_exclude:nnN #1#2#3 + { + \exp_args:Ne \@@_change_case_exclude:nnnN + { + \exp_not:V \l_text_math_arg_tl + \exp_not:V \l_text_case_exclude_arg_tl + } + {#1} {#2} #3 + } +\cs_new:Npn \@@_change_case_exclude:nnnN #1#2#3#4 + { + \@@_change_case_exclude:nnNN {#2} {#3} #4 #1 + \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \@@_change_case_exclude:nnNN #1#2#3#4 + { + \quark_if_recursion_tail_stop_do:Nn #4 + { \use:c { @@_change_case_letterlike_ #1 :nnN } {#1} {#2} #3 } + \cs_if_eq:NNTF #3 #4 + { + \use_i_delimit_by_q_recursion_stop:nw + { \@@_change_case_exclude:nnNn {#1} {#2} #3 } + } + { \@@_change_case_exclude:nnNN {#1} {#2} #3 } + } +\cs_new:Npn \@@_change_case_exclude:nnNn #1#2#3#4 + { + \@@_change_case_store:n { #3 {#4} } + \@@_change_case_loop:nnw {#1} {#2} + } +% \end{macrocode} +% Letter-like commands may still be present: they are set up using a simple +% lookup approach, so can easily be handled with no loop. If there is no +% hit, we are at the end of the process: we loop around. Letter-like chars +% are all available only in upper- and lowercase, so titlecasing maps to the +% uppercase version. +% \begin{macrocode} +\cs_new:Npn \@@_change_case_letterlike_lower:nnN #1#2#3 + { \@@_change_case_letterlike:nnnnN {#1} {#1} {#1} {#2} #3 } +\cs_new_eq:NN \@@_change_case_letterlike_upper:nnN + \@@_change_case_letterlike_lower:nnN +\cs_new:Npn \@@_change_case_letterlike_title:nnN #1#2#3 + { \@@_change_case_letterlike:nnnnN { upper } { lower } {#1} {#2} #3 } +\cs_new:Npn \@@_change_case_letterlike_titleonly:nnN #1#2#3 + { \@@_change_case_letterlike:nnnnN { upper } { end } {#1} {#2} #3 } +\cs_new:Npn \@@_change_case_letterlike:nnnnN #1#2#3#4#5 + { + \cs_if_exist:cTF { c_@@_ #1 case_ \token_to_str:N #5 _tl } + { + \@@_change_case_store:v + { c_@@_ #1 case_ \token_to_str:N #5 _tl } + \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#4} + } + { + \@@_change_case_store:n {#5} + \cs_if_exist:cTF + { + c_@@_ + \str_if_eq:nnTF {#1} { lower } { upper } { lower } + case_ \token_to_str:N #5 _tl + } + { \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#4} } + { \@@_change_case_loop:nnw {#3} {#4} } + } + } +% \end{macrocode} +% For upper- and lowercase changes, once we get to this stage there are only +% a couple of questions remaining: is there a language-specific mapping and +% 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 + { + \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 } + } + {#1} {#1} {#2} #3 + } +\cs_new:Npn \@@_change_case_char_upper:nnN #1#2#3 + { + \cs_if_exist_use:cF { @@_change_case_upper_ #2 :nnnN } + { \@@_change_case_char:nnnN } + {#1} {#1} {#2} #3 + } +% \end{macrocode} +% If the current character is an uppercase sigma, the a check is made on the +% next item in the input. If it is \texttt{N}-type and not a control sequence +% 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 + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_change_case_lower_sigma:nnnN #1#2#3#4 + { + \int_compare:nNnTF { `#4 } = { "03A3 } + { \@@_change_case_lower_sigma:nnNw {#2} {#3} #4 } + { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + } + \cs_new:Npn \@@_change_case_lower_sigma:nnNw #1#2#3#4 \q_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_lower_sigma:NnnN #3 } + { + \@@_change_case_store:e + { \char_generate:nn { "03C2 } { \@@_char_catcode:N #3 } } + \@@_change_case_loop:nnw + } + {#1} {#2} #4 \q_recursion_stop + } + \cs_new:Npn \@@_change_case_lower_sigma:NnnN #1#2#3#4 + { + \@@_change_case_store:e + { + \token_if_letter:NTF #4 + { \char_generate:nn { "03C3 } { \@@_char_catcode:N #1 } } + { \char_generate:nn { "03C2 } { \@@_char_catcode:N #1 } } + } + \@@_change_case_loop:nnw {#2} {#3} #4 + } + } +% \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 +% \TeX{}'s, where we just have one token to worry about. The one wrinkle here +% is that for look-ahead we'd get into trouble: luckily, only Dutch has that +% issue. +% \begin{macrocode} +\cs_new:Npx \@@_change_case_char_title:nnN #1#2#3 + { + \bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { \exp_not:N \token_if_letter:NTF #3 } + { + \exp_not:N \bool_lazy_or:nnTF + { \exp_not:N \token_if_letter_p:N #3 } + { \exp_not:N \token_if_active_p:N #3 } + } + { \exp_not:N \use:c { @@_change_case_char_ #1 :nN } } + { \exp_not:N \@@_change_case_char_title:nnnN { title } {#1} } + {#2} #3 + } +\cs_new_eq:NN \@@_change_case_char_titleonly:nnN + \@@_change_case_char_title:nnN +\cs_new:Npn \@@_change_case_char_title:nN #1#2 + { \@@_change_case_char_title:nnnN { title } { lower } {#1} #2 } +\cs_new:Npn \@@_change_case_char_titleonly:nN #1#2 + { \@@_change_case_char_title:nnnN { title } { end } {#1} #2 } +\cs_new:Npn \@@_change_case_char_title:nnnN #1#2#3#4 + { + \cs_if_exist_use:cF { @@_change_case_title_ #3 :nnnN } + { + \cs_if_exist_use:cF { @@_change_case_upper_ #3 :nnnN } + { \@@_change_case_char:nnnN } + } + {#1} {#2} {#3} #4 + } +% \end{macrocode} +% For Unicode engines we can handle all characters directly. However, for +% the $8$-bit engines the aim is to deal with (a subset of) Unicode (UTF-8) +% input. They deal with that by making the upper half of the range active, +% so we look for that and if found work out how many UTF-8 octets there +% are to deal with. Those can then be grabbed to reconstruct the full +% Unicode character, which is then used in a lookup. (As will become +% obvious below, there is no intention here of covering all of Unicode.) +% \begin{macrocode} +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_change_case_char:nnnN #1#2#3#4 + { + \@@_change_case_store:e + { \use:c { char_ #1 case :N } #4 } + \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#3} + } + } + { + \cs_new:Npn \@@_change_case_char:nnnN #1#2#3#4 + { + \int_compare:nNnTF { `#4 } > { "80 } + { + \int_compare:nNnTF { `#4 } < { "E0 } + { \@@_change_case_char_UTFviii:nnnNN } + { + \int_compare:nNnTF { `#4 } < { "F0 } + { \@@_change_case_char_UTFviii:nnnNNN } + { \@@_change_case_char_UTFviii:nnnNNNN } + } + {#1} {#2} {#3} #4 + } + { + \@@_change_case_store:e{ \use:c { char_ #1 case :N } #4 } + \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#3} + } + } + \cs_new:Npn \@@_change_case_char_UTFviii:nnnNN #1#2#3#4#5 + { \@@_change_case_char_UTFviii:nnnn {#1} {#2} {#3} {#4#5} } + \cs_new:Npn \@@_change_case_char_UTFviii:nnnNNN #1#2#3#4#5#6 + { \@@_change_case_char_UTFviii:nnnn {#1} {#2} {#3} {#4#5#6} } + \cs_new:Npn \@@_change_case_char_UTFviii:nnnNNNNN #1#2#3#4#5#6#7 + { \@@_change_case_char_UTFviii:nnnn {#1} {#2} {#3} {#4#5#6#7} } + \cs_new:Npn \@@_change_case_char_UTFviii:nnnn #1#2#3#4 + { + \cs_if_exist:cTF { c_@@_ #1 case_ \tl_to_str:n {#4} _tl } + { + \@@_change_case_store:v + { c_@@_ #1 case_ \tl_to_str:n {#4} _tl } + } + { \@@_change_case_store:n {#4} } + \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#3} + } + } +\cs_new:Npn \@@_change_case_char_next_lower:nn #1#2 + { \@@_change_case_loop:nnw {#1} {#2} } +\cs_new_eq:NN \@@_change_case_char_next_upper:nn + \@@_change_case_char_next_lower:nn +\cs_new_eq:NN \@@_change_case_char_next_title:nn + \@@_change_case_char_next_lower:nn +\cs_new_eq:NN \@@_change_case_char_next_titleonly:nn + \@@_change_case_char_next_lower:nn +\cs_new:Npn \@@_change_case_char_next_end:nn #1#2 + { \@@_change_case_break:w } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \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_upper_de-alt:nnnN} +% A simple alternative version for German. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:cpn { @@_change_case_upper_de-alt:nnnN } #1#2#3#4 + { + \int_compare:nNnTF { `#4 } = { "00DF } + { + \@@_change_case_store:e + { \char_generate:nn { "1E9E } { \@@_char_catcode:N #4 } } + \use:c { @@_change_case_char_next_ #2 :nn } + {#2} {#3} + } + { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + } + } +% \end{macrocode} +% \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} +% 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. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_change_case_upper_el:nnnN #1#2#3#4 + { + \@@_change_case_if_greek:nTF { `#4 } + { + \exp_args:Ne \@@_change_case_upper_el:nnnn + { \char_to_nfd:N #4 } {#1} {#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 + { + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_upper_el:nnN } + { \@@_change_case_loop:nnw } + {#1} {#2} #3 \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. +% \begin{macrocode} + \cs_new:Npn \@@_change_case_upper_el:nnN #1#2#3 + { + \token_if_cs:NTF #3 + { \@@_change_case_loop:nnw {#1} {#2} #3 } + { + \int_compare:nNnTF { `#3 } = { "0308 } + { + \@@_change_case_store:n {#3} + \@@_change_case_upper_el_loop:nnw {#1} {#2} + } + { + \bool_lazy_any:nTF + { + { \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_store:e + { + \char_generate:nn { "0308 } + { \@@_char_catcode:N #3 } + } + \@@_change_case_upper_el_loop:nnw {#1} {#2} + } + { + \int_compare:nNnTF { `#3 } = { "0345 } + { \@@_change_case_loop:nnw {#1} {#2} } + { \@@_change_case_loop:nnw {#1} {#2} #3 } + } + } + } + } + } + \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 > "1FFF \exp_stop_f: + \prg_return_false: + \else: + \prg_return_true: + \fi: + \fi: + \else: + \prg_return_true: + \fi: + \fi: + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \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. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_change_case_title_el:nnnN #1#2#3#4 + { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP] +% { +% \@@_change_cases_lower_lt:nnnN , +% \@@_change_cases_lower_lt_auxi:nnnN , +% \@@_change_cases_lower_lt_auxii:nnnN +% } +% \begin{macro}[rEXP]{\@@_change_case_lower_lt:nnw} +% \begin{macro}[rEXP]{\@@_change_case_lower_lt:nnN} +% For Lithuanian, the issue to be dealt with is dots over lower case +% letters: these should be present if there is another accent. The first step +% is a simple match attempt: look for the three uppercase accented letters +% which should gain a dot-above char in their lowercase form. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_change_case_lower_lt:nnnN #1#2#3#4 + { + \exp_args:Ne \@@_change_case_lower_lt_auxi:nnnN + { + \int_case:nn { `#4 } + { + { "00CC } { "0300 } + { "00CD } { "0301 } + { "0128 } { "0303 } + } + } + {#2} {#3} #4 + } +% \end{macrocode} +% If there was a hit, output the result with the dot-above and move on. +% Otherwise, look for one of the three letters that can take a combining +% accent: I, J and I-ogonek. +% \begin{macrocode} + \cs_new:Npn \@@_change_case_lower_lt_auxi:nnnN #1#2#3#4 + { + \tl_if_blank:nTF {#1} + { + \exp_args:Ne \@@_change_case_lower_lt_auxii:nnnN + { + \int_case:nn { `#4 } + { + { "0049 } { "0069 } + { "004A } { "006A } + { "012E } { "012F } + } + } + {#2} {#3} #4 + } + { + \@@_change_case_store:e + { + \char_generate:nn { "0069 } { \@@_char_catcode:N #4 } + \char_generate:nn { "0307 } { \@@_char_catcode:N #4 } + \char_generate:nn {#1} { \@@_char_catcode:N #4 } + } + \@@_change_case_loop:nnw {#2} {#3} + } + } +% \end{macrocode} +% Again, branch depending on a hit. If there is one, we output the character +% then need to look for a combining accent: as usual, we need to be aware of +% the loop situation. +% \begin{macrocode} + \cs_new:Npn \@@_change_case_lower_lt_auxii:nnnN #1#2#3#4 + { + \tl_if_blank:nTF {#1} + { \@@_change_case_lower_sigma:nnnN {#2} {#2} {#3} #4 } + { + \@@_change_case_store:e + { \char_generate:nn {#1} { \@@_char_catcode:N #4 } } + \@@_change_case_lower_lt:nnw {#2} {#3} + } + } + \cs_new:Npn \@@_change_case_lower_lt:nnw #1#2#3 \q_recursion_stop + { + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_lower_lt:nnN } + { \@@_change_case_loop:nnw } + {#1} {#2} #3 \q_recursion_stop + } + \cs_new:Npn \@@_change_case_lower_lt:nnN #1#2#3 + { + \bool_lazy_and:nnT + { ! \token_if_cs_p:N #3 } + { + \bool_lazy_any_p:n + { + { \int_compare_p:nNn { `#3 } = { "0300 } } + { \int_compare_p:nNn { `#3 } = { "0301 } } + { \int_compare_p:nNn { `#3 } = { "0303 } } + } + } + { + \@@_change_case_store:e + { \char_generate:nn { "0307 } { \@@_char_catcode:N #3 } } + } + \@@_change_case_loop:nnw {#1} {#2} #3 + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}[EXP] +% { +% \@@_change_cases_upper_lt:nnnN , +% \@@_change_cases_upper_lt_aux:nnnN +% } +% \begin{macro}[rEXP]{\@@_change_case_upper_lt:nnw} +% \begin{macro}[rEXP]{\@@_change_case_upper_lt:nnN} +% The uppercasing version: first find i/j/i-ogonek, then look for the +% combining char: drop it if present. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_change_case_upper_lt:nnnN #1#2#3#4 + { + \exp_args:Ne \@@_change_case_upper_lt_aux:nnnN + { + \int_case:nn { `#4 } + { + { "0069 } { "0049 } + { "006A } { "004A } + { "012F } { "012E } + } + } + {#2} {#3} #4 + } + \cs_new:Npn \@@_change_case_upper_lt_aux:nnnN #1#2#3#4 + { + \tl_if_blank:nTF {#1} + { \@@_change_case_char:nnnN { upper } {#2} {#3} #4 } + { + \@@_change_case_store:e + { \char_generate:nn {#1} { \@@_char_catcode:N #4 } } + \@@_change_case_upper_lt:nnw {#2} {#3} + } + } + \cs_new:Npn \@@_change_case_upper_lt:nnw #1#2#3 \q_recursion_stop + { + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_upper_lt:nnN } + { \use:c { @@_change_case_char_next_ #1 :nn } } + {#1} {#2} #3 \q_recursion_stop + } + \cs_new:Npn \@@_change_case_upper_lt:nnN #1#2#3 + { + \bool_lazy_and:nnTF + { ! \token_if_cs_p:N #3 } + { \int_compare_p:nNn { `#3 } = { "0307 } } + { \use:c { @@_change_case_char_next_ #1 :nn } {#1} {#2} } + { \use:c { @@_change_case_char_next_ #1 :nn } {#1} {#2} #3 } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_change_case_title_nl:nnnN} +% \begin{macro}[EXP]{\@@_change_case_title_nl:nnw} +% \begin{macro}[EXP]{\@@_change_case_title_nl:nnN} +% For Dutch, there is a single look-ahead test for \texttt{ij} when +% title casing. If the appropriate letters are found, produce \texttt{IJ} +% and gobble the \texttt{j}/\texttt{J}. +% \begin{macrocode} +\cs_new:Npn \@@_change_case_title_nl:nnnN #1#2#3#4 + { + \bool_lazy_or:nnTF + { \int_compare_p:nNn { `#4 } = { "0049 } } + { \int_compare_p:nNn { `#4 } = { "0069 } } + { + \@@_change_case_store:e + { \char_generate:nn { "0049 } { \@@_char_catcode:N #4 } } + \@@_change_case_title_nl:nnw {#2} {#3} + } + { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + } +\cs_new:Npn \@@_change_case_title_nl:nnw #1#2#3 \q_recursion_stop + { + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_title_nl:nnN } + { \use:c { @@_change_case_char_next_ #1 :nn } } + {#1} {#2} #3 \q_recursion_stop + } +\cs_new:Npn \@@_change_case_title_nl:nnN #1#2#3 + { + \bool_lazy_and:nnTF + { ! \token_if_cs_p:N #3 } + { + \bool_lazy_or_p:nn + { \int_compare_p:nNn { `#3 } = { "004A } } + { \int_compare_p:nNn { `#3 } = { "006A } } + } + { + \@@_change_case_store:e + { \char_generate:nn { "004A } { \@@_char_catcode:N #3 } } + \use:c { @@_change_case_char_next_ #1 :nn } {#1} {#2} + } + { \use:c { @@_change_case_char_next_ #1 :nn } {#1} {#2} #3 } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_change_case_lower_tr:nnnN} +% \begin{macro}[EXP]{\@@_change_case_lower_tr:nnNw} +% \begin{macro}[EXP]{\@@_change_case_lower_tr:nnN} +% \begin{macro}[EXP]{\@@_change_case_lower_tr:nnnNN} +% The Turkic languages need special treatment for dotted-i and dotless-i. +% The lower casing rule can be expressed in terms of searching first for +% either a dotless-I or a dotted-I. In the latter case the mapping is +% easy, but in the former there is a second stage search. +% \begin{macrocode} +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_change_case_lower_tr:nnnN #1#2#3#4 + { + \int_compare:nNnTF { `#4 } = { "0049 } + { \@@_change_case_lower_tr:nnNw {#1} {#3} #4 } + { + \int_compare:nNnTF { `#4 } = { "0130 } + { + \@@_change_case_store:e + { \char_generate:nn { "0069 } { \@@_char_catcode:N #4 } } + \@@_change_case_loop:nnw {#1} {#3} + } + { \@@_change_case_lower_sigma:nnnN {#1} {#2} {#3} #4 } + } + } +% \end{macrocode} +% After a dotless-I there may be a dot-above character. If there is then +% a dotted-i should be produced, otherwise output a dotless-i. When the +% combination is found both the dotless-I and the dot-above char have to +% be removed from the input. +% \begin{macrocode} + \cs_new:Npn \@@_change_case_lower_tr:nnNw #1#2#3#4 \q_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_lower_tr:nnN } + { + \@@_change_case_store:e + { \char_generate:nn { "0131 } { \@@_char_catcode:N #3 } } + \@@_change_case_loop:nnw + } + {#1} {#2} #4 \q_recursion_stop + } + \cs_new:Npn \@@_change_case_lower_tr:nnN #1#2#3 + { + \bool_lazy_or:nnTF + { \token_if_cs_p:N #3 } + { ! \int_compare_p:nNn { `#3 } = { "0307 } } + { + \@@_change_case_store:e + { \char_generate:nn { "0131 } { \@@_char_catcode:N #3 } } + \@@_change_case_loop:nnw {#1} {#2} #3 + } + { + \@@_change_case_store:e + { \char_generate:nn { "0069 } { \@@_char_catcode:N #3 } } + \@@_change_case_loop:nnw {#1} {#2} + } + } + } +% \end{macrocode} +% For $8$-bit engines, dot-above is not available so there is a simple +% test for an upper-case I. Then we can look for the UTF-8 representation of +% an upper case dotted-I without the combining char. If it's not there, +% preserve the UTF-8 sequence as-is. With $8$bit engines, we cannot +% completely preserve category codes, so we have to make some assumptions: +% output a \enquote{normal} \texttt{i} for the dotted case. As the original +% character here is catcode-$13$, we have to make a choice about handling +% of |i|: generate a \enquote{normal} one. +% \begin{macrocode} + { + \cs_new:Npn \@@_change_case_lower_tr:nnnN #1#2#3#4 + { + \int_compare:nNnTF { `#4 } = { "0049 } + { + \@@_change_case_store:V \c_@@_dotless_i_tl + \@@_change_case_loop:nnw {#1} {#3} + } + { + \int_compare:nNnTF { `#4 } = { "00C4 } + { \@@_change_case_lower_tr:nnnNN {#1} {#2} {#3} #4 } + { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + } + } + \cs_new:Npn \@@_change_case_lower_tr:nnnNN #1#2#3#4#5 + { + \int_compare:nNnTF { `#5 } = { "00B0 } + { + \@@_change_case_store:e + { + \char_generate:nn { "0069 } + { \char_value_catcode:n { "0069 } } + } + \@@_change_case_loop:nnw {#1} {#3} + } + { \@@_change_case_char:nnnN {#1} {#2} {#3} #4#5 } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}[EXP]{\@@_change_case_upper_tr:nnnN} +% Uppercasing is easier: just one exception with no context. +% \begin{macrocode} +\cs_new:Npx \@@_change_case_upper_tr:nnnN #1#2#3#4 + { + \exp_not:N \int_compare:nNnTF { `#4 } = { "0069 } + { + \bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \exp_not:N \@@_change_case_store:e + { + \exp_not:N \char_generate:nn { "0130 } + { \exp_not:N \@@_char_catcode:N #4 } + } + } + { + \exp_not:N \@@_change_case_store:V + \exp_not:N \c_@@_dotted_I_tl + } + \exp_not:N \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#3} + } + { \exp_not:N \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP] +% {\@@_change_case_lower_az:nnnN, \@@_change_case_upper_az:nnnN} +% Straight copies. +% \begin{macrocode} +\cs_new_eq:NN \@@_change_case_lower_az:nnnN + \@@_change_case_lower_tr:nnnN +\cs_new_eq:NN \@@_change_case_upper_az:nnnN + \@@_change_case_upper_tr:nnnN +% \end{macrocode} +% \end{macro} +% +% \subsection{Case changing data for $8$-bit engines} +% +% \begin{variable} +% { +% \c_@@_dotless_i_tl , +% \c_@@_dotted_I_tl , +% \c_@@_i_ogonek_tl , +% \c_@@_I_ogonek_tl +% } +% For cases where there is an $8$-bit option in the |T1| font set up, +% a variant is provided in both cases. +% \begin{macrocode} +\group_begin: + \bool_lazy_or:nnF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_set_protected:Npn \@@_tmp:w #1#2 + { + \group_begin: + \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4 + { + \tl_const:Nx #1 + { + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {##1} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {##2} { 13 } + } + } + \use:x + { \@@_tmp:w \char_to_utfviii_bytes:n { "#2 } } + \group_end: + } + \@@_tmp:w \c_@@_dotless_i_tl { 0131 } + \@@_tmp:w \c_@@_dotted_I_tl { 0130 } + \@@_tmp:w \c_@@_i_ogonek_tl { 012F } + \@@_tmp:w \c_@@_I_ogonek_tl { 012E } + } +\group_end: +% \end{macrocode} +% \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 +% 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. +% \begin{macrocode} +\group_begin: + \bool_lazy_or:nnF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_set_protected:Npn \@@_loop:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#1} + \use:x + { + \@@_tmp:w + \char_to_utfviii_bytes:n { "#1 } + \char_to_utfviii_bytes:n { "#2 } + } + \@@_loop:nn + } + \cs_set_protected:Npn \@@_tmp:nnnn #1#2#3#4#5 + { + \tl_const:cx + { + c_@@_ #1 case_ + \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 {#4} { 13 } + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_not:N \char_generate:nn {#5} { 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 } + _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 } + } + \@@_tmp:nnnn { upper } {#5} {#6} {#1} {#2} + \@@_tmp:nnnn { title } {#5} {#6} {#1} {#2} + } + \@@_loop:nn + { 00C0 } { 00E0 } + { 00C1 } { 00E1 } + { 00C2 } { 00E2 } + { 00C3 } { 00E3 } + { 00C4 } { 00E4 } + { 00C5 } { 00E5 } + { 00C6 } { 00E6 } + { 00C7 } { 00E7 } + { 00C8 } { 00E8 } + { 00C9 } { 00E9 } + { 00CA } { 00EA } + { 00CB } { 00EB } + { 00CC } { 00EC } + { 00CD } { 00ED } + { 00CE } { 00EE } + { 00CF } { 00EF } + { 00D0 } { 00F0 } + { 00D1 } { 00F1 } + { 00D2 } { 00F2 } + { 00D3 } { 00F3 } + { 00D4 } { 00F4 } + { 00D5 } { 00F5 } + { 00D6 } { 00F6 } + { 00D8 } { 00F8 } + { 00D9 } { 00F9 } + { 00DA } { 00FA } + { 00DB } { 00FB } + { 00DC } { 00FC } + { 00DD } { 00FD } + { 00DE } { 00FE } + { 0100 } { 0101 } + { 0102 } { 0103 } + { 0104 } { 0105 } + { 0106 } { 0107 } + { 0108 } { 0109 } + { 010A } { 010B } + { 010C } { 010D } + { 010E } { 010F } + { 0110 } { 0111 } + { 0112 } { 0113 } + { 0114 } { 0115 } + { 0116 } { 0117 } + { 0118 } { 0119 } + { 011A } { 011B } + { 011C } { 011D } + { 011E } { 011F } + { 0120 } { 0121 } + { 0122 } { 0123 } + { 0124 } { 0125 } + { 0128 } { 0129 } + { 012A } { 012B } + { 012C } { 012D } + { 012E } { 012F } + { 0132 } { 0133 } + { 0134 } { 0135 } + { 0136 } { 0137 } + { 0139 } { 013A } + { 013B } { 013C } + { 013E } { 013F } + { 0141 } { 0142 } + { 0143 } { 0144 } + { 0145 } { 0146 } + { 0147 } { 0148 } + { 014A } { 014B } + { 014C } { 014D } + { 014E } { 014F } + { 0150 } { 0151 } + { 0152 } { 0153 } + { 0154 } { 0155 } + { 0156 } { 0157 } + { 0158 } { 0159 } + { 015A } { 015B } + { 015C } { 015D } + { 015E } { 015F } + { 0160 } { 0161 } + { 0162 } { 0163 } + { 0164 } { 0165 } + { 0168 } { 0169 } + { 016A } { 016B } + { 016C } { 016D } + { 016E } { 016F } + { 0170 } { 0171 } + { 0172 } { 0173 } + { 0174 } { 0175 } + { 0176 } { 0177 } + { 0178 } { 00FF } + { 0179 } { 017A } + { 017B } { 017C } + { 017D } { 017E } + { 01CD } { 01CE } + { 01CF } { 01D0 } + { 01D1 } { 01D2 } + { 01D3 } { 01D4 } + { 01E2 } { 01E3 } + { 01E6 } { 01E7 } + { 01E8 } { 01E9 } + { 01EA } { 01EB } + { 01F4 } { 01F5 } + { 0218 } { 0219 } + { 021A } { 021B } + \q_recursion_tail ? + \q_recursion_stop + \cs_set_protected:Npn \@@_tmp:w #1#2#3 + { + \group_begin: + \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4 + { + \tl_const:cx + { + c_@@_ #3 case_ + \char_generate:nn {##1} { 12 } + \char_generate:nn {##2} { 12 } + _tl + } + {#2} + } + \use:x + { \@@_tmp:w \char_to_utfviii_bytes:n { "#1 } } + \group_end: + } + \@@_tmp:w { 00DF } { SS } { upper } + \@@_tmp:w { 00DF } { Ss } { title } + \@@_tmp:w { 0131 } { I } { upper } + } + \group_end: +% \end{macrocode} +% +% The (fixed) look-up mappings for letter-like control sequences. +% \begin{macrocode} +\group_begin: + \cs_set_protected:Npn \@@_change_case_setup:NN #1#2 + { + \quark_if_recursion_tail_stop:N #1 + \tl_const:cn { c_@@_lowercase_ \token_to_str:N #1 _tl } + { #2 } + \tl_const:cn { c_@@_uppercase_ \token_to_str:N #2 _tl } + { #1 } + \@@_change_case_setup:NN + } + \@@_change_case_setup:NN + \AA \aa + \AE \ae + \DH \dh + \DJ \dj + \IJ \ij + \L \l + \NG \ng + \O \o + \OE \oe + \SS \ss + \TH \th + \q_recursion_tail ? + \q_recursion_stop + \tl_const:cn { c_@@_uppercase_ \token_to_str:N \i _tl } { I } + \tl_const:cn { c_@@_uppercase_ \token_to_str:N \j _tl } { J } +\group_end: +% \end{macrocode} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text.dtx new file mode 100644 index 00000000000..0efc072cf89 --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3text.dtx @@ -0,0 +1,903 @@ +% \iffalse meta-comment +% +%% File: l3text.dtx +% +% Copyright (C) 2020 The LaTeX3 Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% This file is part of the "l3kernel bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/latex3 +% +% for those people who are interested. +% +%<*driver> +\documentclass[full,kernel]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{^^A +% The \textsf{l3text} package: text processing^^A +% } +% +% \author{^^A +% The \LaTeX3 Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Released 2020-01-12} +% +% \maketitle +% +% \begin{documentation} +% +% \section{\pkg{l3text} documentation} +% +% This module deals with manipulation of (formatted) text; such material is +% comprised of a restricted set of token list content. The functions provided +% here concern conversion of textual content for example in case changing, +% generation of bookmarks and extraction to tags. All of the major functions +% operate by expansion. Begin-group and end-group tokens in the \meta{text} +% are normalized and become |{| and |}|, respectively. +% +% \subsection{Expanding text} +% +% \begin{function}[EXP, added = 2020-01-02]{\text_expand:n} +% \begin{syntax} +% \cs{text_expand:n} \Arg{text} +% \end{syntax} +% Takes user input \meta{text} and transforms expandable and implicit +% content to the explicit equivalent. Protected commands (typically +% formatting) are left in place, and no processing takes place of +% math mode material (as delimited by pairs given in +% \cs{l_text_math_delims_tl} or as the argument to commands listed +% in \cs{l_text_math_arg_tl}). Commands which are neither engine- +% nor \LaTeX{} protected are expanded exhaustively. Implicit tokens, +% including implicit groups, are converted to their explicit equivalent. +% Any commands listed in \cs{l_text_expand_exclude_tl}, +% \cs{l_text_accents_tl} and \cs{l_text_letterlike_tl} are excluded from +% expansion +% \end{function} +% +% \subsection{Case changing} +% +% \begin{function}[EXP, added = 2019-11-20] +% { +% \text_lowercase:n, \text_uppercase:n, \text_titlecase:n, +% \text_titlecase_first:n, +% \text_lowercase:nn, \text_uppercase:nn, \text_titlecase:nn, +% \text_titlecase_first:nn +% } +% \begin{syntax} +% \cs{text_uppercase:n} \Arg{tokens} +% \cs{text_uppercase:nn} \Arg{language} \Arg{tokens} +% \end{syntax} +% Takes user input \meta{text} first applies \cs{text_expand}, then +% transforms the case of character tokens as specified by the +% function name. The category code of letters are not changed by this +% process (at least where they can be represented by the engine as a single +% token: $8$-bit engines may require active characters). +% +% Upper- and lowercase have the obvious meanings. Titlecasing may be regarded +% informally as converting the first character of the \meta{tokens} to +% uppercase and the rest to lowercase. However, the process is more complex +% than this as there are some situations where a single lowercase character +% maps to a special form, for example \texttt{ij} in Dutch which becomes +% \texttt{IJ}. The \texttt{titlecase_first} variant does not attempt +% any case changing at all after the first letter has been processed. +% +% Importantly, notice that these functions are intended for working with +% user \emph{text for typesetting}. For case changing programmatic data see +% the \pkg{l3str} module and discussion there of \cs{str_lowercase:n}, +% \cs{str_uppercase:n} and \cs{str_foldcase:n}. +% +% Case changing does not take place within math mode material so for example +% \begin{verbatim} +% \text_uppercase:n { Some~text~$y = mx + c$~with~{Braces} } +% \end{verbatim} +% becomes +% \begin{verbatim} +% SOME TEXT $y = mx + c$ WITH {BRACES} +% \end{verbatim} +% +% The arguments of commands listed in \cs{l_text_case_exclude_arg_tl} +% are excluded from case changing; the latter are entirely non-textual +% content (such as labels). +% +% As is generally true for \pkg{expl3}, these functions are designed to +% work with Unicode input only. As such, UTF-8 input is assumed for +% \emph{all} engines. When used with \XeTeX{} or \LuaTeX{} a full range of +% Unicode transformations are enabled. Specifically, the standard mappings +% here follow those defined by the \href{http://www.unicode.org}^^A +% {Unicode Consortium} in \texttt{UnicodeData.txt} and +% \texttt{SpecialCasing.txt}. In the case of $8$-bit engines, mappings +% are provided for characters which can be represented in output typeset +% using the |T1| font encoding. Thus for example \texttt{ä} can be +% case-changed using \pdfTeX{}. For \pTeX{} only the ASCII range is +% covered as the engine treats input outside of this range as east Asian. +% +% Language-sensitive conversions are enabled using the \meta{language} +% argument, and follow Unicode Consortium guidelines. Currently, the +% languages recognised for special handling are as follows. +% \begin{itemize} +% \item Azeri and Turkish (\texttt{az} and \texttt{tr}). +% The case pairs I/i-dotless and I-dot/i are activated for these +% languages. The combining dot mark is removed when lowercasing +% I-dot and introduced when upper casing i-dotless. +% \item German (\texttt{de-alt}). +% An alternative mapping for German in which the lowercase +% \emph{Eszett} maps to a \emph{gro\ss{}es Eszett}. +% \item Greek (\texttt{el}). +% Removes accents from Greek letters when uppercasing; titlecasing +% leaves accents in place. +% \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 +% lowercasing of the relevant uppercase letters both when input as +% single Unicode codepoints and when using combining accents. The +% combining dot is removed when uppercasing in these cases. Note that +% \emph{only} the accents used in Lithuanian are covered: the behaviour +% of other accents are not modified. +% \item Dutch (\texttt{nl}). +% Capitalisation of \texttt{ij} at the beginning of titlecased +% input produces \texttt{IJ} rather than \texttt{Ij}. The output +% retains two separate letters, thus this transformation \emph{is} +% available using \pdfTeX{}. +% \end{itemize} +% \end{function} +% +% \subsection{Control variables} +% +% \begin{variable}{\l_text_accents_tl} +% Lists commands which represent accents, and which are left unchanged +% by expansion. (Defined only for the \LaTeXe{} package.) +% \end{variable} +% +% \begin{variable}{\l_text_letterlike_tl} +% Lists commands which represent letters; these are left unchanged by +% expansion. (Defined only for the \LaTeXe{} package.) +% \end{variable} +% +% \begin{variable}{\l_text_math_arg_tl} +% Lists commands present in the \meta{text} where the argument of the +% command should be treated as math mode material. The treatment here is +% similar to \cs{l_text_math_delims_tl} but for a command rather than +% paired delimiters. +% \end{variable} +% +% \begin{variable}{\l_text_math_delims_tl} +% Lists pairs of tokens which delimit (in-line) math mode content; such +% content \emph{may} be excluded from processing. +% \end{variable} +% +% \begin{variable}{\l_text_expand_exclude_tl} +% Lists commands which are excluded from expansion. (Defined only for the +% \LaTeXe{} package.) +% \end{variable} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3text} implementation} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=text> +% \end{macrocode} +% +% \subsection{Utilities} +% +% \begin{macro}[EXP] +% { +% \@@_token_to_explicit:N , +% \@@_token_to_explicit_char:N , +% \@@_token_to_explicit_cs:N , +% \@@_token_to_explicit_cs_aux:N +% } +% \begin{macro}[EXP]{\@@_token_to_explicit:n} +% \begin{macro}[EXP] +% { +% \@@_token_to_explicit_auxi:w , +% \@@_token_to_explicit_auxii:w , +% \@@_token_to_explicit_auxiii:w +% } +% The idea here is to take a token and ensure that if it's an implicit +% char, we output the explicit version. Otherwise, the token needs to be +% unchanged. First, we have to split between control sequences and everything +% else. +% \begin{macrocode} +\group_begin: + \char_set_catcode_active:n { 0 } + \cs_new:Npn \@@_token_to_explicit:N #1 + { + \if_catcode:w \exp_not:N #1 + \if_catcode:w \scan_stop: \exp_not:N #1 + \scan_stop: + \else: + \exp_not:N ^^@ + \fi: + \exp_after:wN \@@_token_to_explicit_cs:N + \else: + \exp_after:wN \@@_token_to_explicit_char:N + \fi: + #1 + } +\group_end: +% \end{macrocode} +% For control sequences, we can check for macros versus other cases using +% \cs{if_meaning:w}, then explicitly check for \tn{chardef} and +% \tn{mathchardef}. +% \begin{macrocode} +\cs_new:Npn \@@_token_to_explicit_cs:N #1 + { + \exp_after:wN \if_meaning:w \exp_not:N #1 #1 + \exp_after:wN \use:nn \exp_after:wN + \@@_token_to_explicit_cs_aux:N + \else: + \exp_after:wN \exp_not:n + \fi: + {#1} + } +\cs_new:Npn \@@_token_to_explicit_cs_aux:N #1 + { + \bool_lazy_or:nnTF + { \token_if_chardef_p:N #1 } + { \token_if_mathchardef_p:N #1 } + { + \char_generate:nn {#1} + { \char_value_catcode:n {#1} } + } + {#1} + } +% \end{macrocode} +% For character tokens, we need to filter out the implicit characters from +% those that are explicit. That's done here, then if necessary we work out +% the category code and generate the char. To avoid issues with alignment +% tabs, that one is done by elimination rather than looking up the code +% explicitly. The trick with finding the charcode is that the \TeX{} +% messages are either \texttt{the \meta{something} character \meta{char}} +% or \texttt{the \meta{type} \meta{char}}. +% \begin{macrocode} +\cs_new:Npn \@@_token_to_explicit_char:N #1 + { + \if:w + \if_catcode:w ^ \exp_args:No \str_tail:n { \token_to_str:N #1 } ^ + \token_to_str:N #1 #1 + \else: + AB + \fi: + \exp_after:wN \exp_not:n + \else: + \exp_after:wN \@@_token_to_explicit:n + \fi: + {#1} + } +\cs_new:Npn \@@_token_to_explicit:n #1 + { + \exp_after:wN \@@_token_to_explicit_auxi:w + \int_value:w + \if_catcode:w \c_group_begin_token #1 1 \else: + \if_catcode:w \c_group_end_token #1 2 \else: + \if_catcode:w \c_math_toggle_token #1 3 \else: + \if_catcode:w ## #1 6 \else: + \if_catcode:w ^ #1 7 \else: + \if_catcode:w \c_math_subscript_token #1 8 \else: + \if_catcode:w \c_space_token #1 10 \else: + \if_catcode:w A #1 11 \else: + \if_catcode:w + #1 12 \else: + 4 \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: + \exp_after:wN ; + \token_to_meaning:N #1 \q_stop + } +\cs_new:Npn \@@_token_to_explicit_auxi:w #1 ; #2 \q_stop + { + \char_generate:nn + { + \if_int_compare:w #1 < 9 \exp_stop_f: + \exp_after:wN \@@_token_to_explicit_auxii:w + \else: + \exp_after:wN \@@_token_to_explicit_auxiii:w + \fi: + #2 + } + {#1} + } +\exp_last_unbraced:NNNNo \cs_new:Npn \@@_token_to_explicit_auxii:w + #1 { \tl_to_str:n { character ~ } } { ` } +\cs_new:Npn \@@_token_to_explicit_auxiii:w #1 ~ #2 ~ { ` } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_char_catcode:N} +% An idea from \pkg{l3char}: we need to get the category code of +% a specific token, not the general case. +% \begin{macrocode} +\cs_new:Npn \@@_char_catcode:N #1 + { + \if_catcode:w \exp_not:N #1 \c_math_toggle_token + 3 + \else: + \if_catcode:w \exp_not:N #1 \c_alignment_token + 4 + \else: + \if_catcode:w \exp_not:N #1 \c_math_superscript_token + 7 + \else: + \if_catcode:w \exp_not:N #1 \c_math_subscript_token + 8 + \else: + \if_catcode:w \exp_not:N #1 \c_space_token + 10 + \else: + \if_catcode:w \exp_not:N #1 \c_catcode_letter_token + 11 + \else: + \if_catcode:w \exp_not:N #1 \c_catcode_other_token + 12 + \else: + 13 + \fi: + \fi: + \fi: + \fi: + \fi: + \fi: + \fi: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP, TF]{\@@_if_expandable:N} +% Test for tokens that make sense to expand here: that is more +% restrictive than the engine view. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_expandable:N #1 { T , F , TF } + { + \token_if_expandable:NTF #1 + { + \bool_lazy_any:nTF + { + { \token_if_protected_macro_p:N #1 } + { \token_if_protected_long_macro_p:N #1 } + { \token_if_eq_meaning_p:NN \q_recursion_tail #1 } + } + { \prg_return_false: } + { \prg_return_true: } + } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Configuration variables} +% +% \begin{variable}{\l_text_accents_tl, \l_text_letterlike_tl} +% Special cases for accents and letter-like symbols, which in some cases will +% need to be converted further. +% \begin{macrocode} +%<*package> +\tl_new:N \l_text_accents_tl +\tl_set:Nn \l_text_accents_tl + { \` \' \^ \~ \= \u \. \" \r \H \v \d \c \k \b \t } +\tl_new:N \l_text_letterlike_tl +\tl_set:Nn \l_text_letterlike_tl + { + \AA \aa + \AE \ae + \DH \dh + \DJ \dj + \IJ \ij + \L \l + \NG \ng + \O \o + \OE \oe + \SS \ss + \TH \th + } +%</package> +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_text_case_exclude_arg_tl} +% Non-text arguments. +% \begin{macrocode} +\tl_new:N \l_text_case_exclude_arg_tl +\tl_set:Nn \l_text_case_exclude_arg_tl { \cite \label \ref } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_text_math_arg_tl} +% Math mode as arguments. +% \begin{macrocode} +\tl_new:N \l_text_math_arg_tl +\tl_set:Nn \l_text_math_arg_tl { \ensuremath } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_text_math_delims_tl} +% Paired math mode delimiters. +% \begin{macrocode} +\tl_new:N \l_text_math_delims_tl +\tl_set:Nn \l_text_math_delims_tl { $ $ \( \) } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_text_expand_exclude_tl} +% Commands which need not to expand. +% \begin{macrocode} +%<*package> +\tl_new:N \l_text_expand_exclude_tl +\tl_set:Nn \l_text_expand_exclude_tl + { \cite \label \ref } +%</package> +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\l_@@_math_mode_tl} +% Used to control math mode output: internal as there is a dedicated +% setter. +% \begin{macrocode} +\tl_new:N \l_@@_math_mode_tl +% \end{macrocode} +% \end{macro} +% +% \subsection{Expansion to formatted text} +% +% \begin{variable}{\c_@@_chardef_space_token, \c_@@_mathchardef_space_token} +% \begin{variable} +% {\c_@@_chardef_group_begin_token, \c_@@_mathchardef_group_begin_token} +% \begin{variable} +% {\c_@@_chardef_group_end_token, \c_@@_mathchardef_group_end_token} +% Markers for implict char handling. +% \begin{macrocode} +\tex_chardef:D \c_@@_chardef_space_token = `\ % +\tex_mathchardef:D \c_@@_mathchardef_space_token = `\ % +\tex_chardef:D \c_@@_chardef_group_begin_token = `\{ % `\} +\tex_mathchardef:D \c_@@_mathchardef_group_begin_token = `\{ % `\} `\{ +\tex_chardef:D \c_@@_chardef_group_end_token = `\} % `\{ +\tex_mathchardef:D \c_@@_mathchardef_group_end_token = `\} % +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{macro}[EXP]{\text_expand:n, \@@_expand:n} +% \begin{macro}[EXP]{\@@_expand_result:n} +% \begin{macro}[EXP]{\@@_expand_store:n, \@@_expand_store:o} +% \begin{macro}[EXP]{\@@_expand_store:nw} +% \begin{macro}[EXP]{\@@_expand_end:w} +% \begin{macro}[EXP]{\@@_expand_loop:w} +% \begin{macro}[EXP]{\@@_expand_group:n} +% \begin{macro}[EXP]{\@@_expand_space:w} +% \begin{macro}[EXP] +% { +% \@@_expand_N_type:N , +% \@@_expand_N_type_auxi:N , +% \@@_expand_N_type_auxii:N , +% \@@_expand_N_type_auxiii:N +% } +% \begin{macro}[EXP]{\@@_expand_math_search:NNN} +% \begin{macro}[EXP]{\@@_expand_math_loop:Nw} +% \begin{macro}[EXP]{\@@_expand_math_N_type:NN} +% \begin{macro}[EXP]{\@@_expand_math_group:Nn} +% \begin{macro}[EXP]{\@@_expand_math_space:Nw} +% \begin{macro}[EXP] +% { +% \@@_expand_implicit:N , +% \@@_expand_explicit:N , +% \@@_expand_exclude:N +% } +% \begin{macro}[EXP]{\@@_expand_exclude:nN} +% \begin{macro}[EXP]{\@@_expand_exclude:NN} +% \begin{macro}[EXP]{\@@_expand_exclude:Nn} +% \begin{macro}[EXP]{\@@_expand_letterlike:N} +% \begin{macro}[EXP]{\@@_expand_letterlike:NN} +% \begin{macro}[EXP] +% { +% \@@_expand_cs:N , +% \@@_expand_protect:N +% } +% \begin{macro}[EXP]{\@@_expand_protect:nN} +% \begin{macro}[EXP]{\@@_expand_protect:Nw} +% \begin{macro}[EXP]{\@@_expand_cs_expand:N} +% After precautions against |&| tokens, start a simple loop: that of +% course means that \enquote{text} cannot contain the two recursion +% quarks. The loop here must be \texttt{f}-type expandable; we have +% arbitrary user commands which might be protected \emph{and} take +% arguments, and if the expansion code is used in a typesetting +% context, that will otherwise explode. (The same issue applies more +% clearly to case changing: see the example there.) +% \begin{macrocode} +\cs_new:Npn \text_expand:n #1 + { + \__kernel_exp_not:w \exp_after:wN + { + \exp:w + \@@_expand:n {#1} + } + } +\cs_new:Npn \@@_expand:n #1 + { + \group_align_safe_begin: + \@@_expand_loop:w #1 + \q_recursion_tail \q_recursion_stop + \@@_expand_result:n { } + } +% \end{macrocode} +% The approach to making the code \texttt{f}-type expandable is to usee +% a marker result token and to shuffle the collected tokens +% \begin{macrocode} +\cs_new:Npn \@@_expand_store:n #1 + { \@@_expand_store:nw {#1} } +\cs_generate_variant:Nn \@@_expand_store:n { o } +\cs_new:Npn \@@_expand_store:nw #1#2 \@@_expand_result:n #3 + { #2 \@@_expand_result:n { #3 #1 } } +\cs_new:Npn \@@_expand_end:w #1 \@@_expand_result:n #2 + { + \group_align_safe_end: + \exp_end: + #2 + } +% \end{macrocode} +% The main loop is a standard \enquote{tl action}; groups are handled +% recursively, while spaces are just passed through. Thus all of the +% action is in handling \texttt{N}-type tokens. +% \begin{macrocode} +\cs_new:Npn \@@_expand_loop:w #1 \q_recursion_stop + { + \tl_if_head_is_N_type:nTF {#1} + { \@@_expand_N_type:N } + { + \tl_if_head_is_group:nTF {#1} + { \@@_expand_group:n } + { \@@_expand_space:w } + } + #1 \q_recursion_stop + } +\cs_new:Npn \@@_expand_group:n #1 + { + \@@_expand_store:o + { + \exp_after:wN + { + \exp:w + \@@_expand:n {#1} + } + } + \@@_expand_loop:w + } +\exp_last_unbraced:NNo \cs_new:Npn \@@_expand_space:w \c_space_tl + { + \@@_expand_store:n { ~ } + \@@_expand_loop:w + } +% \end{macrocode} +% Before we get into the real work, we have to watch out for problematic +% implicit characters: spaces and grouping tokens. Converting these to +% explicit characters later would lead to real issues as they are \emph{not} +% \texttt{N}-type. A space is the easy case, so it's dealt with first: +% just insert the explicit token and continue the loop. +% \begin{macrocode} +\cs_new:Npx \@@_expand_N_type:N #1 + { + \exp_not:N \quark_if_recursion_tail_stop_do:Nn #1 + { \exp_not:N \@@_expand_end:w } + \exp_not:N \bool_lazy_any:nTF + { + { \exp_not:N \token_if_eq_meaning_p:NN #1 \c_space_token } + { + \exp_not:N \token_if_eq_meaning_p:NN #1 + \c_@@_chardef_space_token + } + { + \exp_not:N \token_if_eq_meaning_p:NN #1 + \c_@@_mathchardef_space_token + } + } + { \exp_not:N \@@_expand_space:w \c_space_tl } + { \exp_not:N \@@_expand_N_type_auxi:N #1 } + } +% \end{macrocode} +% Implicit |{|/|}| offer two issues. First, the token could be an implicit +% brace character: we need to avoid turning that into a brace group, so filter +% out the cases manually. Then we handle the case where an implicit group is +% present. That is done in an \enquote{open-ended} way: there's the possibility +% the closing token is hidden somewhere. +% \begin{macrocode} +\cs_new:Npn \@@_expand_N_type_auxi:N #1 + { + \bool_lazy_or:nnTF + { \token_if_eq_meaning_p:NN #1 \c_@@_chardef_group_begin_token } + { \token_if_eq_meaning_p:NN #1 \c_@@_mathchardef_group_begin_token } + { + \@@_expand_store:o \c_left_brace_str + \@@_expand_loop:w + } + { + \bool_lazy_or:nnTF + { \token_if_eq_meaning_p:NN #1 \c_@@_chardef_group_end_token } + { \token_if_eq_meaning_p:NN #1 \c_@@_mathchardef_group_end_token } + { + \@@_expand_store:o \c_right_brace_str + \@@_expand_loop:w + } + { \@@_expand_N_type_auxii:N #1 } + } + } +\cs_new:Npn \@@_expand_N_type_auxii:N #1 + { + \token_if_eq_meaning:NNTF #1 \c_group_begin_token + { + { \if_false: } \fi: + \@@_expand_loop:w + } + { + \token_if_eq_meaning:NNTF #1 \c_group_end_token + { + \if_false: { \fi: } + \@@_expand_loop:w + } + { \@@_expand_N_type_auxiii:N #1 } + } + } +% \end{macrocode} +% The first step in dealing with \texttt{N}-type tokens is to look for +% math mode material: that needs to be left alone. The starting function +% has to be split into two as we need \cs{quark_if_recursion_tail_stop:N} +% first before we can trigger the search. We then look for matching +% pairs of delimiters, allowing for the case where math mode starts +% but does not end. Within math mode, we simply pass all the tokens +% through unchanged, just checking the \texttt{N}-type ones against the +% end marker. +% \begin{macrocode} +\cs_new:Npn \@@_expand_N_type_auxiii:N #1 + { + \exp_after:wN \@@_expand_math_search:NNN + \exp_after:wN #1 \l_text_math_delims_tl + \q_recursion_tail \q_recursion_tail + \q_recursion_stop + } +\cs_new:Npn \@@_expand_math_search:NNN #1#2#3 + { + \quark_if_recursion_tail_stop_do:Nn #2 + { \@@_expand_implicit:N #1 } + \token_if_eq_meaning:NNTF #1 #2 + { + \use_i_delimit_by_q_recursion_stop:nw + { + \@@_expand_store:n {#1} + \@@_expand_math_loop:Nw #3 + } + } + { \@@_expand_math_search:NNN #1 } + } +\cs_new:Npn \@@_expand_math_loop:Nw #1#2 \q_recursion_stop + { + \tl_if_head_is_N_type:nTF {#2} + { \@@_expand_math_N_type:NN } + { + \tl_if_head_is_group:nTF {#2} + { \@@_expand_math_group:Nn } + { \@@_expand_math_space:Nw } + } + #1#2 \q_recursion_stop + } +\cs_new:Npn \@@_expand_math_N_type:NN #1#2 + { + \quark_if_recursion_tail_stop_do:Nn #2 + { \@@_expand_end:w } + \@@_expand_store:n {#2} + \token_if_eq_meaning:NNTF #2 #1 + { \@@_expand_loop:w } + { \@@_expand_math_loop:Nw #1 } + } +\cs_new:Npn \@@_expand_math_group:Nn #1#2 + { + \@@_expand_store:n { {#2} } + \@@_expand_math_loop:Nw #1 + } +\exp_after:wN \cs_new:Npn \exp_after:wN \@@_expand_math_space:Nw + \exp_after:wN # \exp_after:wN 1 \c_space_tl + { + \@@_expand_store:n { ~ } + \@@_expand_math_loop:Nw #1 + } +% \end{macrocode} +% Conversion of implicit to explicit tokens does not have to account for +% spaces or brace groups: they are already fixed above. So we can assume that +% the result of this conversion is still an \texttt{N}-type token. +% \begin{macrocode} +\cs_new:Npn \@@_expand_implicit:N #1 + { + \exp_args:NNe \use:nn \@@_expand_explicit:N + { \@@_token_to_explicit:N #1 } + } +% \end{macrocode} +% At this stage, either we have a control sequence or a simple character: +% split and handle. +% \begin{macrocode} +\cs_new:Npn \@@_expand_explicit:N #1 + { + \token_if_cs:NTF #1 + { \@@_expand_exclude:N #1 } + { + \@@_expand_store:n {#1} + \@@_expand_loop:w + } + } +% Next we exclude math commands: this is mainly as there \emph{might} be an +% \cs{ensuremath}. We also handle accents, which are basically the same issue +% but are kept separate for semantic reasons. +% \begin{macrocode} +\cs_new:Npn \@@_expand_exclude:N #1 + { +%<*initex> + \exp_after:wN \@@_expand_exclude:NN + \l_text_math_arg_tl + #1 + \q_recursion_tail \q_recursion_stop +%</initex> +%<*package> + \exp_args:Ne \@@_expand_exclude:nN + { + \exp_not:V \l_text_math_arg_tl + \exp_not:V \l_text_accents_tl + \exp_not:V \l_text_expand_exclude_tl + } + #1 +%</package> + } +%<*package> +\cs_new:Npn \@@_expand_exclude:nN #1#2 + { + \@@_expand_exclude:NN #2 #1 + \q_recursion_tail \q_recursion_stop + } +%</package> +\cs_new:Npn \@@_expand_exclude:NN #1#2 + { + \quark_if_recursion_tail_stop_do:Nn #2 +%<*initex> + { \@@_expand_cs:N #1 } +%</initex> +%<*package> + { \@@_expand_letterlike:N #1 } +%</package> + \cs_if_eq:NNTF #2 #1 + { + \use_i_delimit_by_q_recursion_stop:nw + { \@@_expand_exclude:Nn #1 } + } + { \@@_expand_exclude:NN #1 } + } +\cs_new:Npn \@@_expand_exclude:Nn #1#2 + { + \@@_expand_store:n { #1 {#2} } + \@@_expand_loop:w + } +% \end{macrocode} +% Another list of exceptions: these ones take no arguments so are +% easier to handle. +% \begin{macrocode} +%<*package> +\cs_new:Npn \@@_expand_letterlike:N #1 + { + \exp_after:wN \@@_expand_letterlike:NN \exp_after:wN + #1 \l_text_letterlike_tl + \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \@@_expand_letterlike:NN #1#2 + { + \quark_if_recursion_tail_stop_do:Nn #2 + { \@@_expand_cs:N #1 } + \cs_if_eq:NNTF #2 #1 + { + \use_i_delimit_by_q_recursion_stop:nw + { + \@@_expand_store:n {#1} + \@@_expand_loop:w + } + } + { \@@_expand_letterlike:NN #1 } + } +%</package> +% \end{macrocode} +% \LaTeXe{}'s \cs{protect} makes life interesting. Where possible, we +% simply remove it and replace with the \enquote{parent} command; of course, +% the \cs{protect} might be explicit, in which case we need to leave it alone +% if it's required. +% \begin{macrocode} +\cs_new:Npn \@@_expand_cs:N #1 + { + \str_if_eq:nnTF {#1} { \protect } + { \@@_expand_protect:N } + { \@@_expand_cs_expand:N #1 } + } +\cs_new:Npn \@@_expand_protect:N #1 + { + \exp_args:Ne \@@_expand_protect:nN + { \cs_to_str:N #1 } #1 + } +\cs_new:Npn \@@_expand_protect:nN #1#2 + { \@@_expand_protect:Nw #2 #1 \q_nil #1 ~ \q_nil \q_nil \q_stop } +\cs_new:Npn \@@_expand_protect:Nw #1 #2 ~ \q_nil #3 \q_nil #4 \q_stop + { + \quark_if_nil:nTF {#4} + { + \cs_if_exist:cTF {#2} + { \exp_args:Ne \@@_expand_store:n { \exp_not:c {#2} } } + { \@@_expand_store:n { \protect #1 } } + } + { \@@_expand_store:n { \protect #1 } } + \@@_expand_loop:w + } +% \end{macrocode} +% Finally, expand any macros which can be: this then loops back around to +% deal with what they produce. +% \begin{macrocode} +\cs_new:Npn \@@_expand_cs_expand:N #1 + { + \@@_if_expandable:NTF #1 + { \exp_after:wN \@@_expand_loop:w #1 } + { + \@@_expand_store:n {#1} + \@@_expand_loop:w + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \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{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx index e4e8b791e9b..e9f36e03b8f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx @@ -2,7 +2,7 @@ % %% File: l3tl-analysis.dtx % -% Copyright (C) 2011-2019 The LaTeX3 Project +% Copyright (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index a3c39d9df95..a564e6eca3e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx @@ -2,7 +2,7 @@ % %% File: l3tl.dtx % -% Copyright (C) 1990-2019 The LaTeX3 Project +% Copyright (C) 1990-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx index 36ca7200714..93b1e6ffc55 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx @@ -2,7 +2,7 @@ % %% File: l3token.dtx % -% Copyright (C) 2005-2019 The LaTeX3 Project +% Copyright (C) 2005-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -151,6 +151,26 @@ % \end{texnote} % \end{function} % +% \begin{function}[added = 2020-01-09, EXP] +% { +% \char_lowercase:N, \char_uppercase:N, +% \char_titlecase:N, \char_foldcase:N, +% \char_str_lowercase:N, \char_str_uppercase:N, +% \char_str_titlecase:N, \char_str_foldcase:N +% } +% \begin{syntax} +% \cs{char_lowercase:N} \meta{char} +% \end{syntax} +% Converts the \meta{char} to the equivalent case-changed character +% as detailed by the function name (see \cs{str_foldcase:n} +% and \cs{text_titlecase:n} for details of these terms). The case mapping +% is carried out with no context-dependence (\emph{cf.}~\cs{text_uppercase:n}, +% \emph{etc.}) The \texttt{str} versions always generate \enquote{other} +% (category code $12$) characters, whilst the standard versions generate +% characters with the category code of the \meta{char} (i.e.~only +% the character code changes). +% \end{function} +% % \begin{variable}[added = 2011-09-05]{\c_catcode_other_space_tl} % Token list containing one character with category code $12$, % (\enquote{other}), and character code $32$ (space). @@ -253,7 +273,7 @@ % \cs{char_set_lccode:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % Sets up the behaviour of the \meta{character} when -% found inside \cs{tl_lower_case:n}, such that \meta{character_1} +% found inside \cs{text_lowercase:n}, such that \meta{character_1} % will be converted into \meta{character_2}. The two \meta{characters} % may be specified using an \meta{integer expression} for the character code % concerned. This may include the \TeX{} |`|\meta{character} @@ -290,7 +310,7 @@ % \cs{char_set_uccode:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % Sets up the behaviour of the \meta{character} when -% found inside \cs{tl_upper_case:n}, such that \meta{character_1} +% found inside \cs{text_uppercase:n}, such that \meta{character_1} % will be converted into \meta{character_2}. The two \meta{characters} % may be specified using an \meta{integer expression} for the character code % concerned. This may include the \TeX{} |`|\meta{character} @@ -1462,9 +1482,7 @@ \tl_put_right:Nn \l_@@_tmp_tl { \or: } % \end{macrocode} % For making spaces, there needs to be an |o|-type expansion of a |\use:n| -% (or some other tokenization) to avoid dropping the space. We also -% set up active tokens although they are (currently) filtered out by the -% interface layer (\tn{Ucharcat} cannot make active tokens). +% (or some other tokenization) to avoid dropping the space. % \begin{macrocode} \char_set_catcode_space:n { 0 } \tl_put_right:No \l_@@_tmp_tl { \use:n { \or: } ^^@ } @@ -1532,6 +1550,306 @@ % \end{macro} % \end{macro} % +% \begin{macro}[EXP]{\char_to_utfviii_bytes:n} +% \begin{macro}[EXP]{\@@_to_utfviii_bytes_auxi:n} +% \begin{macro}[EXP]{\@@_to_utfviii_bytes_auxii:Nnn} +% \begin{macro}[EXP]{\@@_to_utfviii_bytes_auxiii:n} +% \begin{macro}[EXP] +% { +% \@@_to_utfviii_bytes_outputi:nw , +% \@@_to_utfviii_bytes_outputii:nw , +% \@@_to_utfviii_bytes_outputiii:nw , +% \@@_to_utfviii_bytes_outputiv:nw +% } +% \begin{macro}[EXP] +% {\@@_to_utfviii_bytes_output:nnn, \@@_to_utfviii_bytes_output:fnn} +% \begin{macro}[EXP]{\@@_to_utfviii_bytes_end:} +% This code converts a codepoint into the correct UTF-8 representation. +% In terms of the algorithm itself, see +% \url{https://en.wikipedia.org/wiki/UTF-8} for the octet pattern. +% \begin{macrocode} +\cs_new:Npn \char_to_utfviii_bytes:n #1 + { + \exp_args:Nf \@@_to_utfviii_bytes_auxi:n + { \int_eval:n {#1} } + } +\cs_new:Npn \@@_to_utfviii_bytes_auxi:n #1 + { + \if_int_compare:w #1 > "80 \exp_stop_f: + \if_int_compare:w #1 < "800 \exp_stop_f: + \@@_to_utfviii_bytes_outputi:nw + { \@@_to_utfviii_bytes_auxii:Nnn C {#1} { 64 } } + \@@_to_utfviii_bytes_outputii:nw + { \@@_to_utfviii_bytes_auxiii:n {#1} } + \else: + \if_int_compare:w #1 < "10000 \exp_stop_f: + \@@_to_utfviii_bytes_outputi:nw + { \@@_to_utfviii_bytes_auxii:Nnn E {#1} { 64 * 64 } } + \@@_to_utfviii_bytes_outputii:nw + { + \@@_to_utfviii_bytes_auxiii:n + { \int_div_truncate:nn {#1} { 64 } } + } + \@@_to_utfviii_bytes_outputiii:nw + { \@@_to_utfviii_bytes_auxiii:n {#1} } + \else: + \@@_to_utfviii_bytes_outputi:nw + { + \@@_to_utfviii_bytes_auxii:Nnn F + {#1} { 64 * 64 * 64 } + } + \@@_to_utfviii_bytes_outputii:nw + { + \@@_to_utfviii_bytes_auxiii:n + { \int_div_truncate:nn {#1} { 64 * 64 } } + } + \@@_to_utfviii_bytes_outputiii:nw + { + \@@_to_utfviii_bytes_auxiii:n + { \int_div_truncate:nn {#1} { 64 } } + } + \@@_to_utfviii_bytes_outputiv:nw + { \@@_to_utfviii_bytes_auxiii:n {#1} } + \fi: + \fi: + \else: + \@@_to_utfviii_bytes_outputi:nw {#1} + \fi: + \@@_to_utfviii_bytes_end: { } { } { } { } + } +\cs_new:Npn \@@_to_utfviii_bytes_auxii:Nnn #1#2#3 + { "#10 + \int_div_truncate:nn {#2} {#3} } +\cs_new:Npn \@@_to_utfviii_bytes_auxiii:n #1 + { \int_mod:nn {#1} { 64 } + 128 } +\cs_new:Npn \@@_to_utfviii_bytes_outputi:nw + #1 #2 \@@_to_utfviii_bytes_end: #3 + { \@@_to_utfviii_bytes_output:fnn { \int_eval:n {#1} } { } {#2} } +\cs_new:Npn \@@_to_utfviii_bytes_outputii:nw + #1 #2 \@@_to_utfviii_bytes_end: #3#4 + { \@@_to_utfviii_bytes_output:fnn { \int_eval:n {#1} } { {#3} } {#2} } +\cs_new:Npn \@@_to_utfviii_bytes_outputiii:nw + #1 #2 \@@_to_utfviii_bytes_end: #3#4#5 + { + \@@_to_utfviii_bytes_output:fnn + { \int_eval:n {#1} } { {#3} {#4} } {#2} + } +\cs_new:Npn \@@_to_utfviii_bytes_outputiv:nw + #1 #2 \@@_to_utfviii_bytes_end: #3#4#5#6 + { + \@@_to_utfviii_bytes_output:fnn + { \int_eval:n {#1} } { {#3} {#4} {#5} } {#2} + } +\cs_new:Npn \@@_to_utfviii_bytes_output:nnn #1#2#3 + { + #3 + \@@_to_utfviii_bytes_end: #2 {#1} + } +\cs_generate_variant:Nn \@@_to_utfviii_bytes_output:nnn { f } +\cs_new:Npn \@@_to_utfviii_bytes_end: { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[rEXP]{\char_to_nfd:N} +% \begin{macro}[rEXP]{\@@_to_nfd:n} +% \begin{macro}[rEXP]{\@@_to_nfd:Nw} +% Look up any \textsc{nfd} and recursively produce the result. +% \begin{macrocode} +\cs_new:Npn \char_to_nfd:N #1 + { + \cs_if_exist:cTF { c_@@_nfd_ \token_to_str:N #1 _ tl } + { + \exp_after:wN \exp_after:wN \exp_after:wN \@@_to_nfd:Nw + \exp_after:wN \exp_after:wN \exp_after:wN #1 + \cs:w c_@@_nfd_ \token_to_str:N #1 _ tl \cs_end: + \q_stop + } + { \exp_not:n {#1} } + } +\cs_set_eq:NN \@@_to_nfd:n \char_to_nfd:N +\cs_new:Npn \@@_to_nfd:Nw #1#2#3 \q_stop + { + \exp_args:Ne \@@_to_nfd:n + { \char_generate:nn { `#2 } { \@@_change_case_catcode:N #1 } } + \tl_if_blank:nF {#3} + { + \exp_args:Ne \@@_to_nfd:n + { \char_generate:nn { `#3 } { \char_value_catcode:n { `#3 } } } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP] +% { +% \char_lowercase:N, \char_uppercase:N, +% \char_titlecase:N, \char_foldcase:N +% } +% \begin{macro}[EXP]{\@@_change_case:nNN} +% \begin{macro}[EXP]{\@@_change_case:nN} +% \begin{macro}[EXP]{\@@_change_case_multi:nN, \@@_change_case_multi:vN} +% \begin{macro}[EXP]{\@@_change_case_multi:NNNNw} +% \begin{macro}[EXP]{\@@_change_case:NNN} +% \begin{macro}[EXP]{\@@_change_case:NNNN} +% \begin{macro}[EXP]{\@@_change_case:NN} +% \begin{macro}[EXP]{\@@_change_case_catcode:N} +% \begin{macro}[EXP] +% { +% \char_str_lowercase:N, \char_str_uppercase:N, +% \char_str_titlecase:N, \char_str_foldcase:N +% } +% \begin{macro}[EXP]{\@@_str_change_case:nNN} +% \begin{macro}[EXP]{\@@_str_change_case:nN} +% To ensure that the category codes produced are predictable, every character +% is re-generated even if it is otherwise unchanged. This makes life a little +% interesting when we might have multiple output characters: we have to +% grab each of them and case change them in reverse order to maintain +% \texttt{f}-type expandability. +% \begin{macrocode} +\cs_new:Npn \char_lowercase:N #1 + { \@@_change_case:nNN { lower } \char_value_lccode:n #1 } +\cs_new:Npn \char_uppercase:N #1 + { \@@_change_case:nNN { upper } \char_value_uccode:n #1 } +\cs_new:Npn \char_titlecase:N #1 + { + \tl_if_exist:cTF { c_@@_titlecase_ \token_to_str:N #1 _tl } + { + \@@_change_case_multi:vN + { c_@@_titlecase_ \token_to_str:N #1 _tl } #1 + } + { \char_uppercase:N #1 } + } +\cs_new:Npn \char_foldcase:N #1 + { \@@_change_case:nNN { fold } \char_value_lccode:n #1 } +\cs_new:Npn \@@_change_case:nNN #1#2#3 + { + \tl_if_exist:cTF { c_@@_ #1 case_ \token_to_str:N #3 _tl } + { + \@@_change_case_multi:vN + { c_@@_ #1 case_ \token_to_str:N #3 _tl } #3 + } + { \exp_args:Nf \@@_change_case:nN { #2 { `#3 } } #3 } + } +\cs_new:Npn \@@_change_case:nN #1#2 + { + \int_compare:nNnTF {#1} = 0 + { #2 } + { \char_generate:nn {#1} { \@@_change_case_catcode:N #2 } } + } +\cs_new:Npn \@@_change_case_multi:nN #1#2 + { \@@_change_case_multi:NNNNw #2 #1 \q_no_value \q_no_value \q_stop } +\cs_generate_variant:Nn \@@_change_case_multi:nN { v } +\cs_new:Npn \@@_change_case_multi:NNNNw #1#2#3#4#5 \q_stop + { + \quark_if_no_value:NTF #4 + { + \quark_if_no_value:NTF #3 + { \@@_change_case:NN #1 #2 } + { \@@_change_case:NNN #1 #2#3 } + } + { \@@_change_case:NNNN #1 #2#3#4 } + } +\cs_new:Npn \@@_change_case:NNN #1#2#3 + { + \exp_args:Nnf \use:nn + { \@@_change_case:NN #1 #2 } + { \@@_change_case:NN #1 #3 } + } +\cs_new:Npn \@@_change_case:NNNN #1#2#3#4 + { + \exp_args:Nnff \use:nnn + { \@@_change_case:NN #1 #2 } + { \@@_change_case:NN #1 #3 } + { \@@_change_case:NN #1 #4 } + } +\cs_new:Npn \@@_change_case:NN #1#2 + { \char_generate:nn { `#2 } { \@@_change_case_catcode:N #1 } } +\cs_new:Npn \@@_change_case_catcode:N #1 + { + \if_catcode:w \exp_not:N #1 \c_math_toggle_token + 3 + \else: + \if_catcode:w \exp_not:N #1 \c_alignment_token + 4 + \else: + \if_catcode:w \exp_not:N #1 \c_math_superscript_token + 7 + \else: + \if_catcode:w \exp_not:N #1 \c_math_subscript_token + 8 + \else: + \if_catcode:w \exp_not:N #1 \c_space_token + 10 + \else: + \if_catcode:w \exp_not:N #1 \c_catcode_letter_token + 11 + \else: + \if_catcode:w \exp_not:N #1 \c_catcode_other_token + 12 + \else: + 13 + \fi: + \fi: + \fi: + \fi: + \fi: + \fi: + \fi: + } +% \end{macrocode} +% Same story for the string version, except category code is easier +% to follow. This of course makes this version significantly faster. +% \begin{macrocode} +\cs_new:Npn \char_str_lowercase:N #1 + { \@@_str_change_case:nNN { lower } \char_value_lccode:n #1 } +\cs_new:Npn \char_str_uppercase:N #1 + { \@@_str_change_case:nNN { upper } \char_value_uccode:n #1 } +\cs_new:Npn \char_str_titlecase:N #1 + { + \tl_if_exist:cTF { c_@@_titlecase_ \token_to_str:N #1 _tl } + { \tl_to_str:c { c_@@_titlecase_ \token_to_str:N #1 _tl } } + { \char_str_uppercase:N #1 } + } +\cs_new:Npn \char_str_foldcase:N #1 + { \@@_str_change_case:nNN { fold } \char_value_lccode:n #1 } +\cs_new:Npn \@@_str_change_case:nNN #1#2#3 + { + \tl_if_exist:cTF { c_@@_ #1 case_ \token_to_str:N #3 _tl } + { \tl_to_str:c { c_@@_ #1 case_ \token_to_str:N #3 _tl } } + { \exp_args:Nf \@@_str_change_case:nN { #2 { `#3 } } #3 } + } +\cs_new:Npn \@@_str_change_case:nN #1#2 + { + \int_compare:nNnTF {#1} = 0 + { \tl_to_str:n {#2} } + { \char_generate:nn {#1} { 12 } } + } +\cs_if_exist:NF \tex_Uchar:D + { + \cs_set:Npn \@@_str_change_case:nN #1#2 + { \tl_to_str:n {#2} } + } +% \end{macrocode} +% \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}{\c_catcode_other_space_tl} % Create a space with category code $12$: an \enquote{other} space. % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx index 9eb3d9747a1..383826eaeb4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx @@ -2,7 +2,7 @@ % %% File: l3unicode.dtx % -% Copyright (C) 2018-2019 The LaTeX3 Project +% Copyright (C) 2018-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-11-07} +% \date{Released 2020-01-12} % % \maketitle % @@ -116,35 +116,56 @@ } } % \end{macrocode} -% Parse the main Unicode data file for title case exceptions (the one-to-one -% lower and upper case mappings it contains are all be covered by the \TeX{} -% data). There are no comments in the main data file so this can be done using -% a standard mapping and no checks. +% Parse the main Unicode data file for two things. First, we want the titlecase +% exceptions: the one-to-one lower- and uppercase mappings it contains are all +% be covered by the \TeX{} data. Second, we need normalization data: at present, +% just the canonical \textsc{nfd} mappings. Those all yield either one or two +% codepoints, so the split is relatively easy. % \begin{macrocode} \ior_open:Nn \g_@@_data_ior { UnicodeData.txt } \cs_set_protected:Npn \@@_data_auxi:w #1 ; #2 ; #3 ; #4 ; #5 ; #6 ; #7 ; #8 ; #9 ; - { \@@_data_auxii:w #1 ; } - \cs_set_protected:Npn \@@_data_auxii:w - #1 ; #2 ; #3 ; #4 ; #5 ; #6 ; #7 \q_stop + { + \tl_if_blank:nF {#6} + { + \tl_if_head_eq_charcode:nNF {#6} < % > + { \@@_data_auxii:w #1 ; #6 ~ \q_stop } + } + \@@_data_auxiii:w #1 ; + } + \cs_set_protected:Npn \@@_data_auxii:w #1 ; #2 ~ #3 \q_stop + { + \tl_const:cx + { c_@@_nfd_ \@@_generate_char:n {#1} _tl } + { + \@@_generate:n { "#2 } + \tl_if_blank:nF {#3} + { \@@_generate:n { "#3 } } + } + } + \cs_set_protected:Npn \@@_data_auxiii:w + #1 ; #2 ; #3 ; #4 ; #5 ; #6 ; #7 ~ \q_stop { \cs_set_nopar:Npn \l_@@_tmpa_tl {#7} \reverse_if:N \if_meaning:w \l_@@_tmpa_tl \c_empty_tl \cs_set_nopar:Npn \l_@@_tmpb_tl {#5} \reverse_if:N \if_meaning:w \l_@@_tmpa_tl \l_@@_tmpb_tl \tl_const:cx - { c_@@_mixed_case_ \@@_generate_char:n {#1} _tl } + { c_@@_titlecase_ \@@_generate_char:n {#1} _tl } { \@@_generate:n { "#7 } } \fi: \fi: } - \ior_map_variable:NNn \g_@@_data_ior \l_@@_tmpa_tl - { - \if_meaning:w \l_@@_tmpa_tl \c_space_tl - \exp_after:wN \ior_map_break: - \fi: - \exp_after:wN \@@_data_auxi:w \l_@@_tmpa_tl \q_stop - } + \group_begin: + \char_set_catcode_space:n { `\ }% + \ior_map_variable:NNn \g_@@_data_ior \l_@@_tmpa_tl + {% + \if_meaning:w \l_@@_tmpa_tl \c_space_tl + \exp_after:wN \ior_map_break: + \fi: + \exp_after:wN \@@_data_auxi:w \l_@@_tmpa_tl \q_stop + }% + \group_end: \ior_close:N \g_@@_data_ior % \end{macrocode} % The other data files all use C-style comments so we have to worry about @@ -161,7 +182,7 @@ \reverse_if:N \if_int_compare:w \char_value_lccode:n {"#1} = "#3 ~ \tl_const:cx - { c_@@_fold_case_ \@@_generate_char:n {#1} _tl } + { c_@@_foldcase_ \@@_generate_char:n {#1} _tl } { \@@_generate:n { "#3 } } \fi: \else: @@ -172,7 +193,7 @@ } \cs_set_protected:Npn \@@_data_auxii:w #1 ~ #2 ~ #3 ~ #4 \q_stop { - \tl_const:cx { c_@@_fold_case_ \@@_generate_char:n {#1} _tl } + \tl_const:cx { c_@@_foldcase_ \@@_generate_char:n {#1} _tl } { \@@_generate:n { "#2 } \@@_generate:n { "#3 } @@ -188,7 +209,7 @@ } \ior_close:N \g_@@_data_ior % \end{macrocode} -% For upper and lower casing special situations, there is a bit more to +% For upper- and lowercasing special situations, there is a bit more to % do as we also have title casing to consider, plus we need to stop part-way % through the file. % \begin{macrocode} @@ -199,14 +220,14 @@ \use:n { \@@_data_auxii:w #1 ~ lower ~ #2 ~ } ~ \q_stop \use:n { \@@_data_auxii:w #1 ~ upper ~ #4 ~ } ~ \q_stop \str_if_eq:nnF {#3} {#4} - { \use:n { \@@_data_auxii:w #1 ~ mixed ~ #3 ~ } ~ \q_stop } + { \use:n { \@@_data_auxii:w #1 ~ title ~ #3 ~ } ~ \q_stop } } \cs_set_protected:Npn \@@_data_auxii:w #1 ~ #2 ~ #3 ~ #4 ~ #5 \q_stop { \tl_if_empty:nF {#4} { - \tl_const:cx { c_@@_ #2 _case_ \@@_generate_char:n {#1} _tl } + \tl_const:cx { c_@@_ #2 case_ \@@_generate_char:n {#1} _tl } { \@@_generate:n { "#3 } \@@_generate:n { "#4 } @@ -244,9 +265,9 @@ \cs_set_protected:Npn \@@_tmp:NN #1#2 { \quark_if_recursion_tail_stop:N #2 - \tl_const:cn { c_@@_upper_case_ #2 _tl } {#1} - \tl_const:cn { c_@@_lower_case_ #1 _tl } {#2} - \tl_const:cn { c_@@_fold_case_ #1 _tl } {#2} + \tl_const:cn { c_@@_uppercase_ #2 _tl } {#1} + \tl_const:cn { c_@@_lowercase_ #1 _tl } {#2} + \tl_const:cn { c_@@_foldcase_ #1 _tl } {#2} \@@_tmp:NN } \@@_tmp:NN diff --git a/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx b/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx index 9a10f7ef791..a570701cf43 100644 --- a/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx +++ b/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx @@ -2,7 +2,7 @@ % %% File: l3keys2e.dtx % -% Copyright (C) 2009,2011-2019 The LaTeX3 Project +% Copyright (C) 2009,2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -62,7 +62,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -133,7 +133,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3keys2e}{2019-10-11}{} +\ProvidesExplPackage{l3keys2e}{2020-01-12}{} {LaTeX2e option processing using LaTeX3 keys} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.ins b/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.ins index df9e88b7e99..a5d2f4e3017 100644 --- a/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.ins +++ b/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.ins @@ -2,7 +2,7 @@ File: l3keys2e.ins -Copyright (C) 2009,2011,2012,2016,2017,2019 The LaTeX3 Project +Copyright (C) 2009,2011,2012,2016,2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -23,7 +23,7 @@ The released version of this bundle is available from CTAN. \preamble -Copyright (C) 2009-2019 The LaTeX3 Project +Copyright (C) 2009-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx b/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx index 33f66c6589d..5eeb3e2aefb 100644 --- a/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx +++ b/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx @@ -2,7 +2,7 @@ % %% File: xfp.dtx % -% Copyright (C) 2017-2019 The LaTeX3 Project +% Copyright (C) 2017-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -64,7 +64,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -167,7 +167,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xfp}{2019-10-11}{} +\ProvidesExplPackage{xfp}{2020-01-12}{} {L3 Floating point unit} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3packages/xfp/xfp.ins b/Master/texmf-dist/source/latex/l3packages/xfp/xfp.ins index 6a2a26d1257..2439b0aae10 100644 --- a/Master/texmf-dist/source/latex/l3packages/xfp/xfp.ins +++ b/Master/texmf-dist/source/latex/l3packages/xfp/xfp.ins @@ -2,7 +2,7 @@ File: xfp.ins -Copyright (C) 2017,2019 The LaTeX3 Project +Copyright (C) 2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -23,7 +23,7 @@ The released version of this bundle is available from CTAN. \preamble -Copyright (C) 2017-2019 The LaTeX3 Project +Copyright (C) 2017-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx b/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx index 62600c37be0..59262e81ad9 100644 --- a/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx +++ b/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx @@ -3,7 +3,7 @@ %% File: xfrac.dtx % % Copyright (C) 2004,2008-2010 Morten Hoegholm -% (C) 2011,2012,2014-2019 The LaTeX3 Project +% (C) 2011,2012,2014-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -65,7 +65,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -535,7 +535,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xfrac}{2019-10-11}{} +\ProvidesExplPackage{xfrac}{2020-01-12}{} {L3 Experimental split-level fractions} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.ins b/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.ins index 39ecdd34b37..1b02e49b54c 100644 --- a/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.ins +++ b/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.ins @@ -3,7 +3,7 @@ File: xfrac.ins Copyright (C) 2004,2008-2010 Morten Hoegholm - (C) 2011,2012,2016,2017,2019 The LaTeX3 Project + (C) 2011,2012,2016,2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -24,7 +24,7 @@ The released version of this bundle is available from CTAN. \preamble -Copyright (C) 2011-2019 The LaTeX3 Project +Copyright (C) 2011-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx index 2a0b842fbb9..8e088957188 100644 --- a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx +++ b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx @@ -4,7 +4,7 @@ % % Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle % (C) 2004-2008 Frank Mittelbach, The LaTeX3 Project -% (C) 2009-2019 The LaTeX3 Project +% (C) 2009-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -67,7 +67,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -916,7 +916,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xparse}{2019-10-11}{} +\ProvidesExplPackage{xparse}{2020-01-12}{} {L3 Experimental document command parser} % \end{macrocode} % @@ -4551,7 +4551,7 @@ LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed. } \__kernel_msg_new:nnnn { xparse } { non-xparse } - { \str_upper_case:n #1~not~defined~using~xparse. } + { \str_uppercase:n #1~not~defined~using~xparse. } { You~have~asked~for~the~argument~specification~for~the~#1,~ but~this~was~not~defined~using~xparse. diff --git a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins index 0fcc01351dd..e65d2547097 100644 --- a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins +++ b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins @@ -2,7 +2,7 @@ File: xparse.ins -Copyright (C) 2000-2012,2016,2017,2019 The LaTeX3 Project +Copyright (C) 2000-2012,2016,2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -23,7 +23,7 @@ The released version of this bundle is available from CTAN. \preamble -Copyright (C) 2009-2019 The LaTeX3 Project +Copyright (C) 2009-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of diff --git a/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx b/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx index c12297b4edd..211a461a61b 100644 --- a/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx +++ b/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx @@ -4,7 +4,7 @@ % % Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle % (C) 2004-2010 Frank Mittelbach, The LaTeX3 Project -% (C) 2011-2019 The LaTeX3 Project +% (C) 2011-2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -63,7 +63,7 @@ % }^^A % } % -% \date{Released 2019-10-11} +% \date{Released 2020-01-12} % % \maketitle % @@ -682,7 +682,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xtemplate}{2019-10-11}{} +\ProvidesExplPackage{xtemplate}{2020-01-12}{} {L3 Experimental prototype document functions} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.ins b/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.ins index dc7f7e5bea5..43dfb266206 100644 --- a/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.ins +++ b/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.ins @@ -2,7 +2,7 @@ File: xtemplate.ins -Copyright (C) 2000-2012,2016,2017,2019 The LaTeX3 Project +Copyright (C) 2000-2012,2016,2017,2019,2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -34,7 +34,7 @@ license information is placed in the derived files. \preamble -Copyright (C) 2011-2019 The LaTeX3 Project +Copyright (C) 2011-2020 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of |