diff --git a/doc/environments/groupthm/5 b/doc/environments/groupthm/5 deleted file mode 100644 index c6414e0..0000000 --- a/doc/environments/groupthm/5 +++ /dev/null @@ -1,3387 +0,0 @@ -% \iffalse meta-comment -% -%% File: groupthm.dtx -% -% Copyright (C) 2022 Maximilian Keßler -% -% 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 -% -% ----------------------------------------------------------------------- -%\ProvidesExplPackage{groupthm}{2022/01/17}{0.0.1}{Grouped theorems.} -% -%<*driver> -\documentclass[full,kernel]{l3doc} -\usepackage{mkessler-todo} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -% -% \fi -% -% \title{^^A -% The \pkg{groupthm} package^^A -% } -% -% \author{^^A -% Maximilian Keßler -% } -% -% \date{Released 2022-01-12} -% -% \maketitle -% -% -% \NewDocumentCommand{\kw}{m} -% {% -% \texttt{#1}% -% } -% -% \NewDocumentCommand{\vocab}{m} -% {% -% \emph{#1}% -% } -% -% \ExplSyntaxOn -% \NewDocumentCommand { \mymeta } { O{} m } -% { -% \meta[#1]{#2} -% \__codedoc_special_index_module:nnnnN { #2 } { #2 } { meta } { usage } { \c_false_bool} -% } -% \ExplSyntaxOff -% -% -% -% \begin{documentation} -% -% \tableofcontents -% \listoftodos -% \newpage -% -% \begin{itemize} -% \item Inheritance -% \item Appending to groups -% \item default group integration -% \item better error message to avoid low level tex errors in any case -% \item potentially: detection of star / nonstar misuse -% \item add command to define group rule for all existing groups -% \item various info commands on defined groups? -% \item debugging information? -% \end{itemize} -% 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, \mymeta{theorem group}s, -% to structure theorems into groups that can subsequently easily altered, -% as well as a mechanism for easily generating \mymeta{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 \mymeta{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 \mymeta{theorem group} is some named group holding some properties for -% the \mymeta{theorem}s that are contained in this group. -% Each \mymeta{theorem} can, when declared, be part of arbitrarily many \mymeta{theorem group}s, -% and will be subject to the styles these groups defined. -% -% This enables to group similar \mymeta{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 \mymeta{theorem group}, and not all \mymeta{theorem}s separately. -% -% The properties. such a \mymeta{theorem group} can hold are as follows -% -% -% \begin{description} -% \item[\kw{prefix}] A prefix (any \mymeta{token list}) that will be inserted -% before the theorem name of each member of this \mymeta{theorem group}. -% \item[\kw{suffix}] A suffix (any \mymeta{token list}) that will be -% inserted before the theorem name for each member of this \mymeta{theorem group}. -% This could be e.g.~some \enquote{$\star$} appended to the name to indicate -% variants of environments. -% \item[\kw{mapname}] A \mymeta{function} (some macro that takes exactly one argument) -% that is applied to the \kw{name}. -% \item[\kw{thmtools}] A \mymeta{clist} of key-value pairs that are passed to the underlying -% \pkg{thmtools} backend of the \mymeta{theorem}. -% This allows e.g.~to set the \kw{topskip} of a certain class of \mymeta{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 \mymeta{theorem} can be member of arbitrary many \mymeta{theorem group}s, -% and will posses their corresponding properties. -% -% To adjust finer controlling of these \mymeta{theorem group}s, \mymeta{theorem group}s can inherit from each other, and \mymeta{theorem group}s are subject to a hierarchy that controls precedence in case -% of conflicting properties of different \mymeta{theorem group}s a \mymeta{theorem} may be part of. -% -% This hierarchy can of course be controlled by the user. -% -% \subsection{Grouped theorems} -% -% A \mymeta{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 \mymeta{theorem variant}s of some \mymeta{theorem}, the most typical -% example being \vocab{starred} version of \mymeta{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 -% \mymeta{theorem family}, which is based on some \mymeta{theorem name} and -% parses additional arguments / syntax to control the \mymeta{theorem groups} -% that this environment is a part of. -% -% So, in addition the name of a \mymeta{theorem}, the corresponding environment will -% accept some options and toggle the membership of certain \mymeta{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 \mymeta{theorem family} by listing the groups that can be toggled -% by this \mymeta{theorem family}, and declaring the actual option parsing -% of the \mymeta{theorem family}, which then controls the membership in these groups -% (and of course prior to this the definition of the desired \mymeta{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}\oarg{keys}\marg{theorem group} -% \end{syntax} -% -% This introduces a new \mymeta{theorem group} with the given name. -% The \mymeta{keys} available are the same as introduced in \autoref{sec:theorem-groups}: -% -% \begin{description} -% \item -% -% \kw{prefix} = \mymeta{token list}. -% Insert the \mymeta{token list} in front of the theorem name. -% -% \item -% -% \kw{suffix} = \mymeta{token list}. -% Insert the \mymeta{token list} after the theorem name. -% -% \item -% -% \kw{mapname} = \mymeta{function}. -% Apply this \mymeta{function} to the theorem name. -% -% \item -% -% \kw{thmtools} = $\{$\mymeta{clist}$\}$. -% Pass these options to \pkg{thmtools}. -% -% \end{description} -% -% For uniqueness of the given options, the \mymeta{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}\oarg{keyname}% -% \marg{theorem group 1}\marg{relation}\marg{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 \mymeta{keyname} can be one of \kw{prefix}, \kw{suffix}, \kw{mapname}, \kw{thmtools}. -% If present, it declares the corresponding relation only for this subkey. -% This can lead to \mymeta{theorem group 1} overwriting \mymeta{theorem group 2} when given -% contradictory \pkg{thmtools} options, but the \kw{prefix} of \mymeta{theorem group 1} -% being applied after the one of \mymeta{theorem group 2}. -% When the \mymeta{keyname} is not given, this applies to all keywords. -% -% \begin{texnote} -% The \mymeta{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>}] -% -% \mymeta{theorem group 1} takes precedence over \mymeta{theorem group 2}. -% Its \kw{prefix} is applied after the one of \mymeta{theorem group 2}. -% -% \item[\kw{lower} or \kw{before} or \kw{\string<}] -% -% \mymeta{theorem group 2} takes precedence over \mymeta{theorem group 1}. -% Its \kw{prefix} is applied after the one of \mymeta{theorem group 1}. -% -% \end{description} -% -% \begin{texnote} -% The \mymeta{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}\marg{theorem group 1}\marg{theorem group 2} -% \end{syntax} -% Declares \mymeta{theorem group 1} to \enquote{inherit} all properties -% of \mymeta{theorem group 2}. -% In other words, \mymeta{theorem group 2} is a parent of \mymeta{theorem group 1} -% in a usual inheritance graph. -% -% The definitions of the groups themselves are unchanged, -% but each new theorem defined with \mymeta{theorem group 1} will also -% have the properties of \mymeta{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 \mymeta{theorem group 1} inherits -% from \mymeta{theorem group 2}, but \mymeta{theorem group 2} overwrites -% \mymeta{theorem group 1}. -% \end{function} -% -% \subsection{Appending to theorem groups} -% \begin{function}{\AppendToTheoremGroup} -% \begin{syntax} -% \cs{AppendToTheoremGroup}\oarg{keys}\marg{theorem group} -% \end{syntax} -% Adds the properties given as \mymeta{keys} to the theorem group. -% The syntax for the \mymeta{keys} is the same as in \cs{NewTheoremGroup}. -% \end{function} -% -% \subsection{Default theorem groups} -% -% There are a number of theorem groups that \pkg{groupthm} 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 \texttt{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}\oarg{keys}\marg{theorem name} -% \end{syntax} -% This defines \mymeta{theorem name} as a new theorem environment. -% Its properties can be set by the following keys: -% -% \begin{description} -% -% \item -% -% \kw{name} $=$ \mymeta{displayed name}. -% If given, this is the displayed name of the environment in the document. -% If not present, the \mymeta{theorem name} is also used as the \mymeta{displayed name} -% in capitalized form. -% -% \item -% -% \kw{group} $=$ \marg{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} = \marg{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*}\oarg{keys}\marg{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}\oarg{keys}\marg{theorem name} -% \end{syntax} -% -% This behaves essentially the same as \cs{NewGroupedTheorem}, -% but will define two grouped theorems, namely \mymeta{theorem name} and \mymeta{theorem name*}. -% -% The \mymeta{theorem name*} environment has the same properties as the \mymeta{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}\oarg{keys}\marg{theorem name} -% \end{syntax} -% Combines the behavior of \cs{NewGroupedTheorem*} and \cs{NewTheorem}, thus -% declaring \mymeta{theorem} to (additionally) be member of the \kw{unnumbered} -% and \mymeta{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}\oarg{keys}\marg{theorem name} -% \end{syntax} -% -% Defines a family of grouped theorems. -% The \mymeta{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}\marg{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}\marg{theorem name}\marg{argument specifiation}% -% \marg{selection body} -% \end{syntax} -% -% Defines a new environment with options, given by \mymeta{theorem name}. -% The \mymeta{argument specification} can be any valid \pkg{xparse} argument specification. -% -% The \mymeta{selection body} is there to process the options of -% the \mymeta{argument specification} and select which variant of the \mymeta{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{xparse} and the \mymeta{selection body} is executed. -% Immediately after, the theorem variant of \mymeta{theorem name} with the specified groups -% by \cs{AddTheoremToGroup} is called. -% -% At the end of the environment, the \mymeta{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*}\marg{theorem name}\marg{argument specifiation}% -% \marg{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}\marg{theorem name}\marg{argument specifiation}% -% \marg{selection body} -% \end{syntax} -% -% This behaves essentially the same as \cs{NewGroupedTheoremFamilyOptions}, -% but also declares the environment \mymeta{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* -% } -% \begin{syntax} -% \cs{NewTheoremFamilyOptions*}\marg{theorem name}\marg{argument specifiation}% -% \marg{selection body} -% \end{syntax} -% -% Combines the behavior of \cs{NewGroupedTheoremFamilyOptions*} and \cs{NewTheoremFamilyOptions}, -% thus declaring both \mymeta{theorem name} and \mymeta{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} -% -% There is also an underlying \LaTeX3 interface provided by the package -% (and in fact, all prior documented macros are just wrappers around this -% internal programming interface. -% -% When building on top of this package, you can also use this interface, -% which is possibly easier to use. -% -% In general, for functions that use key-value syntax, there are typically -% three (public) versions of the command, namely -% -% \begin{itemize} -% \item A \LaTeX3 command that requires all key-values as mandatory arguments, -% so this does not use the key-value interface. -% Use this if you already know with which keys you deal and know their -% corresponding values. -% \item A \LaTeX3 command having the first argument accepting the keys as a -% comma-separated list. -% Use this if you want to profit of the key-value syntax. -% \item A \LaTeX2e document command. These were documented before, -% and these just wrap the second type of command. -% \end{itemize} -% If the corresponding command would be something like \enquote{new foo}, -% The syntax will typically be -% \begin{itemize} -% \item \cs{groupthm_new_foo:mmm}\mymeta{mandatory args}\mymeta{optional args}, -% where the \mymeta{mandatory args} list the mandatory args of the \LaTeX2e -% interface, and the \mymeta{optional args} list the optional args -% of the key-value interface, but requiring them mandatory as well. -% \item \cs{groupthm_new_foo_from_keys:mmm}\marg{keys}\mymeta{mandatory args} -% where we pass a \texttt{clist} as the first argument and all mandatory args -% as further mandatory arguments. -% \item \cs{NewFoo}\oarg{keys}\mymeta{mandatory args}, -% where the keys can be passed optionally. -% \end{itemize} -% -% \subsection{Theorem groups} -% -% -% \begin{function} -% { -% \groupthm_new_theorem_group_from_keys:nn, -% \groupthm_renew_theorem_group_from_keys:nn, -% \groupthm_provide_theorem_group_from_keys:nn, -% \groupthm_declare_theorem_group_from_keys:nn -% } -% \begin{syntax} -% \cs{groupthm_new_theorem_group_from_keys:nn}\marg{keys}\marg{theorem group} -% \end{syntax} -% -% \LaTeX3 versions of \cs{NewTheoremGroup}, \cs{RenewTheoremGroup}, -% \cs{ProvideTheoremGroup} and \cs{DeclareTheoremGroup} -% -% \end{function} -% -% -% -% \begin{function} -% { -% \groupthm_new_theorem_group:nnnnn, -% \groupthm_renew_theorem_group:nnnnn, -% \groupthm_provide_theorem_group:nnnnn, -% \groupthm_declare_theorem_group:nnnnn, -% \groupthm_new_theorem_group:nVVVV, -% \groupthm_renew_theorem_group:nVVVV, -% \groupthm_provide_theorem_group:nVVVV, -% \groupthm_declare_theorem_group:nVVVV -% } -% \begin{syntax} -% \cs{groupthm_new_theorem_group:nnnnn}\marg{theorem group}\marg{prefix tl} -% \marg{suffix tl}\marg{mapname clist}\marg{thmtools clist} -% \end{syntax} -% -% Non-keyval versions of -% \cs{groupthm_new_theorem_group_from_keys:nn}, -% \cs{groupthm_renew_theorem_group_from_keys:nn}, -% \cs{groupthm_provide_theorem_group_from_keys:nn} -% and -% \cs{groupthm_declare_theorem_group_from_keys:nn} -% -% These take the individual values of the keyval keys directly, in the order -% indicated by the syntax specification. -% -% \end{function} -% -% -% \begin{function}{\groupthm_declare_theorem_group_rule:nnnn} -% \begin{syntax} -% \cs{groupthm_declare_theorem_group_rule:nnnn}\marg{keyname}\marg{theorem group 1} -% \marg{relation}\marg{theorem group 2} -% \end{syntax} -% -% \LaTeX3 version of \cs{DeclareTheoremGroupRule} -% -% \end{function} -% -% -% \subsection{Grouped theorems} -% -% \begin{function}{\groupthm_new_grouped_theorem_from_keys:nn, \groupthm_provide_grouped_theorem_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_provide_grouped_theorem_from_keys:nn}\marg{keys}\marg{environment name} -% \end{syntax} -% -% \LaTeX3 version of \cs{NewGroupedTheorem}, \cs{ProvideGroupedTheorem} -% -% -% \end{function} -% -% \begin{function} -% { -% \groupthm_new_grouped_theorem_star_from_keys:nn, -% \groupthm_provide_grouped_theorem_star_from_keys:nn -% } -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem_star_from_keys:nn}\marg{keys}\marg{environment name} -% \end{syntax} -% -% -% \LaTeX3 version of \cs{NewGroupedTheorem*}, \cs{ProvideGroupedTheorem*} -% -% -% \end{function} -% -% -% -% \begin{function}{\groupthm_new_theorem_from_keys:nn, \groupthm_provide_theorem_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_provide_theorem_from_keys:nn}\marg{keys}\marg{environment name} -% \end{syntax} -% -% \LaTeX3 version of \cs{NewTheorem}, \cs{ProvideTheorem} -% -% -% \end{function} -% -% \begin{function}{\groupthm_new_theorem_star_from_keys:nn, \groupthm_provide_theorem_star_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_new_theorem_star_from_keys:nn}\marg{keys}\marg{environment name} -% \end{syntax} -% -% \LaTeX3 version of \cs{NewTheorem*}, \cs{ProvideTheorem*} -% -% \end{function} -% -% -% \begin{function} -% { -% \groupthm_new_grouped_theorem:nnnn, -% \groupthm_provide_grouped_theorem:nnnn, -% \groupthm_new_grouped_theorem_star:nnnn, -% \groupthm_provide_grouped_theorem_star:nnnn, -% \groupthm_new_theorem:nnnn, -% \groupthm_provide_theorem:nnnn, -% \groupthm_new_theorem_star:nnnn, -% \groupthm_provide_theorem_star:nnnn -% } -% \begin{syntax} -% \cs{groupthm_new_theorem:nnnn}\marg{environment name}\marg{groups clist} -% \marg{theorem name}\marg{thmtools keys} -% \end{syntax} -% -% Non-keyval versions of above macros. -% -% \end{function} -% -% -% \subsection{Theorem families} -% -% -% \begin{function} -% { -% \groupthm_new_grouped_theorem_family_from_keys:nn, -% \groupthm_provide_grouped_theorem_family_from_keys:nn -% } -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem_family_from_keys:nn}\marg{keys}\marg{theorem family} -% \end{syntax} -% -% The \LaTeX3 versions of \cs{NewGroupedTheoremFamily} and \cs{ProvideGroupedTheoremFamily} -% -% \end{function} -% -% -% -% \begin{function} -% { -% \groupthm_new_grouped_theorem_family_star_from_keys:nn, -% \groupthm_provide_grouped_theorem_family_star_from_keys:nn -% } -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem_family_star_from_keys:nn}\marg{keys}\marg{theorem family} -% \end{syntax} -% -% The \LaTeX3 versions of \cs{NewGroupedTheoremFamily*} and \cs{ProvideGroupedTheoremFamily*} -% -% \end{function} -% -% -% -% \begin{function} -% { -% \groupthm_new_theorem_family_from_keys:nn, -% \groupthm_provide_theorem_family_from_keys:nn -% } -% \begin{syntax} -% \cs{groupthm_new_theorem_family_from_keys:nn}\marg{keys}\marg{theorem family} -% \end{syntax} -% -% The \LaTeX3 versions of \cs{NewTheoremFamily} and \cs{ProvideTheoremFamily} -% -% \end{function} -% -% -% -% \begin{function} -% { -% \groupthm_new_theorem_family_star_from_keys:nn, -% \groupthm_provide_theorem_family_star_from_keys:nn -% } -% \begin{syntax} -% \cs{groupthm_new_theorem_family_star_from_keys:nn}\marg{keys}\marg{theorem family} -% \end{syntax} -% -% The \LaTeX3 versions of \cs{NewTheoremFamily*} and \cs{ProvideTheoremFamily*} -% -% \end{function} -% -% -% \begin{function} -% { -% \groupthm_new_grouped_theorem_family:nnnn, -% \groupthm_provide_grouped_theorem_family:nnnn, -% \groupthm_new_grouped_theorem_family_star:nnnn, -% \groupthm_provide_grouped_theorem_family_star:nnnn, -% \groupthm_new_theorem_family:nnnn, -% \groupthm_provide_theorem_family:nnnn, -% \groupthm_new_theorem_family_star:nnnn, -% \groupthm_provide_theorem_family_star:nnnn -% } -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem_family:nnnn}\marg{theorem family} -% \marg{groups}\marg{name}\marg{thmtools clist} -% \end{syntax} -% -% The non-key-value versions of the prior macros. -% -% \end{function} -% -% \end{documentation} -% -% -% -% -% -% -% -% -% -% -% -% -% -% \begin{implementation} -% -% \section{\pkg{groupthm} implementation} -% -% \begin{macrocode} -%<*package> -% \end{macrocode} -% -% \begin{macrocode} -%<@@=groupthm> -% \end{macrocode} -% -% -% -% -% \subsection{Dependencies} -% -% -% -% First, we import other packages on which we rely on, and -% set up some private wrappers around these. -% \begin{macrocode} -\RequirePackage{amsthm} -\RequirePackage{thmtools} -% \end{macrocode} -% -% \begin{macro}{\@@_thmtools_declare_theorem:nn, \@@_thmtools_declare_theorem:Vn} -% \begin{syntax} -% \cs{@@_thmtools_declare_theorem:nn} \mymeta{theorem name}\mymeta{thmtools keyval args} -% \end{syntax} -% -% This is just a private wrapper around \cs{declaretheorem} of the \pkg{thmtools} package. -% -% \begin{macrocode} -\cs_new:Npn \@@_thmtools_declare_theorem:nn #1 #2 -{ - \tl_log:n { Declaring ~ thmtools ~ theorem ~ #2 } - \declaretheorem [ #1 ] { #2 } -} -\cs_generate_variant:Nn \@@_thmtools_declare_theorem:nn { V n } -% \end{macrocode} -% \end{macro} -% -% -% -% It also comes in handy to have a stronger version of the -% hook role setting mechanism: -% \begin{macro}{\@@_hook_gset_rule_foreach:nNnn} -% \begin{syntax} -% \cs{@@_hook_gset_rule_foreach:nNnn}\marg{hook}\mymeta{clist name}\mymeta{relation}\mymeta{label} -% \end{syntax} -% -% This is a wrapper around the \cs{hook_gset_rule:nnnn} macro -% that takes a clist name of labels, and executes the corresponding -% command for each such label. -% -% \begin{macrocode} -\cs_new:Npn \@@_hook_gset_rule_foreach:nNnn #1 #2 #3 #4 - { - \cs_set:Npn \@@_map_aux:n ##1 - { - \hook_gset_rule:nnnn { #1 } { ##1 } { #3 } { #4 } - } - \clist_map_function:NN #2 \@@_map_aux:n - } -% \end{macrocode} -% \end{macro} -% -% -% -% \subsection{Messages} -% These are messages that we might emit. -% -% When an unknown group is used somwhere: -% \begin{syntax} -% \cs{msg_error:nnn}\{ groupthm \}\{ unknown group \}\marg{groupname} -% \end{syntax} -% \begin{macrocode} -\msg_new:nnn { groupthm } { unknown ~ group } -{ - Unknown ~ group ~ '#1' ~ supplied ~ \msg_line_context: -} -% \end{macrocode} -% -% When an unknown key has been used: -% \begin{syntax} -% \cs{msg_error:nnn}\{ groupthm \}\{ unknown key \}\marg{key} -% \end{syntax} -% \begin{macrocode} -\msg_new:nnn { groupthm } { unknown ~ key } -{ - Unknown ~ key ~ '#1' ~ supplied ~ \msg_line_context: -} -% \end{macrocode} -% -% Some data structure is already defined or not defined yet. -% \begin{syntax} -% \cs{msg_error:nnnnn}\{ groupthm \}\{ wrong definition \} -% \marg{type}\marg{name}\marg{already $\|$ not} -% \end{syntax} -% \begin{macrocode} -\msg_new:nnn { groupthm } { wrong ~ definition } -{ - Bad ~ definition ~ of ~ #1 ~ '#2' ~ \msg_line_context:, ~ #1 ~ is ~ #3 ~ defined. -} -% \end{macrocode} -% -% -% When the special \cs{AddTheoremToGroup} macro is issued outside a theorem family options -% body. -% \begin{syntax} -% \cs{msg_error:nn} \{ groupthm \}\{ misuse add theorem to group \} -% \end{syntax} -% \begin{macrocode} -\msg_new:nnn { groupthm } { misuse ~ add ~ theorem ~ to ~ group } - { - Bad ~ usage ~ of ~ 'AddTheoremToGroup' ~ macro ~ outside ~ theorem ~ - family ~ options ~ \msg_line_context: - } -% \end{macrocode} -% -% -% -% When a theorem family is invoked, but has not been generated yet. -% \begin{syntax} -% \cs{msg_error:nn} \{ groupthm \}\{ undefined theorem variant \} -% \end{syntax} -% \begin{macrocode} -\msg_new:nnnn { groupthm } { undefined ~ theorem ~ variant } - { - Bad ~ call ~ of ~ theorem ~ variant ~ of ~ '#1' ~ \msg_line_context: - } - { - You ~ wanted ~ to ~ call ~ the ~ variant ~ with ~ group(s) ~ - '#2' ~ of ~ theorem ~ family ~ '#1', ~ but ~ it ~ has ~ not ~ been ~ - generated ~ yet. ~ - Probably ~ you ~ forgot ~ this. ~ - \msg_see_documentation_text:n { groupthm } - } -% \end{macrocode} -% -% \subsection{Allocation and initialization} -% -% We use hooks at several places. However, these are not intended for outer use, -% and we thus mark them with a preceding \texttt{__}. -% -% \begin{macrocode} -\hook_new:n { @@/prefix } -\hook_new:n { @@/suffix } -\hook_new:n { @@/mapname } -\hook_new:n { @@/thmtools } -% \end{macrocode} -% \begin{macrocode} -\hook_new:n { @@/groupsort } -% \end{macrocode} -% -% \begin{macro}{\hook_gset_rule:nnVn} -% \begin{syntax} -% \cs{hook_gset_rule:nnVn}\marg{hook}\marg{label 1}\marg{relation}\marg{label 2} -% \end{syntax} -% -% Just a variant of the usual \cs{hook_gset_rule:nnnn} macro that we use. -% -% \begin{macrocode} -\cs_generate_variant:Nn \hook_gset_rule:nnnn { n n V n } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{variable} -% { -% \l_@@_key_prefix_tl, \l_@@_key_name_tl, \l_@@_key_suffix_tl, -% \l_@@_key_group_clist, \l_@@_key_mapname_clist, \l_@@_key_thmtools_clist -% } -% These variables will be set by the key-value interface provided by -% \pkg{l3keys} and are used in various places in the package. -% \begin{macrocode} -\tl_new:N \l_@@_key_prefix_tl -\tl_new:N \l_@@_key_name_tl -\tl_new:N \l_@@_key_suffix_tl -\clist_new:N \l_@@_key_group_clist -\clist_new:N \l_@@_key_mapname_clist -\clist_new:N \l_@@_key_thmtools_clist -% \end{macrocode} -% \end{variable} -% -% \begin{variable} -% { -% \l_@@_prefix_tl, -% \l_@@_name_tl, -% \l_@@_suffix_tl, -% \l_@@_mapname_clist, -% \l_@@_thmtools_clist, -% \l_@@_group_clist -% } -% -% General local variables. -% Will typically be used to extract the variables set by the \pkg{l3keys} interface, -% but also in just a local variable sense. -% -% \begin{macrocode} -\tl_new:N \l_@@_prefix_tl -\tl_new:N \l_@@_name_tl -\tl_new:N \l_@@_suffix_tl -\clist_new:N \l_@@_mapname_clist -\clist_new:N \l_@@_thmtools_clist -\clist_new:N \l_@@_group_clist -% \end{macrocode} -% \end{variable} -% -% -% -% \begin{variable}{\g_@@_defined_theorem_groups_clist} -% -% This variable will hold a global list of declared theorem groups -% -% \begin{macrocode} -\clist_new:N \g_@@_defined_theorem_groups_clist -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_@@_in_family_options_environment_bool} -% This variable indicates whether we are in the special environment -% used to parse a set of groups out of options given to a theorem -% family. -% -% This bool toggles the availability of the special \cs{AddTheoremToGroup} macro. -% \begin{macrocode} -\bool_new:N \l_@@_in_family_options_environment_bool -% \end{macrocode} -% \end{variable} -% -% -% \subsection{Key interface} -% As mentioned, all keys will set their corresponding local variables -% (containing \enquote{\texttt{_key_}} in their name) and store the -% user input in these. -% -% Additionally, we group these keys by use cases, -% and provide defaults that in most cases will not require further handling. -% -% -% -% \begin{macrocode} -\keys_define:nn { groupthm } - { - prefix .tl_set:N = \l_@@_key_prefix_tl, - prefix .default:n = \c_empty_tl, - prefix .groups:n = { theoremgroup }, - name .tl_set:N = \l_@@_key_name_tl, - name .default:n = \c_novalue_tl, - name .groups:n = { groupedtheorem, theoremvariants }, - suffix .tl_set:N = \l_@@_key_suffix_tl, - suffix .default:n = \c_empty_tl, - suffix .groups:n = { theoremgroup }, - group .clist_set:N = \l_@@_key_group_clist, - group .default:n = {}, - group .groups:n = { groupedtheorem, theoremvariants }, - mapname .clist_set:N = \l_@@_mapname_clist, - mapname .default:n = {}, - mapname .groups:n = { theoremgroup }, - thmtools .clist_set:N = \l_@@_key_thmtools_clist, - thmtools .default:n = {}, - thmtools .groups:n = - { theoremgroup, groupedtheorem, theoremvariants }, - unknown .code:n = - \msg_error:nnn { groupthm } { unknown ~ group } { \l_keys_key_str } - } -% \end{macrocode} -% -% -% The only key whose default requires such handling is the \enquote{\texttt{name}} key, -% which will be set to a capitalized version of the environment name -% when not specified. -% -% -% \begin{macro}{\@@_set_normalized_keys:nnn} -% \begin{syntax} -% \cs{@@_set_normalized_keys:nnn}\marg{keys}\marg{key group}\marg{fallback name} -% \end{syntax} -% -% Sets the packages keys and normalizes the retrieved values, that is, -% clears old set keys, stores all keys in local variables, -% and replaces the \cs{l_@@_name_tl} with the capitalized version of the -% \mymeta{fallback name}. -% -% \begin{macrocode} -\cs_new:Npn \@@_set_normalized_keys:nnn #1 #2 #3 - { - \keys_set:nn { groupthm } { prefix, name, suffix, group, mapname, thmtools } - \keys_set_groups:nnn { groupthm } { #2 } { #1 } -% \end{macrocode} -% -% Normalize given name -% -% \begin{macrocode} - \tl_if_eq:NnTF \l_@@_key_name_tl { \c_novalue_tl } - { - \tl_set:Nx \l_@@_name_tl - { - \text_titlecase_first:n {#3} - } - } - { - \tl_set_eq:NN \l_@@_name_tl \l_@@_key_name_tl - } -% \end{macrocode} -% -% Copy set keys into local variables -% -% \begin{macrocode} - \tl_set_eq:NN \l_@@_prefix_tl \l_@@_key_prefix_tl - \tl_set_eq:NN \l_@@_suffix_tl \l_@@_key_suffix_tl - \clist_set_eq:NN \l_@@_group_clist \l_@@_key_group_clist - \clist_set_eq:NN \l_@@_mapname_clist \l_@@_key_mapname_clist - \clist_set_eq:NN \l_@@_thmtools_clist \l_@@_key_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% \subsection{Theorem groups} -% -% For technical reasons explained in the \todoref section, we need to -% some arbitrary, but unique total ordering on the set of all defined theorem groups. -% -% Since unfortunately (by now) there is no standard mechanism for sorting strings -% in \LaTeX3 directly, we use an ugly hack to achieve what we want: -% -% We will use an internal hook, and apply hook rules to each pair of internal groups -% such that the resulting relation is a total order. -% Whenever we want to sort a list of groups now, we do the following: -% First, for each group element in the list, insert into the hook the function -% \enquote{put this group back into the list}, using the group itself as a label. -% Then we clear the list, and finally execute the hook. -% -% Essentially, we thus split up the hook in the single groups, let the \LaTeX3 hook -% mechanism take care of the sorting, and restore the sorted single pieces into our list. -% Of course, this is very inefficient, but for now it seems to be the simplest solution, -% without having to implement an own string sorting function. -% -% Once there is such a proper mechanism, the author will likely update this to proper -% string sorting. -% -% \begin{macro}{\@@_add_to_theorem_group_ordering:n} -% \begin{syntax} -% \cs{@@_add_to_theorem_group_ordering:n}\marg{theorem group} -% \end{syntax} -% -% Sets hook relations for this group and all already defined theorem groups. -% -% \begin{macrocode} -\cs_new:Npn \@@_add_to_theorem_group_ordering:n #1 - { - \@@_hook_gset_rule_foreach:nNnn - { @@/groupsort } - \g_@@_defined_theorem_groups_clist - { before } - { #1 } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_remove_from_theorem_group_ordering:n} -% \begin{syntax} -% \cs{@@_remove_from_theorem_group_ordering:n}\marg{theorem group} -% \end{syntax} -% -% Removes all relations of this theorem group with the currently defined theorem groups. -% -% \begin{macrocode} -\cs_new:Npn \@@_remove_from_theorem_group_ordering:n #1 - { - \@@_hook_gset_rule_foreach:nNnn - { @@/groupsort } - \g_@@_defined_theorem_groups_clist - { unrelated } - { #1 } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_add_to_sort_hook:n} -% \begin{syntax} -% \cs{@@_add_to_sort_hook:n}\marg{theorem group} -% \end{syntax} -% -% Adds the theorem group into the sort hook to be restored later from it. -% This already uses the assumption, that we want to use the \cs{l_@@_group_clist} -% variable (which we do). -% -% \begin{macrocode} -\cs_new:Npn \@@_add_to_sort_hook:n #1 -{ - \hook_gput_code:nnn { @@/groupsort } - { #1 } - { - \clist_put_left:Nn \l_@@_group_clist { #1 } - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@@_sort_theorem_group_names:} -% -% As explained briefly before, we first insert all theorems -% into the hook, clear the list, and then use the hook again. -% -% This then sorts the \cs{l_@@_group_clist} variable, -% which is also assumed to hold only defined theorem group names. -% -% \begin{macrocode} -\cs_new:Npn \@@_sort_theorem_group_names: - { - \hook_gremove_code:nn { @@/groupsort }{*} - \clist_map_function:NN \l_@@_group_clist \@@_add_to_sort_hook:n - \clist_clear:N \l_@@_group_clist - \hook_use:n { @@/groupsort } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@@_define_group_aux:nnnnn} -% \begin{syntax} -% \cs{@@_define_group_aux:nnnnn}\marg{theorem group}\marg{prefix tl} -% \marg{suffix tl}\marg{mapname clist}\marg{thmtools clist} -% \end{syntax} -% -% This creates a new theorem group out of the given parameters. -% We store all given contents in our (private) hooks, using the group name as the key -% so that we can later retrieve the components of each group separately. -% -% This is an internal function and assumes that the group is currently not defined, -% and also removed from all hooks. -% -% -% \begin{macrocode} -\cs_new:Npn \@@_define_group_aux:nnnnn #1#2#3#4#5 - { -% \end{macrocode} -% -% \begin{macro}{\@@_use_group_\meta{theorem group}:} -% -% This is the internal macro that will be called when retrieving contents of a group. -% We define this here to store the properties of the group. -% -% \begin{macrocode} - \cs_new:cpn { @@_use_group_#1: } - { - \hook_gput_code:nnn { @@/prefix } { #1 } - { - \tl_put_left:Nx \l_@@_prefix_tl { #2 } - } - \hook_gput_code:nnn { @@/suffix } { #1 } - { - \tl_put_right:Nx \l_@@_suffix_tl { #3 } - } - \hook_gput_code:nnn { @@/mapname } { #1 } - { - \clist_put_right:Nn \l_@@_mapname_clist { #4 } - } - \hook_gput_code:nnn { @@/thmtools } { #1 } - { - \clist_put_right:Nn \l_@@_thmtools_clist { #5 } - } - } -% \end{macrocode} -% \end{macro} -% -% This ensures the ordering hacks explained before. -% -% \begin{macrocode} - \@@_add_to_theorem_group_ordering:n { #1 } -% \end{macrocode} -% -% Add defined group to corresponding list -% -% \begin{macrocode} - \clist_gput_left:Nn \g_@@_defined_theorem_groups_clist { #1 } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@@_undefine_group_aux:n} -% \begin{syntax} -% \cs{@@_undefine_group_aux:n}\marg{theorem group} -% \end{syntax} -% -% Undeclares / undefines the given theorem group. -% This means removing its hook code in the \texttt{prefix}, \texttt{suffix}, -% \texttt{mapname} and \texttt{thmtools} hooks, -% and removing all relations with other theorem groups globally -% as well as for each hook individually. -% -% This macro assumes that the group was defined prior to calling. -% -% \begin{macrocode} -\cs_new:Npn \@@_undefine_group_aux:n #1 - { - \cs_undefine:c { @@_use_group_#1: } -% \end{macrocode} -% -% Remove properties from hooks -% -% \begin{macrocode} - \hook_gremove_code:nn { @@/prefix } { #1 } - \hook_gremove_code:nn { @@/suffix } { #1 } - \hook_gremove_code:nn { @@/mapname } { #1 } - \hook_gremove_code:nn { @@/thmtools } { #1 } -% \end{macrocode} -% -% Remove theorem group from list of defined theorems -% -% \begin{macrocode} - \clist_gremove_all:Nn \g_@@_defined_theorem_groups_clist { #1 } -% \end{macrocode} -% -% Now, unset all relations with all defined theorem groups in the internal hooks. -% -% \begin{macrocode} - \@@_hook_gset_rule_foreach:nNnn - { ?? } - \g_@@_defined_theorem_groups_clist - { unrelated } - { #1 } - \@@_hook_gset_rule_foreach:nNnn - { @@/prefix } - \g_@@_defined_theorem_groups_clist - { unrelated } - { #1 } - \@@_hook_gset_rule_foreach:nNnn - { @@/suffix } - \g_@@_defined_theorem_groups_clist - { unrelated } - { #1 } - \@@_hook_gset_rule_foreach:nNnn - { @@/mapname } - \g_@@_defined_theorem_groups_clist - { unrelated } - { #1 } - \@@_hook_gset_rule_foreach:nNnn - { @@/thmtools } - \g_@@_defined_theorem_groups_clist - { unrelated } - { #1 } -% \end{macrocode} -% -% Also clear all sorting relations -% -% \begin{macrocode} - \@@_remove_from_theorem_group_ordering:n { #1 } - } -% \end{macrocode} -% \end{macro} -% -% With these two helper functions, we can now easily implement the -% \texttt{new}, \texttt{renew}, \texttt{provide} and \texttt{declare} variants -% of the theorem group macro: -% -% \begin{macro}{\groupthm_new_theorem_group:nnnnn, \groupthm_new_theorem_group:nVVVV} -% -% \begin{macrocode} -\cs_new:Npn \@@_define_aux:nnnNNNn #1 #2 #3 #4 #5 #6 #7 -{ - \bool_if:nT - { - \str_if_eq_p:nn { #1 } { new } - && - \cs_if_exist_p:N #4 - } - { - \msg_error:nnnn { groupthm } { wrong ~ definition } - { #2 } { #3 } { already } - } - - \bool_if:nT - { - \str_if_eq_p:nn { #1 } { renew } - && - ! \cs_if_exist_p:N #4 - } - { - \msg_error:nnnn { groupthm } { wrong ~ definition } - { #2 } { #3 } { not } - } - - \bool_if:nT - { - ( - \str_if_eq_p:nn { #1 } { declare } || - \str_if_eq_p:nn { #1 } { renew } - ) && - \cs_if_exist_p:N #4 - } - { - #5 { #1 } - } - - #6 #7 -} -\cs_generate_variant:Nn \@@_define_aux:nnnNNNn { n n n c N N n } - -\cs_new:Npn \@@_define_list_aux:nnnNNnn #1 #2 #3 #4 #5 #6 #7 -{ - \cs_set:Npn \@@_map_aux:n ##1 - { - \cs_new:cn { #6 } - { - \@@_define_aux:nnncNNn - { ##1 } - { #2 } - { ####1 } - { #3 } - #4 - #5 - { - #7 - } - } - } - \cs_show:N \@@_map_aux:n - - \clist_map_function:nN { #1 } \@@_map_aux:n -} - - -\@@_define_list_aux:nnnNNnn - { new, renew, provide, declare } - { theorem group } - { @@_use_group_##1: } - \@@_undefine_group_aux:n - \@@_define_group_aux:nnnnn - { groupthm_#1_group:nnnnn } - { { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } } -% \end{macrocode} -% -% Finally, generate some extra variant. -% -% \begin{macrocode} -\cs_generate_variant:Nn \groupthm_new_theorem_group:nnnnn { n V V V V } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} - -% \end{macrocode} -% -% -% -% With the \cs{@@_set_normalized_keys:nnn} macro at hand, -% it is also easy to provide key-value interfaces for these commands: -% -% \begin{macro}{\groupthm_new_theorem_group_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_new_theorem_group_from_keys:nn}\marg{keys}\marg{theorem group} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem_group_from_keys:nn #1#2 -{ - \@@_set_normalized_keys:nnn { #1 } { theoremgroup } { #2 } - \groupthm_new_theorem_group:nVVVV { #2 } - \l_@@_prefix_tl - \l_@@_suffix_tl - \l_@@_mapname_clist - \l_@@_thmtools_clist -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_renew_theorem_group_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_renew_theorem_group_from_keys:nn}\marg{keys}\marg{theorem group} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_renew_theorem_group_from_keys:nn #1#2 -{ - \@@_set_normalized_keys:nnn { #1 } { theoremgroup } { #2 } - \groupthm_renew_theorem_group:nVVVV { #2 } - \l_@@_prefix_tl - \l_@@_suffix_tl - \l_@@_mapname_clist - \l_@@_thmtools_clist -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_theorem_group_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_provide_theorem_group_from_keys:nn}\marg{keys}\marg{theorem group} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem_group_from_keys:nn #1#2 -{ - \@@_set_normalized_keys:nnn { #1 } { theoremgroup } { #2 } - \groupthm_provide_theorem_group:nVVVV { #2 } - \l_@@_prefix_tl - \l_@@_suffix_tl - \l_@@_mapname_clist - \l_@@_thmtools_clist -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_declare_theorem_group_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_declare_theorem_group_from_keys:nn}\marg{keys}\marg{theorem group} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_declare_theorem_group_from_keys:nn #1#2 -{ - \@@_set_normalized_keys:nnn { #1 } { theoremgroup } { #2 } - \groupthm_declare_theorem_group:nVVVV { #2 } - \l_@@_prefix_tl - \l_@@_suffix_tl - \l_@@_mapname_clist - \l_@@_thmtools_clist -} -% \end{macrocode} -% \end{macro} -% -% -% Finally, we provide \LaTeX2e wrappers as document commands for these. -% -% -% \begin{macro}{\NewTheoremGroup} -% -% \begin{macrocode} -\NewDocumentCommand{\NewTheoremGroup}{ O{} m } - { - \groupthm_new_theorem_group_from_keys:nn { #1 } { #2 } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\RenewTheoremGroup} -% -% \begin{macrocode} -\NewDocumentCommand{\RenewTheoremGroup}{ O{} m } - { - \groupthm_renew_theorem_group_from_keys:nn { #1 } { #2 } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\ProvideTheoremGroup} -% -% \begin{macrocode} -\NewDocumentCommand{\ProvideTheoremGroup}{ O{} m } - { - \groupthm_provide_theorem_group_from_keys:nn { #1 } { #2 } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\DeclareTheoremGroup} -% -% \begin{macrocode} -\NewDocumentCommand{\DeclareTheoremGroup}{ O{} m } - { - \groupthm_declare_theorem_group_from_keys:nn { #1 } { #2 } - } -% \end{macrocode} -% \end{macro} -% -% We also provide the interface for declaring the precedence rules for theorem groups. -% -% -% \begin{macro}{\groupthm_declare_theorem_group_rule:nnnn} -% \begin{syntax} -% \cs{groupthm_declare_theorem_group_rule:nnnn}\marg{keyname}\marg{theorem group 1} -% \marg{relation}\marg{theorem group 2} -% \end{syntax} -% -% We have to normalize the arguments a little bit, namely replacing \texttt{higher} -% and \texttt{lower} with \texttt{before} \texttt{after} respectively, -% and prefix the \mymeta{keyname} with \texttt{__groupthm} -% in case it is not the general hook \enquote{\texttt{??}}. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_declare_theorem_group_rule:nnnn #1 #2 #3 #4 - { - \str_set:Nx \l_tmpa_str { \tl_trim_spaces:n { #3 } } - - \str_if_eq:VnT \l_tmpa_str { higher } - { - \str_set:Nn \l_tmpa_tl { after } - } - - \str_if_eq:VnT \l_tmpa_str { lower } - { - \str_set:Nn \l_tmpa_tl { before } - } - - \str_if_eq:nnTF { #1 } { ?? } - { - \hook_gset_rule:nnVn {??} {#2} \l_tmpa_tl {#4} - } - { - \hook_gset_rule:nnVn { @@ / #1 } {#2} \l_tmpa_tl {#4} - } - } -% \end{macrocode} -% \end{macro} - -% \begin{macro}{\DeclareTheoremGroupRule} -% \begin{syntax} -% \cs{DeclareTheoremGroupRule}\oarg{keyname}% -% \marg{theorem group 1}\marg{relation}\marg{theorem group 2} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand { \DeclareTheoremGroupRule } { O{??} m m m } - { - \groupthm_declare_theorem_group_rule:nnnn {#1} {#2} {#3} {#4} - } -% \end{macrocode} -% \end{macro} -% - % \subsection{Iterating over powersets} -% For generating the different variants of a theorem family, -% we need to iterate over over the powerset of some list. -% This is a collection of hacks that perform exactly this, -% but these are poorly documented for now. -% -% -% \begin{macro}{\@@_powerset_clist_foreach:Nn} -% \begin{syntax} -% \cs{@@_powerset_clist_foreach:Nn}\mymeta{clist}\marg{code} -% \end{syntax} -% -% Executes \mymeta{code} for each subset of the given clist variable. -% The value of the (local) variable is changes throughout the iteration, -% and is thus available regularly in \mymeta{code}. -% Its value is restored at the end of the iteration. -% -% \begin{macrocode} -\clist_new:N \l__powerset_copied_clist -\seq_new:N \l__powerset_saved_seq -\cs_generate_variant:Nn \clist_remove_all:Nn { N V } -\cs_new:Npn \__powerset_clist_foreach_aux:Nn #1 #2 - { - \clist_if_empty:NTF \l__powerset_copied_clist - { - #2 - } - { - \clist_get:NN \l__powerset_copied_clist \l_tmpa_tl - \seq_push:NV \l__powerset_saved_seq \l_tmpa_tl - \clist_pop:NN \l__powerset_copied_clist { \l_tmpa_tl } - - \__powerset_clist_foreach_aux:Nn #1 {#2} - - \seq_get:NN \l__powerset_saved_seq \l_tmpa_tl - \clist_put_left:NV #1 \l_tmpa_tl - - \__powerset_clist_foreach_aux:Nn #1 {#2} - - \seq_get:NN \l__powerset_saved_seq \l_tmpa_tl - \clist_remove_all:NV #1 \l_tmpa_tl - \clist_push:NV \l__powerset_copied_clist \l_tmpa_tl - \seq_pop:NN \l__powerset_saved_seq \l_tmpa_tl - } - } -\cs_new:Npn \powerset_clist_foreach:Nn #1 #2 - { - \clist_set_eq:NN \l__powerset_copied_clist #1 - \clist_clear:N #1 - \clist_remove_duplicates:N \l__powerset_copied_clist - \__powerset_clist_foreach_aux:Nn #1 {#2} - \clist_set_eq:NN #1 \l__powerset_copied_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% -% \subsection{Grouped Theorems} -% -% -% \begin{macro}{\@@_use_theorem_group:n} -% \begin{syntax} -% \cs{@@_use_theorem_group:n}\mymeta{theorem group} -% \end{syntax} -% -% Uses this theorem group, i.e.~applies its definition by writing -% to the internal hooks. -% A proper error message is emitted if the group is not defined. -% -% \begin{macrocode} -\cs_new:Npn \@@_use_theorem_group:n #1 - { - \cs_if_exist_use:cF { @@_use_group_#1: } - { - \msg_error:nnn { groupthm } { unknown ~ group } { #1 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_use_function_on_name:n} -% \begin{syntax} -% \cs{@@_use_function_on_name:n}\mymeta{function} -% \end{syntax} -% -% The \mymeta{function} is expected to be of type \texttt{:n}, -% This applies the function to the \cs{l_@@_name_tl} -% -% \begin{macrocode} -\cs_new:Npn \@@_use_function_on_name:n #1 - { - \tl_set:Nx \l_@@_name_tl - { - #1 { \tl_use:N \l_@@_name_tl } - } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_declare_grouped_theorem_aux:nnnn} -% \begin{syntax} -% \cs{@@_declare_grouped_theorem_aux:nnnn}\marg{environment name} -% \marg{groups clist}\marg{theorem name}\marg{thmtools keys} -% \end{syntax} -% -% This is the internal backend that declares a grouped theorem -% by retrieving all the group properties and issuing a (single) \cs{declaretheorem} -% command of \pkg{thmtools}. -% -% \begin{macrocode} -\cs_new:Npn \@@_declare_grouped_theorem_aux:nnnn #1 #2 #3 #4 - { -% \end{macrocode} -% First, set local variables to default values and store current name. -% \begin{macrocode} - \tl_clear:N \l_@@_prefix_tl - \tl_set:Nn \l_@@_name_tl { #3 } - \tl_clear:N \l_@@_suffix_tl - \clist_clear:N \l_@@_mapname_clist - \clist_clear:N \l_@@_thmtools_clist -% \end{macrocode} -% Clear all hooks -% \begin{macrocode} - \hook_gremove_code:nn { @@/prefix }{*} - \hook_gremove_code:nn { @@/suffix }{*} - \hook_gremove_code:nn { @@/mapname }{*} - \hook_gremove_code:nn { @@/thmtools }{*} -% \end{macrocode} -% Now, retrieve the group properties, by writing these into the hooks -% \begin{macrocode} - \clist_map_function:nN { #2 } \@@_use_theorem_group:n -% \end{macrocode} -% Execute the hooks, so that local variables will get modified according to the groups -% and in the order that were specified for the hooks. -% \begin{macrocode} - \hook_use:n { @@/prefix } - \hook_use:n { @@/suffix } - \hook_use:n { @@/mapname } - \hook_use:n { @@/thmtools } -% \end{macrocode} -% We are left with dealing with the obtained data. -% We first map on the name, before appending to it. -% \begin{macrocode} - \clist_map_function:NN \l_@@_mapname_clist \map_use_on_name:n -% \end{macrocode} -% We now glue the name together of its three parts, -% and pass this key directly to the \pkg{thmtools} arguments -% \begin{macrocode} - \clist_put_right:Nx \l_@@_thmtools_clist - { - name = \tl_use:N \l_@@_prefix_tl - \tl_use:N \l_@@_name_tl - \tl_use:N \l_@@_suffix_tl - } -% \end{macrocode} -% Finally, apply the additional \pkg{thmtools} keys for this specific theorem. -% Putting them last will overwrite keys that were given by the groups. -% \begin{macrocode} - \clist_put_right:Nn \l_@@_thmtools_clist { #4 } -% \end{macrocode} -% We can now pass our list to \pkg{thmtools}, declaring the theorem. -% \begin{macrocode} - \@@_thmtools_declare_theorem:Vn - \l_@@_thmtools_clist - { #1 } - } -% \end{macrocode} -% \end{macro} -% -% -% -% As usual, we provide a \texttt{new} and a \texttt{provide} variant wrapped -% around this that do proper error checking. -% -% -% -% \begin{macro} -% { -% \groupthm_new_grouped_theorem:nnnn, -% \groupthm_new_grouped_theorem:nVVV, -% \groupthm_new_grouped_theorem:xVnn -% } -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem:nnnn}\marg{environment name} -% \marg{groups clist}\marg{theorem name}\marg{thmtools keys} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_grouped_theorem:nnnn #1 #2 #3 #4 - { -% \end{macrocode} -% Note that the next comparison depends on \pkg{thmtools} declaring -% environments, and that \LaTeX\ handles environments called with the -% |\begin{environment}| syntax by calling |\environment| subsequently. -% \begin{macrocode} - \cs_if_exist:cTF { #1 } - { - \msg_error:nnnnn { groupthm } { wrong ~ definition } - { grouped ~ theorem } { #1 } { already } - } - { - \@@_declare_grouped_theorem_aux:nnnn - { #1 } { #2 } { #3 } { #4 } - } - } -\cs_generate_variant:Nn \groupthm_new_grouped_theorem:nnnn { n V V V } -% \end{macrocode} -% We need this extra variant here for the generation of theorem families later: -% \begin{macrocode} -\cs_generate_variant:Nn \groupthm_new_grouped_theorem:nnnn { x V n n } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\groupthm_provide_grouped_theorem:nnnn,\groupthm_provide_grouped_theorem:nVVV} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_grouped_theorem:nnnn #1 #2 #3 #4 - { -% \end{macrocode} -% Note that the next comparison depends on \pkg{thmtools} declaring -% environments, and that \LaTeX\ handles environments called with the -% |\begin{environment}| syntax by calling |\environment| subsequently. -% \begin{macrocode} - \cs_if_exist:cF { #1 } - { - \@@_declare_grouped_theorem_aux:nnnn - { #1 } { #2 } { #3 } { #4 } - } - } -\cs_generate_variant:Nn \groupthm_provide_grouped_theorem:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% The star variants of these that add the \texttt{unnumbered} group -% are straightforward: -% -% -% \begin{macro}{\groupthm_new_grouped_theorem_star:nnnn} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_grouped_theorem_star:nnnn #1 #2 #3 #4 - { - \groupthm_new_grouped_theorem:nnnn - { #1 } { #2, unnumbered } { #3 } { #4 } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_grouped_theorem_star:nnnn} -% \begin{syntax} -% \cs{groupthm_provide_grouped_theorem_star:nnnn}\marg{environment name} -% \marg{groups clist}\marg{theorem name}\marg{thmtools keys} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_grouped_theorem_star:nnnn #1 #2 #3 #4 - { - \groupthm_provide_grouped_theorem:nnnn - { #1 } { #2, unnumbered } { #3 } { #4 } - } -% \end{macrocode} -% \end{macro} -% -% -% On top of these, we can provide the shorter versions that will generate -% two theorems each, one with and one without a \enquote{*} in its -% environment name -% -% -% -% \begin{macro}{\groupthm_new_theorem:nnnn,\groupthm_new_theorem:nVVV} -% \begin{syntax} -% \cs{groupthm_new_theorem:nnnn}\marg{environment name} -% \marg{groups clist}\marg{theorem name}\marg{thmtools keys} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem:nnnn #1 #2 #3 #4 - { - \groupthm_new_grouped_theorem:nnnn - { #1 } { #2 } { #3 } { #4 } - \groupthm_new_grouped_theorem:nnnn - { #1* } { #2, starred } { #3 } { #4 } - } -\cs_generate_variant:Nn \groupthm_new_theorem:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_theorem:nnnn,\groupthm_provide_theorem:nVVV} -% \begin{syntax} -% \cs{groupthm_provide_theorem:nnnn}\marg{environment name} -% \marg{groups clist}\marg{theorem name}\marg{thmtools keys} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem:nnnn #1 #2 #3 #4 - { - \groupthm_provide_grouped_theorem:nnnn - { #1 } { #2 } { #3 } { #4 } - \groupthm_provide_grouped_theorem:nnnn - { #1* } { #2, starred } { #3 } { #4 } - } -\cs_generate_variant:Nn \groupthm_provide_theorem:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% Combining these is also not difficult: -% -% -% -% -% \begin{macro}{\groupthm_new_theorem_star:nnnn} -% \begin{syntax} -% \cs{groupthm_new_theorem_star:nnnn}\marg{environment name} -% \marg{groups clist}\marg{theorem name}\marg{thmtools keys} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem_star:nnnn #1 #2 #3 #4 - { - \groupthm_new_theorem:nnnn - { #1 } { #2, unnumbered } { #3 } { #4 } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_theorem_star:nnnn} -% \begin{syntax} -% \cs{groupthm_provide_theorem_star:nnnn}\marg{environment name} -% \marg{groups clist}\marg{theorem name}\marg{thmtools keys} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem_star:nnnn #1 #2 #3 #4 - { - \groupthm_provide_theorem:nnnn - { #1 } { #2, unnumbered } { #3 } { #4 } - } -% \end{macrocode} -% \end{macro} -% -% We now provide the corresponding key-valued interfaces around these. -% All of these work in the same way: -% We set the normalized keys, and then pass these by value to the -% previously defined macros -% -% -% \begin{macro}{\groupthm_new_grouped_theorem_from_keys:nn} -% \begin{macrocode} -\cs_new:Npn \groupthm_new_grouped_theorem_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - - \groupthm_new_grouped_theorem:nVVV - { #1 } - \l_@@_key_group_clist - \l_@@_name_tl - \l_@@_key_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\groupthm_provide_grouped_theorem_from_keys:nn} -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_grouped_theorem_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - - \groupthm_provide_grouped_theorem:nVVV - { #1 } - \l_@@_key_group_clist - \l_@@_name_tl - \l_@@_key_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\groupthm_new_grouped_theorem_star_from_keys:nn} -% \begin{macrocode} -\cs_new:Npn \groupthm_new_grouped_theorem_star_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - - \groupthm_new_grouped_theorem_star:nVVV - { #2 } - \l_@@_key_group_clist - \l_@@_name_tl - \l_@@_key_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\groupthm_provide_grouped_theorem_star_from_keys:nn} -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_grouped_theorem_star_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - - \groupthm_provide_grouped_theorem_star:nVVV - { #2 } - \l_@@_key_group_clist - \l_@@_name_tl - \l_@@_key_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_new_theorem_from_keys:nn} -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - - \groupthm_new_theorem:nVVV - { #2 } - \l_@@_key_group_clist - \l_@@_name_tl - \l_@@_key_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\groupthm_provide_theorem_from_keys:nn} -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - - \groupthm_provide_theorem:nVVV - { #2 } - \l_@@_key_group_clist - \l_@@_name_tl - \l_@@_key_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\groupthm_new_theorem_star_from_keys:nn} -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem_star_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - - \groupthm_new_theorem_star:nVVV - { #1 } - \l_@@_key_group_clist - \l_@@_name_tl - \l_@@_key_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\groupthm_provide_theorem_star_from_keys:nn} -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem_star_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - - \groupthm_provide_theorem_star:nVVV - { #1 } - \l_@@_key_group_clist - \l_@@_name_tl - \l_@@_key_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% Now, we can wrap these into document commands -% -% -% \begin{macro}{\NewGroupedTheorem, \NewGroupedTheorem*} -% \begin{syntax} -% \cs{NewGroupedTheorem}\oarg{keys}\marg{theorem name} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand{\NewGroupedTheorem}{s O{} m} - { - \IfBooleanTF{#1} - { - \groupthm_new_grouped_theorem_star_from_keys:nn { #2 } { #3 } - } - { - \groupthm_new_grouped_theorem_from_keys:nn { #2 } { #3 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\ProvideGroupedTheorem, \ProvideGroupedTheorem*} -% \begin{syntax} -% \cs{ProvideGroupedTheorem}\oarg{keys}\marg{theorem name} -% \end{syntax} -% -% \begin{macrocode} -\ProvideDocumentCommand{\NewGroupedTheorem}{s O{} m} - { - \IfBooleanTF{#1} - { - \groupthm_provide_grouped_theorem_star_from_keys:nn { #2 } { #3 } - } - { - \groupthm_provide_grouped_theorem_from_keys:nn { #2 } { #3 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\NewTheorem, \NewTheorem*} -% \begin{syntax} -% \cs{NewTheorem}\oarg{keys}\marg{theorem name} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand{\NewTheorem}{s O{} m} - { - \IfBooleanTF{#1} - { - \groupthm_new_theorem_star_from_keys:nn { #2 } { #3 } - } - { - \groupthm_new_theorem_from_keys:nn { #2 } { #3 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\ProvideTheorem, \ProvideTheorem*} -% \begin{syntax} -% \cs{ProvideTheorem}\oarg{keys}\marg{theorem name} -% \end{syntax} -% -% \begin{macrocode} -\ProvideDocumentCommand{\NewTheorem}{s O{} m} - { - \IfBooleanTF{#1} - { - \groupthm_provide_theorem_star_from_keys:nn { #2 } { #3 } - } - { - \groupthm_provide_theorem_from_keys:nn { #2 } { #3 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% -% -% \subsection{Theorem families} -% -% -% We now want to implement the generation of theorem families and their -% corresponding options. -% As a backend, we use the following auxiliary function -% -% -% \begin{macro}{\@@_declare_grouped_theorem_family_aux:nnnnnn} -% \begin{syntax} -% \cs{@@_declare_grouped_theorem_family_aux:nnnnnn}\marg{family name}\marg{groups clist} -% \marg{name}\marg{name}\marg{thmtools clist}\marg{extra groups clist}\marg{generation type} -% \end{syntax} -% -% This will generate a new grouped theorem for each union of a subset of \mymeta{groups clist} -% and the extra set \mymeta{extra groups clist}, with the given properties, that is -% the \mymeta{nam} and \mymeta{thmtools clist} will be passed to the grouped theorem. -% The \mymeta{theorem name} of the grouped theorem will be an internal name that contains -% the \mymeta{family name} and the list of groups of this variant, that will be generated -% in a unique manner to later retrieve the generated theorems when parsing theorem families. -% -% The \mymeta{generation type} can be either \texttt{new} or \texttt{provide}, -% depending on which backend for grouped theorem generation to use -% \begin{macrocode} -\cs_new:Npn \@@_declare_grouped_theorem_family_aux:nnnnnn #1 #2 #3 #4 #5 #6 - { -% \end{macrocode} -% Make a local copy of the \mymeta{groups clist} argument, -% and iterate over its powerset -% \begin{macrocode} - \clist_set:Nn \l_tmpa_clist { #2 } - \powerset_clist_foreach:Nn \l_tmpa_clist - { -% \end{macrocode} -% We read out the current value of the list, and append the extra groups -% This ensures that now \cs{l_@@_group_clist} iterates over the proper subsets -% \begin{macrocode} - \clist_set_eq:NN \l_@@_group_clist \l_tmpa_clist - \clist_put_right:Nn \l_@@_group_clist { #5 } -% \end{macrocode} -% This sorting is necessary so that for each theorem family and set of groups, -% the generated name will be unique: -% \begin{macrocode} - \@@_sort_theorem_group_names: -% \end{macrocode} -% Now just declare the grouped theorem, passing the corresponding arguments and using -% specified \texttt{\#6} as backend. -% \begin{macrocode} - \use:c{groupthm_#6_grouped_theorem:xVnn} - {__#1__groups_\clist_use:Nn \l_@@_group_clist {_}} - \l_@@_group_clist - { #3 } - { #4 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\groupthm_new_grouped_theorem_family:nnnn,\groupthm_new_grouped_theorem_family:nVVV} -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem_family:nnnn}\marg{family name} -% \marg{groups}\marg{name}\marg{thmtools clist} -% \end{syntax} -% -% Just pass the arguments to the auxiliary function, with no additional groups -% and the \texttt{new} backend. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_grouped_theorem_family:nnnn #1 #2 #3 #4 - { - \@@_declare_grouped_theorem_family_aux:nnnnnn - { #1 } { #2 } { #3 } { #4 } { } { new } - } -\cs_generate_variant:Nn \groupthm_new_grouped_theorem_family:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_grouped_theorem_family:nnnn,\groupthm_provide_grouped_theorem_family:nVVV} -% \begin{syntax} -% \cs{groupthm_provide_grouped_theorem_family:nnnn}\marg{family name} -% \marg{groups}\marg{name}\marg{thmtools clist} -% \end{syntax} -% -% Just pass the arguments to the auxiliary function, with no additional groups -% and the \texttt{provide} backend. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_grouped_theorem_family:nnnn #1 #2 #3 #4 - { - \@@_declare_grouped_theorem_family_aux:nnnnnn - { #1 } { #2 } { #3 } { #4 } { } { provide } - } -\cs_generate_variant:Nn \groupthm_provide_grouped_theorem_family:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% The starred variants that add the \texttt{unnumbered} group are straightforward: -% -% -% -% \begin{macro}{\groupthm_new_grouped_theorem_family_star:nnnn,\groupthm_new_grouped_theorem_family_star:nVVV} -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem_family_star:nnnn}\marg{family name} -% \marg{groups}\marg{name}\marg{thmtools clist} -% \end{syntax} -% -% Just pass the arguments to the auxiliary function, with the additional -% \texttt{unnumbered group} and the \texttt{new} backend. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_grouped_theorem_family_star:nnnn #1 #2 #3 #4 - { - \@@_declare_grouped_theorem_family_aux:nnnnnn - { #1 } { #2 } { #3 } { #4 } { unnumbered } { new } - } -\cs_generate_variant:Nn \groupthm_new_grouped_theorem_family_star:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_grouped_theorem_family_star:nnnn,\groupthm_provide_grouped_theorem_family_star:nVVV} -% \begin{syntax} -% \cs{groupthm_provide_grouped_theorem_family_star:nnnn}\marg{family name} -% \marg{groups}\marg{name}\marg{thmtools clist} -% \end{syntax} -% -% Just pass the arguments to the auxiliary function, with the additional -% \texttt{unnumbered group} and the \texttt{provide} backend. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_grouped_theorem_family_star:nnnn #1 #2 #3 #4 - { - \@@_declare_grouped_theorem_family_aux:nnnnnn - { #1 } { #2 } { #3 } { #4 } { } { provide } - } -\cs_generate_variant:Nn \groupthm_provide_grouped_theorem_family_star:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% Now define the variants that also generate the starred and unstarred family versions. -% -% -% \begin{macro}{\groupthm_new_theorem_family:nnnn,\groupthm_new_theorem_family:nVVV} -% \begin{syntax} -% \cs{groupthm_new_theorem_family:nnnn}\marg{family name} -% \marg{groups}\marg{name}\marg{thmtools clist} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem_family:nnnn #1 #2 #3 #4 - { - \@@_declare_grouped_theorem_family_aux:nnnnnn - { #1 } { #2, starred } { #3 } { #4 } { } { new } - } -\cs_generate_variant:Nn \groupthm_new_theorem_family:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_theorem_family:nnnn,\groupthm_provide_theorem_family:nVVV} -% \begin{syntax} -% \cs{groupthm_provide_theorem_family:nnnn}\marg{family name} -% \marg{groups}\marg{name}\marg{thmtools clist} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem_family:nnnn #1 #2 #3 #4 - { - \@@_declare_grouped_theorem_family_aux:nnnnnn - { #1 } { #2, starred } { #3 } { #4 } { } { provide } - } -\cs_generate_variant:Nn \groupthm_provide_theorem_family:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\groupthm_new_theorem_family_star:nnnn,\groupthm_new_theorem_family_star:nVVV} -% \begin{syntax} -% \cs{groupthm_new_theorem_family_star:nnnn}\marg{family name} -% \marg{groups}\marg{name}\marg{thmtools clist} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem_family_star:nnnn #1 #2 #3 #4 - { - \@@_declare_grouped_theorem_family_aux:nnnnnn - { #1 } { #2, starred } { #3 } { #4 } { unnumbered } { new } - } -\cs_generate_variant:Nn \groupthm_new_theorem_family_star:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_theorem_family_star:nnnn,\groupthm_provide_theorem_family_star:nVVV} -% \begin{syntax} -% \cs{groupthm_provide_theorem_family_star:nnnn}\marg{family name} -% \marg{groups}\marg{name}\marg{thmtools clist} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem_family_star:nnnn #1 #2 #3 #4 - { - \@@_declare_grouped_theorem_family_aux:nnnnnn - { #1 } { #2, starred } { #3 } { #4 } { } { provide } - } -\cs_generate_variant:Nn \groupthm_provide_theorem_family_star:nnnn { n V V V } -% \end{macrocode} -% \end{macro} -% -% -% -% We now make the key variants available of these, all of the work in the same way -% as we just have to set the normalized keys and pass to our non-key-value versions. -% -% -% -% -% \begin{macro}{\groupthm_new_grouped_theorem_family_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem_family_from_keys:nn}\marg{keys}\marg{family name} -% \end{syntax} -% -% Just retrieve the normalized keys and pass on arguments. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_grouped_theorem_family_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - \groupthm_new_grouped_theorem_family:nVVV - { #2 } - \l_@@_group_clist - \l_@@_name_tl - \l_@@_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_grouped_theorem_family_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_provide_grouped_theorem_family_from_keys:nn}\marg{keys}\marg{family name} -% \end{syntax} -% -% Just retrieve the normalized keys and pass on arguments. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_grouped_theorem_family_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } {groupedtheorem} { #2 } - \groupthm_provide_grouped_theorem_family:nVVV - { #2 } - \l_@@_group_clist - \l_@@_name_tl - \l_@@_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_new_grouped_theorem_family_star_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem_family_star_from_keys:nn}\marg{keys}\marg{family name} -% \end{syntax} -% -% Just retrieve the normalized keys and pass on arguments. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_grouped_theorem_family_star_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem }{ #2 } - \groupthm_new_grouped_theorem_family_star:nVVV - { #2 } - \l_@@_group_clist - \l_@@_name_tl - \l_@@_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_grouped_theorem_family_star_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_provide_grouped_theorem_family_star_from_keys:nn}\marg{keys}\marg{family name} -% \end{syntax} -% -% Just retrieve the normalized keys and pass on arguments. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_grouped_theorem_family_star_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem }{ #2 } - \groupthm_provide_grouped_theorem_family_star:nVVV - { #2 } - \l_@@_group_clist - \l_@@_name_tl - \l_@@_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_new_theorem_family_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_new_theorem_family_from_keys:nn}\marg{keys}\marg{family name} -% \end{syntax} -% -% Just retrieve the normalized keys and pass on arguments. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem_family_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - \groupthm_new_theorem_family:nVVV - { #2 } - \l_@@_group_clist - \l_@@_name_tl - \l_@@_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_theorem_family_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_provide_theorem_family_from_keys:nn}\marg{keys}\marg{family name} -% \end{syntax} -% -% Just retrieve the normalized keys and pass on arguments. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem_family_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - \groupthm_provide_theorem_family:nVVV - { #2 } - \l_@@_group_clist - \l_@@_name_tl - \l_@@_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_new_theorem_family_star_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_new_theorem_family_star_from_keys:nn}\marg{keys}\marg{family name} -% \end{syntax} -% -% Just retrieve the normalized keys and pass on arguments. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem_family_star_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - \groupthm_new_theorem_family_star:nVVV - { #2 } - \l_@@_group_clist - \l_@@_name_tl - \l_@@_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_theorem_family_star_from_keys:nn} -% \begin{syntax} -% \cs{groupthm_provide_theorem_family_star_from_keys:nn}\marg{keys}\marg{family name} -% \end{syntax} -% -% Just retrieve the normalized keys and pass on arguments. -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem_family_star_from_keys:nn #1 #2 - { - \@@_set_normalized_keys:nnn { #1 } { groupedtheorem } { #2 } - \groupthm_provide_theorem_family_star:nVVV - { #2 } - \l_@@_group_clist - \l_@@_name_tl - \l_@@_thmtools_clist - } -% \end{macrocode} -% \end{macro} -% -% -% -% Finally, we can provide document commands that make these available. -% -% -% \begin{macro}{\NewGroupedTheoremFamily,\NewGroupedTheoremFamily*} -% \begin{syntax} -% \cs{NewGroupedTheoremFamily}\oarg{keys}\marg{family name} -% \end{syntax} -% -% -% -% \begin{macrocode} -\NewDocumentCommand{\NewGroupedTheoremFamily}{s O{} m} - { - \IfBooleanTF { #1 } - { - \groupthm_new_grouped_theorem_family_star_from_keys:nn { #2 } { #3 } - } - { - \groupthm_new_grouped_theorem_family_from_keys:nn { #2 } { #3 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\ProvideGroupedTheoremFamily,\ProvideGroupedTheoremFamily*} -% \begin{syntax} -% \cs{ProvideGroupedTheoremFamily}\oarg{keys}\marg{family name} -% \end{syntax} -% -% -% -% \begin{macrocode} -\NewDocumentCommand{\ProvideGroupedTheoremFamily}{s O{} m} - { - \IfBooleanTF { #1 } - { - \groupthm_provide_grouped_theorem_family_star_from_keys:nn { #2 } { #3 } - } - { - \groupthm_provide_grouped_theorem_family_from_keys:nn { #2 } { #3 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\NewTheoremFamily,\NewTheoremFamily*} -% \begin{syntax} -% \cs{NewTheoremFamily}\oarg{keys}\marg{family name} -% \end{syntax} -% -% -% -% \begin{macrocode} -\NewDocumentCommand{\NewTheoremFamily}{s O{} m} - { - \IfBooleanTF { #1 } - { - \groupthm_new_theorem_family_star_from_keys:nn { #2 } { #3 } - } - { - \groupthm_new_theorem_family_from_keys:nn { #2 } { #3 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\ProvideTheoremFamily,\ProvideTheoremFamily*} -% \begin{syntax} -% \cs{ProvideTheoremFamily}\oarg{keys}\marg{family name} -% \end{syntax} -% -% -% -% \begin{macrocode} -\NewDocumentCommand{\ProvideTheoremFamily}{s O{} m} - { - \IfBooleanTF { #1 } - { - \groupthm_provide_theorem_family_star_from_keys:nn { #2 } { #3 } - } - { - \groupthm_provide_theorem_family_from_keys:nn { #2 } { #3 } - } - } -% \end{macrocode} -% \end{macro} -% -% -% \subsection{Theorem family options} -% -% -% -% \begin{macro}{\groupthm_add_theorem_to_group:n} -% \begin{syntax} -% \cs{groupthm_add_theorem_to_group:n}\marg{theorem group} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_add_theorem_to_group:n #1 - { -% \end{macrocode} -% As mentioned earlier, this bool will indicate whether we are -% executing a \mymeta{selection body} from some family options. -% If used outside, we emit an error message. -% \begin{macrocode} - \bool_if:NTF \l_@@_in_family_options_environment_bool - { - \clist_put_left:Nn \l_@@_group_clist { #1 } - } - { - \msg_error:nn { groupthm } { misuse ~ add ~ theorem ~ to ~ group } - } - } -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\AddTheoremToGroup} -% \begin{syntax} -% \cs{AddTheoremToGroup}\marg{theorem group} -% \end{syntax} -% -% -% -% \begin{macrocode} - \NewDocumentCommand { \AddTheoremToGroup } { m } - { - \groupthm_add_theorem_to_group:n { #1 } - } -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_declare_theorem_family_options_aux:nnnnn} -% \begin{syntax} -% \c{@@_declare_theorem_family_options_aux:nnnnn}\marg{theorem family} -% \marg{argument specification}\marg{selection body}\marg{extra groups}\marg{declaring backend} -% \end{syntax} -% -% This declares a new theorem variant option parser, i.e.~ introduces the environment -% \mymeta{theorem family} with signature \marg{argument specification}. -% -% The \mymeta{selection body} will be executed and selects some groups the environment shall have. -% The \mymeta{extra groups} will be added regardless of the arguments given -% to the \mymeta{theorem family} -% The \mymeta{declaring backend} is one of \texttt{New}, \texttt{Renew}, \texttt{Provide} -% and \texttt{Declare} and is given to the \texttt{DocumentEnvironment} command from \pkg{xpars}. -% -% \begin{macrocode} -\cs_new:Npn \@@_declare_theorem_family_options_aux:nnnnn #1 #2 #3 #4 #5 - { - \use:c{ #5 DocumentEnvironment } - { #1 } - { #2 } - { -% \end{macrocode} -% We can now clear the group list and execute the \mymeta{selection body} -% that populates this list again. -% Additionally, we add the groups that should always be present and activate the -% \cs{AddTheoremToGroup} macro by setting the bool. -% \begin{macrocode} - \clist_clear:N \l_@@_group_clist - \bool_set_true:N \l_@@_in_family_options_environment_bool - #3 - \bool_set_false:N \l_@@_in_family_options_environment_bool - \clist_put_right:Nn \l_@@_group_clist { #4 } -% \end{macrocode} -% We now got the list of groups parsed. We sort this and start the corresponding -% environment that has been generated by a \cs{NewGroupedTheoremFamily} command -% or similar. -% \begin{macrocode} - \@@_sort_theorem_group_names: - \cs_if_exist:cTF { __#1__groups_ \clist_use:Nn \l_@@_group_clist { _ } } - { - \begin { __#1__groups_ \clist_use:Nn \l_@@_group_clist { _ } } - } - { - \msg_error:nnxx { groupthm } { undefined ~ theorem ~ variant } - { #1 } - { \clist_use:Nnnn \l_@@_group_clist { ~ and ~ } {, ~} { , ~ and ~ } } - } - } - { -% \end{macrocode} -% At the end of the environment, we have to do the same parsing again. -% \begin{macrocode} - \clist_clear:N \l_@@_group_clist - \bool_set_true:N \l_@@_in_family_options_environment_bool - #3 - \bool_set_false:N \l_@@_in_family_options_environment_bool - \clist_put_right:Nn \l_@@_group_clist { #4 } -% \end{macrocode} -% End the corresponding environment. -% \begin{macrocode} - \@@_sort_theorem_group_names: - \end { __#1__groups_ \clist_use:Nn \l_@@_group_clist { _ } } - } - } -% \end{macrocode} -% \end{macro} -% -% -% All other macros are now essentially wrappers around this aux macro, -% passing different \mymeta{extra groups} to them -% -% \begin{macro}{\groupthm_new_grouped_theorem_family_options:nnn} -% \begin{syntax} -% \cs{groupthm_new_grouped_theorem_family_options:nnn}\marg{theorem family} -% \marg{signature}\marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_grouped_theorem_family_options:nnn #1 #2 #3 -{ - \@@_declare_theorem_family_options_aux:nnnnn - { #1 } { #2 } { #3 } { } { New } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_renew_grouped_theorem_family_options:nnn} -% \begin{syntax} -% \cs{groupthm_renew_grouped_theorem_family_options:nnn}\marg{theorem family} -% \marg{signature}\marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_renew_grouped_theorem_family_options:nnn #1 #2 #3 -{ - \@@_declare_theorem_family_options_aux:nnnnn - { #1 } { #2 } { #3 } { } { Renew } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_provide_grouped_theorem_family_options:nnn} -% \begin{syntax} -% \cs{groupthm_provide_grouped_theorem_family_options:nnn}\marg{theorem family} -% \marg{signature}\marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_grouped_theorem_family_options:nnn #1 #2 #3 -{ - \@@_declare_theorem_family_options_aux:nnnnn - { #1 } { #2 } { #3 } { } { Provide } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\groupthm_declare_grouped_theorem_family_options:nnn} -% \begin{syntax} -% \cs{groupthm_declare_grouped_theorem_family_options:nnn}\marg{theorem family} -% \marg{signature}\marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\cs_new:Npn \groupthm_declare_grouped_theorem_family_options:nnn #1 #2 #3 -{ - \@@_declare_theorem_family_options_aux:nnnnn - { #1 } { #2 } { #3 } { } { Declare } -} -% \end{macrocode} -% \end{macro} -% -% -% -% The variants without \enquote{grouped} in their name will just issue two commands, -% one with and one without the \texttt{starred} group, and add a \enquote{*} to the name. -% -% \begin{macro}{\groupthm_new_theorem_family_options:nnn} -% \begin{syntax} -% \cs{groupthm_new_theorem_family_options:nnn}\marg{theorem family} -% \marg{signature}\marg{selection body} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_new_theorem_family_options:nnn #1 #2 #3 -{ - \@@_declare_theorem_family_options_aux:nnnnn - { #1 } { #2 } { #3 } { } { New } - \@@_declare_theorem_family_options_aux:nnnnn - { #1* } { #2 } { #3 } { starred } { New } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\groupthm_renew_theorem_family_options:nnn} -% \begin{syntax} -% \cs{groupthm_renew_theorem_family_options:nnn}\marg{theorem family} -% \marg{signature}\marg{selection body} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_renew_theorem_family_options:nnn #1 #2 #3 -{ - \@@_declare_theorem_family_options_aux:nnnnn - { #1 } { #2 } { #3 } { } { Renew } - \@@_declare_theorem_family_options_aux:nnnnn - { #1* } { #2 } { #3 } { starred } { Renew } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\groupthm_provide_theorem_family_options:nnn} -% \begin{syntax} -% \cs{groupthm_provide_theorem_family_options:nnn}\marg{theorem family} -% \marg{signature}\marg{selection body} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_provide_theorem_family_options:nnn #1 #2 #3 -{ - \@@_declare_theorem_family_options_aux:nnnnn - { #1 } { #2 } { #3 } { } { Provide } - \@@_declare_theorem_family_options_aux:nnnnn - { #1* } { #2 } { #3 } { starred } { Provide } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\groupthm_declare_theorem_family_options:nnn} -% \begin{syntax} -% \cs{groupthm_declare_theorem_family_options:nnn}\marg{theorem family} -% \marg{signature}\marg{selection body} -% \end{syntax} -% -% -% \begin{macrocode} -\cs_new:Npn \groupthm_declare_theorem_family_options:nnn #1 #2 #3 -{ - \@@_declare_theorem_family_options_aux:nnnnn - { #1 } { #2 } { #3 } { } { Declare } - \@@_declare_theorem_family_options_aux:nnnnn - { #1* } { #2 } { #3 } { starred } { Declare } -} -% \end{macrocode} -% \end{macro} -% -% -% It remains to wrap these into document commands -% -% -% \begin{macro}{\NewGroupedTheoremFamilyOptions, \NewGroupedTheoremFamilyOptions*} -% \begin{syntax} -% \cs{NewGroupedTheoremFamilyOptions}\marg{family name}\marg{signature} -% \marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand { \NewGroupedTheoremFamilyOptions } { s m m m } -{ - \IfBooleanTF { #1 } - { - \groupthm_new_grouped_theorem_family_options:nnn - { #2 } - { #3 } - { - #4 - \groupthm_add_theorem_to_group:n { unnumbered } - } - } - { - \groupthm_new_grouped_theorem_family_options:nnn - { #2 } - { #3 } - { #4 } - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\RenewGroupedTheoremFamilyOptions, \RenewGroupedTheoremFamilyOptions*} -% \begin{syntax} -% \cs{RenewGroupedTheoremFamilyOptions}\marg{family name}\marg{signature} -% \marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand { \RenewGroupedTheoremFamilyOptions } { s m m m } -{ - \IfBooleanTF { #1 } - { - \groupthm_renew_grouped_theorem_family_options:nnn - { #2 } - { #3 } - { - #4 - \groupthm_add_theorem_to_group:n { unnumbered } - } - } - { - \groupthm_renew_grouped_theorem_family_options:nnn - { #2 } - { #3 } - { #4 } - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\ProvideGroupedTheoremFamilyOptions, \ProvideGroupedTheoremFamilyOptions*} -% \begin{syntax} -% \cs{ProvideGroupedTheoremFamilyOptions}\marg{family name}\marg{signature} -% \marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand { \ProvideGroupedTheoremFamilyOptions } { s m m m } -{ - \IfBooleanTF { #1 } - { - \groupthm_provide_grouped_theorem_family_options:nnn - { #2 } - { #3 } - { - #4 - \groupthm_add_theorem_to_group:n { unnumbered } - } - } - { - \groupthm_provide_grouped_theorem_family_options:nnn - { #2 } - { #3 } - { #4 } - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\DeclareGroupedTheoremFamilyOptions, \DeclareGroupedTheoremFamilyOptions*} -% \begin{syntax} -% \cs{DeclareGroupedTheoremFamilyOptions}\marg{family name}\marg{signature} -% \marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand { \DeclareGroupedTheoremFamilyOptions } { s m m m } -{ - \IfBooleanTF { #1 } - { - \groupthm_declare_grouped_theorem_family_options:nnn - { #2 } - { #3 } - { - #4 - \groupthm_add_theorem_to_group:n { unnumbered } - } - } - { - \groupthm_declare_grouped_theorem_family_options:nnn - { #2 } - { #3 } - { #4 } - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% \begin{macro}{\NewTheoremFamilyOptions, \NewTheoremFamilyOptions*} -% \begin{syntax} -% \cs{NewTheoremFamilyOptions}\marg{family name}\marg{signature} -% \marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand { \NewTheoremFamilyOptions } { s m m m } -{ - \IfBooleanTF { #1 } - { - \groupthm_new_theorem_family_options:nnn - { #2 } - { #3 } - { - #4 - \groupthm_add_theorem_to_group:n { unnumbered } - } - } - { - \groupthm_new_theorem_family_options:nnn - { #2 } - { #3 } - { #4 } - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\RenewTheoremFamilyOptions, \RenewTheoremFamilyOptions*} -% \begin{syntax} -% \cs{RenewTheoremFamilyOptions}\marg{family name}\marg{signature} -% \marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand { \RenewTheoremFamilyOptions } { s m m m } -{ - \IfBooleanTF { #1 } - { - \groupthm_renew_theorem_family_options:nnn - { #2 } - { #3 } - { - #4 - \groupthm_add_theorem_to_group:n { unnumbered } - } - } - { - \groupthm_renew_theorem_family_options:nnn - { #2 } - { #3 } - { #4 } - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\ProvideTheoremFamilyOptions, \ProvideTheoremFamilyOptions*} -% \begin{syntax} -% \cs{ProvideTheoremFamilyOptions}\marg{family name}\marg{signature} -% \marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand { \ProvideTheoremFamilyOptions } { s m m m } -{ - \IfBooleanTF { #1 } - { - \groupthm_provide_theorem_family_options:nnn - { #2 } - { #3 } - { - #4 - \groupthm_add_theorem_to_group:n { unnumbered } - } - } - { - \groupthm_provide_theorem_family_options:nnn - { #2 } - { #3 } - { #4 } - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\DeclareTheoremFamilyOptions, \DeclareTheoremFamilyOptions*} -% \begin{syntax} -% \cs{DeclareTheoremFamilyOptions}\marg{family name}\marg{signature} -% \marg{selection body} -% \end{syntax} -% -% \begin{macrocode} -\NewDocumentCommand { \DeclareTheoremFamilyOptions } { s m m m } -{ - \IfBooleanTF { #1 } - { - \groupthm_declare_theorem_family_options:nnn - { #2 } - { #3 } - { - #4 - \groupthm_add_theorem_to_group:n { unnumbered } - } - } - { - \groupthm_declare_theorem_family_options:nnn - { #2 } - { #3 } - { #4 } - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% -% \begin{macrocode} -% -% \end{macrocode} -% -% \end{implementation} -% -% -% -% -% \ExplSyntaxOn -% \__codedoc_special_index_module:nnnnN { key } { macro } { module } { main } { \c_false_bool} -% \__codedoc_special_index_module:nnnnN { l } { bla } { module } { usage } { \c_false_bool} -% \ExplSyntaxOff -% -% \newpage -% \PrintIndex diff --git a/doc/environments/groupthm/groupthm.dtx b/doc/environments/groupthm/groupthm.dtx index ba92496..f6f5207 100644 --- a/doc/environments/groupthm/groupthm.dtx +++ b/doc/environments/groupthm/groupthm.dtx @@ -37,7 +37,6 @@ % % \begin{documentation} % -% \tableofcontents % % % A central thing in \LaTeX is the usage of \enquote{theorems}. @@ -63,6 +62,14 @@ % % Thus, any styles supported by \pkg{thmtools} will be supported by \pkg{groupthm} % as well, by passing them to \pkg{thmtools}. +% +% +% In this documentation, we first give a more detailed overview of the concepts +% provided, and then describe the usage in detail. +% +% \newpage +% \tableofcontents +% \newpage % % \section{Concepts} % @@ -207,6 +214,12 @@ % Thus, actually, calls to \cs{NewGroupedTheorem} will have an underlying % \cs{declaretheorem}, but you do not have to bother with this. % \end{texnote} +% +% \begin{danger} +% Paragraphs like this that begin with a dangerous bend sign give more details +% that could be used, but whose use is not recommended, as it does not apply +% to the usual naming conventions. Use at your own responsibility. +% \end{danger} % % \section{Theorem groups} % diff --git a/doc/environments/groupthm/groupthm.sty b/doc/environments/groupthm/groupthm.sty deleted file mode 100644 index 19ea16d..0000000 --- a/doc/environments/groupthm/groupthm.sty +++ /dev/null @@ -1,752 +0,0 @@ -%% -%% This is file `groupthm.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% groupthm.dtx (with options: `package') -%% -%% IMPORTANT NOTICE: -%% -%% For the copyright see the source file. -%% -%% Any modified versions of this file must be renamed -%% with new filenames distinct from groupthm.sty. -%% -%% For distribution of the original source see the terms -%% for copying and modification in the file groupthm.dtx. -%% -%% This generated file may be distributed as long as the -%% original source files, as listed above, are part of the -%% same distribution. (The sources need not necessarily be -%% in the same archive or directory.) -%% File: groupthm.dtx -\ProvidesExplPackage{groupthm}{2022/01/17}{0.0.1}{Grouped theorems.} - -\RequirePackage{amsthm} -\RequirePackage{thmtools} -\cs_new:Npn \__groupthm_thmtools_declare_theorem:nn #1 #2 - { - \tl_log:n { Declaring ~ thmtools ~ theorem ~ #2 } - \declaretheorem [ #1 ] { #2 } - } -\cs_generate_variant:Nn \__groupthm_thmtools_declare_theorem:nn { V n } -\cs_new:Npn \__groupthm_hook_gset_rule_foreach:nNnn #1 #2 #3 #4 - { - \cs_set:Npn \__groupthm_map_aux:n ##1 - { - \hook_gset_rule:nnnn { #1 } { ##1 } { #3 } { #4 } - } - \clist_map_function:NN #2 \__groupthm_map_aux:n - } -\msg_new:nnn { groupthm } { unknown ~ group } -{ - Unknown ~ group ~ '#1' ~ supplied ~ \msg_line_context: -} -\msg_new:nnn { groupthm } { unknown ~ key } -{ - Unknown ~ key ~ '#1' ~ supplied ~ \msg_line_context: -} -\msg_new:nnn { groupthm } { wrong ~ definition } -{ - Bad ~ definition ~ of ~ #1 ~ '#2' ~ \msg_line_context:, ~ #1 ~ is ~ #3 ~ defined. -} -\msg_new:nnn { groupthm } { misuse ~ add ~ theorem ~ to ~ group } - { - Bad ~ usage ~ of ~ 'AddTheoremToGroup' ~ macro ~ outside ~ theorem ~ - family ~ options ~ \msg_line_context: - } -\msg_new:nnnn { groupthm } { undefined ~ theorem ~ variant } - { - Bad ~ call ~ of ~ theorem ~ variant ~ of ~ '#1' ~ \msg_line_context: - } - { - You ~ wanted ~ to ~ call ~ the ~ variant ~ with ~ group(s) ~ - '#2' ~ of ~ theorem ~ family ~ '#1', ~ but ~ it ~ has ~ not ~ been ~ - generated ~ yet. ~ - Probably ~ you ~ forgot ~ this. ~ - \msg_see_documentation_text:n { groupthm } - } -\hook_new:n { __groupthm/prefix } -\hook_new:n { __groupthm/suffix } -\hook_new:n { __groupthm/mapname } -\hook_new:n { __groupthm/thmtools } -\hook_new:n { __groupthm/groupsort } -\cs_generate_variant:Nn \hook_gset_rule:nnnn { n n V n } -\bool_new:N \l__groupthm_key_starred_version_bool -\tl_new:N \l__groupthm_key_prefix_tl -\tl_new:N \l__groupthm_key_name_tl -\tl_new:N \l__groupthm_key_suffix_tl -\clist_new:N \l__groupthm_key_group_clist -\clist_new:N \l__groupthm_key_mapname_clist -\clist_new:N \l__groupthm_key_thmtools_clist -\tl_new:N \l__groupthm_prefix_tl -\tl_new:N \l__groupthm_name_tl -\tl_new:N \l__groupthm_suffix_tl -\clist_new:N \l__groupthm_mapname_clist -\clist_new:N \l__groupthm_thmtools_clist -\clist_new:N \l__groupthm_group_clist -\clist_new:N \g__groupthm_defined_groups_clist -\bool_new:N \l__groupthm_in_family_options_environment_bool -\int_new:N \g__groupthm_append_groups_int -\keys_define:nn { groupthm / theorem ~ group } - { - prefix .tl_set:N = \l__groupthm_key_prefix_tl, - prefix .default:n = \c_empty_tl, - suffix .tl_set:N = \l__groupthm_key_suffix_tl, - suffix .default:n = \c_empty_tl, - suffix .groups:n = { theoremgroup }, - map ~ name .clist_set:N = \l__groupthm_mapname_clist, - map ~ name .default:n = {}, - map ~ name .groups:n = { theoremgroup }, - thmtools .clist_set:N = \l__groupthm_key_thmtools_clist, - thmtools .default:n = {}, - unknown .code:n = - \msg_error:nnn { groupthm } { unknown ~ key } { \l_keys_key_str } - } -\keys_define:nn { groupthm / grouped ~ theorem } - { - name .tl_set:N = \l__groupthm_key_name_tl, - name .default:n = \c_novalue_tl, - group .clist_set:N = \l__groupthm_key_group_clist, - group .default:n = {}, - thmtools .clist_set:N = \l__groupthm_key_thmtools_clist, - thmtools .default:n = {}, - starred ~ version .bool_set:N = \l__groupthm_key_starred_version_bool, - starred ~ version .default:n = { true }, - unknown .code:n = - \msg_error:nnn { groupthm } { unknown ~ key } { \l_keys_key_str } - } -\keys_define:nn { groupthm / theorem ~ family } - { - name .tl_set:N = \l__groupthm_key_name_tl, - name .default:n = \c_novalue_tl, - group .clist_set:N = \l__groupthm_key_group_clist, - group .default:n = {}, - thmtools .clist_set:N = \l__groupthm_key_thmtools_clist, - thmtools .default:n = {}, - starred ~ version .bool_set:N = \l__groupthm_key_starred_version_bool, - starred ~ version .default:n = { true }, - unknown .code:n = - \msg_error:nnn { groupthm } { unknown ~ key } { \l_keys_key_str } - } -\keys_define:nn { groupthm / theorem ~ family ~ options } - { - starred ~ version .bool_set:N = \l__groupthm_key_starred_version_bool, - starred ~ version .default:n = { true }, - unknown .code:n = - \msg_error:nnn { groupthm } { unknown ~ key } { \l_keys_key_str } - } -\cs_new:Npn \__groupthm_set_normalized_keys:nnn #1 #2 #3 - { - \keys_set:nn { groupthm / theorem ~ group } - { prefix, suffix, thmtools, map ~ name } - \keys_set:nn { groupthm / grouped ~ theorem } - { name, group, thmtools, starred ~ version } - \keys_set:nn { groupthm / theorem ~ family } - { name, group, thmtools, starred ~ version } - \keys_set:nn { groupthm / #2 } { #1 } - \tl_if_eq:NnTF \l__groupthm_key_name_tl { \c_novalue_tl } - { - \tl_set:Nx \l__groupthm_name_tl - { - \text_titlecase_first:n {#3} - } - } - { - \tl_set_eq:NN \l__groupthm_name_tl \l__groupthm_key_name_tl - } - \bool_set_eq:NN \l__groupthm_starred_version_bool \l__groupthm_key_starred_version_bool - \tl_set_eq:NN \l__groupthm_prefix_tl \l__groupthm_key_prefix_tl - \tl_set_eq:NN \l__groupthm_suffix_tl \l__groupthm_key_suffix_tl - \clist_set_eq:NN \l__groupthm_group_clist \l__groupthm_key_group_clist - \clist_set_eq:NN \l__groupthm_mapname_clist \l__groupthm_key_mapname_clist - \clist_set_eq:NN \l__groupthm_thmtools_clist \l__groupthm_key_thmtools_clist - } -\cs_new:Npn \__groupthm_add_to_group_ordering:n #1 - { - \__groupthm_hook_gset_rule_foreach:nNnn - { __groupthm/groupsort } - \g__groupthm_defined_groups_clist - { before } - { #1 } - } -\cs_new:Npn \__groupthm_remove_from_group_ordering:n #1 - { - \__groupthm_hook_gset_rule_foreach:nNnn - { __groupthm/groupsort } - \g__groupthm_defined_groups_clist - { unrelated } - { #1 } - } -\cs_new:Npn \__groupthm_add_to_sort_hook:n #1 -{ - \hook_gput_code:nnn { __groupthm/groupsort } - { #1 } - { - \clist_put_left:Nn \l__groupthm_group_clist { #1 } - } -} -\cs_new:Npn \__groupthm_sort_group_names: - { - \hook_gremove_code:nn { __groupthm/groupsort }{*} - \clist_map_function:NN \l__groupthm_group_clist \__groupthm_add_to_sort_hook:n - \clist_clear:N \l__groupthm_group_clist - \hook_use:n { __groupthm/groupsort } - } -\cs_new:Npn \__groupthm_define_group:nnnnn #1#2#3#4#5 - { - \cs_new:cpn { __groupthm_use_group__#1: } - { - \hook_gput_code:nnn { __groupthm/prefix } { #1 } - { - \tl_put_left:Nx \l__groupthm_prefix_tl { #2 } - } - \hook_gput_code:nnn { __groupthm/suffix } { #1 } - { - \tl_put_right:Nx \l__groupthm_suffix_tl { #3 } - } - \hook_gput_code:nnn { __groupthm/mapname } { #1 } - { - \clist_put_right:Nn \l__groupthm_mapname_clist { #4 } - } - \hook_gput_code:nnn { __groupthm/thmtools } { #1 } - { - \clist_put_right:Nn \l__groupthm_thmtools_clist { #5 } - } - } - \__groupthm_add_to_group_ordering:n { #1 } - \clist_new:c { g__groupthm_parents_group__#1__clist } - \hook_gset_rule:nnnn { ?? } { all } { before } { #1 } - \hook_gset_rule:nnnn { ?? } { unnumbered } { after } { #1 } - \hook_gset_rule:nnnn { ?? } { starred } { after } { #1 } - \clist_gput_left:Nn \g__groupthm_defined_groups_clist { #1 } - } -\cs_new:Npn \__groupthm_undefine_group:n #1 - { - \tl_log:n { Undefining ~ theorem ~ group ~ '#1' } - \cs_undefine:c { __groupthm_use_group__#1: } - \hook_gremove_code:nn { __groupthm/prefix } { #1 } - \hook_gremove_code:nn { __groupthm/suffix } { #1 } - \hook_gremove_code:nn { __groupthm/mapname } { #1 } - \hook_gremove_code:nn { __groupthm/thmtools } { #1 } - \clist_gremove_all:Nn \g__groupthm_defined_groups_clist { #1 } - \cs_undefine:c { g__groupthm_parents_group__#1__clist } - \__groupthm_hook_gset_rule_foreach:nNnn - { ?? } - \g__groupthm_defined_groups_clist - { unrelated } - { #1 } - \__groupthm_hook_gset_rule_foreach:nNnn - { __groupthm/prefix } - \g__groupthm_defined_groups_clist - { unrelated } - { #1 } - \__groupthm_hook_gset_rule_foreach:nNnn - { __groupthm/suffix } - \g__groupthm_defined_groups_clist - { unrelated } - { #1 } - \__groupthm_hook_gset_rule_foreach:nNnn - { __groupthm/mapname } - \g__groupthm_defined_groups_clist - { unrelated } - { #1 } - \__groupthm_hook_gset_rule_foreach:nNnn - { __groupthm/thmtools } - \g__groupthm_defined_groups_clist - { unrelated } - { #1 } - \__groupthm_remove_from_group_ordering:n { #1 } - } -\cs_new:Npn \__groupthm_define:nnnNNNn #1 #2 #3 #4 #5 #6 #7 - { - \bool_if:nT - { - \str_if_eq_p:nn { #1 } { new } - && - \cs_if_exist_p:N #4 - } - { - \tl_log:n { Wrong ~ 'new' ~ definition ~ of ~ #2 ~ '#3' ~ detected. } - \msg_error:nnnnn { groupthm } { wrong ~ definition } - { #2 } { #3 } { already } - } - \bool_if:nT - { - \str_if_eq_p:nn { #1 } { renew } - && - ! \cs_if_exist_p:N #4 - } - { - \tl_log:n { Wrong ~ 'renew' ~ definition ~ of ~ #2 ~ '#3' ~ detected. } - \msg_error:nnnnn { groupthm } { wrong ~ definition } - { #2 } { #3 } { not } - } - \bool_if:nT - { - ( - \str_if_eq_p:nn { #1 } { declare } || - \str_if_eq_p:nn { #1 } { renew } - ) && - \cs_if_exist_p:N #4 - } - { - \tl_log:n { Removing ~ definition ~ of ~ #2 ~ '#3'. } - \tl_log:n { Declarator ~ was ~ #1. } - #5 { #3 } - } - \bool_if:nTF - { - \cs_if_exist_p:N #4 - && - \str_if_eq_p:nn { #1 } { provide } - } - { - \tl_log:n { Providing ~ #2 ~ '#3' ~ skipped: ~ '#3' ~ already ~ defined. } - } - { - \tl_log:n { Defining ~ #2 ~ '#3'. } - #6 #7 - } - } -\cs_generate_variant:Nn \__groupthm_define:nnnNNNn { n n n c N N n } -\cs_new:Npn \__groupthm_define_multiple:nnnNNnn #1 #2 #3 #4 #5 #6 #7 - { - \cs_set:Npn \__groupthm_map_aux:n ##1 - { - \cs_new:cn { #6 } - { - \__groupthm_define:nnncNNn - { ##1 } - { #2 } - { ####1 } - { #3 } - #4 - #5 - { #7 } - } - } - \clist_map_function:nN { #1 } \__groupthm_map_aux:n - } -\__groupthm_define_multiple:nnnNNnn - { new, renew, provide, declare } - { theorem group } - { __groupthm_use_group__##1: } - \__groupthm_undefine_group:n - \__groupthm_define_group:nnnnn - { groupthm_#1_group:nnnnn } - { { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } } -\cs_generate_variant:Nn \groupthm_new_group:nnnnn { n V V V V } -\cs_generate_variant:Nn \groupthm_renew_group:nnnnn { n V V V V } -\cs_generate_variant:Nn \groupthm_provide_group:nnnnn { n V V V V } -\cs_generate_variant:Nn \groupthm_declare_group:nnnnn { n V V V V } - -\cs_new:Npn \__groupthm_wrap_multiple:nnn #1 #2 #3 - { - \cs_set:Npn \__groupthm_map_aux:n ##1 - { - \cs_new:cn { #2 } - { - #3 - } - } - \clist_map_function:nN { #1 } \__groupthm_map_aux:n - } - -\__groupthm_wrap_multiple:nnn - { new, renew, provide, declare } - { groupthm_#1_group:nn } - { - \__groupthm_set_normalized_keys:nnn { ##1 } { theorem ~ group } { ##2 } - \use:c { groupthm_#1_group:nVVVV } - { ##2 } - \l__groupthm_prefix_tl - \l__groupthm_suffix_tl - \l__groupthm_mapname_clist - \l__groupthm_thmtools_clist - } -\cs_generate_variant:Nn \groupthm_new_group:nn { n x } -\cs_new:Npn \__groupthm_new_document_command:Nnn #1 #2 #3 - { - \NewDocumentCommand { #1 } { #2 } { #3 } - } -\cs_generate_variant:Nn \__groupthm_new_document_command:Nnn { c n n } -\cs_new:Npn \__groupthm_wrap_multiple_document:nnnn #1 #2 #3 #4 - { - \cs_set:Npn \__groupthm_map_aux:n ##1 - { - \cs_set:Nn \__groupthm_Declarator: { \text_titlecase_first:n { ##1 } } - \__groupthm_new_document_command:cnn { #2 } { #3 } { #4 } - } - \clist_map_function:nN { #1 } \__groupthm_map_aux:n - } -\__groupthm_wrap_multiple_document:nnnn - { new, renew, provide, declare } - { \__groupthm_Declarator: TheoremGroup } - { O{} m } - { - \use:c { groupthm_#1 _group:nn } { ##1 } { ##2 } - } -\cs_new:Npn \groupthm_declare_group_rule:nnnn #1 #2 #3 #4 - { - \str_set:Nx \l_tmpa_str { \tl_trim_spaces:n { #3 } } - \str_if_eq:VnT \l_tmpa_str { higher } - { - \str_set:Nn \l_tmpa_str { after } - } - \str_if_eq:VnT \l_tmpa_str { lower } - { - \str_set:Nn \l_tmpa_str { before } - } - \str_if_eq:nnTF { #1 } { ?? } - { - \hook_gset_rule:nnVn {??} {#2} \l_tmpa_str {#4} - } - { - \hook_gset_rule:nnVn { __groupthm / #1 } {#2} \l_tmpa_str {#4} - } - } -\cs_generate_variant:Nn \groupthm_declare_group_rule:nnnn { n n n x } - -\NewDocumentCommand { \DeclareTheoremGroupRule } { O{??} m m m } - { - \groupthm_declare_group_rule:nnnn {#1} {#2} {#3} {#4} - } -\cs_new:Npn \groupthm_add_parent:nn #1 #2 - { - \__groupthm_ensure_group_exists:n { #1 } - \__groupthm_ensure_group_exists:n { #2 } - \clist_gput_left:cn { g__groupthm_parents_group__#1__clist } { #2 } - } -\cs_generate_variant:Nn \groupthm_add_parent:nn { n x } -\NewDocumentCommand { \AddTheoremGroupParent } { m m } - { - \groupthm_add_parent:nn { #1 } { #2 } - } - -\cs_new:Npn \__groupthm_push_tmpa_seq:n #1 - { - \seq_push:Nn \l_tmpa_seq { #1 } - } -\cs_new:Npn \__groupthm_flatten_groups_hierarchy:nN #1 #2 - { - \clist_clear:N #2 - \seq_set_from_clist:Nn \l_tmpa_seq { #1 } - \bool_until_do:nn - { - \seq_if_empty_p:N \l_tmpa_seq - } - { - \seq_pop:NN \l_tmpa_seq \l_tmpa_tl - \clist_if_in:NVF #2 \l_tmpa_tl - { - \clist_put_left:NV #2 \l_tmpa_tl - \clist_map_function:cN - { g__groupthm_parents_group__ \l_tmpa_tl __clist } - \__groupthm_push_tmpa_seq:n - } - } - } -\cs_new:Npn \groupthm_append_to_group:nn #1 #2 - { - \groupthm_new_group:nx { #1 } { __append__ \int_use:N \g__groupthm_append_groups_int } - \groupthm_add_parent:nx { #2 } { __append__ \int_use:N \g__groupthm_append_groups_int } - \groupthm_declare_group_rule:nnnx - { ?? } { #2 } { before } { __append__ \int_use:N \g__groupthm_append_groups_int } - \int_gincr:N \g__groupthm_append_groups_int - } - -\NewDocumentCommand { \AppendToTheoremGroup } { O{} m } - { - \groupthm_append_to_group:nn { #1 } { #2 } - } - -\groupthm_new_group:nnnnn { all } { } { } { } { } -\groupthm_new_group:nnnnn { starred } { } { } { } { numbered = no } -\groupthm_new_group:nnnnn { unnumbered } { } { } { } { numbered = no } -\clist_new:N \l__powerset_copied_clist -\seq_new:N \l__powerset_saved_seq -\cs_generate_variant:Nn \clist_remove_all:Nn { N V } -\cs_new:Npn \__powerset_clist_foreach_aux:Nn #1 #2 - { - \clist_if_empty:NTF \l__powerset_copied_clist - { - #2 - } - { - \clist_get:NN \l__powerset_copied_clist \l_tmpa_tl - \seq_push:NV \l__powerset_saved_seq \l_tmpa_tl - \clist_pop:NN \l__powerset_copied_clist { \l_tmpa_tl } - - \__powerset_clist_foreach_aux:Nn #1 {#2} - - \seq_get:NN \l__powerset_saved_seq \l_tmpa_tl - \clist_put_left:NV #1 \l_tmpa_tl - - \__powerset_clist_foreach_aux:Nn #1 {#2} - - \seq_get:NN \l__powerset_saved_seq \l_tmpa_tl - \clist_remove_all:NV #1 \l_tmpa_tl - \clist_push:NV \l__powerset_copied_clist \l_tmpa_tl - \seq_pop:NN \l__powerset_saved_seq \l_tmpa_tl - } - } -\cs_new:Npn \powerset_clist_foreach:Nn #1 #2 - { - \clist_set_eq:NN \l__powerset_copied_clist #1 - \clist_clear:N #1 - \clist_remove_duplicates:N \l__powerset_copied_clist - \__powerset_clist_foreach_aux:Nn #1 {#2} - \clist_set_eq:NN #1 \l__powerset_copied_clist - } -\cs_new:Npn \__groupthm_ensure_group_exists:n #1 - { - \cs_if_exist:cF { __groupthm_use_group__#1: } - { - \msg_error:nnn { groupthm } { unknown ~ group } { #1 } - } - } -\cs_new:Npn \__groupthm_use_group:n #1 - { - \__groupthm_ensure_group_exists:n { #1 } - \use:c { __groupthm_use_group__#1: } - } -\cs_new:Npn \__groupthm_use_function_on_name:n #1 - { - \tl_set:Nx \l__groupthm_name_tl - { - #1 { \tl_use:N \l__groupthm_name_tl } - } - } -\cs_new:Npn \__groupthm_define_theorem:nnnn #1 #2 #3 #4 - { - \tl_clear:N \l__groupthm_prefix_tl - \tl_set:Nn \l__groupthm_name_tl { #3 } - \tl_clear:N \l__groupthm_suffix_tl - \clist_clear:N \l__groupthm_mapname_clist - \clist_clear:N \l__groupthm_thmtools_clist - \hook_gremove_code:nn { __groupthm/prefix }{*} - \hook_gremove_code:nn { __groupthm/suffix }{*} - \hook_gremove_code:nn { __groupthm/mapname }{*} - \hook_gremove_code:nn { __groupthm/thmtools }{*} - \__groupthm_flatten_groups_hierarchy:nN { #2, all } \l__groupthm_group_clist - \clist_map_function:NN \l__groupthm_group_clist \__groupthm_use_group:n - \tl_log:x { Flattened ~ groups ~ '#2' ~ to ~ '\clist_use:Nn \l__groupthm_group_clist {,}' ~ when ~ - defining ~ theorem ~ '#1' } - \hook_use:n { __groupthm/prefix } - \hook_use:n { __groupthm/suffix } - \hook_use:n { __groupthm/mapname } - \hook_use:n { __groupthm/thmtools } - \clist_map_function:NN \l__groupthm_mapname_clist \map_use_on_name:n - \clist_put_right:Nx \l__groupthm_thmtools_clist - { - name = \tl_use:N \l__groupthm_prefix_tl - \tl_use:N \l__groupthm_name_tl - \tl_use:N \l__groupthm_suffix_tl - } - \clist_put_right:Nn \l__groupthm_thmtools_clist { #4 } - \__groupthm_thmtools_declare_theorem:Vn - \l__groupthm_thmtools_clist - { #1 } - } -\__groupthm_define_multiple:nnnNNnn - { new, provide } - { grouped ~ theorem } - { ##1 } - \__groupthm_error: - \__groupthm_define_theorem:nnnn - { groupthm_#1_theorem:nnnn } - { { ##1 } { ##2 } { ##3 } { ##4 } } -\cs_generate_variant:Nn \groupthm_new_theorem:nnnn { n V V V } -\cs_generate_variant:Nn \groupthm_provide_theorem:nnnn { n V V V } -\cs_generate_variant:Nn \groupthm_new_theorem:nnnn { x V n n } -\cs_generate_variant:Nn \groupthm_provide_theorem:nnnn { x V n n } -\__groupthm_wrap_multiple:nnn - { new, provide } - { groupthm_#1_theorem:nnn } - { - \__groupthm_set_normalized_keys:nnn { ##1 } { grouped ~ theorem } { ##2 } - \bool_if:nT { ##3 } - { - \clist_put_left:Nn \l__groupthm_group_clist { unnumbered } - } - \use:c { groupthm_#1_theorem:nVVV } - { ##2 } - \l__groupthm_group_clist - \l__groupthm_name_tl - \l__groupthm_thmtools_clist - \bool_if:NT \l__groupthm_starred_version_bool - { - \clist_put_left:Nn \l__groupthm_group_clist { starred } - \use:c { groupthm_#1_theorem:nVVV } - { ##2* } - \l__groupthm_group_clist - \l__groupthm_name_tl - \l__groupthm_thmtools_clist - } - } -\__groupthm_wrap_multiple_document:nnnn - { new, provide } - { \__groupthm_Declarator: GroupedTheorem } - { s O{} m } - { - \use:c { groupthm_#1_theorem:nnn } - { ##2 } - { ##3 } - { ##1 } - } -\cs_new:Npn \__groupthm_define_family:nnnnn #1 #2 #3 #4 #5 - { - \clist_set:Nn \l_tmpa_clist { #2 } - \powerset_clist_foreach:Nn \l_tmpa_clist - { - \clist_set_eq:NN \l__groupthm_group_clist \l_tmpa_clist - \clist_put_right:Nn \l__groupthm_group_clist { #5 } - \__groupthm_sort_group_names: - \use:c{groupthm_new_theorem:xVnn} - {__#1__groups_\clist_use:Nn \l__groupthm_group_clist {_}} - \l__groupthm_group_clist - { #3 } - { #4 } - } - \clist_new:c { __groupthm_family__#1__group_clist } - \clist_set_eq:cN {__groupthm_family__#1__group_clist } \l_tmpa_clist - \clist_new:c { __groupthm_family__#1__always_group_clist } - \clist_set:cn {__groupthm_family__#1__always_group_clist } { #5 } - } -\__groupthm_define_multiple:nnnNNnn - { new, provide } - { theorem ~ family } - { __groupthm_family__##1__group_clist } - \__groupthm_error: - \__groupthm_define_family:nnnnn - { groupthm_#1_family:nnnnn } - { { ##1 } { ##2 } { ##3 } { ##4 } { ##5 }} -\cs_generate_variant:Nn \groupthm_new_family:nnnnn { n V V V V } -\cs_generate_variant:Nn \groupthm_provide_family:nnnnn { n V V V V } -\__groupthm_wrap_multiple:nnn -{ new, provide } -{ groupthm_#1_family:nnn } -{ - \__groupthm_set_normalized_keys:nnn { ##1 } { theorem ~ family } { ##2 } - \bool_if:nTF { ##3} - { - \clist_set:Nn \l_tmpa_clist { unnumbered } - } - { - \clist_clear:N \l_tmpa_clist - } - \bool_if:NT \l__groupthm_starred_version_bool - { - \clist_put_left:Nn \l__groupthm_group_clist { starred } - } - \use:c { groupthm_#1_family:nVVVV } - { ##2 } - \l__groupthm_group_clist - \l__groupthm_name_tl - \l__groupthm_thmtools_clist - \l_tmpa_clist -} -\__groupthm_wrap_multiple_document:nnnn - { new, provide } - { \__groupthm_Declarator: GroupedTheoremFamily } - { s O{} m } - { - \use:c { groupthm_#1_family:nnn } - { ##2 } - { ##3 } - { ##1 } - } -\cs_new:Npn \groupthm_add_theorem_to_group:n #1 - { - \bool_if:NTF \l__groupthm_in_family_options_environment_bool - { - \clist_put_left:Nn \l__groupthm_group_clist { #1 } - } - { - \msg_error:nn { groupthm } { misuse ~ add ~ theorem ~ to ~ group } - } - } - \NewDocumentCommand { \AddTheoremToGroup } { m } - { - \groupthm_add_theorem_to_group:n { #1 } - } -\cs_new:Npn \__groupthm_define_family_options:nnnn #1 #2 #3 #4 - { - \DeclareDocumentEnvironment - { #1 } - { #2 } - { - \clist_clear:N \l__groupthm_group_clist - \bool_set_true:N \l__groupthm_in_family_options_environment_bool - #3 - \bool_set_false:N \l__groupthm_in_family_options_environment_bool - \clist_put_right:Nn \l__groupthm_group_clist { #4 } - \__groupthm_sort_group_names: - \cs_if_exist:cTF { __#1__groups_ \clist_use:Nn \l__groupthm_group_clist { _ } } - { - \begin { __#1__groups_ \clist_use:Nn \l__groupthm_group_clist { _ } } - } - { - \msg_error:nnxx { groupthm } { undefined ~ theorem ~ variant } - { #1 } - { \clist_use:Nnnn \l__groupthm_group_clist { ~ and ~ } {, ~} { , ~ and ~ } } - } - } - { - \clist_clear:N \l__groupthm_group_clist - \bool_set_true:N \l__groupthm_in_family_options_environment_bool - #3 - \bool_set_false:N \l__groupthm_in_family_options_environment_bool - \clist_put_right:Nn \l__groupthm_group_clist { #4 } - \__groupthm_sort_group_names: - \end { __#1__groups_ \clist_use:Nn \l__groupthm_group_clist { _ } } - } - } -\__groupthm_define_multiple:nnnNNnn - { new, renew, provide, declare } - { theorem ~ family ~ options } - { ##1 } - \use_none:n - \__groupthm_define_family_options:nnnn - { groupthm_#1_family_options:nnnn } - { { ##1 } { ##2 } { ##3 } { ##4 } } -\cs_generate_variant:Nn \groupthm_new_family_options:nnnn { n n n V } -\cs_generate_variant:Nn \groupthm_renew_family_options:nnnn { n n n V } -\cs_generate_variant:Nn \groupthm_provide_family_options:nnnn { n n n V } -\cs_generate_variant:Nn \groupthm_declare_family_options:nnnn { n n n V } -\__groupthm_wrap_multiple_document:nnnn - { new, renew, provide, declare } - { \__groupthm_Declarator: GroupedTheoremFamilyOptions } - { s O{} m m m } - { - \keys_set:nn { groupthm / theorem ~ family ~ options } { starred ~ version } - \keys_set:nn { groupthm / theorem ~ family ~ options } { ##2 } - \bool_if:nTF { ##1 } - { - \clist_set:Nn \l_tmpa_clist { unnumbered } - } - { - \clist_clear:N \l_tmpa_clist - } - \use:c { groupthm_#1_family_options:nnnV } - { ##3 } - { ##4 } - { ##5 } - \l_tmpa_clist - \bool_if:NT \l__groupthm_starred_version_bool - { - \use:c { groupthm_#1_family_options:nnnV } - { ##3* } - { ##4 } - { - ##5 - \groupthm_add_theorem_to_group:n { starred } - } - \l_tmpa_clist - } - } -\endinput -%% -%% End of file `groupthm.sty'.