summaryrefslogtreecommitdiff
path: root/obsolete
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-01-25 03:01:16 +0000
committerNorbert Preining <norbert@preining.info>2023-01-25 03:01:16 +0000
commit90299d4f0bdde9fb84d583d5c0e923cfe3869132 (patch)
tree18aafa9c8d28266a65ed09979c53c6277b6502ef /obsolete
parentb06c6695162b493aeec3b594c6beb518c15c98ba (diff)
CTAN sync 202301250301
Diffstat (limited to 'obsolete')
-rw-r--r--obsolete/macros/generic/expkv-cs/README.md32
-rw-r--r--obsolete/macros/generic/expkv-cs/expkv-cs.dtx3431
-rw-r--r--obsolete/macros/generic/expkv-cs/expkv-cs.pdfbin470406 -> 0 bytes
-rw-r--r--obsolete/macros/generic/expkv-def/README.md32
-rw-r--r--obsolete/macros/generic/expkv-def/expkv-def.dtx2493
-rw-r--r--obsolete/macros/generic/expkv-def/expkv-def.pdfbin424547 -> 0 bytes
-rw-r--r--obsolete/macros/generic/expkv-opt/README.md29
-rw-r--r--obsolete/macros/generic/expkv-opt/expkv-opt-2020-10-10.dtx938
-rw-r--r--obsolete/macros/generic/expkv-opt/expkv-opt.dtx1012
-rw-r--r--obsolete/macros/generic/expkv-opt/expkv-opt.pdfbin268534 -> 0 bytes
-rw-r--r--obsolete/macros/generic/expkv/README.md35
-rw-r--r--obsolete/macros/generic/expkv/expkv.dtx2980
-rw-r--r--obsolete/macros/generic/expkv/expkv.pdfbin490757 -> 0 bytes
13 files changed, 0 insertions, 10982 deletions
diff --git a/obsolete/macros/generic/expkv-cs/README.md b/obsolete/macros/generic/expkv-cs/README.md
deleted file mode 100644
index 481d94ba34..0000000000
--- a/obsolete/macros/generic/expkv-cs/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
--------------------------------------------------------------------------------
-# expkv-cs -- define expandable key=val macros using expkv
-
-Version 2022-02-13 v1.2
-
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
-
-Hosted at https://github.com/Skillmon/tex_expkv-cs
-
--------------------------------------------------------------------------------
-
-Copyright (C) 2020-2022 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.
-
--------------------------------------------------------------------------------
-
-This provides means to define expandable key=val taking macros utilizing
-[`expkv`](https://github.com/Skillmon/tex_expkv). It is generic code and only
-requires `expkv` for its parsing. There is a LaTeX package `expkv-cs.sty`
-included to play nice on LaTeX's package loading system, but that package is not
-needed and does not provide more functionality than the generic code in
-`expkv-cs.tex`.
diff --git a/obsolete/macros/generic/expkv-cs/expkv-cs.dtx b/obsolete/macros/generic/expkv-cs/expkv-cs.dtx
deleted file mode 100644
index 561dec7af9..0000000000
--- a/obsolete/macros/generic/expkv-cs/expkv-cs.dtx
+++ /dev/null
@@ -1,3431 +0,0 @@
-% \iffalse meta-comment
-%
-% File: expkv-cs.dtx Copyright (C) 2020-2022 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
-%
-% ------------------------------------------------------------------------------
-%
-%<*driver>^^A>>=
-\def\nameofplainTeX{plain}
-\ifx\fmtname\nameofplainTeX\else
- \expandafter\begingroup
-\fi
-\input l3docstrip.tex
-\askforoverwritefalse
-\preamble
-
---------------------------------------------------------------
-expkv-cs -- define expandable key=val macros using expkv
-E-mail: jspratte@yahoo.de
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
---------------------------------------------------------------
-
-Copyright (C) 2020-2022 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.
-
-This work consists of the file expkv-cs.dtx
-and the derived files expkv-cs.pdf
- expkv-cs.sty
- expkv-cs.tex
- t-expkv-cs.tex
-
-\endpreamble
-% stop docstrip adding \endinput
-\postamble
-\endpostamble
-\generate{\file{expkv-cs.sty}{\from{expkv-cs.dtx}{pkg}}}
-\generate{\file{expkv-cs.tex}{\from{expkv-cs.dtx}{tex}}}
-\generate{\file{t-expkv-cs.tex}{\from{expkv-cs.dtx}{ctx}}}
-\ifx\fmtname\nameofplainTeX
- \expandafter\endbatchfile
-\else
- \expandafter\endgroup
-\fi
-%
-\IfFileExists{expkv-cs.tex}{\input{expkv-cs.tex}}{}
-\ProvidesFile{expkv-cs.dtx}
- [\csname ekvcDate\endcsname\ define expandable key=val macros using expkv]
-\PassOptionsToPackage{full}{textcomp}
-\documentclass{l3doc}
-\RequirePackage[oldstylenums,nott]{kpfonts}
-\input{glyphtounicode}
-\pdfgentounicode=1
-\RequirePackage{tcolorbox}
-\newtcolorbox{exresult}[2][]
- {colback=expkvgrey!10!white,colframe=expkvgrey,fontupper=\small,width={#2},#1}
-\newtcbox\exres[1][]
- {
- colback=expkvgrey!10!white
- ,colframe=expkvgrey
- ,size=small
- ,nobeforeafter
- ,tcbox raise base
- ,fontupper=\small
- ,#1
- }
-\RequirePackage{listings}
-\RequirePackage{booktabs}
-\RequirePackage{array}
-\RequirePackage{collcell}
-\RequirePackage{siunitx}
-\RequirePackage{xcolor}
-\RequirePackage{caption}
-\RequirePackage{microtype}
-\RequirePackage{accsupp}
-\lstdefinelanguage{expkvc}[primitive]{TeX}
- {
- ,moretexcs=[4]^^A e-TeX
- {
- expanded,
- numexpr,
- protected,
- }
- ,moretexcs=[5]^^A plain/LaTeX
- {
- approx,
- begin,
- empty,
- item,
- LaTeX,
- makeatletter,makeatother,multicolumn,
- newcommand,newdimen,
- RequirePackage,
- rule,
- TeX,
- textit,texttt,
- usepackage,
- usemodule,
- }
- ,moretexcs=[6]^^A used packages
- {
- ^^A xfp
- fpeval,
- ^^A keyval
- setkeys,
- ^^A yax
- defactiveparameter,storevalue,setparameterlist
- }
- ,moretexcs=[2]^^A expkv-cs macros
- {
- ekvcSplit,ekvcSplitAndForward,ekvcSplitAndUse,
- ekvcHash,ekvcHashAndForward,ekvcHashAndUse,
- ekvcValue,ekvcValueFast,ekvcValueSplit,ekvcValueSplitFast,
- ekvcSecondaryKeys,
- ekvcChange,
- ekvcFlagNew,
- ekvcFlagHeight,
- ekvcFlagRaise,
- ekvcFlagSetTrue,ekvcFlagSetFalse,
- ekvcFlagIf,ekvcFlagIfRaised,
- ekvcFlagReset,
- ekvcFlagGetHeight,ekvcFlagGetHeights,
- ekvcPass
- }
- ,moretexcs=[3]^^A expkv-pkg macros
- {
- ^^A expkv
- ekvdef,ekvdefNoVal,^^A
- ekvlet,ekvletNoVal,ekvletkv,ekvletkvNoVal,^^A
- ekvdefunknown,ekvdefunknownNoVal,^^A
- ekvredirectunknown,ekvredirectunknownNoVal,^^A
- ekvset,ekvsetSneaked,^^A
- ekvsetdef,ekvsetSneakeddef,ekvsetdefSneaked,^^A
- ekvparse,^^A
- ekvVersion,ekvDate,^^A
- ekvifdefined,ekvifdefinedNoVal,ekvifdefinedset,^^A
- ekvbreak,ekvbreakPreSneak,ekvbreakPostSneak,^^A
- ekvsneak,ekvsneakPre,^^A
- ekvchangeset,^^A
- ekvoptarg,ekvoptargTF,^^A
- ekverr,
- ^^A expkv-def
- ekvdefinekeys
- }
- }
-\colorlet{codeparam}{cyan!65!black}
-\def\mylstwd{.55em}
-\lstset
- {
- ,language=expkvc
- ,flexiblecolumns=false
- ,basewidth=\mylstwd
- ,gobble=2
- ,basicstyle=\fontfamily{jkp}\itshape
- ,texcsstyle=*[1]{\bfseries\color{expkvgrey}} ^^A primitives
- ,texcsstyle=*[2]{\bfseries\color{expkvred}} ^^A expkv
- ,texcsstyle=*[3]{\color{expkvred}} ^^A expkv-pkg
- ,texcsstyle=*[4]{\bfseries\color{expkvgrey}} ^^A e-TeX
- ,texcsstyle=*[5]{\bfseries\color{expkvgrey}} ^^A plain/LaTeX macros
- ,texcsstyle=*[6]{} ^^A macros of other packages
- ,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}
- ^^A,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}}}
-\RequirePackage{randtext}
-\let\metaORIG\meta
-\protected\def\meta #1{\texttt{\metaORIG{#1}}}
-\renewcommand*\thefootnote{\fnsymbol{footnote}}
-\definecolor{expkvred}{HTML}{9F393D}
-\colorlet{expkvgrey}{black!75}
-\makeatletter
-\newcommand*\example{\par\smallskip\noindent\textit{Example:} \ignorespaces}
-\newcommand*\expkv
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv}^^A
- \href{https://github.com/Skillmon/tex_expkv}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv}^^A
- }
-\newcommand*\expkvpkg[1]
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv-#1}^^A
- \href{https://github.com/Skillmon/tex_expkv-#1}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- {\color{expkvgrey}^^A
- \kern.05em\rule[-.1ex]{.08em}{1.2ex}\kern.05em\textsc{#1}^^A
- }^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv-#1}^^A
- }
-\newcommand*\expkvd{\expkvpkg{def}}
-\newcommand*\expkvc{\expkvpkg{cs}}
-\newcommand\kv{\meta{key}=\meta{value}}
-\newcommand\key{\meta{key}}
-\newcommand\val{\meta{value}}
-\newcommand\set{\meta{set}}
-\newcommand\enflong{\textcolor{black}{long}}
-\newcommand\alllong{\textcolor{gray}{long}}
-\newcommand\notlong{\textcolor{red!80!black}{long}}
-\newcommand\prefixes[1]
- {^^A
- \hfill
- \ifcase\numexpr#1\relax\or
- \enflong\or
- \alllong\or
- \notlong\fi
- }
-\hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
-\DoNotIndex{\def,\edef,\,,\=,\begingroup,\catcode,\chardef,\csname,\endcsname}
-\DoNotIndex{\endgroup,\endinput,\errmessage,\expandafter,\input,\let,\long,\z@}
-\DoNotIndex{\protected,\ProvidesFile,\ProvidesPackage,\relax,\space,\advance}
-\DoNotIndex{\@,\unexpanded,\string,\expanded,\dimexpr,\global,\glueexpr,\hbox}
-\DoNotIndex{\numexpr,\RequirePackage,\setbox,\the,\unless,\xdef,\gdef,\newcount}
-\DoNotIndex{\number,\detokenize,\meaning,\lccode,\lowercase}
-\DoNotIndex{\^,\\,\@firstofone,\@firstoftwo,\@gobble,\@secondoftwo}
-\DoNotIndex{\ifcsname}
-\DoNotIndex{\ifx}
-\DoNotIndex{\ifodd}
-\DoNotIndex{\ifnum}
-\DoNotIndex{\ifdefined}
-\DoNotIndex{\iffalse}
-\DoNotIndex{\iftrue}
-\DoNotIndex{\else}
-\DoNotIndex{\fi}
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
-\makeatother
-\begin{document}
- \title
- {^^A
- \texorpdfstring
- {^^A
- \huge\expkvc
- \\[\medskipamount]
- \Large define expandable \kv\ macros using \expkv
- }{expkv-cs - define expandable key=val macros using expkv}^^A
- }
- \date{\ekvcDate\space v\ekvcVersion}
- \author{Jonathan P. Spratte\thanks{\protect\randomize{jspratte@yahoo.de}}}
- \DocInput{expkv-cs.dtx}
-\end{document}
-%</driver>^^A=<<
-% \fi
-%
-% \maketitle
-% \renewcommand*\thefootnote{\arabic{footnote}}
-%
-% \begin{abstract}
-% \noindent\parfillskip=0pt
-% \expkvc\ provides two small interfaces to define expandable \kv\ macros using
-% \expkv. It therefore lowers the entrance boundary to expandable \kv\ macros.
-% The stylised name is \expkvc\ but the files use \file{expkv-cs}, this is due
-% to CTAN-rules which don't allow \string| in package names since that is the
-% pipe symbol in *nix shells.
-% \end{abstract}
-%
-% \tableofcontents
-%
-% \begin{documentation}^^A>>=
-%
-% \section{Documentation}
-%
-% The \expkv\ package enables the new possibility of creating \kv\ macros which
-% are fully expandable. The creation of such macros is however cumbersome for
-% the average user. \expkvc\ tries to step in here. It provides interfaces to
-% define \kv\ macros without worrying too much about the implementation. In case
-% you're wondering now, the |cs| in \expkvc\ stands for control sequence,
-% because |def| was already taken by \expkvd\ and ``control sequence'' is the
-% term D.\,E.\,Knuth used in his \TeX book for named commands hence macros
-% (though he also used the term ``macro''). So \expkvc\ defines control
-% sequences for and with \expkv.
-%
-% There are two different approaches supported by this package. The first is
-% splitting the keys up into individual arguments, the second is providing all
-% the keys as a single argument to the underlying macro and getting an
-% individual \val\ by using a hash. Well, actually there is no real hash, just
-% some markers which are parsed, but this shouldn't be apparent to the user, the
-% behaviour matches that of a hash-table.
-%
-% In addition to these two methods of defining a macro with primary keys a way
-% to define secondary keys, which can reference the primary ones, is provided.
-% These secondary keys don't correspond to an argument or an entry in the hash
-% table directly but might come in handy for the average use case. Each macro
-% has its own set of primary and secondary keys.
-%
-% A word of advice you should consider: If your macro doesn't have to be
-% expandable (and often it doesn't) consider not using \expkvc. The interface
-% has some overhead (though it still is fast -- check \autoref{sec:speed}) and
-% the approach has its limits in versatility. If you don't need to be
-% expandable, you should consider either defining your keys manually using
-% \expkv\ or using \expkvd\ for convenience. Or you resort to another \kv\
-% interface. Nevertheless setting up macros with \expkvc, especially with
-% |\ekvcSplit|, is very convenient in my opinion, so if you just want to define
-% a single macro with just a few keys this might be the way to go.
-%
-% \expkvc\ is usable as generic code, as a \LaTeX\ package, and as a \ConTeXt\
-% module. It'll automatically load \expkv\ in the same mode as well. To use it,
-% just use one of
-% \begin{lstlisting}
-% \input expkv-cs % plainTeX
-% \usepackage{expkv-cs} % LaTeX
-% \usemodule[expkv-cs] % ConTeXt
-% \end{lstlisting}
-%
-%
-% \subsection{Define Macros and Primary Keys}\label{sec:define}
-%
-% All macros defined with \expkvc\ have to be previously undefined or have the
-% |\meaning| of |\relax|. This is necessary as there is no way to automatically
-% undefine keys once they are set up (neither \expkv\ nor \expkvc\ keep track of
-% defined keys) -- so to make sure there are no conflicts only new definitions
-% are allowed (that's not the case for individual keys, only for frontend
-% macros).
-%
-%
-% \subsubsection{Primary Keys}\label{sec:primaries}
-%
-% In the following descriptions there will be one argument named \meta{primary
-% keys}. This argument should be a \kv\ list where each \key\ will be one
-% primary key and \val\ the associated initial value. By default all keys are
-% defined short, but you can define long keys by prefixing \key\ with |long|
-% (\emph{e.g.}, \texttt{long name=Jonathan P. Spratte}). You only need |long| if
-% the key should be able to take an explicit |\par| token. Note however that
-% |long| keys are a microscopic grain faster (due to some internals of \expkvc).
-% Only if at least one of the keys was |long| the \meta{cs} in the following
-% defining macros will be |\long|. For obvious reasons there is no possibility
-% to define a macro or key as |\protected|.
-%
-% To allow keys not defined |long| which key names should start with |long|, you
-% can also use the prefix |short| (|short| and |long| are mutually exclusive,
-% which ever comes first defines the behaviour, the latter is considered part of
-% the key name). Note that this is the only reason for |short|'s existance,
-% essentially it does nothing.
-%
-% The consequence culminates in the following:
-% \begin{lstlisting}
-% \ekvcSplit\foo
-% {
-% long short = abc\par
-% ,short long = def
-% }
-% {#1#2}
-% \end{lstlisting}
-% will define a macro |\foo| that knows two primary keys, the first one is
-% called |short|, and accepts explicit |\par| tokens inside its values, the
-% second one is called |long| and will not accept |\par| tokens (leading to a
-% low level \TeX\ error). A description of |\ekvcSplit| follows shortly.
-%
-% There is one exception to these syntax rules of \meta{primary keys}: One can
-% include a key named |...| without a value. If this is found the \meta{cs} will
-% be defined |\long|. Any unknown keys found at use time will end up in a list
-% at this spot. See some examples in \autoref{sec: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
-% \texttt{EKVC\string|} as that should be the private name space.
-%
-%
-% \subsubsection{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:primaries}). 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 |\ekvcSplit| you can define macros using at most
-% nine primary keys.
-% \end{function}
-% \example The following defines a macro |\foo| that takes the keys |a| and |b|
-% and outputs their values in a textual form:\\
-% \begin{minipage}{.75\linewidth}
-% \begin{lstlisting}
-% \ekvcSplit\foo{a=a,b=b}{a is #1.\par b is #2.\par}
-% \foo{}
-% \foo{b=e}
-% \end{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \ekvcSplit\foo{a=a,b=b}{a is #1.\par b is #2.\par}
-% \foo{}
-% \foo{b=e}
-% \end{exresult}
-%
-% \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{lstlisting}
-% \ekvcSplitAndForward\foo\foo@aux{keyA = A, keyB = B}
-% \ekvcSplitAndForward\foo{\foo@aux{more args}}{keyA = A, keyB = B}
-% \end{lstlisting}
-% \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 |\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}\{\key=\val, \ldots\}\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}
-%
-% 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 |\ekvcValue|, not the
-% parsing, and for a key access using |\ekvcValueFast| it was still about $1.2$
-% times slower). So if your macro uses less than ten primary keys, you should
-% consider using 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
-% \texttt{\cs[no-index]{ekvcValue}\{\key\}\{\#1\}}.
-% \end{function}
-% \example This defines an equivalent macro to the |\foo| defined with
-% |\ekvcSplit| earlier:\\
-% \begin{minipage}{.75\linewidth}
-% \begin{lstlisting}
-% \ekvcHash\foo{a=a,b=b}{a is \ekvcValue{a}{#1}.\par
-% b is \ekvcValue{b}{#1}.\par}
-% \foo{}
-% \foo{b=e}
-% \end{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \ekvcHash\foo{a=a,b=b}{a is \ekvcValue{a}{#1}.\par
-% b is \ekvcValue{b}{#1}.\par}
-% \foo{}
-% \foo{b=e}
-% \end{exresult}
-%
-% \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
-% \texttt{\cs[no-index]{ekvcValue}\{\key\}\{\#1\}} (or whichever argument the
-% hashed \kv\ list will be).
-% \end{function}
-% \example This defines a macro |\foo| processing two keys, and passing the
-% result to |\foobar|:
-% \begin{lstlisting}
-% \ekvcHashAndForward\foo\foobar{a=a,b=b}
-% \newcommand*\foobar[1]{a is \ekvcValue{a}{#1}.\par
-% b is \ekvcValue{b}{#1}.\par}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvcHashAndUse}
-% \begin{syntax}
-% \cs{ekvcHashAndUse}\meta{cs}\marg{primary keys}
-% \end{syntax}
-% This will roughly do the same as |\ekvcHashAndForward|, but instead of
-% specifying what will be used after hashing the keys at install time,
-% \meta{cs} will use what follows the \kv\ list. So its syntax will be
-% \end{function}
-% \begin{quote}
-% \ttfamily
-% \meta{cs}\{\key=\val, \ldots\}\marg{after}
-% \end{quote}
-%
-% \begin{function}{\ekvcValue}
-% \begin{syntax}
-% \cs{ekvcValue}\{\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 |\ekvcHash|, |\ekvcHashAndForward|, or |\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}\{\key\}\marg{key list}
-% \end{syntax}
-% This behaves just like |\ekvcValue|, but \emph{without any} safety 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 \key\
-% name). Use it if you know what you're doing. This macro needs exactly three
-% steps of expansion in the no-errors case.
-% \end{function}
-%
-% \begin{function}{\ekvcValueSplit}
-% \begin{syntax}
-% \cs{ekvcValueSplit}\{\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. Hence the macro \cs{ekvcValueSplit} will extract one
-% specific \key's value 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
-% |\ekvcValue| and runs the same tests.
-% \end{function}
-% \example 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{minipage}{.75\linewidth}
-% \begin{lstlisting}
-% \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{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \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{exresult}
-%
-% \begin{function}{\ekvcValueSplitFast}
-% \begin{syntax}
-% \cs{ekvcValueSplitFast}\{\key\}\marg{key list}\marg{next}
-% \end{syntax}
-% This behaves just like |\ekvcValueSplit|, but it won't run the same tests,
-% hence it is faster but more error prone, just like the relation between
-% |\ekvcValue| and |\ekvcValueFast|.
-% \end{function}
-%
-%
-% \subsection{Secondary Keys}\label{sec:secondaries}
-%
-% To remove some of the limitations with the approach that each primary key
-% matches an 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 a split or a hash variant. If a secondary key references another key
-% it doesn't matter whether that other key is primary or secondary unless
-% otherwise specified.
-%
-% Secondary keys can have a prefix (like |long|) which are called |p|-type
-% prefix and must have a type (like |meta|) which are called |t|-type prefix.
-% Some types might require some |p|-prefixes, while others might forbid those.
-%
-% Please keep in mind that key names shouldn't start with \texttt{EKVC\string|}.
-%
-% \begin{function}{\ekvcSecondaryKeys}
-% \begin{syntax}
-% \cs{ekvcSecondaryKeys}\meta{cs}\{\kv, \ldots\}
-% \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\small
-% \meta{prefix} \meta{name}
-% \end{quote}
-% Where \meta{prefix} is a space separated list of optional |p|-type prefixes
-% followed by one |t|-type prefix. The syntax of \val\ is dependent on the
-% used |t|-prefix.
-% \end{function}
-%
-%
-% \subsubsection{\texttt{p}-type Prefixes}
-%
-% There is only one |p|-prefix available, which is |long|.
-%
-% \begin{function}{long}
-% The following key will be defined |\long|.
-% \end{function}
-%
-%
-% \subsubsection{\texttt{t}-type Prefixes}
-%
-% If you're familiar with \expkvd\ you'll notice that the |t|-type prefixes
-% provided here are much fewer. The expansion only concept doesn't allow for
-% great variety in the auto-defined keys.
-%
-% The syntax examples of the |t|-prefixes will show which |p|-prefix will be
-% automatically used by printing those black (\texttt{\enflong}), which
-% will be available in grey (\texttt{\alllong}), and which will be disallowed in
-% red (\texttt{\notlong}). This will be put flush right next to the syntax line.
-%
-% \begin{function}{meta}
-% \begin{syntax}
-% meta \key\ = \{\kv, \ldots\} \prefixes2
-% \end{syntax}
-% With a |meta| key you can set other keys. Whenever \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. The keys in the \kv\ list can
-% be primary and secondary ones.
-% \end{function}
-%
-% \begin{function}{nmeta}
-% \begin{syntax}
-% nmeta \key\ = \{\kv, \ldots\} \prefixes3
-% \end{syntax}
-% An |nmeta| key is like a |meta| key, but it doesn't take a value, so the
-% \kv\ list is static.
-% \end{function}
-%
-% \begin{function}{alias}
-% \begin{syntax}
-% alias \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 value taking and the
-% |NoVal| version (that's \expkv\ slang for a key not accepting a value) will
-% be copied if they are defined when |alias| is used. Of course, \meta{key_2}
-% has to be defined, be it as a primary or secondary one.
-% \end{function}
-%
-% \begin{function}{default}
-% \begin{syntax}
-% default \key\ = \marg{default} \prefixes3
-% \end{syntax}
-% If \key\ is a defined value taking key, you can define a |NoVal| version
-% with this that 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 in |\ekvcSplit| and friends (see |\ekvcChange| in
-% \autoref{sec:change} for this). \key\ can be a primary or secondary key.
-% \end{function}
-%
-% \begin{function}{enum}
-% \begin{syntax}
-% enum \key\ = \marg{key_2}\{\val, \ldots\} \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 treated as a string, 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}
-% \example First a small example that might give you an idea of what the
-% description above could mean:\\
-% \begin{minipage}[c]{.75\linewidth}
-% \begin{lstlisting}
-% \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{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \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{exresult}
-% \example 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
-% |\ifcase|:\\
-% \begin{minipage}[c]{.75\linewidth}
-% \begin{lstlisting}
-% \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{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \ekvcSplit\foo{k-internal=-1}
-% {^^A
-% \ifcase#1
-% is\or
-% This\or
-% easy^^A
-% \else
-% .^^A
-% \fi
-% }
-% \ekvcSecondaryKeys\foo
-% {enum k = {k-internal}{a,b,c}}
-% \foo{k=b} \foo{k=a} \foo{k=c}\foo{}
-% \end{exresult}
-%
-% \begin{function}{aggregate}
-% \begin{syntax}
-% aggregate \key\ = \marg{primary}\marg{definition} \prefixes3
-% \end{syntax}
-% While all other key types replace the current value of the associated
-% \meta{primary} key, with |aggregate| you can create keys that append or
-% prepend (or whatever you like) the new value to the current one. The
-% value must be exactly two \TeX\ arguments, where \meta{primary} should
-% be the name of a \meta{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 (so
-% this doesn't allow general processing of current and new values). The
-% resulting \key\ will inherit being either |short| or |long| from the
-% \meta{primary} key.
-% \end{function}
-% \example 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{minipage}[c]{.75\linewidth}
-% \begin{lstlisting}
-% \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{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \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{exresult}
-%
-% But also more strange stuff could end there, like macros or using the same
-% value multiple times:
-% \begin{lstlisting}
-% \ekvcSecondaryKeys\foo
-% {aggregate k = {k-internal}{\old{#1}\new{#2\old{#1}}}}
-% \end{lstlisting}
-%
-%
-% \begin{function}{flag-bool}
-% \begin{syntax}
-% flag-bool \key\ = \meta{cs} \prefixes3
-% \end{syntax}
-% This is a secondary key that doesn't directly involve any of the primary or
-% 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.
-% Please also read \autoref{sec:flags}.
-% \end{function}
-%
-% \begin{function}{flag-true,flag-false}
-% \begin{syntax}
-% flag-true \key\ = \meta{cs} \prefixes3
-% \end{syntax}
-% This is a secondary key that doesn't directly involve any of the primary or
-% secondary keys.
-% This defines \key\ to take no value and set the flag called \meta{cs} to
-% |true| or |false|, respectively.
-% If \meta{cs} isn't defined yet it will be initialised as a flag.
-% Please also read \autoref{sec:flags}.
-% \end{function}
-%
-% \begin{function}{flag-raise}
-% \begin{syntax}
-% flag-raise \key\ = \meta{cs} \prefixes3
-% \end{syntax}
-% This is a secondary key that doesn't directly involve any of the primary or
-% secondary keys.
-% This defines \key\ to take no value and raise the flag called \meta{cs}.
-% If \meta{cs} isn't defined yet it will be initialised as a flag.
-% Please also read \autoref{sec:flags}.
-% \end{function}
-%
-%
-% \subsection{Changing the Initial Values}\label{sec:change}
-%
-% \begin{function}{\ekvcChange}
-% \begin{syntax}
-% \cs{ekvcChange}\meta{cs}\{\kv,\ldots\}
-% \end{syntax}
-% This processes the \kv\ list for the macro \meta{cs} to set new defaults for
-% it (meaning the values used if you don't provide anything at use time, not
-% those specified with the |default| secondary key). \meta{cs} should be
-% defined with \expkvc\ (so with any of the methods in \autoref{sec:define}).
-% 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 defaults were). If there
-% was an unknown key forwarding added to \meta{cs} (see \autoref{sec:unknown})
-% any unknown key will be stored inside the list of unknown keys as well.
-% |\ekvcChange| is not expandable!
-% \end{function}
-%
-% Consider the following example:\\
-% \begin{minipage}[c]{.75\linewidth}
-% \begin{lstlisting}
-% \ekvcSplit\foo{a=a,b=b}{a is #1.\par b is #2.\par}
-% \begingroup
-% \ekvcChange\foo{b=B}
-% \foo{} % new defaults
-% \ekvcSecondaryKeys\foo{meta c={a={#1},b={#1}}}
-% \ekvcChange\foo{c=c}
-% \foo{} % newer defaults
-% \endgroup
-% \foo{} % initial defaults
-% \end{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \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{exresult}
-%
-% As a result with this the typical setup macro could be implemented:
-% \begin{lstlisting}
-% \ekvcHashAndUse\foo{key=a,key=b}
-% \newcommand*\foosetup{\ekvcChange\foo}
-% \end{lstlisting}
-% Of course the usage is limited to a single macro |\foo|, 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.
-%
-%
-% \subsection{Handling Unknown Keys}\label{sec: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 name will be the result of one |\detokenize|, the value
-% will be forwarded as \verb*| {|\meta{value}\verb*|} |, so with spaces around
-% one set of braces (this way, most other \kv\ implementations should parse the
-% correct input).
-%
-% The exact behaviour differs slightly between the two variants (as all 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.
-%
-% \example The following will forward any unknown key to |\includegraphics| to
-% control the appearance while processing its own keys:\\
-% \begin{minipage}{.6\linewidth}
-% \begin{lstlisting}
-% \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{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.4\linewidth}
-% \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{exresult}
-%
-% Inside the hash variants the unknown keys list will be put inside the hash
-% named |...| (we have to use some name, so why not this). 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.
-%
-% \example The following is more or less equivalent to the example above, 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{minipage}{.76\linewidth}
-% \begin{lstlisting}
-% \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
-% \expanded{\noexpand\includegraphics
-% [{\ekvcValue{...}{#1}}]}
-% {#2}\par
-% }
-% \foo[width=\linewidth, b=c]
-% {example-image-duck-portrait}
-% \end{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.24\linewidth}
-% \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
-% \expanded{\noexpand\includegraphics
-% [{\ekvcValue{...}{#1}}]}
-% {#2}\par
-% }
-% \foo[width=\linewidth, b=c]
-% {example-image-duck-portrait}
-% \end{exresult}
-%
-%
-% \subsection{Flags}\label{sec: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 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 |t|-types involving flags
-% bear in mind that they can affect other macros using the same flags at the
-% current group level!
-%
-% \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 |\ifnum| for example and it will terminate the number scanning
-% on its own).
-% \end{function}
-%
-% All other macros dealing with flags take as a parameter a macro defined as a
-% \meta{flag} with |\ekvcFlagNew|.
-%
-% \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}
-% \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. 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
-% \texttt
-% {^^A
-% \cs[no-index]{ekvcFlagGetHeights}\hskip0pt^^A
-% \{\cs[no-index]{myflagA}\cs[no-index]{myflagB}\}\hskip0pt^^A
-% \{\cs[no-index]{stuff}\}^^A
-% }
-% will expand to
-% \texttt{\cs[no-index]{stuff}\{\marg{height-A}\marg{height-B}\}}.
-% \end{function}
-%
-%
-% \subsection{Further Examples}\label{sec:examples}
-%
-% How could a documentation be a good documentation without enough basic
-% examples? Say we want to define a small macro expanding to some character
-% description (who knows why this has to be expandable?). A character
-% description will not have too many items to it, so we use |\ekvcSplit| (the
-% comments with the parameter numbers are of course not necessary and just ease
-% reading the example).
-% \begin{lstlisting}
-% \ekvcSplit\character
-% {
-% name=John Doe, % #1
-% age=any, % #2
-% nationality=the Universe, % #3
-% hobby=to exist, % #4
-% type=Mister, % #5
-% pronoun=He, % #6
-% possessive=his, % #7
-% }
-% {#1 is a #5 from #3. #6 is of #2 age and #7 hobby is #4.\par}
-% \end{lstlisting}
-% Also we want to give some short cuts so that it's easier to describe several
-% persons.
-% \begin{lstlisting}
-% \ekvcSecondaryKeys\character
-% {
-% alias pro = pronoun,
-% alias pos = possessive,
-% nmeta me =
-% {
-% name=Jonathan,
-% age=a young,
-% nationality=Germany,
-% hobby=\TeX\ coding,
-% },
-% meta lady =
-% {type=Lady, pronoun=She, possessive=her, name=Jane Doe, #1},
-% nmeta paulo =
-% {
-% name=Paulo,
-% type=duck,
-% age=a young,
-% nationality=Brazil,
-% hobby=to quack,
-% }
-% }
-% \end{lstlisting}
-% Now we can describe people using
-% \begin{lstlisting}
-% \character{}
-% \character{me}
-% \character{paulo}
-% \character
-% {lady={name=Evelyn,nationality=Ireland,age=the best,hobby=reading}}
-% \character
-% {
-% name=Our sun, type=star, nationality=our solar system, pro=It,
-% age=an old, pos=its, hobby=shining
-% }
-% \end{lstlisting}
-% As one might see, the |lady| key could actually have been an |nmeta| key as
-% well, as all that is done with the argument is using it as a \kv\ list.
-%
-% The result of only the first two usages would be:
-% \begin{exresult}{\linewidth}
-% \ekvcSplit\character
-% {
-% name=John Doe,
-% age=any,
-% nationality=the Universe,
-% hobby=to exist,
-% type=Mister,
-% pronoun=He,
-% possessive=his,
-% }
-% {#1 is a #5 from #3. #6 is of #2 age and #7 hobby is #4.\par}
-% \ekvcSecondaryKeys\character
-% {
-% alias pro = pronoun,
-% alias pos = possessive,
-% nmeta me =
-% {
-% name=Jonathan,
-% age=a young,
-% nationality=Germany,
-% hobby=\TeX\ coding,
-% },
-% meta lady =
-% {type=Lady, pronoun=She, possessive=her, name=Jane Doe, #1},
-% nmeta paulo =
-% {
-% name=Paulo,
-% type=duck,
-% age=a young,
-% nationality=Brazil,
-% hobby=to quack,
-% }
-% }
-% \character{}
-% \character{me}
-% \end{exresult}
-%
-% Using \pkg{xparse} 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 (which should
-% perhaps use |\ekvcSplitAndForward| instead of |\ekvcHashAndForward| since it
-% only uses four keys and one other argument -- and isn't expandable since it
-% uses a \env{tabular} environment, so it would've been better to use a more
-% feature rich \kv\ interface most likely, \emph{e.g.}, the one provided by
-% \expkvd):
-% \begin{lstlisting}
-% \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
-% \end{lstlisting}
-% And then we would be able to do some nonsense
-% \begin{lstlisting}
-% \nonsense{}
-% \nonsense[keyA=hihi]{haha}
-% \nonsense[keyA=hihi, keyB=A]{hehe}
-% \nonsense[keyC=huhu, keyA=hihi, keyB=A]{haha}
-% \end{lstlisting}
-% resulting in
-% \begin{exresult}{\linewidth}
-% \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{}
-% \nonsense[keyA=hihi]{haha}
-% \nonsense[keyA=hihi, keyB=A]{hehe}
-% \nonsense[keyC=huhu, keyA=hihi, keyB=A]{haha}
-% \end{exresult}
-%
-%
-% \subsection{Freedom for Keys!}
-%
-% If this was the \TeX book this subsection would have 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 types listed in \autoref{sec:secondaries} 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
-% |\string|\meta{cs} is used. This can be exploited to define additional keys
-% with arbitrary code. Consider the following \emph{bad} example:
-% \begin{lstlisting}
-% \ekvcSplit\foo{a=A,b=B}{a is #1.\par b is #2\par}
-% \protected\ekvdef{\string\foo}{c}{\def\fooC{#1}}
-% \end{lstlisting}
-% This would define a key named |c| that will store its value 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
-% create a key that pre-parses the input and after that passes the parsed value
-% on. This parsing would have to be completely expandable though. 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 \meta{value} on to \meta{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}
-%
-% With this we could for example split the value of a key at a hyphen and pass
-% the parts to different keys:\\
-% \begin{minipage}[c]{.75\linewidth}
-% \begin{lstlisting}
-% \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{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \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{exresult}
-%
-% Additionally, there is a more general version of the |aggregate| secondary key
-% type (described in \autoref{sec:secondaries}), namely the |process| key type:
-%
-% \begin{function}{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 |\ekvcPass| to forward the
-% values afterwards. Unlike |aggregate| you can specify whether the \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}
-% \example We could define a key that only accepts values greater than the
-% current value with this:\\
-% \begin{minipage}[c]{.75\linewidth}
-% \begin{lstlisting}
-% \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{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \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{exresult}
-%
-%
-% \subsection{Speed Considerations}\label{sec:speed}
-%
-% As already mentioned in the introduction there are some speed considerations
-% implied if you choose to define macros via \expkvc. However the overhead isn't
-% the factor which should hinder you to use \expkvc\ if you found a reasonable
-% use case. The key-parsing is still faster than with most other \kv\ packages
-% (see the ``Comparisons'' subsection in the \expkv\ documentation).
-%
-% The speed considerations in this subsection use the first example of
-% \autoref{sec:examples} as the benchmark. So we have seven keys and a short
-% sentence which should be typeset. For comparisons I use the following
-% equivalent \expkvd\ definitions. Each result is the average between changing
-% no keys from their initial values and altering four. Furthermore I'll compare
-% three variants of \expkvc\ with the \expkvd\ definitions, namely the split
-% example from above, a hash variant using |\ekvcValue| and a hash variant using
-% |\ekvcValueFast|.
-% \begin{lstlisting}
-% \usepackage{expkv-def}
-% \ekvdefinekeys{keys}
-% {%
-% ,store name = \KEYSname
-% ,initial name = John Doe
-% ,store age = \KEYSage
-% ,initial age = any
-% ,store nationality = \KEYSnationality
-% ,initial nationality = the Universe
-% ,store hobby = \KEYShobby
-% ,initial hobby = to exist
-% ,store type = \KEYStype
-% ,initial type = Mister
-% ,store pronoun = \KEYSpronoun
-% ,initial pronoun = He
-% ,store possessive = \KEYSpossessive
-% ,initial possessive = his
-% }
-% \newcommand*\KEYS[1]
-% {%
-% \begingroup
-% \ekvset{keys}{#1}%
-% \KEYSname\ is a \KEYStype\ from \KEYSnationality.
-% \KEYSpronoun\ is of \KEYSage\ age and
-% \KEYSpossessive\ hobby is \KEYShobby.%
-% \endgroup
-% }
-% \end{lstlisting}
-%
-% The first comparison removes the typesetting part from all the definitions, so
-% that only the key parsing is compared. In this comparison the |\ekvcValue|
-% and |\ekvcValueFast| variants will not differ, as they are exactly the same
-% until the key usage. We find that the split approach is $1.4$ times slower
-% than the \expkvd\ setup and the hash variants end up in the middle at $1.17$
-% times slower.
-%
-% Next we put the typesetting part back in. Every call of the macros will
-% typeset the sentences into a box register in horizontal mode. With the
-% typesetting part (which includes the accessing of values) the fastest remains
-% the \expkvd\ definitions, but split is close at $1.16$ times slower, followed
-% by the hash variant with fast accesses at $1.36$ times slower, and the safe
-% hash access variant ranks in the slowest $1.8$ times slower than \expkvd.
-%
-% Just in case you're wondering now, a simple macro taking seven arguments is
-% $30$ to $40$ times faster than any of those in the argument grabbing and \kv\
-% parsing part and only $1.5$ to $2.8$ times faster if the typesetting part is
-% factored in. So the real choke isn't the parsing.
-%
-% So to summarise this, if you have a use case for expandable \kv\
-% parsing macros you should go on and define them using \expkvc. If you just
-% want to define a simple macro with a few keys |\ekvcSplit| might be the
-% easiest interface there is. If you have a reasonable use case for \kv\ parsing
-% macros but defining them expandable isn't necessary for your use you should
-% take advantage of the greater flexibility of non-expandable \kv\ setups (but
-% if you're after maximum speed there aren't that many \kv\ parsers beating
-% \expkvc). And if you are after maximum performance maybe ditching the \kv\
-% interface altogether is a good idea, but depending on the number of arguments
-% your interface might get convoluted.
-%
-%
-% \subsection{Useless Macros}
-%
-% Perhaps these macros aren't completely useless, but I figured from a user's
-% point of view I wouldn't know what I should do with these.
-%
-% \begin{function}{\ekvcDate,\ekvcVersion}
-% These two macros store the version and the date of the package/generic code.
-% \end{function}
-%
-%
-% \subsection{Bugs}
-%
-% Of course I don't think there are any bugs (who would knowingly distribute
-% buggy software as long as he isn't a multi-million dollar corporation?). But
-% if you find some please let me know. For this one might find my email address
-% on the first page or file an issue on Github:
-% \url{https://github.com/Skillmon/tex_expkv-cs}
-%
-%
-% \subsection{License}
-%
-% Copyright \textcopyright\ 2020\unless\ifnum\year=2020--\the\year\fi\
-% Jonathan P. Spratte
-%
-% \medskip\noindent
-% 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:
-%
-% \url{http://www.latex-project.org/lppl.txt}
-%
-% \noindent
-% This work is ``maintained'' (as per LPPL maintenance status) by
-%
-% \mbox{Jonathan P. Spratte}.
-%
-% \end{documentation}^^A=<<
-%
-% \begin{implementation}^^A>>=
-%
-% \clearpage
-%
-% \section{Implementation}^^A>>=
-%^^A the LaTeX package >>=
-% \subsection{The \LaTeX\ Package}
-% Just like for \expkv\ we provide a small \LaTeX\ package that sets up things
-% such that we behave nicely on \LaTeX\ packages and files system. It'll
-% |\input| the generic code which implements the functionality.
-% \gobbledocstriptag
-%<*pkg>
-% \begin{macrocode}
-\RequirePackage{expkv}
-\def\ekvc@tmp
- {%
- \ProvidesFile{expkv-cs.tex}%
- [%
- \ekvcDate\space v\ekvcVersion\space
- define expandable key=val macros using expkv%
- ]%
- }
-\input{expkv-cs.tex}
-\ProvidesPackage{expkv-cs}%
- [%
- \ekvcDate\space v\ekvcVersion\space
- define expandable key=val macros using expkv%
- ]
-% \end{macrocode}
-% \gobbledocstriptag
-%</pkg>
-%^^A=<<
-%^^A the ConTeXt module >>=
-% \subsection{The \ConTeXt\ module}
-% \gobbledocstriptag
-%<*ctx>
-% \begin{macrocode}
-\writestatus{loading}{ConTeXt User Module / expkv-cs}
-\usemodule[expkv]
-\unprotect
-\input expkv-cs.tex
-\writestatus{loading}
- {ConTeXt User Module / expkv-cs / Version \ekvcVersion\space loaded}
-\protect\endinput
-% \end{macrocode}
-% \gobbledocstriptag
-%</ctx>
-%^^A=<<
-%^^A main file >>=
-% \subsection{The Generic Code}
-% The rest of this implementation will be the generic code.
-% \gobbledocstriptag
-%<*tex>
-%
-% Load \expkv\ if the package didn't already do so -- since \expkv\ has
-% safeguards against being loaded twice this does no harm and the overhead
-% isn't that big. Also we reuse some of the internals of \expkv\ to save us from
-% retyping them.
-% \begin{macrocode}
-\input expkv
-% \end{macrocode}
-%
-% We make sure that \file{expkv-cs.tex} is only input once:
-% \begin{macrocode}
-\expandafter\ifx\csname ekvcVersion\endcsname\relax
-\else
- \expandafter\endinput
-\fi
-% \end{macrocode}
-%
-% \begin{macro}{\ekvcVersion,\ekvcDate}
-% We're on our first input, so lets store the version and date in a macro.
-% \begin{macrocode}
-\def\ekvcVersion{1.2}
-\def\ekvcDate{2022-02-13}
-% \end{macrocode}
-% \end{macro}
-%
-% If the \LaTeX\ format is loaded we want to be a good file and report back who
-% we are, for this the package will have defined |\ekvc@tmp| to use
-% |\ProvidesFile|, else this will expand to a |\relax| and do no harm.
-% \begin{macrocode}
-\csname ekvc@tmp\endcsname
-% \end{macrocode}
-%
-% Store the category code of |@| to later be able to reset it and change it to
-% 11 for now.
-% \begin{macrocode}
-\expandafter\chardef\csname ekvc@tmp\endcsname=\catcode`\@
-\catcode`\@=11
-% \end{macrocode}
-% |\ekvc@tmp| will be reused later, but we don't need it to ever store
-% information long-term after \expkvc\ was initialized.
-%
-% \begin{macro}[internal]{\ekvc@tripledots}
-% This macro just serves as a marker for a comparison to allow the syntax
-% for the unknown key handlers.
-% \begin{macrocode}
-\def\ekvc@tripledots{...}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@keycount}
-% We'll need to keep count how many keys must be defined for each macro in the
-% |split| variants.
-% \begin{macrocode}
-\newcount\ekvc@keycount
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@long,\ekvc@any@long}
-% Some macros will have to be defined long. These two will be let to |\long|
-% when this should be the case.
-% \begin{macrocode}
-\let\ekvc@long\ekv@empty
-\let\ekvc@any@long\ekv@empty
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@ifdefined}
-% We want to test whether a macro is already defined. This test checks for a
-% defined macro that isn't |\relax|.
-% \begin{macrocode}
-\long\def\ekvc@ifdefined#1%
- {%
- \ifdefined#1%
- \ifx\relax#1%
- \ekv@fi@gobble
- \fi
- \@firstofone
- \ekv@fi@firstoftwo
- \fi
- \@secondoftwo
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@ekvset@pre@expander,
-% \ekvc@ekvset@pre@expander@a,
-% \ekvc@ekvset@pre@expander@b
-% }
-% This macro expands |\ekvset| twice so that the first two steps of expansion
-% don't have to be made every time the \expkvc\ macros are used. We have to do
-% a little magic trick to get the macro parameter |#1| for the macro
-% definition this is used in, even though we're calling |\unexpanded|. We do
-% that by splitting the expanded |\ekvset| at some marks and place |##1| in
-% between. At this spot we also add |\ekv@alignsafe| and |\ekv@endalignsafe|
-% to ensure that macros created with \expkvc\ are alignment safe.
-% \begin{macrocode}
-\def\ekvc@ekvset@pre@expander#1%
- {%
- \expandafter\ekvc@ekvset@pre@expander@a\ekvset{#1}\ekvc@stop\ekvc@stop
- }
-\def\ekvc@ekvset@pre@expander@a
- {%
- \expandafter\ekvc@ekvset@pre@expander@b
- }
-\def\ekvc@ekvset@pre@expander@b#1\ekvc@stop#2\ekvc@stop
- {%
- \ekv@unexpanded\expandafter{\ekv@alignsafe}%
- \ekv@unexpanded{#1}##1\ekv@unexpanded{#2}%
- \ekv@unexpanded\expandafter{\ekv@endalignsafe}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcSplitAndUse}
-% The first user macro we want to set up can be reused for
-% \cs[no-index]{ekvcSplitAndForward} and \cs[no-index]{ekvcSplit}. We'll split
-% this one up so that the test whether the macro is already defined doesn't
-% run twice.
-% \begin{macrocode}
-\protected\long\def\ekvcSplitAndUse#1#2%
- {%
- \let\ekvc@helpers@needed\@firstoftwo
- \ekvc@ifdefined#1%
- {\ekvc@err@already@defined#1}%
- {\ekvcSplitAndUse@#1{}{#2}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvcSplitAndUse@}
-% The actual macro setting up things. We need to set some variables, forward
-% the key list to |\ekvc@SetupSplitKeys|, and afterwards define the front
-% facing macro to call |\ekvset| and put the initials and the argument sorting
-% macro behind it. The internals |\ekvc@any@long|, |\ekvc@initials| and
-% |\ekvc@keycount| will be set correctly by |\ekvc@SetupSplitKeys|.
-% \begin{macrocode}
-\protected\long\def\ekvcSplitAndUse@#1#2#3%
- {%
- \edef\ekvc@set{\string#1}%
- \ekvc@SetupSplitKeys{#3}%
- \ekvc@helpers@needed
- {%
- \ekvc@any@long\edef#1##1%
- {%
- \expandafter\ekvc@ekvset@pre@expander\expandafter{\ekvc@set}%
- \ekv@unexpanded\expandafter
- {\csname ekvc@split@\the\ekvc@keycount\endcsname}%
- \ekv@unexpanded\expandafter{\ekvc@initials{}#2}%
- }%
- }%
- {%
- \ekvc@any@long\edef#1##1%
- {%
- \expandafter\ekvc@ekvset@pre@expander\expandafter{\ekvc@set}%
- \ekv@unexpanded{#2}%
- \ekv@unexpanded\expandafter{\ekvc@initials}%
- }%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\ekvcSplitAndForward}
-% This just reuses |\ekvcSplitAndUse@| with a non-empty second argument,
-% resulting in that argument to be called after the splitting.
-% \begin{macrocode}
-\protected\long\def\ekvcSplitAndForward#1#2#3%
- {%
- \let\ekvc@helpers@needed\@firstoftwo
- \ekvc@ifdefined#1%
- {\ekvc@err@already@defined#1}%
- {\ekvcSplitAndUse@#1{{#2}}{#3}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcSplit}
-% The first half is just |\ekvcSplitAndForward| then we define the macro to
-% which the parsed key list is forwarded. There we need to allow for up to
-% nine arguments.
-% \begin{macrocode}
-\protected\long\def\ekvcSplit#1#2#3%
- {%
- \let\ekvc@helpers@needed\@secondoftwo
- \ekvc@ifdefined#1%
- {\ekvc@err@already@defined#1}%
- {%
- \expandafter
- \ekvcSplitAndUse@\expandafter#1\csname ekvc@\string#1\endcsname{#2}%
- \ifnum\ekvc@keycount<1
- \ekvc@any@long\expandafter\def\csname ekvc@\string#1\endcsname{#3}%
- \else
- \ifnum\ekvc@keycount>9
- \ekvc@err@toomany{#1}%
- \let#1\ekvc@undefined
- \else
- \ekvcSplit@build@argspec
- \ekvc@any@long\expandafter
- \def\csname ekvc@\string#1\expandafter\endcsname\ekvc@tmp{#3}%
- \fi
- \fi
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvcSplit@build@argspec,\ekvcSplit@build@argspec@}
-% \begin{macrocode}
-\protected\def\ekvcSplit@build@argspec
- {%
- \begingroup
- \edef\ekvc@tmp
- {\endgroup\def\ekv@unexpanded{\ekvc@tmp}{\ekvcSplit@build@argspec@{1}}}%
- \ekvc@tmp
- }
-\def\ekvcSplit@build@argspec@#1%
- {%
- \ifnum#1>\ekvc@keycount
- \ekv@fi@gobble
- \fi
- \@firstofone
- {%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@#1\endcsname####}#1%
- \expandafter\ekvcSplit@build@argspec@\expandafter{\the\numexpr#1+1}%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@SetupSplitKeys, \ekvc@SetupSplitKeys@a, \ekvc@SetupSplitKeys@b,
-% \ekvc@SetupSplitKeys@c, \ekvc@SetupSplitKeys@d, \ekvc@SetupSplitKeys@e,
-% \ekvc@SetupSplitKeys@check@unknown,\ekvc@SetupSplitKeys@unknown
-% }
-% These macros parse the list of keys and set up the key macros. First we need
-% to initialise some macros and start |\ekvparse|.
-% \begin{macrocode}
-\protected\long\def\ekvc@SetupSplitKeys
- {%
- \ekvc@keycount=\ekv@zero
- \let\ekvc@any@long\ekv@empty
- \let\ekvc@initials\ekv@empty
- \ekvparse\ekvc@SetupSplitKeys@check@unknown\ekvc@SetupSplitKeys@a
- }
-% \end{macrocode}
-% Then we need to step the key counter for each key. Also we have to check
-% whether this key has a |long| prefix so we initialise |\ekvc@long|.
-% \begin{macrocode}
-\protected\long\def\ekvc@SetupSplitKeys@a#1%
- {\expandafter\ekvc@SetupSplitKeys@b\detokenize{#1}\ekvc@stop}
-\protected\def\ekvc@SetupSplitKeys@b#1\ekvc@stop
- {%
- \advance\ekvc@keycount1
- \let\ekvc@long\ekv@empty
- \ekvc@ifspace{#1}%
- {\ekvc@SetupSplitKeys@c#1\ekvc@stop}%
- {\ekvc@SetupSplitKeys@d{#1}}%
- }
-% \end{macrocode}
-% If there was a space, there might be a prefix. If so call the prefix macro,
-% else call the next step |\ekvc@SetupSplitKeys@d| which will define the key
-% macro and add the key's value to the initials list.
-% \begin{macrocode}
-\protected\long\def\ekvc@SetupSplitKeys@c#1 #2\ekvc@stop
- {%
- \ekv@ifdefined{ekvc@split@p@#1}%
- {\csname ekvc@split@p@#1\endcsname{#2}}%
- {\ekvc@SetupSplitKeys@d{#1 #2}}%
- }
-% \end{macrocode}
-% The inner definition is grouped, because we don't want to actually define
-% the marks we build with |\csname|. We have to append the value to the
-% |\ekvc@initials| list here with the correct split mark. The key macro will
-% read everything up to those split marks and change the value following it to
-% the value given to the key. Additionally we'll need a sorting macro for each
-% key count in use so we set it up with |\ekvc@setup@splitmacro|.
-% \begin{macrocode}
-\protected\def\ekvc@SetupSplitKeys@d
- {%
- \begingroup\expandafter\endgroup
- \expandafter\ekvc@SetupSplitKeys@e
- \csname ekvc@splitmark@\the\ekvc@keycount\endcsname
- }
-\protected\long\def\ekvc@SetupSplitKeys@e#1#2#3%
- {%
- \long\def\ekvc@tmp##1##2#1##3{##2#1{##1}}%
-% \end{macrocode}
-% The short variant needs a bit of special treatment. The key macro will be
-% short to throw the correct error, but since there might be long macros
-% somewhere the reordering of arguments needs to be long, so for short keys we
-% use a two step approach, first grabbing only the short argument, then
-% reordering.
-% \begin{macrocode}
- \unless\ifx\ekvc@long\long
- \expandafter\let\csname ekvc@\ekvc@set(#2)\endcsname\ekvc@tmp
- \edef\ekvc@tmp##1%
- {%
- \ekv@unexpanded\expandafter{\csname ekvc@\ekvc@set(#2)\endcsname}%
- {##1}%
- }%
- \fi
- \ekvlet\ekvc@set{#2}\ekvc@tmp
- \edef\ekvc@initials{\ekv@unexpanded\expandafter{\ekvc@initials#1{#3}}}%
- \ekvc@helpers@needed
- {\expandafter\ekvc@setup@splitmacro\expandafter{\the\ekvc@keycount}}%
- {}%
- }
-% \end{macrocode}
-% If no value was provided this could either be an error, or the unknown key
-% forwarding. We have to check this (comparing against |...| inside
-% |\ekvc@tripledots|) and if this is the unknown key list type, set it up
-% accordingly (advancing the key count and setting up the unknown handlers of
-% \expkv). Else we simply throw an error and ignore the incident.
-% \begin{macrocode}
-\protected\long\def\ekvc@SetupSplitKeys@check@unknown#1%
- {%
- \begingroup
- \edef\ekvc@tmp{\detokenize{#1}}%
- \expandafter
- \endgroup
- \ifx\ekvc@tripledots\ekvc@tmp
- \advance\ekvc@keycount1
-% \end{macrocode}
-% The |\begingroup\expandafter\endgroup| ensures that the split mark isn't
-% actually defined (even if it just were with meaning |\relax|).
-% \begin{macrocode}
- \begingroup\expandafter\endgroup
- \expandafter\ekvc@SetupSplitKeys@unknown
- \csname ekvc@splitmark@\the\ekvc@keycount\endcsname
- \let\ekvc@any@long\long
- \else
- \ekvc@err@value@required{#1}%
- \fi
- }
-% \end{macrocode}
-%
-% \begin{macrocode}
-\protected\long\def\ekvc@SetupSplitKeys@unknown#1%
- {%
- \long\expandafter\def\csname\ekv@name\ekvc@set{}u\endcsname##1##2##3#1##4%
- {##3#1{##4,##2= {##1} }}%
- \long\expandafter\def\csname\ekv@name\ekvc@set{}uN\endcsname##1##2#1##3%
- {##2#1{##3,##1}}%
- \edef\ekvc@initials{\ekv@unexpanded\expandafter{\ekvc@initials#1{}}}%
- \ekvc@helpers@needed
- {\expandafter\ekvc@setup@splitmacro\expandafter{\the\ekvc@keycount}}%
- {}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@split@p@long}
-% The |long| prefix lets the internals |\ekvc@long| and |\ekvc@any@long| to
-% |\long| so that the key macro will be long.
-% \begin{macrocode}
-\protected\def\ekvc@split@p@long
- {%
- \let\ekvc@long\long
- \let\ekvc@any@long\long
- \ekvc@SetupSplitKeys@d
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@split@p@short}
-% The |short| prefix does essentially nothing, it is only provided to allow
-% key names starting with |long| that aren't |\long|.
-% \begin{macrocode}
-\def\ekvc@split@p@short{\ekvc@SetupSplitKeys@d}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@defarggobbler}
-% This is needed to define a macro with 1-9 parameters programmatically.
-% \LaTeX's \cs[no-index]{newcommand} does something similar for example.
-% \begin{macrocode}
-\protected\def\ekvc@defarggobbler#1{\def\ekvc@tmp##1#1##2##{##1#1}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@setup@splitmacro,
-% \ekvc@split@1, \ekvc@split@2, \ekvc@split@3,
-% \ekvc@split@4, \ekvc@split@5, \ekvc@split@6,
-% \ekvc@split@7
-% }
-% Since the first few split macros are different from the others we manually
-% set those up now. All the others will be defined as needed (always
-% globally). The split macros just read up until the correct split mark, move
-% that argument into a list and reinsert the rest, calling the next split
-% macro afterwards.
-% \begin{macrocode}
-\begingroup
-\edef\ekvc@tmp
- {%
- \long\gdef\ekv@unexpanded\expandafter{\csname ekvc@split@1\endcsname}%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@1\endcsname}%
- ##1##2##3%
- {##3{##1}##2}%
- \long\gdef\ekv@unexpanded\expandafter{\csname ekvc@split@2\endcsname}%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@1\endcsname}##1%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@2\endcsname}##2%
- ##3##4%
- {##4{##1}{##2}##3}%
- \long\gdef\ekv@unexpanded\expandafter{\csname ekvc@split@3\endcsname}%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@1\endcsname}##1%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@2\endcsname}##2%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@3\endcsname}##3%
- ##4##5%
- {##5{##1}{##2}{##3}##4}%
- \long\gdef\ekv@unexpanded\expandafter{\csname ekvc@split@4\endcsname}%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@1\endcsname}##1%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@2\endcsname}##2%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@3\endcsname}##3%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@4\endcsname}##4%
- ##5##6%
- {##6{##1}{##2}{##3}{##4}##5}%
- \long\gdef\ekv@unexpanded\expandafter{\csname ekvc@split@5\endcsname}%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@1\endcsname}##1%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@2\endcsname}##2%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@3\endcsname}##3%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@4\endcsname}##4%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@5\endcsname}##5%
- ##6##7%
- {##7{##1}{##2}{##3}{##4}{##5}##6}%
- \long\gdef\ekv@unexpanded\expandafter{\csname ekvc@split@6\endcsname}%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@1\endcsname}##1%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@2\endcsname}##2%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@3\endcsname}##3%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@4\endcsname}##4%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@5\endcsname}##5%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@6\endcsname}##6%
- ##7##8%
- {##8{##1}{##2}{##3}{##4}{##5}{##6}##7}%
- \long\gdef\ekv@unexpanded\expandafter{\csname ekvc@split@7\endcsname}%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@1\endcsname}##1%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@2\endcsname}##2%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@3\endcsname}##3%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@4\endcsname}##4%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@5\endcsname}##5%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@6\endcsname}##6%
- \ekv@unexpanded\expandafter{\csname ekvc@splitmark@7\endcsname}##7%
- ##8##9%
- {##9{##1}{##2}{##3}{##4}{##5}{##6}{##7}##8}%
- }
-\ekvc@tmp
-\endgroup
-\protected\def\ekvc@setup@splitmacro#1%
- {%
- \ekv@ifdefined{ekvc@split@#1}{}%
- {%
- \begingroup
- \edef\ekvc@tmp
- {%
- \long\gdef
- \ekv@unexpanded\expandafter{\csname ekvc@split@#1\endcsname}%
- ####1%
- \ekv@unexpanded\expandafter
- {\csname ekvc@splitmark@#1\endcsname}%
- ####2####3%
- {%
- \ekv@unexpanded\expandafter
- {\csname ekvc@split@\the\numexpr#1-1\relax\endcsname}%
- ####1{{####2}####3}%
- }%
- }%
- \ekvc@tmp
- \endgroup
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcHashAndUse}
-% |\ekvcHashAndUse| works just like |\ekvcSplitAndUse|.
-% \begin{macrocode}
-\protected\long\def\ekvcHashAndUse#1#2%
- {%
- \let\ekvc@helpers@needed\@firstoftwo
- \ekvc@ifdefined#1%
- {\ekvc@err@already@defined#1}%
- {\ekvcHashAndUse@#1{}{#2}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvcHashAndUse@}
-% This is more or less the same as |\ekvcSplitAndUse@|. Instead of an empty
-% group we place a marker after the initials, we don't use the sorting macros
-% of |split|, but instead pack all the values in one argument.
-% \begin{macrocode}
-\protected\long\def\ekvcHashAndUse@#1#2#3%
- {%
- \edef\ekvc@set{\string#1}%
- \ekvc@SetupHashKeys{#3}%
- \ekvc@helpers@needed
- {%
- \ekvc@any@long\edef#1##1%
- {%
- \expandafter\ekvc@ekvset@pre@expander\expandafter{\ekvc@set}%
- \ekv@unexpanded{\ekvc@hash@pack@argument}%
- \ekv@unexpanded\expandafter{\ekvc@initials\ekvc@stop#2}%
- }%
- }%
- {%
- \ekvc@any@long\edef#1##1%
- {%
- \expandafter\ekvc@ekvset@pre@expander\expandafter{\ekvc@set}%
- \ekv@unexpanded{#2}%
- \ekv@unexpanded\expandafter{\ekvc@initials\ekvc@stop}%
- }%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcHashAndForward}
-% |\ekvcHashAndForward| works just like |\ekvcSplitAndForward|.
-% \begin{macrocode}
-\protected\long\def\ekvcHashAndForward#1#2#3%
- {%
- \let\ekvc@helpers@needed\@firstoftwo
- \ekvc@ifdefined#1%
- {\ekvc@err@already@defined#1}%
- {\ekvcHashAndUse@#1{{#2}}{#3}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcHash}
-% |\ekvcHash| does the same as |\ekvcSplit|, but has the advantage of not
-% needing to count arguments, so the definition of the internal macro is a bit
-% more straight forward.
-% \begin{macrocode}
-\protected\long\def\ekvcHash#1#2#3%
- {%
- \let\ekvc@helpers@needed\@secondoftwo
- \ekvc@ifdefined#1%
- {\ekvc@err@already@defined#1}%
- {%
- \expandafter
- \ekvcHashAndUse@\expandafter#1\csname ekvc@\string#1\endcsname{#2}%
- \ekvc@any@long\expandafter\def\csname ekvc@\string#1\endcsname
- ##1\ekvc@stop
- {#3}%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@hash@pack@argument}
-% All this macro does is pack the values into one argument and forward that to
-% the next macro.
-% \begin{macrocode}
-\long\def\ekvc@hash@pack@argument#1\ekvc@stop#2{#2{#1}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@SetupHashKeys,\ekvc@SetupHashKeys@a,\ekvc@SetupHashKeys@b,
-% \ekvc@SetupHashKeys@c,\ekvc@SetupHashKeys@d,\ekvc@SetupHashKeys@e,
-% \ekvc@SetupHashKeys@check@unknown,\ekvc@SetupHashKeys@unknown
-% }
-% This should look awfully familiar as well, since it's just the same as for
-% the split keys with a few other names here and there.
-% \begin{macrocode}
-\protected\long\def\ekvc@SetupHashKeys#1%
- {%
- \let\ekvc@any@long\ekv@empty
- \let\ekvc@initials\ekv@empty
- \ekvparse\ekvc@SetupHashKeys@check@unknown\ekvc@SetupHashKeys@a{#1}%
- }
-\protected\long\def\ekvc@SetupHashKeys@a#1%
- {\expandafter\ekvc@SetupHashKeys@b\detokenize{#1}\ekvc@stop}
-\protected\def\ekvc@SetupHashKeys@b#1\ekvc@stop
- {%
- \let\ekvc@long\ekv@empty
- \ekvc@ifspace{#1}%
- {\ekvc@SetupHashKeys@c#1\ekvc@stop}%
- {\ekvc@SetupHashKeys@d{#1}}%
- }
-\protected\def\ekvc@SetupHashKeys@c#1 #2\ekvc@stop
- {%
- \ekv@ifdefined{ekvc@hash@p@#1}%
- {\csname ekvc@hash@p@#1\endcsname{#2}}%
- {\ekvc@SetupHashKeys@d{#1 #2}}%
- }
-% \end{macrocode}
-% Again we build the marker, this time instead of a numbered one a named
-% hashmark, inside a group to not actually define the macro used as a marker.
-% \begin{macrocode}
-\protected\long\def\ekvc@SetupHashKeys@d#1%
- {%
- \begingroup\expandafter\endgroup
- \expandafter\ekvc@SetupHashKeys@e\csname ekvc@hashmark@#1\endcsname{#1}%
- }
-% \end{macrocode}
-% Yes, even the defining macro looks awfully familiar. Instead of numbered we
-% have named marks. Still the key macros grab everything up to their
-% respective mark and reorder the arguments. The same quirk is applied for
-% short keys. And instead of the |\ekvc@setup@splitmacro| we use
-% |\ekvc@setup@hashmacro|.
-% \begin{macrocode}
-\protected\long\def\ekvc@SetupHashKeys@e#1#2#3%
- {%
- \long\def\ekvc@tmp##1##2#1##3{##2#1{##1}}%
- \unless\ifx\ekvc@long\long
- \expandafter\let\csname ekvc@\ekvc@set(#2)\endcsname\ekvc@tmp
- \edef\ekvc@tmp##1%
- {%
- \ekv@unexpanded\expandafter{\csname ekvc@\ekvc@set(#2)\endcsname}%
- {##1}%
- }%
- \fi
- \ekvlet\ekvc@set{#2}\ekvc@tmp
- \edef\ekvc@initials{\ekv@unexpanded\expandafter{\ekvc@initials#1{#3}}}%
- \ekvc@setup@hashmacro{#2}%
- }
-% \end{macrocode}
-% \begin{macrocode}
-\protected\long\def\ekvc@SetupHashKeys@check@unknown#1%
- {%
- \begingroup
- \edef\ekvc@tmp{\detokenize{#1}}%
- \expandafter
- \endgroup
- \ifx\ekvc@tripledots\ekvc@tmp
- \ekvc@SetupHashKeys@unknown
- \let\ekvc@any@long\long
- \else
- \ekvc@err@value@required{#1}%
- \fi
- }
-% \end{macrocode}
-% \begin{macrocode}
-\def\ekvc@SetupHashKeys@unknown#1%
- {%
- \protected\def\ekvc@SetupHashKeys@unknown
- {%
- \expandafter
- \let\csname\ekv@name\ekvc@set{}u\endcsname\ekvc@hash@unknown@kv
- \expandafter
- \let\csname\ekv@name\ekvc@set{}uN\endcsname\ekvc@hash@unknown@k
- \edef\ekvc@initials{\ekv@unexpanded\expandafter{\ekvc@initials#1{}}}%
- \ekvc@setup@hashmacro{...}%
- }%
- \long\def\ekvc@hash@unknown@kv##1##2##3#1##4{##3#1{##4,##2= {##1} }}%
- \long\def\ekvc@hash@unknown@k##1##2#1##3{##2#1{##3,##1}}%
- }
-\expandafter\ekvc@SetupHashKeys@unknown
- \csname ekvc@hashmark@\ekvc@tripledots\endcsname
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@hash@p@long}
-% Nothing astonishing here either.
-% \begin{macrocode}
-\protected\def\ekvc@hash@p@long
- {%
- \let\ekvc@long\long
- \let\ekvc@any@long\long
- \ekvc@SetupHashKeys@d
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@hash@p@short}
-% The |short| prefix does essentially nothing, it is only provided to allow
-% key names starting with |long| that aren't |\long|.
-% \begin{macrocode}
-\def\ekvc@hash@p@short{\ekvc@SetupHashKeys@d}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@setup@hashmacro}
-% The safe hash macros will be executed inside of an |\unexpanded| expansion
-% context, so they have to insert braces for that once they are done.
-% Most of the tests which have to be executed will already be done, but we
-% have to play safe if the hash doesn't show up in the hash list. Therefore we
-% use some |\ekvc@mark|s and |\ekvc@stop| to throw errors if the hash isn't
-% found in the right place. The fast variants have an easier life and just
-% return the correct value.
-% \begin{macrocode}
-\protected\def\ekvc@setup@hashmacro#1%
- {%
- \ekv@ifdefined{ekvc@fasthash@#1}{}%
- {%
- \begingroup
- \edef\ekvc@tmp
- {%
- \long\gdef
- \ekv@unexpanded\expandafter{\csname ekvc@fasthash@#1\endcsname}%
- ####1%
- \ekv@unexpanded\expandafter
- {\csname ekvc@hashmark@#1\endcsname}%
- ####2####3\ekv@unexpanded{\ekvc@stop}%
- {####2}%
- \long\gdef
- \ekv@unexpanded\expandafter{\csname ekvc@safehash@#1\endcsname}%
- ####1%
- {%
- \ekv@unexpanded\expandafter
- {\csname ekvc@@safehash@#1\endcsname}%
- ####1\ekv@unexpanded{\ekvc@mark}{}%
- \ekv@unexpanded\expandafter
- {%
- \csname ekvc@hashmark@#1\endcsname{}%
- \ekvc@mark{\ekvc@err@missing@hash{#1}}\ekvc@stop
- }%
- }%
- \long\gdef
- \ekv@unexpanded\expandafter
- {\csname ekvc@@safehash@#1\endcsname}%
- ####1%
- \ekv@unexpanded\expandafter
- {\csname ekvc@hashmark@#1\endcsname}%
- ####2####3\ekv@unexpanded{\ekvc@mark}####4####5%
- \ekv@unexpanded{\ekvc@stop}%
- {%
- ####4{####2}%
- }%
- \long\gdef\ekv@unexpanded\expandafter
- {\csname ekvc@fastsplithash@#1\endcsname}%
- ####1%
- \ekv@unexpanded\expandafter
- {\csname ekvc@hashmark@#1\endcsname}%
- ####2####3\ekv@unexpanded{\ekvc@stop}####4%
- {%
- ####4{####2}%
- }%
- \long\gdef\ekv@unexpanded\expandafter
- {\csname ekvc@safesplithash@#1\endcsname}####1%
- {%
- \ekv@unexpanded\expandafter
- {\csname ekvc@@safesplithash@#1\endcsname}%
- ####1\ekv@unexpanded{\ekvc@mark\ekvc@safe@after@hash}%
- \ekv@unexpanded\expandafter
- {%
- \csname ekvc@hashmark@#1\endcsname{}%
- \ekvc@mark
- {\ekvc@err@missing@hash{#1}\ekvc@safe@after@hash}%
- \ekvc@stop
- }%
- }%
- \long\gdef\ekv@unexpanded\expandafter
- {\csname ekvc@@safesplithash@#1\endcsname}%
- ####1%
- \ekv@unexpanded\expandafter
- {\csname ekvc@hashmark@#1\endcsname}%
- ####2####3\ekv@unexpanded{\ekvc@mark}####4####5%
- \ekv@unexpanded{\ekvc@stop}%
- {%
- ####4{####2}%
- }%
- }%
- \ekvc@tmp
- \endgroup
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcValue}
-% \begin{macro}[internal]{\ekvcValue@}
-% All this does is a few consistency checks on the first argument (not empty,
-% hash macro exists) and then call that hash-grabbing macro that will also
-% test whether the hash is inside of |#2| or not.
-% \begin{macrocode}
-\long\def\ekvcValue#1%
- {%
- \ekv@unexpanded
- \expandafter\ekvcValue@\detokenize{#1}\ekvc@stop
- }
-\def\ekvcValue@#1\ekvc@stop
- {%
- \ekv@ifdefined{ekvc@safehash@#1}%
- {\csname ekvc@safehash@#1\endcsname}%
- {\ekvc@err@unknown@hash{#1}\@firstoftwo{{}}}%
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\ekvcValueFast}
-% To be as fast as possible, this doesn't test for anything, assuming the user
-% knows best.
-% \begin{macrocode}
-\long\def\ekvcValueFast#1#2%
- {\csname ekvc@fasthash@\detokenize{#1}\endcsname#2\ekvc@stop}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcValueSplit}
-% \begin{macro}[internal]{\ekvcValueSplit@,\ekvcValueSplit@recover}
-% This splits off a single value.
-% \begin{macrocode}
-\long\def\ekvcValueSplit#1%
- {\expandafter\ekvcValueSplit@\detokenize{#1}\ekvc@stop}
-\def\ekvcValueSplit@#1\ekvc@stop
- {%
- \ekv@ifdefined{ekvc@safesplithash@#1}%
- {\csname ekvc@safesplithash@#1\endcsname}%
- {\ekvc@err@unknown@hash{#1}\ekvcValueSplit@recover}%
- }
-\long\def\ekvcValueSplit@recover#1#2{#2{}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@safe@after@hash}
-% \begin{macrocode}
-\long\def\ekvc@safe@after@hash#1#2%
- {%
- #2{#1}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcValueSplitFast}
-% Again a fast approach which doesn't provide too many safety measurements.
-% This needs to build the hash function and expand it before passing the
-% results to the next control sequence. The first step only builds the control
-% sequence.
-% \begin{macrocode}
-\long\def\ekvcValueSplitFast#1#2%
- {\csname ekvc@fastsplithash@\detokenize{#1}\endcsname#2\ekvc@stop}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@safehash@,\ekvc@fasthash@,
-% \ekvc@safesplithash@,\ekvc@fastsplithash@
-% }
-% At least in the empty hash case we can provide a meaningful error message
-% without affecting performance by just defining the macro that would be build
-% in that case. There is of course a downside to this, the error will not be
-% thrown by |\ekvcValueFast| in three expansion steps. The safe hash variant
-% has to also stop the |\unexpanded| expansion.
-% \begin{macrocode}
-\long\def\ekvc@safehash@#1{\ekvc@err@empty@hash{}}
-\long\def\ekvc@fasthash@#1\ekvc@stop{\ekvc@err@empty@hash}
-\long\def\ekvc@safesplithash@#1#2{\ekvc@err@empty@hash#2{}}
-\long\def\ekvc@fastsplithash@#1\ekvc@stop#2{\ekvc@err@empty@hash#2{}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcSecondaryKeys}
-% \begin{macro}[internal]
-% {\ekvcSecondaryKeys@a,\ekvcSecondaryKeys@b,\ekvcSecondaryKeys@c}
-% The secondary keys are defined pretty similar to the way the originals are,
-% but here we also introduce some key types (those have a |@t@| in their name)
-% additionally to the prefixes.
-% \begin{macrocode}
-\protected\long\def\ekvcSecondaryKeys#1#2%
- {%
- \edef\ekvc@set{\string#1}%
- \ekvparse\ekvc@err@value@required\ekvcSecondaryKeys@a{#2}%
- }
-\protected\long\def\ekvcSecondaryKeys@a#1%
- {\expandafter\ekvcSecondaryKeys@b\detokenize{#1}\ekvc@stop}
-\protected\def\ekvcSecondaryKeys@b#1\ekvc@stop
- {%
- \let\ekvc@long\ekv@empty
- \ekvc@ifspace{#1}%
- {\ekvcSecondaryKeys@c#1\ekvc@stop}%
- {\ekvc@err@missing@type{#1}\@gobble}%
- }
-\protected\def\ekvcSecondaryKeys@c#1 #2\ekvc@stop
- {%
- \ekv@ifdefined{ekvc@p@#1}%
- {\csname ekvc@p@#1\endcsname}%
- {%
- \ekv@ifdefined{ekvc@t@#1}%
- {\csname ekvc@t@#1\endcsname}%
- {\ekvc@err@unknown@keytype{#1}\@firstoftwo\@gobble}%
- }%
- {#2}%
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\ekvcChange}
-% This can be used to change the defaults of an \expkvc\ defined macro. It
-% checks whether there is a set with the correct name and that the macro is
-% defined. If both is true the real work is done by |\ekvc@change|.
-% \begin{macrocode}
-\protected\long\def\ekvcChange#1%
- {%
- \ekvifdefinedset{\string#1}%
- {%
- \ekvc@ifdefined#1%
- {\ekvc@change#1}%
- {\ekvc@err@no@key@macro#1\@gobble}%
- }%
- {\ekvc@err@no@key@macro#1\@gobble}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@change ,\ekvc@change@a,\ekvc@change@b,
-% \ekvc@change@c,\ekvc@change@d,\ekvc@change@e
-% }
-% First we need to see whether the macro is currently |\long|. For this we get
-% the meaning and will parse it. |#1| is the macro name in which we want to
-% change the defaults.
-% \begin{macrocode}
-\protected\def\ekvc@change#1%
- {\expandafter\ekvc@change@a\meaning#1\ekv@stop#1}
-% \end{macrocode}
-% A temporary definition to get the stringified |macro:|. |##1| will be the
-% list of prefixes, we don't care for the exact contents of |##2| and |##3|.
-% \begin{macrocode}
-\def\ekvc@change@a#1%
- {%
- \protected\def\ekvc@change@a##1#1##2->##3\ekv@stop
- {%
- \ekvc@change@iflong{##1}%
- {\ekvc@change@b{}}%
- {\ekvc@change@b{\long}}%
- }%
- }
-\expandafter\ekvc@change@a\expandafter{\detokenize{macro:}}
-% \end{macrocode}
-% Next we expand the macro once to get its contents (including the current
-% default values with their markers) and place |\ekvc@stop| instead of an
-% argument as a marker for the last step. |#1| is either |\long| or empty,
-% |#2| is the macro.
-% \begin{macrocode}
-\protected\def\ekvc@change@b#1#2%
- {\expandafter\ekvc@change@c\expandafter{#2\ekvc@stop}{#1}#2}
-% \end{macrocode}
-% Here we place an unbalanced closing brace after the expansion of the macro.
-% Then we just parse the \kv-list with |\ekvset|, that will exchange the
-% values behind the markers. Once those are changed we give control to
-% |\ekvc@change@d|. The |\ekvset| step might horribly fail if the user defined
-% some keys that don't behave nice. |#1| is the expansion of the macro, |#2|
-% is either |\long| or empty, |#3| is the macro, and |#4| is the \kv-list
-% containing the new defaults.
-% \begin{macrocode}
-\ekv@exparg{\protected\long\def\ekvc@change@c#1#2#3#4}%
- {%
- \expandafter\iffalse\expandafter{\expandafter{\expandafter\fi
- \ekvset{\string#3}{#4}%
- \ekvc@change@d{#2}{#3}%
- #1%
- }}%
- }
-% \end{macrocode}
-% The final step needs to put an unbalanced opening brace after |\edef|. Also
-% we have to protect everything from further expanding with the exception of
-% the redefined macro's argument, which is why we placed the |\ekvc@stop|
-% earlier. Then we need to also protect the rest of the contents from further
-% expanding using |\unexpanded| with another unbalanced opening brace.
-% |#1| will be either empty or |\long| and |#2| is the macro.
-% \begin{macrocode}
-\protected\def\ekvc@change@d#1#2%
- {#1\edef#2##1{\expandafter\ekvc@change@e\iffalse}\fi}
-\long\def\ekvc@change@e#1\ekvc@stop
- {\ekv@unexpanded{#1}##1\ekv@unexpanded\expandafter{\iffalse}\fi}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@change@iflong,\ekvc@change@iflong@}
-% Checking whether a string contains the string representation of |\long| can
-% be done by gobbling everything up to the first |\long| and checking whether
-% the result is completely empty. We need a temporary macro to get the result
-% of |\string\long| inside the definitions.
-% \begin{macrocode}
-\def\ekvc@change@iflong#1%
- {%
- \protected\def\ekvc@change@iflong##1%
- {\expandafter\ekv@ifempty\expandafter{\ekvc@change@iflong@##1#1}}%
- \def\ekvc@change@iflong@##1#1{}
- }
-\expandafter\ekvc@change@iflong\expandafter{\string\long}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcPass}
-% This macro can be used to pass a value to a key of some macro (this way
-% more complicated key codes are possible that in the end pass processed
-% values on to some macro). The implemantation is pretty straight forward.
-% \begin{macrocode}
-\long\def\ekvcPass#1#2%
- {%
- \ekvifdefined{\string#1}{#2}%
- {\csname\ekv@name{\string#1}{#2}\endcsname}%
- {\ekvc@err@unknown@key@or@macro{#1}{#2}\@gobble}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsubsection{Secondary Key Types}
-%
-% \begin{macro}[internal]{\ekvc@p@long,\ekvc@after@ptype}
-% The prefixes are pretty straight forward again. Just set |\ekvc@long| and
-% forward to the |@t@| type.
-% \begin{macrocode}
-\protected\def\ekvc@p@long#1%
- {%
- \ekvc@ifspace{#1}%
- {%
- \let\ekvc@long\long
- \ekvc@after@ptype#1\ekvc@stop
- }%
- {\ekvc@err@missing@type{long #1}\@gobble}%
- }
-\protected\def\ekvc@after@ptype#1 #2\ekvc@stop
- {%
- \ekv@ifdefined{ekvc@t@#1}%
- {\csname ekvc@t@#1\endcsname{#2}}%
- {\ekvc@err@unknown@keytype{#1}\@gobble}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@t@meta, \ekvc@t@nmeta,
-% \ekvc@type@meta, \ekvc@type@meta@a, \ekvc@type@meta@b
-% }
-% The |meta| and |nmeta| key types use a nested |\ekvset| to set other keys in
-% the same macro's \set.
-% \begin{macrocode}
-\protected\def\ekvc@t@meta
- {%
- \edef\ekvc@tmp{\ekvc@set}%
- \expandafter\ekvc@type@meta\expandafter{\ekvc@tmp}\ekvc@long{##1}\ekvlet
- }
-\protected\def\ekvc@t@nmeta#1%
- {%
- \ekvc@assert@not@long{nmeta #1}%
- \edef\ekvc@tmp{\ekvc@set}%
- \expandafter\ekvc@type@meta\expandafter{\ekvc@tmp}{}{}\ekvletNoVal{#1}%
- }
-\protected\long\def\ekvc@type@meta#1#2#3#4#5#6%
- {%
- \expandafter\ekvc@type@meta@a\expandafter{\ekvset{#1}{#6}}{#2}{#3}%
- #4\ekvc@set{#5}\ekvc@tmp
- }
-\protected\def\ekvc@type@meta@a
- {%
- \expandafter\ekvc@type@meta@b\expandafter
- }
-\protected\long\def\ekvc@type@meta@b#1#2#3%
- {%
- #2\def\ekvc@tmp#3{#1}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@t@alias}
-% |alias| just checks whether there is a key and/or |NoVal| key defined with
-% the target name and |\let| the key to those.
-% \begin{macrocode}
-\protected\def\ekvc@t@alias#1#2%
- {%
- \ekvc@assert@not@long{alias #1}%
- \let\ekvc@tmp\@firstofone
- \ekvifdefined\ekvc@set{#2}%
- {%
- \ekvletkv\ekvc@set{#1}\ekvc@set{#2}%
- \let\ekvc@tmp\@gobble
- }%
- {}%
- \ekvifdefinedNoVal\ekvc@set{#2}%
- {%
- \ekvletkvNoVal\ekvc@set{#1}\ekvc@set{#2}%
- \let\ekvc@tmp\@gobble
- }%
- {}%
- \ekvc@tmp{\ekvc@err@unknown@key{#2}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@t@default}
-% The |default| key can be used to set a |NoVal| key for an existing key. It
-% will just pass the \val\ to the key macro of that other key.
-% \begin{macrocode}
-\protected\long\def\ekvc@t@default#1#2%
- {%
- \ekvifdefined\ekvc@set{#1}%
- {%
- \ekvc@assert@not@long{default #1}%
- \edef\ekvc@tmp
- {%
- \ekv@unexpanded\expandafter
- {\csname\ekv@name\ekvc@set{#1}\endcsname{#2}}%
- }%
- \ekvletNoVal\ekvc@set{#1}\ekvc@tmp
- }%
- {\ekvc@err@unknown@key{#1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@t@enum}
-% \begin{macro}[internal]
-% {\ekvc@type@enum,\ekvc@h@enum,\ekvc@h@enum@,\ekvc@enum@name}
-% Enums don't need to apply special trickery to make the parts of the names
-% retrievable, so unlike in \expkvd\ we don't need catcode juggling.
-% The setup of an |enum| requires unpacking the value in two different
-% arguments so we need an auxiliary here.
-% \begin{macrocode}
-\def\ekvc@enum@name#1#2#3{ekvc#1(#2)#3}
-\protected\long\def\ekvc@t@enum#1#2%
- {\ekvc@assert@twoargs{#2}{enum #1}{\ekvc@type@enum{#1}#2}}
-\protected\long\def\ekvc@type@enum#1#2%
- {%
- \ekvifdefined\ekvc@set{#2}%
- {%
-% \end{macrocode}
-% At run time we need another helper and we need to expand the current
-% |\ekvc@set| now. The helper will build a control sequence from each given
-% value, those will be set up in the |\ekvcsvloop|.
-% \begin{macrocode}
- \ekvc@long\edef\ekvc@tmp##1%
- {%
- \ekv@unexpanded{\expandafter\ekvc@h@enum\detokenize}{##1}%
- \ekv@unexpanded{\ekvc@stop}%
- {\ekvc@set}{#1}%
- }%
- \ekvlet\ekvc@set{#1}\ekvc@tmp
- \def\ekvc@tmp{0}%
- \expandafter\ekvcsvloop\expandafter
- {%
- \expandafter\ekvc@type@enum@
- \csname\ekv@name\ekvc@set{#2}\endcsname
- {#1}%
- }%
- }%
- {%
- \ekvc@err@unknown@key{#2}%
- \@gobble
- }%
- }
-% \end{macrocode}
-% Here |#1| will be the key-macro of the underlying primary or secondary key,
-% |#2| is the |enum| key's name, and |#3| will be the choice. The rest is
-% pretty obvious.
-% \begin{macrocode}
-\ekv@exparg{\protected\long\def\ekvc@type@enum@#1#2#3}%
- {%
- \expandafter\expandafter\expandafter\edef\expandafter
- \csname\ekvc@enum@name\ekvc@set{#2}{\detokenize{#3}}\endcsname
- {\ekv@unexpanded{#1}{\ekvc@tmp}}%
- \edef\ekvc@tmp{\the\numexpr\ekvc@tmp+1\relax}%
- }
-% \end{macrocode}
-% The use-time helper will check if the macro for the passed in choice exists,
-% if it doesn't throws an error, else calls that macro which will set the
-% correct value.
-% \begin{macrocode}
-\ekv@if@lastnamedcs
- {%
- \ekv@exparg{\def\ekvc@h@enum#1\ekvc@stop#2#3}%
- {%
- \expandafter\ifcsname\ekvc@enum@name{#2}{#3}{#1}\endcsname
- \expandafter\ekvc@h@enum@\lastnamedcs
- \fi
- \ekvc@err@unknown@enum{#2}{#3}{#1}%
- }
- \def\ekvc@h@enum@#1\fi\ekvc@err@unknown@enum#2#3#4%
- {%
- \fi
- \ifx#1\relax
- \ekvc@err@unknown@enum{#2}{#3}{#4}%
- \expandafter\@gobble
- \fi
- #1%
- }
- }
- {%
- \def\ekvc@h@enum#1%
- {%
- \def\ekvc@h@enum##1\ekvc@stop##2##3%
- {%
- \expandafter\ekvc@h@enum@
- \csname\ifcsname#1\endcsname#1\else relax\fi\endcsname
- {##2}{##3}{##1}%
- }%
- }
- \expandafter\ekvc@h@enum\expandafter{\ekvc@enum@name{#2}{#3}{#1}}
- \def\ekvc@h@enum@#1#2#3#4%
- {%
- \ifx#1\relax
- \ekvc@err@unknown@enum{#2}{#3}{#4}%
- \expandafter\@gobble
- \fi
- #1%
- }
- }
-% \end{macrocode}
-% We don't need |\ekvc@enum@name| anymore, so let's undefine it.
-% \begin{macrocode}
-\let\ekvc@enum@name\ekvc@undefined
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@t@aggregate}
-% Aggregating isn't easy to define. We'll have to extract the correct mark for
-% the specified key, branch correctly for short and long keys, and use a small
-% hack to have the correct arguments on the user interface (|#1| as the
-% current contents, |#2| as the new value). This is split into a few steps
-% here.
-%
-% First, assert that the user input is well-behaved.
-% \begin{macrocode}
-\protected\def\ekvc@t@aggregate#1%
- {%
- \ekvc@assert@not@long{aggregate #1}%
- \ekvc@type@aggregate
- \ekvc@type@aggregate@long\ekvc@type@aggregate@short
- {process}%
- {#1}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekvc@type@aggregate,\ekvc@type@aggregate@a,\ekvc@type@aggregate@b}
-% The next step stores the user defined processing in a temporary macro that's
-% used to do the parameter number swapping later. It also builds the names of
-% the key macro and the helper which would be used for processing a short key.
-% \begin{macrocode}
-\protected\long\def\ekvc@type@aggregate#1#2#3#4#5%
- {%
- \ekvc@assert@twoargs{#5}{#3 #4}{\ekvc@type@aggregate@a#1#2{#4}#5}%
- }
-\protected\long\def\ekvc@type@aggregate@a#1#2#3#4#5%
- {%
- \ekvifdefined\ekvc@set{#4}%
- {%
- \def\ekvc@type@aggregate@tmp##1##2{#5}%
- \begingroup\expandafter\endgroup
- \expandafter\ekvc@type@aggregate@b
- \csname\ekv@name\ekvc@set{#4}\expandafter\endcsname
- \csname ekvc@\ekvc@set(#4)\endcsname
- #1#2%
- {#3}%
- }%
- {\ekvc@err@unknown@key{#4}}%
- }
-\protected\long\def\ekvc@type@aggregate@b#1#2#3#4%
- {%
- \ekvc@type@aggregate@check@long#1#2%
- {#3#1}%
- {#4#2}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@type@aggregate@check@long,
-% \ekvc@type@aggregate@check@long@a,\ekvc@type@aggregate@check@long@b
-% }
-% To check whether the primary key is long we see whether its |\meaning|
-% contains the helper which would only be there for short keys. For this we
-% have to get the stringified name of the internal (using |\detokenize|),
-% and afterwards get the |\meaning| of the macro. A temporary helper does the
-% real test by gobbling and forwarding the result to |\ekv@ifempty|.
-% \begin{macrocode}
-\protected\long\def\ekvc@type@aggregate@check@long#1#2%
- {\expandafter\ekvc@type@aggregate@check@long@a\detokenize{#2}\ekv@stop#1}
-\protected\long\def\ekvc@type@aggregate@check@long@a#1\ekv@stop#2%
- {%
- \def\ekvc@type@aggregate@check@long@@##1#1{}%
- \expandafter\ekvc@type@aggregate@check@long@b\meaning#2\ekv@stop{#1}%
- }
-\protected\def\ekvc@type@aggregate@check@long@b#1\ekv@stop#2%
- {\expandafter\ekv@ifempty\expandafter{\ekvc@type@aggregate@check@long@@#1#2}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@type@aggregate@long,\ekvc@type@aggregate@long@}
-% The long variant just builds the split mark we extract, uses the hack to
-% swap argument order, and then does the definition via |\ekvlet| and a
-% temporary macro.
-% \begin{macrocode}
-\protected\long\def\ekvc@type@aggregate@long#1%
- {%
- \begingroup\expandafter\endgroup\expandafter
- \ekvc@type@aggregate@long@
- \csname\ekvc@extract@mark#1\expandafter\endcsname
- \expandafter{\ekvc@type@aggregate@tmp{##3}{##1}}%
- }
-\protected\long\def\ekvc@type@aggregate@long@#1#2#3%
- {%
- \long\def\ekvc@type@aggregate@tmp##1##2#1##3{##2#1{#2}}
- \ekvlet\ekvc@set{#3}\ekvc@type@aggregate@tmp
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekvc@type@aggregate@short,\ekvc@type@aggregate@short@}
-% The short variant will have to build the marker and the name of the helper
-% function, and swap the user argument order. Hence here are a few more
-% |\expandafter|s involved. But afterwards we can do the definition of the key
-% and the helper macro directly.
-% \begin{macrocode}
-\protected\long\def\ekvc@type@aggregate@short#1#2%
- {%
- \begingroup\expandafter\endgroup\expandafter
- \ekvc@type@aggregate@short@
- \csname\ekvc@extract@mark#1\expandafter\endcsname
- \csname ekvc@\ekvc@set(#2)\expandafter\endcsname
- \expandafter{\ekvc@type@aggregate@tmp{##3}{##1}}%
- {#2}%
- }
-\protected\long\def\ekvc@type@aggregate@short@#1#2#3#4%
- {%
- \ekvdef\ekvc@set{#4}{#2{##1}}%
- \long\def#2##1##2#1##3{##2#1{#3}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@t@process}
-% The |process| type can reuse much of |aggregate|, just the last step of
-% definition differ.
-% \begin{macrocode}
-\protected\def\ekvc@t@process
- {%
- \ifx\ekvc@long\long
- \ekv@fi@firstoftwo
- \fi
- \@secondoftwo
- {%
- \ekvc@type@aggregate
- \ekvc@type@process@long\ekvc@type@process@long
- }%
- {%
- \ekvc@type@aggregate
- \ekvc@type@process@short\ekvc@type@process@short
- }%
- {process}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@type@process@long,\ekvc@type@process@long@}
-% This defines a temporary macro to grab the current value (found after the
-% marker |#1|), executes the user code and puts everything back to where it
-% belongs. Then |\ekvlet| is used to assign that meaning to the key macro.
-% \begin{macrocode}
-\protected\long\def\ekvc@type@process@long#1%
- {%
- \begingroup\expandafter\endgroup\expandafter
- \ekvc@type@process@long@
- \csname\ekvc@extract@mark#1\expandafter\endcsname
- \expandafter{\ekvc@type@aggregate@tmp{##3}{##1}}%
- }
-\protected\long\def\ekvc@type@process@long@#1#2#3%
- {%
- \long\def\ekvc@type@aggregate@tmp##1##2#1##3{#2##2#1{##3}}%
- \ekvlet\ekvc@set{#3}\ekvc@type@aggregate@tmp
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@type@process@short,\ekvc@type@process@short@}
-% We define the key macro directly to just grab the argument once and forward
-% it to the auxiliary. That one does essentially the same as the long variant.
-% \begin{macrocode}
-\protected\long\def\ekvc@type@process@short#1#2%
- {%
- \begingroup\expandafter\endgroup\expandafter
- \ekvc@type@process@short@
- \csname\ekvc@extract@mark#1\expandafter\endcsname
- \csname ekvc@\ekvc@set(#2)\expandafter\endcsname
- \expandafter{\ekvc@type@aggregate@tmp{##3}{##1}}%
- {#2}%
- }
-\protected\long\def\ekvc@type@process@short@#1#2#3#4%
- {%
- \ekvdef\ekvc@set{#4}{#2{##1}}%
- \long\def#2##1##2#1##3{#3##2#1{##3}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@t@flag-bool}
-% \begin{macrocode}
-\protected\expandafter\def\csname ekvc@t@flag-bool\endcsname#1#2%
- {%
- \ekvc@assert@not@long{flag-bool #1}%
- \unless\ifdefined#2\ekvcFlagNew#2\fi
- \ekvdef\ekvc@set{#1}%
- {%
- \ekv@ifdefined{ekvc@flag@set@##1}%
- {%
- \csname ekvc@flag@set@##1\expandafter\endcsname
- \ekvcFlagHeight#2\ekv@stop#2%
- }%
- {\ekvc@err@invalid@bool{##1}}%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekvc@t@flag-true,\ekvc@t@flag-false,\ekvc@t@flag-raise,\ekvc@type@flag}
-% \begin{macrocode}
-\protected\def\ekvc@type@flag#1#2#3#4%
- {%
- \ekvc@assert@not@long{flag-#1 #3}%
- \unless\ifdefined#4\ekvcFlagNew#4\fi
- \ekv@exparg{\ekvdefNoVal\ekvc@set{#3}}{#2#4}%
- }
-\protected\expandafter\def\csname ekvc@t@flag-true\endcsname
- {\ekvc@type@flag{true}\ekvcFlagSetTrue}
-\protected\expandafter\def\csname ekvc@t@flag-false\endcsname
- {\ekvc@type@flag{false}\ekvcFlagSetFalse}
-\protected\expandafter\def\csname ekvc@t@flag-raise\endcsname
- {\ekvc@type@flag{raise}\ekvcFlagRaise}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsubsection{Flags}
-%
-% The basic idea of flags is to store information by the fact that \TeX\
-% expandably assigns the meaning |\relax| to undefined control sequences which
-% were built with |\csname|. This mechanism is borrowed from \pkg{expl3}.
-%
-% \begin{macro}[internal]{\ekvc@flag@name,\ekvc@flag@namescheme}
-% Flags follow a simple naming scheme which we define here. |\ekvc@flag@name|
-% will store the name of an internal function that is used to build names of
-% the second naming scheme defined by |\ekvc@flag@namescheme|.
-% \begin{macrocode}
-\def\ekvc@flag@name{ekvcf\string}
-\def\ekvc@flag@namescheme#1#2{ekvch#2#1}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcFlagHeight}
-% For semantic reasons we use |\number| with another name.
-% \begin{macrocode}
-\let\ekvcFlagHeight\number
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcFlagNew}
-% This macro defines a new flag. It stores the function build with the
-% |\ekvc@flag@name| naming scheme after the internal function
-% |\ekvc@flag@height| that'll determine the current flag height. It'll also
-% define the macro named via |\ekvc@flag@name| to build names according to
-% |\ekvc@flag@namescheme|.
-% \begin{macrocode}
-\protected\def\ekvcFlagNew#1%
- {%
- \edef#1%
- {%
- \ekv@unexpanded{\ekvc@flag@height}%
- \ekv@unexpanded\expandafter{\csname\ekvc@flag@name#1\endcsname}%
- }%
- \ekv@expargtwice
- {\expandafter\def\csname\ekvc@flag@name#1\endcsname##1}%
- {\expandafter\ekvc@flag@namescheme\expandafter{\string#1}{##1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@flag@height,\ekvc@flag@height@}
-% This macro gets the height of a flag by a simple loop. The first loop
-% iteration differs a bit from the following in that it doesn't have to get
-% the current iteration count. The space at the end of |\ekvc@flag@height|
-% ends the |\number| evaluation.
-% \begin{macrocode}
-\def\ekvc@flag@height#1%
- {%
- \ifcsname#10\endcsname
- \ekvc@flag@height@1\ekv@stop#1%
- \fi
- \@firstofone{0} % leave this space
- }
-\def\ekvc@flag@height@#1\ekv@stop#2\fi\@firstofone#3%
- {%
- \fi
- \ifcsname#2{#1}\endcsname
- \expandafter\ekvc@flag@height@\the\numexpr#1+1\relax\ekv@stop#2%
- \fi
- \@firstofone{#1}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcFlagRaise}
-% Raising a flag simply means letting the |\ekvc@flag@namescheme| macro for
-% the current height to relax. The result of raising a flag is that its height
-% is bigger by $1$.
-% \begin{macrocode}
-\ekv@exparg{\def\ekvcFlagRaise#1}%
- {%
- \expandafter\expandafter\expandafter\@gobble\expandafter
- \csname\ekvc@flag@namescheme{\string#1}{\ekvcFlagHeight#1}\endcsname
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcFlagSetTrue,\ekvcFlagSetFalse}
-% \begin{macro}[internal]{\ekvc@flag@set@true,\ekvc@flag@set@false}
-% A flag is considered true if its current height is odd, and as false if it
-% is even. Therefore |\ekvcFlagSetTrue| and |\ekvcFlagSetFalse| only need to
-% raise the flag if the opposing boolean value is the current one.
-% \begin{macrocode}
-\def\ekvcFlagSetTrue#1%
- {\expandafter\ekvc@flag@set@true\ekvcFlagHeight#1\ekv@stop#1}
-\def\ekvcFlagSetFalse#1%
- {\expandafter\ekvc@flag@set@false\ekvcFlagHeight#1\ekv@stop#1}
-% \end{macrocode}
-% We can expand |\ekvc@flag@namescheme| at definition time here, which is why
-% we're using a temporary definition to set up |\ekvc@flag@set@true| and
-% |\ekvc@flag@set@false|.
-% \begin{macrocode}
-\def\ekvc@flag@set@true#1%
- {%
- \def\ekvc@flag@set@true##1\ekv@stop##2%
- {%
- \ifodd##1
- \ekv@fi@gobble
- \fi
- \@firstofone{\expandafter\@gobble\csname#1\endcsname}%
- }%
- \def\ekvc@flag@set@false##1\ekv@stop##2%
- {%
- \ifodd##1
- \ekv@fi@firstofone
- \fi
- \@gobble{\expandafter\@gobble\csname#1\endcsname}%
- }%
- }
-\expandafter\ekvc@flag@set@true\expandafter
- {\ekvc@flag@namescheme{\string#2}{#1}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\ekvcFlagIf}
-% As already explained, truthiness is defined as a flag's height being odd, so
-% we just branch accordingly here.
-% \begin{macrocode}
-\def\ekvcFlagIf#1%
- {%
- \ifodd#1%
- \ekv@fi@firstoftwo
- \fi
- \@secondoftwo
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcFlagIfRaised}
-% This macro uses flags as a switch, if a flag's current height is bigger than
-% $0$ this test yields true.
-% \begin{macrocode}
-\ekv@exparg{\def\ekvcFlagIfRaised#1}%
- {%
- \expandafter\ifcsname\ekvc@flag@namescheme{\string#1}0\endcsname
- \ekv@fi@firstoftwo
- \fi
- \@secondoftwo
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcFlagReset}
-% \begin{macro}[internal]{\ekvc@flag@reset,\ekvc@flag@reset@}
-% Resetting works by locally letting all the defined internal macros named
-% after |\ekvc@flag@namescheme| to undefined.
-% \begin{macrocode}
-\protected\def\ekvcFlagReset#1%
- {\expandafter\ekvc@flag@reset\csname\ekvc@flag@name#1\endcsname}
-\protected\def\ekvc@flag@reset#1%
- {%
- \ifcsname#10\endcsname
- \expandafter\let\csname#10\endcsname\ekvc@undefined
- \ekvc@flag@reset@1\ekv@stop#1%
- \fi
- }
-\protected\def\ekvc@flag@reset@#1\ekv@stop#2\fi
- {%
- \fi
- \ifcsname#2{#1}\endcsname
- \expandafter\let\csname#2{#1}\endcsname\ekvc@undefined
- \expandafter\ekvc@flag@reset@\the\numexpr#1+1\relax\ekv@stop#2%
- \fi
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\ekvcFlagGetHeight}
-% \begin{macro}[internal]{\ekvc@flag@get@height@single}
-% These are just small helpers, first getting the height of the flag and then
-% passing it on to the user supplied code.
-% \begin{macrocode}
-\def\ekvcFlagGetHeight#1%
- {\expandafter\ekvc@flag@get@height@single\ekvcFlagHeight#1\ekv@stop}
-\long\def\ekvc@flag@get@height@single#1\ekv@stop#2{#2{#1}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\ekvcFlagGetHeights}
-% \begin{macro}[internal]
-% {\ekvc@flag@get@heights,\ekvc@flag@get@heights@,\ekvc@flag@get@heights@done}
-% This works by a simple loop that stops at |\ekv@stop|. As long as that
-% marker isn't hit, get the next flags height and put it into a list after
-% |\ekv@stop|. |\ekvc@flag@get@heights@| uses the same marker name for the
-% end of the height, which shouldn't clash in any case. Once we're done we
-% remove the remainder of the current iteration and leave the user supplied
-% code in the input stream with all the flags' heights as a single argument.
-% \begin{macrocode}
-\def\ekvcFlagGetHeights#1%
- {%
- \ekvc@flag@get@heights#1\ekv@stop{}%
- }
-\def\ekvc@flag@get@heights#1%
- {%
- \ekv@gobbleto@stop#1\ekvc@flag@get@heights@done\ekv@stop
- \expandafter\ekvc@flag@get@heights@\ekvcFlagHeight#1\ekv@stop
- }
-\def\ekvc@flag@get@heights@#1\ekv@stop#2\ekv@stop#3%
- {\ekvc@flag@get@heights#2\ekv@stop{#3{#1}}}
-\long\def\ekvc@flag@get@heights@done
- \ekv@stop
- \expandafter\ekvc@flag@get@heights@\ekvcFlagHeight\ekv@stop\ekv@stop#1#2%
- {#2{#1}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-%
-% \subsubsection{Helper Macros}
-%
-% \begin{macro}[internal]{\ekvc@ifspace,\ekvc@ifspace@}
-% A test which can be reduced to an if-empty by gobbling everything up to the
-% first space.
-% \begin{macrocode}
-\long\def\ekvc@ifspace#1%
- {%
- \ekvc@ifspace@#1 \ekv@ifempty@B
- \ekv@ifempty@false\ekv@ifempty@A\ekv@ifempty@B\@firstoftwo
- }
-\long\def\ekvc@ifspace@#1 % keep this space
- {%
- \ekv@ifempty@\ekv@ifempty@A
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@ifnottwoargs,\ekvc@ifempty@gtwo}
-% Used to test whether a token list contains exactly two \TeX\ arguments.
-% \begin{macrocode}
-\long\def\ekvc@ifnottwoargs#1%
- {%
- \ekvc@ifempty@gtwo#1\ekv@ifempty@B
- \ekv@ifempty@false\ekv@ifempty@A\ekv@ifempty@B\@firstoftwo
- }
-\long\def\ekvc@ifempty@gtwo#1#2{\ekv@ifempty@\ekv@ifempty@A}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@extract@mark,\ekvc@extract@mark@}
-% This is used to extract the mark of a split or hash key from its definition.
-% This is kind of fragile, it assumes |#1| is always a macro used for hashing
-% or splitting. Also it assumes that the escape character is a backslash.
-% \begin{macrocode}
-\def\ekvc@extract@mark#1{\expandafter\ekvc@extract@mark@\meaning#1\ekv@stop}
-\begingroup
-\lccode`;=`#
-\lccode`/=`\\
-\lowercase{\endgroup
-\def\ekvc@extract@mark@#1:#2/#3 ;#4\ekv@stop{#3}%
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsubsection{Assertions}
-% \begin{macro}[internal]{\ekvc@assert@not@long}
-% Some keys don't want to be |long| and we have to educate the user, so let's
-% throw an error if someone wanted these to be long.
-% \begin{macrocode}
-\long\def\ekvc@assert@not@long#1{\ifx\ekvc@long\long\ekvc@err@no@long{#1}\fi}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@assert@twoargs}
-% Some keys need exactly two arguments as their definition, so we have to
-% somehow assert this.
-% \begin{macrocode}
-\protected\long\def\ekvc@assert@twoargs#1#2%
- {\ekvc@ifnottwoargs{#1}{\ekvc@err@not@two{#2}}}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsubsection{Messages}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@err@toomany,\ekvc@err@value@required,\ekvc@err@missing@type,
-% \ekvc@err@already@defined,\ekvc@err@no@key@macro,
-% \ekvc@err@not@two
-% }
-% Boring unexpandable error messages.
-% \begin{macrocode}
-\protected\def\ekvc@err@toomany#1%
- {%
- \errmessage{expkv-cs Error: Too many keys for macro `\string#1'}%
- }
-\protected\long\def\ekvc@err@value@required#1%
- {%
- \errmessage{expkv-cs Error: Missing value for key `\ekv@unexpanded{#1}'}%
- }
-\protected\long\def\ekvc@err@missing@type#1%
- {%
- \errmessage
- {expkv-cs Error: Missing type for secondary key `\ekv@unexpanded{#1}'}%
- }
-\protected\long\def\ekvc@err@no@long#1%
- {%
- \errmessage
- {expkv-cs Error: prefix `long' not accepted for `\ekv@unexpanded{#1}'}%
- }
-\protected\long\def\ekvc@err@already@defined#1%
- {%
- \errmessage{expkv-cs Error: Macro `\string#1' already defined}%
- }
-\protected\long\def\ekvc@err@unknown@keytype#1%
- {%
- \errmessage{expkv-cs Error: Unknown key type `\ekv@unexpanded{#1}'}%
- }
-\protected\long\def\ekvc@err@unknown@key#1%
- {%
- \errmessage
- {expkv-cs Error: Unknown key `\ekv@unexpanded{#1}' for macro `\ekvc@set'}%
- }
-\protected\long\def\ekvc@err@no@key@macro#1%
- {\errmessage{expkv-cs Error: \string#1 is no key=val macro}}
-\protected\long\def\ekvc@err@not@two#1%
- {%
- \errmessage
- {%
- expkv-cs Error: Definition of `\ekv@unexpanded{#1}' doesn't contain
- exactly two arguments%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvc@err}
-% We need a way to throw error messages expandably in some contexts.
-% \begin{macrocode}
-\ekv@exparg{\long\def\ekvc@err#1}{\ekverr{expkv-cs}{#1}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvc@err@unknown@hash,\ekvc@err@empty@hash,\ekvc@err@missing@hash,
-% \ekvc@err@invalid@bool,\ekvc@err@unknown@enum
-% }
-% And here are the expandable error messages.
-% \begin{macrocode}
-\long\def\ekvc@err@unknown@hash#1{\ekvc@err{unknown hash `#1'}}
-\long\def\ekvc@err@missing@hash#1{\ekvc@err{hash `#1' not found}}
-\long\def\ekvc@err@empty@hash{\ekvc@err{empty hash}}
-\def\ekvc@err@invalid@bool#1{\ekvc@err{invalid boolean value `#1'}}
-\long\def\ekvc@err@unknown@key@or@macro#1#2%
- {\ekvc@err{unknown key `#2' for macro #1}}
-\def\ekvc@err@unknown@enum#1#2#3%
- {\ekvc@err{unknown value `#3' for enum `#2' in macro #1}}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% Now everything that's left is to reset the category code of |@|.
-% \begin{macrocode}
-\catcode`\@=\ekvc@tmp
-% \end{macrocode}
-%
-% \gobbledocstriptag
-%</tex>
-%^^A=<<
-%
-%^^A=<<
-%
-% \end{implementation}^^A=<<
-%
-% \clearpage
-% \PrintIndex
-%
-\endinput
-%
-^^A vim: ft=tex fdm=marker fmr=>>=,=<<
diff --git a/obsolete/macros/generic/expkv-cs/expkv-cs.pdf b/obsolete/macros/generic/expkv-cs/expkv-cs.pdf
deleted file mode 100644
index 0c37223ebf..0000000000
--- a/obsolete/macros/generic/expkv-cs/expkv-cs.pdf
+++ /dev/null
Binary files differ
diff --git a/obsolete/macros/generic/expkv-def/README.md b/obsolete/macros/generic/expkv-def/README.md
deleted file mode 100644
index 79a69057e4..0000000000
--- a/obsolete/macros/generic/expkv-def/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
--------------------------------------------------------------------------------
-# expkv-def -- a key-defining frontend for expkv
-
-Version 2022-01-29 v0.9
-
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
-
-Hosted at https://github.com/Skillmon/tex_expkv-def
-
--------------------------------------------------------------------------------
-
-Copyright (C) 2020-2021 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.
-
--------------------------------------------------------------------------------
-
-This provides a key=val frontend to define keys for
-[`expkv`](https://github.com/Skillmon/tex_expkv). It is generic code and only
-requires `expkv` for its parsing. There is a LaTeX package `expkv-def.sty`
-included to play nice on LaTeX's package loading system, but that package is not
-needed and does not provide more functionality than the generic code in
-`expkv-def.tex`.
diff --git a/obsolete/macros/generic/expkv-def/expkv-def.dtx b/obsolete/macros/generic/expkv-def/expkv-def.dtx
deleted file mode 100644
index 059c7dda01..0000000000
--- a/obsolete/macros/generic/expkv-def/expkv-def.dtx
+++ /dev/null
@@ -1,2493 +0,0 @@
-% \iffalse meta-comment
-%
-% File: expkv-def.dtx Copyright (C) 2020-2022 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
-%
-% ------------------------------------------------------------------------------
-%
-%<*driver>^^A>>=
-\def\nameofplainTeX{plain}
-\ifx\fmtname\nameofplainTeX\else
- \expandafter\begingroup
-\fi
-\input l3docstrip.tex
-\askforoverwritefalse
-\preamble
-
---------------------------------------------------------------
-expkv-def -- a key-defining frontend for expkv
-E-mail: jspratte@yahoo.de
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
---------------------------------------------------------------
-
-Copyright (C) 2020-2022 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.
-
-This work consists of the file expkv-def.dtx
-and the derived files expkv-def.pdf
- expkv-def.sty
- expkv-def.tex
- t-expkv-def.tex
-
-\endpreamble
-% stop docstrip adding \endinput
-\postamble
-\endpostamble
-\generate{\file{expkv-def.sty}{\from{expkv-def.dtx}{pkg}}}
-\generate{\file{expkv-def.tex}{\from{expkv-def.dtx}{tex}}}
-\generate{\file{t-expkv-def.tex}{\from{expkv-def.dtx}{ctx}}}
-\ifx\fmtname\nameofplainTeX
- \expandafter\endbatchfile
-\else
- \expandafter\endgroup
-\fi
-%
-\IfFileExists{expkv-def.tex}{\input{expkv-def.tex}}{}
-\ProvidesFile{expkv-def.dtx}
- [\csname ekvdDate\endcsname\ a key-defining frontend for expkv]
-\PassOptionsToPackage{full}{textcomp}
-\documentclass{l3doc}
-\RequirePackage[oldstylenums,nott]{kpfonts}
-\input{glyphtounicode}
-\pdfgentounicode=1
-\RequirePackage{tcolorbox}
-\newtcolorbox{exresult}[2][]
- {colback=expkvgrey!10!white,colframe=expkvgrey,fontupper=\small,width={#2},#1}
-\newtcbox\exres[1][]
- {
- colback=expkvgrey!10!white
- ,colframe=expkvgrey
- ,size=small
- ,nobeforeafter
- ,tcbox raise base
- ,fontupper=\small
- ,#1
- }
-\RequirePackage{listings}
-\RequirePackage{booktabs}
-\RequirePackage{array}
-\RequirePackage{collcell}
-\RequirePackage{siunitx}
-\RequirePackage{xcolor}
-\RequirePackage{caption}
-\RequirePackage{microtype}
-\RequirePackage{accsupp}
-\lstdefinelanguage{expkvd}[primitive]{TeX}
- {
- ,moretexcs=[4]^^A e-TeX
- {
- expanded,
- numexpr,
- protected,
- }
- ,moretexcs=[5]^^A plain/LaTeX
- {
- approx,
- begin,
- empty,
- item,
- LaTeX,
- makeatletter,makeatother,
- newcommand,newdimen,
- RequirePackage,
- rule,
- TeX,
- textit,texttt,
- usepackage,
- }
- ,moretexcs=[6]^^A used packages
- {
- ^^A xfp
- fpeval,
- ^^A keyval
- setkeys,
- ^^A yax
- defactiveparameter,storevalue,setparameterlist
- }
- ,moretexcs=[2]^^A expkv-def macros
- {
- ekvdefinekeys
- }
- ,moretexcs=[3]^^A expkv-pkg macros
- {
- ^^A expkv
- ekvdef,ekvdefNoVal,^^A
- ekvlet,ekvletNoVal,ekvletkv,ekvletkvNoVal,^^A
- ekvdefunknown,ekvdefunknownNoVal,^^A
- ekvredirectunknown,ekvredirectunknownNoVal,^^A
- ekvset,ekvsetSneaked,^^A
- ekvsetdef,ekvsetSneakeddef,ekvsetdefSneaked,^^A
- ekvparse,^^A
- ekvVersion,ekvDate,^^A
- ekvifdefined,ekvifdefinedNoVal,ekvifdefinedset,^^A
- ekvbreak,ekvbreakPreSneak,ekvbreakPostSneak,^^A
- ekvsneak,ekvsneakPre,^^A
- ekvchangeset,^^A
- ekvoptarg,ekvoptargTF,^^A
- ekverr,
- ^^A expkv-cs
- ekvcSecondaryKeys,ekvcSplitAndForward,
- }
- }
-\colorlet{codeparam}{cyan!65!black}
-\def\mylstwd{.55em}
-\lstset
- {
- ,language=expkvd
- ,flexiblecolumns=false
- ,basewidth=\mylstwd
- ,gobble=2
- ,basicstyle=\fontfamily{jkp}\itshape
- ,texcsstyle=*[1]{\bfseries\color{expkvgrey}} ^^A primitives
- ,texcsstyle=*[2]{\bfseries\color{expkvred}} ^^A expkv
- ,texcsstyle=*[3]{\color{expkvred}} ^^A expkv-pkg
- ,texcsstyle=*[4]{\bfseries\color{expkvgrey}} ^^A e-TeX
- ,texcsstyle=*[5]{\bfseries\color{expkvgrey}} ^^A plain/LaTeX macros
- ,texcsstyle=*[6]{} ^^A macros of other packages
- ,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}
- ^^A,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}}}
-\RequirePackage{randtext}
-\let\metaORIG\meta
-\protected\def\meta #1{\texttt{\metaORIG{#1}}}
-\renewcommand*\thefootnote{\fnsymbol{footnote}}
-\definecolor{expkvred}{HTML}{9F393D}
-\colorlet{expkvgrey}{black!75}
-\makeatletter
-\newcommand*\expkv
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv}^^A
- \href{https://github.com/Skillmon/tex_expkv}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv}^^A
- }
-\newcommand*\expkvd
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv-def}^^A
- \href{https://github.com/Skillmon/tex_expkv-def}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- {\color{expkvgrey}^^A
- \kern.05em\rule[-.1ex]{.08em}{1.2ex}\kern.05em\textsc{def}^^A
- }^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv-def}^^A
- }
-\newcommand\kv{\meta{key}=\meta{value}}
-\newcommand\key{\meta{key}}
-\newcommand\val{\meta{value}}
-\newcommand\set{\meta{set}}
-\newcommand\enfprefix{\textcolor{black}}
-\newcommand\allprefix{\textcolor{gray}}
-\newcommand\notprefix{\textcolor{red!80!black}}
-\newcommand\printprefix[2]
- {^^A
- \ifcase\numexpr#1\relax\or
- \enfprefix{#2}\or
- \allprefix{#2}\or
- \notprefix{#2}\fi
- }
-\newcommand\prefixes[4]
- {^^A
- \hfill
- \printprefix{#1}{new}
- \printprefix{#2}{also}
- \printprefix{#3}{protected}
- \printprefix{#4}{long}^^A
- }
-\hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
-\DoNotIndex{\def,\edef,\,,\=,\begingroup,\catcode,\chardef,\csname,\endcsname}
-\DoNotIndex{\endgroup,\endinput,\errmessage,\expandafter,\input,\let,\long}
-\DoNotIndex{\protected,\ProvidesFile,\ProvidesPackage,\relax,\space}
-\DoNotIndex{\@,\unexpanded,\string,\expanded,\dimexpr,\global,\glueexpr,\hbox}
-\DoNotIndex{\numexpr,\RequirePackage,\setbox,\the,\unless,\xdef,\@firstofone}
-\DoNotIndex{\@firstoftwo,\@gobble,\@secondoftwo,\meaning,\detokenize}
-\DoNotIndex{\romannumeral,\^}
-\DoNotIndex{\ifcsname}
-\DoNotIndex{\ifx}
-\DoNotIndex{\ifdefined}
-\DoNotIndex{\iffalse}
-\DoNotIndex{\iftrue}
-\DoNotIndex{\else}
-\DoNotIndex{\fi}
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
-\makeatother
-\begin{document}
- \title
- {^^A
- \texorpdfstring
- {^^A
- \huge\expkvd
- \\[\medskipamount]
- \Large a key-defining frontend for \expkv
- }{expkv-def - a key-defining frontend for expkv}^^A
- }
- \date{\ekvdDate\space v\ekvdVersion}
- \author{Jonathan P. Spratte\thanks{\protect\randomize{jspratte@yahoo.de}}}
- \DocInput{expkv-def.dtx}
-\end{document}
-%</driver>^^A=<<
-% \fi
-%
-% \maketitle
-% \renewcommand*\thefootnote{\arabic{footnote}}
-%
-% \begin{abstract}
-% \noindent\parfillskip=0pt
-% \expkvd\ provides a small \kv\ interface to define keys for \expkv. Key-types
-% are declared using prefixes, similar to static typed languages. The stylised
-% name is \expkvd\ but the files use \file{expkv-def}, this is due to CTAN-rules
-% which don't allow \string| in package names since that is the pipe symbol in
-% *nix shells.
-% \end{abstract}
-%
-% \tableofcontents
-%
-% \begin{documentation}^^A>>=
-%
-% \section{Documentation}
-%
-% 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, besides its
-% unique selling points of being fully expandable, and fast and reliable. But at
-% the same time I don't want to widen \expkv's initial scope. So here it 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 space is way easier than parsing for the last one.
-% \expkvd's prefixes are sorted into two categories: |p|-type, which are
-% equivalent to \TeX's prefixes like |\long|, and |t|-type defining the type of
-% the key. For a description of the available |p|-prefixes take a look at
-% \autoref{sec:prefix:p}, the |t|-prefixes are described in
-% \autoref{sec:prefix:t}.
-%
-% \expkvd\ is usable as generic code, as a \LaTeX\ package, and as a \ConTeXt\
-% module. It'll automatically load \expkv\ in the same mode as well. To use it,
-% just use one of
-% \begin{lstlisting}
-% \input expkv-def % plainTeX
-% \usepackage{expkv-def} % LaTeX
-% \usemodule[expkv-def] % ConTeXt
-% \end{lstlisting}
-%
-% \subsection{Macros}
-% Apart from version and date containers there is only a single user-facing
-% macro, and that should be used to define keys.
-%
-% \begin{function}{\ekvdefinekeys}
-% \begin{syntax}
-% \cs{ekvdefinekeys}\marg{set}\{\kv, \ldots\}
-% \end{syntax}
-% In \set, define \key\ to have definition \val. The general syntax for \key\
-% should be
-% \begin{quote}\ttfamily\small
-% \meta{prefix} \meta{name}
-% \end{quote}
-% Where \meta{prefix} is a space separated list of optional |p|-type prefixes
-% followed by one |t|-type prefix. The syntax of \val\ is dependent on the
-% used |t|-prefix.
-% \end{function}
-%
-% \begin{function}{\ekvdDate,\ekvdVersion}
-% These two macros store the version and date of the package.
-% \end{function}
-%
-% \subsection{Prefixes}
-% As already said there are |p|-prefixes and |t|-prefixes. Not every |p|-prefix
-% is allowed for all |t|-prefixes.
-%
-% \subsubsection{\texttt{p}-Prefixes}\label{sec:prefix:p}
-% The two |p|-type prefixes |long| and |protected| are pretty simple by nature,
-% so their description is pretty simple. They affect the \key\ at use-time, so
-% omitting |long| doesn't mean that a \meta{definition} can't contain a |\par|
-% token, only that the \key\ will not accept a |\par| in \val. On the other
-% hand |new| and |also| might be simple on first sight as well, but their rules
-% are a bit more complicated.
-%
-% \begin{function}{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 |long| or
-% |protected|, but you can as well add |long| or |protected| with the |also|
-% definition.
-%
-% As a small example, suppose you want to create a boolean key, but
-% additionally to setting a boolean value you want to execute some more code
-% as well, you can use the following
-% \begin{lstlisting}
-% \ekvdefinekeys{also-example}
-% {
-% bool key = \ifmybool
-% ,also code key = \domystuff{#1}
-% }
-% \end{lstlisting}
-%
-% 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.
-% \end{function}
-%
-% \begin{function}{protected,protect}
-% The following key will be defined |\protected|. Note that key-types which
-% can't be defined expandable will always use |\protected|.
-% \end{function}
-%
-% \begin{function}{long}
-% The following key will be defined |\long|.
-% \end{function}
-%
-% \begin{function}{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 |NoVal| keys and other |NoVal|
-% keys or value taking keys and other value taking keys. For example you can
-% use the following without an error:
-% \begin{lstlisting}
-% \ekvdefinekeys{new-example}
-% {
-% code key = \domystuffwitharg{#1}
-% ,new noval key = \domystuffwithoutarg
-% }
-% \end{lstlisting}
-% \end{function}
-%
-% \subsubsection{\texttt{t}-Prefixes}\label{sec:prefix:t}
-% Since the |p|-type prefixes apply to some of the |t|-prefixes 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}{code,ecode}
-% \begin{syntax}
-% code \key\ = \marg{definition} \prefixes2222
-% \end{syntax}
-% Define \key\ to expand to \meta{definition}. The \key\ will require a \val\
-% for which you can use |#1| inside \meta{definition}. The |ecode| variant
-% will fully expand \meta{definition} inside an |\edef|.
-% \end{function}
-%
-% \begin{function}{noval,enoval}
-% \begin{syntax}
-% noval \key\ = \marg{definition} \prefixes2223
-% \end{syntax}
-% The |noval| type defines \key\ to expand to \meta{definition}. The \key\
-% will not take a \val. |enoval| fully expands \meta{definition} inside an
-% |\edef|.
-% \end{function}
-%
-% \begin{function}{default,qdefault,odefault,fdefault,edefault}
-% \begin{syntax}
-% default \key\ = \marg{definition} \prefixes3223
-% \end{syntax}
-% This serves to place a default \val\ for a \key\ that takes an argument, the
-% \key\ can be of any argument-grabbing kind, and when used without a \val\
-% it will be passed \meta{definition} instead. The |qdefault| variant will
-% expand the \key's code once, so will be slightly quicker, but not change if
-% you redefine \key. |odefault| is just another name for |qdefault|. 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 inside of an |\edef|.
-% \end{function}
-% \footnotetext
-% {^^A
-% For those familiar with \TeX-coding: This uses a
-% \cs[no-index]{romannumeral}-expansion.
-% }
-%
-% \begin{function}{initial,oinitial,finitial,einitial}
-% \begin{syntax}
-% initial \key\ = \{\val\} \prefixes3333
-% initial \key
-% \end{syntax}
-% With |initial| you can set an initial \val\ for an already defined argument
-% taking \key. It'll just call the key-macro of \key\ and pass it \val. The
-% |einitial| variant will expand \val\ using an |\edef| expansion prior to
-% passing it to the key-macro 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 value (and no equals sign) a |noval| \key\ of the
-% same name is called once (or, if you specified a |default| for a value
-% taking key that would be used).
-% \end{function}
-% \footnotetext{Again using \cs[no-index]{romannumeral}.}
-%
-% \begin{function}{bool,gbool,boolTF,gboolTF}
-% \begin{syntax}
-% bool \key\ = \meta{cs} \prefixes2223
-% \end{syntax}
-% The \meta{cs} should be a single control sequence, such as |\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 without a \val\ it'll have the same effect as if you use
-% \texttt{\key=true}. |bool| and |gbool| will behave like \TeX-ifs so either
-% be |\iftrue| or |\iffalse|. The |boolTF| and |gboolTF| variants will both
-% 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 control sequence globally, the others 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| \key\ is the
-% same as a |choice| key which is set up to handle |true| and |false| as
-% choices.
-% \end{function}
-%
-% \begin{function}{invbool,ginvbool,invboolTF,ginvboolTF}
-% \begin{syntax}
-% bool \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
-% \texttt{key=true} is used |invbool| will set \meta{cs} to |\iffalse| and
-% vice versa.
-% \end{function}
-%
-% \begin{function}{boolpair,gboolpair,boolpairTF,gboolpairTF}
-% \begin{syntax}
-% boolpair \key\ = \meta{cs_1}\meta{cs_2} \prefixes2223
-% \end{syntax}
-% The |boolpair| key 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}{store,estore,gstore,xstore}
-% \begin{syntax}
-% store \key\ = \meta{cs} \prefixes2212
-% \end{syntax}
-% The \meta{cs} should be a single control sequence, such as |\foo|.
-% This will define \key\ 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 |store| and |gstore| will allow you to store macro
-% parameters inside of them by using |\unexpanded|.
-% \end{function}
-%
-% \begin{function}{data,edata,gdata,xdata}
-% \begin{syntax}
-% data \key\ = \meta{cs} \prefixes2212
-% \end{syntax}
-% The \meta{cs} should be a single control sequence, such as |\foo|. This will
-% define \key\ 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 \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. The |p|-prefixes will
-% only affect the key-macro, \meta{cs} will always be expandable and |\long|.
-% \end{function}
-%
-% \begin{function}{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 a \val\ was
-% given to \key\ the \meta{cs} will behave like |\@firstofone| appended by
-% \marg{value}.
-% \end{function}
-%
-% \begin{function}{int,eint,gint,xint}
-% \begin{syntax}
-% int \key\ = \meta{cs} \prefixes2212
-% \end{syntax}
-% The \meta{cs} should be a single control sequence, such as |\foo|.
-% An |int| key will be a \TeX-count register. If \meta{cs} isn't defined yet,
-% |\newcount| will be used to initialise it. The |eint| and |xint| versions
-% will use |\numexpr| to allow basic computations in their \val. The |gint|
-% and |xint| variants set the register globally.
-% \end{function}
-%
-% \begin{function}{dimen,edimen,gdimen,xdimen}
-% \begin{syntax}
-% dimen \key\ = \meta{cs} \prefixes2212
-% \end{syntax}
-% The \meta{cs} should be a single control sequence, such as |\foo|.
-% This is just like |int| but uses a dimen register, |\newdimen| and
-% |\dimexpr| instead.
-% \end{function}
-%
-% \begin{function}{skip,eskip,gskip,xskip}
-% \begin{syntax}
-% skip \key\ = \meta{cs} \prefixes2212
-% \end{syntax}
-% The \meta{cs} should be a single control sequence, such as |\foo|.
-% This is just like |int| but uses a skip register, |\newskip| and |\glueexpr|
-% instead.
-% \end{function}
-%
-% \begin{function}{toks,gtoks,apptoks,gapptoks,pretoks,gpretoks}
-% \begin{syntax}
-% toks \key\ = \meta{cs} \prefixes2212
-% \end{syntax}
-% The \meta{cs} should be a single control sequence, such as |\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}{box,gbox}
-% \begin{syntax}
-% box \key\ = \meta{cs} \prefixes2212
-% \end{syntax}
-% The \meta{cs} should be a single control sequence, such as |\foo|.
-% Typesets \val\ into a |\hbox| and stores the result in a box register. The
-% boxes are colour safe. \expkvd\ doesn't provide a |vbox| type.
-% \end{function}
-%
-% \begin{function}{meta}
-% \begin{syntax}
-% meta \key\ = \{\kv, \ldots\} \prefixes2222
-% \end{syntax}
-% This key type can set other keys, you can access the \val\ which was passed
-% to \key\ inside the \kv\ list with |#1|. It works by calling a sub-|\ekvset|
-% on the \kv\ list, so a |set| key will only affect that \kv\ list and not the
-% current |\ekvset|. Since it runs in a separate |\ekvset| you can't use
-% |\ekvsneak| using keys or similar macros in the way you normally could.
-% \end{function}
-%
-% \begin{function}{nmeta}
-% \begin{syntax}
-% nmeta \key\ = \{\kv, \ldots\} \prefixes2223
-% \end{syntax}
-% This key type can set other keys, the difference to |meta| is, that this key
-% doesn't take a value, so the \kv\ list is static.
-% \end{function}
-%
-% \begin{function}{smeta}
-% \begin{syntax}
-% smeta \key\ = \marg{set}\{\kv, \ldots\} \prefixes2222
-% \end{syntax}
-% Yet another |meta| variant. An |smeta| key will take a \val\ which you can
-% access using |#1|, but it sets the \kv\ list inside of \set, so is equal to
-% \texttt{\cs[no-index]{ekvset}\marg{set}\{\kv, \ldots\}}.
-% \end{function}
-%
-% \begin{function}{snmeta}
-% \begin{syntax}
-% snmeta \key\ = \marg{set}\{\kv, \ldots\} \prefixes2223
-% \end{syntax}
-% And the last |meta| variant. |snmeta| is a combination of |smeta| and
-% |nmeta|. It doesn't take an argument and sets the \kv\ list inside of \set.
-% \end{function}
-%
-% \begin{function}{set}
-% \begin{syntax}
-% set \key\ = \marg{set} \prefixes2233
-% \end{syntax}
-% This will define \key\ to change the set of the current |\ekvset|
-% invocation to \set. You can omit \set\ (including the equals sign),
-% which is the same as using \texttt{set \key\ = \{\key\}}. The created |set|
-% key will not take a \val. Note that just like in \expkv\ it'll not be
-% checked whether \set\ is defined and you'll get a low-level \TeX\ error if
-% you use an undefined \set.
-% \end{function}
-%
-% \begin{function}{choice}
-% \begin{syntax}
-% choice \key\ = \{\val=\meta{definition}, \ldots\} \prefixes2223
-% \end{syntax}
-% Defines \key\ to be a |choice| key, meaning it will only accept a limited
-% set of values. You should define each possible \val\ inside of the
-% \val=\meta{definition} list. If a defined \val\ is passed to \key\ the
-% \meta{definition} will be left in the input stream. You can make
-% individual values |protected| inside the \val=\meta{definition} list. By
-% default a |choice| key is expandable, an undefined \val\ will throw an error
-% in an expandable way (but see the |unknown-choice| prefix). You can add
-% additional choices after the \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.
-% \end{function}
-%
-% \begin{function}{choice-store}
-% \begin{syntax}
-% choice-store \key\ = \meta{cs}\{\val, \ldots\} \prefixes2223
-% \end{syntax}
-% This is defines a special type of |choice| key that'll store the given
-% choice inside the macro \meta{cs} (so \meta{cs} should be a single control
-% sequence name such as |\foo|). Since storing inside a macro can't be done
-% expandably every choice-code is |\protected|, you might define the
-% |choice-store| key itself as |protected| as well if you want. Since the
-% definition of each choice is predefined with this key type the choice list
-% should just be a comma separated list of valid choices.
-% \end{function}
-% This means that the following |choice| and |choice-store| keys are equivalent
-% at use time:
-% \begin{lstlisting}
-% \newcommand*\mya{}
-% \ekvdefinekeys{example}
-% {
-% choice key1 = {a=\def\mya{a}, b=\def\mya{b}, c=\def\mya{c}}
-% ,choice-store key2 = \mya{a,b,c}
-% }
-% \end{lstlisting}
-%
-% \begin{function}{choice-enum}
-% \begin{syntax}
-% choice-enum \key\ = \meta{cs}\{\val, \ldots\} \prefixes2223
-% \end{syntax}
-% This is similar to |choice-store|, the differences are: \meta{cs} should be
-% a count-register or is initialised as such if the \meta{cs} is undefined
-% (via |\newcount|); instead of the value the position of the value in the
-% given list is stored in this register (zero-based).
-% \end{function}
-% This means that the following |choice| and |choice-enum| keys are equivalent
-% at use time:
-% \begin{lstlisting}
-% \newcount\myb
-% \ekvdefinekeys{example}
-% {
-% choice key1 = {a={\myb=0 }, b={\myb=1 }, c={\myb=2 }}
-% ,choice-enum key2 = \myb{a,b,c}
-% }
-% \end{lstlisting}
-%
-% \begin{function}{unknown-choice}
-% \begin{syntax}
-% unknown-choice \key\ = \marg{definition} \prefixes2323
-% \end{syntax}
-% By default an unknown \val\ passed to a |choice| or |bool| key 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 choice which was passed in with |#1|.
-% \end{function}
-%
-% \begin{function}{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| prefix you can define handlers that deal with undefined
-% keys, instead of a \key\ name you have to specify a subtype for this prefix,
-% here the subtype is |code|.\par
-% With |unknown code| the \meta{definition} is used for unknown keys which
-% were provided a value (so corresponds to |\ekvdefunknown|), you can access
-% the key name with |#1| and the value with |#2|.\footnotemark
-% \end{function}
-% \footnotetext
-% {^^A
-% 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.^^A
-% }
-%
-% \begin{function}{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 key name with |#1|.
-% \end{function}
-%
-% \begin{function}{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 \key\ in each \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 \key\ isn't found in any \set\ an
-% expandable error will be thrown eventually. Internally \expkv's
-% |\ekvredirectunknown| will be used.
-% \end{function}
-%
-% \begin{function}{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}{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}
-%
-% \subsection{Bugs}
-% I don't think there are any (but every developer says that), if you find some
-% please let me know, either via the email address on the first page or on
-% GitHub:
-% \url{https://github.com/Skillmon/tex_expkv-def}
-%
-% \subsection{Example}
-% The following is an example code defining each base key-type once. Please
-% admire the very creative key-name examples.
-%
-% \begin{lstlisting}
-% \ekvdefinekeys{example}
-% {
-% long code keyA = #1
-% ,noval keyA = NoVal given
-% ,bool keyB = \keyB
-% ,boolTF keyC = \keyC
-% ,store keyD = \keyD
-% ,data keyE = \keyE
-% ,dataT keyF = \keyF
-% ,int keyG = \keyG
-% ,dimen keyH = \keyH
-% ,skip keyI = \keyI
-% ,toks keyJ = \keyJ
-% ,default keyJ = \empty test
-% ,new box keyK = \keyK
-% ,qdefault keyK = K
-% ,choice keyL =
-% {
-% protected 1 = \texttt{a}
-% ,2 = b
-% ,3 = c
-% ,4 = d
-% ,5 = e
-% }
-% ,edefault keyL = 2
-% ,meta keyM = {keyA={#1},keyB=false}
-% ,invbool keyN = \keyN
-% ,boolpair keyO = \keyOa\keyOb
-% }
-% \end{lstlisting}
-%
-% \bigskip
-% Since the |data| type might be a bit strange, here is another usage example
-% for it.
-% \begin{lstlisting}
-% \ekvdefinekeys{ex}
-% {
-% data name = \Pname
-% ,data age = \Page
-% ,dataT hobby = \Phobby
-% }
-% \newcommand\Person[1]
-% {%
-% \begingroup
-% \ekvset{ex}{#1}%
-% \begin{description}
-% \item[\Pname{}{\errmessage{A person requires a name}}]
-% \item[Age] \Page{\textit}{\errmessage{A person requires an age}}
-% \Phobby{\item[Hobbies]}
-% \end{description}
-% \endgroup
-% }
-% \Person{name=Jonathan P. Spratte, age=young, hobby=\TeX\ coding}
-% \Person{name=Some User, age=unknown, hobby=Reading Documentation}
-% \Person{name=Anybody, age=any}
-% \end{lstlisting}
-% In this example a person should have a name and an age, but doesn't have to
-% have hobbies. The name will be displayed as the description item and the age
-% in Italics. If a person has no hobbies the description item will be silently
-% left out. The result of the above code looks like this:
-%
-% \begin{exresult}{\linewidth}
-% \ekvdefinekeys{ex}
-% {
-% data name = \Pname
-% ,data age = \Page
-% ,dataT hobby = \Phobby
-% }
-% \newcommand\Person[1]
-% {%
-% \begingroup
-% \ekvset{ex}{#1}%
-% \begin{description}
-% \item[\Pname{}{\errmessage{A person requires a name}}]
-% \item[Age] \Page{\textit}{\errmessage{A person requires an age}}
-% \Phobby{\item[Hobbies]}
-% \end{description}
-% \endgroup
-% }
-% \Person{name=Jonathan P. Spratte, age=young, hobby=\TeX\ coding}
-% \Person{name=Some User, age=unknown, hobby=Reading Documentation}
-% \Person{name=Anybody, age=any}
-% \end{exresult}
-%
-% \subsection{License}
-%
-% Copyright \textcopyright\ 2020\unless\ifnum\year=2020--\the\year\fi\
-% Jonathan P. Spratte
-%
-% \medskip\noindent
-% 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:
-%
-% \url{http://www.latex-project.org/lppl.txt}
-%
-% \noindent
-% This work is ``maintained'' (as per LPPL maintenance status) by
-%
-% \mbox{Jonathan P. Spratte}.
-%
-% \end{documentation}^^A=<<
-%
-% \begin{implementation}^^A>>=
-%
-% \clearpage
-%
-% \section{Implementation}^^A>>=
-%^^A the LaTeX package >>=
-% \subsection{The \LaTeX\ Package}
-% Just like for \expkv\ we provide a small \LaTeX\ package that sets up things
-% such that we behave nicely on \LaTeX\ packages and files system. It'll
-% |\input| the generic code which implements the functionality.
-% \gobbledocstriptag
-%<*pkg>
-% \begin{macrocode}
-\RequirePackage{expkv}
-\def\ekvd@tmp
- {%
- \ProvidesFile{expkv-def.tex}%
- [\ekvdDate\space v\ekvdVersion\space a key-defining frontend for expkv]%
- }
-\input{expkv-def.tex}
-\ProvidesPackage{expkv-def}%
- [\ekvdDate\space v\ekvdVersion\space a key-defining frontend for expkv]
-% \end{macrocode}
-% \gobbledocstriptag
-%</pkg>
-%^^A=<<
-%^^A the ConTeXt module >>=
-% \subsection{The \ConTeXt\ module}
-% \gobbledocstriptag
-%<*ctx>
-% \begin{macrocode}
-\writestatus{loading}{ConTeXt User Module / expkv-def}
-\usemodule[expkv]
-\unprotect
-\input expkv-def.tex
-\writestatus{loading}
- {ConTeXt User Module / expkv-def / Version \ekvdVersion\space loaded}
-\protect\endinput
-% \end{macrocode}
-% \gobbledocstriptag
-%</ctx>
-%^^A=<<
-%^^A main file >>=
-% \subsection{The Generic Code}
-% The rest of this implementation will be the generic code.
-% \gobbledocstriptag
-%<*tex>
-%
-% Load \expkv\ if the package didn't already do so -- since \expkv\ has
-% safeguards against being loaded twice this does no harm and the overhead
-% isn't that big. Also we reuse some of the internals of \expkv\ to save us from
-% retyping them.
-% \begin{macrocode}
-\input expkv
-% \end{macrocode}
-%
-% We make sure that \file{expkv-def.tex} is only input once:
-% \begin{macrocode}
-\expandafter\ifx\csname ekvdVersion\endcsname\relax
-\else
- \expandafter\endinput
-\fi
-% \end{macrocode}
-%
-% \begin{macro}{\ekvdVersion,\ekvdDate}
-% We're on our first input, so lets store the version and date in a macro.
-% \begin{macrocode}
-\def\ekvdVersion{0.9}
-\def\ekvdDate{2022-01-29}
-% \end{macrocode}
-% \end{macro}
-%
-% If the \LaTeX\ format is loaded we want to be a good file and report back who
-% we are, for this the package will have defined |\ekvd@tmp| to use
-% |\ProvidesFile|, else this will expand to a |\relax| and do no harm.
-% \begin{macrocode}
-\csname ekvd@tmp\endcsname
-% \end{macrocode}
-%
-% Store the category code of |@| to later be able to reset it and change it to
-% 11 for now.
-% \begin{macrocode}
-\expandafter\chardef\csname ekvd@tmp\endcsname=\catcode`\@
-\catcode`\@=11
-% \end{macrocode}
-% |\ekvd@tmp| will be reused later to handle expansion during the key
-% defining. But we don't need it to ever store information long-term after
-% \expkvd\ was initialized.
-%
-% \begin{macro}[internal]{\ekvd@ifprimitive}
-% \begin{macrocode}
-\protected\long\def\ekvd@ifprimitive#1%
- {%
- \begingroup
- \edef\ekvd@tmpa{\string #1}%
- \edef\ekvd@tmpb{\meaning#1}%
- \expandafter
- \endgroup
- \ifx\ekvd@tmpa\ekvd@tmpb
- \ekv@fi@firstoftwo
- \fi
- \@secondoftwo
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekvd@long,\ekvd@prot,\ekvd@clear@prefixes,\ekvd@ifalso}
-% \expkvd\ will use |\ekvd@long|, |\ekvd@prot|, and |\ekvd@ifalso| to store
-% whether a key should be defined as |\long| or |\protected| or adds an action
-% to an existing key, and we have to clear them for every new key. By default
-% |long| and |protected| will just be empty, |ifalso| will be
-% |\@secondoftwo|, and |ifnew| will just use its third argument.
-% \begin{macrocode}
-\protected\def\ekvd@clear@prefixes
- {%
- \let\ekvd@long\ekv@empty
- \let\ekvd@prot\ekv@empty
- \let\ekvd@ifalso\@secondoftwo
- \long\def\ekvd@ifnew##1##2##3{##3}%
- }
-\ekvd@clear@prefixes
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvdefinekeys}
-% This is the one front-facing macro which provides the interface to define
-% keys. It's using |\ekvparse| to handle the \kv\ list, the interpretation will
-% be done by |\ekvd@noarg| and |\ekvd@|. The \set\ for which the keys should be
-% defined is stored in |\ekvd@set|.
-% \begin{macrocode}
-\protected\def\ekvdefinekeys#1%
- {%
- \def\ekvd@set{#1}%
- \ekvparse\ekvd@noarg\ekvd@arg
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@noarg,\ekvd@arg,\ekvd@handle}
-% |\ekvd@noarg| and |\ekvd@arg| store whether there was a value in the \kv\
-% pair. |\ekvd@handle| has to test whether there is a space inside the key and
-% if so calls the prefix grabbing routine, else we throw an error and ignore the
-% key.
-% \begin{macrocode}
-\protected\long\def\ekvd@noarg#1%
- {%
- \let\ekvd@ifnoarg\@firstoftwo
- \expandafter\ekvd@handle\detokenize{#1}\ekvd@stop{}%
- }
-\protected\long\def\ekvd@arg#1%
- {%
- \let\ekvd@ifnoarg\@secondoftwo
- \expandafter\ekvd@handle\detokenize{#1}\ekvd@stop
- }
-\protected\long\def\ekvd@handle#1\ekvd@stop#2%
- {%
- \ekvd@clear@prefixes
- \def\ekvd@cur{#1}%
- \ekvd@ifspace{#1}%
- {\ekvd@prefix\ekv@mark#1\ekv@stop{#2}}%
- \ekvd@err@missing@type
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@prefix,\ekvd@prefix@}
-% \expkvd\ separates prefixes into two groups, the first being prefixes in the
-% \TeX\ sense (|long| and |protected|) which use |@p@| in their name, the other
-% being key-types (|code|, |int|, \emph{etc.}) which use |@t@| instead.
-% |\ekvd@prefix| splits at the first space and checks whether its a |@p@|
-% or |@t@| type prefix. If it is neither throw an error and gobble the
-% definition (the value).
-% \begin{macrocode}
-\protected\def\ekvd@prefix#1 {\ekv@strip{#1}\ekvd@prefix@\ekv@mark}
-\protected\def\ekvd@prefix@#1#2\ekv@stop
- {%
- \ekv@ifdefined{ekvd@t@#1}%
- {\ekv@strip{#2}{\csname ekvd@t@#1\endcsname}}%
- {%
- \ekv@ifdefined{ekvd@p@#1}%
- {\csname ekvd@p@#1\endcsname\ekvd@prefix@after@p{#2}}%
- {\ekvd@err@undefined@prefix{#1}\@gobble}%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@prefix@after@p}
-% The |@p@| type prefixes are all just modifying a following |@t@| type, so they
-% will need to search for another prefix. This is true for all of them, so we
-% use a macro to handle this. It'll throw an error if there is no other prefix.
-% \begin{macrocode}
-\protected\def\ekvd@prefix@after@p#1%
- {%
- \ekvd@ifspace{#1}%
- {\ekvd@prefix#1\ekv@stop}%
- {\ekvd@err@missing@type\@gobble}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekvd@p@long,\ekvd@p@protected,\ekvd@p@protect,\ekvd@p@also,\ekvd@p@new}
-% Define the |@p@| type prefixes, they all just store some information in a
-% temporary macro.
-% \begin{macrocode}
-\protected\def\ekvd@p@long{\let\ekvd@long\long}
-\protected\def\ekvd@p@protected{\let\ekvd@prot\protected}
-\let\ekvd@p@protect\ekvd@p@protected
-\protected\def\ekvd@p@also{\let\ekvd@ifalso\@firstoftwo}
-\protected\def\ekvd@p@new{\let\ekvd@ifnew\ekvd@assert@new}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{Key Types}
-%
-% \begin{macro}[internal]{\ekvd@type@set,\ekvd@t@set}
-% The |set| type is quite straight forward, just define a |NoVal| key to call
-% |\ekvchangeset|.
-% \begin{macrocode}
-\protected\def\ekvd@type@set#1#2%
- {%
- \ekvd@assert@not@long
- \ekvd@assert@not@protected
- \ekvd@ifnew{NoVal}{#1}%
- {%
- \ekv@ifempty{#2}%
- {\ekvd@err@missing@definition}%
- {%
- \ekvd@ifalso
- {%
- \ekv@expargtwice{\ekvd@add@noval{#1}}%
- {\ekvchangeset{#2}}%
- \ekvd@assert@not@protected@also
- }%
- {\ekv@expargtwice{\ekvdefNoVal\ekvd@set{#1}}{\ekvchangeset{#2}}}%
- }%
- }%
- }
-\protected\def\ekvd@t@set#1#2%
- {%
- \ekvd@ifnoarg
- {\ekvd@type@set{#1}{#1}}%
- {\ekvd@type@set{#1}{#2}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@type@noval,\ekvd@t@noval,\ekvd@t@enoval}
-% Another pretty simple type, |noval| just needs to assert that there is a
-% definition and that |long| wasn't specified.
-% There are types where the difference in the variants is so small, that we
-% define a common handler for them, those common handlers are named with
-% |@type@|. |noval| and |enoval| are so similar that we can use such a |@type@|
-% macro, even if we could've done |noval| in a slightly faster way without it.
-% \begin{macrocode}
-\protected\long\def\ekvd@type@noval#1#2#3%
- {%
- \ekvd@ifnew{NoVal}{#2}%
- {%
- \ekvd@assert@arg
- {%
- \ekvd@assert@not@long
- \ekvd@prot#1\ekvd@tmp{#3}%
- \ekvd@ifalso
- {\ekv@exparg{\ekvd@add@noval{#2}}\ekvd@tmp{}}%
- {\ekvletNoVal\ekvd@set{#2}\ekvd@tmp}%
- }%
- }%
- }
-\protected\def\ekvd@t@noval{\ekvd@type@noval\def}
-\protected\def\ekvd@t@enoval{\ekvd@type@noval\edef}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@type@code,\ekvd@t@code,\ekvd@t@ecode}
-% |code| is simple as well, |ecode| has to use |\edef| on a temporary macro,
-% since \expkv\ doesn't provide an |\ekvedef|.
-% \begin{macrocode}
-\protected\long\def\ekvd@type@code#1#2#3%
- {%
- \ekvd@ifnew{}{#2}%
- {%
- \ekvd@assert@arg
- {%
- \ekvd@prot\ekvd@long#1\ekvd@tmp##1{#3}%
- \ekvd@ifalso
- {\ekv@exparg{\ekvd@add@val{#2}}{\ekvd@tmp{##1}}{}}%
- {\ekvlet\ekvd@set{#2}\ekvd@tmp}%
- }%
- }%
- }
-\protected\def\ekvd@t@code{\ekvd@type@code\def}
-\protected\def\ekvd@t@ecode{\ekvd@type@code\edef}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@type@default,\ekvd@t@default,\ekvd@t@qdefault,\ekvd@t@odefault,
-% \ekvd@t@fdefault
-% }
-% |\ekvd@type@default| asserts there was an argument, also the key for which one
-% wants to set a default has to be already defined (this is not so important for
-% |default|, but |qdefault| requires is). If everything is good, |\edef| a
-% temporary macro that expands |\ekvd@set| and the |\csname| for the key, and in
-% the case of |qdefault| does the first expansion step of the key-macro.
-% \begin{macrocode}
-\protected\long\def\ekvd@type@default#1#2#3#4%
- {%
- \ekvd@assert@arg
- {%
- \ekvifdefined\ekvd@set{#3}%
- {%
- \ekvd@assert@not@new
- \ekvd@assert@not@long
- \ekvd@prot\edef\ekvd@tmp
- {%
- \ekv@unexpanded\expandafter#1%
- {#2\csname\ekv@name\ekvd@set{#3}\endcsname{#4}}%
- }%
- \ekvd@ifalso
- {\ekv@exparg{\ekvd@add@noval{#3}}\ekvd@tmp{}}%
- {\ekvletNoVal\ekvd@set{#3}\ekvd@tmp}%
- }%
- {\ekvd@err@undefined@key{#3}}%
- }%
- }
-\protected\def\ekvd@t@default{\ekvd@type@default{}{}}
-\protected\def\ekvd@t@qdefault{\ekvd@type@default{\expandafter\expandafter}{}}
-\let\ekvd@t@odefault\ekvd@t@qdefault
-\protected\def\ekvd@t@fdefault{\ekvd@type@default{}{\romannumeral`\^^@}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@t@edefault}
-% |edefault| is too different from |default| and |qdefault| to reuse the
-% |@type@| macro, as it doesn't need |\unexpanded| inside of |\edef|.
-% \begin{macrocode}
-\protected\long\def\ekvd@t@edefault#1#2%
- {%
- \ekvd@assert@arg
- {%
- \ekvifdefined\ekvd@set{#1}%
- {%
- \ekvd@assert@not@new
- \ekvd@assert@not@long
- \ekvd@prot\edef\ekvd@tmp
- {\csname\ekv@name\ekvd@set{#1}\endcsname{#2}}%
- \ekvd@ifalso
- {\ekv@exparg{\ekvd@add@noval{#1}}\ekvd@tmp{}}%
- {\ekvletNoVal\ekvd@set{#1}\ekvd@tmp}%
- }%
- {\ekvd@err@undefined@key{#1}}%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekvd@t@initial,\ekvd@t@oinitial,\ekvd@t@finitial,\ekvd@t@einitial}
-% \begin{macrocode}
-\long\def\ekvd@type@initial#1#2#3#4%
- {%
- \ekvd@assert@not@new
- \ekvd@assert@not@also
- \ekvd@assert@not@long
- \ekvd@assert@not@protected
- \ekvd@ifnoarg
- {%
- \ekvifdefinedNoVal\ekvd@set{#3}%
- {\csname\ekv@name\ekvd@set{#3}N\endcsname}%
- {\ekvd@err@undefined@noval{#3}}%
- }%
- {%
- \ekvifdefined\ekvd@set{#3}%
- {%
- #1{#2#4}%
- \csname\ekv@name\ekvd@set{#3}\expandafter\endcsname\expandafter
- {\ekvd@tmp}%
- }%
- {\ekvd@err@undefined@key{#3}}%
- }%
- }
-\def\ekvd@t@initial{\ekvd@type@initial{\def\ekvd@tmp}{}}
-\def\ekvd@t@oinitial{\ekvd@type@initial{\ekv@exparg{\def\ekvd@tmp}}{}}
-\def\ekvd@t@einitial{\ekvd@type@initial{\edef\ekvd@tmp}{}}
-\def\ekvd@t@finitial
- {\ekvd@type@initial{\ekv@exparg{\def\ekvd@tmp}}{\romannumeral`\^^@}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@type@bool,\ekvd@t@bool,\ekvd@t@gbool,\ekvd@t@boolTF,\ekvd@t@gboolTF,
-% \ekvd@t@invbool,\ekvd@t@ginvbool,\ekvd@t@invboolTF,\ekvd@t@ginvboolTF,
-% }
-% The boolean types are a quicker version of a |choice| that accept |true| and
-% |false|, and set up the |NoVal| action to be identical to \texttt{\key=true}.
-% The |true| and |false| actions are always just |\let|ting the macro in |#7| to
-% some other macro (\emph{e.g.}, \cs[no-index]{iftrue}).
-% \begin{macrocode}
-\protected\def\ekvd@type@bool#1#2#3#4#5%
- {%
- \ekvd@ifnew{}{#4}%
- {%
- \ekvd@ifnew{NoVal}{#4}%
- {%
- \ekvd@assert@filledarg{#5}%
- {%
- \ekvd@newlet#5#3%
- \ekvd@type@choice{#4}%
- \protected\ekvdefNoVal\ekvd@set{#4}{#1\let#5#2}%
- \protected\expandafter\def
- \csname\ekvd@choice@name\ekvd@set{#4}{true}\endcsname
- {#1\let#5#2}%
- \protected\expandafter\def
- \csname\ekvd@choice@name\ekvd@set{#4}{false}\endcsname
- {#1\let#5#3}%
- }%
- }%
- }%
- }
-\protected\def\ekvd@t@bool{\ekvd@type@bool{}\iftrue\iffalse}
-\protected\def\ekvd@t@gbool{\ekvd@type@bool\global\iftrue\iffalse}
-\protected\def\ekvd@t@boolTF{\ekvd@type@bool{}\@firstoftwo\@secondoftwo}
-\protected\def\ekvd@t@gboolTF{\ekvd@type@bool\global\@firstoftwo\@secondoftwo}
-\protected\def\ekvd@t@invbool{\ekvd@type@bool{}\iffalse\iftrue}
-\protected\def\ekvd@t@ginvbool{\ekvd@type@bool\global\iffalse\iftrue}
-\protected\def\ekvd@t@invboolTF{\ekvd@type@bool{}\@secondoftwo\@firstoftwo}
-\protected\def\ekvd@t@ginvboolTF
- {\ekvd@type@bool\global\@secondoftwo\@firstoftwo}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@type@boolpair,
-% \ekvd@t@boolpair,\ekvd@t@gboolpair,\ekvd@t@boolpairTF,\ekvd@t@gboolpairTF
-% }
-% The boolean pair types are essentially the same as the boolean types, but set
-% two macros instead of one.
-% \begin{macrocode}
-\protected\def\ekvd@type@boolpair#1#2#3#4#5#6%
- {%
- \ekvd@ifnew{}{#4}%
- {%
- \ekvd@ifnew{NoVal}{#4}%
- {%
- \ekvd@newlet#5#3%
- \ekvd@newlet#6#2%
- \ekvd@type@choice{#4}%
- \protected\ekvdefNoVal\ekvd@set{#4}{#1\let#5#2#1\let#6#3}%
- \protected\expandafter\def
- \csname\ekvd@choice@name\ekvd@set{#4}{true}\endcsname
- {#1\let#5#2#1\let#6#3}%
- \protected\expandafter\def
- \csname\ekvd@choice@name\ekvd@set{#4}{false}\endcsname
- {#1\let#5#3#1\let#6#2}%
- }%
- }%
- }
-\protected\def\ekvd@t@boolpair#1#2%
- {\ekvd@assert@twoargs{#2}{\ekvd@type@boolpair{}\iftrue\iffalse{#1}#2}}
-\protected\def\ekvd@t@gboolpair#1#2%
- {\ekvd@assert@twoargs{#2}{\ekvd@type@boolpair\global\iftrue\iffalse{#1}#2}}
-\protected\def\ekvd@t@boolpairTF#1#2%
- {%
- \ekvd@assert@twoargs{#2}%
- {\ekvd@type@boolpair{}\@firstoftwo\@secondoftwo{#1}#2}%
- }
-\protected\def\ekvd@t@gboolpairTF#1#2%
- {%
- \ekvd@assert@twoargs{#2}%
- {\ekvd@type@boolpair\global\@firstoftwo\@secondoftwo{#1}#2}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@type@data,\ekvd@t@data,\ekvd@t@gdata,\ekvd@t@dataT,\ekvd@t@gdataT
-% }
-% \begin{macrocode}
-\protected\def\ekvd@type@data#1#2#3#4#5#6%
- {%
- \ekvd@ifnew{}{#5}%
- {%
- \ekvd@assert@filledarg{#6}%
- {%
- \ekvd@newlet#6#1%
- \ekvd@ifalso
- {%
- \let\ekvd@prot\protected
- \ekvd@add@val{#5}{\long#2#6####1#3{####1{#4}}}{}%
- }%
- {%
- \protected\ekvd@long\ekvdef\ekvd@set{#5}%
- {\long#2#6####1#3{####1{#4}}}%
- }%
- }%
- }%
- }
-\protected\def\ekvd@t@data
- {\ekvd@type@data\@secondoftwo\edef{####2}{\ekv@unexpanded{##1}}}
-\protected\def\ekvd@t@edata{\ekvd@type@data\@secondoftwo\edef{####2}{##1}}
-\protected\def\ekvd@t@gdata
- {\ekvd@type@data\@secondoftwo\xdef{####2}{\ekv@unexpanded{##1}}}
-\protected\def\ekvd@t@xdata{\ekvd@type@data\@secondoftwo\xdef{####2}{##1}}
-\protected\def\ekvd@t@dataT
- {\ekvd@type@data\@gobble\edef{}{\ekv@unexpanded{##1}}}
-\protected\def\ekvd@t@edataT{\ekvd@type@data\@gobble\edef{}{##1}}
-\protected\def\ekvd@t@gdataT
- {\ekvd@type@data\@gobble\xdef{}{\ekv@unexpanded{##1}}}
-\protected\def\ekvd@t@xdataT{\ekvd@type@data\@gobble\xdef{}{##1}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@type@box,\ekvd@t@box,\ekvd@t@gbox}
-% Set up our boxes. Though we're a generic package we want to be colour safe, so
-% we put an additional grouping level inside the box contents, for the case that
-% someone uses \pkg{color}. |\ekvd@newreg| is a small wrapper which tests
-% whether the first argument is defined and if not does
-% |\csname new#2\endcsname#1|.
-% \begin{macrocode}
-\protected\def\ekvd@type@box#1#2#3%
- {%
- \ekvd@ifnew{}{#2}%
- {%
- \ekvd@assert@filledarg{#3}%
- {%
- \ekvd@newreg#3{box}%
- \ekvd@ifalso
- {%
- \let\ekvd@prot\protected
- \ekvd@add@val{#2}{#1\setbox#3=\hbox{\begingroup##1\endgroup}}{}%
- }%
- {%
- \protected\ekvd@long\ekvdef\ekvd@set{#2}%
- {#1\setbox#3=\hbox{\begingroup##1\endgroup}}%
- }%
- }%
- }%
- }
-\protected\def\ekvd@t@box{\ekvd@type@box{}}
-\protected\def\ekvd@t@gbox{\ekvd@type@box\global}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@type@toks,\ekvd@t@toks,\ekvd@t@gtoks}
-% Similar to |box|, but set the |toks|.
-% \begin{macrocode}
-\protected\def\ekvd@type@toks#1#2#3%
- {%
- \ekvd@ifnew{}{#2}%
- {%
- \ekvd@assert@filledarg{#3}%
- {%
- \ekvd@newreg#3{toks}%
- \ekvd@ifalso
- {%
- \let\ekvd@prot\protected
- \ekvd@add@val{#2}{#1#3={##1}}{}%
- }%
- {\protected\ekvd@long\ekvdef\ekvd@set{#2}{#1#3={##1}}}%
- }%
- }%
- }
-\protected\def\ekvd@t@toks{\ekvd@type@toks{}}
-\protected\def\ekvd@t@gtoks{\ekvd@type@toks\global}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@type@preapptoks,\ekvd@t@apptoks,\ekvd@t@gapptoks}
-% Just like |toks|, but expand the current contents of the |toks| register to
-% append the new contents.
-% \begin{macrocode}
-\ekvd@ifprimitive\toksapp
- {%
- \protected\def\ekvd@type@preapptoks#1#2#3%
- {%
- \ekvd@ifnew{}{#2}%
- {%
- \ekvd@assert@filledarg{#3}%
- {%
- \ekvd@newreg#3{toks}%
- \ekvd@ifalso
- {%
- \let\ekvd@prot\protected
- \ekvd@add@val{#2}{#1#3{##1}}{}%
- }%
- {\protected\ekvd@long\ekvdef\ekvd@set{#2}{#1#3{##1}}}%
- }%
- }%
- }
- \protected\def\ekvd@t@apptoks{\ekvd@type@preapptoks\toksapp}
- \protected\def\ekvd@t@gapptoks{\ekvd@type@preapptoks\gtoksapp}
- \protected\def\ekvd@t@pretoks{\ekvd@type@preapptoks\tokspre}
- \protected\def\ekvd@t@gpretoks{\ekvd@type@preapptoks\gtokspre}
- }
- {%
- \protected\def\ekvd@type@apptoks#1#2#3%
- {%
- \ekvd@ifnew{}{#2}%
- {%
- \ekvd@assert@filledarg{#3}%
- {%
- \ekvd@newreg#3{toks}%
- \ekvd@ifalso
- {%
- \let\ekvd@prot\protected
- \ekvd@add@val{#2}{#1#3=\expandafter{\the#3##1}}{}%
- }%
- {%
- \protected\ekvd@long\ekvdef\ekvd@set{#2}%
- {#1#3=\expandafter{\the#3##1}}%
- }%
- }%
- }%
- }
- \protected\def\ekvd@t@apptoks{\ekvd@type@apptoks{}}
- \protected\def\ekvd@t@gapptoks{\ekvd@type@apptoks\global}
- \newtoks\ekvd@toks
- \protected\def\ekvd@type@pretoks#1#2#3%
- {%
- \ekvd@ifnew{}{#2}%
- {%
- \ekvd@assert@filledarg{#3}%
- {%
- \ekvd@newreg#3{toks}%
- \ekvd@ifalso
- {%
- \let\ekvd@prot\protected
- \ekvd@add@val{#2}%
- {%
- \ekvd@toks={##1}%
- #1#3=\expandafter{\the\expandafter\ekvd@toks\the#3}%
- }%
- {}%
- }%
- {%
- \protected\ekvd@long\ekvdef\ekvd@set{#2}%
- {%
- \ekvd@toks={##1}%
- #1#3=\expandafter{\the\expandafter\ekvd@toks\the#3}%
- }%
- }%
- }%
- }%
- }
- \protected\def\ekvd@t@pretoks{\ekvd@type@pretoks{}}
- \protected\def\ekvd@t@gpretoks{\ekvd@type@pretoks\global}
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@type@reg,\ekvd@t@int,\ekvd@t@eint,\ekvd@t@gint,\ekvd@t@xint,
-% \ekvd@t@dimen,\ekvd@t@edimen,\ekvd@t@gdimen,\ekvd@t@xdimen,
-% \ekvd@t@skip,\ekvd@t@eskip,\ekvd@t@gskip,\ekvd@t@xskip
-% }
-% The |\ekvd@type@reg| can handle all the types for which the assignment will
-% just be \texttt{\meta{register}=\meta{value}}.
-% \begin{macrocode}
-\protected\def\ekvd@type@reg#1#2#3#4#5#6%
- {%
- \ekvd@ifnew{}{#5}%
- {%
- \ekvd@assert@filledarg{#6}%
- {%
- \ekvd@newreg#6{#1}%
- \ekvd@ifalso
- {%
- \let\evkd@prot\protected
- \ekvd@add@val{#5}{#2#6=#3##1#4\relax}{}%
- }%
- {\protected\ekvd@long\ekvdef\ekvd@set{#5}{#2#6=#3##1#4\relax}}%
- }%
- }%
- }
-\protected\def\ekvd@t@int{\ekvd@type@reg{count}{}{}{}}
-\protected\def\ekvd@t@eint{\ekvd@type@reg{count}{}\numexpr\relax}
-\protected\def\ekvd@t@gint{\ekvd@type@reg{count}\global{}{}}
-\protected\def\ekvd@t@xint{\ekvd@type@reg{count}\global\numexpr\relax}
-\protected\def\ekvd@t@dimen{\ekvd@type@reg{dimen}{}{}{}}
-\protected\def\ekvd@t@edimen{\ekvd@type@reg{dimen}{}\dimexpr\relax}
-\protected\def\ekvd@t@gdimen{\ekvd@type@reg{dimen}\global{}{}}
-\protected\def\ekvd@t@xdimen{\ekvd@type@reg{dimen}\global\dimexpr\relax}
-\protected\def\ekvd@t@skip{\ekvd@type@reg{skip}{}{}{}}
-\protected\def\ekvd@t@eskip{\ekvd@type@reg{skip}{}\glueexpr\relax}
-\protected\def\ekvd@t@gskip{\ekvd@type@reg{skip}\global{}{}}
-\protected\def\ekvd@t@xskip{\ekvd@type@reg{skip}\global\glueexpr\relax}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@type@store,\ekvd@t@store,\ekvd@t@gstore}
-% The none-expanding |store| types use an |\edef| or |\xdef| and |\unexpanded|
-% to be able to also store |#| easily.
-% \begin{macrocode}
-\protected\def\ekvd@type@store#1#2#3#4%
- {%
- \ekvd@ifnew{}{#3}%
- {%
- \ekvd@assert@filledarg{#4}%
- {%
- \ekvd@newlet#4\ekv@empty
- \ekvd@ifalso
- {%
- \let\ekvd@prot\protected
- \ekvd@add@val{#3}{#1#4{#2}}{}%
- }%
- {\protected\ekvd@long\ekvdef\ekvd@set{#3}{#1#4{#2}}}%
- }%
- }%
- }
-\protected\def\ekvd@t@store{\ekvd@type@store\edef{\ekv@unexpanded{##1}}}
-\protected\def\ekvd@t@gstore{\ekvd@type@store\xdef{\ekv@unexpanded{##1}}}
-\protected\def\ekvd@t@estore{\ekvd@type@store\edef{##1}}
-\protected\def\ekvd@t@xstore{\ekvd@type@store\xdef{##1}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@type@meta,\ekvd@type@meta@a,\ekvd@type@meta@b,\ekvd@type@meta@c,
-% \ekvd@t@meta,\ekvd@t@nmeta
-% }
-% |meta| sets up things such that another instance of |\ekvset| will be run on
-% the argument, with the same \set.
-% \begin{macrocode}
-\protected\long\def\ekvd@type@meta#1#2#3#4#5#6#7%
- {%
- \ekvd@ifnew{#1}{#6}%
- {%
- \ekvd@assert@filledarg{#7}%
- {%
- \edef\ekvd@tmp{\ekvd@set}%
- \expandafter\ekvd@type@meta@a\expandafter{\ekvd@tmp}{#7}{#2}%
- \ekvd@ifalso
- {\ekv@exparg{#3{#6}}{\ekvd@tmp#4}{#5}}%
- {\csname ekvlet#1\endcsname\ekvd@set{#6}\ekvd@tmp}%
- }%
- }%
- }
-\protected\long\def\ekvd@type@meta@a#1#2%
- {%
- \expandafter\ekvd@type@meta@b\expandafter{\ekvset{#1}{#2}}%
- }
-\protected\def\ekvd@type@meta@b
- {%
- \expandafter\ekvd@type@meta@c\expandafter
- }
-\protected\long\def\ekvd@type@meta@c#1#2%
- {%
- \ekvd@prot\ekvd@long\def\ekvd@tmp#2{#1}%
- }
-\protected\def\ekvd@t@meta{\ekvd@type@meta{}{##1}\ekvd@add@val{{##1}}{}}
-\protected\def\ekvd@t@nmeta
- {%
- \ekvd@assert@not@long
- \ekvd@type@meta{NoVal}{}\ekvd@add@noval{}\ekvd@assert@not@long@also
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekvd@type@smeta,\ekvd@type@smeta@,\ekvd@t@smeta,\ekvd@t@snmeta}
-% |smeta| is pretty similar to |meta|, but needs two arguments inside of \val,
-% such that the first is the \set\ for which the sub-|\ekvset| and the second is
-% the \kv\ list.
-% \begin{macrocode}
-\protected\long\def\ekvd@type@smeta#1#2#3#4#5#6#7%
- {%
- \ekvd@ifnew{#1}{#6}%
- {%
- \ekvd@assert@twoargs{#7}%
- {%
- \ekvd@type@meta@a#7{#2}%
- \ekvd@ifalso
- {\ekv@exparg{#3{#6}}{\ekvd@tmp#4}{#5}}%
- {\csname ekvlet#1\endcsname\ekvd@set{#6}\ekvd@tmp}%
- }%
- }%
- }
-\protected\def\ekvd@t@smeta{\ekvd@type@smeta{}{##1}\ekvd@add@val{{##1}}{}}
-\protected\def\ekvd@t@snmeta
- {%
- \ekvd@assert@not@long
- \ekvd@type@smeta{NoVal}{}\ekvd@add@noval{}\ekvd@assert@not@long@also
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@type@choice,
-% \ekvd@populate@choice,\ekvd@populate@choice@,\ekvd@populate@choice@noarg,
-% \ekvd@choice@prefix,\ekvd@choice@prefix@,\ekvd@choice@prefix@done,
-% \ekvd@choice@p@protected,\ekvd@choice@p@protect,
-% \ekvd@choice@p@long,\ekvd@choice@p@long@,
-% \ekvd@t@choice
-% }
-% The |choice| type is by far the most complex type, as we have to run a
-% sub-parser on the choice-definition list, which should support the |@p@| type
-% prefixes as well (but |long| will always throw an error, as they are not
-% allowed to be long). |\ekvd@type@choice| will just define the choice-key, the
-% handling of the choices definition will be done by |\ekvd@populate@choice|.
-% \begin{macrocode}
-\protected\def\ekvd@type@choice#1%
- {%
- \ekvd@assert@not@long
- \ekv@expargtwice{\ekvd@prot\def\ekvd@tmp##1}%
- {%
- \expandafter\expandafter\expandafter
- \ekvd@h@choice
- \expandafter\expandafter\expandafter
- {\expandafter\ekvd@choice@name\expandafter{\ekvd@set}{#1}{##1}}%
- }%
- \ekvd@ifalso
- {%
- \ekvd@assert@val{#1}%
- {%
- \ekvd@if@not@already@choice{#1}%
- {%
- \ekv@exparg
- {%
- \expandafter\ekvd@add@aux
- \csname\ekv@name\ekvd@set{#1}\endcsname{{##1}}{#1}%
- }%
- {\ekvd@tmp{##1}}%
- {\ekvd@long\ekvdef}\ekvd@assert@not@long@also
- }%
- }%
- }%
- {\ekvlet\ekvd@set{#1}\ekvd@tmp}%
- }
-% \end{macrocode}
-% |\ekvd@populate@choice| just uses |\ekvparse| and then gives control to
-% |\ekvd@populate@choice@noarg|, which throws an error, and
-% |\ekvd@populate@choice@|.
-% \begin{macrocode}
-\protected\def\ekvd@populate@choice
- {%
- \ekvparse\ekvd@populate@choice@noarg\ekvd@populate@choice@
- }
-\protected\long\def\ekvd@populate@choice@noarg#1%
- {%
- \expandafter\ekvd@err@missing@definition@msg\expandafter{\ekvd@cur : #1}%
- }
-% \end{macrocode}
-% |\ekvd@populate@choice@| runs the prefix-test, if there is none we can
-% directly define the choice, for that |\ekvd@set@choice| will expand to the
-% current choice-key's name, which will have been defined by |\ekvd@t@choice|.
-% If there is a prefix run the prefix grabbing routine, which was altered for
-% |@type@choice|.
-% \begin{macrocode}
-\protected\long\def\ekvd@populate@choice@#1#2%
- {%
- \ekvd@clear@prefixes
- \ekvd@ifspace{#1}%
- {\ekvd@choice@prefix{\ekv@mark#1}\ekv@mark#1\ekv@stop}%
- {%
- \expandafter\edef
- \csname\ekvd@choice@name\ekvd@set\ekvd@set@choice{#1}\endcsname
- }%
- {\unexpanded{#2}}%
- }
-\protected\def\ekvd@choice@prefix#1#2
- {%
- \ekv@strip{#2}{\ekvd@choice@prefix@{#1}}\ekv@mark
- }
-\protected\def\ekvd@choice@prefix@#1#2#3\ekv@stop
- {%
- \ekv@ifdefined{ekvd@choice@p@#2}%
- {%
- \csname ekvd@choice@p@#2\endcsname
- \ekvd@ifspace{#3}%
- {\ekvd@choice@prefix{#3}#3\ekv@stop}%
- {\ekvd@choice@prefix@done{#3}}%
- }%
- {\ekvd@choice@prefix@done{#1}}%
- }
-\protected\def\ekvd@choice@prefix@done#1%
- {%
- \ekvd@prot\expandafter\edef
- \csname
- \ekv@strip{#1}{\ekvd@choice@name\ekvd@set\ekvd@set@choice}%
- \endcsname
- }
-\protected\def\ekvd@choice@p@protected{\let\ekvd@prot\protected}
-\let\ekvd@choice@p@protect\ekvd@choice@p@protected
-\protected\def\ekvd@choice@invalid@p#1\ekvd@ifspace#2%
- {%
- \expandafter\ekvd@choice@invalid@p@\expandafter{\ekv@gobble@mark#2}{#1}%
- \ekvd@ifspace{#2}%
- }
-\protected\def\ekvd@choice@invalid@p@#1#2%
- {%
- \expandafter\ekvd@err@no@prefix@msg\expandafter{\ekvd@cur : #2 #1}{#2}%
- }
-\protected\def\ekvd@choice@p@long{\ekvd@choice@invalid@p{long}}%
-\protected\def\ekvd@choice@p@also{\ekvd@choice@invalid@p{also}}%
-\protected\def\ekvd@choice@p@new{\ekvd@choice@invalid@p{new}}%
-% \end{macrocode}
-% Finally we're able to set up the |@t@choice| macro, which has to store the
-% current choice-key's name, define the key, and parse the available choices.
-% \begin{macrocode}
-\protected\long\def\ekvd@t@choice#1#2%
- {%
- \ekvd@ifnew{}{#1}%
- {%
- \ekvd@assert@arg
- {%
- \ekvd@type@choice{#1}%
- \def\ekvd@set@choice{#1}%
- \ekvd@populate@choice{#2}%
- }%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@t@choice-store,\ekvd@t@choice-enum}
-% These two types define a special kind of |choice| key and are quite similar,
-% the only difference is what the different choices do (hence they use a
-% shared initialisation which differs in the chosen |populate| step).
-% \begin{macrocode}
-\protected\long\expandafter\def\csname ekvd@t@choice-store\endcsname
- {\ekvd@type@choicespecial\ekvd@populate@choicestore}
-\protected\long\expandafter\def\csname ekvd@t@choice-enum\endcsname
- {\ekvd@type@choicespecial\ekvd@populate@choiceenum}
-% \end{macrocode}
-% \begin{macro}[internal]{\ekvd@type@choicespecial}
-% Initialise similar to a |choice| key. The difference is that we require two
-% arguments (which we assert), a macro to store things in, and a |csv|-list
-% containing the allowed values. |#1| is the |populate| macro according to the
-% type used.
-% \begin{macrocode}
-\protected\long\def\ekvd@type@choicespecial#1#2#3%
- {%
- \ekvd@ifnew{}{#2}%
- {%
- \ekvd@assert@twoargs{#3}%
- {%
- \ekvd@type@choice{#2}%
- \def\ekvd@set@choice{#2}%
- #1#3%
- }%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}[internal]
-% {\ekvd@populate@choicestore,\ekvd@populate@choicestore@}
-% We initialise the storing macro if it doesn't yet exist, and then we loop
-% over the value list. The |\edef|s with |\unexpanded| are both necessary to
-% be able to store macro parameter tokens (the outer protects at define time,
-% the inner at use time).
-% \begin{macrocode}
-\protected\long\def\ekvd@populate@choicestore#1%
- {%
- \ekvd@newlet#1\ekv@empty
- \ekvcsvloop{\ekvd@populate@choicestore@#1}%
- }
-\protected\long\def\ekvd@populate@choicestore@#1#2%
- {%
- \protected\expandafter\edef
- \csname\ekvd@choice@name\ekvd@set\ekvd@set@choice{#2}\endcsname
- {\unexpanded{\edef#1{\unexpanded{#2}}}}%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}[internal]
-% {\ekvd@populate@choiceenum,\ekvd@populate@choiceenum@}
-% This is similar to the population of a |choice-store| type, but instead of
-% storing the values in a macro this initialises a count and stores the
-% position of the value in the list inside that count (zero-indexed). The
-% space is necessary to terminate the number scanning, which is the reason we
-% use |\@firstofone| (so that the space after the macro name isn't gobbled by
-% \TeX).
-% \begin{macrocode}
-\protected\long\def\ekvd@populate@choiceenum#1%
- {%
- \ekvd@newreg#1{count}%
- \def\ekvd@tmp{0}%
- \ekvcsvloop{\ekvd@populate@choiceenum@#1}%
- }
-\protected\long\def\ekvd@populate@choiceenum@#1#2%
- {%
- \protected\expandafter\edef
- \csname\ekvd@choice@name\ekvd@set\ekvd@set@choice{#2}\endcsname
- {#1=\@firstofone{\ekvd@tmp} }%
- \edef\ekvd@tmp{\the\numexpr\ekvd@tmp+1\relax}%
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@t@unknown-choice}
-% \begin{macrocode}
-\protected\long\expandafter\def\csname ekvd@t@unknown-choice\endcsname#1#2%
- {%
- \ekvd@assert@new@for@name{\ekvd@unknown@choice@name\ekvd@set{#1}}%
- {%
- \ekvd@assert@arg
- {%
- \ekvd@assert@not@long
- \ekvd@assert@not@also
- \ekvd@prot\expandafter
- \def\csname\ekvd@unknown@choice@name\ekvd@set{#1}\endcsname##1{#2}%
- }%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekvd@t@unknown,\ekvd@type@unknown@code,\ekvd@type@unknown@noval}
-% The |unknown| type has different subtypes which would be the key names for
-% other types. It is first checked whether that subtype is defined, if it
-% isn't throw an error, else use that subtype.
-% \begin{macrocode}
-\protected\long\def\ekvd@t@unknown#1#2%
- {%
- \ekv@ifdefined{ekvd@type@unknown@\detokenize{#1}}%
- {\csname ekvd@type@unknown@\detokenize{#1}\endcsname{#2}}%
- \ekvd@err@misused@unknown
- }
-% \end{macrocode}
-% The |unknown noval| type can use |\ekvdefunknownNoVal| directly (after
-% asserting some prefixes).
-% \begin{macrocode}
-\protected\long\def\ekvd@type@unknown@noval#1%
- {%
- \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}uN}%
- {%
- \ekvd@assert@arg
- {%
- \ekvd@assert@not@also
- \ekvd@assert@not@long
- \ekvd@prot\ekvdefunknownNoVal\ekvd@set{#1}%
- }%
- }%
- }
-% \end{macrocode}
-% The |unknown code| type uses some trickery during the definition in order to
-% swap out |#1| and |#2| in the user supplied definition. This is done via a
-% temporary macro that stores the definition but gets the parameter numbers
-% reversed while the real definition is done.
-% \begin{macrocode}
-\protected\long\def\ekvd@type@unknown@code#1%
- {%
- \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}u}%
- {%
- \ekvd@assert@arg
- {%
- \ekvd@assert@not@also
- \begingroup
- \def\ekvd@tmp##1##2{#1}%
- \ekv@exparg
- {%
- \endgroup
- \ekvd@prot\ekvd@long\ekvdefunknown\ekvd@set
- }%
- {\ekvd@tmp{##2}{##1}}%
- }%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@type@unknown@redirect,
-% \ekvd@type@unknown@redirect-code,
-% \ekvd@type@unknown@redirect-noval
-% }
-% The |unknown redirect| types also just forward to |\ekvredirectunknown|
-% after asserting some prefixes.
-% \begin{macrocode}
-\protected\edef\ekvd@type@unknown@redirect#1%
- {%
- \expandafter\noexpand\csname ekvd@type@unknown@redirect-code\endcsname{#1}%
- \expandafter\noexpand\csname ekvd@type@unknown@redirect-noval\endcsname{#1}%
- }
-\protected\expandafter\def\csname ekvd@type@unknown@redirect-code\endcsname#1%
- {%
- \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}u}%
- {%
- \ekvd@assert@arg
- {%
- \ekvd@assert@not@also
- \ekvd@assert@not@protected
- \expandafter\ekvredirectunknown\expandafter{\ekvd@set}{#1}%
- }%
- }%
- }
-\protected\expandafter\def\csname ekvd@type@unknown@redirect-noval\endcsname#1%
- {%
- \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}uN}%
- {%
- \ekvd@assert@arg
- {%
- \ekvd@assert@not@also
- \ekvd@assert@not@protected
- \ekvd@assert@not@long
- \expandafter\ekvredirectunknownNoVal\expandafter{\ekvd@set}{#1}%
- }%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{Key Type Helpers}
-% There are some keys that might need helpers during their execution (not during
-% their definition, which are gathered as |@type@| macros). These helpers are
-% named |@h@|.
-%
-% \begin{macro}[internal]{\ekvd@h@choice,\ekvd@h@choice@}
-% The |choice| helper will just test whether the given choice was defined, if
-% not throw an error expandably, else call the macro which stores the code for
-% this choice.
-% \begin{macrocode}
-\def\ekvd@h@choice#1%
- {%
- \expandafter\ekvd@h@choice@
- \csname\ifcsname#1\endcsname#1\else relax\fi\endcsname
- {#1}%
- }
-\def\ekvd@h@choice@#1#2%
- {%
- \ifx#1\relax
- \ekvd@err@choice@invalid{#2}%
- \expandafter\@gobble
- \fi
- #1%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsubsection{Handling \texttt{also}}
-%
-% \begin{macro}[internal]
-% {\ekvd@add@val,\ekvd@add@noval,\ekvd@add@aux,\ekvd@add@aux@}
-% \begin{macrocode}
-\protected\long\def\ekvd@add@val#1#2#3%
- {%
- \ekvd@assert@val{#1}%
- {%
- \expandafter\ekvd@add@aux\csname\ekv@name\ekvd@set{#1}\endcsname{{##1}}%
- {#1}{#2}{\ekvd@long\ekvdef}{#3}%
- }%
- }
-\protected\long\def\ekvd@add@noval#1#2#3%
- {%
- \ekvd@assert@noval{#1}%
- {%
- \expandafter\ekvd@add@aux\csname\ekv@name\ekvd@set{#1}N\endcsname{}%
- {#1}{#2}\ekvdefNoVal{#3}%
- }%
- }
-\protected\long\def\ekvd@add@aux#1#2%
- {%
- \ekvd@extract@prefixes#1%
- \expandafter\ekvd@add@aux@\expandafter{#1#2}%
- }
-\protected\long\def\ekvd@add@aux@#1#2#3#4#5%
- {%
- #5%
- \ekvd@prot#4\ekvd@set{#2}{#1#3}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@extract@prefixes,\ekvd@extract@prefixes@,
-% \ekvd@extract@prefixes@long,\ekvd@extract@prefixes@prot
-% }
-% This macro checks which prefixes were used for the definition of a macro and
-% sets |\ekvd@long| and |\ekvd@prot| accordingly.
-% \begin{macrocode}
-\protected\def\ekvd@extract@prefixes#1%
- {%
- \expandafter\ekvd@extract@prefixes@\meaning#1\ekvd@stop
- }
-% \end{macrocode}
-% In the following definition |#1| will get replaced by |macro:|, |#2| by
-% |\long| and |#3| by |\protected| (in each, all tokens will have category
-% other). This allows us to parse the |\meaning| of a macro for those strings.
-% \begin{macrocode}
-\protected\def\ekvd@extract@prefixes@#1#2#3%
- {%
- \protected\def\ekvd@extract@prefixes@##1#1##2\ekvd@stop
- {%
- \ekvd@extract@prefixes@long
- ##1\ekvd@mark\@firstofone#2\ekvd@mark\@gobble\ekvd@stop
- {\let\ekvd@long\long}%
- \ekvd@extract@prefixes@prot
- ##1\ekvd@mark\@firstofone#3\ekvd@mark\@gobble\ekvd@stop
- {\let\ekvd@prot\protected}%
- }%
- \protected\def\ekvd@extract@prefixes@long##1#2##2\ekvd@mark##3##4\ekvd@stop
- {##3}%
- \protected\def\ekvd@extract@prefixes@prot##1#3##2\ekvd@mark##3##4\ekvd@stop
- {##3}%
- }
-% \end{macrocode}
-% We use a temporary macro to expand the three arguments of
-% |\ekvd@extract@prefixes@|, which will set up the real meaning of itself and
-% the parsing for |\long| and |\protected|.
-% \begin{macrocode}
-\begingroup
-\edef\ekvd@tmp
- {%
- \endgroup
- \ekvd@extract@prefixes@
- {\detokenize{macro:}}%
- {\string\long}%
- {\string\protected}%
- }
-\ekvd@tmp
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsubsection{Tests}
-%
-% \begin{macro}[internal]{\ekvd@newlet,\ekvd@newreg}
-% These macros test whether a control sequence is defined, if it isn't they
-% define it, either via |\let| or via the correct \cs[no-index]{new\meta{reg}}.
-% \begin{macrocode}
-\protected\def\ekvd@newlet#1#2%
- {%
- \ifdefined#1\ekv@fi@gobble\fi\@firstofone{\let#1#2}%
- }
-\protected\def\ekvd@newreg#1#2%
- {%
- \ifdefined#1\ekv@fi@gobble\fi\@firstofone{\csname new#2\endcsname#1}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekvd@assert@twoargs,\ekvd@ifnottwoargs,\ekvd@ifempty@gtwo}
-% A test for exactly two tokens can be reduced for an empty-test after gobbling
-% two tokens, in the case that there are fewer tokens than two in the argument,
-% only macros will be gobbled that are needed for the true branch, which doesn't
-% hurt, and if there are more this will not be empty.
-% \begin{macrocode}
-\long\def\ekvd@assert@twoargs#1%
- {%
- \ekvd@ifnottwoargs{#1}{\ekvd@err@missing@definition}%
- }
-\long\def\ekvd@ifnottwoargs#1%
- {%
- \ekvd@ifempty@gtwo#1\ekv@ifempty@B
- \ekv@ifempty@false\ekv@ifempty@A\ekv@ifempty@B\@firstoftwo
- }
-\long\def\ekvd@ifempty@gtwo#1#2{\ekv@ifempty@\ekv@ifempty@A}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@assert@val,\ekvd@assert@val@,\ekvd@assert@noval,\ekvd@assert@noval@,
-% \ekvd@extract@args,\ekvd@extracted@args,\ekvd@one@arg@string
-% }
-% Assert that a given key is defined as a value taking key or a |NoVal| key with
-% the correct argument structure, respectively.
-% \begin{macrocode}
-\protected\def\ekvd@assert@val#1%
- {%
- \ekvifdefined\ekvd@set{#1}%
- {\expandafter\ekvd@assert@val@\csname\ekv@name\ekvd@set{#1}\endcsname}%
- {%
- \ekvifdefinedNoVal\ekvd@set{#1}%
- \ekvd@err@add@val@on@noval
- {\ekvd@err@undefined@key{#1}}%
- \@gobble
- }%
- }
-\protected\def\ekvd@assert@val@#1%
- {%
- \expandafter\ekvd@extract@args\meaning#1\ekvd@stop
- \unless\ifx\ekvd@extracted@args\ekvd@one@arg@string
- \ekvd@err@unsupported@arg
- \fi
- \@firstofone
- }%
-\protected\def\ekvd@assert@noval#1%
- {%
- \ekvifdefinedNoVal\ekvd@set{#1}%
- {\expandafter\ekvd@assert@noval@\csname\ekv@name\ekvd@set{#1}N\endcsname}%
- {%
- \ekvifdefined\ekvd@set{#1}%
- \ekvd@err@add@noval@on@val
- {\ekvd@err@undefined@key{#1}}%
- \@gobble
- }%
- }
-\protected\def\ekvd@assert@noval@#1%
- {%
- \expandafter\ekvd@extract@args\meaning#1\ekvd@stop
- \unless\ifx\ekvd@extracted@args\ekv@empty
- \ekvd@err@unsupported@arg
- \fi
- \@firstofone
- }
-\protected\def\ekvd@extract@args#1%
- {%
- \protected\def\ekvd@extract@args##1#1##2->##3\ekvd@stop
- {\def\ekvd@extracted@args{##2}}%
- }
-\expandafter\ekvd@extract@args\expandafter{\detokenize{macro:}}
-\edef\ekvd@one@arg@string{\string#1}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@assert@arg,\ekvd@assert@arg@msg,\ekvd@ifnoarg}
-% There is no need to actually define |\ekvd@ifnoarg| here, as it will be set by
-% either |\ekvd@arg| or |\ekvd@noarg|.
-% \begin{macrocode}
-\def\ekvd@assert@arg{\ekvd@ifnoarg\ekvd@err@missing@definition}
-\long\def\ekvd@assert@arg@msg#1%
- {%
- \ekvd@ifnoarg{\ekvd@err@missing@definition@msg{#1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@assert@filledarg,\ekvd@ifnoarg@or@empty}
-% \begin{macrocode}
-\long\def\ekvd@assert@filledarg#1%
- {%
- \ekvd@ifnoarg@or@empty{#1}\ekvd@err@missing@definition
- }
-\long\def\ekvd@ifnoarg@or@empty#1%
- {%
- \ekvd@ifnoarg
- \@firstoftwo
- {\ekv@ifempty{#1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@assert@not@long,\ekvd@assert@not@protected,\ekvd@assert@not@also
-% \ekvd@assert@not@long@also,\ekvd@assert@not@protected@also,
-% \ekvd@assert@new,\ekvd@assert@not@new
-% }
-% Some key-types don't want to be |also|, |\long| or |\protected|, so we provide
-% macros to test this and throw an error, this could be silently ignored but now
-% users will learn to not use unnecessary stuff which slows the compilation
-% down.
-% \begin{macrocode}
-\def\ekvd@assert@not@long{\ifx\ekvd@long\long\ekvd@err@no@prefix{long}\fi}
-\def\ekvd@assert@not@protected
- {\ifx\ekvd@prot\protected\ekvd@err@no@prefix{protected}\fi}
-\def\ekvd@assert@not@also{\ekvd@ifalso{\ekvd@err@no@prefix{also}}{}}
-\def\ekvd@assert@not@long@also
- {\ifx\ekvd@long\long\ekvd@err@no@prefix@also{long}\fi}
-\def\ekvd@assert@not@protected@also
- {\ifx\ekvd@prot\protected\ekvd@err@no@prefix@also{protected}\fi}
-\def\ekvd@assert@new#1#2%
- {\csname ekvifdefined#1\endcsname\ekvd@set{#2}{\ekvd@err@not@new}}
-\def\ekvd@assert@not@new
- {\ifx\ekvd@ifnew\ekvd@assert@new\ekvd@err@no@prefix{new}\fi}
-\def\ekvd@assert@new@for@name#1%
- {%
- \ifx\ekvd@ifnew\ekvd@assert@new
- \ekv@fi@firstoftwo
- \fi
- \@secondoftwo
- {\ekv@ifdefined{#1}\ekvd@err@not@new}%
- \@firstofone
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@if@not@already@choice, \ekvd@if@not@already@choice@a,
-% \ekvd@if@not@already@choice@b
-% }
-% It is bad to use |also| on a key that already contains a |choice|, as both
-% choices would share the same valid values and thus lead to each callback being
-% used twice. The following is a rudimentary test against this.
-% \begin{macrocode}
-\protected\def\ekvd@if@not@already@choice#1%
- {%
- \expandafter\ekvd@if@not@already@choice@a
- \csname\ekv@name\ekvd@set{#1}\endcsname
- {}\ekvd@h@choice\ekvd@stop
- }
-\protected\def\ekvd@if@not@already@choice@a
- {%
- \expandafter\ekvd@if@not@already@choice@b
- }
-\long\protected\def\ekvd@if@not@already@choice@b#1\ekvd@h@choice#2\ekvd@stop
- {%
- \ekv@ifempty{#2}\@firstofone\@gobble
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@ifspace,\ekvd@ifspace@}
-% Yet another test which can be reduced to an if-empty, this time by gobbling
-% everything up to the first space.
-% \begin{macrocode}
-\long\def\ekvd@ifspace#1%
- {%
- \ekvd@ifspace@#1 \ekv@ifempty@B
- \ekv@ifempty@false\ekv@ifempty@A\ekv@ifempty@B\@firstoftwo
- }
-\long\def\ekvd@ifspace@#1 % keep this space
- {%
- \ekv@ifempty@\ekv@ifempty@A
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{Messages}
-%
-% Most messages of \expkvd\ are not expandable, since they only appear during
-% key-definition, which is not expandable anyway.
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@errm,\ekvd@err@missing@definition,\ekvd@err@missing@definition@msg,
-% \ekvd@err@missing@type,\ekvd@err@undefined@prefix,\ekvd@err@undefined@key,
-% \ekvd@err@no@prefix,\ekvd@err@no@prefix@msg,\ekvd@err@no@prefix@also,
-% \ekvd@err@add@val@on@noval,\ekvd@err@add@noval@on@val,
-% \ekvd@err@unsupported@arg,\ekvd@err@not@new
-% }
-% The non-expandable error messages are boring, so here they are:
-% \begin{macrocode}
-\protected\def\ekvd@errm#1{\errmessage{expkv-def Error: #1}}
-\protected\def\ekvd@err@missing@definition
- {\ekvd@errm{Missing definition for key `\ekvd@cur'}}
-\protected\def\ekvd@err@missing@definition@msg#1%
- {\ekvd@errm{Missing definition for key `\ekv@unexpanded{#1}'}}
-\protected\def\ekvd@err@missing@type
- {\ekvd@errm{Missing type prefix for key `\ekvd@cur'}}
-\protected\def\ekvd@err@undefined@prefix#1%
- {%
- \ekvd@errm
- {%
- Undefined prefix `\ekv@unexpanded{#1}' found while processing
- `\ekvd@cur'%
- }%
- }
-\protected\def\ekvd@err@undefined@key#1%
- {%
- \ekvd@errm
- {Undefined key `\ekv@unexpanded{#1}' found while processing `\ekvd@cur'}%
- }
-\protected\def\ekvd@err@undefined@noval#1%
- {%
- \ekvd@errm
- {%
- Undefined noval key `\unexpanded{#1}' found while processing
- `\ekvd@cur'%
- }%
- }
-\protected\def\ekvd@err@no@prefix#1%
- {\ekvd@errm{prefix `#1' not accepted in `\ekvd@cur'}}
-\protected\def\ekvd@err@no@prefix@msg#1#2%
- {\ekvd@errm{prefix `#2' not accepted in `\ekv@unexpanded{#1}'}}
-\protected\def\ekvd@err@no@prefix@also#1%
- {\ekvd@errm{`\ekvd@cur' not allowed with a `#1' key}}
-\protected\def\ekvd@err@add@val@on@noval
- {\ekvd@errm{`\ekvd@cur' not allowed with a NoVal key}}
-\protected\def\ekvd@err@add@noval@on@val
- {\ekvd@errm{`\ekvd@cur' not allowed with a value taking key}}
-\protected\def\ekvd@err@unsupported@arg\fi\@firstofone#1%
- {%
- \fi
- \ekvd@errm
- {%
- Existing key-macro has the unsupported argument string
- `\ekvd@extracted@args' for key `\ekvd@cur'%
- }%
- }
-\protected\def\ekvd@err@not@new
- {\ekvd@errm{The key for `\ekvd@cur' is already defined}}
-\protected\long\def\ekvd@err@misused@unknown
- {\ekvd@errm{Misuse of the unknown type found while processing `\ekvd@cur'}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvd@err@choice@invalid,\ekvd@err@choice@invalid@,\ekvd@choice@name,
-% \ekvd@unknown@choice@name
-% }
-% |\ekvd@err@choice@invalid| will have to use this mechanism to throw its
-% message. Also we have to retrieve the name parts of the choice in an easy way,
-% so we use parentheses of catcode 8 here, which should suffice in most cases to
-% allow for a correct separation.
-% \begin{macrocode}
-\def\ekvd@err@choice@invalid#1%
- {%
- \ekvd@err@choice@invalid@#1%
- }
-\begingroup
-\catcode40=8
-\catcode41=8
-\@firstofone{\endgroup
-\def\ekvd@choice@name#1#2#3%
- {%
- ekvd#1(#2)\detokenize{#3}%
- }
-\def\ekvd@unknown@choice@name#1#2%
- {%
- ekvd:u:#1(#2)%
- }
-\def\ekvd@err@choice@invalid@ ekvd#1(#2)\detokenize#3%
- {%
- \ekv@ifdefined{\ekvd@unknown@choice@name{#1}{#2}}%
- {\csname\ekvd@unknown@choice@name{#1}{#2}\endcsname{#3}}%
- {\ekvd@err{invalid choice `#3' for `#2' in set `#1'}}%
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@err}
-% The expandable error messages use |\ekvd@err|, which is just like |\ekv@err|
-% from \expkv. It uses a runaway argument to start the error message.
-% \begin{macrocode}
-\ekv@exparg{\long\def\ekvd@err#1}{\ekverr{expkv-def}{#1}}
-% \end{macrocode}
-% \end{macro}
-%
-% Now everything that's left is to reset the category code of |@|.
-% \begin{macrocode}
-\catcode`\@=\ekvd@tmp
-% \end{macrocode}
-%
-% \gobbledocstriptag
-%</tex>
-%^^A=<<
-%
-%^^A=<<
-%
-% \end{implementation}^^A=<<
-%
-% \clearpage
-% \PrintIndex
-%
-\endinput
-%
-^^A vim: ft=tex fdm=marker fmr=>>=,=<<
diff --git a/obsolete/macros/generic/expkv-def/expkv-def.pdf b/obsolete/macros/generic/expkv-def/expkv-def.pdf
deleted file mode 100644
index ea5678d280..0000000000
--- a/obsolete/macros/generic/expkv-def/expkv-def.pdf
+++ /dev/null
Binary files differ
diff --git a/obsolete/macros/generic/expkv-opt/README.md b/obsolete/macros/generic/expkv-opt/README.md
deleted file mode 100644
index 447c4a87da..0000000000
--- a/obsolete/macros/generic/expkv-opt/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
--------------------------------------------------------------------------------
-# expkv-opt -- parse class and package options with expkv
-
-Version 2021-04-04 v0.2
-
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
-
-Hosted at https://github.com/Skillmon/tex_expkv-opt
-
--------------------------------------------------------------------------------
-
-Copyright (C) 2020 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.
-
--------------------------------------------------------------------------------
-
-This package allows to parse key=val options for LaTeX classes and packages
-using [`expkv`](https://github.com/Skillmon/tex_expkv). It handles global and
-local options completely separately. The only required package is `expkv`.
diff --git a/obsolete/macros/generic/expkv-opt/expkv-opt-2020-10-10.dtx b/obsolete/macros/generic/expkv-opt/expkv-opt-2020-10-10.dtx
deleted file mode 100644
index ab2dcec41a..0000000000
--- a/obsolete/macros/generic/expkv-opt/expkv-opt-2020-10-10.dtx
+++ /dev/null
@@ -1,938 +0,0 @@
-% \iffalse meta-comment
-%
-% File: expkv-opt.dtx Copyright (C) 2020 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
-%
-% ------------------------------------------------------------------------------
-%
-%<*driver>^^A>>=
-\def\nameofplainTeX{plain}
-\ifx\fmtname\nameofplainTeX\else
- \expandafter\begingroup
-\fi
-\input l3docstrip.tex
-\askforoverwritefalse
-\preamble
-
---------------------------------------------------------------
-expkv-opt -- parse class and package options with expkv
-E-mail: jspratte@yahoo.de
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
---------------------------------------------------------------
-
-Copyright (C) 2020 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.
-
-This work consists of the file expkv-opt.dtx
-and the derived files expkv-opt.pdf
- expkv-opt.sty
-
-\endpreamble
-% stop docstrip adding \endinput
-\postamble
-\endpostamble
-\generate{\file{expkv-opt-2020-10-10.sty}{\from{expkv-opt-2020-10-10.dtx}{pkg}}}
-\ifx\fmtname\nameofplainTeX
- \expandafter\endbatchfile
-\else
- \expandafter\endgroup
-\fi
-%
-\IfFileExists{expkv-opt.sty}{\RequirePackage{expkv-opt}}{}
-\ProvidesFile{expkv-opt.dtx}
- [\csname ekvoDate\endcsname\ parse class and package options with expkv]
-\PassOptionsToPackage{full}{textcomp}
-\documentclass{l3doc}
-\RequirePackage[oldstylenums,nott]{kpfonts}
-\input{glyphtounicode}
-\pdfgentounicode=1
-\RequirePackage{listings}
-\RequirePackage{booktabs}
-\RequirePackage{array}
-\RequirePackage{collcell}
-\RequirePackage{siunitx}
-\RequirePackage{xcolor}
-\RequirePackage{caption}
-\RequirePackage{microtype}
-\RequirePackage{accsupp}
-\lstset
- {
- ,flexiblecolumns=false
- ,basewidth=.53em
- ,gobble=2
- ,basicstyle=\fontfamily{jkp}\itshape
- ,morekeywords=^^A
- {^^A
- \ekvoProcessLocalOptions,
- \ekvoProcessGlobalOptions,
- \ekvoProcessUnusedGlobalOptions,
- \ekvoProcessOptionsList,
- \ekvoUseUnknownHandlers
- }
- ,morecomment=[l]\%
- ,commentstyle=\color[gray]{0.4}
- ,literate={\{}{{\CodeSymbol\{}}{1}
- {\}}{{\CodeSymbol\}}}{1}
- ^^A,literate=*{<key>}{\key}{4}{<set>}{\set}{4}
- }
-\newcommand*\CodeSymbol[1]{\textbf{#1}}
-\RequirePackage{randtext}
-\let\metaORIG\meta
-\protected\def\meta #1{\texttt{\metaORIG{#1}}}
-\renewcommand*\thefootnote{\fnsymbol{footnote}}
-\definecolor{expkvred}{HTML}{9F393D}
-\colorlet{expkvgrey}{black!75}
-\makeatletter
-\newcommand*\expkv
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv}^^A
- \href{https://github.com/Skillmon/tex_expkv}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv}^^A
- }
-\newcommand*\expkvpkg[1]
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv-#1}^^A
- \href{https://github.com/Skillmon/tex_expkv-#1}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- {\color{expkvgrey}^^A
- \kern.05em\rule[-.1ex]{.08em}{1.2ex}\kern.05em\textsc{#1}^^A
- }^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv-#1}^^A
- }
-\newcommand*\expkvd{\expkvpkg{def}}
-\newcommand*\expkvc{\expkvpkg{cs}}
-\newcommand*\expkvo{\expkvpkg{opt}}
-\newcommand\kv{\meta{key}=\meta{value}}
-\newcommand\key{\meta{key}}
-\newcommand\val{\meta{value}}
-\newcommand\set{\meta{set}}
-\newcommand\enfprot{\textcolor{black}{protected}}
-\newcommand\allprot{\textcolor{gray}{protected}}
-\newcommand\notprot{\textcolor{red!80!black}{protected}}
-\newcommand\enflong{\textcolor{black}{long}}
-\newcommand\alllong{\textcolor{gray}{long}}
-\newcommand\notlong{\textcolor{red!80!black}{long}}
-\newcommand\prefixes[2]
- {^^A
- \hfill
- \ifcase\numexpr#1\relax\or
- \enfprot\or
- \allprot\or
- \notprot\fi\space
- \ifcase\numexpr#2\relax\or
- \enflong\or
- \alllong\or
- \notlong\fi
- }
-\hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
-\DoNotIndex{\def,\edef,\,,\=,\begingroup,\catcode,\chardef,\csname,\endcsname}
-\DoNotIndex{\endgroup,\endinput,\errmessage,\expandafter,\input,\let,\long}
-\DoNotIndex{\protected,\ProvidesFile,\ProvidesPackage,\relax,\space}
-\DoNotIndex{\@,\unexpanded,\string,\expanded,\dimexpr,\global,\glueexpr,\hbox}
-\DoNotIndex{\numexpr,\RequirePackage,\setbox,\the,\unless,\xdef,\@firstofone}
-\DoNotIndex{\@firstoftwo,\@gobble,\@secondoftwo,\AtEndOfPackage,\newcommand}
-\DoNotIndex{\PackageError,\@classoptionslist,\@clsextension,\@currext}
-\DoNotIndex{\@currname,\@empty,\@gobbletwo,\@onlypreamble,\@unprocessedoptions}
-\DoNotIndex{\@unusedoptionlist}
-\DoNotIndex{\ifcsname}
-\DoNotIndex{\ifx}
-\DoNotIndex{\ifdefined}
-\DoNotIndex{\iffalse}
-\DoNotIndex{\iftrue}
-\DoNotIndex{\else}
-\DoNotIndex{\fi}
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
-\makeatother
-\begin{document}
- \title
- {^^A
- \texorpdfstring
- {^^A
- \huge\expkvo
- \\[\medskipamount]
- \Large parse class and package options with \expkv
- }{expkv-opt - parse class and package options with expkv}^^A
- }
- \date{\ekvoDate\space v\ekvoVersion}
- \author{Jonathan P. Spratte\thanks{\protect\randomize{jspratte@yahoo.de}}}
- \DocInput{expkv-opt.dtx}
-\end{document}
-%</driver>^^A=<<
-% \fi
-%
-% \maketitle
-% \renewcommand*\thefootnote{\arabic{footnote}}
-%
-% \begin{abstract}
-% \noindent\parfillskip=0pt
-% \expkvo\ provides option parsing for classes and packages in \LaTeXe\ based on
-% \expkv. Global and local options are parsed individually by different
-% commands. The stylised name is \expkvo\ but the files use \file{expkv-opt},
-% this is due to CTAN-rules which don't allow \string| in package names since
-% that is the pipe symbol in *nix shells.
-% \end{abstract}
-%
-% \tableofcontents
-%
-% \begin{documentation}^^A>>=
-%
-% \section{Documentation}
-%
-% The \expkv\ family provides at its core a \kv\ parser and additionally
-% packages, one to conveniently define new keys (\expkvd) and another to build
-% expandable \kv\ taking control sequences (\expkvc). Still missing from the mix
-% was a solution to parse \LaTeXe\ class and package options, a gap that's
-% hereby filled with \expkvo.
-%
-% \expkvo\ shouldn't place any restrictions on the keys, but note that parts of
-% \LaTeXe\ can break if the \kv\ list contains braces. This includes the global
-% options list depending on which class you're using. Also keep in mind that
-% every value provided should be save from an |\edef| expansion, as the space
-% stripping code of \LaTeXe\ options (which is applied before \expkvo\ takes
-% control) uses such an expansion.
-%
-% The package can be loaded with
-% \begin{lstlisting}
-% \usepackage{expkv-opt}
-% \end{lstlisting}
-% Unlike the other packages in the \expkv\ family, \expkvo\ is only provided as
-% a \LaTeX\ package.
-%
-% Before reading this documentation you should read \expkv's documentation and
-% might want to also read the documentation of \expkvd.
-%
-%
-% \subsection{Macros}
-%
-% \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 separated
-% in \key\ and \val\ but as a whole) is stored within the macro
-% \cs{CurrentOption}.
-%
-% \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}
-% \begin{description}
-% \item[Class:]
-% \begin{description}
-% \item[defined] \emph{nothing}
-% \item[undefined]
-% add the key to the list of unused global options (if the local option
-% list matches the option list of the main class)
-% \end{description}
-% \item[Package:]
-% \begin{description}
-% \item[defined] \emph{nothing}
-% \item[undefined] throw an error
-% \end{description}
-% \end{description}
-%
-% \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}
-% \begin{description}
-% \item[Class:]
-% \begin{description}
-% \item[defined] remove the option from the list of unused global options
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \item[Package:]
-% \begin{description}
-% \item[defined] remove the option from the list of unused global options
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \end{description}
-%
-% \begin{function}{\ekvoProcessUnusedGlobalOptions}
-% \begin{syntax}
-% \cs{ekvoProcessUnusedGlobalOptions}\marg{set}
-% \end{syntax}
-% If you want to, instead of parsing all global options, you can parse only
-% those global options which weren't yet used by another package or class.
-% \end{function}
-% \begin{description}
-% \item[Class:]
-% \begin{description}
-% \item[defined] remove the option from the list of unused global options
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \item[Package:]
-% \begin{description}
-% \item[defined] remove the option from the list of unused global options
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \end{description}
-%
-% \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}
-% \begin{description}
-% \item[Class:]
-% \begin{description}
-% \item[defined] \emph{nothing}
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \item[Package:]
-% \begin{description}
-% \item[defined] \emph{nothing}
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \end{description}
-%
-% \begin{function}{\ekvoUseUnknownHandlers}
-% \begin{syntax}
-% \cs{ekvoUseUnknownHandlers}\meta{cs_1}\meta{cs_2}
-% \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 \key\ without a \val\
-% is encountered and get one argument, being the \key. Analogous the macro
-% \meta{cs_2} will be called if an undefined \key\ with a \val\ was specified.
-% It will get two arguments, the first being the \key\ and the second the
-% \val.
-% \end{function}
-%
-% \begin{function}{\ekvoVersion,\ekvoDate}
-% These two macros store the version and date of the package.
-% \end{function}
-%
-%
-% \subsection{Example}
-%
-% 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
-% \cs[no-index]{thefootnote} and we'll call this package \pkg{ex-footnote}.
-% First we report back which package we are:
-% \begin{lstlisting}
-% \ProvidesPackage{ex-footnote}[2020-02-02 v1 change footnotes]
-% \end{lstlisting}
-% Next we'll need to provide the options we want the package to have.
-% \begin{lstlisting}
-% \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{lstlisting}
-% We can provide initial values just by defining the two macros storing the
-% value.
-% \begin{lstlisting}
-% \newcommand*\exfn@color{}
-% \newcommand*\exfn@format{arabic}
-% \end{lstlisting}
-% Next we need to process the options given to the package. The package should
-% only obey options directly passed to it, so we're only using
-% |\ekvoProcessLocalOptions|:
-% \begin{lstlisting}
-% \ekvoProcessLocalOptions{ex-footnote}
-% \end{lstlisting}
-% Now everything that's still missing is actually changing the way footnotes
-% appear:
-% \begin{lstlisting}
-% \renewcommand*\thefootnote
-% {%
-% \ifx\exfn@color\@empty
-% \csname\exfn@format\endcsname{footnote}%
-% \else
-% \textcolor{\exfn@color}{\csname\exfn@format\endcsname{footnote}}%
-% \fi
-% }
-% \end{lstlisting}
-% \bigskip
-%
-% \noindent
-% So the complete code of the package would look like this:
-% \begin{lstlisting}
-% \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}
-%
-% \renewcommand*\thefootnote
-% {%
-% \ifx\exfn@color\@empty
-% \csname\exfn@format\endcsname{footnote}%
-% \else
-% \textcolor{\exfn@color}{\csname\exfn@format\endcsname{footnote}}%
-% \fi
-% }
-% \end{lstlisting}
-% \bigskip
-%
-% \noindent
-% And it could be used with one of the following lines:
-% \begin{lstlisting}
-% \usepackage{ex-footnote}
-% \usepackage[format=fnsymbol]{ex-footnote}
-% \usepackage[color=green]{ex-footnote}
-% \usepackage[color=red,format=roman]{ex-footnote}
-% \end{lstlisting}
-%
-%
-% \subsection{Bugs}
-%
-% If you happen to find bugs, it'd be great if you let me know. Just write me an
-% email (see the front page) or submit a bug report on GitHub:
-% \url{https://github.com/Skillmon/tex_expkv-opt}
-%
-%
-% \subsection{License}
-%
-% Copyright \textcopyright\ 2020\unless\ifnum\year=2020--\the\year\fi\
-% Jonathan P. Spratte
-%
-% \medskip\noindent
-% 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:
-%
-% \url{http://www.latex-project.org/lppl.txt}
-%
-% \noindent
-% This work is ``maintained'' (as per LPPL maintenance status) by
-%
-% \mbox{Jonathan P. Spratte}.
-%
-% \end{documentation}^^A=<<
-%
-% \begin{implementation}^^A>>=
-%
-% \clearpage
-%
-%
-% \section{Implementation}
-%
-% \gobbledocstriptag
-%<*pkg>
-% Start the package with the typical \LaTeX\ standards.
-%
-% \begin{macro}{\ekvoVersion,\ekvoDate}
-% Store the packages version and date in two macros.
-% \begin{macrocode}
-\newcommand*\ekvoVersion{0.1b}
-\newcommand*\ekvoDate{2020-10-10}
-% \end{macrocode}
-% \end{macro}
-% And we report who we are and what we need.
-% \begin{macrocode}
-\ProvidesPackage{expkv-opt}
- [%
- \ekvoDate\space v\ekvoVersion\space
- parse class and package options with expkv%
- ]
-\RequirePackage{expkv}
-% \end{macrocode}
-%
-%
-% \subsection{Loop}
-%
-% \begin{macro}[internal]
-% {\ekvo@CurrentOption@loop,\ekvo@CurrentOption@loop@,\ekvo@end@loop}
-% We'll need some loop which can iterate over a comma separated list. The loop
-% is very basic and only works for commas of category~12. First we insert the
-% delimiters for the actual loop.
-% \begin{macrocode}
-\protected\long\def\ekvo@CurrentOption@loop#1#2%
- {%
- \ekvo@CurrentOption@loop@#2\ekv@mark#1,\ekv@stop,\ekvo@tail
- }
-% \end{macrocode}
-% The actual loop checks whether the final element has been read and if so
-% ends the loop. Else blank elements are ignored, |\CurrentOption| is set and
-% the macro which parses the list elements called. Then call the next
-% iteration.
-% \begin{macrocode}
-\long\def\ekvo@CurrentOption@loop@#1#2,%
- {%
- \ekv@gobble@from@mark@to@stop#2\ekvo@end@loop\ekv@stop
- \ekv@ifblank{#2}%
- {}%
- {%
- \edef\CurrentOption{\unexpanded\expandafter{\@gobble#2}}%
- #1{#2}%
- }%
- \ekvo@CurrentOption@loop@#1\ekv@mark
- }
-\long\def\ekvo@end@loop#1\ekvo@tail{}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{Tests}
-%
-% \begin{macro}[internal]{\ekvo@ifx@TF,\ekvo@ifx@F}
-% We'll need branching |\ifx| tests so that user input containing unbalanced
-% \TeX\ ifs doesn't break (at least not because of us, everything else is the
-% fault of \LaTeXe).
-% \begin{macrocode}
-\def\ekvo@ifx@TF#1#2{\ifx#1#2\ekv@fi@firstoftwo\fi\@secondoftwo}
-\def\ekvo@ifx@F#1#2{\ifx#1#2\ekv@fi@gobble\fi\@firstofone}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@do@with@set,\ekvo@name,\ekvo@setname}
-% This test checks whether the \set\ is defined. If it is we store it in
-% |\ekvo@setname| and set |\ekvo@name| to a short cut to get the \key's
-% callback name. Next we execute the code in |#2|, if the \set\ isn't defined
-% |#2| is gobbled.
-% \begin{macrocode}
-\protected\def\ekvo@do@with@set#1#2%
- {%
- \ekvifdefinedset{#1}%
- {%
- \expandafter
- \let\expandafter\ekvo@name\csname\ekv@undefined@set{#1}\endcsname
- \def\ekvo@setname{#1}%
- #2%
- }%
- {\ekvo@err@undefined@set{#1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{Key handlers}
-%
-% \expkvo\ uses handlers specifying what happens if a parsed \key\ is defined or
-% undefined.
-%
-% \begin{macro}[internal]
-% {\ekvo@handle@undefined@k@pkg,\ekvo@handle@undefined@kv@pkg}
-% The case for undefined keys in a local list of a package is easy, just throw
-% appropriate errors.
-% \begin{macrocode}
-\protected\long\def\ekvo@handle@undefined@k@pkg#1%
- {%
- \ekv@ifdefined{\ekvo@name{#1}}%
- {\ekvo@err@value@required{#1}}%
- {\ekvo@err@undefined@key{#1}}%
- }
-\def\ekvo@handle@undefined@kv@pkg#1#2%
- {%
- \ekv@ifdefined{\ekvo@name{#1}N}%
- {\ekvo@err@value@forbidden{#1}}%
- {\ekvo@err@undefined@key{#1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvo@addto@unused@one,\ekvo@addto@unused@two,
-% \ekvo@rmfrom@unused@one,\ekvo@rmfrom@unused@two
-% }
-% These macros will add or remove the |\CurrentOption| to or from the list of
-% unused global options.
-% \begin{macrocode}
-\long\def\ekvo@addto@unused@one#1{\ekvo@addto@list\@unusedoptionlist}
-\long\def\ekvo@addto@unused@two#1#2{\ekvo@addto@list\@unusedoptionlist}
-\long\def\ekvo@rmfrom@unused@one#1{\ekvo@rmfrom@list\@unusedoptionlist}
-\long\def\ekvo@rmfrom@unused@two#1#2{\ekvo@rmfrom@list\@unusedoptionlist}
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}[internal]
-% {
-% \ekvo@set@handlers@local,\ekvo@set@handlers@global,
-% \ekvo@set@handlers@unusedglobal,\ekvo@set@handlers@list
-% }
-% These macros are boring. They just set up the handlers to respect the rules
-% documented earlier.
-% \begin{macrocode}
-\protected\def\ekvo@set@handlers@local
- {%
- \ekvo@if@need@handlers
- {%
- \ifx\@currext\@clsextension
- \ifx\@classoptionslist\relax
- \let\ekvo@handle@undefined@k\@gobble
- \let\ekvo@handle@undefined@kv\@gobbletwo
- \else
- \expandafter
- \ifx\csname opt@\@currname.\@currext\endcsname\@classoptionslist
- \let\ekvo@handle@undefined@k\ekvo@addto@unused@one
- \let\ekvo@handle@undefined@kv\ekvo@addto@unused@two
- \else
- \let\ekvo@handle@undefined@k\@gobble
- \let\ekvo@handle@undefined@kv\@gobbletwo
- \fi
- \fi
- \else
- \let\ekvo@handle@undefined@k\ekvo@handle@undefined@k@pkg
- \let\ekvo@handle@undefined@kv\ekvo@handle@undefined@kv@pkg
- \fi
- }%
- }
-\protected\def\ekvo@set@handlers@global
- {%
- \unless\ifx\@unusedoptionlist\@empty
- \let\ekvo@handle@defined@k\ekvo@rmfrom@unused@one
- \let\ekvo@handle@defined@kv\ekvo@rmfrom@unused@two
- \fi
- \ekvo@if@need@handlers
- {%
- \let\ekvo@handle@undefined@k\@gobble
- \let\ekvo@handle@undefined@kv\@gobbletwo
- }%
- }
-\protected\def\ekvo@set@handlers@unusedglobal
- {%
- \ekvo@if@need@handlers
- {%
- \let\ekvo@handle@undefined@k\ekvo@addto@unused@one
- \let\ekvo@handle@undefined@kv\ekvo@addto@unused@two
- \let\@unusedoptionlist\@empty
- \@gobbletwo
- }%
- \@firstofone
- {%
- \let\ekvo@handle@defined@k\ekvo@rmfrom@unused@one
- \let\ekvo@handle@defined@kv\ekvo@rmfrom@unused@two
- }%
- }
-\protected\def\ekvo@set@handlers@list
- {%
- \ekvo@if@need@handlers
- {%
- \let\ekvo@handle@undefined@k\@gobble
- \let\ekvo@handle@undefined@kv\@gobbletwo
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@if@need@handlers,\ekvo@dont@need@handlers}
-% If the user specifies handlers this macro will be let to
-% |\ekvo@dont@need@handlers|, which will act like |\@gobble| and also let it
-% to |\@firstofone| afterwards.
-% \begin{macrocode}
-\let\ekvo@if@need@handlers\@firstofone
-\protected\long\def\ekvo@dont@need@handlers#1%
- {%
- \let\ekvo@if@need@handlers\@firstofone
- }%
-% \end{macrocode}
-% \end{macro}
-%
-% We have to set the default for the handlers of defined keys, because they
-% don't necessarily get defined before a list is parsed.
-% \begin{macrocode}
-\let\ekvo@handle@defined@k\@gobble
-\let\ekvo@handle@defined@kv\@gobbletwo
-% \end{macrocode}
-%
-%
-% \subsection{Processing list elements}
-%
-% \begin{macro}[internal]{\ekvo@process@common}
-% All the key processing frontend macros use the same basic structure. |#1|
-% will be a simple test, deciding whether the list will really be parsed or
-% not, |#3| will be the \set, and |#2| will be the individual code of the
-% frontend macro which should be executed if both the test in |#1| is true and
-% the \set\ is defined.
-% \begin{macrocode}
-\protected\def\ekvo@process@common#1#2#3%
- {%
- #1{\ekvo@do@with@set{#3}{#2}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@process@list}
-% This macro only expands the list holding macro and forwards it to the
-% loop macro.
-% \begin{macrocode}
-\protected\def\ekvo@process@list#1%
- {%
- \expandafter\ekvo@CurrentOption@loop\expandafter{#1}\ekvo@parse
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@parse}
-% This macro calls internals of |\ekvparse| such that the code splitting at
-% commas isn't executed, else this is equivalent to
-% |\ekvparse\ekvo@set@k\ekvo@set@kv{#1}|.
-% \begin{macrocode}
-\protected\long\def\ekvo@parse#1%
- {%
- \ekv@eq@other#1\ekv@nil\ekv@mark\ekv@parse@eq@other@a
- =\ekv@mark\ekv@parse@eq@active
- \ekvo@set@k\ekvo@set@kv
- \ekvo@tail
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@set@k,\ekvo@set@kv}
-% These two macros check whether the key is defined and if so call the handler
-% for defined keys and execute the key, else the handler for undefined keys is
-% called. They have to clean up a bit of code which is left by |\ekvo@parse|.
-% \begin{macrocode}
-\protected\def\ekvo@set@k#1#2\ekvo@tail
- {%
- \ekv@ifdefined{\ekvo@name{#1}N}%
- {%
- \ekvo@handle@defined@k{#1}%
- \csname\ekvo@name{#1}N\endcsname
- }%
- {\ekvo@handle@undefined@k{#1}}%
- }
-\protected\def\ekvo@set@kv#1#2#3\ekvo@tail
- {%
- \ekv@ifdefined{\ekvo@name{#1}}%
- {%
- \ekvo@handle@defined@kv{#1}{#2}%
- \csname\ekvo@name{#1}\endcsname{#2}%
- }%
- {\ekvo@handle@undefined@kv{#1}{#2}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{List variable helpers}
-%
-% \begin{macro}[internal]{\ekvo@addto@list}
-% This macro is rather simple. If the list to which the |\CurrentOption|
-% should be added is empty we can just let the list to the |\CurrentOption|.
-% Else we have to expand the list once and the |\CurrentOption| once.
-% \begin{macrocode}
-\protected\def\ekvo@addto@list#1%
- {%
- \ekvo@ifx@TF#1\@empty
- {\let#1\CurrentOption}%
- {%
- \edef#1%
- {%
- \unexpanded\expandafter{#1},%
- \unexpanded\expandafter{\CurrentOption}%
- }%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@rmfrom@list,\ekvo@rmfrom@list@}
-% This works by looping over every list item and comparing it to
-% |\ekvo@curropt| which stores the real |\CurrentOption|. This is
-% comparatively slow, but works for items containing braces unlike what
-% \LaTeXe\ does. We could be faster for items not containing braces, though.
-% \begin{macrocode}
-\protected\def\ekvo@rmfrom@list#1%
- {%
- \ekvo@ifx@F#1\@empty
- {%
- \let\ekvo@tmp@list\@empty
- \let\ekvo@curropt\CurrentOption
- \expandafter\ekvo@CurrentOption@loop\expandafter{#1}\ekvo@rmfrom@list@
- \let\CurrentOption\ekvo@curropt
- \let#1\ekvo@tmp@list
- }%
- }
-\protected\long\def\ekvo@rmfrom@list@#1%
- {%
- \ekvo@ifx@F\CurrentOption\ekvo@curropt
- {\ekvo@addto@list\ekvo@tmp@list}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{Errors}
-%
-% \begin{macro}[internal]
-% {
-% \ekvo@err@undefined@key,\ekvo@err@value@required,
-% \ekvo@err@value@forbidden,\ekvo@err@undefined@set
-% }
-% Just some macros to throw errors in the few cases an error has to be thrown.
-% \begin{macrocode}
-\protected\def\ekvo@err@undefined@key#1%
- {%
- \PackageError{expkv-opt}{Undefined key `#1' in set `\ekvo@setname'}{}%
- }
-\protected\def\ekvo@err@value@required#1%
- {%
- \PackageError{expkv-opt}%
- {Value required for key `#1' in set `\ekvo@setname'}%
- {}%
- }
-\protected\def\ekvo@err@value@forbidden#1%
- {%
- \PackageError{expkv-opt}%
- {Value forbidden for key `#1' in set `\ekvo@setname'}%
- {}%
- }
-\protected\def\ekvo@err@undefined@set#1%
- {%
- \PackageError{expkv-opt}%
- {Undefined set `#1'}%
- {The set for which you try to parse options isn't defined in expkv.}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{User Interface}
-%
-% The user interface macros just put together the bits and pieces.
-% \begin{macro}{\ekvoProcessLocalOptions}
-% \begin{macrocode}
-\protected\def\ekvoProcessLocalOptions
- {%
- \ekvo@process@common
- {\ekv@ifdefined{opt@\@currname.\@currext}\@firstofone\@gobble}%
- {%
- \ekvo@set@handlers@local
- \expandafter
- \ekvo@process@list\csname opt@\@currname.\@currext\endcsname
- \AtEndOfPackage{\let\@unprocessedoptions\relax}%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}{\ekvoProcessGlobalOptions}
-% \begin{macrocode}
-\protected\def\ekvoProcessGlobalOptions
- {%
- \ekvo@process@common{\ekvo@ifx@F\@classoptionslist\relax}%
- {%
- \ekvo@set@handlers@global
- \ekvo@process@list\@classoptionslist
- \let\ekvo@handle@defined@k\@gobble
- \let\ekvo@handle@defined@kv\@gobbletwo
- }%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}{\ekvoProcessUnusedGlobalOptions}
-% \begin{macrocode}
-\protected\def\ekvoProcessUnusedGlobalOptions
- {%
- \ekvo@process@common{\ekvo@ifx@F\@unusedoptionlist\@empty}%
- {%
- \let\ekvo@tmp@list\@unusedoptionlist
- \ekvo@set@handlers@unusedglobal
- \ekvo@process@list\ekvo@tmp@list
- \let\ekvo@handle@defined@k\@gobble
- \let\ekvo@handle@defined@kv\@gobbletwo
- }%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}{\ekvoProcessOptionsList}
-% \begin{macrocode}
-\protected\def\ekvoProcessOptionsList#1%
- {%
- \ekvo@process@common{\ekvo@ifx@F#1\@empty}%
- {%
- \ekvo@set@handlers@list
- \ekvo@process@list#1%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}{\ekvoUseUnknownHandlers}
-% \begin{macrocode}
-\protected\def\ekvoUseUnknownHandlers#1#2%
- {%
- \let\ekvo@handle@undefined@k#1\relax
- \let\ekvo@handle@undefined@kv#2\relax
- \let\ekvo@if@need@handlers\ekvo@dont@need@handlers
- }
-% \end{macrocode}
-% \end{macro}
-%
-% All user interface macros should be only used in the preamble.
-% \begin{macrocode}
-\@onlypreamble\ekvoProcessLocalOptions
-\@onlypreamble\ekvoProcessGlobalOptions
-\@onlypreamble\ekvoProcessUnusedGlobalOptions
-\@onlypreamble\ekvoProcessOptionsList
-\@onlypreamble\ekvoUseUnknownHandlers
-% \end{macrocode}
-%
-% \gobbledocstriptag
-%</pkg>
-%
-% \end{implementation}^^A=<<
-%
-% \clearpage
-% \PrintIndex
-%
-% \Finale
-\endinput
-%
-^^A vim: ft=tex fdm=marker fmr=>>=,=<<
diff --git a/obsolete/macros/generic/expkv-opt/expkv-opt.dtx b/obsolete/macros/generic/expkv-opt/expkv-opt.dtx
deleted file mode 100644
index 22a9a9b0c3..0000000000
--- a/obsolete/macros/generic/expkv-opt/expkv-opt.dtx
+++ /dev/null
@@ -1,1012 +0,0 @@
-% \iffalse meta-comment
-%
-% File: expkv-opt.dtx Copyright (C) 2020 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
-%
-% ------------------------------------------------------------------------------
-%
-%<*driver>^^A>>=
-\def\nameofplainTeX{plain}
-\ifx\fmtname\nameofplainTeX\else
- \expandafter\begingroup
-\fi
-\input l3docstrip.tex
-\askforoverwritefalse
-\preamble
-
---------------------------------------------------------------
-expkv-opt -- parse class and package options with expkv
-E-mail: jspratte@yahoo.de
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
---------------------------------------------------------------
-
-Copyright (C) 2020 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.
-
-This work consists of the file expkv-opt.dtx
-and the derived files expkv-opt.pdf
- expkv-opt.sty
-
-\endpreamble
-% stop docstrip adding \endinput
-\postamble
-\endpostamble
-\generate{\file{expkv-opt.sty}{\from{expkv-opt.dtx}{pkg}}}
-\ifx\fmtname\nameofplainTeX
- \expandafter\endbatchfile
-\else
- \expandafter\endgroup
-\fi
-%
-\IfFileExists{expkv-opt.sty}{\RequirePackage{expkv-opt}}{}
-\ProvidesFile{expkv-opt.dtx}
- [\csname ekvoDate\endcsname\ parse class and package options with expkv]
-\PassOptionsToPackage{full}{textcomp}
-\documentclass{l3doc}
-\RequirePackage[oldstylenums,nott]{kpfonts}
-\input{glyphtounicode}
-\pdfgentounicode=1
-\RequirePackage{listings}
-\RequirePackage{booktabs}
-\RequirePackage{array}
-\RequirePackage{collcell}
-\RequirePackage{siunitx}
-\RequirePackage{xcolor}
-\RequirePackage{caption}
-\RequirePackage{microtype}
-\RequirePackage{accsupp}
-\lstset
- {
- ,flexiblecolumns=false
- ,basewidth=.53em
- ,gobble=2
- ,basicstyle=\fontfamily{jkp}\itshape
- ,morekeywords=^^A
- {^^A
- \ekvoProcessLocalOptions,
- \ekvoProcessGlobalOptions,
- \ekvoProcessUnusedGlobalOptions,
- \ekvoProcessOptionsList,
- \ekvoUseUnknownHandlers
- }
- ,morecomment=[l]\%
- ,commentstyle=\color[gray]{0.4}
- ,literate={\{}{{\CodeSymbol\{}}{1}
- {\}}{{\CodeSymbol\}}}{1}
- ^^A,literate=*{<key>}{\key}{4}{<set>}{\set}{4}
- }
-\newcommand*\CodeSymbol[1]{\textbf{#1}}
-\RequirePackage{randtext}
-\let\metaORIG\meta
-\protected\def\meta #1{\texttt{\metaORIG{#1}}}
-\renewcommand*\thefootnote{\fnsymbol{footnote}}
-\definecolor{expkvred}{HTML}{9F393D}
-\colorlet{expkvgrey}{black!75}
-\makeatletter
-\newcommand*\expkv
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv}^^A
- \href{https://github.com/Skillmon/tex_expkv}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv}^^A
- }
-\newcommand*\expkvpkg[1]
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv-#1}^^A
- \href{https://github.com/Skillmon/tex_expkv-#1}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- {\color{expkvgrey}^^A
- \kern.05em\rule[-.1ex]{.08em}{1.2ex}\kern.05em\textsc{#1}^^A
- }^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv-#1}^^A
- }
-\newcommand*\expkvd{\expkvpkg{def}}
-\newcommand*\expkvc{\expkvpkg{cs}}
-\newcommand*\expkvo{\expkvpkg{opt}}
-\newcommand\kv{\meta{key}=\meta{value}}
-\newcommand\key{\meta{key}}
-\newcommand\val{\meta{value}}
-\newcommand\set{\meta{set}}
-\hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
-\DoNotIndex{\def,\edef,\,,\=,\begingroup,\catcode,\chardef,\csname,\endcsname}
-\DoNotIndex{\endgroup,\endinput,\errmessage,\expandafter,\input,\let,\long}
-\DoNotIndex{\protected,\ProvidesFile,\ProvidesPackage,\relax,\space}
-\DoNotIndex{\@,\unexpanded,\string,\expanded,\dimexpr,\global,\glueexpr,\hbox}
-\DoNotIndex{\numexpr,\RequirePackage,\setbox,\the,\unless,\xdef,\@firstofone}
-\DoNotIndex{\@firstoftwo,\@gobble,\@secondoftwo,\AtEndOfPackage,\newcommand}
-\DoNotIndex{\PackageError,\@classoptionslist,\@clsextension,\@currext}
-\DoNotIndex{\@currname,\@empty,\@gobbletwo,\@onlypreamble,\@raw@classoptionslist}
-\DoNotIndex{\@unprocessedoptions,\@unusedoptionlist}
-\DoNotIndex{\DeclareRelease,\DeclareCurrentRelease,\IfFormatAtLeastTF}
-\DoNotIndex{\PackageWarning,\requestedLaTeXdate,\@ifstar}
-\DoNotIndex{\pkgcls@parse@date@arg,\pkgcls@targetdate,\pkgcls@targetlabel}
-\DoNotIndex{\ifcsname}
-\DoNotIndex{\ifx}
-\DoNotIndex{\ifdefined}
-\DoNotIndex{\iffalse}
-\DoNotIndex{\iftrue}
-\DoNotIndex{\ifnum}
-\DoNotIndex{\else}
-\DoNotIndex{\fi}
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
-\@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
-\makeatother
-\begin{document}
- \title
- {^^A
- \texorpdfstring
- {^^A
- \huge\expkvo
- \\[\medskipamount]
- \Large parse class and package options with \expkv
- }{expkv-opt - parse class and package options with expkv}^^A
- }
- \date{\ekvoDate\space v\ekvoVersion}
- \author{Jonathan P. Spratte\thanks{\protect\randomize{jspratte@yahoo.de}}}
- \DocInput{expkv-opt.dtx}
-\end{document}
-%</driver>^^A=<<
-% \fi
-%
-% \maketitle
-% \renewcommand*\thefootnote{\arabic{footnote}}
-%
-% \begin{abstract}
-% \noindent\parfillskip=0pt
-% \expkvo\ provides option parsing for classes and packages in \LaTeXe\ based on
-% \expkv. Global and local options are parsed individually by different
-% commands. The stylised name is \expkvo\ but the files use \file{expkv-opt},
-% this is due to CTAN-rules which don't allow \string| in package names since
-% that is the pipe symbol in *nix shells.
-% \end{abstract}
-%
-% \tableofcontents
-%
-% \begin{documentation}^^A>>=
-%
-% \section{Documentation}
-%
-% The \expkv\ family provides at its core a \kv\ parser and additionally
-% packages, one to conveniently define new keys (\expkvd) and another to build
-% expandable \kv\ taking control sequences (\expkvc). Still missing from the mix
-% was a solution to parse \LaTeXe\ class and package options, a gap that's
-% hereby filled with \expkvo.
-%
-% 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. One thing 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.
-% \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. The one thing that \expkvo\ doesn't support, which \expkv\
-% alone would, is active commas. But there is no good reason why a comma could
-% be active in the preamble.
-%
-% The package can be loaded with
-% \begin{lstlisting}
-% \usepackage{expkv-opt}
-% \end{lstlisting}
-% and if you need a specific version you can use \LaTeXe's rollback support, so
-% to load v0.1 explicitly use:
-% \begin{lstlisting}
-% \usepackage{expkv-opt}[=v0.1]
-% \end{lstlisting}
-% which will load the latest subversion of v0.1
-% (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)
-% Unlike the other packages in the \expkv\ family, \expkvo\ is only provided as
-% a \LaTeX\ package.
-%
-% Before reading this documentation you should read \expkv's documentation and
-% might want to also read the documentation of \expkvd.
-%
-%
-% \subsection{Macros}
-%
-% \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 \cs{CurrentOption}.
-%
-% \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}
-% \begin{description}
-% \item[Class:]
-% \begin{description}
-% \item[defined] \emph{nothing}
-% \item[undefined]
-% add the key to the list of unused global options (if the local option
-% list matches the option list of the main class)
-% \end{description}
-% \item[Package:]
-% \begin{description}
-% \item[defined] \emph{nothing}
-% \item[undefined] throw an error
-% \end{description}
-% \end{description}
-%
-% \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}
-% \begin{description}
-% \item[Class:]
-% \begin{description}
-% \item[defined] remove the option from the list of unused global options
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \item[Package:]
-% \begin{description}
-% \item[defined] remove the option from the list of unused global options
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \end{description}
-%
-% \begin{function}{\ekvoProcessUnusedGlobalOptions}
-% \begin{syntax}
-% \cs{ekvoProcessUnusedGlobalOptions}\marg{set}
-% \end{syntax}
-% This does no longer work with \LaTeXe\ kernels starting from 2021-05-01,
-% since the handling of the unused option list changed and no longer includes
-% the values. As a result this will throw a warning and else will be ignored.
-% \end{function}
-%
-% \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}
-% \begin{description}
-% \item[Class:]
-% \begin{description}
-% \item[defined] \emph{nothing}
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \item[Package:]
-% \begin{description}
-% \item[defined] \emph{nothing}
-% \item[undefined] \emph{nothing}
-% \end{description}
-% \end{description}
-%
-% \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 \key\ without a \val\
-% is encountered and get one argument, being the \key. Analogous the macro
-% \meta{cs_2} will be called if an undefined \key\ with a \val\ was specified.
-% It will get two arguments, the first being the \key\ 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{Example}
-%
-% 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
-% \cs[no-index]{thefootnote} and we'll call this package \pkg{ex-footnote}.
-% First we report back which package we are:
-% \begin{lstlisting}
-% \ProvidesPackage{ex-footnote}[2020-02-02 v1 change footnotes]
-% \end{lstlisting}
-% Next we'll need to provide the options we want the package to have.
-% \begin{lstlisting}
-% \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{lstlisting}
-% We can provide initial values just by defining the two macros storing the
-% value.
-% \begin{lstlisting}
-% \newcommand*\exfn@color{}
-% \newcommand*\exfn@format{arabic}
-% \end{lstlisting}
-% Next we need to process the options given to the package. The package should
-% only obey options directly passed to it, so we're only using
-% |\ekvoProcessLocalOptions|:
-% \begin{lstlisting}
-% \ekvoProcessLocalOptions{ex-footnote}
-% \end{lstlisting}
-% Now everything that's still missing is actually changing the way footnotes
-% appear:
-% \begin{lstlisting}
-% \renewcommand*\thefootnote
-% {%
-% \ifx\exfn@color\@empty
-% \csname\exfn@format\endcsname{footnote}%
-% \else
-% \textcolor{\exfn@color}{\csname\exfn@format\endcsname{footnote}}%
-% \fi
-% }
-% \end{lstlisting}
-% \bigskip
-%
-% \noindent
-% So the complete code of the package would look like this:
-% \begin{lstlisting}
-% \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}
-%
-% \renewcommand*\thefootnote
-% {%
-% \ifx\exfn@color\@empty
-% \csname\exfn@format\endcsname{footnote}%
-% \else
-% \textcolor{\exfn@color}{\csname\exfn@format\endcsname{footnote}}%
-% \fi
-% }
-% \end{lstlisting}
-% \bigskip
-%
-% \noindent
-% And it could be used with one of the following lines:
-% \begin{lstlisting}
-% \usepackage{ex-footnote}
-% \usepackage[format=fnsymbol]{ex-footnote}
-% \usepackage[color=green]{ex-footnote}
-% \usepackage[color=red,format=roman]{ex-footnote}
-% \end{lstlisting}
-%
-%
-% \subsection{Bugs}
-%
-% If you happen to find bugs, it'd be great if you let me know. Just write me an
-% email (see the front page) or submit a bug report on GitHub:
-% \url{https://github.com/Skillmon/tex_expkv-opt}
-%
-%
-% \subsection{License}
-%
-% Copyright \textcopyright\ 2020\unless\ifnum\year=2020--\the\year\fi\
-% Jonathan P. Spratte
-%
-% \medskip\noindent
-% 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:
-%
-% \url{http://www.latex-project.org/lppl.txt}
-%
-% \noindent
-% This work is ``maintained'' (as per LPPL maintenance status) by
-%
-% \mbox{Jonathan P. Spratte}.
-%
-% \end{documentation}^^A=<<
-%
-% \begin{implementation}^^A>>=
-%
-% \clearpage
-%
-%
-% \section{Implementation}
-%
-% \gobbledocstriptag
-%<*pkg>
-%
-% First we check whether the \LaTeXe\ kernel supports raw options. If it doesn't
-% we check whether a specific version was requested, and if that's not the case
-% we manually run |\pkgcls@parse@date@arg| with the last version that supported
-% non-raw options.
-% \begin{macrocode}
-\IfFormatAtLeastTF{2021/05/01}
- {}
- {%
- \ifx\pkgcls@targetlabel\@empty
- \ifnum\requestedLaTeXdate=\pkgcls@targetdate
- \pkgcls@parse@date@arg{=v0.1}%
- \fi
- \fi
- }
-% \end{macrocode}
-% Then we tell \LaTeXe\ where to find which release so that the package rollback
-% code of \LaTeXe\ can do its thing.
-% \begin{macrocode}
-\DeclareRelease{v0.1}{2020/10/10}{expkv-opt-2020-10-10.sty}
-\DeclareCurrentRelease{v0.2}{2021/04/04}
-% \end{macrocode}
-%
-% Start the package with the typical \LaTeX\ standards.
-%
-% \begin{macro}{\ekvoVersion,\ekvoDate}
-% Store the packages version and date in two macros.
-% \begin{macrocode}
-\newcommand*\ekvoVersion{0.2}
-\newcommand*\ekvoDate{2021-04-04}
-% \end{macrocode}
-% \end{macro}
-% And we report who we are and what we need.
-% \begin{macrocode}
-\ProvidesPackage{expkv-opt}
- [%
- \ekvoDate\space v\ekvoVersion\space
- parse class and package options with expkv%
- ]
-\RequirePackage{expkv}
-% \end{macrocode}
-%
-%
-% \subsection{Loop}
-%
-% \begin{macro}[internal]
-% {\ekvo@CurrentOption@loop,\ekvo@CurrentOption@loop@,\ekvo@end@loop}
-% We'll need some loop which can iterate over a comma separated list. The loop
-% is very basic and only works for commas of category~12. First we insert the
-% delimiters for the actual loop.
-% \begin{macrocode}
-\protected\long\def\ekvo@CurrentOption@loop#1#2%
- {%
- \ekvo@CurrentOption@loop@#2\ekv@mark#1,\ekv@stop,\ekvo@tail
- }
-% \end{macrocode}
-% The actual loop checks whether the final element has been read and if so
-% ends the loop. Else blank elements are ignored, |\CurrentOption| is set and
-% the macro which parses the list elements called. Then call the next
-% iteration.
-% \begin{macrocode}
-\long\def\ekvo@CurrentOption@loop@#1#2,%
- {%
- \ekv@gobble@from@mark@to@stop#2\ekvo@end@loop\ekv@stop
- \ekv@ifblank{#2}%
- {}%
- {%
- \edef\CurrentOption{\unexpanded\expandafter{\@gobble#2}}%
- #1{#2}%
- }%
- \ekvo@CurrentOption@loop@#1\ekv@mark
- }
-\long\def\ekvo@end@loop#1\ekvo@tail{}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{Tests}
-%
-% \begin{macro}[internal]{\ekvo@ifx@TF,\ekvo@ifx@F}
-% We'll need branching |\ifx| tests so that user input containing unbalanced
-% \TeX\ ifs doesn't break (at least not because of us, everything else is the
-% fault of \LaTeXe).
-% \begin{macrocode}
-\def\ekvo@ifx@TF#1#2{\ifx#1#2\ekv@fi@firstoftwo\fi\@secondoftwo}
-\def\ekvo@ifx@F#1#2{\ifx#1#2\ekv@fi@gobble\fi\@firstofone}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@do@with@set,\ekvo@name,\ekvo@setname}
-% This test checks whether the \set\ is defined. If it is we store it in
-% |\ekvo@setname| and set |\ekvo@name| to a short cut to get the \key's
-% callback name. Next we execute the code in |#2|, if the \set\ isn't defined
-% |#2| is gobbled.
-% \begin{macrocode}
-\protected\def\ekvo@do@with@set#1#2%
- {%
- \ekvifdefinedset{#1}%
- {%
- \expandafter
- \let\expandafter\ekvo@name\csname\ekv@undefined@set{#1}\endcsname
- \def\ekvo@setname{#1}%
- #2%
- }%
- {\ekvo@err@undefined@set{#1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{Key handlers}
-%
-% \expkvo\ uses handlers specifying what happens if a parsed \key\ is defined or
-% undefined.
-%
-% \begin{macro}[internal]
-% {\ekvo@handle@undefined@k@pkg,\ekvo@handle@undefined@kv@pkg}
-% The case for undefined keys in a local list of a package is easy, just throw
-% appropriate errors.
-% \begin{macrocode}
-\protected\long\def\ekvo@handle@undefined@k@pkg#1%
- {%
- \ekv@ifdefined{\ekvo@name{#1}}%
- {\ekvo@err@value@required{#1}}%
- {\ekvo@err@undefined@key{#1}}%
- }
-\def\ekvo@handle@undefined@kv@pkg#1#2%
- {%
- \ekv@ifdefined{\ekvo@name{#1}N}%
- {\ekvo@err@value@forbidden{#1}}%
- {\ekvo@err@undefined@key{#1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvo@addto@unused@one,\ekvo@addto@unused@two,
-% \ekvo@rmfrom@unused@one,\ekvo@rmfrom@unused@two
-% }
-% These macros will add or remove the |\CurrentOption| to or from the list of
-% unused global options. Since |\ekvo@do@unusedoptionlist| will have some
-% overhead before calling the list changing macro in filtering the current
-% option, we use an optimization here in that we check whether the list is
-% empty before calling the |rmfrom| function.
-% \begin{macrocode}
-\long\def\ekvo@addto@unused@one#1{\ekvo@do@unusedoptionlist\ekvo@addto@list}
-\long\def\ekvo@addto@unused@two#1#2{\ekvo@do@unusedoptionlist\ekvo@addto@list}
-\long\def\ekvo@rmfrom@unused@one#1%
- {%
- \ekvo@ifx@F\@unusedoptionlist\@empty
- {\ekvo@do@unusedoptionlist\ekvo@rmfrom@list}%
- }
-\long\def\ekvo@rmfrom@unused@two#1#2%
- {%
- \ekvo@ifx@F\@unusedoptionlist\@empty
- {\ekvo@do@unusedoptionlist\ekvo@rmfrom@list}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvo@do@unusedoptionlist,
-% \ekvo@prepare@unusedoption,
-% \ekvo@prepare@unusedoption@a,
-% \ekvo@prepare@unusedoption@b,
-% \ekvo@prepare@unusedoption@c
-% }
-% The way the new \LaTeXe\ kernel handles the unused option list changed. Now
-% not the entire |\CurrentOption| is listed, but just everything up to the
-% first equals sign, and spaces got zapped, doesn't matter whether the raw
-% option list gets used or not. So we have to zap spaces and remove everything
-% from the first equals sign onwards. The code used here will fail if the
-% current option contains an |\ekv@mark| or |\ekv@stop| before the first
-% equals sign (this seems rather unlikely).
-% \begin{macrocode}
-\protected\def\ekvo@do@unusedoptionlist#1%
- {%
- \let\ekvo@unpreparedCurrentOption\CurrentOption
- \edef\CurrentOption
- {\expandafter\ekvo@prepare@unusedoption\CurrentOption=\ekv@mark}%
- #1\@unusedoptionlist
- \let\CurrentOption\ekvo@unpreparedCurrentOption
- }
-\def\ekvo@prepare@unusedoption{\ekvo@prepare@unusedoption@a\@empty}
-\def\ekvo@prepare@unusedoption@a#1%
- {%
- \long\def\ekvo@prepare@unusedoption@a##1=##2\ekv@mark
- {%
- \ekvo@prepare@unusedoption@b##1\ekv@stop
- \ekv@mark\ekvo@prepare@unusedoption@b
- #1\ekv@mark\ekvo@prepare@unusedoption@c
- }%
- }
-\ekvo@prepare@unusedoption@a{ }
-\long\def\ekvo@prepare@unusedoption@b#1 #2\ekv@mark#3{#3#1#2\ekv@mark#3}
-\long\def\ekvo@prepare@unusedoption@c
- #1\ekv@stop
- \ekv@mark\ekvo@prepare@unusedoption@b\ekv@mark\ekvo@prepare@unusedoption@c
- {\unexpanded\expandafter{#1}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekvo@set@handlers@local,\ekvo@set@handlers@global,
-% \ekvo@set@handlers@list
-% }
-% These macros are boring. They just set up the handlers to respect the rules
-% documented earlier.
-% \begin{macrocode}
-\protected\def\ekvo@set@handlers@local
- {%
- \ekvo@if@need@handlers
- {%
- \ifx\@currext\@clsextension
- \ifx\@classoptionslist\relax
- \let\ekvo@handle@undefined@k\@gobble
- \let\ekvo@handle@undefined@kv\@gobbletwo
- \else
- \expandafter
- \ifx
- \csname @raw@opt@\@currname.\@currext\endcsname
- \@raw@classoptionslist
- \let\ekvo@handle@undefined@k\ekvo@addto@unused@one
- \let\ekvo@handle@undefined@kv\ekvo@addto@unused@two
- \else
- \let\ekvo@handle@undefined@k\@gobble
- \let\ekvo@handle@undefined@kv\@gobbletwo
- \fi
- \fi
- \else
- \let\ekvo@handle@undefined@k\ekvo@handle@undefined@k@pkg
- \let\ekvo@handle@undefined@kv\ekvo@handle@undefined@kv@pkg
- \fi
- }%
- }
-\protected\def\ekvo@set@handlers@global
- {%
- \unless\ifx\@unusedoptionlist\@empty
- \let\ekvo@handle@defined@k\ekvo@rmfrom@unused@one
- \let\ekvo@handle@defined@kv\ekvo@rmfrom@unused@two
- \fi
- \ekvo@if@need@handlers
- {%
- \let\ekvo@handle@undefined@k\@gobble
- \let\ekvo@handle@undefined@kv\@gobbletwo
- }%
- }
-\protected\def\ekvo@set@handlers@list
- {%
- \ekvo@if@need@handlers
- {%
- \let\ekvo@handle@undefined@k\@gobble
- \let\ekvo@handle@undefined@kv\@gobbletwo
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@if@need@handlers,\ekvo@dont@need@handlers}
-% If the user specifies handlers this macro will be let to
-% |\ekvo@dont@need@handlers|, which will act like |\@gobble| and also let it
-% to |\@firstofone| afterwards.
-% \begin{macrocode}
-\let\ekvo@if@need@handlers\@firstofone
-\protected\long\def\ekvo@dont@need@handlers#1%
- {%
- \let\ekvo@if@need@handlers\@firstofone
- }%
-% \end{macrocode}
-% \end{macro}
-%
-% We have to set the default for the handlers of defined keys, because they
-% don't necessarily get defined before a list is parsed.
-% \begin{macrocode}
-\let\ekvo@handle@defined@k\@gobble
-\let\ekvo@handle@defined@kv\@gobbletwo
-% \end{macrocode}
-%
-%
-% \subsection{Processing list elements}
-%
-% \begin{macro}[internal]{\ekvo@process@common}
-% All the key processing frontend macros use the same basic structure. |#1|
-% will be a simple test, deciding whether the list will really be parsed or
-% not, |#3| will be the \set, and |#2| will be the individual code of the
-% frontend macro which should be executed if both the test in |#1| is true and
-% the \set\ is defined.
-% \begin{macrocode}
-\protected\def\ekvo@process@common#1#2#3%
- {%
- #1{\ekvo@do@with@set{#3}{#2}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@process@list}
-% This macro only expands the list holding macro and forwards it to the
-% loop macro.
-% \begin{macrocode}
-\protected\def\ekvo@process@list#1%
- {%
- \expandafter\ekvo@CurrentOption@loop\expandafter{#1}\ekvo@parse
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@parse}
-% This macro calls internals of |\ekvparse| such that the code splitting at
-% commas isn't executed, else this is equivalent to
-% |\ekvparse\ekvo@set@k\ekvo@set@kv{#1}|.
-% \begin{macrocode}
-\protected\long\def\ekvo@parse#1%
- {%
- \ekv@eq@other#1\ekv@nil\ekv@mark\ekv@parse@eq@other@a
- =\ekv@mark\ekv@parse@eq@active
- \ekvo@set@k\ekvo@set@kv
- \ekvo@tail
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@set@k,\ekvo@set@kv}
-% These two macros check whether the key is defined and if so call the handler
-% for defined keys and execute the key, else the handler for undefined keys is
-% called. They have to clean up a bit of code which is left by |\ekvo@parse|.
-% \begin{macrocode}
-\protected\def\ekvo@set@k#1#2\ekvo@tail
- {%
- \ekv@ifdefined{\ekvo@name{#1}N}%
- {%
- \ekvo@handle@defined@k{#1}%
- \csname\ekvo@name{#1}N\endcsname
- }%
- {\ekvo@handle@undefined@k{#1}}%
- }
-\protected\def\ekvo@set@kv#1#2#3\ekvo@tail
- {%
- \ekv@ifdefined{\ekvo@name{#1}}%
- {%
- \ekvo@handle@defined@kv{#1}{#2}%
- \csname\ekvo@name{#1}\endcsname{#2}%
- }%
- {\ekvo@handle@undefined@kv{#1}{#2}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{List variable helpers}
-%
-% \begin{macro}[internal]{\ekvo@addto@list}
-% This macro is rather simple. If the list to which the |\CurrentOption|
-% should be added is empty we can just let the list to the |\CurrentOption|.
-% Else we have to expand the list once and the |\CurrentOption| once.
-% \begin{macrocode}
-\protected\def\ekvo@addto@list#1%
- {%
- \ekvo@ifx@TF#1\@empty
- {\let#1\CurrentOption}%
- {%
- \edef#1%
- {%
- \unexpanded\expandafter{#1},%
- \unexpanded\expandafter{\CurrentOption}%
- }%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvo@rmfrom@list,\ekvo@rmfrom@list@}
-% This works by looping over every list item and comparing it to
-% |\ekvo@curropt| which stores the real |\CurrentOption|. This is
-% comparatively slow, but works for items containing braces unlike what
-% \LaTeXe\ does. We could be faster for items not containing braces, though.
-% \begin{macrocode}
-\protected\def\ekvo@rmfrom@list#1%
- {%
- \ekvo@ifx@F#1\@empty
- {%
- \let\ekvo@tmp@list\@empty
- \let\ekvo@curropt\CurrentOption
- \expandafter\ekvo@CurrentOption@loop\expandafter{#1}\ekvo@rmfrom@list@
- \let\CurrentOption\ekvo@curropt
- \let#1\ekvo@tmp@list
- }%
- }
-\protected\long\def\ekvo@rmfrom@list@#1%
- {%
- \ekvo@ifx@F\CurrentOption\ekvo@curropt
- {\ekvo@addto@list\ekvo@tmp@list}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{Errors}
-%
-% \begin{macro}[internal]
-% {
-% \ekvo@err@undefined@key,\ekvo@err@value@required,
-% \ekvo@err@value@forbidden,\ekvo@err@undefined@set
-% }
-% Just some macros to throw errors in the few cases an error has to be thrown.
-% \begin{macrocode}
-\protected\def\ekvo@err@undefined@key#1%
- {%
- \PackageError{expkv-opt}{Undefined key `#1' in set `\ekvo@setname'}{}%
- }
-\protected\def\ekvo@err@value@required#1%
- {%
- \PackageError{expkv-opt}%
- {Value required for key `#1' in set `\ekvo@setname'}%
- {}%
- }
-\protected\def\ekvo@err@value@forbidden#1%
- {%
- \PackageError{expkv-opt}%
- {Value forbidden for key `#1' in set `\ekvo@setname'}%
- {}%
- }
-\protected\def\ekvo@err@undefined@set#1%
- {%
- \PackageError{expkv-opt}%
- {Undefined set `#1'}%
- {The set for which you try to parse options isn't defined in expkv.}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsection{User Interface}
-%
-% The user interface macros just put together the bits and pieces.
-% \begin{macro}{\ekvoProcessLocalOptions}
-% \begin{macrocode}
-\protected\def\ekvoProcessLocalOptions
- {%
- \ekvo@process@common
- {\ekv@ifdefined{@raw@opt@\@currname.\@currext}\@firstofone\@gobble}%
- {%
- \ekvo@set@handlers@local
- \expandafter
- \ekvo@process@list\csname @raw@opt@\@currname.\@currext\endcsname
- \AtEndOfPackage{\let\@unprocessedoptions\relax}%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}{\ekvoProcessGlobalOptions}
-% \begin{macrocode}
-\protected\def\ekvoProcessGlobalOptions
- {%
- \ekvo@process@common{\ekvo@ifx@F\@classoptionslist\relax}%
- {%
- \ekvo@set@handlers@global
- \ekvo@process@list\@raw@classoptionslist
- \let\ekvo@handle@defined@k\@gobble
- \let\ekvo@handle@defined@kv\@gobbletwo
- }%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}{\ekvoProcessUnusedGlobalOptions}
-% \begin{macrocode}
-\protected\def\ekvoProcessUnusedGlobalOptions#1%
- {%
- \PackageWarning{expkv-opt}%
- {This macro no longer works because of changes in the LaTeX2e kernel.}%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}{\ekvoProcessOptionsList}
-% \begin{macrocode}
-\protected\def\ekvoProcessOptionsList#1%
- {%
- \ekvo@process@common{\ekvo@ifx@F#1\@empty}%
- {%
- \ekvo@set@handlers@list
- \ekvo@process@list#1%
- }%
- }
-% \end{macrocode}
-% \end{macro}
-% \begin{macro}{\ekvoUseUnknownHandlers}
-% \begin{macrocode}
-\protected\def\ekvoUseUnknownHandlers
- {\@ifstar\ekvoUseUnknownHandlers@s\ekvoUseUnknownHandlers@n}
-\protected\def\ekvoUseUnknownHandlers@s
- {%
- \def\ekvo@handle@undefined@k
- {%
- \ekv@ifdefined{\ekvo@name{}uN}%
- {\csname\ekvo@name{}uN\endcsname}%
- {\@gobble}%
- }%
- \long\def\ekvo@handle@undefined@kv##1##2%
- {%
- \ekv@ifdefined{\ekvo@name{}u}%
- {\csname\ekvo@name{}u\endcsname{##2}{##1}}%
- {}%
- }%
- \let\ekvo@if@need@handlers\ekvo@dont@need@handlers
- }
-\protected\def\ekvoUseUnknownHandlers@n#1#2%
- {%
- \let\ekvo@handle@undefined@k#1\relax
- \let\ekvo@handle@undefined@kv#2\relax
- \let\ekvo@if@need@handlers\ekvo@dont@need@handlers
- }
-% \end{macrocode}
-% \end{macro}
-%
-% All user interface macros should be only used in the preamble.
-% \begin{macrocode}
-\@onlypreamble\ekvoProcessLocalOptions
-\@onlypreamble\ekvoProcessGlobalOptions
-\@onlypreamble\ekvoProcessUnusedGlobalOptions
-\@onlypreamble\ekvoProcessOptionsList
-\@onlypreamble\ekvoUseUnknownHandlers
-% \end{macrocode}
-%
-% \gobbledocstriptag
-%</pkg>
-%
-% \end{implementation}^^A=<<
-%
-% \clearpage
-% \PrintIndex
-%
-% \Finale
-\endinput
-%
-^^A vim: ft=tex fdm=marker fmr=>>=,=<<
diff --git a/obsolete/macros/generic/expkv-opt/expkv-opt.pdf b/obsolete/macros/generic/expkv-opt/expkv-opt.pdf
deleted file mode 100644
index 5ecded074a..0000000000
--- a/obsolete/macros/generic/expkv-opt/expkv-opt.pdf
+++ /dev/null
Binary files differ
diff --git a/obsolete/macros/generic/expkv/README.md b/obsolete/macros/generic/expkv/README.md
deleted file mode 100644
index ccfa3194b3..0000000000
--- a/obsolete/macros/generic/expkv/README.md
+++ /dev/null
@@ -1,35 +0,0 @@
--------------------------------------------------------------------------------
-# expkv -- an expandable key=val implementation
-
-Version 2021-09-20 v1.9a
-
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
-
-Hosted at https://github.com/Skillmon/tex_expkv
-
--------------------------------------------------------------------------------
-
-Copyright (C) 2020-2021 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.
-
--------------------------------------------------------------------------------
-
-This provides an expandable key=val implementation that is somewhat fast, but
-not the fastest key=val implementation available. It is generic code and
-completely self-contained. There is a LaTeX package `expkv.sty` included to play
-nice on LaTeX's package loading system, but that package is not needed and does
-not provide more functionality than the generic code in `expkv.tex`.
-
-A key-defining interface that is not as rudimentary as the macros provided in
-this package is contained in expkv-def:
-https://github.com/Skillmon/tex_expkv-def
diff --git a/obsolete/macros/generic/expkv/expkv.dtx b/obsolete/macros/generic/expkv/expkv.dtx
deleted file mode 100644
index 8651ad97a3..0000000000
--- a/obsolete/macros/generic/expkv/expkv.dtx
+++ /dev/null
@@ -1,2980 +0,0 @@
-% \iffalse meta-comment
-%
-% File: expkv.dtx Copyright (C) 2020-2021 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
-%
-% ------------------------------------------------------------------------------
-%
-%<*driver>^^A>>=
-\def\nameofplainTeX{plain}
-\ifx\fmtname\nameofplainTeX\else
- \expandafter\begingroup
-\fi
-\input l3docstrip.tex
-\askforoverwritefalse
-\preamble
-
---------------------------------------------------------------
-expkv -- an expandable key=val implementation
-E-mail: jspratte@yahoo.de
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
---------------------------------------------------------------
-
-Copyright (C) 2020-2021 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.
-
-This work consists of the file expkv.dtx
-and the derived files expkv.pdf
- expkv.sty
- expkv.tex
- t-expkv.tex
-
-\endpreamble
-% stop docstrip adding \endinput
-\postamble
-\endpostamble
-\generate{\file{expkv.sty}{\from{expkv.dtx}{pkg}}}
-\generate{\file{expkv.tex}{\from{expkv.dtx}{tex}}}
-\generate{\file{t-expkv.tex}{\from{expkv.dtx}{ctx}}}
-\ifx\fmtname\nameofplainTeX
- \expandafter\endbatchfile
-\else
- \expandafter\endgroup
-\fi
-%
-\IfFileExists{expkv.tex}{\input{expkv.tex}}{}
-\ProvidesFile{expkv.dtx}
- [\csname ekvDate\endcsname\ an expandable key=val implementation]
-\PassOptionsToPackage{full}{textcomp}
-\documentclass{l3doc}
-\RequirePackage[oldstylenums,nott]{kpfonts}
-\input{glyphtounicode}
-\pdfgentounicode=1
-\RequirePackage{xfp} ^^A required for an example
-\RequirePackage{listings}
-\RequirePackage{booktabs}
-\RequirePackage{array}
-\RequirePackage{collcell}
-\RequirePackage{siunitx}
-\DeclareSIUnit\ops{ops}
-\RequirePackage{xcolor}
-\RequirePackage{caption}
-\RequirePackage{microtype}
-\RequirePackage{accsupp}
-\RequirePackage{enumitem}
-\RequirePackage{tcolorbox}
-\newtcolorbox{exresult}[2][]
- {colback=expkvgrey!10!white,colframe=expkvgrey,fontupper=\small,width={#2},#1}
-\newtcbox\exres[1][]
- {
- colback=expkvgrey!10!white
- ,colframe=expkvgrey
- ,size=small
- ,nobeforeafter
- ,tcbox raise base
- ,fontupper=\small
- ,#1
- }
-\def\mylstwd{.55em}
-\lstdefinelanguage{expkv}[primitive]{TeX}
- {
- ,moretexcs=[4]^^A e-TeX
- {
- expanded,
- numexpr,
- protected,
- }
- ,moretexcs=[5]^^A plain/LaTeX/ConTeXt
- {
- approx,
- begin,
- empty,
- item,
- LaTeX,
- makeatletter,makeatother,
- newcommand,newdimen,
- RequirePackage,
- rule,
- TeX,
- textit,texttt,
- usepackage,
- usemodule,
- }
- ,moretexcs=[6]^^A used packages
- {
- ^^A xfp
- fpeval,
- ^^A keyval
- setkeys,
- ^^A yax
- defactiveparameter,storevalue,setparameterlist
- }
- ,moretexcs=[2]^^A expkv macros
- {
- ekvdef,ekvdefNoVal,^^A
- ekvlet,ekvletNoVal,ekvletkv,ekvletkvNoVal,^^A
- ekvdefunknown,ekvdefunknownNoVal,^^A
- ekvredirectunknown,ekvredirectunknownNoVal,^^A
- ekvset,ekvsetSneaked,^^A
- ekvsetdef,ekvsetSneakeddef,ekvsetdefSneaked,^^A
- ekvparse,^^A
- ekvVersion,ekvDate,^^A
- ekvifdefined,ekvifdefinedNoVal,ekvifdefinedset,^^A
- ekvbreak,ekvbreakPreSneak,ekvbreakPostSneak,^^A
- ekvsneak,ekvsneakPre,^^A
- ekvchangeset,^^A
- ekvoptarg,ekvoptargTF,^^A
- ekverr
- }
- ,moretexcs=[3]^^A expkv-pkg macros
- {
- ^^A expkv-cs
- ekvcSecondaryKeys,ekvcSplitAndForward,
- ^^A expkv-def
- ekvdefinekeys
- }
- }
-\colorlet{codeparam}{cyan!65!black}
-\lstset
- {
- ,language=expkv
- ,flexiblecolumns=false
- ,basewidth=\mylstwd
- ,gobble=2
- ,basicstyle=\fontfamily{jkp}\itshape
- ,texcsstyle=*[1]{\bfseries\color{expkvgrey}} ^^A primitives
- ,texcsstyle=*[2]{\bfseries\color{expkvred}} ^^A expkv
- ,texcsstyle=*[3]{\color{expkvred}} ^^A expkv-pkg
- ,texcsstyle=*[4]{\bfseries\color{expkvgrey}} ^^A e-TeX
- ,texcsstyle=*[5]{\bfseries\color{expkvgrey}} ^^A plain/LaTeX macros
- ,texcsstyle=*[6]{} ^^A macros of other packages
- ,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}
- ^^A,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}}}
-\RequirePackage{randtext}
-\let\metaORIG\meta
-\protected\def\meta #1{\texttt{\metaORIG{#1}}}
-\renewcommand*\thefootnote{\fnsymbol{footnote}}
-\definecolor{expkvred}{HTML}{9F393D}
-\colorlet{expkvgrey}{black!75}
-\makeatletter
-\newcommand*\example{\par\smallskip\noindent\textit{Example:} \ignorespaces}
-\newcommand*\expFormat
- {^^A
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex\hbox{{\color{expkvgrey}P}}^^A
- }^^A
- }
-\newcommand*\kvstyle
- {^^A
- \normalfont\rmfamily\bfseries\color{expkvred}^^A
- }
-\newcommand*\expkv
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv}^^A
- \href{https://github.com/Skillmon/tex_expkv}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv}^^A
- }
-\newcommand*\expkvpkg[1]
- {^^A
- \texorpdfstring
- {^^A
- \mbox
- {^^A
- \BeginAccSupp{ActualText=expkv-#1}^^A
- \href{https://github.com/Skillmon/tex_expkv-#1}
- {^^A
- \rmfamily
- \bfseries
- {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
- \lower.493ex
- \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
- \kern-.18em{\color{expkvred}v}^^A
- {\color{expkvgrey}^^A
- \kern.05em\rule[-.1ex]{.08em}{1.2ex}\kern.05em\textsc{#1}^^A
- }^^A
- }^^A
- \EndAccSupp{}^^A
- }^^A
- }
- {expkv-#1}^^A
- }
-\newcommand*\expkvd{\expkvpkg{def}}
-\newcommand*\expkvc{\expkvpkg{cs}}
-\newcommand*\expkvo{\expkvpkg{opt}}
-\ExplSyntaxOn
-\newcommand*\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
-\newcommand\kv{\meta{key}=\meta{value}}
-\newcommand\key{\meta{key}}
-\newcommand\val{\meta{value}}
-\newcommand\set{\meta{set}}
-\hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
-\DoNotIndex{\directlua}
-\DoNotIndex{\def,\edef,\,,\=,\begingroup,\catcode,\chardef,\csname,\endcsname}
-\DoNotIndex{\endgroup,\endinput,\errmessage,\expandafter,\input,\let,\long}
-\DoNotIndex{\protected,\ProvidesFile,\ProvidesPackage,\relax,\space}
-\DoNotIndex{\^,\@,\unexpanded,\string,\expanded,\detokenize,\meaning}
-\DoNotIndex{\lastnamedcs,\romannumeral,\z@}
-\DoNotIndex{\noexpand,\normalexpanded,\normalunexpanded}
-\DoNotIndex{\par,\protect}
-\DoNotIndex{\unprotect}
-\DoNotIndex{\writestatus}
-\DoNotIndex{\ifcsname}
-\DoNotIndex{\ifx}
-\DoNotIndex{\iffalse}
-\DoNotIndex{\ifnum}
-\DoNotIndex{\else}
-\DoNotIndex{\fi}
-\@gobble\fi ^^A ignoring \ifx etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx etc., but only one \fi
-\@gobble\fi ^^A ignoring \ifx etc., but only one \fi
-\@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
-\newcommand*\pmso[1] ^^A poor man's strike out
- {^^A
- \leavevmode
- \begingroup
- \sbox0{#1}^^A
- \rlap{\vrule height .6ex depth -.5ex width \wd0\relax}^^A
- \usebox0\relax
- \endgroup
- }
-\makeatother
-\begin{document}
- \title
- {^^A
- \texorpdfstring
- {^^A
- \huge\expkv
- \\[\medskipamount]
- \Large an {\expFormat}andable
- \meta{{\kvstyle k}\kern-.05em ey}=^^A
- \meta{{\kvstyle v}\kern-.05em alue}
- implementation^^A
- }{expkv - an expandable <key>=<value> implementation}^^A
- }
- \date{\ekvDate\space v\ekvVersion}
- \author{Jonathan P. Spratte\thanks{\protect\randomize{jspratte@yahoo.de}}}
- \DocInput{expkv.dtx}
-\end{document}
-%</driver>^^A=<<
-% \fi
-%
-% \maketitle
-% \renewcommand*\thefootnote{\arabic{footnote}}
-%
-% \begin{abstract}
-% \noindent\parfillskip=0pt
-% \expkv\ provides a small interface for \kv\ parsing. The parsing macro is
-% \emph{fully expandable}, the \meta{code} of your keys might be not. \expkv\ is
-% \emph{swift}, close to the fastest \kv\ implementation. However it is the
-% fastest which copes with active commas and equal signs and doesn't strip
-% braces accidentally.
-% \end{abstract}
-%
-% \tableofcontents
-%
-% \begin{documentation}^^A>>=
-%
-% \section{Documentation}
-%
-% \expkv\ provides an expandable \kv\ parser. The \kv\ pairs should be given as
-% a comma separated list and the separator between a \key\ and the associated
-% \val\ should be an equal sign. Both, the commas and the equal signs, might be
-% of category 12 (other) or 13 (active). To support this is necessary as for
-% example \pkg{babel} turns characters active for some languages, for instance
-% the equal sign is turned active for Turkish.
-%
-% \expkv\ is usable as generic code, as a \LaTeX\ package or as a \ConTeXt\
-% module. To use it, just use one of:
-% \begin{lstlisting}
-% \input expkv % plainTeX
-% \usepackage{expkv} % LaTeX
-% \usemodule[expkv] % ConTeXt
-% \end{lstlisting}
-% Both the \LaTeX\ package and the \ConTeXt\ module don't do more than
-% \file{expkv.tex}, except calling |\ProvidesPackage| and setting things up such
-% that \file{expkv.tex} will use |\ProvidesFile|, or printing some status
-% information. The \ConTeXt\ support is not thoroughly tested, though (since I
-% don't use \ConTeXt\ myself I don't know if there are additional pitfalls I
-% wasn't aware of).
-%
-% In the \expkv\ family are other packages contained which provide additional
-% functionality. Those packages currently are:
-% \begin{description}[format=\expkvpkg]
-% \item[def]
-% a key-defining frontend for \expkv\ using a \kv\ syntax
-% \item[cs]
-% define expandable \kv\ macros using \expkv
-% \item[opt]
-% parse package and class options with \expkv
-% \end{description}
-% Note that while the package names are stylised with a vertical rule, their
-% names are all lower case with a hyphen (\emph{e.g.}, \file{expkv-def}).
-%
-% A list of concise comparisons to other \kv\ packages is contained in
-% \autoref{sec:cmp}.
-%
-% \subsection{Setting up Keys}\label{sec:define}
-% \expkv\ provides a rather simple approach to setting up keys, similar to
-% \pkg{keyval}. However there is an auxiliary package named \expkvd\ which
-% provides a more sophisticated interface, similar to well established packages
-% like \pkg{pgfkeys} or \pkg{l3keys}.
-%
-% Keys in \expkv\ (as in almost all other \kv\ implementations) belong to a
-% \emph{set} such 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 values and keys that don't (the latter
-% are called |NoVal| keys by \expkv), but both can have the same name (on the
-% user level).
-%
-% The following macros are available to define new keys. Those macros containing
-% ``|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),
-% prefixes allowed for |\let| can prefix those with ``|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 \key\ taking a value in a \set\ to expand to \meta{code}. In
-% \meta{code} you can use |#1| to refer to the given value.
-% \end{function}
-% \example Define |text| in |foo| to store the value inside |\foo@text|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \protected\long\ekvdef{foo}{text}{\def\foo@text{#1}}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvdefNoVal}
-% \begin{syntax}
-% \cs{ekvdefNoVal}\marg{set}\marg{key}\marg{code}
-% \end{syntax}
-% Defines a no value taking \key\ in a \set\ to expand to \meta{code}.
-% \end{function}
-% \example Define |bool| in |foo| to set |\iffoo@bool| to |true|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \protected\ekvdefNoVal{foo}{bool}{\foo@booltrue}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvlet}
-% \begin{syntax}
-% \cs{ekvlet}\marg{set}\marg{key}\meta{cs}
-% \end{syntax}
-% Let the value taking \key\ in \set\ to \meta{cs}, there are no checks on
-% \meta{cs} enforced, but the code should expect the value as a single braced
-% argument directly following it.
-% \end{function}
-% \example Let |cmd| in |foo| do the same as |\foo@cmd|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvlet{foo}{cmd}\foo@cmd
-% \end{lstlisting}
-%
-% \begin{function}{\ekvletNoVal}
-% \begin{syntax}
-% \cs{ekvletNoVal}\marg{set}\marg{key}\meta{cs}
-% \end{syntax}
-% Let the no value taking \key\ in \set\ to \meta{cs}, it is not checked
-% whether \meta{cs} exists or that it takes no parameter.
-% \end{function}
-% \example See above.
-%
-% \begin{function}{\ekvletkv}
-% \begin{syntax}
-% \cs{ekvletkv}\marg{set}\marg{key}\marg{set2}\marg{key2}
-% \end{syntax}
-% Let the \key\ in \set\ to \meta{key2} in \meta{set2}, it is not checked
-% whether that second key exists (but take a look at
-% \cs[no-index]{ekvifdefined}).
-% \end{function}
-% \example Let |B| in |bar| be an alias for |A| in |foo|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvletkv{bar}{B}{foo}{A}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvletkvNoVal}
-% \begin{syntax}
-% \cs{ekvletkvNoVal}\marg{set}\marg{key}\marg{set2}\marg{key2}
-% \end{syntax}
-% Let the \key\ in \set\ to \meta{key2} in \meta{set2}, it is not checked
-% whether that second key exists (but take a look at
-% \cs[no-index]{ekvifdefinedNoVal}).
-% \end{function}
-% \example See above.
-%
-% \begin{function}{\ekvdefunknown}
-% \begin{syntax}
-% \cs{ekvdefunknown}\marg{set}\marg{code}
-% \end{syntax}
-% By default an error will be thrown if an unknown \key\ is encountered. With
-% this macro you can define \meta{code} that will be executed for a given
-% \set\ when an unknown \key\ with a \val\ was encountered instead of throwing
-% an error. You can refer to the given \val\ with |#1| and to the unknown
-% \key's name with |#2| in \meta{code}.\footnotemark{}
-% |\ekvdefunknown| and |\ekvredirectunknown| are mutually exclusive,
-% you can't use both.
-% \end{function}
-% \footnotetext{That order is correct, this way the code is faster.}
-% \example Also search |bar| for undefined keys of set |foo|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \long\ekvdefunknown{foo}{\ekvset{bar}{#2={#1}}}
-% \end{lstlisting}
-% 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
-% |\ekvredirectunknown|.
-%
-% \begin{function}{\ekvdefunknownNoVal}
-% \begin{syntax}
-% \cs{ekvdefunknownNoVal}\marg{set}\marg{code}
-% \end{syntax}
-% As already explained for \cs[no-index]{ekvdefunknown}, \expkv\ would throw
-% an error when encountering an unknown \key. With this you can instead let it
-% execute \meta{code} if an unknown |NoVal| \key\ was encountered. You can
-% refer to the given \key\ with |#1| in \meta{code}.
-% |\ekvdefunknownNoVal| and |\ekvredirectunknownNoVal| are mutually exclusive,
-% you can't use both.
-% \end{function}
-% \example Also search |bar| for undefined keys of set |foo|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvdefunknownNoVal{foo}{\ekvset{bar}{#1}}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvredirectunknown}
-% \begin{syntax}
-% \cs{ekvredirectunknown}\marg{set}\marg{set-list}
-% \end{syntax}
-% This is a short cut to set up a special |\ekvdefunknown| for \set\ that will
-% check each set in the comma separated \meta{set-list} for the unknown \key.
-% You can't use prefixes (so no |\long| or |\protected|) with this macro, the
-% resulting unknown-key handler will always be |\long|. The first set in the
-% \meta{set-list} has highest priority. Once the \key\ is found the remaining
-% sets are discarded, if the \key\ isn't found in any set an error will be
-% thrown eventually. Note that the error messages are affected by the use of
-% this macro, in particular, it isn't checked whether a |NoVal| key of the
-% same name is defined in order to throw an |unwanted value| error.
-% |\ekvdefunknown| and |\ekvredirectunknown| are mutually exclusive,
-% you can't use both.
-% \end{function}
-% \example For every key not defined in the set |foo| also search the sets |bar|
-% and |baz|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvredirectunknown{foo}{bar, baz}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvredirectunknownNoVal}
-% \begin{syntax}
-% \cs{ekvredirectunknownNoVal}\marg{set}\marg{set-list}
-% \end{syntax}
-% This behaves just like |\ekvredirectunknown| and does the same but for the
-% |NoVal| keys. Again no prefixes are supported. Note that the error messages
-% are affected by the use of this macro, in particular, it isn't checked
-% whether a normal key of the same name is defined in order to throw a
-% |missing value| error.
-% |\ekvdefunknownNoVal| and |\ekvredirectunknownNoVal| are mutually exclusive,
-% you can't use both.
-% \end{function}
-% \example See above.
-%
-% \subsection{Parsing Keys}
-%
-% \begin{function}{\ekvset}
-% \begin{syntax}
-% \cs{ekvset}\marg{set}\{\kv,\ldots\}
-% \end{syntax}
-% Splits \kv\ pairs on commas. From both \key\ and \val\ up to one space is
-% stripped from both ends, if then only a braced group remains the braces are
-% stripped as well. So |\ekvset{foo}{bar=baz}| and
-% |\ekvset{foo}{ {bar}= {baz} }| will both do
-% \texttt{\cs[no-index]{\meta{foobarcode}}\{baz\}}, so you can hide commas,
-% equal signs and spaces at the ends of either \key\ or \val\ by putting
-% braces around them. If you omit the equal sign the code of the key created
-% with the |NoVal| variants described in \autoref{sec:define} will be
-% executed. If \kv\ contains more than a single unhidden equal sign, it will
-% be split at the first one and the others are considered part of the value.
-% |\ekvset| should be nestable.
-%
-% |\ekvset| is currently \emph{not} alignment safe.\footnotemark\ As a result,
-% key names and values that contain an |&| must be wrapped in braces when
-% |\ekvset| is used inside an alignment (like \LaTeXe's |tabular| environment)
-% or you have to create a wrapper that ensures an alignment safe context.
-% \end{function}
-% \footnotetext{This might change in the future, I've not decided yet.}
-% \example Parse |key=arg, key| in the set |foo|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvset{foo}{key=arg, key}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvsetSneaked}
-% \begin{syntax}
-% \cs{ekvsetSneaked}\marg{set}\marg{sneak}\{\kv,\ldots\}
-% \end{syntax}
-% Just like \cs[no-index]{ekvset}, this macro parses the \kv\ pairs within the
-% given \set. But \cs[no-index]{ekvsetSneaked} will behave as if
-% \cs[no-index]{ekvsneak} has been called with \meta{sneak} as its argument as
-% the first action.
-% \end{function}
-% \example Parse |key=arg, key| in the set |foo| with |\afterwards| sneaked out:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvsetSneaked{foo}{\afterwards}{key=arg, key}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvsetdef}
-% \begin{syntax}
-% \cs{ekvsetdef}\meta{cs}\marg{set}
-% \end{syntax}
-% With this function you can define a shorthand macro \meta{cs} to parse keys
-% of a specified \set. It is always defined |\long|, but if you need to you
-% can also prefix it with |\global|. The resulting macro is faster than but
-% else equivalent to the idiomatic definition:\par
-% \texttt
-% {\string\long\string\def\meta{cs}\#1\{\string\ekvset\marg{set}\{\#1\}\}}
-% \end{function}
-% \example Define the macro |\foosetup| to parse keys in the set |foo| and use
-% it to parse |key=arg, key|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvsetdef\foosetup{foo}
-% \foosetup{key=arg, key}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvsetSneakeddef}
-% \begin{syntax}
-% \cs{ekvsetSneakeddef}\meta{cs}\marg{set}
-% \end{syntax}
-% Just like \cs[no-index]{ekvsetdef} this defines a shorthand macro \meta{cs},
-% but this macro will make it a shorthand for \cs[no-index]{ekvsetSneaked},
-% meaning that \meta{cs} will take two arguments, the first being stuff that
-% should be given to \cs[no-index]{ekvsneak} and the second the \kv\ list. The
-% resulting macro is faster than but else equivalent to the idiomatic
-% definition:\par
-% \texttt
-% {%
-% \string\long\string\def\meta{cs}\#1\#2\{^^A
-% \string\ekvsetSneaked\marg{set}\{\#1\}\{\#2\}\}^^A
-% }
-% \end{function}
-% \example 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{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvsetSneakeddef\foothings{foo}
-% \foothings{\afterwards}{key=arg, key}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvsetdefSneaked}
-% \begin{syntax}
-% \cs{ekvsetdefSneaked}\meta{cs}\marg{set}\marg{sneaked}
-% \end{syntax}
-% And this one behaves like \cs[no-index]{ekvsetSneakeddef} but with a fixed
-% \meta{sneaked} argument. So the resulting macro is faster than but else
-% equivalent to the idiomatic definition:\par
-% \texttt
-% {%
-% \string\long\string\def\meta{cs}\#1\{^^A
-% \string\ekvsetSneaked\marg{set}\marg{sneaked}\{\#1\}\}^^A
-% }
-% \end{function}
-% \example 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{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvsetdefSneaked\barthing{bar}{\afterwards}
-% \barthing{key=arg, key}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvparse}
-% \begin{syntax}
-% \cs{ekvparse}\marg{code1}\marg{code2}\{\kv,\ldots\}
-% \end{syntax}
-% This macro parses the \kv\ pairs and provides those list elements which are
-% only keys as an argument to \meta{code1}, and those which are a \kv\ pair
-% to \meta{code2} as two arguments. It is fully expandable as well and returns
-% each element of the parsed list in |\unexpanded|, which has no effect
-% outside of an |\expanded| or |\edef| context.
-% Also |\ekvparse| expands in exactly two steps of expansion.
-% You can use multiple tokens in \meta{code1} and \meta{code2} or just a
-% single control sequence name. In both cases the found \key\ and \val\ are
-% provided as a brace group following them.
-%
-% |\ekvparse| is alignment safe, meaning that you don't have to take any
-% precautions if it is used inside an alignment context (like \LaTeXe's
-% |tabular| environment) and any key or value can contain an |&|.
-%
-% |\ekvbreak|, |\ekvsneak|, and |\ekvchangeset| and their relatives don't work
-% in |\ekvparse|. It is analogue to \pkg{expl3}'s |\keyval_parse:NNn|, but
-% not with the same parsing rules -- |\keyval_parse:NNn| throws an error on
-% multiple equal signs per \kv\ pair and on empty \key\ names in a \kv\ pair,
-% both of which |\ekvparse| doesn't deal with.
-% \end{function}
-% \example
-% \begin{lstlisting}
-% \ekvparse{\handlekey{S}}{\handlekeyval{S}}{foo = bar, key, baz={zzz}}
-% \end{lstlisting}
-% would be equivalent to
-% \begin{lstlisting}
-% \handlekeyval{S}{foo}{bar}\handlekey{S}{key}\handlekeyval{S}{baz}{zzz}
-% \end{lstlisting}
-% and afterwards |\handlekey| and |\handlekeyval| would have to further handle
-% the \key. There are no macros like these two contained in \expkv, you have
-% to set them up yourself if you want to use |\ekvparse| (of course the names
-% might differ). If you need the results of |\ekvparse| as the argument for
-% another macro, you should use |\expanded|, or expand |\ekvparse| twice, as
-% only then the input stream will contain the output above:
-% \begin{lstlisting}
-% \expandafter\parse\expanded{\ekvparse\k\kv{foo = bar, key, baz={zzz}}}
-% \end{lstlisting}
-% or
-% \begin{lstlisting}
-% \expandafter\expandafter\expandafter
-% \parse\ekvparse\k\kv{foo = bar, key, baz={zzz}}
-% \end{lstlisting}
-% would both expand to
-% \begin{lstlisting}
-% \parse\kv{foo}{bar}\k{key}\kv{baz}{zzz}
-% \end{lstlisting}
-%
-% \subsection{Other Macros}
-%
-% \expkv\ provides some other macros which might be of interest.
-%
-% \begin{function}{\ekvVersion,\ekvDate}
-% These two macros store the version and date of the package.
-% \end{function}
-%
-% \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}
-% \example Check whether the key |special| is already defined in set |foo|, if
-% it isn't input a file that contains more key definitions:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvifdefined{foo}{special}{}{\input{foo.morekeys.tex}}
-% \end{lstlisting}
-%
-% \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}
-% \example Check whether the set |VeRyUnLiKeLy| is already defined, if so throw
-% an error, else do nothing:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvifdefinedset{VeRyUnLiKeLy}
-% {\errmessage{VeRyUnLiKeLy already defined}}{}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvbreak,\ekvbreakPreSneak,\ekvbreakPostSneak}
-% \begin{syntax}
-% \cs{ekvbreak}\marg{after}
-% \end{syntax}
-% Gobbles the remainder of the current |\ekvset| macro and its argument list
-% and reinserts \meta{after}. So this can be used to break out of |\ekvset|.
-% The first variant will also gobble anything that has been sneaked out using
-% |\ekvsneak| or |\ekvsneakPre|, while |\ekvbreakPreSneak| will put
-% \meta{after} before anything that has been smuggled and |\ekvbreakPostSneak|
-% will put \meta{after} after the stuff that has been sneaked out.
-% \end{function}
-% \example 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{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvdefNoVal{foo}{abort}{\ekvbreak{\foo@aborted}}
-% \ekvdef{foo}{abort}{\ekvbreak{\foo@aborted@with{#1}}}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvsneak,\ekvsneakPre}
-% \begin{syntax}
-% \cs{ekvsneak}\marg{after}
-% \end{syntax}
-% Puts \meta{after} after the effects of |\ekvset|. The first variant will put
-% \meta{after} after any other tokens which might have been sneaked before,
-% while |\ekvsneakPre| will put \meta{after} before other smuggled stuff.
-% This reads and reinserts the remainder of the current |\ekvset| macro and
-% its argument list to do its job. After |\ekvset| has parsed the entire \kv\
-% list everything that has been |\ekvsneak|ed will be left in the input
-% stream. A small usage example is shown in \autoref{sec:sneakex}.
-% \end{function}
-% \example Define a key |secret| in the set |foo| that will sneak out
-% |\foo@secretly@sneaked|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvdefNoVal{foo}{secret}{\ekvsneak{\foo@secretly@sneaked}}
-% \end{lstlisting}
-%
-% \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
-% |\ekvset| call, that call behaves as if it was called with
-% \texttt{\cs[no-index]{ekvset}\marg{new-set}}. It is comparable to using
-% \texttt{\meta{key}/.cd} in \pkg{pgfkeys}.
-% \end{function}
-% \example Define a key |cd| in set |foo| that will change to another set as
-% specified in the value, if the set is undefined it'll stop the parsing and
-% throw an error as defined in the macro |\foo@cd@error|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \ekvdef{foo}{cd}
-% {\ekvifdefinedset{#1}{\ekvchangeset{#1}}{\ekvbreak{\foo@cd@error}}}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvoptarg}
-% \begin{syntax}
-% \cs{ekvoptarg}\marg{next}\marg{default}
-% \end{syntax}
-% This macro will check for a following optional argument in brackets (|[]|)
-% expandably. After the optional argument there has to be a mandatory one. The
-% code in \meta{next} should expect two arguments (the processed optional
-% argument and the mandatory one). 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 being read once -- if
-% it was already wrapped it is effectively unchanged).
-% \end{function}
-% |\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, the optional argument has to use nested
-% braces like so: |[{arg]ument}]|.
-% \example Say we have a macro that should take an optional argument defaulting
-% to 1:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \newcommand\foo{\ekvoptarg\@foo{1}}
-% \newcommand\@foo[2]{Mandatory: #2\par Optional: #1}
-% \end{lstlisting}
-%
-% \begin{function}{\ekvoptargTF}
-% \begin{syntax}
-% \cs{ekvoptargTF}\marg{true}\marg{false}
-% \end{syntax}
-% This macro is similar to |\ekvoptarg|, but will result in
-% \meta{true}\marg{optional}\meta{mandatory} or \meta{false}\marg{mandatory}
-% instead of placing a default value.
-% \end{function}
-% |\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 |\ekvoptarg|.
-% \example Say we have a macro that should behave differently depending on
-% whether there was an optional argument or not. This could be done with:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \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.}
-% \end{lstlisting}
-%
-% \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
-% \texttt
-% {^^A
-% \cs[no-index]{unexpanded}\hskip0pt
-% \{\hskip0pt
-% \meta{code}\hskip0pt
-% \marg{item}\hskip0pt
-% \}^^A
-% }
-% for each list item in the input stream. Blank elements are ignored (if you
-% need a blank element it should be given as |{}|). It supports both active
-% commas and commas of category other. You could consider it as a watered down
-% version of |\ekvparse|. However it is not alignment safe, which you could
-% achieve by nesting it in |\expanded| (since the braces around the argument
-% of |\expanded| will hide |&|s from \TeX's alignment parsing).
-% \end{function}
-% \example The following splits a comma separated list and prints it in a
-% typewriter font with parentheses around each element.\\
-% \begin{minipage}{.75\linewidth}
-% \begin{lstlisting}
-% \newcommand*\myprocessor[1]{\texttt{(#1)}}
-% \ekvcsvloop\myprocessor{abc,def,ghi}\par
-% \ekvcsvloop\myprocessor{1,,2,,3,,4}\par
-% \end{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \newcommand*\myprocessor[1]{\texttt{(#1)}}
-% \ekvcsvloop\myprocessor{abc,def,ghi}\par
-% \ekvcsvloop\myprocessor{1,,2,,3,,4}\par
-% \end{exresult}
-%
-% \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 for \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 plain \TeX\ 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.
-% \example Say we set up a small calculation which works with user input. In our
-% calculation we need a division, so have to watch out for division by zero. If
-% we detect such a case we throw an error and do the recovery by using the
-% biggest integer allowed in \TeX\ as the result.
-% \begin{lstlisting}
-% \newcommand*\mydivision[2]
-% {%
-% \the\numexpr
-% \ifnum\numexpr#2=0 % space here on purpose
-% \ekverr{my}{division by 0. Setting result to 2147483647.}%
-% 2147483647%
-% \else
-% (#1)/(#2)%
-% \fi
-% \relax
-% }
-% $(10+5)/(3-3)\approx\mydivision{10+5}{3-3}$
-% \end{lstlisting}
-% If that code gets executed the following will be the terminal output
-% \begin{verbatim}
-% Runaway argument?
-% ! my Error: division by 0. Setting result to 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.15 $(10+5)/(3-3)\approx\mydivision{10+5}{3-3}
-% $
-% ?
-% \end{verbatim}
-% and the output would contain
-% \exres{$(10+5)/(3-3)\approx2147483647$}
-% if we continued the \TeX\ run at the prompt.
-%
-% \bigskip
-%
-% \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 that correspond to a key in a set are build with
-% these macros. The name is built from two blocks, one that is formatting the
-% \set\ name (|\ekv@name@set|) and one for formatting the \key\ name
-% (|\ekv@name@key|). To get the actual name the argument to |\ekv@name@key|
-% must be |\detokenize|d. Both blocks are put together (with the necessary
-% |\detokenize|) by |\ekv@name|.
-% For |NoVal| keys an additional |N| gets appended irrespective of these
-% macros' definition, so their name is
-% \texttt{\cs[no-index]{ekv@name}\marg{set}\marg{key}N}.\par
-% 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}
-% \example Execute the callback of the |NoVal| key |key| in set |foo|:
-% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \csname\ekv@name{foo}{key}N\endcsname
-% \end{lstlisting}
-%
-% \subsection{Examples}
-%
-% \subsubsection{Standard Use-Case}
-%
-% Say we have a macro for which we want to create a \kv\ interface. The macro
-% has a parameter, which is stored in the dimension |\ourdim| having a default
-% value from its initialisation. Now we want to be able to change that dimension
-% with the |width| key to some specified value. For that we'd do
-% \begin{lstlisting}
-% \newdimen\ourdim
-% \ourdim=150pt
-% \protected\ekvdef{our}{width}{\ourdim=#1\relax}
-% \end{lstlisting}
-% as you can see, we use the set |our| here. We want the key to behave different
-% if no value is specified. In that case the key should not use its initial
-% value, but be smart and determine the available space from
-% \cs[no-index]{hsize}, so we also define
-% \begin{lstlisting}
-% \protected\ekvdefNoVal{our}{width}{\ourdim=.9\hsize}
-% \end{lstlisting}
-% Now we set up our macro to use this \kv\ interface
-% \begin{lstlisting}
-% \protected\def\ourmacro#1%
-% {\begingroup\ekvset{our}{#1}\the\ourdim\endgroup}
-% \end{lstlisting}
-% Finally we can use our macro like in the following\\
-% \begin{minipage}{.5\linewidth}
-% \begin{lstlisting}
-% \ourmacro{}\par
-% \ourmacro{width}\par
-% \ourmacro{width=5pt}\par
-% \end{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.5\linewidth}
-% \newdimen\ourdim\ourdim=150pt
-% \protected\ekvdef{our}{width}{\ourdim=#1\relax}^^A
-% \protected\ekvdefNoVal{our}{width}{\ourdim=.9\hsize}^^A
-% \protected\def\ourmacro#1^^A
-% {\begingroup\ekvset{our}{#1}\the\ourdim\endgroup}^^A
-% \ourmacro{}\par
-% \ourmacro{width}\par
-% \ourmacro{width=5pt}\par
-% \end{exresult}
-%
-% \paragraph{The same keys using \protect\expkvd}
-% Using \expkvd\ we can set up the equivalent key using a \kv\ interface, after
-% the following we could use |\ourmacro| in the same way as above. \expkvd\ will
-% allocate and initialise |\ourdim| and define the |width| key |\protected| for
-% us, so the result will be exactly the same -- with the exception that the
-% default will use |\ourdim=.9\hsize\relax| instead.
-% \begin{lstlisting}
-% \input expkv-def % or \usepackage{expkv-def}
-% \ekvdefinekeys{our}
-% {
-% dimen width = \ourdim,
-% qdefault width = .9\hsize,
-% initial width = 150pt
-% }
-% \end{lstlisting}
-%
-% \subsubsection{A Macro to Draw Rules}
-%
-% Another small example could be a \kv\ driven |\rule| alternative, because I
-% keep forgetting the correct order of its arguments. First we define the keys
-% (and initialize the macros used to store the keys):
-% \begin{lstlisting}
-% \makeatletter
-% \newcommand*\myrule@ht{1ex}
-% \newcommand*\myrule@wd{0.1em}
-% \newcommand*\myrule@raise{\z@}
-% \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{lstlisting}
-% Then we define a macro to change the defaults outside of |\myrule| and
-% |\myrule| itself:
-% \begin{lstlisting}
-% \ekvsetdef\myruleset{myrule}
-% \newcommand*\myrule[1][]
-% {\begingroup\myruleset{#1}\myrule@out\endgroup}
-% \end{lstlisting}
-% And finally the output:
-% \begin{lstlisting}
-% \newcommand*\myrule@out{\rule[\myrule@raise]\myrule@wd\myrule@ht}
-% \makeatother
-% \end{lstlisting}
-% And we can use it:\\
-% \begin{minipage}{.5\linewidth}
-% \begin{lstlisting}
-% a\myrule\par
-% a\myrule[ht=2ex,lower=.5ex]\par
-% \myruleset{wd=5pt}
-% a\myrule
-% \end{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.5\linewidth}
-% \makeatletter
-% \newcommand*\myrule@ht{1ex}
-% \newcommand*\myrule@wd{0.1em}
-% \newcommand*\myrule@raise{\z@}
-% \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}}
-% \ekvsetdef\myruleset{myrule}
-% \newcommand*\myrule[1][]{\begingroup\myruleset{#1}\myrule@out\endgroup}
-% \newcommand*\myrule@out{\rule[\myrule@raise]\myrule@wd\myrule@ht}
-% \makeatother
-% a\myrule\par
-% a\myrule[ht=2ex,lower=.5ex]\par
-% \myruleset{wd=5pt}
-% a\myrule
-% \end{exresult}
-%
-%
-% \subsubsection{An Expandable \kv\ Macro Using \cs[no-index]{ekvsneak}}
-% \label{sec:sneakex}
-%
-% 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,
-% |\ekvset| or |\ekvparse|. For this example we also want to show the
-% usage of |\ekvsneak|, hence we'll choose |\ekvset|. And we'll have to use
-% |\ekvset| such that it builds a parsable list for our macro internals. To
-% gain back control after |\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
-% |\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 the following will use |\ekvsneakPre| for the
-% user-level keys. If we wanted some key for which the first usage should be the
-% binding one we would use |\ekvsneak| instead for that key.
-%
-% 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 the parsing list terminator.
-%
-% Ordering the keys can be done simply by searching for a specific token for
-% each argument which acts like a flag, so our sneaked out values will include
-% specific tokens acting as markers.
-%
-% Now that we have answers for our technical problems, we have to decide what
-% our example macro should do. How about we define a macro that calculates the
-% sine of a number and rounds that to a specified precision? As a small extra
-% this macro should understand input in radian and degree and the used
-% trigonometric function should be selectable as well. For the hard part of this
-% task (expandably evaluating trigonometric functions) we'll use the \pkg{xfp}
-% package.
-%
-% 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 defaults
-% right before it. The user macro |\sine| uses |\ekvoptargTF| to check for the
-% optional argument short cutting to the final step if no optional argument was
-% found. This way we safe some time in this case, though we have to specify the
-% default values twice.
-%
-% \begin{lstlisting}
-% \RequirePackage{xfp}
-% \makeatletter
-% \ekvdef{expex}{f}{\ekvsneakPre{\f{#1}}}
-% \ekvdef{expex}{round}{\ekvsneakPre{\rnd{#1}}}
-% \ekvdefNoVal{expex}{degree}{\ekvsneakPre{\deg{d}}}
-% \ekvdefNoVal{expex}{radian}{\ekvsneakPre{\deg{}}}
-% \ekvdefNoVal{expex}{internal}{\ekvsneakPre{\sine@rnd}}
-% \newcommand*\sine{\ekvoptargTF\sine@args{\sine@final{sin}{d}{3}}}
-% \newcommand*\sine@args[2]
-% {\ekvset{expex}{#1,internal}\rnd{3}\deg{d}\f{sin}\sine@stop{#2}}
-% \end{lstlisting}
-%
-% Now we need to define some internal macros to extract the value of each key's
-% last usage (remember that this will be the group after the first special
-% flag-token). For that we use one delimited macro per key.
-% \begin{lstlisting}
-% \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{lstlisting}
-% After the macros |\sine@rnd|, |\sine@deg|, and |\sine@f| the macro
-% |\sine@final| will see
-% \texttt
-% {^^A
-% \cs[no-index]{sine@final}^^A
-% \marg{f}\marg{degree/radian}\marg{round}\marg{num}^^A
-% }.
-% Now |\sine@final| has to expandably deal with those arguments such that the
-% |\fpeval| macro of \pkg{xfp} gets the correct input. Luckily this is pretty
-% straight forward in this example. In |\fpeval| the trigonometric functions
-% have names such as |sin| or |cos| and the degree taking variants |sind| or
-% |cosd|. And since the |degree| key puts a |d| in |#2| and the |radian| key
-% leaves |#2| empty all we have to do to get the correct function name is stick
-% the two together.
-% \begin{lstlisting}
-% \newcommand*\sine@final[4]{\fpeval{round(#1#2(#4),#3)}}
-% \makeatother
-% \end{lstlisting}
-% Let's test our macro:\\
-% \begin{minipage}{.75\linewidth}
-% \begin{lstlisting}[gobble=4]
-% \sine{60}\par
-% \sine[round=10]{60}\par
-% \sine[f=cos,radian]{pi}\par
-% \edef\myval{\sine[f=tan]{1}}\texttt{\meaning\myval}
-% \end{lstlisting}
-% \end{minipage}^^A
-% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
-% \makeatletter
-% \ekvdef{expex}{f}{\ekvsneakPre{\f{#1}}}^^A
-% \ekvdef{expex}{round}{\ekvsneakPre{\rnd{#1}}}^^A
-% \ekvdefNoVal{expex}{degree}{\ekvsneakPre{\deg{d}}}^^A
-% \ekvdefNoVal{expex}{radian}{\ekvsneakPre{\deg{}}}^^A
-% \ekvdefNoVal{expex}{internal}{\ekvsneakPre{\sine@rnd}}^^A
-% \newcommand*\sine{\ekvoptargTF\sine@args{\sine@final{sin}{d}{3}}}
-% \newcommand*\sine@args[2]
-% {\ekvset{expex}{#1,internal}\rnd{3}\deg{d}\f{sin}\sine@stop{#2}}
-% \def\sine@rnd#1\rnd#2#3\sine@stop{\sine@deg#1#3\sine@stop{#2}}^^A
-% \def\sine@deg#1\deg#2#3\sine@stop{\sine@f#1#3\sine@stop{#2}}^^A
-% \def\sine@f#1\f#2#3\sine@stop{\sine@final{#2}}^^A
-% \newcommand*\sine@final[4]{\fpeval{round(#1#2(#4),#3)}}^^A
-% \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{exresult}
-%
-% \paragraph{The same macro using \protect\expkvc}
-% Using \expkvc\ we can set up something equivalent with a bit less code. The
-% implementation chosen in \expkvc\ is more efficient than the example above and
-% way easier to code for the user.
-% \begin{lstlisting}
-% \makeatletter
-% \newcommand*\sine{\ekvoptargTF\sine@a{\sine@b{sin}{d}{3}}}
-% \ekvcSplitAndForward\sine@a\sine@b
-% {
-% f=sin,
-% unit=d,
-% round=3,
-% }
-% \ekvcSecondaryKeys\sine@a
-% {
-% nmeta degree={unit=d},
-% nmeta radian={unit={}},
-% }
-% \newcommand*\sine@b[4]{\fpeval{round(#1#2(#4),#3)}}
-% \makeatother
-% \end{lstlisting}
-% The resulting macro will behave just like the one previously defined, but will
-% have an additional |unit| key, since in \expkvc\ every argument must have a
-% value taking key which defines it.
-%
-%
-% \subsection{Error Messages}
-%
-% \expkv\ should only send messages in case of errors, there are no warnings and
-% no info messages. In this subsection those errors are listed.
-%
-% \subsubsection{Load Time}
-%
-% \file{expkv.tex} checks whether \eTeX\ and the |\expanded| primitive are
-% available. If it isn't, an error will be thrown using |\errmessage|:
-% \begin{lstlisting}
-% ! expkv Error: e-TeX and \expanded required.
-% \end{lstlisting}
-%
-% \subsubsection{Defining Keys}
-%
-% If you get any error from \expkv\ while you're trying to define a key, the
-% definition will be aborted and gobbled.
-%
-% If you try to define a key with an empty set name you'll get:
-% \begin{lstlisting}
-% ! expkv Error: empty set name not allowed.
-% \end{lstlisting}
-%
-% Similarly, if you try to define a key with an empty key name:
-% \begin{lstlisting}
-% ! expkv Error: empty key name not allowed.
-% \end{lstlisting}
-%
-% Both of these messages are done in a way that doesn't throw additional errors
-% due to |\global|, |\long|, etc., not being used correctly if you prefixed one
-% of the defining macros.
-%
-% \subsubsection{Using Keys}
-%
-% This subsubsection contains the errors thrown during |\ekvset|. The errors are
-% thrown in an expandable manner using |\ekverr|. In the following messages
-% \lstinline|<key>| gets replaced with the problematic key's name, and
-% \lstinline|<set>| with the corresponding set. If any errors during \kv\
-% handling are encountered, the entry in the comma separated list will be
-% omitted after the error is thrown and the next \kv\ pair will be parsed.
-%
-% If you're using an undefined key you'll get:
-% \begin{lstlisting}
-% Runaway argument?
-% ! expkv Error: unknown key `<key>' in set `<set>'
-% \end{lstlisting}
-%
-% If you're using a key for which only a normal version and no |NoVal| version
-% is defined, but don't provide a value, you'll get:
-% \begin{lstlisting}
-% Runaway argument?
-% ! expkv Error: missing value for `<key>' in set `<set>'
-% \end{lstlisting}
-%
-% If you're using a key for which only a |NoVal| version and no normal version
-% is defined, but provide a value, you'll get:
-% \begin{lstlisting}
-% Runaway argument?
-% ! expkv Error: unwanted value for `<key>' in set `<set>'
-% \end{lstlisting}
-%
-% If you're using an undefined key in a set for which |\ekvredirectunknown| was
-% used, and the key isn't found in any of the other sets as well, you'll get:
-% \begin{lstlisting}
-% Runaway argument?
-% ! expkv Error: no key `<key>' in sets {<set1>}{<set2>}...
-% \end{lstlisting}
-%
-% If you're using an undefined |NoVal| key in a set for which
-% |\ekvredirectunknownNoVal| was used, and the key isn't found in any of the
-% other sets as well, you'll get:
-% \begin{lstlisting}
-% Runaway argument?
-% ! expkv Error: no NoVal key `<key>' in sets {<set1>}{<set2>}...
-% \end{lstlisting}
-%
-% If you're using a set for which you never executed one of the defining macros
-% from \autoref{sec:define} you'll get a low level \TeX\ error, as that isn't
-% actively tested by the parser (and hence will lead to undefined behaviour and
-% not be gracefully ignored). The error will look like
-% \begin{lstlisting}[language={}]
-% ! Missing \endcsname inserted.
-% <to be read again>
-% \! expkv Error: Set `<set>' undefined.
-% \end{lstlisting}
-%
-% \subsection{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 GitHub if you have an account there:
-% \url{https://github.com/Skillmon/tex_expkv}
-%
-% \subsection{Comparisons}\label{sec:cmp}
-%
-% This subsection 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), 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{lstlisting}
-% \protected\ekvdef{test}{height}{\def\myheight{#1}}
-% \ekvsetdef\expkvtest{test}
-% \expkvtest{ height = 6 }
-% \end{lstlisting}
-% 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
-% the two tests (for empty key names and only a single equal sign) which are
-% omitted.
-%
-% \paragraph{\pkg{keyval}} is about \SIrange{30}{40}{\percent} faster and has a
-% comparable feature set (actually a bit smaller since \expkv\ supports
-% unknown-key handlers and redirection to other sets) just a slightly different
-% way how it handles keys without values. 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 bug, 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 argument isn'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{lstlisting}[belowskip=0pt]
-% \setkeys{foo}{bar=baz}
-% \setkeys{foo}{bar= {baz}}
-% \setkeys{foo}{bar={ baz}} % should be ` baz'
-% \setkeys{foo}{bar={{baz}}} % should be `{baz}'
-% \end{lstlisting}
-%
-% \paragraph{\pkg{xkeyval}} is roughly twenty times slower, but it provides more
-% functionality, e.g., it has choice keys, boolean keys, and so on. 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.
-%
-% \paragraph{\pkg{ltxkeys}} is no longer compatible with the \LaTeX\ kernel
-% starting with the release 2020-10-01. It is over 380 times slower -- 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. 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).
-%
-% \paragraph{\pkg{l3keys}} is around four and a half times slower, 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 is pretty much bound to \pkg{expl3} code. Whether that's a drawback is up
-% to you.
-%
-% \paragraph{\pkg{pgfkeys}} is around \num{2.7} times slower for one key if one
-% uses the |/|\meta{path}|/.cd| syntax and almost \SI{20}{\percent} slower if
-% one uses |\pgfqkeys|, but has an \emph{enormous} feature set.
-% To get the best performance |\pgfqkeys| was used in the benchmark. This
-% reduces the overhead for setting the base directory of the benchmark keys by
-% about \SI{43}{\ops} (so 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 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.
-%
-% \paragraph{\pkg{kvsetkeys} with \pkg{kvdefinekeys}} is about \num{4.4} times
-% slower, but it works even if commas and equals have category codes different
-% from 12 (just as some other packages in this list). Else the features of the
-% keys are equal to those of \pkg{keyval}, the parser has more features, though.
-%
-% \paragraph{\pkg{options}} is \num{1.7} times slower for only a single value.
-% It has a much bigger feature set. Unfortunately it also suffers from the
-% premature unbracing bug \pkg{keyval} has.
-%
-% \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 adds
-% functionality so that it can be used more like most of the other \kv\
-% packages. It has problems with stripping braces and spaces in a hard to
-% predict manner just like \pkg{keyval}. Also, while it tries to be robust
-% against category code changes of commas and equal signs, the used mechanism
-% fails if the \kv\ list already got tokenised. 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. For up to three keys, \expkv\ is a bit faster,
-% for more keys \pkg{simplekv} takes the lead.
-%
-% \paragraph{\protect\yax} is over twenty times slower. 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,
-% it's just atypical). It has the premature unbracing bug, too. Also somehow
-% loading \yax\ broke \pkg{options} for me. The tested definition was:
-% \begin{lstlisting}[belowskip=0pt]
-% \usepackage{yax}
-% \defactiveparameter yax {\storevalue\myheight yax:height } % setup
-% \setparameterlist{yax}{ height = 6 } % benchmark
-% \end{lstlisting}
-%
-% \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 the \href{https://github.com/Skillmon/tex_expkv}{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.742 & 1.486 & 7.254 & \yes & \yes & 2014-10-28 \\
-% \expkv & 19.701 & 2.169 & 6.592 & \no & \no & 2020-10-10 \\
-% simplekv & 18.334 & 6.971 & 17.710 & \yes & \yes & 2020-04-27 \\
-% pgfkeys & 24.274 & 1.725 & 10.650 & \yes & \yes & 2020-09-05 \\
-% options & 23.600 & 15.638 & 20.830 & \yes & \yes & 2015-03-01 \\
-% kvsetkeys & {\fnsym} & {\fnsym} & 40.290 & \no & \no & 2019-12-15 \\
-% l3keys & 71.309 & 33.131 & 31.590 & \no & \no & 2020-09-24 \\
-% xkeyval & 253.563 & 202.246 & 168.300 & \yes & \yes & 2014-12-03 \\
-% \yax & 421.853 & 157.003 & 114.700 & \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{8.240}$, $p_1=\num{44.862}$, and $p_0=\num{60.793}$. 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}
-%
-% \subsection{License}
-%
-% Copyright \textcopyright\ 2020\unless\ifnum\year=2020--\the\year\fi\
-% Jonathan P. Spratte
-%
-% \medskip\noindent
-% 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:
-%
-% \url{http://www.latex-project.org/lppl.txt}
-%
-% \noindent
-% This work is ``maintained'' (as per LPPL maintenance status) by
-%
-% \mbox{Jonathan P. Spratte}.
-%
-% \end{documentation}^^A=<<
-%
-% \begin{implementation}^^A>>=
-%
-% \clearpage
-%
-% \section{Implementation}^^A>>=
-%^^A the LaTeX package >>=
-% \subsection{The \LaTeX\ Package}
-% First we set up the \LaTeX\ package. That one doesn't really do much except
-% |\input|ting the generic code and identifying itself as a package.
-% \gobbledocstriptag
-%<*pkg>
-% \begin{macrocode}
-\def\ekv@tmp
- {%
- \ProvidesFile{expkv.tex}%
- [\ekvDate\space v\ekvVersion\space an expandable key=val implementation]%
- }
-\input{expkv.tex}
-\ProvidesPackage{expkv}%
- [\ekvDate\space v\ekvVersion\space an expandable key=val implementation]
-% \end{macrocode}
-% \gobbledocstriptag
-%</pkg>
-%^^A=<<
-%^^A the ConTeXt module >>=
-% \subsection{The \ConTeXt\ module}
-% This is pretty straight forward, we just have to change the error throwing
-% mechanism for \ConTeXt\ (the approach taken for plain and \LaTeX\ breaks in
-% \ConTeXt, effectively breaking \ConTeXt, dropping you in an interactive \TeX\
-% session with almost no means of escape).
-% \gobbledocstriptag
-%<*ctx>
-% \begin{macrocode}
-\writestatus{loading}{ConTeXt User Module / expkv}
-\unprotect
-\input expkv.tex
-\long\def\ekv@err@collect#1\par#2%
- {\directlua{tex.error[[\detokenize{#2} Error: #1]]}}
-\writestatus{loading}
- {ConTeXt User Module / expkv / Version \ekvVersion\space loaded}
-\protect\endinput
-% \end{macrocode}
-% \gobbledocstriptag
-%</ctx>
-%^^A=<<
-%^^A main file >>=
-% \subsection{The Generic Code}
-% The rest of this implementation will be the generic code.
-% \gobbledocstriptag
-%<*tex>
-%
-% We make sure that it's only input once:
-% \begin{macrocode}
-\expandafter\ifx\csname ekvVersion\endcsname\relax
-\else
- \expandafter\endinput
-\fi
-% \end{macrocode}
-%
-% Check whether \eTeX\ and |\expanded| are available -- \expkv\ requires \eTeX.
-% \begin{macrocode}
-\begingroup
- \edef\ekvtmpa{\string\expanded}
- \edef\ekvtmpb{\meaning\expanded}
- \expandafter
-\endgroup
-\ifx\ekvtmpa\ekvtmpb
- \expandafter\let\csname ekv@expanded\endcsname\expanded
- \expandafter\let\csname ekv@unexpanded\endcsname\unexpanded
-\else
- \begingroup
- \edef\ekvtmpa{\string\expanded}
- \edef\ekvtmpb{\meaning\normalexpanded}
- \expandafter
- \endgroup
- \ifx\ekvtmpa\ekvtmpb
- \expandafter\let\csname ekv@expanded\endcsname\normalexpanded
- \expandafter\let\csname ekv@unexpanded\endcsname\normalunexpanded
- \else
- \errmessage
- {expkv Error: e-TeX and the \noexpand\expanded primitive required}%
- \expandafter\endinput
- \fi
-\fi
-% \end{macrocode}
-%
-% \begin{macro}{\ekvVersion,\ekvDate}
-% We're on our first input, so lets store the version and date in a macro.
-% \begin{macrocode}
-\def\ekvVersion{1.9a}
-\def\ekvDate{2021-09-20}
-% \end{macrocode}
-% \end{macro}
-%
-% If the \LaTeX\ format is loaded we want to be a good file and report back who
-% we are, for this the package will have defined |\ekv@tmp| to use
-% |\ProvidesFile|, else this will expand to a |\relax| and do no harm.
-% \begin{macrocode}
-\csname ekv@tmp\endcsname
-% \end{macrocode}
-%
-% Store the category code of |@| to later be able to reset it and change it to
-% 11 for now.
-% \begin{macrocode}
-\expandafter\chardef\csname ekv@tmp\endcsname=\catcode`\@
-\catcode`\@=11
-% \end{macrocode}
-% |\ekv@tmp| might later be reused to gobble any prefixes which might be
-% provided to |\ekvdef| and similar in case the names are invalid, we just
-% temporarily use it here as means to store the current category code of |@| to
-% restore it at the end of the file, we never care for the actual definition of
-% it.
-%
-% \begin{macro}[internal]{\ekv@if@lastnamedcs}
-% If the primitive |\lastnamedcs| is available, we can be a bit faster than
-% without it. So we test for this and save the test's result in this macro.
-% \begin{macrocode}
-\begingroup
- \edef\ekv@tmpa{\string \lastnamedcs}
- \edef\ekv@tmpb{\meaning\lastnamedcs}
- \ifx\ekv@tmpa\ekv@tmpb
- \def\ekv@if@lastnamedcs{\long\def\ekv@if@lastnamedcs##1##2{##1}}
- \else
- \def\ekv@if@lastnamedcs{\long\def\ekv@if@lastnamedcs##1##2{##2}}
- \fi
- \expandafter
-\endgroup
-\ekv@if@lastnamedcs
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@empty}
-% Sometimes we have to introduce a token to prevent accidental brace stripping.
-% This token would then need to be removed by |\@gobble| or similar. Instead we
-% can use |\ekv@empty| which will just expand to nothing, that is faster than
-% gobbling an argument.
-% \begin{macrocode}
-\def\ekv@empty{}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \@gobble,\@firstofone,\@firstoftwo,\@secondoftwo,
-% \ekv@fi@gobble,\ekv@fi@firstofone,\ekv@fi@firstoftwo,\ekv@fi@secondoftwo,
-% \ekv@gobble@mark,\ekv@gobbleto@stop,\ekv@gobble@from@mark@to@stop
-% }
-% Since branching tests are often more versatile than |\if...\else...\fi|
-% constructs, we define helpers that are branching pretty fast. Also here are
-% some other utility functions that just grab some tokens. The ones that are
-% also contained in \LaTeX\ don't use the |ekv| prefix. Not all of the ones
-% defined here are really needed by \expkv\ but are provided because packages
-% like \expkvd\ or \expkvo\ need them (and I don't want to define them in each
-% package which might need them).
-% \begin{macrocode}
-\long\def\@gobble#1{}
-\long\def\@firstofone#1{#1}
-\long\def\@firstoftwo#1#2{#1}
-\long\def\@secondoftwo#1#2{#2}
-\long\def\ekv@fi@gobble\fi\@firstofone#1{\fi}
-\long\def\ekv@fi@firstofone\fi\@gobble#1{\fi#1}
-\long\def\ekv@fi@firstoftwo\fi\@secondoftwo#1#2{\fi#1}
-\long\def\ekv@fi@secondoftwo\fi\@firstoftwo#1#2{\fi#2}
-\def\ekv@gobble@mark\ekv@mark{}
-\long\def\ekv@gobbleto@stop#1\ekv@stop{}
-\long\def\ekv@gobble@from@mark@to@stop\ekv@mark#1\ekv@stop{}
-% \end{macrocode}
-% \end{macro}
-% As you can see |\ekv@gobbleto@stop| uses a special marker |\ekv@stop|. The
-% package will use three such markers, the one you've seen already, |\ekv@mark|
-% and |\ekv@nil|. Contrarily to how for instance \pkg{expl3} does things, we
-% don't define them, as we don't need them to have an actual meaning. This has
-% the advantage that if they somehow get expanded -- which should never happen
-% if things work out -- they'll throw an error directly.
-%
-% \begin{macro}[internal]
-% {
-% \ekv@ifempty,\ekv@ifempty@,\ekv@ifempty@true,\ekv@ifempty@false,
-% \ekv@ifempty@true@F,\ekv@ifempty@true@F@gobble,
-% \ekv@ifempty@true@F@gobbletwo
-% }
-% We can test for a lot of things building on an if-empty test, so lets define a
-% really fast one. Since some tests might have reversed logic (true if something
-% is not empty) we also set up macros for the reversed branches.
-% \begin{macrocode}
-\long\def\ekv@ifempty#1%
- {%
- \ekv@ifempty@\ekv@ifempty@A#1\ekv@ifempty@B\ekv@ifempty@true
- \ekv@ifempty@A\ekv@ifempty@B\@secondoftwo
- }
-\long\def\ekv@ifempty@#1\ekv@ifempty@A\ekv@ifempty@B{}
-\long\def\ekv@ifempty@true\ekv@ifempty@A\ekv@ifempty@B\@secondoftwo#1#2{#1}
-\long\def\ekv@ifempty@false\ekv@ifempty@A\ekv@ifempty@B\@firstoftwo#1#2{#2}
-\long\def\ekv@ifempty@true@F\ekv@ifempty@A\ekv@ifempty@B\@firstofone#1{}
-\long\def\ekv@ifempty@true@F@gobble\ekv@ifempty@A\ekv@ifempty@B\@firstofone#1#2%
- {}
-\long\def\ekv@ifempty@true@F@gobbletwo
- \ekv@ifempty@A\ekv@ifempty@B\@firstofone#1#2#3%
- {}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@ifblank,\ekv@ifblank@}
-% The obvious test that can be based on an if-empty is if-blank, meaning a test
-% checking whether the argument is empty or consists only of spaces. Our version
-% here will be tweaked a bit, as we want to check this, but with one leading
-% |\ekv@mark| token that is to be ignored. The wrapper |\ekv@ifblank| will not
-% be used by \expkv\ for speed reasons but \expkvo\ uses it.
-% \begin{macrocode}
-\long\def\ekv@ifblank#1%
- {%
- \ekv@ifblank@#1\ekv@nil\ekv@ifempty@B\ekv@ifempty@true
- \ekv@ifempty@A\ekv@ifempty@B\@secondoftwo
- }
-\long\def\ekv@ifblank@\ekv@mark#1{\ekv@ifempty@\ekv@ifempty@A}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@ifdefined}
-% We'll need to check whether something is defined quite frequently, so why not
-% define a macro that does this. The following test is expandable and pretty
-% fast. The version with |\lastnamedcs| is the fastest version to test for an
-% undefined macro I know of (that considers both undefined macros and those with
-% the meaning |\relax|).
-% \begin{macrocode}
-\ekv@if@lastnamedcs
- {%
- \long\def\ekv@ifdefined#1{\ifcsname#1\endcsname\ekv@ifdef@\fi\@secondoftwo}
- \def\ekv@ifdef@\fi\@secondoftwo
- {%
- \fi
- \expandafter\ifx\lastnamedcs\relax
- \ekv@fi@secondoftwo
- \fi
- \@firstoftwo
- }
- }
- {%
- \long\def\ekv@ifdefined#1%
- {%
- \ifcsname#1\endcsname\ekv@ifdef@\fi\ekv@ifdef@false#1\endcsname\relax
- \ekv@fi@secondoftwo
- \fi
- \@firstoftwo
- }
- \def\ekv@ifdef@\fi\ekv@ifdef@false{\fi\expandafter\ifx\csname}
- \long\def\ekv@ifdef@false
- #1\endcsname\relax\ekv@fi@secondoftwo\fi\@firstoftwo#2#3%
- {#3}
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@strip,\ekv@strip@a,\ekv@strip@b,\ekv@strip@c}
-% We borrow some ideas of \pkg{expl3}'s \pkg{l3tl} to strip spaces
-% from keys and values. This |\ekv@strip| also strips one level of outer braces
-% \emph{after} stripping spaces, so an input of | {abc} | becomes |abc| after
-% stripping. It should be used with |#1| prefixed by |\ekv@mark|. Also this
-% implementation at most strips \emph{one} space from both sides (which should
-% be fine most of the time, since \TeX\ reads consecutive spaces as a single one
-% during tokenisation).
-% \begin{macrocode}
-\def\ekv@strip#1%
- {%
- \long\def\ekv@strip##1%
- {%
- \ekv@strip@a
- ##1\ekv@nil
- \ekv@mark#1%
- #1\ekv@nil
- }%
- \long\def\ekv@strip@a##1\ekv@mark#1{\ekv@strip@b##1\ekv@mark}%
- }
-\ekv@strip{ }
-\long\def\ekv@strip@b#1 \ekv@nil{\ekv@strip@c#1\ekv@nil}
-\long\def\ekv@strip@c\ekv@mark#1\ekv@nil\ekv@mark#2\ekv@nil#3{#3{#1}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekv@exparg,\ekv@exparg@,\ekv@expargtwice,\ekv@expargtwice@,\ekv@zero}
-% To reduce some code doublets while gaining some speed (and also as convenience
-% for other packages in the family), it is often useful to expand the first
-% token in a definition once. Let's define a wrapper for this.
-%
-% Also, to end a |\romannumeral| expansion, we want to use |\z@|, which is
-% contained in both plain \TeX\ and \LaTeX, but we use a private name for it to
-% make it easier to spot and hence easier to manage.
-% \begin{macrocode}
-\let\ekv@zero\z@
-\long\def\ekv@exparg#1#2{\expandafter\ekv@exparg@\expandafter{#2}{#1}}
-\long\def\ekv@exparg@#1#2{#2{#1}}%
-\long\def\ekv@expargtwice#1#2{\expandafter\ekv@expargtwice@\expandafter{#2}{#1}}
-\def\ekv@expargtwice@{\expandafter\ekv@exparg@\expandafter}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvcsvloop}
-% \begin{macro}[internal]{\ekv@csv@loop@active,\ekv@csv@loop@active@end}
-% An |\ekvcsvloop| will just loop over a csv list in a simple manner. First we
-% split at active commas (gives better performance this way), next we have to
-% check whether we're at the end of the list (checking for |\ekv@stop|). If
-% not we go on splitting at commas of category other.
-% \begin{macrocode}
-\begingroup
-\def\ekvcsvloop#1{%
-\endgroup
-\long\def\ekvcsvloop##1##2%
- {\ekv@csv@loop@active{##1}\ekv@mark##2#1\ekv@stop#1}
-% \end{macrocode}
-% This does the same as |\ekv@csv@loop| but for active commas.
-% \begin{macrocode}
-\long\def\ekv@csv@loop@active##1##2#1%
- {%
- \ekv@gobble@from@mark@to@stop##2\ekv@csv@loop@active@end\ekv@stop
- \ekv@csv@loop{##1}##2,\ekv@stop,%
- }%
-\long\def\ekv@csv@loop@active@end
- \ekv@stop
- \ekv@csv@loop##1\ekv@mark\ekv@stop,\ekv@stop,%
- {}%
-}
-% \end{macrocode}
-% Do the definitions with the weird catcode.
-% \begin{macrocode}
-\catcode`\,=13
-\ekvcsvloop,
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@csv@loop,\ekv@csv@loop@do,\ekv@csv@loop@end}
-% We use temporary macros and an |\expandafter| chain to preexpand
-% |\ekv@strip| here. After splitting at other commas we check again for end
-% the end of the sublist, check for blank elements which should be ignored,
-% and else strip spaces and execute the user code (protecting it from further
-% expanding with |\unexpanded|).
-% \begin{macrocode}
-\def\ekv@csv@loop#1%
- {%
- \long\def\ekv@csv@loop##1##2,%
- {%
- \ekv@gobble@from@mark@to@stop##2\ekv@csv@loop@end\ekv@stop
- \ekv@ifblank@##2\ekv@nil\ekv@ifempty@B\ekv@csv@loop@blank
- \ekv@ifempty@A\ekv@ifempty@B
- #1\ekv@csv@loop@do{##1}%
- }%
- }
-\expandafter\ekv@csv@loop\expandafter{\ekv@strip{#2}}
-\long\def\ekv@csv@loop@do#1#2{\ekv@unexpanded{#2{#1}}\ekv@csv@loop{#2}\ekv@mark}
-\def\ekv@csv@loop@end#1%
- {%
- \long\def\ekv@csv@loop@end
- \ekv@stop
- \ekv@ifblank@\ekv@mark\ekv@stop\ekv@nil\ekv@ifempty@B\ekv@csv@loop@blank
- \ekv@ifempty@A\ekv@ifempty@B
- #1\ekv@csv@loop@do##1%
- {\ekv@csv@loop@active{##1}\ekv@mark}%
- }
-\expandafter\ekv@csv@loop@end\expandafter{\ekv@strip{\ekv@mark\ekv@stop}}
-\long\expandafter\def\expandafter\ekv@csv@loop@blank
- \expandafter\ekv@ifempty@A\expandafter\ekv@ifempty@B
- \ekv@strip{\ekv@mark#1}\ekv@csv@loop@do#2%
- {\ekv@csv@loop{#2}\ekv@mark}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekv@name,\ekv@name@set,\ekv@name@key}
-% The keys will all follow the same naming scheme, so we define it here.
-% \begin{macrocode}
-\def\ekv@name@set#1{ekv#1(}
-\long\def\ekv@name@key#1{#1)}
-\edef\ekv@name
- {%
- \ekv@unexpanded\expandafter{\ekv@name@set{#1}}%
- \ekv@unexpanded\expandafter{\ekv@name@key{\detokenize{#2}}}%
- }
-\long\ekv@exparg{\def\ekv@name#1#2}{\ekv@name}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@undefined@set}
-% We can misuse the macro name we use to expandably store the set-name in a
-% single token -- since this increases performance drastically, especially for
-% long set-names -- to throw a more meaningful error message in case a set isn't
-% defined. The name of |\ekv@undefined@set| is a little bit misleading, as it is
-% called in either case inside of |\csname|, but the result will be a control
-% sequence with meaning |\relax| if the set is undefined, hence will break the
-% |\csname| building the key-macro which will throw the error message.
-% \begin{macrocode}
-\def\ekv@undefined@set#1{! expkv Error: Set `#1' undefined.}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@checkvalid}
-% We place some restrictions on the allowed names, though, namely sets and
-% keys are not allowed to be empty -- blanks are fine (meaning \mbox{set-
-% or} key-names consisting of spaces). The |\def\ekv@tmp| gobbles any \TeX\
-% prefixes which would otherwise throw errors. This will, however, break the
-% package if an |\outer| has been gobbled this way. I consider that good,
-% because keys shouldn't be defined |\outer| anyways.
-% \begin{macrocode}
-\edef\ekv@checkvalid
- {%
- \ekv@unexpanded\expandafter{\ekv@ifempty{#1}}%
- \ekv@unexpanded
- {{%
- \def\ekv@tmp{}%
- \errmessage{expkv Error: empty set name not allowed}%
- }}%
- {%
- \ekv@unexpanded\expandafter{\ekv@ifempty{#2}}%
- \ekv@unexpanded
- {%
- {%
- \def\ekv@tmp{}%
- \errmessage{expkv Error: empty key name not allowed}%
- }%
- \@secondoftwo
- }%
- }%
- \ekv@unexpanded{\@gobble}%
- }
-\ekv@exparg{\protected\def\ekv@checkvalid#1#2}{\ekv@checkvalid}%
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvifdefined,\ekvifdefinedNoVal}
-% And provide user-level macros to test whether a key is defined.
-% \begin{macrocode}
-\ekv@expargtwice{\long\def\ekvifdefined#1#2}%
- {\expandafter\ekv@ifdefined\expandafter{\ekv@name{#1}{#2}}}
-\ekv@expargtwice{\long\def\ekvifdefinedNoVal#1#2}%
- {\expandafter\ekv@ifdefined\expandafter{\ekv@name{#1}{#2}N}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}
-% {
-% \ekvdef,\ekvdefNoVal,\ekvlet,\ekvletNoVal,\ekvletkv,\ekvletkvNoVal,
-% \ekvdefunknown,\ekvdefunknownNoVal
-% }
-% Set up the key defining macros |\ekvdef| etc. We use temporary macros to set
-% these up with a few expansions already done.
-% \begin{macrocode}
-\def\ekvdef#1#2#3#4%
- {%
- \protected\long\def\ekvdef##1##2##3%
- {#1{\expandafter\def\csname#2\endcsname####1{##3}#3}}%
- \protected\long\def\ekvdefNoVal##1##2##3%
- {#1{\expandafter\def\csname#2N\endcsname{##3}#3}}%
- \protected\long\def\ekvlet##1##2##3%
- {#1{\expandafter\let\csname#2\endcsname##3#3}}%
- \protected\long\def\ekvletNoVal##1##2##3%
- {#1{\expandafter\let\csname#2N\endcsname##3#3}}%
- \ekv@expargtwice{\protected\long\def\ekvdefunknown##1##2}%
- {%
- \romannumeral
- \expandafter\ekv@exparg@\expandafter
- {%
- \expandafter\expandafter\expandafter
- \def\expandafter\csname\ekv@name{##1}{}u\endcsname####1####2{##2}%
- #3%
- }%
- {\ekv@zero\ekv@checkvalid{##1}.}%
- }%
- \ekv@expargtwice{\protected\long\def\ekvdefunknownNoVal##1##2}%
- {%
- \romannumeral
- \expandafter\ekv@exparg@\expandafter
- {%
- \expandafter\expandafter\expandafter
- \def\expandafter\csname\ekv@name{##1}{}uN\endcsname####1{##2}%
- #3%
- }%
- {\ekv@zero\ekv@checkvalid{##1}.}%
- }%
- \protected\long\def\ekvletkv##1##2##3##4%
- {%
- #1%
- {%
- \expandafter\let\csname#2\expandafter\endcsname
- \csname#4\endcsname
- #3%
- }%
- }%
- \protected\long\def\ekvletkvNoVal##1##2##3##4%
- {%
- #1%
- {%
- \expandafter\let\csname#2N\expandafter\endcsname
- \csname#4N\endcsname
- #3%
- }%
- }%
- }
-\edef\ekvdefNoVal
- {%
- {\ekv@unexpanded\expandafter{\ekv@checkvalid{#1}{#2}}}%
- {\ekv@unexpanded\expandafter{\ekv@name{#1}{#2}}}%
- {%
- \ekv@unexpanded{\expandafter\ekv@defsetmacro\csname}%
- \ekv@unexpanded\expandafter{\ekv@undefined@set{#1}\endcsname{#1}}%
- }%
- {\ekv@unexpanded\expandafter{\ekv@name{#3}{#4}}}%
- }
-\expandafter\ekvdef\ekvdefNoVal
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvredirectunknown,\ekvredirectunknownNoVal}
-% \begin{macro}[internal]
-% {
-% \ekv@defredirectunknown,\ekv@redirectunknown@aux,
-% \ekv@redirectunknownNoVal@aux
-% }
-% The redirection macros prepare the unknown function by looping over the
-% provided list of sets and leaving a |\ekv@redirect@kv| or |\ekv@redirect@k|
-% for each set. Only the first of these internals will receive the \key\ and
-% \val\ as arguments.
-% \begin{macrocode}
-\protected\def\ekvredirectunknown
- {%
- \ekv@defredirectunknown
- \ekv@redirect@kv
- \ekv@err@redirect@kv@notfound
- {\long\ekvdefunknown}%
- \ekv@redirectunknown@aux
- }
-\protected\def\ekvredirectunknownNoVal
- {%
- \ekv@defredirectunknown
- \ekv@redirect@k
- \ekv@err@redirect@k@notfound
- \ekvdefunknownNoVal
- \ekv@redirectunknownNoVal@aux
- }
-\protected\def\ekv@defredirectunknown#1#2#3#4#5#6%
- {%
- \begingroup
- \edef\ekv@tmp
- {%
- \ekvcsvloop#1{#6}%
- \ekv@unexpanded{#2}%
- {\ekvcsvloop{}{#5,#6}}%
- }%
- \ekv@expargtwice
- {\endgroup#3{#5}}%
- {\expandafter#4\ekv@tmp\ekv@stop}%
- }
-\def\ekv@redirectunknown@aux#1{#1{##1}{##2}}
-\def\ekv@redirectunknownNoVal@aux#1{#1{##1}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekv@redirect@k,\ekv@redirect@k@a,\ekv@redirect@k@a@,
-% \ekv@redirect@k@b,\ekv@redirect@k@c,\ekv@redirect@k@d,
-% \ekv@redirect@kv,\ekv@redirect@kv@a,\ekv@redirect@kv@a@,
-% \ekv@redirect@kv@b,\ekv@redirect@kv@c,\ekv@redirect@kv@d
-% }
-% The redirect code works by some simple loop over all the sets, which we
-% already preprocessed in |\ekv@defredirectunknown|. For some optimisation we
-% blow this up a bit code wise, essentially, all this does is |\ekvifdefined|
-% or |\ekvifdefinedNoVal| in each set, if there is a match gobble the
-% remainder of the specified sets and execute the key macro, else go on with
-% the next set (to which the \key\ and \val\ are forwarded).
-%
-% First we set up some code which is different depending on |\lastnamedcs|
-% being available or not. All this is stored in a temporary macro to have
-% pre-expanded |\ekv@name| constellations ready.
-% \begin{macrocode}
-\def\ekv@redirect@k#1#2#3#4%
- {%
- \ekv@if@lastnamedcs
- {%
- \def\ekv@redirect@k##1##2##3%
- {%
- \ifcsname#1\endcsname\ekv@redirect@k@a\fi
- ##3{##1}%
- }%
- \def\ekv@redirect@k@a\fi{\fi\expandafter\ekv@redirect@k@b\lastnamedcs}%
- \long\def\ekv@redirect@kv##1##2##3##4%
- {%
- \ifcsname#2\endcsname\ekv@redirect@kv@a\fi\@gobble{##1}%
- ##4{##1}{##2}%
- }%
- \def\ekv@redirect@kv@a\fi\@gobble
- {\fi\expandafter\ekv@redirect@kv@b\lastnamedcs}%
- }
- {%
- \def\ekv@redirect@k##1##2##3%
- {%
- \ifcsname#1\endcsname\ekv@redirect@k@a\fi\ekv@redirect@k@a@
- #1\endcsname
- ##3{##1}%
- }%
- \def\ekv@redirect@k@a@#3\endcsname{}%
- \def\ekv@redirect@k@a\fi\ekv@redirect@k@a@
- {\fi\expandafter\ekv@redirect@k@b\csname}%
- \long\def\ekv@redirect@kv##1##2##3##4%
- {%
- \ifcsname#2\endcsname\ekv@redirect@kv@a\fi\ekv@redirect@kv@a@
- #2\endcsname{##1}%
- ##4{##1}{##2}%
- }%
- \long\def\ekv@redirect@kv@a@#4\endcsname##3{}%
- \def\ekv@redirect@kv@a\fi\ekv@redirect@kv@a@
- {\fi\expandafter\ekv@redirect@kv@b\csname}%
- }%
- }
-% \end{macrocode}
-% The key name given to this loop will already be |\detokenize|d by |\ekvset|,
-% so we can safely remove the |\detokenize| here for some performance gain.
-% \begin{macrocode}
-\def\ekv@redirect@kv#1\detokenize#2#3\ekv@stop{\ekv@unexpanded{#1#2#3}}
-\edef\ekv@redirect@kv
- {%
- {\expandafter\ekv@redirect@kv\ekv@name{#2}{#1}N\ekv@stop}%
- {\expandafter\ekv@redirect@kv\ekv@name{#3}{#2}\ekv@stop}%
- {\expandafter\ekv@redirect@kv\ekv@name{#1}{#2}N\ekv@stop}%
- {\expandafter\ekv@redirect@kv\ekv@name{#1}{#2}\ekv@stop}%
- }
-% \end{macrocode}
-% Everything is ready to make the real definitions.
-% \begin{macrocode}
-\expandafter\ekv@redirect@k\ekv@redirect@kv
-% \end{macrocode}
-% The remaining macros here are independent on |\lastnamedcs|, starting from
-% the |@b| we know that there is a hash table entry, and get the macro as a
-% parameter. We still have to test whether the macro is |\relax|, depending on
-% the result of that test we have to either remove the remainder of the
-% current test, or the remainder of the set list and invoke the macro.
-% \begin{macrocode}
-\def\ekv@redirect@k@b#1%
- {\ifx\relax#1\ekv@redirect@k@c\fi\ekv@redirect@k@d#1}
-\def\ekv@redirect@k@c\fi\ekv@redirect@k@d#1{\fi}
-\def\ekv@redirect@k@d#1#2\ekv@stop{#1}
-\def\ekv@redirect@kv@b#1%
- {\ifx\relax#1\ekv@redirect@kv@c\fi\ekv@redirect@kv@d#1}
-\long\def\ekv@redirect@kv@c\fi\ekv@redirect@kv@d#1#2{\fi}
-\long\def\ekv@redirect@kv@d#1#2#3\ekv@stop{#1{#2}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@defsetmacro}
-% In order to enhance the speed the set name given to |\ekvset| will be turned
-% into a control sequence pretty early, so we have to define that control
-% sequence.
-% \begin{macrocode}
-\edef\ekv@defsetmacro
- {%
- \ekv@unexpanded{\ifx#1\relax\edef#1##1}%
- {%
- \ekv@unexpanded\expandafter{\ekv@name@set{#2}}%
- \ekv@unexpanded\expandafter{\ekv@name@key{##1}}%
- }%
- \ekv@unexpanded{\fi}%
- }
-\ekv@exparg{\protected\def\ekv@defsetmacro#1#2}{\ekv@defsetmacro}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvifdefinedset}
-% \begin{macrocode}
-\ekv@expargtwice{\def\ekvifdefinedset#1}%
- {\expandafter\ekv@ifdefined\expandafter{\ekv@undefined@set{#1}}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvset}
-% Set up |\ekvset|, which should not be affected by active commas and equal
-% signs. The equal signs are a bit harder to cope with and we'll do that later,
-% but the active commas can be handled by just doing two comma-splitting loops
-% one at actives one at others. That's why we define |\ekvset| here with a
-% temporary meaning just to set up the things with two different category codes.
-% |#1| will be a \texttt{,\textsubscript{13}} and |#2| will be a
-% \texttt{=\textsubscript{13}}.
-% \begin{macrocode}
-\begingroup
-\def\ekvset#1#2{%
-\endgroup
-\ekv@exparg{\long\def\ekvset##1##2}%
- {%
- \expandafter\expandafter\expandafter
- \ekv@set\expandafter\csname\ekv@undefined@set{##1}\endcsname
- \ekv@mark##2#1\ekv@stop#1{}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@set}
-% |\ekv@set| will split the \kv\ list at active commas. Then it has to check
-% whether there were unprotected other commas and resplit there.
-% \begin{macrocode}
-\long\def\ekv@set##1##2#1%
- {%
-% \end{macrocode}
-% Test whether we're at the end, if so invoke |\ekv@endset|,
-% \begin{macrocode}
- \ekv@gobble@from@mark@to@stop##2\ekv@endset\ekv@stop
-% \end{macrocode}
-% else go on with other commas.
-% \begin{macrocode}
- \ekv@set@other##1##2,\ekv@stop,%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@endset}
-% |\ekv@endset| is a hungry little macro. It will eat everything that remains
-% of |\ekv@set| and unbrace the sneaked stuff.
-% \begin{macrocode}
-\long\def\ekv@endset
- \ekv@stop\ekv@set@other##1\ekv@mark\ekv@stop,\ekv@stop,##2%
- {##2}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@eq@other,\ekv@eq@active}
-% Splitting at equal signs will be done in a way that checks whether there is
-% an equal sign and splits at the same time. This gets quite messy and the
-% code might look complicated, but this is pretty fast (faster than first
-% checking for an equal sign and splitting if one is found). The splitting
-% code will be adapted for |\ekvset| and |\ekvparse| to get the most speed,
-% but some of these macros don't require such adaptions. |\ekv@eq@other| and
-% |\ekv@eq@active| will split the argument at the first equal sign and insert
-% the macro which comes after the first following |\ekv@mark|. This allows for
-% fast branching based on \TeX's argument grabbing rules and we don't have to
-% split after the branching if the equal sign was there.
-% \begin{macrocode}
-\long\def\ekv@eq@other##1=##2\ekv@mark##3{##3##1\ekv@stop\ekv@mark##2}
-\long\def\ekv@eq@active##1#2##2\ekv@mark##3{##3##1\ekv@stop\ekv@mark##2}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@set@other}
-% The macro |\ekv@set@other| is guaranteed to get only single \kv\ pairs.
-% \begin{macrocode}
-\long\def\ekv@set@other##1##2,%
- {%
-% \end{macrocode}
-% First we test whether we're done.
-% \begin{macrocode}
- \ekv@gobble@from@mark@to@stop##2\ekv@endset@other\ekv@stop
-% \end{macrocode}
-% If not we split at the equal sign of category other.
-% \begin{macrocode}
- \ekv@eq@other##2\ekv@nil\ekv@mark\ekv@set@eq@other@a
- =\ekv@mark\ekv@set@eq@active
-% \end{macrocode}
-% And insert the set name for the next recursion step of |\ekv@set@other|.
-% \begin{macrocode}
- ##1%
- \ekv@mark
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@set@eq@other@a, \ekv@set@eq@other@b}
-% The first of these two macros runs the split-test for equal signs of
-% category active. It will only be inserted if the \kv\ pair contained at
-% least one equal sign of category other and |##1| will contain everything up
-% to that equal sign.
-% \begin{macrocode}
-\long\def\ekv@set@eq@other@a##1\ekv@stop
- {%
- \ekv@eq@active##1\ekv@nil\ekv@mark\ekv@set@eq@other@active
- #2\ekv@mark\ekv@set@eq@other@b
- }
-% \end{macrocode}
-% The second macro will have been called by |\ekv@eq@active| if no active
-% equal sign was found. All it does is remove the excess tokens of that
-% test and forward the \kv\ pair to |\ekv@set@pair|. Normally we would have to
-% also gobble an additional |\ekv@mark| after |\ekv@stop|, but this mark is
-% needed to delimit |\ekv@set@pair|'s argument anyway, so we just leave it
-% there.
-% \begin{macrocode}
-\ekv@exparg
- {%
- \long\def\ekv@set@eq@other@b
- ##1\ekv@nil\ekv@mark\ekv@set@eq@other@active\ekv@stop\ekv@mark
- ##2\ekv@nil=\ekv@mark\ekv@set@eq@active
- }%
- {\ekv@strip{##1}{\expandafter\ekv@set@pair\detokenize}\ekv@mark##2\ekv@nil}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@set@eq@other@active}
-% |\ekv@set@eq@other@active| will be called if the \kv\ pair was wrongly
-% split on an equal sign of category other but has an earlier equal sign of
-% category active. |##1| will be the contents up to the active equal sign and
-% |##2| everything that remains until the first found other equal sign. It has
-% to reinsert the equal sign and forward things to |\ekv@set@pair|.
-% \begin{macrocode}
-\ekv@exparg
- {%
- \long\def\ekv@set@eq@other@active
- ##1\ekv@stop##2\ekv@nil#2\ekv@mark
- \ekv@set@eq@other@b\ekv@mark##3=\ekv@mark\ekv@set@eq@active
- }%
- {\ekv@strip{##1}{\expandafter\ekv@set@pair\detokenize}\ekv@mark##2=##3}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@set@eq@active, \ekv@set@eq@active@}
-% |\ekv@set@eq@active| will be called when there was no equal sign of category
-% other in the \kv\ pair. It removes the excess tokens of the prior test and
-% split-checks for an active equal sign.
-% \begin{macrocode}
-\long\def\ekv@set@eq@active
- ##1\ekv@nil\ekv@mark\ekv@set@eq@other@a\ekv@stop\ekv@mark
- {%
- \ekv@eq@active##1\ekv@nil\ekv@mark\ekv@set@eq@active@
- #2\ekv@mark\ekv@set@noeq
- }
-% \end{macrocode}
-% If an active equal sign was found in |\ekv@set@eq@active| we'll have to pass
-% the now split \kv\ pair on to |\ekv@set@pair|.
-% \begin{macrocode}
-\ekv@exparg
- {\long\def\ekv@set@eq@active@##1\ekv@stop##2\ekv@nil#2\ekv@mark\ekv@set@noeq}%
- {\ekv@strip{##1}{\expandafter\ekv@set@pair\detokenize}\ekv@mark##2\ekv@nil}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@set@noeq}
-% If no active equal sign was found by |\ekv@set@eq@active| there is no equal
-% sign contained in the parsed list entry. In that case we have to check
-% whether the entry is blank in order to ignore it (in which case we'll have
-% to gobble the set-name which was put after these tests by |\ekv@set@other|).
-% Else this is a |NoVal| key and the entry is passed on to |\ekv@set@key|.
-% \begin{macrocode}
-\edef\ekv@set@noeq
- {%
- \ekv@unexpanded
- {%
- \ekv@ifblank@##1\ekv@nil\ekv@ifempty@B\ekv@set@was@blank
- \ekv@ifempty@A\ekv@ifempty@B
- }%
- \ekv@unexpanded\expandafter
- {\ekv@strip{##1}{\expandafter\ekv@set@key\detokenize}\ekv@mark}%
- }
-\ekv@exparg
- {%
- \long\def\ekv@set@noeq
- ##1\ekv@nil\ekv@mark\ekv@set@eq@active@\ekv@stop\ekv@mark
- }%
- {\ekv@set@noeq}
-\expandafter\def\expandafter\ekv@set@was@blank
- \expandafter\ekv@ifempty@A\expandafter\ekv@ifempty@B
- \ekv@strip{\ekv@mark##1}##2\ekv@mark
- {\ekv@set@other}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@endset@other}
-% All that's left for |\ekv@set@other| is the macro which breaks the recursion
-% loop at the end. This is done by gobbling all the remaining tokens.
-% \begin{macrocode}
-\long\def\ekv@endset@other
- \ekv@stop
- \ekv@eq@other\ekv@mark\ekv@stop\ekv@nil\ekv@mark\ekv@set@eq@other@a
- =\ekv@mark\ekv@set@eq@active
- {\ekv@set}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvbreak,\ekvbreakPreSneak,\ekvbreakPostSneak}
-% Provide macros that can completely stop the parsing of |\ekvset|, who knows
-% what it'll be useful for.
-% \begin{macrocode}
-\long\def\ekvbreak##1##2\ekv@stop#1##3{##1}
-\long\def\ekvbreakPreSneak ##1##2\ekv@stop#1##3{##1##3}
-\long\def\ekvbreakPostSneak##1##2\ekv@stop#1##3{##3##1}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvsneak,\ekvsneakPre}
-% One last thing we want to do for |\ekvset| is to provide macros that just
-% smuggle stuff after |\ekvset|'s effects.
-% \begin{macrocode}
-\long\def\ekvsneak##1##2\ekv@stop#1##3{##2\ekv@stop#1{##3##1}}
-\long\def\ekvsneakPre##1##2\ekv@stop#1##3{##2\ekv@stop#1{##1##3}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvparse}
-% Additionally to the |\ekvset| macro we also want to provide an |\ekvparse|
-% macro, that has the same scope as |\keyval_parse:NNn| from \pkg{expl3}.
-% This is pretty analogue to the |\ekvset| implementation, we just put an
-% |\unexpanded| here and there instead of other macros to stop the |\expanded|
-% on our output. The |\unexpanded\expanded{{...}}| ensures that the material
-% is in an alignment safe group at all time, and that it doesn't expand any
-% further in an |\edef| or |\expanded| context.
-% \begin{macrocode}
-\long\def\ekvparse##1##2##3%
- {%
- \ekv@unexpanded\ekv@expanded
- {{\ekv@parse{##1}{##2}\ekv@mark##3#1\ekv@stop#1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@parse}
-% \begin{macrocode}
-\long\def\ekv@parse##1##2##3#1%
- {%
- \ekv@gobble@from@mark@to@stop##3\ekv@endparse\ekv@stop
- \ekv@parse@other{##1}{##2}##3,\ekv@stop,%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@endparse}
-% \begin{macrocode}
-\long\def\ekv@endparse
- \ekv@stop\ekv@parse@other##1\ekv@mark\ekv@stop,\ekv@stop,%
- {}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@parse@other}
-% \begin{macrocode}
-\long\def\ekv@parse@other##1##2##3,%
- {%
- \ekv@gobble@from@mark@to@stop##3\ekv@endparse@other\ekv@stop
- \ekv@eq@other##3\ekv@nil\ekv@mark\ekv@parse@eq@other@a
- =\ekv@mark\ekv@parse@eq@active
- {##1}{##2}%
- \ekv@mark
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@parse@eq@other@a,\ekv@parse@eq@other@b}
-% \begin{macrocode}
-\long\def\ekv@parse@eq@other@a##1\ekv@stop
- {%
- \ekv@eq@active##1\ekv@nil\ekv@mark\ekv@parse@eq@other@active
- #2\ekv@mark\ekv@parse@eq@other@b
- }
-\ekv@exparg
- {%
- \long\def\ekv@parse@eq@other@b
- ##1\ekv@nil\ekv@mark\ekv@parse@eq@other@active\ekv@stop\ekv@mark
- ##2\ekv@nil=\ekv@mark\ekv@parse@eq@active
- }%
- {\ekv@strip{##1}\ekv@parse@pair##2\ekv@nil}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@parse@eq@other@active}
-% \begin{macrocode}
-\ekv@exparg
- {%
- \long\def\ekv@parse@eq@other@active
- ##1\ekv@stop##2\ekv@nil#2\ekv@mark
- \ekv@parse@eq@other@b\ekv@mark##3=\ekv@mark\ekv@parse@eq@active
- }%
- {\ekv@strip{##1}\ekv@parse@pair##2=##3}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@parse@eq@active,\ekv@parse@eq@active@}
-% \begin{macrocode}
-\long\def\ekv@parse@eq@active
- ##1\ekv@nil\ekv@mark\ekv@parse@eq@other@a\ekv@stop\ekv@mark
- {%
- \ekv@eq@active##1\ekv@nil\ekv@mark\ekv@parse@eq@active@
- #2\ekv@mark\ekv@parse@noeq
- }
-\ekv@exparg
- {\long\def\ekv@parse@eq@active@##1\ekv@stop##2#2\ekv@mark\ekv@parse@noeq}%
- {\ekv@strip{##1}\ekv@parse@pair##2}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@parse@noeq}
-% \begin{macrocode}
-\edef\ekv@parse@noeq
- {%
- \ekv@unexpanded
- {%
- \ekv@ifblank@##1\ekv@nil\ekv@ifempty@B\ekv@parse@was@blank
- \ekv@ifempty@A\ekv@ifempty@B
- }%
- \ekv@unexpanded\expandafter{\ekv@strip{##1}\ekv@parse@key}%
- }
-\ekv@exparg
- {%
- \long\def\ekv@parse@noeq
- ##1\ekv@nil\ekv@mark\ekv@parse@eq@active@\ekv@stop\ekv@mark
- }%
- {\ekv@parse@noeq}
-\expandafter\def\expandafter\ekv@parse@was@blank
- \expandafter\ekv@ifempty@A\expandafter\ekv@ifempty@B
- \ekv@strip{\ekv@mark##1}\ekv@parse@key
- {\ekv@parse@other}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@endparse@other}
-% \begin{macrocode}
-\long\def\ekv@endparse@other
- \ekv@stop
- \ekv@eq@other\ekv@mark\ekv@stop\ekv@nil\ekv@mark\ekv@parse@eq@other@a
- =\ekv@mark\ekv@parse@eq@active
- {\ekv@parse}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@parse@pair,\ekv@parse@pair@}
-% \begin{macrocode}
-\ekv@exparg{\long\def\ekv@parse@pair##1##2\ekv@nil}%
- {\ekv@strip{##2}\ekv@parse@pair@{##1}}
-\long\def\ekv@parse@pair@##1##2##3##4%
- {%
- \ekv@unexpanded{##4{##2}{##1}}%
- \ekv@parse@other{##3}{##4}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@parse@key}
-% \begin{macrocode}
-\long\def\ekv@parse@key##1##2%
- {%
- \ekv@unexpanded{##2{##1}}%
- \ekv@parse@other{##2}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% Finally really setting things up with |\ekvset|'s temporary meaning:
-% \begin{macrocode}
-}
-\catcode`\,=13
-\catcode`\==13
-\ekvset,=
-% \end{macrocode}
-%
-% \begin{macro}{\ekvsetSneaked}
-% This macro can be defined just by expanding |\ekvsneak| once after expanding
-% |\ekvset|. To expand everything as much as possible early on we use a
-% temporary definition.
-% \begin{macrocode}
-\edef\ekvsetSneaked
- {%
- \ekv@unexpanded{\ekvsneak{#2}}%
- \ekv@unexpanded\expandafter{\ekvset{#1}{#3}}%
- }
-\ekv@expargtwice{\long\def\ekvsetSneaked#1#2#3}{\ekvsetSneaked}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvchangeset}
-% Provide a macro that is able to switch out the current \set\ in |\ekvset|.
-% This operation allows something similar to \pkg{pgfkeys}'s
-% \texttt{\meta{key}/.cd} mechanism. However this operation can be more
-% expensive than |/.cd| as we can't just redefine some token to reflect this,
-% but have to switch out the set expandably, so this works similar to the
-% |\ekvsneak| macros reading and reinserting things, but it only has to read and
-% reinsert the remainder of the current key's replacement code.
-% \begin{macrocode}
-\ekv@exparg{\def\ekvchangeset#1}%
- {%
- \expandafter\expandafter\expandafter
- \ekv@changeset\expandafter\csname\ekv@undefined@set{#1}\endcsname\ekv@empty
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@changeset}
-% This macro does the real change-out of |\ekvchangeset|. |#2| will have a
-% leading |\ekv@empty| so that braces aren't stripped accidentally, but that
-% will not hurt and just expand to nothing in one step.
-% \begin{macrocode}
-\long\def\ekv@changeset#1#2\ekv@set@other#3{#2\ekv@set@other#1}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}[internal]
-% {
-% \ekv@set@pair,\ekv@set@pair@a,\ekv@set@pair@b,\ekv@set@pair@c,
-% \ekv@set@pair@d,\ekv@set@pair@e
-% }
-% |\ekv@set@pair| gets invoked with the space and brace stripped and
-% |\detokenize|d key-name as its first, the value as the second, and the set
-% name as the third argument. It provides tests for the key-macros and
-% everything to be able to throw meaningful error messages if it isn't
-% defined. We have two routes here, one if |\lastnamedcs| is defined and one
-% if it isn't. The big difference is that if it is we can omit a |\csname| and
-% instead just expand |\lastnamedcs| once to get the control sequence.
-% If the macro is defined the value will be space and brace stripped and the
-% key-macro called. Else branch into the error handling provided by
-% |\ekv@set@pair|.
-% \begin{macrocode}
-\ekv@if@lastnamedcs
- {%
- \long\def\ekv@set@pair#1\ekv@mark#2\ekv@nil#3%
- {%
- \ifcsname #3{#1}\endcsname\ekv@set@pair@a\fi\@secondoftwo
- {#2}%
- {%
- \ifcsname #3{}u\endcsname\ekv@set@pair@a\fi\@secondoftwo
- {#2}%
- {%
- \ekv@ifdefined{#3{#1}N}%
- \ekv@err@noarg
- \ekv@err@unknown
- #3%
- }%
- {#1}%
- }%
- \ekv@set@other#3%
- }
- \def\ekv@set@pair@a\fi\@secondoftwo
- {\fi\expandafter\ekv@set@pair@b\lastnamedcs}
- }
- {%
- \long\def\ekv@set@pair#1\ekv@mark#2\ekv@nil#3%
- {%
- \ifcsname #3{#1}\endcsname
- \ekv@set@pair@a\fi\ekv@set@pair@c#3{#1}\endcsname
- {#2}%
- {%
- \ifcsname #3{}u\endcsname
- \ekv@set@pair@a\fi\ekv@set@pair@c#3{}u\endcsname
- {#2}%
- {%
- \ekv@ifdefined{#3{#1}N}%
- \ekv@err@noarg
- \ekv@err@unknown
- #3%
- }%
- {#1}%
- }%
- \ekv@set@other#3%
- }
- \def\ekv@set@pair@a\fi\ekv@set@pair@c{\fi\expandafter\ekv@set@pair@b\csname}
- \long\def\ekv@set@pair@c#1\endcsname#2#3{#3}
- }
-\long\def\ekv@set@pair@b#1%
- {%
- \ifx#1\relax
- \ekv@set@pair@e
- \fi
- \ekv@set@pair@d#1%
- }
-\ekv@exparg{\long\def\ekv@set@pair@d#1#2#3}{\ekv@strip{#2}#1}
-\long\def\ekv@set@pair@e\fi\ekv@set@pair@d#1#2#3{\fi#3}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {\ekv@set@key,\ekv@set@key@a,\ekv@set@key@b,\ekv@set@key@c}
-% Analogous to |\ekv@set@pair|, |\ekv@set@key| builds the |NoVal| key-macro and
-% provides an error-branch. |\ekv@set@key@| will test whether the key-macro is
-% defined and if so call it, else the errors are thrown.
-% \begin{macrocode}
-\ekv@if@lastnamedcs
- {%
- \long\def\ekv@set@key#1\ekv@mark#2%
- {%
- \ifcsname #2{#1}N\endcsname\ekv@set@key@a\fi\@firstofone
- {%
- \ifcsname #2{}uN\endcsname\ekv@set@key@a\fi\@firstofone
- {%
- \ekv@ifdefined{#2{#1}}%
- \ekv@err@reqval
- \ekv@err@unknown
- #2%
- }%
- {#1}%
- }%
- \ekv@set@other#2%
- }
- \def\ekv@set@key@a\fi\@firstofone{\fi\expandafter\ekv@set@key@b\lastnamedcs}
- }
- {%
- \long\def\ekv@set@key#1\ekv@mark#2%
- {%
- \ifcsname #2{#1}N\endcsname
- \ekv@set@key@a\fi\ekv@set@key@c#2{#1}N\endcsname
- {%
- \ifcsname #2{}uN\endcsname
- \ekv@set@key@a\fi\ekv@set@key@c#2{}uN\endcsname
- {%
- \ekv@ifdefined{#2{#1}}%
- \ekv@err@reqval
- \ekv@err@unknown
- #2%
- }%
- {#1}%
- }%
- \ekv@set@other#2%
- }
- \def\ekv@set@key@a\fi\ekv@set@key@c{\fi\expandafter\ekv@set@key@b\csname}
- \long\def\ekv@set@key@c#1N\endcsname#2{#2}
- }
-\long\def\ekv@set@key@b#1%
- {%
- \ifx#1\relax
- \ekv@fi@secondoftwo
- \fi
- \@firstoftwo#1%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvsetdef}
-% Provide a macro to define a shorthand to use |\ekvset| on a specified \set.
-% To gain the maximum speed |\ekvset| is expanded twice by
-% |\ekv@exparg| so that during runtime the macro storing the set name
-% is already built and one |\expandafter| doesn't have to be used.
-% \begin{macrocode}
-\ekv@expargtwice{\protected\def\ekvsetdef#1#2}%
- {%
- \romannumeral
- \ekv@exparg{\ekv@zero\ekv@exparg{\long\def#1##1}}%
- {\ekvset{#2}{##1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvsetSneakeddef,\ekvsetdefSneaked}
-% And do the same for |\ekvsetSneaked| in the two possible ways, with a fixed
-% sneaked argument and with a flexible one.
-% \begin{macrocode}
-\ekv@expargtwice{\protected\def\ekvsetSneakeddef#1#2}%
- {%
- \romannumeral
- \ekv@exparg{\ekv@zero\ekv@exparg{\long\def#1##1##2}}%
- {\ekvsetSneaked{#2}{##1}{##2}}%
- }
-\ekv@expargtwice{\protected\def\ekvsetdefSneaked#1#2#3}%
- {%
- \romannumeral
- \ekv@exparg{\ekv@zero\ekv@exparg{\long\def#1##1}}%
- {\ekvsetSneaked{#2}{#3}{##1}}%
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@alignsafe,\ekv@endalignsafe}
-% These macros protect the usage of ampersands inside of alignment contexts.
-% \begin{macrocode}
-\begingroup
-\catcode`\^^@=2
-\@firstofone{\endgroup
- \def\ekv@alignsafe{\romannumeral\iffalse{\fi`^^@ }
-}
-\def\ekv@endalignsafe{\ifnum`{=\ekv@zero}\fi}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekvoptarg,\ekvoptargTF}
-% Provide macros to expandably collect an optional argument in brackets. The
-% macros here are pretty simple in nature compared to \pkg{xparse}'s
-% possibilities (they don't care for nested bracket levels).
-%
-% We start with a temporary definition to pre-expand |\ekv@alignsafe| (will be
-% |#1|) and |\ekv@endalignsafe| (will be |#2|). As |\ekv@alignsafe| starts with
-% a |\romannumeral| we use that to also control the number of steps needed
-% instead of adding another |\romannumeral|. For this we have to remove the
-% space token from the end of |\ekv@alignsafe|'s definition.
-% \begin{macrocode}
-\begingroup
-\def\ekvoptarg#1#2{%
-\endgroup
-% \end{macrocode}
-% The real definition starts an expansion context and afterwards grabs the
-% arguments. |#1| will be the next step, |#2| the default value, and |#3| might
-% be an opening bracket, or the mandatory argument. We check for the opening
-% bracket, if it is found grab the optional argument, else leave |#1{#2}| in the
-% input stream after ending the expansion context.
-% \begin{macrocode}
-\def\ekvoptarg{#1\ekv@optarg@a}
-\long\def\ekv@optarg@a##1##2##3%
- {%
- \ekv@optarg@if\ekv@mark##3\ekv@mark\ekv@optarg@b\ekv@mark[\ekv@mark
- #2%
- \@firstofone{ ##1}{##2}{##3}%
- }%
-% \end{macrocode}
-% The other variant of this will do roughly the same. Here, |#1| will be the
-% next step if an optional argument is found, |#2| the next step else, and |#3|
-% might be the opening bracket or mandatory argument.
-% \begin{macrocode}
-\def\ekvoptargTF{#1\ekv@optargTF@a}
-\long\def\ekv@optargTF@a##1##2##3%
- {%
- \ekv@optarg@if\ekv@mark##3\ekv@mark\ekv@optargTF@b{##1}\ekv@mark[\ekv@mark
- #2%
- \@firstofone{ ##2}{##3}%
- }
-% \end{macrocode}
-% The two macros to grab the optional argument have to remove the remainder of
-% the test and the wrong next step as well as grabbing the argument.
-% \begin{macrocode}
-\long\def\ekv@optarg@b\ekv@mark[\ekv@mark\ifnum`##1\fi\@firstofone##2##3##4##5]%
- {#2##2{##5}}
-\long\def\ekv@optargTF@b
- ##1\ekv@mark[\ekv@mark\ifnum`##2\fi\@firstofone##3##4##5]%
- {#2 ##1{##5}}
-}
-% \end{macrocode}
-% Do the definitions and add the test macro. We use |\ekv@strip| to remove the
-% trailing space from the definition of |\ekv@alignsafe|.
-% \begin{macrocode}
-\ekv@exparg
- {%
- \expandafter\ekv@strip\expandafter
- {\expandafter\ekv@mark\ekv@alignsafe}%
- \ekvoptarg
- }%
- \ekv@endalignsafe
-\long\def\ekv@optarg@if#1\ekv@mark[\ekv@mark{}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\ekverr}
-% \begin{macro}[internal]{\ekv@err@collect,\ekv@err@cleanup}
-% Since |\ekvset| is fully expandable as long as the code of the keys is (which
-% is unlikely) we want to somehow throw expandable errors, in our case via
-% a runaway argument (to my knowledge the first version of this method was
-% implemented by Jean-François Burnol, many thanks to him). The first step is to
-% ensure that the second argument (which might contain user input) doesn't
-% contain tokens we use as delimiters (in this case |\par|), this will be done
-% by the front facing macro |\ekverr|. But first we set some other things up.
-%
-% We use a temporary definition for |\ekverr| to get multiple consecutive
-% spaces. Then we set up the macro that will collect the error and the macro
-% that will throw the error. The latter will have an unreasonable long name.
-% This way we can convey more information. Though the information in the macro
-% name is static and has to be somewhat general to fit every occurence. The
-% important bit is that the long named macro has a delimited argument and is
-% short which will throw the error at the |\par| at the end of
-% |\ekv@err@collect|. This macro has the drawback that it will only print nicely
-% if the |\newlinechar| is |^^J|.
-% \begin{macrocode}
-\def\ekv@err@cleanup\par{}
-\def\ekv@err@collect#1%
- {%
- \def\ekv@err@collect##1\par##2%
- {%
- \expandafter
- \ekv@err@cleanup
- #1! ##2 Error: ##1\par
- }%
- \def#1##1\thanks@jfbu{}%
- }
-\def\ekverr{ }
-\expandafter\ekv@err@collect\csname <an-expandable-macro>^^J%
- completed due to above exception. \ekverr If the error^^J%
- summary is \ekverr not comprehensible \ekverr see the package^^J%
- documentation.^^J%
- I will try to recover now. \ekverr If you're in inter-^^J%
- active mode hit <return> \ekverr at the ? prompt and I^^J%
- continue hoping recovery\endcsname
-% \end{macrocode}
-% \begin{macrocode}
-\long\def\ekverr#1#2{\expandafter\ekv@err@collect\detokenize{#2}\par{#1}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekv@err}
-% We define a shorthand to throw errors in \expkv.
-% \begin{macrocode}
-\ekv@exparg{\long\def\ekv@err#1}{\ekverr{expkv}{#1}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]
-% {
-% \ekv@err@common,\ekv@err@common@,
-% \ekv@err@unknown,\ekv@err@noarg,\ekv@err@reqval
-% }
-% Now we can use |\ekv@err| to set up some error messages so that we can later
-% use those instead of the full strings.
-% \begin{macrocode}
-\long\def\ekv@err@common #1#2{\expandafter\ekv@err@common@\string#2{#1}}
-\ekv@exparg{\long\def\ekv@err@common@#1`#2' #3.#4#5}%
- {\ekv@err{#4 `#5' in set `#2'}}
-\ekv@exparg{\long\def\ekv@err@unknown#1}{\ekv@err@common{unknown key}{#1}}
-\ekv@exparg{\long\def\ekv@err@noarg #1}
- {\ekv@err@common{unwanted value for}{#1}}
-\ekv@exparg{\long\def\ekv@err@reqval #1}{\ekv@err@common{missing value for}{#1}}
-\ekv@exparg{\long\def\ekv@err@redirect@kv@notfound#1#2#3\ekv@stop}%
- {\ekv@err{no key `#2' in sets #3}}
-\ekv@exparg{\def\ekv@err@redirect@k@notfound#1#2\ekv@stop}%
- {\ekv@err{no NoVal key `#1' in sets #2}}
-% \end{macrocode}
-% \end{macro}
-%
-% Now everything that's left is to reset the category code of |@|.
-% \begin{macrocode}
-\catcode`\@=\ekv@tmp
-% \end{macrocode}
-%
-% \gobbledocstriptag
-%</tex>
-%^^A=<<
-%
-%^^A=<<
-%
-% \end{implementation}^^A=<<
-%
-% \clearpage
-% \PrintIndex
-%
-\endinput
-%
-^^A vim: ft=tex fdm=marker fmr=>>=,=<<
diff --git a/obsolete/macros/generic/expkv/expkv.pdf b/obsolete/macros/generic/expkv/expkv.pdf
deleted file mode 100644
index 2da6f6dada..0000000000
--- a/obsolete/macros/generic/expkv/expkv.pdf
+++ /dev/null
Binary files differ