summaryrefslogtreecommitdiff
path: root/macros/latex/exptl/thmtools/thm-patch.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/exptl/thmtools/thm-patch.dtx')
-rw-r--r--macros/latex/exptl/thmtools/thm-patch.dtx252
1 files changed, 252 insertions, 0 deletions
diff --git a/macros/latex/exptl/thmtools/thm-patch.dtx b/macros/latex/exptl/thmtools/thm-patch.dtx
new file mode 100644
index 0000000000..b1e28b6fe4
--- /dev/null
+++ b/macros/latex/exptl/thmtools/thm-patch.dtx
@@ -0,0 +1,252 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2008 by Ulrich M. Schwarz
+%
+% This file may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License, version 1.3a.
+% The license can be obtained from
+% http://www.latex-project.org/lppl/lppl-1-3a.txt
+%
+% \fi
+%
+%\iffalse (hide this from DocInput)
+%<*patch>
+%\fi
+%
+% This package is maybe not very suitable for the end user. It redefines
+% |\newtheorem| in a way that lets other packages (or the user) add code
+% to the newly-defined theorems, in a reasonably cross-compatible (with
+% the kernel, \pkg{theorem} and \pkg{amsthm}) way.
+%
+% \textbf{Warning:} the new |\newtheorem| is a superset of the allowed
+% syntax. For example, you can give a star and both optional arguments,
+% even though you cannot have an unnumbered theorem that shares a counter
+% and yet has a different reset-regimen. At some point, your command is
+% re-assembled and passed on to the original |\newtheorem|. This might
+% complain, or give you the usual ``Missing |\begin{document}|'' that
+% marks too many arguments in the preamble.
+%
+% \DescribeMacro{\addtotheorem(pre/post)(head/foot)hook}
+% A call to |\addtotheorempreheadhook|\oarg{kind}\marg{code} will
+% insert the code to be executed whenever a kind theorem is opened, before
+% the actual call takes place. (I.e., before the header ``Kind 1.3 (Foo)''
+% is typeset.) There are also posthooks that are executed after this header,
+% and the same for the end of the environment, even though nothing
+% interesting ever happens there. These are useful to put
+% |\begin{shaded}|\dots |\end{shaded}| around your theorems.
+% Note that foothooks are executed LIFO (last addition first) and headhooks
+% are executed FIFO (first addition first). There is a special kind called
+% generic that is called for all theorems. This is the default if no kind
+% is given.
+%
+% The added code may examine |\thmt@thmname| to get the title,
+% |\thmt@envname| to get the environment's name, and |\thmt@optarg| to get
+% the extra optional title, if any.
+%
+%\StopEventually{}
+% \begin{macrocode}
+\RequirePackage{parseargs}
+
+\newif\ifthmt@isstarred
+\newif\ifthmt@hassibling
+\newif\ifthmt@hasparent
+
+\def\thmt@parsetheoremargs#1{%
+ \parse{%
+ {\parseOpt[]{\def\thmt@optarg{##1}}{%
+ \let\thmt@shortoptarg\@empty
+ \let\thmt@optarg\@empty}}%
+ {%
+ \def\thmt@local@preheadhook{}%
+ \def\thmt@local@postheadhook{}%
+ \def\thmt@local@prefoothook{}%
+ \def\thmt@local@postfoothook{}%
+ \thmt@local@preheadhook
+ \csname thmt@#1@preheadhook\endcsname
+ \thmt@generic@preheadhook
+ % change following to \@xa-orgy at some point?
+ % forex, might have keyvals involving commands.
+ %\protected@edef\tmp@args{%
+ % \ifx\@empty\thmt@optarg\else [{\thmt@optarg}]\fi
+ %}%
+ \ifx\@empty\thmt@optarg
+ \def\tmp@args{}%
+ \else
+ \@xa\def\@xa\tmp@args\@xa{\@xa[\@xa{\thmt@optarg}]}%
+ \fi
+ \csname thmt@original@#1\@xa\endcsname\tmp@args
+ %%moved down: \thmt@local@postheadhook
+ %% (give postheadhooks a chance to re-set nameref data)
+ \csname thmt@#1@postheadhook\endcsname
+ \thmt@generic@postheadhook
+ \thmt@local@postheadhook
+%FMi 2019-07-31
+% \let\@parsecmd\@empty
+ \let\@parsecmd\ignorespaces
+%FMi ---
+ }%
+ }%
+}%
+
+\let\thmt@original@newtheorem\newtheorem
+\let\thmt@theoremdefiner\thmt@original@newtheorem
+
+\def\newtheorem{%
+ \thmt@isstarredfalse
+ \thmt@hassiblingfalse
+ \thmt@hasparentfalse
+ \parse{%
+ {\parseFlag*{\thmt@isstarredtrue}{}}%
+ {\parseMand{\def\thmt@envname{##1}}}%
+ {\parseOpt[]{\thmt@hassiblingtrue\def\thmt@sibling{##1}}{}}%
+ {\parseMand{\def\thmt@thmname{##1}}}%
+ {\parseOpt[]{\thmt@hasparenttrue\def\thmt@parent{##1}}{}}%
+ {\let\@parsecmd\thmt@newtheoremiv}%
+ }%
+}
+
+\newcommand\thmt@newtheoremiv{%
+ \thmt@newtheorem@predefinition
+ % whee, now reassemble the whole shebang.
+ \protected@edef\thmt@args{%
+ \@nx\thmt@theoremdefiner%
+ \ifthmt@isstarred *\fi
+ {\thmt@envname}%
+ \ifthmt@hassibling [\thmt@sibling]\fi
+ {\thmt@thmname}%
+ \ifthmt@hasparent [\thmt@parent]\fi
+ }
+ \thmt@args
+ \thmt@newtheorem@postdefinition
+}
+
+\newcommand\thmt@newtheorem@predefinition{}
+\newcommand\thmt@newtheorem@postdefinition{%
+ \let\thmt@theoremdefiner\thmt@original@newtheorem
+}
+
+\g@addto@macro\thmt@newtheorem@predefinition{%
+ \@xa\thmt@providetheoremhooks\@xa{\thmt@envname}%
+}
+\g@addto@macro\thmt@newtheorem@postdefinition{%
+ \@xa\thmt@addtheoremhook\@xa{\thmt@envname}%
+ \ifthmt@isstarred\@namedef{the\thmt@envname}{}\fi
+ \protected@edef\thmt@tmp{%
+ \def\@nx\thmt@envname{\thmt@envname}%
+ \def\@nx\thmt@thmname{\thmt@thmname}%
+ }%
+ \@xa\addtotheorempreheadhook\@xa[\@xa\thmt@envname\@xa]\@xa{%
+ \thmt@tmp
+ }%
+}
+\newcommand\thmt@providetheoremhooks[1]{%
+ \@namedef{thmt@#1@preheadhook}{}%
+ \@namedef{thmt@#1@postheadhook}{}%
+ \@namedef{thmt@#1@prefoothook}{}%
+ \@namedef{thmt@#1@postfoothook}{}%
+ \def\thmt@local@preheadhook{}%
+ \def\thmt@local@postheadhook{}%
+ \def\thmt@local@prefoothook{}%
+ \def\thmt@local@postfoothook{}%
+}
+\newcommand\thmt@addtheoremhook[1]{%
+ % this adds two command calls to the newly-defined theorem.
+ \@xa\let\csname thmt@original@#1\@xa\endcsname
+ \csname#1\endcsname
+ \@xa\renewcommand\csname #1\endcsname{%
+ \thmt@parsetheoremargs{#1}%
+ }%
+ \@xa\let\csname thmt@original@end#1\@xa\endcsname\csname end#1\endcsname
+ \@xa\def\csname end#1\endcsname{%
+ % these need to be in opposite order of headhooks.
+ \csname thmt@generic@prefoothook\endcsname
+ \csname thmt@#1@prefoothook\endcsname
+ \csname thmt@local@prefoothook\endcsname
+ \csname thmt@original@end#1\endcsname
+ \csname thmt@generic@postfoothook\endcsname
+ \csname thmt@#1@postfoothook\endcsname
+ \csname thmt@local@postfoothook\endcsname
+ }%
+}
+\newcommand\thmt@generic@preheadhook{\refstepcounter{thmt@dummyctr}}
+\newcommand\thmt@generic@postheadhook{}
+\newcommand\thmt@generic@prefoothook{}
+\newcommand\thmt@generic@postfoothook{}
+
+\def\thmt@local@preheadhook{}
+\def\thmt@local@postheadhook{}
+\def\thmt@local@prefoothook{}
+\def\thmt@local@postfoothook{}
+
+
+\providecommand\g@prependto@macro[2]{%
+ \begingroup
+ \toks@\@xa{\@xa{#1}{#2}}%
+ \def\tmp@a##1##2{##2##1}%
+ \@xa\@xa\@xa\gdef\@xa\@xa\@xa#1\@xa\@xa\@xa{\@xa\tmp@a\the\toks@}%
+ \endgroup
+}
+
+\newcommand\addtotheorempreheadhook[1][generic]{%
+ \expandafter\g@addto@macro\csname thmt@#1@preheadhook\endcsname%
+}
+\newcommand\addtotheorempostheadhook[1][generic]{%
+ \expandafter\g@addto@macro\csname thmt@#1@postheadhook\endcsname%
+}
+
+\newcommand\addtotheoremprefoothook[1][generic]{%
+ \expandafter\g@prependto@macro\csname thmt@#1@prefoothook\endcsname%
+}
+\newcommand\addtotheorempostfoothook[1][generic]{%
+ \expandafter\g@prependto@macro\csname thmt@#1@postfoothook\endcsname%
+}
+
+% \end{macrocode}
+% Since rev1.16, we add hooks to the proof environment as well, if it exists.
+% If it doesn't exist at this point, we're probably using ntheorem as
+% backend, where it goes through the regular theorem mechanism anyway.
+% \begin{macrocode}
+\ifx\proof\endproof\else% yup, that's a quaint way of doing it :)
+ % FIXME: this assumes proof has the syntax of theorems, which
+ % usually happens to be true (optarg overrides "Proof" string).
+ % FIXME: refactor into thmt@addtheoremhook, but we really don't want to
+ % call the generic-hook...
+ \let\thmt@original@proof=\proof
+ \renewcommand\proof{%
+ \thmt@parseproofargs%
+ }%
+ \def\thmt@parseproofargs{%
+ \parse{%
+ {\parseOpt[]{\def\thmt@optarg{##1}}{\let\thmt@optarg\@empty}}%
+ {%
+ \thmt@proof@preheadhook
+ %\thmt@generic@preheadhook
+ \protected@edef\tmp@args{%
+ \ifx\@empty\thmt@optarg\else [\thmt@optarg]\fi
+ }%
+ \csname thmt@original@proof\@xa\endcsname\tmp@args
+ \thmt@proof@postheadhook
+ %\thmt@generic@postheadhook
+ \let\@parsecmd\@empty
+ }%
+ }%
+ }%
+
+ \let\thmt@original@endproof=\endproof
+ \def\endproof{%
+ % these need to be in opposite order of headhooks.
+ %\csname thmtgeneric@prefoothook\endcsname
+ \thmt@proof@prefoothook
+ \thmt@original@endproof
+ %\csname thmt@generic@postfoothook\endcsname
+ \thmt@proof@postfoothook
+ }%
+ \@namedef{thmt@proof@preheadhook}{}%
+ \@namedef{thmt@proof@postheadhook}{}%
+ \@namedef{thmt@proof@prefoothook}{}%
+ \@namedef{thmt@proof@postfoothook}{}%
+\fi
+% \end{macrocode}
+%\iffalse
+%</patch>
+%\fi