9

What I'm trying to do sounds quite simple:

\begin{thm}
Theorem 1 text.
\end{thm}
...
\begin{thm}
Theorem 2 text.
\end{thm}
...
\RepeaAllThms

This should display the theorems as it usually does, but then \RepeaAllThms should redisplay them all in one place.

I thought I'd make an environment that increases some counter, creates a name depending on it (say, thmA, thmB,...), use it as a restatable name, and collect all of those for \RepeaAllThms. For some reason, I cannot get it to work. Here is my MNWE (minimal NOT working example), with theorems actually being called "recommendations":

\documentclass[a4paper]{article}

\usepackage{thmtools}
\usepackage{thm-restate}
\usepackage{etoolbox}

\makeatletter
\def\recommend@tions{}
\newcounter{recommend@cnt}
\declaretheorem[name=Recommendation,numberwithin=section]{thmrecommend}
\newenvironment{recommendation}{%
    \stepcounter{recommend@cnt}%
    \edef\rcmdname{recommend\Alph{recommend@cnt}}%
    \restatable{thmrecommend}{\rcmdname}%
}{\endrestatable%
    %\xappto\recommend@tions{recommend\Alph{recommend@cnt}}%
    recommend\Alph{recommend@cnt}%
    %\csname recommend\Alph{recommend@cnt}* \endcsname%
    \recommendA*
}
\newcommand{\allrecommendations}{\recommend@tions}
\makeatother


\begin{document}

\section{Originals}

Some text.

\begin{recommendation}
This is the first recommendation.
\end{recommendation}

Some text.

\begin{recommendation}
This is the second recommendation.
\end{recommendation}

Some text.

\section{All together}

%\allrecommendations
%\recommendA*
%\recommendB*

\end{document}

I have added \recommendA* at the end of my environment to check that it works, and it is always redefined as the last theorem. Uncommenting \recommendA* or \recommendB* causes errors that I do not understand.

Any idea how to do this? It doesn't have to be with restatable. Any approach letting me automatically repeat the contents of the theorems would be OK.

2

2 Answers 2

10

You were almost there. You have to pass to \restatable the full expansion of recommendation\Alph{recommend@cnt} and then append the right tokens to \recommend@tions.

\documentclass[a4paper]{article}

\usepackage{thmtools}
\usepackage{thm-restate}
\usepackage{etoolbox}

\makeatletter
\def\recommend@tions{}
\newcounter{recommend@cnt}
\declaretheorem[name=Recommendation,numberwithin=section]{thmrecommend}
\newenvironment{recommendation}{%
  \stepcounter{recommend@cnt}%
  % fully expand the counter representation
  % before calling \restatable
  \begingroup\edef\x{\endgroup
    \noexpand\restatable{thmrecommend}{recommend\Alph{recommend@cnt}}%
  }\x
}{\endrestatable
  % add to \recommend@tions the command
  % \recommend<letter>*
  \xappto\recommend@tions{%
    \expandafter\noexpand\csname recommend\Alph{recommend@cnt}\endcsname*%
  }%
}
\newcommand{\allrecommendations}{\recommend@tions}
\makeatother


\begin{document}

\section{Originals}

Some text.

\begin{recommendation}
This is the first recommendation.
\end{recommendation}

Some text.

\begin{recommendation}
This is the second recommendation.
\end{recommendation}

Some text.

\section{All together}

\allrecommendations

\end{document}

enter image description here

An implementation with xparse and expl3 that also copes with the optional argument, for attribution.

\documentclass[a4paper]{article}

\usepackage{thmtools}
\usepackage{thm-restate}
\usepackage{xparse}

\declaretheorem[
  name=Recommendation,
  numberwithin=section,
]{thmrecommend}

