summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/coolthms/coolthms.dtx
blob: 8212c0621ac886f3ef4c65a4406a9ec50c414a66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
% \iffalse meta-coment:
%
% The coolthms package
%
% \fi
%
% ^^A Driver stuff:
% \iffalse not to be used in package ....
%<*driver>
\documentclass[a4paper]{ltxdoc}
\usepackage{ifxetex}
\usepackage{hypdoc}
\ifxetex
  \usepackage[no-math]{fontspec}
  \usepackage{polyglossia}
  \setmainfont[Mapping=tex-text,Numbers=OldStyle]{Linux Libertine O}
  \setsansfont[Mapping=tex-text,Numbers=OldStyle]{Linux Biolinum O}
  \setdefaultlanguage{english}
\else
  \usepackage[utf8]{inputenc}
  \usepackage[T1]{fontenc}
  \usepackage[english]{babel}
\fi
\usepackage{etoolbox}
\usepackage{textcomp}
\usepackage{enumitem}
\usepackage{csquotes}
\usepackage{fancyvrb}
\PassOptionsToPackage{nameinlink}{cleveref}
\usepackage{coolthms}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{coolthms.dtx}
\end{document}
%</driver>
% \fi
%
% \iffalse package preamble
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{coolthms}[2013/02/04 v1.2 Theorem markup and advanced referencing]
% \fi
%
% \MakeShortVerb{\"}
%
% \newcommand{\ctp}{\texttt{coolthms}}
% \newenvironment{syntax}{\medskip\hspace*{1em}}{\par\medskip}
% \setenumerate[1]{leftmargin=*,labelindent=\parindent,label=(\alph*)}
% \setenumerate[2]{leftmargin=*,labelindent=\parindent,label=(\roman*),ref=\theenumi~(\roman*)}
% \AfterEndEnvironment{verbatim}{\vspace*{-11pt}}
%
% \GetFileInfo{coolthms.sty}
%
% \VerbatimFootnotes
%
% \title{The \ctp{} Package}
% \author{Jonathan Zachhuber\thanks{\url{jonathan.zachhuber@gmail.com}} \and Michael Fütterer\thanks{\url{michaelfuetterer@gmail.com}}}
% \date{Version \fileversion, \filedate}
%
% \maketitle
%
% \begin{abstract}
%   This package makes it possible to directly reference "\item"s
%   in theorem-like environments using the "ntheorem" and "cleveref" packages.
% \end{abstract}
%
% \tableofcontents
%
% \section{Overview}
%
% Especially when typesetting lecture notes, one encounters
% situations such as\\[3pt]
% "\begin{theorem}\label{thm1}"\\
% "\begin{enumerate}"\\
%  \hspace*{10pt}"\item\label{1.1}" First point.\\
%  \hspace*{10pt}"\item\label{1.2}" Second point.\\
% "\end{enumerate}"\\"\end{theorem}"\\[3pt]
% and would subsequently like to write something like "\ref{1.1}"
% to get something of the form `Theorem 1 (a)'.
%
% This, however, is not possible. Of course, one could retreat to 
% writing something like "\ref{thm1}~\ref{1.1}", but this is no satisfactory solution.
%
% \DescribeMacro{\Label}
% The \ctp{} package therefore provides the "\Label" command to create a special kind of label that internally saves the name and number of a possible "theorem"-like environment enclosing it.
%
% In our above example, one could now write\\[3pt]
% "\begin{theorem}\label{thm1}"\\
% "\begin{enumerate}"\\
%  \hspace*{10pt}"\item\Label{1.1}" First point.\\
%  \hspace*{10pt}"\item\Label{1.2}" Second point.\\
% "\end{enumerate}"\\"\end{theorem}"\\[3pt]
% and then "\cref{1.1}" provides the desired result. See \cref{examples} for some concrete examples.
%
% \DescribeMacro{\definetheorem}
% For this to work, one needs to define the theorem-like environments with the new "\definetheorem" command. This is simply an extension of "ntheorem"'s "\newtheorem" command.
%
% \section{Usage}
%
% \subsection{Main Commands}
%
% The \ctp{} package only defines three useful commands and uses one from the "cleveref" package.
%
% \DescribeMacro{\theoremmarkup} This command changes the formatting of theorems. It is explained in \cref{format}.
%
% \DescribeMacro{\definetheorem} The "\definetheorem" command expands "ntheorem"'s "\newtheorem" by saving information later to be used in generating the labels. The syntax is as follows:
%
% \begin{syntax}"\definetheorem["\meta{counter1}"]{"\meta{env name}"}["\meta{thm plural name}"]"\\
% \hspace*{.3\textwidth}"{"\meta{thm name}"}["\meta{counter2}"]"\end{syntax}
%
% \noindent This command defines \emph{two} environments, \meta{env name} and "n"\meta{env name}. The first one is for numbered theorems, the second one is an unnumbered version. The displayed name of the theorem is \meta{thm name}. You can optionally give the plural form \meta{thm plural name}, which will be used if several theorems of this type are referenced at any one time.
% 
% The counter arguments are similar to those of "\newtheorem". The \meta{counter1} is the counter that is used for this type of theorem. The package creates a dummy counter, named "thmcnt", and this is the default value of \meta{counter1}. Hence, the default setting is for all different types of theorems to be numbered consecutively. If you want to number some type of theorem seperately, you should specify a new counter name via the optional argument \meta{counter1}; if the counter does not exist, it will be created. You can also provide the counter of another theorem environment, to group several types of theorem together.
%
% The \meta{counter2} is a counter that resets \meta{counter1} every time it is incremented. Its default value is "section", so the theorems are numbered within sections and \meta{counter1} is reset to $0$ whenever a new section starts. If you want a theorem type to be numbered document-wide without the counter being reset at any time, you should give an empty \meta{counter2} argument.
%
% The default numbering of the theorem environment is \meta{counter2}.\meta{counter1}. See \cref{examples} for concrete examples.
%
% \DescribeMacro{\Label} The "\Label" command replaces (or re-implements) the `conventional' "\label" command and is to be used \emph{only} inside theorem-like environments (which were previously defined with "\definetheorem"!). The "\label" command can (and should) of course still be used, if no special behaviour is desired\footnote{Actually, if you use the "Label" command inside an unnested theorem environment, or for the theorem itself, it will simply display the theorem number twice as the counter is used both in the reference name and, of course, the reference counter. See \cref{implementation}.}. The syntax is exactly the same as for "\label":
%
% \begin{syntax}"\Label"\marg{label name}\end{syntax}
%
% \DescribeMacro{\cref}
% The labels thus defined should then be referenced with:
%
% \begin{syntax}"\cref"\marg{label name}\end{syntax}
%
% \noindent This is the "cleveref" `version' of "\ref" and is being used here without being altered in any way.
%
% \subsection{Package Options}
%
% The package can be called with several options, which are listed in the table below.
%
% \medskip
%
% \noindent
% \begin{tabular}{p{.25\textwidth} p{.15\textwidth} p{.5\textwidth}}
%  \hline
%  Option & Default value & Description\\
%  \hline\hline
%  "indent"            & "0em"        & The space every theorem's \emph{content} will be indented. \\
%  "separator"         & ":"          & The punctuation sign that will be printed after the caption. \\
%  "proofname"         & "\proofname" & The caption for proofs. \\
%  "proofsymbol"       & "$\Box$"     & The symbol that will be printed at the end of proofs. \\
%  "proofcaptionstyle" & "\it"        & The font shape in which the caption for proofs (as given in "proofname") is printed. \\
%  "proofindent"       & "indent"     & The space proofs will be indented. \\
%  "minskip"           & "0pt"        & The minimal theorem pre- and post skip amount. \\
%  "maxskip"           & "6pt"        & The maximal theorem pre- and post skip amount. \\
%  "externalchapters"  & "False"      & Turn on external chapter mode (see below). \\
%  \hline
% \end{tabular}
%
% \medskip
%
% Note that the "\proofname" macro is defined by "babel" or "polyglossia" and is a language-specific string containing the proof name. If none of these package is loaded, we define "\proofname" just as \enquote{Proof} and use that as a default value. If no value is supplied for "proofindent", proofs are indented the same amount as all other theorems (i.e. the default value is taken from "indent").
%\changes{v1.1}{2012/04/01}{Included new default value of "proofindent" in option description list.}
%
% \DescribeMacro{externalchapters} When the (boolean) option "externalchapters" is given \emph{and} you use a document class that has chapters, a special behaviour is turned on (if there are no chapters, nothing happens). Usually, sections are numbered within chapters by \meta{chapter number}.\meta{section number}. Consequently, when numbering theorem-like environments within a section (which is the default behaviour), such an environment gets the number \meta{chapter number}.\meta{section number}.\meta{thm number}.
%
% In the external chapter mode, however, section numbers are \emph{not} preceded by the chapter number, i.e. they are numbered by a \emph{single} (arabic) number (it follows that subsections then have only two numbers instead of three, and so on). To avoid having chapters and sections with the same numbers, chapters are numbered by roman numerals in this mode (if you don't like this, you can change it by redefining "\thechapter"). Consequently theorems are then numbered by \meta{section number}.\meta{thm number}, without any reference to the chapter in their number. Therefore, there can be theorems that have the same number (if they are in the same section in different chapters). To avoid confusion, in external chapter mode, in every reference to anything that is in another chapter as the current one, the number for whatever we are referring to is additionally preceded by the chapter number (except when referencing a chapter). When referring to something from the current chapter, the chapter number is omitted.
%\changes{v1.2}{2013/02/04}{Included new option "externalchapters".}
%
% \subsection{Formatting Details}\label{format}
%
% \DescribeMacro{\theoremmarkup} The "\theoremmarkup" command is used to describe how your theorems will be formatted. It should be
% called prior to any "\definetheorem" command. All theorems you define afterwards with "\definetheorem" will be formatted in
% the way you have set with "\theoremmarkup", until you invoke "\theoremmarkup" again to change these values. The syntax is:
%
% \begin{syntax}"\theoremmarkup"\oarg{header font}\oarg{body font}\oarg{symbol}\\
% \hspace*{.3\textwidth}\oarg{indentation}\oarg{separator}\oarg{numbering}\end{syntax}
% 
% \noindent All these parameters are optional and have the following default values:
% 
% \medskip
% 
% \begin{center}
% \begin{tabular}{p{.2\textwidth} p{.5\textwidth}}
%  \hline
%  Option & Default value \\
%  \hline\hline
%  "header font"      & "\bf" \\
%  "body font" & "\normalfont" \\
%  "symbol" & "\relax" \\
%  "intendation" & the value of the package option "indent" \\
%  "separator"    & ":" \\
%  "numbering" & "arabic" \\
%  \hline
% \end{tabular}
% \end{center}
% 
% \medskip
% 
% \noindent For more detailed information about these parameters, see the documentation of the "ntheorem" package.
%
% \DescribeMacro{\theoremstyle\{mitnummern\}}
% \DescribeMacro{\theoremstyle\{keinenummern\}}
% \DescribeMacro{\theoremstyle\{unserbeweis\}}
% The package also provides (and uses with "\definetheorem") three new theorem styles. They provide a numbered and an unnumbered
% theorem style, as well as one intended for proofs. They respect "ntheorem"'s "\theoremheaderfont" but put the optional title
% addon in parentheses and "\normalfont". See \cref{implementation} for details.
% 
% \DescribeEnv{proof}
% The package also defines a theorem environment intended for proofs, which is called "proof".
%
%
% \section{Examples}\label{examples}
%
% We define a theorem enviroment "thm" with caption \enquote{Theorem}:
%
% \begin{verbatim}
% \definetheorem{thm}{Theorem}
% \end{verbatim}
% \definetheorem{thm}{Theorem}
%
% Now we use this environment to typeset a theorem:
%
% \begin{verbatim}
% \begin{thm}\label{testthm}
%   This is a theorem.
% \end{thm}
% \end{verbatim}
% \begin{thm}\label{testthm}
%   This is a theorem.
% \end{thm}
% Notice that here we use the conventional "\label" command, as we are not in a nested situation.
%
% Now we'll define -- and then use -- a more fancy theorem environment, "fancythm". Before doing that, we invoke "\theoremmarkup":
% \begin{verbatim}
% \theoremmarkup[\sc][\it][\textleaf][3em][.][Roman]
% \definetheorem{fncythm}{Fancy Theorem}
% \begin{fncythm}[Title]
%   The \ctp{} package is a very useful package for typesetting theorems.
%   This theorem is a long one, and we can see that its content is indented.
%   We furthermore have an enumerated list of claims.
%   \begin{enumerate}
%   \item\Label{claim1} Claim 1
%   \item\Label{claim2} Claim 2
%   \end{enumerate}
% \end{fncythm}
% \end{verbatim}
% Thus the header font will be small caps, the body font will be italic, each fancy theorem will be ended by a leaf symbol, its content will be indented "3em", the punctuation sign after its caption will be a period, and the numbering will be Roman. Note that -- by default -- we use the same numbering as \cref{testthm}\footnote{This is just "\cref{testthm}".}. And indeed:
%
% \theoremmarkup[\sc][\it][\textleaf][3em][.][Roman]
% \definetheorem{fncythm}{Fancy Theorem}
% \begin{fncythm}[Title]
%   The \ctp{} package is a very useful package for typesetting theorems.
%   This theorem is a long one, and we can see that its content is indented.
%   We furthermore have an enumerated list of claims.
%   \begin{enumerate}
%   \item\Label{claim1} Claim 1
%   \item\Label{claim2} Claim 2
%   \end{enumerate}
% \end{fncythm}
% 
% Finally, by writing "\cref{claim1}", we get what we wanted: \cref{claim1}.
%
% This even works for nested "enumerate"s. However, we recommend using the "enumitem" package to improve the appeareance of the reference. For example, when we define
% \begin{verbatim}
% \usepackage{enumitem}
% \setenumerate[1]{leftmargin=*,labelindent=\parindent,label=(\alph*)}
% \setenumerate[2]{leftmargin=*,labelindent=\parindent,label=(\roman*),%
%     ref=\theenumi~(\roman*)}
% \end{verbatim}
% and we have a theorem
% \begin{verbatim}
% \begin{thm}
%   Test theorem.
%   \begin{enumerate}
%   \item First point.
%     \begin{enumerate}
%     \item First sub-point.
%     \item\Label{testlabel} Second sub-point.
%     \end{enumerate}
%   \item Second point.
%   \end{enumerate}
% \end{thm}
% \end{verbatim}
% \begin{thm}
%   Test theorem.
%   \begin{enumerate}
%   \item First point.
%     \begin{enumerate}
%     \item First sub-point.
%     \item\Label{testlabel} Second sub-point.
%     \end{enumerate}
%   \item Second point.
%   \end{enumerate}
% \end{thm}
% then writing "\cref{testlabel}" correctly yields \cref{testlabel}.
% 
% \section{Interaction with other packages}
%
% To achieve its goals, "coolthms" relies on several other packages, some of which are quite picky. Most notably, we use the "cleveref" package, which likes to be loaded at quite a late point in the document head (please refer to "cleveref"'s package documentation for a detailed account of its interaction with other packages).
%
% In general, you will be on the safe side if "coolthms" is the last package you load. If you want to use the language-specific "\sectionname" commands, you should definitely load it \emph{after} "babel" or "polyglossia", otherwise they will have no effect.
%
% Since we use the "ntheorem" package, "coolthms" \emph{must} be loaded \emph{after} "amsmath", if this is used. The package works with and without "amsmath", though.
%
% \section{Implementation}\label{implementation}
%
% First we load the packages we'll be needing. 
%
% Before loading the amssymb package, we need to undefine some commands to avoid errors.
%    \begin{macrocode}
\let\Finv\@undefined
\let\Game\@undefined
\let\beth\@undefined
\let\gimel\@undefined
\let\daleth\@undefined
\RequirePackage{amssymb}
%    \end{macrocode}
% "hyperref" support is always good when linking stuff, we need lots of little "etoolbox" macros and "xargs" as well as "kvoptions" for our argument and option processing.
%    \begin{macrocode}
\RequirePackage{hyperref}
\RequirePackage{etoolbox}
\RequirePackage{scrbase} % for \ifstr string comparison macro
\RequirePackage{letltxmacro}
\RequirePackage{ifthen}
\RequirePackage{xargs}
\RequirePackage{kvoptions}
%    \end{macrocode}
% We then check if "amsmath" has been loaded, so we know if to invoke the "amsmath" option in "ntheorem".
%    \begin{macrocode}
\@ifpackageloaded{amsmath}
  {\RequirePackage[thmmarks,amsmath,hyperref]{ntheorem}}
  {\RequirePackage[thmmarks,hyperref]{ntheorem}}
%    \end{macrocode}
% Note that the "cleveref" package must be loaded \emph{after} the "ntheorem" package.
%    \begin{macrocode}
\RequirePackage{cleveref}
%    \end{macrocode}
% \begin{macro}{\ctp@hashchar}
% In order to write a verbatim `hash' sign into our files later, it's practical to write the "\catcode" change into a small macro:
%    \begin{macrocode}
\begingroup
\catcode`\#=12
\gdef\ctp@hashchar{#}%
\endgroup
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\proofname}
% We provide options for the proofname, the theorem separator, the proof end symbol and the amount to indent theorem content. The default value of "proofname" should be "\proofname", which is set by "babel" or "polyglossia". If the command is not defined, we simply define it as \enquote{Proof}. The value of "proofindent" is set to that of "indent" if none is specified.
%
% \changes{v1.2}{2012/04/23}{Fixed bug concerning proofname}
% There's a funny aspect of using "\proofname" here: If your proof environment is named \enquote{proof}, then we have a problem, because if it's ever called with an \emph{optional} argument, "ntheorem" defines the \emph{internal} command "\proofname" to be the optional argument just passed to the environment. This results in \emph{all} proofs after this to have \emph{only} the optional argument of \emph{this} proof as their title!
%
% \begin{macro}{\ctp@temp}
% To solve this, we simply expand "\proofname", revealing the string behind it. The only problem is that if we do so immediately, we might miss any change of language, i.e. a \enquote{legal} change of "\proofname" by "polyglossia" or "babel". Therefore, we define "\ctp@temp" to be an unexpanded "\proofname" first and -- using "\AtBeginDocument" -- substitute that for an expanded version and do so \emph{every time the language is changed}. Then, at the end of a proof, we simply substitute the \enquote{real} "\proofname" for the one just created by the "proof" environment.
%    \begin{macrocode}
\@ifundefined{proofname}{\newcommand{\proofname}{Proof}}{}
\let\ctp@temp\proofname\relax
\AtBeginDocument{\edef\ctp@temp{\proofname}%
   \apptocmd{\select@language}{\edef\ctp@temp{\proofname}}{}{}}
\AfterEndEnvironment{proof}{\gdef\proofname{\ctp@temp}}
\DeclareStringOption[\ctp@temp]{proofname}
\DeclareStringOption[$\Box$]{proofsymbol}
\DeclareStringOption[\it]{proofcaptionstyle}
\DeclareStringOption[\coolthms@indent]{proofindent}
\DeclareStringOption[:]{separator}
\DeclareStringOption[0em]{indent}
\DeclareStringOption[0pt]{minskip}
\DeclareStringOption[6pt]{maxskip}
\DeclareBoolOption{externalchapters}
\DeclareLocalOptions{separator,indent,minskip,maxskip%
  proofname,proofsymbol,proofcaptionstyle,proofindent,externalchapters}
\ProcessKeyvalOptions*
%    \end{macrocode}
% \changes{v1.1}{2012/04/01}{Default value for "proofindent" is "indent".}
% \end{macro}\end{macro}
%
% If there are no chapters (e.g. article class), we should manually create that counter and set it to 1, as we need that in the name of our label:
%    \begin{macrocode}
\@ifundefined{c@chapter}{%
  \newcounter{chapter}%
  \setcounter{chapter}{1}%
}{}%
%    \end{macrocode}
% We now handle external chapters. If these were requested, "\thesection" should be redefined to contain only a single number.
%    \begin{macrocode}
\ifcoolthms@externalchapters
\renewcommand{\thechapter}{\Roman{chapter}}
\renewcommand{\thesection}{\arabic{section}}
%    \end{macrocode}
% Next, we overwrite some definitions made by "cleveref", namely "\refstepcounter@noarg" and "\refstepcounter@optarg" (which together are used by "cleveref" to redefine the "\refstepcounter" macro). These are invoked when a counter is incremented, and create "\cref@currentlabel". This definition is altered by us to contain a conditional which might print the chapter number. However, we repeat "cleveref"'s original definition of "\cref@currentlabel" to define "\cref@old@currentlabel", which we will need later to define the "\Label" command. The last "\ifstr" command ensures that no extra chapter number is printed when referring a chapter.
%
% Note that we are still in the external chapters case.
%    \begin{macrocode}
\def\refstepcounter@noarg#1{%
  \cref@old@refstepcounter{#1}%
  \cref@constructprefix{#1}{\cref@result}%
  \@ifundefined{cref@#1@alias}%
    {\def\@tempa{#1}}%
    {\def\@tempa{\csname cref@#1@alias\endcsname}}%
  \edef\chapter@current@value{\the\value{chapter}}
  \protected@edef\cref@currentlabel{%
    [\@tempa][\arabic{#1}][\cref@result]%
    \string\ifstr{\string\the\string\value{chapter}}%
    {\chapter@current@value}{\string\relax}{\thechapter.}%
    \csname p@#1\endcsname\csname the#1\endcsname}
  \protected@edef\cref@old@currentlabel{%
    [\@tempa][\arabic{#1}][\cref@result]%
    \csname p@#1\endcsname\csname the#1\endcsname}
  \ifstr{\@tempa}{chapter}{\protected@edef\cref@currentlabel{\cref@old@currentlabel}}{}}
\def\refstepcounter@optarg[#1]#2{%
  \cref@old@refstepcounter{#2}%
  \cref@constructprefix{#2}{\cref@result}%
  \edef\chapter@current@value{\the\value{chapter}}
  \protected@edef\cref@currentlabel{%
    [#1][\arabic{#2}][\cref@result]%
    \string\ifstr{\string\the\string\value{chapter}}%
    {\chapter@current@value}{\string\relax}{\thechapter.}%
    \csname p@#2\endcsname\csname the#2\endcsname}
  \protected@edef\cref@old@currentlabel{%
    [#1][\arabic{#2}][\cref@result]%
    \csname p@#2\endcsname\csname the#2\endcsname}
  \ifstr{#1}{chapter}{\protected@edef\cref@currentlabel{\cref@old@currentlabel}}{}}
%    \end{macrocode}
% Next we redefine the "label" command.
% We are still in the external chapters case.
%    \begin{macrocode}
    \def\ctp@label@noarg#1{%
    \letcs{\mycurrentlabel}{@currentlabel}
    \expandafter\def\csname @currentlabel\endcsname{\string\ifstr%
      {\string\the\string\value{chapter}}{\the\value{chapter}}%
      {\string\relax}{\thechpt}\mycurrentlabel}
    \label@noarg{#1}
    \cslet{@currentlabel}{\mycurrentlabel}
    }%
    \def\ctp@label@optarg[#1]#2{%
    \letcs{\mycurrentlabel}{@currentlabel}
    \expandafter\def\csname @currentlabel\endcsname{\string\ifstr%
      {\string\the\string\value{chapter}}{\the\value{chapter}}%
      {\string\relax}{\thechpt}\mycurrentlabel}
    \label@optarg[#1]{#2}
    \cslet{@currentlabel}{\mycurrentlabel}
    \def\label{\@ifnextchar[\ctp@label@optarg\ctp@label@noarg}%]
    }
%    \end{macrocode}
% This is where the external chapters case ends.
%    \begin{macrocode}
\else % belongs to \ifcoolthms@externalchapters
\fi
%    \end{macrocode}
% Now we need to define various (an unnumbered, a numbered and a third one for proofs) "theoremstyle"s\footnote{Here we use the "ntheorem" package.} we will be using:
%    \begin{macrocode}
\newtheoremstyle{keinenummern}%
  {\item[\hskip\labelsep\theorem@headerfont ##1\theorem@separator]}%
  {\item[\hskip\labelsep\theorem@headerfont ##1\ %
    {\normalfont(##3)}\theorem@separator]}
\newtheoremstyle{mitnummern}%
  {\item[\hskip\labelsep\theorem@headerfont ##1\ ##2\theorem@separator]}%
  {\item[\hskip\labelsep\theorem@headerfont ##1\ ##2\ %
    {\normalfont(##3)}\theorem@separator]}
\newtheoremstyle{unserbeweis}%
  {\item[{\hskip\labelsep\theorem@headerfont ##1\theorem@separator}]}%
  {\item[\hskip\labelsep{\theorem@headerfont ##3\theorem@separator}]}
%    \end{macrocode}
% \begin{macro}{\definetheorem}
% Now comes the real work: the "\definetheorem" command. "\definetheorem" takes five arguments and passes them to "ntheorem"'s "\newtheorem" in a slightly altered order. We then create a numbered theorem style by name of "#2" and an unnumbered style by name of "n#2". This is necessary as the starred versions have a different meaning in the "ntheorem" package.
%
% The optional arguments are first checked (i.e. nothing happens if they are not set) and then passed to "\newtheorem" to create the dummy counters that will later be used for numbering the environments.
%
%    \begin{macrocode}
\newcommandx*{\definetheorem}[5][1=thmcnt,3=,5=section]{
  \@ifundefined{c@#1}{
    \@ifundefined{c@#5}{
      \newtheorem{#1}{#1}
    }{
      \newtheorem{#1}{#1}[#5]
    }
  }{}
  \theoremstyle{mitnummern}
  \newtheorem{#2}[#1]{#4}
  \theoremstyle{keinenummern}
  \newtheorem{n#2}[#1]{#4}
%    \end{macrocode}
% When simply referring to the environment (i.e. something from a "\label", not "\Label" command!), we want the reference to
% consist of `\meta{theorem name} \meta{theorem number}' and all of it should be a hyperlink. "\crefname" takes three arguments: The name of the theorem environment, the singular and plural form of the theorem name. These are stored in "#2", "#4" and "#3", respectively. If no plural form is given, i.e. "#3" is undefined, we simply replace it with its singular form ("#4"): 
%    \begin{macrocode}
  \ifblank{#3}{
    \crefname{#2}{#4}{#4}
  }{
    \crefname{#2}{#4}{#3}
  }
  \crefformat{#2}{##2#4~##1##3}
%    \end{macrocode}
% In the unnumbered version we need to subtract $1$ from the counter, as it is nonetheless incremented.
%    \begin{macrocode}
  \BeforeBeginEnvironment{n#2}{\addtocounter{#1}{-1}}
%    \end{macrocode}
% \begin{macro}{\ctp@labelcode}
% Now, every time we call our new theorem environment, we want to create a new \emph{unique} label ("\ctp@labelcode"), which we can then use as the label of the nested "enumerate" environments. However, at this point the counter "#1" has not been incremented yet, so we need to do (and later undo) this.
%    \begin{macrocode}
  \BeforeBeginEnvironment{#2}{%
     \addtocounter{#1}{1}%
     \edef\ctp@labelcode%
        {ctp@#2@\roman{chapter}@\roman{section}@\arabic{#1}}\relax%
%    \end{macrocode}
% \end{macro}
% We then write all this information (including the \emph{format} of the label) to the "aux" file so that it is available at the next run of \LaTeX.
%    \begin{macrocode}
\ifcoolthms@externalchapters
     \immediate\write\@auxout{\string\crefname{\ctp@labelcode}%
               {#4\noexpand~%
                 \string\ifstr{\string\the\string\value{chapter}}%
                 {\chapter@current@value}{\string\relax}{\thechapter.}%
                 \csname the#1\endcsname}%
               {#3\noexpand~\csname the#1\endcsname}}\relax%
     \immediate\write\@auxout{\string\crefformat{\ctp@labelcode}%
               {\string##2#4\noexpand~%
                 \string\ifstr{\string\the\string\value{chapter}}%
                 {\chapter@current@value}{\string\relax}{\thechapter.}%
                 \csname the#1\endcsname\noexpand~%
                  \ctp@hashchar1\ctp@hashchar3}}\relax%
\else
     \immediate\write\@auxout{\string\crefname{\ctp@labelcode}%
               {#4\noexpand~\csname the#1\endcsname}%
               {#4 plural\noexpand~\csname the#1\endcsname}}\relax%
     \immediate\write\@auxout{\string\crefformat{\ctp@labelcode}%
               {\string##2#4\noexpand~\csname the#1\endcsname\noexpand~%
                  \ctp@hashchar1\ctp@hashchar3}}\relax%
\fi
%    \end{macrocode}
% \begin{macro}{\Label}
% We finally (re)define the "\Label" command. Without the "externalchapters" option, all it does is call the classic "\label" command (from "cleveref") with our unique label name as identifier. With that option, it does exactly what "cref"'s original "\label@optarg" command (which is simply the "label" command with an optional argument, as defined by "cref") would do if it were called with "\ctp@labelcode" as optional argument, except that it uses "\cref@old@currentlabel" instead of "\cref@currentlabel".
%    \begin{macrocode}
\ifcoolthms@externalchapters
     \def\Label##1{\cref@old@label{##1}%
       \protected@edef\cref@currentlabel{%
         \expandafter\cref@override@label@type%
         \cref@old@currentlabel\@nil{\ctp@labelcode}}%
       \protected@write\@auxout{}%
       {\string\newlabel{##1@cref}{{\cref@currentlabel}{\thepage}}}}
\else
      \edef\Label##1{\noexpand\label[\ctp@labelcode]{##1}}%
\fi
%    \end{macrocode}
% \end{macro}
% Now we're done, all we need to do is correct "#1".
%    \begin{macrocode}
      \addtocounter{#1}{-1} %
  }% End of \BeforeBeginEnvironment
}% End of \newcommandx*{\definetheorem}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\theoremmarkup}
% Now we define the "\theoremmarkup" command, which is described above.
%    \begin{macrocode}
\newcommandx*{\theoremmarkup}[6][1=\bf,2=\normalfont,3=\relax,%
              4=\coolthms@indent,5=\coolthms@separator,6=arabic]{
%    \end{macrocode}
% \changes{v1.1}{2012/04/01}{Fixed indentation bug.}
% For some reason, "\hspace*{-#4}" lets the theorem start just slightly into the margin (i.e. somewhere in the conversion process about one character space gets lost). Using "\theorem@indent" solves the problem, although it remains unclear exactly why.
%    \begin{macrocode}
  \theoremheaderfont{\hspace*{-\theorem@indent}#1}
  \theorembodyfont{#2}
  \theoremsymbol{#3}
  \theoremindent#4\relax
  \theoremseparator{#5}
  \theoremnumbering{#6}
}
%    \end{macrocode}
% \end{macro}
% And then we want to adjust the format for the other types of references:
%    \begin{macrocode}
\crefformat{equation}{#2(#1)#3}
\crefformat{chapter}{#2\chaptername~#1#3}
%    \end{macrocode}
% \begin{macro}{\theorempreskipamount}\begin{macro}{\theorempostskipamount}
% We set theorem pre- and post skip amounts.
%    \begin{macrocode}
\theorempreskipamount\coolthms@minskip plus \coolthms@maxskip\relax
\theorempostskipamount\coolthms@minskip plus \coolthms@maxskip\relax
%    \end{macrocode}
% \end{macro}\end{macro}
% This is for proofs:
%    \begin{macrocode}
\theoremstyle{unserbeweis}
\theoremmarkup[\coolthms@proofcaptionstyle][\normalfont]%
  [\coolthms@proofsymbol][\coolthms@proofindent]
\expandafter\newtheorem{proof}{\coolthms@proofname}
%    \end{macrocode}
% At the end we invoke "\theoremmarkup" to set everything back to the default values.
%    \begin{macrocode}
\theoremmarkup
%    \end{macrocode}
% \changes{v0.1}{2011/08/09}{Started project}
% \changes{v1.0}{2012/03/29}{First public version}
% \PrintChanges
% \PrintIndex