% \iffalse meta-comment % % Copyright (c) 2024- Jesse Straat % % 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 % https://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of LaTeX % version 2008 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Jesse Sraat. % % This work consists of the main file reptheorem.dtx % and the derived files % reptheorem.sty, reptheorem.pdf, reptheorem.ins % % Unpacking: % (a) If reptheorem.ins is present: % latex reptheorem.ins % (b) If reptheorem.ins is absent: % latex reptheorem.dtx % % Documentation: % pdflatex reptheorem.dtx % makeindex -s gind.ist -o reptheorem.ind reptheorem.idx % makeindex -s gglo.ist -o reptheorem.gls reptheorem.glo % pdflatex reptheorem.dtx % dtx file based on https://www.texdev.net/2009/10/06/a-model-dtx-file/ % %<*ignore> \iffalse % % %<*readme> # `reptheorem` When writing a large manuscript, it is sometimes beneficial to repeat a theorem (or lemma or…) at an earlier or later point for didactical purposes. However, `thmtools`'s built-in `restatable` only allows replicating theorems *after* they have been stated, and only in the same document. `reptheorem` solves the issue by making use of the `.aux` file, and also introduces its own file extension, `.thm`, to replicate theorems in other files. # Installation Run the following in the command line: 1. If reptheorem.ins is present: `latex reptheorem.ins` 2. If reptheorem.ins is absent: `latex reptheorem.dtx` Move `reptheorem.sty` to a folder that TeX can find. # Documentation Run the following in the command line: ``` pdflatex reptheorem.dtx makeindex -s gind.ist -o reptheorem.ind reptheorem.idx makeindex -s gglo.ist -o reptheorem.gls reptheorem.glo pdflatex reptheorem.dtx ``` This automatically unpacks the package, as well. --- © 2024- Jesse Straat License: [LPPL1.3c](https://www.latex-project.org/lppl.txt) [GitHub Repository](https://github.com/JesseStraat/reptheorem) % % %<*ignore> \fi \def\plainTeXstring{plain} \ifx\fmtname\plainTeXstring\else \expandafter\begingroup \fi % % %<*install> \input docstrip.tex \Msg{************************************************************************} \Msg{* Installation} \Msg{* Package: reptheorem 2024-03-27 v1.0} \Msg{************************************************************************} \keepsilent \askforoverwritefalse \preamble Copyright (c) 2024- Jesse Straat 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 https://www.latex-project.org/lppl.txt and version 1.3c or later is part of all distributions of LaTeX version 2008 or later. This work has the LPPL maintenance status `maintained'. The Current Maintainer of this work is Jesse Sraat. This work consists of the main file reptheorem.dtx and the derived files reptheorem.sty, reptheorem.pdf, reptheorem.ins \endpreamble \usedir{tex/latex/reptheorem} \generate{ \file{\jobname.sty}{\from{\jobname.dtx}{package}} } \obeyspaces \Msg{************************************************************************} \Msg{*} \Msg{* To finish the installation you have to move the following} \Msg{* file into a directory searched by TeX:} \Msg{*} \Msg{* repthm.sty} \Msg{*} \Msg{* To produce the documentation run the file `reptheorem.dtx'} \Msg{* through LaTeX.} \Msg{*} \Msg{* Happy TeXing!} \Msg{*} \Msg{************************************************************************} % %\endbatchfile % %<*ignore> \usedir{source/latex/reptheorem} \generate{ \file{\jobname.ins}{\from{\jobname.dtx}{install}} } \nopreamble\nopostamble \usedir{doc/latex/reptheorem} \generate{ \file{README.md}{\from{\jobname.dtx}{readme}} } \ifx\fmtname\plainTeXstring \expandafter\endbatchfile \else \expandafter\endgroup \fi % %<*driver> \NeedsTeXFormat{LaTeX2e} \documentclass{ltxdoc} \usepackage{\jobname} \usepackage{amsthm} \newtheorem{theorem}{Theorem} \usepackage[final, hyperindex=false, colorlinks, ]{hyperref} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \GetFileInfo{\jobname.sty} % % \DoNotIndex{\begin,\end,\begingroup,\endgroup,\csname,\endcsname,\ifcsname,\if,\else,\IfFileExists,\IfValueTF,\fi} % \DoNotIndex{\def,\edef,\expandafter,\gdef} % \DoNotIndex{\immediate,\input} % \DoNotIndex{\jobname,\label,\let,\long,\newcounter,\NewDocumentCommand} % \DoNotIndex{\NewDocumentEnvironment,\noexpand} % \DoNotIndex{\ProvidesPackage,\ref,\relax,\setcounter} % \DoNotIndex{\string,\value,\write} % % \title{^^A % \textsf{reptheorem}\thanks{^^A % Version \fileversion, last revised \filedate.^^A % }^^A % }^^A % \author{^^A % Jesse Straat^^A % } % \date{\filedate} % % \maketitle % % \begin{abstract} % \noindent When writing a large manuscript, it is sometimes % beneficial to repeat a theorem (or lemma or \dots) at % an earlier or later point for didactical purposes. % However, \textsf{thmtools}'s built-in |restatable| % only allows replicating theorems \textit{after} they % have been stated, and only in the same document. % \textsf{reptheorem} solves the issue by making use % of the |.aux| file, and also introduces its own file % extension, |.thm|, to replicate theorems in other files. % \end{abstract} % % \tableofcontents % %\changes{v1.0}{2024-03-27}{First public release} % % % %\StopEventually{^^A % \PrintChanges % \PrintIndex %} % % % % % \section{Repeating theorems} % Let's say we define a theorem as follows: % \begin{verbatim} % \begin{theorem}[Yoneda Lemma] % For \(F\colon \mathcal{C}\to \mathbf{Set}\) a functor, % \([\mathcal{C}^\mathrm{op},\mathbf{Set}](YA, F) \cong F(A)\)% % for all objects \(A\) in \(\mathcal{C}\). % \end{theorem} % \end{verbatim} % Its output is of course % \begin{makethm}{theorem}{thm:Yoneda}[Yoneda Lemma] % For \(F\colon \mathcal{C}\to \mathbf{Set}\) a functor, % \([\mathcal{C}^\mathrm{op},\mathbf{Set}](YA, F) \cong F(A)\) % for all objects \(A\) in \(\mathcal{C}\). % \end{makethm} % Now let's say we want to replicate the theorem % within the same document. That is what the new % environment \DescribeEnv{makethm} |makethm| is % used for. % \begin{verbatim} % \begin{makethm}{theorem}{thm:Yoneda}[Yoneda Lemma]{ % For \(F\colon \mathcal{C}\to \mathbf{Set}\) a functor, % \([\mathcal{C}^\mathrm{op},\mathbf{Set}](YA, F) \cong F(A)\)% % for all objects \(A\) in \(\mathcal{C}\). % \end{makethm} % \end{verbatim} % Its output is the same (in fact, we've secretly used % |makethm| in the previous example), but the important % difference is that we have saved the theorem for later use.\par % The |makethm| environment takes two mandatory arguments % and one optional one. The first mandatory argument is the % type of theorem environment, like |theorem|, |lemma|, % |definition|, etc. The second is the theorem's label. % The label is mandatory because to replicate the theorem, % we need to have a ``name'' attached to it. |makethm| % automatically attaches a |\label|, as well, so |\ref{thm:Yoneda}| % becomes \ref{thm:Yoneda}. The optional argument is passed % right to the optional argument of the theorem environment, % giving the name of a theorem\par % % Now let's say we want to replicate the theorem later % or earlier in the text. This may be done if, for example, % the theorem is proven at a later point, or we want to % ``tease'' the reader with a powerful theorem that will be % proven later in the chapter. To do this, we use the % \DescribeMacro{repthm} command, as follows. % \begin{verbatim} % \repthm{theorem}{thm:Yoneda} % \end{verbatim} % This outputs the theorem again. % \repthm{theorem}{thm:Yoneda} % The label of this theorem is a |\ref|, and automatically % links to the original theorem statement.\par % If the original theorem statement exists in a different % file, or has not been created yet, we can add a placeholder % alt text to the |\repthm| as an optional argument, which % only displays if the theorem is undefined. For example, % |\repthm{theorem}{thm:foo}[bar]| returns % \repthm{theorem}{thm:foo}[bar] % If we do the same without providing an alt text, we get % \repthm{theorem}{thm:foo} % together with a warning.\par % Since we're using the |.aux| file, it is possible % to replicate a theorem before it is stated. For example, % \begin{verbatim} % \repthm{theorem}{thm:later} % \begin{makethm}{theorem}{thm:later}[Later] % Alligator! % \end{makethm} % \end{verbatim} % returns % \repthm{theorem}{thm:later} % \begin{makethm}{theorem}{thm:later}[Later] % Alligator % \end{makethm} % Note that it is necessary to run a |.tex| file twice % to replicate theorems ahead of time, similarly to % how one has to run a file twice to make sure the % references are correct.\par % % \section{Replicating theorems between files} % Let's say we have the following files for our project: % \begin{verbatim} % foo.tex % bar.tex % \end{verbatim} % Let's say that we have defined a theorem |thm:baz| % in |bar.tex|, and we want to replicate it in |foo.tex|. % To achieve this, we first use the \DescribeMacro{\theoremfile} % |\theoremfile| command in the preamble of |bar.tex|. This % compiles all theorems defined in |bar.tex| and outputs them % into a file |bar.thm|. To then import these into |foo.tex|, we % use \DescribeMacro{\loadtheorems} |\loadtheorems{bar.thm}| in % the preamble, which loads all theorems saved in |bar.thm|. % One can then use |\repthm| as usual.\par % Since the |.aux| file is loaded at |\begin{document}|, putting % |\loadtheorems| in the preamble of a file will guarantee that % the loaded theorem file will be overwritten by the theorems in % the |.aux| file, i.e., theorems defined in the same document. % In our example, if we also defined a |thm:baz| in |foo.tex|, % loading |bar.thm| into |foo.tex| will not overwrite the local % |thm:baz|. % % \subsection{Replicating theorems to subfiles} % Replicating theorems to different files is particularly % useful when working in big documents with multiple subfiles. % For example, let's say we have the files % \begin{verbatim} % main.tex % foo.tex % bar.tex % \end{verbatim} % Here, |main.tex| is generated by including |foo.tex| % and |bar.tex| as chapters, creating a single large document. % It is now possible to replicate theorems within the % subfiles by running |\theoremfile| in |main.tex|, % and then using |\loadtheorems{main.thm}| in % |foo.tex| and |bar.tex|. This will allow us to % use all theorems in the final |main.tex| in each of % the subfiles. % % % % \section{Source code} % \begin{macrocode} %<*package> \ProvidesPackage{reptheorem}[2024-03-27 v1.0 Reptheorem package] % \end{macrocode} % % \begin{macro}{\theoremfile} % Using |\theoremfile| will output all saved theorems into an output file. % By default, if your \LaTeX file is |foo.tex|, the output file is |foo.thm|. % \begin{macrocode} \def\reptheorem@theoremfile{\relax} \NewDocumentCommand{\theoremfile}{ O{\jobname.thm} }{ % O: the path of the file to which we should save theorems % \def\reptheorem@theoremfile{#1} \newwrite\@thmlist \immediate\openout\@thmlist=#1 } % \end{macrocode} % \end{macro} % % \begin{macro}{\loadtheorems} % If you have exported saved theorems to a file, you can load them % into another file using the macro |\loadtheorems|. % \begin{macrocode} \NewDocumentCommand{\loadtheorems}{ m }{ \IfFileExists{#1}{ \input{#1} }{ \PackageWarning{reptheorem}{% File #1 not found. I will not import any theorems.% } } } % \end{macrocode} % \end{macro} % % \begin{environment}{makethm} % On to defining the actual theorems to be saved. % \begin{macrocode} \NewDocumentEnvironment{makethm}{ m m o +b } % m: the type of theorem environment % m: the name of the theorem % o: optional parameter for environment % b: the content of the theorem % {% \IfValueTF{#3}{% Check if theorem has optional arguments \begin{#1}[#3]\label{#2} }{ \begin{#1}\label{#2} } #4 \end{#1} \expandafter\long\expandafter\gdef\csname thm@#2\endcsname{#4}% \expandafter\gdef\csname thmdesc@#2\endcsname{#3}% % Saving parameters to aux file \long\gdef\@thmoutput{% \string\expandafter\string\long\string\expandafter% \string\gdef\noexpand\csname thm@#2\string\endcsname{#4}% ^^J% \string\expandafter\string\expandafter% \string\gdef\noexpand\csname thmdesc@#2\string\endcsname{#3}% } \write\@auxout{\@thmoutput} \if\reptheorem@theoremfile\relax % No file has been set \else % We have a theorem file % Saving parameters to theorem file \write\@thmlist{\@thmoutput} \fi }{} % \end{macrocode} % \end{environment} % % \begin{macro}{\repthm} % To repeat a theorem, use the |\repthm| command. % The type of theorem is not saved, so it is necessary to % respecify it each time a theorem is repeated. % \begin{macrocode} \newcounter{old@counter} \NewDocumentCommand{\repthm}{ m m +o }{ % m: the type of theorem environment % m: the name of the theorem % o: alt text \begingroup \setcounter{old@counter}{\value{#1}} % Save theorem counter so we don't increase it \def\thetheorem{\ref{#2}} \let\@@theoremnotdefined\relax % \ifcsname thm@#2\endcsname% Check if theorem is even defined % Theorem is defined \expandafter\edef\expandafter\@@thmdesc{\csname thmdesc@#2\endcsname}% \expandafter\let\expandafter\@@thm\csname thm@#2\endcsname % Output theorem \IfValueTF{\@@thmdesc}{% Check if theorem has name \begin{#1}[\@@thmdesc] \@@thm \end{#1} }{% No optionals \begin{#1} \@@thm \end{#1} } \else % Theorem undefined \IfValueTF{#3}{ \begin{#1} #3 \end{#1} }{% No theorem or alt text provided: throw warning \begin{#1} \end{#1} \PackageWarning{reptheorem}{% Theorem #2 not defined; rebuild your project. If the issue persists, create the theorem using \begin{makethm} or consider adding alt text to \repthm using the optional parameter% } } \fi \setcounter{#1}{\value{old@counter}} % Reset theorem counter back to original \endgroup } % \end{macrocode} % \end{macro} % \begin{macrocode} % % \end{macrocode} %\Finale