% \iffalse meta-comment % % Copyright (C) 2008-2014 by Ulrich M. Schwarz % Copyright (C) 2019 by Frank Mittelbach % Copyright (C) 2020- by Yukai Chou % % This file may be distributed and/or modified under the conditions of % the LaTeX Project Public License, version 1.3c. % The license can be obtained from % http://www.latex-project.org/lppl/lppl-1.3c.txt % % \fi % %\iffalse (hide this from DocInput) %<*restate> %\fi % %\DescribeEnv{restatable} %Only one environment is provided: \verb|restatable|, which takes one %optional and two mandatory arguments. The first mandatory argument is the %type of the theorem, i.e. if you want |\begin{lemma}| to be called on %the inside, give |lemma|. The second argument is the name of the macro %that the text should be stored in, for example \verb|mylemma|. Be careful %not to specify existing command names! The optional argument will become the %optional argument to your theorem command. Consider the following example: %\begin{verbatim} % \documentclass{article} % \usepackage{amsmath, amsthm, thm-restate} % \newtheorem{lemma}{Lemma} % \begin{document} % \begin{restatable}[Zorn]{lemma}{zornlemma}\label{thm:zorn} % If every chain in $X$ is upper-bounded, % $X$ has a maximal element. % % It's true, you know! % \end{restatable} % \begin{lemma} % This is some other lemma of no import. % \end{lemma} % And now, here's Mr. Zorn again: \zornlemma* % \end{document} %\end{verbatim} %which yields % \begin{restatable}[Zorn]{lemma}{zornlemma}\label{thm:zorn} % If every chain in $X$ is upper-bounded, $X$ has a maximal element. % % It's true, you know! % \end{restatable} % \begin{lemma} % This is some other lemma of no import. % \end{lemma} % Actually, we have set a label in the environment, so we know that % it's Lemma~\ref{thm:zorn} on page~\ref{thm:zorn}. % And now, here's Mr. Zorn again: \zornlemma* % Since we prevent the label from being set again, we find that % it's still Lemma~\ref{thm:zorn} on page~\ref{thm:zorn}, even though % it occurs later also. % % \DescribeEnv{restatable*} % As you can see, we use the starred form |\mylemma*|. As in many cases in % \LaTeX, the star means ``don't give a number'', since we want to retain % the original number. There is also a starred variant of the |restatable| % environment, where the first call doesn't determine the number, but a % later call to |\mylemma| without star would. Since the number is carried % around using \LaTeX' |\label| machanism, you'll need a rerun for things to % settle. % % \subsection{Restrictions} % The only counter that is saved is the one for the theorem number. So, % putting floats inside a restatable is not advised: they will appear in the % LoF several times with new numbers. % Equations should work, but the code handling them might turn out to be % brittle, in particular when you add/remove hyperref. % %In the same vein, numbered equations % %within the statement appear again and are numbered again, with new % %numbers. (This is vaguely non-trivial to do correctly if equations are not % %numbered consecutively, but per-chapter, or there are multiple numbered % %equations.) % Note that you cannot successfully reference the equations % since all labels are disabled in the starred appearance. (The reference % will point at the unstarred occurence.) % % You cannot nest % restatables either. You \emph{can} use the |\restatable|\dots|\endrestatable| % version, but everything up to the next matching |\end{...}| is scooped up. % I've also probably missed many border cases. % % %\StopEventually{} % \begin{macrocode} \RequirePackage{thmtools} \let\@xa\expandafter \let\@nx\noexpand \@ifundefined{c@thmt@dummyctr}{% \newcounter{thmt@dummyctr}% }{} \gdef\theHthmt@dummyctr{dummy.\arabic{thmt@dummyctr}}% \gdef\thethmt@dummyctr{}% \long\def\thmt@collect@body#1#2\end#3{% \@xa\thmt@toks\@xa{\the\thmt@toks #2}% \def\thmttmpa{#3}%\def\thmttmpb{restatable}% \ifx\thmttmpa\@currenvir%thmttmpb \@xa\@firstoftwo% this is the end of the environment. \else \@xa\@secondoftwo% go on collecting \fi{% this is the end, my friend, drop the \end. % and call #1 with the collected body. \@xa#1\@xa{\the\thmt@toks}% }{% go on collecting \@xa\thmt@toks\@xa{\the\thmt@toks\end{#3}}% \thmt@collect@body{#1}% }% } % \end{macrocode} % A totally ignorant version of |\ref|, defaulting to \#2 if label not % known yet. Otherwise, return the formatted number. % \begin{macrocode} \def\thmt@trivialref#1#2{% \ifcsname r@#1\endcsname \@xa\@xa\@xa\thmt@trivi@lr@f\csname r@#1\endcsname\relax\@nil \else #2\fi } \def\thmt@trivi@lr@f#1#2\@nil{#1} % \end{macrocode} % % Counter safeties: some counters' values should be stored, such as % equation, so we don't get a new number. (We cannot reference it anyway.) % We cannot store everything, though, think page counter or section number! % There is one problem here: we have to remove all references to other % counters from |\theequation|, otherwise your equation could get a number % like (3.1) in one place and (4.1) in another section. % % The best solution I can come up with is to override the usual macros % that counter display goes through, to check if their argument is one % that should be fully-expanded away or retained. % % The following should only be called from within a group, and the sanitized % |\thectr| must not be called from within that group, since it needs the % original |\@arabic| et al. % % \begin{macrocode} \def\thmt@innercounters{% equation} \def\thmt@counterformatters{% @alph,@Alph,@arabic,@roman,@Roman,@fnsymbol} \@for\thmt@displ:=\thmt@counterformatters\do{% \@xa\let\csname thmt@\thmt@displ\@xa\endcsname\csname \thmt@displ\endcsname }% \def\thmt@sanitizethe#1{% \@for\thmt@displ:=\thmt@counterformatters\do{% \@xa\protected@edef\csname\thmt@displ\endcsname##1{% \@nx\ifx\@xa\@nx\csname c@#1\endcsname ##1% \@xa\protect\csname \thmt@displ\endcsname{##1}% \@nx\else \@nx\csname thmt@\thmt@displ\endcsname{##1}% \@nx\fi }% }% \expandafter\protected@edef\csname the#1\endcsname{\csname the#1\endcsname}% \ifcsname theH#1\endcsname \expandafter\protected@edef\csname theH#1\endcsname{\csname theH#1\endcsname}% \fi } \def\thmt@rst@storecounters#1{% \bgroup % ugly hack: save chapter,..subsection numbers % for equation numbers. %\refstepcounter{thmt@dummyctr}% why is this here? %% temporarily disabled, broke autorefname. \def\@currentlabel{}% \@for\thmt@ctr:=\thmt@innercounters\do{% \thmt@sanitizethe{\thmt@ctr}% \protected@edef\@currentlabel{% \@currentlabel \protect\def\@xa\protect\csname the\thmt@ctr\endcsname{% \csname the\thmt@ctr\endcsname}% \ifcsname theH\thmt@ctr\endcsname \protect\def\@xa\protect\csname theH\thmt@ctr\endcsname{% (restate \protect\theHthmt@dummyctr)\csname theH\thmt@ctr\endcsname}% \fi \protect\setcounter{\thmt@ctr}{\number\csname c@\thmt@ctr\endcsname}% }% }% \label{thmt@@#1@data}% \egroup }% % \end{macrocode} % % Now, the main business. % % \begin{macrocode} \newif\ifthmt@thisistheone \newenvironment{thmt@restatable}[3][]{% \thmt@toks{}% will hold body % \stepcounter{thmt@dummyctr}% used for data storage label. % \long\def\thmrst@store##1{% \@xa\gdef\csname #3\endcsname{% \@ifstar{% \thmt@thisistheonefalse\csname thmt@stored@#3\endcsname }{% \thmt@thisistheonetrue\csname thmt@stored@#3\endcsname }% }% \@xa\long\@xa\gdef\csname thmt@stored@#3\@xa\endcsname\@xa{% \begingroup \ifthmt@thisistheone % these are the valid numbers, store them for the other % occasions. \thmt@rst@storecounters{#3}% \else % this one should use other numbers... % first, fake the theorem number. \@xa\protected@edef\csname the#2\endcsname{% \thmt@trivialref{thmt@@#3}{??}}% % if the number wasn't there, have a "re-run to get labels right" % warning. \ifcsname r@thmt@@#3\endcsname\else \G@refundefinedtrue \fi % prevent stepcountering the theorem number, % but still, have some number for hyperref, just in case. \@xa\let\csname c@#2\endcsname=\c@thmt@dummyctr \@xa\let\csname theH#2\endcsname=\theHthmt@dummyctr % disable labeling. \let\label=\thmt@gobble@label \let\ltx@label=\@gobble% amsmath needs this % We shall need to restore the counters at the end % of the environment, so we get % (4.2) [(3.1 from restate)] (4.3) \def\thmt@restorecounters{}% \@for\thmt@ctr:=\thmt@innercounters\do{% \protected@edef\thmt@restorecounters{% \thmt@restorecounters \protect\setcounter{\thmt@ctr}{\arabic{\thmt@ctr}}% }% }% % pull the new semi-static definition of \theequation et al. % from the aux file. \thmt@trivialref{thmt@@#3@data}{}% \fi % call the proper begin-env code, possibly with optional argument % (omit if stored via key-val) \ifthmt@restatethis \thmt@restatethisfalse \else \csname #2\@xa\endcsname\ifx\@nx#1\@nx\else[{#1}]\fi \fi \ifthmt@thisistheone % store a label so we can pick up the number later. \label{thmt@@#3}% \fi % this will be the collected body. ##1% \csname end#2\endcsname % if we faked the counter values, restore originals now. \ifthmt@thisistheone\else\thmt@restorecounters\fi \endgroup }% thmt@stored@#3 % in either case, now call the just-created macro, \csname #3\@xa\endcsname\ifthmt@thisistheone\else*\fi % and artificially close the current environment. \@xa\end\@xa{\@currenvir} }% thm@rst@store \thmt@collect@body\thmrst@store }{% %% now empty, just used as a marker. } \let\thmt@gobble@label\@gobble % cleveref extends syntax of \label to \label[...]{...} \AtBeginDocument{ \@ifpackageloaded{cleveref}{ \renewcommand*\thmt@gobble@label[2][]{} }{} } \newenvironment{restatable}{% \thmt@thisistheonetrue\thmt@restatable }{% \endthmt@restatable } \newenvironment{restatable*}{% \thmt@thisistheonefalse\thmt@restatable }{% \endthmt@restatable } %%% support for keyval-style: restate=foobar \protected@edef\thmt@thmuse@families{% \thmt@thmuse@families% ,restate phase 1% ,restate phase 2% } \newcommand\thmt@splitrestateargs[1][]{% \g@addto@macro\thmt@storedoptargs{,#1}% \def\tmp@a##1\@{\def\thmt@storename{##1}}% \tmp@a } \newif\ifthmt@restatethis \define@key{restate phase 1}{restate}{% \thmt@thmuse@iskvtrue \def\thmt@storedoptargs{}% discard the first time around \thmt@splitrestateargs #1\@ \def\thmt@storedoptargs{}% discard the first time around %\def\thmt@storename{#1}% \thmt@debug{we will restate as `\thmt@storename' with more args `\thmt@storedoptargs'}% \@namedef{thmt@unusedkey@restate}{}% % spurious "unused key" fixes itself once we are after tracknames... \thmt@restatethistrue \protected@edef\tmp@a{% \@nx\thmt@thisistheonetrue \@nx\def\@nx\@currenvir{\thmt@envname}% \@nx\@xa\@nx\thmt@restatable\@nx\@xa[\@nx\thmt@storedoptargs]% {\thmt@envname}{\thmt@storename}% }% \@xa\g@addto@macro\@xa\thmt@local@postheadhook\@xa{% \tmp@a }% } \thmt@mkignoringkeyhandler{restate phase 1} \define@key{restate phase 2}{restate}{% % do not store restate as a key for repetition: % infinite loop. % instead, retain the added keyvals % overwriting thmt@storename should be safe here, it's been % xdefd into the postheadhook \thmt@splitrestateargs #1\@ } \kv@set@family@handler{restate phase 2}{% \ifthmt@restatethis \@xa\@xa\@xa\g@addto@macro\@xa\@xa\@xa\thmt@storedoptargs\@xa\@xa\@xa{\@xa\@xa\@xa,% \@xa\kv@key\@xa=\kv@value}% \fi } % \end{macrocode} %\iffalse % %\fi