1

I'm trying to manually do a small script that let me put proofs at the end, restate theorem... But I'm having some troubles with the restate, because all the theorems have the same name, so when I want to restate them at the end all of them have the same name. Indeed, I wrote in a function:

\edef\namerestate{prAtEndRestate\roman{counterAllProofEnd}}
\begin{restatable}{#2}{\namerestate}\label{thm:prAtEnd\thecounterAllProofEnd}
    #4
\end{restatable}

and in my code:

\prAtEndRestatei*
\prAtEndRestateii*

But the two theorems that are displayed are exactly the same (the last theorem written)!

Any idea what's going wrong?

enter image description here

MWE:

\documentclass{article}
\usepackage{mathtools}
\usepackage{amssymb, amsthm, amsmath, thm-restate}
\usepackage{thmtools} %%
\usepackage{hyperref}
\usepackage{etoolbox}

\newtheorem{thm}{Theorem}[section]
\providecommand*\thmautorefname{Theorem}
\newtheorem{corollary}[thm]{Corollary}
\providecommand*\corollaryautorefname{Corollary}
\newtheorem{lemma}[thm]{Lemma}
\providecommand*\lemmaautorefname{Lemma}

\begin{document}

\section{Manual theorems}
\edef\namerestate{manualtheoremi}
\begin{restatable}{thm}{\namerestate}
  My first manual theorem
\end{restatable}

\edef\namerestate{manualtheoremii}
\begin{restatable}{thm}{\namerestate}
  My second manual theorem
\end{restatable}

Restitution:
\manualtheoremi*
\manualtheoremii*

\end{document}

EDIT: This appears to work, but please let me know if there is a better way, especially if xparse/latex3e proposed better solutions: How to expand several arguments in an environment?

1 Answer 1

2

Simple LaTeX3-based solution

Here is a simple solution using LaTeX3:

\documentclass{article}
\usepackage{thm-restate}
\usepackage{hyperref}
\usepackage{expl3}
\usepackage{xparse}

\newtheorem{thm}{Theorem}[section]
\providecommand*\thmautorefname{Theorem}

\ExplSyntaxOn

\int_new:N \g_tobias_thm_counter_int

\cs_new_protected:Npn \tobias_declare_thm_label:nn #1#2
{
  \label { thm #1 prAtEnd #2 }
}

\cs_generate_variant:Nn \tobias_declare_thm_label:nn { xn }

% #1: theorem type
% #2: unique suffix for theorem (e.g., counter representation as roman numerals)
\cs_new_protected:Npn \tobias_start_proclaim_thm:nn #1#2
{
  % Start 'restatable' environment
  \restatable {#1} { restatableThm #2 }
  % Write the \label command with the appropriate label based on #2
  \tobias_declare_thm_label:xn
    { \char_generate:nn { `\: } { 12 } } % colon with catcode 12 (other)
    {#2}
}

\cs_generate_variant:Nn \tobias_start_proclaim_thm:nn { nx }

\NewDocumentEnvironment { proclaimRestatable } { m }
  {
    \int_gincr:N \g_tobias_thm_counter_int % increment the counter
    % Start 'restatable' environment
    \tobias_start_proclaim_thm:nx
      {#1}
      { \int_to_roman:n \g_tobias_thm_counter_int }
  }
  { \endrestatable }

\ExplSyntaxOff


\begin{document}

\section{Some section}

\begin{proclaimRestatable}{thm}
  My first theorem
\end{proclaimRestatable}

\begin{proclaimRestatable}{thm}
  My second theorem
\end{proclaimRestatable}

Restitution:
\restatableThmi*
\restatableThmii*

Reference to \autoref{thm:prAtEndi}.\par
Reference to \autoref{thm:prAtEndii}.
\end{document}

screenshot of result

This terminates the simpler LaTeX3-based solution I found. Here follows the first solution I came up with. It was a bit more complicated; I'm leaving it here in case you find the technique and explanations useful.

Other (more convoluted) LaTeX3-based solution

The trickiest part for me in this first solution was to produce the theorem labels you wanted with correct category codes, because in LaTeX3 syntax (after specifying \ExplSyntaxOn), the category code of a colon : is letter (11), whereas in LaTeX2e syntax (in particular, in your document body), it is other (12).a In order to do this, I used a token list variable (\l__tobias_thm_label_tl) that is assembled bits by bits using \tl_put_right:Nx and \tl_put_right:Nn, and passed it as a value argument (V) to a macro that expands to \label {#1} (#1 being replaced by the value of the token list variable).

Actually, writing the \label{thm:prAtEnd...} with a : of category code 11 (letter) seems to work as well—but not with category code 10 or 13, for instance. I suppose this is because writing a : of category code 11 or 12 to the .aux file produces the same result (excerpt from my .aux file):

\newlabel{thm:prAtEndi}{{1.1}{1}{Some section}{thm.1.1}{}}

Therefore, when the .aux file is read back, it makes no difference whether the : character tokens in the label were passed to \label with category code 11 or 12. Still, I think it is cleaner to keep the logic that passes \label an argument with exactly the same category codes as would be obtained for a \label written after \begin{document}.

\documentclass{article}
\usepackage{thm-restate}
\usepackage{hyperref}
\usepackage{expl3}
\usepackage{xparse}

\newtheorem{thm}{Theorem}[section]
\providecommand*\thmautorefname{Theorem}

\ExplSyntaxOn

\int_new:N \g_tobias_thm_counter_int
\tl_new:N \l__tobias_thm_label_tl

% #1: unique suffix for theorem (e.g., counter representation as roman numerals)
\cs_new_protected:Npn \tobias_make_thm_label_name:n #1
{
  % Start of label: three tokens
  \tl_set:Nn \l__tobias_thm_label_tl { thm }
  % Append a colon of category 12 (other)
  % [unlike normal colons under \ExplSyntaxOn regime]
  \tl_put_right:Nx \l__tobias_thm_label_tl { \char_generate:nn { `\: } { 12 } }
  % End of label
  \tl_put_right:Nn \l__tobias_thm_label_tl { prAtEnd #1 }
}

\cs_new_protected:Npn \tobias_declare_thm_label:n #1
{
  \label {#1}
}

\cs_generate_variant:Nn \tobias_declare_thm_label:n { V }

% #1: theorem type
% #2: unique suffix for theorem (e.g., counter representation as roman numerals)
\cs_new_protected:Npn \tobias_start_proclaim_thm:nn #1#2
{
  % Assemble and store the label name with correct category codes inside
  % token list variable \l__tobias_thm_label_tl.
  \tobias_make_thm_label_name:n {#2}
  % Start 'restatable' environment
  \restatable {#1} { restatableThm #2 }
  % Write the \label command with the appropriate label based on #2
  \tobias_declare_thm_label:V \l__tobias_thm_label_tl
}

\cs_generate_variant:Nn \tobias_start_proclaim_thm:nn { nx }

\NewDocumentEnvironment { proclaimRestatable } { m }
  {
    \int_gincr:N \g_tobias_thm_counter_int % increment the counter
    % Start 'restatable' environment
    \tobias_start_proclaim_thm:nx
      {#1}
      { \int_to_roman:n \g_tobias_thm_counter_int }
  }
  { \endrestatable }

\ExplSyntaxOff


\begin{document}

\section{Some section}

\begin{proclaimRestatable}{thm}
  My first theorem
\end{proclaimRestatable}

\begin{proclaimRestatable}{thm}
  My second theorem
\end{proclaimRestatable}

Restitution:
\restatableThmi*
\restatableThmii*

Reference to \autoref{thm:prAtEndi}.\par
Reference to \autoref{thm:prAtEndii}.
\end{document}

Footnote

a. Note that in French documents, the colon : typically has category code 13 (active) in order to produce the desired spacing. For this reason, I generally don't use it in labels (avoiding potential problems...).

1
  • I found a simpler solution and edited my post. If it doesn't do what you wanted, please explain precisely why.
    – frougon
    Apr 12, 2019 at 12:09

You must log in to answer this question.

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