texlive[53939] Master/texmf-dist: expkv (27feb20)
commits+karl at tug.org
commits+karl at tug.org
Thu Feb 27 23:05:11 CET 2020
Revision: 53939
http://tug.org/svn/texlive?view=revision&revision=53939
Author: karl
Date: 2020-02-27 23:05:11 +0100 (Thu, 27 Feb 2020)
Log Message:
-----------
expkv (27feb20)
Modified Paths:
--------------
trunk/Master/texmf-dist/doc/latex/expkv/README.md
trunk/Master/texmf-dist/doc/latex/expkv/expkv.pdf
trunk/Master/texmf-dist/source/latex/expkv/expkv.dtx
trunk/Master/texmf-dist/tex/generic/expkv/expkv.tex
Modified: trunk/Master/texmf-dist/doc/latex/expkv/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/expkv/README.md 2020-02-27 22:04:59 UTC (rev 53938)
+++ trunk/Master/texmf-dist/doc/latex/expkv/README.md 2020-02-27 22:05:11 UTC (rev 53939)
@@ -1,7 +1,7 @@
-------------------------------------------------------------------------------
# expkv -- an expandable key=val implementation
-Version 2020-02-22 v0.4
+Version 2020-02-27 v0.5a
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
@@ -29,3 +29,7 @@
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
Modified: trunk/Master/texmf-dist/doc/latex/expkv/expkv.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/source/latex/expkv/expkv.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/expkv/expkv.dtx 2020-02-27 22:04:59 UTC (rev 53938)
+++ trunk/Master/texmf-dist/source/latex/expkv/expkv.dtx 2020-02-27 22:05:11 UTC (rev 53939)
@@ -85,7 +85,7 @@
\ekvdef,\ekvdefNoVal,\ekvlet,\ekvletNoVal,\ekvletkv,\ekvletkvNoVal,^^A
\ekvset,\ekvparse,\ekvVersion,\ekvDate,\ekvifdefined,^^A
\ekvifdefinedNoVal,\ekvbreak,\ekvbreakPreSneak,\ekvbreakPostSneak,^^A
- \ekvsneak,\ekvsneakPre
+ \ekvsneak,\ekvsneakPre,\ekvchangeset
}
,morecomment=[l]\%
,commentstyle=\color[gray]{0.4}
@@ -108,6 +108,27 @@
\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
\rmfamily
\bfseries
{\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
@@ -114,10 +135,13 @@
\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
\EndAccSupp{}^^A
}^^A
}
- {expkv}^^A
+ {expkv-def}^^A
}
\newcommand\kv{\meta{key}=\meta{value}}
\newcommand\key{\meta{key}}
@@ -149,9 +173,7 @@
{^^A
\texorpdfstring
{^^A
- \huge
- \href{https://github.com/Skillmon/tex_expkv}
- {\expkv}^^A
+ \huge\expkv
\\[\medskipamount]
\Large an expandable \kv\ implementation^^A
}{expkv - an expandable <key>=<value> implementation}^^A
@@ -199,6 +221,12 @@
% |\ProvidesFile|.
%
% \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
+% \href{https://github.com/Skillmon/tex_expkv-def}{\expkvd} (the files use
+% \file{expkv-def} instead because \string| isn't allowed in package names by
+% CTAN) 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
@@ -292,11 +320,11 @@
% If you need control over the necessary steps of expansion you
% can use |\expanded| around it.
%
-% |\ekvbreak| and |\ekvsneak| 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.
+% |\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.
%
% As a small example:
% \begin{lstlisting}
@@ -372,6 +400,17 @@
% \autoref{sec:sneakex}.
% \end{function}
%
+% \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}}. Just like |\ekvsneak| this
+% reads and reinserts the remainder of the current |\ekvset| macro to do its
+% job. It is comparable to using \texttt{\meta{key}/.cd} in \pkg{pgfkeys}.
+% \end{function}
+%
% \bigskip
%
% \begin{function}{\ekv at name,\ekv at name@set,\ekv at name@key}
@@ -606,6 +645,22 @@
% \ourmacro{width=5pt}\par
% \end{minipage}
%
+% \paragraph{The same key 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{An Expandable \kv\ Macro Using \cs[no-index]{ekvsneak}}
% \label{sec:sneakex}
%
@@ -794,7 +849,7 @@
% \begin{lstlisting}
% ! Missing \endcsname inserted.
% <to be read again>
-% \ekv<set>(
+% \! expkv Error: Set `<set>' undefined.
% \end{lstlisting}
%
% \subsection{License}
@@ -866,8 +921,8 @@
% \begin{macro}{\ekvVersion,\ekvDate}
% We're on our first input, so lets store the version and date in a macro.
% \begin{macrocode}
-\def\ekvVersion{0.4}
-\def\ekvDate{2020-02-22}
+\def\ekvVersion{0.5a}
+\def\ekvDate{2020-02-27}
% \end{macrocode}
% \end{macro}
%
@@ -893,7 +948,7 @@
% \begin{macro}[internal]
% {
% \@gobble,\@firstofone,\@firstoftwo,\@secondoftwo,
-% \ekv at gobbletostop,\ekv at fi@gobble,\ekv at fi@secondoftwo
+% \ekv at gobbleto@stop,\ekv at fi@secondoftwo,\ekv at gobble@mark
% }
% Since branching tests are often more versatile than |\if...\else...\fi|
% constructs, we define helpers that are branching pretty fast. Also here are
@@ -904,12 +959,12 @@
\long\def\@firstofone#1{#1}
\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
-\long\def\ekv at gobbletostop#1\ekv at stop{}
-\long\def\ekv at fi@gobble\fi\@firstofone#1{\fi}
\long\def\ekv at fi@secondoftwo\fi\@firstoftwo#1#2{\fi#2}
+\long\def\ekv at gobbleto@stop#1\ekv at stop{}
+\def\ekv at gobble@mark\ekv at mark{}
% \end{macrocode}
% \end{macro}
-% As you can see |\ekv at gobbletostop| uses a special marker |\ekv at stop|. The
+% As you can see |\ekv at gobbleto@stop| uses a special marker |\ekv at stop|. The
% package will use three such markers, the one you've seen already, |\ekv at mark|
% and |\ekv at 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
@@ -1021,6 +1076,18 @@
\def\ekv at name@key#1{#1)}
% \end{macrocode}
% \end{macro}
+% \begin{macro}[internal]{\ekv at 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 at 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 at undefined@set#1{! expkv Error: Set `#1' undefined.}
+% \end{macrocode}
+% \end{macro}
% \begin{macro}[internal]{\ekv at 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-
@@ -1116,7 +1183,7 @@
% \begin{macrocode}
\protected\def\ekv at defset#1%
{%
- \expandafter\edef\csname\ekv at name@set{#1}\endcsname##1%
+ \expandafter\edef\csname\ekv at undefined@set{#1}\endcsname##1%
{\ekv at name@set{#1}\ekv at name@key{##1}}%
}
% \end{macrocode}
@@ -1134,7 +1201,7 @@
\endgroup
\long\def\ekvset##1##2%
{%
- \expandafter\ekv at set\csname\ekv at name@set{##1}\endcsname
+ \expandafter\ekv at set\csname\ekv at undefined@set{##1}\endcsname
\ekv at mark##2#1\ekv at stop#1{}%
}
% \end{macrocode}
@@ -1148,7 +1215,7 @@
% \end{macrocode}
% Test whether we're at the end, if so invoke |\ekv at endset|,
% \begin{macrocode}
- \ekv at ifstop##2\ekv at endset\ekv at mark\ekv at stop
+ \ekv at gobbleto@markstop##2\ekv at endset\ekv at mark\ekv at stop
% \end{macrocode}
% else go on with other commas,
% \begin{macrocode}
@@ -1179,7 +1246,7 @@
% \begin{macrocode}
\long\def\ekv at set@other##1##2,%
{%
- \ekv at ifstop##2\ekv at endset@other\ekv at mark\ekv at stop
+ \ekv at gobbleto@markstop##2\ekv at endset@other\ekv at mark\ekv at stop
\ekv at ifhas@eq at other##2=\ekv at ifempty@B\ekv at ifempty@false
\ekv at ifempty@A\ekv at ifempty@B\@firstoftwo
{\ekv at set@eq at other##1##2\ekv at stop}%
@@ -1278,7 +1345,7 @@
% \begin{macrocode}
\long\def\ekv at parse##1##2##3#1%
{%
- \ekv at ifstop##3\ekv at endparse\ekv at mark\ekv at stop
+ \ekv at gobbleto@markstop##3\ekv at endparse\ekv at mark\ekv at stop
\ekv at parse@other##1##2##3,\ekv at stop,%
\ekv at parse##1##2\ekv at mark
}
@@ -1295,7 +1362,7 @@
% \begin{macrocode}
\long\def\ekv at parse@other##1##2##3,%
{%
- \ekv at ifstop##3\ekv at endparse@other\ekv at mark\ekv at stop
+ \ekv at gobbleto@markstop##3\ekv at endparse@other\ekv at mark\ekv at stop
\ekv at ifhas@eq at other##3=\ekv at ifempty@B\ekv at ifempty@false
\ekv at ifempty@A\ekv at ifempty@B\@firstoftwo
{\ekv at parse@eq at other##3\ekv at stop##2}%
@@ -1373,15 +1440,43 @@
\ekvset,=
% \end{macrocode}
%
-% \begin{macro}[internal]{\ekv at ifstop}
-% The |\ekv at ifstop| test works similar to our if-empty test, but instead of
-% using tokens which are used nowhere else (|\ekv at ifempty@A| and
-% |\ekv at ifempty@B|) we use |\ekv at mark| and |\ekv at stop|.
+% \begin{macro}{\ekvchangeset}
+% Provide a macro that is able to switch out the current \set\ in |\ekvset|.
+% This operation is slow (by comparison, it should be slightly faster than
+% |\ekvsneak|), but allows for something similar to \pkg{pgfkeys}'s
+% \texttt{\meta{key}/.cd} mechanism. However this operation is 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 the remainder of the \kv\ list.
% \begin{macrocode}
-\long\def\ekv at ifstop#1\ekv at mark\ekv at stop{}
+\def\ekvchangeset#1%
+ {%
+ \expandafter\ekv at changeset\csname\ekv at undefined@set{#1}\endcsname\ekv at mark
+ }
% \end{macrocode}
% \end{macro}
+% \begin{macro}[internal]{\ekv at changeset}
+% This macro does the real change-out of |\ekvchangeset|. We introduced an
+% |\ekv at mark| to not accidentally remove some braces which we have to remove
+% again.
+% \begin{macrocode}
+\long\def\ekv at changeset#1#2\ekv at set@other#3#4\ekv at set#5%
+ {%
+ \ekv at gobble@mark#2\ekv at set@other#1#4\ekv at set#1%
+ }
+% \end{macrocode}
+% \end{macro}
%
+%
+% \begin{macro}[internal]{\ekv at gobbleto@markstop}
+% The |\ekv at gobbleto@markstop| can be used to test for |\ekv at stop| similar to
+% our if-empty test, but instead of using tokens which are used nowhere else
+% (|\ekv at ifempty@A| and |\ekv at ifempty@B|) it uses |\ekv at mark| and |\ekv at stop|.
+% \begin{macrocode}
+\long\def\ekv at gobbleto@markstop#1\ekv at mark\ekv at stop{}
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}[internal]{\ekv at set@pair,\ekv at set@pair@}
% |\ekv at set@pair| gets invoked with the space and brace stripped key-name as its
% first argument, the set-macro as the second argument, and following that is
@@ -1400,7 +1495,7 @@
\ekv at err@noarg
\ekv at err@unknown
#2{#1}%
- \ekv at gobbletostop
+ \ekv at gobbleto@stop
}%
}
% \end{macrocode}
@@ -1452,7 +1547,7 @@
}%
}
\ekv at err
-\def\ekv at err@{\expandafter\ekv at gobbletostop}
+\def\ekv at err@{\expandafter\ekv at gobbleto@stop}
% \end{macrocode}
% \end{macro}
% \begin{macro}[internal]
@@ -1464,7 +1559,7 @@
% use those instead of the full strings.
% \begin{macrocode}
\long\def\ekv at err@common #1#2{\expandafter\ekv at err@common@\string#2{#1}}
-\long\def\ekv at err@common@#1#2#3#4#5(#6#7{\ekv at err{#6 (`#7', set `#5')}}
+\long\def\ekv at err@common@#1`#2' #3.#4#5{\ekv at err{#4 (`#5', set `#2')}}
\long\def\ekv at err@unknown#1#2{\ekv at err@common{unknown key}#1{#2}}
\long\def\ekv at err@noarg #1#2{\ekv at err@common{value forbidden}#1{#2}}
\long\def\ekv at err@reqval #1#2{\ekv at err@common{value required}#1{#2}}
Modified: trunk/Master/texmf-dist/tex/generic/expkv/expkv.tex
===================================================================
--- trunk/Master/texmf-dist/tex/generic/expkv/expkv.tex 2020-02-27 22:04:59 UTC (rev 53938)
+++ trunk/Master/texmf-dist/tex/generic/expkv/expkv.tex 2020-02-27 22:05:11 UTC (rev 53939)
@@ -39,8 +39,8 @@
\else
\expandafter\endinput
\fi
-\def\ekvVersion{0.4}
-\def\ekvDate{2020-02-22}
+\def\ekvVersion{0.5a}
+\def\ekvDate{2020-02-27}
\csname ekv at tmp\endcsname
\expandafter\chardef\csname ekv at tmp\endcsname=\catcode`\@
\catcode`\@=11
@@ -48,9 +48,9 @@
\long\def\@firstofone#1{#1}
\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
-\long\def\ekv at gobbletostop#1\ekv at stop{}
-\long\def\ekv at fi@gobble\fi\@firstofone#1{\fi}
\long\def\ekv at fi@secondoftwo\fi\@firstoftwo#1#2{\fi#2}
+\long\def\ekv at gobbleto@stop#1\ekv at stop{}
+\def\ekv at gobble@mark\ekv at mark{}
\long\def\ekv at ifempty#1%
{%
\ekv at ifempty@\ekv at ifempty@A#1\ekv at ifempty@B\ekv at ifempty@true
@@ -110,6 +110,7 @@
\def\ekv at name#1#2{\ekv at name@set{#1}\ekv at name@key{#2}}
\def\ekv at name@set#1{ekv#1(}
\def\ekv at name@key#1{#1)}
+\def\ekv at undefined@set#1{! expkv Error: Set `#1' undefined.}
\protected\def\ekv at checkvalid#1#2%
{%
\ekv at ifempty{#1}%
@@ -181,7 +182,7 @@
}
\protected\def\ekv at defset#1%
{%
- \expandafter\edef\csname\ekv at name@set{#1}\endcsname##1%
+ \expandafter\edef\csname\ekv at undefined@set{#1}\endcsname##1%
{\ekv at name@set{#1}\ekv at name@key{##1}}%
}
\def\ekvset#1#2{%
@@ -188,12 +189,12 @@
\endgroup
\long\def\ekvset##1##2%
{%
- \expandafter\ekv at set\csname\ekv at name@set{##1}\endcsname
+ \expandafter\ekv at set\csname\ekv at undefined@set{##1}\endcsname
\ekv at mark##2#1\ekv at stop#1{}%
}
\long\def\ekv at set##1##2#1%
{%
- \ekv at ifstop##2\ekv at endset\ekv at mark\ekv at stop
+ \ekv at gobbleto@markstop##2\ekv at endset\ekv at mark\ekv at stop
\ekv at set@other##1##2,\ekv at stop,%
\ekv at set##1\ekv at mark
}
@@ -203,7 +204,7 @@
{##3}
\long\def\ekv at set@other##1##2,%
{%
- \ekv at ifstop##2\ekv at endset@other\ekv at mark\ekv at stop
+ \ekv at gobbleto@markstop##2\ekv at endset@other\ekv at mark\ekv at stop
\ekv at ifhas@eq at other##2=\ekv at ifempty@B\ekv at ifempty@false
\ekv at ifempty@A\ekv at ifempty@B\@firstoftwo
{\ekv at set@eq at other##1##2\ekv at stop}%
@@ -256,7 +257,7 @@
}
\long\def\ekv at parse##1##2##3#1%
{%
- \ekv at ifstop##3\ekv at endparse\ekv at mark\ekv at stop
+ \ekv at gobbleto@markstop##3\ekv at endparse\ekv at mark\ekv at stop
\ekv at parse@other##1##2##3,\ekv at stop,%
\ekv at parse##1##2\ekv at mark
}
@@ -265,7 +266,7 @@
{}
\long\def\ekv at parse@other##1##2##3,%
{%
- \ekv at ifstop##3\ekv at endparse@other\ekv at mark\ekv at stop
+ \ekv at gobbleto@markstop##3\ekv at endparse@other\ekv at mark\ekv at stop
\ekv at ifhas@eq at other##3=\ekv at ifempty@B\ekv at ifempty@false
\ekv at ifempty@A\ekv at ifempty@B\@firstoftwo
{\ekv at parse@eq at other##3\ekv at stop##2}%
@@ -316,7 +317,15 @@
\catcode`\,=13
\catcode`\==13
\ekvset,=
-\long\def\ekv at ifstop#1\ekv at mark\ekv at stop{}
+\def\ekvchangeset#1%
+ {%
+ \expandafter\ekv at changeset\csname\ekv at undefined@set{#1}\endcsname\ekv at mark
+ }
+\long\def\ekv at changeset#1#2\ekv at set@other#3#4\ekv at set#5%
+ {%
+ \ekv at gobble@mark#2\ekv at set@other#1#4\ekv at set#1%
+ }
+\long\def\ekv at gobbleto@markstop#1\ekv at mark\ekv at stop{}
\long\def\ekv at set@pair#1#2%
{%
\ekv at ifdefined@pair#2{#1}%
@@ -325,7 +334,7 @@
\ekv at err@noarg
\ekv at err@unknown
#2{#1}%
- \ekv at gobbletostop
+ \ekv at gobbleto@stop
}%
}
\long\def\ekv at set@pair@#1#2\ekv at stop
@@ -354,9 +363,9 @@
}%
}
\ekv at err
-\def\ekv at err@{\expandafter\ekv at gobbletostop}
+\def\ekv at err@{\expandafter\ekv at gobbleto@stop}
\long\def\ekv at err@common #1#2{\expandafter\ekv at err@common@\string#2{#1}}
-\long\def\ekv at err@common@#1#2#3#4#5(#6#7{\ekv at err{#6 (`#7', set `#5')}}
+\long\def\ekv at err@common@#1`#2' #3.#4#5{\ekv at err{#4 (`#5', set `#2')}}
\long\def\ekv at err@unknown#1#2{\ekv at err@common{unknown key}#1{#2}}
\long\def\ekv at err@noarg #1#2{\ekv at err@common{value forbidden}#1{#2}}
\long\def\ekv at err@reqval #1#2{\ekv at err@common{value required}#1{#2}}
More information about the tex-live-commits
mailing list.