Typesetting ‘lettrines’ in L^{A}TEX 2ε documents

Daniel Flipo

                    Daniel.Flipo@univ-lille1.fr

Copyright 1999-2002 Daniel Flipo. This program can be redistributed and/or modified under the terms of the LaTeX Project Public License Distributed from CTAN archives in directory macros/latex/base/lppl.txt; either version 1 of the License, or any later version. NO PERMISSION is granted to produce or to distribute a modified version of this file under its original name.

1 Introduction

The file lettrine.dtx^{1}, provides a command \lettrine which requires two mandatory arguments, and an optional one. Adding \usepackage{lettrine} in the preamble of a document defines the command \lettrine, the simplest use of which is \lettrine{<letter>}{<text>}. It produces a dropped capital <letter> (2 lines high), followed by <text> typeset in small caps, and the rest of the paragraph is wrapped around the dropped capital. Various parameters are provided to control the size and layout of the dropped capital and match the requirements described in the books

• “Lexique des règles typographiques en usage à l’Imprimerie nationale” troisième édition (1994), ISBN-2-11-081075-0,

• “Mise en page et impression” Yves Perrousseaux, ISBN-2-911220-01-3.

The parameters can be set using David Carlisle’s keyval.sty syntax:

• lines=<integer> sets how many lines the dropped capital will occupy (default=2);

• lhang=<decimal> (0 ≤ lhang ≤ 1) sets how much of the dropped capital’s width should hang into the margin (default=0);

• loversize=<decimal> (−1 < loversize ≤ 1) enlarges the dropped capital’s height: with loversize=0.1 its height is enlarged by 10% so that it raises above the top paragraph’s line (default=0);

• lraise=<decimal> does not affect the dropped capital’s height, but moves it up (if positive), down (if negative); useful with capitals like J or Q which have a positive depth, (default=0);

• findent=<dimen> (positive or negative) controls the horizontal gap between the dropped capital and the indented block of text (default=0pt);

• nindent=<dimen> shifts all indented lines, starting from the second one, horizontally by <dimen> (this shift is relative to the first line, default=0.5em); • slope=<dimen> can be used with dropped capitals like A or V to add

1The file described in this section has version number v1.4 and was last revised on 2002/10/26.

<dimen> (positive or negative) to the indentation of each line starting from the third one (no effect if lines=2, default=0pt);

• ante=<text> can be used to typeset <text> before the dropped capital (typical use is for French guillemots starting the paragraph).

Example: \lettrine[lines=4, lraise=0.1, nindent=0em,  slope=-.5em]%
                   {V}{oici} un exemple . . .

Once lettrine.sty will be installed (run latex on lettrine.ins to extract it), compile and print demo.tex to see the possible usage of these parameters. The default settings can be customized either in a config file lettrine.cfg (for a global usage), or on a per document basis, in the preamble of each document. The following list shows the syntax to set them and their default values:

   • \setcounter{DefaultLines}{2},
   • \renewcommand{\DefaultLoversize}{0},
   • \renewcommand{\DefaultLraise}{0},
   • \renewcommand{\DefaultLhang}{0},
   • \setlength{\DefaultFindent}{0pt},
   • \setlength{\DefaultNindent}{0.5em},
   • \setlength{\DefaultSlope}{0pt}.

\LettrineTextFont sets the font used for the second argument of \lettrine,

its default definition is \newcommand{\LettrineTextFont}{\scshape} (second

argument in small caps, this can be changed using \renewcommand). \LettrineFont sets the font used for the dropped capital, usually the current font in a (large) size, computed automatically from the number of lines it will fill: the font size is computed so that, a standard dropped capital (say X, not À) when sitting on its baseline, gets its top aligned with the top of the following text (provided loversize = 0 and lines ≥ 2). When lines = 1, size is computed as if lines was 2. A hook \LettrineFontHook is provided to change the font used for the dropped capital, syntax follows L^{A}TEX’s low-level font interface (see L^{A}TEX Companion, p.187–192), the \selectfont command is issued by \LettrineFont:

