summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/latex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2023-01-24 20:57:30 +0000
committerKarl Berry <karl@freefriends.org>2023-01-24 20:57:30 +0000
commitee97f6dbd2e6acf46b912ba49ad1e59892892707 (patch)
treed57f5081c212d6c288b80fa545be94c459075c4d /Master/texmf-dist/doc/latex
parent81de637794cea58fe8f1a7128ac5f305de1ae155 (diff)
expkv-bundle (24jan23)
git-svn-id: svn://tug.org/texlive/trunk@65623 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/latex')
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/README.md46
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/comparison.tex246
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/expkv-bundle.pdfbin0 -> 714141 bytes
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/expkv-bundle.tex353
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/impatient.tex56
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/introduction.tex115
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/pkg-cs.tex937
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/pkg-def.tex727
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/pkg-main.tex1097
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/pkg-opt.tex229
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/pkg-pop.tex439
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/preamble-enverb.tex348
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/preamble-examples.tex16
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/preamble-l3doctweaks.tex39
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/preamble-logos.tex107
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/preamble-lst.tex218
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/preamble-noidx.tex50
-rw-r--r--Master/texmf-dist/doc/latex/expkv-bundle/preamble-prefixes.tex36
18 files changed, 5059 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/README.md b/Master/texmf-dist/doc/latex/expkv-bundle/README.md
new file mode 100644
index 00000000000..8d484d62d4e
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/README.md
@@ -0,0 +1,46 @@
+-------------------------------------------------------------------------------
+# `expkv-bundle` -- an expandable key=value implementation and more
+
+Version 2023-01-23
+
+Released under the LaTeX Project Public License v1.3c or later
+See http://www.latex-project.org/lppl.txt
+
+Hosted on the Island of TeX at https://gitlab.com/islandoftex/texmf/expkv-bundle
+
+-------------------------------------------------------------------------------
+
+Copyright (C) 2020-2023 Jonathan P. Spratte
+
+This work may be distributed and/or modified under the conditions of the LaTeX
+Project Public License (LPPL), either version 1.3c of this license or (at your
+option) any later version. The latest version of this license is in the file:
+
+ http://www.latex-project.org/lppl.txt
+
+This work is "maintained" (as per LPPL maintenance status) by
+ Jonathan P. Spratte
+
+-------------------------------------------------------------------------------
+
+## Summary of Contents
+
+`expkv-bundle` is a collection of different packages that provide key=value
+functionality in plainTeX, LaTeX, and ConTeXt.
+
+At the core the `expkv` package implements two expandable key=value parsers that
+are somewhat fast and robust against common bugs in many key=value
+implementations (no accidental brace stripping, no fragility for active commas
+or equals signs).
+
+`expkv-cs` enables users to define expandable key=value macros in a comfortable
+and straight forward way.
+
+`expkv-def` provides an interface to define common key types for `expkv` similar
+to the key defining interfaces of wide spread key=value implementations.
+
+`expkv-opt` allows to parse package or class options in LaTeX via `expkv`.
+
+`expkv-pop` is a utility package to define prefix oriented parsers that allow a
+somewhat natural formulation (it provides the core functionality for the
+key-defining front ends of both `expkv-cs` and `expkv-def`).
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/comparison.tex b/Master/texmf-dist/doc/latex/expkv-bundle/comparison.tex
new file mode 100644
index 00000000000..7736f0a4f1b
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/comparison.tex
@@ -0,0 +1,246 @@
+\section{Comparisons}\label{sec:cmp}
+
+This section makes some basic comparison between \expkv\ and other \kv\
+packages. The comparisons are really concise, regarding speed, feature range
+(without listing the features of each package, comparisons are done against the
+base \expkv\ not counting other packages in \expkvbundle\ that extend it, so
+\enquote{bigger feature set} might not necessarily be true if everything is
+included), and bugs and misfeatures.
+
+Comparisons of speed are done with a very simple test key and the help of the
+\pkg{l3benchmark} package. The key and its usage should be equivalent to
+\begin{enverb}[no-tcb]
+ \protected\ekvdef{test}{height}{\def\myheight{#1}}
+ \ekvsetdef\expkvtest{test}
+ \expkvtest{ height = 6 }
+\end{enverb}
+and only the usage of the key, not its definition, is benchmarked. For the
+impatient, the essence of these comparisons regarding speed and buggy
+behaviour is contained in \autoref{tab:comp}.
+
+As far as I know \expkv\ is the only fully expandable \kv\ parser. I tried to
+compare \expkv\ to every \kv\ package listed on
+\href{https://ctan.org/topic/keyval}{CTAN}, however, one might notice that
+some of those are missing from this list. That's because I didn't get the
+others to work due to bugs, or because they just provide wrappers around other
+packages in this list.
+
+In this subsection is no benchmark of |\ekvparse| and |\keyval_parse:NNn|
+contained, as most other packages don't provide equivalent features to my
+knowledge. |\ekvparse| is slightly faster than |\ekvset|, but keep in mind
+that it does less. The same is true for |\keyval_parse:NNn| compared to
+|\keys_set:nn| of \pkg{expl3} (where the difference is much bigger). Comparing
+just the two, |\ekvparse| is a tad faster than |\keyval_parse:NNn| because of
+two tests (for empty key names and only a single equal sign) which are
+omitted.
+
+\paragraph{\pkg{keyval}} is the fastest \kv\ package there is and has a minimal
+feature set with a slightly different way how it handles keys without values
+compared to \expkv. That might be considered a drawback, as it limits the
+versatility, but also as an advantage, as it might reduce doubled code. Keep in
+mind that as soon as someone loads \pkg{xkeyval} the performance of \pkg{keyval}
+gets replaced by \pkg{xkeyval}'s.
+
+Also \pkg{keyval} has a \pmso{bug}feature, which unfortunately can't really be
+resolved without breaking backwards compatibility for \emph{many} documents,
+namely it strips braces from the argument before stripping spaces if the
+outer most braces aren't surrounded by spaces, also it might strip more than one
+set of braces. Hence all of the following are equivalent in their outcome,
+though the last two lines should result in something different than the first
+two:
+\begin{enverb}[no-tcb]
+ \setkeys{foo}{bar=baz}
+ \setkeys{foo}{bar= {baz}}
+ \setkeys{foo}{bar={ baz}} % should be ` baz'
+ \setkeys{foo}{bar={{baz}}} % should be `{baz}'
+\end{enverb}
+
+\pkg{keyval} doesn't work with non-standard category codes of |=| and |,|. Also
+if a \kv\ pair contains multiple equals signs outside of braces everything post
+the first is silently ignored so the following two inputs yield identical
+outputs:
+\begin{enverb}[no-tcb,lst=belowskip=0pt]
+ \setkeys{foo}{bar=baz}
+ \setkeys{foo}{bar=baz=and more}
+\end{enverb}
+
+\paragraph{\pkg{xkeyval}} is pretty slow (yet not the slowest), but it provides
+more functionality, e.g., it has an interface to disable a list of keys, can
+search multiple sets simultaneously, and has an intriguing mechanism it calls
+\enquote{Pointers} to save the value of particular keys for later reuse. It
+contains the same bug as \pkg{keyval} as it has to be compatible with it by
+design (it replaces \pkg{keyval}'s frontend), but also adds even more cases in
+which braces are stripped that shouldn't be stripped, worsening the situation.
+
+\pkg{xkeyval} does work with non-standard category codes of |=| and |,|, but the
+used mechanism fails if the input contains a mix of different category codes for
+the same character. Just like with \pkg{keyval} equals signs after the first and
+everything after those is ignored.
+
+\paragraph{\pkg{ltxkeys}} is no longer compatible with the \LaTeX\ kernel
+starting with the release 2020-10-01. It is by far the slowest \kv\ package I've
+tested -- which is funny, because it aims to be ``[\ldots] faster [\ldots] than
+these earlier packages [referring to \pkg{keyval} and \pkg{xkeyval}].'' It needs
+more time to parse zero~keys than five of the packages in this comparison need
+to parse 100~keys. Since it aims to have a bigger feature set than
+\pkg{xkeyval}, it most definitely also has a bigger feature set than \expkv.
+Also, it can't parse |\long| input, so as soon as your values contain a |\par|,
+it'll throw errors. Furthermore, \pkg{ltxkeys} doesn't strip outer braces at
+all by design, which, imho, is a weird design choice. Some of the more
+intriguing features (e.g., the |\argpattern| mechanism) didn't work for me. In
+addition \pkg{ltxkeys} loads \pkg{catoptions} which is known to introduce bugs
+(e.g., see \url{https://tex.stackexchange.com/questions/461783}). Because it is
+no longer compatible with the kernel, I stop benchmarking it (so the numbers
+listed here and in \autoref{tab:comp} regarding \pkg{ltxkeys} were last updated
+on 2020-10-05).
+
+\pkg{ltxkeys} works with non-standard category codes, it also silently ignores
+any additional equals signs and the following tokens.
+
+\paragraph{\pkg{l3keys}} is at the slower end of the midfield yet not unusably
+slow, but has an, imho, great interface to define keys. It strips \emph{all}
+outer spaces, even if somehow multiple spaces ended up on either end. It offers
+more features, but has pretty much been bound to \pkg{expl3} code before.
+Nowadays the \LaTeX\ kernel has an interface with the macros |\DeclareKeys|,
+|\SetKeys|, and |\ProcessKeyOptions| that provides access to \pkg{l3keys} from
+the \LaTeXe\ layer as well as parsing package options with it. Because of the
+|\ProcessKeyOptions| macro and its features the only two viable options to
+provide \kv\ options for new projects in my opinion are the kernel's methods and
+\expkvo\ as those are the only two until now up to my knowledge that support
+parsing the raw options, and future options.
+
+\pkg{l3keys} handles active commas and equals signs fine. Multiple equals signs
+lead to an error if additional equals signs aren't nested inside of braces, so
+perfectly predictable behaviour here.
+
+\paragraph{\pkg{pgfkeys}} is among the top~4 of speed if one uses |\pgfqkeys|
+over |\pgfkeys|, else the initialisation parsing the family path takes roughly
+\SI{43}{\ops} and moves it two spots down the list (so in \autoref{tab:comp}
+both $p_0$ and $T_0$ would be about \SI{43}{\ops} bigger if
+|\pgfkeys{|\meta{path}|/.cd,|\meta{keys}|}| was used instead). It has an
+\emph{enormous} feature set. It stores keys in a way that reminds one of folders
+in a Unix system which allows interesting features and has other syntactic
+sugars. It is another package that implements something like the \expnotation\
+with less different options though. To get the best performance |\pgfqkeys| was
+used in the benchmark. It has the same or a very similar bug \pkg{keyval} has.
+The brace bug (and also the category fragility) can be fixed by \pkg{pgfkeyx},
+but this package was last updated in 2012 and it slows down |\pgfkeys| by
+factor~\num{8}. Also \pkg{pgfkeyx} is no longer compatible with versions of
+\pkg{pgfkeys} newer than 2020-05-25.
+
+\pkg{pgfkeys} silently drops anything after the second unbraced equals sign in a
+\kv\ pair.
+
+\paragraph{\pkg{kvsetkeys} with \pkg{kvdefinekeys}} is in the slower midfield,
+but it works even if commas and equals have category codes different from 12
+(just as some other packages in this list). It has quadratic run-time unlike
+most other \kv\ implementations which behave linear. The features of the
+keys are equal to those of \pkg{keyval}, the parser adds handling of unknown
+keys.
+
+\pkg{kvsetkeys} does include any additional equals sign in the value. But any
+active equals sign is turned into one of category code 12 if it's not nested in
+braces. Also spaces around superfluous equals signs are stripped. So the
+following all result in the same:
+\begin{enverb}[no-tcb,lst=belowskip=0pt]
+ \kvsetkeys{foo}{bar=baz=morebaz}
+ \kvsetkeys{foo}{bar=baz =morebaz}
+ \kvsetkeys{foo}{bar=baz= morebaz}
+ \kvsetkeys{foo}{bar=baz = morebaz}
+\end{enverb}
+
+\paragraph{\pkg{options}} is in the midfield of speed. It is faster per
+individual key than \pkg{pgfkeys} but has no shortcut like |\pgfqkeys|.
+It has a much bigger feature set than \expkv. Similar to \pkg{pgfkeys} it uses a
+folder like structure, makes searching multiple paths easy, incorporates package
+options and more. It also features a form of expansion control, predefined
+expansion kinds are limited though one can define additional ones. Unfortunately
+it also suffers from the premature unbracing bug \pkg{keyval} has.
+
+\pkg{options} can't handle non-standard category codes and will silently ignore
+superfluous equals signs and following tokens.
+
+\paragraph{\pkg{simplekv}} is hard to compare because I don't speak French (so
+I don't understand the documentation). There was an update released on
+2020-04-27 which greatly improved the package's performance and added
+functionality so that it can be used more like most of the other \kv\
+packages. Speed wise it is pretty close to \expkv. Regarding unknown keys it got
+a very interesting behaviour. It doesn't throw an error, but stores the \val\ in
+a new entry accessible with \cs[no-index]{useKV}. Also if you omit \val\ it
+stores |true| for that \key.
+
+\pkg{simplekv} can't correctly handle non-standard category codes. It silently
+ignores any unbraced equals sign beyond the first and any following tokens.
+
+\paragraph{\protect\yax} is the second slowest package I've tested. It has a
+pretty strange syntax for the \TeX-world, imho, and again a direct equivalent is
+hard to define (don't understand me wrong, I don't say I don't like the syntax,
+quite the contrary, it's just atypical). It has the premature unbracing bug,
+too. \yax\ features some prefixes one can use to make an assignment use |\edef|,
+|\gdef| or |\xdef| so has something that comes close to expansion control. Also
+somehow loading \yax\ broke \pkg{options} for me. The tested definition was:
+\begin{enverb}[no-tcb]
+ \usepackage{yax}
+ \defactiveparameter yax {\storevalue\myheight yax:height } % setup
+ \setparameterlist{yax}{ height = 6 } % benchmark
+\end{enverb}
+This seems important to state as \yax\ supports two different input syntaxes,
+the tested one was the one closer to traditional \kv\ input.
+
+\yax\ won't handle non-standard category codes correctly. Superfluous equals
+signs end up in the value in an unaltered form (just like with \expkv).
+
+\begin{table}
+ \def\fnsym{\textcolor{red!80!black}{*}}%
+ \sisetup{round-precision=1, round-mode=places}%
+ \begingroup
+ \centering
+ \newcommand*\yes{\textcolor{red!80!black} {yes}}^^A
+ \newcommand*\no {\textcolor{green!80!black}{no}}^^A
+ \caption[Comparison of \kv\ packages]
+ {^^A
+ Comparison of \kv\ packages. The packages are ordered from
+ fastest to slowest for one \kv\ pair. Benchmarking was done using
+ \pkg{l3benchmark} and the scripts in the \file{Benchmarks} folder
+ of \href{https://github.com/Skillmon/tex_expkv}{the original \expkv's git
+ repository}.
+ The columns $p_i$ are the polynomial coefficients of a linear fit to the
+ run-time, $p_0$ can be interpreted as the overhead for initialisation
+ and $p_1$ the cost per key. The $T_0$ column is the actual mean ops
+ needed for an empty list argument, as the linear fit doesn't match that
+ point well in general. The column ``BB'' lists whether the
+ parsing is affected by some sort of brace bug, ``CF'' stands for
+ category code fragile and lists whether the parsing breaks with active
+ commas or equal signs.^^A
+ \label{tab:comp}^^A
+ }
+ \begin{tabular}
+ {>{\collectcell\pkg}l<{\endcollectcell}*3{S[table-format=4.1]}ccc}
+ \toprule
+ \rmfamily Package & {$p_1$} & {$p_0$} & {$T_0$}& BB & CF & Date \\
+ \midrule
+ keyval & 13.557 & 2.202 & 7.185 & \yes & \yes & 2022-05-29 \\
+ \expkv & 16.669 & 3.132 & 5.836 & \no & \no & 2023-01-10 \\
+ simplekv & 19.943 & 2.850 & 15.120 & \no & \yes & 2022-10-01 \\
+ pgfkeys & 24.465 & 2.244 & 10.283 & \yes & \yes & 2021-05-15 \\
+ options & 23.255 & 16.160 & 20.400 & \yes & \yes & 2015-03-01 \\
+ kvsetkeys & {\fnsym} & {\fnsym} & 40.360 & \no & \no & 2022-10-05 \\
+ l3keys & 70.643 & 35.602 & 32.230 & \no & \no & 2022-12-17 \\
+ xkeyval & 255.906 & 221.276 & 173.400 & \yes & \yes & 2022-06-16 \\
+ \yax & 438.242 & 131.846 & 114.800 & \yes & \yes & 2010-01-22 \\
+ ltxkeys & 3400.142 & 4737.958 & 5368.000 & \no & \no & 2012-11-17 \\
+ \bottomrule
+ \end{tabular}
+ \par
+ \endgroup
+ \medskip
+ \fnsym For \pkg{kvsetkeys} the linear model used for the other
+ packages is a poor fit, \pkg{kvsetkeys} seems to have approximately
+ quadratic run-time, the coefficients of the second degree polynomial fit are
+ $p_2=\num{7.617}$, $p_1=\num{47.727}$, and $p_0=\num{57.988}$. Of course the
+ other packages might not really have linear run-time, but at least from 1~to
+ 20~keys the fits don't seem too bad. If one extrapolates the fits for 100
+ \kv\ pairs one finds that most of them match pretty well, the exception
+ being \pkg{ltxkeys}, which behaves quadratic as well with
+ $p_2=\num{23.500}$, $p_1=\num{2906.634}$, and $p_0=\num{6547.489}$.
+\end{table}
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/expkv-bundle.pdf b/Master/texmf-dist/doc/latex/expkv-bundle/expkv-bundle.pdf
new file mode 100644
index 00000000000..1d7023208a8
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/expkv-bundle.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/expkv-bundle.tex b/Master/texmf-dist/doc/latex/expkv-bundle/expkv-bundle.tex
new file mode 100644
index 00000000000..f8110ea36a1
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/expkv-bundle.tex
@@ -0,0 +1,353 @@
+\PassOptionsToPackage{full}{textcomp}
+\documentclass[exfoo=value, exbar, exfoo=\empty]{l3doc}
+
+% preamble >>=
+\makeatletter
+\let\save@onlypreamble\@onlypreamble
+\let\@onlypreamble\@gobble
+\usepackage[all]{expkv}
+\let\@onlypreamble\save@onlypreamble
+\makeatother
+\usepackage[oldstylenums,nott]{kpfonts}
+\input{glyphtounicode}
+\pdfgentounicode=1
+\usepackage{xfp} % required for an example
+\usepackage{booktabs}
+\usepackage{array}
+\usepackage{collcell}
+\usepackage{siunitx}
+\DeclareSIUnit\ops{ops}
+\usepackage{xcolor}
+\usepackage{caption}
+\usepackage{microtype}
+\usepackage{accsupp}
+\usepackage{enumitem}
+\usepackage{randtext}
+
+\usepackage{tcolorbox}%>>=
+\newtcolorbox{exresult}[2][]
+ {%
+ colback=ekvgrey!10!white%
+ ,colframe=ekvgrey%
+ ,fontupper=\small
+ ,width={\dimexpr#2\relax}%
+ ,#1%
+ }
+\newtcbox\exres[1][]
+ {
+ colback=ekvgrey!10!white
+ ,colframe=ekvgrey
+ ,size=small
+ ,nobeforeafter
+ ,tcbox raise base
+ ,fontupper=\small
+ ,#1
+ }
+%=<<
+
+\usepackage{listings}%>>=
+\input{preamble-lst.tex}
+%=<<
+
+\let\metaORIG\meta
+\protected\def\meta #1{\texttt{\metaORIG{#1}}}
+
+\input{preamble-examples.tex}
+\input{preamble-logos.tex}
+
+\makeatletter
+% shortcuts >>=
+\newcommand\Vkey{\texttt{Val}-\key}
+\newcommand*\Nkey{\texttt{NoVal}-\key}
+\newcommand\kv{\meta{key}=\penalty2000\meta{value}}
+\newcommand\kvarg{\{\kv, \ldots\}}
+\newcommand\key{\meta{key}}
+\newcommand\val{\meta{value}}
+\newcommand\set{\meta{set}}
+\newcommand\prefix{\texorpdfstring{\textit{prefix}}{prefix}}
+\newcommand\prefixes{\textit{prefixes}}
+\newcommand\type{\texorpdfstring{\textit{type}}{type}}
+\newcommand\types{\textit{types}}
+\newcommand\tkn[2]{\texttt{\char`#1}\textsubscript{#2}}
+\newcommand\expansion{\meta{expansion}}
+%\newcommand\expnotation{}
+%\edef\expnotation
+ %{\noexpand\texttt{exp\string|}\penalty\@M-\hskip\z@skip notation}
+\newcommand\singlecs[1]
+ {%
+ The \meta{cs} should be a single control sequence, such as
+ \cs[no-index]{#1}. \ignorespaces
+ }
+\newcommand\ekvdocsection[8]
+ {%
+ \clearpage
+ \chardef\ekvdoc@insection1
+ \section[{#7}]%
+ {%
+ #7%
+ \hfill
+ \begingroup\scriptsize\ttfamily
+ \begin{tabular}{@{}r@{}l@{}}%
+ #1{\string\input\{expkv#8\}} & \rlap{#2{\ \% plain}}\\
+ #3{\string\usepackage\{expkv#8\}} & \rlap{#4{\ \% LaTeX}}\\
+ #5{\string\usemodule[expkv#8]} & \rlap{#6{\ \% ConTeXt}}\\
+ \end{tabular}%
+ \endgroup
+ \label{sec:expkv#8}%
+ }%
+ \chardef\ekvdoc@insection0
+ }
+\chardef\ekvdoc@insection0
+\newcommand*\genericekv
+ {\ekvdocsection{}{\textcolor{gray}}{}{\textcolor{gray}}{}{\textcolor{gray}}}
+\newcommand*\latexekv
+ {\ekvdocsection\phantom\phantom{}{\textcolor{gray}}\phantom\phantom}
+%=<<
+
+\hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
+
+\input{preamble-prefixes.tex}
+\input{preamble-noidx.tex}
+\input{preamble-enverb.tex}
+
+% vissp >>=
+\ExplSyntaxOn
+\cs_new_protected:Npn \vissp #1
+ {
+ \group_begin:
+ \tl_set:Nn \l_tmpa_tl {#1}
+ \tl_replace_all:Nnn \l_tmpa_tl { ~ } { \asciispace }
+ \l_tmpa_tl
+ \group_end:
+ }
+\ExplSyntaxOff
+% =<<
+
+\ekvcSplit\expkvorules% >>=
+ {
+ cd = \emph{nothing}
+ ,cu = \emph{nothing}
+ ,pd = \emph{nothing}
+ ,pu = \emph{nothing}
+ }
+ {%
+ \begin{description}
+ \item[Class:]
+ \begin{description}
+ \item[defined] #1
+ \item[undefined] #2
+ \end{description}
+ \item[Package:]
+ \begin{description}
+ \item[defined] #3
+ \item[undefined] #4
+ \end{description}
+ \end{description}%
+ }
+\ekvcSecondaryKeys\expkvorules
+ {
+ meta d = {cd={#1},pd={#1}}
+ ,meta u = {cu={#1},pu={#1}}
+ }% =<<
+
+\newcommand*\pmso[1] % poor man's strike out%>>=
+ {%
+ \leavevmode
+ \begingroup
+ \sbox0{#1}%
+ \rlap{\vrule height .6ex depth -.5ex width \wd0\relax}%
+ \usebox0\relax
+ \endgroup
+ }%=<<
+
+\@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
+
+\renewcommand*\partname{Part}
+
+% \addsec and friends >>=
+\newcommand*\addsec@[2]
+ {%
+ \c@secnumdepth=%
+ \expanded
+ {%
+ \m@ne
+ \unexpanded{#1{#2}}%
+ \c@secnumdepth=\the\c@secnumdepth\relax
+ }%
+ }
+\newcommand*\addsec {\addsec@\section}
+\newcommand*\addssec {\addsec@\subsection}
+\newcommand*\addsssec{\addsec@\subsubsection}
+% =<<
+
+\newenvironment{syntaxexample}% >>=
+ {%
+ \quote
+ \ttfamily\small\frenchspacing
+ \parskip=\z@
+ \def\indent{\leavevmode\phantom{mm}}%
+ }
+ {\endquote}
+\newenvironment{syntaxexample*}
+ {\syntaxexample\obeylines}
+ {\endsyntaxexample}% =<<
+
+\newcommand\expkvdocPrintErrors[1][]
+ {%
+ \protected\long\def\expkvdoc@errfont##1%
+ {\texttt{\frenchspacing\textcolor{red!80!black}{##1}}}%
+ \protected\long\def\ekv@err@collect##1\par##2%
+ {\expkvdoc@errfont{! \detokenize{##2} Error: ##1}#1}%
+ \protected\long\def\expkvdoc@errm##1##2%
+ {\expkvdoc@errfont{! expkv##1 Error: ##2}#1}%
+ \def\ekv@errm{\expkvdoc@errm{}}%
+ \def\ekvc@errm{\expkvdoc@errm{-cs}}%
+ \def\ekvd@errm{\expkvdoc@errm{-def}}%
+ \def\ekvp@errm{\expkvdoc@errm{-pop}}%
+ }
+\makeatother
+
+\ExplSyntaxOn
+\str_new:N \g__expkvdoc_module_str
+\cs_new_protected:Npn \expkvdocfile #1% >>=
+ {
+ \expkvdoc_for_module:nn {#1}
+ {
+ \str_if_eq:nnTF {#1} {main}
+ { \lstset{style=expkv} }
+ { \lstset{style=expkv-#1} }
+ \addtocontents{exs}
+ {
+ \medskip
+ \noindent
+ \use:c { expkv \str_if_eq:nnF {#1} {main} { \str_head:n {#1} } }
+ \smallskip
+ }
+ \input{pkg-#1.tex}
+ }
+ }% =<<
+\cs_new_protected:Npn \expkvdocdtx #1% >>=
+ {
+ \expkvdoc_for_module:nn {#1}
+ {
+ \str_if_eq:nnTF {#1} {main}
+ { \DocInput{expkv.dtx} }
+ { \DocInput{expkv-#1.dtx} }
+ }
+ }% =<<
+\cs_new_protected:Npn \expkvdoc_for_module:nn #1#2% >>=
+ {
+ \use:e
+ {
+ \exp_not:n
+ {
+ \str_gset:Nn \g__expkvdoc_module_str {#1}
+ #2
+ \str_gset:Nn \g__expkvdoc_module_str
+ }
+ { \g__expkvdoc_module_str }
+ }
+ }% =<<
+\ExplSyntaxOff
+
+\input{preamble-l3doctweaks.tex}
+
+%=<<
+
+% for thanking Niranjan
+% code from https://tex.stackexchange.com/a/635125/117050
+\def\DevnagVersion{2.17}
+\usepackage{devanagari}
+
+\newif\ifexpkvDocImplementation%\expkvDocImplementationtrue
+
+\begin{document}
+\title{\expkvbundle}
+%\title% >>=
+ %{%
+ %\texorpdfstring
+ %{%
+ %\huge\expkvbundle
+ %\\[\medskipamount]
+ %\Large an {\expFormat}andable
+ %\meta{{\kvstyle k}\kern-.05em ey}=%
+ %\meta{{\kvstyle v}\kern-.05em alue}
+ %implementation and more%
+ %}
+ %{expkv-bundle - an expandable <key>=<value> implementation and more}%
+ %}% =<<
+\author
+ {%
+ Jonathan P. Spratte%
+ \thanks
+ {%
+ \protect\randomize{jspratte@yahoo.de};
+ Special thanks to {\protect\dn Enr\2jn} (Niranjan) for valuable
+ suggestions and additions to this documentation.%
+ }%
+ }
+\date{2023-01-23}
+\begingroup
+\renewcommand*\thefootnote{\fnsymbol{footnote}}
+\maketitle
+\endgroup
+
+\begin{abstract}%>>=
+ \noindent\parfillskip=0pt
+ The \expkvbundle\ provides at its core a \emph{fully expandable} \kv\ parser,
+ that is \emph{safe} for active commas and equals signs, \emph{reliable} to
+ only strip one set of braces after spaces are stripped, and blazingly
+ \emph{fast}, as of writing this only \pkg{keyval} is faster.
+ \par
+ \bigskip
+ This parser gets augmented by a family of packages. \expkvc\ allows to easily
+ define expandable macros using a \kv\ interface, making the expandable parser
+ available to the masses. \expkvd\ provides a \kv\ interface to
+ define common \key-types. With \expkvo\ you can parse package
+ and class options. \expkvp\ enables you to design your own prefix
+ oriented parsers for interface definitions.
+\end{abstract}%=<<
+
+\tableofcontents
+
+\clearpage
+
+\begin{documentation}% >>=
+\ifexpkvDocImplementation\part{Documentation}\fi
+
+\input{introduction.tex}
+\clearpage
+\input{impatient.tex}
+
+\expkvdocfile{main}
+\expkvdocfile{cs}
+\expkvdocfile{def}
+\expkvdocfile{opt}
+\expkvdocfile{pop}
+\clearpage
+\lstset{style=expkv-all}
+\input{comparison.tex}
+\end{documentation}% =<<
+
+\clearpage
+\listofexamples
+
+\ifexpkvDocImplementation
+ \clearpage
+ \begin{implementation}% >>=
+ \part{Implementation}
+ \expkvdocdtx{main}
+ \clearpage
+ \expkvdocdtx{cs}
+ \clearpage
+ \expkvdocdtx{def}
+ \clearpage
+ \expkvdocdtx{opt}
+ \clearpage
+ \expkvdocdtx{pop}
+ \end{implementation}% =<<
+\fi
+
+\clearpage
+\PrintIndex
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/impatient.tex b/Master/texmf-dist/doc/latex/expkv-bundle/impatient.tex
new file mode 100644
index 00000000000..b3d62b07faf
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/impatient.tex
@@ -0,0 +1,56 @@
+\addsec{\expkvbundle\ for the Impatient}
+
+This section gives a very brief and non-exhaustive overview over the contents of
+the \expkvbundle. For more information (and more functionality) you'll have to
+read the sections of the packages you're interested in.
+
+\expkvbundle\ supports expansion control in \kv\ lists. The corresponding
+syntax and features are documented in \autoref{sec:expkv:expansion}.
+
+The following user interface macros (and more) are available in the different
+packages of the bundle:
+\paragraph{Defining keys}
+\begin{itemize}
+ \item \cs[no-index]{ekvdefinekeys}\marg{set}\texttt{\kvarg}
+ defines the keys in the \kv\ list, many common key types are available
+ (\autoref{sec:d:macros} and for the types \autoref{sec:d:types}).
+ \item \cs[no-index]{ekvdef}\marg{set}\marg{key}\marg{code}
+ defines the behaviour of a \Vkey\ (\autoref{sec:expkv:setup}).
+ \item \cs[no-index]{ekvdefNoVal}\marg{set}\marg{key}\marg{code}
+ defines the behaviour of a \Nkey\ (\autoref{sec:expkv:setup}).
+\end{itemize}
+\paragraph{Parsing \kv\ lists}
+\begin{itemize}
+ \item \cs[no-index]{ekvset}\marg{set}\texttt{\kvarg}
+ sets defined keys (\autoref{sec:expkv:set}).
+ \item \cs[no-index]{ekvparse}\marg{k-code}\marg{kv-code}\texttt{\kvarg}
+ parses the \kv\ list and runs \meta{k-code} or \meta{kv-code} on the
+ elements (\autoref{sec:expkv:parse}).
+\end{itemize}
+\paragraph{Defining expandable \kv\ macros}
+\begin{itemize}
+ \item \cs[no-index]{ekvcSplit}\meta{cs}\texttt{\kvarg}\marg{code}
+ defines a fully expandable macro with the keys in the \kv\ list,
+ values are accessed by |#1| to |#9| (\autoref{sec:c:split}).
+ \item \cs[no-index]{ekvcHash}\meta{cs}\texttt{\kvarg}\marg{code}
+ defines a fully expandable macro with the keys in the \kv\ list,
+ values are accessed using \cs[no-index]{ekvcValue}\hskip0pt\marg{key}|{#1}|
+ (\autoref{sec:c:hash}).
+ \item \cs[no-index]{ekvcSecondaryKeys}\meta{cs}\texttt{\kvarg}
+ defines additional keys of predefined types for a \meta{cs} defined with
+ \cs[no-index]{ekvcSplit} or \cs[no-index]{ekvcHash}
+ (\autoref{sec:c:secondary} and for the types
+ \autoref{sec:c:secondarytypes}).
+\end{itemize}
+\paragraph{Parsing options} (\autoref{sec:o:macros})
+\begin{itemize}
+ \item \cs[no-index]{ekvoProcessOptions}\marg{set}
+ processes the global options, and the options given to the current and
+ all future calls of the package.
+ \item \cs[no-index]{ekvoProcessGlobalOptions}\marg{set}
+ processes the global options.
+ \item \cs[no-index]{ekvoProcessLocalOptions}\marg{set}
+ processes the local options of a package or class.
+ \item \cs[no-index]{ekvoProcessFutureOptions}\marg{set}
+ processes the options of future calls of the package.
+\end{itemize}
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/introduction.tex b/Master/texmf-dist/doc/latex/expkv-bundle/introduction.tex
new file mode 100644
index 00000000000..de52d9e5843
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/introduction.tex
@@ -0,0 +1,115 @@
+\addsec{Introduction}
+%The name \expkv\ stands for \emph{exp}andable \emph{k}ey-\emph{v}alue and shall
+%be pronounced \enquote{axe(b) kay vee}.
+
+This bundle consists of different packages the base being \expkv. Most of these
+packages are available for \hologo{plainTeX}, \LaTeXe, and \hologo{ConTeXt}. For
+stylistic reasons the package names are printed as
+\expkvLogoFormat{\textit{$\langle$pkg$\rangle$}}, but the files are named
+\texttt{expkv-\meta{pkg}} (CTAN-rules don't allow \string| in names), so in
+order to load \expkvc\ in \LaTeXe\ you should use
+\begin{enverb}[no-tcb]
+ \usepackage{expkv-cs}
+\end{enverb}
+Each section describing a package of this bundle has next to its heading the
+formats in which they work printed flush right. If more than a single format is
+supported by a package the functionality is defined by the \hologo{plainTeX}
+variant and the other variants only load the generic code in a way suitable for
+the format.
+
+\addssec{Terminology}
+This documentation uses a few terms which always mean specific things:
+\begin{description}
+ \item[\kv\ pair]
+ is one element in a comma separated list which contains at least one equals
+ sign \emph{not} contained in any braces, and the first such equals sign is
+ the separator between the \key\ (with an optional \expansion\ prefix) and
+ the \val.
+ \item[\key]
+ means the entire left-hand side of a \kv\ pair with an optional \expansion\
+ prefix stripped, or if =\val\ is omitted the complete list element, again
+ with an \expansion\ prefix stripped.
+ \item[\key-name]
+ synonymous to \key.
+ \item[\Vkey]
+ describes a \key\ in a \kv\ pair.
+ \item[\Nkey]
+ describes a \key\ for which =\val\ was or should be omitted.
+ \item[\val]
+ is the right-hand side of a \kv\ pair.
+ \item[\kv\ list]
+ is a comma separated list containing \kv\ pairs and \Nkey{}s (each possibly
+ with an \expansion\ prefix).
+ \item[\kvarg]
+ an argument that should get a \kv\ list.
+ \item[\expansion\ prefix]
+ an optional prefix in front of \key\ to specify \expansion-rules (see
+ \autoref{sec:expkv:expansion}), that prefix consists of the \expansion-rules
+ followed by a colon immediately followed by a space.
+ \item[\expansion]
+ a list of tokens specifying expansion steps for \key\ and \val.
+ \item[\expansion-rule]
+ a single expansion step in the \expansion-rules.
+ \item[\expansion-rules]
+ synonymous to \expansion.
+ \item[\expnotation]
+ the notation of \expansion-rules in form of the \expansion\ prefix.
+ \item[key-code]
+ the code that is executed for a given \key.
+ \item[key-macro]
+ the internal macro that stores the key-code.
+\end{description}
+
+Though not really terminology but more typographic representation I want to
+highlight a distinction between two different types of code listings in this
+documentation. I use the following looks to show a code example and its results:
+\begin{enverb}[same-line=0.6]
+ \newcommand*\foo{This is an example.}
+ \foo
+\end{enverb}
+And this is how a syntax summary or a syntax example looks like (this is more
+abstract than an example and contains short meta-descriptions of inputs):
+\begin{syntaxexample}
+ \cs[no-index]{function}\marg{syntax}
+\end{syntaxexample}
+Inside such syntax summaries the following rules usually apply (and \meta{arg}
+would be the meta description here):
+\begin{description}[font=\small\ttfamily]
+ \item[\marg{arg}]
+ a mandatory argument is shown in braces
+ \item[\meta{arg}]
+ a mandatory argument that should be a single token is shown without
+ additional parentheses/braces/brackets
+ \item[\oarg{arg}]
+ an optional argument is shown in brackets (and should be input with
+ brackets)
+ \item[\meta{*}]
+ an optional star is shown like this
+\end{description}
+If other types of arguments are displayed the documentation will explain what
+they mean in this particular place.
+
+\addssec{Category Codes}
+Supporting different category codes of a single character code makes the
+programmer's life harder in \TeX, but there are valid reasons to make some
+active, or letter. Because of this the packages in this bundle support different
+category codes for specific syntax relevant characters (unless otherwise
+documented). This doesn't mean that \expkv\ changes any category codes, only
+that parsing is correct \emph{if} they are changed later (the codes listed
+assume standard category codes of \hologo{plainTeX} and \LaTeXe\ apply while
+\expkv\ is loaded). The supported tokens are:
+\begin{description}
+ \item[=] \tkn{=}{12} and \tkn{=}{13}
+ \item[,] \tkn{,}{12} and \tkn{,}{13}
+ \item[:] (for the \expnotation) \tkn{:}{11}, \tkn{:}{12}, and \tkn{:}{13}
+ \item[*] (for starred macros) \tkn{*}{3}, \tkn{*}{4}, \tkn{*}{6}, \tkn{*}{7},
+ \tkn{*}{8}, \tkn{*}{11}, \tkn{*}{12}, and \tkn{*}{13}
+ \item[{[}] (for |\ekvoptarg|) only \tkn{[}{12}
+ \item[{]}] (for |\ekvoptarg|) only \tkn{]}{12}
+\end{description}
+
+\addssec{Bugs}
+Just like \pkg{keyval}, \expkv\ is bug free. But if you find \pmso{bugs}hidden
+features\footnote{Thanks, David!} you can tell me about them either via mail
+(see the first page) or directly on GitLab if you have an account there:
+\url{https://gitlab.com/islandoftex/texmf/expkv-bundle}
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/pkg-cs.tex b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-cs.tex
new file mode 100644
index 00000000000..850b9af6205
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-cs.tex
@@ -0,0 +1,937 @@
+\genericekv\expkvc{-cs}
+
+\expkvc\ aids in creating fully expandable macros that take a \kv\ argument. It
+implements somewhat efficient solutions to expandable \kv\ parsing without the
+user having to worry too much about the details.
+
+The package supports two main approaches for this. The first is splitting the
+keys up into individual arguments, the second preparses the \kv\ list into a
+single argument in which accessing the value of individual keys is fast. The
+behaviour of the second type is similar to a hash table, so we call that variant
+|Hash|, the first type is called |Split|. Both these variants support a number
+of so called \emph{primary keys} (a primary key matches an argument, roughly
+speaking).
+
+In addition to these methods there is a structured way to define additional keys
+which might build upon the primary keys but not directly relate to an argument.
+These keys are called \emph{secondary keys}. Primary and secondary keys belong
+to a specific macro (the macro name serves as the \emph{set}).
+
+A word of advice you should consider: Macros defined with \expkvc\ are simple to
+create, and there might be good use cases for them (for instance since they
+don't work by assignments but only by argument forwarding logic they have no
+issues with implicit or explicit groups whatsoever). But they don't scale as
+well as established \kv\ interfaces (think of the idiomatic key definitions with
+\pkg{keyval}, or \pkg{l3keys}, or \expkv\ with or without \expkvd), and they are
+slower than idiomatic key definitions in packages with fast \kv\ parsing.
+
+
+\subsection{Defining Macros and Primary Keys}
+
+All macros defined with \expkvc\ have to be previously undefined (or have the
+|\meaning| of |\relax|). There is no way to automatically undefine keys once
+they are set up -- so to make sure there are no conflicts only new definitions
+are allowed. The \emph{set} name (as used by \cs[no-index]{ekvset}) will be
+\cs[no-index]{string}\cs[no-index]{\meta{macro}}.
+
+
+\subsubsection{Primary Keys\label{sec:c:primary}}
+
+The notion of primary keys needs a bit of explanation, or better, the input
+syntax for the argument \meta{primary keys} in the following explanations. The
+\meta{primary keys} argument should be a \kv\ list in which each \key\ will be
+one primary key and \val\ the initial value of said \key\ (and that value is
+mandatory, even if you leave it blank that's fine, but you have to explicitly
+state it). By default all keys are defined short, but you can define |\long|
+keys by prefixing \key\ with |long| (\emph{e.g.},
+|long name=Jonathan P. Spratte| to define a |\long| key called |name|). Due to
+some internal implementations it's worth noting that |\long| keys are a
+microscopic grain faster. The \meta{cs} will only be defined |\long| if at least
+one of the keys was |\long|. For obvious reasons there is no interface in place
+to define something as |\protected|.
+
+To allow keys to start with the word |long| even if you don't want them to be
+|\long| you can also prefix them with |short|. The first found prefix of the two
+will stop the parsing for prefixes and what remains becomes the \key.
+
+These rules culminate in the following:
+
+\begin{enverb}[no-tcb]
+ \ekvcSplit\foo
+ {
+ long short = abc\par
+ ,short long = def
+ }
+ {#1#2}
+\end{enverb}
+will define a macro |\foo| that knows two primary keys, |short| which is defined
+|\long| (so will accept explicit |\par| tokens inside its value at use time),
+and |long| which doesn't accept explicit |\par| tokens (leading to a low level
+\TeX\ error). The description of |\ekvcSplit| follows shortly.
+
+There is one exception to the rule that each \key\ in \meta{primary keys} needs
+to get a value: If you include a key named |...| without a value this will be a
+primary key in which every unknown key will be collected -- and \meta{cs} will
+be defined |\long|. The unknown keys will be stored in a way that \emph{most}
+\kv\ parsers will parse them correctly (but this is no general guarantee, for
+instance \pkg{pgfkeys} can accidentally strip multiple sets of braces at the
+wrong moment). See some examples in \autoref{sec:c:unknown}.
+
+At the moment \expkvc\ doesn't require any internal keys, but I can't foresee
+whether this will be the case in the future as well, as it might turn out that
+some features I deem useful can't be implemented without such internal keys.
+Because of this, please don't use key names starting with "EKVC|" as that
+should be the private name space.
+
+
+\subsubsection{Split\label{sec:c:split}}
+
+The split variants will provide the key values as separate arguments. This
+limits the number of keys for which this is truly useful.
+
+\begin{function}{\ekvcSplit}
+ \begin{syntax}
+ \cs{ekvcSplit}\meta{cs}\marg{primary keys}\marg{definition}
+ \end{syntax}
+ This defines \meta{cs} to be a macro taking one mandatory argument which
+ should contain a \kv\ list. The \meta{primary keys} will be defined for this
+ macro (see \autoref{sec:c:primary}). The \meta{definition} is the code that
+ will be executed. You can access the \val\ of a \key\ by using a macro
+ parameter from |#1| to |#9|. The order of the macro parameters will be the
+ order provided in the \meta{primary keys} list (so |#1| is the \val\ of the
+ \key\ defined first). With \cs{ekvcSplit} you can define macros using at most
+ nine primary keys.
+\end{function}
+\begin{example}{Simple macro with \cs[no-index]{ekvcSplit}}
+ The following defines a macro |\foo| that takes the keys |a| and |b|
+ and outputs their values in a textual form:
+ \begin{enverb}
+ \ekvcSplit\foo{a=a,b=b}{a is #1.\par b is #2.\par}
+ \foo{}
+ \foo{b=e}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvcSplitAndForward}
+ \begin{syntax}
+ \cs{ekvcSplitAndForward}\meta{cs}\marg{after}\marg{primary keys}
+ \end{syntax}
+ This defines \meta{cs} to be a macro taking one mandatory argument which
+ should contain a \kv\ list. You can use as many primary keys as you want with
+ this. The primary keys will be forwarded to \meta{after} as braced arguments
+ (as many as necessary for your primary keys). The order of the braced
+ arguments will be the order of your primary key definitions. In \meta{after}
+ you can use just a single control sequence, or some arbitrary stuff which will
+ be left in the input stream before your braced values (with one set of braces
+ stripped from \meta{after}), so both of the following would be fine:
+ \begin{enverb}[no-tcb]
+ \ekvcSplitAndForward\foo\foo@aux{keyA = A, keyB = B}
+ \ekvcSplitAndForward\foo{\foo@aux{more args}}{keyA = A, keyB = B}
+ \end{enverb}
+\end{function}
+\noindent
+In the first case |\foo@aux| should take at least two arguments (|keyA| and
+|keyB|), in the second case at least three (|more args|, |keyA|, and |keyB|).
+
+\begin{function}{\ekvcSplitAndUse}
+ \begin{syntax}
+ \cs{ekvcSplitAndUse}\meta{cs}\marg{primary keys}
+ \end{syntax}
+ This will roughly do the same as \cs{ekvcSplitAndForward}, but instead of
+ specifying what will be used after splitting the keys, \meta{cs} will use what
+ follows the \kv\ list. So its syntax will be
+\end{function}
+\begin{quote}
+ \ttfamily
+ \meta{cs}\kvarg\marg{after}
+\end{quote}
+and the code in |after| should expect at least as many arguments as the number
+of keys defined for \meta{cs}.
+
+
+\subsubsection{Hash\label{sec:c:hash}}
+
+The hash variants will provide the key values as a single argument in which you
+can access specific values using a special macro. The implementation might be
+more convenient and scale better, \emph{but} it is slower (for a rudimentary
+macro with a single key benchmarking was almost 1.7~times slower, the root of
+which being the key access with \cs{ekvcValue}, not the parsing, and for a key
+access using \cs{ekvcValueFast} it was still about 1.2~times slower). Still to
+be future proof, considering the hash variants is a good idea, and to get best
+performance but less maintainable code you can resort to the split approach.
+
+\begin{function}{\ekvcHash}
+ \begin{syntax}
+ \cs{ekvcHash}\meta{cs}\marg{primary keys}\marg{definition}
+ \end{syntax}
+ This defines \meta{cs} to be a macro taking one mandatory argument which
+ should contain a \kv\ list. You can use as many primary keys as you want. The
+ primary keys will be forwarded as a single argument containing every key to
+ the underlying macro. The underlying macro is defined as \meta{definition}, in
+ which you can access the \val\ of a \key\ by using
+ \cs{ekvcValue}\marg{key}|{#1}| (or similar).
+\end{function}
+\begin{example}{Simple macro with \cs[no-index]{ekvcHash}}
+ This defines an equivalent macro to the |\foo| defined with \cs{ekvcSplit}
+ earlier:
+ \begin{enverb}
+ \ekvcHash\foo{a=a,b=b}{a is \ekvcValue{a}{#1}.\par
+ b is \ekvcValue{b}{#1}.\par}
+ \foo{}
+ \foo{b=e}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvcHashAndForward}
+ \begin{syntax}
+ \cs{ekvcHashAndForward}\meta{cs}\marg{after}\marg{primary keys}
+ \end{syntax}
+ This defines \meta{cs} to be a macro taking one mandatory argument which
+ should contain a \kv\ list. You can use as many primary keys as you want. The
+ primary keys will be forwarded as a single argument containing every key to
+ \meta{after}. You can use a single macro for \meta{after} or use some
+ arbitrary stuff, which will be left in the input stream before the hashed \kv\
+ list with one set of braces stripped. In the macro called in \meta{after} you
+ can access the \val\ of a \key\ by using \cs{ekvcValue}\marg{key}|{#1}| (or
+ whichever argument the hashed \kv\ list will be in).
+\end{function}
+\begin{example}{Using \cs[no-index]{ekvcHashAndForward}}
+ This defines a macro |\foo| processing two keys, and passing the result to
+ |\foobar|:
+ \begin{enverb}
+ \ekvcHashAndForward\foo\foobar{a=a,b=b}
+ \newcommand*\foobar[1]{a is \ekvcValue{a}{#1}.\par
+ b is \ekvcValue{b}{#1}.\par}
+ \foo{}
+ \foo{b=e}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvcHashAndUse}
+ \begin{syntax}
+ \cs{ekvcHashAndUse}\meta{cs}\marg{primary keys}
+ \end{syntax}
+ This will roughly do the same as \cs{ekvcHashAndForward}, but instead of
+ specifying what will be used after hashing the keys during the definition,
+ \meta{cs} will use what follows the \kv\ list. So its syntax will be
+ \begin{quote}
+ \ttfamily
+ \meta{cs}\kvarg\marg{after}
+ \end{quote}
+\end{function}
+
+\begin{function}{\ekvcValue}
+ \begin{syntax}
+ \cs{ekvcValue}\marg{key}\marg{key list}
+ \end{syntax}
+ This is a safe way to access your keys in a hash variant. \key\ is the key
+ which's \val\ you want to use out of the \meta{key list}. \meta{key list}
+ should be the key list argument forwarded to your underlying macro by
+ \cs{ekvcHash}, \cs{ekvcHashAndForward}, or \cs{ekvcHashAndUse}. It will be
+ tested whether the hash function to access that \key\ exists, the \key\
+ argument is not empty, and that the \meta{key list} really contains a \val\ of
+ that \key. This macro needs exactly two steps of expansion and if used inside
+ of an |\edef| or |\expanded| context will protect the \val\ from further
+ expanding.
+\end{function}
+
+\begin{function}{\ekvcValueFast}
+ \begin{syntax}
+ \cs{ekvcValueFast}\marg{key}\marg{key list}
+ \end{syntax}
+ This behaves similar to \cs{ekvcValue}, but \emph{without any} safefy tests.
+ As a result this is about 1.4~times faster \emph{but} will throw low level
+ \TeX\ errors eventually if the hash function isn't defined or the \key\ isn't
+ part of the \meta{key list} (\emph{e.g.}, because it was defined as a key for
+ another macro -- all macros share the same hash function per \meta{key} name).
+ Note that this will not only throw low level errors but result in undefined
+ behaviour as well! This macro needs exactly three steps of expansion in the
+ no-error case.
+\end{function}
+
+\begin{function}{\ekvcValueSplit}
+ \begin{syntax}
+ \cs{ekvcValueSplit}\marg{key}\marg{key list}\marg{next}
+ \end{syntax}
+ If you need a specific \key\ from a \meta{key list} more than once, it'll be a
+ good idea to only extract it once and from then on keep it as a separate
+ argument (or if you want to forward this value to another macro). Hence the
+ macro \cs{ekvcValueSplit} will extract one specific \key's \val\ from the list
+ and forward it as an argument to \meta{next}, so the result of this will be
+ \meta{next}\marg{value}. This is roughly as fast as \cs{ekvcValue} and runs
+ the same tests.
+\end{function}
+\begin{example}
+ {Splitting of a key from a hash list using \cs[no-index]{ekvcValueSplit}}
+ The following defines a macro |\foo| which will take three keys. Since the
+ next parsing step will need the value of one of the keys multiple times we
+ split that key off the list (in this example the next step doesn't use the key
+ multiple times for simplicity though), and the entire list is forwarded as the
+ second argument:
+ \begin{enverb}
+ \ekvcHash\foo{a=a,b=b,c=c}
+ {\ekvcValueSplit{a}{#1}\foobar{#1}}
+ \newcommand*\foobar[2]{a is #1.\par
+ b is \ekvcValue{b}{#2}.\par
+ c is \ekvcValue{c}{#2}.\par}
+ \foo{}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvcValueSplitFast}
+ \begin{syntax}
+ \cs{ekvcValueSplitFast}\marg{key}\marg{key list}\marg{next}
+ \end{syntax}
+ This behaves just like \cs{ekvcValueSplit}, but it won't run the safety tests,
+ hence it is faster but more error prone, just like the relation between
+ \cs{ekvcValue} and \cs{ekvcValueFast}.
+\end{function}
+
+
+\subsection{Secondary Keys\label{sec:c:secondary}}
+
+To lift some limitations of each primary key matching one argument or hash
+entry, you can define secondary keys. Those have to be defined for each macro
+individually but it doesn't matter whether that macro was set up as a split or
+hash variant.
+
+Secondary keys can have a \prefix\ (|long|), and must have a \type\
+(like |meta|). Some \types\ might require some \prefix\ while other
+\types\ might forbid the usage of a specific \prefix.
+
+Please keep in mind that key names shouldn't start with "EKVC|".
+
+\begin{function}{\ekvcSecondaryKeys}
+ \begin{syntax}
+ \cs{ekvcSecondaryKeys}\meta{cs}\kvarg
+ \end{syntax}
+ This is the front facing macro to define secondary keys. For the macro
+ \meta{cs} define \key\ to have definition \val. The general syntax for \key\
+ should be
+ \begin{quote}\ttfamily
+ \meta{prefix} \meta{name}
+ \end{quote}
+ Where \meta{prefix} is a space separated list of optional \prefixes\
+ followed by one \type. The syntax of \meta{value} is dependent on the
+ used \type.
+\end{function}
+
+
+\subsubsection{\textit{Prefixes}}
+
+Currently there is only one \prefix\ available, which is
+\begin{function}[module=expkv-cs prefix]{long}
+ The following key will be defined |\long|.
+\end{function}
+
+
+\subsubsection{\textit{Types}\label{sec:c:secondarytypes}}
+
+Compared to \expkvd\ you might notice that the \types\ here are much fewer.
+Unfortunately the expansion only concept doesn't allow for great variety in the
+common key \types.
+
+The syntax examples of the \types\ will show which \prefix\ will be
+automatically used by printing those black (\texttt{\enfprefix{long}}), which
+will be available in grey (\texttt{\allprefix{long}}), and which will be
+disallowed in red (\texttt{\notprefix{long}}). This will be put flush right next
+to the syntax line.
+
+If a secondary key references another key it doesn't matter whether that other
+key is a primary or secondary key (unless explicitly stated otherwise).
+
+\begin{function}[module=expkv-cs type]{meta}
+ \begin{syntax}
+ meta \key\ = \kvarg \prefixes2
+ \end{syntax}
+ With a |meta| key you can set other keys. Whenever \meta{key} is used the keys
+ in the \kv\ list will be set to the values given there. You can use the \val\
+ given to \key\ by using |#1| in the \kv\ list.
+\end{function}
+
+\begin{function}[module=expkv-cs type]{nmeta}
+ \begin{syntax}
+ nmeta \key\ = \kvarg \prefixes3
+ \end{syntax}
+ An |nmeta| key is like a |meta| key, but it doesn't take a value at use time,
+ so the \kv\ list is static.
+\end{function}
+
+\begin{function}[module=expkv-cs type]{alias}
+ \begin{syntax}
+ alias \meta{key} = \marg{key_2} \prefixes3
+ \end{syntax}
+ This assigns the definition of \meta{key_2} to \key. As a result \key\ is an
+ alias for \meta{key_2} behaving just the same. Both the \Vkey\ and the \Nkey\
+ will be copied if they are defined when |alias| is used. Of course,
+ \meta{key_2} has to be defined as at least one of \Nkey\ or \Vkey.
+\end{function}
+
+\begin{function}[module=expkv-cs type]{default}
+ \begin{syntax}
+ default \key\ = \marg{default} \prefixes3
+ \end{syntax}
+ If \key\ is defined as a \Vkey\ you can define a \Nkey\ version with this. The
+ \Nkey\ will behave as if \key\ was given \meta{default} as its \val. Note that
+ this doesn't change the initial values of primary keys set at definition time
+ (see \cs{ekvcChange} in \autoref{sec:c:change} for this). If \key\ isn't yet
+ defined this results in an error.
+\end{function}
+
+\begin{function}[module=expkv-cs type]{enum}
+ \begin{syntax}
+ enum \key\ = \marg{key_2}\kvarg \prefixes2
+ \end{syntax}
+ This defines \key\ to only accept the values given in the list of the second
+ argument of its definition. It forwards the position of \val\ in that list to
+ \meta{key_2} (zero-based). The \meta{key_2} has to already be defined by the
+ time an |enum| key is set up. Each \val\ in the list (and at use time) is
+ |\detokenize|d, so no expansion takes place here.
+
+ If you use |enum| twice on the same \key\ the new values will again start at
+ zero (so it is possible to define multiple values with the same outcome),
+ however since you can't skip values you'll have to use the same as in the
+ first call for values with just a single variant. There is no interface to
+ delete existing values.
+\end{function}
+\begin{example}{Enumerating choices with the \texttt{enum} \type}
+ First a small example that might give you an idea of what the description
+ above could mean:
+ \begin{enverb}
+ \ekvcSplit\foo{k-internal=-1}{#1}
+ \ekvcSecondaryKeys\foo
+ {enum k = {k-internal}{a,b,c}}
+ \foo{}\foo{k=a}\foo{k=b}\foo{k=c}
+ \end{enverb}
+\end{example}
+\begin{example}{A slightly more complicated usage of the \texttt{enum} \type}
+ We can define a choice setup that might do different things based on the
+ choice encountered, and the numeric value is easy to parse using
+ \cs[no-index]{ifcase}:
+ \begin{enverb}
+ \ekvcSplit\foo{k-internal=-1}
+ {%
+ \ifcase#1
+ is\or
+ This\or
+ easy%
+ \else
+ .%
+ \fi
+ }
+ \ekvcSecondaryKeys\foo
+ {enum k = {k-internal}{a,b,c}}
+ \foo{k=b} \foo{k=a} \foo{k=c}\foo{}
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-cs type]{choice}
+ \begin{syntax}
+ choice \key\ = \marg{key_2}\kvarg \prefixes2
+ \end{syntax}
+ This is pretty similar to an |enum|, but unlike with |enum| the forwarded
+ \val\ will not be numeric, instead the \val\ as given during the definition
+ time will be forwarded. This means that while the user input has to match in a
+ |\detokenize|d form, the \val\ might still expand further during your macro's
+ expansion (if what you provided as a choice is expandable).
+\end{function}
+\begin{example}{Filtering possible values with the \texttt{choice} \type}
+ We could use this to filter out the possible vertical placements of a \LaTeXe\
+ |tabular|:
+ \begin{enverb}
+ \ekvcSplit\foo{v-internal=c,a=t,b=c,c=b}
+ {%
+ \begin{tabular}[#1]{@{} c @{:} c @{}}
+ a & #2\\
+ b & #3\\
+ c & #4\\
+ \end{tabular}%
+ }
+ \ekvcSecondaryKeys\foo
+ {choice v = {v-internal}{t,c,b}}
+ \foo{} \foo{v=t} \foo{v=c} \foo{v=b}
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-cs type]{aggregate,e-aggregate}
+ \begin{syntax}
+ aggregate \key\ = \marg{primary}\marg{definition} \prefixes3
+ \end{syntax}
+ While other key \types\ replace the current value of the associated
+ primary key, with |aggregate| you can create keys that append or prepend (or
+ whatever you like) the new value to the current one. Your definition of an
+ |aggregate| key must be exactly two \TeX\ arguments, where \meta{primary}
+ should be the name of a primary key, and \meta{definition} the way you want to
+ store the current and the new value. Inside \meta{definition} you can use |#1|
+ for the current, and |#2| for the new value. The \meta{definition} will not
+ expand any further during the entire parsing for |aggregate|, whereas in
+ |e-aggregate| everything that ends up in \meta{definition} (so whatever you
+ provide including the values in |#1| and |#2|) will be fully expanded (using
+ the |\expanded| primitive), so use |\noexpand| and |\unexpanded| to protect
+ what shouldn't be expanded.
+ The resulting \meta{key} will inherit being either |short| or |long| from the
+ \meta{primary} key.
+\end{function}
+\begin{example}{Building a list with the \texttt{aggregate} \type}
+ The following defines an internal key (|k-internal|), which is used to build a
+ comma separated list from each call of the user facing key (|k|):
+ \begin{enverb}
+ \ekvcSplit\foo
+ {k-internal=0,color=red}
+ {\textcolor{#2}{#1}}
+ \ekvcSecondaryKeys\foo
+ {aggregate k = {k-internal}{#1,#2}}
+ \foo{}\par
+ \foo{k=1,k=2,k=3,k=4}
+ \end{enverb}
+\end{example}
+\begin{example}{Building a convoluted list with the \texttt{aggregate} \type}
+ But also more strange stuff could end there, like macros or using the same
+ value multiple times:
+ \begin{enverb}[no-tcb]
+ \ekvcSecondaryKeys\foo
+ {aggregate k = {k-internal}{\old{#1}\new{#2\old{#1}}}}
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-cs type]{flag-bool}
+ \begin{syntax}
+ flag-bool \key\ = \meta{cs} \prefixes3
+ \end{syntax}
+ This is a secondary \type\ that doesn't involve any of the primary or other
+ secondary keys. This defines \key\ to take a value, which should be either
+ |true| or |false|, and set the flag called \meta{cs} accordingly as a boolean.
+ If \meta{cs} isn't defined yet it will be initialised as a flag. Note that the
+ flag will not be set to a specific state automatically so a flag set in one
+ macro might affect every other macro in the current scope. Please also read
+ \autoref{sec:c:flags}.
+\end{function}
+\begin{example}{Using a Boolean flag with the \texttt{flag-bool} \type}
+ Provide a key |bold| to turn the output of our macro bold if the associated
+ flag is |true|.
+ \begin{enverb}
+ \ekvcSplit\foo{a=a,b=b}
+ {%
+ \ekvcFlagIf\fooFlag
+ {\textbf{a is #1 and b is #2}\par}
+ {a is #1 and b is #2\par}%
+ }
+ \ekvcSecondaryKeys\foo{flag-bool bold = \fooFlag}
+ \foo{}\foo{bold=true}\foo{}\foo{bold=false}\foo{}
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-cs type]{flag-true,flag-false}
+ \begin{syntax}
+ flag-true \key\ = \meta{cs} \prefixes3
+ \end{syntax}
+ This is similar to |flag-bool|, but the \meta{key} will be a \Nkey\ and if
+ used will set the flag to either |true| or |false|. If \meta{cs} isn't defined
+ yet it will be initialised as a flag. Note that the flag will not be set to a
+ specific state automatically. Please also read \autoref{sec:c:flags}.
+\end{function}
+
+\begin{function}[module=expkv-cs type]{flag-raise}
+ \begin{syntax}
+ flag-raise \key\ = \meta{cs} \prefixes3
+ \end{syntax}
+ This defines \key\ to be a \Nkey\ that will raise the flag called \meta{cs} on
+ usage. If \meta{cs} isn't defined yet it will be initialised as a flag. Note
+ that the flag will not be set to a specific state automatically. Please also
+ read \autoref{sec:c:flags}.
+\end{function}
+
+
+\subsection{Changing the Initial Values\label{sec:c:change}}
+
+\begin{function}{\ekvcChange}
+ \begin{syntax}
+ \cs{ekvcChange}\meta{cs}\kvarg
+ \end{syntax}
+ This processes the \kv\ list for the macro \meta{cs} to set new defaults for
+ it (meaning the initial values used if you don't provide anything at use time,
+ not those specified with the |default| \type). \meta{cs} should be defined
+ with \expkvc\ (but it doesn't matter if it's a split or hash variant). Inside
+ the \kv\ list both primary and secondary keys can be used. If \meta{cs} was
+ defined |\long| earlier it will still be |\long|, every other \TeX\ prefix
+ will be stripped (but \expkvc\ doesn't support them anywhere else so that
+ should be fine). The resulting new defaults will be stored inside the
+ \meta{cs} locally (just as the original initial values were). If there was an
+ unknown key forwarding added to \meta{cs} (see \autoref{sec:c:unknown}) any
+ unknown key will be stored inside the list of unknown keys as well.
+ \cs{ekvcChange} is not expandable!
+\end{function}
+\begin{example}
+ {Changing the values for future calls using \cs[no-index]{ekvcChange}}
+ With \cs{ekvcChange} we can now do the following:
+ \begin{enverb}
+ \ekvcSplit\foo{a=a,b=b}{a is #1.\par b is #2.\par}
+ \begingroup
+ \ekvcChange\foo{b=B}
+ \foo{}
+ \ekvcSecondaryKeys\foo{meta c={a={#1},b={#1}}}
+ \ekvcChange\foo{c=c}
+ \foo{}
+ \endgroup
+ \foo{}
+ \end{enverb}
+\end{example}
+\begin{example}{A typical setup macro for \expkvc\ macros}
+ As a result with this the typical setup macro could be implemented:
+ \begin{enverb}[no-tcb]
+ \ekvcHashAndUse\fooKV{keyA=a,keyB=b}
+ \def\fooA#1{\fooKV{#1}\fooAinternal}
+ \def\fooB#1{\fooKV{#1}\fooBinternal}
+ \protected\def\foosetup{\ekvcChange\fooKV}
+ \end{enverb}
+ Of course the usage is limited to a single macro |\fooKV|, hence this might
+ not be as powerful as similar macros used with other \kv\ interfaces. But at
+ least a few similar macros could be grouped using the same key parsing macro
+ internally like |\fooA| and |\fooB| do in this example.
+\end{example}
+
+
+\subsection{Handling Unknown Keys\label{sec:c:unknown}}
+
+If your macro should handle unknown keys without directly throwing an error you
+can use the special |...| marker in the \meta{primary keys} list. Since those
+keys will be processed once by \expkv\ they will be forwarded normalised: The
+\key\ and the \val\ will be forwarded with one set of surrounding spaces and
+braces, so a \kv\ pair will result in \texttt{\vissp{ \marg{key} = \marg{val} }}
+and a \Nkey\ is forwarded as \texttt{\vissp{ \marg{key} }} (this way most other
+\kv\ implementations should parse the correct input).
+
+The exact behaviour differs slightly between the two variants (as all primary
+keys do). The behaviour inside the split variants will be similar to normal
+primary keys, the $n$-th argument (corresponding to the position of |...| inside
+the primary keys list) will contain any unknown key encountered while parsing
+the argument. And inside the split variant you can use a primary key named |...|
+at the same time (since only the position in the list determines the argument,
+not the name).
+\begin{example}{Using unknown key handlers to wrap another \kv\ enabled macro}
+ The following will forward any unknown key to |\includegraphics| to control
+ the appearance while processing its own keys:
+ \begin{enverb}[same-line=0.6]
+ \newcommand*\foo{\ekvoptarg\fooKV{}}
+ \ekvcSplitAndForward\fooKV\fooOUT
+ {
+ a=a
+ ,...
+ ,b=b
+ ,...={}
+ }
+ \newcommand\fooOUT[5]
+ {%
+ a is #1 and b is #3.\par
+ \includegraphics[{#2}]{#5}\par
+ \texttt{...} is #4.\par
+ }
+ \foo[width=.5\linewidth, b=c,
+ ...={a stupid key name, but works}]
+ {example-image-duck}
+ \end{enverb}
+\end{example}
+
+Inside the hash variants the unknown keys list will be put inside the hash named
+|...| (we have to use some name, and this one seems reasonable). As a
+consequence a primary key named |...| would clash with the unknown key handler.
+If you still used such a key it would remove any unknown key stored there until
+that point and replace the list with its value.
+\begin{example}{Wrapping an existing macro, but with a hash variant}
+ The following is more or less equivalent to the above example, but with the
+ hash variant, and it will not contain the primary |...| key. We have to make
+ sure that |\includegraphics| sees the \kv\ list, so need to expand
+ |\ekvcValue{...}{#1}| before |\includegraphics| parses it.
+ \begin{enverb}[same-line=0.76]
+ \newcommand*\foo{\ekvoptarg\fooKV{}}
+ \ekvcHashAndForward\fooKV\fooOUT
+ {a=a, b=b, ...}
+ \newcommand\fooOUT[2]
+ {%
+ a is \ekvcValue{a}{#1} and
+ b is \ekvcValue{b}{#1}.\par
+ \ekvcValueSplit{...}{#1}{\includegraphics[}]%
+ {#2}\par
+ }
+ \foo[width=\linewidth, b=c]
+ {example-image-duck-portrait}
+ \end{enverb}
+\end{example}
+
+
+\subsection{Flags\label{sec:c:flags}}
+
+The idea of flags is taken from \pkg{expl3}. They provide a way to store
+numerical information expandably, however only incrementing and accessing works
+expandably, decrementing is unexpandable. A flag has a height, which is a
+numerical value, and which can be raised by 1. Flags come at a high
+computational cost (accessing them is slow and they require more memory than
+normal \TeX\ data types like registers, both issues getting linearly worse with
+the height), so don't use them if not necessary.
+
+The state of flags is always changed locally to the current group, but not to
+the current macro, so if you're using one of the \types\ involving flags
+bear in mind that they can affect other macros using the same flags at the
+current scope!
+
+\expkvc\ provides some macros to access, alter, and use flags. Flags of \expkvc\
+don't share a name space with the flags of \pkg{expl3}.
+
+\begin{function}{\ekvcFlagNew}
+ \begin{syntax}
+ \cs{ekvcFlagNew}\meta{flag}
+ \end{syntax}
+ This initialises the macro \meta{flag} as a new flag. It isn't checked whether
+ the macro \meta{flag} is currently undefined. A \meta{flag} will expand to the
+ flag's current height with a trailing space (so you can use it directly with
+ \cs[no-index]{ifnum} for example and it will terminate the number scanning on
+ its own).
+
+ All other macros dealing with flags take as a parameter a macro defined as a
+ \meta{flag} with \cs{ekvcFlagNew}.
+\end{function}
+
+\begin{function}{\ekvcFlagHeight}
+ \begin{syntax}
+ \cs{ekvcFlagHeight}\meta{flag}
+ \end{syntax}
+ This expands to the current height of \meta{flag} in a single step of
+ expansion (without a trailing space).
+\end{function}
+
+\begin{function}{\ekvcFlagRaise}
+ \begin{syntax}
+ \cs{ekvcFlagRaise}\meta{flag}
+ \end{syntax}
+ This expandably raises the height of \meta{flag} by 1.
+\end{function}
+
+\begin{function}{\ekvcFlagSetTrue,\ekvcFlagSetFalse}
+ \begin{syntax}
+ \cs{ekvcFlagSetTrue}\meta{flag}
+ \end{syntax}
+ By interpreting an even value as false and an odd value as true we can use a
+ flag as a boolean. This expandably sets \meta{flag} to true or false,
+ respectively, by raising it if necessary.
+\end{function}
+
+\begin{function}{\ekvcFlagIf}
+ \begin{syntax}
+ \cs{ekvcFlagIf}\meta{flag}\marg{true}\marg{false}
+ \end{syntax}
+ This interprets a \meta{flag} as a boolean and expands to either \meta{true}
+ or \meta{false}.
+\end{function}
+
+\begin{function}{\ekvcFlagIfRaised}
+ \begin{syntax}
+ \cs{ekvcFlagIfRaised}\meta{flag}\marg{true}\marg{false}
+ \end{syntax}
+ This tests whether the \meta{flag} is raised, meaning it has a height greater
+ than zero, and if so expands to \meta{true} else to \meta{false}.
+\end{function}
+
+\begin{function}{\ekvcFlagReset,\ekvcFlagResetGlobal}
+ \begin{syntax}
+ \cs{ekvcFlagReset}\meta{flag}
+ \end{syntax}
+ This resets a flag (so restores its height to 0). This operation is \emph{not}
+ expandable and done locally for \cs{ekvcFlagReset} and globally for
+ \cs{ekvcFlagResetGlobal}. If you really intend to use flags you can reset them
+ every now and then to keep the performance hit low.
+\end{function}
+
+\begin{function}{\ekvcFlagGetHeight}
+ \begin{syntax}
+ \cs{ekvcFlagGetHeight}\meta{flag}\marg{next}
+ \end{syntax}
+ This retrieves the current height of the \meta{flag} and provides it as a
+ braced argument to \meta{next}, leaving \meta{next}\marg{height} in the input
+ stream.
+\end{function}
+
+\begin{function}{\ekvcFlagGetHeights}
+ \begin{syntax}
+ \cs{ekvcFlagGetHeights}\marg{flag-list}\marg{next}
+ \end{syntax}
+ This retrieves the current height of each \meta{flag} in the \meta{flag-list}
+ and provides them as a single argument to \meta{next}. Inside that argument
+ each height is enclosed in a set of braces individually. The \meta{flag-list}
+ is just a single argument containing the \meta{flag}s. So a usage like
+ |\ekvcFlagGetHeights{\myflagA\myflagB}{\stuff}| will expand to
+ |\stuff{|\marg{height-A}\marg{height-B}|}|.
+\end{function}
+
+
+\subsection{Further Examples}
+
+\begin{example}{Defining an expandable \kv\ macro with an optional argument}
+ Using \cs[no-index]{NewExpandableDocumentCommand} or \expkv's \cs{ekvoptarg}
+ or \cs{ekvoptargTF} and forwarding arguments one can easily define \kv\ macros
+ with actual optional and mandatory arguments as well. A small nonsense
+ example:
+ \begin{enverb}[below,inter=resulting in]
+ \makeatletter
+ \newcommand*\nonsense{\ekvoptarg\nonsense@a{}}
+ \ekvcHashAndForward\nonsense@a\nonsense@b
+ {
+ keyA = A,
+ keyB = B,
+ keyC = c,
+ keyD = d,
+ }
+ \newcommand*\nonsense@b[2]
+ {%
+ \begin{tabular}{lll|}
+ key & A & \ekvcValue{keyA}{#1} \\
+ & B & \ekvcValue{keyB}{#1} \\
+ & C & \ekvcValue{keyC}{#1} \\
+ & D & \ekvcValue{keyD}{#1} \\
+ \multicolumn{2}{l}{mandatory} & #2 \\
+ \end{tabular}%
+ }
+ \makeatother
+ \nonsense{} % do nonsense
+ \nonsense[keyA=hihi]{haha}
+ \nonsense[keyA=hihi, keyB=A]{hehe}
+ \nonsense[keyC=huhu, keyA=hihi, keyB=A]{haha}
+ \end{enverb}
+\end{example}
+
+\begin{example}{The \cs[no-index]{sine} example revisited}
+ In \autoref{sec:expkv:sneak} I presented an expandable macro to calculate the
+ sine of some user input with a few keys, and there I hinted to \expkvc, so
+ here's the same function implemented with |\ekvcSplitAndForward|. There is a
+ small difference here, we need to use an internal key to store whether degrees
+ or radians will be used, but we don't need to use an internal key to collect
+ the values of our individual keys in the correct order.
+ \begin{enverb}
+ \makeatletter
+ \newcommand\sine{\ekvoptarg\sine@kv{}}
+ \ekvcSplitAndForward\sine@kv\sine@do
+ {
+ f = sin
+ ,internal = d
+ ,round = 3
+ }
+ \ekvcSecondaryKeys\sine@kv
+ {
+ nmeta degree = internal=d
+ ,nmeta radian = internal={}
+ }
+ \newcommand*\sine@do[4]{\fpeval{round(#1#2(#4),#3)}}
+ \makeatother
+ \sine{60}\par
+ \sine[round=10]{60}\par
+ \sine[f=cos,radian]{pi}\par
+ \edef\myval{\sine[f=tan]{1}}\texttt{\meaning\myval}
+ \end{enverb}
+\end{example}
+
+
+\subsection{Freedom for Keys!}
+
+If this had been the \TeX{}book this subsection would have had a double bend
+sign. Not because it is overly complicated, but because it shows things which
+could break \expkvc's expandability and its alignment safety. This is for
+experienced users wanting to get the most flexibility and knowing what they are
+doing.
+
+In case you're wondering, it is possible to define other keys than the primaries
+and the secondary key \types\ listed in \autoref{sec:c:secondary} for a
+macro defined with \expkvc\ by using the low-level interface of \expkv\ or even
+the interface provided by \expkvd. The set name used for \expkvc's keys is the
+macro name, including the leading backslash, or more precisely the result of
+|\string|\meta{cs} is used. This can be exploited to define additional keys with
+arbitrary code. Consider the following \emph{bad} example:
+\begin{enverb}[no-tcb]
+ \ekvcSplit\foo{a=A,b=B}{a is #1.\par b is #2.\par}
+ \protected\ekvdef{\string\foo}{c}{\def\fooC{#1}}
+\end{enverb}
+This would define a key named |c| that will store its \val\ inside a macro. The
+issue with this is that this can't be done expandably. As a result, the macro
+|\foo| isn't always expandable any more (not that bad if this was never
+required; killjoy if it was) and as soon as the key |c| is used it is also no
+longer alignment safe\footnote{This means that the \kv\ list can't contain
+ alignment markers that are not inside an additional set of braces if used
+ inside a \TeX\ alignment}
+(might be bad depending on the usage).
+
+So why do I show you this? Because we could as well do something useful like
+creating a key that pre-parses the input and after that passes the parsed value
+on. This parsing would have to be completely expandable though (and we could
+perhaps also implement this using the |e-aggregate| \type). For the
+pass-on part we can use the following function:
+
+\begin{function}{\ekvcPass}
+ \begin{syntax}
+ \cs{ekvcPass}\meta{cs}\marg{key}\marg{value}
+ \end{syntax}
+ This passes \val\ on to \key\ for the \expkvc-macro \meta{cs}. It should be
+ used inside the key parsing of a macro defined with \expkvc, else this most
+ likely results in a low level \TeX\ error. You can't forward anything to the
+ special unknown key handler |...| as that is no defined key.
+\end{function}
+\begin{example}
+ {Forwarding pre-parsed keys to an \expkvc\ key with \cs[no-index]{ekvcPass}}
+ With this we could for example split the value of a key at a hyphen and pass
+ the parts to different keys:
+ \begin{enverb}
+ \ekvcSplit\foo{a=A,b=B}{a is #1.\par b is #2.\par}
+ \ekvdef{\string\foo}{c}{\fooSplit#1\par}
+ \def\fooSplit#1-#2\par
+ {\ekvcPass\foo{a}{#1}\ekvcPass\foo{b}{#2}}
+ \foo{}
+ \foo{c=1-2}
+ \end{enverb}
+\end{example}
+
+Additionally, there is a more general version of the |aggregate| secondary key
+type, namely the |process| key type:
+
+\begin{function}[module=expkv-cs type]{process}
+ \begin{syntax}
+ process \key\ = \marg{primary}\marg{definition} \prefixes2
+ \end{syntax}
+ This will grab the current value of a \meta{primary} key as |#1| (without
+ changing the current value) and the new value as |#2| and leave all the
+ processing to \meta{definition}. You should use \cs{ekvcPass} to forward the
+ values afterwards. Unlike |aggregate| you can specify whether the \meta{key}
+ should be long or not, this isn't inherited from the \meta{primary} key. Keep
+ in mind that you could easily break things here if your code does not work by
+ expansion.
+\end{function}
+\begin{example}{Filtering out values with the \texttt{process} \type}
+ We could define a key that only accepts values greater than the current value
+ with this:
+ \begin{enverb}
+ \ekvcSplit\foo{internal=5}{a is #1.\par}
+ \ekvcSecondaryKeys\foo
+ {
+ process a={internal}
+ {\ifnum#1<#2 \ekvcPass\foo{internal}{#2}\fi}
+ }
+ \foo{a=1}
+ \foo{a=5}
+ \foo{a=9}
+ \end{enverb}
+\end{example}
+\begin{example}{Filtering out values with the \texttt{e-aggregate} \type}
+ The same is possible with an |e-aggregate| key as well though:
+ \begin{enverb}[no-tcb]
+ \ekvcSplit\foo{internal=5}{a is #1.\par}
+ \ekvcSecondaryKeys\foo
+ {
+ e-aggregate a={internal}
+ {\ifnum#1<#2 \unexpanded{#2}\else\unexpanded{#1}\fi}
+ }
+ \end{enverb}
+\end{example}
+
+\subsection{Useless Macros}
+
+These macros are most likely of little to no interest to users.
+
+\begin{function}{\ekvcDate,\ekvcVersion}
+ These two macros store the version and date of the package/generic code.
+\end{function}
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/pkg-def.tex b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-def.tex
new file mode 100644
index 00000000000..fade98e8b8f
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-def.tex
@@ -0,0 +1,727 @@
+\genericekv\expkvd{-def}
+
+Since the trend for the last couple of years goes to defining keys for a \kv\
+interface using a \kv\ interface, I thought that maybe providing such an
+interface for \expkv\ will make it more attractive for actual use. But at the
+same time I didn't want to broaden \expkv's initial scope. So here is \expkvd,
+go define \kv\ interfaces with \kv\ interfaces.
+
+Unlike many of the other established \kv\ interfaces to define keys, \expkvd\
+works using prefixes instead of suffixes (\emph{e.g.}, |.tl_set:N| of
+\pkg{l3keys}) or directory like handlers (\emph{e.g.}, |/.store in| of
+\pkg{pgfkeys}). This was decided as a personal preference, more over in \TeX\
+parsing for the first spaces is way easier than parsing for the last one, so
+this should also turn out to be faster. \expkvd's prefixes are sorted into two
+categories: \prefixes, which are equivalent to \TeX's prefixes like |\long| and
+of which a \key\ can have multiple, and \types\ defining the basic behaviour of
+the \key\ and of which a \key\ must have one. For a description of the available
+\prefixes\ take a look at \autoref{sec:d:prefixes}, the \types\ are described in
+\autoref{sec:d:types}.
+
+
+\subsection{Macros\label{sec:d:macros}}
+
+The number of user-facing macros is quite manageable:
+
+\begin{function}{\ekvdefinekeys}
+ \begin{syntax}
+ \cs{ekvdefinekeys}\marg{set}\kvarg
+ \end{syntax}
+ In \meta{set}, define \key\ to have definition \val. The general syntax for
+ \key\ should be
+ \begin{quote}
+ \ttfamily
+ \meta{prefix} \meta{name}
+ \end{quote}
+ where \meta{prefix} is a space separated list of optional \prefixes\ followed
+ by one \type. The syntax of \val\ is dependent on the used \type.
+\end{function}
+
+\begin{function}{\ekvdDate,\ekvdVersion}
+ These two macros store the version and date of the package.
+\end{function}
+
+
+\subsection{Prefixes}
+
+As already said, prefixes are separated into two groups, \prefixes\ and \types.
+Not every \prefix\ is allowed for all \types.
+
+
+\subsubsection{\textit{Prefixes}\label{sec:d:prefixes}}
+
+\begin{function}[module=expkv-def prefix]{new}
+ The following \key\ must be new (so previously undefined). An error is thrown
+ if it is already defined and the new definition is ignored. |new| only asserts
+ that there are no conflicts between \Nkey{}s and other \Nkey{}s or \Vkey{}s
+ and other \Vkey{}s.
+\end{function}
+\begin{example}{The effects of the \texttt{new} \prefix}
+ You can test the following (lines throwing an error are marked by a comment,
+ error messages are printed in red for this example):
+ \expkvdocPrintErrors[\par]%
+ \begin{enverb}[below]
+ \ekvdefinekeys{new-example}
+ {
+ new code key = \domystuffwitharg{#1}
+ ,new noval KEY = \domystuffwithoutarg
+ ,new bool key = \mybool % Error!
+ ,new bool KEY = \mybool % Error!
+ ,new meta key = {KEY} % Error!
+ ,new nmeta KEY = {key} % Error!
+ }
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def prefix]{also}
+ The following key \type\ will be \emph{added} to an existing \key's
+ definition. You can't add a \type\ taking an argument at use time to an
+ existing \key\ which doesn't take an argument and vice versa. Also you'll get
+ an error if you try to add an action which isn't allowed to be either |\long|
+ or |\protected| to a \key\ which already is |\long| or |\protected| (the
+ opposite order would be suboptimal as well, but can't be really captured with
+ the current code).
+
+ A \key\ already defined as |\long| or |\protected| will stay that way, but you
+ can add |\long| or |\protected| to a \key\ which isn't by using |also|.
+\end{function}
+\begin{example}
+ {Overload a key \type\ with another with the \texttt{also} \prefix}
+ Suppose you want to create a boolean \key, but additionally to setting a
+ boolean value you want to execute some more code as well. For this you can use
+ the following:
+ \begin{enverb}[no-tcb]
+ \ekvdefinekeys{also-example}
+ {
+ bool key = \ifmybool
+ ,also code key = \domystuff{#1}
+ }
+ \end{enverb}
+\end{example}
+
+If you use |also| on a |choice|, |bool|, |invbool|, or |boolpair| \key\ it is
+tried to determine if the key already is of one of those types. If this test is
+true the declared choices will be added to the possible choices but the key's
+definition will not be changed other than that. If that wouldn't have been done,
+the callbacks of the different choices could get called multiple times.
+
+\begin{function}[module=expkv-def prefix]{protected,protect}
+ The following \key\ will be defined |\protected|. Note that \types\ which
+ can't be defined expandable will always use |\protected|. This only affects
+ the key at use time not the \key\ definition.
+\end{function}
+
+\begin{function}[module=expkv-def prefix]{long}
+ The following \key\ will be defined |\long| (so can take an explicit |\par|
+ token in its \val). Please note that this only changes the \key\ at use time.
+ |long| being present or not doesn't limit you to use |\par| inside of the
+ \key's definition (if the \type\ allows this).
+\end{function}
+
+
+\subsubsection{\textit{Types}\label{sec:d:types}}
+
+Since the \prefixes\ apply to some of the \types\ automatically but sometimes
+one might be disallowed we need some way to highlight this behaviour. In the
+following an enforced \prefix\ will be printed black
+(\texttt{\enfprefix{protected}}), allowed \prefixes\ will be grey
+(\texttt{\allprefix{protected}}), and disallowed \prefixes\ will be red
+(\texttt{\notprefix{protected}}). This will be put flush-right in the syntax
+showing line.
+
+\begin{function}[module=expkv-def type]{code,ecode}
+ \begin{syntax}
+ code \key\ = \marg{definition} \prefixes2222
+ \end{syntax}
+ Define \key\ to be a \Vkey\ expanding to \meta{definition}. You can use |#1|
+ inside \meta{definition} to access the \key's \val. The |ecode| variant will
+ fully expand \meta{definition} inside an |\edef|.
+\end{function}
+\ekvset{enverb}{no-tcb,store}% affect all the next examples.
+\begin{example}
+ {Defining a \Vkey\ with arbitrary effect with the \texttt{code} \type}
+ The following defines the key |foo|, that'll count the number of tokens passed
+ to it (we'll borrow a function from \pkg{expl3} for this). It'll accept
+ explicit |\par| tokens. Also it'll flip the \TeX-if \cs[no-index]{iffoo} to
+ true. The result of the counting will be stored in a count register. (Don't
+ get confused, all the next examples are part of this |\ekvdefinekeys| call, so
+ there is no closing brace here.)
+ \begin{enverb}
+ \ExplSyntaxOn
+ \cs_new_eq:NN \exampleCount \tl_count_tokens:n
+ \ExplSyntaxOff
+ \newcount\examplefoocount
+ \newif\iffoo
+ \ekvdefinekeys{example}
+ {
+ protected long code foo =
+ \footrue
+ \examplefoocount=\exampleCount{#1}\relax
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{noval,enoval}
+ \begin{syntax}
+ noval \key\ = \marg{definition} \prefixes2223
+ \end{syntax}
+ The |noval| \type\ defines \key\ as a \Nkey\ expanding to \meta{definition}.
+ |enoval| fully expands \meta{definition} inside an |\edef|.
+\end{function}
+\begin{example}{An arbitrary \Nkey\ action with the \texttt{noval} \type}
+ The following defines the \Nkey\ |foo| to toggle the \TeX-if
+ \cs[no-index]{iffoo} to false and set |\examplecount| to |0|. It'll be
+ |\protected| and mustn't override any existing key.
+ \begin{enverb}
+ ,new protected noval foo = \foofalse\examplefoocount=0\relax
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{default,odefault,fdefault,edefault}
+ \begin{syntax}
+ default \key\ = \marg{definition} \prefixes2223
+ \end{syntax}
+ This serves to place a default \val\ for a \Vkey. Afterwards if you use \key\
+ as a \Nkey\ it will be the same as if \key\ got passed \meta{definition} as
+ its \val. The |odefault| variant will expand the key-macro once, so will be
+ slightly quicker, but not change if you redefine the \Vkey\ afterwards. The
+ |fdefault| version will expand the key-code until a non-expandable token or a
+ space is found, a space would be gobbled.\footnotemark{}
+ The |edefault| on the other hand fully expands the key-code with
+ \meta{definition} as its argument in |\expanded|. The \prefix\ |new|
+ means that there should be no \Nkey\ of that name yet.
+\end{function}%
+\footnotetext{For those familiar with \TeX-coding: This uses a
+\cs[no-index]{romannumeral}-expansion}
+\begin{example}
+ {Setting a default value for a \Vkey\ with the \texttt{default} \type}
+ We later decide that the above behaviour isn't what we need any more and
+ instead redefine the \Nkey\ |foo| to pass some default value to the \Vkey\
+ |foo|.
+ \begin{enverb}
+ ,default foo = {Some creative default text}
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{initial,oinitial,finitial,einitial}
+ \begin{syntax}
+ initial \key\ = \marg{value} \prefixes3333
+ initial \key
+ \end{syntax}
+ With |initial| you can set an initial \val\ for an already defined \key. It'll
+ just call the \key\ and pass it \val. The |einitial| variant will expand \val\
+ using |\expanded| prior to passing it to the \key\ and the |oinitial|
+ variant will expand the first token in \val\ once. |finitial| will expand
+ \val\ until a non-expandable token or a space is found, a space would be
+ gobbled.\footnotemark
+
+ If you don't provide a \val\ (and no equals sign) the \Nkey\ of the same name
+ is called once (or, if you specified a |default| for a \Vkey\ that would be
+ used).
+\end{function}%
+\footnotetext{Again using \cs[no-index]{romannumeral}}
+\begin{example}{Specifying initial values with the \texttt{initial} \type}
+ We want to get a defined initial behaviour for our |foo|. So we count
+ 0~tokens.
+ \begin{enverb}
+ ,initial foo = {}
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{bool,gbool,boolTF,gboolTF}
+ \begin{syntax}
+ bool \key\ = \meta{cs} \prefixes2223
+ \end{syntax}
+ \singlecs{iffoo}
+ This will define \key\ to be a boolean key, which only takes the values |true|
+ or |false| and will throw an error for other values. If the \key\ is used as
+ a \Nkey\ it'll have the same effect as if you use |true|. |bool| and |gbool|
+ will behave like \TeX-ifs, so either be \cs[no-index]{iftrue} or
+ \cs[no-index]{iffalse}. The \meta{cs} in the |boolTF| and |gboolTF| variants
+ will take two arguments and if true the first will be used else the second, so
+ they are always either |\@firstoftwo| or |\@secondoftwo|. The variants with a
+ leading |g| will set the \meta{cs} globally, the other locally. If \meta{cs}
+ is not yet defined it'll be initialised as the |false| version. Note that the
+ initialisation is \emph{not} done with |\newif|, so you will not be able to do
+ |\footrue| outside of the \kv\ interface, but you could use |\newif| yourself.
+ Even if the \key\ will not be |\protected| the commands which execute the
+ |true| or |false| choice will be, so the usage should be safe in an expansion
+ context (\emph{e.g.}, you can use \texttt{edefault \key\ = false} without an
+ issue to change the default behaviour to execute the |false| choice).
+ Internally a |bool| is the same as a |choice| \type\ which is set up to handle
+ |true| and |false| as choices. |new| will assert that neither the \Vkey\ nor
+ the \Nkey\ are already defined.
+\end{function}
+\begin{example}{Defining Boolean keys with the \texttt{bool} \type}
+ Also we want to have a direct way to set our \cs[no-index]{iffoo}, now that
+ the \Nkey\ doesn't toggle it any longer.
+ \begin{enverb}
+ ,bool dofoo = \iffoo
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{invbool,ginvbool,invboolTF,ginvboolTF}
+ \begin{syntax}
+ invbool \key\ = \meta{cs} \prefixes2223
+ \end{syntax}
+ These are inverse boolean keys, they behave like |bool| and friends but set
+ the opposite meaning to the macro \meta{cs} in each case. So if |key=true| is
+ used |invbool| will set \meta{cs} to \cs[no-index]{iffalse} and vice versa.
+\end{function}
+\begin{example}
+ {Inversing the logic of a Boolean with the \texttt{invbool} \type}
+ And since traditional interfaces lacked \kv\ support for packages, often a
+ negated boolean key was used as well.
+ \begin{enverb}
+ ,invbool nofoo = \iffoo
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{boolpair,gboolpair,boolpairTF,gboolpairTF}
+ \begin{syntax}
+ boolpair \key\ = \meta{cs_1}\meta{cs_2} \prefixes2223
+ \end{syntax}
+ The |boolpair| \type\ behaves like both |bool| and |invbool|, the \meta{cs_1}
+ will be set to the meaning according to the rules of |bool|, and \meta{cs_2}
+ will be set to the opposite.
+\end{function}
+
+\begin{function}[module=expkv-def type]{store,estore,gstore,xstore}
+ \begin{syntax}
+ store \key\ = \meta{cs} \prefixes2212
+ \end{syntax}
+ \singlecs{foo}
+ This will define a \Vkey\ to store \val\ inside of the control sequence. If
+ \meta{cs} isn't yet defined it will be initialised as empty. The variants
+ behave similarly to their |\def|, |\edef|, |\gdef|, and |\xdef| counterparts,
+ but will allow you to store macro parameters inside them without needing to
+ double them. So |estore foo = \foo, initial foo = #1| will not result in a low
+ level \TeX\ error.
+\end{function}
+\begin{example}
+ {Also store the \val\ of an existing \key\ in a macro using the
+ \texttt{also} \prefix\ and the \texttt{store} \type}
+ Not only do we want to count the tokens handed to |foo|, but we want to also
+ store them inside of a macro (and we don't need to specify |long| here, since
+ |foo| is already |\long| from our |code| definition above).
+ \begin{enverb}
+ ,also store foo = \examplefoostore
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{data,edata,gdata,xdata}
+ \begin{syntax}
+ data \key\ = \meta{cs} \prefixes2212
+ \end{syntax}
+ \singlecs{foo}
+ This will define a \Vkey\ to store \val\ inside of the control sequence. But
+ unlike the |store| \type\ the macro \meta{cs} will be a switch at the same
+ time, it'll take two arguments and if \meta{key} was used expands to the first
+ argument followed by \val\ in braces, if \key\ was not used \meta{cs} will
+ expand to the second argument (so behave like |\@secondoftwo|). The idea is
+ that with this type you can define a key which should be typeset formatted.
+ The |edata| and |xdata| variants will fully expand \val, the |gdata| and
+ |xdata| variants will store \val\ inside \meta{cs} globally. Juts like with
+ |store| you can use macro parameters without having to double them. The
+ \prefixes\ only affect the key-macro, \meta{cs} will always be expandable and
+ |\long|.
+\end{function}
+\begin{example}{Define a key using the \texttt{data} \type}
+ Next we start to define other keys, now that our |foo| is pretty much
+ exhausted. The following defines a key |bar| to be a |data| key.
+ \begin{enverb}
+ ,data bar = \examplebar
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{dataT,edataT,gdataT,xdataT}
+ \begin{syntax}
+ dataT \key\ = \meta{cs} \prefixes2212
+ \end{syntax}
+ Just like |data|, but instead of \meta{cs} grabbing two arguments it'll only
+ grab one, so by default it'll behave like |\@gobble|, and if \val\ was given
+ to \key\ the \meta{cs} will behave like |\@firstofone| appended by
+ \marg{value}.
+\end{function}
+\begin{example}{Define a key using the \texttt{dataT} \type}
+ Another key we want to use is |baz|.
+ \begin{enverb}
+ ,dataT baz = \examplebaz
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{int,eint,gint,xint}
+ \begin{syntax}
+ int \key\ = \meta{cs} \prefixes2212
+ \end{syntax}
+ \singlecs{foo}
+ An |int| key will be a \Vkey\ setting a \TeX\ count register. If \meta{cs}
+ isn't defined yet, |\newcount| will be used to initialise it. The |eint| and
+ |xint| variants will use |\numexpr| to allow basic computations in their \val.
+ The |gint| and |xint| variants set the register globally.
+\end{function}
+
+\begin{function}[module=expkv-def type]{dimen,edimen,gdimen,xdimen}
+ \begin{syntax}
+ dimen \key\ = \meta{cs} \prefixes2212
+ \end{syntax}
+ \singlecs{foo}
+ This is just like |int| but uses a dimen register, |\newdimen|, and |\dimexpr|
+ instead.
+\end{function}
+
+\begin{function}[module=expkv-def type]{skip,eskip,gskip,xskip}
+ \begin{syntax}
+ skip \key\ = \meta{cs} \prefixes2212
+ \end{syntax}
+ \singlecs{foo}
+ This is just like |int| but uses a skip register, |\newskip|, and |\glueexpr|
+ instead.
+\end{function}
+\begin{example}
+ {Define keys that use \TeX\ registers, here a skip with the \texttt{eskip}
+ \type}
+ Exemplary for the different register keys, the following defines |distance| so
+ that we can store some distance.
+ \begin{enverb}
+ ,eskip distance = \exampledistance
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{toks,gtoks,apptoks,gapptoks,pretoks,gpretoks}
+ \begin{syntax}
+ toks \key\ = \meta{cs} \prefixes2212
+ \end{syntax}
+ \singlecs{foo}
+ Store \val\ inside of a toks-register. The |g| variants use |\global|, the
+ |app| variants append \val\ to the contents of that register, the |pre|
+ variants will prepend \val. If \meta{cs} is not yet defined it will be
+ initialised with |\newtoks|.
+\end{function}
+
+\begin{function}[module=expkv-def type]{box,gbox}
+ \begin{syntax}
+ box \key\ = \meta{cs} \prefixes2212
+ \end{syntax}
+ \singlecs{foo}
+ Typesets \val\ into a |\hbox| and stores the result in a box register. The
+ boxes are colour safe. \expkvd\ currently doesn't provide a |vbox| type.
+\end{function}
+
+\begin{function}[module=expkv-def type]{meta}
+ \begin{syntax}
+ meta \key\ = \kvarg \prefixes2222
+ \end{syntax}
+ This key \type\ can set other keys, you can access the \val\ given to the
+ created \Vkey\ inside the \kv\ list using |#1|. This works by injecting the
+ \kv\ list into the currently parsed list, so behaves just as if the \kv\ list
+ was directly used instead of \key.
+\end{function}
+\begin{example}
+ {Define a \Vkey\ as a shortcut to set multiple other keys with the
+ \texttt{meta} \type}
+ And we want to set a full set of keys with just this single one called |all|.
+ \begin{enverb}
+ ,meta all =
+ {distance=5pt,baz=cheese cake,bar=cocktail bar,foo={#1}}
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{nmeta}
+ \begin{syntax}
+ nmeta \key\ = \kvarg \prefixes2223
+ \end{syntax}
+ This \type\ sets other keys, but unlike |meta| this defines a \Nkey, so the
+ \kv\ list is static.
+\end{function}
+\begin{example}
+ {Set multiple other keys from a \Nkey\ with the \texttt{nmeta} \type}
+ and if |all| is set without a value we want to do something about it as well.
+ \begin{enverb}
+ ,nmeta all =
+ {distance=10pt,baz=nothing,bar=Waikiki bar,foo}
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{smeta}
+ \begin{syntax}
+ smeta \key\ = \marg{set}\kvarg \prefixes2222
+ \end{syntax}
+ Yet another |meta| variant. |smeta| will define a \Vkey, you can access the
+ given \val\ in the provided \kv\ list using |#1|. Unlike |meta| this will
+ process that \kv\ list inside of \meta{set} using a nested |\ekvset| call, so
+ this is equal to \texttt{\cs[no-index]{ekvset}\marg{set}\kvarg}. As a
+ result you can't use |\ekvsneak| using keys or similar macros in the way you
+ normally could.
+\end{function}
+
+\begin{function}[module=expkv-def type]{snmeta}
+ \begin{syntax}
+ snmeta \key\ = \marg{set}\kvarg \prefixes2223
+ \end{syntax}
+ And the last |meta| variant. |snmeta| combines |smeta| and |nmeta|, so parses
+ the \kv\ list inside of \meta{set} and defines a \Nkey\ with a static list.
+\end{function}
+
+\begin{function}[module=expkv-def type]{set}
+ \begin{syntax}
+ set \key\ = \marg{set} \prefixes2233
+ set \key
+ \end{syntax}
+ This will define a \Nkey\ that will change the current set to \meta{set}. If
+ you give no value to this definition (omit |= |\marg{set}) the set name will
+ be the same as \key\ so
+ |set |\key\
+ is equivalent to
+ |set |\key| = |\marg{key}.
+ Note that just like in \expkv\ it'll not be checked whether \meta{set} is
+ defined and you'll get a low-level \TeX\ error if you use an undefined
+ \meta{set}.
+\end{function}
+
+\begin{function}[module=expkv-def type]{choice}
+ \begin{syntax}
+ choice \key\ = \{\val=\meta{definition}, \ldots\} \prefixes2223
+ \end{syntax}
+ |choice| defines a \Vkey\ that will only accept a limited set of values. You
+ should define each possible \meta{value} inside of the \val=\meta{definition}
+ list. If a defined \meta{value} is passed to \meta{key} the \meta{definition}
+ will be left in the input stream. You can make individual values |protected|
+ inside the \val=\meta{definition} list by using that \prefix. To also allow
+ choices that shouldn't be |\protected| but which start with the word
+ |protected| you can also use |unprotected| as a special \prefix. By default a
+ |choice| key and all its choices are expandable, an undefined \meta{value}
+ will throw an error in an expandable way. You can add additional choices after
+ the \meta{key} was created by using |choice| again for the same \key,
+ redefining choices is possible the same way, but there is no interface to
+ remove certain choices. To change the behaviour of unknown choices see also
+ the |unknown-choice| \type.
+\end{function}
+\begin{example}
+ {Define a choice with arbitrary code using the \texttt{choice} \type}
+ We give the users a few choices.
+ \begin{enverb}
+ ,choice choose =
+ {
+ protected lemonade = \def\exampledrink{something sour}
+ ,protected water = \def\exampledrink{something boring}
+ }
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{choice-store}
+ \begin{syntax}
+ choice-store \key\ = \meta{cs}\{\val=\meta{definition}, \ldots\} \prefixes2223
+ \end{syntax}
+ \singlecs{foo}
+ This is a special \type\ of the |choice| \type\ that'll store the given choice
+ inside the macro \meta{cs}. Since storing inside a macro can't be done
+ expandably every choice-code is |\protected|, and you might define the
+ |choice-store| key itself as |\protected| as well if you want. Inside the
+ \val|=|\meta{definition} list the |=|\meta{definition} part is optional, if
+ you omit it the \val\ will be stored as given during define-time inside of
+ \meta{cs} (during use-time the \val\ needs to be matched |\detokenize|d), and
+ if you specify |=|\meta{definition} that \meta{definition} will be stored
+ inside of \meta{cs} instead. If \meta{cs} doesn't yet exist it's initialised
+ as empty.
+\end{function}
+\begin{example}
+ {Show the equivalent setup for a \texttt{choice} \type\ to mimic a
+ \texttt{choice-store} \type}
+ The following keys |key1| and |key2| are equivalent at use time (this doesn't
+ continue the |\ekvdefinekeys|-call for the set |example| above):
+ \begin{enverb}[no-store,no-tcb]
+ \newcommand*\mya{}% initialise \mya
+ \ekvdefinekeys{choice-store-example}
+ {
+ choice key1 =
+ {
+ protected a = \def\mya{a}
+ ,protected b = \def\mya{b}
+ ,protected c = \def\mya{c}
+ ,protected d = \def\mya{FOO}
+ }
+ ,choice-store key2 = \myb{a,b,c,d=FOO}
+ }
+ \end{enverb}
+\end{example}
+\begin{example}
+ {Store the user's choices in a macro with the \texttt{choice-store} \type}
+ (this continues the |\ekvdefinekeys|-call for the set |example| from above)
+ After the above drinks we define a few more choices which are directly stored.
+ \begin{enverb}
+ ,choice-store choose = \exampledrink{beer,wine}
+ \end{enverb}
+ One might notice that the entire setup of the |choose| key could've been done
+ using only |choice-store|.
+\end{example}
+
+\begin{function}[module=expkv-def type]{choice-enum}
+ \begin{syntax}
+ choice-enum \key\ = \meta{cs}\{\val, \ldots\} \prefixes2223
+ \end{syntax}
+ \singlecs{foo}
+ This is similar to |choice-store|, the differences are: \meta{cs} should be a
+ count register or is initialised as such using |\newcount|; instead of the
+ \val\ itself being stored its position in the list of choices is stored
+ (zero-based). It is not possible to specify a \meta{definition} to store
+ something else than the numerical position inside the list.
+\end{function}
+\begin{example}
+ {Show the equivalent setup for a \texttt{choice} \type\ to mimic a
+ \texttt{choice-enum} \type}
+ The following keys |key1| and |key2| are equivalent at use time (another
+ example not using the |example| set of above's |\ekvdefinekeys|):
+ \begin{enverb}[no-store,no-tcb]
+ \newcount\myc
+ \ekvdefinekeys{choice-enum-example}
+ {
+ choice key1 =
+ {
+ protected a={\myc=0 }
+ ,protected b={\myc=1 }
+ ,protected c={\myc=2 }
+ }
+ ,choice-enum key2 = \myd{a,b,c}
+ }
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{unknown-choice}
+ \begin{syntax}
+ unknown-choice \key\ = \marg{definition} \prefixes2323
+ \end{syntax}
+ By default an unknown \val\ passed to a |choice| or |bool| \type\ (and all
+ their variants) will throw an error. However, with this prefix you can define
+ an alternative action which should be executed if \key\ received an unknown
+ choice. In \meta{definition} you can refer to the given invalid choice with
+ |#1|.
+\end{function}
+\begin{example}
+ {Handle unknown choices without throwing an error with the
+ \texttt{unknown-choice} \type}
+ If a drink was chosen with |choose| that's not defined we don't want to throw
+ an error, but store something else instead.
+ \begin{enverb}
+ ,protected unknown-choice choose =
+ \def\exampledrink{something unavailable}
+ }% closing brace for \ekvdefinekeys
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=expkv-def type]{unknown code}
+ \begin{syntax}
+ unknown code = \marg{definition} \prefixes2322
+ \end{syntax}
+ By default \expkv\ throws errors when it encounters unknown keys in a set.
+ With the |unknown| \type\ you can define handlers that deal with undefined
+ keys, instead of a \key\ name you have to specify a subtype for this, here the
+ subtype is |code|.
+
+ With |unknown code| the \meta{definition} is used for unknown keys which were
+ provided a value (so corresponds to |\ekvdefunknown|), you can access the
+ unknown \key\ name with |#1| (|\detokenize|d), the given \val\ with |#2|, and
+ the unprocessed \key\ name with |#3| (in case you want to further expand
+ it).\footnotemark
+\end{function}%
+\footnotetext{There is some trickery involved to get this more intuitive
+argument order without any performance hit if you compare this to
+\cs[no-index]{ekvdefunknown} directly}
+
+\begin{function}[module=expkv-def type]{unknown noval}
+ \begin{syntax}
+ unknown noval = \marg{definition} \prefixes2323
+ \end{syntax}
+ This is like |unknown code| but uses \meta{definition} for unknown keys to
+ which no value was passed (so corresponds to |\ekvdefunknownNoVal|). You can
+ access the |\detokenize|d \key\ name with |#1| and the unprocessed one with
+ |#2|.
+\end{function}
+
+\begin{function}[module=expkv-def type]{unknown redirect-code}
+ \begin{syntax}
+ unknown redirect-code = \marg{set-list} \prefixes2331
+ \end{syntax}
+ This uses a predefined action for |unknown code|. Instead of throwing an
+ error, it is tried to find the \meta{key} in each \meta{set} in the comma
+ separated \meta{set-list}. The first found match will be used and the
+ remaining options from the list discarded. If the \meta{key} isn't found in
+ any \meta{set} an expandable error will be thrown eventually. Internally
+ \expkv's |\ekvredirectunknown| will be used.
+\end{function}
+
+\begin{function}[module=expkv-def type]{unknown redirect-noval}
+ \begin{syntax}
+ unknown redirect-noval = \marg{set-list} \prefixes2333
+ \end{syntax}
+ This behaves just like |unknown redirect-code| but will set up means to
+ forward keys for |unknown noval|. Internally \expkv's
+ |\ekvredirectunknownNoVal| will be used.
+\end{function}
+
+\begin{function}[module=expkv-def type]{unknown redirect}
+ \begin{syntax}
+ unknown redirect = \marg{set-list} \prefixes2333
+ \end{syntax}
+ This is a short cut to apply both, |unknown redirect-code| and
+ |unknown redirect-noval|, as a result you might get doubled error messages,
+ one from each.
+\end{function}
+
+\bigskip
+Time to use all those keys defined in the different examples!
+% undo the global no-tcb setting
+\ekvset{enverb}{no-store,undo-no-tcb}%
+\begin{enverb}[restore,below,inter=Which results in three paragraphs of text:]
+ \newcommand\defexample[1][]
+ {%
+ \ekvset{example}{#1}%
+ After walking \the\exampledistance\space we finally reached
+ \examplebar{\emph}{no particular place}.
+ There I ordered
+ \iffoo
+ a drink called \examplefoostore\space (that has
+ \the\examplefoocount\space tokens in it)%
+ \else
+ nothing of particular interest%
+ \fi
+ \examplebaz{ and ate \emph}.
+ Then a friend of mine also chose \exampledrink.
+ \par
+ }
+ \defexample[nofoo]
+ \defexample[all,choose=lemonade]
+ \defexample
+ [all=wheat beer,bar=Biergarten,baz=pretzel,choose=champagne]
+\end{enverb}
+
+\subsection{Another Example}
+
+This picks up the standard use case from \autoref{sec:expkv:standard}, but
+defines the keys using |\ekvdefinekeys|.
+
+\begin{enverb}
+ \makeatletter
+ \ekvdefinekeys{myrule}
+ {
+ store ht = \myrule@ht
+ ,initial ht = 1ex
+ ,store wd = \myrule@wd
+ ,initial wd = 0.1em
+ ,store raise = \myrule@raise
+ ,initial raise = \z@
+ ,meta lower = {raise={-#1}}
+ }
+ \ekvsetdef\myruleset{myrule}
+ \newcommand*\myrule[1][]
+ {%
+ \begingroup
+ \myruleset{#1}%
+ \rule[\myrule@raise]{\myrule@wd}{\myrule@ht}%
+ \endgroup
+ }
+ \makeatother
+ a\myrule\par
+ a\myrule[ht=2ex,lower=.5ex]\par
+ \myruleset{wd=5pt}
+ a\myrule
+\end{enverb}
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/pkg-main.tex b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-main.tex
new file mode 100644
index 00000000000..0109eb70dae
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-main.tex
@@ -0,0 +1,1097 @@
+\genericekv\expkv{}
+
+This package supports two different front ends to parse a \kv\ list. The first
+(|\ekvset|) is similar to \pkg{keyval}'s |\setkeys|, it parses the list and
+executes defined actions based on the encountered \key{}s. The second
+(|\ekvparse|) is more versatile, it only splits the list into \key{}s and
+\val{}s and then runs user-provided code on the result.
+
+The first is described in subsections~\ref{sec:expkv:setup}
+to~\ref{sec:expkv:set}, the latter is described in \autoref{sec:expkv:parse}.
+
+Unlike the other packages in the bundle, if you load \expkv\ as a \LaTeXe\
+package there is a single option available:
+\begin{function}{all}
+ \begin{syntax}
+ \cs[no-index]{usepackage}[all]\{expkv\}
+ \end{syntax}
+ Loads all the packages of \expkvbundle.
+\end{function}
+
+\subsection{General Parsing Rules}
+
+\expkv\ parses a \kv\ list by first splitting the elements on commas (active or
+other), then looking for an equals sign (active or other). If there is one the
+\kv\ pair will be split at the first. From both \key\ and \val\ (if there was a
+\val) one set of outer spaces is stripped, and afterwards one set of outer
+braces (meaning braces which are around the complete remainder after space
+stripping if there are any).
+
+So the syntax looks something like the following pseudo-input:
+\begin{syntaxexample}
+ \vissp{ \marg{key} = \marg{value} }
+\end{syntaxexample}
+with the displayed spaces and braces being optional and removed if found. Note
+that if you want either \key\ or \val\ to include a comma the braces become
+mandatory, the same is true if \key\ should contain an equals sign.
+
+\subsubsection{Expansion Control\label{sec:expkv:expansion}}
+
+\expkv\ provides a mechanism to specify expansions of a \key\ and/or \val. For
+those familiar with \pkg{pgfkeys} this is similar to its |.expand once| or
+|.expanded| handlers. This concept will be called \expnotation\ or \expansion\
+throughout this documentation.
+
+The syntax for this notation is a leading list of \expansion-rules followed by a
+colon that is immediately followed by a space. Also the \expansion-rules must
+not contain any spaces outside of braces, and the remainder on the right hand
+side of the colon must not be blank, else it is not considered an \expnotation\
+but just a weirdly formed \key-name.
+
+The entire syntax of a \kv\ pair is
+\begin{syntaxexample}
+ \vissp{ \{\expansion: \asciispace\marg{key} \} = \marg{value} }
+\end{syntaxexample}
+Note that the \expansion\ prefix is right delimited by \verb*|: | so the space
+after the colon is only optional in the sense that the entire \expansion\ prefix
+is optional. Else all displayed spaces and braces are optional, the inner set of
+spaces and braces around \key\ only being optional if the optional \expansion\
+prefix (\expansion\verb*|: |) was present. If that part was present the list of
+\expansion-rules will be executed, which might change the contents of both \key\
+and \val. For |\ekvparse| this is always true, however in |\ekvset| it is only
+parsed for the \expnotation\ if there is no \key\ matching the given input (so
+this notation doesn't impose a restriction on key names, though \key-names
+actually containing what would otherwise be an \expansion\ prefix should be
+pretty rare in practice).
+
+All packages in \expkvbundle\ support this notation (most of them internally use
+|\ekvset| or |\ekvparse|). Please note however that while \expkvo\ fully
+supports them, reinsertion via the |\r| \expansion-rule might affect the unused
+global options list if used in the class options.
+
+An \expansion-rule consists of a single token. In a \Vkey\ they work on the
+\val\ (but you can use the |\key| rule to also affect the \key\ there) while in
+a \Nkey\ they work on the \key. The following rules are available (those
+familiar with \pkg{expl3} will notice that the first six are identical to its
+argument types):
+
+\begingroup
+\let\bigskip\medskip
+\begin{function}[module=Expansion]{o}
+ Expands the first token once.
+\end{function}
+
+\begin{function}[module=Expansion]{e}
+ Expands the entire \val\ inside of |\expanded|.
+\end{function}
+
+\begin{function}[module=Expansion]{c}
+ Builds a |\csname| from the contents.
+\end{function}
+
+\begin{function}[module=Expansion]{f}
+ Expands the contents until a space or an unexpandable token is found (the
+ space would be removed).
+\end{function}
+
+\begin{function}[module=Expansion]{V}
+ The \val\ should be a single token, either defined as a parameterless macro or
+ as a register (via |\newcount| etc.). This expands to the value of the
+ register or the macro's replacement text. If the token in \val\ has the
+ |\meaning| of |\relax| an error is thrown and the result is empty.
+\end{function}
+
+\begin{function}[module=Expansion]{v}
+ This is a combination of |c| and |V|, meaning the \val\ is turned into a
+ single control sequence via |\csname|, and then expanded to its value. The
+ control sequence will only be built if it's defined.
+\end{function}
+\begin{example}{The difference between \texttt{co} and \texttt{v} expansion}
+ Say we want to hand the contents of a macro as the value to our key, but the
+ actual macro name depends on user input. For this we have two options which
+ behave slightly different. One is to use |v| the other is to combine the |co|
+ \expansion-rules. The following demonstrates both (I modified the way errors
+ are thrown to instead output them in red for this; you'll learn about
+ |\ekvparse| in a few pages, for now just stick with me):
+ \expkvdocPrintErrors
+ \makeatletter
+ \begin{enverb}[below]
+ \newcommand\mypair[2]{Arg: `\detokenize{#2}'. }%
+ \newcommand\myvalue{Value}%
+ \ekvparse\@firstofone\mypair
+ {
+ co: key = myvalue, v: key = myvalue, \par
+ ,co: key = myValue, v: key = myValue, \par
+ }
+ \end{enverb}
+ The difference is that in |co| the variable is implicitly initialised as
+ |\relax| by |c| if it doesn't exist and then doesn't expand in |o|. On the
+ other hand |v| will check whether the variable would exist and throw an error
+ if it doesn't (and will not set it to |\relax| by blindly using |\csname|).
+\end{example}
+
+\begin{function}[module=Expansion]{s}
+ Strips one set of outer spaces and outer braces.
+\end{function}
+
+\begin{function}[module=Expansion]{b}
+ Adds one set of outer braces.
+\end{function}
+
+\begin{function}[module=Expansion]{p}
+ \begin{syntax}
+ p\marg{contents}
+ \end{syntax}
+ Places \meta{contents} before the \val.
+\end{function}
+
+\begin{function}[module=Expansion]{P}
+ \begin{syntax}
+ P\marg{contents}
+ \end{syntax}
+ Places \meta{contents} after the \val.
+\end{function}
+
+\begin{function}[module=Expansion]{g}
+ Gobbles the first token or balanced group on the left (leads to a low-level
+ \TeX-error if the \val\ is empty).
+\end{function}
+
+\begin{function}[module=Expansion]{\r}
+ In a \Vkey\ reinserts the contents of \val\ after all the \expansion-rules
+ were executed (the \key-name needs to be empty). In a \Nkey\ the contents of
+ \key\ are reinserted after all the \expansion-rules were executed (the \val\
+ needs to be empty, which is an easy to fulfil rule as there was no \val).
+ Normal \kv\ parsing is aborted afterwards for the current \kv\ list element.
+\end{function}
+\begin{example}{Parse the contents of a macro as additional \kv\ input}
+ Say we want to store a list of common settings in a macro, then we want to
+ parse a few keys, insert the contents of the macro, and parse a few more keys.
+ The following does exactly that (|\ekvset| is analogue to |\setkeys| of the
+ \pkg{keyval} package if you're familiar with it, else you'll learn about
+ |\ekvset| a few pages down the road so be patient):
+ \begin{enverb}[no-tcb]
+ \newcommand*\mykeylist{color=red,height=5cm}
+ \ekvset{mypkg}{key=value, o\r: \mykeylist, other key=other value}
+ \end{enverb}
+ You could also use the following with the same outcome, but this looks more
+ complicated so the other form should be preferred:
+ \begin{enverb}[no-tcb]
+ \ekvset{mypkg}{key=value, o\r: {}=\mykeylist, other key=other value}
+ \end{enverb}
+\end{example}
+
+\begin{function}[module=Expansion]{\key}
+ \begin{syntax}
+ \cs[module=Expansion]{key}\marg{expansion}
+ \end{syntax}
+ This is the only supported way to change the contents of \key\ for a \Vkey\ in
+ the \expnotation. All the rules in \expansion\ are applied to \key\ instead of
+ \val.
+\end{function}
+
+\begin{function}[module=Expansion]{R}
+ This is the same as if you used |V\r|. So it expects a single token, retrieves
+ its value, and reinserts this as additional \kv\ input.
+\end{function}
+
+\begin{function}[module=Expansion]{r}
+ This is the same as if you used |v\r|. So it builds a |\csname| if that is
+ defined, retrieves its value, and reinserts this as additional \kv\ input.
+\end{function}
+\begin{example}
+ {Parse the contents of a macro as additional \kv\ input (revisited)}
+ Now that we also know the |R| and |r| rule, the example above can be input
+ even simpler:
+ \begin{enverb}[no-tcb]
+ \ekvset{mypkg}{key=value, R: \mykeylist, other key=other value}
+ \end{enverb}
+ or
+ \begin{enverb}[no-tcb]
+ \ekvset{mypkg}{key=value, r: mykeylist, other key=other value}
+ \end{enverb}
+\end{example}
+\endgroup
+
+\subsection{Setting up Keys\label{sec:expkv:setup}}
+
+\expkv\ provides a rather simple approach to setting up keys, similar to
+\pkg{keyval}. If you're looking for a more sophisticated interface similar to
+those of \pkg{l3keys} or \pkg{pgfkeys} take a look at \expkvd\ described in
+\autoref{sec:expkv-def} or for a simple interface that defines expandable macros
+at \expkvc\ described in \autoref{sec:expkv-cs}.
+
+Keys in \expkv\ (as in many other \kv\ implementations) belong to a \emph{set},
+so that different sets can contain keys of the same name. Unlike many other
+implementations \expkv\ doesn't provide means to set a default value, instead we
+have keys that take a value (we call those \Vkey) and keys that don't (which are
+called \Nkey\ by \expkv), but both can share the same name on the user level,
+the only difference for the user is whether =\val\ was used or not.
+
+The following macros are available to define new keys. Those macros containing
+\enquote{\texttt{def}} in their name can be prefixed by anything allowed to
+prefix |\def| (but \emph{don't} use |\outer|, keys defined with it won't ever be
+usable). And prefixes allowed for |\let| can prefix those macros with
+\enquote{\texttt{let}} in their name, accordingly. Neither \set\ nor \key\ are
+allowed to be empty for new keys. \set\ will be used as is inside of
+|\csname ...\endcsname| and \key\ will get |\detokenize|d. Also \set\ should not
+contain an explicit |\par| token.
+
+\begin{function}{\ekvdef}
+ \begin{syntax}
+ \cs{ekvdef}\marg{set}\marg{key}\marg{code}
+ \end{syntax}
+ Defines a \Vkey\ in a \set\ to expand to \meta{code}. In \meta{code} you can
+ use |#1| to refer to the given \val.
+\end{function}
+\begin{example}{Define a single \Vkey}
+ Define |text| in |foo| to store the \val\ inside |\foo@text|:
+ \begin{enverb}[no-tcb]
+ \protected\long\ekvdef{foo}{text}{\def\foo@text{#1}}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvdefNoVal}
+ \begin{syntax}
+ \cs{ekvdefNoVal}\marg{set}\marg{key}\marg{code}
+ \end{syntax}
+ Defines a \Nkey\ in \set\ to expand to \meta{code}.
+\end{function}
+\begin{example}{Define a single \Nkey}
+ Define |bool| in |foo| to set |\iffoo@bool| to |true|:
+ \begin{enverb}[no-tcb]
+ \protected\ekvdefNoVal{foo}{bool}{\foo@booltrue}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvlet}
+ \begin{syntax}
+ \cs{ekvlet}\marg{set}\marg{key}\meta{cs}
+ \end{syntax}
+ Let the \Vkey\ in \set\ to \meta{cs}. There are no checks on \meta{cs}
+ enforced, but the code should expect the \val\ as a single braced argument
+ directly following it.
+\end{function}
+\begin{example}{Copy a macro to define a \Vkey}
+ Let |cmd| in |foo| do the same as |\foo@cmd|:
+ \begin{enverb}[no-tcb]
+ \ekvlet{foo}{cmd}\foo@cmd
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvletNoVal}
+ \begin{syntax}
+ \cs{ekvletNoVal} \marg{set} \marg{key} \meta{cs}
+ \end{syntax}
+ Let the \Nkey\ in \set\ to \meta{cs}. Again no checks on \meta{cs} are done.
+ It shouldn't expect any provided argument.
+\end{function}
+\begin{example}{Copy a macro to define a \Nkey}
+ See above.
+\end{example}
+
+\begin{function}{\ekvletkv}
+ \begin{syntax}
+ \cs{ekvletkv}\marg{set}\marg{key}\marg{set2}\marg{key2}
+ \end{syntax}
+ Copies the definition such that \Vkey\ in \set\ behaves like \meta{key2} of
+ \meta{set2}. It is not checked whether that second key exists!
+\end{function}
+\begin{example}{Copy an existing \Vkey}
+ Let |B| in |bar| do the same as |A| in |foo|:
+ \begin{enverb}[no-tcb]
+ \ekvletkv{bar}{B}{foo}{A}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvletkvNoVal}
+ \begin{syntax}
+ \cs{ekvletkvNoVal}\marg{set}\marg{key}\marg{set2}\marg{key2}
+ \end{syntax}
+ And this lets the \Nkey\ in \set\ to the definition of the |NoVal|-\meta{key2}
+ in \meta{set2}. Again, it is not checked whether the second key exists.
+\end{function}
+\begin{example}{Copy an existing \Nkey}
+ See above.
+\end{example}
+
+\subsection{Handle Unknown Keys}
+
+By default \expkv\ throws an error message if it encounters an undefined \key.
+You can change this behaviour with the macros listed here. Just like in the
+section above, prefixes for |\def| are allowed if the macro has |def| in its
+name, and |\let| prefixes are allowed if the macro is named something with
+|let|.
+
+\begin{function}{\ekvdefunknown}
+ \begin{syntax}
+ \cs{ekvdefunknown}\marg{set}\marg{code}
+ \end{syntax}
+ Execute \meta{code} if an undefined \Vkey\ is encountered while parsing in
+ \set. You can refer to the given \val\ with |#1|, the unknown \key's name
+ with |#2| (will be |\detokenize|d), and to the \key's name without
+ |\detokenize| applied with |#3| in \meta{code} (this order is chosen for
+ performance reasons).
+
+ \cs{ekvdefunknown} and \cs{ekvredirectunknown} are mutually exclusive, you
+ can't use both.
+\end{function}
+\begin{example}{Search undefined \Vkey{}s in another \set}
+ Also search |bar| for undefined keys of set |foo| (and use the not yet
+ |\detokenize|d \key's name in case the undefined key handler of |bar| needs
+ that):
+ \begin{enverb}[no-tcb]
+ \long\ekvdefunknown{foo}{\ekvset{bar}{{#3}={#1}}}
+ \end{enverb}
+ This example differs from using |\ekvredirectunknown{foo}{bar}| (see below) in
+ that also the unknown-key handler of the |bar| set will be triggered, error
+ messages for undefined keys will look different, and this is slower than using
+ \cs{ekvredirectunknown}.
+\end{example}
+
+\begin{function}{\ekvdefunknownNoVal}
+ \begin{syntax}
+ \cs{ekvdefunknownNoVal}\marg{set}\marg{code}
+ \end{syntax}
+ With this you can let \expkv\ execute \meta{code} if an unknown \Nkey\ was
+ encountered. You can refer to the given \key\ with |#1| (will be
+ |\detokenize|d), and to the not |\detokenize|d \key's name with |#2|.
+
+ \cs{ekvdefunknownNoVal} and \cs{ekvredirectunknownNoVal}
+ are mutually exclusive, you can't use both.
+\end{function}
+\begin{example}{Search undefined \Nkey{}s in another \set}
+ Adding to the above also handling of \Nkey{}s in |foo|:
+ \begin{enverb}[no-tcb]
+ \ekvdefunknownNoVal{foo}{\ekvset{bar}{{#2}}}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvredirectunknown}
+ \begin{syntax}
+ \cs{ekvredirectunknown}\marg{set}\marg{set-list}
+ \end{syntax}
+ This is a short cut to set up a special \cs{ekvdefunknown}-rule for \set\ that
+ will check each set in the comma separated \meta{set-list} for an unknown
+ \Vkey. The resulting unknown-key handler will always be |\long| and \emph{not}
+ |\protected|. The first set in \meta{set-list} has highest priority, once the
+ \Vkey\ is found in one of the sets the remainder of the list is discarded. If
+ \meta{key} isn't found in any of the sets an error will be thrown eventually.
+ Note that the error message looks different than a normal key-not-found error,
+ in particular no unwanted-value message can be thrown (it will not be checked
+ if a \Nkey\ of the same name does exist), and the error message will contain
+ all sets.
+
+ \cs{ekvdefunknown} and \cs{ekvredirectunknown}
+ are mutually exclusive, you can't use both.
+\end{function}
+\begin{example}{Search an undefined \Vkey\ in a list of other \set{}s}
+ For every undefined \Vkey\ in |foo| also search the sets |bar| and |baz|:
+ \begin{enverb}[no-tcb]
+ \ekvredirectunknown{foo}{bar, baz}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvredirectunknownNoVal}
+ \begin{syntax}
+ \cs{ekvredirectunknownNoVal}\marg{set}\marg{set-list}
+ \end{syntax}
+ This behaves just like \cs{ekvredirectunknown}, it does the same but for
+ \Nkey{}s. Again no prefixes are supported (the result will neither be |\long|
+ nor |\protected|). Note that the error messages will not check whether a
+ missing-value error should be thrown.
+
+ \cs{ekvdefunknownNoVal} and \cs{ekvredirectunknownNoVal}
+ are mutually exclusive, you can't use both.
+\end{function}
+\begin{example}{Search an undefined \Nkey\ in a list of other \set{}s}
+ See above.
+\end{example}
+
+\begin{function}{\ekvletunknown}
+ \begin{syntax}
+ \cs{ekvletunknown}\marg{set}\meta{cs}
+ \end{syntax}
+ This lets the handler for unknown \Vkey{}s to \meta{cs}. \meta{cs} should
+ expect three arguments, the first will be the \val\ the second the
+ |\detokenize|d \key-name, the third the unprocessed \key-name. No conditions
+ on \meta{cs} are enforced.
+\end{function}
+\begin{example}
+ {Do the same as an already defined macro if an unknown \Vkey\ is found}
+ Let the set |foo| do the same as the macro |\foo@unknown| whenever an unknown
+ \Vkey\ is encountered:
+ \begin{enverb}[no-tcb]
+ \ekvletunknown{foo}\foo@unknown
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvletunknownNoVal}
+ \begin{syntax}
+ \cs{ekvletunknownNoVal}\marg{set}\meta{cs}
+ \end{syntax}
+ This does the same as \cs{ekvletunknown} but for \Nkey{}s. The \meta{cs}
+ should expect two arguments, namely the |\detokenize|d \key\ and the
+ unprocessed \key.
+\end{function}
+\begin{example}{Silently ignore unknown \Nkey{}s}
+ Let the set |foo| ignore unknown \Nkey{}s by gobbling the \key-name:
+ \begin{enverb}[no-tcb]
+ \ekvletunknownNoVal{foo}\@gobbletwo
+ \end{enverb}
+\end{example}
+
+\subsection{Helpers in Actions}
+
+\begin{function}{\ekvifdefined,\ekvifdefinedNoVal}
+ \begin{syntax}
+ \cs{ekvifdefined}\marg{set}\marg{key}\marg{true}\marg{false}
+ \cs{ekvifdefinedNoVal}\marg{set}\marg{key}\marg{true}\marg{false}
+ \end{syntax}
+ These two macros test whether there is a \key\ in \set. It is false if either
+ a hash table entry doesn't exist for that key or its meaning is |\relax|.
+\end{function}
+\begin{example}{Check if a \Vkey\ is already defined}
+ Check whether the key |special| is already defined in set |foo|, if it isn't
+ input a file that contains more key definitions:
+ \begin{enverb}[no-tcb]
+ \ekvifdefined{foo}{special}{}{\input{foo.morekeys.tex}}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvifdefinedset}
+ \begin{syntax}
+ \cs{ekvifdefinedset}\marg{set}\marg{true}\marg{false}
+ \end{syntax}
+ This macro tests whether \set\ is defined (which it is if at least one key was
+ defined for it). If it is \meta{true} will be run, else \meta{false}.
+\end{function}
+\begin{example}{Check if a \set\ is already defined}
+ Check whether the set |VeRyUnLiKeLy| is already defined, if so throw an error,
+ else do nothing:
+ \begin{enverb}[no-tcb]
+ \ekvifdefinedset{VeRyUnLiKeLy}
+ {\errmessage{VeRyUnLiKeLy already defined}}{}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvsneak,\ekvsneakPre}
+ \begin{syntax}
+ \cs{ekvsneak}\marg{after}
+ \end{syntax}
+ Puts \meta{after} after the effects of \cs{ekvset} (without cancelling the
+ current \cs{ekvset} call). The first variant will put \meta{after} after any
+ other tokens which might have been sneaked before, while \cs{ekvsneakPre} will
+ put \meta{after} before other smuggled stuff. After \cs{ekvset} has parsed the
+ entire \kv\ list everything that has been \cs{ekvsneak}ed will be left in the
+ input stream.
+\end{function}
+\begin{example}{Execute code after \cs[no-index]{ekvset} if a \Nkey\ was used}
+ Define a key |secret| in the set |foo| that will sneak out
+ |\foo@secretly@sneaked|:
+ \begin{enverb}[no-tcb]
+ \ekvdefNoVal{foo}{secret}{\ekvsneak{\foo@secretly@sneaked}}
+ \end{enverb}
+\end{example}
+A more elaborate usage example is shown in \autoref{sec:expkv:sneak}.
+
+\begin{function}{\ekvbreak,\ekvbreakPreSneak,\ekvbreakPostSneak}
+ \begin{syntax}
+ \cs{ekvbreak}\marg{after}
+ \end{syntax}
+ Gobbles the remainder of the current \cs{ekvset} call and its argument list
+ and inserts \meta{after}. So this can be used to break out of \cs{ekvset}. The
+ first variant will also gobble anything that has been sneaked out using
+ \cs{ekvsneak} or \cs{ekvsneakPre}, while \cs{ekvbreakPreSneak} will put
+ \meta{after} before anything that has been smuggled and \cs{ekvbreakPostSneak}
+ will put \meta{after} after the stuff that has been sneaked out.
+\end{function}
+\begin{example}{Stop parsing a \kv\ list if a specific \Nkey\ was used}
+ Define a key |abort| that will stop key parsing inside the set |foo| and
+ execute |\foo@aborted|, or if it got a value |\foo@aborted@with|:
+ \begin{enverb}[no-tcb]
+ \ekvdefNoVal{foo}{abort}{\ekvbreak{\foo@aborted}}
+ \ekvdef{foo}{abort}{\ekvbreak{\foo@aborted@with{#1}}}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvmorekv}
+ \begin{syntax}
+ \cs{ekvmorekv}\kvarg
+ \end{syntax}
+ Adds the contents of the \kv\ list to the list processed by the current call
+ of |\ekvset|.
+\end{function}
+\begin{example}{Use one \key\ to set multiple other keys}
+ Define a \Nkey\ |style| that sets the keys |border|, |width|, and |height| as
+ a shortcut:
+ \begin{enverb}[no-tcb]
+ \ekvdefNoVal{foo}{style}{\ekvmorekv{border, width=2cm, height=1.5ex}}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvchangeset}
+ \begin{syntax}
+ \cs{ekvchangeset}\marg{new-set}
+ \end{syntax}
+ Replaces the current \set\ with \meta{new-set}, so for the rest of the current
+ \cs{ekvset} call that call behaves as if it was called with
+ \cs{ekvset}\marg{new-set}. It is comparable to using \key|/.cd| in
+ \pkg{pgfkeys}.
+\end{function}
+\begin{example}{Change the current \set}
+ Define a key |cd| in set |foo| that will change to another set as specified in
+ the \val. If the set is undefined it'll stop the parsing and throw an error as
+ defined in the macro |\foo@cd@error|:
+ \begin{enverb}[no-tcb]
+ \ekvdef{foo}{cd}
+ {\ekvifdefinedset{#1}{\ekvchangeset{#1}}{\ekvbreak{\foo@cd@error}}}
+ \end{enverb}
+\end{example}
+
+\subsection{Parsing Keys in Sets}\label{sec:expkv:set}
+
+\begin{function}{\ekvset}
+ \begin{syntax}
+ \cs{ekvset}\marg{set}\kvarg
+ \end{syntax}
+ This macro parses the \kv\ list and checks for defined \key{}s that are in
+ \set. Unlike the generic \cs{ekvparse} this macro uses |\detokenize| on the
+ \key\ before checking whether it is a defined key.
+
+ \cs{ekvset} is nestable, and fully expandable. But it is \emph{not} alignment
+ safe. As a result \key\ names and \val{}s that contain an |&| must be wrapped
+ in braces if \cs{ekvset} is used inside an alignment (like \LaTeXe's |tabular|
+ environment) or alternatively you have to create a wrapper that ensurs an
+ alignment safe context.
+\end{function}
+\begin{example}{Set defined keys using \cs[no-index]{ekvset}}
+ Parse |key=arg, key| in set |foo|:
+ \begin{enverb}[no-tcb]
+ \ekvset{foo}{key=arg, key}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvsetSneaked}
+ \begin{syntax}
+ \cs{ekvsetSneaked}\marg{set}\marg{sneak}\kvarg
+ \end{syntax}
+ This behaves like \cs{ekvset} in which \cs{ekvsneak} was immediately called.
+\end{function}
+\begin{example}
+ {Set defined keys and execute code afterwards using
+ \cs[no-index]{ekvsetSneaked}}
+ Parse |key=arg, key| in the set |foo| with |\afterwards| sneaked out:
+ \begin{enverb}[no-tcb]
+ \ekvsetSneaked{foo}{\afterwards}{key=arg, key}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvsetdef}
+ \begin{syntax}
+ \cs{ekvsetdef}\meta{cs}\marg{set}
+ \end{syntax}
+ Defines the macro \meta{cs} to be a shortcut for \cs{ekvset}\marg{set}. You
+ can use any \TeX-prefix allowed to prefix |\def| for \cs{ekvsetdef} (so
+ |\long|, |\protected|, or |\global| -- don't use |\outer|).
+ The resulting macro is faster than but else equivalent to the idiomatic
+ definition:\par
+ |\def|\meta{cs}|#1{|\cs{ekvset}\marg{set}|{#1}}|
+\end{function}
+\begin{example}
+ {Define a setup command for a defined \set\ using \cs[no-index]{ekvsetdef}}
+ Define the macro |\foosetup| to parse keys in the set |foo| and use it to
+ parse |key=arg, key|:
+ \begin{enverb}[no-tcb]
+ \ekvsetdef\foosetup{foo}
+ \foosetup{key=arg, key}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvsetSneakeddef}
+ \begin{syntax}
+ \cs{ekvsetSneakeddef}\meta{cs}\marg{set}
+ \end{syntax}
+ Just like \cs{ekvsetdef} this defines a shorthand macro \meta{cs}, but this
+ will make it a shorthand for \cs{ekvsetSneaked}, meaning \meta{cs} will take
+ two arguments (first the \cs{ekvsneak} argument, then the \kv\ list). Hence
+ the result is a faster version of:\par
+ |\long\def|\meta{cs}|#1#2{|\cs{ekvsetSneaked}\marg{set}|{#1}{#2}}|
+\end{function}
+\begin{example}
+ {Define a setup command that will also require code to execute after all
+ keys were processed using \cs[no-index]{ekvsetSneakeddef}}
+ Define the macro |\foothings| to parse keys in the set |foo| and accept a
+ sneaked argument, then use it to parse |key=arg, key| and sneak |\afterwards|:
+ \begin{enverb}[no-tcb]
+ \ekvsetSneakeddef\foothings{foo}
+ \foothings{\afterwards}{key=arg, key}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvsetdefSneaked}
+ \begin{syntax}
+ \cs{ekvsetdefSneaked}\meta{cs}\marg{set}\marg{sneaked}
+ \end{syntax}
+ This macro behaves like \cs{ekvsetSneakeddef}, but with a fixed \meta{sneaked}
+ argument. So the resulting macro is faster than but else equivalent to\par
+ |\long\def|\meta{cs}|#1{|\cs{ekvsetSneaked}\marg{set}\marg{sneaked}|{#1}}|
+\end{function}
+\begin{example}
+ {Define a setup command that will execute codes after all keys were
+ processed using \cs[no-index]{ekvsetdefSneaked}}
+ Define the macro |\barthing| to parse keys in the set |bar| and always execute
+ |\afterwards| afterwards, then use it to parse |key=arg, key|:
+ \begin{enverb}[no-tcb]
+ \ekvsetdefSneaked\barthing{bar}{\afterwards}
+ \barthing{key=arg, key}
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvcompile}
+ \begin{syntax}
+ \cs{ekvcompile}\meta{*}\meta{cs}\meta{parameters}\marg{set}\kvarg
+ \end{syntax}
+ This macro defines \meta{cs} to be a \emph{fast} way to set the given \kv\
+ list in \meta{set}. The meaning of the keys is frozen if you don't give the
+ optional |*| (if the star is present the stored content will be the key-macros
+ and later redefinitions of keys will affect them, otherwise the key-macros are
+ expanded once, hence the key-code is stored). This does support the unknown
+ key handlers set up with |\ekvdefunknown| and |\ekvdefunknownNoVal| and also
+ the redirection of unknown keys (the latter will not be expanded exhaustively
+ though, so the key-search is done on every later call of \meta{cs}). Any
+ prefix allowed for |\def| might prefix \cs{ekvcompile}. The list is not
+ entirely fixed, as you might use \meta{parameters} in a \val\ (this is not a
+ single token but a parameter text as you'd use it with |\def|). They can not
+ be part of a \key-name (the names are indeed fixed). If you need a |#| in a
+ \val\ you'll need to double it just as you'd do in |\def|. Internally
+ \cs{ekvcompile} uses |\ekvparse| and no |\ekvset| variant, because of this the
+ \expnotation\ is handled slightly differently; in case you're using a
+ \key-name that starts with something that looks like \expnotation\ you'll have
+ to explicitly add an empty \expansion\ prefix.
+\end{function}
+\begin{example}
+ {Compile a \kv\ list into a macro that will quickly set that list}
+ Define the macro |\foo| to set some keys in the set |foo|. Since one key has a
+ strange name we need to add an empty \expansion\ prefix. Also we'd like |\foo|
+ to take one parameter which is part of the \val\ of |bar| (since the list is
+ parsed now and not when |\foo| is used we don't need to put braces around that
+ value, even if at use time |#1| contains commas):
+ \begin{enverb}[no-tcb]
+ \ekvcompile\foo#1{foo}
+ {
+ bar = #1baz
+ ,: part-of-key: name = strange
+ ,NoVal
+ }
+ \end{enverb}
+ After this using |\foo{VAL}| will be the same as but faster than
+ \begin{enverb}[no-tcb]
+ \ekvset{foo}{bar={VALbaz},part-of-key: name=strange,NoVal}
+ \end{enverb}
+\end{example}
+
+\subsection{Generic Key Parsing}\label{sec:expkv:parse}
+
+\begin{function}{\ekvparse}
+ \begin{syntax}
+ \cs{ekvparse}\marg{code1}\marg{code2}\kvarg
+ \end{syntax}
+ This macro parses the \kv\ list and provides \Nkey{}s to \meta{code1} as a
+ single argument and \Vkey{}s with their corresponding \val\ as two arguments
+ to \meta{code2}.
+
+ \cs{ekvparse} is fully expandable and alignment safe, meaning that you don't
+ have to take any extra precautions if it is used inside an alignment context
+ (like \LaTeXe's |tabular| environment) and any \key\ or \val\ can contain an
+ |&|. \cs{ekvparse} expands in exactly two steps, the result is provided inside
+ |\unexpanded| (so doesn't expand further in an |\edef| or |\expanded|
+ context).
+
+ \cs{ekvbreak}, \cs{ekvsneak}, \cs{ekvmorekv}, \emph{etc.}\ don't work
+ in \cs{ekvparse}. \cs{ekvparse} does not throw an error if multiple
+ unprotected equals signs are found (it just splits at the first), and doesn't
+ throw an error if a \key\ is empty. If something looks like \expnotation\ (has
+ a colon followed but not preceded by a space and with non-blank material
+ following it) it'll be parsed as such (which might throw errors due to
+ undefined \expansion-rules if that wasn't the intended input). If you for some
+ reason need to input a \key-name that would match that pattern you'll need to
+ precede it by \verb*|: | (an empty \expansion\ prefix).
+\end{function}
+\begin{example}
+ {Parse a \kv\ list and execute arbitrary code for each element using
+ \cs[no-index]{ekvparse}}
+ \begin{enverb}[no-tcb]
+ \ekvparse{\handlekey{S}}{\handlekeyval{S}}{foo = bar, key, baz={zzz}}
+ \end{enverb}
+ would be equivalent to
+ \begin{enverb}[no-tcb]
+ \handlekeyval{S}{foo}{bar}\handlekey{S}{key}\handlekeyval{S}{baz}{zzz}
+ \end{enverb}
+ and afterwards |\handlekey| and |\handlekeyval| would have to further handle
+ the keys. No such macros are contained in \expkv, but I hope you get the idea.
+ Because it expands in two steps and doesn't expand any further both
+ \begin{enverb}[no-tcb]
+ \expandafter\parse\expanded{\ekvparse\k\kv{foo = bar, key, baz={zzz}}}
+ \end{enverb}
+ and
+ \begin{enverb}[no-tcb]
+ \expandafter\expandafter\expandafter
+ \parse\ekvparse\k\kv{foo={bar}, key, baz = zzz}
+ \end{enverb}
+ expand to
+ \begin{enverb}[no-tcb]
+ \parse\kv{foo}{bar}\k{key}\kv{baz}{zzz}
+ \end{enverb}
+\end{example}
+
+\subsection{Other Useful Macros}
+
+\begin{function}{\ekvoptarg}
+ \begin{syntax}
+ \cs{ekvoptarg}\marg{next}\marg{default}
+ \end{syntax}
+ This macro will expandably check for a following optional argument in brackets
+ (|[]|). After the optional argument there has to be a mandatory one (or else
+ this might have unwanted side effects). The code in \meta{next} should expect
+ two arguments (or more), namely the processed optional argument and the
+ mandatory one that followed it. If there was an optional argument the result
+ will be \meta{next}\marg{optional}\meta{mandatory} (so the optional argument
+ will be wrapped in braces, the mandatory argument will be untouched). If there
+ was no optional argument the result will be
+ \meta{next}\marg{default}\marg{mandatory} (so the default will be used and the
+ mandatory argument will be wrapped in braces after it was read once -- if it
+ was already wrapped it is effectively unchanged).
+
+ \cs{ekvoptarg} expands in exactly two steps, grabs all the arguments only at
+ the second expansion step, and is alignment safe. It has its limitations
+ however. It can't tell the difference between |[| and |{[}|, so it doesn't
+ work if the mandatory argument is a single bracket. Also if the optional
+ argument should contain a nested closing bracket it has to be nested in braces
+ like so: |[{arg[u]ment}]| (or else the result would be |arg[u| with a trailing
+ |ment]|).
+\end{function}
+\begin{example}{Expandably search for an optional argument with a default value}
+ Say we have a macro that should take an optional argument defaulting to |1|,
+ we could program it like this:
+ \makeatletter
+ \begin{enverb}
+ \newcommand\foo{\ekvoptarg\@foo{1}}
+ \newcommand\@foo[2]{Mandatory: #2\par Optional: #1}
+ \foo{5}\par
+ \foo[4]{5}\par
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvoptargTF}
+ \begin{syntax}
+ \cs{ekvoptargTF}\marg{true}\marg{false}
+ \end{syntax}
+ This macro is similar to \cs{ekvoptarg} but will result in
+ \meta{true}\marg{optional}\meta{mandatory} or \meta{false}\marg{mandatory}
+ instead of placing a default value.
+
+ \cs{ekvoptargTF} expands in exactly two steps, grabs all the arguments only at
+ the second expansion step, and is alignment safe. It has the same limitations
+ as \cs{ekvoptarg}.
+\end{function}
+\begin{example}
+ {Expandably search for an optional argument and behave differently if it's
+ found or not}
+ Say we have a macro that should behave differently depending on whether there
+ was an optional argument or not. This could be done with:
+ \makeatletter
+ \begin{enverb}
+ \newcommand\foo{\ekvoptargTF\foo@a\foo@b}
+ \newcommand\foo@a[2]{Mandatory: #2\par Optional: #1}
+ \newcommand\foo@b[1]{Mandatory: #1\par No optional.}
+ \foo{5}\par
+ \foo[4]{5}\par
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekvcsvloop}
+ \begin{syntax}
+ \cs{ekvcsvloop}\marg{code}\marg{csv-list}
+ \end{syntax}
+ This loops over the comma separated items in \meta{csv-list} and, after
+ stripping spaces from either end of \meta{item} and removing at most one set
+ of outer braces, leaves |\unexpanded{|\meta{code}\marg{item}|}| for each list
+ item in the input stream. Blank elements are ignored (if you need a blank
+ element it should be given as \verb*|{ }|). It supports both active commas and
+ commas of category other. \cs{ekvcsvloop} is not alignment safe, but you could
+ make it so by nesting it in |\expanded| (since the braces around the argument
+ of |\expanded| will hide alignment characters from \TeX's parsing).
+\end{function}
+\begin{example}
+ {Loop over a comma separated list and execute arbitrary code for each
+ element}
+ The following splits a comma separated list and prints it in a typewriter font
+ with parentheses around each element:
+ \begin{enverb}
+ \newcommand*\myprocessor[1]{\texttt{(#1)}}
+ \ekvcsvloop\myprocessor{abc,def,ghi}\par
+ \ekvcsvloop\myprocessor{1,,2,,3,,4}\par
+ \end{enverb}
+\end{example}
+
+\begin{function}{\ekverr}
+ \begin{syntax}
+ \cs{ekverr}\marg{package}\marg{message}
+ \end{syntax}
+ This macro will throw an error fully expandably.\footnotemark\ The error
+ length is limited to a total length of 69~characters, and since ten characters
+ will be added for the formatting (\verb*|! | and \verb*| Error: |) that leaves
+ us with a total length of \meta{package} plus \meta{message} of 59~characters.
+ If the message gets longer \TeX\ will only display the first 69~characters and
+ append |\ETC.| to the end.
+
+ Neither \meta{package} nor \meta{message} expand any further. Also
+ \meta{package} must not contain an explicit |\par| token or the token
+ |\thanks@jfbu|. No such restriction applies to \meta{message}.
+
+ If |^^J| is set up as the |\newlinechar| (which is the case in \LaTeXe\ but
+ not in \hologo{plainTeX} by default) you can use that to introduce line breaks
+ in your error message. However that doesn't change the message length limit.
+\end{function}
+\footnotetext{The used mechanism was to the best of my knowledge first
+implemented by Jean-François Burnol.}
+After your own error message some further text will be placed. The formatting
+of that text will look good if |^^J| is the |\newlinechar|, else not so much.
+That text will read:
+\begin{verbatim}
+ ! Paragraph ended before \<an-expandable-macro>
+ completed due to above exception. If the error
+ summary is not comprehensible see the package
+ documentation.
+ I will try to recover now. If you're in inter-
+ active mode hit <return> at the ? prompt and I
+ continue hoping recovery was complete.
+\end{verbatim}
+Any clean up has to be done by you, |\ekverr| will expand to nothing after
+throwing the error message.
+
+In \ConTeXt\ this macro works differently. While still being fully expandable,
+it doesn't have the character count limitation and doesn't impose restrictions
+on \meta{package}. It will not display the additional text and adding line
+breaks is not possible.
+\begin{example}{Expandably throw error messages using \cs[no-index]{ekverr}}
+ Say we set up a macro that takes as mandatory argument a simple equation which
+ must not be empty and if it's not empty it displays it and calculates the
+ result:
+ \begin{enverb}[no-tcb]
+ \newcommand*\mycalc[1]
+ {%
+ \the\numexpr
+ \if\relax\detokenize{#1}\relax
+ \ekverr{my}{Empty equation not allowed, leaving -2147483647}%
+ -2147483647%
+ \else
+ #1%
+ \fi
+ \relax
+ }
+ Using \mycalc{} wrong.
+ \end{enverb}
+ If that code gets executed the following will be the terminal output
+ \begin{verbatim}
+ Runaway argument?
+ ! my Error: Empty equation not allowed, leaving -2147483647
+ ! Paragraph ended before \<an-expandable-macro>
+ completed due to above exception. If the error
+ summary is not comprehensible see the package
+ documentation.
+ I will try to recover now. If you're in inter-
+ active mode hit <return> at the ? prompt and I
+ continue hoping recovery was complete.
+ <to be read again>
+ \par
+ l.17 Using \mycalc{}
+ wrong.
+ ?
+ \end{verbatim}
+ and the output would contain
+ \exres{Using -2147483647 wrong}
+ if we continued the \TeX\ run at the prompt.
+\end{example}
+
+
+\subsection{Other Macros}
+
+\begin{variable}{\ekvDate,\ekvVersion}
+ These two macros store \expkv's date and version.
+\end{variable}
+
+\begin{function}{\ekv@name,\ekv@name@set,\ekv@name@key}
+ \begin{syntax}
+ \cs{ekv@name}\marg{set}\marg{key}
+ \cs{ekv@name@set}\marg{set}
+ \cs{ekv@name@key}\marg{key}
+ \end{syntax}
+ The names of the macros storing the code of \Vkey{}s are stored in are built
+ with these macros. The name is built from two blocks, one that is formatting
+ the \set\ name, and on for formatting the \key\ name. To get the actual name
+ the argument to \cs{ekv@name@key} must be |\detokenize|d. Both blocks are put
+ together (with the necessary |\detokenize|) by \cs{ekv@name}. For \Nkey{}s an
+ additional |N| gets appended, so their name is
+ \cs{ekv@name}\marg{set}\marg{key}|N|.
+
+ You can use these macros to implement additional functionality or access
+ key-macros outside of \expkv, but \emph{don't} change them! \expkv\ relies on
+ their exact definitions internally.
+\end{function}
+\begin{example}{Directly call key code without parsing a \kv\ list}
+ Execute the key-macro of the \Nkey\ named |bar| in set |foo|:
+ \begin{enverb}[no-tcb]
+ \csname\ekv@name{foo}{bar}N\endcsname
+ \end{enverb}
+\end{example}
+
+
+\subsection{Examples}
+\subsubsection{Standard Use-Case\label{sec:expkv:standard}}
+
+\begin{example}{A \kv\ based replacement for \LaTeXe's \cs[no-index]{rule}}
+ Because I keep forgetting the correct order of \LaTeXe's |\rule| command I
+ want to create a \kv\ interface to it. For this I define the keys |ht| to
+ specify the rule's height, |wd| to specify its width, and to give a
+ displacement I use two keys (because who can remember whether the rule is
+ moved upwards or downwards?).
+
+ First the internals storing the values are initialised
+ \begin{enverb}[no-tcb,store]
+ \makeatletter
+ \newcommand*\myrule@ht{1ex}
+ \newcommand*\myrule@wd{0.1em}
+ \newcommand*\myrule@raise{\z@}
+ \end{enverb}
+ then the keys are defined. We could use |\dimen| registers instead of defining
+ macros, but macros have the advantage that the font dependent dimensions are
+ evaluated at use time.
+ \begin{enverb}[no-tcb,store]
+ \protected\ekvdef{myrule}{ht}{\def\myrule@ht{#1}}
+ \protected\ekvdef{myrule}{wd}{\def\myrule@wd{#1}}
+ \protected\ekvdef{myrule}{raise}{\def\myrule@raise{#1}}
+ \protected\ekvdef{myrule}{lower}{\def\myrule@raise{-#1}}
+ \end{enverb}
+ We also want a way to change the initial values without outputting a rule
+ (since there are unexpandable keys involved it's a good idea to define this
+ |\protected|)
+ \begin{enverb}[no-tcb,store]
+ \protected\ekvsetdef\myruleset{myrule}
+ \end{enverb}
+ and we need an actual frontend that does the job:
+ \begin{enverb}[no-tcb,store]
+ \newcommand*\myrule[1][]
+ {%
+ \begingroup
+ \myruleset{#1}%
+ \rule[\myrule@raise]{\myrule@wd}{\myrule@ht}%
+ \endgroup
+ }
+ \makeatother
+ \end{enverb}
+ Now we can use it:
+ \begin{enverb}[same-line=0.5,restore]
+ a\myrule\par
+ a\myrule[ht=2ex,lower=.5ex]\par
+ \myruleset{wd=5cm}
+ a\myrule
+ \end{enverb}
+\end{example}
+
+
+\subsubsection{An Expandable \kv\ Macro Using
+ \cs[no-index]{ekvsneak}\label{sec:expkv:sneak}}
+
+\begin{example}{An expandable \kv\ macro using \cs[no-index]{ekvsneak}}
+ Let's set up an expandable macro that uses a \kv\ interface. The problems
+ we'll face for this are:
+ \begin{enumerate}
+ \item ignoring duplicate keys
+ \item default values for keys which weren't used
+ \item providing the values as the correct argument to a macro (ordered)
+ \end{enumerate}
+
+ First we need to decide which \kv\ parsing macro we want to do this with,
+ \cs{ekvset} or \cs{ekvparse}. For this example we also want to show the usage
+ of \cs{ekvsneak}, hence we'll choose \cs{ekvset}. And we'll have to use
+ \cs{ekvset} such that it builds a parsable list for our macro internals. To
+ gain back control after \cs{ekvset} is done we have to put an internal of our
+ macro at the start of that list, so we use an internal key that uses
+ \cs{ekvsneakPre} after any user input.
+
+ To ignore duplicates will be easy if the value of the key used last will be
+ put first in the list, so we'll use \cs{ekvsneakPre} for the real values as
+ well. If for some reason we wanted a key for which the first usage was the
+ binding one we'd use \cs{ekvsneak} for that one.
+
+ Providing default values can be done in different ways. We'll use a simple
+ approach in which we'll just put the outcome of our keys if they were used
+ with default values before our end marker.
+
+ Ordering the keys can be done simply by searching for a specific token for
+ each argument (that token acts as a flag), so our sneaked out values will
+ include these specific tokens acting as markers.
+
+ Now we got an answer to each of our initial problems. Everything that's left
+ is deciding what our macro should actually do. For this example we'll define a
+ macro that calculates the sine of a number rounded to a specified precision.
+ The macro should also understand input in radian and degree, and we could also
+ decide to evaluate a different function. For the real hard part of this
+ (expandably calculating trigonometric functions) we'll use \pkg{xfp}.
+
+ First we set up our keys according to our earlier considerations and set up
+ the user facing macro |\sine|. The end marker of the parsing list will be a
+ |\sine@stop| token (which we don't need to define) and we put our default
+ values right before it. The user macro |\sine| uses |\ekvoptargTF| to check
+ for the optional argument short cutting a bit if no optional argument was
+ found. If you'd so prefer you could use \pkg{ltcmd}'s
+ |\NewExpandableDocumentCommand| to expandably get an optional argument as
+ well.
+ \begin{enverb}[no-tcb,store]
+ \RequirePackage{xfp}
+ \makeatletter
+ \ekvdef{sine}{f}{\ekvsneakPre{\f{#1}}}
+ \ekvdef{sine}{round}{\ekvsneakPre{\rnd{#1}}}
+ \ekvdefNoVal{sine}{degree}{\ekvsneakPre{\deg{d}}}
+ \ekvdefNoVal{sine}{radian}{\ekvsneakPre{\deg{}}}
+ \ekvdefNoVal{sine}{internal}{\ekvsneakPre{\sine@rnd}}
+ \newcommand*\sine{\ekvoptargTF\sine@args{\sine@final{sin}{d}{3}}}
+ \newcommand*\sine@args[2]
+ {\ekvset{sine}{#1,internal}\rnd{3}\deg{d}\f{sin}\sine@stop{#2}}
+ \end{enverb}
+
+ Now we need to define some internal macros to extract the value of each key's
+ last usage (remember that this will be the argument after the first matching
+ flag). For that we use one delimited macro per key.
+ \begin{enverb}[no-tcb,store]
+ \def\sine@rnd#1\rnd#2#3\sine@stop{\sine@deg#1#3\sine@stop{#2}}
+ \def\sine@deg#1\deg#2#3\sine@stop{\sine@f#1#3\sine@stop{#2}}
+ \def\sine@f#1\f#2#3\sine@stop{\sine@final{#2}}
+ \end{enverb}
+ After the macros |\sine@rnd|, |\sine@deg|, and |\sine@f| the macro
+ |\sine@final| will see
+ |\sine@final|\marg{f}\marg{degree/radian}\marg{round}\marg{num}. Now
+ |\sine@final| has to expandably deal with those arguments such that the
+ |\fpeval| macro of \pkg{xfp} gets the correct input. Luckily this part is
+ pretty easy after the build up we've done until now. In |\fpeval| the
+ trigonometric functions have names such as |sin| or |cos|, and the degree
+ taking alternatives just have an appended |d| (so |sind| or |cosd|). So
+ putting \meta{f} and \meta{degree/radian} together will form the correct
+ names.
+ \begin{enverb}[no-tcb,store]
+ \newcommand*\sine@final[4]{\fpeval{round(#1#2(#4),#3)}}
+ \makeatother
+ \end{enverb}
+ Let's give our macro a test:
+ \begin{enverb}[restore,inter=\def\RequirePackage#1{}]
+ \sine{60}\par
+ \sine[round=10]{60}\par
+ \sine[f=cos,radian]{pi}\par
+ \edef\myval{\sine[f=tan]{1}}\texttt{\meaning\myval}
+ \end{enverb}
+\end{example}
+
+Please note that setting this up a lot more user friendly is easily possible by
+utilizing \expkvc\ (see \autoref{sec:expkv-cs}).
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/pkg-opt.tex b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-opt.tex
new file mode 100644
index 00000000000..452fbd1c281
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-opt.tex
@@ -0,0 +1,229 @@
+\latexekv\expkvo{-opt}
+
+\expkvo\ allows to parse \LaTeXe\ class and package options as \kv\ lists using
+sets of \expkv.
+
+With the 2021-05-01 release of \LaTeXe\ there were some very interesting changes
+to the package and class options code. It is now possible to use braces inside
+the options, and we can access options without them being preprocessed. As a
+result, some but not all restrictions were lifted from the possible option
+usage. What will still fail is things that aren't save from an |\edef| expansion
+(luckily, the \expnotation\ can be used to get around that as well). One feature
+of \expkvo\ that doesn't work any more is the possibility to parse the unused
+option list, because that one doesn't contain the full information any more.
+\expkvo\ will fall back to v0.1 if the kernel is older than 2021-05-01.
+
+Another very interesting change in \LaTeXe\ was the addition of \pkg{ltkeys} and
+its |\ProcessKeyOptions| with the possibility to parse future options with it
+instead of getting the dreaded |Option clash| error. The idea is brilliant and
+changes made in the 2022-10-22 version allow us to provide the same feature
+without having to hack any kernel internals, so starting with kernel version
+2022-11-01 \expkvo\ supports this as well.
+
+\expkvo\ shouldn't place any restrictions on the keys, historic shortcomings of
+the kernel cannot be helped though, so the supported things vary with the kernel
+version (see above). The one thing that \expkvo\ doesn't support, which \expkv\
+alone would, is active commas or equals signs. But there is no good reason why
+any of the two should be active in the preamble.
+
+You can use \LaTeXe's rollback support, so to load v0.1 explicitly use:
+\begin{enverb}[no-tcb]
+ \usepackage{expkv-opt}[=v0.1]
+\end{enverb}
+which will load the last version of \expkvo\ that doesn't use the raw option
+lists (this shouldn't be done by a package author, but only by a user on a
+single-document basis if there are some incompatibilities, which is unlikely).
+
+
+\subsection{Macros\label{sec:o:macros}}
+
+\subsubsection{Option Processors\label{sec:o:processors}}
+
+\expkvo's behaviour if it encounters a defined or an undefined \key\ depends on
+which list is being parsed and whether the current file is a class or not. Of
+course in every case a defined \key's callback will be invoked but an
+additional action might be executed. For this reason the rule set of every macro
+will be given below the short description which list it will parse.
+
+During each of the processing macros the current list element (not processed in
+any way) is stored within the macro |\CurrentOption|.
+
+\begin{function}{\ekvoProcessOptions}
+ \begin{syntax}
+ \cs{ekvoProcessOptions}\marg{set}
+ \end{syntax}
+ This runs |\ekvoProcessGlobalOptions|, then |\ekvoProcessLocalOptions|, and
+ finally |\ekvoProcessFutureOptions|. If you're using |\ekvoUseUnknownHandlers|
+ it'll affect all three option processors. Else the respective default
+ unknown-rules are used.
+\end{function}
+
+\begin{function}{\ekvoProcessLocalOptions}
+ \begin{syntax}
+ \cs{ekvoProcessLocalOptions}\marg{set}
+ \end{syntax}
+ This parses the options which are directly passed to the current class or
+ package for an \expkv\ \set.
+\end{function}
+\expkvorules
+ {%
+ cd = {remove the option from the list of unused global options if the local
+ option list matches the option list of the main class and the unused
+ global options list is not empty; else \emph{nothing}}
+ ,cu = add the key to the list of unused global options (if the local option
+ list matches the option list of the main class)
+ ,pu = throw an error
+ }
+
+\begin{function}{\ekvoProcessGlobalOptions}
+ \begin{syntax}
+ \cs{ekvoProcessGlobalOptions}\marg{set}
+ \end{syntax}
+ In \LaTeXe\ the options given to |\documentclass| are global options. This
+ macro processes the global options for an \expkv\ \set.
+\end{function}
+\expkvorules{d = remove the option from the list of unused global options}
+
+\begin{function}{\ekvoProcessFutureOptions}
+ \begin{syntax}
+ \cs{ekvoProcessFutureOptions}\marg{set}
+ \end{syntax}
+ This parses the option list of every future call of the package with
+ |\usepackage| or similar with an \expkv\ \set, circumventing the
+ |Option clash| error that'd be thrown by \LaTeXe. It is only available for
+ kernel versions starting with 2022-11-01. It is mutually exclusive with
+ \LaTeXe's |\ProcessKeyOptions| (which ever comes last defines how future
+ options are parsed).
+\end{function}
+\expkvorules{u = throw an error}
+
+\begin{function}{\ekvoProcessOptionsList}
+ \begin{syntax}
+ \cs{ekvoProcessOptionsList}\meta{list}\marg{set}
+ \end{syntax}
+ Process the \kv\ list stored in the macro \meta{list}.
+\end{function}
+\expkvorules{}
+
+
+\subsubsection{Other Macros\label{sec:o:others}}
+
+\begin{function}{\ekvoUseUnknownHandlers}
+ \begin{syntax}
+ \cs{ekvoUseUnknownHandlers}\meta{cs_1}\meta{cs_2}\quad{\normalfont\itshape or}
+ \cs{ekvoUseUnknownHandlers}*
+ \end{syntax}
+ With this macro you can change the action \expkvo\ executes if it encounters
+ an undefined \key\ for the next (and only the next) list processing macro. The
+ macro \meta{cs_1} will be called if an undefined \Nkey\ is encountered and get
+ one argument being the \key\ (without being |\detokenize|d). Analogous the
+ macro \meta{cs_2} will be called if an undefined \Vkey\ was parsed and get two
+ arguments, the first being the \key\ (without being |\detokenize|d) and the
+ second the \val.
+ \par
+ If you use the starred variant, it'll not take further arguments. In this case
+ the undefined handlers defined via |\ekvdefunknown| and |\ekvdefunknownNoVal|
+ in the parsing set get used, and if those aren't available they'll simply do
+ nothing.
+\end{function}
+
+\begin{function}{\ekvoVersion,\ekvoDate}
+ These two macros store the version and date of the package.
+\end{function}
+
+
+\subsection{Examples}
+
+\begin{example}{A package using \expkvo}
+ Let's say we want to create a package that changes the way footnotes are
+ displayed in \LaTeX. For this it will essentially just redefine |\thefootnote|
+ and we'll call this package \pkg{ex-footnote}. First we report back which
+ package we are:
+ \begin{enverb}[no-tcb]
+ \ProvidesPackage{ex-footnote}[2020-02-02 v1 change footnotes]
+ \end{enverb}
+ Next we'll need to provide the options we want the package to have.
+ \begin{enverb}[no-tcb]
+ \RequirePackage{color}
+ \RequirePackage{expkv-opt}% also loads expkv
+ \ekvdef{ex-footnote}{color}{\def\exfn@color{#1}}
+ \ekvdef{ex-footnote}{format}{\def\exfn@format{#1}}
+ \end{enverb}
+ We can provide initial values just by defining the two macros storing the
+ value.
+ \begin{enverb}[no-tcb]
+ \newcommand*\exfn@color{}
+ \newcommand*\exfn@format{arabic}
+ \end{enverb}
+ Next we need to process the options given to the package. The package should
+ only obey options directly passed to it, so we're using
+ |\ekvoProcessLocalOptions| and |\ekvoProcessFutureOptions|:
+ \begin{enverb}[no-tcb]
+ \ekvoProcessLocalOptions {ex-footnote}
+ \ekvoProcessFutureOptions{ex-footnote}
+ \end{enverb}
+ Now everything that's still missing is actually changing the way footnotes
+ appear:
+ \begin{enverb}[no-tcb]
+ \renewcommand*\thefootnote
+ {%
+ \ifx\exfn@color\@empty
+ \csname\exfn@format\endcsname{footnote}%
+ \else
+ \textcolor{\exfn@color}{\csname\exfn@format\endcsname{footnote}}%
+ \fi
+ }
+ \end{enverb}
+ So the complete code of the package would look like this:
+ \begin{enverb}[no-tcb]
+ \ProvidesPackage{ex-footnote}[2020-02-02 v1 change footnotes]
+
+ \RequirePackage{color}
+ \RequirePackage{expkv-opt}% also loads expkv
+
+ \ekvdef{ex-footnote}{color}{\def\exfn@color{#1}}
+ \ekvdef{ex-footnote}{format}{\def\exfn@format{#1}}
+ \newcommand*\exfn@color{}
+ \newcommand*\exfn@format{arabic}
+
+ \ekvoProcessLocalOptions {ex-footnote}
+ \ekvoProcessFutureOptions{ex-footnote}
+
+ \renewcommand*\thefootnote
+ {%
+ \ifx\exfn@color\@empty
+ \csname\exfn@format\endcsname{footnote}%
+ \else
+ \textcolor{\exfn@color}{\csname\exfn@format\endcsname{footnote}}%
+ \fi
+ }
+ \end{enverb}
+ And it could be used with one (or thanks to |\ekvoProcessFutureOptions| all)
+ of the following lines:
+ \begin{enverb}[no-tcb]
+ \usepackage{ex-footnote}
+ \usepackage[format=fnsymbol]{ex-footnote}
+ \usepackage[color=green]{ex-footnote}
+ \usepackage[color=red,format=roman]{ex-footnote}
+ \end{enverb}
+\end{example}
+
+\begin{example}{Parsing the global options}
+ This document was compiled with the global options
+ \texttt{[\detokenize\expandafter\expandafter\expandafter{\csname @raw@classoptionslist\endcsname]}}
+ in use. If we define the following keys
+ \begin{enverb}[store,no-tcb]
+ \ekvdef{optexample}{exfoo}
+ {Global option \texttt{exfoo} got \texttt{\detokenize{#1}}.\par}
+ \ekvdefNoVal{optexample}{exbar}
+ {Global option \texttt{exbar} set.\par}
+ \end{enverb}
+ we can use those options to control the result of the following:
+ \begin{enverb}[restore,same-line=.55]
+ \ekvoProcessGlobalOptions{optexample}
+ \end{enverb}
+ Please note that under normal conditions
+ \cs[no-index]{ekvoProcessGlobalOptions} is only useable in the preamble; this
+ example is only for academic purposes, you'll not be able to reproduce this
+ with the exact code shown above.
+\end{example}
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/pkg-pop.tex b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-pop.tex
new file mode 100644
index 00000000000..e34d0c5d1f9
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/pkg-pop.tex
@@ -0,0 +1,439 @@
+\genericekv\expkvp{-pop}
+
+The \expkvp\ is mainly written to lay the basis for \expkvc's and \expkvd's
+key-defining front ends. Historically the two packages shared pretty similar
+code. To unify this and reduce the overall code amount some auxiliary package
+was originally planned, but then I realised that with little to no overhead
+(apart from documentation) this can also be provided to users. Well, and then I
+thought, why not make the whole thing expandable as well. And here we are.
+
+So what's the idea? This package provides a \textbf{p}refix \textbf{o}riented
+\textbf{p}arser\footnote{Naming packages is hard, especially when the name
+should fit a particular naming scheme. Big thanks to samcarter for helping
+me: \url{https://topanswers.xyz/tex?q=1985}. The author apologises that there is
+no \texttt{expkv-pnk}, \texttt{expkv-rok}, \texttt{expkv-jaz} or any other music
+themed name in \expkvbundle.} with two kinds of prefixes. The first is called a
+\prefix, of which an item can have arbitrary many, the second a \type, of which
+every item has only one. To distinguish the concept of an optional \prefix\ from
+the generic term \enquote{prefix} I'll use this formatting whenever the special
+kind of prefix is meant.
+
+Another peculiarity of \expkvp\ compared to the other packages in
+\expkvbundle\ is that it doesn't separate \Nkey{}s from \Vkey{}s as
+strictly. Instead a |NoVal|-marker is used as the value. If this is not what you
+want you can use \cs{ekvpValueAlwaysRequired} (see there).
+
+
+\subsection{Parsing Rules}
+
+A parser is processing only the \key\ of a \kv\ pair. The \key\ is split at
+spaces (braces might be lost by this process!). Each split off piece is checked
+whether it's a defined prefix. If it's a \type\ parsing of the \key\ stops and
+the remainder is considered a \meta{name}. If it's a \prefix\ it'll be recorded
+and parsing goes on. If it's neither parsing is also stopped (and the last
+parsed space delimited part is put back -- braces might've been lost at this
+step). If a no-type rule has been defined (\cs{ekvpDefNoType}) that one is
+executed else an error is thrown.
+
+The \prefix\ or \type\ has to match after being |\detokenize|d, whereas the
+\meta{name} will be unchanged (except for stripping off the prefixes). If only a
+\key\ is given (so no =\val\ used) the same is done, and instead of \val\ a
+no-value marker is used (if that accidentally ends up in the input stream this
+looks like this: \csname c\string_novalue\string_tl\endcsname; this is the same
+as the marker used by \pkg{expl3} for those familiar with it).
+
+A \prefix\ has two parts to it, a \meta{pre} and a \meta{post} code, whereas a
+\type\ only results in a \type-action (or the no-type action if that's defined
+and no \type\ found). The parsing result can also be seen in
+\autoref{fig:p:result}.
+
+\begin{figure}[b]
+ \centering
+ \def\plevel#1{\raisebox{1ex}{#1}}%
+ \def\ts#1{\textsubscript{$#1$}}%
+ \begingroup
+ \ttfamily
+ pre\ts1
+ \plevel
+ {%
+ pre\ts2
+ \plevel
+ {%
+ \ldots\space
+ \plevel
+ {%
+ pre\ts n
+ \plevel{\type-action}
+ post\ts n
+ }%
+ \ldots\space
+ }%
+ post\ts2
+ }%
+ post\ts{1}%
+ \endgroup
+ \caption
+ {%
+ Structure of a single \kv\ pair's parsing result with $n$~\prefix{}es%
+ \label{fig:p:result}%
+ }
+\end{figure}
+
+Please note that \expkvp's parsers are fully expandable as long as your
+\prefixes\ and \types\ are. Additionally \expkvp\ doesn't provide means to
+define parsers, \prefixes, or \types\ |\protected|. As a result, make sure
+you'll always call |\ekvpParse| inside of a |\protected| macro if you need
+anything that's unexpandable or else your code might not do what you intended
+since some states may not be updated when expandable code tries to access them.
+The macro |\ekvpProtect| can help to overcome this issue, but it's more of a
+last resort than a clean solution.
+
+\subsection{Defining Parsers}
+
+\begin{function}{\ekvpNewParser}
+ \begin{syntax}
+ \cs{ekvpNewParser}\marg{parser}
+ \end{syntax}
+ Defines a new parser called \meta{parser}. Every parser has to be defined this
+ way. Throws an error if the parser is already defined.
+\end{function}
+
+\begin{function}{\ekvpDefType}
+ \begin{syntax}
+ \cs{ekvpDefType}\marg{parser}\marg{type}\marg{code}
+ \end{syntax}
+ Defines a \type\ that is called \meta{type} for the parser \meta{parser}. If
+ the \type\ is parsed the \meta{code} will be used as a \type-action. Inside of
+ \meta{code} you can use |#1| to refer to the \meta{name} (the remainder of the
+ \key\ after stripping off all the prefixes), |#2| to use the unaltered \key,
+ and |#3| to access the \val\ which was given to your \key.
+\end{function}
+
+\begin{function}{\ekvpDefPrefix}
+ \begin{syntax}
+ \cs{ekvpDefPrefix}\marg{parser}\marg{prefix}\marg{pre}\marg{post}
+ \end{syntax}
+ Defines a \prefix\ that is called \meta{prefix} for the parser \meta{parser}.
+ If the \prefix\ is encountered the code in \meta{pre} will be put before the
+ \type-action and the code in \meta{post} will be put behind it.
+ If multiple \prefix{}es are used the \meta{pre} of the first will be put first
+ and the \meta{post} of the first will be put last. Inside of \meta{pre} and
+ \meta{post} |#1| is replaced with the found \type, |#2| the \meta{name}, and
+ |#3| the unaltered \key. If no valid type was found and the no-type rule
+ defined with \cs{ekvpDefNoType} is executed the argument |#1| will be empty.
+\end{function}
+
+\begin{function}{\ekvpDefAutoPrefix}
+ \begin{syntax}
+ \cs{ekvpDefAutoPrefix}\marg{parser}\marg{pre}\marg{post}
+ \end{syntax}
+ You can also define a \prefix-like rule that is executed on each element
+ automatically. So the \meta{pre} and \meta{post} code of this will be inserted
+ for every valid element of the \kv\ list. Just like for \cs{ekvpDefPrefix} you
+ can access the \type\ with |#1|, the \meta{name} with |#2|, and the unaltered
+ \key\ with |#3|.
+\end{function}
+
+\begin{function}{\ekvpDefPrefixStore}
+ \begin{syntax}
+ \cs{ekvpDefPrefixStore}\marg{parser}\marg{prefix}\meta{cs}\marg{pre}\marg{post}
+ \end{syntax}
+ This is a shortcut to define a \prefix\ named \meta{prefix} for \meta{parser}
+ that'll store \meta{pre} inside of \meta{cs} (which should be a single control
+ sequence) before the \type-action and afterwards store \meta{post} in it. Both
+ definitions (in \meta{pre} and in \meta{post}) are put inside |\ekvpProtect|.
+\end{function}
+
+\begin{function}{\ekvpDefPrefixLet}
+ \begin{syntax}
+ \cs{ekvpDefPrefixLet}\marg{parser}\marg{prefix}\meta{cs}\meta{pre}\meta{post}
+ \end{syntax}
+ This is similar to \cs{ekvpDefPrefixStore}, but instead of storing in the
+ \meta{cs} it'll be let to the single tokens specified by \meta{pre} and
+ \meta{post}. If either \meta{pre} or \meta{post} contains more than a single
+ token the remainder is put after the |\let| statement. Both assignments (in
+ \meta{pre} and in \meta{post}) are put inside |\ekvpProtect|.
+\end{function}
+
+\begin{function}{\ekvpLet}
+ \begin{syntax}
+ \cs{ekvpLet}\marg{parser_1}\marg{type}\marg{name_1}\oarg{parser_2}\marg{name_2}
+ \end{syntax}
+ Copies the definition of a \prefix\ or \type. The \meta{type} should be one of
+ |prefix|, or |type|. The \prefix\ or \type\ \meta{name_1} for \meta{parser_1}
+ will be let equal to the \prefix\ or \type\ \meta{name_2} of \meta{parser_2}.
+ If you omit the optional \meta{parser_2} it will default to \meta{parser_1}.
+\end{function}
+
+
+\subsection{Changing Default Behaviours}
+
+\begin{function}{\ekvpValueAlwaysRequired}
+ \begin{syntax}
+ \cs{ekvpValueAlwaysRequired}\marg{parser}
+ \end{syntax}
+ By default a special no-value marker will be provided for \val\ if no value
+ was given to a key. If this is used instead an error will be thrown that a
+ value is required.
+\end{function}
+
+\begin{function}{\ekvpDefNoValue}
+ \begin{syntax}
+ \cs{ekvpDefNoValue}\marg{parser}\marg{code}
+ \end{syntax}
+ This is a third alternative to the default behaviour and
+ \cs{ekvpValueAlwaysRequired}. With this macro you can stop normal parsing if
+ no value was specified and instead run \meta{code}. Inside of \meta{code} the
+ unprocessed \Nkey\ is available as |#1|. No further processing of this \kv\
+ list element takes place.
+\end{function}
+
+\begin{function}{\ekvpUseNoValueMarker}
+ \begin{syntax}
+ \cs{ekvpUseNoValueMarker}\marg{parser}\marg{marker}
+ \end{syntax}
+ This macro changes the no-value marker from the package default to
+ \meta{marker}. Note that macros like \cs{ekvpAssertValue} don't work with
+ markers different from the default one.
+\end{function}
+
+\begin{function}{\ekvpDefNoValuePrefix}
+ \begin{syntax}
+ \cs{ekvpDefNoValuePrefix}\marg{parser}\marg{pre}\marg{post}
+ \end{syntax}
+ It is also possible to handle \Nkey{}s as if this was some special \prefix.
+ So if a \Nkey\ is encountered you'll have \meta{pre} and \meta{post} put
+ before and behind the \type-action (as the outermost \prefix). The no-value
+ marker will be forwarded as \val. If you want to change a parser's marker and
+ use this you have to use \cs{ekvpUseNoValueMarker} before calling
+ \cs{ekvpDefNoValuePrefix}, and you must not use \cs{ekvpDefNoValue} or
+ \cs{ekvpValueAlwaysRequired} before using \cs{ekvpDefNoValuePrefix} (both
+ result in undefined behaviour).
+\end{function}
+
+\begin{function}{\ekvpDefNoType}
+ \begin{syntax}
+ \cs{ekvpDefNoType}\marg{parser}\marg{code}
+ \end{syntax}
+ This defines an action if no valid \type\ was found, otherwise this behaves
+ like \cs{ekvpDefType} with the same arguments |#1| (\meta{name}), |#2|
+ (unaltered \key), and |#3| (\val) in \meta{code}. If this isn't used for the
+ \meta{parser} instead an error will be thrown whenever no \type\ is found.
+\end{function}
+
+
+\subsection{Markers}
+
+\expkvp\ will place three markers for each list element that was parsed and
+defines an auxiliary to gobble up to that marker. After each marker an
+additional group is placed containing the current list element (excluding the
+\val). The gobblers gobble that group as well. Those markers are:
+
+\begin{function}{\ekvpEOP,\ekvpGobbleP}
+ Is placed after all the \prefix{}es' \meta{pre} code, directly before the
+ \type-action.
+\end{function}
+
+\begin{function}{\ekvpEOT,\ekvpGobbleT}
+ Is placed after the \type-action, directly before the last \prefix's
+ \meta{post} code.
+\end{function}
+
+\begin{function}{\ekvpEOA,\ekvpGobbleA}
+ Is placed at the end of the complete result of the current element, so after
+ all the \prefix{}es' \meta{post} code.
+\end{function}
+
+
+\subsection{Helpers in Actions}
+
+\begin{function}{\ekvpIfNoVal}
+ \begin{syntax}
+ \cs{ekvpIfNoVal}\marg{arg}\marg{true}\marg{false}
+ \end{syntax}
+ This will expand to \meta{true} if the \meta{arg} is the special no-value
+ marker, otherwise \meta{false} is left in the input stream.
+\end{function}
+
+\begin{function}{\ekvpAssertIf,\ekvpAssertIfNot}
+ \begin{syntax}
+ \cs{ekvpAssertIf}\oarg{marker}\marg{if}\marg{message}
+ \end{syntax}
+ This macro will run the \TeX-if test specified by \meta{if} (should expand to
+ any \TeX-style if, e.g., \cs[no-index]{iftrue} or
+ \cs[no-index]{ifx}\meta{A}\meta{B}). If the test is true everything's fine,
+ else an error message is thrown using \meta{message} followed by the current
+ element and everything up to \meta{marker} is gobbled (\meta{marker} can be
+ any of |EOT|, which is the default, |EOP|, or |EOA|). The |Not| variant will
+ invert the logic, so if the \TeX-style if is true this will throw the error.
+\end{function}
+
+\begin{function}{\ekvpAssertTF,\ekvpAssertTFNot}
+ \begin{syntax}
+ \cs{ekvpAssertTF}\oarg{marker}\marg{if}\marg{message}
+ \end{syntax}
+ This is pretty similar to \cs{ekvpAssertIf}, but \meta{if} should be a test
+ that uses its first argument if it's true and its second otherwise (so an
+ error is thrown if the second argument is used, nothing happens otherwise).
+ The |Not| variant is again inversed.
+\end{function}
+
+\begin{function}{\ekvpAssertValue,\ekvpAssertNoValue}
+ \begin{syntax}
+ \cs{ekvpAssertValue}\oarg{marker}\marg{arg}
+ \end{syntax}
+ Asserts that \meta{arg} is not the no-value marker (\cs{ekvpAssertValue}) or
+ is the no-value marker (\cs{ekvpAssertNoValue}), otherwise throws an error and
+ gobbles everything up to \meta{marker} (like \cs{ekvpAssertIf}).
+\end{function}
+
+\begin{function}{\ekvpAssertOneValue,\ekvpAssertTwoValues}
+ \begin{syntax}
+ \cs{ekvpAssertOneValue}\oarg{marker}\marg{arg}
+ \end{syntax}
+ Asserts that \meta{arg} contains exactly one or two values (which could both
+ be either single tokens or braced groups -- spaces between the two values in
+ the \cs{ekvpAssertTwoValues} case are ignored), if the number of values
+ doesn't match an error is thrown and everything up to \meta{marker} gobbled.
+\end{function}
+
+\begin{function}{\ekvpProtect}
+ \begin{syntax}
+ \cs{ekvpProtect}\marg{code}
+ \end{syntax}
+ This macro protects \meta{code} from further expanding in every context a
+ |\protected| macro wouldn't expand. It needs at least two steps of expansion.
+ When a |\protected| macro would expand this will remove the braces around
+ \meta{code} and \TeX\ will process \meta{code} the same way it normally would.
+ After the first step of expansion it'll leave two macros, and after each
+ further full expansion these two macros stay there. Since \expkvp\ offers no
+ method to define \prefixes\ or \types\ |\protected| you can instead use this
+ macro. But if your parser needs any assignments you should nest the
+ |\ekvpParse| call in a |\protected| macro anyway.
+\end{function}
+
+\subsection{Using Parsers}
+
+\begin{function}{\ekvpParse}
+ \begin{syntax}
+ \cs{ekvpParse}\marg{parser}\kvarg
+ \end{syntax}
+ Parses the \kv\ list as defined for \meta{parser}. This expands in exactly two
+ steps, and returns inside of |\unexpanded|, so doesn't expand any further in
+ an |\edef| or |\expanded|. After the two steps it'll directly leave the code
+ as though every \prefix's \meta{pre} and \meta{post} code and the \type-action
+ were input directly along with the different markers.
+\end{function}
+
+\subsection{The Boring Macros}
+Just for the sake of completeness.
+\begin{function}{\ekvpDate,\ekvpVersion}
+ Store the date and version, respectively.
+\end{function}
+
+\subsection{Examples}
+\begin{example}{Defining a parser similar to \expkvd}
+ \ekvset{enverb}{store,no-tcb}%
+ Let's define a parser that is similar to \expkvd's |\ekvdefinekeys|. First we
+ define a new parser named |exdef|:
+ \begin{enverb}
+ \ekvpNewParser{exdef}
+ \end{enverb}
+ We'll need to provide our prefixes, |long| and |protected|. The following
+ initialises them and defines their action.
+ \begin{enverb}
+ \newcommand*\exLong{}
+ \newcommand*\exProtected{}
+ \ekvpDefPrefixLet{exdef}{long}\exLong\long\empty
+ \ekvpDefPrefixLet{exdef}{protected}\exProtected\protected\empty
+ \end{enverb}
+ Now we define a few types, I'll go with |noval|, |store|, and |code| for
+ starters. We exploit the fact that |\ekvdef| and |\ekvdefNoVal| will expand
+ the first argument, so we can simply store the set name in a macro.
+ \begin{enverb}
+ \ekvpDefType{exdef}{code}
+ {%
+ \ekvpAssertValue{#3}%
+ \exProtected\exLong\ekvdef\exSetName{#1}{#3}%
+ }
+ \ekvpDefType{exdef}{noval}
+ {%
+ \ekvpAssertValue{#3}%
+ \ekvpAssertIfNot{\ifx\exLong\long}{`long' not accepted}%
+ \exProtected\ekvdefNoVal\exSetName{#1}{#3}%
+ }
+ \ekvpDefType{exdef}{store}
+ {%
+ \ekvpAssertOneValue{#3}%
+ \ifdefined#3\else
+ \let#3\empty
+ \fi
+ \protected\exLong\ekvdef\exSetName{#1}{\edef#3{\unexpanded{##1}}}%
+ }
+ \end{enverb}
+ Now we need a user facing macro that puts the pieces together (this uses
+ |\NewDocumentCommand| instead of |\newcommand| because the former defines
+ macros |\protected|).
+ \begin{enverb}
+ \NewDocumentCommand\exdefinekeys{m +m}
+ {\def\exSetName{#1}\ekvpParse{exdef}{#2}}
+ \end{enverb}
+ Now we got that sorted so we can use our little parser:
+ \ekvset{enverb}{no-store,undo-no-tcb}%
+ \begin{enverb}[restore]
+ \newif\ifbar
+ \exdefinekeys{exampleset}
+ {
+ long store foo = \myfoo
+ ,protected noval bar = \bartrue
+ ,code baz = baz was called with \detokenize{#1}
+ }
+ \ekvset{exampleset}{foo=Foobar,bar,baz=\empty}
+ \ifbar bar was true so: \myfoo\fi
+ \end{enverb}
+\end{example}
+
+\begin{example}{Visualising the expandability of \cs[no-index]{ekvpParse}}
+ \ekvset{enverb}{store,no-tcb}%
+ With this example we want to take a closer look at the expansion of
+ |\ekvpParse|. So please bear with me if this doesn't make much sense
+ otherwise. One of the issues is that \prefixes\ are a somewhat unordered
+ concept, and only \types\ must come last. We could juggle with flags (an
+ expandable data-storage, see \autoref{sec:c:flags}) to overcome this somehow
+ just to define some pseudo-syntax here, but I guess that's not worth it.
+ Anyhow, here goes nothing.\par
+ First we need a parser
+ \begin{enverb}
+ \ekvpNewParser{exexp}
+ \end{enverb}
+ and a \prefix. We could define one that ensures the name starts of with
+ a letter. We also want each element to start a new line, which we do using an
+ auto prefix.
+ \begin{enverb}
+ \newcommand\ifletter{}
+ \long\def\ifletter#1#2\stop{\ifcat a\noexpand#1}
+ \ekvpDefPrefix{exexp}{letter}
+ {\ekvpAssertIf{\ifletter#2\stop}{not a letter}}
+ { (really a letter)}
+ \ekvpDefAutoPrefix{exexp}{\noindent}{\par}
+ \end{enverb}
+ Finally we define a \type\ and a |NoType| rule:
+ \begin{enverb}
+ \ekvpDefType{exexp}{*}{$#1\cdot#3 = \the\numexpr#1*#3\relax$}
+ \ekvpDefNoType{exexp}{the #3th letter is #1}
+ \end{enverb}
+ Now we want to see whether the thing is expandable:
+ \ekvset{enverb}{no-store,undo-no-tcb}%
+ \begin{enverb}[restore,below]
+ \raggedright
+ \edef\foo{\ekvpParse{exexp}{letter e = 5, * 4 = \empty3}}
+ 1st full expansion
+ \texttt{\meaning\foo}\par
+ \medskip
+ \edef\foo{\foo}
+ 2nd full expansion
+ \texttt{\meaning\foo}\par
+ \medskip
+ \foo
+ \end{enverb}
+\end{example}
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/preamble-enverb.tex b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-enverb.tex
new file mode 100644
index 00000000000..22f39cd31cc
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-enverb.tex
@@ -0,0 +1,348 @@
+\RequirePackage{expkv-def}
+
+\ExplSyntaxOn
+\cs_new_eq:NN \enverb@count \tl_count:n
+\cs_set:Npx \enverb@othercr { \char_generate:nn {13} {12} }
+\ExplSyntaxOff
+%% key setup
+\ekvdefinekeys{enverb}
+ {
+ boolTF auto-ignore = \enverb@ifautoignore
+ ,initial auto-ignore
+ ,protected code ignore = \let\enverb@ifautoignore\@secondoftwo
+ ,eint more-ignore = \enverb@moreignore
+ ,initial more-ignore = 2
+ ,also eint ignore = \enverb@ignore
+ ,boolTF same-line = \enverb@ifsameline
+ ,unknown-choice same-line =
+ \let\enverb@ifsameline\@firstoftwo\edef\enverb@codeshare{\unexpanded{#1}}
+ ,initial same-line = 0.75
+ ,invboolTF other-line = \enverb@ifsameline
+ ,nmeta below = {same-line=false, no-aboveskip, no-belowskip}
+ ,nmeta undo-below = {same-line=true, aboveskip, belowskip}
+ ,store same-line-lst = \enverb@options@lst@same
+ ,store same-line-tcb = \enverb@options@tcb@same
+ ,initial same-line-lst = {aboveskip=0pt,belowskip=0pt}
+ ,initial same-line-tcb = {nobeforeafter,box align=center}
+ ,store other-line-lst = \enverb@options@lst@other
+ ,store other-line-tcb = \enverb@options@tcb@other
+ ,meta slst = same-line-lst={#1}
+ ,meta stcb = same-line-tcb={#1}
+ ,meta olst = other-line-lst={#1}
+ ,meta otcb = other-line-tcb={#1}
+ ,store lst = \enverb@options@lst
+ ,store tcb = \enverb@options@tcb
+ ,long store bol = \enverb@bol@content
+ ,long store eol = \enverb@eol@content
+ ,einitial eol = \enverb@othercr
+ ,boolTF no-lst = \enverb@ifno@lst
+ ,also nmeta no-lst = below
+ ,boolTF no-tcb = \enverb@ifno@tcb
+ ,also nmeta no-tcb = below
+ ,nmeta undo-no-tcb = {no-tcb=false, undo-below}
+ ,store inter = \enverb@inter
+ ,data gappend = \enverb@append
+ ,dataT pre-tcb = \enverb@pretcb
+ ,store after = \enverb@after
+ ,nmeta store = gappend=\enverb@store
+ ,noval no-store = \let\enverb@append\@secondoftwo
+ ,nmeta restore = {pre-tcb=\enverb@store,after=\enverb@clear@store}
+ ,code aboveskip = \edef\enverb@aboveskip{\vskip\unexpanded{#1}\relax}
+ ,code belowskip = \edef\enverb@belowskip{\vskip\unexpanded{#1}\relax}
+ ,default aboveskip = \medskipamount
+ ,default belowskip = \medskipamount
+ ,initial aboveskip
+ ,initial belowskip
+ ,noval no-aboveskip = \let\enverb@aboveskip\@empty
+ ,noval no-belowskip = \let\enverb@belowskip\@empty
+ }
+\protected\long\ekvsetdef\enverbsetup{enverb}
+\protected\def\enverb@clear@store{\global\let\enverb@store\@empty}
+\enverb@clear@store
+
+%% start of nested environments
+\newcommand\enverb@tcb
+ {%
+ \expanded
+ {%
+ \noexpand\begin{exresult}%
+ [{%
+ \enverb@options@tcb,%
+ \enverb@ifsameline\enverb@options@tcb@same\enverb@options@tcb@other
+ }]%
+ }%
+ {\linewidth\enverb@ifsameline{-\enverb@codeshare\linewidth}{}}%
+ }
+\newcommand\enverb@lst
+ {%
+ \expanded
+ {%
+ \noexpand\begin{lstlisting}%
+ [{%
+ \enverb@options@lst,%
+ \enverb@ifsameline\enverb@options@lst@same\enverb@options@lst@other
+ }]%
+ }%
+ }
+
+%% auxiliary error function
+\newcommand\enverb@error[1]
+ {%
+ \GenericError
+ {(enverb)\@spaces\@spaces\@spaces\@spaces}%
+ {Environment enverb error: #1}%
+ {Just use it correctly!}%
+ {Read the sources.}%
+ }
+
+%% setup for weird category code regime
+\begingroup
+\lccode`\~=`\^^M
+\catcode`\:=13
+\lccode`\:=`\ % <- space
+\catcode`\;=13
+\lccode`\;=`\^^I % <- tab
+\lowercase{\endgroup
+%% code for spaces and CR
+\def\enverb@body@space{}%
+\def\enverb@body@tab{}%
+\def\enverb@body@newline#1~%
+ {\enverb@ifnotend{#1}{\enverb@bol\unexpanded{#1}\enverb@eol~}}%
+%% activate the category code regime of the body
+\protected\def\enverb@body@setup
+ {%
+ \let\enverb@collected@body\@empty
+ \let\do\@makeother\dospecials
+ \catcode`\^^M=13 \let~\enverb@body@newline
+ \catcode`\ =13 \let:\enverb@body@space
+ \catcode`\^^I=13 \let;\enverb@body@tab
+ \let\enverb@bol\relax
+ \let\enverb@eol\relax
+ }
+%% check for optional argument
+\newcommand\enverb@search@oarg@a
+ {%
+ \ifx:\next
+ \ifenverb@firsteol
+ \else
+ \enverb@body@add{:}%
+ \fi
+ \let\next\enverb@search@oarg@b
+ \else
+ \ifx~\next
+ \ifenverb@firsteol
+ \enverb@firsteolfalse
+ \else
+ \enverb@body@add{~}%
+ \fi
+ \let\next\enverb@search@oarg@b
+ \else
+ \ifx[\next\@gobble]%
+ \let\next\enverb@oarg
+ \else
+ \ifenverb@firsteol
+ \let\next\enverb@body@after@begin
+ \else
+ \let\next\enverb@body
+ \fi
+ \fi
+ \fi
+ \fi
+ \next
+ }
+%% start body collection
+\newcommand\enverb@body
+ {\edef\enverb@collected@body{\iffalse}\fi\expandafter~\enverb@collected@body}
+%% check the line after an oarg
+\def\enverb@body@after@oarg#1~%
+ {\enverb@ensure@blank{#1}{closing bracket}\enverb@body}
+%% check the line after the \begin statement
+\def\enverb@body@after@begin#1~%
+ {\enverb@ensure@blank{#1}{\string\begin}\enverb@body}
+}
+%% quick check for empty line
+\newcommand\enverb@ensure@blank[2]
+ {%
+ \expandafter\enverb@ifempty\expanded{{#1}}{}%
+ {%
+ \expanded{%
+ \noexpand\enverb@error
+ {%
+ Line after #2 not empty.\noexpand\MessageBreak
+ Contains: \detokenize\expandafter{\romannumeral`\^^@#1}%
+ }%
+ }%
+ }%
+ }
+%% quick check for empty argument
+\newcommand\enverb@ifempty[1]
+ {%
+ \enverb@ifempty@\enverb@ifempty@A#1\enverb@ifempty@B.\enverb@ifempty@true
+ \enverb@ifempty@A\enverb@ifempty@B
+ }
+\def\enverb@ifempty@#1\enverb@ifempty@A\enverb@ifempty@B#2#3{#3}
+\def\enverb@ifempty@true\enverb@ifempty@A\enverb@ifempty@B#1#2{#1}
+\newcommand\enverb@gadd[2]{\xdef#1{\unexpanded\expandafter{#1#2}}}
+\newcommand\enverb@body@add[1]
+ {%
+ \edef\enverb@collected@body
+ {\unexpanded\expandafter{\enverb@collected@body#1}}%
+ }
+% start of environment `enverb'
+\newcommand\enverb
+ {%
+ \begingroup
+ \def\tmp{enverb}%
+ \expandafter
+ \endgroup
+ \expandafter\enverb@ifnotend@setup@perhaps\expanded
+ {{\string{\@currenvir\string}}}%
+ \begingroup
+ \enverb@body@setup
+ \enverb@firsteoltrue
+ \let\enverb@collected@oarg\@empty
+ \enverb@search@oarg
+ }
+\newif\ifenverb@firsteol
+\newcommand\enverb@search@oarg{\futurelet\next\enverb@search@oarg@a}
+\newcommand\enverb@search@oarg@b{\expandafter\enverb@search@oarg\@gobble}
+\newcommand\enverb@oarg{\endgroup\enverb@oarg@}
+\NewDocumentCommand\enverb@oarg@{O{}}
+ {%
+ \edef\enverb@collected@oarg{\unexpanded{#1}}%
+ \begingroup
+ \enverb@body@setup
+ \enverb@body@after@oarg
+ }
+\def\enverb@ifnotend#1%
+ {%
+ \def\enverb@ifnotend##1%
+ {%
+ \enverb@ifnotend@
+ ##1\enverb@mark\enverb@ifnotend@maybe
+ #1\enverb@mark\@thirdofthree
+ \enverb@stop
+ }%
+ \def\enverb@ifnotend@##1#1##2\enverb@mark##3##4\enverb@stop{##3{##1}{##2}}%
+ }
+\expandafter\enverb@ifnotend\expanded{{\expandafter\@gobble\string\\end}}
+\newcommand\enverb@ifnotend@maybe[2]
+ {\expandafter\enverb@ifnotend@perhaps\expandafter{\romannumeral`\^^@#2}{#1}}
+\newcommand\enverb@ifnotend@setup@perhaps[1]
+ {%
+ \def\enverb@ifnotend@perhaps##1%
+ {%
+ \enverb@ifnotend@perhaps@\enverb@mark##1\enverb@mark\enverb@ifnotend@end
+ \enverb@mark#1\enverb@mark\@thirdofthree
+ \enverb@stop
+ }%
+ \def\enverb@ifnotend@perhaps@
+ ##1\enverb@mark#1##2\enverb@mark##3##4\enverb@stop
+ {##3{##2}}%
+ }
+\providecommand\@thirdofthree[3]{#3}
+\outer\def\myabsolutestop{\stop}
+\newcommand\enverb@ifnotend@end[3]
+ {%
+ \iffalse{\fi}%
+ \enverb@ensure@blank{#1}{\string\end}%
+ \expanded
+ {%
+ \endgroup
+ \enverbsetup
+ {\unexpanded\expandafter{\enverb@collected@oarg}}%
+ \noexpand\enverb@output
+ {\unexpanded\expandafter{\enverb@collected@body}}%
+ }%
+ {#2}%
+ \expandafter\end\expandafter{\@currenvir}%
+ }
+\long\def\enverb@output#1#2%
+ {%
+ \enverb@ifautoignore
+ {\enverb@setup@ignore{\enverb@count{#2}+\enverb@moreignore}}%
+ {\enverb@setup@ignore\enverb@ignore}%
+ \edef\enverb@line##1\enverb@eol
+ {%
+ \noexpand\detokenize{##1}%
+ \noexpand\unexpanded{\unexpanded\expandafter{\enverb@eol@content}}%
+ }%
+ \edef\enverb@collected@body{#1}%
+ \expanded
+ {\unexpanded{\enverb@append\enverb@gadd\@gobble}\expandafter}%
+ \expandafter{\enverb@collected@body}%
+ \par
+ \enverb@aboveskip
+ \enverb@ifno@lst{}%
+ {%
+ \enverb@ifsameline
+ {\noindent\begin{minipage}[c]{\enverb@codeshare\linewidth}}%
+ {}%
+ \begingroup
+ \everyeof{\noexpand}%
+ \expandafter
+ \endgroup
+ \scantokens\expanded
+ {{%
+ \noexpand\csname enverb@lst\endcsname
+ \enverb@othercr
+ \enverb@collected@body
+ \string\end{lstlisting}\enverb@othercr
+ }}%
+ \enverb@ifsameline{\end{minipage}}{}%
+ }%
+ \enverb@inter
+ \enverb@ifno@tcb{}%
+ {%
+ \begingroup
+ \everyeof{\noexpand}%
+ \newlinechar=\endlinechar
+ \expandafter
+ \endgroup
+ \scantokens\expanded
+ {{%
+ \noexpand\csname enverb@tcb\endcsname
+ \enverb@pretcb{\unexpanded\expandafter}%
+ \enverb@collected@body
+ \noexpand\end{exresult}%
+ }}%
+ }%
+ \par
+ \enverb@belowskip
+ \enverb@after
+ \@endpetrue
+ }
+\providecommand\@firstofnine[9]{#1}
+\newcommand\enverb@setup@ignore[1]
+ {\expandafter\enverb@setup@ignore@\the\numexpr#1\relax;\enverb@line}
+\def\enverb@setup@ignore@#1;#2%
+ {%
+ \ifnum#1>9
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {\expandafter\enverb@setup@ignore@\the\numexpr#1-8;{\@firstofnine{#2}}}%
+ {%
+ \let\enverb@bol@gobble\@empty % just so that renewcommand doesn't go nuts
+ \expanded
+ {%
+ \unexpanded{\renewcommand\enverb@bol@gobble}\ifnum#1>\z@[#1]\fi
+ {%
+ \noexpand\unexpanded
+ {\unexpanded\expandafter{\enverb@bol@content}}%
+ \unexpanded{#2}%
+ }%
+ \unexpanded{\def\enverb@bol##1\enverb@eol}%
+ {%
+ \noexpand\unexpanded
+ {\unexpanded\expandafter{\enverb@bol@content}}%
+ \unexpanded{\expandafter\enverb@ifempty\expanded}{{##1}}%
+ {\noexpand\enverb@line}%
+ {\noexpand\enverb@bol@gobble}%
+ ##1\unexpanded{\enverb@eol}%
+ }%
+ }%
+ }%
+ }
+\let\endenverb\@empty
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/preamble-examples.tex b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-examples.tex
new file mode 100644
index 00000000000..5a146d9eb6b
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-examples.tex
@@ -0,0 +1,16 @@
+\makeatletter
+\newcounter{example}[section]
+\newcommand*\example[1]
+ {%
+ \par\smallskip
+ \refstepcounter{example}%
+ \addcontentsline{exs}{example}{#1}%
+ \noindent\textit{Example:} \ignorespaces
+ }
+\newcommand*\l@example{\@dottedtocline{0}{1.5em}{2.3em}}
+\newcommand\listofexamples
+ {%
+ \addsec{List of Examples}%
+ \@starttoc{exs}%
+ }
+\makeatother
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/preamble-l3doctweaks.tex b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-l3doctweaks.tex
new file mode 100644
index 00000000000..47d2c744a52
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-l3doctweaks.tex
@@ -0,0 +1,39 @@
+\ExplSyntaxOn
+\cs_new_protected:Npn \__expkvdoc_patchfootnote:% >>=
+ {
+ \cs_set:Npx \footnote
+ {
+ \exp_not:n { \ClassError {expkvdoc} {Footnote~ in~ function} {} }
+ \exp_not:o { \footnote }
+ }
+ }% =<<
+\AddToHook{env/function/begin}{\__expkvdoc_patchfootnote:}
+
+\group_begin:
+\cs_set_protected:Npn \__expkvdoc_tmp:nN #1#2
+ {
+ \__kernel_tl_set:Nx #2 { \tl_to_str:n {#1} }
+ \tl_replace_all:Nxn #2 { \c_underscore_str } { / }
+ \tl_remove_all:Nx #2 { \c_backslash_str }
+ \tl_put_left:Nn #2 { doc/function// }
+ }
+\cs_if_eq:NNTF \__expkvdoc_tmp:nN \__codedoc_get_hyper_target:nN
+ {
+ \cs_gset:Npn \__codedoc_get_hyper_target:nN #1#2
+ {
+ \__kernel_tl_set:Nx #2 { \tl_to_str:n {#1} }
+ \tl_replace_all:Nxn #2 { \c_underscore_str } { / }
+ \tl_remove_all:Nx #2 { \c_backslash_str }
+ \tl_put_left:Nx #2 { doc/function/ \g__expkvdoc_module_str / }
+ }
+ }
+ {
+ \ClassWarning{expkvdoc}
+ {
+ Didn't~ patch~ l3doc's~ hyper~ targets.~ You~ might~ get~ duplicate~
+ labels.
+ }
+ }
+\group_end:
+
+\ExplSyntaxOff
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/preamble-logos.tex b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-logos.tex
new file mode 100644
index 00000000000..f5c963134c8
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-logos.tex
@@ -0,0 +1,107 @@
+\definecolor{ekvred}{HTML}{9F393D}
+\colorlet{ekvgrey}{black!75}
+\makeatletter
+\newcommand*\kvstyle%>>=
+ {\normalfont\rmfamily\bfseries\color{ekvred}}%=<<
+\newcommand*\expFormat % used for the title only >>=
+ {%
+ {%
+ \rmfamily
+ \bfseries
+ {\color{ekvgrey}e\kern-.05em x\kern-.05em}%
+ \lower.493ex\hbox{{\color{ekvgrey}P}}%
+ }%
+ }%=<<
+\newcommand\expnotation% >>=
+ {%
+ \begingroup
+ \BeginAccSupp{ActualText=exp|notation,E=expansion-notation}%
+ \rmfamily
+ \bfseries
+ \color{ekvgrey}%
+ e\kern-.05em x\kern-.05em%
+ \lower.493ex\hbox{{\color{ekvgrey}P}}%
+ \kern-.05em:%
+ \kern.05em\textsc{notation}%
+ \EndAccSupp{}%
+ \endgroup
+ }% =<<
+\newcommand\expkvLogoFormat[1]% >>=
+ {%
+ \begingroup
+ \rmfamily
+ \bfseries
+ {\color{ekvgrey}e\kern-.05em x\kern-.05em}%
+ \lower.493ex\hbox{{\color{ekvgrey}P}\kern-.1em{\color{ekvred}k}}%
+ \kern-.18em{\color{ekvred}v}%
+ \IfValueT{#1}
+ {%
+ \begingroup
+ \color{ekvgrey}%
+ \kern.05em\rule[-.1ex]{.08em}{1.2ex}%
+ \kern.05em\textsc{#1}%
+ \endgroup
+ }%
+ \endgroup
+ }% =<<
+\NewDocumentCommand \expkvLogo { o }%>>=
+ {%
+ \mbox
+ {%
+ \BeginAccSupp{ActualText=expkv\IfValueT{#1}{-#1}}%
+ \ifodd\ekvdoc@insection
+ \href{https://gitlab.com/islandoftex/texmf/expkv-bundle}%
+ {\expkvLogoFormat{#1}}%
+ \else
+ \hyperref[sec:expkv\IfValueT{#1}{-#1}]{\expkvLogoFormat{#1}}%
+ \fi
+ \EndAccSupp{}%
+ }%
+ }%=<<
+\newcommand*\expkv%>>=
+ {%
+ \texorpdfstring
+ {\expkvLogo}
+ {expkv}%
+ }%=<<
+\newcommand*\expkvpkg[1]%>>=
+ {%
+ \texorpdfstring
+ {\expkvLogo[{#1}]}%
+ {expkv-#1}%
+ }%=<<
+\newcommand*\expkvbundle% >>=
+ {%
+ \texorpdfstring
+ {\begingroup\chardef\ekvdoc@insection1 \expkvpkg{bundle}\endgroup}%
+ {\expkvpkg{bundle}}%
+ }% =<<
+\newcommand*\expkvc{\expkvpkg{cs}}
+\newcommand*\expkvd{\expkvpkg{def}}
+\newcommand*\expkvo{\expkvpkg{opt}}
+\newcommand*\expkvp{\expkvpkg{pop}}
+\ExplSyntaxOn
+\cs_new_protected:Npn \pkglogo #1%>>=
+ {
+ \texorpdfstring
+ {
+ \mbox
+ {
+ \BeginAccSupp{ActualText=#1}
+ \rmfamily
+ \str_case:nn {#1}
+ {
+ {yax}
+ {
+ Y\kern-.1em
+ \raise.15em\hbox{\scshape a}
+ \kern-.1em \lower.15em\hbox{X}%
+ }
+ }
+ \EndAccSupp{}
+ }
+ }
+ {#1}
+ }%=<<
+\newcommand*\yax{\pkglogo{yax}}
+\ExplSyntaxOff
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/preamble-lst.tex b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-lst.tex
new file mode 100644
index 00000000000..a94920bfffa
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-lst.tex
@@ -0,0 +1,218 @@
+\def\mylstwd{.55em}
+\lstdefinelanguage{expkv}[primitive]{TeX}
+ {
+ ,moretexcs=[2]% e-TeX
+ {
+ expanded,
+ numexpr,
+ protected,
+ unexpanded,
+ ifdefined,
+ detokenize,
+ }
+ ,moretexcs=[3]% plain/LaTeX/ConTeXt
+ {
+ approx,
+ begin,end,
+ cdot,
+ emph,empty,
+ item,
+ LaTeX,
+ makeatletter,makeatother,multicolumn,
+ newcommand,renewcommand,newdimen,newif,newcount,NewDocumentCommand,
+ usepackage,RequirePackage,ProvidesPackage,
+ raggedright,
+ rule,
+ space,stop,
+ smallskip,medskip,bigskip,
+ TeX,
+ textit,texttt,
+ usepackage,
+ usemodule,
+ @gobble,@gobbletwo,@firstofone,@empty,
+ ExplSyntaxOn,ExplSyntaxOff,
+ }
+ ,moretexcs=[4]% used packages
+ {
+ % xfp
+ fpeval,
+ % keyval
+ setkeys,
+ % kvsetkeys
+ kvsetkeys,
+ % color
+ textcolor,
+ % yax
+ defactiveparameter,storevalue,setparameterlist,
+ % graphics
+ includegraphics,
+ }
+ ,moretexcs=[5]% expkv macros
+ {
+ ekvdef,ekvdefNoVal,%
+ ekvlet,ekvletNoVal,ekvletkv,ekvletkvNoVal,%
+ ekvdefunknown,ekvdefunknownNoVal,%
+ ekvletunknown,ekvletunknownNoVal,%
+ ekvredirectunknown,ekvredirectunknownNoVal,%
+ ekvset,ekvsetSneaked,%
+ ekvsetdef,ekvsetSneakeddef,ekvsetdefSneaked,%
+ ekvcompile,%
+ ekvparse,%
+ ekvVersion,ekvDate,%
+ ekvifdefined,ekvifdefinedNoVal,ekvifdefinedset,%
+ ekvbreak,ekvbreakPreSneak,ekvbreakPostSneak,%
+ ekvsneak,ekvsneakPre,%
+ ekvchangeset,%
+ ekvmorekv,%
+ ekvoptarg,ekvoptargTF,%
+ ekvcsvloop,%
+ ekverr,%
+ ekv@name,%
+ }
+ ,moretexcs=[6]% expkv-cs macros
+ {
+ ekvcSecondaryKeys,%
+ ekvcSplit,ekvcSplitAndForward,ekvcSplitAndUse,%
+ ekvcHash,ekvcHashAndForward,ekvcHashAndUse,%
+ ekvcValue,ekvcValueFast,ekvcValueSplit,ekvcValueSplitFast,%
+ ekvcChange,%
+ ekvcPass,%
+ }
+ ,moretexcs=[7]% expkv-def macros
+ {
+ ekvdefinekeys
+ }
+ ,moretexcs=[8]% expkv-pop macros
+ {
+ ekvpNewParser,
+ ekvpDefType,
+ ekvpDefPrefix,ekvpDefAutoPrefix,ekvpDefPrefixStore,ekvpDefPrefixLet,
+ ekvpLet,
+ ekvpValueAlwaysRequired,ekvpDefNoValue,ekvpUseNoValueMarker,
+ ekvpDefNoValuePrefix,ekvpDefNoType,ekvpDefNoValue,
+ ekvpEOP,ekvpGobbleP,ekvpEOT,ekvpGobbleT,ekvpEOA,ekvpGobbleA,
+ ekvpIfNoVal,
+ ekvpAssertIf,ekvpAssertIfNot,ekvpAssertTF,ekvpAssertTFNot,
+ ekvpAssertValue,ekvpAssertNoValue,
+ ekvpAssertOneValue,ekvpAssertTwoValues,
+ ekvpParse,
+ }
+ ,moretexcs=[9]% expkv-opt macros
+ {
+ ekvoProcessOptions,%
+ ekvoProcessLocalOptions,ekvoProcessGlobalOptions,%
+ ekvoProcessFutureOptions,ekvoProcessOptionsList,%
+ ekvoUseUnknownHandlers,%
+ ekvoVersion,ekvoDate,%
+ }
+ ,alsoletter={_:}
+ ,moretexcs=[10]% expl3
+ {
+ cs_new_eq:NN,
+ tl_count_tokens:n,
+ }
+ }
+\colorlet{codeparam}{cyan!65!black}
+\lstdefinestyle{expkv}
+ {
+ texcsstyle=*[5]{\bfseries\color{ekvred}} % expkv
+ ,texcsstyle=*[6]{\color{ekvred}} % expkv-cs
+ ,texcsstyle=*[7]{\color{ekvred}} % expkv-def
+ ,texcsstyle=*[8]{\color{ekvred}} % expkv-pop
+ ,texcsstyle=*[9]{\color{ekvred}} % expkv-opt
+ }
+\lstdefinestyle{expkv-cs}
+ {
+ texcsstyle=*[5]{\color{ekvred}} % expkv
+ ,texcsstyle=*[6]{\bfseries\color{ekvred}} % expkv-cs
+ ,texcsstyle=*[7]{\color{ekvred}} % expkv-def
+ ,texcsstyle=*[8]{\color{ekvred}} % expkv-pop
+ ,texcsstyle=*[9]{\color{ekvred}} % expkv-opt
+ }
+\lstdefinestyle{expkv-def}
+ {
+ texcsstyle=*[5]{\color{ekvred}} % expkv
+ ,texcsstyle=*[6]{\color{ekvred}} % expkv-cs
+ ,texcsstyle=*[7]{\bfseries\color{ekvred}} % expkv-def
+ ,texcsstyle=*[8]{\color{ekvred}} % expkv-pop
+ ,texcsstyle=*[9]{\color{ekvred}} % expkv-opt
+ }
+\lstdefinestyle{expkv-pop}
+ {
+ texcsstyle=*[5]{\color{ekvred}} % expkv
+ ,texcsstyle=*[6]{\color{ekvred}} % expkv-cs
+ ,texcsstyle=*[7]{\color{ekvred}} % expkv-def
+ ,texcsstyle=*[8]{\bfseries\color{ekvred}} % expkv-pop
+ ,texcsstyle=*[9]{\color{ekvred}} % expkv-opt
+ }
+\lstdefinestyle{expkv-opt}
+ {
+ texcsstyle=*[5]{\color{ekvred}} % expkv
+ ,texcsstyle=*[6]{\color{ekvred}} % expkv-cs
+ ,texcsstyle=*[7]{\color{ekvred}} % expkv-def
+ ,texcsstyle=*[8]{\color{ekvred}} % expkv-pop
+ ,texcsstyle=*[9]{\bfseries\color{ekvred}} % expkv-opt
+ }
+\lstdefinestyle{expkv-all}
+ {
+ texcsstyle=*[5]{\bfseries\color{ekvred}} % expkv
+ ,texcsstyle=*[6]{\bfseries\color{ekvred}} % expkv-cs
+ ,texcsstyle=*[7]{\bfseries\color{ekvred}} % expkv-def
+ ,texcsstyle=*[8]{\bfseries\color{ekvred}} % expkv-pop
+ ,texcsstyle=*[9]{\bfseries\color{ekvred}} % expkv-opt
+ }
+\lstset
+ {
+ ,language=expkv
+ ,style=expkv
+ ,flexiblecolumns=false
+ ,basewidth=\mylstwd
+ %,basicstyle=\fontfamily{lmtt}\selectfont
+ %,basicstyle=\fontfamily{GoMono-TLF}\selectfont%\itshape
+ %,basicstyle=\fontfamily{jkp}\selectfont%\itshape
+ %,basicstyle=\fontfamily{jkptt}\selectfont%\itshape
+ ,basicstyle=\fontfamily{txtt}\selectfont%\itshape
+ ,texcsstyle=*[1]{\bfseries\color{ekvgrey}} % primitives
+ ,texcsstyle=*[2]{\bfseries\color{ekvgrey}} % e-TeX
+ ,texcsstyle=*[3]{\bfseries\color{ekvgrey}} % plain/LaTeX macros
+ ,texcsstyle=*[4]{\bfseries\color{ekvgrey}} % macros of other packages
+ ,texcsstyle=*[10]{\bfseries\color{ekvgrey}} % macros of expl3
+ ,commentstyle=\color[gray]{0.4}
+ ,literate=
+ {\{} {{\CodeUpBf\{}}{1}
+ {\}} {{\CodeUpBf\}}}{1}
+ {$} {{\CodeUpBf\$}}{1}
+ {[} {{\CodeUp[}}{1}
+ {]} {{\CodeUp]}}{1}
+ {(} {{\CodeUp(}}{1}
+ {)} {{\CodeUp)}}{1}
+ {*} {{$*$}}{1}
+ {1} {{\CodeUp{1}}}{1}
+ {2} {{\CodeUp{2}}}{1}
+ {3} {{\CodeUp{3}}}{1}
+ {4} {{\CodeUp{4}}}{1}
+ {5} {{\CodeUp{5}}}{1}
+ {6} {{\CodeUp{6}}}{1}
+ {7} {{\CodeUp{7}}}{1}
+ {8} {{\CodeUp{8}}}{1}
+ {9} {{\CodeUp{9}}}{1}
+ {0} {{\CodeUp{0}}}{1}
+ {##} {{\CodeColored{codeparam}{1}{\#}}}{1}
+ {##1}{{\CodeColored{codeparam}{2}{\#1}}}{2}
+ {##2}{{\CodeColored{codeparam}{2}{\#2}}}{2}
+ {##3}{{\CodeColored{codeparam}{2}{\#3}}}{2}
+ {##4}{{\CodeColored{codeparam}{2}{\#4}}}{2}
+ {##5}{{\CodeColored{codeparam}{2}{\#5}}}{2}
+ {##6}{{\CodeColored{codeparam}{2}{\#6}}}{2}
+ {##7}{{\CodeColored{codeparam}{2}{\#7}}}{2}
+ {##8}{{\CodeColored{codeparam}{2}{\#8}}}{2}
+ {##9}{{\CodeColored{codeparam}{2}{\#9}}}{2}
+ {<key>}{{$\langle$}key{$\rangle$}}{5}
+ {<set>}{{$\langle$}set{$\rangle$}}{5}
+ {<set1>}{{$\langle$}set1{$\rangle$}}{6}
+ {<set2>}{{$\langle$}set2{$\rangle$}}{6}
+ %,literate=*{<key>}{\key}{4}{<set>}{\set}{4}
+ }
+\newcommand*\CodeColored[3]{\textcolor{#1}{\makebox[\dimexpr\mylstwd*#2]{#3}}}
+\newcommand*\CodeUpBf[1]{\makebox[\mylstwd]{\textup{\textbf{#1}}}}
+\newcommand*\CodeUp[1]{\makebox[\mylstwd]{\textup{#1}}}
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/preamble-noidx.tex b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-noidx.tex
new file mode 100644
index 00000000000..410db834839
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-noidx.tex
@@ -0,0 +1,50 @@
+\DoNotIndex{\-,\:,\\,\~}
+\DoNotIndex{\advance,\AtEndOfPackage}
+\DoNotIndex{\ClassError,\CurrentOption}
+\DoNotIndex{\DeclareCurrentRelease,\DeclareOption,\DeclareRelease}
+\DoNotIndex{\directlua,\dimexpr}
+\DoNotIndex{\def,\edef,\,,\=,\begingroup,\catcode,\chardef,\csname,\endcsname}
+\DoNotIndex{\endgroup,\endinput,\errmessage,\expandafter,\input,\let,\long}
+\DoNotIndex{\gdef,\global,\glueexpr,\gtoksapp,\gtokspre}
+\DoNotIndex{\hbox}
+\DoNotIndex{\IfFormatAtLeastTF}
+\DoNotIndex{\key}
+\DoNotIndex{\lccode,\lowercase}
+\DoNotIndex{\MessageBreak}
+\DoNotIndex{\N,\newcommand,\newcount,\newtoks,\number,\numexpr}
+\DoNotIndex{\PackageError,\PackageWarning,\ProcessOptions}
+\DoNotIndex{\requestedLaTeXdate,\RequirePackage}
+\DoNotIndex{\setbox}
+\DoNotIndex{\@classoptionslist,\@clsextension,\@currext,\@currname,\@empty}
+\DoNotIndex{\@firstofone,\@firstoftwo,\@gobble,\@gobblethree,\@gobbletwo}
+\DoNotIndex{\@ifstar,\@onlypreamble,\@raw@classoptionslist,\@secondoftwo}
+\DoNotIndex{\@unprocessedoptions,\@unusedoptionlist}
+\DoNotIndex{\pkgcls@parse@date@arg,\pkgcls@targetdate,\pkgcls@targetlabel}
+\DoNotIndex{\protected,\ProvidesFile,\ProvidesPackage,\relax,\space}
+\DoNotIndex{\^,\@,\unexpanded,\string,\expanded,\detokenize,\meaning}
+\DoNotIndex{\lastnamedcs,\romannumeral,\z@}
+\DoNotIndex{\noexpand,\normalexpanded,\normalunexpanded}
+\DoNotIndex{\par,\protect}
+\DoNotIndex{\the,\toksapp,\tokspre}
+\DoNotIndex{\unprotect,\unless,\usemodule}
+\DoNotIndex{\V}
+\DoNotIndex{\writestatus}
+\DoNotIndex{\xdef}
+\DoNotIndex{\Z,\z}
+\DoNotIndex{\ifcsname}
+\DoNotIndex{\if}
+\DoNotIndex{\ifdefined}
+\DoNotIndex{\ifodd}
+\DoNotIndex{\iftrue}
+\DoNotIndex{\ifx}
+\DoNotIndex{\iffalse}
+\DoNotIndex{\ifnum}
+\DoNotIndex{\else}
+\DoNotIndex{\fi}
+\@gobble\fi % ignoring \ifx etc., but only one \fi
+\@gobble\fi % ignoring \ifx etc., but only one \fi
+\@gobble\fi % ignoring \ifx etc., but only one \fi
+\@gobble\fi % ignoring \ifx etc., but only one \fi
+\@gobble\fi % ignoring \ifx etc., but only one \fi
+\@gobble\fi % ignoring \ifx etc., but only one \fi
+\@gobble\fi % ignoring \ifx etc., but only one \fi
diff --git a/Master/texmf-dist/doc/latex/expkv-bundle/preamble-prefixes.tex b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-prefixes.tex
new file mode 100644
index 00000000000..a961fc3f244
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/expkv-bundle/preamble-prefixes.tex
@@ -0,0 +1,36 @@
+\AddToHook{env/syntax/begin}{\let\prefixes\prefixline}
+\newcount\prefixes@num
+\newcommand\enfprefix{\textcolor{black}}
+\newcommand\allprefix{\textcolor{gray}}
+\newcommand\notprefix{\textcolor{red!80!black}}
+\@ifdefinable\prefixline
+ {\protected\def\prefixline{\hfill\afterassignment\prefixes@\prefixes@num=}}
+\ExplSyntaxOn
+\newcommand\prefixes@place[1]
+ {%
+ \numexpr
+ \int_mod:nn { \int_div_truncate:nn \prefixes@num {#1} } { 10 }
+ \relax
+ }
+\ExplSyntaxOff
+\newcommand\printprefix[2]
+ {%
+ \ifcase\prefixes@place{#1}\or
+ \enfprefix{#2}\or
+ \allprefix{#2}\or
+ \notprefix{#2}\fi
+ }
+\protected\def\prefixes@
+ {%
+ \ifnum\prefixes@num>10
+ \printprefix{1000}{new}
+ \printprefix {100}{also}
+ \printprefix {10}{protected}
+ \printprefix {1}{long}%
+ \else
+ \ifcase\prefixes@num\or
+ \enfprefix{long}\or
+ \allprefix{long}\or
+ \notprefix{long}\fi
+ \fi
+ }