texlive[63449] Master/texmf-dist: l3 (30may22)

commits+karl at tug.org commits+karl at tug.org
Mon May 30 22:10:02 CEST 2022


Revision: 63449
          http://tug.org/svn/texlive?view=revision&revision=63449
Author:   karl
Date:     2022-05-30 22:10:02 +0200 (Mon, 30 May 2022)
Log Message:
-----------
l3 (30may22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3kernel/README.md
    trunk/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3doc.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex
    trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3packages/README.md
    trunk/Master/texmf-dist/doc/latex/l3packages/l3keys2e/l3keys2e.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xfp/xfp.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xfrac/xfrac.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xparse/xparse.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xtemplate/xtemplate.pdf
    trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.lua
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md	2022-05-30 20:10:02 UTC (rev 63449)
@@ -7,10 +7,19 @@
 
 ## [Unreleased]
 
+## [2022-05-30]
+
+### Added
+- Add `\lua_load_module:n`
+
+### Fixed
+- Typo in implementation of titlecase `hy-x-yiwn`
+- Definition order issue with `\str_case:Nn(TF)`
+
 ## [2022-05-04]
 
 ### Added
-- Language settings `hy` and `hy-x-yiwn` for handling of ech-yiwm ligature
+- Language settings `hy` and `hy-x-yiwn` for handling of ech-yiwn ligature
   uppercasing
 
 ## Changed
@@ -1104,7 +1113,8 @@
 - Step functions have been added for dim variables,
   e.g. `\dim_step_inline:nnnn`
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2022-05-04...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2022-05-30...HEAD
+[2022-05-30]: https://github.com/latex3/latex3/compare/2022-05-04...2022-05-30
 [2022-05-04]: https://github.com/latex3/latex3/compare/2022-04-29...2022-05-04
 [2022-04-29]: https://github.com/latex3/latex3/compare/2022-04-20...2022-04-29
 [2022-04-20]: https://github.com/latex3/latex3/compare/2022-04-10...2022-04-20

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2022-05-30 20:10:02 UTC (rev 63449)
@@ -1,7 +1,7 @@
 LaTeX3 Programming Conventions
 ==============================
 
-Release 2022-05-04
+Release 2022-05-30
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex	2022-05-30 20:10:02 UTC (rev 63449)
@@ -54,7 +54,7 @@
          {latex-team at latex-project.org}%
    }%
 }
-\date{Released 2022-05-04}
+\date{Released 2022-05-30}
 
 \pagenumbering{roman}
 \maketitle

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv	2022-05-30 20:10:02 UTC (rev 63449)
@@ -47,6 +47,7 @@
 conteq,conteq,Joachim Breitner,https://github.com/nomeata/conteq,https://github.com/nomeata/conteq.git,https://github.com/nomeata/conteq/issues,2013-05-26,2013-05-27,
 cookingunits,cooking-units,Ben Vitecek,https://github.com/Vidabe/cooking-units,https://github.com/Vidabe/cooking-units.git,https://github.com/Vidabe/cooking-units/issues,2018-09-26,2018-09-26,
 cs,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+csl,citation-style-language,Zeping Lee,https://github.com/zepinglee/citeproc-lua,https://github.com/zepinglee/citeproc-lua.git,https://github.com/zepinglee/citeproc-lua/issues,2022-05-09,2022-05-09,
 csvsim,csvsimple,Thomas F. Sturm,https://github.com/T-F-S/csvsimple,https://github.com/T-F-S/csvsimple.git,https://github.com/T-F-S/csvsimple/issues,2020-02-19,2020-02-19,
 ctex,ctex,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2014-03-08,2014-03-08,
 ctuthesis,ctuthesis,Tom Hejda,https://github.com/tohecz/ctuthesis,https://github.com/tohecz/ctuthesis.git,https://github.com/tohecz/ctuthesis/issues,2015-07-26,2015-07-26,

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex	2022-05-30 20:10:02 UTC (rev 63449)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2022-05-04}
+\date{Released 2022-05-30}
 
 \begin{document}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex	2022-05-30 20:10:02 UTC (rev 63449)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2022-05-04}
+\date{Released 2022-05-30}
 
 \newcommand{\TF}{\textit{(TF)}}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex	2022-05-30 20:10:02 UTC (rev 63449)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2022-05-04}
+\date{Released 2022-05-30}
 
 \newcommand{\TF}{\textit{(TF)}}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex	2022-05-30 20:10:02 UTC (rev 63449)
@@ -53,7 +53,7 @@
          {latex-team at latex-project.org}%
    }%
 }
-\date{Released 2022-05-04}
+\date{Released 2022-05-30}
 
 \pagenumbering{roman}
 \maketitle

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md	2022-05-30 20:10:02 UTC (rev 63449)
@@ -7,6 +7,17 @@
 
 ## [Unreleased]
 
+## [2022-05-30]
+
+## Added
+- `\SetTemplateKeys` for _ad hoc_ adjustment of template values
+
+### Changed
+- Make `\AssignTemplateKeys` optional
+
+### Removed
+- `\EvaluateNow` command
+
 ## [2022-01-12]
 
 ### Changed
@@ -170,7 +181,8 @@
 - Switch to ISO date format
 - Improve cross-module use of internal functions
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2022-01-12...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2022-05-30...HEAD
+[2022-05-30]: https://github.com/latex3/latex3/compare/2022-01-12...2022-05-30
 [2022-01-12]: https://github.com/latex3/latex3/compare/2021-11-12...2022-01-12
 [2021-11-12]: https://github.com/latex3/latex3/compare/2021-08-27...2021-11-12
 [2021-08-27]: https://github.com/latex3/latex3/compare/2021-08-04...2021-08-27

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3packages/README.md	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/doc/latex/l3packages/README.md	2022-05-30 20:10:02 UTC (rev 63449)
@@ -1,7 +1,7 @@
 LaTeX3 High-Level Concepts
 ==========================
 
-Release 2022-01-12
+Release 2022-05-30
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/l3keys2e/l3keys2e.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xfp/xfp.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xfrac/xfrac.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xparse/xparse.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xtemplate/xtemplate.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -24,7 +24,7 @@
 %
 %<*driver|generic|package|2ekernel>
 %</driver|generic|package|2ekernel>
-\def\ExplFileDate{2022-05-04}%
+\def\ExplFileDate{2022-05-30}%
 %<*driver>
 \documentclass[full]{l3doc}
 \usepackage{graphicx}
@@ -51,7 +51,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -85,7 +85,7 @@
 %    require you to do updates, if the class changes.}}
 %
 % \author{\Team}
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 % \maketitle
 % \tableofcontents
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -63,7 +63,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 % \maketitle
 %
 % \begin{documentation}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 % \maketitle
 %
 % \begin{documentation}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -49,7 +49,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %
@@ -115,6 +115,24 @@
 %   \end{texnote}
 % \end{function}
 %
+% \begin{function}[added = 2022-05-14]{\lua_load_module:n}
+%   \begin{syntax}
+%     \cs{lua_load_module:n} \Arg{Lua module name}
+%   \end{syntax}
+%   Loads a Lua module into the Lua interpreter.
+%
+%   \cs{lua_now:n} passes its \Arg{token list} argument to the Lua interpreter
+%   as a single line, with characters interpreted under the current catcode
+%   regime. These two facts mean that \cs{lua_now:n} rarely behaves as expected
+%   for larger pieces of code. Therefore, package authors should \textbf{not}
+%   write significant amounts of Lua code in the arguments to \cs{lua_now:n}.
+%   Instead, it is strongly recommended that they write the majorty of their Lua
+%   code in a separate file, and then load it using \cs{lua_load_module:n}.
+%   \begin{texnote}
+%     This is a wrapper around the Lua call |require '|\meta{module}|'|.
+%   \end{texnote}
+% \end{function}
+%
 % \section{Lua interfaces}
 %
 % As well as interfaces for \TeX{}, there are a small number of Lua functions
@@ -208,9 +226,7 @@
 % \begin{macro}[EXP]{\lua_now:n, \lua_now:e}
 % \begin{macro}{\lua_shipout_e:n, \lua_shipout:n}
 % \begin{macro}[EXP]{\lua_escape:n, \lua_escape:e}
-%   Wrappers around the primitives. As with engines other than \LuaTeX{}
-%   these have to be macros, we give them the same status in all cases.
-%   When \LuaTeX{} is not in use, simply give an error message/
+%   Wrappers around the primitives.
 %    \begin{macrocode}
 \cs_new:Npn \lua_now:e #1 { \@@_now:n {#1} }
 \cs_new:Npn \lua_now:n #1 { \lua_now:e { \exp_not:n {#1} } }
