summaryrefslogtreecommitdiff
path: root/macros/latex/exptl/thmtools/thm-kv.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/exptl/thmtools/thm-kv.dtx')
-rw-r--r--macros/latex/exptl/thmtools/thm-kv.dtx486
1 files changed, 486 insertions, 0 deletions
diff --git a/macros/latex/exptl/thmtools/thm-kv.dtx b/macros/latex/exptl/thmtools/thm-kv.dtx
new file mode 100644
index 0000000000..1e7e358082
--- /dev/null
+++ b/macros/latex/exptl/thmtools/thm-kv.dtx
@@ -0,0 +1,486 @@
+% \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)
+%<*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
+ \noexpand\KVS@ProcessorDefault{#1}{\etex@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