我想要使定理、定义等以首字下沉的形式开始,如下图所示。
它是用代码生成的
\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
这是可行的,但在我看来,这是一个糟糕的黑客攻击。
楼主的尝试失败的原因是
该
\lettrine
命令排版首字母然后设置段落形状以排版段落的剩余部分。如果你把它放在 的“name”参数中\declaretheoremstyle
,事情就会在错误的地方完成。但除此之外,\declaretheoremstyle
并\lettrine
争论使用相同的临时 LaTeX 变量,其名称如\@tempdima
,等等。这就是导致实际错误消息的原因。
解决方法是:
修改
\lettrine
命令以将段落形状保存在全局宏中,而不是每次在本地宏中重新计算。这很糟糕,因为该\lettrine
命令是一个巨大的整体代码块 - 事实上它几乎是整个lettrine
包 - 虽然只需要更改 3 行。只需运行
\lettrine
一次命令,设置单词的排版Definition
,并将结果存储在 LaTeX 框中。改为
\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}