@@ -219,6 +235,31 @@
   { \lua_shipout_e:n { \exp_not:n {#1} } }
 \cs_new:Npn \lua_escape:e #1 { \@@_escape:n {#1} }
 \cs_new:Npn \lua_escape:n #1 { \lua_escape:e { \exp_not:n {#1} } }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\lua_load_module:n}
+%   Wrapper around |require'|\meta{module}|'|.
+%    \begin{macrocode}
+\str_new:N \l_@@_err_msg_str
+\cs_generate_variant:Nn \msg_error:nnnn { nnnV }
+\cs_new_protected:Npn \lua_load_module:n #1
+  {
+    \bool_if:nF { \@@_load_module_p:n { #1 } }
+      {
+        \msg_error:nnnV
+          { luatex } { module-not-found } { #1 } { \l_@@_err_msg_str }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%   As with engines other than \LuaTeX{}
+%   these have to be macros, we give them the same status in all cases.
+%   When \LuaTeX{} is not in use, simply give an error message/
+%    \begin{macrocode}
 \sys_if_engine_luatex:F
   {
     \clist_map_inline:nn
@@ -234,7 +275,7 @@
           }
       }
     \clist_map_inline:nn
-      { \lua_shipout_e:n , \lua_shipout:n }
+      { \lua_shipout_e:n , \lua_shipout:n, \lua_load_module:n }
       {
         \cs_set_protected:Npn #1 ##1
           {
@@ -244,10 +285,6 @@
       }
   }
 %    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
 % \subsection{Messages}
 %
 %    \begin{macrocode}
@@ -257,6 +294,19 @@
     The~feature~you~are~using~is~only~available~
     with~the~LuaTeX~engine.~LaTeX3~ignored~'#1'.
   }
+
+\msg_new:nnnn { luatex } { module-not-found }
+  { Lua~module~`#1'~not~found. }
+  {
+    The~file~`#1.lua'~could~not~be~found.~Please~ensure~
+    that~the~file~was~properly~installed~and~that~the~
+    filename~database~is~current. \\ \\
+    The~Lua~loader~provided~this~additional~information: \\
+    #2
+  }
+
+\prop_gput:Nnn \g_msg_module_name_prop { luatex } { LaTeX3 }
+\prop_gput:Nnn \g_msg_module_type_prop { luatex } { }
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -311,6 +361,9 @@
 local write      = tex.write
 local write_nl   = texio.write_nl
 local utf8_char  = utf8.char
+local package_loaded    = package.loaded
+local package_searchers = package.searchers
+local table_concat      = table.concat
 
 local scan_int     = token.scan_int or token.scan_integer
 local scan_string  = token.scan_string
@@ -318,6 +371,7 @@
 local put_next     = token.put_next
 local token_create = token.create
 local token_new    = token.new
+local set_macro    = token.set_macro
 %    \end{macrocode}
 %
 %   Since token.create only returns useful values after the tokens
@@ -554,6 +608,57 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[int]{try_require}
+%   Loads a Lua module. This function loads the module similarly to the standard
+%   Lua global function |require|, with a few differences. On success,
+%   |try_require| returns |true, module|. If the module cannot be found, it
+%   returns |false, err_msg|. If the module is found, but something goes wrong
+%   when loading it, the function throws an error.
+%    \begin{macrocode}
+local function try_require(name)
+  if package_loaded[name] then
+    return true, package_loaded[name]
+  end
+
+  local failure_details = {}
+  for _, searcher in ipairs(package_searchers) do
+    local loader, data = searcher(name)
+    if type(loader) == 'function' then
+      package_loaded[name] = loader(name, data) or true
+      return true, package_loaded[name]
+    elseif type(loader) == 'string' then
+      failure_details[#failure_details + 1] = loader
+    end
+  end
+
+  return false, table_concat(failure_details, '\n')
+end
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_load_module_p:n}
+%   Check to see if we can load a module using |require|. If we
+%   can load the module, then we load it immediately. Otherwise, we save the
+%   error message in |\l_@@_err_msg_str|.
+%    \begin{macrocode}
+local char_given   = command_id'char_given'
+local c_true_bool  = token_create(1, char_given)
+local c_false_bool = token_create(0, char_given)
+local c_str_cctab  = token_create('c_str_cctab').mode
+
+luacmd('@@_load_module_p:n', function()
+  local success, result = try_require(scan_string())
+  if success then
+    set_macro(c_str_cctab, 'l_@@_err_msg_str', '')
+    put_next(c_true_bool)
+  else
+    set_macro(c_str_cctab, 'l_@@_err_msg_str', result)
+    put_next(c_false_bool)
+  end
+end)
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsection{Preserving iniTeX Lua data for runs}
 %
 %    \begin{macrocode}
@@ -595,7 +700,7 @@
     end
 %    \end{macrocode}
 % \end{macro}
-% 
+%
 % The actual work is done in \texttt{pre_dump}. The \texttt{luadata_order} is used
 % to ensure that the order is consistent over multiple runs.
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %
@@ -1234,12 +1234,12 @@
 \cs_new:Npn \@@_case:nnTF #1#2#3#4
   { \@@_case:nw {#1} #2 {#1} { } \s_@@_mark {#3} \s_@@_mark {#4} \s_@@_stop }
 \cs_generate_variant:Nn \str_case:nn   { V , o , nV , nv }
+\prg_generate_conditional_variant:Nnn \str_case:nn
+  { V , o , nV , nv } { T , F , TF }
 \cs_new_eq:NN \str_case:Nn   \str_case:Vn
 \cs_new_eq:NN \str_case:NnT  \str_case:VnT
 \cs_new_eq:NN \str_case:NnF  \str_case:VnF
 \cs_new_eq:NN \str_case:NnTF \str_case:VnTF
-\prg_generate_conditional_variant:Nnn \str_case:nn
-  { V , o , nV , nv } { T , F , TF }
 \cs_new:Npn \@@_case:nw #1#2#3
   {
     \str_if_eq:nnTF {#1} {#2}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %
@@ -1301,7 +1301,7 @@
     \cs_new:cpn { @@_change_case_upper_hy-x-yiwn:nnnN } #1#2#3#4
       { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 }
     \cs_new_eq:cc { @@_change_case_title_hy-x-yiwn:nnnN }
-      { @@_change_case_upper_hy-x-yiwm:nnnN }
+      { @@_change_case_upper_hy-x-yiwn:nnnN }
   }
 %    \end{macrocode}
 % \end{macro}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-05-04}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -62,7 +62,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-01-12}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %
@@ -139,7 +139,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3keys2e}{2022-01-12}{}
+\ProvidesExplPackage{l3keys2e}{2022-05-30}{}
   {LaTeX2e option processing using LaTeX3 keys}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -63,7 +63,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-01-12}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %
@@ -171,7 +171,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xfp}{2022-01-12}{}
+\ProvidesExplPackage{xfp}{2022-05-30}{}
   {L3 Floating point unit}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 %% File: xfrac.dtx
-% 
+%
 % Copyright (C) 2004,2008-2010 Morten Hoegholm
 %           (C) 2011,2012,2014-2022 The LaTeX Project
 %
@@ -65,7 +65,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-01-12}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %
@@ -535,7 +535,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xfrac}{2022-01-12}{}
+\ProvidesExplPackage{xfrac}{2022-05-30}{}
   {L3 Experimental split-level fractions}
 %    \end{macrocode}
 %
@@ -781,7 +781,6 @@
 % whether the surroundings are text or math(s), and react accordingly.
 %    \begin{macrocode}
   {
-    \AssignTemplateKeys
     \mode_if_math:TF
       {
         \cs_set_eq:NN \@@_text_or_math:n \text

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -67,7 +67,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-01-12}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %
@@ -1064,7 +1064,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xparse}{2022-01-12}{}
+\ProvidesExplPackage{xparse}{2022-05-30}{}
   {L3 Experimental document command parser}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -63,7 +63,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2022-01-12}
+% \date{Released 2022-05-30}
 %
 % \maketitle
 %
@@ -358,24 +358,14 @@
 %     \cs{AssignTemplateKeys}
 %   \end{syntax}
 %   In the final argument of \cs{DeclareTemplateCode} the assignment of
-%   keys defined by the template is carried out by using the function
-%   \cs{AssignTemplateKeys}. Thus no keys are assigned if this is missing
-%   from the \meta{code} used.
+%   keys defined by the template may be delayed by including the command
+%   \cs{AssignTemplateKeys}. If this is \emph{not} present, keys are assigned
+%   immediately before the template code. If \cs{AssignTemplateKeys} is
+%   present, assignment is delayed until this point. Note that the
+%   command must be \emph{directly} present in the code, not placed
+%   within a nested command/macro.
 % \end{function}
 %
-% \begin{function}{\EvaluateNow}
-%   \begin{syntax}
-%     \cs{EvaluateNow} \Arg{expression}
-%   \end{syntax}
-%   The standard method when creating an instance from a template is to
-%   evaluate the \meta{expression} when the instance is used. However, it may
-%   be desirable to calculate the value when declared, which can be
-%   forced using \cs{EvaluateNow}. Currently, this functionality is
-%   regarded as experimental: the team have not found an example where it
-%   is actually needed, and so it may be dropped \emph{if} no good
-%   examples are suggested!
-% \end{function}
-%
 % \section{Multiple choices}
 % \label{sec:choices-key}
 %
@@ -587,6 +577,40 @@
 %   be changed when creating an instance.
 % \end{function}
 %
+% \section{\emph{Ad hoc} adjustment of templates}
+%
+% \begin{function}{\SetTemplateKeys}
+%   \begin{syntax}
+%    \cs{SetTemplateKeys} \Arg{object type} \Arg{template} \Arg{keyvals}
+%   \end{syntax}
+%   At point of use it may be useful to apply changed to individual instances.
+%   This is supported as each template key is made available for adjustment
+%   using \cs{SetTemplateKeys}.
+% \end{function}
+%
+% For example, after
+% \begin{verbatim}
+%   \DeclareObjectType{MyObj}{0}
+%   \DeclareTemplateInterface{MyObj}{TemplateA}{0}
+%     {
+%       akey: tokenlist  ,
+%       bkey: function{2}
+%     }
+%   \DeclareTemplateCode{MyObj}{TemplateA}{0}
+%     {
+%       akey = SomeTokens ,
+%       bkey = \func:nn ,
+%     }
+% \end{verbatim}
+% the template keys could be adjusted in an \emph{ad hoc} fashion using
+% \begin{verbatim}
+%   \SetTemplateKeys{MyObj}{TemplateA}
+%     {
+%       akey = OtherTokens ,
+%       bkey = \AltFunc:nn
+%     }
+% \end{verbatim}
+%
 % \section{Getting information about templates and instances}
 %
 % \begin{function}{\ShowInstanceValues}
@@ -682,10 +706,15 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xtemplate}{2022-01-12}{}
+\ProvidesExplPackage{xtemplate}{2022-05-30}{}
   {L3 Experimental prototype document functions}
 %    \end{macrocode}
 %
