Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set template keys docu #1614

Merged
merged 12 commits into from
Jan 20, 2025
6 changes: 6 additions & 0 deletions base/changes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ not part of the distribution.
* ltkeys.dtx
Parse global options only once per package (gh/1619)

2025-01-13 Frank Mittelbach <[email protected]>

* lttemplates.dtx (subsection{User functions}):
Speed up common case of \SetTemplateKeys, i.e., when the
key/val list is empty.

2025-01-11 Udi Fogiel <[email protected]>

* ltluatex.dtx (subsubsection{Handlers}):
Expand Down
170 changes: 122 additions & 48 deletions base/lttemplates.dtx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
%<*driver>
% \fi
\ProvidesFile{lttemplates.dtx}
[2024-11-17 v1.0d LaTeX Kernel (Prototype document functions)]
[2025-01-20 v1.0e LaTeX Kernel (Prototype document functions)]
% \iffalse
\documentclass{l3doc}
\GetFileInfo{lttemplates.dtx}
Expand Down Expand Up @@ -91,15 +91,15 @@
% \item Loading one of the many packages to customise certain elements of
% the standard classes.
% \item Loading a completely different document class, such as
% \textsf{KOMA-Script} or \textsf{memoir}, that allows easy customisation.
% \textsf{KOMA-Script} or \textsf{memoir}, that allows easy customization.
% \end{itemize}
% All three of these approaches have their drawbacks and learning curves.
%
% The idea behind \pkg{lttemplates} is to cleanly separate the three layers
% introduced at the beginning of this section, so that document authors who
% are not programmers can easily change the design of their documents.
% \pkg{lttemplates} also makes it easier for \LaTeX{} programmers to provide
% their own customisations on top of a pre-existing class.
% their own customizations on top of a pre-existing class.
%
% \section{What is a document?}
%
Expand All @@ -120,7 +120,7 @@
% contain the same sort of information but present it in slightly
% different ways. For example, the difference between a numbered and an
% unnumbered section, \cs{section} and |\section*|, or the difference
% between an itemised list or an enumerated list.
% between an itemized list or an enumerated list.
%
% There are three distinct layers in the definition of
% \enquote{a document} at this level
Expand Down Expand Up @@ -180,7 +180,7 @@
% \section{Templates}
% \label{sec:templates}
%
% A \emph{template} is a generalised design solution for representing
% A \emph{template} is a generalized design solution for representing
% the information of a specified type. Templates that do the same
% thing, but in different ways, are grouped together by their type
% and given separate names. There are two important parts to a template:
Expand Down Expand Up @@ -320,7 +320,7 @@
% \toprule
% \multicolumn{1}{l}{Key-type} & Description of binding \\
% \midrule
% \ & Boolean variable, \emph{e.g}.~\cs{l_tmpa_bool} \\
% boolean & Boolean variable, \emph{e.g}.~\cs{l_tmpa_bool} \\
% choice
% & List of choice implementations
% (see Section~\ref{sec:choices-key}) \\
Expand Down Expand Up @@ -351,12 +351,95 @@
% In the final argument of \cs{DeclareTemplateCode} the assignment of
% keys defined by the template may be delayed by including the command
% \cs{AssignTemplateKeys}. If this is \emph{not} present, keys are assigned
% immediately before the template code. If \cs{AssignTemplateKeys} is
% immediately before the template code. If an
% \cs{AssignTemplateKeys} command is
% present, assignment is delayed until this point. Note that the
% command must be \emph{directly} present in the code, not placed
% within a nested command/macro.
% \end{function}
%