\renewcommand{\LettrineFontHook}{\fontfamily{ppl}\fontseries{bx}}%
                                 \fontshape{sl}},

selects Palatino bold expanded slanted for the dropped capital. Another definition, \LettrineFontEPS, is provided for dropped capitals defined as EPS files, see file demo.tex for examples of its usage.

Important notice: the sizing works fine with fully scalable fonts (like the standard PostScript fonts), but might not work well with CM/EC fonts which have two limitations: only a limited number of sizes is available by default (precise adjustments are impossible), and the largest size (25pt or 35pt) is often too small. The CM fonts are now available in PostScript type1 format for free (courtesy of BlueSky/Y&Y), to make them fully scalable, it is mandatory to add \usepackage{type1cm} in the preamble of your document. The EC fonts are also available in type1 format for free (thanks to Vladimir Volovich, they are called cm-super), and adding \usepackage{type1ec} ^{2} in the preamble will make them fully scalable too. So, if you want lettrine.sty to work properly with CM or EC fonts, you will need PostScript versions of these fonts and one of the packages type1cm.sty or type1ec.sty. You can still consider using one of the standard PostScript fonts (Times, Palatino,…) though, they are fully scalable too!

Known problems:

• nothing is done to prevent page-breaking in a paragraph starting with a dropped capital; when it happens to hang into the footer, page-breaking has to be done manually;

• \lettrine works within ‘quote’ ‘quotation’, ‘abstract’ environments but does not work within ‘center’ environments (except with option [lines=1]);

• \lettrine does not work within lists;

• if a list has to be included in a paragraph starting with a ‘lettrine’, it is necessary to add the command \parshape=0 just after the end of the list (starting a new paragraph just before or just after the list works too).

2 TEXnical details

This package only runs with L^{A}TEX 2ε and requires keyval.sty

1 ⟨∗code⟩

 2 %% Please report errors to: Daniel.Flipo@univ-lille1.fr
 3 %%
 4 \NeedsTeXFormat{LaTeX2e}[1995/12/01] \RequirePackage{keyval}

Default initializations: define the necessary counters, lengths, and commands to hold the default settings and set these default settings.

 5 \newcounter{DefaultLines}
 6 \setcounter{DefaultLines}{2}
 7 \newcommand{\DefaultLoversize}{0}
 8 \newcommand{\DefaultLraise}{0}
 9 \newcommand{\DefaultLhang}{0}
10 \newdimen\DefaultFindent
11 \setlength{\DefaultFindent}{\z@}
12 \newdimen\DefaultNindent
13 \setlength{\DefaultNindent}{0.5em}
14 \newdimen\DefaultSlope
15 \setlength{\DefaultSlope}{\z@}

Then let’s define the necessary internal counters, lengths, and commands.

16 \newsavebox{\L@lbox}
17 \newsavebox{\L@tbox}
18 \newcounter{L@lines}
19 \newdimen\L@Pindent
20 \newdimen\L@Findent

2This package, available on CTAN, was first released on 2002/07/30.

21 \newdimen\L@Nindent
22 \newdimen\L@lraise
23 \newdimen\L@first
24 \newdimen\L@next
25 \newdimen\L@slope
26 \newdimen\L@height
27 \newcommand{\L@hang}{}
28 \newcommand{\L@oversize}{}
29 \newcommand{\L@raise}{}
30 \newcommand{\L@ante}{}

Provide commands for the fonts used to typeset the two mandatory arguments of

\lettrine.

\LettrineTextFont In French, small caps usually follow the dropped capital.

31 \newcommand{\LettrineTextFont}{\scshape}

\LettrineFont \LettrineFontHook \LettrineFontEPS The default size for the dropped capital is computed so that the top of it is exactly aligned with the top of the following text; an extra height (positive or negative) may be added with Defaultloversize or an optional argument loversize=. If lines=1, the default size for the dropped capital is computed as if lines=2. \Lettrine@height computes the wished height for the dropped capital and stores it into \L@height. As \baselineskip might be a rubber length, we convert it into a ‘dimen’ using \@tempdima. \LettrineFontHook enables to select another font for the dropped capital. Its default definition is empty (the current text font is used).

