7

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.

8

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

  • 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? – Vedran Šego Jun 23 '15 at 22:44
  • 1
    @VedranŠego You didn't expand \rcmdname afterwards. – egreg Jun 23 '15 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 '16 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 '16 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.

  • 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 '15 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? – Andrew Jun 23 '15 at 22:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.