latex-packages/doc/environments/fancythm/fancythm.dtx

558 lines
12 KiB
TeX

% \iffalse meta-comment
%
%% File: fancytm.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
%
% -----------------------------------------------------------------------
%<package>\ProvidesExplPackage{fancythm}{2022/01/17}{0.0.1}{Grouped theorems.}
%
%<*driver>
\documentclass[full,kernel]{l3doc}
\usepackage{mkessler-todo}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
% The \pkg{fancythm} package^^A
% }
%
% \author{^^A
% Maximilian Keßler
% }
%
% \date{Released 2022-01-12}
%
% \maketitle
%
% \begin{documentation}
% \end{documentation}
%
%
% \begin{implementation}
%
% \section{\pkg{fancythm} implementation}
%
% \begin{macrocode}
%<*package>
% \end{macrocode}
%
% \begin{macrocode}
%<@@=fancythm>
% \end{macrocode}
%
%
% \subsection{Dependencies}
% \begin{macrocode}
\RequirePackage{l3keys2e}
\RequirePackage{groupthm}
\RequirePackage[default styles]{mkessler-thmstyle}
% \end{macrocode}
%
% \subsection{Counter management}
%
%
% Wrappers for \LaTeX2e counter manipulation
%
%
% \begin{macro}{\arabic:n, \counter_new:n, \counter_within:nn,\counter_new:nn}
%
% Obvious meanings.
%
% \begin{macrocode}
\cs_set_eq:NN \arabic:n \arabic
\cs_set_eq:NN \counter_new:n \newcounter
\cs_set_eq:NN \counter_within:nn \counterwithin
\cs_new:Npn \counter_new:nn #1 #2
{
\counter_new:n { #1 }
\counter_within:nn { #1 } { #2 }
}
% \end{macrocode}
% \end{macro}
%
%
%
%
% \begin{macro}
% {
% \counter_if_exist_p:n,
% \counter_if_exist:nT,
% \counter_if_exist:F,
% \counter_if_exist:nTF,
% }
%
%
%
% \begin{macrocode}
\cs_new:Npn \counter_if_exist_p:n #1
{
\cs_if_exist_p:c { c@ #1 }
}
\cs_new:Npn \counter_if_exist:nT #1
{
\cs_if_exist:cT { c@ #1 }
}
\cs_new:Npn \counter_if_exist:nF #1
{
\cs_if_exist:cF { c@ #1 }
}
\cs_new:Npn \counter_if_exist:nTF #1
{
\cs_if_exist:cTF { c@ #1 }
}
% \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\counter_undefined_error:n}
%
% Standard counter error message.
%
% \begin{macrocode}
\cs_set_eq:Nc \counter_undefined_error:n { @nocounterr }
% \end{macrocode}
% \end{macro}
%
%
%
%
% \begin{macro}{\counter_ensure_exist:n}
%
%
%
% \begin{macrocode}
\cs_new:Npn \counter_ensure_exist:n #1
{
\counter_if_exist:nF { #1 }
{
\counter_undefined_error:n { #1 }
}
}
% \end{macrocode}
% \end{macro}
%
%
%
%
%
% \begin{macro}{\counter_the:n, \counter_set_the:nn}
%
%
% \begin{macrocode}
\cs_new:Npn \counter_the:n #1
{
\use:c { the #1 }
}
\cs_new:Npn \counter_set_the:nn #1 #2
{
\counter_ensure_exist:n { #1 }
\exp_args:Nc \renewcommand { the #1 } { #2 }
}
% \end{macrocode}
% \end{macro}
%
%
%
%
% \begin{macro}{\counter_sub:nn}
% \begin{syntax}
% \cs{counter_sub:nn}\marg{counter_1}\marg{counter_2}
% \end{syntax}
%
%
%
% \begin{macrocode}
\cs_new:Npn \counter_sub:nn #1 #2
{
\counter_within:nn { #1 } { #2 }
\counter_set_the:nn { #1 }
{
\counter_the:n { #2 } . \arabic:n { #1 }
}
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\counter_new_sub:nn #1 #2}
%
%
%
% \begin{macrocode}
\cs_new:Npn \counter_new_sub:nn #1 #2
{
\counter_new:n { #1 }
\counter_sub:nn { #1 } { #2 }
}
% \end{macrocode}
% \end{macro}
%
% \subsection{Counter management}
%
%
%
% \begin{macro}{\@@_counter_sub_if_exist:n}
%
%
%
% \begin{macrocode}
\cs_new:Npn \@@_counter_sub_if_exist:n #1
{
\counter_if_exist:nT { #1 }
{
\counter_new_sub:nn { in #1 } { #1 }
}
}
% \end{macrocode}
% \end{macro}
%
%
%
%
%
%
% \begin{macro}{\counter_alias:nn, \counter_alias:nx}
% \begin{syntax}
% \cs{counter_alias:nn}\marg{counter_1}\marg{counter_2}
% \end{syntax}
%
%
%
% \begin{macrocode}
\cs_set_eq:Nc \counter_alias:nn { @counteralias }
\cs_generate_variant:Nn \counter_alias:nn { n x }
% \end{macrocode}
% \end{macro}
%
%
%
%
%
%
% \subsection{Initialization}
%
%
%
% \begin{variable}{indocument, insection, insubsection, inchapter, inpart}
%
%
%
% \begin{macrocode}
\counter_new:n { indocument }
\@@_counter_sub_if_exist:n { section }
\@@_counter_sub_if_exist:n { subsection }
\@@_counter_sub_if_exist:n { chapter }
\@@_counter_sub_if_exist:n { part }
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{toplevel, sublevel, subsublevel, subsubsublevel}
%
% Note that the \texttt{toplevel} counter will be potentially redefined
% by the given package options.
%
% \begin{macrocode}
\counter_alias:nn { toplevel } { indocument }
\counter_new_sub:nn { sublevel } { toplevel }
\counter_new_sub:nn { subsublevel } { sublevel }
\counter_new_sub:nn { subsubsublevel } { subsublevel }
% \end{macrocode}
% \end{variable}
%
%
% \begin{variable}{\g_@@_style_str}
%
% This will hold the style information of the package.
%
% \begin{macrocode}
\str_new:N \g_@@_style_str
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_translator_bool}
%
%
%
% \begin{macrocode}
\bool_new:N \g_@@_translator_bool
% \end{macrocode}
% \end{variable}
%
%
% \begin{variable}{\g_@@_generate_defaults_bool}
%
%
%
% \begin{macrocode}
\bool_new:N \g_@@_generate_defaults_bool
% \end{macrocode}
% \end{variable}
%
%
%
%
% \begin{variable}
% {
% \l_@@_key_name_tl,
% \l_@@_key_mdframed_tl,
% \l_@@_key_style_tl,
% \l_@@_key_group_clist,
% \l_@@_key_thmtools_clist,
% }
%
%
% \begin{macrocode}
\tl_new:N \l_@@_key_name_tl
\tl_new:N \l_@@_key_mdframed_tl
\tl_new:N \l_@@_key_style_tl
\clist_new:N \l_@@_key_group_clist
\clist_new:N \l_@@_key_thmtools_clist
% \end{macrocode}
% \end{variable}
%
%
%
% \begin{variable}
% {
% \l_@@_name_tl,
% \l_@@_thmtools_clist,
% \l_@@_group_clist,
% }
%
%
% \begin{macrocode}
\tl_new:N \l_@@_name_tl
\clist_new:N \l_@@_thmtools_clist
\clist_new:N \l_@@_group_clist
% \end{macrocode}
% \end{variable}
%
% \subsection{Key interface}
%
% \begin{texnote}
% Note that unfortunately, none of the keynames really containes a space.
% \LaTeX2e strips spaces before loading a package, so introducing them here
% would make them inaccessible.
% Here they are ignored by \LaTeX3 and are present for readability.
% \end{texnote}
%
%
% \begin{macrocode}
\keys_define:nn { fancythm }
{
translator .bool_set:N = \g_@@_translator_bool ,
translator .default:n = { true } ,
generate defaults .bool_set:N = \g_@@_generate_defaults_bool ,
generate defaults .default:n = { true } ,
number in .choices:nn =
{ document, section, subsection, chapter, part }
{
\counter_alias:nx { toplevel } { in \tl_use:N \l_keys_choice_tl }
} ,
number in .default:n = { document } ,
style .choices:nn =
{ fancy, plain, classic }
{
\str_set:Nn \g_@@_style_str { \tl_use:N \l_keys_choice_tl }
} ,
style .default:n = { fancy } ,
}
% \end{macrocode}
%
%
%
%
%
%
% \begin{macrocode}
\keys_define:nn { fancythm / fancytheorem }
{
name .tl_set:N = \l_@@_key_name_tl ,
name .default:n = \c_novalue_tl ,
mdframed .tl_set:N = \l_@@_key_mdframed_tl ,
mdframed .default:n = \c_novalue_tl ,
style .tl_set:N = \l_@@_key_style_tl ,
style .default:n = \c_novalue_tl ,
group .clist_set:N = \l_@@_key_group_clist ,
group .default:n = {} ,
thmtools .clist_set:N = \l_@@_key_thmtools_clist ,
thmtools .default:n = {} ,
}
% \end{macrocode}
%
%
% Process the given keys:
%
% \begin{macrocode}
\ProcessKeysOptions{ fancythm }
% \end{macrocode}
%
%
%
%
% This sets up translation if requested.
% Throughout implementation, we can just use \cs{@@_translate:n}
% and will (or not) have translation according to the specified options.
%
% \begin{macrocode}
\bool_if:NTF \g_@@_translator_bool
{
\RequirePackage{translator}
\usedictionary{translator-environment-names}
\cs_set_eq:NN \@@_translate:n \translate
}
{
\cs_set_eq:NN \@@_translate:n \use:n
}
% \end{macrocode}
%
%
%
%
% \begin{macro}{\@@_set_normalized_keys:nn}
%
% \begin{syntax}
% \cs{@@_set_normalized_keys:nn}\marg{keys}\marg{fallback name}
% \end{syntax}
%
%
% \begin{macrocode}
\cs_new:Npn \@@_set_normalized_keys:nn #1 #2
{
\keys_set:nn { fancythm / fancytheorem } { name, mdframed, style, group, thmtools }
\keys_set:nn { fancythm / fancytheorem } { #1 }
\clist_set_eq:NN \l_@@_group_clist \l_@@_key_group_clist
\clist_set_eq:NN \l_@@_thmtools_clist \l_@@_key_thmtools_clist
\tl_if_eq:NnF \l_@@_key_mdframed_tl { \c_novalue_tl }
{
\clist_put_right:Nx \l_@@_thmtools_clist
{
mdframed = { style = \tl_use:N \l_@@_key_mdframed_tl }
}
}
\tl_if_eq:NnF \l_@@_key_style_tl { \c_novalue_tl }
{
\clist_put_right:Nx \l_@@_thmtools_clist
{
style = \tl_use:N \l_@@_key_style_tl
}
}
\tl_if_eq:NnTF \l_@@_key_name_tl { \c_novalue_tl }
{
\tl_set:Nx \l_@@_name_tl
{
\text_titlecase_first:n { \tl_trim_spaces:n { #2 } }
}
}
{
\tl_set_eq:NN \l_@@_name_tl \l_@@_key_name_tl
}
}
% \end{macrocode}
% \end{macro}
%
%
%
%
% \begin{macro}{\fancythm_new_theorem:nnnn}
% \begin{syntax}
% \cs{fancythm_new_theorem:nnnn}\marg{fancy theorem}\marg{groups}
% \marg{name}\marg{thmtools keys}
% \end{syntax}
%
%
%
% \begin{macrocode}
\cs_new:Npn \fancythm_new_theorem:nnnn #1 #2 #3 #4
{
% \tl_show:n { new ~ fancy ~ theorem ~ with ~ 1 = '#1', ~ 2='#2', ~ 3='#3', 4='#4'}
\groupthm_new_family:nnnnn { #1 } { dagger, star } { #3 } { #4 } { #2 }
\groupthm_new_family_options:nnnn
{ #1 }
{ !s !t+ }
{
\IfBooleanT { ##1 }
{
\groupthm_add_theorem_to_group:n { star }
}
\IfBooleanT { ##2 }
{
\groupthm_add_theorem_to_group:n { dagger }
}
}
{ #2 }
}
\cs_generate_variant:Nn \fancythm_new_theorem:nnnn { n V V V }
% \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\fancythm_new_theorem:nn}
% \begin{syntax}
% \cs{fanythm_new_theorem:nn}\marg{key=value list}\marg{fancy theorem}
% \end{syntax}
%
%
%
% \begin{macrocode}
\cs_new:Npn \fancythm_new_theorem:nn #1 #2
{
\@@_set_normalized_keys:nn { #1 } { #2 }
\fancythm_new_theorem:nVVV
{ #2 }
\l_@@_group_clist
\l_@@_name_tl
\l_@@_thmtools_clist
}
% \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\NewFancyTheorem}
% \begin{syntax}
% \cs{NewFancyTheorem}\marg{key=value list}\marg{fancy theorem}
% \end{syntax}
%
%
%
% \begin{macrocode}
\NewDocumentCommand { \NewFancyTheorem } { O{} m }
{
\fancythm_new_theorem:nn { #1 } { #2 }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%
% \end{macrocode}
%
%
%
% \begin{macrocode}
%</package>
% \end{macrocode}
%
% \end{implementation}
%
%
%
% \newpage