15

I'm learning how to use the thmtools package, and I came across a strange quirk. A minimal example is as follows:

\documentclass{article}

\usepackage{amsthm}
\usepackage{thmtools}

\declaretheorem{theorem}

\begin{document}

\begin{restatable*}{theorem}{mythm}
This is a restated theorem.
\end{restatable*}


\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}

\mythm
\mythm
\mythm

\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}

\mythm*
\mythm*
\mythm*

\end{document}

When I compile this, there is extra space above the restated, renumbered theorem (the \mythm commands). There is not extra space below these theorems (as you can see between Theorems 5 and 6). The \mythm* commands do not create any extra space.

Realistically, the restatable* environment would be used to state a result at the beginning of a paper. There would only be one accompanying \mythm command (and possible any number of \mythm* commands). So this extra space would only be an issue once. Still, I'd like to know what's going on here.

enter image description here

1
  • 1
    Is there any simpler solution that came up? As far as I know, this issue still exists.
    – Clément
    Feb 6, 2019 at 18:22

3 Answers 3

4

I added one line to the definition of the \thmt@rst@storecounters macro: a hardwired \vspace. It might not be pretty, but it gets the job done. (EDITED to make the fix to a smaller routine, so as to take up less space. The ORIGINAL post had the same fix applied to the much longer thmt@restatable environment.)

\documentclass{article}

\usepackage{amsthm}
\usepackage{thmtools}

\makeatletter

\def\thmt@rst@storecounters#1{%
%THIS IS THE LINE I ADDED:
\vspace{-1.9ex}%
  \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
}%

\makeatother

\declaretheorem{theorem}

\begin{document}

\begin{restatable*}{theorem}{mythm}
This is a restated theorem.
\end{restatable*}

\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}

\mythm
\mythm
\mythm

\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}

\mythm*
\mythm*
\mythm*

\end{document}

enter image description here

3
  • Sorry for the slow reply. I upvoted this response, since it does fix the issue. Thanks! I'm going to hold off accepting the answer for a bit, in the hopes that somebody can explain what's putting the extra space in there in the first place.
    – user18452
    May 10, 2013 at 18:19
  • Is there any simpler solution that came up? As far as I know, this issue still exists. Thanks!
    – Clément
    Feb 11, 2019 at 15:18
  • 1
    @Clément I haven't followed up (in the last 5+ years, LOL) to know if there is a better fix. Sorry. Feb 11, 2019 at 15:37
5

The problem with your solution is that restatable only introduces extra space when it is preceded by another environment. In the other cases, spacing is correct, and the \vspace should be avoided.

By doing several experiments, it seems the culprit is the \label{thmt@@#1@data} in \thmt@rst@storecounters. By removing the \label command, spacing is correct, but something else probably will go wrong. My solution, which I am testing in these days, is to move the call to \thmt@rst@storecounters in \thmt@restatable. This is the version of \thmt@restatable I am testing right now:

\renewenvironment{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
        % nothing here in my patched version
      \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=\@gobble
        \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
         % these are the valid numbers, store them for the other
         % occasions.
         \thmt@rst@storecounters{#3}%
        % 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.
}
4
  • Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. Nov 26, 2014 at 13:37
  • To be more precise, it sometimes occurs that compiling the document will raise a strange error. I work around it by using directly pdflatex rather than latexmk, and removing the .aux and .out file before recompiling.
    – a3nm
    Jan 18, 2015 at 15:31
  • 1
    Is there any simpler solution that came up? As far as I know, this issue still exists. Thanks!
    – Clément
    Feb 11, 2019 at 15:18
  • @Clément I give not so general, but much more easy solution
    – Smylic
    Dec 7, 2019 at 22:19
2

There is an easy way to fix this problem in not so general, but (IMHO) the most natural case, when a theorem gets a number as soon as it appears and all restates have the same number. So case is:

\documentclass{article}

\usepackage{amsthm}
\usepackage{thmtools}

\declaretheorem{theorem}

\begin{document}

\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{restatable}{theorem}{mythm}
This is a restated theorem.
\end{restatable}

\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}

\mythm*
\mythm*
\mythm*

\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}

\mythm*
\mythm*
\mythm*

\end{document}

1

And I fix it using \begin{theorem}[restated = mythm, name = ] instead of \begin{restatable}{theorem}{mythm}.

\documentclass{article}

\usepackage{amsthm}
\usepackage{thmtools}

\declaretheorem{theorem}

\begin{document}

\begin{theorem}
This is a regular theorem.
\end{theorem}

% If you have only restate argument then the name argument value will be , (comma),
% so you need to specify any other argument
\begin{theorem}[restate = mythm, name = ]\label{Thm:my}
This is a restated theorem.
\end{theorem}

\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}

\mythm*
\mythm*
\mythm*

\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}
\begin{theorem}
This is a regular theorem.
\end{theorem}

\mythm*
\mythm*
\mythm*

\end{document}

2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .