You are on page 1of 14

Rolling your own Document Class:

Using LATEX to keep away from the Dark Side

Peter Flynn
Silmaril Consultants
peter (at) silmaril dot ie
http://silmaril.ie/cgi-bin/blog

Abstract
Document classes in LATEX provide automation to improve consistency, produc-
tivity, and accuracy in creating and maintaining documents, thereby avoiding the
inefficiencies of wordprocessors. However, users who want to package their macros
or applications as a document class are often put off by the apparent complexity
of the sample classes in the standard distribution. This paper describes what the
code in the article document class file does and suggests solutions to some of the
popular requirements for changes.

1 Know thine enemy 1.1 Standard document classes


One of the key features of TEX systems is the ex- The standard document classes installed with LATEX
tensibility offered by re-usable pieces of program- (article, report, book, and letter) were written in a hy-
ming called macros. Rudimentary macros exist brid of LATEX and plain TEX code. Sometimes this
in many text-handling packages (in fact they were was because the function Lamport wanted was not
at the heart of the first editors for markup ap- worth writing a single-use LATEX macro for; some-
plications), and some wordprocessors make use of times it is because (as Knuth describes in another
general-purpose programming languages such as context) TEX is only half obedient while these
Visual Basic or Java; but only typesetters have ded- definitions are half finished [4, p. 352]; and some-
icated languages to doing typesetting, and TEXs is times because of the need mentioned above to per-
by far the most accessible. form lower-level functions. While the LATEX 2 de-
This has led to several large and well-known velopers and maintainers have replaced much of the
macro packages (LATEX, ConTEXt, Texinfo, Eplain, earlier plain TEX code with updated LATEX equiva-
etc) which have all but taken the place of Knuths lents, the code remains fairly dense and is not im-
original language as the end-users primary inter- mediately obvious to the beginner; and the mix of
faces. Most users now only have to use the macro syntax variants can be confusing to the user accus-
commands of their chosen interface instead of hav- tomed to the fairly small set of commands used for
ing to write their own macros afresh or maintain a common LATEX documents. Plain TEX itself has
large private collection of personal macros. some 900 control sequences (commands) of which
This is not to say that there is no place for about 350 are primitives (indivisible low-level op-
homebrew macros in plain TEX: some people have erations), whereas many regular LATEX users get by
perfectly valid reasons for avoiding the aforemen- with some 2030 commands, if even that.
tioned packages and continuing to use TEX in the Users who have started to write their own
raw. Using one of the above standards does not macros, or who have encountered the need to mod-
always mean that you avoid raw TEX in your own ify LATEXs defaults for whatever reason, sometimes
code, because you may need some advanced oper- find the need to encapsulate their favourite format
ations which operate at a lower level than normal. as a document class, governing the entire document,
It nevertheless remains true that the use of macros rather than just a package (style file) handling one
to perform groups of frequently-used functions pro- or two specific features. In this paper we will dissect
vides a level of automation not found in most word- one of the common document classes and examine
processing systems, and is a major factor in helping what the features and functions are.
users become and remain more productive.
1.2 Caveats
This paper uses the article class as the example. The
book and report classes are structured very similarly

110 TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference
Rolling your own Document Class: Using LATEX to keep away from the Dark Side

