% \iffalse meta-comment % % Copyright (C) 2016 by Philippe Faist, philippe.faist@bluewin.ch % ------------------------------------------------------- % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in: % % http://www.latex-project.org/lppl.txt % % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % \fi % % \iffalse %<*driver> \ProvidesFile{phfthm.dtx} % %\NeedsTeXFormat{LaTeX2e}[2005/12/01] %\ProvidesPackage{phfthm} %<*package> [2021/03/01 v1.2 phfthm package] % % %<*driver> \documentclass{ltxdoc} \usepackage{xcolor} \usepackage{phfthm} \usepackage[preset=xpkgdoc]{phfnote} \usepackage{needspace} \expandafter\def\csname eqsign@\endcsname{=} \def\eqsign{\expandafter\protect\csname eqsign@\endcsname} \robustify\eqsign \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{phfthm.dtx} \end{document} % % \fi % % \CheckSum{0} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % % \changes{v1.0}{2016/04/20}{Initial version} % % \GetFileInfo{phfthm.dtx} % % \DoNotIndex{\newcommand,\newenvironment,\def,\gdef,\edef,\xdef,\if,\else,\fi,\ifx} % \DoNotIndex{\expandafter,\csname,\endcsname,\let} % % \title{\phfqitltxPkgTitle{phfthm}} % \author{Philippe Faist\quad\email{philippe.faist@bluewin.ch}} % \date{\pkgfmtdate\filedate} % \maketitle % % \begin{abstract} % \pkgname{phfthm}---Goodies for theorems and proofs. % \end{abstract} % % \inlinetoc % % \section{Introduction} % % The \pkgname{phfthm} package provides enhanced theorem and proof environments, % based on the \pkgname{amsthm} original versions. It allows for hooks to be % placed, adds some default goodies and is highly customizable. % % There are three generic types of environments provided: theorem environments, % proof environments and ``thmheading'' environments. % % \subsection{Theorem environments} % % Theorem environments look like this: % \begingroup\setlength{\fboxsep}{1ex} % \par\noindent\fbox{\begin{minipage}{\dimexpr\textwidth-2\fboxsep-2\fboxrule\relax} % \begin{theorem}[Gauss]\noproofref % \label{thm:example-Gauss} % For a closed surface $S$ enclosing a volume $V$, we have % \begin{equation} % \oint_S\vec u\cdot d\vec S = \int_V(\vec\nabla\cdot\vec u)\,dV\ . % \end{equation} % \end{theorem} % \end{minipage}}\endgroup % % \subsection{Proof environments} % % A proof environment might look like this: % \begingroup\setlength{\fboxsep}{1ex} % \par\noindent\fbox{\begin{minipage}{\dimexpr\textwidth-2\fboxsep-2\fboxrule\relax} % \begin{proof}[*thm:example-Gauss] % The proof of the theorem goes here. \par\ldots % \end{proof} % \end{minipage}}\endgroup % % The enhanced theorem and proof environments provided by this package allow to % pair theorems with proofs, automatically generating references from one to the % other (see \autoref{sec:proof-ref-mechanism}). % % % \subsection{Theorem-heading environments} % % Finally, theorem-heading environments are formatted like theorems, but the % heading title is set as an argument to the environment. These environments % are a nice alternative for definitions, and look like this: % \begingroup\setlength{\fboxsep}{1ex} % \par\noindent\fbox{\begin{minipage}{\dimexpr\textwidth-2\fboxsep-2\fboxrule\relax} % \begin{thmheading}{Trace Distance} % The `trace distance' between $\rho$ and $\sigma$ is defined as % \begin{equation} % \delta(\rho,\sigma)=\frac12\,\left\Vert \rho - \sigma \right\Vert_1\ , % \end{equation} % where $\lVert\cdot\rVert_1$ is the Schatten-1 norm. % \end{thmheading} % \end{minipage}}\endgroup % % % % \section{Quick start and package options} % \label{sec:quick-start} % \label{sec:global-pkg-options} % % Example: Load the rich theorem set, with separate counters, and with proof-ref % mechanism on and always displaying the proof reference in the margin: % \begin{verbatim} % \usepackage[thmset=rich,sepcounters=true,proofref={always,margin}]{phfthm} % \end{verbatim} % % By default, some styles are tweaked a bit so that they appear nicely as % documented below (for example, by using a filled square instead of a simple % square for end-of-proof QED markers). Use the package option % \pkgoptionfmt{resetstyle} to instruct \pkgname{phfthm} not to proceed to these % style adjustments; this allows you to enable features individually and % selectively: % \begin{verbatim} % \usepackage[resetstyle,prooftitleitbf=true]{phfthm} % \end{verbatim} % % % \subsection{Predefined theorem environments} % \label{sec:theorem-sets} % % You may load predefined theorem sets via the package option % \pkgoptionfmt{thmset}. Theorem sets group common environments used in % mathematical works such as Theorem, Proposition, Definition, etc. % % Some package options control the way these environments are defined. If you % would like more refined control over the appearance of these environments, or % over which environments are defined, you may consider calling |\phfLoadThmSet| % manually or defining individual environments with |\phfMakeTheorem|. % % Possible theorem sets are: % \begin{pkgoptions} % \item[thmset=,thmset=empty] Do not define any environment at package loading. % You may of course invoke |\phfLoadThmSet| or |\phfMakeTheorem| manually at % any later point. % \item[thmset=simple] % \DescribeEnv{theorem} \DescribeEnv{proposition} % \DescribeEnv{lemma} \DescribeEnv{corollary} \DescribeEnv{definition} % Define the environments |theorem|, |proposition|, |lemma| % and |corollary| as theorem-like environments, and |definition| as a % definition-like environment. % \item[thmset=default] \DescribeEnv{conjecture} \DescribeEnv{remark} Define the % environments |theorem|, |proposition|, |lemma|, |corollary|, |conjecture|, % |remark| as theorem-like environments, and |definition| as a definition-like % environment. % \item[thmset=shortnames] \iffalse\DescribeEnv{thm}\DescribeEnv{prop} % \DescribeEnv{lem}\DescribeEnv{cor}\DescribeEnv{conj}\DescribeEnv{rem} % \DescribeEnv{defn}\fi In case you prefer to type less: the same environments % are defined as the default set, but with shorter names. Define the % environments |thm|, |prop|, |lem|, |cor|, |conj|, |rem| as theorem-like % environments, and |defn| as a definition-like environment. % \item[thmset=rich] \DescribeEnv{idea} \DescribeEnv{question} % \DescribeEnv{claim} \DescribeEnv{observation} \DescribeEnv{problem} Provides % the same environments as the |default| theorem set, as well as in addition: % |idea|, |question|, |claim|, |observation|, and |problem| as theorem-like % environments. % \end{pkgoptions} % % You may also load a theorem set at a later % point after loading the \pkgname{phfthm} package by invoking the % |\phfLoadThmSet| macro, see \autoref{sec:load-thm-set-manually}. % % Further package options modify the style of the theorem-like and % definition-like environments defined via the \pkgoptionfmt{thmset} package % option: % % \begin{pkgoptions} % \item[theoremstyle=\meta{theorem style name}] Use this package option to % specify which style to use for theorem-like environments when loading the % theorem set specified via the \pkgoptionfmt{thmset} package option. The % theorem style name should be one of |plain|, |definition|, |remark|, or any % other |\newtheoremstyle|-defined theorem style (see documentation of % \pkgname{amsthm}). % \item[definitionstyle=\meta{theorem style name}] Use this package option to % specify which style to use for definition-like environments when loading the % theorem set specified via the \pkgoptionfmt{thmset} package option. The % theorem style name should be one of |plain|, |definition|, |remark|, or any % other |\newtheoremstyle|-defined theorem style (see documentation of % \pkgname{amsthm}). % \end{pkgoptions} % % Further options control various aspects of the environments defined by % \pkgoptionfmt{thmset}. % \begin{pkgoptions} % \item[sepcounters=\metatruefalsearg] Each theorem environment defined with the % \pkgoptionfmt{thmset} package option will use a separate counter if this % option is set; otherwise (the default), there is a single counter which is % shared by all those theorem environments. % \item[parentcounter=\meta{counter name}] Theorem counters will reset each time % the parent counter is increased. Use this option for per-chapter or % per-section numbering (use parent counter |parentcounter=chapter| or % |parentcounter=section|). See also the \pkgoptionfmt{countpersection} % package option. % \end{pkgoptions} % % The \pkgoptionfmt{proofref} package option allows to specify a comma-separated % list of attributes to apply to the proof reference (``proof on page XYZ'') % displayed along with the theorem. The following attributes may be specified: % \begin{pkgoptions} % \item[proofref=\pkgoptattribempty{},proofref=\pkgoptattribnodots{default}] Do % not change the default proof reference appearance. % % \item[proofref=false] Deactivate the proof-ref mechanism. % % \item[proofref=\pkgoptattrib{margin}] The proof reference is displayed in % the margin, instead of after the theorem. % % \item[proofref=\pkgoptattrib{marginbottom}] The proof reference is displayed % in the margin, but aligned with the bottom of the theorem statement. % % \item[proofref=\pkgoptattrib{longref}] The proof reference is displayed as % a full sentence (``The proof of this \meta{Theorem Name} can be found on % page \meta{XYZ}.''). % % \item[proofref=\pkgoptattrib{off}] Turn off the proof reference mechanism % completely for theorems defined with the \pkgoptionfmt{thmset} option. % % \item[proofref=\pkgoptattrib{always}] Always display the proof reference, % even if the proof is on the same page or on a nearby page. % % Note: this option has a global effect. % % \item[proofref=\pkgoptattrib{onyifveryfar}] The proof reference is only % displayed if the proof is at least two pages back, or four pages ahead. % % Note: this option has a global effect. % % \end{pkgoptions} % % \begin{pkgnote} % The two package options \pkgoptionfmt{proofref=\pkgoptattribnodots{always}} % and \pkgoptionfmt{proofref=\pkgoptattribnodots{onlyifveryfar}} apply to % \emph{all} theorem environments which use the proof-ref mechanism, whether % they have already been defined or not (see |\phfProofrefPageBackTolerance| % and |\phfProofrefPageAheadTolerance|). % % All the other above options apply only to the theorem environments defined % via the \pkgoptionfmt{thmset} package option. % \end{pkgnote} % % \subsection{The proof environment} % \label{sec:proof-env} % % \DescribeEnv{proof} % By default, the \pkgname{phfthm} package overrides the |proof| environment % with a the package's own enhanced version. If you want to preserve the % original \emph{AMS} environment, you should use the % \pkgoptionfmt{proofenv=false} package option. % % \begin{pkgoptions} % \item[proofenv=\metatruefalsearg] If set to |true|, then define an enhanced % |proof| environment when loading this package. This will override any % previously existing |proof| environment such as \emph{AMS}'. % % If set to |false|, no action is taken at package loading time. You should % then directly use the |\phfMakeProofEnv| macro to define proof environments. % \end{pkgoptions} % % If you want finer control over how the proof environment is defined, or if you % want to customize its appearance, you should use the |\phfMakeProofEnv| macro % directly (\autoref{sec:mk-proof-env}). % % If you set \pkgoptionfmt{proofenv=true}, there are a couple package options % which alter the way the proof displays: % \begin{pkgoptions} % \item[smallproofs=\metatruefalsearg] If set to |true|, then proofs display in % a smaller font. % % \item[qedsymbolblacksquare=\metatruefalsearg] If set to |true|, the QED % end-of-proof symbol (usually ``$\square$'' with \pkgname{amsthm}) is % replaced by a filled square (``$\blacksquare$''). % % \item[prooftitleitbf=\metatruefalsearg] If set to |true|, then the proof title % (``Proof'' or ``Proof of Theorem 1'') is typeset in bold italic font. % \end{pkgoptions} % % % \subsection{The theorem-heading environment} % \label{sec:thmheading-default} % \DescribeEnv{thmheading} By default, the |thmheading| environment is provided % by the \pkgname{phfthm} package: % \begin{verbatim} % \begin{thmheading}{Trace Distance} % The `trace distance' between $\rho$ and $\sigma$ is defined as % \begin{equation} % \delta(\rho,\sigma)=\frac12\,\left\Vert\rho-\sigma\right\Vert_1\ , % \end{equation} % where $\lVert\cdot\rVert_1$ is the Schatten-1 norm. % \end{thmheading} % \end{verbatim} % \begingroup\setlength{\fboxsep}{1ex} % \par\noindent\fbox{\begin{minipage}{\dimexpr\textwidth-2\fboxsep-2\fboxrule\relax} % \begin{thmheading}{Trace Distance} % The `trace distance' between $\rho$ and $\sigma$ is defined as % \begin{equation} % \delta(\rho,\sigma)=\frac12\,\left\Vert \rho - \sigma \right\Vert_1\ , % \end{equation} % where $\lVert\cdot\rVert_1$ is the Schatten-1 norm. % \end{thmheading} % \end{minipage}}\endgroup % % You may also use |\label| and |\ref| as usual (|\ref| simply displays the % given title). % % Some package options control the way this environment is defined. % % \begin{pkgoptions} % \item[thmheading=\metatruefalsearg] Define the environment % |\begin{thmheading}...\end{thmheading}| when loading the \pkgname{phfthm} % package, with reasonable default settings. % \item[thmheadingstyle=\meta{theorem style}] If \pkgoptionfmt{thmheading=true} % was specified, you may use this option to specify the theorem style to use % for the |thmheading| environment. Possible values are \emph{AMS} theorem % style names (e.g.\@ the base styles |plain|, |definition| or |remark|), or % any other style defined with |\newtheoremstyle|. % \end{pkgoptions} % % If you want to define theorem-heading environments manually, see % \autoref{sec:thmheading-manually}. % % % % % \section{Theorem environments} % % A theorem environment is based on the environment furnished by % \pkgname{amsthm}'s |\newtheorem| command, but with added goodies. % % % \subsection{Define theorem environments manually} % % \DescribeMacro{\phfMakeTheorem} If you don't want to load a full theorem set % (\autoref{sec:theorem-sets}), you can define theorem environments individually % with |\phfMakeTheorem|: % % \noindent |\phfMakeTheorem|\hspace{0pt}\oarg{key-value % options}\hspace{0pt}\marg{theorem environment name}\hspace{0pt}\marg{theorem % name} % % This command defines a new environment (given as the first mandatory argument) % which behaves as a theorem and is displayed as given by the second mandatory % argument. For example, we might call |\phfMakeTheorem{theorem}{Theorem}| to % define the environment |\begin{theorem}...\end{theorem}| which displays % ``\textit{Theorem N.} \ldots'' % % The possible key-value options for the optional argument are: % \begin{cmdoptions} % \item[counter=\meta{\LaTeX{} counter $\mid$ (empty)}] The name of the \LaTeX{} % counter to use for the theorem environment. If this is empty, then a new % counter will be created which is specific to this theorem environment (the % default). If not empty, then the theorem environment uses the given counter % (or an alias thereof, see \cmdoptionfmt{aliascounter}). % % If a counter is specified, the counter should already be defined with % \LaTeX's |\newcounter|. % % \item[aliascounter=\metatruefalsearg] In some cases % (e.g.\@ if you're using \pkgname{hyperref}'s |\autoref|), it is important to % have counters specific to each theorem environment (so you get ``Theorem 5'' % or ``Proposition 5'' right). However, you may want different theorem % environments to share a same logical counter (Say ``Definition 1'', % ``Definition 2'', ``Theorem 3'', ``Proposition 4''). In this case, you % should specify \cmdoptionfmt{aliascounter=true}. % % When this option is on, then first we define an alias counter of the one % given to the \cmdoptionfmt{counter} option, and then use the alias for the % theorem environment. The alias is declared using the \pkgname{aliascnt} % package. The alias counter is automatically set up correctly for using % |\autoref|. % % Note that the \cmdoptionfmt{aliascounter} option only has an effect if the % \cmdoptionfmt{counter} option is set to some non-empty value. If % \cmdoptionfmt{counter} is set to a non-empty value, then % \cmdoptionfmt{aliascounter} defaults to |true|. % % \item[thmstyle=\meta{theorem style $\mid$ (empty)}] The theorem style to use % to define this theorem environment. The value of this option should be a % valid argument to \textit{AMS}'s |\theoremstyle|. If you leave this empty % (the default), then the theorem style is not set explicitly and whatever % default style is used. % % \item[defnostar=\metatruefalsearg] Set this to % |true| if you want the corresponding non-starred theorem environment to be % defined, e.g.\@ |\begin{theorem}...\end{theorem}|. % % Normal (non-starred) versions of the environments have an associated theorem % number, as you expect by default. % % \item[defstar=\metatruefalsearg] Set this to % |true| if you want the corresponding starred theorem environment to be % defined, e.g.\@ |\begin{theorem*}...\end{theorem*}|. % % Starred versions of the environments do not have an associated theorem % number. % % \item[proofref=\metatruefalsearg] Enable or disable % the proof-ref mechanism for this theorem environment (enabled by default). % % \item[proofrefstyle=\meta{proof-ref style}] The style to use for the proof % references. Here you may specify how the proof ref appears, for example (in % the margin, long sentence, ...). Possible styles are % \cmdoptionfmt{proofrefstyle=default} (the default), % \cmdoptionfmt{proofrefstyle=margin} (display the proof ref in the margin of % the page), \cmdoptionfmt{proofrefstyle=marginbottom} (display the proof ref % in the margin of the page aligned with the bottom of the theorem statement) % and \cmdoptionfmt{proofrefstyle=longref} (as by default but with a full % sentence). See \autoref{sec:proof-ref-customize-appearance} for how to % further customize the appearance of the proof reference. % % \end{cmdoptions} % % For example, you may use the following command invocation to define a theorem % environment named ``Remark'' implemented as |\begin{remark}...\end{remark}|, % also with a starred verison |\begin{remark*}...\end{remark*}|, using the % |plain| \emph{AMS} theorem style, and without the proof-ref mechanism: % \begin{verbatim} % \phfMakeTheorem[defstar=true,defnostar=true,thmstyle=plain,counter=,% % proofref=false]{remark}{Remark} % \end{verbatim} % % % % \subsection{Loading theorem sets manually} % \label{sec:load-thm-set-manually} % % \DescribeMacro{\phfLoadThmSet} You may load theorem sets at any time via the % macro |\phfLoadThmSet|. This may be useful, for example, to load theorem sets % only after you have defined a custom theorem style. The syntax of % |\phfLoadThmSet| is: % % \noindent |\phfLoadThmSet|\hspace{0pt}\marg{options to % \phfverb{\phfMakeTheorem} for theorem-like % environments}\hspace{0pt}\marg{options to \phfverb{\phfMakeTheorem} for % definition-like environments}\hspace{0pt}\marg{name of theorem set to load} % % The first and second argument to this macro are tokens to expand in front of % |\phfMakeTheorem| for theorem-like or definition-like environments. For % example: % \begin{verbatim} % \newcounter{mythmcounter} % \newtheoremstyle{mythmstyle}{...} % \newtheoremstyle{mydefnstyle}{...} % \phfLoadThmSet{[thmstyle=mythmstyle,counter=mythmcounter]} % {[thmstyle=mydefnstyle,counter=mythmcounter]}{rich} % \end{verbatim} % % \begin{pkgwarning} % The first and second arguments to |\phfLoadThmSet| must either be empty, % or be enclosed in square braces. % \end{pkgwarning} % % \needspace{10\baselineskip} % \DescribeMacro{\theoremname} % \DescribeMacro{\propositionname} % \DescribeMacro{\lemmaname} % \DescribeMacro{\corollaryname} % \DescribeMacro{\conjecturename} % The title of the theorem environments defined in theorem sets use the same % scheme as figures, tables, etc.\@ with regard to translations and % \pkgname{babel}: they use |\theoremname|, |\propositionname|, etc. % % \DescribeMacro{\remarkname} % \DescribeMacro{\definitionname} % \DescribeMacro{\ideaname} % \DescribeMacro{\questionname} % \DescribeMacro{\claimname} % \DescribeMacro{\problemname} % % This package is language agnostic (with titles defined by default in English), % and does not provide the titles for other languages. In order to support % language switching with \pkgname{babel} and |\selectlanguage|, you should add % the relevant names to the corresponding |\captions|\meta{language name} macro, % for example: % \begin{verbatim} % \usepackage[french,...]{babel} % ... % \addto\captionsfrench{% % \def\theoremname{Th\'eor\`eme}% % \def\propositionname{Proposition}% % \def\lemmaname{Lemme}% % \def\corollaryname{Corollaire}% % \def\conjecturename{Conjecture}% % \def\remarkname{Remarque}% % \def\definitionname{D\'efinition}% % \def\ideaname{Id\'ee}% % \def\questionname{Question}% % \def\claimname{Affirmation}% % \def\problemname{Probl\`eme}% % } % ... \selectlanguage{french} ... % \end{verbatim} % % % \subsection{Theorem hooks} % \label{sec:theorem-hooks} % % Any theorem environment automatically calls some hooks. There are hooks % available per theorem environment as well as generic for all theorem % environments. % % \DescribeMacro{\phfthm@hook@start@thmname} The hook % |\phfthm@hook@start@|\meta{theorem environment name}\marg{theorem title} is % called at the start of the environment. More precisely, it is called inside % the original \pkgname{amsthm} base environment; that is, after the heading was % generated. It takes one mandatory argument, the optional title provided to % the theorem environment which may be empty. By default, the hook defers to % the global hook |\phfthm@hook@startcommonnostar|. % % \DescribeMacro{\phfthm@hook@start@thmname*} The hook % |\phfthm@hook@start@|\meta{starred theorem environment name} is completely % analogous, and is called for the starred environment. The only difference is % that by default, it defers its call to |\phfthm@hook@startcommonstar|. % % \DescribeMacro{\phfthm@hook@startcommonnostar} The hook % |\phfthm@hook@startcommonnostar|\marg{theorem environment name}\marg{theorem % optional given title} collects the default definitions for non-starred % environments (none by default) and continues to defer to % \DescribeMacro{\phfthm@hook@startcommon} % |\phfthm@hook@startcommon|\marg{theorem environment name}\marg{theorem % optional given title}. \DescribeMacro{\phfthm@hook@startcommonstar} % Analogously, the macro |\phfthm@hook@startcommonstar|\marg{theorem environment % name}\marg{theorem optional given title} groups commands for starred % environments (typically doesn't take care of |\label| stuff) and also defers % to |\phfthm@hook@startcommon|. % % The end hooks work very much % analogously. \DescribeMacro{\phfthm@hook@end@thmname} % |\phfthm@hook@end@|\meta{theorem environment name} and % \DescribeMacro{\phfthm@hook@end@thmname*} |\phfthm@hook@end@|\meta{starred % theorem environment name} are called respectively for the non-starred and % starred version of that theorem environment, and by default they defer to the % common \DescribeMacro{\phfthm@hook@endcommonnostar} % |\phfthm@hook@endcommonnostar|\marg{theorem environment name} or % \DescribeMacro{\phfthm@hook@endcommonstar} % |\phfthm@hook@endcommonstar|\marg{theorem environment name}. Both these hooks % defer their calls to |\phfthm@hook@endcommon|\marg{theorem environment name}. % % For theorems using the proof-reference mechanism, i.e.\@ for which % \cmdoptionfmt{proofref=true} was specified to |\phfMakeTheorem| and which uses % the |\label| hack (\autoref{sec:proof-ref-mechanism}), there is an additional % hook. \DescribeMacro{\phfthm@hook@afterlabel@thmname} The hook % |\phfthm@hook@afterlabel@|\meta{theorem environment name} is called just after % the |\label| command corresponding to the theorem is encountered (this should % always be at the \emph{beginning} of the theorem, see % \autoref{sec:proof-ref-mechanism}). Depending on the proof-ref style, this % hook may be used to generate the proof reference text (for example, with the % |margin| proof-ref style). The hook is called after the theorem label is set. % The label itself can be recovered from the value of the macro % |\phfthm@val@thmlabel|. By default, that hook calls the common hook % \DescribeMacro{\phfthm@hook@afterlabelcommon} % |\phfthm@hook@afterlabelcommon|\marg{theorem environment name}. (After the % first occurrence of the command |\label|, the latter's definition is % restored.) % % % % \section{Proof environments} % % Proof environments typeset mathematical proofs. The proof environment(s) % provided by \pkgname{phfthm} give some added functionality with respect to the % \emph{AMS}-default |proof| environment, such as supporting the proof-reference % mechanism described in \autoref{sec:proof-ref-mechanism}. % % A proof environment might look like the following: % \begin{proof}[Theorem 5] % Let $\mathcal{T}_{X\to X'}$ be any trace nonincreasing completely positive % map such that $\mathcal{T}_{X\to X'}\left(\Gamma_X\right)$ lies within the % support of $\Gamma_{X'}$. Define the normalized state % $\gamma_X = \Gamma_X / \operatorname{tr}\Gamma_X$. % % Now consider this and that \ldots % \end{proof} % % % The proof environments defined by this package wrap a given proof display % environment (such as \emph{AMS}' (\pkgname{amsthm}'s) or \pkgname{IEEEtran}'s % original |proof| environment) by adding functionality in the form of hooks. % In the following, we refer to the ``underlying proof display environment'' as % the original environment which is wrapped. It may be any \LaTeX{} environment % whose task is to format the proof nicely. % % % \subsection{Manually define a proof environment} % \label{sec:mk-proof-env} % % \DescribeMacro{\phfMakeProofEnv} You may use the macro |\phfMakeProofEnv| to % declare a new proof environment. The syntax is: % % \noindent |\phfMakeProofEnv|\oarg{key-value options}\marg{proof environment name} % % This defines a new environment with the given name, which may be used to % display proofs to theorems. The options may be: % \begin{cmdoptions} % \item[displayenv=\meta{name of \LaTeX{} environment}] Set a % \LaTeX{} environment to use to actually format and display the proof. (The % |\phfMakeProofEnv| command itself doesn't care about how the proof is % displayed or formatted; rather it adds a goodies infrastructure in which % stuff can be plugged in and provides options for such goodies.) % % You may specify here the name of a \LaTeX{} environment, or give the special % value \cmdoptionfmt{displayenv=*} to indicate the default appearance % provided by \pkgname{phfthm}, or leave the value empty % \cmdoptionfmt{displayenv=} to signify that no underlying display environment % should be invoked. (The latter may be useful if you are plugging a % |\phfMakeProofEnv|-generated environment into a larger environment which % already takes care of the display.) % % \item[defaultproofname=\meta{default proof title}] Specify here the title to % use (e.g.\@ ``Proof'') if no argument was given to the proof environment. % If you do not specify any |defaultproofname|, or pass an empty value, then % the value of |\proofname| is used. % % \item[parselabel=\metatruefalsearg] Specify whether % the environment should parse its argument for some special information. If % set to |true|, then the proof argument is passed on to a command (specified % by the \cmdoptionfmt{parselabelcmd} option). % % \item[parselabelcmd=\meta{{\LaTeX} macro}] If \cmdoptionfmt{parselabel} is set % to |true|, then specify here a \LaTeX{} command which parses whatever it % wants from the proof environment's argument. The macro should set the % |\phfthm@val@displayargs| macro to tokens which will be expanded just after % the invocation of the proof environment's display environment % (\cmdoptionfmt{displayenv}). It should also set |\phfthm@val@proofoflabel| % (if appropriate) to the label corresponding to the theorem for which this is % the proof of. % % By default, the command |\phfthm@proof@parselabel| is used, which parses the % proof environment's argument for a reference to a theorem in the context of % a proof-ref mechanism (see \autoref{sec:proof-ref-mechanism}). The label is % parsed to see if it is of the form |[*thm:reference]|, where |thm:reference| % is the label pinned to a theorem. % % \item[override=\metatruefalsearg] Whether to % override any existing environment with the same name as the new proof % environment. If |true| is specified here, then |\renewenvironment| is used % to define the proof environment, otherwise a simple |\newenvironment| is % used. % % \item[internalcounter=\meta{name of \LaTeX{} counter}] The name of the % internal counter the proof environment should use. The count number is not % displayed (by default at least), but it is only used to pin down anchors for % PDF hyperlinks. % % The counter should already be defined with |\newcounter|. % % \item[proofofname=\meta{\LaTeX{} macro}] Specify here a macro % which will be called with a single argument. The macro produces the text to % display when the proof environment is parsed as the proof of a specific % theorem or proposition (or other theorem environment). The argument which % will be given to it is the title of what the proof is of (e.g.\@ ``Theorem % 3''). Typically, the macro should produce something like ``Proof of Theorem % XYZ.'' % % By default, the global macro |\proofofname| is used. % \end{cmdoptions} % % \DescribeMacro{\proofname} Text to use to display ``Proof.'' This should be % already defined by the \LaTeX{} system, and \pkgname{babel} should already % provide translations in different languages. % % \DescribeMacro{\proofofname} The globally defined macro |\proofofname| % specifies the default way of displaying ``Proof of Theorem~5.'' It is % originally defined as something like % \begin{verbatim} % \newcommand\proofofname[1]{\proofname{} of #1} % \end{verbatim} % You may override this to obtain something fancier, of you wish to display the % document in a different language. For instance, you might want to display % (``D\'emonstration (Th\'eor\`eme 5)'' in french: % \begin{verbatim} % \def\proofofnameinparentheses#1{\proofname\ (#1)} % \addto\captionsfrench{% % \def\proofname{D\'emonstration}% % \let\proofofname\proofofnameinparentheses% % } % ... % \selectlanguage{french} ... % \end{verbatim} % % % % \subsection{Proof hooks} % \label{sec:proof-hooks} % % The proof hooks are relatively straightforward. All hooks presented here take % no argument. % % Information about the argument of the proof, both the raw argument and the % possibly parsed reference, are available as macros to some of the hooks (but % don't change these values unless you know what you're doing). The macro % |\phfthm@val@proofarg| contains the raw argument to the proof environment, and % is available to all hooks. If you use the default proof environment argument % parsing (which you must have enabled when calling |\phfMakeProofEnv|), then % additionally the macros |\phfthm@val@prooftitle| and |\phfthm@val@proofofname| % are available containing, respectively, the label of the theorem which is % referenced, and the displayable reference to it (e.g. ``Theorem~5''). The % last two macros are available to all hooks except the first one (|..@start|). % % The hooks named |..@start...| are called within the call to % |\beg||in{}|. % % \expandafter\DescribeMacro\expandafter{\csname phfthm@hookproof@...@start\endcsname} % The hook named |\phfthm@hookproof@|\meta{environment name}|@start| is called % at the very beginning of the proof environment. % % \expandafter\DescribeMacro\expandafter{\csname phfthm@hookproof@...@startafterdisplay\endcsname} % % The hook named |\phfthm@hookproof@|\meta{environment name}|@startafterdisplay| % is invoked immediately after the beginning of the underlying ``display'' % environment (the environment used to display the proof contents). % % \expandafter\DescribeMacro\expandafter{\csname phfthm@hookproof@...@startlast\endcsname} % % The hook named |\phfthm@hookproof@|\meta{environment name}|@startlast| is % called after we are sure that an anchor has been pinned down for the proof. % This hook is called last within the commands in |\beg||in{}|. % % \DescribeMacro{\phfPinProofAnchor} By the way, the macro |\phfPinProofAnchor| % may be used within the hooks to pin down an anchor for referring to the proof % (especially via the proof-ref mechanism). Just call it anywhere appropriate % (a good idea is calling it after leaving v-mode before displaying the title, % in order to avoid placing it just before a page break). If you do not call % this macro, it is automatically called for you just before the |...@startlast| % hook. % % % The two following hooks are called within the call to% % |\en||d{}|. % % \expandafter\DescribeMacro\expandafter{\csname phfthm@hookproof@...@end\endcsname} % The hook |\phfthm@hookproof@|\meta{environment name}|@end| is called before % the proof display environment is closed. % % \expandafter\DescribeMacro\expandafter{\csname phfthm@hookproof@...@final\endcsname} % The hook |\phfthm@hookproof@|\meta{environment name}|@final| is called after % the proof environment display is finished, as the very last. % % All proof hooks call are defined by default to defer their call to a common % hook. The common hooks each take one argument (the proof environment name). % They are named |\phfthm@hookproof@startcommon|\marg{environment name}, % |\phfthm@hookproof@startafterdisplaycommon|\marg{environment name}, % |\phfthm@hookproof@startlastcommon|\marg{environment name}, % |\phfthm@hookproof@endcommon|\marg{environment name}, and % |\phfthm@hookproof@finalcommon|\marg{environment name}. % They are all defined to be empty by default. % % % \section{Pairing theorems to proofs and proof-reference mechanism} % \label{sec:proof-ref-mechanism} % % One of the goodies provided by the \pkgname{phfthm} package is the proof-ref % mechanism, where in a theorem environment, the text ``see proof on page % \ldots'' is displayed to direct the reader to the location of the % corresponding proof. The mechanism is deactivated by default, but can be % enabled with a simple package option. % % This only works if the proof is given the label of the corresponding theorem % or proposition. For example: % \begin{verbatim} % \begin{theorem}[Gauss] % \label{thm:Gauss} % For a closed surface $S$ enclosing a volume $V$, we have % \begin{equation} % \oint_S\vec u\cdot d\vec S = \int_V(\vec\nabla\cdot\vec u)\,dV\ . % \end{equation} % \end{theorem} % % ... % % \begin{proof}[*thm:Gauss] % ... % \end{proof} % \end{verbatim} % % The above example might produce the following output: % \begingroup\setlength{\fboxsep}{1em} % \par\noindent\fbox{% % \begin{minipage}{\dimexpr\textwidth-2\fboxsep-2\fboxrule\relax} % \textbf{Theorem 17} (Gauss). For a closed surface $S$ enclosing a % volume $V$, we have % \begin{equation} % \oint_S\vec u\cdot d\vec S = \int_V(\vec\nabla\cdot\vec u)\,dV\ . % \tag*{(41)} % \end{equation} % \hfill{\small\itshape (Proof on page XXX.)}\hfilneg % {\par\vspace{1ex}\relax % \ldots\par\vspace{1ex}}\relax % \par\textit{Proof of Theorem 17.}\hspace{2em}\ldots % \end{minipage} % }\endgroup % % A positive side-effect is that in your LaTeX source, if you consistently % label your proofs then you always know what theorem a proof refers to. If % you would like to simply output ``Proof.'' instead of ``Proof of Theorem % X.'', for instance, because the proof immediately succeeds the theorem in % question, you may use the syntax |[**thm:label]| instead. In this case, the % proof-reference mechanism will know that this is the proof of the theorem % labeled |thm:label| and will avoid undefined references. For example, % the following code: % \begin{verbatim} % \begin{theorem}[Gauss] % \label{thm:Gauss} % For a closed surface $S$ enclosing a volume $V$, we have % \begin{equation} % \oint_S\vec u\cdot d\vec S = \int_V(\vec\nabla\cdot\vec u)\,dV\ . % \end{equation} % \end{theorem} % \begin{proof}[**thm:Gauss] % ... % \end{proof} % \end{verbatim} % might output: % \begingroup\setlength{\fboxsep}{1em} % \par\noindent\fbox{% % \begin{minipage}{\dimexpr\textwidth-2\fboxsep-2\fboxrule\relax} % \textbf{Theorem 17} (Gauss). For a closed surface $S$ enclosing a % volume $V$, we have % \begin{equation} % \oint_S\vec u\cdot d\vec S = \int_V(\vec\nabla\cdot\vec u)\,dV\ . % \tag*{(41)} % \end{equation} % \par\textit{Proof.}\hspace{2em}\ldots % \end{minipage} % }\endgroup % % % \subsection{On the theorem side} % % On the theorem side, the proof-ref mechanism works by hacking into the % definition of \LaTeX's |\label|. The |\label| command should be placed first % within the theorem (see example above). It is important, in theorems which % use the proof-ref mechanism (on by default), to always have a corresponding % label: Indeed, you may experience weird results if you don't have a theorem % label, but then have labels for other objects in the theorem such as equations % or itemize items. % % Once the corresponding proof is detected (a proof environment with an optional % argument of the form |[*thm:the-label]| for the same label |thm:the-label| as % specified to the theorem, see \autoref{sec:proof-ref-mechanism-proof-side}), % then a text is generated (by default ``Proof on page \ldots'') and placed % after the theorem. The appearance of this text is customizable % (\autoref{sec:proof-ref-customize-appearance}). % % More precisely, the hack with the |\label| command works as follows: At the % beginning of the theorem, the |\label| command is redefined so that at its % fist occurrence, it stores its argument as the theorem's label to use for the % proof reference, it then pins down a \LaTeX{} label as the original |\label| % command would do, and finally it calls the |...@afterlabel| theorem hook (see % \ref{sec:theorem-hooks}). After the first occurrence of |\label|, the % |\label| command is restored to its original \LaTeX{} meaning in case there % are other objects within the theorem which are to be referred to. % % \begin{pkgtip} % The |\label| hack is only active within theorem environments where the % proof-ref mechanism has been enabled. Outside these environments, the % |\label| macro retains its original \LaTeX{} definition. % \end{pkgtip} % % \DescribeMacro{\noproofref} If, for any reason, you do not want to make sure % you don't have any text ``Proof on page \ldots'' appearing (for example there % is no corresponding proof because the theorem is obvious), then you should % call |\noproofref| immediately inside the theorem: % \begin{verbatim} % \begin{theorem} % \noproofref % Theorem text ... % \end{theorem} % \end{verbatim} % % The command |\noproofref| temporarily disables the proof-ref mechanism (and % restores |\label| to \LaTeX's original meaning) for the current theorem. % % % \subsection{On the proof side} % \label{sec:proof-ref-mechanism-proof-side} % % On the proof side, you just need to specify for which theorem this is the % proof of. For that (unless you override the defaults and plug in your own % magic parsing; see \autoref{sec:mk-proof-env}), you should specify an optional % argument to the proof which is of the following form: % |\begin{proof}[*|\meta{label}|]|, % \iffalse meta-comment \end{proof} [-- emacs is confused] \fi % where \meta{label} is the label name you have associated with the theorem in % question (see example above). % % This has two effects: it sets the proof to display ``\textit{Proof of % \ldots},'' and also does some background dark magic to display, at the % location of the corresponding theorem, some text like ``\textit{Proof on page % \ldots},'' where the page number corresponds to the page on which this proof % is located. % % You may also use the syntax |\begin{proof}[**|\meta{label}|]|, which has the % effect of producing the simple output ``Proof.'' (this is desirable e.g.\@ % if the proof immediately follows the theorem statement) but which still % informs the proof-reference mechanism that this proof is associated with the % given theorem labeled by \meta{label}. This can avoid undefined references, % and can simplify your job if you want to move proofs around in your document. % % (It would be nice, of course, to have the package automatically output % ``Proof'' only if the proof immediately follows the theorem and output ``Proof % of XXX'' if the proof is further away. Unfortunately this is hard to detect % in \LaTeX\ and I currently have no plans to try to implement this.) % % \subsection{Customizing appearance of the proof reference text} % \label{sec:proof-ref-customize-appearance} % % Here we explain the workings of the |\phfthm@proofrefstyle@...| macros and how % they are called. It allows you to define new proof-ref styles, for example. % % When the option \cmdoptionfmt{proofref=true} is given to |\phfMakeTheorem| to % define an environment (say |mytheoremenv|), then the hook % |phfthm@hook@start@mytheoremenv| will automatically include the following % calls: % \begin{itemize} % \item The macro |\phfthm@proofrefstyle@|\meta{proof-ref style}|@setup| is called % (for the proof-ref style given via the % \cmdoptionfmt{proofenvstyle=\meta{style name}} key-value option to % |\phfMakeTheorem|); % \item The macro |\phfthm@def@label@thmlabel| is invoked, implementing the hack % on the |\label| macro; % \item The macro |\phfthm@proofref@impl@start| is called. This macro is % expected to be defined after calling |\phfthm@proofrefstyle@|\meta{proof-ref % style}|@setup|. % \end{itemize} % % Furthermore, the |\phfthm@hook@afterlabel@mytheoremenv| hook will include a % call to |\phfthm@proofref@impl@afterlabel|\marg{label of the theorem}. Again, % the latter macro is expected to be defined after calling % |\phfthm@proofrefstyle@|\meta{proof-ref style}|@setup|. % % Finally, the hook |\phfthm@hook@end@mytheoremenv| includes a call to % |\phfthm@proofref@impl@end|\marg{label of the theorem}. Again, % the latter macro is expected to be defined after calling % |\phfthm@proofrefstyle@|\meta{proof-ref style}|@setup|. % % % Hence, to define a new proof-ref style, you simply need to define a macro % called |\phfthm@proofrefstyle@@setup|. This macro % should include commands to locally define the macros % |\phfthm@proofref@impl@start|, |\phfthm@proofref@impl@afterlabel|, and % |\phfthm@proofref@impl@end|. % % % Different proof-ref styles may work similarly and want to share most of the % code. A good idea is to build up on the |default| proof-ref style, which is % highly modular and can be instantiated in different flavors. For an example, % check the |margin| proof-ref style which does precisely that. For more % documentation, check out the implementation of the |default| proof-ref style % in \autoref{sec:impl-default-proof-ref-style}. % % % % % \section{Theorem-heading definition-like environments} % \label{sec:thmheading} % % A theorem-heading environment is an environment which displays in the same way % as a theorem environment, but where the title may be any text (say, ``Trace % Distance'' instead of, e.g., ``Theorem~5''). % % By default, the \pkgname{phfthm} package provides the |thmheading| environment % (see \autoref{sec:thmheading-default}). % % % \subsection{Define theorem-heading environments manually} % \label{sec:thmheading-manually} % % \DescribeMacro{\phfMakeThmheadingEnvironment} A new theorem-heading % environment can be defined by calling |\phfMakeThmheadingEnvironment|. % The syntax is: % % \noindent |\phfMakeThmheadingEnvironment|\oarg{key-value options}\marg{environment name} % % The key-value options may be any combination of the following: % \begin{cmdoptions} % \item[thmstyle=\meta{theorem style name}] The theorem style to use to display % the environment. You may specify here any default \emph{AMS} style % (|plain|, |remark| or |definition|), or any other |\newtheoremstyle|-defined % style. % \item[internalcounter=\meta{name of counter}] The name of a counter which will % internally track environment instances. By default, a common internal % counter is used for all theorem-heading environments (named % |phfthmheadingcounter|). The counter must be already defined (see \LaTeX's % |\newcounter|). % \end{cmdoptions} % % % You can also use |\label| and |\ref| (the latter simply displays the given % title). % % \subsection{Available hooks for theorem-heading environments} % % The hook |\phfthm@hook@thmheading@...@start|\marg{title} is invoked at start, % within an internal environment created with |\newtheorem|. This hook accepts % one argument, the title of the theorem-heading. % % The hook |\phfthm@hook@thmheading@...@end| is called at the end, but still % within the internal theorem environment. % % Replace the dots with the name of the theorem-heading environment (such as % |thmheading|). % % By default, these hooks simply call the common hooks % |\phfthm@hook@thmheading@start| and |\phfthm@hook@thmheading@end|. These % common hooks are empty by default. % % % % % % \StopEventually{\PrintChangesAndIndex} % % % % \section{Implementation} % \label{sec:implementation} % % First, load some packages. General toolboxes: % \begin{macrocode} \RequirePackage{xkeyval} \RequirePackage{etoolbox} % \end{macrocode} % % To define alias counters for theorems, load \pkgname{aliascnt}: % \begin{macrocode} \RequirePackage{aliascnt} % \end{macrocode} % % And finally, load the \textit{AMS} math and theorem (\pkgname{amsmath}, % \pkgname{amsthm}) packages: % \begin{macrocode} \RequirePackage{amsmath} \RequirePackage{amsthm} % \end{macrocode} % % % \subsection{Generic Internal Stuff} % % \begin{macro}{\phfthm@internal@execattribs} % % Internal command: execute all definitions given in list of attributes. This was % copy-pasted from a similar definition in the \pkgname{phfnote} package. % % |#1| = prefix to look for attributes % % |#2| = name of what |#1| represents, to use in message in case attribute is not found % % |#3| = list of attributes % % \begin{macrocode} \def\phfthm@internal@execattribs#1#2#3{% \@for\next:=#3\do{% \ifcsname #1\next\endcsname% \csname #1\next\endcsname% \else% \PackageWarning{phfthm}{Unknown #2: '\next'. Ignoring.} \fi } } % \end{macrocode} % \end{macro} % % % \subsection{Definitions for theorem environments} % % \subsubsection{\phfverb{\phfMakeTheorem}: definition of a new theorem environment} % % First, define some key-value syntax accepted by the |\phfMakeTheorem| command. % \begin{macrocode} \define@cmdkey{phfmkthm}{counter}{} \define@boolkey{phfmkthm}{aliascounter}[true]{} \define@cmdkey{phfmkthm}{thmstyle}{} \define@boolkey{phfmkthm}{defnostar}[true]{} \define@boolkey{phfmkthm}{defstar}[true]{} \define@boolkey{phfmkthm}{proofref}[true]{} \define@cmdkey{phfmkthm}{parentcounter}{} \define@cmdkey{phfmkthm}{proofrefstyle}{} % \end{macrocode} % % \begin{macro}{\phfMakeTheorem} % Define a new theorem environment. The syntax is % |\phfMakeTheorem|\hspace{0pt}\oarg{options}\hspace{0pt}\marg{theorem % environment name}\hspace{0pt}\marg{Theorem Display Name}. For example: % |\phfMakeTheorem[counter=thmcounter]{prop}{Proposition}| % \begin{macrocode} \newcommand\phfMakeTheorem[3][]{% } % \end{macrocode} % Handle the [options]. First, ensure that the defaults are set, and then, parse the input. % \begin{macrocode} \KV@phfmkthm@aliascountertrue% \def\cmdKV@phfmkthm@counter{}% \def\cmdKV@phfmkthm@thmstyle{}% \KV@phfmkthm@defnostartrue% \KV@phfmkthm@defstartrue% \KV@phfmkthm@proofreftrue% \def\cmdKV@phfmkthm@parentcounter{}% \def\cmdKV@phfmkthm@proofrefstyle{default}% \setkeys{phfmkthm}{#1}% % \end{macrocode} % % Now, react to whatever was given in the options. % % \verbdef\tmptheifconstruct|\if\relax\detokenize{...}\relax| % Set the theorem style, if requested.\footnote{The construct % \tmptheifconstruct\space tests whether \phfverb{...} is empty: see % \url{http://tex.stackexchange.com/a/53091/32188}} % \begin{macrocode} \if\relax\detokenize\expandafter{\cmdKV@phfmkthm@thmstyle}\relax% \else% \theoremstyle{\cmdKV@phfmkthm@thmstyle}% \fi% % \end{macrocode} % % If requested, define the default, unstarred version of the theorem. Use % |\newtheorem| for that, which we make sure to call appropriately depending on % whether a separate counter is requested or not. Make sure also to define % |\...autorefname| for |\autoref|. If an alias counter is requested, create it % and pass that one to |\newtheorem|. % % At this point, we create a theorem named |phfthm@...| using |\newtheorem| % (because we still want to add calls to hooks). % \begin{macrocode} \ifKV@phfmkthm@defnostar% \if\relax\detokenize\expandafter{\cmdKV@phfmkthm@counter}\relax% % \end{macrocode} % ---in case we use a separate given counter (if \cmdoptionfmt{counter=} is % given empty or not specified). Also check if we want a parent counter % (per-section or per-chapter numbering) and take that into account: % \begin{macrocode} \if\relax\detokenize\expandafter{\cmdKV@phfmkthm@parentcounter}\relax% \edef\x{\noexpand\newtheorem{phfthm@#2}{#3}}% \else \edef\x{\noexpand\newtheorem{phfthm@#2}{#3}[\expandonce\cmdKV@phfmkthm@parentcounter]}% \fi \x \csdef{phfthm@#2autorefname}{#3}% \else% \ifKV@phfmkthm@aliascounter% % \end{macrocode} % ---in case we make a distinct alias counter, eg. for use with |\autoref|: % \begin{macrocode} \newaliascnt{#2}{\cmdKV@phfmkthm@counter}% \newtheorem{phfthm@#2}[#2]{#3}% \aliascntresetthe{#2}% \csdef{#2autorefname}{#3}% \else% % \end{macrocode} % ---in case we directly instruct |\newtheorem| to use the other counter (does % not work with |\autoref|): % \begin{macrocode} \newtheorem{phfthm@#2}[\cmdKV@phfmkthm@counter]{#3}% \fi% \fi% % \end{macrocode} % % And also define the actual theorem environment, adding calls to hooks. % \begin{macrocode} \newenvironment{#2}[1][]{% \begin{phfthm@#2}[{##1}]% \begingroup% \csname phfthm@hook@start@#2\endcsname{##1}% }{% \csname phfthm@hook@end@#2\endcsname% \endgroup% \end{phfthm@#2}% }% % \end{macrocode} % Define hooks specific to this theorem with sensible defaults. If proof-ref is % on, call the appropriate callbacks. Then, call the common hooks (see % |\phfthm@hook@startcommonnostar|, |\phfthm@hook@afterlabelcommon| and % |\phfthm@hook@endcommonnostar|, detailed in \autoref{sec:theorem-hooks}). % \begin{macrocode} \csedef{phfthm@hook@start@#2}##1{% \ifKV@phfmkthm@proofref% \expandafter\noexpand% \csname phfthm@proofrefstyle@\cmdKV@phfmkthm@proofrefstyle @setup\endcsname% \noexpand\phfthm@def@label@thmlabel{#2}% \noexpand\phfthm@proofref@impl@start% \fi% \noexpand\phfthm@hook@startcommonnostar{#2}{##1}% }% \csedef{phfthm@hook@afterlabel@#2}{% \ifKV@phfmkthm@proofref% \noexpand\phfthm@proofref@expandthmlabeltoarg% \noexpand\phfthm@proofref@impl@afterlabel% \fi% \noexpand\phfthm@hook@afterlabelcommon{#2}% }% \csedef{phfthm@hook@end@#2}{% \ifKV@phfmkthm@proofref% \noexpand\phfthm@proofref@expandthmlabeltoarg% \noexpand\phfthm@proofref@impl@end% \fi% \noexpand\phfthm@hook@endcommonnostar{#2}% }% \fi% % \end{macrocode} % % % If requested, define the starred version of the theorem. We call % |\newtheorem*| to define the base theorem environment (which we call % |phfthm@...|), after which as above we define the actual environment which % also calls the relevant hooks. % \begin{macrocode} \ifKV@phfmkthm@defstar% \newtheorem*{phfthm@#2*}{#3}% \newenvironment{#2*}[1][]{% \begin{phfthm@#2*}[##1]% \begingroup% \csname phfthm@hook@start@#2*\endcsname{##1}% }{% \csname phfthm@hook@end@#2*\endcsname% \endgroup% \end{phfthm@#2*}% }% \fi% % \end{macrocode} % % Finally, define the default hooks specific to the starred version of the % theorem (see \autoref{sec:theorem-hooks}). % \begin{macrocode} \csdef{phfthm@hook@start@#2*}##1{\phfthm@hook@startcommonstar{#2}{##1}}% \csdef{phfthm@hook@end@#2*}{\phfthm@hook@endcommonstar{#2}}% } % \end{macrocode} % \end{macro} % % % \subsubsection{Default hooks for theorems} % % \needspace{3\baselineskip} % \begin{macro}{\phfthm@hook@startcommonnostar} % \begin{macro}{\phfthm@hook@startcommonstar} % \begin{macro}{\phfthm@hook@startcommon} % Common default hooks definitions for start of the theorems. % % For all three of these hooks, we have % |#1| = theorem name, e.g. |proposition| and % |#2| = full (optional) title of proposition, if given, or empty. % % Make sure to invoke the |\label| re-definition hack only for non-starred % theorems/propositions; indeed, if no theorem label is set we don't want to % interfere with labels set to inner equations, itemizes etc. Hence, call % |\phfhtm@def@label@thmlabel| only in the ``nostar'' hook. % \begin{macrocode} \def\phfthm@hook@startcommonnostar#1#2{% \phfthm@hook@startcommon{#1}{#2}% } \def\phfthm@hook@startcommonstar#1#2{% \phfthm@hook@startcommon{#1}{#2}% } \def\phfthm@hook@startcommon#1#2{% % \end{macrocode} % Furthermore, in any case, set the |\postdisplaypenalty| to avoid an orphan % line on a new page after display equation. % \begin{macrocode} \postdisplaypenalty=10000\relax% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\phfthm@hook@afterlabelcommon} % \begin{macro}{\phfthm@hook@endcommonnostar} % \begin{macro}{\phfthm@hook@endcommonstar} % \begin{macro}{\phfthm@hook@endcommon} % Further hooks, for after the theorem main |\label| command % (|\phfthm@hook@afterlabelcommon|) and for the end of the theorem. % \begin{macrocode} \def\phfthm@hook@afterlabelcommon#1{} \def\phfthm@hook@endcommonnostar#1{\phfthm@hook@endcommon{#1}} \def\phfthm@hook@endcommonstar#1{\phfthm@hook@endcommon{#1}} \def\phfthm@hook@endcommon#1{} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \subsubsection{Proof-ref mechanism (on the theorem side)} % % These macros enable the proof-ref mechanism % (\autoref{sec:proof-ref-mechanism}). The theorem's label is stored upon % calling |\label|, because we (locally) hack into the definition of |\label|. % (After the first usage of |\label| its meaning is restored.) % \begin{macro}{\phfthm@def@label@thmlabel} % Main macro to invoke at the beginning of the theorem environment, so that % the theorem label is stored in a local macro once |\label| is invoked. This % hacks the |\label| macro locally. Here, |#1| = the theorem environment % name, e.g.\@ |proposition|. % \begin{macrocode} \def\phfthm@def@label@thmlabel#1{% \ifdefined\phfthm@old@label \PackageWarning{phfthm}{Internal inconsistency: \string\phfthm@def@label@thmlabel called twice for the same theorem environment!} \else \let\phfthm@old@label\label% \edef\label{\noexpand\phfthm@thmlabel{#1}}% \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\phfthm@thmlabel} % The first call to |\label| within the theorem redirects to the macro % |\phfthm@thmlabel|. (Applies to theorem environments for which % |\phfthm@def@label@thmlabel| was called, which is the default). % % Here |#1| = theorem environment name, e.g.\@ |proposition|; and |#2| = the % label value (argument to the |\label| macro). % \begin{macrocode} \def\phfthm@thmlabel#1#2{% % \end{macrocode} % First, store the label value into a macro called |\phfthm@val@thmlabel|. % \begin{macrocode} \def\phfthm@val@thmlabel{#2}% % \end{macrocode} % Then, call the original |\label| macro to do what \LaTeX\space would normally % do for a |\label{|\ldots|}| call. % \begin{macrocode} \phfthm@old@label{#2}% % \end{macrocode} % Restore the old |\label| definition, in case there are other items in the % theorem environment such as equations, itemizes etc.\@ which may themselves % have |\label|'s. % \begin{macrocode} \let\label\phfthm@old@label% % \end{macrocode} % Invoke the |\phfthm@hook@afterlabel@thmname| hook for this theorem % environment. % \begin{macrocode} \csname phfthm@hook@afterlabel@#1\endcsname% % \end{macrocode} % Finally, ignore any spaces following the |\label| command. (Maybe we should % have done something with |\@bsphack| and |\@esphack| but oh well\ldots % \begin{macrocode} \ignorespaces% } % \end{macrocode} % \end{macro} % % % \subsection{Definitions for proof environments} % % Improved, smarter |proof| environments. % % \begin{macro}{\phfthm@old@proof} % \begin{macro}{\endphfthm@old@proof} % Save old |proof| environment provided by \pkgname{amsthm}. % \begin{macrocode} \let\phfthm@old@proof\proof \let\endphfthm@old@proof\endproof % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\proofname} % And provide a default name for proofs (this should normally already be % provided by \pkgname{amsthm}). % \begin{macrocode} \providecommand\proofname{Proof} % \end{macrocode} % \end{macro} % % \begin{macro}{\proofofname} % Default text to display when we want to say e.g.\@ ``Proof of Theorem 3.'' % \begin{macrocode} \def\proofofname#1{\proofname\space of #1} % \end{macrocode} % \end{macro} % % The default counter for proofs. The value of this counter is typically not % displayed, we just use it to pin down anchors for labels for cross references. % \begin{macrocode} \newcounter{phfthmproofcnt} % \end{macrocode} % % Utility: to see if an argument was specified (possibly empty) to the proof % environment. % \begin{macrocode} \def\phfthm@NOPROOFARG{} \def\phfthm@test@NOPROOFARG{\phfthm@NOPROOFARG} % \end{macrocode} % % \subsubsection{Define a proof environment: \phfverb{\phfMakeProofEnv}} % % Declare some key-value options accepted by |\phfMakeProofEnv|. See % \autoref{sec:mk-proof-env} for the documentation of these options. % \begin{macrocode} \define@cmdkey{phfmkprf}{displayenv}{} \define@cmdkey{phfmkprf}{defaultproofname}{} \define@boolkey{phfmkprf}{override}[true]{} \define@cmdkey{phfmkprf}{internalcounter}{} \define@cmdkey{phfmkprf}{proofofname}{} \define@boolkey{phfmkprf}{parselabel}[true]{} \define@cmdkey{phfmkprf}{parselabelcmd}{} % \end{macrocode} % % \begin{macro}{\phfMakeProofEnv} % Make a proof environment. Syntax: % |\phfMakeProofEnv|\hspace{0pt}\oarg{options}\hspace{0pt}\marg{proof % environment name}. % \begin{macrocode} \newcommand\phfMakeProofEnv[2][]{%} % \end{macrocode} % % Parse the key-value options. First, make sure that all the defaults are set, % then parse the options. % \begin{macrocode} \KV@phfmkprf@overridefalse% \def\cmdKV@phfmkprf@displayenv{*}% \def\cmdKV@phfmkprf@defaultproofname{\proofname}% \def\cmdKV@phfmkprf@internalcounter{phfthmproofcnt}% \def\cmdKV@phfmkprf@proofofname{\proofofname}% \KV@phfmkprf@parselabeltrue \def\cmdKV@phfmkprf@parselabelcmd{\phfthm@proof@parselabel}% \setkeys{phfmkprf}{#1}% % \end{macrocode} % % The meaning of the options are detailed in \autoref{sec:mk-proof-env}. % % The general idea here is first to pre-process all the options, and save all % the useful information in macros named % |\phfthm@prfenv@@val@|. Then, we can define % the begin/end environment macros which will recall the saved information. % % Take care of the display environment to use. Recall that if |displayenv=*|, % we use our own default; if |displayenv=| (empty), there is no display % environment. Here, we set % |\phfthm@prfenv@@val@displayenv| to the name of the % environment to use (possibly empty), for later reference. % \begin{macrocode} \def\phfmkprf@tmp@star{*}% \ifx\cmdKV@phfmkprf@displayenv\phfmkprf@tmp@star\relax% \def\cmdKV@phfmkprf@displayenv{phfthm@proof@defaultdisplayenv}% \fi \cslet{phfthm@prfenv@#2@val@displayenv}\cmdKV@phfmkprf@displayenv% % \end{macrocode} % % Process the default proof name. If none is given, use |\proofname| and pass % no option to the underlying display environment whenever the proof environment % is called with no option. Here, we set % |\phfthm@prfenv@@val@defaultproofnameargs| and % |\phfthm@prfenv@@val@setdefaultprooftitle|; the former % is the tokens to put in front of the proof environment invocation in case no % explicit proof title is given to the proof environment while the latter % contains the command to set |\phfthm@val@prooftitle| to the default proof % name. % \begin{macrocode} \if\relax\detokenize\expandafter{\cmdKV@phfmkprf@defaultproofname}\relax% \csdef{phfthm@prfenv@#2@val@defaultproofnameargs}{}% \csdef{phfthm@prfenv@#2@val@setdefaultprooftitle}{% \def\phfthm@val@prooftitle{\proofname}}% \else \csedef{phfthm@prfenv@#2@val@defaultproofnameargs}{% [\expandonce{\cmdKV@phfmkprf@defaultproofname}]}% \csedef{phfthm@prfenv@#2@val@setdefaultprooftitle}{% \noexpand\def\noexpand\phfthm@val@prooftitle{% \expandonce{\cmdKV@phfmkprf@defaultproofname}}}% \fi \csedef{phfthm@prfenv@#2@val@parselabelandmkdisplayargs}##1{% \ifKV@phfmkprf@parselabel \expandonce\cmdKV@phfmkprf@parselabelcmd{##1}% \else \noexpand\phfthm@proof@noparselabel{##1}% \fi \noexpand\if\noexpand\relax\noexpand\detokenize% \noexpand\expandafter{\noexpand\phfthm@val@prooftitle}\noexpand\relax \noexpand\def\noexpand\phfthm@val@displayargs{} \noexpand\else \noexpand\def\noexpand\phfthm@val@displayargs{[{% \expandafter\noexpand\csname phfthm@prfenv@#2@val@proofofname\endcsname {\noexpand\phfthm@val@prooftitle}% }]}% \noexpand\fi } % \end{macrocode} % % Store the macro which creates the ``Proof of \ldots'' text (|proofofname| % option). % \begin{macrocode} \cslet{phfthm@prfenv@#2@val@proofofname}\cmdKV@phfmkprf@proofofname% % \end{macrocode} % % Create the macro which will take care of pinning down the label for the % proof-ref (see \autoref{sec:proof-ref-mechanism}). This macro first ref-steps % the internal counter and then pins down a label, if appropriate. % \begin{macrocode} \csdef{phfthm@prfenv@#2@val@pinproofanchor}{% \csname phfthm@prfenv@#2@val@refstepinternalcounter\endcsname% \if\relax\detokenize\expandafter{\phfthm@val@proofoflabel}\relax\else% \edef\phfthm@tmp@larg{{proof:\phfthm@val@proofoflabel}}% \expandafter\label\phfthm@tmp@larg% \fi }% % % \end{macrocode} % % The command to ref-step the internal proof counter. Use the value of the % \cmdoptionfmt{internalcounter} command option. % \begin{macrocode} \csedef{phfthm@prfenv@#2@val@refstepinternalcounter}{% \noexpand\refstepcounter{\cmdKV@phfmkprf@internalcounter}}% % \end{macrocode} % % Make macros |\phfthm@prfenv@@val@displayenvbegincmd| % and |\phfthm@prfenv@@val@displayenvendcmd|, which % essentially expand to |\begin{}| and % |\end{}| for the display environment given in the option % \cmdoptionfmt{displayenv}. % \begin{macrocode} \if\relax\detokenize\expandafter{\cmdKV@phfmkprf@displayenv}\relax% \csdef{phfthm@prfenv@#2@val@displayenvbegincmd}##1{}% \csdef{phfthm@prfenv@#2@val@displayenvendcmd}##1{}% \else \csedef{phfthm@prfenv@#2@val@displayenvbegincmd}##1{% \noexpand\begin{\csname phfthm@prfenv@#2@val@displayenv\endcsname}##1}% \csedef{phfthm@prfenv@#2@val@displayenvendcmd}##1{% \noexpand\end{\csname phfthm@prfenv@#2@val@displayenv\endcsname}##1}% \fi % \end{macrocode} % % See if we need to call |\newenvironment| or |\renewenvironment|, depending on % the value of the \cmdoptionfmt{override} option. % \begin{macrocode} \def\phfthm@tmp@defcmd{\newenvironment}% \ifKV@phfmkprf@override\def\phfthm@tmp@defcmd{\renewenvironment}\fi% % \end{macrocode} % % Finally, (re-)define the environment. The default value of the optional % argument is the token |\phfthm@NOPROOFARG|, which indicates that no argument % was provided. % % Start by storing the value of the argument into a macro, and then call the % ``start'' hook (see proof hooks in \autoref{sec:proof-hooks}). % \begin{macrocode} \phfthm@tmp@defcmd{#2}[1][\phfthm@NOPROOFARG]{% \def\phfthm@val@proofarg{##1}% \csname phfthm@hookproof@#2@start\endcsname% % \end{macrocode} % % First, parse the optional argument into proof label (maybe) and proof title. % If no optional argument was given, don't give any argument to the underlying % display environment. If an empty argument was given, set some defaults; % otherwise, use the necessary command to potentially parse the label and create % the proper arguments for the underlying display environment. % \begin{macrocode} \ifx\phfthm@val@proofarg\phfthm@test@NOPROOFARG\relax% \def\phfthm@val@proofoflabel{}% \csname phfthm@prfenv@#2@val@setdefaultprooftitle\endcsname% \letcs\phfthm@val@displayargs{phfthm@prfenv@#2@val@defaultproofnameargs}% \else% \if\relax\detokenize{##1}\relax% \def\phfthm@val@proofoflabel{}% \csname phfthm@prfenv@#2@val@setdefaultprooftitle\endcsname% \def\phfthm@val@displayargs{[{% \csname phfthm@prfenv@#2@val@proofofname\endcsname {\phfthm@val@prooftitle}% }]}% \else \csname phfthm@prfenv@#2@val@parselabelandmkdisplayargs\endcsname{##1}% \fi \fi% % \end{macrocode} % % Define the |\phfPinProofAnchor| command (locally) in case the % display formatting environment takes care of where to place the anchor already. % \begin{macrocode} \def\phfPinProofAnchor{% \csname phfthm@prfenv@#2@val@pinproofanchor\endcsname% \global\let\phfPinProofAnchor\relax}% % \end{macrocode} % [Also provide the obsolete |\phfthmPinProofAnchor| which I previously had in % older versions of this package:] % \begin{macrocode} \def\phfthmPinProofAnchor{\phfPinProofAnchor}% % \end{macrocode} % % Start the proof's display environment. Don't be fooled here by the curly % braces after |\x|, it only protects the argument to the % |\phfthm@prfenv@#2@val@displayenvbegincmd| command itself: the % |\phfthm@val@displayargs| are still just tokens which will be expanded in % front of the |\beg||in{}| command. % \begin{macrocode} \def\x{\csname phfthm@prfenv@#2@val@displayenvbegincmd\endcsname}% \expandafter\x\expandafter{\phfthm@val@displayargs}% % \end{macrocode} % And call the corresponding hook: % \begin{macrocode} \csname phfthm@hookproof@#2@startafterdisplay\endcsname% % \end{macrocode} % If required, pin anchor after the proof-display-environment. % (|\phfPinProofAnchor| auto-destructs after first use, so it's safe to % potentially call it a second time here). Then, call the corresponding hook. % \begin{macrocode} \phfPinProofAnchor% \expandafter\noexpand\csname phfthm@hookproof@#2@startlast\endcsname% }% % \end{macrocode} % % Now, the definitions for the ``end'' part of the environment. Just call the % relevant hooks and close the display environment. % \begin{macrocode} {% \expandafter\noexpand\csname phfthm@hookproof@#2@end\endcsname% \csname phfthm@prfenv@#2@val@displayenvendcmd\endcsname \expandafter\noexpand\csname phfthm@hookproof@#2@final\endcsname% }% % \end{macrocode} % % Finally, define the default values of the proof-environment-specific hooks. % These just call the corresponding global hooks (see \autoref{sec:proof-hooks}). % \begin{macrocode} \csdef{phfthm@hookproof@#2@start}{\phfthm@hookproof@startcommon{#2}}% \csdef{phfthm@hookproof@#2@startafterdisplay}{% \phfthm@hookproof@startafterdisplaycommon{#2}}% \csdef{phfthm@hookproof@#2@startlast}{\phfthm@hookproof@startlastcommon{#2}}% \csdef{phfthm@hookproof@#2@end}{\phfthm@hookproof@endcommon{#2}}% \csdef{phfthm@hookproof@#2@final}{\phfthm@hookproof@finalcommon{#2}}% } % \end{macrocode} % \end{macro} % % % \subsubsection{Common hooks for proofs} % % The hooks are documented in \autoref{sec:proof-hooks}. % \begin{macrocode} \def\phfthm@hookproof@startcommon#1{} \def\phfthm@hookproof@startafterdisplaycommon#1{} \def\phfthm@hookproof@startlastcommon#1{} \def\phfthm@hookproof@endcommon#1{} \def\phfthm@hookproof@finalcommon#1{} % \end{macrocode} % % % \subsubsection{Default display environment for proofs} % % \begin{environment}{phfthm@proof@defaultdisplayenv} % Provide an environment which displays a proof in a similar fashion as % \emph{AMS}', but with some small additional features. % \begin{macrocode} \newenvironment{phfthm@proof@defaultdisplayenv}[1][\proofname]{% \par \pushQED{\qed}% \normalfont \topsep6\p@\@plus6\p@\relax \trivlist\item\relax \phfPinProofAnchor \phfthm@ProofTitleFmt{#1}% \phfthm@ProofTitleHspace \ignorespaces }{% \popQED\endtrivlist\@endpefalse } % \end{macrocode} % \end{environment} % % \begin{macro}{\phfthm@ProofTitleFmt} % \begin{macro}{\phfthm@ProofTitleHspace} % These macros may be overridden to change the proof title appearance. % \begin{macrocode} \def\phfthm@ProofTitleFmt#1{% {\itshape #1.}% } \def\phfthm@ProofTitleHspace{% \hspace{1.5ex plus 0.5ex minus 0.2ex}% } % \end{macrocode} % \end{macro} % \end{macro} % % \subsubsection{Parsing the proof argument} % % These macros parse the argument of the proof environment to see if it is of % the form |*| (see \autoref{sec:proof-ref-mechanism}). % % \begin{macro}{\phfthm@proof@parselabel} % Call |\phfthm@proof@parselabel|\marg{proof environment argument} to parse % the argument string. This macro will set |\phfthm@val@proofoflabel| and % |\phfthm@val@prooftitle| to appropriate values (respectively, the label name % of the corresponding theorem and a representative title such as ``Theorem % 6''). % \begin{macrocode} \def\phfthm@proof@parselabel#1{% \phfthm@proof@parselabel@maybelabel#1\phfthm@proof@parselabel@END% } % \end{macrocode} % If the argument is |[*thm-label]| we want ``Proof of \meta{ref to % thm-label}.''. If the argument is |[**thm-label]| we want ``Proof.'' but % we're informing the proofref-system that this is the proof of \meta{thm-label} % (e.g., to avoid undefined references to proofs). Otherwise if we get % % |[Some Custom Theorem]| then we want ``Proof of Some Custom Theorem.''. % \begin{macrocode} \def\phfthm@proof@parselabel@maybelabel{% \@ifnextchar*\phfthm@proof@parselabel@label\phfthm@proof@parselabel@title% } \def\phfthm@proof@parselabel@label*{% \@ifnextchar*\phfthm@proof@parselabel@labelsilent\phfthm@proof@parselabel@labelnormal% } \def\phfthm@proof@parselabel@labelsilent*#1\phfthm@proof@parselabel@END{% % \end{macrocode} % The use of |\detokenize| here is a trick to make sure that all chars in the % label text have a non-active category (e.g.\@ we would have problems, e.g., if % in the label ``|thm:gauss|'' the ``|:|'' is an active char---such as in French): % \begin{macrocode} \edef\phfthm@val@proofoflabel{\detokenize{#1}}% \def\phfthm@val@prooftitle{}% } \def\phfthm@proof@parselabel@labelnormal#1\phfthm@proof@parselabel@END{% \edef\phfthm@val@proofoflabel{\detokenize{#1}}% \def\phfthm@val@prooftitle{\phfthm@autoref{#1}}% } \def\phfthm@proof@parselabel@title#1\phfthm@proof@parselabel@END{% \def\phfthm@val@proofoflabel{}% \def\phfthm@val@prooftitle{#1}% } % \end{macrocode} % \end{macro} % \begin{macro}{\phfthm@proof@noparselabel} % Enjoys the same syntax as |\phfthm@proof@parselabel|, i.e., it is a drop-in % replacement for the latter, except that it invariably sets % |\phfhtm@val@proofoflabel| to an empty value and |\phfthm@val@prooftitle| to % the argument itself. You could use this as a \cmdoptionfmt{parselabelcmd} % macro if you didn't want to parse the label. % \begin{macrocode} \def\phfthm@proof@noparselabel#1{% \def\phfthm@val@proofoflabel{}% \def\phfthm@val@prooftitle{#1}% } % \end{macrocode} % \end{macro} % % % In order to look up what we are a proof of, we use |\autoref| provided by the % \pkgname{hyperref} package. Crucially, it is NOT the job of \pkgname{phfthm} % to load this package, and we should only use them if they are available (we % don't want to depend on it). If it is not available, then we fall back to the % regular |\ref| command. % \begin{macrocode} \def\phfthm@autoref{\ref} \AtBeginDocument{% \@ifpackageloaded{hyperref}{\def\phfthm@autoref{\autoref}}{}% } % \end{macrocode} % % % \subsection{Implementation of the proof-ref machinery} % % \subsubsection{Small general stuff} % % \begin{macro}{\proofonname} % The macro |\proofonname| displays ``Proof on \ldots.'' Here, |#2| is the % full page reference and |#1| is the label name of the referenced theorem. % \begin{macrocode} \providecommand\proofonname[2]{Proof on #2.} % \end{macrocode} % \end{macro} % % \begin{macro}{\proofrefsize} % Format the proof reference ``Proof on page \ldots''. This macro is meant to % set the font size (or other font properties), but it may also be defined to % take one argument, the proof reference text. % \begin{macrocode} \def\proofrefsize{\footnotesize} % \end{macrocode} % \end{macro} % % % \begin{macro}{\noproofref} % Use |\noproofref| inside a theorem to signify that no proof reference should % be attempted. % % The implementation just defines |\phfthm@val@noproofref|. If this macro is % defined, then no proof ref should be generated for the current thmlabel. % Also, restore |\label| to its original definition in case it was overridden. % \begin{macrocode} \def\noproofref{% \def\phfthm@val@noproofref{1}% \ifdefined\phfthm@old@label \let\label\phfthm@old@label \fi% } % \end{macrocode} % \end{macro} % % % \begin{macro}{\phfthm@proofref@warnnolabel} % Produce a warning that no label was provided in order to infer the proof % reference. % \begin{macrocode} \def\phfthm@proofref@warnnolabel{% \PackageWarning{phfthm}{No label provided for proof reference!}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\phfthm@proofref@expandthmlabeltoarg} % Utility to expand the value of |\phfthm@val@thmlabel| as an argument to a % callback command. |#1| = the macro to relay the call to. % \begin{macrocode} \def\phfthm@proofref@expandthmlabeltoarg#1{% % \end{macrocode} % % First, check if the proof-ref mechanism was explicitly temporarily disabled, % and do nothing if that is the case. % \begin{macrocode} \ifdefined\phfthm@val@noproofref\relax% \else% % \end{macrocode} % % Then make sure |\phfthm@val@thmlabel| is defined (maybe empty), and then % either call the callback macro |#1| with the value of |\phfthm@val@thmlabel| % as argument, or generate a warning if that value is empty. % \begin{macrocode} \providecommand\phfthm@val@thmlabel{}% \edef\phfthm@tmpa{{\phfthm@val@thmlabel}}% \expandafter\notblank\phfthm@tmpa{% \expandafter#1\phfthm@tmpa% }{% \phfthm@proofref@warnnolabel% no label provided }% \fi% } % \end{macrocode} % \end{macro} % % % \subsubsection{Utilities for interacting with \phfverb{\autoref} labels} % % In this context, we also need some generic utilities for interacting with % |\autoref| labels. % % \begin{macro}{\phfthm@autorefnameof} % The macro |\phfthm@autorefnameof| extracts the name of the counter which % generated this reference (e.g.\@ ``section'' or ``theorem''). % \begin{macrocode} \def\phfthm@autorefnameof#1{% % \end{macrocode} % % Extract the counter part of the reference |section.NN|, which is 4th element in the % |\r@label| macro. (Code extracted from |hyperref.sty|.) % \begin{macrocode} \expandafter\ifx\csname r@#1\endcsname\relax% \textbf{??}% \else% \expandafter\expandafter\expandafter\phfthm@HyPsd@autorefname% \csname r@#1\endcsname{}{}{}{}\@nil% \fi% } \def\phfthm@HyPsd@autorefname#1#2#3#4#5\@nil{% \ifx\\#4\\% \else% \phfthm@HyPsd@@autorefname#4.\@nil% \fi% } \def\phfthm@HyPsd@@autorefname#1.#2\@nil{% \ltx@IfUndefined{#1autorefname}{% \ltx@IfUndefined{#1name}{% }{% \csname#1name\endcsname% }% }{% \csname#1autorefname\endcsname% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\phfthm@min@pageref} % A minimal pageref macro, which just extracts the page number on which the % given label is located. % % The dark magic going on here is beyond me. The code was copied from % |hyperref.sty|, in ``|\def\HyPsd@@@pageref...|'' and seems to work. % % \begin{macrocode} \def\phfthm@min@pageref#1{% \ifcsname r@#1\endcsname% \expandafter\expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\@car \expandafter\expandafter\expandafter\@gobble \csname r@#1\endcsname{}\@nil \else% 0% \fi% } % \end{macrocode} % \end{macro} % % % \subsubsection{Default proof-ref style, with basic machinery} % \label{sec:impl-default-proof-ref-style} % % Now we define the relevant callbacks for the default style. See documentation % in \autoref{sec:proof-ref-customize-appearance}. Recall a proof-ref style % just needs to define |\phfthm@proofrefstyle@@setup|, which in turn % should just define the callbacks |\phfthm@proofref@impl@start|, % |\phfthm@proofref@impl@afterlabel| and |\phfthm@proofref@impl@end|. For our % default style, these callbacks further call other callbacks of the form % |\phfthm@proofref@impl@...|, such that these definitions can be re-used to % create new styles. The main proof-ref generation routine is % |\phfthm@proofrefstyle@default@main|, which can be used for either the % |...@afterlabel| or the |...@end| callback. % % \begin{macro}{\phfthm@proofrefstyle@default@fmt} % Format and display the proof reference. |#1| = the theorem's label % (e.g. |prop:1|); |#2| = the full reference (e.g. ``page XYZ''). % % This macro is the default value of the callback |\phfthm@proofref@impl@fmt|, % which is called by the default style itself. % % Use correct spacing for right-aligning the reference.\footnote{Thanks % \url{http://tex.stackexchange.com/a/43239/32188}!} If there is room on the % current line, just right-align the proof-ref text; if not, add it on a % separate line. [We can achieve this with the sequences |\hfil\null\hfil|: % if there is space, it all fits on the same line, if not, the line breaks at % the |\null| point.] % \begin{macrocode} \def\phfthm@proofrefstyle@default@fmt#1#2{% {\parfillskip=0pt\relax% \hfil\null\hfil\null\hfil% \hbox{\proofrefsize{(\proofonname{#1}{#2})}}\par}% } % \end{macrocode} % \end{macro} % % % \begin{macro}{\phfthm@proofrefstyle@default@fmtfarback} % \begin{macro}{\phfthm@proofrefstyle@default@fmtfarahead} % \begin{macro}{\phfthm@proofrefstyle@default@fmtcloseby} % These macros are the default values of the callbacks % |\phfthm@proofref@impl@fmtfarback|, |\phfthm@proofref@impl@fmtfarahead|, and % |\phfthm@proofref@impl@fmtcloseby|, which are called by the default style % itself. These callbacks define how to format and (possibly not) display the % proof reference depending on whether the proof is ``far behind'' (several % pages back), ``far ahead'' (several pages ahead) or ``close by'' (neither % far back nor far ahead), as defined by |\phfProofrefPageBackTolerance| % and |\phfProofrefPageAheadTolerance|. % \begin{macrocode} \def\phfthm@proofrefstyle@default@fmtfarback#1#2{% \phfthm@proofref@impl@fmt{#1}{#2}} \def\phfthm@proofrefstyle@default@fmtfarahead#1#2{% \phfthm@proofref@impl@fmt{#1}{#2}} \def\phfthm@proofrefstyle@default@fmtcloseby#1#2{} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\phfProofrefPageBackTolerance} % \begin{macro}{\phfProofrefPageAheadTolerance} % The macros |\phfProofrefPageBackTolerance| and % |\phfProofrefPageAheadTolerance| define how many pages back or ahead the % proof should be in order to consider it ``far back'' or ``far ahead.'' % % Either value may be set to |-1| to force the proof to be considered ``far % back'' or ``far ahead.'' % \begin{macrocode} \newcommand\phfProofrefPageBackTolerance{1} \newcommand\phfProofrefPageAheadTolerance{1} % \end{macrocode} % \end{macro} % \end{macro} % % Define the internal counter which allows to check on which page we are at the % place of the proof reference. This is used by % |\phfthm@proofrefstyle@default@main|. % \begin{macrocode} \newcounter{phfthmInternalProofrefCounter} % \end{macrocode} % % \begin{macro}{\phfthm@proofrefstyle@default@main} % The main proof-ref generation routine. The argument |#1| is the current % label of the theorem; the referenced label is |proof:#1|. % \begin{macrocode} \def\phfthm@proofrefstyle@default@main#1{% % \end{macrocode} % % Check to see if the proof is far away ahead or back (as defined by the % tolerance macros above). Depending on each case, call the corresponding % callbacks.{\makeatletter\footnote{See \url{http://tex.stackexchange.com/a/2526} to test % whether ref is on same page. Note that was problematic, probably due to % hyperref. I needed to use my own \phfverb{\phfthm@min@pageref} % without any hyper linking mechanism in place.}} % % \begin{macrocode} \refstepcounter{phfthmInternalProofrefCounter}% \label{internalproofref\thephfthmInternalProofrefCounter}% \edef\phfthm@proofref@tmp@proofpage{\phfthm@min@pageref{proof:#1}}% \edef\phfthm@proofref@tmp@thispage{% \phfthm@min@pageref{internalproofref\thephfthmInternalProofrefCounter}}% \edef\phfthm@proofref@tmp@pagediff{% \the\numexpr\phfthm@proofref@tmp@proofpage-\phfthm@proofref@tmp@thispage\relax}% % \end{macrocode} % % If the proof is ``far back,'' call the corresponding callback. % \begin{macrocode} \ifnum\numexpr\phfthm@proofref@tmp@pagediff\relax% <\numexpr-\phfProofrefPageBackTolerance\relax% \phfthm@proofref@impl@fmtfarback{#1}{\autopageref{proof:#1}}% \else% % \end{macrocode} % % If the proof is ``far ahead,'' call the corresponding callback. % \begin{macrocode} \ifnum\numexpr\phfthm@proofref@tmp@pagediff\relax% >\numexpr\phfProofrefPageAheadTolerance\relax% \phfthm@proofref@impl@fmtfarahead{#1}{\autopageref{proof:#1}}% % \end{macrocode} % % Otherwise, it is close by. % \begin{macrocode} \else% \phfthm@proofref@impl@fmtcloseby{#1}{\autopageref{proof:#1}}% \fi% \fi% %% [\number\numexpr\phfthm@proofref@tmp@proofpage\relax{} vs % DEBUG %% \number\numexpr\phfthm@proofref@tmp@thispage\relax or % DEBUG %% \number\numexpr1+\phfthm@proofref@tmp@thispage\relax] % DEBUG } % \end{macrocode} % \end{macro} % % % % \begin{macro}{\phfthm@proofrefstyle@default@setup} % The main set-up macro for the |default| proof-ref style. It sets all the % call-backs to the default ones. % \begin{macrocode} \def\phfthm@proofrefstyle@default@setup{% \let\phfthm@proofref@impl@start\relax \let\phfthm@proofref@impl@afterlabel\@gobble \let\phfthm@proofref@impl@end\phfthm@proofrefstyle@default@main \let\phfthm@proofref@impl@fmtfarback\phfthm@proofrefstyle@default@fmtfarback \let\phfthm@proofref@impl@fmtfarahead\phfthm@proofrefstyle@default@fmtfarahead \let\phfthm@proofref@impl@fmtcloseby\phfthm@proofrefstyle@default@fmtcloseby \let\phfthm@proofref@impl@fmt\phfthm@proofrefstyle@default@fmt } % \end{macrocode} % \end{macro} % % % \subsubsection{Other proof-ref styles: \phfverb{margin} and \phfverb{marginbottom}} % % These styles simply use the same mechanism as the default style, but plug in % different sub-callbacks. % % Here's a command that actually places the marginpar: % \begin{macro}{\phfthmproofref@placemarginpar} % \begin{macrocode} \newcommand\phfthmproofref@placemarginpar[2]{% \marginpar[% \raggedleft #1% ]{% \raggedright #2% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\phfthmproofref@placephantommarginpar} % In the |marginbottom| proof-ref style, we place an invisible |\marginpar| at % the top of the proof so that the proof-ref margin note will not be shifted % too high when we try to align it to the bottom of the theorem statement. To % work around a weird bug in Rev\TeX, where I get the error message `command % sequence undefined: |\@captype|', I have found that a fix is to override % this local invisible |\marginpar| to locally make sure the |\@captype| is % defined. The wild fix I've found---no guarantees, there are dark magic % forces at work here---is the following, which you can include in your % document preamble if you're banging your head against this problem and % you're desperate: % \begin{verbatim} % \makeatletter % \renewcommand\phfthmproofref@placephantommarginpar{% % \begingroup\csdef{@captype}{figure}\marginpar{% % \vspace{-\baselineskip}\rule{0pt}{0pt}}\endgroup% % } % \makeatother % \end{verbatim} % \begin{macrocode} \newcommand\phfthmproofref@placephantommarginpar{% \leavevmode\marginpar{\vspace{-\baselineskip}\rule{\z@}{\z@}}% }% % \end{macrocode} % \end{macro} % % % \paragraph{The \phfverb{margin} style} % % \begin{macro}{\phfthm@proofrefstyle@margin@setup} % Set-up macro for the ``|margin|'' proof-ref style (displays the proof % reference in the margin of the page). % \begin{macrocode} \def\phfthm@proofrefstyle@margin@setup{% \phfthm@proofrefstyle@default@setup % \end{macrocode} % % The proof reference should be displayed directly at the top, not at the end of % the theorem, so plug in |\phfthm@proofref@default@main| onto |...@afterlabel| % and not onto |...@end|. Don't forget that these macros accept one argument, % the theorem label. % \begin{macrocode} \let\phfthm@proofref@impl@afterlabel\phfthm@proofrefstyle@default@main \let\phfthm@proofref@impl@end\@gobble % \end{macrocode} % % Define the formatting callback to put the note in the margin of the page using % a |\marginpar|. We need |\leavevmode| to make sure it's aligned properly % vertically with the paragraph.\footnote{See % \url{http://tex.stackexchange.com/a/16161/32188}} % \begin{macrocode} \def\phfthm@proofref@impl@fmt##1##2{% \leavevmode\phfthmproofref@placemarginpar{% \proofrefsize{\proofonname{##1}{##2}}% }{% \proofrefsize{\proofonname{##1}{##2}}% }% }% } % \end{macrocode} % \end{macro} % % \paragraph{The \phfverb{marginbottom} style} % % \begin{macro}{\phfthm@proofrefstyle@marginbottom@setup} % Set-up macro for the ``|marginbottom|'' proof-ref style (displays the proof % reference in the margin of the page). % \begin{macrocode} \def\phfthm@proofrefstyle@marginbottom@setup{% \phfthm@proofrefstyle@default@setup % \end{macrocode} % % The proof reference should be displayed directly at the bottom, not at the end % of the theorem, so plug in |\phfthm@proofref@default@main| onto |...@end| and % not onto |...@afterlabel|. Don't forget that these macros accept one % argument, the theorem label. In |...@afterlabel| we place a dummy marginpar % with an invisible rule one |\baselineskip| upwards, so that we force any % proof-ref marginpar not to extend above the top of the theorem statement. % \begin{macrocode} \def\phfthm@proofref@impl@afterlabel##1{% \phfthmproofref@placephantommarginpar }% \let\phfthm@proofref@impl@end\phfthm@proofrefstyle@default@main % \end{macrocode} % % Define the formatting callback to put the note in the margin of the page using % a |\marginpar|. We use a trick to align the margin note with the bottom of % the paragraph.\footnote{\url{https://tex.stackexchange.com/a/388018/32188}} % \begin{macrocode} \def\phfthm@proofref@impl@fmt##1##2{% \phfthmproofref@marginbottom@domarginpar{##1}{##2}% }% } \def\phfthmproofref@marginbottom@domarginpar#1#2{% \setbox\phfthm@tmp@boxa=\hbox to \marginparwidth{% \parbox[b]{\marginparwidth}{\raggedleft\sloppy \proofrefsize{\strut\proofonname{#1}{#2}\strut}}}% \setbox\phfthm@tmp@box=\hbox to \marginparwidth{% \parbox[b]{\marginparwidth}{\raggedright\sloppy \proofrefsize{\strut\proofonname{#1}{#2}\strut}}}% \phfthmproofref@placemarginpar{% \box\phfthm@tmp@boxa% }{% \box\phfthm@tmp@box% }% } \newbox\phfthm@tmp@box \newbox\phfthm@tmp@boxa % \end{macrocode} % \end{macro} % % % \subsection{Thmheading definition-like environments} % % % \subsubsection{Manually define a thmheading environment} % % Define the key-value options accepted by |\phfMakeThmheadingEnvironment|. % \begin{macrocode} \define@cmdkey{phfthmmkthmheading}{thmstyle}{} \define@cmdkey{phfthmmkthmheading}{internalcounter}{} % \end{macrocode} % % \begin{macrocode} \newcounter{phfthmheadingcounter}% % \end{macrocode} % % \begin{macro}{\phfMakeThmheadingEnvironment} % % Creates a new environment |\begin{thmheading}{Title}...\end{thmheading}| for % customizing the heading on-the-fly (see documentation in % \autoref{sec:thmheading}). Useful for an alternative formatting of % definitions. The syntax is: % % \noindent|\phfMakeThmheadingEnvironment|\oarg{key-value options}\marg{environment name} % % You can also use |\label| and |\ref| (the latter simply displays the given % title). % % % \begin{macrocode} \newcommand\phfMakeThmheadingEnvironment[2][]{% } % \end{macrocode} % % Parse the options. First set defaults, and then parse the input string. % \begin{macrocode} \def\cmdKV@phfthmmkthmheading@thmstyle{plain}% \def\cmdKV@phfthmmkthmheading@internalcounter{phfthmheadingcounter}% \setkeys{phfthmmkthmheading}{#1}% % \end{macrocode} % % And now, produce the relevant definitions: % \begin{macrocode} \csdef{phfthm@thmheading@#2@val@title}{$\langle$No Title Given$\rangle$}% \theoremstyle{\cmdKV@phfthmmkthmheading@thmstyle}% % \end{macrocode} % % We use |\newtheorem*| to create an unnumbered theorem. The fixed title is just % a single token, the macro which will be set to the relevant title at the last % moment. % \begin{macrocode} \newtheorem*{phfthm@internal@thmheading@#2}{% \csname phfthm@thmheading@#2@val@title\endcsname}% % \end{macrocode} % % Define the actual environment. % \begin{macrocode} \newenvironment{#2}[1]{%} \csdef{phfthm@thmheading@#2@val@title}{##1}% \letcs\thephfthmheadingcounter{phfthm@thmheading@#2@val@title}% % \end{macrocode} % Relay call to the internal \textit{AMS}-defined ``theorem:'' % \begin{macrocode} \csname phfthm@internal@thmheading@#2\endcsname% % \end{macrocode} % Pin down an anchor. The use of |\hspace*{0pt}| is explained at % \url{http://tex.stackexchange.com/a/88493/32188} (see especially the first % comment). % \begin{macrocode} \hspace*{0pt}\refstepcounter{\cmdKV@phfthmmkthmheading@internalcounter}% \csname phfthm@hook@thmheading@#2@start\endcsname{##1}% % \end{macrocode} % Also, let's add some flexibility in the hspace: % \begin{macrocode} \hskip 0em plus 0.5em minus 0em% \ignorespaces% }% % \end{macrocode} % % Now, the END part of the environment: just call the callback and close the % internal AMS-defined theorem. % \begin{macrocode} {% \csname phfthm@hook@thmheading@#2@end\endcsname% \csname endphfthm@internal@thmheading@#2\endcsname% }% % \end{macrocode} % % Also define the relevant callbacks, which just relay their calls to the % default callbacks. % \begin{macrocode} \csdef{phfthm@hook@thmheading@#2@start}##1{% \phfthm@hook@thmheading@start{##1}}% \csdef{phfthm@hook@thmheading@#2@end}{\phfthm@hook@thmheading@end}% } % \end{macrocode} % % Provide as well the obsolete command |\phfthmMakeThmheadingEnvironment| which % was provided in earlier versions of this package: % \begin{macrocode} \def\phfthmMakeThmheadingEnvironment{\phfMakeThmheadingEnvironment} % \end{macrocode} % \end{macro} % % % \begin{macro}{\phfthm@hook@thmheading@start} % \begin{macro}{\phfthm@hook@thmheading@end} % Global callbacks which are called for all thmheading-type environments % defined with |\phfMakeThmheadingEnvironment| (unless their hooks have % been changed in order for them not to call these global hooks). % \begin{macrocode} \def\phfthm@hook@thmheading@start#1{} \def\phfthm@hook@thmheading@end{} % \end{macrocode} % \end{macro} % \end{macro} % % % \subsection{Theorem sets} % % Here, we define the theorem sets proposed by the package for quick loading. % % We first define the names. These are defined in any case regardless of % whether we are loading a theorem set or of which theorem set we are loading. % \begin{macrocode} \def\theoremname{Theorem} \def\propositionname{Proposition} \def\lemmaname{Lemma} \def\corollaryname{Corollary} \def\conjecturename{Conjecture} \def\remarkname{Remark} \def\definitionname{Definition} \def\ideaname{Idea} \def\questionname{Question} \def\claimname{Claim} \def\observationname{Observation} \def\problemname{Problem} % \end{macrocode} % % As we define the theorem sets, remember the names in a comma-separated list % which we can display in help text. The |\phfthm@def@thmset| replaces the % |\def| command and expects the definitions to follow immediately. % \begin{macrocode} \def\phfthm@def@thmset@optlist{} \def\phfthm@def@thmset#1{% \appto\phfthm@def@thmset@optlist{#1,}\csdef{phfthm@thmset@#1}} % \end{macrocode} % % % \begin{macro}{\phfthm@def@thmset@mktheorem} % \begin{macro}{\phfthm@def@thmset@mkdefn} % In definitions of theorem sets, use these macros to define a new % theorem-like environment (theorem, proposition, corollary, etc.) or % definition-like environment (definition, remark). The macros % |\phfthm@val@mkthmoptarg@theorem| and |\phfthm@val@mkthmoptarg@defn| are % defined by |\phfLoadThmSet|. % \begin{macrocode} \def\phfthm@def@thmset@mktheorem{% \expandafter\phfMakeTheorem\phfthm@val@mkthmoptarg@theorem} \def\phfthm@def@thmset@mkdefn{% \expandafter\phfMakeTheorem\phfthm@val@mkthmoptarg@defn} % \end{macrocode} % \end{macro} % \end{macro} % % The default set (empty name, or name ``|empty|'') provides no theorem. (The % first line uses |\def| directly so that we don't include an empty item in the % list of available choices.) % \begin{macrocode} \def\phfthm@thmset@{} \phfthm@def@thmset{empty}{} % \end{macrocode} % % Theorem set |simple|: % \begin{macrocode} \phfthm@def@thmset{simple}{ \phfthm@def@thmset@mktheorem{theorem}{\theoremname} \phfthm@def@thmset@mktheorem{proposition}{\propositionname} \phfthm@def@thmset@mktheorem{lemma}{\lemmaname} \phfthm@def@thmset@mktheorem{corollary}{\corollaryname} \phfthm@def@thmset@mkdefn{definition}{\definitionname} } % \end{macrocode} % % Theorem set |default|: % \begin{macrocode} \phfthm@def@thmset{default}{ \phfthm@def@thmset@mktheorem{theorem}{\theoremname} \phfthm@def@thmset@mktheorem{proposition}{\propositionname} \phfthm@def@thmset@mktheorem{lemma}{\lemmaname} \phfthm@def@thmset@mktheorem{corollary}{\corollaryname} \phfthm@def@thmset@mktheorem{conjecture}{\conjecturename} \phfthm@def@thmset@mktheorem{remark}{\remarkname} \phfthm@def@thmset@mkdefn{definition}{\definitionname} } % \end{macrocode} % % Theorem set |shortnames|: % \begin{macrocode} \phfthm@def@thmset{shortnames}{ \phfthm@def@thmset@mktheorem{thm}{\theoremname} \phfthm@def@thmset@mktheorem{prop}{\propositionname} \phfthm@def@thmset@mktheorem{lem}{\lemmaname} \phfthm@def@thmset@mktheorem{cor}{\corollaryname} \phfthm@def@thmset@mktheorem{conj}{\conjecturename} \phfthm@def@thmset@mktheorem{rem}{\remarkname} \phfthm@def@thmset@mkdefn{defn}{\definitionname} } % \end{macrocode} % % Theorem set |rich|. Add definitions to the |default| set: % \begin{macrocode} \phfthm@def@thmset{rich}{ \phfthm@thmset@default \phfthm@def@thmset@mktheorem{idea}{\ideaname} \phfthm@def@thmset@mktheorem{question}{\questionname} \phfthm@def@thmset@mktheorem{claim}{\claimname} \phfthm@def@thmset@mktheorem{observation}{\observationname} \phfthm@def@thmset@mktheorem{problem}{\problemname} } % \end{macrocode} % % % \begin{macro}{\phfLoadThmSet} % The macro |\phfLoadThmSet| loads a theorem set. See documentation at % \autoref{sec:load-thm-set-manually}. % % |#1| = options to |\phfMakeTheorem| for theorem-like environments % % |#2| = options to |\phfMakeTheorem| for definition-like environments % % |#3| = name of the theorem set to load % % \begin{macrocode} \newcommand\phfLoadThmSet[3]{% \ifcsname phfthm@thmset@#3\endcsname% \edef\phfthm@val@mkthmoptarg@theorem{#1}% \edef\phfthm@val@mkthmoptarg@defn{#2}% \csname phfthm@thmset@#3\endcsname% \else% \PackageWarning{phfthm}{Unknown theorem set: `#3'!}% \fi% } % \end{macrocode} % % For compatibility with my earlier versions of \pkgname{phfthm}, also provide % the obsolete |\phfthmLoadThmSet|: % \begin{macrocode} \def\phfthmLoadThmSet{\phfLoadThmSet} % \end{macrocode} % \end{macro} % % % \subsection{Package option handling} % % The machinery is in place, now define and parse the package options. % % \subsubsection{Declaring the package options} % % The package options all use the |keyval| parsing mechanism using the % \pkgname{xkeyval} package. % % Recall when using |\define@XXXkey| that the optional argument after the second % mandatory argument is the value which is assumed if the key is given with no % explicit value; it is not the initial default value. % % \paragraph{The \pkgoptionfmt{resetstyle} package option} % An option to reset all options so that the package provides only stand-alone % definitions and is not invasive (see \autoref{sec:global-pkg-options}). % % This option does not expect any argument (i.e., you should specify % |\usepackage[resetstyle,|\meta{other options}|]{phfthm}|, and not % |\usepackage[resetstyle=true,|\meta{other options}|]{phfthm}|). % \begin{macrocode} \define@key{phfthmpkg}{resetstyle}[]{% \KV@phfthmpkg@smallproofsfalse% \KV@phfthmpkg@qedsymbolblacksquarefalse% \KV@phfthmpkg@prooftitleitbffalse% \KV@phfthmpkg@sepcountersfalse% \KV@phfthmpkg@countpersectionfalse% \KV@phfthmpkg@proofreffalse% \if\relax\detokenize{#1}\relax\else% \PackageError{phfthm}{'resetstyle' does not take any argument.}{You specified the 'resetstyle' argument and provided a value to it ('resetstyle=...'). However the 'resetstyle' option does not accept any value argument.} \fi% } % \end{macrocode} % % % \paragraph{Options for loading theorem sets} % Define the various package options for the loading of predefined theorem sets % (\autoref{sec:theorem-sets}). % % The \pkgoptionfmt{sepcounters} option, off by default. % \begin{macrocode} \define@boolkey{phfthmpkg}{sepcounters}[true]{} \KV@phfthmpkg@sepcountersfalse % \end{macrocode} % % The \pkgoptionfmt{countpersection} option, off by default. % \begin{macrocode} \define@boolkey{phfthmpkg}{countpersection}[true]{} \KV@phfthmpkg@countpersectionfalse % \end{macrocode} % % % The \pkgoptionfmt{proofref} option. The proof-ref is on initially by default. % \begin{macrocode} \newif\ifKV@phfthmpkg@proofref \KV@phfthmpkg@proofreftrue \def\cmdKV@phfthmpkg@proofref@style{default} % \end{macrocode} % Actually define the option itself. Here we do some customized parsing of the % value of the |proofref=...| option, to treat the cases |proofref=| (empty % argument) and |proofref=false| separately. % \begin{macrocode} \define@key{phfthmpkg}{proofref}[]{% \ifblank{#1}{% % \end{macrocode} % If a blank argument provided, set some sensible defaults with proofref on: % \begin{macrocode} \KV@phfthmpkg@proofreftrue% \def\cmdKV@phfthmpkg@proofref@style{default}% }{% % \end{macrocode} % Otherwise, check to see if the value is |false|, in which case deactivate the % proof-ref mechanism, or else, activate it and set the given style value as % documented in \autoref{sec:theorem-sets}. % \begin{macrocode} \ifstrequal{#1}{false}{% \KV@phfthmpkg@proofreffalse% }{% \KV@phfthmpkg@proofreftrue% \def\cmdKV@phfthmpkg@proofref@style{#1}% }% }% } % \end{macrocode} % % The \pkgoptionfmt{thmset} option. We subtly construct the command % |\define@choicekey{phfthmpkg}{thmset}[\val]{\phfthm@def@thmset@optlist}|, but % with the last macro (option list) expanded. % \begin{macrocode} \def\@tmpa{\define@choicekey{phfthmpkg}{thmset}[\val]} \edef\@tmpb{{\phfthm@def@thmset@optlist}} \expandafter\@tmpa\@tmpb{% \xdef\cmdKV@phfthmpkg@thmset{\val}% } % \end{macrocode} % By default we should load the |default| set. % \begin{macrocode} \def\cmdKV@phfthmpkg@thmset{default} % \end{macrocode} % % % The options \pkgoptionfmt{theoremstyle} and \pkgoptionfmt{definitionstyle} set % which theorem style to use for theorems and definitions, when loading the % given thmset. % \begin{macrocode} \define@cmdkey{phfthmpkg}{theoremstyle}{} \def\cmdKV@phfthmpkg@theoremstyle{plain} \define@cmdkey{phfthmpkg}{definitionstyle}{} \def\cmdKV@phfthmpkg@definitionstyle{definition} % \end{macrocode} % % % \paragraph{Proof environment options} % Define the package options \pkgoptionfmt{proofenv}, % \pkgoptionfmt{smallproofs}, \pkgoptionfmt{qedsymbolblacksquare}, and % \pkgoptionfmt{prooftitleitbf} (\autoref{sec:proof-env}). % \begin{macrocode} \define@boolkey{phfthmpkg}{proofenv}[true]{} \define@boolkey{phfthmpkg}{smallproofs}[true]{} \define@boolkey{phfthmpkg}{qedsymbolblacksquare}[true]{} \define@boolkey{phfthmpkg}{prooftitleitbf}[true]{} % \end{macrocode} % % Set the initial default values for these options. % \begin{macrocode} \KV@phfthmpkg@smallproofstrue \KV@phfthmpkg@qedsymbolblacksquaretrue \KV@phfthmpkg@proofenvtrue \KV@phfthmpkg@prooftitleitbffalse % \end{macrocode} % % % \paragraph{Options for a theorem-like heading environment} % Define the \pkgoptionfmt{thmheading} and \pkgoptionfmt{thmheadingstyle} % package options, documented in \autoref{sec:thmheading}. % \begin{macrocode} \define@boolkey{phfthmpkg}{thmheading}[true]{} \define@cmdkey{phfthmpkg}{thmheadingstyle}{} % \end{macrocode} % % The |thmheading| environment is provided by default; it's a stand-alone % definition anyway. The style defaults to the |plain| style. % \begin{macrocode} \KV@phfthmpkg@thmheadingtrue \def\cmdKV@phfthmpkg@thmheadingstyle{plain} % \end{macrocode} % % % \subsubsection{Parsing the package options} % The usual stuff (\pkgname{xkeyval}-flavored). % \begin{macrocode} \DeclareOptionX*{% \PackageWarning{phfthm}{Invalid option: `\CurrentOption'}% } \ProcessOptionsX % \end{macrocode} % % % \subsubsection{Execute package options-controlled actions} % % \paragraph{Loading a theorem set} % First, we need to take into account the options which alter the way the % theorem sets will be loaded (separate counters, proof-ref, etc.). % % Take care of the proof-ref stuff. First, define the possible styles (note % that these are not the same as the values to the |proofrefstyle| argument to % the |\phfMakeTheorem| command). % \begin{macrocode} \def\phfthm@val@mkthmopt@proofrefstyle{} \ifKV@phfthmpkg@proofref \def\phfthm@proofref@style@default{} \def\phfthm@proofref@style@{} % \end{macrocode} % Note that |proofref=always| and |proofref=onlyifveryfar| have a global effect, % because they set |\phfProofrefPageBackTolerance| and % |\phfProofrefPageAheadTolerance| (see documentation in % \autoref{sec:theorem-sets}). % \begin{macrocode} \def\phfthm@proofref@style@always{ \def\phfProofrefPageBackTolerance{-1} \def\phfProofrefPageAheadTolerance{-1} } \def\phfthm@proofref@style@onlyifveryfar{ \def\phfProofrefPageBackTolerance{2} \def\phfProofrefPageAheadTolerance{4} } \def\phfthm@proofref@style@margin{ \def\phfthm@val@mkthmopt@proofrefstyle{proofrefstyle=margin} } \def\phfthm@proofref@style@marginbottom{ \def\phfthm@val@mkthmopt@proofrefstyle{proofrefstyle=marginbottom} } \def\phfthm@proofref@style@longref{ % \end{macrocode} % For |longref|: by setting |\proofonname| globally, this option can be combined % with other styles. But then we also change the default style formatting to % avoid ugly line breaks. % \begin{macrocode} \def\proofonname##1##2{The proof of this \phfthm@autorefnameof{##1} can be found on ##2.} \def\phfthm@proofrefstyle@default@fmt##1##2{% \par{\raggedleft\proofrefsize{(\proofonname{##1}{##2})}\par}% } } \def\phfthm@proofref@style@off{ \def\phfthm@val@mkthmopt@proofrefstyle{proofref=false} } % \end{macrocode} % % Now execute the given styles. Construct the command % |\phfthm@internal@execattribs{phfthm@proofref@style@}|\hspace % {0pt}|{ProofRef Style}|\hspace{0pt}|{\cmdKV@phfthmpkg@proofref@style}|, but with % the last macro expanded. % \begin{macrocode} \def\x{% \phfthm@internal@execattribs{phfthm@proofref@style@}{ProofRef Style}} \expandafter\x\expandafter{\cmdKV@phfthmpkg@proofref@style} % \end{macrocode} % % Prepare the proof-ref option in case we don't want any proof reference % mechanism on. % % \changed[chg-bugfix-pkgopt-proofreffalse]{v1.1}{2019/03/12}{Bug fix: package % option \texttt{proofref\eqsign false} didn't have any effect} % \begin{macrocode} \else \def\phfthm@val@mkthmopt@proofrefstyle{proofref=false} \fi % \end{macrocode} % % % Take care of counters. In any case, define a common counter, in case we use a % common counter for all theorem types. (The counter is defined in any case, to % avoid breaking other code which might use it if suddenly the user decides to % use |sepcounters=true| for their document.) % \begin{macrocode} \newcounter{phfthmcounter} \setcounter{phfthmcounter}{0} % \end{macrocode} % % Prepare an argument to |\phfMakeTheorem| according to the % \pkgoptionfmt{countpersection} and \pkgoptionfmt{sepcounters} options. First % determine the parent counter in case \pkgoptionfmt{countpersection} is set % (|chapter| if |chapter| counter exists, else |section|). % \begin{macrocode} \ifKV@phfthmpkg@countpersection \ifcsname c@chapter\endcsname \def\phfthm@tmp@parentcountername{chapter} \else \def\phfthm@tmp@parentcountername{section} \fi \fi \ifKV@phfthmpkg@sepcounters \ifKV@phfthmpkg@countpersection \edef\phfthm@val@mkthmopt@counteropts{parentcounter=\phfthm@tmp@parentcountername} \else \def\phfthm@val@mkthmopt@counteropts{} \fi \else \def\phfthm@val@mkthmopt@counteropts{counter=phfthmcounter} \ifKV@phfthmpkg@countpersection \numberwithin{phfthmcounter}{\phfthm@tmp@parentcountername} \fi \fi % \end{macrocode} % % % Finally, load the theorem set defined by the options. The first argument % regroups the options for theorem environments (Theorem, Proposition, % Corollary, \ldots); the second argument regroups the options for definition % environments (Definition); the third argument is the theorem set name itself. % \begin{macrocode} \phfLoadThmSet% {[\phfthm@val@mkthmopt@counteropts,\phfthm@val@mkthmopt@proofrefstyle, thmstyle=\cmdKV@phfthmpkg@theoremstyle]}% {[\phfthm@val@mkthmopt@counteropts,proofref=false, thmstyle=\cmdKV@phfthmpkg@definitionstyle]}% {\cmdKV@phfthmpkg@thmset} % \end{macrocode} % (Note the absence of the proof-ref for definitions.) % % \paragraph{Define the proof environment} % If requested, define the |proof| environment (\autoref{sec:proof-env}). % First, make sure we take into account the options \pkgoptionfmt{smallproofs}, % \pkgoptionfmt{qedsymbolblacksquare} and \pkgoptionfmt{prooftitleitbf}. % \begin{macrocode} \def\phfthm@pkgopterr@require@proofenv#1{% \ifKV@phfthmpkg@proofenv\else% \PackageError{phfthm}{Option `#1' depends on `proofenv=true'}% \fi } \ifKV@phfthmpkg@smallproofs %\phfthm@pkgopterr@require@proofenv{smallproofs} \apptocmd\phfthm@hookproof@startcommon{% \def\baselinestretch{1.2}\footnotesize}{}{% Failed to change command \string\phfthm@hook@start@proof} \fi \ifKV@phfthmpkg@qedsymbolblacksquare %\phfthm@pkgopterr@require@proofenv{qedsymbolblacksquare} \RequirePackage{amssymb} \providecommand\filledsquare{\ensuremath{\blacksquare}} \renewcommand\qedsymbol{\text{\tiny\ensuremath{\filledsquare}}} \fi \ifKV@phfthmpkg@prooftitleitbf %\phfthm@pkgopterr@require@proofenv{prooftitleitbf} \def\phfthm@ProofTitleFmt#1{{\itshape\bfseries#1.}} \fi % \end{macrocode} % Go ahead and define the |proof| environment. Because we have already loaded % \pkgname{amsthm}, we need to override the existing |proof| environment. % \begin{macrocode} \ifKV@phfthmpkg@proofenv \phfMakeProofEnv[override=true]{proof} \fi % \end{macrocode} % % \paragraph{Define the theorem-heading environment} % Define the |thmheading| environment, if requested. % \begin{macrocode} \ifKV@phfthmpkg@thmheading \phfMakeThmheadingEnvironment% [thmstyle=\cmdKV@phfthmpkg@thmheadingstyle]{thmheading} \fi % \end{macrocode} % %\Finale \endinput