I'm trying to define a macro \CreateTheorem(*)
, the intention is to be able to define the theorem-like environments as easy as before, but can be traced correctly by cref
in a multi-language document. For example,
\CreateTheorem{theorem}<section>
\CreateTheorem{definition}[theorem]
should create theorem
and definition
environments as usual. The result would be like (this is produced by the document in the last of this question, which manually does the work of \CreateTheorem
):
Currently I have (below is a complete, but not yet working MWE):
\documentclass{article}
\usepackage[french,english]{babel}
\usepackage{xcolor}
\definecolor{paper}{RGB}{255,255,255}
\usepackage{mathtools}
\usepackage{amsthm}
\makeatletter
\newtheoremstyle{simple}%
{}{}%
{\normalfont}{}%
{\normalfont}{}%
{0pt}%
{\thmname{\MakeUppercase{#1}}\thmnumber{ #2}\hspace{.4em}\textcolor{gray!55!paper}{$|$}\hspace{.4em}\color{gray}\thmnote{\ensuremath{(\text{#3})}~~}\pushQED{\qed}}
\def\@endtheorem{\popQED\endtrivlist\@endpefalse }
\makeatother
\renewcommand{\qedsymbol}{\makebox[1em]{\color{gray!55!paper}\rule[-0.1em]{.95em}{.95em}}}
\PassOptionsToPackage{hidelinks,linktoc=all}{hyperref}
\RequirePackage{hyperref}
\PassOptionsToPackage{nameinlink}{cleveref}
\RequirePackage{cleveref}
\crefdefaultlabelformat{#2#1#3~\aftergroup\ignorespaces}
\theoremstyle{simple}
\newcommand\englishABBR{EN}
\newcommand\frenchABBR{FR}
%% macro for creating theorems
\RequirePackage{xstring}
\NewDocumentCommand{\CreateTheorem}{smod<>}{%
\IfBooleanTF{#1}
{% Stared version
\IfEndWith{#2}{*}
{% \CreateTheorem*{theorem*}
\StrGobbleRight{#2}{1}[\temp]%
\newtheorem*{\temp EN*}{\csname\temp nameEN\endcsname}
\newtheorem*{\temp FR*}{\csname\temp nameFR\endcsname}
\NewDocumentEnvironment{\temp*}{O{}}{\begin{\temp \csname\languagename ABBR\endcsname*}[##1]}{\end{\temp \csname\languagename ABBR\endcsname*}}
}
{% \CreateTheorem*{theorem}
\newtheorem*{#2EN}{\csname#2nameEN\endcsname}
\newtheorem*{#2FR}{\csname#2nameFR\endcsname}
\NewDocumentEnvironment{#2}{O{}}{\begin{#2\csname\languagename ABBR\endcsname}[##1]}{\end{#2\csname\languagename ABBR\endcsname}}
}%
}
{% Non-stared version
\IfEndWith{#2}{*}
{% \CreateTheorem{theorem*}[...]<...>
\StrGobbleRight{#2}{1}[\temp]%
\newtheorem{\temp EN*}[#3]{\csname\temp nameEN\endcsname}[#4]
\newtheorem{\temp FR*}[#3]{\csname\temp nameFR\endcsname}[#4]
\crefname{\temp EN*}{\protect\MakeUppercase{\csname\temp nameEN\endcsname}}{\protect\MakeUppercase{\csname\temp nameEN\endcsname}}
\crefname{\temp FR*}{\protect\MakeUppercase{\csname\temp nameFR\endcsname}}{\protect\MakeUppercase{\csname\temp nameFR\endcsname}}
\NewDocumentEnvironment{\temp*}{O{}}{\begin{\temp \csname\languagename ABBR\endcsname*}[##1]}{\end{\temp \csname\languagename ABBR\endcsname*}}
}
{% \CreateTheorem{theorem}[...]<...>
\newtheorem{#2EN}[#3]{\csname#2nameEN\endcsname}[#4]
\newtheorem{#2FR}[#3]{\csname#2nameFR\endcsname}[#4]
\crefname{#2EN}{\protect\MakeUppercase{\csname#2nameEN\endcsname}}{\protect\MakeUppercase{\csname#2nameEN\endcsname}}
\crefname{#2FR}{\protect\MakeUppercase{\csname#2nameFR\endcsname}}{\protect\MakeUppercase{\csname#2nameFR\endcsname}}
\NewDocumentEnvironment{#2}{O{}}{\begin{#2\csname\languagename ABBR\endcsname}[##1]}{\end{#2\csname\languagename ABBR\endcsname}}
}%
}%
}
\def\theoremnameEN{Theorem}
\def\theoremnameFR{Théorème}
\def\definitionnameEN{Definition}
\def\definitionnameFR{Définition}
\def\remarknameEN{Remark}
\def\remarknameFR{Remarque}
\def\notenameEN{Note}
\def\notenameFR{Note}
\CreateTheorem{theorem}<section>
\CreateTheorem{definition}[theorem]
\CreateTheorem*{theorem*}
\CreateTheorem*{definition*}
\CreateTheorem*{remark}
\CreateTheorem{note*} % This is strange, only for test
\begin{document}
\begin{theorem}
\end{theorem}
\begin{definition}
\end{definition}
\end{document}
There're two problems:
- As @Skillmon points out to me, one cannot use
\newtheorem
with two counters as optional arguments. (Using \newtheorem) So[#3]
and[#4]
should only appear when they are non-empty. - The
theorem*
case uses\temp
string, which is not static and may get changed. Something similar to this question should be considered.
Could anyone please help me building this macro?
This macro is intended to simplify to process for defining theorem-like environments in a multi-language document. Below is a document with manually defined theorem-like environments. As a comparison, when \CreateTheorem
is finished, it should be able to produce the same result, but with a much easier process.
\documentclass{article}
\usepackage[french,english]{babel}
\usepackage{xcolor}
\definecolor{paper}{RGB}{255,255,255}
\usepackage{mathtools}
\usepackage{amsthm}
\makeatletter
\newtheoremstyle{simple}%
{}{}%
{\normalfont}{}%
{\normalfont}{}%
{0pt}%
{\thmname{\MakeUppercase{#1}}\thmnumber{ #2}\hspace{.4em}\textcolor{gray!55!paper}{$|$}\hspace{.4em}\color{gray}\thmnote{\ensuremath{(\text{#3})}~~}\pushQED{\qed}}
\def\@endtheorem{\popQED\endtrivlist\@endpefalse }
\makeatother
\renewcommand{\qedsymbol}{\makebox[1em]{\color{gray!55!paper}\rule[-0.1em]{.95em}{.95em}}}
\PassOptionsToPackage{hidelinks,linktoc=all}{hyperref}
\RequirePackage{hyperref}
\PassOptionsToPackage{nameinlink}{cleveref}
\RequirePackage{cleveref}
\crefdefaultlabelformat{#2#1#3~\aftergroup\ignorespaces}
\theoremstyle{simple}
\newcounter{theorem}
\newcounter{conjecture}
\newcounter{example}
\newcounter{problem}
\newcounter{remark}
\numberwithin{theorem}{section}
\numberwithin{conjecture}{section}
\numberwithin{example}{section}
\numberwithin{problem}{section}
\numberwithin{remark}{section}
\newcommand\englishABBR{EN}
\newcommand\frenchABBR{FR}
%% English theorems
\newtheorem{theoremEN}[theorem]{\theoremnameEN}
\newtheorem{lemmaEN}[theorem]{\lemmanameEN}
\newtheorem{propositionEN}[theorem]{\propositionnameEN}
\newtheorem{corollaryEN}[theorem]{\corollarynameEN}
\newtheorem{factEN}[theorem]{\factnameEN}
\newtheorem{conjectureEN}[conjecture]{\conjecturenameEN}
\newtheorem*{theoremEN*}{\theoremnameEN}
\newtheorem*{lemmaEN*}{\lemmanameEN}
\newtheorem*{propositionEN*}{\propositionnameEN}
\newtheorem*{corollaryEN*}{\corollarynameEN}
\newtheorem*{factEN*}{\factnameEN}
\newtheorem*{conjectureEN*}{\conjecturenameEN}
\newtheorem{definitionEN}[theorem]{\definitionnameEN}
\newtheorem{exampleEN}[example]{\examplenameEN}
\newtheorem{problemEN}[problem]{\problemnameEN}
\newtheorem*{definitionEN*}{\definitionnameEN}
\newtheorem*{exampleEN*}{\examplenameEN}
\newtheorem*{problemEN*}{\problemnameEN}
\newtheorem{remarkEN}[remark]{\remarknameEN}
\newtheorem*{remarkEN*}{\remarknameEN}
\def\theoremnameEN{Theorem}
\def\lemmanameEN{Lemma}
\def\propositionnameEN{Proposition}
\def\corollarynameEN{Corollary}
\def\factnameEN{Fact}
\def\conjecturenameEN{Conjecture}
\def\definitionnameEN{Definition}
\def\examplenameEN{Example}
\def\problemnameEN{Problem}
\def\remarknameEN{Remark}
%% French theorems
\newtheorem{theoremFR}[theorem]{\theoremnameFR}
\newtheorem{lemmaFR}[theorem]{\lemmanameFR}
\newtheorem{propositionFR}[theorem]{\propositionnameFR}
\newtheorem{corollaryFR}[theorem]{\corollarynameFR}
\newtheorem{factFR}[theorem]{\factnameFR}
\newtheorem{conjectureFR}[conjecture]{\conjecturenameFR}
\newtheorem*{theoremFR*}{\theoremnameFR}
\newtheorem*{lemmaFR*}{\lemmanameFR}
\newtheorem*{propositionFR*}{\propositionnameFR}
\newtheorem*{corollaryFR*}{\corollarynameFR}
\newtheorem*{factFR*}{\factnameFR}
\newtheorem*{conjectureFR*}{\conjecturenameFR}
\newtheorem{definitionFR}[theorem]{\definitionnameFR}
\newtheorem{exampleFR}[example]{\examplenameFR}
\newtheorem{problemFR}[problem]{\problemnameFR}
\newtheorem*{definitionFR*}{\definitionnameFR}
\newtheorem*{exampleFR*}{\examplenameFR}
\newtheorem*{problemFR*}{\problemnameFR}
\newtheorem{remarkFR}[remark]{\remarknameFR}
\newtheorem*{remarkFR*}{\remarknameFR}
\def\theoremnameFR{Théorème}
\def\lemmanameFR{Lemme}
\def\propositionnameFR{Proposition}
\def\corollarynameFR{Corollaire}
\def\factnameFR{Fait}
\def\conjecturenameFR{Conjecture}
\def\definitionnameFR{Définition}
\def\examplenameFR{Exemple}
\def\problemnameFR{Problème}
\def\remarknameFR{Remarque}
%% cleveref configuration
\crefname{theoremEN}{\protect\MakeUppercase{\theoremnameEN}}{\protect\MakeUppercase{\theoremnameEN}}
\crefname{lemmaEN}{\protect\MakeUppercase{\lemmanameEN}}{\protect\MakeUppercase{\lemmanameEN}}
\crefname{propositionEN}{\protect\MakeUppercase{\propositionnameEN}}{\protect\MakeUppercase{\propositionnameEN}}
\crefname{corollaryEN}{\protect\MakeUppercase{\corollarynameEN}}{\protect\MakeUppercase{\corollarynameEN}}
\crefname{factEN}{\protect\MakeUppercase{\factnameEN}}{\protect\MakeUppercase{\factnameEN}}
\crefname{conjectureEN}{\protect\MakeUppercase{\conjecturenameEN}}{\protect\MakeUppercase{\conjecturenameEN}}
\crefname{definitionEN}{\protect\MakeUppercase{\definitionnameEN}}{\protect\MakeUppercase{\definitionnameEN}}
\crefname{exampleEN}{\protect\MakeUppercase{\examplenameEN}}{\protect\MakeUppercase{\examplenameEN}}
\crefname{problemEN}{\protect\MakeUppercase{\problemnameEN}}{\protect\MakeUppercase{\problemnameEN}}
\crefname{remarkEN}{\protect\MakeUppercase{\remarknameEN}}{\protect\MakeUppercase{\remarknameEN}}
\crefname{theoremFR}{\protect\MakeUppercase{\theoremnameFR}}{\protect\MakeUppercase{\theoremnameFR}}
\crefname{lemmaFR}{\protect\MakeUppercase{\lemmanameFR}}{\protect\MakeUppercase{\lemmanameFR}}
\crefname{propositionFR}{\protect\MakeUppercase{\propositionnameFR}}{\protect\MakeUppercase{\propositionnameFR}}
\crefname{corollaryFR}{\protect\MakeUppercase{\corollarynameFR}}{\protect\MakeUppercase{\corollarynameFR}}
\crefname{factFR}{\protect\MakeUppercase{\factnameFR}}{\protect\MakeUppercase{\factnameFR}}
\crefname{conjectureFR}{\protect\MakeUppercase{\conjecturenameFR}}{\protect\MakeUppercase{\conjecturenameFR}}
\crefname{definitionFR}{\protect\MakeUppercase{\definitionnameFR}}{\protect\MakeUppercase{\definitionnameFR}}
\crefname{exampleFR}{\protect\MakeUppercase{\examplenameFR}}{\protect\MakeUppercase{\examplenameFR}}
\crefname{problemFR}{\protect\MakeUppercase{\problemnameFR}}{\protect\MakeUppercase{\problemnameFR}}
\crefname{remarkFR}{\protect\MakeUppercase{\remarknameFR}}{\protect\MakeUppercase{\remarknameFR}}
%% Theorem environments
\NewDocumentEnvironment{theorem}{O{}}{\begin{theorem\csname\languagename ABBR\endcsname}[#1]}{\end{theorem\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{theorem*}{O{}}{\begin{theorem\csname\languagename ABBR\endcsname*}[#1]}{\end{theorem\csname\languagename ABBR\endcsname*}}
\NewDocumentEnvironment{lemma}{O{}}{\begin{lemma\csname\languagename ABBR\endcsname}[#1]}{\end{lemma\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{lemma*}{O{}}{\begin{lemma\csname\languagename ABBR\endcsname*}[#1]}{\end{lemma\csname\languagename ABBR\endcsname*}}
\NewDocumentEnvironment{proposition}{O{}}{\begin{proposition\csname\languagename ABBR\endcsname}[#1]}{\end{proposition\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{proposition*}{O{}}{\begin{proposition\csname\languagename ABBR\endcsname*}[#1]}{\end{proposition\csname\languagename ABBR\endcsname*}}
\NewDocumentEnvironment{corollary}{O{}}{\begin{corollary\csname\languagename ABBR\endcsname}[#1]}{\end{corollary\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{corollary*}{O{}}{\begin{corollary\csname\languagename ABBR\endcsname*}[#1]}{\end{corollary\csname\languagename ABBR\endcsname*}}
\NewDocumentEnvironment{fact}{O{}}{\begin{fact\csname\languagename ABBR\endcsname}[#1]}{\end{fact\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{fact*}{O{}}{\begin{fact\csname\languagename ABBR\endcsname*}[#1]}{\end{fact\csname\languagename ABBR\endcsname*}}
\NewDocumentEnvironment{conjecture}{O{}}{\begin{conjecture\csname\languagename ABBR\endcsname}[#1]}{\end{conjecture\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{conjecture*}{O{}}{\begin{conjecture\csname\languagename ABBR\endcsname*}[#1]}{\end{conjecture\csname\languagename ABBR\endcsname*}}
\NewDocumentEnvironment{definition}{O{}}{\begin{definition\csname\languagename ABBR\endcsname}[#1]}{\end{definition\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{definition*}{O{}}{\begin{definition\csname\languagename ABBR\endcsname*}[#1]}{\end{definition\csname\languagename ABBR\endcsname*}}
\NewDocumentEnvironment{example}{O{}}{\begin{example\csname\languagename ABBR\endcsname}[#1]}{\end{example\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{example*}{O{}}{\begin{example\csname\languagename ABBR\endcsname*}[#1]}{\end{example\csname\languagename ABBR\endcsname*}}
\NewDocumentEnvironment{problem}{O{}}{\begin{problem\csname\languagename ABBR\endcsname}[#1]}{\end{problem\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{problem*}{O{}}{\begin{problem\csname\languagename ABBR\endcsname*}[#1]}{\end{problem\csname\languagename ABBR\endcsname*}}
\NewDocumentEnvironment{remark}{O{}}{\begin{remark\csname\languagename ABBR\endcsname}[#1]}{\end{remark\csname\languagename ABBR\endcsname}}
\NewDocumentEnvironment{remark*}{O{}}{\begin{remark\csname\languagename ABBR\endcsname*}[#1]}{\end{remark\csname\languagename ABBR\endcsname*}}
\def\sometext{Here's some text without a meaning. This text ...}
\begin{document}
In English:
\begin{theorem}\label{thm:1}
\sometext
\end{theorem}
\begin{theorem*}
\sometext
\end{theorem*}
\begin{definition}\label{def:1}
\sometext
\end{definition}
\selectlanguage{french}
En français:
\begin{theorem}\label{thm:2}
\sometext
\end{theorem}
\begin{theorem*}
\sometext
\end{theorem*}
\begin{definition}\label{def:2}
\sometext
\end{definition}
\selectlanguage{english}
See \cref{thm:1,thm:2,def:1,def:2}. % reference should be in their original language
\end{document}
\CreateTheorem*{foo}
,\CreateTheorem*{foo}
and\CreateTheorem*{foo*}
should be.\CreateTheorem
creates numbered theorems,\CreateTheorem*
creates unnumbered theorems.foo
andfoo*
are just different choices of names, I chose to process them separately because I wantfooEN*
, notfoo*EN
.