% \iffalse %% File: l3keys2e.dtx (C) Copyright 2009 LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the ``l3keys2e'' (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% % %<*driver|package> \RequirePackage{l3names} % %\fi \GetIdInfo$Id: l3keys2e.dtx 1494 2009-08-24 11:05:44Z joseph $ {Parsing LaTeX3 keyvals as LaTeX2e package options} %\iffalse %<*driver> %\fi \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse \documentclass{l3doc} \begin{document} \DocInput{l3keys2e.dtx} \end{document} % % \fi % % \title{The \textsf{l3keys2e} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ % Parsing \LaTeX3 keyvals as \LaTeXe\ package options} % \author{\Team} % \date{\filedate} % \maketitle % %\begin{documentation} % %\section{Key--value arguments as \LaTeXe\ class and package options} % % The key--value method for optional arguments is very popular, as it % allows the class or package author to define a large number of % options with a simple interface. The \pkg{expl3} bundle of \LaTeX3 % base code includes the module \pkg{l3keys} for defining keys, but % to use these when loading \LaTeXe\ packages and classes requires % extra support. That support is provided by this small package, which % is intended to enable \LaTeXe\ packages to benefit from the power of % the \LaTeX3 key--value system. % %\subsection{Creating and using keyval options} % % As with any key--value input, using key--value pairs as package or % class options has two parts. The first stage is to define one or % more keys. This should be done using the \LaTeX3 module \pkg{l3keys}. % For example, an option which simply stores a value would be created % using: %\begin{verbatim} % \keys_define:nn { module } { % option .set:N = \l_module_variable_tl % } %\end{verbatim} % On its own, this will not make the key an option for the package or % class containing the definition. The second stage is therefore to % process the current options, searching for applicable keys. % %\begin{function}{\ProcessKeysOptions} % \begin{syntax} % "\ProcessKeysOptions" \Arg{module} % \end{syntax} % The \cs{ProcessKeysOptions} function is used to check the current % option list against the keys defined for . Global (class) % options and local (package) options are checked when this function % is called in a package. Each option which does match a key name is % then used to attempt to set the appropriate key using % \cs{keys_set:nn}. For example, the option defined earlier would be % processed by the line % \begin{verbatim} % \ProcessKeysOptions { module } % \end{verbatim} %\end{function} % %\begin{function}{\ProcessKeysPackageOptions} % \begin{syntax} % "\ProcessKeysPackageOptions" \Arg{module} % \end{syntax} % This function works in a similar manner to \cs{ProcessKeysOptions}. % When used in a LaTeX2e package, \cs{ProcessKeysPackageOptions} % will not examine any class options available. In contrast, % \cs{ProcessKeysOptions} does parse class options (in common with the % LaTeX2e kernel function \cs{ProcessOptions}). %\end{function} % %\subsection{Internal functions and variables} % %\begin{variable}{\keys_latexe_options_clist} % Local options and applicable global (class) options are collected up % here prior to processing using \cs{keys_set:nn}. %\end{variable} % %\begin{function}{\keys_latexe_options:n} % \begin{syntax} % "\keys_latexe_options:n" \Arg{module} % \end{syntax} % Examines current global and local options, comparing them to the % keys defined for . Option names which match defined keys are % then executed by passing the appropriate data to \cs{keys_set:nn}. %\end{function} % %\begin{function}{\keys_latexe_options_global:n} % \begin{syntax} % "\keys_latexe_options_global:n" \Arg{module} % \end{syntax} % Makes appropriate checks on global (class) options, then searches for % key matches for . %\end{function} % %\begin{function}{\keys_latexe_options_class:n} % \begin{syntax} % "\keys_latexe_options_class:n" \Arg{module} % \end{syntax} % Processes global options when the current file is itself a class, % checking the options against keys defined for . %\end{function} % %\begin{function}{\keys_latexe_options_package:n} % \begin{syntax} % "\keys_latexe_options_package:n" \Arg{module} % \end{syntax} % Processes global options when the current file is a \LaTeXe\ package, % checking the options against keys defined for . %\end{function} % %\begin{function}{\keys_latexe_options_local:} % \begin{syntax} % "\keys_latexe_options_local:" % \end{syntax} % Finds local (package) options and adds them to the list to be % parsed by \cs{keys_set:nn}. %\end{function} % %\begin{function}{ % \keys_latexe_remove_equals:n / (EXP) | % \keys_latexe_remove_equals:w / (EXP) %} % \begin{syntax} % "\keys_latexe_remove_equals:n" \Arg{option} % "\keys_latexe_remove_equals:w" = "\q_stop" % \end{syntax} % Returns only the key part of a key--value option by removing % everything after the first equals sign. It is assumed that, as this % will apply in the preamble, equals signs have category code 12. %\end{function} % %\end{documentation} % %\begin{implementation} % %\subsection{Implementation} % % The usual lead-off, using \pkg{xparse} at the interface level. % \begin{macrocode} %<*package> \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} \RequirePackage{xparse} % \end{macrocode} % %\begin{macro}{\keys_latexe_options_clist} % The module collects all applicable global and local options into a % single list before processing them. % \begin{macrocode} \clist_new:N \keys_latexe_options_clist % \end{macrocode} %\end{macro} % %\begin{macro}{\_l_keys_process_class_bool} % A flag to indicate that class options should be processed for % packages. % \begin{macrocode} \bool_new:N \_l_keys_process_class_bool % \end{macrocode} %\end{macro} % %\begin{macro}{\keys_latexe_options:n} % The main function calls functions to collect up the global and local % options into \cs{keys_latexe_options_clist} before calling the main % \pkg{l3keys} module to actually do the processing. So that a suitable % message is produced if the option is unknown, the special % \texttt{unknown} key is set if it does not already exist for the % current module. % \begin{macrocode} \cs_new:Npn \keys_latexe_options:n #1 { \clist_clear:N \keys_latexe_options_clist \keys_latexe_options_global:n {#1} \keys_latexe_options_local: \keys_if_exist:nnF {#1} { unknown } { \keys_define:nn {#1} { unknown .code:n = { \msg_warning:nnxx { Option~Processing } { unknown-option } { \l_keys_key_tl } { \@currname } } } } \keys_set:nV {#1} \keys_latexe_options_clist \AtEndOfPackage { \cs_set_eq:NN \@unprocessedoptions \scan_stop: } } \msg_new:nnn { Option~Processing } { unknown-option } {% Unknown~option~`#1'\\% for~module~#2.% } % \end{macrocode} %\end{macro} % %\begin{macro}{\keys_latexe_options_global:n} % Global (class) options are handled differently for \LaTeXe\ packages % and classes. Hence this function is essentially a check on the current % file type. The initial test is needed as \LaTeXe\ allows variables to % be equal to \cs{scan_stop:}, which is forbidden in \LaTeX3 code. % \begin{macrocode} \cs_new:Npn \keys_latexe_options_global:n #1 { \cs_if_eq:NNF \@classoptionslist \scan_stop: { \cs_if_eq:NNTF \@currext \@clsextension { \keys_latexe_options_class:n {#1} }{ \bool_if:NT \_l_keys_process_class_bool { \keys_latexe_options_package:n {#1} } } } } % \end{macrocode} %\end{macro} % %\begin{macro}{\keys_latexe_options_class:n} % For classes, each option (stripped of any content after `\texttt{=}') % is checked for existence as a key. If found, the option is added to % the combined list for processing. On the other hand, unused options % are stored up in \cs{@unusedoptionlist}. % \begin{macrocode} \cs_new:Npn \keys_latexe_options_class:n #1 { \clist_map_inline:Nn \@classoptionslist { \keys_if_exist:nnTF {#1} { \keys_latexe_remove_equals:n {##1} } { \clist_put_right:Nn \keys_latexe_options_clist {##1} }{ \clist_put_right:Nn \@unusedoptionlist {##1} } } } % \end{macrocode} %\end{macro} % %\begin{macro}{\keys_latexe_options_package:n} % For global options when processing a package, the tasks are slightly % different from those for a class. The check is the same, but here % there is nothing to do if the option is not applicable. Each valid % option also needs to be removed from \cs{@unusedoptionlist}. % \begin{macrocode} \cs_new:Npn \keys_latexe_options_package:n #1 { \clist_map_inline:Nn \@classoptionslist { \keys_if_exist:nnT {#1} { \keys_latexe_remove_equals:n {##1} } { \clist_put_right:Nn \keys_latexe_options_clist {##1} \clist_remove_element:Nn \@unusedoptionlist {##1} } } } % \end{macrocode} %\end{macro} % %\begin{macro}{\keys_latexe_options_local:} % If local options are found, the are added to the processing list. % \LaTeXe\ stores options for each file in a macro which may or may not % exist, hence the need to use \cs{cs_if_exist:c}. % \begin{macrocode} \cs_new_nopar:Npn \keys_latexe_options_local: { \cs_if_eq:NNF \@currext \@clsextension { \cs_if_exist:cT { opt@ \@currname . \@currext } { \exp_args:NNc \clist_put_right:NV \keys_latexe_options_clist { opt@ \@currname . \@currext } } } } % \end{macrocode} %\end{macro} % %\begin{macro}{\keys_latexe_remove_equals:n} %\begin{macro}{\keys_latexe_remove_equals:w} % As the name suggests, this is a simple function to remove an equals % sign from the input. This is all wrapped up in an \texttt{n} function % so that there will always be a sign available. % \begin{macrocode} \cs_new:Npn \keys_latexe_remove_equals:n #1 { \keys_latexe_remove_equals:w #1 = \q_stop } \cs_new:Npn \keys_latexe_remove_equals:w #1 = #2 \q_stop {#1} % \end{macrocode} %\end{macro} %\end{macro} % %\begin{macro}{\ProcessKeysOptions} %\begin{macro}{\ProcessKeysOptions} % The user macro are simply wrappers around the internal process. In % contrast to other similar packages, the module name is always required % here. % \begin{macrocode} \NewDocumentCommand \ProcessKeysOptions { m } { \bool_set_true:N \_l_keys_process_class_bool \keys_latexe_options:n {#1} } \NewDocumentCommand \ProcessKeysPackageOptions { m } { \bool_set_false:N \_l_keys_process_class_bool \keys_latexe_options:n {#1} } \@onlypreamble \ProcessKeysOptions \@onlypreamble \ProcessKeysPackageOptions % \end{macrocode} %\end{macro} %\end{macro} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % % \PrintIndex