4

I'm trying to understand and modify this code:

\newtheorem*{nonamethm}{\nonamethmname}
\newcommand{\nonamethmname}{}

\newenvironment{genthm}[1]
 {\renewcommand{\nonamethmname}{#1}\nonamethm}
 {\endnonamethm}
\newenvironment{genthm*}[1]
 {\renewcommand{\nonamethmname}{#1}\nonamethmcheck}
 {\endnonamethm}

\newcommand\nonamethmcheck[1][]{%
  \if\relax\detokenize{#1}\relax
    \nonamethm\relax
  \else
    \nonamethm[#1]%
  \fi
  \mbox{}%
}

It was proposed by @egreg in one of my previous questions. It works perfectly, but I don't understand why and now I'd like to extend its functionality.

With this code I can just write

\begin{genthm}
Theorem statement
\end{genthm}

instead of

\newtheorem{arbitraryname}
\begin{arbitraryname}
Theorem statement
\end{arbitraryname}

I'd like to understand how this code works. As far as I know \relax effectively does nothing, but I'm having troubles understanding the other pieces. For example, does the % symbol do anything, or is it just an "empty" comment? What about the empty command \newcommand{\nonamethmname}{}?

Finally I'd like to know what's the best way to extend the above commands in such a way that I can optionally specify the theorem style. Ideally, I could do \begin{genthm}{definition} Definition statement. \end{genthm} to avoid having to write \theoremstyle{definition}. If the second argument is omitted, it should be defaulted to \theoremstyle{plain}, which is the default.

Is this possible?

4
  • % at the end prevents spurious whitespace, often found if omitted, \newcommand{\nonamethmname}{} just provides the empty macro \nonamethmname, which expands to nothing since it's empty, but it's there such that the compiler does not complain. Your code seems to generate theorem - environment definitions on the fly.
    – user31729
    Feb 28, 2015 at 18:26
  • Please provide a link to the original question. The code should be easily extensible with xparse package for optional arguments.
    – user31729
    Feb 28, 2015 at 18:30
  • I found the question: tex.stackexchange.com/questions/226105/…
    – user31729
    Feb 28, 2015 at 18:32
  • @ChristianHupfer Sorry I definitely should have linked it. That is the right one, thanks. I'll edit the post.
    – rubik
    Feb 28, 2015 at 18:35

2 Answers 2

2

The trick is quite simple: we define a generic unnumbered theorem, where the theorem label is not explicitly given as a word, but given as a macro that we can redefine at will.

The redefinition happens in the environment around this newly defined theorem environment: when you say

\begin{genthm}{Name}

the environment redefines \nonamethmname to the argument, in this case Name and starts the nonamethm environment that will typeset the statement. At the end, we close nonamethm. In genthm* we delay the opening of the nonamethm environment looking first for the “attribution” optional argument, because we want to issue \mbox{} so an enumerate will start after a line break. The test \if\relax\detokenize{#1}\relax returns true if the optional argument is missing. The \relax after \begin{nonamethm} in the definition of genthm* is just to stop its lookup for an optional argument (we already know it's not there), so gaining some nanosecond.

In order to do what you want, you need to define a generic unnumbered theorem for each style you plan to use, because the style is chosen at definition time.

It's easy to extend the definitions to allow for your request, but it's handier to use xparse.

\documentclass{article}
\usepackage{amsthm}
\usepackage{xparse}

\newtheorem*{nonamethmplain}{\nonamethmname}
\theoremstyle{definition}
\newtheorem*{nonamethmdefinition}{\nonamethmname}
\theoremstyle{remark}
\newtheorem*{nonamethmremark}{\nonamethmname}
\newcommand{\nonamethmname}{}

\NewDocumentEnvironment{genthm}{O{plain}m}
 {\renewcommand{\nonamethmname}{#2}\begin{nonamethm#1}}
 {\end{nonamethm#1}}
\NewDocumentEnvironment{genthm*}{O{plain}mo}
 {\renewcommand{\nonamethmname}{#2}%
  \IfNoValueTF{#3}
    {\begin{nonamethm#1}\relax}%
    {\begin{nonamethm#1}[#3]}%
  \mbox{}}
 {\end{nonamethm#1}}

\begin{document}

\begin{genthm}{Hairy ball theorem}
Whatever it says
\end{genthm}

\begin{genthm}[definition]{Transcendental number}
A \emph{transcendental} number is a number that is not algebraic.
Easy, no?
\end{genthm}

\begin{genthm}[remark]{Easy remark}[J. de La Palice]
Everything is easy when it is.
\end{genthm}

\begin{genthm*}[definition]{Bunch of definitions}
\begin{enumerate}
\item A
\item B
\item C
\end{enumerate}
\end{genthm*}

\end{document}

The genthm environment now looks for an optional argument (default plain) and appends it to nonamethm in order to choose the correct style.

Note that the final attribution optional argument is still honored, thanks to the features in xparse.

enter image description here

Please, be friendly to your readers and provide them theorem numbers.

4
  • Similiar ideas ;-)
    – user31729
    Feb 28, 2015 at 18:54
  • 1
    @ChristianHupfer Yes, but mine are better. ;-)
    – egreg
    Feb 28, 2015 at 18:55
  • 1
    But I was quicker :-P
    – user31729
    Feb 28, 2015 at 18:55
  • Thanks to both of you! I'm choosing this one because it contains the explanation of the commands. I switched to numbered theorems by removing the star at \newtheorem*{nonamethmplain}{\nonamethmname}.
    – rubik
    Mar 1, 2015 at 20:54
2

I just stole the code from egreg's answer to the linked question Make `enumerate` start from a new line

and redefined the genthm environment, wrapping * and unstarred version together (with some minor caveat, the position of the star) and added the optional argument.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[italian]{babel}

\usepackage{xparse}
\usepackage{amsthm}

\newtheorem*{nonamethm}{\nonamethmname}
\newcommand{\nonamethmname}{}


\newcommand\nonamethmcheck[1][]{%
  \if\relax\detokenize{#1}\relax
    \nonamethm\relax
  \else
    \nonamethm[#1]%
  \fi
  \mbox{}%
}


\NewDocumentEnvironment{genthm}{s+om}{%
  \IfBooleanTF{#1}{% Check for starred version 
    \IfValueTF{#2}{%  Check for optional 2nd argument
      \theoremstyle{#2}%
    }{}%
    \renewcommand{\nonamethmname}{#3}\nonamethmcheck%
  }{% No, it's the unstarred versions
    \IfValueTF{#2}{%
      \theoremstyle{#2}%
    }{}
    \renewcommand{\nonamethmname}{#3}\nonamethm%
  }%
}{%
  \endnonamethm%
}



\begin{document}

%\begin{aenv}*
%Something
%\end{aenv}

\begin{genthm}*{Teoremi del quoziente}
\begin{enumerate}
\item Se $\lim\limits_{x \to \alpha} |f(x)| = +\infty$,
  allora $\lim\limits_{x \to \alpha} \frac{1}{f(x)} = 0$.

\item Se $\lim\limits_{x \to \alpha} f(x) = 0$,
  allora $\lim\limits_{x \to \alpha} \frac1{|f(x)|} = +\infty$.

\item Se $\lim\limits_{x \to \alpha} f(x) = l \neq 0$,
  allora $\lim\limits_{x \to \alpha} \frac1{f(x)} = \frac{1}{l}$.

\item Se $\lim\limits_{x \to \alpha} f(x) = l$ e $\lim\limits_{x \to \alpha} g(x) = m \neq 0$,
  allora $\lim\limits_{x \to \alpha} \frac{f(x)}{g(x)} = \frac{l}{m}$.
\end{enumerate}
\end{genthm}

\begin{genthm}*{Teoremi del quoziente}
Siano $f$ e $g$ funzioni definite in un intorno bucato di~$\alpha$.
\begin{enumerate}
\item Se $\lim\limits_{x \to \alpha} |f(x)| = +\infty$,
  allora $\lim\limits_{x \to \alpha} \frac{1}{f(x)} = 0$.

\item Se $\lim\limits_{x \to \alpha} f(x) = 0$,
  allora $\lim\limits_{x \to \alpha} \frac1{|f(x)|} = +\infty$.

\item Se $\lim\limits_{x \to \alpha} f(x) = l \neq 0$,
  allora $\lim\limits_{x \to \alpha} \frac1{f(x)} = \frac{1}{l}$.

\item Se $\lim\limits_{x \to \alpha} f(x) = l$ e $\lim\limits_{x \to \alpha} g(x) = m \neq 0$,
  allora $\lim\limits_{x \to \alpha} \frac{f(x)}{g(x)} = \frac{l}{m}$.
\end{enumerate}
\end{genthm}

\end{document}

enter image description here

You must log in to answer this question.

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