and the user who has examined the following sec- 2.1 Version and identification
tions should have no difficulty in identifying the dif- The first thing a document class or package must do
ferences. is identify itself by name, and specify the oldest ver-
The letter class, however, is a very different ani- sion of LATEX with which it will work (it is assumed
mal. It implements a vertically-centered format once that it will therefore work with all later versions).
common in typewritten letters but rarely seen nowa- article.cls
days, and has no provision for many of the features 54 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
users expect to be able to find in a letter template. 55 \ProvidesClass{article}
For this reason I do not refer any further to this 56 [2004/02/16 v1.4f
format. 57 Standard LaTeX document class]
The ConTEXt system implements a different
and extensible set of document classes including In your new document class file you should set
letters in a radically different manner to LATEX the date and version to the earliest version you have
and has been discussed and presented extensively in tested your code with (probably your current ver-
recent years. The Eplain macros implement many sion). The name of the document class being pro-
of the features of the LATEX internal mechanisms, vided gets checked against the name requested in the
but without imposing any document format at all, \documentclass declaration, and LATEX will give a
leaving the plain TEX user free to write those herself. warning if there is a discrepancy. You may provide a
label for the class as well: this will appear in the log
1.3 More background
file. The linebreaks and indentation are for human
The essential documentation to read before you start readability only.
writing your own classes is LATEX 2 for class and
package writers [8] (available on all modern TEX \NeedsTeXFormat{LaTeX2e}[1995/12/01]
installations by typing texdoc clsguide, and The \ProvidesClass{ladingbill} [2006/07/01 v0.01 Bill of Lading
LATEX Companion [6, App : A.4]. These describe in specialist LaTeX document class]
detail the additional commands available to class
and package authors. There are also some spe- 2.2 Initial code and compatibility
cial declarations explained in Companion [6, p. 847].
The article by Hefferon [3] which I refer to later is a On a number of occasions, classes define values as
good example of how to build on an existing class. null or a default for later use, so that subsequent
If you have to deal with an obsolete LATEX 2.09 style code wont trip up as it would if they were undefined.
file, there is an older paper in TUGboat [1]. In most cases you will probably need to keep the
internal definitions (such as \@ptsize here) for use
2 Dissection of article.cls later on (see section 2.4.1 on p. 113).2
article.cls
In this example, we use the file from the TEX Live
58 \newcommand\@ptsize{}
2005 distribution (so the line numbers refer to that
59 \newif\if@restonecol
version only). Lines 153 are comments and are
60 \newif\if@titlepage
omitted here for brevity: they explain where the file
61 \@titlepagefalse
came from and how it can be used. This is auto-
generated because the document class and pack- The conditionals \if@restonecol (which flags
age files in the standard distributions of LATEX are the restoration of one-column layout after using
derived from master copies maintained in docTEX LATEXs built-in two-column usage, as distinct from
(.dtx) format [7], which combines documentation using the multicol package) and \if@titlepage
and LATEX code in a single file, much in the same (which flags use of the separate title-page layout
way that Knuths WEB system does for many pro- set to false in the following line) are used in the
gramming languages [9].1 A short explanation of default \maketitle command in section 2.4.4 on
the sources of the class files is in the TEX FAQ [2,
2 The use of the @ sign may be unfamiliar to newcomers:
label : ltxcmds].
in normal LATEX it is classified as an other character [4,
p. 37]. This means it cannot be used as part of a control
sequence (command) in your document. But in class and
1 If you intend making your document class available to package files, LATEX reclassifies it as a letter, and uses it in
the rest of the LATEX community (eg via CTAN), you should command definitions which are intended to be inaccessible
make it a docTEX document so that you can combine docu- to the normal user. Its use here indicates that the \@ptsize
mentation with your code. Actually, you should probably be command is going to be given a value that the end-user should
doing this anyway. . . not be able to interfere with, or even know exists.

TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference 111
Peter Flynn

p. 116. If youre planning to rewrite \maketitle to In some cases you may be writing for a highly
your own design you may need to take these condi- specific environment such as your own office or em-
tionals into account.3 ployer, where only one size is required. If so, just
If you are going to invoke additional pack- omit all the other declarations and add the one op-
ages to provide facilities needed by your options, tion to the \ExecuteOptions command (see sec-
use the \RequirePackage command here, before tion 2.3.4 on p. 113).
the options section. If the additional packages are
unconnected with your option definitions, use the 2.3.2 Type sizes and layout options
\RequirePackage command after the options are As mentioned above, the compatibility settings in
executed (see section 2.3.4 on p. 113). this block can be removed in your own class, because
modern class files use default option settings via the
2.3 Options \DeclareOption command instead.
In an ideal world we wouldnt have to support obso- article.cls
lete versions of software, but the LATEX defaults still 86 \if@compatibility
allow v2.09-type \documentstyle declarations to be 87 \renewcommand\@ptsize{0}
processed, with a warning. However, for a modern 88 \else
class file this is not necessary, so in your own class 89 \DeclareOption{10pt}{\renewcommand\@ptsize{0}}
you can omit all the tests for \@ifcompatibility 90 \fi
and their \else and terminating \fi commands, 91 \DeclareOption{11pt}{\renewcommand\@ptsize{1}}
here and throughout, leaving just the code that was 92 \DeclareOption{12pt}{\renewcommand\@ptsize{2}}
in the \else blocks. 93 \if@compatibility\else
94 \DeclareOption{oneside}{\@twosidefalse \@mparswitchfalse}
2.3.1 Paper sizes 95 \fi
How many paper size options you want to support 96 \DeclareOption{twoside}{\@twosidetrue \@mparswitchtrue}
in your class is entirely up to you. You should allow 97 \DeclareOption{draft}{\setlength\overfullrule{5pt}}
at least A4 and Letter for normal office work. 98 \if@compatibility\else
article.cls 99 \DeclareOption{final}{\setlength\overfullrule{0pt}}
62 \if@compatibility\else 100 \fi
63 \DeclareOption{a4paper}
64 {\setlength\paperheight {297mm}% 101 \DeclareOption{titlepage}{\@titlepagetrue}
65 \setlength\paperwidth {210mm}} 102 \if@compatibility\else
66 \DeclareOption{a5paper} 103 \DeclareOption{notitlepage}{\@titlepagefalse}
67 {\setlength\paperheight {210mm}% 104 \fi
68 \setlength\paperwidth {148mm}}
69 \DeclareOption{b5paper} 105 \if@compatibility\else
70 {\setlength\paperheight {250mm}% 106 \DeclareOption{onecolumn}{\@twocolumnfalse}
71 \setlength\paperwidth {176mm}} 107 \fi
72 \DeclareOption{letterpaper}
108 \DeclareOption{twocolumn}{\@twocolumntrue}
73 {\setlength\paperheight {11in}%
74 \setlength\paperwidth {8.5in}} 109 \DeclareOption{leqno}{\input{leqno.clo}}
75 \DeclareOption{legalpaper} 110 \DeclareOption{fleqn}{\input{fleqn.clo}}
76 {\setlength\paperheight {14in}% 111 \DeclareOption{openbib}{%
77 \setlength\paperwidth {8.5in}}
78 \DeclareOption{executivepaper}
112 \AtEndOfPackage{%
79 {\setlength\paperheight {10.5in}% 113 \renewcommand\@openbib@code{%
80 \setlength\paperwidth {7.25in}} 114 \advance\leftmargin\bibindent
81 \DeclareOption{landscape} 115 \itemindent -\bibindent
82 {\setlength\@tempdima {\paperheight}%
83 \setlength\paperheight {\paperwidth}%
116 \listparindent \itemindent
84 \setlength\paperwidth {\@tempdima}} 117 \parsep \z@
85 \fi 118 }%
119 \renewcommand\newblock{\par}}%
3
120 }
How much to cater for and how much to ignore will
depend on how much your class deviates from the default.
Many LATEX users will expect to be able to use options like The other options should probably be retained,
twocolumn and titlepage simply because they are available as users may expect them to work, bearing in mind
in the default classes. But if you are writing a much more
the comment about two-column and title-page set-
prescriptive format, you may want to remove these options
entirely, which means removing all references to conditional tings above. Note that the openbib declaration is
flags which depend on them. 10 lines long, and defers itself to end of the package

112 TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference
Rolling your own Document Class: Using LATEX to keep away from the Dark Side

as a \renewcommand so that it doesnt conflict with 2.4.1 Type size


the command being declared later. To invoke the right settings, the \@ptsize command
As with paper sizes above, if your class only is embedded in the argument to an \input com-
needs one specific size setup, just invoke it in mand:
\ExecuteOptions. article.cls
123 \input{size1\@ptsize.clo}
2.3.3 Your own options 124 \setlength\lineskip{1\p@}
Now is the time to add your own option declarations, 125 \setlength\normallineskip{1\p@}
if any. Note that option names have no backslash; 126 \renewcommand\baselinestretch{}
otherwise the \DeclareOption command works the 127 \setlength\parskip{0\p@ \@plus \p@}
same way as the \newcommand command (but with
no parameters). A number of basic settings are then made using
Details of how to preserve the options of an ex- the internal definition of a point (\p@). The class
isting class you are borrowing via the \LoadClass option files contain a lot of other size-specific set-
command are discussed in section 3.1 on p. 122. tings as well as the font size specifications for the
chosen body size.
2.3.4 Applying options
Two commands control when the options are ap- 2.4.1.1 Identity and basic sizes The class op-
plied: tion files (we show size10.clo here) identify them-
selves in the same way as class files, but using the
\ProvidesFile instead of \ProvidesClass.
article.cls size10.clo
121 \ExecuteOptions{letterpaper,10pt,oneside,onecolumn,final} 54 \ProvidesFile{size10.clo}
55 [2004/02/16 v1.4f
122 \ProcessOptions
56 Standard LaTeX file (size option)]
57 \renewcommand\normalsize{%
58 \@setfontsize\normalsize\@xpt\@xiipt
\ExecuteOptions applies all the options you
59 \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@
specify in the argument, in order, as your selected 60 \abovedisplayshortskip \z@ \@plus3\p@
defaults. The \ProcessOptions command then 61 \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
applies any options the user has selected in their 62 \belowdisplayskip \abovedisplayskip
\documentclass declaration. 63 \let\@listi\@listI}
64 \normalsize
2.4 Layout 65 \newcommand\small{%
A large number of size and shape settings depend 66 \@setfontsize\small\@ixpt{11}%
on the selected point size (default 10pt, otherwise 67 \abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@
as selected in your options). The exact sizes of 68 \abovedisplayshortskip \z@ \@plus2\p@
type chosen for all the different type-size commands 69 \belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@
70 \def\@listi{\leftmargin\leftmargini
are kept in three Class Option files, size10.clo,
71 \topsep 4\p@ \@plus2\p@ \@minus2\p@
size11.clo, and size12.clo. There are some oth- 72 \parsep 2\p@ \@plus\p@ \@minus\p@
ers available from CTAN, such as James Kilfigers 73 \itemsep \parsep}%
size14.clo for readers needing larger type editions, 74 \belowdisplayskip \abovedisplayskip
but the three mentioned above cover the vast ma- 75 }
jority of normal text setting. 76 \newcommand\footnotesize{%
If you are going to invoke additional packages 77 \@setfontsize\footnotesize\@viiipt{9.5}%
that are unconnected with your option definitions, 78 \abovedisplayskip 6\p@ \@plus2\p@ \@minus4\p@
put the \RequirePackage commands here (see sec- 79 \abovedisplayshortskip \z@ \@plus\p@
tion 3.2 on p. 122). Be aware that some packages 80 \belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@
expect certain variables or definitions already to be 81 \def\@listi{\leftmargin\leftmargini
82 \topsep 3\p@ \@plus\p@ \@minus\p@
present, so their invocation may need to be deferred
83 \parsep 2\p@ \@plus\p@ \@minus\p@
until after everything else. In this case, enclose the 84 \itemsep \parsep}%
\RequirePackage command in a \AtEndOfPackage 85 \belowdisplayskip \abovedisplayskip
or \AtBeginDocument command. This will invoke 86 }
the package[s] at the specified point in processing, 87 \newcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt}
and thus avoid error messages or interference with 88 \newcommand\tiny{\@setfontsize\tiny\@vpt\@vipt}
code in the class file that has not yet been executed. 89 \newcommand\large{\@setfontsize\large\@xiipt{14}}

TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference 113
Peter Flynn

90 \newcommand\Large{\@setfontsize\Large\@xivpt{18}} 121 \else


91 \newcommand\LARGE{\@setfontsize\LARGE\@xviipt{22}} 122 \setlength\textwidth{\@tempdima}
92 \newcommand\huge{\@setfontsize\huge\@xxpt{25}} 123 \fi
93 \newcommand\Huge{\@setfontsize\Huge\@xxvpt{30}} 124 \else
125 \ifdim\@tempdima>\@tempdimb\relax
The first block defines the standard LATEX sizes. 126 \setlength\textwidth{\@tempdimb}
These are named using roman numerals (eg \@xiipt 127 \else
for 12pt) because digits are not allowed in control se- 128 \setlength\textwidth{\@tempdima}
quence names. The more frequently-used sizes also 129 \fi
define the display math spacing and the spacing for 130 \fi
top-level lists (list definition names also use roman 131 \fi
numerals like \@listi). 132 \if@compatibility\else
133 \@settopoint\textwidth
2.4.1.2 Spacing This section controls para- 134 \fi
graph indentation (differing between one-column 135 \if@compatibility
and two-column setting); the dimensions of the three 136 \setlength\textheight{43\baselineskip}
shortcut spacing commands (small, med, and big) 137 \else
but not the actual commands themselves, which are 138 \setlength\@tempdima{\paperheight}
defined in LATEX itself; and some top-of-page and 139 \addtolength\@tempdima{-2in}
bottom-of-page spacing settings (normally reset us- 140 \addtolength\@tempdima{-1.5in}
ing the geometry package). 141 \divide\@tempdima\baselineskip
size10.clo 142 \@tempcnta=\@tempdima
94 \if@twocolumn 143 \setlength\textheight{\@tempcnta\baselineskip}
95 \setlength\parindent{1em} 144 \fi
96 \else 145 \addtolength\textheight{\topskip}
97 \setlength\parindent{15\p@}
98 \fi (The compatibility-mode settings were absolute
99 \setlength\smallskipamount{3\p@ \@plus 1\p@ \@minus 1\p@} values in points.) As with paper size and type size,
100 \setlength\medskipamount{6\p@ \@plus 2\p@ \@minus 2\p@} you can preselect exact values for the text area and
101 \setlength\bigskipamount{12\p@ \@plus 4\p@ \@minus 4\p@} margins (see next section) using the geometry pack-
102 \setlength\headheight{12\p@} age.
103 \setlength\headsep {25\p@}
104 \setlength\topskip {10\p@}
105 \setlength\footskip{30\p@} 2.4.1.4 Page margins Margins also depend on
106 \if@compatibility \setlength\maxdepth{4\p@} \else the column settings, and on the one-side/two-side
107 \setlength\maxdepth{.5\topskip} \fi setting.
size10.clo
146 \if@twocolumn
2.4.1.3 Text area Text width and text height 147 \setlength\marginparsep {10\p@}
are set to depend on the columnar setting and a 148 \else
multiple of line-heights respectively. 149 \setlength\marginparsep{11\p@}
size10.clo 150 \fi
108 \if@compatibility 151 \setlength\marginparpush{5\p@}
109 \if@twocolumn 152 \if@compatibility
110 \setlength\textwidth{410\p@} 153 \if@twoside
111 \else 154 \setlength\oddsidemargin {44\p@}
112 \setlength\textwidth{345\p@} 155 \setlength\evensidemargin {82\p@}
113 \fi 156 \setlength\marginparwidth {107\p@}
114 \else 157 \else
115 \setlength\@tempdima{\paperwidth} 158 \setlength\oddsidemargin {63\p@}
116 \addtolength\@tempdima{-2in} 159 \setlength\evensidemargin {63\p@}
117 \setlength\@tempdimb{345\p@} 160 \setlength\marginparwidth {90\p@}
118 \if@twocolumn 161 \fi
119 \ifdim\@tempdima>2\@tempdimb\relax 162 \if@twocolumn
120 \setlength\textwidth{2\@tempdimb} 163 \setlength\oddsidemargin {30\p@}

114 TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference
Rolling your own Document Class: Using LATEX to keep away from the Dark Side

164 \setlength\evensidemargin {30\p@} size10.clo


