diff --git a/doc/environments/groupthm/groupthm.dtx b/doc/environments/groupthm/groupthm.dtx new file mode 100644 index 0000000..6a69e6a --- /dev/null +++ b/doc/environments/groupthm/groupthm.dtx @@ -0,0 +1,680 @@ +% \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} diff --git a/doc/environments/groupthm/groupthm.tex b/doc/environments/groupthm/groupthm.tex deleted file mode 100644 index 474a8db..0000000 --- a/doc/environments/groupthm/groupthm.tex +++ /dev/null @@ -1,632 +0,0 @@ -\documentclass[full]{l3doc} - -\usepackage{mkessler-todo} - -\title{% - The \pkg{groupthm} package \\ - Theorem Groups and Families -} - -\author{% - Maximilian Keßler -} - -\date{Released 2022-01-17} - -\NewDocumentCommand{\kw}{m} -{% - \texttt{#1}% -} - -\NewDocumentCommand{\vocab}{m} -{% - \emph{#1}% -} - -\begin{document} -\maketitle - -\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} - -\end{documentation} - -\PrintIndex -\end{document}