diff options
author | Norbert Preining <norbert@preining.info> | 2020-07-18 03:01:08 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2020-07-18 03:01:08 +0000 |
commit | 63c4f21a5716ebbed11926d0bfbb26d656a766ea (patch) | |
tree | c02159e6ceb2453208664129ccda8ff306147328 /macros/latex/contrib/thmtools/source | |
parent | 4ea983e3d411ade406c09b30ece9139457516b6f (diff) |
CTAN sync 202007180301
Diffstat (limited to 'macros/latex/contrib/thmtools/source')
17 files changed, 2613 insertions, 0 deletions
diff --git a/macros/latex/contrib/thmtools/source/aliasctr.dtx b/macros/latex/contrib/thmtools/source/aliasctr.dtx new file mode 100644 index 0000000000..3c75e11c98 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/aliasctr.dtx @@ -0,0 +1,117 @@ +% \iffalse meta-comment +% +% Copyright (C) 2005-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +%<*code> +% \fi +% |\@counteralias{#1}{#2}| makes |#1| a counter that uses |#2|'s count register. +% This is useful for things like \pkg{hyperref}'s |\autoref|, which otherwise +% can't distinguish theorems and definitions if they share a counter. +% +% For detailed information, see Die TeXnische Kom\"odie 3/2006. +% \StopEventually{} +% \begin{macro}{\@addtoreset} +% add |\@elt{#1}| to |\cl@#2|. +% This differs from the kernel implementation insofar as we trail the +% cl lists until we find one that is empty or starts with |\@elt|. +% \begin{macrocode} +\def\aliasctr@f@llow#1#2\@nil#3{% + \ifx#1\@elt + \noexpand #3% + \else + \expandafter\aliasctr@f@llow#1\@elt\@nil{#1}% + \fi +} +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\aliasctr@follow[1]{% + \expandafter\aliasctr@f@llow +% \end{macrocode} +% Don't be confused: the third parameter is ignored here, we always +% have recursion here since the \emph{token} |\cl@#1| is (hopefully) not |\@elt|. +% \begin{macrocode} + \csname cl@#1\endcsname\@elt\@nil{\csname cl@#1\endcsname}% +} +% \end{macrocode} +% +% \begin{macrocode} +\renewcommand*\@addtoreset[2]{\bgroup + \edef\aliasctr@@truelist{\aliasctr@follow{#2}}% + \let\@elt\relax + \expandafter\@cons\aliasctr@@truelist{{#1}}% +\egroup} +% \end{macrocode} +% +% This code has been adapted from David Carlisle's \pkg{remreset}. We +% load that here only to prevent it from being loaded again. +% \begin{macrocode} +% FMi 2019-07-31 \@removereset is in the kernel these days +\@ifundefined{@removefromreset}{\RequirePackage{remreset}}{} +\renewcommand*\@removefromreset[2]{\bgroup + \edef\aliasctr@@truelist{\aliasctr@follow{#2}}% + \expandafter\let\csname c@#1\endcsname\@removefromreset + \def\@elt##1{% + \expandafter\ifx\csname c@##1\endcsname\@removefromreset + \else + \noexpand\@elt{##1}% + \fi}% + \expandafter\xdef\aliasctr@@truelist{% + \aliasctr@@truelist} +\egroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@counteralias} +% make |#1| a counter that uses counter |#2|'s count register. +% \begin{macrocode} +\newcommand\@counteralias[2]{{% + \def\@@gletover##1##2{% + \expandafter\global + \expandafter\let\csname ##1\expandafter\endcsname + \csname ##2\endcsname + }% + \@ifundefined{c@#2}{\@nocounterr{#2}}{% + \@ifdefinable{c@#1}{% +% \end{macrocode} +% Four values make a counter foo: +% \begin{itemize} +% \item the count register accessed through |\c@foo|, +% \item the output macro |\thefoo|, +% \item the prefix macro |\p@foo|, +% \item the reset list |\cl@foo|. +% \end{itemize} +% \pkg{hyperref} adds |\theHfoo| in particular. +% \begin{macrocode} + \@@gletover{c@#1}{c@#2}% + \@@gletover{the#1}{the#2}% +% \end{macrocode} +% I don't see \@counteralias being called hundreds of times, +% let's just unconditionally create |\theHctr|-macros for hyperref. +% \begin{macrocode} + \@@gletover{theH#1}{theH#2}% + \@@gletover{p@#1}{p@#2}% + \expandafter\global + \expandafter\def\csname cl@#1\expandafter\endcsname + \expandafter{\csname cl@#2\endcsname}% +% \end{macrocode} +% It is not necessary to save the value again: since we share a +% count register, we will pick up the restored value of the +% original counter. +% \begin{macrocode} + %\@addtoreset{#1}{@ckpt}% + }% + }% +}} +% \end{macrocode} +% \end{macro} +%\iffalse +%</code> +%\fi diff --git a/macros/latex/contrib/thmtools/source/parseargs.dtx b/macros/latex/contrib/thmtools/source/parseargs.dtx new file mode 100644 index 0000000000..4efcd3ecd9 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/parseargs.dtx @@ -0,0 +1,82 @@ +% \iffalse meta-comment +% +% Copyright (C) 2008-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +% \fi +% +%\iffalse (hide this from DocInput) +%<*parseargs> +%\fi +% +% The main command provided by the package is |\parse|\marg{spec}. +% \emph{spec} consists of groups of commands. Each group should set up the +% command |\@parsecmd| which is then run. The important point is that +% |\@parsecmd| will pick up its arguments from the running text, not from +% the rest of \emph{spec}. When it's done storing the arguments, +% |\@parsecmd| must call |\@parse| to continue with the next element of +% \emph{spec}. The process terminates when we run out of spec. +% +% Helper macros are provided for the three usual argument types: mandatory, +% optional, and flag. +% +%\StopEventually{} +% \begin{macrocode} + +\newtoks\@parsespec +\def\parse@endquark{\parse@endquark} +\newcommand\parse[1]{% + \@parsespec{#1\parse@endquark}\@parse} + +\newcommand\@parse{% + \edef\p@tmp{\the\@parsespec}% + \ifx\p@tmp\parse@endquark + \expandafter\@gobble + \else +% \typeout{parsespec remaining: \the\@parsespec}% + \expandafter\@firstofone + \fi{% + \@parsepop + }% +} +\def\@parsepop{% + \expandafter\p@rsepop\the\@parsespec\@nil + \@parsecmd +} +\def\p@rsepop#1#2\@nil{% + #1% + \@parsespec{#2}% +} + +\newcommand\parseOpt[4]{% + %\parseOpt{openchar}{closechar}{yes}{no} +% \typeout{attemping #1#2...}% + \def\@parsecmd{% + \@ifnextchar#1{\@@reallyparse}{#4\@parse}% + }% + \def\@@reallyparse#1##1#2{% + #3\@parse + }% +} + +\newcommand\parseMand[1]{% + %\parseMand{code} + \def\@parsecmd##1{#1\@parse}% +} + +\newcommand\parseFlag[3]{% + %\parseFlag{flagchar}{yes}{no} + \def\@parsecmd{% + \@ifnextchar#1{#2\expandafter\@parse\@gobble}{#3\@parse}% + }% +} +% \end{macrocode} +%\iffalse +%</parseargs> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thm-amsthm.dtx b/macros/latex/contrib/thmtools/source/thm-amsthm.dtx new file mode 100644 index 0000000000..b45a6c276e --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thm-amsthm.dtx @@ -0,0 +1,169 @@ +% \iffalse meta-comment +% +% Copyright (C) 2010-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +%\fi +% +%\iffalse (hide this from DocInput) +%<*amsthm> +%\fi +% \begin{macrocode} +\providecommand\thmt@space{ } + +\define@key{thmstyle}{spaceabove}{% + \def\thmt@style@spaceabove{#1}% +} +\define@key{thmstyle}{spacebelow}{% + \def\thmt@style@spacebelow{#1}% +} +\define@key{thmstyle}{headfont}{% + \def\thmt@style@headfont{#1}% +} +\define@key{thmstyle}{bodyfont}{% + \def\thmt@style@bodyfont{#1}% +} +\define@key{thmstyle}{notefont}{% + \def\thmt@style@notefont{#1}% +} +\define@key{thmstyle}{headpunct}{% + \def\thmt@style@headpunct{#1}% +} +\define@key{thmstyle}{notebraces}{% + \def\thmt@style@notebraces{\thmt@embrace#1}% +} +\define@key{thmstyle}{break}[]{% + \def\thmt@style@postheadspace{\newline}% +} +\define@key{thmstyle}{postheadspace}{% + \def\thmt@style@postheadspace{#1}% +} +\define@key{thmstyle}{headindent}{% + \def\thmt@style@headindent{#1}% +} + +\newtoks\thmt@style@headstyle +\define@key{thmstyle}{headformat}[]{% + \thmt@setheadstyle{#1}% +} +\define@key{thmstyle}{headstyle}[]{% + \thmt@setheadstyle{#1}% +} +\def\thmt@setheadstyle#1{% + \thmt@style@headstyle{% + \def\NAME{\the\thm@headfont ##1}% + \def\NUMBER{\bgroup\@upn{##2}\egroup}% + \def\NOTE{\if=##3=\else\bgroup\thmt@space\the\thm@notefont(##3)\egroup\fi}% + }% + \def\thmt@tmp{#1}% + \@onelevel@sanitize\thmt@tmp + %\tracingall + \ifcsname thmt@headstyle@\thmt@tmp\endcsname + \thmt@style@headstyle\@xa{% + \the\thmt@style@headstyle + \csname thmt@headstyle@#1\endcsname + }% + \else + \thmt@style@headstyle\@xa{% + \the\thmt@style@headstyle + #1% + }% + \fi + %\showthe\thmt@style@headstyle +} +% examples: +\def\thmt@headstyle@margin{% + \makebox[0pt][r]{\NUMBER\ }\NAME\NOTE +} +\def\thmt@headstyle@swapnumber{% + \NUMBER\ \NAME\NOTE +} + + + +\def\thmt@embrace#1#2(#3){#1#3#2} + +\def\thmt@declaretheoremstyle@setup{% + \let\thmt@style@notebraces\@empty% + \thmt@style@headstyle{}% + \kvsetkeys{thmstyle}{% + spaceabove=3pt, + spacebelow=3pt, + headfont=\bfseries, + bodyfont=\normalfont, + headpunct={.}, + postheadspace={ }, + headindent={}, + notefont={\fontseries\mddefault\upshape} + }% +} +\def\thmt@declaretheoremstyle#1{% + %\show\thmt@style@spaceabove + \thmt@toks{\newtheoremstyle{#1}}% + \thmt@toks\@xa\@xa\@xa{\@xa\the\@xa\thmt@toks\@xa{\thmt@style@spaceabove}}% + \thmt@toks\@xa\@xa\@xa{\@xa\the\@xa\thmt@toks\@xa{\thmt@style@spacebelow}}% + \thmt@toks\@xa\@xa\@xa{\@xa\the\@xa\thmt@toks\@xa{\thmt@style@bodyfont}}% + \thmt@toks\@xa\@xa\@xa{\@xa\the\@xa\thmt@toks\@xa{\thmt@style@headindent}}% indent1 FIXME + \thmt@toks\@xa\@xa\@xa{\@xa\the\@xa\thmt@toks\@xa{\thmt@style@headfont}}% + \thmt@toks\@xa\@xa\@xa{\@xa\the\@xa\thmt@toks\@xa{\thmt@style@headpunct}}% + \thmt@toks\@xa\@xa\@xa{\@xa\the\@xa\thmt@toks\@xa{\thmt@style@postheadspace}}% + \thmt@toks\@xa\@xa\@xa{\@xa\the\@xa\thmt@toks\@xa{\the\thmt@style@headstyle}}% headspec FIXME + \the\thmt@toks + %1 Indent amount: empty = no indent, \parindent = normal paragraph indent + %2 Space after theorem head: { } = normal interword space; \newline = linebreak + %% BUGFIX: amsthm ignores notefont setting altogether: + \thmt@toks\@xa\@xa\@xa{\csname th@#1\endcsname}% + \thmt@toks + \@xa\@xa\@xa\@xa\@xa\@xa\@xa{% + \@xa\@xa\@xa\@xa\@xa\@xa\@xa\thm@notefont + \@xa\@xa\@xa\@xa\@xa\@xa\@xa{% + \@xa\@xa\@xa\thmt@style@notefont + \@xa\thmt@style@notebraces + \@xa}\the\thmt@toks}% + \@xa\def\csname th@#1\@xa\endcsname\@xa{\the\thmt@toks}% +% \@xa\def\csname th@#1\@xa\@xa\@xa\@xa\@xa\@xa\@xa\endcsname +% \@xa\@xa\@xa\@xa\@xa\@xa\@xa{% +% \@xa\@xa\@xa\@xa\@xa\@xa\@xa\thm@notefont +% \@xa\@xa\@xa\@xa\@xa\@xa\@xa{% +% \@xa\@xa\@xa\thmt@style@notefont +% \@xa\@xa\@xa\thmt@style@notebraces +% \@xa\@xa\@xa}\csname th@#1\endcsname +% } +} + +\define@key{thmdef}{qed}[\qedsymbol]{% + \thmt@trytwice{}{% + \addtotheorempostheadhook[\thmt@envname]{% + \protected@edef\qedsymbol{#1}% + \pushQED{\qed}% + }% + \addtotheoremprefoothook[\thmt@envname]{% + \protected@edef\qedsymbol{#1}% + \popQED + }% + }% +} + +\def\thmt@amsthmlistbreakhack{% + \leavevmode + \vspace{-\baselineskip}% + \par + \everypar{\setbox\z@\lastbox\everypar{}}% +} + +\define@key{thmuse}{listhack}[\relax]{% + \addtotheorempostheadhook[local]{% + \thmt@amsthmlistbreakhack + }% +} + +% \end{macrocode} +%\iffalse (hide this from DocInput) +%</amsthm> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thm-autoref.dtx b/macros/latex/contrib/thmtools/source/thm-autoref.dtx new file mode 100644 index 0000000000..cf84463c09 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thm-autoref.dtx @@ -0,0 +1,121 @@ +% \iffalse meta-comment +% +% Copyright (C) 2008-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +% \fi +% +%\iffalse (hide this from DocInput) +%<*autoref> +%\fi +% +% \pkg{hyperref}'s |\autoref| command does not work well with theorems that +% share a counter: it'll always think it's a Lemma even if it's a Remark +% that shares the Lemma counter. Load this package to fix it. No further +% intervention needed. +% +%\StopEventually{} +% \begin{macrocode} + +\RequirePackage{thm-patch, aliasctr, parseargs, keyval} + +\let\@xa=\expandafter +\let\@nx=\noexpand + +\newcommand\thmt@autorefsetup{% + \@xa\def\csname\thmt@envname autorefname\@xa\endcsname\@xa{\thmt@thmname}% + \ifthmt@hassibling + \@counteralias{\thmt@envname}{\thmt@sibling}% + \@xa\def\@xa\thmt@autoreffix\@xa{% + \@xa\let\csname the\thmt@envname\@xa\endcsname + \csname the\thmt@sibling\endcsname + \def\thmt@autoreffix{}% + }% + \protected@edef\thmt@sibling{\thmt@envname}% + \fi +} +\g@addto@macro\thmt@newtheorem@predefinition{\thmt@autorefsetup}% +\g@addto@macro\thmt@newtheorem@postdefinition{\csname thmt@autoreffix\endcsname}% + +\def\thmt@refnamewithcomma #1#2#3,#4,#5\@nil{% + \@xa\def\csname\thmt@envname #1utorefname\endcsname{#3}% + \ifcsname #2refname\endcsname + \csname #2refname\@xa\endcsname\@xa{\thmt@envname}{#3}{#4}% + \fi +} +\define@key{thmdef}{refname}{\thmt@trytwice{}{% + \thmt@refnamewithcomma{a}{c}#1,\textbf{?? (pl. #1)},\@nil +}} +\define@key{thmdef}{Refname}{\thmt@trytwice{}{% + \thmt@refnamewithcomma{A}{C}#1,\textbf{?? (pl. #1)},\@nil +}} + + +\ifcsname Autoref\endcsname\else +\let\thmt@HyRef@testreftype\HyRef@testreftype +\def\HyRef@Testreftype#1.#2\\{% + \ltx@IfUndefined{#1Autorefname}{% + \thmt@HyRef@testreftype#1.#2\\% + }{% + \edef\HyRef@currentHtag{% + \expandafter\noexpand\csname#1Autorefname\endcsname + \noexpand~% + }% + }% +} + + +\let\thmt@HyPsd@@autorefname\HyPsd@@autorefname +\def\HyPsd@@Autorefname#1.#2\@nil{% + \tracingall + \ltx@IfUndefined{#1Autorefname}{% + \thmt@HyPsd@@autorefname#1.#2\@nil + }{% + \csname#1Autorefname\endcsname\space + }% +}% +\def\Autoref{% + \parse{% + {\parseFlag*{\def\thmt@autorefstar{*}}{\let\thmt@autorefstar\@empty}}% + {\parseMand{% + \bgroup + \let\HyRef@testreftype\HyRef@Testreftype + \let\HyPsd@@autorefname\HyPsd@@Autorefname + \@xa\autoref\thmt@autorefstar{##1}% + \egroup + \let\@parsecmd\@empty + }}% + }% +} +\fi % ifcsname Autoref + +% not entirely appropriate here, but close enough: +\AtBeginDocument{% + \@ifpackageloaded{nameref}{% + \addtotheorempostheadhook{% + \expandafter\NR@gettitle\expandafter{\thmt@shortoptarg}% + }}{} +} + +\AtBeginDocument{% + \@ifpackageloaded{cleveref}{% + \@ifpackagelater{cleveref}{2010/04/30}{% + % OK, new enough + }{% + \PackageWarningNoLine{thmtools}{% + Your version of cleveref is too old!\MessageBreak + Update to version 0.16.1 or later% + } + } + }{} +} +% \end{macrocode} +%\iffalse +%</autoref> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thm-beamer.dtx b/macros/latex/contrib/thmtools/source/thm-beamer.dtx new file mode 100644 index 0000000000..44319480c7 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thm-beamer.dtx @@ -0,0 +1,51 @@ +% \iffalse meta-comment +% +% Copyright (C) 2010-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +%\fi +% +%\iffalse (hide this from DocInput) +%<*beamer> +%\fi +% \begin{macrocode} +\newif\ifthmt@hasoverlay +\def\thmt@parsetheoremargs#1{% + \parse{% + {\parseOpt<>{\thmt@hasoverlaytrue\def\thmt@overlay{##1}}{}}% + {\parseOpt[]{\def\thmt@optarg{##1}}{% + \let\thmt@shortoptarg\@empty + \let\thmt@optarg\@empty}}% + {\ifthmt@hasoverlay\expandafter\@gobble\else\expandafter\@firstofone\fi + {\parseOpt<>{\thmt@hasoverlaytrue\def\thmt@overlay{##1}}{}}% + }% + {% + \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 + \protected@edef\tmp@args{% + \ifthmt@hasoverlay <\thmt@overlay>\fi + \ifx\@empty\thmt@optarg\else [{\thmt@optarg}]\fi + }% + \csname thmt@original@#1\@xa\endcsname\tmp@args + \thmt@local@postheadhook + \csname thmt@#1@postheadhook\endcsname + \thmt@generic@postheadhook + \let\@parsecmd\@empty + }% + } +}% +% \end{macrocode} +%\iffalse (hide this from DocInput) +%</beamer> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thm-kv.dtx b/macros/latex/contrib/thmtools/source/thm-kv.dtx new file mode 100644 index 0000000000..bdac30899d --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thm-kv.dtx @@ -0,0 +1,489 @@ +% \iffalse meta-comment +% +% Copyright (C) 2008-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +% \fi +% +%\iffalse (hide this from DocInput) +%<*kv> +%\fi +% +%\StopEventually{} +% \begin{macrocode} + +\let\@xa\expandafter +\let\@nx\noexpand + +\DeclareOption{lowercase}{% + \PackageInfo{thm-kv}{Theorem names will be lowercased}% + \global\let\thmt@modifycase\MakeLowercase} + +\DeclareOption{uppercase}{% + \PackageInfo{thm-kv}{Theorem names will be uppercased}% + \global\let\thmt@modifycase\MakeUppercase} + +\DeclareOption{anycase}{% + \PackageInfo{thm-kv}{Theorem names will be unchanged}% + \global\let\thmt@modifycase\@empty} + +\ExecuteOptions{uppercase} +\ProcessOptions\relax + +\RequirePackage{keyval,kvsetkeys,thm-patch} + +\long\def\thmt@kv@processor@default#1#2#3{% + \def\kvsu@fam{#1}% new + \@onelevel@sanitize\kvsu@fam% new + \def\kvsu@key{#2}% new + \@onelevel@sanitize\kvsu@key% new + \unless\ifcsname KV@#1@\kvsu@key\endcsname + \unless\ifcsname KVS@#1@handler\endcsname + \kv@error@unknownkey{#1}{\kvsu@key}% + \else + \csname KVS@#1@handler\endcsname{#2}{#3}% + % still using #2 #3 here is intentional: handler might + % be used for strange stuff like implementing key names + % that contain strange characters or other strange things. + \relax + \fi + \else + \ifx\kv@value\relax + \unless\ifcsname KV@#1@\kvsu@key @default\endcsname + \kv@error@novalue{#1}{\kvsu@key}% + \else + \csname KV@#1@\kvsu@key @default\endcsname + \relax + \fi + \else + \csname KV@#1@\kvsu@key\endcsname{#3}% + \fi + \fi +} + +\@ifpackagelater{kvsetkeys}{2012/04/23}{% + \PackageInfo{thm-kv}{kvsetkeys patch (v1.16 or later)}% + \long\def\tmp@KVS@PD#1#2#3{% + \def \kv@fam {#1}% + \unless \ifcsname KV@#1@#2\endcsname + \unless \ifcsname KVS@#1@handler\endcsname + \kv@error@unknownkey {#1}{#2}% + \else + \kv@handled@true + \csname KVS@#1@handler\endcsname {#2}{#3}\relax + \ifkv@handled@ \else + \kv@error@unknownkey {#1}{#2}% + \fi + \fi + \else + \ifx \kv@value \relax + \unless \ifcsname KV@#1@#2@default\endcsname + \kv@error@novalue {#1}{#2}% + \else + \csname KV@#1@#2@default\endcsname \relax + \fi + \else + \csname KV@#1@#2\endcsname {#3}% + \fi + \fi + }% + \ifx\tmp@KVS@PD\KVS@ProcessorDefault + \let\KVS@ProcessorDefault\thmt@kv@processor@default + \def\kv@processor@default#1#2{% + \begingroup + \csname @safe@activestrue\endcsname + \@xa\let\csname ifincsname\@xa\endcsname\csname iftrue\endcsname + \edef\KVS@temp{\endgroup +% 2019/12/22 removed dependency on etexcmds package + \noexpand\KVS@ProcessorDefault{#1}{\unexpanded{#2}}% + }% + \KVS@temp + }% + \else + \PackageError{thm-kv}{kvsetkeys patch failed}{Try kvsetkeys v1.16 or earlier} + \fi +}{\@ifpackagelater{kvsetkeys}{2011/04/06}{% + % Patch has disappeared somewhere... thanksalot. + \PackageInfo{thm-kv}{kvsetkeys patch (v1.13 or later)} + \long\def\tmp@KVS@PD#1#2#3{% no non-etex-support here... + \unless\ifcsname KV@#1@#2\endcsname + \unless\ifcsname KVS@#1@handler\endcsname + \kv@error@unknownkey{#1}{#2}% + \else + \csname KVS@#1@handler\endcsname{#2}{#3}% + \relax + \fi + \else + \ifx\kv@value\relax + \unless\ifcsname KV@#1@#2@default\endcsname + \kv@error@novalue{#1}{#2}% + \else + \csname KV@#1@#2@default\endcsname + \relax + \fi + \else + \csname KV@#1@#2\endcsname{#3}% + \fi + \fi + }% + \ifx\tmp@KVS@PD\KVS@ProcessorDefault + \let\KVS@ProcessorDefault\thmt@kv@processor@default + \def\kv@processor@default#1#2{% + \begingroup + \csname @safe@activestrue\endcsname + \let\ifincsname\iftrue + \edef\KVS@temp{\endgroup + \noexpand\KVS@ProcessorDefault{#1}{\unexpanded{#2}}% + }% + \KVS@temp + } + \else + \PackageError{thm-kv}{kvsetkeys patch failed, try kvsetkeys v1.13 or earlier} + \fi +}{% + \RequirePackage{etex} + \PackageInfo{thm-kv}{kvsetkeys patch applied (pre-1.13)}% + \let\kv@processor@default\thmt@kv@processor@default +}} + +% useful key handler defaults. +\newcommand\thmt@mkignoringkeyhandler[1]{% + \kv@set@family@handler{#1}{% + \thmt@debug{Key `##1' with value `##2' ignored by #1.}% + }% +} +\newcommand\thmt@mkextendingkeyhandler[3]{% +% #1: family +% #2: prefix for file +% #3: key hint for error + \kv@set@family@handler{#1}{% + \thmt@selfextendingkeyhandler{#1}{#2}{#3}% + {##1}{##2}% + }% +} + +\newcommand\thmt@selfextendingkeyhandler[5]{% + % #1: family + % #2: prefix for file + % #3: key hint for error + % #4: actual key + % #5: actual value + \IfFileExists{#2-#4.sty}{% + \PackageInfo{thmtools}% + {Automatically pulling in `#2-#4'}% + \RequirePackage{#2-#4}% + \ifcsname KV@#1@#4\endcsname + \csname KV@#1@#4\endcsname{#5}% + \else + \PackageError{thmtools}% + {#3 `#4' not known} + {I don't know what that key does.\MessageBreak + I've even loaded the file `#2-#4.sty', but that didn't help. + }% + \fi + }{% + \PackageError{thmtools}% + {#3 `#4' not known} + {I don't know what that key does by myself,\MessageBreak + and no file `#2-#4.sty' to tell me seems to exist. + }% + }% +} + + +\newif\if@thmt@firstkeyset + +% many keys are evaluated twice, because we don't know +% if they make sense before or after, or both. +\def\thmt@trytwice{% + \if@thmt@firstkeyset + \@xa\@firstoftwo + \else + \@xa\@secondoftwo + \fi +} + +\@for\tmp@keyname:=parent,numberwithin,within\do{% +\define@key{thmdef}{\tmp@keyname}{\thmt@trytwice{\thmt@setparent{#1}}{}}% +} + +\@for\tmp@keyname:=sibling,numberlike,sharenumber\do{% +\define@key{thmdef}{\tmp@keyname}{\thmt@trytwice{\thmt@setsibling{#1}}{}}% +} + +\@for\tmp@keyname:=title,name,heading\do{% +\define@key{thmdef}{\tmp@keyname}{\thmt@trytwice{\thmt@setthmname{#1}}{}}% +} + +\@for\tmp@keyname:=unnumbered,starred\do{% +\define@key{thmdef}{\tmp@keyname}[]{\thmt@trytwice{\thmt@isnumberedfalse}{}}% +} + +\def\thmt@YES{yes} +\def\thmt@NO{no} +\def\thmt@UNIQUE{unless unique} +\define@key{thmdef}{numbered}[\thmt@YES]{ + \def\thmt@tmp{#1}% + \thmt@trytwice{% + \ifx\thmt@tmp\thmt@YES + \thmt@isnumberedtrue + \else\ifx\thmt@tmp\thmt@NO + \thmt@isnumberedfalse + \else\ifx\thmt@tmp\thmt@UNIQUE + \RequirePackage[unq]{unique} + \ifuniq{\thmt@envname}{% + \thmt@isnumberedfalse + }{% + \thmt@isnumberedtrue + }% + \else + \PackageError{thmtools}{Unknown value `#1' to key numbered}{}% + \fi\fi\fi + }{% trytwice: after definition + \ifx\thmt@tmp\thmt@UNIQUE + \addtotheorempreheadhook[\thmt@envname]{\setuniqmark{\thmt@envname}}% + \addtotheorempreheadhook[\thmt@envname]{\def\thmt@dummyctrautorefname{\thmt@thmname\@gobble}} + \fi + }% +} + + +\define@key{thmdef}{preheadhook}{\thmt@trytwice{}{\addtotheorempreheadhook[\thmt@envname]{#1}}} +\define@key{thmdef}{postheadhook}{\thmt@trytwice{}{\addtotheorempostheadhook[\thmt@envname]{#1}}} +\define@key{thmdef}{prefoothook}{\thmt@trytwice{}{\addtotheoremprefoothook[\thmt@envname]{#1}}} +\define@key{thmdef}{postfoothook}{\thmt@trytwice{}{\addtotheorempostfoothook[\thmt@envname]{#1}}} + +\define@key{thmdef}{style}{\thmt@trytwice{\thmt@setstyle{#1}}{}} + +% ugly hack: style needs to be evaluated first so its keys +% are not overridden by explicit other settings +\define@key{thmdef0}{style}{% + \ifcsname thmt@style #1@defaultkeys\endcsname + \thmt@toks{\kvsetkeys{thmdef}}% + \@xa\@xa\@xa\the\@xa\@xa\@xa\thmt@toks\@xa\@xa\@xa{% + \csname thmt@style #1@defaultkeys\endcsname}% + \fi +} +\thmt@mkignoringkeyhandler{thmdef0} + +% fallback definition. +% actually, only the kernel does not provide \theoremstyle. +% is this one worth having glue code for the theorem package? +\def\thmt@setstyle#1{% + \PackageWarning{thm-kv}{% + Your backend doesn't have a `\string\theoremstyle' command. + }% +} + +\ifcsname theoremstyle\endcsname + \let\thmt@originalthmstyle\theoremstyle + \def\thmt@outerstyle{plain} + \renewcommand\theoremstyle[1]{% + \def\thmt@outerstyle{#1}% + \thmt@originalthmstyle{#1}% + } + \def\thmt@setstyle#1{% + \thmt@originalthmstyle{#1}% + } + \g@addto@macro\thmt@newtheorem@postdefinition{% + \thmt@originalthmstyle{\thmt@outerstyle}% + } +\fi + +\newif\ifthmt@isnumbered +\newcommand\thmt@setparent[1]{% + \def\thmt@parent{#1}% +} +\newcommand\thmt@setsibling{% + \def\thmt@sibling +} +\newcommand\thmt@setthmname{% + \def\thmt@thmname +} + +\thmt@mkextendingkeyhandler{thmdef}{thmdef}{\string\declaretheorem\space key} + +\let\thmt@newtheorem\newtheorem + +\newcommand\declaretheorem[2][]{% + % why was that here? + %\let\thmt@theoremdefiner\thmt@original@newtheorem + \def\thmt@envname{#2}% + \thmt@setthmname{\thmt@modifycase #2}% + \thmt@setparent{}% + \thmt@setsibling{}% + \thmt@isnumberedtrue% + \@thmt@firstkeysettrue% + \kvsetkeys{thmdef0}{#1}% + \kvsetkeys{thmdef}{#1}% + \protected@edef\thmt@tmp{% + \@nx\thmt@newtheorem + \ifthmt@isnumbered\else *\fi + {#2}% + \ifx\thmt@sibling\@empty\else [\thmt@sibling]\fi + {\thmt@thmname}% + \ifx\thmt@parent\@empty\else [\thmt@parent]\fi + \relax% added so we can delimited-read everything later + % (recall newtheorem is patched) + }%\show\thmt@tmp + \thmt@tmp + % uniquely ugly kludge: some keys make only sense + % afterwards. + % and it gets kludgier: again, the default-inherited + % keys need to have a go at it. + \@thmt@firstkeysetfalse% + \kvsetkeys{thmdef0}{#1}% + \kvsetkeys{thmdef}{#1}% +} +\@onlypreamble\declaretheorem + +\providecommand\thmt@quark{\thmt@quark} + +% in-document keyval, i.e. \begin{theorem}[key=val,key=val] + +\thmt@mkextendingkeyhandler{thmuse}{thmuse}{\thmt@envname\space optarg key} + +\addtotheorempreheadhook{% + \ifx\thmt@optarg\@empty\else + \@xa\thmt@garbleoptarg\@xa{\thmt@optarg}\fi +}% + +\newif\ifthmt@thmuse@iskv + +\providecommand\thmt@garbleoptarg[1]{% + \thmt@thmuse@iskvfalse + \def\thmt@newoptarg{\@gobble}% + \def\thmt@newoptargextra{}% + \let\thmt@shortoptarg\@empty + \def\thmt@warn@unusedkeys{}% + \@for\thmt@fam:=\thmt@thmuse@families\do{% + \kvsetkeys{\thmt@fam}{#1}% + }% + \ifthmt@thmuse@iskv + \protected@edef\thmt@optarg{% + \@xa\thmt@newoptarg + \thmt@newoptargextra\@empty + }% + \ifx\thmt@shortoptarg\@empty + \protected@edef\thmt@shortoptarg{\thmt@newoptarg\@empty}% + \fi + \thmt@warn@unusedkeys + \else + \def\thmt@optarg{#1}% + \def\thmt@shortoptarg{#1}% + \fi +} +\def\thmt@splitopt#1=#2\thmt@quark{% + \def\thmt@tmpkey{#1}% + \ifx\thmt@tmpkey\@empty + \def\thmt@tmpkey{\thmt@quark}% + \fi + \@onelevel@sanitize\thmt@tmpkey +} + +\def\thmt@thmuse@families{thm@track@keys} + +\kv@set@family@handler{thm@track@keys}{% + \@onelevel@sanitize\kv@key + \@namedef{thmt@unusedkey@\kv@key}{% + \PackageWarning{thmtools}{Unused key `#1'}% + }% + \@xa\g@addto@macro\@xa\thmt@warn@unusedkeys\@xa{% + \csname thmt@unusedkey@\kv@key\endcsname + } +} + +% key, code. +\def\thmt@define@thmuse@key#1#2{% + \g@addto@macro\thmt@thmuse@families{,#1}% + \define@key{#1}{#1}{\thmt@thmuse@iskvtrue + \@namedef{thmt@unusedkey@#1}{}% + #2}% + \thmt@mkignoringkeyhandler{#1}% +} + +\thmt@define@thmuse@key{label}{% + \addtotheorempostheadhook[local]{\label{#1}}% +} +\thmt@define@thmuse@key{name}{% + \thmt@setnewoptarg #1\@iden% +} +\newcommand\thmt@setnewoptarg[1][]{% + \def\thmt@shortoptarg{#1}\thmt@setnewlongoptarg +} +\def\thmt@setnewlongoptarg #1\@iden{% + \def\thmt@newoptarg{#1\@iden}} + +\providecommand\thmt@suspendcounter[2]{% + \@xa\protected@edef\csname the#1\endcsname{#2}% + \@xa\let\csname c@#1\endcsname\c@thmt@dummyctr +} + +\providecommand\thmcontinues[1]{% + \ifcsname hyperref\endcsname + \hyperref[#1]{continuing} + \else + continuing + \fi + from p.\,\pageref{#1}% +} + +\thmt@define@thmuse@key{continues}{% + \thmt@suspendcounter{\thmt@envname}{\thmt@trivialref{#1}{??}}% + \g@addto@macro\thmt@newoptarg{{, }% + \thmcontinues{#1}% + \@iden}% +} + + +% \end{macrocode} +% +% Defining new theorem styles; keys are in opt-arg +% even though not having any doesn't make much sense. +% It doesn't do anything exciting here, it's up to +% the glue layer to provide keys. +% +% \begin{macrocode} +\def\thmt@declaretheoremstyle@setup{} +\def\thmt@declaretheoremstyle#1{% + \PackageWarning{thmtools}{Your backend doesn't allow styling theorems}{} +} +\newcommand\declaretheoremstyle[2][]{% + \def\thmt@style{#2}% + \@xa\def\csname thmt@style \thmt@style @defaultkeys\endcsname{}% + \thmt@declaretheoremstyle@setup + \kvsetkeys{thmstyle}{#1}% + \thmt@declaretheoremstyle{#2}% +} +\@onlypreamble\declaretheoremstyle + +\kv@set@family@handler{thmstyle}{% + \@onelevel@sanitize\kv@value + \@onelevel@sanitize\kv@key + \PackageInfo{thmtools}{% + Key `\kv@key' (with value `\kv@value')\MessageBreak + is not a known style key.\MessageBreak + Will pass this to every \string\declaretheorem\MessageBreak + that uses `style=\thmt@style'% + }% + \ifx\kv@value\relax% no value given, don't pass on {}! + \@xa\g@addto@macro\csname thmt@style \thmt@style @defaultkeys\endcsname{% + #1,% + }% + \else + \@xa\g@addto@macro\csname thmt@style \thmt@style @defaultkeys\endcsname{% + #1={#2},% + }% + \fi +} +% \end{macrocode} +% +%\iffalse +%</kv> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thm-listof.dtx b/macros/latex/contrib/thmtools/source/thm-listof.dtx new file mode 100644 index 0000000000..39603b4341 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thm-listof.dtx @@ -0,0 +1,224 @@ +% \iffalse meta-comment +% +% Copyright (C) 2008-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +% \fi +% +%\iffalse (hide this from DocInput) +%<*listof> +%\fi +% +% This package provides two main commands: +% \DescribeMacro{\listoftheorems} +% |\listoftheorems| will generate, well, a list of all theorems, lemmas, +% etc. in your document. This list is hyperlinked if you use \pkg{hyperref}, +% and it will list the optional argument to the theorem. +% +% Currently, some options can be given as an optional argument keyval list: +% \begin{description} +% \item[numwidth] The width allocated for the numbers, default 2.3em. Since +% you are more likely to have by-section numbering than with figures, this +% needs to be accessible. +% \item[ignore=foo,bar] A last-second call to |\ignoretheorems|, see below. +% \item[onlynamed=foo,bar] Only list those foo and bar environments that +% had an optional title. This weeds out unimportant definitions, for +% example. If no argument is given, this applies to all environments +% defined by |\newtheorem| and |\declaretheorem|. +% \item[show=foo,bar] Undo a previous |\ignoretheorems| and restore default +% formatting for these environments. Useful in combination with +% ignoreall. +% \item[ignoreall] +% \item[showall] Like applying ignore or show with a list of all theorems +% you have defined. +% \item[title] +% Provide a title for this list overwriting the default in |\listtheoremname|. +% \end{description} +% +% \DescribeMacro{\listtheoremname} +% The heading name is stored in the macro |\listtheoremname| and is +% ``List of Theorems'' by default. All other formatting aspects are taken +% from |\listoffigures|. (As a matter of fact, |\listoffigures| is called +% internally.) +% +% \DescribeMacro{\ignoretheorems} +% |\ignoretheorems|\marg{remark,example,...} can be used to suppress some +% types of theorem from the LoTh. Be careful not to have spaces in the list, +% those are currently \emph{not} filtered out. +% +% There's currently no interface to change the look of the list. If you're +% daring, the code for the theorem type ``lemma'' is in |\l@lemma| and so on. +% +%\StopEventually{} +% \begin{macrocode} +\let\@xa=\expandafter +\let\@nx=\noexpand +\RequirePackage{thm-patch,keyval,kvsetkeys} + +\def\thmtlo@oldchapter{0}% +\newcommand\thmtlo@chaptervspacehack{} +\ifcsname c@chapter\endcsname + \ifx\c@chapter\relax\else + \def\thmtlo@chaptervspacehack{% + \ifnum \value{chapter}=\thmtlo@oldchapter\relax\else + % new chapter, add vspace to loe. + \addtocontents{loe}{\protect\addvspace{10\p@}}% + \xdef\thmtlo@oldchapter{\arabic{chapter}}% + \fi + }% + \fi +\fi + + +\providecommand\listtheoremname{List of Theorems} +\newcommand\listoftheorems[1][]{% + %% much hacking here to pick up the definition from the class + %% without oodles of conditionals. + \bgroup + \setlisttheoremstyle{#1}% + \let\listfigurename\listtheoremname + \def\contentsline##1{% + \csname thmt@contentsline@##1\endcsname{##1}% + }% + \@for\thmt@envname:=\thmt@allenvs\do{% + \@xa\protected@edef\csname l@\thmt@envname\endcsname{% CHECK: why p@edef? + \@nx\@dottedtocline{1}{1.5em}{\@nx\thmt@listnumwidth}% + }% + }% + \let\thref@starttoc\@starttoc + \def\@starttoc##1{\thref@starttoc{loe}}% + % new hack: to allow multiple calls, we defer the opening of the + % loe file to AtEndDocument time. This is before the aux file is + % read back again, that is early enough. + % TODO: is it? crosscheck include/includeonly! + \@fileswfalse + \AtEndDocument{% + \if@filesw + \@ifundefined{tf@loe}{% + \expandafter\newwrite\csname tf@loe\endcsname + \immediate\openout \csname tf@loe\endcsname \jobname.loe\relax + }{}% + \fi + }% + %\expandafter + \listoffigures + \egroup +} + +\newcommand\setlisttheoremstyle[1]{% + \kvsetkeys{thmt-listof}{#1}% +} +\define@key{thmt-listof}{numwidth}{\def\thmt@listnumwidth{#1}} +\define@key{thmt-listof}{ignore}[\thmt@allenvs]{\ignoretheorems{#1}} +\define@key{thmt-listof}{onlynamed}[\thmt@allenvs]{\onlynamedtheorems{#1}} +\define@key{thmt-listof}{show}[\thmt@allenvs]{\showtheorems{#1}} +\define@key{thmt-listof}{ignoreall}[true]{\ignoretheorems{\thmt@allenvs}} +\define@key{thmt-listof}{showall}[true]{\showtheorems{\thmt@allenvs}} +% FMi 2019-09-31 allow local title +\define@key{thmt-listof}{title}{\def\listtheoremname{#1}} +% -- FMi + +\providecommand\thmt@listnumwidth{2.3em} + +\providecommand\thmtformatoptarg[1]{ (#1)} + +\newcommand\thmt@mklistcmd{% + \@xa\protected@edef\csname l@\thmt@envname\endcsname{% CHECK: why p@edef? + \@nx\@dottedtocline{1}{1.5em}{\@nx\thmt@listnumwidth}% + }% + \ifthmt@isstarred + \@xa\def\csname ll@\thmt@envname\endcsname{% + \protect\numberline{\protect\let\protect\autodot\protect\@empty}% + \thmt@thmname + \ifx\@empty\thmt@shortoptarg\else\protect\thmtformatoptarg{\thmt@shortoptarg}\fi + }% + \else + \@xa\def\csname ll@\thmt@envname\endcsname{% + \protect\numberline{\csname the\thmt@envname\endcsname}% + \thmt@thmname + \ifx\@empty\thmt@shortoptarg\else\protect\thmtformatoptarg{\thmt@shortoptarg}\fi + }% + \fi + \@xa\gdef\csname thmt@contentsline@\thmt@envname\endcsname{% + \thmt@contentslineShow% default:show + }% +} +\def\thmt@allenvs{\@gobble} +\newcommand\thmt@recordenvname{% + \edef\thmt@allenvs{\thmt@allenvs,\thmt@envname}% +} +\g@addto@macro\thmt@newtheorem@predefinition{% + \thmt@mklistcmd + \thmt@recordenvname +} + +\addtotheorempostheadhook{% + \thmtlo@chaptervspacehack + \addcontentsline{loe}{\thmt@envname}{% + \csname ll@\thmt@envname\endcsname + }% +} + +\newcommand\showtheorems[1]{% + \@for\thmt@thm:=#1\do{% + \typeout{showing \thmt@thm}% + \@xa\let\csname thmt@contentsline@\thmt@thm\endcsname + =\thmt@contentslineShow + }% +} + +\newcommand\ignoretheorems[1]{% + \@for\thmt@thm:=#1\do{% + \@xa\let\csname thmt@contentsline@\thmt@thm\endcsname + =\thmt@contentslineIgnore + }% +} +\newcommand\onlynamedtheorems[1]{% + \@for\thmt@thm:=#1\do{% + \global\@xa\let\csname thmt@contentsline@\thmt@thm\endcsname + =\thmt@contentslineIfNamed + }% +} + +\AtBeginDocument{% +\@ifpackageloaded{hyperref}{% + \let\thmt@hygobble\@gobble +}{% + \let\thmt@hygobble\@empty +} +\let\thmt@contentsline\contentsline +} + +\def\thmt@contentslineIgnore#1#2#3{% + \thmt@hygobble +} +\def\thmt@contentslineShow{% + \thmt@contentsline +} + +\def\thmt@contentslineIfNamed#1#2#3{% + \thmt@ifhasoptname #2\thmtformatoptarg\@nil{% + \thmt@contentslineShow{#1}{#2}{#3}% + }{% + \thmt@contentslineIgnore{#1}{#2}{#3}% + %\thmt@contentsline{#1}{#2}{#3}% + } +} + +\def\thmt@ifhasoptname #1\thmtformatoptarg#2\@nil{% + \ifx\@nil#2\@nil + \@xa\@secondoftwo + \else + \@xa\@firstoftwo + \fi +} +% \end{macrocode} +%\iffalse +%</listof> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thm-llncs.dtx b/macros/latex/contrib/thmtools/source/thm-llncs.dtx new file mode 100644 index 0000000000..134acb18b7 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thm-llncs.dtx @@ -0,0 +1,97 @@ +% \iffalse meta-comment +% +% Copyright (C) 2010-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +%\fi +% +%\iffalse (hide this from DocInput) +%<*llncs> +%\fi +% \begin{macrocode} +\@ifclasslater{llncs}{2010/04/15}{}{% + \PackageWarningNoLine{thmtools}{% + LLNCS.cls too old, not supported by thmtools + }% + \endinput} +% Thank you very much, Springer, for having yet another bloody +% system. Annoyingly, it makes \xdefs all over the place, so +% they break \MakeUppercase and hence name=. +\ifx\thmt@modifycase\@empty\else + \PackageWarningNoLine{thmtools}{% + LLNCS support disables automatic casing of theorem names + }% + \let\thmt@modifycase\@empty +\fi +%% +% Usage: +% +% \spnewtheorem{env_nam}{caption}[within]{cap_font}{body_font} +% or \spnewtheorem{env_nam}[numbered_like]{caption}{cap_font}{body_font} +% or \spnewtheorem*{env_nam}{caption}{cap_font}{body_font} +\providecommand\thmt@style@headfont{\normalfont\bfseries} +\providecommand\thmt@style@bodyfont{\normalfont\itshape} + +\let\thmt@original@spnewtheorem\spnewtheorem +\let\thmt@theoremdefiner\thmt@original@spnewtheorem + +% cf thm-patch.dtx +\def\spnewtheorem{% + \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}}{}}% + {\parseMand{\def\thmt@style@headfont{##1}}}% + {\parseMand{\def\thmt@style@bodyfont{##1}}}% + {\let\@parsecmd\thmt@spnewtheoremiv}% + }% +} + +\newcommand\thmt@spnewtheoremiv{% + \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@style@headfont}{\thmt@style@bodyfont}% + } + \thmt@args + \thmt@newtheorem@postdefinition +} + +% for the keyval interface: +\define@key{thmdef}{headfont}{% + \def\thmt@style@headfont{#1}% +} +\define@key{thmdef}{bodyfont}{% +\def\thmt@style@bodyfont{#1}% +} + +\def\thmt@almost@spnewtheorem#1\relax{% + \def\thm@tmpa{\spnewtheorem#1}% + \@xa\@xa\@xa\thm@tmpa + \@xa\@xa\@xa{\@xa\thmt@style@headfont\@xa}% + \@xa{\thmt@style@bodyfont}% +} +\let\thmt@newtheorem\thmt@almost@spnewtheorem +% \end{macrocode} +%\iffalse (hide this from DocInput) +%</llncs> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thm-ntheorem.dtx b/macros/latex/contrib/thmtools/source/thm-ntheorem.dtx new file mode 100644 index 0000000000..ef29870931 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thm-ntheorem.dtx @@ -0,0 +1,138 @@ +% \iffalse meta-comment +% +% Copyright (C) 2010-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +%\fi +% +%\iffalse (hide this from DocInput) +%<*ntheorem> +%\fi +% \begin{macrocode} + +\providecommand\thmt@space{ } + +% actually, ntheorem's so-called style is nothing like a style at all... +\def\thmt@declaretheoremstyle@setup{} +\def\thmt@declaretheoremstyle#1{% + \ifcsname th@#1\endcsname\else + \@xa\let\csname th@#1\endcsname\th@plain + \fi +} + +\def\thmt@notsupported#1#2{% + \PackageWarning{thmtools}{Key `#2' not supported by #1}{}% +} + +\define@key{thmstyle}{spaceabove}{% + \setlength\theorempreskipamount{#1}% +} +\define@key{thmstyle}{spacebelow}{% + \setlength\theorempostskipamount{#1}% +} +\define@key{thmstyle}{headfont}{% + \theoremheaderfont{#1}% +} +\define@key{thmstyle}{bodyfont}{% + \theorembodyfont{#1}% +} +% not supported in ntheorem. +\define@key{thmstyle}{notefont}{% + \thmt@notsupported{ntheorem}{notefont}% +} +\define@key{thmstyle}{headpunct}{% + \theoremseparator{#1}% +} +% not supported in ntheorem. +\define@key{thmstyle}{notebraces}{% + \thmt@notsupported{ntheorem}{notebraces}% +} +\define@key{thmstyle}{break}{% + \theoremstyle{break}% +} +% not supported in ntheorem... +\define@key{thmstyle}{postheadspace}{% + %\def\thmt@style@postheadspace{#1}% + \@xa\g@addto@macro\csname thmt@style \thmt@style @defaultkeys\endcsname{% + postheadhook={\hspace{-\labelsep}\hspace*{#1}},% + }% +} + +% not supported in ntheorem +\define@key{thmstyle}{headindent}{% + \thmt@notsupported{ntheorem}{headindent}% +} +% sorry, only style, not def with ntheorem. +\define@key{thmstyle}{qed}[\qedsymbol]{% + \@ifpackagewith{ntheorem}{thmmarks}{% + \theoremsymbol{#1}% + }{% + \thmt@notsupported + {ntheorem without thmmarks option}% + {headindent}% + }% +} + +\let\@upn=\textup +\define@key{thmstyle}{headformat}[]{% + \def\thmt@tmp{#1}% + \@onelevel@sanitize\thmt@tmp + %\tracingall + \ifcsname thmt@headstyle@\thmt@tmp\endcsname + \newtheoremstyle{\thmt@style}{% + \item[\hskip\labelsep\theorem@headerfont% + \def\NAME{\theorem@headerfont ####1}% + \def\NUMBER{\bgroup\@upn{####2}\egroup}% + \def\NOTE{}% + \csname thmt@headstyle@#1\endcsname + \theorem@separator + ] + }{% + \item[\hskip\labelsep\theorem@headerfont% + \def\NAME{\theorem@headerfont ####1}% + \def\NUMBER{\bgroup\@upn{####2}\egroup}% + \def\NOTE{\if=####3=\else\bgroup\thmt@space(####3)\egroup\fi}% + \csname thmt@headstyle@#1\endcsname + \theorem@separator + ] + } + \else + \newtheoremstyle{\thmt@style}{% + \item[\hskip\labelsep\theorem@headerfont% + \def\NAME{\the\thm@headfont ####1}% + \def\NUMBER{\bgroup\@upn{####2}\egroup}% + \def\NOTE{}% + #1% + \theorem@separator + ] + }{% + \item[\hskip\labelsep\theorem@headerfont% + \def\NAME{\the\thm@headfont ####1}% + \def\NUMBER{\bgroup\@upn{####2}\egroup}% + \def\NOTE{\if=####3=\else\bgroup\thmt@space(####3)\egroup\fi}% + #1% + \theorem@separator + ] + } + \fi +} + +\def\thmt@headstyle@margin{% + \makebox[0pt][r]{\NUMBER\ }\NAME\NOTE +} +\def\thmt@headstyle@swapnumber{% + \NUMBER\ \NAME\NOTE +} + + + +% \end{macrocode} +%\iffalse (hide this from DocInput) +%</ntheorem> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thm-patch.dtx b/macros/latex/contrib/thmtools/source/thm-patch.dtx new file mode 100644 index 0000000000..dd00028ca8 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thm-patch.dtx @@ -0,0 +1,254 @@ +% \iffalse meta-comment +% +% Copyright (C) 2008-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1.3c.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 diff --git a/macros/latex/contrib/thmtools/source/thm-restate.dtx b/macros/latex/contrib/thmtools/source/thm-restate.dtx new file mode 100644 index 0000000000..d02b3630ab --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thm-restate.dtx @@ -0,0 +1,346 @@ +% \iffalse meta-comment +% +% Copyright (C) 2008-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1.3c.txt +% +% \fi +% +%\iffalse (hide this from DocInput) +%<*restate> +%\fi +% +%\DescribeEnv{restatable} +%Only one environment is provided: \verb|restatable|, which takes one +%optional and two mandatory arguments. The first mandatory argument is the +%type of the theorem, i.e. if you want |\begin{lemma}| to be called on +%the inside, give |lemma|. The second argument is the name of the macro +%that the text should be stored in, for example \verb|mylemma|. Be careful +%not to specify existing command names! The optional argument will become the +%optional argument to your theorem command. Consider the following example: +%\begin{verbatim} +% \documentclass{article} +% \usepackage{amsmath, amsthm, thm-restate} +% \newtheorem{lemma}{Lemma} +% \begin{document} +% \begin{restatable}[Zorn]{lemma}{zornlemma}\label{thm:zorn} +% If every chain in $X$ is upper-bounded, +% $X$ has a maximal element. +% +% It's true, you know! +% \end{restatable} +% \begin{lemma} +% This is some other lemma of no import. +% \end{lemma} +% And now, here's Mr. Zorn again: \zornlemma* +% \end{document} +%\end{verbatim} +%which yields +% \begin{restatable}[Zorn]{lemma}{zornlemma}\label{thm:zorn} +% If every chain in $X$ is upper-bounded, $X$ has a maximal element. +% +% It's true, you know! +% \end{restatable} +% \begin{lemma} +% This is some other lemma of no import. +% \end{lemma} +% Actually, we have set a label in the environment, so we know that +% it's Lemma~\ref{thm:zorn} on page~\ref{thm:zorn}. +% And now, here's Mr. Zorn again: \zornlemma* +% Since we prevent the label from being set again, we find that +% it's still Lemma~\ref{thm:zorn} on page~\ref{thm:zorn}, even though +% it occurs later also. +% +% \DescribeEnv{restatable*} +% As you can see, we use the starred form |\mylemma*|. As in many cases in +% \LaTeX, the star means ``don't give a number'', since we want to retain +% the original number. There is also a starred variant of the |restatable| +% environment, where the first call doesn't determine the number, but a +% later call to |\mylemma| without star would. Since the number is carried +% around using \LaTeX' |\label| machanism, you'll need a rerun for things to +% settle. +% +% \subsection{Restrictions} +% The only counter that is saved is the one for the theorem number. So, +% putting floats inside a restatable is not advised: they will appear in the +% LoF several times with new numbers. +% Equations should work, but the code handling them might turn out to be +% brittle, in particular when you add/remove hyperref. +% %In the same vein, numbered equations +% %within the statement appear again and are numbered again, with new +% %numbers. (This is vaguely non-trivial to do correctly if equations are not +% %numbered consecutively, but per-chapter, or there are multiple numbered +% %equations.) +% Note that you cannot successfully reference the equations +% since all labels are disabled in the starred appearance. (The reference +% will point at the unstarred occurence.) +% +% You cannot nest +% restatables either. You \emph{can} use the |\restatable|\dots|\endrestatable| +% version, but everything up to the next matching |\end{...}| is scooped up. +% I've also probably missed many border cases. +% +% +%\StopEventually{} +% \begin{macrocode} +\RequirePackage{thmtools} +\let\@xa\expandafter +\let\@nx\noexpand +\@ifundefined{c@thmt@dummyctr}{% + \newcounter{thmt@dummyctr}% + }{} +\gdef\theHthmt@dummyctr{dummy.\arabic{thmt@dummyctr}}% +\gdef\thethmt@dummyctr{}% +\long\def\thmt@collect@body#1#2\end#3{% + \@xa\thmt@toks\@xa{\the\thmt@toks #2}% + \def\thmttmpa{#3}%\def\thmttmpb{restatable}% + \ifx\thmttmpa\@currenvir%thmttmpb + \@xa\@firstoftwo% this is the end of the environment. + \else + \@xa\@secondoftwo% go on collecting + \fi{% this is the end, my friend, drop the \end. + % and call #1 with the collected body. + \@xa#1\@xa{\the\thmt@toks}% + }{% go on collecting + \@xa\thmt@toks\@xa{\the\thmt@toks\end{#3}}% + \thmt@collect@body{#1}% + }% +} +% \end{macrocode} +% A totally ignorant version of |\ref|, defaulting to \#2 if label not +% known yet. Otherwise, return the formatted number. +% \begin{macrocode} +\def\thmt@trivialref#1#2{% + \ifcsname r@#1\endcsname + \@xa\@xa\@xa\thmt@trivi@lr@f\csname r@#1\endcsname\relax\@nil + \else #2\fi +} +\def\thmt@trivi@lr@f#1#2\@nil{#1} +% \end{macrocode} +% +% Counter safeties: some counters' values should be stored, such as +% equation, so we don't get a new number. (We cannot reference it anyway.) +% We cannot store everything, though, think page counter or section number! +% There is one problem here: we have to remove all references to other +% counters from |\theequation|, otherwise your equation could get a number +% like (3.1) in one place and (4.1) in another section. +% +% The best solution I can come up with is to override the usual macros +% that counter display goes through, to check if their argument is one +% that should be fully-expanded away or retained. +% +% The following should only be called from within a group, and the sanitized +% |\thectr| must not be called from within that group, since it needs the +% original |\@arabic| et al. +% +% \begin{macrocode} +\def\thmt@innercounters{% + equation} +\def\thmt@counterformatters{% + @alph,@Alph,@arabic,@roman,@Roman,@fnsymbol} + +\@for\thmt@displ:=\thmt@counterformatters\do{% + \@xa\let\csname thmt@\thmt@displ\@xa\endcsname\csname \thmt@displ\endcsname +}% +\def\thmt@sanitizethe#1{% + \@for\thmt@displ:=\thmt@counterformatters\do{% + \@xa\protected@edef\csname\thmt@displ\endcsname##1{% + \@nx\ifx\@xa\@nx\csname c@#1\endcsname ##1% + \@xa\protect\csname \thmt@displ\endcsname{##1}% + \@nx\else + \@nx\csname thmt@\thmt@displ\endcsname{##1}% + \@nx\fi + }% + }% + \expandafter\protected@edef\csname the#1\endcsname{\csname the#1\endcsname}% + \ifcsname theH#1\endcsname + \expandafter\protected@edef\csname theH#1\endcsname{\csname theH#1\endcsname}% + \fi +} + +\def\thmt@rst@storecounters#1{% + \bgroup + % ugly hack: save chapter,..subsection numbers + % for equation numbers. + %\refstepcounter{thmt@dummyctr}% why is this here? + %% temporarily disabled, broke autorefname. + \def\@currentlabel{}% + \@for\thmt@ctr:=\thmt@innercounters\do{% + \thmt@sanitizethe{\thmt@ctr}% + \protected@edef\@currentlabel{% + \@currentlabel + \protect\def\@xa\protect\csname the\thmt@ctr\endcsname{% + \csname the\thmt@ctr\endcsname}% + \ifcsname theH\thmt@ctr\endcsname + \protect\def\@xa\protect\csname theH\thmt@ctr\endcsname{% + (restate \protect\theHthmt@dummyctr)\csname theH\thmt@ctr\endcsname}% + \fi + \protect\setcounter{\thmt@ctr}{\number\csname c@\thmt@ctr\endcsname}% + }% + }% + \label{thmt@@#1@data}% + \egroup +}% +% \end{macrocode} +% +% Now, the main business. +% +% \begin{macrocode} +\newif\ifthmt@thisistheone +\newenvironment{thmt@restatable}[3][]{% + \thmt@toks{}% will hold body +% + \stepcounter{thmt@dummyctr}% used for data storage label. +% + \long\def\thmrst@store##1{% + \@xa\gdef\csname #3\endcsname{% + \@ifstar{% + \thmt@thisistheonefalse\csname thmt@stored@#3\endcsname + }{% + \thmt@thisistheonetrue\csname thmt@stored@#3\endcsname + }% + }% + \@xa\long\@xa\gdef\csname thmt@stored@#3\@xa\endcsname\@xa{% + \begingroup + \ifthmt@thisistheone + % these are the valid numbers, store them for the other + % occasions. + \thmt@rst@storecounters{#3}% + \else + % this one should use other numbers... + % first, fake the theorem number. + \@xa\protected@edef\csname the#2\endcsname{% + \thmt@trivialref{thmt@@#3}{??}}% + % if the number wasn't there, have a "re-run to get labels right" + % warning. + \ifcsname r@thmt@@#3\endcsname\else + \G@refundefinedtrue + \fi + % prevent stepcountering the theorem number, + % but still, have some number for hyperref, just in case. + \@xa\let\csname c@#2\endcsname=\c@thmt@dummyctr + \@xa\let\csname theH#2\endcsname=\theHthmt@dummyctr + % disable labeling. + \let\label=\thmt@gobble@label + \let\ltx@label=\@gobble% amsmath needs this + % We shall need to restore the counters at the end + % of the environment, so we get + % (4.2) [(3.1 from restate)] (4.3) + \def\thmt@restorecounters{}% + \@for\thmt@ctr:=\thmt@innercounters\do{% + \protected@edef\thmt@restorecounters{% + \thmt@restorecounters + \protect\setcounter{\thmt@ctr}{\arabic{\thmt@ctr}}% + }% + }% + % pull the new semi-static definition of \theequation et al. + % from the aux file. + \thmt@trivialref{thmt@@#3@data}{}% + \fi + % call the proper begin-env code, possibly with optional argument + % (omit if stored via key-val) + \ifthmt@restatethis + \thmt@restatethisfalse + \else + \csname #2\@xa\endcsname\ifx\@nx#1\@nx\else[{#1}]\fi + \fi + \ifthmt@thisistheone + % store a label so we can pick up the number later. + \label{thmt@@#3}% + \fi + % this will be the collected body. + ##1% + \csname end#2\endcsname + % if we faked the counter values, restore originals now. + \ifthmt@thisistheone\else\thmt@restorecounters\fi + \endgroup + }% thmt@stored@#3 + % in either case, now call the just-created macro, + \csname #3\@xa\endcsname\ifthmt@thisistheone\else*\fi + % and artificially close the current environment. + \@xa\end\@xa{\@currenvir} + }% thm@rst@store + \thmt@collect@body\thmrst@store +}{% + %% now empty, just used as a marker. +} + +\let\thmt@gobble@label\@gobble +% cleveref extends syntax of \label to \label[...]{...} +\AtBeginDocument{ + \@ifpackageloaded{cleveref}{ + \renewcommand*\thmt@gobble@label[2][]{} + }{} +} + +\newenvironment{restatable}{% + \thmt@thisistheonetrue\thmt@restatable +}{% + \endthmt@restatable +} +\newenvironment{restatable*}{% + \thmt@thisistheonefalse\thmt@restatable +}{% + \endthmt@restatable +} + +%%% support for keyval-style: restate=foobar +\protected@edef\thmt@thmuse@families{% + \thmt@thmuse@families% + ,restate phase 1% + ,restate phase 2% +} +\newcommand\thmt@splitrestateargs[1][]{% + \g@addto@macro\thmt@storedoptargs{,#1}% + \def\tmp@a##1\@{\def\thmt@storename{##1}}% + \tmp@a +} + +\newif\ifthmt@restatethis +\define@key{restate phase 1}{restate}{% + \thmt@thmuse@iskvtrue + \def\thmt@storedoptargs{}% discard the first time around + \thmt@splitrestateargs #1\@ + \def\thmt@storedoptargs{}% discard the first time around + %\def\thmt@storename{#1}% + \thmt@debug{we will restate as `\thmt@storename' with more args + `\thmt@storedoptargs'}% + \@namedef{thmt@unusedkey@restate}{}% + % spurious "unused key" fixes itself once we are after tracknames... + \thmt@restatethistrue + \protected@edef\tmp@a{% + \@nx\thmt@thisistheonetrue + \@nx\def\@nx\@currenvir{\thmt@envname}% + \@nx\@xa\@nx\thmt@restatable\@nx\@xa[\@nx\thmt@storedoptargs]% + {\thmt@envname}{\thmt@storename}% + }% + \@xa\g@addto@macro\@xa\thmt@local@postheadhook\@xa{% + \tmp@a + }% +} +\thmt@mkignoringkeyhandler{restate phase 1} + +\define@key{restate phase 2}{restate}{% + % do not store restate as a key for repetition: + % infinite loop. + % instead, retain the added keyvals + % overwriting thmt@storename should be safe here, it's been + % xdefd into the postheadhook + \thmt@splitrestateargs #1\@ +} +\kv@set@family@handler{restate phase 2}{% + \ifthmt@restatethis + \@xa\@xa\@xa\g@addto@macro\@xa\@xa\@xa\thmt@storedoptargs\@xa\@xa\@xa{\@xa\@xa\@xa,% + \@xa\kv@key\@xa=\kv@value}% + \fi +} + +% \end{macrocode} +%\iffalse +%</restate> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thmdef-mdframed.dtx b/macros/latex/contrib/thmtools/source/thmdef-mdframed.dtx new file mode 100644 index 0000000000..85c5d9bd2d --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thmdef-mdframed.dtx @@ -0,0 +1,35 @@ +% \iffalse meta-comment +% +% Copyright (C) 2010-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +%\fi +% +%\iffalse (hide this from DocInput) +%<*mdframed> +%\fi +% +% Mostly, this key wraps the theorem in a |mdframed| environment. +% The parameters are set by treating the value we are given as +% a new key-val list, see below. +% +% \begin{macrocode} +\define@key{thmdef}{mdframed}[{}]{% + \thmt@trytwice{}{% + \RequirePackage{mdframed}% + \RequirePackage{thm-patch}% + \addtotheorempreheadhook[\thmt@envname]{% + \begin{mdframed}[#1]}% + \addtotheorempostfoothook[\thmt@envname]{\end{mdframed}}% + }% +} +% \end{macrocode} +%\iffalse (hide this from DocInput) +%</mdframed> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thmdef-shaded.dtx b/macros/latex/contrib/thmtools/source/thmdef-shaded.dtx new file mode 100644 index 0000000000..c7501cae36 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thmdef-shaded.dtx @@ -0,0 +1,116 @@ +% \iffalse meta-comment +% +% Copyright (C) 2010-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +%\fi +% +%\iffalse (hide this from DocInput) +%<*shaded> +%\fi +% +% Mostly, this key wraps the theorem in a |shadebox| environment. +% The parameters are set by treating the value we are given as +% a new key-val list, see below. +% +% \begin{macrocode} + \define@key{thmdef}{shaded}[{}]{% + \thmt@trytwice{}{% + \RequirePackage{shadethm}% + \RequirePackage{thm-patch}% + \addtotheorempreheadhook[\thmt@envname]{% + \setlength\shadedtextwidth{\linewidth}% + \kvsetkeys{thmt@shade}{#1}\begin{shadebox}}% + \addtotheorempostfoothook[\thmt@envname]{\end{shadebox}}% + }% + } +% \end{macrocode} +% The docs for |shadethm| say: +% \begin{quote} +% There are some parameters you could set the default for (try them as is, +% first). +% \begin{itemize} +% \item |shadethmcolor|\quad The shading color of the background. See the +% documentation for the color package, but with a `gray' model, I find .97 +% looks good out of my printer, while a darker shade like .92 is needed +% to make it copy well. (Black is 0, white is 1.) +% \item |shaderulecolor|\quad The shading color of the border of the shaded box. +% See (i). If shadeboxrule is set to 0pt then this won't print anyway. +% \item |shadeboxrule|\quad The width of the border around the shading. Set it to +% 0pt (not just 0) to make it disappear. +% \item |shadeboxsep|\quad The length by which the shade box surrounds the text. +% \end{itemize} +% \end{quote} +% +% So, let's just define keys for all of these. +% +% \begin{macrocode} +\define@key{thmt@shade}{textwidth} {\setlength\shadedtextwidth{#1}} +\define@key{thmt@shade}{bgcolor} {\thmt@definecolor{shadethmcolor}{#1}} +\define@key{thmt@shade}{rulecolor} {\thmt@definecolor{shaderulecolor}{#1}} +\define@key{thmt@shade}{rulewidth} {\setlength\shadeboxrule{#1}} +\define@key{thmt@shade}{margin} {\setlength\shadeboxsep{#1}} +\define@key{thmt@shade}{padding} {\setlength\shadeboxsep{#1}} +\define@key{thmt@shade}{leftmargin} {\setlength\shadeleftshift{#1}} +\define@key{thmt@shade}{rightmargin}{\setlength\shaderightshift{#1}} +% \end{macrocode} +% +% What follows is wizardry you don't have to understand. In essence, +% we want to support two notions of color: one is ``everything that goes +% after |\definecolor{shadethmcolor}|'', such as +% |{rgb}{0.8,0.85,1}|. On the other hand, we'd also like +% to recognize an already defined color name such as |blue|. +% +% To handle the latter case, we need to copy the definition of one color +% into another. The \pkg{xcolor} package offers |\colorlet| for that, +% for the \pkg{color} package, we just cross our fingers. +% \begin{macrocode} +\def\thmt@colorlet#1#2{% + %\typeout{don't know how to let color `#1' be like color `#2'!}% + \@xa\let\csname\string\color@#1\@xa\endcsname + \csname\string\color@#2\endcsname + % this is dubious at best, we don't know what a backend does. +} +\AtBeginDocument{% + \ifcsname colorlet\endcsname + \let\thmt@colorlet\colorlet + \fi +} +% \end{macrocode} +% Now comes the interesting part: we assume that a simple color name +% must not be in braces, and a color definition starts with an opening +% curly brace. (So, if |\definecolor| ever gets an optional arg, +% we are in a world of pain.) +% +% If the second argument to |\thmt@definecolor| (the key) starts +% with a brace, +% then |\thmt@def@color| will have an empty second argument, +% delimited by the brace of the key. Hopefully, the key will have exactly +% enough arguments to satisfy |\definecolor|. Then, +% |thmt@drop@relax| will be executed and gobble the fallback +% values and the |\thmt@colorlet|. +% +% If the key does not contain an opening brace, |\thmt@def@color| +% will drop everything up to |{gray}{0.5}|. So, first the color +% gets defined to a medium gray, but then, it immediately gets overwritten +% with the definition corresponding to the color name. +% \begin{macrocode} +\def\thmt@drop@relax#1\relax{} +\def\thmt@definecolor#1#2{% + \thmt@def@color{#1}#2\thmt@drop@relax + {gray}{0.5}% + \thmt@colorlet{#1}{#2}% + \relax +} +\def\thmt@def@color#1#2#{% + \definecolor{#1}} +% \end{macrocode} +%\iffalse (hide this from DocInput) +%</shaded> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thmdef-thmbox.dtx b/macros/latex/contrib/thmtools/source/thmdef-thmbox.dtx new file mode 100644 index 0000000000..59409fd79e --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thmdef-thmbox.dtx @@ -0,0 +1,43 @@ +% \iffalse meta-comment +% +% Copyright (C) 2010-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% +%\fi +% +%\iffalse (hide this from DocInput) +%<*thmbox> +%\fi +% The \pkg{thmbox} package does something else: instead of having a separate +% environment, we have to use a command different from +% |\newtheorem| to get the boxed style. Fortunately, +% \thmtools stores the command as |\thmt@theoremdefiner|, so we +% can modify it. (One of the perks if extension writer and framework writer +% are the same person.) So, in contrast to the previous example, this time +% we need to do something before the actual |\newtheorem| is +% called. +% \begin{macrocode} +\define@key{thmdef}{thmbox}[L]{% + \thmt@trytwice{% + \let\oldproof=\proof + \let\oldendproof=\endproof + \let\oldexample=\example + \let\oldendexample=\endexample + \RequirePackage[nothm]{thmbox} + \let\proof=\oldproof + \let\endproof=\oldendproof + \let\example=\oldexample + \let\endexample=\oldendexample + \def\thmt@theoremdefiner{\newboxtheorem[#1]}% + }{}% +}% +% \end{macrocode} +%\iffalse (hide this from DocInput) +%</thmbox> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thmtools.dtx b/macros/latex/contrib/thmtools/source/thmtools.dtx new file mode 100644 index 0000000000..32e819c8e1 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thmtools.dtx @@ -0,0 +1,92 @@ +% \iffalse meta-comment +% +% Copyright (C) 2008-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1.3c.txt +% +% \fi +% +%\iffalse (hide this from DocInput) +%<*driver> +\makeatletter +\ifx\documentclass\@twoclasserror\else + \expandafter\@firstofone +\fi{% + \makeatother + %% we are either \RequirePackage'd + %% (which we won't support) or compiled directly. + %% If we are compiled directly, yield the manual. + %% Otherwise, this looks like a debugging session + %% that directly uses the dtx file instead of the sty. + \input{thmtools-manual.tex} + \endinput +} +%</driver> +%<*thmtools> +%\fi +% \begin{macrocode} +\DeclareOption{debug}{% + \def\thmt@debug{\typeout}% +} +% common abbreviations and marker macros. +\let\@xa\expandafter +\let\@nx\noexpand +\def\thmt@debug{\@gobble} +\def\thmt@quark{\thmt@quark} +\newtoks\thmt@toks + +\@for\thmt@opt:=lowercase,uppercase,anycase\do{% + \@xa\DeclareOption\@xa{\thmt@opt}{% + \@xa\PassOptionsToPackage\@xa{\CurrentOption}{thm-kv}% + }% +} + +\ProcessOptions\relax + +% a scratch counter, mostly for fake hyperlinks +\newcounter{thmt@dummyctr}% +\def\theHthmt@dummyctr{dummy.\arabic{thmt@dummyctr}}% +\def\thethmt@dummyctr{}% + + +\RequirePackage{thm-patch, thm-kv, + thm-autoref, thm-listof, + thm-restate} + +% Glue code for the big players. +\@ifpackageloaded{amsthm}{% + \RequirePackage{thm-amsthm} +}{% + \AtBeginDocument{% + \@ifpackageloaded{amsthm}{% + \PackageWarningNoLine{thmtools}{% + amsthm loaded after thmtools + }{}% + }{}}% +} +\@ifpackageloaded{ntheorem}{% + \RequirePackage{thm-ntheorem} +}{% + \AtBeginDocument{% + \@ifpackageloaded{ntheorem}{% + \PackageWarningNoLine{thmtools}{% + ntheorem loaded after thmtools + }{}% + }{}}% +} +\@ifclassloaded{beamer}{% + \RequirePackage{thm-beamer} +}{} +\@ifclassloaded{llncs}{% + \RequirePackage{thm-llncs} +}{} +% \end{macrocode} + +%\iffalse +%</thmtools> +%\fi diff --git a/macros/latex/contrib/thmtools/source/thmtools.ins b/macros/latex/contrib/thmtools/source/thmtools.ins new file mode 100644 index 0000000000..461856c73c --- /dev/null +++ b/macros/latex/contrib/thmtools/source/thmtools.ins @@ -0,0 +1,64 @@ +%% +%% This is a bog-standard .ins file: thmtools.ins +%% +\input VERSION.tex +%\show\VERSION +\def\dropext #1.#2\relax{#1} +\input docstrip.tex +%\keepsilent +\askonceonly +\preamble +This is a generated file. + +This file is part of the `thmtools' package. +The `thmtools' package has the LPPL maintenance status: maintained. +Current Maintainer is Yukai Chou, muzimuzhi@gmail.com + +Copyright (C) 2008-2014 by Ulrich M. Schwarz +Copyright (C) 2019 by Frank Mittelbach +Copyright (C) 2020- by Yukai Chou + +This file may be distributed and/or modified under the +conditions of the LaTeX Project Public License, version 1.3c. +This version is obtainable at +http://www.latex-project.org/lppl/lppl-1-3c.txt + +^^J\noexpand\noexpand\noexpand\NeedsTeXFormat{LaTeX2e}^^J\noexpand\noexpand\noexpand\ProvidesPackage{\noexpand\expandafter\noexpand\dropext\outFileName\relax}[\VERSION] +\endpreamble + +\generate{% + \file{thmtools.sty} {\from{thmtools.dtx}{thmtools}} + \file{thm-restate.sty} {\from{thm-restate.dtx}{restate}} + \file{thm-patch.sty} {\from{thm-patch.dtx}{patch}} + \file{thm-autoref.sty} {\from{thm-autoref.dtx}{autoref}} + \file{thm-listof.sty} {\from{thm-listof.dtx}{listof}} + \file{thm-kv.sty} {\from{thm-kv.dtx}{kv}} + \file{parseargs.sty} {\from{parseargs.dtx}{parseargs}} + \file{aliasctr.sty} {\from{aliasctr.dtx}{code}} + \file{unique.sty} {\from{unique.dtx}{code}} + \file{thm-amsthm.sty} {\from{thm-amsthm.dtx}{amsthm}} + \file{thm-ntheorem.sty} {\from{thm-ntheorem.dtx}{ntheorem}} + \file{thm-beamer.sty} {\from{thm-beamer.dtx}{beamer}} + \file{thm-llncs.sty} {\from{thm-llncs.dtx}{llncs}} + \file{thmdef-shaded.sty} {\from{thmdef-shaded.dtx}{shaded}} + \file{thmdef-thmbox.sty} {\from{thmdef-thmbox.dtx}{thmbox}} + \file{thmdef-mdframed.sty}{\from{thmdef-mdframed.dtx}{mdframed}} +} +\Msg{*********************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the} +\Msg{* following files into a directory searched by TeX:} +\Msg{*} +\Msg{* \space\space thmtools.sty} +\Msg{* \space\space thm-restate.sty} +\Msg{* \space\space thm-patch.sty} +\Msg{* \space\space thm-autoref.sty} +\Msg{* \space\space thm-listof.sty} +\Msg{* \space\space thm-kv.sty} +\Msg{* \space\space aliasctr.sty} +\Msg{* \space\space unique.sty} +\Msg{* \space\space parseargs.sty} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*********************************************************} +\endbatchfile diff --git a/macros/latex/contrib/thmtools/source/unique.dtx b/macros/latex/contrib/thmtools/source/unique.dtx new file mode 100644 index 0000000000..bf013ca6d4 --- /dev/null +++ b/macros/latex/contrib/thmtools/source/unique.dtx @@ -0,0 +1,175 @@ +% \iffalse meta-comment +% +% Copyright (C) 2005-2014 by Ulrich M. Schwarz +% Copyright (C) 2019 by Frank Mittelbach +% Copyright (C) 2020- by Yukai Chou +% +% This file may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, version 1.3c. +% The license can be obtained from +% http://www.latex-project.org/lppl/lppl-1.3c.txt +% +% \fi +% +%\iffalse +%<*code> +%\fi +% Two macros are provided: |\setuniqmark| takes a single parameter, +% the name, which should be a string of letters. |\ifuniqmark| takes +% three parameters: a name, a true-part and a false-part. The true +% part is executed if and only if there was exactly one call to +% |\setuniqmark| with the given name during the previous \LaTeX\ run. +% +% Example application: legal documents are often very strongly numbered. +% However, if a section has only a single paragraph, this paragraph is +% not numbered separately, this only occurs from two paragraphs onwards. +% +% It's also possible to not-number the single theorem in your paper, but +% fall back to numbering when you add another one. +% +% \StopEventually{} +% +% \begin{macrocode} + +\DeclareOption{unq}{% + \newwrite\uniq@channel + \InputIfFileExists{\jobname.unq}{}{}% + \immediate\openout\uniq@channel=\jobname.unq + \AtEndDocument{% + \immediate\closeout\uniq@channel% + } +} +\DeclareOption{aux}{% + \let\uniq@channel\@auxout +} + +% \end{macrocode} +% +% +% \iffalse $Id: unique.dtx,v 1.4 2010/04/25 19:37:46 ulmi Exp $\fi +% \begin{macro}{\setuniqmark} +% Call this with a name to set the corresponding uniqmark. The name must +% be suitable for |\csname|-constructs, i.e. fully expansible to a +% string of characters. If you use some counter values to generate this, +% it might be a good idea to try and use hyperref's |\theH...| macros, +% which have similar restrictions. You can check whether a particular +% |\setuniqmark| was called more than once during \emph{the last run} +% with |\ifuniq|. +% \begin{macrocode} +\newcommand\setuniqmark[1]{% + \expandafter\ifx\csname uniq@now@#1\endcsname\relax + \global\@namedef{uniq@now@#1}{\uniq@ONE}% + \else + \expandafter\ifx\csname uniq@now@#1\endcsname\uniq@MANY\else + \immediate\write\uniq@channel{% + \string\uniq@setmany{#1}% + }% + \ifuniq{#1}{% + \uniq@warnnotunique{#1}% + }{}% + \fi + \global\@namedef{uniq@now@#1}{\uniq@MANY}% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ifuniq} +% Companion to |\setuniqmark|: if the uniqmark given in the first +% argument was called more than once, execute the second argument, +% otherwise execute the first argument. Note than no call to +% |\setuniqmark| for a particular uniqmark at all means that this +% uniqmark is unique. +% +% This is a lazy version: we could always say false if we already had two calls +% to setuniqmark this run, but we have to rerun for any ifuniq prior +% to the first setuniqmark anyway, so why bother? +% \begin{macrocode} +\newcommand\ifuniq[1]{% + \expandafter\ifx\csname uniq@last@#1\endcsname\uniq@MANY + \expandafter \@secondoftwo + \else + \expandafter\@firstoftwo + \fi +} +% \end{macrocode} +% \end{macro} +% +% Two quarks to signal if we have seen an uniqmark more than once. +% \begin{macrocode} +\def\uniq@ONE{\uniq@ONE} +\def\uniq@MANY{\uniq@MANY} +% \end{macrocode} +% Flag: suggest a rerun? +% \begin{macrocode} +\newif\if@uniq@rerun +% \end{macrocode} +% +% Helper macro: a call to this is written to the .aux file when we see +% an uniqmark for the second time. This sets the right information for +% the next run. It also checks on subsequent runs if the number of +% uniqmarks drops to less than two, so that we'll need a rerun. +% \begin{macrocode} +\def\uniq@setmany#1{% + \global\@namedef{uniq@last@#1}{\uniq@MANY}% + \AtEndDocument{% + \uniq@warnifunique{#1}% + }% +} +% \end{macrocode} +% +% Warning if something is unique now. This always warns if the +% setting for this run is not ``many'', because it was generated +% by a setmany from the last run. +% \begin{macrocode} +\def\uniq@warnifunique#1{% + \expandafter\ifx\csname uniq@now@#1\endcsname\uniq@MANY\else + \PackageWarningNoLine{uniq}{% + `#1' is unique now.\MessageBreak + Rerun LaTeX to pick up the change% + }% + \@uniq@reruntrue + \fi +} +% \end{macrocode} +% +% Warning if we have a second uniqmark this run around. Since this is +% checked immediately, we could give the line of the second +% occurence, but we do not do so for symmetry. +% \begin{macrocode} +\def\uniq@warnnotunique#1{% + \PackageWarningNoLine{uniq}{% + `#1' is not unique anymore.\MessageBreak + Rerun LaTeX to pick up the change% + }% + \@uniq@reruntrue +} +% \end{macrocode} +% +% Maybe advise a rerun (duh!). This is executed at the end of the +% second reading of the aux-file. If you manage to set uniqmarks +% after that (though I cannot imagine why), you might need reruns +% without being warned, so don't to that. +% \begin{macrocode} +\def\uniq@maybesuggestrerun{% + \if@uniq@rerun + \PackageWarningNoLine{uniq}{% + Uniquenesses have changed. \MessageBreak + Rerun LaTeX to pick up the change% + }% + \fi +} +% \end{macrocode} +% +% Make sure the check for rerun is pretty late in processing, so it +% can catch all of the uniqmarks (hopefully). +% \begin{macrocode} +\AtEndDocument{% + \immediate\write\@auxout{\string\uniq@maybesuggestrerun}% +} +\ExecuteOptions{aux} +\ProcessOptions\relax +% \end{macrocode} +%\iffalse +%</code> +%\fi |