165 \setlength\marginparwidth {48\p@} 209 \setlength\footnotesep{6.65\p@}
166 \fi 210 \setlength{\skip\footins}{9\p@ \@plus 4\p@ \@minus 2\p@}
167 \else 211 \setlength\floatsep {12\p@ \@plus 2\p@ \@minus 2\p@}
168 \if@twoside 212 \setlength\textfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
169 \setlength\@tempdima {\paperwidth} 213 \setlength\intextsep {12\p@ \@plus 2\p@ \@minus 2\p@}
170 \addtolength\@tempdima {-\textwidth} 214 \setlength\dblfloatsep {12\p@ \@plus 2\p@ \@minus 2\p@}
171 \setlength\oddsidemargin {.4\@tempdima} 215 \setlength\dbltextfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
172 \addtolength\oddsidemargin {-1in} 216 \setlength\@fptop{0\p@ \@plus 1fil}
173 \setlength\marginparwidth {.6\@tempdima} 217 \setlength\@fpsep{8\p@ \@plus 2fil}
174 \addtolength\marginparwidth {-\marginparsep} 218 \setlength\@fpbot{0\p@ \@plus 1fil}
175 \addtolength\marginparwidth {-0.4in} 219 \setlength\@dblfptop{0\p@ \@plus 1fil}
176 \else 220 \setlength\@dblfpsep{8\p@ \@plus 2fil}
177 \setlength\@tempdima {\paperwidth} 221 \setlength\@dblfpbot{0\p@ \@plus 1fil}
178 \addtolength\@tempdima {-\textwidth} 222 \setlength\partopsep{2\p@ \@plus 1\p@ \@minus 1\p@}
179 \setlength\oddsidemargin {.5\@tempdima}
180 \addtolength\oddsidemargin {-1in}
181 \setlength\marginparwidth {.5\@tempdima}
182 \addtolength\marginparwidth {-\marginparsep}
183 \addtolength\marginparwidth {-0.4in} 2.4.1.6 Lists Finally, for the values dependent
184 \addtolength\marginparwidth {-.4in} on type size, the dimensions of lists are set. As
185 \fi mentioned above, names are fabricated using roman
186 \ifdim \marginparwidth >2in numerals (i to vi).
187 \setlength\marginparwidth{2in}
size10.clo
188 \fi
223 \def\@listi{\leftmargin\leftmargini
189 \@settopoint\oddsidemargin
224 \parsep 4\p@ \@plus2\p@ \@minus\p@
190 \@settopoint\marginparwidth
225 \topsep 8\p@ \@plus2\p@ \@minus4\p@
191 \setlength\evensidemargin {\paperwidth}
226 \itemsep4\p@ \@plus2\p@ \@minus\p@}
192 \addtolength\evensidemargin{-2in}
227 \let\@listI\@listi
193 \addtolength\evensidemargin{-\textwidth}
228 \@listi
194 \addtolength\evensidemargin{-\oddsidemargin}
229 \def\@listii {\leftmargin\leftmarginii
195 \@settopoint\evensidemargin
230 \labelwidth\leftmarginii
196 \fi
231 \advance\labelwidth-\labelsep
197 \if@compatibility
232 \topsep 4\p@ \@plus2\p@ \@minus\p@
198 \setlength\topmargin{27pt}
233 \parsep 2\p@ \@plus\p@ \@minus\p@
199 \else
234 \itemsep \parsep}
200 \setlength\topmargin{\paperheight}
235 \def\@listiii{\leftmargin\leftmarginiii
201 \addtolength\topmargin{-2in}
236 \labelwidth\leftmarginiii
202 \addtolength\topmargin{-\headheight}
237 \advance\labelwidth-\labelsep
203 \addtolength\topmargin{-\headsep}
238 \topsep 2\p@ \@plus\p@\@minus\p@
204 \addtolength\topmargin{-\textheight}
239 \parsep \z@
205 \addtolength\topmargin{-\footskip}% this might be wrong
240 \partopsep \p@ \@plus\z@ \@minus\p@
206 \addtolength\topmargin{-.5\topmargin}
241 \itemsep \topsep}
207 \@settopoint\topmargin
242 \def\@listiv {\leftmargin\leftmarginiv
208 \fi
243 \labelwidth\leftmarginiv
244 \advance\labelwidth-\labelsep}
Again, the compatibility-mode settings are ab- 245 \def\@listv {\leftmargin\leftmarginv
solute, whereas the modern defaults are computed. 246 \labelwidth\leftmarginv
247 \advance\labelwidth-\labelsep}
2.4.1.5 Footnote space Spacing for footnotes 248 \def\@listvi {\leftmargin\leftmarginvi
and floats is flexible (plus and minus a certain 249 \labelwidth\leftmarginvi
amount) so that the page-breaking routine doesnt 250 \advance\labelwidth-\labelsep}
become too rigid. 251 \endinput

TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference 115
Peter Flynn

