diff options
author | Karl Berry <karl@freefriends.org> | 2006-08-14 00:00:58 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-08-14 00:00:58 +0000 |
commit | f68c66c2fd38fcd1146a01bbe28f58ed0efc6f79 (patch) | |
tree | 6c52bf9ca94926efe01ce319c811ec0379eef72f /Master/texmf-dist/source/latex/oberdiek | |
parent | 42bc6d37351f5002d650f9a782eeb7972c7a1703 (diff) |
oberdiek update to get kvoptions 2.2 (2aug06)
git-svn-id: svn://tug.org/texlive/trunk@1948 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/oberdiek')
-rw-r--r-- | Master/texmf-dist/source/latex/oberdiek/kvoptions.dtx | 2293 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/oberdiek/refcount.dtx | 548 |
2 files changed, 2841 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/oberdiek/kvoptions.dtx b/Master/texmf-dist/source/latex/oberdiek/kvoptions.dtx new file mode 100644 index 00000000000..66bfb7f615c --- /dev/null +++ b/Master/texmf-dist/source/latex/oberdiek/kvoptions.dtx @@ -0,0 +1,2293 @@ +% \iffalse meta-comment +% +% Copyright (C) 2004, 2006 by Heiko Oberdiek <oberdiek@uni-freiburg.de> +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 of this license or (at your option) any later +% version. The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of +% LaTeX version 2003/12/01 or later. +% +% This work has the LPPL maintenance status "maintained". +% +% This Current Maintainer of this work is Heiko Oberdiek. +% +% This work consists of the main source file kvoptions.dtx +% and the derived files +% kvoptions.sty, kvoptions.pdf, kvoptions.ins, kvoptions.drv, +% example-mycolorsetup.sty. +% +% Distribution: +% CTAN:macros/latex/contrib/oberdiek/kvoptions.dtx +% CTAN:macros/latex/contrib/oberdiek/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 \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/oberdiek/kvoptions.sty +% TDS:doc/latex/oberdiek/kvoptions.pdf +% TDS:doc/latex/oberdiek/example-mycolorsetup.sty +% TDS:source/latex/oberdiek/kvoptions.dtx +% +%<*ignore> +\begingroup + \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 2006/06/01 v2.2 Connects package keyval with LaTeX options (HO)} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\preamble + +This is a generated file. + +Copyright (C) 2004, 2006 by Heiko Oberdiek <oberdiek@uni-freiburg.de> + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in + http://www.latex-project.org/lppl.txt +and version 1.3 or later is part of all distributions of +LaTeX version 2003/12/01 or later. + +This work has the LPPL maintenance status "maintained". + +This Current Maintainer of this work is Heiko Oberdiek. + +This work consists of the main source file kvoptions.dtx +and the derived files + kvoptions.sty, kvoptions.pdf, kvoptions.ins, kvoptions.drv, + example-mycolorsetup.sty. + +\endpreamble + +\generate{% + \file{kvoptions.ins}{\from{kvoptions.dtx}{install}}% + \file{kvoptions.drv}{\from{kvoptions.dtx}{driver}}% + \usedir{tex/latex/oberdiek}% + \file{kvoptions.sty}{\from{kvoptions.dtx}{package}}% + \usedir{doc/latex/oberdiek}% + \file{example-mycolorsetup.sty}{\from{kvoptions.dtx}{example}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* kvoptions.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}% + [2006/06/01 v2.2 Connects package keyval with LaTeX options (HO)] +\documentclass{ltxdoc} +\usepackage{holtxdoc} +\begin{document} + \DocInput{kvoptions.dtx} +\end{document} +%</driver> +% \fi +% +% \CheckSum{1488} +% +% \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{2006/06/01 v2.2} +% \author{Heiko Oberdiek\\\xemail{oberdiek@uni-freiburg.de}} +% +% \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} +% +% \subsection{The beginning} +% +% This package 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{DeclareBooleanOption}\\ +% \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. +% +% Note, neither of the following commands 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}\\ +% \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{DeclareBooleanOption} \\ +% &&& \cs{DeclareStringOption} \\ +% \hline +% \rule{0pt}{1.2\ht\csname @arstrutbox\endcsname}^^A +% |prefix| & \meta{\cs{\@currname}}|@| & (|foobar@|) +% & \cs{DeclareBooleanOption} \\ +% &&& \cs{DeclareStringOption} \\ +% &&& \cs{DeclareVoidOption} +% \end{tabular} +% \end{quote} +% +% \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} +% |\ProvidedPackage{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{DeclareBooleanOption}} +% +% \begin{declcs}{DeclareBooleanOption}\,\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{DeclareBooleanOption} 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}|\\ +% |\DeclareBooleanOption{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{final} +% vs.\@ \xoption{final}. Both options behave like boolean +% options but they do not need to different switches, they +% should share one. \cs{DeclareComplementaryOption} allows this. +% The option \meta{key} shares the switch of option \meta{parent}. +% Example: +% \begin{quote} +% |\DeclareBooleanOption{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} +% This command does not define a 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. +% During the execution of \meta{code} +% \cs{CurrentOption} contains the current option string. +% Additionally \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. +% +% 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{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} 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{DisableKeyvalOptions} +% can be executed everywhere, also outside the package. Therefore +% the family name and the package/class name is usually unknown for +% \cs{DisableKeyvalOptions}. 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} +%\DeclareBooleanOption{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} +% +% \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{quote} +% \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{DeclareBooleanOption} +% & \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{quote} +% +% \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}[2006/06/01 Managing my colors] + +\RequirePackage{ifpdf} +\RequirePackage{kvoptions} + + % Option declarations + % ------------------- + +\SetupKeyvalOptions{ + family=MCS, + prefix=MCS@ +} + % Use a shorter family name and prefix + + % Option print +\DeclareBooleanOption{print} + % is the same as + % \DeclareBooleanOption[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. +% +% \subsection{Option \xoption{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 option \xoption{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[patch]{kvoptions}|\\ +% |\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[patch]{kvoptions}|\\ +% |\usepackage[Fran\c coise M\"uller]{hyperref}| +% \end{quote} +% Some remarks: +% \begin{itemize} +% \item The patch and requires \eTeX, its \cs{unexpanded} feature +% is much to 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. +% \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{DeclareBooleanOption} 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{Option \xoption{patch} vs. package \xpackage{xkvltxp}} +% +% Package \xpackage{xkvltxp} from the \xpackage{xkeyval} project +% has the same goal as \xpackage{kvoptions}'s +% option \xoption{patch} and patches \LaTeX's kernel commands. +% Of course they cannot be used both. The user must decide, which +% method he prefers. Package \xpackage{kvoptions} drops option +% \xoption{patch} if it detects that \xpackage{xkvltxp} is +% already loaded. +% +% However both \emph{packages} 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} 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[patch]{kvoptions} +%\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 options, e.g. option clash check, +% \cs{@ifpackagewith}, \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 option \xoption{patch}} +% +% With option \xoption{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[patch]{kvoptions}|\\ +% |\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} +% \paragraph{Package identification.} +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{kvoptions} + [2006/06/01 v2.2 Connects package keyval with LaTeX options (HO)] +% \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} +\RequirePackage{keyval} +% \end{macrocode} +% +% \paragraph{Options} +% Option \xoption{debugshow} enables additional lines of +% code that prints information into the \xfile{.log} +% file. +% \begin{macrocode} +\begingroup + \edef\x{\endgroup + \noexpand\AtEndOfPackage{% + \catcode\@ne=\the\catcode\@ne\relax + \catcode\tw@=\the\catcode\tw@\relax + }% + }% +\x +\catcode\@ne=14 % +\catcode\tw@=14 % +\DeclareOption{debugshow}{\catcode\@ne=9 } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareOption{patch}{\catcode\tw@=9 } +% \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, declared by \cs{DeclareBooleanOption} +% 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{% + \@ifundefined{KVO@prefix@\@currname.\@currext}{% + \@currname @% + }{% + \csname KVO@prefix@\@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}{% + \setkeys{KVO}% +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\cs{DeclareBooleanOption}} +% +% \begin{macro}{\DeclareBooleanOption} +% 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*{\DeclareBooleanOption}[2][false]{% + \KVO@ifdefinable{if\KVO@prefix#2}{% + \KVO@ifdefinable{\KVO@prefix#2true}{% + \KVO@ifdefinable{\KVO@prefix#2false}{% + \expandafter\newif\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{DeclareBooleanOption} 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}% + \@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{@onelevel@sanitize} +% we have only tokens with catcode 12 (other). +% \begin{macrocode} +\def\KVO@true{true} +\def\KVO@false{false} +\@onelevel@sanitize\KVO@true +\@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}[1]{% + \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 + \@namedef{\KVO@prefix#1}% + }% +} +\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} +% +% \subsection{Dynamic options} +% +% \subsubsection{\cs{DisableKeyvalOption}} +% +% \begin{macrocode} +\SetupKeyvalOptions{% + family=KVOdyn,% + prefix=KVOdyn@% +} +\DeclareBooleanOption[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 + \setkeys{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 + \@gobble + \ifKVOdyn@global\global\fi + \let + \expandafter\noexpand\csname KV@#1@#2@default\endcsname + \@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{Process options} +% +% \subsection{\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 + \ifx\@classoptionslist\relax + \else + \@for\KVO@CurrentOption:=\@classoptionslist\do{% + \@ifundefined{KV@#1@\expandafter\KVO@getkey\KVO@CurrentOption=\@nil}{% + }{% + \edef\KVO@temp{% +^^B \unexpanded\expandafter{% + \KVO@temp +^^B }% + ,% +^^B \unexpanded\expandafter{% + \KVO@CurrentOption +^^B }% + ,% + }% +^^B \@onelevel@sanitize\KVO@CurrentOption + \@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. +% \begin{macrocode} +^^B \@onelevel@sanitize\CurrentOption + \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@\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\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{Patch} +% +% Caution: docstrip stops at \cs{endinput} at begin of line! +% \begin{macrocode} +^^B\@gobble + \endinput +\PackageInfo{kvoptions}{Patching LaTeX's option system} +% \end{macrocode} +% +% Check for \eTeX. +% \begin{macrocode} +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname eTeXversion\endcsname\relax + \PackageWarningNoLine{kvoptions}{% + Option `patch' ignored, because e-TeX is missing% + }% + \expandafter\endinput +\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 option `patch' will be ignored% + }% + \endinput +}{} +% \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 + \toks@\expandafter{\@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 + \@for\CurrentOption:=\@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} +% +% \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{% + \unexpanded\expandafter{\KVO@result},\KVO@x + }% + \fi + }{% + % #1: "key", #2: "value=" + % add key part + \edef\KVO@result{% + \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{% + \unexpanded\expandafter{\KVO@result}% + \unexpanded\expandafter{\KVO@removegarbage#1\KVO@nil}% + }% + }{% + \edef\KVO@result{% + \unexpanded\expandafter{\KVO@result}% + \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{macrocode} +%</package> +% \end{macrocode} +% \section{Installation} +% +% \paragraph{CTAN.} This package is available on +% CTAN\footnote{\url{ftp://ftp.ctan.org/tex-archive/}}: +% \begin{description} +% \item[\CTAN{macros/latex/contrib/oberdiek/kvoptions.dtx}] The source file. +% \item[\CTAN{macros/latex/contrib/oberdiek/kvoptions.pdf}] Documentation. +% \end{description} +% +% \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} +% \sbox0{^^A +% \begin{tabular}{@{}>{\ttfamily}l@{$\quad\rightarrow\quad$}>{\ttfamily}l@{}} +% kvoptions.sty & tex/latex/oberdiek/kvoptions.sty\\ +% kvoptions.pdf & doc/latex/oberdiek/kvoptions.pdf\\ +% example-mycolorsetup.sty & doc/latex/oberdiek/example-mycolorsetup.sty\\ +% kvoptions.dtx & source/latex/oberdiek/kvoptions.dtx\\ +% \end{tabular}^^A +% }% +% \ifdim\wd0>\linewidth +% \mbox{}\nobreak\hskip0pt minus\leftmargin +% \usebox0 +% \nobreak\hskip0pt minus\rightmargin +% \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. +% +% \paragraph{Refresh file databases.} If your \TeX~distribution +% (\teTeX, \mikTeX, \dots) rely on file databases, you must refresh +% these. For example, \teTeX\ users run \verb|texhash| or +% \verb|mktexlsr|. +% +% Now the installation is complete. +% +% \subsection{Some details for the interested} +% +% \paragraph{Attached source.} +% +% The PDF documentation on CTAN also includes the +% \xfile{.dtx} source file. It can be extracted by +% AcrobatReader 6 or higher. Another option is \textsf{pdftk}, +% e.g. unpack the file into the current directory: +% \begin{quote} +% \verb|pdftk kvoptions.pdf unpack_files output .| +% \end{quote} +% +% \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 intension: +% \begin{quote} +% \verb|latex \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} +% +% \newcommand*{\bibpackage}[4]{^^A +% \bibitem{#1} +% Package \xpackage{#1}, #2, #3.^^A +% \ifx\\#4\\\else#4\fi\par +% } +% +% \begin{thebibliography}{99} +% \bibpackage{ifthen}{David Carlisle}{2001/05/26} +% {\CTAN{macros/latex/base/ifthen.dtx}} +% \bibpackage{helvet}{Sebastian Rahtz, Walter Schmidt}{2004/01/26} +% {\CTAN{macros/latex/required/psnfss/psfonts.dtx}} +% \bibpackage{hyperref}{Sebastian Rahtz, Heiko Oberdiek}{2006/02/12} +% {\CTAN{macros/latex/contrib/hyperref/}} +% \bibpackage{keyval}{David Carlisle}{1999/03/16} +% {\CTAN{macros/latex/required/graphics/keyval.dtx}} +% \bibpackage{multicol}{Frank Mittelbach}{2004/02/14} +% {\CTAN{macros/latex/required/tools/multicol.dtx}} +% \bibpackage{tabularx}{David Carlisle}{1999/01/07} +% {\CTAN{macros/latex/required/tools/tabularx.dtx}} +% \bibpackage{tracefnt}{Frank Mittelbach, Rainer Sch\"opf}{1997/05/29} +% {\CTAN{macros/latex/base/ltfsstrc.dtx}} +% \bibpackage{xkeyval}{Hendri Adriaens}{2005/05/07} +% {\CTAN{macros/latex/contrib/xkeyval/}} +% \bibitem{clsguide} +% The \LaTeX3 Project, \textit{\LaTeXe\ for class and package writers}, +% 2003/12/09. +% \CTAN{macros/latex/doc/clsguide.pdf} +% +% \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} +% \end{History} +% +% \PrintIndex +% +% \Finale +\endinput diff --git a/Master/texmf-dist/source/latex/oberdiek/refcount.dtx b/Master/texmf-dist/source/latex/oberdiek/refcount.dtx new file mode 100644 index 00000000000..5a2fcbf7fef --- /dev/null +++ b/Master/texmf-dist/source/latex/oberdiek/refcount.dtx @@ -0,0 +1,548 @@ +% \iffalse meta-comment +% +% Copyright (C) 1998, 2000, 2006 by +% Heiko Oberdiek <oberdiek@uni-freiburg.de> +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 of this license or (at your option) any later +% version. The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of +% LaTeX version 2003/12/01 or later. +% +% This work has the LPPL maintenance status "maintained". +% +% This Current Maintainer of this work is Heiko Oberdiek. +% +% This work consists of the main source file refcount.dtx +% and the derived files +% refcount.sty, refcount.pdf, refcount.ins, refcount.drv. +% +% Distribution: +% CTAN:macros/latex/contrib/oberdiek/refcount.dtx +% CTAN:macros/latex/contrib/oberdiek/refcount.pdf +% +% Unpacking: +% (a) If refcount.ins is present: +% tex refcount.ins +% (b) Without refcount.ins: +% tex refcount.dtx +% (c) If you insist on using LaTeX +% latex \install=y\input{refcount.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% (a) If refcount.drv is present: +% latex refcount.drv +% (b) Without refcount.drv: +% latex refcount.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 refcount.dtx +% makeindex -s gind.ist refcount.idx +% pdflatex refcount.dtx +% makeindex -s gind.ist refcount.idx +% pdflatex refcount.dtx +% +% Installation: +% TDS:tex/latex/oberdiek/refcount.sty +% TDS:doc/latex/oberdiek/refcount.pdf +% TDS:source/latex/oberdiek/refcount.dtx +% +%<*ignore> +\begingroup + \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: refcount 2006/02/20 v3.0 Data extraction from references (HO)} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\preamble + +This is a generated file. + +Copyright (C) 1998, 2000, 2006 by + Heiko Oberdiek <oberdiek@uni-freiburg.de> + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in + http://www.latex-project.org/lppl.txt +and version 1.3 or later is part of all distributions of +LaTeX version 2003/12/01 or later. + +This work has the LPPL maintenance status "maintained". + +This Current Maintainer of this work is Heiko Oberdiek. + +This work consists of the main source file refcount.dtx +and the derived files + refcount.sty, refcount.pdf, refcount.ins, refcount.drv. + +\endpreamble + +\generate{% + \file{refcount.ins}{\from{refcount.dtx}{install}}% + \file{refcount.drv}{\from{refcount.dtx}{driver}}% + \usedir{tex/latex/oberdiek}% + \file{refcount.sty}{\from{refcount.dtx}{package}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* refcount.sty} +\Msg{*} +\Msg{* To produce the documentation run the file `refcount.drv'} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +%</install> +%<*ignore> +\fi +%</ignore> +%<*driver> +\NeedsTeXFormat{LaTeX2e} +\ProvidesFile{refcount.drv}% + [2006/02/20 v3.0 Data extraction from references (HO)] +\documentclass{ltxdoc} +\usepackage{holtxdoc} +\begin{document} + \DocInput{refcount.dtx} +\end{document} +%</driver> +% \fi +% +% \CheckSum{198} +% +% \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{refcount.drv} +% +% \title{The \xpackage{refcount} package} +% \date{2006/02/20 v3.0} +% \author{Heiko Oberdiek\\\xemail{oberdiek@uni-freiburg.de}} +% +% \maketitle +% +% \begin{abstract} +% References are not numbers, however they often store numerical +% data such as section or page numbers. \cs{ref} or \cs{pageref} +% cannot be used for counter assignments or calculations because +% they are not expandable, generate warnings, or can even be links, +% The package provides expandable macros to extract the data +% from references. Packages \xpackage{hyperref}, \xpackage{nameref}, +% \xpackage{titleref}, and \xpackage{babel} are supported. +% \end{abstract} +% +% \tableofcontents +% +% \section{Usage} +% +% \subsection{Setting counters} +% +% The following commands are similar to \LaTeX's +% \cs{setcounter} and \cs{addtocounter}, +% but they extract the number value from a reference: +% \begin{quote} +% \cs{setcounterref}, \cs{addtocounterref}\\ +% \cs{setcounterpageref}, \cs{addtocounterpageref} +% \end{quote} +% They take two arguments: +% \begin{quote} +% \cs{...counter...ref} |{|\meta{\LaTeX\ counter}|}| +% |{|\meta{reference}|}| +% \end{quote} +% An undefined references produces the usual LaTeX warning +% and its value is assumed to be zero. +% Example: +% \begin{quote} +%\begin{verbatim} +%\newcounter{ctrA} +%\newcounter{ctrB} +%\refstepcounter{ctrA}\label{ref:A} +%\setcounterref{ctrB}{ref:A} +%\addtocounterpageref{ctrB}{ref:A} +%\end{verbatim} +% \end{quote} +% +% \subsection{Expandable commands} +% +% These commands that can be used in expandible contexts +% (inside calculations, \cs{edef}, \cs{csname}, \cs{write}, \dots): +% \begin{quote} +% \cs{getrefnumber}, \cs{getpagerefnumber} +% \end{quote} +% They take one argument, the reference: +% \begin{quote} +% \cs{get...refnumber} |{|\meta{reference}|}| +% \end{quote} +% The default for undefined references can be changed +% with macro \cs{setrefcountdefault}, for example this +% package calls: +% \begin{quote} +% \cs{setrefcountdefault}|{0}| +% \end{quote} +% +% Since version 2.0 of this package there is a new +% command: +% \begin{quote} +% \cs{getrefbykeydefault} |{|\meta{reference}|}| +% |{|\meta{key}|}| |{|\meta{default}|}| +% \end{quote} +% This generalized version allows the extraction +% of further properties of a reference than the +% two standard ones. Thus the following properties +% are supported, if they are available: +% \begin{quote} +% \begin{tabular}{@{}l|l|l@{}} +% Key & Description & Package\\ +% \hline +% \meta{empty} & same as \cs{ref} & \LaTeX\\ +% |page| & same as \cs{pageref} & \LaTeX\\ +% |title| & section and caption titles & \xpackage{titleref}\\ +% |name| & section and caption titles & \xpackage{nameref}\\ +% |anchor| & anchor name & \xpackage{hyperref}\\ +% |url| & url/file & \xpackage{hyperref}/\xpackage{xr} +% \end{tabular} +% \end{quote} +% +% \subsection{Undefined references} +% +% Because warnings and assignments cannot be used in +% expandible contexts, undefined references do not +% produce a warning, their values are assumed to be zero. +% Example: +% \begin{quote} +%\begin{verbatim} +%\label{ref:here}% somewhere +%\refused{ref:here}% see below +%\ifodd\getpagerefnumber{ref:here}% +% reference is on an odd page +%\else +% reference is on an even page +%\fi +%\end{verbatim} +% \end{quote} +% +% In case of undefined references the user usually want's +% to be informed. Also \LaTeX\ prints a warning at +% the end of the \LaTeX\ run. To notify \LaTeX\ and +% get a normal warning, just use +% \begin{quote} +% \cs{refused} |{|\meta{reference}|}| +% \end{quote} +% outside the expanding context. Example, see above. +% +% \subsection{Notes} +% +% \begin{itemize} +% \item +% The method of extracting the number in this +% package also works in cases, where the +% reference cannot be used directly, because +% a package such as \xpackage{hyperref} has added +% extra stuff (hyper link), so that the reference cannot +% be used as number any more. +% \item +% If the reference does not contain a number, +% assignments to a counter will fail of course. +% \end{itemize} +% +% +% \StopEventually{ +% } +% +% \section{Implementation} +% +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{refcount} + [2006/02/20 v3.0 Data extraction from references (HO)] + +\def\setrefcountdefault#1{% + \def\rc@default{#1}% +} +\setrefcountdefault{0} + +% \def\@car#1#2\@nil{#1} % defined in LaTeX kernel +\def\rc@cartwo#1#2#3\@nil{#2} + +% generic check without babel support +\long\def\rc@refused#1{% + \expandafter\ifx\csname r@#1\endcsname\relax + \protect\G@refundefinedtrue + \@latex@warning{% + Reference `#1' on page \thepage\space undefined% + }% + \fi +} + +% user command, add babel support +\newcommand*{\refused}[1]{% + \begingroup + \csname @safe@activestrue\endcsname + \rc@refused{#1}{}% + \endgroup +} + +% Generic command for "\{set,addto}counter{page,}ref": +% #1: \setcounter, \addtocounter +% #2: \@car (for \ref), \@cartwo (for \pageref) +% #3: LaTeX counter +% #4: reference +\def\rc@set#1#2#3#4{% + \begingroup + \csname @safe@activestrue\endcsname + \rc@refused{#4}% + \expandafter\rc@@set\csname r@#4\endcsname{#1}{#2}{#3}% + \endgroup +} +% #1: \r@<...> +% #2: \setcounter, \addtocounter +% #3: \@car (for \ref), \@cartwo (for \pageref) +% #4: LaTeX counter +\def\rc@@set#1#2#3#4{% + \ifx#1\relax + #2{#4}{\rc@default}% + \else + #2{#4}{% + \expandafter#3#1\rc@default\rc@default\@nil + }% + \fi +} + +% user commands: + +\newcommand*{\setcounterref}{\rc@set\setcounter\@car} +\newcommand*{\addtocounterref}{\rc@set\addtocounter\@car} +\newcommand*{\setcounterpageref}{\rc@set\setcounter\rc@cartwo} +\newcommand*{\addtocounterpageref}{\rc@set\addtocounter\rc@cartwo} + +\newcommand*{\getrefnumber}[1]{% + \expandafter\ifx\csname r@#1\endcsname\relax + \rc@default + \else + \expandafter\expandafter\expandafter\@car + \csname r@#1\endcsname\@nil + \fi +} +\newcommand*{\getpagerefnumber}[1]{% + \expandafter\ifx\csname r@#1\endcsname\relax + \rc@default + \else + \expandafter\expandafter\expandafter\rc@cartwo + \csname r@#1\endcsname\rc@default\rc@default\@nil + \fi +} +\newcommand*{\getrefbykeydefault}[2]{% + \expandafter\rc@getrefbykeydefault + \csname r@#1\expandafter\endcsname + \csname rc@extract@#2\endcsname +} +% #1: \r@<...> +% #2: \rc@extract@<...> +% #3: default +\def\rc@getrefbykeydefault#1#2#3{% + \ifx#1\relax + % reference is undefined + #3% + \else + \ifx#2\relax + % extract method is missing + #3% + \else + \expandafter\rc@generic#1{#3}{#3}{#3}{#3}{#3}\@nil#2{#3}% + \fi + \fi +} +% #1: first item in \r@<...> +% #2: remaining items in \r@<...> +% #3: \rc@extract@<...> +% #4: default +\def\rc@generic#1#2\@nil#3#4{% + #3{#1\TR@TitleReference\@empty{#4}\@nil}{#1}#2\@nil +} +\def\rc@extract@{% + \expandafter\@car\@gobble +} +\def\rc@extract@page{% + \expandafter\@car\@gobbletwo +} +\def\rc@extract@name{% + \expandafter\@car\@gobblefour\@empty +} +\def\rc@extract@anchor{% + \expandafter\@car\@gobblefour +} +\def\rc@extract@url{% + \expandafter\expandafter\expandafter\@car\expandafter + \@gobble\@gobblefour +} +\def\rc@extract@title#1#2\@nil{% + \rc@@extract@title#1% +} +\def\rc@@extract@title#1\TR@TitleReference#2#3#4\@nil{#3} +%</package> +% \end{macrocode} +% \section{Installation} +% +% \paragraph{CTAN.} This package is available on +% CTAN\footnote{\url{ftp://ftp.ctan.org/tex-archive/}}: +% \begin{description} +% \item[\CTAN{macros/latex/contrib/oberdiek/refcount.dtx}] The source file. +% \item[\CTAN{macros/latex/contrib/oberdiek/refcount.pdf}] Documentation. +% \end{description} +% +% \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 refcount.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} +% \sbox0{^^A +% \begin{tabular}{@{}>{\ttfamily}l@{$\quad\rightarrow\quad$}>{\ttfamily}l@{}} +% refcount.sty & tex/latex/oberdiek/refcount.sty\\ +% refcount.pdf & doc/latex/oberdiek/refcount.pdf\\ +% refcount.dtx & source/latex/oberdiek/refcount.dtx\\ +% \end{tabular}^^A +% }% +% \ifdim\wd0>\linewidth +% \mbox{}\nobreak\hskip0pt minus\leftmargin +% \usebox0 +% \nobreak\hskip0pt minus\rightmargin +% \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. +% +% \paragraph{Refresh file databases.} If your \TeX~distribution +% (\teTeX, \mikTeX, \dots) rely on file databases, you must refresh +% these. For example, \teTeX\ users run \verb|texhash| or +% \verb|mktexlsr|. +% +% Now the installation is complete. +% +% \subsection{Some details for the interested} +% +% \paragraph{Attached source.} +% +% The PDF documentation on CTAN also includes the +% \xfile{.dtx} source file. It can be extracted by +% AcrobatReader 6 or higher. Another option is \textsf{pdftk}, +% e.g. unpack the file into the current directory: +% \begin{quote} +% \verb|pdftk refcount.pdf unpack_files output .| +% \end{quote} +% +% \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 intension: +% \begin{quote} +% \verb|latex \install=y\input{refcount.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 refcount.dtx +%makeindex -s gind.ist refcount.idx +%pdflatex refcount.dtx +%makeindex -s gind.ist refcount.idx +%pdflatex refcount.dtx +%\end{verbatim} +% \end{quote} +% +% \begin{History} +% \begin{Version}{1998/04/08 v1.0} +% \item +% First public release, written as answer in the +% newsgroup \texttt{comp.text.tex} in the thread +% ``Re: Adding a \cs{ref} to a counter?'', date: 1998/08/04. +% \end{Version} +% \begin{Version}{2000/09/07 v2.0} +% \item +% Documentation added. +% \item +% LPPL 1.2 +% \item +% Package rewritten, new commands added. +% \end{Version} +% \begin{Version}{2006/06/20 v3.0} +% \item +% Support for \xpackage{hyperref} and \xpackage{nameref} improved. +% \item +% Support for \xpackage{titleref} and \xpackage{babel}'s shorthands added. +% \item +% New: \cs{refused}, \cs{getrefbykeydefault} +% \end{Version} +% \end{History} +% +% \PrintIndex +% +% \Finale +\endinput |