summaryrefslogtreecommitdiff
path: root/macros/generic/expkv-def/expkv-def.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-07-13 03:01:06 +0000
committerNorbert Preining <norbert@preining.info>2020-07-13 03:01:06 +0000
commit6f2b7e75418a2fad9e80f85a4c97d3fa4da8978b (patch)
treec45d40bd282d46fecd886f57a03dd0bef8fef40a /macros/generic/expkv-def/expkv-def.dtx
parent145ca8eeaa26583fb8cf216fc5a079f3d65260e2 (diff)
CTAN sync 202007130301
Diffstat (limited to 'macros/generic/expkv-def/expkv-def.dtx')
-rw-r--r--macros/generic/expkv-def/expkv-def.dtx637
1 files changed, 470 insertions, 167 deletions
diff --git a/macros/generic/expkv-def/expkv-def.dtx b/macros/generic/expkv-def/expkv-def.dtx
index 3dfff1f80f..12b58cbe97 100644
--- a/macros/generic/expkv-def/expkv-def.dtx
+++ b/macros/generic/expkv-def/expkv-def.dtx
@@ -152,14 +152,21 @@ and the derived files expkv-def.pdf
\newcommand\enflong{\textcolor{black}{long}}
\newcommand\alllong{\textcolor{gray}{long}}
\newcommand\notlong{\textcolor{red!80!black}{long}}
-\newcommand\prefixes[2]
+\newcommand\enfalso{\textcolor{black}{also}}
+\newcommand\allalso{\textcolor{gray}{also}}
+\newcommand\notalso{\textcolor{red!80!black}{also}}
+\newcommand\prefixes[3]
{^^A
\hfill
\ifcase\numexpr#1\relax\or
+ \enfalso\or
+ \allalso\or
+ \notalso\fi\space
+ \ifcase\numexpr#2\relax\or
\enfprot\or
\allprot\or
\notprot\fi\space
- \ifcase\numexpr#2\relax\or
+ \ifcase\numexpr#3\relax\or
\enflong\or
\alllong\or
\notlong\fi
@@ -170,7 +177,7 @@ and the derived files expkv-def.pdf
\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}
+\DoNotIndex{\@firstoftwo,\@gobble,\@secondoftwo,\meaning,\detokenize}
\DoNotIndex{\ifcsname}
\DoNotIndex{\ifx}
\DoNotIndex{\ifdefined}
@@ -272,10 +279,38 @@ and the derived files expkv-def.pdf
% is allowed for all |t|-prefixes.
%
% \subsubsection{\texttt{p}-Prefixes}\label{sec:prefix:p}
-% The |p|-type prefixes 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.
+% 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
+% |also| might be simple on first sight as well, but its 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
+% }
+% \end{lstlisting}
+% \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|.
@@ -295,7 +330,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{code,ecode}
% \begin{syntax}
-% code \key\ = \marg{definition} \prefixes22
+% code \key\ = \marg{definition} \prefixes222
% \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
@@ -304,7 +339,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{noval,enoval}
% \begin{syntax}
-% noval \key\ = \marg{definition} \prefixes23
+% noval \key\ = \marg{definition} \prefixes223
% \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
@@ -313,7 +348,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{default,qdefault,edefault}
% \begin{syntax}
-% default \key\ = \marg{definition} \prefixes23
+% default \key\ = \marg{definition} \prefixes223
% \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\
@@ -325,7 +360,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{initial,oinitial,einitial}
% \begin{syntax}
-% initial \key\ = \{\val\} \prefixes33
+% initial \key\ = \{\val\} \prefixes333
% \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
@@ -336,7 +371,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{bool,gbool,boolTF,gboolTF}
% \begin{syntax}
-% bool \key\ = \meta{cs} \prefixes23
+% bool \key\ = \meta{cs} \prefixes223
% \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
@@ -361,7 +396,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{store,estore,gstore,xstore}
% \begin{syntax}
-% store \key\ = \meta{cs} \prefixes12
+% store \key\ = \meta{cs} \prefixes212
% \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
@@ -373,7 +408,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{data,edata,gdata,xdata}
% \begin{syntax}
-% data \key\ = \meta{cs} \prefixes12
+% data \key\ = \meta{cs} \prefixes212
% \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
@@ -389,7 +424,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{dataT,edataT,gdataT,xdataT}
% \begin{syntax}
-% dataT \key\ = \meta{cs} \prefixes12
+% dataT \key\ = \meta{cs} \prefixes212
% \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
@@ -399,7 +434,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{int,eint,gint,xint}
% \begin{syntax}
-% int \key\ = \meta{cs} \prefixes12
+% int \key\ = \meta{cs} \prefixes212
% \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,
@@ -410,7 +445,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{dimen,edimen,gdimen,xdimen}
% \begin{syntax}
-% dimen \key\ = \meta{cs} \prefixes12
+% dimen \key\ = \meta{cs} \prefixes212
% \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
@@ -419,7 +454,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{skip,eskip,gskip,xskip}
% \begin{syntax}
-% skip \key\ = \meta{cs} \prefixes12
+% skip \key\ = \meta{cs} \prefixes212
% \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|
@@ -428,7 +463,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{toks,gtoks,apptoks,gapptoks}
% \begin{syntax}
-% toks \key\ = \meta{cs} \prefixes12
+% toks \key\ = \meta{cs} \prefixes212
% \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
@@ -438,7 +473,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{box,gbox}
% \begin{syntax}
-% box \key\ = \meta{cs} \prefixes12
+% box \key\ = \meta{cs} \prefixes212
% \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
@@ -447,7 +482,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{meta}
% \begin{syntax}
-% meta \key\ = \{\kv, \ldots\} \prefixes22
+% meta \key\ = \{\kv, \ldots\} \prefixes222
% \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|
@@ -458,7 +493,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{nmeta}
% \begin{syntax}
-% nmeta \key\ = \{\kv, \ldots\} \prefixes23
+% nmeta \key\ = \{\kv, \ldots\} \prefixes223
% \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.
@@ -466,7 +501,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{smeta}
% \begin{syntax}
-% smeta \key\ = \marg{set}\{\kv, \ldots\} \prefixes22
+% smeta \key\ = \marg{set}\{\kv, \ldots\} \prefixes222
% \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
@@ -475,7 +510,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{snmeta}
% \begin{syntax}
-% snmeta \key\ = \marg{set}\{\kv, \ldots\} \prefixes23
+% snmeta \key\ = \marg{set}\{\kv, \ldots\} \prefixes223
% \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.
@@ -483,7 +518,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{set}
% \begin{syntax}
-% set \key\ = \marg{set} \prefixes33
+% set \key\ = \marg{set} \prefixes233
% \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),
@@ -495,7 +530,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{choice}
% \begin{syntax}
-% choice \key\ = \{\val=\meta{definition}, \ldots\} \prefixes23
+% choice \key\ = \{\val=\meta{definition}, \ldots\} \prefixes223
% \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
@@ -511,7 +546,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{unknown-choice}
% \begin{syntax}
-% unknown-choice \key\ = \marg{definition} \prefixes23
+% unknown-choice \key\ = \marg{definition} \prefixes323
% \end{syntax}
% By default an unknown \val\ passed to a |choice| key will throw an error.
% However, with this prefix you can define an alternative action which should
@@ -532,7 +567,7 @@ and the derived files expkv-def.pdf
% \begin{lstlisting}
% \ekvdefinekeys{example}
% {
-% ,long code keyA = #1
+% long code keyA = #1
% ,noval keyA = NoVal given
% ,bool keyB = \keyB
% ,boolTF keyC = \keyC
@@ -548,7 +583,7 @@ and the derived files expkv-def.pdf
% ,qdefault keyK = text
% ,choice keyL =
% {
-% ,protected 1 = \texttt{a}
+% protected 1 = \texttt{a}
% ,2 = b
% ,3 = c
% ,4 = d
@@ -556,7 +591,6 @@ and the derived files expkv-def.pdf
% }
% ,edefault keyL = 2
% ,meta keyM = {keyA={#1},keyB=false}
-% ,data
% }
% \end{lstlisting}
%
@@ -566,7 +600,7 @@ and the derived files expkv-def.pdf
% \begin{lstlisting}
% \ekvdefinekeys{ex}
% {
-% ,data name = \Pname
+% data name = \Pname
% ,data age = \Page
% ,dataT hobby = \Phobby
% }
@@ -593,7 +627,7 @@ and the derived files expkv-def.pdf
% \begingroup
% \ekvdefinekeys{ex}
% {
-% ,data name = \Pname
+% data name = \Pname
% ,data age = \Page
% ,dataT hobby = \Phobby
% }
@@ -684,8 +718,8 @@ and the derived files expkv-def.pdf
% \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.4}
-\def\ekvdDate{2020-07-04}
+\def\ekvdVersion{0.5}
+\def\ekvdDate{2020-07-12}
% \end{macrocode}
% \end{macro}
%
@@ -707,21 +741,36 @@ and the derived files expkv-def.pdf
% \expkvd\ was initialized.
%
% \begin{macro}[internal]
-% {\ekvd@long,\ekvd@prot,\ekvd@clear@prefixes,\ekvd@empty}
-% \expkvd\ will use |\ekvd@long| and |\ekvd@prot| to store whether a key should
-% be defined as |\long| or |\protected|, and we have to clear them for every new
-% key. By default they'll just be empty.
+% {\ekvd@long,\ekvd@prot,\ekvd@clear@prefixes,\ekvd@empty,\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 and |ifalso| will be
+% |\@secondoftwo|.
% \begin{macrocode}
\def\ekvd@empty{}
\protected\def\ekvd@clear@prefixes
{%
\let\ekvd@long\ekvd@empty
\let\ekvd@prot\ekvd@empty
+ \let\ekvd@ifalso\@secondoftwo
}
\ekvd@clear@prefixes
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[internal]{\ekvd@exp@Nno,\ekvd@exp@reinsert@n}
+% These are expansion helpers, similar to what \LaTeX3 uses, but simpler and
+% for just a few cases
+% \begin{macrocode}
+\long\def\ekvd@exp@Nno#1#2#3%
+ {%
+ \expandafter\ekvd@exp@reinsert@n\expandafter{#3}{#1{#2}}%
+ }
+\long\def\ekvd@exp@reinsert@n#1#2{#2{#1}}
+% \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
@@ -745,9 +794,10 @@ and the derived files expkv-def.pdf
\protected\long\def\ekvd@#1#2%
{%
\ekvd@clear@prefixes
+ \edef\ekvd@cur{\detokenize{#1}}%
\ekvd@ifspace{#1}%
{\ekvd@prefix\ekv@mark#1\ekv@stop{#2}}%
- {\ekvd@err@missing@prefix{#1}}%
+ \ekvd@err@missing@type
}
% \end{macrocode}
% \end{macro}
@@ -767,7 +817,7 @@ and the derived files expkv-def.pdf
{\ekv@strip{#2}{\csname ekvd@t@#1\endcsname}}%
{%
\ekv@ifdefined{ekvd@p@#1}%
- {\csname ekvd@p@#1\endcsname{#2}}%
+ {\csname ekvd@p@#1\endcsname\ekvd@prefix@after@p{#2}}%
{\ekvd@err@undefined@prefix{#1}\@gobble}%
}%
}
@@ -783,21 +833,20 @@ and the derived files expkv-def.pdf
{%
\ekvd@ifspace{#1}%
{\ekvd@prefix#1\ekv@stop}%
- {%
- \expandafter\ekvd@err@missing@prefix\expandafter{\ekv@gobble@mark#1}%
- \@gobble
- }%
+ {\ekvd@err@missing@type\@gobble}%
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\ekvd@p@long,\ekvd@p@protected,\ekvd@p@protect}
+% \begin{macro}[internal]
+% {\ekvd@p@long,\ekvd@p@protected,\ekvd@p@protect,\ekvd@p@also}
% Define the |@p@| type prefixes, they all just store some information in a
-% temporary macro and call |\ekvd@prefix@after@p|.
+% temporary macro.
% \begin{macrocode}
-\protected\def\ekvd@p@long{\let\ekvd@long\long\ekvd@prefix@after@p}
-\protected\def\ekvd@p@protected{\let\ekvd@prot\protected\ekvd@prefix@after@p}
+\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}
% \end{macrocode}
% \end{macro}
%
@@ -809,14 +858,23 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@t@set#1#2%
{%
- \ekvd@assert@not@long{set #1}%
- \ekvd@assert@not@protected{set #1}%
- \ekvd@ifnoarg{#2}%
- {\ekvdefNoVal\ekvd@set{#1}{\ekvchangeset{#1}}}%
+ \ekvd@assert@not@long
+ \ekvd@assert@not@protected
+ \ekv@ifempty{#2}%
+ {\ekvd@err@missing@definition}%
{%
- \ekv@ifempty{#2}%
- {\ekvd@err@missing@definition{set #1}}%
- {\ekvdefNoVal\ekvd@set{#1}{\ekvchangeset{#2}}}%
+ \ekvd@ifalso
+ {%
+ \ekvd@ifnoarg{#2}%
+ {\ekvd@add@noval{#1}{\ekvchangeset{#1}}}%
+ {\ekvd@add@noval{#1}{\ekvchangeset{#2}}}%
+ \ekvd@assert@not@protected@also
+ }%
+ {%
+ \ekvd@ifnoarg{#2}%
+ {\ekvdefNoVal\ekvd@set{#1}{\ekvchangeset{#1}}}%
+ {\ekvdefNoVal\ekvd@set{#1}{\ekvchangeset{#2}}}%
+ }%
}%
}
% \end{macrocode}
@@ -832,11 +890,13 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\long\def\ekvd@type@noval#1#2#3#4%
{%
- \ekvd@assert@arg{#1noval #3}{#4}%
+ \ekvd@assert@arg{#4}%
{%
- \ekvd@assert@not@long{#1noval #3}%
+ \ekvd@assert@not@long
\ekvd@prot#2\ekvd@tmp{#4}%
- \ekvletNoVal\ekvd@set{#3}\ekvd@tmp
+ \ekvd@ifalso
+ {\ekvd@exp@Nno\ekvd@add@noval{#3}\ekvd@tmp{}}%
+ {\ekvletNoVal\ekvd@set{#3}\ekvd@tmp}%
}%
}
\protected\def\ekvd@t@noval{\ekvd@type@noval{}\def}
@@ -850,10 +910,12 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\long\def\ekvd@type@code#1#2#3#4%
{%
- \ekvd@assert@arg{#1code #3}{#4}
+ \ekvd@assert@arg{#4}
{%
\ekvd@prot\ekvd@long#2\ekvd@tmp##1{#4}%
- \ekvlet\ekvd@set{#3}\ekvd@tmp
+ \ekvd@ifalso
+ {\ekvd@exp@Nno\ekvd@add@val{#3}{\ekvd@tmp{##1}}{}}%
+ {\ekvlet\ekvd@set{#3}\ekvd@tmp}%
}%
}
\protected\def\ekvd@t@code{\ekvd@type@code{}\def}
@@ -870,17 +932,19 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\long\def\ekvd@type@default#1#2#3#4%
{%
- \ekvd@assert@arg{#1default #3}{#4}%
+ \ekvd@assert@arg{#4}%
{%
\ekvifdefined\ekvd@set{#3}%
{%
- \ekvd@assert@not@long{#1default #3}%
+ \ekvd@assert@not@long
\ekvd@prot\edef\ekvd@tmp
{%
\unexpanded\expandafter#2%
{\csname\ekv@name\ekvd@set{#3}\endcsname{#4}}%
}%
- \ekvletNoVal\ekvd@set{#3}\ekvd@tmp
+ \ekvd@ifalso
+ {\ekvd@exp@Nno\ekvd@add@noval{#3}\ekvd@tmp{}}%
+ {\ekvletNoVal\ekvd@set{#3}\ekvd@tmp}%
}%
{\ekvd@err@undefined@key{#3}}%
}%
@@ -896,14 +960,16 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\long\def\ekvd@t@edefault#1#2%
{%
- \ekvd@assert@arg{edefault #1}{#2}%
+ \ekvd@assert@arg{#2}%
{%
\ekvifdefined\ekvd@set{#1}%
{%
- \ekvd@assert@not@long{edefault #1}%
+ \ekvd@assert@not@long
\ekvd@prot\edef\ekvd@tmp
{\csname\ekv@name\ekvd@set{#1}\endcsname{#2}}%
- \ekvletNoVal\ekvd@set{#1}\ekvd@tmp
+ \ekvd@ifalso
+ {\ekvd@exp@Nno\ekvd@add@noval{#1}\ekvd@tmp{}}%
+ {\ekvletNoVal\ekvd@set{#1}\ekvd@tmp}%
}%
{\ekvd@err@undefined@key{#1}}%
}%
@@ -915,12 +981,13 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\long\def\ekvd@t@initial#1#2%
{%
- \ekvd@assert@arg{initial #1}{#2}%
+ \ekvd@assert@arg{#2}%
{%
\ekvifdefined\ekvd@set{#1}%
{%
- \ekvd@assert@not@long{initial #1}%
- \ekvd@assert@not@protected{initial #1}%
+ \ekvd@assert@not@also
+ \ekvd@assert@not@long
+ \ekvd@assert@not@protected
\csname\ekv@name\ekvd@set{#1}\endcsname{#2}%
}%
{\ekvd@err@undefined@key{#1}}%
@@ -928,12 +995,13 @@ and the derived files expkv-def.pdf
}
\long\def\ekvd@t@oinitial#1#2%
{%
- \ekvd@assert@arg{oinitial #1}{#2}%
+ \ekvd@assert@arg{#2}%
{%
\ekvifdefined\ekvd@set{#1}%
{%
- \ekvd@assert@not@long{oinitial #1}%
- \ekvd@assert@not@protected{oinitial #1}%
+ \ekvd@assert@not@also
+ \ekvd@assert@not@long
+ \ekvd@assert@not@protected
\csname\ekv@name\ekvd@set{#1}\expandafter\endcsname\expandafter{#2}%
}%
{\ekvd@err@undefined@key{#1}}%
@@ -941,12 +1009,13 @@ and the derived files expkv-def.pdf
}
\long\def\ekvd@t@einitial#1#2%
{%
- \ekvd@assert@arg{einitial #1}{#2}%
+ \ekvd@assert@arg{#2}%
{%
\ekvifdefined\ekvd@set{#1}%
{%
- \ekvd@assert@not@long{einitial #1}%
- \ekvd@assert@not@protected{einitial #1}%
+ \ekvd@assert@not@also
+ \ekvd@assert@not@long
+ \ekvd@assert@not@protected
\edef\ekvd@tmp{#2}%
\csname\ekv@name\ekvd@set{#1}\expandafter\endcsname\expandafter
{\ekvd@tmp}%
@@ -966,7 +1035,7 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@type@bool#1#2#3#4#5#6#7%
{%
- \ekvd@assert@filledarg{#1bool#2 #6}{#7}%
+ \ekvd@assert@filledarg{#7}%
{%
\ekvd@newlet#7#5%
\ekvd@type@choice{#1bool#2}{#6}%
@@ -992,22 +1061,33 @@ and the derived files expkv-def.pdf
% \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#7%
+\protected\def\ekvd@type@data#1#2#3#4#5#6#7#8%
{%
- \ekvd@assert@filledarg{#1data#2 #6}{#7}%
+ \ekvd@assert@filledarg{#8}%
{%
- \ekvd@newlet#7#3%
- \protected\ekvd@long\ekvdef\ekvd@set{#6}{\long#4#7####1#5{####1{##1}}}%
+ \ekvd@newlet#8#3%
+ \ekvd@ifalso
+ {%
+ \let\ekvd@prot\protected
+ \ekvd@add@val{#7}{\long#4#8####1#5{####1{#6}}}{}%
+ }%
+ {%
+ \protected\ekvd@long\ekvdef\ekvd@set{#7}%
+ {\long#4#8####1#5{####1{#6}}}%
+ }%
}%
}
-\protected\def\ekvd@t@data{\ekvd@type@data{}{}\@secondoftwo\def{####2}}
-\protected\def\ekvd@t@edata{\ekvd@type@data e{}\@secondoftwo\edef{####2}}
-\protected\def\ekvd@t@gdata{\ekvd@type@data g{}\@secondoftwo\gdef{####2}}
-\protected\def\ekvd@t@xdata{\ekvd@type@data x{}\@secondoftwo\xdef{####2}}
-\protected\def\ekvd@t@dataT{\ekvd@type@data{}T\@gobble\def{}}
-\protected\def\ekvd@t@edataT{\ekvd@type@data eT\@gobble\edef{}}
-\protected\def\ekvd@t@gdataT{\ekvd@type@data gT\@gobble\gdef{}}
-\protected\def\ekvd@t@xdataT{\ekvd@type@data xT\@gobble\xdef{}}
+\protected\def\ekvd@t@data
+ {\ekvd@type@data{}{}\@secondoftwo\edef{####2}{\unexpanded{##1}}}
+\protected\def\ekvd@t@edata{\ekvd@type@data e{}\@secondoftwo\edef{####2}{##1}}
+\protected\def\ekvd@t@gdata
+ {\ekvd@type@data g{}\@secondoftwo\xdef{####2}{\unexpanded{##1}}}
+\protected\def\ekvd@t@xdata{\ekvd@type@data x{}\@secondoftwo\xdef{####2}{##1}}
+\protected\def\ekvd@t@dataT{\ekvd@type@data{}T\@gobble\edef{}{\unexpanded{##1}}}
+\protected\def\ekvd@t@edataT{\ekvd@type@data eT\@gobble\edef{}{##1}}
+\protected\def\ekvd@t@gdataT
+ {\ekvd@type@data gT\@gobble\xdef{}{\unexpanded{##1}}}
+\protected\def\ekvd@t@xdataT{\ekvd@type@data xT\@gobble\xdef{}{##1}}
% \end{macrocode}
% \end{macro}
%
@@ -1020,11 +1100,18 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@type@box#1#2#3#4%
{%
- \ekvd@assert@filledarg{#1box #3}{#4}%
+ \ekvd@assert@filledarg{#4}%
{%
\ekvd@newreg#4{box}%
- \protected\ekvd@long\ekvdef\ekvd@set{#3}%
- {#2\setbox#4\hbox{\begingroup##1\endgroup}}%
+ \ekvd@ifalso
+ {%
+ \let\ekvd@prot\protected
+ \ekvd@add@val{#3}{#2\setbox#4\hbox{\begingroup##1\endgroup}}{}%
+ }%
+ {%
+ \protected\ekvd@long\ekvdef\ekvd@set{#3}%
+ {#2\setbox#4\hbox{\begingroup##1\endgroup}}%
+ }%
}%
}
\protected\def\ekvd@t@box{\ekvd@type@box{}{}}
@@ -1037,10 +1124,15 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@type@toks#1#2#3#4%
{%
- \ekvd@assert@filledarg{#1toks #3}{#4}%
+ \ekvd@assert@filledarg{#4}%
{%
\ekvd@newreg#4{toks}%
- \protected\ekvd@long\ekvdef\ekvd@set{#3}{#2#4{##1}}%
+ \ekvd@ifalso
+ {%
+ \let\ekvd@prot\protected
+ \ekvd@add@val{#3}{#2#4{##1}}{}%
+ }%
+ {\protected\ekvd@long\ekvdef\ekvd@set{#3}{#2#4{##1}}}%
}%
}
\protected\def\ekvd@t@toks{\ekvd@type@toks{}{}}
@@ -1054,10 +1146,18 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@type@apptoks#1#2#3#4%
{%
- \ekvd@assert@filledarg{#1apptoks #3}{#4}%
+ \ekvd@assert@filledarg{#4}%
{%
\ekvd@newreg#4{toks}%
- \protected\ekvd@long\ekvdef\ekvd@set{#3}{#2#4\expandafter{\the#4##1}}%
+ \ekvd@ifalso
+ {%
+ \let\ekvd@prot\protected
+ \ekvd@add@val{#3}{#2#4\expandafter{\the#4##1}}{}%
+ }%
+ {%
+ \protected\ekvd@long\ekvdef\ekvd@set{#3}%
+ {#2#4\expandafter{\the#4##1}}%
+ }%
}%
}
\protected\def\ekvd@t@apptoks{\ekvd@type@apptoks{}{}}
@@ -1076,10 +1176,15 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@type@reg#1#2#3#4#5#6#7%
{%
- \ekvd@assert@filledarg{#1 #6}{#7}%
+ \ekvd@assert@filledarg{#7}%
{%
\ekvd@newreg#7{#2}%
- \protected\ekvd@long\ekvdef\ekvd@set{#6}{#3#7=#4##1#5\relax}%
+ \ekvd@ifalso
+ {%
+ \let\evkd@prot\protected
+ \ekvd@add@val{#6}{#3#7=#4##1#5\relax}{}%
+ }%
+ {\protected\ekvd@long\ekvdef\ekvd@set{#6}{#3#7=#4##1#5\relax}}%
}%
}
\protected\def\ekvd@t@int{\ekvd@type@reg{int}{count}{}{}{}}
@@ -1103,10 +1208,15 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@type@store#1#2#3#4%
{%
- \ekvd@assert@filledarg{#1store #3}{#4}%
+ \ekvd@assert@filledarg{#4}%
{%
- \unless\ifdefined#4\let#4\ekvd@empty\fi
- \protected\ekvd@long\ekvdef\ekvd@set{#3}{#2#4{\unexpanded{##1}}}%
+ \ekvd@newlet#4\ekvd@empty
+ \ekvd@ifalso
+ {%
+ \let\ekvd@prot\protected
+ \ekvd@add@val{#3}{#2#4{\unexpanded{##1}}}{}%
+ }%
+ {\protected\ekvd@long\ekvdef\ekvd@set{#3}{#2#4{\unexpanded{##1}}}}%
}%
}
\protected\def\ekvd@t@store{\ekvd@type@store{}\edef}
@@ -1119,10 +1229,15 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@type@estore#1#2#3#4%
{%
- \ekvd@assert@filledarg{#1store #3}{#4}%
+ \ekvd@assert@filledarg{#4}%
{%
\ekvd@newlet#4\ekvd@empty
- \protected\ekvd@long\ekvdef\ekvd@set{#3}{#2#4{##1}}%
+ \ekvd@ifalso
+ {%
+ \let\ekvd@prot\protected
+ \ekvd@add@val{#3}{#2#4{##1}}{}%
+ }%
+ {\protected\ekvd@long\ekvdef\ekvd@set{#3}{#2#4{##1}}}%
}%
}
\protected\def\ekvd@t@estore{\ekvd@type@estore{e}\edef}
@@ -1138,13 +1253,15 @@ and the derived files expkv-def.pdf
% |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%
+\protected\long\def\ekvd@type@meta#1#2#3#4#5#6#7#8%
{%
- \ekvd@assert@filledarg{#1meta #4}{#5}%
+ \ekvd@assert@filledarg{#8}%
{%
\edef\ekvd@tmp{\ekvd@set}%
- \expandafter\ekvd@type@meta@a\expandafter{\ekvd@tmp}{#5}{#3}%
- #2\ekvd@set{#4}\ekvd@tmp
+ \expandafter\ekvd@type@meta@a\expandafter{\ekvd@tmp}{#8}{#3}%
+ \ekvd@ifalso
+ {\ekvd@exp@Nno#4{#7}{\ekvd@tmp#5}{#6}}%
+ {#2\ekvd@set{#7}\ekvd@tmp}%
}%
}
\protected\long\def\ekvd@type@meta@a#1#2%
@@ -1159,11 +1276,12 @@ and the derived files expkv-def.pdf
{%
\ekvd@prot\ekvd@long\def\ekvd@tmp#2{#1}%
}
-\protected\def\ekvd@t@meta{\ekvd@type@meta{}\ekvlet{##1}}
-\protected\long\def\ekvd@t@nmeta#1#2%
+\protected\def\ekvd@t@meta{\ekvd@type@meta{}\ekvlet{##1}\ekvd@add@val{{##1}}{}}
+\protected\def\ekvd@t@nmeta
{%
- \ekvd@assert@not@long{nmeta #1}%
- \ekvd@type@meta n\ekvletNoVal{}{#1}{#2}%
+ \ekvd@assert@not@long
+ \ekvd@type@meta
+ n\ekvletNoVal{}\ekvd@add@noval{}\ekvd@assert@not@long@also
}
% \end{macrocode}
% \end{macro}
@@ -1174,19 +1292,23 @@ and the derived files expkv-def.pdf
% 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%
+\protected\long\def\ekvd@type@smeta#1#2#3#4#5#6#7#8%
{%
- \ekvd@assert@twoargs{s#1meta #4}{#5}%
+ \ekvd@assert@twoargs{#8}%
{%
- \ekvd@type@meta@a#5{#3}%
- #2\ekvd@set{#4}\ekvd@tmp
+ \ekvd@type@meta@a#8{#3}%
+ \ekvd@ifalso
+ {\ekvd@exp@Nno#4{#7}{\ekvd@tmp#5}{#6}}%
+ {#2\ekvd@set{#7}\ekvd@tmp}%
}%
}
-\protected\def\ekvd@t@smeta{\ekvd@type@smeta{}\ekvlet{##1}}
-\protected\long\def\ekvd@t@snmeta#1#2%
+\protected\def\ekvd@t@smeta
+ {\ekvd@type@smeta{}\ekvlet{##1}\ekvd@add@val{{##1}}{}}
+\protected\def\ekvd@t@snmeta
{%
- \ekvd@assert@not@long{snmeta #1}%
- \ekvd@type@smeta n\ekvletNoVal{}{#1}{#2}%
+ \ekvd@assert@not@long
+ \ekvd@type@smeta
+ n\ekvletNoVal{}\ekvd@add@noval{}\ekvd@assert@not@long@also
}
% \end{macrocode}
% \end{macro}
@@ -1206,12 +1328,16 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@type@choice#1#2%
{%
- \ekvd@assert@not@long{#1 #2}%
+ \ekvd@assert@not@long
\ekvd@prot\edef\ekvd@tmp##1%
{%
\unexpanded{\ekvd@h@choice}{\ekvd@choice@name\ekvd@set{#2}{##1}}%
}%
- \ekvlet\ekvd@set{#2}\ekvd@tmp
+ \ekvd@ifalso
+ {%
+ \ekvd@exp@Nno\ekvd@add@val{#2}{\ekvd@tmp{##1}}\ekvd@assert@not@long@also
+ }%
+ {\ekvlet\ekvd@set{#2}\ekvd@tmp}%
}
% \end{macrocode}
% |\ekvd@populate@choice| just uses |\ekvparse| and then gives control to
@@ -1224,7 +1350,7 @@ and the derived files expkv-def.pdf
}
\protected\long\def\ekvd@populate@choice@noarg#1%
{%
- \expandafter\ekvd@err@missing@definition\expandafter{\ekvd@set@choice : #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
@@ -1236,7 +1362,7 @@ and the derived files expkv-def.pdf
\protected\long\def\ekvd@populate@choice@#1#2%
{%
\ekvd@clear@prefixes
- \expandafter\ekvd@assert@arg\expandafter{\ekvd@set@choice : #1}{#2}%
+ \expandafter\ekvd@assert@arg@msg\expandafter{\ekvd@cur : #1}{#2}%
{%
\ekvd@ifspace{#1}%
{\ekvd@choice@prefix\ekv@mark#1\ekv@stop}%
@@ -1269,23 +1395,24 @@ and the derived files expkv-def.pdf
}
\protected\def\ekvd@choice@p@protected{\let\ekvd@prot\protected}
\let\ekvd@choice@p@protect\ekvd@choice@p@protected
-\protected\def\ekvd@choice@p@long\ekvd@ifspace#1%
+\protected\def\ekvd@choice@invalid@p#1\ekvd@ifspace#2%
{%
- \expandafter\ekvd@choice@p@long@\expandafter{\ekv@gobble@mark#1}%
- \ekvd@ifspace{#1}%
+ \expandafter\ekvd@choice@invalid@p@\expandafter{\ekv@gobble@mark#2}{#1}%
+ \ekvd@ifspace{#2}%
}
-\protected\def\ekvd@choice@p@long@#1%
+\protected\def\ekvd@choice@invalid@p@#1#2%
{%
- \expandafter\ekvd@err@no@long\expandafter
- {\ekvd@set@choice : long #1}%
+ \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}}%
% \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@assert@arg{choice #1}{#2}%
+ \ekvd@assert@arg{#2}%
{%
\ekvd@type@choice{choice}{#1}%
\def\ekvd@set@choice{#1}%
@@ -1299,9 +1426,10 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\long\expandafter\def\csname ekvd@t@unknown-choice\endcsname#1#2%
{%
- \ekvd@assert@arg{unknown-choice #1}{#2}%
+ \ekvd@assert@arg{#2}%
{%
- \ekvd@assert@not@long{unknown-choice #1}%
+ \ekvd@assert@not@long
+ \ekvd@assert@not@also
\ekvd@prot\expandafter
\def\csname\ekvd@unknown@choice@name\ekvd@set{#1}\endcsname##1{#2}%
}%
@@ -1336,6 +1464,93 @@ and the derived files expkv-def.pdf
% \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}
@@ -1344,11 +1559,11 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@newlet#1#2%
{%
- \unless\ifdefined#1\let#1#2\fi
+ \ifdefined#1\ekv@fi@gobble\fi\@firstofone{\let#1#2}%
}
\protected\def\ekvd@newreg#1#2%
{%
- \unless\ifdefined#1\csname new#2\endcsname#1\fi
+ \ifdefined#1\ekv@fi@gobble\fi\@firstofone{\csname new#2\endcsname#1}%
}
% \end{macrocode}
% \end{macro}
@@ -1360,10 +1575,9 @@ and the derived files expkv-def.pdf
% 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#2%
+\long\def\ekvd@assert@twoargs#1%
{%
- \ekvd@ifnottwoargs{#2}%
- {\ekvd@err@missing@definition{#1}}%
+ \ekvd@ifnottwoargs{#1}{\ekvd@err@missing@definition}%
}
\long\def\ekvd@ifnottwoargs#1%
{%
@@ -1375,15 +1589,74 @@ and the derived files expkv-def.pdf
% \end{macro}
%
% \begin{macro}[internal]
-% {\ekvd@assert@arg,\ekvd@ifnoarg,\ekvd@ifnoarg@,\ekvd@ifnoarg@}
+% {
+% \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\ekvd@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,\ekvd@ifnoarg@,
+% \ekvd@ifnoarg@
+% }
% An |\ifx| comparison would fail if the first token of the user input is a
% \TeX-if primitive or the user input contains unbalanced \TeX-if constructs, so
% the test is done using \TeX's argument grabbing logic.
% \begin{macrocode}
-\long\def\ekvd@assert@arg#1#2%
+\long\def\ekvd@assert@arg#1{\ekvd@ifnoarg{#1}\ekvd@err@missing@definition}
+\long\def\ekvd@assert@arg@msg#1#2%
{%
- \ekvd@ifnoarg{#2}%
- {\ekvd@err@missing@definition{#1}}%
+ \ekvd@ifnoarg{#2}{\ekvd@err@missing@definition@msg{#1}}%
}
\long\def\ekvd@ifnoarg#1%
{%
@@ -1401,10 +1674,9 @@ and the derived files expkv-def.pdf
%
% \begin{macro}[internal]{\ekvd@assert@filledarg,\ekvd@ifnoarg@or@empty}
% \begin{macrocode}
-\long\def\ekvd@assert@filledarg#1#2%
+\long\def\ekvd@assert@filledarg#1%
{%
- \ekvd@ifnoarg@or@empty{#2}%
- {\ekvd@err@missing@definition{#1}}%
+ \ekvd@ifnoarg@or@empty{#1}\ekvd@err@missing@definition
}
\long\def\ekvd@ifnoarg@or@empty#1%
{%
@@ -1415,18 +1687,29 @@ and the derived files expkv-def.pdf
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\ekvd@assert@not@long,\ekvd@assert@not@protected}
-% Some key-types don't want to be |\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{macro}[internal]
+% {
+% \ekvd@assert@not@long,\ekvd@assert@not@protected,\ekvd@assert@not@also
+% \ekvd@assert@not@long@also,\ekvd@assert@not@protected@also
+% }
+% 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}
-\long\def\ekvd@assert@not@long#1%
+\def\ekvd@assert@not@long{\ifx\ekvd@long\long\ekvd@err@no@prefix{long}\fi}
+\def\ekvd@assert@not@protected
{%
- \ifx\ekvd@long\long\ekvd@err@no@long{#1}\fi
+ \ifx\ekvd@prot\protected\ekvd@err@no@prefix{protected}\fi
}
-\long\def\ekvd@assert@not@protected#1%
+\def\ekvd@assert@not@also{\ekvd@ifalso{\ekvd@err@no@prefix{also}}{}}
+\def\ekvd@assert@not@long@also
{%
- \ifx\ekvd@prot\protected\ekvd@err@no@protected{#1}\fi
+ \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
}
% \end{macrocode}
% \end{macro}
@@ -1454,29 +1737,49 @@ and the derived files expkv-def.pdf
%
% \begin{macro}[internal]
% {
-% \ekvd@err@missing@definition,\ekvd@err@missing@prefix,
-% \ekvd@err@undefined@prefix,\ekvd@err@undefined@key,\ekvd@err@no@protected,
-% \ekvd@err@no@long
+% \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
% }
% The non-expandable error messages are boring, so here they are:
% \begin{macrocode}
-\protected\def\ekvd@err@missing@definition#1%
- {\errmessage{expkv-def Error: Missing definition for key `\unexpanded{#1}'}}
-\protected\def\ekvd@err@missing@prefix#1%
- {\errmessage{expkv-def Error: Missing prefix for key `\unexpanded{#1}'}}
+\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 `\unexpanded{#1}'}}
+\protected\def\ekvd@err@missing@type
+ {\ekvd@errm{Missing type prefix for key `\ekvd@cur'}}
\protected\def\ekvd@err@undefined@prefix#1%
- {\errmessage{expkv-def Error: Undefined prefix `\unexpanded{#1}'}}
-\protected\def\ekvd@err@undefined@key#1%
- {\errmessage{expkv-def Error: Undefined key `\unexpanded{#1}'}}
-\protected\def\ekvd@err@no@protected#1%
{%
- \errmessage
- {expkv-def Error: prefix `protected' not accepted for `\unexpanded{#1}'}%
+ \ekvd@errm
+ {Undefined prefix `\unexpanded{#1}' found while processing `\ekvd@cur'}%
}
-\protected\def\ekvd@err@no@long#1%
+\protected\def\ekvd@err@undefined@key#1%
+ {%
+ \ekvd@errm
+ {Undefined 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 `\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%
{%
- \errmessage
- {expkv-def Error: prefix `long' not accepted for `\unexpanded{#1}'}%
+ \fi
+ \ekvd@errm
+ {%
+ Existing key-macro has the unsupported argument string
+ `\ekvd@extracted@args' for key `\ekvd@cur'%
+ }%
}
% \end{macrocode}
% \end{macro}