2.4.2 Spacing penalties 165 \markright {\MakeUppercase{%


Three penalties are set which get invoked in vari- 166 \ifnum \c@secnumdepth >\m@ne
ous decisions on paragraph-breaking. You probably 167 \thesection\quad
dont want to change these unless you are doing deep 168 \fi
surgery. 169 ##1}}}}
article.cls 170 \fi
128 \@lowpenalty 51 171 \def\ps@myheadings{%
129 \@medpenalty 151 172 \let\@oddfoot\@empty\let\@evenfoot\@empty
130 \@highpenalty 301 173 \def\@evenhead{\thepage\hfil\slshape\leftmark}%
131 \setcounter{topnumber}{2} 174 \def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
132 \renewcommand\topfraction{.7} 175 \let\@mkboth\@gobbletwo
133 \setcounter{bottomnumber}{1} 176 \let\sectionmark\@gobble
134 \renewcommand\bottomfraction{.3} 177 \let\subsectionmark\@gobble
135 \setcounter{totalnumber}{3} 178 }
136 \renewcommand\textfraction{.2}
137 \renewcommand\floatpagefraction{.5} In many cases it may be preferable to use the
138 \setcounter{dbltopnumber}{2} fancyhdr package instead. This lets you specify a
139 \renewcommand\dbltopfraction{.7} very wide range of header and footer layouts, with
140 \renewcommand\dblfloatpagefraction{.5} left/right switching for double-sided work.
2.4.4 Titling
The fractions and numbers refer to the propor-
tions of the page that can be taken up by figures This is possibly the first big change youll need to
and tables, and the number of floats allowed, when make. There are two \maketitle commands de-
calculating the location of floats. fined, one for use on a separate title page (without
facilities for attribution), and one for normal use on
2.4.3 Running heads the starting page (with attributions, and allowing
Depending on the imposition (one-sided or two- for two columns, using the \@maketitle command
sided), the default running heads are specified as as well). Both are controlled by the \if@titlepage
in the original LATEX manual [5]. switch.
article.cls
article.cls 179 \if@titlepage
141 \if@twoside 180 \newcommand\maketitle{\begin{titlepage}%
142 \def\ps@headings{% 181 \let\footnotesize\small
182 \let\footnoterule\relax
143 \let\@oddfoot\@empty\let\@evenfoot\@empty
183 \let \footnote \thanks
144 \def\@evenhead{\thepage\hfil\slshape\leftmark}% 184 \null\vfil
145 \def\@oddhead{{\slshape\rightmark}\hfil\thepage}% 185 \vskip 60\p@
146 \let\@mkboth\markboth 186 \begin{center}%
187 {\LARGE \@title \par}%
147 \def\sectionmark##1{% 188 \vskip 3em%
148 \markboth {\MakeUppercase{% 189 {\large
149 \ifnum \c@secnumdepth >\z@ 190 \lineskip .75em%
150 \thesection\quad 191 \begin{tabular}[t]{c}%
192 \@author
151 \fi 193 \end{tabular}\par}%
152 ##1}}{}}% 194 \vskip 1.5em%
153 \def\subsectionmark##1{% 195 {\large \@date \par}% % Set date in \large size.
154 \markright {% 196 \end{center}\par
197 \@thanks
155 \ifnum \c@secnumdepth >\@ne 198 \vfil\null
156 \thesubsection\quad 199 \end{titlepage}%
157 \fi 200 \setcounter{footnote}{0}%
158 ##1}}} 201 \global\let\thanks\relax
202 \global\let\maketitle\relax
159 \else 203 \global\let\@thanks\@empty
160 \def\ps@headings{% 204 \global\let\@author\@empty
161 \let\@oddfoot\@empty 205 \global\let\@date\@empty
206 \global\let\@title\@empty
162 \def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
207 \global\let\title\relax
163 \let\@mkboth\markboth 208 \global\let\author\relax
164 \def\sectionmark##1{% 209 \global\let\date\relax

116 TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference
Rolling your own Document Class: Using LATEX to keep away from the Dark Side

210 \global\let\and\relax You can also make up your own additional ele-
211 } ments, for example an optional subtitle:
212 \else
213 \newcommand\maketitle{\par
\def\@subtitle{\relax}
214 \begingroup
215 \renewcommand\thefootnote{\@fnsymbol\c@footnote}% \newcommand{\subtitle}[1]{\gdef\@subtitle{#1}}
216 \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}% \renewcommand{\maketitle}{
217 \long\def\@makefntext##1{\parindent 1em\noindent \begin{titlepage}
218 \hb@xt@1.8em{%
219 \hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
\huge\@author\par
220 \if@twocolumn \Large\@title\par
221 \ifnum \col@number=\@ne \if\@subtitle\relax\else\large\@subtitle\par\fi
222 \@maketitle \normalsize\@date\par
223 \else
224 \twocolumn[\@maketitle]%
\end{titlepage}
225 \fi }
226 \else
227 \newpage This lets the phantom \@subtitle exist unused,
228 \global\@topnum\z@ % Prevents figures from going at top of page.
229 \@maketitle
set to \relax unless an author explicitly uses the
230 \fi \subtitle command, because the titling routine
231 \thispagestyle{plain}\@thanks can test whether it is still set to \relax, and if not,
232 \endgroup format it accordingly. This technique can be used
233 \setcounter{footnote}{0}%
234 \global\let\thanks\relax to add many of the items of metadata used by pub-
235 \global\let\maketitle\relax lishers, such as author affiliations, email and web
236 \global\let\@maketitle\relax addresses, and dates of submission.
237 \global\let\@thanks\@empty
238 \global\let\@author\@empty 2.5 Structure
239 \global\let\@date\@empty
240 \global\let\@title\@empty Unless you are doing a very rigid class for data-
241 \global\let\title\relax handling, you probably want to keep the basic sec-
242 \global\let\author\relax
tional structures for normal continuous text as they
243 \global\let\date\relax
244 \global\let\and\relax are, and only change the formatting.
245 } article.cls
246 \def\@maketitle{% 265 \setcounter{secnumdepth}{3}
247 \newpage 266 \newcounter {part}
248 \null 267 \newcounter {section}
249 \vskip 2em% 268 \newcounter {subsection}[section]
250 \begin{center}% 269 \newcounter {subsubsection}[subsection]
251 \let \footnote \thanks 270 \newcounter {paragraph}[subsubsection]
252 {\LARGE \@title \par}% 271 \newcounter {subparagraph}[paragraph]
253 \vskip 1.5em% 272 \renewcommand \thepart {\@Roman\c@part}
254 {\large 273 \renewcommand \thesection {\@arabic\c@section}
255 \lineskip .5em% 274 \renewcommand\thesubsection {\thesection.\@arabic\c@subsection}
256 \begin{tabular}[t]{c}% 275 \renewcommand\thesubsubsection{\thesubsection .\@arabic\c@subsubsection}
257 \@author 276 \renewcommand\theparagraph {\thesubsubsection.\@arabic\c@paragraph}
258 \end{tabular}\par}% 277 \renewcommand\thesubparagraph {\theparagraph.\@arabic\c@subparagraph}
259 \vskip 1em% 278 \newcommand\part{%
260 {\large \@date}% 279 \if@noskipsec \leavevmode \fi
261 \end{center}% 280 \par
262 \par 281 \addvspace{4ex}%
263 \vskip 1.5em} 282 \@afterindentfalse
264 \fi 283 \secdef\@part\@spart}

The \part command is defined separately, as it


operates like \chapter in other classes, with more
In all of these you can redefine the size, loca- space and a prefix (the book and report classes define
tion, and spacing of the three basic titling elements, a separate \chapter command).
\@title, \@author, and \@date. (\author itself article.cls
is defined as part of the LATEX core.) If you are 285 \def\@part[#1]#2{%
not using two-column setting, or a title-page op- 286 \ifnum \c@secnumdepth >\m@ne
tion, you could replace the whole lot with a single 287 \refstepcounter{part}%
\renewcommand{\maketitle}{...} of your own de- 288 \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}%
sign. 289 \else

TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference 117
Peter Flynn

290 \addcontentsline{toc}{part}{#1}% ted in command names, all these parameters end in


291 \fi the Roman-numeral equivalents.
292 {\parindent \z@ \raggedright article.cls
293 \interlinepenalty \@M 332 \if@twocolumn
294 \normalfont 333 \setlength\leftmargini {2em}
295 \ifnum \c@secnumdepth >\m@ne 334 \else
296 \Large\bfseries \partname\nobreakspace\thepart 335 \setlength\leftmargini {2.5em}
297 \par\nobreak 336 \fi
298 \fi 337 \leftmargin \leftmargini
299 \huge \bfseries #2% 338 \setlength\leftmarginii {2.2em}
300 \markboth{}{}\par}% 339 \setlength\leftmarginiii {1.87em}
301 \nobreak 340 \setlength\leftmarginiv {1.7em}
302 \vskip 3ex 341 \if@twocolumn
303 \@afterheading} 342 \setlength\leftmarginv {.5em}
304 \def\@spart#1{% 343 \setlength\leftmarginvi {.5em}
305 {\parindent \z@ \raggedright 344 \else
306 \interlinepenalty \@M 345 \setlength\leftmarginv {1em}
307 \normalfont 346 \setlength\leftmarginvi {1em}
308 \huge \bfseries #1\par}% 347 \fi
309 \nobreak 348 \setlength \labelsep {.5em}
310 \vskip 3ex 349 \setlength \labelwidth{\leftmargini}
311 \@afterheading} 350 \addtolength\labelwidth{-\labelsep}
351 \@beginparpenalty -\@lowpenalty
The sectional formatting is one of the most 352 \@endparpenalty -\@lowpenalty
common features of a document class that need 353 \@itempenalty -\@lowpenalty
to change. Details of the operation of the 354 \renewcommand\theenumi{\@arabic\c@enumi}
\@startsection command are in the LATEX man- 355 \renewcommand\theenumii{\@alph\c@enumii}
ual [5] if you want to do a complete rewrite, but in 356 \renewcommand\theenumiii{\@roman\c@enumiii}
many cases one of the packages like sectsty can be 357 \renewcommand\theenumiv{\@Alph\c@enumiv}
used to change fonts or spacing without you having 358 \newcommand\labelenumi{\theenumi.}
to redo everything from scratch. 359 \newcommand\labelenumii{(\theenumii)}
article.cls 360 \newcommand\labelenumiii{\theenumiii.}
312 \newcommand\section{\@startsection {section}{1}{\z@}% 361 \newcommand\labelenumiv{\theenumiv.}
313 {-3.5ex \@plus -1ex \@minus -.2ex}%
314 {2.3ex \@plus.2ex}% 362 \renewcommand\p@enumii{\theenumi}
315 {\normalfont\Large\bfseries}} 363 \renewcommand\p@enumiii{\theenumi(\theenumii)}
316 \newcommand\subsection{\@startsection{subsection}{2}{\z@}% 364 \renewcommand\p@enumiv{\p@enumiii\theenumiii}
317 {-3.25ex\@plus -1ex \@minus -.2ex}% 365 \newcommand\labelitemi{\textbullet}
318 {1.5ex \@plus .2ex}%
319 {\normalfont\large\bfseries}} 366 \newcommand\labelitemii{\normalfont\bfseries \textendash}
320 \newcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% 367 \newcommand\labelitemiii{\textasteriskcentered}
321 {-3.25ex\@plus -1ex \@minus -.2ex}% 368 \newcommand\labelitemiv{\textperiodcentered}
322 {1.5ex \@plus .2ex}%
369 \newenvironment{description}
323 {\normalfont\normalsize\bfseries}}
324 \newcommand\paragraph{\@startsection{paragraph}{4}{\z@}% 370 {\list{}{\labelwidth\z@ \itemindent-\leftmargin
325 {3.25ex \@plus1ex \@minus.2ex}% 371 \let\makelabel\descriptionlabel}}
326 {-1em}% 372 {\endlist}
327 {\normalfont\normalsize\bfseries}}
328 \newcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}%
373 \newcommand*\descriptionlabel[1]{\hspace\labelsep
329 {3.25ex \@plus1ex \@minus .2ex}% 374 \normalfont\bfseries #1}
330 {-1em}%
331 {\normalfont\normalsize\bfseries}} The variables and their meaning are described
in more detail in the LATEX manual [5] and the Com-
2.6 Indents and margins panion [6], but essentially:
In this section the class file defines the internal mar- \leftmarginrr are the list level indentations from
gins set around block elements like lists. For control- outer page margin to the start of the text;
ling lists, LATEX provides four levels of indentation. \labelsep is the space between the number or bul-
As explained earlier, because digits are not permit- let and the start of the text;

118 TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference
Rolling your own Document Class: Using LATEX to keep away from the Dark Side

\labelwidth is how much space to allow for the


numbering or bulleting; \newenvironment{abstract}{%
\theenumrr controls the style of numbering; \titlepage
\labelenumrr controls the style of bulleting. \subsection*{\abstractname}}%
{\par\vfil\null\endtitlepage}
In all these cases, you can remove the conditional
code surrounding the variants for two-column work, Some styles require turning off the initial indenta-
and have just one setting, if you are not going to tion when the abstract is on the first page, for con-
provide for two-column setting. sistency with the default Anglo-American style used
The description environment works slightly dif- in sections:
ferently: the \makelabel command is equated to a
\descriptionlabel command to indent and format \newenvironment{abstract}{%
the item label. This is easily redefined, for example \if@twocolumn
to make the labels use the sans-serif font instead of \section*{\abstractname}%
the default roman typeface, and add an automatic \else
em-rule afterwards: \small
\begin{center}%
\renewcommand*\descriptionlabel[1]{ {\bfseries \abstractname\vspace{-.5em}
\hspace\labelsep \vspace{\z@}}%
\relax\sffamily{\bfseries #1}~---\space \end{center}%
\ignorespaces} \quotation\noindent\ignorespaces
\fi}
2.7 Abstract {\if@twocolumn\else\endquotation\fi}
The default abstract is formatted differently accord-
Note that if you will be adding to an existing class in
ing to where it appears: on the first page or on a
the manner described in section 3.1 on p. 122, these
page by itself after a separate title page.
article.cls
last two examples will use the \renewenvironment
375 \if@titlepage command instead.
376 \newenvironment{abstract}{% 2.8 Structural elements
377 \titlepage
378 \null\vfil The default classes contain some rudimentary envi-
379 \@beginparpenalty\@lowpenalty ronments for verse and quotations, and a compat-
380 \begin{center}% ibility setting for LATEX 2.09 users, which can be
381 \bfseries \abstractname omitted from new classes (make sure you keep one
382 \@endparpenalty\@M definition of the titlepage environment, though!
article.cls
383 \end{center}}% 398 \newenvironment{verse}
384 {\par\vfil\null\endtitlepage} 399 {\let\\\@centercr
385 \else 400 \list{}{\itemsep \z@
386 \newenvironment{abstract}{% 401 \itemindent -1.5em%
387 \if@twocolumn 402 \listparindent\itemindent
388 \section*{\abstractname}% 403 \rightmargin \leftmargin
389 \else 404 \advance\leftmargin 1.5em}%
390 \small 405 \item\relax}
391 \begin{center}% 406 {\endlist}
392 {\bfseries \abstractname\vspace{-.5em}\vspace{\z@}}% 407 \newenvironment{quotation}
393 \end{center}% 408 {\list{}{\listparindent 1.5em%
394 \quotation 409 \itemindent \listparindent
395 \fi} 410 \rightmargin \leftmargin
396 {\if@twocolumn\else\endquotation\fi} 411 \parsep \z@ \@plus\p@}%
397 \fi 412 \item\relax}
413 {\endlist}
One common requirement is for the Abstract
414 \newenvironment{quote}
formatting to follow the pattern of a subsection
415 {\list{}{\rightmargin\leftmargin}%
when it appears on a separate page, eg
416 \item\relax}

TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference 119
Peter Flynn

417 {\endlist} 2.9 Figures and tables


418 \if@compatibility These are controlled by a number of dimensions
419 \newenvironment{titlepage} which you may already be familiar with, such as
420 {% \tabcolsep for the gap between table columns. The
421 \if@twocolumn \fboxsep and \fboxrule dimensions control the
422 \@restonecoltrue\onecolumn gap and rule thickness around boxed text.
423 \else
424 \@restonecolfalse\newpage
425 \fi article.cls
426 \thispagestyle{empty}% 452 \setlength\arraycolsep{5\p@}
427 \setcounter{page}\z@ 453 \setlength\tabcolsep{6\p@}
428 }% 454 \setlength\arrayrulewidth{.4\p@}
429 {\if@restonecol\twocolumn \else \newpage \fi 455 \setlength\doublerulesep{2\p@}
430 } 456 \setlength\tabbingsep{\labelsep}
431 \else 457 \skip\@mpfootins = \skip\footins
432 \newenvironment{titlepage} 458 \setlength\fboxsep{3\p@}
433 {% 459 \setlength\fboxrule{.4\p@}
434 \if@twocolumn 460 \renewcommand \theequation {\@arabic\c@equation}
435 \@restonecoltrue\onecolumn 461 \newcounter{figure}
436 \else 462 \renewcommand \thefigure {\@arabic\c@figure}
437 \@restonecolfalse\newpage 463 \def\fps@figure{tbp}
438 \fi 464 \def\ftype@figure{1}
439 \thispagestyle{empty}% 465 \def\ext@figure{lof}
440 \setcounter{page}\@ne 466 \def\fnum@figure{\figurename\nobreakspace\thefigure}
441 }% 467 \newenvironment{figure}
442 {\if@restonecol\twocolumn \else \newpage \fi 468 {\@float{figure}}
443 \if@twoside\else 469 {\end@float}
444 \setcounter{page}\@ne 470 \newenvironment{figure*}
445 \fi 471 {\@dblfloat{figure}}
446 } 472 {\end@dblfloat}
447 \fi 473 \newcounter{table}
448 \newcommand\appendix{\par 474 \renewcommand\thetable{\@arabic\c@table}
449 \setcounter{section}{0}% 475 \def\fps@table{tbp}
450 \setcounter{subsection}{0}% 476 \def\ftype@table{2}
451 \gdef\thesection{\@Alph\c@section}} 477 \def\ext@table{lot}
478 \def\fnum@table{\tablename\nobreakspace\thetable}
479 \newenvironment{table}
The quotation environment is another which
480 {\@float{table}}
benefits from the removal of the initial indentation:
481 {\end@float}
482 \newenvironment{table*}
\newenvironment{quotation} 483 {\@dblfloat{table}}
{\list{}{\listparindent 1.5em% 484 {\end@dblfloat}
\itemindent \z@ 485 \newlength\abovecaptionskip
\rightmargin \leftmargin 486 \newlength\belowcaptionskip
\parsep \z@ \@plus\p@}% 487 \setlength\abovecaptionskip{10\p@}
\item\relax} 488 \setlength\belowcaptionskip{0\p@}
{\endlist} 489 \long\def\@makecaption#1#2{%
490 \vskip\abovecaptionskip
491 \sbox\@tempboxa{#1: #2}%
For the reasons noted in section 2.7 on p. 119, this 492 \ifdim \wd\@tempboxa >\hsize
may need to be a \renewcommand. 493 #1: #2\par
This section ends with a definition for 494 \else
\appendix which switches the \section settings to 495 \global \@minipagefalse
produce labels with A, B, C, etc instead of 1, 2, 3. 496 \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%

120 TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference
Rolling your own Document Class: Using LATEX to keep away from the Dark Side

497 \fi 542 \parfillskip -\@pnumwidth


498 \vskip\belowcaptionskip} 543 \leavevmode \bfseries
544 \advance\leftskip\@tempdima
545 \hskip -\leftskip
At the end of this section is the \@makecaption 546 #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
command, another popular candidate for redesign, 547 \endgroup
but consider also using the ccaption package. 548 \fi}
549 \newcommand*\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}}
550 \newcommand*\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}}
2.10 Legacy support
551 \newcommand*\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}}
The obsolescent commands \rm, \it, \bf, etc are 552 \newcommand*\l@subparagraph{\@dottedtocline{5}{10em}{5em}}
declared here to function as their modern equiva- 553 \newcommand\listoffigures{%
554 \section*{\listfigurename}%
lents. 555 \@mkboth{\MakeUppercase\listfigurename}%
article.cls 556 {\MakeUppercase\listfigurename}%
499 \DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} 557 \@starttoc{lof}%
500 \DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} 558 }
501 \DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} 559 \newcommand*\l@figure{\@dottedtocline{1}{1.5em}{2.3em}}
560 \newcommand\listoftables{%
502 \DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} 561 \section*{\listtablename}%
503 \DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} 562 \@mkboth{%
504 \DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} 563 \MakeUppercase\listtablename}%
505 \DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} 564 {\MakeUppercase\listtablename}%
565 \@starttoc{lot}%
506 \DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} 566 }
507 \DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} 567 \let\l@table\l@figure

