texlive[58772] Master/texmf-dist: expkv-opt (7apr21)

commits+preining at tug.org commits+preining at tug.org
Wed Apr 7 00:16:32 CEST 2021


Revision: 58772
          http://tug.org/svn/texlive?view=revision&revision=58772
Author:   preining
Date:     2021-04-07 00:16:32 +0200 (Wed, 07 Apr 2021)
Log Message:
-----------
expkv-opt (7apr21)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/generic/expkv-opt/README.md
    trunk/Master/texmf-dist/doc/generic/expkv-opt/expkv-opt.pdf
    trunk/Master/texmf-dist/source/generic/expkv-opt/expkv-opt.dtx
    trunk/Master/texmf-dist/tex/generic/expkv-opt/expkv-opt.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/source/generic/expkv-opt/expkv-opt-2020-10-10.dtx
    trunk/Master/texmf-dist/tex/generic/expkv-opt/expkv-opt-2020-10-10.sty

Modified: trunk/Master/texmf-dist/doc/generic/expkv-opt/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/generic/expkv-opt/README.md	2021-04-06 22:14:08 UTC (rev 58771)
+++ trunk/Master/texmf-dist/doc/generic/expkv-opt/README.md	2021-04-06 22:16:32 UTC (rev 58772)
@@ -1,7 +1,7 @@
 -------------------------------------------------------------------------------
 # expkv-opt -- parse class and package options with expkv
 
-Version 2020-10-10 v0.1b
+Version 2021-04-04 v0.2
 
 Released under the LaTeX Project Public License v1.3c or later
 See http://www.latex-project.org/lppl.txt

