summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex')
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3color/l3color.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx5
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx10
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3str/l3str.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/expl3.dtx136
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3.ins8
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3basics.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3box.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx1927
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3clist.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3debug.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx81
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3doc.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3expan.dtx8
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3file.dtx157
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3final.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3flag.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3format.ins9
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3int.dtx8
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx2
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3keys.dtx5
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx60
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3msg.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3names.dtx5
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3prg.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3prop.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3quark.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3regex.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3seq.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3skip.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3sort.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3str.dtx60
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3sys.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx1421
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3text.dtx903
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3tl.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3token.dtx332
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx71
-rw-r--r--Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xfp/xfp.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx8
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins4
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.ins4
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