Skip to content

Commit

Permalink
Set template keys docu (#1614)
Browse files Browse the repository at this point in the history
* typo

* reordered and changed docu

* testing for empty in \SetTemplateKays; more docu; changelog; open: csname change

* update to \SetKnownTemplateKeys et al; new handling of user supplied keys (checking) --- WIP

* missing decl

* Make a proper error message and document why \SetTemplateKeys may not be a good choice compared to \SetKnownTemplateKeys

* update after review

* updating and reorganizing docu after review

* typo
  • Loading branch information
FrankMittelbach authored Jan 20, 2025
1 parent 10aa4e1 commit 1990ab7
Show file tree
Hide file tree
Showing 6 changed files with 352 additions and 66 deletions.
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
%\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

0 comments on commit 1990ab7

Please sign in to comment.