\ExplSyntaxOn
\NewDocumentEnvironment{recommendation}{o}
 {
  \int_gincr:N \g_vedran_recommendation_int
  \IfNoValueTF{#1}
   {
    \vedran_restatable:x { \int_to_Alph:n { \g_vedran_recommendation_int } }
   }
   {
    \vedran_restatable:nx { #1 } { \int_to_Alph:n { \g_vedran_recommendation_int } }
   }
 }
 {
  \endrestatable
  \seq_gput_right:Nx \g_vedran_recommendation_seq
   {
    recommend \int_to_Alph:n { \g_vedran_recommendation_int }
   }
 }

\NewDocumentCommand{\allrecommendations}{}
 {
  \seq_map_inline:Nn \g_vedran_recommendation_seq
   {
    \use:c { ##1 } *
   }
 }

\int_new:N \g_vedran_recommendation_int
\seq_new:N \g_vedran_recommendation_seq

\cs_new_protected:Npn \vedran_restatable:n #1
 {
  \restatable{thmrecommend}{recommend#1}
 }
\cs_generate_variant:Nn \vedran_restatable:n { x }
\cs_new_protected:Npn \vedran_restatable:nn #1 #2
 {
  \restatable[#1]{thmrecommend}{recommend#2}
 }
\cs_generate_variant:Nn \vedran_restatable:nn { nx }
\ExplSyntaxOff

\begin{document}

\section{Originals}

Some text.

\begin{recommendation}[Egreg]
This is the first recommendation.
\end{recommendation}

Some text.

\begin{recommendation}
This is the second recommendation.
\end{recommendation}

Some text.

\section{All together}

\allrecommendations

\end{document}

enter image description here

4
  • Thank you. "You have to pass to \restatable the full expansion of recommendation\Alph{recommend@cnt}" --> I got that and it was my intention to do so with \edef\rcmdname{recommend\Alph{recommend@cnt}}. Can you please explain in short why that didn't produce the desired effect? Jun 23, 2015 at 22:44
  • 1
    @VedranŠego You didn't expand \rcmdname afterwards.
    – egreg
    Jun 23, 2015 at 22:51
  • Do you know if we can adapt this code when we have several environments (as Theorem, Proposition, Definition, etc.) ? Thank you very much!
    – Watson
    Dec 27, 2016 at 23:15
  • @Watson I think it can be done. But hanc commentari exiguitas non caperet, to mimic a famous quote: not doable in comments.
    – egreg
    Dec 27, 2016 at 23:22
4

I think that this is an expansion problem because you are trying to create a dynamic label for your restartable recommendations that depends on a counter. TeX does not seem to like expanding in such places unless forced! It is a little ungainly but I get around this using \fakerec in the macros below.

Here is the output:

enter image description here

and here is the code:

\documentclass[a4paper]{article}

\usepackage{thmtools}
\usepackage{thm-restate}
\usepackage{etoolbox}

\usepackage{environ}
\newcounter{recommendations}
\renewcommand\therecommendations{\Alph{recommendations}}
\declaretheorem[name=Recommendation,numberwithin=section]{thmrecommend}
\NewEnviron{recommendation}[1][]{%
  \stepcounter{recommendations}% makes the change global
  \edef\fakerec{\noexpand\restatable[#1]{thmrecommend}\therecommendations\BODY}
  \fakerec\endrestatable\relax%
  \typeout{Stated restable for \therecommendations}
  \listxadd\recommendationsList\therecommendations%
}

\newcommand\AllRecommendations{%
  \renewcommand{\do}[1]{\csuse{##1}*}
  \dolistloop\recommendationsList%
}

\begin{document}

  \section{Originals}

  Some text.

  \begin{recommendation}
  This is the first recommendation.
  \end{recommendation}

  Some text.

  \begin{recommendation}
  This is the second recommendation.
  \end{recommendation}

  Some text.

  \section{All together}

  \AllRecommendations

\end{document}

Some comments. First I really like the environ package so I have used it to create the recommendation environment.

As I said above, my use of \fakerec is a hack to get \therecommendations to expand when passed to \restatable. It is also needed to expand \BODY because \restatable keeps a copy of the contents of the recommendation for later use. I would be happy if there was a better way to do this.

Finally, the \AllRecommendations macro uses some of the list functionality from the etoolbox package. Specifically, the recommendation environment creates a list, \recommendationsList, of the names of the recommendation environments and then \dolistloop is used to print them out.

2
  • The difference between \refstepcounter and \stepcounter is that the former also sets things up so a following \label will point to the generated number; both act globally on the counter.
    – egreg
    Jun 23, 2015 at 22:16
  • @egreg Thanks. Fixed .I think i had a looping issue and thought that this was the problem. Is there a better way to solve the expansion problem above?
    – user30471
    Jun 23, 2015 at 22:19

You must log in to answer this question.

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