Nested case distinctions in LaTeX

Trust me, I am not one to enjoy deeply nested case distinctions in a mathematical proof. In fact, I'd rather there were no case distinctions necessary at all. However, to quote the famous mathematician Nikolai Nowaczyk: > Some theorems have beautiful proof - and some theorems are worth fighting for. Anyway. If you have to do it, you should do it in beautiful $\KaTeX$. Consequently, I sat down and ~~figured out~~ asked the good people of tex.se1 how to do nested case distinctions in LaTeX in such a way that numbering is done automatically, while maintaining the possibility to reference them nicely with cleveref. The following is a minimal, but complete example:
\documentclass[12pt]{article}

\usepackage{enumitem}
\usepackage[amsthm,thmmarks]{ntheorem}
\usepackage{cleveref}
\usepackage{forloop}

\theoremstyle{plain}
\newtheorem{thm}{Theorem}

% At this point we create the environment for nested case distinctions.
% Note that it is used like an enumerate environment, and you can nest
% at most 10 layers deep. Of course, you could change that.
% We will later define a macro \case which will be the equivalent of
% \item, except that we can pass it an optional argument which, instead
% of replacing the number label, adds a comment in brackets.

\newlist{caselist}{enumerate}{10}
\setlist[caselist]{itemsep=1ex,topsep=1ex,parsep=0pt,leftmargin=0pt,%
labelwidth=*,labelsep=1ex,align=caselabel,label*=.\arabic*}
\setlist[caselist,1]{label=\arabic*}

% The macro \thecaselabeltext serves as the optional parameter that we
% can later pass to the \case macro.

\newcommand\thecaselabeltext{}
\SetLabelAlign{caselabel}{\textbf{Case~#1\thecaselabeltext.}\hfil}

% The following sets the cleveref label name of the first layer of cases
% and then loops to alias all the other caselist counters. This way,
% cleveref will display references to nested cases correctly.

\crefname{caselisti}{case}{cases}
\newcounter{i}
\forLoop{1}{10}{i}{\crefalias{caselist\roman{i}}{caselisti}}

% Now I define the \case command. We need a little macro to check whether
% a string is empty. The \case macro will then redefine the \thecaselabeltext
% accordingly.

\makeatletter
\def\ifempty#1{\def\@x{#1}\ifx\@x\@empty}
\makeatother

{\ifempty{#1}\else~(#1)\fi}\item}

\begin{document}

\begin{thm}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{thm}
\begin{proof}
At vero eos et accusam et justo duo dolores et ea rebum.
\begin{caselist}
\case \label{a} Stet clita kasd gubergren, no sea takimata sanctus est
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur
sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua.
\begin{caselist}
\case At vero eos et accusam et justo duo dolores et ea rebum.
\case[Easy Case] \label{b} Stet clita kasd gubergren, no sea takimata sanctus est
Lorem ipsum dolor sit amet.
\end{caselist}
\case \Cref{a,b} imply: Consetetur sadipscing elitr, sed diam nonumy eirmod
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\end{caselist}
\end{proof}

\end{document}

Note that you should really use the ntheorem package to ensure that the QED-symbol is placed correctly. If you use amsthm instead and your proof ends with a caselist environment, the QED-symbol will always be placed on the line below, because that's how amsthm and enumerate's fail to work properly. By the way, if you want your case list to have no spacing, replace the configuration line with the following:
\setlist[caselist]{nolistsep,leftmargin=0pt,%
labelwidth=*,labelsep=1ex,align=caselabel,label*=.\arabic*}

1. See my question about numbering and one about the interaction with cref. []

Tags: -