diff options
Diffstat (limited to 'macros/latex/exptl/thmtools/thm-patch.dtx')
-rw-r--r-- | macros/latex/exptl/thmtools/thm-patch.dtx | 252 |
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 |