Modified: trunk/Master/texmf-dist/doc/generic/expkv-opt/expkv-opt.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/source/generic/expkv-opt/expkv-opt-2020-10-10.dtx
===================================================================
--- trunk/Master/texmf-dist/source/generic/expkv-opt/expkv-opt-2020-10-10.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/generic/expkv-opt/expkv-opt-2020-10-10.dtx	2021-04-06 22:16:32 UTC (rev 58772)
@@ -0,0 +1,938 @@
+% \iffalse meta-comment
+%
+% File: expkv-opt.dtx Copyright (C) 2020 Jonathan P. Spratte
+%
+% This work  may be  distributed and/or  modified under  the conditions  of the
+% LaTeX Project Public License (LPPL),  either version 1.3c  of this license or
+% (at your option) any later version.  The latest version of this license is in
+% the file:
+%
+%   http://www.latex-project.org/lppl.txt
+%
+% ------------------------------------------------------------------------------
+%
+%<*driver>^^A>>=
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+  \expandafter\begingroup
+\fi
+\input l3docstrip.tex
+\askforoverwritefalse
+\preamble
+
+--------------------------------------------------------------
+expkv-opt -- parse class and package options with expkv
+E-mail: jspratte at yahoo.de
+Released under the LaTeX Project Public License v1.3c or later
+See http://www.latex-project.org/lppl.txt
+--------------------------------------------------------------
+
+Copyright (C) 2020 Jonathan P. Spratte
+
+This  work may be  distributed and/or  modified under  the conditions  of the
+LaTeX Project Public License (LPPL),  either version 1.3c  of this license or
+(at your option) any later version.  The latest version of this license is in
+the file:
+
+  http://www.latex-project.org/lppl.txt
+
+This work is "maintained" (as per LPPL maintenance status) by
+  Jonathan P. Spratte.
+
+This work consists of the file  expkv-opt.dtx
+and the derived files           expkv-opt.pdf
+                                expkv-opt.sty
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+\generate{\file{expkv-opt-2020-10-10.sty}{\from{expkv-opt-2020-10-10.dtx}{pkg}}}
+\ifx\fmtname\nameofplainTeX
+  \expandafter\endbatchfile
+\else
+  \expandafter\endgroup
+\fi
+%
+\IfFileExists{expkv-opt.sty}{\RequirePackage{expkv-opt}}{}
+\ProvidesFile{expkv-opt.dtx}
+  [\csname ekvoDate\endcsname\ parse class and package options with expkv]
+\PassOptionsToPackage{full}{textcomp}
+\documentclass{l3doc}
+\RequirePackage[oldstylenums,nott]{kpfonts}
+\input{glyphtounicode}
+\pdfgentounicode=1
+\RequirePackage{listings}
+\RequirePackage{booktabs}
+\RequirePackage{array}
+\RequirePackage{collcell}
+\RequirePackage{siunitx}
+\RequirePackage{xcolor}
+\RequirePackage{caption}
+\RequirePackage{microtype}
+\RequirePackage{accsupp}
+\lstset
+  {
+    ,flexiblecolumns=false
+    ,basewidth=.53em
+    ,gobble=2
+    ,basicstyle=\fontfamily{jkp}\itshape
+    ,morekeywords=^^A
+      {^^A
+        \ekvoProcessLocalOptions,
+        \ekvoProcessGlobalOptions,
+        \ekvoProcessUnusedGlobalOptions,
+        \ekvoProcessOptionsList,
+        \ekvoUseUnknownHandlers
+      }
+    ,morecomment=[l]\%
+    ,commentstyle=\color[gray]{0.4}
+    ,literate={\{}{{\CodeSymbol\{}}{1}
+              {\}}{{\CodeSymbol\}}}{1}
+    ^^A,literate=*{<key>}{\key}{4}{<set>}{\set}{4}
+  }
+\newcommand*\CodeSymbol[1]{\textbf{#1}}
+\RequirePackage{randtext}
+\let\metaORIG\meta
+\protected\def\meta #1{\texttt{\metaORIG{#1}}}
+\renewcommand*\thefootnote{\fnsymbol{footnote}}
+\definecolor{expkvred}{HTML}{9F393D}
+\colorlet{expkvgrey}{black!75}
+\makeatletter
+\newcommand*\expkv
+  {^^A
+    \texorpdfstring
+      {^^A
+        \mbox
+          {^^A
+            \BeginAccSupp{ActualText=expkv}^^A
+            \href{https://github.com/Skillmon/tex_expkv}
+              {^^A
+                \rmfamily
+                \bfseries
+                {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
+                \lower.493ex
+                  \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
+                \kern-.18em{\color{expkvred}v}^^A
+              }^^A
+            \EndAccSupp{}^^A
+          }^^A
+      }
+      {expkv}^^A
+  }
+\newcommand*\expkvpkg[1]
+  {^^A
+    \texorpdfstring
+      {^^A
+        \mbox
+          {^^A
+            \BeginAccSupp{ActualText=expkv-#1}^^A
+            \href{https://github.com/Skillmon/tex_expkv-#1}
+              {^^A
+                \rmfamily
+                \bfseries
+                {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
+                \lower.493ex
+                  \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
+                \kern-.18em{\color{expkvred}v}^^A
+                {\color{expkvgrey}^^A
+                  \kern.05em\rule[-.1ex]{.08em}{1.2ex}\kern.05em\textsc{#1}^^A
+                }^^A
+              }^^A
+            \EndAccSupp{}^^A
+          }^^A
+      }
+      {expkv-#1}^^A
+  }
+\newcommand*\expkvd{\expkvpkg{def}}
+\newcommand*\expkvc{\expkvpkg{cs}}
+\newcommand*\expkvo{\expkvpkg{opt}}
+\newcommand\kv{\meta{key}=\meta{value}}
+\newcommand\key{\meta{key}}
+\newcommand\val{\meta{value}}
+\newcommand\set{\meta{set}}
+\newcommand\enfprot{\textcolor{black}{protected}}
+\newcommand\allprot{\textcolor{gray}{protected}}
+\newcommand\notprot{\textcolor{red!80!black}{protected}}
+\newcommand\enflong{\textcolor{black}{long}}
+\newcommand\alllong{\textcolor{gray}{long}}
+\newcommand\notlong{\textcolor{red!80!black}{long}}
+\newcommand\prefixes[2]
+  {^^A
+    \hfill
+    \ifcase\numexpr#1\relax\or
+      \enfprot\or
+      \allprot\or
+      \notprot\fi\space
+    \ifcase\numexpr#2\relax\or
+      \enflong\or
+      \alllong\or
+      \notlong\fi
+  }
+\hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
+\DoNotIndex{\def,\edef,\,,\=,\begingroup,\catcode,\chardef,\csname,\endcsname}
+\DoNotIndex{\endgroup,\endinput,\errmessage,\expandafter,\input,\let,\long}
+\DoNotIndex{\protected,\ProvidesFile,\ProvidesPackage,\relax,\space}
+\DoNotIndex{\@,\unexpanded,\string,\expanded,\dimexpr,\global,\glueexpr,\hbox}
+\DoNotIndex{\numexpr,\RequirePackage,\setbox,\the,\unless,\xdef,\@firstofone}
+\DoNotIndex{\@firstoftwo,\@gobble,\@secondoftwo,\AtEndOfPackage,\newcommand}
+\DoNotIndex{\PackageError,\@classoptionslist,\@clsextension,\@currext}
+\DoNotIndex{\@currname,\@empty,\@gobbletwo,\@onlypreamble,\@unprocessedoptions}
+\DoNotIndex{\@unusedoptionlist}
+\DoNotIndex{\ifcsname}
+\DoNotIndex{\ifx}
+\DoNotIndex{\ifdefined}
+\DoNotIndex{\iffalse}
+\DoNotIndex{\iftrue}
+\DoNotIndex{\else}
+\DoNotIndex{\fi}
+\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
+\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
+\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
+\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
+\@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
+\makeatother
+\begin{document}
+  \title
+    {^^A
+      \texorpdfstring
+        {^^A
+          \huge\expkvo
+          \\[\medskipamount]
+          \Large parse class and package options with \expkv
+        }{expkv-opt - parse class and package options with expkv}^^A
+    }
+  \date{\ekvoDate\space v\ekvoVersion}
+  \author{Jonathan P. Spratte\thanks{\protect\randomize{jspratte at yahoo.de}}}
+  \DocInput{expkv-opt.dtx}
+\end{document}
+%</driver>^^A=<<
+% \fi
+%
+% \maketitle
+% \renewcommand*\thefootnote{\arabic{footnote}}
+%
+% \begin{abstract}
+% \noindent\parfillskip=0pt
+% \expkvo\ provides option parsing for classes and packages in \LaTeXe\ based on
+% \expkv. Global and local options are parsed individually by different
+% commands. The stylised name is \expkvo\ but the files use \file{expkv-opt},
+% this is due to CTAN-rules which don't allow \string| in package names since
+% that is the pipe symbol in *nix shells.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \begin{documentation}^^A>>=
+%
+% \section{Documentation}
+%
+% The \expkv\ family provides at its core a \kv\ parser and additionally
+% packages, one to conveniently define new keys (\expkvd) and another to build
+% expandable \kv\ taking control sequences (\expkvc). Still missing from the mix
+% was a solution to parse \LaTeXe\ class and package options, a gap that's
+% hereby filled with \expkvo.
+%
+% \expkvo\ shouldn't place any restrictions on the keys, but note that parts of
+% \LaTeXe\ can break if the \kv\ list contains braces. This includes the global
+% options list depending on which class you're using. Also keep in mind that
+% every value provided should be save from an |\edef| expansion, as the space
+% stripping code of \LaTeXe\ options (which is applied before \expkvo\ takes
+% control) uses such an expansion.
+%
+% The package can be loaded with
+% \begin{lstlisting}
+% \usepackage{expkv-opt}
+% \end{lstlisting}
+% Unlike the other packages in the \expkv\ family, \expkvo\ is only provided as
+% a \LaTeX\ package.
+%
+% Before reading this documentation you should read \expkv's documentation and
+% might want to also read the documentation of \expkvd.
+%
+%
+% \subsection{Macros}
+%
+% \expkvo's behaviour if it encounters a defined or an undefined \key\ depends
+% on which list is being parsed and whether the current file is a class or not.
+% Of course in every case a defined \key's callback will be invoked but an
+% additional action might be executed. For this reason the rule set of every
+% macro will be given below the short description which list it will parse. 
+%
+% During each of the processing macros the current list element (not separated
+% in \key\ and \val\ but as a whole) is stored within the macro
+% \cs{CurrentOption}.
+%
+% \begin{function}{\ekvoProcessLocalOptions}
+%   \begin{syntax}
+%     \cs{ekvoProcessLocalOptions}\marg{set}
+%   \end{syntax}
+%   This parses the options which are directly passed to the current class or
+%   package for an \expkv\ \set.
+% \end{function}
+% \begin{description}
+%   \item[Class:]
+%     \begin{description}
+%       \item[defined] \emph{nothing}
+%       \item[undefined]
+%         add the key to the list of unused global options (if the local option
+%         list matches the option list of the main class)
+%     \end{description}
+%   \item[Package:]
+%     \begin{description}
+%       \item[defined] \emph{nothing}
+%       \item[undefined] throw an error
+%     \end{description}
+% \end{description}
+%
+% \begin{function}{\ekvoProcessGlobalOptions}
+%   \begin{syntax}
+%     \cs{ekvoProcessGlobalOptions}\marg{set}
+%   \end{syntax}
+%   In \LaTeXe\ the options given to |\documentclass| are global options. This
+%   macro processes the global options for an \expkv\ \set.
+% \end{function}
+% \begin{description}
+%   \item[Class:]
+%     \begin{description}
+%       \item[defined] remove the option from the list of unused global options
+%       \item[undefined] \emph{nothing}
+%     \end{description}
+%   \item[Package:]
+%     \begin{description}
+%       \item[defined] remove the option from the list of unused global options
+%       \item[undefined] \emph{nothing}
+%     \end{description}
+% \end{description}
+%
+% \begin{function}{\ekvoProcessUnusedGlobalOptions}
+%   \begin{syntax}
+%     \cs{ekvoProcessUnusedGlobalOptions}\marg{set}
+%   \end{syntax}
+%   If you want to, instead of parsing all global options, you can parse only
+%   those global options which weren't yet used by another package or class.
+% \end{function}
+% \begin{description}
+%   \item[Class:]
+%     \begin{description}
+%       \item[defined] remove the option from the list of unused global options
+%       \item[undefined] \emph{nothing}
+%     \end{description}
+%   \item[Package:]
+%     \begin{description}
+%       \item[defined] remove the option from the list of unused global options
+%       \item[undefined] \emph{nothing}
+%     \end{description}
+% \end{description}
+%
+% \begin{function}{\ekvoProcessOptionsList}
+%   \begin{syntax}
+%     \cs{ekvoProcessOptionsList}\meta{list}\marg{set}
+%   \end{syntax}
+%   Process the \kv\ list stored in the macro \meta{list}.
+% \end{function}
+% \begin{description}
+%   \item[Class:]
+%     \begin{description}
+%       \item[defined] \emph{nothing}
+%       \item[undefined] \emph{nothing}
+%     \end{description}
+%   \item[Package:]
+%     \begin{description}
+%       \item[defined] \emph{nothing}
+%       \item[undefined] \emph{nothing}
+%     \end{description}
+% \end{description}
+%
+% \begin{function}{\ekvoUseUnknownHandlers}
+%   \begin{syntax}
+%     \cs{ekvoUseUnknownHandlers}\meta{cs_1}\meta{cs_2}
+%   \end{syntax}
+%   With this macro you can change the action \expkvo\ executes if it encounters
+%   an undefined \key\ for the next (and only the next) list processing macro.
+%   The macro \meta{cs_1} will be called if an undefined \key\ without a \val\
+%   is encountered and get one argument, being the \key. Analogous the macro
+%   \meta{cs_2} will be called if an undefined \key\ with a \val\ was specified.
+%   It will get two arguments, the first being the \key\ and the second the
+%   \val.
+% \end{function}
+%
+% \begin{function}{\ekvoVersion,\ekvoDate}
+%   These two macros store the version and date of the package.
+% \end{function}
+%
+%
+% \subsection{Example}
+%
+% Let's say we want to create a package that changes the way footnotes are
+% displayed in \LaTeX. For this it will essentially just redefine
+% \cs[no-index]{thefootnote} and we'll call this package \pkg{ex-footnote}.
+% First we report back which package we are:
+% \begin{lstlisting}
+% \ProvidesPackage{ex-footnote}[2020-02-02 v1 change footnotes]
+% \end{lstlisting}
+% Next we'll need to provide the options we want the package to have.
+% \begin{lstlisting}
+% \RequirePackage{color}
+% \RequirePackage{expkv-opt} % also loads expkv
+% \ekvdef{ex-footnote}{color}{\def\exfn at color{#1}}
+% \ekvdef{ex-footnote}{format}{\def\exfn at format{#1}}
+% \end{lstlisting}
+% We can provide initial values just by defining the two macros storing the
+% value.
+% \begin{lstlisting}
+% \newcommand*\exfn at color{}
+% \newcommand*\exfn at format{arabic}
+% \end{lstlisting}
+% Next we need to process the options given to the package. The package should
+% only obey options directly passed to it, so we're only using
+% |\ekvoProcessLocalOptions|:
+% \begin{lstlisting}
+% \ekvoProcessLocalOptions{ex-footnote}
+% \end{lstlisting}
+% Now everything that's still missing is actually changing the way footnotes
+% appear:
+% \begin{lstlisting}
+% \renewcommand*\thefootnote
+%   {%
+%     \ifx\exfn at color\@empty
+%       \csname\exfn at format\endcsname{footnote}%
+%     \else
+%       \textcolor{\exfn at color}{\csname\exfn at format\endcsname{footnote}}%
+%     \fi
+%   }
+% \end{lstlisting}
+% \bigskip
+%
+% \noindent
+% So the complete code of the package would look like this:
+% \begin{lstlisting}
+% \ProvidesPackage{ex-footnote}[2020-02-02 v1 change footnotes]
+%
+% \RequirePackage{color}
+% \RequirePackage{expkv-opt} % also loads expkv
+%
+% \ekvdef{ex-footnote}{color}{\def\exfn at color{#1}}
+% \ekvdef{ex-footnote}{format}{\def\exfn at format{#1}}
+% \newcommand*\exfn at color{}
+% \newcommand*\exfn at format{arabic}
+%
+% \ekvoProcessLocalOptions{ex-footnote}
+%
+% \renewcommand*\thefootnote
+%   {%
+%     \ifx\exfn at color\@empty
+%       \csname\exfn at format\endcsname{footnote}%
+%     \else
+%       \textcolor{\exfn at color}{\csname\exfn at format\endcsname{footnote}}%
+%     \fi
+%   }
+% \end{lstlisting}
+% \bigskip
+%
+% \noindent
+% And it could be used with one of the following lines:
+% \begin{lstlisting}
+% \usepackage{ex-footnote}
+% \usepackage[format=fnsymbol]{ex-footnote}
+% \usepackage[color=green]{ex-footnote}
+% \usepackage[color=red,format=roman]{ex-footnote}
+% \end{lstlisting}
+%
+%
+% \subsection{Bugs}
+%
+% If you happen to find bugs, it'd be great if you let me know. Just write me an
+% email (see the front page) or submit a bug report on GitHub:
+% \url{https://github.com/Skillmon/tex_expkv-opt}
+%
+%
+% \subsection{License}
+%
+% Copyright \textcopyright\ 2020\unless\ifnum\year=2020--\the\year\fi\
+% Jonathan P. Spratte
+%
+% \medskip\noindent
+% This work may be distributed and/or modified under the conditions of the
+% \LaTeX\ Project Public License (LPPL), either version 1.3c of this license or
+% (at your option) any later version. The latest version of this license is in
+% the file:
+%
+% \url{http://www.latex-project.org/lppl.txt}
+%
+% \noindent
+% This work is ``maintained'' (as per LPPL maintenance status) by
+%
+% \mbox{Jonathan P. Spratte}.
+%
+% \end{documentation}^^A=<<
+%
+% \begin{implementation}^^A>>=
+%
+% \clearpage
+%
+%
+% \section{Implementation}
+%
+% \gobbledocstriptag
+%<*pkg>
+% Start the package with the typical \LaTeX\ standards.
+% 
+% \begin{macro}{\ekvoVersion,\ekvoDate}
+%   Store the packages version and date in two macros.
+%    \begin{macrocode}
+\newcommand*\ekvoVersion{0.1b}
+\newcommand*\ekvoDate{2020-10-10}
+%    \end{macrocode}
+% \end{macro}
+% And we report who we are and what we need.
+%    \begin{macrocode}
+\ProvidesPackage{expkv-opt}
+  [%
+    \ekvoDate\space v\ekvoVersion\space
+    parse class and package options with expkv%
+  ]
+\RequirePackage{expkv}
+%    \end{macrocode}
+%
+%
+% \subsection{Loop}
+%
+% \begin{macro}[internal]
+%   {\ekvo at CurrentOption@loop,\ekvo at CurrentOption@loop@,\ekvo at end@loop}
+%   We'll need some loop which can iterate over a comma separated list. The loop
+%   is very basic and only works for commas of category~12. First we insert the
+%   delimiters for the actual loop.
+%    \begin{macrocode}
+\protected\long\def\ekvo at CurrentOption@loop#1#2%
+  {%
+    \ekvo at CurrentOption@loop@#2\ekv at mark#1,\ekv at stop,\ekvo at tail
+  }
+%    \end{macrocode}
+%   The actual loop checks whether the final element has been read and if so
+%   ends the loop. Else blank elements are ignored, |\CurrentOption| is set and
+%   the macro which parses the list elements called. Then call the next
+%   iteration.
+%    \begin{macrocode}
+\long\def\ekvo at CurrentOption@loop@#1#2,%
+  {%
+    \ekv at gobble@from at mark@to at stop#2\ekvo at end@loop\ekv at stop
+    \ekv at ifblank{#2}%
+      {}%
+      {%
+        \edef\CurrentOption{\unexpanded\expandafter{\@gobble#2}}%
+        #1{#2}%
+      }%
+    \ekvo at CurrentOption@loop@#1\ekv at mark
+  }
+\long\def\ekvo at end@loop#1\ekvo at tail{}
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Tests}
+%
+% \begin{macro}[internal]{\ekvo at ifx@TF,\ekvo at ifx@F}
+%   We'll need branching |\ifx| tests so that user input containing unbalanced
+%   \TeX\ ifs doesn't break (at least not because of us, everything else is the
+%   fault of \LaTeXe).
+%    \begin{macrocode}
+\def\ekvo at ifx@TF#1#2{\ifx#1#2\ekv at fi@firstoftwo\fi\@secondoftwo}
+\def\ekvo at ifx@F#1#2{\ifx#1#2\ekv at fi@gobble\fi\@firstofone}
+%    \end{macrocode}
+% \end{macro}
+% 
+% \begin{macro}[internal]{\ekvo at do@with at set,\ekvo at name,\ekvo at setname}
+%   This test checks whether the \set\ is defined.  If it is we store it in
+%   |\ekvo at setname| and set |\ekvo at name| to a short cut to get the \key's
+%   callback name. Next we execute the code in |#2|, if the \set\ isn't defined
+%   |#2| is gobbled.
+%    \begin{macrocode}
+\protected\def\ekvo at do@with at set#1#2%
+  {%
+    \ekvifdefinedset{#1}%
+      {%
+        \expandafter
+        \let\expandafter\ekvo at name\csname\ekv at undefined@set{#1}\endcsname
+        \def\ekvo at setname{#1}%
+        #2%
+      }%
+      {\ekvo at err@undefined at set{#1}}%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Key handlers}
+%
+% \expkvo\ uses handlers specifying what happens if a parsed \key\ is defined or
+% undefined.
+%
+% \begin{macro}[internal]
+%   {\ekvo at handle@undefined at k@pkg,\ekvo at handle@undefined at kv@pkg}
+%   The case for undefined keys in a local list of a package is easy, just throw
+%   appropriate errors.
+%    \begin{macrocode}
+\protected\long\def\ekvo at handle@undefined at k@pkg#1%
+  {%
+    \ekv at ifdefined{\ekvo at name{#1}}%
+      {\ekvo at err@value at required{#1}}%
+      {\ekvo at err@undefined at key{#1}}%
+  }
+\def\ekvo at handle@undefined at kv@pkg#1#2%
+  {%
+    \ekv at ifdefined{\ekvo at name{#1}N}%
+      {\ekvo at err@value at forbidden{#1}}%
+      {\ekvo at err@undefined at key{#1}}%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]
+%   {
+%     \ekvo at addto@unused at one,\ekvo at addto@unused at two,
+%     \ekvo at rmfrom@unused at one,\ekvo at rmfrom@unused at two
+%   }
+%   These macros will add or remove the |\CurrentOption| to or from the list of
+%   unused global options.
+%    \begin{macrocode}
+\long\def\ekvo at addto@unused at one#1{\ekvo at addto@list\@unusedoptionlist}
+\long\def\ekvo at addto@unused at two#1#2{\ekvo at addto@list\@unusedoptionlist}
+\long\def\ekvo at rmfrom@unused at one#1{\ekvo at rmfrom@list\@unusedoptionlist}
+\long\def\ekvo at rmfrom@unused at two#1#2{\ekvo at rmfrom@list\@unusedoptionlist}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}[internal]
+%   {
+%     \ekvo at set@handlers at local,\ekvo at set@handlers at global,
+%     \ekvo at set@handlers at unusedglobal,\ekvo at set@handlers at list
+%   }
+%   These macros are boring. They just set up the handlers to respect the rules
+%   documented earlier.
+%    \begin{macrocode}
+\protected\def\ekvo at set@handlers at local
+  {%
+    \ekvo at if@need at handlers
+      {%
+        \ifx\@currext\@clsextension
+          \ifx\@classoptionslist\relax
+            \let\ekvo at handle@undefined at k\@gobble
+            \let\ekvo at handle@undefined at kv\@gobbletwo
+          \else
+            \expandafter
+            \ifx\csname opt@\@currname.\@currext\endcsname\@classoptionslist
+              \let\ekvo at handle@undefined at k\ekvo at addto@unused at one
+              \let\ekvo at handle@undefined at kv\ekvo at addto@unused at two
+            \else
+              \let\ekvo at handle@undefined at k\@gobble
+              \let\ekvo at handle@undefined at kv\@gobbletwo
+            \fi
+          \fi
+        \else
+          \let\ekvo at handle@undefined at k\ekvo at handle@undefined at k@pkg
+          \let\ekvo at handle@undefined at kv\ekvo at handle@undefined at kv@pkg
+        \fi
+      }%
+  }
+\protected\def\ekvo at set@handlers at global
+  {%
+    \unless\ifx\@unusedoptionlist\@empty
+      \let\ekvo at handle@defined at k\ekvo at rmfrom@unused at one
+      \let\ekvo at handle@defined at kv\ekvo at rmfrom@unused at two
+    \fi
+    \ekvo at if@need at handlers
+      {%
+        \let\ekvo at handle@undefined at k\@gobble
+        \let\ekvo at handle@undefined at kv\@gobbletwo
+      }%
+  }
+\protected\def\ekvo at set@handlers at unusedglobal
+  {%
+    \ekvo at if@need at handlers
+      {%
+        \let\ekvo at handle@undefined at k\ekvo at addto@unused at one
+        \let\ekvo at handle@undefined at kv\ekvo at addto@unused at two
+        \let\@unusedoptionlist\@empty
+        \@gobbletwo
+      }%
+    \@firstofone
+      {%
+        \let\ekvo at handle@defined at k\ekvo at rmfrom@unused at one
+        \let\ekvo at handle@defined at kv\ekvo at rmfrom@unused at two
+      }%
+  }
+\protected\def\ekvo at set@handlers at list
+  {%
+    \ekvo at if@need at handlers
+      {%
+        \let\ekvo at handle@undefined at k\@gobble
+        \let\ekvo at handle@undefined at kv\@gobbletwo
+      }%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\ekvo at if@need at handlers,\ekvo at dont@need at handlers}
+%   If the user specifies handlers this macro will be let to
+%   |\ekvo at dont@need at handlers|, which will act like |\@gobble| and also let it
+%   to |\@firstofone| afterwards.
+%    \begin{macrocode}
+\let\ekvo at if@need at handlers\@firstofone
+\protected\long\def\ekvo at dont@need at handlers#1%
+  {%
+    \let\ekvo at if@need at handlers\@firstofone
+  }%
+%    \end{macrocode}
+% \end{macro}
+%
+% We have to set the default for the handlers of defined keys, because they
+% don't necessarily get defined before a list is parsed.
+%    \begin{macrocode}
+\let\ekvo at handle@defined at k\@gobble
+\let\ekvo at handle@defined at kv\@gobbletwo
+%    \end{macrocode}
+%
+%
+% \subsection{Processing list elements}
+%
+% \begin{macro}[internal]{\ekvo at process@common}
+%   All the key processing frontend macros use the same basic structure. |#1|
+%   will be a simple test, deciding whether the list will really be parsed or
+%   not, |#3| will be the \set, and |#2| will be the individual code of the
+%   frontend macro which should be executed if both the test in |#1| is true and
+%   the \set\ is defined.
+%    \begin{macrocode}
+\protected\def\ekvo at process@common#1#2#3%
+  {%
+    #1{\ekvo at do@with at set{#3}{#2}}%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\ekvo at process@list}
+%   This macro only expands the list holding macro and forwards it to the
+%   loop macro.
+%    \begin{macrocode}
+\protected\def\ekvo at process@list#1%
+  {%
+    \expandafter\ekvo at CurrentOption@loop\expandafter{#1}\ekvo at parse
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\ekvo at parse}
+%   This macro calls internals of |\ekvparse| such that the code splitting at
+%   commas isn't executed, else this is equivalent to
+%   |\ekvparse\ekvo at set@k\ekvo at set@kv{#1}|.
+%    \begin{macrocode}
+\protected\long\def\ekvo at parse#1%
+  {%
+    \ekv at eq@other#1\ekv at nil\ekv at mark\ekv at parse@eq at other@a
+      =\ekv at mark\ekv at parse@eq at active
+    \ekvo at set@k\ekvo at set@kv
+    \ekvo at tail
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\ekvo at set@k,\ekvo at set@kv}
+%   These two macros check whether the key is defined and if so call the handler
+%   for defined keys and execute the key, else the handler for undefined keys is
+%   called. They have to clean up a bit of code which is left by |\ekvo at parse|.
+%    \begin{macrocode}
+\protected\def\ekvo at set@k#1#2\ekvo at tail
+  {%
+    \ekv at ifdefined{\ekvo at name{#1}N}%
+      {%
+        \ekvo at handle@defined at k{#1}%
+        \csname\ekvo at name{#1}N\endcsname
+      }%
+      {\ekvo at handle@undefined at k{#1}}%
+  }
+\protected\def\ekvo at set@kv#1#2#3\ekvo at tail
+  {%
+    \ekv at ifdefined{\ekvo at name{#1}}%
+      {%
+        \ekvo at handle@defined at kv{#1}{#2}%
+        \csname\ekvo at name{#1}\endcsname{#2}%
+      }%
+      {\ekvo at handle@undefined at kv{#1}{#2}}%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{List variable helpers}
+%
+% \begin{macro}[internal]{\ekvo at addto@list}
+%   This macro is rather simple. If the list to which the |\CurrentOption|
+%   should be added is empty we can just let the list to the |\CurrentOption|.
+%   Else we have to expand the list once and the |\CurrentOption| once.
+%    \begin{macrocode}
+\protected\def\ekvo at addto@list#1%
+  {%
+    \ekvo at ifx@TF#1\@empty
+      {\let#1\CurrentOption}%
+      {%
+        \edef#1%
+          {%
+            \unexpanded\expandafter{#1},%
+            \unexpanded\expandafter{\CurrentOption}%
+          }%
+      }%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\ekvo at rmfrom@list,\ekvo at rmfrom@list@}
+%   This works by looping over every list item and comparing it to
+%   |\ekvo at curropt| which stores the real |\CurrentOption|. This is
+%   comparatively slow, but works for items containing braces unlike what
+%   \LaTeXe\ does. We could be faster for items not containing braces, though.
+%    \begin{macrocode}
+\protected\def\ekvo at rmfrom@list#1%
+  {%
+    \ekvo at ifx@F#1\@empty
+      {%
+        \let\ekvo at tmp@list\@empty
+        \let\ekvo at curropt\CurrentOption
+        \expandafter\ekvo at CurrentOption@loop\expandafter{#1}\ekvo at rmfrom@list@
+        \let\CurrentOption\ekvo at curropt
+        \let#1\ekvo at tmp@list
+      }%
+  }
+\protected\long\def\ekvo at rmfrom@list@#1%
+  {%
+    \ekvo at ifx@F\CurrentOption\ekvo at curropt
+      {\ekvo at addto@list\ekvo at tmp@list}%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Errors}
+%
+% \begin{macro}[internal]
+%   {
+%     \ekvo at err@undefined at key,\ekvo at err@value at required,
+%     \ekvo at err@value at forbidden,\ekvo at err@undefined at set
+%   }
+%   Just some macros to throw errors in the few cases an error has to be thrown.
+%    \begin{macrocode}
+\protected\def\ekvo at err@undefined at key#1%
+  {%
+    \PackageError{expkv-opt}{Undefined key `#1' in set `\ekvo at setname'}{}%
+  }
+\protected\def\ekvo at err@value at required#1%
+  {%
+    \PackageError{expkv-opt}%
+      {Value required for key `#1' in set `\ekvo at setname'}%
+      {}%
+  }
+\protected\def\ekvo at err@value at forbidden#1%
+  {%
+    \PackageError{expkv-opt}%
+      {Value forbidden for key `#1' in set `\ekvo at setname'}%
+      {}%
+  }
+\protected\def\ekvo at err@undefined at set#1%
+  {%
+    \PackageError{expkv-opt}%
+      {Undefined set `#1'}%
+      {The set for which you try to parse options isn't defined in expkv.}%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{User Interface}
+%
+% The user interface macros just put together the bits and pieces.
+% \begin{macro}{\ekvoProcessLocalOptions}
+%    \begin{macrocode}
+\protected\def\ekvoProcessLocalOptions
+  {%
+    \ekvo at process@common
+      {\ekv at ifdefined{opt@\@currname.\@currext}\@firstofone\@gobble}%
+      {%
+        \ekvo at set@handlers at local
+        \expandafter
+        \ekvo at process@list\csname opt@\@currname.\@currext\endcsname
+        \AtEndOfPackage{\let\@unprocessedoptions\relax}%
+      }%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ekvoProcessGlobalOptions}
+%    \begin{macrocode}
+\protected\def\ekvoProcessGlobalOptions
+  {%
+    \ekvo at process@common{\ekvo at ifx@F\@classoptionslist\relax}%
+      {%
+        \ekvo at set@handlers at global
+        \ekvo at process@list\@classoptionslist
+        \let\ekvo at handle@defined at k\@gobble
+        \let\ekvo at handle@defined at kv\@gobbletwo
+      }%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ekvoProcessUnusedGlobalOptions}
+%    \begin{macrocode}
+\protected\def\ekvoProcessUnusedGlobalOptions
+  {%
+    \ekvo at process@common{\ekvo at ifx@F\@unusedoptionlist\@empty}%
+      {%
+        \let\ekvo at tmp@list\@unusedoptionlist
+        \ekvo at set@handlers at unusedglobal
+        \ekvo at process@list\ekvo at tmp@list
+        \let\ekvo at handle@defined at k\@gobble
+        \let\ekvo at handle@defined at kv\@gobbletwo
+      }%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ekvoProcessOptionsList}
+%    \begin{macrocode}
+\protected\def\ekvoProcessOptionsList#1%
+  {%
+    \ekvo at process@common{\ekvo at ifx@F#1\@empty}%
+      {%
+        \ekvo at set@handlers at list
+        \ekvo at process@list#1%
+      }%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ekvoUseUnknownHandlers}
+%    \begin{macrocode}
+\protected\def\ekvoUseUnknownHandlers#1#2%
+  {%
+    \let\ekvo at handle@undefined at k#1\relax
+    \let\ekvo at handle@undefined at kv#2\relax
+    \let\ekvo at if@need at handlers\ekvo at dont@need at handlers
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% All user interface macros should be only used in the preamble.
+%    \begin{macrocode}
+\@onlypreamble\ekvoProcessLocalOptions
+\@onlypreamble\ekvoProcessGlobalOptions
+\@onlypreamble\ekvoProcessUnusedGlobalOptions
+\@onlypreamble\ekvoProcessOptionsList
+\@onlypreamble\ekvoUseUnknownHandlers
+%    \end{macrocode}
+% 
+% \gobbledocstriptag
+%</pkg>
+%
+% \end{implementation}^^A=<<
+%
+% \clearpage
+% \PrintIndex
+%
+% \Finale
+\endinput
+%
+^^A vim: ft=tex fdm=marker fmr=>>=,=<<


Property changes on: trunk/Master/texmf-dist/source/generic/expkv-opt/expkv-opt-2020-10-10.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/generic/expkv-opt/expkv-opt.dtx
===================================================================
--- trunk/Master/texmf-dist/source/generic/expkv-opt/expkv-opt.dtx	2021-04-06 22:14:08 UTC (rev 58771)
+++ trunk/Master/texmf-dist/source/generic/expkv-opt/expkv-opt.dtx	2021-04-06 22:16:32 UTC (rev 58772)
@@ -151,24 +151,6 @@
 \newcommand\key{\meta{key}}
 \newcommand\val{\meta{value}}
 \newcommand\set{\meta{set}}
-\newcommand\enfprot{\textcolor{black}{protected}}
-\newcommand\allprot{\textcolor{gray}{protected}}
-\newcommand\notprot{\textcolor{red!80!black}{protected}}
-\newcommand\enflong{\textcolor{black}{long}}
-\newcommand\alllong{\textcolor{gray}{long}}
-\newcommand\notlong{\textcolor{red!80!black}{long}}
-\newcommand\prefixes[2]
-  {^^A
-    \hfill
-    \ifcase\numexpr#1\relax\or
-      \enfprot\or
-      \allprot\or
-      \notprot\fi\space
-    \ifcase\numexpr#2\relax\or
-      \enflong\or
-      \alllong\or
-      \notlong\fi
-  }
 \hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
 \DoNotIndex{\def,\edef,\,,\=,\begingroup,\catcode,\chardef,\csname,\endcsname}
 \DoNotIndex{\endgroup,\endinput,\errmessage,\expandafter,\input,\let,\long}
@@ -177,13 +159,17 @@
 \DoNotIndex{\numexpr,\RequirePackage,\setbox,\the,\unless,\xdef,\@firstofone}
 \DoNotIndex{\@firstoftwo,\@gobble,\@secondoftwo,\AtEndOfPackage,\newcommand}
 \DoNotIndex{\PackageError,\@classoptionslist,\@clsextension,\@currext}
-\DoNotIndex{\@currname,\@empty,\@gobbletwo,\@onlypreamble,\@unprocessedoptions}
-\DoNotIndex{\@unusedoptionlist}
+\DoNotIndex{\@currname,\@empty,\@gobbletwo,\@onlypreamble,\@raw at classoptionslist}
+\DoNotIndex{\@unprocessedoptions,\@unusedoptionlist}
+\DoNotIndex{\DeclareRelease,\DeclareCurrentRelease,\IfFormatAtLeastTF}
+\DoNotIndex{\PackageWarning,\requestedLaTeXdate,\@ifstar}
+\DoNotIndex{\pkgcls at parse@date at arg,\pkgcls at targetdate,\pkgcls at targetlabel}
 \DoNotIndex{\ifcsname}
 \DoNotIndex{\ifx}
 \DoNotIndex{\ifdefined}
 \DoNotIndex{\iffalse}
 \DoNotIndex{\iftrue}
+\DoNotIndex{\ifnum}
 \DoNotIndex{\else}
 \DoNotIndex{\fi}
 \@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
@@ -190,6 +176,7 @@
 \@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
 \@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
 \@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
+\@gobble\fi ^^A ignoring \ifx, \ifcsname, etc., but only one \fi
 \@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
 \makeatother
 \begin{document}
@@ -233,17 +220,34 @@
 % was a solution to parse \LaTeXe\ class and package options, a gap that's
 % hereby filled with \expkvo.
 %
-% \expkvo\ shouldn't place any restrictions on the keys, but note that parts of
-% \LaTeXe\ can break if the \kv\ list contains braces. This includes the global
-% options list depending on which class you're using. Also keep in mind that
-% every value provided should be save from an |\edef| expansion, as the space
-% stripping code of \LaTeXe\ options (which is applied before \expkvo\ takes
-% control) uses such an expansion.
+% With the 2021-05-01 release of \LaTeXe\ there were some very interesting
+% changes to the package and class options code. It is now possible to use
+% braces inside the options, and we can access options without them being
+% preprocessed. As a result, some but not all restrictions were lifted from the
+% possible option usage. What will still fail is things that aren't save from an
+% |\edef| expansion. One thing that doesn't work any more is the possibility to
+% parse the unused option list, because that one doesn't contain the full
+% information any more.
 %
+% \expkvo\ will fall back to v0.1 if the kernel is older than 2021-05-01.
+% \expkvo\ shouldn't place any restrictions on the keys, historic shortcomings
+% of the kernel cannot be helped though, so the supported things vary with the
+% kernel version. The one thing that \expkvo\ doesn't support, which \expkv\
+% alone would, is active commas. But there is no good reason why a comma could
+% be active in the preamble.
+%
 % The package can be loaded with
 % \begin{lstlisting}
 % \usepackage{expkv-opt}
 % \end{lstlisting}
+% and if you need a specific version you can use \LaTeXe's rollback support, so
+% to load v0.1 explicitly use:
+% \begin{lstlisting}
+% \usepackage{expkv-opt}[=v0.1]
+% \end{lstlisting}
+% which will load the latest subversion of v0.1
+% (this shouldn't be done by a package author, but only by a user on a
+% single-document basis if there are some incompatibilities, which is unlikely)
 % Unlike the other packages in the \expkv\ family, \expkvo\ is only provided as
 % a \LaTeX\ package.
 %
@@ -259,9 +263,8 @@
 % additional action might be executed. For this reason the rule set of every
 % macro will be given below the short description which list it will parse. 
 %
-% During each of the processing macros the current list element (not separated
-% in \key\ and \val\ but as a whole) is stored within the macro
-% \cs{CurrentOption}.
+% During each of the processing macros the current list element (not processed
+% in any way) is stored within the macro \cs{CurrentOption}.
 %
 % \begin{function}{\ekvoProcessLocalOptions}
 %   \begin{syntax}
@@ -309,21 +312,10 @@
 %   \begin{syntax}
 %     \cs{ekvoProcessUnusedGlobalOptions}\marg{set}
 %   \end{syntax}
-%   If you want to, instead of parsing all global options, you can parse only
-%   those global options which weren't yet used by another package or class.
+%   This does no longer work with \LaTeXe\ kernels starting from 2021-05-01,
+%   since the handling of the unused option list changed and no longer includes
+%   the values. As a result this will throw a warning and else will be ignored.
 % \end{function}
-% \begin{description}
-%   \item[Class:]
-%     \begin{description}
-%       \item[defined] remove the option from the list of unused global options
-%       \item[undefined] \emph{nothing}
-%     \end{description}
-%   \item[Package:]
-%     \begin{description}
-%       \item[defined] remove the option from the list of unused global options
-%       \item[undefined] \emph{nothing}
-%     \end{description}
-% \end{description}
 %
 % \begin{function}{\ekvoProcessOptionsList}
 %   \begin{syntax}
@@ -346,7 +338,8 @@
 %
 % \begin{function}{\ekvoUseUnknownHandlers}
 %   \begin{syntax}
-%     \cs{ekvoUseUnknownHandlers}\meta{cs_1}\meta{cs_2}
+%     \cs{ekvoUseUnknownHandlers}\meta{cs_1}\meta{cs_2}\quad{\normalfont\itshape or}
+%     \cs{ekvoUseUnknownHandlers}*
 %   \end{syntax}
 %   With this macro you can change the action \expkvo\ executes if it encounters
 %   an undefined \key\ for the next (and only the next) list processing macro.
@@ -354,7 +347,11 @@
 %   is encountered and get one argument, being the \key. Analogous the macro
 %   \meta{cs_2} will be called if an undefined \key\ with a \val\ was specified.
 %   It will get two arguments, the first being the \key\ and the second the
-%   \val.
+%   \val.\par
+%   If you use the starred variant, it'll not take further arguments. In this
+%   case the undefined handlers defined via |\ekvdefunknown| and
+%   |\ekvdefunknownNoVal| in the parsing set get used, and if those aren't
+%   available they'll simply do nothing.
 % \end{function}
 %
 % \begin{function}{\ekvoVersion,\ekvoDate}
@@ -476,13 +473,36 @@
 %
 % \gobbledocstriptag
 %<*pkg>
+%
+% First we check whether the \LaTeXe\ kernel supports raw options. If it doesn't
+% we check whether a specific version was requested, and if that's not the case
+% we manually run |\pkgcls at parse@date at arg| with the last version that supported
+% non-raw options.
+%    \begin{macrocode}
+\IfFormatAtLeastTF{2021/05/01}
+  {}
+  {%
+    \ifx\pkgcls at targetlabel\@empty
+      \ifnum\requestedLaTeXdate=\pkgcls at targetdate
+        \pkgcls at parse@date at arg{=v0.1}%
+      \fi
+    \fi
+  }
+%    \end{macrocode}
+% Then we tell \LaTeXe\ where to find which release so that the package rollback
+% code of \LaTeXe\ can do its thing.
+%    \begin{macrocode}
+\DeclareRelease{v0.1}{2020/10/10}{expkv-opt-2020-10-10.sty}
+\DeclareCurrentRelease{v0.2}{2021/04/04}
+%    \end{macrocode}
+% 
 % Start the package with the typical \LaTeX\ standards.
 % 
 % \begin{macro}{\ekvoVersion,\ekvoDate}
 %   Store the packages version and date in two macros.
 %    \begin{macrocode}
-\newcommand*\ekvoVersion{0.1b}
-\newcommand*\ekvoDate{2020-10-10}
+\newcommand*\ekvoVersion{0.2}
+\newcommand*\ekvoDate{2021-04-04}
 %    \end{macrocode}
 % \end{macro}
 % And we report who we are and what we need.
@@ -594,18 +614,73 @@
 %     \ekvo at rmfrom@unused at one,\ekvo at rmfrom@unused at two
 %   }
 %   These macros will add or remove the |\CurrentOption| to or from the list of
-%   unused global options.
+%   unused global options. Since |\ekvo at do@unusedoptionlist| will have some
+%   overhead before calling the list changing macro in filtering the current
+%   option, we use an optimization here in that we check whether the list is
+%   empty before calling the |rmfrom| function.
 %    \begin{macrocode}
-\long\def\ekvo at addto@unused at one#1{\ekvo at addto@list\@unusedoptionlist}
-\long\def\ekvo at addto@unused at two#1#2{\ekvo at addto@list\@unusedoptionlist}
-\long\def\ekvo at rmfrom@unused at one#1{\ekvo at rmfrom@list\@unusedoptionlist}
-\long\def\ekvo at rmfrom@unused at two#1#2{\ekvo at rmfrom@list\@unusedoptionlist}
+\long\def\ekvo at addto@unused at one#1{\ekvo at do@unusedoptionlist\ekvo at addto@list}
+\long\def\ekvo at addto@unused at two#1#2{\ekvo at do@unusedoptionlist\ekvo at addto@list}
+\long\def\ekvo at rmfrom@unused at one#1%
+  {%
+    \ekvo at ifx@F\@unusedoptionlist\@empty
+      {\ekvo at do@unusedoptionlist\ekvo at rmfrom@list}%
+  }
+\long\def\ekvo at rmfrom@unused at two#1#2%
+  {%
+    \ekvo at ifx@F\@unusedoptionlist\@empty
+      {\ekvo at do@unusedoptionlist\ekvo at rmfrom@list}%
+  }
 %    \end{macrocode}
 % \end{macro}
+%
 % \begin{macro}[internal]
 %   {
+%     \ekvo at do@unusedoptionlist,
+%     \ekvo at prepare@unusedoption,
+%     \ekvo at prepare@unusedoption at a,
+%     \ekvo at prepare@unusedoption at b,
+%     \ekvo at prepare@unusedoption at c
+%   }
+%   The way the new \LaTeXe\ kernel handles the unused option list changed. Now
+%   not the entire |\CurrentOption| is listed, but just everything up to the
+%   first equals sign, and spaces got zapped, doesn't matter whether the raw
+%   option list gets used or not. So we have to zap spaces and remove everything
+%   from the first equals sign onwards. The code used here will fail if the
+%   current option contains an |\ekv at mark| or |\ekv at stop| before the first
+%   equals sign (this seems rather unlikely).
+%    \begin{macrocode}
+\protected\def\ekvo at do@unusedoptionlist#1%
+  {%
+    \let\ekvo at unpreparedCurrentOption\CurrentOption
+    \edef\CurrentOption
+      {\expandafter\ekvo at prepare@unusedoption\CurrentOption=\ekv at mark}%
+    #1\@unusedoptionlist
+    \let\CurrentOption\ekvo at unpreparedCurrentOption
+  }
+\def\ekvo at prepare@unusedoption{\ekvo at prepare@unusedoption at a\@empty}
+\def\ekvo at prepare@unusedoption at a#1%
+  {%
+    \long\def\ekvo at prepare@unusedoption at a##1=##2\ekv at mark
+      {%
+        \ekvo at prepare@unusedoption at b##1\ekv at stop
+          \ekv at mark\ekvo at prepare@unusedoption at b
+          #1\ekv at mark\ekvo at prepare@unusedoption at c
+      }%
+  }
+\ekvo at prepare@unusedoption at a{ }
+\long\def\ekvo at prepare@unusedoption at b#1 #2\ekv at mark#3{#3#1#2\ekv at mark#3}
+\long\def\ekvo at prepare@unusedoption at c
+    #1\ekv at stop
+    \ekv at mark\ekvo at prepare@unusedoption at b\ekv at mark\ekvo at prepare@unusedoption at c
+  {\unexpanded\expandafter{#1}}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]
+%   {
 %     \ekvo at set@handlers at local,\ekvo at set@handlers at global,
-%     \ekvo at set@handlers at unusedglobal,\ekvo at set@handlers at list
+%     \ekvo at set@handlers at list
 %   }
 %   These macros are boring. They just set up the handlers to respect the rules
 %   documented earlier.
@@ -620,7 +695,9 @@
             \let\ekvo at handle@undefined at kv\@gobbletwo
           \else
             \expandafter
-            \ifx\csname opt@\@currname.\@currext\endcsname\@classoptionslist
+            \ifx
+                \csname @raw at opt@\@currname.\@currext\endcsname
+                \@raw at classoptionslist
               \let\ekvo at handle@undefined at k\ekvo at addto@unused at one
               \let\ekvo at handle@undefined at kv\ekvo at addto@unused at two
             \else
@@ -646,21 +723,6 @@
         \let\ekvo at handle@undefined at kv\@gobbletwo
       }%
   }
-\protected\def\ekvo at set@handlers at unusedglobal
-  {%
-    \ekvo at if@need at handlers
-      {%
-        \let\ekvo at handle@undefined at k\ekvo at addto@unused at one
-        \let\ekvo at handle@undefined at kv\ekvo at addto@unused at two
-        \let\@unusedoptionlist\@empty
-        \@gobbletwo
-      }%
-    \@firstofone
-      {%
-        \let\ekvo at handle@defined at k\ekvo at rmfrom@unused at one
-        \let\ekvo at handle@defined at kv\ekvo at rmfrom@unused at two
-      }%
-  }
 \protected\def\ekvo at set@handlers at list
   {%
     \ekvo at if@need at handlers
@@ -853,11 +915,11 @@
 \protected\def\ekvoProcessLocalOptions
   {%
     \ekvo at process@common
-      {\ekv at ifdefined{opt@\@currname.\@currext}\@firstofone\@gobble}%
+      {\ekv at ifdefined{@raw at opt@\@currname.\@currext}\@firstofone\@gobble}%
       {%
         \ekvo at set@handlers at local
         \expandafter
-        \ekvo at process@list\csname opt@\@currname.\@currext\endcsname
+        \ekvo at process@list\csname @raw at opt@\@currname.\@currext\endcsname
         \AtEndOfPackage{\let\@unprocessedoptions\relax}%
       }%
   }
@@ -870,7 +932,7 @@
     \ekvo at process@common{\ekvo at ifx@F\@classoptionslist\relax}%
       {%
         \ekvo at set@handlers at global
-        \ekvo at process@list\@classoptionslist
+        \ekvo at process@list\@raw at classoptionslist
         \let\ekvo at handle@defined at k\@gobble
         \let\ekvo at handle@defined at kv\@gobbletwo
       }%
@@ -879,16 +941,10 @@
 % \end{macro}
 % \begin{macro}{\ekvoProcessUnusedGlobalOptions}
 %    \begin{macrocode}
-\protected\def\ekvoProcessUnusedGlobalOptions
+\protected\def\ekvoProcessUnusedGlobalOptions#1%
   {%
-    \ekvo at process@common{\ekvo at ifx@F\@unusedoptionlist\@empty}%
-      {%
-        \let\ekvo at tmp@list\@unusedoptionlist
-        \ekvo at set@handlers at unusedglobal
-        \ekvo at process@list\ekvo at tmp@list
-        \let\ekvo at handle@defined at k\@gobble
-        \let\ekvo at handle@defined at kv\@gobbletwo
-      }%
+    \PackageWarning{expkv-opt}%
+      {This macro no longer works because of changes in the LaTeX2e kernel.}%
   }
 %    \end{macrocode}
 % \end{macro}
@@ -906,8 +962,26 @@
 % \end{macro}
 % \begin{macro}{\ekvoUseUnknownHandlers}
 %    \begin{macrocode}
-\protected\def\ekvoUseUnknownHandlers#1#2%
+\protected\def\ekvoUseUnknownHandlers
+  {\@ifstar\ekvoUseUnknownHandlers at s\ekvoUseUnknownHandlers at n}
+\protected\def\ekvoUseUnknownHandlers at s
   {%
+    \def\ekvo at handle@undefined at k
+      {%
+        \ekv at ifdefined{\ekvo at name{}uN}%
+          {\csname\ekvo at name{}uN\endcsname}%
+          {\@gobble}%
+      }%
+    \long\def\ekvo at handle@undefined at kv##1##2%
+      {%
+        \ekv at ifdefined{\ekvo at name{}u}%
+          {\csname\ekvo at name{}u\endcsname{##2}{##1}}%
+          {}%
+      }%
+    \let\ekvo at if@need at handlers\ekvo at dont@need at handlers
+  }
+\protected\def\ekvoUseUnknownHandlers at n#1#2%
+  {%
     \let\ekvo at handle@undefined at k#1\relax
     \let\ekvo at handle@undefined at kv#2\relax
     \let\ekvo at if@need at handlers\ekvo at dont@need at handlers
@@ -932,6 +1006,7 @@
 % \clearpage
 % \PrintIndex
 %
+% \Finale
 \endinput
 %
 ^^A vim: ft=tex fdm=marker fmr=>>=,=<<

Added: trunk/Master/texmf-dist/tex/generic/expkv-opt/expkv-opt-2020-10-10.sty
===================================================================
--- trunk/Master/texmf-dist/tex/generic/expkv-opt/expkv-opt-2020-10-10.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/generic/expkv-opt/expkv-opt-2020-10-10.sty	2021-04-06 22:16:32 UTC (rev 58772)
@@ -0,0 +1,287 @@
+%%
+%% This is file `expkv-opt-2020-10-10.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% expkv-opt-2020-10-10.dtx  (with options: `pkg')
+%% 
+%% --------------------------------------------------------------
+%% expkv-opt -- parse class and package options with expkv
+%% E-mail: jspratte at yahoo.de
+%% Released under the LaTeX Project Public License v1.3c or later
+%% See http://www.latex-project.org/lppl.txt
+%% --------------------------------------------------------------
+%% 
+%% Copyright (C) 2020 Jonathan P. Spratte
+%% 
+%% This  work may be  distributed and/or  modified under  the conditions  of the
+%% LaTeX Project Public License (LPPL),  either version 1.3c  of this license or
+%% (at your option) any later version.  The latest version of this license is in
+%% the file:
+%% 
+%%   http://www.latex-project.org/lppl.txt
+%% 
+%% This work is "maintained" (as per LPPL maintenance status) by
+%%   Jonathan P. Spratte.
+%% 
+%% This work consists of the file  expkv-opt.dtx
+%% and the derived files           expkv-opt.pdf
+%%                                 expkv-opt.sty
+%% 
+\newcommand*\ekvoVersion{0.1b}
+\newcommand*\ekvoDate{2020-10-10}
+\ProvidesPackage{expkv-opt}
+  [%
+    \ekvoDate\space v\ekvoVersion\space
+    parse class and package options with expkv%
+  ]
+\RequirePackage{expkv}
+\protected\long\def\ekvo at CurrentOption@loop#1#2%
+  {%
+    \ekvo at CurrentOption@loop@#2\ekv at mark#1,\ekv at stop,\ekvo at tail
+  }
+\long\def\ekvo at CurrentOption@loop@#1#2,%
+  {%
+    \ekv at gobble@from at mark@to at stop#2\ekvo at end@loop\ekv at stop
+    \ekv at ifblank{#2}%
+      {}%
+      {%
+        \edef\CurrentOption{\unexpanded\expandafter{\@gobble#2}}%
+        #1{#2}%
+      }%
+    \ekvo at CurrentOption@loop@#1\ekv at mark
+  }
+\long\def\ekvo at end@loop#1\ekvo at tail{}
+\def\ekvo at ifx@TF#1#2{\ifx#1#2\ekv at fi@firstoftwo\fi\@secondoftwo}
+\def\ekvo at ifx@F#1#2{\ifx#1#2\ekv at fi@gobble\fi\@firstofone}
+\protected\def\ekvo at do@with at set#1#2%
+  {%
+    \ekvifdefinedset{#1}%
+      {%
+        \expandafter
+        \let\expandafter\ekvo at name\csname\ekv at undefined@set{#1}\endcsname
+        \def\ekvo at setname{#1}%
+        #2%
+      }%
+      {\ekvo at err@undefined at set{#1}}%
+  }
+\protected\long\def\ekvo at handle@undefined at k@pkg#1%
+  {%
+    \ekv at ifdefined{\ekvo at name{#1}}%
+      {\ekvo at err@value at required{#1}}%
+      {\ekvo at err@undefined at key{#1}}%
+  }
+\def\ekvo at handle@undefined at kv@pkg#1#2%
+  {%
+    \ekv at ifdefined{\ekvo at name{#1}N}%
+      {\ekvo at err@value at forbidden{#1}}%
+      {\ekvo at err@undefined at key{#1}}%
+  }
+\long\def\ekvo at addto@unused at one#1{\ekvo at addto@list\@unusedoptionlist}
+\long\def\ekvo at addto@unused at two#1#2{\ekvo at addto@list\@unusedoptionlist}
+\long\def\ekvo at rmfrom@unused at one#1{\ekvo at rmfrom@list\@unusedoptionlist}
+\long\def\ekvo at rmfrom@unused at two#1#2{\ekvo at rmfrom@list\@unusedoptionlist}
+\protected\def\ekvo at set@handlers at local
+  {%
+    \ekvo at if@need at handlers
+      {%
+        \ifx\@currext\@clsextension
+          \ifx\@classoptionslist\relax
+            \let\ekvo at handle@undefined at k\@gobble
+            \let\ekvo at handle@undefined at kv\@gobbletwo
+          \else
+            \expandafter
+            \ifx\csname opt@\@currname.\@currext\endcsname\@classoptionslist
+              \let\ekvo at handle@undefined at k\ekvo at addto@unused at one
+              \let\ekvo at handle@undefined at kv\ekvo at addto@unused at two
+            \else
+              \let\ekvo at handle@undefined at k\@gobble
+              \let\ekvo at handle@undefined at kv\@gobbletwo
+            \fi
+          \fi
+        \else
+          \let\ekvo at handle@undefined at k\ekvo at handle@undefined at k@pkg
+          \let\ekvo at handle@undefined at kv\ekvo at handle@undefined at kv@pkg
+        \fi
+      }%
+  }
+\protected\def\ekvo at set@handlers at global
+  {%
+    \unless\ifx\@unusedoptionlist\@empty
+      \let\ekvo at handle@defined at k\ekvo at rmfrom@unused at one
+      \let\ekvo at handle@defined at kv\ekvo at rmfrom@unused at two
+    \fi
+    \ekvo at if@need at handlers
+      {%
+        \let\ekvo at handle@undefined at k\@gobble
+        \let\ekvo at handle@undefined at kv\@gobbletwo
+      }%
+  }
+\protected\def\ekvo at set@handlers at unusedglobal
+  {%
+    \ekvo at if@need at handlers
+      {%
+        \let\ekvo at handle@undefined at k\ekvo at addto@unused at one
+        \let\ekvo at handle@undefined at kv\ekvo at addto@unused at two
+        \let\@unusedoptionlist\@empty
+        \@gobbletwo
+      }%
+    \@firstofone
+      {%
+        \let\ekvo at handle@defined at k\ekvo at rmfrom@unused at one
+        \let\ekvo at handle@defined at kv\ekvo at rmfrom@unused at two
+      }%
+  }
+\protected\def\ekvo at set@handlers at list
+  {%
+    \ekvo at if@need at handlers
+      {%
+        \let\ekvo at handle@undefined at k\@gobble
+        \let\ekvo at handle@undefined at kv\@gobbletwo
+      }%
+  }
+\let\ekvo at if@need at handlers\@firstofone
+\protected\long\def\ekvo at dont@need at handlers#1%
+  {%
+    \let\ekvo at if@need at handlers\@firstofone
+  }%
+\let\ekvo at handle@defined at k\@gobble
+\let\ekvo at handle@defined at kv\@gobbletwo
+\protected\def\ekvo at process@common#1#2#3%
+  {%
+    #1{\ekvo at do@with at set{#3}{#2}}%
+  }
+\protected\def\ekvo at process@list#1%
+  {%
+    \expandafter\ekvo at CurrentOption@loop\expandafter{#1}\ekvo at parse
+  }
+\protected\long\def\ekvo at parse#1%
+  {%
+    \ekv at eq@other#1\ekv at nil\ekv at mark\ekv at parse@eq at other@a
+      =\ekv at mark\ekv at parse@eq at active
+    \ekvo at set@k\ekvo at set@kv
+    \ekvo at tail
+  }
+\protected\def\ekvo at set@k#1#2\ekvo at tail
+  {%
+    \ekv at ifdefined{\ekvo at name{#1}N}%
+      {%
+        \ekvo at handle@defined at k{#1}%
+        \csname\ekvo at name{#1}N\endcsname
+      }%
+      {\ekvo at handle@undefined at k{#1}}%
+  }
+\protected\def\ekvo at set@kv#1#2#3\ekvo at tail
+  {%
+    \ekv at ifdefined{\ekvo at name{#1}}%
+      {%
+        \ekvo at handle@defined at kv{#1}{#2}%
+        \csname\ekvo at name{#1}\endcsname{#2}%
+      }%
+      {\ekvo at handle@undefined at kv{#1}{#2}}%
+  }
+\protected\def\ekvo at addto@list#1%
+  {%
+    \ekvo at ifx@TF#1\@empty
+      {\let#1\CurrentOption}%
+      {%
+        \edef#1%
+          {%
+            \unexpanded\expandafter{#1},%
+            \unexpanded\expandafter{\CurrentOption}%
+          }%
+      }%
+  }
+\protected\def\ekvo at rmfrom@list#1%
+  {%
+    \ekvo at ifx@F#1\@empty
+      {%
+        \let\ekvo at tmp@list\@empty
+        \let\ekvo at curropt\CurrentOption
+        \expandafter\ekvo at CurrentOption@loop\expandafter{#1}\ekvo at rmfrom@list@
+        \let\CurrentOption\ekvo at curropt
+        \let#1\ekvo at tmp@list
+      }%
+  }
+\protected\long\def\ekvo at rmfrom@list@#1%
+  {%
+    \ekvo at ifx@F\CurrentOption\ekvo at curropt
+      {\ekvo at addto@list\ekvo at tmp@list}%
+  }
+\protected\def\ekvo at err@undefined at key#1%
+  {%
+    \PackageError{expkv-opt}{Undefined key `#1' in set `\ekvo at setname'}{}%
+  }
+\protected\def\ekvo at err@value at required#1%
+  {%
+    \PackageError{expkv-opt}%
+      {Value required for key `#1' in set `\ekvo at setname'}%
+      {}%
+  }
+\protected\def\ekvo at err@value at forbidden#1%
+  {%
+    \PackageError{expkv-opt}%
+      {Value forbidden for key `#1' in set `\ekvo at setname'}%
+      {}%
+  }
+\protected\def\ekvo at err@undefined at set#1%
+  {%
+    \PackageError{expkv-opt}%
+      {Undefined set `#1'}%
+      {The set for which you try to parse options isn't defined in expkv.}%
+  }
+\protected\def\ekvoProcessLocalOptions
+  {%
+    \ekvo at process@common
+      {\ekv at ifdefined{opt@\@currname.\@currext}\@firstofone\@gobble}%
+      {%
+        \ekvo at set@handlers at local
+        \expandafter
+        \ekvo at process@list\csname opt@\@currname.\@currext\endcsname
+        \AtEndOfPackage{\let\@unprocessedoptions\relax}%
+      }%
+  }
+\protected\def\ekvoProcessGlobalOptions
+  {%
+    \ekvo at process@common{\ekvo at ifx@F\@classoptionslist\relax}%
+      {%
+        \ekvo at set@handlers at global
+        \ekvo at process@list\@classoptionslist
+        \let\ekvo at handle@defined at k\@gobble
+        \let\ekvo at handle@defined at kv\@gobbletwo
+      }%
+  }
+\protected\def\ekvoProcessUnusedGlobalOptions
+  {%
+    \ekvo at process@common{\ekvo at ifx@F\@unusedoptionlist\@empty}%
+      {%
+        \let\ekvo at tmp@list\@unusedoptionlist
+        \ekvo at set@handlers at unusedglobal
+        \ekvo at process@list\ekvo at tmp@list
+        \let\ekvo at handle@defined at k\@gobble
+        \let\ekvo at handle@defined at kv\@gobbletwo
+      }%
+  }
+\protected\def\ekvoProcessOptionsList#1%
+  {%
+    \ekvo at process@common{\ekvo at ifx@F#1\@empty}%
+      {%
+        \ekvo at set@handlers at list
+        \ekvo at process@list#1%
+      }%
+  }
+\protected\def\ekvoUseUnknownHandlers#1#2%
+  {%
+    \let\ekvo at handle@undefined at k#1\relax
+    \let\ekvo at handle@undefined at kv#2\relax
+    \let\ekvo at if@need at handlers\ekvo at dont@need at handlers
+  }
+\@onlypreamble\ekvoProcessLocalOptions
+\@onlypreamble\ekvoProcessGlobalOptions
+\@onlypreamble\ekvoProcessUnusedGlobalOptions
+\@onlypreamble\ekvoProcessOptionsList
+\@onlypreamble\ekvoUseUnknownHandlers
+%% 
+%%
+%% End of file `expkv-opt-2020-10-10.sty'.


Property changes on: trunk/Master/texmf-dist/tex/generic/expkv-opt/expkv-opt-2020-10-10.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/generic/expkv-opt/expkv-opt.sty
===================================================================
--- trunk/Master/texmf-dist/tex/generic/expkv-opt/expkv-opt.sty	2021-04-06 22:14:08 UTC (rev 58771)
+++ trunk/Master/texmf-dist/tex/generic/expkv-opt/expkv-opt.sty	2021-04-06 22:16:32 UTC (rev 58772)
@@ -29,8 +29,19 @@
 %% and the derived files           expkv-opt.pdf
 %%                                 expkv-opt.sty
 %% 
-\newcommand*\ekvoVersion{0.1b}
-\newcommand*\ekvoDate{2020-10-10}
+\IfFormatAtLeastTF{2021/05/01}
+  {}
+  {%
+    \ifx\pkgcls at targetlabel\@empty
+      \ifnum\requestedLaTeXdate=\pkgcls at targetdate
+        \pkgcls at parse@date at arg{=v0.1}%
+      \fi
+    \fi
+  }
+\DeclareRelease{v0.1}{2020/10/10}{expkv-opt-2020-10-10.sty}
+\DeclareCurrentRelease{v0.2}{2021/04/04}
+\newcommand*\ekvoVersion{0.2}
+\newcommand*\ekvoDate{2021-04-04}
 \ProvidesPackage{expkv-opt}
   [%
     \ekvoDate\space v\ekvoVersion\space
@@ -78,10 +89,42 @@
       {\ekvo at err@value at forbidden{#1}}%
       {\ekvo at err@undefined at key{#1}}%
   }
-\long\def\ekvo at addto@unused at one#1{\ekvo at addto@list\@unusedoptionlist}
-\long\def\ekvo at addto@unused at two#1#2{\ekvo at addto@list\@unusedoptionlist}
-\long\def\ekvo at rmfrom@unused at one#1{\ekvo at rmfrom@list\@unusedoptionlist}
-\long\def\ekvo at rmfrom@unused at two#1#2{\ekvo at rmfrom@list\@unusedoptionlist}
+\long\def\ekvo at addto@unused at one#1{\ekvo at do@unusedoptionlist\ekvo at addto@list}
+\long\def\ekvo at addto@unused at two#1#2{\ekvo at do@unusedoptionlist\ekvo at addto@list}
+\long\def\ekvo at rmfrom@unused at one#1%
+  {%
+    \ekvo at ifx@F\@unusedoptionlist\@empty
+      {\ekvo at do@unusedoptionlist\ekvo at rmfrom@list}%
+  }
+\long\def\ekvo at rmfrom@unused at two#1#2%
+  {%
+    \ekvo at ifx@F\@unusedoptionlist\@empty
+      {\ekvo at do@unusedoptionlist\ekvo at rmfrom@list}%
+  }
+\protected\def\ekvo at do@unusedoptionlist#1%
+  {%
+    \let\ekvo at unpreparedCurrentOption\CurrentOption
+    \edef\CurrentOption
+      {\expandafter\ekvo at prepare@unusedoption\CurrentOption=\ekv at mark}%
+    #1\@unusedoptionlist
+    \let\CurrentOption\ekvo at unpreparedCurrentOption
+  }
+\def\ekvo at prepare@unusedoption{\ekvo at prepare@unusedoption at a\@empty}
+\def\ekvo at prepare@unusedoption at a#1%
+  {%
+    \long\def\ekvo at prepare@unusedoption at a##1=##2\ekv at mark
+      {%
+        \ekvo at prepare@unusedoption at b##1\ekv at stop
+          \ekv at mark\ekvo at prepare@unusedoption at b
+          #1\ekv at mark\ekvo at prepare@unusedoption at c
+      }%
+  }
+\ekvo at prepare@unusedoption at a{ }
+\long\def\ekvo at prepare@unusedoption at b#1 #2\ekv at mark#3{#3#1#2\ekv at mark#3}
+\long\def\ekvo at prepare@unusedoption at c
+    #1\ekv at stop
+    \ekv at mark\ekvo at prepare@unusedoption at b\ekv at mark\ekvo at prepare@unusedoption at c
+  {\unexpanded\expandafter{#1}}
 \protected\def\ekvo at set@handlers at local
   {%
     \ekvo at if@need at handlers
@@ -92,7 +135,9 @@
             \let\ekvo at handle@undefined at kv\@gobbletwo
           \else
             \expandafter
-            \ifx\csname opt@\@currname.\@currext\endcsname\@classoptionslist
+            \ifx
+                \csname @raw at opt@\@currname.\@currext\endcsname
+                \@raw at classoptionslist
               \let\ekvo at handle@undefined at k\ekvo at addto@unused at one
               \let\ekvo at handle@undefined at kv\ekvo at addto@unused at two
             \else
@@ -118,21 +163,6 @@
         \let\ekvo at handle@undefined at kv\@gobbletwo
       }%
   }
-\protected\def\ekvo at set@handlers at unusedglobal
-  {%
-    \ekvo at if@need at handlers
-      {%
-        \let\ekvo at handle@undefined at k\ekvo at addto@unused at one
-        \let\ekvo at handle@undefined at kv\ekvo at addto@unused at two
-        \let\@unusedoptionlist\@empty
-        \@gobbletwo
-      }%
-    \@firstofone
-      {%
-        \let\ekvo at handle@defined at k\ekvo at rmfrom@unused at one
-        \let\ekvo at handle@defined at kv\ekvo at rmfrom@unused at two
-      }%
-  }
 \protected\def\ekvo at set@handlers at list
   {%
     \ekvo at if@need at handlers
@@ -234,11 +264,11 @@
 \protected\def\ekvoProcessLocalOptions
   {%
     \ekvo at process@common
-      {\ekv at ifdefined{opt@\@currname.\@currext}\@firstofone\@gobble}%
+      {\ekv at ifdefined{@raw at opt@\@currname.\@currext}\@firstofone\@gobble}%
       {%
         \ekvo at set@handlers at local
         \expandafter
-        \ekvo at process@list\csname opt@\@currname.\@currext\endcsname
+        \ekvo at process@list\csname @raw at opt@\@currname.\@currext\endcsname
         \AtEndOfPackage{\let\@unprocessedoptions\relax}%
       }%
   }
@@ -247,21 +277,15 @@
     \ekvo at process@common{\ekvo at ifx@F\@classoptionslist\relax}%
       {%
         \ekvo at set@handlers at global
-        \ekvo at process@list\@classoptionslist
+        \ekvo at process@list\@raw at classoptionslist
         \let\ekvo at handle@defined at k\@gobble
         \let\ekvo at handle@defined at kv\@gobbletwo
       }%
   }
-\protected\def\ekvoProcessUnusedGlobalOptions
+\protected\def\ekvoProcessUnusedGlobalOptions#1%
   {%
-    \ekvo at process@common{\ekvo at ifx@F\@unusedoptionlist\@empty}%
-      {%
-        \let\ekvo at tmp@list\@unusedoptionlist
-        \ekvo at set@handlers at unusedglobal
-        \ekvo at process@list\ekvo at tmp@list
-        \let\ekvo at handle@defined at k\@gobble
-        \let\ekvo at handle@defined at kv\@gobbletwo
-      }%
+    \PackageWarning{expkv-opt}%
+      {This macro no longer works because of changes in the LaTeX2e kernel.}%
   }
 \protected\def\ekvoProcessOptionsList#1%
   {%
@@ -271,8 +295,26 @@
         \ekvo at process@list#1%
       }%
   }
-\protected\def\ekvoUseUnknownHandlers#1#2%
+\protected\def\ekvoUseUnknownHandlers
+  {\@ifstar\ekvoUseUnknownHandlers at s\ekvoUseUnknownHandlers at n}
+\protected\def\ekvoUseUnknownHandlers at s
   {%
+    \def\ekvo at handle@undefined at k
+      {%
+        \ekv at ifdefined{\ekvo at name{}uN}%
+          {\csname\ekvo at name{}uN\endcsname}%
+          {\@gobble}%
+      }%
+    \long\def\ekvo at handle@undefined at kv##1##2%
+      {%
+        \ekv at ifdefined{\ekvo at name{}u}%
+          {\csname\ekvo at name{}u\endcsname{##2}{##1}}%
+          {}%
+      }%
+    \let\ekvo at if@need at handlers\ekvo at dont@need at handlers
+  }
+\protected\def\ekvoUseUnknownHandlers at n#1#2%
+  {%
     \let\ekvo at handle@undefined at k#1\relax
     \let\ekvo at handle@undefined at kv#2\relax
     \let\ekvo at if@need at handlers\ekvo at dont@need at handlers



More information about the tex-live-commits mailing list.