+%    \begin{macrocode}
+\cs_generate_variant:Nn \keys_define:nn { nx }
+\cs_generate_variant:Nn \tl_trim_spaces:n { e }
+%    \end{macrocode}
+%
 % \subsection{Variables and constants}
 %
 % \begin{variable}{\c_@@_code_root_tl}
@@ -979,8 +1008,7 @@
 % \end{macro}
 %
 % \begin{macro}[TF]{\@@_if_key_value:n, \@@_if_key_value:o}
-%   Tests for the first token in a string being \cs{KeyValue}, where
-%   \cs{EvaluateNow} is not important.
+%   Tests for the first token in a string being \cs{KeyValue}.
 %    \begin{macrocode}
 \prg_new_conditional:Npnn \@@_if_key_value:n #1 { T , F , TF }
   {
@@ -994,18 +1022,6 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_if_eval_now:nTF}
-%   Tests for the first token in a string being \cs{EvaluateNow}.
-%    \begin{macrocode}
-\prg_new_conditional:Npnn \@@_if_eval_now:n #1 { TF }
-  {
-    \str_if_eq:noTF { \EvaluateNow } { \tl_head:w #1 \q_nil \q_stop }
-      { \prg_return_true: }
-      { \prg_return_false: }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}[TF]{\@@_if_instance_exist:nnn}
 %   Testing for an instance is collection dependent.
 %    \begin{macrocode}
@@ -1305,8 +1321,8 @@
 % \begin{macro}{\@@_split_keytype:n}
 % \begin{macro}{\@@_split_keytype_aux:w}
 %   The keytype and key name should be separated by |:|. As the
-%   definition might be given inside or outside of a code block, spaces
-%   are removed and the category code of colons is standardised. After
+%   definition might be given inside or outside of a code block,
+%   the category code of colons is standardised. After
 %   that, the standard delimited argument method is used to separate the
 %   two parts.
 %    \begin{macrocode}
@@ -1314,7 +1330,6 @@
   {
     \exp_not:N \bool_set_false:N \exp_not:N \l_@@_error_bool
     \tl_set:Nn \exp_not:N \l_@@_tmp_tl {#1}
-    \tl_remove_all:Nn \exp_not:N \l_@@_tmp_tl { ~ }
     \tl_replace_all:Nnn \exp_not:N \l_@@_tmp_tl { : } { \token_to_str:N : }
     \tl_if_in:onTF \exp_not:N \l_@@_tmp_tl { \token_to_str:N : }
       {
@@ -1336,7 +1351,10 @@
       ##1 \token_to_str:N : ##2 \s_@@_stop
       {
         \tl_put_right:Nx \exp_not:N \l_@@_key_name_tl
-          { \exp_not:N \tl_to_str:n {##1} }
+          {
+            \exp_not:N \tl_trim_spaces:e
+              { \exp_not:N \tl_to_str:n {##1} }
+          }
         \tl_if_in:nnTF {##2} { \token_to_str:N : }
           {
             \tl_put_right:Nn \exp_not:N \l_@@_key_name_tl
@@ -1419,30 +1437,9 @@
 % value to be processed and potentially stored.
 %
 % \begin{macro}{\@@_store_value_boolean:n}
-%   Storing Boolean values requires a test for delayed evaluation, but
-%   is different to the various numerical variable types as there are
-%   only two possible values to store. So the code here tests the default
-%   switch and then records the meaning (either \texttt{true} or
-%   \texttt{false}).
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_store_value_boolean:n #1
-  {
-    \@@_if_eval_now:nTF {#1}
-      {
-        \bool_if:cTF { c_ #1 _bool }
-          {
-            \prop_put:Non \l_@@_values_prop \l_@@_key_name_tl
-              { true }
-          }
-          {
-            \prop_put:Non \l_@@_values_prop \l_@@_key_name_tl
-              { false }
-          }
-      }
-      {
-        \prop_put:Non \l_@@_values_prop \l_@@_key_name_tl {#1}
-      }
-  }
+  { \prop_put:Non \l_@@_values_prop \l_@@_key_name_tl {#1} }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1464,17 +1461,9 @@
 %   \@@_store_value_real:n, \@@_store_value_skip:n,
 %   \@@_store_value_tokenlist:n, \@@_store_value_commalist:n}
 %   Storing values in \cs{l_@@_values_prop} is in most cases the same.
-%   If evaluation is taking place now, one \texttt{x}-expands an
-%   evaluation function and the result is then stored. On the other
-%   hand, if evaluation is delayed the current data is simply stored
-%   \enquote{as is}.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_store_value_aux:Nn #1#2
-  {
-    \@@_if_eval_now:nTF {#2}
-      { \prop_put:NVx \l_@@_values_prop \l_@@_key_name_tl { #1 {#2} } }
-      { \prop_put:Non \l_@@_values_prop \l_@@_key_name_tl {#2} }
-  }
+  { \prop_put:Non \l_@@_values_prop \l_@@_key_name_tl {#2} }
 \cs_new_protected:Npn \@@_store_value_integer:n
   { \@@_store_value_aux:Nn \int_eval:n }
 \cs_new_protected:Npn \@@_store_value_length:n
@@ -1494,6 +1483,7 @@
 % \subsection{Implementation part of template declaration}
 %
 % \begin{macro}{\@@_declare_template_code:nnnnn}
+% \begin{macro}{\@@_declare_template_code:nnn}
 %   The main function for implementing a template starts with a couple of
 %   simple checks to make sure that there are no obvious mistakes: the
 %   number of arguments must agree and the template keys must have been
@@ -1508,15 +1498,25 @@
           \@@_if_keys_exist:nnT {#1} {#2}
             {
               \@@_store_key_implementation:nnn {#1} {#2} {#4}
-              \cs_generate_from_arg_count:cNnn
-                { \c_@@_code_root_tl #1 / #2 }
-                \cs_gset_protected:Npn {#3} {#5}
+              \regex_match:nnTF { \c { AssignTemplateKeys } } {#5}
+                { \@@_declare_template_code:nnn { #1 / #2 } {#3} {#5} }
+                {
+                  \@@_declare_template_code:nnn
+                    { #1 / #2 } {#3} { \AssignTemplateKeys #5 }
+                }
             }
          }
       }
   }
+\cs_new_protected:Npn \@@_declare_template_code:nnn #1#2#3
+  {
+    \cs_generate_from_arg_count:cNnn
+      { \c_@@_code_root_tl #1 }
+      \cs_gset_protected:Npn {#2} {#3}
+  }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\@@_store_key_implementation:nnn}
 %   Actually storing the implementation part of a template is quite easy
@@ -1532,8 +1532,8 @@
     \@@_recover_restrictions:n { #1 / #2 }
     \@@_recover_keytypes:n { #1 / #2 }
     \prop_clear:N \l_@@_vars_prop
-    \keyval_parse:NNn
-      \@@_parse_vars_elt:n \@@_parse_vars_elt:nn {#3}
+    \keyval_parse:nnn
+      { \@@_parse_vars_elt:n } { \@@_parse_vars_elt:nnn { #1 / #2 } } {#3}
     \@@_store_vars:n { #1 / #2 }
     \@@_store_restrictions:n { #1 / #2 }
     \prop_map_inline:Nn \l_@@_keytypes_prop
@@ -1554,16 +1554,16 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_parse_vars_elt:nn}
+% \begin{macro}{\@@_parse_vars_elt:nnn}
 %   The actual storage part here is very simple: the storage bin name
 %   is placed into the property list. At the same time, a comparison is
 %   made with the keytypes defined earlier: if there is a mismatch then
 %   an error is raised.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_vars_elt:nn #1#2
+\cs_new_protected:Npn \@@_parse_vars_elt:nnn #1#2#3
  {
-    \tl_set:Nx \l_@@_key_name_tl { \tl_to_str:n {#1} }
-    \tl_remove_all:Nn \l_@@_key_name_tl { ~ }
+    \tl_set:Nx \l_@@_key_name_tl
+      { \tl_trim_spaces:e { \tl_to_str:n {#2} } }
     \prop_get:NoNTF
       \l_@@_keytypes_prop
       \l_@@_key_name_tl
@@ -1570,109 +1570,146 @@
       \l_@@_keytype_tl
       {
         \@@_split_keytype_arg:o \l_@@_keytype_tl
-        \@@_parse_vars_elt_aux:n {#2}
+        \@@_parse_vars_elt_aux:nn {#1} {#3}
         \prop_remove:NV \l_@@_keytypes_prop \l_@@_key_name_tl
       }
-      { \msg_error:nnx { xtemplate } { unknown-key } {#1} }
+      { \msg_error:nnx { xtemplate } { unknown-key } {#2} }
   }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\@@_parse_vars_elt_aux:n}
-% \begin{macro}{\@@_parse_vars_elt_aux:w}
-%   There now needs to be some sanity checking on the variable name
-%   given. This does not apply for \texttt{choice} or
-%   \texttt{code} \enquote{variables}, but in all other cases the variable
-%   needs to exist. Also, the only prefix acceptable is \texttt{global}. So
-%   there are a few related checks to make.
+% \begin{macro}{\@@_parse_vars_elt_aux:nn}
+% \begin{macro}{\@@_parse_vars_elt_aux:nw}
+% \begin{macro}{\@@_parse_vars_elt_aux:nnn}
+% \begin{macro}{\@@_parse_vars_elt_key:nn}
+%   Split off any leading \texttt{global} and they look for the way to
+%   implement.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_parse_vars_elt_aux:n #1
+\cs_new_protected:Npn \@@_parse_vars_elt_aux:nn #1#2
   {
-    \str_if_eq:onTF \l_@@_keytype_tl { choice }
-      { \@@_implement_choices:n {#1} }
+    \@@_parse_vars_elt_aux:nw {#1} #2 global global \s_@@_stop
+  }
+\cs_new_protected:Npn \@@_parse_vars_elt_aux:nw
+  #1#2 global #3 global #4 \s_@@_stop
+  {
+    \tl_if_blank:nTF {#4}
+      { \@@_parse_vars_elt_aux:nnn {#1} { } {#2} }
       {
-        \str_if_eq:onTF \l_@@_keytype_tl { code }
+        \tl_if_blank:nTF {#2}
           {
+            \exp_args:Nnnx \@@_parse_vars_elt_aux:nnn
+              {#1} { global } { \tl_trim_spaces:n {#3} }
+          }
+          { \msg_error:nnn { xtemplate } { bad-variable } { #2 global #3 } }
+      }
+  }
+\cs_new_protected:Npn \@@_parse_vars_elt_aux:nnn #1#2#3
+  {
+    \str_case:VnF \l_@@_keytype_tl
+      {
+        { choice } { \@@_implement_choices:nn {#1} {#3} }
+        { code }
+          {
+            \@@_parse_vars_elt_key:nn {#1}
+              {
+                .cs_ \str_if_eq:nnT {#1} { global } { g }
+                   set_protected:Np = \exp_not:N #3
+              }
             \prop_put:Non \l_@@_vars_prop
-              \l_@@_key_name_tl {#1}
+              \l_@@_key_name_tl {#2#3}
           }
+        { function }
           {
-            \tl_if_single:nTF {#1}
+            \cs_if_exist:NF #3
+              { \cs_new:Npn #3 { } }
+            \@@_parse_vars_elt_key:nn {#1}
               {
-                \cs_if_exist:NF #1
-                  { \@@_create_variable:N #1 }
-                \prop_put:Non \l_@@_vars_prop
-                  \l_@@_key_name_tl {#1}
+                .code:n =
+                  {
+                    \exp_not:c
+                      { cs_ \str_if_eq:nnT {#1} { global } { g } seq_eq:NN }
+                      \exp_not:N #3 ####1
+                  }
               }
+            \prop_put:Non \l_@@_vars_prop
+              \l_@@_key_name_tl {#2#3}
+          }
+        { instance }
+          {
+            \@@_parse_vars_elt_key:nn {#1}
               {
-                \tl_if_in:nnTF {#1} { global }
-                  { \@@_parse_vars_elt_aux:w #1 \s_@@_stop }
+                .code:n =
                   {
-                    \msg_error:nnx { xtemplate } { bad-variable }
-                      { \tl_to_str:n {#1} }
+                    \exp_not:c
+                      { cs_ \str_if_eq:nnT {#1} { global } { g } set:Npn }
+                      \exp_not:N #3 { \UseInstance {####1} }
                   }
               }
+            \prop_put:Non \l_@@_vars_prop
+              \l_@@_key_name_tl {#2#3}
           }
       }
-  }
-\cs_new_protected:Npn \@@_parse_vars_elt_aux:w #1 global #2 \s_@@_stop
-  {
-    \tl_if_empty:nTF {#1}
       {
-        \tl_if_single:nTF {#2}
+        \tl_if_single:nTF {#3}
           {
-            \cs_if_exist:NF #2
-              { \@@_create_variable:N #2 }
+            \cs_if_exist:NF #3
+              { \use:c { \@@_map_var_type: _new:N } #3 }
+            \@@_parse_vars_elt_key:nn {#1}
+              {
+                . \@@_map_var_type:
+                  _ \str_if_eq:nnT {#1} { global } { g } set:N
+                    = \exp_not:N #3
+              }
             \prop_put:Non \l_@@_vars_prop
-              \l_@@_key_name_tl { #1 global #2 }
+              \l_@@_key_name_tl {#2#3}
           }
-          {
-            \msg_error:nnx { xtemplate } { bad-variable }
-              { \tl_to_str:n { #1 global #2 } }
-          }
+          { \msg_error:nnx { xtemplate } { bad-variable } { #2#3 } }
       }
-      {
-          \msg_error:nnx { xtemplate } { bad-variable }
-            { \tl_to_str:n { #1 global #2 } }
-      }
   }
+\cs_new_protected:Npn \@@_parse_vars_elt_key:nn #1#2
+  {
+    \keys_define:nx { template / #1 }
+      { \l_@@_key_name_tl #2 }
+  }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
 %
-% \begin{macro}{\@@_create_variable:N}
-%   A shortcut to create non-declared variables. Some types need a name
-%   mapping, others can be used directly.
+% \begin{macro}[EXP]{\@@_map_var_type:}
+%   Turn a \enquote{friendly} variable type into an \texttt{expl3} one.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_create_variable:N #1
+\cs_new:Npn \@@_map_var_type:
   {
-    \str_case:onF \l_@@_keytype_tl
+    \str_case:on \l_@@_keytype_tl
       {
-        { boolean }   { \bool_new:N #1 }
-        { commalist } { \clist_new:N #1 }
-        { function }  { \cs_new:Npn #1 { } }
-        { instance }  { \cs_new_protected:Npn #1 { } }
-        { integer }   { \int_new:N #1 }
-        { length }    { \dim_new:N #1 }
-        { real }      { \fp_new:N #1 }
-        { tokenlist } { \tl_new:N #1 }
+        { boolean }   { bool }
+        { commalist } { clist }
+        { integer }   { int }
+        { length }    { dim }
+        { muskip }    { muskip }
+        { real }      { fp }
+        { skip }      { skip }
+        { tokenlist } { tl }
       }
-      { \use:c { \l_@@_keytype_tl _ new:N } #1 }
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_implement_choices:n}
+% \begin{macro}{\@@_implement_choices:nn}
 % \begin{macro}{\@@_implement_choices_default:}
 %   Implementing choices requires a second key--value loop. So after a
 %   little set-up, the standard parser is called.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_implement_choices:n #1
+\cs_new_protected:Npn \@@_implement_choices:nn #1#2
   {
     \clist_set:No \l_@@_tmp_clist { \l_@@_keytype_arg_tl }
     \prop_put:Non \l_@@_vars_prop \l_@@_key_name_tl { }
-    \keyval_parse:NNn
-      \@@_implement_choice_elt:n \@@_implement_choice_elt:nn
-      {#1}
+    \keys_define:nx { template / #1 } { \l_@@_key_name_tl .choice: }
+    \keyval_parse:nnn
+      { \@@_implement_choice_elt:n }
+      { \@@_implement_choice_elt:nnn {#1} }
+      {#2}
     \prop_get:NoNT \l_@@_values_prop \l_@@_key_name_tl
       \l_@@_tmp_tl
       { \@@_implement_choices_default: }
@@ -1714,8 +1751,8 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\@@_implement_choice_elt:nnn, \@@_implement_choice_elt_aux:nnn}
 % \begin{macro}{\@@_implement_choice_elt:n}
-% \begin{macro}{\@@_implement_choice_elt:nn}
 %   The actual storage of the implementation of a choice is mainly about
 %   error checking. The code here ensures that all choices have to have
 %   been declared, apart from the special \texttt{unknown} choice, which
@@ -1722,40 +1759,50 @@
 %   must come last. The code for each choice is stored along with the
 %   key name in the variables property list.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_implement_choice_elt:n #1
+\cs_new_protected:Npn \@@_implement_choice_elt:nnn #1#2#3
   {
     \clist_if_empty:NTF \l_@@_tmp_clist
       {
-        \str_if_eq:nnF {#1} { unknown }
+        \str_if_eq:nnTF {#2} { unknown }
+          { \@@_implement_choice_elt_aux:nnn {#1} {#2} {#3} }
           {
             \prop_get:NoN \l_@@_keytypes_prop \l_@@_key_name_tl
               \l_@@_tmp_tl
             \@@_split_keytype_arg:o \l_@@_tmp_tl
             \msg_error:nnxxx { xtemplate } { unknown-choice }
-              { \l_@@_key_name_tl } {#1}
+              { \l_@@_key_name_tl } {#2}
               { \l_@@_keytype_arg_tl }
           }
       }
       {
-        \clist_if_in:NnTF \l_@@_tmp_clist {#1}
-          { \clist_remove_all:Nn \l_@@_tmp_clist {#1} }
+        \clist_if_in:NnTF \l_@@_tmp_clist {#2}
           {
+            \clist_remove_all:Nn \l_@@_tmp_clist {#2}
+            \@@_implement_choice_elt_aux:nnn {#1} {#2} {#3}
+          }
+          {
             \prop_get:NoN \l_@@_keytypes_prop \l_@@_key_name_tl
               \l_@@_tmp_tl
             \@@_split_keytype_arg:o \l_@@_tmp_tl
             \msg_error:nnxxx { xtemplate } { unknown-choice }
-              { \l_@@_key_name_tl } {#1}
+              { \l_@@_key_name_tl } {#2}
               { \l_@@_keytype_arg_tl }
           }
       }
   }
-\cs_new_protected:Npn \@@_implement_choice_elt:nn #1#2
+\cs_new_protected:Npn \@@_implement_choice_elt_aux:nnn #1#2#3
   {
-    \@@_implement_choice_elt:n {#1}
+    \keys_define:nx { template / #1 }
+      { \l_@@_key_name_tl / #2 .code:n = { \exp_not:n {#3} } }
     \tl_set:Nx \l_@@_tmp_tl
-      { \l_@@_key_name_tl \c_space_tl #1 }
-    \prop_put:Non \l_@@_vars_prop \l_@@_tmp_tl {#2}
+      { \l_@@_key_name_tl \c_space_tl #2 }
+    \prop_put:Non \l_@@_vars_prop \l_@@_tmp_tl {#3}
   }
+\cs_new_protected:Npn \@@_implement_choice_elt:n #1
+  {
+    \msg_error:nnxxx { xtemplate } { choice-requires-code }
+      { \l_@@_key_name_tl } {#1}
+  }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -1849,8 +1896,8 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_parse_values_elt:nn #1#2
   {
-    \tl_set:Nx \l_@@_key_name_tl { \tl_to_str:n {#1} }
-    \tl_remove_all:Nn \l_@@_key_name_tl { ~ }
+    \tl_set:Nx \l_@@_key_name_tl
+      { \tl_trim_spaces:e { \tl_to_str:n {#1} } }
     \prop_get:NoNTF \l_@@_keytypes_prop \l_@@_key_name_tl
       \l_@@_tmp_tl
       {
@@ -2351,8 +2398,7 @@
   { \exp_after:wN \@@_key_to_value_auxi:w \l_@@_value_tl }
 \cs_new_protected:Npn \@@_key_to_value_auxi:w \KeyValue #1
   {
-    \tl_set:Nx \l_@@_tmp_tl { \tl_to_str:n {#1} }
-    \tl_remove_all:Nn \l_@@_key_name_tl { ~ }
+    \tl_set:Nx \l_@@_tmp_tl { \tl_trim_spaces:e { \tl_to_str:n {#1} } }
     \prop_get:NoNTF
       \l_@@_vars_prop
       \l_@@_tmp_tl
@@ -2591,6 +2637,13 @@
     each~choice~name~must~have~an~associated~implementation.\\
     This~should~be~given~after~a~'='~sign:~LaTeX~did~not~find~one.
   }
+\msg_new:nnnn { xtemplate } { choice-requires-code }
+  { The~choice~'#2'~for~key~'#1'~requires~an~implementation. }
+  {
+    You~should~have~put:\\
+    \ \ #1~:~choice~{~#2 = <code> ~} \\
+    but~LaTeX~did~not~find~any~<code>.
+  }
 \msg_new:nnnn { xtemplate } { duplicate-key-interface }
   { Key~'#1'~appears~twice~in~interface~definition~\msg_line_context:. }
   {
@@ -2842,16 +2895,12 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\EvaluateNow}
 % \begin{macro}{\KeyValue}
-%   These are both do nothing functions. Both simply dump their arguments
-%   when executed: this should not happen with \cs{KeyValue}.
+%   Simply dump the argument when executed: this should not happen.
 %    \begin{macrocode}
-\cs_new_protected:Npn \EvaluateNow #1 {#1}
 \cs_new_protected:Npn \KeyValue #1 {#1}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\AssignTemplateKeys}
 %   A short call to use a token register by proxy.
@@ -2861,7 +2910,15 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\SetTemplateKeys}
+%   A friendly wrapper
 %    \begin{macrocode}
+\cs_new_protected:Npn \SetTemplateKeys #1#2#3
+  { \keys_set:nn { template / #1 / #2 } {#3} }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
 \cs_new_eq:NN \ShowTemplateKeytypes \ShowTemplateInterface
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2022-05-30 20:10:02 UTC (rev 63449)
@@ -70,7 +70,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2022-05-04}%
+\def\ExplFileDate{2022-05-30}%
 \begingroup
   \def\next{\endgroup}%
   \expandafter\ifx\csname PackageError\endcsname\relax
@@ -5022,12 +5022,12 @@
 \cs_new:Npn \__str_case:nnTF #1#2#3#4
   { \__str_case:nw {#1} #2 {#1} { } \s__str_mark {#3} \s__str_mark {#4} \s__str_stop }
 \cs_generate_variant:Nn \str_case:nn   { V , o , nV , nv }
+\prg_generate_conditional_variant:Nnn \str_case:nn
+  { V , o , nV , nv } { T , F , TF }
 \cs_new_eq:NN \str_case:Nn   \str_case:Vn
 \cs_new_eq:NN \str_case:NnT  \str_case:VnT
 \cs_new_eq:NN \str_case:NnF  \str_case:VnF
 \cs_new_eq:NN \str_case:NnTF \str_case:VnTF
-\prg_generate_conditional_variant:Nnn \str_case:nn
-  { V , o , nV , nv } { T , F , TF }
 \cs_new:Npn \__str_case:nw #1#2#3
   {
     \str_if_eq:nnTF {#1} {#2}
@@ -31504,6 +31504,16 @@
   { \lua_shipout_e:n { \exp_not:n {#1} } }
 \cs_new:Npn \lua_escape:e #1 { \__lua_escape:n {#1} }
 \cs_new:Npn \lua_escape:n #1 { \lua_escape:e { \exp_not:n {#1} } }
+\str_new:N \l__lua_err_msg_str
+\cs_generate_variant:Nn \msg_error:nnnn { nnnV }
+\cs_new_protected:Npn \lua_load_module:n #1
+  {
+    \bool_if:nF { \__lua_load_module_p:n { #1 } }
+      {
+        \msg_error:nnnV
+          { luatex } { module-not-found } { #1 } { \l__lua_err_msg_str }
+      }
+  }
 \sys_if_engine_luatex:F
   {
     \clist_map_inline:nn
@@ -31519,7 +31529,7 @@
           }
       }
     \clist_map_inline:nn
-      { \lua_shipout_e:n , \lua_shipout:n }
+      { \lua_shipout_e:n , \lua_shipout:n, \lua_load_module:n }
       {
         \cs_set_protected:Npn #1 ##1
           {
@@ -31534,6 +31544,19 @@
     The~feature~you~are~using~is~only~available~
     with~the~LuaTeX~engine.~LaTeX3~ignored~'#1'.
   }
+
+\msg_new:nnnn { luatex } { module-not-found }
+  { Lua~module~`#1'~not~found. }
+  {
+    The~file~`#1.lua'~could~not~be~found.~Please~ensure~
+    that~the~file~was~properly~installed~and~that~the~
+    filename~database~is~current. \\ \\
+    The~Lua~loader~provided~this~additional~information: \\
+    #2
+  }
+
+\prop_gput:Nnn \g_msg_module_name_prop { luatex } { LaTeX3 }
+\prop_gput:Nnn \g_msg_module_type_prop { luatex } { }
 %% File: l3unicode.dtx
 \ior_new:N \g__char_data_ior
 \bool_lazy_or:nnTF { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: }
@@ -33117,7 +33140,7 @@
     \cs_new:cpn { __text_change_case_upper_hy-x-yiwn:nnnN } #1#2#3#4
       { \__text_change_case_char:nnnN {#1} {#2} {#3} #4 }
     \cs_new_eq:cc { __text_change_case_title_hy-x-yiwn:nnnN }
-      { __text_change_case_upper_hy-x-yiwm:nnnN }
+      { __text_change_case_upper_hy-x-yiwn:nnnN }
   }
 \bool_lazy_or:nnT
   { \sys_if_engine_luatex_p: }

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2022-05-30 20:10:02 UTC (rev 63449)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2022-05-04}%
+\def\ExplFileDate{2022-05-30}%
 \let\ExplLoaderFileDate\ExplFileDate
 \begingroup
   \catcode`\_=11

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx	2022-05-30 20:10:02 UTC (rev 63449)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2022-05-04}%
+\def\ExplFileDate{2022-05-30}%
 \let\ExplLoaderFileDate\ExplFileDate
 \begingroup
   \catcode`\_=11

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.lua
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.lua	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.lua	2022-05-30 20:10:02 UTC (rev 63449)
@@ -50,6 +50,9 @@
 local write      = tex.write
 local write_nl   = texio.write_nl
 local utf8_char  = utf8.char
+local package_loaded    = package.loaded
+local package_searchers = package.searchers
+local table_concat      = table.concat
 
 local scan_int     = token.scan_int or token.scan_integer
 local scan_string  = token.scan_string
@@ -57,6 +60,7 @@
 local put_next     = token.put_next
 local token_create = token.create
 local token_new    = token.new
+local set_macro    = token.set_macro
 local token_create_safe
 do
   local is_defined = token.is_defined
@@ -217,6 +221,39 @@
     end
   end
 end
+local function try_require(name)
+  if package_loaded[name] then
+    return true, package_loaded[name]
+  end
+
+  local failure_details = {}
+  for _, searcher in ipairs(package_searchers) do
+    local loader, data = searcher(name)
+    if type(loader) == 'function' then
+      package_loaded[name] = loader(name, data) or true
+      return true, package_loaded[name]
+    elseif type(loader) == 'string' then
+      failure_details[#failure_details + 1] = loader
+    end
+  end
+
+  return false, table_concat(failure_details, '\n')
+end
+local char_given   = command_id'char_given'
+local c_true_bool  = token_create(1, char_given)
+local c_false_bool = token_create(0, char_given)
+local c_str_cctab  = token_create('c_str_cctab').mode
+
+luacmd('__lua_load_module_p:n', function()
+  local success, result = try_require(scan_string())
+  if success then
+    set_macro(c_str_cctab, 'l__lua_err_msg_str', '')
+    put_next(c_true_bool)
+  else
+    set_macro(c_str_cctab, 'l__lua_err_msg_str', result)
+    put_next(c_false_bool)
+  end
+end)
 local register_luadata, get_luadata
 
 if luatexbase then

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2022-05-30 20:10:02 UTC (rev 63449)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2022-05-04}%
+\def\ExplFileDate{2022-05-30}%
 \let\ExplLoaderFileDate\ExplFileDate
 \ProvidesPackage{expl3}
   [%

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty	2022-05-30 20:10:02 UTC (rev 63449)
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{l3keys2e}{2022-01-12}{}
+\ProvidesExplPackage{l3keys2e}{2022-05-30}{}
   {LaTeX2e option processing using LaTeX3 keys}
 \cs_if_exist:NT \ProcessKeysOptions
   { \file_input_stop: }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty	2022-05-30 20:10:02 UTC (rev 63449)
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{xfp}{2022-01-12}{}
+\ProvidesExplPackage{xfp}{2022-05-30}{}
   {L3 Floating point unit}
 \ProvideExpandableDocumentCommand \fpeval { m } { \fp_eval:n {#1} }
 \ProvideExpandableDocumentCommand \inteval { m } { \int_eval:n {#1} }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty	2022-05-30 20:10:02 UTC (rev 63449)
@@ -34,7 +34,7 @@
     \endinput
   }
 \RequirePackage{amstext,graphicx,l3keys2e,textcomp,xparse,xtemplate}
-\ProvidesExplPackage{xfrac}{2022-01-12}{}
+\ProvidesExplPackage{xfrac}{2022-05-30}{}
   {L3 Experimental split-level fractions}
 \keys_define:nn { xfrac }
   {
@@ -156,7 +156,6 @@
     v-scale             = \l__xfrac_vscale_fp
   }
   {
-    \AssignTemplateKeys
     \mode_if_math:TF
       {
         \cs_set_eq:NN \__xfrac_text_or_math:n \text

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty	2022-05-30 20:10:02 UTC (rev 63449)
@@ -60,7 +60,7 @@
       }
   }
 \ExplSyntaxOff
-\ProvidesExplPackage{xparse}{2022-01-12}{}
+\ProvidesExplPackage{xparse}{2022-05-30}{}
   {L3 Experimental document command parser}
 \clist_new:N \l__cmd_options_clist
 \DeclareOption* { \clist_put_right:NV \l__cmd_options_clist \CurrentOption }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty	2022-05-30 20:07:45 UTC (rev 63448)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty	2022-05-30 20:10:02 UTC (rev 63449)
@@ -32,8 +32,10 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{xtemplate}{2022-01-12}{}
+\ProvidesExplPackage{xtemplate}{2022-05-30}{}
   {L3 Experimental prototype document functions}
+\cs_generate_variant:Nn \keys_define:nn { nx }
+\cs_generate_variant:Nn \tl_trim_spaces:n { e }
 \tl_const:Nn \c__xtemplate_code_root_tl      { template~code~>~ }
 \tl_const:Nn \c__xtemplate_defaults_root_tl  { template~defaults~>~ }
 \tl_const:Nn \c__xtemplate_instances_root_tl { template~instance~>~  }
@@ -125,12 +127,6 @@
 \cs_generate_variant:Nn \__xtemplate_if_key_value:nT  { o }
 \cs_generate_variant:Nn \__xtemplate_if_key_value:nF  { o }
 \cs_generate_variant:Nn \__xtemplate_if_key_value:nTF { o }
-\prg_new_conditional:Npnn \__xtemplate_if_eval_now:n #1 { TF }
-  {
-    \str_if_eq:noTF { \EvaluateNow } { \tl_head:w #1 \q_nil \q_stop }
-      { \prg_return_true: }
-      { \prg_return_false: }
-  }
 \prg_new_conditional:Npnn \__xtemplate_if_instance_exist:nnn #1#2#3
   { T, F, TF }
   {
@@ -326,7 +322,6 @@
   {
     \exp_not:N \bool_set_false:N \exp_not:N \l__xtemplate_error_bool
     \tl_set:Nn \exp_not:N \l__xtemplate_tmp_tl {#1}
-    \tl_remove_all:Nn \exp_not:N \l__xtemplate_tmp_tl { ~ }
     \tl_replace_all:Nnn \exp_not:N \l__xtemplate_tmp_tl { : } { \token_to_str:N : }
     \tl_if_in:onTF \exp_not:N \l__xtemplate_tmp_tl { \token_to_str:N : }
       {
@@ -348,7 +343,10 @@
       ##1 \token_to_str:N : ##2 \s__xtemplate_stop
       {
         \tl_put_right:Nx \exp_not:N \l__xtemplate_key_name_tl
-          { \exp_not:N \tl_to_str:n {##1} }
+          {
+            \exp_not:N \tl_trim_spaces:e
+              { \exp_not:N \tl_to_str:n {##1} }
+          }
         \tl_if_in:nnTF {##2} { \token_to_str:N : }
           {
             \tl_put_right:Nn \exp_not:N \l__xtemplate_key_name_tl
@@ -393,23 +391,7 @@
 \cs_new:Npn \__xtemplate_split_keytype_arg_aux:n #1 { }
 \cs_new:Npn \__xtemplate_split_keytype_arg_aux:w #1 \s__xtemplate_stop { }
 \cs_new_protected:Npn \__xtemplate_store_value_boolean:n #1
-  {
-    \__xtemplate_if_eval_now:nTF {#1}
-      {
-        \bool_if:cTF { c_ #1 _bool }
-          {
-            \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl
-              { true }
-          }
-          {
-            \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl
-              { false }
-          }
-      }
-      {
-        \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#1}
-      }
-  }
+  { \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#1} }
 \cs_new_protected:Npn \__xtemplate_store_value_code:n #1
   { \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#1} }
 \cs_new_eq:NN \__xtemplate_store_value_choice:n    \__xtemplate_store_value_code:n
@@ -416,11 +398,7 @@
 \cs_new_eq:NN \__xtemplate_store_value_function:n  \__xtemplate_store_value_code:n
 \cs_new_eq:NN \__xtemplate_store_value_instance:n  \__xtemplate_store_value_code:n
 \cs_new_protected:Npn \__xtemplate_store_value_aux:Nn #1#2
-  {
-    \__xtemplate_if_eval_now:nTF {#2}
-      { \prop_put:NVx \l__xtemplate_values_prop \l__xtemplate_key_name_tl { #1 {#2} } }
-      { \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#2} }
-  }
+  { \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#2} }
 \cs_new_protected:Npn \__xtemplate_store_value_integer:n
   { \__xtemplate_store_value_aux:Nn \int_eval:n }
 \cs_new_protected:Npn \__xtemplate_store_value_length:n
@@ -443,13 +421,22 @@
           \__xtemplate_if_keys_exist:nnT {#1} {#2}
             {
               \__xtemplate_store_key_implementation:nnn {#1} {#2} {#4}
-              \cs_generate_from_arg_count:cNnn
-                { \c__xtemplate_code_root_tl #1 / #2 }
-                \cs_gset_protected:Npn {#3} {#5}
+              \regex_match:nnTF { \c { AssignTemplateKeys } } {#5}
+                { \__xtemplate_declare_template_code:nnn { #1 / #2 } {#3} {#5} }
+                {
+                  \__xtemplate_declare_template_code:nnn
+                    { #1 / #2 } {#3} { \AssignTemplateKeys #5 }
+                }
             }
          }
       }
   }
+\cs_new_protected:Npn \__xtemplate_declare_template_code:nnn #1#2#3
+  {
+    \cs_generate_from_arg_count:cNnn
+      { \c__xtemplate_code_root_tl #1 }
+      \cs_gset_protected:Npn {#2} {#3}
+  }
 \cs_new_protected:Npn \__xtemplate_store_key_implementation:nnn #1#2#3
   {
     \__xtemplate_recover_defaults:n { #1 / #2 }
@@ -456,8 +443,8 @@
     \__xtemplate_recover_restrictions:n { #1 / #2 }
     \__xtemplate_recover_keytypes:n { #1 / #2 }
     \prop_clear:N \l__xtemplate_vars_prop
-    \keyval_parse:NNn
-      \__xtemplate_parse_vars_elt:n \__xtemplate_parse_vars_elt:nn {#3}
+    \keyval_parse:nnn
+      { \__xtemplate_parse_vars_elt:n } { \__xtemplate_parse_vars_elt:nnn { #1 / #2 } } {#3}
     \__xtemplate_store_vars:n { #1 / #2 }
     \__xtemplate_store_restrictions:n { #1 / #2 }
     \prop_map_inline:Nn \l__xtemplate_keytypes_prop
@@ -468,10 +455,10 @@
   }
 \cs_new_protected:Npn \__xtemplate_parse_vars_elt:n #1
   { \msg_error:nnx { xtemplate } { key-no-variable } {#1} }
-\cs_new_protected:Npn \__xtemplate_parse_vars_elt:nn #1#2
+\cs_new_protected:Npn \__xtemplate_parse_vars_elt:nnn #1#2#3
  {
-    \tl_set:Nx \l__xtemplate_key_name_tl { \tl_to_str:n {#1} }
-    \tl_remove_all:Nn \l__xtemplate_key_name_tl { ~ }
+    \tl_set:Nx \l__xtemplate_key_name_tl
+      { \tl_trim_spaces:e { \tl_to_str:n {#2} } }
     \prop_get:NoNTF
       \l__xtemplate_keytypes_prop
       \l__xtemplate_key_name_tl
@@ -478,83 +465,120 @@
       \l__xtemplate_keytype_tl
       {
         \__xtemplate_split_keytype_arg:o \l__xtemplate_keytype_tl
-        \__xtemplate_parse_vars_elt_aux:n {#2}
+        \__xtemplate_parse_vars_elt_aux:nn {#1} {#3}
         \prop_remove:NV \l__xtemplate_keytypes_prop \l__xtemplate_key_name_tl
       }
-      { \msg_error:nnx { xtemplate } { unknown-key } {#1} }
+      { \msg_error:nnx { xtemplate } { unknown-key } {#2} }
   }
-\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:n #1
+\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:nn #1#2
   {
-    \str_if_eq:onTF \l__xtemplate_keytype_tl { choice }
-      { \__xtemplate_implement_choices:n {#1} }
+    \__xtemplate_parse_vars_elt_aux:nw {#1} #2 global global \s__xtemplate_stop
+  }
+\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:nw
+  #1#2 global #3 global #4 \s__xtemplate_stop
+  {
+    \tl_if_blank:nTF {#4}
+      { \__xtemplate_parse_vars_elt_aux:nnn {#1} { } {#2} }
       {
-        \str_if_eq:onTF \l__xtemplate_keytype_tl { code }
+        \tl_if_blank:nTF {#2}
           {
+            \exp_args:Nnnx \__xtemplate_parse_vars_elt_aux:nnn
+              {#1} { global } { \tl_trim_spaces:n {#3} }
+          }
+          { \msg_error:nnn { xtemplate } { bad-variable } { #2 global #3 } }
+      }
+  }
+\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:nnn #1#2#3
+  {
+    \str_case:VnF \l__xtemplate_keytype_tl
+      {
+        { choice } { \__xtemplate_implement_choices:nn {#1} {#3} }
+        { code }
+          {
+            \__xtemplate_parse_vars_elt_key:nn {#1}
+              {
+                .cs_ \str_if_eq:nnT {#1} { global } { g }
+                   set_protected:Np = \exp_not:N #3
+              }
             \prop_put:Non \l__xtemplate_vars_prop
-              \l__xtemplate_key_name_tl {#1}
+              \l__xtemplate_key_name_tl {#2#3}
           }
+        { function }
           {
-            \tl_if_single:nTF {#1}
+            \cs_if_exist:NF #3
+              { \cs_new:Npn #3 { } }
+            \__xtemplate_parse_vars_elt_key:nn {#1}
               {
-                \cs_if_exist:NF #1
-                  { \__xtemplate_create_variable:N #1 }
-                \prop_put:Non \l__xtemplate_vars_prop
-                  \l__xtemplate_key_name_tl {#1}
+                .code:n =
+                  {
+                    \exp_not:c
+                      { cs_ \str_if_eq:nnT {#1} { global } { g } seq_eq:NN }
+                      \exp_not:N #3 ####1
+                  }
               }
+            \prop_put:Non \l__xtemplate_vars_prop
+              \l__xtemplate_key_name_tl {#2#3}
+          }
+        { instance }
+          {
+            \__xtemplate_parse_vars_elt_key:nn {#1}
               {
-                \tl_if_in:nnTF {#1} { global }
-                  { \__xtemplate_parse_vars_elt_aux:w #1 \s__xtemplate_stop }
+                .code:n =
                   {
-                    \msg_error:nnx { xtemplate } { bad-variable }
-                      { \tl_to_str:n {#1} }
+                    \exp_not:c
+                      { cs_ \str_if_eq:nnT {#1} { global } { g } set:Npn }
+                      \exp_not:N #3 { \UseInstance {####1} }
                   }
               }
+            \prop_put:Non \l__xtemplate_vars_prop
+              \l__xtemplate_key_name_tl {#2#3}
           }
       }
-  }
-\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:w #1 global #2 \s__xtemplate_stop
-  {
-    \tl_if_empty:nTF {#1}
       {
-        \tl_if_single:nTF {#2}
+        \tl_if_single:nTF {#3}
           {
-            \cs_if_exist:NF #2
-              { \__xtemplate_create_variable:N #2 }
+            \cs_if_exist:NF #3
+              { \use:c { \__xtemplate_map_var_type: _new:N } #3 }
+            \__xtemplate_parse_vars_elt_key:nn {#1}
+              {
+                . \__xtemplate_map_var_type:
+                  _ \str_if_eq:nnT {#1} { global } { g } set:N
+                    = \exp_not:N #3
+              }
             \prop_put:Non \l__xtemplate_vars_prop
-              \l__xtemplate_key_name_tl { #1 global #2 }
+              \l__xtemplate_key_name_tl {#2#3}
           }
-          {
-            \msg_error:nnx { xtemplate } { bad-variable }
-              { \tl_to_str:n { #1 global #2 } }
-          }
+          { \msg_error:nnx { xtemplate } { bad-variable } { #2#3 } }
       }
-      {
-          \msg_error:nnx { xtemplate } { bad-variable }
-            { \tl_to_str:n { #1 global #2 } }
-      }
   }
-\cs_new_protected:Npn \__xtemplate_create_variable:N #1
+\cs_new_protected:Npn \__xtemplate_parse_vars_elt_key:nn #1#2
   {
-    \str_case:onF \l__xtemplate_keytype_tl
+    \keys_define:nx { template / #1 }
+      { \l__xtemplate_key_name_tl #2 }
+  }
+\cs_new:Npn \__xtemplate_map_var_type:
+  {
+    \str_case:on \l__xtemplate_keytype_tl
       {
-        { boolean }   { \bool_new:N #1 }
-        { commalist } { \clist_new:N #1 }
-        { function }  { \cs_new:Npn #1 { } }
-        { instance }  { \cs_new_protected:Npn #1 { } }
-        { integer }   { \int_new:N #1 }
-        { length }    { \dim_new:N #1 }
-        { real }      { \fp_new:N #1 }
-        { tokenlist } { \tl_new:N #1 }
+        { boolean }   { bool }
+        { commalist } { clist }
+        { integer }   { int }
+        { length }    { dim }
+        { muskip }    { muskip }
+        { real }      { fp }
+        { skip }      { skip }
+        { tokenlist } { tl }
       }
-      { \use:c { \l__xtemplate_keytype_tl _ new:N } #1 }
   }
-\cs_new_protected:Npn \__xtemplate_implement_choices:n #1
+\cs_new_protected:Npn \__xtemplate_implement_choices:nn #1#2
   {
     \clist_set:No \l__xtemplate_tmp_clist { \l__xtemplate_keytype_arg_tl }
     \prop_put:Non \l__xtemplate_vars_prop \l__xtemplate_key_name_tl { }
-    \keyval_parse:NNn
-      \__xtemplate_implement_choice_elt:n \__xtemplate_implement_choice_elt:nn
-      {#1}
+    \keys_define:nx { template / #1 } { \l__xtemplate_key_name_tl .choice: }
+    \keyval_parse:nnn
+      { \__xtemplate_implement_choice_elt:n }
+      { \__xtemplate_implement_choice_elt:nnn {#1} }
+      {#2}
     \prop_get:NoNT \l__xtemplate_values_prop \l__xtemplate_key_name_tl
       \l__xtemplate_tmp_tl
       { \__xtemplate_implement_choices_default: }
@@ -588,40 +612,50 @@
           }
       }
   }
-\cs_new_protected:Npn \__xtemplate_implement_choice_elt:n #1
+\cs_new_protected:Npn \__xtemplate_implement_choice_elt:nnn #1#2#3
   {
     \clist_if_empty:NTF \l__xtemplate_tmp_clist
       {
-        \str_if_eq:nnF {#1} { unknown }
+        \str_if_eq:nnTF {#2} { unknown }
+          { \__xtemplate_implement_choice_elt_aux:nnn {#1} {#2} {#3} }
           {
             \prop_get:NoN \l__xtemplate_keytypes_prop \l__xtemplate_key_name_tl
               \l__xtemplate_tmp_tl
             \__xtemplate_split_keytype_arg:o \l__xtemplate_tmp_tl
             \msg_error:nnxxx { xtemplate } { unknown-choice }
-              { \l__xtemplate_key_name_tl } {#1}
+              { \l__xtemplate_key_name_tl } {#2}
               { \l__xtemplate_keytype_arg_tl }
           }
       }
       {
-        \clist_if_in:NnTF \l__xtemplate_tmp_clist {#1}
-          { \clist_remove_all:Nn \l__xtemplate_tmp_clist {#1} }
+        \clist_if_in:NnTF \l__xtemplate_tmp_clist {#2}
           {
+            \clist_remove_all:Nn \l__xtemplate_tmp_clist {#2}
+            \__xtemplate_implement_choice_elt_aux:nnn {#1} {#2} {#3}
+          }
+          {
             \prop_get:NoN \l__xtemplate_keytypes_prop \l__xtemplate_key_name_tl
               \l__xtemplate_tmp_tl
             \__xtemplate_split_keytype_arg:o \l__xtemplate_tmp_tl
             \msg_error:nnxxx { xtemplate } { unknown-choice }
-              { \l__xtemplate_key_name_tl } {#1}
+              { \l__xtemplate_key_name_tl } {#2}
               { \l__xtemplate_keytype_arg_tl }
           }
       }
   }
-\cs_new_protected:Npn \__xtemplate_implement_choice_elt:nn #1#2
+\cs_new_protected:Npn \__xtemplate_implement_choice_elt_aux:nnn #1#2#3
   {
-    \__xtemplate_implement_choice_elt:n {#1}
+    \keys_define:nx { template / #1 }
+      { \l__xtemplate_key_name_tl / #2 .code:n = { \exp_not:n {#3} } }
     \tl_set:Nx \l__xtemplate_tmp_tl
-      { \l__xtemplate_key_name_tl \c_space_tl #1 }
-    \prop_put:Non \l__xtemplate_vars_prop \l__xtemplate_tmp_tl {#2}
+      { \l__xtemplate_key_name_tl \c_space_tl #2 }
+    \prop_put:Non \l__xtemplate_vars_prop \l__xtemplate_tmp_tl {#3}
   }
+\cs_new_protected:Npn \__xtemplate_implement_choice_elt:n #1
+  {
+    \msg_error:nnxxx { xtemplate } { choice-requires-code }
+      { \l__xtemplate_key_name_tl } {#1}
+  }
 \cs_new_protected:Npn \__xtemplate_declare_restricted:nnnn #1#2#3#4
   {
     \__xtemplate_if_keys_exist:nnT {#1} {#2}
@@ -665,8 +699,8 @@
   }
 \cs_new_protected:Npn \__xtemplate_parse_values_elt:nn #1#2
   {
-    \tl_set:Nx \l__xtemplate_key_name_tl { \tl_to_str:n {#1} }
-    \tl_remove_all:Nn \l__xtemplate_key_name_tl { ~ }
+    \tl_set:Nx \l__xtemplate_key_name_tl
+      { \tl_trim_spaces:e { \tl_to_str:n {#1} } }
     \prop_get:NoNTF \l__xtemplate_keytypes_prop \l__xtemplate_key_name_tl
       \l__xtemplate_tmp_tl
       {
@@ -980,8 +1014,7 @@
   { \exp_after:wN \__xtemplate_key_to_value_auxi:w \l__xtemplate_value_tl }
 \cs_new_protected:Npn \__xtemplate_key_to_value_auxi:w \KeyValue #1
   {
-    \tl_set:Nx \l__xtemplate_tmp_tl { \tl_to_str:n {#1} }
-    \tl_remove_all:Nn \l__xtemplate_key_name_tl { ~ }
+    \tl_set:Nx \l__xtemplate_tmp_tl { \tl_trim_spaces:e { \tl_to_str:n {#1} } }
     \prop_get:NoNTF
       \l__xtemplate_vars_prop
       \l__xtemplate_tmp_tl
@@ -1132,6 +1165,13 @@
     each~choice~name~must~have~an~associated~implementation.\\
     This~should~be~given~after~a~'='~sign:~LaTeX~did~not~find~one.
   }
+\msg_new:nnnn { xtemplate } { choice-requires-code }
+  { The~choice~'#2'~for~key~'#1'~requires~an~implementation. }
+  {
+    You~should~have~put:\\
+    \ \ #1~:~choice~{~#2 = <code> ~} \\
+    but~LaTeX~did~not~find~any~<code>.
+  }
 \msg_new:nnnn { xtemplate } { duplicate-key-interface }
   { Key~'#1'~appears~twice~in~interface~definition~\msg_line_context:. }
   {
@@ -1320,10 +1360,11 @@
   { \__xtemplate_if_instance_exist:nnnT {#1} { } {#2} }
 \cs_new:Npn \IfInstanceExistF #1#2
   { \__xtemplate_if_instance_exist:nnnF {#1} { } {#2} }
-\cs_new_protected:Npn \EvaluateNow #1 {#1}
 \cs_new_protected:Npn \KeyValue #1 {#1}
 \cs_new_protected:Npn \AssignTemplateKeys
   { \__xtemplate_assignments_pop: }
+\cs_new_protected:Npn \SetTemplateKeys #1#2#3
+  { \keys_set:nn { template / #1 / #2 } {#3} }
 \cs_new_eq:NN \ShowTemplateKeytypes \ShowTemplateInterface
 %% 
 %%



More information about the tex-live-commits mailing list.