3

I would like a theoremstyle-like definition which induces the first letter of the theorem-head to be drop-capped.

I do not intend to use counters, at all, with this style. I fully intend to use other environments like propositions, definitions, etc. that I don't want altered. I'd prefer to just use amsthm; however, I'd look at solutions with ntheorem or thmtools to see if there's any collisions with other things I use.

An MWE is below:

\documentclass{article}
\usepackage{amsmath, amsthm}
\usepackage{lettrine}
\usepackage{type1cm} % scalable fonts (needed for 'T' to top-align with 'h')
\usepackage{blindtext} % filler text

% Global formatting for the example underneath.
% Ideally, these get replaced with local variants.
\renewcommand{\LettrineFontHook}{\bfseries} % drop-cap bold
\renewcommand{\LettrineTextFont}{\bfseries} % first word bold
\setlength{\DefaultNindent}{0em} % better spacing around T on second line
\setlength{\DefaultFindent}{0.125em}  % better spacing around T on first line
\LettrineRealHeighttrue % align the top of T with top of h

% AMS
\theoremstyle{definition}
\newtheorem*{thm}{Theorem}

\begin{document}
    \lettrine{T}{heorem.} \blindtext    % what I want it to look like

    \begin{thm}     %
        \blindtext  % what I'd like the syntax to be
    \end{thm}       %
\end{document}

The reason why I want to limit to amsthm is that the white space placed around theorem environments is perfect. So, an alternate solution could just mimic the spacing. I have tried the following environment definition

\newenvironment{thm}{%
    \noindent\ignorespaces%
    \renewcommand{\LettrineFontHook}{\bfseries}%
    \renewcommand{\LettrineTextFont}{\bfseries}%
    \lettrine[nindent=0em, findent=0.125em, realheight]{T}{heorem.}%
}{
    \renewcommand{\LettrineFontHook}{\scshape}%
    \renewcommand{\LettrineTextFont}{\scshape}%
    \par\noindent\ignorespacesafterend%
}

However, this environment exhibits mixed results. There's too little space when preceded by a body of text. And too much space above it when it begins a section. Spacing after this environment is sometimes good, sometimes not. And I can't reason the whys.

  • 2
    I think what you want is first letter of the theorem head, since label has another meaning in TeX. – Sigur Dec 7 '18 at 16:11
  • amsmath has nothing to do with theorems other than cooperation in the proof environment to get the qed box in the right place. – barbara beeton Dec 8 '18 at 4:45
  • @barbarabeeton low-level user. Thanks for the correction of understanding. – Robert Wolfe Dec 8 '18 at 4:52
  • if no answer has appeared by tomorrow, i'll try to look up the dimension values; i don't have any tex resources on the laptop i'm using now. – barbara beeton Dec 8 '18 at 4:56
2
+50

Here is a version that uses ntheorem to create such theorem environments. Its spacing is identical to that of the amsthm theorem environments.

Theorems are actually list environments with just a single item whose label is the theorem's head. What makes drop-capped theorem heads a little difficult to implement is the fact that \lettrine doesn't just produce the theorem head but also sets the indentation of the first two lines of the theorem. Both amsthm and ntheorem allow you to change the appearance of this label, but amsthm doesn't allow you to insert any code after the theorem head.

With ntheorem this is possible, however. The second and third arguments of ntheorem's \newtheoremstyle are normally of the form \item[…\theorem@headerfont…]… and you can use the third to e.g. change the indentation based on what happened in the item label.

To accomplish this, we need access to \L@parshape (the variable in which the \parshape parameters used by lettrine are stored) from outside the item label, which is why we globally set \dropitem@ps equal to this parameter. We can then use \everypar and \parshape to change the shape of just the next paragraph appropriately.

\documentclass{article}

\usepackage{ntheorem}
\usepackage{lettrine}