32 \def\Lettrine@height{%
33 \@tempdima=\baselineskip
34 \setlength{\L@height}{\theL@lines\@tempdima}%
35 \ifnum\theL@lines>1%
36  \addtolength{\L@height}{-\@tempdima}%
37 \fi
38 \sbox{\L@tbox}{\LettrineTextFont x}%
39 \addtolength{\L@height}{\ht\L@tbox}%
40 \addtolength{\L@height}{\L@oversize\L@height}}
41 \newcommand{\LettrineFontHook}{}
42 \newcommand{\LettrineFont}{%
43 \Lettrine@height

\L@height now holds the exact height required for the dropped capital, setting \fontsize to that height would not give the expected result (capital too small), some computing has to be done: we measure how high an ‘X’ capital would be and compute a scaling factor (always ≥ 1).

44 \sbox{\L@tbox}{\LettrineFontHook\fontsize{\L@height}{\L@height}%
45  \selectfont X}%

Arithmetic calculations convert the dimensions into integers (in sp) and compute a (4 decimal accurate) scaling factor.

46 \@tempcntb=\ht\L@tbox
47 \@tempcnta=\L@height
48 \multiply\@tempcnta by 100%
49 \divide\@tempcntb by 100%
50 \divide\@tempcnta by \@tempcntb
51 \advance\@tempcnta by -9999%

52 \ifnum\@tempcnta>0%
53  \def\@tempa{1.\the\@tempcnta}%
54 \else
55  \def\@tempa{1}%
56 \fi
57 \LettrineFontHook
58 \fontsize{\@tempa\L@height}{\@tempa\L@height}%
59 \selectfont}

The following definition is for use with dropped capitals defined as EPS files (see examples in demo.tex). Its use requires the graphicx package to be loaded in the preamble with \usepackage{graphicx}. The required size is computed just as in the standard case, \includegraphics prints the EPS file at this size.

60 \newcommand{\LettrineFontEPS}{%
61 \Lettrine@height
62 \includegraphics[height=\L@height]}

Set up keyval initializations.