% \begin{function}{\SetKnownTemplateKeys,\SetTemplateKeys,\UnusedTemplateKeys}
% \begin{syntax}
% \cs{SetKnownTemplateKeys} \Arg{type} \Arg{template} \Arg{keyvals}
% \cs{SetTemplateKeys} \Arg{type} \Arg{template} \Arg{keyvals}
%
% \cs{UnusedTemplateKeys} \% all \meta{keyvals} unused by previous \cs{SetKnownTemplateKeys}
% \end{syntax}
%
% In the final argument of \cs{DeclareTemplateCode} one can also
% overwrite (some of) the current template key value settings by
% using the command \cs{SetKnownTemplateKeys} or
% \cs{SetTemplateKeys}, i.e., they can overwrite the template default values and
% the values assigned by the instance.
%
% The \cs{SetKnownTemplateKeys} and \cs{SetTemplateKeys} commands
% are only supported within the code of a template; using them
% elsewhere has unpredictable results. If they are used together
% with \cs{AssignTemplateKeys} then the latter command should come first
% in the template code.
%
% The main use case for these commands is the situation where there
% is an argument (normally \texttt{\#1}) to the template in which
% a key/value list can be specified that overwrites the normal
% settings. In that case one could use
FrankMittelbach marked this conversation as resolved.
Show resolved Hide resolved
%\begin{quote}
% \verb/\SetKnownTemplateKeys/\Arg{type}\Arg{template}\verb/{#1}/
%\end{quote}
% to process this key/value list inside the template.
%
% If \cs{SetKnownTemplateKeys} is executed and the \meta{keyvals} argument contains keys not known to the
% \meta{template} they are simply ignored and stored in the
% tokenlist \cs{UnusedTemplateKeys}
% without generating an error. This way it is possible to
% apply the same key/val list specified by the user on a
% document-level command or environment to several templates, which
% is useful, if the command or environment is implemented by calling several different template instances.
%
% \end{function}
%
% As a variation of that, you can use this key/val
% list the first time, and for the next template instance use what remains in
% \cs{UnusedTemplateKeys} (i.e., the key/val list with only the keys that have not been processed previously). The final processing step could then be
% \cs{SetTemplateKeys}, which unconditionally attempts to set the
% \meta{keyvals} received in its third argument. This command
% complains if any of them are unknown keys. Alternatively, you
% could use \cs{SetKnownTemplateKeys} and afterwards check whether \cs{UnusedTemplateKeys} is empty.\footnote{Using
% \cs{SetTemplateKeys} exposes the inner structure of the template
% keys when generating an error. This is something one may want to
% avoid as it can be confusing to the user, especially if several
% templates are involved. In that
% case use \cs{SetKnownTemplateKeys} and afterwards check whether
% \cs{UnusedTemplateKeys} is empty; if it is not empty then generate your own
% error message.}
%
% For example, a list, such as \env{enumerate}, is made up from a
% \texttt{blockenv}, \texttt{block}, \texttt{list}, and a
% \texttt{para} template and in the single user-supplied optional
% argument of \env{enumerate} key/values for any of these templates might
% be specified.
%
% In fact, in the particular example of list environments,
% the supplied key/value list is also saved and then applied to each
% \cs{item} which is implemented through an \texttt{item}
% template. This way, one can specify one-off settings for all the items
% of a single list (on the environment level), as well as to
% individual items within that list (by specifying them in the
% optional argument of an \cs{item}). With
% \cs{SetKnownTemplateKeys} and \cs{SetTemplateKeys} working
% together, it is possible to provide this flexibility and still
% alert the user when one of their keys is misspelled.
%
% On the other hand you may want to allow for
% \enquote{misspellings} without generating an error or a
% warning. For example, if you define a template that accepts only a
% few keys, you might just want to ignore anything specified in the
% source when you use this template in place of a different one,
% without the need to alter the document source. Or you might just
% generate a warning message, which is easy, given that the unused
% key/values are available in the \cs{UnusedTemplateKeys} variable.
%
%
% \begin{function}{\DeclareTemplateCopy}
% \begin{syntax}
% \cs{DeclareTemplateCopy}
Expand Down Expand Up @@ -418,7 +501,7 @@
% For keys which accept the values \texttt{true} and \texttt{false}
% both the boolean and choice key types can be used. As template
% interfaces are intended to prompt clarity at the design level, the
% boolean key type should be favoured, with the choice type reserved
% boolean key type should be favored, with the choice type reserved
% for keys which take arbitrary values.
%
% \section{Instances}
Expand All @@ -432,10 +515,10 @@
% are input into it.
%
% For example, a template might say \enquote{here is a section with or
% without a number that might be centred or left aligned and print its
% without a number that might be centered or left aligned and print its
% contents in a certain font of a certain size, with a bit of a gap
% before and after it} whereas an instance declares \enquote{this is a
% section with a number, which is centred and set in $12\,\text{pt}$
% section with a number, which is centered and set in $12\,\text{pt}$
% italic with a $10\,\text{pt}$ skip before and a
% $12\,\text{pt}$ skip after it}. Therefore, an instance is just a
% frozen version of a template with specific settings as chosen by the
Expand Down Expand Up @@ -516,8 +599,8 @@
% detailed by the \meta{type} declaration. This in effect
% is the same as creating an instance using \cs{DeclareInstance}
% and immediately using it with \cs{UseInstance}, but without the
% instance having any further existence. It is therefore useful where
% a template needs to be used once.
% instance having any further existence. This command is therefore useful when
% a template needs to be used only once.
%
% This function can also be used as the argument to \texttt{instance}
% key types:
Expand Down Expand Up @@ -565,39 +648,6 @@
% template untouched.
% \end{function}
%
% \section{\emph{Ad hoc} adjustment of templates}
%
% \begin{function}{\SetTemplateKeys}
% \begin{syntax}
% \cs{SetTemplateKeys} \Arg{type} \Arg{template} \Arg{keyvals}
% \end{syntax}
% At point of use it may be useful to apply changed to individual instances.
% This is supported as each template key is made available for adjustment
% using \cs{SetTemplateKeys}.
% \end{function}
%
% For example, after
% \begin{verbatim}
% \NewTypeType{MyObj}{0}
% \DeclareTemplateInterface{MyObj}{TemplateA}{0}
% {
% akey: tokenlist ,
% bkey: function{2}
% }
% \DeclareTemplateCode{MyObj}{TemplateA}{0}
% {
% akey = SomeTokens ,
% bkey = \func:nn ,
% }
% \end{verbatim}
% the template keys could be adjusted in an \emph{ad hoc} fashion using
% \begin{verbatim}
% \SetTemplateKeys{MyObj}{TemplateA}
% {
% akey = OtherTokens ,
% bkey = \AltFunc:nn
% }
% \end{verbatim}
%
% \section{Getting information about templates and instances}
%
Expand Down Expand Up @@ -2619,11 +2669,35 @@
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SetTemplateKeys}
% A friendly wrapper
% \begin{macro}{\SetKnownTemplateKeys,\SetTemplateKeys}
% A friendly wrapper, with some speed up for the common case of the
% third argument being empty.
% \changes{2025-01-08}{v1.0d}{Test for empty key/val list to speed up processing}
% \begin{macrocode}
\cs_new_protected:Npn \SetKnownTemplateKeys #1#2#3
{
\tl_if_empty:oTF {#3}
{
\tl_set_eq:NN \UnusedTemplateKeys \c_empty_tl
}
{
\keys_set_known:noN { template / #1 / #2 } {#3} \UnusedTemplateKeys
}
}
% \end{macrocode}
%
% \begin{macrocode}
\cs_new_protected:Npn \SetTemplateKeys #1#2#3
{ \keys_set_known:nnN { template / #1 / #2 } {#3} \l_@@_tmp_clist }
{
\tl_if_empty:oF {#3}
{
\keys_set:no { template / #1 / #2 } {#3}
}
}
% \end{macrocode}
%
% \begin{macrocode}
\tl_new:N \UnusedTemplateKeys
% \end{macrocode}
% \end{macro}
%
Expand Down
Loading
Loading