summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-10-12 21:40:18 +0000
committerKarl Berry <karl@freefriends.org>2020-10-12 21:40:18 +0000
commit6f427f96627adfd5999246707610e7c96564897d (patch)
tree30ce1093d2bcb8db6cd22e6f3778bcf7d6330485 /Master/texmf-dist/source
parentce08ee94146637c4c9b8f352678141b83d741eed (diff)
expkv-def (12oct20)
git-svn-id: svn://tug.org/texlive/trunk@56643 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r--Master/texmf-dist/source/latex/expkv-def/expkv-def.dtx798
1 files changed, 459 insertions, 339 deletions
diff --git a/Master/texmf-dist/source/latex/expkv-def/expkv-def.dtx b/Master/texmf-dist/source/latex/expkv-def/expkv-def.dtx
index 12b58cbe97e..2dc41641530 100644
--- a/Master/texmf-dist/source/latex/expkv-def/expkv-def.dtx
+++ b/Master/texmf-dist/source/latex/expkv-def/expkv-def.dtx
@@ -146,30 +146,23 @@ and the derived files expkv-def.pdf
\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\enfalso{\textcolor{black}{also}}
-\newcommand\allalso{\textcolor{gray}{also}}
-\newcommand\notalso{\textcolor{red!80!black}{also}}
-\newcommand\prefixes[3]
+\newcommand\enfprefix{\textcolor{black}}
+\newcommand\allprefix{\textcolor{gray}}
+\newcommand\notprefix{\textcolor{red!80!black}}
+\newcommand\printprefix[2]
{^^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#3\relax\or
- \enflong\or
- \alllong\or
- \notlong\fi
+ \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}
@@ -282,9 +275,9 @@ and the derived files expkv-def.pdf
% 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.
+% 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
@@ -306,9 +299,16 @@ and the derived files expkv-def.pdf
% \ekvdefinekeys{also-example}
% {
% bool key = \ifmybool
-% ,also code key = \domystuff
+% ,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}
@@ -320,17 +320,33 @@ and the derived files expkv-def.pdf
% 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{\enfprot}), allowed prefixes will be grey (\texttt{\allprot}), and
-% disallowed prefixes will be red (\texttt{\notprot}). This will be put
-% flush-right in the syntax showing line.
+% (\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} \prefixes222
+% 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
@@ -339,7 +355,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{noval,enoval}
% \begin{syntax}
-% noval \key\ = \marg{definition} \prefixes223
+% 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
@@ -348,7 +364,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{default,qdefault,edefault}
% \begin{syntax}
-% default \key\ = \marg{definition} \prefixes223
+% 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\
@@ -360,7 +376,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{initial,oinitial,einitial}
% \begin{syntax}
-% initial \key\ = \{\val\} \prefixes333
+% initial \key\ = \{\val\} \prefixes3333
% \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
@@ -371,7 +387,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{bool,gbool,boolTF,gboolTF}
% \begin{syntax}
-% bool \key\ = \meta{cs} \prefixes223
+% 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
@@ -394,9 +410,28 @@ and the derived files expkv-def.pdf
% 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} \prefixes212
+% 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
@@ -408,7 +443,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{data,edata,gdata,xdata}
% \begin{syntax}
-% data \key\ = \meta{cs} \prefixes212
+% 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
@@ -424,7 +459,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{dataT,edataT,gdataT,xdataT}
% \begin{syntax}
-% dataT \key\ = \meta{cs} \prefixes212
+% 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
@@ -434,7 +469,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{int,eint,gint,xint}
% \begin{syntax}
-% int \key\ = \meta{cs} \prefixes212
+% 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,
@@ -445,7 +480,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{dimen,edimen,gdimen,xdimen}
% \begin{syntax}
-% dimen \key\ = \meta{cs} \prefixes212
+% 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
@@ -454,7 +489,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{skip,eskip,gskip,xskip}
% \begin{syntax}
-% skip \key\ = \meta{cs} \prefixes212
+% 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|
@@ -463,7 +498,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{toks,gtoks,apptoks,gapptoks}
% \begin{syntax}
-% toks \key\ = \meta{cs} \prefixes212
+% 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
@@ -473,7 +508,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{box,gbox}
% \begin{syntax}
-% box \key\ = \meta{cs} \prefixes212
+% 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
@@ -482,7 +517,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{meta}
% \begin{syntax}
-% meta \key\ = \{\kv, \ldots\} \prefixes222
+% 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|
@@ -493,7 +528,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{nmeta}
% \begin{syntax}
-% nmeta \key\ = \{\kv, \ldots\} \prefixes223
+% 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.
@@ -501,7 +536,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{smeta}
% \begin{syntax}
-% smeta \key\ = \marg{set}\{\kv, \ldots\} \prefixes222
+% 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
@@ -510,7 +545,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{snmeta}
% \begin{syntax}
-% snmeta \key\ = \marg{set}\{\kv, \ldots\} \prefixes223
+% 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.
@@ -518,7 +553,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{set}
% \begin{syntax}
-% set \key\ = \marg{set} \prefixes233
+% 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),
@@ -530,7 +565,7 @@ and the derived files expkv-def.pdf
%
% \begin{function}{choice}
% \begin{syntax}
-% choice \key\ = \{\val=\meta{definition}, \ldots\} \prefixes223
+% 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
@@ -546,12 +581,12 @@ and the derived files expkv-def.pdf
%
% \begin{function}{unknown-choice}
% \begin{syntax}
-% unknown-choice \key\ = \marg{definition} \prefixes323
+% unknown-choice \key\ = \marg{definition} \prefixes2323
% \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
-% be executed if \key\ received an unknown choice. In \meta{definition} you
-% can refer to the choice which was passed in with |#1|.
+% 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}
%
% \subsection{Bugs}
@@ -579,8 +614,8 @@ and the derived files expkv-def.pdf
% ,skip keyI = \keyI
% ,toks keyJ = \keyJ
% ,default keyJ = \empty test
-% ,box keyK = \keyK
-% ,qdefault keyK = text
+% ,new box keyK = \keyK
+% ,qdefault keyK = K
% ,choice keyL =
% {
% protected 1 = \texttt{a}
@@ -591,6 +626,8 @@ and the derived files expkv-def.pdf
% }
% ,edefault keyL = 2
% ,meta keyM = {keyA={#1},keyB=false}
+% ,invbool keyN = \keyN
+% ,boolpair keyO = \keyOa\keyOb
% }
% \end{lstlisting}
%
@@ -718,8 +755,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.5}
-\def\ekvdDate{2020-07-12}
+\def\ekvdVersion{0.6}
+\def\ekvdDate{2020-10-12}
% \end{macrocode}
% \end{macro}
%
@@ -745,8 +782,8 @@ and the derived files expkv-def.pdf
% \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|.
+% |long| and |protected| will just be empty, |ifalso| will be
+% |\@secondoftwo|, and |ifnew| will just use its third argument.
% \begin{macrocode}
\def\ekvd@empty{}
\protected\def\ekvd@clear@prefixes
@@ -754,23 +791,12 @@ and the derived files expkv-def.pdf
\let\ekvd@long\ekvd@empty
\let\ekvd@prot\ekvd@empty
\let\ekvd@ifalso\@secondoftwo
+ \long\def\ekvd@ifnew##1##2##3{##3}%
}
\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
@@ -780,18 +806,28 @@ and the derived files expkv-def.pdf
\protected\def\ekvdefinekeys#1%
{%
\def\ekvd@set{#1}%
- \ekvparse\ekvd@noarg\ekvd@
+ \ekvparse\ekvd@noarg\ekvd@arg
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\ekvd@noarg,\ekvd@}
-% |\ekvd@noarg| just places a special marker and gives control to |\ekvd@|.
-% |\ekvd@| 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{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\def\ekvd@noarg#1{\ekvd@{#1}\ekvd@noarg@mark}
-\protected\long\def\ekvd@#1#2%
+\protected\def\ekvd@noarg#1%
+ {%
+ \let\ekvd@ifnoarg\@firstoftwo
+ \ekvd@handle{#1}{}%
+ }
+\protected\def\ekvd@arg
+ {%
+ \let\ekvd@ifnoarg\@secondoftwo
+ \ekvd@handle
+ }
+\protected\long\def\ekvd@handle#1#2%
{%
\ekvd@clear@prefixes
\edef\ekvd@cur{\detokenize{#1}}%
@@ -839,7 +875,7 @@ and the derived files expkv-def.pdf
% \end{macro}
%
% \begin{macro}[internal]
-% {\ekvd@p@long,\ekvd@p@protected,\ekvd@p@protect,\ekvd@p@also}
+% {\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}
@@ -847,36 +883,45 @@ and the derived files expkv-def.pdf
\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@t@set}
+% \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@t@set#1#2%
+\protected\def\ekvd@type@set#1#2%
{%
\ekvd@assert@not@long
\ekvd@assert@not@protected
- \ekv@ifempty{#2}%
- {\ekvd@err@missing@definition}%
+ \ekvd@ifnew{NoVal}{#1}%
{%
- \ekvd@ifalso
+ \ekv@ifempty{#2}%
+ {\ekvd@err@missing@definition}%
{%
- \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}}}%
+ \ekvd@ifalso
+ {%
+ \ekv@expB@unbraceA{\ekv@expB@unbraceA{\ekvd@add@noval{#1}}}%
+ {\ekvchangeset{#2}}%
+ \ekvd@assert@not@protected@also
+ }%
+ {%
+ \ekv@expB@unbraceA
+ {\ekv@expB@unbraceA{\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}
%
@@ -888,19 +933,22 @@ and the derived files expkv-def.pdf
% |@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#4%
+\protected\long\def\ekvd@type@noval#1#2#3%
{%
- \ekvd@assert@arg{#4}%
+ \ekvd@ifnew{NoVal}{#2}%
{%
- \ekvd@assert@not@long
- \ekvd@prot#2\ekvd@tmp{#4}%
- \ekvd@ifalso
- {\ekvd@exp@Nno\ekvd@add@noval{#3}\ekvd@tmp{}}%
- {\ekvletNoVal\ekvd@set{#3}\ekvd@tmp}%
+ \ekvd@assert@arg
+ {%
+ \ekvd@assert@not@long
+ \ekvd@prot#1\ekvd@tmp{#3}%
+ \ekvd@ifalso
+ {\ekv@expB@unbraceA{\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 e\edef}
+\protected\def\ekvd@t@noval{\ekvd@type@noval\def}
+\protected\def\ekvd@t@enoval{\ekvd@type@noval\edef}
% \end{macrocode}
% \end{macro}
%
@@ -908,18 +956,21 @@ and the derived files expkv-def.pdf
% |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#4%
+\protected\long\def\ekvd@type@code#1#2#3%
{%
- \ekvd@assert@arg{#4}
+ \ekvd@ifnew{}{#2}%
{%
- \ekvd@prot\ekvd@long#2\ekvd@tmp##1{#4}%
- \ekvd@ifalso
- {\ekvd@exp@Nno\ekvd@add@val{#3}{\ekvd@tmp{##1}}{}}%
- {\ekvlet\ekvd@set{#3}\ekvd@tmp}%
+ \ekvd@assert@arg
+ {%
+ \ekvd@prot\ekvd@long#1\ekvd@tmp##1{#3}%
+ \ekvd@ifalso
+ {\ekv@expB@unbraceA{\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 e\edef}
+\protected\def\ekvd@t@code{\ekvd@type@code\def}
+\protected\def\ekvd@t@ecode{\ekvd@type@code\edef}
% \end{macrocode}
% \end{macro}
%
@@ -930,27 +981,28 @@ and the derived files expkv-def.pdf
% 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%
+\protected\long\def\ekvd@type@default#1#2#3%
{%
- \ekvd@assert@arg{#4}%
+ \ekvd@assert@arg
{%
- \ekvifdefined\ekvd@set{#3}%
+ \ekvifdefined\ekvd@set{#2}%
{%
+ \ekvd@assert@not@new
\ekvd@assert@not@long
\ekvd@prot\edef\ekvd@tmp
{%
- \unexpanded\expandafter#2%
- {\csname\ekv@name\ekvd@set{#3}\endcsname{#4}}%
+ \unexpanded\expandafter#1%
+ {\csname\ekv@name\ekvd@set{#2}\endcsname{#3}}%
}%
\ekvd@ifalso
- {\ekvd@exp@Nno\ekvd@add@noval{#3}\ekvd@tmp{}}%
- {\ekvletNoVal\ekvd@set{#3}\ekvd@tmp}%
+ {\ekv@expB@unbraceA{\ekvd@add@noval{#2}}\ekvd@tmp{}}%
+ {\ekvletNoVal\ekvd@set{#2}\ekvd@tmp}%
}%
- {\ekvd@err@undefined@key{#3}}%
+ {\ekvd@err@undefined@key{#2}}%
}%
}
-\protected\def\ekvd@t@default{\ekvd@type@default{}{}}
-\protected\def\ekvd@t@qdefault{\ekvd@type@default q{\expandafter\expandafter}}
+\protected\def\ekvd@t@default{\ekvd@type@default{}}
+\protected\def\ekvd@t@qdefault{\ekvd@type@default{\expandafter\expandafter}}
% \end{macrocode}
% \end{macro}
%
@@ -960,15 +1012,16 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\long\def\ekvd@t@edefault#1#2%
{%
- \ekvd@assert@arg{#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
- {\ekvd@exp@Nno\ekvd@add@noval{#1}\ekvd@tmp{}}%
+ {\ekv@expB@unbraceA{\ekvd@add@noval{#1}}\ekvd@tmp{}}%
{\ekvletNoVal\ekvd@set{#1}\ekvd@tmp}%
}%
{\ekvd@err@undefined@key{#1}}%
@@ -979,115 +1032,150 @@ and the derived files expkv-def.pdf
%
% \begin{macro}[internal]{\ekvd@t@initial,\ekvd@t@oinitial,\ekvd@t@einitial}
% \begin{macrocode}
-\long\def\ekvd@t@initial#1#2%
- {%
- \ekvd@assert@arg{#2}%
- {%
- \ekvifdefined\ekvd@set{#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}}%
- }%
- }
-\long\def\ekvd@t@oinitial#1#2%
+\long\def\ekvd@type@initial#1#2#3%
{%
- \ekvd@assert@arg{#2}%
+ \ekvd@assert@arg
{%
- \ekvifdefined\ekvd@set{#1}%
+ \ekvifdefined\ekvd@set{#2}%
{%
+ \ekvd@assert@not@new
\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}}%
- }%
- }
-\long\def\ekvd@t@einitial#1#2%
- {%
- \ekvd@assert@arg{#2}%
- {%
- \ekvifdefined\ekvd@set{#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
+ #1{#3}%
+ \csname\ekv@name\ekvd@set{#2}\expandafter\endcsname\expandafter
{\ekvd@tmp}%
}%
- {\ekvd@err@undefined@key{#1}}%
+ {\ekvd@err@undefined@key{#2}}%
}%
}
+\def\ekvd@t@initial{\ekvd@type@initial{\def\ekvd@tmp}}
+\def\ekvd@t@oinitial{\ekvd@type@initial{\ekv@expB@unbraceA{\def\ekvd@tmp}}}
+\def\ekvd@t@einitial{\ekvd@type@initial{\edef\ekvd@tmp}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]
-% {\ekvd@type@bool,\ekvd@t@bool,\ekvd@t@gbool,\ekvd@t@boolTF,\ekvd@t@gboolTF}
+% {
+% \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#6#7%
+\protected\def\ekvd@type@bool#1#2#3#4#5%
{%
- \ekvd@assert@filledarg{#7}%
+ \ekvd@ifnew{}{#4}%
{%
- \ekvd@newlet#7#5%
- \ekvd@type@choice{#1bool#2}{#6}%
- \protected\ekvdefNoVal\ekvd@set{#6}{#3\let#7#4}%
- \protected\expandafter\def
- \csname\ekvd@choice@name\ekvd@set{#6}{true}\endcsname
- {#3\let#7#4}%
- \protected\expandafter\def
- \csname\ekvd@choice@name\ekvd@set{#6}{false}\endcsname
- {#3\let#7#5}%
+ \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 g{}\global\iftrue\iffalse}
-\protected\def\ekvd@t@boolTF{\ekvd@type@bool{}{TF}{}\@firstoftwo\@secondoftwo}
-\protected\def\ekvd@t@gboolTF
- {\ekvd@type@bool g{TF}\global\@firstoftwo\@secondoftwo}
+\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@data,\ekvd@t@data,\ekvd@t@gdata,\ekvd@t@dataT,\ekvd@t@gdataT
+% \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@data#1#2#3#4#5#6#7#8%
+\protected\def\ekvd@type@boolpair#1#2#3#4#5#6%
{%
- \ekvd@assert@filledarg{#8}%
+ \ekvd@ifnew{}{#4}%
{%
- \ekvd@newlet#8#3%
- \ekvd@ifalso
+ \ekvd@ifnew{NoVal}{#4}%
{%
- \let\ekvd@prot\protected
- \ekvd@add@val{#7}{\long#4#8####1#5{####1{#6}}}{}%
+ \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}%
{%
- \protected\ekvd@long\ekvdef\ekvd@set{#7}%
- {\long#4#8####1#5{####1{#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}{\unexpanded{##1}}}
-\protected\def\ekvd@t@edata{\ekvd@type@data e{}\@secondoftwo\edef{####2}{##1}}
+ {\ekvd@type@data\@secondoftwo\edef{####2}{\unexpanded{##1}}}
+\protected\def\ekvd@t@edata{\ekvd@type@data\@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}}
+ {\ekvd@type@data\@secondoftwo\xdef{####2}{\unexpanded{##1}}}
+\protected\def\ekvd@t@xdata{\ekvd@type@data\@secondoftwo\xdef{####2}{##1}}
+\protected\def\ekvd@t@dataT{\ekvd@type@data\@gobble\edef{}{\unexpanded{##1}}}
+\protected\def\ekvd@t@edataT{\ekvd@type@data\@gobble\edef{}{##1}}
+\protected\def\ekvd@t@gdataT{\ekvd@type@data\@gobble\xdef{}{\unexpanded{##1}}}
+\protected\def\ekvd@t@xdataT{\ekvd@type@data\@gobble\xdef{}{##1}}
% \end{macrocode}
% \end{macro}
%
@@ -1098,45 +1186,51 @@ and the derived files expkv-def.pdf
% 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#4%
+\protected\def\ekvd@type@box#1#2#3%
{%
- \ekvd@assert@filledarg{#4}%
+ \ekvd@ifnew{}{#2}%
{%
- \ekvd@newreg#4{box}%
- \ekvd@ifalso
- {%
- \let\ekvd@prot\protected
- \ekvd@add@val{#3}{#2\setbox#4\hbox{\begingroup##1\endgroup}}{}%
- }%
+ \ekvd@assert@filledarg{#3}%
{%
- \protected\ekvd@long\ekvdef\ekvd@set{#3}%
- {#2\setbox#4\hbox{\begingroup##1\endgroup}}%
+ \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 g\global}
+\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#4%
+\protected\def\ekvd@type@toks#1#2#3%
{%
- \ekvd@assert@filledarg{#4}%
+ \ekvd@ifnew{}{#2}%
{%
- \ekvd@newreg#4{toks}%
- \ekvd@ifalso
+ \ekvd@assert@filledarg{#3}%
{%
- \let\ekvd@prot\protected
- \ekvd@add@val{#3}{#2#4{##1}}{}%
+ \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\ekvd@long\ekvdef\ekvd@set{#3}{#2#4{##1}}}%
}%
}
-\protected\def\ekvd@t@toks{\ekvd@type@toks{}{}}
-\protected\def\ekvd@t@gtoks{\ekvd@type@toks{g}\global}
+\protected\def\ekvd@t@toks{\ekvd@type@toks{}}
+\protected\def\ekvd@t@gtoks{\ekvd@type@toks\global}
% \end{macrocode}
% \end{macro}
%
@@ -1144,24 +1238,27 @@ and the derived files expkv-def.pdf
% Just like |toks|, but expand the current contents of the |toks| register to
% append the new contents.
% \begin{macrocode}
-\protected\def\ekvd@type@apptoks#1#2#3#4%
+\protected\def\ekvd@type@apptoks#1#2#3%
{%
- \ekvd@assert@filledarg{#4}%
+ \ekvd@ifnew{}{#2}%
{%
- \ekvd@newreg#4{toks}%
- \ekvd@ifalso
- {%
- \let\ekvd@prot\protected
- \ekvd@add@val{#3}{#2#4\expandafter{\the#4##1}}{}%
- }%
+ \ekvd@assert@filledarg{#3}%
{%
- \protected\ekvd@long\ekvdef\ekvd@set{#3}%
- {#2#4\expandafter{\the#4##1}}%
+ \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{g}\global}
+\protected\def\ekvd@t@apptoks{\ekvd@type@apptoks{}}
+\protected\def\ekvd@t@gapptoks{\ekvd@type@apptoks\global}
% \end{macrocode}
% \end{macro}
%
@@ -1174,31 +1271,34 @@ and the derived files expkv-def.pdf
% 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#7%
+\protected\def\ekvd@type@reg#1#2#3#4#5#6%
{%
- \ekvd@assert@filledarg{#7}%
+ \ekvd@ifnew{}{#5}%
{%
- \ekvd@newreg#7{#2}%
- \ekvd@ifalso
+ \ekvd@assert@filledarg{#6}%
{%
- \let\evkd@prot\protected
- \ekvd@add@val{#6}{#3#7=#4##1#5\relax}{}%
+ \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\ekvd@long\ekvdef\ekvd@set{#6}{#3#7=#4##1#5\relax}}%
}%
}
-\protected\def\ekvd@t@int{\ekvd@type@reg{int}{count}{}{}{}}
-\protected\def\ekvd@t@eint{\ekvd@type@reg{eint}{count}{}\numexpr\relax}
-\protected\def\ekvd@t@gint{\ekvd@type@reg{gint}{count}\global{}{}}
-\protected\def\ekvd@t@xint{\ekvd@type@reg{xint}{count}\global\numexpr\relax}
-\protected\def\ekvd@t@dimen{\ekvd@type@reg{dimen}{dimen}{}{}{}}
-\protected\def\ekvd@t@edimen{\ekvd@type@reg{edimen}{dimen}{}\dimexpr\relax}
-\protected\def\ekvd@t@gdimen{\ekvd@type@reg{gdimen}{dimen}\global{}{}}
-\protected\def\ekvd@t@xdimen{\ekvd@type@reg{xdimen}{dimen}\global\dimexpr\relax}
-\protected\def\ekvd@t@skip{\ekvd@type@reg{skip}{skip}{}{}{}}
-\protected\def\ekvd@t@eskip{\ekvd@type@reg{eskip}{skip}{}\glueexpr\relax}
-\protected\def\ekvd@t@gskip{\ekvd@type@reg{gskip}{skip}\global{}{}}
-\protected\def\ekvd@t@xskip{\ekvd@type@reg{xskip}{skip}\global\glueexpr\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}
%
@@ -1208,40 +1308,24 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\def\ekvd@type@store#1#2#3#4%
{%
- \ekvd@assert@filledarg{#4}%
- {%
- \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}
-\protected\def\ekvd@t@gstore{\ekvd@type@store{g}\xdef}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\ekvd@type@estore,\ekvd@t@estore,\ekvd@t@xstore}
-% And the straight forward |estore| types.
-% \begin{macrocode}
-\protected\def\ekvd@type@estore#1#2#3#4%
- {%
- \ekvd@assert@filledarg{#4}%
+ \ekvd@ifnew{}{#3}%
{%
- \ekvd@newlet#4\ekvd@empty
- \ekvd@ifalso
+ \ekvd@assert@filledarg{#4}%
{%
- \let\ekvd@prot\protected
- \ekvd@add@val{#3}{#2#4{##1}}{}%
+ \ekvd@newlet#4\ekvd@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\ekvd@long\ekvdef\ekvd@set{#3}{#2#4{##1}}}%
}%
}
-\protected\def\ekvd@t@estore{\ekvd@type@estore{e}\edef}
-\protected\def\ekvd@t@xstore{\ekvd@type@estore{x}\xdef}
+\protected\def\ekvd@t@store{\ekvd@type@store\edef{\unexpanded{##1}}}
+\protected\def\ekvd@t@gstore{\ekvd@type@store\xdef{\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}
%
@@ -1253,15 +1337,18 @@ 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#6#7#8%
+\protected\long\def\ekvd@type@meta#1#2#3#4#5#6#7%
{%
- \ekvd@assert@filledarg{#8}%
+ \ekvd@ifnew{#1}{#6}%
{%
- \edef\ekvd@tmp{\ekvd@set}%
- \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}%
+ \ekvd@assert@filledarg{#7}%
+ {%
+ \edef\ekvd@tmp{\ekvd@set}%
+ \expandafter\ekvd@type@meta@a\expandafter{\ekvd@tmp}{#7}{#2}%
+ \ekvd@ifalso
+ {\ekv@expB@unbraceA{#3{#6}}{\ekvd@tmp#4}{#5}}%
+ {\csname ekvlet#1\endcsname\ekvd@set{#6}\ekvd@tmp}%
+ }%
}%
}
\protected\long\def\ekvd@type@meta@a#1#2%
@@ -1276,12 +1363,11 @@ 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}\ekvd@add@val{{##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
- n\ekvletNoVal{}\ekvd@add@noval{}\ekvd@assert@not@long@also
+ \ekvd@type@meta{NoVal}{}\ekvd@add@noval{}\ekvd@assert@not@long@also
}
% \end{macrocode}
% \end{macro}
@@ -1292,23 +1378,24 @@ 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#6#7#8%
+\protected\long\def\ekvd@type@smeta#1#2#3#4#5#6#7%
{%
- \ekvd@assert@twoargs{#8}%
+ \ekvd@ifnew{#1}{#6}%
{%
- \ekvd@type@meta@a#8{#3}%
- \ekvd@ifalso
- {\ekvd@exp@Nno#4{#7}{\ekvd@tmp#5}{#6}}%
- {#2\ekvd@set{#7}\ekvd@tmp}%
+ \ekvd@assert@twoargs{#7}%
+ {%
+ \ekvd@type@meta@a#7{#2}%
+ \ekvd@ifalso
+ {\ekv@expB@unbraceA{#3{#6}}{\ekvd@tmp#4}{#5}}%
+ {\csname ekvlet#1\endcsname\ekvd@set{#6}\ekvd@tmp}%
+ }%
}%
}
-\protected\def\ekvd@t@smeta
- {\ekvd@type@smeta{}\ekvlet{##1}\ekvd@add@val{{##1}}{}}
+\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
- n\ekvletNoVal{}\ekvd@add@noval{}\ekvd@assert@not@long@also
+ \ekvd@type@smeta{NoVal}{}\ekvd@add@noval{}\ekvd@assert@not@long@also
}
% \end{macrocode}
% \end{macro}
@@ -1326,18 +1413,28 @@ and the derived files expkv-def.pdf
% 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#2%
+\protected\def\ekvd@type@choice#1%
{%
\ekvd@assert@not@long
\ekvd@prot\edef\ekvd@tmp##1%
- {%
- \unexpanded{\ekvd@h@choice}{\ekvd@choice@name\ekvd@set{#2}{##1}}%
- }%
+ {\unexpanded{\ekvd@h@choice}{\ekvd@choice@name\ekvd@set{#1}{##1}}}%
\ekvd@ifalso
{%
- \ekvd@exp@Nno\ekvd@add@val{#2}{\ekvd@tmp{##1}}\ekvd@assert@not@long@also
+ \ekvd@assert@val{#1}%
+ {%
+ \ekvd@if@not@already@choice{#1}%
+ {%
+ \ekv@expB@unbraceA
+ {%
+ \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{#2}\ekvd@tmp}%
+ {\ekvlet\ekvd@set{#1}\ekvd@tmp}%
}
% \end{macrocode}
% |\ekvd@populate@choice| just uses |\ekvparse| and then gives control to
@@ -1362,7 +1459,7 @@ and the derived files expkv-def.pdf
\protected\long\def\ekvd@populate@choice@#1#2%
{%
\ekvd@clear@prefixes
- \expandafter\ekvd@assert@arg@msg\expandafter{\ekvd@cur : #1}{#2}%
+ \expandafter\ekvd@assert@arg@msg\expandafter{\ekvd@cur : #1}%
{%
\ekvd@ifspace{#1}%
{\ekvd@choice@prefix\ekv@mark#1\ekv@stop}%
@@ -1406,17 +1503,21 @@ and the derived files expkv-def.pdf
}
\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@assert@arg{#2}%
+ \ekvd@ifnew{}{#1}%
{%
- \ekvd@type@choice{choice}{#1}%
- \def\ekvd@set@choice{#1}%
- \ekvd@populate@choice{#2}%
+ \ekvd@assert@arg
+ {%
+ \ekvd@type@choice{#1}%
+ \def\ekvd@set@choice{#1}%
+ \ekvd@populate@choice{#2}%
+ }%
}%
}
% \end{macrocode}
@@ -1426,12 +1527,20 @@ and the derived files expkv-def.pdf
% \begin{macrocode}
\protected\long\expandafter\def\csname ekvd@t@unknown-choice\endcsname#1#2%
{%
- \ekvd@assert@arg{#2}%
+ \ifx\ekvd@ifnew\ekvd@assert@new
+ \ekv@fi@firstoftwo
+ \fi
+ \@secondoftwo
+ {\ekv@ifdefined{\ekvd@unknown@choice@name\ekvd@set{#1}}\ekvd@err@not@new}%
+ \@firstofone
{%
- \ekvd@assert@not@long
- \ekvd@assert@not@also
- \ekvd@prot\expandafter
- \def\csname\ekvd@unknown@choice@name\ekvd@set{#1}\endcsname##1{#2}%
+ \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}
@@ -1644,30 +1753,14 @@ and the derived files expkv-def.pdf
% \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{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}
-\long\def\ekvd@assert@arg#1{\ekvd@ifnoarg{#1}\ekvd@err@missing@definition}
-\long\def\ekvd@assert@arg@msg#1#2%
+\def\ekvd@assert@arg{\ekvd@ifnoarg\ekvd@err@missing@definition}
+\long\def\ekvd@assert@arg@msg#1%
{%
- \ekvd@ifnoarg{#2}{\ekvd@err@missing@definition@msg{#1}}%
- }
-\long\def\ekvd@ifnoarg#1%
- {%
- \ekvd@ifnoarg@\ekvd@ifnoarg@mark#1\ekvd@ifnoarg@mark\ekvd@ifnoarg@t
- \ekvd@ifnoarg@mark\ekvd@noarg@mark\ekvd@ifnoarg@mark\@secondoftwo
- }
-\long\def\ekvd@ifnoarg@#1\ekvd@ifnoarg@mark\ekvd@noarg@mark\ekvd@ifnoarg@mark{}
-\long\def\ekvd@ifnoarg@t
- \ekvd@ifnoarg@mark\ekvd@noarg@mark\ekvd@ifnoarg@mark\@secondoftwo#1#2%
- {%
- #1%
+ \ekvd@ifnoarg{\ekvd@err@missing@definition@msg{#1}}%
}
% \end{macrocode}
% \end{macro}
@@ -1680,7 +1773,7 @@ and the derived files expkv-def.pdf
}
\long\def\ekvd@ifnoarg@or@empty#1%
{%
- \ekvd@ifnoarg{#1}%
+ \ekvd@ifnoarg
\@firstoftwo
{\ekv@ifempty{#1}}%
}
@@ -1690,7 +1783,8 @@ and the derived files expkv-def.pdf
% \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@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
@@ -1699,17 +1793,41 @@ and the derived files expkv-def.pdf
% \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
- }
+ {\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}
+% \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%
{%
- \ifx\ekvd@long\long\ekvd@err@no@prefix@also{long}\fi
+ \expandafter\ekvd@if@not@already@choice@a
+ \csname\ekv@name\ekvd@set{#1}\endcsname
+ {}\ekvd@h@choice\ekvd@stop
}
-\def\ekvd@assert@not@protected@also
+\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
{%
- \ifx\ekvd@prot\protected\ekvd@err@no@prefix@also{protected}\fi
+ \ekv@ifempty{#2}\@firstofone\@gobble
}
% \end{macrocode}
% \end{macro}
@@ -1741,7 +1859,7 @@ and the derived files expkv-def.pdf
% \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@unsupported@arg,\ekvd@err@not@new
% }
% The non-expandable error messages are boring, so here they are:
% \begin{macrocode}
@@ -1781,6 +1899,8 @@ and the derived files expkv-def.pdf
`\ekvd@extracted@args' for key `\ekvd@cur'%
}%
}
+\protected\def\ekvd@err@not@new
+ {\ekvd@errm{The key for `\ekvd@cur' is already defined}}
% \end{macrocode}
% \end{macro}
%