diff options
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/expl3.dtx | 874 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3.ins | 3 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3clist.dtx | 29 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3keys.dtx | 1529 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3keyval.dtx | 11 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3msg.dtx | 61 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/source3.tex | 1 |
7 files changed, 1979 insertions, 529 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/expl3.dtx b/Master/texmf-dist/source/latex/expl3/expl3.dtx index a22e1b53417..61672cc7228 100644 --- a/Master/texmf-dist/source/latex/expl3/expl3.dtx +++ b/Master/texmf-dist/source/latex/expl3/expl3.dtx @@ -37,7 +37,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: expl3.dtx 1381 2009-06-01 20:36:02Z joseph $ +\GetIdInfo$Id: expl3.dtx 1439 2009-08-05 19:05:55Z joseph $ {L3 Experimental code bundle wrapper}% %\iffalse %<*driver> @@ -45,27 +45,19 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} -\usepackage{shortvrb,hypdoc} -\MakeShortVerb{\|} -\hyphenation{para-meters para-meter} -% I have found at least 3 other hyphenations of this in various refs, -% but I did also find this, which is my personal favourite ---chris -\hyphenation{ignore ignored ignores} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} + \DocInput{expl3.dtx} \end{document} %</driver> % \fi % % \providecommand\acro[1]{\textsc{\MakeLowercase{#1}}} -% \providecommand\ie{i.e.,~} -% \providecommand\eg{e.g.,~} % \newenvironment{arg-description}{% % \begin{itemize}\def\makelabel##1{\hss\llap{\bfseries##1}}}{\end{itemize}} % -% \title{The \textsf{expl3} package and philosophy\thanks{This file -% has version number \fileversion, last +% \title{The \textsf{expl3} package and \LaTeX3 programming^^A +% \thanks{This file has version number \fileversion, last % revised \filedate.}} % \author{\Team} % \date{\filedate} @@ -76,44 +68,43 @@ % % \begin{abstract} % -% This paper gives a brief introduction to a new set of programming +% This document gives an introduction to a new set of programming % conventions that have been designed to meet the requirements of % implementing large scale \TeX\ macro programming projects such as -% \LaTeX. +% \LaTeX. These programming conventions are the base layer of \LaTeX3. % % The main features of the system described are: % \begin{itemize} -% \item classification of the macros (or, in \LaTeX{} terminology, -% commands) into \LaTeX{} functions and \LaTeX{} parameters, and also +% \item classification of the macros (or, in \LaTeX\ terminology, +% commands) into \LaTeX\ functions and \LaTeX\ parameters, and also % into modules containing related commands; -% \item a systematic naming scheme based on these -% classifications; +% \item a systematic naming scheme based on these classifications; % \item a simple mechanism for controlling the expansion of a function's -% arguments. +% arguments. % \end{itemize} -% This system is being used as the basis for -% \TeX{} programming within the \LaTeX3 project. -% Note that the language is not intended for either -% document mark-up or style specification. +% This system is being used as the basis for \TeX\ programming within +% the \LaTeX3 project. Note that the language is not intended for either +% document mark-up or style specification. Instead, it is intended that +% such features will be built on top of the conventions described here. % -% An earlier description of the \LaTeX3 programming language is -% available from \url{http://www.latex-project.org/papers}. -% \end{abstract} -% +% \end{abstract} % % \section{Introduction} % -% This paper describes the conventions for a \TeX-based programming -% language which is intended to provide a more consistent and rational -% environment for the construction of large scale systems, such as -% \LaTeX, using \TeX{} macros. -% -% Variants of this language have been in use by The \LaTeX3 Project Team -% since around 1990 but the syntax specification to be outlined here -% should \emph{not} be considered final. This is an experimental -% language thus many aspects, such as the syntax conventions and naming -% schemes, may (and probably will) change as more experience is gained -% with using the language in practice. +% The first step to develop a \LaTeX\ kernel beyond \LaTeXe\ is to +% address how the underlying system is programmed. Rather than the +% current mix of \LaTeX\ and \TeX\ macros, the \LaTeX3 system provides +% its own consistent interface to all of the functions needed to +% control \TeX. A key part of this work is to ensure that everything +% is documented, so that \LaTeX\ programmers and users can work +% efficiently without needing to be familiar with the internal nature +% of the kernel or with plain \TeX. +% +% The \pkg{expl3} bundle provides this new programming interface for +% \LaTeX. To make programming systematic, \LaTeX3 uses some very +% different conventions to \LaTeXe\ or plain TeX. As a result, +% programmers starting with \LaTeX3 will need to become familiar with +% the syntax of the new language. % % The next section shows where this language fits into a complete % \TeX-based document processing system. We then describe the major @@ -121,25 +112,16 @@ % argument specification syntax used in function names. % % The practical ideas behind this argument syntax will be explained, -% together with the semantics of the expansion control mechanism and the -% interface used to define variant forms of functions. The paper also -% discusses some advantages of the syntax for parameter names. +% together with the expansion control mechanism and the interface +% used to define variant forms of functions. % % As we shall demonstrate, the use of a structured naming scheme and of % variant forms for functions greatly improves the readability of the % code and hence also its reliability. Moreover, experience has shown % that the longer command names which result from the new syntax do not -% make the process of \emph{writing} code significantly harder -% (especially when using a reasonably intelligent editor). -% -% The final section gives some details of our plans to distribute parts -% of this system. Although the paper is now a little dated, more general -% information concerning the work of the \LaTeX3 Project can be found -% in Ref.~\cite{tub:MR97-1}. -% +% make the process of \emph{writing} code significantly harder. % % \section{Languages and interfaces} -% \label{sec:langs} % % It is possible to identify several distinct languages related to the % various interfaces that are needed in a \TeX-based document processing @@ -147,14 +129,13 @@ % the \LaTeX3 system. % % \begin{description} -% \item[Document mark-up] This comprises those commands (often called tags) -% that are to embedded in the document (the |.tex| file). +% \item[Document mark-up] This comprises those commands (often called +% tags) that are to embedded in the document (the |.tex| file). % % It is generally accepted that such mark-up should be essentially -% \emph{declarative}. -% It may be traditional \TeX-based mark-up such as -% \LaTeXe, as described in~\cite{A-W:LLa94} and~\cite{A-W:GMS94}, -% or a mark-up language defined via \acro{SGML} or \acro{XML}. +% \emph{declarative}. It may be traditional \TeX-based mark-up such +% as \LaTeXe, as described in~\cite{A-W:LLa94} and~\cite{A-W:GMS94}, +% or a mark-up language defined via \acro{HTML} or \acro{XML}. % % One problem with more traditional \TeX\ coding conventions (as % described in~\cite{A-W:K-TB}) is that the names and syntax of \TeX's @@ -164,92 +145,89 @@ % superiority) of logical mark-up has meant that such explicit % formatting commands are almost never needed in documents or in % author-defined macros. Thus they are used almost exclusively by -% \TeX{} programmers to define higher-level commands; and their +% \TeX\ programmers to define higher-level commands, and their % idiosyncratic syntax is not at all popular with this community. % Moreover, many of them have names that could be very useful as -% document mark-up tags were they not pre-empted as primitives (\eg -% |\box| or |\special|). +% document mark-up tags were they not pre-empted as primitives +% (e.g.~\cs{box} or \cs{special}). % % \item[Designer interface] This relates a (human) typographic % designer's specification for a document to a program that `formats % the document'. It should ideally use a declarative language that -% facilitates expression of the relationship and spacing rules specified -% for the layout of the various document elements. +% facilitates expression of the relationship and spacing rules +% specified for the layout of the various document elements. % % This language is not embedded in document text and it will be very -% different in form to the document mark-up language. For -% \acro{SGML}-based systems the \acro{DSSSL} language may come to play -% this role. For \LaTeX, this level was almost completely missing -% from \LaTeX2.09; \LaTeXe\ made some improvements in this area but it -% is still the case that implementing a design specification in -% \LaTeX\ requires far more `low-level' coding than is acceptable. +% different in form to the document mark-up language. For \LaTeX, +% this level was almost completely missing from \LaTeX2.09; \LaTeXe\ +% made some improvements in this area but it is still the case that +% implementing a design specification in \LaTeX\ requires far more +% `low-level' coding than is acceptable. +% % \item[Programmer interface] -% This language is the implementation -% language within which the basic typesetting functionality is -% implemented, building upon the primitives of \TeX\ (or a -% successor program). -% It may also be used to implement the previous -% two languages `within' \TeX, as in the current \LaTeX\ system. +% This language is the implementation language within which the +% basic typesetting functionality is implemented, building upon the +% primitives of \TeX\ (or a successor program). It may also be used +% to implement the previous two languages `within' \TeX, as in the +% current \LaTeX\ system. +% % \end{description} % -% Only the last of these three interfaces is covered by this paper, -% which describes a system aimed at providing a suitable basis for -% coding large scale projects in \TeX{} (but this should not preclude its -% use for smaller projects). Its main distinguishing features are -% summarised here. -% -% \begin{itemize} -% \item A consistent naming scheme for all commands, including \TeX\ -% primitives. -% \item The classification of commands as \LaTeX{} functions or \LaTeX{} -% parameters, and also their division into modules according to their -% functionality. -% \item A simple mechanism for controlling argument expansion. -% \item Provision of a set of core \LaTeX{} functions that is sufficient -% for handling programming constructs such as queues, sets, -% stacks, property lists. -% \item A \TeX{} programming environment in which, for example, all -% white space is ignored. +% The last layer is covered by the conventions described in this +% doucment, which describes a system aimed at providing a suitable +% basis for coding \LaTeX3. Its main distinguishing features are +% summarised here: +%\begin{itemize} +% \item A consistent naming scheme for all commands, including \TeX\ +% primitives. +% \item The classification of commands as \LaTeX\ functions or \LaTeX\ +% parameters, and also their division into modules according to their +% functionality. +% \item A simple mechanism for controlling argument expansion. +% \item Provision of a set of core \LaTeX\ functions that is sufficient +% for handling programming constructs such as queues, sets, stacks, +% property lists. +% \item A \TeX\ programming environment in which, for example, all +% white space is ignored. % \end{itemize} % % \section{The naming scheme} -% \label{sec:scheme} +% +% \LaTeX3 does not use \texttt{@} as a `letter' for defining +% internal macros. Instead, the symbols \texttt{_} and \texttt{:} +% are used in internal macro names to provide structure. In +% contrast to the plain \TeX\ format and the \LaTeXe\ kernel, these +% extra letters are used only between parts of a macro name (no +% strange vowel replacement). % % The naming conventions for this programming language distinguish -% between \textit{functions} and \textit{parameters}. Functions can have -% arguments and they are executed. Parameters can be assigned values +% between \emph{functions} and \emph{variables}. Functions can have +% arguments and they are executed. Variables can be assigned values % and they are used in arguments to functions; they are not directly -% executed but are manipulated by mutator and accessor functions. -% Functions and parameters with a related functionality (for example -% accessing counters, or manipulating token-lists, etc.)\ are collected -% together into a -% \textit{module}. +% executed but are manipulated by functions. Functions and variables +% with a related functionality (for example accessing counters, or +% manipulating token lists, etc.)\ are collected together into a +% \emph{module}. % -% -% Note that all these terms are only \LaTeX{} terminology and are not, -% for example, intended to indicate that the commands have these -% properties when considered in the context of basic \TeX{} or in any -% more general programming context. -% -% -% \subsection{Examples} -% \label{sec:ex} +%\subsection{Examples} % % Before giving the details of the naming scheme, here are a few typical -% examples to indicate the flavour of the scheme; first some parameter +% examples to indicate the flavour of the scheme; first some variable % names. -% \begin{quote} -% |\l_tmpa_box| is a local parameter (hence the~|l_| prefix) -% corresponding to a box register.\\ -% |\g_tmpa_int| is a global parameter (hence the~|g_| prefix) -% corresponding to an integer register (\ie a \TeX{} count register).\\ -% |\c_empty_toks| -% is the constant~(|c_|) token register parameter that is for ever empty. -% \end{quote} +%\begin{quote} +% \cs{l_tmpa_box} is a local variable (hence the~|l_| prefix) +% corresponding to a box register.\\ +% \cs{g_tmpa_int} is a global variable (hence the~|g_| prefix) +% corresponding to an integer register (i.e.~a \TeX\ count +% register).\\ +% \cs{c_empty_toks} is the constant~(|c_|) token register variable +% that is always empty. +%\end{quote} +% % Now here is an example of a typical function name. % -% |\seq_push:Nn| is the function which puts the token list specified by -% its second argument onto the stack specified by its first argument. +% \cs{seq_push:Nn} is the function which puts the token list specified +% by its second argument onto the stack specified by its first argument. % The different natures of the two arguments are indicated by the~|:Nn| % suffix. The first argument must be a single token which `names' % the stack parameter: such single-token arguments are denoted~|N|. @@ -259,135 +237,123 @@ % denotes such a `normal' argument form. The name of the function % indicates it belongs to the |seq| module. % -%^^A |\seq_push:cn| would be similar to the above, but in this case the~|c| -%^^A means that the stack-name is specified in the first argument by a -%^^A token list that expands, using |\csname...|, to a control sequence that -%^^A is the \emph{name} of the stack parameter. -%^^A -%^^A \noindent -%^^A The names of these two functions also indicate that they are in the -%^^A module called |seq|. -% -% -% \subsection{Formal syntax of the conventions} -% \label{sec:namesyn} -% -% We shall now look in more detail at the syntax of these names.\\ -% The syntax of parameter names is as follows: -% \begin{quote} -% |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type} -% \end{quote} -% The syntax of function names is as follows: -% \begin{quote} -% |\|\m{module}|_|\m{description}|:|\m{arg-spec} -% \end{quote} -% -% -% \subsection{Modules and descriptions} -% \label{sec:modules} -% +% \subsection{Formal naming syntax} +% +% We shall now look in more detail at the syntax of these names. A +% function name in \LaTeX3 will have a name consisting of three parts: +%\begin{quote} +% |\|\m{module}|_|\m{description}|:|\m{arg-spec} +%\end{quote} +% while a variable will have (up to) four distinct parts to its name: +%\begin{quote} +% |\|\m{scope}|_|\m{module}|_|\m{description}|_|\m{type} +%\end{quote} +% % The syntax of all names contains % \begin{quote} -% \m{module} and \m{description}: +% \m{module} and \m{description} % \end{quote} % these both give information about the command. % -% A \textit{module} is a collection of -% closely related functions and parameters. -% Typical module names include~|int| for integer parameters +% A \emph{module} is a collection of closely related functions and +% variables. Typical module names include~|int| for integer parameters % and related functions,~|seq| for sequences and~|box| for boxes. % % Packages providing new programming functionality will add new modules % as needed; the programmer can choose any unused name, consisting -% of letters only, for a module. +% of letters only, for a module. In general, the module name and module +% prefix should be related: for example, the kernel module containing +% \texttt{box} functions is called \texttt{l3box}. % -% The \textit{description} gives more detailed information about the +% The \emph{description} gives more detailed information about the % function or parameter, and provides a unique name for it. It should -% consist of letters and, possibly,~|_|~characters. +% consist of letters and, possibly,~|_|~characters. In general, the +% description should use |_| to divide up `words' or other easy to +% follow parts of the name. For example, the \LaTeX3 kernel provides +% \cs{if_cs_exist:N} which, as might be expected, tests if a command +% name exists. % % As a semi-formalized concept the letter |g| is sometimes used to % prefix certain parts of the \m{description} -% to mark the function as ``globally acting'', e.g., |\int_set:Nn| is -% a local operation while |\int_gset:Nn| is a global operation. This -% of course goes hand in hand with when to use |\l_| and |\g_| +% to mark the function as `globally acting', e.g., \cs{int_set:Nn} is +% a local operation while \cs{int_gset:Nn} is a global operation. This +% of course goes hand in hand with when to use \cs{l_} and \cs{g_} % variable prefixes. % -% \subsection{Parameters: access and type} -% \label{sec:parms} -% -% The \m{access} part of the name describes how the parameter can be -% accessed. Parameters are primarily classified as local, global or -% constant (there are further, more technical, classes). This -% \textit{access} type appears as a code at the beginning of the name; -% the codes used include: -% \begin{arg-description} -% \item[c] -% constants (global parameters whose value should not be changed); -% \item[g] -% parameters whose value should only be set globally; -% \item[l] -% parameters whose value should only be set locally. -% \end{arg-description} -% -% The \m{type} will normally (except when introducing a new data-type) -% be in the list of available \textit{data-types}; these include the +%\subsubsection{Variables: scope and type} +% +% The \m{scope} part of the name describes how the variable can be +% accessed. Variables are classified as local, global or constant. +% This \emph{scope} type appears as a code at the beginning of the name; +% the codes used are: +%\begin{arg-description} +% \item[c] constants (global variables whose value should not be +% changed); +% \item[g] variables whose value should only be set globally; +% \item[l] variables whose value should only be set locally. +%\end{arg-description} +% +% The \m{type} will be in the list of available +% \emph{data-types};\footnote{Of course, if a totally new data type is +% needed then this will not be the case. However, it is hoped that only +% the kernel team will need to create new data types.} these include the % primitive \TeX\ data-types, such as the various registers, but to -% these will be added data-types built within the \LaTeX{} programming +% these will be added data-types built within the \LaTeX\ programming % system. % -% Here are some typical data-type names: -% \begin{description} -% \item[int] integer-valued count register; -% \item[tl] token list variables: placeholders for token lists; -% \item[toks] token register; -% \item[box] box register; -% \item[skip] `rubber' lengths; -% \item[dim] `rigid' lengths; -% \item[num] A `fake' integer type using only macros. Useful for -% setting up allocation routines; -% \item[seq] `sequence': a data-type used to implement lists -% (with access at both ends) and stacks; -% \item[prop] property list; -% \item[clist] comma separated list; -% \item[stream] an input or output stream (for reading from or writing to, respectively); -% \item[bool] either true or false. -% \end{description} +% The data types in \LaTeX3 are: +%\begin{description} +% \item[int] integer-valued count register; +% \item[tl] `token list variables': placeholders for token lists; +% \item[toks] token register; +% \item[box] box register; +% \item[skip] `rubber' lengths; +% \item[dim] `rigid' lengths; +% \item[num] A `fake' integer type using only macros. Useful for +% setting up allocation routines; +% \item[seq] `sequence': a data-type used to implement lists (with +% access at both ends) and stacks; +% \item[prop] property list; +% \item[clist] comma separated list; +% \item[stream] an input or output stream (for reading from or writing +% to, respectively); +% \item[bool] either true or false (the \LaTeX3 implementation does +% not use \cs{iftrue} or \cs{ iffalse}). +%\end{description} % When the \m{type} and \m{module} are identical (as often happens in % the more basic modules) the \m{module} part is often omitted for % aesthetic reasons. % -% -% \subsection{Functions: basic argument specifications} -% \label{sec:args} -% -% Function names end with an \m{arg-spec} after a colon. This -% gives an indication of the types of argument that a function takes, -% and provides a convenient method of naming similar functions that -% differ only in their argument forms (see the next section for -% examples). -% -% The \m{arg-spec} consists of a (possibly empty) list of characters, -% each denoting one argument of the function. It is important to -% understand that `argument' here refers to the effective argument of -% the \LaTeX{} function, not to an argument at the \TeX-level. Indeed, -% the top level \TeX\ macro that has this name typically has no -% arguments. This is an extension of the existing \LaTeX\ convention -% where one says that |\section| has an optional argument and a -% mandatory argument, whereas the \TeX\ macro |\section| actually has -% zero parameters at the \TeX\ level, it merely calls an internal \LaTeX\ -% command which in turn calls others that look ahead for star forms and -% optional arguments. +% The name `token list' may cause confusion, and so some background is +% useful. \TeX\ works with tokens and lists of tokens, rather than +% characters. It provides two ways to store these token lists: within +% macros and as token registers (toks). \LaTeX3 retains the name `toks' +% for the later, and adopts the name `token list variables' (tl vars) +% for macros used to store tokens. In most circumstances, the tl var +% data type is more convenient for storing token lists. +% +%\subsubsection{Functions: argument specifications} +% +% Function names end with an \m{arg-spec} after a colon. This +% gives an indication of the types of argument that a function takes, +% and provides a convenient method of naming similar functions that +% differ only in their argument forms (see the next section for +% examples). +% +% The \m{arg-spec} consists of a (possibly empty) list of letters, +% each denoting one argument of the function. The letter, including +% its case, conveys information about the type of argument required. % -% All functions have a base form with arguments using one of the -% following argument specifiers. -% \begin{arg-description} -% \item[n] Unexpanded token or braced token list.\\ -% This is a standard \TeX\ undelimited macro argument. -% \item[N] Single token (unlike~|n|, the argument must \emph{not} be -% surrounded by braces).\\ -% A typical example of a command taking an~|N| -% argument is~|\cs_set|, in which the command being defined must be -% unbraced. +% All functions have a base form with arguments using one of the +% following argument specifiers: +%\begin{arg-description} +% \item[n] Unexpanded token or braced token list.\\ +% This is a standard \TeX\ undelimited macro argument. +% \item[N] Single token (unlike~|n|, the argument must \emph{not} be +% surrounded by braces).\\ +% A typical example of a command taking an~|N| +% argument is~|\cs_set|, in which the command being defined must be +% unbraced. % \item[p] Primitive \TeX\ parameter specification.\\ % This can be something simple like~|#1#2#3|, but may use arbitrary % delimited argument syntax such as: |#1,#2\q_stop#3|. This is used @@ -395,147 +361,128 @@ % \item[T,F] % These are special cases of~|n| arguments, used for the % true and false code in conditional commands. -% \end{arg-description} +%\end{arg-description} % There are two other specifiers with more general meanings: -% \begin{arg-description} -% \item[D] This means: \textbf{Do not -% use}. This special case is used -% for \TeX\ primitives and other commands that are provided for use -% only while bootstrapping the \LaTeX\ kernel. If the \TeX\ primitive -% needs to be used in other contexts it will be given an alternative, -% more appropriate, name with a useful argument specification. The -% argument syntax of these is often weird, in the sense described next. +%\begin{arg-description} +% \item[D] This means: \textbf{Do not use}. This special case is used +% for \TeX\ primitives and other commands that are provided for use +% only while bootstrapping the \LaTeX\ kernel. Programmers outside +% the kernel team should not use these functions! % \item[w] This means that the argument syntax is `weird' in that it % does not follow any standard rule. It is used for functions with % arguments that take non standard forms: examples are \TeX-level % delimited arguments and the boolean tests needed after certain % primitive |\if|\ldots\ commands. -% \end{arg-description} +%\end{arg-description} % -% In case of "n" arguments that consist of a -% single token the surrounding braces can be omitted in nearly all +% In case of "n" arguments that consist of a single token the +% surrounding braces can be omitted in nearly all % situations---functions that force the use of braces even for single -% token arguments are explicitly mentioned. For example, "\seq_gpush:Nn" -% is a function that takes two arguments, the first is a single token -% (the sequence) and the second may consist of several tokens surrounded -% by braces. -% -% This concept of argument specification makes it easy to read the code -% and should be followed when defining new functions. -% -% +% token arguments are explicitly mentioned. However, programmers are +% encouraged to always use braces around \texttt{n} arguments, as this +% makes the relationship between function and argument clearer. % +% Further argument specifiers are available as part of the expansion +% control system. These are discussed in the next section. % -% \section{Expansion control} -% \label{sec:exp} +%\section{Expansion control} % % Let's take a look at some typical operations one might want to % perform. Suppose we maintain a stack of open files and we use the -% stack |\g_io_file_name_seq| to keep track of them (|io| is the -% input-output file module). The basic operation -% here is to push a name onto this stack which could be done by the -% operation +% stack |\g_ior_file_name_seq| to keep track of them (|io| is the +% file reading and writing module: it uses the module prefixe +% \texttt{ior} for reading functions and variables). The basic +% operation here is to push a name onto this stack which could be +% done by the operation % \begin{quote} -% "\seq_gpush:Nn" \\ -% " \g_io_file_name_seq" \\ -% " {#1}" +% "\seq_gpush:Nn \g_ior_file_name_seq {#1}" % \end{quote} % where |#1| is the filename. In other words, this operation would -% push the file name as is. +% push the file name as is onto the stack. % -% However, we might face a situation where -% the filename is stored in a register of some sort, say -% |\l_io_curr_file_tl|. In this case we want to retrieve the value of -% the register. If we simply use +% However, we might face a situation where the filename is stored in +% a variable of some sort, say |\l_ior_curr_file_tl|. In this case we +% want to retrieve the value of the variable. If we simply use % \begin{quote} -% "\seq_gpush:Nn" \\ -% " \g_io_file_name_seq" \\ -% " \l_io_curr_file_tl " +% "\seq_gpush:Nn \g_io_file_name_seq \l_io_curr_file_tl " % \end{quote} -% we will not get the value of the register pushed onto the stack, -% only the register name itself. Instead a suitable number of +% we will not get the value of the variable pushed onto the stack, +% only the variable name itself. Instead a suitable number of % "\exp_after:wN" would be necessary (together with extra braces) to -% change the order of execution, i.e. +% change the order of execution,\footnote{\cs{exp_after:wN} is +% the \LaTeX3 name for the \TeX\ \cs{expandafter} primitive.} i.e. % \begin{quote} % "\exp_after:wN" \\ % " \seq_gpush:Nn" \\ % "\exp_after:wN" \\ -% " \g_io_file_name_seq" \\ +% " \g_io_file_name_seq" \\ % "\exp_after:wN" \\ -% " {\l_io_curr_file_tl}" +% " { \l_io_curr_file_tl }" % \end{quote} % % The above example is probably the simplest case but already shows -% how the code changes to something difficult to -% understand. Furthermore there is an assumption in this: That the -% storage bin reveals its contents after exactly one -% expansion. Relying on this means that you cannot do proper checking -% plus you have to know exactly how a storage bin acts in order to get -% the correct number of expansions. Therefore \LaTeX3 provides the -% programmer with a general scheme that keeps the code compact and -% easy to understand. +% how the code changes to something difficult to understand. +% Furthermore there is an assumption in this: that the storage bin +% reveals its contents after exactly one expansion. Relying on this +% means that you cannot do proper checking plus you have to know +% exactly how a storage bin acts in order to get the correct number +% of expansions. Therefore \LaTeX3 provides the programmer with a +% general scheme that keeps the code compact and easy to understand. % % To denote that some argument to a function needs special treatment one -% just uses different letters in the argument part of the function to -% mark the desired behavior. In the above example one would write +% just uses different letters in the arg-spec part of the function to +% mark the desired behaviour. In the above example one would write % \begin{quote} -% "\seq_gpush:NV" \\ -% " \g_io_file_name_seq " \\ -% " \l_io_curr_file_tl " +% "\seq_gpush:NV \g_io_file_name_seq \l_io_curr_file_tl " % \end{quote} -% to achieve the desired effect. Here the "V" is for ``retrieve the -% value of the register'' (the second argument) before passing it to +% to achieve the desired effect. Here the "V" (the second argument) +% is for `retrieve the value of the variable' before passing it to % the base function. % -% % The following letters can be used to denote special treatment of % arguments before passing it to the base function: -% \begin{description} -% \item[c] Character string used as a command name.\\ The argument (a -% token or braced token list) must, when fully expanded, produce a -% sequence of characters which is then used to construct a command -% name (via~|\csname|, |\endcsname|). This command name is the -% single token that is passed to the function as the argument. Hence -% \begin{quote} -% "\seq_gpush:cV {g_file_name_stack} \l_tmpa_tl" -% \end{quote} -% is equivalent to -% \begin{quote} -% "\seq_gpush:NV \g_file_name_stack \l_tmpa_tl". -% \end{quote} -% -% \item[V] Value of a register.\\ -% This means that the register in question is returned, be it an -% integer, a length type register, a macro storage register or -% similar. The value is returned to the function as a braced token list. -% -% \item[v] Value of a register, constructed from a character string -% used as a command name.\\ -% This is a combination of |c| and |V| which first constructs a -% control sequence from the argument and then returns the value. -% -% \item[x] Fully-expanded token or braced token list.\\ -% This means that the argument is expanded as in the replacement -% text of an~|\edef|, and the expansion is passed to the function as -% a braced token list. This means that expansion takes place until -% only unexpandable tokens are left. -% +%\begin{description} +% \item[c] Character string used as a command name.\\ The argument (a +% token or braced token list) must, when fully expanded, produce a +% sequence of characters which is then used to construct a command +% name (via~|\csname| \ldots |\endcsname|). This command name is the +% single token that is passed to the function as the argument. Hence +% \begin{quote} +% "\seq_gpush:cV { g_file_name_stack } \l_tmpa_tl" +% \end{quote} +% is equivalent to +% \begin{quote} +% "\seq_gpush:NV \g_file_name_stack \l_tmpa_tl". +% \end{quote} +% \item[V] Value of a variable.\\ +% This means that the register in question is returned, be it an +% integer, a length-type register, a token list variable or +% similar. The value is returned to the function as a braced token +% list. +% \item[v] Value of a register, constructed from a character string +% used as a command name.\\ +% This is a combination of |c| and |V| which first constructs a +% control sequence from the argument and then returns the value. +% \item[x] Fully-expanded token or braced token list.\\ +% This means that the argument is expanded as in the replacement +% text of an~|\edef|, and the expansion is passed to the function as +% a braced token list. This means that expansion takes place until +% only unexpandable tokens are left. % \item[o] One-level-expanded token or braced token list.\\ -% This means that the argument is expanded one level, as by -% |\expandafter|, and the expansion is passed to the function as a braced -% token list. Note that if the original argument is a braced -% token list then only the first token in that list is expanded. -% +% This means that the argument is expanded one level, as by +% \cs{expandafter}, and the expansion is passed to the function as a +% braced token list. Note that if the original argument is a braced +% token list then only the first token in that list is expanded. +% In general, using \texttt{V} should be preferred to using +% \texttt{o} for simple variable retrival. % \item[f] Almost the same as the |x| type except here the token list -% is expanded fully until the first unexpandable token is found and -% the rest is left unchanged. Note that if this function finds a -% space at the beginning of the argument it will gobble it and not -% expand the next argument. -% \end{description} +% is expanded fully until the first unexpandable token is found and +% the rest is left unchanged. Note that if this function finds a +% space at the beginning of the argument it will gobble it and not +% expand the next argument. +%\end{description} % -% % \subsection{Simpler means better} -% \label{sec;simpler} % % Anyone who programs in \TeX\ is frustratingly familiar with the % problem of arranging that arguments to functions are suitably expanded @@ -562,13 +509,14 @@ % Using the conventions and functionality outlined here, the task would % be achieved with code such as this: % \begin{verbatim} -% \cs_gset_eq:cc {\cf@encoding \string #1} -% {?\string #1} +% \cs_gset_eq:cc +% { \cf@encoding \token_to_str:N #1 } { ? \token_to_str:N #1 } % \end{verbatim} % The command |\cs_gset_eq:cc| is a global~|\let| that generates % command names out of both of its arguments before making the % definition. This produces code that is far more readable and more -% likely to be correct first time. +% likely to be correct first time. (\cs{token_to_str:N} is the \LaTeX3 +% name for \cs{string}.) % % Here is the second example. % \begin{verbatim} @@ -594,15 +542,13 @@ % defined with the appropriate argument types and its name will be % |\seq_test_in:cV|. Now this code fragment will be simply: % \begin{verbatim} -% \seq_test_in:cV {sym#3} \l_group_seq +% \seq_test_in:cV { sym #3 } \l_group_seq % \end{verbatim} % Note that, in addition to the lack of |\expandafter|, the space after % the~|}| will be silently ignored since all white space is ignored in % this programming environment. % -% % \subsection{New functions from old} -% \label{sec:newfunc} % % For many common functions the \LaTeX3 kernel will provide variants % with a range of argument forms, and similarly it is expected that @@ -616,18 +562,18 @@ % \TeX\ undelimited arguments. % % To illustrate this let us suppose you have a `base function' -% |\demo_cmd:nnn| that takes three normal arguments, and that you need +% |\demo_cmd:Nnn| that takes three normal arguments, and that you need % to construct the variant |\demo_cmd:cnx|, for which the first argument % is used to construct the \emph{name} of a command, whilst the third % argument must be fully expanded before being passed to -% |\demo_cmd:nnn|. +% |\demo_cmd:Nnn|. % To produce the variant form from the base form, simply use this: % \begin{verbatim} -% \cs_generate_variant:Nn \demo_cmd:nnn {cnx} +% \cs_generate_variant:Nn \demo_cmd:Nnn { cnx } % \end{verbatim} % This defines the variant form so that you can then write, for example: % \begin{verbatim} -% \demo_cmd:cnx {abc} {pq} {\rst \xyz } +% \demo_cmd:cnx { abc } { pq } { \rst \xyz } % \end{verbatim} % rather than \ldots\ well, something like this! % \begin{verbatim} @@ -655,142 +601,40 @@ % arguments 2 and~4 using~|\csname|. % The definition you need is simply % \begin{verbatim} -% \cs_generate_variant:Nn -% \demo_cmd_b:nnnnn {xcxcx} +% \cs_generate_variant:Nn \demo_cmd_b:nnnnn { xcxcx } % \end{verbatim} % % This extension mechanism is written so that if the same new form of % some existing command is implemented by two extension packages then the % two definitions will be identical and thus no conflict will occur. % +%\section{The distribution} % -% \section{Parameter assignments and accessor functions} -% \label{sec:access} -% -% \subsection{Checking assignments} -% \label{sec:check} -% -% One of the advantages of having a consistent scheme is that the system -% can provide more extensive error-checking and debugging facilities. -% For example, an accessor function that makes a \emph{global} -% assignment of a value to a parameter can check that it is not passed -% the name of a \emph{local} parameter as that argument: it does this by -% checking that the name starts with~|\g_|. -% -% Such checking is probably too slow for normal use, but the code can -% have hooks built in that allow a format to be made in which all -% functions perform this kind of check. -% -% A typical section of the source^^A -% \footnote{This code uses the \textsf{docstrip} -% system described in~\cite{A-W:GMS94}, Section~14.3.} -% for such code might look like this -% (recall that all white space is ignored): -% -% \begin{verbatim} -% %<*!check> -% \cs_new_eq:NN -% \toks_gset:Nn \tex_global:D -% %</!check> -% %<*check> -% \cs_new_nopar:Npn -% \toks_gset:Nn #1 -% { -% \chk_global:N #1 -% \tex_global:D #1 -% } -% %</check> -% \end{verbatim} -% In the above code the function |\toks_gset:Nn| takes a single -% token~(|N|) specifying a token register, and globally sets it to the -% value passed in the second argument. -% -% A typical use of it would be: -% \begin{verbatim} -% \toks_gset:Nn \g_xxx_toks {<some value>} -% \end{verbatim} -% In the normal definition, |\toks_gset:Nn| can be simply~|\let| -% to~|\global| because the primitive \TeX{} token register does not -% require any explicit assignment function: -% this is done by the |%<*!check>| code above. -% -% The alternative definition first checks that the argument -% passed as~|#1| is the name of a global parameter and raises an error -% if it is not. It does this by taking apart the command name passed -% as~|#1| and checking that it starts~|\g_|. -% -% \subsection{Consistency} -% \label{sec:cons} -% -% The primitive \TeX\ syntax for register assignments has a very minimal -% syntax and, apart from box functions, there are no explicit functions -% for assigning values to these registers. -% -% This makes it impossible to implement alternative data-types with a -% syntax that is both consistent and at all similar to the syntax for -% the primitives; moreover, it encourages a coding style that is very -% error prone. -% -% As in the |\toks_gset:Nn| example given above, all \LaTeX\ data-types -% are provided with explicit functions for assignment and for use, even -% when these have essentially empty definitions. This allows for better -% error-checking as described above; it also allows the construction of -% further data-types with a similar interface, even when the -% implementation of the associated functions is very complex. -% -% For example, the `fake-integer' (\texttt{num}) data-type mentioned -% above will appear at the \LaTeX{} programming level to be exactly like -% the data-type based on primitive count registers; however, internally -% it makes no use of count registers. Typical functions in this module -% are illustrated here. +% At present, the \pkg{expl3} modules are designed to be loaded on top +% of \LaTeXe. In time, a \LaTeX3 format will be produced based on this +% code. This allows the code to be used in \LaTeXe\ packages \emph{now} +% while a stand-alone \LaTeX3 is developed. % -% \begin{verbatim} -% \num_new:N \l_tmpa_num -% \end{verbatim} -% This declares the local parameter |\l_example_num| as a fake-counter. -% -% \begin{verbatim} -% \num_add:Nn \l_example_num \c_thirty_two -% \end{verbatim} -% This increments the value of this fake-counter by 32. -% -% -% \section{The experimental distribution} -% \label{sec:dist} -% -% The initial implementations of a \LaTeX\ programming language using -% this kind of syntax remain unreleased (and not completely functional); -% they partly pre-date \LaTeXe! The planned distribution will provide a -% subset of the functionality of those implementations, in the form of -% packages to be used on top of \LaTeXe. -% -% The intention is to allow experienced \TeX\ programmers to experiment -% with the system and to comment on the interface. This means that -% \textbf{\itshape the interface will change}. No part of this system, -% including the name of anything, should be relied upon as being -% available in a later release. Please do \emph{experiment} with these -% packages, but do \emph{not} use them for code that you expect to keep -% unchanged over a long period. -% -% In view of the intended experimental use for this distribution we -% shall, in the first instance, produce only a few modules for use with -% \LaTeXe. These will set up the conventions and the basic functionality -% of, for example, the expansion mechanism; they will also implement some -% of the basic programming constructs, such as token-lists and sequences. -% They are intended only to give a flavour of the code: the full \LaTeX3 -% kernel will provide a very rich set of programming constructs so that -% packages can efficiently share code, in contrast with the situation in -% the current \LaTeX\ where every large package must implement its own -% version of queues, stacks, etc., as necessary. -% -% At time of writing the \textsf{expl3} bundle consists of the -% following modules. -% -% This distribution will also contain the \LaTeX\ source for the latest -% version of this document, a docstrip install file and three small test -% files. -% -% \begin{description} +%\begin{bfseries} +% While \pkg{expl3} is still experimental, the bundle is now regarded +% as broadly stable. The syntax conventions and functions provided +% are now ready for wider use. There may still be changes to some +% functions, but these will be minor when compared to the scope of +% \pkg{expl3}. +%\end{bfseries} +% +% New modules will be added to the distributed version of \pkg{expl3} +% as they reach maturity. At present, the \pkg{expl3} bundle consists +% of a number of modules, most of which are loaded by including the +% line: +%\begin{verbatim} +% \RequirePackage{expl3} +%\end{verbatim} +% in a \LaTeXe\ package, class or other file. The \pkg{expl3} modules +% regarded as stable, and therefore suitable for basing real code on, +% are as follows: +% +%\begin{description} % \providecommand\explpkg[2]{\item[#1]#2} % \explpkg{l3basics}{ % This contains the basic definition modules used @@ -804,48 +648,45 @@ % \pkg{expl3} that provides extended methods for numeric and dimensional % calculations and assignments. % } -% \explpkg{l3chk}{ -% A module that provides functionality comparable to -% \LaTeX's \cmd{\newcommand} and \cmd{\renewcommand}, and also the -% extra level of -% checking for ensure internal consistency in the code. -% } % \explpkg{l3clist}{ % Methods for manipulating comma-separated token lists. % } % \explpkg{l3expan}{ -% This is the argument expansion module discussed above. +% This is the argument expansion module discussed earlier in this +% document. % } % \explpkg{l3int}{ % This implements the integer data-type \texttt{int}. % } +% \explpkg{l3intexpr}{ +% For carring out integer expression calculations and comparisons, +% whether the input is stored in \texttt{int}, \texttt{tl} or +% other variable types, or is given literally. +% } % \explpkg{l3io}{ % A module providing low level input and output functions. % } % \explpkg{l3keyval}{ -% A re-implementation of the \LaTeXe\ package \pkg{keyval}; -% provides low-level macros for dealing with lists of the form +% Low-level implementation for processing lists of the form % \texttt{\{ key1=val1 , key2=val2 \}}. % } -% \explpkg{l3messages/l3msg}{ -% Communicating with the user. +% \explpkg{l3keys}{ +% Higher-level implementation of key--value methods: intended to work +% as a \LaTeX3 version of \pkg{xkeyval}/\pkg{kvoptions}, although +% with input syntax more like that of \pkg{pgfkeys}. +% } +% \explpkg{l3msg}{ +% Communicating with the user: includes low-level hooks to allow +% messages to be filtered (higher-level interface for filtering +% to be written!). % } % \explpkg{l3names}{ % This sets up the basic naming scheme and renames all -% the \TeX\ primitives. If it is loaded with the option -% \texttt{[removeoldnames]} then the old primitive names such as~\cmd{\box} -% become \emph{undefined} and are thus available for user -% definition. Caution: use of this option will certainly break existing -% \TeX\ code! +% the \TeX\ primitives. % } % \explpkg{l3num}{ % This implements the `fake integer' datatype \texttt{num}. % } -% \explpkg{l3precom}{ -% A `pre-compilation' module that provides functions dealing with pointer -% creation and handling, and using external files to record the state of the current -% definitions. -% } % \explpkg{l3prg}{ % Program control structures such as boolean data type |bool|, generic % do-while loops, case-switches, sorting routines and stepwise loops. @@ -857,7 +698,7 @@ % \explpkg{l3quark}{ % A `quark' is a command that is defined to expand to % itself! Therefore they must never be expanded as this will generate -% infinite recursion; they do however have many uses, \eg as +% infinite recursion; they do however have many uses, e.g.~as % special markers and delimiters within code. % } % \explpkg{l3seq}{ @@ -880,11 +721,59 @@ % \explpkg{l3toks}{ % A data-type corresponding to \TeX's primitive token registers. % } -% \explpkg{l3xref}{ -% Data structure for low-level document cross-referencing. This -% provided the foundation for Heiko Oberdiek's \pkg{zref} package. -% } -% \end{description} +%\end{description} +% +%\section{Moving from \LaTeXe\ to \LaTeX3} +% +% To help programmers to use \LaTeX3 code in existing \LaTeXe\ package, +% some short notes on making the change are probably desirable. +% Suggestions for inclusion here are welcome! Some of the following +% is concerned with code, and some with coding style. +% +%\begin{itemize} +% \item \pkg{expl3} is mainly focussed on programming. This means that +% some areas still require the use of \LaTeXe\ internal macros. +% For example, you may well need \cs{@ifpackageloaded}, as there +% is currently no native \LaTeX3 package loading module. +% \item User level macros should be generated using the mechansim +% availble in the \pkg{xparse} package, which is available from CTAN +% or the \LaTeX3 SVN repository. +% \item At an internal level, most functions should be generated +% \cs{long} (using \cs{cs_new:Nn}) rather than `short' (using +% \cs{cs_new_nopar:Nn}). The exceptions are: +% \begin{itemize} +% \item Functions which take no arguments; +% \item Functions which are used with pre-set arguments which +% therefore cannot be \cs{long}: this is mainly the case with +% auxilliary functions. +% \end{itemize} +% \item Where possible, declare all variables and functions (using +% \cs{cs_new:NN}, \cs{tl_new:N}, etc.) before use. +% \item Prefer `higher-level' functions over `lower-level', where +% possible. So for example use \cs{cs_new:Nn} in preference to +% \cs{cs_new:Npn}, and \cs{cs_if_exist:N(TF)} over +% \cs{if_cs_exist:N}. +% \item Use space to make code readable. In general, we recommand +% a layout such as: +% \begin{verbatim} +% \cs_new:Nn \foo_bar:Nn { +% \cs_if_exist:NTF #1 { +% \foo_bar_aux_i:n {#2} +% }{ +% \foo_bar_aux_ii:nn {#2} { literal } +% } +% } +% \end{verbatim} +% where spaces are used around |{| and |}| except for isolated +% |#1|, |#2|, etc. +% \item Put different code items on separate lines: readablity is +% much more useful than compactness. +% \item Use long, descriptive names for functions and variables, +% and for auxilliary functions use the parent function name plus +% |aux|, |aux_i|, |aux_ii| and so on. +% \item If in doubt, ask the team via the LaTeX-L list: someone will +% soon get back to you! +%\end{itemize} % % \begin{thebibliography}{1} % @@ -925,7 +814,7 @@ {\filename}{\filedate}{\fileversion}{\filedescription} % \end{macrocode} % -% We already loaded \pkg{l3names} at the beginning of the \acro{dtx} file. +% We already loaded \pkg{l3names} at the beginning of the \texttt{dtx} file. % % The \pkg{l3chk} package is omitted since it is only used for conditional % processing with full error-checking turned on. Most users will generally @@ -957,6 +846,7 @@ \RequirePackage{ l3box, l3keyval, + l3keys, l3precom, l3calc, l3xref, diff --git a/Master/texmf-dist/source/latex/expl3/l3.ins b/Master/texmf-dist/source/latex/expl3/l3.ins index 9280d68eac5..d4b5bf9aeee 100644 --- a/Master/texmf-dist/source/latex/expl3/l3.ins +++ b/Master/texmf-dist/source/latex/expl3/l3.ins @@ -108,8 +108,9 @@ Do not distribute a modified version of this file. %% LaTeX3 calc module
\generate{\file{l3calc.sty}{\from{l3calc.dtx}{package}}}
-%% LaTeX3 keyval module
+%% LaTeX3 keyval modules
\generate{\file{l3keyval.sty}{\from{l3keyval.dtx}{package}}}
+\generate{\file{l3keys.sty}{\from{l3keys.dtx}{package}}}
%% LaTeX3 file loading
\generate{\file{l3file.sty}{\from{l3file.dtx}{package}}}
diff --git a/Master/texmf-dist/source/latex/expl3/l3clist.dtx b/Master/texmf-dist/source/latex/expl3/l3clist.dtx index f875b7e0cbc..adf2e659ba5 100644 --- a/Master/texmf-dist/source/latex/expl3/l3clist.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3clist.dtx @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3clist.dtx 1362 2009-05-28 20:19:21Z joseph $ +\GetIdInfo$Id: l3clist.dtx 1441 2009-08-05 19:23:23Z joseph $ {L3 Experimental comma separated lists} %\iffalse %<*driver> @@ -143,6 +143,15 @@ % Function that globally makes <clist1> identical to <clist2>. % \end{function} % +% +% \begin{function}{\clist_set_from_seq:NN|\clist_gset_from_seq:NN} +% \begin{syntax} +% "\clist_set_from_seq:NN" <clist> <seq> +% \end{syntax} +% Transforms sequence <seq> into comma-list variable <clist>. +% \end{function} +% +% % \section{Putting data in} % % \begin{function}{% @@ -559,7 +568,7 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} +% \end{macro} % % \begin{macro}{\clist_set_eq:NN} % \begin{macro}{\clist_set_eq:cN} @@ -594,6 +603,22 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\clist_set_from_seq:NN,\clist_gset_from_seq:NN} +% I hope this technique is more efficient than looping through each element +% and using "\clist_put_right:Nn" (Will). +% \begin{macrocode} +\cs_new:Npn \clist_set_from_seq_aux:NNN #1#2#3 { + \cs_set:Npn \seq_elt:w ##1 \seq_elt_end: ##2 { + \exp_not:n {##1} + \quark_if_nil:NF ##2 { , ##2 } + } + #1 #2 { #3 \q_nil } +} +\cs_new:Npn \clist_set_from_seq:NN { \clist_set_from_seq_aux:NNN \tl_set:Nx } +\cs_new:Npn \clist_gset_from_seq:NN { \clist_set_from_seq_aux:NNN \tl_gset:Nx } +% \end{macrocode} +% \end{macro} +% % \subsection{Predicates and conditionals} % % \begin{macro}{\clist_if_empty_p:N,\clist_if_empty_p:c} diff --git a/Master/texmf-dist/source/latex/expl3/l3keys.dtx b/Master/texmf-dist/source/latex/expl3/l3keys.dtx new file mode 100644 index 00000000000..e606f91f0a1 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3keys.dtx @@ -0,0 +1,1529 @@ +% \iffalse +%% File: l3keys.dtx Copyright (C) 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 ``expl3 bundle'' (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} +%</driver|package> +%\fi +\GetIdInfo$Id: l3keys.dtx 1441 2009-08-05 19:23:23Z joseph $ + {L3 Experimental key-value support} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass[full]{l3doc} +\begin{document} + \DocInput{l3keys.dtx} +\end{document} +%</driver> +% \fi +% +% \title{The \textsf{l3keys} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Key--value support} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +%\begin{documentation} +% +% The key--value method is a popular system for creating large numbers +% of settings for controlling function or package behaviour. For the +% user, the system normally results in input of the form +%\begin{verbatim} +% \PackageControlMacro{ +% key-one = value one, +% key-two = value two +% } +%\end{verbatim} +% or +%\begin{verbatim} +% \PackageMacro[ +% key-one = value one, +% key-two = value two +% ]{argument}. +%\end{verbatim} +% For the programmer, the original \pkg{keyval} package gives only +% the most basic interface for this work. All key macros have to be +% created one at a time, and as a result the \pkg{kvoptions} and +% \pkg{xkeyval} packages have been written to extend the ease of +% creating keys. A very different approach has been provided by +% the \pkg{pgfkeys} package, which uses a key--value list to +% generate keys. +% +% The \pkg{l3keys} package is aimed at creating a programming +% interface for key--value controls in \LaTeX3. Keys are +% created using a key--value interface, in a similar manner to +% \pkg{pgfkeys}. Each key is created by setting one or more +% \emph{properties} of the key: +%\begin{verbatim} +% \keys_define:nn { module } +% key-one .code:n = code including parameter #1, +% key-two .set = \l_module_store_tl +% } +%\end{verbatim} +% These values can then be set as with other key--value approaches: +%\begin{verbatim} +% \keys_set:nn { module } +% key-one = value one, +% key-two = value two +% } +%\end{verbatim} +% +% At a document level, \cs{keys_set:nn} is used within a +% document function. For \LaTeXe, a generic set up function could be +% created with +%\begin{verbatim} +% \newcommand*\SomePackageSetup[1]{% +% \@nameuse{keys_set:nn}{module}{#1}% +% } +%\end{verbatim} +% or to use key--value input as the optional argument for a macro: +%\begin{verbatim} +% \newcommand*\SomePackageMacro[2][]{% +% \begingroup +% \@nameuse{keys_set:nn}{module}{#1}% +% % Main code for \SomePackageMacro +% \endgroup +% } +%\end{verbatim} +% The same concepts using \pkg{xparse} for \LaTeX3 use: +%\begin{verbatim} +% \DeclareDocumentCommand \SomePackageSetup { m } { +% \keys_set:nn { module } { #1 } +% } +% \DeclareDocumentCommand \SomePackageMacro { o m } { +% \group_begin: +% \keys_set:nn { module } { #1 } +% % Main code for \SomePackageMacro +% \group_end: +% } +%\end{verbatim} +% +% Key names may contain any tokens, as they are handled internally +% using \cs{tl_to_str:n}. As will be discussed in +% section~\ref{sec:subdivision}, it is suggested that the character +% ``\texttt{/}'' is reserved for sub-division of keys into logical +% groups. Macros are \emph{not} expanded when creating key names, +% and so +%\begin{verbatim} +% \tl_set:Nn \l_module_tmp_tl { key } +% \keys_define:nn { module } { +% \l_module_tmp_tl .code:n = code +% } +%\end{verbatim} +% will create a key called \cs{l_module_tmp_tl}, and not one called +% \texttt{key}. +% +%\subsection{Creating keys} +% +%\begin{function}{\keys_define:nn} +% \begin{syntax} +% "\keys_define:nn" <module> <keyval list> +% \end{syntax} +% Parses the <keyval list> and defines the keys listed there for +% <module>. This function is designed for use in code, and therefore +% does not check the category codes of characters or ignore spaces. +%\end{function} +% +% Setting up and altering keys is carried out using one or more +% properties. The properties determine how a key acts, and may require +% zero, one or two argument: this is indicated by an argument specifier, +% in the same way as a standard \LaTeX3 function. If only a single +% argument is required, braces around \texttt{n} arguments can be +% omitted.\footnote{This is a general feature of key--value input +% methods.} +% +% +%\begin{function}{.bool:N} +% \begin{syntax} +% <key> .bool:N = <bool> +% \end{syntax} +% Defines <key> to set <bool> to <value> (which must be either +% \texttt{true} or \texttt{false}). +%\end{function} +% +%\begin{function}{.choice:} +% \begin{syntax} +% <key> .choice: +% \end{syntax} +% Sets <key> to act as a multiple choice key. Creating choices +% is discussed in section~\ref{sec:choice}. +%\end{function} +% +%\begin{function}{ +% .code:n| +% .code:x +% } +% \begin{syntax} +% <key> .code:n = <code> +% \end{syntax} +% Stores the <code> for execution when <key> is called. The <code> can +% include one parameter (|#1|), which will be the <value> given for the +% <key>. +%\end{function} +% +%\begin{function}{ +% .code:Nn| +% .code:Nx +% } +% \begin{syntax} +% <key> .code:Nn = <number> <code> +% \end{syntax} +% Stores the <code> for execution when <key> is called. The <code> can +% include <number> parameters, which can be in the standard \TeX\ +% range 0--9. If too few parameters are given when the key is used, +% sufficient empty groups will be supplied to prevent an error +% occurring. +%\end{function} +% +%\begin{function}{ +% .default:n| +% .default:V| +% } +% \begin{syntax} +% <key> .default:n = <default> +% \end{syntax} +% Creates a <default> value for <key>, which is used if no value is +% given. This will be used if only the key name is given, but not if +% a blank <value> is given: +% \begin{verbatim} +% \keys_define:nn { module } { +% key .code:n = Hello #1, +% key .default = World +% } +% \keys_set:nn { module} { +% key = Fred, % Prints "Hello Fred" +% key, % Prints "Hello World" +% key = , % Prints "Hello " +% } +% \end{verbatim} +% \begin{texnote} +% The <default> is stored as a token list variable. +% \end{texnote} +%\end{function} +% +%\begin{function}{.function:N} +% \begin{syntax} +% <key> .function:N = <function> +% \end{syntax} +% The input for <key> is used to define <function>, which internally +% uses \cs{cs_set:Nn}. The effect is the same as \texttt{<key> +% .code:n = \{ \cs{cs_set:Nn} <function> } |{#1}| \texttt{ \} }. +% The <function> should be an internal function, as the number of +% arguments is detected from the argument specifier. If the +% <function> is not defined, it is initialised to empty. +%\end{function} +% +%\begin{function}{ +% .generate_choices:nn| +% .generate_choices:nx| +% } +% \begin{syntax} +% <key> .generate_choices:nn = <comma list> <code> +% \end{syntax} +% Makes <key> a multiple choice key, accepting the choices specified +% in <comma list>. Each choice will execute <code> if it given. Within +% <code>, the name of the current choice is available as +% \cs{l_keys_choice_tl}, and its position in the <comma list> as +% \cs{l_keys_choice_int}. Multiple choices are discussed further in +% section~\ref{sec:choice}. +%\end{function} +% +%\begin{function}{ +% .initial:n| +% .initial:V +% } +% \begin{syntax} +% <key> .initial:n = <initial> +% \end{syntax} +% Sets <key> using the <initial> value given. This can only be given +% after the<key> is created. +%\end{function} +% +%\begin{function}{.meta:n} +% \begin{syntax} +% <key> .meta:n = <keys> +% \end{syntax} +% Makes <key> a meta-key, which will set several other <keys> in +% one go. If <key> is given with a value, it is passed through to +% the subsidiary <keys> for processing. +%\end{function} +% +%\begin{function}{ +% .set:N| +% .set_x:N +%} +% \begin{syntax} +% <key> .set:N = <variable> +% \end{syntax} +% Defines <key> to store the value given in <variable>. The type and +% scope (local or global) of <variable> are determined from the +% name. The \texttt{x} version performs an expanded assignment. For +% example +% \begin{verbatim} +% \keys_define:nn { module } { +% key-one .set:N = \l_module_tmpa_tl, % Locally sets a tl var. +% key_two .set:N = \g_module_tmpa_toks % Globally sets a toks +% } +% \keys_set:nn { module } { +% key-one = Value, % \l_module_tmpa_tl contains "Value" +% key-two = Stuff % \g_module_tmpa_toks contains "Stuff" +% } +% \end{verbatim} +% Assignments are automatically global for global variables. +% +% A \cs{<variable>_set:Nn} function must exist to allow setting of the +% <variable>. An error will result if this is not the case. The +% \texttt{.set_x:N} version can only be applied to variable types which +% have a \cs{<variable>_set:Nx} function: other cases will result in an +% error. +%\end{function} +% +%\begin{function}{ +% .value_forbidden:| +% .value_required:| +% } +% \begin{syntax} +% <key> .value_forbidden: +% \end{syntax} +% Flags for forbidding and requiring a <value> for <key>. Any <value> +% given will be ignored. +%\end{function} +% +%\subsection{Sub-dividing keys} +%\label{sec:subdivision} +% +% When creating large numbers of keys, it may be desirable to divide +% them into several sub-groups for a given module. This can be achieved +% either by adding a sub-division to the module name: +%\begin{verbatim} +% \keys_define:nn { module / subgroup } { +% key .code:n = code +% } +%\end{verbatim} +% or to the key name: +%\begin{verbatim} +% \keys_define:nn { module } { +% subgroup / key .code:n = code +% } +%\end{verbatim} +% As illustrated, the best choice of token for sub-dividing keys in +% this way is ``\texttt{/}''. This is because of the method that is +% used to represent keys internally. Both of the above code fragments +% set the same key, which has full name \texttt{module/subgroup/key}. +% +% As will be illustrated in the next section, this subdivision is +% particularly relevant to making multiple choices. +% +%\subsection{Multiple choices} +%\label{sec:choice} +% +% Multiple choices are created by setting the \texttt{.choice:} +% property: +%\begin{verbatim} +% \keys_define:nn { module } { +% key .choice: +% } +%\end{verbatim} +% For keys which are set up as choices, the valid choices are generated +% by creating sub-keys of the choice key. This can be carried out in +% two ways. +% +% In many cases, choices execute similar code which is dependant only +% on the name of the choice or the position of the choice in the +% list of choices. Here, the keys can share the same code, and can +% be rapidly created using the \texttt{.generate_choices:nn} +% property: +%\begin{verbatim} +% \keys_define:nn { module } { +% key .generate_choices:nn = { +% choice-a, choice-b, choice-c +% } { +% You~gave~choice~``\l_keys_choice_tl'',~ +% which~is~in~position~\l_keys_choice_int +% \~in~the~list. +% } +% } +%\end{verbatim} +% +%\begin{variable}{ +% \l_keys_choice_tl| +% \l_keys_choice_int| +%} +% Inside the code block, the variables \cs{l_keys_choice_tl} and +% \cs{l_keys_choice_int} are available to indicate the name of the +% current choice, and its position in the comma list. The position +% is indexed from \(1\). +%\end{variable} +% +% On the other hand, it is sometimes useful to create choices which +% use entirely different code from one another. This can be achieved +% by setting the \texttt{.choice:} property of a key, then manually +% defining sub-keys. +%\begin{verbatim} +% \keys_define:nn { module } { +% key choices:n, +% key / choice-a .code:n = code-a, +% key / choice-b .code:n = code-b, +% key / choice-c .code:n = code-c, +% } +%\end{verbatim} +% +% It is possible to mix the two methods, but manually-created choices +% should \emph{not} use \cs{l_keys_choice_tl} or \cs{l_keys_choice_int}. +% +%\subsection{Setting keys} +% +%\begin{function}{ +% \keys_set:nn| +% \keys_set:nV| +% \keys_set:nv +%} +% \begin{syntax} +% "\keys_set:nn" <module> <keyval list> +% \end{syntax} +% Parses the <keyval list>, and sets those keys which are defined +% for <module>. The behaviour on finding an unknown key can be +% set by defining a special \texttt{unknown} key: this will be +% illustrated later. In contrast to \cs{keys_define:nn}, this function +% does check category codes and ignore spaces, and is therefore +% suitable for user input. +%\end{function} +% +% If a key is not known, \cs{keys_set:nn} will look for a special +% \texttt{unknown} key for the same module. This mechanism can be +% used to create new keys from user input. +%\begin{verbatim} +% \keys_define:nn { module } { +% unknown .code:n = +% You~tried~to~set~key~`\l_keys_path_tl'~to~`#1' +% } +%\end{verbatim} +% +%\begin{variable}{\l_keys_key_tl} +% When processing an unknown key, the name of the key is available +% as \cs{l_keys_key_tl}. Note that this will have been processed +% using \cs{tl_to_str:N}. The value passed to the key (if any) is +% available as the macro parameter |#1|. +%\end{variable} +% +%\subsection{Examining keys: internal representation} +% +%\begin{function}{\keys_show:nn} +% \begin{syntax} +% "\keys_show:nn" <module> <key> +% \end{syntax} +% Shows the internal representation of a <key>. The function which +% executes a <key> is called \cs{keys > <module>/<key>.cmd:w}. +%\end{function} +% +%\subsection{Internal functions} +% +%\begin{function}{\keys_arguments_tidy:w} +% \begin{syntax} +% "\keys_arguments_tidy:w " <args> "\q_keys_stop" +% \end{syntax} +% Clears <args> from the stack: used to clean up after executing a +% key. +%\end{function} +% +%\begin{function}{ +% \keys_bool_set:N | +% \keys_bool_set_inverse:N +%} +% \begin{syntax} +% "\keys_bool_set:N" <bool> +% \end{syntax} +% Creates code to set <bool> when <key> is given. +%\end{function} +% +%\begin{function}{\keys_choice_make:} +% \begin{syntax} +% "\keys_choice_make:" +% \end{syntax} +% Makes <key> a choice key. +%\end{function} +% +%\begin{function}{\keys_choices_generate:nx} +% \begin{syntax} +% "\keys_choices_generate:nx" <comma list> <code> +% \end{syntax} +% Makes <comma list> choices for <key>, each using <code>. +%\end{function} +% +%\begin{function}{\keys_choice_find:n} +% \begin{syntax} +% "\keys_choice_find:n" <choice> +% \end{syntax} +% Searches for <choice> as a sub-key of <key>. +%\end{function} +% +%\begin{function}{ +% \keys_cmd_set:nNn | +% \keys_cmd_set:nNx +%} +% \begin{syntax} +% "\keys_cmd_set:nNn" <path> <num args> <code> +% \end{syntax} +% Creates a function for <path>, taking <num args> and using <code>. +%\end{function} +% +%\begin{function}{ +% \keys_default_set:n | +% \keys_default_set:V +%} +% \begin{syntax} +% "\keys_default_set:n" <default> +% \end{syntax} +% Sets <default> for <key>. +%\end{function} +% +%\begin{function}{ +% \keys_define_elt:n | +% \keys_define_elt:nn +%} +% \begin{syntax} +% "\keys_define_elt:n" <key> <value> +% \end{syntax} +% Processing functions for key--value pairs when defining keys. +%\end{function} +% +%\begin{function}{\keys_define_key:n} +% \begin{syntax} +% "\keys_define_key:n" <key> +% \end{syntax} +% Defines <key>. +%\end{function} +% +%\begin{function}{\keys_execute:} +% \begin{syntax} +% "\keys_execute:" +% \end{syntax} +% Executes <key>. +%\end{function} +% +%\begin{function}{\keys_execute_unknown:} +% \begin{syntax} +% "\keys_execute_unknown:" +% \end{syntax} +% Handles unknown <key> names. +%\end{function} +% +%\begin{function}{\keys_if_value_requirement:nTF} +% \begin{syntax} +% "\keys_if_value_requirement:nTF" <requirement> +% ~~~~<true code> <false code> +% \end{syntax} +% Check if <requirement> applies to <key>. +%\end{function} +% +%\begin{function}{ +% \keys_initial_value:n | +% \keys_initial_value:V +%} +% \begin{syntax} +% "\keys_initial_value:n" <value> +% \end{syntax} +% Sets <value> as initial contents for <key>. +%\end{function} +% +%\begin{function}{\keys_meta_make:n} +% \begin{syntax} +% "\keys_meta_make:n" <keys> +% \end{syntax} +% Makes <key> a meta-key to set <keys>. +%\end{function} +% +%\begin{function}{\keys_property_find:n} +% \begin{syntax} +% "\keys_property_find:n" <key> +% \end{syntax} +% Separates <key> from <property>. +%\end{function} +% +%\begin{function}{\keys_property_new:nn} +% \begin{syntax} +% "\keys_property_new:nn" <property> <code> +% \end{syntax} +% Makes a new <property> expanding to <code> +%\end{function} +% +%\begin{function}{\keys_property_undefine:n} +% \begin{syntax} +% "\keys_property_undefine:n" <property> +% \end{syntax} +% Deletes <property> of <key>. +%\end{function} +% +%\begin{function}{ +% \keys_set_elt:n | +% \keys_set_elt:nn +%} +% \begin{syntax} +% "\keys_set_elt:n" <key> <value> +% \end{syntax} +% Processing functions for key--value pairs when setting keys. +%\end{function} +% +%\begin{function}{\keys_tmp:w} +% \begin{syntax} +% "\keys_tmp:w" <args> +% \end{syntax} +% Used to store <code> to execute a <key>. +%\end{function} +% +%\begin{function}{\keys_value_or_default:n} +% \begin{syntax} +% "\keys_value_or_default:n" <value> +% \end{syntax} +% Sets \cs{l_keys_value_toks} to <value>, or <default> if +% <value> was not given and if <default> is available. +%\end{function} +% +%\begin{function}{\keys_value_requirement:n} +% \begin{syntax} +% "\keys_value_requirement:nn" <requirement> +% \end{syntax} +% Sets <key> to have <requirement> concerning <value>. +%\end{function} +% +%\begin{function}{\keys_variable_set:NN} +% \begin{syntax} +% "\keys_variable_set:NN" <expansion> <var> +% \end{syntax} +% Sets <key> to assign <value> to <variable> +%\end{function} +% +%\begin{function}{ +% \keys_variable_get_scope:N / (EXP) | +% \keys_variable_get_type:N / (EXP) +%} +% \begin{syntax} +% "\keys_variable_get_scope:N" <var> +% \end{syntax} +% Returns the scope (\texttt{g} or blank) or the type of <var>. +%\end{function} +% +%\subsection{Variables and constants} +% +%\begin{variable}{ +% \c_keys_properties_root_tl| +% \c_keys_root_tl +%} +% The root paths for keys and properties. +%\end{variable} +% +%\begin{variable}{ +% \c_keys_value_forbidden_tl| +% \c_keys_value_required_tl +%} +% Marker text containers. +%\end{variable} +% +%\begin{variable}{ +% \l_keys_module_tl| +% \l_keys_path_tl| +% \l_keys_property_tl +%} +% Various key paths need to be stored. +%\end{variable} +% +%\begin{variable}{ +% \l_keys_nesting_seq| +% \l_keys_nesting_tl +%} +% To allow safe nesting of \cs{keys_define:nn} and \cs{keys_set:nn}. +%\end{variable} +% +%\begin{variable}{\l_keys_no_value_bool} +% A marker for ``no value'' as key input. +%\end{variable} +% +%\begin{variable}{\l_keys_value_toks} +% Holds the currently supplied value. +%\end{variable} +% +%\begin{variable}{\q_keys_stop} +% A quark for delimiting arguments. +%\end{variable} +% +%\end{documentation} +% +%\begin{implementation} +% +% The usual preliminaries. +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> +%<*initex|package> +% \end{macrocode} +% +%\subsubsection{Variables and constants} +% +%\begin{macro}{\c_keys_root_tl} +%\begin{macro}{\c_keys_properties_root_tl} +% Where the keys are really stored. +% \begin{macrocode} +\tl_new:Nn \c_keys_root_tl { keys~>~ } +\tl_new:Nn \c_keys_properties_root_tl { keys_properties } +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\c_keys_value_forbidden_tl} +%\begin{macro}{\c_keys_value_required_tl} +% Two marker token lists. +% \begin{macrocode} +\tl_new:Nn \c_keys_value_forbidden_tl { forbidden } +\tl_new:Nn \c_keys_value_required_tl { required } +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\l_keys_choice_int} +%\begin{macro}{\l_keys_choice_tl} +% Used for the multiple choice system. +% \begin{macrocode} +\int_new:N \l_keys_choice_int +\tl_new:N \l_keys_choice_tl +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\l_keys_key_tl} +%\begin{macro}{\l_keys_path_tl} +%\begin{macro}{\l_keys_property_tl} +% Storage for the current key name and the path of the key (key name +% plus module name). +% \begin{macrocode} +\tl_new:N \l_keys_key_tl +\tl_new:N \l_keys_path_tl +\tl_new:N \l_keys_property_tl +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\l_keys_module_tl} +% The module for an entire set of keys. +% \begin{macrocode} +\tl_new:N \l_keys_module_tl +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_keys_nesting_seq} +%\begin{macro}{\l_keys_nesting_tl} +% For nesting. +% \begin{macrocode} +\seq_new:N \l_keys_nesting_seq +\tl_new:Nn \l_keys_nesting_tl { none } +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\l_keys_no_value_bool} +% To indicate that no value has been given. +% \begin{macrocode} +\bool_new:N \l_keys_no_value_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_keys_value_toks} +% A token register for the given value. +% \begin{macrocode} +\toks_new:N \l_keys_value_toks +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\q_keys_stop} +% A quark for delimiting keys: no one else should use it! +% \begin{macrocode} +\quark_new:N \q_keys_stop +% \end{macrocode} +%\end{macro} +% +%\subsubsection{Internal functions} +% +%\begin{macro}{\keys_arguments_tidy:w} +% So that nothing runs away, a safety precaution is taken in the code. +% \begin{macrocode} +\cs_new:Npn \keys_arguments_tidy:w #1 \q_keys_stop { } +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_bool_set:N} +%\begin{macro}{\keys_bool_set_inverse:N} +%\begin{macro}[aux]{\keys_bool_set_aux:N} +% Boolean keys are really just choices, but all done by hand. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_bool_set:N { + \keys_cmd_set:nNx { \l_keys_path_tl / true } 1 { + \exp_not:c { bool_ \keys_variable_get_scope:N #1 set_true:N } + \exp_not:N #1 + } + \keys_cmd_set:nNx { \l_keys_path_tl / false } 1 { + \exp_not:N \use:c + { bool_ \keys_variable_get_scope:N #1 set_false:N } + \exp_not:N #1 + } + \keys_bool_set_aux:N #1 +} +\cs_new_nopar:Nn \keys_bool_set_inverse:N { + \keys_cmd_set:nNx { \l_keys_path_tl / true } 1 { + \exp_not:c { bool_ \keys_variable_get_scope:N #1 set_false:N } + \exp_not:N #1 + } + \keys_cmd_set:nNx { \l_keys_path_tl / false } 1 { + \exp_not:c { bool_ \keys_variable_get_scope:N #1 set_true:N } + \exp_not:N #1 + } + \keys_bool_set_aux:N #1 +} +\cs_new_nopar:Nn \keys_bool_set_aux:N { + \keys_choice_make: + \cs_if_exist:NF #1 { + \bool_new:N #1 + } + \keys_default_set:n { true } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_choice_find:n} +% Executing a choice has two parts. First, try the choice given, then +% if that fails call the unknown key. That will exist, as it is created +% when a choice is first made. So there is no need for any escape code. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_choice_find:n { + \keys_execute_aux:nn { \l_keys_path_tl / #1 } { + \keys_execute_aux:nn { \l_keys_path_tl / unknown } { } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_choice_make:} +% To make a choice from a key, two steps: set the code, and set the +% unknown key. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_choice_make: { + \keys_cmd_set:nNn { \l_keys_path_tl } 1 { + \keys_choice_find:n {##1} + } + \keys_cmd_set:nNn { \l_keys_path_tl / unknown } 1 { + \msg_kernel_error:nxx { key-choice-unknown } { \l_keys_path_tl } + {##1} + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_choices_generate:nx} +%\begin{macro}[aux]{\keys_choices_generate_aux:n} +% Creating multiple-choices means setting up the ``indicator'' code, +% then applying whatever the user wanted. +% \begin{macrocode} +\cs_new:Nn \keys_choices_generate:nx { + \keys_choice_make: + \int_zero:N \l_keys_choice_int + \cs_set_nopar:Nn \keys_choices_generate_aux:n { + \int_incr:N \l_keys_choice_int + \keys_cmd_set:nNx { \l_keys_path_tl / ##1 } 1 { + \exp_not:n { \tl_set:Nn \l_keys_choice_tl } {##1} + \exp_not:n { \int_set:Nn \l_keys_choice_int } + { \int_use:N \l_keys_choice_int } + #2 + } + } + \clist_map_function:nN {#1} \keys_choices_generate_aux:n +} +\cs_new_nopar:Nn \keys_choices_generate_aux:n { } +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_cmd_set:nNn} +%\begin{macro}{\keys_cmd_set:nNx} +%\begin{macro}[aux]{\keys_cmd_set_aux:nN} +% Creating a new command means setting properties and then creating +% a function with the correct number of arguments. +% \begin{macrocode} +\cs_new:Nn \keys_cmd_set:nNn { + \keys_cmd_set_aux:nN {#1} #2 + \cs_generate_from_arg_count:cNnn { \c_keys_root_tl #1 .cmd:w } + \cs_set:Npn #2 { #3 \keys_arguments_tidy:w } +} +\cs_new:Nn \keys_cmd_set:nNx { + \keys_cmd_set_aux:nN {#1} #2 + \cs_generate_from_arg_count:cNnn { \c_keys_root_tl #1 .cmd:w } + \cs_set:Npx #2 { #3 \exp_not:N \keys_arguments_tidy:w } +} +\cs_new_nopar:Nn \keys_cmd_set_aux:nN { + \keys_property_undefine:n { #1 .default_tl } + \num_set:cn { \c_keys_root_tl #1 .args_num } {#2} + \tl_set:cn { \c_keys_root_tl #1 .req_tl } { } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_default_set:n} +%\begin{macro}{\keys_default_set:V} +% Setting a default value is easy. +% \begin{macrocode} +\cs_new:Nn \keys_default_set:n { + \tl_set:cn { \c_keys_root_tl \l_keys_path_tl .default_tl } {#1} +} +\cs_generate_variant:Nn \keys_default_set:n { V } +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_define:nn} +% The main key-defining function mainly sets up things for \pkg{l3keyval} +% to use. +% \begin{macrocode} +\cs_new:Nn \keys_define:nn { + \tl_set:Nn \l_keys_module_tl {#1} + \cs_set_eq:NN \KV_key_no_value_elt:n \keys_define_elt:n + \cs_set_eq:NN \KV_key_value_elt:nn \keys_define_elt:nn + \seq_push:NV \l_keys_nesting_seq \l_keys_nesting_tl + \tl_set:Nn \l_keys_nesting_tl { define } + \KV_parse_no_space_removal_no_sanitize:n {#2} + \seq_pop:NN \l_keys_nesting_seq \l_keys_nesting_tl + \cs_set_eq:Nc \KV_key_no_value_elt:n + { keys_ \l_keys_nesting_tl _elt:n } + \cs_set_eq:Nc \KV_key_value_elt:nn + { keys_ \l_keys_nesting_tl _elt:nn } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_define_elt:n} +%\begin{macro}{\keys_define_elt:nn} +% The element processors for defining keys. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_define_elt:n { + \bool_set_true:N \l_keys_no_value_bool + \keys_define_elt_aux:nn {#1} { } +} +\cs_new:Nn \keys_define_elt:nn { + \bool_set_false:N \l_keys_no_value_bool + \keys_define_elt_aux:nn {#1} {#2} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\begin{macro}[aux]{\keys_define_elt_aux:nn} +% The auxiliary function does most of the work. +% \begin{macrocode} +\cs_new:Nn \keys_define_elt_aux:nn { + \keys_property_find:n {#1} + \cs_set_eq:Nc \keys_tmp:w + { \c_keys_properties_root_tl \l_keys_property_tl } + \cs_if_exist:NTF \keys_tmp:w { + \keys_define_key:n {#2} + }{ + \msg_kernel_error:nx { key-property-unknown } + { \l_keys_property_tl } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_define_key:n} +% Defining a new key means finding the code for the appropriate +% property then running it. As properties have signatures, a check +% can be made for required values without needing anything set +% explicitly. +% \begin{macrocode} +\cs_new:Nn \keys_define_key:n { + \bool_if:NTF \l_keys_no_value_bool { + \intexpr_compare:nTF { + \exp_args:Nc \cs_get_arg_count_from_signature:N + { \l_keys_property_tl } = \c_zero + } { + \keys_tmp:w \q_keys_stop + }{ + \msg_kernel_error:nx { key-property-value-required } + { \l_keys_property_tl } + } + }{ + \intexpr_compare:nTF { + \exp_args:Nc \cs_get_arg_count_from_signature:N + { \l_keys_property_tl } = \c_one + } { + \keys_tmp:w {#1} \q_keys_stop + }{ + \keys_tmp:w #1 { } { } { } { } { } { } { } { } { } \q_keys_stop + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_execute:} +%\begin{macro}{\keys_execute_unknown:} +%\begin{macro}[aux]{\keys_execute_aux:nn} +% Actually executing a key is done in two parts. First, look for the +% key itself, then look for the \texttt{unknown} key with the same +% path. If both of these fail, complain! +% \begin{macrocode} +\cs_new_nopar:Nn \keys_execute: { + \keys_execute_aux:nn { \l_keys_path_tl } { + \keys_execute_unknown: + } +} +\cs_new_nopar:Nn \keys_execute_unknown: { + \keys_execute_aux:nn { \l_keys_module_tl / unknown } { + \msg_kernel_error:nx { key-unknown } { \l_keys_path_tl } + } +} +% \end{macrocode} +% If there is only one argument required, it is wrapped in braces so +% that everything is passed through properly. On the other hand, if more +% than one is needed it is down to the user to have put things in +% correctly! The use of \cs{q_keys_stop} here means that arguments +% do not run away (hence the nine empty groups), but that the module +% can clean up the spare groups at the end of executing the key. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_execute_aux:nn { + \cs_set_eq:Nc \keys_tmp:w { \c_keys_root_tl #1 .cmd:w } + \cs_if_exist:NTF \keys_tmp:w { + \intexpr_compare:nTF { + \num_use:c { \c_keys_root_tl #1 .args_num } = \c_one + } { + \exp_args:NV \keys_tmp:w \l_keys_value_toks \q_keys_stop + }{ + \exp_after:wN \keys_tmp:w \toks_use:N \l_keys_value_toks + { } { } { } { } { } { } { } { } { } \q_keys_stop + } + }{ + #2 + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_if_value_requirement:nTF} +% To test if a value is required or forbidden. Only one version is +% needed, so done by hand. +% \begin{macrocode} +\cs_new_nopar:Npn \keys_if_value_requirement:nTF #1 { + \tl_if_eq:ccTF { c_keys_value_ #1 _tl } { + \c_keys_root_tl \l_keys_path_tl .req_tl + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_initial_value:n} +%\begin{macro}{\keys_initial_value:V} +% Pretty easy to set initial values. +% \begin{macrocode} +\cs_new:Nn \keys_initial_value:n { + \toks_set:Nn \l_keys_value_toks {#1} + \keys_execute_aux:nn { \l_keys_path_tl } { + \msg_kernel_error:nx { key-initial-without-code } + { \l_keys_path_tl } + } +} +\cs_generate_variant:Nn \keys_initial_value:n { V } +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_meta_make:n} +% To create a met-key, simply set up to pass data through. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_meta_make:n { + \keys_cmd_set:nNx { \l_keys_path_tl } 1 { + \exp_not:N \keys_set:nn { \l_keys_module_tl } {#1} + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_property_find:n} +%\begin{macro}[aux]{\keys_property_find_aux:n} +%\begin{macro}[aux]{\keys_property_find_aux:w} +% Searching for a property means finding the last ``\texttt{.}'' in +% the input, and storing the text before and after it. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_property_find:n { + \tl_set:Nx \l_keys_path_tl { \l_keys_module_tl / } + \tl_if_in:nnTF {#1} {.} { + \keys_property_find_aux:n {#1} + }{ + \msg_kernel_error:nx { key-no-property } { #1 } + } +} +\cs_new_nopar:Nn \keys_property_find_aux:n { + \keys_property_find_aux:w #1 \q_stop +} +\cs_new_nopar:Npn \keys_property_find_aux:w #1 . #2 \q_stop { + \tl_if_in:nnTF {#2} {.} { + \tl_set:Nx \l_keys_path_tl { + \l_keys_path_tl \tl_to_str:n {#1} . + } + \keys_property_find_aux:w #2 \q_stop + }{ + \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl \tl_to_str:n {#1} } + \tl_set:Nn \l_keys_property_tl { . #2 } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_property_new:nn} +% Creating a new property is simply a case of making the correctly-named +% function. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_property_new:nn { + \cs_new:cn { \c_keys_properties_root_tl #1 } + { #2 \keys_arguments_tidy:w } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_property_undefine:n} +% Removing a property means undefining it. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_property_undefine:n { + \cs_set_eq:cN { \c_keys_root_tl #1 } \c_undefined +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_set:nn} +%\begin{macro}{\keys_set:nV} +%\begin{macro}{\keys_set:nv} +% The main setting function just does the set up to get \pkg{l3keyval} +% to do the hard work. +% \begin{macrocode} +\cs_new:Nn \keys_set:nn { + \tl_set:Nn \l_keys_module_tl {#1} + \cs_set_eq:NN \KV_key_no_value_elt:n \keys_set_elt:n + \cs_set_eq:NN \KV_key_value_elt:nn \keys_set_elt:nn + \seq_push:NV \l_keys_nesting_seq \l_keys_nesting_tl + \tl_set:Nn \l_keys_nesting_tl { set } + \KV_parse_space_removal_sanitize:n {#2} + \seq_pop:NN \l_keys_nesting_seq \l_keys_nesting_tl + \cs_set_eq:Nc \KV_key_no_value_elt:n + { keys_ \l_keys_nesting_tl _elt:n } + \cs_set_eq:Nc \KV_key_value_elt:nn + { keys_ \l_keys_nesting_tl _elt:nn } +} +\cs_generate_variant:Nn \keys_set:nn { nV, nv } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_set_elt:n} +%\begin{macro}{\keys_set_elt:nn} +% The two element processors are almost identical, and pass the data +% through to the underlying auxiliary, which does the work. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_set_elt:n { + \bool_set_true:N \l_keys_no_value_bool + \keys_set_elt_aux:nn {#1} { } +} +\cs_new:Nn \keys_set_elt:nn { + \bool_set_false:N \l_keys_no_value_bool + \keys_set_elt_aux:nn {#1} {#2} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\begin{macro}[aux]{\keys_set_elt_aux:nn} +%\begin{macro}[aux]{\keys_set_elt_aux:} +% First, set the current path and add a default if needed. There are +% then checks to see if the a value is required or forbidden. If +% everything passes, move on to execute the code. +% \begin{macrocode} +\cs_new:Nn \keys_set_elt_aux:nn { + \tl_set:Nx \l_keys_key_tl { \tl_to_str:n {#1} } + \tl_set:Nx \l_keys_path_tl { \l_keys_module_tl / \l_keys_key_tl } + \keys_value_or_default:n {#2} + \keys_if_value_requirement:nTF { required } { + \bool_if:NTF \l_keys_no_value_bool { + \msg_kernel_error:nx { key~value~required } { \l_keys_path_tl } + }{ + \keys_set_elt_aux: + } + }{ + \keys_set_elt_aux: + } +} +\cs_new_nopar:Nn \keys_set_elt_aux: { + \keys_if_value_requirement:nTF { forbidden } { + \bool_if:NTF \l_keys_no_value_bool { + \keys_execute: + }{ + \msg_kernel_error:nxx { key-value-forbidden } { \l_keys_path_tl } + { \toks_use:N \l_keys_value_toks } + } + }{ + \keys_execute: + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_show:nn} +% Showing a key is just a question of using the correct name. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_show:nn { + \cs_show:c { \c_keys_root_tl #1 / \tl_to_str:n {#2} .cmd:w } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_tmp:w} +% This scratch function is used to actually execute keys. +% \begin{macrocode} +\cs_new:Npn \keys_tmp:w {} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_value_or_default:n} +% If a value is given, return it as |#1|, otherwise send a default if +% available. +% \begin{macrocode} +\cs_new:Nn \keys_value_or_default:n { + \toks_set:Nn \l_keys_value_toks {#1} + \bool_if:NT \l_keys_no_value_bool { + \cs_if_exist:cT { \c_keys_root_tl \l_keys_path_tl .default_tl } { + \toks_set:Nv \l_keys_value_toks { + \c_keys_root_tl \l_keys_path_tl .default_tl + } + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_value_requirement:n} +% Values can be required or forbidden by having the appropriate marker +% set. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_value_requirement:n { + \tl_set_eq:cc { \c_keys_root_tl \l_keys_path_tl .req_tl } + { c_keys_value_ #1 _tl } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_variable_get_scope:N} +%\begin{macro}[aux]{\keys_variable_get_scope_aux:w} +%\begin{macro}{\keys_variable_get_type:N} +%\begin{macro}[aux]{\keys_variable_get_type:w} +% Expandable functions to find the type of a variable, and to +% return \texttt{g} if the variable is global. The trick for +% \cs{keys_variable_get_scope:N} is the same as that in +% \cs{cs_split_function:NN}, but it can be simplified as the +% requirements here are less complex. +% \begin{macrocode} +\group_begin: + \char_set_lccode:nn {`\&} {`\g} + \char_make_other:N \& +\tl_to_lowercase:n { + \group_end: + \cs_new_nopar:Nn \keys_variable_get_scope:N { + \exp_last_unbraced:Nf \keys_variable_get_scope_aux:w + { \cs_to_str:N #1 \exp_stop_f: \q_nil } + } + \cs_new_nopar:Npn \keys_variable_get_scope_aux:w #1#2 \q_nil { + \token_if_eq_meaning:NNT & #1 {g} + } +} +\group_begin: + \char_set_lccode:nn {`\&} {`\_} + \char_make_other:N \& +\tl_to_lowercase:n { + \group_end: + \cs_new_nopar:Nn \keys_variable_get_type:N { + \exp_after:wN \keys_variable_get_type_aux:w + \token_to_str:N #1 & a \q_nil + } + \cs_new_nopar:Npn \keys_variable_get_type_aux:w #1 & #2#3 \q_nil { + \token_if_eq_meaning:NNTF a #2 { + #1 + }{ + \keys_variable_get_type_aux:w #2#3 \q_nil + } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\keys_variable_set:NN} +% To set a variable, there is first a check so that it must exist. +% The setting function is then created by recovering the type and +% scope from the variable name. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_variable_set:NN { + \cs_if_exist:cF { + \keys_variable_get_type:N #2 _ + \keys_variable_get_scope:N #2 set:N #1 + } { + \msg_kernel_error:nxx { key-no-set-function } { + \exp_not:c { + \keys_variable_get_type:N #2 _ + \keys_variable_get_scope:N #2 set:N #1 + } + } {#2} + } + \cs_if_exist:NF #2 { + \use:c { \keys_variable_get_type:N #2 _new:N } #2 + } + \keys_cmd_set:nNx { \l_keys_path_tl } 1 { + \exp_not:c { + \keys_variable_get_type:N #2 _ + \keys_variable_get_scope:N #2 set:N #1 + } \exp_not:N #2 {##1} + } +} +% \end{macrocode} +%\end{macro} +% +%\subsubsection{Properties} +% +%\begin{macro}{.bool:N} +% One function for this. +% \begin{macrocode} +\keys_property_new:nn { .bool:N } { + \keys_bool_set:N #1 +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{.choice:} +% Making a choice is handled internally, as it is also needed by +% \texttt{.generate_choices:nn}. +% \begin{macrocode} +\keys_property_new:nn { .choice: } { + \keys_choice_make: +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{.code:n} +%\begin{macro}{.code:x} +%\begin{macro}{.code:Nn} +%\begin{macro}{.code:Nx} +% Creating code is simply a case of passing through to the underlying +% \texttt{set} function. +% \begin{macrocode} +\keys_property_new:nn { .code:n } { + \keys_cmd_set:nNn { \l_keys_path_tl } 1 {#1} +} +\keys_property_new:nn { .code:Nn } { + \keys_cmd_set:nNn { \l_keys_path_tl } #1 {#2} +} +\keys_property_new:nn { .code:x } { + \keys_cmd_set:nNx { \l_keys_path_tl } 1 {#1} +} +\keys_property_new:nn { .code:Nx } { + \keys_cmd_set:nNx { \l_keys_path_tl } #1 {#2} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{.default:n} +%\begin{macro}{.default:V} +% Expansion is left to the internal functions. +% \begin{macrocode} +\keys_property_new:nn { .default:n } { + \keys_default_set:n {#1} +} +\keys_property_new:nn { .default:V } { + \keys_default_set:V #1 +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{.function:N} +% Creating functions is pretty easy, so is done without an extra +% internal function. There is a check to ensure that the function is +% defined. +% \begin{macrocode} +\keys_property_new:nn { .function:N } { + \keys_cmd_set:nNn { \l_keys_path_tl } 1 { + \cs_set:Nn #1 {##1} + } + \cs_if_free:NT #1 { + \cs_set:Nn #1 { } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{.generate_choices:nn} +%\begin{macro}{.generate_choices:nx} +% Making choices is expansion-dependent. +% \begin{macrocode} +\keys_property_new:nn { .generate_choices:nn } { + \keys_choices_generate:nx {#1} { \exp_not:n {#2} } +} +\keys_property_new:nn { .generate_choices:nx } { + \keys_choices_generate:nx {#1} {#2} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{.initial:n} +%\begin{macro}{.initial:V} +% Sending things off as usual. +% \begin{macrocode} +\keys_property_new:nn { .initial:n } { + \keys_initial_value:n {#1} +} +\keys_property_new:nn { .initial:V } { + \keys_initial_value:V #1 +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{.meta:n} +% Making a meta is handled internally. +% \begin{macrocode} +\keys_property_new:nn { .meta:n } { + \keys_meta_make:n {#1} +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{.set:N} +%\begin{macro}{.set_x:N} +% Setting a variable is very easy: just pass the data along. +% \begin{macrocode} +\keys_property_new:nn { .set:N } { + \keys_variable_set:NN n #1 +} +\keys_property_new:nn { .set_x:N } { + \keys_variable_set:NN x #1 +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{.value_forbidden:} +%\begin{macro}{.value_required:} +% These are very similar, so both call the same function. +% \begin{macrocode} +\keys_property_new:nn { .value_forbidden: } { + \keys_value_requirement:n { forbidden } +} +\keys_property_new:nn { .value_required: } { + \keys_value_requirement:n { required } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\subsubsection{Messages} +% +% For when there is a need to complain. +% \begin{macrocode} +\msg_kernel_new:nn { key-choice-unknown } {% + Choice `#2' unknown for key `#1':\\% + the key is being ignored.% +} +\msg_kernel_new:nn { key-initial-without-code } {% + An initial value cannot be set for key `#1': + the key has not yet been created.% +} +\msg_kernel_new:nn { key-unknown } {% + The key `#1' is unknown and is being ignored.% +} +\msg_kernel_new:nn { key-value-forbidden }{% + The key `#1' cannot taken a value:\\% + the given input `#2' is being ignored.% +} +\msg_kernel_new:nn { key~value~required } {% + The key `#1' requires a value\\% + and is being ignored.% +} +\msg_kernel_new:nn { key-no-property } {% + No property given in definition of key `#1'.% +} +\msg_kernel_new:nnn { key-no-set-function } {% + There is no function #1\\% + for setting variable \exp_not:N #2.% +}{% + LaTeX can only `set' variables which have a function\\% + \exp_not:N \<var>_(g)set:Nn, or in some cases + \exp_not:N \<var>_(g)set:Nx.\\% + You have asked to `set' some other kind of variable.% + +} +\msg_kernel_new:nn { key-property-unknown } {% + The key property `#1' is unknown.% +} +\msg_kernel_new:nn { key-property-value-required } {% + The property `#1' requires a value\\% + and is being ignored.% +} +% \end{macrocode} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +%\end{implementation}
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/expl3/l3keyval.dtx b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx index 6af4faab0bc..79ea988459a 100644 --- a/Master/texmf-dist/source/latex/expl3/l3keyval.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx @@ -35,7 +35,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3keyval.dtx 1412 2009-06-14 17:55:48Z joseph $ +\GetIdInfo$Id: l3keyval.dtx 1424 2009-07-13 06:05:25Z joseph $ {L3 Experimental keyval processing} %\iffalse %<*driver> @@ -61,11 +61,10 @@ % % \begin{documentation} % -% \section{Introduction} -% -% Currently, this module only provides functions for extracting keys -% and values from a list. How this information is used is up to the -% programmer. +% This module only provides functions for extracting keys and values +% from a list. How this information is used is up to the programmer. +% The \pkg{l3keys} module provides a higher-level interface for +% managing run-time key--value input. % % A \meta{keyval list} is a list consisting of % \begin{verbatim} diff --git a/Master/texmf-dist/source/latex/expl3/l3msg.dtx b/Master/texmf-dist/source/latex/expl3/l3msg.dtx index 4eb211be1a6..b0a8b3891eb 100644 --- a/Master/texmf-dist/source/latex/expl3/l3msg.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3msg.dtx @@ -37,7 +37,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3msg.dtx 1362 2009-05-28 20:19:21Z joseph $ +\GetIdInfo$Id: l3msg.dtx 1423 2009-07-12 20:23:53Z joseph $ {L3 Experimental LaTeX Messages module} %\iffalse %<*driver> @@ -919,20 +919,20 @@ } \cs_set:Nn \msg_use_loop:n { \clist_if_in:NnTF \l_msg_redirect_classes_clist {#1} { - \msg_kernel_error:n { message~loop } + \msg_kernel_error:n { message-loop } }{ \clist_put_right:Nn \l_msg_redirect_classes_clist {#1} \cs_if_exist:cTF { msg_ ##1 :nnxx } { \use:c { msg_ ##1 :nnxx } {#3} {#4} {#5} {#6} }{ - \msg_kernel_error:nx { message~class~unknown } { ##1 } + \msg_kernel_error:nx { message-class-unknown } { ##1 } } } } \cs_if_exist:cTF { \c_msg_text_prefix_tl #3 / #4 :nn } { \msg_use_aux:nnn {#1} {#3} {#4} }{ - \msg_kernel_error:nxx { message~unknown } { #3 } { #4 } + \msg_kernel_error:nxx { message-unknown } { #3 } { #4 } } } % \end{macrocode} @@ -1287,30 +1287,35 @@ % % Some very basic error messages. % \begin{macrocode} -\msg_kernel_new:nnn - { coding~bug } - {This is a LaTeX bug: check coding!\\#1} - {#2} -\msg_kernel_new:nnn - { message~unknown } - {Unknown message `#2' for module `#1'.} - {LaTeX was asked to display a message by the `#1' module.\\ - The message was supposed to be called `#2', but I can't\\ - find a message with that name. - \c_msg_return_text_tl} -\msg_kernel_new:nnn - { message~class~unknown } - {Unknown message class `#1'.} - {You have asked for a message to be redirected to class `#1'\\ - but this class is unknown. - \c_msg_return_text_tl} -\msg_kernel_new:nnn - { message~loop } - {Message redirection loop.} - {You have asked for a message to be redirected,\\ - but the redirection instructions form a loop:\\ - you've lost the message. - \c_msg_return_text_tl} +\msg_kernel_new:nnn { coding-bug } {% + This is a LaTeX bug: check coding!\\% + #1% +}{% + #2% +} +\msg_kernel_new:nnn { message-unknown } {% + Unknown message `#2' for module `#1'.% +}{% + LaTeX was asked to display a message by the `#1' module.\\% + The message was supposed to be called `#2', but I can't\\% + find a message with that name. + \c_msg_return_text_tl +} +\msg_kernel_new:nnn { message-class-unknown } {% + Unknown message class `#1'.% +}{% + You have asked for a message to be redirected to class `#1'\\% + but this class is unknown. + \c_msg_return_text_tl +} +\msg_kernel_new:nnn { message-loop } {% + Message redirection loop.% +}{% + You have asked for a message to be redirected,\\% + but the redirection instructions form a loop:\\% + you've lost the message. + \c_msg_return_text_tl +} % \end{macrocode} % %\begin{macro}{\msg_kernel_bug:x} diff --git a/Master/texmf-dist/source/latex/expl3/source3.tex b/Master/texmf-dist/source/latex/expl3/source3.tex index 837260437b1..2fd332f5563 100644 --- a/Master/texmf-dist/source/latex/expl3/source3.tex +++ b/Master/texmf-dist/source/latex/expl3/source3.tex @@ -356,6 +356,7 @@ note}' section: \DocInput{l3box.dtx} \DocInput{l3xref.dtx} \DocInput{l3keyval.dtx} +\DocInput{l3keys.dtx} \DocInput{l3calc.dtx} \DocInput{l3file.dtx} |