In the previous chapters, many macros for performing special tricks in were presented with little explanation of how and why they work. Development of the skills necessary to create elaborate macros often requires an understanding of ’s inner workings that few of us have the time (or desire) to obtain. However, as demonstrated by the many macro examples used in this book, allows us to use macros created by others without the need to understand them fully. Often only a superficial knowledge of commands is sufficient to make minor modifications in a particular macro to alter what it does.
In this chapter, brief explanations are given of some of the commands used in the earlier macro examples. This introduction to the basics of macro programming for is intended mainly to provide the reader with a very rudimentary understanding of how macro and style files are written. To gain a detailed knowledge about how to write macros and style files from scratch, there is no substitute for many careful readings of D. L. Knuth’s The book (Addison-Wesley, New York, NY, 1990).
Later in this chapter, a series of recipes or tricks for doing several nonstandard things with is presented. For the most part, these tricks have been gleaned from various network sources, notably UKHAX, TUG Newsletters, TEXHAX, and NetNews. This later resource, the Internet News Service, has a discussion group comp.text.tex
which is an excellent place to pick up various tricks and to ask for help from a worldwide community of experts.
is a large collection of macros (about 11,000 lines) built using the rich command set of . These macros are defined in four files: (1) lplain.tex
(a minor modification of ’s plain.tex
, which is used for normal documents), (2) latex.tex
(the file containing the bulk of ’s macros), (3) lfonts.tex
(which defines ’s fonts and their commands), and (4) hyphen.tex
(which defines American hyphenation patterns). These four files are compiled to produce a binary file lplain.fmt
that can load quickly whenever you want to your document. If you want to see how does a particular task, the macro for the task is probably to be found in latex.tex
. This is an excellent file to browse through to become more familiar with creating macros and style files.
also has four primary style files: letter, report, article
, and book that define macros for special commands used by these four styles (for example, the section heading commands). If you want to change how formats, for example, the section heading command, you extract the macro for the section heading from the appropriate .STY
file and modify it (see Section 9.2.3).
The key to creating new macros and styles for is to define new commands. A command name begins with a backslash and an alphabetic label (no numbers!). The command names used by use only the lowercase alphabetic characters, and to avoid conflicts by inadvertently choosing a command name that is the same as an existing command name, it is a good idea to use some uppercase alphabetic letters in your command names, for example, Mycmd
.
’s
ewcommand
may be used to define a new command. Its syntax is
ewcommand{ cmdname} [numargs] {cmddefn}
where cmdname
is the command name, [noargs] is optional and gives the number of arguments for the command (a maximum of nine), and cmddefn is the text string that defines the command. If cmdname is the name of an existing command, will produce an error message. Here are a couple of examples.
ewcommand{keff}{$k_{!mbox{scriptsize em eff}}$}
ewcommand{Nuclide}[2]{${}©{#2}$#1}
With these macros (placed either in the preamble or in the document itself before they are first used), keff
will produce ke f ff and Nuclide{U}{235}
gives 235U.
To change an existing command, provides
enewcommand
. Its syntax and use are the same as that of
ewcommand
. For example, the vertical space normally made by igskip
can be increased by redefining this command as
enewcommand{igskip}{vspace{3cm}}
provides the def
command to define new commands. It is used as
defcmdname#l#2#3…{cmddefn}
where the argument specifiers #1#2#3.. . are used only if cmddefn needs arguments. This command may be used in but, unlike ’s
ewcommand
, it does not check to see if cmdname
is already used. Here’s how the keff
and Nuclide
macro (previously defined with
ewcommand
) could be defined using the def
command.
defkeff{$k_{!mbox{scriptsize em eff}}$ }
defNuclide#l#2{${}˜{#2}$#l}
The argument list #1#2#3… can specify up to nine arguments and must be in increasing order, although they can be used in any order in cmddefn.
The cmddefn string, which defines the new command, can be spread over several lines, but no blank lines (or par
commands) may appear in the definition. If blank lines or par
are needed in cmddefn, use the compound longdef
command. Other modifiers to the def command include outer
, to restrict the use of the command to the outermost level of processing, and global
, to enable the continued operation of the command even outside the group in which it was invoked.
Internal © Commands
In the definition of a large macro or style, often commands are used only as local or internal commands. By convention, these command names contain the © character to avoid inadvertent conflicts with a command name you might choose. By contrast, commands to be used in a document are external commands and are named only with letters.
To enforce this convention, will accept commands containing the © symbol only in style files loaded as style options in the documentstyle
command. normally refuses to accept such commands in the document itself. However, you can force to accept these internal commands inside your document by preceding their appearance with the command makeatletter
, which causes © to be treated as an ordinary character. The makeatother
command reestablishes the normal convention. Many macros suggested in earlier chapters contain commands with the ©symbol, and to include them in a document’s preamble, it is necessary to begin them with makeatletter
and to end them with makeat
other.
In the definition of new commands and macros, several commands are frequently used. In this section a brief overview of some of the more important commands is presented.
The assignment statement let
newcommand=oldcommand creates a new command
newcommand that has exactly the same definition as the command
oldcommand.
To allow a macro to change the control flow, uses the following conditional statements:
if condition true-commands fi
if condition true-commands else false-commands fi
where the true-commands {false-commands) are executed if condition is true (false). Many conditions are predefined, such as ifodd
number, ifdim
, ifcase
number, and ifnum
.
There are also logical switches that may be defined by the user. The command
ewifif
myswitch defines three control sequences: (1) myswitchtrue
to set my switch to true, (2) myswitchfalse
to set my switch to false, and (3) if
myswitch true-commands else
false-commands fi
.
has defined a very useful conditional ifthenelse
command. To use this command the document style option ifthen
must be specified. The syntax of this command is
ifthenelse{test}{true-commands}{false-commands}
The test argument allows easy construction of logical conditions using two basic constructions. The first has the form number 1 rel number2, where rel is one of < = >
. Such simple tests may be combined into complex Boolean expressions using and,
ot, or
, and parentheses (and ). The second construction has the form equal
{cmdsl}{cmds2}. Here cmdsl and cmds2 are sets of macro calls that produce a true condition only if they produce identical results after expansion.
commands can be recursive, that is, they can call themselves thereby allowing them to be repeated many times until some terminating condition is satisfied. also has a loop
command that allows iterative execution of macros. This command has the syntax
loop pre-test-cmds if condition post-test-cmds epeat
The pre-test-cmds are executed first. Then the condition is evaluated, and, if condition is true, the post-test-cmds are executed and the loop is begun again. If condition is false, execution continues with the commands after
epeat
.
has also defined the following easy-to-use looping command:
whiledo{ test}{ while-commands}
where the logical test is constructed in the same manner as used for the test condition in the ifthenelse
command described previously. To use this command the document style option ifthen
must first be specified.
The macro commands used in the arguments of looping and conditional statements can be confined to groups with the usual braces { and } or with the pair of commands egingroup
and endgroup
. These group delimiters must appear in matched pairs.
Sometimes a macro definition requires an unmatched group delimiter. For this purpose, has the special commands group
(for a”begin group”) and egroup
(for an “end group”), which need not appear in matched pairs.
Sometimes you will want to produce side-by-side displays of material such as
This was produced by
egstart
.....(material for left minipage)
egmid
.....(material for right minipage)
egend
The egstart, egmid, egend
commands are defined by the following macros placed in the preamble of your document:
%========== Macro for LaTeX Side-by-Side Minipages ===========
ewlength{egwidth}setlength{egwidth}{0.45 extwidth}
ewenvironment{eg}%
{egin{list}{}{setlength{leftmargin}{0.05 extwidth}%
setlength{
ightmargin}{leftmargin}}item[]footnotesize}%
{end{list}}
ewenvironment{egbox}%
{egin{minipage} [t] {egwidth}}%
{end{minipage}}
ewcommand{egstart}{egin{eg}egin{egbox}}
ewcommand{egmid}{end{egbox}hfillegin{egbox}}
ewcommand{egend}{end{egbox}end{eg}}
%==========================================
===================
The command underline
only works for a small portion of text since it puts the text into an hbox
that cannot be broken at the end of a line. A very cumbersome way to get around this limitation is to underline each word and interword space separately as in
underbar{this}underbar{ }underbar{will}underbar{ }%/
underbar{do}underbar{ }underbar{the}underbar{ }underbar{job}.
Knuth wrote in the book “If you really want underlined text, it’s best to have a special font in which all the letters are underlined.” Until such fonts become available, here are two useful macros, one for underlining and the other for striking out text. Although not perfect, they are adequate for drafts. To underline text, use underlinewords
{text}, and to strike out text, use stikeoutwords
{text). Note: The text cannot have a paragraph break in it. To underline multiple paragraphs, place each paragraph in its own underlinewords
command.
%========== Macros for Underlining and Striking Out ===========
%-- by Michael Barr
defunderlinewords#l{%
defstuff{#l }leavevmodeexpandafterulwordstuff * }
defulword#l {defone{#l} ifxoneasterlet
ext
elax
elsevtop{hbox{strut#l}hrule
elax} let
extulwordfi
ext}
defstrikeoutwords#l{%
defstuff{#l }leavevmodeexpandaftersowordstuff * }
defsoword#l {defone{#l} ifxoneasterlet
ext
elax
elsevtop{hbox{strut#l}kern-.5aselineskiphrule
elax}
let
extsowordfi
ext}
defaster{*}
#==========================================
====================
The normal chapter and section headings are viewed by many as being too large and too assertive. The format for a lOpt book document’s headings, for example, is defined in ’s BOOK.STY
and BK10.STY
style files. The style file SSHDBK10.STY
below is extracted from these style files and modified to produce sans serif headings at a slightly reduced size (for example, huge in place of Huge). The changes to the original definitions are indicated by in the comment lines. This style file can be used with other document styles and should be specified as a style option in the documentstyle
command. Alternatively, you could put makeatletter
at the beginning and makeatother
at the end, and place the command input sshdlO.sty
in the preamble.
You can easily modify this style file to change the font size or even the font itself. Using the methods described in Section 1.5, for example, you could define bold sans serif commands Bsfhuge, BsfLarge
, and so on, and replace the following sf
commands by the appropriate bold font.
%================== SSHDBK10. STY ===================
% SSHDBK10.STY Makes slightly smaller headings in sans serif font
Modified from BK10.STY (changes indicated by ^^^)
% Adapted by Dominik Wujastyk
%----------------------------- part ----------------------------------
% From book.sty:
def©part[#l]#2{ifnum c©secnumdepth >-2
elax
efstepcounter{part}
addcontentsline{toc}{part}{ hepart hspace{lem}#l}else
addcontentsline{toc}{part}{#l}fi markboth{}{}
{centering ifnum c©secnumdepth >-2
elax Largesf Part hepart par
% ^^^
vskip 20pt fi huge sf #lpar}©endpart}
% ^^^
def©endpart{vfil
ewpage if©twoside hbox{} hispagestyle{empty}
ewpage
fi if©tempswa wocolumn fi}
def©spart#l{{centering huge sf #lpar}©endpart}
% ^^^^^^^^^
%------------------------- chapter ------------------------------------
% From bklO.sty:
def©makechapterhead#l{ vspace*{50pt} { parindent Opt
aggedright
ifnum c©secnumdepth >m©ne hugesf ©chapapp{} hechapter par
vskip 20pt fi huge sf #lpar
% ^^^
obreak vskip 40pt } }
%
def©makeschapterhead#l{ vspace*{50pt} { parindent Opt
aggedright
huge sf #lpar
%^^^^^^^^^
obreak vskip 40pt } }
%
%------------------------ section ---------------------------------
defsection{©startsection {section}{l}{z©}{-3.5ex plus -lex minus -.2ex}{2.3ex plus .2ex}{Largesf}}
% ^^^
%--------------------- subsection ---------------------------------
defsubsection{©startsection{subsection}{2}{z©}{-3• 25ex plus -lex minus -.2ex}{1.5ex plus .2ex}{largesf}}
% ^^^
%-------------------- subsubsection -------------------------------
def subsubsection{©startsection{subsubsection}{3}{z©}{-3.25ex plus -lex minus -.2ex}{1.5ex plus .2ex}{
ormalsizesf}}
% ^^^
% ^^^
%----------------------- paragraph --------------------------------
defparagraph{©startsection
{paragraph}{4}{z©}{3.25ex plus lex minus .2ex}{-lem}{
ormalsizesf}}
% ^^^
%---------------------- subparagraph ------------------------------
defsubparagraph{©startsection
{subparagraph}{4}{parindent}{3.25ex pins lex minus
.2ex>{-lem}{
ormalsizesf}}
% ^^^
%==================================================
Many modern book styles specify that section headings are to be outdented to the left of the text body. If you want this effect, the SSBK10.STY
file in the preceding section can be modified to produce heading outdenting. For example, if you want the section heading to be outdented to the left by half an inch, the macro for the section heading in the style file would become
%---------------------- section -------------------------------
%------ modified for outdent of section title
defsection{©startsection {section}{l}{z©}{-3.5ex plus -lex minus
-.2ex}{2.3ex plus .2ex}{leftskip=-2cm
ightskip=0pt plus Ifil Largesf}}
% ^^^ ^^^
The right header normally corresponds to the first section on the page. However, it can be made to refer to the last section. This problem arises only if there is more than one section heading on the same page. Insert in the preamble
makeat letter def ightmark{expandafter©rightmarkotmark} makeatother
The indentation environment defined next allows temporary resetting of the page margins. This environment takes two arguments, which are the left and right indents. The text in between the egin{indendation}
and end{indendation}
will be set as a paragraph with the specified left and right indentation. Here are some examples.
This text is set in a centered and right-justified paragraph with larger left and right margins than usual. This paragraph is indented half an inch on each side from the surrounding margins. This was produced with
egin{indentation}{.5in}{.5in}
This text is set in …
end{indentation}
These three lines of text are set in a right-justified paragraph that is indented only at the right. The indentation on the right is 1.5 inches, and is produced by egin{indentation}{0in}{1.5in}.
This text will be indented on the left only by 1 inch from the normal margin with egin{indentation}{l.5in}{0in}.
The indentation environment can also be nested, giving indents within indents, as is the text of this paragraph.
After leaving the second level of indentation, you return to the first indentation level as in this paragraph.
To use this indentation environment in your document include the following macro in your preamble (or in your style file after removing the first and last lines):
Frequently, the caption for a figure or table needs to be printed in a smaller font than that used for the main text. Unfortunately, the caption
command cannot successfully be embedded in a font size command. Here is a macro for the preamble that can be used to change the font size for the caption, restrict its width, and control the vertical space after the caption.
%============== Macro for small caption ===================
ewlength{captsize} letcaptsize=footnotesize
ewlength{captwidth} setlength{captwidth}{0.5 extwidth}
ewlength{eforetableskip}setlength{eforetableskip}{.5aselineskip}
ewcommand{capt}[1]{egin{minipage}{captwidth}
let
ormalsize=captsize
caption[#l]{#l}
end{minipage}\ vspace{eforetableskip}}
%===================================================
The parameter captsize
specifies the font size, captwidth
specifies the caption width, and eforetableskip
controls the vertical space placed after the caption. Default values are shown in the preceding definition. Table 9.1 is an example of a simple floating table produced with this capt
command. It is produced with
Table 9.1. The discrete energies E{ (MeV) used for deriving the line-beam response function
i Ei | i Ei |
1 0.02 | 6 0.1 |
2 0.03 | 7 0.2 |
3 0.04 | 8 0.4 |
4 0.06 | 9 0.7 |
5 0.08 | 10 1.0 |
egin{table} [htbp] %--- Table for footnotesize caption
centering
setlength{captwidth}{2.0in}
capt{The discrete energies $E_i$ (MeV) used for deriving
the line-beam response function label{capttstl}}
footnotesize egin{tabular}{|rc||rc|}
..... (define table)
end{tabular}
end{table}
There is a great variation in how figure and table captions are formatted in different publications. Here is a hack that changes three caption format features: (1) the colon(:) appended to the caption label (for example, “Figure 5.4:” or “Table 10.5:”) is replaced by a period(.), (2) the figure or table label is put in boldface, and (3) one-line captions are left justified rather than centered. Place the following in your preamble (or in a style file without the makeat
letter and makeatother
).
%========= Redefine the ©makecaption Command ==========
makeatletter
longdef©makecaption#l#2{vskip 10p©
%%setboxfltempboxahbox{#l: #2}% %% original definition
setbox©tempboxahbox{{f #1.} #2}% %% bold and . instead of :
ifdim wd©tempboxa >hsize
%% #1: #2par %% original definition
{f #1.} #2par %% bold and . instead of :
else
%% hbox tohsize{hfilox©tempboxahfil} %% original
hbox tohsize{oxQtempboxahfil}% %% no centering
fi}
makeatother
%===================================================
This macro is easily modified to make other format changes (for example, to have italics labels instead of bold) or to restore some aspect of the default format.
In the following examples, the capt
command (see previous subsection) is used instead of the caption
command both to restrict the caption width and to use a smaller font. However, the caption
command also works just as well (although changing font size and width restriction cannot be used). Table 9.2 was produced with the following input.
egin{table}[htbp]
egin{center}
setlength{captwidth}{3.0in}
capt{A caption in {protect{verb|footnotesize|}} font with
the table label in boldface and the usual colon at the
end on the label replaced by a period.label{tablOcolon}}
framebox[3in]{
ule{0in}{.2in}}
end{center}
end{table}
Here is an example of a left-justified label for a one-line caption produced with the redefined ©makecaption
macro.
To change the figure label “Figure” to “Fig.”, place the following in your preamble (or in a style file without the makeatletter
and makeatother
).
makeatletter
ewcommand{ hefigurename}{Figure} %-- set default: Figure
deffnum©figure{ hefigurename hefigure}
makeatother
Then, to change the figure label from “Figure” to”Fig.”, simply redefine the parameter hefigurename
by placing the following statement in your document:
enewcommand{ hef igurename}{Fig.}
Note: If you place this redefinition inside the egin
{figure} … end{figure}
, it will apply only to that figure. Figure 9.1 was produced by the following:
egin{figure}[htbp]
egin{center}
framebox[3in]{
ule{0in}{.5in}}
setlength{captwidth}{3.0in}
enewcommand{ hef igurenameMFig.}
capt{A figure caption in which the figure label has been
modified to ’’Fig.”.label{figfigtest}}
end{center}
end{figure}
Here is a style macro that affixes the chapter number by a hyphen to the page number. Moreover, at the beginning of each chapter, the page number is reset to 1.
Note that if you use any command in your document that changes the macro hepage
, for example, pagenumbering{roman}
, you will have to follow such a command by the
enewcommand
… in the above macro.
If you have appendices in the document, then after the appendix
command that starts the appendices, insert the statement
enewcommand{ hepage}{Alpha{chapter}-arabic{page}}
in order to have the appendix pages numbered A-l, A-2, and so on.
If the style file FANCYHDS. STY
is too elaborate for your needs, here is a file that puts the page number 30 points to the right of the right margin. By modifying and playing with it, you can do all sorts of tricks, such as page styles that don’t have numbers or that have them centered. This should be put into the document preamble (or into a style file without the makeatletter and makeatother
commands).
You can obtain equation numbering of the form (secnum.eqnum) by including in the document preamble
enewcommand{ heequation}{{
m
hesection.arabic{equation}}}
You must also reset the counter at the beginning of each section with
section{…} setcounter{equation}{0}
Equivalently, you can add the following to a style file:
allows only solid horizontal and vertical rules to be placed inside tabular or array environments. Sometimes it is useful to use dashed lines to show, for example, a partitioned matrix. Nakashima has developed a useful style file HVDASHLN.STY
(freely available in many Internet archives) that allows horizontal and vertical dashed lines to be placed inside array and tabular environments. Here are some examples.
The widths of the dashes and the interdash space are set, as in these examples, with
hdashlinewidth = 2pt hdashlinegap = 2pt
The spacing around the equal sign in an eqnarray environment is larger than that in an equation environment. In Section 4.5, a new equation array environment was defined to avoid this problem.
Rather than define a new equation array environment, here is a hack to modify the eqnarray
environment to give proper spacing around the = sign. Put the following in a style file.
Donald Arseneau has written a useful macro overunderbraces
(reproduced here) to put labeled horizontal brackets above and below a mathematical expressions, such as
(9.1)
The math command to produce such an expression has the syntax
overunderbraces{upper-brace-spec}{main-formula}{lower-brace-spec}
The above example has seven segments shown schematically as follows
Then, in composing the math expression, place an & between each segment (that is, where the tips of the braces point), as follows:
Then each brace is specified by r{number-of-segments}{label}
separated by &s to indicate the brace’s location (with & & indicating a skipped segment). For the preceding example, the upper and lower brace specifiers are
top row: |
&r{2}{x}& &r{2}{y} |
bottom row: |
& &r{3}{z} |
Finally, putting this all together, the example of Eq. (9.1) is produced with
egin{equation}
overunderbraces{&r{2}{x}& &r{2}{y}}%
{a + b +&C + d +&e + f&+&g + h&+ i + j&+ k + 1 + m}%
{& &r{3}{z}} = pi rˆ2
end{equation}
Here is the macro, which can be placed in a style file or placed in the document preamble between makeatletter
and makeatotheer
.
To make reference citations appear as superscipts [5] rather than the default [5] used by , you need to change the macro cite
that defines their appearence. Add the following to your style file:
In this style, if
aisedcitations
is declared, the citations are raised above the lines like footnotes. The
oraisedcitations
command causes the normal citation style to be used. To eliminate the [ and ] in the raised style, simply delete the [ and ] in the line flagged by %/<<<. Likewise, you could replace the square brackets by parentheses or omit any delimiters at all.
does not break citations and long ones such as [Kwiatkowska et al., 1990] can give overfilled lines very easily. To allow to break a citation across a line, the /citex
command in LATEX.TEX
must be modified. Specifically, change the definition of citex
in LATEX.TEX
by removing just the hbox
and nothing else. You will then need to put in ties (˜) wherever you do not want a citation broken at the end of a line.
For some reports or books, a separate bibliography may be desired at the end of each chapter. In such a style, the citations in each chapter are to be independent of those in other chapters. Unfortunately, allows only a single bibliography for each document. There is a style CHAPTERBIB.STY
, freely available from many Internet archives, that allows each chapter to have its own independent bibliography.
As an altertnative, here is a smaller and more limited style file that can be used if you put each chapter into a separate file and then include
each file into the root document (see Section 7.1). At the end of each chapter’s file, you put a egin{thebibliography} … end{thebibliography}
block containing all the references for the chapter to force the chapter bibliography to be printed.
For short documents, you may want to use endnotes rather than footnotes. Here is a style file that is a minor modification of a similar one by Erica Harris that produces endnotes.
Use endnote{ endnotetext}
to generate the reference number in the text just as you would with footnote
. At the end of your document (or at the end of each chapter), type producenotes
to output all endnotes created since the beginning of the document or since the last producenotes
. The following style file produces the endnotes in footnotesize
using the default font. The fifth line from the bottom (marked by %<<<)
can be modified to change the font and its size.