summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/latex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/doc/latex')
-rw-r--r--Master/texmf-dist/doc/latex/datatool/CHANGES70
-rw-r--r--Master/texmf-dist/doc/latex/datatool/INSTALL64
-rw-r--r--Master/texmf-dist/doc/latex/datatool/README29
-rw-r--r--Master/texmf-dist/doc/latex/datatool/datatool-user.pdfbin0 -> 495654 bytes
-rw-r--r--Master/texmf-dist/doc/latex/datatool/datatool-user.tex8247
-rw-r--r--Master/texmf-dist/doc/latex/datatool/datatool.pdfbin1850660 -> 732186 bytes
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.pdfbin0 -> 35087 bytes
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.tex57
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.pdfbin0 -> 19543 bytes
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.tex21
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.pdfbin0 -> 33969 bytes
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.tex36
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-student-records.csv7
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.pdfbin0 -> 34628 bytes
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.tex34
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.pdfbin0 -> 31764 bytes
-rw-r--r--Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.tex55
17 files changed, 8614 insertions, 6 deletions
diff --git a/Master/texmf-dist/doc/latex/datatool/CHANGES b/Master/texmf-dist/doc/latex/datatool/CHANGES
index bee8676f0e6..7236ed455d9 100644
--- a/Master/texmf-dist/doc/latex/datatool/CHANGES
+++ b/Master/texmf-dist/doc/latex/datatool/CHANGES
@@ -1,3 +1,73 @@
+v2.10 (2012/07/18):
+
+ * datatool.sty:
+
+ - Split package into datatool-base.sty, datatool-fp.sty and
+ datatool-pgfmath.sty
+
+ - Added package option "math" (math=fp -> use fp.sty,
+ math=pgfmath -> use pgfmath.sty)
+
+ - datatool.sty now requires etoolbox (changed commands like
+ \@ifundefined to etoolbox equivalents)
+
+ - Added 'omitlines' option when loading csv file (from patch supplied by Bruno Le Floch
+ at:
+ http://tex.stackexchange.com/questions/22942/skipping-the-first-line-of-a-data-file-for-pgfplotstable/25133#25133 )
+
+ - \DTLloaddb : adds default column header if missing
+
+ - Added optional argument to \DTLdisplaydb
+
+ - Added omit key to \DTLdisplaylongdb
+
+ - added environment dtlenvgforint
+
+ - added environments DTLenvforeach and DTLenvforeach*
+
+ - added check for at least version 1.2 (2009/10/20) of substr.sty
+
+ - added \DTLassign
+
+ - added DTLnumitemsinlist
+
+ - added \dtlrecombine, \dtlrecombineomitcurrent,
+ \dtlreplaceentryincurrentrow, \dtlswapentriesincurrentrow,
+ \dtlremoveentryincurrentrow, \dtlappendentrytocurrentrow
+
+ - Rewritten \@dtl@ifDigitOrDecimalSep (code provided by Bruno Le Floch)
+
+ - ensured first argument of \DTLconverttodecimal gets one-level
+ expansion in commands like \DTLaddall
+
+ - Fixed \DTLloaddb to work if % used at the start of a row in CSV file.
+
+ - Fixed \@dtl@qlopoff to substitute escaped CSV delimiters
+
+ - Fixed bug in \DTLloadrawdb, which only performed a single
+ substitution per line
+
+ - Added \long before \edef in \DTLsubstituteall
+
+ - Fixed bug in \@dtl@getkeyforcolumn (affects
+ \DTLgetkeyforcolumn)
+
+ - Changed tab character to ^^I
+
+ - Fixed bug in \DTLloaddb and \DTLloadrawdb when CSV file only contains one column
+
+ * databib.bst:
+
+ - Added eprints field
+
+ * datatool-user.tex (User guide):
+
+ - fixed typo "\value{DTLbibrow}<11" => "\value{DTLbibrow}<10"
+
+ - added section "Operating on Current Row"
+
+ - added remark on using etoolbox to check for empty values
+
v2.03 (2009/11/15):
* Added facility to clear or delete a database.
diff --git a/Master/texmf-dist/doc/latex/datatool/INSTALL b/Master/texmf-dist/doc/latex/datatool/INSTALL
new file mode 100644
index 00000000000..55acc329594
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/INSTALL
@@ -0,0 +1,64 @@
+INSTALLATION
+
+If you have downloaded the datatool package using the TeX
+Directory Structure (TDS), that is you have downloaded the archive
+datatool.tds.zip containing doc, tex, scripts and source
+directories, you need to follow the "Installing from TDS"
+instructions below.
+
+If you have downloaded the following files:
+
+datatool.dtx
+datatool.ins
+
+You need to follow the "Installing from DTX and INS" instructions
+below.
+
+For further information on installing LaTeX packages see:
+
+http://www.tex.ac.uk/cgi-bin/texfaq2html?label=installthings
+
+INSTALLING FROM TDS
+===================
+
+Files in tex and doc directories should go in the corresponding
+TEXMF directories (for example, /usr/share/texmf-local/ or
+C:\localtexmf\).
+
+*Remember to refresh TeX's database*
+
+Example (on UNIX like systems):
+
+unzip datatool.tds.zip -d ~/texmf/
+texhash ~/texmf/
+
+INSTALLING FROM DTX AND INS
+===========================
+
+Run LaTeX on datatool.ins to generate the package style files:
+
+latex datatool.ins
+
+To create the package documentation (datatool.pdf):
+
+pdflatex datatool.dtx
+makeindex -s gind.ist datatool.idx
+pdflatex datatool.dtx
+pdflatex datatool.dtx
+
+If TEXMF denotes the base directory of your local TeX installation (e.g.
+/usr/share/texmf-local/ or C:\localtexmf\) then create the following
+directories (if they don't already exist):
+
+TEXMF/doc/latex/datatool
+TEXMF/doc/latex/datatool/samples
+TEXMF/tex/latex/datatool
+
+Move the sample files (*.tex) to TEXMF/doc/latex/datatool/sample/
+
+Move the documentation (*.pdf) to TEXMF/doc/latex/datatool/
+
+Move style files (*.sty) to TEXMF/tex/latex/datatool/
+
+*Remember to refresh TeX's database*
+
diff --git a/Master/texmf-dist/doc/latex/datatool/README b/Master/texmf-dist/doc/latex/datatool/README
index 0a6d97f88d4..23c357ae670 100644
--- a/Master/texmf-dist/doc/latex/datatool/README
+++ b/Master/texmf-dist/doc/latex/datatool/README
@@ -1,9 +1,14 @@
-LaTeX Bundle : datatool v2.03 (datatool.sty, datapie.sty, dataplot.sty, databar.sty, databib.sty)
+LaTeX Bundle : datatool v2.10
-Last Modified : 15 November 2009
+Last Modified : 2012-07-18
Author : Nicola Talbot
+This bundle consists of the packages: datatool.sty,
+datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty,
+databar.sty, databib.sty, datapie.sty dataplot.sty,
+person.sty.
+
datatool.sty:
Databases can be created using LaTeX commands or loaded
@@ -17,6 +22,8 @@ datatool.sty:
data in a database (such as mail merging.) Conditions
can be imposed to exclude rows.
+datatool-base.sty:
+
Commands are provided to determine if an argument is
an integer, a real number, currency or a string.
(Scientific notation is currently not supported.)
@@ -27,7 +34,7 @@ datatool.sty:
Commands are provided to convert between locale dependent
numbers/currency and the standard decimal format required
- by the fp package enabling fixed point arithmetic to be
+ by the fp or pgfmath packages enabling fixed point arithmetic to be
performed on elements of the database.
Strings can be tested to determine if they are all upper
@@ -35,6 +42,12 @@ datatool.sty:
Names can be converted to initials using \DTLinitials.
+datatool-fp.sty:
+ Provides an interface with fp.sty
+
+datatool-pgfmath.sty:
+ Provides an interface with pgfmath.sty
+
datapie.sty:
A database defined by datatool.sty can be converted into a
@@ -87,14 +100,18 @@ person.sty:
REQUIRED PACKAGES:
-The datatool.sty package requires the following packages/files:
+The datatool.sty and datatool-base.sty packages requires the following packages/files:
xkeyval
ifthen
xfor
-fp
-substr
+substr (at least 2009/10/20)
etex
+etoolbox
+amsmath
+
+The datatool-fp package requires fp.sty
+The datatool-pgfmath package requires pgfmath.sty
The datapie.sty, dataplot.sty and databar.sty packages
additionally require the tikz/pgf bundle.
diff --git a/Master/texmf-dist/doc/latex/datatool/datatool-user.pdf b/Master/texmf-dist/doc/latex/datatool/datatool-user.pdf
new file mode 100644
index 00000000000..59d242c0cee
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/datatool-user.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/datatool/datatool-user.tex b/Master/texmf-dist/doc/latex/datatool/datatool-user.tex
new file mode 100644
index 00000000000..86ac37d6af7
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/datatool-user.tex
@@ -0,0 +1,8247 @@
+\documentclass[report,widecs]{nlctdoc}
+
+\usepackage{ifthen}
+\usepackage[verbose=false]{datatool}
+\usepackage{datapie,databar,databib,person}
+\usepackage{textcomp}
+\usepackage{graphicx}
+\usepackage{colortbl}
+\usepackage{cmap}
+\usepackage[T1]{fontenc}
+\usepackage[utf8]{inputenc}
+\ifpdf
+\usepackage{mathpazo}
+\usepackage[scaled=.88]{helvet}
+\usepackage{courier}
+\fi
+\usepackage{caption}
+\usepackage[colorlinks,
+ bookmarks,
+ hyperindex=false,
+ pdfauthor={Nicola L.C. Talbot},
+ pdftitle={datatool: Databases and data manipulation},
+ pdfkeywords={LaTeX,package,database,data,chart,plot}]{hyperref}
+\usepackage{xr-hyper}
+\usetikzlibrary{snakes}
+
+\PageIndex
+\IndexPrologue{\chapter*{Index}}
+\setcounter{IndexColumns}{2}
+
+\ifpdf
+ \externaldocument{datatool}
+\fi
+
+\doxitem{Counter}{counter}{counters}
+\doxitem{Option}{option}{package options}
+
+\newcommand*{\desctr}[1]{\ctrfmt{#1}\DescribeCounter{#1}}
+
+ %bibliography database
+\DTLnewdb{docbib}
+\DTLnewrow{docbib}
+\DTLnewdbentry{docbib}{CiteKey}{Goossens}
+\DTLnewdbentry{docbib}{EntryType}{book}
+\DTLnewdbentry{docbib}{Author}{{}{Goossens}{}{Michel},{}{Mittelbach}{}{Frank},{}{Samarin}{}{Alexander}}
+\DTLnewdbentry{docbib}{Title}{The \LaTeX\ Companion}
+\DTLnewdbentry{docbib}{Publisher}{Addison-Wesley}
+\DTLnewdbentry{docbib}{Year}{1994}
+
+
+\begin{document}
+% Some of the commands are too long to produce nicely formatted
+% paragraphs so use ragged-right:
+\raggedright
+
+\MakeShortVerb{"}
+\DeleteShortVerb{\|}
+
+ \title{User Manual for datatool bundle version~2.10}
+ \author{Nicola L.C. Talbot\\[10pt]
+School of Computing Sciences\\
+University of East Anglia\\
+Norwich. Norfolk\\
+NR4 7TJ. United Kingdom.\\
+\url{http://theoval.cmp.uea.ac.uk/~nlct/}}
+
+ \date{2012-07-18}
+ \maketitle
+
+\pagenumbering{roman}
+
+\noindent
+The \styfmt{datatool} bundle comes with the following documentation:
+\begin{description}
+ \item[datatool-user.pdf]
+ This document is the main user guide for the \styfmt{datatool}
+ bundle.
+
+ \item[\url{datatool.pdf}]
+ Advanced users wishing to know more about the inner workings of
+ all the packages provided in the \styfmt{datatool} bundle should
+ read \qt{Documented Code for datatool v2.10}
+
+ \item[INSTALL] Installation instructions.
+
+ \item[CHANGES] Change log.
+
+ \item[README] Package summary.
+\end{description}
+
+\begin{important}
+The \styfmt{datatool} bundle is provided to help perform repetitive
+commands, such as mail merging, but since \TeX\ is designed as a
+typesetting language, don't expect this bundle to perform as
+efficiently as custom database systems or a dedicated mathematical or
+scripting language.
+\end{important}
+
+This bundle consists of the following packages:
+\begin{description}
+\item[\sty{datatool}] Main package providing database support.
+Automatically loads \sty{datatool-base}.
+
+\item[\sty{datatool-base}] Provides the main library code for
+numerical and string functions. Automatically
+loads \sty{datatool-fp} or \sty{datatool-pgfmath} depending on
+package options.
+
+\item[\sty{databar}] Package for drawing bar charts.
+Automatically loads \sty{datatool}.
+
+\item[\sty{datapie}] Package for drawing pie charts.
+Automatically loads \sty{datatool}.
+
+\item[\sty{dataplot}] Package for drawing simple line graphs.
+Automatically loads \sty{datatool}.
+
+\item[\sty{databib}] Package for loading a bibliography into a
+database. Automatically loads \sty{datatool}.
+
+\item[\sty{person}] Package for referencing people by the
+appropriate gender pronouns. Automatically loads \sty{datatool}.
+
+\end{description}
+
+In addition, there are two mutually exclusive packages
+\sty{datatool-fp} and \sty{datatool-pgfmath} that provide
+mathematical related commands that are just wrapper functions for
+\sty{fp} or \sty{pgfmath} commands. These can be loaded individually
+without loading \sty{datatool}. For example, the following documents
+produce the same results, but the first uses the \sty{fp} package
+and the second uses the \sty{pgfmath} package:
+
+\begin{enumerate}
+\item Using \sty{fp} macros:
+\begin{verbatim}
+\documentclass{article}
+\usepackage{datatool-fp}
+\begin{document}
+1=2: \dtlifnumeq{1}{2}{true}{false}.
+\end{document}
+\end{verbatim}
+
+\item Using \sty{pgfmath} macros:
+\begin{verbatim}
+\documentclass{article}
+\usepackage{datatool-pgfmath}
+\begin{document}
+1=2: \dtlifnumeq{1}{2}{true}{false}.
+\end{document}
+\end{verbatim}
+
+\end{enumerate}
+
+\cleardoublepage
+\pdfbookmark[0]{Contents}{contents}
+\tableofcontents
+\cleardoublepage
+\pdfbookmark[0]{List of Examples}{examples}
+\listofexamples
+\cleardoublepage
+\pdfbookmark[0]{List of Figures}{figures}
+\listoffigures
+\cleardoublepage
+\pdfbookmark[0]{List of Tables}{tables}
+\listoftables
+
+\pagenumbering{arabic}
+\chapter{Introduction}
+
+ \changes{1.0}{2007 July 22}{Initial version}
+The \sty{datatool} bundle consists of the following
+packages: \sty{datatool} (which loads \sty{datatool-base} and either \sty{datatool-fp} or \sty{datatool-pgfmath}), \sty{datapie}, \sty{dataplot},
+\sty{databar} and \sty{databib}.
+
+The \sty{datatool} package can be used to:
+\begin{itemize}
+\item Create or load databases.
+\item Sort rows of a database (either numerically or alphabetically,
+ascending or descending).
+\item Perform repetitive operations on each row of a database
+(e.g.\ mail merging). Conditions may be imposed to exclude rows.
+
+\item Package Options:
+ \begin{description}
+ \item[\pkgopt{verbose}] Boolean key. If
+ \pkgoptval{true}{verbose}, prints informational messages in
+ transcript.
+ \item[\pkgopt{math}] May take one of two values:
+ \pkgoptval{fp}{math} (load \sty{datatool-fp}) or
+ \pkgoptval{pgfmath}{math} (load \sty{datatool-pgfmath}). Default is:
+ \pkgoptval{fp}{math}.
+ \item[\pkgopt{delimiter}] Delimiter used in CSV files.
+ Default is a double quote (\texttt{\string"}).
+ \item[\pkgopt{separator}] Delimiter used in CSV files.
+ Default is a comma (\texttt{,}).
+ \end{description}
+\end{itemize}
+
+The \sty{datatool-base} package can be used to:
+\begin{itemize}
+\item Determine whether an argument is an integer, a real number,
+currency or a string. (Scientific notation is currently not
+supported.) Locale dependent number settings are supported (such
+as a comma as a decimal character and a full stop as a number
+group character).
+\item Convert locale dependent numbers/currency to the decimal
+format required by the \sty{fp} or \sty{pgfmath} packages, enabling fixed point
+arithmetic to be performed on elements of the database.
+\item Names can be converted to initials.
+\item Determine if strings are all upper or lower case.
+\item Perform string comparisons (both case sensitive and case insensitive).
+
+\item Package Options:
+ \begin{description}
+ \item[\pkgopt{verbose}] Boolean key. If
+ \pkgoptval{true}{verbose}, prints informational messages in
+ transcript.
+ \item[\pkgopt{math}] May take one of two values:
+ \pkgoptval{fp}{math} (load \sty{datatool-fp}) or
+ \pkgoptval{pgfmath}{math} (load \sty{datatool-pgfmath}). Default is:
+ \pkgoptval{fp}{math}.
+ \end{description}
+\end{itemize}
+
+The \sty{datapie} package (see \autoref{sec:datapie}) can be used to convert a database into
+a pie chart:
+\begin{itemize}
+\item Segments can be separated from the rest of the chart to make
+them stand out.
+\item Colour/grey scale options.
+\item Predefined segment colours can be changed.
+\item Hooks provided to add extra information to the chart
+\end{itemize}
+
+The \sty{databar} package (see \autoref{sec:databar}) can be used to convert a database into
+a bar chart:
+\begin{itemize}
+\item Colour/grey scale options.
+\item Predefined bar colours can be changed.
+\item Hooks provided to add extra information to the chart
+\end{itemize}
+
+(The \sty{datapie} and \sty{databar} packages do not support the
+creation of 3D charts, and I have no plans to implement them at any
+later date. The use of 3D charts should be discouraged. They may look
+pretty, but the purpose of a chart is to be informative. Three
+dimensional graphics cause distortion, which can result in misleading
+impressions. The \sty{pgf} manual provides a more in-depth
+discussion on the matter.)
+
+The \sty{dataplot} package (see \autoref{sec:dataplot}) can be used to convert a database into
+a two dimensional plot using markers and/or lines. Three dimensional
+plots are currently not supported.
+
+The \sty{databib} package (see \autoref{sec:databib}) can be used to convert a \BibTeX\ database
+into a \sty{datatool} database.
+
+\chapter{Data Types}
+\label{sec:datatypes}
+
+The \sty{datatool-base} package recognises four data types: integers,
+real numbers, currency and strings.
+
+\begin{description}
+\item[Integers] An integer is a sequence of digits, optionally
+groups of three digits may be separated by the number group character.
+The default number group character is a comma (,) but may be
+changed using \cs{DTLsetnumberchars} (see below).
+
+\item[Real Numbers] A real number is an integer followed by the
+decimal character followed by one or more digits. The decimal
+character is a full stop (.) by default. The number group
+and decimal characters may be changed using
+\begin{definition}[\DescribeMacro{\DTLsetnumberchars}]%
+\cs{DTLsetnumberchars}\marg{number group character}\marg{decimal character}
+\end{definition}
+Note that scientific notation is not supported, and the number group
+character may not be used after the decimal character.
+
+\item[Currency] A currency symbol followed by an integer or
+real number is considered to be the currency data type.
+There are two predefined currency symbols, "\$" and \cs{pounds}.
+In addition, if any of the following commands are defined at the
+start of the document, they are also considered to be a currency
+symbol: \cs{texteuro}, \cs{textdollar}, \cs{textstirling},
+\cs{textyen}, \cs{textwon}, \cs{textcurrency}, \cs{euro}
+and \cs{yen}. Additional currency symbols can be defined using
+\begin{definition}[\DescribeMacro{\DTLnewcurrencysymbol}]%
+\cs{DTLnewcurrencysymbol}\marg{symbol}
+\end{definition}
+
+\item[Strings] Anything that doesn't belong to the above three
+types is considered to be a string.
+
+\end{description}
+
+\section{Conditionals}
+\label{sec:ifconditions}
+
+The following conditionals are provided by the \sty{datatool-base}
+package:
+\begin{definition}[\DescribeMacro{\DTLifint}]%
+\cs{DTLifint}\marg{text}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{text} is an integer then do \meta{true part}, otherwise
+do \meta{false part}. For example
+\begin{verbatim}
+\DTLifint{2536}{integer}{not an integer}
+\end{verbatim}
+produces:
+\DTLifint{2536}{integer}{not an integer}.
+
+The number group character may appear in the number, for example:
+\begin{verbatim}
+\DTLifint{2,536}{integer}{not an integer}
+\end{verbatim}
+produces:
+\DTLifint{2,536}{integer}{not an integer}.
+However, the number group character may only be followed by a group
+of three digits. For example:
+\begin{verbatim}
+\DTLifint{2,5,3,6}{integer}{not an integer}
+\end{verbatim}
+produces:
+\DTLifint{2,5,3,6}{integer}{not an integer}.
+The number group character may be changed. For example:
+\begin{verbatim}
+\DTLsetnumberchars{.}{,}%
+\DTLifint{2,536}{integer}{not an integer}
+\end{verbatim}
+this now produces:
+\DTLsetnumberchars{.}{,}\relax
+\DTLifint{2,536}{integer}{not an integer}, since 2,536 is now
+a real number.
+
+Note that nothing else can be appended or prepended to the
+number. For example:
+\begin{verbatim}
+\DTLsetnumberchars{,}{.}%
+\DTLifint{2,536m}{integer}{not an integer}
+\end{verbatim}
+produces:
+\DTLsetnumberchars{,}{.}\relax
+\DTLifint{2,536m}{integer}{not an integer}.
+
+\begin{definition}[\DescribeMacro{\DTLifreal}]%
+\cs{DTLifreal}\marg{text}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{text} is a real number then do \meta{true part}, otherwise
+do \meta{false part}. For example
+\begin{verbatim}
+\DTLifreal{1000.0}{real}{not real}
+\end{verbatim}
+produces:
+\DTLifreal{1000.0}{real}{not real}.
+
+Note that an integer is not considered a real number:
+\begin{verbatim}
+\DTLifreal{1,000}{real}{not real}
+\end{verbatim}
+produces:
+\DTLifreal{1,000}{real}{not real}.
+
+Whereas
+\begin{verbatim}
+\DTLifreal{1,000.0}{real}{not real}
+\end{verbatim}
+produces:
+\DTLifreal{1,000.0}{real}{not real}.
+
+However
+\begin{verbatim}
+\DTLsetnumberchars{.}{,}%
+\DTLifreal{1,000}{real}{not real}
+\end{verbatim}
+produces:
+\DTLsetnumberchars{.}{,}\relax
+\DTLifreal{1,000}{real}{not real} since the comma is now
+the decimal character.
+
+Currency is not considered to be real:
+\begin{verbatim}
+\DTLsetnumberchars{,}{.}%
+\DTLifreal{\$1.00}{real}{not real}
+\end{verbatim}
+produces:
+\DTLsetnumberchars{,}{.}\relax
+\DTLifreal{\$1.00}{real}{not real}.
+
+\begin{definition}[\DescribeMacro{\DTLifcurrency}]%
+\cs{DTLifcurrency}\marg{text}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{text} is currency, then do \meta{true part}, otherwise
+do false part. For example:
+\begin{verbatim}
+\DTLifcurrency{\$5.99}{currency}{not currency}
+\end{verbatim}
+produces:
+\DTLifcurrency{\$5.99}{currency}{not currency}. Similarly:
+\begin{verbatim}
+\DTLifcurrency{\pounds5.99}{currency}{not currency}
+\end{verbatim}
+produces:
+\DTLifcurrency{\pounds5.99}{currency}{not currency}.
+Note, however, that
+\begin{verbatim}
+\DTLifcurrency{US\$5.99}{currency}{not currency}
+\end{verbatim}
+produces:
+\DTLifcurrency{US\$5.99}{currency}{not currency}. If you want
+this to be considered currency, you will have to add the
+sequence "US\$" to the set of currency symbols:
+\begin{verbatim}
+\DTLnewcurrencysymbol{US\$}%
+\DTLifcurrency{US\$5.99}{currency}{not currency}
+\end{verbatim}
+this now produces:
+\DTLnewcurrencysymbol{US\$}\relax
+\DTLifcurrency{US\$5.99}{currency}{not currency}.
+
+This document has used the \sty{textcomp} package which defines
+\cs{texteuro}, so this is also considered to be currency. For
+example:
+\begin{verbatim}
+\DTLifcurrency{\texteuro5.99}{currency}{not currency}
+\end{verbatim}
+produces:
+\DTLifcurrency{\texteuro5.99}{currency}{not currency}.
+
+The preferred method is to display the euro symbol in a sans-serif
+font, but
+\begin{verbatim}
+\DTLifcurrency{\textsf{\texteuro}5.99}{currency}{not currency}
+\end{verbatim}
+will produce:
+\DTLifcurrency{\textsf{\texteuro}5.99}{currency}{not currency}.
+
+It is better to define a new command, for example:
+\begin{verbatim}
+\DeclareRobustCommand*{\euro}{\textsf{\texteuro}}
+\end{verbatim}
+and add that command to the list of currency symbols. In fact,
+in this case, if you define the command \cs{euro} in the
+preamble, it will automatically be added to the list of known
+currency symbols. If however you define \cs{euro} in the document,
+you will have to add it using \ics{DTLnewcurrencysymbol}. For
+example:
+\begin{verbatim}
+\newcommand*{\euro}{\textsf{\texteuro}}%
+\DTLnewcurrencysymbol{\euro}%
+\DTLifcurrency{\euro5.99}{currency}{not currency}
+\end{verbatim}
+produces:
+\DeclareRobustCommand*{\euro}{\textsf{\texteuro}}\relax
+\DTLnewcurrencysymbol{\euro}\relax
+\DTLifcurrency{\euro5.99}{currency}{not currency}.
+
+\begin{definition}[\DescribeMacro{\DTLifcurrencyunit}]%
+\cs{DTLifcurrencyunit}\marg{text}\marg{symbol}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{text} is currency, and uses \meta{symbol} as the unit of
+currency, then do \meta{true part} otherwise do \meta{false part}.
+For example:
+\begin{verbatim}
+\DTLifcurrencyunit{\$6.99}{\$}{dollars}{not dollars}
+\end{verbatim}
+produces:
+\DTLifcurrencyunit{\$6.99}{\$}{dollars}{not dollars}.
+Another example:
+\begin{verbatim}
+\def\cost{\euro10.50}%
+\DTLifcurrencyunit{\cost}{\euro}{euros}{not euros}
+\end{verbatim}
+produces:
+\def\cost{\euro10.50}\relax
+\DTLifcurrencyunit{\cost}{\euro}{euros}{not euros}.
+
+\begin{definition}[\DescribeMacro{\DTLifnumerical}]%
+\cs{DTLifnumerical}\marg{text}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{text} is numerical (either an integer, real number or
+currency) then do \meta{true part} otherwise do
+\meta{false part}.
+For example:
+\begin{verbatim}
+\DTLifnumerical{1,000.0}{number}{string}.
+\end{verbatim}
+produces: \DTLifnumerical{1,000.0}{number}{string}.
+Whereas
+\begin{verbatim}
+\DTLsetnumberchars{.}{,}%
+\DTLifnumerical{1,000.0}{number}{string}.
+\end{verbatim}
+produces:
+\DTLsetnumberchars{.}{,}\relax
+\DTLifnumerical{1,000.0}{number}{string}.
+Since the number group character is now a full stop, and the
+decimal character is now a comma. (The number group character
+may only appear before the decimal character, not after it.)
+
+Currency is also considered to be numerical:
+\begin{verbatim}
+\DTLsetnumberchars{,}{.}%
+\DTLifnumerical{\$1,000.0}{number}{string}.
+\end{verbatim}
+produces:
+\DTLsetnumberchars{,}{.}\relax
+\DTLifnumerical{\$1,000.0}{number}{string}.
+
+\begin{definition}[\DescribeMacro{\DTLifstring}]%
+\cs{DTLifstring}\marg{text}\marg{true part}\marg{false part}
+\end{definition}
+This is the opposite of \cs{DTLifnumerical}. If \meta{text} is
+not numerical, do \meta{true part}, otherwise do \meta{false part}.
+
+\begin{definition}[\DescribeMacro{\DTLifcasedatatype}]%
+\cs{DTLifcasedatatype}\marg{text}\marg{string case}\marg{int case}\marg{real case}\marg{currency case}
+\end{definition}
+If \meta{text} is a string do \meta{string case}, if \meta{text}
+is an integer do \meta{int case}, if \meta{text} is a real number
+do \meta{real case}, if \meta{text} is currency do
+\meta{currency case}. For example:
+\begin{verbatim}
+\DTLifcasedatatype{1,000}{string}{integer}{real}{currency}
+\end{verbatim}
+produces:
+\DTLifcasedatatype{1,000}{string}{integer}{real}{currency}.
+
+\begin{definition}[\DescribeMacro{\dtlifnumeq}]%
+\cs{dtlifnumeq}\marg{num1}\marg{num2}\marg{true part}\marg{false
+paty}
+\end{definition}
+If \meta{num1} is equal to \meta{num2}, then do \meta{true part},
+otherwise to \meta{false part} where \meta{num1} and \meta{num2}
+are plain numbers using a full stop as the decimal point and no
+number group separator. For currency or locale dependent numbers use
+\cs{DTLifnumeq}.
+
+\begin{definition}[\DescribeMacro{\DTLifnumeq}]%
+\cs{DTLifnumeq}\marg{num1}\marg{num2}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{num1} is equal to \meta{num2}, then do \meta{true part},
+otherwise do \meta{false part}. Note that both \meta{num1} and
+\meta{num2} must be numerical (either integers, real numbers or
+currency). The currency symbol is ignored when determining
+equality. For example
+\begin{verbatim}
+\DTLifnumeq{\pounds10.50}{10.5}{true}{false}
+\end{verbatim}
+produces:
+\DTLifnumeq{\pounds10.50}{10.5}{true}{false}, since they are
+considered to be numerically equivalent. Likewise:
+\begin{verbatim}
+\DTLifnumeq{\pounds10.50}{\$10.50}{true}{false}
+\end{verbatim}
+produces:
+\DTLifnumeq{\pounds10.50}{\$10.50}{true}{false}.
+
+\pagebreak
+\begin{definition}[\DescribeMacro{\DTLifstringeq}]%
+\cs{DTLifstringeq}\marg{string1}\marg{string2}\marg{true part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLifstringeq*}]%
+\cs{DTLifstringeq*}\marg{string1}\marg{string2}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{string1} and \meta{string2} are the same, then do
+\meta{true part}, otherwise do \meta{false part}. The starred
+version ignores the case, the unstarred version is case
+sensitive. Both
+\meta{string1} and \meta{string2} are considered to be strings,
+so for example:
+\begin{verbatim}
+\DTLifstringeq{10.50}{10.5}{true}{false}
+\end{verbatim}
+produces:
+\DTLifstringeq{10.50}{10.5}{true}{false}.
+
+Note that
+\begin{verbatim}
+\DTLifstringeq{Text}{text}{true}{false}
+\end{verbatim}
+produces:
+\DTLifstringeq{Text}{text}{true}{false}, whereas
+\begin{verbatim}
+\DTLifstringeq*{Text}{text}{true}{false}
+\end{verbatim}
+produces:
+\DTLifstringeq*{Text}{text}{true}{false}, however it should also be
+noted that many commands will be ignored, so:
+\begin{verbatim}
+\DTLifstringeq{\uppercase{t}ext}{text}{true}{false}
+\end{verbatim}
+produces:
+\DTLifstringeq{\uppercase{t}ext}{text}{true}{false}.
+
+Spaces are considered to be equivalent to \cs{space} and "~". For
+example:
+\begin{verbatim}
+\DTLifstringeq{an apple}{an~apple}{true}{false}
+\end{verbatim}
+produces:
+\DTLifstringeq{an apple}{an~apple}{true}{false}. Consecutive spaces
+are treated as the same, for example:
+\begin{verbatim}
+\DTLifstringeq{an apple}{an apple}{true}{false}
+\end{verbatim}
+produces:
+\DTLifstringeq{an apple}{an apple}{true}{false}.
+
+\begin{definition}[\DescribeMacro{\DTLifeq}]%
+\cs{DTLifeq}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLifeq*}]%
+\cs{DTLifeq*}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part}
+\end{definition}
+If both \meta{arg1} and \meta{arg2} are numerical, then this is
+equivalent to \cs{DTLifnumeq}, otherwise it is equivalent to
+\cs{DTLifstringeq} (when using \cs{DTLifeq}) or \cs{DTLifstringeq*}
+(when using \cs{DTLifeq*}).
+
+\begin{definition}[\DescribeMacro{\dtlifnumlt}]%
+\cs{dtlifnumlt}\marg{num1}\marg{num2}\marg{true part}\marg{false
+paty}
+\end{definition}
+If \meta{num1} is less than \meta{num2}, then do \meta{true part},
+otherwise to \meta{false part} where \meta{num1} and \meta{num2}
+are plain numbers using a full stop as the decimal point and no
+number group separator. For currency or locale dependent numbers use
+\cs{DTLifnumlt}.
+
+\begin{definition}[\DescribeMacro{\DTLifnumlt}]%
+\cs{DTLifnumlt}\marg{num1}\marg{num2}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{num1} is less than \meta{num2}, then do \meta{true part},
+otherwise do \meta{false part}. Note that both \meta{num1} and
+\meta{num2} must be numerical (either integers, real numbers or
+currency).
+
+\begin{definition}[\DescribeMacro{\DTLifstringlt}]%
+\cs{DTLifstringlt}\marg{string1}\marg{string2}\marg{true
+part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLifstringlt*}]%
+\cs{DTLifstringlt*}\marg{string1}\marg{string2}\marg{true
+part}\marg{false part}
+\end{definition}
+If \meta{string1} is alphabetically less than \meta{string2}, then do
+\meta{true part}, otherwise do \meta{false part}. The starred
+version ignores the case, the unstarred version is case
+sensitive.
+For example:
+\begin{verbatim}
+\DTLifstringlt{aardvark}{zebra}{less}{not less}
+\end{verbatim}
+produces:
+\DTLifstringlt{aardvark}{zebra}{less}{not less}.
+
+Note that both \meta{string1} and \meta{string2} are considered to be
+strings, so for example:
+\begin{verbatim}
+\DTLifstringlt{2}{10}{less}{not less}
+\end{verbatim}
+produces:
+\DTLifstringlt{2}{10}{less}{not less}, since the string "2"
+comes after the string "10" when arranged alphabetically.
+
+The case sensitive (unstarred) version considers uppercase characters
+to be less than lowercase characters, so
+\begin{verbatim}
+\DTLifstringlt{B}{a}{less}{not less}
+\end{verbatim}
+produces:
+\DTLifstringlt{B}{a}{less}{not less}, whereas
+\begin{verbatim}
+\DTLifstringlt*{B}{a}{less}{not less}
+\end{verbatim}
+produces:
+\DTLifstringlt*{B}{a}{less}{not less}.
+
+\begin{definition}[\DescribeMacro{\DTLiflt}]%
+\cs{DTLiflt}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLiflt*}]%
+\cs{DTLiflt*}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{arg1} and \meta{arg2} are both numerical, then this
+is equivalent to \cs{DTLifnumlt}, otherwise it is equivalent
+to \cs{DTLstringlt} (when using \cs{DTLiflt}) or
+\cs{DTLstringlt*} (when using \cs{DTLiflt*}).
+
+\begin{definition}[\DescribeMacro{\DTLifnumgt}]%
+\cs{DTLifnumgt}\marg{num1}\marg{num2}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{num1} is greater than \meta{num2}, then do \meta{true part},
+otherwise do \meta{false part}. Note that both \meta{num1} and
+\meta{num2} must be numerical (either integers, real numbers or
+currency).
+
+\begin{definition}[\DescribeMacro{\DTLifstringgt}]%
+\cs{DTLifstringgt}\marg{string1}\marg{string2}\marg{true
+part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLifstringgt*}]%
+\cs{DTLifstringgt*}\marg{string1}\marg{string2}\marg{true
+part}\marg{false part}
+\end{definition}
+If \meta{string1} is alphabetically greater than \meta{string2}, then
+do \meta{true part}, otherwise do \meta{false part}. The
+starred version ignores the case, the unstarred version is
+case sensitive. For example:
+\begin{verbatim}
+\DTLifstringgt{aardvark}{zebra}{greater}{not greater}
+\end{verbatim}
+produces:
+\DTLifstringgt{aardvark}{zebra}{greater}{not greater}.
+
+Note that both \meta{string1} and \meta{string2} are considered to be
+strings, so for example:
+\begin{verbatim}
+\DTLifstringgt{2}{10}{greater}{not greater}
+\end{verbatim}
+produces:
+\DTLifstringgt{2}{10}{greater}{not greater}, since the string "2"
+comes after the string "10" when arranged alphabetically.
+
+As with \cs{DTLifstringlt}, uppercase characters are considered
+to be less than lower case characters when performing a
+case sensitive comparison so:
+\begin{verbatim}
+\DTLifstringgt{B}{a}{greater}{not greater}
+\end{verbatim}
+produces:
+\DTLifstringgt{B}{a}{greater}{not greater}, whereas
+\begin{verbatim}
+\DTLifstringgt*{B}{a}{greater}{not greater}
+\end{verbatim}
+produces:
+\DTLifstringgt*{B}{a}{greater}{not greater}.
+
+\begin{definition}[\DescribeMacro{\DTLifgt}]%
+\cs{DTLifgt}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLifgt*}]%
+\cs{DTLifgt*}\marg{arg1}\marg{arg2}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{arg1} and \meta{arg2} are both numerical, then this
+is equivalent to \cs{DTLifnumgt}, otherwise it is equivalent
+to \cs{DTLstringgt} (when using \cs{DTLifgt}) or
+\cs{DTLstringgt*} (when using \cs{DTLifgt*}).
+
+\begin{definition}[\DescribeMacro{\DTLifnumclosedbetween}]%
+\cs{DTLifnumclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{min} $\leq$ \meta{num} $\leq$ \meta{max} then do \meta{true part},
+otherwise do \meta{false part}. Note that \meta{num}, \meta{min} and
+\meta{max} must be numerical (either integers, real numbers or
+currency). The currency symbol is ignored when determining
+equality. For example:
+\begin{verbatim}
+\DTLifnumclosedbetween{5.4}{5}{7}{inside}{outside}
+\end{verbatim}
+produces:
+\DTLifnumclosedbetween{5.4}{5}{7}{inside}{outside}.
+Note that the closed range includes end points:
+\begin{verbatim}
+\DTLifnumclosedbetween{5}{5}{7}{inside}{outside}
+\end{verbatim}
+produces:
+\DTLifnumclosedbetween{5}{5}{7}{inside}{outside}.
+
+\begin{definition}[\DescribeMacro{\DTLifstringclosedbetween}]%
+\cs{DTLifstringclosedbetween}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLifstringclosedbetween*}]%
+\cs{DTLifstringclosedbetween*}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+This determines if \meta{string} is between \meta{min} and
+\meta{max} in the alphabetical sense, or is equal to either
+\meta{min} or \meta{max}. The starred version ignores the case,
+the unstarred version is case sensitive.
+
+\begin{definition}[\DescribeMacro{\DTLifclosedbetween}]%
+\cs{DTLifclosedbetween}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLifclosedbetween*}]%
+\cs{DTLifclosedbetween*}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{arg}, \meta{min} and \meta{max} are numerical, then this is
+equivalent to\newline
+\cs{DTLifnumclosedbetween}\newline
+otherwise it is equivalent to\newline
+\cs{DTLifstringclosedbetween}\newline
+(when using \cs{DTLifclosedbetween}) or\newline
+\cs{DTLifstringclosedbetween*}\newline
+(when using \cs{DTLifclosedbetween*}).
+
+\begin{definition}[\DescribeMacro{\DTLifnumopenbetween}]%
+\cs{DTLifnumopenbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{min} $<$ \meta{num} $<$ \meta{max} then do \meta{true part},
+otherwise do \meta{false part}. Note that \meta{num}, \meta{min} and
+\meta{max} must be numerical (either integers, real numbers or
+currency). Again, the currency symbol is ignored when determining
+equality. For example:
+\begin{verbatim}
+\DTLifnumopenbetween{5.4}{5}{7}{inside}{outside}
+\end{verbatim}
+produces:
+\DTLifnumopenbetween{5.4}{5}{7}{inside}{outside}.
+Note that end points are not included. For example:
+\begin{verbatim}
+\DTLifnumopenbetween{5}{5}{7}{inside}{outside}
+\end{verbatim}
+produces:
+\DTLifnumopenbetween{5}{5}{7}{inside}{outside}.
+
+\begin{definition}[\DescribeMacro{\DTLifstringopenbetween}]%
+\cs{DTLifstringopenbetween}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLifstringopenbetween*}]%
+\cs{DTLifstringopenbetween*}\marg{string}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+This determines if \meta{string} is between \meta{min} and
+\meta{max} in the alphabetical sense.
+The starred version ignores the case,
+the unstarred version is case sensitive.
+
+\begin{definition}[\DescribeMacro{\DTLifopenbetween}]%
+\cs{DTLifopenbetween}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLifopenbetween*}]%
+\cs{DTLifopenbetween*}\marg{arg}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{arg}, \meta{min} and \meta{max} are numerical, then this is
+equivalent to
+\cs{DTLifnumopenbetween}
+otherwise it is equivalent to
+\cs{DTLifstringopenbetween}
+(when using \cs{DTLifopenbetween}) or
+\cs{DTLifstringopenbetween*}
+(when using \cs{DTLifopenbetween*}).
+
+\begin{definition}[\DescribeMacro{\DTLifFPclosedbetween}]%
+\cs{DTLifFPclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{min} $\leq$ \meta{num} $\leq$ \meta{max} then do \meta{true part},
+otherwise do \meta{false part} where \meta{num}, \meta{min}
+and \meta{max} are all in standard fixed point notation (i.e.\
+no number group separator, no currency symbols and a full stop as
+a decimal point).
+
+\begin{definition}[\DescribeMacro{\DTLifFPopenbetween}]%
+\cs{DTLifFPopenbetween}\marg{num}\marg{min}\marg{max}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{min} $<$ \meta{num} $<$ \meta{max} then do \meta{true part},
+otherwise do \meta{false part} where \meta{num}, \meta{min}
+and \meta{max} are all in standard fixed point notation (i.e.\
+no number group separator, no currency symbols and a full stop as
+a decimal point).
+
+\begin{definition}[\DescribeMacro{\DTLifAllUpperCase}]%
+\cs{DTLifAllUpperCase}\marg{string}\marg{true part}\marg{false part}
+\end{definition}
+Tests if \meta{string} is all upper case. For example:
+\begin{verbatim}
+\DTLifAllUpperCase{WORD}{all upper}{not all upper}
+\end{verbatim}
+produces:
+\DTLifAllUpperCase{WORD}{all upper}{not all upper},
+whereas
+\begin{verbatim}
+\DTLifAllUpperCase{Word}{all upper}{not all upper}
+\end{verbatim}
+produces:
+\DTLifAllUpperCase{Word}{all upper}{not all upper}.
+Note also that:
+\begin{verbatim}
+\DTLifAllUpperCase{\MakeUppercase{word}}{all upper}{not all upper}
+\end{verbatim}
+also produces:
+\DTLifAllUpperCase{\MakeUppercase{word}}{all upper}{not all upper}.
+\cs{MakeTextUppercase} (defined in David Carlisle's \sty{textcase}
+package) and \cs{uppercase} are also detected, otherwise, if
+a command is encountered, the case of the command is considered.
+For example:
+\begin{verbatim}
+\DTLifAllUpperCase{MAN{\OE}UVRE}{all upper}{not all upper}
+\end{verbatim}
+produces:
+\DTLifAllUpperCase{MAN{\OE}UVRE}{all upper}{not all upper}.
+
+\begin{definition}[\DescribeMacro{\DTLifAllLowerCase}]%
+\cs{DTLifAllLowerCase}\marg{string}\marg{true part}\marg{false part}
+\end{definition}
+Tests if \meta{string} is all lower case. For example:
+\begin{verbatim}
+\DTLifAllLowerCase{word}{all lower}{not all lower}
+\end{verbatim}
+produces:
+\DTLifAllLowerCase{word}{all lower}{not all lower},
+whereas
+\begin{verbatim}
+\DTLifAllLowerCase{Word}{all lower}{not all lower}
+\end{verbatim}
+produces:
+\DTLifAllLowerCase{Word}{all lower}{not all lower}.
+Note also that:
+\begin{verbatim}
+\DTLifAllLowerCase{\MakeLowercase{WORD}}{all lower}{not all lower}
+\end{verbatim}
+also produces:
+\DTLifAllLowerCase{\MakeLowercase{WORD}}{all lower}{not all lower}.
+\cs{MakeTextLowercase} (defined in David Carlisle's \sty{textcase}
+package) and \cs{lowercase} are also detected, otherwise, if
+a command is encountered, the case of the command is considered.
+For example:
+\begin{verbatim}
+\DTLifAllLowerCase{man{\oe}uvre}{all lower}{not all lower}
+\end{verbatim}
+produces:
+\DTLifAllLowerCase{man{\oe}uvre}{all lower}{not all lower}.
+
+\begin{definition}[\DescribeMacro{\DTLifSubString}]%
+\cs{DTLifSubString}\marg{string}\marg{substring}\marg{true
+part}\marg{false part}
+\end{definition}
+This tests if \meta{substring} is a sub-string of \meta{string}.
+This command performs a case sensitive match. For example:
+\begin{verbatim}
+\DTLifSubString{An apple}{app}{is substring}{isn't substring}
+\end{verbatim}
+produces:
+\DTLifSubString{An apple}{app}{is substring}{isn't substring}.
+Note that spaces are considered to be equivalent to \cs{space}
+or "~", so
+\begin{verbatim}
+\DTLifSubString{An apple}{n~a}{is substring}{isn't substring}
+\end{verbatim}
+produces:
+\DTLifSubString{An apple}{n~a}{is substring}{isn't substring},
+but other commands are skipped, so
+\begin{verbatim}
+\DTLifSubString{An \uppercase{a}pple}{app}{is substring}{isn't
+substring}
+\end{verbatim}
+produces:
+\DTLifSubString{An \uppercase{a}pple}{app}{is substring}{isn't
+substring}, since the \cs{uppercase} command is ignored. Note also
+that grouping is ignored, so:
+\begin{verbatim}
+\DTLifSubString{An {ap}ple}{app}{is substring}{isn't substring}
+\end{verbatim}
+produces:
+\DTLifSubString{An {ap}ple}{app}{is substring}{isn't substring}.
+
+\cs{DTLifSubString} is case sensitive, so:
+\begin{verbatim}
+\DTLifSubString{An Apple}{app}{is substring}{isn't substring}
+\end{verbatim}
+produces:
+\DTLifSubString{An Apple}{app}{is substring}{isn't substring}.
+
+\begin{definition}[\DescribeMacro{\DTLifStartsWith}]%
+\cs{DTLifStartsWith}\marg{string}\marg{substring}\marg{true
+part}\marg{false part}
+\end{definition}
+This is like \cs{DTLifSubString}, except that \meta{substring} must
+occur at the start of \meta{string}. This command performs a case
+sensitive match. For example,
+\begin{verbatim}
+\DTLifStartsWith{An apple}{app}{prefix}{not a prefix}
+\end{verbatim}
+produces:
+\DTLifStartsWith{An apple}{app}{prefix}{not a prefix}. All the
+above remarks for \cs{DTLifSubString} also applies to
+\cs{DTLifStartsWith}. For example:
+\begin{verbatim}
+\DTLifStartsWith{\uppercase{a}n apple}{an~}{prefix}{not a prefix}
+\end{verbatim}
+produces:
+\DTLifStartsWith{\uppercase{a}n apple}{an~}{prefix}{not a prefix},
+since \cs{uppercase} is ignored, and "~" is considered to be the
+same as a space, whereas
+\begin{verbatim}
+\DTLifStartsWith{An apple}{an~}{prefix}{not a prefix}
+\end{verbatim}
+produces:
+\DTLifStartsWith{An apple}{an~}{prefix}{not a prefix}.
+
+\section{\texorpdfstring{\sty{ifthen}}{ifthen} conditionals}
+\label{sec:ifthen}
+
+The commands described in the previous section can not be
+used as the conditional part of the \cs{ifthenelse} or
+\cs{whiledo} commands provided by the \sty{ifthen} package.
+This section describes analogous commands which may only be
+used in the conditional argument of \cs{ifthenelse} and
+\cs{whiledo}. These may be used with the boolean operations
+\cs{not}, \cs{and} and \cs{or} provided by the \sty{ifthen} package.
+See the \sty{ifthen} documentation for further details.
+
+\begin{definition}[\DescribeMacro{\DTLisstring}]%
+\cs{DTLisstring}\marg{text}
+\end{definition}
+Tests if \meta{text} is a string. For example:
+\begin{verbatim}
+\ifthenelse{\DTLisstring{some text}}{string}{not a string}
+\end{verbatim}
+produces:
+\ifthenelse{\DTLisstring{some text}}{string}{not a string}.
+
+\begin{definition}[\DescribeMacro{\DTLisnumerical}]%
+\cs{DTLisnumerical}\marg{text}
+\end{definition}
+Tests if \meta{text} is numerical (i.e.\ not a string). For example:
+\begin{verbatim}
+\ifthenelse{\DTLisnumerical{\$10.95}}{numerical}{not numerical}
+\end{verbatim}
+produces:
+\ifthenelse{\DTLisnumerical{\$10.95}}{numerical}{not numerical}.
+
+Note however that \cs{DTLisnumerical} requires more care than
+\cs{DTLifnumerical} when used with some of the other currency
+symbols. Consider:
+\begin{verbatim}
+\DTLifnumerical{\pounds10.95}{numerical}{not numerical}
+\end{verbatim}
+This produces:
+\DTLifnumerical{\pounds10.95}{numerical}{not numerical}.
+However
+\begin{verbatim}
+\ifthenelse{\DTLisnumerical{\pounds10.95}}{numerical}{not numerical}
+\end{verbatim}
+produces:
+\ifthenelse{\DTLisnumerical{\pounds10.95}}{numerical}{not numerical}.
+This is due to the expansion that occurs within \cs{ifthenelse}.
+This can be prevented using \cs{noexpand}, for example:
+\begin{verbatim}
+\ifthenelse{\DTLisnumerical{\noexpand\pounds10.95}}{numerical}{not numerical}
+\end{verbatim}
+produces:
+\ifthenelse{\DTLisnumerical{\noexpand\pounds10.95}}{numerical}{not numerical}.
+
+Likewise:
+\begin{verbatim}
+\def\cost{\pounds10.95}%
+\ifthenelse{\DTLisnumerical{\noexpand\cost}}{numerical}{not numerical}
+\end{verbatim}
+produces:
+\def\cost{\pounds10.95}\relax
+\ifthenelse{\DTLisnumerical{\noexpand\cost}}{numerical}{not numerical}.
+
+\begin{definition}[\DescribeMacro{\DTLiscurrency}]%
+\cs{DTLiscurrency}\marg{text}
+\end{definition}
+Tests if \meta{text} is currency. For example:
+\begin{verbatim}
+\ifthenelse{\DTLiscurrency{\$10.95}}{currency}{not currency}
+\end{verbatim}
+produces:
+\ifthenelse{\DTLiscurrency{\$10.95}}{currency}{not currency}.
+
+The same warning given above for \cs{DTLisnumerical} also applies
+here.
+
+\begin{definition}[\DescribeMacro{\DTLiscurrencyunit}]%
+\cs{DTLiscurrencyunit}\marg{text}\marg{symbol}
+\end{definition}
+Tests if \meta{text} is currency and that currency uses \meta{symbol} as the unit
+of currency.
+For example:
+\begin{verbatim}
+\ifthenelse{\DTLiscurrencyunit{\$6.99}{\$}}{dollars}{not dollars}
+\end{verbatim}
+produces:
+\ifthenelse{\DTLiscurrencyunit{\$6.99}{\$}}{dollars}{not dollars}.
+Another example:
+\begin{verbatim}
+\def\cost{\euro10.50}%
+\ifthenelse{\DTLiscurrencyunit{\noexpand\cost}{\noexpand\euro}}%
+{euros}{not euros}
+\end{verbatim}
+produces:
+\def\cost{\euro10.50}\relax
+\ifthenelse{\DTLiscurrencyunit{\noexpand\cost}{\noexpand\euro}}%
+{euros}{not euros}. Again note the use of \cs{noexpand}.
+
+\begin{definition}[\DescribeMacro{\DTLisreal}]%
+\cs{DTLisreal}\marg{text}
+\end{definition}
+Tests if \meta{text} is a fixed point number (again, an integer is
+not considered to be a fixed point number). For example:
+\begin{verbatim}
+\ifthenelse{\DTLisreal{1.5}}{real}{not real}
+\end{verbatim}
+produces:
+\ifthenelse{\DTLisreal{1.5}}{real}{not real}.
+
+\begin{definition}[\DescribeMacro{\DTLisint}]%
+\cs{DTLisint}\marg{text}
+\end{definition}
+Tests if \meta{text} is an integer. For example:
+\begin{verbatim}
+\ifthenelse{\DTLisint{153}}{integer}{not an integer}
+\end{verbatim}
+produces:
+\ifthenelse{\DTLisint{153}}{integer}{not an integer}.
+
+\begin{definition}[\DescribeMacro{\DTLislt}]%
+\cs{DTLislt}\marg{arg1}\marg{arg2}
+\end{definition}
+This checks if \meta{arg1} is less than \meta{arg2}. As with
+\cs{DTLiflt}, if \meta{arg1} and \meta{arg2} are numerical,
+a numerical comparison is used, otherwise a case sensitive
+alphabetical comparison is used. (Note that there is no starred
+version of this command, but you can instead use \cs{DTLisilt}
+to ignore the case.)
+
+\begin{definition}[\DescribeMacro{\DTLisilt}]%
+\cs{DTLisilt}\marg{arg1}\marg{arg2}
+\end{definition}
+This checks if \meta{arg1} is less than \meta{arg2}. As with
+\cs{DTLiflt*}, if \meta{arg1} and \meta{arg2} are numerical,
+a numerical comparison is used, otherwise a case insensitive
+alphabetical comparison is used.
+
+\begin{definition}[\DescribeMacro{\DTLisgt}]%
+\cs{DTLisgt}\marg{arg1}\marg{arg2}
+\end{definition}
+This checks if \meta{arg1} is greater than \meta{arg2}. As with
+\cs{DTLifgt}, if \meta{arg1} and \meta{arg2} are numerical,
+a numerical comparison is used, otherwise a case sensitive
+alphabetical comparison is used. (Note that there is no starred
+version of this command, instead use \cs{DTLisigt} to
+ignore the case.)
+
+\begin{definition}[\DescribeMacro{\DTLisigt}]%
+\cs{DTLisigt}\marg{arg1}\marg{arg2}
+\end{definition}
+This checks if \meta{arg1} is greater than \meta{arg2}. As with
+\cs{DTLifgt*}, if \meta{arg1} and \meta{arg2} are numerical,
+a numerical comparison is used, otherwise a case insensitive
+alphabetical comparison is used.
+
+\begin{definition}[\DescribeMacro{\DTLiseq}]%
+\cs{DTLiseq}\marg{arg1}\marg{arg2}
+\end{definition}
+This checks if \meta{arg1} is equal to \meta{arg2}. As with
+\cs{DTLifeq}, if \meta{arg1} and \meta{arg2} are numerical,
+a numerical comparison is used, otherwise a case sensitive
+alphabetical comparison is used. (Note that there is no starred
+version of this command, instead use \cs{DTLisieq}.)
+
+\begin{definition}[\DescribeMacro{\DTLisieq}]%
+\cs{DTLisieq}\marg{arg1}\marg{arg2}
+\end{definition}
+This checks if \meta{arg1} is equal to \meta{arg2}. As with
+\cs{DTLifeq*}, if \meta{arg1} and \meta{arg2} are numerical,
+a numerical comparison is used, otherwise a case insensitive
+alphabetical comparison is used.
+
+\begin{definition}[\DescribeMacro{\DTLisclosedbetween}]%
+\cs{DTLisclosedbetween}\marg{arg}\marg{min}\marg{max}
+\end{definition}
+This checks if \meta{arg} lies between \meta{min} and
+\meta{max} (end points included). As with
+\cs{DTLifclosedbetween}, if the arguments are numerical,
+a numerical comparison is used, otherwise a case sensitive
+alphabetical comparison is used. (Note that there is no starred
+version of this command, instead use \cs{DTLisiclosedbetween}.)
+
+\begin{definition}[\DescribeMacro{\DTLisiclosedbetween}]%
+\cs{DTLisiclosedbetween}\marg{arg}\marg{min}\marg{max}
+\end{definition}
+This checks if \meta{arg} lies between \meta{min} and
+\meta{max} (end points included). As with
+\cs{DTLifclosedbetween*}, if the arguments are numerical,
+a numerical comparison is used, otherwise a case insensitive
+alphabetical comparison is used.
+
+\begin{definition}[\DescribeMacro{\DTLisopenbetween}]%
+\cs{DTLisopenbetween}\marg{arg}\marg{min}\marg{max}
+\end{definition}
+This checks if \meta{arg} lies between \meta{min} and
+\meta{max} (end points excluded). As with
+\cs{DTLifopenbetween}, if the arguments are numerical,
+a numerical comparison is used, otherwise a case sensitive
+alphabetical comparison is used. (Note that there is no starred
+version of this command, instead use \cs{DTLisiopenbetween}.)
+
+\begin{definition}[\DescribeMacro{\DTLisiopenbetween}]%
+\cs{DTLisiopenbetween}\marg{arg}\marg{min}\marg{max}
+\end{definition}
+This checks if \meta{arg} lies between \meta{min} and
+\meta{max} (end points excluded). As with
+\cs{DTLifopenbetween*}, if the arguments are numerical,
+a numerical comparison is used, otherwise a case insensitive
+alphabetical comparison is used.
+
+\begin{definition}[\DescribeMacro{\DTLisFPlt}]%
+\cs{DTLisFPlt}\marg{num1}\marg{num2}
+\end{definition}
+This checks if \meta{num1} is less than \meta{num2}, where both
+numbers are in standard fixed point format (i.e.\ no number group
+separators, no currency and a full stop as a decimal point).
+
+\begin{definition}[\DescribeMacro{\DTLisFPlteq}]%
+\cs{DTLisFPlteq}\marg{num1}\marg{num2}
+\end{definition}
+This checks if \meta{num1} is less than or equal to \meta{num2}, where both
+numbers are in standard fixed point format (i.e.\ no number group
+separators, no currency and a full stop as a decimal point).
+
+\begin{definition}[\DescribeMacro{\DTLisFPgt}]%
+\cs{DTLisFPgt}\marg{num1}\marg{num2}
+\end{definition}
+This checks if \meta{num1} is greater than \meta{num2}, where both
+numbers are in standard fixed point format (i.e.\ no number group
+separators, no currency and a full stop as a decimal point).
+
+\begin{definition}[\DescribeMacro{\DTLisFPgteq}]%
+\cs{DTLisFPgteq}\marg{num1}\marg{num2}
+\end{definition}
+This checks if \meta{num1} is greater than or equal to \meta{num2}, where both
+numbers are in standard fixed point format (i.e.\ no number group
+separators, no currency and a full stop as a decimal point).
+
+\begin{definition}[\DescribeMacro{\DTLisFPeq}]%
+\cs{DTLisFPeq}\marg{num1}\marg{num2}
+\end{definition}
+This checks if \meta{num1} is equal to \meta{num2}, where both
+numbers are in standard fixed point format (i.e.\ no number group
+separators, no currency and a full stop as a decimal point).
+
+\begin{definition}[\DescribeMacro{\DTLisFPclosedbetween}]%
+\cs{DTLisFPclosedbetween}\marg{num}\marg{min}\marg{max}
+\end{definition}
+This checks if \meta{num} lies between \meta{min} and
+\meta{max} (end points included). All arguments must be
+numbers in standard fixed point format (i.e.\ no number group
+separators, no currency and a full stop as a decimal point).
+
+\begin{definition}[\DescribeMacro{\DTLisFPopenbetween}]%
+\cs{DTLisFPopenbetween}\marg{num}\marg{min}\marg{max}
+\end{definition}
+This checks if \meta{num} lies between \meta{min} and
+\meta{max} (end points excluded). All arguments must be
+numbers in standard fixed point format (i.e.\ no number group
+separators, no currency and a full stop as a decimal point).
+
+\begin{definition}[\DescribeMacro{\DTLisSubString}]%
+\cs{DTLisSubString}\marg{string}\marg{substring}
+\end{definition}
+This checks if \meta{substring} is contained in \meta{string}.
+The remarks about \cs{DTLifSubString} also apply to
+\cs{DTLisSubString}. This command performs a case sensitive
+match.
+
+\begin{definition}[\DescribeMacro{\DTLisPrefix}]%
+\cs{DTLisPrefix}\marg{string}\marg{prefix}
+\end{definition}
+This checks if \meta{string} starts with \meta{prefix}.
+The remarks about \cs{DTLifStartsWith} also apply to
+\cs{DTLisPrefix}. This command performs a case sensitive
+match.
+
+\chapter{Fixed Point Arithmetic}
+\label{sec:fp}
+
+The \sty{datatool-base} package uses either the \sty{fp} or the \sty{pgfmath} package to perform
+fixed point arithmetic, however all numbers must be converted
+from the locale dependent format into the format required by the
+\sty{fp} or \sty{pgfmath} packages. A numerical value (i.e.\ an integer, a real
+or currency) can be converted into a plain decimal number using
+\begin{definition}[\DescribeMacro{\DTLconverttodecimal}]%
+\cs{DTLconverttodecimal}\marg{num}\marg{cmd}
+\end{definition}
+The decimal number will be stored in \meta{cmd} which must be
+a control sequence. For example:
+\begin{verbatim}
+\DTLconverttodecimal{1,563.54}{\mynum}
+\end{verbatim}
+\DTLconverttodecimal{1,563.54}{\mynum}\relax
+will define \cs{mynum} to be \texttt{\mynum}. The command \cs{mynum}
+can then be used in any of the arithmetic macros provided by the
+\sty{fp} or \sty{pgfmath} packages.
+
+\begin{important}
+The arguments to \cs{DTLconverttodecimal} don't get fully expanded
+so, for example,
+\begin{verbatim}
+\def\myval{1.23}
+\DTLconverttodecimal{\myval}{\mynum}
+\end{verbatim}
+will work, but the following \emph{\bfseries won't} work:
+\begin{verbatim}
+\def\myval{1.23}
+\def\myotherval{\myval}
+\DTLconverttodecimal{\myotherval}{\mynum}
+\end{verbatim}
+Nor will the following work:
+\begin{verbatim}
+\def\myval{9}
+\DTLconverttodecimal{\myval 9}{\mynum}
+\end{verbatim}
+\end{important}
+There are two commands provided to perform
+the reverse:
+\begin{definition}[\DescribeMacro{\DTLdecimaltolocale}]%
+\cs{DTLdecimaltolocale}\marg{number}\marg{cmd}
+\end{definition}
+This converts a plain decimal number \meta{number} (that uses a full
+stop as the decimal character and has no number group characters)
+into a locale dependent format. The resulting number is stored
+in \meta{cmd}, which must be a control sequence. For example:
+\begin{verbatim}
+\DTLdecimaltolocale{6795.3}{\mynum}
+\end{verbatim}
+\DTLdecimaltolocale{6795.3}{\mynum}
+will define \cs{mynum} to be \texttt{\mynum}.
+
+\begin{definition}[\DescribeMacro{\DTLdecimaltocurrency}]%
+\cs{DTLdecimaltocurrency}\marg{number}\marg{cmd}
+\end{definition}
+This will convert a plain decimal number \meta{number} into a
+locale dependent currency format. For example:
+\begin{verbatim}
+\DTLdecimaltocurrency{267.5}{\price}\price
+\end{verbatim}
+will produce:
+\DTLdecimaltocurrency{267.5}{\price}\price.
+
+The currency symbol used by \cs{DTLdecimaltocurrency} is
+initially "\$", but it will use the currency last encountered.
+So, for example
+\begin{verbatim}
+\DTLifcurrency{\texteuro45.00}{}{}%
+\DTLdecimaltocurrency{267.5}{\price}\price
+\end{verbatim}
+will produce:
+\DTLifcurrency{\texteuro45.00}{}{}\relax
+\DTLdecimaltocurrency{267.5}{\price}\price. This is because
+the last currency symbol to be encountered was \cs{texteuro}.
+You can reset the currency symbol using the command:
+\begin{definition}[\DescribeMacro{\DTLsetdefaultcurrency}]%
+\cs{DTLsetdefaultcurrency}\marg{symbol}
+\end{definition}
+For example:
+\begin{verbatim}
+\DTLsetdefaultcurrency{\textyen}%
+\DTLdecimaltocurrency{267.5}{\price}\price
+\end{verbatim}
+will produce:
+\DTLsetdefaultcurrency{\textyen}\relax
+\DTLdecimaltocurrency{267.5}{\price}\price
+
+The \sty{datatool-base} package provides convenience commands which
+use \cs{DTLconverttodecimal}, and then use the basic macros provided
+by the \sty{fp}\slash\sty{pgfmath} package. The resulting value is then converted
+back into the locale format using
+\cs{DTLdecimaltolocale} or \cs{DTLdecimaltocurrency}.
+Note that since these commands use \cs{DTLconverttodecimal} the
+caveat above regarding expansion also applies to all the commands.
+
+
+\begin{definition}[\DescribeMacro{\DTLadd}]%
+\cs{DTLadd}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgadd}]%
+\cs{DTLgadd}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+This sets the control sequence \meta{cmd} to \meta{num1}+\meta{num2}.
+\cs{DLTadd} sets \meta{cmd} locally, while \cs{DTLgadd} sets
+\meta{cmd} globally.
+
+For example:
+\begin{verbatim}
+\DTLadd{\result}{3,562.65}{412.2}\result
+\end{verbatim}
+will produce:
+\DTLadd{\result}{3,562.65}{412.2}\result. Since
+\cs{DTLconverttodecimal} can convert currency to a real
+number, you can also add prices. For example:
+\begin{verbatim}
+\DTLadd{\result}{\pounds3,562.65}{\pounds452.2}\result
+\end{verbatim}
+produces:
+\DTLadd{\result}{\pounds3,562.65}{\pounds452.2}\result.
+
+Note that \sty{datatool} isn't aware of exchange rates! If you
+use different currency symbols, the last symbol will be used.
+For example
+\begin{verbatim}
+\DTLadd{\result}{\pounds3,562.65}{\euro452.2}\result
+\end{verbatim}
+produces:
+\DTLadd{\result}{\pounds3,562.65}{\euro452.2}\result.
+
+Likewise, if one value is a number and the other is a currency,
+the type of the last value, \meta{num2}, will be used for the
+result. For example:
+\begin{verbatim}
+\DTLadd{\result}{3,562.65}{\$452.2}\result
+\end{verbatim}
+produces:
+\DTLadd{\result}{3,562.65}{\$452.2}\result.
+
+\begin{definition}[\DescribeMacro{\DTLaddall}]%
+\cs{DTLaddall}\marg{cmd}\marg{number list}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgaddall}]%
+\cs{DTLgaddall}\marg{cmd}\marg{number list}
+\end{definition}
+This sets the control sequence \meta{cmd} to the sum of all
+the numbers in \meta{number list}.
+\cs{DLTaddall} sets \meta{cmd} locally, while \cs{DTLgaddall} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLaddall{\total}{25.1,45.2,35.6}\total
+\end{verbatim}
+produces:
+\DTLaddall{\total}{25.1,45.2,35.6}\total.
+Note that if any of the numbers in \meta{number list} contain
+a comma, you must group the number. Example:
+\begin{verbatim}
+\DTLaddall{\total}{{1,525},{2,340},500}\total
+\end{verbatim}
+produces:
+\DTLaddall{\total}{{1,525},{2,340},500}\total.
+
+\begin{definition}[\DescribeMacro{\DTLsub}]%
+\cs{DTLsub}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgsub}]%
+\cs{DTLgsub}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+This sets the control sequence \meta{cmd} to
+\meta{num1}$-$\meta{num2}.
+\cs{DLTsub} sets \meta{cmd} locally, while \cs{DTLgsub} sets
+\meta{cmd} globally.
+
+For example:
+\begin{verbatim}
+\DTLsub{\result}{3,562.65}{412.2}\result
+\end{verbatim}
+will produce:
+\DTLsub{\result}{3,562.65}{412.2}\result. As with \cs{DTLadd},
+\meta{num1} and \meta{num2} may be currency.
+
+\begin{definition}[\DescribeMacro{\DTLmul}]%
+\cs{DTLmul}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgmul}]%
+\cs{DTLgmul}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+This sets the control sequence \meta{cmd} to
+\meta{num1}$\times$\meta{num2}.
+\cs{DLTmul} sets \meta{cmd} locally, while \cs{DTLgmul} sets
+\meta{cmd} globally.
+
+For example:
+\begin{verbatim}
+\DTLmul{\result}{568.95}{2}\result
+\end{verbatim}
+will produce:
+\DTLmul{\result}{568.95}{2}\result. Again, \meta{num1} or
+\meta{num2} may be currency, but unlike \cs{DTLadd} and \cs{DTLsub},
+currency overrides integer/real. For example:
+\begin{verbatim}
+\DTLmul{\result}{\pounds568.95}{2}\result
+\end{verbatim}
+will produce:
+\DTLmul{\result}{\pounds568.95}{2}\result. Likewise,
+\begin{verbatim}
+\DTLmul{\result}{2}{\pounds568.95}\result
+\end{verbatim}
+will produce:
+\DTLmul{\result}{2}{\pounds568.95}\result. Although it doesn't make
+sense to multiply two currencies, \sty{datatool} will allow
+\begin{verbatim}
+\DTLmul{\result}{\$2}{\pounds568.95}\result
+\end{verbatim}
+which will produce:
+\DTLmul{\result}{\$2}{\pounds568.95}\result.
+
+\begin{definition}[\DescribeMacro{\DTLdiv}]%
+\cs{DTLdiv}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgdiv}]%
+\cs{DTLgdiv}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+This sets the control sequence \meta{cmd} to
+\meta{num1}$\div$\meta{num2}.
+\cs{DLTdiv} sets \meta{cmd} locally, while \cs{DTLgdiv} sets
+\meta{cmd} globally.
+
+For example:
+\begin{verbatim}
+\DTLdiv{\result}{501}{2}\result
+\end{verbatim}
+will produce:
+\DTLdiv{\result}{501}{2}\result. Again, \meta{num1} or \meta{num2}
+may be currency, but the resulting type will be not be a currency
+if both \meta{num1} and \meta{num2} use the same currency symbol.
+For example:
+\begin{verbatim}
+\DTLdiv{\result}{\$501}{\$2}\result
+\end{verbatim}
+will produce:
+\DTLdiv{\result}{\$501}{\$2}\result. Whereas
+\begin{verbatim}
+\DTLdiv{\result}{\$501}{2}\result
+\end{verbatim}
+will produce:
+\DTLdiv{\result}{\$501}{2}\result.
+
+\begin{definition}[\DescribeMacro{\DTLabs}]%
+\cs{DTLabs}\marg{cmd}\marg{num}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgabs}]%
+\cs{DTLgabs}\marg{cmd}\marg{num}
+\end{definition}
+This sets \meta{cmd} to the absolute value of \meta{num}.
+\cs{DLTabs} sets \meta{cmd} locally, while \cs{DTLgabs} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLabs{\result}{-\pounds2.50}\result
+\end{verbatim}
+produces:
+\DTLabs{\result}{-\pounds2.50}\result.
+
+\begin{definition}[\DescribeMacro{\DTLneg}]%
+\cs{DTLneg}\marg{cmd}\marg{num}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgneg}]%
+\cs{DTLgneg}\marg{cmd}\marg{num}
+\end{definition}
+This sets \meta{cmd} to the negative of \meta{num}.
+\cs{DLTneg} sets \meta{cmd} locally, while \cs{DTLgneg} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLneg{\result}{\pounds2.50}\result
+\end{verbatim}
+produces:
+\DTLneg{\result}{\pounds2.50}\result.
+
+\begin{definition}[\DescribeMacro{\DTLsqrt}]%
+\cs{DTLsqrt}\marg{cmd}\marg{num}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgsqrt}]%
+\cs{DTLgsqrt}\marg{cmd}\marg{num}
+\end{definition}
+This sets \meta{cmd} to the sqrt root of \meta{num}.
+\cs{DLTsqrt} sets \meta{cmd} locally, while \cs{DTLgsqrt} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLsqrt{\result}{2}\result
+\end{verbatim}
+produces:
+\DTLsqrt{\result}{2}\result.
+
+\begin{definition}[\DescribeMacro{\DTLmin}]%
+\cs{DTLmin}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgmin}]%
+\cs{DTLgmin}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+This sets the control sequence \meta{cmd} to the minimum of
+\meta{num1} and \meta{num2}.
+\cs{DLTmin} sets \meta{cmd} locally, while \cs{DTLgmin} sets
+\meta{cmd} globally. For example:
+\begin{verbatim}
+\DTLmin{\result}{256}{32}\result
+\end{verbatim}
+produces:
+\DTLmin{\result}{256}{32}\result.
+Again, \meta{num1} and \meta{num2} may
+be currency. For example:
+\begin{verbatim}
+\DTLmin{\result}{256}{\pounds32}\result
+\end{verbatim}
+produces:
+\DTLmin{\result}{256}{\pounds32}\result, whereas
+\begin{verbatim}
+\DTLmin{\result}{\pounds256}{32}\result
+\end{verbatim}
+produces:
+\DTLmin{\result}{\pounds256}{32}\result. As mentioned above,
+\sty{datatool} doesn't know about exchange rates, so be careful
+about mixing currencies. For example:
+\begin{verbatim}
+\DTLmin{\result}{\pounds5}{\$6}\result
+\end{verbatim}
+produces:
+\DTLmin{\result}{\pounds5}{\$6}\result, which may not necessarily
+be true!
+
+\begin{definition}[\DescribeMacro{\DTLminall}]%
+\cs{DTLminall}\marg{cmd}\marg{number list}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgminall}]%
+\cs{DTLgminall}\marg{cmd}\marg{number list}
+\end{definition}
+This sets the control sequence \meta{cmd} to the minimum of all
+the numbers in \meta{number list}.
+\cs{DLTminall} sets \meta{cmd} locally, while \cs{DTLgminall} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLminall{\theMin}{25.1,45.2,35.6}\theMin
+\end{verbatim}
+produces:
+\DTLminall{\theMin}{25.1,45.2,35.6}\theMin.
+Note that if any of the numbers in \meta{number list} contain
+a comma, you must group the number. Example:
+\begin{verbatim}
+\DTLminall{\theMin}{{1,525},{2,340},500}\theMin
+\end{verbatim}
+produces:
+\DTLminall{\theMin}{{1,525},{2,340},500}\theMin.
+
+\begin{definition}[\DescribeMacro{\DTLmax}]%
+\cs{DTLmax}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgmax}]%
+\cs{DTLgmax}\marg{cmd}\marg{num1}\marg{num2}
+\end{definition}
+This sets the control sequence \meta{cmd} to the maximum of
+\meta{num1} and \meta{num2}.
+\cs{DLTmax} sets \meta{cmd} locally, while \cs{DTLgmax} sets
+\meta{cmd} globally. For example:
+\begin{verbatim}
+\DTLmax{\result}{256}{32}\result
+\end{verbatim}
+produces:
+\DTLmax{\result}{256}{32}\result.
+Again, \meta{num1} and \meta{num2} may
+be currency, but the same warnings for \cs{DTLmin} apply.
+
+\begin{definition}[\DescribeMacro{\DTLmaxall}]%
+\cs{DTLmaxall}\marg{cmd}\marg{number list}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgmaxall}]%
+\cs{DTLgmaxall}\marg{cmd}\marg{number list}
+\end{definition}
+This sets the control sequence \meta{cmd} to the maximum of all
+the numbers in \meta{number list}.
+\cs{DLTmaxall} sets \meta{cmd} locally, while \cs{DTLgmaxall} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLmaxall{\theMax}{25.1,45.2,35.6}\theMax
+\end{verbatim}
+produces:
+\DTLmaxall{\theMax}{25.1,45.2,35.6}\theMax.
+Note that if any of the numbers in \meta{number list} contain
+a comma, you must group the number. Example:
+\begin{verbatim}
+\DTLmaxall{\theMax}{{1,525},{2,340},500}\theMax
+\end{verbatim}
+produces:
+\DTLmaxall{\theMax}{{1,525},{2,340},500}\theMax.
+
+\begin{definition}[\DescribeMacro{\DTLmeanforall}]%
+\cs{DTLmeanforall}\marg{cmd}\marg{number list}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgmeanall}]%
+\cs{DTLgmeanforall}\marg{cmd}\marg{number list}
+\end{definition}
+This sets the control sequence \meta{cmd} to the arithmetic mean of all
+the numbers in \meta{number list}.
+\cs{DLTmeanforall} sets \meta{cmd} locally, while \cs{DTLgmeanforall} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLmeanforall{\theMean}{25.1,45.2,35.6}\theMean
+\end{verbatim}
+produces:
+\DTLmeanforall{\theMean}{25.1,45.2,35.6}\theMean.
+Note that if any of the numbers in \meta{number list} contain
+a comma, you must group the number. Example:
+\begin{verbatim}
+\DTLmeanforall{\theMean}{{1,525},{2,340},500}\theMean
+\end{verbatim}
+produces:
+\DTLmeanforall{\theMean}{{1,525},{2,340},500}\theMean.
+
+\begin{definition}[\DescribeMacro{\DTLvarianceforall}]%
+\cs{DTLvarianceforall}\marg{cmd}\marg{number list}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgvarianceforall}]%
+\cs{DTLgvarianceforall}\marg{cmd}\marg{number list}
+\end{definition}
+This sets the control sequence \meta{cmd} to the variance of all
+the numbers in \meta{number list}.
+\cs{DLTvarianceforall} sets \meta{cmd} locally, while \cs{DTLgvarianceforall} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLvarianceforall{\theVar}{25.1,45.2,35.6}\theVar
+\end{verbatim}
+produces:
+\DTLvarianceforall{\theVar}{25.1,45.2,35.6}\theVar.
+Again note that if any of the numbers in \meta{number list}
+contain a comma, you must group the number.
+
+\begin{definition}[\DescribeMacro{\DTLsdforall}]%
+\cs{DTLsdforall}\marg{cmd}\marg{number list}
+\end{definition}
+\pagebreak
+\begin{definition}[\DescribeMacro{\DTLgsdforall}]%
+\cs{DTLgsdforall}\marg{cmd}\marg{number list}
+\end{definition}
+This sets the control sequence \meta{cmd} to the standard deviation of all
+the numbers in \meta{number list}.
+\cs{DLTsdforall} sets \meta{cmd} locally, while \cs{DTLgsdforall} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLsdforall{\theSD}{25.1,45.2,35.6}\theSD
+\end{verbatim}
+produces:
+\DTLsdforall{\theSD}{25.1,45.2,35.6}\theSD.
+Note that if any of the numbers in \meta{number list} contain
+a comma, you must group the number. Example:
+\begin{verbatim}
+\DTLsdforall{\theSD}{{1,525},{2,340},500}\theSD
+\end{verbatim}
+produces:
+\DTLsdforall{\theSD}{{1,525},{2,340},500}\theSD.
+
+\begin{definition}[\DescribeMacro{\DTLround}]%
+\cs{DTLround}\marg{cmd}\marg{num}\marg{num digits}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLground}]%
+\cs{DTLground}\marg{cmd}\marg{num}\marg{num digits}
+\end{definition}
+This sets \meta{cmd} to \meta{num} rounded to \meta{num digits}
+after the decimal character.
+\cs{DLTround} sets \meta{cmd} locally, while \cs{DTLground} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLround{\result}{3.135276}{2}\result
+\end{verbatim}
+produces: \DTLround{\result}{3.135276}{2}\result.
+
+\begin{definition}[\DescribeMacro{\DTLtrunc}]%
+\cs{DTLtrunc}\marg{cmd}\marg{num}\marg{num digits}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgtrunc}]%
+\cs{DTLgtrunc}\marg{cmd}\marg{num}\marg{num digits}
+\end{definition}
+This sets \meta{cmd} to \meta{num} truncated to \meta{num digits}
+after the decimal character.
+\cs{DLTtrunc} sets \meta{cmd} locally, while \cs{DTLgtrunc} sets
+\meta{cmd} globally. Example:
+\begin{verbatim}
+\DTLtrunc{\result}{3.135276}{2}\result
+\end{verbatim}
+produces: \DTLtrunc{\result}{3.135276}{2}\result.
+
+\pagebreak
+\begin{definition}[\DescribeMacro{\DTLclip}]%
+\cs{DTLclip}\marg{cmd}\marg{num}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLgclip}]%
+\cs{DTLgclip}\marg{cmd}\marg{num}
+\end{definition}
+This sets \meta{cmd} to \meta{num} with all unnecessary 0's
+removed.
+\cs{DLTclip} sets \meta{cmd} locally, while \cs{DTLgclip} sets
+\meta{cmd} globally.
+
+\chapter{Strings}
+\label{sec:strings}
+
+Strings are considered to be anything non-numerical. The
+\sty{datatool} package loads the \sty{substr} package, so
+you can use the commands defined in that package to determine
+if one string is contained in another string. In addition,
+the \sty{datatool} provides the following macros:
+
+\begin{definition}[\DescribeMacro{\DTLsubstitute}]%
+\cs{DTLsubstitute}\marg{cmd}\marg{original}\marg{replacement}
+\end{definition}
+This replaces the first occurrence of \meta{original} in
+\meta{cmd} with \meta{replacement}. Note that \meta{cmd} must
+be the name of a command. For example:
+\begin{verbatim}
+\def\mystr{abcdce}\DTLsubstitute{\mystr}{c}{z}\mystr
+\end{verbatim}
+produces:
+\def\mystr{abcdce}\DTLsubstitute{\mystr}{c}{z}\mystr.
+
+\begin{definition}[\DescribeMacro{\DTLsubstituteall}]%
+\cs{DTLsubstituteall}\marg{cmd}\marg{original}\marg{replacement}
+\end{definition}
+This replaces all occurrences of \meta{original} in
+\meta{cmd} with \meta{replacement}, where again, \meta{cmd} must
+be the name of a command. For example:
+\begin{verbatim}
+\def\mystr{abcdce}\DTLsubstituteall{\mystr}{c}{z}\mystr
+\end{verbatim}
+produces:
+\def\mystr{abcdce}\DTLsubstituteall{\mystr}{c}{z}\mystr.
+
+\begin{definition}[\DescribeMacro{\DTLsplitstring}]%
+\cs{DTLsplitstring}\marg{string}\marg{split text}\marg{before
+cmd}\marg{after cmd}
+\end{definition}
+This splits \meta{string} at the first occurrence of \meta{split text}
+and stores the before part in the command \meta{before cmd} and
+the after part in the command \meta{after cmd}. For example:
+\begin{verbatim}
+\DTLsplitstring{abcdce}{c}{\beforepart}{\afterpart}%
+Before part: ``\beforepart''. After part: ``\afterpart''
+\end{verbatim}
+produces:
+\DTLsplitstring{abcdce}{c}{\beforepart}{\afterpart}\relax
+Before part: ``\beforepart''. After part: ``\afterpart''.
+Note that for \cs{DTLsplitstring}, \meta{string} is not
+expanded, so
+\begin{verbatim}
+\def\mystr{abcdce}%
+\DTLsplitstring{\mystr}{c}{\beforepart}{\afterpart}%
+Before part: ``\beforepart''. After part: ``\afterpart''
+\end{verbatim}
+produces:
+\def\mystr{abcdce}\relax
+\DTLsplitstring{\mystr}{c}{\beforepart}{\afterpart}%
+Before part: ``\beforepart''. After part: ``\afterpart''. If you
+want the string expanded, you will need to use \cs{expandafter}:
+\begin{verbatim}
+\def\mystr{abcdce}%
+\expandafter\DTLsplitstring\expandafter
+{\mystr}{c}{\beforepart}{\afterpart}%
+Before part: ``\beforepart''. After part: ``\afterpart''
+\end{verbatim}
+which produces:
+\def\mystr{abcdce}\relax
+\expandafter\DTLsplitstring\expandafter
+{\mystr}{c}{\beforepart}{\afterpart}\relax
+Before part: ``\beforepart''. After part: ``\afterpart''.
+
+\begin{definition}[\DescribeMacro{\DTLinitials}]%
+\cs{DTLinitials}\marg{string}
+\end{definition}
+This converts \meta{string} (typically a name) into initials.
+For example:
+\begin{verbatim}
+\DTLinitials{Mary Ann}
+\end{verbatim}
+produces:
+\DTLinitials{Mary Ann} (including the final full stop). Note that
+\begin{verbatim}
+\DTLinitials{Mary-Ann}
+\end{verbatim}
+produces:
+\DTLinitials{Mary-Ann} (including the final full stop).
+Be careful if the initial letter has an
+accent. The accented letter needs to be placed in a group, if
+you want the initial to also have an accent, otherwise the
+accent command will be ignored. For example:
+\begin{verbatim}
+\DTLinitials{{\'E}lise Adams}
+\end{verbatim}
+produces:
+\DTLinitials{{\'E}lise Adams}, whereas
+\begin{verbatim}
+\DTLinitials{\'Elise Adams}
+\end{verbatim}
+produces:
+\DTLinitials{\'Elise Adams} In fact, any command which appears
+at the start of the name that is not enclosed in a group will
+be ignored. For example:
+\begin{verbatim}
+\DTLinitials{\MakeUppercase{m}ary ann}
+\end{verbatim}
+produces:
+\DTLinitials{\MakeUppercase{m}ary ann}, whereas
+\begin{verbatim}
+\DTLinitials{{\MakeUppercase{m}}ary ann}
+\end{verbatim}
+produces:
+\DTLinitials{{\MakeUppercase{m}}ary ann}, but note that
+\begin{verbatim}
+\DTLinitials{\MakeUppercase{mary ann}}
+\end{verbatim}
+produces:
+\DTLinitials{\MakeUppercase{mary ann}}
+
+\begin{definition}[\DescribeMacro{\DTLstoreinitials}]%
+\cs{DTLstoreinitials}\marg{string}\marg{cmd}
+\end{definition}
+This converts \meta{string} into initials and stores the
+result in \meta{cmd} which must be a command name. The remarks
+about \cs{DTLinitials} also relate to \cs{DTLstoreinitials}.
+For example
+\begin{verbatim}
+\DTLstoreinitials{Marie-{\'E}lise del~Rosario}{\theInitials}\theInitials
+\end{verbatim}
+produces:
+\DTLstoreinitials{Marie-{\'E}lise del~Rosario}{\theInitials}\theInitials
+
+Both the above commands rely on the following to format the
+initials:
+\begin{definition}[\DescribeMacro{\DTLafterinitials}]%
+\cs{DTLafterinitials}
+\end{definition}
+This indicates what to do at the end of the initials. This
+simply does a full stop by default.
+
+\begin{definition}[\DescribeMacro{\DTLbetweeninitials}]%
+\cs{DTLbetweeninitials}
+\end{definition}
+This indicates what to do between initials. This does a
+full stop by default.
+
+\begin{definition}[\DescribeMacro{\DTLinitialhyphen}]%
+\cs{DTLinitialhyphen}
+\end{definition}
+This indicates what to do at a hyphen. This simply does a hyphen
+by default, but can be redefined to do nothing to prevent the
+hyphen appearing in the initials.
+
+\begin{definition}[\DescribeMacro{\DTLafterinitialbeforehyphen}]%
+\cs{DTLafterinitialbeforehyphen}
+\end{definition}
+This indicates what to do between an initial and a hyphen.
+This simply does a full stop by default.
+
+For example
+\begin{verbatim}
+\renewcommand*{\DTLafterinitialbeforehyphen}{}%
+\DTLinitials{Marie-{\'E}lise del~Rosario}
+\end{verbatim}
+produces:
+{\renewcommand*{\DTLafterinitialbeforehyphen}{}\relax
+\DTLinitials{Marie-{\'E}lise del~Rosario}}
+whereas
+\begin{verbatim}
+\renewcommand*{\DTLafterinitialbeforehyphen}{}%
+\renewcommand*{\DTLafterinitials}{}%
+\renewcommand*{\DTLbetweeninitials}{}%
+\renewcommand*{\DTLinitialhyphen}{}%
+\DTLinitials{Marie-{\'E}lise del~Rosario}
+\end{verbatim}
+produces:
+{\renewcommand*{\DTLafterinitialbeforehyphen}{}\relax
+\renewcommand*{\DTLafterinitials}{}\relax
+\renewcommand*{\DTLbetweeninitials}{}\relax
+\renewcommand*{\DTLinitialhyphen}{}\relax
+\DTLinitials{Marie-{\'E}lise del~Rosario}}
+
+\chapter{Databases}
+\label{sec:databases}
+
+The \sty{datatool} package provides a means of creating and
+loading databases. Once a database has been created (or loaded),
+it is possible to iterate through each row of data, to make it
+easier to perform repetitive actions, such as mail merging.
+
+\begin{important}
+Whilst \TeX\ is an excellent typesetting language,
+it is not designed as a database management system, and
+attempting to use it as such is like trying to fasten a screw
+with a knife instead of a screwdriver: it can be done, but requires
+great care and is more time consuming. Version 2.0 of the
+\sty{datatool} package uses a completely different method of storing
+the data to previous versions.\footnote{Thanks to Morten H\o gholm
+for the suggestion.} As a result, the code is much more efficient,
+however, large databases and complex operations will still slow the
+time taken to process your document. Therefore, if you can, it is
+better to do the complex operations using whatever system created
+the data in the first place.
+\end{important}
+
+Some advanced commands for accessing database information are
+described in \autoref{sec:advanced}, but using \TeX\ is nowhere near
+as efficient as, say, using a SQL database, so don't expect too much
+from this package.
+
+\section{Creating a New Database}
+\label{sec:newdb}
+
+\begin{definition}[\DescribeMacro{\DTLnewdb}]%
+\cs{DTLnewdb}\marg{db name}
+\end{definition}
+This command creates a new empty database called \meta{db name}. You
+can test if a database is empty using:
+\begin{definition}[\DescribeMacro{\DTLifdbempty}]%
+\cs{DTLifdbempty}\marg{db name}\marg{true part}\marg{false part}
+\end{definition}
+If the database called \meta{db name} is empty, do \meta{true part},
+otherwise do \meta{false part}.
+
+\begin{definition}[\DescribeMacro{\DTLrowcount}]%
+\cs{DTLrowcount}\marg{db name}
+\end{definition}
+This command displays the number of rows in the database called
+\meta{db name}.
+
+\begin{definition}[\DescribeMacro{\DTLcolumncount}]%
+\cs{DTLcolumncount}\marg{db name}
+\end{definition}
+This command displays the number of columns (or keys) in the
+database called \meta{db name}.
+
+\begin{definition}[\DescribeMacro{\DTLnewrow}]%
+\cs{DTLnewrow}\marg{db name}
+\end{definition}
+This command starts a new row in the database called \meta{db name}.
+This new row becomes the current row when adding new entries.
+
+For example, the following creates an empty database called
+\texttt{mydata}:
+\begin{verbatim}
+\DTLnewdb{mydata}
+\end{verbatim}
+\DTLnewdb{mydata}\relax
+The following tests if the database is empty:
+\begin{verbatim}
+\DTLifdbempty{mydata}{empty}{not empty}!
+\end{verbatim}
+This produces:
+\DTLifdbempty{mydata}{empty}{not empty}!
+
+The following adds an empty row to the database, this is the
+first row of the database:
+\begin{verbatim}
+\DTLnewrow{mydata}
+\end{verbatim}
+\DTLnewrow{mydata}\relax
+Note that even though the only row in the database is currently
+empty, the database is no longer considered to be empty:
+\begin{verbatim}
+\DTLifdbempty{mydata}{empty}{not empty}!
+\end{verbatim}
+This now produces:
+\DTLifdbempty{mydata}{empty}{not empty}! The row count is
+given by
+\begin{verbatim}
+\DTLrowcount{mydata}
+\end{verbatim}
+which produces:
+\DTLrowcount{mydata}. The column count is given by
+\begin{verbatim}
+\DTLcolumncount{mydata}
+\end{verbatim}
+which produces: \DTLcolumncount{mydata}.
+
+\begin{definition}[\DescribeMacro{\DTLnewdbentry}]%
+\cs{DTLnewdbentry}\marg{db name}\marg{key}\marg{value}
+\end{definition}
+This creates a new entry with the identifier \meta{key} whose value
+is \meta{value} and adds it to the last row of the database
+called \meta{db name}. For example:
+\begin{verbatim}
+\DTLnewdbentry{mydata}{Surname}{Smith}
+\DTLnewdbentry{mydata}{FirstName}{John}
+\end{verbatim}
+Adds an entry with identifier \texttt{Surname} and value
+\texttt{Smith} to the last row of the database named
+\texttt{mydata}, and then adds an entry with identifier
+\texttt{FirstName} and value \texttt{John}. Note that the
+key should not contain any fragile commands. It is generally
+best to only use non-active characters in the key.
+
+The value isn't expanded by default, but you can change this
+using the declaration:
+\begin{definition}[\DescribeMacro{\dtlexpandnewvalue}]
+\cs{dtlexpandnewvalue}
+\end{definition}
+This can be localised by placing it in a group, or you can
+switch back using:
+\begin{definition}[\DescribeMacro{\dtlnoexpandnewvalue}]
+\cs{dtlnoexpandnewvalue}
+\end{definition}
+
+\importantpar
+Note that database entries can't contain paragraph
+breaks as many of the macros used by \sty{datatool} are short
+commands. If you do need a paragraph break in an entry, you can
+instead use the command:
+\begin{definition}[\DescribeMacro{\DTLpar}]%
+\cs{DTLpar}
+\end{definition}
+For example:
+\begin{verbatim}
+\DTLnewdbentry{mydata}{Description}{First paragraph.\DTLpar
+Second paragraph.}
+\end{verbatim}
+
+\begin{definition}[\DescribeMacro{\DTLaddentryforrow}]%
+\cs{DTLaddentryforrow}\marg{db}\marg{assign list}\marg{condition}\marg{key}\marg{value}
+\end{definition}
+This adds the entry with the key given by \meta{key} and value
+given by \meta{value} to the first row in the database
+\meta{db} which satisfies the condition given by
+\meta{condition}. The \meta{assign list} argument is the same
+as for \cs{DTLforeach} (described in \autoref{sec:dbforeach})
+and may be used to set the values which are to be tested in
+\meta{condition} (where, again, \meta{condition} is the same
+as for \cs{DTLforeach}). For example:
+\begin{verbatim}
+\DTLaddentryforrow{mydata}{\firstname=FirstName,\surname=Surname}%
+{\DTLiseq{\firstname}{John}\and\DTLiseq{\surname}{Smith}}%
+{Score}{75}
+\end{verbatim}
+Note that unlike \cs{DTLnewdbentry}, the value is always expanded
+when adding an entry using \cs{DTLaddentryforrow}.
+
+\begin{definition}[\DescribeMacro{\DTLsetheader}]%
+\cs{DTLsetheader}\marg{db}\marg{key}\marg{header}
+\end{definition}
+This assigns a header for a given key in the database named
+\meta{db}. This is used by \cs{DTLdisplaydb} and
+\cs{DTLdisplaylongdb} in the header row (see
+\autoref{sec:displaydb}). If you don't assign
+a header, the header will be given by the key.
+For example:
+\begin{verbatim}
+\DTLsetheader{mydata}{Price}{Price (\$)}
+\end{verbatim}
+
+\section{Loading a Database from an External ASCII File}
+\label{sec:loaddb}
+
+Instead of using the commands described in \autoref{sec:newdb}
+to create a new database, you can load a database from an
+external ASCII file using:
+\begin{definition}[\DescribeMacro{\DTLloaddb}]%
+\cs{DTLloaddb}\oarg{options}\marg{db name}\marg{filename}
+\end{definition}
+\begin{important}
+Make sure your document uses the same encoding as \meta{filename}.
+For example, if \meta{filename} is UTF-8, then include the following
+in your document:
+\begin{verbatim}
+\usepackage[utf8]{inputenc}
+\end{verbatim}
+\end{important}
+This creates a new database called \meta{db name}, and fills
+it with the entries given in the file \meta{filename}.
+The filename may have a header row at the start of the file,
+which provides the \meta{key} when creating a new database entry
+using \ics{DTLnewdbentry}. The optional argument \meta{options}
+is a key=value list of options. Available options are:
+\begin{description}
+\item[\csopt{DTLloaddb}{noheader}] This is a boolean value and
+indicates if the file does not contain a header. If no value is
+supplied, "true" is assumed (i.e.\ the file doesn't contain a header
+row). If this option is omitted, it is assumed that the file
+contains a header row.
+
+\item[\csopt{DTLloaddb}{keys}] This is a comma-separated list of
+keys to use, where the keys are listed in the same order as the
+columns. If the file has a header, these keys will override the
+values given in the header row. If the file has no header row and no
+keys are supplied in \meta{options}, then the keys will be given by
+\cs{dtldefaultkey}\meta{n}, where \meta{n} is the column number and
+\DescribeMacro{\dtldefaultkey}\cs{dtldefaultkey} defaults to
+``\dtldefaultkey''. Note that the list of keys must be delimited by
+braces since they contain commas. For example:
+\begin{verbatim}
+\DTLloaddb[noheader,keys={Temperature,Time,T2G}]{data}{data.csv}
+\end{verbatim}
+
+\item[\csopt{DTLloaddb}{headers}] This is a comma-separated list of
+headers. If not supplied, the header will be the same as that given
+in the header row, or the key if there is no header row. Note that
+the list of headers must be delimited by braces since they contain
+commas. For example:
+\begin{verbatim}
+\DTLloaddb[noheader,keys={Temperature,Time,T2G},%
+headers={\shortstack{Incubation\\Temperature},%
+\shortstack{Incubation\\Time},%
+\shortstack{Time to\\Growth}}]{data}{data.csv}
+\end{verbatim}
+
+\item[\csopt{DTLloaddb}{omitlines}]
+This should be a non-negative integer that specifies how many rows
+to skip at the start of the file.
+\end{description}
+
+By default, the entries in the database
+must be separated by a comma, and optionally delimited by the
+double quote character (\verb|"|). The separator can be changed
+to a tab separator using the command:
+\begin{definition}[\DescribeMacro{\DTLsettabseparator}]%
+\cs{DTLsettabseparator}
+\end{definition}
+To set the separator to a character other than a tab, you need to use
+\begin{definition}[\DescribeMacro{\DTLsetseparator}]%
+\cs{DTLsetseparator}\marg{character}
+\end{definition}
+The delimiter can be changed using
+\begin{definition}[\DescribeMacro{\DTLsetdelimiter}]%
+\cs{DTLsetdelimiter}\marg{character}
+\end{definition}
+
+For example, suppose you have a file called \texttt{mydata.csv}
+which contains the following:
+\begin{verbatim}
+FirstName,Surname,Score
+John,"Smith, Jr",68
+Jane,Brown,75
+Andy,Brown,42
+Z\"oe,Adams,52
+\end{verbatim}
+then
+\begin{verbatim}
+\DTLloaddb{mydata}{mydata.csv}
+\end{verbatim}
+is equivalent to:
+\begin{verbatim}
+\DTLnewdb{mydata}
+\DTLnewrow{mydata}%
+\DTLnewdbentry{mydata}{FirstName}{John}%
+\DTLnewdbentry{mydata}{Surname}{Smith, Jr}%
+\DTLnewdbentry{mydata}{Score}{68}%
+\DTLnewrow{mydata}%
+\DTLnewdbentry{mydata}{FirstName}{Jane}%
+\DTLnewdbentry{mydata}{Surname}{Brown}%
+\DTLnewdbentry{mydata}{Score}{75}%
+\DTLnewrow{mydata}%
+\DTLnewdbentry{mydata}{FirstName}{Andy}%
+\DTLnewdbentry{mydata}{Surname}{Brown}%
+\DTLnewdbentry{mydata}{Score}{42}%
+\DTLnewrow{mydata}%
+\DTLnewdbentry{mydata}{FirstName}{Z\"oe}%
+\DTLnewdbentry{mydata}{Score}{52}%
+\DTLnewdbentry{mydata}{Surname}{Adams}%
+\end{verbatim}
+Note that the entry \texttt{Smith, Jr} had to be delimited in
+\texttt{mydata.csv} using the double quote character since it
+contained a comma which is used as the separator.
+The percent symbol \% can be used as a comment character within the
+file.
+
+The file used in the above example contained a \LaTeX\ command,
+namely \verb|\"|. When using \ics{DTLloaddb} all the special
+characters that appear in the command retain their \LaTeX\ meaning
+when the file is loaded. It is likely however that the data file
+may have been created by another application that is not \TeX-aware,
+such as a spreadsheet application. For example, suppose you
+have a file called, say, \texttt{products.csv} which looks
+like:
+\begin{verbatim}
+Product,Cost
+Fruit & Veg,$1.25
+Stationary,$0.80
+\end{verbatim}
+This file contains two of \TeX's special characters, namely
+"&" and \verb|$|. In this case, if you try to load the file
+using \ics{DTLloaddb}, you will encounter errors. Instead you
+can use:
+\begin{definition}[\DescribeMacro{\DTLloadrawdb}]%
+\cs{DTLloadrawdb}\oarg{options}\marg{db name}\marg{filename}
+\end{definition}
+This is the same as \ics{DTLloaddb} except that it maps nine of
+the ten special characters onto commands which produce that
+symbol. The only character that retains its active state is the
+backslash character, so you will still need to check the file
+for backslash characters. The mappings used are listed in
+\autoref{tab:rawmappings}. So using the file \texttt{products.csv},
+as described above,
+\begin{verbatim}
+\DTLloadrawdb{mydata}{products.csv}
+\end{verbatim}
+is equivalent to:
+\begin{verbatim}
+\DTLnewdb{mydata}
+\DTLnewrow{mydata}%
+\DTLnewdbentry{mydata}{Product}{Fruit \& Veg}%
+\DTLnewdbentry{mydata}{Cost}{\$1.25}%
+\DTLnewrow{mydata}%
+\DTLnewdbentry{mydata}{Product}{Stationary}%
+\DTLnewdbentry{mydata}{Cost}{\$0.80}%
+\end{verbatim}
+
+\begin{table}[htbp]
+\caption[Special character mappings used by
+\cs{DTLloadrawdb}]{Special character mappings used by
+\cs{DTLloadrawdb} (note that the backslash retains its active state)}
+\label{tab:rawmappings}
+\centering
+\begin{tabular}{cl}
+Character & Mapping\\
+\verb|%| & \verb|\%|\\
+\verb|$| & \verb|\$|\\
+\verb|&| & \verb|\&|\\
+\verb|#| & \verb|\#|\\
+\verb|_| & \verb|\_|\\
+\verb|{| & \verb|\{|\\
+\verb|}| & \verb|\}|\\
+\verb|~| & \cs{textasciitilde}\\
+\verb|^| & \cs{textasciicircum}
+\end{tabular}
+\end{table}
+
+It may be that there are other characters that require mapping.
+For example, the file \texttt{products.csv} may instead look like:\par
+\vskip\baselineskip
+\begin{ttfamily}\obeylines\setlength{\parindent}{0pt}
+Product,Cost
+Fruit \& Veg,\pounds1.25
+Stationary,\pounds0.80
+\end{ttfamily}
+\vskip\baselineskip
+The pound character is not an internationally standard keyboard
+character, and does not generally achieve the desired effect when used
+in a \LaTeX\ document. It may therefore be necessary to convert
+this symbol to an appropriate control sequence. This can be done
+using the command:
+\begin{definition}[\DescribeMacro{\DTLrawmap}]%
+\cs{DTLrawmap}\marg{string}\marg{replacement}
+\end{definition}
+For example:\par
+\vskip\baselineskip
+\begin{ttfamily}\obeylines\setlength{\parindent}{0pt}
+\cs{DTLrawmap}\char`\{\pounds\char`\}\char`\{\cs{pounds}\char`\}
+\end{ttfamily}
+\vskip\baselineskip\noindent
+will replace all occurrences\footnote{when it is loaded into the
+\LaTeX\ database, it does not modify the data file!}\ of
+\texttt{\pounds} with \cs{pounds}. Naturally, the mappings must be
+set \emph{prior} to loading the data with \cs{DTLloadrawdb}.
+
+\begin{important}
+Note that the warning in the previous section about no
+paragraph breaks in an entry also applies to entries loaded from a
+database. If you do need a paragraph break, use \ics{DTLpar} instead
+of \cs{par}, but remember that each row of data in an external data
+file must not have a line break.
+\end{important}
+
+\section{Displaying the Contents of a Database}
+\label{sec:displaydb}
+
+Once you have created a database, either loading it from an
+external file, as described in \autoref{sec:loaddb}, or using the
+commands described in \autoref{sec:newdb}, you can display the
+entire database in a \env{tabular} or \env{longtable}
+environment.
+
+\begin{definition}[\DescribeMacro{\DTLdisplaydb}]%
+\cs{DTLdisplaydb}\oarg{omit list}\marg{db}
+\end{definition}
+This displays the database given by \meta{db} in a \env{tabular}
+environment. The first row displays the headers for the database
+in bold, the subsequent rows display the values for each key
+in each row of the database. The optional argument \meta{omit list}
+is a comma-separated list of column keys to omit. (All columns displayed by default.)
+
+\begin{definition}[\DescribeMacro{\DTLdisplaylongdb}]%
+\cs{DTLdisplaylongdb}\oarg{options}\marg{db}
+\end{definition}
+This is like \cs{DTLdisplaydb} except that it uses the
+\env{longtable} environment instead of the \env{tabular}
+environment. Note that if you use this command, you must load the
+\sty{longtable} package, as it is not loaded by \sty{datatool}.
+The optional argument \meta{options} is a comma-separated list
+of key=value pairs. The following keys are available:
+\begin{description}
+\item[caption] The caption for the \env{longtable}.
+
+\item[contcaption] The continuation caption.
+
+\item[shortcaption] The caption to be used in the list of figures.
+
+\item[label] The label for this table.
+
+\item[omit] Comma-separated list of column keys to omit.
+
+\item[foot] The \env{longtable}'s foot.
+
+\item[lastfoot] The foot for the last page of the \env{longtable}.
+\end{description}
+For example, suppose I have a database called "iris", then I can
+display the contents in a \env{longtable} using:
+\begin{verbatim}
+\DTLdisplaylongdb[%
+caption={Iris Data},%
+label={tab:iris},%
+contcaption={Iris Data (continued)},%
+foot={\em Continued overleaf},%
+lastfoot={}%
+]{iris}
+\end{verbatim}
+I can then reference the table using \verb|\ref{tab:iris}|.
+
+See the \sty{longtable} documentation for details on how to
+change the \env{longtable} settings, such as how to change the
+table so that it is left aligned instead of centred on the page.
+
+Note that if you want more control over the way the data is
+displayed, for example, you want to filter rows or columns, you will
+need to use \cs{DTLforeach}, described in \autoref{sec:dbforeach}.
+
+\begin{example}{Displaying the Contents of a Database}{ex:displaydb}
+Suppose I have a file called \texttt{t2g.csv} that contains the
+following:
+\begin{verbatim}
+40,120,40
+40,90,60
+35,180,20
+55,190,40
+\end{verbatim}
+This represents time to growth data, where the first column
+is the incubation temperature, the second column is the incubation
+time and the third column is the time to growth. This file has no
+header row, so when it is loaded, the \csopt{DTLloaddb}{noheaders}
+option is required. Note that \cs{DTLdisplaydb} only puts the data
+in a \env{tabular} environment, so \cs{DTLdisplaydb} needs to be
+put in a \env{table} environment with a caption to make it a float.
+
+First load the data base, setting the keys and headers:
+\begin{verbatim}
+\DTLloaddb[noheader,%
+keys={Temperature,Time,T2G},%
+headers={\shortstack{Incubation\\Temperature},%
+\shortstack{Incubation\\Time},\shortstack{Time to\\Growth}}%
+]{t2g}{t2g.csv}
+\end{verbatim}
+\DTLnewdb{t2g}\relax
+\DTLnewrow*{t2g}\relax
+\DTLnewdbentry*{t2g}{Temperature}{40}\relax
+\DTLnewdbentry*{t2g}{Time}{120}\relax
+\DTLnewdbentry*{t2g}{T2G}{40}\relax
+\DTLnewrow*{t2g}\relax
+\DTLnewdbentry*{t2g}{Temperature}{40}\relax
+\DTLnewdbentry*{t2g}{Time}{90}\relax
+\DTLnewdbentry*{t2g}{T2G}{60}\relax
+\DTLnewrow*{t2g}\relax
+\DTLnewdbentry*{t2g}{Temperature}{35}\relax
+\DTLnewdbentry*{t2g}{Time}{180}\relax
+\DTLnewdbentry*{t2g}{T2G}{20}\relax
+\DTLnewrow*{t2g}\relax
+\DTLnewdbentry*{t2g}{Temperature}{55}\relax
+\DTLnewdbentry*{t2g}{Time}{190}\relax
+\DTLnewdbentry*{t2g}{T2G}{40}\relax
+\DTLsetheader*{t2g}{Temperature}{\shortstack{Incubation\\Temperature}}\relax
+\DTLsetheader*{t2g}{Time}{\shortstack {Incubation\\Time}}\relax
+\DTLsetheader*{t2g}{T2G}{\shortstack {Time to\\Growth}}\relax
+
+Now display the data in a table:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Time to Growth Data}
+\centering
+\DTLdisplaydb{t2g}
+\end{table}
+\end{verbatim}
+The result is shown in \autoref{tab:t2g}.
+\begin{table}[htbp]
+\caption{Time to Growth Data}
+\label{tab:t2g}
+\centering
+\DTLdisplaydb{t2g}
+\end{table}
+\end{example}
+
+Each column in the database has an associated data type which
+indicates what type of data is in that column. This may be one
+of: string, integer, real number or currency. If a column contains
+more than one type, the data type is determined as follows:
+\begin{itemize}
+\item If the column contains at least one string, then the column
+data type is string.
+
+\item If the column doesn't contain a string, but contains at least
+one currency, then the column data type is currency.
+
+\item If the column contains only real numbers and integers, the
+column data type is real number.
+
+\item The column data type is integer if the column only
+contains integers.
+\end{itemize}
+The column data type is updated whenever a new entry is added
+to the database. Note that the column data type is not adjusted
+when an entry is removed from the database.
+
+The column alignments used by \cs{DTLdisplaydb} are given by:
+\begin{definition}[\DescribeMacro{\dtlstringalign}]%
+\cs{dtlstringalign}
+\end{definition}\noindent
+The string alignment defaults to \texttt{l} (left aligned).
+
+\begin{definition}[\DescribeMacro{\dtlintalign}]%
+\cs{dtlintalign}
+\end{definition}\noindent
+The integer alignment defaults to \texttt{r} (right aligned).
+
+\begin{definition}[\DescribeMacro{\dtlrealalign}]%
+\cs{dtlrealalign}
+\end{definition}\noindent
+The alignment for real numbers defaults to \texttt{r} (right
+aligned).
+
+\begin{definition}[\DescribeMacro{\dtlcurrencyalign}]%
+\cs{dtlcurrencyalign}
+\end{definition}\noindent
+The currency alignment defaults to \texttt{r} (right aligned).
+
+You can redefine these to change the column alignments. For
+example, if you want columns containing strings to have the
+alignment "p{2in}", then you can redefine \cs{dtlstringalign} as
+follows:
+\begin{verbatim}
+\renewcommand{\dtlstringalign}{p{2in}}
+\end{verbatim}
+
+\begin{important}
+You can't use \sty{siunitx}'s "S" column alignment
+with either \cs{DTLdisplaydb} or \cs{DTLdisplaylongdb}. Instead, you
+will need to use \cs{DTLforeach}. The \sty{siunitx} documentation
+provides an example.
+\end{important}
+
+In addition to the \cs{dtl}\meta{type}"align" commands above, you
+can also modify the \env{tabular} column styles by redefining
+\DescribeMacro{\dtlbeforecols}\cs{dtlbeforecols},
+\DescribeMacro{\dtlbetweencols}\cs{dtlbetweencols} and
+\DescribeMacro{\dtlaftercols}\cs{dtlaftercols}. For example, to
+place a vertical line before the start of the first column and
+after the last column, do:
+\begin{verbatim}
+\renewcommand{\dtlbeforecols}{|}
+\renewcommand{\dtlaftercols}{|}
+\end{verbatim}
+If you additionally want vertical lines between columns, do:
+\begin{verbatim}
+\renewcommand{\dtlbetweencols}{|}
+\end{verbatim}
+
+Limited modifications can be made to the way the data is displayed
+with \cs{DTLdisplaydb} and \cs{DTLdisplaylongdb}.
+The commands controlling the formatting are described below.
+If a more complicated layout is required, you will need to use
+\cs{DTLforeach} described in \autoref{sec:dbforeach}.
+
+\begin{definition}[\DescribeMacro{\dtlheaderformat}]%
+\cs{dtlheaderformat}\marg{header}
+\end{definition}
+This indicates how to format a column header, where the header is
+given by \meta{header}. This defaults to
+\cs{null}\cs{hfil}\cs{textbf}\marg{header}\cs{hfil}\cs{null}.
+
+\begin{definition}[\DescribeMacro{\dtlstringformat}]%
+\cs{dtlstringformat}\marg{text}
+\end{definition}
+This specifies how to format each entry in the columns that contain
+strings. This defaults to just displaying \meta{text}.
+
+\begin{definition}[\DescribeMacro{\dtlintformat}]%
+\cs{dtlintformat}\marg{text}
+\end{definition}
+This specifies how to format each entry in the columns that contain
+only integers. This defaults to just displaying \meta{text}.
+
+\begin{definition}[\DescribeMacro{\dtlrealformat}]%
+\cs{dtlrealformat}\marg{text}
+\end{definition}
+This specifies how to format each entry in the columns that contain
+only real numbers or a mixture of real numbers and integers. This
+defaults to just displaying \meta{text}.
+
+\begin{definition}[\DescribeMacro{\dtlcurrencyformat}]%
+\cs{dtlcurrencyformat}\marg{text}
+\end{definition}
+This specifies how to format each entry in the columns that contain
+only currency or currency mixed with real numbers and/or integers.
+This defaults to just displaying \meta{text}.
+
+\begin{definition}[\DescribeMacro{\dtldisplaystarttab}]%
+\cs{dtldisplaystarttab}
+\end{definition}
+This is a hook to add something at the beginning of the
+\env{tabular} environment. This defaults to nothing.
+
+\begin{definition}[\DescribeMacro{\dtldisplayendtab}]%
+\cs{dtldisplayendtab}
+\end{definition}
+This is a hook to add something at the end of the
+\env{tabular} environment. This defaults to nothing.
+
+\begin{definition}[\DescribeMacro{\dtldisplayafterhead}]%
+\cs{dtldisplayafterhead}
+\end{definition}
+This is a hook to add something after the header row, before
+the first row of data. This defaults to nothing.
+
+\begin{definition}[\DescribeMacro{\dtldisplaystartrow}]%
+\cs{dtldisplaystartrow}
+\end{definition}
+This is a hook to add something at the start of each row, but
+not including the header row or the first row of data. This
+defaults to nothing.
+
+If you want to use the \sty{booktabs} package, you can redefine the
+above three commands to use \ics{toprule}, \ics{midrule} and
+\ics{bottomrule}:
+\begin{verbatim}
+\renewcommand{\dtldisplaystarttab}{\toprule}
+\renewcommand{\dtldisplayafterhead}{\midrule}
+\renewcommand{\dtldisplayendtab}{\\\bottomrule}
+\end{verbatim}
+
+\begin{example}{Balance Sheet}{ex:balance}
+Suppose you have a file called "balance.csv" that contains
+the following:
+\begin{verbatim}
+Description,In,Out,Balance
+Travel expenses,,230,-230
+Conference fees,,400,-630
+Grant,700,,70
+Train fare,,70,0
+\end{verbatim}
+\DTLnewdb{balance}\relax
+\DTLnewrow{balance}\relax
+\DTLnewdbentry{balance}{Description}{Travel expenses}\relax
+\DTLnewdbentry{balance}{In}{}\relax
+\DTLnewdbentry{balance}{Out}{230.00}\relax
+\DTLnewdbentry{balance}{Balance}{-230.00}\relax
+\DTLnewrow{balance}\relax
+\DTLnewdbentry{balance}{Description}{Conference fees}\relax
+\DTLnewdbentry{balance}{In}{}\relax
+\DTLnewdbentry{balance}{Out}{400.00}\relax
+\DTLnewdbentry{balance}{Balance}{-630.00}\relax
+\DTLnewrow{balance}\relax
+\DTLnewdbentry{balance}{Description}{Grant}\relax
+\DTLnewdbentry{balance}{In}{700.00}\relax
+\DTLnewdbentry{balance}{Out}{}\relax
+\DTLnewdbentry{balance}{Balance}{70.00}\relax
+\DTLnewrow{balance}\relax
+\DTLnewdbentry{balance}{Description}{Train Fare}\relax
+\DTLnewdbentry{balance}{In}{}\relax
+\DTLnewdbentry{balance}{Out}{70.00}\relax
+\DTLnewdbentry{balance}{Balance}{0.00}\relax
+\DTLsetheader{balance}{In}{In (\pounds)}\relax
+\DTLsetheader{balance}{Out}{Out (\pounds)}\relax
+\DTLsetheader{balance}{Balance}{Balance (\pounds)}\relax
+The data can be loaded using:
+\begin{verbatim}
+\DTLloaddb[headers={Description,In (\pounds),Out (\pounds),Balance
+(\pounds)}]{balance}{balance.csv}
+\end{verbatim}
+
+Suppose I want negative numbers to be displayed in red. I can do
+this by redefining \cs{dtlrealformat} to check if the entry
+is negative. For example:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Balance Sheet}
+\renewcommand*{\dtlrealformat}[1]{\DTLiflt{#1}{0}{\color{red}}{}#1}
+\centering
+\DTLdisplaydb{balance}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:balance}.
+\begin{table}[htbp]
+\caption{Balance Sheet}
+\label{tab:balance}
+\renewcommand*{\dtlrealformat}[1]{\DTLiflt{#1}{0}{\color{red}}{}#1}
+\centering
+\DTLdisplaydb{balance}
+\end{table}
+\end{example}
+
+\section{Iterating Through a Database}
+\label{sec:dbforeach}
+
+Once you have created a database, either loading it from an
+external file, as described in \autoref{sec:loaddb}, or using the
+commands described in \autoref{sec:newdb}, you can then iterate
+through each row of the database and access elements in that row.
+
+\begin{definition}[\DescribeMacro{\DTLforeach}]%
+\cs{DTLforeach}\oarg{condition}\marg{db name}\marg{assign list}\marg{text}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLforeach*}]%
+\cs{DTLforeach*}\oarg{condition}\marg{db name}\marg{assign list}\marg{text}
+\end{definition}
+This will iterate through each row of the database called
+\meta{db name}, applying \meta{text} to each row of the database
+where \meta{condition} is met. The argument \meta{assign list} is a
+comma separated list of \meta{cmd}"="\meta{key} pairs. At the
+start of each row, each command \meta{cmd} in \meta{assign list}
+will be set to the value of the entry given by \meta{key}.
+These commands may then be used in \meta{text}.
+
+\begin{important}
+Note that this assignment is done globally to ensure
+that \cs{DLTforeach} works correctly in a \env{tabular} environment.
+Since you may want to use the same set of commands in a later
+\cs{DTLforeach}, the commands are not checked to determine if they
+already exist. It is therefore important that you check you are not
+using an existing command whose value should not be changed.
+\end{important}
+
+The optional argument \meta{condition} is a condition in the
+form allowed by \cs{ifthenelse}. This includes the commands
+provided by the \sty{ifthen} package (such as \cs{not}, \cs{and},
+\cs{or}), as well as the commands
+described in \autoref{sec:ifthen}. The default value of
+\meta{condition} is "\boolean{true}".
+
+The starred version \cs{DTLforeach*} is a read-only version.
+If you want to modify the database using any of the commands
+described in \autoref{sec:editdb}, you must use the unstarred
+version. The starred version is faster.
+
+\begin{important}
+As is generally the case with command arguments, verbatim (for
+example, using \cs{verb} or the \env{verbatim} environment) can't be used in any of
+the arguments of \cs{DTLforeach}, specifically verbatim can't be
+used in \meta{text}.
+\end{important}
+
+There are also environment alternatives:
+\begin{definition}[\DescribeEnv{DTLenvforeach}]%
+\cs{begin}\{DTLenvforeach\}\oarg{condition}\marg{db name}\marg{assign list}
+\end{definition}
+\begin{definition}[\DescribeEnv{DTLenvforeach*}]%
+\cs{begin}\{DTLenvforeach*\}\oarg{condition}\marg{db name}\marg{assign list}
+\end{definition}
+However, note that since these environments gather the contents of
+their body, they also suffer from the above limitation.
+\begin{important}
+Verbatim can't be used in the body of \env{DTLenvforeach} or
+\env{DTLenvforeach*}.
+\end{important}
+
+\begin{example}{Student scores}{ex:scores}
+Suppose you have a data file called \texttt{studentscores.csv} that
+contains the following:
+\begin{verbatim}
+FirstName,Surname,StudentNo,Score
+John,"Smith, Jr",102689,68
+Jane,Brown,102647,75
+Andy,Brown,103569,42
+Z\"oe,Adams,105987,52
+Roger,Brady,106872,58
+Clare,Verdon,104356,45
+\end{verbatim}
+\DTLnewdb{scores}\relax
+\DTLnewrow{scores}\relax
+\DTLnewdbentry{scores}{FirstName}{John}\relax
+\DTLnewdbentry{scores}{Surname}{Smith, Jr}\relax
+\DTLnewdbentry{scores}{StudentNo}{102689}\relax
+\DTLnewdbentry{scores}{Score}{68}\relax
+\DTLnewrow{scores}\relax
+\DTLnewdbentry{scores}{FirstName}{Jane}\relax
+\DTLnewdbentry{scores}{Surname}{Brown}\relax
+\DTLnewdbentry{scores}{StudentNo}{102647}\relax
+\DTLnewdbentry{scores}{Score}{75}\relax
+\DTLnewrow{scores}\relax
+\DTLnewdbentry{scores}{FirstName}{Andy}\relax
+\DTLnewdbentry{scores}{Surname}{Brown}\relax
+\DTLnewdbentry{scores}{StudentNo}{103569}\relax
+\DTLnewdbentry{scores}{Score}{42}\relax
+\DTLnewrow{scores}\relax
+\DTLnewdbentry{scores}{FirstName}{Z\"oe}\relax
+\DTLnewdbentry{scores}{Score}{52}\relax
+\DTLnewdbentry{scores}{StudentNo}{105987}\relax
+\DTLnewdbentry{scores}{Surname}{Adams}\relax
+\DTLnewrow{scores}\relax
+\DTLnewdbentry{scores}{FirstName}{Roger}\relax
+\DTLnewdbentry{scores}{Score}{58}\relax
+\DTLnewdbentry{scores}{StudentNo}{106872}\relax
+\DTLnewdbentry{scores}{Surname}{Brady}\relax
+\DTLnewrow{scores}\relax
+\DTLnewdbentry{scores}{FirstName}{Clare}\relax
+\DTLnewdbentry{scores}{Score}{45}\relax
+\DTLnewdbentry{scores}{StudentNo}{104356}\relax
+\DTLnewdbentry{scores}{Surname}{Verdon}\relax
+and you load the data into a database called "scores" using:
+\begin{verbatim}
+\DTLloaddb{scores}{studentscores.csv}
+\end{verbatim}
+you can then display the database in a table as follows:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student scores}
+\centering
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)%
+\DTLforeach{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\
+\firstname & \surname & \score}
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:scores}. (Note that since I didn't
+need the student registration number, I didn't bother to
+assign a command to the key "StudentNo".)
+
+\begin{table}[htbp]
+\caption[Student scores (displaying a database in a
+table)]{Student scores}\label{tab:scores}
+\centering
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)\relax
+\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\
+\firstname & \surname & \score}
+\end{tabular}
+\end{table}
+\end{example}
+
+The macro \ics{DTLforeach} may be nested up to three times. Each
+level uses the corresponding counters:
+\desctr{DTLrowi},
+\desctr{DTLrowii} and
+\desctr{DTLrowiii} which keep track of
+the current row.
+
+\begin{important}
+Note that these counters are only incremented when
+\meta{condition} is satisfied, therefore they will not have the
+correct value in \meta{condition}. These counters are incremented
+using \cs{refstepcounter} before the start of \meta{text}, so they
+may be referenced using \cs{label}, however remember that \cs{label}
+references the last counter to be incremented using
+\cs{refstepcounter} \emph{in the current scope}. The \cs{label}
+should therefore be the first command in \meta{text} to ensure that
+it references the current row counter.
+\end{important}
+
+\begin{definition}[\DescribeMacro{\DTLcurrentindex}]%
+\cs{DTLcurrentindex}
+\end{definition}
+At the start of each iteration in \cs{DTLforeach},
+\cs{DTLcurrentindex} is set to the arabic value of the current row
+counter. Note that this is only set after the condition is tested,
+so it should only be used in the body of \cs{DTLforeach} not in
+the condition. It is also only set locally, so if you use it in
+a tabular environment, it can only be used before the first instance
+of \verb|\\| or \verb|&| in the current iteration.
+
+Within the body of \ics{DTLforeach} (i.e.\ within \meta{text})
+the following conditionals may be used:
+\begin{definition}[\DescribeMacro{\DTLiffirstrow}]%
+\cs{DTLiffirstrow}\marg{true part}\marg{false part}
+\end{definition}
+If the current row is the first row, then do \meta{true part},
+otherwise do \meta{false part}.
+
+\begin{definition}[\DescribeMacro{\DTLifoddrow}]%
+\cs{DTLifoddrow}\marg{true part}\marg{false part}
+\end{definition}
+If the current row number is an odd number, then do \meta{true part},
+otherwise do \meta{false part}.
+
+\begin{definition}[\DescribeMacro{\DTLsavelastrowcount}]%
+\cs{DTLsavelastrowcount}\marg{cmd}
+\end{definition}
+This command will store the value of the row counter used in
+the last occurrence of \ics{DTLforeach} in the control sequence
+\meta{cmd}.
+
+\begin{definition}[\DescribeMacro{\DTLforeachkeyinrow}]%
+\cs{DTLforeachkeyinrow}\marg{cmd}\marg{text}
+\end{definition}
+This iterates through each key in the current row, (globally) assigns
+\meta{cmd} to the value of that key, and does \meta{text}
+(\meta{cmd} must be a control sequence and may be used in
+\meta{text}). This command may only be used in the body of
+\cs{DTLforeach}. At each iteration, \cs{DTLforeachkeyinrow} sets
+\cs{dtlkey} to the current key, \cs{dtlcol} to the current column
+index, \cs{dtltype} to the data type for the current column,
+and \cs{dtlheader} to the header for the current column. Note that
+\cs{dtltype} corresponds to the column type but if the entries in
+the column have mixed types, it may not correspond to the type
+of the current entry.
+
+\begin{definition}[\DescribeMacro{\dtlbreak}]%
+\cs{dtlbreak}
+\end{definition}
+You can break out of most of the loops provided by \sty{datatool}
+using \cs{dtlbreak}. Note, however, that it doesn't break the loop
+until the end of the current iteration. There is no provision for
+a "next" or "continue" style command.
+
+Additional loop commands provided by \sty{datatool} are
+described in the documented code (datatool.pdf).
+
+\begin{example}{Student Scores---Labelling}{ex:label}
+In the previous example, the student scores, stored in the
+database "scores" were placed in a table. In this example the
+table will be modified slightly to number each student according
+to the row. Suppose I also want to identify which row Jane Brown
+is in, and reference it in the text. The easiest way to do this
+is to construct a label on each row which uniquely identifies
+that student. The label can't simply be constructed from the
+surname, as there are two students with the same surname. In order
+to create a unique label, I can either construct a label from
+both the surname and the first name, or I can use the student's
+registration number, or I can use the student's score, since all
+the scores are unique. The former method will cause a problem since
+one of the names (Z\"oe) contains an accent command. Although
+the registration numbers are all unique, they are not particularly
+memorable, so I shall instead use the scores.
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student scores}
+\centering
+\begin{tabular}{cllc}
+\bfseries Row &
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)%
+\DTLforeach*{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\label{row:\score}\\\theDTLrowi &
+\firstname & \surname & \score}%
+\end{tabular}
+\end{table}
+
+Jane Brown scored the highest (75\%), her score can be seen on
+row~\ref{row:75}.
+\end{verbatim}
+This produces \autoref{tab:scoreslab} and the following text:
+Jane Brown scored the highest (75\%), her score can be seen on
+row~\ref*{row:75}.
+
+Notes:
+\begin{itemize}
+\item the \cs{label} command is placed before
+"\\" to ensure that it is in the same scope as the command
+"\refstepcounter{DTLrowi}".
+
+\item To avoid unwanted spaces the end of line characters are
+commented out with the percent (\texttt{\%}) symbol.
+\end{itemize}
+
+\begin{table}[htbp]
+\caption[Student scores (labelling rows)]{Student
+scores}\label{tab:scoreslab}
+\centering
+\begin{tabular}{cllc}
+\bfseries Row &
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)\relax
+\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\label{row:\score}\\\theDTLrowi &
+\firstname & \surname & \score}\relax
+\end{tabular}
+\end{table}
+\end{example}
+
+\begin{example}{Filtering Rows}{ex:filter}
+As mentioned earlier, the optional argument \meta{condition} of
+\ics{DTLforeach} provides a means to exclude certain rows.
+This example uses the database defined in \autoref{ex:scores},
+but only displays the information for students whose marks are
+above 60. At the end of the table, \cs{DTLsavelastrowcount}
+is used to store the number of rows in the table. (Note that
+\cs{DTLsavelastrowcount} is outside of \ics{DTLforeach}.)
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Top student scores}
+\centering
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)%
+\DTLforeach*[\DTLisgt{\score}{60}]{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\
+\firstname & \surname & \score}
+\end{tabular}
+
+\DTLsavelastrowcount{\n}%
+\n\ students scored above 60\%.
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:topscores}. Note that in this example,
+I could have specified the condition as "\score>60" since all
+the scores are integers, however, as it's possible that an entry
+may feasibly have a decimal score I have used \ics{DTLisgt} instead.
+
+\begin{table}[htbp]
+\caption[Top student scores (filtering rows using
+\cs{DTLisgt})]{Top student scores}\label{tab:topscores}
+\centering
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)\relax
+\DTLforeach*[\DTLisgt{\score}{60}]{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\
+\firstname & \surname & \score}
+\end{tabular}
+
+\DTLsavelastrowcount{\n}\relax
+\n\ students scored above 60\%.
+\end{table}
+
+Suppose now, I only want to display the scores for students whose
+surname begins with `B'. I can do this as follows:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student scores (B)}
+\centering
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)%
+\DTLforeach*[\DTLisopenbetween{\surname}{B}{C}]{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\
+\firstname & \surname & \score}
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:Bscores}.
+
+\begin{table}[htbp]
+\caption[Student scores (B) --- filtering rows using \newline
+\cs{DTLisopenbetween}]{Student scores (B)}\label{tab:Bscores}
+\centering
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)\relax
+\DTLforeach*[\DTLisopenbetween{\surname}{B}{C}]{scores}
+{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\
+\firstname & \surname & \score}
+\end{tabular}
+\end{table}
+
+\end{example}
+
+\begin{example}{Breaking Out of a Loop}{ex:dtlbreak}
+Suppose I only want to display the first three rows of a database.
+I could do:\footnote{Recall that \ctr{DTLrowi} is incremented
+after the condition is tested, so it will be out by 1 when the
+condition is tested which is why \texttt{<3} is used instead of
+\texttt{<4}.}
+\begin{verbatim}
+\DTLforeach*[\value{DTLrowi}<3]{scores}%
+{\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\\firstname & \surname & \score
+}
+\end{verbatim}
+However, this isn't very efficient, as it still has to iterate
+through the entire database, checking if the condition is met. If
+the database has over 100 entries, this will slow the time taken
+to create the table. It would therefore be much more efficient
+to break out of the loop when row count exceeds 3:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{First Three Rows}
+\centering
+\begin{tabular}{llr}
+\bfseries First Name & \bfseries Surname & \bfseries Score (\%)%
+\DTLforeach*{scores}%
+{\firstname=FirstName,\surname=Surname,\score=Score}{%
+\ifthenelse{\DTLcurrentindex=3}{\dtlbreak}{}%
+\\\firstname & \surname & \score
+}%
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:dtlbreak}. Note that the loop is not
+broken until the end of the current iteration, so even though
+\cs{dtlbreak} occurs at the start of the third row, the loop isn't
+finished until the third row is completed. (Recall that
+\cs{DTLcurrentindex} must be used before the first instance of
+\verb|\\| or \verb|&|.) Alternatively, you can use
+\ctr{DTLrowi} instead:
+\begin{verbatim}
+\DTLforeach{scores}%
+{\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\\firstname & \surname & \score
+\ifthenelse{\value{DTLrowi}=3}{\dtlbreak}{}%
+}%
+\end{verbatim}
+
+\begin{table}[htbp]
+\caption{First Three Rows}
+\label{tab:dtlbreak}%
+\centering
+\begin{tabular}{llr}
+\bfseries First Name & \bfseries Surname & \bfseries Score (\%)\relax
+\DTLforeach*{scores}%
+{\firstname=FirstName,\surname=Surname,\score=Score}{%
+\ifthenelse{\DTLcurrentindex=3}{\dtlbreak}{}\relax
+\\\firstname & \surname & \score
+}%
+\end{tabular}
+\end{table}
+\end{example}
+
+\begin{example}{Stripy Tables}{ex:stripy}
+This example uses the same database as in the previous examples.
+It requires the \sty{colortbl} package, which provides the
+command \cs{rowcolor}. The command \cs{DTLifoddrow} is used
+to produce a striped table.
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{A stripy table}\label{tab:stripy}
+\centering
+\begin{tabular}{llc}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)%
+\DTLforeach*{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\\DTLifoddrow{\rowcolor{blue}}{\rowcolor{green}}%
+\firstname & \surname & \score}%
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:stripy}.
+
+\begin{table}[htbp]
+\caption[A stripy table (illustrating the use of
+\cs{DTLifoddrow})]{A stripy table}\label{tab:stripy}
+\centering
+\begin{tabular}{llc}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)\relax
+\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\\DTLifoddrow{\rowcolor{blue}}{\rowcolor{green}}\relax
+\firstname & \surname & \score}\relax
+\end{tabular}
+\end{table}
+\end{example}
+
+\begin{example}{Two Database Rows per Tabular Row}{ex:2rows}
+In order to save space, you may want two database rows per
+tabular row, when displaying a database in a \env{tabular}
+environment. This can be accomplished using \ics{DTLifoddrow}.
+For example
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Two database rows per tabular row}
+\centering
+\begin{tabular}{llcllc}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%) &
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)%
+\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{%
+\DTLifoddrow{\\}{&}%
+\firstname & \surname & \score}%
+\end{tabular}
+\end{table}
+\end{verbatim}
+produces \autoref{tab:2rows}
+
+\begin{table}[htbp]
+\caption[Two database rows per tabular row (illustrating the
+use of\newline \cs{DTLifoddrow})]{Two database rows per tabular
+row}\label{tab:2rows}
+\centering
+\begin{tabular}{llcllc}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%) &
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)\relax
+\DTLforeach*{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\DTLifoddrow{\\}{&}\relax
+\firstname & \surname & \score}\relax
+\end{tabular}
+\end{table}
+
+(To order column-wise, instead of row-wise, see
+\autoref{ex:twoblocks}.)
+\end{example}
+
+\begin{example}{Iterating Through Keys in a Row}{ex:foreachkey}
+Suppose you have lots of columns in your database, and you
+want to display them all without having to set a variable for
+each column. You can leave the assignment list in \cs{DTLforeach}
+blank, and iterate through the keys using \cs{DTLforeachkeyinrow}.
+For example:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student Scores (Iterating Through Keys)}
+\centering
+\begin{tabular}{llll}
+\bfseries First Name & \bfseries Surname &
+\bfseries Registration No. &
+\bfseries Score (\%)%
+\DTLforeach*{scores}{}{%
+\\\gdef\doamp{\gdef\doamp{&}}%
+\DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}%
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:foreachkey}.
+\begin{table}[htbp]
+\caption{Student Scores (Iterating Through Keys)}
+\label{tab:foreachkey}
+\centering
+\begin{tabular}{llll}
+\bfseries First Name & \bfseries Surname &
+\bfseries Registration No. &
+\bfseries Score (\%)\relax
+\DTLforeach*{scores}{}{%
+\\\gdef\doamp{\gdef\doamp{&}}\relax
+\DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}\relax
+\end{tabular}
+\end{table}
+
+Note that the "&" must be between columns, so I have defined
+a command called \cs{doamp} that on first use redefines
+itself to do "&". So, for each row, at the start of
+the key iteration, \cs{doamp} does nothing, and on subsequent
+iterations it does "&". This ensures that the correct number of
+"&"s are used. Since each cell in the \env{tabular} environment
+is scoped, \cs{gdef} is needed instead of \cs{def}.
+
+In the above, I needed to know how many columns are in the
+database, and the order that the headings should appear. If you
+are unsure, you can use \cs{dtlforeachkey} to determine the
+number of columns and to display the header row. For example:
+\begin{verbatim}
+ \begin{table}[htbp]
+ \caption{Student Scores}
+ \centering
+ % Work out the column alignments.
+ \def\colalign{}%
+ \dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do
+ {\edef\colalign{\colalign l}}%
+ % Begin the tabular environment.
+ \edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}%
+ \dobegintabular
+ % Do the header row.
+ \gdef\doamp{\gdef\doamp{&}}%
+ \dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do
+ {\doamp\bfseries \theHead}%
+ % Iterate through the data.
+ \DTLforeach*{scores}{}{%
+ \\\gdef\doamp{\gdef\doamp{&}}%
+ \DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}%
+ \end{tabular}
+ \end{table}
+\end{verbatim}
+
+\begin{table}[htbp]
+\caption[Student Scores (Using \cs{dtlforeachkey} and \newline
+\cs{DTLforeachkeyinrow})]{Student Scores (Using \cs{dtlforeachkey} and
+\cs{DTLforeachkeyinrow})}
+\label{tab:foreachkey2}
+\centering
+\def\colalign{}%
+\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do
+{\edef\colalign{\colalign l}}%
+\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}\relax
+\dobegintabular
+\gdef\doamp{\gdef\doamp{&}}\relax
+\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do
+{\doamp\bfseries \theHead}\relax
+\DTLforeach*{scores}{}{%
+\\\gdef\doamp{\gdef\doamp{&}}\relax
+\DTLforeachkeyinrow{\thisValue}{\doamp\thisValue}}\relax
+\end{tabular}
+\end{table}
+
+Notes:
+\begin{itemize}
+\item In order to determine the column alignment for the
+\env{tabular} environment, I first define \cs{colalign} to
+nothing, and then I iterate through the keys appending
+\texttt{l} to \cs{colalign}. Since \cs{colalign} only contains
+alphabetical characters, I can just use \cs{edef} for this. I
+could modify this to check the data type and, say, use \texttt{l}
+(left alignment) for columns containing strings and \texttt{c}
+(centred) for the other columns:
+\begin{verbatim}
+\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do
+{\ifnum\theType=0\relax
+ \edef\colalign{\colalign l}% column contains strings
+ \else
+ \edef\colalign{\colalign c}% column contains numerical values
+ \fi
+}%
+\end{verbatim}
+
+\item To ensure \cs{colalign} gets correct expanded when passed
+to the \env{tabular} environment I temporarily define
+\cs{dobegintabular} to the code required to start the
+\env{tabular} environment:
+\begin{verbatim}
+\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}%
+\end{verbatim}
+This sets \cs{dobegintabular} to \verb|\begin{tabular}{llll}|.
+After defining \cs{dobegintabular}, I then need to use it.
+
+\item As before, I use \cs{doamp} to put the ampersands between
+columns.
+
+\item Recall that I can set the headers using \cs{DTLsetheader}
+or using the \csopt{DTLloaddb}{headers} key when loading the data
+from an external file. For example:
+\begin{verbatim}
+\DTLsetheaders{scores}{FirstName}{First Name}
+\DTLsetheaders{scores}{Score}{Score (\%)}
+\end{verbatim}
+\end{itemize}
+
+Recall that \cs{DTLforeachkeyinrow} sets \cs{dtlkey} to the
+current key. This can be used to filter out columns. Alternatively,
+if you know the column index, you can test \cs{dtlcol} instead.
+The following code modifies the above example so that it filters
+out the column whose key is \texttt{StudentNo}:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student Scores (Filtering Out a Column)}
+\centering
+\def\colalign{}%
+\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do
+{\DTLifeq{\theKey}{StudentNo}{}{\edef\colalign{\colalign l}}}%
+\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}%
+\dobegintabular
+\gdef\doamp{\gdef\doamp{&}}%
+\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do
+{\DTLifeq{\theKey}{StudentNo}{}{\doamp\bfseries \theHead}}%
+\DTLforeach*{scores}{}{%
+\\\gdef\doamp{\gdef\doamp{&}}%
+\DTLforeachkeyinrow{\thisValue}{%
+ \DTLifeq{\dtlkey}{StudentNo}{}{\doamp\thisValue}}}%
+\end{tabular}
+\end{table}
+\end{verbatim}
+The result is shown in \autoref{tab:foreachkey3}.
+
+\begin{table}[htbp]
+\caption{Student Scores (Filtering Out a Column)}
+\label{tab:foreachkey3}
+\centering
+\def\colalign{}%
+\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do
+{\DTLifeq{\theKey}{StudentNo}{}{\edef\colalign{\colalign l}}}%
+\edef\dobegintabular{\noexpand\begin{tabular}{\colalign}}\relax
+\dobegintabular
+\gdef\doamp{\gdef\doamp{&}}\relax
+\dtlforeachkey(\theKey,\theCol,\theType,\theHead)\in{scores}\do
+{\DTLifeq{\theKey}{StudentNo}{}{\doamp\bfseries \theHead}}\relax
+\DTLforeach*{scores}{}{%
+\\\gdef\doamp{\gdef\doamp{&}}\relax
+\DTLforeachkeyinrow{\thisValue}{\relax
+\DTLifeq{\dtlkey}{StudentNo}{}{\doamp\thisValue}}}\relax
+\end{tabular}
+\end{table}
+\end{example}
+
+\begin{example}{Nested \cs{DTLforeach}}{ex:nested}
+In this example I have a CSV file called "index.csv" which
+contains:
+\begin{verbatim}
+File,Temperature,NaCl,pH
+exp25a.csv,25,4.7,0.5
+exp25b.csv,25,4.8,1.5
+exp30a.csv,30,5.12,4.5
+\end{verbatim}
+\DTLnewdb{index}\relax
+\DTLnewrow{index}\relax
+\DTLnewdbentry{index}{File}{exp25a.csv}\relax
+\DTLnewdbentry{index}{Temperature}{25}\relax
+\DTLnewdbentry{index}{NaCl}{4.7}\relax
+\DTLnewdbentry{index}{pH}{0.5}\relax
+\DTLnewrow{index}\relax
+\DTLnewdbentry{index}{File}{exp25b.csv}\relax
+\DTLnewdbentry{index}{Temperature}{25}\relax
+\DTLnewdbentry{index}{NaCl}{4.8}\relax
+\DTLnewdbentry{index}{pH}{1.5}\relax
+\DTLnewrow{index}\relax
+\DTLnewdbentry{index}{File}{exp30a.csv}\relax
+\DTLnewdbentry{index}{Temperature}{30}\relax
+\DTLnewdbentry{index}{NaCl}{5.12}\relax
+\DTLnewdbentry{index}{pH}{4.5}\relax
+The first column of this file contains the name of another
+CSV file which has the results of a time to growth experiment
+performed at the given incubation temperature, salt concentration
+and pH. The file "exp25a.csv" contains the following:
+\begin{verbatim}
+Time,Log Count
+0,3.75
+23,3.9
+45,4.0
+\end{verbatim}
+\DTLnewdb{exp25a.csv}\relax
+\DTLnewrow{exp25a.csv}\relax
+\DTLnewdbentry{exp25a.csv}{Time}{0}\relax
+\DTLnewdbentry{exp25a.csv}{Log Count}{3.75}\relax
+\DTLnewrow{exp25a.csv}\relax
+\DTLnewdbentry{exp25a.csv}{Time}{23}\relax
+\DTLnewdbentry{exp25a.csv}{Log Count}{3.9}\relax
+\DTLnewrow{exp25a.csv}\relax
+\DTLnewdbentry{exp25a.csv}{Time}{45}\relax
+\DTLnewdbentry{exp25a.csv}{Log Count}{4.0}\relax
+The file "exp25b.csv" contains the following:
+\begin{verbatim}
+Time,Log Count
+0,3.6
+60,3.8
+120,4.0
+\end{verbatim}
+\DTLnewdb{exp25b.csv}\relax
+\DTLnewrow{exp25b.csv}\relax
+\DTLnewdbentry{exp25b.csv}{Time}{0}\relax
+\DTLnewdbentry{exp25b.csv}{Log Count}{3.6}\relax
+\DTLnewrow{exp25b.csv}\relax
+\DTLnewdbentry{exp25b.csv}{Time}{60}\relax
+\DTLnewdbentry{exp25b.csv}{Log Count}{3.8}\relax
+\DTLnewrow{exp25b.csv}\relax
+\DTLnewdbentry{exp25b.csv}{Time}{120}\relax
+\DTLnewdbentry{exp25b.csv}{Log Count}{4.0}\relax
+The file "exp30a.csv" contains the following:
+\begin{verbatim}
+Time,Log Count
+0,3.73
+23,3.67
+60,4.9
+\end{verbatim}
+\DTLnewdb{exp30a.csv}\relax
+\DTLnewrow{exp30a.csv}\relax
+\DTLnewdbentry{exp30a.csv}{Time}{0}\relax
+\DTLnewdbentry{exp30a.csv}{Log Count}{3.73}\relax
+\DTLnewrow{exp30a.csv}\relax
+\DTLnewdbentry{exp30a.csv}{Time}{23}\relax
+\DTLnewdbentry{exp30a.csv}{Log Count}{3.67}\relax
+\DTLnewrow{exp30a.csv}\relax
+\DTLnewdbentry{exp30a.csv}{Time}{60}\relax
+\DTLnewdbentry{exp30a.csv}{Log Count}{4.9}\relax
+Suppose I now want to iterate through "index.csv", load the given
+file, and create a table for that data. I can do this using
+nested \ics{DTLforeach} as follows:
+\begin{verbatim}
+ % load index data file
+\DTLloaddb{index}{index.csv}
+
+ % iterate through index database
+\DTLforeach{index}{\theFile=File,\theTemp=Temperature,%
+\theNaCl=NaCl,\thepH=pH}{%
+ % load results file into database of the same name
+\DTLloaddb{\theFile}{\theFile}%
+ % Create a table
+\begin{table}[htbp]
+\caption{Temperature = \theTemp, NaCl = \theNaCl,
+pH = \thepH}\label{tab:\theFile}
+\centering
+\begin{tabular}{rl}
+\bfseries Time & \bfseries Log Count
+\DTLforeach{\theFile}{\theTime=Time,\theLogCount=Log Count}{%
+\\\theTime & \theLogCount}%
+\end{tabular}
+\end{table}
+}
+\end{verbatim}
+This creates \autoref{tab:exp25a.csv} to \autoref{tab:exp30a.csv}.
+(Note that each table is given a label that is based on the
+database name, to ensure that it is unique.)
+
+\DTLforeach{index}{\theFile=File,\theTemp=Temperature,\theNaCl
+=NaCl,\thepH=pH}{
+\begin{table}[htbp]
+\caption[Temperature = \theTemp, NaCl = \theNaCl,
+pH = \thepH\space (illustrating nested
+\cs{DTLforeach})]{Temperature = \theTemp, NaCl = \theNaCl,
+pH = \thepH}\label{tab:\theFile}
+\centering
+\begin{tabular}{rl}
+\bfseries Time & \bfseries Log Count
+\DTLforeach{\theFile}{\theTime=Time,\theLogCount=Log Count}{
+\\\theTime & \theLogCount}%
+\end{tabular}
+\end{table}
+}
+\end{example}
+
+\begin{example}{Dynamically Allocating Field Name}{ex:dyn}
+(This example was suggested by Bill~Hobbs.) Suppose you have a
+directory containing members of multiple clubs. The CSV file
+(say, \texttt{clubs.csv}) may look something like:
+\begin{verbatim}
+First Name,Surname,Rockin,Single
+John,"Smith, Jr",member,
+Jane,Brown,,friend
+Andy,Brown,friend,member
+Z\"oe,Adams,member,member
+Roger,Brady,friend,friend
+Clare,Verdon,member,
+\end{verbatim}
+\DTLnewdb{clubs}\relax
+\DTLnewrow{clubs}\relax
+\DTLnewdbentry{clubs}{First Name}{John}\relax
+\DTLnewdbentry{clubs}{Surname}{Smith, Jr}\relax
+\DTLnewdbentry{clubs}{Rockin}{member}\relax
+\DTLnewdbentry{clubs}{Single}{}\relax
+\DTLnewrow{clubs}\relax
+\DTLnewdbentry{clubs}{First Name}{Jane}\relax
+\DTLnewdbentry{clubs}{Surname}{Brown}\relax
+\DTLnewdbentry{clubs}{Rockin}{}\relax
+\DTLnewdbentry{clubs}{Single}{friend}\relax
+\DTLnewrow{clubs}\relax
+\DTLnewdbentry{clubs}{First Name}{Andy}\relax
+\DTLnewdbentry{clubs}{Surname}{Brown}\relax
+\DTLnewdbentry{clubs}{Rockin}{friend}\relax
+\DTLnewdbentry{clubs}{Single}{member}\relax
+\DTLnewrow{clubs}\relax
+\DTLnewdbentry{clubs}{First Name}{Z\"oe}\relax
+\DTLnewdbentry{clubs}{Surname}{Adams}\relax
+\DTLnewdbentry{clubs}{Rockin}{member}\relax
+\DTLnewdbentry{clubs}{Single}{member}\relax
+\DTLnewrow{clubs}\relax
+\DTLnewdbentry{clubs}{First Name}{Roger}\relax
+\DTLnewdbentry{clubs}{Surname}{Brady}\relax
+\DTLnewdbentry{clubs}{Rockin}{friend}\relax
+\DTLnewdbentry{clubs}{Single}{friend}\relax
+\DTLnewrow{clubs}\relax
+\DTLnewdbentry{clubs}{First Name}{Clare}\relax
+\DTLnewdbentry{clubs}{Surname}{Verdon}\relax
+\DTLnewdbentry{clubs}{Rockin}{member}\relax
+\DTLnewdbentry{clubs}{Single}{}\relax
+(Blank entries indicate that the person is not a member of that
+club.) The data can be loaded as follows:
+\begin{verbatim}
+\DTLloaddb{clubs}{clubs.csv}
+\end{verbatim}
+Suppose at the beginning of your document you have specified
+which club you are interested in ("Rockin" or "Single") and
+store it in \cs{DIdent}:
+\begin{verbatim}
+\newcommand{\DIdent}{Rockin}
+\end{verbatim}
+\newcommand{\DIdent}{Rockin}\relax
+You can now display the members for this particular club as
+follows:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Club Membership}
+\centering
+\begin{tabular}{lll}
+\bfseries First Name & \bfseries Surname & \bfseries Status
+\DTLforeach*[\not\DTLiseq{\status}{}]{clubs}
+{\firstname=First Name,\surname=Surname,\status=\DIdent}{%
+\\\firstname & \surname & \status
+}%
+\end{tabular}
+\end{table}
+\end{verbatim}
+The result is shown in \autoref{tab:dyn}.
+
+\begin{table}[htbp]
+\caption{Club Membership}
+\label{tab:dyn}
+\centering
+\begin{tabular}{lll}
+\bfseries First Name & \bfseries Surname & \bfseries Status
+\DTLforeach*[\not\DTLiseq{\status}{}]{clubs}
+{\firstname=First Name,\surname=Surname,\status=\DIdent}{\relax
+\\\firstname & \surname & \status
+}\relax
+\end{tabular}
+\end{table}
+\end{example}
+
+\section{Null Values}
+If a database is created using \cs{DTLnewdb}, \cs{DTLnewrow}
+and \cs{DTLnewdbentry} (rather than loading it from an ASCII
+file), it is possible for some of the entries to have null values
+when a value is not assigned to a given key for a given row.
+(Note that a null value is not the same as an empty value. Empty
+values can be tested using \sty{etoolbox}'s \ics{ifdefempty} or
+similar.)
+
+When you iterate through the database using \cs{DTLforeach}
+(described in \autoref{sec:dbforeach}),
+if an entry is missing for a given row, the associated command given
+in the \meta{values} argument will be set to a null value. This
+value depends on the data type associated with the given key.
+
+\begin{definition}[\DescribeMacro{\DTLstringnull}]%
+\cs{DTLstringnull}
+\end{definition}
+This is the null value for a string.
+
+\begin{definition}[\DescribeMacro{\DTLnumbernull}]%
+\cs{DTLnumbernull}
+\end{definition}
+This is the null value for a number.
+
+\begin{definition}[\DescribeMacro{\DTLifnull}]%
+\cs{DTLifnull}\marg{cmd}\marg{true part}\marg{false part}
+\end{definition}
+This checks if \meta{cmd} is null where \meta{cmd} is a command name,
+if it is, then \meta{true part}
+is done, otherwise \meta{false part} is done. This macro is
+illustrated in \autoref{ex:null} below.
+
+\begin{example}{Null Values}{ex:null}
+Consider the following (which creates a database called "emailDB"):
+\begin{verbatim}
+\DTLnewdb{emailDB}
+\DTLnewrow{emailDB}
+\DTLnewdbentry{emailDB}{Surname}{Jones}
+\DTLnewdbentry{emailDB}{FirstName}{Mary}
+\DTLnewdbentry{emailDB}{Email1}{mj@my.uni.ac.uk}
+\DTLnewdbentry{emailDB}{Email2}{mj@somewhere.com}
+\DTLnewrow{emailDB}
+\DTLnewdbentry{emailDB}{Surname}{Smith}
+\DTLnewdbentry{emailDB}{FirstName}{Adam}
+\DTLnewdbentry{emailDB}{Email1}{as@my.uni.ac.uk}
+\DTLnewdbentry{emailDB}{RegNum}{12345}
+\end{verbatim}
+\DTLnewdb{emailDB}\relax
+\DTLnewrow{emailDB}\relax
+\DTLnewdbentry{emailDB}{Surname}{Jones}\relax
+\DTLnewdbentry{emailDB}{FirstName}{Mary}\relax
+\DTLnewdbentry{emailDB}{Email1}{mj@my.uni.ac.uk}\relax
+\DTLnewdbentry{emailDB}{Email2}{mj@somewhere.com}\relax
+\DTLnewrow{emailDB}\relax
+\DTLnewdbentry{emailDB}{Surname}{Smith}\relax
+\DTLnewdbentry{emailDB}{FirstName}{Adam}\relax
+\DTLnewdbentry{emailDB}{Email1}{as@my.uni.ac.uk}\relax
+\DTLnewdbentry{emailDB}{RegNum}{12345}\relax
+In the above example, the first row of the database contains
+an entry with the key "Email2", but the second row doesn't.
+Whereas the second row contains an entry with the key "RegNum",
+but the first row doesn't.
+
+The following code puts the information in a \env{tabular}
+environment:
+\begin{verbatim}
+\begin{tabular}{lllll}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Email 1 &
+\bfseries Email 2 &
+\bfseries Reg Num%
+\DTLforeach{emailDB}{\firstname=FirstName,\surname=Surname,%
+\emailI=Email1,\emailII=Email2,\regnum=RegNum}{%
+\\\firstname & \surname & \emailI & \emailII & \regnum}%
+\end{tabular}
+\end{verbatim}
+This produces the following:\par\vskip\baselineskip\noindent
+\begin{tabular}{lllll}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Email 1 &
+\bfseries Email 2 &
+\bfseries Reg Num\relax
+\DTLforeach{emailDB}{\firstname=FirstName,\surname
+=Surname,\emailI=Email1,\emailII=Email2,\regnum=RegNum}{\relax
+\\\firstname & \surname & \emailI & \emailII & \regnum}\relax
+\end{tabular}
+\par\vskip\baselineskip
+Note that on the first row of data, the registration number appears as
+0, while on the next row, the second email address appears as
+NULL. The \sty{datatool} package has identified the key "RegNum"
+for this database as a numerical key, since all elements in the
+database with that key are numerical, whereas it has
+identified the key "Email2" as a string, since there is at least
+one element in this database with that key that is a string. Null
+numerical values are set to \cs{DTLnumbernull} (\DTLnumbernull), and
+null strings are set to \cs{DTLstringnull} (\DTLstringnull).
+
+The following code checks each value to determine whether it
+is null using \cs{DTLifnull}. If it is, the text \emph{Missing}
+is inserted, otherwise the value itself is used:
+\begin{verbatim}
+\begin{tabular}{lllll}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Email 1 &
+\bfseries Email 2 &
+\bfseries Reg Num%
+\DTLforeach{emailDB}{\firstname=FirstName,\surname=Surname,%
+\emailI=Email1,\emailII=Email2,\regnum=RegNum}{%
+\\\DTLifnull{\firstname}{\emph{Missing}}{\firstname} &
+\DTLifnull{\surname}{\emph{Missing}}{\surname} &
+\DTLifnull{\emailI}{\emph{Missing}}{\emailI} &
+\DTLifnull{\emailII}{\emph{Missing}}{\emailII} &
+\DTLifnull{\regnum}{\emph{Missing}}{\regnum}}%
+\end{tabular}
+\end{verbatim}
+This produces the following:\par\vskip\baselineskip\noindent
+\begin{tabular}{lllll}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Email 1 &
+\bfseries Email 2 &
+\bfseries Reg Num\relax
+\DTLforeach{emailDB}{\firstname=FirstName,\surname
+=Surname,\emailI=Email1,\emailII=Email2,\regnum=RegNum}{\relax
+\\\DTLifnull{\firstname}{\emph{Missing}}{\firstname} &
+\DTLifnull{\surname}{\emph{Missing}}{\surname} &
+\DTLifnull{\emailI}{\emph{Missing}}{\emailI} &
+\DTLifnull{\emailII}{\emph{Missing}}{\emailII} &
+\DTLifnull{\regnum}{\emph{Missing}}{\regnum}}\relax
+\end{tabular}
+\par\vskip\baselineskip\noindent
+If you want to do this, you may find it easier to define a
+convenience command that will display some appropriate text
+if an entry is missing, for example:
+\begin{verbatim}
+\newcommand*{\checkmissing}[1]{\DTLifnull{#1}{---}{#1}}
+\end{verbatim}
+Then instead of typing, say,
+\begin{verbatim}
+\DTLifnull{\regnum}{---}{\regnum}
+\end{verbatim}
+you can instead type:
+\begin{verbatim}
+\checkmissing{\regnum}
+\end{verbatim}
+
+Now suppose that instead of defining the database using \cs{DTLnewdb},
+\cs{DTLnewrow} and \cs{DTLnewdbentry}, you have a file with the
+contents:
+\begin{ttfamily}\setlength{\parindent}{0pt}\par\vskip\baselineskip
+Surname,FirstName,RegNum,Email1,Email2
+
+\DTLforeach{emailDB}{\surname=Surname,\firstname=FirstName,\regNo
+=RegNum,\emailI=Email1,\emailII
+=Email2}{\relax
+\surname,\firstname,\DTLifnull{\regNo}{}{\regNo},\emailI,\DTLifnull{\emailII}{}{\emailII}\par
+}
+\end{ttfamily}\par\vskip\baselineskip\noindent
+and you load the data from this file using \cs{DTLloaddb}
+(defined in \autoref{sec:loaddb}). Now the
+database has no null values, but has an empty value for the
+key "RegNum" on the first row of the database, and an empty
+value for the key "Email2" on the second row of the database.
+Now, the following code
+\begin{verbatim}
+\begin{tabular}{lllll}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Email 1 &
+\bfseries Email 2 &
+\bfseries Reg Number%
+\DTLforeach{emailDB}{\firstname=FirstName,\surname=Surname,%
+\emailI=Email1,\emailII=Email2,\regnum=RegNum}{%
+\\\DTLifnull{\firstname}{\emph{Missing}}{\firstname} &
+\DTLifnull{\surname}{\emph{Missing}}{\surname} &
+\DTLifnull{\emailI}{\emph{Missing}}{\emailI} &
+\DTLifnull{\emailII}{\emph{Missing}}{\emailII} &
+\DTLifnull{\regnum}{\emph{Missing}}{\regnum}}%
+\end{tabular}
+\end{verbatim}
+produces:\par\vskip\baselineskip\noindent
+\begin{tabular}{lllll}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Email 1 &
+\bfseries Email 2 &
+\bfseries Reg Number\relax
+\DTLforeach{emailDB}{\firstname=FirstName,\surname
+=Surname,\emailI=Email1,\emailII=Email2,\regnum=RegNum}{\relax
+\\\firstname & \surname & \emailI & \DTLifnull{\emailII}{}{\emailII} & \DTLifnull{\regnum}{}{\regnum}}\relax
+\end{tabular}
+\end{example}
+
+\section{Editing Database Rows}
+\label{sec:editdb}
+
+A row can be removed from a data base using:
+\begin{definition}[\DescribeMacro{\DTLremoverow}]%
+\cs{DTLremoverow}\marg{db name}\marg{row index}
+\end{definition}
+where \meta{row index} is the index of the unwanted row. For
+example:
+\begin{verbatim}
+\DTLremoverow{scores}{2}
+\end{verbatim}
+will delete the second row in the database labelled ``scores''.
+There is also a starred version that doesn't check for the
+existence of the database.
+
+The following commands may be used in the body of the
+\ics{DTLforeach} loop,\footnote{Only the unstarred version of
+\cs{DTLforeach}; the starred version is read-only.}\ to edit the
+current row of the loop. (See also \autoref{sec:currentrow}.)
+
+\begin{definition}[\DescribeMacro{\DTLappendtorow}]%
+\cs{DTLappendtorow}\marg{key}\marg{value}
+\end{definition}
+This appends a new entry with the given \meta{key} and \meta{value}
+to the current row.
+(\meta{value} is expanded.)
+
+\begin{definition}[\DescribeMacro{\DTLreplaceentryforrow}]%
+\cs{DTLreplaceentryforrow}\marg{key}\marg{value}
+\end{definition}
+This replaces the entry for \meta{key} with \meta{value}.
+(\meta{value} is expanded.)
+
+\begin{definition}[\DescribeMacro{\DTLremoveentryfromrow}]%
+\cs{DTLremoveentryfromrow}\marg{key}
+\end{definition}
+This removes the entry for \meta{key} from the current row.
+
+\begin{definition}[\DescribeMacro{\DTLremovecurrentrow}]%
+\cs{DTLremovecurrentrow}
+\end{definition}
+This removes the current row from the database.
+
+\begin{example}{Editing Database Rows}{ex:editdb}
+In this example I have a CSV file called "marks.csv" that contains
+student marks for three assignments:
+\DTLnewdb{marks}\relax
+\DTLnewrow{marks}\relax
+\DTLnewdbentry{marks}{FirstName}{John}\relax
+\DTLnewdbentry{marks}{Surname}{Smith, Jr}\relax
+\DTLnewdbentry{marks}{StudentNo}{102689}\relax
+\DTLnewdbentry{marks}{Assignment 1}{68}\relax
+\DTLnewdbentry{marks}{Assignment 2}{57}\relax
+\DTLnewdbentry{marks}{Assignment 3}{72}\relax
+\DTLnewrow{marks}\relax
+\DTLnewdbentry{marks}{FirstName}{Jane}\relax
+\DTLnewdbentry{marks}{Surname}{Brown}\relax
+\DTLnewdbentry{marks}{StudentNo}{102647}\relax
+\DTLnewdbentry{marks}{Assignment 1}{75}\relax
+\DTLnewdbentry{marks}{Assignment 2}{84}\relax
+\DTLnewdbentry{marks}{Assignment 3}{80}\relax
+\DTLnewrow{marks}\relax
+\DTLnewdbentry{marks}{FirstName}{Andy}\relax
+\DTLnewdbentry{marks}{Surname}{Brown}\relax
+\DTLnewdbentry{marks}{StudentNo}{103569}\relax
+\DTLnewdbentry{marks}{Assignment 1}{42}\relax
+\DTLnewdbentry{marks}{Assignment 2}{52}\relax
+\DTLnewdbentry{marks}{Assignment 3}{54}\relax
+\DTLnewrow{marks}\relax
+\DTLnewdbentry{marks}{FirstName}{Z\"oe}\relax
+\DTLnewdbentry{marks}{Surname}{Adams}\relax
+\DTLnewdbentry{marks}{StudentNo}{105987}\relax
+\DTLnewdbentry{marks}{Assignment 1}{52}\relax
+\DTLnewdbentry{marks}{Assignment 2}{48}\relax
+\DTLnewdbentry{marks}{Assignment 3}{57}\relax
+\DTLnewrow{marks}\relax
+\DTLnewdbentry{marks}{FirstName}{Roger}\relax
+\DTLnewdbentry{marks}{Surname}{Brady}\relax
+\DTLnewdbentry{marks}{StudentNo}{106872}\relax
+\DTLnewdbentry{marks}{Assignment 1}{58}\relax
+\DTLnewdbentry{marks}{Assignment 2}{60}\relax
+\DTLnewdbentry{marks}{Assignment 3}{62}\relax
+\DTLnewrow{marks}\relax
+\DTLnewdbentry{marks}{FirstName}{Clare}\relax
+\DTLnewdbentry{marks}{Surname}{Verdon}\relax
+\DTLnewdbentry{marks}{StudentNo}{104356}\relax
+\DTLnewdbentry{marks}{Assignment 1}{45}\relax
+\DTLnewdbentry{marks}{Assignment 2}{50}\relax
+\DTLnewdbentry{marks}{Assignment 3}{48}\relax
+\begin{ttfamily}\setlength{\parindent}{0pt}\par
+Surname,FirstName,StudentNo,Assignment 1,Assignment 2,Assignment 3
+
+\DTLforeach{marks}{\surname=Surname,\firstname=FirstName,\regNo
+=StudentNo,\assignI=Assignment 1,\assignII
+=Assignment 2,\assignIII=Assignment 3}{\relax
+\char`\"\surname\char`\",\DTLifstringeq{\firstname}{Zoe}{Z\string\"oe}{\firstname},\regNo,\assignI,\assignII,\assignIII\par
+}
+\end{ttfamily}\par\noindent
+First load this into a database called "marks":
+\begin{verbatim}
+\DTLloaddb{marks}{marks.csv}
+\end{verbatim}
+Suppose now I want to compute the average mark for each
+student, and append this to the database. I can do this as
+follows:
+\begin{verbatim}
+\DTLforeach{marks}{%
+\assignI=Assignment 1,%
+\assignII=Assignment 2,%
+\assignIII=Assignment 3}{%
+\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}%
+\DTLappendtorow{Average}{\theMean}}
+\end{verbatim}
+\DTLforeach{marks}{\assignI=Assignment 1,\assignII
+=Assignment 2,\assignIII=Assignment 3}{\relax
+\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}%
+\DTLappendtorow{Average}{\theMean}}\relax
+For each row in the "marks" database, I now have an extra key
+called "Average" that contains the average mark over all three
+assignments for a given student. I can now put this data into
+a table:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student marks}
+\centering
+\begin{tabular}{llcccc}
+\bfseries Surname & \bfseries First Name &
+\bfseries Assign 1 &
+\bfseries Assign 2 &
+\bfseries Assign 3 &
+\bfseries Average Mark%
+\DTLforeach{marks}{\surname=Surname,\firstname=FirstName,\average
+=Average,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII
+=Assignment 3}{\\\surname
+& \firstname & \assignI & \assignII & \assignIII &
+\DTLround{\average}{\average}{2}\DTLclip{\average}\average}\relax
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:meanmarks}.
+
+Note that if I only wanted the averages for the table and nothing
+else, I could simply have computed the average in each row of the
+table and displayed it without adding the information to the
+database, however I am going to reuse this information in
+\autoref{ex:multibar}, so adding it to the database means that
+I don't need to recompute the mean.
+
+\begin{table}[htbp]
+\caption[Student marks (with averages)]{Student
+marks}\label{tab:meanmarks}
+\centering
+\begin{tabular}{llcccc}
+\bfseries Surname & \bfseries First Name &
+\bfseries Assign 1 &
+\bfseries Assign 2 &
+\bfseries Assign 3 &
+\bfseries Average Mark\relax
+\DTLforeach{marks}{\surname=Surname,\firstname=FirstName,\average
+=Average,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII
+=Assignment 3}{\\\surname
+& \firstname & \assignI & \assignII & \assignIII &
+\DTLround{\average}{\average}{2}\DTLclip{\average}\average}\relax
+\end{tabular}
+\end{table}
+
+\end{example}
+
+\section{Arithmetical Computations on Database Entries}
+
+The commands used in \autoref{sec:fp} can be used on database
+entries. You can, of course, directly use the commands provided
+by the \sty{fp} package if you know that the values are in the
+correct format (i.e.\ no currency symbols, no number group
+separators and a full stop as the decimal point) but if this is
+not the case, then you should use the commands described in
+\autoref{sec:fp}. If you want to use a command provided by the
+\sty{fp} package, that does not have a wrapper function in
+\sty{datatool}, then you will need to convert the value using
+\ics{DTLconverttodecimal}, and convert it back using either
+\ics{DTLdecimaltolocale} or \ics{DTLdecimaltocurrency}.
+
+\begin{example}{Arithmetical Computations}{ex:mean}
+In this example, I am going to produce a table similar to
+\autoref{tab:scores}, except that I want to add an extra row at the
+end which contains the average score.
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student scores}\label{tab:mean}
+\centering
+\def\total{0}%
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)%
+\DTLforeach{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\
+\firstname & \surname &
+\DTLgadd{\total}{\score}{\total}%
+\score
+}\\
+\multicolumn{2}{l}{\bfseries Average Score} &
+\DTLsavelastrowcount{\n}%
+\DTLdiv{\average}{\total}{\n}%
+\DTLround{\average}{\average}{2}%
+\average
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:mean}.
+\textbf{Notes:}
+\begin{itemize}
+\item I had to use \ics{DTLgadd} rather than \ics{DTLadd} since it
+occurs within a \env{tabular} environment which puts each entry
+in a local scope.
+
+\item I used \ics{DTLsavelastrowcount} to store the number of
+rows produced by \ics{DTLforeach} in the control sequence \cs{n}.
+
+\item I used \ics{DTLround} to round the average score to 2 decimal
+places.
+\end{itemize}
+
+\begin{table}[htbp]
+\caption[Student scores (using arithmetic computations)]{Student
+scores}\label{tab:mean}
+\centering
+\def\total{0}\relax
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)\relax
+\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\
+\firstname & \surname &
+\DTLgadd{\total}{\score}{\total}\relax
+\score
+}\\
+\multicolumn{2}{l}{\bfseries Average Score} &
+\DTLsavelastrowcount{\n}\relax
+\DTLdiv{\average}{\total}{\n}\relax
+\DTLround{\average}{\average}{2}\relax
+\average
+\end{tabular}
+\end{table}
+\end{example}
+
+\begin{definition}[\DescribeMacro{\DTLsumforkeys}]%
+\cs{DTLsumforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd}
+\end{definition}
+This command sums all the entries over all the databases listed in
+the comma separated list of database names \meta{db list} for each
+key in \meta{key list} where the condition given by \meta{condition}
+is true. The second optional argument \meta{assign list} is the same
+as the assignment list used by \ics{DTLforeach}, so that you can use
+the information in \meta{condition}. The result is stored in
+\meta{cmd} which must be a control sequence. For example:
+\begin{verbatim}
+\DTLsumforkeys{scores}{Score}{\total}
+\end{verbatim}
+sets \cs{total} to the sum of all the scores in the database
+called "scores".
+
+\begin{definition}[\DescribeMacro{\DTLsumcolumn}]%
+\cs{DTLsumcolumn}\marg{db}\marg{key}\marg{cmd}
+\end{definition}
+This is a faster version of \cs{DTLsumforkeys} that only sums
+the entries in a single column (specified by \meta{key}) for
+a single database (specified by \meta{db}) and doesn't provide any
+filtering. The result is stored in \meta{cmd} which must be
+a control sequence.
+
+\begin{definition}[\DescribeMacro{\DTLmeanforkeys}]%
+\cs{DTLmeanforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd}
+\end{definition}
+This command computes the arithmetic mean of all the entries over
+all the databases listed in \meta{db list} for all keys in \meta{key
+list} where the condition given by \meta{condition} is true. The
+second optional argument \meta{assign list} is the same as the
+assignment list used by \ics{DTLforeach}, so that you can use the
+information in \meta{condition}. The result is stored in \meta{cmd}
+which must be a control sequence. For example:
+\begin{verbatim}
+\DTLmeanforkeys{scores}{Score}{\average}
+\end{verbatim}
+sets \cs{average} to the mean of all the scores in the database
+called "scores".
+
+\begin{definition}[\DescribeMacro{\DTLmeanforcolumn}]%
+\cs{DTLmeanforcolumn}\marg{db}\marg{key}\marg{cmd}
+\end{definition}
+This is a faster version of \cs{DTLmeanforkeys} that only computes
+the mean for a single column (specified by \meta{key}) for
+a single database (specified by \meta{db}) and doesn't provide any
+filtering. The result is stored in \meta{cmd} which must be
+a control sequence.
+
+\begin{definition}[\DescribeMacro{\DTLvarianceforkeys}]%
+\cs{DTLvarianceforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd}
+\end{definition}
+This command computes the variance of all the entries over all the
+databases listed in \meta{db list} for all keys in \meta{key list}
+where the condition given by \meta{condition} is true. The second
+optional argument \meta{assign list} is the same as the assignment
+list used by \ics{DTLforeach}, so that you can use the information
+in \meta{condition}. The result is stored in \meta{cmd} which must
+be a control sequence.
+
+\begin{definition}[\DescribeMacro{\DTLvarianceforcolumn}]%
+\cs{DTLvarianceforcolumn}\marg{db}\marg{key}\marg{cmd}
+\end{definition}
+This is a faster version of \cs{DTLvarianceforkeys} that only
+computes the variance for a single column (specified by \meta{key})
+for a single database (specified by \meta{db}) and doesn't provide
+any filtering. The result is stored in \meta{cmd} which must be a
+control sequence.
+
+\begin{definition}[\DescribeMacro{\DTLsdforkeys}]%
+\cs{DTLsdforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd}
+\end{definition}
+This command computes the standard deviation of all the entries over
+all the databases listed in \meta{db list} for all keys in \meta{key
+list} where the condition given by \meta{condition} is true. The
+second optional argument \meta{assign list} is the same as the
+assignment list used by \ics{DTLforeach}, so that you can use the
+information in \meta{condition}. The result is stored in \meta{cmd}
+which must be a control sequence.
+
+\begin{definition}[\DescribeMacro{\DTLsdforcolumn}]%
+\cs{DTLsdforcolumn}\marg{db}\marg{key}\marg{cmd}
+\end{definition}
+This is a faster version of \cs{DTLsdforkeys} that only computes the
+standard deviation for a single column (specified by \meta{key}) for
+a single database (specified by \meta{db}) and doesn't provide any
+filtering. The result is stored in \meta{cmd} which must be a
+control sequence.
+
+\begin{definition}[\DescribeMacro{\DTLminforkeys}]%
+\cs{DTLminforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd}
+\end{definition}
+This command determines the minimum value over all entries for all
+keys in \meta{key list} over all the databases listed in \meta{db
+list} where \meta{condition} is true. The second optional argument
+\meta{assign list} is the same as the assignment list used by
+\ics{DTLforeach}, so that you can use the information in
+\meta{condition}. The result is stored in \meta{cmd}, which must be
+a control sequence. For example
+\begin{verbatim}
+\DTLminforkeys{scores}{Score}{\theMin}
+\end{verbatim}
+sets \cs{theMin} to the minimum score in the database.
+
+\begin{definition}[\DescribeMacro{\DTLminforcolumn}]%
+\cs{DTLminforcolumn}\marg{db}\marg{key}\marg{cmd}
+\end{definition}
+This is a faster version of \cs{DTLminforkeys} that only computes
+the minimum for a single column (specified by \meta{key}) for
+a single database (specified by \meta{db}) and doesn't provide any
+filtering. The result is stored in \meta{cmd} which must be
+a control sequence.
+
+\begin{definition}[\DescribeMacro{\DTLmaxforkeys}]%
+\cs{DTLmaxforkeys}\oarg{condition}\oarg{assign list}\marg{db list}\marg{key list}\marg{cmd}
+\end{definition}
+This command determines the maximum value over all entries for all
+keys in \meta{key list} over all the databases listed in \meta{db
+list} where \meta{condition} is true. The second optional argument
+\meta{assign list} is the same as the assignment list used by
+\ics{DTLforeach}, so that you can use the information in
+\meta{condition}. The result is stored in \meta{cmd}, which must be
+a control sequence. For example
+\begin{verbatim}
+\DTLminforkeys{scores}{Score}{\theMax}
+\end{verbatim}
+sets \cs{theMax} to the minimum score in the database.
+
+\begin{definition}[\DescribeMacro{\DTLmaxforcolumn}]%
+\cs{DTLmaxforcolumn}\marg{db}\marg{key}\marg{cmd}
+\end{definition}
+This is a faster version of \cs{DTLmaxforkeys} that only computes
+the maximum for a single column (specified by \meta{key}) for
+a single database (specified by \meta{db}) and doesn't provide any
+filtering. The result is stored in \meta{cmd} which must be
+a control sequence.
+
+\begin{definition}[\DescribeMacro{\DTLcomputebounds}]%
+\cs{DTLcomputebounds}\marg{db list}\marg{x key}\marg{y key}\marg{minX cmd}\marg{minY cmd}\marg{maxX cmd}\marg{maxY cmd}
+\end{definition}
+Computes the maximum and minimum $x$ and $y$ values over all
+the databases listed in \meta{db list} where the $x$ value
+is given by \meta{x key} and the $y$ value is given by
+\meta{y key}. The results are stored in \meta{minX cmd},
+\meta{minY cmd}, \meta{maxX cmd} and \meta{maxY cmd}.
+
+\begin{example}{Mail Merging}{ex:mailmerging}
+This example uses the database given in \autoref{ex:scores} and
+uses \ics{DTLmeanforkeys} to determine the average score. A letter
+is then created for each student to inform them of their score
+and the class average.
+
+\begin{verbatim}
+\documentclass{letter}
+
+\usepackage{datatool}
+
+\begin{document}
+ % load database
+\DTLloaddb{scores}{studentscores.csv}
+ % compute arithmetic mean for key `Score'
+\DTLmeanforkeys{scores}{Score}{\average}
+ % Round the average to 2 decimal places
+\DTLround{\average}{\average}{2}
+ % Save the highest score in \maxscore
+\DTLmaxforkeys{scores}{Score}{\maxscore}
+
+\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,%
+\score=Score}{%
+\begin{letter}{}
+\opening{Dear \firstname\ \surname}
+
+\DTLifnumgt{\score}{60}{Congratulations you}{You} achieved a score
+of \score\% which was \DTLifnumgt{\score}{\average}{above}{below}
+the average of \average\%. \DTLifnumeq{\score}{\maxscore}{You
+achieved the highest score}{The top score was \maxscore}.
+
+\closing{Yours Sincerely}
+\end{letter}
+}
+\end{document}
+\end{verbatim}
+
+To determine a person's gender when mail merging, see
+\autoref{sec:person}.
+\end{example}
+
+\section{Sorting a Database}
+\label{sec:sort}
+
+\begin{definition}[\DescribeMacro{\DTLsort}]%
+\cs{DTLsort}\oarg{replacement key list}\marg{sort criteria}\marg{db name}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLsort*}]%
+\cs{DTLsort*}\oarg{replacement key list}\marg{sort criteria}\marg{db name}
+\end{definition}
+This will sort the database called \meta{db name} according to
+the criteria given by \meta{sort criteria}, which must be a
+comma separated list of keys and optionally "="\meta{order}, where
+\meta{order} is either "ascending" or "descending". If the order
+is omitted, "ascending" is assumed. The database keeps track of
+the data type for a given key, and uses this to determine whether
+an alphabetical or numerical sort is required. (String comparisons
+are made using the command \cs{dtlcompare} or \cs{dtlicompare}
+described in \autoref{src:dtlcompare}.)
+
+The optional argument \meta{replacement key list} is a list of
+keys to use if the current key given in \meta{sort criteria}
+is null for a given entry. Null keys are unlikely to occur if
+you have loaded the database from an external ASCII file, but
+may occur if the database is created using \cs{DTLnewdb},
+\cs{DTLnewrow} and \cs{DTLnewdbentry}. For example:
+\begin{verbatim}
+\DTLsort[Editor,Organization]{Author}{mydata}
+\end{verbatim}
+will sort according to the "Author" key, but if that key is missing
+for a given row of the database, the "Editor" key will be used,
+and if the "Editor" key is missing, it will use the "Organization"
+key. Note that this is not the same as:
+\begin{verbatim}
+\DTLsort{Author,Editor,Organization}{mydata}
+\end{verbatim}
+which will first compare the "Author" keys, but if the author names
+are the same, it will then compare the "Editor" keys, and if the
+editor names are also the same, it will then compare the
+"Organization" keys.
+
+The unstarred version uses a case sensitive comparison for strings,
+whereas the starred version ignores the case when comparing strings.
+Note that the case sensitive comparison orders uppercase characters
+before lowercase characters, so the letter B is considered to be
+lower than the letter a.
+
+\begin{example}{Sorting a Database}{ex:sort}
+This example uses the database called "scores" defined in
+\autoref{ex:scores}. First, I am going to sort the database
+according to the student scores in descending order (highest to
+lowest) and display the database in a table
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student scores (sorted by score)}
+\centering
+\DTLsort{Score=descending}{scores}%
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)%
+\DTLforeach{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\
+\firstname & \surname & \score}
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:sortscores}.
+
+\begin{table}[htbp]
+\caption{Student scores (sorted by score)}\label{tab:sortscores}
+\centering
+\DTLsort{Score=descending}{scores}\relax
+\begin{tabular}{llr}
+\bfseries First Name &
+\bfseries Surname &
+\bfseries Score (\%)\relax
+\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\
+\firstname & \surname & \score}
+\end{tabular}
+\end{table}
+
+Now I am going to sort the database according to
+surname and then first name, and display it in a table. Note that
+since I want to sort in ascending order, I can omit the
+"=ascending" part of the sort criteria. I have also decided to
+reverse the first and second columns, so that the surname is
+in the first column.
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student scores (sorted by name)}
+\centering
+\DTLsort{Surname,FirstName}{scores}%
+\begin{tabular}{llr}
+\bfseries Surname &
+\bfseries First Name &
+\bfseries Score (\%)%
+\DTLforeach{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\
+\surname & \firstname & \score}
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:sortname}.
+\begin{table}[htbp]
+\caption{Student scores (sorted by name)}\label{tab:sortname}
+\centering
+\DTLsort{Surname,FirstName}{scores}\relax
+\begin{tabular}{llr}
+\bfseries Surname &
+\bfseries First Name &
+\bfseries Score (\%)\relax
+\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\
+\surname & \firstname & \score}
+\end{tabular}
+\end{table}
+
+Now suppose I add two new students to the database:
+\begin{verbatim}
+\DTLnewrow{scores}%
+\DTLnewdbentry{scores}{Surname}{van der Mere}%
+\DTLnewdbentry{scores}{FirstName}{Henk}%
+\DTLnewdbentry{scores}{Score}{71}%
+\DTLnewrow{scores}%
+\DTLnewdbentry{scores}{Surname}{de la Mere}%
+\DTLnewdbentry{scores}{FirstName}{Jos}%
+\DTLnewdbentry{scores}{Score}{58}%
+\end{verbatim}
+\DTLnewrow{scores}
+\DTLnewdbentry{scores}{Surname}{van der Mere}\relax
+\DTLnewdbentry{scores}{FirstName}{Henk}\relax
+\DTLnewdbentry{scores}{Score}{71}\relax
+\DTLnewrow{scores}\relax
+\DTLnewdbentry{scores}{Surname}{de la Mere}\relax
+\DTLnewdbentry{scores}{FirstName}{Jos}\relax
+\DTLnewdbentry{scores}{Score}{58}\relax
+and again I try sorting the database, and displaying the contents
+as a table:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student scores (case sensitive sort)}
+\centering
+\DTLsort{Surname,FirstName}{scores}%
+\begin{tabular}{llr}
+\bfseries Surname &
+\bfseries First Name &
+\bfseries Score (\%)%
+\DTLforeach{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\
+\surname & \firstname & \score}
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:sortname2}. Notice that the surnames
+aren't correctly ordered. This is because a case-sensitive
+sort was used. Changing \cs{DTLsort} to \cs{DTLsort*} in the
+above code produces \autoref{tab:sortname3}.
+
+\begin{table}[htbp]
+\caption{Student scores (case sensitive sort)}\label{tab:sortname2}
+\centering
+\DTLsort{Surname,FirstName}{scores}\relax
+\begin{tabular}{llr}
+\bfseries Surname &
+\bfseries First Name &
+\bfseries Score (\%)\relax
+\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\
+\surname & \firstname & \score}
+\end{tabular}
+\end{table}
+
+\begin{table}[htbp]
+\caption{Student scores (case ignored when
+sorting)}\label{tab:sortname3}
+\centering
+\DTLsort*{Surname,FirstName}{scores}\relax
+\begin{tabular}{llr}
+\bfseries Surname &
+\bfseries First Name &
+\bfseries Score (\%)\relax
+\DTLforeach{scores}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\
+\surname & \firstname & \score}
+\end{tabular}
+\end{table}
+
+\end{example}
+
+\begin{example}{Influencing the sort order}{ex:sortswitchargs}
+Consider the data displayed in \autoref{tab:sortname3}, suppose that
+you want the names ``van der Mere'' and ``de la Mere'' sorted
+according to the actual surname ``Mere'' rather than by the ``von
+part''. There are two ways you can do this: firstly, you could store
+the von part in a separate field, and then sort by surname, then von
+part, then first name, or you could define a command called, say,
+\cs{switchargs}, as follows:
+\begin{verbatim}
+\newcommand*{\switchargs}[2]{#2#1}
+\end{verbatim}
+\newcommand*{\switchargs}[2]{#2#1}\relax
+then store the data as:
+\begin{verbatim}
+FirstName,Surname,StudentNo,Score
+John,"Smith, Jr",102689,68
+Jane,Brown,102647,75
+Andy,Brown,103569,42
+Z\"oe,Adams,105987,52
+Roger,Brady,106872,58
+Clare,Verdon,104356,45
+Henk,\switchargs{Mere}{van der },106789,71
+Jos,\switchargs{Mere}{de la },104256,58
+\end{verbatim}
+\DTLnewdb{scores2}\relax
+\DTLnewrow{scores2}\relax
+\DTLnewdbentry{scores2}{FirstName}{John}\relax
+\DTLnewdbentry{scores2}{Surname}{Smith, Jr}\relax
+\DTLnewdbentry{scores2}{StudentNo}{102689}\relax
+\DTLnewdbentry{scores2}{Score}{68}\relax
+\DTLnewrow{scores2}\relax
+\DTLnewdbentry{scores2}{FirstName}{Jane}\relax
+\DTLnewdbentry{scores2}{Surname}{Brown}\relax
+\DTLnewdbentry{scores2}{StudentNo}{102647}\relax
+\DTLnewdbentry{scores2}{Score}{75}\relax
+\DTLnewrow{scores2}\relax
+\DTLnewdbentry{scores2}{FirstName}{Andy}\relax
+\DTLnewdbentry{scores2}{Surname}{Brown}\relax
+\DTLnewdbentry{scores2}{StudentNo}{103569}\relax
+\DTLnewdbentry{scores2}{Score}{42}\relax
+\DTLnewrow{scores2}\relax
+\DTLnewdbentry{scores2}{FirstName}{Z\"oe}\relax
+\DTLnewdbentry{scores2}{Score}{52}\relax
+\DTLnewdbentry{scores2}{StudentNo}{105987}\relax
+\DTLnewdbentry{scores2}{Surname}{Adams}\relax
+\DTLnewrow{scores2}\relax
+\DTLnewdbentry{scores2}{FirstName}{Roger}\relax
+\DTLnewdbentry{scores2}{Score}{58}\relax
+\DTLnewdbentry{scores2}{StudentNo}{106872}\relax
+\DTLnewdbentry{scores2}{Surname}{Brady}\relax
+\DTLnewrow{scores2}\relax
+\DTLnewdbentry{scores2}{FirstName}{Clare}\relax
+\DTLnewdbentry{scores2}{Score}{45}\relax
+\DTLnewdbentry{scores2}{StudentNo}{104356}\relax
+\DTLnewdbentry{scores2}{Surname}{Verdon}\relax
+\DTLnewrow{scores2}
+\DTLnewdbentry{scores2}{Surname}{\switchargs{Mere}{van der }}\relax
+\DTLnewdbentry{scores2}{FirstName}{Henk}\relax
+\DTLnewdbentry{scores2}{Score}{71}\relax
+\DTLnewrow{scores2}\relax
+\DTLnewdbentry{scores2}{Surname}{\switchargs{Mere}{de la }}\relax
+\DTLnewdbentry{scores2}{FirstName}{Jos}\relax
+\DTLnewdbentry{scores2}{Score}{58}\relax
+Now sort the data, and put it in table (this is the same code
+as in the previous example:
+\begin{verbatim}
+\begin{table}[htbp]
+\caption{Student scores (influencing the sort order)}
+\centering
+\DTLsort*{Surname,FirstName}{scores}%
+\begin{tabular}{llr}
+\bfseries Surname &
+\bfseries First Name &
+\bfseries Score (\%)%
+\DTLforeach{scores}{%
+\firstname=FirstName,\surname=Surname,\score=Score}{%
+\\
+\surname & \firstname & \score}
+\end{tabular}
+\end{table}
+\end{verbatim}
+This produces \autoref{tab:influencesort}.
+
+\begin{table}[htbp]
+\caption{Student scores (influencing the sort order)}\label{tab:influencesort}
+\centering
+\DTLsort*{Surname,FirstName}{scores2}\relax
+\begin{tabular}{llr}
+\bfseries Surname &
+\bfseries First Name &
+\bfseries Score (\%)\relax
+\DTLforeach{scores2}{\firstname=FirstName,\surname=Surname,\score=Score}{\relax
+\\
+\surname & \firstname & \score}
+\end{tabular}
+\end{table}
+
+\end{example}
+
+\section{Saving a Database to an External File}
+\label{sec:savedb}
+
+\begin{definition}[\DescribeMacro{\DTLsavedb}]%
+\cs{DTLsavedb}\marg{db name}\marg{filename}
+\end{definition}
+This writes the database called \meta{db name} to a file called
+\meta{filename}. The separator and delimiter characters used
+are as given by \ics{DTLsetseparator} (or \ics{DTLsettabseparator})
+and \ics{DTLsetdelimiter}. For example:
+\begin{verbatim}
+\DTLsettabdelimiter
+\DTLsavedb{scores}{scores.txt}
+\end{verbatim}
+will create a file called "scores.txt" and will save the data in a
+tab separated format. (The delimiters will only be used if a
+given entry contains the separator character.)
+
+\begin{definition}[\DescribeMacro{\DTLsavetexdb}]%
+\cs{DTLsavetexdb}\marg{db name}\marg{filename}
+\end{definition}
+This writes the database called \meta{db name} to a \LaTeX\ file
+called \meta{filename}, where the database is stored as
+a combination of \ics{DTLnewdb}, \ics{DTLnewrow} and
+\ics{DTLnewdbentry} commands.
+
+\section{Deleting or Clearing a Database}\label{sec:deletedb}
+
+A database can be cleared or deleted when its contents are no
+longer required.
+\begin{definition}[\DescribeMacro{\DTLcleardb}]
+\cs{DTLcleardb}\marg{db name}
+\end{definition}
+Clears the database given by \meta{db name}. The database is emptied
+but remains defined.
+
+\begin{definition}[\DescribeMacro{\DTLdeletedb}]
+\cs{DTLdeletedb}\marg{db name}
+\end{definition}
+Deletes (undefines) the database given by \meta{db name}.
+
+\section{Advanced Database Commands}
+\label{sec:advanced}
+
+This section describes more advanced commands. Further details
+can be found in the documented code (datatool.pdf).
+
+\begin{definition}[\DescribeMacro{\DTLgetdatatype}]
+\cs{DTLgetdatatype}\marg{cs}\marg{db}\marg{key}
+\end{definition}
+Gets the data type for the given key \meta{key} for the database
+given by \meta{db}. The data type is stored in \meta{cs} which
+must be a command name. The type will be one of:
+\begin{itemize}
+\item\DescribeMacro{\DTLunsettype}\cs{DTLunsettype} (not set),
+\item\DescribeMacro{\DTLstringtype}\cs{DTLstringtype} (string),
+\item\DescribeMacro{\DTLinttype}\cs{DTLinttype} (integer),
+\item\DescribeMacro{\DTLrealtype}\cs{DTLrealtype} (real number) or
+\item\DescribeMacro{\DTLcurrencytype}\cs{DTLcurrenttype} (currency).
+\end{itemize}
+
+\begin{definition}[\DescribeMacro{\dtlforeachkey}]%
+\cs{dtlforeachkey}(\meta{key cs},\meta{col cs},\meta{type
+cs},\meta{header cs})\cs{in}\marg{db}\cs{do}\marg{body}
+\end{definition}
+This iterates through all the keys in the database given by
+\meta{db}. In each iteration, \meta{key cs} is set to the key,
+\meta{col cs} is set to the column index, \meta{type cs} is set to
+the data type (as for \cs{DTLgetdatatype}), \meta{header cs} is set
+to the header for that column, and then \meta{body} is done. Note
+that \meta{key cs}, \meta{col cs}, \meta{type cs} and \meta{header
+cs} must all be control sequences. No check is performed to
+determine if that control sequence already exists, and the control
+sequences are defined globally (since it's likely that
+\cs{dtlforeachkey} may be used within a \env{tabular} environment),
+so you need to make sure you don't override an existing command of
+the same name.
+
+\begin{definition}[\DescribeMacro{\dtlforcolumn}]%
+\cs{dtlforcolumn}\marg{cs}\marg{db}\marg{key}\marg{body}
+\end{definition}
+This iterates through the column given by \meta{key} in the
+database given by \meta{db} and applies \meta{body}. In each
+iteration, \meta{cs} (which must be a control sequence) is set to
+the current element in the column and may be used in \meta{body}.
+Alternatively, if you want to identify the column by its index
+rather than its key, use:
+\begin{definition}[\DescribeMacro{\dtlforcolumnindex}]%
+\cs{dtlforcolumnindex}\marg{cs}\marg{db}\marg{col index}\marg{body}
+\end{definition}
+
+\begin{definition}[\DescribeMacro{\DTLifdbexists}]
+\cs{DTLifdbexists}\marg{db name}\marg{true part}\marg{false part}
+\end{definition}
+Determines if the database given by \meta{db name} exists.
+
+\begin{definition}[\DescribeMacro{\DTLifhaskey}]
+\cs{DTLifhaskey}\marg{db name}\marg{key}\marg{true part}\marg{false part}
+\end{definition}
+This determines if the database given by \meta{db name} has
+any entries with the key given by \meta{key}. If so, it does
+\meta{true part} otherwise it does \meta{false part}.
+
+Each key has an associated column index. This can be obtained
+using:
+\begin{definition}[\DescribeMacro{\DTLgetcolumnindex}]
+\cs{DTLgetcolumnindex}\marg{cs}\marg{db}\marg{key}
+\end{definition}
+where \meta{cs} is a command name, \meta{db} is the database label
+and \meta{key} is the key. The column index is stored in
+\meta{cs}.
+
+You can also do the reverse and find the key associated with a
+given column index:
+\begin{definition}[\DescribeMacro{\DTLgetkeyforcolumn}]
+\cs{DTLgetkeyforcolumn}\marg{key cs}\marg{db}\marg{column index}
+\end{definition}
+The key is stored in \meta{key cs} (which must be a command name).
+
+There is also a full expandable way of obtaining the column
+index, but note that no check is performed to determine
+if the database exists, or if it contains the given key:
+\begin{definition}[\DescribeMacro{\dtlcolumnindex}]
+\cs{dtlcolumnindex}\marg{db name}\marg{key}
+\end{definition}
+
+\begin{definition}[\DescribeMacro{\DTLgetkeydata}]
+\cs{DTLgetkeydata}\marg{key}\marg{db}\marg{col cs}\marg{type cs}\marg{header cs}
+\end{definition}
+Gets data for given key in database \meta{db}: the column index is
+stored in \meta{col cs} (as \cs{DTLgetcolumnindex}), the type is
+stored in \meta{type cs} (as \cs{DTLgetdatatype}) and the header
+is stored in \meta{header cs}.
+
+\begin{definition}[\DescribeMacro{\DTLgetvalue}]
+\cs{DTLgetvalue}\marg{cs}\marg{db}\marg{r}\marg{c}
+\end{definition}
+This gets the value for row given by index \meta{r} and column
+given by \meta{c} for the database \meta{db} and stores it in
+\meta{cs} which must be a command name. If you want to get the
+value by key rather than column index you can use
+\cs{dtlcolumnindex}. For example, the following gets the value
+for row~3 with key \texttt{Surname} from the database
+\texttt{data} and stores in \cs{myval}:
+\begin{verbatim}
+\DTLgetvalue{\myval}{data}{3}{\dtlcolumnindex{data}{Surname}}
+\end{verbatim}
+
+\begin{definition}[\DescribeMacro{\DTLgetlocation}]
+\cs{DTLgetlocation}\marg{row cs}\marg{column cs}\marg{database}%
+\marg{value}
+\end{definition}
+Assigns \meta{row cs} and \meta{column cs} to the indices of the
+first entry in \meta{database} that matches \meta{value}.
+
+\begin{definition}[\DescribeMacro{\DTLgetvalueforkey}]
+\cs{DTLgetvalueforkey}\marg{cmd}\marg{key}\marg{db name}\marg{ref
+ key}\marg{ref value}
+\end{definition}
+This (globally) sets \meta{cmd} (a control sequence) to the
+value of the key specified by \meta{key} in the first row
+of the database called \meta{db name} which contains the key
+\meta{ref key} which has the value \meta{value}.
+
+\begin{definition}[\DescribeMacro{\DTLassign}]
+\cs{DTLassign}\marg{db name}\marg{row idx}\marg{assign list}
+\end{definition}
+This (globally) assigns the list of commands in \meta{assign list}
+for row \meta{row idx} in database \meta{db name}, where
+\meta{assign list} has the same format as in \ics{DTLforeach}.
+
+Two rows can be swapped using:
+\begin{definition}[\DescribeMacro{\DTLswaprows}]%
+\cs{DTLswaprows}\marg{db name}\marg{row1 index}\marg{row2 index}
+\end{definition}
+where \meta{row1 index} and \meta{row2 index} are the indices
+of the rows to be swapped. For example:
+\begin{verbatim}
+\DTLswaprows{scores}{3}{5}
+\end{verbatim}
+will swap the third and fifth rows.
+
+\begin{definition}[\DescribeMacro{\DTLifinlist}]
+\cs{DTLifinlist}\marg{element}\marg{list}\marg{true part}\marg{false part}
+\end{definition}
+If \meta{element} is contained in the comma-separated list given
+by \meta{list}, then do \meta{true part} otherwise do false
+part. (Does a one level expansion on \meta{list}, but no
+expansion on \meta{element}.)
+
+\begin{definition}[\DescribeMacro{\DTLnumitemsinlist}]
+\cs{DTLnumitemsinlist}\marg{list}\marg{cmd}
+\end{definition}
+Counts the number of non-empty elements in \meta{list} and stores
+result in \meta{cmd}, which must be a control sequence.
+
+\begin{example}{Two Database Rows Per Tabular Row
+(Column-Wise)}{ex:twoblocks}
+This example adapts \autoref{ex:2rows} so that the list is ordered
+vertically rather than horizontally.
+\begin{verbatim}
+\begin{table}[htbp]
+ \caption{Two database rows per tabular row (column-wise)}
+ \centering
+ % store half number of rows
+ \edef\maxrows{\DTLrowcount{scores}}%
+ \DTLdiv{\halfrowidx}{\maxrows}{2}
+ \begin{tabular}{llcllc}
+ \bfseries First Name &
+ \bfseries Surname &
+ \bfseries Score (\%) &
+ \bfseries First Name &
+ \bfseries Surname &
+ \bfseries Score (\%)%
+ \DTLforeach*[\value{DTLrowi}<\halfrowidx]{scores}%
+ {\firstname=FirstName,\surname=Surname,\score=Score}%
+ {%
+ \\%
+ \firstname & \surname & \score
+ &
+ \edef\currentrowidx{\arabic{DTLrowi}}%
+ \DTLadd{\rowidxII}{\halfrowidx}{\currentrowidx}%
+ \DTLassign{scores}{\rowidxII}%
+ {\firstnameII=FirstName,\surnameII=Surname,\scoreII=Score}%
+ \firstnameII & \surnameII & \scoreII
+ }%
+ \end{tabular}
+\end{table}
+\end{verbatim}
+
+This produces \autoref{tab:twoblocks}.
+
+\begin{table}[htbp]
+ \caption{Two database rows per tabular row (column-wise)}
+ \label{tab:twoblocks}
+ \centering
+ % store half number of rows
+ \edef\maxrows{\DTLrowcount{scores}}%
+ \DTLdiv{\halfrowidx}{\maxrows}{2}
+ \begin{tabular}{llcllc}
+ \bfseries First Name &
+ \bfseries Surname &
+ \bfseries Score (\%) &
+ \bfseries First Name &
+ \bfseries Surname &
+ \bfseries Score (\%)%
+ \DTLforeach*[\value{DTLrowi}<\halfrowidx]{scores}%
+ {\firstname=FirstName,\surname=Surname,\score=Score}%
+ {%
+ \\%
+ \firstname & \surname & \score
+ &
+ \edef\currentrowidx{\arabic{DTLrowi}}%
+ \DTLadd{\rowidxII}{\halfrowidx}{\currentrowidx}%
+ \DTLassign{scores}{\rowidxII}{\firstnameII=FirstName,\surnameII=Surname,\scoreII=Score}%
+ \firstnameII & \surnameII & \scoreII
+ }%
+ \end{tabular}
+\end{table}
+\end{example}
+
+\subsection{Operating on Current Row}
+\label{sec:currentrow}
+
+If you want to select from or edit a particular row in a database without having
+to iterate through the database using \cs{DTLforeach}, you can use
+the commands described in this section.
+
+\begin{definition}[\DescribeMacro{\dtlgetrow}]
+\cs{dtlgetrow}\marg{db name}\marg{row idx}
+\end{definition}
+Gets the row with index \meta{row idx} from the database \meta{db
+name}. The required row is stored in the token register
+\begin{definition}[\DescribeMacro{\dtlcurrentrow}]
+\cs{dtlcurrentrow}
+\end{definition}
+the preceding rows are stored in the token register
+\begin{definition}[\DescribeMacro{\dtlbeforerow}]
+\cs{dtlbeforerow}
+\end{definition}
+the following rows are stored in the token register
+\begin{definition}[\DescribeMacro{\dtlafterrow}]
+\cs{dtlafterrow}
+\end{definition}
+the row index, \meta{row idx}, is stored in the register
+\begin{definition}[\DescribeMacro{\dtlrownum}]
+\cs{dtlrownum}
+\end{definition}
+and the database name is stored in the control sequence
+\begin{definition}[\DescribeMacro{\dtldbname}]
+\cs{dtldbname}
+\end{definition}
+\begin{important}
+No check is made in \cs{dtlgetrow} to see
+if the database exists or if the row index is valid. You will probably get a \qt{Missing \{
+inserted} error if you misspell the database name and a \qt{Runaway
+argument} error if you specify a row index that is out of range.
+\end{important}
+
+You can use the commands below to access or edit \cs{dtlcurrentrow}, but
+they won't change the database. Instead, once you've finished
+editing \cs{dtlcurrentrow}, you need to reconstruct the database
+token by recombining \cs{dtlbeforerow}, \cs{dtlcurrentrow} and
+\cs{dtlafterrow} using:
+\begin{definition}[\DescribeMacro{\dtlrecombine}]
+\cs{dtlrecombine}
+\end{definition}
+Alternatively, to recombine omitting the current row:
+\begin{definition}[\DescribeMacro{\dtlrecombineomitcurrent}]
+\cs{dtlrecombineomitcurrent}
+\end{definition}
+(This removes the current row from the database, shifting the row
+indices in \cs{dtlafterrow}.) Note that these recombining commands
+assume that you haven't altered \cs{dtlrownum}, \cs{dtldbname},
+\cs{dtlbeforerow} and \cs{dtlafterrow}.
+
+\begin{important}
+\cs{dtlcurrentrow} stores the row information using \sty{datatool}'s
+internal row syntax, described in the documented code (datatool.pdf).
+Don't explicitly modify \cs{dtlcurrentrow} unless you have a good
+understanding of the syntax.
+\end{important}
+
+\begin{definition}[\DescribeMacro{\dtlgetentryfromcurrentrow}]
+\cs{dtlgetentryfromcurrentrow}\marg{cs}\marg{col idx}
+\end{definition}
+Gets the value from \cs{dtlcurrentrow} for the column given by
+\meta{col idx} (an integer) and stores in \meta{cs}, which must be a
+control sequence.
+
+\begin{definition}[\DescribeMacro{\dtlreplaceentryincurrentrow}]
+\cs{dtlreplaceentryincurrentrow}\meta{new value}\marg{col idx}
+\end{definition}
+Replaces the value in \cs{dtlcurrentrow} for the column given by
+\meta{col idx} (an integer) with \meta{new value}.
+\begin{important}
+The new value doesn't get expanded.
+\end{important}
+
+\begin{definition}[\DescribeMacro{\dtlremoveentryincurrentrow}]
+\cs{dtlremoveentryincurrentrow}\marg{col idx}
+\end{definition}
+Removes the value in \cs{dtlcurrentrow} for the column given by
+\meta{col idx}.
+
+\begin{definition}[\DescribeMacro{\dtlswapentriesincurrentrow}]
+\cs{dtlswapentriesincurrentrow}\marg{col1 idx}\marg{col2 idx}
+\end{definition}
+Swaps entries in columns \meta{col1 idx} and \meta{col2 idx} in
+\cs{dtlcurrentrow} (where \meta{col1 idx} and \meta{col2 idx} are
+the column indices).
+
+\begin{definition}[\DescribeMacro{\dtlappendentrytocurrentrow}]
+\cs{dtlappendentrytocurrentrow}\marg{key}\marg{value}
+\end{definition}
+Appends \meta{value} to the current row for column given by
+\meta{key}. (Note this is the only command in this section to
+reference by key rather than by index.)
+
+\chapter{Pie Charts (\texorpdfstring{\sty{datapie}}{datapie} package)}
+\label{sec:datapie}
+
+The \sty{datapie} package is not loaded by the \sty{datatool} package,
+so you need to explicitly load \sty{datapie} if you want to use any of the
+commands defined in this section. You will also need to have the
+\sty{pgf}/\sty{tikz} packages installed. The \sty{datapie} package
+may be given the following options:
+\begin{description}
+\item[{\pkgopt[datapie]{color}}] Colour option (default).
+\item[{\pkgopt[datapie]{gray}}] Grey scale option.
+\item[{\pkgopt[datapie]{rotateinner}}]
+Rotate inner labels so that they are aligned
+with the pie chart radial axis.
+\item[{\pkgopt[datapie]{norotateinner}}]
+Don't rotate inner labels (default).
+\item[{\pkgopt[datapie]{rotateouter}}]
+Rotate outer labels so that they are aligned
+with the pie chart radial axis.
+\item[{\pkgopt[datapie]{norotateouter}}]
+Don't rotate outer labels (default).
+\end{description}
+
+Numerical information contained in a database created by the
+\sty{datatool} package can be converted into a pie chart using
+\begin{definition}[\DescribeMacro{\DTLpiechart}]%
+\cs{DTLpiechart}\oarg{condition}\marg{settings list}\marg{db name}\marg{values}
+\end{definition}\noindent
+where \meta{db name} is the name of the database, and
+\meta{condition} has the same form as the optional argument
+to \ics{DTLforeach} described in \autoref{sec:dbforeach}. If
+\meta{condition} is false, that information is omitted from the
+construction of the pie chart. The argument \meta{values} is a
+comma separated list of \meta{cmd}"="\meta{key} pairs, the same
+as that required by the penultimate argument of \ics{DTLforeach}.
+The \meta{settings list} is a comma separated list of
+\meta{setting}=\meta{value} pairs, where \meta{setting} can be any of
+the following:
+\begin{description}
+\item[\csopt{DTLpiechart}{variable}]
+This specifies the control sequence to use that
+contains the value used to construct the pie chart. The control
+sequence must be one of the control sequences to appear in
+the assignment list \meta{values}. This setting is required.
+
+\item[\csopt{DTLpiechart}{start}]
+This is the starting angle of the first segment. The
+value is 0 by default.
+
+\item[\csopt{DTLpiechart}{radius}]
+This is the radius of the pie chart. The default value
+is 2cm.
+
+\item[\csopt{DTLpiechart}{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 ratio. The default value is 0.5.
+
+\item[\csopt{DTLpiechart}{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 ratio. The default value is 1.25.
+
+\item[\csopt{DTLpiechart}{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. The default value is 0.2.
+
+\item[\csopt{DTLpiechart}{inneroffset}]
+This is the absolute distance from the centre
+of the pie chart to the point where the inner labels are placed.
+You should use only one or other of \csopt{DTLpiechart}{innerratio}
+and \csopt{DTLpiechart}{inneroffset}, not both. If you also want to
+specify the radius, you must use \csopt{DTLpiechart}{ratio}
+before \csopt{DTLpiechart}{inneroffset}. If omitted, the inner
+offset is obtained from the ratio multiplied by the
+\csopt{DTLpiechart}{innerratio} value.
+
+\item[\csopt{DTLpiechart}{outeroffset}]
+This is the absolute distance from the centre
+of the pie chart to the point where the outer labels are placed.
+You should use only one or other of \csopt{DTLpiechart}{outerratio}
+and \csopt{DTLpiechart}{outeroffset}, not both. If you also want to
+specify the radius, you must use \csopt{DTLpiechart}{ratio}
+before \csopt{DTLpiechart}{outeroffset}. If omitted, the outer
+offset is obtained from the ratio multiplied by the
+\csopt{DTLpiechart}{outerratio} value.
+
+\item[\csopt{DTLpiechart}{cutawayoffset}]
+This is the absolute distance from the centre of
+the pie chart to the point of the cutaway segments. You should use
+only one or other of \csopt{DTLpiechart}{cutawayratio} and
+\csopt{DTLpiechart}{cutawayoffset}, not both. If
+you also want to specify the radius, you must use
+\csopt{DTLpiechart}{ratio} before
+\csopt{DTLpiechart}{cutawayoffset}. If omitted, the cutaway offset
+is obtained from the ratio multiplied by the
+\csopt{DTLpiechart}{cutawayratio} value.
+
+\item[\csopt{DTLpiechart}{cutaway}]
+This is a 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, offset
+by the value of the \csopt{DTLpiechart}{cutawayoffset} setting,
+whereas "cutaway={1-3}" will separate the
+first three segments from the rest of the pie chart. If omitted,
+the pie chart will be whole.
+
+\item[\csopt{DTLpiechart}{innerlabel}]
+The value of this is positioned in the middle of each segment at a
+distance of \csopt{DTLpiechart}{inneroffset} from the centre
+of the pie chart. The default is the same as the value of
+\csopt{DTLpiechart}{variable}.
+
+\item[\csopt{DTLpiechart}{outerlabel}]
+The value of this is positioned at a distance of
+\csopt{DTLpiechart}{outeroffset} from the centre of the pie chart.
+The default is empty.
+
+\item[\csopt{DTLpiechart}{rotateinner}] This is a boolean setting,
+so it can only take the values "true" and "false". If the value is
+omitted "true" is assumed. If true, the inner labels are rotated
+along the spokes of the pie chart, otherwise the inner labels are not
+rotated. There are analogous package options
+\pkgopt[datapie]{rotateinner} and \pkgopt[datapie]{norotateinner}.
+
+\item[\csopt{DTLpiechart}{rotateouter}]
+This is a boolean setting, so it can only take
+the values "true" and "false". If the value is omitted "true" is
+assumed. If true, the outer labels are rotated along the spokes of
+the pie chart, otherwise the outer labels are not rotated.
+There are analogous package options
+\pkgopt[datapie]{rotateouter} and \pkgopt[datapie]{norotateouter}.
+
+\end{description}
+
+\begin{example}{A Pie Chart}{ex:piechart}
+This example loads data from a file called "fruit.csv" which contains
+the following:
+\begin{verbatim}
+Name,Quantity
+"Apples",30
+"Pears",25
+"Lemons,Limes",40.5
+"Peaches",34.5
+"Cherries",20
+\end{verbatim}
+First load the data:
+\begin{verbatim}
+\DTLloaddb{fruit}{fruit.csv}
+\end{verbatim}
+\DTLnewdb{fruit}\relax
+\DTLnewrow{fruit}\relax
+\DTLnewdbentry{fruit}{Name}{Apples}\relax
+\DTLnewdbentry{fruit}{Quantity}{30}\relax
+\DTLnewrow{fruit}\relax
+\DTLnewdbentry{fruit}{Name}{Pears}\relax
+\DTLnewdbentry{fruit}{Quantity}{25}\relax
+\DTLnewrow{fruit}\relax
+\DTLnewdbentry{fruit}{Name}{Lemons,Limes}\relax
+\DTLnewdbentry{fruit}{Quantity}{40.5}\relax
+\DTLnewrow{fruit}\relax
+\DTLnewdbentry{fruit}{Name}{Peaches}\relax
+\DTLnewdbentry{fruit}{Quantity}{34.5}\relax
+\DTLnewrow{fruit}\relax
+\DTLnewdbentry{fruit}{Name}{Cherries}\relax
+\DTLnewdbentry{fruit}{Quantity}{20}\relax
+Now create a pie chart in a figure:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity}{fruit}{\name=Name,\quantity=Quantity}
+\caption{A pie chart}
+\end{figure}
+\end{verbatim}
+This creates \autoref{fig:piechart}.
+
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity}{fruit}{\name=Name,\quantity=Quantity}
+\caption{A pie chart}
+\label{fig:piechart}
+\end{figure}
+
+There are no outer labels by default, but they can be set
+using the \csopt{DTLpiechart}{outerlabel} setting.
+The following sets the outer label to the value of the "Name" key:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name}{fruit}{%
+\name=Name,\quantity=Quantity}
+\caption{A pie chart (outer labels set)}
+\end{figure}
+\end{verbatim}
+This creates \autoref{fig:piechartouter}.
+
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name}{fruit}
+{\name=Name,\quantity=Quantity}
+\caption{A pie chart (outer labels set)}
+\label{fig:piechartouter}
+\end{figure}
+
+You may prefer the labels to be rotated. The following
+switches on the rotation for the inner and outer labels:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name,%
+rotateinner,rotateouter}{fruit}{%
+\name=Name,\quantity=Quantity}
+\caption{A pie chart (rotation enabled)}
+\end{figure}
+\end{verbatim}
+This creates \autoref{fig:piechartrot}.
+
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name
+,rotateinner,rotateouter}{fruit}
+{\name=Name,\quantity=Quantity}
+\caption{A pie chart (rotation enabled)}
+\label{fig:piechartrot}
+\end{figure}
+\end{example}
+
+\begin{example}{Separating Segments from the Pie Chart}{ex:cutaway}
+You may want to separate one or more segments from the pie chart,
+perhaps to emphasize them. You can do this using the
+\csopt{DTLpiechart}{cutaway}
+setting. The following separates the first and third segments
+from the pie chart:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name,%
+cutaway={1,3}}{fruit}{%
+\name=Name,\quantity=Quantity}
+\caption{A pie chart with cutaway segments}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:piecutaway}.
+
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name
+,cutaway={1,3}}{fruit}{\name=Name,\quantity=Quantity}
+\caption{A pie chart with cutaway segments}
+\label{fig:piecutaway}
+\end{figure}
+
+Alternatively I can specify a range of segments. The following
+separates the first two segments:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name,%
+cutaway={1-2}}{fruit}{%
+\name=Name,\quantity=Quantity}
+\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1-2\}})}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:piecutaway2}.
+
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name
+,cutaway={1-2}}{fruit}{\name=Name,\quantity=Quantity}
+\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1-2\}})}
+\label{fig:piecutaway2}
+\end{figure}
+
+Notice the difference between \autoref{fig:piecutaway2} and
+\autoref{fig:piecutaway3} which was produced using:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name,%
+cutaway={1,2}}{fruit}{%
+\name=Name,\quantity=Quantity}
+\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1,2\}})}
+\end{figure}
+\end{verbatim}
+
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,outerlabel=\name
+,cutaway={1,2}}{fruit}{\name=Name,\quantity=Quantity}
+\caption{A pie chart with cutaway segments (\texttt{cutaway=\{1,2\}})}
+\label{fig:piecutaway3}
+\end{figure}
+
+\end{example}
+
+\section{Pie Chart Variables}
+
+\begin{definition}[\DescribeMacro{\DTLpievariable}]%
+\cs{DTLpievariable}
+\end{definition}
+This command is set to the variable given by the
+\csopt{DTLpiechart}{variable} setting in the \meta{settings list}
+argument of \cs{DTLpiechart}. The \csopt{DTLpiechart}{innerlabel}
+is set to \cs{DTLpievariable} by default.
+
+\begin{definition}[\DescribeMacro{\DTLpiepercent}]%
+\cs{DTLpiepercent}
+\end{definition}
+This command is set to the percentage value of \cs{DTLpievariable}.
+The percentage value is rounded to \meta{n} digits, where \meta{n}
+is the value of the \LaTeX\ counter
+\desctr{DTLpieroundvar}.
+
+\begin{example}{Changing the Inner and Outer Labels}{ex:pielabels}
+This example uses the database defined in \autoref{ex:piechart}.
+The inner label is now set to the percentage value, rather than
+the actual value, and the outer label is set to the name with
+the actual value in parentheses.
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,%
+innerlabel={\DTLpiepercent\%},%
+outerlabel={\name\ (\DTLpievariable)}}{fruit}{%
+\name=Name,\quantity=Quantity}
+\caption{A pie chart (changing the labels)}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:piechartlabels}.
+
+\begin{figure}[htbp]
+\centering
+\DTLpiechart{variable=\quantity,innerlabel={\DTLpiepercent
+\%},outerlabel={\name\ (\DTLpievariable)}}{fruit}{\name=Name,\quantity=Quantity}
+\caption{A pie chart (changing the labels)}
+\label{fig:piechartlabels}
+\end{figure}
+\end{example}
+
+\section{Pie Chart Label Formatting}
+
+\begin{definition}[\DescribeMacro{\DTLdisplayinnerlabel}]%
+\cs{DTLdisplayinnerlabel}\marg{text}
+\end{definition}
+This governs how the inner label is formatted, where \meta{text}
+is the text of the inner label. The default is to just do \meta{text}.
+
+\begin{definition}[\DescribeMacro{\DTLdisplayouterlabel}]%
+\cs{DTLdisplayouterlabel}\marg{text}
+\end{definition}
+This governs how the outer label is formatted, where \meta{text}
+is the text of the outer label. The default is to just do \meta{text}.
+
+\begin{example}{Changing the Inner and Outer Label
+Format}{ex:pielabelformat}
+This example extends \autoref{ex:pielabels}.
+The inner and outer labels are now both typeset in a sans-serif
+font:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}}
+\renewcommand*{\DTLdisplayouterlabel}[1]{\textsf{#1}}
+\DTLpiechart{variable=\quantity,%
+innerlabel={\DTLpiepercent\%},%
+outerlabel={\name\ (\DTLpievariable)}}{fruit}{%
+\name=Name,\quantity=Quantity}
+\caption{A pie chart (changing the label format)}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:piechartlabelformat}.
+
+\begin{figure}[htbp]
+\centering
+\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}}
+\renewcommand*{\DTLdisplayouterlabel}[1]{\textsf{#1}}
+\DTLpiechart{variable=\quantity,innerlabel={\DTLpiepercent
+\%},outerlabel={\name\ (\DTLpievariable)}}{fruit}{\name=Name,\quantity=Quantity}
+\caption{A pie chart (changing the label format)}
+\label{fig:piechartlabelformat}
+\end{figure}
+\end{example}
+
+\section{Pie Chart Colours}
+
+The \sty{datapie} package predefines colours for the first
+eight segments of the pie chart. If you require more than
+eight segments or if you want to change the default colours, you
+will need to use
+\begin{definition}[\DescribeMacro{\DTLsetpiesegmentcolor}]%
+\cs{DTLsetpiesegmentcolor}\marg{n}\marg{color}
+\end{definition}\noindent
+The first argument \meta{n} is the segment index (starting from 1),
+and the second argument \meta{color} is a colour specifier as used
+in commands such as \cs{color}.
+
+It is a good idea to set the colours so that each segment colour
+is somehow relevant to whatever the segment represents. For
+example, in the previous examples of pie charts depicting fruit,
+some of default colours were inappropriate. Whilst red is
+appropriate for apples and green is appropriate for pears, blue
+doesn't really correspond to lemons or limes.
+
+\begin{definition}[\DescribeMacro{\DTLdopiesegmentcolor}]%
+\cs{DTLdopiesegmentcolor}\meta{n}
+\end{definition}
+This sets the current text colour to that of the \meta{n}th
+segment.
+
+\begin{definition}[\DescribeMacro{\DTLdocurrentpiesegmentcolor}]%
+\cs{DTLdocurrentpiesegmentcolor}
+\end{definition}
+This sets the current text colour to that of the current pie
+segment. This command may only be used within a pie chart, or
+within the body of \ics{DTLforeach}.
+
+\begin{definition}[\DescribeMacro{\DTLpieoutlinecolor}]%
+\cs{DTLpieoutlinecolor}
+\end{definition}
+This sets the outline colour for the pie chart. The default is
+black.
+
+\begin{definition}[\DescribeMacro{\DTLpieoutlinewidth}]%
+\cs{DTLpieoutlinewidth}
+\end{definition}
+This is a length that governs the line width of the outline. The
+default value is 0pt, but can be changed using \cs{setlength}.
+The outline is only drawn if \cs{DTLpieoutlinewidth} is greater
+than 0pt.
+
+\begin{example}{Pie Segment Colours}{ex:piecolours}
+This example extends \autoref{ex:pielabelformat}.
+It sets the outline thickness to 2pt, and
+the outer label is now set in the same colour as the fill colour
+of the segment to which it belongs. The third segment (lemons and
+limes) is set to yellow and the fourth segment (peaches) is set
+to pink. In addition, a legend is created using \ics{DTLforeach}.
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\setlength{\DTLpieoutlinewidth}{2pt}
+\DTLsetpiesegmentcolor{3}{yellow}
+\DTLsetpiesegmentcolor{4}{pink}
+\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}}
+\renewcommand*{\DTLdisplayouterlabel}[1]{%
+\DTLdocurrentpiesegmentcolor
+\textsf{\shortstack{#1}}}
+\DTLpiechart{variable=\quantity,%
+innerlabel={\DTLpiepercent\%},%
+outerlabel={\name\\(\DTLpievariable)}}{fruit}{%
+\name=Name,\quantity=Quantity}
+\begin{tabular}[b]{ll}
+\DTLforeach{fruit}{\name=Name}{\DTLiffirstrow{}{\\}%
+\DTLdocurrentpiesegmentcolor\rule{10pt}{10pt} &
+\name
+}
+\end{tabular}
+\caption{A pie chart (using segment colours and outline)}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:piesegcolour}. (The format of the
+outer label has been changed to use \cs{shortstack} to
+prevent the outer labels from taking up so much horizontal
+space. The \csopt{DTLpiechart}{outerlabel} setting has also been
+modified to use "\\" after the name to move the percentage value onto
+the next row.)
+
+\begin{figure}[htbp]
+\centering
+\setlength{\DTLpieoutlinewidth}{2pt}
+\DTLsetpiesegmentcolor{3}{yellow}
+\DTLsetpiesegmentcolor{4}{pink}
+\renewcommand*{\DTLdisplayinnerlabel}[1]{\textsf{#1}}
+\renewcommand*{\DTLdisplayouterlabel}[1]{\relax
+\DTLdocurrentpiesegmentcolor
+\textsf{\shortstack{#1}}}
+\DTLpiechart{variable=\quantity,innerlabel={\DTLpiepercent
+\%},outerlabel={\name\\(\DTLpievariable)}}{fruit}{\name=Name,\quantity=Quantity}
+\begin{tabular}[b]{ll}
+\DTLforeach{fruit}{\name=Name}{\DTLiffirstrow{}{\\}\relax
+\DTLdocurrentpiesegmentcolor\rule{10pt}{10pt} &
+\name
+}
+\end{tabular}
+\caption{A pie chart (using segment colours and outline)}
+\label{fig:piesegcolour}
+\end{figure}
+\end{example}
+
+\section{Adding Extra Commands Before and After the Pie Chart}
+
+The pie charts created using \ics{DTLpiechart} are placed inside
+a \env{tikzpicture} environment (defined by the \sty{tikz} package).
+
+\begin{definition}[\DescribeMacro{\DTLpieatbegintikz}]%
+\cs{DTLpieatbegintikz}
+\end{definition}
+The macro \cs{DTLpieatbegintikz} is called at the start of the
+\env{tikzpicture} environment, allowing you to change the
+\env{tikzpicture} settings. By default \cs{DTLpieatbegintikz}
+does nothing, but you can redefine it to, say, scale the pie
+chart (but be careful not to distort the chart).
+
+\begin{definition}[\DescribeMacro{\DTLpieatendtikz}]%
+\cs{DTLpieatendtikz}
+\end{definition}
+The macro \cs{DTLpieatendtikz} is called at the end of the
+\env{tikzpicture} environment, allowing you add additional
+graphics to the pie chart. This does nothing by default.
+
+\begin{example}{Adding Information to the Pie Chart}{ex:piescale}
+This example modifies \autoref{ex:piechart}. It redefines
+\cs{DTLpieatendtikz} to add an annotated arrow.
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\renewcommand*{\DTLpieatendtikz}{%
+\draw[<-] (45:1.5cm) -- (40:2.5cm)node[right]{Apples};}
+\DTLpiechart{variable=\quantity}{fruit}{%
+\name=Name,\quantity=Quantity}
+\caption{An annotated pie chart}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:pieannote}. (Note that the centre
+of the pie chart is the origin of the TikZ picture.)
+
+\begin{figure}[htbp]
+\centering
+\renewcommand*{\DTLpieatendtikz}{%
+\draw[<-] (45:1.5cm) -- (40:2.5cm)node[right]{Apples};}
+\DTLpiechart{variable=\quantity}{fruit}{\name=Name,\quantity=Quantity}
+\caption{An annotated pie chart}
+\label{fig:pieannote}
+\end{figure}
+\end{example}
+
+\chapter{Scatter and Line Plots (\texorpdfstring{\sty{dataplot}}{dataplot}
+package)}
+\label{sec:dataplot}
+
+The \sty{dataplot} package provides commands for creating
+scatter or line plots from databases. It uses the pgf/TikZ plot
+handler library to create the plots. See the \sty{pgf} manual for
+more detail on pgf streams and plot handles. The \sty{dataplot}
+package is not loaded by \sty{datatool} so if you want to use
+it you need to load it explicitly using "\usepackage{dataplot}".
+
+
+\begin{definition}[\DescribeMacro{\DTLplot}]%
+\cs{DTLplot}\oarg{condition}\marg{db list}\marg{settings}
+\end{definition}
+This command creates a plot (inside a \env{tikzpicture} environment)
+of all the data given in the databases listed in \meta{db list},
+which should be a comma separated list of database names.
+The optional argument \meta{condition} is the same as that for
+\ics{DTLforeach}. The \meta{settings} argument is a comma separated
+list of \meta{setting}"="\meta{value} pairs. There are two settings
+that must be specified \csopt{DTLplot}{x} and \csopt{DTLplot}{y}.
+The other settings are optional. Note that any value that contains
+a comma, must be enclosed in braces. For example
+"colors={red,cyan,blue}". Note where any setting requires
+a number, or list of numbers (such as \csopt{DTLplot}{bounds})
+the number must be supplied in standard decimal notation (i.e.\
+no currency, no number groups, and a full stop as the decimal
+point). Available settings are as follows:
+\begin{description}
+\item[\csopt{DTLplot}{x}] The database key
+that specifies the $x$ co-ordinates. This setting is required.
+
+\item[\csopt{DTLplot}{y}] The database key that specifies
+the $y$ co-ordinates. This setting is required.
+
+\item[\csopt{DTLplot}{markcolors}] A comma separated list of colour
+names for the markers. An empty value will use the current colour.
+
+\item[\csopt{DTLplot}{linecolors}] A comma separated list of colour
+names for the plot lines. An empty value will use the current colour.
+
+\item[\csopt{DTLplot}{colors}] A comma separated list of colour
+names for the lines and markers.
+
+\item[\csopt{DTLplot}{marks}] A comma separated list of
+code to generate plot marks. (This should typically be a list
+of \cs{pgfuseplotmark} commands, see the \sty{pgf} manual for
+further details.) You may use \cs{relax} as an element
+of the list to suppress markers for the corresponding plot.
+For example: "marks={\pgfuseplotmark{o},\relax}" will use an
+open circle marker for the first database, and no markers for the
+second database listed in \meta{db list}.
+
+\item[\csopt{DTLplot}{lines}] A comma separated list of
+line style settings. (This should typically be a list of
+\cs{pgfsetdash} commands, see the \sty{pgf} manual for
+further details on how to set the line style.) An empty value
+will use the current line style.
+You may use \cs{relax} as an element
+of the list to suppress line for the corresponding plot.
+For example: "lines={\relax,\pgfsetdash{}{0pt}}"
+will have no lines for the first database, and a solid line
+for the second database listed in \meta{db list}.
+
+\item[\csopt{DTLplot}{width}] The width of the plot. This must
+be a length. The plot width does not include outer tick marks or
+labels.
+
+\item[\csopt{DTLplot}{height}] The height of the plot. This must
+be a length. The plot height does not include outer tick marks
+or labels.
+
+\item[\csopt{DTLplot}{style}] This setting governs whether
+to use lines or markers in the plot, and may take one of
+the following values: "both" (lines and markers),
+"lines" (only lines) or "markers" (only markers). The default is
+"markers".
+
+\item[\csopt{DTLplot}{axes}] This setting governs whether
+to display the axes, and may take one of
+the following values: "both", "x", "y" or "none". If no value
+is specified, "both" is assumed.
+
+\item[\csopt{DTLplot}{box}] This setting governs whether
+or not to surround the plot in a box. It is a boolean setting,
+taking only the values "true" and "false". If no value is
+specified, "true" is assumed.
+
+\item[\csopt{DTLplot}{xtics}] This setting governs whether
+or not to display the $x$ tick marks. It is a boolean setting,
+taking only the values "true" and "false". If no value is
+specified "true" is assumed. If the \csopt{DTLplot}{axes}
+setting is set to "both" or "x", this value will automatically
+be set to "true", otherwise it will be set to "false".
+
+\item[\csopt{DTLplot}{ytics}] This setting governs whether
+or not to display the $y$ ticks. It is a boolean setting,
+taking only the values "true" and "false". If no value is
+specified "true" is assumed. If the \csopt{DTLplot}{axes}
+setting is set to "both" or "y", this value will automatically
+be set to "true", otherwise it will be set to "false".
+
+
+\item[\csopt{DTLplot}{xminortics}] This setting governs whether
+or not to display the $x$ minor tick marks. It is a boolean
+setting, taking only the values "true" and "false". If no value is
+specified "true" is assumed. This setting also sets the
+$x$ major tick marks on if the value is "true".
+
+\item[\csopt{DTLplot}{yminortics}] This setting governs whether
+or not to display the $y$ minor tick marks. It is a boolean
+setting, taking only the values "true" and "false". If no value is
+specified "true" is assumed. This setting also sets the
+$y$ major tick marks on if the value is "true".
+
+\item[\csopt{DTLplot}{xticdir}] This sets the $x$ tick direction,
+and may only take the values "in" or "out".
+
+\item[\csopt{DTLplot}{yticdir}] This sets the $y$ tick direction,
+and may only take the values "in" or "out".
+
+\item[\csopt{DTLplot}{ticdir}] This sets the $x$ and $y$ tick
+direction, and may only take the values "in" or "out".
+
+\item[\csopt{DTLplot}{bounds}] The value must be in the form
+\meta{min x}","\meta{min y}","\meta{max x}","\meta{max y}. This
+sets the graph bounds to the given values. If omitted the
+bounds are computed from the maximum and minimum values of the
+data. For example
+\begin{verbatim}
+\DTLplot{data1,data2}{x=Height,y=Weight,bounds={0,0,10,20}}
+\end{verbatim}
+Note that the \csopt{DTLplot}{bounds} setting overrides
+the \csopt{DTLplot}{minx}, \csopt{DTLplot}{maxx},
+\csopt{DTLplot}{miny} and \csopt{DTLplot}{maxy} settings.
+
+\item[\csopt{DTLplot}{minx}] The value is the minimum value
+of the $x$ axis.
+
+\item[\csopt{DTLplot}{miny}] The value is the minimum value
+of the $y$ axis.
+
+\item[\csopt{DTLplot}{maxx}] The value is the maximum value
+of the $x$ axis.
+
+\item[\csopt{DTLplot}{maxy}] The value is the maximum value
+of the $y$ axis.
+
+\item[\csopt{DTLplot}{xticpoints}] The value must be a comma
+separated list of decimal numbers indicating where to put the
+$x$ tick marks. If omitted, the $x$ tick marks are placed at
+equal intervals along the $x$ axis such that each interval is
+not less than the length given by \ics{DTLmintickgap}.
+This setting overrides \csopt{DTLplot}{xticgap}.
+
+\item[\csopt{DTLplot}{xticgap}] This value specifies the
+gap between the $x$ tick marks.
+
+\item[\csopt{DTLplot}{yticpoints}] The value must be a comma
+separated list of decimal numbers indicating where to put the
+$y$ tick marks. If omitted, the $y$ tick marks are placed at
+equal intervals along the $y$ axis such that each interval is
+not less than the length given by \ics{DTLmintickgap}.
+This setting overrides \csopt{DTLplot}{yticgap}.
+
+\item[\csopt{DTLplot}{yticgap}] This value specifies the
+gap between the $y$ tick marks.
+
+\item[\csopt{DTLplot}{grid}] This is a boolean value that
+specifies whether or not to display the grid. If no value
+is given, "true" is assumed. The minor grid lines are only
+displayed if the minor tick marks are set.
+
+\item[\csopt{DTLplot}{xticlabels}] The value must be a comma
+separated list of labels for each $x$ tick mark. If omitted,
+the labels are the value of the $x$ tick position, rounded
+\meta{n} digits after the decimal point, where \meta{n} is
+given by the value of the counter \ctr{DTLplotroundXvar}.
+
+\item[\csopt{DTLplot}{yticlabels}] The value must be a comma
+separated list of labels for each $y$ tick mark. If omitted,
+the labels are the value of the $y$ tick position, rounded
+\meta{n} digits after the decimal point, where \meta{n} is
+given by the value of the counter \ctr{DTLplotroundYvar}.
+
+\item[\csopt{DTLplot}{xlabel}] The value is the label for
+the $x$ axis. If omitted, the axis has no label.
+
+\item[\csopt{DTLplot}{ylabel}] The value is the label for
+the $y$ axis. If omitted, the axis has no label.
+
+\item[\csopt{DTLplot}{legend}] This setting governs whether
+or not to display the legend, and where it should be displayed.
+It may take one of the following values "none" (don't display
+the legend), "north", "northeast", "east", "southeast", "south",
+"southwest", "west" or "northwest". If the value is omitted,
+"northeast" is assumed.
+
+\item[\csopt{DTLplot}{legendlabels}] The value must be a comma
+separated list of labels for the legend. If omitted, the database
+names are used.
+
+\end{description}
+
+\begin{example}{A Basic Graph}{ex:basicplot}
+Suppose you have a file called "groupa.csv" that contains the
+following:
+\DTLnewdb{groupa}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.55}\relax
+\DTLnewdbentry{groupa}{Weight}{45.4}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.54}\relax
+\DTLnewdbentry{groupa}{Weight}{48.0}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.56}\relax
+\DTLnewdbentry{groupa}{Weight}{58.0}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.56}\relax
+\DTLnewdbentry{groupa}{Weight}{50.2}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.57}\relax
+\DTLnewdbentry{groupa}{Weight}{46.0}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.58}\relax
+\DTLnewdbentry{groupa}{Weight}{48.3}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.59}\relax
+\DTLnewdbentry{groupa}{Weight}{56.5}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.59}\relax
+\DTLnewdbentry{groupa}{Weight}{58.1}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.60}\relax
+\DTLnewdbentry{groupa}{Weight}{60.9}\relax
+\DTLnewrow{groupa}\relax
+\DTLnewdbentry{groupa}{Height}{1.62}\relax
+\DTLnewdbentry{groupa}{Weight}{56.3}\relax
+\begin{ttfamily}\obeylines\setlength{\parindent}{0pt}
+Height,Weight
+\DTLforeach{groupa}{\x=Height,\y=Weight}{\x,\y
+}\end{ttfamily}\par\noindent
+First load this into a database called "groupa":
+\begin{verbatim}
+\DTLloaddb{groupa}{groupa.csv}
+\end{verbatim}
+The data can now be converted into a scatter plot as follows:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLplot{groupa}{x=Height,y=Weight}
+\caption{A scatter plot}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:basicplot}.
+
+\begin{figure}[htbp]
+\centering
+\DTLplot{groupa}{x=Height,y=Weight}
+\caption{A scatter plot}
+\label{fig:basicplot}
+\end{figure}
+
+Alternatively, you can use the \csopt{DTLplot}{style} setting
+to change it into a line plot:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLplot{groupa}{x=Height,y=Weight,style=lines}
+\caption{A line plot}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:basiclineplot}.
+
+\begin{figure}[htbp]
+\centering
+\DTLplot{groupa}{x=Height,y=Weight,style=lines}
+\caption{A line plot}
+\label{fig:basiclineplot}
+\end{figure}
+\end{example}
+
+\begin{example}{Plotting Multiple Data Sets}{ex:2db}
+In this example, I shall use the database called "groupa" defined
+in \autoref{ex:basicplot}, and another database called "groupb"
+which is loaded from the file "groupb.csv" which contains the
+following:
+\DTLnewdb{groupb}
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.54}\relax
+\DTLnewdbentry{groupb}{Weight}{48.4}\relax
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.54}\relax
+\DTLnewdbentry{groupb}{Weight}{42.0}\relax
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.55}\relax
+\DTLnewdbentry{groupb}{Weight}{64.0}\relax
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.56}\relax
+\DTLnewdbentry{groupb}{Weight}{58.2}\relax
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.56}\relax
+\DTLnewdbentry{groupb}{Weight}{49.0}\relax
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.57}\relax
+\DTLnewdbentry{groupb}{Weight}{40.3}\relax
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.58}\relax
+\DTLnewdbentry{groupb}{Weight}{51.5}\relax
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.58}\relax
+\DTLnewdbentry{groupb}{Weight}{63.1}\relax
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.59}\relax
+\DTLnewdbentry{groupb}{Weight}{74.9}\relax
+\DTLnewrow{groupb}\relax
+\DTLnewdbentry{groupb}{Height}{1.59}\relax
+\DTLnewdbentry{groupb}{Weight}{59.3}\relax
+\begin{ttfamily}\obeylines\setlength{\parindent}{0pt}
+Height,Weight
+\DTLforeach{groupb}{\x=Height,\y=Weight}{\x,\y
+}\end{ttfamily}\par\noindent
+First load this into a database called "groupb":
+\begin{verbatim}
+\DTLloaddb{groupb}{groupb.csv}
+\end{verbatim}
+I can now plot both groups in the same graph, but I want a smaller
+graph than \autoref{fig:basicplot} and \autoref{fig:basiclineplot},
+so I am going to set the plot width and height to 3in:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLplot{groupa,groupb}{x=Height,y=Weight,width=3in,height=3in}
+\caption{A scatter plot}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:2db}.
+
+\begin{figure}[htbp]
+\centering
+\DTLplot{groupa,groupb}{x=Height,y=Weight,width=3in,height=3in}
+\caption[A scatter plot (multiple datasets)]{A scatter plot}
+\label{fig:2db}
+\end{figure}
+
+Now let's add a legend using the \csopt{DTLplot}{legend} setting,
+with the legend labels "Group A" and "Group B",
+and set the $x$ tick intervals using \csopt{DTLplot}{xticpoints}
+setting. I am also going to set the $x$ axis label to
+"Height (m)" and the $y$ axis label to "Weight (kg)", and place
+a box around the plot.
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLplot{groupa,groupb}{x=Height,y=Weight,
+width=3in,height=3in,legend,legendlabels={Group A,Group B},
+xlabel={Height (m)},ylabel={Weight (kg)},box,
+xticpoints={1.54,1.55,1.56,1.57,1.58,1.59,1.60,1.61,1.62}}
+\caption{A scatter plot}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:legend}.
+
+\begin{figure}[htbp]
+\centering
+\DTLplot{groupa,groupb}{x=Height,y=Weight,legend,
+width=3in,height=3in,legendlabels={Group A,Group B},
+xlabel={Height (m)},ylabel={Weight (kg)},box,
+xticpoints={1.54,1.55,1.56,1.57,1.58,1.59,1.60,1.61,1.62}}
+\caption[A scatter plot (with a legend)]{A scatter plot}
+\label{fig:legend}
+\end{figure}
+\end{example}
+
+\section{Adding Information to the Plot}
+
+The \sty{datatool} package provides two hooks used at the beginning
+and end of the \env{tikzpicture} environment:
+\begin{definition}[\DescribeMacro{\DTLplotatbegintikz}]%
+\cs{DTLplotatbegintikz}
+\end{definition}\noindent
+and
+\begin{definition}[\DescribeMacro{\DTLplotatendtikz}]%
+\cs{DTLplotatendtikz}
+\end{definition}
+They are both defined to do nothing by default, but can be redefined
+to add commands to the image. The unit vectors are set prior to
+using these hooks, so you can use the same co-ordinates as those
+in the data sets.
+
+\begin{definition}[\DescribeMacro{\DTLaddtoplotlegend}]%
+\cs{DTLaddtoplotlegend}\marg{marker}\marg{line style}\marg{text}
+\end{definition}
+This adds a new row to the plot legend where \meta{marker} is
+code to produce the marker, \meta{line style} is code to set
+the line style and \meta{text} is a textual label. You can
+use \cs{relax} to suppress the marker or line. For example:
+\begin{verbatim}
+\DTLaddtoplotlegend{\pgfuseplotmark{x}}{\relax}{Some Data}
+\end{verbatim}
+Note that the legend is plotted before \cs{DTLplotatendtikz},
+so if you want to add information to the legend you will need
+to do the in \cs{DTLplotatstarttikz}.
+
+\begin{example}{Adding Information to a Plot}{ex:addtoplot}
+Returning to the plots created in \autoref{ex:2db}, suppose
+I now want to annotate the plot, say I want to draw your notice
+to a particular point, say the point (1.58,48.3), then I can
+redefine \cs{DTLplotatendtikz} to draw an annotated arrow to
+that point:
+\begin{verbatim}
+\renewcommand*{\DTLplotatendtikz}{%
+\draw[<-,line width=1pt] (1.58,48.3) -- (1.6,43)
+ node[below]{interesting point};
+}
+\end{verbatim}
+So \autoref{fig:legend} now looks like \autoref{fig:annote}.
+(Obviously, \cs{DTLplotatendtikz} needs to be redefined before
+using \cs{DTLplot}.)
+
+\begin{figure}[htbp]
+\renewcommand*{\DTLplotatendtikz}{%
+\draw[<-,line width=1pt] (1.58,48.3) -- (1.6,43)
+ node[below]{interesting point};
+}
+\centering
+\DTLplot{groupa,groupb}{x=Height,y=Weight,legend,
+width=3in,height=3in,legendlabels={Group A,Group B},box,
+xlabel={Height (m)},ylabel={Weight (kg)},
+xticpoints={1.54,1.55,1.56,1.57,1.58,1.59,1.60,1.61,1.62}}
+\caption[A scatter plot (using the end plot hook to annotate the
+plot)]{A scatter plot}
+
+\label{fig:annote}
+\end{figure}
+\end{example}
+
+\section{Global Plot Settings}
+
+\subsection{Lengths}
+This section describes the lengths that govern the appearance of
+the plot created using \ics{DTLplot}. These lengths can be
+changed using \cs{setlength}.
+
+\begin{definition}[\DescribeMacro{\DTLplotwidth}]%
+\cs{DTLplotwidth}
+\end{definition}
+This length governs the length of the $x$ axis. Note that the plot
+width does not include any outer tick marks or labels. The default
+value is 4in.
+
+\begin{definition}[\DescribeMacro{\DTLplotheight}]%
+\cs{DTLplotheight}
+\end{definition}
+This length governs the length of the $y$ axis. Note that the plot
+height does not include any outer tick marks or labels. The default
+value is 4in
+
+\begin{definition}[\DescribeMacro{\DTLticklength}]%
+\cs{DTLticklength}
+\end{definition}
+This governs the length of the tick marks. The default value is
+5pt.
+
+\begin{definition}[\DescribeMacro{\DTLminorticklength}]%
+\cs{DTLminorticklength}
+\end{definition}
+This governs the length of the minor tick marks. The default value is
+2pt.
+
+\begin{definition}[\DescribeMacro{\DTLticklabeloffset}]%
+\cs{DTLticklabeloffset}
+\end{definition}
+This governs the distance from the axis to the tick labels. The
+default value is 8pt.
+
+\begin{definition}[\DescribeMacro{\DTLmintickgap}]%
+\cs{DTLmintickgap}
+\end{definition}
+This is the minimum distance allowed between tick marks. If the
+plot width or height is less than this distance there will only
+be tick marks at either end of the axis. The default value is
+20pt.
+
+\begin{definition}[\DescribeMacro{\DTLlegendxoffset}]%
+\cs{DTLlegendxoffset}
+\end{definition}
+This is the horizontal distance from the border of the plot to the
+outer border of the legend. The default value is 10pt.
+
+\begin{definition}[\DescribeMacro{\DTLlegendyoffset}]%
+\cs{DTLlegendyoffset}
+\end{definition}
+This is the vertical distance from the border of the plot to the
+outer border of the legend. The default value is 10pt.
+
+\subsection{Counters}
+These counters govern the appearance of plots
+created using \ics{DTLplot}. The value of the counters can be
+changed using \cs{setcounter}.
+
+\begin{definition}[\DescribeCounter{DTLplotroundXvar}]
+\ctrfmt{DTLplotroundXvar}
+\end{definition}
+Unless you specify your own tick labels, the $x$ tick labels will
+be given by the tick points rounded to \meta{n} digits after the
+decimal point, where \meta{n} is the value of the counter
+\ctrfmt{DTLplotroundXvar}.
+
+\begin{definition}[\DescribeCounter{DTLplotroundYvar}]
+\ctrfmt{DTLplotroundYvar}
+\end{definition}
+Unless you specify your own tick labels, the $y$ tick labels will
+be given by the tick points rounded to \meta{n} digits after the
+decimal point, where \meta{n} is the value of the counter
+\ctrfmt{DTLplotroundYvar}.
+
+\subsection{Macros}
+These macros govern the appearance of plots created using
+\ics{DTLplot}. They can be changed using \cs{renewcommand}.
+
+\begin{definition}[\DescribeMacro{\DTLplotmarks}]%
+\cs{DTLplotmarks}
+\end{definition}
+This must be a comma separated list of \sty{pgf} code to create the
+plot marks. \ics{DTLplot} cycles through this list for each
+database listed. The \sty{pgf} package provides convenient commands
+for generating plots using \cs{pgfuseplotmark}. See the \sty{pgf}
+manual for more details.
+
+\begin{definition}[\DescribeMacro{\DTLplotmarkcolors}]%
+\cs{DTLplotmarkcolors}
+\end{definition}
+This must be a comma separated list of defined colours to apply to the
+plot marks. \ics{DTLplot} cycles through this list for each database
+listed. If this macro is set to empty, the current colour will
+be used instead.
+
+\begin{definition}[\DescribeMacro{\DTLplotlines}]%
+\cs{DTLplotlines}
+\end{definition}
+This must be a comma separated list of \sty{pgf} code to set the
+style of the plot lines. \ics{DTLplot} cycles through this list for
+each database listed. Dash patterns can be set using \cs{pgfsetdash},
+see the \sty{pgf} manual for more details. If \cs{DTLplotlines} is
+set to empty the current line style will be used instead.
+
+\begin{definition}[\DescribeMacro{\DTLplotlinecolors}]%
+\cs{DTLplotlinecolors}
+\end{definition}
+This must be a comma separated list of defined colours to apply to the
+plot lines. \cs{DTLplot} cycles through this list for each database
+listed. If this macro is set to empty, the current colour will
+be used instead. The default is the same as \cs{DTLplotmarkcolors}.
+
+\begin{definition}[\DescribeMacro{\DTLXAxisStyle}]%
+\cs{DTLXAxisStyle}
+\end{definition}
+This governs the style of the $x$ axis. It is passed as the optional
+argument to the TikZ \cs{draw} command. By default it is just "-"
+which is a solid line style with no start or end arrows. The $x$
+axis line starts from the bottom left corner of the plot and extends
+to the bottom right corner of the plot. So if you want the $x$ axis
+to have an arrow head at the right end, you can do:
+\begin{verbatim}
+\renewcommand*{\DTLXAxisStyle}{->}
+\end{verbatim}
+
+\begin{definition}[\DescribeMacro{\DTLYAxisStyle}]%
+\cs{DTLYAxisStyle}
+\end{definition}
+This governs the style of the $y$ axis. It is analogous to
+\cs{DTLXAxisStyle} described above.
+
+\begin{definition}[\DescribeMacro{\DTLmajorgridstyle}]%
+\cs{DTLmajorgridstyle}
+\end{definition}
+This specifies the format of the major grid lines.
+It may be set to any TikZ setting that you can pass to the
+optional argument of \cs{draw}. The default value is
+"color=gray,-" which indicates a grey solid line.
+
+\begin{definition}[\DescribeMacro{\DTLminorgridstyle}]%
+\cs{DTLminorgridstyle}
+\end{definition}
+This specifies the format of the minor grid lines.
+It may be set to any TikZ setting that you can pass to the
+optional argument of \cs{draw}. The default value is
+"color=gray,loosely dotted" which indicates a grey dotted line.
+
+\begin{definition}[\DescribeMacro{\DTLformatlegend}]%
+\cs{DTLformatlegend}\marg{legend}
+\end{definition}
+This formats the entire legend, which is passed as the argument.
+The default is to set the legend with
+a white background, a black frame.
+
+\section{Adding to a Plot Stream}
+
+\begin{definition}[\DescribeMacro{\DTLplotstream}]%
+\cs{DTLplotstream}\oarg{condition}\marg{db name}\marg{x key}\marg{y key}
+\end{definition}
+This adds points to a stream from the database called \meta{db name}
+where the $x$ co-ordinates are given by the key \meta{x key}
+and the $y$ co-ordinates are given by the key \meta{y key}.
+(\ics{DTLconverttodecimal} is used to convert locale dependent
+values to a standard decimal that is recognised by the
+\sty{pgf} package.)
+The optional argument \meta{condition} is the same as that
+for \ics{DTLforeach}.
+
+\begin{example}{Adding to a Plot Stream}{ex:plotstream}
+Suppose you have a CSV file called "data.csv" containing the
+following:
+\begin{verbatim}
+x,y
+0,0
+1,1
+2,0.5
+1.5,0.3
+\end{verbatim}
+\DTLnewdb{data}\relax
+\DTLnewrow{data}\relax
+\DTLnewdbentry{data}{x}{0}\relax
+\DTLnewdbentry{data}{y}{0}\relax
+\DTLnewrow{data}\relax
+\DTLnewdbentry{data}{x}{1}\relax
+\DTLnewdbentry{data}{y}{1}\relax
+\DTLnewrow{data}\relax
+\DTLnewdbentry{data}{x}{2}\relax
+\DTLnewdbentry{data}{y}{0.5}\relax
+\DTLnewrow{data}\relax
+\DTLnewdbentry{data}{x}{1.5}\relax
+\DTLnewdbentry{data}{y}{0.3}\relax
+First load the file into a database called "data":
+\begin{verbatim}
+\DTLloaddb{data}{data.csv}
+\end{verbatim}
+Now create a figure containing this data:
+\begin{verbatim}
+\begin{figure}[tbhp]
+\centering
+\begin{tikzpicture}
+\pgfplothandlermark{\pgfuseplotmark{o}}
+\pgfplotstreamstart
+\DTLplotstream{data}{x}{y}%
+\pgfplotstreamend
+\pgfusepath{stroke}
+\end{tikzpicture}
+\caption{Adding to a plot stream}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:plotstream}.
+
+\begin{figure}[tbhp]
+\centering
+\begin{tikzpicture}
+\pgfplothandlermark{\pgfuseplotmark{o}}
+\pgfplotstreamstart
+\DTLplotstream{data}{x}{y}%
+\pgfplotstreamend
+\pgfusepath{stroke}
+\end{tikzpicture}
+\caption{Adding to a plot stream}
+\label{fig:plotstream}
+\end{figure}
+\end{example}
+
+\begin{example}{Plotting Multiple Keys in the Same
+Database}{ex:multikey}
+Suppose I have conducted two time to growth experiments. For each
+experiment, I have recorded the log count at set times, and I have
+recorded this information in the same data file called, say,
+"growth.csv" which contains the following:
+\begin{verbatim}
+Time,Experiment 1,Experiment 2
+0,3.73,3.6
+23,3.67,3.7
+60,4.9,3.8
+\end{verbatim}
+\DTLnewdb{growth}\DTLnewrow{growth}\relax
+\DTLnewdbentry{growth}{Time}{0}\relax
+\DTLnewdbentry{growth}{Experiment 1}{3.73}\relax
+\DTLnewdbentry{growth}{Experiment 2}{3.6}\relax
+\DTLnewrow{growth}\relax
+\DTLnewdbentry{growth}{Time}{23}\relax
+\DTLnewdbentry{growth}{Experiment 1}{3.67}\relax
+\DTLnewdbentry{growth}{Experiment 2}{3.7}\relax
+\DTLnewrow{growth}\relax
+\DTLnewdbentry{growth}{Time}{60}\relax
+\DTLnewdbentry{growth}{Experiment 1}{4.9}\relax
+\DTLnewdbentry{growth}{Experiment 2}{3.8}\relax
+I can load the data into a database using:
+\begin{verbatim}
+\DTLloaddb{growth}{growth.csv}
+\end{verbatim}
+However, I'd like to plot both results on the same graph. Since they
+are contained in the same database, I can't use the method I used
+in \autoref{ex:2db}. Instead I can use a combination of
+\ics{DTLplot} and \ics{DTLplotstream}:
+\begin{verbatim}
+\begin{figure}[tbhp]
+\centering
+ % computer bounds
+\DTLminforkeys{growth}{Time}{\minX}
+\DTLminforkeys{growth}{Experiment 1,Experiment 2}{\minY}
+\DTLmaxforkeys{growth}{Time}{\maxX}
+\DTLmaxforkeys{growth}{Experiment 1,Experiment 2}{\maxY}
+ % round x tick labels
+\setcounter{DTLplotroundXvar}{0}
+ % redefine \DTLplotatbegintikz to plot the data for Experiment 1
+\renewcommand*{\DTLplotatbegintikz}{%
+ % set plot mark
+\pgfplothandlermark{\color{green}\pgfuseplotmark{x}}
+ % start plot stream
+\pgfplotstreamstart
+ % add data from Experiment 1 to plot stream
+\DTLplotstream{growth}{Time}{Experiment 1}%
+ % end plot stream
+\pgfplotstreamend
+ % stroke path
+\pgfusepath{stroke}
+ % add information to legend (no line is require so use \relax)
+\DTLaddtoplotlegend{\color{green}%
+\pgfuseplotmark{x}}{\relax}{Experiment 1}
+}
+ % now plot the data for Experiment 2
+\DTLplot{growth}{x=Time,y=Experiment 2,legend,
+width=3in,height=3in,bounds={\minX,\minY,\maxX,\maxY},
+xlabel={Time},ylabel={Log Count},
+legendlabels={Experiment 2}}
+\caption{Time to growth data}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:multikey}.
+Notes:
+\begin{itemize}
+\item I redefined \ics{DTLplotatbegintikz} in order to add
+the new plot to the legend, since \ics{DTLplotatendtikz} is
+used after the legend is plotted. The $x$ and $y$ unit vectors
+are set before \ics{DTLplotatbegintikz} so I don't need to
+worry about the co-ordinates.
+\item I set the counter \ctr{DTLplotroundXvar} to zero
+otherwise the $x$ axis would have looked too cluttered.
+\item I have used \ics{DTLminforkeys} and \ics{DTLmaxforkeys} to
+determine the bounds since \ics{DTLplot} won't take the data
+for Experiment 1 into account when computing the bounds.
+\end{itemize}
+
+\begin{figure}[htbp]
+\DTLminforkeys{growth}{Time}{\minX}
+\DTLminforkeys{growth}{Experiment 1,Experiment 2}{\minY}
+\DTLmaxforkeys{growth}{Time}{\maxX}
+\DTLmaxforkeys{growth}{Experiment 1,Experiment 2}{\maxY}
+\setcounter{DTLplotroundXvar}{0}
+\renewcommand*{\DTLplotatbegintikz}{%
+\pgfplothandlermark{\color{green}\pgfuseplotmark{x}}
+\pgfplotstreamstart
+\DTLplotstream{growth}{Time}{Experiment 1}%
+\pgfplotstreamend
+\pgfusepath{stroke}
+\DTLaddtoplotlegend{\color{green}\pgfuseplotmark{x}}{\relax}{Experiment 1}
+}
+\centering
+\DTLplot{growth}{x=Time,y=Experiment 2,legend,
+width=3in,height=3in,bounds={\minX,\minY,\maxX,\maxY},
+xlabel={Time},ylabel={Log Count},
+legendlabels={Experiment 2}}
+\caption[Time to growth data (plotting from the same database using
+different keys)]{Time to growth data}
+\label{fig:multikey}
+\end{figure}
+\end{example}
+
+\chapter{Bar Charts (\texorpdfstring{\sty{databar}}{databar}
+package)}
+\label{sec:databar}
+
+The \sty{databar} package provides commands for creating bar charts.
+It is not loaded by the \sty{datatool} package, so if you want to
+use it you will need to load it explicitly using
+"\usepackage{databar}". You must also have the \sty{pgf} package
+installed.
+
+Bar charts can either be vertical or horizontal, the default is
+vertical. In this section the $x$ axis refers to the horizontal
+axis when plotting a vertical bar chart and to the vertical axis
+when plotting a horizontal bar chart. The $x$ axis units are in
+increments of one bar. The $y$ axis refers to the vertical axis
+when plotting a vertical bar chart and to the horizontal axis when
+plotting a horizontal bar chart. The $y$ axis uses the same
+co-ordinates as the data. The bars may have an upper and lower
+label. In a vertical bar chart, the lower label is placed below
+the $x$ axis and the upper label is placed above the top of the bar.
+In a horizontal bar chart, the lower label is placed to the left of
+the $x$ axis and the upper label is placed to the right of the
+end of the bar. (This is actually a misnomer as it is possible
+for the ``upper'' label to be below the ``lower'' label if a
+bar has a negative value, however the bars are considered to
+be anchored on the $x$ axis, and the other end of the bar is
+considered to be the ``upper'' end, regardless of its
+direction.)
+
+The \sty{databar} package options are as follows:
+\begin{description}
+\item[{\pkgopt[databar]{color}}] Created coloured bar charts
+(default).
+
+\item[{\pkgopt[databar]{gray}}] Created grey scale bar charts.
+
+\item[{\pkgopt[databar]{vertical}}] Created vertical bar charts
+(default).
+
+\item[{\pkgopt[databar]{horizontal}}] Created horizontal bar charts.
+\end{description}
+
+
+
+\begin{definition}[\DescribeMacro{\DTLbarchart}]%
+\cs{DTLbarchart}\oarg{condition}\marg{db name}\marg{settings}\marg{values}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLmultibarchart}]%
+\cs{DTLmultibarchart}\oarg{condition}\marg{db name}\marg{settings}\marg{values}
+\end{definition}
+These commands both create a bar chart from the information in
+the database \meta{db name}, where \meta{condition} is the same
+as the optional argument for \ics{DTLforeach} described in
+\autoref{sec:dbforeach}, and \meta{values} is the same as the
+penultimate argument of \ics{DTLforeach}. The \meta{settings}
+argument is a \meta{setting}"="\meta{value} list of settings. The
+first command, \cs{DLTbarchart}, will draw a bar chart for a
+given column of data in the database, whereas the second command,
+\cs{DTLmultibarchart}, will draw a bar chart that is divided into
+groups of bars where each bar within a group represents data from
+several columns of a given row in the database.
+
+The \csopt{DTLbarchart}{variable} setting is
+required for \cs{DTLbarchart} and the
+\csopt{DTLmultibarchart}{variables}, the other settings are
+optional (though some may only be used for one of
+\cs{DTLbarchart} and \cs{DLTmultibarchart}), and are as follows:
+
+\begin{description}
+\item[\csopt{DTLbarchart}{variable}]
+This specifies the control sequence to use that
+contains the value used to construct the bar chart. The control
+sequence must be one of the control sequences to appear in
+the assignment list \meta{values}. This setting is required
+for \cs{DTLbarchart}, and is unavailable for \cs{DTLmultibarchart}.
+
+\item[\csopt{DTLmultibarchart}{variables}]
+This specifies a list of control sequences to use which
+contain the values used to construct the bar chart. Each control
+sequence must be one of the control sequences to appear in
+the assignment list \meta{values}. This setting is required
+for \cs{DTLmultibarchart}, and is unavailable for
+\cs{DTLbarchart}.
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{max}]
+This specifies the maximum value on the $y$ axis. (This should
+be a standard decimal value.)
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{length}]
+This specifies the overall length of the $y$ axis, and must
+be a dimension.
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{maxdepth}]
+This must be a zero or negative number. It specifies the maximum
+depth of the $y$ axis. (This should be a standard decimal value.)
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{axes}]
+This setting specifies which axes to display. This may take one
+of the following values: "both", "x", "y" or "none".
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{barlabel}]
+This setting specifies the lower bar label. When used with
+\cs{DTLmultibarchart} it indicates the group label.
+
+\item[\csopt{DTLmultibarchart}{multibarlabels}]
+This setting should contain a comma separated list of labels
+for each bar within a group for \cs{DTLmultibarchart}. This
+setting is not available for \cs{DTLbarchart}.
+
+\item[\csopt{DTLbarchart}{upperbarlabel}]
+This setting specifies the upper bar label. This setting
+is not available for \cs{DTLmultibarchart}.
+
+\item[\csopt{DTLmultibarchart}{uppermultibarlabels}]
+This setting must be a comma separated list of upper bar
+labels for each bar within a group. This setting is not
+available for \cs{DTLbarchart}.
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{yticpoints}]
+This must be a comma separated list of tick locations for the
+$y$ axis. (These should be standard decimal values.)
+This setting overrides \csopt{DTLbarchart}{yticgap}.
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{yticgap}]
+This specifies the gap between the $y$ tick marks. (This should
+be a standard decimal value.)
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{yticlabels}]
+This must be a comma separated list of tick labels for the
+$y$ axis.
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{ylabel}]
+This specifies the label for the $y$ axis.
+
+\item[\csopt{DTLmultibarchart}{groupgap}] This specifies
+the gap between groups when using \cs{DTLmultibarchart}.
+This value is given as a multiple of the bar width. The
+default value is 1, which indicates a gap of one bar width.
+This setting is not available for \cs{DTLbarchart}.
+
+\item[\csopt{DTLbarchart,DTLmultibarchart}{verticalbars}]
+This is a boolean setting, so it can only take the values
+"true" (do a vertical bar chart) or "false" (do a horizontal
+bar chart). If the value is omitted, "true" is assumed.
+\end{description}
+
+\begin{example}{A Basic Bar Chart}{ex:barchart}
+Recall \autoref{ex:piechart} defined a database called "fruit".
+This example will be using that database to plot a bar chart.
+The following plots a basic vertical bar chart:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLbarchart{variable=\theQuantity}{fruit}{\theQuantity=Quantity}
+\caption{A basic bar chart}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:barchart}.
+
+\begin{figure}[htbp]
+\centering
+\DTLbarchart{variable=\theQuantity}{fruit}{\theQuantity=Quantity}
+\caption{A basic bar chart}
+\label{fig:barchart}
+\end{figure}
+\end{example}
+
+\section{Changing the Appearance of a Bar Chart}
+
+
+\begin{definition}[\DescribeMacro{\DTLbarchartlength}]%
+\cs{DTLbarchartlength}
+\end{definition}
+This specifies the total length of the $y$ axis. You must use
+\cs{setlength} to change this value. The default value is 3in.
+
+\begin{definition}[\DescribeMacro{\DTLbarwidth}]%
+\cs{DTLbarwidth}
+\end{definition}
+This specifies the width of each bar. You must use \cs{setlength}
+to change this value. The default value is 1cm.
+
+\begin{definition}[\DescribeMacro{\DTLbarlabeloffset}]%
+\cs{DTLbarlabeloffset}
+\end{definition}
+This specifies the distance from the $x$ axis to the lower bar label.
+You must use \cs{setlength} to change this value. The default value
+is 10pt.
+
+\begin{definition}[\DescribeCounter{DTLbarroundvar}]
+\ctrfmt{DTLbarroundvar}
+\end{definition}
+The $y$ tick labels are rounded to \meta{n} digits after the
+decimal point, where \meta{n} is given by the value of the
+counter \ctrfmt{DTLbarroundvar}. You must use \cs{setcounter}
+to change this value.
+
+\begin{definition}[\DescribeMacro{\DTLsetbarcolor}]%
+\cs{DTLsetbarcolor}\marg{n}\marg{color}
+\end{definition}
+This sets the \meta{n}th bar colour to \meta{color}.
+Only the first eight bars have a colour defined by default. If you
+need more than eight bars, you will need to define more bar colours.
+It is recommended that you set the colour of each bar to
+correspond with whatever the bar represents.
+
+\begin{definition}[\DescribeMacro{\DTLdobarcolor}]%
+\cs{DTLdobarcolor}\marg{n}
+\end{definition}
+This sets the current colour to the colour of the \meta{n}th bar.
+
+\begin{definition}[\DescribeMacro{\DTLbaroutlinecolor}]%
+\cs{DTLbaroutlinecolor}
+\end{definition}
+This macro contains the colour of the bar outlines. This defaults
+to "black".
+
+\begin{definition}[\DescribeMacro{\DTLbaroutlinewidth}]%
+\cs{DTLbaroutlinewidth}
+\end{definition}
+This length specifies the line width for the bar outlines. If it
+is 0pt, the outline is not drawn. The default value is 0pt.
+
+
+\begin{definition}[\DescribeMacro{\DTLbaratbegintikz}]%
+\cs{DTLbaratbegintikz}
+\end{definition}
+This specifies any additional commands to add to the start of
+the plot. It defaults to nothing, and is called after the
+unit vectors are set.
+
+\begin{definition}[\DescribeMacro{\DTLbaratendtikz}]%
+\cs{DTLbaratendtikz}
+\end{definition}
+This specifies any additional commands to add to the end of
+the plot. It defaults to nothing.
+
+\begin{definition}[\DescribeMacro{\DTLeverybarhook}]%
+\cs{DTLeverybarhook}
+\end{definition}
+The specifies code to apply at every bar. Within the definition
+of \cs{DTLeverybarhook} you can use the commands
+\DescribeMacro{\DTLstartpt}\cs{DTLstartpt} (the start
+of the bar), \DescribeMacro{\DTLmidpt}\cs{DTLmidpt}
+(the mid point of the bar) and
+\DescribeMacro{\DTLendpt}\cs{DTLendpt} (the end of the bar). For
+example (using the earlier "fruit" database):
+\begin{verbatim}
+\renewcommand*{\DTLeverybarhook}{%
+\pgftext[at=\DTLmidpt]{\insertName\space(\insertValue)}%
+}
+\DTLbarchart{variable=\insertValue,axes=both,
+ylabel=Quantity,max=50,verticalbars=false
+}%
+{fruit}{\insertValue=Value,\insertName=Name}
+\end{verbatim}
+This puts the name followed by the quantity in brackets in the
+middle of the bar.
+
+\begin{definition}[\DescribeMacro{\ifDTLverticalbars}]%
+\cs{ifDTLverticalbars}
+\end{definition}
+This conditional governs whether the chart uses vertical or
+horizontal bars.
+
+\begin{definition}[\DescribeMacro{\DTLbarXlabelalign}]%
+\cs{DTLbarXlabelalign}
+\end{definition}
+This specifies the text alignment of the lower bar labels. This
+defaults to "left,rotate=-90" if you use the \pkgopt[databar]{vertical}
+package option or the \csopt{DTLbarchart}{verticalbars} setting,
+and defaults to "right" if you use the \pkgopt[databar]{horizontal}
+package option or the \csopt{DTLbarchart}{verticalbars}"=false"
+setting.
+
+\begin{definition}[\DescribeMacro{\DTLbarYticklabelalign}]%
+\cs{DTLbarYlabelalign}
+\end{definition}
+This specifies the text alignment of the $y$ axis labels. This
+defaults to "right" for vertical bar charts and "center" for
+horizontal bar charts.
+
+\begin{definition}[\DescribeMacro{\DTLbardisplayYticklabel}]%
+\cs{DTLbardisplayYticklabel}\marg{text}
+\end{definition}
+This specifies how to display the $y$ tick label. The argument
+is the tick label.
+
+\begin{definition}[\DescribeMacro{\DTLdisplaylowerbarlabel}]%
+\cs{DTLdisplaylowerbarlabel}\marg{text}
+\end{definition}
+This specifies how to display the lower bar label for
+\cs{DTLbarchart} and the lower bar group label for
+\cs{DTLmultibarchart}. The argument is the label.
+
+\begin{definition}[\DescribeMacro{\DTLdisplaylowermultibarlabel}]%
+\cs{DTLdisplaylowermultibarlabel}\marg{text}
+\end{definition}
+This specifies how to display the lower bar label for
+\cs{DTLmultibarchart}. The argument is the label. This
+command is ignored by \cs{DTLbarchart}.
+
+\begin{definition}[\DescribeMacro{\DTLdisplayupperbarlabel}]%
+\cs{DTLdisplayupperbarlabel}\marg{text}
+\end{definition}
+This specifies how to display the upper bar label for
+\cs{DTLbarchart} and the upper bar group label for
+\cs{DTLmultibarchart}. The argument is the label.
+
+\begin{definition}[\DescribeMacro{\DTLdisplayuppermultibarlabel}]%
+\cs{DTLdisplayuppermultibarlabel}\marg{text}
+\end{definition}
+This specifies how to display the upper bar label for
+\cs{DTLmultibarchart}. The argument is the label. This
+command is ignored by \cs{DTLbarchart}.
+
+\begin{example}{A Labelled Bar Chart}{ex:annotebarchart}
+This example extends \autoref{ex:barchart} so that the chart is
+a bit more informative (which is after all the whole point of
+a chart). This chart now has a label below each bar, as well
+as a label above the bar. The lower label uses the value of the
+"Name" key, and the upper label uses the quantity. I have also
+set the outline width so each bar has a border.
+\begin{verbatim}
+\begin{figure}[htbp]
+\setlength{\DTLbaroutlinewidth}{1pt}
+\centering
+\DTLbarchart{variable=\theQuantity,barlabel=\theName,%
+upperbarlabel=\theQuantity}{fruit}{%
+\theQuantity=Quantity,\theName=Name}
+\caption{A bar chart}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:annotebarchart}.
+
+\begin{figure}[htbp]
+\centering
+\setlength{\DTLbaroutlinewidth}{1pt}
+\DTLbarchart{variable=\theQuantity,barlabel=\theName,
+upperbarlabel=\theQuantity}{fruit}{\theQuantity=Quantity,\theName=Name}
+\caption[A bar chart (labelled)]{A bar chart}
+\label{fig:annotebarchart}
+\end{figure}
+\end{example}
+
+\begin{example}{Profit/Loss Bar Chart}{ex:profit}
+Suppose I have a file called "profits.csv" that looks like:
+\DTLnewdb{profits}
+\DTLnewrow{profits}
+\DTLnewdbentry{profits}{Year}{2000}\relax
+\DTLnewdbentry{profits}{Profit}{\protect\pounds2,525}\relax
+\DTLnewrow{profits}
+\DTLnewdbentry{profits}{Year}{2001}\relax
+\DTLnewdbentry{profits}{Profit}{\protect\pounds3,752}\relax
+\DTLnewrow{profits}
+\DTLnewdbentry{profits}{Year}{2002}\relax
+\DTLnewdbentry{profits}{Profit}{-\protect\pounds1,520}\relax
+\DTLnewrow{profits}
+\DTLnewdbentry{profits}{Year}{2003}\relax
+\DTLnewdbentry{profits}{Profit}{\protect\pounds1,270}\relax
+\begin{verbatim}
+Year,Profit
+2000,\pounds2,535
+2001,\pounds3,752
+2002,-\pounds1,520
+2003,\pounds1,270
+\end{verbatim}
+First I can load this file into a database called "profits":
+\begin{verbatim}
+\DTLloaddb{profits}{profits.csv}
+\end{verbatim}
+Now I can plot the data as a bar chart:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+ % Set the width of each bar to 10pt
+\setlength{\DTLbarwidth}{10pt}
+ % Set the outline width to 1pt
+\setlength{\DTLbaroutlinewidth}{1pt}
+ % Round the $y$ tick labels to integers
+\setcounter{DTLbarroundvar}{0}
+ % Adjust the tick label offset
+\setlength{\DTLticklabeloffset}{20pt}
+ % Change the y tick label alignment
+\renewcommand*{\DTLbarYticklabelalign}{left}
+ % Rotate the y tick labels
+\renewcommand*{\DTLbardisplayYticklabel}[1]{\rotatebox{-45}{#1}}
+ % Set the bar colours depending on the value of \theProfit
+\DTLforeach{profits}{\theProfit=Profit}{%
+\ifthenelse{\DTLislt{\theProfit}{0}}
+{\DTLsetbarcolor{\DTLcurrentindex}{red}}
+{\DTLsetbarcolor{\DTLcurrentindex}{blue}}}
+ % Do the bar chart
+\DTLbarchart{variable=\theProfit,upperbarlabel=\theYear,
+ylabel={Profit/Loss (\pounds)},verticalbars=false,
+maxdepth=-2000,max=4000}{profits}
+{\theProfit=Profit,\theYear=Year}
+\caption{Profits for 2000--2003}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:profits}. Notes:
+\begin{enumerate}
+\item This example uses \cs{rotatebox}, so the \sty{graphics}
+or \sty{graphicx} package is required.
+\item The $y$ tick labels are too wide to fit horizontally
+so they have been rotated to avoid overlapping with their
+neighbour.
+\item Rotating the $y$ tick labels puts them too close to
+the $y$ axis, so \ics{DTLticklabeloffset} is made larger to
+compensate.
+\item Remember not to use \cs{year} as an assignment command
+as this command already exists!
+\item Before the bar chart is created I have iterated through
+the database, setting the bar colour to red or blue
+depending on the value of \cs{theProfit}.
+\end{enumerate}
+
+Both \cs{DTLbarchart} and \cs{DTLmultibarchart} set the following
+macros, which may be used in \cs{DTLbaratbegintikz} and
+\cs{DTLbaratendtikz}:
+\begin{definition}[\DescribeMacro{\DTLbarchartwidth}]%
+\cs{DTLbarchartwidth}
+\end{definition}
+This is the overall width of the bar chart. In the case of
+\cs{DTLbarchart} this is just the number of bars. In the case
+of \cs{DTLmultibarchart} it is computed as:
+\begin{displaymath}
+m \times n + (m-1)\times g
+\end{displaymath}
+where $m$ is the number of bar groups (i.e.\ the number of rows
+of data), $n$ is the number of bars within a group (i.e.\
+the number of commands listed in the
+\csopt{DTLmultibarchart}{variables}) setting and $g$ is the
+group gap (as specified by the \csopt{DTLmultibarchart}{groupgap} setting).
+
+\begin{definition}[\DescribeMacro{\DTLnegextent}]%
+\cs{DTLnegextent}
+\end{definition}
+This is set to the negative extent of the bar chart. (This value
+may either be zero or negative, and corresponds to the
+\csopt{DTLbarchart,DTLmultibarchart}{maxdepth} setting.)
+
+\begin{definition}[\DescribeMacro{\DTLbarmax}]%
+\cs{DTLbarmax}
+\end{definition}
+This is set to the maximum extent of the bar chart. (This value
+corresponds to the
+\csopt{DTLbarchart,DTLmultibarchart}{max} setting.)
+
+\begin{figure}[htbp]
+\centering
+\setlength{\DTLbarwidth}{10pt}
+\setlength{\DTLbaroutlinewidth}{1pt}
+\setlength{\DTLticklabeloffset}{20pt}
+\setcounter{DTLbarroundvar}{0}
+\renewcommand*{\DTLbarYticklabelalign}{left}
+\renewcommand*{\DTLbardisplayYticklabel}[1]{\rotatebox{-45}{#1}}
+\DTLforeach{profits}{\theProfit=Profit}{\relax
+\ifthenelse{\DTLislt{\theProfit}{0}}
+{\DTLsetbarcolor{\DTLcurrentindex}{red}}
+{\DTLsetbarcolor{\DTLcurrentindex}{blue}}}
+\DTLbarchart{variable=\theProfit,upperbarlabel=\theYear,
+ylabel={Profit/Loss (\pounds)},verticalbars=false,
+maxdepth=-2000,max=4000
+}{profits}
+{\theProfit=Profit,\theYear=Year}
+\caption[Profits for 2000--2003 (a horizontal bar chart)]{Profits for
+2000--2003}
+\label{fig:profits}
+\end{figure}
+
+\end{example}
+
+\begin{example}{A Multi-Bar Chart}{ex:multibar}
+This example uses the "marks" database described in
+\autoref{ex:editdb}.
+Recall that this database stores student marks for three
+assignments. The keys for the assignment marks are
+\texttt{Assignment 1}, \texttt{Assignment 2} and
+\texttt{Assignment 3}, respectively. I can convert this
+data into a bar chart using the following:
+\begin{verbatim}
+\begin{figure}[htbp]
+\centering
+\DTLmultibarchart{variables={\assignI,\assignII,\assignIII},
+barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII},
+barlabel={\firstname\ \surname}}{marks}{%
+\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,%
+\assignII=Assignment 2,\assignIII=Assignment 3}
+\caption{Student marks}
+\end{figure}
+\end{verbatim}
+This produces \autoref{fig:multibar}. Notes:
+\begin{enumerate}
+\item I used "variables={\assignI,\assignII,\assignIII}" to
+set the variable to use for each bar within a group. This means
+that there will be three bars in each group.
+\item I have set the bar width to 10pt, otherwise the chart
+will be too wide.
+\item I used "uppermultibarlabels={\assignI,\assignII,\assignIII}"
+to set the upper labels for each bar within a group. This
+will print the assignment mark above the relevant bar.
+\item I used "barlabel={\firstname\ \surname}" to place the
+student's name below the group corresponding to that student.
+\end{enumerate}
+
+\begin{figure}[htbp]
+\centering
+\DTLmultibarchart{variables={\assignI,\assignII,\assignIII},
+barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII},
+barlabel={\firstname\ \surname}}{marks}
+{\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII=Assignment 3}
+\caption[Student marks (a multi-bar chart)]{Student
+marks}\label{fig:multibar}
+\end{figure}
+
+Recall that \autoref{ex:editdb} computed the average score over
+for each student, and saved it with the key "Average". This
+information can be added to the bar chart. It might also be
+useful to compute the average over all students and add this
+information to the chart. This is done as follows:
+\begin{verbatim}
+ \begin{figure}[htbp]
+ \centering
+ % compute the overall mean
+ \DTLmeanforkeys{marks}{Average}{\overallmean}
+ % round it to 2 decimal places
+ \DTLround{\overallmean}{\overallmean}{2}
+ % draw a grey dotted line indicating the overall mean
+ % covering the entire width of the bar chart
+ \renewcommand*{\DTLbaratendtikz}{%
+ \draw[lightgray,loosely dotted] (0,\overallmean) --
+ (\DTLbarchartwidth,\overallmean)
+ node[right,black]{Average (\overallmean)};}
+ % Set the lower bar labels to draw a brace across the current
+ % group, along with the student's name and average score
+ \renewcommand*{\DTLdisplaylowerbarlabel}[1]{%
+ \tikz[baseline=(current bounding box.center)]{
+ \draw[snake=brace,rotate=-90](0,0) -- (\DTLbargroupwidth,0);}
+ \DTLround{\theMean}{\theMean}{2}%
+ \shortstack{#1\\(Average: \theMean)}}
+ % draw the bar chart
+ \DTLmultibarchart{variables={\assignI,\assignII,\assignIII},
+ barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII},
+ barlabel={\firstname\ \surname}}{marks}
+ {\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,%
+ \assignII=Assignment 2,\assignIII=Assignment 3,\theMean=Average}
+ \caption{Student marks}
+ \end{figure}
+\end{verbatim}
+which produces \autoref{fig:multibarmean}. Notes:
+\begin{enumerate}
+\item I've used the TikZ snake library to create a brace, so
+I need to put
+\begin{verbatim}
+\usetikzlibrary{snakes}
+\end{verbatim}
+in the preamble. See the \sty{pgf} manual for more details on
+how to use this library.
+
+\item I used \ics{DTLbargroupwidth} to indicate the width of
+each bar group.
+
+\item I used \ics{DTLbarchartwidth} to indicate the width of the
+entire bar chart
+\end{enumerate}
+
+\begin{figure}[htbp]
+\centering
+\DTLmeanforkeys{marks}{Average}{\overallmean}
+\DTLround{\overallmean}{\overallmean}{2}
+\renewcommand*{\DTLbaratendtikz}{\draw[lightgray,loosely dotted] (0,\overallmean) --
+(\DTLbarchartwidth,\overallmean) node[right,black]{Average (\overallmean)};}
+\renewcommand*{\DTLdisplaylowerbarlabel}[1]{\relax
+\tikz[baseline=(current bounding box.center)]{
+\draw[snake=brace,rotate=-90](0,0) -- (\DTLbargroupwidth,0);}
+\DTLround{\theMean}{\theMean}{2}\relax
+\shortstack{#1\\(Average: \theMean)}}
+\DTLmultibarchart{variables={\assignI,\assignII,\assignIII},
+barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII},
+barlabel={\firstname\ \surname}}{marks}
+{\surname=Surname,\firstname=FirstName,\assignI=Assignment 1,\assignII=Assignment 2,\assignIII=Assignment 3,\theMean=Average}
+\caption[Student marks (annotating a bar chart)]{Student marks}
+\label{fig:multibarmean}
+\end{figure}
+
+\end{example}
+
+\chapter{Converting a \texorpdfstring{\BibTeX}{BibTeX} database
+into a \texorpdfstring{\sty{datatool}}{datatool} database
+(\texorpdfstring{\sty{databib}}{databib} package)}
+\label{sec:databib}
+
+The \sty{databib} package provides the means of converting a \BibTeX\
+database into a \sty{datatool} database. The database can then be
+sorted using \cs{DTLsort}, described in \autoref{sec:sort}.
+For example, you may want to sort the bibliography in
+reverse chronological order. Once you have sorted the bibliography,
+you can display it using \cs{DTLbibliography}, described in
+\autoref{sec:thebib}, or you can iterate through the database
+using \cs{DTLforeachbib}, described in \autoref{sec:foreachbib}.
+
+Note that the \sty{databib}
+package is not automatically loaded by \sty{datatool}, so if
+you want to use it, you must load it using
+"\usepackage{databib}".
+
+\begin{important}
+The purpose of this package is to provide a means for
+authors to format their own bibliography style where there is no
+bibliography style file available that produces the desired results.
+The \cs{DTLsort} macro uses a much less efficient sorting algorithm
+than \BibTeX, and loading the bibliography as a \sty{datatool}
+database is much slower than loading a standard \filetype{bbl} file. If
+you have a large database, and you are worried that \LaTeX\ may have
+become stuck, try using the \pkgopt{verbose} option to \sty{datatool}
+or use the command \cs{dtlverbosetrue}. This will print informative
+messages to the console and transcript file, to let you know what's
+going on.
+\end{important}
+
+\section{\texorpdfstring{\BibTeX}{BibTeX}: An Overview}
+\label{sec:bibtex}
+This document assumes that you have at least some passing
+familiarity with \BibTeX, but here follows a brief refresher.
+
+\BibTeX\ is an external application used in conjunction with \LaTeX.
+When you run \BibTeX, you need to specify the name of the document's
+auxiliary file (without the \filetype{aux} extension). \BibTeX\ then reads
+this file and looks for the commands \cs{bibstyle} (which indicates
+which bibliography style (\filetype{bst}) file to load), \cs{bibdata}
+(which indicates which bibliography database (\filetype{bib}) files to
+load) and \cs{citation} (produced by \cs{cite} and \cs{nocite}, which
+indicates which entries should be included in the bibliography).
+\BibTeX\ then creates a file with the extension \filetype{bbl} which
+contains the bibliography, formatted according to the layout defined
+in the bibliography style file.
+
+In general, given a document called, say, \texttt{mydoc.tex}, you
+will have to perform the following steps to ensure that the
+bibliography and all citations are up-to-date:
+\begin{enumerate}
+\item
+\begin{verbatim}
+latex mydoc
+\end{verbatim}
+This writes the citation information to the auxiliary file.
+The bibliography currently doesn't exists, so it isn't displayed.
+Citations will appear in the document as ?? since the internal
+cross-references don't exist yet.
+
+\item
+\begin{verbatim}
+bibtex mydoc
+\end{verbatim}
+This reads the auxiliary file, and creates a file with the extension
+\filetype{bbl} which typically contains the typeset bibliography.
+
+\item
+\begin{verbatim}
+latex mydoc
+\end{verbatim}
+Now that the \filetype{bbl} file exists, the bibliography can be input
+into the document. The internal cross-referencing information for the
+bibliography can now be written to the auxiliary file.
+
+\item
+\begin{verbatim}
+latex mydoc
+\end{verbatim}
+The cross-referencing information can be read from the auxiliary
+file.
+\end{enumerate}
+
+\subsection{\texorpdfstring{\BibTeX}{BibTeX} database}
+
+The bibliographic data required by \BibTeX\ must be stored in
+a file with the extension \filetype{bib}, where each entry is stored
+in the form:\par\vskip\baselineskip\noindent
+{\obeylines
+\noindent\texttt{@}\meta{entry\_type}\verb|{|\meta{cite\_key}\texttt,
+ \meta{field\_name} \texttt{=} \char`\"\meta{value}\char`\"\texttt,
+ \mbox{}\vdots
+ \meta{field\_name} \texttt{=} \char`\"\meta{value}\char`\"
+\noindent\verb|}|
+}
+\par\vskip\baselineskip\noindent
+Note that curly braces "{" and "}" may be used instead of \verb|"|
+and \verb|"|.
+
+The entry type, given by \meta{entry\_type} above, indicates
+the type of document. This may be one of: "article", "book",
+"booklet", "inbook", "incollection", "inproceedings"\footnote
+{Note that \texttt{conference} is a synonym for \texttt{inproceedings}.},
+"manual",
+"mastersthesis", "misc", "phdthesis", "proceedings", \linebreak
+"techreport" or "unpublished".
+
+The \meta{cite\_key} above is a unique label identifying this
+entry, and is the label used in the argument of \cs{cite} or
+\cs{nocite}. The available fields depends on the entry type, for
+example, the field "journal" is required for the "article" entry
+type, but is ignored for the "inproceedings" entry type. The standard
+fields are: "address", "author", "booktitle", "chapter", "edition",
+"editor", "howpublished", "institution", "journal", "key", "month",
+"note", "number", "organization", "pages", "publisher", "school",
+"series", "title", "type", "volume" and "year".
+
+Author and editor names must be entered in one of the following
+ways:
+\begin{enumerate}
+\item \meta{First names} \meta{von part} \meta{Surname}, \meta{Jr part}
+
+The \meta{von part} is optional and is identified by the name(s)
+starting with lowercase letters. The final comma followed by
+\meta{Jr part} is also optional. Examples:
+\begin{verbatim}
+author = "Henry James de Vere"
+\end{verbatim}
+In the above, the first names are Henry James, the ``von part'' is
+de and the surname is Vere. There is no ``junior part''.
+\begin{verbatim}
+author = "Mary-Jane Brown, Jr"
+\end{verbatim}
+In the above, the first name is Mary-Jane, there is no von part,
+the surname is Brown and the junior part is Jr.
+\begin{verbatim}
+author = "Peter {Murphy Allen}"
+\end{verbatim}
+In the above, the first name is Peter, and the surname is Murphy
+Allen. Note that in this case, the surname must be grouped, otherwise
+Murphy would be considered part of the forename.
+\begin{verbatim}
+author = "Maria Eliza {\uppercase{d}e La} Cruz"
+\end{verbatim}
+In the above, the first name is Maria Eliza, the von part is
+De La, and the surname is Cruz. In this case, the von part starts
+with an uppercase letter, but specifying
+\begin{verbatim}
+author = "Maria Eliza De La Cruz"
+\end{verbatim}
+would make \BibTeX\ incorrectly classify ``Maria Eliza De La'' as
+the first names, and the von part would be empty. Since \BibTeX\
+doesn't understand \LaTeX\ commands, using "{\uppercase{d}e La}"
+will trick \BibTeX\ into thinking that it starts with a lower
+case letter.
+
+\item \meta{von part} \meta{Surname}, \meta{Forenames}
+
+Again the \meta{von part} is optional, and is determined by the
+case of the first letter. For example:
+\begin{verbatim}
+author = "de Vere, Henry James"
+\end{verbatim}
+\end{enumerate}
+
+Multiple authors or editors should be separated by the key word
+"and", for example:
+\begin{verbatim}
+author = "Michel Goossens and Frank Mittlebach and Alexander Samarin"
+\end{verbatim}
+
+Below is an example of a book entry:
+\begin{verbatim}
+@book{latexcomp,
+ title = "The \LaTeX\ Companion",
+ author = "Michel Goossens and Frank Mittlebach and
+ Alexander Samarin",
+ publisher = "Addison-Wesley",
+ year = 1994
+}
+\end{verbatim}
+Note that numbers may be entered without delimiters, as in "year = 1994".
+There are also some predefined strings, including those for the month
+names. You should always use these strings instead of the actual
+month name, as the way the month name is displayed depends on the
+bibliography style. For example:
+\begin{verbatim}
+@article{Cawley2007b,
+author = "Gavin C. Cawley and Nicola L. C. Talbot",
+title = "Preventing over-fitting in model selection via {B}ayesian
+ regularisation of the hyper-parameters",
+journal = "Journal of Machine Learning Research",
+volume = 8,
+pages = "841--861",
+month = APR,
+year = 2007
+}
+\end{verbatim}
+
+You can concatenate strings using the "#" character, for example:
+\begin{verbatim}
+month = JUL # "~31~--~" # AUG # "~4",
+\end{verbatim}
+Depending on the bibliography style, this may be displayed as:
+July~31~--~August~4, or it may be displayed as:
+Jul~31~--~Aug~4. For further information, see~\cite{Goossens}.
+
+\section{Loading a \texorpdfstring{\sty{databib}}{databib}
+database}
+\label{sec:loadbbl}
+
+The \sty{databib} package always requires the \texttt{databib.bst}
+bibliography style file (which is supplied with this bundle).
+You need to use \cs{cite} or \cs{nocite} as usual. If you want to
+add all entries in the \filetype{bib} file to the \sty{datatool} database,
+you can use "\nocite{*}".
+
+\begin{definition}[\DescribeMacro{\DTLloadbbl}]%
+\cs{DTLloadbbl}\oarg{bbl name}\marg{db name}\marg{bib list}
+\end{definition}
+This command performs several functions:
+
+\begin{enumerate}
+\item it writes the following line in the auxiliary file:
+\begin{verbatim}
+\bibstyle{databib}
+\end{verbatim}
+which tells \BibTeX\ to use the \texttt{databib.bst}
+\BibTeX\ style file,
+
+\item it writes \cs{bibdata}\marg{bib list} to the
+auxiliary file, which tells \BibTeX\ which \filetype{bib} files to use,
+
+\item it creates a \sty{datatool} database called \meta{db name},
+
+\item it loads the file \meta{bbl name} if it exists. (The value
+defaults to \cs{jobname}".bbl", which is the usual name for
+a \filetype{bbl} file.) If the \filetype{bbl} file doesn't exist, the
+database \meta{db name} will remain empty.
+\end{enumerate}
+
+You then need to run your document through \LaTeX\ (or PDF\LaTeX)
+and then run \BibTeX\ on the auxiliary file, as described in
+\autoref{sec:bibtex}. This will create a \filetype{bbl} file which
+contains all the commands required to add the bibliography information
+to the \sty{datatool} database called \meta{db name}. The next
+time you \LaTeX\ your document, this file will be read, and the
+information will be added to \meta{db name}.
+
+\begin{important}
+Note that \cs{DTLloadbbl} doesn't generate any text. Once you have
+loaded the data, you can display the bibliography uses
+\cs{DTLbibliography} (described below) or you can iterate through it
+using \cs{DTLforeachbibentry} described in \autoref{sec:foreachbib}.
+\end{important}
+
+Note that the \texttt{databib.bst} \BibTeX\ style file provides
+the following additional fields: "isbn", "doi", "pubmed", "url"
+and "abstract".
+However these fields are ignored by the three predefined
+\sty{databib} styles ("plain", "abbrv" and "alpha"). If you
+want these fields to be displayed in the bibliography you will
+need to modify the bibliography style (see \autoref{sec:modbibstyle}).
+
+\section{Displaying a \texorpdfstring{\sty{databib}}{databib}
+database}
+\label{sec:thebib}
+
+A \sty{databib} database which has been loaded using
+\cs{DTLloadbbl} (described in \autoref{sec:loadbbl}) can be
+displayed using:
+\begin{definition}[\DescribeMacro{\DTLbibliography}]
+\cs{DTLbibliography}\oarg{conditions}\marg{db name}
+\end{definition}\noindent
+where \meta{db name} is the name of the database.
+
+Within the optional argument \meta{condition}, you may use any of the
+commands that may be used within the optional argument of
+\cs{DTLforeach} \emph{In addition}, you may use the following
+commands:
+
+\begin{definition}[\DescribeMacro{\DTLbibfieldexists}]%
+\cs{DTLbibfieldexists}\marg{field label}
+\end{definition}
+This tests whether the field with the given label exists for the
+current entry.
+The field label may be one of: "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", "Url" or "Eprints".
+
+For example, suppose you have loaded a \sty{databib} database
+called "mybib" using \cs{DTLloadbbl} (described in
+\autoref{sec:loadbbl}) then the following bibliography will only
+include those entries which have a "Year" field:
+\begin{verbatim}
+\DTLbibliography[\DTLbibfieldexists{Year}]{mybib}
+\end{verbatim}
+
+\begin{definition}[\DescribeMacro{\DTLbibfieldiseq}]%
+\cs{DTLbibfieldiseq}\marg{field label}\marg{value}
+\end{definition}
+This tests whether the value of the field given by
+\meta{field label} equals \meta{value}. If the field doesn't
+exist for the current entry, this evaluates to false.
+For example, the following will produce a bibliography which
+only contains entries which have the "Year" field set to 2004:
+\begin{verbatim}
+\DTLbibliography[\DTLbibfieldiseq{Year}{2004}]{mybib}
+\end{verbatim}
+
+\begin{definition}[\DescribeMacro{\DTLbibfieldcontains}]%
+\cs{DTLbibfieldcontains}\marg{field label}\marg{sub string}
+\end{definition}
+This tests whether the value of the field given by \meta{field label}
+contains \meta{sub string}. For example, the following will produce
+a bibliography which only contains entries where the author field
+contains the name "Knuth":
+\begin{verbatim}
+\DTLbibliography[\DTLbibfieldcontains{Author}{Knuth}]{mybib}
+\end{verbatim}
+
+\begin{definition}[\DescribeMacro{\DTLbibfieldislt}]%
+\cs{DTLbibfieldislt}\marg{field label}\marg{value}
+\end{definition}
+This tests whether the value of the field given by \meta{field label}
+is less than \meta{value}. If the field doesn't exist for the
+current entry, this evaluates to false.
+For example, the following will produce a bibliography which only
+contains entries whose "Year" field is less than 1983:
+\begin{verbatim}
+\DTLbibliography[\DTLbibfieldislt{Year}{1983}]{mybib}
+\end{verbatim}
+
+\begin{definition}[\DescribeMacro{\DTLbibfieldisle}]%
+\cs{DTLbibfieldisle}\marg{field label}\marg{value}
+\end{definition}
+This tests whether the value of the field given by \meta{field label}
+is less than or equal to \meta{value}. If the field doesn't exist
+for the current entry, this evaluates to false.
+For example, the following will produce a bibliography which only
+contains entries whose "Year" field is less than or equal to 1983:
+\begin{verbatim}
+\DTLbibliography[\DTLbibfieldisle{Year}{1983}]{mybib}
+\end{verbatim}
+
+\begin{definition}[\DescribeMacro{\DTLbibfieldisgt}]%
+\cs{DTLbibfieldisgt}\marg{field label}\marg{value}
+\end{definition}
+This tests whether the value of the field given by \meta{field label}
+is greater than \meta{value}. If the field doesn't exist for the
+current entry, this evaluates to false.
+For example, the following will produce a bibliography which only
+contains entries whose "Year" field is greater than 1983:
+\begin{verbatim}
+\DTLbibliography[\DTLbibfieldisgt{Year}{1983}]{mybib}
+\end{verbatim}
+
+\begin{definition}[\DescribeMacro{\DTLbibfieldisge}]%
+\cs{DTLbibfieldisge}\marg{field label}\marg{value}
+\end{definition}
+This tests whether the value of the field given by \meta{field label}
+is greater than or equal to \meta{value}. If the field doesn't exist
+for the current entry, this evaluates to false.
+For example, the following will produce a bibliography which only
+contains entries whose "Year" field is greater than or equal to 1983:
+\begin{verbatim}
+\DTLbibliography[\DTLbibfieldisge{Year}{1983}]{mybib}
+\end{verbatim}
+
+Note that \cs{DTLbibliography} uses \cs{DTLforeachbibentry}
+(described in \autoref{sec:foreachbib}) so you may also use
+test the value of the counter \ctr{DTLbibrow} within
+\meta{conditions}. You may also use the boolean commands defined
+by the \sty{ifthen} package, such as \ics{not}.
+
+\begin{example}{Creating a list of publications since a given year}{ex:bibsince2000}
+Suppose my boss has asked me to produce a list of my
+publications in reverse chronological order, but doesn't want any
+publications published prior
+to the year 2000. I have a file called "nlct.bib" which contains
+all my publications which I keep in the directory
+\verb!$HOME/texmf/bibtex/bib/!. I could look through this file,
+work out the labels for all the publications whose year field
+is greater or equal to 2000, and
+create a file with a \cs{nocite} command containing all those labels
+in a comma separated list in reverse chronological order,
+but I really can't be bothered to do that.
+Instead, I can create the following document:
+\begin{verbatim}
+\documentclass{article}
+\usepackage{databib}
+\begin{document}
+\nocite{*}
+\DTLloadbbl{mybib}{nlct}
+\DTLsort{Year=descending,Month=descending}{mybib}
+\DTLbibliography[\DTLbibfieldisge{Year}{2000}]{mybib}
+\end{document}
+\end{verbatim}
+Suppose I save this file as "mypubs.tex", then I need to do:
+\begin{verbatim}
+latex mypubs
+bibtex mypubs
+latex mypubs
+\end{verbatim}
+Notes:
+\begin{enumerate}
+\item "\nocite{*}" is used to add all the citations in the
+bibliography file ("nlct.bib" in this case) to the \sty{databib}
+database.
+
+\item "\DTLloadbbl{mybib}{nlct}" does the following:
+\begin{enumerate}
+\item writes the line
+\begin{verbatim}
+\bibstyle{databib}
+\end{verbatim}
+to the auxiliary file. This tells \BibTeX\ to use "databib.bst"
+(which is supplied with this package). You therefore shouldn't
+use \cs{bibliographystyle}.
+
+\item writes the line
+\begin{verbatim}
+\bibdata{nlct}
+\end{verbatim}
+to the auxiliary file. This tells \BibTeX\ that the bibliography
+data is stored in the file "nlct.bib". Since I have placed this
+file in \TeX's search path, \BibTeX\ will be able to find it.
+
+\item creates a \sty{datatool} database called "mybib".
+
+\item if the \filetype{bbl} file ("mypubs.bbl" in this example) exists,
+it loads this file (which adds the bibliography data to the
+database), otherwise it does nothing further.
+
+\end{enumerate}
+
+\item In my \BibTeX\ database ("nlct.bib" in this example), I
+have remembered to use the \BibTeX\ month macros: "jan", "feb"
+etc. This means that the months are stored in the database in
+the form \cs{DTLmonthname}\marg{nn}, where \meta{nn} is a two
+digit number from 01 to 12. \cs{DTLsort} ignores command names
+when it compares strings, which means I can not only sort by
+year, but also by month\footnote{as long as I haven't put anything
+before the month name in the bibliography file, e.g.\
+\mbox{\texttt{month = "2~" \# apr}} will sort by 2~03, instead of
+03}.
+
+\item Once I have loaded and sorted my database, I can then
+display it using \cs{DTLbibliography}. This uses the style
+given by the \sty{databib} \pkgopt[databib]{style} package option,
+or the \cs{DTLbibliographystyle} command, both of which are
+described in \autoref{sec:bibstyle}.
+
+\item I have filtered the bibliography using the optional
+argument\linebreak "[\DTLbibfieldisge{Year}{2000}]", which checks if the
+year field of the current entry is greater than or equal to
+2000. (Note that if an entry has no year field, the condition
+evaluates to false, and the entry will be omitted from the
+bibliography.)
+
+\item If the bibliography database is large, sorting and creating
+the bibliography may take a while. Using \sty{databib} is much
+slower than using a standard \BibTeX\ style file.
+\end{enumerate}
+\end{example}
+
+\begin{example}{Creating a list of my 10 most recent
+publications}{ex:top10bib}
+Suppose now my boss has asked me to produce a list of my ten most
+recent publications (in reverse chronological order).
+As in the previous example, I have a file called "nlct.bib"
+which contains all my publications. I can create the required
+document as follows:
+\begin{verbatim}
+\documentclass{article}
+\usepackage{databib}
+\begin{document}
+\nocite{*}
+\DTLloadbbl{mybib}{nlct}
+\DTLsort{Year=descending,Month=descending}{mybib}
+\DTLbibliography[\value{DTLbibrow}<10]{mybib}
+\end{document}
+\end{verbatim}
+\end{example}
+
+\section{Changing the bibliography style}
+\label{sec:bibstyle}
+The style of the bibliography produced using \cs{DTLbibliography}
+depends on the \pkgopt[databib]{style}
+package option, or can be set using
+\begin{definition}[\DescribeMacro{\DTLbibliographystyle}]%
+\cs{DTLbibliographystyle}\marg{style}
+\end{definition}
+Note that this is \emph{not} the same as \cs{bibliographystyle},
+as the \sty{databib} package uses its custom \texttt{databib.bst}
+bibliography style file.
+
+Example:
+\begin{verbatim}
+\usepackage[style=plain]{databib}
+\end{verbatim}
+This sets the plain bibliography style. This is, in fact, the
+default style, so it need not be specified.
+
+Available styles are: "plain", "abbrv" and "alpha". These are similar to the
+standard \BibTeX\ styles of the same name, but are by no means
+identical. The most notable difference is that these styles
+do not sort the bibliography. It is up to you to sort the
+bibliography using \cs{DTLsort} (described in \autoref{sec:sort}).
+
+\subsection{Modifying an existing style}
+\label{sec:modbibstyle}
+
+This section describes some of the commands which are used to
+format the bibliography. You can choose whichever predefined
+style best fits your required style, and then modify the commands
+described in this section. A description of the remaining
+commands not listed in this section can be found in
+\autoref{sec:src:bibnames}, \autoref{sec:src:displaybib}
+and \autoref{sec:src:bibstyle}.
+
+\begin{definition}[\DescribeMacro{\DTLformatauthor}]%
+\cs{DTLformatauthor}\marg{von part}\marg{surname}\marg{jr part}\marg{forenames}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLformateditor}]%
+\cs{DTLformateditor}\marg{von part}\marg{surname}\marg{jr part}\marg{forenames}
+\end{definition}
+These commands are used to format an author/editor's name,
+respectively. The list of authors and editors are stored in
+the \sty{databib} database as a comma separated list of
+\marg{von part}\marg{surname}\marg{jr part}\marg{forenames}
+data. This ensures that when you sort on the Author or Editor
+field, the names will be sorted by the first author or editor's
+surname.
+
+Within \cs{DTLformatauthor} and \cs{DTLformateditor}, you may
+use the following commands:
+\begin{definition}[\DescribeMacro{\DTLformatforenames}]%
+\cs{DTLformatforenames}\marg{forenames}
+\end{definition}
+This is used by the "plain" style to display the author's
+forenames\footnote{It also checks
+whether \meta{forenames} ends with a full stop using
+\cs{DTLcheckendsperiod} to prevent a sentence ending full stop
+from following an abbreviation full stop}.
+
+\begin{definition}[\DescribeMacro{\DTLformatabbrvforenames}]%
+\cs{DTLformatabbrvforenames}\marg{forenames}
+\end{definition}
+This is used by the "abbrv" style to display the author's
+initials (which are determined from \meta{forenames}).
+Note that if any of the authors has a name starting with an
+accent, the accented letter must be grouped in order for this
+command to work. For example:
+\begin{verbatim}
+author = "{\'E}lise {\"E}awyn Edwards",
+\end{verbatim}
+The initials are formed using \cs{DTLstoreinitials} described
+in \autoref{sec:strings}, so if you want to change the way the
+initials are displayed (e.g.\ put a space between them) you will
+need to redefine the commands used by \cs{DTLstoreinitials} (such
+as \cs{DTLbetweeninitials}).
+
+\begin{definition}[\DescribeMacro{\DTLformatsurname}]%
+\cs{DTLformatsurname}\marg{surname}
+\end{definition}
+This displays its argument by default\footnote{It also checks
+whether the surname ends with a full stop using
+\cs{DTLcheckendsperiod}}.
+
+\begin{definition}[\DescribeMacro{\DTLformatvon}]%
+\cs{DTLformatvon}\marg{von part}
+\end{definition}
+If the \meta{von part} is empty, this command does nothing,
+otherwise it displays its argument followed by a
+non-breakable space.
+\begin{definition}[\DescribeMacro{\DTLformatjr}]%
+\cs{DTLformatjr}\marg{jr part}
+\end{definition}
+If the \meta{jr part} is empty, this command displays nothing,
+otherwise it displays a comma followed by its argument\footnote
+{again, it also checks \meta{jr part} to determine if it ends
+with a full stop}.
+
+For example, suppose you want the author's surname to appear
+first in small capitals, followed by a comma and the forenames. This
+can be achieved by redefining \cs{DTLformatauthor} as follows:
+\begin{verbatim}
+\renewcommand*{\DTLformatauthor}[4]{%
+\textsc{\DTLformatvon{#1}%
+\DTLformatsurname{#2}\DTLformatjr{#3}},
+\DTLformatforenames{#4}%
+}
+\end{verbatim}
+
+\begin{definition}[\DescribeCounter{DTLmaxauthors}]
+\ctrfmt{DTLmaxauthors}
+\end{definition}
+The counter \ctrfmt{DTLmaxauthors} is used to determine the
+maximum number of authors to display for a given entry. If the
+entry's author list contains more than that number of authors,
+\cs{etalname} is used, the definition of which is given in
+\autoref{sec:src:bibnames}. The default value of
+\ctrfmt{DTLmaxauthors} is \theDTLmaxauthors.
+
+\begin{definition}[\DescribeCounter{DTLmaxeditors}]
+\ctrfmt{DTLmaxeditors}
+\end{definition}
+The \ctrfmt{DTLmaxeditors} counter is analogous to the
+\ctrfmt{DTLmaxauthors} counter. It is used to determine the
+maximum number of editor names to display. The default value
+of \ctrfmt{DTLmaxeditors} is \theDTLmaxeditors.
+
+\DescribeMacro{\DTLandlast}
+Within a list of author or editor names, \cs{DTLandlast} is
+used between the last two names, otherwise
+\DescribeMacro{\DTLandnotlast}\cs{DTLandnotlast} is used between
+names.
+However, if there are only two author or editor names,
+\DescribeMacro{\DTLtwoand}\cs{DTLtwoand}
+is used instead of \cs{DTLandlast}.
+
+\DescribeMacro{\DTLendbibitem}
+The command \cs{DTLendbibitem} is a hook provided to add
+additional information at the end of each bibliography item.
+This does nothing by default, but if you want to display the
+additional fields provided by the "databib.bst" style file,
+you can redefine \cs{DTLendbibitem} so that it displays a
+particular field, if it is defined. Within this command, you
+may use the commands \cs{DTLbibfield}, \cs{DTLifbibfieldexist}
+and \cs{DTLifanybibfieldexist}, which are described in
+\autoref{sec:foreachbib}. For example, if you have used the
+"abstract" field in any of your entries, you can display the
+abstract as follows:
+\begin{verbatim}
+\renewcommand{\DTLendbibitem}{%
+\DTLifbibfieldexists{Abstract}{\DTLpar\textbf{Abstract}
+\begin{quote}\DTLbibfield{Abstract}\end{quote}}{}}
+\end{verbatim}
+(Note that \cs{DTLpar} needs to be used instead of
+\cs{par}.)
+
+\begin{example}{Compact bibliography}{ex:compactbib}
+Suppose I don't have much space in my document, and I need to
+produce a compact bibliography. Firstly, I can use the
+bibliography style "abbrv", either through the package option:
+\begin{verbatim}
+\usepackage[style=abbrv]{databib}
+\end{verbatim}
+or using:
+\begin{verbatim}
+\DTLbibliographystyle{abbrv}
+\end{verbatim}
+Once I have set the style, I can further modify it thus:
+\begin{verbatim}
+\renewcommand*{\andname}{\&}
+\renewcommand*{\editorname}{ed.}
+\renewcommand*{\editorsname}{eds.}
+\renewcommand*{\pagesname}{pp.}
+\renewcommand*{\pagename}{p.}
+\renewcommand*{\volumename}{vol.}
+\renewcommand*{\numbername}{no.}
+\renewcommand*{\editionname}{ed.}
+\renewcommand*{\techreportname}{T.R.}
+\renewcommand*{\mscthesisname}{MSc thesis}
+\end{verbatim}
+Now I can load\footnote{I can load the bibliography earlier, but
+obviously the bibliography should only be displayed after the
+bibliography styles have been set, otherwise they will have no
+effect} and display the bibliography:
+\begin{verbatim}
+ % create a database called mybib from the information given
+ % in mybib1.bib and mybib2.bib
+ \DTLloadbbl{mybib}{mybib1,mybib2}
+ % display the bibliography
+ \DTLbibliography{mybib}
+\end{verbatim}
+\end{example}
+
+\begin{example}{Highlighting a given author}{ex:highlightauthor}
+Suppose my boss wants me to produce a list of all my publications
+(which I have stored in the file "nlct.bib", as in
+\autoref{ex:bibsince2000}). Most of my
+publications have multiple co-authors, but suppose my boss would
+like me to highlight my name so that when he skims through
+the document, he can easily see my name in the list of
+co-authors. I can do this by redefining \cs{DTLformatauthor}
+so that it checks if the given surname matches mine. (This
+assumes that none of the other co-author's share my surname.)
+\begin{verbatim}
+\renewcommand*{\DTLformatauthor}[4]{%
+{\DTLifstringeq{#2}{Talbot}{\bfseries }{}%
+\DTLformatforenames{#4}
+\DTLformatvon{#1}%
+\DTLformatsurname{#2}%
+\DTLformatjr{#3}}}
+\end{verbatim}
+Notes:
+\begin{enumerate}
+\item I have used \cs{DTLifstringeq} (described in
+\autoref{sec:ifconditions}) to perform the string comparison.
+\item If one or more of my co-authors shared the same surname as
+me, I would also have had to check the first name, however there
+is regrettably a lack of consistency in my \filetype{bib} file when
+it comes to my forenames. Sometimes my name is given as
+\texttt{Nicola L. C. Talbot}, sometimes the middle initials
+are omitted, \texttt{Nicola Talbot}, or sometimes, just initials
+are used, \texttt{N. L. C. Talbot}. This can cause problems
+when checking the forenames, but as long as the other authors
+who share the same surname as me, don't also share the same
+first initial, I can use \cs{DTLifStartsWith} or \cs{DTLisPrefix},
+which are described in \autoref{sec:ifconditions} and
+\autoref{sec:ifthen}, respectively. Using the first approach
+I can do:
+\begin{verbatim}
+\renewcommand*{\DTLformatauthor}[4]{%
+{\DTLifstringeq{#2}{Talbot}{\DTLifStartsWith{#4}{N}{\bfseries }{}}{}%
+\DTLformatforenames{#4}
+\DTLformatvon{#1}%
+\DTLformatsurname{#2}%
+\DTLformatjr{#3}}}
+\end{verbatim}
+Using the second approach I can do:
+\begin{verbatim}
+\renewcommand*{\DTLformatauthor}[4]{%
+{\ifthenelse{\DTLiseq{#2}{Talbot}\and
+\DTLisPrefix{#4}{N}}{\bfseries }{}%
+\DTLformatforenames{#4}
+\DTLformatvon{#1}%
+\DTLformatsurname{#2}%
+\DTLformatjr{#3}}}
+\end{verbatim}
+
+\item I have used a group to localise the effect of \cs{bfseries}.
+\end{enumerate}
+\end{example}
+
+\section{Iterating through a
+\texorpdfstring{\sty{databib}}{databib} database}
+\label{sec:foreachbib}
+
+\cs{DTLbibliography} (described in \autoref{sec:thebib}) may still
+not meet your needs. For example, you may be required
+to list journal papers and conference proceedings in separate
+sections. In which case, you may find it easier to iterate through
+the bibliography using:
+\begin{definition}[\DescribeMacro{\DTLforeachbib}]%
+\cs{DTLforeachbib}\oarg{condition}\marg{db name}\marg{text}
+\end{definition}
+\begin{definition}[\DescribeMacro{\DTLforeachbib*}]%
+\cs{DTLforeachbib*}\oarg{condition}\marg{db name}\marg{text}
+\end{definition}
+This iterates through the \sty{databib} database called
+\meta{db name} and does \meta{text} if \meta{condition} is met.
+As with \cs{DTLforeach}, the starred version is read-only.
+
+For each row of the database, the following commands are set:
+\begin{itemize}
+\item \cs{DBIBcitekey} \DescribeMacro{\DBIBcitekey}This is the
+unique label which identifies the current entry (as used in the
+argument of \cs{cite} and \cs{nocite}).
+
+\item \cs{DBIBentrytype} \DescribeMacro{\DBIBentrytype}This
+is the current entry type, and will be one of: "article", "book",
+"booklet", "inbook", "incollection", "inproceedings",
+"manual", "mastersthesis", "misc", "phdthesis", "proceedings",
+"techreport" or "unpublished". (Note that even if you used the
+entry type "conference" in your \filetype{bib} file, its entry type
+will be set to "inproceedings").
+\end{itemize}
+
+The remaining fields may be accessed using:
+\begin{definition}[\DescribeMacro{\DTLbibfield}]%
+\cs{DTLbibfield}\marg{field label}
+\end{definition}\noindent
+where \meta{field label} may be one of: "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" or "Url".
+
+You can determine if a field exists for a given entry using
+\begin{definition}[\DescribeMacro{\DTLifbibfieldexists}]%
+\cs{DTLifbibfieldexists}\marg{field label}\marg{true part}\marg{false
+part}
+\end{definition}
+If the field given by \meta{field label} exists for the current
+bibliography entry, it does \meta{true part}, otherwise it
+does \meta{false part}.
+
+\begin{definition}[\DescribeMacro{\DTLifbibanyfieldexists}]%
+\cs{DTLifanybibfieldexists}\marg{field label list}\marg{true
+part}\marg{false part}
+\end{definition}
+This is similar to \cs{DTLifbibfieldexists} except that the
+first argument is a list of field names. If one or more of
+the fields given in \meta{field label list} exists for the
+current bibliography item, this does \meta{true part}, otherwise
+it does \meta{false part}.
+
+\begin{definition}[\DescribeMacro{\DTLformatbibentry}]%
+\cs{DTLformatbibentry}
+\end{definition}
+This formats the bibliography entry for the current row. It
+checks for the existence of the command
+\cs{DTLformat}\meta{entry type}, where \meta{entry type}
+is given by \cs{DBIBentrytype}. These commands are defined
+by the bibliography style.
+
+\begin{definition}[\DescribeMacro{\DTLcomputewidestbibentry}]%
+\cs{DTLcomputewidestbibentry}\marg{conditions}\marg{db
+name}\marg{bib label}\marg{cmd}
+\end{definition}
+This computes the widest bibliography entry over all entries
+satisfying \meta{conditions} in the database \meta{db name},
+where the label is given by \meta{bib label}, and the result
+is stored in \meta{cmd}, which may then be used in the
+argument of the \env{thebibliography} environment.
+
+The counter \desctr{DTLbibrow} keeps track of the current
+bibliography entry. This is reset at the start of each
+\cs{DTLforeachbib} and is incremented if \meta{conditions}
+is met.
+
+Within the optional argument \meta{condition}, you may use any of the
+commands that may be used within the optional argument of
+\cs{DTLbibliography}, described in \autoref{sec:thebib}.
+
+\begin{example}{Separate List of Journals and Conference Papers}{ex:jcbib}
+Suppose now my boss has decided that I need to produce a list
+of all my publications, but they need to be separated so that
+all the journal papers appear in one section, and all the
+conference papers appear in another section. The journal papers
+need to be labelled [J1], [J2] and so on, while the conference
+papers need to be labelled [C1], [C2] and so on. (My boss isn't
+interested in any of my other publications!) Again, all my
+publications are stored in the \BibTeX\ database "nlct.bib". The
+following creates the required document:
+\begin{verbatim}
+\documentclass{article}
+\usepackage{databib}
+\begin{document}
+\nocite{*}
+\DTLloadbbl{mybib}{nlct}
+
+\renewcommand*{\refname}{Journal Papers}
+\DTLcomputewidestbibentry{\equal{\DBIBentrytype}{article}}
+{mybib}{J\theDTLbibrow}{\widest}
+
+\begin{thebibliography}{\widest}
+\DTLforeachbibentry[\equal{\DBIBentrytype}{article}]{mybib}{%
+\bibitem[J\theDTLbibrow]{\DBIBcitekey} \DTLformatbibentry}
+\end{thebibliography}
+
+\renewcommand*{\refname}{Conference Papers}
+\DTLcomputewidestbibentry{\equal{\DBIBentrytype}{inproceedings}}
+{mybib}{C\theDTLbibrow}{\widest}
+
+\begin{thebibliography}{\widest}
+\DTLforeachbibentry[\equal{\DBIBentrytype}{inproceedings}]{mybib}{%
+\bibitem[C\theDTLbibrow]{\DBIBcitekey} \DTLformatbibentry}
+\end{thebibliography}
+
+\end{document}
+\end{verbatim}
+\end{example}
+
+\section{Multiple Bibliographies}
+\label{sec:multibib}
+
+It is possible to have more than one bibliography in a document,
+but it then becomes necessary to have a separate auxiliary file
+for each bibliography, and each auxiliary file must then be
+passed to \BibTeX. In order to do this, you need to use
+\begin{definition}[\DescribeMacro{\DTLmultibibs}]%
+\cs{DTLmultibibs}\marg{name list}
+\end{definition}
+where \meta{name list} is a comma separated list of names,
+\meta{name}. For each \meta{name}, this command creates an
+auxiliary file called \meta{name}".aux" (note that this
+command may only be used in the preamble).
+
+When you want to cite an entry for a given bibliography named
+in \cs{DTLmultibibs}, you must use:
+\begin{definition}[\DescribeMacro{\DTLcite}]%
+\cs{DTLcite}\oarg{text}\marg{mbib}\marg{cite key list}
+\end{definition}\noindent
+This is analogous to \cs{cite}\oarg{text}\marg{cite key list},
+but writes the \cs{citation} command to \meta{mbib}".aux" instead
+of to the document's main auxiliary file. It also ensures that
+the cross-referencing labels are based on \meta{mbib}, to allow
+you to have the same reference in more than one bibliography
+without incurring a ``multiply defined'' warning message. Note
+that you can still use \cs{cite} to add citation information to
+the main auxiliary file.
+
+If you want to add an entry to the bibliography without producing
+any text, you can use
+\begin{definition}[\DescribeMacro{\DTLnocite}]
+\cs{DTLnocite}\marg{mbib}\marg{cite key list}
+\end{definition}\noindent
+which is analogous to \cs{nocite}\marg{cite key list}, where
+again the citation information is written to \meta{mbib}".aux"
+instead of the document's main auxiliary file.
+
+Note that for both \cs{DTLcite} and \cs{DTLnocite} the
+\meta{mbib} part must be one of the names listed in
+\cs{DTLmultibibs}.
+
+\begin{definition}[\DescribeMacro{\DTLloadmbbl}]%
+\cs{DTLloadmbbl}\marg{mbib}\marg{db name}\marg{bib list}
+\end{definition}
+This is analogous to \cs{DTLloadbbl}\marg{db name}\marg{bib list}
+described in \autoref{sec:loadbbl}. (Again \meta{mbib} must be
+one of the names listed in \cs{DTLmultibibs}.) This creates
+a new \sty{datatool} database called \meta{db name} and loads the
+bibliography information from \meta{mbib}".bbl" (if it exists).
+
+\begin{definition}[\DescribeMacro{\DTLmbibliography}]%
+\cs{DTLmbibliography}\oarg{condition}\marg{mbib}\marg{db name}
+\end{definition}
+This is analogous to \cs{DTLbibliography}\oarg{condition}\marg{db name},
+but is required when displaying a bibliography in which elements have
+been cited using \cs{DTLcite} and \cs{DTLnocite}.
+
+\begin{example}{Multiple Bibliographies}{ex:multibib}
+Suppose I need to create a document which contains a section listing
+all my publications, but I also need to have separate sections
+covering each of my research topics, with a mini-bibliography
+at the end of each section. As in the earlier examples, all my
+publications are stored in the file "nlct.bib" which is somewhere
+on \TeX's path. Note that there will be some duplication as the
+references in the mini-bibliographies will also appear in the
+main bibliography at the end of the document, but using
+\cs{DTLcite} and \cs{DTLmbibliography} ensures that all the
+cross-referencing labels (and hyperlinks if they are enabled)
+are unique.
+\begin{verbatim}
+\documentclass{article}
+\usepackage{databib}
+\DTLmultibibs{kernel,food}
+\begin{document}
+\section{Kernel methods}
+In this section I'm going to describe some research work into
+kernel methods, and in the process I'm going to cite some related
+papers \DTLcite{kernel}{Cawley2007a,Cawley2006a}.
+
+\DTLloadmbbl{kernel}{kernelDB}{nlct}
+\DTLmbibliography{kernel}{kernelDB}
+
+\section{Food research}
+
+In this section I'm going to describe some research work
+in the area of food safety, and in the process, I'm going
+to cite some related papers \DTLcite{food}{Peck1999,Barker1999a}
+
+\DTLloadmbbl{food}{foodDB}{nlct}
+\DTLmbibliography{food}{foodDB}
+
+\cite{*}
+\renewcommand{\refname}{Complete List of Publications}
+\DTLloadbbl{fullDB}{nlct}
+\DTLbibliography{fullDB}
+\end{document}
+\end{verbatim}
+Notes:
+\begin{enumerate}
+\item This will create the files "kernel.aux" and "food.aux".
+These will have to be passed to \BibTeX, in addition to the
+documents main auxiliary file. So, if my document is called
+"researchwork.tex", then I need to do:
+\begin{verbatim}
+latex researchwork
+bibtex researchwork
+bibtex kernel
+bibtex food
+latex researchwork
+latex researchwork
+\end{verbatim}
+
+\item "\cite{*}" is used to add all the entries in the bib file
+to the main bibliography database. As before, \cs{DTLloadbbl}
+and \cs{DTLbibliography} are used to load and display the main
+bibliography.
+\end{enumerate}
+\end{example}
+
+\begin{important}
+Don't try to directly input the ".bbl" file using \cs{input} (or
+\cs{include}) instead of using \cs{DTLloadbbl} or \cs{DTLloadmbbl}
+as these commands store the name of the required database and
+initialise the database before loading the \texttt{.bbl} file.
+Similarly, don't just copy the contents of the ".bbl" file into your
+document without first defining the database using \ics{DTLnewdb}
+and setting \ics{DTLBIBdbname} to the name of the database.
+\end{important}
+
+\chapter{Referencing People (\sty{person} package)}
+\label{sec:person}
+
+Sometimes when mail-merging, it may be necessary to reference a
+person by their pronoun which can lead to the cumbersome and
+impersonal ``he/she'' construct. The \sty{person} package
+allows you to define a person by their full name, familiar name and
+gender. You can then use the commands described in
+\autoref{sec:refperson} to produce the appropriate pronoun.
+
+This can also be useful for other types of documents, such as an
+order of service for a baptism or funeral. Since the
+document is much the same from one person to the next, documents of
+this nature are frequently simply copied and a search and replace
+edit is used to change the relevant text. However this can lead to
+errors (especially if the previous person's name was Mary!) With
+the \sty{person} package, you need only change the definition of
+the person by modifying the arguments of \cs{newperson}.
+
+\section{Defining and Undefining People}
+
+A person is defined (globally) using the command:
+\begin{definition}[\DescribeMacro{\newperson}]
+\cs{newperson}\oarg{label}\marg{full name}\marg{familiar name}\marg{gender}
+\end{definition}
+The optional argument is a unique label identifying this person,
+in the event that there is more than one person. If \meta{label}
+is omitted \texttt{anon} is used. (This is also the case for
+subsequent commands that take an optional label.)
+The gender may be any of those given by
+\begin{definition}[\DescribeMacro{\malelabels}]
+\cs{malelabels}
+\end{definition}
+or
+\begin{definition}[\DescribeMacro{\femalelabels}]
+\cs{femalelabels}
+\end{definition}
+The default definition of \cs{malelabels} is \texttt{\malelabels}
+and the default definition of \cs{femalelabels} is
+\texttt{\femalelabels}. You can add extra identifiers using
+\begin{definition}[\DescribeMacro{\addmalelabel}]
+\cs{addmalelabel}\marg{identifier}
+\end{definition}
+or
+\begin{definition}[\DescribeMacro{\addfemalelabel}]
+\cs{addfemalelabel}\marg{identifier}
+\end{definition}
+For example:
+\begin{verbatim}
+\addmalelabel{boy}
+\addfemalelabel{girl}
+\end{verbatim}
+
+The total number of defined people is given by:
+\begin{definition}[\DescribeMacro{\thepeople}]
+\cs{thepeople}
+\end{definition}
+
+A person can be undefined using:
+\begin{definition}[\DescribeMacro{\removeperson}]
+\cs{removeperson}\oarg{label}
+\end{definition}
+where the person is given by \meta{label}.
+
+If more than one person has been defined, they can all be
+removed using:
+\begin{definition}[\DescribeMacro{\removeallpeople}]
+\cs{removeallpeople}
+\end{definition}
+or you can remove a subset using:
+\begin{definition}[\DescribeMacro{\removepeople}]
+\cs{removepeople}\marg{list}
+\end{definition}
+where \meta{list} is a comma-separated list of labels.
+
+\section{Displaying Information}
+\label{sec:refperson}
+
+Once a person has been defined, you can display their name using:
+\begin{definition}[\DescribeMacro{\personfullname}]
+\cs{personfullname}\oarg{label}
+\end{definition}
+where \meta{label} is the unique label used in the optional
+argument to \cs{newperson}. The person's familiar name is displayed
+using:
+\begin{definition}[\DescribeMacro{\personname}]
+\cs{personname}\oarg{label}
+\end{definition}
+The person's pronoun (``he'' or ``she'') is displayed using:
+\begin{definition}[\DescribeMacro{\personpronoun}]
+\cs{personpronoun}\oarg{label}
+\end{definition}
+The objective pronoun (``him'' or ``her'') is displayed using:
+\begin{definition}[\DescribeMacro{\personobjpronoun}]
+\cs{personobjpronoun}\oarg{label}
+\end{definition}
+The possessive adjective (``his'' or ``her'') is displayed using:
+\begin{definition}[\DescribeMacro{\personpossadj}]
+\cs{personpossadj}\oarg{label}
+\end{definition}
+The possessive pronoun ``his'' or ``hers'' is displayed using:
+\begin{definition}[\DescribeMacro{\personposspronoun}]
+\cs{personposspronoun}\oarg{label}
+\end{definition}
+The person's relationship to their parent (``son'' or ``daughter'')
+is displayed using:
+\begin{definition}[\DescribeMacro{\personchild}]
+\cs{personchild}\oarg{label}
+\end{definition}
+The person's relationship to their child (``mother'' or ``father'')
+is displayed using:
+\begin{definition}[\DescribeMacro{\personparent}]
+\cs{personparent}\oarg{label}
+\end{definition}
+The person's relationship to their sibling (``brother'' or
+``sister'') is displayed using:
+\begin{definition}[\DescribeMacro{\personsibling}]
+\cs{personsibling}\oarg{label}
+\end{definition}
+
+If the word occurs at the start of a sentence, you will need one
+of the following commands, which are as the above, except the
+first letter is converted to upper case:
+\begin{definition}[\DescribeMacro{\Personpronoun}]
+\cs{Personpronoun}\oarg{label}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Personobjpronoun}]
+\cs{Personobjpronoun}\oarg{label}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Personpossadj}]
+\cs{Personpossadj}\oarg{label}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Personposspronoun}]
+\cs{Personposspronoun}\oarg{label}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Personchild}]
+\cs{Personchild}\oarg{label}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Personparent}]
+\cs{Personparent}\oarg{label}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Personsibling}]
+\cs{Personsibling}\oarg{label}
+\end{definition}
+
+\begin{example}{Order of Service (Memorial)}{ex:memorial}
+This example is for a memorial order of service.
+
+\begin{verbatim}
+\documentclass{article}
+
+\usepackage{person}
+
+\newperson{Jane Doe}{Jane}{female}
+
+\begin{document}
+\begin{center}
+\Large
+In Memory of \personfullname
+\end{center}
+
+We are gathered here to remember our \personsibling\ \personname.
+\Personpronoun\ will be much missed, and \personpossadj\
+family are in our prayers.
+\end{document}
+\end{verbatim}
+
+\newperson{Jane Doe}{Jane}{female}
+\begin{center}
+\Large
+In Memory of \personfullname
+\end{center}
+
+We are gathered here to remember our \personsibling\ \personname.
+\Personpronoun\ will be much missed, and \personpossadj\
+family are in our prayers.
+\removeperson
+
+\end{example}
+
+If there is more than one person, you will need to use the
+optional argument \meta{label} to \cs{newperson} to uniquely
+identify each person. You can then list all of the people's full
+or familiar names using:
+\begin{definition}[\DescribeMacro{\peoplefullname}]
+\cs{peoplefullname}
+\end{definition}
+\begin{definition}[\DescribeMacro{\peoplename}]
+\cs{peoplename}
+\end{definition}
+Note that if there is only one person defined, these commands behave
+the same as \cs{personfullname}\oarg{label} and
+\cs{personname}[\meta{label}].
+
+Similarly for the pronouns:
+\begin{definition}[\DescribeMacro{\peoplepronoun}]
+\cs{peoplepronoun}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Peoplepronoun}]
+\cs{Peoplepronoun}
+\end{definition}
+\begin{definition}[\DescribeMacro{\peopleobjpronoun}]
+\cs{peopleobjpronoun}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Peopleobjpronoun}]
+\cs{Peopleobjpronoun}
+\end{definition}
+\begin{definition}[\DescribeMacro{\peoplepossadj}]
+\cs{peoplepossadj}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Peoplepossadj}]
+\cs{Peoplepossadj}
+\end{definition}
+\begin{definition}[\DescribeMacro{\peopleposspronoun}]
+\cs{peopleposspronoun}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Peopleposspronoun}]
+\cs{Peopleposspronoun}
+\end{definition}
+where, again, if only one person has been defined, each of these
+commands is equivalent to
+\cs{person}\ldots\oarg{label} or
+\cs{Person}\ldots\oarg{label}. If more than
+one person has been defined, these commands will display
+they/them/their/theirs or They/Them/Their/Theirs, as appropriate.
+
+Likewise for relationship commands:
+\begin{definition}[\DescribeMacro{\peoplechild}]
+\cs{peoplechild}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Peoplechild}]
+\cs{Peoplechild}
+\end{definition}
+\begin{definition}[\DescribeMacro{\peopleparent}]
+\cs{peopleparent}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Peopleparent}]
+\cs{Peopleparent}
+\end{definition}
+\begin{definition}[\DescribeMacro{\peoplesibling}]
+\cs{peoplesibling}
+\end{definition}
+\begin{definition}[\DescribeMacro{\Peoplesibling}]
+\cs{Peoplesibling}
+\end{definition}
+
+\begin{example}{Order of Service (Baptism)}{ex:baptism}
+In this example two people are defined.
+\begin{verbatim}
+\documentclass{article}
+
+\usepackage{person}
+
+\newperson[john]{John Joseph}{John}{male}
+\newperson[jane]{Jane Mary}{Jane}{female}
+
+\begin{document}
+\begin{center}
+\Large
+Baptism of \peoplefullname.
+\end{center}
+
+Today we welcome \peoplename\ into God's family, may He guide
+and protect \peopleobjpronoun.
+\end{document}
+\end{verbatim}
+
+This is produces the following text:
+
+\newperson[john]{John Joseph}{John}{male}
+\newperson[jane]{Jane Mary}{Jane}{female}
+
+\begin{center}
+\Large
+Baptism of \peoplefullname.
+\end{center}
+
+Today we welcome \peoplename\ into God's family, may He guide
+and protect \peopleobjpronoun.
+\removeallpeople
+\end{example}
+
+\begin{example}{Mail Merging Using Appropriate Gender}{ex:personmerge}
+In this example I have a CSV file called \texttt{students.csv}
+containing the following:
+\begin{verbatim}
+FirstName,Surname,Gender,Parent,Address
+John,"Smith, Jr",M,Mr and Mrs Smith,1 The Street\\Newtown
+Jane,Brown,F,Ms Brown,2 The Avenue\\Oldtown
+Andy,Brown,male,Mr Brown and Miss Sepia,3 The Road\\Newtown
+Z\"oe,Adams,f,Mr and Mrs Adams,5 The Street\\Newtown
+Roger,Brady,m,Mrs Brady,6 The Avenue\\Oldtowm
+Clare,Vernon,female,Mr Vernon,7 The Close\\Anytown
+\end{verbatim}
+Suppose I have to write to each student's parents regarding their
+child. I can load the information using \ics{DTLloaddb} (described
+in \autoref{sec:loaddb}). I can then iterate through the database
+and define the student as a person and use the commands defined in
+the \sty{person} package to display the correct gender related text.
+I could give each person a unique label based on the row count
+(\ics{DTLcurrentindex}), but since I don't need to reuse the
+information, I can use the default "anon" label and undefine the
+person when no longer required.
+
+Note that in the CSV file, the gender label isn't consistent.
+For some students the gender is identified by a single letter
+(``m'' or ``f'') and for others the gender is identified by a
+complete word (``male'' or ``female''). There's also no regard
+for case. This doesn't matter to \ics{newperson} as all the
+identifiers used are listed in \ics{malelabels} and
+\ics{femalelabels}.
+
+The following is an example letter sent to all parents:
+\begin{verbatim}
+\documentclass{letter}
+\usepackage{person}
+
+% load student information from file "students.csv"
+\DTLloaddb{students}{students.csv}
+\begin{document}
+% Iterate through the student database:
+\DTLforeach{students}{\FirstName=FirstName,\Surname=Surname,%
+\Gender=Gender,\Parent=Parent,\Address=Address}{%
+% Define "anon":
+ \newperson{\FirstName\space\Surname}{\FirstName}{\Gender}%
+% Do the letter:
+ \begin{letter}{\Parent\\\Address}
+ \opening{Dear \Parent}
+ Your \personchild\ \personname\ has been awarded a
+ place. We look forward to seeing \personobjpronoun\
+ on \personpossadj\ arrival.
+ \closing{Yours Sincerely}
+ \end{letter}
+% Undefine "anon":
+ \removeperson
+}
+\end{document}
+\end{verbatim}
+
+The body of the first letter appears as follows:
+\newperson{John Smith Jr}{John}{m}
+\par\vskip\baselineskip
+
+ Your \personchild\ \personname\ has been awarded a
+ place. We look forward to seeing \personobjpronoun\
+ on \personpossadj\ arrival.
+
+\removeperson
+\par\vskip\baselineskip
+Whereas the body of the second letter appears as follows:
+\newperson{Jane Brown}{Jane}{f}
+\par\vskip\baselineskip
+
+ Your \personchild\ \personname\ has been awarded a
+ place. We look forward to seeing \personobjpronoun\
+ on \personpossadj\ arrival.
+
+\removeperson
+\end{example}
+
+\section{Advanced Commands}
+
+This section describes additional commands provided by the
+\sty{person} package. More detail can be found in
+the documented code (datatool.pdf).
+
+\subsection{Conditionals}
+
+\begin{definition}[\DescribeMacro{\ifpersonexists}]
+\cs{ifpersonexists}\marg{label}\marg{true part}\marg{false part}
+\end{definition}
+Tests if the person identified by \meta{label} has been defined.
+If true, do \meta{true part} otherwise do \meta{false part}.
+
+\begin{definition}[\DescribeMacro{\ifmale}]
+\cs{ifmale}\marg{label}\marg{true part}\marg{false part}
+\end{definition}
+Test if the person identified by \meta{label} is male.
+If true, do \meta{true part} otherwise do \meta{false part}.
+
+\begin{definition}[\DescribeMacro{\iffemale}]
+\cs{iffemale}\marg{label}\marg{true part}\marg{false part}
+\end{definition}
+Test if the person identified by \meta{label} is female.
+If true, do \meta{true part} otherwise do \meta{false part}.
+
+\begin{definition}[\DescribeMacro{\ifallmale}]
+\cs{ifallmale}\oarg{label list}\marg{true part}\marg{false part}
+\end{definition}
+Tests if all the people listed in \meta{label list} are male.
+If true, do \meta{true part} otherwise do \meta{false part}.
+If \meta{label list} is omitted, applied to all defined people.
+\begin{definition}[\DescribeMacro{\ifallfemale}]
+\cs{ifallfemale}\oarg{label list}\marg{true part}\marg{false part}
+\end{definition}
+Likewise to test if all the people tested are female.
+
+To determine if a string is an allowed male label:
+\begin{definition}[\DescribeMacro{\ifmalelabel}]
+\cs{ifmalelabel}\marg{identifier}\marg{true part}\marg{false part}
+\end{definition}
+where \meta{identifier} is the string to be tested. If true, do
+\meta{true part} otherwise do \meta{false part}.
+For example:
+\begin{verbatim}
+\def\gender{M}
+\ifmalelabel{\gender}{male}{not male}
+\end{verbatim}
+Similarly to for an allowed female label:
+\begin{definition}[\DescribeMacro{\iffemalelabel}]
+\cs{iffemalelabel}\marg{identifier}\marg{true part}\marg{false part}
+\end{definition}
+For example:
+\begin{verbatim}
+\ifmalelabel{\gender}{Male}{%
+ \iffemalelabel{\gender}{Female}%
+ {Undefined Gender}%
+}
+\end{verbatim}
+
+\subsection{Iterating Through Defined People}
+
+You can iterate through all defined people using:
+\begin{definition}[\DescribeMacro{\foreachperson}]
+\cs{foreachperson}(\meta{name cs},\meta{full name cs},\meta{gender cs},\meta{label cs})\cs{do}\marg{body}
+\end{definition}
+At each iteration, \meta{name cs}, \meta{full name cs},
+\meta{gender cs} and \meta{label cs} are set to the current person's
+name, full name, gender and label, respectively. (These arguments
+must all be command names.) Note that the gender is set to
+the definition of \DescribeMacro{\malename}\cs{malename} or
+\DescribeMacro{\femalename}\cs{femalename}, as appropriate.\footnote{Predefined names provided by the \sty{person} package are described
+in the documented code (datatool.pdf).} Once these
+commands are set, \meta{body} is applied.
+
+If you only want to iterate through a subset of defined people,
+you can use:
+\begin{definition}
+\cs{foreachperson}(\meta{name cs},\meta{full name cs},\meta{gender cs},\meta{label cs})\cs{in}\marg{list}\cs{do}\marg{body}
+\end{definition}
+where \meta{list} is a comma-separated list of labels.
+
+\subsection{Accessing Individual Information}
+
+\begin{definition}[\DescribeMacro{\getpersongender}]
+\cs{getpersongender}\marg{cs}\marg{label}
+\end{definition}
+Gets the gender of the person identified by \meta{label} and
+stores in \meta{cs} (which must be a command name). This
+sets \meta{cs} to the definition of \ics{malename} or
+\ics{femalename} as appropriate.
+
+\begin{definition}[\DescribeMacro{\getpersonname}]
+\cs{getpersonname}\marg{cs}\marg{label}
+\end{definition}
+Gets the name of the person identified by \meta{label} and
+stores in \meta{cs} (which must be a command name).
+
+\begin{definition}[\DescribeMacro{\getpersonfullname}]
+\cs{getpersonfullname}\marg{cs}\marg{label}
+\end{definition}
+Gets the full name of the person identified by \meta{label} and
+stores in \meta{cs} (which must be a command name).
+
+\clearpage
+\phantomsection
+\addcontentsline{toc}{chapter}{\bibname}
+\DTLbibliography{docbib}
+
+\clearpage
+\phantomsection
+\addcontentsline{toc}{chapter}{Acknowledgements}
+\chapter*{Acknowledgements}
+
+Many thanks to Morten~H\o gholm for suggesting a much more
+efficient way of storing the information in databases which
+has significantly improved the time it takes to \LaTeX\ documents
+containing large databases.
+
+\clearpage
+\phantomsection
+\addcontentsline{toc}{chapter}{Index}\PrintIndex
+
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/datatool/datatool.pdf b/Master/texmf-dist/doc/latex/datatool/datatool.pdf
index 61220a750bb..bd25ebec2ea 100644
--- a/Master/texmf-dist/doc/latex/datatool/datatool.pdf
+++ b/Master/texmf-dist/doc/latex/datatool/datatool.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.pdf
new file mode 100644
index 00000000000..89ea8bf27c2
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.tex
new file mode 100644
index 00000000000..142f1eeb810
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-barchart.tex
@@ -0,0 +1,57 @@
+ % This file is public domain.
+\documentclass[captions=tableheading]{scrartcl}
+
+\usepackage{tikz}
+\usetikzlibrary{snakes}
+
+\usepackage{databar}
+
+\DTLloaddb{marks}{sample-student-records.csv}
+
+\begin{document}
+
+% Compute average mark for each student:
+\DTLforeach{marks}{%
+\assignI=Assignment 1,%
+\assignII=Assignment 2,%
+\assignIII=Assignment 3}{%
+\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}%
+\DTLround{\theMean}{\theMean}{0}\DTLclip{\theMean}{\theMean}%
+\DTLappendtorow{Average}{\theMean}}
+
+\begin{table}
+\caption{Student Marks}
+ \centering
+\DTLdisplaydb[Address,RegNum,Title]{marks}
+\end{table}
+
+\begin{figure}[htbp]
+ \centering
+ % compute the overall mean
+ \DTLmeanforkeys{marks}{Average}{\overallmean}
+ % round it to 2 decimal places
+ \DTLround{\overallmean}{\overallmean}{2}
+ % draw a grey dotted line indicating the overall mean
+ % covering the entire width of the bar chart
+ \renewcommand*{\DTLbaratendtikz}{%
+ \draw[lightgray,loosely dotted] (0,\overallmean) --
+ (\DTLbarchartwidth,\overallmean)
+ node[right,black]{Average (\overallmean)};}
+ % Set the lower bar labels to draw a brace across the current
+ % group, along with the student's name and average score
+ \renewcommand*{\DTLdisplaylowerbarlabel}[1]{%
+ \tikz[baseline=(current bounding box.center)]{
+ \draw[snake=brace,rotate=-90](0,0) -- (\DTLbargroupwidth,0);}
+ \DTLround{\theMean}{\theMean}{2}%
+ \shortstack{#1\\(Average: \theMean)}}
+ % draw the bar chart
+ \DTLmultibarchart{variables={\assignI,\assignII,\assignIII},
+ barwidth=10pt,uppermultibarlabels={\assignI,\assignII,\assignIII},
+ barlabel={\firstname\ \surname}}{marks}
+ {\surname=Surname,\firstname=First Name,\assignI=Assignment 1,%
+ \assignII=Assignment 2,\assignIII=Assignment 3,\theMean=Average}
+ \caption{Student marks}
+\end{figure}
+
+
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.pdf
new file mode 100644
index 00000000000..73fb2f1c83e
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.tex
new file mode 100644
index 00000000000..384584e540e
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-mail-merge.tex
@@ -0,0 +1,21 @@
+ % This file is public domain.
+\documentclass{scrlttr2}
+
+\usepackage{datatool}
+
+\DTLloaddb{data}{sample-student-records.csv}
+
+\begin{document}
+\begin{DTLenvforeach*}{data}{\Title=Title,\FirstName=First Name,\Surname=Surname,\AssignmentI=Assignment 1,\AssignmentII=Assignment 2,\AssignmentIII=Assignment 3,\Address=Address}
+\begin{letter}{\Title\space\FirstName\space\Surname\\\Address}
+\opening{Dear \Title~\Surname}
+
+\DTLmeanforall{\Score}{\AssignmentI,\AssignmentII,\AssignmentIII}
+\DTLround{\Score}{\Score}{0}\DTLclip{\Score}{\Score}%
+You were awarded a mark of \Score\%.
+
+\closing{Yours Sincerely}
+\end{letter}
+
+\end{DTLenvforeach*}
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.pdf
new file mode 100644
index 00000000000..43d1a30f341
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.tex
new file mode 100644
index 00000000000..2bcd49dcf61
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-piechart.tex
@@ -0,0 +1,36 @@
+ % This file is public domain.
+\documentclass[captions=tableheading]{scrartcl}
+
+\usepackage{datapie}
+
+\DTLloaddb{marks}{sample-student-records.csv}
+
+\begin{document}
+
+% Compute average mark for each student:
+\DTLforeach{marks}{%
+\assignI=Assignment 1,%
+\assignII=Assignment 2,%
+\assignIII=Assignment 3}{%
+\DTLmeanforall{\theMean}{\assignI,\assignII,\assignIII}%
+\DTLround{\theMean}{\theMean}{0}\DTLclip{\theMean}{\theMean}%
+\DTLappendtorow{Average}{\theMean}}
+
+% Sort according to average mark
+\DTLsort{Average=descending}{marks}
+
+\begin{table}
+\caption{Student Marks}
+\centering
+\DTLdisplaydb[Address,RegNum,Title]{marks}
+\end{table}
+
+\begin{figure}
+\caption{Pie Chart}
+\centering
+\DTLpiechart{variable=\Average,outerlabel={\Surname, \FirstName},rotateouter}{marks}%
+ {\Average=Average,\Surname=Surname,\FirstName=First
+Name}
+\end{figure}
+
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-student-records.csv b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-records.csv
new file mode 100644
index 00000000000..b8d212d4885
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-records.csv
@@ -0,0 +1,7 @@
+"Title","First Name","Surname","RegNum","Assignment 1","Assignment 2","Assignment 3","Address"
+"Miss","Jane","Brown",1234567891,75,84,80,"Flat 1a\\The Street\\The Town"
+"Mr","John","Smith, Jr",1234567892,68,57,72,"Flat 1b\\The Street\\The Town"
+"Mr","Zack","Watts",1234567893,32,43,49,"Flat 1c\\The Street\\The Town"
+"Mrs","Hillary","Rix",1234567894,87,88,86,"Flat 1d\\The Street\\The Town"
+"Miss","Z\""oe","Adams",1234567895,52,48,57,"Flat 1e\\The Street\\The Town"
+"Mr","Andy","Brown",1234567896,42,52,54,"Flat 1f\\The Street\\The Town"
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.pdf
new file mode 100644
index 00000000000..1abee68d126
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.tex
new file mode 100644
index 00000000000..ff61d4dbbff
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-student-scores.tex
@@ -0,0 +1,34 @@
+ % This file is public domain.
+\documentclass[captions=tableheading]{scrartcl}
+
+\usepackage{datatool}
+\usepackage{longtable}
+
+\DTLloaddb{scores}{sample-student-records.csv}
+
+\begin{document}
+Sort by surname, then first name:
+\DTLsort{Surname,First Name}{scores}
+
+% omit Address column
+\DTLdisplaydb[Address]{scores}
+
+Sort by assignment 1 score in descending order:
+\DTLsort{Assignment 1=descending}{scores}
+
+% omit Address column
+\DTLdisplaydb[Address]{scores}
+
+Average score:
+\DTLmeanforcolumn{scores}{Assignment 1}{\averagescore}%
+\averagescore\%.
+Rounded to two decimal places: \DTLround{\averagescore}{\averagescore}{2}%
+\averagescore\%.
+
+A long list will require the longtable environment (supplied by
+longtable.sty). Example in Table~\ref{tab:records}.
+
+% Omit RegNum and Address columns
+\DTLdisplaylongdb[caption={Student Scores},label={tab:records},omit={RegNum,Address}]{scores}
+
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.pdf b/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.pdf
new file mode 100644
index 00000000000..17676a1093f
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.tex b/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.tex
new file mode 100644
index 00000000000..c8f266d739a
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/datatool/samples/sample-two-per-row.tex
@@ -0,0 +1,55 @@
+ % This file is public domain.
+\documentclass[captions=tableheading]{scrartcl}
+
+\usepackage{datatool}
+
+\DTLloaddb{scores}{sample-student-records.csv}
+% Sort by surname then first name
+\DTLsort{Surname,First Name}{scores}
+
+\begin{document}
+
+\begin{table}[htbp]
+ \caption{Two database rows per tabular row}
+ \centering
+ \begin{tabular}{llcllc}
+ \bfseries First Name &
+ \bfseries Surname &
+ \bfseries Assignment 1 (\%) &
+ \bfseries First Name &
+ \bfseries Surname &
+ \bfseries Assignment 1 (\%)%
+ \DTLforeach*{scores}{\firstname=First Name,\surname=Surname,\score=Assignment 1}{%
+ \DTLifoddrow{\\}{&}%
+ \firstname & \surname & \score}%
+ \end{tabular}
+\end{table}
+
+\begin{table}[htbp]
+ \caption{Two database rows per tabular row (column-wise)}
+ \centering
+ % store half number of rows
+ \edef\maxrows{\DTLrowcount{scores}}%
+ \DTLdiv{\halfrowidx}{\maxrows}{2}
+ \begin{tabular}{llcllc}
+ \bfseries First Name &
+ \bfseries Surname &
+ \bfseries Assignment 1 (\%) &
+ \bfseries First Name &
+ \bfseries Surname &
+ \bfseries Assignment 1 (\%)%
+ \DTLforeach*[\value{DTLrowi}<\halfrowidx]{scores}%
+ {\firstname=First Name,\surname=Surname,\score=Assignment 1}%
+ {%
+ \\%
+ \firstname & \surname & \score
+ &
+ \edef\currentrowidx{\arabic{DTLrowi}}%
+ \DTLadd{\rowidxII}{\halfrowidx}{\currentrowidx}%
+ \DTLassign{scores}{\rowidxII}{\firstnameII=First Name,\surnameII=Surname,\scoreII=Assignment 1}%
+ \firstnameII & \surnameII & \scoreII
+ }%
+ \end{tabular}
+\end{table}
+
+\end{document}