diff options
Diffstat (limited to 'Master/texmf-dist/source/latex3/template/template.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex3/template/template.dtx | 2053 |
1 files changed, 2053 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex3/template/template.dtx b/Master/texmf-dist/source/latex3/template/template.dtx new file mode 100644 index 00000000000..286449af968 --- /dev/null +++ b/Master/texmf-dist/source/latex3/template/template.dtx @@ -0,0 +1,2053 @@ +% \iffalse +%% +%% (C) Copyright 1999 David Carlisle, Frank Mittelbach +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +%<*dtx> + \ProvidesFile{template.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{template} +%<driver>\ProvidesFile{template.drv} +% \fi +% \ProvidesFile{template.dtx} + [1999/09/28 v0.14 template parsing (DPC,FMi)] +% +% \iffalse +%<*driver> + \documentclass{ltxdoc} +\makeatletter + \newenvironment{decl}[1][]% + {\par\small\addvspace{4.5ex plus 1ex}% + \vskip -\parskip + \ifx\relax#1\relax + \def\@decl@date{}% + \else + \def\@decl@date{\NEWfeature{#1}}% + \fi + \noindent\hspace{-\leftmargini}% + \begin{tabular}{|l|}\hline\ignorespaces}% + {\\\hline\end{tabular}\nobreak\@decl@date\par\nobreak + \vspace{2.3ex}\vskip -\parskip\@afterheading} +\makeatother + + \begin{document} + \DocInput{template.dtx} + \end{document} +%</driver> +% \fi +% +% +% \CheckSum{864} +% +% \GetFileInfo{template.dtx} +% +% \title{The \textsf{template} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{DPC, FMi} +% \date{\filedate} +% \maketitle +% +% \changes{0.06}{1998/12/17}{generic functions reborn as templates} +% +% \tableofcontents +% +% \section{Introduction} +% A \emph{Template} is a named `function' that has a fixed number +% of \emph{mandatory arguments} and an additional set of \emph{keys} +% or `named attributes' that are set in a `key value list'. That is, +% a comma separated set of assignments of the form:\\ +% \meta{key$_1$} |=| \meta{value$_1$} |,| +% \meta{key$_2$} |=| \meta{value$_2$} \ldots +% +% More specific instances of the template may be declared by +% specifying settings of the parameters. The key value list is parsed +% at the time the instance is declared, and an `internal' set of +% parameter assignments is passed to the template code. It is normally +% not parsed at run-time, though it is possible to enforce this +% behaviour. +% +% Templates have a \emph{type} and a \emph{name}. Templates +% of the same type have the same argument and parameter +% structure. That is, templates of the same type are expected to be +% exchangeable semantically. (However, except for checking that +% templates of the same type always have the same number of arguments +% this is not enforced by the code.) +% +% A template type is declared via the |\DeclareTemplateType| +% declaration which takes two arguments: the name for the type and the +% number of arguments a template of this type requires. +% +% Templates are declared via the |\DeclareTemplate| +% command which takes five arguments +% \begin{itemize} +% \item The \emph{type} of the template (no |\|). +% \item The \emph{name} of the template (no |\|). +% \item The number of arguments for the template (same as on type +% declaration). +% \item A list declaring the keys accepted by the template, +% with information about the action to take when the key is specified +% with a value. +% \item The code for the template. This may be arbitrary \TeX\ +% code. At some point it should execute |\DoParameterAssignments| +% to run the parameter assigments. +% +% The mandatory arguments are accessed via |#1|, |#2|, \ldots +% \end{itemize} +% +% +% Each element of the key specification list is of the form: +% \begin{flushleft} +% \meta{key name} |=| +% \meta{key type} \meta{optional default} \meta{internal code} +% \end{flushleft} +% +% The \meta{key types} are essentially specified by giving a symbolic +% representation of the assignment function to be used by \TeX. +% +% Currently the possibilities are +% +% \begin{center}\catcode`|=12 +% \begin{tabular}{l|ll|l} +% key type& letter& internal code& argument form\\\hline +% Command & f\emph{n}&command name & command definition\\ +% name & n & command name & command definition\\ +% length & l & length register& calc length syntax\\ +% fake length & L & command name & calc length syntax\\ +% count & c & count register& calc count syntax\\ +% fake count & C & command name & calc count syntax\\ +% boolean & b & name of \verb|\newif| switch& true or false\\ +% switch & s & \marg{true code}\marg{false code}& true or false\\ +% instance& i\marg{type}& command name& instance of this \emph{type}\\ +% direct & x & Internal code& any\\ +% general & g & general code & any +% \end{tabular} +% \end{center} +% +% In addition, any of these types may be prefixed by |+| to +% denote a global assignment (described below). +% |f| takes a digit from 0--9 to denote the number of arguments. +% |n| is in fact the same as |f0|. When an instance is declared +% The value assigned to the key should be the definition of +% the command, using |#1|\ldots|#9| to denote the specified arguments. +% +% |c| takes an internal form a count register, +% not a \LaTeX\ counter name. +% +% For |f|, |n|, |l|, and |c|, the assignment is done twice, once +% at the time an instance is \emph{declared}. (This may involve +% using \textsf{calc} expresions. Then the `primitive assignment' +% of the value (not using calc) is copied to the internal parameter +% list, to be executed when an instance is run. Sometimes you need the +% expression to be evaluated at the time an instance is run rather +% than the time it is declared. For example it may be an expression +% involving some values that are not fixed throughout a document. +% In this case the instance declaration may give a value in the +% form |\DelayedEvaluation|\marg{calc expression}. In this case +% the value is not evaluated when the instance is declared, and +% instead the entire expression is copied to the `internal parameter +% list' and is evaluated whenever the instance is used. +% +% |L| and |C| take the same value types as |l| and |c| but the internal +% assignments are to macros not registers. +% +% Keys declared with |b| and |s| each take values either \emph{true} or +% \emph{false}. if the key zzz is declared with |b| then specifying +% |zzz=true| will essentially pass |\zzztrue| to the internal parameter +% list (although in fact |\zzztrue| need not be defined) . If instead +% zzz had been declared via |s|, then |zzz=true| would pass the tokens +% of the \marg{true code} to the internal parameter list. +% +% If a key is specified as |x|, then when used the \emph{internal code} +% will be copied to the internal parameter lists. This code may use |#1| +% to denote the value supplied to the key in the instance declaration. +% Note that this code is \emph{only} copied at the time the instance is +% declared. It is not executed at this time. It is executed when the +% instance is executed.\footnote{Despite the question of whether or +% not x and g are still necessary these days, they have the wrong +% `names' since x is the one that is not executed during delcaration +% while g is.} +% +% If a key is declared with |g| then the code is run at the time the +% instance is declared. By default \emph{nothing} is passed to the +% internal parameter list. This code may use |#1| to denote the +% value that will be supplied when an instance is declared. +% Any code that should be run when an instance is executed should +% be explicitly passed to the internal parameter list using +% |\addto@hook\TP@toks{|\ldots|}| +% +% A key declared with |i|\marg{type} takes as value the name of a +% declared instance of that type. The command token associated with +% the key will store a command essentially equivalent to a call +% to |\UseInstance|\marg{type}\marg{name}, but in a slightly optimised +% internal form. +% As an exception to this rule the replacement code may be of the form +% |\UseTemplate| followed by the key settings for the template +% but without the mandatory arguments. In this case the `inner' +% instance declaration is `pre compiled' and the token assigned to +% the store the value assigned to this key will execute an instance +% of the template directly, it will not re-parse the keyword settings +% each time the instance is used. +% +% \section{Commands} +% +% +% \subsection{Template declaration commands} +% +% \begin{decl} +% |\DeclareTemplateType| \marg{type}\marg{num} +% \end{decl} +% Declare a template type. +% +% \begin{decl} +% |\DeclareTemplate| +% \marg{type}\marg{tname}\marg{num}\marg{keyspec}\marg{code} +% \end{decl} +% Declare a template \meta{tname} of type \meta{type} with the set of +% keys as defined by \meta{keyspec}. From this template instances can +% be declared using |\DeclareInstance| At runtime such instances will run +% \meta{code} and expect \meta{num} mandatory arguments (same number +% for all templates of one type).\footnote{The \meta{num} argument is +% redundent as it can be deduced from the type. However, for practical +% reasons it seems better to keep that information with each +% individual template declaration.} +% +% \begin{decl} +% |\DeclareRestrictedTemplate| +% \marg{type}\marg{new-tname}\marg{old-tname}\marg{keyvals} +% \end{decl} +% Declare as new template \meta{new-tname} for type \meta{type} by +% taking template \meta{old-tname} as the basis and setting one or +% more of its keys to specific values. +% +% \begin{decl} +% |\DoParameterAssignments| +% \end{decl} +% The list of key value assignments made (and saved) during template +% declaration is evaluated at this point in the template code. +% +% +% \subsection{Instance declaration commands} +% +% \begin{decl} +% |\DeclareInstance| \marg{type}\marg{iname}\marg{tname}\marg{keyvals} +% \end{decl} +% Declare an instance of type \meta{type} named \meta{iname} build +% from using template \meta{tname} with key settings as given by +% \meta{keyvals}. +% +% \begin{decl} +% |\DeclareCollectionInstance| +% \marg{collection}\marg{type}\marg{iname}\marg{tname}\marg{keyvals} +% \end{decl} +% Same as |\DeclareInstance| except that this instance is only active +% when for the type \meta{type} the collection \meta{collection} was +% selected via |\UseCollection|. E.g., within the frontmatter one +% could make all headings behave differently by defining collection +% instances for template type `head'. +% +% \subsection{Key value commands} +% +% \begin{decl} +% |\DelayEvaluation|\marg{code} +% \end{decl} +% Used in the value spec for an instance to declare that the value +% \meta{code} should not be evaluated at declaration time but at +% run-time. Can also be used in the defaults for keys (given in square +% brackets) in the declaration of templates. +% +% \begin{decl} +% |\MultiSelection| \meta{counter} \marg{cases} \marg{else} +% \end{decl} +% Used in the value spec for an instance key to declare that the value of +% this key depends on the current setting of \meta{counter} at run-time. +% The \meta{cases} argument is a comma-separated list of ``values'', +% the \meta{else} argument a single ``value''. If at run-time +% \meta{counter} has the value $i$ then the $i$-th element of the +% \meta{cases} list is selected. If that does not exist the +% \meta{else} case is returned. +% +% +% \subsection{Processing commands} +% +% \begin{decl} +% |\UseTemplate| \marg{type}\marg{tname}\marg{keyval} +% \end{decl} +% Execute a template \meta{tname} of type \meta{type} at run-time +% using \meta{keyvals} as the value assignments for its keys. In this +% case the keys are evaluated at run-time thus this method is far +% slower than using a predeclared instance of this template (see +% below). This command can also appear as the value for a key of type +% `i' in which case the evaluation happens at declaration time of the +% template that contains this key! +% +% +% \begin{decl} +% |\UseInstance| \marg{type}\marg{iname} +% \end{decl} +% Run the instance \meta{iname} of template type \meta{type}. If a +% collection is in force see if there is a collection instance of name +% \meta{iname} and if so run that instead. +% +% \begin{decl} +% |\UseCollection| \marg{type}\marg{collection} +% \end{decl} +% Declare that from now on (normal scoping rules) the collection +% \meta{collection} for template type \meta{type} is in force. This +% means that a call to |\UseInstance| will first check if there is a +% collection instance defined, and if so use that instance, otherwise +% use the normal instance. +% +% +% \subsection{Test commands} +% +% \begin{decl} +% |\IfExistsInstanceTF| \marg{type}\marg{iname}\marg{true}\marg{false} +% \end{decl} +% Test if for template type \meta{type} an instance with name +% \meta{iname} exists. Select \meta{true} or \meta{false} code +% accordingly. +% +% +% +% \section{Examples of template key types} +% +% The general syntax for key specification in templates (fourth argument +% of the command |\DeclareTemplate|) is: +%\begin{flushleft} +%| {| \\ +%| | \meta{key-name$_1$} |=|\meta{key-type$_1$} +% \meta{optional-default$_1$} \meta{storage-bin$_1$}|,|\\ +%| | \meta{key-name$_2$} |=|\meta{key-type$_2$} +% \meta{optional-default$_2$} \meta{storage-bin$_2$}|,|\\ +%| ...|\\ +%| }| +%\end{flushleft} +% In this section we look at all possible key types and give examples +% for them. +% +% +% \subsection{Attributes that receive names as values} +% +% The type |n| expects to receive a \LaTeX{} name as a value. Used, +% for example, to specify the name of a \LaTeX{} counter to use. +%\begin{verbatim} +% heading-id =n \heading@id, +% counter-id =n [\DelayEvaluation{\heading@id}] \heading@counter, +%\end{verbatim} +% Notice the use of |\DelayEvaluation| in the default of +% |counter-id|. It is necessary to make the default the token +% |\heading@id| if we want to inherit the value from the |heading-id| +% key. Otherwise it gets value of |\heading@id| at the time the +% instance is declared. +% +% +% \subsection{Attributes that receive functions as values} +% +% +% The type |f|\meta{num} expects a function with \meta{num} arguments +% as a value. The arguments are denoted by |#1|, |#2|, etc. In most +% cases either |f0| (for declarations) or |f1| (to format one argument) are +% needed. +%\begin{verbatim} +% initial-font =f0 \initial@font, +% initial-format =f1 [#1] \initial@boxhandling, +%\end{verbatim} +% +% \subsection{Attributes that receive dimensions as values} +% +% As far as specifying instances the |l| and |L| type behave +% identically. They differ only in the type of internal storage-bin +% they need: |l| expects a length register while |L| expects an +% ordinary macro name and assigns its value via |\def|. +%\begin{verbatim} +% pre-sep =l \topsep, +% post-sep =L \botsep, +%\end{verbatim} +% +% +% +% \subsection{Attributes that receive integers as values} +% +% The |c| and |C| type receive integers as values. Again either of +% them can be transparently used. In case of |c| the +% \meta{storage-bin} has to be a \TeX{} count register not a \LaTeX{} +% counter name, i.e., set up via |\newcount|. (\LaTeX{} counters can +% be used as well if they are accessed via their internal name, i.e., +% via |\c@|\meta{\LaTeX-counter}) +%\begin{verbatim} +% pre-penalty =c \@beginparpenalty, +% penalty =C \hmaterial@penalty, +%\end{verbatim} +% +% +% +% \subsection{Attributes that receive template instances as values} +% +% The type |i|\marg{type} takes as value the name of a declared +% instance of that type. The \meta{storage-bin} associated with the +% key will store a command essentially equivalent to a call to +% |\UseInstance|\marg{type}\marg{name}, but in a slightly optimised +% internal form. +% +% As an exception to this rule the replacement code may be of the form +% |\UseTemplate| followed by the key settings for the template but +% without the mandatory arguments. In this case the `inner' instance +% declaration is `pre compiled' and the token assigned to the store +% the value assigned to this key will execute an instance of the +% template directly, it will not re-parse the keyword settings each +% time the instance is used. +%\begin{verbatim} +% justification-setup =i{justification} \list@justification, +%\end{verbatim} +% +% Usage within an instance declaration is either +%\begin{verbatim} +% justification-setup = raggedright, +%\end{verbatim} +% i.e., name of a declared instance or a call to |\UseTemplate| +%\begin{verbatim} +% justification-setup = \UseTemplate{justification}{TeX} +% { startskip = 0pt, ... }, +%\end{verbatim} +% +% +% +% \subsection{Attributes that receive true or false values} +% +% The type |s| expects the strings |true| or |false| as values. In +% this case the declaration has no \meta{storage-bin}. Instead the +% declaration consists of two brace groups containing code. Depending +% on the value one of the groups gets copied verbatim into the +% internal parameter list of the instance and gets executed at +% run-time at the point where |\DoParameterAssignments| is seen. +%\begin{verbatim} +% item-implicit-boolean =s +% { \def\item@implicit@code{\item\relax} }{}, +% numbered-boolean =b [true] @heading@nums, +%\end{verbatim} +% +% +% \subsection{Attributes that accept any value} +% +% The type |g| is a low-level specification which contains arbitrary +% code in place of the \meta{storage-bin}. This code is evaluated at +% declaration time of the instance and by default \emph{nothing} is +% passed to the internal parameter list (this has to happen explicitly +% from within the code). |#1| may be used to access the value +% specified. + +% The main purpose for this type is of historical nature (originally +% most of the other types have been implemented internally using |g|). +% +% The type |x| also requires code in place of the \meta{storage-bin}. +% However with this type all of the code is copied unevaluated to the +% internal parameter list. There are some applications for this type +% when implementing customisable defaults. However, it is likely that +% it will not survive a final release. +%\begin{verbatim} +% generic-key =g \typeout{#1}, +% extra-assigns =x \typeout{#1}, +%\end{verbatim} +% +% +% +% +% +% +% \section{A complete example} +% +% The following example shows a sketch of a template for typesetting +% captions to be used as part of a larger mechanism setting whole +% floats.\footnote{I made it up while I went along so if you spot the +% ``missing brace'' or some other blunder tell me, FMi.} +% +% We declare a template type \texttt{caption} then define an example +% template for that type and finally produce some instances from that. +% +% \subsection{Declaring the template type} +% +% To define the template type we first have to ask ourselves what +% information would be varying each time such a template is used? A +% potential answer could be the following: +% \begin{itemize} +% \item +% The float name, e.g., `Table' or `Fig.' etc. +% \item +% The float +% number e.g., `10' or `3--c' etc. +% \item +% The actual caption text as specified in the document. +% \end{itemize} +% Since the above items would be differed in each instantiation of +% such a template we would pass them as mandatory argument to the +% template. +% +% Are there others? Possibly. Here are two more that seem to be +% useful, at least in a number of cases: +% \begin{itemize} +% \item +% The text of the legend in document classes that distinguish +% between caption text (heading to the figure/table) and legend +% (explanatory material) +% \item +% Measure to which the caption should be typeset. +% \end{itemize} +% The last one of these might need some extra explanation. Suppose a +% design requires that the caption width is decided depending on the +% width of the table of figure, e.g., the caption is supposed to +% typeset below some illustration and should not be wider than that +% illustration, or the caption is typeset aside to the illustration +% using the remaining space. In that case the process that formats the +% whole float needs to communicate with the current template to pass +% that (varying) information along. Of course, that could happen by +% using global variables, e.g., the outer process sets the measure as +% desired before calling the caption formatting template. What makes +% more sense is likely to be a matter of taste but it also has to do +% with the precise semantics of the template type. Staying with our +% example: if the the semantics of the template type \texttt{caption} +% is supposed to produce a formatted box (in \TeX{} terms) then we +% should pass the measure as an argument if we ever intend to allow +% for variations. If on the other hand the semantics are to format a +% certain set of text into the current galley (which has measure of +% its own) then a measure argument would not belong to this template +% type. +% +% Are there other variations sensible? Yes, for example, instead of +% passing a fixed string like ``Fig.'' as the first argument one could +% pass an abstract float type identifier and let the template worry to +% deduce from that information what fixed string to produce. +% +% Another question: why should we pass the fixed text (or an abstract +% identifier from which it can be deduced) and the number as separate +% arguments to the template instead of passing a combined string (like +% it is done in the |\@makecaption| command of \LaTeXe{})? Answer: +% because this allows to build templates that can individually +% manipulate both bits of information, e.g., to format the number in a +% different font, etc. +% +% So what are the conclusions of this discussion? Defining the +% semantics of a template type is difficult and often needs several +% trials to come up with something that is covering the anticipated +% use. There is clearly not a cardinal way for defining template +% types; how the overall separation into smaller units is done is +% partly a matter of taste and partly a matter of the major layout +% characteristics that one tries to support. +% +% Returning to our example: let's assume we settle for the first four +% arguments, i.e., the calling template is responsible for setting the +% measure for the caption text if necessary. +% +% What we also have to do is to define (at least for ourselves) what +% data the arguments accept and what their semantics are. An informal +% summary of that could be the following: +% \begin{center} +% \begin{tabular}{rrl} +% \textit{Arg} & \textit{Data Type} & \textit{Description} \\[3pt] +% 1 & text & fixed float description +% \\ +% 2 & text/|\NoValue| & float number +% \\ +% 3 & text & caption text +% \\ +% 4 & text/|\NoValue| & legend text +% \\ +% \end{tabular} +% \end{center} +% The second and the fourth argument are allowed to be missing (i.e., +% can get |\NoValue| passed as a value). Note that the empty string in +% case of a text argument is different from |\NoValue|. +% +% We further declare that it is permissible for a template of this +% type to ignore the information provided by all arguments except 3, +% i.e., the caption text. +% +% Finally the result of the template formatting should is to typeset +% text into a current galley (paragraph mode in \LaTeX{} lingua). +% +% All the above is semantic information that (at least right now) is +% not being enforced by declaring a template type (except for the +% number of arguments) but each template of a certain type is supposed +% to conform to this specification nonetheless.\footnote{To make this +% even clearer we are thinking of extending the template type +% declaration with another argument in which one has to formally or +% informally (?) specifies information like the one in the table +% above.} +% +% This finally leads to the following declaration: +%\begin{verbatim} +%\DeclareTemplateType{caption}{4} +%\end{verbatim} +% +% \subsection{Defining a first template} +% +% We start by defining a simple template of type \texttt{caption} +% which roughly formats a caption like those being presented in +% \LaTeXe{}'s article class, i.e., the caption is typeset as a +% paragraph if it is longer than a single line, otherwise it is +% centered. The legend even if present is ignored. Above and below we +% give the designer the possibility to add some space. +% +% In fact the examples is more or less identical in code to +% |\@makecaption| except that if the second argument (i.e., the +% number) is |\NoValue| it and its preceding space\footnote{For those +% who wonder: spaces are by default ignored within definitions when +% the new packages are used due to a command \texttt{\textbackslash +% IgnoreWhiteSpace}, do get a normal space one has to use +% \texttt{\textasciitilde} and to obtain an unbreakable space +% \texttt{\textbackslash nobreakspace}.} gets ignored. +% +% We start by declaring the template \texttt{toosimple} of type +% \texttt{caption} having four mandatory arguments (as described in +% the discussion of the template type). +%\begin{verbatim} +%\DeclareTemplate{caption}{toosimple}{4} +%\end{verbatim} +% The next argument of |\DeclareTemplate| lists all keys for the +% template. In this case we have keys for the vertical spaces above +% and below. We make them type |L| to save on registers but with a bit +% of care we could also have used scratch registers like |\@tempskipa| +% etc. Their default values are both zero. +%\begin{verbatim} +% { +% above-skip =L [0pt] \caption@above@skip , +% below-skip =L [0pt] \caption@below@skip , +% } +%\end{verbatim} +% The final argument of |\DeclareTemplate| contains the actual +% processing code. We start with looking at the second mandatory +% argument (caption number) to find out if it is |\NoValue| and +% depending on the result define a helper command |\caption@start|. +%\begin{verbatim} +% { +% \IfNoValueTF{#2} +% { \def\caption@start{#1:~} } +% { \def\caption@start{#1~#2:~} } +%\end{verbatim} +% Having dealt with the prelims we now run |\DoParameterAssigments| at +% which point the keys of the template are made available, e.g., at +% this point all those right hand containers such as +% |\caption@above@skip| get assigned the value specified in an +% instantiation of the template. (That scheme allows to do preliminary +% processing up front, e.g., defaults for the keys could be assigned +% prior to that point in which case they are overwritten if the +% template instance specifies a different value. the use of specifying +% defaults via the |[..]| syntax as done above is slightly faster at +% run-time but needs more memory.) +%\begin{verbatim} +% \DoParameterAssigments +%\end{verbatim} +% The rest of the code should look familiar to anybody who ever looked +% at \texttt{article.cls}. The only point worth mentioning are the +% |\relax| commands after |\caption@above@skip| and +% |\caption@below@skip|. Since we have decided to use |L| as key type +% these commands are macros and not registers containing the +% dimensions as strings. This means that we have to be careful to +% ensure that \TeX{} knows where the dimension ends. In certain cases +% text following such a command might be mistaken as being part of the +% dimension (e.g., if followed by the word \texttt{plus}, etc.). In +% the code below this could only happen for the second |\vskip| but it +% is good practice to always add a terminating |\relax| to avoid such +% hidden traps. +%\begin{verbatim} +% \vskip \caption@above@skip \relax +% \sbox \@tempboxa {\caption@start #3} +% \ifdim \wd\@tempboxa >\hsize +% \caption@start #3\par +% \else +% \global \@minipagefalse +% \hb@xt@\hsize{\hfil\box\@tempboxa\hfil} +% \fi +% \vskip \caption@below@skip \relax +% } +%\end{verbatim} +% +% Why is the above template of not much use? Simply because it doesn't +% offer any flexibility to declare different designs. The only +% alteration offered to the designer is to modify the space above and +% below the caption, e.g., the following declaration would mimic the +% definition within the \texttt{article.cls} class of \LaTeXe: +%\begin{verbatim} +%\DeclareInstance{caption}{article}{toosimple} +% { +% above-skip = 0pt, +% below-skip = 10pt, +% } +%\end{verbatim} +% And that's all that can be manipulated. All items that people asking +% to change, e.g., not having a colon after the number, using +% different fonts and font sizes, etc.\ are still hard-wired and thus +% inaccessible. So we have to do better if we want to make use of the +% power the template mechanism offers. +% +% +% +% \subsection{Defining a better template} +% +% First step in defining better templates is to ask ourselves a couple +% of questions: +% \begin{itemize} +% \item What are the main characteristics of the layout the template +% is supposed to support? +% \item What are the elements that we want to allow (or can allow) the +% designer to modify? +% \end{itemize} +% +% Take the first question first: the layout supported by the template +% of the previous section had as its main characteristics that it +% would center the caption if it would fit in a single line in the +% current measure. We could consider this being an unchangable +% characteristic of the layout this template produces (and a designer +% would need to use a different template of type \texttt{caption} if a +% design compatible with this restriction is desired) or we could try +% to make our template smarter by adding bells and wistles that allow +% the designer to say stuff like: +%\begin{verbatim} +% one-line-format = \hfil #1 \hfil, +%\end{verbatim} +% or +%\begin{verbatim} +% one-line-action = center, +%\end{verbatim} +% depending on how we intend to offer changing the behavior of the +% template. Like when trying to define sensible template types we have +% no single road to heaven (and probably as many to hell) --- it has a +% lot to do with how we think about design. +% +% My advice, after having tried to work with these concepts for a +% while, is to keep templates simple in so far as that most of not all +% attribute for a template should be relevant for the design. In other +% words, if you have attributes that, depending on their setting, make +% half of the other attributes not applicable then it may be +% appropriate to think about providing several templates instead. To +% give an example from \LaTeXe: instead of having |\@startsection| +% deal with both vertical heads and run-in heads provide individual +% templates. (|\@startsection| is this famous command where design +% switches are build in by making dimensions negative to signal +% something and afterwards use the absolute value.) +% Another way to look at this is to say that a template should +% normally not contain large amounts of code which is only selected in +% a subset of attribute settings. +% +% As said before there are no golden rules, it is perfectly possible +% to make hugely complicated templates that solve every possible +% aspect of layout one could think of in one go --- it is just that +% with keeping it more simple one can get the same functionality with +% less headaches for the template writer as well as the template user +% later on. +% +% Returning to our example: allowing to handle the case of a single +% line caption specially could well be considered part of the +% template. In contrast: layouts that would put the caption number +% sideways, i.e., which would need totally different internal coding +% should probably be coded as a separate template of type +% \texttt{caption}. +% +% So for our next example template we settle for the fixed caption +% text plus number (if any) being at the beginning of the variable +% caption text (coming from the document) and being together formatted +% as some sort of a pargraph. In case of the whole caption being a +% single line we allow the designer to specify how to lay it out +% (e.g., centered, flush left, etc.). If there is a legend it will get +% formatted by a vertical space followed by the legend formatted as +% another paragraph. +% +% More precisely we allow for the following bells and wistles: +%\begin{verbatim} +%\DeclareTemplate{caption}{lesssimple}{4} +% { +%\end{verbatim} +% The designer can specify the space above and below the caption like +% we did in our first example. +%\begin{verbatim} +% above-skip =L [0pt] \caption@above@skip , +% below-skip =L [0pt] \caption@below@skip , +%\end{verbatim} +% Regarding the caption number we support the case where no number is +% present (the value being |\NoValue|) as well as the number being +% present. For both cases the designer has to specify what formatting +% should be attached. By default all is being typeset in the font the +% whole caption is presented but if there is a need for it the +% designer can use the following keys to attach special formatting +% devices to each particular item beside specifying special spacing +% information or replacing the default colon after the number with +% something else. +%\begin{verbatim} +% number-format =f2 [#1~#2:~] \caption@number@format, +% nonumber-format =f1 [#1:~] \caption@nonumber@format, +%\end{verbatim} +% If the caption is fitting onto a single line we make it possible +% for the designer to specify how this single line should be +% positioned (the default is to center the line). +%\begin{verbatim} +% single-line-format =f1 [\hfil#1\hfil] \caption@single@line@format, +%\end{verbatim} +% The font for the caption (including the fixed text and the number +% unless specified differently above) is going to be the one decided +% by the next key. +%\begin{verbatim} +% caption-font =f0 [\normalfont] \caption@font, +%\end{verbatim} +% The next attribute deserves some extra explanation: here we make use +% of an interface which is explained in more detail when we reveil the +% support for galley formatting.\footnote{Guess I have to apologize +% for the fact that i partly make use of that interface in this +% example while on other occasions (like the use of vertical spacing) +% within the example I do not---consistency around midnight is not my +% strength I fear (FMi).} In a nutshell the template type \texttt{hj} +% (hyphenation \& justification) allows one to define a) the +% justification concepts applied to the upcoming paragraphs, e.g., +% whether they should be set flush left, adjusted, first line +% centered, etc.\ b) the linebreaking strategy used and c) the +% hyphenation rules which should apply. All this is done by selecting +% an appropriate (predefined) instance of this type as will hopefully +% become somewhat clearer in the example instances shown below. +%\begin{verbatim} +% caption-hj-setup =i {hj} [default] \caption@hj@instance, +%\end{verbatim} +% In case there is a legend to format we give the designer the +% possibility to specify by how much vertical space it should be +% separated from the preceding paragraph (i.e., the caption text). The +% attributes for font and hj setup are comparable to those for the +% caption text itself (except that they will only apply to the +% legend). The only addition is the key \texttt{legend-text} which is +% allowed to take a fixed text (plus any formating and spacing for it) +% which will be added to the front of the legend in case it is +% provided at all (by default it is empty). +%\begin{verbatim} +% legend-sep =L [0pt] \caption@legend@sep , +% legend-text =f0 [] \caption@legend@text, +% legend-font =f0 [\normalfont] \caption@legend@font, +% legend-hj-setup =i {hj} [default] \caption@legend@hj@instance, +% } +%\end{verbatim} +% The actual code for the template should hold few if any +% surprises. In fact it is more or less identical to the one of the +% first template example, except that now we have now taken out some +% of the hardwired decisions and placed them into attributes. +%\begin{verbatim} +% { +% \IfNoValueTF{#2} +% { \def\caption@start{\caption@number@format{#1}{#2}} } +% { \def\caption@start{\caption@nonumber@format{#1}} } +% \DoParameterAssigments +% \vskip \caption@above@skip \relax +%\end{verbatim} +% To properly measure the caption to determine if it fits a single +% line we have to set it in the right font, so here as well as below +% we have to apply |\caption@font|. +%\begin{verbatim} +% \sbox \@tempboxa {\caption@font \caption@start #3} +% \ifdim \wd\@tempboxa >\hsize +% \begingroup +% \caption@font \caption@hj@instance +% \caption@start #3\par +% \endgroup +% \else +% \global \@minipagefalse +% \hb@xt@\hsize{\caption@single@line@format{\box\@tempboxa}} +% \fi +%\end{verbatim} +% To decide whether or not we have to set any legend we have to test +% |#4| for being |\NoValue|. This part of the code was not present in +% the previous example but otherwise should be straight forward. +%\begin{verbatim} +% \IfNoValueF{#4} +% { +% \vskip \caption@legend@sep \relax +% \begingroup +% \caption@legend@font \caption@legend@hj@instance +% \caption@legend@text +% #4\par +% \endgroup +% } +% \vskip \caption@below@skip \relax +% } +%\end{verbatim} +% +% I wouldn't claim the the above template is good or contains +% everything that would be desired and I'm sure that in the end we +% will have several such template for typesetting the caption part and +% perhaps decide on a different template type in the first place. So +% this is only to give a glimpse of how the template interface could +% be applied and I hope that reading it can see a) how they can apply +% it to other areas as well as see what is wrong with the example +% itself. +% +% To just note one point that i thought of being wrong after writing +% the above paragraphs: the key \texttt{single-line-format} was +% declared to be a function with one argument with the idea that +% besides specifying the single line should be centered (|\hfil|) on +% both sides, or flush left, or flush right (|\hfil| on one side) one +% could also specify something like +%\begin{verbatim} +% single-line-format = \hspace{10pt}#1\hfil, +%\end{verbatim} +% that is a fixed indentation on the left in case where the caption is +% a single line. However, of course one can't. Or at least it is not +% safe to do so since our test in the code tests the width of the line +% without taking into account such a finite fixed space and guess what +% might happen? So in summary, flexibility needs some thought and +% often some afterthoughts as well --- happy thinking :-) +% +% +% +% \subsection{Defining a few instances} +% +% So let us conclude this example with a few sample instances. We +% start with one that repeats what current \LaTeXe{} provides in the +% article class. It shows all keys with values. However in fact only +% the first key is actually needed since all others are the same as +% the default values in the template (and of course a legend is not +% specifiable in standard \LaTeX{} coding so those settings simply do +% not apply anyway). +%\begin{verbatim} +%\DeclareInstance{caption}{article}{lesssimple} +% { +% above-skip = 10pt, +% below-skip = 0pt, +% number-format = #1~#2:~, +% nonumber-format = #1:~, +% single-line-format = \hfil#1\hfil, +% caption-font = \normalfont, +% caption-hj-setup = default, +% legend-sep = 0pt, +% legend-text = , +% legend-font = \normalfont, +% legend-hj-setup = default, +% } +%\end{verbatim} +% +% The next examples are taken from books on the shelf essentially a +% random selection I fear. This one is from \emph{Introduction to +% Database Design} by C.~J.~Date and it uses Helvetica for the caption +% text with the caption flush left, with the figure and the fixed +% string (e.g., `Fig.' in bold face) separated by a quad of space. No +% legend either so this is not set up. The \texttt{hj} instance +% \texttt{noindentflushleft} is supposed to produce a ragged right paragraph +% without any indentation. It would have to be set up elsewhere +% (instance to the template of type \texttt{hj}). +%\begin{verbatim} +%\DeclareInstance{caption}{DATE}{lesssimple} +% { +% above-skip = 10pt, +% below-skip = 0pt, +% number-format = \textbf{#1~#2}\quad, +% nonumber-format = \textbf{#1}\quad, +% single-line-format = #1\hfil, +% caption-font = \fontfamily{phv} \normalfont, +% caption-hj-setup = noindentflushleft, +% } +%\end{verbatim} +% +% The final example is from the book ``Methods of Book Design'' by +% H.~Williamson which sets the caption centered if it fits a single +% line but adjusted as a paragraph without any indentation if longer +% than a single line. It uses old style numerals followed by a period +% for the number (though the example isn't quite right as i guess the +% text font used already has oldstyle numerals as default, so +% |\oldstylenums| is in fact not necessary). +%\begin{verbatim} +%\DeclareInstance{caption}{WILLIAMSON}{lesssimple} +% { +% above-skip = 10pt, +% below-skip = 0pt, +% number-format = #1~\oldstylenums{#2}.~, +% nonumber-format = #1~, +% single-line-format = \hfil#1\hfil, +% caption-font = \normalfont, +% caption-hj-setup = noindentadjusted, +% } +%\end{verbatim} +% +% +% +% \section{Notes} +% +% \subsection{Note on multi-valued parameters} +% +% +% The following code\footnote{docu taken from trial implementation in +% xlists.dtx, FMi} implements for registers (ie L,l,C,c keys) and +% for names (ie n key) a multi-selection mechanism of the following +% form: +% \begin{verbatim} +% key = \MultiSelection \@listdepth { +% \DelayEvaluation {2.5em}, +% 20pt + 34pt } +% { \DelayEvaluation {1em} }, +% \end{verbatim} +% where the first argument to |\MultiSelection| is a counter, the +% second argument is a comma separated list of values denoting the +% values for the cases 1, 2,\ldots, and the third argument contains +% the value for all other cases. +% +% The values are evaluated at declaration time in case of registers +% and therefore can contain calc expressions as well as +% |\DelayEvaluation|. +% +% Due to the implementation the case list is not allowed to have a +% trailing comma! And of course no checks are made whatsoever :-( +% +% A probably much nicer syntax would be something like this: +% \begin{verbatim} +% key = \MultiSelection { +% selector = \@listdepth, +% 1 = \DelayEvaluation {2.5em}, +% 2 = 20pt + 34pt, +% else = \DelayEvaluation {1em} +% }, +% \end{verbatim} +% but i found that too difficult to implement right now. +% +% I think it should also be considered if this kind of thing should be +% a generally available feature on all key types especially on the +% f\meta{number} ones. +% +% Anyway it is what i need for lists right now and as such it is +% sufficient. +% +% +% \subsection{Notes on template restriction} +% +% Possible semantics: +% +% a: just:-) changes the defaults ie the new template has as +% defaults those of its source as modified by the supplied +% keyvals; +% +% b: similar to a: but also removes some keywords ie the new template +% will not accept the keywods whose values are set by the suppied +% keyvals; +% +% c: plan C. +% +% +% Towards an implementation of b: but without a restriction on what +% keys appear where. +% +% +% +% +% \subsection{Open issues} +% +% In this section unresolved issues or ideas to think about and +% perhaps implement are collected. There is no particular order to +% them. +% +% \begin{itemize} +% \item The order of arguments in |\UseCollection| is illogical in my +% eyes! A collection typically modifies the behavior of several +% types and thus should perhaps be first (as it is in the +% |\DeclareCollectionInstance| case). Or not, or what? +% +% \item How should |\IfExistsInstanceTF| behave for Collection +% instances? Do we need a special check for those or a default +% action? Or do we need an additional test for the existence of +% collection instances? +% +% \item It was suggested that the template type declaration should get +% another argument in which (in?)formally the semantics for the +% template types are described, e.g., data type of arguments, +% resulting output, \ldots{} (somewhat like the description arguments +% for functions and variables in Emacs-Lisp). The advantage being +% that this helps employing the templates better as well as perhaps +% guiding context sensitive editors to support the work with such +% templates (e.g., providing help texts). +% +% \item The same might be of interest for the keys of individual +% templates though here syntax support is already available to some +% extend by the declaration of key types. +% +% \item There might be a need to distinguish between \TeX's dimen and +% skip registers. Right now this is not done and both |l| and |L| +% accepts what \LaTeX{} calls ``rubber length'' specifications. +% +% \item The type |b| can probably vanish. It is equivalent to +% specifying the mutators of a |\newif| command in the brace groups, +% e.g. +%\begin{verbatim} +% numbered-boolean =b [true] @heading@nums, +% numbered-boolean =s [true] {\@heading@numstrue} +% {\@heading@numsfalse}, +%\end{verbatim} +% +% \item See issue raised about syntax (and semantics) for +% |\Multiselection|. +% +% \end{itemize} +% +% \StopEventually{} +% +% \section{Implementation} +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage{ldcsetup} +% \end{macrocode} +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% Declare a private token register for building parameter lists. +% Having the number saves a few expandafters +% (probably not needed in the end). +% \begin{macrocode} +\newtoks\TP@toks +\newtoks\TP@toksb +\newtoks\TP@toksc +% \end{macrocode} +% +% +% \begin{macro}{\functiondefine} +% |\def| setup with a latex style `number of arguments' argument. +% definition setup left in toksb for possible future use. +% \begin{macrocode} +\def\functiondefine#1#2#3{% + \def\@tempa##1#1##2##{% + \TP@toksb\expandafter{\expandafter\def\expandafter#2\@gobble##1#1} + \the\TP@toksb}% + \@tempa0##1##2##3##4##5##6##7##8##9{#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@DCI} +% Declare a command name to be an instance of a template +% ie with a particular setting of the parameters.\\ +% |#1| internal command name for instance to be (globally) declared\\ +% |#2| template type/template name\\ +% |#3| key value assignments for parameters of |#2| +% \begin{macrocode} +\def\TP@DCI#1#2#3{ + \begingroup + \TP@get@restrictions {#2} % puts stuff in \TP@toks + \toks@\expandafter\expandafter\expandafter + {\csname TPD>/#2\endcsname\relax\relax} + \setkeys{\the\TP@toksc} % temp OK? + {#3} % adds stuff to \TP@toks + \expandafter\TP@add@default \the\toks@ % prepends stuff to \TP@toks + \xdef#1{ + \expandafter\ifx\csname TP>/#2\endcsname\TP@dpa + \the\TP@toks + \else + \noexpand\TP@assignments{\the\TP@toks} + \expandafter\noexpand\csname TP>/#2\endcsname + \fi} + \endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@dpa} +% \begin{macrocode} +\long\def\TP@dpa{\DoParameterAssignments} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@add@default} +% \begin{macrocode} +\def\TP@add@default#1#2{ + \ifx#1\relax + \else + \@temptokena{#2} + \edef\@tempa{{\the\@temptokena\the\TP@toks}} + \TP@toks\@tempa + \expandafter\TP@add@default + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\UseTemplate} +% |{type}{templatename}{keyval}| +% Directly use a template with a particular parameter setting. +% This is also picked up if used in a nested fashion inside a parameter +% list.\\ +% |#1| type of a template.\\ +% |#2| name of a template.\\ +% |#3| key value assignments for parameters of |#1|. +% \begin{macrocode} +\def\UseTemplate#1#2#3{ + \TP@get@restrictions {#1/#2} % from here ... + \toks@\expandafter\expandafter\expandafter + {\csname TPD>/#1/#2\endcsname\relax\relax} + \setkeys{\the\TP@toksc}{#3} + \expandafter \TP@add@default \the\toks@ % to here is : + % Shared with \def\DeclareCommandInstance + \TP@push + \csname TP>/#1/#2\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DoParameterAssignments} +% Acces the list stored in |\TP@toks|. +% \begin{macrocode} +\def\DoParameterAssignments{ + \expandafter\TP@pop\the\TP@stack\@@} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@pop} +% \begin{macrocode} +\def\TP@pop#1#2\@@{ + \global\TP@stack{#2} + #1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@stack} +% \begin{macrocode} +\newtoks\TP@stack +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@stack} +% \begin{macrocode} +\global\TP@stack{\relax}% avoid brace loss +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@assignments} +% Access the list stored in |\TP@toks|. +% \begin{macrocode} +\def\TP@assignments{ + \afterassignment\TP@push\TP@toks} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@push} +% \begin{macrocode} +\def\TP@push{ + \global\TP@stack\expandafter + {\expandafter{\the\expandafter\TP@toks\expandafter} + \the\TP@stack}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareTemplateType} +% |{type}{nofarg}| +% \begin{macrocode} +\def\DeclareTemplateType#1#2{ + \expandafter\def\csname TP@<#1>\endcsname{{}#2}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TP@prefix} +% |{type}| returns prefix for csnames for type, based on current collection. +% \begin{macrocode} +\def\TP@prefix#1{ + <\expandafter\expandafter\expandafter + \@firstoftwo\csname TP@<#1>\endcsname>#1/} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@args} +% |{type}| returns arg count for type, +% \begin{macrocode} +\def\TP@args#1{ + \expandafter\expandafter\expandafter + \@secondoftwo\csname TP@<#1>\endcsname} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\DeclareTemplate} +% |{type}{templatename}{nofarg}{keywordspec}{code}| +% \begin{macrocode} +\long\def\DeclareTemplate#1#2#3#4#5{ + \@ifundefined{TP@<#1>} + {\undefinedtype\DeclareTemplateType{#1}#3} + {\ifnum#3=\TP@args{#1}\relax\else + \BadArgCount\fi} +% \end{macrocode} +% Parse the key declaration, and execute the list with a suitable +% definition of |\KV@elt|. +% \begin{macrocode} + \let\KV@elt\TP@elt + \def\KV@default@elt##1{ + \PackageError{template}{Missing = after ##1}\@ehd} + \def\TP@name{#1/#2} + \toks@{} + \KV@parse{#4} +% \end{macrocode} +% +% Define the defaults +% \begin{macrocode} + \expandafter\edef\csname TPD>/\TP@name\endcsname{\the\toks@} +% \end{macrocode} +% +% Define the template +% \begin{macrocode} + \expandafter\newcommand\csname TP>/\TP@name\endcsname[#3]{#5}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@elt} +% The list of undefined keys and values is put in the list of the form\\ +% |\KV@elt|\marg{key}\marg{val}%^^A +% |\KV@elt|\marg{key}\marg{val}\ldots\\ +% So just need to give this macro a suitable definition. We just need +% to look at the first token of the value, to see what sort of key +% it is, so call a helper function to split that off. +% \begin{macrocode} +\def\TP@elt#1#2{% + \let\TP@global\@empty + \TP@do{#1}#2\TP@do} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@f@shift} +% Helper for |\TP@do|. +% \begin{macrocode} +\def\TP@f@shift#1#2{% + \TP@testopt{#1}{\TPkeycommand{#1}{#2}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@i@shift} +% Helper for |\TP@do|. +% \begin{macrocode} +\def\TP@i@shift#1#2{% + \TP@testopt{#1}{\TP@instance{#1}{#2}}} +% \end{macrocode} +% +% declaration |hd =i{head} \fooo| \\ +% use |hd = mine|\\ +% makes |\fooo| shorthand for |\UseInstance{head}{mine}| +% +% also allowed: |hd = \UseTemplate{head}{...}{...}|\\ +% in case you want to use an unnamed instance of type |head| +% in this place. +% \end{macro} +% +% \begin{macro}{\TP@instance} +% \begin{macrocode} +\def\TP@instance#1#2#3{ + \TP@define@key{#1}{ + \TPinstance#3{#2}{##1}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPinstance} +% \begin{macrocode} +\def\TPinstance#1#2#3{ + \expandafter\ifx\@car#3.\@nil\UseTemplate + \typeout{\string\UseTemplate\space seen} +% \end{macrocode} +% +% code below from |\TPkeycommand| (should be combined and cleaned up) +% at this point one should also check if first arg of |\UseTemplate| +% corresponds to |#2| and if not complain (not done) +% +% \begin{macrocode} + {\TP@fudge#3} + \expandafter\addto@hook\expandafter\TP@toks\expandafter{ + \expandafter\KV@toks\expandafter{\TP@gtemp} + \edef#1{\the\KV@toks}} + \else + \@letinstance#1{#2}{#3} + \expandafter\expandafter\expandafter\addto@hook + \expandafter\expandafter\expandafter\TP@toks + \expandafter\expandafter\expandafter{ + \@letinstance#1{#2}{#3}} + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TP@do} +% Case switch on the possible key types. +% \begin{macrocode} +\def\TP@do#1#2#3\TP@do{ + \ifx#2f + \TP@f@shift{#1}#3\@@ + \else\ifx#2n + \TP@testopt{#1}{\TPnamecommand{#1}}#3\@@ + \else\ifx#2l + \TP@testopt{#1}{\TP@register\setlength{#1}}#3\@@ + \else\ifx#2L + \TP@testopt{#1}{\TP@fakeregister\setlength\fake@length + {#1}}#3\@@ + \else\ifx#2c + \TP@testopt{#1}{\TP@register\SetInternalCounter{#1}}#3\@@ + \else\ifx#2C + \TP@testopt{#1}{\TP@fakeregister\SetInternalCounter\@tempcnta + {#1}}#3\@@ + \else\ifx#2b + \TP@testopt{#1}{\TP@setboolean{#1}}#3\@@ + \else\ifx#2s + \TP@testopt{#1}{\TP@booltest{#1}}#3\@@ + \else\ifx#2g + \TP@testopt{#1}{\TP@setgeneral{#1}}#3\@@ + \else\ifx#2x + \TP@testopt{#1}{\TP@setx{#1}}#3\@@ + \else\ifx#2i + \TP@i@shift{#1}#3\@@ + \else\ifx#2+ + \def\TP@global{\addto@hook\TP@toks{\global}} + \TP@do{#1}#3\TP@do + \else + \PackageError{template}{Unknown~key~type~ (#2)~for~#1}\@eha + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@testopt} +% \begin{macrocode} +\def\TP@testopt#1#2{ + \@ifnextchar[%] + {\TP@test@pt{#1}{#2}} + {\TP@zap@@{#2}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@zap@@} +% \begin{macrocode} +\def\TP@zap@@#1#2\@@{ + #1{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@test@pt} +% \begin{macrocode} +\def\TP@test@pt#1#2[#3]#4\@@{ + #2 + {#4} + \begingroup + \TP@toks{} + \let\TP@remove\@gobble + \csname KV@\TP@name @#1\endcsname{#3} + \expandafter + \endgroup + \expandafter + \toks@\expandafter{ + \csname KV@\TP@name @#1\expandafter\endcsname\expandafter + {\the\expandafter\TP@toks\expandafter}\the\toks@}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@setgeneral} +% \begin{macrocode} +\def\TP@setx#1#2{ + \TP@define@key{#1}{\addto@hook\TP@toks{#2}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@setgeneral} +% \begin{macrocode} +\def\TP@setgeneral#1#2{ + \TP@define@key{#1}{#2}} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@setboolean} +% \begin{macrocode} +\def\TP@setboolean#1#2{ + \expandafter\let\csname if#2\endcsname\iftrue + \TP@define@key{#1}{ + \TPsetboolean{#2}{##1}} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPsetboolean} +% Modify so the boolean does not need to have been +% declared with |\newif| +% \begin{macrocode} +\def\TPsetboolean#1#2{ + \expandafter\ifx\csname if#2\endcsname\relax + \PackageError{template}{Bad~boolean~setting~#1=#2}\@eha + \else + \expandafter\let\csname if#1\expandafter\endcsname + \csname if#2\endcsname + \expandafter\addto@hook\expandafter\TP@toks\expandafter{ + \expandafter\let + \csname if#1\expandafter\endcsname\csname if#2\endcsname} + \fi} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@booltest} +% \begin{macrocode} +\def\TP@booltest#1#2{ + \TP@define@key{#1}{ + \TPbooltest{##1}#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@true} +% \begin{macrocode} +\def\TP@true{true} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPbooltest} +% \begin{macrocode} +\def\TPbooltest#1#2#3{ +% no error check on this yet. + \def\@tempa{#1} + \ifx\@tempa\TP@true + \addto@hook\TP@toks{#2} + \else + \addto@hook\TP@toks{#3} + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@register} +% This is normally called automatically by |\DeclareTemplate|. +% +% Command for setting a template attribute whose name +% corresponds directly to a tex count or length register\\ +% |#1| the fuction to set the value eg \setlength.\\ +% |#2| key name.\\ +% |#3| the register to set. +% +% This command \emph{fully evaluates} the argument at declare time, +% and assigns the value to the register. It also passes an assignment +% of the register to the final value into the parameter list for the +% template. +% +% If the value is a call to |\DelayEvaluation|, don't evaluate it now, +% just pass the whole assignment to the template. +% +% [Note that the code below contains some : being used in csnames in other files +% this is currently being allowed by default but in this one it is right now +% manually added --- need fixing either way] +% \begin{macrocode} +\catcode`\:=11\relax +\def\TP@register#1#2#3{ + \TP@define@key{#2}{ + \expandafter\ifx\@car##1\@nil\DelayEvaluation + \addto@hook\TP@toks{#1#3{##1}} + \else +% \end{macrocode} +% +% +% check for |\MultiSelection| creeping up and if so add something like +% +% \begin{verbatim} +% \setlength\register{\ifcase\selector \or value1 \or value2 +% ... \else valueotherwise \fi} +% \end{verbatim} +% to |\TP@toks|. +% +% \begin{macrocode} + \expandafter\ifx\@car##1..\@nil\MultiSelection + \begingroup + \TP@multi#1#3##1 + \endgroup +% \end{macrocode} +% +% +% there are probably better ways to do this :-) +% +% \begin{macrocode} + \expandafter\in@\expandafter\DelayEvaluation + \expandafter{\the\TP@multi@toks} + \ifin@ + \addto@hook:No\TP@toks + {\expandafter#1\expandafter#3\expandafter + {\the\TP@multi@toks}} + \else + \addto@hook:No\TP@toks + {\expandafter #3 + \expandafter= \the\TP@multi@toks\relax} + \fi +% \end{macrocode} +% +% +% otherwise do as before +% +% \begin{macrocode} + \else + #1#3{##1} + \addto@hook:No\TP@toks + {\expandafter #3 + \expandafter= \the#3\relax} + \fi\fi}} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\addto@hook:No} +% \begin{macrocode} +\def\addto@hook:No#1#2 { + \expandafter\addto@hook\expandafter#1\expandafter{#2}} +\catcode`\:=12\relax +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\DelayEvaluation} +% \begin{macrocode} +\let\DelayEvaluation\@firstofone +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPkeycommand} +% Same for macro names. Again usually called automatically when +% declaring a new template.\\ +% |#1| the key.\\ +% |#2| Determines how many arguments the function should have.\\ +% |#3| The macro to be defined. +% +% If the `|##1|`, the value passed as the argument of the key |#1| +% to the macro |#3| is invoked starts with |\FunctionInstance|, then a +% special procedure is taken. Instead of defining a macro with the +% specified number of arguments, the paramater list of the nested +% function instance is parsed, and |#3| is defined to be a macro +% expanding to that instance. In this case the specified template +% is responsible for picking up the requested number of +% arguments. (This is \emph{not} checked.) +% \begin{macrocode} +\def\TP@define@key#1#2{% + \expandafter\def + \csname KV@\TP@name @#1\expandafter\endcsname + \expandafter##\expandafter1 + \expandafter{ + \expandafter\TP@remove + \csname KV@\TP@name @#1\expandafter\endcsname + \TP@global + #2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@remove} +% \begin{macrocode} +\def\TP@remove#1{ + \def\@tempa##1#1##2##3#1##4\@@{ + \toks@{##1##3}} + \expandafter\@tempa\the\toks@#1\relax#1\@@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPkeycommand} +% \begin{macrocode} +\def\TPkeycommand#1#2#3{ + \TP@define@key{#1}{ +% \end{macrocode} +% +% |##1| can either be arbitrary inline code, in which case it will be +% defined with |\newcommand[val]| so it needs to use |#1| -- |#val|. +% +% define it locally here +% \begin{macrocode} + \functiondefine#2#3{##1} +% \end{macrocode} +% +% \begin{macrocode} + \expandafter\addto@hook\expandafter\TP@toks\expandafter{ + \the\TP@toksb{##1}} + } + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\TPnamecommand} +% Here is the extended version that tries to deal with +% |\MultiSelection|. +% +% In case of `n' keys there is no evaluation at declaration time so it +% is not sensible to look for |\DelayEvaluation|. For this reason as +% well as for the fact that |\TP@multi| above assumes that it deals +% with registers that can be accessed via |\the| we have to use a +% different command to handle the |\MultiSelection| args but +% it is essentially doing the same. +% +% \begin{macrocode} +\catcode`\:=11\relax +\def\TPnamecommand#1#2{ + \TP@define@key{#1}{ + \expandafter\ifx\@car##1..\@nil\MultiSelection + \begingroup + \TP@multi@name##1 + \endgroup + \addto@hook:No\TP@toks + {\expandafter\def\expandafter#2\expandafter + {\the\TP@multi@toks}} + \else + \def#2{##1} % setting it? + \addto@hook\TP@toks{\def#2{##1}} + \fi + } + } +\catcode`\:=12\relax +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@multi@name} +% \begin{macrocode} +%\catcode`\:=12\relax +\def\TP@multi@name #1#2#3#4{ + \global\TP@multi@toks{\ifcase #2} + \@for\next:=\@empty #3\do{ + \TP@do@multi\next +} + \global\addto@hook\TP@multi@toks{\else #4\fi} + } +%\catcode`\:=11\relax +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% +% \begin{macro}{\DeclareInstance} +% |{type}{instname}{templatename}{keyval}| +% \begin{macrocode} +\def\DeclareInstance{\DeclareCollectionInstance{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareCollectionInstance} +% |{collection}{type}{instname}{templatename}{keyval}| +% \begin{macrocode} +\long\def\DeclareCollectionInstance#1#2#3#4{ + \expandafter\TP@DCI\csname<#1>#2/#3\endcsname{#2/#4}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\UseCollection} +% |{type}{collection}| +% \begin{macrocode} +\def\UseCollection#1#2{ + \expandafter\edef\csname TP@<#1>\endcsname{ + {#2} + \TP@args{#1}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@letinstance} +% |\internalcommand{type}{instname}| +% \begin{macrocode} +\def\@letinstance#1#2#3{ + \expandafter\let\expandafter#1\csname + \@ifundefined{\TP@prefix{#2}#3} + {<>#2/} + {\TP@prefix{#2}} + #3 + \endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\UseInstance} +% |{type}{instname}| +% \begin{macrocode} +\def\UseInstance#1#2{ + \@letinstance\@tempa{#1}{#2} + \ifx\@tempa\relax + \INSTANCEundefined + \else + \expandafter\@tempa + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@fudge} +% \begin{macrocode} +\long\def\TP@fudge#1#2#3{% + \TP@DCI\TP@gtemp{#2/#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ShowTemplate} +% Some extension to |\ShowTemplate| so that we also get to see the +% restrictions if any +% \begin{macrocode} +\def\ShowTemplate#1#2{ + \typeout{*******~ Template:~ #1/#2~ *******} + \typeout{*} + \typeout{*~ Defaults:} + \typeout{*} + \typeout{\string\TPD>/#1/#2= + \expandafter\meaning\csname TPD>/#1/#2\endcsname} + \typeout{*} + \typeout{*~ Restrictions:} + \typeout{*} + \typeout{\string\TPR>/#1/#2= + \expandafter\meaning\csname TPR>/#1/#2\endcsname} + \typeout{*} + \typeout{*~ Body:} + \typeout{*} + \expandafter\show\csname TP>/#1/#2\endcsname} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\ShowCollectionInstance} +% \begin{macrocode} +\def\ShowCollectionInstance#1#2#3{ + \typeout{*******~ Instance:~ <#1>#2/#3~ *******} + \typeout{*} + \expandafter\show\csname <#1>#2/#3\endcsname} +\def\ShowInstance{\ShowCollectionInstance{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@fakeregister} +% |{setcomand}{privateregister}{key}{internalcode}| +% \begin{macrocode} +\catcode`\:=11\relax +\def\TP@fakeregister#1#2#3#4{ + \TP@define@key{#3}{ + \expandafter\ifx\@car##1..\@nil\DelayEvaluation +% \end{macrocode} +% In the v0.08 version of \texttt{template.dtx} a +% |\DelayEvaluation| for a faked register would simply be equiv to +% a |\def| (code is below commented out). The negative side effect +% of this is that something like |=L| used with |\DelayEvaluation| +% would not allow for calc syntax since it would end up as +% |\def|\allowbreak|\foo|\allowbreak|{a+b}|. The code below changes +% this to first assign to a scratch register (at runtime) and then +% do an |\edef|. Could be coded differently to save space (at cost +% of time) +% \begin{macrocode} +% \addto@hook\TP@toks{\def#4{##1}} + \addto@hook\TP@toks{#1#2{##1}\edef#4{\the#2}} + \else +% \end{macrocode} +% +% +% Otherwise same game for fake registers except that instead of +% passing the register to |\TP@multi| we pass a temp fake one and +% doing a def instead of using |\setlength| or |\setcounter| +% +% and i haven't done the |\DelayEvaluation| bit for that case! as +% i'm not sure what the best approach is for those +% things\footnote{we might disallow it for that case in general --- +% not a nice rule but an explainable one} +% +% \begin{macrocode} + \expandafter\ifx\@car##1..\@nil\MultiSelection + \begingroup + \TP@multi#1#2##1 + \endgroup + \addto@hook:No\TP@toks + {\expandafter\def\expandafter#4\expandafter + {\the\TP@multi@toks}} + \else + #1#2{##1} + \addto@hook:No\TP@toks + {\expandafter + \def + \expandafter + #4 + \expandafter + {\the#2}} + \fi\fi}} +\catcode`\:=12\relax +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TP@multi@toks} +% \begin{macrocode} +\newtoks\TP@multi@toks +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@multi} +% \marg{operation} \marg{register} |\MultiSelection| +% \marg{selector} \marg{case-list} \marg{else-case} +% +% This command builds up the |\ifcase| code from the three arguments +% of |\MultiSelection| and stores it in |\TP@multi@toks|. This code is +% supposed to be run in a group so a) we don't have to initialise +% |\TP@multi@toks| and b) all changes to the used registers not +% affecting the outside. +% +% Warning: this code uses |\@for| which will not work if put into files where +% ``:'' was made a letter! +% +% \begin{macrocode} +%\catcode`\:=12\relax +\def\TP@multi #1#2#3#4#5#6{ + \global\TP@multi@toks{\ifcase #4} + \@for\next:=\@empty #5\do{ + \expandafter \expandafter\expandafter\ifx\expandafter + \@car\next..\@nil\DelayEvaluation + \TP@do@multi\next + \else + #1#2{\next} + \TP@do@multi{\the#2} + \fi + } + \global\addto@hook\TP@multi@toks{\else #6\fi} + } +%\catcode`\:=11\relax +% \end{macrocode} +% +% Since we intend to add |\or| to |\TP@multi@toks| within the |\@for| +% loop we have to hide it carefully or else we will get some unmatched +% conditionals. +% \end{macro} +% +% \begin{macro}{\TP@do@multi} +% \begin{macrocode} +\def\TP@do@multi#1{ + \global\expandafter\addto@hook\expandafter\TP@multi@toks + \expandafter{\expandafter\or #1 } +} +% \end{macrocode} +% \end{macro} +% +% Since i like to set things like |item-label-text| using this +% mechanism i need to handle the `n' key specially. +% +% Actually i could have probably extended |\TPkeycommand| thus making +% this generally available to all f\meta{number} keys but was too lazy +% (or too stupid) to get it right first time so settled for the simple +% solution. +% +% So |\TP@do| now calls |\TPnamecommand| for the `n' key. looks like +% this thus be fixed some time soon +% +% +% +% +% +% +% \begin{macro}{\fake@length} +% \begin{macrocode} +\newlength\fake@length +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\IfExistsInstanceTF} +% tests that there is a \emph{default} definition +% taken from xinitials.dtx: +% \begin{macrocode} +\def\IfExistsInstanceTF#1#2{ + \expandafter\ifx\csname <>#1/#2\endcsname\relax + \expandafter\@secondoftwo + \else + \expandafter\@firstoftwo + \fi} +% \end{macrocode} +% +% FMi: what happens if we are in collection FOO and there exists an +% instance I for type T within this collection but there doesn't exist +% an instance in the empty collection? +% +% What would happen if \ldots\ --- not clear to me what the sematics +% really should be. The code below is not better only different( and +% slower).\footnote{fix semantics} +% \begin{macrocode} +\def\IfExistsInstanceTF#1#2{ + \@letinstance\@tempa{#1}{#2} + \ifx\@tempa\relax + \expandafter\@secondoftwo + \else + \expandafter\@firstoftwo + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareRestrictedTemplate} +% Setting it up: +% +%| \DeclareRestrictedTemplate|\\ +% |{T-type} {new-T-name} {source-T-name} {keyvals}| +% +% This uses the same code as {T-type} {source-T-name} but adds +% settings from {keyvals} +% \begin{macrocode} +\def\DeclareRestrictedTemplate#1#2#3#4{ + % CCC do we need a group here?? + \letcc { TPD>/#1/#2 } { TPD>/#1/#3 } + \letcc { TP>/#1/#2 } { TP>/#1/#3 } + \TP@get@restrictions {#1/#3} % puts stuff in \TP@toks + \setkeys{\the\TP@toksc} % temp OK? + {#4} % adds stuff to \TP@toks + \TP@store@restrictions {#1/#2}{#1/#3}} % stores the contents of + % \TP@toks +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\letcc} +% \begin{macrocode} +\def\letcc#1#2{ + \expandafter \let + \csname #1 \expandafter \endcsname + \csname #2 \endcsname} +% \end{macrocode} +% \end{macro} +% +% Internals: +% +% \begin{macro}{\TP@get@restrictions} +% These could probably be inlined, even when they do something! +% \begin{macrocode} +\def\TP@get@restrictions#1{ % Returns to \TP@toks the restrictions + % stored in the TP-structure (at present + % in YAM) of the template #1 + \@ifundefined {TPR>/#1} + {\TP@toks {}} + {\TP@toks \expandafter\expandafter\expandafter + {\csname TPR>/#1\endcsname}} + \@ifundefined {TPO>/#1} + {\@namedef {TPO>/#1} {#1} + \TP@toksc {#1} } % temp OK? + {\TP@toksc \expandafter\expandafter\expandafter + {\csname TPO>/#1\endcsname} }} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@store@restrictions} +% \begin{macrocode} +\def\TP@store@restrictions#1#2{ % Stores the contents of \TP@toks + % in the TP-structure (at present + % in YAM) of the template #1 + \expandafter\edef\csname TPR>/#1\endcsname{\the\TP@toks} + \@ifundefined{TPO>/#2} + {\@namedef{TPO>/#1}{#2}} + {\letcc{TPO>/#1}{TPO>/#2}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \Finale +% + + + |