diff options
author | Karl Berry <karl@freefriends.org> | 2019-11-30 22:19:04 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-11-30 22:19:04 +0000 |
commit | 296ed3e2e65f36c6c418b68a25b6398586f61abf (patch) | |
tree | 179c4df51b037921e794e7a4b92205bd90504dc2 /Master | |
parent | 4b5127164d0e1d685bfd39748c2df3dd613040e1 (diff) |
kvoptions (30nov19)
git-svn-id: svn://tug.org/texlive/trunk@52985 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/latex/kvoptions/README.md | 7 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/kvoptions/example-mycolorsetup.sty | 143 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/kvoptions/kvoptions.pdf | bin | 0 -> 488653 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/kvoptions/kvoptions.dtx | 3376 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/kvoptions/kvoptions-patch.sty | 544 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/kvoptions/kvoptions.sty | 836 | ||||
-rwxr-xr-x | Master/tlpkg/bin/tlpkg-ctan-check | 2 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc | 1 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/kvoptions.tlpsrc | 0 |
9 files changed, 4908 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/kvoptions/README.md b/Master/texmf-dist/doc/latex/kvoptions/README.md new file mode 100644 index 00000000000..b307ffc87f1 --- /dev/null +++ b/Master/texmf-dist/doc/latex/kvoptions/README.md @@ -0,0 +1,7 @@ +# kvoptions + +kvoptions package for LaTeX + +This package is intended for package authors who want to +use options in key value format for their package options. + diff --git a/Master/texmf-dist/doc/latex/kvoptions/example-mycolorsetup.sty b/Master/texmf-dist/doc/latex/kvoptions/example-mycolorsetup.sty new file mode 100644 index 00000000000..7db8cc90e73 --- /dev/null +++ b/Master/texmf-dist/doc/latex/kvoptions/example-mycolorsetup.sty @@ -0,0 +1,143 @@ +%% +%% This is file `example-mycolorsetup.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% kvoptions.dtx (with options: `example') +%% +%% This is a generated file. +%% +%% Project: kvoptions +%% Version: 2019/11/29 v3.13 +%% +%% Copyright (C) +%% 2004, 2006, 2007, 2009-2011 Heiko Oberdiek +%% 2016-2019 Oberdiek Package Support Group +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3c of this license or (at your option) any later +%% version. This version of this license is in +%% https://www.latex-project.org/lppl/lppl-1-3c.txt +%% and the latest version of this license is in +%% https://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of +%% LaTeX version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status "maintained". +%% +%% The Current Maintainers of this work are +%% Heiko Oberdiek and the Oberdiek Package Support Group +%% https://github.com/ho-tex/kvoptions/issues +%% +%% +%% This work consists of the main source file kvoptions.dtx +%% and the derived files +%% kvoptions.sty, kvoptions.pdf, kvoptions.ins, kvoptions.drv, +%% kvoptions-patch.sty, example-mycolorsetup.sty, +%% kvoptions-test1.tex, kvoptions-test2.tex, +%% kvoptions-test3.tex, kvoptions-test4.tex, +%% kvoptions-test4.sty. +%% +%% No we don't need the option 'color'. +%% With color support option 'emphcolor' will dynamically +%% change the color of \emph statements. + % Package identification + % ----------------------- +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{example-mycolorsetup}[2019/11/29 Managing my colors] + +\RequirePackage{iftex} +\RequirePackage{kvoptions} + + % Option declarations + % ------------------- + +\SetupKeyvalOptions{ + family=MCS, + prefix=MCS@ +} + % Use a shorter family name and prefix + + % Option print +\DeclareBoolOption{print} + % is the same as + % \DeclareBoolOption[false]{print} + + % Option driver +\ifpdf + \DeclareStringOption[pdftex]{driver} +\else + \DeclareStringOption[dvips]{driver} +\fi + + % Alternative interface for driver options +\DeclareVoidOption{dvips}{\SetupDriver} +\DeclareVoidOption{dvipdfm}{\SetupDriver} +\DeclareVoidOption{pdftex}{\SetupDriver} + % In \SetupDriver we take the current option \CurrentOption + % and pass it to the driver option. + % The \expandafter commands expand \CurrentOption at the + % time, when \SetupDriver is executed and \CurrentOption + % has the correct meaning. +\newcommand*{\SetupDriver}{% + \expandafter\@SetupDriver\expandafter{\CurrentOption}% +} +\newcommand*{\@SetupDriver}[1]{% + \setkeys{MCS}{driver={#1}}% +} + + % Option emph + % An empty value means, we want to have no color for \emph. + % If the user specifies option emph without value, the red is used. +\DeclareStringOption{emph}[red] + % is the same as + % \DeclareStringOption[]{emph}[red] + + % Default option rule +\DeclareDefaultOption{% + \ifx\CurrentOptionValue\relax + \PackageWarningNoLine{\@currname}{% + Unknown option `\CurrentOption'\MessageBreak + is passed to package `color'% + }% + % Pass the option to package color. + % Again it is better to expand \CurrentOption. + \expandafter\PassOptionsToPackage + \expandafter{\CurrentOption}{color}% + \else + % Package color does not take options with values. + % We provide the standard LaTeX error. + \@unknownoptionerror + \fi +} + + % Process options + % --------------- +\ProcessKeyvalOptions* + + % Implementation depending on option values + % ----------------------------------------- + % Code for print mode +\ifMCS@print + \PassOptionsToPackage{monochrome}{color} + % tells package color to use black and white +\fi + +\RequirePackage[\MCS@driver]{color} + % load package color with the correct driver + + % \emph setup +\ifx\MCS@emph\@empty + % \@empty is a predefined macro with empty contents. + % the option value of option emph is empty, thus + % we do not want a redefinition of \emph. +\else + \renewcommand*{\emph}[1]{% + \textcolor{\MCS@emph}{#1}% + } +\fi +\endinput +%% +%% End of file `example-mycolorsetup.sty'. diff --git a/Master/texmf-dist/doc/latex/kvoptions/kvoptions.pdf b/Master/texmf-dist/doc/latex/kvoptions/kvoptions.pdf Binary files differnew file mode 100644 index 00000000000..d3c53e30962 --- /dev/null +++ b/Master/texmf-dist/doc/latex/kvoptions/kvoptions.pdf diff --git a/Master/texmf-dist/source/latex/kvoptions/kvoptions.dtx b/Master/texmf-dist/source/latex/kvoptions/kvoptions.dtx new file mode 100644 index 00000000000..8dd9701d479 --- /dev/null +++ b/Master/texmf-dist/source/latex/kvoptions/kvoptions.dtx @@ -0,0 +1,3376 @@ +% \iffalse meta-comment +% +% File: kvoptions.dtx +% Version: 2019/11/29 v3.13 +% Info: Key value format for package options +% +% Copyright (C) +% 2004, 2006, 2007, 2009-2011 Heiko Oberdiek +% 2016-2019 Oberdiek Package Support Group +% https://github.com/ho-tex/kvoptions/issues +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3c of this license or (at your option) any later +% version. This version of this license is in +% https://www.latex-project.org/lppl/lppl-1-3c.txt +% and the latest version of this license is in +% https://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of +% LaTeX version 2005/12/01 or later. +% +% This work has the LPPL maintenance status "maintained". +% +% The Current Maintainers of this work are +% Heiko Oberdiek and the Oberdiek Package Support Group +% https://github.com/ho-tex/kvoptions/issues +% +% This work consists of the main source file kvoptions.dtx +% and the derived files +% kvoptions.sty, kvoptions.pdf, kvoptions.ins, kvoptions.drv, +% kvoptions-patch.sty, example-mycolorsetup.sty, +% kvoptions-test1.tex, kvoptions-test2.tex, +% kvoptions-test3.tex, kvoptions-test4.tex, +% kvoptions-test4.sty. +% +% Distribution: +% CTAN:macros/latex/contrib/kvoptions/kvoptions.dtx +% CTAN:macros/latex/contrib/kvoptions/kvoptions.pdf +% +% Unpacking: +% (a) If kvoptions.ins is present: +% tex kvoptions.ins +% (b) Without kvoptions.ins: +% tex kvoptions.dtx +% (c) If you insist on using LaTeX +% latex \let\install=y\input{kvoptions.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% (a) If kvoptions.drv is present: +% latex kvoptions.drv +% (b) Without kvoptions.drv: +% latex kvoptions.dtx; ... +% The class ltxdoc loads the configuration file ltxdoc.cfg +% if available. Here you can specify further options, e.g. +% use A4 as paper format: +% \PassOptionsToClass{a4paper}{article} +% +% Programm calls to get the documentation (example): +% pdflatex kvoptions.dtx +% makeindex -s gind.ist kvoptions.idx +% pdflatex kvoptions.dtx +% makeindex -s gind.ist kvoptions.idx +% pdflatex kvoptions.dtx +% +% Installation: +% TDS:tex/latex/kvoptions/kvoptions.sty +% TDS:tex/latex/kvoptions/kvoptions-patch.sty +% TDS:doc/latex/kvoptions/kvoptions.pdf +% TDS:doc/latex/kvoptions/example-mycolorsetup.sty +% TDS:source/latex/kvoptions/kvoptions.dtx +% +%<*ignore> +\begingroup + \catcode123=1 % + \catcode125=2 % + \def\x{LaTeX2e}% +\expandafter\endgroup +\ifcase 0\ifx\install y1\fi\expandafter + \ifx\csname processbatchFile\endcsname\relax\else1\fi + \ifx\fmtname\x\else 1\fi\relax +\else\csname fi\endcsname +%</ignore> +%<*install> +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: kvoptions 2019/11/29 v3.13 Key value format for package options (HO)} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\let\MetaPrefix\relax +\preamble + +This is a generated file. + +Project: kvoptions +Version: 2019/11/29 v3.13 + +Copyright (C) + 2004, 2006, 2007, 2009-2011 Heiko Oberdiek + 2016-2019 Oberdiek Package Support Group + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3c of this license or (at your option) any later +version. This version of this license is in + https://www.latex-project.org/lppl/lppl-1-3c.txt +and the latest version of this license is in + https://www.latex-project.org/lppl.txt +and version 1.3 or later is part of all distributions of +LaTeX version 2005/12/01 or later. + +This work has the LPPL maintenance status "maintained". + +The Current Maintainers of this work are +Heiko Oberdiek and the Oberdiek Package Support Group +https://github.com/ho-tex/kvoptions/issues + + +This work consists of the main source file kvoptions.dtx +and the derived files + kvoptions.sty, kvoptions.pdf, kvoptions.ins, kvoptions.drv, + kvoptions-patch.sty, example-mycolorsetup.sty, + kvoptions-test1.tex, kvoptions-test2.tex, + kvoptions-test3.tex, kvoptions-test4.tex, + kvoptions-test4.sty. + +\endpreamble +\let\MetaPrefix\DoubleperCent + +\generate{% + \file{kvoptions.ins}{\from{kvoptions.dtx}{install}}% + \file{kvoptions.drv}{\from{kvoptions.dtx}{driver}}% + \usedir{tex/latex/kvoptions}% + \file{kvoptions.sty}{\from{kvoptions.dtx}{package}}% + \file{kvoptions-patch.sty}{\from{kvoptions.dtx}{patch}}% + \usedir{doc/latex/kvoptions}% + \file{example-mycolorsetup.sty}{\from{kvoptions.dtx}{example}}% +% \usedir{doc/latex/kvoptions/test}% +% \file{kvoptions-test1.tex}{\from{kvoptions.dtx}{test1}}% +% \file{kvoptions-test2.tex}{\from{kvoptions.dtx}{test2}}% +% \file{kvoptions-test3.tex}{\from{kvoptions.dtx}{test3}}% +% \file{kvoptions-test4.tex}{\from{kvoptions.dtx}{test4}}% +% \file{kvoptions-test4.sty}{\from{kvoptions.dtx}{test4pkg}}% + \nopreamble + \nopostamble +% \usedir{source/latex/kvoptions/catalogue}% +% \file{kvoptions.xml}{\from{kvoptions.dtx}{catalogue}}% +} + +\catcode32=13\relax% active space +\let =\space% +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* files into a directory searched by TeX:} +\Msg{*} +\Msg{* kvoptions.sty, kvoptions-patch.sty} +\Msg{*} +\Msg{* To produce the documentation run the file `kvoptions.drv'} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +%</install> +%<*ignore> +\fi +%</ignore> +%<*driver> +\NeedsTeXFormat{LaTeX2e} +\ProvidesFile{kvoptions.drv}% + [2019/11/29 v3.13 Key value format for package options (HO)]% +\documentclass{ltxdoc} +\usepackage{holtxdoc}[2011/11/22] +\begin{document} + \DocInput{kvoptions.dtx}% +\end{document} +%</driver> +% \fi +% +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \GetFileInfo{kvoptions.drv} +% +% \title{The \xpackage{kvoptions} package} +% \date{2019/11/29 v3.13} +% \author{Heiko Oberdiek\thanks +% {Please report any issues at \url{https://github.com/ho-tex/kvoptions/issues}}} +% +% \maketitle +% +% \begin{abstract} +% This package is intended for package authors who want to +% use options in key value format for their package options. +% \end{abstract} +% +% \tableofcontents +% +% \def\M#1{\texttt{\{}\meta{#1}\texttt{\}}} +% \def\O#1{\texttt{[}\meta{#1}\texttt{]}} +% +% \section{Introduction} +% +% First I want to recommend the very good review article +% ``A guide to key-value methods'' by Joseph Wright \cite{tb94wright}. +% It introduces the different key-value packages and compares them. +% +% \subsection{The beginning} +% +% This package \xpackage{kvoptions} addresses class or package writers +% that want to allow their users to specify options +% as key value pairs, e.g.: +% \begin{quote} +% |\documentclass[verbose=false,name=me]{myclass}|\\ +% |\usepackage[format=print]{mylayout}| +% \end{quote} +% Prominent example is package \xpackage{hyperref}, +% probably the first package that offers this service. +% It's \cs{ProcessOptionsWithKV} is often copied und +% used in other packages, e.g. package \xpackage{helvet} +% that uses this interface for its option \xoption{scaled}. +% +% However copying code is not the most modern software +% development technique. And \xpackage{hyperref}'s +% code for \cs{ProcessOptionsWithKV} was changed +% to fix bugs. The version used in other packages +% depends on the time of copying and the awareness +% of \xpackage{hyperref}'s changes. +% Now the code is sourced out into this package and +% available for other package or class writers. +% +% \subsection{Overview} +% +% Package \xpackage{kvoptions} connects package +% \xpackage{\emph{k}ey\emph{v}al} +% with \LaTeX's package and class \emph{options}: +% \begin{center} +% \def\T#1{\bfseries #1} +% \renewcommand{\arraystretch}{1.5} +% \begin{tabular}{l|l|l} +% \T{Package \xpackage{keyval}} +% & \T{Package \xpackage{kvoptions}} +% & \T{\LaTeX\ kernel} +% \\ +% \hline +% \cs{define@key} +% & +% \renewcommand*{\arraystretch}{1}^^A +% \begin{tabular}[t]{@{}l@{}} +% \cs{DeclareVoidOption}\\ +% \cs{DeclareStringOption}\\ +% \cs{DeclareBoolOption}\\ +% \cs{DeclareComplementaryOption}\\ +% \cs{DisableKeyvalOption} +% \end{tabular} +% & \cs{DeclareOption} +% \\ +% \hline +% & \cs{DeclareDefaultOption} +% & \cs{DeclareOption*} +% \\ +% \hline +% & \cs{ProcessKeyvalOptions} +% & \cs{ProcessOptions*} +% \\ +% \hline +% & Option \xoption{patch} +% & +% \renewcommand*{\arraystretch}{1}^^A +% \begin{tabular}[t]{@{}l@{}} +% Class/package\\ +% option system +% \end{tabular} +% \\ +% \hline +% & \cs{SetupKeyvalOptions} & +% \\ +% \end{tabular} +% \end{center} +% +% \hypersetup{bookmarksopenlevel=3} +% \section{Usage} +% +% \subsection{Process options} +% +% \subsubsection{\cs{ProcessKeyvalOptions}} +% +% \begin{declcs}{ProcessKeyvalOptions}\,\M{family}\\ +% \cs{ProcessKeyvalOptions} \* +% \end{declcs} +% This command evaluates the global or local options of +% the package that are defined with \xpackage{keyval}'s +% interface within the family \meta{family}. It acts the +% same way as \LaTeX's \cs{ProcessOptions*}. In a package +% unknown global options are ignored, in a class they +% are added to the unknown option list. The known global +% options and all local options are passed to \xpackage{keyval}'s +% \cs{setkeys} command for executing the options. +% Unknown options are reported to the user by an error. +% +% If the family name happens to be the same as the name +% of the package or class where \cs{ProcessKeyvalOptions} +% is used or the family name has previously been setup by +% \cs{SetupKeyvalOptions}, then \cs{ProcessKeyvalOptions} +% knows the family name already and you can use the star form +% without mandatory argument. +% +% \subsubsection{\cs{ProcessLocalKeyvalOptions}} +% +% \begin{declcs}{ProcessLocalKeyvalOptions}\,\M{family}\\ +% \cs{ProcessLocalKeyvalOptions} \* +% \end{declcs} +% This macro has the same syntax and works similar as +% \cs{ProcessKeyvalOptions}. However it ignores +% global options and only processes the local package options. +% Therefore it only can be used inside a package. +% An error is thrown, if it is used inside a class. +% +% Neither of the following macros are necessary for +% \cs{ProcessKeyvalOptions{}}. They just help the package/class +% author in common tasks. +% +% \subsubsection{\cs{SetupKeyvalOptions}}\label{setup} +% +% \begin{declcs}{SetupKeyvalOptions}\,\texttt{\{}\\ +% \hspace{1.5em}|family|\,|=|\,\meta{family}|,|\\ +% \hspace{1.5em}|prefix|\,|=|\,\meta{prefix}\\ +% \hspace{1.5em}|setkeys|\,|=|\,\meta{setkeys command}\\ +% \texttt{\}} +% \end{declcs} +% This command allows to configure the default assumptions +% that are based on the current package or class name. +% \LaTeX\ remembers this name in \cs{@currname}. The syntax +% description of the default looks a little weird, therefor +% an example is given for a package or class named |foobar|. +% \begin{quote} +% \begin{tabular}{@{}l|ll|l@{}} +% Key & Default & (example) & Used by\\ +% \hline +% \rule{0pt}{1.2\ht\csname @arstrutbox\endcsname}^^A +% |family| & \meta{\cs{@currname}} & (|foobar|) +% & \cs{ProcessKeyvalOptions*} \\ +% &&& \cs{DeclareBoolOption} \\ +% &&& \cs{DeclareStringOption} \\ +% \hline +% \rule{0pt}{1.2\ht\csname @arstrutbox\endcsname}^^A +% |prefix| & \meta{\cs{@currname}}|@| & (|foobar@|) +% & \cs{DeclareBoolOption} \\ +% &&& \cs{DeclareStringOption} \\ +% &&& \cs{DeclareVoidOption} \\ +% \hline +% \rule{0pt}{1.2\ht\csname @arstrutbox\endcsname}^^A +% |setkeys| & \cs{setkeys} & (\cs{kvsetkeys}) +% & \cs{ProcessKeyvalOptions} \\ +% &&& \cs{ProcessLocalKeyvalOptions} +% \end{tabular} +% \end{quote} +% Key |setkeys| was added in version 3.9. The original +% \cs{setkeys} of package \xpackage{keyval} is not reentrant. +% If an option is processed by this \cs{setkeys}, then +% the option should not call \cs{setkeys} again with a +% different family. Otherwise the next options of the +% first \cs{setkeys} call are processed with the wrong +% family. With key |setkeys| the macro \cs{kvsetkeys} +% can be set that does not have the problem of the +% original \cs{setkeys} of package {keyval}. +% +% Probably \cs{setkeys} of package \xpackage{xkeyval} +% is safe in this respect. But I haven't made a full +% analysis. At least it does not have the problem +% of the original \cs{setkeys}. +% +% \subsection{Option declarations} +% +% The options for \cs{ProcessKeyvalOptions} are defined +% by \xpackage{keyval}'s \cs{define@key}. +% Common purposes of such keys are boolean switches, they +% enable or disable something. Or they store a name or some kind of +% string in a macro. The following commands help the user. He +% declares what he wants and \xpackage{kvoptions} take care of +% the key definition, resource allocation and initialization. +% +% In order to avoid name clashes of macro names, internal +% commands are prefixed. Both the prefix and the family +% name for the defined keys can be configured by +% \cs{SetupKeyvalOptions}. +% +% \subsubsection{\cs{DeclareStringOption}} +% +% \begin{declcs}{DeclareStringOption}\,\O{init}\,\M{key}\,\O{default} +% \end{declcs} +% A macro is created that remembers the value of the key \meta{key}. +% The name of the macro consists of the option name \meta{key} that +% is prefixed by the prefix (see \ref{setup}). +% The initial contents of the +% macro can be given by the first optional argument \meta{init}. +% The default is empty. +% +% The the option \meta{key} is defined. The option code +% just stores its value in the macro. If the optional argument +% at the end of \cs{DeclareStringOption} is given, then option +% \meta{key} is defined with the default \meta{default}. +% +% Example for a package with the following two lines: +% \begin{quote} +% |\ProvidesPackage{foobar}|\\ +% |\DeclareStringOption[me]{name}| +% \end{quote} +% Then \cs{DeclareStringOption} defines the macro with content |me|, +% note \LaTeX\ complains if the name of the macro already exists: +% \begin{quote} +% |\newcommand*{\foobar@name}{me}| +% \end{quote} +% The option definition is similar to: +% \begin{quote} +% |\define@key{foobar}{name}{%|\\ +% | \renewcommand*{\foobar@name}{#1}%|\\ +% |}| +% \end{quote} +% +% \subsubsection{\cs{DeclareBoolOption}} +% +% \begin{declcs}{DeclareBoolOption}\,\O{init}\,\M{key} +% \end{declcs} +% A boolean switch is generated, initialized by value \meta{init} +% and the corresponding key \meta{key} is defined. If the +% initialization value is not given, |false| is used as default. +% +% The internal actions of \cs{DeclareBoolOption} are shown below. +% The example is given for a package author who has the following +% two lines in his package/class: +% \begin{quote} +% |\ProvidesPackage{foobar}|\\ +% |\DeclareBoolOption{verbose}| +% \end{quote} +% First a new switch is created: +% \begin{quote} +% |\newif\iffoobar@verbose| +% \end{quote} +% and initialized: +% \begin{quote} +% |\foobar@verbosefalse| +% \end{quote} +% Finally the key is defined: +% \begin{quote} +% |\define@key{foobar}{verbose}[true]{|\dots|}| +% \end{quote} +% The option code configures the boolean option in the following way: +% If the author specifies |true| or |false| then the switch is +% turned on or off respectivly. Also the option can be given without +% explicit value. Then the switch is enabled. +% Other values are reported as errors. +% +% Now the switch is ready to use in the package/class, e.g.: +% \begin{quote} +% |\iffoobar@verbose|\\ +% \qquad\textit{\% print verbose message}\\ +% |\else|\\ +% \qquad\textit{\% be quiet}\\ +% |\fi| +% \end{quote} +% Users of package \cs{ifthen} can use the switch as +% boolean: +% \begin{quote} +% |\boolean{foobar@verbose}| +% \end{quote} +% +% \subsubsection{\cs{DeclareComplementaryOption}} +% +% \begin{declcs}{DeclareComplementaryOption}\,\M{key}\,\M{parent} +% \end{declcs} +% Sometimes contrasting names are used to characterize the +% two states of a boolean switch, for example \xoption{draft} +% vs.\@ \xoption{final}. Both options behave like boolean +% options but they do not need two different switches, they +% should share one. \cs{DeclareComplementaryOption} allows this. +% The option \meta{key} shares the switch of option \meta{parent}. +% Example: +% \begin{quote} +% |\DeclareBoolOption{draft}|\\ +% |\DeclareComplementaryOption{final}{draft}| +% \end{quote} +% Then |final| sets the switch of \xoption{draft} to |false|, and +% |final=false| enables the \xoption{draft} switch. +% +% \subsubsection{\cs{DeclareVoidOption}} +% +% \begin{declcs}{DeclareVoidOption}\,\M{key}\,\M{code} +% \end{declcs} +% \cs{ProcessKeyvalOptions} can be extended to recognize +% options that are declared in traditional way by \cs{DeclareOption}. +% But in case of the error that the user specifies a value, then +% this option would not recognized as key value option because +% of \cs{DeclareOption} and not detected as traditional option +% because of the value part. The user would get an unknown option +% error, difficult to understand. +% +% \cs{DeclareVoidOption} solves +% this problem. It defines the option \meta{key} as key value option. +% If the user specifies a value, a warning is given and the +% value is ignored. +% +% The code part \meta{code} is stored in a macro. +% The name of the macro consists of the option name \meta{key} that +% is prefixed by the prefix (see \ref{setup}). +% If the option is set, the macro will be executed. During the +% execution \cs{CurrentOption} is available with the current key name. +% +% \subsubsection{\cs{DeclareDefaultOption}} +% +% \begin{declcs}{DeclareDefaultOption}\,\M{code} +% \end{declcs} +% \begin{sloppypar} +% This command does not define a specific key, it is the equivalent +% to \LaTeX's \cs{DeclareOption*}. It allows the specification +% of a default action \meta{code} that is invoked if an unknown option +% is found. +% While \meta{code} is called, +% macro \cs{CurrentOption} contains the current option string. +% In addition \cs{CurrentOptionValue} contains the value part +% if the option string is parsable as key value pair, otherwise +% it is \cs{relax}. \cs{CurrentOptionKey} contains the key of +% the key value pair, or the whole option string, if it misses +% the equal sign. +% \end{sloppypar} +% +% Inside packages typical default actions are to pass unknown +% options to another package. Or an error message can be thrown +% by \cs{@unknownoptionerror}. This is the original error +% message that \LaTeX\ gives for unkown package options. +% This error message is easier to understand for the user +% as the error message from package \xpackage{keyval} that +% is given otherwise. +% +% A Class ignores unknown options and puts them on the +% unused option list. Let \LaTeX\ do the job and just +% call \cs{OptionNotUsed}. Or the options can be passed to +% another class that is later loaded. +% +% \subsubsection{Local options} +% +% \begin{declcs}{DeclareLocalOption} \M{option}\\ +% \cs{DeclareLocalOptions} \M{option list} +% \end{declcs} +% Both macros mark package options as local options. That means +% that they are ignored by \cs{ProcessKeyvalOptions} if they are given +% as global options. \cs{DeclareLocalOptions} takes one option, +% \cs{DeclareLocalOptions} expects a comma separated list of options. +% +% \subsubsection{Dynamic options} +% +% Options of \LaTeX's package/class system are cleared +% in \cs{ProcessOptions}. They modify the static model +% of a package. For example, depending on option \xoption{bookmarks} +% package \xpackage{hyperref} loads differently. +% +% Options, however, +% defined by \xpackage{keyval}'s \cs{define@key} remain +% defined, if the options are processed by \cs{setkeys}. +% Therefore these options can also be used to model +% the dynamic behaviour of a package. For example, in +% \xpackage{hyperref} the link colors can be changed +% everywhere until the end in |\end{document}|. +% +% However package \xpackage{color} that adds color support +% is necessary and it +% cannot be loaded after |\begin{document}|. Option \xoption{colorlinks} +% that loads \xpackage{color} should be active until |\begin{document}| +% and die in some way if it is too late for loading packages. +% With \cs{DisableKeyvalOption} the package/class author can +% specify and configure the death of an option and controls +% the life period of the option. +% +% \subsubsection{\cs{DisableKeyvalOption}} +% +% \begin{declcs}{DisableKeyvalOption}\,\O{options}\,\M{family}\,\M{key} +% \\[0.5ex] +% \meta{options}:\\ +% \hspace{1.5em}^^A +% \begin{tabular}[t]{@{}l@{ \texttt{=} }l@{\qquad}>{default: }l@{}} +% |action| & |undef|, |warning|, |error|, or |ignore| +% & |undef| +% \\ +% \multicolumn{1}{@{}l}{|global| or |local|} & & |global| +% \\ +% |package| or |class| & \meta{name} +% \\ +% \end{tabular}^^A +% \end{declcs} +% \cs{DisableKeyvalOption} can be called to mark the end when +% the option \meta{key} is no longer useful. The behaviour of +% an option after its death can be configured by \xoption{action}: +% \begin{description} +% \item[\texttt{undef}:] The option will be undefined, +% If it is called, \cs{setkeys} reports an error because +% of unknown key. +% \item[\texttt{error} or \texttt{warning}:] Use of the +% option will cause an error or warning message. +% Also these actions require that exclusivly either the +% package or class name is given in options \xoption{package} +% or \xoption{class}. +% \item[\texttt{ignore}:] The use of the option will silently +% be ignored. +% \end{description} +% The option's death can be limited to the end of the current +% group, if option \xoption{local} is given. Default is +% \xoption{global}. +% +% The package/class author can wish the end of the option +% already during the package loading, then he will have +% static behaviour. In case of dynamic options \cs{DisableKeyvalOption} +% can be executed everywhere, also outside the package. Therefore +% the family name and the package/class name is usually unknown for +% \cs{DisableKeyvalOption}. Therefore the argument for the family +% name is mandatory and for some actions the package/class name +% must be provided. +% +% Usually a macro would configure the option death, Example: +%\begin{quote} +%\begin{verbatim} +%\ProvidesPackage{foobar} +%\DeclareBoolOption{color} +%\DeclareStringOption[red]{emphcolor} +%\ProcessKeyvalOptions* +% +%\newcommand*{\foobar@DisableOption}[2]{% +% \DisableKeyvalueOption[ +% action={#1}, +% package=foobar +% ]{foobar}{#2}% +%} +% +%\iffoobar@color +% \RequirePackage{color} +% \renewcommand*{\emph}[1]{\textcolor{\foobar@emphcolor}{#1}} +%\else +% % Option emphcolor is not wrong, if we have color support. +% % otherwise the option has no effect, but we don't want to +% % remove it. Therefore action 'ignore' is the best choice: +% \foobar@DisableOption{ignore}{emphcolor} +%\fi +%% No we don't need the option 'color'. +%\foobar@DisableOption{warning}{color} +% +%% With color support option 'emphcolor' will dynamically +%% change the color of \emph statements. +%\end{verbatim} +%\end{quote} +% +% \subsubsection{\cs{AddToKeyvalOption}} +% +% \begin{declcs}{AddToKeyvalOption}\,\M{family}\,\M{key}\,\M{code}\\ +% \cs{AddToKeyvalOption} \*\,\M{key}\,\M{code} +% \end{declcs} +% The code for an existing key \meta{key} of family \meta{family} is +% extended by code \meta{code}. In the starred form the current +% family setting is used, see \cs{ProcessKeyvalOptions*}. +% +% \subsection{Global vs. local options} +% +% Options that are given for \cs{documentclass} are called +% global options. They are known to the class and all packages. +% A package may make use of a global option and marks it as +% used. The advantage for the user is the freedom to specify +% options both in the \cs{documentclass} or \cs{usepackage} +% commands. +% +% However global options are shared with the class options +% and options of all other packages. Thus there can be the +% same option with different semantics for different +% packages and classes. As example, package \xpackage{bookmark} +% knows option \xoption{open} that specifies whether the bookmarks +% are opened or closed initially. It's values are |true| or |false|. +% Since KOMA-Script version 3.00 the KOMA classes also introduces +% option \xoption{open} with values |right| and |any| and a +% complete different meaning. +% +% Such conflicts can be resolved by marking all or part of options +% as local by \cs{DeclareLocalOption} or \cs{DeclareLocalOptions}. +% Then the packages ignores global occurences of these options. +% Package \xpackage{kvoptions} provides two methods: +% \begin{itemize} +% \item \cs{ProcessLocalKeyvalOptions} automatically uses all options +% as local options. It ignores all global options. +% \item \cs{DeclareLocalOption} or \cs{DeclareLocalOptions} marks +% options as local options. \cs{ProcessKeyvalOptions} will then +% ignore global occurences for these local options. +% \end{itemize} +% Since version 1.5 package \xpackage{bookmark} uses the latter +% method. It checks global and local option places for driver options +% and limits all other options as local options. Thus the class +% option \xoption{open} of KOMA-Script is not misread as +% option for package \xpackage{bookmark}. +% +% \subsection{Summary of internal macros} +% +% The \cs{Declare}\texttt{\dots Option} commands define +% macros, additionally to the macros generated by the key definition. +% These macros can be used by the package/class author. +% The name of the macros starts with the prefix \meta{prefix} +% that can be configured by \cs{SetupKeyvalOptions}. +% \begin{center} +% \def\prefix{\cs{}\meta{prefix}\meta{key}}^^A +% \def\Hline{^^A +% \hline +% \rule{0pt}{1.2\ht\csname @arstrutbox\endcsname}^^A +% }^^A +% \begin{tabular}{@{}l|>{\ttfamily}l|l@{}} +% Declare \meta{key} & \textrm{Defined macro} & Description\\ +% \Hline +% \cs{DeclareStringOption} +% & \prefix & holds the string\\ +% \Hline +% \cs{DeclareBoolOption} +% & \cs{if}\meta{prefix}\meta{key}& boolean switch\\ +% &\prefix false& disable switch\\ +% &\prefix true& enable switch\\ +% \Hline +% \cs{DeclareComplementaryOption} +% & \prefix false& enable parent switch\\ +% & \prefix true& disable parent switch\\ +% \Hline +% \cs{DeclareVoidOption} +% & \prefix & holds the action +% \end{tabular} +% \end{center} +% +% \subsection{\plainTeX} +% +% Package \xpackage{keyval} is also usable in \plainTeX\ with +% the help of file \xfile{miniltx.tex}. Some features of this +% package \xpackage{kvoptions} might also be useful for \plainTeX. +% If \LaTeX\ is not found, \cs{ProcessKeyvalOptions} and option +% \xoption{patch} are disabled. Before using the option declaration +% commands \cs{Declare...Option}, \cs{SetupKeyvalOptions} must be +% used. +% +% \hypersetup{bookmarksopenlevel=1} +% +% \section{Example} +% +% The following example defined a package that serves some +% private color management. A boolean option \xoption{print} enables +% print mode without colors. An option \xoption{emph} redefines +% \cs{emph} to print in the given color. And the driver +% can be specified by option \xoption{driver}. +% +% \begin{macrocode} +%<*example> + % Package identification + % ----------------------- +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{example-mycolorsetup}[2019/11/29 Managing my colors] + +\RequirePackage{iftex} +\RequirePackage{kvoptions} + + % Option declarations + % ------------------- + +\SetupKeyvalOptions{ + family=MCS, + prefix=MCS@ +} + % Use a shorter family name and prefix + + % Option print +\DeclareBoolOption{print} + % is the same as + % \DeclareBoolOption[false]{print} + + % Option driver +\ifpdf + \DeclareStringOption[pdftex]{driver} +\else + \DeclareStringOption[dvips]{driver} +\fi + + % Alternative interface for driver options +\DeclareVoidOption{dvips}{\SetupDriver} +\DeclareVoidOption{dvipdfm}{\SetupDriver} +\DeclareVoidOption{pdftex}{\SetupDriver} + % In \SetupDriver we take the current option \CurrentOption + % and pass it to the driver option. + % The \expandafter commands expand \CurrentOption at the + % time, when \SetupDriver is executed and \CurrentOption + % has the correct meaning. +\newcommand*{\SetupDriver}{% + \expandafter\@SetupDriver\expandafter{\CurrentOption}% +} +\newcommand*{\@SetupDriver}[1]{% + \setkeys{MCS}{driver={#1}}% +} + + % Option emph + % An empty value means, we want to have no color for \emph. + % If the user specifies option emph without value, the red is used. +\DeclareStringOption{emph}[red] + % is the same as + % \DeclareStringOption[]{emph}[red] + + % Default option rule +\DeclareDefaultOption{% + \ifx\CurrentOptionValue\relax + \PackageWarningNoLine{\@currname}{% + Unknown option `\CurrentOption'\MessageBreak + is passed to package `color'% + }% + % Pass the option to package color. + % Again it is better to expand \CurrentOption. + \expandafter\PassOptionsToPackage + \expandafter{\CurrentOption}{color}% + \else + % Package color does not take options with values. + % We provide the standard LaTeX error. + \@unknownoptionerror + \fi +} + + % Process options + % --------------- +\ProcessKeyvalOptions* + + % Implementation depending on option values + % ----------------------------------------- + % Code for print mode +\ifMCS@print + \PassOptionsToPackage{monochrome}{color} + % tells package color to use black and white +\fi + +\RequirePackage[\MCS@driver]{color} + % load package color with the correct driver + + % \emph setup +\ifx\MCS@emph\@empty + % \@empty is a predefined macro with empty contents. + % the option value of option emph is empty, thus + % we do not want a redefinition of \emph. +\else + \renewcommand*{\emph}[1]{% + \textcolor{\MCS@emph}{#1}% + } +\fi +%</example> +% \end{macrocode} +% +% \section{Package options} +% +% The package \xpackage{kvoptions} knows two package options +% \xoption{patch} and \xoption{debugshow}. +% The options of package \xpackage{kvoptions} are intended +% for authors, not for package/class writers. Inside a package +% it is too late for option \xoption{patch} and \xoption{debugshow} +% enables some messages that are perhaps useful for the debugging +% phase. Also \LaTeX\ is unhappy if a package is loaded +% later again with options that are previously not given. +% Thus package and class authors, stay with |\RequirePackage{kvoptions}| +% without options. +% +% Option \xoption{patch} loads package \xpackage{kvoptions-patch}. +% +% \subsection{Package \xpackage{kvoptions-patch}} +% +% \LaTeX's system of package/class options has some severe limitations +% that especially affects the value part if options are used as +% pair of key and value. +% \begin{itemize} +% \item Spaces are removed, regardless where: +% \begin{quote} +% |\documentclass[box=0 0 400 600]{article}| +% \end{quote} +% Now each package will see |box=00400600| as global option. +% \item In the previous case also braces would not help: +% \begin{quote} +% |\documentclass[box={0 0 400 600}]{article}| +% \end{quote} +% The result is an error message: +% \begin{quote} +% |! LaTeX Error: Missing \begin{document}.| +% \end{quote} +% As local option, however, it works if the package +% knows about key value options (By using this package, for example). +% \item The requirements on robustness are extremly high. +% \LaTeX\ expands the option. All that will not work as environment +% name will break also as option. Even a \cs{relax} will generate +% an error message: +% \begin{quote} +% |! Missing \endcsname inserted.| +% \end{quote} +% Of course, \LaTeX\ does not use its protecting mechanisms. +% On contrary \cs{protect} itself will cause errors. +% \item The options are expanded. But perhaps the package will +% do that, because it has to setup some things before? +% Example \xpackage{hyperref}: +% \begin{quote} +% |\usepackage[pdfauthor=M\"uller]{hyperref}| +% \end{quote} +% Package \xpackage{hyperref} does not see |M\"uller| but +% its expansion and it does not like it, you get many warnings +% \begin{quote} +% |Token not allowed in a PDFDocEncoded string| +% \end{quote} +% And the title becomes: |Mu127uller|. +% Therefore such options must usually be given after package +% \xpackage{hyperref} +% is loaded: +% \begin{quote} +% |\usepackage{hyperref}|\\ +% |\hypersetup{pdfauthor=Fran\c coise M\"uller}| +% \end{quote} +% As package option it will even break with |Fran\c coise| +% because of the cedilla |\c c|, it is not robust enough. +% \end{itemize} +% For users that do not want with this limitations the package +% offers package \xoption{kvoptions-patch}. It patches \LaTeX's option system +% and tries to teach it also to handle options that are given +% as pairs of key and value and to prevent expansion. +% It can already be used at the very beginning, before \cs{documentclass}: +% \begin{quote} +% |\RequirePackage{kvoptions-patch}|\\ +% |\documentclass[pdfauthor=Fran\c coise M\"uller]{article}|\\ +% |\usepackage{hyperref}| +% \end{quote} +% The latest time is before the package where you want to use +% problematic values: +% \begin{quote} +% |\usepackage{kvoptions-patch}|\\ +% |\usepackage[Fran\c coise M\"uller]{hyperref}| +% \end{quote} +% Some remarks: +% \begin{itemize} +% \item The patch requires \eTeX, its \cs{unexpanded} feature +% is much too nice. It is possible to work around using token +% registers. But the code becomes longer, slower, more difficult +% to read and maintain. The package without option \xoption{patch} +% works and will work without \eTeX. +% \item The code for the patch is quite long, there are many test +% cases. Thus the probability for bugs is probably not too small. +% \item Since 2008/10/18 v3.0 package \xpackage{kvoptions-patch} is +% available. Before option \xoption{patch} of package \xpackage{kvoptions} +% must be used instead. I think, the solution as standalone package +% \xpackage{kvoptions-patch} is cleaner and avoids option clashes. +% \end{itemize} +% +% \subsection{Option \xoption{debugshow}} +% +% The name of this option follows the convention of packages +% \xpackage{multicol}, \xpackage{tabularx}, and \xpackage{tracefnt}. +% Currently it prints the setting of boolean options, declared +% by \cs{DeclareBoolOption} in the \xfile{.log} file, if that +% boolean option is used. +% You can activate the option by +% \begin{itemize} +% \item |\PassOptionsToPackage{debugshow}{kvoptions}|\\ +% Put this somewhere before package \xpackage{kvoptions} is +% loaded first, e.g. before \cs{documentclass}. +% \item |\RequirePackage[debugshow]{kvoptions}|\\ +% Before \cs{documentclass} even an author has to use +% \cs{RequirePackage}. \cs{usepackage} only works after +% \cs{documentclass}. +% \end{itemize} +% The preferred method is \cs{PassOptionsToPackage}, because +% it does not force the package loading and does not disturb, +% if the package is not loaded later at all. +% +% \section{Limitations} +% +% \subsection{Compatibility} +% \subsubsection{Package \xpackage{kvoptions-patch} vs. package \xpackage{xkvltxp}} +% +% Package \xpackage{xkvltxp} from the \xpackage{xkeyval} project +% has the same goal as package \xpackage{kvoptions-patch} +% and to patch \LaTeX's kernel commands in order to get better support +% for key value options. +% Of course they cannot be used both. The user must decide, which +% method he prefers. Package \xpackage{kvoptions-patch} aborts itself, +% if it detects that \xpackage{xkvltxp} is +% already loaded. +% +% However package \xpackage{xkvltxp} and \xpackage{kvoptions} +% can be used together, example: +% \begin{quote} +% |\usepackage{xkvltxp}|\\ +% |\usepackage[...]{foobar} % |\texttt{\itshape foobar using kvoptions} +% \end{quote} +% The other way should work, too. +% +% Package \xpackage{kvoptions-patch} tries to catch more situations +% and to be more robust. +% For example, during the comparison of options it normalizes +% them by removing spaces around |=| and the value. Thus the +% following is not reported as option clash: +% \begin{quote} +%\begin{verbatim} +%\RequirePackage{kvoptions-patch} +%\documentclass{article} +% +%\usepackage[scaled=0.7]{helvet} +%\usepackage[scaled = 0.7]{helvet} +% +%\begin{document} +%\end{document} +%\end{verbatim} +% \end{quote} +% +% \subsection{Limitations} +% +% \subsubsection{Option comparisons} +% +% In some situations \LaTeX\ compares option lists, e.g. option clash check, +% \cs{@ifpackagewith}, or \cs{@ifclasswith}. Apart from catcode and +% sanitizing problems of option \xoption{patch}, there is another problem. +% \LaTeX\ does not know about the type and default values of +% options in key value style. Thus an option clash is reported, +% even if the key value has the same meaning: +% \begin{quote} +% |\usepackage[scaled]{helvet} %| \texttt{\textit{default is }.95}\\ +% |\usepackage[.95]{helvet}|\\ +% |\usepackage[0.95]{helvet}| +% \end{quote} +% +% \subsubsection{Option list parsing with package \xpackage{kvoptions-patch}} +% +% With package \xpackage{kvoptions-patch} the range of possible values +% in key value specifications is much large, for example +% the comma can be used, if enclosed in curly braces. +% +% Other packages, especially the packages that uses their +% own process option code can be surprised to find tokens +% inside options that they do not expect and errors would +% be the consequence. To avoid errors the options, especially +% the unused option list is sanitized. That means the list +% will only contain tokens with catcode 12 (other) and +% perhaps spaces (catcode 10). This allows a safe parsing +% for other packages. But a comma in the value part is +% no longer protected by curly braces because they have lost +% their special meaning. This is the price for compatibility. +% +% Example: +% \begin{quote} +% |\RequirePackage{kvoptions-patch}|\\ +% |\documentclass[a={a,b,c},b]{article}|\\ +% |\begin{document}|\\ +% |\end{document}| +% \end{quote} +% Result: +% \begin{quote} +% |LaTeX Warning: Unused global option(s):|\\ +% | [a={a,c},b].| +% \end{quote} +% +% \StopEventually{ +% } +% +% \section{Implementation} +% +% \subsection{Preamble} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \paragraph{Reload check and identification.} +% Reload check, especially if the package is not used with \LaTeX. +% \begin{macrocode} +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode35=6 % # + \catcode39=12 % ' + \catcode44=12 % , + \catcode45=12 % - + \catcode46=12 % . + \catcode58=12 % : + \catcode64=11 % @ + \catcode123=1 % { + \catcode125=2 % } + \expandafter\let\expandafter\x\csname ver@kvoptions.sty\endcsname + \ifx\x\relax % plain-TeX, first loading + \else + \def\empty{}% + \ifx\x\empty % LaTeX, first loading, + % variable is initialized, but \ProvidesPackage not yet seen + \else + \expandafter\ifx\csname PackageInfo\endcsname\relax + \def\x#1#2{% + \immediate\write-1{Package #1 Info: #2.}% + }% + \else + \def\x#1#2{\PackageInfo{#1}{#2, stopped}}% + \fi + \x{kvoptions}{The package is already loaded}% + \aftergroup\endinput + \fi + \fi +\endgroup% +% \end{macrocode} +% Package identification: +% \begin{macrocode} +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode35=6 % # + \catcode39=12 % ' + \catcode40=12 % ( + \catcode41=12 % ) + \catcode44=12 % , + \catcode45=12 % - + \catcode46=12 % . + \catcode47=12 % / + \catcode58=12 % : + \catcode64=11 % @ + \catcode91=12 % [ + \catcode93=12 % ] + \catcode123=1 % { + \catcode125=2 % } + \expandafter\ifx\csname ProvidesPackage\endcsname\relax + \def\x#1#2#3[#4]{\endgroup + \immediate\write-1{Package: #3 #4}% + \xdef#1{#4}% + }% + \else + \def\x#1#2[#3]{\endgroup + #2[{#3}]% + \ifx#1\@undefined + \xdef#1{#3}% + \fi + \ifx#1\relax + \xdef#1{#3}% + \fi + }% + \fi +\expandafter\x\csname ver@kvoptions.sty\endcsname +\ProvidesPackage{kvoptions}% + [2019/11/29 v3.13 Key value format for package options (HO)]% +% \end{macrocode} +% +% \paragraph{Catcodes} +% +% \begin{macrocode} +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode123=1 % { + \catcode125=2 % } + \catcode64=11 % @ + \def\x{\endgroup + \expandafter\edef\csname KVO@AtEnd\endcsname{% + \endlinechar=\the\endlinechar\relax + \catcode13=\the\catcode13\relax + \catcode32=\the\catcode32\relax + \catcode35=\the\catcode35\relax + \catcode61=\the\catcode61\relax + \catcode64=\the\catcode64\relax + \catcode123=\the\catcode123\relax + \catcode125=\the\catcode125\relax + }% + }% +\x\catcode61\catcode48\catcode32=10\relax% +\catcode13=5 % ^^M +\endlinechar=13 % +\catcode35=6 % # +\catcode64=11 % @ +\catcode123=1 % { +\catcode125=2 % } +\def\TMP@EnsureCode#1#2{% + \edef\KVO@AtEnd{% + \KVO@AtEnd + \catcode#1=\the\catcode#1\relax + }% + \catcode#1=#2\relax +} +\TMP@EnsureCode{1}{14}% ^^A (comment) +\TMP@EnsureCode{2}{14}% ^^A (comment) +\TMP@EnsureCode{33}{12}% ! +\TMP@EnsureCode{39}{12}% ' +\TMP@EnsureCode{40}{12}% ( +\TMP@EnsureCode{41}{12}% ) +\TMP@EnsureCode{42}{12}% * +\TMP@EnsureCode{44}{12}% , +\TMP@EnsureCode{45}{12}% - +\TMP@EnsureCode{46}{12}% . +\TMP@EnsureCode{47}{12}% / +\TMP@EnsureCode{58}{12}% : +\TMP@EnsureCode{62}{12}% > +\TMP@EnsureCode{91}{12}% [ +\TMP@EnsureCode{93}{12}% ] +\TMP@EnsureCode{94}{7}% ^ (superscript) +\TMP@EnsureCode{96}{12}% ` +\edef\KVO@AtEnd{\KVO@AtEnd\noexpand\endinput} +% \end{macrocode} +% +% \paragraph{External resources.} +% The package extends the support for key value pairs of +% package \cs{keyval} to package options. Thus the package +% needs to be loaded anyway. and we use it for +% \cs{SetupKeyvalOptions}. AFAIK this does not disturb +% users of \xpackage{xkeyval}. +% \begin{macrocode} +\@ifundefined{define@key}{% + \RequirePackage{keyval}\relax +}{} +% \end{macrocode} +% +% Macro \cs{DeclareLocalOptions} parses a comma separated key list +% and uses \cs{comma@parse} of package \xpackage{kvsetkeys}, +% version 1.3. +% \begin{macrocode} +\RequirePackage{ltxcmds}[2010/12/02] +\RequirePackage{kvsetkeys}[2007/09/29] +% \end{macrocode} +% +% \paragraph{Provide macros for \plainTeX.} +% \begin{macrocode} +\@ifundefined{@x@protect}{% + \def\@x@protect#1\fi#2#3{% + \fi\protect#1% + }% + \let\@typeset@protect\relax +}{} +\@ifundefined{@currname}{% + \def\@currname{}% +}{} +\@ifundefined{@currext}{% + \def\@currext{}% +}{} +% \end{macrocode} +% +% \paragraph{Options} +% Option \xoption{debugshow} enables additional lines of +% code that prints information into the \xfile{.log} +% file. +% \begin{macrocode} +\DeclareOption{debugshow}{\catcode\@ne=9 } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareOption{patch}{% + \AtEndOfPackage{% + \RequirePackage{kvoptions-patch}[2019/11/29]% + }% +} +% \end{macrocode} +% +% Optionen auswerten: +% \begin{macrocode} +\ProcessOptions\relax +% \end{macrocode} +% +% \subsection{Option declaration macros} +% +% \subsubsection{\cs{SetupKeyvalOptions}} +% +% The family for the key value pairs can be setup once +% and is remembered later. +% The package name seems a reasonable default for the +% family key, if it is not set by the package author. +% +% \begin{macro}{\KVO@family} +% We cannot store the family setting in one macro, +% because the package should be usable for many +% other packages, too. Thus we remember the family +% setting in a macro, whose name contains the +% package name with extension, a key in \LaTeX's +% class/package system. +% \begin{macrocode} +\define@key{KVO}{family}{% + \expandafter\edef\csname KVO@family@% + \@currname.\@currext\endcsname{#1}% +} +\def\KVO@family{% + \@ifundefined{KVO@family@\@currname.\@currext}{% + \@currname + }{% + \csname KVO@family@\@currname.\@currext\endcsname + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KVO@prefix} +% The value settings of options that are declared by \cs{DeclareBoolOption} +% and \cs{DeclareStringOption} need to be saved in macros. +% in the first case this is a switch \cs{if}\meta{prefix}\meta{key}, +% in the latter case a macro \cs{}\meta{prefix}\meta{key}. +% The prefix can be configured, by \xoption{prefix} that is declared +% here. The default is the package name with |@| appended. +% \begin{macrocode} +\define@key{KVO}{prefix}{% + \expandafter\edef\csname KVO@prefix@% + \@currname.\@currext\endcsname{#1}% +} +\def\KVO@prefix{% + \ltx@ifundefined{KVO@prefix@\@currname.\@currext}{% + \@currname @% + }{% + \csname KVO@prefix@\@currname.\@currext\endcsname + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\define@key{KVO}{setkeys}{% + \expandafter\def\csname KVO@setkeys@% + \@currname.\@currext\endcsname{#1}% +} +% \end{macrocode} +% \begin{macro}{\KVO@setkeys} +% \begin{macrocode} +\def\KVO@setkeys{% + \ltx@IfUndefined{KVO@setkeys@\@currname.\@currext}{% + \setkeys + }{% + \csname KVO@setkeys@\@currname.\@currext\endcsname + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\SetupKeyvalOptions} +% The argument of \cs{SetupKeyvalOptions} expects a key value +% list, known keys are \xoption{family} and \xoption{prefix}. +% \begin{macrocode} +\newcommand*{\SetupKeyvalOptions}{% + \kvsetkeys{KVO}% +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\cs{DeclareBoolOption}} +% +% \begin{macro}{\DeclareBoolOption} +% Usually options of boolean type can be given by the +% user without value and this means a setting to \emph{true}. +% We follow this convention here. Also it simplifies the +% user interface. +% +% The switch is created and initialized with \emph{false}. +% The default setting can be overwritten by the optional +% argument. +% +% \LaTeX's \cs{newif} does not check for already defined +% macros, therefore we add this check here to prevent +% the user from accidently redefining of \TeX's primitives +% and other macros. +% \begin{macrocode} +\newcommand*{\DeclareBoolOption}[2][false]{% + \KVO@ifdefinable{if\KVO@prefix#2}{% + \KVO@ifdefinable{\KVO@prefix#2true}{% + \KVO@ifdefinable{\KVO@prefix#2false}{% + \csname newif\expandafter\endcsname + \csname if\KVO@prefix#2\endcsname + \@ifundefined{\KVO@prefix#2#1}{% + \PackageWarning{kvoptions}{% + Initialization of option `#2' failed,\MessageBreak + cannot set boolean option to `#1',\MessageBreak + use `true' or `false', now using `false'% + }% + }{% + \csname\KVO@prefix#2#1\endcsname + }% + \begingroup + \edef\x{\endgroup + \noexpand\define@key{\KVO@family}{#2}[true]{% + \noexpand\KVO@boolkey{\@currname}% + \ifx\@currext\@clsextension + \noexpand\@clsextension + \else + \noexpand\@pkgextension + \fi + {\KVO@prefix}{#2}{####1}% + }% + }% + \x + }% + }% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareComplementaryOption} +% The first argument is the key name, the second the +% key that must be a boolean option with the same +% current family and prefix. A new switch is not +% created for the new key, we have already a switch. +% Instead we define switch setting commands to work +% on the parent switch. +% \begin{macrocode} +\newcommand*{\DeclareComplementaryOption}[2]{% + \@ifundefined{if\KVO@prefix#2}{% + \PackageError{kvoptions}{% + Cannot generate option code for `#1',\MessageBreak + parent switch `#2' does not exist% + }{% + You are inside % + \ifx\@currext\@clsextension class\else package\fi\space + `\@currname.\@currext'.\MessageBreak + `\KVO@family' is used as familiy % + for the keyval options.\MessageBreak + `\KVO@prefix' serves as prefix % + for internal switch macros.\MessageBreak + \MessageBreak + \@ehc + }% + }{% + \KVO@ifdefinable{\KVO@prefix#1true}{% + \KVO@ifdefinable{\KVO@prefix#1false}{% + \expandafter\let\csname\KVO@prefix#1false\expandafter\endcsname + \csname\KVO@prefix#2true\endcsname + \expandafter\let\csname\KVO@prefix#1true\expandafter\endcsname + \csname\KVO@prefix#2false\endcsname +% \end{macrocode} +% The same code part as in \cs{DeclareBoolOption} can +% now be used. +% \begin{macrocode} + \begingroup + \edef\x{\endgroup + \noexpand\define@key{\KVO@family}{#1}[true]{% + \noexpand\KVO@boolkey{\@currname}% + \ifx\@currext\@clsextension + \noexpand\@clsextension + \else + \noexpand\@pkgextension + \fi + {\KVO@prefix}{#1}{####1}% + }% + }% + \x + }% + }% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KVO@ifdefinable} +% Generate the command token LaTeX's \cs{@ifdefinable} expects. +% \begin{macrocode} +\def\KVO@ifdefinable#1{% + \expandafter\@ifdefinable\csname #1\endcsname +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KVO@boolkey} +% We check explicitly for |true| and |false| to prevent +% the user from accidently calling other macros. +% \begin{quote} +% \begin{tabular}{@{}ll@{}} +% |#1|& package/class name\\ +% |#2|& |\@pkgextension|/|\@clsextension|\\ +% |#3|& prefix \\ +% |#4|& key name\\ +% |#5|& new value +% \end{tabular} +% \end{quote} +% \begin{macrocode} +\def\KVO@boolkey#1#2#3#4#5{% + \edef\KVO@param{#5}% + \ltx@onelevel@sanitize\KVO@param + \ifx\KVO@param\KVO@true + \expandafter\@firstofone + \else + \ifx\KVO@param\KVO@false + \expandafter\expandafter\expandafter\@firstofone + \else + \ifx#2\@clsextension + \expandafter\ClassWarning + \else + \expandafter\PackageWarning + \fi + {#1}{% + Value `\KVO@param' is not supported by\MessageBreak + option `#4'% + }% + \expandafter\expandafter\expandafter\@gobble + \fi + \fi + {% + ^^A\ifx#2\@clsextension + ^^A \expandafter\ClassInfo + ^^A\else + ^^A \expandafter\PackageInfo + ^^A\fi + ^^A{#1}{[option] #4=\KVO@param}% + \csname#3#4\KVO@param\endcsname + }% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\KVO@true} +% \begin{macro}{\KVO@false} +% The macros \cs{KVO@true} and \cs{KVO@false} are used +% for string comparisons. After \cs{ltx@onelevel@sanitize} +% we have only tokens with catcode 12 (other). +% \begin{macrocode} +\def\KVO@true{true} +\def\KVO@false{false} +\ltx@onelevel@sanitize\KVO@true +\ltx@onelevel@sanitize\KVO@false +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{\cs{DeclareStringOption}} +% +% \begin{macro}{\DeclareStringOption} +% \begin{macrocode} +\newcommand*{\DeclareStringOption}[2][]{% + \@ifnextchar[{% + \KVO@DeclareStringOption{#1}{#2}@% + }{% + \KVO@DeclareStringOption{#1}{#2}{}[]% + }% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\KVO@DeclareStringOption} +% \begin{macrocode} +\def\KVO@DeclareStringOption#1#2#3[#4]{% + \KVO@ifdefinable{\KVO@prefix#2}{% + \@namedef{\KVO@prefix#2}{#1}% + \begingroup + \ifx\\#3\\% + \toks@{}% + \else + \toks@{[{#4}]}% + \fi + \edef\x{\endgroup + \noexpand\define@key{\KVO@family}{#2}\the\toks@{% + ^^A\begingroup + ^^A \toks@{####1}% + ^^A \ifx\@currext\@clsextension + ^^A \noexpand\ClassInfo + ^^A \else + ^^A \noexpand\PackageInfo + ^^A \fi + ^^A {\@currname}{% + ^^A [option] #2={\noexpand\the\toks@}% + ^^A }% + ^^A\endgroup + \noexpand\def + \expandafter\noexpand\csname\KVO@prefix#2\endcsname{####1}% + }% + }% + \x + }% +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\cs{DeclareVoidOption}} +% +% \begin{macro}{\DeclareVoidOption} +% \begin{macrocode} +\newcommand*{\DeclareVoidOption}[2]{% + \begingroup + \let\next\@gobbletwo + \KVO@ifdefinable{\KVO@prefix#1}{% + \let\next\@firstofone + }% + \expandafter\endgroup + \next{% + \begingroup + \edef\x{\endgroup + \noexpand\define@key{\KVO@family}{#1}[\KVO@VOID@]{% + \noexpand\KVO@voidkey{\@currname}% + \ifx\@currext\@clsextension + \noexpand\@clsextension + \else + \noexpand\@pkgextension + \fi + {#1}% + {####1}% + \expandafter\noexpand\csname\KVO@prefix#1\endcsname + }% + }% + \x + \begingroup + \toks@{#2}% + \expandafter\endgroup + \expandafter\def + \csname\KVO@prefix#1\expandafter\endcsname + \expandafter{\the\toks@}% + }% +} +\def\KVO@VOID@{@VOID@} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\KVO@voidkey} +% \begin{tabular}{@{}ll@{}} +% |#1|& package/class name\\ +% |#2|& |\@pkgextension|/|\@clsextension|\\ +% |#3|& key name\\ +% |#4|& default (|@VOID@|)\\ +% |#5|& macro with option code +% \end{tabular} +% \begin{macrocode} +\def\KVO@voidkey#1#2#3#4{% + \def\CurrentOption{#3}% + \begingroup + \def\x{#4}% + \expandafter\endgroup + \ifx\x\KVO@VOID@ + \else + \ifx#2\@clsextension + \expandafter\ClassWarning + \else + \expandafter\PackageWarning + \fi + {#1}{% + Unexpected value for option `#3'\MessageBreak + is ignored% + }% + \fi + ^^A\ifx#2\@clsextension + ^^A \expandafter\ClassInfo + ^^A\else + ^^A \expandafter\PackageInfo + ^^A\fi + ^^A{#1}{[option] #3}% +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\cs{DeclareDefaultOption}} +% +% \begin{macro}{\DeclareDefaultOption} +% \begin{macrocode} +\newcommand*{\DeclareDefaultOption}{% + \@namedef{KVO@default@\@currname.\@currext}% +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\cs{DeclareLocalOptions}} +% +% \begin{macro}{\DeclareLocalOptions} +% \begin{macrocode} +\newcommand*{\DeclareLocalOptions}[1]{% + \comma@parse{#1}\KVO@DeclareLocalOption +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\KVO@DeclareLocalOption} +% \begin{macrocode} +\def\KVO@DeclareLocalOption#1{% + \expandafter\def\csname KVO@local@\KVO@family @#1\endcsname{}% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Dynamic options} +% +% \subsubsection{\cs{DisableKeyvalOption}} +% +% \begin{macrocode} +\SetupKeyvalOptions{% + family=KVOdyn,% + prefix=KVOdyn@% +} +\DeclareBoolOption[true]{global} +\DeclareComplementaryOption{local}{global} +\DeclareStringOption[undef]{action} +\let\KVOdyn@name\relax +\let\KVOdyn@ext\@empty +\define@key{KVOdyn}{class}{% + \def\KVOdyn@name{#1}% + \let\KVOdyn@ext\@clsextension +} +\define@key{KVOdyn}{package}{% + \def\KVOdyn@name{#1}% + \let\KVOdyn@ext\@pkgextension +} +\newcommand*{\DisableKeyvalOption}[3][]{% + \begingroup + \kvsetkeys{KVOdyn}{#1}% + \def\x{\endgroup}% + \@ifundefined{KVO@action@\KVOdyn@action}{% + \PackageError{kvoptions}{% + Unknown disable action % + `\expandafter\strip@prefix\meaning\KVOdyn@action'\MessageBreak + for option `#3' in keyval family '#2'% + }\@ehc + }{% + \csname KVO@action@\KVOdyn@action\endcsname{#2}{#3}% + }% + \x +} +\def\KVO@action@undef#1#2{% + \edef\x{\endgroup + \ifKVOdyn@global\global\fi + \let + \expandafter\noexpand\csname KV@#1@#2\endcsname + \relax + \ifKVOdyn@global\global\fi + \let + \expandafter\noexpand\csname KV@#1@#2@default\endcsname + \relax + }% + ^^A\PackageInfo{kvoptions}{% + ^^A [option] key `#2' of family `#1'\MessageBreak + ^^A is disabled (undef, \ifKVOdyn@global global\else local\fi)% + ^^A}% +} +\def\KVO@action@ignore#1#2{% + \edef\x{\endgroup + \ifKVOdyn@global\global\fi + \let + \expandafter\noexpand\csname KV@#1@#2\endcsname + \noexpand\@gobble + \ifKVOdyn@global\global\fi + \let + \expandafter\noexpand\csname KV@#1@#2@default\endcsname + \noexpand\@empty + }% + ^^A\PackageInfo{kvoptions}{% + ^^A [option] key `#2' of family `#1'\MessageBreak + ^^A is disabled (ignore, \ifKVOdyn@global global\else local\fi)% + ^^A}% +} +\def\KVO@action@error{% + \KVO@do@action{error}% +} +\def\KVO@action@warning{% + \KVO@do@action{warning}% +} +% \end{macrocode} +% \begin{tabular}{@{}ll@{}} +% |#1|& |error| or |warning|\\ +% |#2|& \meta{family}\\ +% |#3|& \meta{key}\\ +% \end{tabular} +% \begin{macrocode} +\def\KVO@do@action#1#2#3{% + \ifx\KVOdyn@name\relax + \PackageError{kvoptions}{% + Action type `#1' needs package/class name\MessageBreak + for key `#3' in family `#2'% + }\@ehc + \else + \edef\x{\endgroup + \noexpand\define@key{#2}{#3}[]{% + \expandafter\noexpand\csname KVO@disable@#1\endcsname + {\KVOdyn@name}\noexpand\KVOdyn@ext{#3}% + }% + \ifKVOdyn@global + \global\let + \expandafter\noexpand\csname KV@#2@#3\endcsname + \expandafter\noexpand\csname KV@#2@#3\endcsname + \global\let + \expandafter\noexpand\csname KV@#2@#3@default\endcsname + \expandafter\noexpand\csname KV@#2@#3@default\endcsname + \fi + }% + ^^A\ifx\KVOdyn@ext\@clsextension + ^^A \expandafter\ClassInfo + ^^A\else + ^^A \expandafter\PackageInfo + ^^A\fi + ^^A{\KVOdyn@name}{% + ^^A [option] key `#3' of family `#2'\MessageBreak + ^^A is disabled (#1, \ifKVOdyn@global global\else local\fi)% + ^^A}% + \fi +} +\def\KVO@disable@error#1#2#3{% + \ifx#2\@clsextension + \expandafter\ClassError + \else + \expandafter\PackageError + \fi + {#1}{% + Option `#3' is given too late,\MessageBreak + now the option is ignored% + }\@ehc +} +\def\KVO@disable@warning#1#2#3{% + \ifx#2\@clsextension + \expandafter\ClassWarning + \else + \expandafter\PackageWarning + \fi + {#1}{% + Option `#3' is already consumed\MessageBreak + and has no effect% + }% +} +% \end{macrocode} +% +% \subsection{Change option code} +% +% \subsubsection{\cs{AddToKeyvalOption}} +% +% \begin{macro}{\AddToKeyvalOption} +% \begin{macrocode} +\newcommand*{\AddToKeyvalOption}{% + \@ifstar{% + \begingroup + \edef\x{\endgroup + \noexpand\KVO@AddToKeyvalOption{\KVO@family}% + }% + \x + }% + \KVO@AddToKeyvalOption +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\KVO@AddToKeyvalOption} +% \begin{macrocode} +\def\KVO@AddToKeyvalOption#1#2{% + \@ifundefined{KV@#1@#2}{% + \PackageWarning{kvoptions}{% + Key `#2' of family `#1' does not exist.\MessageBreak + Ignoring \string\AddToKeyvalOption + }% + \@gobble + }{% + \edef\KVO@next{% + \noexpand\KVO@@AddToKeyvalOption + \expandafter\noexpand\csname KV@#1@#2\endcsname + }% + \afterassignment\KVO@next + \def\KVO@temp##1% + }% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\KVO@@AddToKeyvalOption} +% \begin{macrocode} +\def\KVO@@AddToKeyvalOption#1{% + \begingroup + \toks@\expandafter{#1{##1}}% + \toks@\expandafter{\the\expandafter\toks@\KVO@temp{##1}}% + \edef\x{\endgroup + \noexpand\def\noexpand#1####1{\the\toks@}% + }% + \x +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Process options} +% +% \subsubsection{Get global options} +% +% Package \xpackage{xkeyval} removes options with equal signs from +% the global options (\cs{@classoptionslist}). The effect is that +% other packages and classes will not see these global options anymore. +% A bug-report was answered that this behaviour is ``by design''. +% Thus I call it a design bug. Now getting the global options require +% an algorithm instead of a simple macro call. +% \begin{macrocode} +%</package> +%<*package|patch> +% \end{macrocode} +% \begin{macro}{\KVO@IfDefThen} +% Call |#2| if command |#1| is defined and not \cs{relax}. +% (Package \xpackage{kvoptions-patch} does not load +% package \xpackage{ltxcmds}.) +% \begin{macrocode} +\def\KVO@IfDefThen#1#2{% + \ifx#1\ltx@undefined + \else + \ifx#1\relax + \else + #2% + \fi + \fi +}% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\KVO@GetClassOptionsList} +% \begin{macrocode} +\def\KVO@GetClassOptionsList{% + \let\KVO@classoptionslist\@classoptionslist + \KVO@IfDefThen\@classoptionslist{% + \KVO@IfDefThen\XKV@documentclass{% + \ifx\XKV@documentclass\ltx@empty + \else + \KVO@IfDefThen\XKV@classoptionslist{% + \ifx\XKV@classoptionslist\ltx@empty + \else + \let\KVO@classoptionslist\XKV@classoptionslist + \fi + }% + \fi + }% + }% +}% +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +%</package|patch> +%<*package> +% \end{macrocode} +% +% \subsubsection{\cs{ProcessKeyvalOptions}} +% +% \begin{macro}{\ProcessKeyvalOptions} +% If the optional star is given, we get the family +% name and expand it for safety. +% \begin{macrocode} +\newcommand*{\ProcessKeyvalOptions}{% + \@ifstar{% + \begingroup + \edef\x{\endgroup + \noexpand\KVO@ProcessKeyvalOptions{\KVO@family}% + }% + \x + }% + \KVO@ProcessKeyvalOptions +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\def\KVO@ProcessKeyvalOptions#1{% + \let\@tempc\relax + \let\KVO@temp\@empty +% \end{macrocode} +% Add any global options that are known to KV to the start of +% the list being built in |\KVO@temp| and mark them used (by +% removing them from the unused option list). +% \begin{macrocode} + \ifx\@currext\@clsextension + \else + \KVO@GetClassOptionsList + \ifx\KVO@classoptionslist\relax + \else + \@for\KVO@CurrentOption:=\KVO@classoptionslist\do{% + \@ifundefined{KV@#1@\expandafter\KVO@getkey + \KVO@CurrentOption=\@nil}{% + }{% + \@ifundefined{KVO@local@#1@\expandafter\KVO@getkey + \KVO@CurrentOption=\@nil}{% + \ifx\KVO@Patch Y% + \edef\KVO@temp{% + \etex@unexpanded\expandafter{% + \KVO@temp + }% + ,% + \etex@unexpanded\expandafter{% + \KVO@CurrentOption + }% + ,% + }% + \ltx@onelevel@sanitize\KVO@CurrentOption + \else + \edef\KVO@temp{% + \KVO@temp + ,% + \KVO@CurrentOption + ,% + }% + \fi + \@expandtwoargs\@removeelement\KVO@CurrentOption + \@unusedoptionlist\@unusedoptionlist + }{}% + }% + }% + \fi + \fi +% \end{macrocode} +% Now stick the package options at the end of the list and wrap +% in a call to \cs{setkeys}. A class ignores unknown global +% options, we must remove them to prevent error messages +% from \cs{setkeys}. +% \begin{macrocode} + \begingroup + \toks\tw@{}% + \@ifundefined{opt@\@currname.\@currext}{% + \toks@\expandafter{\KVO@temp}% + }{% + \toks@\expandafter\expandafter\expandafter{% + \csname opt@\@currname.\@currext\endcsname + }% + \ifx\@currext\@clsextension + \edef\CurrentOption{\the\toks@}% + \toks@\expandafter{\KVO@temp}% + \@for\CurrentOption:=\CurrentOption\do{% + \@ifundefined{% + KV@#1@\expandafter\KVO@getkey\CurrentOption=\@nil + }{% +% \end{macrocode} +% A class puts not used options in the unused option list +% unless there is a default handler. +% \begin{macrocode} + \@ifundefined{KVO@default@\@currname.\@currext}{% + \ifx\KVO@Patch Y% + \ltx@onelevel@sanitize\CurrentOption + \fi + \ifx\@unusedoptionlist\@empty + \global\let\@unusedoptionlist\CurrentOption + \else + \expandafter\expandafter\expandafter\gdef + \expandafter\expandafter\expandafter\@unusedoptionlist + \expandafter\expandafter\expandafter{% + \expandafter\@unusedoptionlist + \expandafter,\CurrentOption + }% + \fi + }{% + \toks\tw@\expandafter{% + \the\toks\expandafter\tw@\expandafter,\CurrentOption + }% + }% + }{% + \toks@\expandafter{% + \the\expandafter\toks@\expandafter,\CurrentOption + }% + }% + }% + \else +% \end{macrocode} +% Without default action we pass all options to \cs{setkeys}. +% Otherwise we have to check which options are known. +% These are passed to \cs{setkeys}. For the others the default +% action is performed. +% \begin{macrocode} + \@ifundefined{KVO@default@\@currname.\@currext}{% + \toks@\expandafter\expandafter\expandafter{% + \expandafter\KVO@temp\the\toks@ + }% + }{% + \edef\CurrentOption{\the\toks@}% + \toks@\expandafter{\KVO@temp}% + \@for\CurrentOption:=\CurrentOption\do{% + \@ifundefined{% + KV@#1@\expandafter\KVO@getkey\CurrentOption=\@nil + }{% + \toks\tw@\expandafter{% + \the\toks\expandafter\tw@\expandafter,\CurrentOption + }% + }{% + \toks@\expandafter{% + \the\expandafter\toks@\expandafter,\CurrentOption + }% + }% + }% + }% + \fi + }% + \edef\KVO@temp{\endgroup + \noexpand\KVO@calldefault{\the\toks\tw@}% + \noexpand\KVO@setkeys{#1}{\the\toks@}% + }% + \KVO@temp +% \end{macrocode} +% Some cleanup of \cs{ProcessOptions}. +% \begin{macrocode} + \let\CurrentOption\@empty + \AtEndOfPackage{\let\@unprocessedoptions\relax}% +} +% \end{macrocode} +% +% \subsubsection{\cs{ProcessLocalKeyvalOptions}} +% +% \begin{macro}{\ProcessLocalKeyvalOptions} +% If the optional star is given, we get the family +% name and expand it for safety. +% \begin{macrocode} +\newcommand*{\ProcessLocalKeyvalOptions}{% + \@ifstar{% + \begingroup + \edef\x{\endgroup + \noexpand\KVO@ProcessLocalKeyvalOptions{\KVO@family}% + }% + \x + }% + \KVO@ProcessLocalKeyvalOptions +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\def\KVO@ProcessLocalKeyvalOptions#1{% + \let\@tempc\relax + \let\KVO@temp\@empty +% \end{macrocode} +% Check if \cs{ProcessLocalKeyvalOptions} is called inside +% a package. +% \begin{macrocode} + \ifx\@currext\@pkgextension + \else + \PackageError{kvoptions}{% + \string\ProcessLocalKeyvalOptions\space is intended for packages only% + }\@ehc + \fi +% \end{macrocode} +% The package options are put into toks register \cs{toks@}. +% \begin{macrocode} + \begingroup + \toks\tw@{}% + \@ifundefined{opt@\@currname.\@currext}{% + \toks@\expandafter{\KVO@temp}% + }{% + \toks@\expandafter\expandafter\expandafter{% + \csname opt@\@currname.\@currext\endcsname + }% +% \end{macrocode} +% Without default action we pass all options to \cs{setkeys}. +% Otherwise we have to check which options are known. +% These are passed to \cs{setkeys}. For the others the default +% action is performed. +% \begin{macrocode} + \@ifundefined{KVO@default@\@currname.\@currext}{% + \toks@\expandafter\expandafter\expandafter{% + \expandafter\KVO@temp\the\toks@ + }% + }{% + \edef\CurrentOption{\the\toks@}% + \toks@\expandafter{\KVO@temp}% + \@for\CurrentOption:=\CurrentOption\do{% + \@ifundefined{% + KV@#1@\expandafter\KVO@getkey\CurrentOption=\@nil + }{% + \toks\tw@\expandafter{% + \the\toks\expandafter\tw@\expandafter,\CurrentOption + }% + }{% + \toks@\expandafter{% + \the\expandafter\toks@\expandafter,\CurrentOption + }% + }% + }% + }% + }% + \edef\KVO@temp{\endgroup + \noexpand\KVO@calldefault{\the\toks\tw@}% + \noexpand\KVO@setkeys{#1}{\the\toks@}% + }% + \KVO@temp +% \end{macrocode} +% Some cleanup of \cs{ProcessOptions}. +% \begin{macrocode} + \let\CurrentOption\@empty + \AtEndOfPackage{\let\@unprocessedoptions\relax}% +} +% \end{macrocode} +% +% \subsubsection{Helper macros} +% +% \begin{macro}{\KVO@getkey} +% Extract the key part of a key=value pair. +% \begin{macrocode} +\def\KVO@getkey#1=#2\@nil{#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KVO@calldefault} +% \begin{macrocode} +\def\KVO@calldefault#1{% + \begingroup + \def\x{#1}% + \expandafter\endgroup + \ifx\x\@empty + \else + \@for\CurrentOption:=#1\do{% + \ifx\CurrentOption\@empty + \else + \expandafter\KVO@setcurrents\CurrentOption=\@nil + \@nameuse{KVO@default@\@currname.\@currext}% + \fi + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\KVO@setcurrents} +% Extract the key part of a key=value pair. +% \begin{macrocode} +\def\KVO@setcurrents#1=#2\@nil{% + \def\CurrentOptionValue{#2}% + \ifx\CurrentOptionValue\@empty + \let\CurrentOptionKey\CurrentOption + \let\CurrentOptionValue\relax + \else + \edef\CurrentOptionKey{\zap@space#1 \@empty}% + \expandafter\KVO@setcurrentvalue\CurrentOption\@nil + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\KV@setcurrentvalue} +% Here the value part is parsed. Package \xpackage{keyval}'s +% \cs{KV@@sp@def} helps in removing spaces at the begin and +% end of the value. +% \begin{macrocode} +\def\KVO@setcurrentvalue#1=#2\@nil{% + \KV@@sp@def\CurrentOptionValue{#2}% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{\plainTeX} +% +% Disable \LaTeX\ stuff. +% \begin{macrocode} +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname documentclass\endcsname\relax + \def\ProcessKeyvalOptions{% + \@ifstar{}\@gobble + }% +\fi +% \end{macrocode} +% +% \begin{macrocode} +\KVO@AtEnd% +%</package> +% \end{macrocode} +% +% \subsection{Package \xpackage{kvoptions-patch}} +% +% \begin{macrocode} +%<*patch> +\NeedsTeXFormat{LaTeX2e} +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode123=1 % { + \catcode125=2 % } + \catcode64=11 % @ + \def\x{\endgroup + \expandafter\edef\csname KVO@AtEnd\endcsname{% + \endlinechar=\the\endlinechar\relax + \catcode13=\the\catcode13\relax + \catcode32=\the\catcode32\relax + \catcode35=\the\catcode35\relax + \catcode61=\the\catcode61\relax + \catcode64=\the\catcode64\relax + \catcode123=\the\catcode123\relax + \catcode125=\the\catcode125\relax + }% + }% +\x\catcode61\catcode48\catcode32=10\relax% +\catcode13=5 % ^^M +\endlinechar=13 % +\catcode35=6 % # +\catcode64=11 % @ +\catcode123=1 % { +\catcode125=2 % } +\def\TMP@EnsureCode#1#2{% + \edef\KVO@AtEnd{% + \KVO@AtEnd + \catcode#1=\the\catcode#1\relax + }% + \catcode#1=#2\relax +} +\TMP@EnsureCode{39}{12}% ' +\TMP@EnsureCode{40}{12}% ( +\TMP@EnsureCode{41}{12}% ) +\TMP@EnsureCode{43}{12}% + +\TMP@EnsureCode{44}{12}% , +\TMP@EnsureCode{45}{12}% - +\TMP@EnsureCode{46}{12}% . +\TMP@EnsureCode{47}{12}% / +\TMP@EnsureCode{58}{12}% : +\TMP@EnsureCode{60}{12}% < +\TMP@EnsureCode{62}{12}% > +\TMP@EnsureCode{91}{12}% [ +\TMP@EnsureCode{93}{12}% ] +\TMP@EnsureCode{96}{12}% ` +\TMP@EnsureCode{124}{12}% | +\edef\KVO@AtEnd{\KVO@AtEnd\noexpand\endinput} +\ProvidesPackage{kvoptions-patch}% + [2019/11/29 v3.13 LaTeX patch for keyval options (HO)]% +% \end{macrocode} +% +% Check for \eTeX. +% \begin{macrocode} +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname eTeXversion\endcsname\relax + \PackageWarningNoLine{kvoptions-patch}{% + Package loading is aborted, because e-TeX is missing% + }% + \expandafter\KVO@AtEnd +\fi% +% \end{macrocode} +% +% Package \xpackage{etexcmds} for \cs{etex@unexpanded}. +% \begin{macrocode} +\RequirePackage{etexcmds}[2007/09/09] +\ifetex@unexpanded +\else + \PackageError{kvoptions-patch}{% + Could not find eTeX's \string\unexpanded.\MessageBreak + Try adding \string\RequirePackage\string{etexcmds\string} % + before \string\documentclass% + }\@ehd + \expandafter\KVO@AtEnd +\fi% +% \end{macrocode} +% +% Check for package \xpackage{xkvltxp}. +% \begin{macrocode} +\@ifpackageloaded{xkvltxp}{% + \PackageWarningNoLine{kvoptions}{% + Option `patch' cannot be used together with\MessageBreak + package `xkvltxp' that is already loaded.\MessageBreak + Therefore package loading is aborted% + }% + \KVO@AtEnd +}{}% +% \end{macrocode} +% +% \begin{macrocode} +\def\@if@ptions#1#2#3{% + \begingroup + \KVO@normalize\KVO@temp{#3}% + \edef\x{\endgroup + \noexpand\@if@pti@ns{% + \detokenize\expandafter\expandafter\expandafter{% + \csname opt@#2.#1\endcsname + }% + }{% + \detokenize\expandafter{\KVO@temp}% + }% + }% + \x +} +% \end{macrocode} +% +% \begin{macrocode} +\def\@pass@ptions#1#2#3{% + \KVO@normalize\KVO@temp{#2}% + \@ifundefined{opt@#3.#1}{% + \expandafter\gdef\csname opt@#3.#1% + \expandafter\endcsname\expandafter{% + \KVO@temp + }% + }{% + \expandafter\gdef\csname opt@#3.#1% + \expandafter\expandafter\expandafter\endcsname + \expandafter\expandafter\expandafter{% + \csname opt@#3.#1\expandafter\endcsname\expandafter,\KVO@temp + }% + }% +} +% \end{macrocode} +% +% \begin{macrocode} +\def\ProcessOptions{% + \let\ds@\@empty + \@ifundefined{opt@\@currname.\@currext}{% + \let\@curroptions\@empty + }{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter\@curroptions + \expandafter\expandafter\expandafter{% + \csname opt@\@currname.\@currext\endcsname + }% + }% + \@ifstar\KVO@xprocess@ptions\KVO@process@ptions +} +% \end{macrocode} +% +% \begin{macrocode} +\def\KVO@process@ptions{% + \@for\CurrentOption:=\@declaredoptions\do{% + \ifx\CurrentOption\@empty + \else + \begingroup + \ifx\@currext\@clsextension + \toks@{}% + \else + \KVO@GetClassOptionsList + \toks@\expandafter{\KVO@classoptionslist,}% + \fi + \toks\tw@\expandafter{\@curroptions}% + \edef\x{\endgroup + \noexpand\in@{,\CurrentOption,}{,\the\toks@\the\toks\tw@,}% + }% + \x + \ifin@ + \KVO@use@ption + \expandafter\let\csname ds@\CurrentOption\endcsname\@empty + \fi + \fi + }% + \KVO@process@pti@ns +} +% \end{macrocode} +% +% \begin{macrocode} +\def\KVO@xprocess@ptions{% + \ifx\@currext\@clsextension + \else + \KVO@GetClassOptionsList + \@for\CurrentOption:=\KVO@classoptionslist\do{% + \ifx\CurrentOption\@empty + \else + \KVO@in@\CurrentOption\@declaredoptions + \ifin@ + \KVO@use@ption + \expandafter\let\csname ds@\CurrentOption\endcsname\@empty + \fi + \fi + }% + \fi + \KVO@process@pti@ns +} +% \end{macrocode} +% +% \begin{macrocode} +\def\KVO@in@#1#2{% + \in@false + \begingroup + \@for\x:=#2\do{% + \ifx\x#1\relax + \in@true + \fi + }% + \edef\x{\endgroup + \ifin@ + \noexpand\in@true + \fi + }% + \x +} +% \end{macrocode} +% +% \begin{macrocode} +\def\KVO@process@pti@ns{% + \@for\CurrentOption:=\@curroptions\do{% + \@ifundefined{ds@\KVO@SanitizedCurrentOption}{% + \KVO@use@ption + \default@ds + }% + \KVO@use@ption + }% + \@for\CurrentOption:=\@declaredoptions\do{% + \expandafter\let\csname ds@\CurrentOption\endcsname\relax + }% + \let\CurrentOption\@empty + \let\@fileswith@pti@ns\@@fileswith@pti@ns + \AtEndOfPackage{\let\@unprocessedoptions\relax}% +} +% \end{macrocode} +% +% \begin{macrocode} +\def\KVO@use@ption{% + \begingroup + \edef\x{\endgroup + \noexpand\@removeelement{% + \detokenize\expandafter{\CurrentOption}% + }{% + \detokenize\expandafter{\@unusedoptionlist}% + }% + }% + \x\@unusedoptionlist + \csname ds@\KVO@SanitizedCurrentOption\endcsname +} +% \end{macrocode} +% +% \begin{macrocode} +\def\OptionNotUsed{% + \ifx\@currext\@clsextension + \xdef\@unusedoptionlist{% + \ifx\@unusedoptionlist\@empty + \else + \detokenize\expandafter{\@unusedoptionlist,}% + \fi + \detokenize\expandafter{\CurrentOption}% + }% + \fi +} +% \end{macrocode} +% +% Variant of \cs{ExecuteOptions} that better protects \cs{CurrentOption}. +% \begin{macrocode} +\def\CurrentOption@SaveLevel{0} +\def\ExecuteOptions{% + \expandafter\KVO@ExecuteOptions + \csname CurrentOption@\CurrentOption@SaveLevel\endcsname +} +\def\KVO@ExecuteOptions#1#2{% + \let#1\CurrentOption + \edef\CurrentOption@SaveLevel{% + \the\numexpr\CurrentOption@SaveLevel+1% + }% + \@for\CurrentOption:=#2\do{% + \csname ds@\CurrentOption\endcsname + }% + \edef\CurrentOption@SaveLevel{% + \the\numexpr\CurrentOption@SaveLevel-1% + }% + \let\CurrentOption#1% +} +% \end{macrocode} +% +% \begin{macrocode} +\def\KVO@fileswith@pti@ns#1[#2]#3[#4]{% + \ifx#1\@clsextension + \ifx\@classoptionslist\relax + \KVO@normalize\KVO@temp{#2}% + \expandafter\gdef\expandafter\@classoptionslist\expandafter{% + \KVO@temp + }% + \def\reserved@a{% + \KVO@onefilewithoptions{#3}[{#2}][{#4}]#1% + \@documentclasshook + }% + \else + \def\reserved@a{% + \KVO@onefilewithoptions{#3}[{#2}][{#4}]#1% + }% + \fi + \else + \begingroup + \let\KVO@temp\relax + \let\KVO@onefilewithoptions\relax + \let\@pkgextension\relax + \def\reserved@b##1,{% + \ifx\@nil##1\relax + \else + \ifx\relax##1\relax + \else + \KVO@onefilewithoptions{##1}[{\KVO@temp}][{#4}]% + \@pkgextension + \fi + \expandafter\reserved@b + \fi + }% + \edef\reserved@a{\zap@space#3 \@empty}% + \edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nil,}% + \toks@{#2}% + \def\KVO@temp{\the\toks@}% + \edef\reserved@a{\endgroup \reserved@a}% + \fi + \reserved@a +} +% \end{macrocode} +% +% \begin{macrocode} +\def\KVO@onefilewithoptions#1[#2][#3]#4{% + \@pushfilename + \xdef\@currname{#1}% + \global\let\@currext#4% + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty + \let\CurrentOption\@empty + \@reset@ptions + \makeatletter + \def\reserved@a{% + \@ifl@aded\@currext{#1}{% + \@if@ptions\@currext{#1}{#2}{% + }{% + \begingroup + \@ifundefined{opt@#1.\@currext}{% + \def\x{}% + }{% + \edef\x{% + \expandafter\expandafter\expandafter\strip@prefix + \expandafter\meaning\csname opt@#1.\@currext\endcsname + }% + }% + \def\y{#2}% + \edef\y{\expandafter\strip@prefix\meaning\y}% + \@latex@error{Option clash for \@cls@pkg\space #1}{% + The package #1 has already been loaded % + with options:\MessageBreak + \space\space[\x]\MessageBreak + There has now been an attempt to load it % + with options\MessageBreak + \space\space[\y]\MessageBreak + Adding the global options:\MessageBreak + \space\space + \x,\y\MessageBreak + to your \noexpand\documentclass declaration may fix this.% + \MessageBreak + Try typing \space <return> \space to proceed.% + }% + \endgroup + }% + }{% + \@pass@ptions\@currext{#2}{#1}% + \global\expandafter + \let\csname ver@\@currname.\@currext\endcsname\@empty + \InputIfFileExists + {\@currname.\@currext}% + {}% + {\@missingfileerror\@currname\@currext}% + \let\@unprocessedoptions\@@unprocessedoptions + \csname\@currname.\@currext-h@@k\endcsname + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname + \@undefined + \@unprocessedoptions + }% + \@ifl@ter\@currext{#1}{#3}{% + }{% + \@latex@warning@no@line{% + You have requested,\on@line, % + version\MessageBreak + #3' of \@cls@pkg\space #1,\MessageBreak + but only version\MessageBreak + `\csname ver@#1.\@currext\endcsname'\MessageBreak + is available% + }% + }% + \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi + \@popfilename + \@reset@ptions + }% + \reserved@a +} +% \end{macrocode} +% +% \begin{macrocode} +\def\@unknownoptionerror{% + \@latex@error{% + Unknown option `\KVO@SanitizedCurrentOption' % + for \@cls@pkg\space`\@currname'% + }{% + The option `\KVO@SanitizedCurrentOption' was not declared in % + \@cls@pkg\space`\@currname', perhaps you\MessageBreak + misspelled its name. % + Try typing \space <return> % + \space to proceed.% + }% +} +% \end{macrocode} +% +% \begin{macrocode} +\def\@@unprocessedoptions{% + \ifx\@currext\@pkgextension + \@ifundefined{opt@\@currname.\@currext}{% + \let\@curroptions\@empty + }{% + \expandafter\let\expandafter\@curroptions + \csname opt@\@currname.\@currext\endcsname + }% + \@for\CurrentOption:=\@curroptions\do{% + \ifx\CurrentOption\@empty\else\@unknownoptionerror\fi + }% + \fi +} +% \end{macrocode} +% +% \begin{macrocode} +\def\KVO@SanitizedCurrentOption{% + \expandafter\strip@prefix\meaning\CurrentOption +} +% \end{macrocode} +% +% Normalize option list. +% \begin{macrocode} +\def\KVO@normalize#1#2{% + \let\KVO@result\@empty + \KVO@splitcomma#2,\@nil + \let#1\KVO@result +} +\def\KVO@splitcomma#1,#2\@nil{% + \KVO@ifempty{#1}{}{% + \KVO@checkkv#1=\@nil + }% + \KVO@ifempty{#2}{}{\KVO@splitcomma#2\@nil}% +} +\def\KVO@ifempty#1{% + \expandafter\ifx\expandafter\\\detokenize{#1}\\% + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi +} +\def\KVO@checkkv#1=#2\@nil{% + \KVO@ifempty{#2}{% + % option without value + \edef\KVO@x{\zap@space#1 \@empty}% + \ifx\KVO@x\@empty + % ignore empty option + \else + % append to list + \edef\KVO@result{% + \etex@unexpanded\expandafter{\KVO@result},\KVO@x + }% + \fi + }{% + % #1: "key", #2: "value=" + % add key part + \edef\KVO@result{% + \etex@unexpanded\expandafter{\KVO@result},% + \zap@space#1 \@empty + }% + \futurelet\@let@token\KVO@checkfirsttok#2 \@nil| = \@nil|\KVO@nil + }% +} +\def\KVO@checkfirsttok{% + \ifx\@let@token\bgroup + % no space at start + \expandafter\KVO@removelastspace\expandafter=% + % "<value><spaceopt>= \@nil" + \else + \expandafter\KVO@checkfirstA + \fi +} +\def\KVO@checkfirstA#1 #2\@nil{% + \KVO@ifempty{#2}{% + \KVO@removelastspace=#1 \@nil + }{% + \KVO@ifempty{#1}{% + \KVO@removelastspace=#2\@nil + }{% + \KVO@removelastspace=#1 #2\@nil + }% + }% +} +\def\KVO@removelastspace#1 = \@nil|#2\KVO@nil{% + \KVO@ifempty{#2}{% + \edef\KVO@result{% + \etex@unexpanded\expandafter{\KVO@result}% + \etex@unexpanded\expandafter{\KVO@removegarbage#1\KVO@nil}% + }% + }{% + \edef\KVO@result{% + \etex@unexpanded\expandafter{\KVO@result}% + \etex@unexpanded{#1}% + }% + }% +} +\def\KVO@removegarbage#1= \@nil#2\KVO@nil{#1}% +% \end{macrocode} +% +% Arguments |#1| and |#2| are macros. +% \begin{macrocode} +\def\KVO@removeelement#1#2{% + \begingroup + \toks@={}% + \@for\x:=#2\do{% + \ifx\x\@empty + \else + \ifx\x#1\relax + \else + \edef\t{\the\toks@}% + \ifx\t\@empty + \else + \toks@\expandafter{\the\toks@,}% + \fi + \toks@\expandafter{\the\expandafter\toks@\x}% + \fi + \fi + }% + \edef\x{\endgroup + \def\noexpand#2{\the\toks@}% + }% + \x +} +% \end{macrocode} +% +% +% \begin{macrocode} +\let\@@fileswith@pti@ns\KVO@fileswith@pti@ns +\ifx\@fileswith@pti@ns\@badrequireerror +\else + \let\@fileswith@pti@ns\KVO@fileswith@pti@ns +\fi +% \end{macrocode} +% +% \begin{macro}{\KVO@Patch} +% \begin{macrocode} +\let\KVO@Patch=Y +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\KVO@AtEnd% +%</patch> +% \end{macrocode} +% +% \section{Test} +% +% \subsection{Preface for standard catcode check} +% +% \begin{macrocode} +%<*test1> +\input miniltx.tex\relax +%</test1> +% \end{macrocode} +% +% \subsection{Catcode checks for loading} +% +% \begin{macrocode} +%<*test1> +% \end{macrocode} +% \begin{macrocode} +\catcode`\{=1 % +\catcode`\}=2 % +\catcode`\#=6 % +\catcode`\@=11 % +\expandafter\ifx\csname count@\endcsname\relax + \countdef\count@=255 % +\fi +\expandafter\ifx\csname @gobble\endcsname\relax + \long\def\@gobble#1{}% +\fi +\expandafter\ifx\csname @firstofone\endcsname\relax + \long\def\@firstofone#1{#1}% +\fi +\expandafter\ifx\csname loop\endcsname\relax + \expandafter\@firstofone +\else + \expandafter\@gobble +\fi +{% + \def\loop#1\repeat{% + \def\body{#1}% + \iterate + }% + \def\iterate{% + \body + \let\next\iterate + \else + \let\next\relax + \fi + \next + }% + \let\repeat=\fi +}% +\def\RestoreCatcodes{} +\count@=0 % +\loop + \edef\RestoreCatcodes{% + \RestoreCatcodes + \catcode\the\count@=\the\catcode\count@\relax + }% +\ifnum\count@<255 % + \advance\count@ 1 % +\repeat + +\def\RangeCatcodeInvalid#1#2{% + \count@=#1\relax + \loop + \catcode\count@=15 % + \ifnum\count@<#2\relax + \advance\count@ 1 % + \repeat +} +\def\RangeCatcodeCheck#1#2#3{% + \count@=#1\relax + \loop + \ifnum#3=\catcode\count@ + \else + \errmessage{% + Character \the\count@\space + with wrong catcode \the\catcode\count@\space + instead of \number#3% + }% + \fi + \ifnum\count@<#2\relax + \advance\count@ 1 % + \repeat +} +\def\space{ } +\expandafter\ifx\csname LoadCommand\endcsname\relax + \def\LoadCommand{\input kvoptions.sty\relax}% +\fi +\def\Test{% + \RangeCatcodeInvalid{0}{47}% + \RangeCatcodeInvalid{58}{64}% + \RangeCatcodeInvalid{91}{96}% + \RangeCatcodeInvalid{123}{255}% + \catcode`\@=12 % + \catcode`\\=0 % + \catcode`\%=14 % + \LoadCommand + \RangeCatcodeCheck{0}{36}{15}% + \RangeCatcodeCheck{37}{37}{14}% + \RangeCatcodeCheck{38}{47}{15}% + \RangeCatcodeCheck{48}{57}{12}% + \RangeCatcodeCheck{58}{63}{15}% + \RangeCatcodeCheck{64}{64}{12}% + \RangeCatcodeCheck{65}{90}{11}% + \RangeCatcodeCheck{91}{91}{15}% + \RangeCatcodeCheck{92}{92}{0}% + \RangeCatcodeCheck{93}{96}{15}% + \RangeCatcodeCheck{97}{122}{11}% + \RangeCatcodeCheck{123}{255}{15}% + \RestoreCatcodes +} +\Test +\csname @@end\endcsname +\end +% \end{macrocode} +% \begin{macrocode} +%</test1> +% \end{macrocode} +% +% \begin{macrocode} +%<*test2> +\NeedsTeXFormat{LaTeX2e} +\makeatletter +\catcode`\@=11 % +\def\RestoreCatcodes{} +\count@=0 % +\loop + \edef\RestoreCatcodes{% + \RestoreCatcodes + \catcode\the\count@=\the\catcode\count@\relax + }% +\ifnum\count@<255 % + \advance\count@\@ne +\repeat + +\def\RangeCatcodeInvalid#1#2{% + \count@=#1\relax + \loop + \catcode\count@=15 % + \ifnum\count@<#2\relax + \advance\count@\@ne + \repeat +} +\def\Test#1{% + \RangeCatcodeInvalid{0}{47}% + \RangeCatcodeInvalid{58}{64}% + \RangeCatcodeInvalid{91}{96}% + \RangeCatcodeInvalid{123}{255}% + \catcode`\@=12 % + \catcode`\\=0 % + \catcode`\{=1 % + \catcode`\}=2 % + \catcode`\#=6 % + \catcode`\[=12 % + \catcode`\]=12 % + \catcode`\%=14 % + \catcode`\ =10 % + \catcode13=5 % + #1\relax + \RestoreCatcodes +} +\Test{\RequirePackage{kvoptions-patch}}% +\Test{\RequirePackage{kvoptions}}% +\csname @@end\endcsname +%</test2> +% \end{macrocode} +% +% \begin{macrocode} +%<*test3> +\NeedsTeXFormat{LaTeX2e} +\makeatletter +\RequirePackage{kvoptions}[2019/11/29] +\def\msg#{\immediate\write16} +\define@key{testfamily}{testkey}{% + \msg{[testfamily/testkey/#1]}% +} +\define@key{testfamily}{testdefaultkey}[testdefault]{% + \msg{[testfamily/testdefaultkey/#1]}% +} +\AddToKeyvalOption{testfamily}{testkey}{% + \msg{[addition/#1]}% +} +\AddToKeyvalOption{testfamily}{testdefaultkey}{% + \msg{[addition/#1]}% +} +\setkeys{testfamily}{% + testkey=testA,% + testdefaultkey=testB,% + testdefaultkey,% +} +\SetupKeyvalOptions{% + family=testfamily% +} +\AddToKeyvalOption*{testkey}{% + \msg{[star addition/#1]}% +} +\AddToKeyvalOption*{testdefaultkey}{% + \msg{[star addition/#1]}% +} +\setkeys{testfamily}{% + testkey=testA,% + testdefaultkey=testB,% + testdefaultkey,% +} +\@@end +%</test3> +% \end{macrocode} +% +% \begin{macrocode} +%<*test4pkg> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{kvoptions-test4}[2019/11/29 package for testing] +\RequirePackage{kvoptions}[2019/11/29] +\SetupKeyvalOptions{% + family=FOO,% + prefix=foo,% + setkeys=\kvsetkeys,% +} +\DeclareStringOption{str} +\define@key{FOO}{set}{% + \setkeys{BAR}{strbar={#1}}% +} +\define@key{BAR}{strbar}{% + \def\foostr{[BAR:#1]}% +} +\ProcessKeyvalOptions* +%</test4pkg> +% \end{macrocode} +% \begin{macrocode} +%<*test4> +\NeedsTeXFormat{LaTeX2e} +\ProvidesFile{kvoptions-test4.tex}[2019/11/29 test file] +\RequirePackage[% + str=A,set=B,str=C,% +]{kvoptions-test4}[2019/11/29] +\def\TestExpected{C} +\ifx\foostr\TestExpected + \typeout{* Test ok.}% +\else + \typeout{* Result: [\foostr]}% + \typeout{* Expected: [\TestExpected]}% + \errmessage{Test failed!}% +\fi +\csname @@end\endcsname\end +%</test4> +% \end{macrocode} +% +% \section{Installation} +% +% \subsection{Download} +% +% \paragraph{Package.} This package is available on +% CTAN\footnote{\CTANpkg{kvoptions}}: +% \begin{description} +% \item[\CTAN{macros/latex/contrib/kvoptions/kvoptions.dtx}] The source file. +% \item[\CTAN{macros/latex/contrib/kvoptions/kvoptions.pdf}] Documentation. +% \end{description} +% +% +% \paragraph{Bundle.} All the packages of the bundle `kvoptions' +% are also available in a TDS compliant ZIP archive. There +% the packages are already unpacked and the documentation files +% are generated. The files and directories obey the TDS standard. +% \begin{description} +% \item[\CTANinstall{install/macros/latex/contrib/kvoptions.tds.zip}] +% \end{description} +% \emph{TDS} refers to the standard ``A Directory Structure +% for \TeX\ Files'' (\CTANpkg{tds}). Directories +% with \xfile{texmf} in their name are usually organized this way. +% +% \subsection{Bundle installation} +% +% \paragraph{Unpacking.} Unpack the \xfile{kvoptions.tds.zip} in the +% TDS tree (also known as \xfile{texmf} tree) of your choice. +% Example (linux): +% \begin{quote} +% |unzip kvoptions.tds.zip -d ~/texmf| +% \end{quote} +% +% \subsection{Package installation} +% +% \paragraph{Unpacking.} The \xfile{.dtx} file is a self-extracting +% \docstrip\ archive. The files are extracted by running the +% \xfile{.dtx} through \plainTeX: +% \begin{quote} +% \verb|tex kvoptions.dtx| +% \end{quote} +% +% \paragraph{TDS.} Now the different files must be moved into +% the different directories in your installation TDS tree +% (also known as \xfile{texmf} tree): +% \begin{quote} +% \def\t{^^A +% \begin{tabular}{@{}>{\ttfamily}l@{ $\rightarrow$ }>{\ttfamily}l@{}} +% kvoptions.sty & tex/latex/kvoptions/kvoptions.sty\\ +% kvoptions-patch.sty & tex/latex/kvoptions/kvoptions-patch.sty\\ +% kvoptions.pdf & doc/latex/kvoptions/kvoptions.pdf\\ +% example-mycolorsetup.sty & doc/latex/kvoptions/example-mycolorsetup.sty\\ +% kvoptions.dtx & source/latex/kvoptions/kvoptions.dtx\\ +% \end{tabular}^^A +% }^^A +% \sbox0{\t}^^A +% \ifdim\wd0>\linewidth +% \begingroup +% \advance\linewidth by\leftmargin +% \advance\linewidth by\rightmargin +% \edef\x{\endgroup +% \def\noexpand\lw{\the\linewidth}^^A +% }\x +% \def\lwbox{^^A +% \leavevmode +% \hbox to \linewidth{^^A +% \kern-\leftmargin\relax +% \hss +% \usebox0 +% \hss +% \kern-\rightmargin\relax +% }^^A +% }^^A +% \ifdim\wd0>\lw +% \sbox0{\small\t}^^A +% \ifdim\wd0>\linewidth +% \ifdim\wd0>\lw +% \sbox0{\footnotesize\t}^^A +% \ifdim\wd0>\linewidth +% \ifdim\wd0>\lw +% \sbox0{\scriptsize\t}^^A +% \ifdim\wd0>\linewidth +% \ifdim\wd0>\lw +% \sbox0{\tiny\t}^^A +% \ifdim\wd0>\linewidth +% \lwbox +% \else +% \usebox0 +% \fi +% \else +% \lwbox +% \fi +% \else +% \usebox0 +% \fi +% \else +% \lwbox +% \fi +% \else +% \usebox0 +% \fi +% \else +% \lwbox +% \fi +% \else +% \usebox0 +% \fi +% \else +% \lwbox +% \fi +% \else +% \usebox0 +% \fi +% \end{quote} +% If you have a \xfile{docstrip.cfg} that configures and enables \docstrip's +% TDS installing feature, then some files can already be in the right +% place, see the documentation of \docstrip. +% +% \subsection{Refresh file name databases} +% +% If your \TeX~distribution +% (\TeX\,Live, \mikTeX, \dots) relies on file name databases, you must refresh +% these. For example, \TeX\,Live\ users run \verb|texhash| or +% \verb|mktexlsr|. +% +% \subsection{Some details for the interested} +% +% \paragraph{Unpacking with \LaTeX.} +% The \xfile{.dtx} chooses its action depending on the format: +% \begin{description} +% \item[\plainTeX:] Run \docstrip\ and extract the files. +% \item[\LaTeX:] Generate the documentation. +% \end{description} +% If you insist on using \LaTeX\ for \docstrip\ (really, +% \docstrip\ does not need \LaTeX), then inform the autodetect routine +% about your intention: +% \begin{quote} +% \verb|latex \let\install=y\input{kvoptions.dtx}| +% \end{quote} +% Do not forget to quote the argument according to the demands +% of your shell. +% +% \paragraph{Generating the documentation.} +% You can use both the \xfile{.dtx} or the \xfile{.drv} to generate +% the documentation. The process can be configured by the +% configuration file \xfile{ltxdoc.cfg}. For instance, put this +% line into this file, if you want to have A4 as paper format: +% \begin{quote} +% \verb|\PassOptionsToClass{a4paper}{article}| +% \end{quote} +% An example follows how to generate the +% documentation with pdf\LaTeX: +% \begin{quote} +%\begin{verbatim} +%pdflatex kvoptions.dtx +%makeindex -s gind.ist kvoptions.idx +%pdflatex kvoptions.dtx +%makeindex -s gind.ist kvoptions.idx +%pdflatex kvoptions.dtx +%\end{verbatim} +% \end{quote} +% +% \begin{thebibliography}{99} +% \bibitem{tb94wright} +% A guide to key-value methods, Joseph Wright, second draft for +% \href{https://www.tug.org/tugboat}{TUGBoat}, 2009-03-17. +% \url{https://www.texdev.net/uploads/2009/03/keyval.pdf} +% \bibpackage{ifthen}{David Carlisle}{2001/05/26} +% {\CTANpkg{ifthen}} +% \bibpackage{helvet}{Sebastian Rahtz, Walter Schmidt}{2004/01/26} +% {\CTANpkg{psfonts}} +% \bibpackage{hyperref}{Sebastian Rahtz, Heiko Oberdiek}{2006/02/12} +% {\CTANpkg{hyperref}} +% \bibpackage{keyval}{David Carlisle}{1999/03/16} +% {\CTANpkg{keyval}} +% \bibpackage{multicol}{Frank Mittelbach}{2004/02/14} +% {\CTANpkg{multicol}} +% \bibpackage{tabularx}{David Carlisle}{1999/01/07} +% {\CTANpkg{tabularx}} +% \bibpackage{tracefnt}{Frank Mittelbach, Rainer Sch\"opf}{1997/05/29} +% {\CTANpkg{latex-base}} +% \bibpackage{xkeyval}{Hendri Adriaens}{2005/05/07} +% {\CTANpkg{xkeyval}} +% \bibitem{clsguide} +% The \LaTeX3 Project, \textit{\LaTeXe\ for class and package writers}, +% 2003/12/09. +% \CTANpkg{clsguide} +% +% \end{thebibliography} +% +% \begin{History} +% \begin{Version}{0000/00/00 v0.0} +% \item +% Probably David Carlisle's code in \xpackage{hyperref} +% was the start. +% \end{Version} +% \begin{Version}{2004/02/22 v1.0} +% \item +% The first version was never published. It also +% has offered a patch to get rid of \LaTeX's option +% expansion. +% \end{Version} +% \begin{Version}{2006/02/16 v2.0} +% \item +% Now the package is redesigned with an easier +% user interface. +% \item +% \cs{ProcessKeyvalOptions} remains the central service, inherited +% from \xpackage{hyperref}'s \cs{ProcessOptionsWithKV}. +% Now the use inside classes is also supported. +% \item +% Provides help macros for boolean and simple string options. +% \item +% Fixes for the patch of \LaTeX{}. The patch is only enabled, +% if the user requests it. +% \end{Version} +% \begin{Version}{2006/02/20 v2.1} +% \item +% Unused option list is sanitized to prevent problems +% with other packages that uses own processing methods +% for key value options. Disadvantage: the unused global +% option detection is weakened. +% \item +% New option type by \cs{DeclareVoidOption} for options without +% value. +% \item +% Default rule by \cs{DeclareDefaultOption}. +% \item +% Dynamic options: \cs{DisableKeyvalOption}. +% \end{Version} +% \begin{Version}{2006/06/01 v2.2} +% \item +% Fixes for option \xoption{patch}. +% \end{Version} +% \begin{Version}{2006/08/17 v2.3} +% \item +% \cs{DeclareBooleanOption} renamed to \cs{DeclareBoolOption} +% to avoid a name clash with package \cs{ifoption}. +% \end{Version} +% \begin{Version}{2006/08/22 v2.4} +% \item +% Option \xoption{patch}: \cs{ExecuteOptions} does not +% change the meaning of macro \cs{CurrentOption} at all. +% \end{Version} +% \begin{Version}{2007/04/11 v2.5} +% \item +% Line ends sanitized. +% \end{Version} +% \begin{Version}{2007/05/06 v2.6} +% \item +% Uses package \xpackage{etexcmds}. +% \end{Version} +% \begin{Version}{2007/06/11 v2.7} +% \item +% The patch part fixes LaTeX bug latex/3965. +% \end{Version} +% \begin{Version}{2007/10/02 v2.8} +% \item +% Compatibility for \plainTeX\ added. +% \item +% Typos in documentation fixed (Axel Sommerfeldt). +% \end{Version} +% \begin{Version}{2007/10/11 v2.9} +% \item +% Bug fix for option \xoption{patch}. +% \end{Version} +% \begin{Version}{2007/10/18 v3.0} +% \item +% New package \xpackage{kvoptions-patch}. +% \end{Version} +% \begin{Version}{2009/04/10 v3.1} +% \item +% Space by line end removed in definition of internal macro. +% \end{Version} +% \begin{Version}{2009/07/17 v3.2} +% \item +% \cs{ProcessLocalKeyvalOptions} added. +% \item +% \cs{DisableKeyvalOption} with the \texttt{action=ignore} option +% fixed (Joseph Wright). +% \end{Version} +% \begin{Version}{2009/07/21 v3.3} +% \item +% \cs{DeclareLocalOption}, \cs{DeclareLocalOptions} added. +% \end{Version} +% \begin{Version}{2009/08/13 v3.4} +% \item +% Documentation addition: recommendation for Joseph Wright's +% review article. +% \item +% Documentation addition: local/global options. +% \end{Version} +% \begin{Version}{2009/12/04 v3.5} +% \item +% \cs{AddToKeyvalOption} added. +% \end{Version} +% \begin{Version}{2009/12/08 v3.6} +% \item +% Fix: If a default handler is configured, it is now also +% called for classes. +% \end{Version} +% \begin{Version}{2010/02/22 v3.7} +% \item +% Missing space in error message added. +% \end{Version} +% \begin{Version}{2010/07/23 v3.8} +% \item +% Documenation for package \xpackage{kvoptions-patch} improved. +% No code changes. +% \end{Version} +% \begin{Version}{2010/12/02 v3.9} +% \item +% Key \texttt{setkeys} added for \cs{SetupKeyvalOptions}. +% \end{Version} +% \begin{Version}{2010/12/23 v3.10} +% \item +% \cs{DeclareVoidOption} also parses the second parameter as +% \hologo{TeX} argument to improve compatibility with +% \cs{DeclareOption}. +% \end{Version} +% \begin{Version}{2011/06/30 v3.11} +% \item +% Fix because of design bug in package \xpackage{xkeyval} that +% removes global options with equal signs. +% \end{Version} +% \begin{Version}{2016/05/16 v3.12} +% \item +% Documentation updates. +% \end{Version} +% \begin{Version}{2019/11/29 v3.13} +% \item +% Documentation updates. +% \end{Version} +% \end{History} +% +% \PrintIndex +% +% \Finale +\endinput diff --git a/Master/texmf-dist/tex/latex/kvoptions/kvoptions-patch.sty b/Master/texmf-dist/tex/latex/kvoptions/kvoptions-patch.sty new file mode 100644 index 00000000000..28c106b8487 --- /dev/null +++ b/Master/texmf-dist/tex/latex/kvoptions/kvoptions-patch.sty @@ -0,0 +1,544 @@ +%% +%% This is file `kvoptions-patch.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% kvoptions.dtx (with options: `patch') +%% +%% This is a generated file. +%% +%% Project: kvoptions +%% Version: 2019/11/29 v3.13 +%% +%% Copyright (C) +%% 2004, 2006, 2007, 2009-2011 Heiko Oberdiek +%% 2016-2019 Oberdiek Package Support Group +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3c of this license or (at your option) any later +%% version. This version of this license is in +%% https://www.latex-project.org/lppl/lppl-1-3c.txt +%% and the latest version of this license is in +%% https://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of +%% LaTeX version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status "maintained". +%% +%% The Current Maintainers of this work are +%% Heiko Oberdiek and the Oberdiek Package Support Group +%% https://github.com/ho-tex/kvoptions/issues +%% +%% +%% This work consists of the main source file kvoptions.dtx +%% and the derived files +%% kvoptions.sty, kvoptions.pdf, kvoptions.ins, kvoptions.drv, +%% kvoptions-patch.sty, example-mycolorsetup.sty, +%% kvoptions-test1.tex, kvoptions-test2.tex, +%% kvoptions-test3.tex, kvoptions-test4.tex, +%% kvoptions-test4.sty. +%% +%% No we don't need the option 'color'. +%% With color support option 'emphcolor' will dynamically +%% change the color of \emph statements. +\def\KVO@IfDefThen#1#2{% + \ifx#1\ltx@undefined + \else + \ifx#1\relax + \else + #2% + \fi + \fi +}% +\def\KVO@GetClassOptionsList{% + \let\KVO@classoptionslist\@classoptionslist + \KVO@IfDefThen\@classoptionslist{% + \KVO@IfDefThen\XKV@documentclass{% + \ifx\XKV@documentclass\ltx@empty + \else + \KVO@IfDefThen\XKV@classoptionslist{% + \ifx\XKV@classoptionslist\ltx@empty + \else + \let\KVO@classoptionslist\XKV@classoptionslist + \fi + }% + \fi + }% + }% +}% +\NeedsTeXFormat{LaTeX2e} +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode123=1 % { + \catcode125=2 % } + \catcode64=11 % @ + \def\x{\endgroup + \expandafter\edef\csname KVO@AtEnd\endcsname{% + \endlinechar=\the\endlinechar\relax + \catcode13=\the\catcode13\relax + \catcode32=\the\catcode32\relax + \catcode35=\the\catcode35\relax + \catcode61=\the\catcode61\relax + \catcode64=\the\catcode64\relax + \catcode123=\the\catcode123\relax + \catcode125=\the\catcode125\relax + }% + }% +\x\catcode61\catcode48\catcode32=10\relax% +\catcode13=5 % ^^M +\endlinechar=13 % +\catcode35=6 % # +\catcode64=11 % @ +\catcode123=1 % { +\catcode125=2 % } +\def\TMP@EnsureCode#1#2{% + \edef\KVO@AtEnd{% + \KVO@AtEnd + \catcode#1=\the\catcode#1\relax + }% + \catcode#1=#2\relax +} +\TMP@EnsureCode{39}{12}% ' +\TMP@EnsureCode{40}{12}% ( +\TMP@EnsureCode{41}{12}% ) +\TMP@EnsureCode{43}{12}% + +\TMP@EnsureCode{44}{12}% , +\TMP@EnsureCode{45}{12}% - +\TMP@EnsureCode{46}{12}% . +\TMP@EnsureCode{47}{12}% / +\TMP@EnsureCode{58}{12}% : +\TMP@EnsureCode{60}{12}% < +\TMP@EnsureCode{62}{12}% > +\TMP@EnsureCode{91}{12}% [ +\TMP@EnsureCode{93}{12}% ] +\TMP@EnsureCode{96}{12}% ` +\TMP@EnsureCode{124}{12}% | +\edef\KVO@AtEnd{\KVO@AtEnd\noexpand\endinput} +\ProvidesPackage{kvoptions-patch}% + [2019/11/29 v3.13 LaTeX patch for keyval options (HO)]% +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname eTeXversion\endcsname\relax + \PackageWarningNoLine{kvoptions-patch}{% + Package loading is aborted, because e-TeX is missing% + }% + \expandafter\KVO@AtEnd +\fi% +\RequirePackage{etexcmds}[2007/09/09] +\ifetex@unexpanded +\else + \PackageError{kvoptions-patch}{% + Could not find eTeX's \string\unexpanded.\MessageBreak + Try adding \string\RequirePackage\string{etexcmds\string} % + before \string\documentclass% + }\@ehd + \expandafter\KVO@AtEnd +\fi% +\@ifpackageloaded{xkvltxp}{% + \PackageWarningNoLine{kvoptions}{% + Option `patch' cannot be used together with\MessageBreak + package `xkvltxp' that is already loaded.\MessageBreak + Therefore package loading is aborted% + }% + \KVO@AtEnd +}{}% +\def\@if@ptions#1#2#3{% + \begingroup + \KVO@normalize\KVO@temp{#3}% + \edef\x{\endgroup + \noexpand\@if@pti@ns{% + \detokenize\expandafter\expandafter\expandafter{% + \csname opt@#2.#1\endcsname + }% + }{% + \detokenize\expandafter{\KVO@temp}% + }% + }% + \x +} +\def\@pass@ptions#1#2#3{% + \KVO@normalize\KVO@temp{#2}% + \@ifundefined{opt@#3.#1}{% + \expandafter\gdef\csname opt@#3.#1% + \expandafter\endcsname\expandafter{% + \KVO@temp + }% + }{% + \expandafter\gdef\csname opt@#3.#1% + \expandafter\expandafter\expandafter\endcsname + \expandafter\expandafter\expandafter{% + \csname opt@#3.#1\expandafter\endcsname\expandafter,\KVO@temp + }% + }% +} +\def\ProcessOptions{% + \let\ds@\@empty + \@ifundefined{opt@\@currname.\@currext}{% + \let\@curroptions\@empty + }{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter\@curroptions + \expandafter\expandafter\expandafter{% + \csname opt@\@currname.\@currext\endcsname + }% + }% + \@ifstar\KVO@xprocess@ptions\KVO@process@ptions +} +\def\KVO@process@ptions{% + \@for\CurrentOption:=\@declaredoptions\do{% + \ifx\CurrentOption\@empty + \else + \begingroup + \ifx\@currext\@clsextension + \toks@{}% + \else + \KVO@GetClassOptionsList + \toks@\expandafter{\KVO@classoptionslist,}% + \fi + \toks\tw@\expandafter{\@curroptions}% + \edef\x{\endgroup + \noexpand\in@{,\CurrentOption,}{,\the\toks@\the\toks\tw@,}% + }% + \x + \ifin@ + \KVO@use@ption + \expandafter\let\csname ds@\CurrentOption\endcsname\@empty + \fi + \fi + }% + \KVO@process@pti@ns +} +\def\KVO@xprocess@ptions{% + \ifx\@currext\@clsextension + \else + \KVO@GetClassOptionsList + \@for\CurrentOption:=\KVO@classoptionslist\do{% + \ifx\CurrentOption\@empty + \else + \KVO@in@\CurrentOption\@declaredoptions + \ifin@ + \KVO@use@ption + \expandafter\let\csname ds@\CurrentOption\endcsname\@empty + \fi + \fi + }% + \fi + \KVO@process@pti@ns +} +\def\KVO@in@#1#2{% + \in@false + \begingroup + \@for\x:=#2\do{% + \ifx\x#1\relax + \in@true + \fi + }% + \edef\x{\endgroup + \ifin@ + \noexpand\in@true + \fi + }% + \x +} +\def\KVO@process@pti@ns{% + \@for\CurrentOption:=\@curroptions\do{% + \@ifundefined{ds@\KVO@SanitizedCurrentOption}{% + \KVO@use@ption + \default@ds + }% + \KVO@use@ption + }% + \@for\CurrentOption:=\@declaredoptions\do{% + \expandafter\let\csname ds@\CurrentOption\endcsname\relax + }% + \let\CurrentOption\@empty + \let\@fileswith@pti@ns\@@fileswith@pti@ns + \AtEndOfPackage{\let\@unprocessedoptions\relax}% +} +\def\KVO@use@ption{% + \begingroup + \edef\x{\endgroup + \noexpand\@removeelement{% + \detokenize\expandafter{\CurrentOption}% + }{% + \detokenize\expandafter{\@unusedoptionlist}% + }% + }% + \x\@unusedoptionlist + \csname ds@\KVO@SanitizedCurrentOption\endcsname +} +\def\OptionNotUsed{% + \ifx\@currext\@clsextension + \xdef\@unusedoptionlist{% + \ifx\@unusedoptionlist\@empty + \else + \detokenize\expandafter{\@unusedoptionlist,}% + \fi + \detokenize\expandafter{\CurrentOption}% + }% + \fi +} +\def\CurrentOption@SaveLevel{0} +\def\ExecuteOptions{% + \expandafter\KVO@ExecuteOptions + \csname CurrentOption@\CurrentOption@SaveLevel\endcsname +} +\def\KVO@ExecuteOptions#1#2{% + \let#1\CurrentOption + \edef\CurrentOption@SaveLevel{% + \the\numexpr\CurrentOption@SaveLevel+1% + }% + \@for\CurrentOption:=#2\do{% + \csname ds@\CurrentOption\endcsname + }% + \edef\CurrentOption@SaveLevel{% + \the\numexpr\CurrentOption@SaveLevel-1% + }% + \let\CurrentOption#1% +} +\def\KVO@fileswith@pti@ns#1[#2]#3[#4]{% + \ifx#1\@clsextension + \ifx\@classoptionslist\relax + \KVO@normalize\KVO@temp{#2}% + \expandafter\gdef\expandafter\@classoptionslist\expandafter{% + \KVO@temp + }% + \def\reserved@a{% + \KVO@onefilewithoptions{#3}[{#2}][{#4}]#1% + \@documentclasshook + }% + \else + \def\reserved@a{% + \KVO@onefilewithoptions{#3}[{#2}][{#4}]#1% + }% + \fi + \else + \begingroup + \let\KVO@temp\relax + \let\KVO@onefilewithoptions\relax + \let\@pkgextension\relax + \def\reserved@b##1,{% + \ifx\@nil##1\relax + \else + \ifx\relax##1\relax + \else + \KVO@onefilewithoptions{##1}[{\KVO@temp}][{#4}]% + \@pkgextension + \fi + \expandafter\reserved@b + \fi + }% + \edef\reserved@a{\zap@space#3 \@empty}% + \edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nil,}% + \toks@{#2}% + \def\KVO@temp{\the\toks@}% + \edef\reserved@a{\endgroup \reserved@a}% + \fi + \reserved@a +} +\def\KVO@onefilewithoptions#1[#2][#3]#4{% + \@pushfilename + \xdef\@currname{#1}% + \global\let\@currext#4% + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty + \let\CurrentOption\@empty + \@reset@ptions + \makeatletter + \def\reserved@a{% + \@ifl@aded\@currext{#1}{% + \@if@ptions\@currext{#1}{#2}{% + }{% + \begingroup + \@ifundefined{opt@#1.\@currext}{% + \def\x{}% + }{% + \edef\x{% + \expandafter\expandafter\expandafter\strip@prefix + \expandafter\meaning\csname opt@#1.\@currext\endcsname + }% + }% + \def\y{#2}% + \edef\y{\expandafter\strip@prefix\meaning\y}% + \@latex@error{Option clash for \@cls@pkg\space #1}{% + The package #1 has already been loaded % + with options:\MessageBreak + \space\space[\x]\MessageBreak + There has now been an attempt to load it % + with options\MessageBreak + \space\space[\y]\MessageBreak + Adding the global options:\MessageBreak + \space\space + \x,\y\MessageBreak + to your \noexpand\documentclass declaration may fix this.% + \MessageBreak + Try typing \space <return> \space to proceed.% + }% + \endgroup + }% + }{% + \@pass@ptions\@currext{#2}{#1}% + \global\expandafter + \let\csname ver@\@currname.\@currext\endcsname\@empty + \InputIfFileExists + {\@currname.\@currext}% + {}% + {\@missingfileerror\@currname\@currext}% + \let\@unprocessedoptions\@@unprocessedoptions + \csname\@currname.\@currext-h@@k\endcsname + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname + \@undefined + \@unprocessedoptions + }% + \@ifl@ter\@currext{#1}{#3}{% + }{% + \@latex@warning@no@line{% + You have requested,\on@line, % + version\MessageBreak + #3' of \@cls@pkg\space #1,\MessageBreak + but only version\MessageBreak + `\csname ver@#1.\@currext\endcsname'\MessageBreak + is available% + }% + }% + \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi + \@popfilename + \@reset@ptions + }% + \reserved@a +} +\def\@unknownoptionerror{% + \@latex@error{% + Unknown option `\KVO@SanitizedCurrentOption' % + for \@cls@pkg\space`\@currname'% + }{% + The option `\KVO@SanitizedCurrentOption' was not declared in % + \@cls@pkg\space`\@currname', perhaps you\MessageBreak + misspelled its name. % + Try typing \space <return> % + \space to proceed.% + }% +} +\def\@@unprocessedoptions{% + \ifx\@currext\@pkgextension + \@ifundefined{opt@\@currname.\@currext}{% + \let\@curroptions\@empty + }{% + \expandafter\let\expandafter\@curroptions + \csname opt@\@currname.\@currext\endcsname + }% + \@for\CurrentOption:=\@curroptions\do{% + \ifx\CurrentOption\@empty\else\@unknownoptionerror\fi + }% + \fi +} +\def\KVO@SanitizedCurrentOption{% + \expandafter\strip@prefix\meaning\CurrentOption +} +\def\KVO@normalize#1#2{% + \let\KVO@result\@empty + \KVO@splitcomma#2,\@nil + \let#1\KVO@result +} +\def\KVO@splitcomma#1,#2\@nil{% + \KVO@ifempty{#1}{}{% + \KVO@checkkv#1=\@nil + }% + \KVO@ifempty{#2}{}{\KVO@splitcomma#2\@nil}% +} +\def\KVO@ifempty#1{% + \expandafter\ifx\expandafter\\\detokenize{#1}\\% + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi +} +\def\KVO@checkkv#1=#2\@nil{% + \KVO@ifempty{#2}{% + % option without value + \edef\KVO@x{\zap@space#1 \@empty}% + \ifx\KVO@x\@empty + % ignore empty option + \else + % append to list + \edef\KVO@result{% + \etex@unexpanded\expandafter{\KVO@result},\KVO@x + }% + \fi + }{% + % #1: "key", #2: "value=" + % add key part + \edef\KVO@result{% + \etex@unexpanded\expandafter{\KVO@result},% + \zap@space#1 \@empty + }% + \futurelet\@let@token\KVO@checkfirsttok#2 \@nil| = \@nil|\KVO@nil + }% +} +\def\KVO@checkfirsttok{% + \ifx\@let@token\bgroup + % no space at start + \expandafter\KVO@removelastspace\expandafter=% + % "<value><spaceopt>= \@nil" + \else + \expandafter\KVO@checkfirstA + \fi +} +\def\KVO@checkfirstA#1 #2\@nil{% + \KVO@ifempty{#2}{% + \KVO@removelastspace=#1 \@nil + }{% + \KVO@ifempty{#1}{% + \KVO@removelastspace=#2\@nil + }{% + \KVO@removelastspace=#1 #2\@nil + }% + }% +} +\def\KVO@removelastspace#1 = \@nil|#2\KVO@nil{% + \KVO@ifempty{#2}{% + \edef\KVO@result{% + \etex@unexpanded\expandafter{\KVO@result}% + \etex@unexpanded\expandafter{\KVO@removegarbage#1\KVO@nil}% + }% + }{% + \edef\KVO@result{% + \etex@unexpanded\expandafter{\KVO@result}% + \etex@unexpanded{#1}% + }% + }% +} +\def\KVO@removegarbage#1= \@nil#2\KVO@nil{#1}% +\def\KVO@removeelement#1#2{% + \begingroup + \toks@={}% + \@for\x:=#2\do{% + \ifx\x\@empty + \else + \ifx\x#1\relax + \else + \edef\t{\the\toks@}% + \ifx\t\@empty + \else + \toks@\expandafter{\the\toks@,}% + \fi + \toks@\expandafter{\the\expandafter\toks@\x}% + \fi + \fi + }% + \edef\x{\endgroup + \def\noexpand#2{\the\toks@}% + }% + \x +} +\let\@@fileswith@pti@ns\KVO@fileswith@pti@ns +\ifx\@fileswith@pti@ns\@badrequireerror +\else + \let\@fileswith@pti@ns\KVO@fileswith@pti@ns +\fi +\let\KVO@Patch=Y +\KVO@AtEnd% +\endinput +%% +%% End of file `kvoptions-patch.sty'. diff --git a/Master/texmf-dist/tex/latex/kvoptions/kvoptions.sty b/Master/texmf-dist/tex/latex/kvoptions/kvoptions.sty new file mode 100644 index 00000000000..6451bb0e7b3 --- /dev/null +++ b/Master/texmf-dist/tex/latex/kvoptions/kvoptions.sty @@ -0,0 +1,836 @@ +%% +%% This is file `kvoptions.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% kvoptions.dtx (with options: `package') +%% +%% This is a generated file. +%% +%% Project: kvoptions +%% Version: 2019/11/29 v3.13 +%% +%% Copyright (C) +%% 2004, 2006, 2007, 2009-2011 Heiko Oberdiek +%% 2016-2019 Oberdiek Package Support Group +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3c of this license or (at your option) any later +%% version. This version of this license is in +%% https://www.latex-project.org/lppl/lppl-1-3c.txt +%% and the latest version of this license is in +%% https://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of +%% LaTeX version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status "maintained". +%% +%% The Current Maintainers of this work are +%% Heiko Oberdiek and the Oberdiek Package Support Group +%% https://github.com/ho-tex/kvoptions/issues +%% +%% +%% This work consists of the main source file kvoptions.dtx +%% and the derived files +%% kvoptions.sty, kvoptions.pdf, kvoptions.ins, kvoptions.drv, +%% kvoptions-patch.sty, example-mycolorsetup.sty, +%% kvoptions-test1.tex, kvoptions-test2.tex, +%% kvoptions-test3.tex, kvoptions-test4.tex, +%% kvoptions-test4.sty. +%% +%% No we don't need the option 'color'. +%% With color support option 'emphcolor' will dynamically +%% change the color of \emph statements. +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode35=6 % # + \catcode39=12 % ' + \catcode44=12 % , + \catcode45=12 % - + \catcode46=12 % . + \catcode58=12 % : + \catcode64=11 % @ + \catcode123=1 % { + \catcode125=2 % } + \expandafter\let\expandafter\x\csname ver@kvoptions.sty\endcsname + \ifx\x\relax % plain-TeX, first loading + \else + \def\empty{}% + \ifx\x\empty % LaTeX, first loading, + % variable is initialized, but \ProvidesPackage not yet seen + \else + \expandafter\ifx\csname PackageInfo\endcsname\relax + \def\x#1#2{% + \immediate\write-1{Package #1 Info: #2.}% + }% + \else + \def\x#1#2{\PackageInfo{#1}{#2, stopped}}% + \fi + \x{kvoptions}{The package is already loaded}% + \aftergroup\endinput + \fi + \fi +\endgroup% +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode35=6 % # + \catcode39=12 % ' + \catcode40=12 % ( + \catcode41=12 % ) + \catcode44=12 % , + \catcode45=12 % - + \catcode46=12 % . + \catcode47=12 % / + \catcode58=12 % : + \catcode64=11 % @ + \catcode91=12 % [ + \catcode93=12 % ] + \catcode123=1 % { + \catcode125=2 % } + \expandafter\ifx\csname ProvidesPackage\endcsname\relax + \def\x#1#2#3[#4]{\endgroup + \immediate\write-1{Package: #3 #4}% + \xdef#1{#4}% + }% + \else + \def\x#1#2[#3]{\endgroup + #2[{#3}]% + \ifx#1\@undefined + \xdef#1{#3}% + \fi + \ifx#1\relax + \xdef#1{#3}% + \fi + }% + \fi +\expandafter\x\csname ver@kvoptions.sty\endcsname +\ProvidesPackage{kvoptions}% + [2019/11/29 v3.13 Key value format for package options (HO)]% +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode123=1 % { + \catcode125=2 % } + \catcode64=11 % @ + \def\x{\endgroup + \expandafter\edef\csname KVO@AtEnd\endcsname{% + \endlinechar=\the\endlinechar\relax + \catcode13=\the\catcode13\relax + \catcode32=\the\catcode32\relax + \catcode35=\the\catcode35\relax + \catcode61=\the\catcode61\relax + \catcode64=\the\catcode64\relax + \catcode123=\the\catcode123\relax + \catcode125=\the\catcode125\relax + }% + }% +\x\catcode61\catcode48\catcode32=10\relax% +\catcode13=5 % ^^M +\endlinechar=13 % +\catcode35=6 % # +\catcode64=11 % @ +\catcode123=1 % { +\catcode125=2 % } +\def\TMP@EnsureCode#1#2{% + \edef\KVO@AtEnd{% + \KVO@AtEnd + \catcode#1=\the\catcode#1\relax + }% + \catcode#1=#2\relax +} +\TMP@EnsureCode{1}{14}% ^^A (comment) +\TMP@EnsureCode{2}{14}% ^^A (comment) +\TMP@EnsureCode{33}{12}% ! +\TMP@EnsureCode{39}{12}% ' +\TMP@EnsureCode{40}{12}% ( +\TMP@EnsureCode{41}{12}% ) +\TMP@EnsureCode{42}{12}% * +\TMP@EnsureCode{44}{12}% , +\TMP@EnsureCode{45}{12}% - +\TMP@EnsureCode{46}{12}% . +\TMP@EnsureCode{47}{12}% / +\TMP@EnsureCode{58}{12}% : +\TMP@EnsureCode{62}{12}% > +\TMP@EnsureCode{91}{12}% [ +\TMP@EnsureCode{93}{12}% ] +\TMP@EnsureCode{94}{7}% ^ (superscript) +\TMP@EnsureCode{96}{12}% ` +\edef\KVO@AtEnd{\KVO@AtEnd\noexpand\endinput} +\@ifundefined{define@key}{% + \RequirePackage{keyval}\relax +}{} +\RequirePackage{ltxcmds}[2010/12/02] +\RequirePackage{kvsetkeys}[2007/09/29] +\@ifundefined{@x@protect}{% + \def\@x@protect#1\fi#2#3{% + \fi\protect#1% + }% + \let\@typeset@protect\relax +}{} +\@ifundefined{@currname}{% + \def\@currname{}% +}{} +\@ifundefined{@currext}{% + \def\@currext{}% +}{} +\DeclareOption{debugshow}{\catcode\@ne=9 } +\DeclareOption{patch}{% + \AtEndOfPackage{% + \RequirePackage{kvoptions-patch}[2019/11/29]% + }% +} +\ProcessOptions\relax +\define@key{KVO}{family}{% + \expandafter\edef\csname KVO@family@% + \@currname.\@currext\endcsname{#1}% +} +\def\KVO@family{% + \@ifundefined{KVO@family@\@currname.\@currext}{% + \@currname + }{% + \csname KVO@family@\@currname.\@currext\endcsname + }% +} +\define@key{KVO}{prefix}{% + \expandafter\edef\csname KVO@prefix@% + \@currname.\@currext\endcsname{#1}% +} +\def\KVO@prefix{% + \ltx@ifundefined{KVO@prefix@\@currname.\@currext}{% + \@currname @% + }{% + \csname KVO@prefix@\@currname.\@currext\endcsname + }% +} +\define@key{KVO}{setkeys}{% + \expandafter\def\csname KVO@setkeys@% + \@currname.\@currext\endcsname{#1}% +} +\def\KVO@setkeys{% + \ltx@IfUndefined{KVO@setkeys@\@currname.\@currext}{% + \setkeys + }{% + \csname KVO@setkeys@\@currname.\@currext\endcsname + }% +} +\newcommand*{\SetupKeyvalOptions}{% + \kvsetkeys{KVO}% +} +\newcommand*{\DeclareBoolOption}[2][false]{% + \KVO@ifdefinable{if\KVO@prefix#2}{% + \KVO@ifdefinable{\KVO@prefix#2true}{% + \KVO@ifdefinable{\KVO@prefix#2false}{% + \csname newif\expandafter\endcsname + \csname if\KVO@prefix#2\endcsname + \@ifundefined{\KVO@prefix#2#1}{% + \PackageWarning{kvoptions}{% + Initialization of option `#2' failed,\MessageBreak + cannot set boolean option to `#1',\MessageBreak + use `true' or `false', now using `false'% + }% + }{% + \csname\KVO@prefix#2#1\endcsname + }% + \begingroup + \edef\x{\endgroup + \noexpand\define@key{\KVO@family}{#2}[true]{% + \noexpand\KVO@boolkey{\@currname}% + \ifx\@currext\@clsextension + \noexpand\@clsextension + \else + \noexpand\@pkgextension + \fi + {\KVO@prefix}{#2}{####1}% + }% + }% + \x + }% + }% + }% +} +\newcommand*{\DeclareComplementaryOption}[2]{% + \@ifundefined{if\KVO@prefix#2}{% + \PackageError{kvoptions}{% + Cannot generate option code for `#1',\MessageBreak + parent switch `#2' does not exist% + }{% + You are inside % + \ifx\@currext\@clsextension class\else package\fi\space + `\@currname.\@currext'.\MessageBreak + `\KVO@family' is used as familiy % + for the keyval options.\MessageBreak + `\KVO@prefix' serves as prefix % + for internal switch macros.\MessageBreak + \MessageBreak + \@ehc + }% + }{% + \KVO@ifdefinable{\KVO@prefix#1true}{% + \KVO@ifdefinable{\KVO@prefix#1false}{% + \expandafter\let\csname\KVO@prefix#1false\expandafter\endcsname + \csname\KVO@prefix#2true\endcsname + \expandafter\let\csname\KVO@prefix#1true\expandafter\endcsname + \csname\KVO@prefix#2false\endcsname + \begingroup + \edef\x{\endgroup + \noexpand\define@key{\KVO@family}{#1}[true]{% + \noexpand\KVO@boolkey{\@currname}% + \ifx\@currext\@clsextension + \noexpand\@clsextension + \else + \noexpand\@pkgextension + \fi + {\KVO@prefix}{#1}{####1}% + }% + }% + \x + }% + }% + }% +} +\def\KVO@ifdefinable#1{% + \expandafter\@ifdefinable\csname #1\endcsname +} +\def\KVO@boolkey#1#2#3#4#5{% + \edef\KVO@param{#5}% + \ltx@onelevel@sanitize\KVO@param + \ifx\KVO@param\KVO@true + \expandafter\@firstofone + \else + \ifx\KVO@param\KVO@false + \expandafter\expandafter\expandafter\@firstofone + \else + \ifx#2\@clsextension + \expandafter\ClassWarning + \else + \expandafter\PackageWarning + \fi + {#1}{% + Value `\KVO@param' is not supported by\MessageBreak + option `#4'% + }% + \expandafter\expandafter\expandafter\@gobble + \fi + \fi + {% + ^^A\ifx#2\@clsextension + ^^A \expandafter\ClassInfo + ^^A\else + ^^A \expandafter\PackageInfo + ^^A\fi + ^^A{#1}{[option] #4=\KVO@param}% + \csname#3#4\KVO@param\endcsname + }% +} +\def\KVO@true{true} +\def\KVO@false{false} +\ltx@onelevel@sanitize\KVO@true +\ltx@onelevel@sanitize\KVO@false +\newcommand*{\DeclareStringOption}[2][]{% + \@ifnextchar[{% + \KVO@DeclareStringOption{#1}{#2}@% + }{% + \KVO@DeclareStringOption{#1}{#2}{}[]% + }% +} +\def\KVO@DeclareStringOption#1#2#3[#4]{% + \KVO@ifdefinable{\KVO@prefix#2}{% + \@namedef{\KVO@prefix#2}{#1}% + \begingroup + \ifx\\#3\\% + \toks@{}% + \else + \toks@{[{#4}]}% + \fi + \edef\x{\endgroup + \noexpand\define@key{\KVO@family}{#2}\the\toks@{% + ^^A\begingroup + ^^A \toks@{####1}% + ^^A \ifx\@currext\@clsextension + ^^A \noexpand\ClassInfo + ^^A \else + ^^A \noexpand\PackageInfo + ^^A \fi + ^^A {\@currname}{% + ^^A [option] #2={\noexpand\the\toks@}% + ^^A }% + ^^A\endgroup + \noexpand\def + \expandafter\noexpand\csname\KVO@prefix#2\endcsname{####1}% + }% + }% + \x + }% +} +\newcommand*{\DeclareVoidOption}[2]{% + \begingroup + \let\next\@gobbletwo + \KVO@ifdefinable{\KVO@prefix#1}{% + \let\next\@firstofone + }% + \expandafter\endgroup + \next{% + \begingroup + \edef\x{\endgroup + \noexpand\define@key{\KVO@family}{#1}[\KVO@VOID@]{% + \noexpand\KVO@voidkey{\@currname}% + \ifx\@currext\@clsextension + \noexpand\@clsextension + \else + \noexpand\@pkgextension + \fi + {#1}% + {####1}% + \expandafter\noexpand\csname\KVO@prefix#1\endcsname + }% + }% + \x + \begingroup + \toks@{#2}% + \expandafter\endgroup + \expandafter\def + \csname\KVO@prefix#1\expandafter\endcsname + \expandafter{\the\toks@}% + }% +} +\def\KVO@VOID@{@VOID@} +\def\KVO@voidkey#1#2#3#4{% + \def\CurrentOption{#3}% + \begingroup + \def\x{#4}% + \expandafter\endgroup + \ifx\x\KVO@VOID@ + \else + \ifx#2\@clsextension + \expandafter\ClassWarning + \else + \expandafter\PackageWarning + \fi + {#1}{% + Unexpected value for option `#3'\MessageBreak + is ignored% + }% + \fi + ^^A\ifx#2\@clsextension + ^^A \expandafter\ClassInfo + ^^A\else + ^^A \expandafter\PackageInfo + ^^A\fi + ^^A{#1}{[option] #3}% +} +\newcommand*{\DeclareDefaultOption}{% + \@namedef{KVO@default@\@currname.\@currext}% +} +\newcommand*{\DeclareLocalOptions}[1]{% + \comma@parse{#1}\KVO@DeclareLocalOption +} +\def\KVO@DeclareLocalOption#1{% + \expandafter\def\csname KVO@local@\KVO@family @#1\endcsname{}% +} +\SetupKeyvalOptions{% + family=KVOdyn,% + prefix=KVOdyn@% +} +\DeclareBoolOption[true]{global} +\DeclareComplementaryOption{local}{global} +\DeclareStringOption[undef]{action} +\let\KVOdyn@name\relax +\let\KVOdyn@ext\@empty +\define@key{KVOdyn}{class}{% + \def\KVOdyn@name{#1}% + \let\KVOdyn@ext\@clsextension +} +\define@key{KVOdyn}{package}{% + \def\KVOdyn@name{#1}% + \let\KVOdyn@ext\@pkgextension +} +\newcommand*{\DisableKeyvalOption}[3][]{% + \begingroup + \kvsetkeys{KVOdyn}{#1}% + \def\x{\endgroup}% + \@ifundefined{KVO@action@\KVOdyn@action}{% + \PackageError{kvoptions}{% + Unknown disable action % + `\expandafter\strip@prefix\meaning\KVOdyn@action'\MessageBreak + for option `#3' in keyval family '#2'% + }\@ehc + }{% + \csname KVO@action@\KVOdyn@action\endcsname{#2}{#3}% + }% + \x +} +\def\KVO@action@undef#1#2{% + \edef\x{\endgroup + \ifKVOdyn@global\global\fi + \let + \expandafter\noexpand\csname KV@#1@#2\endcsname + \relax + \ifKVOdyn@global\global\fi + \let + \expandafter\noexpand\csname KV@#1@#2@default\endcsname + \relax + }% + ^^A\PackageInfo{kvoptions}{% + ^^A [option] key `#2' of family `#1'\MessageBreak + ^^A is disabled (undef, \ifKVOdyn@global global\else local\fi)% + ^^A}% +} +\def\KVO@action@ignore#1#2{% + \edef\x{\endgroup + \ifKVOdyn@global\global\fi + \let + \expandafter\noexpand\csname KV@#1@#2\endcsname + \noexpand\@gobble + \ifKVOdyn@global\global\fi + \let + \expandafter\noexpand\csname KV@#1@#2@default\endcsname + \noexpand\@empty + }% + ^^A\PackageInfo{kvoptions}{% + ^^A [option] key `#2' of family `#1'\MessageBreak + ^^A is disabled (ignore, \ifKVOdyn@global global\else local\fi)% + ^^A}% +} +\def\KVO@action@error{% + \KVO@do@action{error}% +} +\def\KVO@action@warning{% + \KVO@do@action{warning}% +} +\def\KVO@do@action#1#2#3{% + \ifx\KVOdyn@name\relax + \PackageError{kvoptions}{% + Action type `#1' needs package/class name\MessageBreak + for key `#3' in family `#2'% + }\@ehc + \else + \edef\x{\endgroup + \noexpand\define@key{#2}{#3}[]{% + \expandafter\noexpand\csname KVO@disable@#1\endcsname + {\KVOdyn@name}\noexpand\KVOdyn@ext{#3}% + }% + \ifKVOdyn@global + \global\let + \expandafter\noexpand\csname KV@#2@#3\endcsname + \expandafter\noexpand\csname KV@#2@#3\endcsname + \global\let + \expandafter\noexpand\csname KV@#2@#3@default\endcsname + \expandafter\noexpand\csname KV@#2@#3@default\endcsname + \fi + }% + ^^A\ifx\KVOdyn@ext\@clsextension + ^^A \expandafter\ClassInfo + ^^A\else + ^^A \expandafter\PackageInfo + ^^A\fi + ^^A{\KVOdyn@name}{% + ^^A [option] key `#3' of family `#2'\MessageBreak + ^^A is disabled (#1, \ifKVOdyn@global global\else local\fi)% + ^^A}% + \fi +} +\def\KVO@disable@error#1#2#3{% + \ifx#2\@clsextension + \expandafter\ClassError + \else + \expandafter\PackageError + \fi + {#1}{% + Option `#3' is given too late,\MessageBreak + now the option is ignored% + }\@ehc +} +\def\KVO@disable@warning#1#2#3{% + \ifx#2\@clsextension + \expandafter\ClassWarning + \else + \expandafter\PackageWarning + \fi + {#1}{% + Option `#3' is already consumed\MessageBreak + and has no effect% + }% +} +\newcommand*{\AddToKeyvalOption}{% + \@ifstar{% + \begingroup + \edef\x{\endgroup + \noexpand\KVO@AddToKeyvalOption{\KVO@family}% + }% + \x + }% + \KVO@AddToKeyvalOption +} +\def\KVO@AddToKeyvalOption#1#2{% + \@ifundefined{KV@#1@#2}{% + \PackageWarning{kvoptions}{% + Key `#2' of family `#1' does not exist.\MessageBreak + Ignoring \string\AddToKeyvalOption + }% + \@gobble + }{% + \edef\KVO@next{% + \noexpand\KVO@@AddToKeyvalOption + \expandafter\noexpand\csname KV@#1@#2\endcsname + }% + \afterassignment\KVO@next + \def\KVO@temp##1% + }% +} +\def\KVO@@AddToKeyvalOption#1{% + \begingroup + \toks@\expandafter{#1{##1}}% + \toks@\expandafter{\the\expandafter\toks@\KVO@temp{##1}}% + \edef\x{\endgroup + \noexpand\def\noexpand#1####1{\the\toks@}% + }% + \x +} +\def\KVO@IfDefThen#1#2{% + \ifx#1\ltx@undefined + \else + \ifx#1\relax + \else + #2% + \fi + \fi +}% +\def\KVO@GetClassOptionsList{% + \let\KVO@classoptionslist\@classoptionslist + \KVO@IfDefThen\@classoptionslist{% + \KVO@IfDefThen\XKV@documentclass{% + \ifx\XKV@documentclass\ltx@empty + \else + \KVO@IfDefThen\XKV@classoptionslist{% + \ifx\XKV@classoptionslist\ltx@empty + \else + \let\KVO@classoptionslist\XKV@classoptionslist + \fi + }% + \fi + }% + }% +}% +\newcommand*{\ProcessKeyvalOptions}{% + \@ifstar{% + \begingroup + \edef\x{\endgroup + \noexpand\KVO@ProcessKeyvalOptions{\KVO@family}% + }% + \x + }% + \KVO@ProcessKeyvalOptions +} +\def\KVO@ProcessKeyvalOptions#1{% + \let\@tempc\relax + \let\KVO@temp\@empty + \ifx\@currext\@clsextension + \else + \KVO@GetClassOptionsList + \ifx\KVO@classoptionslist\relax + \else + \@for\KVO@CurrentOption:=\KVO@classoptionslist\do{% + \@ifundefined{KV@#1@\expandafter\KVO@getkey + \KVO@CurrentOption=\@nil}{% + }{% + \@ifundefined{KVO@local@#1@\expandafter\KVO@getkey + \KVO@CurrentOption=\@nil}{% + \ifx\KVO@Patch Y% + \edef\KVO@temp{% + \etex@unexpanded\expandafter{% + \KVO@temp + }% + ,% + \etex@unexpanded\expandafter{% + \KVO@CurrentOption + }% + ,% + }% + \ltx@onelevel@sanitize\KVO@CurrentOption + \else + \edef\KVO@temp{% + \KVO@temp + ,% + \KVO@CurrentOption + ,% + }% + \fi + \@expandtwoargs\@removeelement\KVO@CurrentOption + \@unusedoptionlist\@unusedoptionlist + }{}% + }% + }% + \fi + \fi + \begingroup + \toks\tw@{}% + \@ifundefined{opt@\@currname.\@currext}{% + \toks@\expandafter{\KVO@temp}% + }{% + \toks@\expandafter\expandafter\expandafter{% + \csname opt@\@currname.\@currext\endcsname + }% + \ifx\@currext\@clsextension + \edef\CurrentOption{\the\toks@}% + \toks@\expandafter{\KVO@temp}% + \@for\CurrentOption:=\CurrentOption\do{% + \@ifundefined{% + KV@#1@\expandafter\KVO@getkey\CurrentOption=\@nil + }{% + \@ifundefined{KVO@default@\@currname.\@currext}{% + \ifx\KVO@Patch Y% + \ltx@onelevel@sanitize\CurrentOption + \fi + \ifx\@unusedoptionlist\@empty + \global\let\@unusedoptionlist\CurrentOption + \else + \expandafter\expandafter\expandafter\gdef + \expandafter\expandafter\expandafter\@unusedoptionlist + \expandafter\expandafter\expandafter{% + \expandafter\@unusedoptionlist + \expandafter,\CurrentOption + }% + \fi + }{% + \toks\tw@\expandafter{% + \the\toks\expandafter\tw@\expandafter,\CurrentOption + }% + }% + }{% + \toks@\expandafter{% + \the\expandafter\toks@\expandafter,\CurrentOption + }% + }% + }% + \else + \@ifundefined{KVO@default@\@currname.\@currext}{% + \toks@\expandafter\expandafter\expandafter{% + \expandafter\KVO@temp\the\toks@ + }% + }{% + \edef\CurrentOption{\the\toks@}% + \toks@\expandafter{\KVO@temp}% + \@for\CurrentOption:=\CurrentOption\do{% + \@ifundefined{% + KV@#1@\expandafter\KVO@getkey\CurrentOption=\@nil + }{% + \toks\tw@\expandafter{% + \the\toks\expandafter\tw@\expandafter,\CurrentOption + }% + }{% + \toks@\expandafter{% + \the\expandafter\toks@\expandafter,\CurrentOption + }% + }% + }% + }% + \fi + }% + \edef\KVO@temp{\endgroup + \noexpand\KVO@calldefault{\the\toks\tw@}% + \noexpand\KVO@setkeys{#1}{\the\toks@}% + }% + \KVO@temp + \let\CurrentOption\@empty + \AtEndOfPackage{\let\@unprocessedoptions\relax}% +} +\newcommand*{\ProcessLocalKeyvalOptions}{% + \@ifstar{% + \begingroup + \edef\x{\endgroup + \noexpand\KVO@ProcessLocalKeyvalOptions{\KVO@family}% + }% + \x + }% + \KVO@ProcessLocalKeyvalOptions +} +\def\KVO@ProcessLocalKeyvalOptions#1{% + \let\@tempc\relax + \let\KVO@temp\@empty + \ifx\@currext\@pkgextension + \else + \PackageError{kvoptions}{% + \string\ProcessLocalKeyvalOptions\space is intended for packages only% + }\@ehc + \fi + \begingroup + \toks\tw@{}% + \@ifundefined{opt@\@currname.\@currext}{% + \toks@\expandafter{\KVO@temp}% + }{% + \toks@\expandafter\expandafter\expandafter{% + \csname opt@\@currname.\@currext\endcsname + }% + \@ifundefined{KVO@default@\@currname.\@currext}{% + \toks@\expandafter\expandafter\expandafter{% + \expandafter\KVO@temp\the\toks@ + }% + }{% + \edef\CurrentOption{\the\toks@}% + \toks@\expandafter{\KVO@temp}% + \@for\CurrentOption:=\CurrentOption\do{% + \@ifundefined{% + KV@#1@\expandafter\KVO@getkey\CurrentOption=\@nil + }{% + \toks\tw@\expandafter{% + \the\toks\expandafter\tw@\expandafter,\CurrentOption + }% + }{% + \toks@\expandafter{% + \the\expandafter\toks@\expandafter,\CurrentOption + }% + }% + }% + }% + }% + \edef\KVO@temp{\endgroup + \noexpand\KVO@calldefault{\the\toks\tw@}% + \noexpand\KVO@setkeys{#1}{\the\toks@}% + }% + \KVO@temp + \let\CurrentOption\@empty + \AtEndOfPackage{\let\@unprocessedoptions\relax}% +} +\def\KVO@getkey#1=#2\@nil{#1} +\def\KVO@calldefault#1{% + \begingroup + \def\x{#1}% + \expandafter\endgroup + \ifx\x\@empty + \else + \@for\CurrentOption:=#1\do{% + \ifx\CurrentOption\@empty + \else + \expandafter\KVO@setcurrents\CurrentOption=\@nil + \@nameuse{KVO@default@\@currname.\@currext}% + \fi + }% + \fi +} +\def\KVO@setcurrents#1=#2\@nil{% + \def\CurrentOptionValue{#2}% + \ifx\CurrentOptionValue\@empty + \let\CurrentOptionKey\CurrentOption + \let\CurrentOptionValue\relax + \else + \edef\CurrentOptionKey{\zap@space#1 \@empty}% + \expandafter\KVO@setcurrentvalue\CurrentOption\@nil + \fi +} +\def\KVO@setcurrentvalue#1=#2\@nil{% + \KV@@sp@def\CurrentOptionValue{#2}% +} +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname documentclass\endcsname\relax + \def\ProcessKeyvalOptions{% + \@ifstar{}\@gobble + }% +\fi +\KVO@AtEnd% +\endinput +%% +%% End of file `kvoptions.sty'. diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index a566e8916c5..82ff1a1f1bc 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -384,7 +384,7 @@ my @TLP_working = qw( koma-moderncvclassic koma-script koma-script-examples koma-script-sfs komacv komacv-rg kotex-oblivoir kotex-plain kotex-utf kotex-utils kpfonts ksfh_nat ksp-thesis - ktv-texdata ku-template kurdishlipsum kurier kvmap + ktv-texdata ku-template kurdishlipsum kurier kvmap kvoptions l2picfaq l2tabu l2tabu-english l2tabu-french l2tabu-italian l2tabu-spanish l3backend l3build l3kernel l3packages l3experimental labbook labels labels4easylist labelschanged diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc index 318963ba206..ea8f464a4b9 100644 --- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc @@ -626,6 +626,7 @@ depend koma-script-sfs depend komacv depend komacv-rg depend ktv-texdata +depend kvoptions depend l3build depend labbook depend labels diff --git a/Master/tlpkg/tlpsrc/kvoptions.tlpsrc b/Master/tlpkg/tlpsrc/kvoptions.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/kvoptions.tlpsrc |