使用 thmtools 进行首字下沉 (lettrine)

使用 thmtools 进行首字下沉 (lettrine)

我想要使​​定理、定义等以首字下沉的形式开始,如下图所示。

在此处输入图片描述

它是用代码生成的

\documentclass{article}

\usepackage{amsthm}
\usepackage{thmtools}
\usepackage{lettrine}
\usepackage{lipsum}

\begin{document}

    \lettrine{D}{efinition.} \lipsum[2]


\end{document}

虽然使用 的方法thmtools会出现错误,但是使用lettrine

\documentclass{article}

\usepackage{amsthm}
\usepackage{thmtools}
\usepackage{lettrine}
\usepackage{lipsum}

\declaretheoremstyle[
headfont=\normalfont\bfseries,
notefont=\mdseries,
headpunct=.,
bodyfont=\normalfont,
postheadspace=0.4em
]{DEFINITIONstyle}

\declaretheorem[%
style=DEFINITIONstyle,%
name=\lettrine{D}{efinition}%
]{Definition}


\begin{document}


    \begin{Definition}
        \lipsum[2]
    \end{Definition}

\end{document}

错误是

! Use of \\declaretheorem doesn't match its definition.
\@ifnextchar ... \reserved@d =#1\def \reserved@a {
                                                  #2}\def \reserved@b {#3}\f...
l.20 ]{Definition}

此外,控制台中还有另一个错误(如果您通过单击 继续编译enter):

?
! Argument of \@lettrine has an extra }.
<inserted text>
                \par
l.20 ]{Definition}

如果我改为name=\lettrine{D}{efinition}name=Definition文件就会成功编译。

我怎样才能达到期望的结果?

答案1

这是可行的,但在我看来,这是一个糟糕的黑客攻击。

楼主的尝试失败的原因是

  1. \lettrine命令排版首字母然后设置段落形状以排版段落的剩余部分。如果你把它放在 的“name”参数中\declaretheoremstyle,事情就会在错误的地方完成。但除此之外,

  2. \declaretheoremstyle\lettrine争论使用相同的临时 LaTeX 变量,其名称如\@tempdima,等等。这就是导致实际错误消息的原因。

解决方法是:

  1. 修改\lettrine命令以将段落形状保存在全局宏中,而不是每次在本地宏中重新计算。这很糟糕,因为该\lettrine命令是一个巨大的整体代码块 - 事实上它几乎是整个lettrine包 - 虽然只需要更改 3 行。

  2. 只需运行\lettrine一次命令,设置单词的排版Definition,并将结果存储在 LaTeX 框中。

  3. 改为\declaretheorem复制包含作品‘定义’的框,并插入预先计算的段落形状来排版每个不同定理的文本。

请注意,该示例仅适用于单一定理类型。如果您需要多种类型(定义、备注、引理、注释等),则需要为每种类型创建一个框,并将段落形状保存\L@parshape在单独的宏中。

\documentclass{article}

\usepackage{amsthm}
\usepackage{thmtools}
\usepackage{lettrine}
\usepackage{lipsum}

% Modify the \@lettrine command to make L@parshape a global variable.

