From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/phfthm/Makefile | 10 + macros/latex/contrib/phfthm/README.md | 15 + macros/latex/contrib/phfthm/phfthm.dtx | 2562 ++++++++++++++++++++++++++++++++ macros/latex/contrib/phfthm/phfthm.ins | 55 + macros/latex/contrib/phfthm/phfthm.pdf | Bin 0 -> 381267 bytes macros/latex/contrib/phfthm/pkg.mk | 167 +++ 6 files changed, 2809 insertions(+) create mode 100644 macros/latex/contrib/phfthm/Makefile create mode 100644 macros/latex/contrib/phfthm/README.md create mode 100644 macros/latex/contrib/phfthm/phfthm.dtx create mode 100644 macros/latex/contrib/phfthm/phfthm.ins create mode 100644 macros/latex/contrib/phfthm/phfthm.pdf create mode 100644 macros/latex/contrib/phfthm/pkg.mk (limited to 'macros/latex/contrib/phfthm') diff --git a/macros/latex/contrib/phfthm/Makefile b/macros/latex/contrib/phfthm/Makefile new file mode 100644 index 0000000000..fa97b2d7fd --- /dev/null +++ b/macros/latex/contrib/phfthm/Makefile @@ -0,0 +1,10 @@ + +PKG = phfthm + +-include pkg.mk + +pkg.mk: + ln -sf ../mkcommon/pkg.mk pkg.mk + +install: install_sty install_doc + diff --git a/macros/latex/contrib/phfthm/README.md b/macros/latex/contrib/phfthm/README.md new file mode 100644 index 0000000000..8f0aece3fe --- /dev/null +++ b/macros/latex/contrib/phfthm/README.md @@ -0,0 +1,15 @@ +# The phfthm package + +Goodies for theorems and proofs. + +The phfthm package provides enhanced theorem and proof environments, based on +the amsthm original versions. It allows for hooks to be placed, adds some +default goodies and is highly customizable. In particular, it can connect +theorems to proofs, automatically producing text such as "See proof on page XYZ" +and "Proof of Theorem 4: ..." + + +# Documentation + +Run 'make sty' to generate the style file and 'make pdf' to generate the package +documentation. Run 'make' or 'make help' for more info. diff --git a/macros/latex/contrib/phfthm/phfthm.dtx b/macros/latex/contrib/phfthm/phfthm.dtx new file mode 100644 index 0000000000..6e9656689b --- /dev/null +++ b/macros/latex/contrib/phfthm/phfthm.dtx @@ -0,0 +1,2562 @@ +% \iffalse meta-comment +% +% Copyright (C) 2016 by Philippe Faist +% ------------------------------------------------------- +% +% 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> + [2016/08/15 v1.0 phfthm package] +% +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{xcolor} +\usepackage{phfthm} +\usepackage[preset=xpkgdoc]{phfnote} +\usepackage{needspace} +\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=]\pkgoptionscombineitem +% \item[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] For if you like typing 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{problem} Provides the same environments as the |default| +% theorem set, as well as in addition: |idea|, |question| 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. +% \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{}]\pkgoptionscombineitem +% \item[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{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) 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{\phfLoadThmSet} for theorem-like +% environments}\hspace{0pt}\marg{options to \phfverb{\phfLoadThmSet} 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{\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[francais,...]{babel} +% ... +% \addto\captionsfrancais{% +% \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\problemname{Probl\`eme}% +% } +% ... \selectlanguage{francais} ... +% \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: +% \begin{verbatim} +% \def\proofofnamefrancais#1{\proofname{} (#1)} +% \addto\captionsfrancais{\let\proofofname\proofofnamefrancais} +% ... +% \selectlanguage{francais} ... +% \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 +% \setcounter{equation}{41} +% \begin{equation} +% \oint_S\vec u\cdot d\vec S = \int_V(\vec\nabla\cdot\vec u)\,dV\ . +% \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 +% +% \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. +% +% +% \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}{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@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 counter (if \cmdoptionfmt{counter=}): +% \begin{macrocode} + \newtheorem{phfthm@#2}{#3}% + \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\def\noexpand\phfthm@val@displayargs{[{% + \expandafter\noexpand\csname phfthm@prfenv@#2@val@proofofname\endcsname + {\noexpand\phfthm@val@prooftitle}% + }]}% + } +% \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% +} +\def\phfthm@proof@parselabel@maybelabel{% + \@ifnextchar*\phfthm@proof@parselabel@label\phfthm@proof@parselabel@title% +} +\def\phfthm@proof@parselabel@label*#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{\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. If it is not available, 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: only \phfverb{margin} for now} +% +% These styles simply use the same mechanism as the default style, but plug in +% different sub-callbacks. +% +% \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\marginpar{\proofrefsize{\proofonname{##1}{##2}}}% + }% +} +% \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\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{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@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{proofref} option. The proof-ref is off initially by +% default. +% \begin{macrocode} +\newif\ifKV@phfthmpkg@proofref +\KV@phfthmpkg@proofreffalse +\def\cmdKV@phfthmpkg@proofref@style{} +% \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@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} +\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{sepcounters} option. +% \begin{macrocode} +\ifKV@phfthmpkg@sepcounters + \def\phfthm@val@mkthmopt@counteropts{} +\else + \def\phfthm@val@mkthmopt@counteropts{counter=phfthmcounter} +\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 diff --git a/macros/latex/contrib/phfthm/phfthm.ins b/macros/latex/contrib/phfthm/phfthm.ins new file mode 100644 index 0000000000..133090b213 --- /dev/null +++ b/macros/latex/contrib/phfthm/phfthm.ins @@ -0,0 +1,55 @@ +%% +%% Copyright (C) 2016 by Philippe Faist +%% +%% 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. +%% + +\input docstrip.tex +\keepsilent + +\usedir{tex/latex/phfqitltx} + +\preamble + +This is a generated file. + +Copyright (C) 2016 by Philippe Faist + +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. + +\endpreamble + +\generate{\file{phfthm.sty}{\from{phfthm.dtx}{package}}} + +\obeyspaces +\Msg{*************************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the following *} +\Msg{* file into a directory searched by TeX: *} +\Msg{* *} +\Msg{* phfthm.sty *} +\Msg{* *} +\Msg{* To produce the documentation run the .dtx file through *} +\Msg{* (PdF-)LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{*************************************************************} + +\endbatchfile diff --git a/macros/latex/contrib/phfthm/phfthm.pdf b/macros/latex/contrib/phfthm/phfthm.pdf new file mode 100644 index 0000000000..ce5c5ecce3 Binary files /dev/null and b/macros/latex/contrib/phfthm/phfthm.pdf differ diff --git a/macros/latex/contrib/phfthm/pkg.mk b/macros/latex/contrib/phfthm/pkg.mk new file mode 100644 index 0000000000..3cc121ce5e --- /dev/null +++ b/macros/latex/contrib/phfthm/pkg.mk @@ -0,0 +1,167 @@ + +# +# Common useful definitions +# +LATEX = latex + +PDFLATEX = TEXINPUTS="$$TEXINPUTS:../phfnote" pdflatex +PDFLATEXOPTS = -interaction=batchmode +PDFLATEXOPTSLAST = -interaction=batchmode --synctex=1 + +MAKEINDEX = makeindex + + +# +# Set default PREFIX. This can be overridden with 'make install PREFIX=/installation/directory' +# +DEFAULT_PREFIX := $(shell kpsewhich -var-value TEXMFHOME) +PREFIX ?= $(DEFAULT_PREFIX) + + +# +# package should be set in variable PKG +# +PKGREADME = README.md + +# +# packages may specify additional files in the distribution with this variable +# (by default empty) +# +DIST_ADDITIONAL_FILES ?= + + +PKGDTX = $(PKG).dtx +PKGINS = $(PKG).ins +PKGSTY = $(PKG).sty +PKGPDF = $(PKG).pdf +PKGTDSZIP = $(PKG).tds.zip +PKGZIP = $(PKG).zip + + + +.PHONY: help sty pdf install install_sty install_doc tdszip dist clean cleanall cleansty cleanaux cleanpdf cleantdszip cleandist + + +help: + @echo "Targets for $(PKG):" + @echo "make sty -- generate LaTeX package file $(PKG).sty" + @echo "make pdf -- generate pdf documentation" + @echo "make install -- install style and documentation files to TEXMF tree" + @echo "make install PREFIX=[specify texmf directory]" + @echo "make $(PKG).tds.zip -- create TDS.ZIP to include in CTAN upload" + @echo "make dist -- create distribution ZIP, ready for upload to CTAN" + @echo "make clean -- remove LaTeX auxiliary files" + @echo "make cleansty -- remove generated style file" + @echo "make cleanpdf -- remove generated pdf documentation" + @echo "make cleanall -- remove all generated files, incl. distribution zip" + + +clean: cleanaux + +cleanall: cleansty cleanaux cleanpdf cleantdszip cleandist + +# ------------------------------------------------ +# make sty +# ------------------------------------------------ + +sty: $(PKGSTY) + +$(PKGSTY): $(PKGINS) $(PKGDTX) + $(LATEX) $< + +cleansty: + @rm -f $(PKGSTY) + +# ------------------------------------------------ +# make pdf +# ------------------------------------------------ + +pdf: $(PKG).pdf + +# +# fake index & glossary so they get a TOC entry from the beginning, and so the page +# numbers in the index are correct. +# +$(PKG).aux $(PKG).idx $(PKG).glo: $(PKGDTX) $(PKGSTY) + DTX=$< ; echo '\\begin{theindex}\\item index here \\end{theindex}' >$${DTX%.dtx}.ind + DTX=$< ; echo '\\begin{theglossary}\\item changes here\\end{theglossary}' >$${DTX%.dtx}.gls + $(PDFLATEX) $(PDFLATEXOPTS) $< + $(PDFLATEX) $(PDFLATEXOPTS) $< + $(PDFLATEX) $(PDFLATEXOPTS) $< + +$(PKG).ind: $(PKG).idx + $(MAKEINDEX) -s gind.ist -o $@ $< + +$(PKG).gls: $(PKG).glo + $(MAKEINDEX) -s gglo.ist -o $@ $< + +# final steps of making the PKG.pdf doc file. At the end, touch the ind and gls files so +# that they don't look out-of-date (because the idx and glo files were overwritten again) +$(PKGPDF): $(PKGDTX) $(PKG).aux $(PKG).ind $(PKG).gls + $(PDFLATEX) $(PDFLATEXOPTS) $< + $(PDFLATEX) $(PDFLATEXOPTS) $< + $(PDFLATEX) $(PDFLATEXOPTSLAST) $< + touch $(PKG).ind $(PKG).gls $(PKG).pdf + + +cleanaux: + @rm -f *.aux *.log *.toc *.glo *.gls *.ind *.idx *.ilg *.out *.bbl *.blg *.synctex.gz *.hd + +cleanpdf: + @rm -f $(PKGPDF) + +# ------------------------------------------------ +# 'make install' partial installation targets +# ------------------------------------------------ + +# +# The install target itself is defined per-package, in case packages want to install more +# files (such as bibtex styles) +# + +install_sty: $(PKGSTY) + mkdir -p $(DESTDIR)$(PREFIX)/tex/latex/$(PKG) + cp $(PKGSTY) $(DESTDIR)$(PREFIX)/tex/latex/$(PKG) + +install_doc: $(PKGPDF) + mkdir -p $(DESTDIR)$(PREFIX)/doc/latex/$(PKG) + cp $(PKGPDF) $(PKGREADME) $(DESTDIR)$(PREFIX)/doc/latex/$(PKG) + + + +# ------------------------------------------------ +# make tdszip +# ------------------------------------------------ + +TDSTMPDIR = $(CURDIR)/_install_tds_zip.make.tmp + +tdszip: $(PKGTDSZIP) + +$(PKGTDSZIP): $(PKGSTY) $(PKGPDF) + mkdir $(TDSTMPDIR) + $(MAKE) install PREFIX=$(TDSTMPDIR) + cd $(TDSTMPDIR) && zip -r $(CURDIR)/$(PKGTDSZIP) * + rm -rf $(TDSTMPDIR) + +cleantdszip: + @rm -f $(PKGTDSZIP) + + +# ------------------------------------------------ +# make dist +# ------------------------------------------------ + +DISTTMPDIR = $(CURDIR)/_install_dist_zip.make.tmp + +dist: $(PKGZIP) + +$(PKGZIP): $(PKGTDSZIP) + rm -rf $(DISTTMPDIR) + mkdir -p $(DISTTMPDIR)/$(PKG) + cp $(PKGTDSZIP) $(DISTTMPDIR) + cp $(PKGDTX) $(PKGINS) $(PKGPDF) $(PKGREADME) Makefile pkg.mk $(DIST_ADDITIONAL_FILES) $(DISTTMPDIR)/$(PKG) + cd $(DISTTMPDIR) && zip -r $(CURDIR)/$(PKGZIP) $(PKGTDSZIP) $(PKG) + rm -rf $(DISTTMPDIR) + +cleandist: + @rm -f $(PKGZIP) -- cgit v1.2.3