From c1252f450552a194da49008918e3def7e6aff6a0 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 10 Apr 2021 21:09:57 +0000 Subject: expkv-def (10apr21) git-svn-id: svn://tug.org/texlive/trunk@58814 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/expkv-def/README.md | 4 +- .../texmf-dist/doc/latex/expkv-def/expkv-def.pdf | Bin 379054 -> 390122 bytes .../source/latex/expkv-def/expkv-def.dtx | 208 ++++++++++++++++++--- .../texmf-dist/tex/generic/expkv-def/expkv-def.tex | 104 +++++++++-- .../texmf-dist/tex/latex/expkv-def/expkv-def.sty | 2 +- 5 files changed, 272 insertions(+), 46 deletions(-) diff --git a/Master/texmf-dist/doc/latex/expkv-def/README.md b/Master/texmf-dist/doc/latex/expkv-def/README.md index ffea8dd5ca4..f2c9e9cfacf 100644 --- a/Master/texmf-dist/doc/latex/expkv-def/README.md +++ b/Master/texmf-dist/doc/latex/expkv-def/README.md @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------- # expkv-def -- a key-defining frontend for expkv -Version 2020-12-28 v0.7 +Version 2021-04-10 v0.8 Released under the LaTeX Project Public License v1.3c or later See http://www.latex-project.org/lppl.txt @@ -10,7 +10,7 @@ Hosted at https://github.com/Skillmon/tex_expkv-def ------------------------------------------------------------------------------- -Copyright (C) 2020 Jonathan P. Spratte +Copyright (C) 2020-2021 Jonathan P. Spratte This work may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this license or diff --git a/Master/texmf-dist/doc/latex/expkv-def/expkv-def.pdf b/Master/texmf-dist/doc/latex/expkv-def/expkv-def.pdf index 727d6c43d4a..b483ade6c11 100644 Binary files a/Master/texmf-dist/doc/latex/expkv-def/expkv-def.pdf and b/Master/texmf-dist/doc/latex/expkv-def/expkv-def.pdf differ 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 5edf48780c5..eaec17b22c0 100644 --- a/Master/texmf-dist/source/latex/expkv-def/expkv-def.dtx +++ b/Master/texmf-dist/source/latex/expkv-def/expkv-def.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% File: expkv-def.dtx Copyright (C) 2020 Jonathan P. Spratte +% File: expkv-def.dtx Copyright (C) 2020-2021 Jonathan P. Spratte % % This work may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this license or @@ -27,7 +27,7 @@ Released under the LaTeX Project Public License v1.3c or later See http://www.latex-project.org/lppl.txt -------------------------------------------------------------- -Copyright (C) 2020 Jonathan P. Spratte +Copyright (C) 2020-2021 Jonathan P. Spratte This work may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this license or @@ -600,6 +600,64 @@ and the derived files expkv-def.pdf % you can refer to the choice which was passed in with |#1|. % \end{function} % +% \begin{function}{unknown code} +% \begin{syntax} +% unknown code = \marg{definition} \prefixes2322 +% \end{syntax} +% By default \expkv\ throws errors when it encounters unknown keys in a set. +% With the |unknown| prefix you can define handlers that deal with undefined +% keys, instead of a \key\ name you have to specify a subtype for this prefix, +% here the subtype is |code|.\par +% With |unknown code| the \meta{definition} is used for unknown keys which +% were provided a value (so corresponds to |\ekvdefunknown|), you can access +% the key name with |#1| and the value with |#2|.\footnotemark +% \end{function} +% \footnotetext +% {^^A +% There is some trickery involved to get this more intuitive argument order +% without any performance hit if you compare this to +% \cs[no-index]{ekvdefunknown} directly.^^A +% } +% +% \begin{function}{unknown noval} +% \begin{syntax} +% unknown noval = \marg{definition} \prefixes2323 +% \end{syntax} +% This is like |unknown code| but uses \meta{definition} for unknown keys to +% which no value was passed (so corresponds to |\ekvdefunknownNoVal|). You can +% access the key name with |#1|. +% \end{function} +% +% \begin{function}{unknown redirect-code} +% \begin{syntax} +% unknown redirect-code = \marg{set-list} \prefixes2331 +% \end{syntax} +% This uses a predefined action for |unknown code|. Instead of throwing an +% error, it is tried to find the \key\ in each \set\ in the comma separated +% \meta{set-list}. The first found match will be used and the remaining +% options from the list discarded. If the \key\ isn't found in any \set\ an +% expandable error will be thrown eventually. Internally \expkv's +% |\ekvredirectunknown| will be used. +% \end{function} +% +% \begin{function}{unknown redirect-noval} +% \begin{syntax} +% unknown redirect-noval = \marg{set-list} \prefixes2333 +% \end{syntax} +% This behaves just like |unknown redirect-code| but will set up means to +% forward keys for |unknown noval|. Internally \expkv's +% |\ekvredirectunknownNoVal| will be used. +% \end{function} +% +% \begin{function}{unknown redirect} +% \begin{syntax} +% unknown redirect = \marg{set-list} \prefixes2333 +% \end{syntax} +% This is a short cut to apply both, |unknown redirect-code| and +% |unknown redirect-noval|, as a result you might get doubled error messages, +% one from each. +% \end{function} +% % \subsection{Bugs} % I don't think there are any (but every developer says that), if you find some % please let me know, either via the email address on the first page or on @@ -766,8 +824,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.7} -\def\ekvdDate{2020-12-28} +\def\ekvdVersion{0.8} +\def\ekvdDate{2021-04-10} % \end{macrocode} % \end{macro} % @@ -1543,12 +1601,7 @@ and the derived files expkv-def.pdf % \begin{macrocode} \protected\long\expandafter\def\csname ekvd@t@unknown-choice\endcsname#1#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@new@for@name{\ekvd@unknown@choice@name\ekvd@set{#1}}% {% \ekvd@assert@arg {% @@ -1562,6 +1615,103 @@ and the derived files expkv-def.pdf % \end{macrocode} % \end{macro} % +% \begin{macro}[internal] +% {\ekvd@t@unknown,\ekvd@type@unknown@code,\ekvd@type@unknown@noval} +% The |unknown| type has different subtypes which would be the key names for +% other types. It is first checked whether that subtype is defined, if it +% isn't throw an error, else use that subtype. +% \begin{macrocode} +\protected\long\def\ekvd@t@unknown#1#2% + {% + \ekv@ifdefined{ekvd@type@unknown@\detokenize{#1}}% + {\csname ekvd@type@unknown@\detokenize{#1}\endcsname{#2}}% + \ekvd@err@misused@unknown + } +% \end{macrocode} +% The |unknown noval| type can use |\ekvdefunknownNoVal| directly (after +% asserting some prefixes). +% \begin{macrocode} +\protected\long\def\ekvd@type@unknown@noval#1% + {% + \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}uN}% + {% + \ekvd@assert@arg + {% + \ekvd@assert@not@also + \ekvd@assert@not@long + \ekvd@prot\ekvdefunknownNoVal\ekvd@set{#1}% + }% + }% + } +% \end{macrocode} +% The |unknown code| type uses some trickery during the definition in order to +% swap out |#1| and |#2| in the user supplied definition. This is done via a +% temporary macro that stores the definition but gets the parameter numbers +% reversed while the real definition is done. +% \begin{macrocode} +\protected\long\def\ekvd@type@unknown@code#1% + {% + \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}u}% + {% + \ekvd@assert@arg + {% + \ekvd@assert@not@also + \begingroup + \def\ekvd@tmp##1##2{#1}% + \ekv@exparg + {% + \endgroup + \ekvd@prot\ekvd@long\ekvdefunknown\ekvd@set + }% + {\ekvd@tmp{##2}{##1}}% + }% + }% + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal] +% { +% \ekvd@type@unknown@redirect, +% \ekvd@type@unknown@redirect-code, +% \ekvd@type@unknown@redirect-noval +% } +% The |unknown redirect| types also just forward to |\ekvredirectunknown| +% after asserting some prefixes. +% \begin{macrocode} +\protected\edef\ekvd@type@unknown@redirect#1% + {% + \expandafter\noexpand\csname ekvd@type@unknown@redirect-code\endcsname{#1}% + \expandafter\noexpand\csname ekvd@type@unknown@redirect-noval\endcsname{#1}% + } +\protected\expandafter\def\csname ekvd@type@unknown@redirect-code\endcsname#1% + {% + \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}u}% + {% + \ekvd@assert@arg + {% + \ekvd@assert@not@also + \ekvd@assert@not@protected + \expandafter\ekvredirectunknown\expandafter{\ekvd@set}{#1}% + }% + }% + } +\protected\expandafter\def\csname ekvd@type@unknown@redirect-noval\endcsname#1% + {% + \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}uN}% + {% + \ekvd@assert@arg + {% + \ekvd@assert@not@also + \ekvd@assert@not@protected + \ekvd@assert@not@long + \expandafter\ekvredirectunknownNoVal\expandafter{\ekvd@set}{#1}% + }% + }% + } +% \end{macrocode} +% \end{macro} +% % \subsubsection{Key Type Helpers} % There are some keys that might need helpers during their execution (not during % their definition, which are gathered as |@type@| macros). These helpers are @@ -1819,6 +1969,15 @@ and the derived files expkv-def.pdf {\csname ekvifdefined#1\endcsname\ekvd@set{#2}{\ekvd@err@not@new}} \def\ekvd@assert@not@new {\ifx\ekvd@ifnew\ekvd@assert@new\ekvd@err@no@prefix{new}\fi} +\def\ekvd@assert@new@for@name#1% + {% + \ifx\ekvd@ifnew\ekvd@assert@new + \ekv@fi@firstoftwo + \fi + \@secondoftwo + {\ekv@ifdefined{#1}\ekvd@err@not@new}% + \@firstofone + } % \end{macrocode} % \end{macro} % @@ -1917,17 +2076,16 @@ and the derived files expkv-def.pdf } \protected\def\ekvd@err@not@new {\ekvd@errm{The key for `\ekvd@cur' is already defined}} +\protected\long\def\ekvd@err@misused@unknown + {\ekvd@errm{Misuse of the unknown type found while processing `\ekvd@cur'}} % \end{macrocode} % \end{macro} % % \begin{macro}[internal] % { % \ekvd@err@choice@invalid,\ekvd@err@choice@invalid@,\ekvd@choice@name, -% \ekvd@unknown@choice@name,\ekvd@err +% \ekvd@unknown@choice@name % } -% The expandable error messages use |\ekvd@err|, which is just like |\ekv@err| -% from \expkv\ or the way \pkg{expl3} throws expandable error messages. It uses -% an undefined control sequence to start the error message. % |\ekvd@err@choice@invalid| will have to use this mechanism to throw its % message. Also we have to retrieve the name parts of the choice in an easy way, % so we use parentheses of catcode 8 here, which should suffice in most cases to @@ -1956,18 +2114,20 @@ and the derived files expkv-def.pdf {\ekvd@err{invalid choice `#3' (`#2', set `#1')}}% } } -\begingroup -\edef\ekvd@err +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\ekvd@err} +% The expandable error messages use |\ekvd@err|, which is just like |\ekv@err| +% from \expkv\ or the way \pkg{expl3} throws expandable error messages. It uses +% an undefined control sequence to start the error message. +% \begin{macrocode} +\def\ekvd@err#1% {% - \endgroup - \unexpanded{\long\def\ekvd@err}##1% - {% - \unexpanded{\expandafter\ekv@err@\@firstofone}% - {\unexpanded\expandafter{\csname ! expkv-def Error:\endcsname}##1.}% - \unexpanded{\ekv@stop}% - }% + \long\def\ekvd@err##1{\expandafter\ekv@err@\@firstofone{#1##1.}\ekv@stop}% } -\ekvd@err +\begingroup\expandafter\endgroup +\expandafter\ekvd@err\csname ! expkv-def Error:\endcsname % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/tex/generic/expkv-def/expkv-def.tex b/Master/texmf-dist/tex/generic/expkv-def/expkv-def.tex index 83df70fc0ea..b5a89d29fbb 100644 --- a/Master/texmf-dist/tex/generic/expkv-def/expkv-def.tex +++ b/Master/texmf-dist/tex/generic/expkv-def/expkv-def.tex @@ -13,7 +13,7 @@ %% See http://www.latex-project.org/lppl.txt %% -------------------------------------------------------------- %% -%% Copyright (C) 2020 Jonathan P. Spratte +%% Copyright (C) 2020-2021 Jonathan P. Spratte %% %% This work may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this license or @@ -35,8 +35,8 @@ \else \expandafter\endinput \fi -\def\ekvdVersion{0.7} -\def\ekvdDate{2020-12-28} +\def\ekvdVersion{0.8} +\def\ekvdDate{2021-04-10} \csname ekvd@tmp\endcsname \expandafter\chardef\csname ekvd@tmp\endcsname=\catcode`\@ \catcode`\@=11 @@ -557,12 +557,7 @@ } \protected\long\expandafter\def\csname ekvd@t@unknown-choice\endcsname#1#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@new@for@name{\ekvd@unknown@choice@name\ekvd@set{#1}}% {% \ekvd@assert@arg {% @@ -573,6 +568,72 @@ }% }% } +\protected\long\def\ekvd@t@unknown#1#2% + {% + \ekv@ifdefined{ekvd@type@unknown@\detokenize{#1}}% + {\csname ekvd@type@unknown@\detokenize{#1}\endcsname{#2}}% + \ekvd@err@misused@unknown + } +\protected\long\def\ekvd@type@unknown@noval#1% + {% + \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}uN}% + {% + \ekvd@assert@arg + {% + \ekvd@assert@not@also + \ekvd@assert@not@long + \ekvd@prot\ekvdefunknownNoVal\ekvd@set{#1}% + }% + }% + } +\protected\long\def\ekvd@type@unknown@code#1% + {% + \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}u}% + {% + \ekvd@assert@arg + {% + \ekvd@assert@not@also + \begingroup + \def\ekvd@tmp##1##2{#1}% + \ekv@exparg + {% + \endgroup + \ekvd@prot\ekvd@long\ekvdefunknown\ekvd@set + }% + {\ekvd@tmp{##2}{##1}}% + }% + }% + } +\protected\edef\ekvd@type@unknown@redirect#1% + {% + \expandafter\noexpand\csname ekvd@type@unknown@redirect-code\endcsname{#1}% + \expandafter\noexpand\csname ekvd@type@unknown@redirect-noval\endcsname{#1}% + } +\protected\expandafter\def\csname ekvd@type@unknown@redirect-code\endcsname#1% + {% + \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}u}% + {% + \ekvd@assert@arg + {% + \ekvd@assert@not@also + \ekvd@assert@not@protected + \expandafter\ekvredirectunknown\expandafter{\ekvd@set}{#1}% + }% + }% + } +\protected\expandafter\def\csname ekvd@type@unknown@redirect-noval\endcsname#1% + {% + \ekvd@assert@new@for@name{\ekv@name\ekvd@set{}uN}% + {% + \ekvd@assert@arg + {% + \ekvd@assert@not@also + \ekvd@assert@not@protected + \ekvd@assert@not@long + \expandafter\ekvredirectunknownNoVal\expandafter{\ekvd@set}{#1}% + }% + }% + } \def\ekvd@h@choice#1% {% \expandafter\ekvd@h@choice@ @@ -733,6 +794,15 @@ {\csname ekvifdefined#1\endcsname\ekvd@set{#2}{\ekvd@err@not@new}} \def\ekvd@assert@not@new {\ifx\ekvd@ifnew\ekvd@assert@new\ekvd@err@no@prefix{new}\fi} +\def\ekvd@assert@new@for@name#1% + {% + \ifx\ekvd@ifnew\ekvd@assert@new + \ekv@fi@firstoftwo + \fi + \@secondoftwo + {\ekv@ifdefined{#1}\ekvd@err@not@new}% + \@firstofone + } \protected\def\ekvd@if@not@already@choice#1% {% \expandafter\ekvd@if@not@already@choice@a @@ -794,6 +864,8 @@ } \protected\def\ekvd@err@not@new {\ekvd@errm{The key for `\ekvd@cur' is already defined}} +\protected\long\def\ekvd@err@misused@unknown + {\ekvd@errm{Misuse of the unknown type found while processing `\ekvd@cur'}} \def\ekvd@err@choice@invalid#1% {% \ekvd@err@choice@invalid@#1\ekv@stop @@ -817,18 +889,12 @@ {\ekvd@err{invalid choice `#3' (`#2', set `#1')}}% } } -\begingroup -\edef\ekvd@err +\def\ekvd@err#1% {% - \endgroup - \unexpanded{\long\def\ekvd@err}##1% - {% - \unexpanded{\expandafter\ekv@err@\@firstofone}% - {\unexpanded\expandafter{\csname ! expkv-def Error:\endcsname}##1.}% - \unexpanded{\ekv@stop}% - }% + \long\def\ekvd@err##1{\expandafter\ekv@err@\@firstofone{#1##1.}\ekv@stop}% } -\ekvd@err +\begingroup\expandafter\endgroup +\expandafter\ekvd@err\csname ! expkv-def Error:\endcsname \catcode`\@=\ekvd@tmp %% %% diff --git a/Master/texmf-dist/tex/latex/expkv-def/expkv-def.sty b/Master/texmf-dist/tex/latex/expkv-def/expkv-def.sty index cccb668f0f9..fd4ee15a178 100644 --- a/Master/texmf-dist/tex/latex/expkv-def/expkv-def.sty +++ b/Master/texmf-dist/tex/latex/expkv-def/expkv-def.sty @@ -13,7 +13,7 @@ %% See http://www.latex-project.org/lppl.txt %% -------------------------------------------------------------- %% -%% Copyright (C) 2020 Jonathan P. Spratte +%% Copyright (C) 2020-2021 Jonathan P. Spratte %% %% This work may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this license or -- cgit v1.2.3