\makeatletter %% <- make @ usable in command sequences
%% Create drop-cap theorem head:
\newcommand\dropitem[1]{%
  \item[\hskip\itemsep                    %% <- undo \hskip-\itemsep in dfn. of \item
        \lettthmhead{#1}%                 %% <- print drop-capped theorem head
        \global\let\dropitem@ps\L@parshape]% %% <- store \L@parshape for later
  \expandafter\everypar\expandafter{%     %% <- this is inserted at the start of a par.
    \the\everypar                         %% <- original \everpar (prints thm head)
    \parshape\dropitem@ps\relax           %% <- set parshape for first paragraph
    \everypar{\parshape0\everypar{}}%     %% <- reset for later paragraphs
  }%
  \ignorespaces
}
%% Drop-cap a word:
\def\lettthmhead#1{\@lettthmhead#1\end@lettthmhead} %% <- Peel off the first letter
\def\@lettthmhead#1#2\end@lettthmhead{% %% #1 = first letter, #2 = remainder
  \let\LettrineFontHook\theorem@headerfont
  \let\LettrineTextFont\theorem@headerfont
  \lettrine[nindent=0em, findent=0.125em, realheight,novskip=\maxdimen]{#1}{#2}%
}

%% Declare dropcap theorem style:
\newtheoremstyle{dropcap}
  {\dropitem{##1\ ##2\theorem@separator}}
  {\dropitem{##1\ifundefined{thm@starredenv}{}{\ ##2}\ (##3)\theorem@separator}}
\newtheoremstyle{nonumberdropcap}
  {\dropitem{##1\theorem@separator}}
  {\dropitem{##1\ (##3)\theorem@separator}}

\makeatletter  %% <- revert @

%% Declare theorems:
\theoremstyle{dropcap}
\theorempreskip{\topsep}
\theorempostskip{\topsep}
\theoremseparator{.}
\newtheorem*{thm}{Theorem}
\theorembodyfont{\normalfont}
\theoremheaderfont{\normalfont\scshape}
\newtheorem*{dfn}{Definition}

%% Dummy text
\def\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 a, magna. Donec vehicula augue eu neque.}

\begin{document}

\lipsum

\begin{thm}
    \lipsum \par \lipsum
\end{thm}

\lipsum

\begin{thm}
    \lipsum
\end{thm}

\section{A section}

\begin{dfn}
    \lipsum
\end{dfn}
\begin{thm}
    \lipsum
\end{thm}

\lipsum

\end{document}

( ↓ amsthm output is on the left, output of the above code is on the right ↓ )

output

Note that using \newtheorem instead of \newtheorem* produces numbered versions of these environments.

The output on the left was created using

\usepackage{amsthm}
\usepackage{lettrine}

\newtheorem*{thm}{Theorem}
\theoremstyle{definition}
\newtheorem*{dfn}{Definition}

and the same document content.


Addendum

Incidentally, the (perfect) spacing of the AMS theorems can be reproduced using the trivlist environment with \@topsep=\topsep and \@topsepadd=\topsep. The thmspacing environment below will be surround by the same amount of space as the amsthm theorems in pretty much all situations (because this is effectively how these environments are defined).

\makeatletter
\newenvironment{thmspacing}{%
  \trivlist
  \@topsep=\topsep
  \@topsepadd=\topsep
  \item\ignorespaces
}{%
  \endtrivlist
  \@endpefalse
}
\makeatother

The following environment is in fact pretty much indistinguishable from the one defined above using ntheorem. It requires no packages other than lettrine (but you will need to copy the definitions of \dropitem and \lettthmheadfrom above to use it).

\makeatletter
\newenvironment{thm}{%
  \trivlist
  \@topsep=\topsep
  \@topsepadd=\topsep
  \itshape
  \def\theorem@headerfont{\normalfont\bfseries}
  \dropitem{Theorem.}
}{%
  \endtrivlist
  \@endpefalse
}
\makeatother
  • I've modified this answer significantly because it turns out that this barely requires any hacks with ntheorem. – Circumscribe Dec 18 '18 at 12:48
  • You've given me a reason to modularize my code. I'm getting that sorted out to test this. How's the spacing with \usepackage{type1cm}? Which should strecth out the T a little more to reach the top of the h. I have a suspicion that lettrine dilates some whitespace that doesn't overlap with the whitespace above it already. – Robert Wolfe Dec 19 '18 at 14:17
  • 1
    I hadn't heard of that package before, but I wouldn't expect it to affect vertical spacing. (Also, here is a screenshot). – Circumscribe Dec 19 '18 at 14:44
  • huh. Something was messing with the whitespace that rendered for me (that's why I ended up using \parsep at the start). Must be something else on my end. – Robert Wolfe Dec 19 '18 at 14:47
  • 1
    So, it turns out that lettrine inserts a \vskip if the initial is too tall. This is (1) not allowed inside an item label (causing the missing \endgroup error) and (2) introduces additional space above the environment (which is the problem you were having before). It can be fixed by adding novskip=\maxdimen as an option to \lettrine. – Circumscribe Dec 19 '18 at 19:26
2

I have come up with this monstrosity:

\newtheoremstyle{dropcap}% name of the style to be used
  {\parsep}% measure of space to leave above the theorem.
  {\topsep}% measure of space to leave below the theorem.
  {}% default font to use in the body of the theorem
  {0pt}% NO indenture of theorem head
  {\bfseries}% name of head font --- DOESN'T MATTER
  {}% NO punctuation between head and body
  {0em}% NO space after theorem head;
  {}

\theoremstyle{dropcap}
\newtheorem*{thmx}{} %NO THEOREM NAME

\newenvironment{thm}{
    \ignorespaces%
    \begin{thmx}%
    \renewcommand{\LettrineFontHook}{\bfseries}%
    \renewcommand{\LettrineTextFont}{\bfseries}%
    \lettrine[nindent=0em, findent=0.125em, realheight]{T}{heorem.}%
}{%
    \end{thmx}%
    \renewcommand{\LettrineFontHook}{\scshape}\renewcommand{\LettrineTextFont}{\scshape}%
    \ignorespacesafterend%
}

This breaks several best practices of programming, I know; however, it renders typographically the way I want 98% of the time. The only oddity I've notice is that if the thm environment receives more than one paragraph in its argument, it'll render the second paragraph indenture as if it's trying to do the same thing as it did with the first, but without the "theoremhead". Of course, it'll look odd if the theorem has only a single line in its statement, but that's not a situation I meet.

Any other answer will be an improvement to this one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.