% \iffalse meta-comment % %% File: latex-lab-template.dtx % % Copyright (C) 2026 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in the file % % https://www.latex-project.org/lppl.txt % % % The latex-lab bundle is developed in the LaTeX2e GitHub. % Issues may be reported at % % https://github.com/latex3/latex2e/issues % \def\ltlabtemplatedate{2026-08-01} \def\ltlabtemplateversion{0.6a} %<*driver> \DocumentMetadata{tagging=on,pdfstandard=ua-2} \documentclass[kernel]{l3in2edoc} \usepackage{amstext} \usepackage{xcolor} \EnableCrossrefs \CodelineIndex %\OnlyDescription \usepackage{todonotes} \begin{document} \DocInput{latex-lab-template.dtx} \PrintIndex \end{document} % % % \fi % % % \NewDocumentCommand\fmi{sO{}m} % {\IfBooleanTF{#1}{\todo[inline,#2]{#3}}^^A % {\todo[#2]{#3}}} % % \NewDocumentCommand\ufi{sO{}m} % {\IfBooleanTF{#1}{\todo[inline,#2]{UFi:#3}}^^A % {\todo[#2]{UFi:#3}}} % % \providecommand\key[1]{\texttt{#1}} % \providecommand\insttype[1]{\texttt{#1}} % % \providecommand\struct[1]{\texttt{<#1>}} % % % \title{Extending the \LaTeX{} templating mechanism} % \author{\LaTeX{} Project\thanks{Initial implementation by Frank Mittelbach.}} % \date{v\ltlabtemplateversion\ \ltlabtemplatedate} % % \maketitle % % % \begin{abstract} % Explain the concepts and requirements for \enquote{order} keys in templates. % \end{abstract} % % % \tableofcontents % \medskip % % % \begin{documentation} % % % % % % % \section{Handling \meta{order} keys in a generic way} % % Templates often have to typeset several items of textual data % (from keys and/or from template arguments) with slight variations % from instance to instance, e.g., the ordering and the separation % between the items might differ or in other cases only a subset of % the items are present (or supported). For example, a theorem-like % environment typically wants to have a fixed title, a number, some % punctuation, and possibly a note (provided through document % input). However, one design might ask for \enquote{Lemma 3.2 (note)}, % the next for \enquote{3.2 Lemma. (note)}, and another for % \enquote{3.2 Lemma \textit{note}.} with a different ordering and % a punctuation somewhere or not. % % While it is, of course, possible to achieve this by providing % different templates that only differ in small aspects, it is often % better to do this by providing a template key that defines the % order of certain elements (and in which you can leave out some) % and have the template code process this key and in this way achieve % various layouts through a single template. % % To make this possible such \meta{order} keys and their allowed % values need to follow a few conventions that we explain below and % give some examples. % % % % \subsection{Conventions for the \meta{order} comma list key} % % The \meta{order} key has to be a clist and the corresponding % variable name (i.e., the binding) must be % \cs{l_@@_\meta{order}_clist}, e.g., in % \cs{DeclareTemplateInterface} %\begin{verbatim} % caption-order : commalist = { title, separator-1, % number, separator-2, note, punct } %\end{verbatim} % and in \cs{DeclareTemplateCode} %\begin{verbatim} % caption-order = name {l_@@_caption-order_clist} %\end{verbatim} % The clist variable needs to contain the \meta{order} key name % which is why we had to resort to the \texttt{name} interface to % get a nonstandard variable name containing a \texttt{-}. For % simple key names like \key{order}, that would not be necessary % and the line would look like this: %\begin{verbatim} % order = \l_@@_order_clist %\end{verbatim} % Of course, there is no requirement to provide a default value (as % we did above) but in many cases there is a commonly used sequence that % could be provided as a default. % % % \subsection{Conventions for the items in the \meta{order} key clist} % % For each \meta{item} in the comma list, e.g, in the above example % \texttt{title}, \texttt{separator-1}, \texttt{number}, % \texttt{punct}, \texttt{separator-2}, and \texttt{note}, there has % to exist a variable with the name \cs{l_@@_\meta{item}_tl}. If % the items themselves are keys in the template that is achieved % through settings such as %\begin{verbatim} % title : tokenlist = Lemma , % separator-1 : tokenlist = \enspace , % ... %\end{verbatim} % and %\begin{verbatim} % title = \l_@@_title_tl , % separator-1 = name {l_@@_separator-1_tl} , % ... %\end{verbatim} % Again, we had to make use of the \texttt{name} keyword because % the key \key{separator-1} contains a hyphen. % % If the data of such an item is user input and provided through a % mandatory argument to the template, e.g., the data for a % \texttt{note}, then you fulfill the requirement by defining the % variable in the template code, e.g., %\begin{verbatim} % \tl_set:Nn \l_@@_note_tl {#3} %\end{verbatim} % or in whatever argument the note data is passed to the template. % % If the user hasn't provided a note, then this is indicated by % passing \cs{NoValue} to the template in that argument (as long as % \cs{NewDocumentCommand} or a similar extended command definition % offered by the \LaTeX{} kernel is used). In that case the % mechanism correctly interprets this and ignores \texttt{note} in % the processing of the \meta{order} key. % % The existence of \cs{l_@@_\meta{item}_tl} is required: if it is % not defined, then using \meta{item} in the comma list will lead to % an error message. % % Not required, but often wanted, are the following additional % token list variables and commands (per \meta{item}): % \begin{description} % \item[\cs{l_@@_\meta{item}_decls_tl}] % % A token list that contains declarations (such as font changes) % that are applied just before the \meta{item} data is % typeset. Processing happens in a group, so that changes are % reverted after the \meta{item} was typeset. % % \item[\cs{@@_\meta{item}_format:n}] % % A command that receives the \meta{item} data as its argument and % can then manipulate it prior to typsetting. % % \end{description} % % So in summary what gets typeset is % \begin{quote} % \cs{group_begin:} \\ % \hspace*{1em} \cs{l_@@_\meta{item}_decls_tl} \\ % \hspace*{1em} \cs{@@_\meta{item}_format:n} % \texttt{\{} \cs{l_@@_\meta{item}_tl} \texttt{\}} \\ % \cs{group_end:} % \end{quote} % % Strictly speaking, the \cs{l_@@_\meta{item}_decls_tl} token list % is not needed, since all one can do with it can also be done % through a suitably defined \cs{@@_\meta{item}_format:n} % command. Thus, what to use is often a matter of taste. Our % default templates provide both to cater for different % preferences. % % If the token list variable and command are exposed via keys (so that % they can be set in an instance) then the names have to be % given exactly as specified above in order for the mechanism to % pick them up. However, you are free to choose whatever key name % you like. By convention, we use \key{\meta{item}-decls} and % \key{\meta{item}-format} as key names because we always use % \texttt{-} in longer key names. % % % \subsection{Conventions for the separators used in the \meta{order} key clist} % % Besides items containing textual data there is also often the % need to specify data that separates them (typically by some % space). These separators need a somewhat different handling, % because if one item such as a \key{note} is not present, then a % separator before it should be dropped, e.g., one should not get % \enquote{Lemma 3.2\textvisiblespace .} but \enquote{Lemma 3.2.} % if the punctuation key \key{punct} comes at the end of the % \meta{order} list. % % We therefore recommend to use (some of) the following names that % have already been prepared for use with the % mechanism.\footnote{It is possible to use other names or provide % more with the help of \cs{template_new_order_separator:n} if % really necessary, but the five (or rather six) we offer should % normally be sufficient.} % % so the typical setup is %\begin{verbatim} % separator-1 : tokenlist = \ , % separator-2 : tokenlist = \ , % ... %\end{verbatim} % %\begin{verbatim} % separator-1 = name {l_@@_separator-1_tl} , % separator-2 = name {l_@@_separator-2_tl} , % ... %\end{verbatim} % up to \key{separator-5} and for cases where you need only one % separator there is also the key \texttt{separator} (which can of % course also be used in addition to the others). % % If several separators are specified directly after another in the % \meta{order} clist then all of them are typeset or dropped % depending on the next item that isn't a separator. Separator(s) % at the very start of the clist use the same logic. % % If a separator is specified at the very end of the clist it is % always typeset. % % If you need some separation that should not be dropped in case % the next normal item is absent (i.e., has \cs{NoValue} as its % value) then you can't use the standard separators. In that case use a % normal item and give it the value that you want for the % separation, e.g., a newline plus some vertical spacing. % % % \subsection{Grouping keys in the \meta{order} key clist} % % In some cases it is necessary to group some items in the \meta{order} % clist, e.g., to indicate that the \texttt{prefix} and the % \texttt{number} form the caption % label. This is done by using special items in the clist: % \texttt{<\meta{name}} to start a group and % \texttt{\meta{name}>} to end it. For example %\begin{verbatim} % order = { , ... } %\end{verbatim} % would group \texttt{prefix}, \texttt{separator-1}, and % \texttt{number}. % % These special group items have to be declared using the % declaration \cs{template_new_order_group:nnnnnn}. With such a % declaration they are made known to the order key % processing mechanism and the necessary tagging support code is defined, % e.g., in the above example tagging support would probably add a % \struct{Lbl} structure. % % Even though we may want to use \texttt{label} as a group % \meta{name} in different kinds of templates, the underlying tagging % support code will most likely differ from case to case. The % declaration therefore takes the current \meta{module} as its % first argument and \meta{name} as its second % argument.\footnote{This may need extension or change, e.g., % perhaps we need to make it based on the current template type and % template name to achieve a proper separation, but for now we hope % that \meta{module} is enough. This is quite different to the case of % separators which can be reused across all templates because they % only need to pass their values to the order key processing % mechanism, i.e., their definition is always the same.} The % remaining four arguments define what should happen when % \texttt{<\meta{name}} and \texttt{\meta{name}>} are % processed. Details are given in the implementation section. % % % To specify specific (typesetting) declarations for such a group % the token list \cs{l_@@_\meta{name}_decls_tl} is available. Thus, % the template can set up, for example %\begin{verbatim} % label-decls : tokenlist = , %\end{verbatim} % and %\begin{verbatim} % label-decls = \l_@@_label_decls_tl , %\end{verbatim} % to enable customization during instance declaration. If no % customization is desired then just don't expose the variable in % which case it automatically remains empty. Note that % \cs{@@_\meta{name}_format:n} \emph{is not supported} for such % groups. % % Examples for such group items can already be found in % \insttype{thmstyle} templates and in \insttype{caption} % templates. More will follow over time. % % % \subsection{Processing the \meta{order} key in the template code} % % In the template code you use the \meta{order} key in the following way %\begin{flushleft}\ttfamily\obeyspaces % \ \ \ \cs{template_process_order_clist:nnn} \\ % \ \ \ \ \ \ \{ \meta{module} \} \\ % \ \ \ \ \ \ \{ \meta{order key name} \} \\ % \ \ \ \ \ \ \{ \meta{supported items} \} %\end{flushleft} % where first argument is the current module name (i.e., what \texttt{@@} % produces but without the leading \verb/__/) and the second % argument is the name of your order key to process. % The % third argument is a comma list of support items, i.e., the value % of the \meta{order key name} must contain only items from that % argument.\footnote{This is checked to prevent the use of items % that aren't supported by the current template but are % defined by some other template and would therefore % produce unpredictable and erroneous results.} % % This command then typesets the items listed in the \meta{order} % key or more precisely the content stored in the associated token % list parameters \cs{l_@@_\meta{item}_tl}, applying % \cs{l_@@_\meta{item}_decls_tl} and/or \cs{@@_\meta{item}_format:n} if % defined, and ignoring those items that have \cs{NoValue} as their % token list value. Separators in front of ignored items are % dropped, all others are typeset in the specified places. % % The command also handles the tagging, i.e., it adds the necessary % structures. How this can be influenced is described below. % % % % \subsection{Tagging produced when processing the \meta{order} key} % % If nothing special is specified then the order key processing % mechanism typesets the items without adding any specific tagging % structures. It does, however, ensure that everything is wrapped % into one or more MCs (marked content structures). This is % normally automatically done by \LaTeX{}'s paragraph % tagging. However, in situations where the mechanism is applied, % we often need \cs{tagpdfparaOff} in which case switching in and % out of hmode does not generate MCs on its own. % The \cs{template_process_order_clist:nnn} command therefore % \begin{itemize} % \item % checks and remembers if an MC is already open at the start; % \item % if not, it opens one; % \item % it then processes all items, possibly also adding structure % elements as explained below; % \item % and at the end it restores the MC state it had found at the % beginning, e.g., closes the MC if none was open at the % start. % \end{itemize} % In addition it is also possible to surround individual items from % the \meta{order} list with a structure element, e.g., a % \struct{text-fragment} or an \struct{Artifact}. In this case, the current MC is ended, % the structure and a new MC are started, then the item is % typeset. Afterwards the MC and the structure are closed and the % next item in the list then opens a new MC to be used for the % remainder of the \meta{order} list.\footnote{Perhaps a better % approach would be to use dedicated sockets generated from the % \meta{item} name. That would give more flexibility that may be % needed.} % % For this to work the desired structure name needs to be stored in % the token list % \cs{l_@@_\meta{item}_tag_tl}. This can be hardwired in the % template code or offered through a key, if the need for % customization is expected, e.g. %\begin{verbatim} % prefix-tag-name : tokenlist , %\end{verbatim} % and %\begin{verbatim} % prefix-tag-name = \l_@@_prefix_tag_tl , %\end{verbatim} % and then changed with \texttt{prefix-tag-name = Artifact} in an % instance. % % As already mentioned, the grouping items also produce special % tagging. For example, an order key setting for a caption might % look like %\begin{verbatim} % order = {