7

I would like to create a theorem style which indents the theorem exactly like a \hangindent would do, expect that the indention should continue for all paragraphs of the theorem.

For example:

Theorem 1.2.3: Lipsum Lorem ipsum dolor sit amet,
    consectetuer adipiscing elit.  Ut purus elit, 
    vestibulum ut, placerat ac, adipiscing vitae, felis.

    Curabitur dictum gravida mauris. Nam arcu libero, 
    nonummy eget, consectetuer id, vulputate ...

I tried this, but it does not work correctly:

\documentclass[parskip=half]{scrartcl}
\usepackage{amsthm,thmtools}
\usepackage{lipsum}
\usepackage{showframe}

\let\thm\relax
\declaretheoremstyle[
    headfont=\bfseries,
    bodyfont=\normalfont\leftskip2.5em,
    headindent={-2.5em}
]{INDENTthm}
\declaretheorem[
    within=section,
    style=INDENTthm,
    name=Theorem
]{thm}

\begin{document}
\begin{thm}
    \lipsum[1]

    \lipsum[2]
\end{thm}
\end{document}

What happens is that the theorem header suddenly has a negative indention relative to the page, i.e. starts just a little to the left of the actual page, although I would expect "2.5em-2.5em=0em"... :-)

Endzone
  • 103

2 Answers2

4

I'm not a fan of this kind of indentation. However no solution using \leftskip is good, since theorems are implemented as lists; try adding an enumerate environment to your theorem and see.

Your problem is that you use two different ems: the medium series one and the boldface one, which are different. So the two facts require a different solution.

\documentclass[a4paper]{scrartcl}
\usepackage{amsthm,thmtools}
\usepackage{lipsum}
\usepackage{showframe}

\declaretheoremstyle[
  headfont=\kern-2.5em\bfseries,
  bodyfont=\normalfont,
  headindent=0pt,
]{INDENTthm}
\declaretheorem[
  within=section,
  style=INDENTthm,
  name=Theorem
]{thm}

\usepackage{etoolbox}
\makeatletter
\AtBeginEnvironment{thm}{%
  \patchcmd\@thm
    {\trivlist}
    {\list{}{\leftmargin2.5em\itemindent-15em}}
    {}{}%
  \patchcmd\thmt@original@endthm{\endtrivlist}{\endlist}{}{}%
}
\makeatother

\begin{document}
\begin{thm}
\lipsum*[2]
\begin{enumerate}
\item a
\item b
\end{enumerate}
\end{thm}
\end{document}

This does the patch only for the thm environment. As Zhen Lin correctly remarks in a comment, the

  \patchcmd\thmt@original@endthm{\endtrivlist}{\endlist}{}{}%

line for a theorem named lemma should become

  \patchcmd\thmt@original@endlemma{\endtrivlist}{\endlist}{}{}%

enter image description here

If one has several theorem-like environments and all should share the hanging indentation, then it's better to abstract the procedure. The \xdeclaretheorem command defined below will do just that.

\documentclass[a4paper]{scrartcl}
\usepackage{amsthm,thmtools}
\usepackage{etoolbox}
\usepackage{lipsum}
\usepackage{showframe}

\makeatletter
\patchcmd\@thm
  {\trivlist}
  {\list{}{\leftmargin2.5em\itemindent-15em}}
  {}{}
\newcommand{\xdeclaretheorem}[2][]{%
  \declaretheorem[#1]{#2}%
  \expandafter\patchcmd\csname thmt@original@end#2\endcsname
    {\endtrivlist}{\endlist}{}{}%
}

\declaretheoremstyle[
  headfont=\kern-2.5em\bfseries,
  bodyfont=\normalfont,
  headindent=0pt,
]{INDENTthm}

\xdeclaretheorem[
  within=section,
  style=INDENTthm,
  name=Theorem
]{thm}

\xdeclaretheorem[
  sibling=thm,
  style=INDENTthm,
  name=Lemma
]{lem}

\begin{document}
\begin{thm}
\lipsum*[2]
\begin{enumerate}
\item a
\item b
\end{enumerate}
\end{thm}

\begin{lem}
\lipsum*[2]
\begin{enumerate}
\item a
\item b
\end{enumerate}
\end{lem}
\end{document}

enter image description here

In case only some theorem-like environment should have hanging indentation the code

\AtBeginEnvironment{#2}{%
  \patchcmd\@thm
    {\trivlist}
    {\list{}{\leftmargin2.5em\itemindent-15em}}
    {}{}%
}

should be added to the definition of \xdeclaretheorem and the global patch removed. Of course, non indented environments should use \declaretheorem.

egreg
  • 1,121,712
  • Thanks, this looks like a good solution. What is the "\itemindent-15em" actually needed for? – Endzone Apr 05 '13 at 08:03
  • 1
    It's perhaps worth mentioning that the last three characters in \thmt@original@endthm should also be replaced with the environment name, to prevent problems with “too much nesting”... – Zhen Lin Apr 13 '13 at 11:26
  • Note that the patch has to be delayed if hyperref is used, see https://tex.stackexchange.com/q/550180/4427 – egreg Jun 19 '20 at 19:59
  • Is the AtBeginEnvironment{thm} in your first code for the same purpose as your last comment, namely to delay the patch? If so, is there a preference between that and AtBeginDocument? – user21820 Dec 17 '20 at 14:24
  • @user21820 There's a big difference! The code in \AtBeginEnvironment{thm} is executed every time \begin{thm} is performed (and the code loses its effects at \end{thm}). – egreg Dec 17 '20 at 15:43
  • I know that, but why do you need to patch \@thm more than once? Oh I see you only wanted to patch \thm... – user21820 Dec 17 '20 at 15:46
  • Maybe also note in your post that if one uses cleveref then one needs to patch \cref@thmnoarg and \cref@thmoptarg instead of \@thm? I just spent a long while trying to figure out why my patch was always failing... – user21820 Dec 17 '20 at 15:49
0

I've hardwired the indents, but you should be able to change them to an argument, and restore them to their original

\documentclass{article}
\parindent 0in
\parskip 1em
\let\svpar\par
\newenvironment{hang}{\hangindent 0.7in\def\par{\svpar\hangindent
0.7in\parindent 0.7in}}
{\let\par\svpar\parindent 0in}
\begin{document}

non-indented text

\begin{hang}
erew ewr ewr ew rwe fsgfkgwerlktmn gghlkrgtkj rgngmn
krwghj,gn ghrgtkrkltgrkgfremgrtgklrwtklrgfd,m srjhgksg 

continuing test to new paragraph

finally ending test now
\end{hang}

non-indent

\end{document}

enter image description here