\makeatletter
\def\@lettrine[#1]#2#3{%
  \setcounter{L@lines}{\value{DefaultLines}}%
  \setcounter{L@depth}{\value{DefaultDepth}}%
  \renewcommand*{\L@hang}{\DefaultLhang}%
  \renewcommand*{\L@oversize}{\DefaultLoversize}%
  \renewcommand*{\L@raise}{\DefaultLraise}%
  \renewcommand*{\L@ante}{}%
  \setlength{\L@Findent}{\DefaultFindent}%
  \setlength{\L@Nindent}{\DefaultNindent}%
  \setlength{\L@slope}{\DefaultSlope}%
  \setlength{\L@novskip}{\DiscardVskip}%
  \ifLettrineImage\L@imagetrue\else\L@imagefalse\fi
  \ifLettrineOnGrid\L@gridtrue\else\L@gridfalse\fi
  \ifLettrineRealHeight\L@realhtrue\else\L@realhfalse\fi
  \setkeys{L}{#1}%
  \sbox{\L@tbox}{\LettrineTextFont{\LettrineSecondString}}%
  \ifL@realh
    \def\@tempa{#3}
    \ifx\@tempa\@empty
      \PackageWarning{lettrine.sty}%
        {Empty second argument,\MessageBreak
         ignoring option `realheight';}%
    \else
      \sbox{\L@tbox}{\LettrineTextFont{#3}}%
    \fi
  \fi
  \if\DefaultOptionsFile\relax
  \else
    \begingroup
    \InputIfFileExists{\DefaultOptionsFile}%
      {}%
      {\PackageWarning{lettrine.sty}%
         {File \DefaultOptionsFile\space not found}%
      }%
    \def\color##1##{\l@color{##1}}%
    \let\l@color\@gobbletwo
    \def\textcolor##1##{\l@textcolor{##1}}%
    \def\l@textcolor##1##2##3{##3}%
    \expandafter\ifx\csname l@#2-keys\endcsname\relax
                  \gdef\l@LOKeys{}%
                \else
                  \xdef\l@LOKeys{\csname l@#2-keys\endcsname}%
                \fi
    \endgroup
    \def\KV@prefix{KV@L@}%
    \let\@tempc\relax
    \expandafter\KV@do\l@LOKeys,\relax,
    \sbox{\L@lbox}{\LettrineFont #2}%
    \setlength{\LettrineWidth}{\wd\L@lbox}%
    \def\KV@prefix{KV@L@}%
    \let\@tempc\relax
    \expandafter\KV@do\l@LOKeys,\relax,
    \setkeys{L}{#1}%
  \fi
  \ifL@image
     \sbox{\L@lbox}{\LettrineFontEPS{#2}}%
  \else
     \sbox{\L@lbox}{\LettrineFont #2}%
  \fi
  \sbox{\L@tbox}{\LettrineTextFont{#3}}%
  \@tempdima=\baselineskip
  \ifnum\value{L@lines}=1
    \setlength{\L@first}{\ht\L@lbox}%
    \addtolength{\L@first}{-\ht\L@tbox}%
    \setlength{\L@lraise}{\z@}%
  \else
    \setlength{\L@first}{-\value{L@lines}\@tempdima}%
    \addtolength{\L@first}{\@tempdima}%
    \sbox{\@tempboxa}{\LettrineTextFont x}%
    \addtolength{\L@first}{-\ht\@tempboxa}%
    \setlength{\L@lraise}{-\L@raise\L@first}%
    \addtolength{\L@first}{\L@lraise}%
    \addtolength{\L@first}{\ht\L@lbox}%
    \addtolength{\L@lraise}{-\value{L@lines}\@tempdima}%
    \addtolength{\L@lraise}{\@tempdima}%
  \fi
  \par
  \ifdim\L@first>\L@novskip
    \ifL@grid
      \@tempdima=\baselineskip
      \@tempdimb=\@tempdima
      \advance\@tempdimb by \L@novskip
      \@tempcnta=1
      \loop\ifdim\L@first>\@tempdimb
         \advance\@tempcnta by 1
         \advance\L@first by -\@tempdima
      \repeat
      \vskip\@tempcnta\baselineskip
    \else
      \vskip\L@first
    \fi
  \fi
  \setlength{\L@Pindent}{\wd\L@lbox}%
  \addtolength{\L@Pindent}{-\L@hang\wd\L@lbox}%
  \settowidth{\L@first}{\L@ante}%
  \addtolength{\L@Pindent}{\L@first}%
  \addtolength{\L@Pindent}{\L@Findent}%
  \setlength{\L@first}{\linewidth}%
  \addtolength{\L@first}{-\L@Pindent}%
  \addtolength{\L@Nindent}{\L@Pindent}%
  \setlength{\L@next}{\linewidth}%
  \addtolength{\L@next}{-\L@Nindent}%
  \addtolength{\L@Pindent}{\rightmargin}%
  \addtolength{\L@Nindent}{\rightmargin}%
  \setlength{\LettrineWidth}{\wd\L@lbox}%
  \setlength{\LettrineHeight}{\ht\L@lbox}%
  \setlength{\LettrineDepth}{\dp\L@lbox}%
  \addtocounter{L@lines}{1}%
  \addtocounter{L@lines}{\value{L@depth}}%
  \gdef\L@parshape{\c@L@lines \the\L@Pindent \the\L@first}% CHANGED
  \@tempcnta=\tw@
  \@whilenum \@tempcnta<\c@L@lines\do{%
     \global\edef\L@parshape{\L@parshape \the\L@Nindent \the\L@next}% CHANGED
     \addtolength{\L@Nindent}{\L@slope}%
     \addtolength{\L@next}{-\L@slope}%
     \advance\@tempcnta\@ne}%
  \global\edef\L@parshape{\L@parshape \rightmargin \the\linewidth}% CHANGED
  \noindent
  \parshape=\L@parshape\relax
  \smash{\llap{\mbox{\L@ante}\raisebox{\L@lraise}{\usebox{\L@lbox}}%
         \hskip \the\L@Findent}}%
  \usebox{\L@tbox}%
}

% Run the lettrine command once, save the result in a box, and set up \L@parshape

\newbox\lettrinebox
\setbox\lettrinebox\hbox{\lettrine{D}{efinition}}

\declaretheoremstyle[
headfont=\normalfont\bfseries,
notefont=\mdseries,
headpunct=.,
bodyfont=\normalfont,
postheadspace=0.4em
]{DEFINITIONstyle}

% 'name' parameter copies the saved box.
% 'postheadhook' inserts the parshape created by lettrine.

\declaretheorem[%
style=DEFINITIONstyle,%
name=\copy\lettrinebox,
postheadhook={\parshape=\L@parshape\relax}%
]{Definition}

\makeatother

\begin{document}

    \begin{Definition}
        \lipsum[1]
    \end{Definition}

    \begin{Definition}
        \lipsum[2]
    \end{Definition}

\end{document}

相关内容