2.11 Table of contents There are \l@ttt commands (\l@part,


\l@section, etc) which produce the ToC lines from
The Table of Contents section starts with some the .aux file. The List of Tables and List of Figures
commands which evaluate to dimensions, plus the are implemented in the same way as the ToC. As
\tableofcontents command itself. with other features, consider the tocloft package for
article.cls
508 \newcommand\@pnumwidth{1.55em}
common modifications.
509 \newcommand\@tocrmarg{2.55em}
510 \newcommand\@dotsep{4.5} 2.12 Bibliography and index
511 \setcounter{tocdepth}{3} Bibliography styles themselves are implemented in
512 \newcommand\tableofcontents{%
513 \section*{\contentsname .bst files, but the style of the section can be changed
514 \@mkboth{% here, including indentation and spacing.
515 \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}% article.cls
516 \@starttoc{toc}% 568 \newdimen\bibindent
517 } 569 \setlength\bibindent{1.5em}
518 \newcommand*\l@part[2]{% 570 \newenvironment{thebibliography}[1]
519 \ifnum \c@tocdepth >-2\relax 571 {\section*{\refname}%
520 \addpenalty\@secpenalty 572 \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}%
521 \addvspace{2.25em \@plus\p@}% 573 \list{\@biblabel{\@arabic\c@enumiv}}%
522 \setlength\@tempdima{3em}% 574 {\settowidth\labelwidth{\@biblabel{#1}}%
523 \begingroup 575 \leftmargin\labelwidth
524 \parindent \z@ \rightskip \@pnumwidth 576 \advance\leftmargin\labelsep
525 \parfillskip -\@pnumwidth 577 \@openbib@code
526 {\leavevmode 578 \usecounter{enumiv}%
527 \large \bfseries #1\hfil \hb@xt@\@pnumwidth{\hss #2}}\par 579 \let\p@enumiv\@empty
528 \nobreak 580 \renewcommand\theenumiv{\@arabic\c@enumiv}}%
529 \if@compatibility 581 \sloppy
530 \global\@nobreaktrue 582 \clubpenalty4000
531 \everypar{\global\@nobreakfalse\everypar{}}% 583 \@clubpenalty \clubpenalty
532 \fi 584 \widowpenalty4000%
533 \endgroup 585 \sfcode\.\@m}
534 \fi} 586 {\def\@noitemerr
535 \newcommand*\l@section[2]{% 587 {\@latex@warning{Empty thebibliography environment}}%
536 \ifnum \c@tocdepth >\z@ 588 \endlist}
537 \addpenalty\@secpenalty 589 \newcommand\newblock{\hskip .11em\@plus.33em\@minus.07em}
538 \addvspace{1.0em \@plus\p@}% 590 \let\@openbib@code\@empty
539 \setlength\@tempdima{1.5em}% 591 \newenvironment{theindex}
540 \begingroup 592 {\if@twocolumn
541 \parindent \z@ \rightskip \@pnumwidth 593 \@restonecolfalse

TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference 121
Peter Flynn

594 \else 643 \flushbottom


595 \@restonecoltrue 644 \else
596 \fi
597 \twocolumn[\section*{\indexname}]%
645 \onecolumn
598 \@mkboth{\MakeUppercase\indexname}% 646 \fi
599 {\MakeUppercase\indexname}% 647 \endinput
600 \thispagestyle{plain}\parindent\z@
601 \parskip\z@ \@plus .3\p@\relax To end with, there is the \today date, which
602 \columnseprule \z@
603 \columnsep 35\p@ non-Americans can recode as:
604 \let\item\@idxitem}
605 {\if@restonecol\onecolumn\else\clearpage\fi}
\def\today{\number\day\space\ifcase\month\or
606 \newcommand\@idxitem{\par\hangindent 40\p@} January\or February\or March\or April\or May\or June\or
607 \newcommand\subitem{\@idxitem \hspace*{20\p@}} July\or August\or September\or October\or November\or
608 \newcommand\subsubitem{\@idxitem \hspace*{30\p@}} December\fi\space\number\year}
609 \newcommand\indexspace{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax}
The last few lines include the column spacing, page
2.13 Odds n ends style, and page numbering setups. Single-sided work
The final section starts with the footnote fence and is allowed to have a slightly variable text height (the
the footnote alignment. There is also a list of the \raggedbottom command), and two-column setting
section names, which are the ones which get cus- has a strict height but slightly greater tolerance on
tomised for other languages when you use the babel justification.
multilingual/multicultural package. 3 Rolling your own
article.cls
610 \renewcommand\footnoterule{% Having seen what the article class does and how it
611 \kern-3\p@ works, you have a choice: create your new class file
612 \hrule\@width.4\columnwidth from scratch, or build onto an existing class.
613 \kern2.6\p@} Writing a wholly new class requires a significant
614 \newcommand\@makefntext[1]{% knowledge of LATEX and TEX internals, but will have
615 \parindent 1em% the advantage of being dedicated to the specific task
616 \noindent on hand, and may offer more scope for automation,
617 \hb@xt@1.8em{\hss\@makefnmark}#1} particularly if the process of generating the output
618 \newcommand\contentsname{Contents} is to be embedded within a larger application.
619 \newcommand\listfigurename{List of Figures}
620 \newcommand\listtablename{List of Tables} 3.1 Re-using an existing class
621 \newcommand\refname{References} Building on the work of other classes is more com-
622 \newcommand\indexname{Index} mon, and has been described for a specific appli-
623 \newcommand\figurename{Figure} cation (Minutes of meetings) in [3]. This involves
624 \newcommand\tablename{Table} loading the existing class file, handling any existing
625 \newcommand\partname{Part} or new options, and then adding or modifying the
626 \newcommand\appendixname{Appendix} commands and environments it provides.
627 \newcommand\abstractname{Abstract} We have already seen the use of \renewcommand
628 \def\today{\ifcase\month\or (section 2.4.4 on p. 116) and its counterpart for
629 January\or February\or March\or April\or May\or June\or environments, \renewenvironment (section 2.7 on
630 July\or August\or September\or October\or p. 119), but you need to ensure the command
631 November \or December\fi \space\number\day, \number\year} and environments you are replacing are correctly
632 \setlength\columnsep{10\p@} preloaded. Hefferon [3] describes in detail the use of
633 \setlength\columnseprule{0\p@} the \LoadClass and \DeclareOption* commands
634 \pagestyle{plain} to specify the class on which you want to base yours,
635 \pagenumbering{arabic} how to preserve existing options, and how to add
636 \if@twoside your own.
637 \else
638 \raggedbottom 3.2 Packages
639 \fi As well as rewriting or modifying the code of an
640 \if@twocolumn existing class, you can also invoke extra packages.
641 \twocolumn In most cases this is faster, more reliable, and easier
642 \sloppy to do than rewriting the code of the existing class.

122 TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference
Rolling your own Document Class: Using LATEX to keep away from the Dark Side

We have mentioned several useful packages: References


geometry for the text area and page margins; [1] Johannes Braams. Document classes and
multicol for multiple columns of text; packages in LATEX 2 . TUGboat, 15(3),
fancyhdr for running headers and footers; Sep 1994. http://www.tug.org/TUGboat/
sectsty for changes to section and title styles; Contents/contents15-3.html.
ccaption for changes to the layout of Table and Fig- [2] Robin Fairbairns (Ed). Frequently Asked
ure captions; Questions about TEX. Technical report,
UK TEX Users Group, Cambridge, UK, Nov
tocloft for changes to the layout of the Table of 2005. http://www.tex.ac.uk/cgi-bin/
Contents and Lists of Figures and Tables; texfaq2html?label=ltxcmds.
babel for working in multiple languages. [3] Jim Hefferon. Minutes in less than hours:
In your new class file, use the \RequirePackage Using LATEX resources. The PracTEX Journal,
command after the options (see section 2.3.4 on 2005(4), Oct 2005. http://www.tug.org/
p. 113). If an option needs to refer to a specific pack- pracjourn/2005-4/hefferon/.
age, put the \RequirePackage after the version and [4] Donald Knuth. The TEXbook. Addison-Wesley,
identification section but before your options (see Reading, MA, Jun 1986.
section 2.2 on p. 111).
[5] Leslie Lamport. LATEX: A document
3.3 Four last things preparation system. Addison-Wesley, Reading,
MA, 2nd edition, 1994.
The Companion [6, p. 888] specifies that every class
file must contain four things: [6] Frank Mittelbach, Michel Goossens, Johannes
Braams, David Carlisle, Chris Rowley,
1. a definition of \normalsize;
Christine Detig, and Joachim Schrod. The
2. a value for \textwidth; LATEX Companion: Tools and Techniques
3. a value for \textheight; for Computer Typesetting. Addison-Wesley,
4. a specification for \pagenumbering. Reading, MA, 2nd edition, May 2004.
Beyond that, its up to you! If you have been doc- [7] Scott Pakin. How to package your LATEX
umenting your class file in docTEX format as you package. CTAN, Nov 2005. http://www.ctan.
go along, as explained in the first paragraph in sec- org/tex-archive/info/dtxtut/dtxtut.pdf.
tion 2, you should now consider releasing it for gen- [8] The LATEX3 Project. LATEX 2 for class and
eral use by submitting it to the CTAN maintainers package writers, Dec 2003. $TEXMFMAIN/
so that others can use it. texmf-dist/doc/latex/base/clsguide.
{dvi|pdf}.
Acknowledgments
[9] Wayne Sewell. Literate Programming in WEB.
This article originally appeared in the PracTEX Van Nostrand Reinhold, New York, NY, 1989.
Journal (2006:4) where it was set full out. The
challenge in a two-column layout of fitting wide
lines of verbatim code from files whose line-numbers
are needed for reference was met by a sugges-
tion from Karl Berry to use the Latin Modern
Typewriter Light Condensed font (lmttlc) in the
\VerbatimInput command of the fancyvrb package.

TUGboat, Volume 28 (2007), No. 1 Proceedings of the Practical TEX 2006 Conference 123

You might also like