63 \define@key{L}{lines}{\setcounter{L@lines}{#1}}
64 \define@key{L}{lhang}{\renewcommand{\L@hang}{#1}}
65 \define@key{L}{loversize}{\renewcommand{\L@oversize}{#1}}
66 \define@key{L}{lraise}{\renewcommand{\L@raise}{#1}}
67 \define@key{L}{ante}{\renewcommand{\L@ante}{#1}}
68 \define@key{L}{findent}{\setlength{\L@Findent}{#1}}
69 \define@key{L}{nindent}{\setlength{\L@Nindent}{#1}}
70 \define@key{L}{slope}{\setlength{\L@slope}{#1}}

Now let’s define \lettrine.

\Lettrine
71 \def\lettrine{\@ifnextchar[\@lettrine{\@lettrine[]}}
72 \def\@lettrine[#1]#2#3{%

First reset the parameters to their default values, then read the optional argument: the keyval package will set the parameters mentioned calling \define@key (see above).

73 \setcounter{L@lines}{\theDefaultLines}%
74 \renewcommand{\L@hang}{\DefaultLhang}%
75 \renewcommand{\L@oversize}{\DefaultLoversize}%
76 \renewcommand{\L@raise}{\DefaultLraise}%
77 \renewcommand{\L@ante}{}%
78 \setlength{\L@Findent}{\DefaultFindent}%
79 \setlength{\L@Nindent}{\DefaultNindent}%
80 \setlength{\L@slope}{\DefaultSlope}%
81 \setkeys{L}{#1}%

Save the two mandatory arguments of \lettrine into two boxes, this will help measuring their sizes.

82 \sbox{\L@lbox}{\LettrineFont #2}%
83 \sbox{\L@tbox}{\LettrineTextFont #3}%

Start a new paragraph, skipping the necessary amount of space if the dropped capital sticks out the top of paragraph. We use \L@first to compute the amount of space to be skipped. Again, as \baselineskip might be a rubber length, we convert it into a ‘dimen’ using \@tempdima.

 84 \@tempdima=\baselineskip
 85 \ifnum\theL@lines=1%
 86  \setlength{\L@first}{\ht\L@lbox}%
 87  \addtolength{\L@first}{-\ht\L@tbox}%
 88  \setlength{\L@lraise}{\z@}%
 89 \else
 90  \setlength{\L@first}{-\theL@lines\@tempdima}%
 91  \addtolength{\L@first}{\@tempdima}%
 92  \sbox{\@tempboxa}{\LettrineTextFont x}%
 93  \addtolength{\L@first}{-\ht\@tempboxa}%

Now, \L@first holds (the opposite of) the raw height of a standard dropped capital (like ’X’), excluding the effect of \L@oversize. This is the basis for \L@raise

 (and \L@oversize, see \LettrineFont).
 94  \setlength{\L@lraise}{-\L@raise\L@first}%
 95  \addtolength{\L@first}{\L@lraise}%
 96  \addtolength{\L@first}{\ht\L@lbox}%
 97  \addtolength{\L@lraise}{-\theL@lines\@tempdima}%
 98  \addtolength{\L@lraise}{\@tempdima}%
 99 \fi
100 \par
101 \ifdim\L@first>0.2\p@\vskip\L@first\fi

Again, we (mis)use the length \L@first to compute the width of the text eventually coming before the dropped capital. It is reset later on to hold the first line’s length.

102 \setlength{\L@Pindent}{\wd\L@lbox}%
103 \addtolength{\L@Pindent}{-\L@hang\wd\L@lbox}%
104 \settowidth{\L@first}{\L@ante}%
105 \addtolength{\L@Pindent}{\L@first}%
106 \addtolength{\L@Pindent}{\L@Findent}%
107 \setlength{\L@first}{\linewidth}%
108 \addtolength{\L@first}{-\L@Pindent}%

Now let’s compute \L@Nindent and \L@next for the next lines.

109 \addtolength{\L@Nindent}{\L@Pindent}%
110 \setlength{\L@next}{\linewidth}%
111 \addtolength{\L@next}{-\L@Nindent}%

This is for quotation, quote, abstract… environments: \linewidth is set by these environments, all we have to do is to shift our text left by \rightmargin (amount of space locally added to \leftmargin in these environments).

112 \addtolength{\L@Pindent}{\rightmargin}%
113 \addtolength{\L@Nindent}{\rightmargin}%

Now, set up the shape of the new paragraph (designed by \parshape).

114 \addtocounter{L@lines}{1}%
115 \def\L@parshape{\c@L@lines \the\L@Pindent \the\L@first}%
116 \@tempcnta=\tw@
117 \@whilenum \@tempcnta<\c@L@lines\do{%
118  \edef\L@parshape{\L@parshape \the\L@Nindent \the\L@next}%
119  \addtolength{\L@Nindent}{\L@slope}%
120  \addtolength{\L@next}{-\L@slope}%
121  \advance\@tempcnta\@ne}%
122 \edef\L@parshape{\L@parshape \rightmargin \the\linewidth}%

123 \noindent\leavevmode
124 \parshape=\L@parshape

Write the dropped capital into the left margin, and wrap the rest of paragraph around it.

125 $\smash{\llap{\mbox{\L@ante}\raisebox{\L@lraise}{\usebox{\L@lbox}}%
126  \hskip \the\L@Findent}}$%
127 \usebox{\L@tbox}}

This ends the definition of \lettrine. Load a local config file if present in L^{A}TEX’s search path.

128 \InputIfFileExists{lettrine.cfg}{}{}

129 ⟨/code⟩