2022-01-17 12:13:09 +01:00
\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.
2022-01-17 14:44:29 +01:00
\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} .
2022-01-17 12:13:09 +01:00
\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).
2022-01-17 14:44:29 +01:00
\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}
2022-01-17 12:13:09 +01:00
\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}
2022-01-17 14:44:29 +01:00
\end { function}
2022-01-17 12:13:09 +01:00
2022-01-17 14:44:29 +01:00
\subsection { Controlling theorem group precedence}
2022-01-17 12:13:09 +01:00
2022-01-17 14:44:29 +01:00
\begin { function} { \DeclareTheoremGroupRule }
2022-01-17 12:13:09 +01:00
\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}
2022-01-17 14:44:29 +01:00
\item [\kw{higher} or \kw{after} or \kw{\string>}]
2022-01-17 12:13:09 +01:00
\meta { theorem group 1} takes precedence over \meta { theorem group 2} .
Its \kw { prename} is applied after the one of \meta { theorem group 2} .
2022-01-17 14:44:29 +01:00
\item [\kw{lower} or \kw{before} or \kw{\string<}]
2022-01-17 12:13:09 +01:00
\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}
2022-01-17 12:15:32 +01:00
\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}
2022-01-17 12:13:09 +01:00
\end { function}
2022-01-17 14:44:29 +01:00
\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}
2022-01-17 12:13:09 +01:00
%\section{\LaTeX3 interface}
\end { documentation}
\PrintIndex
\end { document}