Admin Report
Admin Report
Version 1.1
Nicola L. C. Talbot
Dickimaw Books
www.dickimaw-books.com
1 Introduction 1
1.1 Packages and Document Classes . . . . . . . . . . . . . . . . . . . 3
1.2 Arara . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Managing Data 9
2.1 Utility Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.1 Macro Definitions . . . . . . . . . . . . . . . . . . . . . . . . 10
2.1.2 Hook Management . . . . . . . . . . . . . . . . . . . . . . . 19
2.1.3 Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2 Loading Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.2.1 Loading Data From a CSV File . . . . . . . . . . . . . . . . 27
2.2.2 Loading Data From a .dbtex File . . . . . . . . . . . . . . 32
2.3 Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.4 Sorting Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.5 Sample Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.5.1 Sample CSV Files . . . . . . . . . . . . . . . . . . . . . . . . 44
2.5.2 Sample XLS File . . . . . . . . . . . . . . . . . . . . . . . . . 47
2.5.3 Sample SQL Tables . . . . . . . . . . . . . . . . . . . . . . . 49
2.6 Displaying Tabulated Data . . . . . . . . . . . . . . . . . . . . . . . 53
2.7 Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
2.7.1 Iterating Through a Database . . . . . . . . . . . . . . . . . 57
2.7.2 Iterating Over a Comma-Separated List . . . . . . . . . . 59
2.7.3 Iteration With etoolbox’s Internal Lists . . . . . . . . . . . . 65
2.7.4 General Iteration with TEX’s \loop . . . . . . . . . . . . . 68
2.7.5 Iteration Tips and Tricks . . . . . . . . . . . . . . . . . . . . 68
2.8 Fetching Data From a Given Row . . . . . . . . . . . . . . . . . . 74
2.9 Null and Boolean Values . . . . . . . . . . . . . . . . . . . . . . . . 79
3 Correspondence 84
3.1 Writing a Letter Using the letter Class . . . . . . . . . . . . . . . . 84
3.2 Writing a Letter Using the scrlttr2 Class . . . . . . . . . . . . . . . 87
3.3 Writing a Letter Using the newlfm Class . . . . . . . . . . . . . . . 96
3.4 Writing a Letter Using the isodoc Class . . . . . . . . . . . . . . . 99
3.5 Mail Merging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
3.6 Envelopes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
4 Invoices 120
4.1 Writing an Invoice Using the isodoc Class . . . . . . . . . . . . . . 120
4.2 Writing an Invoice Using the invoice Package . . . . . . . . . . . 122
4.3 Building Your Own Invoice using longtable and datatool . . . . . . 126
i
Contents ii
11 Forms 326
11.1 Writing a Class File for a Form . . . . . . . . . . . . . . . . . . . . 329
11.2 Electronic PDF Forms . . . . . . . . . . . . . . . . . . . . . . . . . 349
12 Charts 359
12.1 Flow Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
12.2 Pie Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
12.2.1 The datapie Package . . . . . . . . . . . . . . . . . . . . . . . 364
12.2.2 The pgf-pie Package . . . . . . . . . . . . . . . . . . . . . . . 369
12.3 Bar Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
12.3.1 The bchart Package . . . . . . . . . . . . . . . . . . . . . . . 371
12.3.2 The databar Package . . . . . . . . . . . . . . . . . . . . . . . 373
12.4 Gantt Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
12.5 Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
Contents iii
Acknowledgements 416
Bibliography 417
Glossary 423
History 500
List of Figures
2.1 datatooltk in Graphical Mode . . . . . . . . . . . . . . . . . . . . . . 34
2.2 Import CSV File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.3 Imported CSV Data Shown in Main Window . . . . . . . . . . . . . 35
2.4 Import SQL Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.5 Imported SQL Data Shown in Main Window . . . . . . . . . . . . . 37
2.6 Changing the Column Header Text . . . . . . . . . . . . . . . . . . . 37
2.7 Running datatooltk via arara . . . . . . . . . . . . . . . . . . . . . . 40
2.8 Sample XLS File (First Sheet) . . . . . . . . . . . . . . . . . . . . . . 48
2.9 Processing \expandafter . . . . . . . . . . . . . . . . . . . . . . . . . 61
iv
List of Figures v
11.1 A Simple Form with Two Fill-In Areas and Two Check Boxes . . 336
11.2 A Simple Form with Multiple Check Box Areas . . . . . . . . . . . 345
11.3 A Simple Form with Multiple Check Box Areas and a Fill-In
Other Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
11.4 A Simple Form with a Text Area. . . . . . . . . . . . . . . . . . . . . 349
11.5 Example Interactive PDF Form Viewed in Adobe Reader . . . . . 352
11.6 Example Interactive PDF Form Viewed in Google Chrome . . . . 352
11.7 Example Interactive PDF Form Viewed in Okular . . . . . . . . . . 353
11.8 Example Interactive PDF Form Viewed in Sumatra . . . . . . . . . 353
11.9 Example Interactive PDF Form Viewed in Foxit on Linux . . . . . 354
11.10 Example Interactive PDF Form Viewed in Foxit on Windows . . . 354
11.11 First Attempt at Laying Out Check Boxes in Rows and Columns 358
11.12 Second Attempt at Laying Out Check Boxes in Rows and Columns358
11.13 Third Attempt at Laying Out Check Boxes in Rows and Columns 358
List of Figures vi
vii
List of Exercises
1 Loading and Displaying Data . . . . . . . . . . . . . . . . . . . . . . . . 56
2 Iterating Through Data . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3 Iterating Through a List . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4 Internal Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5 Oxford Comma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6 Fetching a Row of Data . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
7 Writing a Letter (letter class) . . . . . . . . . . . . . . . . . . . . . . . . 87
8 Writing a Letter (scrlttr2 class) . . . . . . . . . . . . . . . . . . . . . . . 96
9 Writing a Letter (newlfm class) . . . . . . . . . . . . . . . . . . . . . . . 99
10 Mail Merging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
11 Mail Merging With Envelope Labels Using newlfm, envlab and datatool119
12 Creating an Invoice for a Customer (isodoc class) . . . . . . . . . . . 122
13 Creating an Invoice for a Customer (invoice package) . . . . . . . . . 126
14 Custom Invoice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
15 Sample CV with Publications . . . . . . . . . . . . . . . . . . . . . . . . 133
16 List of Selected Publications (europecv class) . . . . . . . . . . . . . . . 145
17 Press Release (pressrelease class) . . . . . . . . . . . . . . . . . . . . . . 154
18 Minutes and Agendas (meetingmins class) . . . . . . . . . . . . . . . . . 156
19 Minutes (minutes package) . . . . . . . . . . . . . . . . . . . . . . . . . . 162
20 Extending the Maximum enumerate Depth . . . . . . . . . . . . . . . . 177
21 Numbered Paragraphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
22 Displaying Times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
23 Calendar for 2014 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
24 Creating an Exam Paper with the exam Class . . . . . . . . . . . . . . 246
25 Creating an Exam Paper with the exsheets Package . . . . . . . . . . 250
26 Creating an Assignment Sheet with the datatool Package . . . . . . . 273
27 Name Labels (Iteration) . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
28 A QR Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
29 Query Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
30 Simple Form Class with Check Boxes . . . . . . . . . . . . . . . . . . 344
31 A Pie Chart (datapie package) . . . . . . . . . . . . . . . . . . . . . . . . 368
32 A Bar Chart (bchart package) . . . . . . . . . . . . . . . . . . . . . . . . 373
viii
List of Examples
1 Convert a .csv File to a .dbtex File . . . . . . . . . . . . . . . . . . . 32
2 Convert an .xls Sheet to a .dbtex File . . . . . . . . . . . . . . . . . 33
3 Importing SQL Data to a .dbtex File . . . . . . . . . . . . . . . . . . . 36
4 Display Product List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5 Displaying Data Imported from a Spreadsheet . . . . . . . . . . . . . 56
6 Iterating Through Data . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
7 List of Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
8 Fetching the Data From Row 1 . . . . . . . . . . . . . . . . . . . . . . 75
9 Fetching a Customer’s Details . . . . . . . . . . . . . . . . . . . . . . . 76
10 Fetching a Customer’s Details (With Expansion) . . . . . . . . . . . . 77
11 Display Customer List (Null Values) . . . . . . . . . . . . . . . . . . . . 81
12 Writing a Simple Letter (letter class) . . . . . . . . . . . . . . . . . . . . 85
13 A Simple Letter (scrlttr2 class) . . . . . . . . . . . . . . . . . . . . . . . . 88
14 Writing a Letter: KOMA Settings . . . . . . . . . . . . . . . . . . . . . 94
15 A Simple Letter (newlfm class) . . . . . . . . . . . . . . . . . . . . . . . . 99
16 A Simple Letter (isodoc class) . . . . . . . . . . . . . . . . . . . . . . . . 103
17 Mail Merging (letter class) . . . . . . . . . . . . . . . . . . . . . . . . . . 105
18 Mail Merging (newlfm class) . . . . . . . . . . . . . . . . . . . . . . . . . 106
19 Envelope Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
20 Mail Merging with letter and envlab . . . . . . . . . . . . . . . . . . . . 115
21 Mail Merging with newlfm, envlab and datatool . . . . . . . . . . . . . . 117
22 An Invoice (isodoc class) . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
23 An Invoice (invoice package) . . . . . . . . . . . . . . . . . . . . . . . . . 125
24 Multi-Paged Tabulated Material . . . . . . . . . . . . . . . . . . . . . . 127
25 A Sample CV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
26 Personal Information Section (europecv class) . . . . . . . . . . . . . . 135
27 Curriculum Vitæ With Sections (europecv class) . . . . . . . . . . . . . 136
28 Tabulating a Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . 141
29 List of Publications (europecv class) . . . . . . . . . . . . . . . . . . . . . 144
30 Sample Memo (newlfm class) . . . . . . . . . . . . . . . . . . . . . . . . 148
31 Press Release (newlfm class) . . . . . . . . . . . . . . . . . . . . . . . . . 151
32 Sample Minutes (minutes package) . . . . . . . . . . . . . . . . . . . . . 158
33 Redaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
34 Watermarks (background package) . . . . . . . . . . . . . . . . . . . . . 168
35 Watermarks (xwatermark package) . . . . . . . . . . . . . . . . . . . . . 171
36 Nested Enumeration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
37 Displaying Dates and Times (datetime2 package) . . . . . . . . . . . . 184
38 Calculating Ages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
39 Custom Date Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . 191
40 Custom Date Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
41 Custom Date and Time Package . . . . . . . . . . . . . . . . . . . . . 199
42 Calendar for May 2014 . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
43 Presentation Themes (Boadilla) . . . . . . . . . . . . . . . . . . . . . . 232
44 Using Both the exam Class and the probsoln Package . . . . . . . . . 254
45 Randomly Selecting Problems . . . . . . . . . . . . . . . . . . . . . . . 262
46 Creating a Problem Sheet using datatool . . . . . . . . . . . . . . . . . 265
47 Randomly Selecting Problems Not Used in the Past Two Years . . 270
48 Random Selection with pgfmath and probsoln . . . . . . . . . . . . . . . 276
49 A Postcard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
50 Name Labels (ticket package) . . . . . . . . . . . . . . . . . . . . . . . . 286
51 Sample Leaflet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
52 Leaflet (with tikz) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
53 ISBN Bar Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
ix
List of Examples x
Advanced. This may include core TEX commands, internal LATEX kernel
commands, or programming concepts.
Most chapters start with the basic or intermediate symbol, but they may
progress to harder sections. Some of the exercises have a “More Adventurous”
part, which increases the difficulty level. There is, of course, a certain amount
of subjectivity in choosing the classifications for each section. What one person
may find straight-forward, may be more difficult to understand for someone
else, so these are just general guides.
To refresh your memory or for those who haven’t read other volumes in
this series, throughout this book source code is illustrated in a typewriter font
with the word Input placed in the margin, and the corresponding output (how it
will appear in the PDF document) is typeset with the word Output in the margin.
1
Chapter 1. Introduction 2
Example:
A single line of code is displayed like this:
This is an \textbf{example}. Input
Segments of code that are longer than one line are bounded above and below,
illustrated as follows:
↑ Input
Line one\par
Line two\par
Line three.
↓ Input
↑ Output
Line one
Line two
Line three.
↓ Output
In this case the command being defined is called \documentclass and text typed
⟨like this⟩ (such as ⟨options⟩ and ⟨class file⟩) indicates the type of thing you
need to substitute. (Don’t type the angle brackets!) For example, if you want
the scrbook class [47] you would substitute ⟨class file⟩ with scrbook and if you
want the letterpaper option you would substitute ⟨options⟩ with letterpaper,
like this:
\documentclass[letterpaper]{scrbook} Input
When it’s important to indicate a space, the visible space symbol is used. For
example:
A sentence consisting of six words. Input
When you type up the code, replace any occurrences of with a space. [FAQ: Spaces in macros]
Recall from Volume 1 [93, §2] that the comment character % is often used
to suppress unwanted space caused by the end of line (EOL) character in the
source code. For example:
↑ Input
Foo%
Bar
↓ Input
produces:
FooBar Output
These should be typed at the command prompt not in your LATEX document.
If a line of code must be typed without any EOL characters but is too long
to display on the page, the symbol line-wrap-symbol is used to indicate a line wrap. Make sure
you don’t insert a line break at that point.
If you are using an operating system with case-sensitive filenames (for example,
Unix-like systems), the ⟨name⟩ part must use the same case as the correspond-
ing filename ⟨name⟩.cls or ⟨name⟩.sty. If the case doesn’t match, the file
won’t be found. In the instance of operating systems with case-insensitive file-
names (such as Windows) the file will be found but there will most likely be a
warning that ⟨name⟩ doesn’t match the declared class or package name. To as-
sist you, this book will always match the filename case when referring to a class
or package, rather than the format used in the class or package’s manual. (For
example, pgf/tikz rather than pgf/TikZ or pstricks rather than PSTricks.) If I use
any upper case characters (for example, Alegreya or DejaVuSerif) then that means
the filename actually contains those upper case characters.
Recall from Volume 1 [93, §1.1] that package and class documentation can
be accessed via the texdoc application. For example:
texdoc datatool Shell
In the past couple of years that I’ve been writing this book, I’ve submitted
more bug reports than I have over the previous twenty or more years of using
LATEX. If it’s of any consolation to my fellow coders, I found more bugs in my
own code than anyone else’s. However this leads me onto a topic I haven’t really
covered in the previous two volumes (except, perhaps, briefly in Volume 1 [93,
§C]) and that’s the difference between commercial software and open source
software (aside from the obvious one of price).
When a company decides to produce a new piece of software, they usually
hire someone to do some market research to find out what potential customers
might need, then they hire a programmer (or group of programmers) to write
the code and then the software gets tested by a group of product testers. After
the buyer has purchased the software, they usually have access to a support
desk, customer helpline or chat. The person on the support desk may just have
a crib sheet of stock solutions for common issues and if the issue isn’t on that
list, the customer will probably be referred to a more technical support person.
In a few years’ time, the company may decide it’s no longer financially viable
to continue to provide or support that product. If the customer upgrades their
operating system (or buys a new computer with a newer operating system) the
software may no longer be able to run (or even install), and customers may
find themselves in a position where they can no longer access their data that’s
stored in a proprietary format.
Open source software, on the other hand, usually starts life when someone
has a need for an application or piece of code that doesn’t exist or exists but
is beyond their budget or exists but doesn’t run on their operating system. If
that person happens to be able to write code (or, perhaps, decides to take this
opportunity to learn) then they may be able to write something that fixes their
1.1 Packages and Document Classes 4
for TEX on StackExchange or the LATEX Community Forum. Are there many
results? If there aren’t, that could mean there’s not much interest in the package.
(Unless, again, it’s a very small package that’s too trivial to cause any issues.) If,
on the other hand, the result list is long and most of the answers involve hacks
using internal commands, then the package most likely falls under the first case.
If the result list is long and most of the answers don’t use internal commands
or indicate that there was a bug that has now been fixed or a new feature has
been added that solves the problem, then the package most likely falls under
the second case. A little time spent on this type of investigation could save you
a lot of grief later on.
Occasionally a package or class that has been under the second case for
some years suddenly loses maintenance. This is most likely due to a change
of circumstances for the developer. (None of us are immortal or immune to
adversity or the ageing process!) Fortunately, in the case of some popular
classes or packages other volunteers have agreed to take over maintenance.
The open source nature of the code makes this more likely than it would with
proprietary code.
1.2 Arara
Volume 2 [96, §1.1.2] introduced arara, a Java application that automates the
process of building a LATEX document. Since then, arara has evolved into ver-
sion 4.0 that has useful new features, including conditionals that can be used to
determine whether or not an application needs to be run.
To refresh your memory, or for those who haven’t read Volume 2 [96, §1.1.2],
you need to tell arara how to build your document by placing directives as
comments within your source code.
Example:
↑ Input
% arara: pdflatex
\documentclass{article}
\begin{document}
\section{A Sample Section}
This is a sample document.
\end{document}
↓ Input
This indicates that arara needs to run pdflatex so if the document file is called,
say, myDoc.tex, then the PDF file can be built using:
arara myDoc Shell
However, it may be that you only want to run pdflatex if the source code
has changed. With the new arara version 4.0, you can now add a conditional to
the directive:
% arara: pdflatex if changed("tex") Input
Now arara will only run pdflatex if the .tex file has changed. You can combine
tests using || (boolean or) && (boolean and) or ! (negation). For example:
1.2 Arara 6
This will now run pdflatex if the .tex file has changed or if the PDF file is
missing.
In addition to if (and the logically opposite unless) you can also have loops
using while (repeat while the condition is true) or until (repeat until the con-
dition is true).
Available tests that can be used in the conditions are listed below. The argu-
ment ⟨file ref⟩ indicates either an extension, such as "log", or a file reference,
such as toFile("xampl.bib"). In the case of just a file extension, such as "log",
the base is the same as the base of the source .tex file that contains the arara
directives. The argument ⟨regex⟩ indicates a regular expression.1
Example:
With earlier versions of arara, if your document had cross-references you
needed two pdflatex directives:
↑ Input
% arara: pdflatex
% arara: pdflatex
\documentclass{article}
\begin{document}
\section{A Sample Section}
Here is a cross-reference to
section~\ref{sec:another}.
\section{Another Section}
\label{sec:another}
\end{document}
↓ Input
However, if you make a change that doesn’t affect the cross-references, you
only need one invocation of pdflatex. The log file contains information if a
rerun is needed:
LaTeX Warning: There were undefined references.
↑ Input
A more general purpose expression to search for is “Rerun”, which may also
be used by some packages if they detect a rerun is required that is unrelated to
cross-references.
These tests can be combined in a loop. This can make for a long line in your
source code, but luckily another new feature of arara version 4.0 is the ability
to break the line using:
% arara: --> Input
↑ Input
% arara: pdflatex while (changed("tex")
% arara: --> || missing("pdf")
% arara: --> || missing("log")
% arara: --> || found("log", "Rerun"))
↓ Input
Now arara will repeatedly run pdflatex while the .pdf or .log files are missing
or while the .tex file has changed or while the log file contains “Rerun”. To
prevent an infinite process occurring, arara will break the loop if the condition is
still true after ten iterations. (This maximum value can be changed, if required.)
The above example provides a single pdflatex directive in the source code,
which is useful if no other applications are required, but this may need to be
broken up into multiple directives if another application, such as bibtex, needs
to be run.
Example:
This example has a citation from the sample xampl.bib database. (This sample
bibliography file should be provided with all modern TEX distributions.)
↑ Input
% arara: pdflatex if changed("tex") || missing("pdf")
% arara: bibtex if (missing("bbl")
% arara: --> || found("log", "Citation"))
% arara: pdflatex while (found("log", "Rerun"))
\documentclass{article}
\begin{document}
\section{A Sample Section}
Here is a cross-reference to
section~\ref{sec:another}.
A citation~\cite{book-minimal}.
\section{Another Section}
\label{sec:another}
\bibliographystyle{plain}
\bibliography{xampl}
\end{document}
↓ Input
Now arara will only run bibtex if the .bbl file is missing or if the log file
contains “Citation”, which will pick up the undefined citation warning:
LaTeX Warning: Citation `book-minimal' on page 1 undefined
Another possible test would be for any changes to the .bib file. In this case,
the .bib file doesn’t have the same root as the main .tex file, so I can’t just
do changed("bib"). Instead I need to indicate that I’m specifying the actual file
rather than the extension. This can be done using
1.2 Arara 8
changed(toFile("⟨filename⟩")) Input
B The boolean operators || and && are short-circuited. This means that under
certain circumstances, only the left-hand condition may be evaluated. For
example, if you have ⟨test1⟩ || ⟨test2⟩ then if ⟨test1⟩ is true, there’s no need to
evaluate ⟨test2⟩ (since both the boolean operations (“true” or “false”) and (“true”
or “true”) evaluate to “true”). Similarly, if you have ⟨test1⟩ && ⟨test2⟩ then if
⟨test1⟩ is false, there’s no need to evaluate ⟨test2⟩ (since both (“false” and “false”)
and (“false” and “true”) evaluate to “false”). You may therefore need to consider
the optimal ordering of any conditionals, such as placing changed or unchanged
at the start of the condition. Alternatively, you can use the non-short-circuited
operators | or &.
Chapter 2
Managing Data
Many of the topics covered in this book have examples that fetch row-and-
column style data from an external source, such as in a spreadsheet or struc-
tured query language (SQL) database. For example, in §3 Correspondence you
may want to pull the recipient’s details from a database or you may want to send
a template letter to everyone listed in a spreadsheet (mail merging).
This chapter covers accessing data from a CSV file or spreadsheet or from
a MySQL database (the most popular open source database [61]). The MySQL
Community Edition is freely downloadable, but there are also commercial ver-
sions available. The free version can be fetched from http://dev.mysql.com/
downloads/mysql/. In addition, this chapter also includes sections on topics that
aren’t specific to databases, but describe useful utility commands that are used
in some of the examples and exercises throughout this book.
B Some of the topics covered in this chapter are quite advanced. If you
don’t need to fetch data from an external source — for example if you
want to write a letter to someone but intend to explicitly write the recipient’s
address in your .tex file — then you can omit this chapter and skip ahead to §3
Correspondence.
There are a number of packages and applications available on CTAN that can
be used to fetch data, see the “Databases” of the TEX Catalogue Topic Index [25].
This book covers the datatool bundle (available on modern TEX distributions such
as TEX Live and MiKTEX1 ) and the datatooltk Java application (the installer and
source are available on CTAN). This book assumes you have the latest version
of datatool installed (version 2.23 at time of writing). If you want to try any of the
datatooltk examples here, ensure you are using the latest version (currently
1.6).
B IfAlthough
you are used to writing programming languages, take care with TEX.
TEX is Turing-complete, it is very different to most programming
languages. (In fact, it’s a document formatting language rather than a program-
ming language.) In, say, C or Java the source code is a series of assignments or
function calls or commands. Data is explicitly assigned to variables. In TEX the
source code consists of data interspersed with control sequences.2 whitespaces
forms part of the data (except at the start of lines or after control words). In
most programming languages foo( bar ) is equivalent to foo(bar) but in TEX
(and LATEX) \foo{ bar } is usually not the same as \foo{bar}.3 This is because
the entire contents of the argument is data not a variable or list of variables. You
may not like or agree with TEX’s unusual syntax, but no one has so far produced
a viable alternative to TEX that has the typesetting power and flexibility of TEX
but the structured coding of popular programming languages (although LuaTEX
comes close). Unless told otherwise, assume that spaces aren’t ignored.
1T
EX Live is included in the MacTeX distribution, and MiKTEX is included in the ProTeXt distribu-
tion.
2 Although LAT X adds the restriction that document text is only permitted within the document
E
environment.
3 Try doing \begin{ document } instead of \begin{document} in a LAT X document.
E
9
2.1 Utility Commands 10
This will interrupt the document build (as though an error had been encoun-
tered) and display the definition of ⟨token⟩ in the transcript. This command
can be used for testing purposes but it should be removed once it’s provided
you with the information you require. The tokens may be a control sequence or
a character, including special characters.
Examples
1. Suppose you’re thinking about defining a command called \c but you first
want to find out if it already exists:
↑ Input
\documentclass{article}
\show\c
\begin{document}
\end{document}
↓ Input
When you run LATEX on this document, the transcript will show:
> \c=macro:
->\OT1-cmd \c \OT1\c .
l.3 \show\c
?
2.1 Utility Commands 11
This tells you that \c is a macro (first line of the above) and it then gives
you the definition (second line of the above between -> and the terminat-
ing full stop). The rest of the message is just the regular error message
prompt, including the line number. If you type h at the prompt for help,
it will tell you that this isn’t actually an error message.
2. Suppose you’re now thinking about defining a command called \kern but
you first want to find out if it already exists:
↑ Input
\documentclass{article}
\show\kern
\begin{document}
\end{document}
↓ Input
> \kern=\kern.
l.3 \show\kern
This may seem a bit strange as it’s not showing you a definition, but in
this case (La)TEX is telling you that \kern is a primitives (a core command
that’s not defined in terms of any other command). If you try redefining
this particular command, the results will be disastrous.
3. Suppose you’re now thinking about defining a command called \tmp but
you first want to find out if it already exists:
↑ Input
\documentclass{article}
\show\tmp
\begin{document}
\end{document}
↓ Input
> \tmp=undefined.
l.3 \show\tmp
There’s a convenient Perl script called texdef that will display the definition
of a command without the need for you to use \show in your document. Syntax:
2.1 Utility Commands 12
where ⟨cs name⟩ is the name of the command you want to check without the
leading backslash. There are a number of options you can use. For example:
• -t ⟨format⟩
This indicates the TEX format. For example, -t latex means you’re
checking a LATEX command. On some systems, there’s a convenient short-
cut script:
• -c ⟨cls name⟩
This indicates that you want to check if the command is defined in a
document that uses the class ⟨cls name⟩.
• -p ⟨sty name⟩
This indicates that you want to check if the command is defined in a
document that uses the package ⟨sty name⟩.
For a complete list of options either use:
texdef --help Shell
or
texdoc texdef Shell
Example
Suppose you want to know the definition of the command \forlistloop pro-
vided by the etoolbox package:
texdef -t latex -p etoolbox forlistloop Shell
This displays:
\forlistloop:
macro:#1#2->\expandafter \etb@forlistloop \expandafter {#2}{#1}
This means that \forlistloop is a macro that has two arguments (indicated
by macro:#1#2) and the code after the arrow -> indicates the definition of
\forlistloop.
What about environments? The start of an environment ⟨envname⟩, is-
sued by the command \begin{⟨envname⟩}, performs some checks, starts a
group, stores the environment name in \@currenvir and does \⟨envname⟩.
The end of the environment \end{⟨envname⟩} checks that ⟨envname⟩ matches
\@currenvir, does \end⟨envname⟩ if that command exists, and then closes the
group. (This, incidentally, is why \newcommand won’t allow you to define a com-
mand where the name starts with end as it may interfere with the environment
end mechanism.)
Example
Suppose you want to know the definition of the figure environment:
2.1 Utility Commands 13
This displays:
\figure:
\long macro:->\@float {figure}
\endfigure:
\long macro:->\end@float
Alternatively you can use the -E switch:
texdef -t latex -E figure Shell
This displays:
\Large:
\long macro:->\@setfontsize \Large \@xivpt {18}
\endLarge:
undefined
This shows the definition of \Large but shows that \endLarge is undefined,
which means \Large can also be used as a declaration.
Now that you know how to check that your chosen macro name doesn’t
already exist, so you won’t accidentally cause a perplexing catastrophic error in
your document, the rest of this section will look at defining commands, while
the next section (§2.1.2) will look at modifying existing commands.
\let⟨new token⟩⟨token⟩ Definition
This command makes ⟨new tokens⟩ have the same definition as ⟨token⟩.
Example:
↑ Input
\let\myemph\emph
\myemph{Test}
↓ Input
produces:
Test Output
Note that this isn’t the same as defining \myemph to use \emph. If \emph is
later redefined, \myemph isn’t affected.
2.1 Utility Commands 14
Example:
↑ Input
\let\myemph\emph
\myemph{Test}.
\renewcommand{\emph}[1]{\textbf{#1}}
\myemph{Test}. \emph{Test}.
↓ Input
produces:
↑ Output
Test.
Test. Test.
↓ Output
The command \let may be prefixed with \global to make the assignment
have a global effect.
Example:
↑ Input
\newcommand{\myemph}[1]{\texttt{#1}}
\myemph{Test}. \emph{Test}.
{% start a group
\global\let\myemph\emph
\myemph{Test}.
\renewcommand{\emph}[1]{\textbf{#1}}%
\myemph{Test}. \emph{Test}.
}% end the group
\myemph{Test}. \emph{Test}.
↓ Input
produces:
↑ Output
Test. Test.
Test.
Test. Test.
Test. Test.
↓ Output
In this case, \myemph has retained its new definition after the end of the group,
but the original definition of \emph has been restored, because the effect of
\renewcommand only lasted until the end of the group.
\providecommand{⟨cs⟩}[⟨n-args⟩][⟨default⟩]{⟨definition⟩} Definition
This is like \newcommand except that it will only define the command if it doesn’t
already exist. If ⟨cs⟩ already exists, no change will be made to it. The syntax
is the same as for \newcommand.
Example:
↑ Input
\providecommand{\emph}[1]{\textbf{#1}}%
\emph{Test}.
↓ Input
2.1 Utility Commands 15
This produces:
Test. Output
Since \emph already exists, \providecommand had no effect. Compare this to:
↑ Input
\providecommand{\Emph}[1]{\textbf{#1}}%
\Emph{Test}.
↓ Input
which produces:
Test. Output
In this case \Emph didn’t exist, so it was okay for \providecommand to define it.
\def⟨cs⟩⟨arg syntax⟩{⟨definition⟩} Definition
This defines ⟨cs⟩ without checking if it already exists. The ⟨definition⟩ part is the
same as that for \newcommand, but with \def you don’t just specify the number
of arguments. Instead you declare the argument syntax in ⟨arg syntax⟩ where
each parameter is identified by #⟨n⟩ (where ⟨n⟩ is a number from 1 to 9).
Examples:
1. The simplest form is when you define a command that has no arguments.
For example:
↑ Input
produces:
↑ Input
\def\test#1#2{\emph{#1} \textbf{#2}}%
\test{First}{Second}
↓ Input
This produces:
3. This example defines a rather more complicated command that has the
syntax:
\test ⟨arg1⟩-⟨arg2⟩-⟨arg3⟩\endtest
Note that this doesn’t define a command called \endtest. The \endtest
token merely forms part of the argument syntax. This \test command
can now be used but only with the correct syntax:
This produces:
\test{First}{Second}{Third} 8
then you will get a runaway argument error:
Runaway argument?
{First}{Second}{Third}
! Paragraph ended before \test was complete.
B Within ⟨arg syntax⟩ the parameters must appear in ascending order (for
example, #2#1 is invalid); parameters can’t be repeated (for example, #1#1
is invalid); intermediate parameters can’t be skipped out (for example, #1#3 is
invalid). This is a restriction on ⟨arg syntax⟩ not on ⟨definition⟩.
\def only has a local effect, like \newcommand. If you want to globally define
a command, then you can use the analogous:
\gdef⟨cs⟩⟨arg syntax⟩{⟨definition⟩} Definition
and
\xdef⟨cs⟩⟨arg syntax⟩{⟨definition⟩} Definition
In both cases, the command being defined is set to the full expansion of ⟨definition⟩.
The first, \edef, only has a local effect. The second, \xdef, has a global effect.
Example:
This example illustrates the difference between the non-expansion \gdef and
the expansion \xdef:
↑ Input
\def\abc{abc}
\def\xyz{xyz}
{% start group
\def\abc{ABC}
\def\xyz{XYZ}
\gdef\test{\abc; \xyz}
\xdef\etest{\abc; \xyz}
\test. \etest.
}%
\test. \etest.
↓ Input
2.1 Utility Commands 17
This produces:
↑ Output
ABC; XYZ. ABC; XYZ.
abc; xyz. ABC; XYZ.
↓ Output
In this example, \test was just defined in terms of \abc and \xyz, so when
\test is executed, it uses the current definitions of those commands. On the
other hand, \etest was defined as the full expansion of \abc and \xyz. This
means that if the definitions of \abc and \xyz later change, \etest is unaffected.
B Take care when using \edef and \xdef that the definition doesn’t contain
fragile commands, as that can cause an error.
If you want to protect against fragile commands, LATEX provides additional
commands analogous to \edef and \xdef:
\protected@edef⟨cs⟩⟨arg syntax⟩{⟨definition⟩} Definition
and
\protected@xdef⟨cs⟩⟨arg syntax⟩{⟨definition⟩} Definition
Note that these are internal commands, so if you need to use them in your
document (rather than in a class or package), you need \makeatletter and
\makeatother. [FAQ: \@ and @ in macro
Note that \def, \gdef, \edef and \xdef all define short commands, unless names]
the prefix \long is used. For example:
\long\def\test#1{\emph{#1}} Input
This now allows a paragraph break within the argument of \test. For further
details see The TEXbook [46]. (Both \protected@edef and \protected@xdef also
define short commands, but they can’t be prefixed with \long.)
In addition to the TEX primitives and core LATEX commands described above,
the etoolbox package [51] also provides ways of defining commands.
\csdef{⟨cs name⟩}⟨arg syntax⟩{⟨definition⟩} Definition
This is analogous to \def except that you supply the control sequence name ⟨cs
name⟩ (without the leading backslash) instead of the actual control sequence.
Note that ⟨cs name⟩ must be fully expandable. The ⟨arg syntax⟩ is the same as
for \def.
Defining a control sequence by its name in this manner means that you can
have control sequences that include punctuation or digits or you can form the
control sequence name on the fly. This is the way that commands with labels
work. For example, recall the \newglossaryentry command from Volume 2 [96,
§6.1.2]. The first argument is a label, and this label is used in the name of the
internal control sequences that store the entry details. The datatool package’s
database commands described later in this chapter also use a similar technique.
The etoolbox package also provides:
\csgdef{⟨cs name⟩}⟨arg syntax⟩{⟨definition⟩} Definition
analogous to \gdef,
\csedef{⟨cs name⟩}⟨arg syntax⟩{⟨definition⟩} Definition
analogous to \edef,
\csxdef{⟨cs name⟩}⟨arg syntax⟩{⟨definition⟩} Definition
analogous to \xdef,
2.1 Utility Commands 18
analogous to \protected@xdef.
There are also commands analogous to \let:
\cslet{⟨cs name⟩}{⟨cs⟩} Definition
and
\csletcs{⟨cs name⟩}{⟨cs name⟩} Definition
where ⟨cs name⟩ is the name of a control sequence and ⟨cs⟩ is a control se-
quence.
You can use a control sequence by its name with:
\csuse{⟨cs name⟩} Definition
Remember that if the control sequence has been defined to have arguments,
you need to specify these afterwards. For example:
\csuse{section}{A Sample Section} Input
is equivalent to:
\section{A Sample Section} Input
If the control sequence doesn’t exist, \csuse{⟨cs name⟩} will expand to nothing.
An alternative is to use TEX’s primitives:
\csname ⟨cs name⟩\endcsname Definition
If the control sequence doesn’t exist, \csname will define the control sequence
to \relax before using it.
The etoolbox package also provides ways of determining if a command al-
ready exists using:
\ifdef{⟨cs⟩}{⟨true part⟩}{⟨false part⟩} Definition
where ⟨cs⟩ is the control sequence whose existence is being tested. Alternative
you can specify the control sequence name using:
\ifcsdef{⟨cs name⟩}{⟨true part⟩}{⟨false part⟩} Definition
In both cases, if the command has been defined, ⟨true part⟩ will be processed,
otherwise ⟨false part⟩ will be processed. You can also use the logically opposite
commands which check for non-existence:
\ifundef{⟨cs⟩}{⟨true part⟩}{⟨false part⟩} Definition
where ⟨cs name⟩ is a control sequence name. Although logically opposite, these
commands differ slightly from their existence counterparts as these commands
will consider a control sequence undefined if its definition is \relax.
If you don’t want to use the etoolbox package, the LATEX kernel provides the
internal commands:
\@ifundefined{⟨cs name⟩}{⟨true part⟩}{⟨false part⟩} Definition
which is equivalent to
\csname ⟨cs name⟩\endcsname Input
and
\@namedef{⟨cs name⟩}⟨arg syntax⟩{⟨definition⟩} Definition
Example
↑ Input
\newcommand{\mymacro}{x}%
\mymacro;
\appto\mymacro{AB}%
\mymacro;
\appto\mymacro{YZ}%
\mymacro.
↓ Input
This produces:
x; xAB; xABYZ. Output
↑ Input
\newcommand{\mymacro}{x}%
\newcommand{\myothermacro}{AB}%
\appto\mymacro{\myothermacro}
\renewcommand{\myothermacro}{YZ}%
\appto\mymacro{\myothermacro}
↓ Input
is equivalent to:
\newcommand{\mymacro}{x\myothermacro\myothermacro} Input
When you actually use \mymacro it will use whatever the definition of \myothermacro
is at the time, which may not be what you intended.
If you want ⟨code⟩ expanded before being appended to ⟨cs⟩ then you need
to use:
\eappto⟨cs⟩{⟨code⟩} Definition
So
2.1 Utility Commands 20
↑ Input
\newcommand{\mymacro}{x}%
\newcommand{\myothermacro}{AB}%
\eappto\mymacro{\myothermacro}%
\renewcommand{\myothermacro}{YZ}%
\eappto\mymacro{\myothermacro}
↓ Input
is equivalent to:
\newcommand{\mymacro}{xABYZ} Input
When you use any of the versions that expand the item, if the item contains
a command that shouldn’t be expanded, you need to use:
\noexpand⟨cs⟩ Definition
where ⟨cs⟩ is the command that shouldn’t be expanded. Fragile commands will
typically need to have their expansion suppressed. For example:
↑ Input
\newcommand{\mymacro}{x}%
\newcommand{\myothermacro}{AB}%
\eappto\mymacro{\noexpand\footnote{\myothermacro}}
↓ Input
is equivalent to:
\newcommand{\mymacro}{x\footnote{AB}} Input
Now the fragile \footnote command won’t be processed until \mymacro is used
later on in the document.
There are similar commands for prepending code to a command:
\preto⟨cs⟩{⟨code⟩} Definition
The expansion commands, such as \eappto and \epreto, fully expand ⟨code⟩.
This means that a recursive expansion is performed until everything is expanded
except commands that have been prefixed with \noexpand or commands that
don’t expand, such as primitives or robust commands. For example:
↑ Input
\newcommand{\mymacro}{x}%
\newcommand{\mymacroB}{\mymacroC}%
\newcommand{\mymacroC}{\mymacroD}%
\newcommand{\mymacroD}{Z}%
\eappto\mymacro{\mymacroB}
↓ Input
2.1 Utility Commands 21
is equivalent to:
\newcommand{\mymacro}{xZ} Input
It may be that you only want one-level of expansion. In which case you can use
the etoolbox command:
\expandonce⟨cs⟩ Definition
For example:
↑ Input
\newcommand{\mymacro}{x}%
\newcommand{\mymacroB}{\mymacroC}%
\newcommand{\mymacroC}{\mymacroD}%
\newcommand{\mymacroD}{Z}%
\eappto\mymacro{\expandonce\mymacroB}
↓ Input
is equivalent to:
\newcommand{\mymacro}{x\mymacroC} Input
There are also analogous commands that require the name (without the
leading backslash) of the control sequence:
\csappto{⟨cs name⟩}{⟨code⟩} Definition
(global version)
\cseappto{⟨cs name⟩}{⟨code⟩} Definition
(global version)
\cspreto{⟨cs name⟩}{⟨code⟩} Definition
(global version)
\csepreto{⟨cs name⟩}{⟨code⟩} Definition
(global version).
2.1.3 Arithmetic
TEX count registers only allow integer values. Even the registers that store
dimensions (such as \parindent) use integer arithmetic as TEX internally stores
lengths in terms of its sp unit (65 536 sp = 1 pt). There are, however, some
packages that allow you to perform decimal calculations using TEX (see, for
example, the calculation topic or the arithmetic topic).
However, first let’s look at just integer arithmetic, as that can be performed
more efficiently using TEX primitives that using LATEX packages. TEX count reg-
isters are defined using:
2.1 Utility Commands 22
This not only allocates a new register, but also assigns a control sequence
⟨register cs⟩ that can be used to reference the register. For example:
\newcount\mycount Input
For example:
\mycount = 25 Input
sets the value of the \mycount register to 25. Note that it’s sometimes necessary
to use \relax after the assignment to prevent TEX from prematurely expanding
the following tokens. 𝜀-TEX provides a primitives for evaluating expressions:
\numexpr⟨integer expression⟩ Definition
For example:
\mycount=\numexpr(25+5)/3 Input
It’s usually a good idea to put \relax after ⟨integer expression⟩ in case it hap-
pens to be followed by something that could be interpreted as part of the ex-
pression:
↑ Input
\mycount=\numexpr(25+5)/3\relax
-- this assignment is followed by an en-dash.
↓ Input
For example:
↑ Input
\mycount = 25\relax
\the\mycount
↓ Input
2.1 Utility Commands 23
produces:
25 Output
produces:
362.58263pt Output
For example:
↑ Input
\mycount = 25
\newcommand{\mynum}{40}%
Register: \number\mycount.
Macro: \number\mynum.
Number: \number46.
↓ Input
Produces:
Register: 25. Macro: 40. Number: 46. Output
↑ Input
\mycount = 12
\advance\mycount by -3
Result: \number\mycount.
↓ Input
produces:
Result: 9. Output
↑ Input
\mycount = 12
\multiply\mycount by 2
Result: \number\mycount.
↓ Input
2.1 Utility Commands 24
produces:
As before the by keyword may be omitted. Remember that this uses integer
arithmetic. For example:
↑ Input
\mycount = 25
\divide\mycount by 3
Result: \number\mycount.
↓ Input
produces:
Result: 8. Output
The pgfmath package is part of the pgf bundle, so if you intend loading pgf (or
tikz) in your document, it’s more efficient to use the pgfmath engine with datatool
to avoid the overhead of loading an additional package.
The fp and pgfmath packages use very different syntax to perform the same
calculations, but datatool provides the same interface commands regardless of
the underlying arithmetical package, so you can switch engines without having
to change your code, however you may find minor differences in the results,
caused by different levels of precision or rounding.
There are two types of arithmetical commands provided by datatool: those
that operate on raw plain numbers that use a full stop as the decimal point with
no group separator, and those that operate on locale dependent numbers or
currency. The first type are prefixed by dtl. For example:
\dtlround{⟨cs⟩}{⟨number⟩}{⟨num digits⟩} Definition
This rounds ⟨number⟩ to ⟨num digits⟩ decimal places and stores the result in
the control sequence ⟨cs⟩.
The second type are prefixed by DTL. For example:
\DTLround{⟨cs⟩}{⟨number⟩}{⟨num digits⟩} Definition
↑ Input
{% local scope
\dtlround\mynum{14.39999}{2}% perform rounding
\global\let\mynum\mynum
}
\mynum
↓ Input
2.1 Utility Commands 25
The locale versions (prefixed with DTL) come with two alternatives: a local ver-
sion and a global version. The global versions have the prefix DTLg such as:
\DTLground{⟨cs⟩}{⟨number⟩}{⟨num digits⟩} Definition
where ⟨number group char⟩ is the number group separator and ⟨decimal char⟩
is the decimal character. For example, to switch to commas for the decimal
character and a full stop for the number group separator:
\DTLsetnumberchars{.}{,} Input
Now, any numbers that use this format need to use the control sequences pre-
fixed with DTL instead of dtl:
↑ Input
\DTLsetnumberchars{.}{,}
\DTLround\mynum{1.250,2398}{2}\mynum.
↓ Input
This produces:
1.250,24. Output
↑ Input
\dtlround{\mynum}{14.399999999999999}{2}\mynum;
\dtlround{\mynum}{2.5}{2}\mynum.
↓ Input
produces:
14.40; 2.50. Output
↑ Input
\DTLround{\mynum}{2,014.399999999999999}{2}\mynum;
\DTLround{\mynum}{1,002.5}{2}\mynum.
↓ Input
produces:
2,014.40; 1,002.50. Output
The locale version \DTLround first converts the formatted number into a plain
number, performs the arithmetical operation, and then converts the result back
into a formatted number. Therefore, if your numbers are all plain numbers,
it’s more efficient to use \dtlround instead of \DTLround. Similarly for all the
commands described below.
Addition can be performed using:
\dtladd{⟨cs⟩}{⟨number 1⟩}{⟨number 2⟩} Definition
for the global locale version. In each case the sum of ⟨number 1⟩ and ⟨number
2⟩ is stored in the control sequence ⟨cs⟩.
Subtraction can be performed using:
\dtlsub{⟨cs⟩}{⟨number 1⟩}{⟨number 2⟩} Definition
for the global locale version. In each case ⟨number 1⟩ minus ⟨number 2⟩ is
stored in the control sequence ⟨cs⟩.
Multiplication can be performed using:
\dtlmul{⟨cs⟩}{⟨number 1⟩}{⟨number 2⟩} Definition
for the global locale version. In each case the product of ⟨number 1⟩ and
⟨number 2⟩ is stored in the control sequence ⟨cs⟩.
Division can be performed using:
\dtldiv{⟨cs⟩}{⟨number 1⟩}{⟨number 2⟩} Definition
for the global locale version. In each case ⟨number 1⟩ divided by ⟨number 2⟩
is stored in the control sequence ⟨cs⟩.
The absolute value can be obtained using:
\dtlabs{⟨cs⟩}{⟨number⟩} Definition
for the global locale version. In each case the absolute value of ⟨number⟩ is
stored in the control sequence ⟨cs⟩.
The negation can be obtained using:
\dtlneg{⟨cs⟩}{⟨number⟩} Definition
\DTLneg{⟨cs⟩}{⟨number⟩} Definition
for the global locale version. In each case the negative of ⟨number⟩ is stored
in the control sequence ⟨cs⟩.
There are also commands available to perform arithmetic operations on
a column of data stored in one of datatool’s internal database. However, these
use the DTL versions and since TEX isn’t designed for data management, it’s
better to perform these calculations in your spreadsheet or when you pull the
data from a SQL database.
B Remember
load the file.
to specify the separator and delimiter characters before you
For example, suppose your data is saved in a CSV file in the form:
2.2 Loading Data 28
For convenience, all the examples in this book assume the default comma sep-
arator and double-quote delimiter.
B When creating your CSV files be careful of spurious spaces. For example,
the following line of data:
Brown , Jane , Miss , 12356 8
isn’t the same as:
Brown,Jane,Miss,12356 4
If the CSV file contains extended characters, make sure the file was saved
with the same encoding as your LATEX document and use the inputenc [40] and
fontenc [59] packages.4 (See Volume 1 [93, §4.3.1].) The sample files that ac-
company this book all use UTF-8s encoding. Make sure you load the inputenc
package with the utf8 option before you load any of these CSV files.
Once your data is in a CSV file you can load it into a datatool database using:
\DTLloaddb[⟨options⟩]{⟨db-name⟩}{⟨filename⟩} Definition
where the CSV file is called ⟨filename⟩. The argument ⟨db-name⟩ is the data-
base label, as described above.
The \DTLloaddb command assumes the CSV file either doesn’t contain any
of TEX’s special characters (see Volume 1 [93, §4.3]) or, if it does, they form
correct LATEX code. If this isn’t the case, instead of using \DTLloaddb, you can
use:
\DTLloadrawdb[⟨options⟩]{⟨db-name⟩}{⟨filename⟩} Definition
Character Mapping
% \%
$ \$
& \&
# \#
_ \_
{ \{
} \}
~ \textasciitilde
^ \textasciicircum
\DTLrawmap{£}{\pounds} Input
B The commands \DTLloaddb and \DTLloadrawdb can’t read data where there
are EOL characters within a cell. For example, neither command can read
a CSV file that looks like:
Title,Price
"Duck and Goose’s
Adventures",10.00
"The Return of
Duck and Goose",11.00
If you have a CSV file in this form, you can use datatooltk to convert the CSV
file to a datatool (.dbtex) file, described in the next section.
You may have noticed that both \DTLloaddb and \DTLloadrawdb have an
optional argument. This is a key=value list. Available keys are as follows:
noheader This is a boolean keys. The value can be either false (the CSV file
has a header row, as in the examples above) or true (the CSV file
doesn’t have a header row). The default is false. If you want to set
this value you may omit =true, so noheader=true is the same as just
noheader.
keys Each column must have a unique label assigned to it. This makes
it easier to reference but, like the database label, the column label
mustn’t contain special characters. The default action of \DTLloaddb
and \DTLloadrawdb is to use the value given in the header row as
a label. This may be inappropriate, so you can set a different set
of labels using this option. The value must be a comma-separated
list of labels in the same order as the columns in the CSV file. For
example,
2.2 Loading Data 30
\DTLloaddb[keys={title,price}]{books}{booklist.csv} Input
↑ Input
omitlines The value must be a non-negative number indicating how many lines
to skip at the start of the CSV file. For example, if the CSV file
contains two lines of unwanted material at the start, then you need
to use omitlines=2.
Examples
1. Suppose your CSV file called products.csv looks like:
Title,Price (£)
"Duck & Goose's Adventures",10.00
"The Return of Duck & Goose",11.00
2.2 Loading Data 31
When you load this data into your document, you need to skip the first
three lines as they don’t form part of the data. You also need to map the
pound symbol (£) and the ampersand (&). Additionally, it’s a good idea to
provide short unique labels to identify the columns:
↑ Input
Here there isn’t a header row. You could assign labels as in the previous
example:
↑ Input
\DTLloaddb
[%
noheader,% no header row in file
keys={title,price},% column labels
headers={Title,Price (\pounds)}% column titles
]%
{products}% database label
{products.csv}% filename
↓ Input
↑ Input
\DTLloaddb
[%
noheader,% no header row in file
headers={Title,Price (\pounds)}% column titles
]%
{products}% database label
{products.csv}% filename
↓ Input
2.2 Loading Data 32
where ⟨filename⟩ is the name of the file including the .dbtex extension. (This
must come after \usepackage{datatool}.) If you can’t remember the label you
assigned to the data, you can reference it using:
\dtllastloadeddb Definition
This inputs ⟨filename⟩ and makes the control sequence ⟨cs⟩ have the same
value as \dtllastloadeddb. For example
\DTLloaddbtex{\people}{people.dbtex} Input
works like:
↑ Input
\input{people.dbtex}
\let\people\dtllastloadeddb
↓ Input
but it checks for the existence of the file people.dbtex and checks that the
new command (\people) isn’t already defined. Using \DTLloaddbtex is there-
fore safer than just using \input and \let. When you use commands like
\DTLdisplaydb (§2.6) and \DTLforeach (§2.7.1) you can now reference the data
using your new command (\people in this example).
The column title can be changed using:
\DTLsetheader{⟨db-name⟩}{⟨col-label⟩}{⟨title⟩} Definition
where ⟨db-name⟩ is the label identifying the data (\people in the above example),
⟨col-label⟩ is the label identifying the required column and ⟨title⟩ is the new
column title.
Example 1. Convert a .csv File to a .dbtex File
B The default CSV escape character is a backslash, which means that if your
data contains any control sequences the backslash will need to be doubled.
For example, \\pounds instead of \pounds. If this causes a problem, you can
change the CSV separator to a different character using datatooltk’s application
settings. (This doesn’t apply to any of the sample files provided with this book
as none of them contain any LATEX commands.)
On page 29 I mentioned that \DTLloaddb and \DTLloadrawdb can’t load CSV
files where there is an EOL within a cell, but datatooltk can. Let’s suppose the
file books-multiline.csv contains the following:
Title,Price
"Duck and Goose's
Adventures",10.00
2.2 Loading Data 33
"The Return of
Duck and Goose",11.00
This can be converted into a datatool (.dbtex) file using one of the following
methods:
1. Run datatooltk in batch mode from a command prompt:
The database label by default is taken from the CSV filename. If you want
to change it you can use the --name ⟨db-name⟩ option:
If you want to import an Excel .xls file to a datatool (.dbtex) file, you can use
the --xls and --sheet options to datatooltk. The argument of --xls is the
name of the .xls file and the argument of --sheet is either an integer (starting
from 0) indicating the sheet index or a string identifying the sheet label. Note
that no formatting information is read from the Excel file. Any font changes or
alignments should be made in your LATEX document. Similarly, you can import
an Open Document .ods spreadsheet using the --ods and --sheet options.
Example 2. Convert an .xls Sheet to a .dbtex File
Suppose you have an Excel file called, say, shop.xls and it contains two sheets:
“products” and “customers”. You can convert, say, the “customers” sheet to a file
called customers.dbtex using one of the following methods:
Or:
(The customer data is in the second sheet, but indices start from 0 so it’s
sheet 1.)
2. Run datatooltk in GUI mode using datatooltk-gui, as described above,
and set the map TEX characters option and header row settings if required.
Next use the FileÏImportÏImport Spreadsheet menu item. This will open a file
selector dialog box. Select the .xls file (shop.xls in this example) and
click on the “Import” button. Another dialog box will appear in which you
need to select the required sheet name (“customers” in this example).
Click on “Okay” and the data will be displayed in the main window. You
can then save the data to a .dbtex file using the FileÏSave As menu item.
Note that formatting information isn’t fetched from the spreadsheet. You
will have to add any necessary font changing commands when you display the
data. This helps to provide a consistent style throughout the document.
You can also use datatooltk to import data from a MySQL database. This
is slightly more complicated as you need to tell datatooltk the database, the
SQL SELECT statement5 , the user name and password. (You may also need to
change the SQL port and host, if different from the defaults.)
5 SQLstatements are beyond the scope of this guide, but for further details I recommend you read
“Managing & Using MySQL” [71].
2.2 Loading Data 36
This will prompt you for a password from the console. As before, you
can use the --map-tex-specials option if required.
Remember that you can use the SELECT statement to filter unwanted rows,
sort data or join the data with data from other tables.
If you use arara to build your document, you can use the datatooltk direc-
tive, but you must make sure you have at least v4.0 of arara installed.
Examples Using arara
1. Fetch the data from a CSV file called booklist.csv:
2.2 Loading Data 37
↑ Input
% arara: datatooltk: {
% arara: --> output: books.dbtex,
% arara: --> csv: booklist.csv }
% arara: pdflatex
\documentclass{article}
\usepackage{datatool}
\DTLloaddbtex{\books}{books.dbtex}
\begin{document}
% Do stuff with data.
\end{document}
↓ Input
Remember that you can also use conditionals to prevent unnecessary ap-
plication calls. For example:
↑ Input
% arara: datatooltk: {
% arara: --> output: books.dbtex,
% arara: --> csv: booklist.csv }
% arara: --> if changed(toFile("booklist.csv"))
% arara: --> || missing(toFile("books.dbtex"))
% arara: pdflatex while changed("tex")
% arara: --> || changed(toFile("books.dbtex"))
% arara: --> || missing("pdf")
% arara: --> || found("log", "Rerun")
\documentclass{article}
\usepackage{datatool}
\DTLloaddbtex{\books}{books.dbtex}
\begin{document}
% Do stuff with data.
\end{document}
↓ Input
2. Fetch the data from the sheet called “products” in an Excel .xls file called
shop.xls:
↑ Input
% arara: datatooltk: {
% arara: --> output: products.dbtex,
% arara: --> xls: shop.xls,
% arara: --> sheet: products }
% arara: pdflatex
\documentclass{article}
\usepackage{datatool}
\DTLloaddbtex{\products}{products.dbtex}
2.3 Security 39
\begin{document}
% Do stuff with data.
\end{document}
↓ Input
3. Fetch all the data from the table called books in a MySQL database called
samples:
↑ Input
% arara: datatooltk: {
% arara: --> output: books.dbtex,
% arara: --> sqldb: samples,
% arara: --> sqluser: sampleuser,
% arara: --> sql: "SELECT * FROM books" }
% arara: pdflatex
\documentclass{article}
\usepackage{datatool}
\DTLloaddbtex{\books}{books.dbtex}
\begin{document}
% Do stuff with data.
\end{document}
↓ Input
In this case, datatooltk will prompt you for the MySQL password asso-
ciated with the specified user name. There’s a slight difference between
running datatooltk directly from a terminal and running it via arara.
The terminal usually provides a console for datatooltk to use to prompt
for a password, but with arara there’s no console so you’ll get a dialog box
instead (even if you haven’t specified the --verbose option when you call
arara). See Figure 2.7. This will also happen if you invoke datatooltk
from another application, such as TeXworks.
If you’re thinking of using a conditional in the arara directive, there’s
B no platform-independent way of determining if the database has been
modified. The way the data is stored on the hard disk varies not only
according to the operating system but also with the way the table was
created (MyISAM, InnoDB, etc). For example, on my Linux computer
I could test if the file /var/lib/mysql/samples/books.MYD has changed,
but I would need to run arara with sudo in order to access the file, which
is unwise.
2.3 Security
When you import data from an SQL database, you need to enter the password
associated with the SQL user. This must be done each time you run datatooltk
with the --sql option. While it is possible to specify the password using the
--sqlpassword option, this is not advisable as it will be visible to anyone who
happens to be looking over your shoulder (and will probably be remembered
by the shell’s history). It’s also not advisable to include the password in an arara
directive since it can be read by anyone with access to the document source.
However, regardless of whether or not you use the --sqlpassword option,
any confidential data that was imported from the SQL database will be present
in the datatool (.dbtex) file, which other users may be able to access and read.
2.3 Security 40
Figure 2.7 Running datatooltk via arara uses a dialog box to prompt for a
MySQL password instead of using a console.
If your operating system supports different permissions for owner and others
(such as Unix-based systems) you can use the --owner-only option when invok-
ing datatooltk so that the permissions on the .dbtex are set to read and write
only for the owner. For example:
datatooltk --output people.dbtex --sqluser sampleuser
line-wrap-symbol
--sqldb samples --sql "SELECT * FROM people" Shell
line-wrap-symbol
--owner-only
This means that only the owner of the file (you, if you ran the datatooltk
command under your own user name) can read or write the people.dbtex file.
Any other users with an account on the same machine should not be able to
read or write that file. If your operating system doesn’t support different owner
and other permissions, the --owner-only option will have no effect.
If you are using arara the directive is:
↑ Input
% arara: datatooltk: {
% arara: --> output: people.dbtex,
% arara: --> sqluser: sampleuser,
% arara: --> owneronly: true,
% arara: --> sqldb: samples,
% arara: --> sql: "SELECT * FROM people" }
↓ Input
B Even if you take the precaution of setting the permissions on the .dbtex
file in this way, if you’ve used the data in your document, that data is also
likely to be present in the resulting PDF file. If this data is sensitive, you also
2.3 Security 41
need to consider changing the permissions of the PDF file as well and possibly
use something like pdftk to add encryption.
If your SQL database contains a mixture of private and public data, but you
only want to use the public data in your document, make sure you omit the
private data in your SELECT statement. For example, instead of using SELECT
* to fetch all columns replace the asterisk with just the columns you want to
fetch. Perhaps you only want to list the countries where you have customers,
then you’d just use SELECT country FROM people which would only write the
country information to the .dbtex file and not the individual customer details.
Remember that TEX discards comments in the form
% ⟨comment text⟩ Input
(unless the category codes of % is changed, for example, by the verbatim envi-
ronment). Here the comment text doesn’t get hidden or embedded within the
resulting PDF, but in other cases don’t assume that just because you can’t see
the text you’ve included in your source code it won’t be somehow present in the
PDF file. For example
\textcolor{white}{some text} Input
PDF elements, but obviously don’t do this if you don’t understand the code you’re
trying to embed.
You have control over the commands you enter into your source code, but
what about the document class or packages that you load? If you have the
shell escapes disabled or restricted, then this automatically prevents any class or
package from running dangerous applications. Some classes or packages may
embed JavaScript code if their purpose is to create an interactive PDF document.
If this concerns you, disable JavaScript in your PDF viewer, as mentioned above.
Remember also that class and package files can be viewed in any text editor, so
it’s possible to inspect the code. While this may not appeal to you, if it’s a well-
used class or package that’s on both MiKTEX and TEX Live, then the chances
are that someone else already has.
What about applications such as arara and latexmk? You can add code to
latexmk through the .latexmkrc file, but if you’re writing the code, you should
know what that code does. It’s possible to embed Java code within the conditional
part of arara directives, but again if you are writing the code it’s up to you
to ensure you don’t write anything dangerous. If someone else has supplied
a LATEX document that contains arara directives, you can search for them in
the document source file before running arara on it. However arara will only
execute a directive that has a corresponding .yaml file in its rules directory, and
you can also use --dry-run to see what commands would be executed.
Remember that if the application is available on TEX Live, then it has to have
the source available. In fact, since latexmk is a Perl script, you can open it in a
text editor. The arara directives are all defined in .yaml files, which again can
be viewed in a text editor. An active open source community with a central file
repository is far more likely to detect and flag malicious code than any users
of proprietary systems.
But what if someone accesses your computer and modifies the .latexmkrc
or .yaml files? In that case, you have far more to worry about than the integrity
of your TEX distribution.
Other security issues you might want to consider are discussed in §6.4 and
§13 Collaborating on Documents.
where ⟨db-name⟩ is the label that identifies the database. The ⟨criteria⟩ argu-
ment is a comma-separated list of column labels that indicate the sort order.
For example, if you first want to sort on the surname column and then on the
forenames column the ⟨criteria⟩ should be surname,forenames (make sure you
don’t have any unwanted spaces in the list). You can optionally add =⟨order⟩
after the column label where ⟨order⟩ is either ascending or descending. If
omitted, ascending is assumed. For example, to sort in descending order, first
by surname and then by forenames, the ⟨criteria⟩ should be:
surname=descending,forenames=descending
The ⟨handler⟩ argument is a control sequence that’s used for the comparisons.
The datatool package comes with four handlers:
1. A case-sensitive comparison:
\dtlcompare Definition
2. A case-insensitive comparison:
2.4 Sorting Data 43
\dtlicompare Definition
\dtlwordindexcompare Definition
\dtlletterindexcompare Definition
The last two are intended for indexes. If you want any further details about those
handlers, see the datatool user guide [95]. The first two handlers, \dtlcompare
and \dtlicompare, are the ones you’re most likely to need for administrative
purposes. The datatool package provides convenient shortcuts:
\DTLsort[⟨replacement list⟩]{⟨criteria⟩}{⟨db-name⟩} Definition
↑ Input
\DTLloaddb{books}{booklist.csv}
\DTLsort{author}{books}
↓ Input
• Or use datatooltk:
\DTLloaddbtex{\books}{books.dbtex} Input
\DTLloaddbtex{\books}{books.dbtex} Input
↑ Input
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
↓ Input
(or just fontspec [76] for XELATEX) and make sure your text editor is set to UTF-8s
encoding. The sample CSV files are as follows (you can download them from
the examples page):
1. booklist.csv (download)
This is a list of sample book titles. They could represent, say, products in
a shop or a reading list for students. The id column provides a number
that uniquely identifies the book. (This would typically be an ISBN in a real
life book list or the ISBN might be in an additional column.)
id,title,author,format,price
1,"The Adventures of Duck and Goose","Sir Quackalot",paperback,
line-wrap-symbol
10.99
2,"The Return of Duck and Goose","Sir Quackalot",paperback,
line-wrap-symbol
19.99
3,"More Fun with Duck and Goose","Sir Quackalot",paperback,
line-wrap-symbol
12.99
4,"Duck and Goose on Holiday","Sir Quackalot",paperback,
line-wrap-symbol
11.99
5,"The Return of Duck and Goose","Sir Quackalot",hardback,
line-wrap-symbol
19.99
6,"The Adventures of Duck and Goose","Sir Quackalot",hardback,
line-wrap-symbol
18.99
7,"My Friend is a Duck","A. Parrot",paperback,14.99
8,"Annotated Notes on the ‘Duck and Goose’ chronicles",
line-wrap-symbol
"Prof Macaw",ebook,8.99
9,"‘Duck and Goose’ Cheat Sheet for Students",
line-wrap-symbol
"Polly Parrot",ebook,5.99
10,"‘Duck and Goose’: an allegory for modern times?",
line-wrap-symbol
"Bor Ing",hardback,59.99
\DTLloaddb{books}{booklist.csv} Input
2. people.csv (download)
This is a list of sample people. They could represent, say, customers
or students or members of an organization. The id column provides
a number that uniquely identifies the person. (For example, a student’s
registration number.) The subscribed field indicates whether the person
wants to be subscribed to some form of mailing list where a value of 1
means they want to be subscribed. The gender column can be either “m”
(male) or “f” (female). The dob column is the date of birth in the ISO
format ⟨year⟩-⟨month⟩-⟨day⟩.
id,forenames,surname,title,address1,address2,town,county,
line-wrap-symbol
country,postcode,subscribed,gender,dob
1,Polly,Parrot,Miss,42 The Lane,,Some Town,Noshire,gb,
line-wrap-symbol
AB1 2XY,1,f,1970-12-31
2.5 Sample Data 46
\DTLloaddb{people}{people.csv} Input
3. country-codes.csv (download)
This is a list of country codes. It contains 250 lines. You can download the
entire file from the examples page. For brevity, only the header row and
the rows containing codes that are referenced in people.csv are shown
below:
code,name
br,Brazil
gb,United Kingdom
us,United States
\DTLloaddb{countries}{country-codes.csv} Input
4. ordergroups.csv (download)
This is a list of customer orders. The first column is a number that
uniquely identifies the order, the second column is a cross-reference to
the id field in the people.csv file above, indicating the purchaser, the
third column is a discount applied to the order, and the fourth column is
the cost of postage and packaging.
id,customerid,discount,postage
1,2,0,5.00
2,4,2.50,20.00
3,1,0,5.00
(In practice, this would typically have extra fields, such as the dispatch
status and order date.)
This file can be loaded using:
\DTLloaddb{ordergroups}{ordergroups.csv} Input
5. orders.csv (download)
This is a list of partial customer orders. Each row represents part of an
order for one of the book titles listed in booklist.csv by one of the people
listed in people.csv. There are four columns: the first is a number that
uniquely identifies each order part, the second is a number that identifies
the entire order (matching the id field in ordergroups.csv), the third
column is a cross-reference to the id field in the booklist.csv file above,
and the fourth column is the quantity ordered.
2.5 Sample Data 47
id,groupid,bookid,quantity
1,1,6,1
2,1,1,4
3,2,10,1
4,2,7,20
5,2,8,1
6,3,1,4
7,3,6,5
8,3,7,2
The first two rows form a single order (id 1 from the ordergroups.csv
file). The order consists of two parts: one copy of the book whose id
is 6 (the hardback version of “The Adventures of Duck and Goose”) and
four copies of the book whose id is 1 (the paperback version of “The
Adventures of Duck and Goose”). The next three rows form another
order (id 2 from ordergroups.csv). The order consists of three parts:
one copy of the book whose id is 10, twenty copies of the book whose
id is 7 and one copy of the book whose id is 8. The last four rows form
the third order (id 3 from ordergroups.csv). The order consists of three
parts: four copies of the book whose id is 1, five copies of the book whose
id is 6 and two copies of the book whose id is 7.
This file can be loaded using:
\DTLloaddb{orders}{orders.csv} Input
↑ Input
% arara: datatooltk: {
% arara: --> output: products.dbtex,
% arara: --> xls: shop.xls,
% arara: --> sheet: products }
↓ Input
You can also import Open Document .ods spreadsheets using a similar
method to the above but you need to use --ods instead of --xls.
2.5 Sample Data 48
(Alternatively, you can use one of the GUI MySQL tools, such as MySQL Work-
bench.)
The tables included in this sample database are analogous to the CSV files
described in §2.5.1. As with those files, some of the SQL tables include UTF-8s
characters, so you’ll also need to use:
↑ Input
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
↓ Input
(or just fontspec [76] for XELATEX) and make sure your text editor is set to UTF-8s
encoding.
The tables are defined as follows:
1. books
This table is created using:
2. people
This table is created using:
3. countries
This is a list of country codes. The table is created using:
This table contains 249 entries. For brevity, only the rows that contain
codes referenced in the people table are shown below:
You can view or download the complete list from the examples web page.
4. ordergroups This is a list of order groups. The table is created using:
5. orders
This is a list of partial orders. The table is created using:
This data can be fetched via datatooltk. For example, to fetch the data from
the books table:
datatooltk --output books.dbtex --sqluser sampleuser
line-wrap-symbol Shell
--sqldb samples --sql "SELECT * FROM books"
↑ Input
% arara: datatooltk: {
% arara: --> output: books.dbtex,
% arara: --> sqluser: sampleuser,
% arara: --> sqldb: samples,
% arara: --> sql: "SELECT * FROM books" }
↓ Input
The resulting file books.dbtex can now be loaded in your document via:
\DTLloaddbtex{\books}{books.dbtex} Input
If required, the column headers can be set using \DTLsetheader. For example:
↑ Input
\DTLsetheader{\books}{id}{ID}
\DTLsetheader{\books}{title}{Title}
\DTLsetheader{\books}{author}{Author}
\DTLsetheader{\books}{format}{Format}
\DTLsetheader{\books}{price}{Price (\pounds)}
↓ Input
2.6 Displaying Tabulated Data 53
Remember you can use the SELECT statement to sort or filter the data or join
with another table. For example, if you only want to fetch customers in the UK
and order them by their surname:
datatooltk --output people.dbtex --sqluser sampleuser
line-wrap-symbol
--sqldb samples --sql "SELECT * FROM people Shell
line-wrap-symbol
WHERE country='gb' ORDER BY surname"
where ⟨db-name⟩ is the database label. The optional argument ⟨omit list⟩ is
a comma-separated list of labels indicating which columns you want omitted
from the tabular environment. Make sure you don’t have any unwanted spaces
in ⟨omit list⟩.
The \DTLdisplaydb command uses a tabular environment internally and should
typically go inside a table environment. If the data is too big to fit on one page,
you can instead use:
\DTLdisplaylongdb[⟨options⟩]{⟨db-name⟩} Definition
This uses the longtable environment defined by the longtable package [11] instead
of the tabular environment (see §4.3). As with \DTLdisplaydb, ⟨db-name⟩ indi-
cates the label identifying the data. Note that \DTLdisplaylongdb should not be
put inside a table environment.
The optional argument ⟨options⟩ is a key=value list. The following keys are
available:
caption The caption for the longtable.
contcaption The continuation caption for the longtable.
shortcaption The caption to be used in the list of tables.
label The label for this table. (To be used in \ref{⟨label⟩}, if required.)
omit Comma-separated list of labels identifying columns to be omitted.
foot The longtable’s foot.
lastfoot The foot for the last page of the longtable.
Remember to load the longtable package if you want to use \DTLdisplaylongdb.
Example 4. Display Product List
Suppose I want to display the data from my sample booklist.csv file in a table
environment, but I don’t want to include the id or author columns:
↑ Input
% Load "booklist.csv":
\DTLloaddb
[headers={Id,Title,Author,Format,Price (\pounds)}]% column headers
{books}{booklist.csv}
\begin{table}[htbp]
\caption{Products}
\label{tab:products}
\centering
\DTLdisplaydb[id,author]{books}
\end{table} ↓ Input
2.6 Displaying Tabulated Data 54
↑ Input
% arara: datatooltk: {
% arara: --> output: books.dbtex,
% arara: --> sqldb: samples,
% arara: --> sqluser: sampleuser,
% arara: --> sql: "SELECT title, author, price FROM books" }
↓ Input
Once the file books.dbtex has been created I can load it into my document
using:
\DTLloaddbtex{\books}{books.dbtex} Input
↑ Input
\DTLsetheader{\books}{title}{Title}
\DTLsetheader{\books}{author}{Author}
\DTLsetheader{\books}{format}{Format}
\DTLsetheader{\books}{price}{Price (\pounds)}
↓ Input
(Alternatively, if I import the SQL data using datatooltk-gui I can set the header
text by double-clicking on the column header as described in §2.2.2.)
The table can now be created in the same way as before. Putting it all
together:
↑ Input
% Load "books.dbtex":
\DTLloaddbtex{\books}{books.dbtex}
\DTLsetheader{\books}{author}{Author}
\DTLsetheader{\books}{format}{Format}
\DTLsetheader{\books}{price}{Price (\pounds)}
\begin{table}[htbp]
\caption{Products}
\label{tab:products}
\centering
\DTLdisplaydb[id,author]{books}
\end{table}
↓ Input
↑ Input
\usepackage{longtable}
\usepackage{datatool}
↓ Input
↑ Input
\DTLdisplaylongdb
[
caption={A Sample Long Table},% main caption
contcaption={A Sample Long Table (Continued)},% continuation
label={tab:countries},% table label
foot={\emph{Continued on next page}},% table foot
lastfoot={}% final table foot
]
{countries}
↓ Input
You can download or view the full example document using CSV files, or
download or view the example using a SQL database.
then
↑ Input
\begin{table}
\caption{Data imported from \texttt{shop.xls}}
\label{tab:xlsproducts}
\centering
\DTLdisplaydb{\xlsproducts}
\end{table}
↓ Input
produces Table 2.3. Note that the second and third columns are no longer
displayed as currency nor are the numbers rounded to two decimal places. (See
Example 6 for a different approach that rounds and formats the price columns.)
which is done after the header row. In the case of \DTLdisplaylongdb, the
hooks \dtldisplaystarttab and \dtldisplayafterhead are used before and
after the header row on each page of the longtable, but \dtldisplayendtab is
only used on the last page of the longtable. You will need to use the foot option
2.7 Iteration 57
if you want to specify code that should appear at the bottom of every page of
the longtable.
These three commands default to nothing, but you can redefine them before
you display the data. For example, recall from Volume 1 [93, §4.6.3] that the
booktabs package [24] provides:
\toprule[⟨wd⟩] Definition
for a horizontal rule between rows. See if you can edit your example document
to include these rules in the table displaying the list of products.
You can download or view the solution to this exercise.
2.7 Iteration
[FAQ: Repeating a
This section covers iterating over data. The datatool package provides a way of command 𝑛 times]
iterating over rows of a database, discussed in §2.7.1, but you may also find you [FAQ: Repeating
need to iterate over a comma-separated lists, so this is discussed in §2.7.2. If something for each
you want to manually build up a list and then iterate over it, you may prefer to ‘thing’ in a set]
use etoolbox’s internal lists, discussed in §2.7.3. For a more general purpose loop
ability, you may prefer to use TEX’s \loop, discussed in §2.7.4.
The unstarred version allows you to modify the data stored internally (that is,
in TEX’s registers used by datatool, not in the original loaded or imported source).
As it’s more efficient to do any modifications in your spreadsheet or via SQL
these datatool commands aren’t covered here. Instead, all the examples in this
document will use the read-only starred version, which compiles faster. The
parameters for both versions are as follows:
⟨db-name⟩ The label identifying the internal database.
⟨assign⟩ A comma-separated list of ⟨cs⟩=⟨col-label⟩ assignments where ⟨cs⟩
is a control sequence that can be used as a placeholder in ⟨body⟩
and ⟨col-label⟩ is the label identifying the required column. Spaces
aren’t ignored in this list (except after ⟨cs⟩ as per TEX’s normal
behaviour). There is no check for the existence of ⟨cs⟩ so be
careful you don’t accidentally overwrite an existing command. You
only need to assign control sequences to the columns whose values
you intend to use in ⟨body⟩. Assignments are performed with the
\global prefix to ensure that \DTLforeach works correctly within
a tabular (or similar) environment.
⟨body⟩ The code to do for each row of data where the condition given in
the optional argument is true.
2.7 Iteration 58
↑ Input
\DTLforeach*
[\equal{\Surname}{Canary}]% condition
{people}% database
{\Surname=surname,\Forenames=forenames}% assignments
{\Forenames. }% body
↓ Input
which produces:
↑ Input
\begin{table}
\caption{Formatted data imported from \texttt{shop.xls}}
\label{tab:xlsproducts2}
\centering
\begin{tabular}{lrr}
\multicolumn{1}{c}{\bfseries Product} &
\multicolumn{1}{c}{\bfseries Price (ex VAT)} &
\multicolumn{1}{c}{\bfseries Price (inc VAT)}%
\DTLforeach*{xlsproducts}%
{%
\Product=Product,%
\exPrice=Price (ex VAT),%
\incPrice=Price (inc VAT)%
2.7 Iteration 59
}%
{%
\\\Product &
\dtlround{\exPrice}{\exPrice}{2}\pounds\exPrice &
\dtlround{\incPrice}{\incPrice}{2}\pounds\incPrice
}%
\end{tabular}
\end{table}
↓ Input
which produces Table 2.4. Note that the new row command \\ is put at the start
of ⟨body⟩ to ensure a new line starts after the header entries. It’s usually best
to put \\ at the start of ⟨body⟩ as it may cause a problem if it’s placed later in
that argument. You can download or view the complete document.
Output
Table 2.4 Formatted Data Imported From shop.xls
Id Author Title
5 Sir Quackalot The Return of Duck and Goose
6 Sir Quackalot The Adventures of Duck and Goose
10 Bor Ing ‘Duck and Goose’: an allegory for modern times?
Id Author Title
1 Sir Quackalot The Adventures of Duck and Goose
2 Sir Quackalot The Return of Duck and Goose
3 Sir Quackalot More Fun with Duck and Goose
4 Sir Quackalot Duck and Goose on Holiday
7 A. Parrot My Friend is a Duck
Id Author Title
8 Prof Macaw Annotated Notes on the ‘Duck and Goose’ chronicles
9 Polly Parrot ‘Duck and Goose’ Cheat Sheet for Students
\docsvlist{⟨item1,item2,. . . ⟩} Definition
at each iteration, where ⟨item⟩ is the current item in the list. It’s up to the user
to define \do before using \docsvlist. For example:
↑ Input
\renewcommand{\do}[1]{#1. }%
\docsvlist{Parrot,Canary,Zebra,Arara,Duck}
↓ Input
produces:
Parrot. Canary. Zebra. Arara. Duck. Output
Alternatively you can provide your own handler instead of \do using
\forcsvlist{⟨handler cs⟩}{⟨list⟩} Definition
For example:
↑ Input
\newcommand{\mylistitem}[1]{#1. }%
\forcsvlist{\mylistitem}{Parrot,Canary,Zebra,Arara,Duck}
↓ Input
↑ Input
\newcommand*{\mylist}{Parrot,Canary,Zebra,Arara,Duck}%
\renewcommand{\do}[1]{#1. }%
\docsvlist{\mylist} 8
↓ Input
then you’ll only have a list with a single item (\mylist) so you’ll just have the
one iteration
\do{\mylist} Input
Instead you need to make sure the argument is expanded before it’s processed
by \docsvlist:
↑ Input
\newcommand*{\mylist}{Parrot,Canary,Zebra,Arara,Duck}%
\renewcommand{\do}[1]{#1. }%
\expandafter\docsvlist\expandafter{\mylist} 4
↓ Input
2.7 Iteration 61
The \expandafter commands may look a bit confusing but the syntax is
\expandafter ⟨token 1⟩⟨token 2⟩ Definition
This makes TEX expand ⟨token 2⟩ before it processes ⟨token 1⟩, so it’s equivalent
to:
⟨token 1⟩⟨expansion of token 2⟩
Therefore
\expandafter \docsvlist \expandafter
↑ ↑
⟨token 1⟩ ⟨token 2⟩
means that TEX must expand the thing after \docsvlist before it does \docsvlist
(step ¬ in Figure 2.9), but that thing happens to be another \expandafter:
\expandafter {\mylist
⟨token 1⟩↗ ↖⟨token 2⟩
This means that before TEX processes the left brace character { it must first
expand the tokens after it (step ), so that \mylist is replaced with its definition
(step ®).
So TEX starts out with the first \expandafter, skips over \docsvlist ¬ and
does the second \expandafter which makes TEX skip over the open brace
and expand \mylist, which replaces \mylist with its definition ®.
Parrot,Canary,Zebra,Arara,Duck
¬
Once \mylist has been expanded, TEX then goes back to the \docsvlist
command, which is now in the form:
\docsvlist{Parrot,Canary,Zebra,Arara,Duck}
In the case of \forcsvlist, this becomes more complicated as the list is the
second argument. However, since the first argument is just a single control
sequence it doesn’t need to be grouped and can therefore be skipped over with
another \expandafter. For example:
↑ Input
\newcommand*{\mylist}{Parrot,Canary,Zebra,Arara,Duck}%
\newcommand{\mylistitem}[1]{#1. }%
\expandafter\forcsvlist\expandafter\mylistitem\expandafter{\mylist}
↓ Input
The datatool package also provides some comma-separated list related com-
mands:
\DTLifinlist{⟨item⟩}{⟨list⟩}{⟨true⟩}{⟨false⟩} Definition
\DTLnumitemsinlist{⟨list⟩}{⟨cs⟩} Definition
This counts the number of non-empty items in ⟨list⟩ and stores the result in the
control sequence ⟨cs⟩. Again, a one-level expansion is performed on ⟨list⟩.
Example:
↑ Input
\newcommand{\mylist}{Parrot,Canary,Zebra,Arara,Duck}%
Parrot
\DTLifinlist{Parrot}{\mylist}{is}{isn't}
in the list.
Number of items in the list:
\DTLnumitemsinlist{\mylist}{\numitems}\numitems. ↓ Input
produces:
Parrot is in the list. Number of items in the list: 5. Output
Spaces
Remember what I mentioned on page 9 about being careful of spaces? Here’s
an illustration of unexpected behaviour involving spaces in lists:
↑ Input
\renewcommand{\do}[1]{``#1''. }%
\docsvlist{ Parrot , Canary , Zebra , Arara , Duck } ↓ Input
This produces:
“Parrot ”. “Canary ”. “Zebra ”. “Arara ”. “Duck ”. Output
The leading spaces have been ignored but the trailing spaces are still present.
The LATEX kernel has a command that can also iterate through a comma-
separated list but it’s an internal command:
\@for⟨cs⟩:=⟨list⟩\do{⟨body⟩} Definition
This iterates through ⟨list⟩ and assigns the control sequence ⟨cs⟩ to the current
item in the list so that it can be used as a placeholder in ⟨body⟩. Note that in
this context \do doesn’t refer to etoolbox’s \do handler macro but is used as an
argument delimiter (so it’s like plain TEX syntax rather than LATEX syntax). Since
\@for is an internal commands it should only be used in a package or class file.
If it has to be used in the document, it should be placed between \makeatletter
and \makeatother like this:
↑ Input
\makeatletter
\@for\thisitem:=Parrot,Canary,Zebra,Arara,Duck\do{\thisitem. }
\makeatother ↓ Input
This produces:
Parrot. Canary. Zebra. Arara. Duck. Output
↑ Input
\newcommand*{\mylist}{Parrot,Canary,Zebra,Arara,Duck}%
\makeatletter
\@for\thisitem:=\mylist\do{\thisitem. }
\makeatother ↓ Input
2.7 Iteration 63
produces the same result as above. However, now let’s look at what happens
when we introduce spaces into the list again:
↑ Input
\makeatletter
\@for\thisitem:= Parrot , Canary , Zebra , Arara , Duck \do
{``\thisitem''. }
\makeatother
↓ Input
This produces:
“ Parrot ”. “ Canary ”. “ Zebra ”. “ Arara ”. “ Duck ”. Output
In this case both the leading and trailing spaces have been retained.
The etextools package [15] also provides commands to iterate over lists. For
example:
\csvloop[⟨auxiliary commands⟩]{⟨list⟩} Definition
The \csvloop macro iterates over the comma-separated list given in ⟨list⟩
(which may be a macro that expands to a list) and at each iteration does ⟨auxiliary
commands⟩. If this optional argument is missing, \do is assumed, which be-
haves in the same way as with etoolbox’s \docsvlist command. So
↑ Input
\renewcommand{\do}[1]{#1. }%
\csvloop{Parrot,Canary,Zebra,Arara,Duck}
↓ Input
produces
Parrot. Canary. Zebra. Arara. Duck. Output
↑ Input
\renewcommand{\do}[1]{``#1''. }%
\csvloop{ Parrot , Canary , Zebra , Arara , Duck }
↓ Input
This produces:
“ Parrot ”. “Canary ”. “Zebra ”. “Arara ”. “Duck ”. Output
In this case the leading space has been retained on the first item, but not on
any of the other items, but all the trailing spaces have been retained.
section introduces one of etextools commands for illustrative purposes,
B Thisbut some of the commands in etextools and etoolbox conflict. For example,
both packages define a command called \forlistloop but the syntax is incom-
patible. Since datatool automatically loads etoolbox this means that datatool and
etextools may also conflict.
Another package is pgffor (part of the pgf bundle [102]) which provides:
\foreach ⟨variables⟩ [⟨options⟩] in {⟨list⟩}{⟨body⟩} Definition
↑ Input
\foreach \thisitem in {Parrot,Canary,Zebra,Arara,Duck}
{\thisitem. }
↓ Input
2.7 Iteration 64
which produces:
Parrot. Canary. Zebra. Arara. Duck. Output
↑ Input
This produces:
“Parrot ”. “Canary ”. “Zebra ”. “Arara ”. “Duck ”. Output
which is the same result as with \docsvlist where the trailing spaces have
been retained but not the leading spaces.
This is why it’s important to ensure any spurious spaces are removed from
comma-separated lists in your source code. It may be that some commands trim
all spaces (for example in the optional argument of \usepackage or \documentclass),6
while some commands only trim leading spaces (as with \docsvlist and \foreach)
but others don’t trim any spaces (such as \cite, which internally uses \@for).
Remember that you can comment out space caused by the EOL character, and
spaces at the start of lines are automatically discarded by TEX, so to make your
code clearer you can do, for example:
↑ Input
\docsvlist
{%
Parrot,%
Canary,%
Zebra,%
Arara,%
Duck%
}
↓ Input
If you comment an EOL character that would naturally be discarded (for ex-
ample, following a control sequence) there’s no harm done, but if you forget
to comment an unwanted EOL character, you can end up with weird spaces in
your document or an error message.
Empty Items
In addition to watching out for spurious spaces, you also need to consider what
happens if you have an empty item in your list. Do you want empty items
skipped or should they be processed either in the same way as the other items
or by displaying a missing data symbol, such as an em-dash? Let’s look at how
the above comma-separated list processing commands deal with this type of
situation:
↑ Input
\renewcommand{\do}[1]{``#1''. }
\docsvlist{,Parrot,Canary,Zebra„Arara,Duck,}
\csvloop{,Parrot,Canary,Zebra„Arara,Duck,}
6 Infact, all spaces are stripped from the optional argument of those two commands, so it’s techni-
cally possible to do, say, \usepackage[dr aft]{graphics} although I don’t recommend you do
this.
2.7 Iteration 65
\foreach\thisitem in {,Parrot,Canary,Zebra„Arara,Duck,}
{``\thisitem''. }
\makeatletter
\@for\thisitem:=,Parrot,Canary,Zebra„Arara,Duck,\do
{``\thisitem''. }
\makeatother ↓ Input
↑ Output
“Parrot”. “Canary”. “Zebra”. “Arara”. “Duck”.
“Parrot”. “Canary”. “Zebra”. “Arara”. “Duck”.
“”. “Parrot”. “Canary”. “Zebra”. “”. “Arara”. “Duck”. “”.
“”. “Parrot”. “Canary”. “Zebra”. “”. “Arara”. “Duck”. “”.
↓ Output
So \docsvlist and \csvloop both skip empty items but \foreach and \@for
don’t.
Exercise 3. Iterating Through a List
Create a document that defines the commands:
↑ Input
\newcommand*{\mylistI}{A,B,C,D}
\newcommand*{\mylistII}{a,b,c,d} ↓ Input
then create the tabular environment shown in Table 2.8 using \docsvlist to
construct columns 2 to 5 for each row.
Table 2.8 Lists for Iteration Exercise
List 1: A B C D
List 2: a b c d
Next, redefine \mylistII so the third item is empty and redo the tabular
environment. Finally, define a command called \missingdata that does nothing
and redefine \mylistII so the third item is \missingdata and redo the tabular
environment.
You can download or view the solution to this exercise.
where ⟨list cs⟩ is the command used to store the list (\mylist in the above
example) and ⟨item⟩ is the item to add to the list. Note that the ⟨item⟩ doesn’t
get expanded and a blank item won’t be added to the list. For example:
2.7 Iteration 66
↑ Input
\listadd{\mylist}{Parrot}
\listadd{\mylist}{Parrot, Jr}
↓ Input
If the item needs to be expanded before being added to the list, you can use:
\listeadd{⟨list cs⟩}{⟨item⟩} Definition
As with \listadd, a blank item won’t be added to the list. For example:
↑ Input
\newcommand*{\Name}{Canary}
\listeadd{\mylist}{\Name}
↓ Input
There are also similar commands where you supply the name of the list macro
without the leading backslash:
\listcsadd{⟨list csname⟩}{⟨item⟩} Definition
↑ Input
\renewcommand*{\Name}{Zebra}
\listcseadd{mylist}{\Name}
\listcsadd{mylist}{Arara}
↓ Input
These commands all use local assignments, so they’re limited to the current
scope. There are analogous commands that use global assignments:
\listgadd{⟨list cs⟩}{⟨item⟩} Definition
↑ Input
Parrot
\ifinlist{Parrot}{\mylist}{is}{isn't}
in the list.
↓ Input
2.7 Iteration 67
For example:
↑ Input
\newcommand*{\Name}{Parrot}%
\Name\ \xifinlist{\Name}{\mylist}{is}{isn't} in the list.
↓ Input
There are also analogous commands where the list control sequence name
(without the leading backslash) is supplied:
\ifinlistcs{⟨item⟩}{⟨list csname⟩}{⟨true⟩}{⟨false⟩} Definition
where ⟨list cs⟩ is the control sequence storing the list (\mylist in the above ex-
amples). If you prefer to supply the control sequence name without the leading
backslash, you can use:
\dolistcsloop{⟨list csname⟩} Definition
Both these commands use \do{⟨item⟩} at each iteration, in the same way as for
\docsvlist described earlier. For example:
↑ Input
\newcommand*{mylist}{}%
\listadd{\mylist}{Parrot}%
\listadd{\mylist}{Canary}%
\listadd{\mylist}{Zebra}%
\listadd{\mylist}{Arara}%
\listadd{\mylist}{Duck}%
\renewcommand*{\do}[1]{#1. }%
\dolistloop{\mylist}
↓ Input
produces:
Parrot. Canary. Zebra. Arara. Duck. Output
Alternatively, you can provide your own handler instead of using \do:
\forlistloop{⟨handler cs⟩}{⟨list cs⟩} Definition
where ⟨handler cs⟩ is the command to use on each iteration of the list and ⟨list
cs⟩ is the list control sequence. If you prefer to supply the list control sequence
name without the leading backslash you can use:
\forlistcsloop{⟨handler cs⟩}{⟨list csname⟩} Definition
2.7 Iteration 68
↑ Output
The Adventures of Duck and Goose
The Return of Duck and Goose
More Fun with Duck and Goose
Duck and Goose on Holiday
My Friend is a Duck
Annotated Notes on the ‘Duck and Goose’ chronicles
‘Duck and Goose’ Cheat Sheet for Students
‘Duck and Goose’: an allegory for modern times?
↓ Output
This repeats ⟨code⟩ while the given condition is true. The \if... part should
be one of TEX’s conditionals, such as \ifnum, without the terminating \fi.
Example:
For example, to print the numbers from 1 to 10:
↑ Input
\newcount\mycount
\loop
\advance\mycount by 1\relax
\the\mycount.
\ifnum\mycount<10
\repeat
↓ Input
This produces:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Output
If I try:
\DTLforeach*{people}{\Surname=surname}{\Surname; }. Input
I get:
Parrot; Canary; Zebra; Arara; Duck; Canary; . Output
(there’s an unwanted semi-colon and space before the terminating full stop) and
if I try:
\DTLforeach*{people}{\Surname=surname}{; \Surname}. Input
I get:
; Parrot; Canary; Zebra; Arara; Duck; Canary. Output
↑ Input
\newcommand{\surnamesep}{%
\renewcommand{\surnamesep}{; }%
}%
\DTLforeach*{people}{\Surname=surname}{\surnamesep\Surname}.
↓ Input
This may look a bit weird at first sight, but here’s how it works:
\surnamesep\Surname Input
is equivalent to
\surnamesep\Surname Input
is equivalent to just
; \Surname Input
↑ Input
\newcommand{\surnamesep}{%
\gdef\surnamesep{; }%
}%
\DTLforeach*{people}{\Surname=surname}{\surnamesep\Surname}.
↓ Input
Alternatively you can do a global \let after you’ve redefined the command:
↑ Input
\newcommand{\surnamesep}{%
\renewcommand\surnamesep{; }%
\global\let\surnamesep\surnamesep
}%
\DTLforeach*{people}{\Surname=surname}{\surnamesep\Surname}.
↓ Input
designed for use within the ⟨body⟩ of \DTLforeach so I could just do:
↑ Input
\DTLforeach*
{people}% database
{\Surname=surname}% assignment list
{\DTLiffirstrow{}{; }\Surname}.
↓ Input
However, the technique described above can be used in more general situ-
ations. For example, suppose I want to use etoolbox’s \docsvlist, described in
§2.7.2, I could do:
↑ Input
\newcommand{\surnamesep}{%
\renewcommand{\surnamesep}{; }%
}%
\renewcommand\do[1]{\surnamesep#1}%
\docsvlist{Parrot,Canary,Zebra,Arara,Duck}.
↓ Input
which produces:
Parrot; Canary; Zebra; Arara; Duck. Output
As with \DTLiffirstrow, this command is designed for use within the ⟨body⟩
of \DTLforeach (or \DTLforeach*). For example:
↑ Input
\DTLforeach*
{people}% database
{\Surname=surname}% assignment list
{%
\DTLiffirstrow{}{\DTLiflastrow{ and }{, }}%
\Surname
}.
↓ Input
2.7 Iteration 71
produces:
Parrot, Canary, Zebra, Arara, Duck and Canary. Output
↑ Input
\newcommand*{\surnamesep}{}%
\newcommand*{\lastsurname}{}%
\newcommand*{\prelastsurname}{}%
\renewcommand*{\do}[1]{%
\surnamesep
\lastsurname
\renewcommand{\lastsurname}{%
\renewcommand{\surnamesep}{, }%
\renewcommand{\prelastsurname}{ and }%
#1%
}%
}%
\docsvlist{Parrot,Canary,Zebra,Arara,Duck}%
\prelastsurname \lastsurname
↓ Input
This produces:
Parrot, Canary, Zebra, Arara and Duck Output
\renewcommand{\lastsurname}{%
\renewcommand{\surnamesep}{, }%
\renewcommand{\prelastsurname}{ and }%
Parrot%
}
(The #1 has been replaced with the argument passed to \do.) So far
nothing has been displayed.
If this was the only item in the list, the loop would end and then:
• \prelastsurname would be done, but this is currently nothing.
• \lastsurname would be done, which is now set to redefine a couple of
commands that are no longer needed (\surnamesep and \prelastsurname)
and then displays “Parrot”.
Therefore, if the list only has one element, it just displays that element.
However, since the list has more than one element, we have nothing
displayed and we move on to the next item in the list.
2. On the second iteration (\do{Canary}) \surnamesep still does nothing but
\lastsurname now does:
\renewcommand{\surnamesep}{, }%
\renewcommand{\prelastsurname}{ and }%
Parrot%
2.7 Iteration 72
\renewcommand{\lastsurname}{%
\renewcommand{\surnamesep}{, }%
\renewcommand{\prelastsurname}{ and }%
Canary%
}
Therefore, by the end of the second iteration, the only text displayed is
“Parrot”. If this happened to be the last item in the list, the loop would
end and then:
• \prelastsurname would be done, which now displays “ and ”.
• \lastsurname would be done, which redefines some commands we
no longer need (\surnamesep and \prelastsurname) and then dis-
plays “Canary”.
Therefore, if the list only contained Parrot,Canary then just the text “Par-
rot and Canary” would be displayed. However, as there are still more
items left, the only text displayed so far is “Parrot”.
3. On the third iteration (\do{Zebra}) \surnamesep now displays a comma
followed by a space and \lastsurname does:
\renewcommand{\surnamesep}{, }%
\renewcommand{\prelastsurname}{ and }%
Canary%
\renewcommand{\lastsurname}{%
\renewcommand{\surnamesep}{, }%
\renewcommand{\prelastsurname}{ and }%
Zebra%
}
So we have thus far produced the text “Parrot, Canary”. If this happened
to be the last item in the list, the loop would end and then:
• \prelastsurname would display “ and ”
• \lastsurname would redefine some commands that we no longer
need (\surnamesep and \prelastsurname) and then display “Zebra”.
The remaining iterations follow the same pattern as this third iteration.
If you plan to use this method more than once, you might prefer to define
a new command. For example:
↑ Input
\renewcommand*{\surnamesep}{}%
\renewcommand*{\lastsurname}{}%
\renewcommand*{\prelastsurname}{}%
% set up list handler:
\renewcommand*{\do}[1]{%
\surnamesep
\lastsurname
\renewcommand{\lastsurname}{%
\renewcommand{\surnamesep}{, }%
\renewcommand{\prelastsurname}{ and }%
##1%
}%
}%
\docsvlist{#1}%
\prelastsurname \lastsurname
}
↓ Input
↑ Input
This removes one of the nested redefinitions and the need to use ##1 instead
of #1.
You can download or view a complete document.
2.8 Fetching Data From a Given Row 74
↑ Input
\displaynames{Parrot,Canary,Zebra,Arara,Duck}
\displaynames{Parrot,Canary,Zebra,Arara}
\displaynames{Parrot,Canary,Zebra}
\displaynames{Parrot,Canary}
\displaynames{Parrot}
↓ Input
should produce:
↑ Output
Parrot, Canary, Zebra, Arara, and Duck
Parrot, Canary, Zebra, and Arara
Parrot, Canary, and Zebra
Parrot and Canary
Parrot
↓ Output
This applies the assignment list to the row given by ⟨row-idx⟩. (Indices start
from 1.)
\DTLassignfirstmatch{⟨db-name⟩}{⟨col-label⟩}{⟨value⟩}{⟨assign list⟩} Definition
This applies the assignment list to the first row where the entry in the column
identified by ⟨col-label⟩ exactly matches the given value. Note that no expansion
is performed on ⟨value⟩.
\xDTLassignfirstmatch{⟨db-name⟩}{⟨col-label⟩}{⟨value⟩}{⟨assign list⟩} Definition
This applies the assignment list to the first row where the entry in the column
identified by ⟨col-label⟩ exactly matches a one-level expansion of ⟨value⟩.
In each case, ⟨db-name⟩ is the label identifying the data and ⟨assign list⟩ is
the comma-separated list of assignments, as used by \DTLforeach and \DTLforeach*.
2.8 Fetching Data From a Given Row 75
↑ Input
\DTLassign{people}{1}{%
\Surname=surname,%
\Title=title,%
\AddressI=address1,%
\AddressII=address2,%
\Town=town,%
\County=county,%
\Postcode=postcode%
}
↓ Input
Remember to make sure you comment out the unwanted EOL characters, as
shown above, or you’ll get an error caused by spurious spaces (recall the note
about spaces on page 62). Now that the data has been fetched, it can be used.
For example, to just display the details in a tabular environment:
↑ Input
\begin{tabular}{l}
\Title\ \Surname\\
\AddressI\\
\AddressII\\
\Town\\
\County\\
\Postcode
\end{tabular}
↓ Input
This produces:
↑ Output
Miss Parrot
42 The Lane
Some Town
Noshire
AB1 2XY
↓ Output
↑ Output
Miss Parrot
42 The Lane
NULL
Some Town
Noshire
AB1 2XY
↓ Output
2.8 Fetching Data From a Given Row 76
See §2.9 on how to deal with null or empty entries. (You can also download or
view a complete document for the SQL version.)
Remember that if you’re importing your data from a SQL database, there’s
no need to import all the data from the table if you don’t require parts of it.
Instead you can filter out all the unwanted rows in your SELECT statement. For
example, if you wanted to fetch the data for just the customer whose surname
is “Parrot”, you can do:
datatooltk --output customer.dbtex --sqldb samples
line-wrap-symbol
--sqluser sampleuser --sql "SELECT * FROM people Shell
line-wrap-symbol
WHERE surname='Parrot'"
If you’re not using SQL then you can fetch the relevant row using the afore
mentioned \DTLassignfirstmatch, but it’s less efficient.
Example 9. Fetching a Customer’s Details
Suppose you only want the details from the customer whose surname matches
“Parrot” in the sample people.csv file. This can be fetched using:
↑ Input
\DTLassignfirstmatch{people}{surname}{Parrot}{%
\Surname=surname,%
\Title=title,%
\AddressI=address1,%
\AddressII=address2,%
\Town=town,%
\County=county,%
\Postcode=postcode%
}
↓ Input
Now the details have been fetched, it can be used as in the previous example:
↑ Input
\begin{tabular}{l}
\Title\ \Surname\\
\AddressI\\
\AddressII\\
\Town\\
\County\\
\Postcode
\end{tabular}
↓ Input
The result is the same as for the previous example. (You can download or view
a complete document.)
↑ Input
\newcommand{\Name}{Parrot}
\DTLassignfirstmatch{people}{surname}{\Name}% 8
{%
\Surname=surname,%
\Title=title,%
2.8 Fetching Data From a Given Row 77
\AddressI=address1,%
\AddressII=address2,%
\Town=town,%
\County=county,%
\Postcode=postcode%
}
↓ Input
Then you’ll get an error that no match was found. This is because you’re effec-
tively asking TEX to find an entry that contains “\Name”, but that control sequence
doesn’t appear in any of the entries, so there’s no match. Instead, you need to
use \xDTLassignfirstmatch which will internally replace \Name with its defini-
tion (“Parrot”).
↑ Input
\newcommand{\Name}{Parrot}
\xDTLassignfirstmatch{people}{surname}{\Name}% 4
{%
\Surname=surname,%
\Title=title,%
\AddressI=address1,%
\AddressII=address2,%
\Town=town,%
\County=county,%
\Postcode=postcode%
}
↓ Input
↑ Input
\DTLassignfirstmatch{people}{surname}{Parrot}{%
\Surname=surname,%
\Title=title,%
\AddressI=address1,%
\Town=town,%
\County=county,%
\Postcode=postcode,%
\CountryCode=country%
}
↓ Input
↑ Input
\begin{tabular}{l}
\Title\ \Surname\\
\AddressI\\
\Town\\
\County\\
\Postcode\\
\CountyCode
\end{tabular}
↓ Input
2.8 Fetching Data From a Given Row 78
This produces:
↑ Output
Miss Parrot
42 The Lane
Some Town
Noshire
AB1 2XY
gb
↓ Output
If this is intended for, say, a letter to a customer, then the country code really
needs to be converted to the country’s name. That information is stored in the
sample country-codes.csv file, so that also needs to be loaded. Therefore the
document should have:
↑ Input
\DTLloaddb{people}{people.csv}
\DTLloaddb{countries}{country-codes.csv}
↓ Input
Once the \CountryCode has been assigned via \DTLassign, as shown above, the
code can be converted to a name:
↑ Input
\xDTLassignfirstmatch{countries}{code}%
{\CountryCode}{\CountryName=name}
↓ Input
↑ Output
Miss Parrot
42 The Lane
Some Town
Noshire
AB1 2XY
United Kingdom
↓ Output
This creates a datatool (.dbtex) file called customer.dbtex that only contains
the one row of data. The country name is now stored in the column labelled
country. So you can just do:
↑ Input
\DTLloaddbtex{customer}{customer.dbtex}
\DTLassign{customer}{1}{%
\Surname=surname,%
2.9 Null and Boolean Values 79
\Title=title,%
\AddressI=address1,%
\Town=town,%
\County=county,%
\Postcode=postcode,%
\CountryName=country%
}
\begin{tabular}{l}
\Title\ \Surname\\
\AddressI\\
\Town\\
\County\\
\Postcode\\
\CountyName
\end{tabular}
↓ Input
This produces the sample result as above. You can download or view this SQL
version.
where ⟨cs⟩ is a control sequence, ⟨true⟩ is what to do if ⟨cs⟩ is null and ⟨false⟩
is what to do if ⟨cs⟩ isn’t null. To test for an empty value, you can use:
\ifdefempty{⟨cs⟩}{⟨true⟩}{⟨false⟩} Definition
The other difference is the way boolean values have been stored. Both the
people.csv file and the SQL people table used “1” to indicate a true value and “0”
to indicate a false value in the subscribed field, but when the data was fetched
from the SQL table, these values were converted to “true” and “false” in the
datatool (.dbtex) file. There are a number of ways of testing whether a control
sequence is equal to “true” or “1”. For example, the etoolbox package defines:
\ifdefstring{⟨cs⟩}{⟨string⟩}{⟨true part⟩}{⟨false part⟩} Definition
This tests if the control sequence ⟨cs⟩ is defined to be ⟨string⟩. If it is, ⟨true
part⟩ is done, otherwise ⟨false part⟩ is done. For example:
2.9 Null and Boolean Values 80
↑ Input
\newcommand*{\Subscribed}{true}%
\ifdefstring{\Subscribed}{true}{Yes}{No}
↓ Input
produces:
Yes Output
Similarly
↑ Input
\newcommand*{\Subscribed}{1}%
\ifdefstring{\Subscribed}{1}{Yes}{No}
↓ Input
produces:
Yes Output
If you want to test for “true” or “1”, you can combine these:
↑ Input
\ifdefstring
{\Subscribed}{true}% test
{Yes}% condition true
{\ifdefstring{\Subscribed}{1}{Yes}{No}}
↓ Input
which evaluates ⟨expression⟩ and does ⟨true part⟩ if true, otherwise it does
⟨false part⟩. In this case I’m going to use the test syntax:
↑ Input
\ifboolexpr
{
test{\ifdefstring{\Subscribed}{true}} or
test{\ifdefstring{\Subscribed}{1}}
}
{Yes}{No}
↓ Input
(For further details of the syntax used in ⟨expression⟩, see the etoolbox docu-
mentation [51].) You might find it easier to define a command to do this. For
example:
↑ Input
\newcommand{\ifcsbool}[3]{%
\ifboolexpr
{
test{\ifdefstring{#1}{true}} or
test{\ifdefstring{#1}{1}}
}
{#2}{#3}%
}
↓ Input
2.9 Null and Boolean Values 81
or (recall from Volume 1 [93, §8.2] the \ding command provided by pifont [84]):
\ifcsbool{\Subscribed}{\ding{52}}{\ding{56}} Input
↑ Input
\DTLloaddb{people}{people.csv}
\begin{sidewaystable}
\caption{Customers (CSV)}
\label{tab:peoplecsv}
\centering
\DTLdisplaydb{people}
[id,forenames,title,country,postcode,gender,dob]% omit
line-wrap-symbol
these columns
{people}
\end{sidewaystable}
↓ Input
This produces Table 2.9. Now let’s look at what happens if we fetch the people
SQL table using:
datatooltk --output people.dbtex --sqluser sampleuser
line-wrap-symbol Shell
--sqldb samples --sql "SELECT * FROM people"
↑ Input
\begin{sidewaystable}
\caption{Customers (SQL)}
\label{tab:peoplesql}
\centering
\DTLdisplaydb
[id,forenames,title,country,postcode,gender,dob]% omit
line-wrap-symbol
these columns
{\people}
\end{sidewaystable}
↓ Input
↑ Input
\begin{table}
\caption{Customers (Check for Null and Boolean)}
\label{tab:peoplenullcheck}
\centering
\begin{tabular}{lllllc}
\multicolumn{1}{c}{\bfseries Surname} &
\multicolumn{1}{c}{\bfseries Address 1} &
\multicolumn{1}{c}{\bfseries Address 2} &
\multicolumn{1}{c}{\bfseries Town} &
\multicolumn{1}{c}{\bfseries County} &
\multicolumn{1}{c}{\bfseries Subscribed}%
\DTLforeach*{people}{\Surname=surname,\AddressI=address1,%
\AddressII=address2,\Town=town,\County=county,\Subscribed=subscribed}
{%
\\\Surname & \AddressI &
\DTLifnullorempty{\AddressII}{\multicolumn{1}{c}{---}}{\AddressII}
& \Town &
\DTLifnullorempty{\County}{\multicolumn{1}{c}{---}}{\County}&
\ifcsbool{\Subscribed}{\ding{52}}{\ding{56}}%
}%
\end{tabular}
\end{table}
↓ Input
scrlttr2 This is one of the KOMA-Script classes and is included here because
the first two volumes in this series looked at other classes in that bundle.
This is more complicated to use than letter but is more flexible. At the time
of writing this, the current version of the scrlttr2 class is 3.14 (2014-10-28).
newlfm This class is less flexible than scrlttr2 but can also be used for memos
(see §6.1) and faxes. At the time of writing this, the current version of the
newlfm class is dated 2009-04-11.
isodoc This class is more flexible than newlfm but less complicated than scrlttr2
and can also be used to write invoices (see §4.1). At the time of writing
this, the current version of the isodoc class is 1.06 (2014-07-26).
B Note that it’s usually considered inappropriate to have floats within a letter,
so letter-style classes, such as letter, scrlttr2 and newlfm, don’t define the figure
or table environments. You can, however, just use a tabular environment. In this
case, you might want to place the tabular environment within the center environ-
ment to centre it and produce a small vertical gap above and below. The isodoc
class inherits the figure and table environments from the underlying base article
class, but that kind of floating material is liable to interfere with the fixed blocks
such as the address information.
↑ Input
\documentclass{letter}
\usepackage[a4paper]{geometry}
↓ Input
A document using the letter class may have one or more letter environments
that contain the text of the letter:
84
3.1 Writing a Letter Using the letter Class 85
\begin{letter}{⟨recipient’s address⟩}
⟨body⟩ Definition
\end{letter}
Within ⟨body⟩, you can use:
\opening{⟨salutation text⟩} Definition
for the closing text (such as “Yours Sincerely”). After \closing you can also
use:
\ps ⟨postscript text⟩ Definition
for any postscripts (note that ⟨postscript text⟩ isn’t an argument and you need
to supply your own “PS” tag at the start of it)
\cc{⟨text⟩} Definition
↑ Input
\documentclass[12pt]{letter}
\usepackage[a4paper]{geometry}
\usepackage[british]{babel}
\begin{document}
\closing{Yours sincerely}
\end{document}
↓ Input
3.1 Writing a Letter Using the letter Class 86
Yours sincerely
(I’ve used the babel package [7] with the british option to ensure that the date
is displayed using the British format rather than the default US format.)
The resulting document is shown in Figure 3.1. You can download or view
this example.
You can add information about the sender as well. This typically goes in the
preamble. The sender’s name is specified using:
\name{⟨text⟩} Definition
Additionally, you can specify the sender’s name as it should appear after the
closing text (supplied by \closing):
\signature{⟨text⟩} Definition
You may use \\ within ⟨text⟩ to separate the lines of the address. The sender’s
telephone number is specified using:
\telephone{⟨text⟩} Definition
after \opening.
The letter class is very old and doesn’t provide a means for specifying mod-
ern communication methods such as email, mobile phone numbers or web
addresses.
Exercise 7. Writing a Letter (letter class)
Modify Example 12 to include sender details.
For the More Adventurous
Recall from §2.8 that you can fetch a single row of data from a database. Use
one of the commands described in that section to fetch the recipient’s details
from the sample people.csv file or the people SQL table rather than explicitly
typing them into the document. You can download or view a solution.
where ⟨addressee⟩ is the recipient’s postal details. Use \\ to separate the lines
of the address. As with the letter class described above, a document may have
more than one letter environment, which will later come in useful when we look
at mail merging in §3.5. Within the letter environment you must start the letter
with
3.2 Writing a Letter Using the scrlttr2 Class 88
\opening{⟨salutation⟩} Definition
The ⟨salutation⟩ is the greeting at the start of the letter, such as Dear Dr~Smith
and the ⟨sign-off text⟩ is the closing text, such as Yours sincerely.
After \closing{⟨sign-off text⟩} you can optionally use:
\ps ⟨postscript text⟩ Definition
(As with the letter class, the ⟨postscript text⟩ is not an argument of \ps, and you
need to include “PS” in ⟨postscript text⟩ if you want it as it’s not automatically
generated.)
\encl{⟨enclosures info⟩} Definition
and
\cc{⟨cc list⟩} Definition
These three commands, if required, must go after \closing and before the end
of the letter environment.
scrlttr2 class is designed for use with the babel package [7], so remember
B Theto load it. (See Volume 1 [93, §5.8].)
Example 13. A Simple Letter (scrlttr2 class)
Here’s a simple example letter:
↑ Input
\documentclass{scrlttr2}
\usepackage[british]{babel}
\begin{document}
\closing{Yours sincerely}
\end{document}
↓ Input
(You can download or view this document.) The resulting document is shown
in Figure 3.2. Things to note:
3.2 Writing a Letter Using the scrlttr2 Class 89
Yours sincerely
• The first paragraph of the letter isn’t indented, subsequent paragraphs are.
If you prefer to have blank lines between paragraphs and no paragraph
indentation you can use the parskip=full or parskip=half class options.
For example:
\documentclass[parskip=full]{scrlttr2} Input
• There is space between the closing text and the postscript for you to sign
your name.
• The page has horizontal marks on the left hand side. These are guides
for folding or punching and are discussed below.
• This example assumes that you are going to print the letter on headed
paper.
Example:
Suppose I want to add a “Your ref” line before the opening salutation. For
example, supposing the recipient has requested the reference “ABC/123” in any
correspondence, then I need to add
\setkomavar{yourref}{ABC/123} Input
before the \opening command. This will now appear in the letter as
↑ Output
Your ref.
ABC/123
↓ Output
Here, the variable is yourref and the content is “ABC/123”. The default descrip-
tion (in English) for this variable is “Your ref.” This can be changed with the
optional argument:
\setkomavar{yourref}[Your Reference:]{ABC/123} Input
KOMA-Script also has “options” that correspond to the variables. The option
name is the same as the variable name and can be set via:
\KOMAoption{⟨option⟩}{⟨value list⟩} Definition
or
\KOMAoptions{⟨option=value list⟩} Definition
For example, the subject option indicates how the subject text should be
displayed. Possible values for this option are: afteropening, beforeopening,
centered, left, right, titled, underlined or untitled. For example, to make
the subject appear after the opening text you can use either
\KOMAoptions{subject=afteropening} Input
or
\KOMAoption{subject}{afteropening} Input
↑ Input
There are a lot of other variables, such as invoice for the invoice number and
customer for the customer number. Common variables are listed in Table 3.1.
Common options with some of their possible values are listed in Table 3.2. See
the KOMA-Script documentation [47] for a complete list of all variables and
options.
Options can also be set via the optional argument of the letter environment.
For example:
\begin{letter}[subject=afteropening]{Mrs~Mabel Canary} Input
The foldmarks option may have the single letter values combined. For ex-
ample:
\KOMAoptions{foldmarks=vpmBT} Input
or
\KOMAoption{foldmarks}{vpmBT} Input
Variable Description
customer Customer number.
date Letter date.
firstfoot Footer for the first page of the letter.
nextfoot Footer for subsequent pages of the letter.
firsthead Header for the first page of the letter.
nexthead Header for subsequent pages of the letter.
fromaddress Sender’s address (without sender’s name).
fromemail Sender’s email.
fromfax Sender’s fax number.
fromlogo Commands for inserting sender’s logo.
frommobilephone Sender’s mobile phone number.
fromname Sender’s full name.
fromphone Sender’s telephone number.
fromurl Sender’s URL (e.g. home page).
invoice Invoice number.
Common scrlttr2 Variables (Continued)
Variable Description
myref Sender’s reference.
location Additional sender details.
signature Signature beneath letter ending.
subject Letter’s subject.
title Letter’s title.
yourref Recipient’s reference.
Recall from Volume 1 [93, §6] that the graphicx package [14] provides the
command:
3.2 Writing a Letter Using the scrlttr2 Class 94
\includegraphics[⟨options⟩]{⟨file⟩} Definition
to include the image file called ⟨file⟩. (The extension may be omitted.)
By default, the logo isn’t displayed, even if you set the fromlogo variable. If
you want it displayed you need to activate it via:
\KOMAoption{fromlogo}{true} Input
↑ Input
\documentclass[12pt,parskip=full]{scrlttr2}
\usepackage[british]{babel}
\KOMAoption{subject}{afteropening,right,underlined,titled}
\KOMAoptions{foldmarks=vpmBT}
\begin{document}
\opening{Dear Mrs~Canary}
\closing{Yours sincerely}
\end{document}
↓ Input
3.2 Writing a Letter Using the scrlttr2 Class 95
Yours sincerely
(You can download or view this example.) The resulting document is shown in
Figure 3.3.
For example
\greetto{Dear Mrs Canary} Input
For example
\closeline{Yours sincerely} Input
For example:
\nameto{Mrs Mabel Canary} Input
For example:
3.3 Writing a Letter Using the newlfm Class 97
↑ Input
For example:
\namefrom{Mr Big Head} Input
For example
↑ Input
\addrfrom{University of Somewhere\\
Some City\\
AB3 4YZ}
↓ Input
For example
\phonefrom{0123456789} Input
For example
\emailfrom{[email protected]} Input
For example:
\regarding{sample letter} Input
For example:
\psitem{Don’t forget to bring some cake!} Input
For example:
3.3 Writing a Letter Using the newlfm Class 98
For example:
\cclist{Prof Important Person} Input
For example:
\encllist{Photograph of a hat} Input
There are other commands as well. See the newlfm documentation [107] for
further details.
The newlfm class comes with a number of predefined letter styles, which can
be set via the class options: busletter, busletternofrom, stdletter, stdletterfrom.
The “nofrom” styles don’t display the sender’s address. The business letter
“busletter” styles use a different alignment to the standard “stdletter” styles.
Alternatively, the letter style can be set via:
\newlfmP{⟨option list⟩} Definition
Other letter-related options that can be set using \newlfmP (or in the class option
list) are listed in Table 3.3.
Option Description
noaddrfrom Omit sender’s address.
addrfromphone Include sender’s phone.
addrfromemail Include sender’s email.
addrfromfax Include sender’s fax.
printallfrom Print all of the sender’s details.
addrfromright Right-align sender’s block.
addrfromleft Left-align sender’s block.
printallto Print all of recipient’s details.
addrtoright Right-align recipient’s block.
addrtoleft Left-align recipient’s block.
addrtophone Include recipient’s phone.
addrtoemail Include recipient’s email.
addrtofax Include recipient’s fax.
dateright Right-align date.
dateleft Left-align date.
datecenter Centre date.
dateyes Include date.
dateno Don’t include date.
orderdatefromto Display order: date, sender, recipient.
orderfromtodate Display order: sender, recipient, date.
orderfromdateto Display order: sender, date, recipient.
sigright Right-align signature.
sigleft Left-align signature.
sigcenter Centre signature.
3.4 Writing a Letter Using the isodoc Class 99
↑ Input
\documentclass[stdletter]{newlfm}
\usepackage[british]{babel}
\newlfmP{orderfromtodate,sigcenter,addrfromphone,addrfromemail}
\begin{document}
\begin{newlfm}
This is an imaginary letter.
\end{document} ↓ Input
(You can download or view this example.) The resulting document is shown
in Figure 3.4.
University of Somewhere
Some City
AB3 4YZ
Telephone: 0123456789
E-mail: [email protected]
Mr Big Head
As with the other classes, a document may contain multiple letters. The optional
argument ⟨recipient options⟩ is a key=value list of options to apply to this letter.
The other argument ⟨contents⟩ contains the contents of the letter. General
options can be set using:
\setupdocument{⟨options⟩} Definition
Again, ⟨options⟩ is a key=value list. There are a lot of options available, so this
section will only cover common settings. For full details, see the isodoc user
guide [21]
You don’t need to use babel with isodoc. Instead you can set the language
using the language key. As of the time of writing, available language options
are: en-GB (default), en-US, fr-FR, de-DE, nl-NL, nl-BE, it-IT, es-ES, ca-ES, nb-NO
and sr-RS. The hyphen is optional so, for example, enGB is the same as en-GB.
For example, to switch to US English:
\setupdocument{language=en-US} Input
foreign If this key is used, the country name will be added to the address,
the zip code will be prefixed with the country code and the tele-
phone numbers will be prefixed with the area code. (This isn’t
a boolean key, but if you want to generate multiple letters with
a mixture of national and international addresses, you can switch
this setting on and off using \foreigntrue and \foreignfalse.)
The above information is placed in the logo area. The options that govern the
address window include:
to The recipient’s address. You can use \\ to break the lines.
yourletter If this letter is a reply to a letter from the recipient, this value is
the date of the recipient’s letter.
3.4 Writing a Letter Using the isodoc Class 102
\setupdocument{date={2014-03-01}} Input
↑ Input
\documentclass[12pt]{isodoc}
\setupdocument
{%
language={en-GB},%
company={University of Somewhere},%
who={Mr Big Head},%
street={Academic Lane},%
city={Some City},%
zip={AB3 4YZ},%
country={United Kingdom},%
countrycode={GB},%
areacode={44},%
cityzip,%
subject={A sample letter},%
closing={Yours sincerely},%
enclosures={Photocopy of something interesting\\
Photocopy of something rather dull},%
signature={Big Head},%
copyto={Prof Important Person\\Dr Bor Ing},%
footer,%
phone={123456789},%
cellphone={712345678},%
email={[email protected]},%
website={somewhere.ac.uk},%
date={2014-03-01}%
}
\begin{document}
\letter
[%
opening={Dear Mrs Canary},%
to={Mrs Mabel Canary\\%
24 The Street\\%
Some Village\\Some Town\\%
Noshire\\AB1 2YZ},%
ourref={ABC/123}%
]%
{%
This is an imaginary letter.
\end{document}
↓ Input
(You can download or view this example.) The resulting document is shown
in Figure 3.5. There’s no space between the closing text and signature as I didn’t
use the autograph option.
3.4 Writing a Letter Using the isodoc Class 104
University of Somewhere
Mr Big Head
Academic Lane
Some City AB3 4YZ
Yours sincerely,
Big Head
Enclosures:
Photocopy of something interesting
Photocopy of something rather dull
Copy to
Prof Important Person
Dr Bor Ing
↑ Input
\documentclass{letter}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[a4paper]{geometry}
\usepackage[british]{babel}
\usepackage{datatool}
\DTLloaddb{people}{people.csv}
\DTLloaddb{countries}{country-codes.csv}
\begin{document}
\DTLforeach*{people}% data
{% assignments
\Id=id,%
\Surname=surname,%
\Forenames=forenames,%
\Title=title,%
\AddressI=address1,%
\AddressII=address2,%
\Town=town,%
\County=county,%
\Postcode=postcode,%
\CountryCode=country%
}
{%
% fetch country name
\xDTLassignfirstmatch{countries}{code}{\CountryCode}{\CountryName=name}
\thispagestyle{firstpage}
This is an imaginary letter.
\closing{Yours sincerely}
\end{document}
↓ Input
This produces a six page document, where each page contains a letter to one
of the six people in the database. You can download or view this document.
↑ Input
\documentclass[stdletter]{newlfm}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[british]{babel}
\usepackage{datatool}
\DTLloaddb{people}{people.csv}
\DTLloaddb{countries}{country-codes.csv}
\newlfmP{orderfromtodate,sigcenter,addrfromphone,addrfromemail}
\begin{document}
\closeline{Yours sincerely}
3.5 Mail Merging 107
\psitem{this is a postscript}
\DTLforeach*{people}% data
{% assignments
\Id=id,%
\Surname=surname,%
\Forenames=forenames,%
\Title=title,%
\AddressI=address1,%
\AddressII=address2,%
\Town=town,%
\County=county,%
\Postcode=postcode,%
\CountryCode=country%
}
{%
\xDTLassignfirstmatch{countries}{code}{\CountryCode}{\CountryName=name}
\begin{newlfm}
This is an imaginary letter.
\end{document}
↓ Input
As with the previous example, this produces a six page document, where
each page contains a letter to one of the six people in the database. You can
download or view this document.
Note
The newlfm environment tries to determine the total number of pages per letter.
This is done using
\label{totpage} Input
at the end of the letter. Since there are six letters, this causes five instances of
LaTeX Warning: Label `totpage' multiply defined.
However, since each letter is of the same length, these warnings can be ignored.
3.6 Envelopes 108
3.6 Envelopes
The letter class defines a preamble-only command:
\makelabels Definition
which gathers the addresses of all the recipients and generates address labels
at the end of the document. These labels can then be stuck onto the envelopes.
For example, the document from Example 17 had six pages, one page for
each letter. If you add \makelabels to the preamble of that document, a seventh
sheet will be generated with the address labels, shown in Figure 3.6.
This is fine if this matches the size of your label sheets, but it can’t be easily
adapted for other label sizes. There are some envelope-related packages listed
on the TEX Catalogue Topic Index [25] or at the letter topic but take care as some
of them, such as envelope, were written for LATEX2.09 and may not work as well
with LATEX 2𝜀 or licensing issues may prevent them from being included in TEX
Live.
Some of the other letter-like classes also provide envelope labelling facilities,
but there are two packages that are both in the TEX Live and MiKTEX distribu-
tions: envlab and envbig. Another possibility is to use the ticket package, which is
discussed in §10.2.
The user guide for envlab [111] can be obtained via:
texdoc elguide Shell
Note that texdoc envlab produces the documented source code, which you may
find more complicated than the user guide. There’s no proper manual for envbig;
texdoc envbig just opens the README file. You need to open envbig.sty in
your text editor and read the comments for an example of how to use the
package. Therefore this book will just look at envlab. At the time of writing, the
current version of envlab is 1.2 (1997-07-16).
The envlab package is designed for US postal layouts, but it’s possible to define
custom label sizes. This package redefines \makelabels but it’s used in the same
way as for the letter class.
The envlab package is configured for three different types of media: en-
velopes (one per page, optionally rotated), labels (without a return address) and
big labels (with a return address). Envelopes are usually printed in landscape
format. This rotation can be switched on or off using the rotateenvelopes or
norotateenvelopes options.
The envelope layout can be set by the package options listed in Table 3.4 or
a custom size can be set via:
3.6 Envelopes 109
Mr Fred Canary
Miss Polly Parrot
24 The Street
42 The Lane
Some Village
Some Town
Some Town
Noshire
Noshire
AB1 2XY
AB1 2YZ
United Kingdom
United Kingdom
Ms Zöe Zebra
856 The Avenue
Some City
CA
123456
United States
José Arara
Nenhuma Rua
São Paulo
123457
Brazil
Mr Dickie Duck
1 The Street
Another Village
Some City
Imagineshire
YZ1 2AB
United Kingdom
where ⟨top margin⟩ is the height of the top margin, ⟨width⟩ is the envelope
width and ⟨height⟩ is the envelope height.
The standard label layout can be set by the package options listed in Table 3.5
or a custom size can be set via:
\SetLabel{⟨width⟩}{⟨height⟩}{⟨top⟩}{⟨left⟩}{⟨sep⟩}{⟨columns⟩}{⟨rows⟩} Definition
where ⟨width⟩ is the total width from the left border of one label and the left
border of the label in the next column, ⟨height⟩ is the total height from the top
border of one label and the top border of the label in the row below, ⟨top⟩ and
⟨left⟩ are the distances between the edge of the paper and the label, ⟨sep⟩ is the
horizontal distance between labels and ⟨columns⟩ and ⟨rows⟩ are the number
of columns and rows of labels per page.
The big label layout can be set by the package options listed in Table 3.6 or
a custom size can be set via:
\SetBigLabel{⟨width⟩}{⟨height⟩}{⟨top⟩}{⟨left⟩}{⟨sep⟩}{⟨columns⟩}{⟨rows⟩} Definition
If you have a partially used sheet, you can specify the starting label via:
\FirstLabel{⟨row⟩}{⟨column⟩} Definition
where ⟨row⟩ is the row index (starting from 1) and ⟨column⟩ is the column
index (starting from 1). The labels are printed row by row.
The return address for the big envelopes is taken from the argument of
\address but this can be changed by redefining:
3.6 Envelopes 111
\returnaddress Definition
↑ Input
\documentclass{letter}
\usepackage[a4paper]{geometry}
\usepackage[british]{babel}
\usepackage{envlab}
\SetBigLabel{101mm}{139mm}{9mm}{3mm}{2mm}{2}{2}
\makelabels
\begin{document}
\thispagestyle{firstpage}
This is an imaginary letter.
\closing{Yours sincerely}
\end{document}
↓ Input
This produces a document with two pages. The first contains the letter and the
second contains the label. This second page is shown in Figure 3.7.
This produces a portrait label, but if you have a wide address it may look
better rotated to make a landscape label. Unfortunately, the envlab options that
govern rotation (rotateenvelope and norotateenvelope) don’t apply to labels.
These big labels are implicitly typeset using
3.6 Envelopes 112
University of Somewhere
Some City
AB3 4YZ
\PrintBigLabel{⟨from-address⟩}{⟨to-address⟩} Definition
↑ Input
\newcommand{\PrintBigLabel}[2]{%
\begin{minipage}[t][\LabelHeight]{\LabelWidth}%
\baselineskip=0pt%
\lineskip=0pt%
\parindent=0pt%
\begin{center}%
\PrintReturnAddress{#1}\\%
\rule{\ToAddressWidth}{0.1pt}%
\PrintAddress{#2}%
\end{center}%
\end{minipage}}
↓ Input
This displays the label in a minipage with the dimensions given by \LabelWidth
and \LabelHeight which have been set to the width and height of the printable
label area. This can be redefined to provide your own custom label format. For
example (recall \rotatebox provided by the graphicx package [14] described in
Volume 1 [93, §6.1]):
↑ Input
\renewcommand{\PrintBigLabel}[2]{%
\begin{minipage}[t]{\LabelHeight}{\LabelWidth}
\vfill
\hspace*{1em}%
\rotatebox[origin=l]{90}{\PrintReturnAddress{#1}}\hfill
\rule{0.1pt}{\ToAddressWidth}\space
\rotatebox[origin=l]{90}{\PrintAddress{#2}}%
\hspace*{1em}%
\vfill
\end{minipage}%
}
↓ Input
This now produces the label shown in Figure 3.8. You can further customize
this redefinition if you like. For example, you may want the recipient’s address
above the return address. You can download or view this example document.
↑ Input
\documentclass{letter}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[nocapaddress]{envlab}
3.6 Envelopes 114
\makelabels
\begin{document}
A sample letter.
\closing{Yours sincerely}
\end{letter}
\end{document}
↓ Input
With the nocapaddress option, this code compiles without error. With the
default capaddress option, the ö must be placed inside a group:
\begin{letter}{Ms Z{ö}e Zebra\\856 The Avenue} Input
(For those of you who have used glossaries or mfirstuc, it stems from a similar
issue. See the section “UTF-8” in the mfirstuc documentation [99].)
Alternatively use XELATEX instead of PDFLATEX (the inputenc and fontenc pack-
ages need to be replaced by the fontspec [76] package):
↑ Input
% arara: xelatex
\documentclass{letter}
\usepackage{fontspec}
\usepackage{envlab}
\makelabels
\begin{document}
A sample letter.
\closing{Yours sincerely}
\end{letter}
\end{document}
↓ Input
↑ Input
\documentclass{letter}
3.6 Envelopes 116
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[a4paper]{geometry}
\usepackage[british]{babel}
\usepackage{datatool}
\usepackage{graphicx}
\usepackage[nocapaddress]{envlab}
\DTLloaddb{people}{people.csv}
\DTLloaddb{countries}{country-codes.csv}
\SetBigLabel{101mm}{139mm}{9mm}{3mm}{2mm}{2}{2}
\renewcommand{\PrintBigLabel}[2]{%
\begin{minipage}[t][\LabelHeight]{\LabelWidth}%
\vfill
\hspace*{1em}%
\rotatebox[origin=l]{90}{\PrintReturnAddress{#1}}\hfill
\rule{0.1pt}{\ToAddressWidth}\space
\rotatebox[origin=l]{90}{\PrintAddress{#2}}%
\hspace*{1em}%
\vfill
\end{minipage}%
}
\makelabels
\begin{document}
\DTLforeach*{people}% data
{% assignments
\Id=id,%
\Surname=surname,%
\Forenames=forenames,%
\Title=title,%
\AddressI=address1,%
\AddressII=address2,%
\Town=town,%
\County=county,%
\Postcode=postcode,%
\CountryCode=country%
}
{%
\xDTLassignfirstmatch{countries}{code}{\CountryCode}{\CountryName=name}
\begin{letter}{\DTLifnullorempty{\Title}{}{\Title\ }%
\Forenames\ \Surname\\\AddressI\\
\DTLifnullorempty{\AddressII}{}{\AddressII\\}\Town\\
\DTLifnullorempty{\County}{}{\County\\}\Postcode\\\CountryName}
3.6 Envelopes 117
\thispagestyle{firstpage}
This is an imaginary letter.
\closing{Yours sincerely}
\end{document}
↓ Input
The newlfm class automatically loads the envlab class. There’s a class option
useenvlab that’s designed to activate the envlab functions but its use seems to
be designed to work with newlfm’s mechanism for storing addresses in an exter-
nal file called letrinfo.tex. This doesn’t fit in with the generic mail-merging
functions discussed here, so instead we’ll look at how to manually make address
labels with envlab. This method can be applied to other classes or you can use
this method if you just want to generate labels without a corresponding letter.
For the manual method, when you want to start typesetting the labels you
need to use:
\startlabels Definition
for each label where ⟨from-address⟩ is the sender’s address and ⟨to-address⟩
is the recipient’s address.
Example 21. Mail Merging with newlfm, envlab and datatool
If you use the manual approach, you must generate the labels after you’ve fin-
ished typesetting the letters. This example illustrates this manual approach to
generate letters and corresponding labels to everyone in the sample people.csv
file database or the people SQL table who has the subscribed field set:
↑ Input
\documentclass[stdletter,nocapaddress,avery5164biglabel]{newlfm}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[british]{babel}
\usepackage{datatool}
\newcommand{\ifcsbool}[3]{%
\ifboolexpr
{
3.6 Envelopes 118
test{\ifdefstring{#1}{true}} or
test{\ifdefstring#1{1}}
}
{#2}{#3}%
}
\DTLloaddb{people}{people.csv}
\DTLloaddb{countries}{country-codes.csv}
\newlfmP{orderfromtodate,sigcenter,addrfromphone,addrfromemail}
\closeline{Yours sincerely}
\psitem{this is a postscript}
\begin{document}
\DTLforeach*{people}% data
{% assignments
\Id=id,%
\Surname=surname,%
\Forenames=forenames,%
\Title=title,%
\AddressI=address1,%
\AddressII=address2,%
\Town=town,%
\County=county,%
\Postcode=postcode,%
\CountryCode=country,%
\Subscribed=subscribed%
}
{%
\ifcsbool{\Subscribed}
{%
\xDTLassignfirstmatch{countries}{code}{\CountryCode}{\CountryName=name}
\begin{newlfm}
3.6 Envelopes 119
\end{newlfm}
}%
{}% not subscribed
}
\startlabels
\DTLforeach*{people}% data
{% assignments
\Id=id,%
\Surname=surname,%
\Forenames=forenames,%
\Title=title,%
\AddressI=address1,%
\AddressII=address2,%
\Town=town,%
\County=county,%
\Postcode=postcode,%
\CountryCode=country,%
\Subscribed=subscribed%
}
{%
\ifcsbool{\Subscribed}
{%
\xDTLassignfirstmatch{countries}{code}{\CountryCode}{\CountryName=name}
\mlabel
{Mr Big Head\\University of Somewhere\\Some City AB3 4YZ}%
{\DTLifnullorempty{\Title}{}{\Title\ }\Forenames\ \Surname\\%
\AddressI\\
\DTLifnullorempty{\AddressII}{}{\AddressII\\}\Town\\
\DTLifnullorempty{\County}{}{\County\\}\Postcode\\\CountryName
}
}%
{}% not subscribed
}
\end{document}
↓ Input
Exercise 11. Mail Merging With Envelope Labels Using newlfm, envlab
and datatool
There is some duplicate code in the previous example that’s inefficient, especially
if you have a large database. For this exercise, rewrite the document from Ex-
ample 21 so that it only has one instance of each of the commands \DTLforeach
and \xDTLassignfirstmatch and only one test for each member’s subscribed
status. Hint: recall the hook management described in §2.1.2. If you’re feeling
adventurous try to make the address on the labels upper case without using
envlab’s case-changing function. (Recall \MakeUppercase from Volume 2 [96,
§5.1.1].)
You can download or view the solution.
Chapter 4
Invoices
There are a number of bundles for typesetting invoices on CTAN (see the invoice
topic or the “Writing Invoices” of the TEX Catalogue Topic Index [25]) including
the invoice package and the isodoc class. These are both available on MiKTEX
and TEX Live and have English documentation available via texdoc.
The isodoc class has already been introduced in §3.4 as it can be used to create
letters, so §4.1 describes how to use that class to create an invoice. However, it
may be that you need to add an invoice to an existing document or need to use
a particular document class, so §4.2 describes how to use the invoice package.
Additionally, the invoice package converts currency (for foreign expenses) and
computes your totals for you, whereas with isodoc you have to do the calculations
yourself.
Finally, in case neither suit your requirements, §4.3 describes how to create
your own custom invoice using the longtable and datatool packages.
In addition to those described in §3.4, there are also some options that relate
to invoices. Some of these are described below. See the isodoc user guide [21] for
details of the options not described in this book, which are omitted for brevity.
Some of the options that set payment information are listed below:
120
4.1 Writing an Invoice Using the isodoc Class 121
acceptreference Reference.
As with \letter you may have multiple \invoice commands within a docu-
ment, but the ⟨contents⟩ part is more complicated. This argument will typically
contain:
\itable{⟨contents⟩} Definition
This creates a two-column tabular-like environment with the given contents. You
may use & and \\ but the isodoc class provides some convenient commands to
do this for you:
\iitem{⟨item description⟩}{⟨amount⟩} Definition
This puts ⟨item description⟩ in the first column and ⟨amount⟩ in the second
column.
\itotal[⟨tag⟩]{⟨amount⟩} Definition
This adds a row for the total amount. The optional argument may be used to
insert a tag, such as “Subtotal”.
In addition to \itable, you can also use
\accountdata Definition
To generate a table containing the account information needed to pay the in-
voice.
Example 22. An Invoice (isodoc class)
The above can be put together to create a simple invoice, listed below. Some of
the options used in this example were introduced in §3.4.
↑ Input
\documentclass{isodoc}
\setupdocument
{
language={en-GB},
company={University of Somewhere},
who={Mr Big Head},
street={Academic Lane},
city={Some City},
zip={AB3 4YZ},
country={United Kingdom},
countrycode={GB},
areacode={44},
cityzip,
date=2014-03-01,
subject=Sample Project,
currency={\pounds}
}
\begin{document}
\invoice
[
ourref=1234,
to={Miss Polly Parrot\\42 The Lane\\Some Town\\Noshire AB1 2XY}
4.2 Writing an Invoice Using the invoice Package 122
]
{%
\itable
{%
\iitem{Proof-reading}{300.00}
\iitem{Train Fare}{43.95}
\itotal{342.95}
}
\\[3ex]\accountdata
}
\end{document}
↓ Input
(You can download or view this example.) The resulting document is shown
in Figure 4.1.
The first argument ⟨base currency⟩ is the currency name and the second argu-
ment ⟨VAT⟩ is the VAT percentage (without the percent sign). The ⟨VAT⟩ may be
4.2 Writing an Invoice Using the invoice Package 123
University of Somewhere
Mr Big Head
Academic Lane
Some City AB3 4YZ
invoice
Description Amount (£)
Proof-reading 300.00
Train Fare 43.95
Total 342.95
Banking data:
Reference: 1234
0, in which case the VAT entries are hidden from the invoice, or 0.0, in which
case the VAT entries are displayed but show zero-rated VAT.
B Take care if you want to use a dollar sign. An error will occur if you use \$
as the base currency unless you also load the fontenc package with the T1
option. (Other options may also work, but the default OT1 font type fails.) This [FAQ: Why bother with
problem can also happen with other currency commands, such as \textdollar inputenc and fontenc?]
(textcomp package [59]) and \pounds, so where possible use fontenc with invoice.
If for some reason you don’t want to load fontenc, then you can use \string$
instead of \$ as a workaround. However, it’s a good idea in general to use the
fontenc package anyway. If you use fontenc remember to use inputenc as well.
Within the invoice environment you can set the project title using:
\ProjectTitle{⟨title⟩} Definition
You must have at least one project title in your invoice environment.
After the project title you specify the fees using:
\Fee{⟨description⟩}{⟨rate/unit⟩}{⟨count⟩} Definition
The local expenses must have a description (first argument) and the amount
(second argument). For example, to claim the cost of a £43.95 train ticket:
\EBC{Train fare}{43.95} Input
The foreign expenses must have a description (first argument), the name of the
foreign currency (second argument), the cost in terms of the foreign currency
unit (third argument), the conversion rate (fourth argument) and the result of
the currency conversion (the fifth argument). One or other of the last two
arguments may be empty.
For example, to charge for hotel accommodation at €300 with an exchange
rate of 0.82:
\EFC{Hotel}{\texteuro}{300}{0.82}{} Input
(Note that if you want to use \texteuro as in this example, you need to load the
textcomp package [59].)
You can hide expenses that should contribute to the total but don’t need to
be itemized using:
\EBCi{⟨description⟩}{⟨amount⟩} Input
for foreign expenses. The arguments are the same as for \EBC and \EFC. You
can make a subtotal appear for all the hidden expenses using:
\STExpenses Definition
↑ Input
\begin{invoice}{\pounds}{20}
\ProjectTitle{Sample Project}
\Fee{Proof-reading}{150.0}{2}
\EBC{Train fare}{43.95}
\EFC{Hotel}{\texteuro}{300}{0.82}{}
\end{invoice}
↓ Input
This produces the invoice shown in Figure 4.2. You can download or view this
example.
Output
The invoice package provides some multilingual support so you can use it
with babel [7]. If there is no support for your language, follow the instructions
in the file invoice.def which is located in the same directory as invoice.sty.
Alternatively, you can redefine the command names that generate the invoice
tags if they don’t suit your purpose. For example:
↑ Input
\renewcommand{\Fees}{Products}
\renewcommand{\UnitRate}{Price}
\renewcommand{\Count}{Quantity}
\renewcommand{\Activity}{Product}
↓ Input
4.3 Building Your Own Invoice using longtable and datatool 126
Unlike tabular the optional argument specifies the horizontal alignment instead
of the vertical alignment since longtable isn’t intended for in-line positioning. The
horizontal alignment may be one of l (left), c (centre) or r (right). The default
is c.
The ⟨column specs⟩ are the same as for tabular and the rows and columns
are separated in the same way using \\ and &. For example:
↑ Input
\begin{longtable}{lr}
Video & 8.99\\
CD & 9.11\\
DVD & 15.00\\
4.3 Building Your Own Invoice using longtable and datatool 127
produces:
↑ Output
Video 8.99
CD 9.11
DVD 15.00
Total 33.10
↓ Output
However, unlike tabular, you can also specify a caption as well as header and
footer information. This is done at the start of the longtable environment:
\begin{longtable}{⟨column specs⟩}
\caption{⟨first page caption⟩}
\label{⟨table label⟩}\\
⟨code for first page header row⟩
\endfirsthead
\caption{⟨continuation caption⟩}
⟨code for the header row⟩
\endhead
⟨code for last page footer row⟩
\endlastfoot
⟨code for the footer row⟩
\endfoot
⟨contents⟩
\end{longtable}
You may omit any of the header, footer or caption information. The document
will need at least two LATEX runs to ensure the longtable environment correctly
aligns the columns. The header and footer code will typically need to include
& and \\ as per the column alignment specifications. You can use the starred
version of \caption to suppress the numbering for example:
\caption*{Products (continued)} Input
↑ Input
\begin{longtable}{cl}
\bfseries Country Code & \bfseries Country Name\\
\endhead
\multicolumn{2}{r}{\emph{Continued on next page}}
\endfoot
\endlastfoot
\DTLforeach*{countries}{\Code=code,\Name=name}{\Code & \Name\\}%
\end{longtable}
↓ Input
4.3 Building Your Own Invoice using longtable and datatool 128
This sets the same header for all the pages and sets the footer to the text
“Continued on next page”. Since this isn’t required for the final page, the last
footer is set to empty. This produces a seven page table (without a caption). The
beginning of the table looks like:
↑ Output
Country Code Country Name
ad Andorra
ae United Arab Emirates
af Afghanistan
ag Antigua and Barbuda
ai Anguilla
↓ Output
↑ Output
bw Botswana
by Belarus
bz Belize
ca Canada
Continued on next page
↓ Output
The final page of the table is shown in Figure 4.3. You can download or view
this example document.
Output
Country Code Country Name
vg Virgin Islands, British
vi Virgin Islands, USA
vn Viet Nam
vu Vanuatu
wf Wallis and Futuna
ws Samoa
ye Yemen
yt Mayotte
za South Africa
zm Zambia
zw Zimbabwe
Remember that you can use the booktabs package [24] if you want horizontal
rules and you can use \DTLiflastrow to suppress the final \\ which would
otherwise create unnecessary extra vertical space at the end of the table. For
example:
↑ Input
\begin{longtable}{cl}
\bfseries Country Code & \bfseries Country Name\\
\midrule
\endhead
\bottomrule
\multicolumn{2}{r}{\emph{Continued on next page}}
\endfoot
\bottomrule
\endlastfoot
\DTLforeach*{countries}{\Code=code,\Name=name}%
4.3 Building Your Own Invoice using longtable and datatool 129
↑ Input
\begin{longtable}{cl}
\bfseries Country Code & \bfseries Country Name\\
\midrule
\endhead
\bottomrule
\multicolumn{2}{r}{\emph{Continued on next page}}
\endfoot
\bottomrule
\endlastfoot
\DTLforeach*{countries}{\Code=code,\Name=name}%
{\DTLiffirstrow{}{\\}\Code & \Name}%
\end{longtable} ↓ Input
As with tabular, the column specifiers may include p{⟨width⟩} for a column
with multilined cells. Recall from Volume 1 [93, §4.6] that the array package [58]
can be used to insert a declaration before each cell in a given column via:
>{⟨declaration⟩} Definition
directly before the column specifier. This means that if you have a column
for the description of an invoiced item, you can have ragged line wrapping,
which looks better than the default fully-justified paragraphs in a narrow column
context.
Example
Suppose my invoice needs four columns: the item description, the quantity
ordered, the unit price and the quantity times price. The last three columns can
just use the r specifier, but the first column may need a paragraph cell in the
event of a long description:
↑ Input
\begin{longtable}{>{\raggedright}p{0.3\linewidth}rrr}
\bfseries Item & \bfseries Quantity &
\bfseries Unit Price (\pounds) &
\bfseries Price (\pounds)\\
\midrule
\endhead
``\,`Duck and Goose': an allegory for modern times?'' (hardback) &
1 & 59.99 & 59.99\\
``My Friend is a Duck'' (paperback) & 20 & 14.99 & 299.80\\
``Annotated Notes on the `Duck and Goose' Chronicles'' (ebook) &
1 & 8.99 & 8.99\\
``The Adventures of Duck and Goose'' (hardback) & 1 & 18.99 & 18.99\\
\midrule
\multicolumn{3}{r}{\bfseries Sub-Total} & 368.78\\
\multicolumn{3}{r}{\bfseries Postage and Packaging} & 20.00\\
\multicolumn{3}{r}{\bfseries Promotional Discount} & $-2.50$\\
\midrule
\multicolumn{3}{r}{\bfseries Total} & 386.28
\end{longtable} ↓ Input
4.3 Building Your Own Invoice using longtable and datatool 130
This produces:
↑ Output
↓ Output
(As per \maketitle.) If you also want to specify a location next to the date, you
can use:
1T
EX Live is more restrictive than MiKTEX as it won’t include any bundles that don’t have an open
source licence or don’t provide source code for all the documentation. This means that there
are some packages or classes that are available on MiKTEX but are not on TEX Live.
131
5.1 The currvita Package 132
\cvplace{⟨location⟩} Definition
where ⟨heading⟩ is the title text, such as “Résumé” or “Curriculum Vitae” (or
“Curriculum Vitæ” if you prefer to use a ligature).
The contents of the CV are typically divided into sections containing lists.
These sections can be typeset within the cv environment using the cvlist environ-
ment:
\begin{cvlist}{⟨section heading⟩} Definition
where ⟨section heading⟩ is the heading text for this list. Within the body of the
cvlist environment, use the standard
\item[⟨label⟩] Definition
↑ Input
This produces:
↑ Output
Résumé
Personal Information
Name: Polly Parrot
Address: 42 The Lane, Some Town, Noshire AB1 2XY, United Kingdom
Telephone: 0123456789
Email: [email protected]
Nationality: British
Recall from Volume 2 [96, §5] that you can generate a list of citations us-
ing BibTEX or biber. In a CV it’s likely that you will want to include a list of
publications without citing them. In this case, instead of using
\cite{⟨key list⟩} Definition
to add the citations referenced in the comma-separated list ⟨key list⟩ without
producing any text. Alternatively, you can add all entries defined in your .bib
file using an asterisk:
\nocite{*} Input
So if you want to include a list of your publications you can use \nocite with
\bibliography and \bibliographystyle (as described in Volume 2 [96, §5.2]).
Exercise 15. Sample CV with Publications
Modify Example 25 so that it also includes a publications list. You can either use
your own .bib file or you can use the test xampl.bib file that’s included in TEX
distributions.
You can download or view a solution.
If you are in the European Union then you also need to switch to narrow Hel-
vetica using the class options helvetica and narrow:
↑ Input
\documentclass[helvetica,narrow]{europecv}
\usepackage{graphicx}
↓ Input
↑ Input
\documentclass[arial,narrow]{europecv}
\usepackage{graphicx}
↓ Input
The default paper size is US Letter, so if you want A4 paper, you need to use
the a4paper option:
↑ Input
\documentclass[helvetica,narrow,a4paper]{europecv}
\usepackage{graphicx}
↓ Input
5.2 The europecv Class 134
↑ Input
\documentclass[helvetica,narrow,a4paper]{europecv}
\usepackage{graphicx}
\begin{document}
\begin{europecv}
\end{europecv}
\end{document}
↓ Input
If you’re not writing in English, you can set the language using the class
option. This adjusts the predefined text used by europecv but doesn’t load babel,
so if you need babel (for example, you want to use the hyphenation patterns for
your language) you have to load it yourself in the preamble. The europecv class
automatically loads the inputenc package with the default input encoding is set to
utf8x. If you are using a different input encoding you must set it in the class
options. Remember that you also need to load the fontenc package.
Example:
If you are writing in French and using Latin 1 encoding:
↑ Input
\documentclass[helvetica,narrow,latin1,french]{europecv}
\usepackage[T1]{fontenc}
\usepackage{babel}
↓ Input
(babel will pick up the language option from the class option list.)
There are other class options as well, such as totpages, which will print the
total number of pages on each page. See the europecv documentation [112] for
further details.
Specifies your name as it will appear in the footer. If omitted, it will be the same
as set by \ecvname.
\ecvaddress{⟨address⟩} Definition
Specifies your address. The address will line-wrap, but if you want to force
a line break you need to use \newline not \\.
\ecvtelephone[⟨mobile⟩]{⟨telephone⟩} Definition
Specifies the name of the graphics file that contains an image of yourself. The
optional argument are as used by \includegraphics. You can also include text
before and after the image using:
\ecvbeforepicture{⟨text⟩} Definition
and
\ecvafterpicture{⟨text⟩} Definition
to make some minor adjustments to the picture’s position. This command can’t
be used outside the argument of \ecvbeforepicture or \ecvafterpicture.
Once you have specified all your personal details, as described above, you
need to use:
\ecvpersonalinfo[⟨vspace⟩] Definition
↑ Input
\documentclass[helvetica,narrow,a4paper]{europecv}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\begin{document}
\begin{europecv}
% display personal data:
5.2 The europecv Class 136
\ecvpersonalinfo
\end{europecv}
\end{document}
↓ Input
(You can download or view this example.) The resulting document is shown
in Figure 5.1.
where ⟨title⟩ is the section title and ⟨vspace⟩ is the height of the vertical space
that can optionally be inserted after the title.
The text within the section is specified using:
\ecvitem[⟨vspace⟩]{⟨left⟩}{⟨right⟩} Definition
where ⟨left⟩ is the text to place on the left of the vertical rule and ⟨right⟩ is the
text to place on the right of the vertical rule. The optional argument is again
the height of the vertical space that can be inserted after the text.
Example 27. Curriculum Vitæ With Sections (europecv class)
This example adds to the code from Example 26 so that it includes a section
listing professional positions.
↑ Input
\documentclass[helvetica,narrow,a4paper]{europecv}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\begin{document}
\begin{europecv}
% display personal data:
\ecvpersonalinfo
\ecvsection{Professional Positions}
\ecvitem{1990--8}{Junior assistant at
``Wibblies Avian Emporium''.}
\ecvitem{1998--Present}{Senior assistant at
``The International Society of Duck and Geese
Co-operation''.}
\end{europecv}
\end{document}
↓ Input
5.2 The europecv Class 137
Europass
Curriculum Vitae
Personal information
(You can download or view this document.) The resulting document is shown
in Figure 5.2.
↑ Input
\begin{document}
\begin{europecv}
% display personal data:
\ecvpersonalinfo
% start a new section:
\ecvsection{Professional Positions}
\ecvitem{1990--8}{Junior assistant at
``Wibblies Avian Emporium''.}
\ecvitem{1998--Present}{Senior assistant at
``The International Society of Duck and Geese Co-operation''.}
\end{europecv}
\bibliographystyle{plain}
\nocite{*}
\bibliography{mypublications}
\end{document}
↓ Input
An alternative is to use the bibentry package2 (part of the natbib bundle [19]), which
provides:
\nobibliography{⟨bib file⟩} Definition
which displays the citation information for the reference identified by ⟨key⟩.
Example:
↑ Input
\documentclass[helvetica,narrow,a4paper]{europecv}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{bibentry}
\begin{document}
\bibliographystyle{plain}
\nocite{*}
\nobibliography{mypublications}
\begin{europecv}
% display personal data:
2 The documentation for bibentry is inside the bibentry.sty file.
5.2 The europecv Class 139
Europass
Curriculum Vitae
Personal information
Professional Positions
1990–8 Junior assistant at “Wibblies Avian Emporium”.
1998–Present Senior assistant at “The International Society of
Duck and Geese Co-operation”.
\ecvpersonalinfo
% start a new section:
\ecvsection{Professional Positions}
\ecvitem{1990--8}{Junior assistant at
``Wibblies Avian Emporium''.}
\ecvitem{1998--Present}{Senior assistant at
``The International Society of Duck and Geese Co-operation''.}
% publications section:
\ecvsection{Publications}
\ecvitem{}{\bibentry{mypub1}}
\ecvitem{}{\bibentry{mypub2}}
\end{europecv}
\end{document}
↓ Input
where ⟨bbl⟩ is the name of the .bbl file (defaults to \jobname.bbl), ⟨db-name⟩
is the name of the new database and ⟨bib list⟩ is the list of .bib files (without
the .bib extension) where the bibliography data is stored.
As with \bibliography (see §5.1 and Volume 2 [96, §5.2]) you need to specify
which citations you want included in the .bbl file either via:
\cite{⟨key list⟩} Definition
which doesn’t produce any text, but ensures that BibTEX includes the references
in the .bbl file.
Example:
↑ Input
\nocite{*}
\DTLloadbbl{mypubdata}{myrefs}
↓ Input
This will create a datatool internal database called mypubdata that contains all the
bibliographic data stored in the file myrefs.bib. (As with \bibliography, this
requires a BibTEX run between LATEX runs to ensure the citations are up-to-date.)
This database can be iterated over using \DTLforeach (as described in §2.7.1).
However, since many of the fields will be null depending on the entry type, it’s
easier to iterate over the entries using:
\DTLforeachbibentry[⟨condition⟩]{⟨db-name⟩}{⟨body⟩} Definition
(This will always be in lower case, regardless of the case used in the .bib file.)
The remaining fields can be displayed using:
\DTLbibfield{⟨field name⟩} Definition
In both cases, ⟨field name⟩ is the column label, but no check is performed to
determine if the column exists, so the result may be a null value (see §2.9).
Available field labels are: Address, Author, BookTitle, Chapter, Edition, Editor,
HowPublished, Institution, Journal, Key, Month, Note, Number, Organization,
Pages, Publisher, School, Series, Title, Type, Volume, Year, ISBN, DOI, PubMed,
Abstract and Url. These labels are case-sensitive (independent of the case used
in the .bib file).
You can determine if a field exists within the ⟨body⟩ part of \DTLforeachbibentry
or \gDTLforeachbibentry using:
\DTLifbibfieldexists{⟨field label⟩}{⟨true part⟩}{⟨false part⟩} Definition
Since it’s quite complicated working out which fields are relevant for which
entry types, databib provides a convenient command that will format the entry
in the current iteration according to its entry type:
\DTLformatbibentry Definition
By default, this only displays the fields that would typically be displayed using the
standard plain bibliography style, so fields such as Url won’t be displayed, even if
they exist. This command also doesn’t use \bibitem (recall Volume 1 [93, §5.6]).
Since \bibitem internally uses \item, it’s only appropriate in a list context, but
it’s possible it may be needed outside a list. Therefore databib provides:
\DTLcustombibitem{⟨marker code⟩}{⟨ref text⟩}{⟨key⟩} Definition
where ⟨db-name⟩ is the label identifying the database and ⟨cite key⟩ is the label
identifying the reference.
Example 28. Tabulating a Bibliography
Using the above commands, it’s possible to display a bibliography within a longtable.
Recall from Exercise 15 that TEX distributions come with an example file called
xampl.bib. This has enough entries to test how well the code deals with page
breaking, and so will be used in this example.
The references in this example will be numbered (rather than using an au-
thor and year system), so a counter is defined to keep track of the numbering.
(See Volume 1 [93, §11].)
5.2 The europecv Class 142
↑ Input
\documentclass{article}
\usepackage{longtable}
\usepackage{databib}
\newcounter{refcount}
\newcommand*{\refmark}{%
\refstepcounter{refcount}[\therefcount]}
\begin{document}
\nocite{*}
\DTLloadbbl{refdata}{xampl}
\section*{Publications}
\begin{longtable}{rp{0.5\textwidth}}
\gDTLforeachbibentry{refdata}
{%
\DTLcustombibitem{\refmark}{\therefcount}{\DBIBcitekey} &
\DTLformatbibentry\\
}%
\end{longtable}
\end{document}
↓ Input
This creates a four-paged document. The first page is shown in Figure 5.3. You
can download or view this example document.
The data is unsorted, but remember that you can sort it using \DTLsort (see
§2.4). For example, to sort in reverse chronological order:
\DTLsort*{Year=descending,Month=descending}{refdata} Input
(The months should be specified using the BibTEX strings JAN, FEB etc, instead
of explicitly writing the month names in order to sort the months in numerical
order. You can redefine \DTLmonthname{⟨number⟩} to make the month names
appear in a different language.)
However, the database will be empty on the first run, which means you’ll get
an error if you try to sort it. You can test if the database is empty using:
\DTLifdbempty{⟨db-name⟩}{⟨true part⟩}{⟨false part⟩} Definition
↑ Input
\DTLifdbempty{refdata}
{}
{%
\DTLsort*{Year=descending,Month=descending}{refdata}%
}
↓ Input
It’s therefore possible to display your list of publications in the europecv en-
vironment, but it will be slow (since TEX is doing the sorting and it requires
iterating over a database).
5.2 The europecv Class 143
Output
Publications
↑ Input
\documentclass[helvetica,narrow,a4paper]{europecv}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{databib}
\newcounter{refcount}
\newcommand*{\refmark}{\refstepcounter{refcount}[\therefcount]}
\begin{document}
\nocite{*}
\DTLloadbbl{mypubdata}{xampl}
\DTLifdbempty{refdata}
{}
{%
\DTLsort*{Year=descending,Month=descending}{mypubdata}
}
\begin{europecv}
% display personal data:
\ecvpersonalinfo
% start a new section
\ecvsection{Professional Positions}
\ecvitem{1990--8}{Junior assistant at
``Wibblies Avian Emporium''.}
\ecvitem{1998--Present}{Senior assistant at
``The International Society of Duck and Geese Co-operation''.}
% publications section
\ecvsection{Publications}
% iterate over bib data:
\gDTLforeachbibentry*{mypubdata}%
{%
\ecvitem
{% left column
\DTLcustombibitem{\refmark}{\therefcount}{\DBIBcitekey}%
}%
{\DTLformatbibentry}% right column
}%
\end{europecv}
\end{document}
↓ Input
You may not want to include all the citations defined in your .bib file. For
example, you may only want to include your ten most recent publications or
you may only want to include just your books or journal articles. This looks as
though the solution can simply be obtained by filtering the rows of data, but un-
fortunately there’s a problem: the optional argument of \gDTLforeachbibentry
5.2 The europecv Class 145
doesn’t work within the longtable environment. Nor does \ifthenelse work
within the final argument of \gDTLforeachbibentry when used inside longtable
(although some of the etoolbox comparison commands, such as \ifnumless can).
When \gDTLforeachbibentry fails in a tabular-like environment, we can go
back to the technique used in the solution to Exercise 11 and again employed in
the more adventurous section of Exercise 12, where the commands described
in §2.1.2 were used to first build a command that could subsequently be used in
the problematic environment.
Exercise 16. List of Selected Publications (europecv class)
Bearing in mind the above note, modify Example 29 so that it just lists the
ten most recent publications. You can keep track of the current row within
\DTLforeachbibentry with the DTLbibrow counter. As with \DTLforeach, you can
prematurely terminate the loop at the end of the current iteration by placing
\dtlbreak anywhere within ⟨body⟩.
Hint: you will need to use the standalone \DTLformatthisbibentry command
instead of \DTLformatbibentry and you can check if one integer value is less
than another integer value using etoolbox’s
\ifnumless{⟨number 1⟩}{⟨number 2⟩}{⟨true part⟩}{⟨false part⟩} Definition
For example:
\ecvmothertongue{English} Input
where ⟨symbol⟩ is a footnote symbol used in the table footer. Each row of the
language table is then typeset using:
\ecvlanguage[⟨vspace⟩]{⟨language⟩}{⟨l1⟩}{⟨l2⟩}{⟨l3⟩}{⟨l4⟩}{⟨l5⟩} Definition
where ⟨vspace⟩ again indicates any vertical space that should be inserted after
the row, and ⟨language⟩ is the name of the language. The other five arguments
⟨l1⟩, . . . , ⟨l5⟩ should be brief descriptions relating to:
⟨l1⟩ understanding (listening);
⟨l2⟩ understanding (reading);
5.2 The europecv Class 146
where ⟨level⟩ is the self-assessment level code and ⟨descr⟩ is a brief description.
There are some convenient shortcuts described in Table 5.1.
Shortcut Expansion
\ecvAOne \ecvCEF{A1}{basic user}
\ecvATwo \ecvCEF{A2}{basic user}
\ecvBOne \ecvCEF{B1}{independent user}
\ecvBTwo \ecvCEF{B2}{independent user}
\ecvCOne \ecvCEF{C1}{proficient user}
\ecvCTwo \ecvCEF{C2}{proficient user}
After the last language row, the table footer is typeset using:
\ecvlanguagefooter[⟨vspace⟩]{⟨symbol⟩} Definition
↑ Input
\ecvmothertongue[10pt]{English}
\ecvlanguageheader{(*)}
\ecvlanguage{French}{\ecvCOne}{\ecvCTwo}{\ecvBTwo}{\ecvCOne}{\ecvCTwo}
\ecvlastlanguage{German}{\ecvATwo}{\ecvATwo}{\ecvATwo}{\ecvATwo}{\ecvATwo}
\ecvlanguagefooter{(*)}
↓ Input
B Unless you use either narrow Arial or condensed Helvetica, the language
table may appear cramped. For this example to work, I used the following
settings to adjust the left column width and the gap on either side of the vertical
rule:
↑ Input
\ecvLeftColumnWidth{2cm}
\ecvColSep{4pt}
↓ Input
This produces the output shown in Figure 5.4 unless you use the booktabs
class option:
\documentclass[helvetica,narrow,a4paper,10pt,booktabs]{europecv} Input
Output
Mother English
tongue(s)
Self- Understanding Speaking Writing
assessment Spoken Spoken
European level (*) Listening Reading
interaction production
C1 Proficient C2 Proficient B2 Independent C1 Proficient C2 Proficient
French user user user user user
German A2 Basic user A2 Basic user A2 Basic user A2 Basic user A2 Basic user
(*)
Common European Framework of Reference (CEF) level
Output
Mother English
tongue(s)
Self-
assessment Understanding Speaking Writing
European level (*) Spoken Spoken
Listening Reading
interaction production
C1 Proficient C2 Proficient B2 Independent C1 Proficient C2 Proficient
French user user user user user
German A2 Basic user A2 Basic user A2 Basic user A2 Basic user A2 Basic user
(*)
Common European Framework of Reference (CEF) level
6.1 Memos
§3.3 introduced the newlfm class [107], which can be used for writing correspon-
dence. This class can also be used for writing memos and press releases. (See
the next section for press releases.) If you read the earlier section on the newlfm
class, you may remember that you can set the style of the document through
the class options. For example, the stdletter option sets the standard letter
style. There are two styles relating to memos: stdmemo (standard memo) and
fullmemo (full memo).
As before, you still use the newlfm environment. However, some of the com-
mands described in §3.3 are ignored for the memo styles, such as those that set
the greeting, closing and signature. Again, options can be set using either the
class option list or the command:
\newlfmP{⟨options list⟩} Definition
that in the current version of newlfm (dated 2009-04-10) there are bugs
B Note
in the memonofrom, memonoto and memonore options. The following lines are
workarounds to implement these options:
↑ Input
\setboolean{@memo@e}{false}% memonofrom
\setboolean{@memo@g}{false}% memonoto
\setboolean{@memo@f}{false}% memonore
↓ Input
↑ Input
\documentclass[12pt]{newlfm}
\usepackage[british]{babel}
\newlfmP{stdmemo,memoemailfrom,memophonefrom,memoaddrfrom,memodate}
148
6.2 Press Releases 149
Option Description
memonofrom Omit sender’s block.
memoemailfrom Include sender’s email.
memoaddrfrom Include recipient’s address.
memophonefrom Include sender’s telephone number.
memofaxfrom Include recipient’s fax number.
memopagerfrom Include recipient’s pager number.
memonoto Omit recipient’s block.
memoemailto Include recipient’s email.
memoaddrto Include recipient’s address.
memophoneto Include recipient’s telephone number.
memofaxto Include recipient’s fax number.
memopagerto Include recipient’s pager number.
memodate Set the date on the memo.
fullmemo Use all optional items.
memonore Omit the “Re:” line.
\dateset{11-03-2014}
\nameto{Mabel Canary}
\re{Cricket Match}
\begin{newlfm}
It has come to my attention that certain members of your team
intend to bring the prototype ray gun to the forthcoming cricket
match against the Department of Stripy Confectioners in order to
`level the playing field'. Please remind them that this is against
regulations. Also, the mind-controlling cookies are inappropriate
for the tea interval provisions.
\end{newlfm}
\end{document}
↓ Input
(You can download or view this example.) The resulting document is shown in
Figure 6.1.
It has come to my attention that certain members of your team intend to bring the prototype
ray gun to the forthcoming cricket match against the Department of Stripy Confectioners in
order to ‘level the playing field’. Please remind them that this is against regulations. Also,
the mind-controlling cookies are inappropriate for the tea interval provisions.
\headline{⟨text⟩} Definition
By default, the phrase “For Immediate Release” is placed at the start. This
wording can be changed using
\release{⟨text⟩} Definition
↑ Input
\documentclass{newlfm}
\usepackage{url}
\usepackage[british]{babel}
\newlfmP{pressrelease}
\begin{document}
\begin{newlfm}
The University of Somewhere is throwing open the doors
of its renowned Secret Experimental Lab to the public
for the first time ever on 1st April 2014.
Website: \url{www.somewhere.ac.uk}
\end{newlfm}
\end{document}
↓ Input
(You can download or view this example.) The resulting document is shown in
Figure 6.2.
The newlfm class is quite difficult to adapt and it seems strange not to have an
email option for a press release in this Internet age. Since this didn’t suit my
purposes and I couldn’t find another class for press releases, I decided to write
my own class called pressrelease [97], which I uploaded to CTAN. At the time of
writing, the current version is 1.0 (dated 2014-09-10).
The pressrelease class has the following class options:
6.2 Press Releases 152
The University of Somewhere is throwing open the doors of its renowned Secret Experimental Lab to
the public for the first time ever on 1st April 2014.
Mr Big Head, managing director of the lab, will be giving conducted tours between 11:59 and 12:00. More
Website: www.somewhere.ac.uk
###
1 of 1
The date of the press release is specified using the standard \date command.
The company logo (if required) is specified using:
\PRlogo{⟨logo⟩} Definition
where ⟨logo⟩ is the command or commands required to input or draw the logo.
For example, if the logo is in the image file company-logo.png:
\PRlogo{\includegraphics{company-logo}} Input
(Remember that you need to load the graphicx package if you want to use the
\includegraphics command.)
The company’s name is specified using:
\PRcompany{⟨name⟩} Definition
\PRhours{⟨times⟩} Definition
For example:
\PRhours{Mon--Fri 9:00--17:00} Input
As with titling commands, such as \title, the above commands just store
the information and may be placed in the preamble. The actual contents of the
press release should go in the pressrelease environment. Within this environment,
you can use the about environment to add information about the company.
\begin{pressrelease}
⟨press release text⟩
\begin{about} Definition
⟨information about the company⟩
\end{about}
\end{pressrelease}
Exercise 17. Press Release (pressrelease class)
Adapt Example 31 so that it uses the pressrelease class and add an email address
to the contact details. You can download or view a solution.
6.3 Minutes
There are only three options for writing minutes listed on the meeting-admin
topic page: the meetingmins class (which can also typeset agendas but has no
multilingual support), the minutes package and the protocol class. The last one,
protocol, only has German documentation, so it’s not discussed here.
\setmembers{⟨list⟩} Definition
where ⟨list⟩ is a list of members. (The member list is only used by the chair
class option.) The list of people present at the meeting is set using:
\setpresent{⟨list⟩} Definition
where again ⟨list⟩ is a list of names. (This list is ignored by the chair and agenda
options.) Within ⟨list⟩, for both \setmembers and \setpresent, the chair’s name
should be set with:
\chair{⟨name⟩} Definition
Example:
↑ Input
This sets information (analogous to \author and \title) but doesn’t actually
display any information, so these commands may be used in the preamble. As
with \author and \title, you need to use
\maketitle Definition
is a convenient shortcut for “The minutes of the previous meeting were ap-
proved”.
Example:
↑ Input
\section{Announcements}
\begin{hiddenitems}
\item A~fire alarm drill is expected during the meeting.
\end{hiddenitems}
\section{Old Business}
\begin{items}
\item \priormins
\end{items}
\section{New Business}
\begin{items}
\item Discuss schedules for secret research.
If the chair or notes class options are used the fire alarm announcement will
be displayed, otherwise it will be skipped.
Exercise 18. Minutes and Agendas (meetingmins class)
Create a document using the meetingmins class that uses all the commands de-
scribed in this section. Try using the different class options to see how they
affect the document. (Remember that you can’t mix the class options.)
You can download or view a solution.
is German, so if you are writing the minutes in English, you’ll need to load
babel [7] with the english option.
The meeting minutes are contained in the body of the Minutes environment
\begin{Minutes}{⟨title⟩} Definition
where ⟨title⟩ is the title of the minutes. You can have more than one Minutes
environment within your document, for example, if you want a compilation of
all the minutes for a particular group or committee.
Within the Minutes environment, you can set various information using the
commands described below.
\subtitle{⟨title⟩} Definition
This sets the name of the meeting moderator (for example, the chair).
\minutetaker{⟨name⟩} Definition
This sets the distribution list. The argument ⟨names⟩ is a list of names of people
who should receive a copy of the minutes. To specify absentees, you can either
use
\missingExcused{⟨excused names⟩} Definition
and
\missingNoExcuse{⟨no-excuse names⟩} Definition
or
\missing[⟨excused names⟩]{⟨no-excuse names⟩} Definition
↑ Input
\documentclass{article}
\usepackage[english]{babel}
\usepackage{minutes}
\begin{document}
\maketitle
\end{Minutes}
\end{document}
↓ Input
The result is shown in Figure 6.3. Since this document only contains the minutes
from a single meeting, I haven’t bothered to include an overall document title
or table of contents. This causes warnings from the minitoc package [22] (which
the minutes package loads). If you want to have a collection of minutes, you can
add the title and contents at the start of the document:
↑ Input
\begin{document}
\title{Minutes from the Secret Lab Meetings}
\author{Dr Bor Ing}
\maketitle
\tableofcontents
% add the Minutes environments here
↓ Input
where ⟨text⟩ is the topic or subtopic and ⟨toc text⟩ is alternative text for the table
of contents. These commands are analogous to sectioning commands such as
\section. The ⟨toc text⟩ (or ⟨text⟩ if the optional argument is omitted) appears
in an overview section in the minutes and also appears in the overall document
table of contents (if \tableofcontents has been used, as described above).
6.3 Minutes 159
Output
Tasks can be specified using the \task command which has a starred and
unstarred version. The unstarred version has the syntax:
\task[⟨footnote text⟩]{⟨name⟩}[⟨when⟩]{⟨text⟩} Definition
Example:
↑ Input
\topic{Tasks}
\subtopic{New Experimental Stuff}
\task[done]{Mabel Canary}[tomorrow]{Proposal for a time machine}
\task[pending]{Polly Parrot}{Apply for a ray gun grant}
\subtopic{Kitchen}
\task*{Order a new coffee machine}
\task*[today]{Remove the mind-controlling cookies} ↓ Input
As with the meetingmins class, the minutes package allows you to hide text. This
is done either via the command:
\secret{⟨secret text⟩} Definition
Example:
↑ Input
\begin{Secret}
\task*{There will be a surprise lab inspection on Tuesday.}
\end{Secret} ↓ Input
6.3 Minutes 160
where ⟨main⟩ is the main opinion held and ⟨differing⟩ is the differing opinion.
The discussion can then be formatted using the Opinions environment:
\begin{Opinions}
\item[⟨name⟩] ⟨opinion⟩
Definition
...
\end{Opinions}
Example:
↑ Input
\opinion
{Keep the coffee break at 11.00am}% main
{Move the coffee break to 10:30am}% differing
\begin{Opinions}
\item[Mabel Canary] We should continue to have
coffee at 11:00am.
\item[Polly Parrot] We should move the coffee
break to an earlier time.
\end{Opinions}
↓ Input
↑ Input
\begin{Argumentation}
\pro We've always had coffee at 11:00am. There's no need to change
it.
\contra 11:00am is too long a wait for the caffeine addicts.
\Pro Coffee at 10:30am would interfere with our clandestine
experiments scheduled at that time.
\item Prof Important Person said it would be better to have tea
6.3 Minutes 161
instead of coffee.
\result The coffee break will continue to be at 11:00am.
\end{Argumentation}
↓ Input
indicates that there were two votes in favour of maintaining coffee at 11am, one
vote against and one abstainer.
Multiple votes can be listed in the Vote environment:
\begin{Vote}
\vote{⟨description⟩}{⟨yes⟩}{⟨no⟩}{⟨abstain⟩}[⟨decision⟩]
Definition
...
\end{Vote}
Example:
↑ Input
\begin{Vote}
\vote{Maintain coffee at 11am?}{2}{1}{1}
\vote{Move clandestine experiments to after lunch?}{1}{3}{0}
\end{Vote}
↓ Input
This doesn’t display anything in the document at this point, but it will be added
to the list of decisions which can be displayed using:
\listofdecisions Definition
There is also a starred version which doesn’t add the decision to the list of
decisions:
\decision*{⟨short description⟩}[⟨long description⟩] Definition
Example:
↑ Input
This should be placed before the end of the Minutes environment. Any additional
information that doesn’t belong to the minutes may be included in the Postscript
environment
\begin{Postscript}
⟨additional information⟩ Definition
\end{Postscript}
or in the argument of
\postscript{⟨additional information⟩} Definition
For other commands not listed here, including how to alter the style, see the
minutes documentation.
Exercise 19. Minutes (minutes package)
Extend the document in Example 32 to include topics, tasks, opinions, argu-
ments, votes and decisions.
You can download or view a solution.
6.4 Confidentiality
This section covers some topics related to confidentiality. There are a number
of options listed on the security topic page. This section will just be looking at
redaction (§6.4.1) and watermarks (§6.4.2). See also §2.3 for advice on document
security.
Example:
↑ Input
Following the research group's unsuccessful attempt
to create \censor{mind-controlling} \censor{cookies},
they will now be working on a new \censor{ray gun}.
↓ Input
produces:
↑ Output
Following the research group’s unsuccessful attempt to create
, they will now be working on a new .
↓ Output
Note that the argument of \censor is placed in a box so its contents can’t be
broken across a line, which is why I split up “mind-controlling” and “cookies”.
In fact, it may even be necessary to do:
6.4 Confidentiality 163
where ⟨box⟩ is the box being redacted and ⟨declarations⟩ are any commands
(such as font-changing declarations) that should be applied before the start of
the box.
Example:
↑ Input
\begin{table}
\caption{A Redacted Table}
\label{tab:redacted}
\centering
\censorbox{%
\begin{tabular}{lc}
\bfseries Project & \bfseries Success Rate \\
Mind-controlling Cookies & 2\%\\
Telepathic Cakes & 1\%\\
Exploding Chocolates & 25\%
\end{tabular}%
}
\end{table}
↓ Input
Example:
↑ Input
produces:
↑ Output
.
↓ Output
Note that there are restrictions on the use of \blackout: ⟨text⟩ can’t end with
“glue”, such as a space or EOL character; periods aren’t redacted; it can’t be
used across changes in scope, such as environment boundaries or across cells
within a tabular-like environment. This command also shows spaces between
6.4 Confidentiality 164
words (unless the spaces are hidden within a token), but there is an alternative
command that hides these spaces:
\xblackout{⟨text⟩} Definition
Example:
↑ Input
produces:
↑ Output
.
↓ Output
This command also suffers from drawbacks. For example, the redaction can
cause lines to protrude into the left and right margins. See the censor documen-
tation for further details.
The unredacted version of the document can be created by placing
\StopCensoring Definition
at the beginning of the document. You can also restart redaction with:
\RestartCensoring Definition
It’s possible that you may need to work on your document at an insecure
location. In which case, you won’t want your sensitive information in your .tex
file. The censor package provides:
\censor*{⟨size⟩} Definition
where ⟨size⟩ is the approximate width (in ex) of the redacted text, and:
\censorbox*[⟨declarations⟩]{⟨width⟩}{⟨height⟩}{⟨depth⟩} Definition
where ⟨width⟩ is the approximate width (in ex) of the box, ⟨height⟩ is the ap-
proximate height (in multiples of \baselineskip) and ⟨depth⟩ is the approximate
depth (in multiples of \baselineskip). The optional argument should be used
to specify any commands (such as font changing declarations) that may effect
the size of an ex or the value of \baselineskip. (For example, \small.) There’s
no starred version of \blackout or \xblackout.
Example:
↑ Input
\newcommand*{\OldProject}{%
\censor*{4}-\censor*{11} \censor*{7}}
\newcommand*{\NewProject}{\censor*{3} \censor*{3}}
\newcommand*{\SuccessRates}{\censorbox*{40}{4}{0}}
\begin{table}
6.4 Confidentiality 165
If the censoring is on, the redacted text will again be replaced by filled rectan-
gles:
↑ Output
Following the research group’s unsuccessful attempt to create -
, they will now be working on a new . The success rate of previous
projects is shown in Table 6.3.
↓ Output
Output
Table 6.3 Project Success Rates
↑ Output
Following the research group’s unsuccessful attempt to create -
, they will now be working on a new . The success rate of previous
projects is shown in Table 6.4.
↓ Output
Output
Table 6.4 Project Success Rates
In your secure environment, you can change the definitions of the macros
for the redacted material:
↑ Input
\newcommand*{\OldProject}{%
\censor{mind}-\censor{controlling} \censor{cookies}}
\newcommand*{\NewProject}{\censor{ray} \censor{gun}}
\newcommand*{\SuccessRates}{%
\censorbox{%
\begin{tabular}{lc}
\bfseries Project & \bfseries Success Rate \\
Mind-controlling Cookies & 2\%\\
Telepathic Cakes & 1\%\\
Exploding Chocolates & 25\%
\end{tabular}%
}%
} ↓ Input
6.4 Confidentiality 166
↑ Input
\newcommand*{\OldProject}{%
\censor{mind}-\censor{controlling} \censor{cookies}}
\newcommand*{\NewProject}{\censor{ray} \censor{gun}}
\newcommand*{\SuccessRates}{%
\censorbox{%
\begin{tabular}{lc}
\bfseries Project & \bfseries Success Rate \\
Mind-controlling Cookies & 2\%\\
Telepathic Cakes & 1\%\\
Exploding Chocolates & 25\%
\end{tabular}%
}
}
↓ Input
This is your secret file that shouldn’t leave your secure location. In your main
document you can test for a file’s existence, and only input it if it exists, using:
\InputIfFileExists{⟨file⟩}{⟨true part⟩}{⟨false part⟩} Definition
This tests if the file named ⟨file⟩ exists (the .tex extension may be omitted). If
the file exists, this command does ⟨true part⟩ and then loads ⟨file⟩. If the file
doesn’t exist, this command just does ⟨false part⟩. So the main document can
include this command to determine whether to use the starred or unstarred
versions:
↑ Input
\documentclass[captions=tableheading]{scrartcl}
\usepackage{censor}
\InputIfFileExists{definitions}{}%
{%
\newcommand*{\OldProject}{%
\censor*{4}-\censor*{11} \censor*{7}}
\newcommand*{\NewProject}{\censor*{3} \censor*{3}}
\newcommand*{\SuccessRates}{\censorbox*{40}{4}{0}}
}
\begin{document}
\begin{table}
\caption{Project Success Rates}
\label{tab:success}
\centering
\SuccessRates
\end{table}
\end{document}
↓ Input
6.4.2 Watermarks
[FAQ: ‘Watermarks’ on
There are a number of packages that enable you to place some text (such as every page]
“CONFIDENTIAL” or “DRAFT”) across the background of every page. In ad-
dition to these packages, the pdftk application described in §2.3, can also be
used for this purpose. CTAN has several topics that cover this area: watermark,
background and decoration. This section will only discuss two packages: xwater-
mark (which extends the draftmark and watermark packages) and background. The
background package is simpler to use. The xwatermark package is more flexible.
where ⟨options⟩ is a key=value list. The background package requires two LATEX
calls during the document build. Available options are:
pages This key specifies whether the watermark should appear on all or
some of the pages. Available values are: all or some. If the value
some is specified, you must use the command \BgThisPage on the
pages where the watermark is required. If the value all is specified,
you can use the command \NoBgThisPage on the pages where you
don’t want a watermark. (Don’t use this command in two-column
mode.)
firstpage This is a boolean key. If true, the watermark only appears on the
first page. (The default is false.)
placement This key specifies the placement of the watermark and may take
one of the values: center (default), top or bottom.
contents This key specifies the material used for the watermark. The value
may be just text (such as “Confidential”) or an image included using
\includegraphics. If the value of this key contains commands, the
key may only be used within \backgroundsetup not as a package
option.
color The watermark colour. (The background package automatically loads
the xcolor package [41].)
angle This key specifies the angle of rotation.
6.4 Confidentiality 168
opacity This key indicates the transparency. The value may be a num-
ber from 0 (full transparency) to 1 (no transparency). Note that
PostScript doesn’t support transparency, so if you use latex and
dvips, the watermark won’t show any transparency in the PostScript
file.
scale This key specifies the scale factor.
position This key can be used to adjust the position of the watermark. The
value should be in TikZ coordinate form (see the pgf manual [102]).
anchor This key specifies the TikZ anchor for the watermark. (See the pgf
manual [102].)
hshift This key specifies the horizontal shift.
vshift This key specifies the vertical shift.
↑ Input
\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{background}
\usepackage{lipsum}
\backgroundsetup{contents={CONFIDENTIAL}}
\begin{document}
\lipsum[1-55]
\end{document}
↓ Input
The first page of this document is shown in Figure 6.4. You can download or
view this example.
L
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida
mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.
A
Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus
et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra
metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus
eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium
quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean
rutrum. TI
faucibus. Morbi dolor nulla, malesuada eu, pulvinar at, mollis ac, nulla. Cur-
abitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue
eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim
Nam dui ligula, fringilla a, euismod sodales, sollicitudin vel, wisi. Morbi
auctor lorem non justo. Nam lacus libero, pretium at, lobortis vitae, ultricies et,
tellus. Donec aliquet, tortor sed accumsan bibendum, erat ligula aliquet magna,
vitae ornare odio metus a mi. Morbi ac orci et nisl hendrerit mollis. Suspendisse
EN
ut massa. Cras nec ante. Pellentesque a nulla. Cum sociis natoque penatibus et
magnis dis parturient montes, nascetur ridiculus mus. Aliquam tincidunt urna.
Nulla ullamcorper vestibulum turpis. Pellentesque cursus luctus mauris.
Nulla malesuada porttitor diam. Donec felis erat, congue non, volutpat at,
tincidunt tristique, libero. Vivamus viverra fermentum felis. Donec nonummy
pellentesque ante. Phasellus adipiscing semper elit. Proin fermentum massa
ac quam. Sed diam turpis, molestie vitae, placerat a, molestie nec, leo. Mae-
cenas lacinia. Nam ipsum ligula, eleifend at, accumsan nec, suscipit a, ipsum.
Morbi blandit ligula feugiat magna. Nunc eleifend consequat lorem. Sed lacinia
nulla vitae enim. Pellentesque tincidunt purus vel magna. Integer non enim.
ID
Praesent euismod nunc eu purus. Donec bibendum quam in tellus. Nullam cur-
sus pulvinar lectus. Donec et mi. Nam vulputate metus eu enim. Vestibulum
pellentesque felis eu massa.
Quisque ullamcorper placerat ipsum. Cras nibh. Morbi vel justo vitae lacus
tincidunt ultrices. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In
hac habitasse platea dictumst. Integer tempus convallis augue. Etiam facilisis.
Nunc elementum fermentum wisi. Aenean placerat. Ut imperdiet, enim sed
gravida sollicitudin, felis odio placerat quam, ac pulvinar elit purus eget enim.
NF
Nunc vitae tortor. Proin tempus nibh sit amet nisl. Vivamus quis tortor vitae
risus porta vehicula.
Fusce mauris. Vestibulum luctus nibh at lectus. Sed bibendum, nulla a fau-
cibus semper, leo velit ultricies tellus, ac venenatis arcu wisi vel nisl. Vestibulum
diam. Aliquam pellentesque, augue quis sagittis posuere, turpis lacus congue
quam, in hendrerit risus eros eget felis. Maecenas eget erat in sapien mattis
porttitor. Vestibulum porttitor. Nulla facilisi. Sed a turpis eu lacus commodo
facilisis. Morbi fringilla, wisi in dignissim interdum, justo lectus sagittis dui, et
vehicula libero dui cursus dui. Mauris tempor ligula sed lacus. Duis cursus enim
ut augue. Cras ac magna. Cras nulla. Nulla egestas. Curabitur a leo. Quisque
CO
egestas wisi eget nunc. Nam feugiat lacus vel est. Curabitur consectetuer.
Suspendisse vel felis. Ut lorem lorem, interdum eu, tincidunt sit amet,
laoreet vitae, arcu. Aenean faucibus pede eu ante. Praesent enim elit, rutrum
at, molestie non, nonummy vel, nisl. Ut lectus eros, malesuada sit amet, fer-
mentum eu, sodales cursus, magna. Donec eu purus. Quisque vehicula, urna sed
ultricies auctor, pede lorem egestas dui, et convallis elit erat sed nulla. Donec
where ⟨mark⟩ is the watermark text. This may be empty if you want an image
for the watermark. There is a starred variant of this command that puts the
watermark in the foreground instead of the background. There is also a prime
variant, but that’s not covered here. See the xwatermark documentation [60] for
further details.
The optional argument, ⟨options⟩, is a key=value list of options. For brevity,
this section only covers a small subset of those options. See the xwatermark
documentation for further details. The option list must contain the page or
page set on which the watermark is to be displayed. The page specifier keys
are as follows:
allpages This key doesn’t have a value. It indicates that the watermark should
be displayed on all pages.
oddpages This key doesn’t have a value. It indicates that the watermark should
be displayed on all odd pages.
evenpages This key doesn’t have a value. It indicates that the watermark should
be displayed on all even pages.
firstpage This key doesn’t have a value. It indicates that the watermark should
only be displayed on the first page.
lastpage This key doesn’t have a value. It indicates that the watermark should
only be displayed on the last page.
page The value of this key should be a page number to indicate that
the page on which the watermark should be display. For example,
page=4 indicates that the watermark should be displayed on page 4.
pages The value of this key should be a range in the form ⟨n⟩-⟨m⟩ to
indicate that the watermark should be displayed on pages ⟨n⟩ to ⟨m⟩,
inclusive. For example, pages=4-10 indicates that the watermark
should be displayed on pages 4 to 10.
pagex The value of this key should be a comma-separated list of page
numbers on which the watermark should be displayed. For example,
pagex={1,3,7} indicates that the watermark should be displayed on
pages 1, 3 and 7.
The text for the watermark may also be specified in ⟨options⟩ using the
textmark={⟨mark⟩} key. The watermark can be scaled, rotated or translated
using the following keys:
scale The value of this key is the scaling factor.
angle The value of this key is the angle of rotation.
xpos The value of this key specifies the horizontal position of the watermark
relative to the centre of the page.
6.4 Confidentiality 171
ypos The value of this key specifies the vertical position of the watermark
relative to the centre of the page.
The formatting of the watermark can be adjusted using the following keys:
textalign The value of this key indicates the horizontal alignment of the
watermark and may be one of: center (default), left, right or
justified.
fontfamily The value of this key is the name of the font family (as supplied to
\fontfamily). For example, fontfamily=pbk indicates Bookman.
fontseries The value of this key is the name of the font series (as supplied to
\fontseries). For example, fontseries=b indicates bold.
fontsize The value of this key is the font size. The default is 1 cm.
textcolor The value if this key is the colour of the watermark text.
If an image is required, the following keys specify the image file information:
picfile The value of this key is the image filename. This should be in the
same form as the mandatory argument of \includegraphics, so
remember to use forward slashes for the directory divider even if
you are building your document on a Windows operating system.
picfileext The value of this key is the image file extension (such as pdf or
png). Note that you have to use picfileext if you use picfile.
picscale The value of this key is the scaling factor to apply to the image.
picangle The value of this key is the angle of rotation to apply to the images.
There are other keys not covered here. See the xwatermark documentation [60]
for further details.
Example 35. Watermarks (xwatermark package)
As with Example 34, this example uses the lipsum package [33] to generate
dummy text to pad out the document.
↑ Input
\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{xwatermark}
\usepackage{lipsum}
\newwatermark[%
allpages,% show on all pages
fontfamily=pbk,% use Bookman font family
angle=55,% rotate by 55 degrees
scale=2.75,% scale by 2.75
xpos=-1cm,% shift by 1cm to the left
ypos=1cm% shift up by 1cm
]{SAMPLE WATERMARK}
\begin{document}
\lipsum[1-55]
\end{document}
↓ Input
6.5 Typesetting Legal Documents (Numbered Paragraphs) 172
The first page of this document is shown in Figure 6.5. You can download
or view this example.
The simplest way of achieving this is to use the enumerate environment (de-
scribed in Volume 1 [93, §4.4.2]) and redefine the way the counters are displayed.
By default, LATEX allows up to four nested enumerate environments. Each level has
a separate counter: enumi, enumii, enumiii and enumiv. Recall from Volume 1 [93,
§11] that the displayed value of a counter is governed by the command:
\the⟨counter⟩ Definition
(For example, \theenumi.) The default formats for each level use: \arabic,
\alph, \roman and \Alph. The format used if the items are cross-referenced
using the \label/\ref mechanism prefixes \the⟨counter⟩ with:
\p@⟨counter⟩ Definition
K
AR
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida
mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.
Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus
et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra
metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus
eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium
M
quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean
faucibus. Morbi dolor nulla, malesuada eu, pulvinar at, mollis ac, nulla. Cur-
abitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue
eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim
rutrum.
ER
Nam dui ligula, fringilla a, euismod sodales, sollicitudin vel, wisi. Morbi
auctor lorem non justo. Nam lacus libero, pretium at, lobortis vitae, ultricies et,
tellus. Donec aliquet, tortor sed accumsan bibendum, erat ligula aliquet magna,
vitae ornare odio metus a mi. Morbi ac orci et nisl hendrerit mollis. Suspendisse
ut massa. Cras nec ante. Pellentesque a nulla. Cum sociis natoque penatibus et
magnis dis parturient montes, nascetur ridiculus mus. Aliquam tincidunt urna.
Nulla ullamcorper vestibulum turpis. Pellentesque cursus luctus mauris.
Nulla malesuada porttitor diam. Donec felis erat, congue non, volutpat at,
AT
sus pulvinar lectus. Donec et mi. Nam vulputate metus eu enim. Vestibulum
pellentesque felis eu massa.
Quisque ullamcorper placerat ipsum. Cras nibh. Morbi vel justo vitae lacus
tincidunt ultrices. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In
hac habitasse platea dictumst. Integer tempus convallis augue. Etiam facilisis.
Nunc elementum fermentum wisi. Aenean placerat. Ut imperdiet, enim sed
gravida sollicitudin, felis odio placerat quam, ac pulvinar elit purus eget enim.
E
Nunc vitae tortor. Proin tempus nibh sit amet nisl. Vivamus quis tortor vitae
risus porta vehicula.
Fusce mauris. Vestibulum luctus nibh at lectus. Sed bibendum, nulla a fau-
PL
cibus semper, leo velit ultricies tellus, ac venenatis arcu wisi vel nisl. Vestibulum
diam. Aliquam pellentesque, augue quis sagittis posuere, turpis lacus congue
quam, in hendrerit risus eros eget felis. Maecenas eget erat in sapien mattis
porttitor. Vestibulum porttitor. Nulla facilisi. Sed a turpis eu lacus commodo
facilisis. Morbi fringilla, wisi in dignissim interdum, justo lectus sagittis dui, et
vehicula libero dui cursus dui. Mauris tempor ligula sed lacus. Duis cursus enim
ut augue. Cras ac magna. Cras nulla. Nulla egestas. Curabitur a leo. Quisque
M
egestas wisi eget nunc. Nam feugiat lacus vel est. Curabitur consectetuer.
Suspendisse vel felis. Ut lorem lorem, interdum eu, tincidunt sit amet,
laoreet vitae, arcu. Aenean faucibus pede eu ante. Praesent enim elit, rutrum
at, molestie non, nonummy vel, nisl. Ut lectus eros, malesuada sit amet, fer-
mentum eu, sodales cursus, magna. Donec eu purus. Quisque vehicula, urna sed
SA
ultricies auctor, pede lorem egestas dui, et convallis elit erat sed nulla. Donec
\label⟨counter⟩ Definition
and you want the label for the third level enumerate items to use parentheses:
\renewcommand*{\labelenumiii}{(\theenumiii)} Input
but when you cross-reference a third level enumerate item, \ref should use the
format ⟨level1⟩.⟨level2⟩.⟨level3⟩:
\renewcommand*{\p@enumiii}{\theenumi.\theenumii.} Input
↑ Input
\renewcommand*{\p@enumii}{\theenumi.}
\renewcommand*{\p@enumiii}{\p@enumii\theenumii.}
↓ Input
↑ Input
\renewcommand*{\theenumi}{\thesection.\arabic{enumi}}
\renewcommand*{\theenumii}{\theenumi.\arabic{enumii}}
\renewcommand*{\theenumiii}{\theenumii.\arabic{enumiii}}
\renewcommand*{\theenumiv}{\theenumiii.\arabic{enumiv}}
↓ Input
↑ Input
\renewcommand*{\labelenumi}{\theenumi.}
\renewcommand*{\labelenumii}{\theenumii.}
\renewcommand*{\labelenumiii}{\theenumiii.}
\renewcommand*{\labelenumiv}{\theenumiv.}
↓ Input
Since all the counter formats (\theenumi, . . . , \theenumiv) are now hierarchi-
cal, the internal commands used as a prefix by the cross-referencing mechanism
need to be defined to do nothing:
↑ Input
\renewcommand*{\p@enumi}{}
\renewcommand*{\p@enumii}{}
\renewcommand*{\p@enumiii}{}
\renewcommand*{\p@enumiv}{}
↓ Input
6.5 Typesetting Legal Documents (Numbered Paragraphs) 175
↑ Input
\begin{enumerate}
\item This website is run by the Secret Lab of Experimental Stuff
(``We'', ``Our''). We operate from the University of Somewhere.
\end{enumerate}
\section{Our Products}
\begin{enumerate}
\item All Products shown on our site are subject to availability.
\item You may only purchase our products if you are at least
18 years old.
\end{enumerate}
\section{Refunds}
\begin{enumerate}
\item You are entitled to a refund unless:
\begin{enumerate}
\item you have eaten the mind-controlling cookies;
\item you have thrown the exploding chocolates;
\item you have used the ray gun as:
\begin{enumerate}
\item a table chock;
\item a weapon unless:
\begin{enumerate}
\item \label{permit}you have a ray gun permit;
\item you are an extraterrestrial.
\end{enumerate}
\end{enumerate}
\end{enumerate}
\end{enumerate}
↓ Input
I’ve labelled one of the items using \label, so I can reference it using:
See clause~\ref{permit}. Input
which produces:
Delving Deeper
If your document is complicated enough to require deeper levels than the default
maximum of four, it’s possible to extend the maximum enumerate depth. In order
to do this, it’s necessary to:
1. Modify the enumerate environment to allow more levels. This may addi-
tionally require modifying the underlying generic list environment that
only allows a maximum of six nested list environments.
6.5 Typesetting Legal Documents (Numbered Paragraphs) 176
2. Define a new enum⟨n⟩ counter (using \newcounter) for each level ⟨n⟩,
where ⟨n⟩ is the lower case Roman numeral representing the level index.
(For example, enumv for the fifth level).
3. Define a new \labelenum⟨n⟩ command for the item label for each level
⟨n⟩.
4. Define a new \leftmargin⟨n⟩ length (using \newlength and \setlength)
for the left margin for each level ⟨n⟩.
5. Define a new \@list⟨n⟩ command that sets up the margin for each level
⟨n⟩.
The counters and label commands are the easy part. For example, to allow
a maximum of six levels, counters and label commands need to be defined for
levels 5 (v) and 6 (vi):
↑ Input
\newcounter{enumv}[enumiv]
\newcounter{enumvi}[enumv]
\newcommand*{\labelenumv}{\theenumv.}
\newcommand*{\labelenumvi}{\theenumvi.}
↓ Input
(If necessary, you can also redefine the counter prefixes \p@⟨counter⟩.)
The left margin lengths are already provided up to six levels, but supposing
you needed a seventh (vii), this would be done using:
↑ Input
\newlength\leftmarginvii
\setlength{\leftmarginvii}{15pt}
↓ Input
↑ Input
\newcommand*{\@listvii}{%
\setlength{\leftmargin}{\leftmarginvii}%
\setlength{\labelwidth}{\leftmarginvii}%
\addtolength{\labelwidth}{-\labelsep}%
}
↓ Input
\enumerate:
macro:->\ifnum \@enumdepth >\thr@@
\@toodeep
\else
\advance\@enumdepth\@ne
\edef\@enumctr{enum\romannumeral\the\@enumdepth}%
\expandafter\list\csname label\@enumctr\endcsname{%
\usecounter\@enumctr
\def\makelabel##1{\hss\llap{##1}}%
}%
\fi
The key part here is the TEX conditional:
\ifnum \@enumdepth >\thr@@
This tests if the number stored in the \@enumdepth register is greater than
\thr@@ (which is defined in the LATEX kernel to have the value 3). So the new
definition of \enumerate needs to change \thr@@ to one less than the new max-
imum.
Since this code contains internal commands, the new definition should either
be placed in a class or package or, if used in the document, be placed between
\makeatletter and \makeatother. Therefore to set the maximum to six levels:
↑ Input
\makeatletter
\renewcommand*{\enumerate}{%
\ifnum \@enumdepth > 5
\@toodeep
\else
\advance\@enumdepth\@ne
\edef\@enumctr{enum\romannumeral\the\@enumdepth}%
\expandafter\list\csname label\@enumctr\endcsname{%
\usecounter\@enumctr
\def\makelabel##1{\hss\llap{##1}}%
}%
\fi
}
\makeatother
↓ Input
If you really do need more than six levels (although I hope you don’t), you
similarly need to modify \list, which by default tests if \@listdepth is greater
than five.
Exercise 20. Extending the Maximum enumerate Depth
For this exercise, extend the maximum enumerate depth to 6 levels (as described
above), so that you can create the following:
↑ Output
1. Information About Us
1.1. This website is run by the Secret Lab of Experimental Stuff (“We”, “Our”).
We operate from the University of Somewhere.
2. Our Products
2.1. All Products shown on our site are subject to availability.
2.2. You may only purchase our products if you are at least 18 years old.
6.5 Typesetting Legal Documents (Numbered Paragraphs) 178
3. Refunds
3.1. You are entitled to a refund unless:
3.1.1. you have eaten the mind-controlling cookies;
3.1.2. you have thrown the exploding chocolates;
3.1.3. you have used the ray gun as:
3.1.3.1. a table chock;
3.1.3.2. a weapon unless:
3.1.3.2.1. you have a ray gun permit;
3.1.3.2.2. you are an extraterrestrial and:
3.1.3.2.2.1. are not a resident of the planet Earth;
3.1.3.2.2.2. have a licence under Galactic Treaty 1024, unless:
3.1.3.2.2.2.1. you come under Article 24, or
3.1.3.2.2.2.2. you live on Saturn.
↓ Output
The choice of document class is up to you. For example, you can use the article or
scrartcl classes. (If you use scrartcl, the class option numbers=endperiod will display
a full stop after the section numbers.) You can download or view a solution.
The numbering can be dealt with using a counter. For example, I could
define a new counter called, say, para:
\newcounter{para} Input
↑ Input
\newcommand*{\numberedparagraph}{%
\refstepcounter{para}\thepara.\space
}
↓ Input
This command needs to go at the start of each paragraph, but it’s rather tiresome
to do this manually, so \everypar can be used instead. For example (using the
lipsum package [33] to generate dummy text):
↑ Input
\everypar{\numberedparagraph}
\lipsum[1-3]
↓ Input
6.5 Typesetting Legal Documents (Numbered Paragraphs) 179
produces:
↑ Output
1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mau-
ris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec
vehicula augue eu neque. Pellentesque habitant morbi tristique senectus et ne-
tus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra metus
rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus eu tel-
lus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium quis,
viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean faucibus.
Morbi dolor nulla, malesuada eu, pulvinar at, mollis ac, nulla. Curabitur auctor
semper nulla. Donec varius orci eget risus. Duis nibh mi, congue eu, accumsan
eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim rutrum.
2. Nam dui ligula, fringilla a, euismod sodales, sollicitudin vel, wisi. Morbi
auctor lorem non justo. Nam lacus libero, pretium at, lobortis vitae, ultricies et,
tellus. Donec aliquet, tortor sed accumsan bibendum, erat ligula aliquet magna,
vitae ornare odio metus a mi. Morbi ac orci et nisl hendrerit mollis. Suspendisse
ut massa. Cras nec ante. Pellentesque a nulla. Cum sociis natoque penatibus et
magnis dis parturient montes, nascetur ridiculus mus. Aliquam tincidunt urna.
Nulla ullamcorper vestibulum turpis. Pellentesque cursus luctus mauris.
3. Nulla malesuada porttitor diam. Donec felis erat, congue non, volutpat at,
tincidunt tristique, libero. Vivamus viverra fermentum felis. Donec nonummy
pellentesque ante. Phasellus adipiscing semper elit. Proin fermentum massa
ac quam. Sed diam turpis, molestie vitae, placerat a, molestie nec, leo. Mae-
cenas lacinia. Nam ipsum ligula, eleifend at, accumsan nec, suscipit a, ipsum.
Morbi blandit ligula feugiat magna. Nunc eleifend consequat lorem. Sed lacinia
nulla vitae enim. Pellentesque tincidunt purus vel magna. Integer non enim.
Praesent euismod nunc eu purus. Donec bibendum quam in tellus. Nullam
cursus pulvinar lectus. Donec et mi. Nam vulputate metus eu enim. Vestibulum
pellentesque felis eu massa.
↓ Output
general you need to be careful about using page as a master counter, but
B In
in this case it’s not a problem as this new para counter only gets incremented
at the beginning of a paragraph so it doesn’t conflict with TEX’s output routine.
There is, however, a problem: some commands, such as the section com-
mands, use \everypar to reset the paragraph behaviour. So, for example,
a \chapter or \section command will override an earlier use of \everypar. It’s
also unlikely that you’ll want the chapter and section headings to have a para-
graph number. This last issue is easily dealt with by hooking into the sectioning
commands using one of the etoolbox commands described in §2.1.2:
↑ Input
\preto\chapter{\everypar{}}
\preto\section{\everypar{}}
\preto\subsection{\everypar{}}
\preto\subsubsection{\everypar{}}
\preto\paragraph{\everypar{}}
\preto\subparagraph{\everypar{}}
↓ Input
6.5 Typesetting Legal Documents (Numbered Paragraphs) 180
within the definition of the sectioning commands. This command uses \everypar
to suppress the indentation of the first paragraph following the heading, and
within the argument of \everypar there is another \everypar that resets the
paragraph hook back to empty, which ensures that subsequent paragraphs are
indented.
As in the previous section, either the \show command or the texdef script
can be used to show the original definition of \@afterheading. For example, if
I run:
texdef -t latex @afterheading Shell
\@afterheading:
macro:->\@nobreaktrue
\everypar{%
\if@nobreak
\@nobreakfalse
\clubpenalty\@M
\if@afterindent
\else
{\setbox \z@ \lastbox }%
\fi
\else
\clubpenalty\@clubpenalty
\everypar{}%
\fi
}
So \@afterheading can be redefined to use our new \numberedparagraph com-
mand:
↑ Input
\renewcommand{\@afterheading}{%
\@nobreaktrue
\everypar{%
\if@nobreak
\@nobreakfalse
\clubpenalty\@M
\if@afterindent
\else
{\setbox\z@\lastbox}%
\fi
\else
\clubpenalty\@clubpenalty
\everypar{\numberedparagraph}% <- modification
\fi
\numberedparagraph% <- modification
}%
}
↓ Input
Remember that this code uses internal commands, so either use \makeatletter
and \makeatother or place the code in a package or class.
6.5 Typesetting Legal Documents (Numbered Paragraphs) 181
↑ Input
\documentclass{article}
\author{Some One}
\title{Numbered Paragraphs Example}
\begin{document}
\maketitle
\section{Sample Section}
\lipsum[1-4]
\subsection{Sample Subsection}
\lipsum[11-15]
\section{Another Section}
\lipsum[16-30]
\end{document}
↓ Input
182
7.1 The datetime2 Package 183
↑ Input
\documentclass{article}
\usepackage{datetime2}
\begin{document}
This PDF was created on \today.
\end{document}
↓ Input
This produces
This is the default date format. If you want the full date, time and time zone,
you can use
\DTMnow Definition
instead of \today. This will display the date and time in the form
2015-09-08 11:17:58+01:00 Output
Note that XELATEX doesn’t provide the time zone information so you will need to
use PDFLATEX or LuaLATEX if you want this.
If you want to use a regional format, you can specify the region in the
package option. For example:
↑ Input
\documentclass{article}
\usepackage[en-GB]{datetime2}
\begin{document}
This PDF was created on \DTMnow.
\end{document}
↓ Input
This produces:
This PDF was created on 8th September 2015 11:17am BST. Output
If you want to pick up the regional setting from babel you can use the
useregional option:
↑ Input
\documentclass[british]{article}
\usepackage[babel]
\usepackage[useregional]{datetime2}
\begin{document}
This PDF was created on \DTMnow.
\end{document}
↓ Input
\DTMdate{⟨date⟩} Definition
You can save a date and time for later use with:
\DTMsavetimestamp{⟨name⟩}{⟨data⟩} Definition
where ⟨name⟩ is a unique label that identifies this date and time, and ⟨data⟩ is
in the format
⟨YYYY ⟩-⟨MM⟩-⟨DD⟩T⟨hh⟩:⟨mm⟩:⟨ss⟩⟨zone⟩
where ⟨YYYY ⟩ is the year, ⟨MM⟩ is the month number, ⟨DD⟩ is the day of the
month, ⟨hh⟩ is the hour (24), ⟨mm⟩ is the minute value, ⟨ss⟩ is the second value
and ⟨zone⟩ is the time zone, which may be either Z or in the format ⟨TZh⟩:
⟨TZm⟩ where ⟨TZh⟩ is the hour offset and ⟨TZm⟩ is the minute offset. The
argument ⟨data⟩ may also be a control sequence that expands (one level) to the
required format.
Alternatively, you can just save the date with:
\DTMsavedate{⟨name⟩}{⟨date⟩} Definition
where the ⟨date⟩ is in the format ⟨YYYY ⟩-⟨DD⟩-⟨MM⟩ and ⟨name⟩ is again
a label.
A previously saved date and time can be displayed in the current style using:
\DTMuse{⟨name⟩} Definition
In all cases, ⟨name⟩ is the label identifying the date or time stamp.
Example 37. Displaying Dates and Times (datetime2 package)
Here’s an example that uses the en-GB style:
↑ Input
\documentclass{article}
\usepackage[en-GB]{datetime2}
\newcommand*{\DateStamp}{2015-11-28T20:13:04Z}
\DTMsavetimestamp{mydate}{\DateStamp}
\DTMsavetimestamp{mydate2}{2014-06-01T09:01:58+01:00}
\begin{document}
Now: \DTMnow.
\end{document}
↓ Input
This produces
7.2 The pgfcalendar Package Utility Commands 185
↑ Output
Now: 8th September 2015 11:25am BST.
Saved: 28th November 2015 8:13pm GMT; 1st June 2014 9:01am BST.
↓ Output
careful if you are using babel with the shorthands on as this may change
B Be
the category codes of characters such as : and - which will cause the date
or time parsing in commands like \DTMsavetimestamp to fail. You may need
to temporarily switch off the shorthands. See the babel manual [7] for further
details.
↑ Input
\usepackage{pgfkeys}
\usepackage{pgfcalendar} ↓ Input
or
\usepackage{pgfkeys,pgfcalendar} Input
In the command definitions below, ⟨date⟩ indicates a date specified using one
of the following formats:
• A specific date:
⟨year⟩-⟨month⟩-⟨day⟩
• The last day of a particular month:
⟨year⟩-⟨month⟩-last
• An increment from a given date:
⟨year⟩-⟨month⟩-⟨day⟩+⟨increment⟩
or
⟨year⟩-⟨month⟩-last+⟨increment⟩
Where ⟨year⟩ is the year (for example, 2014 or \year for the current year);
⟨month⟩ is the month number (for example, 6 for June or \month for the current
month) and ⟨day⟩ is the day number (for example, 21 for the twenty-first of the
month or \day for the current day). The ⟨increment⟩ (in days) may be either
a positive or negative number. If negative the leading + is still required. For
example, 2014-6-last+-4 means four days before the last day of June.
The pgfcalendar provides the commands:
\pgfcalendardatetojulian{⟨date⟩}{⟨register⟩} Definition
This converts a Gregorian date into the Julian day number and stores the result
in ⟨register⟩, which must be a TEX register (not a LATEX counter).
Example:
(Recall \newcount from §2.1.3.)
↑ Input
\newcount\mycount
\pgfcalendardatetojulian{2014-03-18+2}{\mycount}
\the\mycount ↓ Input
7.2 The pgfcalendar Package Utility Commands 186
produces:
2456737 Output
This converts a Julian day number to an ISO-date and stores the resulting year,
month and day-of-month numbers in the control sequences ⟨year cs⟩, ⟨month
cs⟩ and ⟨day cs⟩.
Example:
↑ Input
\pgfcalendarjuliantodate{2456737}{\theyear}{\themonth}{\theday}
\theyear/\themonth/\theday
↓ Input
produces:
2014/03/20 Output
This converts a Julian day number to a week day number, where 0 indicates
Monday, 1 indicates Tuesday, etc. The result is stored in the TEX register speci-
fied by ⟨register⟩.
Example:
↑ Input
\newcount\mycount
\pgfcalendarjuliantoweekday{2456737}{\mycount}
\the\mycount
↓ Input
produces:
3 Output
This tests the given date and does ⟨true code⟩ if the test succeeds otherwise it
does ⟨false code⟩. The ⟨test⟩ may be one of the following key words:
Example:
↑ Input
2014-03-20 is in the
\pgfcalendarifdate{2014-03-20}{at most=06-last}
{first}% test true
{second}% test false
\space half of the year.
↓ Input
produces:
2014-03-20 is in the first half of the year. Output
What happens if your date isn’t in the form ⟨yyyy⟩-⟨m⟩-⟨d⟩? For example, it
might be in the form ⟨m⟩/⟨d⟩/⟨yyyy⟩. Recall from §2.1.1 that the \def primitives
can be used to define a macro that has a custom syntax. It’s therefore possible
to define a command that will parse this syntax and convert it:
\def\parsemdydate#1/#2/#3\endparsemdydate{#3-#1-#2} Input
\newcommand*{\mydate}{3/19/2014} Input
then you first need to expand the macro before it can be parsed by \parsemdydate.
(Recall \expandafter from §2.7.2.)
\expandafter\parsemdydate\mydate\endparsemdydate Input
↑ Input
\documentclass[captions=tableheading]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{pgfkeys,pgfcalendar}
\usepackage{datatool}
\DTLloaddb{people}{people.csv}
\newcount\julianday
\newcount\juliantoday
\newcount\age
\begin{document}
Ages as of \number\year-\number\month-\number\day\ are
listed in Table~\ref{tab:ages}.
\begin{table}[htbp]
\caption{Ages}
\label{tab:ages}
\centering
\begin{tabular}{lc}
\bfseries Name & \bfseries Age%
\DTLforeach*{people}%
{\Forenames=forenames,\Surname=surname,\DoB=dob}%
{%
\\\Forenames\ \Surname &
% Compute the Julian day number for the date of birth
\pgfcalendardatetojulian{\DoB}{\julianday}%
% Compute \age = (\juliantoday - \julianday)/365
\age=\juliantoday
\advance\age by -\julianday
\divide\age by 365
\number\age
}%
\end{tabular}
\end{table}
7.3 Displaying a Date 189
\end{document}
↓ Input
Output
Table 7.1 Ages
Name Age
Polly Parrot 44
Mabel Canary 47
Zöe Zebra 26
José Arara 24
Dickie Duck 62
Fred Canary 48
You can download or view this example. Remember that if your dates are in
a different numerical format, for example, ⟨m⟩/⟨d⟩/⟨yyyy⟩, you need to convert
them as described above. For example, replace
\pgfcalendardatetojulian{\DoB}{\julianday} Input
with
↑ Input
\pgfcalendardatetojulian
{\expandafter\parsemdydate\DoB\endparsemdydate}
{\julianday}
↓ Input
This expands to a textual representation of the day of the week, where the
numbering starts from 0 (Monday).
\pgfcalendarweekdayshortname{⟨week day number⟩} Definition
↑ Input
\documentclass[french,german]{article}
\usepackage{babel}
\usepackage{translator}
\usepackage{pgfkeys,pgfcalendar}
↓ Input
which produces:
30 September 2015 Output
Alternatively, you can define a custom command called, say, \datefmt that
formats any date:
↑ Input
\newcommand*{\datefmt}[3]{%
\number#3~\pgfcalendarmonthname{#2} \number#1%
}
↓ Input
which produces:
31 January 2014 Output
If you want to use an ordinal instead of a plain number for the day of the
month (for example, 1st instead of 1), then you can use TEX’s \ifcase condi-
tional:
\ifcase ⟨number⟩
⟨case 0 code⟩%
\or
⟨case 1 code⟩%
\or
⟨case 2 code⟩% Definition
\or
...
\else
⟨default code⟩%
\fi
This tests ⟨number⟩. If ⟨number⟩ equals 0, ⟨case 0 code⟩ is performed. If
⟨number⟩ equals 1, ⟨case 1 code⟩ is performed. If ⟨number⟩ equals 2, ⟨case 2
code⟩ is performed, etc. If none of the cases match, ⟨default code⟩ is performed.
(The \else ⟨default code⟩ part may be omitted.) Since there are a maximum
of 31 days in a month, 32 cases (including the unnecessary case 0) are needed:
7.3 Displaying a Date 191
↑ Input
\newcommand*{\ord}[1]{%
\number#1%
\ifcase#1\or st\or nd\or rd\or th\or th\or th\or th\or
th\or th\or th\or th\or th\or th\or th\or th\or th\or
th\or th\or th\or th\or st\or nd\or rd\or th\or th\or
th\or th\or th\or th\or th\or st\fi
} ↓ Input
Now
\ord{1} Input
produces:
1st Output
and
\ord{2} Input
produces:
2nd Output
↑ Input
\newcommand*{\datefmt}[3]{%
\ord{#3}~\pgfcalendarmonthname{#2} \number#1%
} ↓ Input
Take care if you use babel as it redefines \today every time the language
B changes (including at the beginning of the document environment). It does
this via the commands \date⟨language⟩ that are invoked when the current
language switches to ⟨language⟩. Each \date⟨language⟩ command redefines
\today to use the format for ⟨language⟩. So if you want to redefine \today
when you are using babel, you need to redefine \date⟨language⟩.
Example:
Suppose I’m using babel with the british option. In this case, the date is reset
using \datebritish so I need to redefine it to use my own format instead:
↑ Input
\renewcommand*{\datebritish}{%
\renewcommand*{\today}{\datefmt{\year}{\month}{\day}}%
} ↓ Input
\printdate{⟨date⟩} Definition
This will display the date in the form: ⟨day name⟩ ⟨day of month number⟩
⟨month name⟩ ⟨year⟩. First, two new count registers need to be defined:
↑ Input
\newcount\julianday
\newcount\dayofweek ↓ Input
↑ Input
\newcommand*{\printdate}[1]{%
\pgfcalendardatetojulian{#1}{\julianday}%
\pgfcalendarjuliantodate{\julianday}{\thisyear}{\thismonth}{\thisday}%
\pgfcalendarjuliantoweekday{\julianday}{\dayofweek}%
% Now display the date:
\datefmt[\dayofweek]{\thisyear}{\thismonth}{\thisday}%
} ↓ Input
The actual date format, including the day of week, is dealt with by a new version
of \datefmt that now has four arguments:
\datefmt[⟨day of week⟩]{⟨yyyy⟩}{⟨m⟩}{⟨d⟩} Definition
↑ Input
\newcommand*{\datefmt}[4][]{%
\ifstrempty{#1}
{}% day of week missing
{%
\pgfcalendarweekdayname{#1}\space
}%
\ord{#4}~\pgfcalendarmonthname{#3} \number#2%
} ↓ Input
This uses etoolbox’s \ifstrempty command to omit the day of week name if
the optional argument is absent. This means that you can still directly use, for
example:
\datefmt{2014}{1}{31} Input
produces:
Saturday 31st May 2014 Output
If you want \today to use the same format, then you can just redefine
\today:
↑ Input
\renewcommand*{\today}{%
\pgfcalendardatetojulian{\year-\month-\day}{\julianday}%
\pgfcalendarjuliantoweekday{\julianday}{\dayofweek}%
\datefmt[\dayofweek]{\year}{\month}{\day}%
} ↓ Input
7.3 Displaying a Date 193
Again, you need to put this in the definition of \date⟨language⟩ if you are using
babel.
You can download or view a complete document.
If this is a format you are likely to use in multiple documents, you might
want to define your own custom package called, say, mycustomdate. This requires
creating a file called mycustomdate.sty, that contains the following:
↑ Input
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mycustomdate}[2014/03/19 1.0 My custom date format]
\RequirePackage{etoolbox}
\RequirePackage{pgfkeys,pgfcalendar}
\endinput
↓ Input
This file should then be saved in your TEXMF path. For example, if you are
using a Unix-like operating system, you can save it in, say, ~/texmf/tex/latex/
mystuff/ (see Volume 1 [93, §A]).
If you’re unfamiliar with writing packages, here’s a brief explanation of the
commands used above:
\NeedsTeXFormat{⟨format⟩}[⟨version⟩] Definition
This should be the first statement of any class or package and is used to identify
the TEX format and, optionally, the version date. For a LATEX 2𝜀 class or package,
the ⟨format⟩ should be LaTeX2e. (Other formats may not define this command.)
The version date, if present, must be in the numeric form ⟨yyyy⟩/⟨mm⟩/⟨dd⟩
(two digits are required for both the month and day numbers).
\ProvidesPackage{⟨name⟩}[⟨version⟩] Definition
This command identifies the package name and optionally a version. The
⟨name⟩ should match the filename (without the extension), so a package called
mycustomdate should be in a file called mycustomdate.sty. The ⟨version⟩ should
start with a numeric date in the form ⟨yyyy⟩/⟨mm⟩/⟨dd⟩ and may optionally be
followed by a version number and a brief description.
\RequirePackage[⟨options⟩]{⟨name⟩}[⟨version⟩] Definition
This is analogous to \usepackage but is for use in a class or package. The final
optional argument ⟨version⟩ indicates that the package must be at least that
version. If an older version is installed a warning is issued.
\endinput Definition
This is a TEX primitives that instructs TEX to stop reading the current file. Any-
thing following this command is skipped. (Some packages have their documen-
tation in the .sty file after \endinput, but this practice has been deprecated in
favour of providing the documentation as a PDF.)
Once you have added mycustomdate.sty to your TEX path, you can now load
this package in your document via
\usepackage{mycustomdate} Input
7.3 Displaying a Date 194
Take care if you need to use babel. If this custom package includes code to rede-
fine \date⟨language⟩ you will need to load babel first (and remember to load the
translator package as well for the month and day of week names). Alternatively,
you can check for the existence of \date⟨language⟩ at the start of the document
environment, and redefine it if it exists:
↑ Input
\AtBeginDocument{%
\ifdef{\datebritish}% check if \datebritish exists
{% it does exist, so redefine it
\renewcommand*{\datebritish}{%
\renewcommand*{\today}{%
\pgfcalendardatetojulian{\year-\month-\day}{\julianday}%
\pgfcalendarjuliantoweekday{\julianday}{\dayofweek}%
\datefmt[\dayofweek]{\year}{\month}{\day}%
}%
}%
\datebritish
}%
{}% doesn't exist, do nothing
}
↓ Input
↑ Input
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mycustomdate}[2014/03/19 1.0 My custom date format]
\RequirePackage{etoolbox}%
\RequirePackage{pgfkeys,pgfcalendar}
\newcommand*{\printdate}[1]{%
\pgfcalendardatetojulian{#1}{\julianday}%
\pgfcalendarjuliantodate{\julianday}{\thisyear}{\thismonth}{\thisday}%
\pgfcalendarjuliantoweekday{\julianday}{\dayofweek}%
% Now display the date:
\datefmt[\dayofweek]{\thisyear}{\thismonth}{\thisday}%
}
\endinput ↓ Input
↑ Input
\documentclass{article}
\usepackage{mycustomdate}
\begin{document}
Today: \today.
Tomorrow: \printdate{\year-\month-\day+1}.
Yesterday: \printdate{\year-\month-\day+-1}.
\end{document} ↓ Input
produces:
D:20150930082715+01’00’ Output
Recall the \parsemdydate command defined in §7.2 used \def to parse a date
string. A similar method can be employed here, but unfortunately it’s more
complicated. At first glance it looks as though we can define a command in the
form:
\def\parsepdfdatetime D:#1\endparsepdfdatetime{⟨code⟩} 8
However if we try this out (ignoring the argument for the time being):
↑ Input
\def\parsepdfdatetime D:#1\endparsepdfdatetime{}
\expandafter\parsepdfdatetime\pdfcreationdate\endparsepdfdatetime
↓ Input
we get an error:
! Use of \parsepdfdatetime doesn't match its definition.
<inserted text> D
:20140319185833Z
l.10 \expandafter\parsepdfdatetime\pdfcreationdate
\endparsepdfdatetime
The problem is the initial D as the following works fine:3
↑ Input
\def\parsepdfdatetime#1:#2\endparsepdfdatetime{}
\expandafter\parsepdfdatetime\pdfcreationdate\endparsepdfdatetime
↓ Input
2 For further details about PDFTEX primitives see the PDFTEX documentation [106].
3 It’s
the category codes of the character “D” in the expansion of \pdfcreationdate that’s the prob-
lem. If it’s first changed to “other” (category codes 12) before defining \parsepdfdatetime then
the error won’t occur.
7.4 Parsing and Displaying Times 197
The first argument (#1) will always be D and can be ignored. Since TEX only
allows a maximum of nine arguments, this leaves eight arguments left, which
can pick up the year (#2#3#4#5), month (#6#7) and day (#8#9) digits. This in-
formation is already available from TEX’s \year, \month and \day primitives,
however PDFTEX provides a similar primitives:
\pdffilemoddate{⟨filename⟩} Definition
that expands to the modification date and time for the file given by ⟨filename⟩,
and this uses the same format, so \parsepdfdatetime should still save the year,
month and day information to be more generally useful.
In order to get around the nine argument maximum \parsepdfdatetime
needs to call another command that will parse the remainder:
↑ Input
\def\parsepdfdatetime#1:#2#3#4#5#6#7#8#9{%
\def\theyear{#2#3#4#5}%
\def\themonth{#6#7}%
\def\theday{#8#9}%
\parsepdftime
} ↓ Input
↑ Input
\def\parsepdftime#1#2#3#4#5#6#7\endparsepdfdatetime{%
\def\thehour{#1#2}%
\def\theminute{#3#4}%
\def\thesecond{#5#6}%
\def\thetimezone{#7}%
} ↓ Input
The hour digits are now given by #1#2, the minute digits are #3#4 the sec-
ond digits are #5#6 and the time zone information is in the final argument #7.
This information has been stored in the new commands \thehour, \theminute,
\thesecond and \thetimezone. If you want \thetimezone to be in the format
⟨sign⟩⟨HH⟩:⟨mm⟩ (where ⟨sign⟩ is either + or -) then replace:
\def\thetimezone{#7}% Input
with
↑ Input
\ifstrequal{#7}{Z}
{%
\def\thetimezone{+00:00}%
}%
{%
\parsepdftimezone#7%
}% ↓ Input
↑ Input
\def\parsepdftimezone#1'#2'{%
\def\thetimezone{#1:#2}%
} ↓ Input
7.4 Parsing and Displaying Times 198
(\ifstrequal is defined by etoolbox and tests if two strings are equal, but unlike
\ifthenelse{\equal{⟨string1⟩}{⟨string2⟩}}{}{}, \ifstrequal doesn’t perform
any expansion on the strings.)
As with the \datefmt command defined in the previous section, we can also
define an analogous command to format the time:
↑ Input
\newcommand*{\timefmt}[4]{%
#1:#2:#3#4%
}
↓ Input
For example:
\timefmt{11}{03}{01}{+01:00} Input
produces:
11:03:01+01:00 Output
↑ Input
\newcommand*{\timefmt}[4]{%
#1:#2%
\ifstrempty{#3}% test for empty 3rd argument
{}% no seconds specified
{:#3}% seconds
\ifstrempty{#4}% test for empty 4th argument
{}% no time zone
{#4}%
}
↓ Input
↑ Input
\newcommand*{\timefmt}[4]{%
#1:#2%
\ifstrempty{#3}% test for empty 3rd argument
{}% no seconds specified
{:#3}% seconds
\timezonefmt{#4}% time zone
}
↓ Input
Since it’s possible that the time zone might not be fully expanded (for example,
the argument might be \thetimezone), the new \timezonefmt first fully expands
its argument before parsing it:
↑ Input
\newcommand*{\timezonefmt}[1]{%
\edef\thistimezone{#1}%
\ifdefempty{\thistimezone}%
{}% empty argument
7.4 Parsing and Displaying Times 199
{%
\expandafter\@timezonefmt\thistimezone\@endtimezonefmt
}%
}
↓ Input
Now the actual parsing is done by a new internal command with the syntax:
\@timezonefmt⟨HH⟩:⟨mm⟩\@endtimezonefmt Definition
Here’s one possible definition of \@timezonefmt that just displays “Z” if both
⟨HH⟩ and ⟨mm⟩ are zero, otherwise it either does just ⟨HH⟩ if ⟨mm⟩ is zero or
it does ⟨HH⟩:⟨mm⟩
↑ Input
\def\@timezonefmt#1:#2\@endtimezonefmt{%
\ifnum#2=0\relax
\ifnum#1=0\relax
Z%
\else
#1%
\fi
\else
#1:#2%
\fi
}
↓ Input
Example:
Since \pdfcreationdate is set at the start of the LATEX run, you only need to
parse it once:
↑ Input
\expandafter\parsepdfdatetime\pdfcreationdate\endparsepdfdatetime
\let\pdfhour\thehour
\let\pdfminute\theminute
\let\pdfsecond\thesecond
\let\pdftimezone\thetimezone
\newcommand*{\pdfnowtime}{%
\timefmt{\pdfhour}{\pdfminute}{\pdfsecond}{\pdftimezone}}
↓ Input
The time stamp for the LATEX run can now be inserted into your document using
this new \pdfnowtime command:
This PDF was created at \pdfnowtime. Input
produces:
This PDF was created at 08:27:15+01. Output
which ensures ⟨number⟩ has at least two digits. Take care when using com-
mands that print numbers, such as \two@digits or \number, as you can unex-
pectedly lose following spaces. It’s for this reason that I’ve occasionally used
\relax or \ (backslash space) in the code below.
7.4 Parsing and Displaying Times 200
↑ Input
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mycustomdatetime}[2014/03/20 1.0 My custom date
and time format]
↓ Input
is defined:
↑ Input
\newcommand*{\timefmt}[4]{%
\two@digits{#1}:\two@digits{#2}%
\ifstrempty{#3}% test for empty 3rd argument
{}% no seconds specified
{:\two@digits{#3}}% seconds
\timezonefmt{#4}% time zone
\relax
}
↓ Input
is defined:
↑ Input
\newcommand*{\timezonefmt}[1]{%
\edef\thistimezone{#1}%
\ifdefempty{\thistimezone}%
{}% empty argument
{%
\expandafter\@timezonefmt\thistimezone\@endtimezonefmt
}%
}
↓ Input
↑ Input
\def\@timezonefmt#1:#2\@endtimezonefmt{%
\ifnum#2=0\relax
\ifnum#1=0\relax
Z%
\else
#1%
\fi
\else
#1:#2%
\fi
}
↓ Input
7.4 Parsing and Displaying Times 201
If you want to use \two@digits in the time zone, you need to be careful with
the plus or minus sign:
↑ Input
\def\@timezonefmt#1:#2\@endtimezonefmt{%
\ifnum #2=0\relax
\ifnum #1=0\relax
Z%
\else
\ifnum #1<0 $-$\two@digits{-#1}\else +\two@digits{#1}\fi
\fi
\else
\ifnum #1<0 $-$\two@digits{-#1}\else +\two@digits{#1}\fi
:\two@digits{#2}%
\fi
}
↓ Input
(The minus sign has been placed in math-mode using $-$ to ensure it’s displayed
as a real minus sign rather than as a hyphen. If for some reason you need to use
\timefmt in math-mode, I suggest you put it in inside the argument of amsmath’s
\text command [1].)
Now for the commands that can parse the PDF date format:
↑ Input
\def\parsepdfdatetime#1:#2#3#4#5#6#7#8#9{%
\def\theyear{#2#3#4#5}%
\def\themonth{#6#7}%
\def\theday{#8#9}%
\parsepdftime
}
\def\parsepdftime#1#2#3#4#5#6#7\endparsepdfdatetime{%
\def\thehour{#1#2}%
\def\theminute{#3#4}%
\def\thesecond{#5#6}%
\ifstrequal{#7}{Z}
{%
\def\thetimezone{+00:00}%
}%
{%
\parsepdftimezone#7%
}%
}
\def\parsepdftimezone#1'#2'{%
\def\thetimezone{#1:#2}%
}
↓ Input
↑ Input
\expandafter\parsepdfdatetime\pdfcreationdate\endparsepdfdatetime
\let\pdfhour\thehour
\let\pdfminute\theminute
\let\pdfsecond\thesecond
\let\pdftimezone\thetimezone
7.4 Parsing and Displaying Times 202
\newcommand*{\pdfnowtime}{%
\timefmt{\pdfhour}{\pdfminute}{\pdfsecond}{\pdftimezone}}
↓ Input
↑ Input
\newcommand*{\pdfnow}{%
\year-\two@digits{\month}-\two@digits{\day}\space
\pdfnowtime
}
↓ Input
↑ Input
\newcommand*{\filedate}[1]{%
\expandafter\parsepdfdatetime\pdffilemoddate{#1}\endparsepdfdatetime
\datefmt{\theyear{\themonth}{\theday}\space
\timefmt{\thehour}{\theminute}{\thesecond}{\thetimezone}}%
}
↓ Input
↑ Input
\newcommand*{\filedate}[1]{%
\expandafter\parsepdfdatetime\pdffilemoddate{#1}\endparsepdfdatetime
\printdate{\theyear-\themonth-\theday}\
\timefmt{\thehour}{\theminute}{\thesecond}{\thetimezone}%
}
↓ Input
↑ Input
\newcommand*{\filedate}[1]{%
\expandafter\parsepdfdatetime\pdffilemoddate{#1}\endparsepdfdatetime
\theyear-\two@digits{\themonth}-\two@digits\theday\
\timefmt{\thehour}{\theminute}{\thesecond}{\thetimezone}%
}
↓ Input
The rest of the package code is as described in Example 40, including the
definitions of \datefmt and \printdate. (You can download the complete pack-
age.) Here’s an example document that uses this new package:
7.4 Parsing and Displaying Times 203
↑ Input
\documentclass{article}
\usepackage{mycustomdatetime}
\begin{document}
\end{document}
↓ Input
Example usage:
↑ Input
\printdatetime{2014-03-25 01:23:15+00:00}
\printdatetime{2014-03-24 23:31:58+01:00}
\printdatetime{2014-03-24 16:28:56-06:00}
\printdatetime{2014-03-24 14:45:23+08:00}
\printdatetime{2014-03-25 03:12:04-04:30}
\printdatetime{2014-03-24 03:45:24-04:30}
\printdatetime{2014-03-24 21:20:24+05:45}
↓ Input
7.5 Displaying a Calendar 204
This is a loop macro that iterates from ⟨start date⟩ to ⟨end date⟩ and performs
⟨code⟩ at each iteration. Within ⟨code⟩ you can access information about the
current iteration using:
• \pgfcalendarcurrentjulian This is a TEX count register that holds the
Julian day number for the current iteration;
\let\%\pgfcalendarshorthand Input
before \pgfcalendar so that you can simply write, for example, \%wt in-
stead of:
\pgfcalendarshorthand{w}{t} Input
but make sure you localise the effect of the \let by placing it inside
a group or environment so that the normal behaviour of \% is restored
after the calendar has been typeset.
Examples:
1. To just display the day of the month from 2014-02-26 to 2014-03-15:
\pgfcalendar{}{2014-02-26}{2014-03-15}{%
\pgfcalendarcurrentday\ } Input
produces:
26 27 28 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 Output
↑ Input
produces:
↑ Output
Sat 1 March 2014
Sun 2 March 2014
Mon 3 March 2014
Tue 4 March 2014
↓ Output
The tikz package (part of the pgf bundle) provides a powerful and user-friendly
way of drawing images. An in-depth discussion of the tikz package is beyond
the scope of this book, but here’s a very brief introduction to drawing nodes in
a tikzpicture environment to help draw a simple calendar. For more detail about
tikz, see the pgf user manual [102].
Within the tikzpicture environment, you can use
7.5 Displaying a Calendar 206
The full syntax is more complicated, but the (⟨node name⟩) is optional, as are
the key=value lists ⟨path options⟩ and ⟨node options⟩. (Spaces before and after
the commas and equal signs are ignored.) The full syntax of (⟨position⟩) is also
quite complicated, but here I’ll just use the (⟨x⟩,⟨y⟩) syntax.
Example:
(Don’t forget to load the tikz package.)
↑ Input
\fbox{%
\begin{tikzpicture}
\path (0,0) node {Mon};
\path (1,0) node {Tue};
\path (2,0) node {Wed};
\path (3,0) node {Thu};
\path (4,0) node {Fri};
\path (5,0) node {Sat};
\path (6,0) node {Sun};
\end{tikzpicture}%
}
↓ Input
I’ve used the \fbox command (described in Volume 1 [93, §4.7.1]) to put a border
around the picture. Fancier borders can be created using tikz commands within
the tikzpicture environment.
The above code produces:
It’s possible to add a \pgfcalendar command to this environment and put the
node drawing part in the ⟨code⟩ argument. Since \pgfcalendarcurrentweekday
is an integer from 0 (Monday) to 6 (Sunday), it can be used for the ⟨x⟩ coordinate.
Since tikz uses a right-handed co-ordinate system, the row below the ⟨y⟩ = 0
weekday name row displayed above needs to be negative. For example:
↑ Input
\fbox{%
\begin{tikzpicture}
% First row
\path (0,0) node {Mon};
\path (1,0) node {Tue};
\path (2,0) node {Wed};
\path (3,0) node {Thu};
\path (4,0) node {Fri};
\path (5,0) node {Sat};
\path (6,0) node {Sun};
% Second row
\pgfcalendar{}{2014-03-01}{2014-03-02}{
\path (\pgfcalendarcurrentweekday,-1)
node {\pgfcalendarcurrentday};
}
\end{tikzpicture}%
}
↓ Input
7.5 Displaying a Calendar 207
This produces:
01 02
↑ Input
01 02
03 04 05 06 07 08 09
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Nodes can have a border and background. These can be specified in the
[⟨node options⟩]. For example:
\path (0,0) node[rectangle,draw] {Mon}; Input
↑ Input
Instead of repeatedly using the same options it’s possible to set them within
a local scope using the scope environment:
↑ Input
Output
01 02
03 04 05 06 07 08 09
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
\pgfcalendar{}{2014-03-01}{2014-03-31}{
% Draw node for current day
\path (\pgfcalendarcurrentweekday,-\rowcount)
node[rectangle,draw] {\pgfcalendarcurrentday};
% Increment row count if today is a Sunday:
\ifdate{Sunday}{\advance\rowcount by 1}{}
}
\end{tikzpicture}%
}
↓ Input
This produces the image shown in Figure 7.2. The nodes in the first row
look a little uneven as the sizes vary according to the node contents. To neaten
things up a bit, a minimum size can be imposed on the nodes:
↑ Input
}
\end{tikzpicture}%
}
↓ Input
01 02
03 04 05 06 07 08 09
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
However now the nodes are bumping into each other, so they need to be
moved apart. The default ⟨x⟩ and ⟨y⟩ coordinate units are 1 cm. This can be
changed in the optional argument of the tikzpicture environment. For example:
↑ Input
Output
01 02
03 04 05 06 07 08 09
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Figure 7.4 Calendar Using Circular and Rectangular Nodes (March 2014)
where ⟨name⟩ is the library name. For example, there are some multi-part
shapes defined in the shapes.multipart library. In order to use these shapes,
you not only need
\usepackage{tikz} Input
Example:
A rectangular split node with 2 splits can be created using:
↑ Input
\begin{tikzpicture}
\path (0,0)
node[rectangle split,rectangle split parts=2,draw]
{%
Top
\nodepart{two}
Bottom
};
\end{tikzpicture}
↓ Input
The \nodepart{⟨part⟩} command moves from the current split part to the split
part identified by ⟨part⟩. In the case of a rectangular split node, the second part
is identified by the keyword two. The above code produces:
7.5 Displaying a Calendar 212
Top
Output
Bottom
With a vertical split node, such as in the above example, you can set a min-
imum width using the minimum width key, but you can’t specify a minimum
height. You can, however, specify a height for empty parts using the option
rectangle split empty part height=⟨length⟩. For example:
↑ Input
\begin{tikzpicture}
\path (0,0)
node
[
rectangle split,
rectangle split parts=2,
rectangle split empty part height=1cm,
minimum width=2cm,
draw
]
{%
Top
\nodepart{two}
% empty bottom part
};
\end{tikzpicture}
↓ Input
This produces:
Top
Output
You can specify fill colours for each part using the rectangle split part
fill={⟨colour list⟩} option, where ⟨colour list⟩ is a comma-separated list of
colours for each part, in order. For example:
↑ Input
\begin{tikzpicture}
\path (0,0)
node
[
rectangle split,
rectangle split parts=2,
rectangle split empty part height=1cm,
rectangle split part fill={cyan,magenta},
minimum width=2cm,
draw
]
{%
Top
\nodepart{two}
% empty bottom part
};
\end{tikzpicture}
↓ Input
7.5 Displaying a Calendar 213
This produces:
Top
Output
Since tikz loads the xcolor package [41], you can specify colours using the xcolor
syntax. For example:
↑ Input
\begin{tikzpicture}
\path (0,0)
node
[
rectangle split,
rectangle split parts=2,
rectangle split empty part height=1cm,
rectangle split part fill={cyan!20,magenta!5},
minimum width=2cm,
draw
]
{%
Top
\nodepart{two}
% empty bottom part
};
\end{tikzpicture}
↓ Input
This produces:
Top
Output
Now the fill colour for the top part is 20% cyan tint and the fill colour for the
bottom part is 5% magenta tint. This isn’t a great colour scheme, but it’s just
used for illustrative purposes.
Example 42. Calendar for May 2014
The above can be put together to create a calendar for the month of May 2014:
↑ Input
\newcount\rowcount
\rowcount=1\relax
\fbox{%
\let\%\pgfcalendarshorthand
\begin{tikzpicture}[x=1.5cm,y=1.75cm]
\begin{scope}
[every node/.style={rectangle,fill=green!5,minimum width=1.4cm}]
\path (0,0) node {Mon};
\path (1,0) node {Tue};
\path (2,0) node {Wed};
\path (3,0) node {Thu};
\path (4,0) node {Fri};
\path (5,0) node {Sat};
\path (6,0) node {Sun};
7.5 Displaying a Calendar 214
\end{scope}
\pgfcalendar{}{2014-05-01}{2014-05-31}
{
\path (\pgfcalendarcurrentweekday,-\rowcount)
node
[
rectangle split,
minimum width=1.4cm,
rectangle split empty part height=1cm,
rectangle split parts=2,
rectangle split part fill={cyan!20,magenta!4},
draw]
{\%d-
\nodepart{two}
};
\ifdate{Sunday}{\advance\rowcount by 1}{}
}
\end{tikzpicture}%
}
↓ Input
Suppose now I want to add some information to the calendar. For example,
the two May bank holidays on the 5th and 26th of May. Additionally, suppose
I also want a different colour background for weekends and bank holidays, for
example, a light grey. The bank holiday information can be stored in control se-
quences whose names are in the format ⟨prefix⟩-⟨YYYY ⟩-⟨MM⟩-⟨DD⟩, which
is the format used by \pgfcalendarsuggestedname. Recall etoolbox’s \csdef com-
mand described in §2.1.1. This can be used to define these control sequences:
7.5 Displaying a Calendar 215
↑ Input
The \pgfcalendar command now needs cal as the ⟨prefix⟩ so that in the ⟨code⟩
part, the current day can be checked if it’s a bank holiday using:
↑ Input
\ifcsdef{\pgfcalendarsuggestedname}%
{%
% Current day is a~bank holiday
}%
{%
% Current day isn't a~bank holiday
}
↓ Input
↑ Input
\fbox{%
\rowcount=1\relax
\let\%\pgfcalendarshorthand
\begin{tikzpicture}[x=1.5cm,y=1.75cm]
\begin{scope}
[every node/.style={rectangle,fill=green!5,minimum width=1.4cm}]
\path (0,0) node {Mon};
\path (1,0) node {Tue};
\path (2,0) node {Wed};
\path (3,0) node {Thu};
\path (4,0) node {Fri};
\path (5,0) node {Sat};
\path (6,0) node {Sun};
\end{scope}
\pgfcalendar{cal}{2014-05-01}{2014-05-31}{%
\def\thebackground{magenta!4}%
\ifcsdef{\pgfcalendarsuggestedname}%
{%
\def\thecontents{\csuse{\pgfcalendarsuggestedname}}%
\def\thebackground{black!4}%
}%
{%
\def\thecontents{\mbox{}}%
\ifdate{weekend}{\def\thebackground{black!4}}{}%
}%
\path (\pgfcalendarcurrentweekday,-\rowcount)
node
[
rectangle split,
rectangle split parts=2,
rectangle split part fill={cyan!20,\thebackground},
draw]
{\%d-
7.5 Displaying a Calendar 216
\nodepart{two}%
\parbox[t][1cm]{1.2cm}{\small\thecontents}%
};
\ifdate{Sunday}{\advance\rowcount by 1}{}%
}%
\end{tikzpicture}%
}
↓ Input
Suppose now you want to fill in the gaps at the beginning and end of the
month. Recall the \foreach command mentioned in §2.7.2. This has the syntax:
\foreach ⟨variables⟩ [⟨options⟩] in {⟨list⟩}{⟨body⟩} Definition
but it’s cleverer than the other list macros described in that section as you can
use ... within ⟨list⟩ if the list contents can be inferred from the beginning and
end of the list. For example:
\foreach \x in {1,...,10} {\x\space} Input
produces
1 2 3 4 5 6 7 8 9 10 Output
Therefore, within the ⟨code⟩ part of \pgfcalendar, you can test if the current
day is the first day of the month (by testing that \pgfcalendarcurrentday is equal
to 1) and use \foreach to fill in the last days of the previous month:
↑ Input
\ifnum\pgfcalendarcurrentday=1\relax
% Fill in days from previous month if this isn't a Monday
\ifdate{Monday}{}
7.5 Displaying a Calendar 217
The tikz package automatically loads the pgffor package, so the \foreach com-
mand will also be available if you use tikz. Note that \foreach uses a local scope
for each iteration which is why \global is required when incrementing the
\julianday register. The gap at the end of the final week can also be filled with
the initial days of the next month, but as with \foreach, \pgfcalendar scopes
each iteration, so the row register \rowcount will need to be incremented glob-
ally so that it can be used after the loop has completed. It’s also useful to store
the Julian day number and the week day number for the last day of the month
so they can be accessed outside the loop. This saves the need to compute them
again. So the last part of ⟨code⟩ needs to replace:
\ifdate{Sunday}{\advance\rowcount by 1}{}% Input
with
↑ Input
\ifdate{Sunday}{\global\advance\rowcount by 1}{}%
\xdef\lastjulianday{\number\pgfcalendarcurrentjulian}
\xdef\lastweekday{\number\pgfcalendarcurrentweekday}
↓ Input
Now the remaining days of the last row can be completed outside the \pgfcalendar
loop:
↑ Input
[
rectangle split,
rectangle split parts=2,
draw]
{\number\theday
\nodepart{two}
\parbox[t]{1cm}{1.2cm}{\mbox{}}%
};
}
\fi
↓ Input
Note that you can also use \foreach to display the week day nodes:
↑ Input
\foreach \x in {0,...,6}
{\path (\x,0) node {\pgfcalendarweekdayshortname{\x}};}
↓ Input
↑ Input
\newcount\rowcount
\newcount\julianday
\fbox{%
\rowcount=1\relax
\let\%\pgfcalendarshorthand
\begin{tikzpicture}[x=1.5cm,y=1.75cm]
\begin{scope}
[every node/.style={rectangle,fill=green!5,minimum width=1.4cm}]
\foreach \x in {0,...,6}
{\path (\x,0) node {\pgfcalendarweekdayshortname{\x}};}
\end{scope}
\pgfcalendar{cal}{2014-05-01}{2014-05-31}
{% Is this the first day of the month?
\ifnum\pgfcalendarcurrentday=1\relax
% Fill in days from previous month if this isn't a Monday
\ifdate{Monday}{}
{% Get last day of previous month
\julianday = \pgfcalendarcurrentjulian\relax
\advance\julianday by -\pgfcalendarcurrentweekday\relax
\foreach \x in {0,...,\numexpr\pgfcalendarcurrentweekday-1}
{
\pgfcalendarjuliantodate{\julianday}{\theyear}{\themonth}{\theday}
\path (\x,-1)
node
[rectangle split,
rectangle split parts=2,
draw]
{\number\theday
\nodepart{two}
\parbox[t][1cm]{1.2cm}{\mbox{}}%
};
\global\advance\julianday by 1\relax
}
}
\fi
\def\thebackground{magenta!4}%
\ifcsdef{\pgfcalendarsuggestedname}%
7.5 Displaying a Calendar 219
{%
\def\thecontents{\csuse{\pgfcalendarsuggestedname}}%
\def\thebackground{black!4}%
}%
{%
\def\thecontents{\mbox{}}%
\ifdate{weekend}{\def\thebackground{black!4}}{}%
}%
\path (\pgfcalendarcurrentweekday,-\rowcount)
node
[rectangle split,
rectangle split parts=2,
rectangle split part fill={cyan!20,\thebackground},
draw]
{\%d-
\nodepart{two}%
\parbox[t][1cm]{1.2cm}{\small\thecontents}%
};
\ifdate{Sunday}{\global\advance\rowcount by 1}{}%
\xdef\lastjulianday{\number\pgfcalendarcurrentjulian}
\xdef\lastweekday{\number\pgfcalendarcurrentweekday}
}%
\ifnum\lastweekday < 6\relax
\julianday = \lastjulianday\relax
\edef\lastweekday{\number\numexpr\lastweekday+1}
\foreach \x in {\lastweekday,...,6}
{
\global\advance\julianday by 1\relax
\pgfcalendarjuliantodate{\julianday}{\theyear}{\themonth}{\theday}
\path (\x,-\rowcount)
node
[rectangle split,
rectangle split parts=2,
draw]
{\number\theday
\nodepart{two}
\parbox[t]{1cm}{1.2cm}{\mbox{}}%
};
}
\fi
\end{tikzpicture}%
}
↓ Input
The result is shown in Figure 7.7. You can download or view a complete
document.
It’s possible to create a general month calendar macro from the above. First
a command that can be used to set information for a given date. This uses
\appto so that information can be appended to a date.
↑ Input
\newcommand*{\addevent}[2]{%
\ifcsdef{cal-#1}
{% already defined so append info
\csappto{cal-#1}{\newline #2}%
}%
{% not defined
7.5 Displaying a Calendar 220
Output
Figure 7.7 May 2014 with Bank Holidays (including end of previous month and
beginning of next month)
\csdef{cal-#1}{#2}%
}
}
↓ Input
↑ Input
\newcommand*{\calendarmonth}[2]{%
\fbox{%
\rowcount=1\relax
\let\%\pgfcalendarshorthand
\begin{tikzpicture}[x=1.5cm,y=1.75cm]
% display the month name at the top
\path (3,1) node {\pgfcalendarmonthname{#2}};
\begin{scope}
[every node/.style={rectangle,fill=green!5,minimum width=1.4cm}]
\foreach \x in {0,...,6}
{\path (\x,0) node {\pgfcalendarweekdayshortname{\x}};}
\end{scope}
\pgfcalendar{cal}{#1-#2-01}{#1-#2-last}
{%
% Is this the first day of the month?
\ifnum\pgfcalendarcurrentday=1\relax
% Fill in days from previous month if this isn't a Monday
\ifdate{Monday}{}
7.5 Displaying a Calendar 221
{
% Get last day of previous month
\julianday = \pgfcalendarcurrentjulian\relax
\advance\julianday by -\pgfcalendarcurrentweekday\relax
\foreach \x in {0,...,\numexpr\pgfcalendarcurrentweekday-1}
{
\pgfcalendarjuliantodate
{\julianday}{\theyear}{\themonth}{\theday}
\path (\x,-1)
node
[
rectangle split,
rectangle split parts=2,
draw]
{\number\theday
\nodepart{two}
\parbox[t][1cm]{1.2cm}{\mbox{}}%
};
\global\advance\julianday by 1\relax
}
}
\fi
\def\thebackground{magenta!4}%
\ifcsdef{\pgfcalendarsuggestedname}%
{%
\def\thecontents{\csuse{\pgfcalendarsuggestedname}}%
\def\thebackground{black!4}%
}%
{%
\def\thecontents{\mbox{}}%
\ifdate{weekend}{\def\thebackground{black!4}}{}%
}%
\path (\pgfcalendarcurrentweekday,-\rowcount)
node
[
rectangle split,
rectangle split parts=2,
rectangle split part fill={cyan!20,\thebackground},
draw]
{\%d-
\nodepart{two}%
\parbox[t][1cm]{1.2cm}{\small\thecontents}%
};
\ifdate{Sunday}{\global\advance\rowcount by 1}{}%
\xdef\lastjulianday{\number\pgfcalendarcurrentjulian}
\xdef\lastweekday{\number\pgfcalendarcurrentweekday}
}%
\ifnum\lastweekday < 6\relax
\julianday = \lastjulianday\relax
\edef\lastweekday{\number\numexpr\lastweekday+1}
\foreach \x in {\lastweekday,...,6}
{
\global\advance\julianday by 1\relax
\pgfcalendarjuliantodate{\julianday}{\theyear}{\themonth}{\theday}
\path (\x,-\rowcount)
node
[
rectangle split,
7.5 Displaying a Calendar 222
↑ Input
\newcount\rowcount
\newcount\julianday
↓ Input
↑ Input
\documentclass{beamer}
\begin{document}
\begin{frame}
\maketitle
\end{frame}
\end{document}
↓ Input
The beamer class provides an optional argument to \title, \author and \date
that isn’t available with standard classes, such as article. The optional argument
can be used to supply an abbreviated version which may be used in headlines
or footlines. There are additional title page commands:
\subtitle[⟨short title⟩]{⟨title⟩} Definition
This specifies graphics for the title page. Typically, ⟨graphic⟩ is code to load an
image file.
\institute[⟨short name⟩]{⟨name⟩} Definition
This specifies the author’s affiliation. If there are multiple authors from different
institutes, the institutes should be separated by \and (in a similar manner to
\author). Additionally, when there are multiple institutes, each institute should
be prefixed by
\inst{⟨text⟩} Definition
This command should also be placed after the corresponding name (or names)
in the argument of \author with matching ⟨text⟩.
223
Chapter 8. Presentations (The beamer Class) 224
Example:
↑ Input
\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\begin{document}
\begin{frame}
\maketitle
\end{frame}
\end{document}
↓ Input
This uses the sample dummy-logo.png file available from the examples page.
The resulting slide is shown in Figure 8.1. The footline (bottom right of the
slide) provides navigation links.
Within the frame environment you can use:
\frametitle{⟨title⟩} Definition
↑ Input
\begin{frame}
\frametitle{Mind-Controlling Cookies}
\framesubtitle{Ingredients}
\begin{itemize}
\item Self-raising flour;
\item Butter;
\item Chocolate chips;
\item Sugar obtained from secret genetically modified beet.
\end{itemize}
\end{frame}
↓ Input
Mind-Controlling Cookies
Ingredients
I Self-raising flour;
I Butter;
I Chocolate chips;
I Sugar obtained from secret genetically modified beet.
↑ Input
\begin{frame}[fragile]
\frametitle{Hello World!}
\begin{verbatim}
#!/usr/bin/perl
print "Hello World!\n";
1;
\end{verbatim}
\end{frame} ↓ Input
↑ Input
\begin{frame}
\tableofcontents
\end{frame}
\section{Experimental Research}
\subsection{Cookies}
\begin{frame}
\frametitle{Mind-Controlling Cookies}
\framesubtitle{Ingredients}
\begin{itemize}
\item Self-raising flour;
\item Butter;
\item Chocolate chips;
\item Sugar obtained from secret genetically modified beet.
\end{itemize}
\end{frame} ↓ Input
Areas of a frame can be divided into titled blocks using the block environ-
ment.
\begin{block}{⟨title⟩} Definition
Example:
↑ Input
\begin{frame}
\frametitle{Mind-Controlling Cookies}
\framesubtitle{Recipe}
\begin{block}{Ingredients}
\begin{itemize}
\item Self-raising flour;
\item Butter;
\item Chocolate chips;
\item Sugar obtained from secret genetically modified beet.
\end{itemize}
\end{block}
\end{frame} ↓ Input
8.1 Overlays 227
If ⟨proof name⟩ is present, it’s used instead of “Proof” as the block title.
8.1 Overlays
Overlays allow you to uncover parts of a slide. For example, to uncover the
items in the above itemize environment:
↑ Input
\begin{frame}
\frametitle{Mind-Controlling Cookies}
\framesubtitle{Recipe}
\begin{block}{Ingredients}
\begin{itemize}[<+->]
\item Self-raising flour;
\item Butter;
\item Chocolate chips;
\item Sugar obtained from secret genetically modified beet.
\end{itemize}
\end{block}
\end{frame}
↓ Input
This creates five slides. The first just has one item (Figure 8.5), the second has
two items (Figure 8.6), etc.
This completely hides the text until it’s uncovered. If you prefer to show the
text faintly before it’s uncovered, you can use:
\setbeamercovered{transparent} Input
This mixes 85% of the background colour with 15% of the text colour. Note that
the effect varies according to the display device. Now the first slide of:
↑ Input
\begin{frame}
\frametitle{Mind-Controlling Cookies}
\framesubtitle{Recipe}
\begin{block}{Ingredients}
\begin{itemize}[<+->]
\item Self-raising flour;
\item Butter;
\item Chocolate chips;
\item Sugar obtained from secret genetically modified beet.
\end{itemize}
\end{block}
\end{frame}
↓ Input
Hello World!
#!/usr/bin/perl
print "Hello World!\n";
1;
Mind-Controlling Cookies
Recipe
Ingredients
I Self-raising flour;
I Butter;
I Chocolate chips;
I Sugar obtained from secret genetically modified beet.
Mind-Controlling Cookies
Recipe
Ingredients
◮ Self-raising flour;
Mind-Controlling Cookies
Recipe
Ingredients
◮ Self-raising flour;
◮ Butter;
Mind-Controlling Cookies
Recipe
Ingredients
◮ Self-raising flour;
◮ Butter;
◮ Chocolate chips;
◮ Sugar obtained from secret genetically modified beet.
Example:
↑ Input
\begin{frame}
\frametitle{Mind-Controlling Cookies}
\framesubtitle{Recipe}
\begin{block}{Ingredients}
\begin{itemize}
\item<1-> Self-raising flour;
\item<2-> Butter;
\item<1-> Chocolate chips;
\item<2-> Sugar obtained from secret genetically modified beet.
\end{itemize}
\end{block}
\end{frame}
↓ Input
This shows the first and third items on the first slide and all items on the second
slide. You can similarly apply overlays to beamer environments, such as block, or
to standard environments, such as enumerate:
↑ Input
\begin{frame}
\frametitle{Mind-Controlling Cookies}
\framesubtitle{Recipe}
\begin{block}{Ingredients}
\begin{enumerate}[<+->]
\item Self-raising flour;
\item Butter;
\item Chocolate chips;
8.2 Themes 231
8.2 Themes
The appearance of the slides is governed by themes. There are five types of
theme:
1. Presentation
A presentation theme governs the whole appearance of the presentation.
A presentation theme is chosen with:
\usetheme[⟨options⟩]{⟨name⟩} Definition
2. Color
A color theme governs the presentation’s colour scheme. A color theme
is chosen with:
\usecolortheme[⟨options⟩]{⟨name⟩} Definition
3. Font
A font theme governs the presentation’s fonts or font attributes. A font
theme is chosen with:
\usefonttheme[⟨options⟩]{⟨name⟩} Definition
4. Inner
An inner theme governs the appearance of elements that are considered
“inside” a frame. (For example, the appearance of theorems or list items.)
An inner theme is chosen with:
\useinnertheme[⟨options⟩]{⟨name⟩} Definition
5. Outer
An outer theme governs the appearance of elements outside a frame.
(For example, the headlines or footlines or whether there is a sidebar.)
An outer theme is chosen with:
\useoutertheme[⟨options⟩]{⟨name⟩} Definition
The examples above used the default presentation theme. There are a large
number of themes to choose from. The rest of this section shows a selection
of these themes. The selection is partly influenced by my own preferences, but
partly by how well they appear in grey scale for the printed version of this book.
8.2 Themes 232
↑ Input
\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usetheme{Boadilla}
\begin{document}
\begin{frame}
\maketitle
\end{frame}
\end{document}
\section{Experimental Research}
\subsection{Cookies}
\begin{frame}
\frametitle{Mind-Controlling Cookies}
\framesubtitle{Recipe}
\begin{block}{Ingredients}
\begin{itemize}
\item Self-raising flour;
\item Butter;
\item Chocolate chips;
\item Sugar obtained from secret genetically modified beet.
\end{itemize}
\end{block}
\end{frame}
↓ Input
This document uses the Boadilla presentation theme. The resulting slides are
shown in Figures 8.8 and 8.9. This theme puts the author names, affiliations,
title and date in the footline. You can download or view this document.
is changed to
\usetheme{EastLansing} Input
then the resulting slides have a green colour scheme with a headline (shown in
Figures 8.10 and 8.11).
8.2 Themes 233
↑ Input
\usetheme{Goettingen}
\useinnertheme[shadow]{rounded}
\usecolortheme{spruce}
↓ Input
Mind-Controlling Cookies
Recipe
Ingredients
◮ Self-raising flour;
◮ Butter;
◮ Chocolate chips;
◮ Sugar obtained from secret genetically modified beet.
Culinary
Experimental
Research
Experimental
Research
Cookies
Ingredients
◮ Self-raising flour;
◮ Butter;
◮ Chocolate chips;
◮ Sugar obtained from secret genetically modified beet.
Culinary
Experimental
Research
Figure 8.16 Goettingen Presentation Theme with rounded Inner Theme and
spruce Color Theme (Title Slide)
Experimental
Research
Cookies
Ingredients
Self-raising flour;
Butter;
Chocolate chips;
Sugar obtained from secret genetically modified beet.
Figure 8.17 Goettingen Presentation Theme with rounded Inner Theme and
spruce Color Theme
Chapter 9
Assignments and Examinations
There are a number of classes or packages available on CTAN to help typeset
assignment sheets or exam papers (see the exam topic).
The exam class (version 2.4, 2011-05-22) is comprehensive with its own list-
like environments for enumerating questions and their parts, as well as environ-
ments for multiple choice questions. It also provides the possibility of assigning
points to each question (or question part), creating solution sheets and grading
tables. The exam class is described in §9.1, but take care as there is also an
exam class provided by the exams bundle. The exam class described in this book
is the one by Philip S. Hirschhorn and is in both the TEX Live and MiKTEX
distributions. The exams bundle isn’t in either of those distributions.
The exsheets package (version 0.17, 2014-10-15) also provides a means to cre-
ate questions and their solutions. Unlike the exam class, the exsheets package
allows you to divide the questions into classes and they can be printed selec-
tively. Meta-data can also be assigned to the questions. The solutions may be
either printed with their question or collected and printed together at a later
point in the document. However, the package doesn’t support multiple choice
style of questions (although you can use a package such as paralist to create inline
numbered lists). The exsheets package is described in §9.2.
The probsoln package (version 3.04, 2012-08-23) provides a way to define prob-
lems and their solutions in a file (or multiple files). You can load all problems,
a specific list of problems or a random selection. You may have one or more
problem datasets and either print the solutions with the questions or print the
solutions later on in the document. The probsoln package provides an inline
numbered list environment. The probsoln package is described in §9.3.
The datatool package used in earlier chapters can also be used to store ques-
tions and their solutions. The datatooltk application can import the dataset files
used by probsoln. You can add extra fields to specify, for example, the difficulty
level or subject. §9.4 describes how you can use datatool to create a database of
exam or assignment questions and their solutions.
Note that it’s possible to use the exam class with either the probsoln package
or the datatool package, but it can’t be used with the exsheets package.
B This chapter assumes that all your files are stored in a secure location that
can’t be accessed by curious students. If your operating system supports
owner-only file permissions, I suggest you set them as appropriate (for example
chmod 600), but don’t rely on that as your only security measure (see also §2.3).
239
9.1 The exam Class 240
In addition to the addpoints class option, you can also switch this mode on
and off using the commands:
\addpoints Definition
↑ Input
\begin{center}
\fbox{\parbox{5.5in}{\centering
Answer the questions in the spaces provided on the
question sheets. If you run out of room for an answer,
continue on the back of the page.%
}}
\end{center}
\vspace{0.1in}
\vspace{0.2in}
\makebox[\textwidth]{Instructor's name:\enspace\hrulefill}
↓ Input
(Although you may prefer to use a fraction of \textwidth instead of the hard-
coded 5.5in.)
9.1 The exam Class 241
Example:
↑ Input
\documentclass[addpoints]{exam}
\begin{document}
\begin{center}
\fbox{\parbox{0.8\textwidth}{\centering
Answer the questions in the spaces provided on the
question sheets. If you run out of room for an answer,
continue on the back of the page.%
}}
\end{center}
\vspace{0.1in}
\vspace{0.2in}
\noindent\makebox[\textwidth]{Instructor's name:\enspace\hrulefill}
\begin{questions}
\question[3\half] What ingredients can be found in
mind-controlling cookies?
This produces:
↑ Output
Instructor’s name:
1. (31/2 points) What ingredients can be found in mind-controlling cookies?
2. (21/2 points) What are the health benefits of exploding chocolates?
↓ Output
\part[⟨points⟩] Definition
Note that outside of the parts environment this command behaves as the standard
\part sectioning command.
Sub-parts should be enclosed in the subparts environment:
\begin{subparts}
⟨question sub-parts⟩ Definition
\end{subparts}
where each sub-part is started with
\subpart[⟨points⟩] Definition
As with \question, the optional argument indicates the number of points the
part is worth, and should only contain digits or \half if the addpoints option is
on.
Example:
↑ Input
\begin{questions}
\question Find the derivatives with respect to $x$ of the following
functions:
\begin{parts}
\part[\half] $y = x + 1$
\part[1] $y = x^3 + 4x^2 - x + 3$
\part[1\half] $y = \cos(x^2)$
\end{parts}
\end{questions}
↓ Input
↑ Output
If you want to specify questions worth bonus points you can use
\bonusquestion Definition
instead of \question,
\bonustitledquestion Definition
instead of \titledquestion,
\bonuspart Definition
instead of \part,
9.1 The exam Class 243
\bonussubpart Definition
instead of \subsubpart.
The default location of the points is after the question (or part) number. This
can be changed to the margin using the declaration
\pointsinmargin Definition
which puts the points in the right margin. If you prefer to place the points
elsewhere, use the declaration
\pointsdroppedatright Definition
at the end of the paragraph where you want the points displayed. If you use
\pointsdroppedatright but don’t use \droppoints the points won’t be displayed.
Note that \droppoints should only occur at the end of a paragraph or between
paragraphs.
The number of questions, parts, sub-parts and sub-sub-parts can be refer-
enced with the commands:
\numquestions Definition
For example:
↑ Input
With the addpoints option, you can also display a grading table using:
\gradetable[⟨orientation⟩][⟨index type⟩] Definition
If you want to centre the grading table, you can place it in the center environ-
ment, which will add extra vertical space at the start and end as well as centre
its contents. (It’s unlikely that you’ll want the grading table in a floating environ-
ment as it typically appears in a fixed location.) The grading table is placed in
a tabular environment, so it can’t break across a page.
Any cover page material can be place in the coverpages environment.
\begin{coverpages}
⟨text⟩ Definition
\end{coverpages}
The cover pages use Roman numeral page numbers. The page counter is reset
at the end of the environment. This environment must not contain the questions
environment.
There are four environments for typesetting the solutions. The default be-
haviour is for the solutions to be hidden. To display the solutions, use the
answers class option. Each environment takes an optional argument, which is
the amount of space to be left for the students to write in their solution. If the
optional argument is omitted, all four environments simply ignore their contents
when the answers option hasn’t been set.
\begin{solution}[⟨length⟩]
⟨solution text⟩ Definition
\end{solution}
If the solutions are hidden, this environment inserts ⟨length⟩ amount of blank
space (as though you had used \vspace*{⟨length⟩}).
\begin{solutionorbox}[⟨length⟩]
⟨solution text⟩ Definition
\end{solutionorbox}
The solutionorbox environment is similar to the solution environment, but inserts
an empty box of height ⟨length⟩ if the answers should be hidden.
\begin{solutionorlines}[⟨length⟩]
⟨solution text⟩ Definition
\end{solutionorlines}
The solutionorlines environment is similar to the solution environment, but inserts
an area of height ⟨length⟩ with ruled lines if the answers should be hidden.
\begin{solutionordottedlines}[⟨length⟩]
⟨solution text⟩ Definition
\end{solutionordottedlines}
The solutionordottedlines environment is similar to solutionorlines but uses dotted
lines.
Example:
↑ Input
\begin{questions}
\question Find the derivatives with respect to $x$ of the following
functions:
\begin{parts}
\part[\half] $y = x + 1$
\begin{solution}
$y' = 1$
\end{solution}
\begin{solution}
9.1 The exam Class 245
$y' = 3x^2 + 8x - 1$
\end{solution}
\part[1\half] $y = \cos(x^2)$
\begin{solution}
$y' = -2x\sin(x^)$
\end{solution}
\end{parts}
\end{questions}
↓ Input
There are four environments provided for multiple choice questions. The
first two label the choices and the other two print checkboxes in front of the
choices for the student to tick. With these environments use:
\choice Definition
instead of \choice.
\begin{choices}
⟨list items⟩ Definition
\end{choices}
The choices environment is a list environment with labelled choices as the items
in the list.
\begin{oneparchoices}
⟨list items⟩ Definition
\end{oneparchoices}
The oneparchoices is an in-line list of labelled choices where there are no para-
graph breaks unless explicitly inserted.
\begin{checkboxes}
⟨list items⟩ Definition
\end{checkboxes}
The checkboxes environment is a list environment with checkbox choices as the
items in the list.
\begin{oneparcheckboxes}
⟨list items⟩ Definition
\end{oneparcheckboxes}
The oneparcheckboxes is an in-line list of checkbox choices where there are no
paragraph breaks unless explicitly inserted.
Example:
↑ Input
\begin{questions}
\question[1] Which of the following ingredients are used in
mind-controlling cookies:
\begin{choices}
\choice arsenic
\choice cyanide
\choice curare
\CorrectChoice secret genetically modified sugar beet
\end{choices}
\end{questions}
↓ Input
9.2 The exsheets Package 246
This produces:
↑ Output
For more details about the exam class, including commands and options not
mentioned here, see the exam class user guide [36].
Exercise 24. Creating an Exam Paper with the exam Class
Create an examination paper containing the questions (and solutions) in the
above examples and add a grading table. Try experimenting with adding and
removing the answers class option and try the variations of the solution environ-
ment (such as solutionorbox).
The exam class user guide [36] describes ways of adjusting the default settings.
Try adding the command \unframedsolutions to the preamble and see how it
changes the way the solutions are displayed or add \bracketedpoints to see
how it affects the way the points are displayed. You can download or view
a solution.
where the options listed in ⟨option list⟩ belong to the given module. If ⟨module⟩
is omitted, the module name is incorporated into the option list. For example,
you can either do:
\SetupExSheets[question]{⟨option⟩=⟨value⟩} Input
or
\SetupExSheets{question/⟨option⟩=⟨value⟩} Input
where ⟨option⟩ is some option defined for the question module and ⟨value⟩ is
the value being assigned to that option. There are a lot of options related to
the formatting of counters, question headings and subtitles, as well as options
related to the table of contents.
Questions are written inside the question environment.
\begin{question}[⟨options⟩]{⟨points⟩}
⟨question text⟩ Definition
\end{question}
9.2 The exsheets Package 247
Note that the ⟨points⟩ argument is optional, despite the lack of square brackets.
The other optional argument, ⟨options⟩, is the list of options. If ⟨points⟩ is
omitted, no points will be associated with the question. The ⟨points⟩ may be in
the form ⟨p⟩ or ⟨p⟩+⟨b⟩ or +⟨b⟩, where ⟨p⟩ is the number of points and ⟨b⟩ is
the number of bonus points.
Examples:
A question with no points allocated:
↑ Input
\begin{question}
How many kilocalories are there in 100 grammes of exploding
chocolate?
\end{question}
↓ Input
↑ Input
\begin{question}{5}
How many kilocalories are there in 100 grammes of exploding
chocolate?
\end{question}
↓ Input
↑ Input
\begin{question}{5+1}
How many kilocalories are there in 100 grammes of exploding
chocolate?
\end{question}
↓ Input
The points for each question are added to the total marks. If you don’t want
the points added for a particular question, you need to put an exclamation mark
! before the points. (This prevents bonus points for the question.)
Example:
A question worth five points where the points aren’t added to the running total:
↑ Input
\begin{question}{!5}
How many kilocalories are there in 100 grammes of exploding
chocolate?
\end{question}
↓ Input
There are a number of ⟨key⟩=⟨value⟩ options available for the question envi-
ronment. For a complete list, see the exsheets documentation [62], but here are
a few:
type=⟨value⟩ Determines the type of question. The value may be either
exam or exercise. In the first case, the question number is
preceded by “Question”, in the second case by “Exercise”.
name=⟨name⟩ Replaces the default “Exercise” or “Question” to ⟨name⟩.
subtitle=⟨title⟩ Adds a subtitle.
class=⟨class⟩ Assigns a class to the question.
9.2 The exsheets Package 248
↑ Input
\begin{question}
What is the main drawback of ray guns?
\end{question}
\begin{solution}
Overheating.
\end{solution}
↓ Input
By default, the question will appear but the solution won’t be displayed. The
default result is:
↑ Output
Exercise 1.
What is the main drawback of ray guns?
↓ Output
If you want the solutions to appear where they are defined (that is, after their
associated question), you can just add the following:
\SetupExSheets[solution]{print=true} Input
or
\SetupExSheets{solution/print=true} Input
However, if you want the solutions to appear later (for example, at the end of
the document) you can use
\printsolutions[⟨settings⟩] Definition
at the place where you want the solutions. Note that this command must only
be used after all the solutions have been defined. The optional argument is
a key=value list. Options include:
chapter If no value is specified, all solutions to the questions defined in the
current chapter are listed. If a value is specified, it may be a comma-
separated list or range of chapter numbers. For example, chapter=
{1-7,10} means chapters one to seven and chapter ten. Remember
to use braces around the value if it contains commas.
section Analogous to the chapter option, but for sections. As above, the value
may be omitted, in which case the current section is assumed, or may
be a comma-separated list or range of values.
9.2 The exsheets Package 249
byID The value should be a comma-separated list of IDs identifying the ques-
tions whose solutions should be printed. (Recall the ID option that can
be used when you define a question.)
indicates to only use those questions that have been assigned to one of the
classes: easy, medium or hard. Any questions that haven’t been assigned to one
of those classes will be discarded.
Similarly, questions can be assigned to a topic using the topic key in the
optional argument of the question environment. The option use-topics is anal-
ogous to use-classes. There are other commands that allow you to assign
properties to questions, but for brevity these are omitted here.
As with the exam class, you can also access the total points and, as before,
you need at least two LATEX runs to get an up-to-date value.
\pointsum Definition
Prints the total number of points (excluding bonus points). This command also
has a starred version that omits the “unit”, which is “P.” by default.
\bonussum Definition
Prints the total number of bonus points. As with the previous command, this
command also has a starred version that omits the unit.
\totalpoints Definition
Prints the total number of points (including bonus points). This command also
has a starred version that omits the unit.
To typeset a number of points without adding it to the cumulative total use:
\points{⟨number⟩} Definition
where ⟨number⟩ is the number of points. As above, this command has a starred
version that omits the unit.
There are some other related commands described in the exsheets man-
ual [62], but for brevity aren’t covered here. The “unit” can be changed via
the name and name-plural keys in the points module. Recall from earlier, that
the option can be set using:
\SetupExSheets[points]{name={point},name-plural={points}} Input
or
\SetupExSheets{points/name={point},points/name-plural={points}} Input
There are also options for the bonus point unit: bonus-name and bonus-plural.
For example:
↑ Input
\SetupExSheets[points]{bonus-name={bonus point},
bonus-plural={bonus points}}
↓ Input
9.2 The exsheets Package 250
There are some other options related to the formatting of the points. See the
exsheets manual for further details.
There is no provision for multiple choice questions, however you can use
the inparaenum environment provided by the paralist package [78].
\begin{inparaenum}[⟨format⟩]
⟨list items⟩ Definition
\end{inparaenum}
This is analogous to the enumerate environment except that each item doesn’t start
a new paragraph (unless you explicitly insert a paragraph break). The optional
argument determines the counter format. The tokens A, a, I, i and 1 indicate the
counter formats \Alph, \alph, \Roman, \roman and \arabic. (The paralist package
also modifies the enumerate environment so that it takes an optional argument
that changes the counter format in the same manner.)
Example:
↑ Input
\begin{question}
Which of the following ingredients are used in
mind-controlling cookies:
\begin{inparaenum}[(A)]
\item arsenic
\item cyanide
\item curare
\item\label{correct-ingredient} secret genetically modified
sugar beet
\end{inparaenum}
\end{question}
\begin{solution}
Correct choice: \ref{correct-ingredient}.
\end{solution}
↓ Input
You can put all your question and solution environments in an external file to
form a databank. These solutions, either all or a subset, can then be included
using:
\includequestions[⟨options⟩]{⟨filenames⟩} Definition
random The value should be a number, ⟨n⟩, indicating that ⟨n⟩ questions should
be randomly selected.
exclude Exclude any questions whose ID is contained in this list. Again, since
the value contains commas, remember to enclose the list with braces.
This option can be combined with the random option.
In addition to the answers and noanswers options, you can also show or
suppress solutions using
\showanswers Definition
(to hide the solutions). These are declarations that can be scoped by placing
them within a group.
You can check if the show solutions setting is on or off by testing the
showanswers boolean flag. This can be done using:
9.3 The probsoln Package 252
or you can use the \ifthenelse command provided by the ifthen package:
\ifthenelse{\boolean{showanswers}}{⟨true part⟩}{⟨false part⟩} Definition
or you can use the \ifbool command provided by the etoolbox package:
\ifbool{showanswers}{⟨true part⟩}{⟨false part⟩} Definition
For example:
Assignment 1\ifbool{showanswers}{ (Solution Sheet)}{} Input
↑ Input
\begin{onlyproblem}
What is the main drawback of ray guns?
\end{onlyproblem}
\begin{onlysolution}
Overheating.
\end{onlysolution}
↓ Input
If the solutions are displayed, only the solution (“Overheating.”) will be typeset,
otherwise only the question (“What is the main drawback of ray guns?”) will be
typeset.
Note that spaces at the start of the environment are discarded but spaces at
the end of the environment aren’t. So the EOL character immediately before
“What” is discarded (and similarly for the EOL character immediately before
“Overheating”) but the EOL character after the question mark is interpreted
as a space (and similarly for the EOL character after the full stop in the solu-
tion). If these spaces are unwanted, you can suppress them with the % comment
character:
↑ Input
\begin{onlyproblem}
What is the main drawback of ray guns?%
\end{onlyproblem}%
\begin{onlysolution}
Overheating.%
\end{onlysolution}
↓ Input
↑ Input
What is the main drawback of ray guns?
\begin{onlysolution}
Overheating.%
\end{onlysolution}
↓ Input
You may prefer to put the solution inside the solution environment:
\begin{solution}⟨text⟩\end{solution} Definition
↑ Input
What is the main drawback of ray guns?
\begin{onlysolution}
\begin{solution}
Overheating.
\end{solution}
\end{onlysolution}
↓ Input
This uses the same counter and label as the enumerate environment would use
at the current level. For example, if the textenum environment was used outside
the enumerate environment, the enumi counter will be used with \labelenumi, but
if textenum was used inside a single enumerate environment, the enumii will be used
with \labelenumii.
As with the standard list environments, each item is started with \item but
no paragraph break is inserted unless you explicitly add one (either via a blank
line or \par). You can also use
\correctitem Definition
item marker, and the default behaviour of \incorrectitem is to just display the
marker (as per \item). You can change this by redefining
\correctitemformat{⟨marker⟩} Definition
↑ Input
\documentclass[addpoints]{exam}
\usepackage{probsoln}
\showanswers
\renewenvironment{solution}%
{\par\noindent\textbf{\solutionname}: \ignorespaces}%
{\ignorespacesafterend}
\renewcommand*{\theenumi}{\Alph{enumi}}
\begin{document}
\begin{center}\bfseries
Assignment~1\ifshowanswers\space (Solution Sheet)\fi
\end{center}
\begin{questions}
\question[1] What is the main drawback of ray guns?
\begin{onlysolution}
\begin{solution}
Overheating.
\end{solution}
\end{onlysolution}
\end{tabular}
\end{textenum}
\end{center}
\end{questions}
\end{document}
↓ Input
↑ Output
A. arsenic B. cyanide
C. curare D. secret genetically modified sugar beet
↓ Output
Thus far I haven’t shown you anything that the exam class can’t already do,
so let’s now look at how to define problems and their associated solutions for
later use. A problem can be defined using the defproblem environment
\begin{defproblem}[⟨n⟩][⟨default args⟩]{⟨label⟩}[⟨option⟩]
⟨text⟩ Definition
\end{defproblem}
where ⟨text⟩ may include the onlyproblem or onlysolution environments (or a com-
bination of both). The first optional argument ⟨n⟩ is the number of arguments
this problem may take. Each argument may be referenced in ⟨text⟩ using the
standard #1 etc method of referencing an argument. The second optional argu-
ment ⟨default args⟩ are the default arguments to use with this problem when it
is automatically used by \thisproblem, described below. (The default argument
is ignored when the problem is referenced with \useproblem, which must have
the arguments explicitly added.)
If ⟨n⟩ is omitted, 0 is assumed and ⟨default args⟩ should also be omitted. The
final optional argument ⟨option⟩ may be used to specify the fragile boolean key
described earlier. If ⟨text⟩ contains any instances of the onlyproblem or onlysolution
environments, they will inherit the fragile state from defproblem.
The only mandatory argument is ⟨label⟩, which is a label that uniquely identi-
fies this problem so that it can later be referenced. As with all the other labelling
systems described in this book, the label must not contain any
.special characters
The problem must be defined before use, typically either in the preamble
or in an external .tex file.
Example:
Here’s a simple example that doesn’t require any arguments:
↑ Input
\begin{defproblem}{raygun}
\begin{onlyproblem}
What is the main drawback of ray guns?%
9.3 The probsoln Package 256
\end{onlyproblem}%
\begin{onlysolution}
Overheating.%
\end{onlysolution}
\end{defproblem}
↓ Input
↑ Input
\begin{defproblem}[1][{2}]{diffsin}
\begin{onlyproblem}
Differentiate $f(x) = \sin(#1x)$.
\end{onlyproblem}%
\begin{onlysolution}
$f'(x) = #1\cos(#1x)$
\end{onlysolution}
\end{defproblem}
↓ Input
In both of the above examples, I’m assuming that the solutions will be printed
later in the document, separate from the question, so I haven’t bothered to use
the solution environment, since the “Solution:” tag is now redundant. If, on the
other hand, I want a solution sheet that displays the solution with its associated
question, then it’s better to remove the onlyproblem environment and add the
solution environment inside the onlysolution environment:
↑ Input
\begin{defproblem}{raygun}
What is the main drawback of ray guns?
\begin{onlysolution}
\begin{solution}
Overheating.%
\end{solution}
\end{onlysolution}
\end{defproblem}
↓ Input
Since it’s quite cumbersome having to write so many \begin and \end com-
mands, the probsoln package provides a convenient shortcut command:
\newproblem[⟨n⟩][⟨default args⟩]{⟨label⟩}{⟨problem⟩}{⟨solution⟩} Definition
↑ Input
\begin{defproblem}[⟨n⟩][⟨default args⟩]{⟨label⟩}%
⟨problem⟩%
\begin{onlysolution}%
\begin{solution}%
⟨solution⟩%
\end{solution}%
\end{onlysolution}%
\end{defproblem}
↓ Input
9.3 The probsoln Package 257
↑ Input
\begin{defproblem}[⟨n⟩][⟨default args⟩]{⟨label⟩}%
⟨problem⟩%
\end{defproblem}
↓ Input
Note that both versions of \newproblem don’t support verbatim, so if your prob-
lem contains verbatim text you must use the defproblem environment (with the
fragile key set).
Once you have defined your problems, you can the use them in your docu-
ment. You can explicitly use a particular problem via the command:
\useproblem[⟨dataset⟩]{⟨label⟩}{⟨arg1 ⟩}...{⟨arg𝑁 ⟩} Definition
where ⟨label⟩ is the label uniquely identifying the problem. If the problem
was defined to have arguments, the arguments must then follow the label. The
optional argument ⟨dataset⟩ indicates the dataset in which the problem is stored.
If omitted the default dataset is assumed.
Example:
Given the definitions in the earlier example of the problems with the labels
raygun and diffsin, these can now be used in the document:
↑ Input
\begin{enumerate}
\item \useproblem{raygun}
\item \useproblem{diffsin}{3}
\end{enumerate}
↓ Input
This is on the assumption that the problems were defined in the document
preamble, which will automatically place them in the default dataset. Since the
diffsin problem was defined to have one argument, that argument has to be
provided.
If you define all your problems in external files, you can input each file
using LATEX’s standard \input command, which will have the same effect as just
defining all those problems within the document. Alternatively, you can load
the problems into a particular dataset using one of the commands described
below, where ⟨dataset⟩ is the name of the dataset and ⟨filename⟩ is the name
of the file. If the dataset is omitted, the default dataset is assumed. Note that the
dataset name mustn’t contain any special characters.
\loadallproblems[⟨dataset⟩]{⟨filename⟩} Definition
This loads all the problems defined in the given ⟨filename⟩ and adds them to
the ⟨dataset⟩ indicated in the optional argument.
\loadselectedproblems[⟨dataset⟩]{⟨labels⟩}{⟨filename⟩} Definition
This only defines the problems listed in the comma-separated list ⟨labels⟩. The
other problems in ⟨filename⟩ are ignored.
\loadexceptproblems[⟨dataset⟩]{⟨exception list⟩}{⟨filename⟩} Definition
\loadrandomproblems[⟨dataset⟩]{⟨n⟩}{⟨filename⟩} Definition
This loads ⟨n⟩ randomly selected problems defined in ⟨filename⟩ and adds them
to the given dataset.
\loadrandomexcept[⟨dataset⟩]{⟨n⟩}{⟨filename⟩}{⟨exception list⟩} Definition
Similar to the previous command but discounts the problems listed in ⟨exception
list⟩ when making the random selection.
Once you have loaded your problems, using one of the above commands,
you can iterate through a dataset using:
\foreachproblem[⟨dataset⟩]{⟨body⟩} Definition
This does ⟨body⟩ at each iteration. Within ⟨body⟩ you can use
\thisproblem Definition
to access the current problem label. Unlike \useproblem, you don’t supply the
problem arguments when you use \thisproblem. If the problem requires one
or more arguments and no default arguments were provided when the problem
was defined or the usedefaultargs package option wasn’t used, then you will
be prompted for the arguments, which requires LATEX to be run in interactive
mode. (Interactive mode is when LATEX stops on encountering an error and
prompts you for a response.)
Example:
To iterate through all problems in the default dataset:
↑ Input
\begin{enumerate}
\foreachproblem{\item\thisproblem}
\end{enumerate}
↓ Input
Assuming that you haven’t switched on the solutions using \showanswers or the
answers package option, this will just list all the problems. If you switch on the
solutions, this will include the solutions but omit any text inside the onlyproblem
environment.
There is also a similar command:
\foreachsolution[⟨dataset⟩]{⟨body⟩} Definition
which behaves like \foreachproblem but only iterates over those problems that
contain an onlysolution environment. (You must have first used the problems
earlier in the document.) Note that you still need to switch on the show solution
flag using \showanswers or the answers package option if you want the solutions
displayed.
\foreachdataset{⟨cs⟩}{⟨body⟩} Definition
This iterates over all the defined datasets and does ⟨body⟩ at each iteration.
Within ⟨body⟩ you can use the control sequence ⟨cs⟩ to access the current
dataset name.
For example, to display all problems in all datasets:
9.3 The probsoln Package 259
↑ Input
\begin{enumerate}
\foreachdataset{\thisdataset}%
{%
\foreachproblem[\thisdataset]{\item\thisproblem}%
}
\end{enumerate}
↓ Input
Example:
Suppose I have some calculus problems defined in a file called calculus.tex and
I have some linear algebra problems defined in a file called linearalgebra.tex,
then in my document preamble I could, say, load five randomly selected calculus
problems and four randomly selected linear algebra problems using:
↑ Input
\loadrandomproblems[calculusproblems]{calculus}
\loadrandomproblems[linearalgebraproblems]{linearalgebra}
↓ Input
(The .tex extension may be omitted.) This creates two datasets with the labels
calculusproblems and linearalgebraproblems. In my document, I could simply
iterate over all datasets using \foreachdataset as described above.
↑ Input
\begin{enumerate}
\foreachdataset{\thisdataset}%
{%
\foreachproblem[\thisdataset]{\item\thisproblem}%
}
\end{enumerate}
↓ Input
Alternatively, I might want to divide the document into sections for each
topic:
↑ Input
\section{Calculus}
\begin{enumerate}
\foreachproblem[calculusproblems]{\item\thisproblem}
\end{enumerate}
\section{Linear Algebra}
\begin{enumerate}
\foreachproblem[linearalgebraproblems]{\item\thisproblem}
\end{enumerate}
↓ Input
The seed used by the pseudo random number generator can be changed
using:
\PSNrandseed{⟨n⟩} Definition
where ⟨n⟩ is a non-zero number to use as the seed. Random numbers can be
generated using:
9.3 The probsoln Package 260
\PSNrandom{⟨register⟩}{⟨n⟩} Definition
which generates a random integer between 1 and ⟨n⟩ (inclusive) and stores it
in the given count register (see §2.1.3) or
\random{⟨counter⟩}{⟨min⟩}{⟨max⟩} Definition
which generates a random integer between ⟨min⟩ and ⟨max⟩ (inclusive) and
stores it in the LATEX counter whose name is ⟨counter⟩. (See also §9.5 below.)
Example:
Recall the earlier diffsin problem. Suppose that instead of defining the prob-
lem to have an argument for the factor, the factor is randomly selected instead.
First a new register needs to be defined:
\newcount\myrandarg Input
↑ Input
\begin{defproblem}{randdiffsin}
\PSNrandom{\myrandarg}{10}%
Differentiate $f(x) = \sin(\the\myrandarg x)$.
\begin{onlysolution}
$f'(x) = \the\myrandarg\cos(\the\myrandarg x)$
\end{onlysolution}
\end{defproblem}
↓ Input
then this problem will appear differently if the same document is rebuilt on
different years.
B If(foryouexample,
want the solutions to appear in a different location to the questions
at the end of the document) you’ll need to store the randomly
generated number to prevent a different number from being generated in the
solution section. For example:
↑ Input
\begin{defproblem}{randdiffsin}
\ifundef\randdiffsinarg
{%
\PSNrandom{\myrandarg}{10}%
\xdef\randdiffsinarg{\the\myrandarg}% globally store
}
{}%
Differentiate $f(x) = \sin(\randdiffsinarg x)$.
\begin{onlysolution}
$f'(x) = \randdiffsinarg\cos(\randdiffsinarg x)$
\end{onlysolution}
\end{defproblem}
↓ Input
This performs ⟨body⟩ at each iteration where ⟨cs⟩ is a control sequence set to
the currently selected item.
9.3 The probsoln Package 261
Example:
Suppose you have four files called file1.tex, file2.tex, file3.tex and file4.
tex that all contain problem definitions, but you only want to load the problems
defined in two of those files selected at random:
↑ Input
\doforrandN
{2}% randomly select 2 items from the list
{\thisfile}% command in which to store the current item
{file1,file2,file3,file4}% the list
{\loadallproblems{\thisfile}}
↓ Input
Example:
In this example, only one random selection is made and the selected item is
saved for later use:
↑ Input
\doforrandN{1}{\thisitem}{cow,duck,chicken}
{\global\let\thesubject\thisitem}%
\doforrandN{1}{\thisitem}{road,field,river}
{\global\let\theobject\thisitem}%
Why did the \thesubject\ cross the \theobject?
\begin{onlysolution}
\begin{solution}
So that the \thesubject\ could get to the other side of the \theobject.
\end{solution}
\end{onlysolution}
↓ Input
The previous warning also applies here if you intend to display the solutions
in another part of the document. In this case, a similar approach can be used:
↑ Input
\begin{defproblem}{whycross}
\ifdef{\thesubject}
{}% already defined
{%
\doforrandN{1}{\thisitem}{cow,duck,chicken}
{\global\let\thesubject\thisitem}%
\doforrandN{1}{\thisitem}{road,field,river}
{\global\let\theobject\thisitem}%
}%
\begin{onlyproblem}
Why did the \thesubject\ cross the \theobject?
\end{onlyproblem}
\begin{onlysolution}
So that the \thesubject\ could get to the other side of the \theobject.
\end{onlysolution}
\end{defproblem}
↓ Input
This uses the \ifdef command provided by the etoolbox package described in
§2.1.1.
Note that the pgfmath package also provides pseudo-random commands, which
you may prefer to use. Some of these are described in §9.5.
9.3 The probsoln Package 262
↑ Input
\begin{defproblem}{diff:sinx/x}
\begin{onlyproblem}%
$y = \frac{\sin x}{x}$.
\end{onlyproblem}
\begin{onlysolution}%
\[\frac{dy}{dx} = \frac{\cos x}{x} - \frac{\sin x}{x^2}\]
\end{onlysolution}%
\end{defproblem}
↓ Input
↑ Input
\begin{defproblem}{dfp:cons}%
\begin{onlyproblem}%
Differentiate from first principles $f(x) = c$ where $c$ is
a constant.%
\end{onlyproblem}%
\begin{onlysolution}%
\begin{align*}
\frac{df}{dx} & = \lim_{\Delta x\rightarrow 0}\frac{c-c}\Delta x\\
& = \lim_{\Delta x\rightarrow 0}0\\
& = 0
\end{align*}%
\end{onlysolution}%
\end{defproblem}
↓ Input
↑ Input
\documentclass{article}
\usepackage{amsmath}
\usepackage{probsoln}
\loadrandomproblems{3}{mth101}
\loadrandomproblems{1}{problems-1stprinciples}
\begin{document}
\section{Differentiation Problems}
9.4 Using the datatool Package for Exams or Assignment Sheets 263
\begin{enumerate}
\foreachproblem{\item\thisproblem}
\end{enumerate}
\section{Solutions}
\showanswers
\begin{enumerate}
\foreachsolution{\item\thisproblem}
\end{enumerate}
\end{document}
↓ Input
defined by the etoolbox package, where ⟨name⟩ is the name of the variable. (Note
that ⟨name⟩ is not a control sequence.) The state can be set using:
\setboolean{⟨name⟩}{⟨state⟩} Definition
\setbool{⟨name⟩}{⟨state⟩} Definition
defined by the etoolbox package, where ⟨state⟩ may be either true or false.
With the etoolbox package, you can also use:
\boolfalse{⟨name⟩} Definition
↑ Input
\documentclass{article}
\usepackage{etoolbox}
\usepackage{datatool}
\newbool{showanswers}
\booltrue{showanswers}
\DTLloaddbtex{\problemDB}{mth101.dbtex}
\begin{document}
\begin{center}\bfseries\Large
Assignment~1\ifbool{showanswers}{ (Solution Sheet)}{}
\end{center}
\begin{enumerate}
\DTLforeach*{\problemDB}
{\Label=Label,\Question=Question,\Answer=Answer}%
{%
\item \Question
\ifbool{showanswers}{\par\textbf{Solution: }\Answer}{}%
}
\end{enumerate}
\end{document}
↓ Input
↑ Input
\documentclass{article}
\usepackage{etoolbox}
\usepackage{datatool}
\newbool{showanswers}
\booltrue{showanswers}
\DTLloaddbtex{\problemDB}{mth101.dbtex}
\begin{document}
\begin{center}\bfseries\Large
Assignment~1
\end{center}
\begin{enumerate}
\DTLforeach*{\problemDB}
{\Label=Label,\Question=Question}%
{%
\item \Question
}
\end{enumerate}
\ifbool{showanswers}
{%
\section{Solutions}
\begin{enumerate}
\DTLforeach*{\problemDB}
{\Label=Label,\Answer=Answer}%
{%
\item \Answer
}
\end{enumerate}
}{}
\end{document}
↓ Input
You can, of course, use the exam class or probsoln package with datatool. That
way you don’t need to define your own boolean variable.
It may, however, be that you only want a random selection of the ques-
tions from the database. While this could be done within the document using
commands provided by the datatool package, it’s more efficient to do this using
datatooltk. That way, the random selection only needs to be done once per
problem sheet (possibly repeated after any modifications to the database) which
reduces the time taken for TEX to compile the document. The datatooltk has
a number of command line options that can help with this:
• --shuffle
Shuffle the rows in the database.
• --seed ⟨number⟩
Set the random generator seed to ⟨number⟩.
9.4 Using the datatool Package for Exams or Assignment Sheets 267
• --shuffle-iterations ⟨number⟩
Sets the number of iterations performed in the shuffle to ⟨number⟩
• --truncate ⟨number⟩
Truncate the database to the first ⟨number⟩ rows. (This option is always
performed after the shuffle option, regardless of the option order.)
• --filter ⟨key⟩ ⟨operator⟩ ⟨value⟩
Adds a filter. This option may be used multiple times. Here ⟨key⟩ is the
column label used by the filter. The ⟨operator⟩ may be one of: eq (equals),
ne (does not equal), le (is less than or equal to), lt (is less than), ge (is
greater than or equal to), gt (is greater than) or regex (matches the regular
expression). In the last case, ⟨value⟩ should be a regular expression as
used by java.util.regex.Pattern. In the other cases, ⟨value⟩ may be an
integer, real number or string. If the datatype for the column identified
by ⟨key⟩ is numerical and ⟨value⟩ is also numerical, then a numerical
comparison is used, otherwise a string comparison is used. For example,
--filter Level le 2 indicates that the filter should return a true value
for any row where the value in the Level column is less than or equal to
2.
Filtering is always applied after shuffling and before truncating (if either
of those options have been specified).
• --filter-and
The default action in the event of multiple --filter options is to apply
a logical “or”. The --filter-and changes this behaviour to apply a logical
“and” to all the filter results instead. For example, suppose the database
also has a column labelled Topic and you want to select five easy questions
from the topic “Algebra”, then you need a logical “and”:
• --filter-exclude
When applying any filters, the --filter-exclude option will cause any
matching rows to be excluded. (The default behaviour is to exclude non-
matching rows.)
• --merge ⟨col-label⟩ ⟨filename⟩
Merges the loaded database with the database in the file whose name is
given by ⟨filename⟩. The merge is performed by merging each row in
⟨filename⟩ with the row in the database where the column given by the
label ⟨col-label⟩ has the same value as the column with the same label in
⟨filename⟩. If no match is found, a new row is added.
With a combination of these options, it’s possible to create a database file
(called, say, problems.dbtex) that only contains a random subset of the complete
database.
Examples:
1. Select five questions (of any level) at random:
3. Select four non-easy questions at random with the seed set to 2014:
The document from Example 46 just needs one line changed, and that’s the line
that loads the database:
\DTLloaddbtex{\problemDB}{problems.dbtex} Input
Alternatively, if you want, say, four level 1 questions, two level 2 questions and
one level 3 question, you can create three separate databases:
datatooltk --in mth101.dbtex --shuffle
line-wrap-symbol
--filter Level eq 1 --truncate 4
line-wrap-symbol
--output problems1.dbtex
datatooltk --in mth101.dbtex --shuffle
line-wrap-symbol
--filter Level eq 2 --truncate 2 Shell
line-wrap-symbol
--output problems2.dbtex
datatooltk --in mth101.dbtex --shuffle
line-wrap-symbol
--filter Level eq 3 --truncate 1
line-wrap-symbol
--output problems3.dbtex
Now you need to load all three databases into your document:
↑ Input
\DTLloaddbtex{\problemDBi}{problems1.dbtex}
\DTLloaddbtex{\problemDBii}{problems2.dbtex}
\DTLloaddbtex{\problemDBiii}{problems3.dbtex}
↓ Input
↑ Input
\begin{enumerate}
\DTLforeach*{\problemDBi}
{\Label=Label,\Question=Question,\Answer=Answer}%
{%
\item \Question
\ifbool{showanswers}{\par\textbf{Solution: }\Answer}{}%
}
\DTLforeach*{\problemDBii}
{\Label=Label,\Question=Question,\Answer=Answer}%
{%
\item \Question
\ifbool{showanswers}{\par\textbf{Solution: }\Answer}{}%
}
\DTLforeach*{\problemDBiii}
{\Label=Label,\Question=Question,\Answer=Answer}%
9.4 Using the datatool Package for Exams or Assignment Sheets 269
{%
\item \Question
\ifbool{showanswers}{\par\textbf{Solution: }\Answer}{}%
}
\end{enumerate}
↓ Input
↑ Input
\newcommand{\doquestions}[1]{%
\DTLforeach*{#1}
{\Label=Label,\Question=Question,\Answer=Answer}%
{%
\item \Question
\ifbool{showanswers}{\par\textbf{Solution: }\Answer}{}%
}%
}
↓ Input
If the original database contains, say, two hundred problems, using datatooltk
in this way can significantly speed up the document build. Each year you can run
the datatooltk commands with a different random generator seed to produce
a new assignment sheet or exam paper.
If you prefer to store your problems in a SQL database, you can perform
the random selection with the SELECT statement. For example, if the problems
are stored in a table called calculus within a database called mth101, then you
can select, say, five questions at random using:
datatooltk --output problems.dbtex --sqluser username
line-wrap-symbol
--sqldb mth101 --sql "SELECT * FROM calculus Shell
line-wrap-symbol
ORDER BY RAND() LIMIT 5"
What if you don’t want to select any problems that appeared in the exam
paper or assignment sheet in, say, the previous two years? You could add a year
column to the original complete database, but this can be tiresome and prone
to error if done manually. It could possibly be done by the LATEX document, but
this would require loading the entire database and saving it using \DTLsaverawdb,
which means it’s pointless using the datatooltk options described above and,
as noted earlier, you’d lose any pretty-printing in the code.
Instead, I think it’s more practical to keep a separate database containing
just the problem labels and the year that problem was selected. This database
can be updated by the document, but since any problems that haven’t been used
in the past two years can be discarded, this database is much smaller than the
original database. Let’s call this database file, say, mth101-years.dbtex. On the
first year, this file won’t exist. Recall from Example 33 the \InputIfFileExists
command. If the file doesn’t exist, a new database can be created using:
\DTLnewdb{⟨db-name⟩} Definition
↑ Input
\InputIfFileExists{mth101-years.dbtex}
{}% file exists
{\DTLnewdb{mth101-years}}% file doesn't exist
↓ Input
9.4 Using the datatool Package for Exams or Assignment Sheets 270
While the main database is iterated over, each question label can be added
to the mth101-years database with the current year. To add data, you first need
to add a new row to the database using:
\DTLnewrow{⟨db-name⟩} Definition
and then you can add the entries for that row using:
\DTLnewdbentry{⟨db-name⟩}{⟨col-label⟩}{⟨value⟩} Definition
where ⟨col-label⟩ is the column label and ⟨value⟩ is the value for that column.
By default, the value isn’t expanded. To change this, you first need to use the
command:
\dtlexpandnewvalue Definition
↑ Input
\documentclass{article}
\usepackage{etoolbox}
\usepackage{datatool}
\newbool{showanswers}
\booltrue{showanswers}
\DTLloaddbtex{\problemDB}{mth101.dbtex}
\InputIfFileExists{mth101-years.dbtex}
{}% file exists
{\DTLnewdb{mth101-years}}% file doesn't exist
\begin{document}
\begin{center}\bfseries\Large
Assignment~1\ifbool{showanswers}{ (Solution Sheet)}{}
\end{center}
\dtlexpandnewvalue
\begin{enumerate}
\DTLforeach*{\problemDB}
{\Label=Label,\Question=Question,\Answer=Answer}%
{%
\item \Question
% add this label to the new database:
\DTLnewrow{mth101-years}% add a new row
\DTLnewdbentry{mth101-years}{Label}{\Label}%
\DTLnewdbentry{mth101-years}{Year}{\number\year}%
% print the solution if this is the answer sheet:
\ifbool{showanswers}{\par\textbf{Solution: }\Answer}{}%
}
\end{enumerate}
↓ Input
↑ Input
\DTLsaverawdb{mth101-years}{mth101-years.dbtex}
\end{document}
↓ Input
If the mth101 database doesn’t need editing, this call only really needs to be
done once a year. However, if you edit the database by removing, adding or
swapping rows, you may end up with a different selection, and labels that are no
longer selected will still be assigned to the current year. For example, suppose
diff:arcsin was selected for this year, but then you add another problem to
mth101.dbtex so that now diff:arcsin is no longer selected, but it’s still listed in
mth101-years.dbtex as having been selected this year. You can fix this using:
datatooltk --in mth101-years.dbtex
line-wrap-symbol
--filter Year eq 2013 --filter Year eq 2012 Shell
line-wrap-symbol
--output mth101-years.dbtex
This also has the advantage of removing any problems from pre-2012, which
trims down the database.
If you use make on a Unix-like system, the Makefile could look something
like:
CURRYEAR:=$(shell date +%Y)
LASTYEAR:=$(shell expr $(CURRYEAR) - 1)
YEARBEFORE:=$(shell expr $(CURRYEAR) - 2)
problems.dbtex : mth101.dbtex
datatooltk --in mth101.dbtex \
--merge Label mth101-years.dbtex \
--shuffle \
--filter-and \
--filter Year ne $(LASTYEAR) \
--filter Year ne $(YEARBEFORE) \
--truncate 5 \
--output problems.dbtex
update :
datatooltk --in mth101-years.dbtex \
--filter Year eq $(LASTYEAR) \
--filter Year eq $(YEARBEFORE) \
--output mth101-years.dbtex
Now, at the start of each year (or after altering the structure of the database
in mth101.dbtex) you can use
9.4 Using the datatool Package for Exams or Assignment Sheets 272
to trim mth101-years.dbtex to just the entries for the previous two years.
(There’s probably a more efficient way of writing this Makefile, but a discus-
sion of the make utility is beyond the scope of this book. If you want to copy
the above code, remember to use the TAB character in the appropriate places.
Alternatively, you can download the file from the examples directory.)
Note that the --merge option will be ignored if the file to be merged doesn’t
exist. (Just a warning message will be displayed on the standard error stream.)
This means that the problems.dbtex target will work on the first instance, even
though the mth101-years.dbtex file doesn’t exist.
Recall the \marginpar command from Exercise 21. This can be used to, say,
display the number of points for a question in the margin. For example, if all
questions are worth 20 points, then within the body of \DTLforeach the number
of points can be inserted into the margin:
\item \marginpar{(20 points)}\Question Input
↑ Input
\newcommand*{\points}[1]{%
\marginpar{(#1 points)}%
}
↓ Input
Now you just need to modify the definition of \points if you want to change the
way the points are displayed. For example, if the argument of \points is always
an integer, you could check for a single point and change “points” to “point”:
↑ Input
\newcommand*{\points}[1]{%
\marginpar{(#1
\ifnum#1=1\relax
point%
\else
points%
\fi)}%
}
↓ Input
If the argument may be a decimal number, the datatool package provides the
command:
\dtlifnumeq{⟨number 1⟩}{⟨number 2⟩}{⟨true⟩}{⟨false⟩} Definition
↑ Input
\newcommand*{\points}[1]{%
\marginpar{(#1
\dtlifnumeq{#1}{1}{point}{points})}%
}
↓ Input
9.4 Using the datatool Package for Exams or Assignment Sheets 273
Perhaps the points should depend on the difficulty level. For example,
5 points for a level 1 question, 10 points for a level 2 question and 20 points
for a level 3 question. The \ifcase command described in §7.3 can be used to
check the level:
↑ Input
\item
\ifcase\Level
\or
\points{5}%
\or
\points{10}%
\or
\points{20}%
\fi
\Question
↓ Input
Again, you can define a command that will simplify the document code:
↑ Input
\newcommand*{\PointsForLevel}[1]{%
\ifcase#1
\or
\points{5}%
\or
\points{10}%
\or
\points{20}%
\fi
}
↓ Input
which will write ⟨text⟩ to the file identified by ⟨output stream⟩. The second
argument, ⟨init code⟩, is provided for any initialisation that needs to be done
prior to writing the text. The output stream for the document’s auxiliary file
9.4 Using the datatool Package for Exams or Assignment Sheets 274
is identified by the command \@auxout. You’ll need to wrap the point total up
in a command that can be used to reference the total at the start of the next
run. Remember to use \protect in ⟨text⟩ to prevent expansion of this helper
command.
You can download or view a solution to this exercise.
where ⟨cs⟩ is a control sequence in which to store the random number. The
random number generator seed is set using
\FPseed=⟨number⟩ Definition
which parses the given mathematical expression and sets \pgfmathresult to the
result. There are a number of functions that may be used within ⟨expression⟩
(see the pgf user guide [102] for further details) but the random generator func-
tions are
rnd Definition
which generates a random integer between ⟨x⟩ and ⟨y⟩, if both are present, or
a random integer between 1 and ⟨x⟩ if only ⟨x⟩ is present:
random(⟨x⟩) Definition
↑ Input
Year: \the\year.
\pgfmathsetseed{\year}
\pgfmathparse{random(2,10)}
Random number: \pgfmathresult.
↓ Input
produces:
where ⟨list name⟩ is the name of the list and ⟨item 1⟩, ⟨item 2⟩ etc are the list
items. (Note that this list isn’t a comma-separated list. Each item is in braces
like an argument.)
Once the list has been defined you can randomly select an item using:
\pgfmathrandomitem{⟨cs⟩}{⟨list name⟩} Definition
where ⟨list name⟩ identifies the list. The result can then be accessed using the
supplied control sequence ⟨cs⟩.
Example:
↑ Input
% define list
\pgfmathdeclarerandomlist{projects}%
{% list items
{ray-guns}% first item
{mind-controlling cookies}% second item
{exploding chocolates}% third item
{telepathic cakes}% fourth item
}
% randomly select an item from the list
\pgfmathrandomitem{\thisproject}{projects}
B As mentioned earlier, take care if you are using a mechanism that first
displays questions and later (for example, at the end of the document) dis-
plays the solutions as this can cause a different randomly generated value in the
solution. As before, I recommend that the question part globally defines a com-
mand that stores the randomly generated value which can later be accessed in
the solution.
Example 48. Random Selection with pgfmath and probsoln
(Recall the commands \ifundef, \global and \let from §2.1.1.)
9.5 Random Numbers 277
↑ Input
\documentclass{article}
\usepackage{pgfmath}
\usepackage{probsoln}
\begin{defproblem}{easy.diff}%
\ifundef\easydiffcoeff
{% random coefficient:
\pgfmathrandominteger{\easydiffcoeff}{2}{10}%
% make it global:
\global\let\easydiffcoeff\easydiffcoeff
}
{}% already been defined
\begin{onlyproblem}
% question
Differentiate with respect to $x$:
\[
y = \sin(\easydiffcoeff x)
\]
\end{onlyproblem}
\begin{onlysolution}
% solution
$ y' = \easydiffcoeff\cos(\easydiffcoeff x) $
\end{onlysolution}
\end{defproblem}
\begin{document}
\section{Questions}
\begin{enumerate}
\foreachproblem{\item\thisproblem}
\end{enumerate}
\showanswers
\section{Solutions}
\begin{enumerate}
\foreachsolution{\item\thisproblem}
\end{enumerate}
\end{document}
↓ Input
This produces (where the year is 2014) the result shown in Figure 9.4. You can
download or view this example.
9.5 Random Numbers 278
Output
1 Questions
1. Differentiate with respect to x:
y = sin(8x)
2 Solutions
1. y ′ = 8 cos(8x)
279
10.1 The picture Environment 280
\begin{picture}(⟨width⟩,⟨height⟩)(⟨llx⟩,⟨lly⟩)
⟨picture commands⟩ Definition
\end{picture}
This has a different syntax to most of the standard environments as the argu-
ments are placed in parentheses rather than curly braces. Another unusual
aspect is that the second argument (⟨llx⟩,⟨lly⟩) is optional, even though it isn’t
delimited by square brackets.
The first argument (⟨width⟩,⟨height⟩) indicates the width and height of the
picture, and the second argument indicates the co-ordinates of the lower left-
hand corner (the origin, if omitted). In both cases, the values are considered to
be in terms of the length \unitlength. The picture environment is in fact just
another instance of a box (see Volume 1 [93, §4.7]) and its contents should only
consist of declarations and drawing or positioning commands.
The most commonly used of these commands is:
\put(⟨x⟩,⟨y⟩){⟨object⟩} Definition
which puts ⟨object⟩ at the co-ordinates specified by (⟨x⟩,⟨y⟩) (which are again
in terms of \unitlength). The ⟨object⟩ may be text, included graphics (using
the graphicx package’s \includegraphics command), straight lines or arrows.
A straight line is specified by:
\line(⟨h⟩,⟨v⟩){⟨length⟩} Definition
There are only a limited number of gradients available. In both cases, the
gradient is specified via the horizontal ⟨h⟩ and vertical ⟨v⟩ displacements, where
⟨h⟩ and ⟨v⟩ are both integers without a common divisor. In the case of \line,
⟨h⟩ and ⟨v⟩ are restricted to values between −6 and +6, inclusive, whereas in
the case of \vector, those arguments are restricted to values between −4 and
+4, inclusive.
Example:
The following code first sets the unit length to 1 cm and then creates a picture
that’s 3 cm wide by 2.5 cm high. I’ve added a border around the picture using
\fbox.
↑ Input
\setlength{\unitlength}{1cm}% set the unit length
\fbox{%
\begin{picture}(3.5,2.5)
\put(0.5,0.5){A}
\put(0.8,0.8){\vector(2,1){1.8}}
\put(2.8,1.8){B}
\end{picture}
}
↓ Input
This produces:
B
*
Output
A
Slanted lines are drawn using a special font where the characters consist of
small line segments. This is why there’s a restriction on the available gradients.
10.1 The picture Environment 281
to create an oval whose width and height are given by ⟨w⟩ and ⟨h⟩. In both cases,
the lengths are again specified in terms of \unitlength. The optional argument
of \oval may be used if only a quarter or half oval is required, instead of the full
oval. In the case of a half oval, ⟨segment⟩ should be a single letter identifying
which half: l (left), r (right), t (top) or b (bottom). For a quarter oval, ⟨segment⟩
should be a two-letter combination, for example, tr indicates top right.
A filled circle is created using the starred form:
\circle*{⟨diameter⟩} Definition
Example:
↑ Input
\setlength{\unitlength}{1cm}
\fbox{%
\begin{picture}(4.0,4.0)
\put(1,1){\circle*{0.5}}
\put(2,1){\oval(3,1)[bl]}
\put(2,3){\oval(3,1)[tr]}
\put(2,2){\oval(3,1)}
\put(3,3){\circle{0.5}}
\end{picture}
}
↓ Input
This produces:
m
Output
}
\shortstack[⟨align⟩]{⟨text⟩} Definition
Example:
↑ Input
This produces:
You may remember \framebox and \makebox from Volume 1 [93, §4.7]. When
used within the picture environment, these commands have different syntax.
\framebox(⟨w⟩,⟨h⟩)[⟨align⟩]{⟨text⟩} Definition
and
\makebox(⟨w⟩,⟨h⟩)[⟨align⟩]{⟨text⟩} Definition
In both cases the reference point is the lower-left corner of the box. The width
and height of the box are given by ⟨w⟩ and ⟨h⟩ (again in terms of \unitlength).
The optional argument ⟨align⟩ indicates the alignment of the text. The default
is to centre the text both vertically and horizontally. To change this, the ⟨align⟩
argument may be one or two letters: l (left), r (right), t (top) and b (bottom).
There’s another box similar to \framebox:
\dashbox{⟨dash length⟩}(⟨w⟩,⟨h⟩)[⟨align⟩]{⟨text⟩} Definition
This mostly has the same syntax as above, but produces a dashed frame. The
additional argument ⟨dash length⟩ specifies the length of the dashes.
Example:
↑ Input
This produces:
10.1 The picture Environment 283
of
Secret Lab
Output
Experimental Stuff
There are two other commands provided for use in the picture environment.
These aren’t used with \put. As before, all lengths are in terms of \unitlength.
\qbezier[⟨points⟩](⟨start x⟩,⟨start y⟩)(⟨control x⟩,⟨control y⟩)(⟨end
Definition
x⟩,⟨end y⟩)
This draws a quadratic Bézier curve with the given start, end and curvature
control points. LATEX draws the curve using multiple points. More points results
in a smoother curve but a longer document build time. You can use the optional
argument to specify the number of points used to draw the curve.
\multiput(⟨x⟩,⟨y⟩)(⟨inc x⟩,⟨inc y⟩){⟨n⟩}{⟨object⟩} Definition
This puts ⟨n⟩ copies of ⟨object⟩, starting at position (⟨x⟩,⟨y⟩) and advancing the
position by (⟨inc x⟩,⟨inc y⟩) each time.
Example 49. A Postcard
This example uses the picture environment to create a simple postcard advertising
an event. The geometry package [110] is used to set a non-standard paper size
(6 in wide by 4 in high with no margins). I also used the graphicx package to
include the sample image chicken.png.
↑ Input
\documentclass[12pt]{article}
\usepackage[papersize={4in,6in},margin={0in,0in}]{geometry}
\usepackage{graphicx}
\pagestyle{empty}
\setlength{\unitlength}{1in}
\begin{document}
\centering
\begin{picture}(4,6)
\put(0,1.25){\makebox(4,3.75){%
\includegraphics[height=3.75in]{chicken}}}
\put(0,5){\makebox(4,1){\large\bfseries
Oh No! The Chickens Have Escaped!}}
\put(0,0.5){\makebox(4,0.75){%
\shortstack
{%
Written by award-winning author Dickie Duck\\
Illustrated by internationally renown artist Jos\'e Arara
}%
}}
\put(0,0){\makebox(4,0.5){\large\bfseries
Book Launch 1st August 2014}}
\end{picture}
10.2 The ticket Package 284
\end{document}
↓ Input
(You can download or view this document.) The resulting document is shown
in Figure 10.1.
where ⟨num cols⟩ and ⟨num rows⟩ are the number of tickets in the horizontal
and vertical directions. The ticket dimensions are specified using:
\ticketSize{⟨width⟩}{⟨height⟩} Definition
where the ⟨width⟩ and ⟨height⟩ are in terms of \unitlength. The distance
between the tickets is specified using:
\ticketDistance{⟨𝑥-dist⟩}{⟨𝑦-dist⟩} Definition
where ⟨𝑥-dist⟩ and ⟨𝑦-dist⟩ are the horizontal and vertical distances in terms
of \unitlength. Note that you need to set \unitlength before using the above
dimension commands.
For single use only, you can just put these settings in your document after you
load the ticket package (without specifying the ⟨tdf-file⟩ in the package options).
In the document you can set up the default ticket content by redefining:
\ticketdefault Definition
Since this is placed inside the picture environment, remember to use picture com-
mands, such as \put. The default definition is:
\put ( 5, 5){Ticket....} Input
Example
Suppose each ticket should have a logo (stored in the image file logo.png) and
departmental information:
↑ Input
\renewcommand*{\ticketdefault}{%
\put (80,82) {\includegraphics[width=12mm]{logo}}
\put (5,85) {\large\bfseries Secret Lab of Experimental Stuff}
}
↓ Input
where ⟨content⟩ is additional content. You either need to have multiple \ticket
commands for each ticket or place \ticket inside a loop. (Recall §2.7.)
Example
Suppose I want to display a ticket with a name on it:
↑ Input
\ticket
{
\put (49,30) {\makebox(0,0) {\Large\bfseries Polly Parrot}}
}
↓ Input
This will create a ticket with the default background (as given by \ticketdefault)
and the name added to it.
The ticket package documentation suggests defining a wrapper command:
10.2 The ticket Package 286
↑ Input
\newcommand*{\myticket}[1]{%
\ticket
{
\put (49,30) {\makebox(0,0) {\Large\bfseries #1}}
}%
}
↓ Input
↑ Input
\myticket{Polly Parrot}
\myticket{Mabel Canary}
↓ Input
The ticket package automatically sets the page style to empty. Package options
are available to create marks or decorations around the tickets:
crossmark Puts a cross at all four corners.
circlemark Puts an unfilled circle at all four corners.
emptycrossmark Like crossmark but only draws the parts of the marker that lie
outside the ticket.
cutmark Just adds cutmarks at the outer region.
boxed Adds a frame around the ticket.
↑ Input
\documentclass[a4paper]{article}
\usepackage[cutmark]{ticket}
\usepackage[margin=5mm]{geometry}
\usepackage{graphicx}
\setlength{\unitlength}{1mm}
\ticketNumbers{2}{3}
\ticketSize{98}{90}
\ticketDistance{4}{4}
\renewcommand*{\ticketdefault}{%
\put (80,80) {\includegraphics[width=12mm]{dummy-logo}}
\put (5,85) {\large\bfseries Secret Lab of Experimental Stuff}
\put (5,75) {\large\scshape University of Somewhere}
\put (45,30) {\makebox(0,0){\Large\itshape Culinary Experimental
10.3 The leaflet Class 287
Research}}
}
\newcommand*{\myticket}[1]{%
\ticket
{
\put (45,50) {\makebox(0,0) {\Large\bfseries #1}}
}%
}
\begin{document}
\myticket{Polly Parrot}
\myticket{Mabel Canary}
\myticket{Zöe Zebra}
\myticket{José Arara}
\myticket{Dickie Duck}
\myticket{Fred Canary}
\end{document}
↓ Input
(You can download or view this document.) The resulting document is shown
in Figure 10.2.
If you just do
texdoc leaflet Shell
Marginal notes and two-column typesetting are disabled and by default there are
no page headers or footers. Paragraph indentation is set to zero and paragraphs
are separated by vertical space.
Class options (in addition to the options provided by article) are:
tumble Print the back sheet upside-down (default).
10.3 The leaflet Class 288
This command may only be used in the preamble and indicates that a cut line
should be drawn to the left of the page given by ⟨page number⟩. The starred
version just draws a dotted line. The unstarred version draws a dotted line with
a pair of scissors.
\AddToBackground{⟨page number⟩}{⟨picture code⟩} Definition
Again this command may only be used in the preamble. This indicates that
⟨picture code⟩ should be added to the page given by ⟨page number⟩. With the
starred version, the ⟨page number⟩ refers to the sheet number (1 for the front
and 2 for the back sheet). The background is placed inside a picture environment,
so the ⟨picture code⟩ may include any of the commands described in §10.1.
Remember that the co-ordinates are in terms of \unitlength. If you want
to provide a specific length that’s independent of \unitlength, the leaflet class
provides:
\LenToUnit{⟨length⟩} Definition
This may be redefined as required. The default value is \bfseries. The font
declaration used for the item label in the description environment is given by
\descfont Definition
bold smallcaps, I’ve used the Alegreya package [105] to switch to the Alegreya
font, which does have bold smallcaps. (For other fonts, have a look at the Font
Catalogue [49].) The wasysym package [42] provides the \Square command used
for the tick boxes 2.
Leaflets and flyers tend to be less structured than normal documents, so I’ve
used some commands that typically shouldn’t be used (or, at least, used only
sparingly on the final copy) in article, report or book-like documents. These
include
\newpage Definition
which forces a page break, without attempting to vertically justify the page,
\bigskip Definition
which inserts a vertical space that will expand to fit the available height. The
paragraph justification can be made through an environment, such as center
or flushright, which additionally inserts a vertical space above and below the
environment, or the justification can be made through a declaration, such as
\raggedright (recall Volume 1 [93, §2.12]).
↑ Input
\documentclass[a4paper,12pt,notumble]{leaflet}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{Alegreya}
\usepackage{wasysym}
\usepackage{xcolor}
\usepackage{graphicx}
\renewcommand*{\sectfont}{\scshape}
\renewcommand*{\descfont}{\bfseries\scshape}
\AddToBackground*{1}{%
\put (0,0)
{\rotatebox{33}{\resizebox{30cm}{!}{\color{lightgray}%
CLASSIFIED}}}%
}
\AddToBackground{1}{%
\put
(\LenToUnit{0.5\paperwidth},\LenToUnit{0.5\paperheight})
{\oval(\LenToUnit{0.95\paperwidth},\LenToUnit{0.95\paperheight})}%
}
\CutLine{6}
\begin{document}
\begin{center}\bfseries\Huge
Culinary Experimental Research
\vfill
\normalsize
\begin{tabular}{c}
10.3 The leaflet Class 291
\vfill
\begin{tabular}{c}
Department of Stripy Confectioners\\
College of Somewhere Else
\end{tabular}
\vfill
\includegraphics[height=3cm]{dummy-logo}
\end{center}
\newpage
\raggedright
\begin{flushright}
\includegraphics{mallard}
\end{flushright}
\newpage
\section{Query Form}
\bigskip
\begin{tabular}{@{}l}
Miss Ingperson\\
Secret Lab of Experimental Stuff\\
University of Somewhere\\
Some City\\
AB3 4YZ
\end{tabular}
10.3 The leaflet Class 292
\bigskip
\bigskip
\begin{tabular}{@{}lp{4cm}}
Name: & \dotfill \\
Address: & \dotfill\\
& \dotfill \\
& \dotfill \\
& \dotfill \\
Postcode: & \dotfill\\
Country: & \dotfill\\
Telephone: & \dotfill\\
Mobile: & \dotfill\\
Email: & \dotfill
\end{tabular}
\newpage
\section{Research Team}
\begin{description}
\item[Administrator] Mr Big Head
\end{description}
\section{Acknowledgements}
\begin{description}
\end{description}
\end{document} ↓ Input
10.3 The leaflet Class 293
(You can download or view this document, and the sample image files dummy-logo.
png, mallard.png and goose.png.)
The resulting document is shown in Figure 10.3 (first sheet) and Figure 10.4
(second sheet). The small marker line to the right of the first section heading
on the second sheet is the folding mark. Try this example first without and then
with the twopart class option.
↑ Input
\documentclass[a4paper,12pt,notumble]{leaflet}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{Alegreya}
\usepackage{wasysym}
\usepackage[x11names]{xcolor}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{calc}
\renewcommand*{\sectfont}{\scshape}
\renewcommand*{\descfont}{\bfseries\scshape}
\AddToBackground{1}{%
\put (0,0)
{\begin{tikzpicture}
\path[fill=Thistle1,draw=Thistle4,double=Orchid1,line width=2pt]
(0,0) rectangle ($(\paperwidth, \paperheight)-(4pt,4pt)$);
\end{tikzpicture}
}%
}
\CutLine{6}
↓ Input
The remainder of the document is as before. This uses the calc tikz library,
which enables co-ordinate calculations using the $ syntax. For example
($(\paperwidth, \paperheight)-(4pt,4pt)$) Input
indicates the co-ordinate obtained by subtracting the point (4 pt, 4 pt) from the
point (\paperwidth, \paperheight). The calc library must first be loaded using:
\usetikzlibrary{calc} Input
The above example code also loads the xcolor package with the x11names
option to enable the use of the X11 colour names, such as Thistle1. For further
details about the syntax of the \path command, see the pgf/tikz user manual [102].
The first sheet is now as shown in Figure 10.5.
For other possible fancy frames or decorations, have a look at the decoration
topic. There is also a non-CTAN tikz-based package called pgfornament available
from http://altermundus.com/pages/tkz/ornament however this will require
' $
University of Somewhere
Some City Acknowledgements
AB3 4YZ Secret Lab of Experimental Stuff
The Culinary Experimental Research team University of Somewhere
2 I would like to receive quarterly newsletters. would like to thank the following:
University of Somewhere For something or
D
other
2 I agree to having my memory wiped.
2 Yes, I’d really like to feed the ducks.
Name: .....................
College of Somewhere Else For providing
bread crumbs
I E
Address: ..................... The Ministry of Top Secret Stuff For
..................... supporting the project somehow. Department of Stripy Confectioners
..................... College of Somewhere Else
Postcode:
.....................
.....................
I F
Country: .....................
Telephone: .....................
Mobile: .....................
Email: S .....................
S
LA
.......................... " .......................... .......................... " ..........................
& %
questions as long as they consent to a memory but, after a full and detailed investigation, the
wipe when they leave. The memory wipe is health and safety department observed that
harmless (well, we haven’t really tested it Mind-Controlling Cookies there are also geese present in the duck pond.
properly, but no one’s complained so far) and
Preliminary tests have shown that the
your memory of the visit will be replaced by a
mind-controlling properties of the
pleasant recollection of spending the day
mind-controlling cookies are somewhat
feeding the ducks in the nearby pond.
disappointing, but critics have said that they
taste very nice and could they have some more
bread for the ducks.
Ingredients
• Self-raising flour;
• Butter;
• Chocolate chips;
• Sugar obtained from secret genetically
Department of Stripy modified beet.
Confectioners
The Department of Stripy Confectioners is a Telepathic Cakes
department within the College of Somewhere
Else. The department is internationally known Preliminary experiments on the telepathic cakes
for its cutting-edge research in the field of stripy have revealed an unfortunate side-effect. The
confectionery, including humbugs and sticks of full results are in the senior scientist’s head.
rock. Telepathy is required to view them. Please read
the full terms and conditions before use.
a manual installation since it’s not included in the TEX distributions (recall Vol-
ume 1 [93, §A]).
latex myDoc
dvips -o myDoc.ps myDoc.dvi Shell
ps2pdf myDoc.ps myDoc.pdf
If you use a frontend, such as TeXworks, you need to find the appropriate
buttons or menu options to run these commands. If you use arara, you
need the following directives:
↑ Input
% arara: latex
% arara: dvips
% arara: ps2pdf
↓ Input
You can replace the two steps dvips and ps2pdf with a single call to
dvipdfm.
2. Put the pstricks code in a standalone document, compile that document
using latex, dvips and ps2pdf, as described above, and include the gen-
erated PDF file into the main document using \includegraphics.
The pst-pdf package [63] can be used to simplify the second option if you have
multiple pstricks images in your document, but you still need the latex, dvips
and ps2pdf invocations.
If I’m designing a flyer that requires a bar code, such as an advance informa-
tion sheet with a QR code, I usually use the second option. Once I’ve generated
the bar code, I rarely need to change it, as my modifications to the document
usually concern the accompanying text rather than the bar code, so it’s easiest
to treat the bar code as an external graphics file.
The pst-barcode package provides the command:
\psbarcode[⟨options⟩]{⟨text or filename⟩}{⟨PS options⟩}{⟨type⟩} Definition
This generates a bar code with zero size, which means it typically needs to
go inside an environment or command where you can specify the height and
width. (Recall Volume 1 [93, §4.7].) Since pst-barcode automatically loads the
pstricks package [117], you can use the pspicture environment:
Query Form Research Team Culinary
If you’d like to know more about the exciting Administrator Mr Big Head
collaboration between the Secret Lab of Assistant Administrator Dr Bor Ing
Experimental
Experimental Stuff and the Department of
Stripy Confectioners please fill in your details Project Co-ordinator Mabel Canary Research
below and post this slip to: Senior Scientists Dickie Duck, Polly Parrot
Research Assistants Zöe Zebra, José Arara,
Miss Ingperson Fred Canary
Secret Lab of Experimental Stuff
University of Somewhere
Some City Acknowledgements
AB3 4YZ Secret Lab of Experimental Stuff
The Culinary Experimental Research team University of Somewhere
10.4 The pst-barcode Package
2 I would like to receive quarterly newsletters. would like to thank the following:
University of Somewhere For something or
other
2 I agree to having my memory wiped.
\begin{pspicture}[⟨baseline⟩](⟨llx⟩,⟨lly⟩)(⟨urx⟩,⟨ury⟩)
⟨picture commands⟩ Definition
\end{pspicture}
As with the picture environment, the co-ordinate arguments are specified using
parentheses, but take care as the syntax of the pspicture environment is slightly
different to that of the picture environment. In the case of pspicture, the first
argument in parentheses (⟨llx⟩,⟨lly⟩) specifies the co-ordinates for the lower
left corner, and second argument in parentheses (⟨urx⟩,⟨ury⟩) specifies the co-
ordinates for the upper right corner of the picture’s bounding box. If (⟨llx⟩,⟨lly⟩)
is omitted, the origin is assumed.
The optional argument ⟨options⟩ of \psbarcode is a key=value list. Available
options include:
file This is a boolean key. This determines whether the argument ⟨text or
filename⟩ is the bar code text (in the case of file=false) or the name
of the file containing the bar code text (in the case of file=true). The
default value for this option is file=false.
transx This specifies a horizontal shift to apply to the bar code. The default
value is transx=0.
transy This specifies a vertical shift to apply to the bar code. The default value
is transy=0.
scalex This specifies a horizontal scaling to apply to the bar code. The default
value is scalex=1.
scaley This specifies a vertical scaling to apply to the bar code. The default
value is scaley=1.
rotate This specifies the rotation (in degrees) to apply to the bar code. The
default value is rotate=0.
↑ Input
\documentclass{article}
\usepackage{pst-barcode}
\begin{document}
\begin{pspicture}(-.4,-.2)(3.8,3)
\psbarcode{1-909440-07-4}{includetext guardwhitespace}{isbn}
\end{pspicture}
\end{document}
↓ Input
How did I work out the co-ordinates for the bounding box? I put the picture
inside the argument of \frame, which marks the picture’s extent with a rectangle
and then adjusted the co-ordinates until the picture fitted inside the frame. Like
this:
↑ Input
\frame{%
\begin{pspicture}(-.4,-.2)(3.8,3)
\psbarcode{1-909440-07-4}{includetext guardwhitespace}{isbn}
\end{pspicture}%
}
↓ Input
Remember that this example document must be compiled with latex rather
than pdflatex. If you want to turn this into an image that you can include in
another document, change the document class to standalone [82] and remove all
unnecessary blank lines:
↑ Input
% arara: latex
% arara: dvips
% arara: ps2pdf
\documentclass{standalone}
\usepackage{pst-barcode}
\begin{document}
\begin{pspicture}(-.4,-.2)(3.8,3)
\psbarcode{1-909440-07-4}{includetext guardwhitespace}{isbn}
\end{pspicture}
\end{document}
↓ Input
Alternatively, if you use arara and have included the arara directives shown
above, you can just do:
arara barcode-isbn Shell
This creates a PDF file called barcode-isbn.pdf that you can now include in
another document using:
10.5 The flowfram Package and the flowframtk Application 300
\includegraphics{barcode-isbn} Input
This produces:
ISBN 978-1-909440-07-4
Output
9 781909 440074
Frames may have a border drawn around them. The default border is just
a rectangle, but other borders may be used. The paragraph shape is unaffected
by the shape of the border but it can be changed either using TEX’s \parshape
primitives or one of the commands provided by the shapepar package [4].
Flow frames can be defined using
\newflowframe[⟨page list⟩]{⟨width⟩}{⟨height⟩}{⟨x⟩}{⟨y⟩}[⟨label⟩] Definition
Each of these commands has a starred version that adds a rectangular border
to the frame. The arguments are as follows:
⟨page list⟩ The list of pages on which this frame is visible. This may be one
of the keywords: all, none, odd or even; or this may be a comma-
separated list of page numbers or page ranges. Page ranges may
be open-ended using <⟨n⟩ for pages less than page ⟨n⟩ or >⟨n⟩ for
pages greater than page ⟨n⟩; or the ranges may be closed using
⟨n⟩-⟨m⟩ for pages between ⟨n⟩ and ⟨m⟩, inclusive. The page num-
bers referenced in the ⟨page list⟩ by default refer to the decimal
value of the page counter. (For example, 1 means page 1 or page i
or page I.) If the pages=absolute package option is used, then the
page number refers to the absolute page number. If ⟨page list⟩ is
omitted, all is assumed.
⟨width⟩ The width of the frame.
⟨height⟩ The height of the frame.
⟨x⟩ The 𝑥-coordinate of the bottom left-hand corner of the frame rela-
tive to the typeblock.
⟨y⟩ The 𝑦-coordinate of the bottom left-hand corner of the frame rela-
tive to the typeblock.
⟨label⟩ A label that uniquely identifies this frame.
The typeblock is the area where the text would be typeset if the document was
in the regular one-column mode. Each frame can be referenced either by its
label or by its index (starting from 1 for each frame type). For example, the
first flow frame to be defined has an index equal to 1, and the first static frame
to be defined also has an index equal to 1.
The contents of a static frame can be set using:
\setstaticcontents{⟨id⟩}{⟨contents⟩} Definition
where the frame contents are given by ⟨contents⟩. For the unstarred version,
⟨id⟩ is the frame’s index. For the starred version, ⟨id⟩ is the label. Alternatively,
the contents can be set using the staticcontents environment:
\begin{staticcontents}{⟨id⟩}
⟨contents⟩ Definition
\end{staticcontents}
As before there is a starred version where ⟨id⟩ is the frame’s label rather than
its index.
The contents of a dynamic frame can be set in a similar manner using:
10.5 The flowfram Package and the flowframtk Application 302
\setdynamiccontents{⟨id⟩}{⟨contents⟩} Definition
As before, these all have starred versions where ⟨id⟩ is the frame’s label.
B Note that verbatim text isn’t permitted in a dynamic frame, even with the
environment version. Make sure that you set the contents before the frame
is displayed on the page.
Example
Static frames are useful for background images, as shown below. This is a
simple document that uses the lipsum package [33] to generate dummy text. This
is a contrived example that shows what happens when you have overlapping
frames and what happens if you have a paragraph spanning flow frames of
different widths. The document text is placed in the flow frames in the order
of the frame definition, which is why the text starts on the right hand frame, as
that was the first flow frame to be defined.
↑ Input
\documentclass[a4paper]{article}
\usepackage{lipsum}
\usepackage{graphicx}
\usepackage{flowfram}
\newflowframe
{0.6\textwidth}% width
{0.3\textheight}% height
{0.4\textwidth}% x position
{0.7\textheight}% y position
\newflowframe{0.6\textwidth}{0.5\textheight}{0pt}{0.5\textheight}
\newflowframe*{\textwidth}{0.4\textheight}{0pt}{0pt}
\newstaticframe{2in}{2in}{0pt}{0pt}
\setstaticcontents{1}{\includegraphics[height=2in]{chicken}}
\begin{document}
\lipsum[1-4]
\end{document}
↓ Input
before the first word of the new frame (between “magna.” and “Nunc” in this
example) should only be resorted to on the final version of the document, once
all the text has been written.
Example 54. Advance Information Sheet
This example uses the flowfram package to create an advance information sheet
for a book. The geometry package is used to set the margins. The page num-
bering is suppressed using the empty page style and the section numbering is
suppressed by setting the secnumdepth counter to 0. (This just saves me from
remembering to use the starred version of \section.) I’ve used the drm pack-
age [29] to illustrate a different font from those I’ve previously used, and I’ve
used the pifont, which provides the dinglist environment that was mentioned in
Volume 1 [93, §8.2]. Recall \dimexpr from §2.1.3, which is used here to calculate
the position of the static frame.
↑ Input
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{drm}
\usepackage{pifont}
\usepackage[margin=0.5in]{geometry}
\usepackage{graphicx}
\usepackage{flowfram}
\pagestyle{empty}
\setcounter{secnumdepth}{0}
\newflowframe{0.6\textwidth}{\textheight}{0pt}{0pt}
\newdynamicframe{.3\textwidth}{\textheight}{.7\textwidth}{0pt}[sidepane]
\newstaticframe{2in}{2in}{\dimexpr(\textwidth-2in)}{0pt}[logo]
\setstaticcontents*{logo}{\includegraphics[width=2in]{dummy-logo}}
\begin{dynamiccontents*}{sidepane}
{\raggedright\bfseries\scshape\Large
Oh No! The Chickens Have Escaped
\par
}
\centering
\bigskip
\includegraphics[width=\linewidth]{chicken}
\bigskip
10.5 The flowfram Package and the flowframtk Application 305
\begin{tabular}{@{}ll}
Genre: & Children's Illustrated \\
& Fiction\\
RRP: & £5.99\\
Format: & Paperback\\
Pages: & 30\\
Pub Date: & 1st August 2014\\
ISBN: & 978-x-xxxxxx-xx-x
\end{tabular}
\vfill
\includegraphics{barcode-qr}
\vfill
\end{dynamiccontents*}
\begin{document}\raggedright
Dickie Duck lives somewhere or other and won the best fowl book
award in 2014. He likes writing silly stories about ducks and
chickens.
\section{Keypoints}
\begin{dinglist}{118}
\item A fun way of teaching children to count.
\section{Marketing}
\begin{dinglist}{118}
\item Written by award-winning author.
\section{Contact}
10.5 The flowfram Package and the flowframtk Application 306
\begin{tabular}{@{}l}
Dickie Duck\\
1 The Street\\
Another Village\\
Some City\\
Imagineshire\\
YZ1 2AB
\end{tabular}
\end{document}
↓ Input
You can download or view this example document. It uses the sample images
chicken.png and dummy-logo.png. It also uses the barcode-qr.pdf file created
in Exercise 28.
The resulting document is shown in Figure 10.7.
If you find it a bit awkward to work out the dimensions and locations of the
frames, there’s a helper GUI application called flowframtk, which provides a
graphical means of defining the frames. As with datatooltk and arara, this is
a Java application so, if you want to use it, make sure you have an up-to-date
version of the Java runtime environment installed on your computer.
To install flowframtk download the installer from flowframtk’s home page.
This is a .jar file. If your operating system knows how to run a .jar file,
you should just be able to double-click on it, otherwise you can run it from the
command line using:
java -jar flowframtk-0.7-installer.jar Shell
(You may need to specify the full path to the .jar file. The version number 0.7
may also need to be changed if a new version has been produced since the time
of writing this.)
Once flowframtk has been installed, it can be run either from your operating
system’s applications menu or from the command line using:
flowframtk Shell
Keypoints
v A fun way of teaching children to count.
v Children will enjoy the repetition and rhyme. Genre: Children's Illustrated
v Features chickens doing stupid things. Fiction
RRP: ¿5.99
v Completely ctitious book encourages children's Format: Paperback
imaginations. Pages: 30
Pub Date: 1st August 2014
Marketing ISBN: 978-x-xxxxxx-xx-x
Contact
Dickie Duck
1 ^e Street
Another Village
Some City
Imagineshire
YZ1 2AB
use the default article class so I’ve left the Use default class radio button selected. If
I want to use a different class, for example scrartcl, then I would have to select the
Use class radio button and type in the class name (without the extension) in the
neighbouring field. Again, click on the green tick button to save the changes
and close the window.
Next I need to specify the packages I want to use. This is done in the pream-
ble editor, which is opened using the TeX/LaTeXÏPreamble menu item. Note that
I don’t include the geometry or flowfram packages since these will automatically be
added when I later use the export function. Here are the packages (as from the
previous example) and I’ve also added the code to set the empty page style and
switch off the section numbering, but I’ve deferred it using \AtBeginDocument:
↑ Input
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{drm}
\usepackage{pifont}
\usepackage{graphicx}
\AtBeginDocument{%
\pagestyle{empty}%
\setcounter{secnumdepth}{0}%
}
↓ Input
You can choose whether to show or hide the grid using the SettingsÏGrid
sub-menu. I’m going to hide the grid but keep the rulers visible. Now I need
to specify the margins. In Example 54 I had 0.5 in margins, but now I want to
have a borderless document, so I’m going to set all the margins to zero. This is
done using the TeX/LaTeXÏFlow FramesÏSet Typeblock menu item, which opens the
10.5 The flowfram Package and the flowframtk Application 311
dialog shown in Figure 10.13. Make sure all the margins are set to 0. (For this
example, you don’t need the other settings in this dialog window.) Although the
margins default to 0, you must still click on the green tick button to save and
close the dialog. A grey rectangle should now be displayed on the canvas with
the word “typeblock” in the bottom left hand corner of the rectangle. (With
zero margins, it may be difficult to see the rectangle.)
Now select the rectangle tool either using the ToolsÏRectangle menu item or
click on the rectangle button in the left tool bar. To draw a rectangle on the can-
vas, click where you want one corner and move the mouse to the location where
the opposite corner should be and click there. For example, in Figure 10.14,
I’ve created a rectangle with top left corner at (0 mm, 0 mm) and bottom right
corner at (130 mm, 297 mm).
This rectangle will represent the main flow frame in my document, but first
I want to add a fill colour and remove the outline. To do this, I need to switch
to the select tool (either using the ToolsÏSelect menu item or by clicking on the
button in the side bar with an arrow on it). Then I can click anywhere inside
the rectangle to select it. When it’s selected, a dashed red rectangle will appear
around it. Then I can use the EditÏFill Colour menu item to open the fill colour
selector. In Figure 10.15, I have selected the Colour radio button and specified
20% cyan, 20% magenta, 0% yellow and 0% black. The rectangle’s black outline
can be removed by selecting the EditÏPathÏLine Colour menu item, which will
open the line colour selector. Click on the Transparent radio button to remove
the outline.
This rectangle now needs to be identified as a flow frame. Make sure it’s
still selected and use the menu item TeX/LaTeXÏFlow FramesÏSet Frame to open
the flow frame selector. Set the Type to Flow and this will enable the flow frame
related options. Give the frame a label (for example, “main”) and select the
Border As Shown option. The margins can also be set to prevent the document
text running against the border. I’ve chosen 5 mm for each margin, as shown
in Figure 10.16. The even page options can be ignored since the result will be
a single-paged document. Again click on the green tick to save the changes
and close the dialog window. The selected rectangle in the main window should
now have a pale grey rectangle inside it that shows the frame’s margins (see
Figure 10.17).
Now I want to create a static frame in the currently unfilled narrow region
on the right hand side of the page. This will just provide a background colour.
I will later make some other frames on top of this one that will contain text and
images. The process is much the same as for the previous frame. The rectangle
tool is selected, a rectangle is drawn with opposing corners at (132 mm, 0 mm)
10.5 The flowfram Package and the flowframtk Application 312
and (210 mm, 297 mm). The fill colour is set to 0% cyan, 0% magenta, 50% yellow,
0% black, and the outline is set to transparent. However, the frame should now
be a static frame, so once the rectangle has been created, select the menu item
TeX/LaTeXÏFlow FramesÏSet Frame and set the Type to Static. This enables a different
set of options to earlier, but for this frame the only extra information needed
is the label. I’ve set this to “sidepane”, as shown in Figure 10.18. Again, click on
the green tick button to save the changes and close the dialog window.
It’s a good idea at this point to save the image in case something goes wrong.
There are two native file formats: .jdr (binary) and .ajr (ASCII). The binary
version has greater precision but the ASCII version works better with version
control systems (see §13.2). Since I use version control and I don’t need double-
precision for my co-ordinates, I’m going to use the ASCII version (.ajr). To
save to a new file use the FileÏSave As menu item and select the appropriate file
type (in my case, flowframtk ascii file (*.ajr)), as shown in Figure 10.19.
Now I need an area in which to put the book title (which appears on the
top right of Figure 10.7). Again I need to use the rectangle tool to use as a
guide for my frame. My rectangle has opposing corners at (136 mm, 5 mm) and
(206 mm, 62 mm). In this case I don’t need to change the colours as I’m only
using the rectangle as a guide to define a borderless dynamic frame. As before,
I need to select this new rectangle and use the TeX/LaTeXÏFlow FramesÏSet Frame
menu item to open the dialog box. Now I set the Type to Dynamic and the label
to “title”, but this time the Border option needs to be set to None as shown in
Figure 10.20.
At the bottom of this dialog window is an area labelled Contents with a button
labelled Edit next to it. This allows you to set the contents of a dynamic or
static frame, just as you can do using commands such as \setdynamiccontents,
described earlier. Click on this Edit button to add the frame contents, which is
the LATEX code from Example 54:
10.5 The flowfram Package and the flowframtk Application 314
↑ Input
\raggedright\bfseries\scshape\Large
Oh No! The Chickens Have Escaped
↓ Input
As shown in Figure 10.21. Click on the green tick button to save these changes
and return to the previous dialog window, and click on the green tick button
there to save and close that window.
is selected, use the TeX/LaTeXÏFlow FramesÏSet Frame menu item to open the
dialog box, and set the Type to Static, the label to, say, “titleimage” and make
sure the Border is set to As Shown. I repeated this process for the sample image
dummy-logo.png (with the scale set to 0.2) and labelled this frame “logo”. The
image so far, with both bitmaps, is as shown in Figure 10.26.
Now I just need another dynamic frame for the rest of the side panel infor-
mation. Again this is done by creating a rectangle, selecting it and using the TeX/
LaTeXÏFlow FramesÏSet Frame menu item to open the frame dialog window. Here
I’ve set the Type to Dynamic, the label to “bookdata” and set Border to None. I’ve
changed the Alignment option to Middle which will vertically balance the frame’s
contents. The contents can again be set by clicking on the Edit button, which
will open the mini-LATEX editor. The contents are as follows:
↑ Input
\begin{tabular}{@{}ll}
Genre: & Children's Illustrated \\
& Fiction\\
RRP: & £5.99\\
Format: & Paperback\\
10.5 The flowfram Package and the flowframtk Application 322
\bigskip
\begin{center}
\colorbox{white}{\includegraphics{barcode-qr}}
\end{center}
↓ Input
(If you prefer, you could convert barcode-qr.pdf to a bitmap and insert it in a
similar manner to the other bitmaps.) Click the green tick to save and return
to the Set Frame dialog, shown in Figure 10.27.
The final image is as shown in Figure 10.28. Make sure you save it to an .ajr
or .jdr before proceeding to the export function. The flowframtk application
can only load its own native files. It can’t load the files it exports, so if you need
to make any modifications you’ll need the .jdr/.ajr file.
Now that the image is complete with all the required flowfram data, you can
export to a LATEX class or package file using the FileÏExport menu item. I’m
going to export to a class file, so I’ve set the file type filter to Class (*.cls) as shown
in Figure 10.29.
My examples directory now contains the files: aisheet.ajr, aisheet.cls
along with my original image files chicken.png, barcode-qr.pdf and dummy-logo.
png. Now I just need to add a LATEX document that uses this new aisheet class
file:
10.5 The flowfram Package and the flowframtk Application 323
↑ Input
\documentclass{aisheet}
\begin{document}\raggedright
Dickie Duck lives somewhere or other and won the best fowl book
award in 2014. He likes writing silly stories about ducks and
chickens.
\section{Keypoints}
\begin{dinglist}{118}
\item A fun way of teaching children to count.
\section{Marketing}
\begin{dinglist}{118}
\item Written by award-winning author.
\section{Contact}
\begin{tabular}{@{}l}
Dickie Duck\\
1 The Street\\
Another Village\\
Some City\\
Imagineshire\\
YZ1 2AB
\end{tabular}
\end{document}
↓ Input
The resulting document is shown in Figure 10.30. You can download or view
this example document.
10.5 The flowfram Package and the flowframtk Application 325
Keypoints
v A fun way of teaching children to count.
v Children will enjoy the repetition and rhyme.
v Features chickens doing stupid things.
v Completely ctitious book encourages children's
imaginations.
Marketing
v Written by award-winning author.
v Illustrated by world famous artist.
Genre: Children's Illustrated
v Some other really interesting marketing information. Fiction
RRP: ¿5.99
Contact Format: Paperback
Pages: 30
Pub Date: 1st August 2014
Dickie Duck ISBN: 978-x-xxxxxx-xx-x
1 ^e Street
Another Village
Some City
Imagineshire
YZ1 2AB
↑ Input
\documentclass{article}
\usepackage{wasysym}
\begin{document}
\section{Query Form}
\bigskip
\begin{tabular}{@{}l}
Miss Ingperson\\
Secret Lab of Experimental Stuff\\
University of Somewhere\\
Some City\\
AB3 4YZ
\end{tabular}
\bigskip
\bigskip
326
Chapter 11. Forms 327
\begin{tabular}{@{}lp{4cm}}
Name: & \dotfill \\
Address: & \dotfill\\
& \dotfill \\
& \dotfill \\
& \dotfill \\
Postcode: & \dotfill\\
Country: & \dotfill\\
Telephone: & \dotfill\\
Mobile: & \dotfill\\
Email: & \dotfill
\end{tabular}
\end{document}
↓ Input
Both \dotfill and \hrulefill are leaders [46] and fill the available horizon-
tal space. In the above example, I used the column identifier p{4cm} to create
a column of width 4 cm, which gives \dotfill 4 cm of horizontal space to fill.
If I’d just used the l left alignment column identifier then no dotted line would
have appeared.
Example
↑ Input
↓ Input
produces:
↑ Output
Some text Some more text.
Some text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Some more text.
Some text . . . . . . . . . . . . . . . . . Some more text.
↓ Output
which produces:
A cut line can be produced with a combination of leaders and a pair of scissors
symbol from a package such as pifont. For example:
↑ Input
\par\noindent
\makebox[2em]{\dotfill}\ding{33}\dotfill\par
↓ Input
which produces:
....!........................................................................... Output
Chapter 11. Forms 328
Note that this doesn’t extend the cut line into the margins. To achieve that
you need to use some negative length and a horizontal box with width given by
\paperwidth. For example:
↑ Input
\par\noindent
\hspace*{-\dimexpr 1in+\hoffset+\oddsidemargin}%
\rlap{%
\makebox[\paperwidth][l]{%
\makebox[4em]{\dotfill}\ding{33}\dotfill
}}\par
↓ Input
For a two-sided document you will need to check if the current page is odd
or even. For example:
↑ Input
\par\noindent
\ifodd\value{page}\relax
\hspace*{-\dimexpr 1in+\hoffset+\oddsidemargin}%
\else
\hspace*{-\dimexpr 1in+\hoffset+\evensidemargin}%
\fi
\rlap{%
\makebox[\paperwidth][l]{%
\makebox[4em]{\dotfill}\ding{33}\dotfill
}}\par
↓ Input
B Be careful using this method of testing for an odd or even page, as it may
not always work due to T X’s asynchronous output routine. If you are using
[FAQ: Finding if you’re
on an odd or an even
E
one of the KOMA-Script classes, you can use KOMA-Script’s \ifthispageodd page]
command to determine if the current page is odd or even in a more robust
manner.
You may find it easier to define a command that produces this with an op-
tional argument to determine the distance between the start of the line and the
scissor symbol. For example:
↑ Input
\newcommand{\cutline}[1][4em]{%
\par\noindent
\ifodd\value{page}\relax
\hspace*{-\dimexpr 1in+\hoffset+\oddsidemargin}%
\else
\hspace*{-\dimexpr 1in+\hoffset+\evensidemargin}%
\fi
\rlap{%
\makebox[\paperwidth][l]{%
\makebox[#1]{\dotfill}\ding{33}\dotfill
}}\par
}
↓ Input
11.1 Writing a Class File for a Form 329
.............! .......................................................................................................................
Remember that if you want a hard copy this requires borderless printing
otherwise a slim margin may still appear (as occurs in the paperback version
of this book).
If you are using the flowfram package, you also need to take into account any
additional offset caused by a frame that doesn’t have its left edge flush against
the left edge of the typeblock. In this case the definition of \cutline needs to
be adjusted as follows:
↑ Input
\newlength\frameoffset
\newcommand{\cutline}[1][4em]{%
\par\noindent
\ifodd\value{page}\relax
\computeleftedgeodd{\frameoffset}%
\getflowbounds{\value{thisframe}}%
\else
\computeleftedgeeven{\frameoffset}%
\getflowevenbounds{\value{thisframe}}%
\fi
\addtolength{\frameoffset}{-\ffareax}%
\hspace*{\frameoffset}%
\rlap{%
\makebox[\paperwidth][l]{%
\makebox[#1]{\dotfill}\ding{33}\dotfill
}}\par
}
↓ Input
\ProvidesClass{⟨name⟩}[⟨version⟩] Definition
This has the same syntax as \ProvidesPackage described in §7.3. The class
code should be saved in a file called ⟨name⟩.cls and placed somewhere on
TEX’s path.
Many classes load a parent class, which saves defining many common ele-
ments, such as the sectioning commands or list environments. The parent class
is loaded using:
\LoadClass[⟨options⟩]{⟨name⟩}[⟨version⟩] Definition
where ⟨name⟩ is the name of the parent class. The optional arguments are
analogous to the optional arguments of \RequirePackage. Before you load a
class, you can specify which options to pass to it using:
\PassOptionsToClass{⟨option-list⟩}{⟨class-name⟩} Definition
where ⟨option⟩ is the option name and ⟨code⟩ is the code to perform for that
option. The starred version of this command only has one argument:
\DeclareOption*{⟨code⟩} Definition
This indicates the code to perform for an unknown option. The option name
can be referenced within ⟨code⟩ using
\CurrentOption Definition
Once all the options have been declared, they then need to be processed using:
\ProcessOptions Definition
↑ Input
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{simple-form}[2014/10/11]
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions
\LoadClass{article}
% class code
\endinput
↓ Input
\CheckedBox Definition
which produces a box with a tick in it 2. These symbols will be useful for this
new class, so the class code needs to load the wasysym package using
\RequirePackage{wasysym} Input
Information for the form can be gathered using the same type of mechanism
as \author, \title and \date. These work by having an internal command that
stores the information and a user command that sets the internal command. For
example, if the form requires a person’s name, the internal command could be
called, say, \@name which is initially empty
\newcommand*{\@name}{} Input
and the user command could be called, say, \name which redefines the internal
command:
↑ Input
\newcommand*{\name}[1]{%
\renewcommand*{\@name}{#1}%
}
↓ Input
↑ Input
\newcommand{\makeform}{%
Name: \@name\ Date: \@date
}
↓ Input
(\@date is the internal command used by \date and is initially defined as \today.)
This definition of \makeform has a problem when \name isn’t used. If \@name
is empty it won’t take up any space. A better solution is to put \@name inside
a horizontal box with a fixed width:
↑ Input
\newcommand{\makeform}{%
Name: \makebox[6em][l]{\@name}\ Date: \@date
}
↓ Input
This will leave a blank space if the name hasn’t been set. If you prefer a lined
space you could make the initial definition of \@name use \hrulefill
\newcommand*{\@name}{\hrulefill} Input
Now a lined space will appear if \name hasn’t been used, but the line won’t be
present if \name has been used. If you still want a line to appear even if \name
has been used, then you could replace
\makebox[6em][l]{\@name} Input
with
\makebox[6em][l]{\rlap{\@name}\hrulefill} Input
If you have more than one blank area to fill in, then it’s best to define a command
to do this. For example:
11.1 Writing a Class File for a Form 332
↑ Input
\newcommand*{\form@fillin}[2]{%
\makebox[#1][l]{\rlap{#2}\hrulefill}%
}
↓ Input
↑ Input
\newcommand{\makeform}{%
Name: \form@fillin{6em}{\@name}\
Date: \form@fillin{4em}{\@date}%
}
↓ Input
↑ Input
\newcommand*{\form@fillin}[2]{%
\makebox[#1][l]{\rlap{#2}\dotfill}%
}
↓ Input
↑ Input
\newcommand*{\form@fillin}[2]{%
\makebox[#1][c]{%
\hrulefill\makebox[0pt][c]{#2}\hrulefill}%
}
↓ Input
↑ Input
\newcommand*{\form@fillin}[2]{%
\makebox[#1][r]{\hrulefill\llap{#2}}%
}
↓ Input
↑ Input
\newcommand*{\gender@male}{\Square}
\newcommand*{\gender@female}{\Square}
↓ Input
11.1 Writing a Class File for a Form 333
The user commands redefine these internal commands. In the first case:
↑ Input
\newcommand*{\male}{%
\renewcommand*{\gender@male}{\XBox}%
}
\newcommand*{\female}{%
\renewcommand*{\gender@female}{\XBox}%
}
↓ Input
↑ Input
\newcommand*{\gender}[1]{%
\ifcsdef{gender@#1}%
{\csdef{gender@#1}{\XBox}}
{% unknown option produces an error
\ClassError{simple-form}{Unknown gender `#1'}
{Options: `male', `female'}%
}%
}
↓ Input
This uses the etoolbox commands \ifcsdef and \csdef described in §2.1.1, and
also uses
\ClassError{⟨class-name⟩}{⟨error-message⟩}{⟨help-message⟩} Definition
to display an error message. The first argument is the class name (simple-form
in this case) and the second argument is the error message. The third argument
provides a help message if the user types “h” in TEX’s interactive mode.
What if I later decide to use \CheckedBox instead of \XBox? Alternatively,
I might decide to use a radio button style. To help with code maintenance it’s
better to define commands for the checked and unchecked status and use those
commands for the form data. For example:
↑ Input
\newcommand*{\form@unchecked}{\Square}
\newcommand*{\form@checked}{\XBox}
\newcommand*{\gender@male}{\form@unchecked}
\newcommand*{\gender@female}{\form@unchecked}
\newcommand*{\male}{%
\renewcommand*{\gender@male}{\form@checked}%
}
\newcommand*{\female}{%
\renewcommand*{\gender@female}{\form@checked}%
}
↓ Input
Or
↑ Input
\newcommand*{\gender}[1]{%
\ifcsdef{gender@#1}%
{\csdef{gender@#1}{\form@checked}}
{%
11.1 Writing a Class File for a Form 334
Now there are only one or two lines to change if I want to use different symbols.
For example, to use \CheckedBox instead of \XBox just requires one edit:
\newcommand*{\form@checked}{\CheckedBox} Input
If you can’t find a symbol that suits you, it’s possible to combine symbols using
a command such as \rlap. For example, to make round radio style buttons,
you could use the ifsym package [45] with the geometry option and combine
\BigCircle with \FilledSmallCircle.
↑ Input
\newcommand*{\form@unchecked}{\BigCircle}
\newcommand*{\form@checked}{%
\rlap{\FilledSmallCircle}\BigCircle}
↓ Input
↑ Input
\newcommand*{\form@checked}{%
\rlap{\textifsymbol[ifgeo]{117}}\textifsymbol[ifgeo]{37}}
\newcommand*{\form@unchecked}{\textifsymbol[ifgeo]{37}}
↓ Input
Alternatively, if you want fancier buttons you can use picture drawing code.
The following example creates on and off buttons using tikz with the shadings
and shadows libraries:
↑ Input
\RequirePackage[x11names]{xcolor}
\RequirePackage{tikz}
\usetikzlibrary{shadings}
\usetikzlibrary{shadows}
\newcommand*{\form@unchecked}{%
\resizebox{!}{2ex}%
{%
\begin{tikzpicture}
\path[fill=LightYellow4,circular glow]
(0,0) circle(.5cm);
\path[fill=LightYellow1,
circular glow={fill=LightYellow3}]
(0,0) circle(.35cm);
\end{tikzpicture}%
}%
}
\newcommand*{\form@checked}{%
\resizebox{!}{2ex}%
{%
11.1 Writing a Class File for a Form 335
\begin{tikzpicture}
\path[shade,inner color=LightYellow2,
outer color=LightYellow4,
circular glow] (0,0) circle(.5cm);
\end{tikzpicture}%
}%
}
↓ Input
For example:
↑ Input
\form@layout@checkbox{\gender@male}{Male}
\form@layout@checkbox{\gender@female}{Female}
↓ Input
This means that if, say, you want to change all your check boxes so that the text
is to the left of the check box symbol, then all you need to do is change the
definition of \form@layout@checkbox. Similarly for the fill-in text fields:
\newcommand*{\form@layout@fillin}[3]{#3: \form@fillin{#1}{#2}} Input
For example:
\form@layout@fillin{6em}{\@name}{Name} Input
↑ Input
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{simple-form}[2014/10/11]
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions
\LoadClass[a4paper,12pt]{article}
\RequirePackage{etoolbox}
\RequirePackage{wasysym}
\newcommand*{\form@fillin}[2]{%
\makebox[#1][l]{\rlap{#2}\hrulefill}%
11.1 Writing a Class File for a Form 336
\newcommand*{\form@checked}{\XBox}
\newcommand*{\form@unchecked}{\Square}
\newcommand*{\form@layout@checkbox}[2]{#1 #2}
\newcommand*{\form@layout@fillin}[3]{#3: \form@fillin{#1}{#2}}
\newcommand*\@name{}
\newcommand*{\name}[1]{\renewcommand*{\@name}{#1}}
\newcommand*{\gender@male}{\form@unchecked}
\newcommand*{\gender@female}{\form@unchecked}
\newcommand*{\gender}[1]{%
\ifcsdef{gender@#1}%
{\csdef{gender@#1}{\form@checked}}
{%
\ClassError{simple-form}{Unknown gender `#1'}%
{Options: `male', `female'}%
}%
}
\newcommand{\makeform}{%
\form@layout@fillin{8em}{\@name}{Name}\qquad
\form@layout@fillin{12em}{\@date}{Date}
\par
\bigskip
\par
\form@layout@checkbox{\gender@male}{Male}\qquad
\form@layout@checkbox\gender@female{Female}
}
\endinput
↓ Input
An example document:
↑ Input
\documentclass{simple-form}
\name{Mabel Canary}
\gender{female}
\begin{document}
\makeform
\end{document}
↓ Input
The result is shown in Figure 11.1. You can download or view this example.
Output
Name: Mabel Canary Date: October 12, 2014
2 Male 4 Female
Figure 11.1 A Simple Form with Two Fill-In Areas and Two Check Boxes
11.1 Writing a Class File for a Form 337
The above example doesn’t test if \gender has already been used, so it’s
possible for a user to do:
\gender{male}\gender{female} Input
which would cause both boxes to be checked. If you want to prevent this from
happening you could either produce an error message if the command is used
more than once or make each subsequent use of the command reset the boxes
before setting the new choice.
Here’s a possible way of implementing the first case. It uses the \let assign-
ment described in §2.1.1.
↑ Input
\newcommand*{\@gendererror}[1]{%
\ClassError{simple-form}
{\string\gender\space may only be used once}
{}%
}
\newcommand*{\gender}[1]{%
\let\gender\@gendererror
\ifcsdef{gender@#1}%
{\csdef{gender@#1}{\form@checked}}
{%
\ClassError{simple-form}{Unknown gender `#1'}%
{Options: `male', `female'}%
}%
}
↓ Input
This works as follows: the first time \gender is used, it redefines itself to have
the same definition as \@gendererror, so the next time \gender is used, it’s
now equivalent to \@gendererror, which ignores its argument and produces an
error message. (\string is a TEX primitives that converts the following control
sequence into a list of characters, which provides an easy way of printing the
control sequence in the transcript file or console.)
Here’s a possible way of implementing the second case that defines a reset
command:
↑ Input
\newcommand*{\@resetgender}{%
\renewcommand*{\gender@male}{\form@unchecked}%
\renewcommand*{\gender@female}{\form@unchecked}%
}
\newcommand*{\gender}[1]{%
\@resetgender
\ifcsdef{gender@#1}%
{\csdef{gender@#1}{\form@checked}}
{%
\ClassError{simple-form}{Unknown gender `#1'}%
{Options: `male', `female'}%
}%
}
↓ Input
11.1 Writing a Class File for a Form 338
↑ Input
\newcommand*{\male}{%
\renewcommand*{\gender@female}{\form@unchecked}
\renewcommand*{\gender@male}{\form@checked}
}
\newcommand*{\female}{%
\renewcommand*{\gender@male}{\form@unchecked}
\renewcommand*{\gender@female}{\form@checked}
}
↓ Input
However the other method is neater for a large set of check boxes. If you do
have many choices, you may find it easier to use a list-based approach. For
example, suppose I want to produce the following:
A convenient user command might be called, say, \project where the argu-
ment may be one of: cookies, cakes, chocolates or raygun. The internal com-
mands are called \project@⟨label⟩ where ⟨label⟩ is the argument of \project.
These commands can be reset using:
\csdef{project@⟨label⟩}{\form@unchecked} Input
These can be wrapped up in two commands that each take the label as the
argument:
↑ Input
\newcommand*{\reset@project}[1]{%
\csdef{project@#1}{\form@unchecked}%
}
\newcommand*{\set@project}[1]{%
\ifcsdef{project@#1}
{\csdef{project@#1}{\form@checked}}
{%
\ClassError{simple-form}{Unknown project `#1'}{}%
}%
}
↓ Input
It’s also useful to provide a command to use the internal \project@⟨label⟩ com-
mand:
↑ Input
\newcommand*{\use@project}[1]{%
\ifcsdef{project@#1}{\csuse{project@#1}}{\form@unchecked}%
}
↓ Input
11.1 Writing a Class File for a Form 339
This will produce an unchecked box if the label hasn’t been defined, which
means that the internal commands don’t need to be initialised if the user wants
a blank form to fill in by hand.
Here’s a comma-separated lists where each element contains two groups. The
first is the label that will be used in the argument of \project and the second
is the text to appear next to the check box in the form:
↑ Input
\newcommand*{\@projectlist}{%
{cookies}{Mind-Controlling Cookies},%
{cakes}{Telepathic Cakes},%
{chocolates}{Exploding Chocolates},%
{raygun}{Ray Gun}%
}
↓ Input
↑ Input
\@for\this@element:=\@projectlist\do{%
\reset@project\this@element
} 8
↓ Input
↑ Input
\@for\this@element:=\@projectlist\do{%
\expandafter\reset@project\this@element
} 8
↓ Input
↑ Input
\newcommand*{\reset@project}[2]{%
\csdef{project@#1}{\form@unchecked}%
}
↓ Input
11.1 Writing a Class File for a Form 340
which does ⟨first⟩ and discards ⟨second⟩. This requires \expandafter to expand
\this@element before applying \@firstoftwo:
↑ Input
\@for\this@element:=\@projectlist\do{%
\reset@project{\expandafter\@firstoftwo\this@element}%
}
↓ Input
A similar method can be used to display the check boxes and their associated
text within the form. There is an analogous LATEX kernel command that grabs
the second argument and discards the first:
\@secondoftwo{⟨first⟩}{⟨second⟩} Definition
Here’s a simple example that just displays the check boxes with their associated
text without any tabulation:
↑ Input
\@for\this@element:=\@projectlist\do{%
\use@project{\expandafter\@firstoftwo\this@element}% check box
\space
\expandafter\@secondoftwo\this@element
\qquad
}
↓ Input
↑ Input
\@for\this@element:=\@projectlist\do{%
\form@layout@checkbox
{\use@project{\expandafter\@firstoftwo\this@element}}% check box
{\expandafter\@secondoftwo\this@element}% text
\qquad
}
↓ Input
This can be converted into a tabular environment but we need a way to track
which column we’re in. One way to do this is to define a register (recall §2.1.3).
↑ Input
% initialise
\newcount\form@columncount
\form@columncount=1\relax
\def\form@precolumn{}%
% layout check boxes and text:
\begin{tabular}{ll}
\@for\this@element:=\@projectlist\do{%
\global\let\this@element\this@element
\form@precolumn
\form@layout@checkbox
{\use@project{\expandafter\@firstoftwo\this@element}}%
{\expandafter\@secondoftwo\this@element}%
\global\advance\form@columncount by 1\relax
11.1 Writing a Class File for a Form 341
\ifnum\form@columncount>2\relax
\global\form@columncount=1\relax
\gdef\form@precolumn{\\}%
\else
\gdef\form@precolumn{&}%
\fi
}%
\end{tabular}%
↓ Input
(\global is required because of the local scoping effect of tabular cells.) This
uses a similar method to those discussed in §2.7.5.
If you are likely to have more than one group of check boxes, then it makes
more sense to create generic commands. First, we need generic versions of the
above \reset@project, \set@project and \use@project where the first argu-
ment is the element label (such as cakes) and the second argument is the block
label (such as project):
↑ Input
\newcommand*{\reset@element}[2]{%
\csdef{#2@#1}{\form@unchecked}%
}
\newcommand*{\set@element}[2]{%
\ifcsdef{#2@#1}%
{\csdef{#2@#1}{\form@checked}}%
{%
\ClassError{simple-form}{Unknown #2 `#1'}{}%
}%
}
\newcommand*{\use@element}[2]{%
\ifcsdef{#2@#1}{\csuse{#2@#1}}{\form@unchecked}%
}
↓ Input
So now instead of
\reset@project{⟨label⟩} Input
I need to use
\reset@element{⟨label⟩}{project} Input
and so on. It’s also convenient to provide a command that can iterate over the
{⟨label⟩}{⟨text⟩} list (such as \@projectlist) for the block:
↑ Input
\newcommand*{\for@block}[3]{%
\ifcsdef{@#2list}%
{%
\expandafter\@for\expandafter
#1\expandafter:\expandafter=\csname @#2list\endcsname\do{#3}%
}%
{%
\ClassError{simple-form}{Unknown block `#2'}{}%
}%
}
↓ Input
11.1 Writing a Class File for a Form 342
(The \expandafters are required because the list control sequence provided
by \csname @#2list\endcsname needs to be expanded to the actual control se-
quence \@⟨block-label⟩list, for example \@projectlist, before \@for tries to
iterate over it.) This has the syntax:
\for@block{⟨cs⟩}{⟨block-label⟩}{⟨body⟩} Definition
where ⟨cs⟩ is assigned to the {⟨label⟩}{⟨text⟩} element for the current iteration.
All elements within a block can be reset using \reset@block, which is defined
as:
↑ Input
\newcommand*{\reset@block}[1]{%
\for@block{\this@element}{#1}%
{%
\reset@element{\expandafter\@firstoftwo\this@element}{#1}%
}%
}
↓ Input
↑ Input
\newcommand*{\project}[1]{%
\reset@block{project}%
\set@element{#1}{project}%
}
↓ Input
↑ Input
\newcount\form@columncount
\newcommand*{\form@block}[1]{%
\def\form@precolumn{}%
\form@columncount=1\relax
\begin{tabular}{ll}
\for@block{\this@element}{#1}%
{%
\global\let\this@element\this@element
\form@precolumn
\form@layout@checkbox
{\use@element{\expandafter\@firstoftwo\this@element}{#1}}%
{\expandafter\@secondoftwo\this@element}%
\global\advance\form@columncount by 1\relax
\ifnum\form@columncount>2\relax
\global\form@columncount=1\relax
\gdef\form@precolumn{\\}%
\else
\gdef\form@precolumn{&}%
\fi
}%
\end{tabular}%
}
↓ Input
11.1 Writing a Class File for a Form 343
This is hard-coded for two columns, but it would be more flexible to allow an
arbitrary number of columns. For example if the command had the syntax
\form@block{⟨block-label⟩}{⟨columns⟩} Definition
can now have the total column count replaced with #2:
\ifnum\form@columncount>#2\relax Input
However the column specifier argument for the tabular environment is a little
more complicated as it now requires #2 lots of l (or whatever alignment specifier
you want).
Recall TEX’s \loop command from §2.7.4 and the hook management com-
mands from §2.1.2. These can be used to generate the argument for the tabular
environment:
↑ Input
% initialise
\def\form@columnargs{}%
\form@columncount=0\relax
% iterate #2 times
\loop
\appto\form@columnargs{l}%
\advance\form@columncount by 1\relax
\ifnum\form@columncount<#2
\repeat
↓ Input
This will store the column specifiers in \form@columnargs which can now be
used in the tabular environment argument:
\begin{tabular}{\form@columnargs} Input
↑ Input
\newcount\form@columncount
\newcommand*{\form@block}[2]{%
\def\form@columnargs{}%
\form@columncount=0\relax
\loop
\appto\form@columnargs{l}%
\advance\form@columncount by 1\relax
\ifnum\form@columncount<#2
\repeat
\def\form@precolumn{}%
\form@columncount=1\relax
11.1 Writing a Class File for a Form 344
\begin{tabular}{\form@columnargs}
\for@block\this@element{#1}%
{%
\global\let\this@element\this@element
\form@precolumn
\form@layout@checkbox
{\use@element{\expandafter\@firstoftwo\this@element}{#1}}%
{\expandafter\@secondoftwo\this@element}%
\global\advance\form@columncount by 1\relax
\ifnum\form@columncount>#2\relax
\global\form@columncount=1\relax
\gdef\form@precolumn{\\}%
\else
\gdef\form@precolumn{&}%
\fi
}%
\end{tabular}%
}
↓ Input
The form check box elements are now much simpler to define:
↑ Input
\newcommand*{\@genderlist}{{male}{Male},{female}{Female}}
\newcommand*{\gender}[1]{%
\reset@block{gender}%
\set@element{#1}{gender}%
}
\newcommand*{\@projectlist}{%
{cookies}{Mind-Controlling Cookies},%
{cakes}{Telepathic Cakes},%
{chocolates}{Exploding Chocolates},%
{raygun}{Ray Gun}%
}
\newcommand*{\project}[1]{%
\reset@block{project}%
\set@element{#1}{project}%
}
↓ Input
↑ Input
\reset@block{project}
\newcommand*{\project}[1]{%
\set@element{#1}{project}%
}
↓ Input
↑ Input
\documentclass{simple-form}
\name{Mabel Canary}
\date{2014-10-13}
\gender{female}
\project{cakes}
\icecream{vanilla}
\icecream{fudge}
\icecream{other}
\begin{document}
\makeform
\end{document}
↓ Input
which both checks the “Other” box and fills in the area, as shown in Figure 11.3.
You can download or view a solution to this exercise.
Output
Name: Mabel Canary Date: 2014-10-13
2 Male 4 Female
Which project would you like to enrol on? (Tick one box.)
If you have a large text area that needs to be filled in, you may prefer to
use an environment to collect the information. For example, instead of creating
a command to specify, say, a project description:
\projectdescription{⟨Several paragraphs of text⟩} Input
Output
Name: Mabel Canary Date: 2014-10-13
2 Male 4 Female
Which project would you like to enrol on? (Tick one box.)
↑ Input
\newcommand{\@projectdescription}{}
\newcommand{\projectdescription}[1]{%
\renewcommand{\@projectdescription}{#1}%
}
↓ Input
↑ Input
\begin{ProjectDescription}
⟨Several paragraphs of text⟩
\end{ProjectDescription}
↓ Input
This is more complicated to define, as you can’t simply gather the contents of
an environment when you use \newenvironment. There are a number of ways
to achieve this.
B Ifstored
the environment contents are being gathered so that they can then be
in a command definition, then the limitations applied to command
definitions also apply to the environment contents. This includes the usual prob- [FAQ: Why doesn’t
lems with verbatim code in a command argument. verbatim work
The collect package [77] provides the collectinmacro environment: within. . . ?]
\begin{collectinmacro}{⟨macro⟩}{⟨before⟩}{⟨after⟩}
⟨body⟩ Definition
\end{collectinmacro}
This defines the command ⟨macro⟩ to be ⟨before⟩⟨body⟩⟨after⟩. For example,
↑ Input
\begin{collectinmacro}{\mycommand}{Before. }{ After.}
Some text here.
\end{collectinmacro}
↓ Input
11.1 Writing a Class File for a Form 347
If you want to define an environment that uses this method, you can’t use the
environment form \begin{collectinmacro} and \end{collectinmacro}, but
must instead use the commands \collectinmacro and \endcollectinmacro.
Example:
↑ Input
\newcommand{\@projectdescription}{}
\newenvironment{ProjectDescription}%
{\collectinmacro{@projectdescription}{}{}}%
{\endcollectinmacro}
↓ Input
command. This gathers the contents of the current environment ⟨body⟩ and
applies ⟨cs⟩{⟨body⟩}.
Example:
↑ Input
\newcommand{\@projectdescription}{}
\newcommand{\projectdescription}[1]{%
\gdef\@projectdescription{#1}%
}
\newenvironment{ProjectDescription}%
{\collect@body\projectdescription}%
{}
↓ Input
↑ Input
\begin{ProjectDescription}
This will be an interesting project.
\end{ProjectDescription}
↓ Input
or
\projectdescription{This will be an interesting project.} Input
Note that I had to use \gdef instead of \renewcommand otherwise the change will
be scoped by the encasing environment.
B The \collect@body command uses short internal commands to gather the
environment contents, which means that the environment can’t contain
paragraph breaks. If you want to allow paragraph breaks, you can use an
analogous command provided by the environ package [75]:
\Collect@Body⟨cs⟩ Definition
↑ Input
\newcommand{\@projectdescription}{}
\newcommand{\projectdescription}[1]{%
\gdef\@projectdescription{#1}%
}
\newenvironment{ProjectDescription}%
{\Collect@Body\projectdescription}%
{}
↓ Input
↑ Input
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{sample-form}[2014/11/03]
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions
\LoadClass[a4paper,12pt]{article}
\RequirePackage{environ}
\newcommand*{\form@fillin}[2]{%
\makebox[#1][l]{\rlap{#2}\hrulefill}%
}
\newcommand*{\form@layout@fillin}[3]{#3:
\form@fillin{#1}{#2}}
\newcommand*\@name{}
\newcommand*{\name}[1]{%
\renewcommand*{\@name}{#1}%
}
\newcommand*\@projectdescription{}
\newcommand{\projectdescription}[1]{%
\long\gdef\@projectdescription{#1}%
}
\newenvironment{ProjectDescription}%
{\Collect@Body\projectdescription}{}
\newcommand{\makeform}{%
\section{Applicant Details}
\form@layout@fillin{8em}{\@name}{Name}
\section{Project Description}
\@projectdescription
}
\endinput
↓ Input
11.2 Electronic PDF Forms 349
↑ Input
\documentclass{sample-form}
\name{Mabel Canary}
\begin{ProjectDescription}
This project will be very interesting.
\begin{document}
\makeform
\end{document}
↓ Input
The result is shown in Figure 11.4. You can download or view this example
document.
Output
1 Applicant Details
Name: Mabel Canary
2 Project Description
This project will be very interesting.
This is another paragraph.
Figure 11.4 A Simple Form with a Text Area.
↑ Input
\documentclass{article}
\usepackage{hyperref}
\begin{document}
\begin{Form}
\TextField{Name}\qquad \TextField{Date}
\ChoiceMenu[combo]{Gender}{Male,Female}
\ChoiceMenu[radio]{Project}{cookies,cakes,chocolates,raygun}
\CheckBox{vanilla}
\CheckBox{mint}
\CheckBox{toffee}
\CheckBox{fudge}
\CheckBox[name=guarana]{guaran\'a}
\CheckBox{strawberry}
\CheckBox{raspberry}
\CheckBox{chilli}
\CheckBox{other}
\end{Form}
\end{document}
↓ Input
How the form elements are rendered depends on your PDF viewer. For
example, Figure 11.5 shows this form displayed in Adobe Reader and Figure 11.6
shows the same file displayed in Google Chrome. For me, Google Chrome
works best (except when it hangs) as there’s no native 64 bit Linux version of
Adobe Reader, which means I have to run Adobe Reader on Wine and some of
the interactive elements cause it to crash. If you use another operating system,
you may find that the Adobe PDF viewers, such as Adobe Reader, produce
suitable results.
Unfortunately I can’t find any other Linux-based PDF viewers that render
this example correctly. Figure 11.7 shows the same PDF file viewed in Okular.
This renders most of the interactive elements correctly, but fails on the group
of radio buttons. Only the first radio button is correctly rendered as an inter-
active element. The other radio buttons appear as non-interactive open single
quote marks. (These appear to be the decorative open quote mark { from the
ZapfDingbats font, \ding{123}.) A similar problem occurs with Evince and with
the document viewer that comes with TeXworks. Other PDF viewers, such as
Sumatra or the Linux version of Foxit (Figures 11.8 and 11.9), don’t recognise
any of the interactive elements (but Foxit on Windows does show the interactive
elements, see Figure 11.10). Therefore, you will need to take care about your
choice of PDF viewer if you want to create an electronic PDF form (and the
PDF viewer for any users of your form).
11.2 Electronic PDF Forms 352
You may have noticed from the above example that each field’s label (such as
“Name” or “Project”) is placed to the left of the interactive element (or elements,
in the case of the radio group). This layout is governed by:
\LayoutTextField{⟨label⟩}{⟨field⟩} Definition
for check boxes. These all default to ⟨label⟩ ⟨field⟩. Since the space is a regular
breakable space, this allowed a line break to occur between the label “raspberry”
and its associated check box (as can be seen, for example, in Figure 11.5). To
prevent this, \LayoutCheckField can be redefined to use a non-breakable space:
\renewcommand*{\LayoutCheckField}[2]{#1~#2} Input
Alternatively, if you also want the check box and label swapped round, so that
the label is on the right:
\renewcommand*{\LayoutCheckField}[2]{#2~#1} Input
Note that \LayoutChoiceField just controls the layout of the label for the
list of choices and the choice list element or group of elements. In the case of
a group of radio buttons, each radio button has a fixed layout with the radio
button label first followed by a space and then the radio button. There’s no user
level macro for changing this layout.
The actual field display is given by:
\MakeRadioField{⟨width⟩}{⟨height⟩} Definition
for choice lists. These commands all default to creating a blank area of the
given ⟨width⟩ and ⟨height⟩. (This is how, in Figure 11.9, the area taken up by
the interactive elements appears as a blank space even though the fields aren’t
rendered. The actual rendering of the field is to some extent determined by the
PDF viewer.)
The layout of the text on push buttons is determined by
\MakeButtonField{⟨text⟩} Definition
\DefaultHeightofReset Definition
for the default width of text fields (3cm). Note that these are all macros not
lengths, so you need to use \renewcommand to change them. These defaults
are used for fields that don’t have the height or width options specified (in the
optional argument of the field commands, such as \CheckBox).
Suppose now I want the check boxes from Example 58 to appear in a tabular
layout, so that they appear more like those from Figure 11.2. A first attempt
might look something like:
↑ Input
\renewcommand*{\LayoutCheckField}[2]{#2 #1}
Which ice cream flavours do you like? (Tick all that apply.)
\begin{center}
\begin{tabular}{lll}
\CheckBox{vanilla} &
\CheckBox{mint} &
\CheckBox{toffee}\\
\CheckBox{fudge} &
\CheckBox[name=guarana]{guaraná} &
\CheckBox{strawberry}\\
\CheckBox{raspberry}&
\CheckBox{chilli} &
\CheckBox{other}
\end{tabular}
\end{center}
↓ Input
11.2 Electronic PDF Forms 357
However, this produces the form shown in Figure 11.11. The check boxes
are far too narrow. Recall from above that the default width of the check boxes
is given by \DefaultWidthofCheckBox, which is initialised to \baselineskip.
One of the peculiarities of the tabular environment is that it temporarily sets the
value of \baselineskip to 0 pt. This means that check boxes default to zero
width when placed inside a tabular environment. Here’s a second attempt that
changes the defaults to depend on the font size instead:
↑ Input
\renewcommand*{\LayoutCheckField}[2]{#2 #1}
\renewcommand*{\DefaultWidthofCheckBox}{2ex}
\renewcommand*{\DefaultHeightofCheckBox}{2ex}
Which ice cream flavours do you like? (Tick all that apply.)
\begin{center}
\begin{tabular}{lll}
\CheckBox{vanilla} &
\CheckBox{mint} &
\CheckBox{toffee}\\
\CheckBox{fudge} &
\CheckBox[name=guarana]{guaraná} &
\CheckBox{strawberry}\\
\CheckBox{raspberry}&
\CheckBox{chilli} &
\CheckBox{other}
\end{tabular}
\end{center}
↓ Input
This produces Figure 11.12, which has check boxes with a better width, but the
heights are too large causing them to overlap. In fact, they are higher than
the specified 2 ex given in the redefinition of \DefaultHeightofCheckBox. This
seems to be caused by the tabular environment stretching the boxes to fill the
available height, but this occurs outside of the box created by \MakeCheckField.
Here’s a third attempt that explicitly sets the width and height within the
definition of \LayoutCheckField using a \parbox:
↑ Input
\renewcommand*{\LayoutCheckField}[2]{#2 #1}
\renewcommand*{\DefaultWidthofCheckBox}{2ex}
\renewcommand*{\DefaultHeightofCheckBox}{2ex}
\renewcommand*{\LayoutCheckField}[2]{%
\parbox[\DefaultHeightofCheckBox]%
{\DefaultWidthofCheckBox}{#2} #1}
Which ice cream flavours do you like? (Tick all that apply.)
\begin{center}
\begin{tabular}{lll}
\CheckBox{vanilla} &
\CheckBox{mint} &
\CheckBox{toffee}\\
\CheckBox{fudge} &
\CheckBox[name=guarana]{guaraná} &
\CheckBox{strawberry}\\
\CheckBox{raspberry}&
\CheckBox{chilli} &
11.2 Electronic PDF Forms 358
\CheckBox{other}
\end{tabular}
\end{center}
↓ Input
This produces the result shown in Figure 11.13, which now has square check
boxes. Unfortunately this doesn’t take into account the height or width options
that may override the default sizes. In this case, that’s not an issue as I want
all the check boxes to be the same size. If you want larger check boxes in
another area of the form, you can localise the effects of the above redefinition
of \LayoutCheckField by scoping it. For example, by placing it inside the start
of the center environment before the start of the tabular environment:
↑ Input
\begin{center}
\renewcommand*{\LayoutCheckField}[2]{%
\parbox[\DefaultHeightofCheckBox]%
{\DefaultWidthofCheckBox}{#2} #1}%
\begin{tabular}{lll}
↓ Input
The other possibility is to use the internal commands \Fld@width and \Fld@height,
which store the width and height for the check box:
\parbox[\Fld@height]{\Fld@width{#2} #1} Input
However, be careful about using internal commands that aren’t part of the LATEX
kernel as they may change with future versions. Also remember that internal
commands must be placed inside a class or package or should be enclosed
inside \makeatletter. . . \makeatother.
Figure 11.11 First Attempt at Laying Out Check Boxes in Rows and Columns
Figure 11.12 Second Attempt at Laying Out Check Boxes in Rows and Columns
Figure 11.13 Third Attempt at Laying Out Check Boxes in Rows and Columns
Chapter 12
Charts
Charts and diagrams can be produced in any graphical application that can
export the image to a format that LATEX can input. However it is also possible
to write LATEX code to generate the diagram. This has the advantage in that the
fonts used in the diagram match those used in the rest of the document, but it’s
more complicated and can significantly slow the document build time.
This chapter describes LATEX packages to generate various charts you may
need in your administrative work. If you prefer to use a graphics application to
generate a chart you can input the exported image using the graphicx package,
as described in Volume 1 [93, §6], but make sure, if possible, that you export
your image using a vector graphics format (such as PDF or EPS1 ) rather than
a bitmap (such as PNG or JPEG).
There are many LATEX packages available, ranging from general drawing
packages, such as tikz or pstricks, to packages designed for specific types of charts.
See, for example, the diagram topic and sub-topics such as the diagram-block topic
(block diagrams) and diagram-ctrl topic (control diagrams), as well as the genchart
topic (bar- or pie-charts), planning topic (timelines and schedules) and gantt topic.
There’s also the pgf-tikz topic (for packages that use pgf/tikz) and the pstricks topic
(for packages that use pstricks).
B With the increase in computer graphics over the last couple of decades,
there has been a corresponding rise in jazzed-up three-dimensional charts
designed to impress the lay person. Such charts can be found from glossy
brochures to company annual reports or news programs, but while these im-
ages may appear visually appealing, they distort the data and can produce a
misleading impression. As a chartered mathematician I can’t condone such de-
ception, whether done by design or accident, so I’m not going to show you how
to produce fancy effects.
B Be careful if you have large numbers or you may get the “Dimension too
large” TEX error. If you are dealing with very large values (in terms of
magnitude), you may be better off using a custom data-handling tool to generate
the image rather than trying to use TEX.
↑ Input
\usetikzlibrary{arrows.meta}
\usetikzlibrary{shapes.geometric}
↓ Input
1 Note that the PDF and EPS file formats also support bitmaps so, if possible, check the settings on
whatever application you use to create the image files to see if it uses a vector graphics format.
If the image appears fuzzy when you magnify it, then it’s most likely a bitmap.
2 These are fairly new libraries, so you’ll need an up-to-date version of pgf/tikz in order to use them.
359
12.1 Flow Charts 360
Recall from §7.5, that within the tikzpicture environment, you can use
\path[⟨path options⟩] (⟨position⟩) node[⟨node options⟩] (⟨node name⟩)
Definition
{⟨text⟩};
to position a node or you can use the shortcut:
\node[⟨node options⟩] (⟨node name⟩) {⟨text⟩}; Definition
Alternatively, if you use the positioning library, the node can be placed rela-
tive to another node using one of the following ⟨key⟩=⟨value⟩ options:
above Place this node above the location specified in the ⟨value⟩.
below Place this node below the location specified in the ⟨value⟩.
left Place this node to the left of the location specified in the ⟨value⟩.
right Place this node to the right of the location specified in the ⟨value⟩.
above left Place this node above left of the location specified in the ⟨value⟩.
above right Place this node above right of the location specified in the ⟨value⟩.
below left Place this node below left of the location specified in the ⟨value⟩.
below right Place this node below right of the location specified in the ⟨value⟩.
For each of these options, the ⟨value⟩ part may simply be in the form ⟨shift⟩
or in the form ⟨shift⟩ of ⟨label⟩, where shift may be a dimension (or an ex-
pression that evaluates to a dimension) or a number (in which case the unit is
the tikz unit currently in use). If of ⟨label⟩ is present then the shift is relative
to the node identified by ⟨label⟩. If the ⟨shift⟩ part is omitted, the default node
distance is used. For further details, and for details of other placement options,
see the pgf manual [102].
Example:
↑ Input
\begin{tikzpicture}
\node (start) {Ray-gun doesn't work};
\node[below=of start] (query) {Is it charged?};
\node[right=of query] (recharge) {Recharge battery};
\node[below=of query] (repair) {Repair ray-gun};
\end{tikzpicture}
↓ Input
Output
Example:
↑ Input
\begin{tikzpicture}
\node[draw,fill=red!30] (start) {Ray-gun doesn't work};
\node[draw,fill=yellow,below=of start] (query) {Is it charged?};
\node[draw,fill=green!40,right=of query] (recharge) {Recharge battery};
\node[draw,fill=green!40,below=of query] (repair) {Repair ray-gun};
\end{tikzpicture}
↓ Input
The rectangles can be given round corners using the rounded corners op-
tion. For example:
↑ Input
If you want to change the node shape, there are a number of shapes provided
by various tikz libraries. For example, the diamond shape is provided by the
shapes.geometric library. The shape name is given in the ⟨node options⟩. For
example:
↑ Input
The default aspect ratio of the diamond width and height is 1. You can change
this using the aspect option. For example:
↑ Input
\node[diamond,aspect=2,draw,fill=yellow,below=of start]
(query) {Is it charged?};
↓ Input
For example:
\draw (start) -- (query); Input
Arrow heads can be added to the start and end of the line using the option
⟨start arrow⟩-⟨end arrow⟩, where ⟨start arrow⟩ and ⟨end arrow⟩ indicate the
type of arrow head. The simplest arrow types are given by < for an arrow head
pointing to the start and > for an arrow head pointing to the end. The ⟨start
arrow⟩ or ⟨end arrow⟩ may be omitted if no arrow head is needed at the start
or end, respectively.
Example:
↑ Input
\begin{tikzpicture}
\node[rounded corners,draw,fill=red!30] (start)
{Ray-gun doesn't work};
\node[diamond,aspect=2,draw,fill=yellow,below=of start]
(query) {Is it charged?};
\node[draw,fill=green!40,rounded corners,right=of query]
(recharge) {Recharge battery};
\node[draw,fill=green!40,rounded corners,below=of query]
(repair) {Repair ray-gun};
% draw in arrows:
\draw[->] (start) -- (query);
\draw[->] (query) -- (recharge);
\draw[->] (query) -- (repair);
\end{tikzpicture}
↓ Input
This places a node (with the text “No”) above and midway along the line between
the query and recharge nodes.
Example 59. Flow Chart
This example builds on the above. The arrows.meta library is loaded in order
to use the Triangle[] arrow tip. This can be used by replacing the > arrow tip
specifier in the optional argument to \draw. For example:
\draw[-{Triangle[]}] (start) -- (query); Input
Alternatively, the > arrow tip specifier can be set to Triangle[] for the given
scope. For example:
\begin{tikzpicture}[>={Triangle []}] Input
This helps to ensure consistent arrow tips within the picture and means that you
only need to edit one line if you decide to change the arrow tips (for example,
from Triangle[] to Stealth[]).
Common node settings can be specified using every node/.style={⟨node
options⟩} within the optional argument of the tikzpicture environment (to apply
to all nodes within the environment) or the effect can be scoped using the scope
environment (recall §7.5). This method can be used for the common settings
for the recharge and repair nodes.
In addition, a thicker line width is set using the ultra thick option.
↑ Input
\documentclass{article}
\begin{document}
\begin{tikzpicture}[ultra thick,>={Triangle[]}]
\node[rounded corners,draw,fill=red!30] (start)
{Ray-gun doesn't work};
\node[diamond,aspect=2,draw,fill=yellow,below=of start]
(query) {Is it charged?};
\begin{scope}[every node/.style={draw,fill=green!40,rounded corners}]
\node[right=of query] (recharge) {Recharge battery};
\node[below=of query] (repair) {Repair ray-gun};
\end{scope}
\draw[->] (start) -- (query);
\draw[->] (query) -- (recharge) node[midway,above] {No};
\draw[->] (query) -- (repair) node[midway,right] {Yes};
\end{tikzpicture}
\end{document}
↓ Input
Note that the last three lines of the tikzpicture environment above can also have
the arrow tips automatically added through the use of the scope environment:
↑ Input
\begin{scope}[->]
\draw (start) -- (query);
\draw (query) -- (recharge) node[midway,above] {No};
12.2 Pie Charts 364
This produces the image shown in Figure 12.4. You can download or view
this example.
Output
Ray-gun doesn’t work
No
Is it charged? Recharge battery
Yes
Repair ray-gun
rotateouter Rotate the outer labels so that they are aligned with the pie chart
radial axis.
3 The licence is unknown and therefore has to be assumed to be non-free.
12.2 Pie Charts 365
The optional argument ⟨condition⟩ is the same as that for \DTLforeach, ⟨db-
name⟩ is the label uniquely identifying the database, and ⟨assign list⟩ is a comma-
separated list of ⟨cmd⟩=⟨col-label⟩ pairs, the same as the penultimate argument
of \DTLforeach. The remaining argument ⟨settings⟩ is a key=value list. The
variable key must be present, but the remaining keys may be omitted.
variable The command to use (as specified in ⟨assign list⟩) that contains
the data to be used to construct the pie chart. (Required.)
start The starting angle (degrees) of the first segment. The default is
0.
radius The radius of the pie chart. The default is 2 cm. This sets the
length \DTLradius.
innerratio The distance from the centre of the pie chart to the point where
the inner labels are placed is given by this value multiplied by
the radius. This must come after radius, if the radius also needs
to be set. The default is 0.5.
inneroffset The distance from the centre of the pie chart to the point where
the inner labels are placed. This may be used instead of innerratio.
If inneroffset is omitted, the innerratio is used.
outerratio The distance from the centre of the pie chart to the point where
the outer labels are placed is given by this value multiplied by
the radius. This must come after radius, if the radius also needs
to be set. The default is 1.25.
outeroffset The distance from the centre of the pie chart to the point where
the outer labels are placed. This may be used instead of outerratio.
If outeroffset is omitted, the outerratio is used.
cutawayratio The distance from the centre of the pie chart to the point of
cutaway segments is given by this value multiplied by the ratio.
This must come after radius, if the radius also needs to be set.
The default is 0.2.
cutawayoffset The distance from the centre of the pie chart to the point of
cutaway segments. This may be used instead of cutawayratio.
If cutawayoffset is omitted, the cutawayratio value is used.
cutaway The list of cutaway segments. This should be a comma-separated
list of individual numbers, or number ranges (separated by a
dash). For example, cutaway={1,3} will separate the first and
third segments from the rest of the pie chart, whereas cutaway
={1-3} will separate the first three segments. If omitted, the pie
chart will be whole with no cutaway segments.
innerlabel The inner label for the segments. The value may contain any
of the commands assigned in ⟨assign list⟩. The default is the
same as the value of the variable key.
outerlabel The outer label for the segments. The value may contain any of
the commands assigned in ⟨assign list⟩. The default is empty.
rotateinner This is a boolean key. If true, the inner labels are rotated so
that they are aligned with the pie chart radial axis.
12.2 Pie Charts 366
rotateouter This is a boolean key. If true, the outer labels are rotated so
that they are aligned with the pie chart radial axis.
The datapie package predefines colours for the first eight segments of the
pie chart. If these don’t suit your requirements, or if you have more than eight
rows of data, you can set the colour for a given segment using:
\DTLsetpiesegmentcolor{⟨n⟩}{⟨colour⟩} Definition
where ⟨n⟩ is the segment index (starting from 1) and ⟨colour⟩ is the colour, as
used in commands like \color.
There are two commands provided that can be used within the inner or
outer labels:
\DTLpievariable Definition
This command is set to the percentage value for the current segment. The
value is rounded to ⟨n⟩ digits, where ⟨n⟩ is given by the counter DTLpieroundvar.
Example 60. An Example Pie Chart (datapie package)
Recall the sample booklist.csv file. Suppose, for some reason, I want to create
a pie chart that displays the price for each book. The database contains 10 rows,
so 10 segment colours need to be defined. A pie chart can be drawn as follows:
↑ Input
\documentclass{article}
\usepackage[x11names]{xcolor}
\usepackage{datapie}
\DTLloaddb{books}{booklist.csv}
\DTLsetpiesegmentcolor{1}{Aquamarine1}
\DTLsetpiesegmentcolor{2}{Azure2}
\DTLsetpiesegmentcolor{3}{Burlywood3}
\DTLsetpiesegmentcolor{4}{CadetBlue2}
\DTLsetpiesegmentcolor{5}{Chartreuse3}
\DTLsetpiesegmentcolor{6}{Salmon1}
\DTLsetpiesegmentcolor{7}{DeepPink1}
\DTLsetpiesegmentcolor{8}{Goldenrod1}
\DTLsetpiesegmentcolor{9}{Honeydew1}
\DTLsetpiesegmentcolor{10}{Plum3}
\begin{document}
\DTLpiechart{%
variable=\ThePrice,%
innerratio=0.4,%
innerlabel={\pounds\ThePrice},%
rotateinner}%
{books}% database name
{\ThePrice=price}% assignment list
\end{document}
↓ Input
12.2 Pie Charts 367
Output
£11.99
9.9
£1
£12
9
9.9
9
.99
£1
£18.9
9 £10.99
.99
£14 9
.9
£5
8
.9
£
9
£5
.99
Figure 12.5 An Example Pie Chart (datapie package)
This produces the chart shown in Figure 12.5. However, this isn’t particularly
informative. The book titles could be added as an outer label, but as some of the
titles are quite long, this would result in a rather messy chart. Instead, it would
be neater to have a legend or key. The current text colour can be switched to
the colour of a given segment using:
\DTLdopiesegmentcolor{⟨n⟩} Definition
where ⟨n⟩ is the segment index. This is a declaration that internally calls \color.
Alternatively, you can use
\DTLdocurrentpiesegmentcolor Definition
which sets the colour for the current segment. This may be used inside a
\DTLforeach loop:
↑ Input
\begin{tabular}{ll}
\DTLforeach*{books}{\TheTitle=title}%
{%
\DTLiffirstrow{}{\\}%
\DTLdocurrentpiesegmentcolor\rule{10pt}{10pt} & \TheTitle
}
\end{tabular}
↓ Input
Recall from Volume 1 [93, §4.7] that the tabular environment is a form of box.
The pie chart created using \DTLpiechart is also a box, so the two can be placed
beside each other, however you might need to adjust the vertical alignment. The
complete document is as follows:
↑ Input
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[x11names]{xcolor}
\usepackage{datapie}
\DTLloaddb{books}{booklist.csv}
\DTLsetpiesegmentcolor{1}{Aquamarine1}
\DTLsetpiesegmentcolor{2}{Azure2}
\DTLsetpiesegmentcolor{3}{Burlywood3}
\DTLsetpiesegmentcolor{4}{CadetBlue2}
\DTLsetpiesegmentcolor{5}{Chartreuse3}
\DTLsetpiesegmentcolor{6}{Salmon1}
\DTLsetpiesegmentcolor{7}{DeepPink1}
\DTLsetpiesegmentcolor{8}{Goldenrod1}
\DTLsetpiesegmentcolor{9}{Honeydew1}
\DTLsetpiesegmentcolor{10}{Plum3}
\begin{document}
% pie chart:
\DTLpiechart{%
variable=\ThePrice,%
innerratio=0.4,%
innerlabel={\pounds\ThePrice},%
rotateinner}%
{books}% database name
{\ThePrice=price}% assignment list
\qquad% add some horizontal space
% legend:
\begin{tabular}[b]{ll}
\DTLforeach*{books}{\TheTitle=title}%
{%
\DTLiffirstrow{}{\\}%
\DTLdocurrentpiesegmentcolor\rule{10pt}{10pt} &
\TheTitle
}
\end{tabular}
\end{document}
↓ Input
This produces the image shown in Figure 12.6. You can download or view this
document.
Output
The Adventures of Duck and Goose
£11.99
.99
£12
9
£1
9
£5
(If you want the data sorted in descending order of total quantities, you can
append ORDER BY total DESC.)
Create a pie chart that shows the order totals for each book with a legend
that shows the book title and format.
\DTLpiechart uses the tikzpicture environment and there are two hooks avail-
able to add additional picture drawing commands to that environment:
\DTLpieatbegintikz Definition
You can use kpsewhich to check that the package has been successfully in-
stalled:
kpsewhich pgf-pie.sty Shell
This should display the full path to pgf-pie.sty if the file is on TEX’s path
otherwise it displays nothing.
The pgf-pie package provides just one command:
12.2 Pie Charts 370
\pie[⟨options⟩]{⟨list⟩} Definition
which should be placed inside the tikzpicture environment. The ⟨list⟩ argument
should be a comma-separated list of values in the form ⟨number⟩/⟨text⟩ where
⟨number⟩ is the value and ⟨text⟩ is the outer label for the segment.
The optional argument ⟨options⟩ is a key=value list where the following keys
are available:
pos Sets the centre of the chart to the value {⟨x⟩,⟨y⟩}. The default
is the origin.
rotate Rotates the chart by the given number of degrees.
radius Sets the radius of the chart. The default is 3.
color Sets the colours for each segment. The value should be a comma-
separated list of colours corresponding to each segment or a
single colour, which indicates the colour for the entire chart.
explode Offset the segments. The value may be a single number, in
which case all segments are offset by that amount, or the value
may be a comma-separated list of numbers where each value
is the offset amount for the corresponding segment.
sum The sum of all the data. This can be calculated automatically if
the auto option is set. The default is 100. If the auto option is
off and the actual data sum is less that this value there will be a
missing segment in the chart.
auto A boolean key. If true, the sum of the data is calculated auto-
matically.
after number Indicates the text to place after the number shown in the seg-
ment. The default is \%.
before number Indicates the text to place before the number shown in the seg-
ment.
scale font A boolean key. If true, this scales the font used for the inner
label according to the size of the segment, so large segments
will have large inner labels and small segments will have small
inner labels.
text Indicates how to position the text (outer label). The value may
be one of: label (place the text label outside the segment), pin
(as label but also draws a line from the segment arc to the
label), inside (place the text label inside the segment above the
value) or legend (create a legend). The default is label.
There are some other options as well. See the manual [116] for further details.
Example 61. A Pie Chart (pgf-pie package)
This example has trivial labels A, . . . , E and uses the optional argument to change
some of the pie chart settings. Note that the pgf-pie package automatically loads
tikz.
↑ Input
\documentclass{article}
\usepackage{pgf-pie}
\begin{document}
12.3 Bar Charts 371
\begin{tikzpicture}
\pie[explode={0,0.5,0,0.75,0},% offset segments 2 and 4
color={yellow,cyan,green,pink,orange},% segment colour
text=legend% create a legend
]% settings
{5/A,10/B,15/C,30/D,40/E}% values and labels
\end{tikzpicture}
\end{document}
↓ Input
15%
10%
A
30% B
5%
C
D
E
40%
This can be redefined using \renewcommand or set to empty to use the docu-
ment font. The default definition is \sf, which is an obsolete font changing
command and may cause issues with some classes such as the KOMA-Script
classes. I suggest you redefine \bcfontstyle to use a modern declaration, such
as \sffamily. For example:
\renewcommand*{\bcfontstyle}{\sffamily} Input
where ⟨number⟩ is the bar’s value. The optional argument ⟨options⟩ is a key=
value list with the following keys:
text Sets the text displayed inside the bar (to the right of the 𝑦-axis).
label Sets the label displayed on the left of the 𝑦-axis.
color Sets the bar colour.
plain Hides the bar’s value, which by default is displayed to the right of the
bar.
value Sets the value displayed to the right of the bar. The default is the
⟨number⟩ in the mandatory argument of \bcbar.
You can insert vertical gaps between bars using:
\bcskip[⟨options⟩]{⟨length⟩} Definition
Within the scope of the bchart environment, the standard vertical skips \smallskip,
\medskip and \bigskip are redefined in terms of \bcskip and may be used to
insert small, medium or large gaps. As with \bcskip, these three commands
also have an optional argument. This option only has one key available: label,
which specifies a label.
A “free” label is placed to the left of the 𝑦-axis at the current location using:
\bclabel{⟨text⟩} Definition
where ⟨text⟩ is the label text. This doesn’t add any gap or bar to the chart.
The 𝑥-axis can be labelled using:
\bcxlabel{⟨text⟩} Definition
12.3 Bar Charts 373
Example:
Here’s the data from the pie chart in Example 61 reproduced as a bar chart:
↑ Input
\begin{bchart}[max=40,step=5]
\bcbar[label=A,color=yellow]{5}
\bcbar[label=B,color=cyan]{10}
\bcbar[label=C,color=green]{15}
\bcbar[label=D,color=pink]{30}
\bcbar[label=E,color=orange]{40}
\end{bchart}
↓ Input
A 5
B 10
C 15
D 30
E 40
0 5 10 15 20 25 30 35 40
2011/12 50,000
2012/13 75,000
2013/14 60,000
vertical Create vertical bar charts (default). The 𝑥-axis is the horizontal axis
and the 𝑦-axis is the vertical axis.
horizontal Create horizontal bar charts. The 𝑥-axis is the vertical axis and the
𝑦-axis is the horizontal axis.
There are two commands provided to generate a bar chart:
\DTLbarchart[⟨condition⟩]{⟨settings⟩}{⟨db-name⟩}{⟨assign list⟩} Definition
and
\DTLmultibarchart[⟨condition⟩]{⟨settings⟩}{⟨db-name⟩}{⟨assign list⟩} Definition
The former generates a bar chart from a single column of data and the latter
generates a bar chart with groups of bars representing multiple columns of data.
The ⟨condition⟩, ⟨db-name⟩ and ⟨assign list⟩ are the same as for \DTLforeach.
The ⟨settings⟩ argument is a key=value list where the following keys are avail-
able:
variable This specifies the control sequence (which must be set
in ⟨assign list⟩) that contains the value used to construct
the bar chart. This key is required for \DTLbarchart and
is unavailable for \DTLmultibarchart.
axes This may take one of the following values: both (show
both axes), x (only show the 𝑥-axis), y (only show the
𝑦-axis) or none (don’t show either axes).
barlabel Sets the lower bar label. When used with \DTLmultibarchart
this indicates the group label.
This is a length register that stores the total length of the 𝑦-axis. The default is
3 in.
\DTLbarwidth Definition
This is a length register that stores the width of each bar. The default is 1 cm.
\DTLbarlabeloffset Definition
This is a length register that stores the distance from the 𝑥-axis to the lower
bar label. The default is 10 pt.
\DTLsetbarcolor{⟨n⟩}{⟨colour⟩} Definition
This sets the ⟨n⟩th bar colour to ⟨colour⟩. Only the first eight bars have a colour
defined by default. You need to use this command if you need more than eight
bars or if you want to override the default colours.
\DTLdobarcolor{⟨n⟩} Definition
Sets the current text colour to the colour of the ⟨n⟩th bar.
\DTLbaroutlinecolor Definition
This macro expands to the colour of the bar outlines. This defaults to black.
Use \renewcommand to change this value.
\DTLbaroutlinewidth Definition
A length register that stores the line width for the bar outlines. If it is set to
0 pt, the outline is not drawn. The default value is 0 pt.
Both \DTLbarchart and \DTLmultibarchart draw the chart inside a tikzpicture
environment. You can redefine the following commands to insert code at the
start or end of this environment:
\DTLbaratbegintikz Definition
for the hook at the start (after the unit vectors are set) and
\DTLbaratendtikz Definition
Within this book you can use \DTLstartpt (the start of the bar), \DTLmidpt (the
mid point of the bar) and \DTLendpt (the end of the bar).
There are other commands as well that can be redefined to change the
appearance of the bar chart. See the databar section of the datatool manual [95]
for further details.
12.4 Gantt Charts 376
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[x11names]{xcolor}
\usepackage{databar}
\DTLloaddb{books}{booklist.csv}
\DTLsetbarcolor{1}{Aquamarine1}
\DTLsetbarcolor{2}{Azure2}
\DTLsetbarcolor{3}{Burlywood3}
\DTLsetbarcolor{4}{CadetBlue2}
\DTLsetbarcolor{5}{Chartreuse3}
\DTLsetbarcolor{6}{Salmon1}
\DTLsetbarcolor{7}{DeepPink1}
\DTLsetbarcolor{8}{Goldenrod1}
\DTLsetbarcolor{9}{Honeydew1}
\DTLsetbarcolor{10}{Plum3}
\setlength{\DTLbaroutlinewidth}{1pt}
\setlength{\DTLbarwidth}{1.2cm}
\begin{document}
\setcounter{DTLbarroundvar}{2}
\DTLbarchart
{variable=\ThePrice,% database column
axes=both,% show both axes
barlabel=\parbox{4cm}{\raggedright\TheTitle},% bar labels
upperbarlabel={\pounds{ThePrice}},% upper bar labels
yticgap=10,% gap between y tick marks
ylabel={Price (\pounds)}% y-axis label
}% settings
{books}% database
{\ThePrice=price,\TheTitle=title}% assignment list
\end{document}
↓ Input
This produces the chart shown in Figure 12.10. You can download or view
this example.
My Friend is a Duck
£19.99 £18.99
50.00
40.00
30.00
20.00
10.00
0.00
Price (£)
12.4 Gantt Charts 378
packages available on both MiKTEX and TEX Live. The pgfgantt package [88] uses
tikz, and the pst-gantt [27] and rtsched [54] packages use pstricks.
This section discusses the pgfgantt package, since it’s driver-independent and
uses the pgfcalendar package, which has already been introduced in §7.2. If you
want to use the pgfgantt package, make sure you have an up-to-date version of
the pgf package installed.
The pgfgantt package defines the ganttchart environment, which can be used
to generate a Gantt chart.
\begin{ganttchart}[⟨options⟩]{⟨start tss⟩}{⟨end tss⟩}
⟨entries⟩ Definition
\end{ganttchart}
The optional argument ⟨options⟩ is a key=value list. You can also use these
keys in the optional argument of the commands, described below, provided for
use within the ganttchart environment to apply the setting to just that element.
Alternatively you can use
\ganttset{⟨options⟩} Definition
isodate-yearmonth As isodate but without the day -⟨dd⟩ part. The date is
assumed to be the first day of the month.
little-endian Each time slot is specified in ⟨dd⟩-⟨mm⟩-⟨year⟩ format.
(You may also use a slash (/) or period (.) instead of a hy-
phen (-) for the separator.) A two-digit year will be com-
pleted according to the base century setting.
middle-endian As little-endian but with the ⟨dd⟩ and ⟨mm⟩ swapped.
big-endian As little-endian but with the order reversed (⟨yyyy⟩ first
and ⟨dd⟩ last).
Draws a single title element that covers ⟨n⟩ time slots, with the given ⟨text⟩.
\gantttitlelist[⟨options⟩]{⟨list⟩}{⟨n⟩} Definition
This iterates over ⟨list⟩ and draws a title element that spans ⟨n⟩ time slots for
each item in the list. The title text is given by the current list element. The list
should be in the format accepted by \foreach (see §2.7.2).
\gantttitlecalendar[⟨options⟩]{⟨calendar lines⟩} Definition
This prints a title calendar that spans the whole chart. The starred form
\gantttitlecalendar*[⟨options⟩]{⟨start tss⟩}{⟨end tss⟩}{⟨calendar lines⟩} Definition
spans from ⟨start tss⟩ to ⟨end tss⟩. In both cases, ⟨calendar lines⟩ is a comma-
separated list of line types:
year Print the year.
month Print the month number. This may optionally be followed by =⟨format⟩
where ⟨format⟩ may be one of: name (the full name) or shortname
(abbreviated name).
week The week. This may optionally be followed by =⟨number⟩ where
⟨number⟩ is the number of the first week of the calendar.
weekday The week day number (starting from 0 for Monday). This may option-
ally be followed by =⟨format⟩ (analogous to month).
day The two-digit day of the month.
There are three chart elements, which can be created using the following:
\ganttbar[⟨options⟩]{⟨text⟩}{⟨start tss⟩}{⟨end tss⟩} Definition
This combines several subtasks into a single task. For the above two commands,
⟨start tss⟩ indicates the starting time slot and ⟨end tss⟩ indicates the end time
slot for the task or task group.
\ganttmilestone[⟨options⟩]{⟨text⟩}{⟨tss⟩} Definition
This indicates that a milestone has been completed on the time slot given by
⟨tss⟩.
If you want to have links between each of these elements (that is, lines drawn
from the end of one element to the start of the next element) you can use one
of the following commands, analogous to the above three commands.
\ganttlinkedbar[⟨options⟩]{⟨text⟩}{⟨start tss⟩}{⟨end tss⟩} Definition
for a group, or
\ganttlinkedmilestone[⟨options⟩]{⟨text⟩}{⟨tss⟩} Definition
for a milestone.
Example 63. A Gantt Chart
This example is for a Gantt chart that spans a whole year. In this case a day as
the time slot would produce a chart that’s far too wide, so I’ve used the compress
calendar option and I set the x unit to 8 mm. The pgfgantt manual recommends
an 𝑥/𝑦 ratio of approximately 1 : 2 so I’ve also set both y unit title and y unit
chart to 16 mm. The newline shortcut option allows me to use \\ instead of
\ganttnewline.
↑ Input
\documentclass{article}
\usepackage{pgfgantt}
\begin{document}
\begin{ganttchart}
[time slot format=isodate,%
newline shortcut,%
x unit=8mm,%
y unit title=16mm,%
y unit chart=16mm,%
compress calendar%
]% options
{2014-1-1}% start time slot
{2014-12-31}% end time slot
\gantttitlecalendar{year,month=shortname}\\
\ganttgroup{Ray Gun Project}{2014-1-1}{2014-06-30}\\
\ganttbar{Design}{2014-1-1}{2014-04-15}\\
\ganttbar{Testing}{2014-04-01}{2014-06-30}\\
\ganttmilestone{Prototype Ready}{2014-07-01}\\
\ganttgroup{Telepathic Cakes}{2014-5-10}{2014-12-31}\\
\ganttbar{Development}{2014-5-10}{2014-12-31}
\end{ganttchart}
\end{document}
↓ Input
12.5 Plots 381
This produces the chart shown in Figure 12.11. You can download or view
this example.
Output
2014
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
Design
Testing
Prototype Ready
Telepathic Cakes
Development
12.5 Plots
If you have a large amount of data, you may want to consider using a mathemat-
ical tool (such as Matlab, Octave or GnuPlot) to generate your graphs as image
files. If you use TEX, you may have excessively long document build times.
Don’t expect TEX to be able to compute logarithms or exponentials with the
speed or precision of a custom-built numerical computing engine. Additionally,
some packages can’t parse scientific notation.
There are, however, some packages that use PostScript rather than TEX
to perform the calculations (in which case you can’t directly use PDFLATEX)
and some of them rely on TEX’s shell escapes to call an application, such as
GnuPlot, to generate the drawing code (in which case you need the shell escapes
enabled). If you have applications such as GnuPlot or Matlab installed or if
you are happy to use the latex+dvips+ps2pdf route to generate your PDF
files, there are a number of useful packages listed on the graphics-plot topic. In
addition, pgf/tikz comes with an impressive mathematical engine provided by the
pgfmath package. If you want to annotate your plot with text that matches your
document format and have the patience to wait for your document to compile,
12.5 Plots 382
you may be surprised by the images that can be produced using some of the
packages available on CTAN.
Since the aim of this book is to be as useful to as many readers as possible,
I’m again going to choose device-independent options that don’t require any
additional applications. (This is, after all, a book on administrative work not high
performance computing or advanced mathematics.) As with pie charts and bar
charts, the datatool package also provides a package (dataplot) for drawing plots
from data stored in a database. However, if you don’t intend using that data
anywhere else in the document, I suggest you use a more flexible package such
as pgfplots, which is described below. The other advantage of pgfplots over dataplot
is that pgfplots can parse scientific notation and can cope with larger values. The
remainder of this section discusses the pgfplots package.
The pgfplots package [26] uses pgf/tikz so make sure you have an up-to-date
version of the pgf package installed. The pgfplots manual [26] is 500 pages long
at the time of writing, so this section is a very brief introduction. See the user
manual for further details.
Options can be set using
\pgfplotsset{⟨options⟩} Definition
There are a number of different ways of specifying the plot, such as:
12.5 Plots 383
or I can just have the data inline as in the example document below:
↑ Input
\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\addplot table
{
year profit
2010 52000
2011 50000
2012 75000
2013 60000
};
\end{axis}
\end{tikzpicture}
\end{document}
↓ Input
to the preamble. This produces the graph shown in Figure 12.12, which doesn’t
look right. The 𝑥-axis is far too cramped and doesn’t need so many tick marks.
Output
·104
2,0102,010.52,0112,011.52,0122,012.52,013
The positions of the 𝑥-axis tick marks can be changed using the xtick
key. This may be set to \empty (generate automatically), the keyword data
(use the co-ordinates provided by the first plot), or a comma-separated list of
co-ordinates. (There are also analogous ytick and ztick keys.)
12.5 Plots 385
The tick labels can be changed using various keys. First is the xticklabels
key which takes a comma-separated list of labels, where each label corresponds
to a tick position. Alternatively, you can use xticklabel where the value is the
code to produce the label. You can access information about the current tick
using the following:
\tick Definition
This command is only valid if the x tick label as interval option has been
set (or y tick label as interval for the 𝑦-axis ticks) in which case it will
contain the position of the next tick position.
The default label format is \pgfmathprintnumber{\tick}, which uses the
number pretty-printing command provided by the pgfmath package. This is why
the 𝑥-tick labels in Figure 12.12 have commas in them (for example, 2,010 rather
than 2010). The comma can be removed by first using:
\pgfkeys{/pgf/number format/set thousands separator={}} Input
Alternatively, if you just want to change the style for a particular axis:
↑ Input
\pgfplotsset{x tick label style={
/pgf/number format/set thousands separator={}
}}
↓ Input
The modified document is shown below. I’ve also added a plot title using
title and axes labels using xlabel and ylabel:
↑ Input
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\begin{document}
\begin{tikzpicture}
\begin{axis}[xtick=data,% get x tick marks from data
xlabel=Year,ylabel={Profits (\pounds)},% axes labels
x tick label style={% change x tick label style
/pgf/number format/set thousands separator={}%
},
title={Profits Since 2010},% plot title
tick align=outside% ticks on the outside
]
\addplot table
{
year profit
2010 52000
2011 50000
2012 75000
2013 60000
};
\end{axis}
\end{tikzpicture}
12.5 Plots 386
\end{document}
↓ Input
This produces the plot shown in Figure 12.13, which is much less cramped.
Output
·104 Profits Since 2010
7
Profits (£)
In order to save space, the 𝑦-tick labels have been scaled by 104 but since, in
this case, the 𝑦 axis represents profits it would look better if this scaling wasn’t
applied. There are a number of different ways of changing the scaling (see the
manual [26]) but to switch it off for all axes, you just need the option scaled
ticks=false. It’s also possible that you don’t like the boxed axes, but this can
be changed using the option axis lines*=left. These extra options produce
the plot shown in Figure 12.14.
Output
Profits Since 2010
70,000
Profits (£)
60,000
50,000
You can download or view this example where I have additionally loaded the
plotmarks library and used the optional argument of \addplot to set the plot
marks to filled diamonds (mark=diamond*) with the marker size set to 5 pt (mark
12.5 Plots 387
size=5pt) and a thick cyan line stroke. (Try it for yourself before you download
the example, as an additional exercise.)
Chapter 13
Collaborating on Documents
There are a number of issues that can occur when multiple authors collaborate
on the same document. For example, suppose Fred and Mabel are co-authors
of a document, here are some problems they may encounter:
1. If both Fred and Mabel edit their own copies of the source code, how do
they merge their edits? If Fred sends Mabel his updated source file, it
could overwrite her changes. Similarly if Mabel sends Fred her updated
source file, it could overwrite his changes.
2. Fred decides to use package foo, which is available on his MiKTEX distri-
bution, but Mabel doesn’t have foo on her TEX Live distribution.
3. Both Fred and Mabel want to use package baz but Mabel has a newer
version and is using commands that aren’t available in the older version
that Fred has installed.
4. Fred and Mabel are working on a sensitive document. If they simply email
each other the source code it could be intercepted or if they transfer it
on a portable device, such as a memory stick, it could get stolen.
5. Fred is the principle author and is in charge of writing the first draft.
Once he has finished, he sends the document to Mabel who makes minor
corrections, but Fred needs to know what modifications she has made.
6. Prof Important Person has decided he’s also going to contribute to the
document but insists on using his favourite word processor.
7. If Fred or Mabel make an inappropriate change to the document, they
may want to roll back to an earlier version of the document to undo the
modifications.
The more co-authors on the document, the more likely these problems will oc-
cur. The last case is an issue that may also need addressing for a single-authored
document. This chapter describes ways of circumventing these problems, but
the most convenient solution may not necessarily be the most appropriate so-
lution if you have to take into account factors such as security or available
resources or recalcitrant co-authors.
Here are some possible solutions to the above problems:
1. The easiest case is when Fred and Mabel are working on separate sections
or chapters. They can then split up the source code and use \input (for
sections) or \include (for complete chapters). Then Fred can just edit
the files for his sections and Mabel can just edit the files for her sections.
This way they won’t be editing the same file at the same time.
In the other case, where Fred and Mabel are both working on the same
sections, then the most convenient solutions are a version control system
(§13.2) or using an online LATEX editor (§13.3).
2. Fred and Mabel agree to only use packages that are available on both
MiKTEX and TEX Live, or Mabel manually installs the missing package, or
they use an online LATEX editor.
3. Fred and Mabel both update their TEX distributions before they start work-
ing on the document or they use an online LATEX editor.
388
Chapter 13. Collaborating on Documents 389
4. In this case, it depends on the level of security needed. Fred and Mabel
may simply be able to use a password-protected version control system.
Alternatively, they may need to store the document source code on a
portable device that’s locked in a safe when the document isn’t being
edited, and the authors will have to take it in turns to access the device in
a non-networked secure environment.
5. Use LATEX commands to markup the changes (§13.1) or use version control.
6. A non-LATEX co-author can cause major headaches for a predominantly
LATEX team of authors. In some cases, gentle persuasion may help. If
arguments about the quality of typesetting, the logic of document markup,
the convenience of cross-referencing and automatically generated table of
contents and similar lists don’t have an effect, it might help to point out the
security issues associated with Word files, such as the automatic hidden
inclusion of personal data and revision information [28].
If persuasion doesn’t help, how much of a contribution will they be making
to the document? If it’s just a matter of a few minor corrections, then it
might be possible for them just to mark their changes and for you to
then incorporate those changes into the LATEX source code. The best way
of creating a Word document from the LATEX source is to use tex4ht to
create an OpenDocument Format (.odt) file which can then be converted
to Word using an application such as LibreOffice. For example, if the
LATEX source is in a file called myDoc.tex then you can create myDoc.odt
using:
where ⟨options⟩ is a key=value list of options and ⟨id⟩ is a label identifying the
author. Available options:
name The author’s name.
color The colour to use when marking up this author’s changes. (Defaults to
black.)
13.1 Change Markup 391
Example:
\definechangesauthor[name={Mabel Canary},color=cyan]{MC} Input
to indicate that ⟨old text⟩ has been replaced by ⟨new text⟩. Each of these com-
mands has an optional argument that’s a key=value list where the following
keys are available:
id The author’s ID (as provided in \definechangesauthor).
remark A remark about the change.
You can create a list or summary of the changes using
\listofchanges[⟨options⟩] Definition
The optional argument is again a key=value list, but there is currently only one
key available: style, which may have the value list or summary. The default
value is list. As with commands such as \tableofcontents and \listoffigures,
this command requires two LATEX runs to produce the list. The default extension
for the summary of changes file is .soc, but this can be changed using
\setsocextension{⟨extension⟩} Definition
You can suppress the change markup using the final package option:
\usepackage[final]{changes} Input
The draft option enables the markup. The other package options are ⟨key⟩=
⟨value⟩ options, where the following keys are available:
• markup=⟨value⟩ sets the markup style. The ⟨value⟩ may be one of:
default Colour markup for added text, strike out for deleted text.
underlined Added text is underlined, deleted text is struck out.
bfit Bold for added text and italic for deleted text.
nocolor As underlined but without colour.
• addedmarkup=⟨value⟩ and deletedmarkup=⟨value⟩ set the markup style for
added and deleted text. The ⟨value⟩ may be one of:
none No markup.
uline Underlined text (example).
uuline Double underlined text (example).
uwave Wavy underlined text (::::::::
example).
dashuline Dashed underlined text (example).
dotuline Dotted underlined text (example).
...........
sout Struck out text (example).
xout Crossed out text (///////////
example).
bf Bold text.
it Italic text.
13.1 Change Markup 392
sl Slanted text.
em Emphasized text.
• authormarkup=⟨value⟩ sets the style of the author identification. The
⟨value⟩ may be one of:
superscript Superscript author’s name or ID.
subscript Subscript author’s name or ID.
brackets Author’s name or ID in parentheses.
footnote Author’s name or ID in a footnote.
none No author identification.
• authormarkupposition=⟨value⟩ sets which side of the change to place the
author’s ID. The ⟨value⟩ may be right or left.
• authormarkuptext=⟨value⟩ sets whether to use the author’s ID or name
in the change markup. The ⟨value⟩ may be either id (default) or name.
There are also commands to provide custom markup. See the changes docu-
mentation [44] for further details.
The changes package automatically loads the ulem [2] and xcolor packages.
You can pass options to these packages using the ulem and xcolor keys. For
example
\usepackage[ulem={normalem,normalbf}]{changes} Input
↑ Input
\documentclass[12pt]{article}
\usepackage[ulem={normalem,normalbf}]{changes}
\definechangesauthor[name={Mabel Canary},color=violet]{MC}
\definechangesauthor[name={Fred Canary},color=blue]{FC}
\definechangesauthor[name={Prof Important Person},color=teal]{IP}
\begin{document}
\section{About the Lab}
\end{document}
↓ Input
The changes are colour-coded according to the author who made the edit. Any
remarks are added as footnotes, as shown in Figure 13.1. You can download or
view this example.
Output
1 About the Lab
The Secret Lab of Experimental Stuff is a top-secretsinisterMC laboratory
whose existence is highly classified so don’t tell anyone about it or we’ll get
really cross with youFC .
The world-renownIP University of Somewhere denies all knowledge of the
Secret Lab of Experimental Stuff, except on Open Days where members of
the public may visit the facility and ask questions as long as they consent to a
memory wipe when they leave. The memory wipe is completelyMC1 harmless
and your memory of the visit will be replaced by a pleasantMC recollection
of spending the day feeding the ducksgeeseFC2 and geeseMC3 in the nearby
pond.
1
MC: no it isn’t
2
FC: what geese?
3
MC: they’re the weird-looking ducks
For Windows users, there’s a command line zip program available in GNU
On Windows (GOW).
Example 66. Accessing Subversion Revision Information
This book and the accompanying example documents and exercise solutions
are in a Subversion repository. In order to insert version control information
into one of these documents, I need to add a keyword anchor. This is just a bit
of text in the form
$⟨KeywordName⟩$ Input
The ⟨KeywordName⟩ indicates the information you want to insert and (for Sub-
version) may be one of [66]:
Date The last time the file was known to have been changed in the repos-
itory.
Revision The last known revision in which the file was changed in the reposi-
tory.
Author The last known user to change this file in the repository.
HeadURL The full URL to the latest version of the file in the repository.
Id A compressed combination of the other keywords.
Header Similar to Id but contains the full URL of the latest revision.
For example:
$Id$ Input
In addition to adding this text to the file under version control (called, for exam-
ple, svninfo-sample.tex) you also need to tell Subversion to perform a keyword
substitution whenever the file is committed. This is done using:
svn propset svn:keywords "Id" svninfo-sample.tex Shell
Now, after I next commit the file svninfo-sample.tex, the keyword anchor $Id$
will be changed to the revision information. For example:
13.2 Version Control 396
This will cause a problem when I build my document as LATEX will interpret
those dollar $ symbols as the maths shift special character, so the information
won’t be typeset correctly. However, recall from §2.1.1 that you can use \def to
define a command with a particular syntax. For example:
↑ Input
\def\svnInfo$#1${%
% do something with #1
}
↓ Input
and the $ symbols are part of the syntax and aren’t interpreted as the maths
mode shift. The svninfo package provides a command called
\svnInfo $⟨Id⟩$ Definition
which is defined in a similar manner. Note that the trailing space is part of
the syntax. This command parses the Id keyword anchor and gathers the
information for later use in the document. By default this information is placed
in the page footer.
For example, here’s my original document called svninfo-sample.tex:
↑ Input
\documentclass{article}
\usepackage{svninfo}
\svnInfo $Id$
\author{Nicola Talbot}
\title{A Sample Document}
\begin{document}
\maketitle
\end{document}
↓ Input
If I build this document using pdflatex, the resulting PDF file contains the
footer
Rev: –revision–, December 15, 2014 1 –sourcefile– Output
This is because there’s currently no version control information in the file, just
the keyword anchor $Id$. Next I need to add this new file to my Subversion
repository:
svn add svninfo-sample.tex Shell
(See the Subversion user manual [66] for information on setting up a repository.)
Also, I need to indicate that this file contains the Id keyword anchor:
svn propset svn:keywords "Id" svninfo-sample.tex Shell
This not only commits the new file svninfo-sample.tex to the repository, but
also modifies the file so that it now looks like:
↑ Input
\documentclass{article}
\usepackage{svninfo}
\author{Nicola Talbot}
\title{A Sample Document}
\begin{document}
\maketitle
If I rebuild this document, the PDF file is now as shown in Figure 13.2. The
footer now contains the revision number and the filename. You can download
or view this example.
For example:
\svnKeyword $Author: nlct$ Input
Remember that you need to include these extra keywords in the svn:keywords
property to ensure they are also expanded. For example, if you want to access
the Author and Date rather than the Id, then you need to set the keywords
using
svn propset svn:keywords "Date Author"
line-wrap-symbol Shell
svninfo-sample.tex
(Keywords are case-sensitive.) The footline can be removed using the nofancy
package option
\usepackage[nofancy]{svninfo} Input
The Subversion information can be accessed using any of the following com-
mands:
\svnInfoFile Definition
for the revision number of the checked out file or --revision-- if unknown;
\svnInfoDate Definition
for the date in the form ⟨YYYY ⟩-⟨MM⟩-⟨DD⟩ when the file was checked out or
the current date if unknown;
13.2 Version Control 398
Output
A Sample Document
Nicola Talbot
December 15, 2014
\svnInfoTime Definition
for the time when the file was checked out or --time-- if unknown;
\svnInfoOwner Definition
for the year when the file was checked out or the current year if unknown;
\svnInfoMonth Definition
for the month (in ⟨MM⟩ form) when the file was checked out or the current
month if unknown;
\svnInfoDay Definition
for the day (in ⟨DD⟩ form) when the file was checked out or the current day if
unknown;
\svnInfoLongDate Definition
for the date in the form of \today when the file was checked out or the current
date if unknown.
A summary of the Subversion information can be obtained using
\svnId Definition
which uses the same format as the Id keyword anchor. In addition to the above
commands, the svninfo package also provides commands for multi-file docu-
ments. Every file of the document must include either \svnInfo or \svnKeyword
with the Revision keyword. Two LATEX runs are required.
\svnInfoMinRevision Definition
displays the minimum revision number for all the files in the document, and
\svnInfoMaxRevision Definition
displays the maximum revision number for all the files in the document. (If
unknown, the defaults are --minrevision-- and --maxrevision--.) The date
from the latest Subversion revision (in the same format as \today) is obtained
using:
\svnInfoMaxToday Definition
If you want the URL to the file in the repository, you need the HeadURL
keyword
\svnKeyword $HeadURL:$ Input
The two most popular online LATEX editors appear to be Overleaf (formerly
WriteLATEX) and ShareLATEX. The information provided here (such as available
features and pricing) may have changed since the time of writing this chapter.
ShareLATEX There are four plans: Personal, Student, Collaborator, and Profes-
sional. The pricing and available features are listed in Table 13.1. The site
supports the following languages: Italian, Japanese, Korean, Portuguese,
Czech, Dutch, Chinese (Simplified), Norwegian, English, German, Danish,
Russian, French, Swedish and Turkish.
To create a free personal account, just go to https://www.sharelatex.
com/register and enter your email address and the password you want to
use. To create a new project, go to https://www.sharelatex.com/project
and click on the “New Project” button. This will drop-down a list of options,
such as a blank project, upload a project, import from GitHub, or create
a project from a template. There’s a wide selection of templates:
• Bibliographies: BibTEX, thebibliography environment, natbib, biblatex, bibla-
tex with split bibliographies, IEEE BibTEX style, and notes2bib.
• Books: includes Springer styles, Tufte style, classic thesis, Wiley
styles, MIT styles and sffms (science fiction and fantasy manuscripts).
• Exams.
• Cover letters: moderncv styles and Illinois University.
• Other: includes business cards, pst-barcode, homework styles, various
letter styles, brochures, flyers, posters, business reports, recipe, lab
reports, assignment sheets, invoices, grant applications, and propos-
als.
• CV or Résumé: includes moderncv styles, europecv styles, classic,
academic, professional, fancy, curve, curvita.
• Thesis: there are a lot of templates in this category, some are general
and some are specific to particular institutes.
• Presentations: again there are a lot of templates, many of them using
various beamer themes.
• Journals: many different journal styles.
Overleaf There are four plans available: Free, Personal+, Pro and Pro+. The
pricing and available features are listed in Table 13.2. There are also
tailored solutions for universities, publishers and enterprise. Students get
all the features of the Pro account for half price.
13.3 Online LATEX Editors 401
When you create a new project with Overleaf, a unique identifier is gen-
erated that’s used in the link to the project. The files that make up the
project are private as long as that link remains private. It’s unlikely that
anyone will guess the link, but if it does get published or shared then the
project can be accessed and edited. It’s your responsibility to ensure you
don’t share the link with anyone who shouldn’t access it. (Be careful of
the link appearing in your browser history if you use a shared computer.)
With the Pro plans you can create protected projects for added security.
Overleaf uses Amazon S3 for secure data storage.
To create a free Overleaf account, just go to https://www.overleaf.com/
signup, fill in your name and email and click on the create new account
button. This takes you to the dashboard and sends you an email with a
link to confirm your account registration and choose a password.
To create a new project, click on the “create new project” button in the
dashboard. This pops up a window where you can select a template for
your document. The available templates are divided into categories:
• Basic: blank paper, sample paper, presentation.
13.3 Online LATEX Editors 402
One thing I noticed when trying out the templates was that once I had
created a project by selecting a template, there was no way to permanently
delete it. If you delete a project from the project list on the dashboard, the
project is moved to trash and after 30 days, the project will be removed
from the dashboard, but the project itself isn’t deleted. This was a bit
annoying as I only created the projects to see what the templates looked
like. Only some of the templates actually included information in their
description about the packages used within the template.
I tried both sites using Mozilla Firefox (v33.1) and Google Chrome (v39.0.2171.71)
running under 64-bit Fedora 19. In addition, to test accessibility support for
visually-impaired users, I tried both sites with the text-only browser Lynx (v2.8.8dev.15)
and with the text-to-speech Jovie plugin for Konqueror (v4.11.5).
User Interface
Overleaf The interface was mostly fine on Firefox and Chrome. In general
on the site, if the window isn’t wide enough for the navigation bar, the
navigation links are replaced by a button that drops-down a list of links
so a horizontal scroll bar is never required by the browser. When editing
a project in the source code pane, there were some issues with trying
to copy selected text in the source code pane to the clipboard. If I used
the popup menu’s “copy” item, I received a message “This action isn’t yet
available from the menu, but you can press Ctrl-C instead.” This cleared
the selection, and I had to reselect the text and use Ctrl-C. (Firefox’s Edit
ÏCopy menu item and Chrome’s Copy button worked. The issue was just
with the popup menu.)
An example document with Overleaf is shown in Figure 13.3. This has a
split pane area with the source code on the left and a preview image on
the right. The divider bar between the two panes can be moved to make
13.3 Online LATEX Editors 403
one pane wider than the other. If the source code pane isn’t wide enough
for all the menu buttons, you can access the remaining buttons through
the “More” drop-down menu.
The preview is automatically updated whenever the file is modified, which
I found distracting, but the automatic compilation can be switched off by
selecting the “Manual” button on the menu bar above the preview image.
The only way of enlarging the preview image is to make the preview pane
wider.
The source code can also be viewed as rich text. This gives a partial
WYSIWYG feel, which may suit some users. To enable this feature, just
click on the “Rich Text” button. The document shown in Figure 13.3 is
reproduced in Figure 13.4 with this feature on. To switch back to viewing
the source code, click on the “Source” button. At the time of writing, the
rich text function is still in beta.
Another interesting feature is that if I click on an area of the preview
pane (for example, on the first section header) the corresponding line in
the source code is highlighted. (There’s a short delay between clicking
and the source code line being found, so be patient, especially if you have
a slow Internet connection.) I wasn’t expecting SyncTEX support given
that the preview window is an image, so I was pleasantly surprised by
this.
The free version of Overleaf doesn’t have spell-checking or the ability to
change the editor themes, but it does have syntax highlighting.
The list of source files that make up a project can be viewed using the
“Menu” button on the main Overleaf navigation bar at the top of the win-
dow. Select the “Project” item from this drop-down menu and a window
will list the files (shown in Figure 13.5). To add new files, you can click on
the “Add files. . . ” button which drops-down a menu where you can choose
various options, such as create a new file or folder, or upload from your
computer or off-site storage, such as GoogleDocs or Dropbox.
You can use the file list to switch the editor to a different source file or you
can use the drop-down menu next to the filename to rename or delete
the file or perform other operations.
There is also a settings button to the left of the account holder’s name
on the top navigation bar. The spell check is disabled because it’s not
available for the free plan, but it’s possible to set the editor mode to Vim
or Emacs, and the font size can be made smaller or larger.
Error Handling
To test the error handling, I misspelt a command. (I removed the “f” from the
command \pdfcreationdate.)
Overleaf The line where the error occurs is highlighted and a popup window
displays the message immediately below the line (see Figure 13.8). Moving
the cursor away from the error line will make the message disappear.
Moving the cursor back to the error line will make the message reappear.
At the right-hand end of the menu bar above the preview pane, there’s
a red drop-down menu labelled “compile error”. There are two items: “go
to first error/warning” and “open latex log”. I couldn’t find any way to
open the log file when there weren’t any errors or warnings. (There are
some useful bits of information in log files that aren’t error or warning
messages, which I sometimes like to check even if the document appears
okay.)
ShareLATEX The line where the error occurs has a small red box with a white
cross in it next to the line number. If you move the mouse over this box,
the error message will be displayed. You can also click on the “Log and
output files” button above the preview window to display more details about
the error (as shown in Figure 13.9). Below the detailed error message are
buttons that allow you to view the full transcript, clear cached files and
a drop-down menu that allows you to view the auxiliary files.
TEX Engine
Overleaf I was interested to discover that Overleaf seems to be able to determine
what engine to use when compiling the document. The example document
shown in Figure 13.3 uses \pdfcreationdate, which is a PDFTEX
Inspecting the log file shows that PDFLATEX is being used and the
.primitives
command successfully produces the date stamp. However, if I add the
pstricks package to this document, I get an “Undefined control sequence”
error for this command. Investigating the log file shows that XELATEX is
being used (which doesn’t provide \pdfcreationdate).
ShareLATEX With ShareLATEX you need to explicitly set the engine you want to use.
You have a choice of PDFLATEX, LATEX, XELATEX and LuaLATEX. The default
is PDFLATEX.
1 The Vim key-bindings with the “terminal” editor theme provided an interface similar to my ac-
customed editing preferences, which I liked.
13.3 Online LATEX Editors
External Applications
To test commonly-used external applications, I added an example bib file (called
example.bib) that contained a sample entry:
@book{sample,
title = "A Sample Book",
author = "Ann Author",
publisher = "A Publisher",
year = 2014
}
I added this sample citation to my document and also added an index (with
the makeidx package), and a glossary and list of acronyms (with the glossaries
package).
Both Overleaf and ShareLATEX correctly generated the bibliography, index,
glossary and list of acronyms. I didn’t need to specify any of the external appli-
cations, both sites automatically ran bibtex and makeindex on the appropriate
files.
Accessibility
Given the complexity and visual nature of both sites, I didn’t expect either site
to work well with a simple text-only browser such as Lynx, but that and the
Konqueror Jovie plugin were the only means I had to test accessibility for the
visually impaired.
Overleaf The site doesn’t appear to provide alternative text for images. For
example, on the pricing and plans page the ticks and crosses that indicate
which options are available with which plans are invisible to the text-
to-speech synthesizer, which is useless for any users who can’t see the
images. On the other hand, text that isn’t visually displayed on the page
is read out, which is a bit confusing.
The project window doesn’t render correctly in either Lynx or Konqueror
and I wasn’t able to view or edit the document source code. It’s possible
that a more sophisticated screen reader, such as Jaws, can produce better
results with a different browser.
ShareLATEX Again there didn’t appear to be any alternative text for images. When
viewed in Lynx, the prices weren’t visible on the Plans and Pricing page,
however they were read out by Konqueror’s Jovie plugin. I couldn’t view
the project window in Konqueror. I just got an error claiming that the
project had been modified by collaborators and that I should ask the
project owner to upgrade the account. Again, it’s possible that a more
sophisticated speech reader can produce better results with a different
browser.
Mobile Devices
I tried both sites on my Arnova 7GB tablet. This is a very basic mobile device
and my rural broadband is a little iffy, so I didn’t expect a fast response from
either site. I also borrowed my brother’s iPad and my son’s “it tablet” and tried
both sites on those.
Both sites worked fine with the iPad and the it tablet, but they didn’t work
well with the Arnova tablet.
Overleaf I was able to login with the Arnova’s default web browser and with
Opera Mobile, but whenever I tried to access my list of projects from the
dashboard, I was redirected to the site’s home page.
ShareLATEX The Arnova’s default web browser and also the Opera Mobile browser
were unable to render the email and password fields in ShareLATEX’s login
page, so I was unable to test out the site as I was unable to login.
Summary
Both sites are impressive and have similar interfaces, but they are not browser-
independent, only fully-functioning with the big well-known browsers (which is
not really surprising given the complexity of the sites). If you have collaborators
who have difficulty using complicated web interfaces (for example, if they are
visually-impaired) you may want to consider using a version control repository
instead so that they can use their preferred text editor and other tools that are
accessible for them.
ShareLATEX’s paid plans have the ability to sync to GitHub, but remember that
private GitHub repositories also require payment. Both sites have paid plans that
also provide the ability to save to Dropbox. Overleaf’s paid plans are cheaper
than ShareLATEX’s.
If any of your collaborators are wary of LATEX and are easily confused by
the document commands, they may be swayed by Overleaf’s rich text view if all
they need to do is write text (as opposed to complicated equations or diagrams).
13.3 Online LATEX Editors 415
ShareLATEX’s free plan comes with a spell checker, multiple editor themes
and auto-complete, but Overleaf’s free plan doesn’t. (The paid plans do.) On the
other hand, ShareLATEX’s free plan doesn’t allow multiple collaborators whereas
Overleaf’s free plan does.
Both sites displayed the time stamp in UTC+0, which also happens to be my
current time zone (GMT) at the time of writing. This surprised me as I was
expecting at least one of the sites to use a server in a different time zone. I can’t
tell if they are actually in the same time zone as me or if they can determine
my location and set the time zone at the start of the document compilation.
Acknowledgements
Thank you to Joseph Wright for proof-reading this book and providing useful
feedback. Thank you to my son, Cameron, for providing the Sumatra and
Foxit on Windows screen shots, and for lending his tablet to try out the online
editors. Thank you to my brother Stephen Talbot for lending his iPad to try out
the online editors. Thank you to Paulo Cereda for being so patient with my bug
reports and awkward feature requests for arara! Thank you to the package and
class authors who responded to my bug reports. Thank you to Barbara Beeton
for spotting errors and giving useful advice, and to everyone else who provided
feedback during the creation of this book, and thank you to all those who keep
the TEX community going, including the CTAN team, TUG and local TEX user
groups, and all the class and package authors who share the fruits of their
labours! And, of course, thank you to Donald Knuth for creating TEX, Leslie
Lamport for creating LATEX, the LATEX team for taking over the development of
LATEX, and the developers of PDFTEX, XETEX and LuaTEX.
If you’re not already a member of TUG or a local TEX user group, please
consider joining.
416
Bibliography
[1] American Mathematical Society (AMS). User’s guide for the amsmath pack-
age (version 2.0), 2002. CTAN Mirror or texdoc amsmath.
[2] Donald Arseneau. The ulem package, 2011. CTAN Mirror or texdoc ulem.
[3] Donald Arseneau. The framed package, 2012. CTAN Mirror or texdoc
framed.
[4] Donald Arseneau. shapepar.sty v2.2, 2013. CTAN Mirror or texdoc
shapepar.
[5] Donald Arseneau. url.sty version 3.4, 2013. CTAN Mirror or texdoc url.
[6] Brian D. Beitzel. Formatting meeting minutes with the meetingmins LATEX
class, 2013. CTAN Mirror or texdoc meetingmins.
[7] Johannes L. Braams and Javier Bezos. babel version 3.9k, 2014. CTAN
Mirror or texdoc babel.
[8] Klaus Dieter Braune and Richard Gussmann. Standard document class
‘dinbrief’, 2007. CTAN Mirror or texdoc dinbrief.
[9] Achim D. Brucker. The svninfo package version 0.7.4, 2010. CTAN Mirror
or texdoc svninfo.
[20] Marco Daniel and Elke Schubert. The mdframed package: auto-split frame
environment, 2013. CTAN Mirror or texdoc mdframed.
[21] Wybo Dekker. The isodoc class for letters, invoices, and more, 2014. CTAN
Mirror or texdoc isodoc.
[22] Jean-Pierre F. Drucbert. The minitoc package, 2008. CTAN Mirror or
texdoc minitoc.
417
Bibliography 418
[23] Thomas Emmel. ticket.sty: making labels, visiting cards, pins and flash-
cards with LATEX, 2010. CTAN Mirror or texdoc ticket.
[24] Simon Fear. Publication quality tables with LATEX, 2005. CTAN Mirror or
texdoc booktabs.
[25] Jürgen Fenn. The TEX catalogue online, topic index. CTAN Mirror.
[26] Christian Feuersänger. Manual for package pgfplots: 2D/3D plots in LATEX,
version 1.11, 2014. CTAN Mirror or texdoc pgfplots.
[27] Denis Girou and Herbert Voß. pst-gantt v.0.22, 2013. CTAN Mirror or
texdoc pst-gantt.
[28] Jeff Goldberg. MS-Word is Not a document exchange format. http://www.
goldmark.org/netrants/no-word/attach.html, 2005. Accessed: 2014-11-
10.
[29] Donald P. Goodman III. The drm font package, 2015. CTAN Mirror or
texdoc drm.
[30] GNU on Windows. http://wiki.github.com/bmatzelle/gow/. Accessed:
2015-09-05.
[31] Thorsten Hansen. The bibunits package, 2004. CTAN Mirror or texdoc
bibunits.
[32] Thorsten Hansen. The multibib package, 2008. CTAN Mirror or texdoc
multibib.
[33] Patrick Happel. lipsum — access to 150 paragraphs of Lorem ipsum dummy
text, 2014. CTAN Mirror or texdoc lipsum.
[34] Carsten Heinz, Brooks Moses, and Jobst Hoffmann. The listings package,
2014. CTAN Mirror or texdoc listings.
[35] Stephan Hennig. The vc bundle, 2008. CTAN Mirror or texdoc vc-manual.
[36] Philip S. Hirschhorn. Using the exam document class, 2011. CTAN Mirror
or texdoc exam.
[37] Neil Chue Hong. Choosing a repository for your software project.
http://software.ac.uk/resources/guides/choosing-repository-
your-software-project, 2013. Accessed: 2014-12-12.
[40] Alan Jeffrey and Frank Mittelbach. inputenc.sty v1.2b, 2014. CTAN Mirror
or texdoc inputenc.
[41] Uwe Kern. Extending LATEX’s color facilities: the xcolor package, 2007.
CTAN Mirror or texdoc xcolor.
[42] Axel Kielhorn. The wasysym macro package for LATEX 2𝜀 v2.0, 2003. CTAN
Mirror or texdoc wasysym.
[43] Sebastian Marius Kirsch. bizcard: a LATEX 2𝜀 package for business/visiting/
calling cards, 1999. CTAN Mirror or texdoc bizcard.
[44] Ekkart Kleinod. The changes-package: Manual change markup — version
2.0.3, 2014. CTAN Mirror or texdoc changes.english.
Bibliography 419
[45] Ingo Klöckl. Paket ifsym und die if...-fonts (German), 2001. CTAN Mirror
or texdoc ifsym.
[46] Donald Ervin Knuth. The TEXbook. Addison-Wesley, 1986.
[47] Markus Kohm and Jens-Uwe Morawski. KOMA-Script a versatile LATEX 2𝜀
bundle, 2014. CTAN Mirror or texdoc koma.
[48] Tobias Kuhn. bchart: Simple bar charts in LATEX, 2012. CTAN Mirror or
texdoc bchart.
[49] The LATEX font catalogue. http://www.tug.dk/FontCatalogue/.
[50] The LATEX3 Project. The LATEX3 interfaces, 2014. texdoc interface3.
[51] Philipp Lehman and Joseph Wright. The etoolbox package: an e-TeX
toolbox for class and package authors, 2011. CTAN Mirror or texdoc
etoolbox.
[52] Richard Lewis. The svn package, 2007. CTAN Mirror or texdoc svn.
[53] Knut Lickert. LATEX 2𝜀 for people in associations minutes.sty, 2009. CTAN
Mirror or texdoc minutes.
[54] Giuseppe Lipari. The rtsched package for LATEX (version 1.0), 2011. CTAN
Mirror or texdoc rtsche.
[55] Brent Longborough. gitinfo2.sty: a package for accessing metadata from
the git DVCS version 2.0.4, 2014. CTAN Mirror or texdoc gitinfo2.
[56] Gonzalo Medina. The background package, 2014. CTAN Mirror or texdoc
background.
[57] Michael Mehlich. fp package, 1999. CTAN Mirror or texdoc fp.
[58] Frank Mittelbach and David Carlisle. A new implementation of LATEX’s
tabular and array environment, 2014. CTAN Mirror or texdoc array.
[59] Frank Mittelbach, Robin Fairbairns, Werner Lemberg, and LATEX3 Project
Team. LATEX font encodings, 2014. texdoc encguide.
[60] Ahmed Musa. The xwatermark package, 2012. CTAN Mirror or texdoc
xwatermark.
[61] MySQL::market share. http://www.mysql.com/why-mysql/marketshare/.
[62] Clemens Niederberger. The ExSheets bundle, 2014. CTAN Mirror or
texdoc exsheets.
[63] Rolf Niepraschk and Hubert Gäßlein. The pst-pdf package, 2008. CTAN
Mirror or texdoc pst-pdf.
[64] Rolf Niepraschk, Walter Schmidt, and Hubert Gäßlein. The document
class leaflet, 2013. CTAN Mirror or texdoc leaflet-manual.
[65] Scott Pakin. The comprehensive LATEX symbol list, 2009. CTAN Mirror or
texdoc symbols.
[66] C. Michael Pilato, Ben Collins-Sussman, and Brian W. Fitzpatrick. Version
Control with Subversion. O’Reilly, 2008. http://svnbook.red-bean.com/.
[67] CV Radhakrishnan, CV Rajagopal, and Antoine Chambert-Loir. Trivial
experiments with psTricks manipulation, 2003. CTAN Mirror or texdoc
pdftricks.
[68] Sebastian Rahtz, Leonor Barroca, Grant Gustafson, and Julian Gilbey. A
package for making sticky labels in LATEX, 2003. texdoc labels.
Bibliography 420
[69] Sebastian Rahtz and Heiko Oberdiek. Hypertext marks in LATEX: a manual
for hyperref, 2012. CTAN Mirror or texdoc hyperref.
[70] Luis Rández and Juan I. Montijano. The ticking digital clock tdclock package
v2.3, 2014. CTAN Mirror or texdoc tdclock.
[71] George Reese, Randy Jay Yarger, and Tim King. Managing & Using
MySQL. O’Reilly, 2nd edition, 2002.
[72] Axel Reichert. currvita.sty, 1999. CTAN Mirror or texdoc currvita.
[73] Alan Ristow. pst-bar v.0.92: bar charts for pstricks, 2008. CTAN Mirror or
texdoc pst-bar.
[74] R. M. Ritter. Oxford Style Manual. Oxford University Press, 2003.
[75] Will Robertson. A couple of things involving environments (environ v0.3),
2014. CTAN Mirror or texdoc environ.
[76] Will Robertson and Khaled Hosny. The fontspec package: Font selection
for XELATEX and LuaLATEX, 2014. CTAN Mirror or texdoc fontspec.
[77] Jonathan Sauer. The collect package, 2004. CTAN Mirror or texdoc
collect.
[78] Bernd Schandl. paralist extended list environments, 2013. CTAN Mirror or
texdoc paralist.
[79] Martin Scharrer. The svn-prov package: Use SVN Id keywords for package,
class and file header (version 3.1862d), 2010. CTAN Mirror or texdoc
svn-prov.
[80] Martin Scharrer. The rcs-multi package v0.1a, 2011. CTAN Mirror or texdoc
rcs-multi.
[81] Martin Scharrer. The svn-multi package version 2.4d, 2011. CTAN Mirror
or texdoc svn-multi.
[82] Martin Scharrer. The standalone package, 2012. CTAN Mirror or texdoc
standalone.
[83] Martin Scharrer. The mwe package, 2012. CTAN Mirror or texdoc mwe.
[84] Walter Schmidt. Using common PostScript fonts with LATEX, 2004. CTAN
Mirror or texdoc psnfss.
[85] Rainer Schöpf, Bernd Raichle, and Chris Rowley. A new implementa-
tion of LATEX’s verbatim and verbatim* environments, 2001. CTAN Mirror or
texdoc verbatim.
[86] Joachim Schrod. The rcs package, 1995. CTAN Mirror or texdoc rcs.
[87] Steven B. Segletes. The censor package, 2013. CTAN Mirror or texdoc
censor.
[88] Wolfgang Skala. The pgfgantt package v4.0, 2013. CTAN Mirror or texdoc
pgfgantt.
[89] Richard M. Smith. Microsoft Word bytes Tony Blair in the butt. http:
//www.computerbytesman.com/privacy/blair.htm, 2003. Accessed: 2014-
11-10.
[90] R. Stepanyan. The bardiag package, 2003. CTAN Mirror or texdoc bardiag.
[92] Nicola L. C. Talbot. Writing a LATEX class file to produce a form. The
LaTeX Community’s Know How Section, November 2009. http://www.
latex-community.org/know-how/latex/54-latex-document-classes/
342-writing-a-latex-class-file-to-produce-a-form.
[103] Till Tantau, Joseph Wright, and Vedran Miletić. The beamer class: user
guide for version 3.33, 2013. CTAN Mirror or texdoc beamer.
[104] Jamal K. Tartir. LATEX package jlabels, 2011. CTAN Mirror or texdoc
jlabels.
[105] Bob Tennent. Alegreya fonts with LATEX support, 2015. CTAN Mirror or
texdoc alegreya.
[106] Hàn Thế Thành, Sebastian Rahtz, Hans Hagen, Hartmut Henkel, Pawel
Jackowski, and Martin Schröder. The pdfTEX user manual, 2014. CTAN
Mirror or texdoc pdftex.
[107] Paul A. Thompson. newlfm.cls: a new letter, fax, memo document class for
LATEX 2𝜀 , 2009. CTAN Mirror or texdoc newlfm.
[108] The TEX user group. http://tug.org/.
[109] UK list of TEX frequently asked questions (UK TEX FAQ). http://www.
tex.ac.uk/faq or texdoc faq.
[110] Hideo Umeki. The geometry package v5.6, 2010. CTAN Mirror or texdoc
geometry.
[111] Boris Veytsman. Printing envelopes and labels in LATEX 2𝜀 : envlab package
user guide, 1997. CTAN Mirror or texdoc elguide.
Bibliography 422
[116] Yuan Xu. Drawing pie chart by using pgf-pie v0.2, 2012. CTAN Mirror or
texdoc pgf-pie.
[117] Timothy Van Zandt. PSTricks PostScript macros for generic TEX, 2007.
CTAN Mirror or texdoc pst-user.
Glossary
active characters A character with category code 13. An active character is in-
terpreted by TEX as a macro but it isn’t escaped with a leading backslash.
By default, there’s only one active character ~ but some packages, such
as babel, make other characters active. In particular the inputenc package
makes all non-Latin or accented characters (such as é) active.
arara A Java application that automates the process of building a LATEX docu-
ment. See also Volume 2 [96, §1.1.2]. URL: http://ctan.org/pkg/arara
basic Latin characters One of the letters a, . . . , z, A, . . . , Z. (Part of the 7-bit ASCII
set.) See also extended Latin character.
boolean keys A key in a key\discretionary {}{}{} where the value may be either true
or false. The value part may be omitted if it’s true. For example,
noheader=true and noheader both switch on the noheader setting.
category codes The code assigned to a character that identifies its category. For
example, the character “a” has the category code 11, which means it’s
a letter and can be used to form control words (see Volume 1 [93, §2.6]).
The character “$” has the category code 3, which means it’s the math-shift
character. It’s possible to change the category code of a character. For
example, in .cls (class) or .sty (package) files, the “@” character has the
category code 11 (“letter”) so it can be used in control words (such as
\@for) but outside of those files the “@” character has the catgory code 12
(“other”), so it can be used in the control symbol \@ but not in any control
words. For more details, see The TEXbook [46].
comma-separated lists A list where each item is separated by a comma. Leading
or trailing spaces on either side of individual items in the list may or may
not be ignored, depending on the context. If in doubt, err on the side
of caution and remove spaces or suppress EOL terminators with the %
comment character.
CSV Comma-separated variable.
CTAN The Comprehensive TEX Archive Network [18]. http://mirror.ctan.
org/.
CV Curriculum vitæ (plural: curricula vitæ).
datatooltk A Java application that can be used to edit datatool databases. It can
also be used to import data from CSV files, Excel spreadsheets, SQL data-
bases and TEX files that can be loaded using probsoln’s \loadallproblems
command. This application can either be run in batch or GUI mode.
Remember to add the datatooltk/bin directory to your system path if
you want to invoke it from a command prompt. The way to do this
varies according to your operating system. If you don’t know how to
do it, try doing a web search for “set path environment”. URL: http:
//www.dickimaw-books.com/software/datatooltk/
datatooltk-gui A script that invokes datatooltk in GUI mode.
EOL End of line.
A character, or sequence of characters, signifying a line break (in the
source code not in the resulting PDF) created by pressing the enter or
return key. The underlying character code is dependent on the
423
Glossary 424
operating system. For example, on Unix the EOL is indicated by the line
feed (\n or 0x0A) symbol (LF) whereas on Microsoft Windows the EOL
is indicated by a combination of the carriage return (\r or 0x0D) symbol
(CR) and the LF symbol. The category codes for an EOL is 5, but usually
TEX treats an EOL the same as the space symbol, unless it’s immediately
followed by another EOL, in which case a paragraph break created.
extended characters A character that’s outside of the 7-bit ASCII set. For example,
an extended Latin character or any character from a non-Latin alphabet.
Note that the numerical code representing a non-Latin character varies
according to the file’s input encoding. See also extended Latin character.
extended Latin characters A character that’s created by combining basic Latin
characters to form ligatures (e.g. æ) or by applying diacritical marks to
a basic Latin characters or characters (e.g. á or ø). (See also extended
character.) Note that the numerical code representing an extended Latin
character varies according to the file’s input encoding. For example, ï
has codepoint 0x00EF in the Unicode table, but has code 139 (0x8B) in the
ASCII table.
flowframtk A Java application that can be used to construct frames for the
flowfram package. URL: http://www.dickimaw-books.com/software/flowframtk/
special characters A character that has a special meaning to TEX. The common
special characters are: \ (the escape character, category codes 0) { (group
beginning, category code 1) } (group ending, category code 2) $ (math-
shift, category code 3) & (alignment tab, category code 4) # (parameter,
category code 6) ^ (superscript, category code 7) _ (subscript, category
code 8) % (comment, category code 9) and ~ (an active characters). In some
cases, the whitespaces characters EOL (category code 5) and (category
code 10) may also be considered special.
SQL Structured query language.
texdef A Perl script that displays the definition of (La)TEX commands. URL:
http://ctan.org/pkg/texdef
tokens Either a character (including special characters) or a control sequence.
TUG TEX User Group [108]. http://tug.org/.
426
Summary of Commands and Environments 427
\ \_
\# \}
Defined in: LATEX Kernel. Defined in: LATEX Kernel.
Summary of Commands and Environments 429
Defined in: arara directive. Indicates picture code to place on the page
given by ⟨page-number⟩. The starred
Logical or. [§1.2] version refers to the sheet number instead.
[§10.3]
}
Defined in: LATEX Kernel. \addtolength{⟨register⟩}{⟨dimension⟩}
Marks the end of a group. (See Defined in: LATEX Kernel.
Volume 1 [93, §2.7].) [§1.0] Adds ⟨dimension⟩ to the value of the given
length register. [§6.5]
~
Defined in: LATEX Kernel. \advance⟨register⟩ by ⟨value⟩
Unbreakable space. (See Volume 1 [93, Defined in: TEX primitive.
§4.3].) [§1.2] Increments the value stored in ⟨register⟩ by
⟨value⟩. The by keyword may be omitted.
A
[§2.1]
\begin{about}
Defined in: pressrelease class. \Alph{⟨counter⟩}
For use within the pressrelease environment, Defined in: LATEX Kernel.
this environment contains information Displays counter value as an upper case
about the company. [§6.2] letter. (A, B, C, . . . , Z) [§6.5]
Summary of Commands and Environments 430
Defined in: exam class. Changes the points format to use square
brackets instead of the default parentheses.
Like \part but indicates the points are [§9.1]
bonus marks. [§9.1]
\breakforeach
\bonusquestion[⟨points⟩]
Defined in: pgffor package.
Defined in: exam class.
When used inside the ⟨body⟩ part of
Like \question but indicates the points are \foreach, the loop will be terminated after
bonus marks. [§9.1] the completion of the current iteration.
Summary of Commands and Environments 432
For use within the textenum, this command As \gappto but requires the name (without Symbols
may be used in place of \item to indicate the leading backslash) of the control A
a correct choice. If the solutions aren’t sequence. [§2.1] B
displayed this command behaves the same
\csgdef{⟨cs-name⟩}⟨arg-syntax⟩ C
as \item. [§9.3]
{⟨definition⟩} D
\correctitemformat{⟨marker⟩} Defined in: etoolbox package. E
Defined in: probsoln package. F
This is analogous to \gdef except that the
The format used by \correctitem. [§9.3] name of the control sequence (without the G
initial backslash) is supplied. [§2.1] H
\cos
I
Defined in: LATEX Kernel (Math Mode). \csgpreto{⟨cs-name⟩}{⟨code⟩}
J
Typesets cos function name. [§9.1] Defined in: etoolbox package. K
\begin{coverpages}
Global version of \cspreto. [§2.1] L
M
Defined in: exam class. \cslet{⟨cs-name⟩}{⟨cs⟩}
N
Contains material to go before the start of Defined in: etoolbox package.
O
the exam. [§9.1] Analogous to \let except that the name of P
\csappto{⟨cs-name⟩}{⟨code⟩} the control sequence (without the initial
backslash) is supplied for the first
Q
Defined in: etoolbox package. argument. [§2.1] R
As \appto but requires the name (without S
the leading backslash) of the control \csletcs{⟨new cs-name⟩}{⟨org cs-name⟩} T
sequence. Use \csgappto for a global Defined in: etoolbox package. U
assignment. [§2.1] Analogous to \let except that the names of V
\csdef{⟨cs-name⟩}⟨arg-syntax⟩ the control sequences (without the initial W
{⟨definition⟩} backslash) are supplied. [§2.1] X
Defined in: etoolbox package. \csname ⟨cs-name⟩\endcsname Y
This is analogous to \def except that the Z
Defined in: TEX primitive.
name of the control sequence (without the
Expands to the control sequence whose
initial backslash) is supplied. [§2.1]
name (without the leading backslash) is
\cseappto{⟨cs-name⟩}{⟨code⟩} given by ⟨cs-name⟩. If the control sequence
isn’t already defined, TEX will first define it
Defined in: etoolbox package.
to \relax before using it. [§2.1]
As \eappto but requires the name (without
the leading backslash) of the control \cspreto{⟨cs-name⟩}{⟨code⟩}
sequence. Use \csxappto for a global Defined in: etoolbox package.
assignment. [§2.1]
As \preto but requires the name (without
\csedef{⟨cs-name⟩}⟨arg-syntax⟩ the leading backslash) of the control
{⟨definition⟩} sequence. Use \csgpreto for a global
Defined in: etoolbox package. assignment. [§2.1]
command \do is used. The list may Similar to \framebox but produces a dashed Symbols
explicitly be a comma-separated list or it frame. [§10.1] A
may be a macro that expands to a list, B
unless the starred form is used. There are \date{⟨text⟩}
C
other variants to this command not Defined in: Most classes that have the
described here. See the etextools concept of a title page.
D
documentation for further details. [§2.7] E
Specifies the document date. This
command doesn’t display any text so may
F
\csxappto{⟨cs-name⟩}{⟨code⟩}
be used in the preamble, but if it’s not in the G
Defined in: etoolbox package. H
preamble it must be placed before
As \xappto but requires the name (without \maketitle. If omitted, most classes I
the leading backslash) of the control assume the current date. Some classes, J
sequence. [§2.1] such as beamer, provide an optional K
argument for this command. [§5.1]
\csxdef{⟨cs-name⟩}⟨arg-syntax⟩ L
{⟨definition⟩} \dateset{⟨date⟩} M
Defined in: etoolbox package. Defined in: newlfm class. N
This is analogous to \xdef except that the Sets the date. [§3.3] O
name of the control sequence (without the P
initial backslash) is supplied. [§2.1] \day Q
\csxpreto{⟨cs-name⟩}{⟨code⟩} Defined in: TEX primitive. R
Defined in: etoolbox package. The current day of the month. [§7.2] S
T
Global version of \csepreto. [§2.1] \DBIBcitekey
U
\CurrentOption Defined in: databib package. V
Defined in: LATEX Kernel. For use with \DTLforeachbibentry or W
\gDTLforeachbibentry, this expands to the X
Refers to the current option when used in
name of the current cite key. [§5.2] Y
the argument of \DeclareOption* [§11.1]
\DBIBentrytype Z
\CutLine{⟨page-number⟩}
Defined in: databib package.
Defined in: leaflet class (preamble only).
Indicates that a cut line should be drawn to For use with \DTLforeachbibentry or
the left of the given page number. The \gDTLforeachbibentry, this expands to the
starred version only draws a dotted line. name of the current entry type (for
The unstarred version draws a dotted line example, book). [§5.2]
and a pair of scissors. [§10.3] \decision{⟨theme⟩}{⟨short-description⟩}
\begin{cv}{⟨heading⟩} [⟨long-description⟩]
Generates a bar chart from a column of the Defined in: datatool package.
datatool database called ⟨db-name⟩. [§12.3] A case-sensitive comparison handler for
use with \dtlsort. [§2.4]
\DTLbarchartlength
Defined in: databar package. \DTLcustombibitem{⟨marker-code⟩}{⟨ref-
text⟩}{⟨key⟩}
A length register storing the total length of
the 𝑦-axis. [§12.3] Defined in: databib package.
This command is analogous to
\DTLbarlabeloffset \bibitem[⟨label⟩]{⟨key⟩} except it uses
Defined in: databar package. ⟨marker code⟩ instead of \item[⟨label⟩].
[§5.2]
A length register storing the offset between
the 𝑥-axis and the lower bar label. [§12.3] \dtldefaultkey
Defined in: datatool package.
Summary of Commands and Environments 439
\DTLmaketabspace \dtlneg{⟨cs⟩}{⟨number⟩}
Defined in: datatool package. Defined in: datatool package.
Changes the category code of the tab Negates ⟨number⟩ and stores the result in
separator to 10 (space). [§2.2] ⟨cs⟩, which must be a control sequence. The
number must be a plain decimal number (a
\DTLmidpt full stop as a decimal point, no number
Defined in: databar package. grouping and no currency prefix). [§2.1]
For use within the definition of \DTLnewdb{⟨db-name⟩}
\DTLeverybarhook, this can be used to
Defined in: datatool package.
reference the mid point of the bar. [§12.3]
Creates a new database called ⟨db-name⟩.
\DTLmonthname{⟨number⟩} [§9.4]
Defined in: databib package.
\DTLnewdbentry{⟨db-name⟩}{⟨col-label⟩}
Displays the month name for the month {⟨value⟩}
given by ⟨number⟩. [§5.2]
Defined in: datatool package.
Summary of Commands and Environments 442
Ends an environment. (Must have a the same as ⟨text2⟩. (Both arguments are Symbols
matching \begin. See Volume 1 [93, §2.15].) expanded.) [§2.7] A
[§1.2] B
\begin{europecv}
\endfirsthead C
Defined in: europecv class.
Defined in: longtable package. D
The body of the CV. [§5.2] E
Marks the end of the header code for the
first page of the longtable environment. [§4.3] \evensidemargin F
Defined in: LATEX Kernel. G
\endfoot H
A length containing the horizontal offset for
Defined in: longtable package. I
even pages. See \hoffset. [§11.0]
Marks the end of the footer code for the J
longtable environment. [§4.3] \everypar{⟨code⟩} K
\endhead
Defined in: TEX primitive. L
Indicates code to be performed at the start M
Defined in: longtable package.
of every paragraph. [§6.5] N
Marks the end of the header code for the O
longtable environment. [§4.3] exists(⟨ref⟩)
P
Defined in: arara directive.
\endinput Q
Defined in: TEX primitive. Evaluates to true if the given file doesn’t R
exist. The argument ⟨ref⟩ may either be a S
Stops reading the current file. Anything in string "⟨extension⟩" which indicates the file
the current file occurring after this extension or a file reference
T
command is skipped. [§7.3] toFile("⟨filename⟩"). [§1.2] U
V
\endlastfoot \expandafter⟨token 1⟩⟨token 2⟩ W
Defined in: longtable package. Defined in: TEX primitive. X
Marks the end of the footer code for the Equivalent to ⟨token 1⟩ expansion of ⟨token Y
last page of the longtable environment. [§4.3] 2⟩. [§2.7]
Z
\endtime{⟨time⟩} \expandonce⟨cs⟩
Defined in: minutes package. Defined in: etoolbox package.
Specifies the end time of the meeting. [§6.3] Only permits one level of expansion of the
\caption may be used one or more times, prematurely terminate the loop after the Symbols
as required. (See Volume 1 [93, §7.1].) [§2.1] current iteration. [§2.7] A
\FilledSmallCircle \foreachdataset{⟨cs⟩}{⟨body⟩} B
C
Defined in: ifsym package with geometry Defined in: probsoln package.
option.
D
Iterates over all defined datasets and E
Produces a small filled circle. [§11.1] performs ⟨body⟩ at each iteration. [§9.3]
F
\FirstLabel{⟨row⟩}{⟨column⟩} \foreachproblem[⟨dataset⟩]{⟨body⟩} G
Defined in: envlab package. Defined in: probsoln package. H
Sets the starting label on a partially used Iterates through the given dataset and does I
sheet. [§3.6] ⟨body⟩ at each iteration. Within ⟨body⟩, J
\thisproblem may be used to display the K
\begin{flushright} current problem and \thisproblemlabel L
Defined in: LATEX Kernel. may be used to access the current problem M
label. [§9.3]
Aligns its contents flush-right and places N
a small vertical gap above and below the \foreachsolution[⟨dataset⟩]{⟨body⟩} O
environment. [§10.3] P
Defined in: probsoln package.
\fontfamily{⟨name⟩} Similar to \foreachproblem but only
Q
Defined in: LATEX Kernel. iterates through problems that contain the R
onlysolution environment. [§9.3] S
Sets the name of the current font family.
(The change won’t take effect until the next
T
\forlistcsloop{⟨handler-cs⟩}{⟨list-
\selectfont.) For example, in text mode, U
csname⟩}
\rmfamily is equivalent to V
Defined in: etoolbox package.
\fontfamily{cmr}\selectfont (unless it’s W
been modified by a font package.) [§6.4] Similar to \forlistloop except the list X
control sequence name (without the leading Y
\fontseries{⟨weight⟩} backslash) is used. [§2.7]
Z
Defined in: LATEX Kernel.
\forlistloop{⟨handler-cs⟩}{⟨list-cs⟩}
Sets the name of the current font series.
(The change won’t take effect until the next Defined in: etoolbox package.
\selectfont.) For example, in text mode, Similar to \dolistloop except it uses
\bfseries is equivalent to ⟨handler-cs⟩ instead of \do at each
\fontseries{b}\selectfont (unless it’s iteration. [§2.7]
been modified by a font package.) [§6.4]
\begin{Form}[⟨parameters⟩]
\footnote[⟨number⟩]{⟨text⟩} Defined in: hyperref package.
Defined in: LATEX Kernel. Environment containing interactive form
Inserts a footnote. [§2.1] elements. [§11.2]
\ifstrempty{⟨string⟩}{⟨true-part⟩}{⟨false- \include{⟨filename⟩}
part⟩} Defined in: LATEX Kernel.
Defined in: etoolbox package. Issues a \clearpage, creates an associated
Tests if ⟨string⟩ is empty. (No expansion is auxiliary file, inputs ⟨filename⟩ and issues
performed on ⟨string⟩.) [§7.3] another \clearpage. (See also \input.)
[§13.0]
\ifstrequal{⟨string1⟩}{⟨string2⟩}{⟨true-
part⟩}{⟨false-part⟩} \includegraphics[⟨option-list⟩]
{⟨filename⟩}
Defined in: etoolbox package.
Defined in: graphicx package.
Tests if ⟨string1⟩ is the same as ⟨string2⟩.
(No expansion is performed on ⟨string1⟩ or Inserts a graphics file into the document.
⟨string2⟩.) [§7.4] Permitted file types depend on the output
format. (PostScript (PS) and Encapsulated
\ifthenelse{⟨condition⟩}{⟨true⟩}{⟨false⟩} PostScript (EPS) for the DVI format. PDF,
Defined in: ifthen package. JPG and PNG for the PDF format (also EPS
if the TEX distribution permits on-the-fly
If the condition is met, does ⟨true⟩ epstopdf conversion). [§3.2]
otherwise does ⟨false⟩. The ⟨condition⟩
Summary of Commands and Environments 452
As \listadd but the assignment is global. list⟩ and adds them to the given dataset. Symbols
[§2.7] [§9.3] A
\listofchanges[⟨options⟩] \loadrandomexcept[⟨dataset⟩]{⟨n⟩} B
{⟨filename⟩}{⟨exception-list⟩} C
Defined in: changes package.
Defined in: probsoln package.
D
Print a list or summary of the changes. At E
least two LATEX runs are required to make Loads ⟨n⟩ randomly selected problems
the list appear. [§13.1] defined in the given filename excluding
F
those listed in ⟨exception list⟩ and adds G
\listofdecisions them to the given dataset. [§9.3] H
Defined in: minutes package. I
\loadrandomproblems[⟨dataset⟩]{⟨n⟩}
Displays a list of decisions. [§6.3] J
{⟨filename⟩}
K
\listoffigures Defined in: probsoln package.
L
Defined in: Most classes that have the Loads ⟨n⟩ randomly selected problems M
concept of document structure. defined in the given filename and adds
N
Inserts the list of figures. A second them to the given dataset. [§9.3]
O
(possibly third) run is required to ensure \loadselectedproblems[⟨dataset⟩] P
the page numbering is correct. [§13.1] {⟨labels⟩}{⟨filename⟩} Q
\listoftables Defined in: probsoln package. R
Defined in: Most classes that have the Loads the listed problems defined in the S
concept of document structure. given filename and adds them to the given T
Inserts the list of tables. A second (possibly dataset. [§9.3] U
third) run is required to ensure the page \location{⟨text⟩} V
numbering is correct. [§6.3] W
Defined in: letter class.
\listxadd{⟨list-cs⟩}{⟨item⟩} X
Specifies the sender’s additional location Y
Defined in: etoolbox package. information. [§3.1]
Z
As \listeadd but the assignment is global.
\location{⟨place⟩}
[§2.7]
Defined in: minutes package.
\llap{⟨text⟩}
Specifies the location of the meeting. [§6.3]
Defined in: LATEX Kernel.
\long⟨assignment⟩
Places ⟨text⟩ to the left of the reference
point without taking up any space. [§11.1] Defined in: TEX primitive.
An assignment prefix that indicates the
\loadallproblems[⟨dataset⟩]{⟨filename⟩}
following assignment (such as \def) should
Defined in: probsoln package. define a long command. [§2.1]
Loads all problems defined in ⟨filename⟩
\begin{longtable}[⟨horizontal
and appends them to the specified data set
alignment⟩]{⟨column specifiers⟩}
in the order in which they are defined in
the file. [§9.3] Defined in: longtable package.
Like a combination of the table and tabular
\LoadClass[⟨options⟩]{⟨name⟩}
environments, except it can span multiple
[⟨version⟩]
pages. [§2.6]
Defined in: LATEX Kernel.
\loop⟨code⟩\if... \repeat
Used in class files to load another class.
[§11.1] Defined in: LATEX Kernel.
Repeats code while the given condition is
\loadexceptproblems[⟨dataset⟩]
true. [§2.7]
{⟨exception-list⟩}{⟨filename⟩}
Defined in: probsoln package. \lstinputlisting{⟨options⟩}{⟨filename⟩}
Loads the problems defined in the given Defined in: listings package.
filename except those listed in ⟨exception
Summary of Commands and Environments 456
\nodepart{⟨part⟩} O Symbols
Defined in: tikz package. \oddsidemargin A
For use within the contents of a split node, Defined in: LATEX Kernel. B
this moves from the current split to the A length containing the horizontal offset for C
split identified by ⟨part⟩. [§7.5] odd pages. See \hoffset. [§11.0] D
E
\noexpand⟨token⟩ \onecolumn F
Defined in: TEX primitive. Defined in: LATEX Kernel. G
Prevents ⟨token⟩ from being expanded in Issues a page break and switches to one H
an expandable context. [§2.1] column mode. [§10.5] I
\noindent \begin{oneparcheckboxes} J
Defined in: LATEX Kernel. K
Defined in: exam class.
Suppress the indentation that would usually Checkbox choices are listed inline. Items
L
occur at the start of the next paragraph. M
are specified via \choice. [§9.1]
[§9.1] N
\begin{oneparchoices} O
\noprintanswers
Defined in: exam class. P
Defined in: exam class. Q
Labelled choices are listed inline. Items are
Disable (don’t show) the solutions. [§9.1] R
specified via \choice. [§9.1]
\normalsize S
\begin{onlyproblem}[⟨option⟩] T
Defined in: LATEX Kernel.
Defined in: probsoln package. U
Switches to normal sized text. [§10.3]
Only displays its contents if the V
\number⟨num⟩ showanswers boolean flag is off. [§9.3] W
Defined in: TEX primitive. \begin{onlysolution}[⟨option⟩] X
Displays the decimal value of ⟨num⟩. (Any Defined in: probsoln package. Y
redundant leading zeros are stripped.) [§2.1] Z
Only displays its contents if the
\numexpr⟨integer expression⟩ showanswers boolean flag is on. [§9.3]
Defined in: 𝜀-TEX primitive. \opening{⟨salutation⟩}
Expands to the value given by the integer Defined in: Classes that define the letter
expression. [§2.1] environment.
\numparts Typesets the salutation at the start of the
Defined in: exam class. letter. [§3.1]
A length containing the total width of the Defined in: minutes package.
page. See also \textwidth. [§10.3] Specifies the names of the people present.
[§6.3]
\par
Defined in: TEX primitive \begin{parts}
(context-dependent). Defined in: exam class.
Insert a paragraph break. Usually just Contains all the question parts. [§9.1]
a blank line in the source code is used
instead of \par. This command is typically \PassOptionsToClass{⟨option-list⟩}
only used within command or environment {⟨class⟩}
definitions or when it’s important to remind Defined in: LATEX Kernel.
authors that a paragraph break is required
Passes the given options to the given class.
at a certain point where a blank line may
(Must be used before the class is loaded.)
appear accidental or may be overlooked.
[§11.1]
(For example, in {\centering Some
centred text.\par} it’s a reminder that \path ⟨specification⟩;
there must be a paragraph break before
Defined in: tikz package.
the closing } to ensure the \centering
declaration has an effect.) [§1.0] For use within the tikzpicture environment.
[§7.5]
\paragraph[⟨short-title⟩]{⟨title⟩}
Defined in: Most classes that have the \pdfcreationdate
concept of document structure. Defined in: PDFTEX primitive.
Summary of Commands and Environments 461
The date and time at the start of the current day number for the current iteration (0 for Symbols
TEX run. This expands to Monday, 1 for Tuesday, etc). [§7.5] A
D:⟨YYYY ⟩⟨MM⟩⟨DD⟩⟨hh⟩⟨mm⟩⟨ss⟩⟨time B
zone⟩. This primitive is also available with \pgfcalendarcurrentyear
C
LuaTEX but not XETEX. [§7.4] Defined in: pgfcalendar package.
D
\pdffilemoddate{⟨filename⟩} For use within the ⟨code⟩ part of E
\pgfcalendar. This expands to the year for
Defined in: PDFTEX primitive.
the current iteration. [§7.5]
F
The modification date and time of the file G
⟨filename⟩. This expands to \pgfcalendardatetojulian{⟨date⟩} H
D:⟨YYYY ⟩⟨MM⟩⟨DD⟩⟨hh⟩⟨mm⟩⟨ss⟩⟨time {⟨register⟩} I
zone⟩. Unlike \pdfcreationdate, this Defined in: pgfcalendar package. J
primitive isn’t provided by LuaTEX. [§7.4]
Converts the specified date into a Julian day K
\pgfcalendar{⟨prefix⟩}{⟨start-date⟩} number and stores the result in the given L
{⟨end-date⟩}{⟨code⟩} register. [§7.2] M
Defined in: pgfcalendar package. \pgfcalendarendiso N
A for loop that iterates from ⟨start-date⟩ to Defined in: pgfcalendar package. O
⟨end-date⟩ and performs ⟨code⟩ at each P
iteration. [§7.5] For use within the ⟨code⟩ part of
\pgfcalendar. The ⟨end-date⟩ parameter in
Q
\pgfcalendarbeginiso ISO format. [§7.5] R
S
Defined in: pgfcalendar package. \pgfcalendarendjulian T
For use within the ⟨code⟩ part of Defined in: pgfcalendar package. U
\pgfcalendar. The ⟨start-date⟩ parameter
in ISO format. [§7.5] For use within the ⟨code⟩ part of V
\pgfcalendar. The ⟨end-date⟩ parameter W
\pgfcalendarbeginjulian converted to a Julian day number. [§7.5] X
Defined in: pgfcalendar package. Y
\pgfcalendarifdate{⟨date⟩}{⟨test⟩}{⟨true-
For use within the ⟨code⟩ part of part⟩}{⟨false-part⟩} Z
\pgfcalendar. The ⟨start-date⟩ parameter
Defined in: pgfcalendar package.
converted to a Julian day number. [§7.5]
Tests the specified date and does
\pgfcalendarcurrentday ⟨true-part⟩ if the test succeeds otherwise it
Defined in: pgfcalendar package. does ⟨false-part⟩. [§7.2]
For use within the ⟨code⟩ part of \pgfcalendarjuliantodate{⟨Julian-day⟩}
\pgfcalendar. This expands to the day of {⟨year-cs⟩}{⟨month-cs⟩}{⟨day-cs⟩}
the month for the current iteration. [§7.5]
Defined in: pgfcalendar package.
\pgfcalendarcurrentjulian Converts a Julian day number into an
Defined in: pgfcalendar package. ISO-date. The resulting numbers are stored
For use within the ⟨code⟩ part of in the ⟨year-cs⟩, ⟨month-cs⟩ and ⟨day-cs⟩
\pgfcalendar. This is a TEX count register control sequences. [§7.2]
that holds the Julian day number for the \pgfcalendarjuliantoweekday{⟨Julian-
current iteration. [§7.5] day⟩}{⟨register⟩}
\pgfcalendarcurrentmonth Defined in: pgfcalendar package.
Defined in: pgfcalendar package. Converts a Julian day number into a week
For use within the ⟨code⟩ part of day number (0 for Monday, 1 for Tuesday,
\pgfcalendar. This expands to the month etc). The resulting number is stored in the
for the current iteration. [§7.5] given register. [§7.2]
\pgfcalendarcurrentweekday \pgfcalendarmonthname{⟨month-number⟩}
Defined in: pgfcalendar package. Defined in: pgfcalendar package.
For use within the ⟨code⟩ part of Expands to a textual representation of the
\pgfcalendar. This expands to the week month. [§7.3]
Summary of Commands and Environments 462
\postscript{⟨text⟩} \PrintAddress{⟨address⟩}
Defined in: minutes package. Defined in: envlab package.
Displays additional information that doesn’t Used internally to typeset the recipient’s
form part of the minutes. [§6.3] address. [§3.6]
\pounds \printanswers
Defined in: LAT
EX Kernel. Defined in: exam class.
Pound £ symbol. This robust command Enable (show) the solutions. [§9.1]
may be used in math or text mode. [§2.2]
\PrintBigLabel{⟨from-address⟩}{⟨to-
\ppsitem{⟨text⟩} address⟩}
Defined in: newlfm class. Defined in: envlab package.
Specifies the PPS line. [§3.3] Used internally to typeset the big labels.
[§3.6]
\PRaddress{⟨address⟩}
Defined in: pressrelease class. \PrintReturnAddress{⟨address⟩}
Specifies the company’s address. [§6.2] Defined in: envlab package.
Used internally to typeset the sender’s
\PRcompany{⟨name⟩}
address. [§3.6]
Defined in: pressrelease class.
\printsolutions[⟨settings⟩]
Specifies the company’s name. [§6.2]
Defined in: exsheets package.
\PRdepartment{⟨name⟩}
Prints all the solutions. [§9.2]
Defined in: pressrelease class.
Summary of Commands and Environments 464
Identifies the package name and optionally For use inside the picture environment, this Symbols
the version date. [§4.2] puts ⟨object⟩ at the given co-ordinates A
(which are in terms of \unitlength). [§10.1] B
\PRphone{⟨number⟩}
Q C
Defined in: pressrelease class.
\qbezier[⟨points⟩](⟨start-x⟩,⟨start-y⟩) D
Specifies the company’s phone number.
(⟨control-x⟩,⟨control-y⟩)(⟨end-x⟩,⟨end-y⟩) E
[§6.2]
Defined in: LATEX Kernel. F
\PRsubheadline{⟨text⟩}
For use in the picture, this draws a quadratic
G
Defined in: pressrelease class. Bézier curve with the given start, end and H
Specifies the sub-headline. [§6.2] curvature control points. [§10.1] I
J
\PRurl{⟨website⟩} \qquad
K
Defined in: pressrelease class. Defined in: LATEX Kernel. L
Specifies the company’s website. [§6.2] Horizontal spacing command (twice as wide M
as \quad). [§11.1] N
\ps
\quad O
Defined in: Classes that define the letter
environment. Defined in: LATEX Kernel.
P
Q
Indicates the start of the postscript. [§3.1] Horizontal spacing command equal to the
R
current font’s em value.
\psbarcode[⟨options⟩]{⟨text or S
filename⟩}{⟨PS options⟩}{⟨type⟩} \begin{question}[⟨options⟩]{⟨points⟩} T
Defined in: pst-barcode package. Defined in: exsheets package. U
Generates a bar code. [§10.4] Creates a new question. Both arguments V
are optional! [§9.2] W
\psitem{⟨text⟩}
X
Defined in: newlfm class. \question[⟨points⟩]
Y
Specifies the PS line. [§3.3] Defined in: exam class. Z
Starts a new numbered question, with
\PSNrandom{⟨register⟩}{⟨n⟩}
optionally the number of points the
Defined in: probsoln package. question is worth. [§9.1]
Randomly generates an integer between 1
\begin{questions}
and ⟨n⟩ (inclusive) and stores the result in
the given register. [§9.3] Defined in: exam class.
Contains all the question in the exam. [§9.1]
\PSNrandseed{⟨n⟩}
Defined in: probsoln package. R
Sets the random number generator seed. \raggedright
[§9.3] Defined in: LATEX Kernel.
\begin{pspicture}[⟨baseline⟩](⟨llx⟩,⟨lly⟩) Ragged-right paragraph justification. [§4.3]
(⟨urx⟩,⟨ury⟩)
\random{⟨counter⟩}{⟨min⟩}{⟨max⟩}
Defined in: pstricks package.
Defined in: probsoln package.
Environment for drawing vector graphics.
Randomly generates an integer between
[§10.4]
⟨min⟩ and ⟨max⟩ (inclusive) and stores the
\PushButton[⟨options⟩]{⟨label⟩} result in the given counter. [§9.3]
Defined in: hyperref package. \re{⟨text⟩}
A push button that performs some action Defined in: newlfm class.
(for use within the Form environment.)
[§11.2] Specifies the “re” part of a memo. [§6.1]
\put(⟨x⟩,⟨y⟩){⟨object⟩} \ref{⟨string⟩}
References the value of the counter linked Scales the specified contents to the given Symbols
to the given label. A second (possibly third) dimensions. [§10.3] A
run of LATEX is required to ensure the B
cross-references are up-to-date. (See \RestartCensoring
C
Volume 1 [93, §5.5].) [§1.2] Defined in: censor package.
D
Switches on the censoring. [§6.4]
\refstepcounter{⟨counter⟩} E
Defined in: LATEX Kernel. \result F
Increments the value of the given counter Defined in: minutes package. G
by one and allows the counter to be For use within the Argumentation H
cross-referenced using \ref and \label. environment, this indicates the start of an I
[§2.1] item indicating the result of the argument. J
\regarding{⟨text⟩} [§6.3] K
Defined in: newlfm class. \returnaddress
L
M
Specifies subject of letter. [§3.3] Defined in: envlab package.
N
\relax The return address. Defaults to the address O
given by \address [§3.6]
Defined in: TEX primitive. P
Unexpandable nothing. [§2.1]
\rightarrow Q
Defined in: LATEX Kernel (Math Mode). R
\release{⟨text⟩} S
Right arrow Ï. [§9.3]
Defined in: newlfm class. T
\rlap{⟨text⟩} U
Specifies the release information. [§6.2]
Defined in: LATEX Kernel. V
\renewcommand{⟨cmd⟩}[⟨n-args⟩]
[⟨default⟩]{⟨text⟩}
Places ⟨text⟩ to the right of the reference W
point without taking up any space. [§11.0] X
Defined in: LATEX Kernel.
\rmfamily Y
Redefines an existing command. (See Z
Volume 1 [93, §8.2].) [§2.1] Defined in: LATEX Kernel.
Switches to the predefined serif font.
\renewenvironment{⟨env-name⟩}[⟨n-args⟩]
(Defaults to Computer Modern Roman.)
[⟨default⟩]{⟨begin-code⟩}{⟨end-code⟩}
Defined in: LATEX Kernel. \Roman{⟨counter⟩}
Redefines an existing environment. [§6.5] Defined in: LATEX Kernel.
Displays counter value as an upper case
\replaced[⟨options⟩]{⟨new-text⟩}{⟨old-
Roman number. (I, II, III, . . . ) [§9.2]
text⟩}
Defined in: changes package. \roman{⟨counter⟩}
Indicates that ⟨old-text⟩ has been replaced Defined in: LATEX Kernel.
with ⟨new text⟩. [§13.1] Displays counter value as a lower case
Roman number. (i, ii, iii, . . . ) [§6.5]
\RequirePackage[⟨options⟩]{⟨name⟩}
[⟨version⟩] \romannumeral⟨number⟩
Defined in: LAT
EX Kernel. Defined in: TEX primitive.
Analogous to \usepackage but for use in Expands ⟨number⟩ to a lower case Roman
class or package files. [§4.2] numeral. [§6.5]
\Reset[⟨options⟩]{⟨label⟩} \rotatebox[⟨option-list⟩]{⟨angle⟩}{⟨text⟩}
Defined in: hyperref package. Defined in: graphicx package.
A reset button that resets the form (for use Rotates the given contents by the given
within the Form environment.) [§11.2] angle. [§3.6]
\resizebox{⟨h-length⟩}{⟨v-length⟩}{⟨text⟩} \rule[⟨raise⟩]{⟨width⟩}{⟨height⟩}
Defined in: graphicx package. Defined in: LATEX Kernel.
Summary of Commands and Environments 467
\setbeamercovered{⟨options⟩} \setkomavar{⟨name⟩}[⟨description⟩]
{⟨content⟩}
Defined in: beamer class.
Defined in: KOMA-Script classes.
Sets how covered material should appear.
Sets the content and optionally the
[§8.1]
description of a KOMA-Script variable.
[§3.2]
Summary of Commands and Environments 468
\sffamily \begin{solution}
Starts a new numbered question sub-part, Prints the date in the form Symbols
with optionally the number of points the ⟨YYYY ⟩-⟨MM⟩-⟨DD⟩ when the file was A
sub-part is worth. [§9.1] checked out or the current date if B
unknown. [§13.2]
\begin{subparts} C
Defined in: exam class. \svnInfoDay D
Defined in: svninfo package. E
Contains all the question sub-parts. [§9.1]
Prints the day (in ⟨DD⟩ form) when the file
F
\subsection[⟨short-title⟩]{⟨title⟩} was checked out or the current day if G
Defined in: Most classes that have the unknown. [§13.2] H
concept of document structure. I
\svnInfoFile
Inserts a subsection header. [§6.3] J
Defined in: svninfo package. K
\subsubpart[⟨points⟩] Prints the name of the source file or L
Defined in: exam class. --sourcefile-- if unknown. [§13.2] M
Starts a new numbered question \svnInfoHeadURL N
sub-sub-part, with optionally the number of O
points the sub-sub-part is worth. [§9.1] Defined in: svninfo package.
P
Prints the information obtained from the
\begin{subsubparts} HeadURL keyword. [§13.2]
Q
Defined in: exam class. R
Contains all the question sub-sub-parts.
\svnInfoLongDate S
[§9.1] Defined in: svninfo package. T
Prints date in the form of \today when the U
\subsubsection[⟨short-title⟩]{⟨title⟩} V
file was checked out or the current date if
Defined in: Most classes that have the unknown. [§13.2] W
concept of document structure. X
\svnInfoMaxRevision
Inserts a subsubsection header. [§6.5] Y
Defined in: svninfo package.
\subtitle{⟨title⟩} Z
Prints the maximum revision number for
Defined in: Various classes or packages all the files in the document or
that have the concept of a subtitle. --maxrevision-- if unknown. [§13.2]
Specifies the subtitle. Usually for use with
\svnInfoMaxToday
\maketitle in a similar manner to \title.
Some classes, such as beamer, also provide Defined in: svninfo package.
an optional argument for this command. Prints date in the form of \today from the
[§6.3] latest Subversion revision. [§13.2]
\subtopic[⟨toc title⟩]{⟨title⟩} \svnInfoMinRevision
Defined in: minutes package. Defined in: svninfo package.
Starts a new subtopic. [§6.3] Prints the minimum revision number for all
the files in the document or
\svnId
--minrevision-- if unknown. [§13.2]
Defined in: svninfo package.
\svnInfoMonth
Prints a summary of the Subversion
information in the same form as the Id Defined in: svninfo package.
keyword anchor. [§13.2] Prints the month (in ⟨MM⟩ form) when the
file was checked out or the current month
\svnInfo $⟨Id⟩$
if unknown. [§13.2]
Defined in: svninfo package.
Parses the Subversion Id keyword anchor. \svnInfoOwner
[§13.2] Defined in: svninfo package.
\begin{tikzpicture}[⟨options⟩] \totalpoints
Defined in: tikz package. Defined in: exsheets package.
Environment for drawing vector graphics. Displays the total number of points,
[§7.5] including bonus points. (Requires two LATEX
runs to ensure it’s up to date.) The starred
\time version omits the unit. [§9.2]
Defined in: TEX primitive.
\two@digits{⟨number⟩}
The current time expressed as the number
Defined in: LATEX Kernel.
of minutes since midnight. [§7.4]
Displays ⟨number⟩, ensuring that it has at
\title{⟨text⟩} least two digits. (If ⟨number⟩ is less than 10
Defined in: Most classes that have the a leading 0 is inserted.) [§7.4]
concept of a title page.
\twocolumn
Specifies the document title. This command
doesn’t display any text so may be used in Defined in: LATEX Kernel.
the preamble, but if it’s not in the preamble Issues a page break and switches to two
it must be placed before \maketitle. Some column mode. [§10.5]
classes, such as beamer, provide an optional
argument for this command. [§5.2]
Summary of Commands and Environments 474
\useinnertheme[⟨options⟩]{⟨name⟩} \verbatiminput{⟨filename⟩}
Defined in: beamer class. Defined in: verbatim package.
Loads a beamer inner theme. [§8.2] Inputs the given file verbatim. [§9.4]
\useoutertheme[⟨options⟩]{⟨name⟩} \vfill
Defined in: beamer class. Defined in: LATEX Kernel.
Loads a beamer outer theme. [§8.2] Inserts a vertical space that will expand to
fit the available height. [§3.6]
\usepackage[⟨option-list⟩]{⟨package-list⟩}
\begin{Vote}
Defined in: LATEX Kernel.
Defined in: minutes package.
Summary of Commands and Environments 475
\XBox
Defined in: wasysym package.
Produces a square with a cross in it 4.
[§11.1]
\xdef⟨cs⟩⟨arg-syntax⟩{⟨definition⟩}
Defined in: TEX primitive.
As \edef but the definition is global. [§2.1]
\xDTLassignfirstmatch{⟨db-name⟩}{⟨col-
label⟩}{⟨value⟩}{⟨assign-list⟩}
Defined in: datatool package.
Finds the first row in the database
⟨db-name⟩ where entry in the column
identified by the label ⟨col-label⟩ matches a
one level expansion of ⟨value⟩ and applies
the assignment list, which has the same
format as for \DTLforeach and
\DTLforeach*. See also
\DTLassignfirstmatch. [§2.8]
Symbols
A
B
Index C
Page numbers in bold indicate the entry definition in the summary. D
E
F
Symbols \{ 28, 428 G
290, 334, 360, 426 \} 28, 428
! H
␣ 2, 425, 426 ] 2, 429
^ 28, 425, 429, 454 I
" 27
_ 28, 425, 429, 454 J
# 15, 28, 73, 187, 196, 347, 425, 426
## 73, 426 { 2, 28, 61, 425, 429 K
$ 28, 29, 293, 423, 425, 426 } 2, 28, 425, 429 L
% 2, 28, 41, 252, 412, 423–425, 426 ~ 28, 423, 425, 429 M
% arara: 5, 426 N
& 28, 58, 121, 126, 140, 425, 426 A O
-- 22, 136, 154, 362, 427 about environment 154, 429 P
--- 82, 427 accept (isodoc) 120
< 362, 427 Q
acceptaccount (isodoc) 120
> 129, 362, 427 acceptaddress (isodoc) 120
R
\@ 423, 427 acceptcents (isodoc) 121 S
@ 291, 423, 424, 427, 456 acceptdescription (isodoc) 121 T
\@afterheading 180, 427 accepteuros (isodoc) 121 U
\@auxout 275, 427 acceptreference (isodoc) 121 V
\@currenvir 12, 427 \accountdata 121, 122, 429
\@endfortrue 427 W
accountname (isodoc) 120
\@enumdepth 177, 427 accountno (isodoc) 120
X
\@firstoftwo 340, 427 active character 423, 425 Y
\@for 62, 64, 65, 423, 424, 427 \added 391, 392, 429 Z
\@genderlist 344 id 391
\@ifundefined 18, 428 remark 391
\@listdepth 177 addedmarkup (changes) 391
\@namedef 19, 428 \addevent 219
\@nameuse 19, 428 \addplot 382–384, 386, 429
\@projectlist 344 \addpoints 240, 429
\@secondoftwo 340, 428 addpoints (exam) 239, 240, 242, 243
\@timezonefmt 199 \address 87, 105, 110, 111, 116, 429
\@toodeep 177, 428 addrfield (KOMA option) 92
[ 2, 428 \addrfrom 97, 106, 118, 149, 151, 429
\& 28, 232, 428 addrfromemail (newlfm) 98
\$ 28, 124, 428 addrfromfax (newlfm) 98
\# 28, 428 addrfromleft (newlfm) 98
\% 28, 205, 428 addrfromphone (newlfm) 98
\ 425, 428 addrfromright (newlfm) 98
\" 158, 428 \addrto 96, 107, 118, 429
\, 129, 428 addrtoemail (newlfm) 98
\[ 262, 277, 428 addrtofax (newlfm) 98
\\ 121, 126, 128, 140, 281, 379, 380, 428 addrtoleft (newlfm) 98
\' 132, 283, 351, 428 addrtophone (newlfm) 98
\␣ 199, 428 addrtoright (newlfm) 98
\] 262, 277, 428 \AddToBackground 289, 290, 293, 429
\_ 28, 428 \addtolength 176, 429
` 129, 429 Adobe Reader 182, 349, 351
`` 62, 429 \advance 23, 429
' 129, 427 agenda (meetingmins) 154–156
'' 62, 427 Alegreya package 290
476
Index 477
.csv 9, 27–33, 36, 43–45, 47, 49, 55, 79, frame environment 223, 224, 226, 448 Symbols
122, 126 \framebox 282, 448 A
.dbtex 27, 29, 32, 33, 36, 39, 78, 79 \framebreak 304, 448 B
.jdr 313, 318, 322 framed package 326
C
.ods 32, 33, 47 \framesubtitle 224, 448
.odt 389 \frametitle 224, 226, 448 D
.soc 391 fromaddress (KOMA variable) 91 E
.tdf 284 fromalign (KOMA option) 92 F
.xls 32, 33, 38, 47, 55, 58 fromemail (KOMA option) 92 G
\filedate 202 fromemail (KOMA variable) 91 H
\FilledSmallCircle 334, 447 fromfax (KOMA option) 92
I
final (changes) 391 fromfax (KOMA variable) 91
final (probsoln) 251 fromlogo (KOMA option) 92 J
firstfoot (KOMA variable) 91 fromlogo (KOMA variable) 91, 94 K
firsthead (KOMA option) 92 frommobilephone (KOMA option) 92 L
firsthead (KOMA variable) 91 frommobilephone (KOMA variable) 91 M
\FirstLabel 110, 447 fromname (KOMA variable) 91 N
\Fld@height 358 fromphone (KOMA option) 92
O
\Fld@width 358 fromphone (KOMA variable) 91
flowchart package 359 fromurl (KOMA option) 92 P
flowfram package 279, 300, 302, 304, 310, 322, fromurl (KOMA variable) 91 Q
329, 424 frontside (leaflet) 289 R
pages=absolute 301 fullmemo (newlfm) 148 S
flowframtk 279, 306, 318, 322, 424 T
flushright environment 290, 447 G U
foldmark (leaflet) 289
foldmarks (KOMA option) 91, 93 \ganttbar 379, 380, 448 V
fontenc package 28, 124, 126, 134, 425 ganttchart environment 378, 379, 448 W
T1 124 time slot format 378 X
\fontfamily 171, 447 \ganttgroup 380, 448
\ganttlinkedbar 380, 448
Y
\fontseries 171, 447 Z
fontspec package 28, 425 \ganttlinkedgroup 380, 448
footer (isodoc) 102 \ganttlinkedmilestone 380, 448
\footnote 20, 447 \ganttmilestone 380, 448
footsepline (KOMA option) 93 \ganttnewline 378–380, 448
\for@block 341 \ganttset 378, 448
forcedate (isodoc) 102 \gantttitle 379, 448
\forcsvlist 60, 61, 73, 447 \gantttitlecalendar 379, 380, 449
\foreach 63, 65, 216, 218, 220, 379, 447 \gantttitlecalendar* 379, 449
\foreachdataset 258, 259, 447 \gantttitlelist 379, 449
\foreachproblem 258, 263, 277, 447 \gappto 19, 449
\foreachsolution 258, 263, 277, 447 \gdef 16, 17, 69, 341, 347, 348, 449
foreign (isodoc) 101 \gDTLforeachbibentry 140–142, 144, 145,
\foreignfalse 101 449
\foreigntrue 101 \gender 344
\forlistcsloop 67, 447 geometry (ifsym) 334
\forlistloop 63, 67, 73, 447 geometry package 84, 170, 283, 286, 304, 310
Form environment 349, 447 \getflowbounds 329, 449
\form@block 343 \getflowevenbounds 329, 449
\form@fillin 332, 335 gitinfo2 package 395
\form@layout@checkbox 335, 336 \global 14, 24, 57, 70, 217, 218, 221, 261,
\form@layout@fillin 335, 336 265, 276, 277, 340, 449
Foxit 351 Google Chrome 351
fp package 24, 275 GOW 395, 424
\FPrandom 275, 447 \gpreto 20, 449
\FPseed 275, 448 \gradetable 243, 449
\frac 262, 448 graphicx package 93, 113, 133, 283, 285, 286,
\frame 299, 448 359
gray (databar) 373
Index 484
gray (datapie) 364 \includegraphics 94, 96, 111, 153, 167, 171, Symbols
\greetto 96, 107, 118, 449 224, 231, 232, 283, 285, 286, 291, 296, A
\guest 157, 158, 449 300, 302, 304, 318, 451 B
GUI 33, 35, 36, 43, 49, 263, 279, 306, 424 \includequestions 250, 452
C
\incorrectitem 253, 452
\incorrectitemformat 254, 452 D
H
inparaenum environment 250, 452 E
\half 239, 240, 242, 449 \input 32, 257, 388, 452 F
\headline 151, 449 inputenc package 28, 29, 124, 423, 425
headsepline (KOMA option) 93
G
utf8 28 H
helvetica (europecv) 133 \InputIfFileExists 166, 269, 452
herma4625label (envlab) 110 \inst I
223, 224, 232, 452
\hfill 113, 116, 449 \institute 223, 224, 232, 452 J
hiddenitems environment 155, 449 internal command 5, 17, 22, 62, 177, 180, 424 K
hiddensubitems environment 155, 449 \invoice 120, 121, 452 L
hiddentext environment 156, 449 invoice environment 122, 452
\hideanswers 251, 449 invoice (KOMA variable)
M
91 N
\hoffset 328, 450 invoice package 120, 122, 125, 126
horizontal (databar) 374 isodoc class O
84, 99, 105, 108, 120, 126
\hrulefill 240, 241, 326, 327, 331, 335, 348, accept 120 P
450 acceptaccount 120 Q
\hspace 113, 116, 328, 450 acceptaddress 120 R
\Huge 290, 450 acceptcents 121
hyperref package 41, 349, 350
S
acceptdescription 121 T
pdfauthor 41 accepteuros 121
\hypersetup 41, 450 U
acceptreference 121
accountname 120 V
I accountno 120 W
iban (isodoc) 120 areacode 101 X
ICO 44, 424 autograph 102, 103 Y
\ifbool 252, 265, 450 bic 120 Z
\ifboolexpr 80, 117, 450 cellphone 102
\ifcase 190, 273, 450 city 101
\ifcsbool 80, 82, 117 cityzip 101
\ifcsdef 18, 215, 219, 333, 336, 337, 450 closing 102
\ifcsundef 18, 450 company 101
\ifdate 204, 207–210, 214–216, 218–221, 450 copyto 102
\ifdef 18, 194, 195, 261, 450 country 101
\ifdefempty 79, 81, 198, 200, 450 countrycode 101
\ifdefstring 79, 118, 450 currency 120
\ifinlist 66, 450 date 102
\ifinlistcs 67, 451 email 102
\ifnum 68, 177, 201, 216, 218, 220, 272, 451 enclosures 102
\ifnumless 145, 451 fax 102
\ifodd 328, 329, 451 footer 102
\ifshowanswers 252, 254, 451 forcedate 102
\ifstrempty 192, 194, 451 foreign 101
\ifstrequal 197, 201, 451 iban 120
ifsym package 334 language 101, 102
geometry 334 logoaddress 101
ifthen package 58, 108, 252, 263 opening 102
\ifthenelse 58, 145, 198, 252, 265, 451 ourref 102
\ifthispageodd 328, 451 phone 102
\ifundef 18, 260, 276, 277, 451 phoneprefix 102
\ignorespaces 254, 451 return 101
\ignorespacesafterend 254, 451 returnaddress 101
\iitem 121, 122, 451 routingno 120
\include 388, 451 signature 102
Index 485
twopart 289, 293 \makeatother 17, 62, 65, 177, 180, 358, 424, Symbols
\leftmargin 176, 453 456 A
\LenToUnit 289, 290, 453 \makebox 240, 241, 282, 283, 285, 286, 327, B
\let 13, 14, 18, 24, 32, 328, 331, 335, 348, 456
C
70, 199, 201, 205, 213, 215, 218, 220, \MakeButtonField 355, 456
261, 276, 277, 337, 340, 453 \MakeCheckField 355, 357, 456 D
\letcs 18, 454 \MakeChoiceField 355, 456 E
\letter 101, 103, 454 makeindex 390 F
letter environment 84, 87, 94, 101, 105, 432, \makelabels 108, 111, 116, 456 G
433, 445, 454, 459, 465 \MakeRadioField 355, 456 H
letter class 84, 105, 108, 111 makeshape package 359
I
\lim 262, 454 \MakeTextField 355, 456
\line 280, 454 \maketitle 131, 155, 157, 223, 456 J
\lineskip 113, 454 \MakeUppercase 119, 456 K
\linewidth 129, 304, 454 ManyBibs (currvita) 131 L
\lipsum 168, 171, 178, 181, 302, 454 \marginpar 181, 272, 456 M
lipsum package 168, 171, 178, 302 markup (changes) 391 N
\list 177 math=pgfmath (datatool) 24
O
list environment 175, 454 \mbox 215, 217–219, 221, 222, 456
list or summary of changes file (.soc) 391 mdframed package 326 P
\listadd 65, 66, 454 \medskip 372, 456 Q
\listcsadd 66, 454 meetingmins class 154, 156, 159 R
\listcseadd 66, 454 agenda 154–156 S
\listcsgadd 66, 454 chair 154–156 T
\listcsxadd 66, 454 notes 154, 156
U
\listeadd 66, 454 memonofrom (newlfm) 148
\listgadd 66, 454 memonore (newlfm) 148 V
listings package 263 memonoto (newlfm) 148 W
\listofchanges 391, 455 \midrule 57, 129, 456 X
style 391 minipage environment 113, 454, 456, 460 Y
\listofdecisions 161, 455 minitoc package 158 Z
\listoffigures 391, 455 Minutes environment 157, 162, 456
\listoftables 161, 455 minutes package 154, 156, 159, 162
\listxadd 66, 455 Secret 159
\llap 332, 455 \minutesdate 157, 158, 456
lmodern package 286 \minutetaker 157, 158, 457
\loadallproblems 257, 261, 423, 455 \missing 157, 158, 457
\LoadClass 330, 335, 348, 455 \missingExcused 157, 457
\loadexceptproblems 257, 455 \missingNoExcuse 157, 457
\loadrandomexcept 258, 455 \mlabel 117, 119, 457
\loadrandomproblems 258, 259, 262, 455 \moderation 157, 158, 457
\loadselectedproblems 257, 455 \month 185, 190, 195, 197, 457
\location 87, 105, 111, 116, 157, 158, 455 multi-line cell 29, 32
location (KOMA variable) 92 multibib package 131
locfield (KOMA option) 92 \multicolumn 58, 82, 127–129, 457
logoaddress (isodoc) 101 multiple choice 245
\long 17, 348, 455 \multiply 23, 457
longtable environment 53, 55–57, 126, 130, \multiput 283, 457
138, 141, 145, 455 mwe package 96
longtable package 53, 55, 120, 126 myref (KOMA variable) 92
\loop 68, 343, 455
\lstinputlisting 263, 455 N
lstlisting environment 224, 456
\n 424
\name 87, 105, 111, 116, 457
M \namefrom 97, 106, 118, 149, 151, 457
make 271, 424 \nameto 96, 107, 118, 148, 149, 457
\makeatletter 17, 62, 65, 177, 180, 358, 424, narrow (europecv) 133
456 natbib package 138
Index 487
\NeedsTeXFormat 193, 329, 335, 348, 457 nextfoot (KOMA variable) 91 Symbols
\newbool 263, 457 nexthead (KOMA variable) 91 A
\newboolean 263, 457 \nextmeeting 156, 458 B
\newcommand 10, 12, 14–16, 273, 347, 457 \noaddpoints 240, 458
C
\newcount 22, 68, 185, 188, 192, 194, noaddrfrom (newlfm) 98
207–210, 215, 217, 218, 222, 260, 340, noanswers (probsoln) 251 D
342, 343, 457 \NoBgThisPage 167, 458 E
\newcounter 22, 142, 144, 176, 178, 179, 457 \nobibliography 138, 458 F
\newdynamicframe 301, 304, 458 nocapaddress (envlab) 113, 115 G
\newenvironment 346–348, 458 \nocite 133, 138, 140, 142, 144, 458 H
\newflowframe 301, 302, 304, 458 nocombine (leaflet) 289
I
\newglossaryentry 17, 458 NoDate (currvita) 131
\newlength 176, 329, 458 \node 206, 360, 363, 458 J
newlfm environment 96, 101, 105, 107, 148, \nodepart 211–214, 216–219, 221, 222, 459 K
458 \noexpand 20, 459 L
newlfm class 84, 96, 99, 105, 117, 148, 149 nofancy (svninfo) 397 M
addrfromemail 98 nofoldmark (leaflet) 289 N
addrfromfax 98 \noindent 253, 254, 327, 459
O
addrfromleft 98 nologo (europecv) 133
addrfromphone 98 \noprintanswers 240, 459 P
addrfromright 98 \normalsize 290, 459 Q
addrtoemail 98 norotateenvelope (envlab) 111 R
addrtofax 98 norotateenvelopes (envlab) 108 S
addrtoleft 98 norotateinner (datapie) 364 T
addrtophone 98 norotateouter (datapie) 365
U
addrtoright 98 notes (meetingmins) 154, 156
busletter 98 notitle (europecv) 133 V
busletternofrom 98 notumble (leaflet) 289 W
datecenter 98 notwopart (leaflet) 289 X
dateleft 98 nousedefaultargs (probsoln) 251 Y
dateno 98 null 43, 76, 79 Z
dateright 98 \number 23, 188, 190, 192, 194, 199, 217–219,
dateyes 98 221, 270, 459
fullmemo 148 numbers=endperiod (KOMA option) 178
memonofrom 148 numericaldate (KOMA option) 92
memonore 148 \numexpr 22, 217–219, 221, 459
memonoto 148 \numparts 243, 459
noaddrfrom 98 \numpoints 243, 459
orderdatefromto 98 \numquestions 243, 459
orderfromdateto 98 \numsubparts 243, 459
orderfromtodate 98 \numsubsubparts 243, 459
pressrelease 151
printallfrom 98 O
printallto 98
sigcenter 98 \oddsidemargin 328, 459
sigleft 98 Okular 351
sigright 98 \onecolumn 300, 459
stdletter 98, 148 oneparcheckboxes environment 245, 459
stdletterfrom 98 oneparchoices environment 245, 459
stdmemo 148 onlyproblem environment 252, 255, 258, 459
useenvlab 117 onlysolution environment 252, 253, 255, 258,
\newlfmP 98, 106, 118, 148, 458 459
\newline 134, 219, 458 Open Document Format (.odt) 389
\newpage 290, 291, 458 Open Document Spreadsheet (.ods) 32, 33,
\newproblem 256, 458 47
\newproblem* 257, 458 openbib (currvita) 131
\newstaticframe 301, 302, 458 \opening 85, 87, 88, 90, 94, 106, 111, 117, 459
\newwatermark 170, 171, 458 opening (isodoc) 102
\opinion 160, 459
Index 488
Opinions environment 160, 459 pgf package 24, 63, 167, 168, 182, 205, 222, Symbols
\or 190 378, 382, 383 A
\ord 191, 194 pgf-pie package 364, 369 B
orderdatefromto (newlfm) 98 \pgfcalendar 204–206, 214–218, 220, 461
C
orderfromdateto (newlfm) 98 pgfcalendar package 189, 204, 378
orderfromtodate (newlfm) 98 \pgfcalendarbeginiso 204, 461 D
OT1 124 \pgfcalendarbeginjulian 204, 461 E
ourref (isodoc) 102 \pgfcalendarcurrentday 204, 216, 461 F
\oval 281, 290, 459 \pgfcalendarcurrentjulian 204, 217, 219, G
221, 461 H
P \pgfcalendarcurrentmonth 204, 461
I
\pgfcalendarcurrentweekday 204, 206, 214,
\p@⟨counter⟩ 172 215, 217–219, 221, 461 J
\p@enumi 174, 460 \pgfcalendarcurrentyear 204, 461 K
\p@enumii 174, 460 \pgfcalendardatetojulian 185, 188, 189, L
\p@enumiii 174, 460 191, 192, 194, 195, 461
\p@enumiv 172, 460
M
\pgfcalendarendiso 204, 461 N
page style \pgfcalendarendjulian 204, 461
empty 304 O
\pgfcalendarifdate 186, 204, 461
pagenumber (KOMA option) 93 \pgfcalendarjuliantodate 186, 192, 195, P
pages=absolute (flowfram) 301 217–219, 221, 461 Q
\pagestyle 283, 304, 310, 460 \pgfcalendarjuliantoweekday 186, 191, R
\paperheight 289, 290, 460 192, 194, 195, 461
\paperwidth 289, 290, 328, 460
S
\pgfcalendarmonthname 189, 192, 194, 220, T
\par 2, 253, 265, 270, 304, 327, 336, 460 461
\paragraph 179, 460 U
\pgfcalendarmonthshortname 189, 462
paralist package 239, 250 \pgfcalendarprefix 204, 462 V
\parbox 216–219, 221, 222, 240, 357, 376, \pgfcalendarshorthand 204, 213, 215, 218, W
454, 456, 460 220, 462 X
\parindent 21, 113, 460 \pgfcalendarsuggestedname 204, 214, 462
\parsemdydate 187
Y
\pgfcalendarweekdayname 189, 192, 194, Z
\parshape 301, 460 462
parskip (KOMA) 90 \pgfcalendarweekdayshortname 189, 218,
\part 242, 287, 460 220, 462
\participant 157, 158, 460 pgffor package 63, 217
parts environment 241, 460 pgfgantt package 378, 448
\PassOptionsToClass 330, 335, 348, 460 \pgfkeys 385, 462
\path 206, 213, 215, 217–221, 293, 334, 335, pgfkeys package 185
360, 378, 383, 460 pgfmath package 24, 261, 275, 381, 385
color 383 \pgfmathdeclarerandomlist 276, 462
dashdotted 383 \pgfmathparse 275, 462
dashed 383 \pgfmathprintnumber 385, 462
dotted 383 \pgfmathrandominteger 276, 277, 462
mark 383 \pgfmathrandomitem 276, 462
mark repeat 383 \pgfmathresult 275
mark size 383 \pgfmathsetseed 275, 462
no markers 383 pgfornament package 293
thick 383 pgfplots package 382
thin 383 \pgfplotsset 382, 384, 385, 462
pdfauthor (hyperref) 41 axis lines* 386
\pdfcreationdate 196, 199, 407, 460 compat 382
\pdffilemoddate 197, 202, 461 height 382
pdflatex 5 major tick length 382
\pdfnow 202 minor tick length 382
\pdfnowtime 199, 202 scale only axis 382
pdftk 41, 167 scaled ticks 386
pdftricks package 296 tick align 382
personalenvelope (envlab) 110 title 382, 385
Index 489
Preamble
The purpose of this License is to make a manual, textbook, or other func-
tional and useful document “free” in the sense of freedom: to assure everyone
the effective freedom to copy and redistribute it, with or without modifying it,
either commercially or noncommercially. Secondarily, this License preserves
for the author and publisher a way to get credit for their work, while not being
considered responsible for modifications made by others.
This License is a kind of “copyleft”, which means that derivative works of the
document must themselves be free in the same sense. It complements the GNU
General Public License, which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free soft-
ware, because free software needs free documentation: a free program should
come with manuals providing the same freedoms that the software does. But
this License is not limited to software manuals; it can be used for any textual
work, regardless of subject matter or whether it is published as a printed book.
We recommend this License principally for works whose purpose is instruction
or reference.
494
GNU Free Documentation License 495
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either commer-
cially or noncommercially, provided that this License, the copyright notices, and
the license notice saying this License applies to the Document are reproduced
in all copies, and that you add no other conditions whatsoever to those of this
License. You may not use technical measures to obstruct or control the reading
or further copying of the copies you make or distribute. However, you may
accept compensation in exchange for copies. If you distribute a large enough
number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you
may publicly display copies.
3. COPYING IN QUANTITY
GNU Free Documentation License 496
If you publish printed copies (or copies in media that commonly have printed
covers) of the Document, numbering more than 100, and the Document’s license
notice requires Cover Texts, you must enclose the copies in covers that carry,
clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover,
and Back-Cover Texts on the back cover. Both covers must also clearly and
legibly identify you as the publisher of these copies. The front cover must
present the full title with all words of the title equally prominent and visible.
You may add other material on the covers in addition. Copying with changes
limited to the covers, as long as they preserve the title of the Document and
satisfy these conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you
should put the first ones listed (as many as fit reasonably) on the actual cover,
and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more
than 100, you must either include a machine-readable Transparent copy along
with each Opaque copy, or state in or with each Opaque copy a computer-
network location from which the general network-using public has access to
download using public-standard network protocols a complete Transparent copy
of the Document, free of added material. If you use the latter option, you must
take reasonably prudent steps, when you begin distribution of Opaque copies
in quantity, to ensure that this Transparent copy will remain thus accessible at
the stated location until at least one year after the last time you distribute an
Opaque copy (directly or through your agents or retailers) of that edition to the
public.
It is requested, but not required, that you contact the authors of the Document
well before redistributing any large number of copies, to give them a chance to
provide you with an updated version of the Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under the
conditions of sections 2 and 3 above, provided that you release the Modified
Version under precisely this License, with the Modified Version filling the role
of the Document, thus licensing distribution and modification of the Modified
Version to whoever possesses a copy of it. In addition, you must do these things
in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct from that
of the Document, and from those of previous versions (which should, if
there were any, be listed in the History section of the Document). You
may use the same title as a previous version if the original publisher of
that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities respon-
sible for authorship of the modifications in the Modified Version, together
with at least five of the principal authors of the Document (all of its prin-
cipal authors, if it has fewer than five), unless they release you from this
requirement.
C. State on the Title page the name of the publisher of the Modified Version,
as the publisher.
G. Preserve in that license notice the full lists of Invariant Sections and re-
quired Cover Texts given in the Document’s license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled “History”, Preserve its Title, and add to it
an item stating at least the title, year, new authors, and publisher of the
Modified Version as given on the Title Page. If there is no section Entitled
“History” in the Document, create one stating the title, year, authors, and
publisher of the Document as given on its Title Page, then add an item
describing the Modified Version as stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for public
access to a Transparent copy of the Document, and likewise the network
locations given in the Document for previous versions it was based on.
These may be placed in the “History” section. You may omit a network
location for a work that was published at least four years before the Doc-
ument itself, or if the original publisher of the version it refers to gives
permission.
K. For any section Entitled “Acknowledgements” or “Dedications”, Preserve
the Title of the section, and preserve in the section all the substance and
tone of each of the contributor acknowledgements and/or dedications
given therein.
L. Preserve all the Invariant Sections of the Document, unaltered in their text
and in their titles. Section numbers or the equivalent are not considered
part of the section titles.
5. COMBINING DOCUMENTS
GNU Free Documentation License 498
You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified versions, pro-
vided that you include in the combination all of the Invariant Sections of all
of the original documents, unmodified, and list them all as Invariant Sections
of your combined work in its license notice, and that you preserve all their
Warranty Disclaimers.
The combined work need only contain one copy of this License, and multiple
identical Invariant Sections may be replaced with a single copy. If there are
multiple Invariant Sections with the same name but different contents, make
the title of each such section unique by adding at the end of it, in parentheses,
the name of the original author or publisher of that section if known, or else
a unique number. Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled “History” in the
various original documents, forming one section Entitled “History”; likewise
combine any sections Entitled “Acknowledgements”, and any sections Entitled
“Dedications”. You must delete all sections Entitled “Endorsements”.
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents
released under this License, and replace the individual copies of this License
in the various documents with a single copy that is included in the collection,
provided that you follow the rules of this License for verbatim copying of each
of the documents in all other respects.
You may extract a single document from such a collection, and distribute it
individually under this License, provided you insert a copy of this License into
the extracted document, and follow this License in all other respects regarding
verbatim copying of that document.
8. TRANSLATION
Translation is considered a kind of modification, so you may distribute trans-
lations of the Document under the terms of section 4. Replacing Invariant Sec-
tions with translations requires special permission from their copyright holders,
but you may include translations of some or all Invariant Sections in addition to
the original versions of these Invariant Sections. You may include a translation
of this License, and all the license notices in the Document, and any Warranty
Disclaimers, provided that you also include the original English version of this
License and the original versions of those notices and disclaimers. In case of
GNU Free Documentation License 499
a disagreement between the translation and the original version of this License
or a notice or disclaimer, the original version will prevail.
If a section in the Document is Entitled “Acknowledgements”, “Dedications”,
or “History”, the requirement (section 4) to Preserve its Title (section 1) will
typically require changing the actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as
expressly provided for under this License. Any other attempt to copy, modify,
sublicense or distribute the Document is void, and will automatically terminate
your rights under this License. However, parties who have received copies, or
rights, from you under this License will not have their licenses terminated so
long as such parties remain in full compliance.
with the Invariant Sections being LIST THEIR TITLES, with the
Front-Cover Texts being LIST, and with the Back-Cover Texts being
LIST.
If you have Invariant Sections without Cover Texts, or some other combina-
tion of the three, merge those two alternatives to suit the situation.
If your document contains nontrivial examples of program code, we recom-
mend releasing these examples in parallel under your choice of free software
license, such as the GNU General Public License, to permit their use in free
software.
History
30th September 2015 (Version 1.1)
Corrected missing braces in \ifdate in calendar examples.
500
Back Cover Text
(See http://www.gnu.org/licenses/fdl-howto-opt.html#SEC2.)
If you choose to buy a copy of this book, Dickimaw Books asks for your
support through buying the Dickimaw Books edition to help cover costs.
501