% \iffalse meta-comment % % Copyright (C) 2016-2026 by Pierre Senellart % % This work 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. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Pierre Senellart % and a version control system for this work % is available at http://github.com/PierreSenellart/apxproof % % This work consists of the files apxproof.dtx, apxproof.ins, % apxproof-synctex and apxproof.sty.ltxml, and the derived file % apxproof.sty. % % \fi % % \iffalse %\NeedsTeXFormat{LaTeX2e}[2005/12/01] %\ProvidesPackage{apxproof} % [2026/08/25 v1.5.0 Automatic proofs in appendix] % %<*driver> \documentclass{ltxdoc} \usepackage{apxproof} \usepackage{hypdoc} \usepackage{textcomp} \usepackage[TS1,T1]{fontenc} \usepackage{lmodern} \usepackage{microtype} \newtheorem{example}{Example} \newtheoremrep{foobar}{Foobar} \newtheoremrep*{foobarstar}{Foobarstar} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{apxproof.dtx} \end{document} % % \fi % % \CheckSum{2586} % % \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.4}{2017/03/02}{Show options commented on in margin and index} %\iffalse % Taken from xkeyval.dtx %\fi %\makeatletter %\def\DescribeOption#1{\leavevmode\@bsphack\marginpar % {\raggedleft\PrintDescribeOption{#1}}\SpecialOptionIndex % {#1}\@esphack\ignorespaces} %\def\PrintDescribeOption#1{\strut\emph{option}\\\MacroFont #1\ } %\def\SpecialOptionIndex#1{\@bsphack % \index{#1\actualchar{\protect\ttfamily#1} % (option)\encapchar usage}\index % {options:\levelchar#1\actualchar{\protect\ttfamily#1}\encapchar % usage}\@esphack} %\def\DescribeOptions#1{\leavevmode\@bsphack % \marginpar{\raggedleft\strut\emph{options}% % \@for\@tempa:=#1\do{% % \\\strut\MacroFont\@tempa\SpecialOptionIndex\@tempa % }}\@esphack\ignorespaces} %\makeatother % % \changes{v1.0.0}{2016/10/31}{Initial released version} % \changes{v1.0.1}{2016/11/07}{Prevent empty bibliography environment; % fix typos} % % \GetFileInfo{apxproof.sty} % % \makeatletter\c@IndexColumns=2\makeatother % \DoNotIndex{ % \newcommand,\newenvironment,\end,\begin,\edef,\if,\else,\fi,\def, % \begingroup,\endgroup,\csname,\let,\noexpand,\protect,\expandafter, % \ifthenelse,\equal,\endcsname,\@empty,\@ifnotempty,\immediate, % \addtocounter,\newcounter,\newtoggle,\global,\ifdefined,\iftoggle, % \ifx,\jobname,\makeatletter,\makeatother,\newwrite,\NewEnviron, % \patchcmd,\relax,\renewcommand,\renewenvironment,\RequirePackage, % \roman,\space,\undefined,\unexpanded % } % % \title{The \textsf{apxproof} package} % % \author{Pierre Senellart \\ \texttt{pierre@senellart.com} \\ % \url{http://github.com/PierreSenellart/apxproof}} % \date{\filedate \quad \fileversion} % % \maketitle % % \begin{abstract} % This package makes it easier to write articles where proofs and other material % are deferred to the appendix. The appendix material is written in the \LaTeX{} % code along with the main text which it naturally complements, and it is % automatically deferred. The package can automatically send proofs to the % appendix, can repeat in the appendix the theorem environments stated in the % main text, can section the appendix automatically based on the sectioning of % the main text, and supports a separate bibliography for the appendix material. % \end{abstract} % % \section{Usage} % The \textsf{apxproof} package is intended to simplify the writing of articles where some of % the content needs to be deferred to an appendix. This is in particular % useful for the submission of scientific articles to conferences or % journals that limit the number of pages in the main text but allow an % extra appendix, where proofs of theorems and other material can be added. % % \subsection{Basics} % To use \textsf{apxproof}, first load it in the header of your document: % \begin{quote}|\usepackage{apxproof}|\end{quote} % On its own, this does not do anything and should not change the % appearance of your document. To add an appendix with some material from % your document, use the |toappendix| environment: % \begin{quote} % |\begin{toappendix}|\DescribeEnv{toappendix}\\ % \hspace*{1em}\dots\\ % |\end{toappendix}| % \end{quote} % The content will appear at the end of your document, in an % automatically generated section that refers to the current section in the main % text. % \begin{example} % Throughout this documentation, all examples produce content % deferred to the appendix, at the very end of this document. % \begin{verbatim} % \begin{toappendix} % This content is in the appendix. % \end{toappendix} % \end{verbatim} % \begin{toappendix} % This content is in the appendix. % \end{toappendix} % \end{example} % \changes{v1.0.3}{2017/01/10}{Note on entire sections in appendix} % When the content to put in appendix is an entire section, make sure % that \verb|\section| is the very first command that appears within the % \verb|toappendix| environment. It will disable the automatic production % of a section heading. % \subsection{Repeated Theorems and Proofs} % In some scientific papers that include proofs, it is common to defer % proofs to the appendix. This can easily be achieved using the % |appendixproof| environment: % \begin{quote} % |\begin{appendixproof}|\DescribeEnv{appendixproof}\\ % \hspace*{1em}\dots\\ % |\end{appendixproof}| % \end{quote} % This behaves like the |toappendix| environment, except that % a proof environment is generated. % \begin{example}We now send a proof to the appendix: % \begin{verbatim} % \begin{appendixproof} % This proof is in the appendix. % \end{appendixproof} % \end{verbatim} % \begin{appendixproof} % This proof is in the appendix. % \end{appendixproof} % \end{example} % % When deferring proofs to the appendix, an annoying problem is that the % statement of the theorem remains in the main text; it is hard to read a % proof that is far away from the statement it proves. \textsf{apxproof} % offers two ways to address this. With % |\newtheoremrep|\DescribeMacro{\newtheoremrep}, the statement % of the theorem is \emph{repeated} in the appendix, immediately above % the deferred proof. With the starred variant % |\newtheoremrep*|\DescribeMacro{\newtheoremrep*}, the % theorem is \emph{not} repeated, but the proof is still automatically % deferred to the appendix; this is convenient when the proofs are short % enough or close enough to the main text that a restatement would be % redundant, especially when combined with the % |\appendixproofname|\DescribeMacro{\appendixproofname}{} hook (see % Section~\ref{sec:customization}) to title proofs with the type and % number of the theorem they refer to (e.g., ``Proof of Theorem~1''). In % summary, three behaviors are available for a theorem environment: % \begin{description} % \item[\textbackslash|newtheorem|] (\LaTeX's standard command): % the theorem appears in the main text only; the |proof| environment is % left unchanged by \textsf{apxproof}. % \item[\textbackslash|newtheoremrep|]: the theorem appears in the main % text \emph{and} is restated in the appendix above its proof; the % |proof| that follows in the source is automatically deferred to the % appendix. % \item[\textbackslash|newtheoremrep*|]: the theorem appears in the % main text only; the |proof| that follows is automatically deferred to % the appendix, without restating the theorem there. % \end{description} % In all cases, theorems can share counters and a single document can % mix the three behaviors freely. % % To use the repeated-theorem feature, you can define a new % \emph{repeated theorem} environment using the |\newtheoremrep| command: % \changes{v1.0.5}{2017/05/31}{Ability to specify a sectioning counter in newtheoremrep} % \begin{quote} % |\newtheoremrep|\marg{name}\oarg{counter}\marg{title}\oarg{countersec}\DescribeMacro{\newtheoremrep} % \end{quote} % or, equivalently, its starred form to obtain a \emph{proof-deferred} % (but not repeated) theorem: % \begin{quote} % |\newtheoremrep*|\marg{name}\oarg{counter}\marg{title}\oarg{countersec}\DescribeMacro{\newtheoremrep*} % \end{quote} % Usage of either form is exactly the same as that of AMS \LaTeX{}'s % |\newtheorem| macro: % \begin{itemize} % \item \meta{name} (e.g., |theorem|) is the name of an environment that is created for this kind of % theorem; % \item \meta{counter} (e.g., |definition|) is an optional counter describing % from which kind of environment the numbering of these environments should be % inherited; % \item \meta{title} % (e.g., |Theorem|) is % the title that will be used to display this theorem environment; % \item \meta{countersec} (e.g., |section|) is an optional counter of a % sectioning command indicating that counters for this theorem should % be prefixed by this counter (and reset at each occurrence of the % sectioning command). % \end{itemize} % \meta{counter} and \meta{countersec} should not be used together. % What % differs from |\newtheorem| is that, when the following is written: % \begin{quote} % |\newtheoremrep{foobar}{Foobar}| % \end{quote} % then \emph{two} environments are defined: the \verb|foobar| % environment, which behaves as if |\newtheorem| had been used, and the % |foobarrep| environment, which results in the statement of this % environment being repeated in the appendix. % The starred form |\newtheoremrep*{foobarstar}{Foobarstar}| similarly % defines two environments |foobarstar| and |foobarstarrep|, except that % |\begin{foobarstarrep}| does not produce any restatement of the % theorem in the appendix; only the following |proof| is deferred. % % One interesting feature of \textsf{apxproof} is that in most % situations, there is no need to use the |appendixproof| environment. % Indeed, the |proof| \DescribeEnv{proof} environment is redefined by \textsf{apxproof} to % automatically put the proof either in the main text (if it follows a % regular theorem) or in the appendix (if it follows a repeated % theorem). % \begin{example} % Assume we have first defined a repeated theorem environment |foobar| as % above. % We can now use this theorem environment, first for a regular theorem in % the main text, then for a theorem repeated in the main text and in the % appendix: % \begin{quote} % \begin{verbatim} % \begin{foobar} % This foobar is a regular one, in the main text. % \end{foobar} % \begin{proof} % This is the proof of the regular foobar. % \end{proof} % \end{verbatim} % \end{quote} % We obtain: % \begin{foobar} % This foobar is a regular one, in the main text. % \end{foobar} % \begin{proof} % This is the proof of the regular foobar. % \end{proof} % Now, if we use a repeated theorem: % \begin{quote} % \begin{verbatim} % \begin{foobarrep} % This foobar is repeated in the appendix. % \end{foobarrep} % \begin{proof} % This is the proof of the repeated foobar. % \end{proof} % \end{verbatim} % \end{quote} % We now obtain: % \begin{foobarrep} % This foobar is repeated in the appendix. % \end{foobarrep} % \begin{proof} % This is the proof of the repeated foobar. % \end{proof} % Note that, since |hyperref| is loaded, there are hyperlinks % created between the statements of the theorems in the main text and in % the appendix. % \end{example} % \begin{example} % In contrast, the starred form of |\newtheoremrep| produces a theorem % whose proof is deferred to the appendix \emph{without} restating the % theorem there. Assuming the declaration % |\newtheoremrep*{foobarstar}{Foobarstar}| at the top of the document, % writing: % \begin{quote} % \begin{verbatim} % \begin{foobarstarrep} % This foobar will not be repeated in the appendix, % but the proof below will be deferred there. % \end{foobarstarrep} % \begin{proof} % This is the proof of the (non-repeated) foobar. % \end{proof} % \end{verbatim} % \end{quote} % yields: % \begin{foobarstarrep} % This foobar will not be repeated in the appendix, % but the proof below will be deferred there. % \end{foobarstarrep} % \begin{proof} % This is the proof of the (non-repeated) foobar. % \end{proof} % In this mode, the title of the deferred proof in the appendix is % controlled by the |\appendixproofname| hook documented in % Section~\ref{sec:customization}; by default, this hook is empty, so % proofs are titled simply ``Proof.'' as usual. The forward hyperlink % from the theorem number in the main text (when \textsf{hyperref} is % loaded) points to the location of the proof in the appendix. % \end{example} % % When the proof is deferred to the appendix, it is common practice to % add a proof sketch in the main text. \textsf{apxproof} defines a simple % |proofsketch| environment for this purpose: % \changes{v1.0.5}{2017/05/31}{Fix compilation of proofsketch environment in inline mode} % \begin{quote} % |\begin{proofsketch}|\DescribeEnv{proofsketch}\\ % \hspace*{1em}\dots\\ % |\end{proofsketch}| % \end{quote} % The proof sketch is typeset similarly to a proof, but is always in the % main text. Similarly, an |inlineproof| \DescribeEnv{inlineproof} % environment is provided so as to % be able to have both a proof in the appendix (using the regular |proof| % environment, or alternatively the |appendixproof| environment) and a % different proof in the main text (using the |inlineproof| environment). % \begin{example} Here are simple examples of proof sketches and inline % proofs: % \begin{verbatim} % \begin{proofsketch} % This is a proof sketch. % \end{proofsketch} % \end{verbatim} % \begin{proofsketch} % This is a proof sketch. % \end{proofsketch} % \begin{verbatim} % \begin{inlineproof} % This is an inline proof. % \end{inlineproof} % \end{verbatim} % \begin{inlineproof} % This is an inline proof. % \end{inlineproof} % \end{example} % % \subsection{Bibliography} % By default, \textsf{apxproof} automatically adds a bibliography in the appendix % with only the references cited in the appendix material. This allows for a % clean separation of references used solely in the main text, and those % used in the appendix. % \begin{example} % Assume we have citations both in the main text and in the appendix. % \begin{verbatim} % This is a citation in the main text~\cite{lamport86}. % \begin{toappendix} % This is a citation in the appendix~\cite{proofsAreHard}. % \end{toappendix} % \end{verbatim} % This is a citation in the main text~\cite{lamport86}. % \begin{toappendix} % This is a citation in the appendix~\cite{proofsAreHard}. % \end{toappendix} % \end{example} % The bibliography in the appendix can use % a different style and heading than the bibliography in the main text (and, by % default, it does). See % Section~\ref{sec:customization} for how to configure the appearance of % that bibliography. % % \DescribeOption{bibliography} % In order to use a single appendix for the main text and the % bibliography, one can specify the % value |common| to the |bibliography| option when loading the package. % % \DescribeOption{bibengine} % By default, \textsf{apxproof} relies on the \textsf{bibunits} package % to typeset a separate bibliography for the appendix material; this is % the |bibengine=bibtex| mode (the default), suitable for documents % that use \textsf{bibtex} (with or without \textsf{natbib}) for % citations and references. Documents using \textsf{biblatex} can % instead set |bibengine=biblatex|, in which case \textsf{apxproof} % wraps the appendix material in a \textsf{biblatex} |refsection| % environment and emits the appendix bibliography with % |\printbibliography|. In this mode the user is responsible for % loading \textsf{biblatex} and declaring bibliography resources with % |\addbibresource| in the preamble; resources are shared between the % main document and the appendix |refsection|, but citations and the % printed bibliography are scoped independently. The |bibengine| option % only has an effect when |bibliography=separate|. % (By default this option is set to |separate|.) % \subsection{Mode} % \DescribeOption{appendix} % An optional \meta{mode} can be specified when loading the package: % \begin{quote}|\usepackage[appendix=|\meta{mode}|]{apxproof}|\end{quote} % \meta{mode} can take one of the following four values: % \begin{description} % \item[|append|] This is the default. % Appendix material gathered by \textsf{apxproof} is appended to % the main text. % \item[|inline|] In this mode, \textsf{apxproof} simply inlines the % content along with the main text. % \item[|strip|] This mode functions similarly to |append| except that % the appendix is not appended at the end of the document. All appendix % material is therefore removed. % \item[|chapterend|] In this mode, appendix material for each chapter % is gathered separately and emitted at the end of that chapter % (i.e., just before the next |\chapter|, |\part|, |\frontmatter|, % |\mainmatter|, or |\backmatter| command, or at the end of the % document), using the |subappendices| environment from the % \textsf{appendix} package. Only |bibliography=common| is supported % in this mode. See Section~\ref{sec:customization} for the % |\chapterappendixprelim| and |\flushchapterappendix| customization % macros. % \end{description} % % \subsection{Customization} % \label{sec:customization} % \textsf{apxproof} provides a few macros that can be redefined (using % |\renewcommand|) to customize the appearance of the appendix: % \begin{description} % \item[\textbackslash|mainbodyrepeatedtheorem|]\DescribeMacro{\mainbodyrepeatedtheorem} % is a macro that is executed at the beginning of the body of every % repeated theorem. This can be used to notify the reader that the % theorem is repeated in appendix in some way, e.g., with a margin note. % \item[\textbackslash|appendixsectionformat|\marg{number}\marg{title}]\DescribeMacro{\appendixsectionformat} is a macro % that indicates how to format the section titles in the Appendix, given % the number and title of the section in the main text. By % default, they appear as ``Proofs for Section~\meta{number} % (\meta{title})''. % \item[\textbackslash|appendixproofname|\marg{type}\marg{ref}]\DescribeMacro{\appendixproofname} % is a macro that determines the title of a proof deferred to the % appendix when it follows a |\newtheoremrep| or |\newtheoremrep*| % environment. By default, this macro is empty, which means proofs are % titled ``Proof.'' as usual. When redefined to a non-empty value, the % expansion is used as the title of the appendix proof; \meta{type} is % the title of the theorem environment (e.g., |Theorem|) and \meta{ref} % is a reference to the theorem statement in the main text. To title % all such proofs ``Proof of \meta{type}~\meta{number}'', one would % typically write: % \begin{quote} % \begin{verbatim} % \renewcommand{\appendixproofname}[2]{Proof of #1~#2} % \end{verbatim} % \end{quote} % This hook applies whether the theorem is restated in the appendix % (|\newtheoremrep|) or not (|\newtheoremrep*|). It has no effect on % manually written |appendixproof| environments or on proofs given an % explicit optional title. % \item[\textbackslash|appendixrefname|]\DescribeMacro{\appendixrefname} contains the heading that is displayed before % the bibliography. By default, this is ``References for the % Appendix''. (Note that this command is also defined and used by the % |memoir| document class.) % \item[\textbackslash|appendixbibliographystyle|]\DescribeMacro{\appendixbibliographystyle} contains the |.bst| bibliography % style that is used in the bibliography in appendix. By default, this is % |alpha|. % \item[\textbackslash|appendixbibliographyprelim|]\DescribeMacro{\appendixbibliographyprelim} contains arbitrary code that is executed % just before the production of the bibliography in appendix, which can % be used to configure the way it is displayed. % \item[\textbackslash|appendixprelim|]\DescribeMacro{\appendixprelim} contains arbitrary code that is executed % just before the production of the appendix, which can % be used to configure the way it is displayed. By default, this command % contains |\clearpage\onecolumn| (the appendix is typeset on a new page % in single-column mode) but redefining this option allows changing this % behavior. This macro has no effect in |chapterend| mode; use % |\chapterappendixprelim| instead. % \item[\textbackslash|chapterappendixprelim|]\DescribeMacro{\chapterappendixprelim} % (|chapterend| mode only) contains arbitrary code that is executed % just before each chapter's appendix block. By default, this command % contains |\clearpage| (each chapter appendix starts on a new page). % This macro has no effect in |append| or |strip| mode; use % |\appendixprelim| instead. % \item[\textbackslash|flushchapterappendix|]\DescribeMacro{\flushchapterappendix} % (|chapterend| mode only) manually emits the current chapter's % accumulated appendix material at the point of invocation, and starts % a fresh per-chapter buffer. The package automatically inserts an % equivalent flush before each |\chapter|, |\part|, |\frontmatter|, % |\mainmatter|, |\backmatter|, and at the end of the document, so % this macro is only useful in unusual document structures where an % appendix needs to be emitted at a location that is not a standard % structural boundary. % \end{description} % \DescribeOption{repeqn} % Another customization capability concerns \emph{numbered equations} that are present % within repeated theorems. An optional |repeqn| option can be specified % when loading the package, which controls whether % equation numbers should be as in the main text (by setting this option % to |same|, the default) or independently % numbered (by setting this option to |independent|). In the latter case, % whenever a referenceable counter is set with |\label{|\meta{counter}|}|, % |\ref{|\meta{counter}|}| references the counter in the main text, while % |\ref{|\meta{counter}|-apx}| references the counter in the appendix % (except in |inline| mode, where both have the same effect). % % Enhanced cross-referencing packages are supported: the optional argument % that \textsf{cleveref} adds to |\label| (as in % |\label[equation]{|\meta{counter}|}|) may be used within repeated material, % and so may the |\zlabel| command of \textsf{zref-clever}, both giving rise % to the same |-apx| variants as |\label| does. Note that \textsf{cleveref} % loses that optional argument inside \textsf{amsmath} display environments % (|equation|, |align|, etc.), where the label ends up unreferenceable; this % happens with or without \textsf{apxproof}, and affects neither plain % |\label| nor \textsf{zref-clever}. % % \DescribeOption{forwardlinking} % Another customization option concerns hyperlinking. % Usually, when \textsf{hyperref} is loaded, |foobarrep| % environments in the main text have their number link to their repetition in the % appendix. To suppress this behavior and have |foobarrep| environments % treated as if \textsf{hyperref} were not loaded, one can specify the % value |no| to the |forwardlinking| option when loading the package. (By % default this option is set to |yes|.) % % \subsection{Sync\TeX{} Support} % \label{sec:synctex} % \changes{v1.5.0}{2026/08/19}{\texttt{synctex} option, \texttt{auto} by default} % \DescribeOption{synctex} % Sync\TeX{} lets editors and PDF viewers jump between a position in the % PDF and the source line that produced it. \textsf{apxproof} supports it % in the appendix as well as in the main text, and nothing has to be done % for that: rather than copying appendix material and repeated theorems to % an auxiliary file, which would attribute them to that file, the package % typesets them from the source itself. % % The |synctex| option says when it does so. With |auto| (the default), % exactly when Sync\TeX{} output was requested (i.e., when the engine was % run with |-synctex=1| or a similar option, which is what editors and % \textsf{latexmk} do); with |yes|, always; with |no|, never, and % Sync\TeX{} is then not supported. The typeset output is the same in all % cases. Should the re-reading cause trouble in a document, |synctex=no| % restores the previous behavior. % % Jumping from the PDF to the source (inverse search) works with every % engine. Jumping from the source to the PDF (forward search) finds % appendix material with Lua\TeX{}; with pdf\TeX{} and Xe\TeX{}, it does so % only if the |apxproof-synctex| script distributed with the package (it % requires Python~3) is run after each compilation: % \begin{quote}|apxproof-synctex |\meta{jobname}\end{quote} % With \textsf{latexmk}, adding % \begin{quote}|$success_cmd = 'apxproof-synctex %R';|\end{quote} % to a |latexmkrc| file does this automatically. % % Section~\ref{sec:issues} lists what re-reading the source asks of a % document, and Section~\ref{sec:synctex-impl} explains how it is done. % % \subsection{Advanced Features} % We now describe a few advanced macros and environments, the usage of % which is limited to special cases: % \begin{description} % \item[|nestedproof|]\DescribeEnv{nestedproof} is an environment that % can be used within a |proof| environment deferred in the appendix; this % is required because, for technical reasons, no |proof| environment can % be nested within a deferred |proof| environment. % \item[\textbackslash|noproofinappendix|]\DescribeMacro{\noproofinappendix} % can be used inside repeated theorems that are not followed by a % |proof| or |appendixproof| environment; the point is to ensure that a further % |proof| environment cannot be mistakenly understood as a proof of the repeated % theorem. It should not be needed in most situations as % \textsf{apxproof} tries figuring out when a proof follows a repeated % theorem automatically, but may occasionally be needed in complex % scenarios. % \item[\textbackslash|nosectionappendix|]\DescribeMacro{\nosectionappendix} % is to be used inside a section that \emph{does} contain appendix material, but % for which a section in the appendix should not be created. This should % be rarely needed. When this command is present, appendix material is % appended to the end of the previously created section. % \item[\textbackslash|apxproofhook|]\DescribeMacro{\apxproofhook} % is a one-argument hook, doing nothing by default, that % \textsf{apxproof} runs inside every proof it typesets in the appendix, % and inside an inline proof whose title names its result through a % cross-reference (|\ref|, |\cref|, |\Cref|, |\autoref|, |\vref| or % |\zcref|). Its argument is a label of the result the proof establishes: % the label of the preceding repeated theorem in the first case, the target % of the title's cross-reference in the second. Redefining it is how a % companion package, such as \textsf{proofgraph}, attributes each proof to % the result it proves; documents have no reason to. % \end{description} % \subsection{Grouping Appendix Material Under a Single Section} % \changes{v1.4.0}{2026/05/14}{Documented workarounds for grouping % per-section appendices under a single wrapping section. See \#56.} % \label{sec:appendix-grouping} % By default, \textsf{apxproof} produces one section in the appendix for % each section of the main text that contains appendix material (with % the format controlled by |\appendixsectionformat|). If you would % rather have a single section in the appendix (e.g., titled % ``Proofs'') with the per-section entries appearing as % \emph{subsections} of that single section, two recipes are available. % % The first is fully explicit: disable the automatic per-section % heading with |\nosectionappendix|, and write the desired structure % directly inside |toappendix| environments. % \begin{quote} % \begin{verbatim} % \begin{toappendix} % \section{Proofs} % \end{toappendix} % % \section{First}\label{sec:first} % \nosectionappendix % \begin{toappendix} % \subsection{Proofs of Section~\ref{sec:first}} % \end{toappendix} % % % ... theorems and proofs of section ``First'' ... % % \section{Second}\label{sec:second} % \nosectionappendix % \begin{toappendix} % \subsection{Proofs of Section~\ref{sec:second}} % \end{toappendix} % % % ... theorems and proofs of section ``Second'' ... % \end{verbatim} % \end{quote} % The reader of the source can then see exactly what will be produced % in the appendix, at the cost of some verbosity. % % The second recipe is more concise. The section level used by % \textsf{apxproof} for the auto-generated appendix headings is swapped % from |\section| to |\subsection| for the duration of an explicit % |\begingroup|/|\endgroup| group: % \begin{quote} % \begin{verbatim} % \begin{toappendix} % \section{Proofs} % \begingroup\makeatletter % \let\axp@oldsection\subsection % \makeatother % \end{toappendix} % % \section{First}\label{sec:first} % % ... theorems and proofs of section ``First'' ... % % \section{Second}\label{sec:second} % % ... theorems and proofs of section ``Second'' ... % % \begin{toappendix} % \endgroup % \end{toappendix} % \end{verbatim} % \end{quote} % The wrapping |\section{Proofs}| is written once, and every subsequent % auto-generated appendix section heading is demoted to a |\subsection| % for the scope of the group. The trade-off is that this recipe relies % on an internal macro (|\axp@oldsection|) and on a manually balanced % |\begingroup|/|\endgroup| pair across two separate |toappendix| % environments. % \section{Supported Document Classes} % Because \textsf{apxproof} modifies sectioning commands, bibliographies, % and proofs, it may not work straight away with arbitrary document classes. % It has currently been tested with and is supported for the following % document classes: % \begin{itemize} % \item \LaTeX{} standard document classes (|article.cls|, |book.cls|) % \item \href{https://www.ctan.org/pkg/koma-script}{KOMA-Script} % (|scrartcl.cls|, |scrbook.cls|) % \item \href{https://ctan.org/pkg/memoir}{|memoir.cls|} % \item \href{https://www.ctan.org/pkg/acmart}{ACM journals and % proceedings} (|acmart.cls|) % \item \href{https://www.ctan.org/pkg/ieeetran}{IEEE transactions and % conferences} (|IEEEtran.cls|) % \item \href{https://www.springer.com/computer/lncs/lncs+authors}{ % Springer's Lecture Notes in Computer Science} (|llncs.cls|) % \item \sloppy % \href{https://www.dagstuhl.de/en/publications/lipics}{Schlo\ss{} % Dagstuhl's Leibniz International Proceedings in Informatics} % (|lipics.cls|, |lipics-v2016.cls|, |lipics-v2019.cls|, % |lipics-v2021.cls|) % \end{itemize} % Other classes may work out of the box. Adding support for specific % classes is possible and can be requested from the % author of this package. % \section{HTML Conversion with \textsf{LaTeXML}} % \label{sec:latexml} % \changes{v1.5.0}{2026/08/25}{Document the \textsf{LaTeXML} binding} % \textsf{LaTeXML} (\url{https://math.nist.gov/~BMiller/LaTeXML/}) converts % \LaTeX{} documents to HTML. It cannot read |apxproof.sty| itself, so the % package comes with a binding, |apxproof.sty.ltxml|, which reproduces its % behavior in the conversion: proofs deferred to the appendix, repeated % theorem statements with their original numbering, automatic appendix % sectioning, forward links from theorems to their proofs, and a separate % appendix bibliography. % % The binding is installed with the package, next to |apxproof.sty|. % \textsf{LaTeXML} looks for it there, and in the directory of the document; % should it be kept anywhere else, point \textsf{LaTeXML} at that directory: % \begin{quote}|latexmlc --path=|\meta{dir}| --dest=paper.html paper.tex|\end{quote} % Do \emph{not} pass |--includestyles|: the binding is self-contained, and % that option makes \textsf{LaTeXML} process the dependencies of the real % |apxproof.sty|, which fails. \textsf{LaTeXML}~0.8.8 or later is required. % \section{Known Issues and Limitations} % \label{sec:issues} % We report here some issues we are currently aware of: % \begin{itemize} % \item When using \textsf{hyperref}, the appendix in the bibliography is % not hyperlinked. This is to avoid possible issues with multiply defined % bibliography entries. % \item |appendixproof|, |proof|, |toappendix| environments cannot be nested. This is a limitation of % the \textsf{fancyvrb} package that \textsf{apxproof} relies on. Note % the existence of the |nestedproof| environment for nested proofs. % \item Sync\TeX{} support (Section~\ref{sec:synctex}) works by re-reading % the source when the appendix is typeset, which requires each captured % environment to appear literally in a source file: |\begin{foobarrep}|, % |\begin{proof}|, |\begin{toappendix}| and their |\end| counterparts % cannot come from a macro (nor could they be captured before, except for % repeated theorems). Conversely, wrapping a |foobarrep| environment in a % user-defined environment is supported only with this option. % \item Sync\TeX{} support also requires the source files to be readable, % under the same names, when the appendix is typeset, which is the case in % any normal compilation. The main file is |\jobname.tex|, or, when \TeX{} was % given a path to it, the name recorded in the |.fls| file written by the % |-recorder| option (\textsf{latexmk} and most editors pass it). When the % main file cannot be located, \textsf{apxproof} says so and copies % appendix material to the |.axp| file as with |synctex=no|, which leaves % the document complete but without Sync\TeX{} support for that material; % when a single piece cannot be re-read, an error message explains why and % that piece is missing from the appendix. % \item Sync\TeX{} forward search, from the source to the PDF, reaches % appendix material with Lua\TeX{} only: with pdf\TeX{} and Xe\TeX{}, a line % of a proof or of a |toappendix| environment lands on the nearest line of % the main text unless the |apxproof-synctex| script is run % (Section~\ref{sec:synctex}), the way Sync\TeX{} identifies files making % it impossible to do better without breaking forward search from the main % text. Sync\TeX{} support also has a cost: each piece of appendix material % is reached by reading its source file from the beginning, which a document % with hundreds of proofs in a very long file will notice. % \item By default, when |bibliography=separate|, \textsf{apxproof} % uses the \textsf{bibunits} package to generate a second bibliography. % Packages incompatible with \textsf{bibunits} (notably % \textsf{biblatex}) will therefore not work in that default % configuration. For \textsf{biblatex} users, set |bibengine=biblatex| % (in addition to |bibliography=separate|) to use \textsf{biblatex}'s % own |refsection| machinery instead. The |bibliography=common| mode % remains a third option that works with most bibliography packages. % \end{itemize} % % Issues not listed here should be reported to the author. % % \section{License} % Copyright \textcopyright{} 2016--2026 by Pierre Senellart. % % This work 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 % \url{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. % % \section{Contact} % \begin{itemize} % \item \url{https://github.com/PierreSenellart/apxproof} % \item % Pierre Senellart % \href{mailto:pierre@senellart.com}{} % \end{itemize} % Bug reports and feature requests should % preferably be submitted through the \emph{Issues} feature of GitHub. % % \section{Acknowledgments} % Thanks to Antoine Amarilli for feedback and proofreading. Thanks to K.~D. % Bauer for the implementation of the forward-linking mechanism, and % for various bugfixes. Thanks to Leonid Kostrykin for an initial % implementation of the |forwardlinking| option. % % \StopEventually{ % \PrintChanges % \PrintIndex % } % % \section{Implementation} % We now describe the entire code of the package, in a literate programming % fashion. Throughout the package, we use the |axp@| prefix to identify % local macros and environment names, which are not meant to be used by the final % user. % \subsection{Dependencies} % We first load a few package dependencies: % \begin{itemize} % \item \textsf{environ} to easily define the repeated theorem % environments. % \begin{macrocode} \RequirePackage{environ} % \end{macrocode} % \item \textsf{etoolbox} to define simple toggles. % \begin{macrocode} \RequirePackage{etoolbox} % \end{macrocode} % \item \textsf{fancyvrb} for the bulk of the work of exporting appendix % material in an auxiliary file. % \begin{macrocode} \RequirePackage{fancyvrb} % \end{macrocode} % \item \textsf{ifthen} for easier comparison of character strings. % \begin{macrocode} \RequirePackage{ifthen} % \end{macrocode} % \item \textsf{kvoptions} to manage options passed to the package. % \begin{macrocode} \RequirePackage{kvoptions} % \end{macrocode} % \item \textsf{catchfile} to be able to check the content of files % |\input| within appendix content. % \begin{macrocode} \RequirePackage{catchfile} % \end{macrocode} % \item \textsf{amsthm} for its |\newteorem| macro. % Some document classes (e.g., \textsf{lipics}) % preload \textsf{amsthm}: this is fine, |\RequirePackage{amsthm}| % will simply have no effect. On the other hand, some other document % classes (e.g., \textsf{llncs} or \textsf{sig-alternate}) define a % |proof| environment that conflicts with \textsf{amsthm}, so we have to % undefine this environment before loading \textsf{amsthm}. In that case, % we reestablish the existing proof environments, in case they had been % customized (e.g., \textsf{sig-alternate}) % \changes{v1.0.4}{2017/03/08}{Re-establish custom proof environments} % \begin{macrocode} \@ifpackageloaded{amsthm}{ }{ \let\apx@oldamsthmproof\proof \let\apx@oldamsthmendproof\endproof \let\proof\undefined \let\endproof\undefined } \RequirePackage{amsthm} \ifdefined\apx@oldamsthmproof \let\proof\apx@oldamsthmproof \let\endproof\apx@oldamsthmendproof \fi % \end{macrocode} % \end{itemize} % \subsection{Option Processing} % Many names throughout the package use an arobase (|@|) to avoid name % conflict with user-defined names. To simplify the compilation of the % documentation, we simply make it a regular character in all the rest. % \begin{macrocode} \makeatletter % \end{macrocode} % We setup the processing of options using \textsf{keyval} facilities. % \begin{macrocode} \SetupKeyvalOptions{ family=axp, prefix=axp@ } % \end{macrocode} % We declare the following options: % \begin{itemize} % \item |appendix|, with a default value of |append| (other possible % values: |strip|, |inline|); % \item |bibliography|, with a default value of |separate| (other % possible value: |common|); % \item |repeqn|, with a default value of |same| (other possible value: % |independent|). % \end{itemize} % \begin{macro}{\axp@appendix} % \begin{macrocode} \DeclareStringOption[append]{appendix} % \end{macrocode} % \end{macro} % \begin{macro}{\axp@bibliography} % \changes{v1.0.4}{2017/03/02}{\texttt{bibliography} option} % \begin{macrocode} \DeclareStringOption[separate]{bibliography} % \end{macrocode} % \end{macro} % \begin{macro}{\axp@bibengine} % \changes{v1.4.0}{2026/05/14}{\texttt{bibengine} option to select % the engine used for separate bibliographies: \textsf{bibunits} % (default) or \textsf{biblatex}. See \#29.} % \begin{macrocode} \DeclareStringOption[bibtex]{bibengine} % \end{macrocode} % \end{macro} % \begin{macro}{\axp@repeqn} % \changes{v1.1.0}{2018/07/20}{\texttt{repeqn} option} % \begin{macrocode} \DeclareStringOption[same]{repeqn} % \end{macrocode} % \end{macro} % \begin{macro}{\axp@forwardlinking} % \changes{v1.2.3}{2021/07/12}{\texttt{forwardlinking} option} % \begin{macrocode} \DeclareStringOption[yes]{forwardlinking} % \end{macrocode} % \end{macro} % \begin{macro}{\axp@synctex} % \changes{v1.5.0}{2026/08/19}{\texttt{synctex} option, \texttt{auto} by default} % \begin{macrocode} \DeclareStringOption[auto]{synctex} % \end{macrocode} % \end{macro} % \begin{macrocode} \ProcessLocalKeyvalOptions* % \end{macrocode} % We check that the value of the options are valid, and add a % message to the compilation log. % \begin{macrocode} \ifthenelse{\equal{\axp@appendix}{append}}{ \message{apxproof: Appendix material appended to the document} }{\ifthenelse{\equal{\axp@appendix}{strip}}{ \message{apxproof: Appendix material stripped} }{\ifthenelse{\equal{\axp@appendix}{inline}}{ \message{apxproof: Appendix material inlined within the document} }{\ifthenelse{\equal{\axp@appendix}{chapterend}}{ \message{apxproof: Appendix material appended at the end of each chapter} }{ \errmessage{Error: unsupported option appendix=\axp@appendix\ for package apxproof} }}}} \ifthenelse{\equal{\axp@bibengine}{bibtex}}{ }{\ifthenelse{\equal{\axp@bibengine}{biblatex}}{ }{ \errmessage{Error: unsupported option bibengine=\axp@bibengine\ for package apxproof} }} \ifthenelse{\equal{\axp@bibliography}{separate}}{ % \end{macrocode} % In |bibengine=bibtex| mode (the default), the external % \textsf{bibunits} package is used to add a second bibliography for % the appendix material. In |bibengine=biblatex| mode, no extra % package is loaded here: \textsf{biblatex} is expected to have been % loaded by the user, and its |refsection| environment is used at % appendix typeset time to scope citations. % \changes{v1.2.0}{2019/04/17}{Do not load \textsf{bibunits} if % \texttt{bibliography} is set to \texttt{common}} % \begin{macrocode} \ifthenelse{\equal{\axp@bibengine}{bibtex}}{ \RequirePackage{bibunits} \message{apxproof: Separate bibliography for appendix material (bibunits)} }{ \message{apxproof: Separate bibliography for appendix material (biblatex)} } }{\ifthenelse{\equal{\axp@bibliography}{common}}{ \message{apxproof: Common bibliography for appendix and main text} }{ \errmessage{Error: unsupported option bibliography=\axp@bibliography\ for package apxproof} }} \ifthenelse{\equal{\axp@appendix}{chapterend} \AND\equal{\axp@bibliography}{separate}}{ \PackageError{apxproof}{% bibliography=separate is not supported with appendix=chapterend}{% Use bibliography=common instead.} }{} \ifthenelse{\equal{\axp@repeqn}{same}}{ \message{apxproof: Repeated equations keep the same numbering} }{\ifthenelse{\equal{\axp@repeqn}{independent}}{ \message{apxproof: Repeated equations are independently numbered} }{ \errmessage{Error: unsupported option repeqn=\axp@repeqn\ for package apxproof} }} % \end{macrocode} % \begin{macro}{\axp@forward@suppress} % \begin{macrocode} \newbool{axp@forward@suppress} \ifthenelse{\equal{\axp@forwardlinking}{yes}}{ }{\ifthenelse{\equal{\axp@forwardlinking}{no}}{ \message{apxproof: Disable forward linking} \global\booltrue{axp@forward@suppress}% }{ \errmessage{Error: unsupported option forwardlinking=\axp@repeqn\ for package apxproof} }} % \end{macrocode} % \end{macro} % \begin{macro}{axp@synctex} % The |axp@synctex| Boolean records whether appendix material is to be % re-read from the source files rather than copied to the |.axp| file (see % Section~\ref{sec:synctex-impl}). With |synctex=auto|, this is decided by % the |\synctex| primitive of the engine, which is nonzero exactly when % Sync\TeX{} output was requested (positive for compressed, negative for % uncompressed |.synctex| files); the primitive is only tested if it exists. % \begin{macrocode} \newbool{axp@synctex} \ifthenelse{\equal{\axp@synctex}{no}}{ }{\ifthenelse{\equal{\axp@synctex}{yes}}{ \booltrue{axp@synctex} }{\ifthenelse{\equal{\axp@synctex}{auto}}{ \ifdefined\synctex \ifnum\synctex=\z@\else \booltrue{axp@synctex} \fi \fi }{ \errmessage{Error: unsupported option synctex=\axp@synctex\ for package apxproof} }}} % \end{macrocode} % Whether re-reading is actually possible further depends on the main source % file being locatable, which is settled at the end of % Section~\ref{sec:synctex-impl}; the Boolean may still be cleared there. % \end{macro} % \subsection{Macros Common to All Compilation Modes} % \begin{macro}{\axp@newtheoremrep@definetheorem} % \changes{v1.2.0}{2019/10/01}{Restore predefined theorem counters} % \changes{v1.2.6}{2025/08/04}{Undefine counter printing command to % avoid warning} % Common to all compilation modes, we define % |\axp@newtheoremrep@definetheorem|. % When called with first argument |foobar|, we first undefine the existing % |foobar| environment (and its counter) if it has already been defined (e.g., by the % document class), then invoke |\axp@newtheorem| for the regular version % of the theorem |foobar|, saving and restoring any existing theorem counter unless the % |\newtheoremdep| redefines the base counter. % \begin{macrocode} \def\axp@newtheoremrep@definetheorem#1#2#3#4{% \expandafter\let\csname #1\endcsname\undefined \expandafter\let\csname the#1\endcsname\undefined \ifcsname c@#1\endcsname \expandafter\expandafter\expandafter\let\expandafter\expandafter \csname c@axp@#1\endcsname\csname c@#1\endcsname \expandafter\let\csname c@#1\endcsname\undefined \fi \axp@newtheorem{#1}{#2}{#3}{#4}% \ifcsname c@axp@#1\endcsname \ifx\relax#2\relax \expandafter\expandafter\expandafter\let\expandafter\expandafter \csname c@#1\endcsname\csname c@axp@#1\endcsname \else \fi \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@newtheorem} % \changes{v1.0.6}{2018/05/10}{Introduce intermediary command for theorem % macro} % \begin{macro}{\@axp@newtheorem} % \begin{macro}{\@@axp@newtheorem} % We introduce an intermediate |\axp@newtheorem| command to define a new % theorem, differently depending on whether there is a section counter or % not. This will be useful, in particular to allow changing this % definition depending on the document class. This command uses two % intermediary commands, |\@axp@newtheorem| and |\@@axp@newtheorem|, for % the non-starred and starred versions. % \begin{macrocode} \def\axp@newtheorem{\@ifstar\@@axp@newtheorem\@axp@newtheorem} \def\@axp@newtheorem#1#2#3#4{% \ifx\relax#4\relax \newtheorem{#1}[#2]{#3}% \else \newtheorem{#1}{#3}[#4]% \fi } \def\@@axp@newtheorem#1#2{% \newtheorem*{#1}{#2}% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\newtheoremrep} % \begin{macro}{\axp@newtheoremreptmp} % We define the high-level |\newtheoremrep| to have the same syntax as % \textsf{amsthm}'s |\newtheorem|, plus an optional |*| variant that % defers the proof to the appendix without restating the theorem. % For this purpose, we need a little % trick to deal with the second and fourth optional arguments, which is what % |\@oparg| and |\axp@newtheoremreptmp| are % used for. |\axp@newtheoremrep| is defined differently % depending on the compilation mode. % \changes{v1.4.0}{2026/05/14}{Added starred form of \cs{newtheoremrep} % for proof-deferred theorems that are not restated in the appendix} % \begin{macrocode} \newcommand\newtheoremrep{% \@ifstar{\axp@newtheoremrep@star}{\axp@newtheoremrep@nostar}% } \newcommand\axp@newtheoremrep@star[1]{% \global\csdef{axp@proofof@#1}{}% \@oparg{\axp@newtheoremreptmp{#1}}[]% } \newcommand\axp@newtheoremrep@nostar[1]{% \global\csundef{axp@proofof@#1}% \@oparg{\axp@newtheoremreptmp{#1}}[]% } \def\axp@newtheoremreptmp#1[#2]#3{% \@oparg{\axp@newtheoremrep{#1}[#2]{#3}}[]% } % \end{macrocode} % \end{macro} % \end{macro} % \begin{environment}{proofsketch} % Simple |proofsketch| environment. % \changes{v1.0.3}{2016/12/16}{Ignore spaces after beginning of Proof sketch} % \begin{macrocode} \newenvironment{proofsketch}{\begin{axp@oldproof}[Proof sketch]}{\end{axp@oldproof}} % \end{macrocode} % \end{environment} % \begin{macro}{\mainbodyrepeatedtheorem} % \changes{v1.2.0}{2019/09/21}{Configurable repeated theorem command} % \begin{macro}{\appendixrefname} % \changes{v1.2.1}{2020/10/09}{Fix compatibility with % \texttt{memoir} document class} % \begin{macro}{\appendixbibliographystyle} % \begin{macro}{\appendixbibliographyprelim} % \begin{macro}{\appendixprelim} % \changes{v1.0.4}{2017/03/03}{Configurable appendix style} % \begin{macro}{\appendixsectionformat} % \changes{v1.1.0}{2018/07/17}{Fix missing space in default % \cs{appendixsectionformat}} % \begin{macro}{\appendixproofname} % \changes{v1.4.0}{2026/05/14}{Added \cs{appendixproofname} hook for % customizing the title of a proof deferred to the appendix} % We provide sensible defaults for these user-customizable macros. % Even though they are not all useful in all modes, we define them for % all modes so that a |\renewcommand| works in all cases. % \begin{macrocode} \newcommand{\mainbodyrepeatedtheorem}{} \providecommand{\appendixrefname}{References for the Appendix} \newcommand{\appendixbibliographystyle}{alpha} \newcommand{\appendixbibliographyprelim}{} \newcommand{\appendixprelim}{\clearpage\onecolumn} \newcommand{\appendixsectionformat}[2]{Proofs for Section~#1\ (#2)} \newcommand{\appendixproofname}[2]{} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{environment}{axp@oldproof} % We save the definition of the existing |proof| environment. % \begin{macrocode} \let\axp@oldproof\proof \let\endaxp@oldproof\endproof % \end{macrocode} % \end{environment} % We define a utility macro that will be used to properly set the % |\label| command (and its \textsf{amsmath} counterpart, % |\label@in@display|) for equations within repeated theorems, depending on the % compilation mode. % % Some packages, \textsf{cleveref} in particular, give |\label| (and % |\label@in@display|) an optional argument specifying the type of the % counter being labeled. Our replacements must therefore look for such an % optional argument and pass it on unchanged, or the opening bracket would % be taken as the label name and the rest of the argument typeset as text. % We do \emph{not} pass the optional argument on to the extra |-apx| label % of the repeated material: that label is set within an unnumbered copy of % the theorem, where overriding the counter type would apply to state that % \textsf{cleveref} did not set up, and the type of the counter (for % equations, the only case where the |-apx| label is really of use) is % correctly inferred from the context anyway. % % \textsf{zref-clever}, the maintained successor of \textsf{cleveref}, does % not touch |\label| at all: it sets its own labels through |\zlabel|, and, % with its |labelhook| option (set by default), also through the kernel's % |label| hook, so that a plain |\label| sets a \textsf{zref} label as well. % The latter needs nothing from us, since our replacement of |\label| calls % the original one. A |\zlabel| used directly, however, must be given the % same treatment as |\label|; it has no optional argument. % \begin{macro}{\axp@label} % \begin{macro}{\axp@label@in@display} % \changes{v1.5.0}{2026/08/03}{Support the optional argument that % \textsf{cleveref} adds to \cs{label} (R. Rowe)} % \changes{v1.5.0}{2026/08/03}{Support \cs{zlabel} of \textsf{zref-clever}} % \begin{macrocode} \def\axp@label{\@ifnextchar[\axp@label@opt\axp@label@noopt}%] \def\axp@label@opt[#1]#2{\axp@label@do{[#1]}{#2}} \def\axp@label@noopt#1{\axp@label@do{}{#1}} \def\axp@label@in@display{% \@ifnextchar[\axp@label@in@display@opt\axp@label@in@display@noopt}%] \def\axp@label@in@display@opt[#1]#2{\axp@label@in@display@do{[#1]}{#2}} \def\axp@label@in@display@noopt#1{\axp@label@in@display@do{}{#1}} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\axp@redefinelabels} % \changes{v1.1.0}{2018/07/04}{Fix \cs{label} not being disabled % in \textsf{amsmath} environments, where \cs{label@in@display} is % used instead (K. D. Bauer)} % \changes{v1.2.0}{2019/02/15}{Fix extra spacing erroneously % introduced within the \texttt{\textbackslash axp@redefinelabels} % macro} % \begin{macrocode} \newcommand{\axp@redefinelabels}{% \providecommand\label@in@display{}% \let\axp@oldlabel\label \let\axp@oldlabel@in@display\label@in@display \ifdefined\zlabel\let\axp@oldzlabel\zlabel\fi \ifthenelse{\equal{\axp@appendix}{inline}}{% \def\axp@label@do##1##2{% \axp@oldlabel##1{##2}% \axp@oldlabel{##2-apx}% }% \def\axp@label@in@display@do##1##2{% \axp@oldlabel@in@display##1{##2}% \axp@oldlabel{##2-apx}% }% \def\axp@zlabel##1{\axp@oldzlabel{##1}\axp@oldzlabel{##1-apx}}% }{% \def\axp@label@do##1##2{\axp@oldlabel{##2-apx}}% \def\axp@label@in@display@do##1##2{\axp@oldlabel@in@display{##2-apx}}% \def\axp@zlabel##1{\axp@oldzlabel{##1-apx}}% }% \let\label\axp@label \let\label@in@display\axp@label@in@display \ifdefined\zlabel\let\zlabel\axp@zlabel\fi } % \end{macrocode} % \end{macro} % \subsubsection{Class-Specific Behavior} % Finally, some class-specific behavior common to all compilation modes. % \paragraph{\textsf{llncs} and other Springer document classes} % \changes{v1.0.6}{2018/05/10}{Better support of Springer document % classes} % \begin{macrocode} \ifdefined\spnewtheorem % \end{macrocode} % \begin{macro}{\@axp@newtheorem} % \begin{macro}{\@@axp@newtheorem} % It is necessary to use |\spnewtheorem| instead of |\newtheorem| in % Springer document classes to obtain standard formatting. % \begin{macrocode} \def\@axp@newtheorem#1#2#3#4{% \ifx\relax#4\relax \ifx\relax#2\relax \spnewtheorem{#1}{#3}{\bfseries}{\itshape}% \else \spnewtheorem{#1}[#2]{#3}{\bfseries}{\itshape}% \fi \else \spnewtheorem{#1}{#3}[#4]{\bfseries}{\itshape}% \fi } \def\@@axp@newtheorem#1#2{% \spnewtheorem*{#1}{#2}{\upshape\bfseries}{\itshape}% } % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{proofsketch} % \changes{v1.2.0}{2019/02/15}{Fix proof sketches in inline % compilation mode for Springer document classes} % We redefine the |proofsketch| environment, which is used % differently in the base class. % \begin{macrocode} \renewenvironment{proofsketch}{\begin{axp@oldproof}[sketch]}{\end{axp@oldproof}} % \end{macrocode} % \end{macro} % We have to redefine the macro |\@thmcountersep| for proper sectioned % counters. % \begin{macrocode} \def\@thmcountersep{.} \fi % \end{macrocode} % \paragraph{\textsf{acmart}} % \changes{v1.2.6}{2025/09/29}{Fix compilation issues in recent versions of \textsf{acmart}} % Some versions of \textsf{acmart} define a |\ACM@origsection| macro and % verify that |\section| has the same content. We need to update % |\ACM@origsection| accordingly. % \begin{macrocode} \ifdefined\ACM@origsection \AtBeginDocument{\let\ACM@origsection\section} \fi % \end{macrocode} % \subsection{Sync\TeX{} Support} % \label{sec:synctex-impl} % \changes{v1.5.0}{2026/08/19}{Sync\TeX{} support: appendix material can % be re-read from the source files instead of being copied to the % \texttt{.axp} file} % Sync\TeX{} records, for every box in the output, the file and line % from which the tokens that produced it were read. Two things defeat it % in \textsf{apxproof}: the body of a |foobarrep| environment collected by % \textsf{environ} is typeset from a macro, so all of it is attributed to % the line of the |\end{foobarrep}|; and appendix material copied % verbatim to the |.axp| file is attributed to that file when it is % typeset. There is no way to tell Sync\TeX{} that some tokens ``really'' % come from elsewhere; the only tokens it attributes correctly are those % read directly from a file. When the |synctex| option is enabled, we % therefore do just that: repeated theorems are typeset directly from the % source instead of being collected, and instead of copying appendix % material to the |.axp| file, we write there the name of the source % file, the line where the environment begins, the line where it ends % and its name; when the appendix is typeset, the source file is opened % again with the primitive |\input|, all lines up to the beginning of the % environment are skipped, and the environment is executed anew, with its % begin and end code replaced by what the appendix needs. All of this % happens with the source file open, so Sync\TeX{} attributes every box % to the right file and line. % % We store, at the beginning of each captured environment, where it was % found. The line comes from |\@currenvline|, which |\begin| sets before % reading any optional argument (|\inputlineno| would be off when the % argument or the body starts on a later line). The file comes from the % kernel's |\CurrentFileUsed| and |\CurrentFilePathUsed|, which are empty % for the main file, in which case we use |\axp@region@mainfile|, the name % under which the main file can be read (see |\axp@region@findmain| below); % older kernels lack these macros, and we then have to assume that every % environment is in the main file. % % We also need to know how Sync\TeX{} identifies the file, see % |\axp@region@input| below: with Lua\TeX{}, we record the tag it gave % the file (|\axp@region@tag| is 0 elsewhere). % \begin{macro}{\axp@region@file} % \begin{macro}{\axp@region@line} % \begin{macro}{\axp@region@env} % \begin{macro}{\axp@region@tag} % \begin{macro}{\axp@region@mainfile} % \begin{macro}{\axp@extract@line} % \begin{macro}{\axp@region@record} % \begin{macrocode} \def\axp@region@file{} \def\axp@region@line{} \def\axp@region@env{} \def\axp@region@tag{0} \edef\axp@region@mainfile{\jobname.tex} \def\axp@extract@line#1line #2\@nil#3\@nnil{#2} \def\axp@region@record{% \ifdefined\CurrentFileUsed \ifx\CurrentFileUsed\@empty \let\axp@region@file\axp@region@mainfile \else \ifx\CurrentFilePathUsed\@empty \edef\axp@region@file{\CurrentFileUsed}% \else \edef\axp@region@file{\CurrentFilePathUsed/\CurrentFileUsed}% \fi \fi \else \let\axp@region@file\axp@region@mainfile \fi \edef\axp@region@line{% \expandafter\axp@extract@line\@currenvline\@nil line 0\@nil\@nnil}% \edef\axp@region@env{\@currenvir}% \ifdefined\directlua \edef\axp@region@tag{\directlua{tex.sprint(tex.get_synctex_tag())}}% \else \def\axp@region@tag{0}% \fi } \ifbool{axp@synctex}{ \ifdefined\CurrentFileUsed\else \PackageWarning{apxproof}{% This LaTeX kernel does not provide \string\CurrentFileUsed; the synctex option assumes\MessageBreak that all appendix material is in \jobname.tex} \fi }{} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\axp@region@write} % At the end of the environment, this writes to the |.axp| file the % |\axp@replaybody| command replaying it, with the recorded position, the % current line (that of the |\end|), the two arguments passed by % the caller: the tokens that will replace the begin code of the % environment in the appendix, and those that will replace its end code, % and the Sync\TeX{} tag. % The trailing |\relax| ensures that the end of the line in the |.axp| % file, which is only tokenized once the replay is over, does not % produce a space, as the copied material never ended with one. % \begin{macrocode} \def\axp@region@write#1#2{% \immediate\write\axp@proofsfile{% \noexpand\axp@replaybody{\axp@region@file}{\axp@region@line}% {\the\inputlineno}{\axp@region@env}{#1}{#2}{\axp@region@tag}\relax }% } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@replaybody} % |\axp@replaybody|\marg{file}\marg{start}\marg{end}\marg{env}\marg{begin}\marg{end code}\marg{tag} % is executed in the appendix. It first checks, by reading the file with % |\readline| (which does not affect Sync\TeX{}), that the file exists and % that its \meta{start} line does contain |\begin{|\meta{env}|}| and its % \meta{end} line an |\end{|; if not, an error is raised and nothing is % typeset. Otherwise the file is replayed. The state of the replay is kept % in |\axp@replay@...| macros, distinct from the |\axp@region@...| ones % set by |\axp@region@record|: a |foobarrep| environment nested in a % |toappendix| environment runs its main-text begin code when replayed, % and must not disturb the replay of the enclosing environment. % \begin{macrocode} \newif\ifaxp@region@ok \newif\ifaxp@region@wrapped \def\axp@replaybody#1#2#3#4#5#6#7{% \def\axp@replay@file{#1}% \def\axp@replay@line{#2}% \def\axp@replay@endline{#3}% \def\axp@replay@env{#4}% \def\axp@replay@begin{#5}% \def\axp@replay@end{#6}% \def\axp@replay@tag{#7}% \axp@region@check \ifaxp@region@ok \axp@region@replay \else \axp@region@flushsection \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@region@section} % \begin{macro}{\axp@region@flushsection} % For |toappendix| environments, the appendix section heading is written % to the |.axp| file as |\axp@region@section|, which stores it; it is % typeset by |\axp@region@toappendix| below with the same look-ahead as % |\axp@section|, once the content of the environment is available, or % by |\axp@region@flushsection| without look-ahead if the environment % cannot be replayed. The assignments are global, as the heading is % typeset from within the group of the environment. % \begin{macrocode} \let\axp@region@pendingsection\relax \def\axp@region@section#1{\gdef\axp@region@pendingsection{#1}} \def\axp@region@flushsection{% \ifx\axp@region@pendingsection\relax\else \expandafter\axp@oldsection\expandafter {\axp@region@pendingsection}% \global\let\axp@region@pendingsection\relax \fi } % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\axp@region@check} % \begin{macro}{\axp@region@readto} % \begin{macro}{\axp@region@readone} % Lines are read one at a time into |\axp@line|, with |\endlinechar| % disabled so that no end-of-line character is appended, until the % desired line number is reached; |\axp@region@readcount| counts the lines % read so far. We never read from a stream on which |\ifeof| is true, since % \TeX{} would then read from the terminal. As the environments of a % given file are replayed in the order in which they appear, we keep the % stream open from one replay to the next and only reopen the file when % we need an earlier line or a different file (|\axp@region@openfile| % records the file currently open); each source file is thus read at % most a few times overall. This state is global, as |\axp@replaybody| % may be called within a group. % \begin{macrocode} \newread\axp@readfile \newcount\axp@region@readcount \def\axp@region@openfile{} \def\axp@line{} \def\axp@region@readto#1{% \loop \ifnum\axp@region@readcount<#1\relax \axp@region@readone{#1}% \repeat } \def\axp@region@readone#1{% \ifeof\axp@readfile \def\axp@line{}% \global\axp@region@readcount=#1\relax \else \global\advance\axp@region@readcount\@ne \readline\axp@readfile to\axp@line \fi } \def\axp@region@check{% \axp@region@okfalse \edef\axp@region@saveendlinechar{\the\endlinechar}% \endlinechar\m@ne \ifx\axp@region@openfile\axp@replay@file \ifnum\axp@region@readcount<\axp@replay@line\relax \else \gdef\axp@region@openfile{}% \fi \else \gdef\axp@region@openfile{}% \fi \ifx\axp@region@openfile\@empty \closein\axp@readfile \openin\axp@readfile=\axp@replay@file\relax \global\axp@region@readcount=\z@ \global\let\axp@region@openfile\axp@replay@file \fi \ifeof\axp@readfile \ifnum\axp@region@readcount=\z@ \PackageError{apxproof}{% Cannot open `\axp@replay@file' to re-read the\MessageBreak \axp@replay@env\space environment starting on line \axp@replay@line}{% The synctex option of apxproof requires the source files of the document\MessageBreak to be readable under the same names when the appendix is typeset.\MessageBreak This appendix material will be missing.}% \gdef\axp@region@openfile{}% \else \axp@region@toofar \fi \else \axp@region@readto{\axp@replay@line}% \ifeof\axp@readfile \axp@region@toofar \else \axp@region@analyze \ifaxp@region@ok \axp@region@readto{\axp@replay@endline}% \axp@region@checkend \fi \fi \fi \endlinechar\axp@region@saveendlinechar\relax } \def\axp@region@toofar{% \axp@region@okfalse \PackageError{apxproof}{% File `\axp@replay@file' has fewer than \axp@replay@line\space lines, where\MessageBreak the \axp@replay@env\space environment to re-read was expected}{% The source file has probably changed since the main text was processed,\MessageBreak or the main file is not `\jobname.tex'. This appendix material will be missing.}% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % Several macros need |\begin{|, |\end{|, |}| or an end-of-line character % as delimiters, with the catcode 12 that these characters have when % read from |\readline| or with the catcodes we set to skip lines. We define % them with |\lowercase|, mapping placeholder characters to the ones we need, % which preserves catcodes. % \begin{macro}{\axp@region@scanline} % \begin{macro}{\axp@region@scan} % \begin{macro}{\axp@region@getname} % \begin{macro}{\axp@region@scanendline} % \begin{macro}{\axp@region@scanend} % \begin{macro}{\axp@gobbleline} % \begin{macro}{\axp@gobbletobegin} % \begin{itemize} % \item |\axp@region@scanline| splits its argument at the first |\begin{|; % \item |\axp@region@getname| splits its argument at the first |}|; % \item |\axp@region@scanendline| splits its argument at the first |\end{|; % \item |\axp@gobbleline| discards the input up to and including the next % end of line; % \item |\axp@gobbletobegin| discards the input up to and including the % next |\begin{|. % \end{itemize} % In the first three, a sentinel is appended so that a match is always % found; the last two then continue with the macros indicated. % \begin{macrocode} \begingroup \lccode`\!=`\\ \lccode`\?=`\{ \lccode`\|=`\} \lccode`\"=`\^^M \lccode`\+=`\b \lccode`\-=`\e \lccode`\*=`\g \lccode`\/=`\i \lccode`\==`\n \lccode`\,=`\d \catcode`\!=12 \catcode`\?=12 \catcode`\|=12 \catcode`\"=12 \catcode`\+=12 \catcode`\-=12 \catcode`\*=12 \catcode`\/=12 \catcode`\==12 \catcode`\,=12 \lowercase{\endgroup \long\def\axp@region@scanline#1{% \axp@region@scan#1!+-*/=?\axp@region@marker\@nil} \long\def\axp@region@scan#1!+-*/=?#2\@nil{\axp@region@scan@i{#2}} \long\def\axp@region@getname#1{\axp@region@getname@i#1|\@nil} \long\def\axp@region@getname@i#1|#2\@nil{\def\axp@region@name{#1}} \long\def\axp@region@scanendline#1{% \axp@region@scanend#1!-=,?\axp@region@marker\@nil} \long\def\axp@region@scanend#1!-=,?#2\@nil{% \def\axp@region@rest{#2}} \long\def\axp@gobbleline#1"{\axp@skiplines} \long\def\axp@gobbletobegin#1!+-*/=?{\axp@region@nextbegin} } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\axp@region@analyze} % \begin{macro}{\axp@region@scan@i} % We look on the start line for |\begin{|\meta{env}|}|. As the % environment may be wrapped in a user-defined environment (in which % case the line contains, say, |\begin{mythm}|), we settle for the first % |\begin{| on the line if the exact one is absent. |\axp@region@begins| % is set to the number of |\begin{| to skip on the line before the one % to use. % \begin{macrocode} \newcount\axp@region@begins \newcount\axp@skipcount \newif\ifaxp@region@found \def\axp@region@marker{\axp@region@marker} \def\axp@region@analyze{% \axp@region@begins=\z@ \axp@region@foundfalse \edef\axp@region@target{% \expandafter\detokenize\expandafter{\axp@replay@env}}% \expandafter\axp@region@scanline\expandafter{\axp@line}% \ifaxp@region@found \axp@region@oktrue \else \ifnum\axp@region@begins>\z@ \axp@region@begins=\z@ \axp@region@oktrue \else \PackageError{apxproof}{% Cannot find \string\begin\@charlb\axp@replay@env\@charrb\space on line \axp@replay@line\space of\MessageBreak `\axp@replay@file' to re-read it}{% The synctex option of apxproof requires \string\begin\@charlb\axp@replay@env\@charrb\space to appear\MessageBreak literally in the source file, on the line where the environment starts.\MessageBreak This appendix material will be missing.}% \fi \fi } % \end{macrocode} % |\axp@region@scan@i| receives what follows a |\begin{|. If this is only % the sentinel, there is no further |\begin{| on the line. Otherwise % we extract the environment name and compare it with the target, % moving on to the next |\begin{| if it differs. % \begin{macrocode} \long\def\axp@region@scan@i#1{% \def\axp@region@rest{#1}% \ifx\axp@region@rest\axp@region@marker \else \axp@region@getname{#1}% \ifx\axp@region@name\axp@region@target \axp@region@foundtrue \else \advance\axp@region@begins\@ne \axp@region@scan#1\@nil \fi \fi } % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\axp@region@checkend} % Similarly, we check that the end line contains an |\end{|. % \begin{macrocode} \def\axp@region@checkend{% \expandafter\axp@region@scanendline\expandafter{\axp@line}% \ifx\axp@region@rest\axp@region@marker \axp@region@okfalse \PackageError{apxproof}{% Cannot find the \string\end\space of the \axp@replay@env\space environment\MessageBreak starting on line \axp@replay@line\space of `\axp@replay@file' (expected on line \axp@replay@endline)}{% The synctex option of apxproof requires the \string\end\space of the environment\MessageBreak to appear literally in the source file. This appendix material will be missing.}% \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@region@replay} % \begin{macro}{\axp@region@cleanup} % \begin{macro}{\axp@region@catcodes} % Now the actual replay. Within the appendix, |\begin{|\meta{env}|}| must % run the begin code we were given and |\end{|\meta{env}|}| the end code; % we save the current meaning of the corresponding macros, and of |\end| % itself (see below), to restore them afterwards. We also save the catcodes of all characters, as they will % be modified at the end of the replay (see below): |\axp@region@catcodes| % expands to the assignments restoring them. We deliberately do not % wrap the replay in a group, so that whatever the |\end| of the % environment does to the paragraph that follows (as |\@doendpe| does) % survives it, exactly as when the material is copied to the |.axp| file. % The file is then opened by the primitive |\input| in a group where every % character is ignored (catcode 9) except the end-of-line character, % which is an ordinary one: lines are skipped without \TeX{} building any % token, until the start line, which is read with every character an % ordinary one (so that none is special, no control sequence is formed % and no line can be mistaken for a paragraph break); the group ends when % we hand over to the environment. % \begin{macrocode} \def\axp@region@catcodes#1{% \catcode#1=\the\catcode#1\relax \ifnum#1<255 \expandafter\axp@region@catcodes\expandafter {\number\numexpr#1+1\expandafter}% \fi} \def\axp@region@setcatcodes#1{% \count@=\z@ \loop \catcode\count@=#1\relax \ifnum\count@<255 \advance\count@\@ne \repeat} \def\axp@region@replay{% \edef\axp@region@catcoderestore{\axp@region@catcodes{0}}% \expandafter\let\expandafter\axp@region@savedbegin \csname\axp@replay@env\endcsname \expandafter\let\expandafter\axp@region@savedend \csname end\axp@replay@env\endcsname \expandafter\let\csname\axp@replay@env\endcsname\axp@replay@begin \expandafter\let\csname end\axp@replay@env\endcsname\axp@replay@end \let\axp@region@savedendcmd\end \axp@region@wrappedfalse \begingroup \axp@region@setcatcodes{9}% \catcode13=12\relax \endlinechar=13\relax \axp@skipcount=\axp@replay@line\relax \advance\axp@skipcount\m@ne \axp@region@input \axp@region@cleanup } \def\axp@region@cleanup{% \axp@region@input@done \expandafter\let\csname\axp@replay@env\endcsname\axp@region@savedbegin \expandafter\let\csname end\axp@replay@env\endcsname\axp@region@savedend \let\end\axp@region@savedendcmd \expandafter\let\csname axp@region@isregion@\axp@replay@env\endcsname \undefined \ifaxp@region@wrapped \expandafter\let\csname end\axp@region@name\endcsname \axp@region@savedwrappedend \fi \axp@region@catcoderestore } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\axp@region@input} % \begin{macro}{\axp@region@input@done} % \begin{macro}{\axp@region@altfile} % Opening the file is where we have to care about the way Sync\TeX{} % names files. \TeX{} gives every file it opens a new tag, and records % the tag and name in the |.synctex| file, so re-reading a file % registers it a second time under the same name; and the parser used by % viewers and editors, when asked (forward search, from the editor to % the PDF) for a source line of some file, resolves the name to a single % tag, the last one registered under that name. With the re-read % registered as is, forward search from the main text would then land in % the appendix, or nowhere. Two remedies: % \begin{itemize} % \item With Lua\TeX{}, we can have the nodes created while re-reading % carry the file's original tag, with the Lua function % |tex.force_synctex_tag| (which requires |tex.set_synctex_mode(2)|; % line numbers remain the actual ones), and % not register the re-read at all (|tex.set_synctex_no_files|). Both % directions then work everywhere. Files |\input| from within the % material are handled normally again during their reading, thanks to % the kernel's file hooks. All this is done in Lua, see below. % \item With other engines, we open the file under a name that the parser % does not consider equivalent to the recorded one, but which designates % the same file and which editors normalize: % \meta{cwd}|/../|\meta{cwd name}|/|\meta{file}. Forward search then % behaves as when the material was copied (main text only), while % inverse search from the appendix gives the right file and line. The % working directory is read from the |.fls| file written by the % |-recorder| option (used by \textsf{latexmk} and most editors); % failing that, the file is opened under its plain name. % \end{itemize} % \begin{macrocode} \ifdefined\directlua \def\axp@region@input{% \ifnum\axp@replay@tag>\z@ \directlua{apxproof.synctex_force(\axp@replay@tag)}% \global\let\axp@region@forcedtag\axp@replay@tag \fi \expandafter\axp@skiplines\@@input\axp@replay@file\relax} \def\axp@region@input@done{% \ifnum\axp@replay@tag>\z@ \directlua{apxproof.synctex_unforce()}% \global\let\axp@region@forcedtag\relax \fi} \let\axp@region@forcedtag\relax \ifdefined\AddToHook \AddToHook{file/before}{% \ifx\axp@region@forcedtag\relax\else \directlua{apxproof.synctex_unforce()}% \fi} \AddToHook{file/after}{% \ifx\axp@region@forcedtag\relax\else \directlua{apxproof.synctex_force(\axp@region@forcedtag)}% \fi} \fi % \end{macrocode} % The Lua side. Forcing the tag does not reach nodes created from Lua % (such as the glyphs that \textsf{luaotfload} inserts for ligatures), % which in this mode get no tag and line at all and would be attributed, % when the page is shipped out, to wherever \TeX{} is then. A filter run % before line breaking and box packing therefore gives such nodes, while % a tag is forced, the tag and the line of the nearest preceding node % (or following one, at the start of a list). (Font kerns are a % different matter: Lua\TeX{} records them with the position of the % enclosing |\input| rather than with the position of the glyphs they % sit between, in the main text just as well, and does not use the % fields we could set; this is a Lua\TeX{} peculiarity that we leave % alone.) % \begin{macrocode} \directlua{ apxproof = apxproof or {} apxproof.forced_tag = 0 local get, set = node.direct.get_synctex_fields, node.direct.set_synctex_fields local traverse, todirect = node.direct.traverse, node.direct.todirect function apxproof.synctex_force(tag) apxproof.saved_tag, apxproof.saved_line = tex.get_synctex_tag(), tex.get_synctex_line() tex.set_synctex_no_files(1) tex.set_synctex_mode(2) tex.force_synctex_tag(tag) tex.set_synctex_tag(tag) tex.set_synctex_line(0) apxproof.forced_tag = tag end function apxproof.synctex_unforce() apxproof.forced_tag = 0 tex.force_synctex_tag(0) tex.set_synctex_tag(apxproof.saved_tag or 0) tex.set_synctex_line(apxproof.saved_line or 0) tex.set_synctex_mode(0) tex.set_synctex_no_files(0) end local getprev, tail = node.direct.getprev, node.direct.tail function apxproof.synctex_fix(head) local tag = apxproof.forced_tag if tag == 0 then return true end local last_l = 0 local pending = false for n in traverse(todirect(head)) do local t, l = get(n) if t == 0 or (t == tag and l == 0) then if last_l > 0 then set(n, tag, last_l) else pending = true end elseif t == tag then last_l = l end end if pending then local n = tail(todirect(head)) last_l = 0 while n do local t, l = get(n) if t == 0 or (t == tag and l == 0) then if last_l > 0 then set(n, tag, last_l) end elseif t == tag then last_l = l end n = getprev(n) end end return true end luatexbase.add_to_callback("pre_linebreak_filter", apxproof.synctex_fix, "apxproof.synctex") luatexbase.add_to_callback("hpack_filter", apxproof.synctex_fix, "apxproof.synctex") } \else \def\axp@region@input{% \axp@region@altfile \expandafter\axp@skiplines\@@input\axp@replay@altfile\relax} \let\axp@region@input@done\relax \fi % \end{macrocode} % |\axp@region@altfile| defines |\axp@replay@altfile| from % |\axp@replay@file|. The working directory is looked up once, in the % first line of the |.fls| file, which reads |PWD |\meta{directory}; its % last component is extracted by |\axp@region@lastcomponent|. An % absolute file name (an unusual case) is prefixed with a second |/| % instead, which has the same effect. As the same read stream is used, we % forget the file the check pass may have kept open. % \begin{macrocode} \let\axp@region@pwd\relax \def\axp@region@altfile{% \ifx\axp@region@pwd\relax \axp@region@findpwd \fi \ifx\axp@region@pwd\@empty \let\axp@replay@altfile\axp@replay@file \else \expandafter\axp@region@altfile@i\axp@replay@file\@nil \fi} \def\axp@region@altfile@i#1#2\@nil{% \if/#1% \edef\axp@replay@altfile{/\axp@replay@file}% \else \edef\axp@replay@altfile{% \axp@region@pwd/../\axp@region@pwdbase/\axp@replay@file}% \fi} \def\axp@region@findpwd{% \gdef\axp@region@pwd{}% \IfFileExists{\jobname.fls}{% \begingroup \endlinechar\m@ne \openin\axp@readfile=\jobname.fls\relax \ifeof\axp@readfile\else \readline\axp@readfile to\axp@line \expandafter\axp@region@findpwd@i\axp@line \relax\relax\relax\relax\@nil \fi \closein\axp@readfile \endgroup \gdef\axp@region@openfile{}% }{}% } \def\axp@region@findpwd@i#1#2#3#4\@nil{% \def\axp@tmp{#1#2#3}% \edef\axp@tmpa{\detokenize{PWD}}% \ifx\axp@tmp\axp@tmpa \axp@region@findpwd@ii#4\@nil \fi} \def\axp@region@findpwd@ii#1\relax#2\@nil{% \axp@region@findpwd@iii#1\@nnil\@nnil} \def\axp@region@findpwd@iii#1#2\@nnil#3\@nnil{% \ifx\@nnil#1\else \xdef\axp@region@pwd{#1#2}% \xdef\axp@region@pwdbase{\axp@region@lastcomponent#1#2/\@nil}% \ifx\axp@region@pwdbase\@empty \gdef\axp@region@pwd{}% \fi \fi} \def\axp@region@lastcomponent#1/#2\@nil{% \ifx\@empty#2\@empty #1% \else \axp@region@lastcomponent#2\@nil \fi} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\axp@region@findmain} % \changes{v1.5.0}{2026/08/25}{Locate the main source file through the % \texttt{.fls} file, and fall back to copying when it cannot be read} % The kernel leaves |\CurrentFileUsed| empty for the main file and tells us % nothing about the name \TeX{} opened it under, so |\jobname.tex| is the % obvious guess; it is wrong whenever the document was compiled by giving % \TeX{} a path, as in |pdflatex sub/doc.tex|, and the material would then % all be missing from the appendix. The |.fls| file records the name that % was actually used, in the first |INPUT| line whose last component is % |\jobname.tex| (the entries before it are the configuration files and the % format). We look it up once, here, rather than at replay time: the % Boolean is consulted while theorems are being defined in the preamble, % and the |.fls| is already complete that early, since \TeX{} opens the % main file before reading anything of it. The lines are parsed as in % |\axp@region@findpwd| above, with |INPUT| in place of |PWD|, and % |\axp@region@stopmain| ends the scan on the first match or at the end of % the file. % \begin{macrocode} \newif\ifaxp@region@stopmain \def\axp@region@findmain{% \IfFileExists{\jobname.fls}{% \begingroup \endlinechar\m@ne \edef\axp@tmp{\jobname.tex}% \edef\axp@region@jobnametex{% \expandafter\detokenize\expandafter{\axp@tmp}}% \openin\axp@readfile=\jobname.fls\relax \axp@region@stopmainfalse \loop \ifaxp@region@stopmain\else \ifeof\axp@readfile \axp@region@stopmaintrue \else \readline\axp@readfile to\axp@line \expandafter\axp@region@findmain@i\axp@line \relax\relax\relax\relax\relax\relax\@nil \fi \repeat \closein\axp@readfile \endgroup \gdef\axp@region@openfile{}% }{}% } \def\axp@region@findmain@i#1#2#3#4#5#6\@nil{% \def\axp@tmp{#1#2#3#4#5}% \edef\axp@tmpa{\detokenize{INPUT}}% \ifx\axp@tmp\axp@tmpa \axp@region@findmain@ii#6\@nil \fi} \def\axp@region@findmain@ii#1\relax#2\@nil{% \axp@region@findmain@iii#1\@nnil\@nnil} \def\axp@region@findmain@iii#1#2\@nnil#3\@nnil{% \ifx\@nnil#1\else \edef\axp@tmpa{\axp@region@lastcomponent#1#2/\@nil}% \ifx\axp@tmpa\axp@region@jobnametex \xdef\axp@region@mainfile{#1#2}% \axp@region@stopmaintrue \fi \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\axp@region@setup} % We can now settle whether re-reading is possible at all. If the main file % cannot be read under the name we have, nothing of it could be replayed, % and every piece of appendix material coming from it would be lost; we % therefore clear the Boolean, so that the whole package behaves exactly as % with |synctex=no|, and say so. The document is then complete, only % without Sync\TeX{} support for appendix material. This has to happen % before any |\newtheoremrep|, which consults the Boolean to decide how to % define the |foobarrep| environment. % \begin{macrocode} \ifbool{axp@synctex}{ \axp@region@findmain \IfFileExists{\axp@region@mainfile}{% \message{apxproof: SyncTeX support enabled, appendix material re-read from source files}% }{% \boolfalse{axp@synctex}% \PackageWarning{apxproof}{% Cannot read the main source file `\axp@region@mainfile'; the synctex\MessageBreak option cannot re-read appendix material from it. Falling back to\MessageBreak copying it to the .axp file, as with synctex=no: the document is\MessageBreak complete, but SyncTeX does not cover appendix material. This\MessageBreak happens when TeX is given a path to the main file and no .fls file\MessageBreak is available to resolve it (option -recorder)}% }% }{} % \end{macrocode} % \end{macro} % \begin{macro}{\axp@skiplines} % \begin{macro}{\axp@region@nextbegin} % \begin{macro}{\axp@region@afterbegin} % Note that the tokens following |\@@input| in |\axp@region@replay| % are only read once the file has been closed, and that when % |\axp@skiplines| starts, the first line of the file has been read into % \TeX's buffer but nothing has been tokenized yet. We gobble whole lines % until the start line, which is read with all characters ordinary, % then |\begin{| as many times as needed, and % close the catcode group: the rest of the line, still in the buffer, % will be tokenized with the normal catcodes, but with |@| an ordinary % character as in the rest of the document. % \begin{macrocode} \def\axp@skiplines{% \ifnum\axp@skipcount>\z@ \advance\axp@skipcount\m@ne \expandafter\axp@gobbleline \else \axp@region@setcatcodes{12}% \axp@skipcount=\axp@region@begins \expandafter\axp@gobbletobegin \fi} \def\axp@region@nextbegin{% \ifnum\axp@skipcount>\z@ \advance\axp@skipcount\m@ne \expandafter\axp@gobbletobegin \else \expandafter\axp@region@afterbegin \fi} \def\axp@region@afterbegin{% \endgroup \catcode`\@=12 \def\axp@region@name{}% \axp@region@readname} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\axp@region@readname} % \begin{macro}{\axp@region@readname@go} % The name of the environment is then read character by character up to % the closing brace, which is consumed by a |\let|. (A macro cannot insert % an unbalanced |{| into the input, and a delimited argument cannot be % delimited by |}|.) % % If the name is the expected one, we do not execute |\begin| at all, % as material copied to the |.axp| file was not enclosed in a group, and % we want the same here (a group would, e.g., undo what a % |\subsection| in a |toappendix| environment does to the paragraph that % follows it). We run the begin code directly, and let |\end| be % |\axp@region@endcmd|, which runs the end code and |\axp@region@finish| % for the expected environment, and delegates every other name to the % saved |\end|; nested environments in the material thus behave as usual. % The test on the name is done with |\ifcsname| on a flag set for the % expected environment, so that the wrapper is expandable, as the kernel's % |\end| is, up to the point where the original |\end| takes over: this % matters when |\end{tabular}| is met while \TeX{} scans the beginning of % an alignment row, where anything unexpandable would open a new row. % |\axp@region@finish| makes every character ignored, so that whatever % remains of the |\end| line is dropped by \TeX's tokenizer, and stops % reading the file with |\endinput|. Doing this with catcodes rather than % by grabbing the rest of the line is necessary, because pending tokens % of the macros being executed would otherwise be grabbed as well. % % If the name is different (the environment is wrapped in a user % environment), we execute |\begin| with that name; the environment's % end code (the user's) is extended with |\aftergroup\axp@region@finish| % so that the file is closed right after the group of the environment % ends. % \begin{macrocode} \def\axp@region@readname{% \futurelet\axp@region@next\axp@region@readname@i} \def\axp@region@readname@i{% \ifx\axp@region@next\egroup \expandafter\axp@region@readname@done \else \expandafter\axp@region@readname@ii \fi} \def\axp@region@readname@ii#1{% \edef\axp@region@name{\axp@region@name#1}\axp@region@readname} \def\axp@region@readname@done{% \afterassignment\axp@region@readname@go\let\axp@region@next= } \def\axp@region@readname@go{% \ifx\axp@region@name\axp@replay@env \expandafter\axp@region@go@direct \else \expandafter\axp@region@go@wrapped \fi} \def\axp@region@go@direct{% \expandafter\let\csname axp@region@isregion@\axp@replay@env\endcsname \@empty \let\end\axp@region@endcmd \axp@replay@begin} \def\axp@region@go@wrapped{% \axp@region@wrappedtrue \expandafter\let\expandafter\axp@region@savedwrappedend \csname end\axp@region@name\endcsname \expandafter\def\csname end\axp@region@name\endcsname{% \axp@region@savedwrappedend\aftergroup\axp@region@finish}% \expandafter\begin\expandafter{\axp@region@name}} \def\axp@region@endcmd#1{% \ifcsname axp@region@isregion@#1\endcsname \expandafter\axp@region@endregion \else \expandafter\axp@region@savedendcmd \fi {#1}} \def\axp@region@endregion#1{\axp@replay@end\axp@region@finish} \def\axp@region@finish{\axp@region@setcatcodes{9}\endinput} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\axp@region@proof} % \begin{macro}{\axp@region@rp} % Finally, the begin codes used in the appendix, which read the optional % argument of the environment from the source. For proofs, the first argument % is the proof environment to use and the second is |1| if the proof is % to be titled by |\axp@apxproofstart| (this is decided in the main text, % and thus passed along). The optional argument is looked for exactly as % in the main text, without skipping spaces. The end of the % |\begin{proof}| line was not copied to the |.axp| file, and we % |\ignorespaces| it, which also prevents the proof environment from % mistaking a |[| at the start of the body for an optional argument. % \begin{macrocode} \def\axp@region@proof#1#2{% \ltx@ifnextchar@nospace[% {\axp@region@proof@opt{#1}}{\axp@region@proof@noopt{#1}{#2}}} \def\axp@region@proof@opt#1[#2]{\begin{#1}[#2]\ignorespaces} \def\axp@region@proof@noopt#1#2{% \ifnum#2=\@ne \expandafter\axp@apxproofstart \else \expandafter\begin \fi {#1}\ignorespaces} % \end{macrocode} % For |toappendix| environments, we typeset the pending appendix section % heading, if any, using |\axp@section| which looks at what follows in the % source, and otherwise skip the end of the |\begin{toappendix}| line, which % was not copied to the |.axp| file. % \begin{macrocode} \def\axp@region@toappendix{% \ifx\axp@region@pendingsection\relax \expandafter\ignorespaces \else \expandafter\axp@region@toappendix@section \fi} \def\axp@region@toappendix@section{% \edef\axp@tmp{\expandonce\axp@region@pendingsection}% \global\let\axp@region@pendingsection\relax \expandafter\axp@section\expandafter{\axp@tmp}% } % \end{macrocode} % For repeated theorems, the arguments are the theorem name and the value of % |axp@rpcounter|; the heading is built as in |\axp@newtheoremrep| below. % \begin{macrocode} \def\axp@region@rp#1#2{% \@ifnextchar[{\axp@region@rp@i{#1}{#2}}{\axp@region@rp@i{#1}{#2}[]}} \def\axp@region@rp@i#1#2[#3]{% \begin{axp@#1rp}[% \axp@refstar{axp@r#2}% \@ifnotempty{#3}{% \ifdefined\theopargself\else \ifdefined\@acmplainnotefont \@acmplainnotefont \else \ifdefined\thm@notefont\the\thm@notefont\fi \fi \fi {} ({#3})% }% ]% \axp@forward@target{axp@fw@r#2}{}% \axp@redefinelabels } % \end{macrocode} % \end{macro} % \end{macro} % \subsection{Inline Compilation Mode} % \begin{macrocode} \ifthenelse{\equal{\axp@appendix}{inline}}{ % \end{macrocode} % \begin{macro}{\axp@newtheoremrep} % In inline mode, |\axp@newtheoremrep| uses % |\axp@newtheoremrep@definetheorem| to define the regular theorem % environment and creates a repeated theorem % environment that behaves exactly as the regular theorem environment, % while calling |\axp@redefinelabels| to make sure that |-axp| variants % of equation counters are defined. % \changes{v1.2.0}{2019/02/15}{Fix formatting of theorems without % notes in some document classes in inline mode} % With the |synctex| option, the environment is defined with % |\newenvironment| so that its body is typeset directly from the source % file (see Section~\ref{sec:synctex-impl}). % \begin{macrocode} \def\axp@newtheoremrep#1[#2]#3[#4]{% \axp@newtheoremrep@definetheorem{#1}{#2}{#3}{#4}% \ifbool{axp@synctex}{% \newenvironment{#1rep}[1][]{% \ifx\relax##1\relax \begin{#1}\axp@redefinelabels \else \begin{#1}[##1]\axp@redefinelabels \fi }{\end{#1}}% }{% \NewEnviron{#1rep}[1][]{% \ifx\relax##1\relax \begin{#1}\axp@redefinelabels\BODY\end{#1}% \else \begin{#1}[##1]\axp@redefinelabels\BODY\end{#1}% \fi }% }% } % \end{macrocode} % \end{macro} % \begin{environment}{inlineproof} % \begin{environment}{nestedproof} % \begin{environment}{appendixproof} % In inline mode, these environments behave like the regular |proof| % environment. % \begin{macrocode} \let\inlineproof\proof \let\endinlineproof\endproof \let\nestedproof\proof \let\endnestedproof\endproof \let\appendixproof\proof \let\endappendixproof\endproof % \end{macrocode} % \end{environment} % \end{environment} % \end{environment} % \begin{environment}{toappendix} % \begin{macro}{\noproofinappendix} % \begin{macro}{\nosectionappendix} % In inline mode, this environment and these macros are no-ops. % \begin{macrocode} \newenvironment{toappendix}{}{} \let\noproofinappendix\relax \let\nosectionappendix\relax % \end{macrocode} % \end{macro} % \end{macro} % \end{environment} % \begin{macrocode} } % \end{macrocode} % \subsection{Append, Strip, or Chapter End Compilation Modes} % \begin{macrocode} { % \end{macrocode} % We now deal with the case where \textsf{apxproof} really does something % useful: either append the appendix material to the document, or strip % it entirely. % \bigskip % \subsubsection{Auxiliary File for the Appendix} % \begin{macro}{\axp@proofsfile} % We open a new auxiliary file, with extension |.axp|, where the appendix % material will be dumped. % \changes{v1.1.0}{2018/07/11}{Initialization deferred to \cs{AtBeginDocument} % for compatibility with \cs{dump}ed precompiled preambles (K. D. % Bauer)} % \begin{macrocode} \AtBeginDocument{ \newwrite\axp@proofsfile \ifthenelse{\equal{\axp@appendix}{chapterend}}{% \axp@openchapterfile }{% \immediate\openout\axp@proofsfile=\jobname.axp }% } % \end{macrocode} % \end{macro} % \begin{environment}{proof} % \begin{macro}{\section} % At the beginning of this file, we make |@| a regular character (since % it will be used in several places for internal names) and reestablish the original definition of % the |proof| environment and the |\section| macro. % \begin{macrocode} \newcommand{\axp@writeproofsfilepreamble}{% \immediate\write\axp@proofsfile{% \noexpand\makeatletter \noexpand\let\noexpand\proof\noexpand\axp@replayproof \noexpand\let\noexpand\endproof\noexpand\endaxp@oldproof \noexpand\let\noexpand\claimproof\noexpand\axp@oldclaimproof \noexpand\let\noexpand\endclaimproof\noexpand\endaxp@oldclaimproof \noexpand\let\noexpand\section\noexpand\axp@oldsection }% } \AtBeginDocument{ \ifthenelse{\equal{\axp@appendix}{chapterend}}{}{% \axp@writeproofsfilepreamble }% } % \end{macrocode} % \end{macro} % \end{environment} % \begin{macro}{\axp@unactivateeightbit} % \changes{v1.1.0}{2019/01/28}{Fix compilation of non-ASCII % characters with \texttt{\textbackslash usepackage[utf8]\{inputenc\}}} % We need an auxiliary macro to disable active characters that have the % high bit set when writing to the |.axp| file. See % \url{https://tex.stackexchange.com/a/145361/166858} % \begin{macrocode} \def\axp@unactivateeightbit{% \count@=128% \loop \catcode\count@=12% \ifnum\count@<255% \advance\count@\@ne \repeat} % \end{macrocode} % \end{macro} % \begin{environment}{axp@VerbatimOut} % \begin{macro}{\FVB@axp@VerbatimOut} % \begin{macro}{\FVE@axp@VerbatimOut} % \changes{v1.1.0}{2018/10/02}{Make \textsf{apxproof} compatible with % independent use of \textsf{fancyvrb}} % Using the functionalities of the \textsf{fancyvrb} package, we define a % custom verbatim environment |axp@VerbatimOut| that writes every line % to the |\axp@proofsfile|. We also use the previous macro to disable active % characters with the eighth bit set, and we make sure the catcode of |@| % is reset for every verbatim environment, in case it is used by the user (e.g., % as in the \textsf{xypic} package). Finally, as an additional % precaution, we reset |\FV@CatCodesHook| that is for example set by the % |commandchars| or |commentchar| option of |\fvset|. % \changes{v1.2.1}{2020/01/01}{Fix compatibility with % \textsf{xypic} package} % \changes{v1.2.1}{2020/10/15}{Fix compatibility with other uses of \textsf{fancyvrb} that set % \texttt{\textbackslash FV@CatCodesHook}} % With the |synctex| option, the environment is still scanned line by line by % \textsf{fancyvrb} (this is how we skip its content in the main text and % find its end), but the lines are not written to the |.axp| file, which % instead receives an |\axp@replaybody| command % (Section~\ref{sec:synctex-impl}). % \begin{macrocode} \DefineVerbatimEnvironment{axp@VerbatimOut}{axp@VerbatimOut}{} \def\FVB@axp@VerbatimOut{% \@bsphack \begingroup \axp@unactivateeightbit \FV@DefineWhiteSpace \def\FV@Space{\space}% \FV@DefineTabOut \ifbool{axp@synctex}{% \let\FV@ProcessLine\@gobble }{% \def\FV@ProcessLine{\immediate\write\axp@proofsfile}% }% \let\FV@FontScanPrep\relax \let\@noligs\relax \def\FV@CatCodesHook{}% \FV@Scan} \def\FVE@axp@VerbatimOut{% \immediate\write\axp@proofsfile{\noexpand\makeatletter}% \endgroup\@esphack} % \end{macrocode} % \end{macro} % \end{macro} % \end{environment} % \begin{macro}{\axp@markchapterhasappendix} % No-op by default; overridden in |chapterend| mode to set a flag % indicating that the current chapter has appendix content. % \begin{macrocode} \newcommand{\axp@markchapterhasappendix}{} % \end{macrocode} % \end{macro} % \begin{environment}{toappendix} % The entire content of this environment is put in appendix, % starting a new appendix section beforehand if needed. With the % |synctex| option, we record where the environment starts and, at its % end, write the replay command; in the appendix, the begin code is % |\axp@region@toappendix| and there is no end code. As % |\axp@section| looks at what follows it to decide whether to % typeset a heading, and the content is now only available once the % environment is replayed, we have the section command written as % |\axp@region@section|, which merely stores the heading for % |\axp@region@toappendix| to handle. % \begin{macrocode} \newenvironment{toappendix} {\axp@markchapterhasappendix \ifbool{axp@synctex}{% \def\axp@sectioncmd{\axp@region@section}% \axp@writesection \axp@region@record }{% \axp@writesection }% \axp@VerbatimOut} {\endaxp@VerbatimOut \ifbool{axp@synctex}{% \axp@region@write{\noexpand\axp@region@toappendix}{\relax}% }{}} % \end{macrocode} % \end{environment} % \subsubsection{Definition of New Theorems} % \begin{macro}{axp@seenreptheorem} % Used to indicate whether a repeated theorem was just typeset, without % its proof. % \begin{macrocode} \newtoggle{axp@seenreptheorem} % \end{macrocode} % \end{macro} % \begin{macro}{axp@rpcounter} % Sequentially incremented for every repeated theorem, used to create labels. % \begin{macrocode} \newcounter{axp@rpcounter} % \end{macrocode} % \end{macro} % \begin{macro}{axp@equation} % \begin{macro}{axp@equationx} % Used to save the value of the |equation| counter, when |repeqn| is set % to |same|. % \begin{macrocode} \newcounter{axp@equation} \newcounter{axp@equationx} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{axp@newtheoremrep} % With first argument |foobar|, we use % |\axp@newtheoremrep@definetheorem| to define the regular version of the % theorem |foobar|. We then patch |\begin{foobar}| so as not to % expect a proof in the appendix and define an internal theorem |axp@foobarrp| that % will be used in the appendix to restate the existing theorem. % In the starred mode, the theorem is not restated in the appendix, % so we do not define the |axp@foobarrp| environment. % \begin{macrocode} \def\axp@newtheoremrep#1[#2]#3[#4]{% \axp@newtheoremrep@definetheorem{#1}{#2}{#3}{#4}% \expandafter\pretocmd\csname #1\endcsname{\noproofinappendix}{}{}% \ifcsdef{axp@proofof@#1}{}{% \axp@newtheorem*{axp@#1rp}{#3}% }% \axp@forward@setup{#1}{#2}{#3}{#4}% % \end{macrocode} % We then define a |foobarrep| environment, whose begin code and code % writing the appendix material are the two macros described below, % |\axp@newtheoremrep@begin| and |\axp@newtheoremrep@end|. Normally, the % body of the environment is collected by \textsf{environ}, typeset, and % stored in a macro for the appendix. With the |synctex| option, the environment % is instead an ordinary one, so that its body is typeset directly from the % source file, and the appendix will re-read the body from there % (Section~\ref{sec:synctex-impl}); we first record where the environment % starts. % \changes{v1.5.0}{2026/08/19}{Repeated theorems typeset directly from % the source with the \texttt{synctex} option} % \begin{macrocode} \ifbool{axp@synctex}{% \newenvironment{#1rep}[1][]{% \axp@region@record \axp@newtheoremrep@begin{#1}{##1}% }{% \end{#1}% \axp@newtheoremrep@end{#1}{#3}{}% }% }{% \NewEnviron{#1rep}[1][]{% \axp@newtheoremrep@begin{#1}{##1}% \BODY\end{#1}% \global\expandafter\let\csname rplet\roman{axp@rpcounter}% \endcsname \BODY \axp@newtheoremrep@end{#1}{#3}{##1}% }% }% } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@newtheoremrep@begin} % The begin code of a |foobarrep| environment increments the % |axp@rpcounter| and typesets the regular |foobar| theorem with a label % derived from the counter, along with a possible custom command to % identify repeated theorems. We distinguish the case when the theorem % argument has a note and when it does not. % \changes{v1.0.6}{2018/05/10}{Better handling of note-free theorems in % document classes that treat theorems differently when they have an % empty note} % We save the equation counter % before typesetting the theorem environment, to reset it to the same % value in the repeated environment when |repeqn| is set to |same|. % \changes{v1.2.2}{2020/11/25}{Fix handling of optional arguments of % repeated theorems containing optional arguments} % \begin{macrocode} \def\axp@newtheoremrep@begin#1#2{% \ifthenelse{\equal{\axp@repeqn}{same}}{% \setcounter{axp@equation}{\value{equation}}% }{}% \addtocounter{axp@rpcounter}{1}% \ifx\relax#2\relax \axp@with@forward{#1}{\begin{#1}}\label{axp@r\roman{axp@rpcounter}}% \else \axp@with@forward{#1}{\begin{#1}[{#2}]}\label{axp@r\roman{axp@rpcounter}}% \fi \mainbodyrepeatedtheorem } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@newtheoremrep@end} % Once the theorem has been typeset, with arguments the theorem name, its % title and its note (the latter is only needed when the body was % collected), we set the |axp@seenreptheorem| toggle to indicate that we % are looking for the proof of the theorem. % \begin{macrocode} \def\axp@newtheoremrep@end#1#2#3{% \global\toggletrue{axp@seenreptheorem}% % \end{macrocode} % Possibly after starting a new appendix section if needed, we typeset a % repeated version of the theorem using the |axp@foobarrp| environment % and a reference to the previously defined label. % We use |\axp@redefinelabels| in this environment to avoid multiply % defined labels. We have to deal in a careful way with theorem notes: we % want to use a theorem note to display the number of the repeated % theorem, but theorem notes are usually typeset in a much % different way (different font, parentheses) than theorem % headings. In the case of the Springer document % classes, we use the |\theopargself| macro to disable parentheses. For % other document classes, we need to manually patch the |\thmhead| % command at the right time. We also specially cover the case of % the ACM document class where |\@acmplainnotefont| is used instead % of |\thm@notefont|. % \changes{v1.0.2}{2016/12/13}{Fix missing space between repeated theorem % counter and theorem note} % \changes{v1.0.2}{2016/12/13}{Fix display of repeated theorem counter in % some document classes} % \changes{v1.0.6}{2018/05/10}{Fix incorrect use of \texttt{\textbackslash noexpand} % in optional argument of macro environment} % \changes{v1.2.0}{2019/10/07}{Fix display of theorem notes} % \begin{macrocode} \axp@markchapterhasappendix \axp@writesection% \immediate\write\axp@proofsfile{\noexpand\makeatletter}% \ifthenelse{\equal{\axp@repeqn}{same}}{% \immediate\write\axp@proofsfile{% \noexpand\setcounter{axp@equationx}{\value{equation}}% \noexpand\setcounter{equation}{\theaxp@equation}% }% }{}% \ifbool{axp@forward@suppress}{% \global\def\axp@refstar{\ref*} }{% \global\def\axp@refstar{\ref} } % \end{macrocode} % We write the auto-title state to the |.axp| file so that the following % deferred proof can title itself via |\appendixproofname|. In starred % mode, we also emit a forward-link target into the appendix so that % hyperlinks from the inline theorem number always land somewhere % defined, even if the user does not provide a proof. % \changes{v1.4.0}{2026/05/14}{Write auto-title state for % \cs{appendixproofname} hook} % \begin{macrocode} \immediate\write\axp@proofsfile{% \noexpand\gdef\noexpand\axp@nextproofof@type{#2}% \noexpand\gdef\noexpand\axp@nextproofof@label{axp@r\roman{axp@rpcounter}}% }% \ifcsdef{axp@proofof@#1}{% \immediate\write\axp@proofsfile{% \noexpand\axp@forward@target{axp@fw@r\roman{axp@rpcounter}}{}% }% }{% % \end{macrocode} % In the default (unstarred) mode, we emit the repeated version of the % theorem to the appendix; the forward-link target sits inside the % restated theorem. In starred mode, we skip this block entirely. % With the |synctex| option, the restated theorem is produced by % replaying the source, and the heading is built by |\axp@region@rp|; % otherwise we write it out here, followed by the stored body. % \begin{macrocode} \immediate\write\axp@proofsfile{{% \ifdefined\theopargself \noexpand\theopargself \else \noexpand\pretocmd{\noexpand\@begintheorem}{% \noexpand\patchcmd{\noexpand\thmhead}{\noexpand\@acmplainnotefont}{}{}{}% \noexpand\patchcmd{\noexpand\thmhead}{\noexpand\the\noexpand\thm@notefont}{}{}{}% \noexpand\patchcmd{\noexpand\thmhead}{(}{}{}{}% \noexpand\patchcmd{\noexpand\thmhead}{)}{}{}{}% }{}{} \fi \ifbool{axp@synctex}{% \noexpand\axp@replaybody{\axp@region@file}{\axp@region@line}% {\the\inputlineno}{\axp@region@env}% {\noexpand\axp@region@rp{#1}{\roman{axp@rpcounter}}}% {\noexpand\end{axp@#1rp}}{\axp@region@tag}% }{% \noexpand\begin{axp@#1rp} [% \noexpand\axp@refstar{axp@r\roman{axp@rpcounter}}% \@ifnotempty{#3}{% \ifdefined\theopargself \else \ifdefined\@acmplainnotefont \noexpand\@acmplainnotefont \else \noexpand\ifdefined\noexpand\thm@notefont \noexpand\the\noexpand\thm@notefont \noexpand\fi \fi \fi {} (\unexpanded{{#3}})% }% ]% \noexpand\axp@forward@target{axp@fw@r\roman{axp@rpcounter}}{}% \noexpand\axp@redefinelabels \expandafter\noexpand\csname rplet\roman{axp@rpcounter}% \endcsname \noexpand\end{axp@#1rp} }% }}% }% \ifthenelse{\equal{\axp@repeqn}{same}}{% \immediate\write\axp@proofsfile{% \noexpand\setcounter{equation}{\value{axp@equationx}}% }% }{}% } % \end{macrocode} % \end{macro} % % \subsubsection{Forward-Linking Mechanism} % \changes{v1.1.0}{2018/07/02}{Added forward-link mechanism (K. D. Bauer)} % % When hyperref is loaded, |foobarrep| environments % in the main text have their number link to their % repetition in the appendix. % % % % \begin{macro}{\axp@with@forward} % In order to make the number of the |foobarrep| theorem a link % to its repeated version, we temporarily redefine the % |\thefoobar| command, or, if we inherited the counter % from a |bazbar| environment, the |\thebazbar| command. % This seems to be the only robust way to make the number % a |\hyperlink|, without adding extensive dependence % on internals of |amsthm|, the builtin |\newtheorem| % and possibly document-class specific definitions. % % In order to allow users to redefine |\thefoobar| without % breaking this feature, we redefine |\thefoobar| only % for the duration of the |\begin{foobar}| form, % resetting it to the old value as soon as possible. % % Redefining |\thefoobar| has the side effect of changing |\newlabel| entries % in the |.aux| file, so we need to to be able to disable % addition of the hyperlink, which is why we use an % intermediate |\axp@forward@link|\marg{target}\marg{text} macro, % We also redefine |\theHfoobar| which is used by |hyperref| but not % defined if |hyperref| was loaded after |\newtheoremrep| was used % and |\protect| it to output it verbatim into the |.aux| file. % % These hyperlinks are of course disabled in the |strip| compilation % mode. % \begin{macrocode} \newcommand{\axp@with@forward}[2]{% \ifthenelse{\equal{\axp@appendix}{strip}}{#2}{ \global\booltrue{axp@forward}% \ifcsundef{axp@old@the\csname axp@cn@#1\endcsname}{% \csletcs{axp@old@the\csname axp@cn@#1\endcsname}{the\csname axp@cn@#1\endcsname}% \csletcs{theH\csname axp@cn@#1\endcsname}{the\csname axp@cn@#1\endcsname}% \csdef{the\csname axp@cn@#1\endcsname}{% \protect\axp@forward@link{axp@fw@r\roman{axp@rpcounter}}% {\csname axp@old@the\csname axp@cn@#1\endcsname\endcsname}% }% }{}% #2% \ifcsdef{axp@old@the\csname axp@cn@#1\endcsname}{% \csletcs{the\csname axp@cn@#1\endcsname}{axp@old@the\csname axp@cn@#1\endcsname}% }{}% \global\boolfalse{axp@forward} }}% % \end{macrocode} % \end{macro} % % \begin{macro}{\axp@forward@link} % \begin{macro}{axp@forward} % Dummy macro, for handling the unwanted change of % the |\newlabel| entry in the |.aux| file caused by % changing the definition of |\thefoobar|. We also use |\texorpdfstring| % to detect whether the reference appears within a PDF bookmark, in which % case we skip the test altogether. % \changes{v1.2.5}{2025/07/25}{Remove forward linking command from PDF bookmarks} % % \begin{macrocode} \newbool{axp@forward} \newcommand{\axp@forward@link}[2]{% \ifdefined\texorpdfstring\else\newcommand\texorpdfstring[2]{#2}\fi \texorpdfstring{% \ifboolexpr{ bool {axp@forward} and not bool {axp@forward@suppress} }{% \ifcsdef{hyperlink}{% \hyperlink{#1}{#2}% }{% #2% }% }{% #2% }% }{% #2% }% }% % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\axp@forward@target} % Provides the needed |\hypertarget|. % Intended to be written to the |.axp| file. % \begin{macrocode} \newcommand{\axp@forward@target}[2]{% \ifcsname hypertarget\endcsname \hypertarget{#1}{#2}% \else #2% \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\axp@forward@setup} % \changes{v1.2.6}{2025/08/04}{Support for \texttt{aliascnt} counters} % In order to support counter inheritance with the first % optional argument of |\newtheoremrep|, % we need access to the name of the counter. % For compliance with the behavior of |\@axp@newtheorem|, % the first optional argument (|#2|) is ignored % if the second optional argument (|#4|) is given. % We also check whether |aliascnt| was used to define this counter; % if so, we use the original name as the counter name to handle % the way such aliases work. % \begin{macrocode} \newcommand{\axp@forward@setup}[4]{% \csedef{axp@cn@#1}{\ifblank{#4}{\ifblank{#2}{#1}{\ifcsdef{AC@cnt@#1}{#1}{#2}}}{#1}}% } % \end{macrocode} % \end{macro} % % % \subsubsection{Proof Environments} % \begin{macro}{\noproofinappendix} % Utility macro that toggles |axp@seenreptheorem| to false. % \begin{macrocode} \newcommand\noproofinappendix{% \global\togglefalse{axp@seenreptheorem}% } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@apxproofstart} % \changes{v1.4.0}{2026/05/14}{Helper that consults \cs{appendixproofname} % at appendix typeset time to auto-title deferred proofs} % Helper invoked from the |.axp| file at appendix typeset time to open % a deferred proof. Reads the |\axp@nextproofof@*| state (set by the % preceding |theoremrep|) and consults |\appendixproofname| to decide % whether to pass an optional title argument. % \begin{macrocode} \gdef\axp@nextproofof@type{} \gdef\axp@nextproofof@label{} % \end{macrocode} % \begin{macro}{\apxproofhook} % \changes{v1.4.1}{2026/05/31}{Hook fired when a deferred proof is % typeset, or for an inline proof whose title names its result through a % \cs{ref}; used by the \textsf{proofgraph} package} % A hook fired, inside the proof environment, each time a deferred proof is % typeset in the appendix (and also for an inline proof whose title names its % result through a |\ref|, see |\axp@inlineproofhook| below). Its argument is % the label of the theorem the proof establishes: the automatic |axp@r|\meta{n} % label of the preceding |theoremrep| for a deferred proof, or the target of % the title's |\ref| for a titled inline proof. A companion package (such as % \textsf{proofgraph}) can thereby attribute, to the right result, the % references the proof makes (which are only executed at typeset time). It is a % no-op by default. % \begin{macrocode} \providecommand\apxproofhook[1]{} \def\axp@apxproofstart#1{% \protected@xdef\axp@apxproofstart@title{% \appendixproofname{\axp@nextproofof@type}% {\noexpand\ref{\axp@nextproofof@label}}% }% \ifx\axp@apxproofstart@title\@empty \begin{#1}% \else \expandafter\axp@apxproofstart@withtitle \expandafter{\axp@apxproofstart@title}{#1}% \fi \apxproofhook{\axp@nextproofof@label}% } \def\axp@apxproofstart@withtitle#1#2{\begin{#2}[#1]} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\axp@inlineproofhook} % A proof that is \emph{not} deferred (no preceding |theoremrep|, so it is % typeset inline) never goes through |\axp@apxproofstart|, hence never fires % |\apxproofhook|. When such a proof carries an explicit title that names % its result through a |\ref| (the idiom |\begin{proof}[of Theorem~\ref{thm:x}]|), % we fire the hook here, inside the proof, with that target, so a companion % package can attribute the proof to it. We only fire when a cross-reference is % found in the title (the result is then unambiguous). The title is scanned for % the first |\ref| (or |\cref|, |\Cref|, |\autoref|, |\vref|, |\zcref|) by pure % token matching, never typesetting it: a title typically contains an % active~|~| and may carry other fragile material, which an auxiliary typeset % pass would perturb or, with |\protect| neutralised, send into an infinite % loop. % \changes{v1.5.0}{2026/08/03}{Recognize \cs{zcref} of \textsf{zref-clever} in % the title of an inline proof} % \textsf{zref-clever}'s |\zcref| is the only one of these that is not simply % \meta{cs}\marg{label}: it is |\zcref*[|\meta{options}|]|\marg{labels}, whose % star and options are to be skipped and whose mandatory argument is a % comma-separated list, of which we keep the first label. Each grabber is % handed the whole remainder of the title and swallows it up to % |\axp@refstop|, so that nothing of it is left to be typeset. % % The matching is |\in@|, hence \TeX{} delimited-argument matching, which only % sees tokens at brace level~0. A cross-reference buried in a brace group is % therefore not found, and the hook does not fire for such a title. This is the % case when the cross-reference takes an optional argument of its own, since % \LaTeX{} then requires it to be braced within the optional title, as in % |\begin{proof}[Proof of {\zcref[noname]{thm:x}}]|. Nothing else is affected: % the title is typeset as given, and |\apxproofhook| is a no-op unless a % companion package has defined it. % \begin{macrocode} \newif\ifaxp@inlineproofof \long\def\axp@inlineproofhook#1{% \global\axp@inlineproofoffalse \axp@tryrefcmd\ref{#1}% \ifaxp@inlineproofof\else\axp@tryrefcmd\cref{#1}\fi \ifaxp@inlineproofof\else\axp@tryrefcmd\Cref{#1}\fi \ifaxp@inlineproofof\else\axp@tryrefcmd\autoref{#1}\fi \ifaxp@inlineproofof\else\axp@tryrefcmd\vref{#1}\fi \ifaxp@inlineproofof\else \axp@tryrefcmd@\zcref\axp@grabzcarg{#1}% \fi \ifaxp@inlineproofof\apxproofhook{\axp@inlineproofof@label}\fi } \let\axp@refmark\relax \long\def\axp@tryrefcmd#1#2{\axp@tryrefcmd@#1\axp@grabarg{#2}} \long\def\axp@tryrefcmd@#1#2#3{% \in@{#1}{#3}% \ifin@ \long\def\axp@grabref##1#1##2\axp@refstop{#2##2\axp@refstop}% \axp@grabref#3\axp@refmark\axp@refstop \fi } \long\def\axp@grabarg#1#2\axp@refstop{% \global\axp@inlineproofoftrue\xdef\axp@inlineproofof@label{#1}} \def\axp@grabzcarg{\@ifstar\axp@grabzcarg@i\axp@grabzcarg@i} \def\axp@grabzcarg@i{\@ifnextchar[\axp@grabzcarg@opt\axp@grabzcarg@ii}%] \def\axp@grabzcarg@opt[#1]{\axp@grabzcarg@ii} \long\def\axp@grabzcarg@ii#1{% \axp@grabzcarg@iii#1,\@nil \axp@gobbletorefstop} \long\def\axp@grabzcarg@iii#1,#2\@nil{% \global\axp@inlineproofoftrue\xdef\axp@inlineproofof@label{#1}} \long\def\axp@gobbletorefstop#1\axp@refstop{} % \end{macrocode} % Proofs placed by hand in a |toappendix| environment are written verbatim to % the |.axp| file and replayed there with |\proof| let to |\axp@oldproof| (see % |\axp@writeproofsfilepreamble|). Such proofs therefore never reach % |\axp@@proof|. So that a titled one still fires |\apxproofhook|, we let, at % replay time, |\proof| to |\axp@replayproof|, which reproduces the inline % behaviour: open the |amsthm| proof, then fire the hook for the title's |\ref|. % \begin{macrocode} \def\axp@replayproof{\@ifnextchar[{\axp@replayproof@opt}{\axp@oldproof}} \def\axp@replayproof@opt[#1]{\axp@oldproof[#1]\axp@inlineproofhook{#1}} % \end{macrocode} % \end{macro} % \begin{environment}{appendixproof} % \changes{v1.2.4}{2021/11/03}{Support optional arguments in proofs} % We dump the content of this in appendix, within an original |proof| % environment, possibly after creating a new appendix section. % We support % optional arguments in proofs, but we need to be careful not to gobble % any newline character, that would make it impossible to process the % first line with \textsf{fancyvrb}. % \changes{v1.4.0}{2026/05/14}{Route deferred proofs through % \cs{axp@apxproofstart} to support \cs{appendixproofname}} % When the proof is auto-routed from a |theoremrep| (the toggle % |axp@seenreptheorem| is true at this point and no explicit optional % argument was given), we delegate the proof opening to % |\axp@apxproofstart| so that |\appendixproofname| is consulted at % appendix typeset time. A user-supplied optional argument or a manual % |\appendixproof| call (toggle false) bypasses this and uses % the standard ``Proof.'' heading. % With the |synctex| option, nothing is written when the proof starts: % we record its position and whether it is to be titled by % |\axp@apxproofstart|, and the replay command written at the end % (by |\axp@appendixproof@write|, with the name of the proof environment % to use in the appendix) carries this information to |\axp@region@proof|, % which reads the optional argument, if any, from the source. % \begin{macrocode} \def\appendixproof{\catcode`\^^M=\active\@ifnextchar[{\catcode`\^^M=5\@@appendixproof[axp@oldproof]}{\catcode`\^^M=5\@appendixproof[axp@oldproof]}} \def\@appendixproof[#1]% {% \axp@markchapterhasappendix \axp@writesection \iftoggle{axp@seenreptheorem}{% \ifbool{axp@synctex}{% \axp@region@record \def\axp@region@flag{1}% }{% \immediate\write\axp@proofsfile{% \noexpand\makeatletter\noexpand\axp@apxproofstart{#1}\noexpand\makeatother% }% }% }{% \ifbool{axp@synctex}{% \axp@region@record \def\axp@region@flag{0}% }{% \immediate\write\axp@proofsfile{% \noexpand\makeatletter\noexpand\begin{#1}\noexpand\makeatother% }% }% }% \axp@VerbatimOut } \def\@@appendixproof[#1][#2]% {% \axp@markchapterhasappendix \axp@writesection \ifbool{axp@synctex}{% \axp@region@record \def\axp@region@flag{0}% }{% \immediate\write\axp@proofsfile{% \noexpand\makeatletter\noexpand\begin{#1}[\unexpanded{#2}]\noexpand\makeatother% }% }% \axp@VerbatimOut } \def\axp@appendixproof@write#1{% \ifbool{axp@synctex}{% \axp@region@write {\noexpand\axp@region@proof{#1}{\axp@region@flag}}% {\noexpand\end{#1}}% }{% \immediate\write\axp@proofsfile{% \noexpand\end{#1}% }% }% } \def\endappendixproof {% \endaxp@VerbatimOut \axp@appendixproof@write{axp@oldproof}% \noproofinappendix } % \end{macrocode} % \end{environment} % \begin{environment}{proof} % This environment either puts the proof in appendix, if we are after a repeated % theorem without its proof, or inlines it otherwise. We support % optional arguments in proofs, but we need to be careful not to gobble % any newline character, that would make it impossible to process the % first line with \textsf{fancyvrb}. % \begin{macrocode} \def\proof{\catcode`\^^M=\active\ltx@ifnextchar@nospace[{\catcode`\^^M=5\axp@@proof}{\catcode`\^^M=5\axp@proof}} \def\axp@proof {% \iftoggle{axp@seenreptheorem}{% \appendixproof }{% \axp@oldproof }% } \def\axp@@proof[#1]% {% \iftoggle{axp@seenreptheorem}{% \appendixproof[#1] }{% \axp@oldproof[#1]% \axp@inlineproofhook{#1}% }% } \def\endproof {% \iftoggle{axp@seenreptheorem}{% \endappendixproof }{% \endaxp@oldproof }% } % \end{macrocode} % \end{environment} % \begin{environment}{claimproof} % \changes{v1.2.4}{2021/11/03}{Support for \texttt{claimproof} environment % from \textsf{lipics}} % \changes{v1.2.5}{2024/01/26}{Support for locally defined \texttt{claimproof} environment} % If the |claimproof| environment exists (\textsf{lipics} document % class or user-defined), we also redefine it, in the same way. % \begin{macrocode} \AtBeginDocument{ \ifdefined\claimproof \let\axp@oldclaimproof\claimproof \let\endaxp@oldclaimproof\endclaimproof \def\claimproof{\catcode`\^^M=\active\ltx@ifnextchar@nospace[{\catcode`\^^M=5\axp@@claimproof}{\catcode`\^^M=5\axp@claimproof}} \def\appendixclaimproof{\catcode`\^^M=\active\@ifnextchar[{\catcode`\^^M=5\@@appendixproof[axp@oldclaimproof]}{\catcode`\^^M=5\expandafter\@appendixproof[axp@oldclaimproof]}} \def\axp@claimproof {% \iftoggle{axp@seenreptheorem}{% \appendixclaimproof }{% \axp@oldclaimproof }% } \def\axp@@claimproof[#1]% {% \iftoggle{axp@seenreptheorem}{% \appendixclaimproof[#1]% }{% \axp@oldclaimproof[#1]% }% } \def\endclaimproof {% \iftoggle{axp@seenreptheorem}{% \endappendixclaimproof }{% \endaxp@oldclaimproof }% } \def\endappendixclaimproof {% \endaxp@VerbatimOut \axp@appendixproof@write{axp@oldclaimproof}% \noproofinappendix } \fi } % \end{macrocode} % \end{environment} % \begin{environment}{inlineproof} % \begin{environment}{nestedproof} % These two environments are synonyms for the original |proof| % environment. % \begin{macrocode} \let\inlineproof\axp@oldproof \let\endinlineproof\endaxp@oldproof \let\nestedproof\axp@oldproof \let\endnestedproof\endaxp@oldproof % \end{macrocode} % \end{environment} % \end{environment} % \subsubsection{Section Management} % \begin{macro}{axp@seccounter} % Sequentially incremented for every section, used to create labels. % \begin{macrocode} \newcounter{axp@seccounter} % \end{macrocode} % \end{macro} % \begin{macro}{\axp@sectitle} % Saves the title of the last encountered section. % \begin{macrocode} \def\axp@sectitle{} % \end{macrocode} % \end{macro} % \begin{macro}{\axp@section} % \changes{v1.2.2}{2021/06/23}{Detect a section within an included % file to avoid produced useless sections} % \changes{v1.3.0}{2026/04/09}{Skip blank lines before detecting % a section command} % \changes{v1.3.0}{2026/04/09}{Detect a section within an % \cs{include}'d file} % \begin{macro}{\axp@@sectionskippar} % \begin{macro}{\axp@@sectiontestinput} % \begin{macro}{\axp@@sectiontestinclude} % \begin{macro}{\axp@@sectionfinishinclude} % \begin{macro}{\axp@@sectiontestsection} % This command |\axp@section| behaves similarly to |\axp@oldsection|, % except that it first tests whether a |\section| follows, and if so, % does not produce anything. This is useful to avoid producing empty % sections in the appendix. Using the \textsf{catchfile} package, we % also check whether a |\section| is within an |\input| or |\include| % that immediately follows. We also skip any |\par| tokens (produced by % blank lines) before performing the check. % \begin{macrocode} \def\axp@section#1{% \@ifnextchar\par {\axp@@sectionskippar{#1}}% {\@ifnextchar\input {\axp@@sectiontestinput{#1}}% {\@ifnextchar\include {\axp@@sectiontestinclude{#1}}% {\axp@@sectiontestsection{#1}}}}% } \def\axp@@sectionskippar#1\par{\axp@section{#1}} \def\axp@@sectiontestinput#1\input#2{% \CatchFileDef{\axp@tmp}{#2}{}% \def\axp@tmptmp{\axp@@sectiontestsection{#1}}% \expandafter\axp@tmptmp\axp@tmp% } \def\axp@@sectiontestinclude#1\include#2{% \set@curr@file{#2}% \edef\axp@tmp{\@strip@tex@ext\@curr@file.tex}% \expandafter\CatchFileDef\expandafter\axp@tmp\expandafter{\axp@tmp}{}% \def\axp@tmptmp{\axp@@sectionfinishinclude{#1}{#2}}% \expandafter\axp@tmptmp\axp@tmp\@nil } \long\def\axp@@sectionfinishinclude#1#2#3#4\@nil{% \ifx#3\section \makeatother \else \axp@oldsection{#1}\makeatother \fi \include{#2}% } \def\axp@@sectiontestsection#1{\@ifnextchar\section{\makeatother}{\axp@oldsection{#1}\makeatother}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\axp@oldsection} % \begin{macro}{\section} % \changes{v1.1.0}{2018/07/25}{Rewrote definition of \cs{section} % to enable optional argument. See \#23. (K. D. Bauer)} % \changes{v1.1.0}{2018/07/25}{Fix handling of fragile macros within % section headings. See \#22.} % \begin{macro}{\@section} % \begin{macro}{\@@section} % We redefine the |\section| command to create a label based on % |axp@seccounter| and to store its title in |\axp@sectitle|. % In order to support starred and unstarred versions, as well % as the optional short-title argument, the intermediate macros % \cs{@section} and \cs{@@section} are needed. % \begin{macrocode} \let\axp@oldsection\section \def\section{\@ifstar\@section\@@section} \newcommand{\@section}[2][\relax]{\axp@@@section{*}{#1}{#2}}% \newcommand{\@@section}[2][\relax]{\axp@@@section{}{#1}{#2}}% \newcommand{\axp@@@section}[3]{% \global\def\axp@sectitle{#3}% \ifx\relax#2\relax \axp@oldsection#1{#3}% \else \axp@oldsection#1[{#2}]{#3}% \fi \addtocounter{axp@seccounter}{1}% \label{axp@s\roman{axp@seccounter}}% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\nosectionappendix} % We remove the current section title, to indicate no section should be % created in the appendix. % \begin{macrocode} \newcommand{\nosectionappendix}{ \global\def\axp@sectitle{}% } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@writesection} % If |\axp@sectitle| is not empty, we create % a new section in the appendix, referring to the main text section. % % Here, we wrap |\ref{axp@si}| into |\axp@protectref@i|, in order % to protect the label name from wrongly being converted to uppercase, % e.g., in \textsf{fancyhdr} with |\pagestyle{fancy}|. % % This macro is defined both in the |.aux| file (in order to ensure availability % when typesetting the |\tableofcontents|), and immediately before typesetting % the appendix section (to ensure availability in the |\section| command). % % \changes{v1.0.6}{2018/05/10}{Fix extraneous space after section number % in appendix titles} % \changes{v1.1.0}{2018/07/09}{Make \cs{axp@tmp} wrapper more robust. % Resolves issues from use of section title in \textsf{fancyhdr}, % and in \cs{tableofcontents} (K. D. Bauer).} % % The command written is normally |\axp@section|; the |toappendix| % environment substitutes |\axp@region@section| for it with the |synctex| % option, so that the heading is decided when the material is replayed % (Section~\ref{sec:synctex-impl}). % \begin{macrocode} \def\axp@sectioncmd{\axp@section} \newcommand\axp@writesection{% \ifx\axp@sectitle\@empty \else \edef\axp@tmp{% \noexpand\global\noexpand\def \expandonce{\csname axp@protectref@\roman{axp@seccounter}\endcsname}{% \noexpand\ref{axp@s\roman{axp@seccounter}}% }% }% \immediate\write\@auxout{\expandonce\axp@tmp} \immediate\write\axp@proofsfile{% \expandonce\axp@tmp^^J% \expandafter\noexpand\axp@sectioncmd{% \noexpand\appendixsectionformat{% \protect \expandonce{\csname axp@protectref@\roman{axp@seccounter}\endcsname}% }{\expandonce\axp@sectitle}% }% }% \nosectionappendix \fi } % \end{macrocode} % \end{macro} % Finally, in a somewhat ad hoc manner, we disable the whole section management % for \cs{tableofcontents}, which may be typeset using a section heading, % but for which automatic section management does not make sense. % % \begin{macro}{\axp@oldtableofcontents} % \begin{macro}{\tableofcontents} % \changes{v1.1.0}{2018/07/09}{Disable section management for table % of contents} % \begin{macrocode} \let\axp@oldtableofcontents\tableofcontents \def\tableofcontents{{\let\section\axp@oldsection\axp@oldtableofcontents}} % \end{macrocode} % \end{macro} % \end{macro} % \subsubsection{Append Compilation Mode} % \begin{macrocode} \ifthenelse{\equal{\axp@appendix}{append}}{ % \end{macrocode} % \begin{macro}{\axp@oldbibliography} % \begin{macro}{\bibliography} % In |bibengine=bibtex| mode, when the |bibliography| option is set to % |separate|, we need to set the appendix bibliography source to be % the same as that of the main text, thanks to \textsf{bibunits}'s % |\defaultbibliography| macro. In |bibengine=biblatex| mode, no such % rebinding is needed: \textsf{biblatex} resources declared with % |\addbibresource| are visible to all |refsection|s globally. % \changes{v1.4.0}{2026/05/14}{Only rebind for bibunits engine. % See \#29.} % \begin{macrocode} \ifthenelse{\equal{\axp@bibliography}{separate} \AND\equal{\axp@bibengine}{bibtex}}{ \let\axp@oldbibliography\bibliography \renewcommand\bibliography[1]{% \defaultbibliography{#1}% \axp@oldbibliography{#1}% } }{} % \end{macrocode} % \end{macro} % \end{macro} % After the end of the main text, we add the appendix (after the command % |\appendixprelim| is issued) % within a |bibunit| environment so as to typeset % a separate bibliography for the appendix (unless the |bibliography| % option is set to |common|). This is done using |\pretocmd| on % |\@enddocumenthook| instead of |\AtEndDocument| because we want the % code to be run before any code in the |\@enddocumenthook| that has % been set in the document class, as in the \textsf{amsart} document % class. % \changes{v1.2.2}{2021/03/23}{Compatibility with AMS document classes: do not % use \texttt{\textbackslash AtEndDocument}} % There is an extra test to % ensure an empty bibliography environment is not produced. % The name of the bibliography is changed to |\appendixrefname|; in most % document classes, it is called |\refname| but it is occasionally % (|scrartcl|, |scrreprt|) called |\bibname|. An ad-hoc test is added % to fix a conflict with the \textsf{natbib} package which redefines % |bibcite| at the end of the document. % \changes{v1.0.6}{2018/05/10}{Deal with document classes where the % bibliography is called \texttt{\textbackslash bibname}} % \changes{v1.2.1}{2020/02/27}{Ad hoc fix for \textsf{natbib} % package conflict} % \changes{v1.2.3}{2021/08/03}{More robust redefinition of % \texttt{thebibliography} environment, for compatibility with % \textsf{tocbibind}} % \begin{macrocode} \pretocmd{\@enddocumenthook}{% \ifdefined\NAT@testdef \renewcommand\bibcite[2]{% \global\@namedef{b@#1\@extra@binfo}{#2}% } \fi \appendixprelim \appendix \ifthenelse{\equal{\axp@bibliography}{separate}}{ \ifthenelse{\equal{\axp@bibengine}{bibtex}}{ \begin{bibunit}[\appendixbibliographystyle] }{ \begin{refsection} } }{} \immediate\closeout\axp@proofsfile \input{\jobname.axp} \ifthenelse{\equal{\axp@bibliography}{separate}}{ \ifthenelse{\equal{\axp@bibengine}{bibtex}}{ \ifdefined\refname \renewcommand{\refname}{\appendixrefname} \else\ifdefined\bibname \renewcommand{\bibname}{\appendixrefname} \fi\fi \let\axp@oldthebibliography\thebibliography \let\endaxp@oldthebibliography\endthebibliography \renewenvironment{thebibliography}[1]{% \def\axp@tmp{#1}% \ifx\axp@tmp\empty \gdef\axp@noappendixbibliography1\relax \else \begin{axp@oldthebibliography}{#1}% \fi }{% \ifdefined\axp@noappendixbibliography\relax\else\end{axp@oldthebibliography}% \fi} \appendixbibliographyprelim \putbib \end{bibunit} }{ \appendixbibliographyprelim \printbibliography[title=\appendixrefname] \end{refsection} } \ifdefined\NAT@testdef \let\bibcite\NAT@testdef \fi }{} }{}{} % \end{macrocode} % \begin{macrocode} }{} % \end{macrocode} % \subsubsection{Chapter End Compilation Mode} % \changes{v1.3.0}{2026/04/14}{Added \texttt{chapterend} appendix mode} % \changes{v1.4.0}{2026/04/29}{Flush \texttt{chapterend} appendices at % \cs{part}, \cs{frontmatter}, \cs{mainmatter}, and \cs{backmatter} % boundaries so the last chapter of a part/matter is not emitted under % the next one} % \changes{v1.4.0}{2026/04/29}{Public \cs{flushchapterappendix} macro % for manually emitting the current chapter's accumulated appendix in % \texttt{chapterend} mode} % In |chapterend| mode, appendix material for each chapter is gathered % in a per-chapter auxiliary file and emitted immediately after that % chapter's content (and bibliography). This requires the % \textsf{appendix} package for its |subappendices| environment. % \begin{macrocode} \ifthenelse{\equal{\axp@appendix}{chapterend}}{ % \end{macrocode} % \begin{macrocode} \RequirePackage{appendix} % \end{macrocode} % \begin{macro}{\chapterappendixprelim} % \begin{macro}{\axp@beginchapterappendix} % \begin{macro}{\axp@endchapterappendix} % User-customizable hooks surrounding each chapter's appendix block. % By default they open and close a |subappendices| environment. % \begin{macrocode} \newcommand{\chapterappendixprelim}{\clearpage} \newcommand{\axp@beginchapterappendix}{% \chapterappendixprelim \begin{subappendices}% } \newcommand{\axp@endchapterappendix}{% \end{subappendices}% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{axp@chaptercounter} % \begin{macro}{axp@chapterhasappendix} % \begin{macro}{\axp@currentaxpfile} % Counter for unique per-chapter file names, a boolean tracking whether % the current chapter has any appendix content, and the current file name. % \begin{macrocode} \newcounter{axp@chaptercounter} \newbool{axp@chapterhasappendix} \def\axp@currentaxpfile{} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\axp@markchapterhasappendix} % Override the no-op to set the boolean when content is written. % \begin{macrocode} \renewcommand{\axp@markchapterhasappendix}{% \global\booltrue{axp@chapterhasappendix}% } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@openchapterfile} % Open a fresh auxiliary file for the current chapter. % We write |\begingroup| first so that all the preamble |\let| % assignments (and any catcode changes from |\makeatletter|) are % scoped to this chapter's appendix and do not leak into the rest of % the document when the file is |\input|'d. We also reset the % section-title tracker and the repeated-theorem toggle so that state % from the previous chapter cannot bleed into the new file. % \begin{macrocode} \newcommand{\axp@openchapterfile}{% \edef\axp@currentaxpfile{\jobname-\arabic{axp@chaptercounter}.axp}% \immediate\openout\axp@proofsfile=\axp@currentaxpfile \immediate\write\axp@proofsfile{\noexpand\begingroup}% \axp@writeproofsfilepreamble \global\boolfalse{axp@chapterhasappendix}% \global\def\axp@sectitle{}% \global\togglefalse{axp@seenreptheorem}% } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@flushchapterappendix} % Close the current chapter's auxiliary file (appending |\endgroup| % to close the group opened in |\axp@openchapterfile|) and, if it % contains any content, emit it inside a |subappendices| block. % \begin{macrocode} \newcommand{\axp@flushchapterappendix}{% \immediate\write\axp@proofsfile{\noexpand\endgroup}% \immediate\closeout\axp@proofsfile \ifbool{axp@chapterhasappendix}{% \axp@beginchapterappendix \input{\axp@currentaxpfile}% \axp@endchapterappendix }{}% } % \end{macrocode} % \end{macro} % \begin{macro}{\axp@chapterboundary} % \begin{macro}{\flushchapterappendix} % |\axp@chapterboundary| flushes the previous chapter's auxiliary file, % increments the counter, and opens the next one. It is used as a hook % for |\chapter|, |\part|, and the |book|-class matter-switching % commands |\frontmatter|, |\mainmatter|, |\backmatter|, so that % per-chapter appendices are emitted before any of these structural % transitions (otherwise the appendix of the last chapter of a % part/matter would end up under the next part/matter). % |\flushchapterappendix| is a public alias for the same operation, % which can be invoked manually wherever an appendix flush boundary is % needed (e.g., before a bibliography that does not produce its own % chapter heading). % \begin{macrocode} \newcommand{\axp@chapterboundary}{% \axp@flushchapterappendix \stepcounter{axp@chaptercounter}% \axp@openchapterfile } \let\flushchapterappendix\axp@chapterboundary % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\axp@hookboundary} % Helper to install |\axp@chapterboundary| as a |\pretocmd| hook on a % structural command (|\chapter|, |\part|, |\frontmatter|, etc.), % issuing a package warning if the hook fails. % \begin{macrocode} \newcommand{\axp@hookboundary}[1]{% \pretocmd{#1}{\axp@chapterboundary}{}{% \PackageWarning{apxproof}{% Could not hook into \string#1;^^J% chapter appendices may not be emitted correctly}}% } % \end{macrocode} % \end{macro} % At the start of each |\chapter|, |\part|, or matter-switching % command, run the boundary hook. At |\end{document}|, flush the % last chapter's file. % \begin{macrocode} \AtBeginDocument{% \ifdef{\chapter}{% \axp@hookboundary{\chapter}% }{% \PackageWarning{apxproof}{% appendix=chapterend used but \string\chapter\space is not defined}% }% \ifdef{\part}{\axp@hookboundary{\part}}{}% \ifdef{\frontmatter}{\axp@hookboundary{\frontmatter}}{}% \ifdef{\mainmatter}{\axp@hookboundary{\mainmatter}}{}% \ifdef{\backmatter}{\axp@hookboundary{\backmatter}}{}% } \pretocmd{\@enddocumenthook}{% \axp@flushchapterappendix }{}{} % \end{macrocode} % \begin{macrocode} }{} % \end{macrocode} % \subsubsection{Class-Specific Behavior} % We conclude with some class-specific behavior. % \paragraph{ACM Document Classes (old versions, till 2017)} % \changes{v1.0.4}{2017/03/08}{More faithful theorem style for ACM templates} % \changes{v1.0.4}{2017/03/08}{More robust coherent styling of proof sketches} % \begin{macrocode} \ifdefined\@acmtitlebox % \end{macrocode} % We first redefine the |proofsketch| environment, which is used % differently in the base class. % \begin{macrocode} \renewenvironment{proofsketch}{\begin{axp@oldproof}[sketch]}{\end{axp@oldproof}} % \end{macrocode} % We adjust the styling of theorems for the needs of \textsf{apxproof}. % \begin{macrocode} \newtheoremstyle{mystyle} {6pt} {6pt} {\itshape} {10pt} {\scshape} {.} {.5em} {} \theoremstyle{mystyle} % \end{macrocode} % \begin{macro}{\thebibliography} % \begin{macro}{\refname} % \begin{macro}{\appendixrefname} % The section title of the bibliography is in uppercase in these document % classes. In addition, the |\thebibliography| macro hard-codes twice % the section title, so we un-hardcode it so that it can be modified % in the appendix. % \begin{macrocode} \patchcmd{\thebibliography}{References}{\protect\refname}{}{} \patchcmd{\thebibliography}{References}{\protect\refname}{}{} \newcommand{\refname}{REFERENCES} \renewcommand{\appendixrefname}{REFERENCES FOR THE APPENDIX} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macrocode} \fi % \end{macrocode} % \changes{v1.0.6}{2018/05/10}{Support of new ACM document class % (\texttt{acmart.cls})} % \paragraph{\textsf{lipcs}} % \begin{macrocode} \ifdefined\lipics@opterrshort % \end{macrocode} % \begin{macro}{\appendixbibliographyprelim} % \changes{v1.0.3}{2017/02/06}{Support for lipics-v2016} % The default bibliography in the \textsf{lipics} document class % formatting is not compatible with the % \textsf{alpha} bibliography style. We fix this here. % \begin{macrocode} \renewcommand{\appendixbibliographyprelim}{% \global\let\@oldbiblabel\@biblabel \def\@biblabel{\hspace*{-2em}\small\@oldbiblabel}% } % \end{macrocode} % \end{macro} % \begin{macrocode} \fi } % \end{macrocode} % \Finale % \bibliographystyle{plain} % \bibliography{apxproof}