% \iffalse meta-comment % %% File: l3prop.dtx % % Copyright (C) 1990-2022 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 % % This file is part of the "l3kernel bundle" (The Work in LPPL) % and all files in that bundle must be distributed together. % % ----------------------------------------------------------------------- % % The development version of the bundle can be found at % % https://github.com/latex3/latex3 % % for those people who are interested. % %<*driver> \documentclass[full,kernel]{l3doc} \usepackage{mkessler-todo} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \title{^^A % The \pkg{l3prop} package\\ Property lists^^A % } % % \author{^^A % Maximilian Keßler % } % % \date{Released 2022-01-12} % % \maketitle % % % \NewDocumentCommand{\kw}{m} % {% % \texttt{#1}% % } % % \NewDocumentCommand{\vocab}{m} % {% % \emph{#1}% % } % % \begin{documentation} % % \tableofcontents % % A central thing in \LaTeX is the usage of \enquote{theorems}. % With \enquote{theorems} we actually mean \enquote{environments} that typically % have a title, some style applied to their contents and are numbered throughout % the document, often later referenced by number and / or name. % % Mechanisms for generating such environments are packages like % \pkg{amsthm}, \pkg{ntheorem}, \pkg{thmtools}. % % While the mechanism in \pkg{thmtools} are pretty versatile and suffice % for almost all needs, it is pretty time-consuming to largely change % the behavior of environments, or have small variants of these. % % This package aims at both providing a versatile mechanism, \meta{theorem group}s, % to structure theorems into groups that can subsequently easily altered, % as well as a mechanism for easily generating \meta{theorem families}. % % As the author is of the opinion that of the mentioned theorem controlling packages % \pkg{thmtools} provides the most versatile interface, the \pkg{groupthm} % will be working on top of \pkg{thmtools} and use this as a backend for declaring % the \meta{theorem}s themselves. % % Thus, any styles supported by \pkg{thmtools} will be supported by \pkg{groupthm} % as well, by passing them to \pkg{thmtools}. % % \section{Concepts} % % \subsection{Theorem groups} % \label{sec:theorem-groups} % A \meta{theorem group} is some named group holding some properties for % the \meta{theorem}s that are contained in this group. % Each \meta{theorem} can, when declared, be part of arbitrarily many \meta{theorem group}s, % and will be subject to the styles these groups defined. % % This enables to group similar \meta{theorem}s and alter them at a late stage of % document development in a unique manner, by only having to change the % definition of the \meta{theorem group}, and not all \meta{theorem}s separately. % % The properties. such a \meta{theorem group} can hold are as follows % % % \begin{description} % \item[\kw{prename}] A prefix (any \meta{token list}) that will be inserted % before the theorem name of each member of this \meta{theorem group}. % \item[\kw{postname}] A suffix (any \meta{token list}) that will be % inserted before the theorem name for each member of this \meta{theorem group}. % This could be e.g.~some \enquote{$\star$} appended to the name to indicate % variants of environments. % \item[\kw{mapname}] A \meta{function} (some macro that takes exactly one argument) % that is applied to the \kw{name}. % \item[\kw{thmtools}] A \meta{clist} of key-value pairs that are passed to the underlying % \pkg{thmtools} backend of the \meta{theorem}. % This allows e.g.~to set the \kw{topskip} of a certain class of \meta{theorem}s. % \end{description} % % The most versatile key here is certainly the \kw{thmtools} key, % providing the most customization to an end user (like you). % % As mentioned, each \meta{theorem} can be member of arbitrary many \meta{theorem group}s, % and will posses their corresponding properties. % % To adjust finer controlling of these \meta{theorem group}s, \meta{theorem group}s can inherit from each other, and \meta{theorem group}s are subject to a hierarchy that controls precedence in case % of conflicting properties of different \meta{theorem group}s a \meta{theorem} may be part of. % % This hierarchy can of course be controlled by the user. % % \subsection{Grouped theorems} % % A \meta{grouped theorem} is just a theorem that is a member of % a given set of groups (possibly empty). % It behaves just a regular theorem, except that by changing the definition of % its theorem groups, we can alter its behavior. % % % It is the core concept of the \pkg{groupthm} package. % For brevity, we will often talk about \enquote{theorems}, % although in fact we mean \enquote{grouped theorems}. % % \subsection{Theorem families} % Often, one needs some small \meta{theorem variant}s of some \meta{theorem}, the most typical % example being \vocab{starred} version of \meta{theorem}s that are not numbered % in contrast to their counterparts. % % \begin{verbatim} % \begin{theorem} % This theorem is numbered. % \end{theorem} % % \begin{theorem*} % This theorem is not numbered. % Probably because we do not want a reference to it. % \end{theorem*} % \end{verbatim} % \todo{insert code example output} % % \pkg{groupthm} extends this idea and provides a versatile mechanism to define a % \meta{theorem family}, which is based on some \meta{theorem name} and % parses additional arguments / syntax to control the \meta{theorem groups} % that this environment is a part of. % % So, in addition the name of a \meta{theorem}, the corresponding environment will % accept some options and toggle the membership of certain \meta{theorem groups}, % thus further customizing its appearance. % % This can lead e.g.~to usages like the following: % % \begin{verbatim} % \begin{theorem}* % This theorem has a visual * at its name. % \end{theorem} % \end{verbatim} % \todo{code} % % Providing this consists of two parts: % declaring the \meta{theorem family} by listing the groups that can be toggled % by this \meta{theorem family}, and declaring the actual option parsing % of the \meta{theorem family}, which then controls the membership in these groups % (and of course prior to this the definition of the desired \meta{theorem group}s). % % % % \subsection{General notions} % % In many cases, there are a number of variants of some command, % call it for example \cs{Foo}. % Then the documentation will look like % % % \begin{function}{\NewFoo, \RenewFoo, \ProvideFoo, \DeclareFoo} % Defines some \kw{foo} \ldots % \end{function} % % % and will not mention anything about the variants. % This follows some general naming convention that also \pkg{xparse} uses, % and is the following: % % \begin{description} % \item[\cs{NewFoo}] % % Defines \kw{foo} if not defined already. % This emits an error in case it has been defined yet. % % \item[\cs{RenewFoo}] % % Redefines \kw{foo} if defined already. % This emits an error in case it has \emph{not} been defined yet. % % \item[\cs{ProvideFoo}] % % Defines \kw{foo} if it is not defined already. % This does not emit an error if \kw{foo} is already defined % (and has no effect in this case). % % \item[\cs{DeclareFoo}] % % Defines \kw{foo} in disregard of any % existing definitions. Any old definition will be overwritten (if present). % \end{description} % % % The documentation margin will list all variants that are available, % they follow their respective conventions. % % % \begin{texnote} % The \pkg{thmtools} package, unfortunately, dose not follow this convention, % as its \cs{declaretheorem} command actually behaves like a \cs{newtheorem}. % The reason for this is that \pkg{amsthm} already defines \cs{newtheorem}. % % Thus, actually, calls to \cs{NewGroupedTheorem} will have an underlying % \cs{declaretheorem}, but you do not have to bother with this. % \end{texnote} % % \section{Theorem groups} % % \subsection{Defining theorem groups} % % \begin{function}{\NewTheoremGroup, \RenewTheoremGroup, \ProvideTheoremGroup, \DeclareTheoremGroup} % \begin{syntax} % \cs{NewTheoremGroup}[\meta{keys}]\{\meta{theorem group}\} % \end{syntax} % % This introduces a new \meta{theorem group} with the given name. % The \meta{keys} available are the same as introduced in \autoref{sec:theorem-groups}: % % \begin{description} % \item % % \kw{prename} = \meta{token list}. % Insert the \meta{token list} in front of the theorem name. % % \item % % \kw{postname} = \meta{token list}. % Insert the \meta{token list} after the theorem name. % % \item % % \kw{mapname} = \meta{function}. % Apply this \meta{function} to the theorem name. % % \item % % \kw{thmtools} = $\{$\meta{clist}$\}$. % Pass these options to \pkg{thmtools}. % % \end{description} % % For uniqueness of the given options, the \meta{clist} given to the \kw{thmtools} key % has to be surrounded by a pair of braces. % % \begin{texnote} % The \kw{mapname} is expected to be a function of \cs{fun:n}. % It is subject to an \kw{x}-type expansion prior to being passed further to \pkg{thmtools}. % \end{texnote} % % \end{function} % % \subsection{Controlling theorem group precedence} % % \begin{function}{\DeclareTheoremGroupRule} % \begin{syntax} % \cs{DeclareTheoremGroupRule}[\meta{keyname}]% % \{\meta{theorem group 1}\}\{\meta{relation}\}\{\meta{theorem group 2}\} % \end{syntax} % % This declares some relation between the two theorem groups, % controlling their order of application in case a theorem is member % of both groups. % % The \meta{keyname} can be one of \kw{prename}, \kw{postname}, \kw{mapname}, \kw{thmtools}. % If present, it declares the corresponding relation only for this subkey. % This can lead to \meta{theorem group 1} overwriting \meta{theorem group 2} when given % contradictory \pkg{thmtools} options, but the \kw{prename} of \meta{theorem group 1} % being applied after the one of \meta{theorem group 2}. % When the \meta{keyname} is not given, this applies to all keywords. % % \begin{texnote} % The \meta{keyname} is just passed to the corresponding argument % of the \kw{lthooks} package. % If the option argument is not present, \kw{??} is used, this has the described effect. % \end{texnote} % % The behavior of the relations is based on the \cs{DeclareHookRule} command % from the \pkg{xparse} package, and all respective keys are in fact available, % but typically not needed, so the reader of this manual is referred to the % \todoref{lthooks} packages documentation for a list of the full keys. % For us, the following list will suffice: % % \begin{description} % \item[\kw{higher} or \kw{after} or \kw{\string>}] % % \meta{theorem group 1} takes precedence over \meta{theorem group 2}. % Its \kw{prename} is applied after the one of \meta{theorem group 2}. % % \item[\kw{lower} or \kw{before} or \kw{\string<}] % % \meta{theorem group 2} takes precedence over \meta{theorem group 1}. % Its \kw{prename} is applied after the one of \meta{theorem group 1}. % % \end{description} % % \begin{texnote} % The \meta{relation} is first stripped, % then checked if it matches either \kw{higher} or \kw{lower} % and in this case replaced by the corresponding \pkg{lthooks} variant % of the relation. % The rest is passed as is to \pkg{lthooks} and thus subject to the usual % normalization process of \pkg{lthooks}. % \end{texnote} % % \end{function} % % % \subsection{Inheritance of theorem groups} % \begin{function}{\AddTheoremGroupParent} % \begin{syntax} % \cs{AddTheoremGroupParent}\{\meta{theorem group 1}\}\{\meta{theorem group 2}\} % \end{syntax} % Declares \meta{theorem group 1} to \enquote{inherit} all properties % of \meta{theorem group 2}. % In other words, \meta{theorem group 2} is a parent of \meta{theorem group 1} % in a usual inheritance graph. % % The definitions of the groups themselves are unchanged, % but each new theorem defined with \meta{theorem group 1} will also % have the properties of \meta{theorem group 2}. % % Inheritance is transitive, when defining a new theorem, we just flatten out the % inheritance graph and apply all properties. % % Inheritance is subject to the usual theorem group hierarchies as discussed in \todoref. % This can even yield to situations, where \meta{theorem group 1} inherits % from \meta{theorem group 2}, but \meta{theorem group 2} overwrites % \meta{theorem group 1}. % \end{function} % % \subsection{Appending to theorem groups} % \begin{function}{\AppendToTheoremGroup} % \begin{syntax} % \cs{AppendToTheoremGroup}[\meta{keys}]\{\meta{theorem group}\} % \end{syntax} % Adds the properties given as \meta{keys} to the theorem group. % The syntax for the \meta{keys} is the same as in \cs{NewTheoremGroup}. % \end{function} % % \subsection{Default theorem groups} % % There are a number of theorem groups that \pkg{group them} will initially declare % and that have certain special treatment in some places. % % \begin{function}{all} % Every declared grouped theorem is a member of this group. % % Initially, this group has no effect (i.e.~an empty property list). % It can be redefined by the user to alter the behavior of all grouped theorems % in a unified way. % % It is the lowest theorem group in the hierarchy by default. % \end{function} % % \begin{function}{starred} % This is group that shall represent the standard variant of theorems that % are called with a \enquote{*} in the environment name. % Theorems of this group are not numbered. % % The user should not add theorems to this group by hand, % as this is handled in a unified way by default. % \todoref{} % % It is the highest theorem group in the hierarchy by default, % except for \cs{unnumbered}, % with which it has no relation. % \end{function} % \addtocounter{footnote}{-1} % % \begin{function}{unnumbered} % Theorems in this group are not numbered. % % It is the highest theorem group in the hierarchy by default, % except for \cs{starred}, % with which it has no relation. % \end{function} % % The reason for the two groups \kw{starred} and \kw{unnumbered} % to both exist is that the \kw{starred} group is \emph{meant} to be applied % to theorems that were called with a \enquote{*} in their name (thus the name), % whereas the \enquote{unnumbered} group \emph{means} that the environment % is 'just unnumbered'. % % This has two reasons: % First, this enables more fine-tuning of the behavior of the theorems in post-processing % of a document. % Second, more importantly, this distinguishes semantically between the environments % \kw{theorem} and \kw{theorem*}, even if \kw{theorem} is in the \kw{unnumbered} group. % % So assuming that \kw{theorem} is member of the \kw{unnumbered} group, both calls % % \begin{verbatim} % \begin{theorem} % This is not numbered. % \end{theorem} % \begin{theorem*} % This is not numbered. % \end{theorem*} % \end{verbatim} % % are defined and will produce the same result by default, but we could still % change the definition of the \kw{starred} group later to do anything we want. % % \begin{texnote} % The mentioned hierarchies are kept intact for newly defined theorem groups, % i.e.~for each new such group, two theorem group rules are created. % \end{texnote} % % \section{Grouped Theorems} % % \subsection{Defining grouped theorems} % % \begin{function}{\NewGroupedTheorem, \ProvideGroupedTheorem} % \begin{syntax} % \cs{NewGroupedTheorem}[\meta{keys}]\{\meta{theorem name}\} % \end{syntax} % This defines \meta{theorem name} as a new theorem environment. % Its properties can be set by the following keys: % % \begin{description} % % \item % % \kw{name} $=$ \meta{displayed name}. % If given, this is the displayed name of the environment in the document. % If not present, the \meta{theorem name} is also used as the \meta{displayed name} % in capitalized form. % % \item % % \kw{group} $=$ \{\meta{clist}\} % % Makes this theorem a member of the listed groups. % It will inherit all respective properties of these groups. % % If groups are present more than one time, this has no (additional) effect. % % \item % % \kw{thmtools} = \{\meta{clist}\} % % Passes these option to the \pkg{thmtools} environment that is declared internally. % % \end{description} % \end{function} % % \begin{function}{\NewGroupedTheorem*,\ProvideGroupedTheorem*} % \begin{syntax} % \cs{NewGroupedTheorem*}[\meta{keys}]\{\meta{theorem name}\} % \end{syntax} % Behaves the same as \cs{NewGroupedTheorem}, % but also adds the theorem to the default \kw{unnumbered} group, % thus resulting in the environment not being numbered. % % This is thus equivalent to using \cs{NewGroupedTheorem} and adding the % \kw{unnumbered} group. % \end{function} % % \begin{function}{\NewTheorem, \ProvideTheorem} % \begin{syntax} % \cs{NewTheorem}[\meta{keys}]\{\meta{theorem name}\} % \end{syntax} % % This behaves essentially the same as \cs{NewGroupedTheorem}, % but will define two grouped theorems, namely \meta{theorem name} and \meta{theorem name*}. % % The \meta{theorem name*} environment has the same properties as the \meta{theorem name}, % but will be member of the \kw{starred} theorem group. % It is thus not recommended to call \cs{NewTheorem} % with an actual \enquote{*} in the environment name, since both environments % will be generated. % \end{function} % % \begin{function}{\NewTheorem*, \ProvideTheorem*} % \begin{syntax} % \cs{NewTheorem}[\meta{keys}]\{\meta{theorem name}\} % \end{syntax} % Combines the behavior of \cs{NewGroupedTheorem*} and \cs{NewTheorem}, thus % declaring \meta{theorem} to (additionally) be member of the \kw{unnumbered} % and \meta{theorem*} to (additionally) be member of the \kw{starred} group. % % As mentioned in \todoref, by default both environments will behave the same. % \end{function} % % \subsection{Defining families of grouped theorems} % % \begin{function}{\NewGroupedTheoremFamily, \ProvideGroupedTheoremFamily} % \begin{syntax} % \cs{NewTheoremFamily}[\meta{keys}]\{\meta{theorem name}\} % \end{syntax} % % Defines a family of grouped theorems. % The \meta{keys} accept the same arguments as the \cs{NewGroupedTheorem} macro. % However, for each \emph{subset} of the given groups, % a grouped theorem is defined. % % These grouped theorems are not meant to be accessed directly (but could), % so we omit their actual (internal) names here. % To call these, some \kw{GroupedTheoremFamilyOptions} have to specified, % see \cs{NewGroupedTheoremFamilyOptions}. % \end{function} % % \begin{function}{\NewGroupedTheoremFamily*, \ProvideGroupedTheoremFamily*} % Behaves the same as \cs{NewGroupedTheoremFamily}, but also adds each variant % to the default \kw{unnumbered} group, thus resulting in the environments not being % numbered. % % This is \emph{almost} equivalent to calling \cs{NewGroupedTheoremFamily} % with the \kw{unnumbered} group being present, as it does not generate the variants % where the \kw{unnumbered} group is not present. % \end{function} % % \begin{function}{\NewTheoremFamily, \ProvideTheoremFamily} % This behaves essentially the same as \cs{NewGroupedTheoremFamily}, % but will add the \kw{starred} group to the list of groups and also generate variants % for these. % % It is thus not recommended to call \cs{NewTheoremFamily} with the \kw{starred} % group explicitly given, since this is added anyways. % \end{function} % % \begin{function}{\NewTheoremFamily*, \ProvideTheoremFamily*} % Combines the behavior of \cs{NewGroupedTheoremFamily*} and \cs{NewTheoremFamily}, thus % declaring all variants to (additionally) be member of the \kw{unnumbered} % group, and also generates definitions with and without the \kw{starred} group. % % As mentioned in \todoref, by default both environments will behave the same. % \end{function} % % % \begin{function}{\AddTheoremToGroup} % \begin{syntax} % \cs{AddTheoremToGroup}\{\meta{theorem group}\} % \end{syntax} % % Means that the current invocation of a theorem family should % call the theorem variant with the given group. % % Can only be used in the body of \cs{NewGroupedTheoremFamilyOptions} or similarly. % \end{function} % % \begin{function} % { % \NewGroupedTheoremFamilyOptions, \RenewGroupedTheoremFamilyOptions, % \ProvideGroupedTheoremFamilyOptions, \DeclareGroupedTheoremFamilyOptions % } % \begin{syntax} % \cs{NewGroupedTheoremFamilyOptions}\{\meta{theorem name}\}\{\meta{argument specifiation}\}% % \{\meta{selection body}\} % \end{syntax} % % Defines a new environment with options, given by \meta{theorem name}. % The \meta{argument specification} can be any valid \pkg{xparse} argument specification. % % The \meta{selection body} is there to process the options of % the \meta{argument specification} and select which variant of the \meta{theorem name} % to enter. % The arguments are available as usual with \pkg{xparse} by \kw{\#1}, \kw{\#2}, \ldots % % The body may also call any number of \cs{AddTheoremToGroup} calls, % which enables the corresponding groups. % % When the environment is called within the document, the options are parsed % as with \pkg{xpars} and the \meta{selection body} is executed. % Immediately after, the theorem variant of \meta{theorem name} with the specified groups % by \cs{AddTheoremToGroup} is called. % % At the end of the environment, the \meta{selection body} is executed again and the % called theorem variant is ended again. % % The possible theorem variants that the newly declared environment will call % \emph{have to be generated subsequently} by a call to the \cs{NewGroupedTheoremFamily} % function. % % \end{function} % % \begin{function} % { % \NewGroupedTheoremFamilyOptions*, \RenewGroupedTheoremFamilyOptions*, % \ProvideGroupedTheoremFamilyOptions*, \DeclareGroupedTheoremFamilyOptions* % } % \begin{syntax} % \cs{NewGroupedTheoremFamilyOptions*}\{\meta{theorem name}\}\{\meta{argument specifiation}\}% % \{\meta{selection body}\} % \end{syntax} % % Does the same as \cs{NewGroupedTheoremFamilyOptions}, % but calls the variants with the additional \kw{unnumbered} group. % % The possible theorem variants have to be generated % with the \cs{NewGroupedTheoremFamily*} command before. % % \end{function} % % \begin{function} % { % \NewTheoremFamilyOptions, \RenewTheoremFamilyOptions, % \ProvideTheoremFamilyOptions, \DeclareTheoremFamilyOptions % } % \begin{syntax} % \cs{NewTheoremFamilyOptions}\{\meta{theorem name}\}\{\meta{argument specifiation}\}% % \{\meta{selection body}\} % \end{syntax} % % This behaves essentially the same as \cs{NewGroupedTheoremFamilyOptions}, % but also declares the environment \meta{theorem name*}, % which behaves the same but calls the theorem variants with the additional \kw{starred} % subgroup. % % The possible theorem variants have to be generated with the \cs{NewTheoremFamily} % command before. % % \end{function} % % \begin{function} % { % \NewTheoremFamilyOptions*, \RenewTheoremFamilyOptions*, % \ProvideTheoremFamilyOptions*, \DeclareTheoremFamilyOptions* % } % % Combines the behavior of \cs{NewGroupedTheoremFamilyOptions*} and \cs{NewTheoremFamilyOptions}, % thus declaring both \meta{theorem name} and \meta{theorem name*} environments, % the latter calling the \kw{starred} variants of the theorem family, % and both of them calling \kw{unnumbered} variants of the family. % % The possible theorem variants have to be generated with the \cs{NewTheoremFamily*} % command before. % % \end{function} % % \section{\LaTeX3 interface} % % \begin{implementation} % % \section{\pkg{l3prop} implementation} % % \begin{macrocode} % \end{macrocode} % \error % \begin{macrocode} %<*package> % \end{macrocode} % % \begin{macrocode} %<@@=groupthm> % \end{macrocode} % % % % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % \end{documentation}