The datatool bundle includes the following documentation:
- User Manual for datatool (datatool-user.pdf)
- This document is the main user guide for the datatool package.
- Documented Code for datatool (datatool-code.pdf)
- Advanced users wishing to know more about the inner workings of all the packages provided in the datatool bundle should read “Documented Code for datatool v3.0”.
- CHANGES
- Change log.
- README.md
- Package summary.
- DEPENDS.txt
- List of all packages unconditionally required by datatool (hard dependencies). Other unlisted packages may be required under certain circumstances. For help on installing packages see, for example, How do I update my TeX distribution? or (for Linux users) Updating TeX on Linux.
Related resources:
If an example shows the icon 📥🖹 then you can click on that icon to try downloading the example source code from a location relative to this document. You can also try using:
The following packages are provided by the datatool bundle:
Main package providing database support.
Automatically loads datatool-base.
This package can be used to:
The datagidx package (see §8) can be used
to generate indexes or glossaries as an alternative to packages
such as glossaries. Note that datagidx is far more
limited than glossaries and doesn’t provide any localisation
support. See §8.
The datapie package can be used to convert a database into
a pie chart:
The dataplot package can be used to convert a database into
a two dimensional plot using markers and/or lines. Three dimensional
plots are currently not supported.
See §6.
The databar package can be used to convert a database into
a bar chart:
The databib package can be used to convert a BibTeX database
into a datatool database.
See §7.
The person package can be used to reference people by the
appropriate gender pronouns. Automatically loads datatool.
See §9.
The code providing the mathematical functions have some limitations.
These limitations will therefore also be present in the various
packages provided with datatool, according to the underlying
package (fp or pgfmath) or LaTeX3 kernel commands or Lua
code used. As from version 3.0, the new default is
lua, if
Version 3.0 is a major new version where many commands have been
rewritten to use LaTeX3 macros. Additionally, some packages, such
as xkeyval and substr are no longer loaded.
If you experience any backward-compatibility problems with the new
version, you can rollback to the previous version (2.32):
The LaTeX kernel has changed significantly since datatool
was first released in 2007. There is now improved support for
UTF-8 and many of the commands provided by datatool now
have much better LaTeX3 alternatives. You may find some tasks more
efficient if you use LaTeX3 commands directly. However, LaTeX3
commands are intended for internal use within the definitions of
document commands rather than explicit use in the document.
LaTeX3 syntax must first be switched on (
The datatool-base package may be loaded on its own, without
the datatool package, if no database commands (see
§3) are required. Available package options
for datatool-base are listed below.
Options can be passed through the package option list in the usual
way. Some options may also be later set with:
The auto-reformat-types does not switch on the corresponding
For example:
The datatool-base package recognises the following data types:
If a whole number is represented in scientific notation (for example,
As from version 3.0, scientific notation, such as
Examples:
Additionally,
There are three temporal types:
The options listed here govern parsing and formatting of localised
integers, decimals and currency. The options may be passed in the value of
the numeric option.
For example:
If auto-reformat-types includes the keyword integer,
then any integers will be reformatted according to the current
localisation settings. If auto-reformat-types includes the
keyword decimal, then any decimals not in scientific
notation will be reformatted according to the current localisation
settings.
If auto-reformat-types includes the keyword si, then
any scientific notation, will be have the string part set to
If auto-reformat-types includes the keyword currency,
then currency will be reformatted to use
Formatted numbers can be parsed provided the appropriate
number group character and decimal character have been set with
A warning is issued if the data type is a string rather
than a numeric value. An empty
For example:
Instead of repeatedly parsing the same content, you may prefer to parse it once
and store the information for later use. This can be done with the following
command:
In both cases, the parsed data is stored in the control sequence
datum control sequence) in a form that includes the original
value (or expanded value in the case of
The “string value”, which is the content that will
expand to, may be automatically reformatted if an applicable setting is
in effect (such as numeric={
The datum item format is particularly useful with databases
(see §3) that
have numeric data which needs to be converted into
plain numbers for arithmetic computations (such as aggregates)
or plotting. If store-datum is enabled before creating the
database, each value will be stored as a datum item. If you
then assign a placeholder command to the value,
for example with
The component parts can then be extracted using the following
expandable commands, where is the datum control sequence.
For example:
Note that the data type is actually stored as a
LaTeX3 integer constant, but
For debugging purposes, you may find it easier to have a textual
representation of the data type so that you don’t have to lookup
what the numeric value represents. You can do this with:
You may also “show” the component parts in the console and
transcript:
Instead of parsing an existing value, you can define a new
datum control sequence using one of the commands below. Only
Datum control sequences may be used in commands that expect a
formatted number, such as
If you have the expansion text from a datum control sequence (a
datum item), that text will be in the form:
Decimals may have the
Temporal data types may have the
The date/time stamp can be extracted with:
To allow for new data types introduced in a later version, you can
check for the current maximum allowed value with:
It’s possible to pick out the desired component using an
If you want to test if a datum control sequence is equal to a string, then
you can’t simply use
If both arguments have a numeric type then they will be compared
numerically and by the currency symbol. If both are ordinary token
lists without the datum markup then they will be compared using a
normal token list comparison. If one has the datum format and the
other doesn’t, then a string comparison is used.
If you need to set an l3fp variable to a value that may be
a datum control sequence or datum item or may not yet be parsed, you can
use:
The datatool-base package (v3.0+) loads the tracklang
package, which attempts to determine the document localisation
settings. No actual localisation is provided by tracklang,
but it enables support to be easily added and maintained
independently from a package (that uses the tracklang
interface) with ldf files that have a particular naming
scheme.
This means that by adding a file
called datatool-.ldf to TeX’s path, the file can
automatically be loaded by datatool-base without any
adjustments to the datatool-base code.
There is a search order for to allow for fine grained
support. See the tracklang documentation for further details
or the “Locale Sensitive Files” section of
Using
tracklang in Packages with Localisation Features.
The tracklang package has limitations, but you may be
able to supply the language identifier as a document class
option, for example:
Note that this option will have an effect on packages that are
subsequently loaded that also use tracklang.
Likewise, if you have already loaded a package that uses
tracklang (such as datetime2) then the tracked locales
from that will be picked up.
For example:
For some packages (such as databib and person), the
localisation support just relates to translating fixed text and the
corresponding filename may simply have as the
tracklang root language label. So regardless of whether you
have used locales=en-GB or locales=en-US, the
person package will require the file
person-english.ldf (provided with
datatool-english).
However, settings such as the currency symbol are specific to a
region not a language. So locales=en-GB would need the
default currency switched to GBP whereas locales=en-IE would
need the default currency switched to EUR and locales=en-ZA
would need the default currency switched to ZAR.
Therefore, localisation support for datatool-base (and its
supplementary packages) is split into two parts: the language file
datatool-.ldf (for example, datatool-english.ldf)
which deals with the orthography, translations of fixed text, and
other language-specific code, and the region file
datatool-.ldf (for example, datatool-GB.ldf) which
deals with language-independent region code. You will need both
files for full support but partial support can be obtained if one is
missing.
The region files are fairly straightforward (albeit time-consuming)
to create. They are therefore all bundled together in a single
distribution datatool-regions which needs to be installed in addition to
installing datatool. See §2.3.4 for
further details.
Locale-sensitive commands that relate to regions may all be reset back to their
original definitions with:
The language files are more complicated and require knowledge of
someone familiar with the language. Each language bundle should
therefore be developed independently by a maintainer fluent in the
language and it will need to be installed in addition to installing
datatool. At the time of writing, only datatool-english is
available, but you can copy and adapt it as appropriate.
(Don’t add me as author or maintainer of your contribution.)
The datatool-english bundle includes limited support for
Old English (Anglo-Saxon) for Latin and Runic scripts, which may be
used as examples for extended Latin or non-Latin languages.
See §2.3.5 for further details.
Locale-sensitive commands that relate to language may all be reset back to their
original definitions with:
The above example produces a warning from babel as the canadien
option is now deprecated by babel. An alternative is:
Localisation files may provide options. These are define with:
These options can be set in the document with:
For example, with datatool-GB.ldf the parent module is “GB” and there
are no sub-modules. To switch number style:
The databib-english.ldf has parent module “en” and
sub-module “databib”. To switch the way month names are
abbreviated for the abbrv style:
The unstarred form uses:
The starred form uses:
If you want to directly use the l3keys functions, the
module path should be prefixed with “
In recent years, the LaTeX kernel has provided significant
improvements to UTF-8 support for pdfLaTeX. (The newer
engines, XeLaTeX and LuaLaTeX are natively UTF-8.)
In particular, even if you don’t load inputenc, the document
is now assumed to be UTF-8 (whereas in the past the default
encoding was ASCII).
To assist localisation files, the datatool-base package provides
both a string (detokenized)
variable and corresponding token list variables that expand to common
symbols (mostly currency) that are included in Unicode and may be of
use with localisation.
These variables are first defined to expand to an
approximate ASCII representation, but then will be
redefined if the relevant
datatool-.ldf file is found.
This means that unsupported encodings will fallback
on ASCII values. There is limited support for ISO-8859-1
(cent, pound, currency and yen).
For example, datatool-GB.ldf defines the GBP currency as follows:
If any of the currency symbols are available in the current
encoding, they will be added to the currency signs regular
expression variable:
Non locale-sensitive numeric commands (such as
Numeric commands for formatted numbers (such as
With LaTeX3 syntax enabled, the following may be used instead.
For more complex parsing requirements, regular expressions can be
provided to match the number group character and
decimal character sub-groups:
The following are just shortcuts that use one of the above.
The region file should register the currency code with:
The prefix command may either expand to nothing or to:
Region files should provide a hook called
Similarly, a hook to set the current number group character and
decimal character:
If you simply want to typeset plain numbers as
formatted numbers then consider using siunitx instead.
However you can use the following, which picks up the above settings.
For example
The commands described in this section are used by string sorting
and initial letter commands to enable locale-sensitive functions to
be used, if available.
The handler definition will usually depend on the encoding.
For example, datatool-english-utf8.ldf defines
For example
As with the English handler, the punctuation characters can be
adjusted to ensure that they are placed before “A”. This means
that the final uppercase letters “Þ”, “Æ” and “Ö” can be reassigned
to the character positions after “Z” and the lowercase “þ”, “æ” and
“ö” can be reassigned to the character positions after “z”
(similar to datatool-ang-Latn.ldf).
The other characters need to be positioned between Basic Latin characters. For
example, “Á” needs to be between “A” and “B”. This can be
achieved by replacing uppercase “Á” with “A” followed by
the control character 0x7F (which is the final ASCII character).
Similarly lowercase “á” is replaced by “a” followed by
0x7F and so on.
The language code for Icelandic is “is” so it will be used in
the command names. Remember that
For example, the string “az” will be unchanged and has the byte
sequence 0x61 0x7A. Whereas the string “áa” will be converted by
the above Icelandic handler to the byte sequence 0x61 0x7F 0x61.
Since 0x7A is less than 0x7F, “az” comes before “áa”. With the
English handler, “áa” will be converted to “aa” which has the
byte sequence 0x61 0x61. Since 0x61 is less than 0x7A, “áa” would
come before “az”.
Note the use of
The language hook (see §2.3.5) then needs to set the locale handler:
Example 10 uses the above to sort a list of words:
For example, datatool-english.ldf sets to the
sort value as this ensures that any supported accented characters and
ligatures will have already been converted to Basic Latin
characters.
However datatool-ang-Latn.ldf and datatool-ang-Runr.ldf can’t do this as
the construction of the sort value means that the characters in the
sort value may be significantly different from the actual letters.
In this case, the original value must be used instead, but it’s
needs some processing to map extended characters to their equivalent
sort group. For example, “Ǽ” needs to be mapped to “Æ”.
Additionally, the actual value is likely to need pre-processing
with
This command is intended for use with sorting functions to obtain the letter
group, so the actual letter returned may not be the initial
letter. For example, if the word starts with the ligature “Æ”
then the localisation may return “A” rather than “Æ”.
For example, datatool-english.ldf defines:
Remember that
The content used to obtain the group letter may be either the
original (“actual”) string or the sort value. This is determined
by
There are two ways of dealing with this. The first method is the
case used by datatool-ang-Latn.ldf which defines
The second method is used here. This starts with the sort value and
reverses the mapping applied by the handler.
In this case, a localisation file that provides
Suppose that this has been implemented via a language hook
(see §2.3.5):
For the Icelandic word sort handler in Example 10,
the will always be the double-quote
The language-independent region files are all bundled together in a
single distribution datatool-regions which is separate from
the core datatool distribution and available on GitHub
(https://github.com/nlct/datatool-regions). There are
currently only a limited number of regions supported but more can be
added via a pull request and only the datatool-regions
collection need be uploaded, without the extra overhead of producing
a new version of datatool.
The region file deals with setting the default currency,
number group character and decimal character, and also the numeric
date formats for use with
A more specific
datatool--.ldf file may be used to
override any of these settings but that file should be provided with the
corresponding language support (see §2.3.5).
For example, datatool-english provides datatool-en-CA.ldf to set the
number group character and decimal character since it varies
according to the language for that region.
The datatool-english package (distributed separately)
may be used as an example. (The datatool-english bundle
includes databib-english.ldf to provide localisation support
for the databib package, and person-english.ldf to
provide localisation support for the person package, see
§§7.11 & 9.7.3 for further details.)
The datatool-english bundle also includes limited support for
Old English (Anglo-Saxon) for Latin and Runic scripts, which may be
used as examples for extended Latin or non-Latin languages.
The language file should be called
datatool-.ldf where
is the root language label (tracklang label). Using the root
language label ensures that it’s the last in tracklang’s
file search list, which means that it can be overridden by a more
specific label, if required.
So in the event that there is some particular language setting that is specific to
a particular region, a language module may also include a file named
datatool--.ldf where
is the language code (such as “fr”) and
is the region code (such as “CA”)..
For example:
In the case of datatool-english, the root language label is “english” (even if
the language has been specified using a dialect label, such as
“british”) so the filename is datatool-english.ldf.
The file needs to identify itself (analogous
to
The datatool-english bundle includes (limited) support for ISO-8859-1
(Latin-1) and ASCII in addition to UTF-8. The
encoding support is provided in the files datatool-english-latin1.ldf,
datatool-english-ascii.ldf and datatool-english-utf8.ldf. The
following code will input the appropriate file or fallback on the
ASCII file if the encoding isn’t supported:
Compare this with the Anglo-Saxon support. The root language label
is “anglosaxon” so there is a file called datatool-anglosaxon.ldf
but because there are two different scripts to cater for, it just
ensures that the appropriate file is loaded.
For example, a package may provide a command called, say
If, however, the source code actually contains characters from
the Runic Unicode block (with an appropriate font that supports
those characters), the source is Runic and so “ang-Runr”
is needed when specifying the locale.
The files datatool-ang-Latn.ldf and datatool-ang-Runr.ldf are similar
to datatool-english.ldf but, in these cases, there’s no fallback to
ASCII as it doesn’t cover all characters from the Latin script
and doesn’t cover any for the Runic script. Instead, if the encoding
isn’t supported, then no localisation can be provided. For example,
datatool-ang-Latn.ldf starts with:
For both the English and Old English support,
we will be using some LaTeX3 syntax, so the
appropriate category codes must be changed:
The definition of
This conveniently works for English, which just maps extended
characters to Basic Latin letters (A–Z, a–z), but will cause a
problem for Anglo-Saxon, both Latin and Runic. In the case of
datatool-ang-Latn.ldf, the extended characters Ƿ (wynn), Ð (eth), Æ
(AE-ligature), Þ (thorn) are converted to the character codes
following “Z” and, similarly, the lowercase ƿ, ð, æ, þ are
converted to the character codes following “z”. This means that
if the sort value is used to obtain the letter group, then these
extended characters will be assigned to the non-letter group.
Therefore, it’s necessary to use the actual value rather than the
sort value, but some additional processing is required to ensure
that characters with diacritics are placed in the same group as the
unaccented character. For example, “Ǽ” needs to be mapped to “Æ”.
This is performed by a low-level function that performs a regular
expression substitution.
Note that this doesn’t take into account a sort handler that strips
content, such as the letter handler functions that remove spaces and
hyphens. This will cause a problem for any words that start with a
hyphen. Since the handler function
In the case of datatool-ang-Runr.ldf there are no hyphens to worry about
so it’s far simpler to just assign the token list variable to the
actual value. Any further processing is down to whether or not the
sort handler considers multiple runes to be considered equivalent
for sorting purposes.
For both English and the two different scripts of Old English,
the support for
The only other support provided by datatool-ang-Latn.ldf
and datatool-ang-Runr.ldf is to redefine
Returning to datatool-english.ldf, support is provided to produce textual
labels for the non-letter group, number group, currency group
and temporal group commands:
(Some of the supplementary packages have additional fixed-text
commands, but they are dealt with in their own ldf files.) An
intermediate command is defined to set
After that comes the support for date and time formatting, but it’s
still experimental.
As with the region datatool-GB.ldf file, describe in
§2.3.4, a single intermediate command is defined
that will be added to the captions hook:
Note that each language file should ensure that the caption hook sets
the token list variable:
The locale handlers are provided in the encoding files.
For example,
In the case of a non-Latin script, such as Runic, the conversion
simply ensures that the characters follow the appropriate order when
the character codes are compared. For example, datatool-ang-Runr.ldf
provides two different ways of ordering the runes. The first mostly
follows the order in the Runic Unicode block. So feoh (U+16A0) is
mapped to character code 31, Runic V (U+16A1) is mapped to character
code 32, etc. The second follows the Old English rune poem order
(fuþorc) so feoh (U+16A0) is mapped to character code 31, ur
(U+16A2) is mapped to character code 32, thorn (U+16A6) is mapped to
character code 33, etc.
There are two types of conditional commands provided by
datatool-base: those with
The robust commands listed in §2.4.1.2, such as
The robust numeric “
Numeric commands listed in §2.4.1.4, such as
The multi-type robust commands listed in §2.4.1.5, such
as
The commands described in this section test the data type of the
argument according to the current settings for the
number group character and decimal character and recognised
currency symbols.
The following comparison commands test for lexicographically
equality, less than (comes before) and greater than (comes after).
The string arguments have a single expansion applied on the
first token and then they are expanded in the same way as for
These commands expect formatted numbers or datum control sequences in
the numerical arguments and compare their values. They
internally use the corresponding command from
§2.4.1.4 after parsing to perform the actual
comparison.
Note that the currency unit (if given) in the above comparisons is disregarded.
Only the numeric value obtained from parsing is considered.
The commands listed in this section parse the 2.4.1.2) or numeric
(§2.4.1.3) command. Those arguments may also be
datum control sequences.
The commands described in §2.4.1 can not be
used in the conditional part of the
Commands with a name prefixed with “
Commands with a name prefixed with “
Commands with a CSV list argument, such as
Note that this produces slightly different results from
Examples 37 & 39. For the division
\(1023.5\div 54.75000\), math=lua produces
18.694063926941 whereas math=l3fp produces the result
18.69406392694064. This is due to rounding when the result from Lua
is input into the TeX stream. With math=fp the result is
18.694063926940639269, which has even more significant digits.
On the other hand, for the square root \(\sqrt {9}\) and cubic root
\(\sqrt [3]{8}\), math=l3fp produces integers 3 and 2,
math=lua returns equivalent decimals 3.0 and 2.0 but
math=fp has rounding errors.
If Example 37 is modified to use the
pgfmath processor, which uses the commands provided by
the pgfmath package, then the LaTeX run will fail with the
error:
The commands listed in this section expect formatted numbers
in the values according to the current number group character and
decimal character settings. Use
The currency data type is represented by a currency symbol and a
numerical value. There is no provision for exchange rates. Commands
such as
In order for the parser to determine the difference between a
currency value and a string (see §2.2),
datatool-base needs to know the currency symbols.
As from version 3.0, datatool-base can now load region files
that setup the currency associated with the region.
As described in §2.3.2,
a plain number can be converted to a formatted currency with
Next a formatted currency (using the current number group character and decimal character
settings) is added to a formatted number. Note that the symbol
doesn’t need to match the current currency symbol:
Rounding is determined by
To demonstrate currency parsing,
The symbol may also occur after the value:
The currency style formatting is described in more detail later in
this section, but
The above uses the formatting style for the current default currency,
but if a currency has been defined with a three-letter currency
code, then
The
Switch to the GB region:
The code is similar for the IE region:
If there is no support for your region, or if you are using a
currency that’s not connected to your region (for example, Bitcoin),
then you can use the commands described below to define a currency
(if not already provided by datatool-base) and to switch to a
previously defined currency.
The set of known currencies is initialised to contain
common currency symbols supported by the document encoding, and the
currency commands:
\$,
The known currency list simply assists parsing, but it’s also
possible to define a currency with a corresponding ISO code and
alternative representation to adjust the way a currency value is
formatted.
The optional argument
The following command is defined by
The underlying function used by
There is a shortcut that sets the format to
The symbol associated with a defined currency may be changed with:
The symbol and associated string value for a currency that has been defined
can be obtained with:
If you don’t know whether or not
If you want to switch to a previously defined currency, you need to use
If no localisation file has been loaded (see
§2.3), then the default is ISO code
“XXX” and symbol
The following currencies are defined by datatool-base:
“XXX” (associated command
The “XXX” and “XBT” currencies use the default currency
formatting command
If you prefer a different symbol, you can use
The currency string depends on the file encoding
(see §2.3.1).
The default definition of
For currencies that have the symbol at the end:
Both
Since
Region files may provide their own format that inserts a tag before
the currency symbol. For example, datatool-GB.ldf provides:
Note that
The datatool-GB.ldf file provided with datatool-regions provides
the GBP currency. The example below is provided to demonstrate how
to define currencies and modify the formatting.
If you want to add support for your region, there is a Perl script
in the datatool-regions GitHub repository that can get you
started. You can then add your region file via a pull request.
See the “README” file at https://github.com/nlct/datatool-regions
for further details.
In the case of
The temporal data types (datetime, date, and time) were only added to
datatool-base version 3.0 and are still experimental so
this feature is off by default. Parsing can be enabled with
the datetime option.
Options that govern date and time parsing can be set within the
datetime setting value. For example:
Note that this will require datetime2 to be loaded and you
will need to set the style using datetime2’s interface.
Note that datatool-base will automatically pick up
datetime2’s regional setting. This will require not only
datetime2 but also datetime2-english (which will be
implicitly loaded by datetime2 if it is installed).
The
If both the
The above commands may use:
The string data type is any non-empty content that can’t be parsed
as a number (or currency). For more information on data types, see
§2.2. For conditionals, see
§2.4. For CSV lists, see
§2.9. The commands described below assume
that the text arguments are strings without parsing them to
determine their data type. Unexpected results may occur if the text
includes math-mode content.
Note that in each case the change is localised to the current scope.
For more complex substitutions,
including replacing commands or command arguments,
use LaTeX3 regular expressions (see §1.2.1).
Once the supplied
In the case of
The following commands are used for the punctuation.
If you want to remove the dots, you can either redefine
The initial-purify=early setting makes
The algorithm used by
The default definition of
These commands use LaTeX3 syntax so you will need
The commands
The hook is a token list variable:
The following commands are intended to work around
the problem of UTF-8 characters being represented by multiple
tokens with pdfLaTeX, when a single grapheme is required from the
start of a token list (for example, when obtaining initials).
For example, with XeLaTeX and LuaLaTeX the character
“Á” is considered a single token and has the category code 11
(letter), but with pdfLaTeX and UTF-8 “Á” consists of two tokens
where the first token has category code 13. However
The regular expression class
The datatool-base package provides some commands that take a
CSV list as the argument, such as
There are two options,
The datatool-base package automatically loads etoolbox
so you can use the etoolbox commands, such as
The options described in this section govern the CSV list
settings. They may be passed in the value of the lists option.
For example:
The datatool-base package automatically loads etoolbox
so you can use commands provided by that package to prepend or
append to a command definition, such as
There are two commands provided by datatool-base for sorting a
CSV list. Both take a command as the first argument whose
definition should be the CSV list. On completion this command
will be (locally) redefined to expand to the ordered list.
The second argument is also a command but its behaviour and syntax is different.
The first (and older) command is
The second command is
The advantage with
A sorted element is in the form:
Currency
The letter group is considered a currency group so
String
If the
If you want to iterate over a list that uses a handler function on
each list element (such as etoolbox’s
The following command is used by
For example, the following sorts a list and shows the result (with
Compare the above with:
The closest match to the case-sensitive
When using lexicographical ordering, there is a distinct difference
between
Switching the
I’ve added line breaks for clarity, replaced constants with
their actual numeric values, and replaced the private commands for
the sort element markup with datum markup with
for compactness:
The
If you have LaTeX3 syntax enabled you can apply the changes made in
the internal hook with:
These comparison commands may be used with
Options that govern comparison commands can be set within the
compare setting value. For example:
The following handler macros are provided for use with
The above handler macros are simple wrapper functions that ensure
the value is expanded and pre-processed (case conversion or
stripping hyphens and spaces) and stored in
The hook used by
The commands changed by this hook are listed below.
There are two ways of dealing with parenthetical content.
An alternative method that can be used with
The use of control codes affects ordering. The normal space
character has character code 0x20 and a comma has the character code
0x2C. This means that a comma would ordinarily be placed after a
space character, whereas the low-end control codes come before
space.
Following the guidelines of the Oxford Style Manual, when sorting terms that have
identical pre-inversion parts, the following ordering is applied: people, places,
subjects, no inversions, and parenthetical. This is achieved through
the marker commands (see Examples 57 & 58).
The hook also redefines
Additional code can be added to the hook with:
The following examples demonstrate the different sorting methods.
Examples 55 & 56 sort the
list: sea, sea lion, Sealyham, seal, sealant, sealing wax, which is
defined as:
The example doesn’t use
The word and letter functions use the word sort hook (see
§2.9.5.3), which means that the special marker functions
expand to low ASCII control characters, which means
that they are placed before ordinary punctuation and letters. The example
list is defined as:
Since the lists have long elements and elements with commas, I’ve used the
multicol package to arrange them in columns and changed
the separators used by
The simple case-insensitive comparison (
Note the difference between using
Note that the position of “duck” has changed. This is because of
the boundary marker that’s appended to all the values. The boundary
marker control code is now compared with the comma and parentheses
marker control codes.
Results with
Note that because
Note that with datatool-english-utf8.ldf, “résumé” is converted into
“resume”, which means “résumé” has an identical sort value to
“resume”. With
Remember that
Note the use of
The datatool package provides a means of creating and
loading databases. Once a database has been created (either with
supplied document commands or by parsing an external file),
it is possible to iterate through each row of data, to make it
easier to perform repetitive actions, such as mail merging.
Some advanced commands for accessing database information are
described in §3.16, but using TeX is nowhere near
as efficient as, say, using a SQL database, so don’t expect too much
from this package.
I’ve written a Java helper application to accompany datatool
called datatooltk. The installer
datatooltk-installer.jar is available on CTAN. The application will allow
you to edit DTLTEX (see §3.15.1.2) and DBTEX (see
§3.15.1.3) files saved using
The datatool package automatically loads the
datatool-base package, so all commands provided by
datatool-base are available. The commands provided by
datatool relate to databases.
The supplementary packages dataplot, datapie,
databar, databib and datagidx automatically load
datatool and provide additional commands that act on
databases. In the case of databib and datagidx, the
databases have a specific structure. The dataplot,
datapie and databar packages provide commands to
visually represent numeric data stored in a database.
All options provided by datatool-base (see
§2) may also be passed to
datatool. Additionally, the following options are also
available, some of which can only be passed as a package option,
some of which can only be used in
After the package has loaded, you can use
If new-value-expand=true, protected expansion is applied to the
value, otherwise no expansion is performed.
For example:
The new-value-expand=true option is useful if you are
programmatically creating entries
with placeholder commands, which need to be expanded.
In the second case, the placeholder command
This setting may also be switched on with:
Note that the I/O
Note that the tab character is normally treated as a space by
LaTeX. For TSV files, the tab character will need to have its
category code changed to distinguish it from a space.
This can be done with
Examples:
There are a number of examples in this user guide that illustrate
database commands on sample data. This section describes the sample
data to provide a convenient point of reference for each example.
Some databases are constructed within the example document preamble
using
The “marks” database consists of columns with the labels:
Surname, Forename, StudentNo (a unique
identifier, which disambiguates between the two students with the
same name), and columns with the marks for each assignment.
The “marks” database is read in from the file
studentmarks.csv, which contains the following content:
This is only a short database for compactness. A similar, but longer
database, is the students scores database.
The “scores” database consists of the columns: forename
(with the title “First Name”), surname (with the title
“Surname”), regnum (with the title “Student Number”),
gender (which may be a recognised gender label, see
§9.4), parent (the student’s
guardian, parent or parents), score and award.
The award column contains currency values, and the
score column contains decimal values. The regnum
column consists of a unique identifier. This happens to be numeric
for this data, but may not necessarily be numeric for a real-world
database. It’s included in the example data to demonstrate querying
by a unique value and the data type isn’t relevant for that.
Since the data contains numeric values that may need to be parsed,
it’s useful to switch on the store-datum option to reduce
parsing.
The database is constructed in the preamble of example
documents as follows:
If you prefer a CSV file, the nearest equivalent would be:
If the CSV file is called studentscores.csv, then it can be
loaded with:
The “customers” database consists of columns with the
labels: Id (a unique integer identifier, which happens to
match the data row number but this isn’t guaranteed),
Organisation, Surname, Forename,
Email, and Age (another numeric column, which
could potentially be decimal but only has integer numbers or missing
items). There are some empty entries in the Organisation, Email and Age
columns.
The customers database can be read in from the file
customers.csv, which contains the following content:
This data may also be defined within the document. Note that there
is a slight difference here as most of the missing values are now entirely
omitted from the database, so any reference to them will result in a
null value rather than an empty value. However, there is one case
where the Organisation column has been set to empty rather then
being omitted, so a reference to that element will result in an
empty value not a null value.
The “product” database consists of the columns: Title,
Author, Format (hardback, paperback or ebook),
Quantity (integer), Price (decimal), and
Notes (which is null in some rows and is only created by
the first row to add an item to it).
Since the data contains numeric values that may need to be parsed,
it’s also useful to switch on the store-datum option to reduce
parsing.
The database is constructed in the preamble of example
documents as follows:
The “pricelist” database has the columns: Product,
Quantity (integer), Price (currency), and Notes
(which is null in some rows). Note that, unlike the larger
products database above, the price column includes the currency
symbol.
Since the data contains numeric values that may need to be parsed,
it’s useful to switch on the store-datum option to reduce
parsing.
The database is constructed in the preamble of example
documents as follows:
The “balance” database consists of columns with the labels:
Description, In, Out, and Balance. The last
three columns are all numeric.
The “balance” database is read in from the file
balance.csv, which contains the following content:
The data can be loaded with:
The “fruit” database consists of columns with the labels:
Name (string) and Quantity (numeric). The quantity
includes decimal values, so evidently some fruit has been cut in
half.
The “fruit” database is read in from the file
fruit.csv, which contains the following content:
This file can be loaded with:
The “profits” database has three columns with the labels:
Year, Profit and Units. There are three negative values
for the Profit column (that is, they are in fact losses
not profits) which have been formatted slightly differently. Two have
the minus sign before the currency symbol and one has the sign
after the symbol. Both formats are supported.
(Example 109 demonstrates how to
automatically reformat the values to tidy them up.)
The “profits” database is read in from the file
profits.csv, which contains the following content:
The “growth1” and “growth2” databases represents data obtained
from hypothetical microbiological experiments, where a microbial
population is observed at various time points. The two different
sets of data correspond to different temperatures. (For example, the
“growth1” data may have had the temperature set to 6 degrees and
“growth2” may have had the temperature set to 8 degrees.) The
first column in each case is the time observations. The other
columns have the population figures as a log count.
The “growth1” database is read in from the file
growth1.csv, which contains the following content:
This file can be loaded with:
The “growth2” database is read in from the file
growth2.csv, which contains the following content:
This file can be loaded with:
Note that since the data contains numeric values, it can be more
efficient to switch on the store-datum setting to reduce
parsing if, for example, the data needs to be displayed in a graph.
This should be done before
The “growthdata” database is an alternative to the above time to
growth data. In this case the data is provided in a TSV file.
Instead of having a single time column with two columns for the
results of each experiment, it has four columns containing the time
and log count for each experiment.
The tab character is represented by the ↹ symbol. The
first file is growth.tsv:
There is a similar second database “growthdata2” in the file
growth2.tsv, but it has an extra pair of columns for a
third experiment:
In both files, the actual headers are in the second line: “Time”,
“Log Count”, “Time” and “Log Count” (and, for the second
file, another “Time” and “Log Count”). Note that they are
duplicated, which means they are not suitable as unique column keys.
Therefore it’s necessary to override the default behaviour to ensure
unique keys. The format needs to be set to ensure that the
tab character is recognised as the separator and has its category
code changed so that it can be distinguished from a space.
Since the data contains numeric values, it can be more
efficient to switch on the store-datum setting to reduce
parsing if, for example, the data needs to be displayed in a graph.
The “xydata” database just contains two columns of numbers that range from
negative to positive.
The “xydata” database is read in from the file
xydata.csv, which contains the following content:
This file can be loaded with:
Note that since the data contains numeric values, it can be more
efficient to switch on the store-datum setting to reduce
parsing if, for example, the data needs to be displayed in a graph.
This should be done before
Some of the commands provided by datatool are quite long and
it can be difficult to remember the syntax. Version 3.0 provides:
Available actions are listed in §3.3.1 and settings
are listed in §3.3.2. The
argument will be trimmed by
An action may have one or more return values consisting of a
primary return value and (optionally) secondary return
values that have an associated property name. There are several ways
of fetching the return values.
The primary and secondary values can be obtained with:
Secondary (but not primary) values can also be obtained with the
If no return value is available (for example, the action failed or
requested information was unavailable or the property name is
unknown) then 3.10).
For example, the
All actions recognise the optional
The
The
The primary return value is the index of the new row, which will be
the same as the updated row count. There is also a secondary return
value that can be accessed with the name property, which
will be the database name. The row property can also be
used, which is the same as the primary return value. The difference
is that
The internal action of
This action has one optional setting:
This action has secondary return values, which can be accessed with
Note the difference between using the
If you try to use both
The
This action has secondary return values, which can be accessed with
The
The
The default match function is simply a first of one function, which
means that the first row (or last row with
direction=descending) in the range
The primary return value will be the row index which satisfied the
match. The return value will not be set of no match was found.
The secondary values will be set to the values of the matching row,
where the property name is the column key. This means that you can
access the values from the match even if you didn’t set the
corresponding assignment in
For example, the following simply fetches all the values from row 2:
The following finds the first row where the surname field is
“Smith” and the forename field is “John”:
An error will occur if the database is undefined or if the key is
missing. This action has one optional setting:
The primary return value (if successful) is the column index, which
may be accessed with
For example:
The primary return value is the column key (regardless of whether
the
An error will occur if the database is undefined or if there is no
If you know the row index, you can use the
If you don’t know the row index, but want to find the first row that
exactly matches a particular value for a specific column then you
need to use
If you want to match by a more complex test, such as a regular
expression, use the
In either case, the
If successful, this action will set the token registers
No return values will be set if unsuccessful, otherwise
the primary return value is the row index (which will be the same as
The later Example 68 uses
For example, to fetch all values in the current row and use the
values from the “Forename” and “Surname” columns:
There are no required settings. If you only want the values from a
subset of columns you can identify those columns with
For example, the following collects the values for the columns with
the labels “Title”, “Price”, “Quantity”, “Total” and the
columns with the indexes 1 and 2:
The primary return value is the number of values collected. This may
be less than the total number of columns in the database or less
than the list of supplied keys if there are missing columns in the
current row. The secondary return properties are the column keys and
the return value the corresponding element (which may have been
parsed and converted into a datum item if the
Example 78 uses the
The primary return value is the total number of numeric items in the first
column. (Non-numeric items are skipped.) This will typically be the
same as the row count, unless there are null or non-numeric items.
The secondary return value properties are:
The actions
In either case, the database name should already be set in the
By default all columns in the current row will be checked, but you
can restrict the function to a subset of columns with the
The
There’s no primary return value, but there are secondary return
values that can be accessed with the properties: name (the
database name), columns (the number of columns displayed),
and rows (the number of rows displayed).
For example:
There’s no primary return value, but there are secondary return
values that can be accessed with the properties: name (the
database name), columns (the number of columns displayed),
and rows (the number of rows displayed).
The primary return value should be equal to the number of rows of
the database if no errors occurred. The secondary return values
can be accessed with the properties: name (the database
name, which will always be set), columns (the number of
columns in the database after sorting) and rows (the number
of rows in the database). The column count of the database may
increase if the options include instructions to add the sort or
group information to the database. See §3.14.1
for further details.
The databar package provides the
Action settings may only be used in the optional argument of
The list may include ranges in the form
Unlike
Available values are:
If
Note the difference if a currency symbol is enforced:
This section describes commands that may be used in a document to
create a database or to locally or globally alter a database. The
global option determines whether or not the modifications to
the database are global or local, except for those commands that are
listed as specifically global only. Note that new databases are
always globally defined.
The new-value-trim option determines whether
or not values are trimmed before adding to a database, and the
new-value-expand option determines whether or not values
should be expanded before adding. The store-datum option
determines whether or not the values should be as a datum item.
Before you can add any data to a database, you must start a new row.
Once you have added a new row, you can add entries to that row with:
If a database with the given label doesn’t exists or the row already
contains an entry in that column, an error will occur with the
unstarred version. The starred version
If a column with the given label doesn’t yet exist, it will be
created and the default metadata will be assigned. The
store-datum option determines whether or not the value is
stored in the database as a datum item. It will be parsed
regardless of that setting in order to set or update the column data
type. The new-value-trim option determines whether or not the
value should have leading and trailing spaces trimmed. The
new-value-expand option determines whether or not the value
should be expanded.
Note that with the default new-value-expand=false, you can
expand a particular value in
The contents of the database can now be displayed with:
Short commands, such as
Deleting or clearing a database simply undefines or resets the
underlying commands and registers that are used to represent the
database.
You can test if a database exists with:
You can test if a database is empty with:
If you have LaTeX3 syntax enabled, you can also use:
The metadata associated with a database consists of the identifying
database label, the number of columns, the number of rows, and the
column metadata.
Rows in a database are only identified by an index (starting
from 1). Columns may be identified by an index (starting from 1) or
by a key (label) that must be unique to the database. You can test
if a database has a column with a given key with:
If you have LaTeX3 syntax enabled you may instead use:
The column metadata not only consists of the index and unique key,
but also a header and the column data type (see §2.2).
When an entry is added to a database the entry is parsed to
determine its data type, and the column metadata is updated.
For example, if an integer is the first element to be added to a
column, the column metadata will be updated to set the column data
type to integer. If a decimal is then added to that column, the
metadata will be updated to “real number”. If another integer is
added, the metadata won’t be updated as the “real number” type
takes precedence.
Some advanced commands require the column index rather than the
column key. You can lookup the index from the key with:
Note that
If you want the reverse, that is the column key given the column
index, you can use:
The column data type is used in some commands, such as
You can look up the column data type with:
Alternatively, you can use the
The data type ID will be one of: 0 (string), 1 (int), 2 (real), 3 (currency),
or empty for unset (which typically means there are no non-empty
elements in the column). There are commands provided that expand to
the corresponding ID:
The column header defaults to the column key, but may be changed. For
example, when reading a CSV or TSV file with
Normally new column metadata is automatically added when an entry is
added with a new key. However, you can also add a new column with:
If you want to add a new column with a header that isn’t the same as
the column key, then you use:
Be careful about defining columns that aren’t required as you can
end up with null values (which isn’t the same as an empty value).
A database can be displayed in a tabulated form using one of the
following commands.
There are analogous actions:
As from version 3.0, both
The
Most of these options can be used with both
For example, to display the contents of the database in reverse order:
The hook takes two arguments:
For example (requires the tabularray package):
For example (requires the tabu package):
The header is essentially in the form:
Each column title in the header row is aligned with:
For example, to add
The tabular or longtable body, which the function
may append content to (regardless of whether or not it expands to
), but bear in mind that the content will be
before
For example, to omit all the odd rows:
Both filter options can access information from the current database row
with current row commands such as
The following commands are used by
The following token list commands are provided to insert extra content into the
tabular or longtable body.
You can use the
For example, to switch to tblr (provided by tabularray):
Alternatively, you can use the
The
The
With
Similarly, the tabular
(or longtable) column number. So will be 1 for
the first displayed column but this may not be the first column in
the database.
It becomes more complicated if
This means that if you want to redefine
The
A token list variable tabular or longtable environment. For
each column to be shown in the table (omitting any that have been
filter by the options), the following command is used to append to
:
The
The last two arguments determine whether to add the expansion text
of
The tokens added to
For example, if you want to use tblr (provided by
tabularray) instead of tabular and you don’t need all
the hooks:
The following variables require LaTeX3 syntax enabled and are used
in some of the above commands.
The unstarred version of
As an alternative to the previous example, you may prefer to list the
columns you want (an
inclusion list). The following indicates that the Author, Title and
Price columns should be include. The other columns will be omitted:
Note that with
The
In Example 75, a command called
Unlike
The
This can either be done using LaTeX3 syntax:
Note that it’s not necessary for the student number to be displayed in the table.
The information is obtained by looking up the value with the
The counter needs to be reset before the data is displayed:
Note that this example doesn’t show the value of the counter. This can be added with
a slight adjustment to the code in the modified
The previous Example 76 incremented a counter at the start of each
row with
Example 77 modifies Example 76 to insert
an extra column at the start that has the counter value. This means that the alignment
and header information will need to be adjusted.
First,
The previous Example 77 inserted an extra column at the
start. Extra columns can be added to the end using a similar manner.
Example 78 uses a slightly different approach that uses
the post-row function and explicitly sets the alignment specification
(
Example 78 has an extra column with the header
“Total” that contains the value obtained by multiplying the
quantity by the price. The booktabs package is required for
the horizontal rules.
The “balance” database contains numeric data.
Since the numbers will be repeatedly parsed, it’s best to switch on
the store-datum setting. A default name for
the database can be set at the same time:
Note that the eighth argument of
To make it clearer how the data is arranged,
Example 80 sorts the data
by surname and then first name. Since the data contains
UTF-8 characters, localisation support is used:
In order to save space, you may want two database rows per tabular
row. This can be done with the
Example 81 is an alternative to
Example 80 that has two database rows per
tabular row, but they are now arranged from top to bottom instead of
from left to right.
Example 81 is as Example 80
except that it uses the
The new row command (
This means that although you can use the filter function to insert
code into the content token list variable, that code will be
inserted at the end of the previous row before the new line command.
Therefore, if you want to insert content at the start of a row, it
needs to be done in the
The default definition of
Example 82 creates a stripy table with
rows alternately coloured blue and green. The colortbl package
provides
Suppose now that you want both a stripy table (like
Example 82) and two database rows per
tabular row (like Example 80). Simply
adding the option
Example 83 adjusts the redefinition
of
The marks database has a Surname and a Forename column.
Example 84 redefines
Note that the scratch variable must be expanded before being added
to the content token list variable as its value changes at each
iteration. However, if there’s a possibility that full expansion
will cause a problem for the formatting command, surname or
forename then they should be protected from expansion (which is
achieved with
If you prefer not to use LaTeX3 commands, the above can be
rewritten with
This example combines elements from previous examples to show the
student surname and forename in the same column
(as Example 84), calculates the average
score which is appended in an extra column (similar to
Example 78), filters out the rows where the average is below 50
(similar to Example 75) and highlights the rows
where the average is above 70 (similar to Example 3.7.3.11).
The colortbl package is needed for this example as it uses
The row condition may be used to skip rows, in a similar way to
Example 75 but in this case the average needs to
be calculated, which can be done with the
The redefinition of
The definition used in §3.7.3.13 already
tests the column number rather than the column index, so only a
small addition is required. Note that since the
The
The newer command,
The
If you have a long loop, you may prefer to use an environment
instead.
In both cases, the command
The loop may be prematurely terminated with:
With the default
Note that since
Within the loop body of
If
Rather than repeatedly using
Alternatively, if you prefer the
If there is no value matching the given column key then the
placeholder command
For example:
If
All edits are saved in a local buffer and are only applied to the database
at the end of
Some of the edit commands may take a
For example:
If the current iteration row already has a value in the given column, the
existing value will be replaced with the new value. If the current
row doesn’t have a value in the given column, the new value will be
added. If the desired column doesn’t exist, you will need to
identify it with
The database can then be sorted by the average mark and displayed:
The newer command
The commands and environments in this section are older
and have extra overhead. They were designed to work in
tabular-like environments, so they perform global assignments
to workaround the automatic scoping within cells. However, alignment
can be sensitive to certain commands occurring at the start of a
cell or row that can trigger “misplaced
Corresponding environments are also available.
After
These counters may be used in other contexts, such as with
At the start of each iteration, the assignments given in
are made. This argument should be a
The
The following commands are defined for use in
If the read-only
With the editable unstarred
Most of these examples can now be performed with either
This example requires the colortbl package which provides
Example 85 in §3.7.3.14, which
highlights rows after computing the average score, may seem similar to this
example, but
As with Example 77, the student number for the referenced
row is obtained with the
As with Example 78, the booktabs package is used
for horizontal rules at the start and end of the table.
Note that this example has a conditional (
It can be problematic using loops and conditionals with the
tabular environment or any similar alignment environment, such
as longtable. Each cell within a row has implicit scoping.
This allows you to conveniently use declarations, such as
In the above, only “A” is bold and only “C” is
italic because of the implicit scope that localises the effect of
the font change.
Suppose now that you want to keep track of the row numbers. Using
the older TeX route, you could define a count register and
increment it at the start of each row. However a local increment
will only have an effect within the current scope. For example:
The local increment within a cell means that the change is lost.
You can prefix
This is what
This means that
Problems arise when more complex operations are needed at the start of
a row or cell that interferes with the column alignment.
Suppose now that I want to include a test at the start of each row
to insert a horizontal rule above every other row:
The best way to avoid this in complex situations where the
tabular content requires various conditionals to adjust rows
or cells is to construct the content in a temporary command
(a token list variable) so that the problematic code is shifted outside of the
tabular environment. This is the method now used by
Using a more traditional LaTeX2e method, you can define the
variable with
If you prefer to use LaTeX3, you can instead use the commands
provided by the l3tl package (token lists) and the
l3int package (integers), which are now part of the
LaTeX kernel so they don’t need loading. For example, first switch
on LaTeX3 syntax and define the variables:
This may seem very convoluted, and certainly is for the above
trivial case, but when using a loop to construct the contents, it
can avoid the headaches of misplaced
First some variables are defined:
The “marks” database used by Example 93 has two
Jane Browns who both have an average above 70, so both their rows
are highlighted in yellow. The students with an average below 50 aren’t
listed.
Certain commands, such as
For example, the “customers” database
described in §3.2.3 can either be read from a
CSV file or defined in the document.
However, there is a slight difference between the two approaches.
When data is loaded from a CSV file, null values can only
occur where final columns are missing. When data is loaded from a
DTLTEX or DBTEX file (see
§§3.15.1.2 & 3.15.1.3) or when the database
is constructed in the document (see
§§3.3.1.1 & 3.4) then null values can also
occur in intermediate columns.
The customers.csv data has null values where the final columns have
been completely omitted in a row (that is, there are no trailing
separators with empty elements between or after them), but the missing
mid-column values are empty because there’s no way of completely
omitting them without interfering with the CSV syntax. So
those values are empty, not null. See the examples in
§3.10.1.
If you have assigned a value to a placeholder command, for example
with
If you want to test for null or empty, use:
Null values will cause different output to empty values when
displaying data (see the examples in §3.10.1), but
they can also produce different results in other functions, such as
sorting (see Example 101), where a null value can
trigger alternative behaviour but an empty value won’t.
This file has some missing final columns but also has some empty
values. For example:
The data is displayed in tabular form using the
The
The following commands are actually provided by datatool-base
rather than datatool as they are used in datum tests or by the
person package (which can be loaded without datatool).
The actual null command is:
In general, it shouldn’t be necessary to use this command, as you
can test with
When fetching values from a database, some commands (such as
A special value is an entry that’s added to a database where the value starts with:
When writing the database to an external DBTEX file with
This command was added for the benefit of the datagidx package
to encapsulate values in internal columns such as Used
to allow them to be reset for use at the start of the next
LaTeX run when the database saved at the end of the previous run
is read in the preamble of the next.
Rows can be edited whilst looping through a database with
It’s also possible to edit a single row of the database outside of those loop
commands. In order to do this, it’s first necessary to select the required row
and set it as the current row. This stores the row information in the
Modifications can then be performed on the
The current row can be setup using commands such as
Note that although iterative commands such as
Within
The customer with Id set to 9 has an empty Organisation column. This
means that the column has actually been set in the current row, so it needs to be
replaced rather than set:
Once all modifications have been made, the
Suppose now, the customer with Id 2 needs to be remove. The required row again
needs to be selected first:
The commands described in §2.5 may be used on
database values. Remember that if you database contains
formatted numbers rather than plain numbers, you will
need to use the commands in §2.5.2 to parse
the formatted number to obtain the numeric value.
The commands described in §2.5 are dependent on the
math processor. As from version 3.0, the aggregate commands
described here directly use the l3fp library after converting
formatted numbers to reduce the parsing overhead.
The first optional argument
A quicker alternative in the case of only one database, one column
and no condition is:
A quicker alternative in the case of only one database, one column
and no condition is:
A quicker alternative in the case of only one database, one column
and no condition is:
A quicker alternative in the case of only one database, one column
and no condition is:
A quicker alternative in the case of only one database, one column
and no condition is:
A quicker alternative in the case of only one database, one column
and no condition is:
If you need the sum, mean, standard deviation, minimum and maximum
values for a column of just one database, it’s more efficient to use
the
The optional
The results are stored as plain numbers in the control
sequences (the minimum \(x\) value),
(the minimum \(y\) value),
(the maximum \(x\) value), and
(the maximum \(y\) value).
If you only have one database and no condition, you may prefer to
use the
If your database isn’t too large and you are unable to include an
external tool into your document to perform sorting, then it’s
possible to sort a database with the commands described in this
section.
Version 3.0 has introduced a new command
The default-name in
The optional argument
An empty setting
The
The
The first “marks” database (§3.2.1)
has three students with the surname “Brown” and two of them have
the surname “Jane”. The student number disambiguates them. So
the following will first sort by surname, then (for identical
surnames) by forename, and finally (for identical surname and
forename) by student number:
If a column has missing (null) values, then those values will be
treated as empty for string columns or 0 for numeric columns. This
means that sorting a string column in ascending order will place all
the null values at the top with the empty values. The secondary sort
columns in the criteria list will then determine their relative
order.
If you want to specify an alternative column to use if a value is
missing, then you need to identify the replacement column
with the
The null values are shown as “NULL” (for string columns) or 0
(for numeric columns) by
Secondary The secondary sort value is only used if the
primary sort values are identical when comparing two rows.
In this case, the secondary sort value is obtained from the Surname
column. If that value is missing, the secondary sort value will be
obtained from the Forename column. If that value is also missing,
the secondary sort value will be empty.
Tertiary The tertiary sort value is only used if both the
primary and secondary sort values are identical when comparing two
rows. In this case, the tertiary sort value is obtained from the
Forename column. However, no replacement columns have been identified, so
if the Forename column is empty, the tertiary sort value will be
empty.
Examples 103 & 104 both sort the data first by
the Age column (which is numerical) and then by the Surname column:
Since
The older
The
The other difference between
If any listed column in either
If any column has been identified as a numeric column, a numerical comparison
will be used (with
For example,
Compare this with:
This means that if the Author, Series and Volume columns are all missing for a particular row,
then the primary, secondary and tertiary sort values will all be the value from the Title column.
Contrast this with the more flexible
The data stored in the database can be saved to an external file
with
There are essentially two different types of file format according
to how that data can be read into a LaTeX document:
In the second case, the file extension would ordinarily be tex
but there is a danger with
The dtltex files are easier to read and edit, but are slower
to load. The dbtex format has two versions: 2.0, which is
very hard to read but is the fastest to load, and 3.0, which is
easier to read and still much faster that the dtltex file
format. Note that datatooltk version 1.9 can read dbtex
v2.0 but not v3.0 (which was only introduced to datatool
v3.0). The pending (at the time of writing) datatooltk version 2.0 will be able to read
the newer format. Datum markup is only preserved for
Note that, while it is also possible to create a file containing
a set of
The format is specified with the
The default file format for both
If the file contains LaTeX code, for example:
The default separator for the csv format is a
comma (
The default separator is a double-quote (
Spaces between the separator and delimiter are always trimmed. Leading and
trailing spaces inside the delimiter, or when there is no delimiter
present, is determined by the general new-value-trim option.
This needs to be set in
Datum markup is not preserved when writing to a CSV or
TSV file nor is the database name.
The dtltex files are simply LaTeX files that contain the
user level commands required to define a database. These are easier
to read and edit by hand, but are slower to load. There are two
supported formats:
3.0 (
Datum markup is not preserved for either version.
When written by
The next comment line provides information about file creator and
creation date. In the case of a file created by datatool, this
will have the datatool version details. The creation date will
be obtained by expanding
DTLTEX version 2.0 was designed to work with
DTLTEX version 3.0 defines the database with the commands listed
below. These are only intended for use within
If
In either case, both
Unless suppressed by
The dbtex files are LaTeX files that contain
internal commands required to define a database. These are harder
to read and edit by hand, but are faster to load than the other file
formats. There are two supported formats:
Datum markup is not preserved. Any spaces at the start of an element
value will be lost.
3.0 (
Datum markup is preserved.
The
As with the DTLTEX format,
The v2.0 format then starts with a check for the existence of the
database and exits the file input if it already exists:
The
Note that
The 2 This
consists of sub-blocks ( ) that contain the data for each row:
Note that with DBTEX v2.0, as mentioned earlier,
It’s not possible to switch to LaTeX3 syntax for a new file format
as the data will likely contain one or more of the characters that
have their category code changed by
The DBTEX v3.0 format, starts with the same command as for DTLTEX
v3.0:
The
The
Every column in
The
Data can be loaded from an external file using
When passed to the optional argument of
If a column key can’t be obtained (either from the file or from the
Only has an effect when
Note that a blank line means an empty line in the file unless it
occurs within grouped content with
For example, if the first two lines of the file consist of:
Whereas with
Note that in both case, the column keys would need to be set with
Suppose now that the next line is:
The final user mappings are applied after the value has been
rescanned. There are none by default, but mappings can be added
with:
This setting is only applicable with
Note that with
The default delimiter may also be set via the delimiter
package option or with:
The default setting for
Bear in mind that if you add content to databases that contain
characters that should have non-standard category codes, this
information may be lost unless it’s hidden inside a robust command
that ensures the correct category codes are used. Normally with
If the
When used with
When used with
When used with
When used with
If
For example:
If
For example:
Note that the argument is expanded when the option is set.
For example:
With
With
With dtltex files, this option will locally redefine the
underlying command used by
With
This option identifies the indexes of the columns that should be automatically
reformatted (but only for data types identified by
auto-reformat-types) when
The default separator may also be set with:
The CSV and TSV files don’t have the database name
included in the file, so the
After the file has been read, the command
The
Example 107 then reads this new file back in with:
This has created a second identical database called
“customers-v3”. The
Example 107 then re-saves the original
“customers” database in the DBTEX v2.0 format. (The default name
is still set to “customers”.)
The DBTEX v2.0 format has the database name hard-coded in the file and
doesn’t allow it to be changed (even if the
Some of the later examples that use this database (see §5) need the
numerical values, so it’s useful to switch on the store-datum
setting to prevent repeated parsing, and I’ve also set the default
name:
The second column is a little untidy as it has a mix of
some negative currency with the negative sign before the currency
symbol and some with the sign after the symbol.
The third column is also missing the number group characters.
The
The auto-reformat-types option could be used to omit integers
from being reformatted, but that would prevent the Unit column
(which also contains integers) from being reformatted.
In this case, the
With localisation support, this reformatting will use the formatting
commands that are sensitive to the region’s currency settings.
This means that the currency style can be modified:
The data is then displayed using the
If you need to fetch more than one entry for a particular row, you can use
the
Some iterative commands, such as
The placeholder command:
Individual entries in the current row can be fetched with:
Multiple entries in the current row can be fetched with:
If you’re not within one of the iterative commands that sets up the
If you don’t know the applicable row index, you can also set the
current row with:
No expansion is performed on
The following commands alter the contents of the
In addition to the iteration commands described in §3.8,
the following are also available.
If you have LaTeX3 syntax enabled, you may prefer the following instead.
The following commands are actually provided by datatool-base, but are listed here
for completeness.
Any package options provided when loading datapie will be passed to
datatool. If datatool has already been loaded, any
options will be passed to
The datapie package additionally loads the tikz
package.
Rollback to version 2.32 is available:
The principle command provided by datapie is:
The argument should be a
The
There is also a corresponding action, which has optional settings:
If you identify the required column of data with
The examples in this chapter use the “fruit” database (see
§3.2.7), which has two columns
identified by the labels “Name” and “Quantity”. The Quantity
column is numeric and so can be used to create a pie chart.
The options listed here may be passed as package options when
loading datapie. Unless otherwise stated, these options can’t
be used in
These settings may be set with the pie option in
These settings determine the pie chart’s radius, outline and segment
colours. See Examples 113, 114 & 115.
For example,
The inner labels are drawn inside each segment, offset from the
segment point by the inner offset. The outer labels are drawn
outside each segment, offset by the outer offset. The labels
will typically include the placeholder commands, which will change
with each segment. If the placeholder commands aren’t used, the
labels will be the same for every segment.
The default behaviour is to show the variable value in the inner
label and nothing in the outer label. See
Examples 116 & 117.
These examples use the “fruit” database (see §3.2.7).
The same result can also be achieved with the optional argument, but
bear in mind that you can’t use both the optional argument and the
include-if setting. The optional argument, if set, will
always override the include-if/include-if-fn setting.
Note the difference between Example 114 which
has a range:
The default behaviour is to show the variable value in the inner
label and nothing in the outer label.
The outer label format is changed to match the text to the segment
colour:
The 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 can either use the
segment-colors option to supply a list or use:
With the default color package option, the first eight
segments are initialised to the colours: red, green, blue,
yellow, magenta, cyan, orange, and white. With the
gray package option, the first eight segments are
initialised to eight different shades of grey. In both cases, only
the first eight segments have an associated colour. Bear in mind
that the gray package option simply sets the first
eight segments. It doesn’t enforce greyscale for any subsequent
segment colour changes.
For example:
The arguments are as follows:
Any package options provided when loading databar will be passed to
datatool. If datatool has already been loaded, any
options will be passed to
Rollback to version 2.32 is available:
The “width” is the fixed distance of the bar along the \(x\) axis
(barwidth) which is equal to 1 \(x\) unit, and the
“height” is the variable length along the \(y\) axis (indicating
the value). “Lower” is the \(y=0\) end of the bar, and “upper”
is the other end of the bar, which will be above (vertical) or to
the right (horizontal) for positive values or below (vertical) or to
the left (horizontal) for negative values.
The databar package provides two commands to draw bar charts.
For both
The
There are also corresponding actions. Both have optional settings:
If you identify the required column of data with
As with the
For example, the “fruit” database (see §3.2.7)
has two columns identified by the labels Name and
Quantity. The Quantity column is numeric and so can be used to
create a bar chart.
The “profits” database (see §3.2.8)
has columns identified by the labels Year and
Profit. The Profit column has some negative values, which
will result in downward bars, with the default vertical setting, or
leftward bars with the horizontal setting.
The “marks” database (see §3.2.1) has data
containing marks for three assignments given in columns labelled
Assign1, Assign2 and Assign3.
The options listed here may be passed as package options when
loading databar. Unless otherwise stated, these options can’t
be used in
These settings may be set with the bar option in
Most of the settings can be used instead of redefining or setting associated
commands (such as
For example, to set the colour list to exactly cyan, yellow, magenta
for a particular bar chart (as in
Example 137):
Certain rows in the database may be omitted from the bar chart
either with the optional
These settings determine the bar chart’s orientation, size, outline
and bar colours. Examples in
§§5.3.3, 5.3.4 & 5.3.7
demonstrate the chart upper and lower labels.
For example,
You can clear the list with
If you prefer, you can redefine
Each bar may have a label at either end. The lower label is the
label along the \(x\)-axis. The upper label is at the opposite end of
the bar. For \(y\) tick labels, see §5.2.4.
With
The bar chart \(x\) axis is horizontal for vertical bars and vertical
for horizontal bars. The \(y\) axis corresponds to the bar data value.
The \(y\)-axis may have tick marks. The \(x\)-axis doesn’t (but may
have labels at either end of each bar, see §5.2.3).
The \(y\) tick marks follow the same algorithm as those for
dataplot (see §6.1.4).
The placeholder commands are assigned using
The
Compare Example 128 with Example 112
which is identical except that one uses
The examples in §5.3.3 demonstrate
the default style for upper labels.
Bear in mind that if you switch to vertical bars the node alignment will need to
be changed to upper-label-align=[above]below.
(Alternatively, include the
In addition to lower and upper bar labels, multi bar charts created
with
The group label normally is positioned at the mid point of the group below the
lower bar labels (if present).
This leads to a cluttered chart. A better solution would be to add
a \(y\)-axis with tick marks to show the values and a legend
associating each bar colour with the corresponding assignment
(see Example 144).
Note that the \(y\) axis label (“Profits”) is aligned at the mid
point of the \(x\) axis, below the \(y\) tick labels. This can look
strangely off-centre if the origin isn’t in the middle of the \(x\)
axis (as in this case, since the absolute value of the negative
extent is smaller than the maximum positive extent.)
If there are insufficient colours, you can cycle round the set.
By default, the negative bars will use the same colour set as the
positive bars (see Example 123).
Each bar is drawn using tikz’s
If the
For a multi bar chart, the colours change for each bar within the
group. If the above
For example, if the original value in the database column labelled
Profit for the current bar is
The placeholder commands assigned in the final
argument of
Since both
The following three commands expand to the start point, mid point
and end point of the main mid-axis through the current bar.
Each point is expressed as a pgf
point
In any of these hooks you can access the total bar chart \(x\)-axis
length with:
With
Any package options provided when loading dataplot will be passed to
datatool. If datatool has already been loaded, any
options will be passed to
The dataplot package additionally loads the tikz package
and also the tikz plot libraries plotmarks,
plothandlers and calc.
Rollback to version 2.32 is available:
The principle command provided by dataplot is:
The
The x and y settings should be a comma-separated
list of column keys identifying the columns to use for the \(x\) and
\(y\) co-ordinates. They must both have at least one element, and the
number of elements in x must be less than or equal to the
number of elements in y. Spaces and empty items are
skipped. For example,
There is also a corresponding action:
The primary return value is the total number of plot streams. This
will be 0 if an error occurred. The secondary return values will
only be set if no errors occurred while parsing the settings:
For both
The bounding box, grid, axes, tick marks, tick labels and axis labels
are drawn first, if applicable. The legend is drawn last, if
applicable. The hook
The plot settings may be provided in the final
For example, suppose the database “results” has columns with
labels “Time”, “Temperature” and “Notes” where the notes
column is set to “Incorrect” for rows where the measurement was
incorrect. These rows can be excluded:
Note that the
The default colour indicates the default for tikzpicture. This
can be changed in the
If you want some plot streams within the same
This is a multiple choice setting so you can combine allowed values
in
This setting is equivalent to style-resets={mark-style,
mark-color,
line-style,
line-color}.
This is a multiple choice setting so you can combine allowed values
in
This setting is equivalent to group-styles={mark-style,
mark-color,
line-style,
line-color}.
This setting has no effect if no plot lines should be shown
(style=markers).
This setting has no effect if no plot lines should be shown
(style=markers).
This setting has no effect if no plot markers should be shown
(style=lines).
This setting has no effect if no plot markers should be shown
(style=lines).
By default, the tick marks will be automatically generated from the
data bounds (which will either be determined from the maximum and
minimum values in the data or by options such as bounds).
If no gap is explicitly set (with x-tick-gap or
y-tick-gap)
then the gap between major tick marks is calculated according to an
algorithm that’s based on the maximum and minimum values and the
minimum gap length (as an absolute dimension) given by
If an exact set of the major tick marks is required, the desired co-ordinates
can be set with x-tick-points (for the \(x\)-axis) and
y-tick-points (for the \(y\)-axis). These should be a
comma-separated list of plain numbers in data units. This will
override the above tick mark algorithm and the gap setting will be
ignored. The minor minimum distance will still be referenced if minor tick
marks are required.
The tick mark labels will then be obtained from the tick mark values
and converted to decimal datum items, where the string part is the
formatted numbers corresponding to the tick mark value (with
rounding applied according to the applicable rounding setting).
The \(x\)-tick mark labels will be encapsulated with
If zero doesn’t lie within the plot bounds, then setting will only
make a difference if you have the box and tick marks.
With side-axestrue, tick marks will be drawn along the
top and right sides of the box. This will only be noticeable if
you have extended the axes. With side-axesfalse,
tick marks will be drawn along all sides of the box.
This option affects the length of the \(x\)-axis, the location of the
lower and upper \(x\) labels, and the size of the
encapsulating box if box=true. The values should
be in data co-ordinates. A positive value extends the axis.
A negative value shortens it.
Extending the axis may result in it overlapping a tick label.
The \(x\)-axis length will end up greater than
This option affects the length of the \(y\)-axis, the location of the
lower and upper \(y\) labels, and the size of the
encapsulating box if box=true. The values should
be in data co-ordinates. A positive value extends the axis.
A negative value shortens it.
Extending the axis may result in it overlapping a tick label.
The \(y\)-axis length will end up greater than
The examples in this section use the “time to growth” data,
described in §§3.2.9 & 3.2.10, and the
“xydata” database, described in §3.2.11.
The time to growth data represents hypothetical microbiological
experiments observing microbial populations after certain time
intervals at a particular temperature. The population figures are
actually recorded as the log count, rather than the actual count.
The dataplot package does support logarithmic axes. The sample
data is simply a list of numbers to demonstrate how to use
The examples in this section demonstrate basic use. They set the
\(x\)-axis label with x-label and the \(y\)-axis label with
y-label. The width and height are also set to produce a
smaller image than the default setting.
For examples demonstrating how to adjust the legend text or move it
to a different position, see §6.2.2. For
examples demonstrating how to have line plots or change the colours,
see §6.2.3.
Note that the “growthdata2” database actually has six columns,
rather than four.
For debugging purposes, it’s useful to show the column keys in the
legend instead of the column headers. This can be done as follows:
The legend is now so large it obscures half of the plot.
Examples that adjust the legend settings are in
§6.2.2.
In general, it’s best to either have a single key in the x
setting or the same number of keys as for the y setting.
To demonstrate what happens when the x list has more than
one key but less than the total number of y keys,
The plot streams for the second database are obtained from the X/Y
pairs: Exp1Time/Exp1Count, Exp2Time/Exp2Count and
Exp1Time/Exp3Count. Once the end of the x list is
reached, it cycles back until all the y columns have been
iterated over. This method allows a single x column to be
plotted against multiple y columns, but also allows a list
of x columns to be plotted against a matching element from
a list of y columns.
In general, it’s better to repeat a column key in x than
to have this situation.
If the legend option is set then each plot stream for a
given x and y pair for a given database will add
a row to the legend (as demonstrated in the previous examples).
There are user hooks available (see
§6.3) but essentially each row in the legend
starts with the plot mark or line (or both) used by the plot stream
followed by text in the form:
The x column,
which is obtained with
If you don’t provide enough items in legend-labels, the defaults will be
used for the missing ones.
The
The use of legend-labels may be sufficient for a small
number of plot streams, as in
Example 152, but it can become more
complicated with additional files. The earlier Example 146
which had two files, showed the database names in the legend
(“growth1” and “growth2”). Let’s suppose that the experiments
in the first database were conducted at a temperature of 6 degrees
and the experiments in the second database were conducted at a
temperature of 8 degrees.
The siunitx package conveniently provides a way of typesetting
temperature, so the legend labels could be set using:
The slash separator can be changed by redefining
The examples so far have simply used legend without a
value. This is equivalent to legend=northwest. This
positions the legend in the north west (top right) of the plot at an
offset given by the lengths
Instead of using one of the pre-defined legend locations,
you can use the legend=custom setting and
redefine
The plot now needs the legend option adjusting:
The examples so far have only shown markers with the default mark
style and colours. The plot can have the style changed to show both
lines and markers with style=both or only lines with
style=lines.
The group-styles option may be used to only change a
particular style per database, rather than using each style per plot
stream.
The examples so far have the plot bounds automatically calculated.
This means that the \(y\) tick marks look a little strange as they
don’t start from a whole or half number. The \(x\) tick marks look
more even as the sample data happens to have convenient \(x\) values.
The examples in this section demonstrate how to set the upper and
lower bounds.
The tikz line drawing style of the \(x\) and \(y\) axes can be
changed with the axis-style option.
The grid option draws a grid in the background before
drawing the plot streams.
The style of the major grid lines is obtained by expanding
The box option encapsulates the (extended) plot bounds
with a box. Note that this doesn’t include the tick labels and axis
labels unless they also happen to lie within those bounds.
By default, the box will have tick marks that match the axes tick
marks. This can be changed with the box-ticks option.
Note that extending the axes and the side-axes option has
an effect on the box option. See
§6.2.4.9.
The examples so far have all had non-negative \(x\) and \(y\) values.
The “xydata” database (see §3.2.11) has some
negative values that can be used to demonstrate a graph with axes
that stretch from positive to negative.
Examples 172 & 173 used
tick-label-style to change the font to a smaller size:
The default side-axes=false setting will draw the axes
crossing at zero, if zero lies within the plot bounds. If zero
doesn’t lie within the plot bounds, the axes will be on the side
with the \(x\) and \(y\)-axis meeting at \((x_{\min },y_{\min })\). That is,
the minimum \(x\) and \(y\) of the bounds plots.
As with Example 174, the tick label style is
redefined to use math mode:
The “time to growth” data (see §3.2.9)
used in earlier examples happens to have 0 as the minimum \(x\) value
(which in this case is the time \(t\) value). The \(y\) values are all
non-negative, which means that the axes will be on the side
regardless of the side-axes setting.
In this case, the
difference between side-axes=true and
side-axes=false is only noticeable when the axes are
extended beyond the minimum bounds and the box option is
set. This is illustrated in
Examples 176 & 177
which adapt Example 170 to extend both axes. The difference
between them is the side-axes setting.
The \(x\) and \(y\) axis labels are independent of the axis extensions.
In
Examples 176 & 177,
the \(x\) label is inside the box because the \(y\) extension is large
enough to include it, but the \(y\) label is outside of the box
because the \(x\) extension isn’t large enough to include it.
Additional information can be added to the plot with the start and
end hooks.
Examples 172, 173 & 174 don’t
show the tick label at \((0,0)\) because of the default
omit-zero-label=auto setting. Changing this setting to
omit-zero-label=false would show 0 at both \(x=0\) and
\(y=0\). However, this will result in the axes passing
through the 0 labels.
The transformation used by
The total number of keys provided in the x and y
lists and the total number of databases can be obtained with the
following macros, which simply use
If you want to redefine
At the end of each stream, the legend text is obtained and, if not
empty,
The token list variable is cleared before passing it to this
function. If the function is redefined so that it doesn’t modify the
token list variable then the current plot stream won’t be added to
the legend.
The default behaviour of
If you need to access other information about the current plot
stream, you can do so with the following integer variables, but bear
in mind that while ldataplotstreamindexint,
As described in §6.3.2, the default legend text is obtained
with
In the following legend commands,
If data is obtained from more than one database and more than one
column for the x variable, then the legend row will be in
the form:
The above
If the legend includes
The following conditionals are defined by dataplot. These are
TeX style
The following length registers are defined by dataplot.
They may be changed with
The following counters are defined by dataplot. They can be
globally changed with
Note that if the tick labels are automatically generated from the
data (rather than by specifying them with x-tick-labels or
y-tick-labels) then the argument will be a datum item
where the string part is the formatted number. If you prefer a
plain number you can redefine
These commands are provided for use in the start and end hooks to
add extra plot streams. However, they are largely redundant now that
The databib package was rewritten in version 3.0 to use
LaTeX3 commands. The xkeyval package has been dropped.
Rollback to version 2.32 is available:
The databib package works by using BibTeX with the custom
databib.bst style file to create a bbl file
that contains commands to construct the datatool database (as
opposed to the more typical behaviour of writing the bibliography
typesetting commands to the bbl file). The commands
Once the database has been created, it can then be sorted using
Whilst the database can be iterated over with
The databib package will automatically load datatool, if
it has not already been loaded. The databib package has the
following options:
All other options will be passed to datatool, if it hasn’t
already been loaded, or will be set with
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 (aux) file. BibTeX then reads
this file and looks for the commands
In general, given a document called, say, mydoc.tex, you
will have to perform the following steps to ensure that the
bibliography and all citations are up-to-date (replace
latex with pdflatex, xelatex or
lualatex, as applicable):
The bibliographic data required by BibTeX must be stored in
a file with the extension bib, where each entry is stored
in the form:
@article{brown2022,
author = "Mary-Jane Brown",
title = {An interesting paper},
journal = TUGBOAT,
year = 2022
}
The entry type, given by bst bibliography style file, but the standard ones are:
article, book, booklet, inbook,
incollection, inproceedings (with synonym
conference), manual, mastersthesis,
misc, phdthesis, proceedings,
techreport or unpublished.
The
With BibTeX, author and editor names must be entered in one of the following
ways:
The
Again the
Multiple authors or editors should be separated by the key word
and, for example:
Below is an example of a book entry:
You can concatenate strings using the # character, for example:
Each row of a databib database corresponds to an entry in the
bib file. The custom databib.bst file ensures that
BibTeX creates a file where each selected citation is added as a
new row to the database, and each column in that row corresponds to
a bib field supported by databib.bst. Note that
although BibTeX fields are case-insensitive, the datatool
column keys are case-sensitive.
These case-sensitive column keys are described below.
The remaining columns correspond to the field provided by
databib.bst and will be null if not set or not supported by the
entry type. The columns will only be added to the database if the
field was found by BibTeX (that is, the field is present in the
bib file and supported by the entry type).
The databib package always requires the databib.bst
bibliography style file (which is supplied with datatool).
This ensures that the bbl file will be in the format required
for
You need to use
You then need to compile your document with LaTeX and then run BibTeX on the auxiliary file, as described in
§7.2. This will create a bbl file which
contains all the commands required to add the bibliography information
to the datatool database called . The next
time you LaTeX your document, this file will be read, and the
information will be added to the database .
Note that the databib.bst BibTeX style file provides
additional fields (see §7.2.2) that are not
supported by the basic BibTeX styles, and so are ignored by the
three predefined 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 §7.7.1). The simplest
method is to added the extra information in the
If you use the standard BibTeX month abbreviations (JAN,
FEB, etc), the databib.bst style will convert those
to:
The bbl file created by the databib.bst BibTeX style
file contains database construction commands rather than code to
typeset the bibliography. These commands don’t have the database
name included in an argument (since the databib.bst style
file doesn’t have that information). Instead, they rely on the
following placeholder command:
This file is input by
This means that it’s possible to append to an existing database by
simply inputting the bbl file (with a check for existence).
However, you must make sure that the databib bibliography
style is set and that
Once a database has been loaded with
For example, to sort in reverse chronological order:
If you want to sort by
To make it easier to adjust the sort value for the
For example, the following sorts by
A databib database which has been loaded using
Within the optional argument
For example, suppose you have loaded a databib database
called “mybib” using
Note that
The style of the bibliography produced using
For example:
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
You can use
The list of authors and editors are stored in the databib
database as a comma separated list where each item is in the form { }{ }{ }{ }. This assists
with sorting by author or editor (but this may require adjustment,
see §7.5). Each element of the
list can then be passed to
Within the definitions of
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 with:
The above two list commands internally use:
Within a list of names, the separators used are:
Within the definition command, you
may use the commands
The commands used by
If the hyperref package has been loaded, the DOI will be a
hyperlink otherwise it will simply be displayed in a monospaced
font with
If hyperref has been loaded, a hyperlink will be created with
the second argument as the link text, otherwise the first argument
will be displayed in a monospaced font, prefixed by the second
argument.
The hooks described in §7.7.1 to adjust the
format of
Although
For each row of the database, the following commands are set:
The remaining fields may be accessed using:
If you want to encapsulate a field with a command, you can simply
include
However, it’s also possible to use:
Alternatively, you can assign the value of a field to a control
sequence
You can determine if a field exists for a given entry using
Note that none of the above three commands use
It is possible to have more than one bibliography in a document,
but it then becomes necessary to have a separate auxiliary (aux) file
for each bibliography, and each auxiliary file must then be
passed to BibTeX. In order to do this, you need to use
When you want to cite an entry for a given bibliography named
in
If you want to add an entry to the bibliography without producing
any text, you can use
The examples here use one or both of the following sample files.
The first file, sample1.bib, contains some of my own
publications with a mixture of entry types:
Note that it’s not necessary to actually display the bibliography if
it’s not required (but it would be required if any entries are
referenced with
The data is then displayed with filtering applied, so that only the
entries where the row is greater than or equal to 2013 are shown:
In addition, to demonstrate the end item hook, I’ve redefined
Note that, although Example 182 only shows five items,
the loop iterates over all entries in the database.
It’s more efficient (particularly for large databases) to
terminate the loop after the fifth row with
Once I have set the style, I can further modify it thus:
As described in §2.3, the
datatool-base package (which will automatically be loaded by
the databib package, if not already loaded) provides
localisation support via the tracklang interface. The
databib package uses the same interface to load the file
databib-.ldf for each tracked locale
if that file is installed on TeX’s path.
The supplementary datatool-english package (which needs to be
installed separately), described in §2.3.5,
includes databib-english.ldf, which provides English
localisation support for the databib package. This file may be
used as a template for other languages.
Any localisation options specific to databib should be
identified by
The datagidx package can be used to generate indexes or
glossaries as an alternative to packages such as glossaries.
It was written in 2013 before I added
The datagidx package was rewritten in version 3.0 to use
LaTeX3 commands. The xkeyval and afterpage
packages have been dropped and the
use of
The datagidx package works by having a predefined database
called
Whenever a term is referenced using a command such as
The list of referenced terms can then be displayed with
Any options that may be passed to datatool can also be passed
to datagidx (unless datatool has already been loaded and
the option isn’t permitted in
The datagidx package provides the
The following options are also considered global options but may be
changed after the package has been loaded.
These options relate to the way the index or glossary is
formatted by
The following options may be set after the datagidx package
has been loaded with the index setting.
For example:
These settings may be localised but they apply to all index or glossary databases.
They can’t be set in the optional argument of
These options are applicable to both
These options are only applicable to
If the
Before you define any terms, you need to create the database in
which to store the information. This is done with:
This does more than simply create the database with
If you have edited and sorted a datagidx database in datatooltk,
you can then just load it using:
Since
A new term may be defined in the preamble with:
If datatool-base’s verbose mode is on,
The sort value is stored in the database’s Sort column,
which is referenced in the default
The term’s hierarchical sort value, which is stored in the
HierSort column and only set for child entries, is obtained by
appending the sort value to the parent’s HierSort
value (or the parent’s Sort value, if the parent doesn’t have a
parent), separated by:
The following options are provided for use by
The commands described below may be used in the term’s name but
expand differently depending on the context.
Remember that if the text, label or sort values
aren’t provided, they will be obtained from the name.
These commands may be nested. For example:
All defined terms must be supplied a unique label in order to
reference them. For example:
The automatic label creation locally redefines certain commands,
performs a protected expansion, strips awkward characters and
purifies the result. This means that the above example can simply be
written as:
The steps are described in more detail below.
The command
Some of the markup commands described in §8.4.1
are redefined. These are:
The user hook is:
If the sort value isn’t set, it will be obtained from
the name. For example:
The steps to create the missing sort value are similar
to those for the label, but there are some slight differences.
The command
The markup commands described in §8.4.1
are redefined:
The user hook is:
Terms that have been defined with
For example, suppose I have
previously (in the preamble) defined the term “reptile” using:
If the hyperref package is loaded, the above commands will
automatically create hyperlinks to the relevant entry in the
index/glossary (produced with
The sentence case version is:
The all caps version is:
You can also specify your own custom text:
In all the above commands, the without the preceding backslash. This command will be
applied to this location in the entry’s location list when it’s
displayed in the index/glossary (produced with
For example:
You can simply display the value of a field using:
The sentence case version is:
The above commands aren’t expandable. If you want to fetch a value
without displaying or using it, you can use:
You can add an entry to the index/glossary without displaying any
text using:
You can also add all entries from a particular database using:
There are some shortcuts to common fields (if you are used to the
glossaries package, note that these commands have different
syntax to the commands provided by glossaries with the same
name):
Each location shown in
Each location is saved in the aux file and added to the
Location field list for the relevant row of the database on
the next run. The location list is then displayed (if supported by
the style) at the end of the relevant row in
A location may be in the form compositor. The default compositor is a
period/full stop but may be changed with the
If you want additional fields, you need to create a new column in
the database and a corresponding option for use in
The
The
Within
For example, suppose I want to be able to specify an alternative
plural. I can add a new field like this:
Here’s another example. Suppose I want to add a field that produces
the past tense of a verb. In this case, the default should be formed
by appending “ed” to the text value. The new
field can be defined as follows:
Let’s define a shortcut command to access this field:
You may have noticed that you can specify short and
long values when you define a new term. There is a
convenient shortcut command which uses
The datagidx package only provides a very basic abbreviation
style. For more complex requirements, consider using the
glossaries-extra package. See
Gallery: Abbreviation Styles for
examples.
You can use terms that represent abbreviations via commands such as
The plural form is obtained using:
Note that, unlike the glossaries package,
As a general rule, it’s not consider appropriate to capitalise the first
letter of an abbreviation (especially if it is displayed in small caps)
but if you need to you, for example, first use occurs at the start
of a sentence, can use the following commands.
The commands used for formatting and indexing the first use form
are:
You can reset a term so it’s marked as not used with:
You can reset all the terms defined in a given database using:
A database created by
The heading and style is obtained from the special datagidx
catalogue database (see §8.10), but
this may be overridden by the options provided to
The code supplied by the
Then
The placeholder commands set by
If the
This allows the styles to compare
Note that
Finally,
The commands described here are independent of the style, that is
the style may use them but should not redefine them. They may
be redefined explicitly, but some of these commands are redefined by
a setting, such as
The name, including the case-changing and font-changing commands,
will be encapsulated with
The symbol and description (if not null and not empty) may be shown,
depending on the
The location list may or may not be shown, depending on the
Each item label in the cross-reference list is encapsulated with:
The style used by
The default index style is a basic style for indexes, but the symbol
and description will be shown if set, and it will follow
the
The indexalign style is similar to the index style but
aligns the descriptions. This requires an initial iteration over the
database to calculate the alignment.
The align style aligns the fields. It will follow
the
The gloss style is a basic style for glossaries.
The dict style is a dictionary style, for a hierarchical
structure where the top level entries have a name. The next level is
used to indicate a category, such as “adjective” or “noun”. If
there is only one meaning this level also has a description. If
there is more than one meaning, each meaning should be a child of
the category entry. Only third level entries are numbered. The
Child column is ignored by this style. The symbol is ignored. The
location and symbol widths are also ignored.
If
When displaying the list,
Prior to version 3.0, the default
If you don’t want the database sorted, just set
Version 3.0 has improved sorting times by switching to
the more efficient l3seq sorting function. However, for a
large database, you may still want to switch on the optimization
settings.
If you have used indexing applications, such as makeindex,
you’ll be familiar with the document creation process. The document
is first compiled, then the indexing application is run to sort and
collate the entries, then the document is compiled again (and
possibly once more). This involves two (or three) runs and one sort
and collate run (with the process possibly repeated in the event of
complex documents with shifting page numbers). With the
datagidx package, the sorting and collation is done every
LaTeX run. For a large index, this can be quite slow. If you’re
not editing the index or glossary, you might prefer not to have to
keep sorting the database whenever you update the document. To
assist this, datagidx provides the optimize
package option. This may take the following values:
Don’t use the optimize facility. The index/glossary databases
will be sorted every run, unless the sorting is switched off
by setting the
Use the “low” optimize setting. This only sorts the index/glossary databases on every run. This is assuming that the sorting
is done via the
Use the “high” optimize setting. This sorts the index/glossary
databases on the first run, then writes the sorted databases to
external files, which are read in on subsequent runs. Again this
assumes that sorting is done via the
The
If
After
The placeholder commands are assigned by expanding:
There is a hook implemented at the end of
When
Certain commands, such as \&, are converted with:
In order to support hyperlinks, the entry name (including the
case-changing and font changing commands) should be placed in the
second argument of:
There are two types of databases recognised by datagidx: the
catalogue database, and the databases used to store the terms.
The datagidx package automatically creates a database called
datagidx. This database keeps track of all the databases
that are created by
Each database created with
The following are considered worker fields that will typically not
be needed in hooks or styles.
This requires two LaTeX runs to ensure that the index is up to
date.
The person package was rewritten in version 3.0 to use
LaTeX3 commands. The internal list of labels is now stored as a
sequence variable, which means that loop commands, such as
If there are any backward-compatibility issues, rollback to version
2.32 is available:
The person package now has the provision for tracklang
localisation support, using the same localisation settings as for
the underlying datatool-base package. The
datatool-english package (distributed separately) includes
the file person-english.ldf which provides the
English localisation support for the person package. This
simply needs to be installed on TeX’s path and will be loaded
automatically if required (see §9.7.3).
Any options recognised by datatool-base may also be passed to
the person package. Similarly for datatool if that
should also be loaded.
For example:
The following options may be passed to the person package when
it loads. They can’t be used in
These options may be used within the person option of
The effect of these commands may be scoped
local=true. Otherwise they will be global.
If the anon will be
used. This is the default label for commands such as
Available options:
When defining a new person, you can identify the person’s gender
using a label. There are four categories:
Alternative male labels, which may be used to reference the gender
in
The list may be set by a localisation file or you can
set or append to it before you define new people.
Alternative female labels, which may be used to reference the gender
in
The list may be set by a localisation file or you can
set or append to it before you define new people.
Alternative non-binary labels, which may be used to reference the gender
in
The list may be set by a localisation file or you can
set or append to it before you define new people.
If you want to test if a label is a recognised gender label, you can
use the following commands. The
The commands below that start with
The commands that start with
The text produced by these commands can be changed with
Some of the commands listed here are a bit cumbersome. The
shortcuts option will define shorter synonyms for some
of the commands. These are listed in Table 9.1.
The information provided when defining a person can be accessed with
these commands. Where the label identifying the person is optional,
anon will be used if omitted.
The commands in this section produce a list of all the defined
people. The separators are given by:
Sometimes when mail-merging, it may be necessary to reference a
person by their pronoun, but it’s inappropriate to make an
assumption and the impersonal “he/she”
construct is not only cumbersome but also dated. By defining a
person with a gender (male, female or non-binary), the commands
described in §9.5 may be used to insert a
language-sensitive pronoun.
For simplicity, the letter class is used:
Example 189 shows the first four pages. Download the
PDF to view the complete document. Note that the student Quinn
doesn’t have the gender field set in the database so the placeholder
Defining a person with a name and gender can also be useful for
other non-database 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 person package, you need only change the definition of
the person by modifying the arguments of
Note that this has the ampersand character (&) rather than the
textual “and”. Add localisation support if text is preferred. If
localisation support is available but the ampersand character is
preferred, then use
Again the
shortcuts option may be used to enable the shorter,
more readable, commands.
For example, load datetime2 first with regional support:
Example 193 makes this modification to
Example 192, along with:
You can alter or set an attribute for a given person using:
You can get an attribute with:
You can undefine an attribute with:
If you have LaTeX3 syntax enabled, you can use the following
commands.
The following commands test a label, which may be
supplied as a token list variable or as a token list,
against the recognised internal gender labels.
In the event that you only need to know if the label is valid, you
can use:
The following command simply compares
The loop commands have changed in version 3.0 to map over a
sequence variable instead of using
As described in §2.3, the
datatool-base package (which will automatically be loaded by
the person package, if not already loaded) provides
localisation support via the tracklang interface. The
person package uses the same interface to load the file
person-.ldf for each tracked locale
if that file is installed on TeX’s path.
The supplementary datatool-english package (which needs to be
installed separately), described in §2.3.5,
includes person-english.ldf, which provides English
localisation support for the person package. This file may be
used as a template for other languages.
If the localisation support provides options (which person-english.ldf
currently doesn’t), the sub-module should be “person” when using
Recognised values of
The localisation file should also use
You can add support for other types, but make sure you document that
those types are only available for your localisation support. The
language text can be obtained with the following commands. In each
case, the
There are hooks available when defining a new person.
If you want to add any extra keys for use with
Many thanks to Morten Høgholm for providing 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.
As
Displays the short form if the abbreviation identified by §8.7.1; 603
Used to encapsulate the short form of an abbreviation defined with
As
Displays the plural short form if the abbreviation identified by §8.7.1; 603
This deprecated command has been replaced with
This deprecated command has been replaced with
Constant regular expression that matches either a straight apostrophe character or a closing single quote character. §2.3.2; 44
Constant datum control sequence representing an empty value with the unknown data type.
Constant integer (0) used to identify the string data type. Note that datatool provides
Shortcut for
Placeholder in
Shortcut for
Constant that expands to female, which is the internal label used to identify the female gender.
Constant that expands to male, which is the internal label used to identify the male gender.
Constant that expands to nonbinary, which is the internal label used to identify the nonbinary gender.
Constant that expands to unknown, which is the internal label used to identify the unknown gender.
Placeholder in
Used by
Placeholder in
Indentation used by the dict style. §8.8.2.5; 612
Style command used by
Style command used to display the current entry within
Defined at the end of
If hyperlinks are support, creates a hyperlink with §8.9.3; 618
Alignment of the location list when the location width has been set. §8.8.1; 610
Dimension that indicates the space to allocate for each location list. If zero or negative, the location list will simply occupy its natural space. §8.8.1; 610
Used by styles to iterate over the database. §8.9.1; 616
Defines a new style called
Assigned by
Used by
Style command used by
Alignment of the symbol when the symbol width has been set. §8.8.1; 610
Dimension that indicates the space to allocate for each symbol. If zero or negative, the symbol will simply occupy its natural space. §8.8.1; 610
Creates a hyperlink target, if supported, and does §8.9.3; 618
Used by
For use within
May be used with
Gets the default legend label (if not provided by legend-labels). The label should be stored in the provided token list variable , which will initially be empty. §6.3.2; 509
Adds the beginning of the legend code to
Adds the end of the legend code to
May be used with
May be used with
Used by
Expands to nothing normally but expands to the delete character (0x7F, the highest ASCII character) inside
Expands to nothing normally but expands to null character inside
Expands to nothing normally but expands to the control character 0x1F, inside
Used by
For use by regions that support a prefix for the currency symbol. The
Inserted by
Inserted by
Used to markup a decimal value. §2.2.4; 21
Interrupts the LaTeX run and shows the component parts of the given datum control sequence. §2.2.3; 18
If the database identified by §3.6; 236
Shortcut that uses
Used by
Extracts the date/time data stored in the given datum control sequence and stores the result in the token list register . §2.2.4; 21
Currency format for GBP (requires datatool-regions, which is not included with datatool).
Obtains the first grapheme of expand to that grapheme. §2.8.3; 148
Similar to
Tests if the integer §2.2.4; 22
Tests if the database with the label §3.6; 237
Tests if the integer §2.2.4; 22
Tests if the integer §2.2.4; 22
For use with display hooks such as
Tests if the integer §2.2.4; 22
Tests if the integer §2.2.4; 21
Tests for equality where one or other variable may be a datum control sequence. If both are numeric datum control sequences they will be compared numerically, otherwise they will be compared by their string values. §2.2.4.2; 23
Tests for equality where datum control sequence and may be a datum item. If both are a numeric datum control sequence and datum item they will be compared numerically, otherwise they will be compared by their string values. §2.2.4.2; 23
Tests for equality where datum control sequence and may be a datum item. If both are a numeric datum item and datum control sequence they will be compared numerically, otherwise they will be compared by their string values. §2.2.4.2; 23
Tests for equality where one or other or the token lists may be a datum item. If both are numeric datum items they will be compared numerically, otherwise they will be compared by their string values. §2.2.4.2; 23
Define keys for localisation support.
Maps over all the columns in the given database, applying the function to each set of column meta data. The function should have four arguments
Maps over all the columns in the given database, applying the inline function to each set of column meta data. Within
Expands to the current maximum known data type identifier. §2.2.4; 21
Measures the width, height and depth of
A shortcut that uses
A shortcut that uses
Measures the combined height and depth of
A shortcut that uses
Pads plain number (decimal or integer) before use. If the number in was originally an integer, it will become a decimal with 0s after the decimal point. This command does nothing if is not greater than zero. §2.8.3; 146
Typesets parenthetical content, this command expands to
Designed to indicate the start of parenthetical content, this command expands to
Designed to indicate word inversion for a person, this command expands to
Designed to indicate a comma to clarify a place, this command expands to
A hook that may be used to post-process the letter group token variable after sorting. §3.14.1.1; 326
Designed for use in
Hook provided by region files to set the region’s currency. This hook should check the boolean
Hook provided by region files to set the region’s number group and decimal characters. This hook should check the boolean
Provided by region files that support a prefix for the currency symbol (not all do). If supported, the region should provide an option called currency-symbol-prefix which can show or hide the prefix. The prefix, if enabled, is formatted with
Region files should use this command to register the currency code defined by that region. §2.3.2; 44
Similar to
Locally redefines common currency commands (for sorting). §2.9.5.3; 168
Sets the floating point variable datum control sequence or a datum item or in a locale-sensitive format that requires parsing. §2.2.4.3; 26
Sets the current number group character and decimal character. §2.3.2; 42
Sets the current number group character and decimal character for formatting and parsing. §2.3.2; 42
Sets the current number group character and decimal character for formatting to and and sets number group character and decimal character regular expressions used by the parser to and . §2.3.2; 43
Sets the current number group character and decimal character for formatting to and and sets number group character regular expressions used by the parser to and the decimal character to . §2.3.2; 43
Sets the current number group character and decimal character for formatting to and , and sets the number group character to and the decimal character regular expressions used by the parser to . §2.3.2; 43
Similar to
Similar to
Expand and apply the current sort hooks to §2.9.5; 162
Designed to indicate heading inversion, this command expands to
Designed for use in
Inserted by
Used by the default timestamp formats to separate the date and time if both provided. By default, simply expands to
Used by
Used by
Inserted by
Placeholder command set by commands such as
Placeholder command set by commands such as
Placeholder command set by commands such as
Placeholder in
Calculates the absolute value of the formatted number and stores the result as a formatted number in the control sequence . §2.5.2; 110
Defines the control sequence plain number. §2.5.1; 100
Performs a command corresponding to §3.3
Calculates \(formatted numbers. The result will be a formatted number. §2.5.2; 108
Calculates \(plain numbers. §2.5.1; 98
Used by
Adds all the formatted numbers in the comma-separated and stores the result as a formatted number in . §2.5.2; 108
Adds all the numbers in the comma-separated list plain numbers. §2.5.1; 99
Adds a column with the label §3.6; 240
Adds a column with the label §3.6; 240
Used by
Adds an entry to the legend. §6.3.2; 508
Expands to content to be inserted by
Used by
Used by
Token register used to store the content after the current row when
Used between the final pair of names where there are more than two names in the list. §7.7.1; 541
Expands to
Used between all except the final pair of names where there are more than two names in the list. §7.7.1; 542
Anglo-Saxon (Latin Script) group string handler. §2.3.5; 57
Used by
Appends an entry with the given
May only be used within the unstarred
Selects the current row according to its row index (using
Globally defines the commands in the assignment list for the first row in the database identified by where the column identified by matches . This command is not affected by the global option. §3.16; 366
Assignments elements in the current row (
Used by
Hook used by
Hook used by
Draws a bar chart using data from the database identified by variable setting to identify the placeholder command that will be assigned to the numeric values for the chart. §5; 396
Length register that governs the bar chart length. §5.4.1; 438
For use in the bar chart hooks, this will expand to the length of the current bar chart’s \(x\)-axis (in terms of bar width) as a dimensionless number. §5.4.4; 445
Used to format \(y\) tick labels. §5.4.2; 441
Placeholder command that expands to the current group bar index, for use in lower or upper labels or hooks (expands to 0 in
The expansion text of this command should be the
For use in the bar chart hooks, this will expand to the width of the bar groups in the current bar chart (in terms of bar width) as a dimensionless number. §5.4.4; 445
Placeholder command that expands to the current bar index, for use in lower or upper labels or hooks. For
Length register that governs the distance from the bar to the bar label. §5.4.2; 439
The maximum value of the \(y\) axis or empty if the maximum value in the data should be used. §5.4.1; 438
The expansion text of this command should be the colour of the bar outline or empty if no outline should be drawn. §5.4.3; 442
Length register that governs the bar outline width. §5.4.3; 442
Used by the upper-label-align=to redefine
This command expands within the optional argument of
For use in the bar chart hooks with
Placeholder command that may be used in lower or upper labels to show the formatted number (which will be rounded according to the round setting) for the bar value. §5.4.2; 439
Placeholder command that may be used in lower or upper labels to show the actual value. §5.4.2; 439
Length register that governs the bar width. §5.4.2; 439
The expansion text of this command should be the tikz line style specifier for the \(x\)-axis. §5.4.1; 438
The expansion text of this command should be the
The expansion text of this command should be the
The expansion text of this command should be the
The expansion text of this command should be the
The expansion text of this command should be the tikz line style specifier for the \(y\)-axis. §5.4.1; 438
The expansion text of this command should be the
Expands to content to be inserted by
Token register used to store the content before the current row when
Expands to content to be inserted by
Used by
Locale-sensitive command used by
As
Placeholder command set by
Used to format the
Used by
Expands to the textual tag used at the start of
Used to format the
For use in
For use in
For use in
For use in
For use in
For use in
For use in
For use in
For use in
Formats the information provided in the
Used within
Shortcut command that starts and ends DTLthebibliography and, within the body of that environment, iterates over the given database with
Sets the bibliography style to plain, abbrv or alpha. §7.7; 539
Used to format the
Used by
Expands to the textual tag used at the start of
Provided for use with the
Used by
Separator used by
Used to format the
Used to format the
When used in the loop body of
Similar to
Clears the bar colour list. §5.4.3; 443
Clears the database with the label §3.5; 236
Clears the negative bar colour list. §5.4.3; 443
Converts the formatted number to a plain number, clips it using
Removes redundant trailing zeros from plain number. §2.5.1; 100
Defined by
Expands to the column count of the database with the label §3.6; 237
Used by
Expands to the column index for the column with the label §3.6; 238
A count register used by various commands to keep track of a column number, which may be used by hooks.
Compares
Computes the maximum and minimum \(x\) and \(y\) values over all databases listed in §3.13; 324
Computes the widest bibliography entry over all entries satisfying the given condition for the given database, where the bibliography label is formatted according to §7.8; 548
Converts the formatted number to a plain number and stores the result in the control sequence . §2.2.2; 15
Expands to
Expands to the currency character associated with the currency identified by §2.6; 126
Expands to one of its arguments (§2.6; 130
Default currency format (initialised to use
Formats
Expands to the column alignment specifier used by
Expands to the ISO code associated with the default currency. §2.6; 127
Used by
Used by
Expands to the internal command used to store the default currency symbol. §2.6; 127
Defined by
The expansion text should be either empty (no rounding) or the number of decimal places that
This command should be redefined by the applicable localisation hook. The arguments should all be integers, but
This command should be redefined by the applicable localisation hook. The arguments should all be integers, but
This command should be redefined by the applicable localisation hook. The arguments should all be integers, but
This command should be redefined by the applicable localisation hook. The arguments should all be integers, but
This command should be redefined by the applicable localisation hook. The arguments should all be integers.
Used by
Used by
This command should be redefined by the applicable localisation hook.
Current locale word handler used by string sorting. §2.3.3; 46
Token register used to store the current row. Once set by commands such as
Euro currency EUR with symbol €. §2.6; 126
Separator used by currency formats. §2.6; 128
Used by
Defined by
Formats the currency with the symbol as a prefix using
Expands to the detokenised string associated with the currency identified by §2.6; 126
Formats the currency with the symbol as a suffix using
Expands to the symbol associated with the currency identified by §2.6; 126
Bitcoin currency XBT with symbol ₿. §2.6; 126
Generic currency XXX with symbol ¤. §2.6; 126
Used to position the legend with legend=custom. This command should be redefined as applicable. §6.3.3; 510
Expands to the name of the currency data type. §2.2.3; 18
Expands to the name of the date data type. §2.2.3; 18
Expands to the name of the datetime data type. §2.2.3; 18
Expands to the name of the decimal data type. §2.2.3; 18
Expands to the name of the integer data type. §2.2.3; 18
Expands to the name of an invalid data type identifier. §2.2.3; 18
Expands to the name of the string data type. §2.2.3; 18
Expands to the name of the time data type. §2.2.3; 18
Expands to the name of the unset data type. §2.2.3; 18
Used by
Used by
Expands to the currency symbol that was parsed by
Expands to an integer representing the data type that was parsed by
Expands to the numeric value that was parsed by
Only for use within the
Only for use within the
Only for use within the
Placeholder that expands to the current database name in certain contexts. §3.16.1; 368
Does
Does
Used at the start of a DTLTEX v3.0 and DBTEX v3.0 file to declare the database. §3.15.1.2; 339
Only for use within the
Only for use within the
Does
Only for use within the
Converts the plain number to a formatted currency using the supplied and stores the result in the control sequence . If the optional argument is omitted, the default currency symbol is used. §2.3.2; 46
Converts the plain number to a formatted number and stores the result in the control sequence . §2.3.2; 45
EUR currency formatting command. §2.6; 127
Expands to the default key prefix when column keys need to be automatically generated in
Word handler used by string sorting. §2.9.5.2; 165
Defines a new currency with associated ISO code, symbol and string equivalent. The optional argument indicates how the currency is formatted and defaults to
Deletes the database with the label §3.5; 235
Used by
Used to format group bar labels. §5.4.2; 442
Used by
Displays the database identified by tabular environment, omitting the columns listed by their label in . §3.7
Displays the database identified by tabular environment with = list of options. §3.7
Used by
Used by
Appends the item to the
Expands to the name of the environment used by
Used by
Used to format the inner label. §4.5; 391
Displays the database identified by longtable environment. §3.7; 242
Used by
Used by
Expands to the name of the environment used by
Used to format lower bar labels. §5.4.2; 441
Used to format lower bar labels for
Used to format the outer label. §4.5; 391
Used by
Used by
Provided for use with
Used to format upper bar labels. §5.4.2; 442
Used to format upper bar labels for
Expands to the tabular vertical alignment specifier used by
Calculates \(formatted numbers. The result will be a formatted number. §2.5.2; 110
Calculates \(plain numbers. §2.5.1; 99
Shortcut that does
For use in bar chart hooks, this will use
Locally sets the current text colour to that of the current pie segment. §4.6; 393
Locally sets the current colour (with
Similar to
Hook used within
For use in the definition of
English group string handler.
English locale word handler. §2.3.5; 61
Hook used by
Hook used by
Hook used by
Ensures that new values are expanded before being added to a database (equivalent to the new-value-expand=true option). Has no effect when loading dbtex files. §3.1; 179
Used during sorting when two sort values are identical. The original values, which may not be identical. This command should expand to , if the values should be swapped and otherwise. The default behaviour uses
Loops through the column identified by §3.16.2; 371
Loops through the column with the index §3.16.2; 371
Iterates over the database identified by and does . §3.8.2
Iterates over all rows in the given database using
Iterates over each column in the database identified by §3.16.2; 370
Iterates over each column in the current row of
A count register that keeps track of the current
Integer iteration from §3.16.2; 371
As
Formats the author’s name. §7.7.1; 539
Used by styles to format the list of author names (which will be obtained from the Author field). Each name is formatted according to
Designed for use within
Used by
Formats the date obtained from the
Formats the editor’s name. §7.7.1; 539
Used by styles to format the list of editor names (which will be obtained from the Editor field). Each name is formatted according to
Formats the forenames (with a leading space and updating conditionals). §7.7.1; 540
Outer formatting of the legend. §6.3.3; 510
Formats the supplied CSV list. The unstarred version adds grouping. §2.9.2; 151
Formats the name, omitting the forenames. §7.7.1; 540
As
As
As
As
Clears the database with the label §3.5; 236
As
Deletes the database with the label §3.5; 235
As
Gets the returned value from the last
Expands to the colour for the given index in the bar colour list or
Gets the index for the column labelled §3.6; 237
Sets the control sequence §3.6; 238
Expands to textual label associated with the data type §2.2.3; 18
Gets the value for the column identified by its index
Gets the value for the column identified by its index
Gets the initial letter of §2.8.2; 142
Gets the key for the column with the index §3.6; 238
Defines the control sequences §3.16; 366
Expands to the colour for the given index in the negative bar colour list or the default colour list if not set. This takes the negative-color-style setting into account. §5.4.3; 443
Expands to the current colour to that associated with the
Gets the row identified by the row index
As
Defines the control sequence §3.16; 366
As
Gets the element in the row identified by §3.16; 366
As
Used to encapsulate the long and short form in the Text field. §8.7; 602
Expands to the assignment list used by
Specific to
Separator used with
Used by
Separator between child entries for
Encapsulates the child entry’s name (including font and case-changing commands and post name hook). §8.8.1; 608
Expands to the counter to use for locations. §8.5.2; 599
Defined by
Specific to
Specific to the dict style, this is done at the end of each item. §8.8.2.5; 612
Enable hyperlinks, if supported. §8.9; 614
Inserted at the end of each item (after the location list, child list and cross references, if applicable). §8.8.1; 609
Fetches the value of the given column in the row identified by §8.5; 597
Used by
Used by
Used by
Encapsulates the description, if set. §8.8.1; 608
Used to format the “see” cross-reference list. §8.8.1; 609
Used to format the “see also” cross-reference list. §8.8.1; 609
Used by
Expands to the title corresponding to the given letter group. §8.8; 606
Normally simply expands to §8.4.1; 592
Used to display the location list, if applicable.
Normally simply expands to “Mac” in the sort value. §8.4.1; 591
Used to markup a person’s name. §8.4.1; 587
Used to apply the appropriate case change to the name. §8.8.1; 607
Used to apply the appropriate font change to the name. §8.8.1; 607
Used to markup a person’s ordinal (for a monarch etc). §8.4.1; 588
Used by
Used to markup a person’s office. §8.4.1; 589
Used to markup parenthetical material. §8.4.1; 591
Used to markup a surname with a particle. §8.4.1; 590
Used to markup a place. §8.4.1; 588
Hook inserted at the end of the list of child entries for
Inserted after the child name. §8.8.1; 608
Inserted after the description. §8.8.1; 608
Inserted after the location list. §8.8.1; 609
Inserted after the name. §8.8.1; 608
Inserted before the location list. §8.8.1; 609
Used to markup a person’s rank. §8.4.1; 590
Normally simply expands to “Saint” in the sort value. §8.4.1; 591
Used to format the
Sets the number of columns in the index. §8.8.1; 607
Sets the location compositor. §8.5.2; 600
Sets the default datagidx database name.
Expands to the command name without the leading backslash. §8.4.1; 592
Separator used with
Used to markup a subject. §8.4.1; 588
Separator between symbol and description if both are present. §8.8.1; 608
As
As
As
As
As
As
As
Globally creates a new database with the label §3.4; 232
As
As
As
As
As
As
Defined by
Used by
Compares
Used to fetch the name of the cross-reference label and display it in a hyperlink, if supported. §8.8.1; 609
Separator between final pair of items in cross-reference list. §8.8.1; 610
Separator used in all but final pair of items in cross-reference list. §8.8.1; 610
Does lowercase (disregarding punctuation and spaces) otherwise does . §2.4.1.2; 71
Does uppercase (disregarding punctuation and spaces) otherwise does . §2.4.1.2; 71
For use in
For use in
Parses the first argument §2.4.1.1; 64
Uses either
Does formatted number (not an integer or decimal) otherwise does . §2.4.1.1; 63
Does formatted number (not an integer or decimal) and has the given currency otherwise does . §2.4.1.1; 63
Uses either
May only be used within
Synonym of
Synonym of
Uses either
Tests if the database with the label §3.6; 237
Does CSV otherwise does . One level expansion performed on but not . §2.4.1.2; 69
Does formatted number (not a decimal or currency) otherwise does . §2.4.1.1; 62
Does plain number integers. §2.4.1.4; 84
Does plain number integers. §2.4.1.4; 83
May only be used within
Uses either
Expands to 3.10), or to otherwise. §3.10; 311
Expands to 3.10), or to otherwise. §3.10; 311
Does formatted numbers. §2.4.1.3; 82
Does plain numbers. §2.4.1.4; 83
Does formatted numbers. §2.4.1.3; 81
Does plain numbers. §2.4.1.4; 83
Does formatted number that’s an integer, decimal or currency) otherwise does . §2.4.1.1; 63
Does formatted numbers. §2.4.1.3; 81
Does plain numbers. §2.4.1.4; 83
Does formatted numbers. §2.4.1.3; 81
Does plain numbers. §2.4.1.4; 83
Does formatted numbers. §2.4.1.3; 81
Does plain numbers. §2.4.1.4; 83
May only be used within
Uses either
Does formatted number (not an integer or currency) otherwise does . §2.4.1.1; 63
Used by
Used by
Splits
Expands to the column alignment specifier used by
Used by
As the unstarred
As
As
As the unstarred
Synonym of
Synonym of
Synonym of
Synonym of
Synonym of
Synonym of
Synonym of
As the unstarred
As the starred
As the starred
As the starred
As the starred
As
As
As the starred
As
As
As
As the unstarred
As
As
As
As
Numerical “less than or equal to” for use in the conditional part of commands like
As
Numerical “less than or equal to” for use in the conditional part of commands like
As
As the unstarred
As
As
As
As
As
Defined by
Expands to the label of the last database to be loaded by
Dimension that specifies the gap between the border of the plot and the legend for the \(x\)-axis. §6.4.1; 516
Dimension that specifies the gap between the border of the plot and the legend for the \(y\)-axis. §6.4.1; 516
Used by
Letter order comparison that may be used in
Used in the default definition of
Formats an item within
Separator used between the final two elements in
Inserted before
Separator used between each item except for the final two within
Does
Loads a CSV/TSV file according to the current delimiter and separator and globally defines a database labelled . §3.15.3; 360
Inputs a dbtex file. §3.15.3; 359
Similar to
Loads a CSV/TSV file where TeX special characters should be interpreted literally according to the current delimiter and separator and globally defines a database labelled . §3.15.3; 360
Expands to the tikz option to use for the major grid line style. §6.4.3; 520
Iterates over each row in the given database and does
Breaks out of
For use within
For use within
Only for use within the
Breaks out of
Sets formatted numbers. The result will be a formatted number. §2.5.2; 113
Defines the control sequence plain numbers. §2.5.1; 100
Sets formatted numbers in the comma-separated . The result will be a formatted number. §2.5.2; 113
Sets plain numbers in the comma-separated . §2.5.1; 100
Determines the maximum value over all numeric values in the column with the label formatted number in the control sequence . §3.13; 324
Determines the maximum value over all numeric values in the listed columns in the given databases and stores the result as a formatted number in the control sequence . The optional arguments may be used to skip rows where the condition evaluates to false. §3.13; 323
Placeholder for use in
Placeholder for use in
Used within
Similar to
Sets formatted numbers in the comma-separated . The result will be a formatted number. §2.5.2; 113
Calculates the mean (average) of all the numbers in the comma-separated list plain numbers. §2.5.1; 101
Computes the mean (average) over all numeric values in the column with the label formatted number in the control sequence . §3.13; 322
Computes the mean (average) over all numeric values in the listed columns in the given databases and stores the result as a formatted number in the control sequence . The optional arguments may be used to skip rows where the condition evaluates to false. §3.13; 322
For use in the definition of
Sets formatted numbers. The result will be a formatted number. §2.5.2; 112
Defines the control sequence plain numbers. §2.5.1; 100
Sets formatted numbers in the comma-separated . The result will be a formatted number. §2.5.2; 113
Sets plain numbers in the comma-separated . §2.5.1; 100
Determines the minimum value over all numeric values in the column with the label formatted number in the control sequence . §3.13; 323
Determines the minimum value over all numeric values in the listed columns in the given databases and stores the result as a formatted number in the control sequence . The optional arguments may be used to skip rows where the condition evaluates to false. §3.13; 323
Dimension used to obtain the suggested minimum minor tick gap when not otherwise specified. §6.4.1; 516
Expands to the tikz option to use for the minor grid line style. If this is redefined to expand to nothing, the minor grid lines won’t be drawn. §6.4.3; 520
Dimension that specifies length of the minor tick marks. §6.4.1; 516
Dimension used to obtain the suggested minimum tick gap if not overridden by x-tick-gap or y-tick-gap or x-tick-points or y-tick-points. §6.4.1; 516
Placeholder for use in
Placeholder for use in
Formats the month name according to the current style. §7.3; 533
Calculates \(formatted numbers. The result will be a formatted number. §2.5.2; 110
Calculates \(plain numbers. §2.5.1; 99
Draws a multi-bar bar chart using data from the database identified by variables setting to identify the placeholder commands that will be assigned to the numeric values for the chart. §5; 396
Creates an auxiliary file for each name in the given §7.9; 548
Calculates the negative of the formatted number and stores the result as a formatted number in the control sequence . §2.5.2; 111
Defines the control sequence plain number. §2.5.1; 101
The maximum depth (negative) of the \(y\) axis or empty if the maximum depth in the data should be used. The expansion text must be either empty (for the default) or a decimal number less than or equal to 0. §5.4.1; 438
Intended for use in the bbl loaded by
As
Intended for use in the bbl loaded by
Creates a new database with the label global option, so this command is equivalent to
Adds an entry to the last row of the database identified by the label §3.4; 232
Adds a new row to the database identified by the label §3.4; 232
As
Prevents new values from being expanded when added to a database (equivalent to the new-value-expand=false option). Has no effect when loading dbtex files. Note that values can still be expanded with the
Used by
Used to represent a null value (see §3.10). Prior to version 3.0, this was defined by datatool rather than datatool-base. §3.10.2; 315
Used by
Used to represent a null value for a numeric column (see §3.10). Prior to version 3.0, this was defined by datatool rather than datatool-base. §3.10.2; 316
Compares formatted numbers or datum control sequences, and sets the count register (integer variable) to \(-1\) if is less than , to 0 if and are equal or to \(+1\) if is greater than . §2.9.5.1; 163
Used by
Counts the number of elements in §2.9.3; 153
Displays the plain number zero-padded to . This command is designed for sorting numbers by character code and so is expandable. Unlike
Inserted at the start of the expansion text of
Inserted at the start of the expansion text of
Robust command defined to do
Parses
Hook used by
Hook used by
Hook used at each segment of the pie chart. §4.7; 393
Draws a pie chart using data from the database identified by variable setting to identify the placeholder command included in that will be assigned to the numeric values for the chart. §4; 373
Expands to the colour name for the segment outline. §4.6; 393
Length register that stores the width of the segment outline. §4.6; 393
Placeholder command that may be used in inner or outer labels to show the percent value. §4.4; 390
Placeholder command that may be used in inner or outer labels to show the actual value. §4.4; 390
Plots the data from the listed databases as line or scatter diagrams. §6; 447
Hook used at the start of the tikzpicture environment within
Hook used at the end of the tikzpicture environment within
Used by both
Used to format \(x\) tick labels. §6.4.3; 519
Used to format \(y\) tick labels. §6.4.3; 519
Only for use within the
Dimension that controls the plot height. §6.4.1; 517
If there more than one database is supplied for the plot or if there is only a single x and y key, the legend will include this command to typeset the database name or a mapping that was previously provided with
If more than one database was specified, this command will be placed after
Provides a mapping from a database name to
Provides a mapping from a column key to
Provides a mapping from a column key to
Used by
If there are multiple keys listed in x, this command will be used to show both the \(x\) and \(y\) headers in the legend. §6.3.3; 513
If there are more than one column keys in x, this command will be used to separate the \(x\) label from the \(y\) label. The default definition is a slash with a space on either side. §6.3.3; 513
The legend will show the \(y\) text using this command if the y option had more than one key. The default definition is to show the header for the column identified by unless a mapping has been provided with
Expands to a comma-separated list of colour specifications for plot lines. §6.4.3; 517
Expands to a comma-separated list of plot line styles. §6.4.3; 518
Expands to a comma-separated list of colour specifications for plot marks. §6.4.3; 518
Expands to a comma-separated list of plot marks. §6.4.3; 518
Adds data from columns identified by pgf plot stream. §6.5; 520
Dimension that controls the plot width. §6.4.1; 517
Space inserted after
Space to insert after the §7.7.1; 540
Used by
Used by
Used by
Used by
Used by
Similar to
Appends a mapping used by the
Loads the data in §3.15.3; 359
Expands to the column alignment specifier used by
Used by
Recombines the database (identified by
As
Used in a DBTEX v3.0 file to construct the database. §3.15.1.3; 344
Used in experimental version of DBTEX v3.0 file to construct the database. This command has been replaced with
May only be used within the unstarred
May only be used within the unstarred
Locally removes the entry for the column identified by the index
May only be used within the unstarred
Replaces the entry for the column identified by the index
Resets all language (not region) sensitive commands back to their default definitions (but only those defined by datatool-base). Commands provided by supplementary packages are not affected. §2.3; 28
Resets all region sensitive commands back to their default definitions. §2.3; 28
Only available with
Only available with
Calculates the plain number. §2.5.1; 99
Rounds the formatted number to and stores the result as a formatted number in the control sequence . §2.5.2; 111
Rounds plain number. §2.5.1; 99
Expands to the row count of the database with the label §3.6; 237
Increments the counter DTLrow where is one more than
A count register used by various commands to keep track of a row number, which may be used by hooks. §3.16.1; 367
Increments DTLrow and resets the counter DTLrow where is one more than
Saves the given database as a CSV file. §3.15.4; 360
Saves the final loop index of the most recent
Saves the given database in its internal form. §3.15.4; 360
Saves the given database in DTLTEX v2.0 format. §3.15.4; 361
If siunitx is loaded, this will expand to
Sets formatted numbers in the comma-separated . The result will be a formatted number. §2.5.2; 114
Calculates the standard deviation of all the numbers in the comma-separated list plain numbers. If the mean value has already been computed, it can be supplied in the optional argument . If omitted, the mean will be calculated before calculating the standard deviation. §2.5.1; 101
Computes the standard deviation over all numeric values in the column with the label formatted number in the control sequence . §3.13; 323
Computes the standard deviation over all numeric values in the listed columns in the given databases and stores the result as a formatted number in the control sequence . The optional arguments may be used to skip rows where the condition evaluates to false. §3.13; 323
Sets the colour for the given index in the bar colour list. §5.4.3; 442
Sets the default currency. §2.3.2; 44
Sets the delimiter for CSV files to . §3.15.2; 352
Only available with
Defines
Sets the header for the column given by §3.6; 240
Set localisation options for all parent/module combinations. §2.3; 30
Sets the colour for the given index in the negative bar colour list. §5.4.3; 443
Sets the current number group character and decimal character. §2.3.2; 42
Assigns the colour for the §4.6; 392
Sets the separator for CSV files to . §3.15.2; 359
Sets the separator to the tab character in order to load TSV files and changes the category code for the tab character to 12 “other”. §3.15.2; 359
Set available options for all loaded packages in the datatool bundle. §2.1; 8
Uses
Sorts the rows of the database identified by §3.14.2; 334
Sorts a database according to the given criteria, which should be a §3.14.1; 325
Expands the actual (original) value from a sorted element obtained by
Expands the letter group from a sorted element obtained by
Expands the sort value from a sorted element obtained by
Case-sensitive letter handler for use in
Case-insensitive letter handler for use in
Sorts the given CSV list according to the command, which must take three arguments:
Case-sensitive word handler for use in
Globally adds
Case-insensitive word handler for use in
Sorts the CSV list stored in the command . The argument is a handler macro used to convert the original value into a byte sequence. The handler macro should be defined with the syntax
Ordinarily simply expands to
Calculates the square root of the formatted number and stores the result as a formatted number in the control sequence . §2.5.2; 111
Calculates the square root of plain number. §2.5.1; 99
For use in the definition of
Used by
Splits expand to the initials of each word. §2.8.2; 140
Expands to the column alignment specifier used by
Used by
Used to represent a null value for a string column (see §3.10). Prior to version 3.0, this was defined by datatool rather than datatool-base. §3.10.2; 316
Calculates \(formatted numbers. The result will be a formatted number. §2.5.2; 110
Calculates \(plain numbers. §2.5.1; 99
Substitutes the first occurrence of expansion text of the command . §2.8.1; 138
Substitutes all occurrences of expansion text of the command . §2.8.1; 139
Sums all numeric values in the column with the label formatted number in the control sequence . §3.13; 322
Sums over all numeric values in the listed columns in the given databases and stores the result as a formatted number in the control sequence . The optional arguments may be used to skip rows where the condition evaluates to false. §3.13; 321
Locally swaps the values in the columns identified by their index,
Swaps the rows identified by their index. No check is performed to determine if the database exists or if the indexes are in range. §3.16; 367
Hook provided by localisation files, in particular, the region hook control sequence name needs to be in this form for datatool-base to add it to the captions hook.
Used within temporal datum values to store both the numeric value and ISO format within the value part. §2.2.4; 21
By default this expands to expand to the second argument, ignoring the first, by commands like
Uses
Dimension that specifies the offset from the axis to the tick label. §6.4.1; 517
Dimension that specifies length of the tick marks. §6.4.1; 517
Used by
For use in the bar chart hooks with
For use in the bar chart hooks, this will expand to the total number of bars in the current bar chart. §5.4.4; 445
Truncates the formatted number to and stores the result as a formatted number in the control sequence . §2.5.2; 112
Truncates plain number. §2.5.1; 100
Used between the names where there are only two names in the list. §7.7.1; 542
Defined by
Appends the entry, as per
Uses the returned value from the last
Expands to the original value that was parsed by
Sets formatted numbers in the comma-separated . The result will be a formatted number. §2.5.2; 114
Calculates the variance of all the numbers in the comma-separated list plain numbers. If the mean value has already been computed, it can be supplied in the optional argument . If omitted, the mean will be calculated before calculating the variance. §2.5.1; 101
Computes the variance over all numeric values in the column with the label formatted number in the control sequence . §3.13; 322
Computes the variance over all numeric values in the listed columns in the given databases and stores the result as a formatted number in the control sequence . The optional arguments may be used to skip rows where the condition evaluates to false. §3.13; 322
Word order comparison that may be used in
Saves the data in the database identified by the
Expands to the tikz option to use for the \(x\)-axis line style. §6.4.3; 520
As
As
Expands to the tikz option to use for the \(y\)-axis line style. §6.4.3; 520
Locale-sensitive command provided if it hasn’t already been defined.
Locale-sensitive command provided if it hasn’t already been defined.
Locale-sensitive command provided if it hasn’t already been defined.
As
Locale-sensitive command provided if it hasn’t already been defined.
Prior to v3.0,
May be used in the
Placeholder in
Iterates over all labels in the given list and, at each iteration, sets §9.7.2; 653
Iterates through the list of people and, at each iteration, assigns
Breaks out of the people loops. §9.7.2; 653
As
As
Shortcut for
Shortcut for
Indexes the term identified by §8.5; 597
Indexes all the terms in the database identified by §8.5; 598
As
Displays the value of the given column in the row identified by §8.5; 597
Like
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Resets a term so that it’s marked as not used. §8.7.2; 605
Resets all terms in the given database. §8.7.2; 605
Shortcut for
Shortcut for
Unsets a term so that it’s marked as used. §8.7.2; 605
Unsets all terms in the given database. §8.7.2; 605
Comma separated list variable used to store the list of labels that may be used to identify the female gender. §9.4; 630
Comma separated list variable used to store the list of labels that may be used to identify the male gender. §9.4; 629
Placeholder in
If true, the \(x\) axis should be drawn on bar charts.
If true, the \(y\) axis should be drawn on bar charts.
If true, \(y\) ticks should be drawn on bar charts.
If true, the plot will be enclosed in a box. §6.4; 514
If true, a grid will be drawn. The minor grid lines will only be drawn if the corresponding minor tick mark setting is on. §6.4; 514
If true, create a new database when loading a CSV/TSV file. Use
If true, lines should be drawn. §6.4; 514
If true, markers should be drawn. §6.4; 515
If true, the bar charts will be drawn with vertical bars, otherwise they will be drawn with horizontal bars. §5.4.1; 437
If true, \(x\)-axis should be drawn. §6.4; 515
If true, the \(x\) minor ticks will be drawn. §6.4; 515
If true, the \(x\) ticks will be drawn. §6.4; 515
If true, the \(x\) ticks will be drawn inwards (if they should be drawn) otherwise they will be draw outwards. §6.4; 515
If true, \(y\)-axis should be drawn. §6.4; 515
If true, the \(y\) minor ticks will be drawn. §6.4; 515
If true, the \(y\) ticks will be drawn. §6.4; 516
If true, the \(y\) ticks will be drawn inwards (if they should be drawn) otherwise they will be draw outwards. §6.4; 516
Robust command that does §8.9.1; 615
Deprecated. Use
Deprecated. Use
Expandable command that does §8.9.1; 614
Placeholder in
Property list used by
Token list variable specifically for accessing values in the
Token list variable used to construct the legend. §6.3.2; 509
Property list used by
Token list variable specifically for accessing values in the
Property list used by
Token variable list specifically for accessing values in the
Integer variable that keeps track of the stream index (starting from 1). §6.3.2; 509
Integer variable used by
Integer variable used by
Expands to the string representation of the austral sign “
Expands to the symbol representation of the austral sign “
Expands to the string representation of the baht sign “
Expands to the symbol representation of the baht sign “
Expands to the string representation of the bitcoin sign “
Expands to the symbol representation of the bitcoin sign “
A token list variable assigned by the
Expands to the string representation of the cedi sign “
Expands to the symbol representation of the cedi sign “
Expands to the string representation of the cent sign “
Expands to the symbol representation of the cent sign “
Expands to the string representation of the colon sign “
Expands to the symbol representation of the colon sign “
A token list variable assigned by the
Expands to the string representation of the cruzerio sign “
Expands to the symbol representation of the cruzerio sign “
A regular expression that matches supported currency symbols. §2.3.1; 42
Expands to the string representation of the currency sign “
Expands to the symbol representation of the currency sign “
Each language file should ensure that the captions hook sets this token list variable to expand to the language’s ISO code. §2.3.5; 60
Each region file should ensure that the captions hook sets this token list variable to expand to the region’s ISO code.
Integer variable that corresponds to the
Integer variable set to the database row count divided by the value of
Expands to the string representation of the dong sign “
Expands to the symbol representation of the dong sign “
Expands to the string representation of the drachma sign “
Expands to the symbol representation of the drachma sign “
Expands to the string representation of the ecu sign “
Expands to the symbol representation of the ecu sign “
Expands to the string representation of the euro sign “
Expands to the symbol representation of the euro sign “
Expands to the string representation of the florin sign “
Expands to the symbol representation of the florin sign “
A token list variable assigned by the
Expands to the string representation of the French franc sign “
Expands to the symbol representation of the French franc sign “
Expands to the string representation of the Germany penny sign “
Expands to the symbol representation of the Germany penny sign “
Expands to the string representation of the guarani sign “
Expands to the symbol representation of the guarani sign “
Expands to the string representation of the hryvnia sign “
Expands to the symbol representation of the hryvnia sign “
A boolean variable corresponding to the inverse of the
Expands to the string representation of the Indian rupee sign “
Expands to the symbol representation of the Indian rupee sign “
Expands to the string representation of the kip sign “
Expands to the symbol representation of the kip sign “
A token list variable assigned by the
Expands to the string representation of the lari sign “
Expands to the symbol representation of the lari sign “
A token list variable assigned by the
Expands to the string representation of the lira sign “
Expands to the symbol representation of the lira sign “
Expands to the string representation of the livre tournois sign “
Expands to the symbol representation of the livre tournois sign “
Expands to the string representation of the manat sign “
Expands to the symbol representation of the manat sign “
Token list variable used by the measuring commands
Expands to the string representation of the middle dot (raised decimal point) “
Expands to the symbol representation of the middle dot (raised decimal point) “
Expands to the string representation of the mill sign “
Expands to the symbol representation of the mill sign “
Expands to the string representation of the naira sign “
Expands to the symbol representation of the naira sign “
Expands to the string representation of the Nordic mark sign “
Expands to the symbol representation of the Nordic mark sign “
Expands to the string representation of the peseta sign “
Expands to the symbol representation of the peseta sign “
Expands to the string representation of the peso sign “
Expands to the symbol representation of the peso sign “
A token list variable assigned by the
Expands to the string representation of the pound sign “
Expands to the symbol representation of the pound sign “
Boolean variable that corresponds to the
Boolean variable that corresponds to the
Expands to the string representation of the ruble sign “
Expands to the symbol representation of the ruble sign “
Expands to the string representation of the rupee sign “
Expands to the symbol representation of the rupee sign “
Expands to the string representation of the shekel sign “
Expands to the symbol representation of the shekel sign “
A token list variable assigned by the
Expands to the string representation of the som sign “
Expands to the symbol representation of the som sign “
Expands to the string representation of the spesmilo sign “
Expands to the symbol representation of the spesmilo sign “
A token list variable containing regular expression cases used by the
Expands to the string representation of the tenge sign “
Expands to the symbol representation of the tenge sign “
Expands to the string representation of the tugrik sign “
Expands to the symbol representation of the tugrik sign “
Expands to the string representation of the Turkish lira sign “
Expands to the symbol representation of the Turkish lira sign “
Expands to the string representation of the won sign “
Expands to the symbol representation of the won sign “
Expands to the string representation of the yen sign “
Expands to the symbol representation of the yen sign “
Loads a previously saved datagidx database. §8.3; 584
Placeholder in
Placeholder in
Placeholder in
Token list variable that expands to the current person label, which may be used in
Prior to v3.0,
Locale-sensitive command provided if it hasn’t already been defined.
Placeholder in
Shortcut that defines an abbreviation with
Defines a new index/glossary database. §8.2; 583
Defines a person identified by the given label. If omitted,
Defines a person identified by the given label. If omitted,
Defines a term with the given name. §8.4; 584
Defines a new column and associated option. §8.6; 600
Used by
Used by
Locale-sensitive command provided if it hasn’t already been defined.
Locale-sensitive command provided if it hasn’t already been defined. This command is defined by language packages, such as babel. §7.7.1; 542
Locale-sensitive command provided if it hasn’t already been defined. §7.7.1; 542
Placeholder in
Shortcut for
Shortcut for
As
Displays the relationship of the defined people to their collective parents. §9.5.0.2; 638
Displays all the defined people, showing the forenames for each person. §9.5.2; 642
Displays all the defined people, showing the full name for each person. §9.5.2; 642
Displays all the defined people, showing the name for each person. §9.5.2; 642
As
Displays the third person plural objective pronoun according to the gender of all defined people. §9.5.0.1; 635
As
Displays the second person plural objective pronoun according to the gender of all defined people. §9.5.0.1; 635
As
Displays the relationship of the defined people to their collective children. §9.5.0.2; 639
As
Displays the third person plural possessive adjective according to the gender of all defined people. §9.5.0.1; 636
As
Displays the second person plural possessive adjective according to the gender of all defined people. §9.5.0.1; 636
As
Displays the third person plural possessive pronoun according to the gender of all defined people. §9.5.0.1; 637
As
Displays the second person plural possessive pronoun according to the gender of all defined people. §9.5.0.1; 638
As
Displays the third person plural subjective pronoun according to the gender of all defined people. §9.5.0.1; 634
As
Displays the second person plural subjective pronoun according to the gender of all defined people. §9.5.0.1; 634
As
Displays the relationship of the defined people to their collective siblings. §9.5.0.2; 639
Displays all the defined people, showing the surname for each person. §9.5.2; 642
Displays all the defined people, showing the title and surname for each person. §9.5.2; 642
Adds the given label (after expansion) to the list of labels that may be used to identify the female gender.
Adds the given label (after expansion) to the list of labels that may be used to identify the male gender.
Adds the given label (after expansion) to the list of labels that may be used to identify the non-binary gender.
As
Displays the person’s relationship to their parents. §9.5.0.2; 638
Expands to the number of female people who have been defined. §9.4; 631
Displays the person’s forenames. If the label is omitted, anon is assumed. §9.5.1; 640
Displays the person’s full name. If the label is omitted, anon is assumed. §9.5.1; 639
As
Displays the person’s gender using localisation. §9.5.1; 640
As
As
Compares the given token list variable (using
As
Expands to the value of the attribute for the given person. No test is made to determine if the person exists or if the attribute is valid. §9.7; 650
Sets the token list variable §9.7; 650
Does
Does
Does
Does
Tests if a person has been defined with the given label. §9.7.1; 651
As
Uses the plural form of the localisation text (
As
Expands to the localisation text for the given §9.7.3; 655
Separator to use between the last pair of people in a list that contains more that two people. §9.5.2; 641
Expands to the number of male people who have been defined. §9.4; 631
Displays the person’s name. If the label is omitted, anon is assumed. §9.5.1; 640
Append
Append
Expands to the number of non-binary people who have been defined. §9.4; 631
As
Displays the third person singular objective pronoun according to the gender of the person identified by the label. §9.5.0.1; 634
As
Displays the second person singular objective pronoun according to the gender of the person identified by the label. §9.5.0.1; 635
As
Displays the person’s relationship to their child. §9.5.0.2; 638
As
Displays the third person singular possessive adjective according to the gender of the person identified by the label. §9.5.0.1; 636
As
Displays the second person singular possessive adjective according to the gender of the person identified by the label. §9.5.0.1; 636
As
Displays the third person singular possessive pronoun according to the gender of the person identified by the label. §9.5.0.1; 637
As
Displays the second person singular possessive pronoun according to the gender of the person identified by the label. §9.5.0.1; 637
As
Displays the third person singular subjective pronoun according to the gender of the person identified by the label. §9.5.0.1; 632
As
Displays the second person singular subjective pronoun according to the gender of the person identified by the label. §9.5.0.1; 634
Append
Separator to use between all but the last pair of people in a list. §9.5.2; 641
Sets the attribute for the given person to local setting). No test is made to determine if the person exists or if the attribute is valid. §9.7; 649
Sets the list of labels that may be used to identify the female gender. §9.4; 630
Sets the localisation text for the given gender label (which must be one of the internal labels male, female, nonbinary or unknown) for the given . §9.7.3; 653
Sets the list of labels that may be used to identify the male gender. §9.4; 629
Sets the list of labels that may be used to identify the non-binary gender. §9.4; 630
As
Displays the person’s relationship to their siblings. §9.5.0.2; 639
Displays the person’s surname. If the label is omitted, anon is assumed. §9.5.1; 640
Displays the person’s title and surname. If the label is omitted, anon is assumed. §9.5.1; 640
The separator between a person’s title and surname. §9.5.1; 640
Expands to the number of people who have been defined. §9.3; 628
Expands to the number of people who have been defined with the gender set to unknown. §9.4; 632
Undefines the attribute for the given person to local setting). No test is made to determine if the person exists or if the attribute name is valid. §9.7; 650
Placeholder in
A hook used at the end of
Displays index/glossary according to the given options. §8.8; 605
Used to restore one column if
Removes all defined people. §9.3; 629
Removes each person identified by their label in the given comma-separated list. §9.3; 629
Removes (undefines) the person identified by anon. §9.3; 628
Placeholder in
Placeholder in
If not already defined, this will be defined to
Placeholder in
Placeholder in
Shortcut for
Shortcut for
Placeholder in
Placeholder in
Locale-sensitive command provided if it hasn’t already been defined.
Placeholder in
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Separator to use in a list of two people. §9.5.2; 641
Placeholder in
As
As
Displays the value of the given column in the row identified by
As
As
As
Locale-sensitive command provided if it hasn’t already been defined.
As
Expands the first token in
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Shortcut for
Environment alternative to
Environment alternative to
Environment form of
Environment form of
Does
Formats the bibliography (using thebibliography) according to the current style.
Initialises the default colour list to: red, green, blue, yellow, magenta, cyan, orange, white. §5.1; 402
Initialises the default colour list to shades of grey. §5.1; 402
Equivalent to verticalbars=false. §5.1; 402
Equivalent to verticalbars=true. §5.1; 402
If true, the bars will be vertical, otherwise they will be horizontal. §5.1; 402
If true, bibtex will be run via the shell escape. §7.1; 523
Sets the bibliography style to plain, abbrv or alpha. §7.1; 523
Sets child style, where the value may be named or noname. §8.1.1.2; 575
Sets the number of columns. §8.1.1.2; 575
Sets the location compositor. §8.1.1.1; 575
Sets the location counter. §8.1.1.1; 575
Switches on draft mode. §8.1.1.1; 575
Switches off draft mode (default). §8.1.1.1; 575
Sets the location list style, where the value may be one of: hide, list or first. §8.1.1.2; 576
Sets name case style, where the value may be nochange, uc, lc, firstuc or capitalise. §8.1.1.2; 576
If true, switch off datagidx warnings. §8.1.1.1; 575
Sets the optimization mode. §8.1.1.1; 574
Highest level of optimization. 614
Some optimization. 614
No optimization. 613
Sets the post-description style, where the value may be one of: none or dot. §8.1.1.2; 576
Sets the code to insert after the name. §8.1.1.2; 576
Sets the style of the pre-location content, where the value may be none, enspace, space, dotfill or hfill. §8.1.1.2; 576
Sets the “see” style, where the value may be one of: comma, brackets, dot, space, nosep, semicolon, or location. §8.1.1.2; 576
Sets the symbol-description style, where the value may be one of: symbol, desc, (symbol) desc, desc (symbol), symbol desc, or desc symbol. §8.1.1.2; 576
Initialises the default colour list to: red, green, blue, yellow, magenta, cyan, orange, white. §4.1; 376
Initialises the default colour list to shades of grey. §4.1; 376
Don’t rotate inner labels. §4.1; 376
Don’t rotate outer labels. §4.1; 376
Rotate inner labels. §4.1; 376
Rotate outer labels. §4.1; 376
If false, suppresses localisation warnings (and also switches off tracklang warnings). If true, enables localisation warnings without affecting tracklang’s warning setting. §2.1; 9
Synonym of locales.
Adds each locale to the list of tracked languages (using
Determines which processor should be used for mathematical functions. The default is l3fp unless
Use fp commands for floating point arithmetic. 9
Use LaTeX3 commands for floating point arithmetic. 8
Use
Use pgfmath commands for floating point arithmetic. 9
Prevent localisation support from being loaded, even if the required localisation files are installed. §2.1; 9
The delimiter character in CSV files. §3.1; 177
The separator character in CSV files. §3.1; 181
Only load datatool-base, not datatool. §9.1; 625
Define shortcut commands. §9.1; 625
List of Figures[link]
List of Tables[link]
List of Examples[link]
texdoc -l datatool-user-example
where is the example number zero-padded to three digits to find out if the example files are installed on your device.
1. Introduction[link]
See §2.
Database commands are described in §3.
See §4.
See §5.
\directlua
is defined, or
l3fp otherwise. To avoid repeated parsing, some
functions, such as the aggregate functions
(§3.13) or charts
(§§4, 6 & 5), will use LaTeX3
commands regardless of the math option.
1.1. Rollback[link]
\usepackage
{datatool}[=v2.32]
1.2. LaTeX3[link]
\ExplSyntaxOn
)
before defining commands that use them and then switched off
(\ExplSyntaxOff
) afterwards. Spaces are ignored, so you
need to use ~
if an actual space is required.
Further information can be found in the interface3.pdf
document:
texdoc interface3
1.2.1. Regular Expressions[link]
\emph{boo}
with
\textbf{BOO}
. More generally, the custom command
searches for any instance of \emph{ }
, where
consists of one or more word characters
(
), and replaces it with
\w
+\textbf{ }
, where the argument is the original
converted to uppercase using \text_uppercase:n
.
\documentclass
{article}
\ExplSyntaxOn
\NewDocumentCommand
{\testreplace
} { m }
{
\regex_replace_all:nnN
{ \c
{emph} \cB
\{ (\w
+) \cE
\} }
{ \c
{textbf} { \c
{text_uppercase:n}{ \1
} } }
#1
}
\ExplSyntaxOff
\begin{document}
\newcommand
{\teststring
}{The duck said \emph
{boo} to the goose.}
Original: \teststring
\testreplace
{\teststring
}
Replaced: \teststring
\end{document}
1.2.2. Comma-Separated Lists[link]
\documentclass
{article}
\ExplSyntaxOn
\clist_new:N
\l_my_clist
\NewDocumentCommand
\createmylist
{ m }
{
\clist_set:Nn
\l_my_clist
{ #1 }
}
\NewDocumentCommand
\mylistelement
{ m }
{
\clist_item:Nn
\l_my_clist
{ #1 }
}
\NewDocumentCommand
\reversemylist
{ }
{
\clist_reverse:N
\l_my_clist
}
\NewDocumentCommand
\displaymylist
{ }
{
\clist_use:Nnnn
\l_my_clist
{~
and~
} { ,~
} { ,~
and~
}
}
\ExplSyntaxOff
\begin{document}
\createmylist
{ant,duck,goose,zebra}
\displaymylist
Second element: \mylistelement
{2}.
\reversemylist
\displaymylist
Second element: \mylistelement
{2}.
\end{document}
1.2.3. Calculations[link]
If you plan on re-parsing commands such as the example \documentclass
{article}
\ExplSyntaxOn
\newcommand
{\myfunc
} [3]
{
\fp_to_decimal:n
{ #1 + 0.5 * sqrt(#2) / (#3) }
}
\ExplSyntaxOff
\newcommand
{\numA
}{1023.5}
\newcommand
{\numB
}{54.75000}
\newcommand
{\numC
}{-20648.68}
\begin{document}
$ \numA
+\frac
{\sqrt
{\numB
}}{2\times
\numC
} =
\myfunc
{\numA
}{\numB
}{\numC
} $
\end{document}
\numA
,
\numB
and \numC
commands, then it would be better to
convert them to LaTeX3 floating point variables or constants.
See the LaTeX3 Interfaces document for further details.
\directlua
, which requires LuaLaTeX:
\newcommand
{\myfunc
}[3]{%
\directlua
{tex.print(#1+0.5*math.sqrt(#2)/(#3))}%
}
2. Base Commands (datatool-base package)[link]
2.1. datatool-base Options[link]
\DTLsetLocaleOptions
,
see §2.3.)
\DTLsetup
, and identifies the required maths processor. This determines
how the floating point commands described in §2.5
are defined. The value may be one of the following.
\dtladd
) to use LaTeX3 commands.
This is the default setting unless LuaLaTeX is used.
\dtladd
) to use \directlua
to perform the
mathematical calculations. This is the default setting if LuaLaTeX is used.
\dtladd
) to use the fp package commands to perform the
mathematical calculations. (Automatically loads the fp
package.) Note that the fp package can be less precise than
LaTeX3 or Lua. (See Examples 37, 39 & 38.)
\dtladd
) to use the pgfmath package commands to perform the
mathematical calculations. (Automatically loads the pgfmath
package.) Note that the pgfmath package has limitations and
may produce the error:
! Dimension too large
This option is maintained for backward-compatibility but, in
general, the new default l3fp or lua
options are better.
\DTLsetup
.
If false, this setting switches off localisation warnings. Note that
this will also switch off tracklang warnings. If true, this
setting will switch on datatool-base localisation warnings
without altering tracklang warnings. If you need
tracklang warnings to be switched back on again for the next
package that requires it, use \TrackLangShowWarningstrue
.
\DTLsetup
, and has no value. If used it will prevent any localisation
files from being loaded, regardless of the document language
settings. This option will override locales (and lang).
See §2.3.
\DTLsetup
. It counteracts the effect of nolocale and
tracks each listed language tag using tracklang’s
\TrackLanguageTag
. Note that localisation support must be
installed separately. See §2.3.
\DTLGetInitialLetter
before parsing.
auto-reformat
numeric option
or auto-reformat
datetime option is on.
auto-reformat
numeric option
or auto-reformat
datetime option.
It simply establishes which data types should be affected when the
applicable option is on.
In the above, if \DTLsetup
{
auto-reformat-types={decimal,si,datetime},
numeric={auto-reformat
},
datetime={parse
=auto-reformat}
}
\DTLparse
identifies a decimal or SI notation
(but not an integer) or a datetime (but not a date or a time)
then the string value will be automatically reformatted.
auto-reformat
numeric option will have no effect.
Similarly,
if auto-reformat-types is missing all temporal types, then
the auto-reformat
datetime option will have no effect.
\DTLparse
should also try parsing for timestamps (date and time), dates (no
time) or times (no date). The temporal data types were only added to
datatool-base version 3.0 and are still experimental so
this feature is off by default. The value should be a = list
of options, which are described in §2.7.
2.2. Data Types[link]
,
) but may be
changed using \DTLsetnumberchars
. Examples: 1,234 (which has
the default number group character) and 1234 (which is also a
plain number) but not 1234.0 (which is a decimal). A double sign (such as
++1234
or -+1234
) isn’t permitted and will be treated
as a string.
1e+4
instead of 1000) then it will be identified as a decimal not an integer.
Otherwise, a large integer will be considered a string (otherwise it
will trip TeX’s integer limit).
decimal point
” by default. The number group and decimal
characters may be changed using \DTLsetnumberchars
.
Examples: 1,234.0 (which has the default number group character and
decimal character), 1234.0 (which is also a plain number)
but not 1234 (which is an integer). A double sign (such as
++1234.0
or -+1234.0
) isn’t permitted and will be treated
as a string.
2.5e+10
or
1E-5
is supported. Note that the locale symbols aren’t
supported when parsing for scientific notation. The format should be
or
E
. A space may occur between
the mantissa and the E/e. The exponent must be an integer. The
mantissa may include a edecimal point.
If the
auto-reformat
setting is on, parsed scientific
notation will have the value encapsulated with \DTLscinum
.
,
\DTLcurrency
{ }\DTLfmtcurrency
{ }{ }
or \DTLfmtcurr
{ }{ } where is a recognised
currency symbol (identified with
\DTLnewcurrencysymbol
)
and is an integer or decimal using the current
number group character and decimal character (not scientific notation).
The sign may occur before the currency symbol.
Some regional localisation files will also recognise currency where
the symbol is prefixed with the region’s code.
$1,234.56
and
(which both have a recognised currency symbol) and
\pounds
1234
or
\DTLfmtcurrency
{£}1,234
(which both use
known currency formatting commands) but not “\DTLcurrency
{1,234.00}1,234 USD
”
(which doesn’t fit the recognised format). Both
-
and \pounds
1234
are recognised
as a currency with a negative numeric value.
\pounds
-1234
will also be recognised as currency (although it requires
the datatool-GB.ldf region file to be loaded in order to correctly format
the value). If datatool-GB.ldf has been loaded, then \DTLfmtcurr
{GBP}1,234GB£1,234
will
also be recognised. However, if, say, datatool-IE.ldf has been loaded,
then IE€1,234
won’t be recognised as that region
doesn’t support a currency prefix.
See §2.6.
parse
)
and converted into a numerical form so that they can be
treated as numbers.
1.Dates are in the form
where - - is the year, is the two digit month
and is the two digit day. The numeric value is the integer
JDN.
2.Times are in the form
or : :
where : is the two digit 24
hour, is the two digit minute, and is the two
digit second (“00” if omitted). The numeric value is the JF.
3.Timestamps include both a date and time. If the time zone is
missing, UTC+0 is assumed. Recognised formats:
Where - - T : : :
- - T : : Z
- - T : :
is the time zone hour and is the time
zone minute.
A space may also be used instead of “T” as the separator between
the date and time. The corresponding numeric value is the JD,
which is the integer JDN plus the fractional JF.
\c_novalue_tl
but uses a
different internal marker. See §3.10 for further
details.
2.2.1. Numeric Options[link]
\DTLsetup
{
numeric={
auto-reformat
,
region-currency-prefix
=smallcaps
}
}
\DTLparse
should reformat the string part for integers, decimals and currency.
(According to the auto-reformat-types setting.)
\num
otherwise it will simply expand to its argument.
\DTLfmtcurr
, if the
associated currency code can be determined, or to
\DTLfmtcurrency
otherwise.
\datatool
SetCurrency which checks this boolean
value before setting the default currency.
\DTLcurrCodeOrSymOrChar
to expand
to its first argument (iso) or second argument
(symbol) or third argument (string).
However, unlike \DTLsetdefaultcurrency
{ }
\DTLsetup
{region-currency
=false}
\DTLsetdefaultcurrency
the value
must be a defined currency code.
\datatoolcurrencysymbolprefixfmt
. Allows values are:
normal (redefines to expand to its argument),
smallcaps (redefines to expand to use \textsc
with
the argument converted to lowercase), or smaller (redefines
to use \textsmaller
, which will require the relsize
package).
2.2.2. Parsing Locale-Formatted Numbers and Currency Values[link]
\DTLsetnumberchars
and the currency symbol has been declared
with \DTLdefcurrency
(typically by loading a region file
via locales or the document language support). If you want to format a
plain number, you can use \DTLdecimaltolocale
or
\DTLdecimaltocurrency
, described in
§2.3, or use siunitx.
\DTLconverttodecimal
is internally used by commands like
\DTLadd
to obtain the numerical value. The result is then
converted back to a formatted number using either
\DTLdecimaltolocale
or \DTLdecimaltocurrency
, depending on
the data type of the supplied arguments.
The result is a datum control sequence to reduce the need for re-parsing.
This will define \DTLconverttodecimal
{\$1,234.50}{\myNum
}
\myName
to expand to 1234.50
(assuming
the default number group character and decimal character).
Again, the result is a datum control sequence to reduce the need for re-parsing.
2.2.3. Datum Commands[link]
\DTLparse
but fully expands before parsing.
\DTLxparse
), the data
type, the numerical value (if one of the numerical types), and the
currency symbol (if applicable).
auto-reformat
}).
\DTLmapgetvalues
, then that command will be a
datum control sequence in the same format as that obtained with
\DTLparse
.
\DTLxparse
, or the reformatted string value, if
the applicable option was in effect). You can also simply use the
datum control sequence. The difference is that \DTLusedatum
can fully
expand the datum value whereas using the datum control sequence
directly won’t.
If is \dtlnovalue
, then
will expand to \DTLusedatum
{ }\dtlnovalue
.
\dtlnovalue
, then
will
expand to \DTLdatumvalue
{ }\DTLnumbernull
.
\dtlnovalue
, then
will expand to \DTLdatumcurrency
{ }\dtlnovalue
.
0
(string),
1
(integer), 2
(decimal), 3
(currency),
4
(timestamp), 5
(date), 6
(time) or
-1
(unknown). If is \dtlnovalue
,
then
will expand to the unknown data type value.
\DTLdatumtype
{ }\DTLparse
\mydatum
{1,234.0}
Data type: \DTLdatumtype
{\mydatum
}.
\DTLdatumtype
will convert
the constant value to an integer denotation.
If you want the actual constant, use:
but there’s no check for \exp_args:NV
\datatool_datum_type:Nnnnn
\dtlnovalue
in this case.
\DTLdatatypeunsetname
,
\DTLdatatypestringname
,
\DTLdatatypeintegername
,
\DTLdatatypedecimalname
,
\DTLdatatypecurrencyname
,
\DTLdatatypedatetimename
,
\DTLdatatypedatename
,
\DTLdatatypetimename
, or
\DTLdatatypeinvalidname
.
\DTLsetfpdatum
performs any parsing.
\DTLsetintegerdatum
but expands and
.
\DTLsetdecimaldatum
but expands and
.
\DTLsetdecimaldatum
but this will expand and parse
and store it with the \datatool_datum_fp:nnn
markup.
\DTLsetcurrencydatum
but expands ,
and .
\DTLsetstringdatum
but expands .
\DTLadd
, as demonstrated in
\usepackage
{datatool-base}
\usepackage
{siunitx}
\DTLparse
{\numA
}{23,452}
\DTLparse
{\numB
}{45.0}
\DTLparse
{\numC
}{\pounds
24.50}
\DTLsetfpdatum
{\numD
}{\num
{1.5e-4}}{1.5e-4}
\begin{document}
Original value: \DTLusedatum
{\numC
} or \numC
.
Numeric value: \DTLdatumvalue
{\numC
}.
Currency: \DTLdatumcurrency
{\numC
}.
Data type: \number
\DTLdatumtype
{\numC
}.
\DTLadd
{\result
}{\numA
}{\numB
}
$\numA
+ \numB
= \result
$
\DTLaddall
{\result
}{\numA
,\numB
,\numC
}
$\numA
+ \numB
+ \numC
= \result
$
\dtladd
{\result
}{\DTLdatumvalue
{\numA
}}{\DTLdatumvalue
{\numB
}}
$\DTLdatumvalue
{\numA
} + \DTLdatumvalue
{\numB
} = \result
$
\dtladdall
{\result
}
{\DTLdatumvalue
{\numA
},\DTLdatumvalue
{\numB
},\DTLdatumvalue
{\numC
}}
$\DTLdatumvalue
{\numA
} + \DTLdatumvalue
{\numB
}
+ \DTLdatumvalue
{\numC
} = \result
$
\DTLxsetdecimaldatum
{\total
}{\num
{\result
}}{\result
}
Total: \total
.
\dtlmul
{\result
}{20}{\DTLdatumvalue
{\numD
}}
$20 \times
\numD
= \result
$
\end{document}
2.2.4. Datum Items (Advanced)[link]
{ }{ }{ }{ }
\datatool_set_fp:Nn
) without
having to reparse the value.
\DTLtemporalvalue
and then
expanding
. If the
part in is just a number and not
encapsulated within \DTLtemporalvalue
{ }\DTLtemporalvalue
then this trick won’t
work and the number will need to be converted back.
The result will be empty if there is no date/time information.
\datatool_if_number_only_datum_type:nTF
{ } { } { }\datatool_if_number_only_datum_type_p:n
{ } { } { }2.2.4.1. Datum Components[link]
2.2.4.2. Datum Tests for Equality[link]
\tl_if_eq:NnTF
or \ifdefstring
as
the datum markup will prevent a match. Commands such as
\DTLifstringeq
expand the arguments which will remove the datum
markup, but the following commands take the data type into account.
The following \DTLparse
{\Fruit
}{Pear}
\DTLparse
{\Price
}{\$1.50}
\DTLparse
{\Quantity
}{10}
\OtherPrice
is numerically equivalent to \Price
and has the same currency symbol but the string representation is different:
Similarly, the following \DTLsetcurrencydatum
{\OtherPrice
}{1 dollar 50\textcent
}{1.5}{\$}
\OtherQuantity
has the same
numerical value as \Quantity
but it’s a decimal instead of an
integer:
For convenience a command is provided for the tests:
\DTLsetdecimaldatum
{\OtherQuantity
}{10.00}{10.0}
The actual tests need to have LaTeX3 syntax enabled:
\newcommand
{\test
}[3]{#1=#2 (\texttt
{\string
#3}) ?
#3{#1}{#2}{true}{false}.\par
}
First are the string tests:
\ExplSyntaxOn
The next set may appear to be numeric tests but they are still string
tests because they are being compared with a non-datum token list.
\test
\Fruit
{Pear} \tl_if_eq:NnTF
\test
\Fruit
{Pear} \tl_if_eq:enTF
\test
\Fruit
{Pear} \datatool_if_value_eq:NnTF
For an actual numeric test, both arguments must use the datum
format. Note that \test
\Price
{\$1.50} \tl_if_eq:NnTF
\test
\Price
{\$1.50} \tl_if_eq:enTF
\test
\Price
{\$1.50} \datatool_if_value_eq:NnTF
\test
\Price
{\$1.5} \datatool_if_value_eq:NnTF
\Price
and \OtherPrice
are
numerically equivalent but when viewed as token list variables, they
don’t have the same content.
There are similar tests for the quantity:
\test
\Price
\OtherPrice
\tl_if_eq:NNTF
\test
\Price
\OtherPrice
\datatool_if_value_eq:NNTF
\test
\Quantity
{10} \tl_if_eq:NnTF
\test
\Quantity
{10} \tl_if_eq:enTF
\test
\Quantity
{10} \datatool_if_value_eq:NnTF
\test
\Quantity
{10.00} \datatool_if_value_eq:NnTF
\test
\Quantity
\OtherQuantity
\tl_if_eq:NNTF
\test
\Quantity
\OtherQuantity
\datatool_if_value_eq:NNTF
2.2.4.3. Conversion to Floating Point[link]
\usepackage
{datatool-base}
\usepackage
{siunitx}
\DTLparse
{\numA
}{1,500.0}
\DTLsetfpdatum
{\numB
}{\num
{1.5e-4}}{1.5e-4}
\begin{document}
A = \numA
\space
(value: \DTLdatumvalue
\numA
).
B = \numB
\space
(value: \DTLdatumvalue
\numB
).
\ExplSyntaxOn
\datatool_set_fp:Nn
\l_tmpa_fp
{ \numA
}
\datatool_set_fp:Nn
\l_tmpb_fp
{ \numB
}
\fp_to_tl:N
\l_tmpa_fp
\c_space_tl
\texttimes
\c_space_tl
\fp_to_tl:N
\l_tmpb_fp
\c_space_tl
= \c_space_tl
\fp_eval:n
{ \l_tmpa_fp
* \l_tmpb_fp
}
\ExplSyntaxOff
\end{document}
2.3. Localisation[link]
or load babel/polyglossia and setup language
support before the first package to load tracklang, for example:
\documentclass
[british]{article}
or use datatool-base’s locales (or lang) option, for example:
\usepackage
[british]{babel}
\usepackage
{datatool-base}
If you use \usepackage
[locales=en-GB]{datatool-base}
\babelprovide
, ensure that you have at least
version 1.6.4 of tracklang and load tracklang after all
instances of \babelprovide
. There’s no support for
“lazy loading” in the document environment.
See the tracklang documentation or
Localisation with
tracklang.tex for further details.
\usepackage
[en-GB]{datetime2}
\usepackage
{datatool-base}
\l_datatool_current_region_tl
and reset
the current number group character and decimal character and currency
in addition to redefining commands such as
\DTLCurrentLocaleCurrencyDP
.
\l_datatool_current_language_tl
in addition to redefining commands such as
\DTLandname
, but only for the datatool-base set of
commands. Additional commands provided for the supplementary
packages are not affected.
The above example shows the default currency code “CAD”, which
has been set by datatool-CA.ldf. The sorted list has “élite” between
“elephant” and “elk” because datatool-english.ldf has enabled support
for common UTF-8 characters so that “é” is treated as “e”
for sorting purposes.
\usepackage
[locales=en-CA]{datatool-base}
\begin{document}
Default currency: \DTLCurrencyCode
.
\newcommand
{\mylist
}{elk,élite,elephant}
\DTLsortwordlist
{\mylist
}{\DTLsortletterhandler
}
Sorted list: \DTLformatlist
{\mylist
}.
\end{document}
In this case, the datatool-CA.ldf file is found, so the default currency
code is still CAD but no file is found to provide support for the
sorting handler so the extended Latin character “é” is placed after
the Basic Latin characters.
\usepackage
[canadien]{babel}
\usepackage
{datatool-base}
\begin{document}
Default currency: \DTLCurrencyCode
.
\newcommand
{\mylist
}{elk,élite,elephant}
\DTLsortwordlist
{\mylist
}{\DTLsortletterhandler
}
Sorted list: \DTLformatlist
{\mylist
}.
\end{document}
However, ensure that you have at least version 1.6.4 of
tracklang.
\usepackage
{babel}
\babelprovide
{canadianfrench}
\usepackage
{datatool-base}
\datatoollocaledefinekeys:nn
This is simply a shortcut that uses \keys_define:nn
. The
should be the applicable language code (for example,
“en”) or region code (for example, “GB”) or tag (for example,
“en-CA” or “fr-CA”), depending on what kind of support the
file provides. Sub-modules may also be specified.
.
If the optional argument is omitted or empty, this iterates over
each locale module and sets the given options.
/
Another example, both datatool-GB.ldf and datatool-CA.ldf support a currency
symbol prefix so the setting can be switched on for both at the same
time:
\DTLsetLocaleOptions
{GB}{number-style=education}
\DTLsetLocaleOptions
{CA,GB}{currency-symbol-prefix}
Or:
\DTLsetLocaleOptions
[en]{databib}{short-month-style=dotless}
\DTLsetLocaleOptions
{en/databib}{short-month-style=dotless}
\datatoolsetlocaleoptions:nn
This iterates over each module and sets the provided options using
\keys_set:nn
, which will trigger an error
for unknown options.
\datatoolsetlocaleoptions:nn
This iterates over each module and sets the provided options using
\keys_set_known:nn
, which won’t trigger an error
for unknown options.
datatool / locale /
”.
2.3.1. Encoding[link]
\DTLdefcurrency
may not be correct.
This means that the region ldf file doesn’t need to keep track
of the encoding. (The language ldf typically does.)
\datatool_def_currency:nnnV
{ \datatoolGBcurrencyfmt
}
{ GBP }
{ \pounds
}
\l_datatool_pound_tl
”, if supported by the current encoding, or “
c
” otherwise..
”, if supported by the current encoding, or “
c
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
#
” otherwise..
”, if supported by the current encoding, or “
#
” otherwise..
”, if supported by the current encoding, or “
Y
” otherwise..
”, if supported by the current encoding, or “
Y
” otherwise..
”, if supported by the current encoding, or “
.
” otherwise..
”, if supported by the current encoding, or “
.
” otherwise..
”, if supported by the current encoding, or “
f
” otherwise..
”, if supported by the current encoding, or “
f
” otherwise..
”, if supported by the current encoding, or “
B
” otherwise..
”, if supported by the current encoding, or “
B
” otherwise..
”, if supported by the current encoding, or “
CE
” otherwise..
”, if supported by the current encoding, or “
CE
” otherwise..
”, if supported by the current encoding, or “
C
” otherwise..
”, if supported by the current encoding, or “
C
” otherwise..
”, if supported by the current encoding, or “
Cr
” otherwise..
”, if supported by the current encoding, or “
Cr
” otherwise..
”, if supported by the current encoding, or “
F
” otherwise..
”, if supported by the current encoding, or “
F
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
m
” otherwise..
”, if supported by the current encoding, or “
m
” otherwise..
”, if supported by the current encoding, or “
N
” otherwise..
”, if supported by the current encoding, or “
N
” otherwise..
”, if supported by the current encoding, or “
Pts
” otherwise..
”, if supported by the current encoding, or “
Pts
” otherwise..
”, if supported by the current encoding, or “
Rs
” otherwise..
”, if supported by the current encoding, or “
Rs
” otherwise..
”, if supported by the current encoding, or “
W
” otherwise..
”, if supported by the current encoding, or “
W
” otherwise..
”, if supported by the current encoding, or “
S
” otherwise..
”, if supported by the current encoding, or “
S
” otherwise..
”, if supported by the current encoding, or “
d
” otherwise..
”, if supported by the current encoding, or “
d
” otherwise..
”, if supported by the current encoding, or “
E
” otherwise..
”, if supported by the current encoding, or “
E
” otherwise..
”, if supported by the current encoding, or “
K
” otherwise..
”, if supported by the current encoding, or “
K
” otherwise..
”, if supported by the current encoding, or “
T
” otherwise..
”, if supported by the current encoding, or “
T
” otherwise..
”, if supported by the current encoding, or “
Dr
” otherwise..
”, if supported by the current encoding, or “
Dr
” otherwise..
”, if supported by the current encoding, or “
p
” otherwise..
”, if supported by the current encoding, or “
p
” otherwise..
”, if supported by the current encoding, or “
P
” otherwise..
”, if supported by the current encoding, or “
P
” otherwise..
”, if supported by the current encoding, or “
G.
” otherwise..
”, if supported by the current encoding, or “
G.
” otherwise..
”, if supported by the current encoding, or “
A
” otherwise..
”, if supported by the current encoding, or “
A
” otherwise..
”, if supported by the current encoding, or “
S
” otherwise..
”, if supported by the current encoding, or “
S
” otherwise..
”, if supported by the current encoding, or “
S
” otherwise..
”, if supported by the current encoding, or “
S
” otherwise..
”, if supported by the current encoding, or “
lt
” otherwise..
”, if supported by the current encoding, or “
lt
” otherwise..
”, if supported by the current encoding, or “
Sm
” otherwise..
”, if supported by the current encoding, or “
Sm
” otherwise..
”, if supported by the current encoding, or “
T
” otherwise..
”, if supported by the current encoding, or “
T
” otherwise..
”, if supported by the current encoding, or “
R
” otherwise..
”, if supported by the current encoding, or “
R
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
M
” otherwise..
”, if supported by the current encoding, or “
M
” otherwise..
”, if supported by the current encoding, or “
M
” otherwise..
”, if supported by the current encoding, or “
M
” otherwise..
”, if supported by the current encoding, or “
R
” otherwise..
”, if supported by the current encoding, or “
R
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
L
” otherwise..
”, if supported by the current encoding, or “
c
” otherwise..
”, if supported by the current encoding, or “
c
” otherwise..
2.3.2. Numerical[link]
\dtladd
)
require plain numbers with a period/full stop decimal point (.
)
and no number group character or currency symbol.
\DTLadd
)
parse their values for the currency symbol, decimal character and
number group character. The number group character is only used in
integers and before the decimal character in decimal and currency
values. The decimal character is only relevant to decimal numbers
and currency values.
” (comma) and
“,
decimal point
” (full stop/period), although localisation
support may change this.
\DTLsetnumberchars
simply uses this
function to set the current number group character and
decimal character.
Allows alternative content to be used when formatting, but be aware
that repeated parsing and formatting will fail if the parsing and
formatting characters are different.
\ur
.
The third argument is a regular expression to match the
number group character but the fourth is just the
decimal character.
The third is just the decimal character but
the fourth argument is a regular expression to match the
decimal character.
\datatool_set_numberchars:nn
but uses
\, (thin space) for the number group character when
formatting, and allows \, or a normal space or the Unicode
character U+2009 (thin space) as the number group character when
parsing. The decimal character for both formatting and parsing is
set to .
\DTLdefcurrency
(see §2.6). This commands also defines
\DTLCurrencyCode
to expand to the associated ISO code and
redefines \DTLfmtcurrency
to match the formatting associated
with the currency.
\DTLdefcurrency
then it’s assumed to be just a
currency symbol and \DTLCurrencyCode
will be defined to
“XXX”. \DTLfmtcurrency
won’t be changed.
This form is now discouraged and may be deprecated in future.
\datatool
symbolprefix command is
important as the parser used by commands like \DTLparse
will check for it
and, if defined, will also check for currency symbols prefixed by
their region’s code.
\DTLcurrCodeOrSymOrChar
to only show the tag when that
command expands to its second or third argument. (Since the tag is typically
the region code, it’s redundant to insert it before the currency
code.) The tag is formatted with:
This may be redefined, which will change the way the tag is
formatted for all regions that support it. For convenience, the
numeric option region-currency-prefix
may be used
to redefine this formatting command to use small caps.
region-currency
numeric
option). The hook should only set the currency if this boolean value
is true.
region-number-chars
numeric
option). The hook should only set the number group and decimal
characters if this boolean value is true.
\DTLdecimaltocurrency
instead.
If \datatool_set_numberchars:nnnn
was used, the characters
supplied with the
and arguments
will be used.
\DTLdecimaltocurrency
won’t
round the result. Otherwise, the expansion text should be the number
of decimal places to round to. This command is redefined by
localisation hooks.
\documentclass
{article}
\usepackage
[en-GB]{datatool-base}
\begin{document}
\DTLdecimaltocurrency
{1234.5672}{\result
}% parse number
Result: \result
.
Value: \DTLdatumvalue
{\result
}.
\end{document}
2.3.3. Lexicographical[link]
\DTLDefaultLocaleWordHandler
.
If no localisation support is provided, this command does nothing.
If localisation support is added, this handler should make any
appropriate adjustments to to convert its content to a
byte sequence that will ensure the string is correctly sorted
according to the locale’s alphabet.
\DTLenLocaleHandler
and the following is
added (indirectly) to the language hook (see §2.3.5):
This allows accented characters, such as “Á”, to be converted to
non-accented Basic Latin characters, such as “A”.
This command is also defined by datatool-english-latin1.ldf and
datatool-english-ascii.ldf but has less support.
\let
\DTLCurrentLocaleWordHandler
\DTLenLocaleHandler
\datatoolpersoncomma
.
\l_datatool_current_language_tl
will need to be redefined to match.
(Alternatively, “isl” or “ice” could also be used but the
important thing is to be consistent in the event that a region file
tries searching for a command name to determine if it’s supported
for the current language.)
Substitutions for foreign language letters (such as replacing “ß”
with “ss”) should be added as applicable. The currency signs and
punctuation are as for \ExplSyntaxOn
\newcommand
{\DTLisLocaleHandler
} [ 1 ]
{
\regex_replace_case_all:nN
{
{ Á } { A\cL
\x
{7f} } { á } { a\cL
\x
{7f} }
{ Ð } { D\cL
\x
{7f} } { ð } { d\cL
\x
{7f} }
{ É } { E\cL
\x
{7f} } { é } { e\cL
\x
{7f} }
{ Í } { I\cL
\x
{7f} } { í } { i\cL
\x
{7f} }
{ Ó } { O\cL
\x
{7f} } { ó } { o\cL
\x
{7f} }
{ Ú } { U\cL
\x
{7f} } { ú } { u\cL
\x
{7f} }
{ Ý } { Y\cL
\x
{7f} } { ý } { y\cL
\x
{7f} }
{ Þ } { \cL
\x
{5b} } { þ } { \cL
\x
{7b} }
{ Æ } { \cL
\x
{5c} } { æ } { \cL
\x
{7c} }
{ Ö } { \cL
\x
{5d} } { ö } { \cL
\x
{7d} }
% currency signs and punctuation
% […]
}
#1
}
\ExplSyntaxOff
\DTLenLocaleHandler
, shown
earlier.
\cL
to ensure that the replacement characters
have a letter category code (even though they’re not actually letters).
This will allow the process to be reversed without changing
punctuation characters that were originally present in the sort string
(see Example 12).
You may prefer to use \let
\DTLCurrentLocaleWordHandler
\DTLisLocaleHandler
\renewcommand
if you want to provide
options to adjust the handler (as with datatool-ang-Runr.ldf).
\newcommand
{\mylist
}{bókstafinn, vera, eða, ég, býsna,
þú, vakna, epli, bragðs, aldar, bað, bolli, ýmist, af,
óáreiðanleg, bær, dalur, ör, þorn, þau, október, esja,
öngull, dæmi, að, yfir, öðrum, orð, detta, áhrif, yngri,
óvinur, ætlað}
\DTLsortwordlist
{\mylist
}{\DTLsortletterhandler
}
Sorted list: \DTLformatlist
{\mylist
}.
\DTLassignlettergroup
to set
(a token list variable) to the content from which the letter group
will be obtained (but only for string data types).
\datatool_sort_preprocess:Nn
.
\DTLGetInitialLetter
and
\DTLassignlettergroup
to obtain the initial letter of
the given text. The default definition just uses
\datatool_get_first_letter:nN
which skips leading non-letters.
and adds the following to the language hook:
\newcommand
{\DTLenLocaleGetInitialLetter
}[2]{
\datatool_get_first_letter:nN
{ #1 } #2
\DTLenLocaleHandler
#2
\int_compare:nNnT
{ \tl_count:N
#2 } > { \c_one_int
}
{
\exp_args:NV
\datatool_get_first_letter:nN
#2 #2
}
}
(See §2.3.5 for further details.)
\let
\DTLCurrentLocaleGetInitialLetter
\DTLenLocaleGetInitialLetter
(Note that this will also find “Ij” and “iJ”. Some adjustment
is required to exclude those cases.)
Suppose that this has been implemented via a language hook (see §2.3.5):
\newcommand
{\DTLdutchLocaleGetInitialLetter
}[2]{
\tl_clear:N
#2
\text_map_inline:nn
{ #1 }
{
\tl_if_empty:NTF
#2
{
\datatool_if_letter:nT
{ ##1 }
{
\tl_set:Nn
#2 { ##1 }
\tl_if_in:nnF
{ Ii } ##1 { \text_map_break:
}
}
}
{
\tl_if_in:nnT
{ Jj } { ##1 }
{
\tl_put_right:Nn
#2 { ##1 }
}
\text_map_break:
}
}
}
Then it will affect commands that fetch an initial letter, such as
\let
\DTLCurrentLocaleGetInitialLetter
\DTLdutchLocaleGetInitialLetter
\DTLinitials
:
IJsselmeer:
The test for a letter (with \DTLinitials
{IJsselmeer}
Industrieel: \DTLinitials
{Industrieel}
``IJsselmeer'': \DTLinitials
{``IJsselmeer''}
``Industrieel'': \DTLinitials
{``Industrieel''}
\datatool_if_letter:nT
) ensures that
leading punctuation is skipped.
\DTLCurrentLocaleGetInitialLetter
is also used to obtain the
letter group (but not the non-letter group) from sort values with
\DTLsortwordlist
.
\DTLCurrentLocaleGetGroupString
. For example,
datatool-english.ldf uses the sort value, since all the extended characters
are mapped to Basic Latin letters. In this case, we have some
awkward control characters which will mess up the letter group.
\DTLangLatnLocaleGetGroupString
.
That starts with the actual value and processes it
with \datatool_sort_preprocess:Nn
and then replaces any
leading accented character with the unaccented letter.
\DTLisLocaleHandler
would also need to provide a way
of reversing the substitutions for the letter groups. Since the replacement
(non-alphabetic) characters are assigned the letter category code, this makes
them easier to distinguish from actual punctuation characters.
Note that, unlike the handler function, this only needs to perform
one replacement as we’re only interested in the start of the string.
Unlike the first method (used by \newcommand
{\DTLisLocaleGetGroupString
}[3]{
\tl_set:Nn
#3 { #2 }
\regex_replace_case_once:nN
{
{ A\cL
\x
{7f} } { Á } { a\cL
\x
{7f} } { á }
{ D\cL
\x
{7f} } { Ð } { d\cL
\x
{7f} } { ð }
{ E\cL
\x
{7f} } { É } { e\cL
\x
{7f} } { é }
{ I\cL
\x
{7f} } { Í } { i\cL
\x
{7f} } { í }
{ O\cL
\x
{7f} } { Ó } { o\cL
\x
{7f} } { ó }
{ U\cL
\x
{7f} } { Ú } { u\cL
\x
{7f} } { ú }
{ Y\cL
\x
{7f} } { Ý } { y\cL
\x
{7f} } { ý }
{ \cL
\x
{5b} } { Þ } { \cL
\x
{7b} } { þ }
{ \cL
\x
{5c} } { Æ } { \cL
\x
{7c} } { æ }
{ \cL
\x
{5d} } { Ö } { \cL
\x
{7d} } { ö }
} #3
}
\DTLangLatnLocaleGetGroupString
)
we don’t need to worry about whether or not leading hyphens have
been stripped.
Deciding which method to use comes down to whether it’s more complex
to reverse the mapping on the sort value or to process the actual
value.
Example 10 can now be adapted to show the letter groups:
\let
\DTLCurrentLocaleGetInitialLetter
\DTLisLocaleGetInitialLetter
\DTLsortwordlist
{\mylist
}{\DTLsortletterhandler
}
\renewcommand
{\DTLlistformatitem
}[1]{#1 (\DTLsortedletter
{#1})}
Sorted list: \DTLformatlist
{\mylist
}.
.
In the case of Dutch, this would need to be changed to use
\text_titlecase_first:n
{ }\text_uppercase:n
instead to ensure that “ij” becomes “IJ”
instead of “Ij”.
"
because of the final substitution case in the regular expression.
For the handler provided in datatool-english-utf8.ldf (see
§2.3.5), the character will either be a
double-quote "
or a literal dollar $
(with category
code other).
sort-datum
={true}.)
By default, this simply expands to . A language file
may redefine this to produce a textual title. For example,
“Numbers”.
sort-datum
={true}.)
By default, this simply expands to . A language file
may redefine this to produce a textual title. For example,
“Currency”.
2.3.4. Adding New Region Support[link]
parse
=region
or parse
=iso+region. Note that any date formats
that have textual parts (such as month names) should be dealt with
by the language support.
2.3.5. Adding New Language Support[link]
The datatool-english distribution provides a similar
datatool-en-CA.ldf file.
\TrackLangProvidesResource
{fr-CA}
\TrackLangRequireResource
{french}
\ExplSyntaxOn
\newcommand
\datatoolfrCASetNumberChars
{
\bool_if:NT
\l_datatool_region_set_numberchars_bool
\DTLsetnumberchars
{.}{,}% number group and decimal symbol
}
\newcommand
\DTLfrCALocaleHook
{
\datatoolfrCASetNumberChars
}
\ExplSyntaxOff
\TrackLangAddToCaptions
{\DTLfrCALocaleHook
}
\ProvidesPackage
for packages):
Although pdfLaTeX now defaults to UTF-8, it can be helpful to
provide some support for other encodings. The document encoding (as
detected by tracklang) can be obtained by expanding
\TrackLangProvidesResource
{ }[ / / v ]
\TrackLangEncodingName
(\inputencoding
isn’t guaranteed to
be defined).
Note the difference between requesting a resource and requiring it.
\TrackLangRequestResource
{english-\TrackLangEncodingName
}
{
\TrackLangRequireResource
{english-ascii}
}
This file is actually just a fallback as the files
datatool-ang-Latn.ldf and datatool-ang-Runr.ldf should be found first.
Note that the script indicates the script of the input or source
text. That is, the text used in the document source code, which
may not correspond to the glyphs visible in the PDF file.
\TrackLangProvidesResource
{anglosaxon}
\TrackLangRequestResource
{ang-\CurrentTrackedDialectScript
-\TrackLangEncodingName
}
{%
\PackageWarning
{datatool-anglosaxon}%
{%
No support for `anglosaxon' with script
`\CurrentTrackedDialectScript
'
and encoding `\TrackLangEncodingName
'%
}%
}
\runic
, which expects Latin characters in the argument
but the font encoding ensures that those characters appear as runes
in the PDF. In this case, the source is Latin and so
“ang-Latn” is needed when specifying the locale.
The code for datatool-ang-Runr.ldf is similar. Only UTF-8 is
supported (datatool-ang-Latn-utf8.ldf and
datatool-ang-Runr-utf8.ldf), but this method allows for
other encodings to be added by simply creating a file with an
appropriate name.
\TrackLangProvidesResource
{ang-Latn}
\TrackLangRequestResource
{ang-Latn-\TrackLangEncodingName
}
{%
\PackageWarning
{datatool-ang-Latn}%
{%
No support for `anglosaxon' with script `Latn'
and encoding `\TrackLangEncodingName
'.%
}%
\endinput
}
\ExplSyntaxOn
\DTLenLocaleGetGroupString
ensures that the
letter group is obtained from the sort value rather than the actual
value:
This ensures that the accents are stripped, but it will mean that
the currency and punctuation marks will have their initial marker
that’s inserted by the handler function \newcommand
\DTLenLocaleGetGroupString
[3]
{
\tl_set:Nn
#3 { #2 }
}
\DTLenLocaleHandler
.
Bear in mind that \DTLenLocaleGetGroupString
is only used for
values that have been identified as strings. It’s not used by other
data types. The non-letter characters used to alter the order
of currency and punctuation marks is usually not relevant, as the
non-letter group title (\dtlnonlettergroup
) typically ignores
the character.
\DTLangLatnLocaleHandler
inserts a double-quote character in front of any punctuation, it’s
possible to check if the actual value starts with a hyphen and
if the sort value starts with a double-quote then the hyphen likely
wasn’t stripped so it can be removed.
This is done as follows:
\newcommand
\DTLangLatnLocaleGetGroupString
{ 3 }
{
\tl_set:Nn
#3 { #1 }
\datatool_angLatn_process_letter_group:N
#3
\bool_lazy_and:nnT
{ \tl_if_head_eq_charcode_p:nN
{ #1 } - }
{ \bool_not_p:n
{ \tl_if_head_eq_charcode_p:nN
{ #2 } " } }
{
\exp_args:NNe
\tl_set:Nn
#3 { \tl_tail:N
#3 }
}
}
\DTLCurrentLocaleGetInitialLetter
is the same
as the default definition provided by datatool-base.
For example, datatool-english.ldf defines:
\newcommand
\DTLenLocaleGetInitialLetter
[ 2 ]
{
\datatool_get_first_letter:nN
{ #1 } #2
}
\DTLandname
to use the Tironian et.
Aside from the above, the fixed-text commands for
datatool-base are \newcommand
\DTLenSetLetterGroups
{
\renewcommand
\dtllettergroup
[ 1 ]
{ \text_titlecase_first:n
{ ##1 } }
\renewcommand
\dtlnonlettergroup
[ 1 ] { Symbols }
\renewcommand
\dtlnumbergroup
[ 1 ] { Numbers }
\renewcommand
\dtlcurrencygroup
[ 2 ] { Currency }
\renewcommand
\dtldatetimegroup
[ 1 ] { Timestamps }
\renewcommand
\dtldategroup
[ 1 ] { Dates }
\renewcommand
\dtltimegroup
[ 1 ] { Times }
}
\DTLandname
,
\DTLdatatypeunsetname
,
\DTLdatatypestringname
,
\DTLdatatypeintegername
,
\DTLdatatypedecimalname
,
\DTLdatatypecurrencyname
,
\DTLdatatypedatetimename
,
\DTLdatatypedatename
,
\DTLdatatypetimename
, and
\DTLdatatypeinvalidname
.
\DTLandname
:
This makes it easier to for the supplied option to redefine it:
\newcommand
\DTLenSetAndName
{
\renewcommand
\DTLandname
{ and }
}
This is added to the hook that sets all the datatool-base
textual commands:
\datatool_locale_define_keys:nn
{ en }
{
and .choice:,
and / word .code:n =
{
\renewcommand
\DTLenSetAndName
{
\renewcommand
\DTLandname
{ and }
}
\tl_if_eq:NnT
\l_datatool_current_language_tl
{ en }
{ \DTLenSetAndName
}
} ,
and / amp .code:n =
{
\renewcommand
\DTLenSetAndName
{
\renewcommand
\DTLandname
{ \& }
}
\tl_if_eq:NnT
\l_datatool_current_language_tl
{ en }
{ \DTLenSetAndName
}
} ,
}
\newcommand
\DTLenTranslations
{
\DTLenSetAndName
\renewcommand
\DTLdatatypeunsetname
{ unset }
\renewcommand
\DTLdatatypestringname
{ string }
\renewcommand
\DTLdatatypeintegername
{ integer }
\renewcommand
\DTLdatatypedecimalname
{ decimal }
\renewcommand
\DTLdatatypecurrencyname
{ currency }
\renewcommand
\DTLdatatypedatetimename
{ date-time }
\renewcommand
\DTLdatatypedatename
{ date }
\renewcommand
\DTLdatatypetimename
{ time }
\renewcommand
\DTLdatatypeinvalidname
{ invalid }
}
If babel or polyglossia have been loaded, this will
add \newcommand
\DTLenLocaleHook
{
\renewcommand
\DTLCurrentLocaleWordHandler
{ \DTLenLocaleHandler
}
\renewcommand
\DTLCurrentLocaleGetInitialLetter
{ \DTLenLocaleGetInitialLetter
}
\renewcommand
\DTLCurrentLocaleGetGroupString
{ \DTLenLocaleGetGroupString
}
\DTLenSetLetterGroups
% date and time assignments
% […]
\tl_set:Nn
\l_datatool_current_language_tl
{ en }
% Fixed text command:
\DTLenTranslations
}
\ExplSyntaxOff
\TrackLangAddToCaptions
{\DTLenLocaleHook
}
\DTLenLocaleHook
to the \captions
hook.
The command will be implemented at this point as well, which will make
it the current setting if there’s no hook.
and datatool-ang-Runr.ldf has:
\tl_set:Nn
\l_datatool_current_language_tl
{ angLatn }
\tl_set:Nn
\l_datatool_current_language_tl
{ angRunr }
\DTLenLocaleHandler
is provided in
datatool-english-utf8.ldf, datatool-english-latin1.ldf
and datatool-english-ascii.ldf. This is used to convert strings
into byte sequences for
lexicographical comparisons. For example, datatool-english-utf8.ldf
replaces common extended Latin characters into the nearest
ASCII equivalent, suitable for English ordering.
This can conveniently be done with regular expression replacement.
The final substitutions are for currency and any punctuation and
is designed to gather together currency symbols and punctuation marks.
(Otherwise they would be in their character code order which would
spread them before and after letters.) Note that character classes
such as \cs_new:Npn
\DTLenLocaleHandler
#1
{
\regex_replace_case_all:nN
{
% alphabetical cases
% [ … ]
{ (\ur
{l_datatool_currencysigns_regex}) } { \cO
\x
{24}\1
}
{ ’ } { \cO
"' }
{ ‘ } { \cO
"` }
{ (“|”) } { \cO
"\cO
" }
{ (—|–) } { \cO
"- }
{ ([[:punct:]]+) } { \cO
"\1
}
}
#1
}
[:punct:]
and [:alpha:]
only apply to Basic
Latin characters. (The use of \cO
ensures that the next
character has category code “other”.)
2.4. Conditionals[link]
{
arguments (such as }{ }\DTLifint
) or case arguments (such as
\DTLifcasedatatype
) and those that are designed to be used in
the conditional part of \ifthenelse
(provided by the
ifthen package). The first type have command names that start
“DTLif
” or “dtlif
” and are described in
§2.4.1, and the second type have command
names starting “DTLis” and are described in
§2.4.2.
2.4.1. If-Else or Case Conditionals[link]
\DTLifstringeq
, treat their
arguments as strings. For example, \DTLifstringlt
is a
test if one string is lexicographical less than another.
DTLif
” commands listed in
§2.4.1.3, such as \DTLifnumeq
, expect
formatted numbers or datum control sequences in the numeric arguments.
If you know that all your values are plain numbers, the
“dtlif
” listed in §2.4.1.4 commands are
quicker.
\dtlifnumeq
, don’t parse for the current decimal character and
number group character or for a currency symbol. They require a
plain number, either a bare integer (such as 12345) or a number
with a decimal point (such as 1234.5). These commands are
listed as being provided by datatool-base, but are actually
defined in the maths processor file datatool-.def corresponding to the value of the math
package option. With math=l3fp or
math=lua, these commands are expandable but
with math=fp or math=pgfmath they are
robust. Note that the fp package doesn’t support
scientific notation.
\DTLifeq
, parse the arguments to determine the data type and
then use the corresponding command from §2.4.1.3 or
§2.4.1.2.
2.4.1.1. Data Type Conditionals[link]
\DTLdatumtype
on a datum control sequence
(obtained with \DTLparse
or \DTLxparse
) to determine the
data type.
\DTLparse
.
\DTLifnumerical
except in the case of an empty argument,
which has an unknown type, and so is neither numerical nor a string.
See Example 17.
2.4.1.1.1. Test if Integer Example[link]
\DTLifint
to determine if the
argument is an integer according to the current localisation
setting.
2536:
Note that the datum control sequence \DTLifint
{2536}{integer}{not an integer}.
2536.0: \DTLifint
{2536.0}{integer}{not an integer}.
2,536: \DTLifint
{2,536}{integer}{not an integer}.
2,5,3,6: \DTLifint
{2,5,3,6}{integer}{not an integer}.
\DTLparse
{\numA
}{2,536}
\numA
: \DTLifint
{\numA
}{integer}{not an integer}.
\DTLsetnumberchars
{.}{,}%
2,536: \DTLifint
{2,536}{integer}{not an integer}.
2.536: \DTLifint
{2.536}{integer}{not an integer}.
\numA
: \DTLifint
{\numA
}{integer}{not an integer}.
\numA
is still identified as an
integer after \DTLsetnumberchars
even though it uses the
original number group character and decimal character. This is
because once the datum control sequence has had its data type set there’s no
need to reparse its value.
2.4.1.1.2. Test if Decimal Example[link]
\DTLifreal
to determine if the
argument is a decimal according to the current localisation
setting. Note that although integers are a subset of real numbers,
this test will only be true if the argument has a fractional part or
is in scientific notation.
1000.0:
\DTLifreal
{1000.0}{real}{not real}.
1,000: \DTLifreal
{1,000}{real}{not real}.
1,000.0: \DTLifreal
{1,000.0}{real}{not real}.
1e+3: \DTLifreal
{1e+3}{real}{not real}.
\DTLsetnumberchars
{.}{,}%
1,000.0: \DTLifreal
{1,000.0}{real}{not real}.
1.000,0: \DTLifreal
{1.000,0}{real}{not real}.
2.4.1.1.3. Test if Currency Example[link]
\DTLifcurrency
and
\DTLifcurrencyunit
to determine if the argument is a currency
value or a currency symbol according to the current localisation
setting and defined currency symbols.
\$5.99:
\DTLifcurrency
{\$5.99}{currency}{not currency}.
\DTLcurrency
{5.99}:
\DTLifcurrency
{\DTLcurrency
{5.99}}{currency}{not currency}.
\pounds
5.99:
\DTLifcurrency
{\pounds
5.99}{currency}{not currency}.
\textsterling
5.99:
\DTLifcurrency
{\textsterling
5.99}{currency}{not currency}.
\$6.99:
\DTLifcurrencyunit
{\$6.99}{\$}{dollars}{not dollars}.
\newcommand
{\cost
}{\pounds
10.50}%
\cost
: \DTLifcurrencyunit
{\cost
}{\pounds
}{pounds}{not pounds}.
US\$5.99:
\DTLifcurrency
{US\$}{currency}{not currency}.
\DTLnewcurrencysymbol
{US\$}%
US\$5.99:
\DTLifcurrency
{US\$}{currency}{not currency}.
2.4.1.1.4. Test if Numerical Example[link]
\DTLifnumerical
to determine if the
argument is numerical (integer, real or currency value) according to
the current localisation setting and defined currency symbols.
1,234:
\DTLifnumerical
{1,234}{numeric}{not numeric}.
1,234.0: \DTLifnumerical
{1,234.0}{numeric}{not numeric}.
\$1,234.0:
\DTLifnumerical
{\$1,234.0}{numeric}{not numeric}.
1.234,0: \DTLifnumerical
{1.234,0}{numeric}{not numeric}.
\DTLsetnumberchars
{.}{,}%
1.234,0: \DTLifnumerical
{1.234,0}{numeric}{not numeric}.
Empty: \DTLifnumerical
{}{numeric}{not numeric}.
2.4.1.1.5. Test if String Example[link]
\DTLifstring
to test if the argument
is considered a string (that is, not numeric and not empty).
1,234:
\DTLifstring
{1,234}{string}{not string}.
\$1,234.0: \DTLifstring
{\$1,234.0}{string}{not string}.
1,2,3,4: \DTLifstring
{1,2,3,4}{string}{not string}.
Empty: \DTLifstring
{}{string}{not string}.
2.4.1.1.6. Test Data Type Example[link]
\DTLifcasedatatype
to determine
the data type of its argument, according to the current localisation
setting and known currency symbols.
1,234:
\DTLifcasedatatype
{1,234}{string}{int}{real}{currency}.
1,234.0: \DTLifcasedatatype
{1,234.0}{string}{int}{real}{currency}.
\$1,234: \DTLifcasedatatype
{\$1,234}{string}{int}{real}{currency}.
1,2,3,4: \DTLifcasedatatype
{1,2,3,4}{string}{int}{real}{currency}.
Empty: \DTLifcasedatatype
{}{string}{int}{real}{currency}.
2.4.1.2. String and List Conditionals[link]
\dtlcompare
and \dtlicompare
, taking into account the
compare settings (see Example 20).
~
,
\nobreakspace
and \space
are considered identical (see
Example 24).
Note that this does not take category codes into account.
\DTLifSubString
but tests if starts
with (see Example 25).
Note that this does not take category codes into account.
\DTLifStartsWith
didn’t ignore commands despite the
documentation. This has now been corrected in v3.0.
\DTLifSubString
but tests if ends
with . The starred version is case-insensitive.
Note that this does not take category codes into account.
\emph
are disregarded by the all
upper/lower case conditionals, as illustrated in Example 27.
2.4.1.2.1. Element in List Example[link]
\newcommand
{\goose
}{goose}
\newcommand
{\mylist
}{duck,\goose
,{ant},zebra}
\DTLifinlist
is used to determine if certain items are the list:
`ant' in list?
The following tests if “goose” is an element of the list. This is
false, because the actual element is \DTLifinlist
{ant}{\mylist
}{true}{false}.
\goose
. The
\mylist
command is only expanded once not fully.
`goose' in list?
\DTLifinlist
{goose}{\mylist
}{true}{false}.
`\goose
' in list? \DTLifinlist
{\goose
}{\mylist
}{true}{false}.
`duck' in list? \DTLifinlist
{duck}{\mylist
}{true}{false}.
`zebra' in list? \DTLifinlist
{zebra}{\mylist
}{true}{false}.
2.4.1.2.2. String Equality Example[link]
The initial first token expansion will expand these commands once before
applying the rules according to the current compare
setting.
\newcommand
{\strA
}{zebra}
\newcommand
{\strB
}{Zebra}
`
The command \strA
' is
\DTLifstringeq
{\strA
}{\strB
}{the same}{not the same}
as `\strB
' (case).
`\strA
' is
\DTLifstringeq
*{\strA
}{\strB
}{the same}{not the same}
as `\strB
' (no case).
`\strA
' is
\DTLifstringeq
{\strA
}{zebra}{the same}{not the same}
as `zebra' (case).
\emph
is robust so it
won’t be expanded by the initial expand first token action in the following:
`
The default \emph
{ant}' is
\DTLifstringeq
{\emph
{ant}}{ant}{the same}{not the same}
as `ant'.
expand-cs
=false and
skip-cs
=false settings mean that commands won’t be
skipped in the comparison. Note the difference when the setting is
changed:
Only the first token is expanded, so \DTLsetup
{compare={skip-cs
}}
`\emph
{ant}' is
\DTLifstringeq
{\emph
{ant}}{ant}{the same}{not the same}
as `ant' (skip cs).
\strA
isn’t expanded in
the initial step:
`ant zebra' is
With \DTLifstringeq
{ant zebra}{ant \strA
}{the same}{not the same}
as `ant \strA
' (no expansion).
expand-cs
=true, expansion will be applied in
the second step:
\DTLsetup
{compare={expand-cs
}}
`ant zebra' is
\DTLifstringeq
{ant zebra}{ant \strA
}{the same}{not the same}
as `ant \strA
' (expansion).
2.4.1.2.3. String Less Than Example[link]
\DTLifstringlt
to determine if one
string is “less than” (comes before) another.
`aardvark' is
\DTLifstringlt
{aardvark}{Zebra}{before}{after}
`Zebra' (case).
`aardvark' is \DTLifstringlt
*{aardvark}{Zebra}{before}{after}
`Zebra' (no case).
2.4.1.2.4. String Greater Than Example[link]
`aardvark' is
\DTLifstringgt
{aardvark}{Zebra}{after}{before}
`Zebra' (case).
`aardvark' is \DTLifstringgt
*{aardvark}{Zebra}{after}{before}
`Zebra' (no case).
2.4.1.2.5. String Between Two Strings Example[link]
`duck' lies between `Duck' and `Duckling'
(exclusive, case)?
\DTLifstringopenbetween
{duck}{Duck}{Duckling}{true}{false}.
`duck' lies between `Duck' and `Duckling'
(exclusive, no case)?
\DTLifstringopenbetween
*{duck}{Duck}{Duckling}{true}{false}.
`duck' lies between `Duck' and `Duckling'
(inclusive, case)?
\DTLifstringclosedbetween
{duck}{Duck}{Duckling}{true}{false}.
`duck' lies between `Duck' and `Duckling'
(inclusive, no case)?
\DTLifstringclosedbetween
*{duck}{Duck}{Duckling}{true}{false}.
2.4.1.2.6. Substring Example[link]
The \newcommand
{\strA
}{An apple}
\newcommand
{\strB
}{n~
ap}
\DTLifSubString
command is used to test if the second
argument is a substring of the first:
(First two arguments expanded) `
\strB
'
\DTLifSubString
{\strA
}{\strB
}{is substring}{isn't substring}
of `\strA
'.
`app'
\DTLifSubString
{An apple}{app}{is substring}{isn't substring}
of `An apple'.
(Non-breakable space same as space) `n~
a'
\DTLifSubString
{An apple}{n~
a}{is substring}{isn't substring}
of `An apple'.
(Robust commands stripped) `app'
\DTLifSubString
{An \MakeUppercase
{a}pple}{app}{is substring}{isn't substring}
of `An \MakeUppercase
{a}pple'.
(Grouping stripped) `app'
\DTLifSubString
{An {ap}ple}{app}{is substring}{isn't substring}
of `An {ap}ple'.
(Case-sensitive) `app'
\DTLifSubString
{An Apple}{app}{is substring}{isn't substring}
of `An Apple'.
(Not case-sensitive) `app'
\DTLifSubString
*{An Apple}{app}{is substring}{isn't substring}
of `An Apple'.
(Leading space) ` app'
\DTLifSubString
{Anapple}{ app}{is substring}{isn't substring}
of `Anapple'.
2.4.1.2.7. String Prefix Example[link]
\DTLifStartsWith
to test if the second argument is at the start
(is a prefix) of the first:
\newcommand
{\strA
}{An apple}
\newcommand
{\strB
}{n~
ap}
\newcommand
{\strC
}{An~
ap}
(First two arguments expanded) `\strB
'
\DTLifStartsWith
{\strA
}{\strB
}{is prefix}{isn't prefix}
of `\strA
'.
(First two arguments expanded) `\strC
'
\DTLifStartsWith
{\strA
}{\strC
}{is prefix}{isn't prefix}
of `\strA
'.
(Non-breakable space same as space) `An~a'
\DTLifStartsWith
{An apple}{An~
a}{is prefix}{isn't prefix}
of `An apple'.
(Robust commands stripped) `app'
\DTLifStartsWith
{\MakeUppercase
{a}pple}{app}{is prefix}{isn't prefix}
of `\MakeUppercase
{a}pple'.
(Case-sensitive) `app'
\DTLifStartsWith
{Apple}{app}{is prefix}{isn't prefix}
of `Apple'.
(Ignore case) `app'
\DTLifStartsWith
*{Apple}{app}{is prefix}{isn't prefix}
of `Apple'.
(Trailing space) `an '
\DTLifStartsWith
{an apple}{an }{is prefix}{isn't prefix}
of `an apple'.
(Trailing space) `an '
\DTLifStartsWith
{anapple}{an }{is prefix}{isn't prefix}
of `anapple'.
2.4.1.2.8. String Suffix Example[link]
\DTLifEndsWith
to test if the second argument is at the end
(is a suffix) of the first. It uses the same \strA
and
\strB
as before:
The tests are as follows:
\newcommand
{\strA
}{An apple}
\newcommand
{\strB
}{n~
apple}
(First two arguments expanded) `
\strB
'
\DTLifEndsWith
{\strA
}{\strB
}{is suffix}{isn't suffix}
of `\strA
'.
(Non-breakable space same as space) `n~apple'
\DTLifEndsWith
{An apple}{n~
apple}{is suffix}{isn't suffix}
of `An apple'.
(Robust commands stripped) `apple'
\DTLifEndsWith
{An \MakeUppercase
{a}pple}{apple}{is suffix}{isn't suffix}
of `An \MakeUppercase
{a}pple'.
(Case-sensitive) `apple'
\DTLifEndsWith
{An Apple}{apple}{is suffix}{isn't suffix}
of `An Apple'.
(Ignore case) `apple'
\DTLifEndsWith
*{An Apple}{apple}{is suffix}{isn't suffix}
of `An Apple'.
(Leading space) ` apple'
\DTLifEndsWith
{anapple}{ apple}{is suffix}{isn't suffix}
of `anapple'.
2.4.1.2.9. String Case Example[link]
café:
\DTLifAllUpperCase
{café}{all caps}{not all caps}.
Café: \DTLifAllUpperCase
{Café}{all caps}{not all caps}.
CAFÉ: \DTLifAllUpperCase
{CAFÉ}{all caps}{not all caps}.
café: \DTLifAllLowerCase
{café}{all lower}{not all lower}.
Café: \DTLifAllLowerCase
{Café}{all lower}{not all lower}.
CAFÉ: \DTLifAllLowerCase
{CAFÉ}{all lower}{not all lower}.
bric-\`
a-brac:
\DTLifAllLowerCase
{bric-\`
a-brac}{all lower}{not all lower}.
\emph
{HORS D'\OE
UVRE}:
\DTLifAllUpperCase
{\emph
{HORS D'\OE
UVRE}}{all caps}{not all caps}.
2.4.1.3. Formatted Number Conditionals[link]
\dtlifnumeq
after
parsing the values.
\dtlifnumlt
after
parsing the values.
\dtlifnumgt
after
parsing the values.
\dtlifnumopenbetween
after parsing the values.
\dtlifnumclosedbetween
after parsing the values.
$1,234.0=1234$?
\DTLifnumeq
{1,234.0}{1234}{true}{false}.
$\$12.00=\pounds
12$? \DTLifnumeq
{\$12.00}{\pounds
12}{true}{false}.
$\$10.50<\pounds
10$? \DTLifnumlt
{\$10.50}{\pounds
10}{true}{false}.
$1,000.0 > 1,000$? \DTLifnumgt
{1,000.0}{1,000}{true}{false}.
$1000 < \$1,000.00 < 2000$?
\DTLifnumopenbetween
{\$1,000.00}{1000}{2000}{true}{false}.
$1000 \leq
\$1,000.00 \leq
2000$?
\DTLifnumclosedbetween
{\$1,000.00}{1000}{2000}{true}{false}.
2.4.1.4. Plain Number Conditionals[link]
\dtlifnumopenbetween
.
\dtlifnumopenbetween
but specifically for integers. This
simply uses \ifnum
for the comparisons and is not dependent on
the math option.
\dtlifnumclosedbetween
.
\dtlifnumclosedbetween
but specifically for integers. This
simply uses \ifnum
for the comparisons and is not dependent on
the math option.
2.4.1.4.1. Example (l3fp)[link]
\edef
(which defines a command with its
provided definition expanded) and \meaning
(which writes the
command’s definition to the PDF) to demonstrate commands that can
expand. Compare the results with using math=fp
(Example 31) and math=pgfmath
(Example 32).
\usepackage
[math=l3fp]{datatool-base}
\newcommand
{\numducks
}{4}
\begin{document}
\edef
\test
{There
\dtlifnumeq
{\numducks
}{1}{is 1 duck}{are \numducks
\space
ducks}.}
\texttt
{\meaning
\test
}
Test text: \test
\edef
\test
{There are
\dtlifnumlt
{\numducks
}{10}{less than}{not less than}
10 ducks.}
\texttt
{\meaning
\test
}
Test text: \test
\edef
\test
{There are
\dtlifnumgt
{\numducks
}{10}{more than}{not more than}
10 ducks.}
\texttt
{\meaning
\test
}
Test text: \test
\edef
\test
{There
\dtlifnumopenbetween
{\numducks
}{4}{10}{are}{are not}
between 4 and 10 ducks (exclusive).}
\texttt
{\meaning
\test
}
Test text: \test
\edef
\test
{There
\dtlifnumclosedbetween
{\numducks
}{4}{10}{are}{are not}
between 4 and 10 ducks (inclusive).}
\texttt
{\meaning
\test
}
Test text: \test
\end{document}
2.4.1.4.2. Example (lua)[link]
\usepackage
[math=lua]{datatool-base}
2.4.1.4.3. Example (fp)[link]
However, note that commands like \usepackage
[math=fp]{datatool-base}
\dtlifnumeq
are now robust and
so can’t expand (but \numducks
does
expand).
2.4.1.4.4. Example (pgfmath)[link]
However, note that commands like \usepackage
[math=pgfmath]{datatool-base}
\dtlifnumeq
are now robust and
so can’t expand (but \numducks
does expand).
2.4.1.5. String or Number Conditionals[link]
\DTLifnumeq
is used otherwise
\DTLifstringeq
is used. The starred version is only applicable
for string equality and will ignore the case. This command is
robust.
\DTLifnumlt
is used otherwise
\DTLifstringlt
is used. The starred version is only applicable
for a string comparison and will ignore the case. This command is
robust.
\DTLifnumgt
is used otherwise
\DTLifstringgt
is used. The starred version is only applicable
for a string comparison and will ignore the case. This command is
robust.
\DTLifnumopenbetween
is used otherwise
\DTLifstringopenbetween
is used. The starred version is only applicable
for a string comparison and will ignore the case. This command is
robust.
\DTLifnumclosedbetween
is used otherwise
\DTLifstringclosedbetween
is used. The starred version is only applicable
for a string comparison and will ignore the case. This command is
robust.
1 = 1.0? (numeric)
\DTLifeq
{1}{1.0}{true}{false}.
1p = 1.0p? (string) \DTLifeq
{1p}{1.0p}{true}{false}.
2 lt 10? (numeric) \DTLiflt
{2}{10}{true}{false}.
A2 lt A10? (string) \DTLiflt
{A2}{A10}{true}{false}.
2.0 gt 10.0? (numeric) \DTLifgt
{2}{10}{true}{false}.
A2.0 gt A10.0? (string) \DTLifgt
{A2.0}{A10.0}{true}{false}.
10 between 1 and 20 (numeric, exclusive)?
\DTLifopenbetween
{10}{1}{20}{true}{false}.
10p between 1p and 20p (string, exclusive)?
\DTLifopenbetween
{10p}{1p}{20p}{true}{false}.
1 between 1.0 and 2 (numeric, inclusive)?
\DTLifclosedbetween
{1}{1.0}{2}{true}{false}.
1 between 1.0 and 2A (string, inclusive)?
\DTLifclosedbetween
{1}{1.0}{2A}{true}{false}.
2.4.2. ifthen conditionals[link]
\ifthenelse
or
\whiledo
commands provided by the ifthen package.
This section describes analogous commands which may only be in
the conditional part of the \ifthenelse
or \whiledo
. These
may be used with the boolean operations \not
, \and
and
\or
provided by the ifthen package. See the ifthen
documentation for further details.
texdoc ifthen
\ifthenelse
that can cause a different result from using
\DTLis…
compared to the corresponding
\DTLif…
(see Example 34).
\DTLifint
but for use in ifthen conditionals (see
Example 2.4.2.1).
\DTLifreal
but for use in ifthen conditionals (see
Example 2.4.2.1).
\DTLifcurrency
but for use in ifthen conditionals.
Note that \DTLfmtcurr
, \DTLfmtcurrency
and \DTLcurrency
are
designed to expand so if you have data that contains those commands
it’s better to use \DTLifcurrency
(see
Example 2.4.2.1).
\DTLifcurrencyunit
but for use in ifthen conditionals (see
Example 2.4.2.1).
\DTLifnumerical
but for use in ifthen conditionals (see
Example 2.4.2.1).
\DTLifstring
but for use in ifthen conditionals (see
Example 2.4.2.1).
\DTLifeq
but for use in ifthen conditionals
(see Example 2.4.2.2).
\DTLifeq*
but for use in ifthen conditionals
(see Example 2.4.2.2).
\DTLifnumeq
but for use in ifthen conditionals.
\DTLisnumeq
.
\DTLiflt
but for use in ifthen conditionals
(see Example 2.4.2.2).
\DTLiflt*
but for use in ifthen conditionals
(see Example 2.4.2.2).
\DTLifnumlt
but for use in ifthen conditionals.
\DTLisnumlt
.
\DTLif…
direct equivalent of this command,
except using \DTLifnumgt
with the final two arguments flipped.
Evaluates to true if \( \leq \), where the
arguments are formatted numbers.
\DTLisnumlteq
.
\DTLifgt
but for use in ifthen conditionals
(see Example 2.4.2.2).
\DTLifgt*
but for use in ifthen conditionals
(see Example 2.4.2.2).
\DTLifnumgt
but for use in ifthen conditionals.
\DTLisnumgt
.
\DTLif…
direct equivalent of this command,
except using \DTLifnumlt
with the final two arguments flipped.
Evaluates to true if \( \geq \), where the
arguments are formatted numbers.
\DTLisnumgteq
.
\DTLifopenbetween
but for use in ifthen conditionals.
\DTLifopenbetween*
but for use in ifthen conditionals.
\DTLifnumopenbetween
but for use in ifthen conditionals.
\DTLisnumopenbetween
.
\DTLifclosedbetween
but for use in ifthen conditionals.
\DTLifclosedbetween*
but for use in ifthen conditionals.
\DTLifnumclosedbetween
but for use in ifthen conditionals.
\DTLisnumclosedbetween
.
\DTLifinlist
but for use in ifthen conditionals (see
Example 36).
\DTLifSubString
but for use in ifthen conditionals (see
Example 36).
\DTLifSubString*
but for use in ifthen conditionals
(see Example 36).
\DTLifStartsWith
but for use in ifthen conditionals
(see Example 36).
\DTLifStartsWith*
but for use in ifthen conditionals
(see Example 36).
\DTLifEndsWith
but for use in ifthen conditionals
(see Example 36).
\DTLifEndsWith*
but for use in ifthen conditionals
(see Example 36).
2.4.2.1. Data Type Conditionals Example[link]
1,234.0:
Note the difference between \ifthenelse
{\DTLisint
{1,234.0}}{int}{not int}.
1,234: \ifthenelse
{\DTLisint
{1,234}}{int}{not int}.
1,234.0: \ifthenelse
{\DTLisreal
{1,234.0}}{real}{not real}.
1,234: \ifthenelse
{\DTLisreal
{1,234}}{real}{not real}.
Compare:
\$1,234: \DTLifcurrency
{\$1,234}{currency}{not currency}.
With: \$1,234: \ifthenelse
{\DTLiscurrency
{\$1,234}}{currency}{not currency}.
\DTLnewcurrencysymbol
{\protect
\$}%
\$1,234: \ifthenelse
{\DTLiscurrency
{\$1,234}}{currency}{not currency}.
1.234,0: \ifthenelse
{\DTLisnumerical
{1.234,0}}{numerical}{not numerical};
\ifthenelse
{\DTLisstring
{1.234,0}}{string}{not string}.
\DTLsetnumberchars
{.}{,}%
1.234,0: \ifthenelse
{\DTLisnumerical
{1.234,0}}{numerical}{not numerical};
\ifthenelse
{\DTLisstring
{1.234,0}}{string}{not string}.
Empty: \ifthenelse
{\DTLisnumerical
{}}{numerical}{not numerical};
\ifthenelse
{\DTLisstring
{}}{string}{not string}.
\DTLifcurrency
and
\DTLiscurrency
. This is because \ifthenelse
causes
\$ to expand to
,
which isn’t recognised as a currency unit by default.
\protect
\$2.4.2.2. Order Conditionals Example[link]
\ifthenelse
:
$1 = 1.0$?
\ifthenelse
{\DTLiseq
{1}{1.0}}{true}{false}.
duck = Duck? (case-sensitive)
\ifthenelse
{\DTLiseq
{duck}{Duck}}{true}{false}.
duck = Duck? (ignore case)
\ifthenelse
{\DTLisieq
{duck}{Duck}}{true}{false}.
$2 < 10$? \ifthenelse
{\DTLislt
{2}{10}}{true}{false}.
a before Z? (case-sensitive)
\ifthenelse
{\DTLislt
{a}{Z}}{true}{false}.
a before Z? (ignore case)
\ifthenelse
{\DTLisilt
{2}{10}}{true}{false}.
$1.5 > 1$?
\ifthenelse
{\DTLisgt
{1.5}{1}}{true}{false}.
a after Z? (case-sensitive)
\ifthenelse
{\DTLisgt
{a}{Z}}{true}{false}.
a after Z? (ignore case)
\ifthenelse
{\DTLisigt
{2}{10}}{true}{false}.
2.4.2.3. List Element and Substring Conditionals Example[link]
`goose' element of list `ant,duck,goose'?
\ifthenelse
{\DTLisinlist
{goose}{ant,duck,goose}}{true}{false}.
`oo' element of list `ant,duck,goose'?
\ifthenelse
{\DTLisinlist
{oo}{ant,duck,goose}}{true}{false}.
`oo' in `goose'?
\ifthenelse
{\DTLisSubString
{goose}{oo}}{true}{false}.
`oo' in `GOOSE' (case-sensitive)?
\ifthenelse
{\DTLisSubString
{GOOSE}{oo}}{true}{false}.
`oo' in `GOOSE' (ignore case)?
\ifthenelse
{\DTLisiSubString
{GOOSE}{oo}}{true}{false}.
`go' prefix of `goose'?
\ifthenelse
{\DTLisPrefix
{goose}{go}}{true}{false}.
`go' prefix of `GOOSE' (case-sensitive)?
\ifthenelse
{\DTLisPrefix
{GOOSE}{go}}{true}{false}.
`go' prefix of `GOOSE' (ignore case)?
\ifthenelse
{\DTLisiPrefix
{GOOSE}{go}}{true}{false}.
`se' suffix of `goose'?
\ifthenelse
{\DTLisSuffix
{goose}{se}}{true}{false}.
`se' suffix of `GOOSE' (case-sensitive)?
\ifthenelse
{\DTLisSuffix
{GOOSE}{se}}{true}{false}.
`se' suffix of `GOOSE' (ignore case)?
\ifthenelse
{\DTLisiSuffix
{GOOSE}{se}}{true}{false}.
2.5. Decimal Functions[link]
dtl
” (such as \dtladd
) that are
described in §2.5.1 don’t parse for the current
decimal character and number group character or for a
currency symbol. They require a plain number, either a bare
integer (such as 12345) or a number with a decimal point (such
as 1234.5). The definition of these commands depends on the value
of the math package option.
DTL
” (such as \DTLadd
)
that are described in §2.5.2 expect
formatted numbers in the supplied values. These commands are
provided by datatool-base and use \DTLconverttodecimal
to
convert the supplied values to plain numbers.
2.5.1. Plain Numbers[link]
\directlua
, as shown in Example 4.
\dtladdall
,
will do at least one expansion. The math=l3fp and
math=lua options will fully expand ,
but the math=fp and math=pgfmath
options will only do a single expansion. This is different to most
CSV list arguments provided by datatool-base (see
§2.9). Since the list is expected to only
contain comma-separated plain numbers there should be no
expansion issues. Avoid empty elements.
\two@digits
, the may be a
decimal.
\dtlpadleadingzeros
if the value is
negative.
\dtlpadleadingzeros
if the value is
positive. Note that this expands to nothing by default. This is
because the plus (+
) character has a lower character code
than the hyphen-minus (-
) character, which would put positive
numbers before negative numbers in a character code sort.
\dtlsqrt
.
2.5.1.1. Example (l3fp)[link]
\documentclass
{article}
\usepackage
[math=l3fp]{datatool-base}
\newcommand
{\numA
}{1023.5}
\newcommand
{\numB
}{54.75000}
\newcommand
{\numC
}{-20648.68}
\newcommand
{\numlist
}{32.456,0.15,-25,48.7,92}
\begin{document}
\dtladd
{\result
}{\numA
}{\numB
}
$\numA
+ \numB
= \result
$.
\dtladd
{\result
}{\result
}{\numC
}
Add $\numC
$ to previous result.
Updated result: \result
.
\dtladdall
{\result
}{\numlist
}
Sum of all numbers in the set $\{
\numlist
\}
$: \result
.
\dtlsub
{\result
}{\numA
}{\numB
}
$\numA
- \numB
= \result
$.
\dtlsub
{\result
}{\result
}{\numC
}
Subtract $\numC
$ from previous result.
Updated result: \result
.
\dtlmul
{\result
}{\numA
}{\numB
}
$\numA
\times
\numB
= \result
$.
\dtlmul
{\result
}{\result
}{\numC
}
Multiply previous result by $\numC
$.
Updated result: \result
.
\dtldiv
{\result
}{\numA
}{\numB
}
$\numA
\div
\numB
= \result
$.
\dtldiv
{\result
}{\result
}{\numC
}
Divide previous result by $\numC
$.
Updated result: \result
.
\dtlsqrt
{\result
}{\numA
}
$\sqrt
{\numA
} = \result
$.
\dtlsqrt
{\result
}{9}
$\sqrt
{9} = \result
$.
\dtlroot
{\result
}{\numA
}{3}
$\sqrt
[3]{\numA
} = \result
$.
\dtlroot
{\result
}{8}{3}
$\sqrt
[3]{8} = \result
$.
\dtlround
{\result
}{\numB
}{1}
Round $\numB
$ to 1dp: \result
.
\dtltrunc
{\result
}{\numB
}{1}
Truncate $\numB
$ to 1dp: \result
.
\dtlclip
{\result
}{\numB
}
Clip $\numB
$: \result
.
\dtlmin
{\result
}{\numA
}{\numB
}
Minimum of $\numA
$ and $\numB
$: \result
.
\dtlminall
{\result
}{\numlist
}
Minimum value in the set $\{
\numlist
\}
$: \result
.
\dtlmax
{\result
}{\numA
}{\numB
}
Maximum of $\numA
$ and $\numB
$: \result
.
\dtlmaxall
{\result
}{\numlist
}
Maximum value in the set $\{
\numlist
\}
$: \result
.
\dtlabs
{\result
}{\numC
}
Absolute value of $\numC
$: \result
.
\dtlneg
{\result
}{\numC
}
Negate value of $\numC
$: \result
.
\dtlmeanforall
{\meanvalue
}{\numlist
}
Mean of all numbers in the set $\{
\numlist
\}
$:
\meanvalue
.
\dtlvarianceforall
[\meanvalue
]{\result
}{\numlist
}
Variance of all numbers in the set $\{
\numlist
\}
$
(using previously calculated mean): \result
.
\dtlvarianceforall
{\result
}{\numlist
}
Variance of all numbers in the set $\{
\numlist
\}
$
(not using previously calculated mean): \result
.
\dtlsdforall
[\meanvalue
]{\result
}{\numlist
}
Standard deviation of all numbers in the set
$\{
\numlist
\}
$
(using previously calculated mean): \result
.
\dtlsdforall
{\result
}{\numlist
}
Standard deviation of all numbers in the set
$\{
\numlist
\}
$
(not using previously calculated mean): \result
.
\end{document}
2.5.1.2. Example (lua)[link]
\directlua
to perform the calculations, and so requires
LuaLaTeX. The only difference to Example 37 is the
package option:
(and the need to use LuaLaTeX).
\usepackage
[math=lua]{datatool-base}
2.5.1.3. Example (fp)[link]
\usepackage
[math=fp]{datatool-base}
2.5.1.4. Example (pgfmath)[link]
! Dimension too large
Example 40 has the commands \numA
, \numB
and \numC
defined to smaller numbers. The rest of the
document is as Example 37.
Note that there are rounding errors.
\usepackage
[math=pgfmath]{datatool-base}
\newcommand
{\numA
}{10.235}
\newcommand
{\numB
}{0.5475000}
\newcommand
{\numC
}{-206.4868}
2.5.2. Formatted Numbers[link]
\DTLsetnumberchars
to set these
first. In general, if calculations are required, it’s better to
store the values as plain numbers if possible and only format
them (for example, using siunitx) when they need to be
typeset. That way the formatted values don’t need to be repeatedly parsed.
\DTLaddall
, expect a CSV list or a command with a
CSV list definition (see §2.9).
The argument isn’t fully expanded to allow for non-robust currency
symbols. Any elements that aren’t numeric will be treated as zero.
\numexpr
otherwise \dtladd
is
used. The result is stored as a formatted number in the command .
\DTLadd
but globally sets .
\DTLaddall
but globally sets .
\numexpr
otherwise \dtlsub
is used. The result is stored as a
formatted number in the command .
\DTLsub
but globally sets .
\numexpr
otherwise \dtlmul
is used. The result is stored as a
formatted number in the command .
\DTLmul
but globally sets .
\dtldiv
. The result is stored as a
formatted number in the command .
\DTLdiv
but globally sets .
\ifnum
and
\numexpr
are used to negate the number if it’s negative. If
is determined to be a decimal or currency, then
\dtlabs
is used.
\DTLabs
but globally sets .
\numexpr
is used
to negate the number. If is determined
to be a decimal or currency, then \dtlneg
is used.
\DTLneg
but globally sets .
\dtlsqrt
.
\DTLsqrt
but globally sets .
\dtlroot
. If an arbitrary root is
required for a formatted number, you will have to convert the
formatted number to a plain number with
\DTLconverttodecimal
and use \dtlroot
.
\dtlround
), and stores the result as a formatted number in
the command .
\DTLround
but globally sets .
\dtltrunc
), and stores the result as a formatted number in
the command .
\DTLtrunc
but globally sets .
\dtlclip
), and stores the
result as a formatted number in the command .
\DTLclip
but globally sets .
\ifnum
is used
otherwise \dtlmin
is used. The result is stored as a
formatted number in the command .
\DTLmin
but globally sets .
\dtlmin
). The result is stored as a
formatted number in the command .
\DTLminall
but globally sets .
\ifnum
is used
otherwise \dtlmax
is used. The result is stored as a
formatted number in the command .
\DTLmax
but globally sets .
\dtlmax
). The result is stored as a
formatted number in the command .
\DTLmaxall
but globally sets .
\DTLmeanforall
but globally sets .
\DTLvarianceforall
but globally sets .
\DTLsdforall
but globally sets .
2.6. Currency[link]
\DTLadd
parse their arguments (which are provided as
formatted numbers) to obtain the actual numerical value, which
can then be passed to commands like \dtladd
, which expect
plain number arguments. The result is then formatted to match
the dominant data type in the arguments. This means that if one or
more of the arguments is a currency value, then the result will use
the same currency symbol.
Parsing is performed using the same method as \DTLparse
.
\DTLsetup
{numeric={region-currency
=false}}
\DTLdecimaltocurrency
. The formatting of the number is
performed in the same manner as with \DTLdecimaltolocale
.
The way that the currency symbol is formatted in relation to the
formatted number depends on the currency formatting style.
First the default currency code and symbol are displayed:
\documentclass
{article}
\usepackage
{datatool-base}
Currency code:
Then a plain number is converted to a formatted currency:
\DTLCurrencyCode
.
Currency symbol: \DTLCurrencySymbol
.
This will use the current number group character and decimal character
to format the value and the current currency symbol and style to
format the currency unit.
\DTLdecimaltocurrency
{12345.678}{\formattedresult
}
Formatted: \formattedresult
.
(Numeric value: \DTLdatumvalue
{\formattedresult
}.)
\$1,234.57 add 1,236.59:
The symbol is ignored during the arithmetic computation. The result
is formatted according to the current settings.
\DTLadd
{\total
}{\$1,234.57}{1,236.59}
Total: \total
.
1,234.57 add £1,236.59:
\DTLadd
{\total
}{1,234.57}{£1,236.59}
Total: \total
.
\DTLCurrentLocaleCurrencyDP
which is
adjusted by regional support.
€48,236.59 multiplied by 0.5:
Note that the rounding only affects the formatting, not the value
stored within the datum control sequence.
\DTLmul
{\result
}{€48,236.59}{0.5}
\result
\␣(\DTLdatumvalue
{\result
}).
\DTLparse
is used to parse to
different currencies. The first has a Euro symbol:
The second has a pound symbol:
\DTLparse
\parsed
{€19,234.56}
String value: \parsed
.
Numeric value: \DTLdatumvalue
{\parsed
}.
Note that even though these symbols don’t match the current default currency
symbol, they are still recognised as currency.
\DTLparse
\parsed
{£28,342.64}
String value: \parsed
.
Numeric value: \DTLdatumvalue
{\parsed
}.
\DTLparse
\parsed
{19,234.56€}
String value: \parsed
.
Data type:
Numeric value: \DTLdatumvalue
{\parsed
}.
\DTLfmtcurrency
can be used to apply the
current formatting style to the currency symbol provided in the
first argument and the formatted number provided in the second
argument. Note that this is just a style command, and doesn’t parse
or format the value. (It’s redefined whenever the default currency
setting is changed.) This means that the following works fine even though
it’s using different number group character and decimal character
to the current default:
Formatting specific currency symbol:
The command \DTLfmtcurrency
{\texteuro
}{12.345,65}
\DTLcurrency
is simply a shortcut that uses
\DTLfmtcurrency
with the current default currency symbol:
Formatting default currency symbol:
Again, the value argument is expected to be in the correct format.
\DTLcurrency
{12 345,65}
\DTLfmtcurr
may be used to format the currency
according to the style and symbol associated with that currency code. Again,
the value argument is expected to be in the correct format:
Formatting EUR:
The “EUR” currency code is predefined by datatool-base as
it covers an number of regions (although any region that sets
“EUR” as the currency should also redefine
\DTLfmtcurr
{EUR}{12.345,65}
\DTLdefaultEURcurrencyfmt
as applicable). Other currency codes need regional
support to provide them, which will be covered in the next example.
Or if just the root language is specified, locales may be used
to add the region to the language:
\usepackage
[british]{babel}
\usepackage
{datatool-base}
In this example, I’m not using a language package so I need to use
the locales option with both the language and region in the
tag:
\usepackage
[english]{babel}
\usepackage
[locales=GB]{datatool-base}
First the default currency code and symbol are displayed:
\usepackage
[locales={en-GB}]{datatool-base}
Currency code:
As with the previous example, I can use \DTLCurrencyCode
.
Currency symbol: \DTLCurrencySymbol
.
\DTLdecimaltocurrency
to convert a plain number into formatted currency using the
current style settings:
As before, currency can be parsed.
\DTLdecimaltocurrency
{12345.678}{\formattedresult
}
Formatted: \formattedresult
.
(Numeric value: \DTLdatumvalue
{\formattedresult
}.)
The currency symbol needs to be
known but doesn’t need to be the current default. However, the
number group character and decimal character must match the current
setting.
\DTLparse
\parsed
{£28,342.64}
String value: \parsed
.
Numeric value: \DTLdatumvalue
{\parsed
}.
A region may provide its own settings. For example, the GB region
support provides different number styles: official (the
default), education (a thin space for the number group character)
or old (a mid-dot for the decimal character).
There is also an option to prefix the currency symbol with the
region code:
\DTLparse
\parsed
{€19,234.56}
String value: \parsed
.
Numeric value: \DTLdatumvalue
{\parsed
}.
This affects the formatting:
\DTLsetLocaleOptions
{GB}{
number-style=old,
currency-symbol-prefix
}
(GB settings: number-style=old,
currency-symbol-prefix=true.)
The old number style uses \DTLdecimaltocurrency
{12345.678}{\formattedresult
}
Formatted: \formattedresult
.
(Numeric value: \DTLdatumvalue
{\formattedresult
}.)
\textperiodcentered
when formatting but
allows \textperiodcentered
or a mid-dot character or a normal dot when parsing:
Note that this doesn’t round the value or format it. The formatted
string is simply parsed to determine its type, numeric value and
currency symbol.
\DTLparse
\parsed
{£28,342.648}
String value: \parsed
.
Numeric value: \DTLdatumvalue
{\parsed
}.
auto-reformat
option will make \DTLparse
automatically reformat the string value and,
since GBP supports a regional prefix, region-currency-prefix
may be used to alter the prefix format:
Note that the prefix isn’t included with the currency symbol
obtained with \DTLsetup
{
numeric={
auto-reformat
,
region-currency-prefix
=smallcaps
}
}
(Numeric settings: auto-reformat,
region-currency-prefix=smallcaps.)
\DTLdatumcurrency
.
\DTLparse
\parsed
{£28,342.648}
String value: \parsed
.
Numeric value: \DTLdatumvalue
{\parsed
}.
Currency symbol: \DTLdatumcurrency
{\parsed
}.
For the GB region, I’m going to use the “education” number
style, which uses a thin space for the number group character when
formatting. For parsing, it allows either a thin space or a normal
space:
\usepackage
[locales={en-GB,en-IE}]{datatool-base}
I’m also going to switch on the \DTLsetLocaleOptions
{GB}{ number-style = education }
auto-reformat
option:
\DTLsetup
{numeric={auto-reformat
}}
and display the currency code and symbol:
\DTLGBLocaleHook
Currency code:
Convert a plain number to a formatted currency:
\DTLCurrencyCode
.
Currency symbol: \DTLCurrencySymbol
.
Parse a formatted currency:
\DTLdecimaltocurrency
{12345.678}{\GBformattedresult
}
Formatted: \GBformattedresult
.
(Numeric value: \DTLdatumvalue
{\GBformattedresult
}.)
Parsing £12 345.67.
Since the \DTLparse
\GBparsed
{£12 345.67}
Parsed: \GBparsed
.
(Numeric value: \DTLdatumvalue
{\GBparsed
}.)
auto-reformat
option is on, the string value
will be reformatted to use a thin space, instead of the normal space
used in the original.
Note that the number group character has been changed to a comma.
The decimal character has been set to a dot, which is the same as
before.
\DTLIELocaleHook
Currency code: \DTLCurrencyCode
.
Currency symbol: \DTLCurrencySymbol
.
\DTLdecimaltocurrency
{12345.678}{\IEformattedresult
}
Formatted: \IEformattedresult
.
(Numeric value: \DTLdatumvalue
{\IEformattedresult
}.)
Parsing €12,345.67.
The package-wide settings are changed:
\DTLparse
\IEparsed
{€12,345.67}
Parsed: \IEparsed
.
(Numeric value: \DTLdatumvalue
{\IEparsed
}.)
Both the GB and IE regions support the currency-symbol-position
setting:
\DTLsetup
{numeric={currency-symbol-style
=iso}}
The datum control sequences are redisplayed:
\DTLsetLocaleOptions
{GB,IE}
{currency-symbol-position=after}
Note that although this has changed the way that the currency symbol
is formatted in relation to the value, the formatting of the value
hasn’t changed.
\begin{enumerate}
\item
\GBformattedresult
.
\item
\GBparsed
.
\item
\IEformattedresult
.
\item
\IEparsed
.
\end{enumerate}
\pounds
, \texteuro
,
\textdollar
, \textsterling
, \textyen
, \textwon
,
and \textcurrency
.
\pounds
or \$, and the argument is a
string (non-command) representation of the currency symbol, such
as £
or $
. (Note that $
will have category code “other” within the argument.)
{
. The
default is }{ }\dtlcurrdefaultfmt
(see below).
\DTLdefcurrency
:
where is the detokenized .
Additionally, \dtltexorsort
{\DTLcurrCodeOrSymOrChar
{ }{ }{ }}
{ }
\DTLdefcurrency
automatically implements:
This ensures that the parser can identify ,
and \DTLnewcurrencysymbol
{ }
\DTLnewcurrencysymbol
{ }
\DTLnewcurrencysymbol
{\DTLcurr
}
\DTLcurr
as currency symbols.
For example, the file datatool-GB.ldf (provided with
datatool-regions) includes the equivalent to:
(where \DTLdefcurrency
[\datatoolGBcurrencyfmt
]{GBP}{\pounds
}{£}
\datatoolGBcurrencyfmt
is also provided.)
This locally defines a currency identified as
GBP
, with the associated symbol \pounds
and character
alternative “£
”. It also defines the command \DTLcurrGBP
,
and adds \DTLcurrGBP
to the set of
known currencies (“£
” and \pounds
should typically already
be in the set).
So the above essentially does (where the second argument of
\dtltexorsort
has been detokenized):
As well as setting the format for the GBP currency to
\def
\DTLcurrGBP
{%
\dtltexorsort
{\DTLcurrCodeOrSymOrChar
{GBP}{\pounds
}{£}}{£}}
\DTLnewcurrencysymbol
{\pounds
}% redundant
\DTLnewcurrencysymbol
{£}
\DTLnewcurrencysymbol
{\DTLcurrGBP
}
\datatoolGBcurrencyfmt
.
\DTLdefcurrency
is:
\DTLdefcurrency
, this doesn’t perform any
category code change or expansion for the final argument.
(If expansion is needed, one of the variants may be used.)
For example, the file datatool-CA.ldf has:
\datatool_def_currency:nnnV
\datatoolCAcurrencyfmt
CAD
\$
\c_dollar_str
\dtlcurrdefaultfmt
:
\datatool_def_currency:nnnn
function.
\DTLnewcurrencysymbol
but does not remove the previous symbol from the set of known
currency symbols.
\pounds
) associated with currency
or to nothing if not defined.
Expands to the character associated with currency or to
nothing if not defined (for example, $ or £).
Expands to the detokenised string value associated with currency or to
nothing if not defined.
\DTLcurr
has been defined
for a given code, you can use:
\DTLcurr
, if defined, otherwise
it will expand to . (The datatooltk application uses
this for currency symbols when importing data that has been given an
associated currency code.)
\DTLsetdefaultcurrency
. For example:
This is done by datatool-GB.ldf in the language hook.
\DTLsetdefaultcurrency
{GBP}
\$
. (The default symbol is
for backward-compatibility, and \$
was one of the
few currency commands guaranteed to be defined when the first
version of datatool was written.)
\DTLcurrXXX
),
“XBT” (associated command \DTLcurrXBT
),
“EUR” (associated command \DTLcurrEUR
).
\dtlcurrdefaultfmt
but the “EUR” currency
is associated with:
\dtlcurrdefaultfmt
but this
makes it possible to vary the format of EUR specifically without
affecting other currencies.
\datatool_set_currency_symbol:nn
. For example:
\newfontfamily
\liberationserif
{Liberation Serif}
\NewDocumentCommand
{\bitcoin
}{}{{\liberationserif
₿}}
\ExplSyntaxOn
\datatool_set_currency_symbol:nn
{ XBT } { \bitcoin
}
\ExplSyntaxOff
\DTLCurrencySymbol
is not automatically added to
the list of known currency symbols.
\DTLsetdefaultcurrency
. Don’t redefine
placeholder commands, such as \DTLCurrencySymbol
and
\DTLCurrencyCode
.
\DTLsetdefaultcurrency
to
expand to the associated ISO code.
\DTLsetdefaultcurrency
to
expand to the associated currency formatting code
(as supplied in the optional argument of
\DTLdefcurrency
). The argument doesn’t need to
have been identified as a known currency symbol, but the
must be a formatted number with the correct
rounding that uses the current number group character and
decimal character.
\DTLfmtcurrency
just does:
\dtlcurrfmtsep
)
which tests if starts with a plus (+
)
or minus (-
) and, if so, shifts the sign in front of
the symbol and encapsulates it with:
This will convert the hyphen-minus sign (-
) to
\textminus
if not in math mode.
\dtlcurrfmtsep
)
which similarly adjusts the leading sign (if present) but in this
case puts the separator and symbol after the value.
\dtlcurrprefixfmt
and \dtlcurrsuffixfmt
use:
This expands to a space with
\DTLcurrCodeOrSymOrChar
{~
}
{\dtlcurrfmtsymsep
}
{\dtlcurrfmtsymsep
}
currency-symbol-style
=iso, otherwise to:
This should be redefined by region files.
\DTLfmtcurrency
will change its format according to the
current localisation settings, which may not be appropriate, you may prefer to use:
instead.
\DTLcurrency
{ }
The default definition of \newcommand
\datatoolGBcurrencyfmt
[2]{%
\dtlcurrprefixfmt
{\datatoolGBsymbolprefix
{GB}#1}% symbol
{#2}% value
}
\datatoolGBsymbolprefix
does
nothing, but the region provides an option to redefine this command
to \datatool_currency_symbol_region_prefix:n
.
\DTLfmtcurrency
requires the currency symbol as an
argument, which doesn’t have to be the default symbol (or even a
recognised currency symbol). If you want the default symbol without
having to specify it, you can use:
where is the default currency symbol, which is initially
\DTLfmtcurrency
{ }{ }\$
but will be changed to \DTLcurr
by
.
\DTLsetdefaultcurrency
{ }\DTLcurr
and \dtlcurrfmtsep
and
should be defined to expand to one of its arguments (ignoring the
other two). The default is to expand to . This means
that \DTLcurrency
will use the symbol command associated with the
default currency. You can redefine \DTLcurrCodeOrSymOrChar
to
expand to a different argument if you prefer.
The numeric option currency-symbol-style
redefines \DTLcurrCodeOrSymOrChar
.
\DTLdecimaltocurrency
internally uses \DTLfmtcurrency
with
the value rounded to the decimal places specified
by \DTLCurrentLocaleCurrencyDP
and formatted according to
the current number group character and decimal character. The
optional argument to \DTLdecimaltocurrency
is used in the
argument of \DTLfmtcurrency
.
\DTLcurrGBP
, \pounds
and £
are all recognised as currency symbols when parsing currency values
(although \pounds
and £
are recognised by default).
However, it’s necessary to explicitly change the default currency
for instances where the currency symbol is omitted:
Default currency:
Note that \DTLCurrencyCode
.
\DTLdecimaltocurrency
{1234.567}{\result
}
Formatted value: \result
.
£1.99:
\DTLifcurrency
{£1.99}{currency}{not currency};
\DTLfmtcurrency
{£}{1.99}:
\DTLifcurrency
{\DTLfmtcurrency
{£}{1.99}}{currency}{not currency}.
Defining GBP.
\DTLdefcurrency
{GBP}{\pounds
}{£}
Default currency: \DTLCurrencyCode
.
£1.99:
\DTLifcurrency
{£1.99}{currency}{not currency}.
Switching to GBP.\DTLsetdefaultcurrency
{GBP}
Default currency: \DTLCurrencyCode
.
\DTLdecimaltocurrency
{1234.567}{\result
}
Formatted value: \result
.
\renewcommand
{\dtlcurrdefaultfmt
}{\dtlcurrsuffixfmt
}
\renewcommand
{\DTLcurrCodeOrSymOrChar
}[3]{#1}
Formatted value: \result
.
\DTLaddall
{\result
}{\pounds
2.50,\DTLcurrGBP
1.25,£0.25}
Formatted value: \result
.
\result
is defined as a datum control sequence. This means
that the resulting command doesn’t need to be reparsed to obtain its
numerical value.
\DTLaddall
the symbol from the final currency in
the list is used (the character “£
”). So the final \result
(indirectly) expands to
.
This now shows the currency unit as a suffix
because of the redefinition of \DTLfmtcurrency
{£}{4}\dtlcurrdefaultfmt
.
2.7. Dates and Times[link]
Available options are listed below.
\DTLsetup
{ datetime={parse
=auto-reformat} }
\DTLsetup
{
datetime={
parse
=iso+region,
auto-reformat
=false,
parse
=false
}
}
.
parse
=true,
auto-reformat
=false
.
parse
=true,
auto-reformat
=true2025-01-14
(date) or 16:25:02
(time) or
2025-01-14T16:25:02
(timestamp with no offset) or
2025-01-14T16:25:02+01:00
(timestamp with offset).
parse
=iso-only
Note that regional support may simply defer to datetime2, if
it has been installed, or may just use the ISO numeric format.
See the applicable localisation documentation for further details.
For example, \DTLsetup
{datetime=auto-reformat
=true}
\renewcommand
\DataToolDateFmt
{%
\DTLCurrentLocaleFormatDate
}
\renewcommand
\DataToolTimeFmt
{%
\DTLCurrentLocaleFormatTime
}
\renewcommand
\DataToolTimeZoneFmt
{%
\DTLCurrentLocaleFormatTimeZone
}
\renewcommand
\DataToolTimeStampWithZoneFmt
{%
\DTLCurrentLocaleFormatTimeStampWithZone
}
\renewcommand
\DataToolTimeStampNoZoneFmt
{%
\DTLCurrentLocaleFormatTimeStampNoZone
}
\renewcommand
\DataToolTimeStampFmtSep
{%
\DTLCurrentLocaleTimeStampFmtSep
}
texdoc datatool-regions
Parsing off by default.
\DTLparse
\result
{2025-01-09}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLparse
\result
{2025-01-09T14:42:01}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLparse
\result
{2025-01-09T15:42:01+01:00}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLparse
\result
{14:42:01}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLsetup
{datetime={parse
}}
Parsing on.
\DTLparse
\result
{2025-01-09}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLparse
\result
{2025-01-09T14:42:01}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLparse
\result
{2025-01-09T15:42:01+01:00}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLparse
\result
{14:42:01}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\datatool_extract_timestamp:NN
, see §2.2.4.)
\usepackage
[en-GB]{datetime2}
\usepackage
{datatool-base}
\begin{document}
\DTLsetup
{datetime={parse
=auto-reformat}}
\DTLparse
\result
{2025-01-09}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLparse
\result
{2025-01-09T14:42:01}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLparse
\result
{2025-01-09T15:42:01+01:00}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\DTLparse
\result
{14:42:01}
String value: \result
.
Data type: \DTLdatumtype
{\result
}.
Value: \DTLdatumvalue
{\result
}.
\end{document}
auto-reformat
=true setting will cause commands like
\DTLparse
to replace the original string with the applicable
commands listed below. These commands will be redefined by settings
such as auto-reformat
=iso or you can redefine them
yourself.
\DataToolDateFmt
( should
be { }{ }{ }{ }), \DataToolTimeFmt
( should be { }{ }{ })
and \DataToolTimeZoneFmt
( should be { }{ }).
\DataToolTimeStampNoZoneFmt
will be
used or if is not empty
\DataToolTimeStampWithZoneFmt
will be used.
\DTLCurrentLocaleFormatTimeStampNoZone
, which may be
redefined by localisation support.
\DTLCurrentLocaleFormatTimeStampWithZone
, which may be
redefined by localisation support.
\DTLCurrentLocaleTimeStampFmtSep
.
\DTLCurrentLocaleFormatDate
, which may be
redefined by localisation support. Note that the argument
may be empty. Otherwise, all arguments must be integers.
\DTLCurrentLocaleFormatTime
, which may be
redefined by localisation support. Note that the argument
may be empty. Otherwise, all arguments must be integers.
\DTLCurrentLocaleFormatTimeZone
, which may be
redefined by localisation support. All arguments must be integers.
2.8. Strings[link]
2.8.1. Substitution and String Splitting[link]
\DTLsplitstring
but expands and once.
Note that the “oo” in \newcommand
{\test
}{The goose looked at a book and said \emph
{ooh}.}
{% local scope
Original: \test
\DTLsubstitute
{\test
}{oo}{ee}
Substituted first: \test
}
{% local scope
Original: \test
\DTLsubstituteall
{\test
}{oo}{ee}
Substituted all: \test
}
Split on `looked' (no expansion)
\DTLsplitstring
{\test
}{looked}{\before
}{\after
}
Before: `\before
'. After: `\after
'
Split on `looked' (with expansion)
\DTLxsplitstring
{\test
}{looked}{\before
}{\after
}
Before: `\before
'. After: `\after
'
\emph{ooh}
isn’t
substituted as it’s inside a group, which hides it from the search.
2.8.2. Initial Letters[link]
\DTLstoreinitials
to obtain
the initials and then displays the result.
\DTLinitials
.
-
), non-breakable spaces (~
) and space
commands \nobreakspace
and \space
are all considered word
boundaries. Words broken by an apostrophe are also detected but by
default the apostrophe and following initial are ignored. For
example, “O’Brien” will become just “O” (followed by a dot)
but it will actually be converted to:
Only the first apostrophe in the word is treated in this way. If a
word has multiple apostrophes, such as “fo’c’s’le” in the example
below, then the word will be split on the first apostrophe (“fo”,
which has the initial “f” and “c’s’le”, which has the initial
“c”). An apostrophe at the end of a word is considered trailing
punctuation.
\DTLaposinitialpunc
{O}{B}{ }
\DTLstoreinitials
uses:
\DTLGetInitialLetter
which means that the results can vary
if localisation support is provided. Ordinarily, this should produce
at least one letter, but it’s possible for \DTLStoreInitialGetLetter
to set the control sequence to expand to nothing. If this
occurs, \DTLstoreinitials
will usually skip the initial and the
following punctuation. The exception is where a word is split by an
apostrophe.
, where '
indicates the initial for and indicates the
initial for (as obtained by
\DTLStoreInitialGetLetter
), then if and are
both empty, the initials and following punctuation are omitted.
If is empty but isn’t then
is used, otherwise
(regardless of whether or not is empty)
\DTLinitialpunc
{ }{ }
is
used.
\DTLaposinitialpunc
{ }{ }{ }\DTLStoreInitialGetLetter
and the second argument
is the command that may expand to the trailing
punctuation character (see below).
. The first
argument ' is the initial for and the second argument
is the initial for . The final argument
is as for
\DTLinitialpunc
. By default this just
expands to (that is, the initial
following the apostrophe is ignored).
\DTLinitialpunc
or \DTLaposinitialpunc
.
\DTLstoreinitials
is designed for text consisting of words with
possible leading or trailing punctuation. Aside from apostrophes and
hyphens, mid-word punctuation isn’t supported. This is demonstrated
in Example 48 where the sequence “+12x,y
” is skipped.
\DTLbetweeninitials
, \DTLafterinitials
and \DTLafterinitialbeforehyphen
to do nothing or redefine \DTLinitialpunc
and \DTLaposinitialpunc
to ignore the final argument. If you want to remove the hyphen then
you need to redefine \DTLinitialhyphen
to do nothing.
\DTLGetInitialLetter
purify the
argument (that is, expand and remove
functions in ) before applying the initial letter
algorithm. With initial-purify=late, the argument
won’t be expanded until content is passed to
\DTLCurrentLocaleGetInitialLetter
(steps 3
or 4). Note that if
initial-purify=early then step 3 in the algorithm below won’t
apply since any commands will have already been stripped or
replaced.
is as follows:
\DTLGetInitialLetter
{ }{ }
See §2.8.2.2.
then will be set to
\
{ }
where is obtained from applying
\
{ }\DTLCurrentLocaleGetInitialLetter
to the argument;
\DTLCurrentLocaleGetInitialLetter
is used to obtain the first
letter of .
\DTLCurrentLocaleGetInitialLetter
as described in §2.3.
2.8.2.1. Initial Letters Example[link]
Marie
Aside from apostrophes and hyphens, mid-word punctuation isn’t supported.
The sequence “\space
Élise del~
Rosario:
\DTLinitials
{Marie\space
Élise del~
Rosario}
Élouise-Mary de Vere: \DTLinitials
{Élouise-Mary de Vere}
Mary-Jane d'Arcy: \DTLinitials
{Mary-Jane d'Arcy}
Mary-Jane d'Arcy-Lancaster:
\DTLinitials
{Mary-Jane d'Arcy-Lancaster}
Mary-Jane d'Arcy FitzGerald:
\DTLinitials
{Mary-Jane d'Arcy FitzGerald}
Niall O'Brien: \DTLinitials
{Niall O'Brien}
De'Ondre Andros: \DTLinitials
{De'Ondre Andros}
Dickie `Quack' von Duck:
\DTLinitials
{Dickie `Quack' von Duck}
+12x,y
” in the following will be skipped because
it isn’t recognised as a word.
@aardvark +12x,y fo'c's'le *zebra?:
\DTLinitials
{@aardvark +12x,y fo'c's'le *zebra?}
\DTLStoreInitialGetLetter
is then redefined to set the second
argument to empty for the given set of words: “d”, “de”, “del” and “von”.
This means that they will be omitted from the list of initials.
Skip `d', `de', `del', and `von':
The same names and words are repeated to illustrate the difference.
\renewcommand
{\DTLStoreInitialGetLetter
}[2]{%
\DTLifinlist
{#1}{d,de,del,von}{\def
#2{}}
{\DTLGetInitialLetter
{#1}{#2}}%
}
\DTLStoreInitialGetLetter
means that, for example, “d’Arcy” has the initial
“d” but this redefinition will change the initial for “d’Arcy”
to “A”. This is a better method than simply redefining
\DTLaposinitialpunc
to expand to the second argument, which
would interfere with “O’Brien” and “De’Ondre”.
2.8.2.2. Initial Letters with UTF-8 Example[link]
ábc:
Note the difference between
\DTLGetInitialLetter
{ábc}{\result
}
Initial: \result
.
{áb}c (áb grouped): \DTLGetInitialLetter
{{áb}c}{\result
}
Initial: \result
.
``ábc'': \DTLGetInitialLetter
{``ábc''}{\result
}
Initial: \result
.
``{áb}c'' (áb grouped): \DTLGetInitialLetter
{``{áb}c''}{\result
}
Initial: \result
.
{áb}c
(which satisfies step 2 of the
\DTLGetInitialLetter
algorithm) and
``{áb}c''
(which doesn’t).
2.8.2.3. Initial Letters with Commands Example[link]
Purify early.
Note that in the last case above, the formatting command
\DTLsetup
{initial-purify=early}
\'
{a}bc (accent command): \DTLGetInitialLetter
{\'
{a}bc}{\result
}
Initial: \result
.
\emph
{ábc}: \DTLGetInitialLetter
{\emph
{ábc}}{\result
}
Initial: \result
.
Purify late.\DTLsetup
{initial-purify=late}
\'
{a}bc (accent command): \DTLGetInitialLetter
{\'
{a}bc}{\result
}
Initial: \result
.
\emph
{ábc}: \DTLGetInitialLetter
{\emph
{ábc}}{\result
}
Initial: \result
.
\emph
isn’t stripped.
2.8.3. Advanced Utility Commands[link]
\ExplSyntaxOn
to change the category codes.
.
)
within .
\datatool_measure_
are simply shortcuts that use
:Nn\settowidth
, \settoheight
and \settodepth
with a hook
to disable problematic commands. That is, each command is defined to
do:
The commands \setto
{ }
\datatool_measure_ht_plus_dp:Nn
and
\datatool_measure:NNNn
are slightly more complicated, but
essentially do something similar.
\label
, \ref
and
\pageref
, makes \refstepcounter
behave like
\stepcounter
, and \hypertarget
and \hyperlink
will
simply expand to their second argument.
\l_datatool_measure_hook_tl
as applicable.
\text_map_inline:nn
and
breaking after the first iteration. Note that this may not be a
“letter” but may be a punctuation character. The is
purified before mapping.
\datatool_if_letter:nT
to test if the grapheme is a letter.
\datatool_if_letter:nTF
will do .
Ensure that is a single character stripped of all
commands and braces.
\text_lowercase:n
is capable of converting “Á” to “á”
and \text_uppercase:n
is capable of converting “á” to “Á”.
So if (which should already have been expanded and
purified) has different uppercase and lowercase
versions, it can be considered a letter.
[:alpha:]
only covers
ASCII letters. Recall also from Example 10 that
ASCII control codes or non-letter characters with the category
code set to “letter” were used to influence sorting. Since
\datatool_if_letter:nTF
was provided to assist with obtaining
letter groups from sort values, it needs to take this into account.
If this behaviour is inappropriate for your use, then use more
appropriate commands provided by LaTeX3, such as the regular
expression matching commands.
2.9. Comma-Separated Lists[link]
\dtladdall
(see
§2.5.1), \DTLaddall
(see
§2.5.2) and \DTLifinlist
(see
§2.4.1.2). Unless otherwise stated, the argument may
also be a command whose definition is a CSV list, but note that
the argument must be exactly one token (the command) with no leading spaces or trailing
tokens.
`duck' in `ant,duck,goose,zebra'?
The above is equivalent to:
\DTLifinlist
{duck}{ant,duck,goose,zebra}{true}{false}.
However, the following searches a list of one element where the sole
element consists of two tokens (a space and the command
\newcommand
{\mylist
}{ant,duck,goose,zebra}
`duck' in `\mylist
'?
\DTLifinlist
{duck}{\mylist
}{true}{false}.
\mylist
):
The following searches a list of two elements, where the first
element is \newcommand
{\mylist
}{ant,duck,goose,zebra}
`duck' in ` \mylist
'?
\DTLifinlist
{duck}{ \mylist
}{true}{false}
\mylist
and the second element is “zebu”:
\newcommand
{\mylist
}{ant,duck,goose,zebra}
`duck' in `\mylist
,zebu'?
\DTLifinlist
{duck}{\mylist
,zebu}{true}{false}.
skip-empty
and trim
,
that determine how to split the elements
in the CSV list. These apply to most CSV list arguments,
such as for \DTLaddall
and \DTLifinlist
, but not for commands
described in §2.5.1 like \dtladdall
. These
settings also don’t apply to = comma-separated list options.
Package options and options provided in \DTLsetup
are always
trimmed and skip empty elements.
\forcsvlist
, to iterate over CSV lists. For examples, see
Iterating Over a
Comma-Separated List.
2.9.1. List Settings[link]
\DTLsetup
{
lists={
trim
={false},
skip-empty
={false}
}
}
\DTLsortwordlist
and \dtlsortlist
will perform a
reverse sort.
\DTLsortwordlist
will parse
each element when it uses the handler macro at the start, storing
each element as a datum item, and will use numerical ordering for
numeric data types. Integers and decimals will be numerically
compared against each other, but the string comparison will be used if
they are compared against another data type (including currency).
Currency elements will be numerically compared if they have the same
currency symbol, otherwise the string comparison will be used.
\DTLlistand
should expand. The may
be: word (expand to \DTLandname
) or symbol
(expand to \&).
\DTLandname
will expand
to \& in which case and
=word won’t produce
any noticeable effect.
2.9.2. Formatting Lists[link]
,␣
(comma followed by a space) by default.
The final two elements are separated with:
This expands to ␣
by default.
If there are more than two items in the list,
\DTLlistand
\space
\DTLlistformatlastsep
will be preceded by \DTLlistformatoxford
which does nothing by default. If you want an Oxford comma then
redefine \DTLlistformatoxford
to a comma:
\renewcommand
{\DTLlistformatoxford
}{,}
\DTLandname
or to \&, depending on
the and
option in the lists setting.
\andname
if that command was defined when datatool-base
was loaded otherwise to \&. However \DTLandname
is
redefined by localisation support to expand to the appropriate word.
\DTLlistformatitem
to render each item
in italic:
\renewcommand
{\DTLlistformatitem
}[1]{\emph
{#1}}
One: \DTLformatlist
{elephant}.
Two: \DTLformatlist
{elephant,ant}.
Three: \DTLformatlist
{elephant,ant,zebra}.
Four: \DTLformatlist
{elephant,ant,zebra,duck}.
\renewcommand
{\DTLlistformatoxford
}{,}
Oxford comma:
\DTLformatlist
{elephant,ant,zebra,duck}.
Omit empty elements and leading/trailing spaces:
\DTLformatlist
{elephant , ant,,duck}.
\DTLsetup
{
lists={
trim
=false,
skip-empty
=false
}
}
Retain empty elements and leading/trailing spaces:
\DTLformatlist
{elephant , ant,,duck}.
2.9.3. List Elements[link]
For comparison, the closest LaTeX3 code is:
\newcommand
{\mylist
}{ant,{bee, wasp and hornet},fly}
List: \DTLformatlist
{\mylist
}.
Number of elements: \DTLnumitemsinlist
{\mylist
}{\total
}\total
.
Second element: \DTLlistelement
{\mylist
}{2}.
Fetch third element:
\DTLfetchlistelement
{\mylist
}{3}{\myelem
}\myelem
.
\LaTeX
3 List:
\ExplSyntaxOn
\clist_set:NV
\l_tmpa_clist
\mylist
\clist_use:Nnnn
\l_tmpa_clist
{ ~
and ~
} { , ~
} { , ~
and ~
}
\ExplSyntaxOff
Number of elements:
\ExplSyntaxOn
\clist_count:N
\l_tmpa_clist
.
\ExplSyntaxOff
Second element:
\ExplSyntaxOn
\clist_item:Nn
\l_tmpa_clist
{ 2 } .
\ExplSyntaxOff
Fetch third element:
\ExplSyntaxOn
\tl_set:Ne
\l_tmpa_tl
{ \clist_item:Nn
\l_tmpa_clist
{ 3 } }
\l_tmpa_tl
.
\ExplSyntaxOff
2.9.4. Adding to Lists[link]
\preto
and \appto
.
Remember to include the comma separator.
\dtlsortlist
. Predefined
comparison commands are described in §2.9.5.1.
\DTLformatlist
after each modification:
\newcommand
{\mylist
}{ant,bee}
Original list: \DTLformatlist
{\mylist
}.
\appto
\mylist
{,zebra}
Item appended: \DTLformatlist
{\mylist
}.
\preto
\mylist
{aardvark,}
Item prepended: \DTLformatlist
{\mylist
}.
\dtlinsertinto
{duck}{\mylist
}{\dtlcompare
}
Item inserted: \DTLformatlist
{\mylist
}.
2.9.5. Sorting Lists[link]
\dtlsortlist
, which requires a
comparison macro. This macro is repeatedly used to compare pairs of
elements of the list throughout the sorting process.
\DTLsortwordlist
, which requires a handler macro
that is used to convert each element of the list into a byte
sequence before sorting. The byte sequences are then compared throughout the
sorting process using a simple character code comparison.
\DTLsortwordlist
is therefore more efficient, particularly if
any localisation support is provided.
where { }{ }{ }
is a count register. If is deemed to be
less than then should set to
\(-1\), if is deemed to be greater than then
should be set to \(+1\) and if and are
deemed equal then should be set to 0. Predefined
comparison commands are described in §2.9.5.1.
\dtlsortlist
that has a
handler macro for converting the original string value of each list
element into a byte sequence. The handler macro should have the syntax:
where { }{ }
is the original value and is a token
list control sequence in which to store the byte sequence.
Predefined handlers are listed in §2.9.5.2.
\DTLsortwordlist
over \dtlsortlist
is
that with \DTLsortwordlist
all the sort values are processed
once at the start whereas with \dtlsortlist
the values are
repeatedly processed every time the comparison function is used.
The lists option sort-datum
only has an effect
with \DTLsortwordlist
. The sort-reverse
option,
which reverses the sort, governs both
\DTLsortwordlist
and \dtlsortlist
.
\dtlsortlist
and \DTLsortwordlist
change the
definition of so that it expands to the sorted list
on completion. However, with \dtlsortlist
the resulting
definition is just a comma-separated list of ordered items from the
original CSV list, but with \DTLsortwordlist
the resulting definition is a comma-separated list
of sorted elements.
where { }{ }{ }
is the original item or the datum item if
the
sort-datum
option is true, is the sort value
obtained by the handler function (regardless of the data type), and
is the letter group identifier obtained from the
via:
The letter group is assigned as follows:
Integer or Decimal
The letter group is considered a numeric group so
is defined as
where
is the numeric value. Before encapsulating with \dtlnumbergroup
{ }\dtlnumbergroup
a hook may be used to alter the argument.
This is used when has been identified as an integer.
This is used when has been identified as a decimal.
In both cases, the argument is a command that
expands to the numeric value and is the original value
passed to \DTLassignlettergroup
. These hooks do nothing by
default.
where is the currency symbol and
is the numeric value. Before encapsulating with \dtlcurrencygroup
{ }{ }\dtlcurrencygroup
a hook may be used to alter the and arguments.
\DTLassignlettergroup
. This hook does nothing by
default.
where is
obtained using \dtllettergroup
{ }\DTLCurrentLocaleGetInitialLetter
otherwise
is defined as
where is the first grapheme in the .
Before encapsulating with \dtlnonlettergroup
{ }\dtllettergroup
or
\dtlnonlettergroup
, hooks are available to alter the
.
\DTLCurrentLocaleWordHandler
.
This hook is used for a non-letter and does nothing by default.
In both cases, the is a command that expands to
.
\forcsvlist
), then
you can use the following commands on the element:
sort-datum
option was true then the actual element will
be a datum item. (That is, the format used in the expansion text of a
datum control sequence.)
\@for
to iterate over the sorted list, you will
need to expand the loop control sequence first.
\DTLsortwordlist
but not by \dtlsortlist
.
\DTLifstringgt
to
compare the original values.
\show
) in the transcript:
The transcript shows the following:
\newcommand
{\mylist
}{\pounds
2,zebu,-.25,bee,\$5,ant,duck,
+10,4.56,\$23.10,123}
\dtlsortlist
{\mylist
}{\dtlcompare
}
\show
\mylist
>
This is a simple character code sort that produces a simple
comma-separated list as the result.
\mylist
=macro:
->\pounds
2,\$23.10,\$5,+10,-.25,123,4.56,ant,bee,duck,zebu.
The result is now more complex. I’ve added line breaks for clarity
and replaced the private command for the sort element markup with
for compactness:
\newcommand
{\mylist
}{\pounds
2,zebu,-.25,bee,\$5,ant,duck,
+10,4.56,\$23.10,123}
\DTLsortwordlist
{\mylist
}{\DTLsortwordcasehandler
}
\show
\mylist
>
This produces a slightly different order: $23.10, $5, +10, -.25,
123, £2, 4.56, ant, bee, duck, zebu. The \mylist
=macro:
-> {\$23.10}{$23.10}{\dtlnonlettergroup
{$}},
{\$5}{$5}{\dtlnonlettergroup
{$}},
{+10}{+10}{\dtlnonlettergroup
{+}},
{-.25}{-.25}{\dtlnonlettergroup
{-}},
{123}{123}{\dtlnonlettergroup
{1}},
{\pounds
2}{2}{\dtlnonlettergroup
{2}},
{4.56}{4.56}{\dtlnonlettergroup
{4}},
{ant}{ant}{\dtllettergroup
{a}},
{bee}{bee}{\dtllettergroup
{b}},
{duck}{duck}{\dtllettergroup
{d}},
{zebu}{zebu}{\dtllettergroup
{z}}.
\pounds
command
is stripped by the handler as it is unable to
expand to just text. Whereas the \$
command is converted to the detokenized $
by the sort
hook (see §2.9.5.3). Note that the currency
and numbers have all been assigned to the non-letter group.
\dtlcompare
is
\DTLsortwordcasehandler
(used above). The closest match to the
case-insensitive \dtlicompare
is \DTLsortwordhandler
.
If the above example was switched to \DTLsortlettercasehandler
or \DTLsortletterhandler
, the hyphen/minus character -
would be stripped from -.25
, resulting in a sort value of
.25
.
-.25
(a string containing four characters) and
-0.25
(a string containing five characters) or between +10
and 10
.
A simple character code comparison will place +10
before
-.25
(since the plus character “+
” has a lower codepoint
value than the hyphen/minus character “-
”).
sort-datum
option to true adds an extra
level of complexity in the result, but creates a different order
because the numbers can now be compared numerically:
\DTLsetup
{lists={sort-datum
={true}}}
\newcommand
{\mylist
}{\pounds
2,zebu,-.25,bee,\$5,ant,duck,
+10,4.56,\$23.10,123}
\DTLsortwordlist
{\mylist
}{\DTLsortwordcasehandler
}
\show
\mylist
>
This expands to a different order: $5, $23.10, -.25, 4.56, +10,
123, £2, ant, bee, duck, zebu. Note that the numeric values
have been split into different sub-groups: currency and number. The
dollar $ currency is placed before the numbers because a string comparison
is used between a currency numeric value and non-currency number.
For example, 4.56 and 123 are compared numerically, so 4.56 is
placed before 123, but $23.10 and +10 are compared
lexicographically.
\mylist
=macro:
-> { {\$5}{5}{\$}{3}}{$5}{\dtlcurrencygroup
{\$}{5}},
{ {\$23.10}{23.10}{\$}{3}}{$23.10}{\dtlcurrencygroup
{\$}{23.10}},
{ {-.25}{-0.25}{}{2}}{-.25}{\dtlnumbergroup
{-0.25}},
{ {4.56}{4.56}{}{2}}{4.56}{\dtlnumbergroup
{4.56}},
{ {+10}{10}{}{1}}{+10}{\dtlnumbergroup
{10}},
{ {123}{123}{}{1}}{123}{\dtlnumbergroup
{123}},
{ {\pounds
2}{2}{\pounds
}{3}}{2}{\dtlcurrencygroup
{\pounds
}{2}},
{ {ant}{}{}{0}}{ant}{\dtllettergroup
{a}},
{ {bee}{}{}{0}}{bee}{\dtllettergroup
{b}},
{ {duck}{}{}{0}}{duck}{\dtllettergroup
{d}},
{ {zebu}{}{}{0}}{zebu}{\dtllettergroup
{z}}.
item has been correctly
parsed as currency, but the string sort value ends up as just
\pounds
22
as a result of stripping \pounds
. Since 123 isn’t
currency but \pounds
2 is, the values are compared lexicography
instead of numerically, which means comparing the string “123”
with the string “2”. The best solution is to provide a local
redefinition of \pounds
:
This is done automatically by datatool-GB.ldf and other localisation files
that support pound sterling currency (see §2.3.5).
Adding localisation support, for example:
\dtlSortWordCommands
{\def
\pounds
{£}}
results in a different order: -.25, +10, $5, $23.10, £2,
4.56, 123, ant, bee, duck, zebu.
\usepackage
[locales=en-GB]{datatool-base}
\DTLCurrentLocaleGetGroupString
if using the “actual” argument.
2.9.5.1. Comparison Commands[link]
\dtlsortlist
,
\dtlinsertinto
, and \dtlsort
. For \DTLsortwordlist
and \DTLsortdata
handler functions, see
§2.9.5.2.
In each case, the syntax is:
where { }{ }{ }
is a count register (integer variable). If
is deemed to be less than (comes before) then will set
to \(-1\), if is deemed to be greater than (comes
after) then is set to \(+1\) and if and
are deemed equal then is set to 0.
Note that the handler’s notion of equality doesn’t necessarily mean
the two arguments are identical. For example, a case-insensitive comparison will consider
“word” and “Word” as equal, and
\DTLnumcompare
will consider
\$1,234.50
and 1234.5
to be equal, since only the numerical
values are compared.
\DTLsortletterhandler
as that also discards hyphens.)
\DTLsortwordhandler
is used to convert both strings
to byte sequences, which are then compared. It’s therefore more
efficient to use \DTLsortwordlist
to avoid repeatedly
converting the same strings to byte sequences.
\dtlletterindexcompare
but spaces aren’t stripped from the
strings so, for example, “sea lion” will come before “sealant”.
\dtlletterindexcompare
and \dtlwordindexcompare
use \DTLsortwordhandler
, they are sensitive to the current
language provided that a suitable language module has been
installed (see §2.3 for more details and
Example 61 for an example). This does not
apply to the simple character code commands \dtlcompare
and
\dtlicompare
.
\DTLifstringlt
, \DTLifstringeq
and \DTLifstringgt
for a case-sensitive comparison.
If you are using \DTLsortwordlist
, the closest matching handler is
\DTLsortwordcasehandler
. However \dtlcompare
has no
localisation support and just performs a character code comparison.
\DTLifstringlt*
, \DTLifstringeq*
and
\DTLifstringgt*
for a case-insensitive comparison.
If you are using \DTLsortwordlist
, the closest matching handler is
\DTLsortwordhandler
. However \dtlicompare
has no
localisation support and just performs a character code comparison
(after converting the strings to lowercase).
\DTLsetup
{ compare={expand-cs
=true} }
\dtlcompare
and \dtlicompare
(but not the other comparison
commands) are governed by the expand-cs
boolean option. When used
with \dtlcompare
or \dtlicompare
: if true, and
will be fully expanded and purified before
comparison. If false, the following boolean option takes effect:
\dtlcompare
or \dtlicompare
where
expand-cs
=false:
if skip-cs
=true, any commands found in
or will be replaced with the control
code 0x0A (newline). This means that a command is considered
lexicographically smaller than punctuation, digits and letters. If
false, all commands will be removed. This conditional has no effect
if expand-cs
=true.
2.9.5.2.
\DTLsortwordlist
Handlers[link]\DTLsortwordlist
and may also be used as the
function
in \DTLsortdata
. In each case,
is the original string and is a control
sequence that will be defined to the resulting sort value (which
will then be treated as a byte sequence).
\DTLDefaultLocaleWordHandler
and
purifies the result. This means that it’s sensitive
to the current language provided that a suitable language
module has been installed (see §2.3 for
more details and Example 61 for an example).
\DTLDefaultLocaleWordHandler
and purifies the result.
\DTLsortwordhandler
but discards hyphens and spaces.
\DTLsortwordcasehandler
but discards hyphens and spaces.
to convert
to a byte sequence that ensures the locale’s alphabetic ordering,
and then appends \DTLCurrentLocaleWordHandler
{ }\datatoolctrlboundary
to .
If you don’t require the boundary marker, you can redefine this command to
just use the current locale handler:
\renewcommand
{\DTLDefaultLocaleWordHandler
}[1]{%
\DTLCurrentLocaleWordHandler
{#1}%
}
2.9.5.3. Word Sort Hook[link]
\dtlwordindexcompare
and \dtlletterindexcompare
is also used at the start of \DTLsortwordlist
. This means that
the hook is applied only once with an instance of
\DTLsortwordlist
, but with \dtlsortlist
the hook is
applied each time a comparison is required by
\dtlwordindexcompare
or \dtlletterindexcompare
.
Therefore, it you want word or letter sorting, it’s better to use
the newer \DTLsortwordlist
with \DTLsortwordhandler
or
\DTLsortletterhandler
.
\DTLsortwordlist
it expands to its second argument instead.
You may recall from §2.6 that \DTLdefcurrency
defines \DTLcurr
to use \dtltexorsort
in its argument.
This allows the currency symbol to expand to a string representation
within \DTLsortwordlist
, \dtlwordindexcompare
or \dtlletterindexcompare
.
\DTLDefaultLocaleWordHandler
.
,
normally. The hook redefines
this command to the character 0x1C. For example,
\space
Kunth
\datatoolpersoncomma
Donald E.
,
normally. The hook redefines
this command to the character 0x1D. For example:
\space
Paris
\datatoolplacecomma
Texas
,
normally. The hook redefines
this command to the character 0x1E. For example:
\space
New York
\datatoolsubjectcomma
population
.
The hook redefines \space
( )\datatoolparen
to expand to
\datatoolctrlboundary
, ignoring the argument. For example:
duck
This means that the parenthetical content is omitted in the
comparison. Note that this will cause the following
terms to be considered identical:
\datatoolparen
{wildfowl}
duck
With \datatoolparen
{wildfowl}
duck\datatoolparen
{cricket}
\DTLsortwordlist
, this is addressed by the default
definition of \dtlfallbackaction
which will compare the
duplicate values using the original definition of \datatoolparen
.
Note that since \DTLDefaultLocaleWordHandler
appends
\datatoolctrlboundary
to all values, “duck” will become
“duck” followed by 0x1F and
duck
will become
“duck” followed by 0x1F 0x1F. The first control character is inserted by
\datatoolparen
{ }\datatoolparen
and the second by
\DTLDefaultLocaleWordHandler
. This means that the parenthetical
entries will come after the word on its own, and the word on its own
will come after the word followed by one of the comma markers.
\dtlsortlist
is to mark
where the parenthetical material starts:
\space
normally. The parenthesis characters
need to be added explicitly. The hook redefines
this command to expand to the character 0x1F. For example:
duck
In this case, the parenthetical content is included in the
comparison.
\datatoolparenstart
(cricket)
\datatoolctrlboundary
and \datatoolparenstart
have the same definition within the hook but expand differently in
normal text.
\pounds
is set to
\l_datatool_pound_str
.
\nobreakspace
and \␣ to
\space
, \TeX
and \LaTeX
are locally redefined to
simply expand to “TeX” and “LaTeX”, respectively, and the
following commands are locally redefined to expand
to the corresponding detokenized character: \$
($
), \_ (_
), \#
(#
), \% (%
), and \&
(&
).
@
character has the letter category code, which means that
you can use internal @
-commands in (see
Example 62).
If you need to use control codes, make sure that you
first (locally) change the category code to “other” before using
them in the hook.
2.9.5.4. CSV List Sorting Examples[link]
2.9.5.4.1. Sorting with
\dtlsortlist
[link]
The sorted order varies depending on whether or not the sort method is
case-sensitive or strips spaces. (See
Example 59 for a UTF-8 example.)
\newcommand
{\mylist
}{sea, sea lion, Sealyham, seal,
sealant, sealing wax}
\dtlsortlist
with
\dtlcompare
(case-sensitive) and then with \dtlicompare
(case-insensitive). Note that case-sensitive sorting places the
uppercase characters before the lowercase characters
(so Sealyham comes first with \dtlcompare
and last with
\dtlicompare
). In both cases, “sea lion” is placed before
“sealing wax” (that is, the space is significant).
\dtlsortlist
{\mylist
}{\dtlcompare
}
Case-sensitive: \DTLformatlist
{\mylist
}.
\dtlsortlist
{\mylist
}{\dtlicompare
}
Case-insensitive: \DTLformatlist
{\mylist
}.
\dtlletterindexcompare
(letter sort) and
\dtlwordindexcompare
(word sort) instead. The order for both
is case-insensitive (so Sealyham comes last), but the letter order
method puts “sea lion” after “sealing wax” (spaces are
discarded, “o” comes after “n”) whereas the word order method
puts “sea lion” before “seal” (the space is significant,
“l” comes after space).
2.9.5.4.2. Sort Markers[link]
\dtlcompare
and
\dtlicompare
are governed by the skip-cs
and
expand-cs
options within the compare setting. If both
options are false, any commands found in the sort value, including the marker
commands, are replaced with the character code 0x0A. If
skip-cs
=true (and expand-cs
=false) then the
marker commands will be stripped. If expand-cs
=true, then the
skip-cs
setting is ignored and the marker commands will
expand to their usual meaning (not the meaning provided by
the word sort hook). I’ve used expand-cs
=true to ensure the
marker commands are expanded.
\dtlcompare
, which would put the
elements starting with “Duck” at the beginning, but would
otherwise use the same relative order as \dtlicompare
.
Note that there is one element that has normal commas (“Duck,
Duck, Goose”). This requires braces to hide the commas from the list
parser. The other commas are hidden in the marker commands:
\newcommand
{\mylist
}{duckling,
Duck\datatoolplacecomma
Mallard County,
Duck\datatoolpersoncomma
Robbie,
Duck\datatoolsubjectcomma
Anatomy of a,
duck\datatoolparenstart
(cricket),
duck\datatoolparen
{verb},
{Duck, Duck, Goose},
duck soup, duck, duck and dive
}
\datatoolpersoncomma
(to signify ,
), \datatoolsubjectcomma
(heading inversion), and
\datatoolplacecomma
(to signify a place). The above example
uses two different ways of marking parenthetical material,
\datatoolparenstart
and \datatoolparen
. This affects
sorting.
\DTLformatlist
to insert line breaks.
This means that the only commas shown are those within the elements.
I’ve used grouping to localise the changes, which ensures that each
sort starts from the same list.
\renewcommand
{\DTLlistformatsep
}{\newline
}
\renewcommand
{\DTLlistformatlastsep
}{\newline
}
\DTLsetup
{compare={expand-cs
=true}}
\begin{multicols}
{3}
{\dtlsortlist
{\mylist
}{\dtlicompare
}
Case-insensitive:\newline
\DTLformatlist
{\mylist
}.}
{\dtlsortlist
{\mylist
}{\dtlwordindexcompare
}
Word sort:\newline
\DTLformatlist
{\mylist
}.}
\dtlsortlist
{\mylist
}{\dtlletterindexcompare
}
Letter sort:\newline
\DTLformatlist
{\mylist
}.
\end{multicols}
\dtlicompare
) doesn’t recognise any
difference between explicit commas and the commas within the marker
commands, so “Duck, Duck, Goose” is placed between “Duck, Anatomy of a”
and “Duck, Mallard County”. Sorting by character code orders
the space character 0x20 before the comma character 0x2C, so “duck
soup” is placed before “Duck, Anatomy of a”.
\datatoolparen
(which inserts
0x1F and discards its argument) and \datatoolparenstart
(which inserts 0x1F). This means that “(verb)” is omitted
from the comparison but “(cricket)” isn’t, so “duck (verb)”
ends up before “duck (cricket)”.
\DTLsortwordlist
, but
there’s no equivalent to the \dtlicompare
handler:
{
I’ve also supplied my own custom handler that first strips explicit
commas and then behaves like \DTLsortwordlist
{\mylist
}{\DTLsortwordhandler
}
Word sort:\newline
\DTLformatlist
{\mylist
}.}
{\DTLsortwordlist
{\mylist
}{\DTLsortletterhandler
}
Letter sort:\newline
\DTLformatlist
{\mylist
}.}
\DTLsortletterhandler
:
\ExplSyntaxOn
\NewDocumentCommand
\mycustomhandler
{ m m }
{
\tl_set:Nn
#2 { #1 }
\regex_replace_all:nnN
{ , } { } #2
\DTLsortletterhandler
{ #2 } #2
}
\ExplSyntaxOff
\DTLsortwordlist
{\mylist
}{\mycustomhandler
}
Custom sort:\newline
\DTLformatlist
{\mylist
}.
2.9.5.4.3. UTF-8[link]
\dtlcompare
or \dtlicompare
for UTF-8
values are less satisfactory. The list for
Examples 59, 60 & 61
is defined as:
XeLaTeX and LuaLaTeX both natively support UTF-8. Modern
pdfLaTeX now defaults to UTF-8 but if you want to use
inputenc remember to load it before datatool-base:
\newcommand
{\mylist
}{elk, Æthelstan, Arnulf, elf,résumé,
Óslác, élan, Aeolus, resume, elephant, zygote, élite,
Valkyrie, Zulu, elbow, Adelolf, rose}
\usepackage
[utf8]{inputenc}
\usepackage
{datatool-base}
\dtlsortlist
as for the earlier
Example 55:
Note that the UTF-8 characters are all placed after the Basic
Latin characters, so “Æthelstan” is placed after “zygote” for
both the case-sensitive and case-insensitive comparators. However,
“Æthelstan” and “Óslác” come before “élan” and “élite”
for the case-sensitive sort. Whereas for the case-insensitive sort,
“Óslác” comes after “élite”.
\dtlsortlist
{\mylist
}{\dtlcompare
}
Case-sensitive: \DTLformatlist
{\mylist
}.
\dtlsortlist
{\mylist
}{\dtlicompare
}
Case-insensitive: \DTLformatlist
{\mylist
}.
\dtlletterindexcompare
and \dtlwordindexcompare
both internally use \DTLsortwordhandler
, they are able to
handle UTF-8 in the same way as using \DTLsortwordlist
with the handler macros described in §2.9.5.2.
However, it’s more efficient to use \DTLsortwordlist
to avoid
repeatedly pre-processing the values.
\DTLsortwordlist
instead of \dtlsortlist
.
Note that the UTF-8 characters are still listed after the Basic
Latin characters when there is no localisation support. So the
result is the same as before.
\DTLsortwordlist
{\mylist
}{\DTLsortlettercasehandler
}
Case-sensitive sort: \DTLformatlist
{\mylist
}.
\DTLsortwordlist
{\mylist
}{\DTLsortletterhandler
}
Case-insensitive sort: \DTLformatlist
{\mylist
}.
Or:
\documentclass
[en-GB]{article}
This produces a better order because the datatool-english-utf8.ldf file
substitutes common UTF-8 characters for the closest ASCII
equivalent (“Æ” for “AE”, “Ó” for “O”, “á” for
“a”, and “é” for “e”). This means that “Æthelstan” is
now at the start before “Adelolf” (because “AE” comes before “Ad”)
for the case-sensitive sort but between “Aeolus” and “Arnulf”
for the case-insensitive sort.
\usepackage
[locales=en-GB]{datatool-base}
\DTLsortwordlist
, the relative ordering of
these duplicates is then determined by \dtlfallbackaction
, which by default
compares the original values with \DTLifstringgt
. Since the
unstarred \DTLifstringgt
internally uses \dtlcompare
without localisation, this places “resume” before “résumé”.
\dtlsortlist
doesn’t use \dtlfallbackaction
so “résumé” and “resume” are deemed equivalent with
\dtlwordindexcompare
\dtlletterindexcompare
so the result
with \dtlsortlist
would retain their original relative order.
2.9.5.4.4. Roman Numerals[link]
Ordinarily this custom \newcommand
{\mylist
}{John XVI,John VI,
John XIX, John IX, John IV,John VII, John V}
\DTLsortwordlist
{\mylist
}{\DTLsortwordhandler
}
\DTLformatlist
\mylist
.
\newcommand
{\Ord
}[1]{\MakeUppercase
{\romannumeral
#1}}
\dtlSortWordCommands
{\renewcommand
\Ord
[1]{\two@digits
{#1}}}
\renewcommand
\mylist
{John \Ord
{16},John \Ord
{6},
John \Ord
{19}, John \Ord
{9}, John \Ord
{4},John \Ord
{7},
John \Ord
{5}}
\DTLsortwordlist
{\mylist
}{\DTLsortwordhandler
}
\DTLformatlist
\mylist
.
\Ord
command will convert its numeric
argument into an uppercase Roman numeral (for example,
\Ord{16}
would expand to “XVI”), but when sorting it
expands to a number instead (for example, \Ord{16}
would expand to “16”).
\two@digits
that zero-pads the number to ensure
that it has at least two digits (for example,
\Ord{6}
would expand to “06”). This is because lexicographic
ordering rather than numeric ordering is used (otherwise “16”
would come before “6”). If large ordinals are
expected then extra padding would be required (which can
be obtained with \dtlpadleadingzeros
).
3. Databases (datatool package)[link]
\DTLwrite
in
a graphical interface or import data from a SQL database,
a CSV file or a probsoln dataset.
3.1. Options[link]
\DTLsetup
, and some may be
used in either context.
\DTLsetup
, this
sets the default database name for commands where the name is
optional (such as \DTLaction
and \DTLwrite
). Note that
the argument is expanded when the option is set.
For example:
In the above, the default database name remains “mydata” after
\newcommand
{\mydatacmd
}{mydata}
\DTLsetup
{default-name=\mydatacmd
}
\renewcommand
{\mydatacmd
}{otherdata}
\mydatacmd
is redefined.
\DTLsetdelimiter
to
set the delimiter. Alternatively, you can use the delimiter
setting within the optional argument of \DTLread
or
\DTLwrite
or within the value of the io option in
\DTLsetup
. For example:
% Package option:
\usepackage
[delimiter={'}]{datatool}
% Change default:
\DTLsetdelimiter
{|}
% Or:
\DTLsetup
{io={delimiter
={|}}}
% Override the default just for this file:
\DTLread
[format
=csv,delimiter
={"}]{myfile}
expand-value
or
expand-once-value
when adding an entry to a database with the
new entry
action.
In the above, the entry will be added to the database as
\newcommand
{\qt
}[1]{``#1''}
\DTLsetup
{new-value-expand=true}
\DTLnewdbentry
{mydata}{Name}{Zoë \qt
{Stripes} Zebra}
Zoë ``Stripes'' Zebra
. This means that if the definition of
\qt
is later changed, it won’t affect this entry. In this
particular case, it’s better to have the default
new-value-expand=false setting to prevent expansion (or
use robust commands).
In the first case, the placeholder command ends up in the database
entry, which means it’s susceptible to the changing definition of
that command. This means that every entry ends up with the same
value. (If I hadn’t redefined \makeatletter
\DTLsetup
{new-value-expand=false}
\DTLnewdb
{test1}
\DTLaddcolumnwithheader
{test1}{entry}{Entry (Not Expanded)}
\@for
\myentry
:=ant,bee,duck,zebra\do
{
\DTLnewrow
{test1}
\DTLnewdbentry
{test1}{entry}{\myentry
}
}
\DTLsetup
{new-value-expand=true}
\DTLnewdb
{test2}
\DTLaddcolumnwithheader
{test1}{entry}{Entry (Expanded)}
\@for
\myentry
:=ant,bee,duck,zebra\do
{
\DTLnewrow
{test2}
\DTLnewdbentry
{test2}{entry}{\myentry
}
}
\makeatother
\renewcommand
{\myentry
}{Unknown!}
\DTLdisplaydb
{test1}
\DTLdisplaydb
{test2}
\myentry
after the \@for
loop it would have resulted in the “Undefined control sequence”
error as at the end of the loop \myentry
is \@nil
,
which is an undefined marker).
\myentry
is
expanded before the entry is added to the database.
expand
option affects this setting. For
example:
This is equivalent to:
\DTLsetup
{ io={expand
=protected} }
This means that:
\DTLsetup
{
io={expand
=protected},
new-value-expand=true
}
is a convenient shortcut for:
\DTLread
[expand
=protected]{filename}
{
\DTLsetup
{new-value-expand=true}% local change
\DTLread
{filename}% where the file contains LaTeX commands
}
trim
option
provided by the base package.
new entry
action will always be
trimmed due to the automated trimming of the = interface.
However, if you specifically want leading or trailing spaces, you
will need both
(that is, group the value and put the spaces inside the group).
\DTLsetup
{new-value-trim=false}
and
\DTLaction
[value
={ ,…]{ }new entry
}
The spaces can be shown by modifying the string formatting command
to enclose the value in double-quotes:
\DTLnewdb
{mydata}
\DTLnewrow
{mydata}
\DTLsetup
{new-value-trim=true}
\DTLnewdbentry
{mydata}{Column1}{ value1 }
\DTLnewrow
{mydata}
\DTLsetup
{new-value-trim=false}
\DTLnewdbentry
{mydata}{Column1}{ value2 }
% compare with \DTLaction
:
\DTLsetup
{default-name=mydata}
\DTLaction
{new row
}
\DTLaction
[column
=1,value
= value3 ]{new entry
}
\DTLaction
{new row
}
\DTLaction
[column
=1,value
={ value4 }]{new entry
}
\renewcommand
{\dtlstringformat
}[1]{``#1''}
\DTLdisplaydb
{mydata}
\DTLread
and
\DTLwrite
, which are described in
§3.15.2.
\DTLsetseparator
to set the separator.
Alternatively, you can use the separator
setting
within the optional argument of \DTLread
or \DTLwrite
or
within the value of io option in \DTLsetup
.
format
=tsv (in
the io option) or with \DTLsettabseparator
.
% Set the default separator to ;
\usepackage
[separator=;]{datatool}
% Set the default separator to |
\DTLsetup
{ io={separator
=|} }
% Load a CSV file with the separator :
\DTLread
[ format
=csv, separator
={:} ]{file-1}
% Load a TSV file with the tab separator
\DTLread
[ format
=tsv ]{file-2}
format
=dbtex-3, as that’s the only format to support
datum items.
3.2. Example Databases[link]
\DTLaction
. Some databases are loaded from a CSV
file, which is the more common way of loading data, but the
self-contained example documents need to create the required
CSV file. This is done using the filecontents
environment, except for the examples with a TSV
file, which needs to have the tab character preserved.
3.2.1. Student Marks (CSV)[link]
Surname,Forename,StudentNo,Assign1,Assign2,Assign3
"Smith, Jr",John,102689,68,57,72
"Brown",Jane,102647,75,84,80
"Brown",Jane,102646,64,92,79
"Brown",Andy,103569,42,52,54
"Adams",Zoë,105987,52,48,57
"Brady",Roger,106872,68,60,62
"Verdon",Clare,104356,45,50,48
The data can be loaded with:
Alternatively, you can setup the default database name first, to
avoid having to repeatedly specify it. Since the data contains
numeric values that may need to be parsed, it’s also useful to
switch on the store-datum option to reduce parsing:
\DTLread
[name
=marks]{studentmarks.csv}
Note that this assumes the default settings for \DTLsetup
{store-datum,default-name=marks}
\DTLread
{studentmarks.csv}
\DTLread
:
\DTLread
[format
=csv,csv-content
=literal]{studentmarks.csv}
3.2.2. Student Scores[link]
\DTLsetup
{store-datum,default-name=scores}
% define database:
\DTLaction
{new
}
% add columns in desired order:
\DTLaction
[key
=forename,value
={First
Name}]{add column
}
\DTLaction
[key
=surname,value
={Surname}]{add column
}
\DTLaction
[key
=regnum,value
={Student
Number}]{add column
}
\DTLaction
[key
=gender]{add column
}
\DTLaction
[key
=parent]{add column
}
\DTLaction
[key
=score,value
={Score (\%)}]{add column
}
\DTLaction
[key
=award]{add column
}
% 1st row:
\DTLaction
[
assign
={
forename = Jane,
surname = Brown,
regnum = 102647,
score = 75,
award = {\$1,830},
gender = F, parent = {Ms Brown}
}
]{new row
}
% 2nd row:
\DTLaction
[
assign
={
forename = John,
surname = {Smith, Jr},
regnum = 102689,
score = 68,
award = {\$1,560},
gender = M, parent = {Mr and Mrs Smith}
}
]{new row
}
% 3rd row:
\DTLaction
[
assign
={
forename = Quinn,
surname = Ó Coinn,
regnum = 103294,
score = 91,
award = {\$3,280},
parent = {Mr and Mrs Ó Coinn}
}
]{new row
}
% 4th row:
\DTLaction
[
assign
={
forename = Evelyn,
surname = O'Leary,
regnum = 107569,
score = 81.5,
award = {\$2,460},
gender = n, parent = {Prof O'Leary}
}
]{new row
}
% 5th row:
\DTLaction
[
assign
={
forename = Zoë,
surname = Adams,
regnum = 105987,
score = 52,
award = {\$1,250},
gender = f, parent = {Mr and Mrs Adams}
}
]{new row
}
% 6th row:
\DTLaction
[
assign
={
forename = Clare,
surname = Vernon,
regnum = 104356,
score = 45,
award = {\$500},
gender = Female, parent = {Mr Vernon}
}
]{new row
}
% 7th row:
\DTLaction
[
assign
={
forename = Roger,
surname = Brady,
regnum = 106872,
score = 58,
award = {\$1,350},
gender = m, parent = {Dr Brady and Dr Mady}
}
]{new row
}
% 8th row:
\DTLaction
[
assign
={
forename = Andy,
surname = Brown,
regnum = 103569,
score = 42,
award = {\$980},
gender = male, parent = {Mr Brown and Prof Sepia}
}
]{new row
}
[fontupper=]
forename,surname,regnum,gender,parent,score,award
Jane,Brown,102647,F,Ms Brown,75,"$1,830"
John,"Smith, Jr",102689,M,Mr and Mrs Smith,68,"$1,560"
Quinn,Ó Coinn,103294,,Mrs and Mrs Ó Coinn,91,"$3,280"
Evelyn,"O’Leary",n,Prof O’Leary,107569,81.5,"$2,460"
Zoë,Adams,105987,f,Mr and Mrs Adams,52,"$1,250"
Clare,Vernon,104356,f,Mr Vernon,45,"$500"
Roger,Brady,106872,m,Dr Brady and Dr Mady,58,"$1,350"
Andy,Brown,103569,m,Mr Brown and Prof Sepia,42,"$980"
However, the CSV format doesn’t support missing mid-row values
so the missing gender field for Quinn is now empty. This will make a
difference if you display the data or test for null but not empty (see
§3.10).
Note that if the dollar symbols (\DTLsetup
{store-datum,default-name=scores}
\DTLread
[ format
=csv, csv-content
=literal,
headers
={ First Name, Surname, Student Number,
gender, parent, Score (\%), award }
]{studentscores.csv}
$
) in the file are
replaced with LaTeX markup (\$), then you will need
csv-content
=tex instead of
csv-content
=literal.
3.2.3. Customers[link]
[fontupper=]Id,Organisation,Surname,Forename,Email,Age
1,,Parrot,Polly,pp@example.com,42
2,University of Somewhere,Canary,Mabel,mc@example.com
3,University of Somewhere,Zebra,Zoë,zz@example.com,21
4,Zinnia Florestry,Arara,José,ja@example.com,42
5,,Duck,Dickie,dd@example.com,
6,Newt Fellowship,Axolotl,Lizzie,la@example.com
7,Avian Emporium,Canary,Fred,fc@example.com,19
8,Newt Fellowship,,Molgina,m@example.com
9,,Mander,Sally
10,Élite Emporium,Fant,Eli,ef@example.com,101
The data can be loaded with:
Alternatively, you can setup the default database name first, to
avoid having to repeatedly specify it.
Since the data contains numeric values that may need to be parsed,
it’s also useful to switch on the store-datum option to reduce
parsing.
\DTLread
[name
=customers]{customers.csv}
Note that this assumes the default settings for \DTLsetup
{store-datum,default-name=customers}
\DTLread
{customers.csv}
\DTLread
:
Null values can only occur with data loaded from a CSV file
when final columns are missing. In this case, the Age column is the last
column and is not set in some rows. For example, there’s no comma
following Lizzie so Lizzie’s age will be null. Compare this with the
previous row where Dickie Duck has no age but there is a trailing
comma. This will set Dickie Duck’s age to empty. In the case of
Sally Mander, both the Email and Age columns are missing. Since they
are final columns both the email and age are null.
\DTLread
[format
=csv,csv-content
=literal]{customers.csv}
\DTLsetup
{default-name=customers}
% define database:
\DTLaction
{new
}
% add columns in desired order:
\DTLaction
[key
=Id]{add column
}
\DTLaction
[key
=Organisation]{add column
}
\DTLaction
[key
=Surname]{add column
}
\DTLaction
[key
=Forename]{add column
}
\DTLaction
[key
=Email]{add column
}
\DTLaction
[key
=Age]{add column
}
% 1st row:
\DTLaction
[
assign
={
% Organisation not set
Id = 1, Email = pp@example.com,
Surname = {Parrot}, Forename = {Polly}, Age = 42
}
]{new row
}
% 2nd row:
\DTLaction
[
assign
={
% Age not set
Id = 2, Organisation = {University of Somewhere},
Email = mc@example.com,
Surname = {Canary},
Forename = {Mabel}
}
]{new row
}
% 3rd row:
\DTLaction
[
assign
={
Id = 3, Organisation = {University of Somewhere},
Age = 21,
Email = zz@example.com,
Surname = {Zebra},
Forename = {Zoë}
}
]{new row
}
% 4th row:
\DTLaction
[
assign
={
Id = 4, Organisation = {Zinnia Florestry}, Age = 42,
Email = ja@example.com,
Surname = {Arara},
Forename = {José}
}
]{new row
}
% 5th row:
\DTLaction
[
assign
={
% Organisation and Age not set
Id = 5, Surname = {Duck}, Forename = {Dickie},
Email = dd@example.com
}
]{new row
}
% 6th row:
\DTLaction
[
assign
={
% Age not set
Id = 6, Organisation = {Newt Fellowship},
Email = la@example.com,
Surname = {Axolotl},
Forename = {Lizzie}
}
]{new row
}
% 7th row:
\DTLaction
[
assign
={
Id = 7, Organisation = {Avian Emporium}, Age =19,
Email = fc@example.com,
Surname = {Canary},
Forename = {Fred}
}
]{new row
}
% 8th row:
\DTLaction
[
assign
={
% Age and Surname not set
Id = 8, Organisation = {Newt Fellowship},
Email = m@example.com,
Forename = {Molgina}
}
]{new row
}
% 9th row:
\DTLaction
[
assign
={
% Organisation empty and Age and Email not set
Id = 9, Organisation = {},
Surname = {Mander}, Forename = {Sally}
}
]{new row
}
% 10th row:
\DTLaction
[
assign
={
Id = 10, Organisation = {Élite Emporium}, Age = 101,
Email = ef@example.com,
Surname = {Fant},
Forename = {Eli}
}
]{new row
}
3.2.4. Product List[link]
\DTLsetup
{store-datum,default-name=products}
% define database:
\DTLaction
{new
}
% add columns in desired order:
\DTLaction
[key
=Title]{add column
}
\DTLaction
[key
=Author]{add column
}
\DTLaction
[key
=Format]{add column
}
\DTLaction
[key
=Quantity]{add column
}
\DTLaction
[key
=Price,value
={Price
(\$)}]{add column
}
% 1st row:
\DTLaction
[
assign
={
Title = {The Adventures of Duck and Goose},
Author = {Sir Quackalot},
Format = paperback,
Quantity = 3,
Price = {10.99}
}
]{new row
}
% 2nd row:
\DTLaction
[
assign
={
Title = {The Return of Duck and Goose},
Author = {Sir Quackalot},
Format = paperback,
Quantity = 5,
Price = {19.99}
}
]{new row
}
% 3rd row:
\DTLaction
[
assign
={
Title = {More Fun with Duck and Goose},
Author = {Sir Quackalot},
Format = paperback,
Quantity = 1,
Price = {12.99}
}
]{new row
}
% 4th row:
\DTLaction
[
assign
={
Title = {Duck and Goose on Holiday},
Author = {Sir Quackalot},
Format = paperback,
Quantity = 3,
Price = {11.99}
}
]{new row
}
% 5th row:
\DTLaction
[
assign
={
Title = {The Return of Duck and Goose},
Author = {Sir Quackalot},
Format = hardback,
Quantity = 3,
Price = {19.99}
}
]{new row
}
% 6th row:
\DTLaction
[
assign
={
Title = {The Adventures of Duck and Goose},
Author = {Sir Quackalot},
Format = hardback,
Quantity = 9,
Price = {18.99}
}
]{new row
}
% 7th row:
\DTLaction
[
assign
={
Title = {My Friend is a Duck},
Author = {A. Parrot},
Format = paperback,
Quantity = 20,
Price = {14.99}
}
]{new row
}
% 8th row:
\DTLaction
[
assign
={
Title = {Annotated Notes on the ‘Duck and Goose’ chronicles},
Author = {Prof Macaw},
Format = ebook,
Quantity = 10,
Price = {8.99}
}
]{new row
}
% 9th row:
\DTLaction
[
assign
={
Title = {‘Duck and Goose’ Cheat Sheet for Students},
Author = {Polly Parrot},
Format = ebook,
Quantity = 50,
Price = {5.99}
}
]{new row
}
% 10th row:
\DTLaction
[
assign
={
Title = {‘Duck and Goose’: an allegory for modern times?},
Author = {Bor Ing},
Format = hardback,
Quantity = 0,
Price = {59.99}
}
]{new row
}
% 11th row:
\DTLaction
[
assign
={
Title = {Oh No! The Chickens have Escaped!},
Author = {Dickie Duck},
Format = ebook,
Quantity = 11,
Price = {2.0}
}
]{new row
}
3.2.5. Price List[link]
% custom expandable command:
\newcommand
{\limiteded
}{limited edition}
% define a database with the name 'pricelist':
\DTLsetup
{store-datum,default-name=pricelist}
\DTLaction
{new
}% create the default database
% 1st row:
\DTLaction
[
assign
={
Product = {The Adventures of Duck and Goose},
Quantity = {1,452},
Price = {\$1.99}
}
]{new row
}
% 2nd row:
\DTLaction
[
assign
={
Product = {Duck and Goose on Holiday},
Quantity = {94},
Price = {\$2.99}
}
]{new row
}
% the next value needs to be expanded:
\DTLaction
[
key
={Notes},
expand-value
={\limiteded
}
]{new entry
}
% 3rd row:
\DTLaction
[
assign
={
Product = {The Return of Sir Quackalot},
Quantity = {3},
Price = {\$4.99}
}
]{new row
}
3.2.6. Balance Sheet (CSV)[link]
Description,In,Out,Balance
Travel expenses,,230,-230
Conference fees,,400,-630
Grant,700,,70
Train fare,,70,0
The database name can be set as the default, if preferred.
The \DTLread
[
name
=balance, format
=csv,
headers
={ Description, in (\pounds
),
Out (\pounds
), Balance (\pounds
) }
]{balance.csv}
format
=csv setting is the default and so may be
omitted.
Since the data contains numeric values that may need to be parsed,
it’s also useful to switch on the store-datum option to reduce
parsing.
\DTLsetup
{store-datum,default-name=balance}
\DTLread
[
headers
={ Description, in (\pounds
),
Out (\pounds
), Balance (\pounds
) }
]{balance.csv}
3.2.7. Fruit (CSV)[link]
Name,Quantity
"Apples",30
"Pears",25
"Lemons,Limes",40.5
"Peaches",34.5
"Cherries",20
Again, the database name can be set as the default, if preferred.
The \DTLread
[name
=fruit,format
=csv]{fruit.csv}
format
=csv setting is the default and so may be
omitted.
Since the data contains numeric values that may need to be parsed,
it’s also useful to switch on the store-datum option to reduce
parsing.
\DTLsetup
{store-datum,default-name=fruit}
\DTLread
{fruit.csv}
3.2.8. Profits (CSV)[link]
Year,Profit,Units
1999,"-\$4,673",12467
2000,"\$2,525.49",8965
2001,"\$1,673.52",14750
2002,"-\$1,320.01",14572
2003,"\$5,694.83",13312
2004,"\$-451.67",9764
2005,"\$6,785.20",11235
Note that this uses \$ rather than a literal
$
symbol, so csv-content
=tex is required:
Again, the database name can be set as the default, if preferred,
and \DTLread
[name
=profits,format
=csv,csv-content
=tex]{profits.csv}
format
=csv is the default so it may be omitted.
Since the data contains numeric values that may need to be parsed,
it’s also useful to switch on the store-datum option to reduce
parsing.
\DTLsetup
{store-datum,default-name=profits}
\DTLread
[csv-content
=tex]{profits.csv}
3.2.9. Time to Growth (CSV)[link]
Time,Experiment 1,Experiment 2
0,3.13,3.4
15,3.42,3.45
30,3.67,3.5
45,4.2,3.64
60,4.9,3.8
\DTLread
[name
=growth1,format
=csv]{growth1.csv}
Time,Experiment 1,Experiment 2
0,3.14,3.2
15,3.51,3.53
30,3.79,3.61
45,4.5,4.25
60,5.1,4.9
\DTLread
[name
=growth2,format
=csv]{growth2.csv}
\DTLread
:
\DTLsetup
{store-datum}
3.2.10. Time to Growth (TSV)[link]
Experiment 1↹↹Experiment 2↹
Time↹Log
Count↹Time↹Log Count
0↹2.9↹0↹3.31
15↹3.14↹10↹3.45
30↹3.26↹25↹3.61
45↹4.01↹40↹3.76
60↹4.2↹55↹3.89
This represents a spreadsheet where the first row originally had
“Experiment 1” spanning the first two columns and “Experiment
2” spanning the last two columns. It was then exported to a
TSV file, which doesn’t support column spanning entries, so
“Experiment 1” is now in the first column and “Experiment 2”
is in the third. This line needs to be omitted when parsing the
file, which can be done with the csv-skip-lines
option.
Experiment 1↹↹Experiment 2↹↹Experiment 3↹
Time↹Log Count↹Time↹Log Count↹Time↹Log Count
0↹3.21↹0↹3.39↹0↹3.28
15↹3.43↹10↹3.51↹10↹3.45
30↹3.68↹25↹3.65↹20↹3.57
45↹4.4↹40↹3.84↹30↹3.64
60↹4.8↹55↹3.92↹40↹3.95
Note that \DTLsetup
{store-datum}
\DTLread
[
name
=growthdata, format
=tsv, csv-skip-lines
=1,
keys
={Exp1Time ,Exp1Count, Exp2Time, Exp2Count}
]{growth}
\DTLread
[
name
=growthdata2, format
=tsv, csv-skip-lines
=1,
keys
={Exp1Time, Exp1Count, Exp2Time, Exp2Count,
Exp3Time, Exp3Count }
]{growth2}
\DTLread
will assume a tsv extension with
format
=tsv so file extension may be omitted.
3.2.11. Generic X/Y Data (CSV)[link]
X,Y
-3.5,-2.75
-3,3
-2.5,-1
-1,1.5
1,-4.2
2.6,1.8
3.2,-0.4
\DTLread
[name
=xydata,format
=csv]{xydata.csv}
\DTLread
:
\DTLsetup
{store-datum}
3.3. Action Command[link]
is equivalent to:
\DTLaction
{new
}
where is the default name (which can be changed
with default-name in \DTLnewdb
{ }
\DTLsetup
). Alternatively, you can
supply the database name:
This is equivalent to:
\DTLaction
[name
=mydata]{new
}
\DTLnewdb
{mydata}
\DTLaction
to remove any leading or
trailing spaces.
display
action:
The “pricelist” database has null values as the Notes column
isn’t set in every row (see §3.10).
\DTLaction
{display}
\DTLaction
in the current scope.
Secondary return values should be identified by their property name.
The should be empty or omitted for the primary value.
return
setting, which should provide a comma-separated
list of assignments. Each
listed control sequence = will be defined to the value of
the secondary property identified by .
options
for the aggregate
action) and also check
that you have correctly spelt the property names.
column index
action has the column index
as the primary return value:
\DTLaction
[key
=Price]{column index
}
\DTLget
{\colidx
}
Column index: \colidx
.
\DTLget
or with the
return
option.
3.3.1. Defined Actions[link]
return
setting,
although it will have no effect with actions that don’t have
secondary return values. The descriptions below only identify
optional settings where support varies according to the action.
3.3.1.1. Creation and Editing[link]
name
, which should be a single name.
There are no required settings. Other action
settings are ignored. The return value is the database name, which
can also be accessed via the name secondary return property.
new
action internally uses \DTLnewdb
.
For example:
is equivalent to:
\DTLaction
[name
=mydata]{new
}
Note that new databases are always globally defined.
\DTLnewdb
{mydata}
name
, which should be a single name.
There are no required settings. Other action settings are ignored.
The return value is the database name, which can also be accessed
via the name return property. The other return properties
are rows and columns, which will be set to the row
and column count before the database was deleted.
name
,
which should be a single name. There are no required settings. Other
action settings are ignored. The return value is the database name,
which can also be accessed via the name return property.
The other return properties are rows and columns,
which will be set to the row and column count before the database
was cleared.
name
(which should be a single name) and
assign
. There are no required settings. Other action
settings are ignored. As with \DTLnewrow
, the global
option determines whether or not the database is altered globally or
locally.
assign
setting allows you to set the values for the
new row at the same time. You can also add values to this new row
with the new entry
action afterwards. It’s more efficient
and more compact to set the values while creating the new row, but if
some values should be expanded but not others, use the
new entry
action for those that need expanding.
For example:
This is equivalent to:
\DTLaction
[
assign
={ Name = {José Arara}, Score = {68},
Award = {\$2,453.99} }
]{new row
}
\DTLaction
{new row
}
\DTLaction
[ key
=Name, value
={José Arara} ]
{new entry
}
\DTLaction
[ key
=Score, value
={68} ]{new entry
}
\DTLaction
[ key
=Award, value
={\$2,453.99} ]
{new entry
}
is expandable but
\DTLuse
{}
isn’t.
\DTLuse
{row}new row
without the
assign
setting is essentially the same as
\DTLnewrow
. For example:
which is the same as:
\DTLsetup
{default-name={mydata}}
\DTLaction
{new row
}
is equivalent to:
\DTLaction
[name
={mydata}]{new row
}
Whereas with the \DTLnewrow
{mydata}
assign
setting, the new row
action
effectively implements not only \DTLnewrow
but also one or more
instances of \DTLnewdbentry
.
\DTLnewdbentry
, the database must have a least one row, and the
global option determines whether or not the database is
altered globally or locally.
name
, which should
be a single name. The required settings are: value
(or
expand-value
or expand-once-value
) and
either key
or column
. Other action settings
are ignored.
\DTLget
or \DTLuse
or the return
setting,
referenced by the following property
names:
The primary return value (accessed with an empty property) is the
column index, so you can access the column index with either
type
action setting
is a keyword, the type return value is a number.
or \DTLuse
{column}
, but
only the latter is expandable.
\DTLuse
{}expand-value
or expand-once-value
for
the values that require expanding. (Unless the majority of your
values require expansion.)
\DTLsetup
option
new-value-expand=true and the action
setting expand-value
. The first performs a protected
expansion. For example:
This will add \DTLsetup
{new-value-expand=true}
\DTLaction
[key
=Price,value
=\$1,234]{new entry
}
\protect \$1,234
to the
default database. Whereas the following:
will add \DTLsetup
{new-value-expand=false}
\DTLaction
[key
=Price,expand-value
=\$1,234]{new entry
}
\protect \T1
to the
default database. In the case of currency, it’s better not to expand
the value otherwise the currency symbol may expand to something that’s not
recognised as a currency unit.
\textdollar
1,234new entry
action internally uses \DTLnewdbentry
if
key
is set. If column
is used instead, a
similar function is used, but be aware that listing column indexes
out of order when the columns haven’t yet been defined may have
unexpected side-effects.
key
and column
this
will cause an error and the column index will be ignored. If you
use key
and a column hasn’t yet been defined, the
column count will increase by 1 and a new column will be created at
the end. If you use column
and no column with that
index has been defined, then a new column will be created with the
key obtained by expanding
and, if the index is greater than the current number of columns,
the database will be expanded so that it has a column count of
.
\dtldefaultkey
new entry
action will automatically create an
undefined column, you may prefer to define your columns in advance
to ensure the ordering and to provide additional column metadata.
add column
action has optional settings:
name
(which should be a single name), key
,
type
, and value
(or expand-value
or expand-once-value
). Note that the column
setting should not be used and will trigger an error if set. All
other settings are ignored. The \DTLsetup
global option
determines whether or not the database is altered globally or
locally.
key
setting, if provided. Otherwise,
it will be obtained by expanding
, where is the index of the new
column.
\dtldefaultkey
value
, if
provided. Otherwise, it will be set to the column key.
type
setting, if provided. Otherwise, the unknown type will be assumed.
Note that the type will be updated if an entry with a greater type
precedence is added to the column. For example, if you set
type
=integer but then add a decimal number to this
column, then the column type will be updated to decimal.
\DTLget
or \DTLuse
or the return
setting,
referenced by the following property names:
The primary return value (accessed with an empty property) is the
column index, so you can access the column index with either
or
\DTLuse
{column}
, but only the latter is expandable.
(Alternatively, use \DTLuse
{}
.)
\DTLcolumncount
{ }\DTLaction
{new
}
\DTLaction
{new row
}
\DTLaction
{add column
}
Added column \DTLuse
{column}
(key: \DTLuse
{key}; header: \DTLuse
{header})
to database `\DTLuse
{name}'.
\DTLaction
[key
=quantity]{add column
}
Added column \DTLuse
{column}
(key: \DTLuse
{key}; header: \DTLuse
{header})
to database `\DTLuse
{name}'.
\DTLaction
[key
=price,value
=Price (\$)]{add column
}
Added column \DTLuse
{column}
(key: \DTLuse
{key}; header: \DTLuse
{header})
to database `\DTLuse
{name}'.
3.3.1.2. Querying[link]
select row
action. Unlike
the select row
action, the find
action doesn’t
change the current row (unless explicitly requested with the
select=true option), so it may be used within the body of
\DTLforeach
to either lookup another row in the current
database or in another database.
find
action doesn’t have any required settings, but if
none are provided it will simply find the first row of the database
(if the database isn’t empty). The optional settings are:
name
: identifies the database;
row
: identifies the row index to start the search from
(defaults to 1, if omitted);
row2
: identifies the row index to end the search
(defaults to the last row, if omitted);
assign
: an assignment list
of pairs to define
placeholder commands for each row, before the match function
is used;
=
options
: may be used to specify options specific
to the find
action, see below.
options
value may include the following = options.
\dtlgetrow
will be used to set
the \dtlcurrentrow
token register (and related registers) for
use with actions (such as row aggregate
) or commands (such
as those described in §3.16.1). If unsuccessful
or if select=false, the \dtlcurrentrow
token register won’t be changed.
row
–row2
, will
match, provided the database isn’t empty. If the assign
setting is used, the placeholders can be referenced in the function.
They will also still be available after the action, and will have
their values from the matching row or from the final row in the search
range if no match was found. They will be null if the database is
empty. If there was no corresponding value in the row, they will be
set to either \DTLnumbernull
(if the column has a numeric
data type) or \DTLstringnull
otherwise (see
§3.10).
assign
.
Each value can then be displayed with
\DTLaction
[row
=2]{find
}
, where is the
column key.
\DTLuse
{ }\DTLaction
[
assign
={\Surname
=surname,\Forename
=forename},
options
={
inline={\DTLifstringeq
{\Surname
}{Smith}
{\DTLifstringeq
{\Forename
}{John}{#1}{}}{}}
}
]{find
}
\DTLifaction
{}% test for primary return value
{\Forename
\␣\Surname
\␣found on row \DTLuse
{}}
{Not found}.
key
.
This action does not create any typeset output. It performs a
similar function as \DTLgetcolumnindex
but it won’t trigger an
error if there’s no column with the given key. Instead you need to
test the return value with \DTLifnull
. Use \dtlcolumnindex
instead if you want a single expandable function with no error
checking.
name
(which should be a single name), and one required setting:
key
. Other settings are ignored.
or
\DTLuse
{}
. The name return property
will be set to the database name, and the key return
property will be set to the column key (if provided). The
column property can also be referenced to obtain the column
index, if successful.
\DTLget
{ }\DTLaction
[key
=Price]{column index
}
\DTLget
{\colidx
}
\DTLifnull
{\colidx
}{No such column}{Column index: \colidx
}.
column index
but gets all the
column metadata (column index, key, type and header) from either the
key or index.
key
or column
setting was used). The
secondary return properties are: column (the column index),
key (the column key), type (the data type), and
header (the column header). The return value will be null
if the column doesn’t exist.
key
or column
setting or if both are
provided. This action has one optional setting: name
(which should be a single name), and one required setting: either
key
or column
(but not both). Other settings
are ignored.
\dtlcurrentrow
token register for
use with actions (such as row aggregate
) or commands (such
as those described in §3.16.1).
\dtlcurrentrow
and \dtldbname
have already been set), for
example within the hooks used by \DTLdisplaydb
, then you can
instead use the current row values
action to access
information in the current row.
row
setting
to select that row. This will internally use \dtlgetrow
.
value
(or expand-value
or
expand-once-value
) for the required value and either
column
or key
(but not both) to identify the
column. In this case, the action will be similar to
\dtlgetrowforvalue
to find the first row that exactly matches
the given value, but it won’t trigger an error if no match is found.
find
action instead with
function or inline and
select=true set in the action options
.
value
={} indicates an empty (not null)
value. If you want to find
the first row that doesn’t have a particular column set, you can
instead use the find
action and search for a null value.
name
setting (which should be a
single name) may be used to identify the database (which must
exist). It omitted, the default is used. You can’t have both
row
and a column identifier (column
or
key
) set.
\dtlgetrowforvalue
, this action (when
matching a column) is primarily intended to work with a column which
has unique values, such as an identification number. If you require
a match on multiple columns or a regular expression match, you will
need to iterate over the database or use the find
action.
\dtlcurrentrow
, \dtlbeforerow
and \dtlafterrow
, and
also the placeholders \dtldbname
(expands to the database name),
\dtlrownum
(the row index) and \dtlcolumnnum
(the column
index). If unsuccessful, \dtlrownum
will be zero.
\dtlrownum
), and the secondary return values will the value of
each entry found in the current row with the return property key the
same as the column key.
\dtlgetrowforvalue
to select a row with a particular value
from the “marks” database (see §3.2.1).
select row
action. First the row selection:
Then calculate the mean for the columns Assign1,
Assign2 and Assign3. This can be done by column
index, for example, \DTLaction
[
name
=marks,
key
=StudentNo,
value
={105987}
]{select row
}
Student \DTLuse
{Forename} \DTLuse
{Surname}
(105987).
columns
={4-6} or by column key,
for example, keys
={Assign1-Assign3}. Since
Assign3 is the last column of the database, an open-ended
range may be used:
Bear in mind that the second \DTLaction
[
keys
={Assign1-},
options
={mean},
datum
={round=1}
]{current row aggregate
}
Average mark: \DTLuse
{mean}.
(Actual value: \DTLget
[mean]{\theMean
}
\DTLdatumvalue
{\theMean
}.)
\DTLaction
will clear the return
values from the first, so if you need to continue referencing those
values, take care to scope the second instance.
\dtlcurrentrow
and \dtldbname
have already been set), for
example within the hooks used by \DTLdisplaydb
or with
\dtlgetrow
, then the
current row values
action can be used to access values
within the current row rather than using the more cumbersome
\dtlgetentryfromcurrentrow
for each required column.
To store the values in placeholder commands with \DTLaction
{current row values
}
Name: \DTLuse
{Forename} \DTLuse
{Surname}.
\DTLget
:
Alternatively, with the \DTLaction
{current row values
}
\DTLget
[Forename]{\Forename
}
\DTLget
[Surname]{\Surname
}
return
setting:
\DTLaction
[
return
={
\Forename
=Forename,
\Surname
=Surname
}
]{current row values
}
columns
and/or keys
.
Otherwise all columns will be assumed.
A warning will occur if the name
option is set as the
name is expected to be in \dtldbname
. An error will occur if
\dtldbname
hasn’t been set.
All other settings are ignored.
\DTLaction
[
keys
={Title,Price,Quantity,Total},
columns
={1,2}
]{current row values
}
datum
option was set, or if conversion automatically occurred with
store-datum when the database was created).
current row values
action to fetch row entries within the
post-row hook of \DTLdisplaydb
to append a total column to the
table.
3.3.1.3. Aggregates[link]
key
or column
must be
set (but not both) to identify the required column. The
key2
or column2
values may also be set (but
not both) if a second column is also required.
Optional settings are: name
(which should be a single
name) and options
, which should be a comma-separated list of
the aggregate functions to apply. The aggregate functions are as
follows:
If options
is empty, the only functions will be to count
and gather numeric items in a sequence.
\DTLmaxforkeys
, that return
formatted numbers.
Additionally, if
(or \DTLget
[seq]{ }return
={)
then =seq} will be in the form of a l3seq sequence variable.
options
list, then this property will be set to the
minimum value in the first column.
options
list, then this property will be set to the
maximum value in the first column.
options
list (or implied by a function that requires the
sum), then this property will be set to the
sum of all numeric values in the first column.
options
list (or implied by a function that requires the
mean), then this property will be set to the
mean of all numeric values in the first column.
options
list (or implied by a function that requires the
variance), then this property will be set to the
variance of all numeric values in the first column.
options
list, then this property will be set to the
standard deviation of all numeric values in the first column.
key2
or column2
have been
set:
(or \DTLget
[seq2]{ }return
={)
then =seq2} will be in the form of a l3seq sequence variable.
options
list, then this property will be set to the
minimum value in the second column.
options
list, then this property will be set to the
maximum value in the second column.
options
list (or implied by a function that requires the
sum), then this property will be set to the
sum of all numeric values in the second column.
options
list (or implied by a function that requires the
mean), then this property will be set to the
mean of all numeric values in the second column.
options
list (or implied by a function that requires the
variance), then this property will be set to the
variance of all numeric values in the second column.
options
list, then this property will be set to the
standard deviation of all numeric values in the second column.
\DTLmapdata
.
(See Example 87.)
\dtlcurrentrow
.
row aggregate
and
current row aggregate
essentially perform the same
function. The difference between them is that row aggregate
is for use within \DTLmapdata
and
current row aggregate
is for use within \DTLforeach
or
after selecting a current row with the select row
action or
with commands like \dtlgetrow
.
\dtldbname
placeholder, so the name
option will
trigger a warning, if set, and an empty \dtldbname
will trigger an
error. These actions are similar to aggregate
but they
aggregate items in the columns of the current row that have a numeric value.
columns
and/or keys
options.
options
setting is as for the aggregate
action. The primary return value is the number of numeric columns
contributing to the aggregates. The secondary return value
properties are:
\dtldbname
).
If any unexpected results occur, check this return value matches the
expected name.
\dtlrownum
).
If any unexpected results occur, check this return value matches the
expected row index.
(or \DTLget
[seq]{ }return
={)
then =seq} will be in the form of a l3seq sequence variable.
options
list, then this property will be set to the
minimum value in the subset.
options
list, then this property will be set to the
maximum value in the subset.
options
list (or implied by a function that requires the
sum), then this property will be set to the
sum of all numeric values in the subset.
options
list (or implied by a function that requires the
mean), then this property will be set to the
mean of all numeric values in the subset.
options
list (or implied by a function that requires the
variance), then this property will be set to the
variance of all numeric values in the subset.
options
list, then this property will be set to the
standard deviation of all numeric values in the subset.
\DTLmapdata
:
For comparison, the example also uses \DTLmapdata
[name
=marks]{
\DTLmapget
{key
=Forename} \DTLmapget
{key
=Surname}
average marks:
\DTLaction
[
columns
={4-},
options
={mean}
]{row aggregate
}
\DTLuse
{mean}.
}
\DTLforeach
:
And selects a particular row:
\DTLforeach
{marks}
{\Forename
=Forename,\Surname
=Surname}
{
\Forename
\␣\Surname
\␣ average mark:
\DTLaction
[
columns
={4-},
options
={mean}
]{current row aggregate
}
\DTLuse
{mean}.
}
The rather cumbersome \dtlgetrowforvalue
{marks}{\dtlcolumnindex
{marks}{StudentNo}}{105987}
Student 105987 average mark:
\DTLaction
[
columns
={4-},
options
={mean}
]{current row aggregate
}
\DTLuse
{mean}.
\dtlgetrowforvalue
can be replaced with the select row
action, as in the earlier Example 67.
3.3.1.4. Tabulation[link]
\DTLdisplaydb*
. This action has optional
settings: name
(which should be a single name) and
options
to pass any options to \DTLdisplaydb*
.
Other settings are ignored.
This is essentially the same as:
\DTLaction
[options
={omit-columns
={1,3}}]{display
}
where is obtained from the default-name option.
The action has the advantage over \DTLdisplaydb*
[omit-columns
={1,3}]{ }
\DTLdisplaydb
as you can use
the return values to find out how many columns or rows were displayed (which
may not necessarily be the same as the column count or row count).
display
action, but it uses the
underlying function of \DTLdisplaylongdb
, which uses
longtable instead of tabular. This action has optional
settings: name
(which should be a single name) and
options
to pass any options to \DTLdisplaylongdb
.
Other settings are ignored.
3.3.1.5. Modifying a Database[link]
\DTLsortdata
. This action has optional
settings: name
(the database name), and
options
(the options to pass to the optional argument of
\DTLsortdata
). There is one required settings:
assign
, which should be the criteria to pass in the
final argument of \DTLsortdata
.
3.3.1.6. Other[link]
bar chart
and multibar chart
actions.
The datapie package provides the pie chart
action.
The dataplot package provides the plot
action.
3.3.2. Action Settings[link]
\DTLaction
and can’t be used in \DTLsetup
. They are reset
to their default values by \DTLaction
before the optional
argument is processed. Settings that aren’t required by the given
action are usually ignored, but an unrequired setting may
occasionally generate an error or warning if it’s likely that the setting may
accidentally be used instead of the correct one (for example,
setting column
when the column can only be identified
with key
).
Some actions don’t permit the database name to be specified as it’s
expected to be provided by \DTLaction
[name
=mydata]{new
}
\dtldbname
(such as
current row aggregate
). Actions that require a
single name will take the first from the list and ignore the rest of
the list.
keys
for a list of keys. Typically, you
won’t be able to use both key
and column
.
keys
for a list of keys. Typically, you
won’t be able to use both key2
and column2
.
columns
for a list of column indexes.
columns
for a list of column indexes.
columns
option can be used to reference the required
columns by their index in a comma-separated list.
, where - is the start of
the range and is the end. If is omitted
then 1 is assumed and if is omitted, the last column is
assumed. For example,
columns
={-4} is equivalent to
columns
={1-4} and
columns
={1,3-5} indicates columns 1, 3, 4, and 5.
Where a range with a start and end value is provided, the start
value must be less than or equal to the end value.
keys
option can be used to reference the required
columns by their key in a comma-separated list. Typically, an action
that allows a list of columns may allow both keys
and
columns
and will merge the subsets. As with
columns
, the list may include ranges in the form
, where - is the start of
the range and is the end. As with
columns
,
if the start range is omitted, the first column is assumed, and if
the end range is omitted, the last column is assumed. For example,
the “marks” database (see §3.2.1) may have
(as in
Example 87).
keys
={Assign1-}columns
, if the
associated column index of is greater that the
associated column index of , the start and end references
will be switched round.
new row
action to assign values to specific columns
according to the column key, in this case the part in
= is the column key. In the case of actions such as
pie chart
and bar chart
, each part is
a placeholder command.
display
action, this provides the option
list to pass to \DTLdisplaydb*
. For example:
This is equivalent to:
\DTLaction
[options
={only-keys
={Product,Price}}]{display
}
Whereas with the \DTLdisplaydb*
[only-keys
={Product,Price}]{ }
aggregate
action, options
provides a list of required aggregate functions.
new entry
action, the
value
setting
is the value to add to the database:
This is equivalent to:
\DTLaction
[key
=Price,value
=\$1.23]{new entry
}
where is obtained from the default-name setting.
\DTLnewdbentry
{ }{Price}{\$1.23}
value
, expand-value
or
expand-once-value
occur in the same option list then
they will override each other. The last one in the list will take
precedence.
value
key with
fully expanded.
value
key with
expanded once. This is the best setting to use if you
have a placeholder command or token list. For example,
\newcommand
{\price
}{\$1.23}
\DTLaction
[
key
=Price,
expand-once-value
=\price
]{new entry
}
return
setting, which should provide a comma-separated
list of assignments. Each
listed control sequence = will be defined to the value of
the secondary property identified by . This may be
used instead of, or in addition to, using
\DTLget
.
aggregate
to avoid the
cumbersome use of \dtlround
and \DTLdecimaltolocale
to
format the results.
datum
setting doesn’t affect primary return values.
However, since the primary return value is often (but not always)
duplicated in the secondary set, the formatted value can be obtained
from the applicable secondary property. Complex secondary values
that have their own markup, such as the seq return property
for the aggregate
action are also not affected.
datum
=false (don’t format secondary return values),
datum
=true (format secondary return values without
changing the datum
settings) or
datum
={ to enable with the given subset
of }datum
settings. For example,
. Note that
datum
={round=2,currency=\$}datum
=true is essentially the same as
datum
={}.
\DTLget
to fetch the value as a datum control sequence and
\DTLdatumvalue
to extract the plain number (see
Example 67). With
\DTLuse
, the formatted number will be inserted into the
document. There’s little advantage in using datum
with text-only return values.
datum
is not set to false, then the secondary
value format (in the string part of the datum item) can be
adjusted according to the following options, which may be set in
datum
={. However, in the case of
secondary return values that simply provide elements from the
database (such as those from the }select row
action), the
return values will be datum items (obtained using
\DTLparse
), but won’t be governed by the options listed below.
false
, the string
part will use a plain number but it will still be affected by
the currency and round options.
Note that the sum return property is always
considered a decimal in this context, even if only integer values
were summed.
aggregate
action). Available option values:
aggregate
action) and
indicates whether the value should be rounded. The keyword
false or a negative value may be used to prevent rounding.
Otherwise the value should be set to a non-negative number
indicating the required number of decimal places.
aggregate
action:
This displays all the statistics as plain numbers
(Example 69).
Using \DTLaction
[
key
=Quantity,
key2
=Price,
options
={sd,min,max}
]{aggregate
}
Quantity column index: \DTLuse
{column}.
Total quantity: \DTLuse
{sum}.
Average quantity: \DTLuse
{mean}.
Quantity standard deviation: \DTLuse
{sd}.
Minimum quantity: \DTLuse
{min}.
Maximum quantity: \DTLuse
{max}.
Price column index: \DTLuse
{column2}.
Total price: \DTLuse
{sum2}.
Average price: \DTLuse
{mean2}.
Price standard deviation: \DTLuse
{sd2}.
Minimum price: \DTLuse
{min2}.
Maximum price: \DTLuse
{max2}.
datum
will produce formatted numbers for the
calculated values (but not for the column index):
Note that this will convert the total, minimum and maximum
quantities to decimals rounded to 2 decimal places (but not the
column index). The actual
numeric values can be obtained with \DTLaction
[
datum
={round=2},
key
=Quantity,
key2
=Price,
options
={sd,min,max}
]{aggregate
}
\DTLget
and
\DTLdatumvalue
:
Quantity column index:
\DTLuse
{column}.
Total quantity: \DTLuse
{sum}
(\DTLget
[sum]{\theTotal
}\DTLdatumvalue
{\theTotal
}).
Average quantity: \DTLuse
{mean}.
Quantity standard deviation: \DTLuse
{sd}.
Minimum quantity: \DTLuse
{min}
(\DTLget
[min]{\theMin
}\DTLdatumvalue
{\theMin
}).
Maximum quantity: \DTLuse
{max}
(\DTLget
[max]{\theMax
}\DTLdatumvalue
{\theMax
}).
This converts all the quantity aggregate values to currency, which
is inappropriate in this case.
\DTLaction
[
datum
={round=2,currency},
key
=Quantity,
key2
=Price,
options
={sd,min,max}
]{aggregate
}
3.4. Creating a New Database[link]
\DTLread
. In that case, the database is always defined globally
because \DTLread
introduces an implicit group to localise the
settings passed in the optional argument.
See §3.15 for further details.
new
action:
\DTLaction
[name
={]{ }new
}
\DTLnewdb
is equivalent to \DTLgnewdb
.
\DTLnewrow*
doesn’t check for existence. Alternatively,
you can use the new row
action (which checks for existence):
\DTLaction
[name
={]{ }new row
}
new entry
action (which checks for existence):
\DTLaction
[
name
={,
}key
={,
}value
={
]{ }new entry
}
\DTLnewdbentry*
doesn’t check for existence of the database, but will still trigger
an error if an entry for the given column already exists.
with the
\DTLaction
{new entry
}expand-value
or expand-once-value
action option. With new-value-expand=true, the value will
always have protected expansion applied.
% custom expandable command:
Note that the second row has introduced a fourth column with the
label “Notes”. Since the other rows don’t have this column set,
an attempt to access it will result in a null value. Expansion needs
to be switched on when a value must be expanded. This is commonly
the case with placeholder commands. The setting must be switched off
again or it will cause the currency symbol to prematurely expand in
the next row (which means the datum parser won’t be able to detect
it as currency).
\newcommand
{\limiteded
}{limited edition}
% define data
\DTLnewdb
{mydata}
\DTLnewrow
{mydata}% create a new row
% Add entries to the first row:
\DTLnewdbentry
{mydata}% database label
{Product}% column key
{The Adventures of Duck and Goose}% value
\DTLnewdbentry
{mydata}% database label
{Quantity}% column key
{1,452}% value
\DTLnewdbentry
{mydata}% database label
{Price}% column key
{\$1.99}% value
\DTLnewrow
{mydata}% create a new row
% Add entries to the second row:
\DTLnewdbentry
{mydata}% database label
{Product}% column key
{Duck and Goose on Holiday}% value
\DTLnewdbentry
{mydata}% database label
{Quantity}% column key
{94}% value
\DTLnewdbentry
{mydata}% database label
{Price}% column key
{\$2.99}% value
% the next value needs to be expanded:
\DTLsetup
{new-value-expand}
\DTLnewdbentry
{mydata}% database label
{Notes}% column key
{\limiteded
}% value
% switch off expansion:
\DTLsetup
{new-value-expand=false}
\DTLnewrow
{mydata}% create a new row
% Add entries to the third row:
\DTLnewdbentry
{mydata}% database label
{Product}% column key
{The Return of Sir Quackalot}% value
\DTLnewdbentry
{mydata}% database label
{Quantity}% column key
{3}% value
\DTLnewdbentry
{mydata}% database label
{Price}% column key
{\$4.99}% value
This displays the database in a tabular environment,
as shown in Example 70.
See Example 65 for an equivalent document using \DTLdisplaydb
{mydata}
\DTLaction
.
\DTLnewdbentry
don’t permit \par
on the argument. If you have a value that spans multiple paragraphs,
you will need to mark the paragraph breaks with:
\par
.
3.5. Deleting or Clearing a Database[link]
delete
action:
\DTLaction
[name
={]{ }delete
}
clear
action:
\DTLaction
[name
={]{ }clear
}
3.6. Database Conditionals and Metadata[link]
\DTLifdbexists
and
\DTLifdbempty
.
If the database identified by exists and is
not empty, this does , if it exists but is empty,
this does . If the database doesn’t exist, this does
.
\DTLifhaskey*
is now simply defined to use
\datatool_if_has_key:nnTF
.)
column index
action:
\DTLaction
[key
={]{ }column index
}
Index: \DTLuse
{}.
Or: \DTLget
{ } index: \cs
.
\DTLgetcolumnindex
is
robust. If you want the column index in an expandable context you
can use:
\relax
if
the database or column didn’t exist.)
\DTLgetkeyforcolumn*
doesn’t check if the database or column exists.
\DTLdisplaydb
(where the column data type determines the column
alignment). However, if the data isn’t stored as a datum item,
it will have to be reparsed for commands like \DTLmaxforkeys
.
It’s more efficient to use store-datum=true, but if you do
so, you will need to remember that a command that is set to an element
value (such as those in an assignment list in \DTLforeach
) will
be a datum control sequence rather than a command whose expansion text is the original value.
column data
action, which
will get the index, key, type and header from the column key or
column index. For example, the following will display the meta data
for the first column:
The following fetches the meta data for the column identified by the
key \DTLaction
[column
=1]{column data
}
Column 1 key: \DTLuse
{key},
title: \DTLuse
{header},
type: \DTLuse
{type}.
Name
:
\DTLaction
[key
=Name]{column data
}
\DTLget
[column]\colidx
Column index: \colidx
.
\DTLget
[header]\colheader
Column title: \colheader
.
\DTLget
[type]\coltype
Column type: \coltype
.
\DTLread
, the headers can be set with the headers
option. Alternatively, you can use:
but it’s shorter and slightly quicker. Alternatively:
\DTLaddcolumn
{ }{ }
\DTLsetheader
{ }{ }{ }
or set the database name as the default so you don’t have to keep
supplying it:
\DTLaction
[name
={, }key
={, }value
={]{ }add column
}
\DTLsetup
{default-name={}
}\DTLaction
[key
={, }value
={]{ }add column
}
Missing values show as “NULL” (see §3.10).
\DTLnewdb
{mydata}
\DTLaddcolumnwithheader
{mydata}{name}{Name}
\DTLaddcolumnwithheader
{mydata}{address}{Address}
\DTLnewrow
{mydata}
\DTLnewdbentry
{mydata}{name}{Zoë}
\DTLnewrow
{mydata}
\DTLnewdbentry
{mydata}{name}{José}
\DTLnewrow
{mydata}
\DTLnewdbentry
{mydata}{name}{Dickie}
% this row has an empty name:
\DTLnewrow
{mydata}
\DTLnewdbentry
{mydata}{name}{}
Number of rows: \DTLrowcount
{mydata}.
Number of columns: \DTLcolumncount
{mydata}.
\DTLdisplaydb
{mydata}
3.7. Displaying the Contents of a Database[link]
\DTLdisplaydb*
and \DTLdisplaylongdb
are listed in
§3.7.1. Associated commands, which can be
redefined to make slight adjustments, are listed in
§3.7.2. Examples are provided in
§3.7.3.
display
(for
\DTLdisplaydb*
) and display long
(for
\DTLdisplaylongdb
).
For example:
or
\DTLaction
[name
={mydata},options
={only-keys
={Name,Description}}]{display
}
are equivalent to:
\DTLsetup
{default-name=mydata}
\DTLaction
[options
={only-keys
={Name,Description}}]{display
}
\DTLdisplaydb*
[only-keys
={Name,Description}]{mydata}
\DTLdisplaydb
and
\DTLdisplaylongdb
use a private token list variable
to construct the content of the tabular or
longtable environment. This removes the loop from within the
alignment and avoids the need to globally set variables. Once
construction of has been completed,
is then expanded.
pre-content
option value is placed immediately before
, so you can set pre-content
to \show
for debugging purposes. This will show the tokens in
in the transcript (and won’t be
expanded).
3.7.1. Display Options[link]
\DTLdisplaydb*
and
\DTLdisplaylongdb
. However, some are only available with
one or other command. If you are using the display
or
display long
actions, you can specify these options in the
options
action setting.
\DTLdisplaylongdb
, options
were defined using the xkeyval interface. In version 3.0, the
xkeyval package has been dropped in favour of the newer
l3keys interface. If you previously used
to set the
options (instead of using the optional argument), you will need to
switch to
\setkeys
{displaylong}{ }
.
\DTLsetup
{display={} }3.7.1.1. General[link]
\show
for debugging purposes, and it will show rather than
typeset the content. Any local redefinitions within will be scoped. For
example, this option can be used to adjust \tabcolsep
or
longtable settings.
pre-content
to locally redefine
customization commands, such as \dtldisplaydbenv
, as they will
have already been expanded.
\dtlrownum
is incremented per included database
row and the column number \dtlcolumnnum
is incremented per included column
regardless of this option. For example, with
per-row
=2 then \dtlrownum
and the
argument of \DTLdisplaydbAddItem
will first be 1
and then 2 for the first tabular line that follows the header
(not including any additional content that may have been inserted by
hooks).
row-idx-map-inline
={\DTLrowcount
{\dtldbname
}-#1+1}
\DTLdisplayTBrowidxmap
is provided for use
with per-row
that will arrange the data rows from top to
bottom instead of left to right, but note that this won’t work if
filtering omits rows.
\dtldisplaycr
separating the rows).
Unlike \dtldisplaystartrow
, which has its expansion text
inserted into the content token list, the post-row hook determines
whether or not to append content to the token list variable or
accumulate information for later insertion. The
post-row-inline
option provides a way to define this
hook inline.
\dtlrownum
. If no rows have been filtered,
\dtlrownum
will have the same value as .
The hook isn’t used for excluded rows.
\dtlcurrentrow
token register will be available within the
hook, so you access row information with commands such as
\dtlgetentryfromcurrentrow
or \DTLassignfromcurrentrow
or actions such as current row aggregate
.
post-row-inline
but provides the name of a function
that takes two arguments.
\DTLdisplaydb*
and indicates the
environment to use. This is a shortcut that redefines \dtldisplaydbenv
to
but additionally checks that the given environment
is defined and redefines \dtldisplayvalign
to empty, unless
is tabular or array, in which case
\dtldisplayvalign
is redefined to c
unless it is
currently defined to t
or b
.
\DTLdisplaydb*
[tabular-env
=tblr]{mydata}
\DTLdisplaylongdb
and indicates the
environment to use. This is a shortcut that redefines
\dtldisplaylongdbenv
to but additionally checks
that the given environment is defined. Note that the
environment needs to support longtable syntax.
\DTLdisplaylongdb
[longtable-env
=longtabu]{mydata}
3.7.1.2. Alignment[link]
\dtlstringalign
to .
\dtlintalign
to .
integer-align
.
\dtlrealalign
to .
decimal-align
.
\dtlcurrencyalign
to .
\dtlbetweencols
to .
For example, inter-col
={|} for a vertical line.
\dtlbeforecols
to .
For example, pre-col
={|} for a vertical line.
\dtlaftercols
to .
For example, post-col
={|} for a vertical line.
string-align
, integer-align
,
decimal-align
, currency-align
,
inter-col
, pre-col
, post-col
will be ignored (although they will still set the underlying
commands).
3.7.1.3. Headers and Footers[link]
where
is the expansion text of
\dtlcolumnheader
{ }{ } &
\dtlcolumnheader
{ }{ } &
…\dtlcolumnheader
{ }{ }
\dtldisplaystarttab
(the same as the value of the
pre-head
option), and etc are the column
headers, and is the value of the
post-head
option. If \dtldisplayafterhead
(the same as the value of
after-head
) is not
empty, this is then followed by:
\dtldisplaycr
\dtldisplayafterhead
The argument is obtained by:
This adds the appropriate to ,
taking into account the \multicolumn
{1}{ }{\dtlheaderformat
{ }}
pre-col
, inter-col
and post-col
settings. The default definition will use
c
(centred) regardless of the data type. (Note used if
header-row
is set.) The token list
is cleared before calling this command, so you
can either append or set it.
\dtldisplaystarttab
to .
Note that with \DTLdisplaylongdb
, this will come after the
caption, if provided.
\l_datatool_post_head_tl
to . Note that this is
different to after-head
which comes after the row end.
\dtldisplayafterhead
, which comes
after the header, to .
\midrule
(booktabs) after the
header, you can either redefine \dtldisplayafterhead
to
\midrule
:
or you can use \renewcommand
{\dtldisplayafterhead
}{\midrule
}
after-head
:
or (for a particular longtable):
\DTLsetup
{display={after-head
={\midrule
}}}
\DTLdisplaylongdb
[after-head
={\midrule
}]{mydata}
You will need to include any required formatting and make sure you
have the correct number of columns.
\DTLdisplaydb*
[header-row
={Name & Description}]{mydata}
pre-head
, post-head
and after-head
.
\c_novalue_tl
which
indicates the setting is switched off. This makes it possible to
distinguish between switching off the setting, and enabling the
setting but requiring an empty value. For example,
caption
={} will create a caption with empty text
(the table number will be displayed). Whereas the default
caption
=\c_novalue_tl
(which would require
LaTeX3 syntax to be enabled) will switch off the setting.
\DTLdisplaylongdb
.)
If set, \caption
will be inserted at the start of
the header with the supplied value in the argument.
\DTLdisplaylongdb
.)
If this option is set in addition to caption
, the
\caption
argument for the first header (\endfirsthead
) will be obtained from
caption
but the \caption
argument for the
subsequent headers (\endhead
) will be obtained from cont-caption
.
This option is ignored if caption
isn’t set.
cont-caption
.
\DTLdisplaylongdb
.)
If this option is set in addition to caption
, the
optional argument of \caption
in the first header will be set to this value.
This option is ignored if caption
isn’t set.
short-caption
.
\DTLdisplaylongdb
.)
If this option is set in addition to caption
, the
\caption
in the first header will be followed by
.
This option is ignored if \label
{ }caption
isn’t set.
\DTLdisplaydb
,
be inserted before \dtldisplaycr
\dtldisplayendtab
at the end of
the tabular environment (see \DTLdisplaydbAddEnd
). In the
case of \DTLdisplaylongdb
,
will
be inserted at the start of the longtable environment (see
\endfoot
\DTLdisplaylongdbAddBegin
).
\DTLdisplaylongdb
.)
If this option is set,
will be
inserted (by \endlastfoot
\DTLdisplaylongdbAddBegin
) as the last footer of the longtable.
last-foot
.
3.7.1.4. Filtering[link]
post-row-inline
or
post-row-function
.
\dtlrownum
within the filter function
before the code, it will contain the filtered row index
of the previous row to be added. The variable is incremented in the
argument.
\tabularnewline
(which is added to the content token
list at the start of the code provided in the third argument of the
filter function, since it’s not possible to tell at the end of the
previous row if there are any additional rows that won’t be filtered).
Or to include all rows but insert a blank row before
every even row:
\DTLdisplaydb*
[row-condition-inline
={\ifodd
#2\else
#3\fi
}]{mydata}
\DTLdisplaydb*
[row-condition-inline
={
\ifodd
#2 \else
\appto
#1{\tabularnewline
}\fi
#3} ]{mydata}
row-condition-inline
,
you can provide a function with row-condition-function
.
The supplied command must have three arguments as per the
inline function for row-condition-inline
.
\dtlgetentryfromcurrentrow
as in Example 75, or an action that acts on the
current row, such as current row aggregate
.
omit
option.
only-keys
and only-columns
, the
table column order will match the inclusion order (that is, the
order given in the option value). Otherwise, the
table column order will match the column index order (with excluded
columns omitted, if applicable).
3.7.2. Associated Commands[link]
\DTLdisplaydb
and
\DTLdisplaylongdb
to format the table contents.
\textbf{ }
Not used if
no-header
is set.
\dtlheaderformat
.
Previously, the definition included \hfil
to centre the text.
The alignment is now performed with \dtlcolumnheader
and
\dtlheaderformat
just deals with any font change.
.
\dtlnumericformat
{ }
.
\dtlnumericformat
{ }
.
\dtlnumericformat
{ }pre-head
option. Not used if no-header
is set.
after-head
option. Not used if no-header
is set.
\DTLdisplaydbAddItem
and
adding a test for the first column with \datatool_if_row_start:nnTF
,
as in Example 85
in §3.7.3.14. (Content can be
inserted into the end of each row with post-row-inline
or post-row-function
).
\DTLdisplaydb
. Note that if you redefine this command to use an
environment that doesn’t take tabular’s optional vertical alignment
argument, you will also need to redefine \dtldisplayvalign
to
expand to nothing.
tabular-env
option instead, which will
also redefine \dtldisplayvalign
.
\DTLdisplaydb
.) This may be redefined to empty
if the optional argument should be omitted.
\renewcommand
{\dtldisplaydbenv
}{tblr}
\renewcommand
{dtldisplayvalign}{}
\DTLdisplaylongdb
. For example, to switch to longtabu
(provided by tabu):
\renewcommand
{\dtldisplaylongdbenv
}{longtabu}
longtable-env
option
to redefine \dtldisplaylongdbenv
.
string-align
redefines this command.
Not used if align-specs
is set to a non-empty value.
integer-align
(or int-align
)
redefines this command.
Not used if align-specs
is set to a non-empty value.
decimal-align
(or real-align
)
redefines this command.
Not used if align-specs
is set to a non-empty value.
currency-align
redefines this command.
Not used if align-specs
is set to a non-empty value.
pre-col
redefines
this command. Not used if align-specs
is set to a non-empty value.
inter-col
redefines
this command. Not used if align-specs
is set to a non-empty value.
post-col
redefines
this command. Not used if align-specs
is set to a non-empty value.
\tabularnewline
rather than \\ as
\\ can interfere with paragraph columns. This allows
\dtlstringalign
to be redefined to p
where the final
column has the string data type.
\dtlstringformat
).
The default definition of this command simply appends
to { } . The remaining
arguments are ignored by default.
per-row
=1, the will correspond to
the tabular (or longtable) row of data, excluding
the header and any rows inserted by hooks. So the first row
following the header will have equal to 1. If all
rows in the database are included, then this will also correspond to
the database row index. However, if some rows are excluded via the
filter function, then the may be less than the
corresponding row index.
per-row
is greater than
1, as the column number will be reset to 1 at the
start of each included database row. The row number
is incremented at the start of each included database row. So the
first line of the table after the header row will start with
equal to 1 but then will be 2 at the
start of the next block of data, which is on the same line of the
table.
\DTLdisplaydbAddItem
to
insert content at the start of a row, you can test if
is 1 if you know that per-row
=1 but if you want to
take into account multiple rows of data per tabular row then you
need to use the following (which requires LaTeX3 syntax enabled):
per-row
=1 then this just tests if
is 1, otherwise it will perform modulo arithmetic on
to determine if corresponds to the first column.
per-row
option sets the integer variable
\l_datatool_display_per_row_int
, which may be used in the definition
of \DTLdisplaydbAddItem
for more complex requirements.
(See Example 83 in
§3.7.3.12.)
\dtladdalign
command won’t be used if align-specs
is set to a non-empty value. Instead, will be
set to the value of align-specs
.
\dtlstringalign
, \dtlintalign
, \dtlrealalign
or
\dtlcurrencyalign
to .
\dtlbeforecols
(\( =1\)), \dtlaftercols
(\( = \)) or \dtlbetweencols
(\(1< \leq \)). Note that
\dtlaftercols
is placed after the alignment specifier, so that
it occurs at the end, whereas \dtlbeforecols
and
\dtlbetweencols
are placed before.
\DTLdisplaydb
to add the beginning of the tabular
environment to the token list variable. The
argument is the content of the
token list variable containing
the column alignment specification (created with \dtladdalign
),
and the argument is the token list
containing the header row (where each column header is encapsulated
with \dtlheaderformat
).
where is the expansion of \begin{
[ } ]{ }
\dtldisplaydbenv
,
is the expansion text of
\dtldisplayvalign
, is the
expansion text of \dtldisplaystarttab
, is
the expansion text of \dtldisplaycr
, and is
the expansion text of \dtldisplayafterhead
.
The [ ] optional argument will be omitted if \dtldisplayvalign
is
empty.
align-specs
option can be used to set
explicitly, the header-row
option can
be used to set explicitly, and the
no-header
option will omit
.
\DTLdisplaydb
. This consists of:
where is the expansion text of
\end{
}\dtldisplayendtab
, and is the expansion of
\dtldisplaydbenv
,
\RenewDocumentCommand
\DTLdisplaydbAddBegin
{mmm}{%
\appto
#1{\begin{tblr}
{#2}#3\\}%
}
\RenewDocumentCommand
\DTLdisplaydbAddEnd
{m}{%
\appto
#1{\end{tblr}
}%
}
\DTLdisplaydbAddBegin
but used by
\DTLdisplaylongdb
to add the start of the longtable
environment to . This is more complicated than
\DTLdisplaydbAddBegin
as it also inserts the caption, label and
footer, according to the caption
,
short-caption
, cont-caption
,
label
, foot
, and last-foot
options.
\DTLdisplaylongdb
. This consists of:
where is the expansion text of
\end{longtable}
\dtldisplayendtab
.
row-idx-map-function
,
this command expands to a row index that will arrange data rows from
top to bottom instead of left to right when per-row
is
greater than 1. Note that this is only designed to work when no rows
are omitted.
caption
key.
short-caption
key.
cont-caption
key.
label
key.
foot
key.
last-foot
key.
post-head
key.
no-header
key.
per-row
option.
\l_datatool_display_per_row_int
rounded up. Bare in mind
that this doesn’t take any filtering into account. It’s used in
\DTLdisplayTBrowidxmap
to calculate the loop index to row index
mapping.
3.7.3. Examples[link]
3.7.3.1. Changing the Alignment[link]
The database has five columns and some of the titles (in the first
column) are quite long, which can lead to an overly wide table. It
would be better to allow line wrapping. This can be done by changing
the string column alignment (\DTLdisplaydb
{products}
string-align
) but this
would also affect the second and third columns. In this case, it’s
simpler to use align-specs
to override the default
alignments for all the columns. Example 72
has:
\DTLdisplaydb*
[align-specs
={p{0.4\linewidth
}llrr}]{products}
3.7.3.2. Omitting Columns[link]
\DTLdisplaydb
has an optional argument that must be a
comma-separated list of column keys that identify which columns
to omit. For example, if I want to omit the Quantity and Price
columns:
With the starred version, the optional argument is a = list:
\DTLdisplaydb
[Quantity,Price]{products}
Alternatively:
\DTLdisplaydb*
[omit-keys
={Quantity,Price}]{products}
These all produce the table shown in Example 73.
\DTLaction
[options
={omit-keys
={Quantity,Price}}]{display
}
3.7.3.3. Column Inclusion List[link]
Or:
\DTLdisplaydb*
[only-keys
={Author,Title,Price}]{products}
These all produce the table shown in Example 74.
\DTLaction
[options
={only-keys
={Author,Title,Price}}]{display
}
only-keys
and only-columns
, the
table column order will match the listed columns. Whereas with
omit-keys
and omit-columns
, the table
column order will be in the order that the columns were added to the
database.
3.7.3.4. Skipping Rows[link]
row-condition-inline
option provides a way to omit rows.
If the condition is quite complicated, you may prefer to define a
handler function and reference it with
row-condition-function
.
\productfilter
is defined which fetches the value from the
“Quantity” column from the current row and only includes rows
where that value is greater than zero:
This command can now be used as the filter function:
\newcommand
{\productfilter
}[3]{%
\dtlgetentryfromcurrentrow
{\theQuantity
}%
{\dtlcolumnindex
{\dtldbname
}{Quantity}}%
\DTLifnumgt
{\theQuantity
}{0}{#3}{}%
}
\DTLaction
[
options
={
row-condition-function
=\productfilter
,
only-keys
={Title,Quantity,Price}
}
]{display
}
3.7.3.5. Referencing Rows[link]
\DTLforeach
, there is no associated row counter for the display commands.
However, you can borrow the \DTLforeach
counters as long as there is no conflict.
Example 76 does this to number and label each row. Note that labels
must be unique. This can be achieved if the database has a column that contains unique
values. For the marks database, this is the student number.
\DTLdisplaydbAddItem
hook can be redefined to increment the counter
and insert the label at the start of each row. The start of the row is determined
by testing if the seventh argument of \DTLdisplaydbAddItem
( )
is one. The current row values
action can be used to fetch the student number
for the current row.
or with etoolbox commands:
\ExplSyntaxOn
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{
\int_compare:nNnT
{ #7 } = { \c_one_int
}
{
\DTLaction
[ return
={ \StudentNo
= StudentNo } ]
{ current ~
row ~
values }
\tl_put_right:Nn
#1 { \DTLrowincr
\label
}
\tl_put_right:Nx
#1 { { \StudentNo
} }
}
\tl_put_right:Nn
#1 { #3 { #2 } }
}
\ExplSyntaxOff
In either case, this modification ensures that the first column of each row starts with:
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }{%
\ifnum
#7 = 1
\DTLaction
[return
={\StudentNo
= StudentNo}]
{current row values
}%
\appto
#1{\DTLrowincr
\label
}%
\eappto
#1{{\StudentNo
}}%
\fi
\appto
#1{#3{#2}}%
}
where is the value of the StudentNo entry for the current row.
\DTLrowincr
\label
{ }
current row values
action.
An alternative method is to find out which column the student number is in and insert the code
into the start of that column. This can either be done by referencing the display column number
argument ( ) or the database column index argument ( ).
The data can then be displayed:
\DTLrowreset
and a particular row can be referenced:
\DTLaction
{display
}
Row
Or if you need to look up the registration number from the student’s name:
\ref
{103569} shows the details for student 103569.
(This method can’t be used for Jane Brown, as there are two students with that name.)
\DTLaction
[
assign
={
\Surname
=Surname,
\Forename
=Forename,
\StudentNo
=StudentNo
},
options
={
inline={%
\DTLifstringeq
{\Surname
}{Brown}
{\DTLifstringeq
{\Forename
}{Andy}{#1}{}}{}%
}
}
]{find
}
Row \ref
{\StudentNo
} shows the details for Andy Brown.
\DTLdisplaydbAddItem
to show the counter value after it has been incremented. For the
LaTeX3 version, the change is:
For the etoolbox version, the change is:
\tl_put_right:Nn
#1 { \DTLrowincr
\DTLtherow
. ~
\label
}
This puts the value at the start of the surname column. Example 3.7.3.6
below places the value in a separate column.
\appto
#1{\DTLrowincr
\DTLtherow
. \label
}%
3.7.3.6. Inserting an Extra Column at the Start[link]
\refstepcounter
and added a label, but the value of the counter wasn’t
shown, although a modification was suggested that would put the value at the start of
the first column (which contains the surname).
\DTLdisplaydbAddItem
needs to insert an extra alignment. For the LaTeX3
code, the modification is:
For the etoolbox version, the change is:
\tl_put_right:Nn
#1 { \DTLrowincr
\label
}
\tl_put_right:Nx
#1 { { \StudentNo
} }
\tl_put_right:Nn
#1 { \DTLtherow
&
}
The extra column can be added to the alignment specifier using \appto
#1{\DTLrowincr
\label
}%
\eappto
#1{{\StudentNo
}}%
\appto
#1{\DTLtherow
&
}%
pre-col
and a corresponding header (possibly empty) needs to be inserted into the header row:
\DTLrowreset
\DTLaction
[
options
={
pre-col
={r},
pre-head
={\bfseries
Row &
}
}
]{display
}
3.7.3.7. Adding an Extra Column at the End[link]
align-specs
) and appends the extra column header with
post-head
.
\newcommand
{\productappendtotal
}[2]{%
\DTLaction
[
return
={
\theQuantity
=Quantity,
\thePrice
=Price
}
]{current row values
}%
\DTLmul
{\theTotal
}{\theQuantity
}{\thePrice
}%
\DTLround
{\theTotal
}{\theTotal
}{2}%
\appto
#1{&
}%
\eappto
#1{\expandonce
\theTotal
}%
\DTLadd
{\runningtotal
}{\runningtotal
}{\theTotal
}%
}
\DTLaction
[
options
={
only-keys
={Title,Quantity,Price},
pre-head
={\toprule
},
after-head
={\midrule
},
align-specs
={lrrr},
post-head
={&
\dtlcolumnheader
{c}{Total}},
init
={\def
\runningtotal
{0}},
post-row-function
=\productappendtotal
,
foot
={\midrule
&
&
&
\runningtotal
}
}
]{display
}
3.7.3.8. Altering Individual Cell Formatting[link]
Suppose now that the negative numbers should be shown in red. This
can be done by redefining \DTLsetup
{store-datum,default-name=balance}
\dtlrealformat
:
An alternative method is to redefine \renewcommand
{\dtlrealformat
}[1]{\DTLiflt
{#1}{0}{\color
{red}}{}#1}
\DTLdisplaydbAddItem
to
perform the test for a particular column, in this case column 4 (the
balance). This also conveniently provides a way to total the
incoming and outgoing columns (columns 2 and 3).
Note that some cells are empty so these are skipped.
The totals can then be appended with the \newcommand
{\theInTotal
}{0}
\newcommand
{\theOutTotal
}{0}
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{%
\DTLifnullorempty
{#2}{}% skip null or empty
{%
\dtlifnumeq
{#8}{4}% balance column
{%
\DTLifnumlt
{#2}{0}{\appto
#1{\color
{red}}}{}%
}%
{%
\dtlifnumeq
{#8}{2}% in column
{\DTLadd
{\theInTotal
}{\theInTotal
}{#2}}%
{%
\dtlifnumeq
{#8}{3}% out column
{\DTLadd
{\theOutTotal
}{\theOutTotal
}{#2}}{}%
}%
}%
\appto
#1{#3{#2}}%
}%
}
foot
option.
As with the previous example, I’ve added rules provided by
booktabs:
\DTLaction
[options
={
after-head
={\midrule
},
foot
={\midrule
Totals &
\theInTotal
&
\theOutTotal
&
}
}
]{display
}
\DTLdisplaydbAddItem
( ) is the column index, which will always be an
integer, so an integer comparison can be used instead of
the decimal \dtlifnumeq
. (Likewise for the , ,
and arguments.) Since the
store-datum option has been set, the second argument
( ) will be in the datum item format except where
it’s empty or null, so the actual numeric value can be obtained with
\datatool_datum_value:Nnnnn
, which will require LaTeX3 syntax
and the argument can be checked to ensure that the
supplied value is numeric. If you switch on LaTeX3 syntax, you may
as well directly use the l3int and l3fp commands:
Note that this relies on the data being stored as datum items.
If you’re not sure if this is the case, you can use \ExplSyntaxOn
\fp_new:N
\l_my_in_total_fp
\fp_new:N
\l_my_out_total_fp
\newcommand
{\theInTotal
}{
\fp_to_decimal:N
\l_my_in_total_fp
}
\newcommand
{\theOutTotal
}{
\fp_to_decimal:N
\l_my_out_total_fp
}
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{
\int_compare:nNnT
{ #4 } > { \c_datatool_string_int
}
{
\int_case:nn
{ #8 }
{
{ 2 }
{
\fp_add:Nn
\l_my_in_total_fp
{ \datatool_datum_value:Nnnnn
#2 }
}
{ 3 }
{
\fp_add:Nn
\l_my_out_total_fp
{ \datatool_datum_value:Nnnnn
#2 }
}
{ 4 }
{
\fp_compare:nNnT
{ \datatool_datum_value:Nnnnn
#2 } < { \c_zero_fp
}
{
\tl_put_right:Nn
#1 { \color
{ red } }
}
}
}
}
\tl_put_right:Nn
#1 { #3 { #2 } }
}
\ExplSyntaxOff
\DTLparse
,
which will check and convert if required.
3.7.3.9. Two Database Rows Per Tabular Row (Left to Right)[link]
This requires datatool-english, which needs to be installed
separately. The sorting is performed with the \usepackage
[locales=en]{datatool}
sort
action:
\DTLaction
[assign
={surname,forename}]{sort
}
per-row
option.
This results in the data tabulated with (below the header)
database row one (Zoë Adams) and two (Roger Brady) on the first line,
three (Andy Brown) and four (Jane Brown) on the second line,
five (Quinn Ó Coinn) and six (Evelyn O’Leary) on the third line, and
seven (John Smith, Jr) and eight (Clare Vernon) on the fourth line.
That is, the data is arranged from left to
right, shifting down a line every other block of data.
For a top to bottom arrange, see Example 81.
\DTLaction
[
options
={
per-row
=2,
only-keys
={forename,surname,score}
}
]{display}
3.7.3.10. Two Database Rows Per Tabular Row (Top to Bottom)[link]
row-idx-map-function
option to
change the mapping from the loop index to the selected row index:
\DTLaction
[
options
={
per-row
=2,
row-idx-map-function
=\DTLdisplayTBrowidxmap
,
only-keys
={forename,surname,score}
}
]{display}
3.7.3.11. Stripy Table[link]
\tabularnewline
or \\) is
inserted at the start of each row, except for the first row. This is
done after filtering (applied with row-condition-inline
or row-condition-function
). It can’t be done at the end
of the previous row as there’s no way of telling at that point if
there will be another row.
\DTLdisplaydbAddItem
command. The
seventh argument of that command is the tabular (or
longtable) column number. This may be different from the
eighth argument, which is the database column index. This means that
if you want to insert content at the start of a row, you need to
test if the seventh argument is 1.
\DTLdisplaydbAddItem
uses a LaTeX3
l3tl command:
The first argument is the content token list variable, the second
argument is the column content and the third argument is the
formatting command . The above definition simply
appends \NewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{
\tl_put_right:Nn
#1 { #3 { #2 } }
}
to the token list. This is
equivalent to:
{ }
\NewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{\appto
#1{#3{#2}}}
\rowcolor
:
In order to insert \usepackage
{colortbl}
\rowcolor
at the start of a row,
\DTLdisplaydbAddItem
needs to be redefined to test if the
seventh argument is equal to one. The fifth argument is the row
number (excluding the header), so the simplest way to alternate is
to test if that value is odd or even. For example:
The data can simply be displayed using the \ExplSyntaxOn
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{
\int_compare:nNnT
{ #7 } = { \c_one_int
}
{ % first column
\int_if_odd:nTF
{ #5 }
{ % odd row
\tl_put_right:Nn
#1 { \rowcolor
{ blue } }
}
{ % even row
\tl_put_right:Nn
#1 { \rowcolor
{ green } }
}
}
\tl_put_right:Nn
#1 { #3 { #2 } }
}
\ExplSyntaxOff
display
action:
\DTLaction
{display}
3.7.3.12. Stripy Two Database Rows Per Tabular Row[link]
per-row
=2 to
Example 82 will cause a problem as the
argument of \DTLdisplaydbAddItem
will loop
round, which will result in \rowcolor
being inserted in the
middle of the tabular row.
\DTLdisplaydbAddItem
to use \datatool_if_row_start:nnT
instead of simply testing if the seventh argument is 1.
Bear in mind that the argument will also increment
mid tabular row as a new row of data is fetched. This means
that will always have an odd value at the start of
each tabular row, so it’s now not as simple as testing if
is odd:
The data is display with:
\ExplSyntaxOn
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{
\datatool_if_row_start:nnT
{ #5 } { #7 }
{ % first column
\int_compare:nNnTF
{ \int_mod:nn
#5 2 * \l_datatool_display_per_row_int
}
= \c_one_int
{
\tl_put_right:Nn
#1 { \rowcolor
{ blue } }
}
{
\tl_put_right:Nn
#1 { \rowcolor
{ green } }
}
}
\tl_put_right:Nn
#1 { #3 { #2 } }
}
\ExplSyntaxOff
\DTLaction
[
options
={
per-row
=2,
only-keys
=forename,surname,score
}
]{display}
3.7.3.13. Two Fields in One Column[link]
\DTLdisplaydbAddItem
to show both the surname and forename in
the same column. The other columns show the student registration
(which disambiguates the students with the same name) and the
assignment marks. This requires the header row to be set with
header-row
=to override the default (which would only
show “Surname” in the first column):
The \DTLaction
[
options
={
only-keys
={Surname,StudentNo,Assign1,Assign2,Assign3},
header-row
={Name &
Reg.\␣No., &
Mark 1 &
Mark 2 &
Mark 3}
}
]{display
}
\DTLdisplaydbAddItem
command is redefined to test for the
first column (as in the earlier Example 3.7.3.11).
Remember that the tabular column number is in
the seventh argument, whereas the database column index is in the
eighth argument. In this case, the Surname column is both the first
column in the table and also the first column in the database. The
example tests if the column number is equal to one and, if true,
fetches the forename from the current row (using the
current row values
action), and stores it in one of
the public scratch token list variables (\l_tmpa_tl
). This uses
LaTeX3 commands, so the syntax needs to be switched on temporarily.
The test for null or empty (see §3.10) isn’t necessary
in this example, as there are no null values in the example database.
It’s provided so that the example can be adapted for other databases.
\ExplSyntaxOn
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{
\int_compare:nNnTF
{ #7 } = { \c_one_int
}
{
\DTLaction
[ return
={ \l_tmpa_tl
= Forename } ]
{ current ~
row ~
values }
\datatool_if_null_or_empty:NTF
\l_tmpa_tl
{
\tl_put_right:Nn
#1 { #3 { #2 } }
}
{
\tl_put_right:Nx
#1
{
\exp_not:N
#3 { \exp_not:n
{ #2 } ,
~
\exp_not:V
\l_tmpa_tl
}
}
}
}
{
\tl_put_right:Nn
#1 { #3 { #2 } }
}
}
\ExplSyntaxOff
\DTLdisplaydbAddItem
uses the current row values
action and this will be used within the display
action.
However, the underlying display function introduces a scope to limit
the effects of the display options, but that scoping also prevents
the inner action from interfering with the return values of the
outer action.
\exp_not:N
, \exp_not:n
and
\exp_not:V
in the above).
\appto
, \eappto
and \expandonce
,
which are provided by etoolbox, \noexpand
(a TeX primitive) and \unexpanded
(an eTeX primitive).
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{
\ifnum
#7 = 1
\DTLaction
[return={\Forename
=Forename}]
{current row values
}
\DTLifnullorempty
{\Forename
}%
{%
\appto
#1{#3{#2}}%
}%
{%
\eappto
#1{\noexpand
#3{\unexpanded
{#2},
\expandonce
\Forename
}}%
}%
\else
\appto
#1{#3{#2}}%
\fi
}
3.7.3.14. Calculations, Filtering and Row Highlighting[link]
\rowcolor
to highlight rows.
Since this example will perform arithmetic calculations and
comparisons, the marks database is loaded with the store-datum
setting on.
\usepackage
{colortbl}
\DTLsetup
{store-datum,default-name=marks}
\DTLread
{studentmarks.csv}
current row aggregate
action.
\newcommand
{\rowfilter
}[3]{%
\DTLaction
[
options
={mean},datum
={round=1},
keys
={Assign1-},
return
={\AverageScore
=mean}
]{current row aggregate
}% calculate average
\DTLifnumlt
{\AverageScore
}{50}%
{}% skip if average less than 50
{#3}%
}
\DTLdisplaydbAddItem
is similar to that for Example 84 described in
§3.7.3.13. However, a check is added to
determine if the average is above 70 so that \rowcolor
can be
added to the content. Note that it can’t be added in the custom
\rowfilter
hook as it will end up before \tabularnewline
,
which will be inserted at the start of the code provided in the
third argument of the filter function.
\DTLdisplaydbAddItem
in order to
insert content at the start of a row, make sure to test if the seventh
argument (the tabular column number) is 1 rather than the eighth
argument (the database column index).
datum
action option was set, the result (\AverageScore
) will be a
datum control sequence so the actual numerical value can be obtained as a
plain number with \DTLdatumvalue
, which means that
\fp_compare:nNnT
can be used instead of \DTLifgt
.
With LaTeX3 commands, the definition is now:
Alternatively, if you prefer to use the etoolbox commands:
\ExplSyntaxOn
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{
\int_compare:nNnTF
{ #7 } = { \c_one_int
}
{
% insert highlight if average greater than 70
\fp_compare:nNnT
{ \DTLdatumvalue
\AverageScore
} > { 70 }
{
\tl_put_right:Nn
#1 { \rowcolor
{yellow} }
}
\DTLaction
[ return
={\l_tmpa_tl
=Forename} ]
{ current ~
row ~
values }
\datatool_if_null_or_empty:NTF
\l_tmpa_tl
{
\tl_put_right:Nn
#1 { #3 { #2 } }
}
{
\tl_put_right:Nx
#1
{
\exp_not:N
#3 { \exp_not:n
{ #2 } ,
~
\exp_not:V
\l_tmpa_tl
}
}
}
}
{
\tl_put_right:Nn
#1 { #3 { #2 } }
}
}
\ExplSyntaxOff
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{
\ifnum
#7 = 1
% highlight if average greater than 70
\DTLifnumgt
{\AverageScore
}{70}%
{\appto
#1{\rowcolor
{yellow}}}{}%
\DTLaction
[return={\Forename
=Forename}]
{current row values
}
\DTLifnullorempty
{\Forename
}%
{\appto
#1{#3{#2}}}%
{%
\eappto
#1{\noexpand
#3{\unexpanded
{#2},
\expandonce
\Forename
}}%
}%
\else
\appto
#1{#3{#2}}%
\fi
}
post-row-function
can be used to append the
average (which should still be available with the custom
\AverageScore
calculated in the above) in a similar manner to
Example 78.
The data is again displayed with the \newcommand
{\appendaverage
}[2]{%
\appto
#1{&
}%
\eappto
#1{\expandonce
\AverageScore
}%
}
display
action, but
this time there are only three columns: the student’s name, the
student number and the average score. As with
Example 78, the tabular alignment
specification must be provided with align-specs
.
\DTLaction
[
options
={
only-keys
={Surname,StudentNo},
align-specs
={lrr},
post-row-function
=\appendaverage
,
row-condition-function
=\rowfilter
,
header-row
={Name &
Reg.\␣No. &
Average}
}
]{display
}
3.8. Iterating Through a Database[link]
\DTLforeach
not \DTLmapdata
. However,
be aware of its limitations. Consider constructing the tabular
contents to move the loop outside of the tabular body.
(See §3.9.)
\DTLmapdata
, is described in
§3.8.1.
The older command \DTLforeach
is described in
§3.8.2.
Both can be used to iterate over rows of a database and both
have a setting that allows the database to be edited.
In the case of \DTLmapdata
, the edits are locally added to a
pending buffer and only applied at the end of \DTLmapdata
and may be discarded with \DTLmapdatabreak*
.
Note that it’s also possible to edit a database outside of a loop.
See §3.12 for those commands.
3.8.1. Iterating Over Rows with
Iterates over the data in a database, performing at
each iteration. The available options are:
Identifies the database. If omitted, the default name is assumed
(as given by the default-name option).
\DTLmapdata
[link]\DTLsetentry
and \DTLrmrow
. Note that the current row editing commands for use with
\DTLforeach
are not compatible with \DTLmapdata
.
read-only
. If true,
this setting switches off read-only mode.
\DTLmapdata
(which may
contain paragraph breaks) is performed at each iteration. Unlike
\DTLforeach
, which has an optional argument to implement
filtering, if you want to skip a row, you will need to add the
appropriate conditional within the loop body.
\DTLmapdata
on the environment body.
See Example 189 in §9.6.1 which uses
DTLenvmapdata for mail merging with the supplementary person package.
\DTLmapdata
doesn’t.
\dtldbname
will be defined to expand
to the database name, and, at the start of each iteration, the current row
number is stored in the \dtlrownum
register. Unlike \DTLforeach
,
there is no associated row counter. However, you can borrow the \DTLforeach
counters as long as there is no conflict. This simplest method is to use
\DTLrowreset
before the start of \DTLmapdata
and use
\DTLrowincr
in the loop body. Alternatively, you can define your own counter.
\DTLforeach
with \dtlbreak
, which will cause the loop to terminate at the
end of the current iteration.)
read-only
=true, there’s
no difference between the starred and unstarred version of
\DTLmapdatabreak
. Otherwise, the starred version will discard any edits as
well as breaking out of the loop, whereas the unstarred version
will break out of the loop but still apply the edits.
\DTLmapdatabreak
will skip all following
content in the rest of the loop iteration, it can’t be placed within
a primitive \if…
… \fi
conditional as the
closing \fi
will be lost. Similarly, it can’t occur within a
non-expandable or scoped context.
\DTLmapdata
, you must scope the inner loop
to prevent conflict. Note that \begin
implicitly creates a
group, so the DTLenvmapdata environment will automatically be
scoped.
Command:
\DTLmapdata
{
\dtldbname
: row \the
\dtlrownum
.
\dtlifnumeq
{\dtlrownum
}{3}{\DTLmapdatabreak
}{}
(after break)
}
Environment:
\begin{DTLenvmapdata}
\dtldbname
: row \the
\dtlrownum
.
\dtlifnumeq
{\dtlrownum
}{3}{\DTLmapdatabreak
}{}
(after break)
\end{DTLenvmapdata}
3.8.1.1. Accessing Data in the Current Row of
\DTLmapdata
[link]\DTLmapdata
, you can access values in
the current iteration row using:
key
or column
is required to identify
the value by its column label or index. If both are used, they will
override each other.
key
or column
). If the value is empty or
omitted (the default), the value will simply be inserted into the
document.
return
=cs is set, you can test if is null
with \DTLifnull
. For example:
In the above, if the title isn’t set, it will be omitted, but if the
forename or surname columns aren’t set, they will appear as “NULL”.
(Note that a null value is not the same as an empty value, see
§3.10.)
\begin{DTLenvmapdata}
Dear
\DTLmapget
{key
=title,return
=\Title
}% fetch title
\DTLifnull
\Title
{}{\Title
}% ignore title if not set
\DTLmapget
{key
=forename} \DTLmapget
{key
=surname}
% …
\end{DTLenvmapdata}
\DTLdatumvalue
and
\DTLdatumtype
. (See §2.2 for further
details.) Similarly for in \DTLmaprow
, and
likewise for assignments in \DTLforeach
and similar commands.
\DTLmapget
for each column, you
can instead use:
\DTLmapdata
(or DTLenvmapdata) and iterates over the columns in
the current (\DTLmapdata
) iteration row. At the
start of each iteration, the register \dtlcolumnnum
is set to
the column index and is defined to the column value. Then
is done. You can prematurely break the loop with:
This will stop the current \DTLmaprow
loop at that point but
won’t stop the \DTLmapdata
loop. As with \DTLmapdatabreak
,
this command should not be placed inside a primitive conditional or
within a non-expandable or scoped context.
\DTLforeach
:
\DTLifnull
). The unstarred
\DTLmapgetvalues
will trigger an error if the database has no column
defined with the given label (as opposed to the
column being defined for the database but no value set in that
column for the given row), whereas the starred
\DTLmapgetvalues*
for won’t and will simply set
to null.
This is essentially equivalent to:
\DTLmapgetvalues
{\thePrice
=Price,\theQuantity
=Quantity}
\DTLmapget
{key
=Price,return
=\thePrice
}
\DTLmapget
{key
=Quantity,return
=\theQuantity
}
3.8.1.2. Editing Rows[link]
read-only
=false (or
allow-edits
=true), the following commands are
available for use in the loop body of \DTLmapdata
(or within
the body of the DTLenvmapdata environment).
\DTLmapdata
. This means that any change applied
within a scope in the loop body will be lost once the scope is
ended. However, the final update to the database at the end will be
applied according to the current global setting. Pending edits
can be discarded by breaking out of the loop with
\DTLmapdatabreak*
.
\DTLrmrow
, then
\DTLrowcount
will still expand to 4 until \DTLmapdata
has
completed. Edits to the current iteration row will be picked up by any
following \DTLmapget
, but \DTLmaprow
will only pick up any
changes made before the \DTLmaprow
loop starts.
column
and key
. If the column
exists, they must both reference the same column. If the column
doesn’t exist, then column
is taken as the column
reference and key
provides a key for that column if
a new column needs to be defined.
value
but will fully expand the value.
value
but will expand the value once.
column
or key
. Note that this
won’t delete the entire column but any reference to this
column for the given row will result in a null value (see
§3.10).
This will remove the entry in column 4 for every row, but column 4
will still be defined.
\DTLmapdata
[allow-edits
]{\DTLrmentry
{column
4}}
column
or key
to the value identified by
value
or expand-value
or
expand-once-value
. Note that the general
new-value-expand and store-datum settings will be
respected, but the expansion with expand-value
or
expand-once-value
occurs before the
new-value-expand setting is implemented.
column
. If you also set
key
that will be used as the label for the new
column, otherwise it will be given the default label (obtained from
).
\dtldefaultkey
to append a column. However, it’s simpler to create the new column
first, as in Example 87.
column
={\DTLcolumncount
{\dtldbname
}+1}\DTLmapdata
to iterate over
each row and append a column containing the average marks for each
assignment. The row aggregate
action may be used within
\DTLmapdata
to calculate the average. For example:
A range may be used in \DTLaction
[key
=Average]{add column
}
\DTLmapdata
[allow-edits]{%
\DTLaction
[
keys
={Assign1,Assign2,Assign3},
options
={mean},
datum
={round=1},% round the result
return
={\Mean
=mean}
]
{row aggregate
}
\DTLifnull
{\Mean
}% test the return value
{}% row aggregate failed!
{% average calculated successfully
\DTLsetentry
{key
=Average,expand-value
=\Mean
}
}
}
keys
=, which may be more
convenient:
Since the new column will have a null value at this point (which
will be skipped by the \DTLaction
[
keys
={Assign1-Assign3},
options
={mean},
datum
={round=1},% round the result
return
={\Mean
=mean}
]
row aggregate
action), an open
ended range may be used instead:
\DTLaction
[
keys
={Assign1-},
options
={mean},
datum
={round=1},% round the result
return
={\Mean
=mean}
]
\DTLaction
[assign
={{Average=desc
}}]{sort
}
\DTLaction
{display
}
3.8.2. Iterating Over Rows with
\DTLforeach
[link]\DTLmapdata
, described
in §3.8.1, locally sets internal variables at each
iteration. This means that it can’t be used within a
tabular-like environment where the loop body contains &
or \\ as internal variables will be lost when the scope
changes between columns and rows.
\noalign
” errors.
In which case, it may be better to use the method suggested in
§3.9.
This is equivalent to:
\DTLforeach
[ ]{ }{}{ }
Any commands applicable to \DTLforeach*
[ ]{ }{}{ }
\DTLforeach
are also applicable to
the corresponding DTLenvforeach environment.
\DTLforeach
(or DTLenvforeach), the final loop
index may be saved with:
\DTLforeach
loop. Note that this refers to the counter
increment at each iteration where the evaluates to
true, and so may not be the database row count. If used within the
body of a \DTLforeach
loop, it will refer to the last
\DTLforeach
loop at the next level up. Where the level index is
obtained from the following:
\DTLforeach
and corresponds to the level index. This will be 1
in the outermost \DTLforeach
, 2 within the first nested
\DTLforeach
, and 3 within the second nested \DTLforeach
.
Each level has an associated row counter, which is incremented with
\refstepcounter
, which means you can use \label
at the
start of in order to reference a row number, but
obviously some method will be needed to make the label unique,
see Example 90 in §3.8.2.2.3.
\label
should occur as soon as possible after \refstepcounter
,
and it must be within the same scope. Therefore if you need to label the rows,
ensure that \label
occurs right at the start of .
\DTLforeach
.
This ensures that \theHDTLrowi
, \theHDTLrowii
and \theHDTLrowiii
expand to unique values.
\DTLmapdata
, but
take care that such use doesn’t conflict with \DTLforeach
. Bear in mind
that these counters don’t have automatic resets (that is, they are not defined with
a parent counter). For convenience, the following commands are provided to minimise conflict.
\dtlforeachlevel
.
\dtlforeachlevel
.
\theDTLrow
where
is one more than \dtlforeachlevel
.
comma-separated list, where
- is a command and is the key uniquely
identifying a column.
\ifthenelse
(so the commands in §2.4.2 may be
used). If the condition evaluates to true, the row counter for the
current level is incremented, and the of the loop is
performed. The placeholder commands in may be
referenced within the . If the optional argument is
omitted, \boolean{true}
is assumed.
\dtlcurrentrow
token register is set to the
special internal database markup for the current row. Commands or
actions that are designed for use with that register, such as the
current row aggregate
action, may be used in , but
avoid the editing commands described in §3.16.1
that alter \dtlcurrentrow
. Instead, use the commands described
in §3.8.2.1 to modify the current row.
\DTLmaprowbreak
, which breaks out of the current
loop immediately.
\DTLforeachkeyinrow
Iterates over each column in the current row of \DTLforeach
,
globally defines to the value in that column, and does .
This internally iterates through the column metadata with
\dtlforeachkey
, assigning \dtlkey
, \dtlcol
,
\dtltype
and \dtlheader
to the column key, column index,
column type and column header, respectively.
3.8.2.1. Editing the Current Row within
\DTLforeach
[link]\DTLforeach*
is used, no changes can be
made to the database. With the editable unstarred version, the
current row may be changed using the commands below, and the
database will be updated after each iteration. This makes it slower
than the read-only version.
allow-edits
mode
for \DTLmapdata
, which stores pending edits in a buffer and only updates
the database after the loop has terminated.
\DTLforeach
, the following commands
may be used to modify the current row of the database. These
commands will trigger an error with the read-only version.
\DTLremoveentryfromrow
, which would result in a blank row.
3.8.2.2. Examples[link]
\DTLdisplaydb*
or \DTLmapdata
.
3.8.2.2.1. Displaying Data[link]
\DTLforeach*
instead of \DTLdisplaydb
. Note that the use of
\DTLdisplaydb
is simpler and less problematic (see §3.9).
Note that the new row command \\ has been placed at the start of the
final argument. This is necessary as placing it at the end of the argument will
cause an unwanted row at the end of the table. This is a feature of the loop
mechanism.
\begin{tabular}
{llr}
\bfseries
Author &
\bfseries
Title &
\bfseries
Price (\$)%
\DTLforeach*
{products}%
{\Author
=Author,\Title
=Title,\Price
=Price}%
{\\% start new row
\Author
&
\Title
&
\Price
}
\end{tabular}
3.8.2.2.2. Stripy Table[link]
\DTLifoddrow
is used, which is expandable.
\rowcolor
.
\begin{tabular}
{llrrrr}
\bfseries
Surname &
\bfseries
Forename &
\bfseries
StudentNo &
\bfseries
Assign1 &
\bfseries
Assign2 &
\bfseries
Assign3%
\DTLforeach*
{marks}
{\Surname
=Surname, \Forename
=Forename,
\StudentNo
=StudentNo, \AssignI
=Assign1,
\AssignII
=Assign2, \AssignIII
=Assign3}
{%
\DTLifoddrow
{\\\rowcolor
{blue}}{\\\rowcolor
{green}}
\Surname
&
\Forename
&
\StudentNo
&
\AssignI
&
\AssignII
&
\AssignIII
}%
\end{tabular}
\DTLifnumlt
is a robust command and will therefore cause a
problem. Either use the method provided in Example 85
or in Example 93.
3.8.2.2.3. Displaying the Data with an Extra Column at the Start[link]
Note that the \begin{tabular}
{rllrrrr}
\bfseries
Row &
\bfseries
Surname &
\bfseries
Forename &
\bfseries
StudentNo &
\bfseries
Assign1 &
\bfseries
Assign2 &
\bfseries
Assign3%
\DTLforeach*
{marks}
{\Surname
=Surname, \Forename
=Forename,
\StudentNo
=StudentNo, \AssignI
=Assign1,
\AssignII
=Assign2, \AssignIII
=Assign3}
{%
\label
{\StudentNo
}
\\ \theDTLrowi
&
\Surname
&
\Forename
&
\StudentNo
&
\AssignI
&
\AssignII
&
\AssignIII
}%
\end{tabular}
\label
must occur in the same scope as \refstepcounter
. This
means that it has to go before the new row \\ which automatically starts
a new scope.
find
action.
3.8.2.2.4. Displaying the Data with an Extra Column at the End[link]
\DTLforeach*
instead of \DTLdisplaydb
to display the data with an
extra column showing the total (quantity times price) as well as the running
total at the end. Note that the scoping introduced by the cells in the
tabular environment means that the running total must be globally
updated.
\newcommand
{\runningtotal
}{0}
\begin{tabular}
{lrrr}
\toprule
\bfseries
Title &
\bfseries
Quantity &
\bfseries
Price &
\bfseries
Total%
\DTLforeach*
{products}% database
{\theTitle
=Title, \theQuantity
=Quantity,
\thePrice
=Price}%
{%
\DTLiffirstrow
{\\\midrule
}{\\}\theTitle
&
\theQuantity
&
\thePrice
&
\DTLmul
{\theTotal
}{\theQuantity
}{\thePrice
}%
\DTLround
{\theTotal
}{\theTotal
}{2}%
\DTLgadd
{\runningtotal
}{\runningtotal
}{\theTotal
}%
\theTotal
}%
\\\midrule
&
&
&
\runningtotal
\end{tabular}
\DTLiffirstrow
) that determines
whether to just start a new row with \\
or to start a new row
and insert a horizontal rule with \\
. If you
need something like this in your document, the conditional command must be
expandable otherwise you will get an error (see §3.9).
\midrule
3.8.2.2.5. Editing Rows[link]
\DTLforeach
instead of \DTLmapdata
to edit the database.
With \DTLmapdata
, the row aggregates are computed with the
row aggregate
action, but with \DTLforeach
the
current row aggregate
action must be used instead.
The database can then be sorted by the average mark and displayed:
\DTLforeach
{marks}{}{%
\DTLaction
[
keys
={Assign1-},
options
={mean},
datum
={round=1},% round the result
return
={\Mean
=mean}
]
{current row aggregate
}
\DTLifnull
{\Mean
}% test the return value
{}% row aggregate failed!
{% average calculated successfully
\DTLappendtorow
{Average}{\Mean
}%
}
}
\DTLsortdata
{marks}{Average=desc}
\DTLdisplaydb
{marks}
3.9. Loops and Conditionals with tabular-like Environments[link]
\bfseries
, at the start of a cell without affecting the rest
of the row. For example:
\begin{tabular}
{cr}
\bfseries
A &
B\\
\itshape
C &
D
\end{tabular}
A
B
C
D
\newcount
\myrowctr
\begin{tabular}
{cr}
\advance
\myrowctr
by 1\relax
A &
B (\the
\myrowctr
)\\
\advance
\myrowctr
by 1\relax
C &
D (\the
\myrowctr
)
\end{tabular}
A
B (0)
C
D (0)
\advance
with \global
to make the
change global, but a higher-level more LaTeX solution is to define
a counter and increment it with \stepcounter
(or
\refstepcounter
), which will make the change global. For
example:
\newcounter
{myrowctr}
\begin{tabular}
{cr}
\stepcounter
{myrowctr} A &
B (\themyrowctr
)\\
\stepcounter
{myrowctr} C &
D (\themyrowctr
)
\end{tabular*}
A
B (1)
C
D (2)
\DTLforeach
does and, to allow it to be nested,
there are three counters (DTLrowi, DTLrowii and
DTLrowiii) associated with each level. These counters are
incremented globally (with \refstepcounter
). The placeholder
commands also need to be globally defined, as well as various other
commands that need to change at each iteration.
\DTLforeach
can, to a limited extent, be used
within a tabular-like context but \DTLmapdata
, which only
locally defines or changes variables, can’t. This means that
\DTLmapdata
can be scoped to prevent any local assignments or
changes conflicting with other content, whereas \DTLforeach
can’t.
This now causes a “misplaced \newcounter
{myrowctr}
\newcommand
{\myrowhook
}{%
\stepcounter
{myrowctr}%
\ifthenelse
{\isodd
{\value
{myrowctr}}}{}{\hline
}%
}
\begin{tabular}
{cr}
\myrowhook
A &
B (\themyrowctr
)\\
\myrowhook
C &
D (\themyrowctr
)
\end{tabular}
\noalign
” error.
\DTLdisplaydb
and \DTLdisplaylongdb
.
\newcommand
and append to it using commands
provided by etoolbox. For example, first define the counter
and the command that will be used to store the content of the
tabular environment:
Provide a command to initialise the above (in case multiple tables
are needed):
\newcounter
{myrowctr}
\newcommand
{\mytabcontent
}{}
Provide a command to finish off:
\newcommand
{\InitTabContent
}{%
\renewcommand
{\mytabcontent
}{\begin{tabular}
{cr}}%
\setcounter
{myrowctr}{0}%
}
Now a command is needed to add a row. Note that the row separator
\\ needs to be inserted at the end of all but the last
row, which is the same as inserting it at the start of all but the
first row. So this first checks if the counter is 0 before incrementing it
to determine whether or not to insert \\.
A horizontal line is inserted every even row (after the counter has
been incremented). Alternatively, this could be modified to insert
\newcommand
{\FinishTabContent
}{%
\appto
\mytabcontent
{\end{tabular}
}%
}
\hline
before the counter is incremented when it’s odd. The two
arguments provided are appended without expansion to the content
(separated by &
). However, the value of the row counter must be expanded
when it’s added so \eappto
is required.
Once the custom commands have been defined, they can be used:
\newcommand
{\AddRow
}[2]{%
\ifthenelse
{\value
{myrowctr}=0}{}{\appto
\mytabcontent
{\\}}%
\stepcounter
{myrowctr}%
\ifthenelse
{\isodd
{\value
{myrowctr}}}{}%
{\appto
\mytabcontent
{\hline
}}% even row
\appto
\mytabcontent
{#1 &
#2}%
\eappto
\mytabcontent
{ (\themyrowctr
)}%
}
This doesn’t actually display the tabular content, but at the end of
the above, the replacement text of the custom command
\InitTabContent
\AddRow
{A}{B}% add first row
\AddRow
{C}{D}% add second row
\FinishTabContent
\mytabcontent
now contains the content of the tabular
environment without the awkward conditionals. You can confirm this with:
This will show the content in the transcript or terminal when you
run LaTeX:
\show
\mytabcontent
>
You can now go ahead and put \mytabcontent
=macro:
->\begin
{tabular}{cr}A &
B (1)\\\hline
C &
D (2)\end
{tabular}.
\mytabcontent
where you want
your table.
The custom command to initialise these variables is now provided as
a document command, which is robust:
\ExplSyntaxOn
\int_new:N
\l_my_row_int
% new integer variable
\tl_new:N
\l_my_content_tl
% new token list variable
Similarly for the command that finishes off:
\NewDocumentCommand
\InitTabContent
{ }
{
\tl_set:Nn
\l_my_content_tl
{ \begin{tabular}
{ cr } }
\int_zero:N
\l_my_row_int
}
And for the command that adds values to the first and second columns
of the current row:
\NewDocumentCommand
\FinishTabContent
{ }
{
\tl_put_right:Nn
\l_my_content_tl
{ \end{tabular}
}
}
The rest is as before:
\NewDocumentCommand
\AddRow
{ m m }
{
\int_if_zero:nF
{ \l_my_row_int
}
{ % row index not zero
\tl_put_right:Nn
\l_my_content_tl
{ \\ }
}
\int_incr:N
\l_my_row_int
\int_if_even:nT
{ \l_my_row_int
}
{ % row index even
\tl_put_right:Nn
\l_my_content_tl
{ \hline
}
}
\tl_put_right:Nn
\l_my_content_tl
{ #1 &
#2 }
\tl_put_right:Nx
\l_my_content_tl
{ ~
( \int_use:N
\l_my_row_int
) }
}
\ExplSyntaxOff
\InitTabContent
\AddRow
{A}{B}% add first row
\AddRow
{C}{D}% add second row
\FinishTabContent
\noalign
errors.
\DTLmapdata
to iterate over
the data in the “marks” database (see §3.2.1).
The average mark is calculated using the row aggregate
action and a row is only appended if the average is 50 or above. Any
row that has an average above 70 is highlighted using \rowcolor
(which requires the colortbl package).
\DTLdisplaydb
(which internally applies a similar method). See
Example 85 in
§3.7.3.14, which produces almost the same
but has an extra column showing the student number.
The initialisation command is the same as before but now its an
internal command:
\ExplSyntaxOn
\int_new:N
\l_my_row_int
\tl_new:N
\l_my_content_tl
\tl_new:N
\l_my_forename_tl
\tl_new:N
\l_my_surname_tl
\tl_new:N
\l_my_mean_tl
Similarly for the command to finish off:
\cs_new:Nn
\my_init_content:
{
\tl_set:Nn
\l_my_content_tl
{ \begin{tabular}
{ lr } }
\int_zero:N
\l_my_row_int
}
The command that adds a row is different. The first argument will be
the student’s name and the second argument will be the average
score. These will be supplied with placeholder commands so the
values will need to be expanded when they are appended to the token
list variable. The command starts off with a test to determine if
the mean is greater than or equal to 50. This test is actually done in
reverse (that is, the code is only done if \(\text {mean} < 50\) is
false).
\cs_new:Nn
\my_finish_content:
{
\tl_put_right:Nn
\l_my_content_tl
{ \end{tabular}
}
}
The document command iterates over the default database.
(Alternatively, you can adapt this to provide an argument with the
database name.) The surname and forename are fetched using
\cs_new:Nn
\my_add_row:nn
{
\fp_compare:nNnF
{ #2 } < { 50 }
{
\int_if_zero:nF
{ \l_my_row_int
}
{
\tl_put_right:Nn
\l_my_content_tl
{ \\ }
}
\int_incr:N
\l_my_row_int
\fp_compare:nNnT
{ #2 } > 70
{
\tl_put_right:Nn
\l_my_content_tl
{ \rowcolor
{ yellow } }
}
\tl_put_right:Nx
\l_my_content_tl
{ #1 &
#2 }
}
}
\DTLmapgetvalues
and the mean is obtained with the
row aggregate
function. Be careful with actions with spaces
in their name when you have LaTeX3 syntax on as spaces are ignored.
You will need to use ~
where a space must actually occur.
This custom command can now be used in the document at the point
where the table is required.
\NewDocumentCommand
{ \meanscorestab
}
{
\my_init_content:
\DTLmapdata
{
\DTLmapgetvalues
{
\l_my_surname_tl
= Surname ,
\l_my_forename_tl
= Forename
}
\DTLaction
[
keys
={Assign1-},
datum
={round=1},
return
={ \l_my_mean_tl
= mean },
options
=mean
]
{ row ~ aggregate }
\my_add_row:nn
{ \l_my_forename_tl
\c_space_tl
\l_my_surname_tl
}
{ \l_my_mean_tl
}
}
\my_finish_content:
% expand the content:
\l_my_content_tl
}
\ExplSyntaxOff
3.10. Null Values[link]
\DTLmapget
, provide a way to fetch a
value from a row in a database. Return values for actions can also
be fetched using the return
option or with \DTLget
.
In either case, if you try to fetch a value that hasn’t been
set then you will get a null value.
\ifdefempty
or
similar.
\DTLmapgetvalues
or with the return
option in
\DTLmapget
, then you can test if that command
represents a null value with:
3.10.1. Examples[link]
\DTLsetup
{default-name=customers}
\DTLread
{customers.csv}
5,,Duck,Dickie,dd@example.com,
This has an empty value in the second column (Organisation, a string
column) and in the final column (Age, a numeric column). If these
values are fetched from the database, they will expand to empty.
By way of contrast, the next line is missing the final column:
6,Newt Fellowship,Axolotl,Lizzie,la@example.com
The difference is subtle (there’s no trailing comma) but in this
case, if the age is fetched from this row, a null value will be
returned.
display
action:
String null values show as “NULL” and numeric null values show as 0.
Whereas empty values show nothing.
\DTLaction
{display}
In this case, the Organisation and Age column aren’t set for this
row. This means that if an attempt is made to fetch those values,
null will be returned. Compare this with another row:
\DTLaction
[
assign
={
Id = 5, Surname = {Duck}, Forename = {Dickie},
Email = dd@example.com
}
]{new row
}
Here, the Age and Email columns are missing but the
Organisation column is set to empty. This means that if an attempt
is made to fetch the Age or Email from this row, null will be
returned, but an attempt to fetch the Organisation will return an
empty value.
\DTLaction
[
assign
={
Id = 9, Organisation = {},
Surname = {Mander}, Forename = {Sally}
}
]{new row
}
\newcommand
{\checkmissing
}[1]{\DTLifnull
{#1}{---}{#1}}
display
action uses the same underlying function as
\DTLdisplaydb
which encapsulates strings with
\dtlstringformat
, integers with \dtlintformat
, decimals
with \dtlrealformat
and currency with \dtlcurrencyformat
.
The numeric formatting commands all internally use
\dtlnumericformat
, so only \dtlstringformat
and
\dtlnumericformat
need to be redefined to use the custom
command:
Note that the empty Organisation field is still shown as empty not
as a dash. Use \renewcommand
{\dtlstringformat
}[1]{\checkmissing
{#1}}
\renewcommand
{\dtlnumericformat
}[1]{\checkmissing
{#1}}
\DTLifnullorempty
if you want to check for empty
as well.
The database is iterated over using \newcommand
{\checkmissing
}[1]{%
\DTLifnullorempty
{#1}{\emph
{Missing}}{#1}}
\DTLmapdata
.
The forename, surname and organisation can be shown
for each customer:
Note that it won’t work if you use \DTLmapdata
{
\DTLmapgetvalues
{\Surname
=Surname,\Organisation
=Organisation}
Forename: \DTLmapget
{key
=Forename}.
Surname: \checkmissing
{\Surname
}.
Organisation: \checkmissing
{\Organisation
}.
\par
}
\DTLmapget
in the argument
of \DTLifnull
or \DTLifnullorempty
as the command
\DTLmapget
{ } doesn’t represent null.
Either use \DTLmapgetvalues
(as above) or get the value with
return
. The actual code used in
Example 97 has a second custom command that
both fetches and tests the value:
\newcommand
{\showvalue
}[1]{%
\DTLmapget
{key
=#1,return
=\myReturnVal
}% fetch value
\checkmissing
{\myReturnVal
}%
}
\DTLmapdata
{
Forename: \showvalue
{Forename}.
Surname: \showvalue
{Surname}.
Organisation: \showvalue
{Organisation}.
\par
}
3.10.2. Advanced Commands[link]
\DTLifnull
, but you can do a simple test against
\dtlnovalue
. For example, with \ifdefequal
(provided by
etoolbox). The difference is that \DTLifnull
will also
test for the string null and number null commands, below.
\DTLdisplaydb
) will set the placeholder that stores the value
of the current row and column to a “string null” or “numeric
null” according to the column type. So the \DTLifnull
and
\DTLifnullorempty
tests for null will also compare their first
argument against the following.
\dtlnovalue
, \DTLstringnull
and \DTLnumbernull
.
\dtlnovalue
, \DTLstringnull
and \DTLnumbernull
and the empty datum constant \c_datatool_empty_datum_tl
as well as testing if the token list variable has an empty value.
\datatool_if_null:NTF
otherwise the result will be false.
The higher level user command \DTLifnull
now simply uses
\datatool_if_null:nTF
.
\datatool_if_null_or_empty:NTF
otherwise it will be true if the
argument is empty and false otherwise.
The higher level user command
\DTLifnullorempty
now simply uses \datatool_if_null_or_empty:nTF
.
\datatool_if_null_or_empty:nTF
won’t test for the string or numeric null values represented by
\DTLstringnull
and \DTLnumbernull
.
3.11. Special Values[link]
new entry
action, the expand-value
and expand-once-value
will remove the special command
and it won’t be considered a special value.
\DTLwrite
,
any entry starting with \dtlspecialvalue
will be allowed to
expand, regardless of the I/O expand
setting. Note that if there
is any trailing content after the argument of \dtlspecialvalue
that will also expand. This doesn’t apply to any of the other file
formats. For example, if you export to DTLTEX or CSV then
\dtlspecialvalue
will be included with expand
=none.
select row
action) where the entry has the
\dtlspecialvalue
command.
3.12. Editing Database Rows[link]
\DTLmapdata
with the allow-edits
option set (see §3.8.1.2
and Example 87) or with the unstarred \DTLforeach
(see
§3.8.2.1 and Example 92).
\dtlcurrentrow
token register, the preceding rows in the
\dtlbeforerow
token register, and the following rows in the
\dtlafterrow
token register.
\dtlcurrentrow
register using the
commands described in §3.16.1. Once all the required changes have
been made, the database contents can then be updated using \dtlrecombine
or,
if the row should be deleted, \dtlrecombineomitcurrent
.
\dtlgetrow
or you can use the
select row
action (or the find
action with the option
select=true).
\DTLdisplaydb
and
\DTLforeach
set the current row, if you use and of the editing commands
described in §3.16.1 within the loop body, they will cause
interference. Within \DTLforeach
, use the designated commands described
in §3.8.2.1.
\DTLdisplaydb
, the current row is only set to allow querying values
from the hooks while the tabular contents are being constructed (for
example, to fetch an entry from the current row or to compute aggregates with
the current row values
or current row aggregate
actions).
\dtlgetrow
:
If it’s possible that the row index may not be the same as the Id value,
\dtlgetrow
{customers}{9}
\dtlgetrowforvalue
may be used (since the Id column has unique values).
The column index (not the key) is needed in the reference. In this case the
Id column has index 1:
If the index isn’t known, it can be obtained with \dtlgetrowforvalue
{customers}{1}{9}
\dtlcolumnindex
:
Alternatively, the \dtlgetrowforvalue
{customers}
{\dtlcolumnindex
{customers}{Id}}% column index
{9}% value
select row
action may be used:
If a more complex selection criteria is required, the \DTLaction
[key
=Id,value
=9]{select row
}
find
action can be used.
Remember that the select option should be set if the find
action
should select the current row.
This row doesn’t have the Age and Email columns set. These can be appended, but note
that in this case the column key rather than column index is supplied. This is because
a new column will be created if it hasn’t already been defined for the database.
\dtlreplaceentryincurrentrow
{Newt Fellowship}% new value
{\dtlcolumnindex
{customers}{Organisation}}% column index
Alternatively, \dtlappendentrytocurrentrow
{Email}% column key
{s@example.com}% value
\dtlupdateentryincurrentrow
may be used to update an entry
if the column is already set or append it otherwise. This again takes the key rather
than the column index as the first argument:
\dtlupdateentryincurrentrow
{Age}% column key
{23}% value
\dtlbeforerow
, \dtlcurrentrow
and \dtlafterrow
content needs to be recombined in order to finish the updates:
\dtlrecombine
The database now needs to be reconstructed without this row:
\dtlgetrowforvalue
{customers}
{\dtlcolumnindex
{customers}{Id}}% column index
{2}% value
Example 98 then redisplays the data after these modifications.
(Compare with the original data shown in Example 94.)
\dtlrecombineomitcurrent
3.13. Arithmetical Computations on Database Entries[link]
aggregate
action (see §3.3) provides
a way of aggregating numeric data in one or two columns of a
database. Alternatively, you can use the commands listed here. Aside
from \DTLcomputebounds
, the aggregate commands in this section
return formatted numbers. Additionally, rows may be filtered
according to a condition. This is different to the
aggregate
action which returns plain numbers with the
default datum
=false action setting (see Example 69).
\ifthenelse
.
The second optional argument may be set to the
assignment list suitable for use
in =
\DTLmapgetvalues
so that the placeholder commands
may be referenced in . If the condition evaluates
to false, the row will be omitted from the total. Note that any
non-numeric values will automatically be skipped.
\DTLsumforkeys
.
\DTLsumforkeys
.
\DTLsumforkeys
.
\DTLsumforkeys
.
\DTLsumforkeys
.
aggregate
action. Note, however, that specifying two
columns in the aggregate
action indicates two separate sets
of data, whereas two columns with commands like \DTLsumforkeys
treats both columns as a single block of data.
\ifthenelse
. Only values in rows where the
conditional evaluates to true will be referenced.
aggregate
action:
\DTLaction
[ ]{aggregate
}
\DTLget
[min]{ }
\DTLget
[min2]{ }
\DTLget
[max]{ }
\DTLget
[max2]{ }
3.14. Sorting a Database[link]
\DTLsortdata
(described in §3.14.1), which is
analogous to \DTLsortwordlist
. It’s more efficient and more flexible than the
older \dtlsort
(described in §3.14.2).
3.14.1. Sorting with
\DTLsortdata
[link]\DTLsortwordlist
, in that it
first converts all the sort values into byte sequences using a
handler function, such as \DTLsortwordhandler
, and then sorts
the byte sequences. This makes sorting faster as it doesn’t have to
repeatedly parse each sort value.
\DTLsetup
) should be sorted. Available are
described in §3.14.1.1 and the
argument is described in
§3.14.1.2.
3.14.1.1.
\DTLsortdata
Options[link]\DTLsortdata
should be
a = list of any of the following:
{
.
If set, all non-null values will be encapsulated with this
command and expanded before being passed to the handler function. The first
argument }{ }{ } is the actual value, the second
is the column index from which the value was obtained, and
is the database name.
encap
set. Be
careful of fragile commands in the database if this option is used.
encap
={} indicates no encapsulation.
Example 179 in §7.10.1 uses
this option to encapsulate values with \DTLbibsortencap
.
replacements
column option is set). The
value may be either null, which will only replace null
values, or null or empty, which will replace null or empty
values.
\DTLsortdata
will
obtain the letter group (using \DTLassignlettergroup
) from the
sort value and save it in the column identified by .
If the column doesn’t exist, it will be created.
After obtaining the letter group, the value will be post-processed
by:
This requires LaTeX3 syntax and does nothing by default. The
argument is the token list variable used to store the letter group.
save-group-key
but identifies the column by its
index. Note that in this case, the column must either exist or be
one more than the database’s column count.
save-group-key
=group.
\DTLsortdata
will
save the sort value in the column identified by .
If the column doesn’t exist, it will be created. This
is primarily intended for debugging. If the resulting order is
unexpected, this can be used to check that the sort values were
correctly set. Alternatively, you can use the verbose package
option to view the information in the transcript.
save-sort-key
but identifies the column by its
index. Note that in this case, the column must either exist or be
one more than the database’s column count.
save-sort-key
=sort.
3.14.1.2.
\DTLsortdata
Column Options[link]\DTLsortdata
should be a comma-separated list where each item is in the form
where
={ } is the label identifying a column to sort and
is a = list of options that apply to
that column.
={
part may be omitted if
the default options should be used. If present, the following
options are available:
}ascending
=true.
ascending
. If true, the sort
will be in descending order.
descending
=true.
replace
) is encountered.
\DTLsortdata
{marks}{Surname,Forename,StudentNo}
replacements
option in .
Whether or not an empty value (as opposed to a null value) is
considered missing is determined by the replace
option, which may be supplied in the optional argument of
\DTLsortdata
.
3.14.1.3.
\DTLsortdata
Examples[link]
In this case, no replacement columns are provided, so the sort value
for the Organisation column in the Polly Parrot, Dickie Duck and
Sally Mander rows will be empty and those rows will be placed at the
start. Their relative order is then determined by their Surname, so
the Dickie Duck row comes first. (Compare Example 99 with the
near identical Example 102 which has localisation
support.)
\DTLsortdata
{customers}{Organisation,Surname,Forename}
\DTLdisplaydb
. Whereas empty values
show as empty. This is why Dickie Duck’s age is blank in the Age
column, because it was set to empty, but the missing ages (where
there was no trailing comma at the end of the line in the CSV
file) show as 0.
\DTLsortdata
by Organisation, Surname and Forename With
No Replacements 📥🖹 📥🖺
In this case, if the sort value is missing from the designated
column, the first column within the corresponding
\DTLsortdata
{customers}
{
Organisation={replacements
={Surname,Forename}},
Surname={replacements
={Forename}},
Forename
}
replacements
list that doesn’t have a missing
value will be used.
Primary In this example, the primary sort value is obtained
from the Organisation column. If that value is missing, the primary
sort value will be obtained from the Surname column, but if that is
also missing then the primary sort value will be obtained from the
Forename column. If that is also missing, then the primary sort
value will be empty.
\DTLsortdata
by Organisation, Surname and Forename With Replacements 📥🖹 📥🖺
replace
={null or empty} setting will treat empty
values as missing, so in Example 101
the resulting order is the same as for Example 100.
However, changing the setting so that only null (not empty) values
are treated as missing results in a different order.
\DTLsortdata
[replace
=null or empty]{customers}
{
Organisation={replacements
={Surname,Forename}},
Surname={replacements
={Forename}},
Forename
}
\DTLsortdata
[replace
=null]{customers}
{
Organisation={replacements
={Surname,Forename}},
Surname={replacements
={Forename}},
Forename
}
\usepackage
[locales=en-GB]{datatool}
The difference between the two is that Example 103
uses data from the CSV file, which has an empty age element as
well as missing age elements, whereas Example 104
uses the data created within the document via action commands, which
has missing but not empty age elements. (There is an empty
Organisation element, but that column isn’t contributing to the
sort.)
\DTLsortdata
{customers}{Age,Surname}
This means that the students who obtained the same mark
for assignment 1 are listed in alphabetical order relative to each
other.
\DTLsortdata
{marks}
{
Assign1={descending
=true},
Surname={ascending
=true}
}
ascending
=true is the default, that
may be omitted for the Surname column, and descending
=true
may have the value omitted if it’s true, so the Assign1 column
criteria can be written as Assign1={
and since the part after the equals (descending
}=
) doesn’t contain any
commas or equals the outer bracing may be omitted. So the above can
be written more succinctly as:
Since \DTLsortdata
{marks}{Assign1=descending
,Surname}
desc
is a synonym of
descending
=true, this can also be written
as:
\DTLsortdata
{marks}{Assign1=desc
,Surname}
\DTLsortdata
by Descending Numeric and Ascending String
Values 📥🖹 📥🖺
3.14.2. Sorting with
\dtlsort
[link]\dtlsort
command is less efficient than the newer \DTLsortdata
,
although \dtlsort
has been rewritten in version 3.0 to use LaTeX3’s sequence sorting.
\DTLsortdata
,
the argument can’t be empty.
. The = may be
ascending or descending. If omitted, ascending is assumed.
\DTLsortdata
, where you may specify more information with
, with ={ }
\dtlsort
, only the
keywords “ascending
” or “descending
” may be used.
\dtlsort
and \DTLsortdata
is that with
\DTLsortdata
, the list of replacements is set for specific columns,
whereas with \dtlsort
, a single list of replacement columns may be
provided in the optional argument, which will be used if any of the columns
listed in have a missing value.
Also with \dtlsort
, the replacements are only used for null values (see §3.10)
not for empty values.
\DTLsortdata
, there’s no option to suppress the warning.) The list
of replacements may be omitted or empty but the argument must
have at least one defined column.
\DTLnumcompare
). In the event that two numeric values
are deemed equivalent, their string value will be compared using the provided
handler.
This will sort the “books” database on the “Author” column (in ascending order).
Any row that doesn’t have the Author column set will have the sort value obtained from the
“Editor” column instead. If that column also isn’t set, the sort value will be obtained from
the “Title” column.
\dtlsort
[Editor,Title]{Author}{books}
{\dtlwordindexcompare
}
In this case, the database will be sorted by the “Author” column first. If
that column isn’t set for a particular row, the sort value will be obtained
from the “Title” column. If the sort value (Author, if set, or Editor
otherwise) is equivalent to the other row being compared (that is, the sort
handler returns 0), then the two rows will be compared on the “Series”
column. If that column isn’t set, the Title will be used for the comparison
instead. If this secondary comparison is also considered equivalent, the two
rows will then be compared on the “Volume” column.
\dtlsort
[Title]{Author,Series,Volume}{books}
{\dtlwordindexcompare
}
\DTLsortdata
:
\DTLsortdata
{books}{
Author={replacements
={Editor,Organisation}},
Series={replacements
={Title}},
Volume
}
\dtlsort
. The starred version uses
\dtlicompare
as the handler function, and the unstarred version
uses \dtlcompare
.
\dtlsort
instead of \DTLsortdata
:
Note that this has produced a different result to Example 100
because with \dtlsort
[Surname,Forename]% replacements
{Organisation,Surname,Forename}% sort criteria
{customers}% database
{\dtlwordindexcompare
}% handler
\dtlsort
the replacements are only used for null values not for empty values.
Remember that in both examples, localisation support will need to be added to correctly
order values that contain non-ASCII characters.
\dtlsort
by Organisation, Surname and Forename With Replacements 📥🖹 📥🖺
3.15. Database Files (I/O)[link]
\DTLwrite
, described in §3.15.4, or
a new database can be created by reading in a file with
\DTLread
, described in §3.15.3.
3.15.1. File Formats[link]
\DTLwrite
of accidentally overwriting a required
document file, so the default file extension is either dtltex
(for files containing user commands, such as \DTLnewdb
)
or dbtex (for files containing special internal commands that
aren’t designed to be edited by hand).
format
=dbtex-3. It will be stripped when writing
to all other formats.
\DTLaction
commands that define a database, this is
slower to load than the dtltex formats. If you want to load
such a file, just use \input
or \InputIfFileExists
as
usual. There’s no provision to save a file in this form.
format
setting in the
optional argument of \DTLread
and \DTLwrite
or within the
io value in \DTLsetup
. The default is
format
=csv.
3.15.1.1. CSV and TSV Files[link]
\DTLwrite
and \DTLread
is
CSV. The only difference between format
=csv and
format
=tsv is the default file extension (csv or
tsv), and format
=tsv will additionally implement
\DTLsettabseparator
to set the separator to a tab character and
change the category code of the tab character to 12 (other).
Product,Price (\$)
Book,\$
the use the csv-content
=tex option. If the file
contains characters that are normally special to LaTeX but need to
be treated literally then use the csv-content
=literal
option. For example:
Product,Price (
$
)
Book,$
,
), and can be changed with the separator
option. Note
that if separator
comes after format
=tsv
in the same option list, this will change the separator but leave
the default extension as tsv.
"
), and can
be changed with the delimiter
option. The delimiter will
always be searched for when loading a CSV/TSV file
with \DTLread
, but you can control whether or not the delimiter
is written with \DTLwrite
with the add-delimiter
option.
\DTLsetup
, not in
the optional argument of \DTLread
. For example, to switch off
trimming:
\DTLsetup
{new-value-trim=false}
3.15.1.2. DTLTEX Files[link]
2.0 (
format
=dtltex-2)
This has the database name hardcoded in the
file and will always try to define the database. This format contains
commands like \DTLnewdb
but \DTLread
locally sets the
global option to true (as the internal workings of
\DTLread
need to be scoped). If you need a local definition,
you can simply input the file, with a command such as \input
.
format
=dtltex-3)
This has the database name identified near the start of
the file but it’s designed to allow the name
option to
override it and the load-action
=append option will
prevent the database from being created (to allow the content to be
appended to another database).
\DTLwrite
, both start with the line:
% DTLTEX
where
identifies the DTLTEX version number
(either 2.0
or 3.0
), and is the
document encoding (obtained by expanding \TrackLangEncodingName
).
Note that this will be incorrect if the encoding changes are
datatool is loaded. There’s no way of knowing if the encoding
was changed after the database was created. In general it’s best to
establish the document encoding as early as possible.
\DTMnow
(provided by the
datetime2 package), if that command has been defined, otherwise
\today
will be used.
\input
, so it only
contains normal user-level commands that have an argument to
identify the database name (see §3.4): \DTLnewdb
,
\DTLnewrow
, and \DTLnewdbentry
. The column headers will then be
set with \DTLsetheader
(regardless of the no-header
option).
Finally, \dtllastloadeddb
is defined to the database name:
(This line was introduced in datatool v2.15, so any file that
matches the rest of the format but omits this line should be
considered DTLTEX v1.0.)
Note that although \def
\dtllastloadeddb
{ }
\def
is used, \DTLread
will change
this to a global definition. Note that since these are all
document-level commands, the file can simply be loaded with
\input
. This method can be used to locally define the database
(provided global=false is set).
\DTLread
,
although the file can simply be \input
.
\DTLread
, this command will
locally set the default-name to either the name
value, if
set, or , otherwise, and will create the database if
required by load-action
.
\DTLdbProvideData
is used outside of the context of
\DTLread
, it will set the default-name to
and define the database if it doesn’t already exist.
\dtllastloadeddb
is defined to the database
name, and the is also set to the same value to
allow the database to be referenced in the following commands:
\DTLnewrow*
{ }
\DTLnewdbentry*
{ }{ }{ }
no-header
, \DTLwrite
will also
include code to set the header for each column with:
Note that this is different to DTLTEX v2.0, which always has the
header code.
\DTLsetheader*
{ }{ }{ }
3.15.1.3. DBTEX Files[link]
2.0 (
format
=dbtex-2)
This has the database name hardcoded in the
file and will always try to define the database.
format
=dbtex-3)
This has the database name identified near the start of
the file but it’s designed to allow the name
option to
override it.
load-action
=append option is not supported for
this format (for either version).
\DTLwrite
will start the file with
comment lines. The first identifies the format:
% DBTEX
where
identifies the DTLTEX version number
(either 2.0
or 3.0
), and is the
document encoding, as for DTLTEX. The second comment line is the
creation information, as for DTLTEX.
The rest of the file consists of low-level internal commands that define the
underlying registers and commands used to store the database information.
This means that \DTLifdbexists
{ }%
{\PackageError
{datatool}{Database ` ' already exists}{}%
\aftergroup
\endinput
}{}%
@
needs to have its category code set to “letter”.
A local scope is introduced to limit the effect of
\makeatletter
and a message will be written to the transcript
if verbose mode is on:
This means that the internal commands used to store the database
information must be globally defined. (Note that \bgroup
\makeatletter
\dtl@message
{Reconstructing database ` '}%
\global
is
redundant as all registers are globally defined, but this is now
part of the DBTEX v2.0 file format.) The column meta data is stored
in a token register, which needs to be defined and then set:
Similarly, the database content is stored in a token register, which
needs to be defined and then set:
\expandafter
\global
\expandafter
\newtoks
\csname
dtlkeys@\endcsname
\expandafter
\global
\csname
dtlkeys@\endcsname
={ }
The total number of rows is stored in a count register that needs to
be defined and set:
\expandafter
\global
\expandafter
\newtoks
\csname
dtldb@\endcsname
\expandafter
\global
\csname
dtldb@\endcsname
={ }
Similarly, the total number of columns is stored in a count register that needs to
be defined and set:
\expandafter
\global
\expandafter
\newcount
\csname
dtlrows@\endcsname
\expandafter
\global
\csname
dtlrows@\endcsname
=\relax
The column key to index mapping is implemented by defining:
\expandafter
\global
\expandafter
\newcount
\csname
dtlcols@\endcsname
\expandafter
\global
\csname
dtlcols@\endcsname
=\relax
This is done for each column. Finally, the local scope is ended and
\expandafter
\gdef
\csname
dtl@ci@ @\endcsname
{ }%
\dtllastloadeddb
is defined:
Note that \egroup
\def
\dtllastloadeddb
{ }%
\dtllastloadeddb
was only introduced in
datatool v2.15, so if the last line is omitted, the file
should be considered DBTEX v1.0.
These commands are quarks and have no meaning. Unpredictable results
can occur in loops if the header blocks aren’t in order of the column index.
It depends on whether the loop iterates over the column index or
maps over the header blocks.
\db@plist@elt@w
\db@col@id@w
%
\db@col@id@end@
%
\db@key@id@w
%
\db@key@id@end@
%
\db@type@id@w
%
\db@type@id@end@
%
\db@header@id@w
%
\db@header@id@end@
%
\db@col@id@w
%
\db@col@id@end@
%
\db@plist@elt@end@
%
\DTLwrite
automatically inserts the comment character
at the end of most lines, even though they are not always required.
If you are writing a tool that reads DBTEX files, remember to
discard the comments.
Again, these commands are quarks and have no meaning, and unpredictable results
can occur if the blocks aren’t ordered according to the row index.
The consists of sub-blocks ( ) that contain the data for each entry in the given row and
column:
\db@row@elt@w
%
\db@row@id@w
%
\db@row@id@end@
%
\db@row@elt@w
%
\db@row@elt@w
%
\db@row@id@w
%
\db@row@id@end@
%
where is the column index and is the
value for that column.
Again, these commands are quarks and have no meaning, and unpredictable results
can occur if the blocks aren’t ordered according to the column index.
\db@col@id@w
%
\db@col@id@end@
%
\db@col@elt@w
%
\db@col@elt@end@
%
\db@col@id@w
%
\db@col@id@end@
%
\makeatletter
is used to allow
internal commands, which means that @
will have a letter
category code. This will affect any data contained in the database
that includes the @
character (for example, if the database
has an email column). See Example 107. Although
the quarks have no meaning, spaces following those commands are
ignored. This means that if an entry starts with a space that space
will be lost.
\ExplSyntaxOn
(most notably
the space character). Therefore, the datum items markup is
stripped by \DTLwrite
, since it contains LaTeX3 commands. The
only way to retain it is via DBTEX v3.0, which hides the LaTeX3
syntax within its custom reconstruction commands, which expand the content
before setting the underlying token registers. This is faster than
constructing the content with \DTLnewdbentry
, but not as fast
as explicitly setting the token register, as is done with DBTEX v2.0.
This sets up the to either the \DTLdbProvideData
{ }
name
setting, if provided, or , otherwise. This allows the
appropriate name to be used in the subsequent commands. Note that
this command also defines \dtllastloadeddb
to the database
name, but within \DTLread
it doesn’t define the database with
the DBTEX formats as the database internals are either explicitly
defined (format
=dbtex-2), or they are constructed by
the following command:
\dtl@ci@
to expand to
@ , described above for DBTEX v2.0.)
The is more complicated, but is designed to
expand to the explicit , describe above for
DBTEX v2.0.
\DTLreconstructdatabase
{ }{4}%
{% Header
\dtldbheaderreconstruct
{1}{Name}{0}{Name}%
\dtldbheaderreconstruct
{2}{Age}{1}{Age}%
\dtldbheaderreconstruct
{3}{Score}{2}{Score (\%
)}%
\dtldbheaderreconstruct
{4}{Award}{2}{Award (\protect
\$)}%
}% End of Header
{ }
{% Key to index
\dtldbreconstructkeyindex
{Name}{1}%
\dtldbreconstructkeyindex
{Age}{2}%
\dtldbreconstructkeyindex
{Score}{3}%
\dtldbreconstructkeyindex
{Award}4%
}% End of key to index
\$12,500
), is the
plain number numeric value (for example, 12500
) or
empty if the value is a string, is the currency
symbol (for example, \$
), and is the
numeric data type identifier.
3.15.2. I/O Settings[link]
\DTLread
,
described in §3.15.3, and saved to an external file
using \DTLwrite
, described in §3.15.4. Both
commands have an optional argument with the settings that govern the
format. Some of the settings are only applicable to a particular
format or to either reading or writing a file.
\DTLread
or
\DTLwrite
, these settings only have a local effect within
the read or write action. You can set up defaults with
the io option in \DTLsetup
. For example:
\DTLsetup
{
io={
separator
= {;},
delimiter
= {'},
format
= {csv}
}
}
keys
option) when reading a csv or
tsv file, then a default key will be used with
the column index prefixed with:
(for example,
the default key for column 4 will be “Column4”).
\dtldefaultkey
\DTLwrite
, and
determines whether or not to use the delimiter when writing to a
csv or tsv file.
This option has no effect on other formats.
The value may be one of the following.
), regardless of whether or not
the file has a header row. This option overrides any previous
\dtldefaultkey
keys
setting and is only applicable when reading a
csv or tsv file.
auto-keys
.
\DTLdecimaltolocale
or
\DTLdecimaltocurrency
, respectively.
Any other type of column will be parsed as usual.
\DTLread
parses
format
=csv or format
=tsv files.
This option is ignored by the other formats.
data-types
, and the values
in the indicated columns should be plain numbers.
The column data type will be updated if a value in that column is found to be
incompatible with the identified type.
\DTLread
and determines how
to act if an empty line is encountered in a csv and
tsv file.
This option has no effect with other formats.
csv-content
=tex.
\DTLread
and determines how
the content of csv and
tsv files should be interpreted.
This option has no effect with other formats.
Name ,Score (\%),{Award
(\$)}
Then with csv-content
=tex this will be read in as a
single header row. The grouping allows an element value to be split
across multiple lines. The first column will have the header
Name
, the second column will have the header
Score (\%)
and the third column will have the
header Award (\$)
.
csv-content
=literal this will be read in
as a header row on line 1 and a row containing a single column on
line 2. The header for the first column is again Name
, but
the header for the second column will be Score
(
, and the header for the
third column will be \textbackslash
\%)\{Award
. The entry of
the first column in the first row will be (
.
\textbackslash
\$)\}auto-keys
or keys
as the headers for the second
and third columns are inappropriate for keys.
"Chlo
In this case, the result depends on the \"
e",89,5.50
csv-escape-chars
setting, which determines whether or not to strip the backslash in
front of the double-quote. With
csv-escape-chars
=none the backslash isn’t removed,
so the value with csv-content
=literal will end up
as Chlo
(Chlo\"e). Whereas with
\textbackslash
"ecsv-content
=tex the value will end up as
Chlo\"e
(Chloë). With the other
csv-escape-chars
settings, the backslash will be removed in
both cases, and the value will be Chlo"e
.
Since the category code for the delimiter is automatically set to 12
(other) at the start of \DTLread
, that’s the category code it
will have in the value.
separator
and the
delimiter
pairs will be removed. Any escape backslashes
(\
) will be stripped according to csv-escape-chars
.
separator
and delimiter
. Each element is then
processed according to the following steps:
The regular expression in the second step uses
csv-escape-chars
;
\n
, \r
and \f
with a
space character, the sequence \t
with a tab character and
the TeX special characters with LaTeX commands (see Table 3.1);
\regex_replace_case_all:nN
with the cases provided in the token
list variable:
The default substitutions are listed in Table 3.1.
If you want to redefine this token list, remember that the input
string will only contain “other” and space tokens when the
substitution is performed.
csv-content
=literal Before
Re-ScanningOriginal
Substituted
#
\#
$
\$
%
\%
&
\&
\
\textbackslash
^
\textasciicircum
_
\_
{
\{
}
\}
~
\textasciitilde
\f
space
\n
space
\r
space
\t
tab character
\DTLloadrawdb
and
is retained for backward-compatibility.
\
) and delimiter
characters that occur
within a value in a CSV or TSV file should be escaped.
(That is, the character should have a backslash inserted in front of
it.)
format
=csv
and format
=tsv. Note that if a value contains the
separator
character, it should be delimited.
\DTLwrite
will insert a
leading backslash and \DTLread
will strip a leading backslash
from the delimiter
character but not from a backslash
character.
delimiter
and backslash characters should be escaped.
\DTLwrite
will insert a leading backslash and \DTLread
will strip a leading backslash from the delimiter
and
backslash characters.
\DTLwrite
won’t insert a leading backslash or
double the delimiter and \DTLread
won’t strip a leading backslash
or convert a double delimiter to a single instance.
false
(which is equivalent to
csv-skip-lines
=0) or a non-negative integer. If the value
is greater than zero, then \DTLread
will skip the first
lines in a format
=csv or
format
=tsv file where is the supplied value.
This option has no effect on other formats.
csv-content
=tex, a “line” may
actually cover multiple lines if a line break occurs within a group.
For example, if the file starts with:
Name ,Score (\%),{Award
(\$)}
"Chlo
Then with \"
e",89,5.50
csv-content
=literal and
csv-skip-lines
=1 then the first line to be parsed
will be the line:
(\$)}
whereas with csv-content
=tex and
csv-skip-lines
=1, the first line to be parsed will
be the line:
"Chlo
\"
e",89,5.50
\DTLread
parses
format
=csv or format
=tsv files.
This option is ignored by the other formats.
format
=csv and
format
=tsv files to ,
which must be a single token.
This setting is ignored by format
=dbtex and
format
=dtltex files.
add-delimiter
=never option.
expand
=protected is assumed.
\DTLwrite
is
expand
=none. The default for \DTLread
is the
current new-value-expand setting. If the value is omitted,
expand
=protected is assumed.
The value may be one of the following.
expand
=none.
Automatically implements new-value-expand=true.
expand
=none, \DTLwrite
will prevent expansion of an
element while writing to a file. However, with the DBTEX formats, if
a database element starts with the special datum item markup or
if the element starts with the command
\dtlspecialvalue
then the datum item will be
stripped in DBTEX v2.0 and \dtlspecialvalue
will be allowed to
expand. (The datagidx package uses this to clear the
“Used” and “Location” columns when writing the index/glossary database to a file for the next run.)
\DTLread
and \DTLwrite
.
The default setting is format
=csv (even if you
have separately set the separator to the tab character).
The format may be one of the following values:
separator
option and the delimiter given by the
delimiter
option. The default file extension is set to
csv. Note that the designated separator and delimiter will
have their category code set to “other”.
delimiter
option. The default
file extension is set to csv.
separator
option is specified after this option, then that
separator will be used instead, but the file extension will still
default to tsv.
\DTLread
. The file
is input as per a normal LaTeX file with
global=true and scoping to limit the effect of the options
and some local redefinitions. In terms of \DTLread
, the
difference between the specific format
values simply
determines the default file extension.
\DTLwrite
, the data will be written to the
file with document level user commands that include the database
name, such as \DTLnewdb
.
\DTLwrite
, the data will be written to the
file with v3.0 document level user commands described in §3.15.1.2.
format
=dtltex-3.
\DTLwrite
, the data will be written to the
file in DBTEX v2.0 format, which uses low-level internal commands to
define and set the registers used to store the data. Note that this
will cause any instance of @
in the database to have a letter
category code (see Example 107) and leading spaces
at the start of database elements will be lost. The DBTEX v3.0
format is better.
\DTLwrite
, the data will be written to the
file in DBTEX v3.0 format, which uses higher level internal commands.
format
=dbtex-3.
\DTLread
parses
format
=csv or format
=tsv files.
This option is ignored by the other formats.
trim
and skip-empty
settings. If you specifically want to
retain these, you will need to use braces around the item.
headers
is set to empty (the default), or there is no
item in the that corresponds to a given column, then
that column header will be the same as the column key.
This is equivalent to:
\DTLread
{headers
={ Name ,,Email,{},Notes,}}
{ }
The first column will be given the header “Name” and the second
column will be given the header “Email”. The third column will
have an empty header, and the fourth column will be given the header
“Notes”. If a fifth column is found in the file, the header for
that column will be the same as the key for that column.
\DTLread
{headers
={Name,Email,{},Notes}}
{ }
\DTLread
parses
format
=csv or format
=tsv files.
This option is ignored by the other formats.
trim
and skip-empty
settings. If you specifically want to
retain these, you will need to use braces around the item.
keys
is set to empty and auto-keys
=false
(the default), then the keys will be the column headers supplied in
the file. If there are no column headers (no-header
=true)
or the header is empty for a given column, then the corresponding
key in will be used. If there is no corresponding key in
, or if the corresponding key is empty, then the default
key is used.
keys
is used with a non-empty list (after stripping
extraneous spaces and commas) then it will automatically implement
auto-keys
=false. If auto-keys
=true is
subsequently used, it will override the keys
setting.
This is equivalent to:
\DTLread
{keys
={ Name ,,Email,{},Notes,}}
{ }
This will set the key to “Name” for the first column and
“Email” for the second. The third column will either pick up the
key from the header row in the file or, if that is missing, the key
will be \DTLread
{keys
={Name,Email,{},Notes}}
{ }
(“Column3”). The
fourth column will have the key “Notes”. If additional columns
are found in the file, they will act as for an empty element in the
list. So a fifth column will either pick up the
key from the header row in the file or, if that is missing, the key
will be \dtldefaultkey
(“Column5”).
\dtldefaultkey
\DTLread
should create a new
database or append to an existing one. This append setting does not
support format
=dtltex-2 or any dbtex format.
load-action
=append, otherwise
it behaves as load-action
=create.
load-action
=create
otherwise it behaves like load-action
=append.
\DTLwrite
for
all formats, and identifies the database to save. If
omitted, the general default-name setting will be used.
In the above, the database name remains “mydata” after
\newcommand
{\mydatacmd
}{mydata}
\DTLsetup
{io={name
=\mydatacmd
}}
\renewcommand
{\mydatacmd
}{otherdata}
\mydatacmd
is redefined.
\DTLread
, this option identifies the database name but
isn’t supported by all formats. This option is ignored by
dtltex-2 and dbtex-2.
If omitted, the default behaviour depends on the format:
csv and tsv will fallback on
the default-name setting, but dbtex-3 and
dtltex-3 will use the name provided in the file.
\DTLwrite
should omit
header information in the file. This option has no effect with
format
=dtltex-2, format
=dbtex-2
and format
=dbtex-3.
\DTLread
, this option only has an effect with the
format
=csv and format
=tsv formats.
If no-header
=true, then there’s no header row in the
file (taking into account any offset introduced with
csv-skip-lines
). The column keys will either be obtained
from the keys
setting or will be set to the default for the
given column index. The column headers will either be obtained from
the headers
setting or will be set to the key.
\DTLsetheader
to do nothing, unless
a corresponding value is found in the headers
option. This
means that the header will be the same as the column key unless the
headers
value supplies an alternative.
\DTLwrite
, this option will omit the header line for the
format
=csv and format
=tsv formats.
So the database content will start on the first line of the file.
With format
=dtltex-3, this will omit the code that sets
the column headers (but the column keys will still be used).
no-header
.
auto-reformat
numeric option and
the auto-reformat
datetime option.
The value should be a comma-separated list of column index numbers.
\DTLread
parses
format
=csv or format
=tsv files.
This option is ignored by the other formats.
auto-reformat
numeric option and
the auto-reformat
datetime option
when parsing a column that’s included in the
only-reformat-columns
list.
If the list is empty, then no change will be made, so whatever
setting was in effect before the file was opened will be obeyed.
csv-skip-lines
but doesn’t allow the keyword
false
and doesn’t trigger an error for negative values.
\DTLwrite
. The value may
be one of the following.
format
=tsv.
.
Only applicable with \DTLsetup
{new-value-trim=}\DTLread
but not for
the dbtex formats.
3.15.3. Loading a Database from an External File[link]
\DTLread
.
name
option may be used to
specify the database name to override the default-name
setting. The name
option may also be used to override the
name supplied in DBTEX 3.0 and DTLTEX 3.0 files, but the name is
hardcoded in DBTEX 2.0 and DTLTEX 2.0 files, so the name
option will have no effect (other than to generate a warning).
\dtllastloadeddb
is defined to expand to the database
name.
\DTLread
[name
={},format
=dbtex]{ }
\let
\dtllastloadeddb
\DTLread
[name
={, }format
=csv,csv-content
=tex, ]{ }
\DTLread
[name
={, }format
=csv,csv-content
=literal, ]{ }
3.15.4. Saving a Database to an External File[link]
\DTLread
. The name
option identifies
the database. If that setting isn’t provided, the default-name
is assumed.
\DTLwrite
[name
={, }overwrite
=warn,format
=csv,expand
=none,add-delimiter
=detect]{ }
\DTLwrite
[name
={, }overwrite
=warn,format
=dbtex-2,expand
=full]{ }
\DTLwrite
[name
={, }overwrite
=warn,format
=dbtex-2,expand
=none]{ }
\DTLwrite
[name
={, }overwrite
=warn,format
=dtltex-2,expand
=full]{ }
3.15.5. I/O Examples[link]
Alternatively, you can setup the default database name first, to
avoid having to repeatedly specify it. The file extension may also
be omitted, as can \DTLread
[name
=customers,format
=csv]{customers.csv}
format
=csv which is the default:
Example 107 does this in the preamble. Setting the
default name makes it easier to use actions without having to
repeatedly write the database name.
\DTLsetup
{default-name=customers}
\DTLread
{customers}% parse customers.csv
select row
action can be used to find the row
where the Email column is set to the email address
fc@example.com
. If successful,
the row index can be accessed with \dtlrownum
.
The database hasn’t been modified, but it can be saved to the DBTEX
v3.0 format with:
\DTLaction
[key
=Email,value
=fc@example.com]
{select row
}
Row: \number
\dtlrownum
.
(The \DTLwrite
[format
=dbtex-3,overwrite
=allow]
{customers-v3}
overwrite
setting allows the test document to be
re-compiled afterwards without triggering an error.) This will
create a file called customers-v3.dbtex.
(If you try this example, compare the DBTEX v3.0 file with and
without the store-datum setting on.)
Note that although the DBTEX v3.0 file format includes the database
name (which will be “customers” in this example), this can be
overridden with the \DTLread
[format
=dbtex,name
=customers-v3]
{customers-v3}
name
option (but not with
default-name, which can’t be used to override the database
name if it’s hard-coded in the file).
select row
action is again used to
look up the row with the email fc@example.com
but note that
the database name now needs to be specified, since it’s not the
default:
\DTLaction
[
name
=customers-v3,
key
=Email,value
=fc@example.com
]{select row
}
Row: \number
\dtlrownum
.
This creates a file called customers-v2.dbtex.
\DTLwrite
[format
=dbtex-2,overwrite
=allow]
{customers-v2}
name
option is
used) nor does it support any load action other than
load-action
={create}. This means that the “customers”
database must be deleted before this new file can be loaded:
This should in theory still be identical to the original but it’s
not because the DBTEX v2.0 file format requires the category code of \DTLaction
{delete
}
\DTLread
[format
=dbtex]{customers-v2}
@
to be set to “letter”. This means that the row look up will now
fail.
This results in “Row: 0” (without an error) indicating that no
match was found because the \DTLaction
[key
=Email,value
=fc@example.com]
{select row
}
Row: \number
\dtlrownum
.
@
character in
has its usual “other”
category code, but the value
=fc@example.comfc@example.com
within the database has
the letter category code.
This is done in Example 108 and the data is then
displayed using the \DTLsetup
{store-datum,default-name=growthdata}
\DTLread
[
format
=tsv,csv-skip-lines
=1,
keys
={Exp1Time,Exp1Count,Exp2Time,Exp2Count}
]{growth}
display
action:
\DTLaction
{display
}
\usepackage
[locales={en-US}]{datatool}
\DTLsetup
{store-datum,default-name=profits}
auto-reformat
numeric option can be set before
reading the CSV file, but that will also reformat the first
column, which contains integers, but as they represent years they
shouldn’t be converted to formatted numbers.
only-reformat-columns
option can be used
to indicate that only columns 2 and 3 should be reformatted:
\DTLread
[
format
=csv,
csv-content
=tex,
only-reformat-columns
={2,3},
]{profits.csv}
\DTLsetLocaleOptions
{US}{currency-symbol-sep=thin-space}
display
action:
\DTLaction
{display
}
3.16. Advanced Database Commands[link]
\dtlgetrowindex
. The unstarred version triggers
an error if not found. (That is, if is set to null.)
\dtlgetrowindex
but expands the value.
\dtlgetrowindex
to find the row where the
entry in the column identified by its label exactly
matches the given value and (globally) performs the placeholder assignments in
, which should be a comma-separated
assignment list.
Unlike =
\DTLassign
, this command doesn’t change
the current row.
\DTLassignfirstmatch
, perform global
assignments when setting the placeholder commands. This is because
the underlying code is shared by \DTLforeach
, which was
designed to work within tabular-like environments and so had
to make global assignments to avoid the scoping created by the cells
within the tabular body (see §3.9).
Be aware that this can cause problems.
find
action to find the required row and make the assignments.
Alternatively, you can select a row to identify it as the current row and then
use the “current row” functions. For example, the current row aggregate
may be used to aggregate the data in the current row, or the row editing commands
may be used to edit the current row (see §3.12).
3.16.1. Operating on Current Row[link]
\DTLdisplaydb
, fetch the
content of the current row and store it in the token register:
\DTLdisplaydb
set \dtlrownum
to the filtered
row index. If rows have been omitted, \dtlrownum
will be less
than the actual database row index.
\dtlcurrentrow
register for the
column with the index and stores the value in
the control sequence . If you only know the column key, you
can obtain the column index with \dtlcolumnindex
.
list, where = is a
placeholder command (token list variable) and is the
column key. Each will be defined to the entry
in the column identified by or to null if the column
isn’t set in the current row.
\DTLaction
with the current row values
or current row aggregate
actions.
\dtlcurrentrow
and associated registers, you can select the
current row by its index with:
\dtlgetrow
, check that the database exists and
contains the required row number. This can be done with
\DTLifdbexists
(to test for existence) and test that the row
index is between 1 and the row count (which can be obtained with
\DTLrowcount
).
\dtlgetrow
, but gets the row where the entry
in the column with the given exactly matches the given
. Internally \dtlgetrowforvalue
uses \dtlgetrowindex
to
first fetch the row index. If the result is null then there was no
match and an error will occur, otherwise the row index is then used
to select the current row with \dtlgetrow
.
\edtlgetrowforvalue
This performs a protected expansion and then uses
\dtlgetrowforvalue
on the expanded value.
but the assignments are global. This first selects the current row
by its row index and then performs the assignments. If you prefer
local assignments, then select the row and use \dtlgetrow
{ }{ }
\DTLassignfromcurrentrow
{}
\DTLassignfromcurrentrow
instead. Alternatively, consider using the select row
action.
\dtlcurrentrow
token register. You will then need to recombine \dtlbeforerow
,
\dtlcurrentrow
and \dtlafterrow
in order to reconstruct
the database with the amendments.
\dtlbeforerow
,
\dtlcurrentrow
and \dtlafterrow
. The global option
is checked to determine if the change should be global.
\dtlbeforerow
with the rows in \dtlafterrow
, where the row
indexes are adjusted to account for the omitted current row.
\DTLforeach
, use the commands described in
§3.8.2 to alter the current row of the database,
not these ones.
\dtlcurrentrow
with the given value . The column data is updated according to the new value
honouring the global option (but \dtlcurrentrow
will only
be locally changed).
\dtlcurrentrow
for the column identified by .
The row must not already contain an element in the given column.
The column data is updated according to .
\dtlappendentrytocurrentrow
, if there is no
entry for the given column in the current row, otherwise updates the entry.
\dtlcurrentrow
.
\dtlcurrentrow
.
3.16.2. Advanced Iteration[link]
\dtlbreak
.
{
where }{ }{ }{ } is the column key, is the column index,
is the data type (\(-1\) for unknown) and is the column header.
#1
references the column key, #2
references the column index,
#3
references the data type (\(-1\) for unknown) and #4
references the column header.
\dtlbreak
.
\dtlbreak
.
\dtlbreak
.
\dtlgforint
but globally sets the count register.
There are environment versions, but note that the environment body can’t contain any verbatim.
\dtlgforint
where the iteration body is obtained from the environment
content with leading and trailing spaces trimmed.
4. Pie Charts (datapie package)[link]
\DTLsetup
instead (which means that
you would only be able to use options that can be set after
datatool has been loaded).
\DTLforeach
has been replaced with \DTLmapdata
. A
number of bugs have also been fixed, which may cause some
differences in the output.
Note that if datatool hasn’t already been loaded, this will
also apply rollback to datatool. Problems may occur if a newer
release of datatool has already been loaded.
\usepackage
{datapie}[=2.32]
list of placeholder command
assignments suitable for use in =
\DTLmapgetvalues
. The
variable setting must be set to the applicable .
Additional assignments may be added if required for the segment
inner or outer labels.
\ifthenelse
(see §2.4.2). Note that if this
option is provided, it will override the include-if/include-if-fn setting.
name
(for the database name), assign
(for
the assignment list corresponding to the argument
of \DTLpiechart
), and options
(for the pie chart
settings corresponding to the argument).
pie chart
action is equivalent to using \DTLpiechart
.
If you include the key
or column
action option
to identify the column to use for the variable then you can omit
variable in the options
setting.
See Example 111 for a simple example.
options
, it will override
the action key
or column
setting. However,
if variable has been previous set within the pie
option in \DTLsetup
and does not occur in the action
options
then the action key
or column
setting
will be used (if provided).
key
or
column
then a temporary placeholder command will be
created and added to the assignment list. If you don’t need to use
any of the database values in hooks or options (such as the segment
labels) then you may omit the assign
action option or
just assign the placeholders required for the labels. You will still
be able to use \DTLpievariable
or \DTLpiepercent
.
The segment colours are the default. See
Example 120 for an example that changes the
default colours. Note that in this case, only the Quantity column
needs to be referenced so only one assignment is made in the final
argument. See Example 116 for an example
that changes the inner and outer labels, with an extra assignment
to allow the corresponding Name item to be shown.
\DTLpiechart
{variable=\Quantity
}% variable required
{fruit}% database
{\Quantity
=Quantity}% assignment list
pie chart
action instead
of \DTLpiechart
:
\DTLaction
[
key
=Quantity % variable
]
{pie chart
}
4.1. Package Options[link]
\DTLsetup
. Additional options that may be set with
\DTLsetup
are listed in §4.2.
4.2. Settings[link]
\DTLsetup
. For example:
\DTLsetup
{pie={rotate-inner,rotate-outer}}
4.2.1. Pie Chart Data[link]
\DTLpiechart
.
This setting is required by \DTLpiechart
.
#1
for any row that should have its variable value
included in the pie chart, and do nothing otherwise.
See Example 112.
\DTLpiechart
. Either use one form or the
other. Don’t use both.
4.2.2. Pie Chart Style[link]
cutaway={1,3}
will
separated the first and third segments, whereas cutaway={1-3}
will separate the first three segments. An empty list, indicates no
cutaway segments.
\color
.
\color
. Note that if any segment colours have
previously been assigned and this list is smaller, this will only
override the given subset.
This will assign cyan and magenta to the first two segments, but the
third segment will be orange and the fourth green. Given the default
settings, the fifth segment will also be magenta, the sixth segment
will also be cyan, the seventh segment will be orange and the eighth
segment will be white. Alternatively, you can use
\DTLsetup
{pie={
segment-colors={pink,red,orange,green},
segment-colors={cyan,magenta},
}}
\DTLsetpiesegmentcolor
to set the colour of a specific segment.
4.2.3. Pie Chart Labels[link]
\DTLpievariable
placeholder, which shows the actual value. You can change this to
\DTLpiepercent
to show the percentage value instead, as in
Example 116.
\DTLpiepercent
.
4.3. Pie Chart Examples[link]
4.3.1. Pie Chart Filtering Examples[link]
This uses \DTLpiechart
{
variable=\Quantity
,% variable required
include-if={\DTLifstringeq
{\Name
}{Pears}{}{#1}}
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\DTLifstringeq
, which expands its arguments, to test value of
the placeholder command. Note that while you can use
etoolbox’s \ifdefstring
with the default
store-datum=false, it won’t work with
store-datum=true as then \Name
will be a
datum control sequence.
You can provide your own
custom command for use with the include-if or
include-if-fn settings. For example:
\DTLpiechart
[\equal
{\Name
}{Pears}]
{
variable=\Quantity
% variable required
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
Alternatively:
\ExplSyntaxOn
\NewDocumentCommand
\PieChartNameFilter
{ m m }
{
\datatool_if_value_eq:NnF
\Name
{ #1 } { #2 }
}
\ExplSyntaxOff
\DTLpiechart
{
variable=\Quantity
,% variable required
include-if={\PieChartNameFilter
{Pears}{#1}}
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\ExplSyntaxOn
\NewDocumentCommand
\PearFilter
{ m }
{
\datatool_if_value_eq:NnF
\Name
{ Pears } { #1 }
}
\ExplSyntaxOff
\DTLpiechart
{
variable=\Quantity
,% variable required
include-if-fn={\PearFilter
}
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
4.3.2. Pie Chart Styles Examples[link]
\DTLpiechart
{
variable=\Quantity
,
outer-label=\Name
,
cutaway={1,3},
start=45,
radius=3cm,
outline-width=1pt
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
and Example 115 which has separate consecutive
segments:
\DTLpiechart
{
variable=\Quantity
,
outer-label=\Name
,
cutaway={1-2},
}
{fruit}{\Quantity
=Quantity,\Name
=Name}
\DTLpiechart
{
variable=\Quantity
,
outer-label=\Name
,
cutaway={1,2}
}
{fruit}{\Quantity
=Quantity,\Name
=Name}
4.3.3. Pie Chart Labels Examples[link]
Note that this has added an extra assignment in the final argument
to provide a placeholder command for the corresponding item in the
“Name” column. See also Example 118
which includes the percentage symbol in the inner label and appends
the actual value to the outer label.
\DTLpiechart
{
variable=\Quantity
,
inner-label=\DTLpiepercent
,
outer-label=\Name
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}
\DTLpiechart
{
variable=\Quantity
,
rotate-inner,
rotate-outer,
inner-label=\DTLpiepercent
,
outer-label=\Name
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}
4.3.4. Pie Chart Placeholder Example[link]
\DTLpiechart
{
variable=\Quantity
,
round=0,
inner-label=\DTLpiepercent
\%,
outer-label=\Name
\
(\DTLpievariable
)
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}
4.3.5. Pie Chart Label Formatting Example[link]
\renewcommand
{\DTLdisplayinnerlabel
}[1]{%
\textcolor
{lightgray}{\bfseries
#1}%
}
\renewcommand
{\DTLdisplayouterlabel
}[1]{\textsf
{#1}}
4.3.6. Pie Chart Colour Example[link]
The outline width is set to 2pt. This can either be
done by explicitly changing \DTLsetpiesegmentcolor
{3}{yellow}
\DTLsetpiesegmentcolor
{4}{pink}
\DTLpieoutlinewidth
:
or implicitly via the outline-width option:
\setlength
{\DTLpieoutlinewidth
}{2pt}
Alternatively, outline-width may be set in the settings argument of
\DTLsetup
{pie={outline-width=2pt}}
\DTLpiechart
if it’s only applicable for that chart.
I’ve used \renewcommand
{\DTLdisplayouterlabel
}[1]{%
\DTLdocurrentpiesegmentcolor
\textsf
{\shortstack
{#1}}}
\shortstack
to compact the outer label by putting
the value below the name:
outer-label=
After the pie chart, a key is created with the tabular
environment. Note the limitations of \Name
\\(\DTLpievariable
)
\DTLmapdata
within a
tabular context, so \DTLforeach
is used instead:
\begin{tabular}
[b]{ll}
\DTLforeach
{fruit}{\Name
=Name}{%
\DTLiffirstrow
{}{\\}%
\DTLdocurrentpiesegmentcolor
\rule
{10pt}{10pt} &
\Name
}
\end{tabular}
4.4. Pie Chart Variables[link]
\DTLpievariable
to . The \DTLpievariable
command
is simply a convenient wrapper that allows the definition of the
inner or outer label to reference the segment value without needing
to know the assignment list used in the final argument of
\DTLpiechart
, and also identifies the required column to use
for the numeric value if multiple fields are assignment.
4.5. Pie Chart Label Formatting[link]
4.6. Pie Chart Colours[link]
\color
.
See Example 120.
This starts by initialising the first eight segment colours to
shades of grey, then the first two segment colours are changed to
pink and green (empty items are skipped when the CSV list is
parsed), then the sixth segment colour is changed to purple, and the
ninth segment colour (which hasn’t yet been set) is set to teal.
Segments 3, 4, 5, 7, and 8 are still shades of grey.
\usepackage
[gray]{datapie}
\DTLsetup
{pie={segment-colors={pink,,green}}}
\DTLsetpiesegmentcolor
{6}{purple}
\DTLsetpiesegmentcolor
{9}{teal}
\color
) to that of the
th segment. Issues a warning and does nothing if no colour
has been set for that segment.
white
if
not set. (This ensures that no error occurs if used in an expandable
context when no colour has been assigned to the given segment.)
Since the page colour is typically white, this will give the
appearance of an unfilled segment but bear in mind that it will
obscure anything drawn in the same position first (for example, by
the \DTLpieatbegintikz
hook).
\DTLpiechart
as a
shortcut that will set the current text colour to that of the
current segment. However, it may also be used within
\DTLmapdata
or \DTLforeach
and will use the current row
index as the segment index but, to avoid ambiguity, use
\DTLdocurrentpiesegmentcolor
in the inner or outer labels
and \DTLdopiesegmentcolor
elsewhere.
\DTLpieoutlinecolor
to the supplied value.
4.7. Pie Chart Hooks[link]
\DTLdopiesegmentcolor
.
5. Bar Charts (databar package)[link]
\DTLsetup
instead (which means that
you would only be able to use options that can be set after
datatool has been loaded). Note that the dataplot
package will then be loaded afterwards without passing any options
to it.
\DTLforeach
has been replaced with \DTLmapdata
. A
number of bugs have also been fixed, which may cause some
differences in the output.
Note that if datatool hasn’t already been loaded, this will
also apply rollback to datatool and dataplot. Problems
may occur if a newer release of datatool or dataplot has
already been loaded.
\usepackage
{databar}[=2.32]
\DTLbarchart
to identify the
column of data to plot. This should be set to the applicable placeholder
command in .
\DTLbarchart
but plots groups of bars, where
each bar in the group has its numeric value obtained from the
corresponding placeholder command in the variables list.
See Example 124 for a simple example.
\DTLmultibarchart
to identify the columns of data to plot. This
should be set to a comma-separated list of the applicable
placeholder commands in .
\DTLbarchart
and \DTLmultibarchart
,
the argument should be a
list of placeholder command
assignments suitable for use in =
\DTLmapgetvalues
.
Additional assignments may be added if required for the bar
lower or upper labels.
\ifthenelse
(see §2.4.2). Note that if this
option is provided, it will override the include-if/include-if-fn setting.
name
(for the database name), assign
(for
the assignment list corresponding to the argument
of \DTLbarchart
and \DTLmultibarchart
), and
options
(for the bar chart settings corresponding to the
argument).
bar chart
action is equivalent to using \DTLbarchart
.
If you include the key
or column
action option
to identify the column to use for the \(y\) values then you can omit
variable in the options
setting.
See Example 122 for a simple example.
options
, it will override
the action key
or column
setting. However,
if variable has been previous set within the bar
option in \DTLsetup
and does not occur in the action
options
then the action key
or column
setting
will be used (if provided).
key
or
column
then a temporary placeholder command will be
created and added to the assignment list. If you don’t need to use
any of the database values in hooks or options (such as the bar
labels) then you may omit the assign
action option or
just assign the placeholders required for the labels. You will still
be able to use \DTLbarvariable
or \DTLbarvalue
.
multibar chart
action is equivalent to using
\DTLmultibarchart
. You can either set the list of bar chart
variable placeholder commands in the variables option
within the action options
setting or you can use the
action settings keys
or columns
(or a
combination of both) to identify the required columns.
See Example 125 for a simple example.
bar chart
action, if you select the columns
using the action settings rather than the variables
option, you may omit the corresponding placeholder commands in the
assign
list.
Note that this has the same syntax as \DTLbarchart
{variable=\Quantity
}% variable required
{fruit}% database name
{\Quantity
=Quantity}% assignment list
\DTLpiechart
(see
Example 110) which makes it simple to swap between a
bar and pie chart if you change your mind about the chart type.
bar chart
action. Note that this doesn’t need to reference the database name.
% Load data from fruit.csv file:
\DTLsetup
{default-name=fruit}
\DTLread
{fruit.csv}
\DTLaction
[key
=Quantity]{bar chart
}
(See Example 139 to make all positive bars blue
and all negative bars red.)
\DTLbarchart
{
variable=\theProfit
,
horizontal,
bar-width=20pt
}
{profits}% database name
{% assignment list
\theYear
=Year,
\theProfit
=Profit
}
\DTLmultibarchart
{
variables={\assignI
,\assignII
,\assignIII
},
barwidth=10pt
}
{marks}% database name
{
\assignI
=Assign1,
\assignII
=Assign2,
\assignIII
=Assign3
}
multibar chart
action.
Alternatively, rather than listing every column key, a column
range may be used:
\DTLaction
[
keys
={Assign1,Assign2,Assign3},
options
={
barwidth=10pt
}
]
{multibar chart
}
This identifies column 4 onwards.
\DTLaction
[
columns
={4-},% column 4 onwards
options
={
barwidth=10pt
}
]
{multibar chart
}
5.1. Package Options[link]
\DTLsetup
. Additional options that may be set with
\DTLsetup
are listed in §5.2.
5.2. Settings[link]
\DTLsetup
. For example:
\DTLsetup
{bar={horizontal,round=0}}
\DTLbarXlabelalign
) or registers (such as
\DTLbarlabeloffset
or DTLbarroundvar). For other
commands, such as \DTLbardisplayYticklabel
, you can put the
redefinition code within init={code} to localise the
effect.
\DTLbarchart
or \DTLmultibarchart
after the
argument has been parsed. This code will be scoped.
Example 142 uses init to locally
redefine \DTLeverybarhook
.
\DTLbarchart
or \DTLmultibarchart
. This means that if you
set the options in \DTLsetup
rather than in the applicable bar
chart command, the effect of pre-init may occur too late.
However, if the settings are moved into \DTLbarchart
{
variable=\Quantity
,
bar-label=\Name
,
pre-init={\DTLclearbarcolors
},
outline-width=1pt,
bar-colors={cyan,magenta,yellow}
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\DTLsetup
:
This will result in white bars as the colour list is set in
\DTLsetup
{
bar={
pre-init={\DTLclearbarcolors
},
outline-width=1pt,
bar-colors={cyan,magenta,yellow}
}
}
\DTLbarchart
{
variable=\Quantity
,
bar-label=\Name
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\DTLsetup
but the pre-init code isn’t done until
\DTLbarchart
, at which point it will clear the colour list.
In this case, the solution is simply to put \DTLclearbarcolors
before \DTLsetup
:
\DTLclearbarcolors
\DTLsetup
{
bar={
outline-width=1pt,
bar-colors={cyan,magenta,yellow}
}
}
5.2.1. Bar Chart Data[link]
\DTLbarchart
. The command must be
included in the assignment list provided in the final argument of
\DTLbarchart
. This setting is required by \DTLbarchart
.
\DTLmultibarchart
. Each
command in the list must be included in the assignment list provided
in the final argument of \DTLmultibarchart
. This setting is
required by \DTLmultibarchart
.
\DTLbarchart
or \DTLmultibarchart
) or by using one of the
filtering options below.
\dtlrownum
is used in
\DTLeverybarhook
or \DTLeverybargrouphook
it will be set
to the current database row index, which doesn’t take the filtering
into account (see Example 142).
#1
for any row that should be included in the bar chart, and do nothing
otherwise. Example 128
demonstrates filtering with the include-if setting.
\DTLbarchart
or
\DTLmultibarchart
. Either use one form or the other. Don’t use
both.
5.2.2. Bar Chart Style[link]
\DTLbarXlabelalign
and \DTLbarXneglabelalign
.
upper-label-align=
[
If is omitted, only the alignment for bars with
positive values will be changed. The grouping around is optional. For example,
upper-label-align=[left]right is equivalent to
upper-label-align=[left]{right}.
See §5.3.4 for an example.
\ifDTLverticalbars
bottom,center\else
left\fi
]
{\ifDTLverticalbars
top,center\else
right\fi
}
\DTLmultibarchart
this
gap is only between bars within a group and does not affect the gap
between groups.
\DTLmultibarchart
, this
sets the gap between each group of bars for \DTLmultibarchart
.
The default value of 1 indicates a gap of one bar width so, for
example, groupgap=0.5 indicates a gap of half a bar.
Then the first bar will be blue, the second red, the third white,
and the fourth green. If there are additional bars, they will cycle back to
the beginning with the fifth bar blue, the sixth red, the seventh
white and the eighth green, etc. See Example 138.
\DTLclearbarcolors
\DTLsetbarcolor
{1}{blue}
\DTLsetbarcolor
{2}{red}
\DTLsetbarcolor
{4}{green}
\DTLsetbarcolor
with the item’s index within the list as the
bar index. Remember that the = parser trims leading an
trailing spaces and the CSV parser used for the argument
removes empty items. This means that if you intend an empty item
(to indicate no fill for that bar) then you need {} to indicate
this. Bear in mind that if you don’t provide a fill colour you will
need to set outline-width to ensure the outline is drawn
(or redefine \DTLBarStyle
).
This will assign cyan and magenta to the first two bars, but the
third bar will be orange and the fourth green. Given the default
settings, the fifth bar will also be magenta, the sixth bar
will also be cyan, the seventh bar will be orange and the eighth
bar will be white. Alternatively, you can use
\DTLsetup
{bar={
bar-colors={pink,red,orange,green},
bar-colors={cyan,magenta},
}}
\DTLsetbarcolor
to set the colour of a specific segment.
\DTLclearbarcolors
or reset the
list with bar-default-colors or bar-default-gray.
See Example 137.
\DTLBarStyle
rather than
setting outline-width and outline-color. For
example, for a dotted outline that will be drawn even if
outline-width0pt:
\renewcommand
{\DTLBarStyle
}{draw,dotted}
5.2.3. Bar Chart Labels[link]
\DTLbarchart
or the databar placeholders
\DTLbarvariable
or \DTLbarvalue
.
See examples in §5.3.3.
\DTLmultibarchart
, this setting provides the group label.
Use multibarlabels for the individual lower bar labels in a
multi-bar chart.
\DTLbarchart
, this sets
the upper bar label to , which will typically include a
placeholder command provided in the argument of
\DTLbarchart
or the databar placeholders
\DTLbarvariable
or \DTLbarvalue
.
\DTLmultibarchart
, the value should be a
comma-separated list, where each item will be used as the lower label for
the corresponding bar within a bar group.
\DTLmultibarchart
, the value should be a
comma-separated list, where each item will be used as the upper label for
the corresponding bar within a bar group.
\DTLmultibarchart
, the value should be
the \pgftext
alignment for the bar group labels.
The default is to use the same alignment as for the lower bar
labels.
\DTLbarlabeloffset
length register.) Note that the direction is dependent on
lower-label-style.
\DTLbarlabeloffset
. If you change this to a
negative value (which will cause the upper bar label to shift inside
the end of the bar) then you will also need to change the alignment.
For example:
upper-label-offset=-
\DTLbarlabeloffset
,
upper-label-align=[left]right
5.2.4. Bar Chart Axes[link]
y-ticks=true, y-axis=false
won’t show any tick marks.
\DTLbarvalue
placeholder
command. It will also be used to round the \(y\) tick labels unless
y-tick-round is set.
\DTLmintickgap
.
\pgftext
alignment specifier. (The expansion occurs within
\DTLbarchart
and \DTLmultibarchart
not when the option is
set.)
5.3. Bar Chart Examples[link]
5.3.1. Labels[link]
\DTLbarchart
{
variable=\Quantity
,% variable required
bar-label=\Name
,
upper-bar-label=\Quantity
,
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\DTLmapgetvalues
(since the drawing code for each bar is constructed within the body
of \DTLmapdata
) so they will expand as they would ordinarily if
\DTLmapgetvalues
is used explicitly within \DTLmapdata
.
If you want the value to be rounded, then use \DTLbarvalue
with
the round option instead. For example:
\DTLbarchart
{
variable=\Quantity
,% variable required
bar-label=\Name
,
round=0,
upper-bar-label=\DTLbarvalue
,
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\DTLbarvalue
command is also useful with bar chart
and multibar chart
actions where the column (or columns,
for multibar chart
) can simply be identified by key or
index rather than assigning a placeholder command.
\DTLmapget
and \DTLbarvalue
to avoid the need to assign any placeholder
commands.
\DTLaction
[
key
=Quantity,
options
={
bar-label={\DTLmapget
{key
=Name}},
upper-bar-label=\DTLbarvalue
}
]
{bar chart
}
5.3.2. Filtering[link]
This uses \DTLbarchart
{
variable=\Quantity
,% variable required
bar-label=\Name
,
include-if={\DTLifstringeq
{\Name
}{Pears}{}{#1}}
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\DTLifstringeq
to test value of
the placeholder command.
\DTLbarchart
and the
other one uses \DTLpiechart
.
As with Example 112,
the same result can also be achieved with the optional argument
instead of include-if or you can use include-if-fn,
but bear in mind that you can’t use
both the optional argument and the include-if/include-if-fn setting.
5.3.3. Lower Label Alignment[link]
\theYear
placeholder command). The
upper bar label is the value (profit or loss). This can be
referenced with the placeholder command \theProfit
or with
\DTLbarvariable
, but this will show the value as given in the
database (which includes the currency symbol and has inconsistently
formatted negative values, see §3.2.8). With
\DTLbarvalue
, the value will be shown as a
formatted number without the currency symbol, rounded according
to the round setting.
An alternative is to reformat the values while the data is read
from the file, as is done in Example 109.
\DTLbarchart
{
variable=\theProfit
,
horizontal,
bar-width=20pt,
bar-label=\theYear
,
round=0,
upper-bar-label=\DTLbarvalue
,
}
{profits}% database name
{% assignment list
\theYear
=Year,
\theProfit
=Profit
}
5.3.4. Upper Label Alignment[link]
This sets upper-label-offset to a negative dimension to shift the upper label
inwards (towards the \(x\)-axis). Note that this shifts the upper labels for
negative bars to the right and for the positive bars to the left.
This now means that the node alignment has to be changed for the
upper labels: left for the negative upper labels and
right for the positive upper labels. Again, this can cause
a problem for short bars.
\DTLbarchart
{
variable=\theProfit
,
horizontal,
bar-width=20pt,
bar-label=\theYear
,
round=0,
upper-bar-label=\DTLbarvalue
,
upper-label-offset={ -\DTLbarlabeloffset
},
upper-label-align=[left]right
}
{profits}% database name
{% assignment list
\theYear
=Year,
\theProfit
=Profit
}
\ifDTLverticalbars
conditional in
the value to allow for either orientation.)
5.3.5. Multi Bar Chart Labels[link]
\DTLmultibarchart
also
have group labels. The upper labels are positioned at the bar end,
as for \DTLbarchart
, and the lower labels are positioned at the
bar start (near the \(x\)-axis). However, the lower labels should now be
specified with multibarlabels (or multi-bar-labels)
and the upper labels with uppermultibarlabels (or
upper-multi-bar-labels). These options take comma-separated
lists for their values, where each item in the list corresponds to
the bar within the group.
\DTLmultibarchart
will be the same for each bar label within the group.
\DTLmultibarchart
{
variables={\assignI
,\assignII
,\assignIII
},
round=0,
bar-width=12pt,
group-label-align={center,top},
bar-label={\xDTLinitials
{\Forename
}\xDTLinitials
{\Surname
}},
multi-bar-labels={A1,A2,A3},
upper-multi-bar-labels={\DTLbarvalue
,\DTLbarvalue
,\DTLbarvalue
},
}
{marks}% database name
{
\assignI
=Assign1,
\assignII
=Assign2,
\assignIII
=Assign3,
\Surname
=Surname,
\Forename
=Forename
}
5.3.6. Axes[link]
\DTLbarvalue
placeholder are set differently.
The bar width (which for a horizontal bar chart is in fact the
height) is set to 20pt and the bar gap is set to 0.5, which is half
a bar width (and therefore 10pt).
\DTLbarchart
{
variable=\theProfit
,
horizontal,
color-style=single,
max-depth=-5000,
max=10000,
bar-width=20pt,bar-gap=0.5,
axes,y-ticks,y-tick-gap=2500,
ylabel=Profits,
bar-label=\theYear
,
upper-bar-label=\DTLbarvalue
,
round=2,
y-tick-round=0
}
{profits}% database
{% assignment list
\theYear
=Year,
\theProfit
=Profit
}
\DTLbardisplayYticklabel
has been
redefined to rotate the tick label. The alignment for the
\pgftext
command is also modified to allow for the rotation:
\renewcommand
{\DTLbardisplayYticklabel
}[1]{\rotatebox
{45}{#1}}
\DTLbarchart
{
variable=\theProfit
,
horizontal,
color-style=single,
max-depth=-5000,
max=10000,
bar-width=20pt,bar-gap=0.5,
axes,y-ticks,y-tick-gap=1000,
ylabel=Loss / Profits,
ylabel-position=zero,
bar-label=\theYear
,
upper-bar-label=\DTLbarvalue
,
round=2,
y-tick-round=0,
ytic-label-align={right,top}
}
{profits}% database
{% assignment list
\theYear
=Year,
\theProfit
=Profit
}
5.3.7. Bar Colours[link]
Remember to use pre-init rather than init in this
case to ensure that the colour list is cleared before the
bar-colors option is processed.
\DTLbarchart
{
variable=\Quantity
,
bar-label=\Name
,
pre-init={\DTLclearbarcolors
},
outline-width=1pt,
bar-colors={cyan,magenta,yellow}
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\DTLbarchart
{
variable=\Quantity
,
bar-label=\Name
,
pre-init={\DTLclearbarcolors
},
bar-colors={cyan,magenta,yellow},
color-style=cycle,
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
Note that without negative-bar-colors=red, all bars
would be blue with \DTLbarchart
{
variable=\theProfit
,
horizontal=,
bar-width=20pt,
bar-label=\theYear
,
upper-bar-label=\DTLbarvalue
,
round=0,
color-style=single,
bar-colors=blue,
negative-bar-colors=red
}
{profits}% database
{% assignment list
\theYear
=Year,
\theProfit
=Profit
}
color-style=single,
bar-colors=blue
.
\path
command with the
option list including fill=
if a non-empty
colour specification has been set for the bar colour and
draw=
if the outline-color is non-empty
and the outline-width is greater than 0pt. This will then
be followed by the full expansion of \DTLBarStyle
, which can be
used to make further adjustments.
\DTLBarStyle
which has the shading settings to be passed to \path
:
\renewcommand
\DTLBarStyle
{%
draw,shade,shading=axis,left color=red,right color=blue
}
\DTLBarStyle
content needs to be constructed according
to each bar variable, then you can redefine
\DTLeveryprebarhook
to redefine \DTLBarStyle
as
applicable.
5.3.8. Hooks[link]
\DTLstartpt
) to the end point (\DTLendpt
)
and draw a circle at the start, middle (\DTLmidpt
), and end
points:
\renewcommand
\DTLeverybarhook
{%
\pgfpathmoveto
{\DTLstartpt
}
\pgfpathlineto
{\DTLendpt
}
\pgfpathcircle
{\DTLstartpt
}2pt
\pgfpathcircle
{\DTLmidpt
}2pt
\pgfpathcircle
{\DTLendpt
}2pt
\pgfusepath
{draw}
}%
\DTLbarchart
{
variable=\theProfit
,
horizontal,
color-style=single,
bar-colors=pink,
}
{profits}% database
{% assignment list
\theYear
=Year,
\theProfit
=Profit
}
\DTLbarindex
) and the row index number
(\dtlrownum
) in the centre of each bar. The second
row (Pears) has been skipped so the row index numbering is: 1, 3, 4 and 5.
Compare this with the bar index numbering: 1, 2, 3, and 4.
\DTLbarchart
{
init={\renewcommand
{\DTLeverybarhook
}{%
\pgftext
[at=\DTLmidpt
]{\DTLbarindex
/\number
\dtlrownum
}}},
variable=\Quantity
,% variable required
bar-label=\Name
,
include-if={\DTLifstringeq
{\Name
}{Pears}{}{#1}}
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\DTLeverybarhook
can be used to gather information for use in
the end hook \DTLbaratendtikz
. This is done in
\DTLbarchart
{
init={%
\def
\mychartlegend
{}%
\renewcommand
{\DTLeverybarhook
}{%
\ifdefempty
{\mychartlegend
}{}{\appto
\mychartlegend
\\}%
\eappto
\mychartlegend
{%
{\noexpand
\DTLdobarcolor
{\DTLbarindex
}
\noexpand
\rule
{\noexpand
\DTLbarwidth
}{\noexpand
\DTLbarwidth
}}
\expandonce
\Name
}%
}%
\renewcommand
{\DTLbaratendtikz
}{%
\node
[at=(\DTLbarchartwidth
,0pt),anchor=south west]
{
\begin{tabular}
{l}
\mychartlegend
\end{tabular}
};
}%
},
variable=\Quantity
,% variable required
y-ticks,ylabel=Quantity
}
{fruit}% database
{\Quantity
=Quantity,\Name
=Name}% assignment list
\DTLeverybarhook
code is used
for the student scores database multi bar chart then the legend would end
up with the number of students times the number of assignments bars.
\DTLmultibarchart
{
init={
\renewcommand
{\DTLbaratendtikz
}{%
\node
[at=(\DTLbarchartwidth
,0pt),anchor=south west]
{\begin{tabular}
{l}
{\DTLdobarcolor
{1}\rule
{\DTLbarwidth
}{\DTLbarwidth
}}
Assignment 1\\
{\DTLdobarcolor
{2}\rule
{\DTLbarwidth
}{\DTLbarwidth
}}
Assignment 2\\
{\DTLdobarcolor
{3}\rule
{\DTLbarwidth
}{\DTLbarwidth
}}
Assignment 3
\end{tabular}
};
}
},
variables={\assignI
,\assignII
,\assignIII
},
bar-width=12pt,
group-label-align={center,top},
bar-label={\xDTLinitials
{\Forename
}\xDTLinitials
{\Surname
}},
y-ticks,axes=both
}
{marks}% database name
{
\assignI
=Assign1,
\assignII
=Assign2,
\assignIII
=Assign3,
\Surname
=Surname,
\Forename
=Forename
}
5.4. Bar Chart Associated Commands[link]
5.4.1. Axes[link]
\setlength
or via the length option.
\path
when each bar is drawn.
5.4.2. Textual[link]
\setcounter
will
globally change the value. To locally change it, use the
round setting. The y-tick-round setting is
initialised to use this counter value, so if you change this counter
or set round but don’t set y-tick-round then the
default \(y\) tick labels will use the same rounding that’s applied to
the definition of \DTLbarvalue
.
-\$12,345.62
and the settings include
variable=\theProfit
with the assignment list
\theProfit-Profit
, then \DTLbarvariable
will expand to the supplied variable \theProfit
, which in
turn will expand to -\$12,345.01
, but
\DTLbarvalue
will expand to the rounded localised decimal
value. For example, with round=0 this will be
-12,345
(without the currency symbol).
\DTLmultibarchart
, this index is reset
at the start of each group.
\DTLbarchart
, this will expand to 0
.
\setlength
or via the barwidth option.
\setlength
or via the label-offset option.
\pgftext
alignment
specifications for the \(x\)-axis lower bar labels for positive values.
As from v3.0, the
\ifDTLverticalbars
conditional has been moved into the
definition of \DTLbarXlabelalign
as it is now fully expanded
before being passed to the pgf parser. The default definition
is now:
This command is redefined by the lower-label-style setting.
\newcommand
\DTLbarXlabelalign
{%
\ifDTLverticalbars
left,rotate=-90\else
right\fi
}
\pgftext
alignment
specifications for the \(x\)-axis lower bar labels for negative values.
The default definition is:
This command is redefined by the lower-label-style setting.
\newcommand
\DTLbarXneglabelalign
{%
\ifDTLverticalbars
right,rotate=-90\else
left\fi
}
\pgftext
alignment specifications for
the upper bar labels. The default definition is:
The upper-label-align=[ option redefines this command to ]{ } .
\newcommand
\DTLbarXupperlabelalign
{%
\ifDTLverticalbars
bottom,center\else
left\fi
}
\pgftext
alignment specifications for
the upper bar labels. The default definition is:
The upper-label-align=[ option redefines this command to ]{ } , if provided.
\newcommand
\DTLbarXnegupperlabelalign
{%
\ifDTLverticalbars
top,center\else
right\fi
}
\DTLbarXupperlabelalign
and optionally redefine
\DTLbarXnegupperlabelalign
.
\pgftext
alignment specification for
the group label alignment (\DTLmultibarchart
only).
The group-label-align option redefines this command.
\pgftext
alignment
specifications for the \(y\)-axis tick labels. As from v3.0, the
\ifDTLverticalbars
conditional has been moved into the
definition of \DTLbarYticklabelalign
as it is now fully expanded
before being passed to the pgf parser. The default definition
is now:
This command is
redefined by the y-tick-label-align setting.
\newcommand
\DTLbarYticklabelalign
{%
\ifDTLverticalbars
right\else
top,center\fi
}
\DTLbardisplayYticklabel
to use \datatool_datum_value:Nnnnn
(which requires LaTeX3 syntax
on).
\DTLbarchart
.
By default, this simply expands to its argument.
\DTLmultibarchart
.
By default, this simply expands to its argument.
\DTLmultibarchart
. By default, this
simply expands to its argument.
\DTLbarchart
.
By default, this simply expands to its argument.
\DTLmultibarchart
. By default, this
simply expands to its argument.
5.4.3. Bar Colours[link]
\color
). This command is redefined by
the outline-color option. If this command is redefined to
empty then the outline won’t be drawn.
\DTLsetbarcolor
may be empty. This is different
to the colour not being set for the given index. An empty value
indicates that the bar should not be filled. Whereas an unset value
may default to white, depending on the style. Most of the time there
will be no visual difference, but if there is content behind the
bar, a white filled bar will obscure it but an unfilled bar won’t.
\DTLgetbarcolor
.
where will be
obtained from \color
{ }
if the
supplied is negative, otherwise from
\DTLgetnegbarcolor
{ }
. If the is
omitted, a non-negative number is assumed.
Does nothing if an empty colour specification has been applied
to the given bar index
\DTLgetbarcolor
{ }\DTLeverybarhook
to do
where
is the current bar index. This command can also be
used in \DTLdobarcolor
{ }\DTLmapdata
or \DTLforeach
(in which case the row
index will be used as the bar index), but without access to
the current bar value it will assume a non-negative value.
5.4.4. Hooks[link]
\DTLbarchart
and \DTLmultibarchart
may be used
in hooks to add information from the current row. Bear in mind that
with \DTLmultibarchart
, those placeholder commands will expand
to the same content for every bar within the same bar group. They
will also be unavailable in the start and end hooks
(\DTLbaratbegintikz
and \DTLbaratendtikz
).
Placeholder commands such as \DTLbarvariable
and
\DTLbarvalue
are updated for every bar.
\DTLbarchart
and \DTLmultibarchart
internally
use \DTLmapdata
, you can reference the current row index within
hooks with \dtlrownum
. Note that this is the database row index which may
not correspond to the bar or group number if filtering has been
applied. Instead, use \DTLbarindex
for the bar index or
\DTLbargroupindex
for the bar group index.
See §5.3.8.
\pgfpointxy
. Below, \(s\) is the starting point of the bar,
\(b/2\) is half a bar width and \(v\) is
variable value for the current bar (see Example 141).
for
vertical bars and to \pgfpointxy
{\(s+b/2\)}{0}
for horizontal bars.
\pgfpointxy
{0}{\(s+b/2\)}
for
vertical bars and to \pgfpointxy
{\(s+b/2\)}{\(v/2\)}
for horizontal bars.
\pgfpointxy
{\(v/2\)}{\(s+b/2\)}
for
vertical bars and to \pgfpointxy
{\(s+b/2\)}{\(v\)}
for horizontal bars.
\pgfpointxy
{\(v\)}{\(s+b/2\)}\DTLmultibarchart
. Note that the above point placeholder
commands will be set for the last bar in the group.
\DTLbarwidth
. The width takes the group gap into account for
multi-bar charts, but it does not take into account the space taken
up by the \(y\)-ticks or \(y\) axis label (if present).
Expands to nothing outside of the bar chart commands.
\DTLmultibarchart
, you can also access the width of each bar group:
\DTLbarchart
, this is the number of rows that contribute to the
chart (which will be less than or equal to the total number of rows
in the database). For \DTLmultibarchart
, this will be the
number of contributing rows multiplied by the number of bars in each
group.
\DTLmultibarchart
only, this expands to the number of
variables (that is, the number of bars in each group). Expands
to nothing outside of \DTLmultibarchart
.
\DTLmultibarchart
only, this expands to the total number of
bar groups in the current chart. Expands to nothing outside of
\DTLmultibarchart
. The number of bar groups is equal to the
number of rows that contribute to the chart (which will be less than
or equal to the total number of rows in the database).
6. Scatter and Line Plots (dataplot package)[link]
\DTLsetup
instead (which means that
you would only be able to use options that can be set after
datatool has been loaded).
\DTLforeach
has been replaced with \DTLmapdata
. A
number of bugs have also been fixed, which may cause some
differences in the output.
Note that if datatool hasn’t already been loaded, this will
also apply rollback to datatool. Problems may occur if a newer
release of datatool has already been loaded.
\usepackage
{dataplot}[=2.32]
\ifthenelse
(see §2.4.2). Note that if this
option is provided, it will override the include-if or
include-if-fn setting.
y={ Exp1,, Exp2 ,}
is equivalent to y={Exp1,Exp2}
. However,
y={Exp1,{},Exp2}
specifies an empty key in the
second item which is invalid.
name
should be set to the database name or list of
names , and options
should be the
plot settings. If the name
is omitted, the
default database is assumed.
The above is equivalent to:
\DTLaction
[name
={, }options
={]{ }plot
}
Note that you can’t use any of the
usual action column identifiers, such as \DTLplot
{ }{ }
keys
, as they
need to be separated into the x and y lists.
\DTLminX
within the plot;
\DTLminY
within the plot;
\DTLmaxX
within the plot;
\DTLmaxY
within the plot;
name
option.
\DTLplot
and the plot
action,
each plot stream is constructed in the following order:
\DTLplotatbegintikz
occurs at the start,
and \DTLplotatendtikz
at the end.
6.1. Plot Settings[link]
\DTLplot
or the options
value for the
plot
action or set with the plot option in
\DTLsetup
. For example, to set defaults:
To override the defaults for a specific plot:
\DTLsetup
{plot={grid,tick-dir=in}}
Alternatively, using the \DTLplot
{mydata}{x=Time,y=Temperature,legend}
plot
action:
\DTLaction
[
name
mydata,
options
={x=Time,y=Temperature,legend}
]
{plot
}
6.1.1. Database Content[link]
\DTLmapgetvalues
when
\DTLplot
loops through each row of the database using
\DTLmapdata
. The placeholder commands identified in the
assignment list can be used in the filter condition.
Alternatively, you can simply use \DTLmapget
in the filter
function include-if or include-if-fn (but not in
the optional argument of \DTLplot
which needs
to expand).
#1
for any row that should have its \(x\) and \(y\) values
included in the plot, and do nothing otherwise.
\DTLplot
. Either use one form or the
other. Don’t use both.
This uses \DTLplot
{results}
{
x=Time,
y=Temperature,
extra-assign={\Notes
=Notes},
include-if={
\DTLifstringeq
{\Notes
}{Incorrect}{}{#1}
}
}
\DTLifstringeq
, which expands its arguments, to test value of
the placeholder command. Note that while you can use
etoolbox’s \ifdefstring
with the default
store-datum=false, it won’t work with
store-datum=true as then \Notes
will be a
datum control sequence.
6.1.2. Plot Size[link]
6.1.3. Marker and Line Styles[link]
blue, red,,green,
is converted to
blue,red,green
. This means that if you explicitly need an
empty item, you must group it. For example:
blue,red,{},green
.
\DTLplotatbegintikz
hook.
\DTLcustomlegend
to position the legend in the
required place.
legendlabels={Experiment1,,Experiment2}
the empty item will be stripped by the parser and it will be
equivalent to:
legendlabels={Experiment1,Experiment2}
However, with the following:
legendlabels={Experiment1,{},Experiment2}
The first and third plot streams will be added to the legend but the
second won’t.
\DTLplot
to have
markers only and some to have lines only, then use
style=both and use \relax
or {}
for the
corresponding item in marks or lines.
For example:
style=both,
lines={
\pgfsetdash
{}{0pt},% solid line
\relax
,% no line
\pgfsetdash
{{10pt}{5pt}}{0pt},% dashed
\pgfsetdash
{{5pt}{5pt}}{0pt},% dashed
\relax
,% no line
\pgfsetdash
{{5pt}{5pt}{1pt}{5pt}}{0pt},% dash dot
},
marks={
\relax
,% no marker
\pgfuseplotmark
{o},% circle marker
\pgfuseplotmark
{x},% cross marker
\relax
,% no marker
\pgfuseplotmark
{+},% plus marker
\pgfuseplotmark
{asterisk},% asterisk marker
}
\color
) to apply to the
corresponding plot line style given in lines. An empty item
{} or \relax
indicates that no colour change should
apply to that line (so the line will be black unless the default
colour is changed). This setting simply redefines
\DTLplotlinecolors
to the supplied value.
\pgfsetdash
). An empty item {} or \relax
indicates that lines should be omitted for the corresponding plot
stream. This setting simply redefines \DTLplotlines
to the
supplied value.
\color
) to apply to the
corresponding plot mark given in marks. An empty item
{} or \relax
indicates that no colour change should
apply to that marker (so the marker will be black unless the default
colour is changed). This setting simply redefines
\DTLplotmarkcolors
to the supplied value.
\pgfuseplotmark
). An empty item
{} or \relax
indicates that markers should be omitted
for the corresponding plot stream. This setting simply redefines
\DTLplotmarks
to the supplied value.
6.1.4. Axes[link]
\DTLmintickgap
. There is a similar length
\DTLminminortickgap
for the suggested minimum distance between
minor tick marks.
\DTLplotdisplayXticklabel
, and the \(x\)-tick mark labels will be
encapsulated with \DTLplotdisplayYticklabel
. Both these
commands default to using \DTLplotdisplayticklabel
so only that
command needs redefining if the same formatting should be used for
both \(x\) and \(y\) tick labels.
x-axis-style={,
}y-axis-style={ }
.
\DTLplotwidth
(set
with width).
\DTLplotwidth
.
\DTLplotheight
(set
with height).
\DTLplotheight
.
extend-x-axis={,
, }extend-y-axis={
, }
Again a single value may be supplied if the lower and upper extent
are the same.
\DTLminorgridstyle
(minor-grid-style) has a non-empty definition.
\DTLmajorgridstyle
to the given .
\DTLminorgridstyle
to the given .
round-x=,
nround-y= n
.
x-ticks=,
y-ticks=
.
x-minor-ticks=,
y-minor-ticks=
.
x-tick-label-style={,
}y-tick-label-style={anchor= east,
}
\DTLticklabeloffset
.
x-tick-dir=,
y-tick-dir=
.
x-tick-gap=,
y-tick-gap=
.
6.2. Plot Examples[link]
\DTLplot
.
6.2.1. Basic Examples[link]
6.2.1.1. One Database[link]
\DTLplot
{growth1}{
x=Time, y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
legend, width=2.5in, height=2.5in
}
6.2.1.2. Two Databases, One X Column[link]
\DTLplot
{growth1,growth2}{
x=Time, y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
legend, width=2.5in, height=2.5in
}
6.2.1.3. Plot Action[link]
plot
action
instead of explicitly using \DTLplot
.
The return values can then be accessed:
\DTLaction
[name
={growth1,growth2},
options
={
x=Time, y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
legend, width=2.5in, height=2.5in
}
]{plot
}
Number of streams:
Alternatively, you can use the \DTLuse
{stream-count}.
Minimum X: \DTLuse
{min-x}.
Minimum Y: \DTLuse
{min-y}.
Maximum X: \DTLuse
{max-x}.
Maximum Y: \DTLuse
{max-y}.
return
setting:
\DTLaction
[name
={growth1,growth2},
options
={
x=Time,
y={Experiment 1,Experiment 2},
x-label={Time ($t$)},y-label={Log Count},
legend, width=2.5in,height=2.5in
},
return
={
\theMinX
=min-x, \theMinY
=min-y,
\theMaxX
=max-x, \theMaxY
=max-y,
\NumStreams
=stream-count
}
]{plot
}
Number of streams: \NumStreams
.
Minimum X: \theMinX
. Minimum Y: \theMinY
.
Maximum X: \theMaxX
. Maximum Y: \theMaxY
.
6.2.1.4. One Database, Two X and Y Columns[link]
\DTLplot
{growthdata}{
x={Exp1Time,Exp2Time}, y={Exp1Count,Exp2Count},
x-label={Time ($t$)}, y-label={Log Count},
legend, width=2.5in, height=2.5in
}
6.2.1.5. Two Databases, Two X and Y Columns[link]
This results in a very cluttered diagram where the legend obscures
a large part of the plot.
\DTLplot
{growthdata,growthdata2}{
x={Exp1Time,Exp2Time},
y={Exp1Count,Exp2Count},
legend, width=2.5in,height=2.5in
}
6.2.1.6. Two Databases, Three X and Y Columns[link]
The unknown columns will be skipped for the first database. If you
switch on verbose mode, messages should be shown in the
transcript. Those messages will turn into a warning if there are
unknown columns when only one database is specified.
\DTLplot
{growthdata,growthdata2}{
x={Exp1Time,Exp2Time,Exp3Time},
y={Exp1Count,Exp2Count,Exp3Count},
x-label={Time ($t$)},y-label={Log Count},
legend, width=2.5in,height=2.5in
}
\RenewDocumentCommand
\DTLplotlegendx
{ O{0} m O{0} m }{#4}
\RenewDocumentCommand
\DTLplotlegendy
{ O{0} m O{0} m }{#4}
6.2.1.7. Two Databases, Two X and Three Y Columns[link]
Again, \DTLplot
{growthdata,growthdata2}{
x={Exp1Time,Exp2Time},
y={Exp1Count,Exp2Count,Exp3Count},
x-label={Time ($t$)}, y-label={Log Count},
legend, width=2.5in, height=2.5in
}
\DTLplotlegendx
and \DTLplotlegendy
are redefined to show
the column keys, and, again, the legend obscures the plot, but it’s
the legend that is of interest as it shows the combinations of the
x and y columns used to generate the plot.
6.2.2. Legend Examples[link]
If there is only one database the /
part will be omitted
(unless there is also only one x and y),
and if there is only one x column the and
following slash separator will be omitted.
\DTLplotlegendx
, and
the part defaults to
the column header for the corresponding y column,
which is obtained with \DTLplotlegendy
.
This means that each set of data is labelled “Time / Log Count” in
Examples 148 & 149, since
the column headers are repeated for each x/y pair.
6.2.2.1. Custom Legend Text With legend-labels[link]
\DTLplot
{growthdata}{
x={Exp1Time,Exp2Time},
y={Exp1Count,Exp2Count},
x-label={Time ($t$)},y-label={Log Count},
legend, legend-labels={Experiment 1,Experiment 2},
width=2.5in, height=2.5in
}
6.2.2.2. Subset Custom Legend Text With
legend-labels[link]
This only occurs when the legend-labels list is shorter
than the total number of plot streams. It’s not possible to have the
default for the first and specify a label for the second with
legend-labels.
\DTLplot
{growthdata}{
x={Exp1Time,Exp2Time},
y={Exp1Count,Exp2Count},
x-label={Time ($t$)},y-label={Log Count},
legend, legend-labels={Experiment 1},
width=2.5in, height=2.5in
}
legend-labels={Experiment 1,}
(with a trailing
comma) is equivalent to legend-labels={Experiment
1}
. If an empty value is required, the empty value needs to be
grouped.
6.2.2.3. Omitting Stream from Legend With
legend-labels[link]
This causes the second stream to be omitted from the legend.
\DTLplot
{growthdata}{
x={Exp1Time,Exp2Time},
y={Exp1Count,Exp2Count},
x-label={Time ($t$)}, y-label={Log Count},
legend, legend-labels={Experiment 1,{}},
width=2.5in, height=2.5in
}
6.2.2.4. Legend Database Mapping[link]
legend-labels={
However, this can get quite cumbersome (particularly for
Example 150, which has two pairs of x/y
data in one database and three in the other).
\qty
{6}{\degreeCelsius
} Experiment 1,
\qty
{6}{\degreeCelsius
} Experiment 2,
\qty
{8}{\degreeCelsius
} Experiment 1,
\qty
{8}{\degreeCelsius
} Experiment 2
}
This needs to be done before \DTLplotlegendsetname
{growth1}{\qty
{6}{\degreeCelsius
}}
\DTLplotlegendsetname
{growth2}{\qty
{8}{\degreeCelsius
}}
\DTLplot
. The rest of
Example 155 is as
Example 146 (but remember to include siunitx).
\DTLplotlegendname
, which is only present
if there are multiple databases.
6.2.2.5. Legend Column Key Mapping[link]
\DTLplotlegendx
and \DTLplotlegendy
from
that example otherwise the mappings will be ignored.
\DTLplotlegendsetname
{growthdata}{\qty
{6}{\degreeCelsius
}}
\DTLplotlegendsetname
{growthdata2}{\qty
{8}{\degreeCelsius
}}
\DTLplotlegendsetxlabel
{Exp1Time}{$t_1$}
\DTLplotlegendsetxlabel
{Exp2Time}{$t_2$}
\DTLplotlegendsetxlabel
{Exp3Time}{$t_3$}
\DTLplotlegendsetylabel
{Exp1Count}{$N_1$}
\DTLplotlegendsetylabel
{Exp2Count}{$N_2$}
\DTLplotlegendsetylabel
{Exp3Count}{$N_3$}
6.2.2.6. Customising the X/Y Legend[link]
\DTLplotlegendxysep
but \DTLplotlegendxy
that doesn’t use \DTLplotlegendxysep
but
instead uses a comma and parentheses:
\RenewDocumentCommand
\DTLplotlegendxy
{ O{0} m O{0} m O{0} m }
{%
(\DTLplotlegendx
[#1]#2[#3]{#4},
\DTLplotlegendy
[#1]#2[#5]{#6})%
}
6.2.2.7. Customising the Legend, No X Label[link]
\DTLplotlegendxy
to omit the \(x\) text, which means that
only the database name and y column key mappings are
needed:
In this case, since each y label needs to be in the form
“Experiment , this can be simplified further:
”\RenewDocumentCommand
\DTLplotlegendxy
{ O{0} m O{0} m O{0} m }
{%
\DTLplotlegendy
[#1]{#2}[#5]{#6}%
}
\DTLplotlegendsetname
{growthdata}{$T=6$}
\DTLplotlegendsetname
{growthdata2}{$T=8$}
\DTLplotlegendsetylabel
{Exp1Count}{Experiment 1}
\DTLplotlegendsetylabel
{Exp2Count}{Experiment 2}
\DTLplotlegendsetylabel
{Exp3Count}{Experiment 3}
\RenewDocumentCommand
\DTLplotlegendxy
{ O{0} m O{0} m O{0} m }
{%
\DTLplotlegendy
[#1]{#2}[#5]{#6}%
}
\DTLplotlegendsetname
{growthdata}{$T=6$}
\DTLplotlegendsetname
{growthdata2}{$T=8$}
\RenewDocumentCommand
\DTLplotlegendy
{ O{0} m O{0} m }
{Experiment #3}
6.2.2.8. Shifting the Legend[link]
\DTLlegendxoffset
and
\DTLlegendyoffset
. These can be more conveniently set with
the legend-offset option. The default value for both
offsets is 10pt. Note that this is an absolute length not in data
co-ordinates. A negative offset will position the legend outside of
the plot.
\DTLplot
{growthdata,growthdata2}{
x={Exp1Time,Exp2Time,Exp3Time},
y={Exp1Count,Exp2Count,Exp3Count},
x-label={Time ($t$)},y-label={Log Count},
legend,legend-offset={-10pt,0pt},
width=2.5in,height=2.5in
}
6.2.2.9. Custom Legend Position[link]
\DTLcustomlegend
to position the legend exactly where
you want it.
shapes.callouts
library:
and redefines \usetikzlibrary
{shapes.callouts}
\DTLcustomlegend
to position the legend at
( , /4) where is the plot width and
is the plot height:
Note that this definition doesn’t include \renewcommand
{\DTLcustomlegend
}[1]{%
\node
[rectangle callout,fill=green!10,anchor=west,outer sep=10pt,
callout relative pointer={(-40pt,10pt)}
] at (\DTLplotwidth
,0.25\DTLplotheight
)
{#1} ;
}
\DTLformatlegend
but
instead uses the \node
options to set the shape and
background colour.
\DTLplot
{growthdata,growthdata2}{
x={Exp1Time,Exp2Time,Exp3Time},
y={Exp1Count,Exp2Count,Exp3Count},
x-label={Time ($t$)},y-label={Log Count},
legend=custom,
width=2.5in,height=2.5in
}
6.2.3. Plot Style Examples[link]
6.2.3.1. Line and Scatter Plot[link]
Note that the legend has also been shifted, as per
Example 159.
\DTLplot
{growth1,growth2}{
style=both,
x=Time, y={Experiment 1,Experiment 2},
x-label={Time ($t$)},y-label={Log Count},
legend, legend-offset={-10pt,0pt},
width=2.5in,height=2.5in
}
6.2.3.2. Changing the Colours and Styles[link]
\DTLplot
{growthdata,growthdata2}{
style=both,% lines and markers
line-colors={brown,blue,lime,black,orange},
mark-colors={magenta,teal,green,violet,cyan},
lines={
\pgfsetdash
{}{0pt},% solid line
\pgfsetdash
{{1pt}{3pt}}{0pt},
\pgfsetdash
{{5pt}{5pt}{1pt}{5pt}}{0pt},
\pgfsetdash
{{4pt}{2pt}}{0pt},
\pgfsetdash
{{1pt}{1pt}{2pt}{2pt}{2pt}{1pt}}{0pt}
},
marks={
\pgfuseplotmark
{o},
\pgfuseplotmark
{square},
\pgfuseplotmark
{diamond},
\pgfuseplotmark
{asterisk},
\pgfuseplotmark
{star}
},
x={Exp1Time,Exp2Time,Exp3Time},
y={Exp1Count,Exp2Count,Exp3Count},
x-label={Time ($t$)},y-label={Log Count},
legend, legend-offset={-10pt,0pt},
width=2.5in,height=2.5in
}
6.2.3.3. One Line Colour Per Database[link]
Note that the other styles (line style, marker style and marker
colour) still cycle round the given lists.
\DTLplot
{growthdata,growthdata2}{
style=both, group-styles={line-color},
line-colors={brown,blue,lime,black,orange},
mark-colors={magenta,teal,green,violet,cyan},
lines={
\pgfsetdash
{}{0pt},% solid line
\pgfsetdash
{{1pt}{3pt}}{0pt},
\pgfsetdash
{{5pt}{5pt}{1pt}{5pt}}{0pt},
\pgfsetdash
{{4pt}{2pt}}{0pt},
\pgfsetdash
{{1pt}{1pt}{2pt}{2pt}{2pt}{1pt}}{0pt}
},
marks={
\pgfuseplotmark
{o},
\pgfuseplotmark
{square},
\pgfuseplotmark
{diamond},
\pgfuseplotmark
{asterisk},
\pgfuseplotmark
{star}
},
x={Exp1Time,Exp2Time,Exp3Time},
y={Exp1Count,Exp2Count,Exp3Count},
x-label={Time ($t$)},y-label={Log Count},
legend, legend-offset={-10pt,0pt},
width=2.5in,height=2.5in
}
6.2.3.4. Resetting the Style for Each Database[link]
This means that a solid line will always be used (with either
style=both or style=lines) regard of
the group-styles or style-resets options.
The first database has brown lines and the second database has blue
lines. Experiment 1 for each database has circle markers,
Experiment 2 has square markers and Experiment 3 (which is only in
the second database) has diamond markers. The other listed markers
aren’t used. Note, however, that the marker colours still cycle
through the entire mark-colors list.
\DTLplot
{growthdata,growthdata2}{
style=both, group-styles={line-color},
style-resets={mark-style},
line-colors={brown,blue,lime,black,orange},
mark-colors={magenta,teal,green,violet,cyan},
lines={
\pgfsetdash
{}{0pt}% solid line
},
marks={
\pgfuseplotmark
{o},
\pgfuseplotmark
{square},
\pgfuseplotmark
{diamond},
\pgfuseplotmark
{asterisk},
\pgfuseplotmark
{star}
},
x={Exp1Time,Exp2Time,Exp3Time},
y={Exp1Count,Exp2Count,Exp3Count},
x-label={Time ($t$)},y-label={Log Count},
legend, legend-offset={-10pt,0pt},
width=2.5in,height=2.5in
}
6.2.4. Plot Axes Examples[link]
6.2.4.1. Setting the Bounds[link]
\DTLplot
{growth1,growth2}{
x=Time,
y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
min-y=3,max-y=6,
style=lines, width=2.5in, height=2.5in
}
6.2.4.2. Tick Label Rounding[link]
\DTLplot
{growth1,growth2}{
x=Time,
y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
min-y=3,max-y=6,
round-x=0, round-y=1,
style=lines, width=2.5in, height=2.5in
}
6.2.4.3. Axis Style[link]
Note that the arrow heads overlap the end tick marks. This can be
dealt with by extending the axes using extend-x-axis and
extend-y-axis (see §6.2.4.7).
This is different to changing the plot bounds as it extends the axes
without adding additional tick marks.
\DTLplot
{growth1,growth2}{
x=Time,
y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
min-y=3,max-y=6,
round-x=0, round-y=1,
tick-dir=out, minor-ticks, axis-style={->,thick},
style=lines, width=3in, height=2.5in
}
6.2.4.4. Grid[link]
\DTLplot
{growth1,growth2}{
x=Time,
y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
min-y=3,max-y=6,
round-x=0, round-y=1,
grid, minor-ticks,
style=lines, width=3in, height=2.5in
}
\DTLmajorgridstyle
, and the style of the minor grid lines
is obtained by expanding \DTLminorgridstyle
. These can be
redefined as required but should expand to valid tikz options.
If \DTLminorgridstyle
is redefined to expand to nothing then
the minor grid lines won’t be drawn even if the tick marks are
enabled. For example:
Instead of explicitly redefining those commands, you can
use the major-grid-style and
minor-grid-style options.
\renewcommand
{\DTLmajorgridstyle
}{gray,ultra thick}
\renewcommand
{\DTLminorgridstyle
}{}
This results in thick major grid lines and no minor grid lines (even
though the minor ticks are on).
\DTLplot
{growth1,growth2}{
x=Time,
y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
min-y=3,max-y=6, minor-ticks,
round-x=0, round-y=1,
grid, major-grid-style={gray,ultra thick}, minor-grid-style={},
style=lines, width=3in, height=2.5in
}
6.2.4.5. Box[link]
\DTLplot
{growth1}{
x=Time,
y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
legend, round=0, minor-ticks,
min-y=3,max-y=5,y-tick-gap=1,
tick-label-offset=0pt, box,
width=2.5in, height=2.5in
}
\DTLplot
{growth1}{
x=Time,
y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
legend, round=0, minor-ticks,
min-y=3,max-y=5,y-tick-gap=1,
tick-label-offset=0pt, box, box-ticks=none,
width=2.5in, height=2.5in
}
6.2.4.6. Negative Axes[link]
The labels in Example 172 are very untidy as they
overlap. This can be addressed by rounding the tick label values and moving
the axis labels to the end (see Example 173).
\DTLplot
{xydata}{
x=X, y={Y},
tick-dir=out, round=1
x-label={$x$}, y-label={$y$},
style=lines, width=3in, height=3in
}
6.2.4.7. Extending the Axes[link]
Note that even though the tick label offset has been set to zero,
there is still a slight gap between the tick mark and the label.
This is due to tikz’s default inner sep for nodes.
\DTLplot
{xydata}{
x=X, y={Y},
tick-dir=out, x-tick-gap=1, round-x=0, round-y=1,
extend-x-axis={0,1}, extend-y-axis={0,0.5},
tick-label-style={font=\small
}, tick-label-offset=0pt,
max-x-label={$x$}, max-y-label={$y$},
style=lines, width=3in, height=3in
}
6.2.4.8. Changing the Tick Label Node Style[link]
tick-label-style={font=
This is equivalent to:
\small
}
x-tick-label-style={font=
Note that the y-tick-label-style includes the node anchor.
Example 174 changes these two values separately
so that they both use a small font, but the \(y\)-tick labels are
additionally rotated, and the inner opt is set to 1pt to
bring the \(y\)-tick label closer to the tick mark.
\small
},
y-tick-label-style={anchor=east,font=\small
}
Additionally, \DTLplot
{xydata}{
x=X, y={Y},
tick-dir=out, x-tick-gap=1, round-x=0, round-y=1,
extend-x-axis={0,1}, extend-y-axis={0,0.5},
x-tick-label-style={font=\small
},
y-tick-label-style={anchor=south east, inner sep=1pt, rotate=45, font=\small
},
tick-label-offset=0pt,
max-x-label={$x$}, max-y-label={$y$},
style=lines, width=3in, height=3in
}
\DTLplotdisplayticklabel
is redefined to ensure
that the tick labels are in math mode:
This shows the negative numbers with a correct minus sign rather
than a hyphen.
\renewcommand
{\DTLplotdisplayticklabel
}[1]{\ensuremath
{#1}}
6.2.4.9. Side Axes[link]
\DTLplot
{xydata}{
x=X, y={Y},
tick-gap=1, round=0,
tick-label-style={font=\small
},
tick-label-offset=0pt,
minor-ticks, side-axes,
style=lines, width=3in, height=3in
}
\renewcommand
{\DTLplotdisplayticklabel
}[1]{\ensuremath
{#1}}
\DTLplot
{growth1}{
x=Time,
y={Experiment 1,Experiment 2},
x-label={Time ($t$)}, y-label={Log Count},
legend, round=0, minor-ticks,
min-y=3,max-y=5,y-tick-gap=1,
tick-label-offset=0pt, box,
side-axes,
extend-x-axis={5},
extend-y-axis={0.5},
width=2.5in, height=2.5in
}
6.2.5. Begin and End Hooks[link]
The end hook is also redefined to show the minimum and maximum \(y\)
values, for illustrative purposes.
\renewcommand
{\DTLplotatbegintikz
}{
\draw
(0,0) node[anchor=north east] {0};
}
The plot options are similar to previous examples in
§6.2.4 but the \(x\) and \(y\) tick settings are
made the same for simplicity. Both axes are extend at their maximum
end and drawn with thick lines and an arrow head at the end.
\renewcommand
{\DTLplotatendtikz
}{
\draw
[blue,dotted] (\DTLminX
,\DTLminY
) -- (\DTLmaxX
, \DTLminY
)
node[right] {$y_{\min
} = \DTLminY
$};
\draw
[blue,dotted] (\DTLminX
,\DTLmaxY
) -- (\DTLmaxX
, \DTLmaxY
)
node[right] {$y_{\max
} = \DTLmaxY
$};
}
\DTLplot
{xydata}{
x=X, y={Y},
tick-dir=out, tick-gap=1, round=0,
extend-x-axis={0,0.5}, extend-y-axis={0,0.5},
tick-label-style={font=\small
},
tick-label-offset=0pt,
axis-style={->,thick},
max-x-label={$x$}, max-y-label={$y$},
style=lines, width=3in, height=3in
}
6.3. Supplementary Plot Commands[link]
\DTLplot
internally starts and ends the tikzpicture
environment. The following hooks are provided to add additional
content.
(1234,567)
.
\DTLplot
can cause plot marks or
other content to appeared skewed. If necessary, you can reset the
transformation matrix with pgf’s \pgftransformreset
but
make sure that \DTLplot
’s transformation matrix is restored
before the end of \DTLplotatbegintikz
. This can either be done
by scoping \pgftransformreset
or by using:
6.3.1. General Functions and Variables[link]
\DTLplot
hooks, this command will expand
to the minimum \(x\) value of the plot bounds. Since the plot code is
scoped, it can’t be referenced outside of the plot hooks. However,
if you use the plot
action, you can access this value with
the min-x secondary return value.
\DTLplot
hooks, this command will expand
to the minimum \(y\) value of the plot bounds. Since the plot code is
scoped, it can’t be referenced outside of the plot hooks. However,
if you use the plot
action, you can access this value with
the min-y secondary return value.
\DTLplot
hooks, this command will expand
to the maximum \(x\) value of the plot bounds. Since the plot code is
scoped, it can’t be referenced outside of the plot hooks. However,
if you use the plot
action, you can access this value with
the max-x secondary return value.
\DTLplot
hooks, this command will expand
to the maximum \(y\) value of the plot bounds. Since the plot code is
scoped, it can’t be referenced outside of the plot hooks. However,
if you use the plot
action, you can access this value with
the max-y secondary return value.
\seq_count:N
or
\clist_count:N
on the internal variables used to store those
lists.
\DTLplot
hooks to return the total number of
items given in the x list. If you use the plot
action, this value can also be accessed after the plot using the
x-count secondary return value.
\DTLplot
hooks to return the total number of
items given in the y list. If you use the plot
action, this value can also be accessed after the plot using the
y-count secondary return value.
\DTLplot
hooks to return the total number of
database names. If you use the plot
action, this value can
also be accessed after the plot using the name-count
secondary return value.
6.3.2. Stream Functions and Variables[link]
\DTLplot
to add the current plot stream to the
legend. The is the marker code and may be empty or
\relax
to indicate no marker. The is the line
style code and may be empty or \relax
to indicate no line. The
is the legend text associated with the current plot
stream. Note that and should include
the associated colour change, if applicable. The marker or line
code is encapsulated in a pgfpicture environment with the line
style scoped so that any colour change doesn’t affect the marker.
\DTLaddtoplotlegend
to change the style
of the legend, you will need to switch to LaTeX3 syntax. The legend
is constructed by appending content to:
\DTLplot
(but
before \DTLplotatendtikz
) should contain the code to typeset
the plot legend.
\DTLaddtoplotlegend
is used to add the current stream
information to the legend. If legend-labels has been used,
the legend text is obtained from the corresponding item in that
list. Otherwise it’s obtained using the following command.
\DTLaddtoplotlegend
) when there is no corresponding label
provided by legendlabels, and stores it in the token list
variable . The and arguments
are the column keys for the current \(x\) and \(y\) plot stream. The
default behaviour for each row of the legend depends on the number
of databases and x and y variables.
\dataplot_get_default_legend:Nnnnn
and
its associated commands is described in more detail in
§6.3.3.
\l_dataplot_x_key_int
and \l_dataplot_y_key_int
can be used in
\dataplot_get_default_legend:Nnnnn
they shouldn’t be added to the
token list variable provided in the first argument as their values
will have changed by the time the token list variable content is
added to the input stream. This means they also shouldn’t be
referenced within commands like \DTLplotlegendx
which are added
unexpanded to the token list variable. This is why their expanded
values are passed in the optional arguments of the legend hooks.
\dataplot_get_default_legend:Nnnnn
, this can be used to
reference current stream index. In the end hook, it may be used to
reference the final stream index, which will be the total number of
streams. (In the start hook, it will be zero.) The plot
action assigns the primary return value (and the secondary
stream-count) value to the value of this integer.
\DTLplot
to keep track of the current \(x\) column key.
That is, the index (starting from 1) of the current item in the
x comma-separated list.
\DTLplot
to keep track of the current \(y\) column key.
That is, the index (starting from 1) of the current item in the
y comma-separated list.
6.3.3. Post-Stream Hooks[link]
\DTLformatlegend
. The
default is to draw the legend in a colour box with a white
background and a black border. Note that this will cause the legend
to blank out the region of the plot drawn behind it.
The default definition simply does:
\setlength
{\fboxrule
}{1.1pt}% sets the border width
\fcolorbox
{black}{white}{ }
This should be redefined as applicable to position the legend in the
required place. The command should expand to valid tikz (or pgf) code.
See Example 160.
\node
{\DTLformatlegend
{ }};
\l_dataplot_legend_tl
. By
default, this inserts the beginning of a tabular environment:
\cs_new:Nn
\dataplot_legend_add_begin:
{
\tl_put_left:Nn
\l_dataplot_legend_tl
{ \begin
{ tabular } { c l } }
}
\l_dataplot_legend_tl
. By
default, this inserts the end of a tabular environment:
\cs_new:Nn
\dataplot_legend_add_end:
{
\tl_put_right:Nn
\l_dataplot_legend_tl
{ \end
{ tabular } }
}
\dataplot_get_default_legend:Nnnnn
. This constructs the
legend text according to the number of items in the database list
, the x list, and the y list.
The applicable commands (described below) are added unexpanded to
the legend token list variable but their arguments are expanded to
ensure that the correct values are present when the legend is
finally drawn.
\DTLplot
,
is the index of the within the x list, and
the index of the within the y list.
This is not the same as the column index (which can be obtained
with
). For example,
with the following:
\dtlcolumnindex
{ }{ }
The of “growthdata2” is 2 as it’s the second in
the list \DTLplot
{growthdata,growthdata2}{
x={Exp1Time,Exp2Time,Exp3Time},
y={Exp1Count,Exp2Count,Exp3Count},
legend
}
growthdata,growthdata2
, the of
“Exp1Time” is 1 as it’s the first in the x list
(coincidentally that also happens to be its column index),
and the of “Exp3Count” is 3 as it’s the third in
the y list (but its column index is 6). Where the indexes
are optional, the default value is 0.
If there is only one database, the name will be omitted:
/
If there is only one /
x variable then the
and separator will be omitted, so with more than one database and
more than one y variable:
If there is only one database and only one
x variable,
then only the will be used if the y option
contained more than one key otherwise only the will be
shown.
\dataplot_get_default_legend:Nnnnn
is used at the end of each plot
stream (and so, can reliably access variables such as
\l_dataplot_stream_index_int
), the legend commands below are only
expanded when the legend is drawn after all the streams have been
plotted, at which point it’s too late to access stream variables.
\DTLplotlegendname
use instead of
. This command is simply a user-level interface that
puts the mapping in the following property list:
If you have LaTeX3 syntax on, you can access this property list
directly. A token list variable is defined specifically for
accessing values in this property list:
\DTLplotlegendname
will be followed by:
part where there are
multiple / x column keys. The default definition is:
\DTLplotlegendx
[ ]{ }[ ]{ }%
\DTLplotlegendxysep
\DTLplotlegendy
[ ]{ }[ ]{ }
\DTLplotlegendx
use instead of the
column header for the given column key. This command is simply
a user-level interface that
puts the mapping in the following property list:
If you have LaTeX3 syntax on, you can access this property list
directly. A token list variable is defined specifically for
accessing values in this property list:
/
with a space on either side.
\DTLplotlegendy
use instead of the
column header for the given column key. This command is simply
a user-level interface that
puts the mapping in the following property list:
If you have LaTeX3 syntax on, you can access this property list
directly. A token list variable is defined specifically for
accessing values in this property list:
6.4. Conditionals[link]
\if
conditionals that can be switched
on or off with the corresponding \
and
true\
commands. There are corresponding settings
that do this, such as falsebox and grid.
\ifDTLshowlines
and \ifDTLshowmarkers
to false, since that
combination makes no sense. If you explicitly change these
conditionals, make sure you don’t set them both to false.
6.4.1. Lengths[link]
\setlength
or, if available, via a
setting.
6.4.2. Counters[link]
\setcounter
or locally changed with the
corresponding setting.
6.4.3. Macros[link]
\color
).
The line-colors option redefines this command. The default
definition is:
Note that spaces and empty items will be removed. Use \newcommand
{\DTLplotlinecolors
}{red, green, blue, yellow,
magenta, cyan, orange, black, gray}
{}
or
\relax
to indicate the default colour.
Note that spaces and empty items will be removed. Use \newcommand
{\DTLplotlines
}{
\pgfsetdash
{}{0pt},% solid line
\pgfsetdash
{{10pt}{5pt}}{0pt},
\pgfsetdash
{{5pt}{5pt}}{0pt},
\pgfsetdash
{{1pt}{5pt}}{0pt},
\pgfsetdash
{{5pt}{5pt}1pt5pt}{0pt},
\pgfsetdash
{{1pt}{3pt}}{0pt}
}
{}
or
\relax
to indicate the line should be omitted for the
corresponding plot stream.
\color
).
The mark-colors option redefines this command. The default
definition is:
Note that spaces and empty items will be removed. Use \newcommand
{\DTLplotmarkcolors
}{red, green, blue,
yellow, magenta, cyan, orange, black, gray}
{}
or
\relax
to indicate the default colour.
Note that spaces and empty items will be removed. Use {} or
\newcommand
*{\DTLplotmarks
}{
\pgfuseplotmark
{o},
\pgfuseplotmark
{x},
\pgfuseplotmark
{+},
\pgfuseplotmark
{square},
\pgfuseplotmark
{triangle},
\pgfuseplotmark
{diamond},
\pgfuseplotmark
{pentagon},
\pgfuseplotmark
{asterisk},
\pgfuseplotmark
{star}
}
\relax
to indicate the marker should be omitted for the
corresponding plot stream.
\DTLplotdisplayXticklabel
and \DTLplotdisplayYticklabel
are initially defined to simply use \DTLplotdisplayticklabel
to
encapsulate the tick labels. This means that if you want the same
formatting for both \(x\) and \(y\) tick labels, you can redefine this
command instead of redefining both
\DTLplotdisplayXticklabel
and \DTLplotdisplayYticklabel
.
For example:
Alternatively, you can use the tick-label-style option to
change the node style (see Example 174).
\renewcommand
{\DTLplotdisplayticklabel
}[1]{\ensuremath
{#1}}
\DTLplotdisplayticklabel
to
use \datatool_datum_value:Nnnnn
(which requires LaTeX3 syntax
on).
6.5. Adding to a Plot Stream at the Start or End[link]
\DTLplot
can take a comma-separated list of y values.
and ensures that \pgftransformreset
\pgfplothandlermark
{ }
\dataplot_apply_pgftransform:
occurs after the
hook. You can use \pgfplothandlermark
directly but remember
that the plot marks will be distorted by the \DTLplot
transformation
matrix if it is still in effect.
\DTLplot
.
7. Converting a BibTeX database
into a datatool database (databib package)[link]
Note that if datatool hasn’t already been loaded, this will
also apply rollback to datatool. Problems may occur if a newer
release of datatool has already been loaded.
\usepackage
{databib}[=v2.32]
\DTLloadbbl
or \DTLloadmbbl
are provided to set the
bibliography style to databib, identify the required
bib file (or files), create the database and input the
bbl file. See §7.4 for further details.
\DTLsortdata
or \DTLsort
. Bear in mind that a column may
not be created if there was no selected reference with the
corresponding field set in the bib file.
\DTLmapdata
or
\DTLforeach
, a wrapper command \DTLforeachbibentry
is
provided (see §7.8) for custom loops, and
\DTLbibliography
(see §7.6) may be used to
display the contents of the database in a format similar the
basic plain, abbrv and alpha bibtex
styles.
CiteKey
(the label used in \cite
that uniquely
identifies the entry) and EntryType
(the BibTeX entry type
in lowercase, without the leading @
). The other fields are
listed in §7.2.2.
7.1. Package Options[link]
\DTLbibliographystyle
after databib has loaded.
\DTLloadbbl
may only be used in the preamble.
\DTLsetup
(if
allowed) otherwise.
7.2. BibTeX: An Overview[link]
\bibstyle
(which indicates
which bibliography style (bst) file to load), \bibdata
(which indicates which bibliography database (bib) files to
load) and \citation
(produced by \cite
and \nocite
, which
indicates which entries should be included in the bibliography).
BibTeX then creates a file with the extension bbl which
contains the bibliography, formatted according to the layout defined
in the bibliography style file.
latex mydoc
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 (similar to ??
which
marks unknown references).
bibtex mydoc
This reads the auxiliary file, and creates a file with the extension
bbl which typically contains the typeset bibliography.
latex mydoc
Now that the 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.
latex mydoc
The cross-referencing information can be read from the auxiliary
file.
7.2.1. BibTeX database[link]
@
The { ,
= ,
\vdots =
}
may be delimited with braces or double-quotes or
may be a number or a predefined string. For example:
@STRING{TUGBOAT = {TUGboat}}
The above first defines a string constant (“TUGBOAT
”) that may
be used instead of a literal string in the field value. Note that
the constant isn’t delimited by braces or double-quotes when
referenced in the field value.
\cite
or \nocite
.
The available fields depends on the entry type (and the bst
file), 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 = "Henry James de Vere"
In the above, the first names are Henry James, the “von part” is
“de” and the surname is “Vere”. There is no “junior part”.
author = "Mary-Jane Brown, Jr"
In the above, the first name is Mary-Jane, there is no von part,
the surname is Brown and the junior part is Jr.
author = "Peter {Murphy Allen}"
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.
author = "Maria Eliza {
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:
\MakeUppercase
{d}e La} Cruz"
author = "Maria Eliza De La Cruz"
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
{
will trick BibTeX into thinking that it starts with a
lowercase letter.
\MakeUppercase
{d}e La}author = "de Vere, Henry James"
author = "Michel Goossens and Frank Mittlebach and Alexander Samarin"
@book{latexcomp,
title = "The
Note that numbers may be entered without delimiters, as in \LaTeX
\␣Companion",
author = "Michel Goossens and Frank Mittlebach and
Alexander Samarin",
publisher = "Addison-Wesley",
year = 1994
}
year = 1994
.
There are also some predefined strings, including those for the month
names. It’s best to use these strings instead of the actual
month name, as the way the month name is displayed depends on the
bibliography style. For example:
@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
}
month = JUL # "
Depending on the bibliography style, this may be displayed as:
July 31 – August 4, or it may be displayed as:
Jul 31 – Aug 4.
~
31~
--~
" # AUG # "~
4",
7.2.2. Column Keys (Fields)[link]
\cite
that uniquely
identifies the entry. The value in this field will match the
given in the bib file.
@
. For example, an entry
defined with @ARTICLE
in the bib file will have the
EntryType
column set to article
.
\doi
command
provided by the doi package is designed to support such
identifiers, that command can’t be used in the argument of another
command. Therefore this field will be set with
\DTLnewbibliteralitem
instead of \DTLnewbibitem
.
Note that any braces within the value must be balanced.
\DTLnewbibliteralitem
instead of \DTLnewbibitem
.
\DTLnewbibliteralitem
instead of \DTLnewbibitem
.
\DTLmonthname
to
make sorting easier.
\DTLnewbibliteralitem
instead of \DTLnewbibitem
.
7.3. Loading a databib database[link]
\DTLloadbbl
. That is, the bbl file will contain the
commands that construct the database with the bibliographic data
(see §7.4).
\cite
or \nocite
as usual. If you want to
add all entries in the bib file to the datatool database,
you can use
.
\nocite
{*}
which tells BibTeX to use the databib.bst
BibTeX style file;
\bibstyle
{databib}
to the
auxiliary file, which tells BibTeX which bib files to
use;
\bibdata
{ }
, which is the usual name for
a bbl file.) If the bbl file doesn’t exist, the
database will remain empty.
\jobname
.bbl\DTLloadbbl
doesn’t generate any text.
Once you have loaded the data, you can display the bibliography using
\DTLbibliography
(described in §7.6) or you
can iterate through it with \DTLforeachbibentry
described in
§7.8.
\DTLendbibitem
hook.
7.4. The databib Database Construction Commands[link]
\DTLloadbbl
and
\DTLloadmbbl
, but note that there’s no database creation
command within the bbl file. The database creation is
performed by \DTLnewdb
within the definition of
\DTLloadbbl
and \DTLloadmbbl
.
\DTLBIBdbname
is defined to expand to the
database name.
Note that this is the starred form that doesn’t test for the
database existence.
\DTLnewrow*
{\DTLBIBdbname
}
Again, the starred form is used which doesn’t test for the database
existence.
\DTLnewdbentry*
{\DTLnewbibitem
}{ }{ }
Url
and DOI
. The will
be detokenized before being added to the final row of the database.
Note that any braces within must be balanced.
\DTLwrite
.
This means that these literal fields may cause a problem if you
choose to save the database. The best solution in this case is to
save to a CSV file which can then be loaded with
csv-content
=literal.
7.5. Sorting a databib database[link]
\DTLloadbbl
(or
\DTLloadmbbl
), it can be sorted using \DTLsortdata
or
\DTLsort
(see §3.14).
The databib package automatically does:
This means that \dtlSortWordCommands
{\let
\DTLmonthname
\@firstofone
}
\DTLmonthname
will expand to its numeric
argument when the sort values are created, which makes it easier to
sort chronologically. Just make sure to use the BibTeX month
strings (JAN, FEB, etc) as in the examples in
§7.10.
This allows for dates to be specified in either the
\DTLsortdata
[missing-column-action
=ignore]
{mybib}% database name
{Date
=descending
,Year
=descending
,Month
=descending
}
Date
field or in the Year
and
Month
fields.
Author
or Editor
, remember
that those fields will contain comma-separated lists where each
element is in the form
{
.
For example, if a }{ }{ }{ }bib entry has:
author = {von Parrot, Jr, Ann and José Arara}
then the Author
field for the corresponding row in the
databib database will be:
{von}{Parrot}{Jr}{Ann},{}{Arara}{}{José}
This means that if the database is sorted by Author
:
then the sort value will be:
\DTLsortdata
{mybib}{Author}
vonParrotJrAnn,AraraJosé
This may or may not be sufficient, depending on your requirements.
Author
and Editor
fields, databib provides:
encap
function. This command
tests if corresponds to the column index for the
Author
or Editor
keys. If it doesn’t, it
will simply expand to . If it does, it will expand the
comma-separated value so that each element is
separated with:
and each element is encapsulated with:
which, by default, does:
This means that the earlier example will expand to:
\tl_if_empty:nF
{ } { ~
}
\tl_if_empty:nF
{ } { , ~
}
\datatoolpersoncomma
von Parrot, Jr
This produces a better result where there are multiple authors. You
can redefine \datatoolpersoncomma
Ann\DTLbibsortnamesep
Arara\datatoolpersoncomma
José
\DTLbibsortname
if a different sort value is
required. For example, to ignore the and parts:
Remember that the definition must be expandable.
\renewcommand
{\DTLbibsortname
}[4]{%
#2\datatoolpersoncomma
#4}
Author
, but if the
Author
field hasn’t been set it will sort by
Editor
, and if the Editor
hasn’t been set, it will
sort by Title
. In the event that there are duplicate
primary values, the secondary sort will be by the Title
:
\DTLsortdata
[encap
=\DTLbibsortencap
]
{mybib}{Author={replacements
={Editor,Title}},Title}
7.6. Displaying a databib database[link]
\DTLloadbbl
(described in §7.3) can be
displayed using:
\begin{DTLthebibliography}
[ ]{ }
\DTLforeachbibentry*
[ ]{ }{%
\DTLbibitem
\DTLformatbibentry
\DTLendbibitem
}%
\end{DTLthebibliography}
\DTLforeach
(that is, any condition that may be used in
\ifthenelse
, see §2.4.2).
In addition, you may use the following commands, which
reference values in the current row.
\DTLloadbbl
(described in
§7.3) then the following bibliography will only
include those entries which have a Year
field:
\DTLbibliography
[\DTLbibfieldexists
{Year}]{mybib}
Year
field set to 2004:
\DTLbibliography
[\DTLbibfieldiseq
{Year}{2004}]{mybib}
\DTLbibliography
[\DTLbibfieldcontains
{Author}{Knuth}]{mybib}
Year
field is less than 1983:
\DTLbibliography
[\DTLbibfieldislt
{Year}{1983}]{mybib}
Year
field is less than or equal to 1983:
\DTLbibliography
[\DTLbibfieldisle
{Year}{1983}]{mybib}
Year
field is greater than 1983:
\DTLbibliography
[\DTLbibfieldisgt
{Year}{1983}]{mybib}
Year
field is greater than or equal to 1983:
\DTLbibliography
[\DTLbibfieldisge
{Year}{1983}]{mybib}
\DTLbibliography
uses \DTLforeachbibentry
(described in §7.8) so you may also
test the value of the counter DTLbibrow within
(as in Example 182), but bear in mind
that the counter is only incremented after testing the condition
(and then only if the condition evaluates to true).
You may also use the boolean commands defined
by the ifthen package, such as \not
.
7.7. Changing the bibliography style[link]
\DTLbibliography
may be set with the style package option, or with:
\bibliographystyle
,
as the databib package uses its custom databib.bst
bibliography style file.
or
\usepackage
[style=plain]{databib}
Both of the above set the plain bibliography style. This is, in fact, the
default style, so it need not be specified.
\DTLbibliographystyle
{plain}
\DTLsortdata
or
\DTLsort
(described in §3.14).
7.7.1. Modifying an existing style[link]
\DTLforeachbibentry
and format each row according
to your particular requirements. However, the predefined styles used
by \DTLbibliography
, \DTLmbibliography
, and
\DTLformatthisbibentry
provide a more convenient method if they are
sufficient for your needs. The hooks described in this section allow
you to make minor adjustments the selected style.
\DTLformatauthor
or
\DTLformateditor
or \DTLformatsurnameonly
for formatting.
\DTLformatauthor
and \DTLformateditor
, you may
use the following commands.
\DTLstoreinitials
(see §2.8.2).
\renewcommand
*{\DTLformatauthor
}[4]{%
\textsc
{\DTLformatvon
{#1}\DTLformatsurname
{#2}\DTLformatjr
{#3}},
\DTLformatforenames
{#4}%
}
\etalname
is used.
Author
field). Each name is
formatted with to \DTLformatauthor
.
Editor
field). Each name is
formatted according to \DTLformateditor
. The list is followed
by a comma and space and either \editorname
or \editorsname
,
depending on whether the list contains one or more elements.
{
and
}{ }{ }{ } must have those four arguments for its syntax. If
the list has more than items, it will be truncated with
\etalname
.
\DTLandlast
and \DTLtwoand
use
\DTLlistand
for “and”.
Date
field is set. If so, it will format that field
with \DTLbibdatefield
. Otherwise, it tests if the
Year
and Month
fields are set.
Pages
field is set, this will be displayed
preceded by the language-sensitive \pagename
or
\pagesname
. The textual tag and the contents of the
Pages
field are separated with:
which expands to a non-breakable space by default.
\DTLbibliography
. It uses \bibitem
to provide a marker,
such as [1], and writes the citation information to the aux
file in order to resolve references on the next LaTeX run.
\DTLmbibliography
, and is analogous to \DTLbibitem
.
\DTLbibliography
and \DTLmbibliography
that
does nothing by default, but may be redefined to include additional
content at the end of the current entry.
\DTLbibfield
, \DTLifbibfieldexists
and \DTLifanybibfieldexists
, which are described in
§7.8. For example, if you have used the
abstract field in any of your entries, you can display the
abstract as follows:
\renewcommand
{\DTLendbibitem
}{%
\DTLifbibfieldexists
{Abstract}{\DTLpar
\textbf
{Abstract}
\begin{quote}
\DTLbibfield
{Abstract}\end{quote}
}{}%
}
\DTLendbibitem
to include the digital
information. The result varies depending on whether or not
the hyperref or url packages have been loaded.
The content will be included in the following order:
PubMed
field is set, this will be displayed
with \DTLbibpubmed
.
DOI
field is set, this will be
displayed with \DTLbibdoi
.
Url
field is set, this will be
displayed with \DTLbiburl
, and if the UrlDate
field is also set, this will be displayed with \DTLbiburldate
.
Eprints
field is set, this will be
displayed with \DTLbibeprints
, where the second argument will
either be the content of the EprintType
field (if
set) or “eprint
” otherwise.
\DTLbibformatdigital
, described below, may be
redefined to customize the output.
PubMed
field. The field
content is passed as the argument.
If the hyperref package has been loaded, the will be a
hyperlink.
\DTLbibpubmed
. By default, this
simply expands to
.
\textsc
{pmid}:␣\DTLbibpubmed
in the formation of the hyperlink, if
applicable.
DOI
field. The field
content is passed as the argument. Remember that this field is set
with \DTLnewbibliteralitem
which detokenizes the content before
adding it to the database. This means that \DTLbibdoi
doesn’t
make any category code changes as it expects the argument to be
detokenized already.
\url
(if defined) or \texttt
otherwise.
If hyperref isn’t required but the DOI needs better
formatting, try loading the url package.
\DTLbibdoi
. By default, this
simply expands to
.
\textsc
{doi}:␣\DTLbibdoi
in the formation of the hyperlink, if
applicable.
Eprints
field.
The field content is passed as the first argument. The second
argument is set by \DTLbibformatdigital
to either the value of
the EprintType
field, if set, or “eprint
”
otherwise.
Eprints
field is assumed to be a
URL. If not, you will need to redefine \DTLbibeprints
as
applicable.
Url
field.
The field content is passed as the argument. If \url
has been
defined (for example, by loading hyperref or the url
package) then that will be used to format the argument otherwise it
will simply be typeset in a monospaced font.
UrlDate
field.
The argument provided by \DTLbibformatdigital
will be:
The definition of \DTLbibdatefield
{UrlDate
}
\DTLbiburldate
is:
which places the date in parentheses prefixed with:
\space
(\DTLbibaccessedname
: )
7.8. Iterating through a databib database[link]
\DTLbibliography
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:
\DTLforeach*
and
the unstarred version uses the unstarred \DTLforeach
. This
means that you can use \dtlbreak
in to terminate
the loop after the current iteration. Note that you can’t have
explicit paragraph breaks in (that is, \par
or a blank line in
your source code). If you need a paragraph break, use \DTLpar
.
\DTLforeach
makes global changes,
\DTLforeachbibentry
only makes local assignments for the
placeholder commands, which means that it’s unsuitable to display the references
in a tabular-like environment.
\DTLforeachbibentry
but the placeholder commands are
globally assigned.
\DBIBcitekey
This is the
unique label which identifies the current entry (as used in the
argument of \cite
and \nocite
).
\DBIBentrytype
This is the current entry type
(converted to lowercase), 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 bib file, its entry type
will be set to inproceedings).
in the command’s
argument. For example:
\DTLbibfield
{ }\strong
{\DTLbibfield
{Year}}
but
encapsulates the field value with . For example:
\DTLbibfield
{ }
The difference is that in this case the field value will be directly
passed to the formatting command. Also if the field isn’t set, the
command won’t be used in the second case but will be used in the
first. For example, \DTLencapbibfield
{\strong
}{Year}
\DTMdate
(provided by the datetime2
package) requires its argument to be in the form
(there are some other formats
as well, see the - -datetime2 manual for further details).
This means that it’s not possible to do, say:
Instead use:
\DTMdate
{\DTLbibfield
{Date}}
\DTLencapbibfield
{\DTMdate
}{Date}
\DTLformatdate
and \DTLbibformatdigital
to format
the Date
and UrlDate
fields,
respectively. The default definition simply uses \DTLbibfield
but may be redefined to format the date.
\DTLifbibfieldexists
except that the
first argument is a list of field names. If one or more of
the fields given in exists for the
current bibliography item, this does , otherwise
it does .
\DTLformat
, where
is given by \DBIBentrytype
. These commands are defined
by the bibliography style. There is also a version for use with
\gDTLforeachbibentry
:
It’s also possible to use \DTLformatbibentry
for a specific key,
rather than using it within \DTLforeachbibentry
.
This formats the row identified by in the database
using the same format as \DTLformatbibentry
.
\bibitem
. You can manually insert
in front of the command, or you can use:
\bibitem
{ }\bibitem
[ ]{ } except that it uses
instead of \item
[ ] and
instead of \the\value{\@listctr}
.
\ifthenelse
, and you may use. any of the
commands that may be used within the optional argument of
\DTLbibliography
, described in §7.6
\DTLforeachbibentry
and is incremented if
is met.
7.9. Multiple Bibliographies[link]
\DTLmultibibs
, you must use:
,
but writes the \cite
[ ]{ }\citation
command to .aux instead
of to the document’s main auxiliary file. It also ensures that
the cross-referencing labels are based on , 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 \cite
to add citation information to
the main auxiliary file.
, where
again the citation information is written to .aux
instead of the document’s main auxiliary file.
\nocite
{ }\DTLloadbbl
,
described in §7.3. This creates
a new datatool database called and inputs
.bbl (if it exists), which should contain the
commands required to construct the database.
\DTLbibliography
,
but is required when displaying a bibliography in which elements have
been cited using \DTLcite
and \DTLnocite
.
As \DTLbibliography
, it iterates over the database using
\DTLforeachbibentry*
.
7.10. Examples[link]
[breakable]
@STRING{TUGBOAT = {TUGboat}}
@STRING{PRACTEX = {The Prac
The second file, sample2.bib, contains fictitious
references:
\TeX
\␣Journal}}
@ARTICLE{Flom2005,
author = {Peter Flom and Hans Hagen and Joe Hogg and Nicola Talbot and Philip
Taylor and Christina Thiele and David Walden},
title = {What is {\TeX
}?},
journal = PRACTEX,
year = 2005,
volume = 3,
url = {http://tug.org/pracjourn/2005-3/walden-whatis}
}
@ARTICLE{tugboat2016,
title = "Localisation of {\TeX
} documents: tracklang",
author = "Nicola Talbot",
month = NOV,
year = 2016,
volume = 37,
number = 3,
journal = TUGBOAT,
url = "http://www.tug.org/TUGboat/tb37-3/tb117talbot.pdf"
}
@ARTICLE{tugboat2022,
title = "bib2gls: Standalone entries and repeated lists (a little
book of poisons)",
author = "Nicola Talbot",
month = APR,
year = 2022,
volume = 43,
number = 1,
journal = TUGBOAT,
doi = 10.47397/tb/43-1/tb133talbot-bib2gls-reorder,
url = "https://tug.org/TUGboat/tb43-1/tb133talbot-bib2gls-reorder.pdf"
}
@BOOK{Talbot2012a,
title = {{\LaTeX
} for Complete Novices},
publisher = {Dickimaw Books},
year = 2012,
month = SEP,
author = {Nicola L C Talbot},
volume = 1,
series = {Dickimaw {\LaTeX
} Series},
isbn = 978-1-909440-00-5,
url = {https://www.dickimaw-books.com/latex/novices/}
}
@INPROCEEDINGS{Talbot2020,
author = {Nicola L C Talbot},
title = {Sorting Glossaries with bib2gls},
booktitle = {{LaTeX}.net},
year = 2020,
month = JUL,
url = {https://latex.net/sorting-glossaries-with-bib2gls/}
}
@BOOK{Talbot2013a,
title = {Using {\LaTeX
} to Write a {PhD} Thesis},
publisher = {Dickimaw Books},
year = 2013,
month = MAR,
author = {Nicola L C Talbot},
volume = 2,
series = {Dickimaw {\LaTeX
} Series},
isbn = {978-1-909440-02-9},
url = {http://www.dickimaw-books.com/latex/thesis/}
}
@INPROCEEDINGS{Talbot2012c,
author = {Nicola L C Talbot},
title = {Creating a glossary without using an external indexing
application},
booktitle = {{LaTeX}.net},
year = 2012,
month = SEP,
url = {https://latex.net/glossary-without-external-app/},
note={Originally posted on the {\LaTeX
} Community's Know How
Section}
}
@BOOK{Talbot2014a,
title = {{\LaTeX
} for Administrative Work},
publisher = {Dickimaw Books},
month = SEP,
year = 2014,
author = {Nicola L C Talbot},
volume = 3,
series = {Dickimaw {\LaTeX
} Series},
isbn = {978-1-909440-07-4},
url = {https://www.dickimaw-books.com/latex/admin/}
}
@BOOK{Talbot2013b,
title = {Quack, Quack, Quack. Give My Hat Back!},
publisher = {Dickimaw Books},
year = 2013,
month = MAY,
author = {Nicola L C Talbot and Magdalene Pritchett},
isbn = {978-1-909440-03-6},
url = {https://www.dickimaw-books.com/fiction/kids/duck/}
}
@BOOK{Talbot2012b,
title = {The Foolish Hedgehog},
publisher = {Dickimaw Books},
year = 2012,
month = NOV,
author = {Nicola L C Talbot and Magdalene Pritchett},
isbn = {978-1-909440-01-2},
url = {https://www.dickimaw-books.com/fiction/kids/hedgehog/}
}
[breakable]
@Article{duck2018,
Author = {Dickie Duck and José Arara and Polly Parrot},
Title = {Avian Friendship},
Journal = {Fowl Times},
Year = 2018,
Volume = 7,
Number = 5,
Pages = "1032--5"
}
@BOOK{duck2016,
AUTHOR = {Dickie Duck},
TITLE = {Feathered stunt doubles:
Note that the bib entry types and field names are
case-insensitive. I’ve used a mixture of cases above.
\emph
{The Birds}
and other films},
PUBLISHER = {Duck Duck Goose},
YEAR = 2016
}
@book{macaw,
author = {Prof Macaw},
title = {Annotated notes on the \emph
{Duck and
Goose} chronicles},
publisher = Duck Duck Goose,
year = 2012
}
@inproceedings{parrot2021a,
author = {Polly Parrot},
title = {Who's a Pretty Polly? {T}he surge of avian chatbots},
booktitle = {Avian Intelligence},
month = jan,
year = 2021
}
@inproceedings{parrot2021b,
author = {Polly Parrot},
title = {Pollybot: the next generation in avian translators},
booktitle = {Avian Advances},
month = apr,
year = 2021
}
@phdthesis{ing2020,
author = {Bor Ing},
title = {\emph
{Duck and Goose}: an allegory for modern
times?},
school = {Department of Literature, University of Somewhere},
month = mar,
year = 2010
}
@booklet{parrots2013,
author = {Polly Parrot and Dickie Duck},
title = {\emph
{Duck and Goose} Cheat Sheet},
howpublished = {Limited print run},
address = {Dubious Student Resources},
year = 2013
}
@book{parrot2012,
author = {von Parrot, Jr, Ann},
title = {My Friend is a Duck},
publisher = {Duck Duck Goose},
year = 2012,
}
@book{quackalot,
author = {Sir Quackalot},
title = {The Adventures of Duck and Goose},
publisher = {Duck Duck Goose},
year = 2011
}
@techreport{zebra2022,
author = {Zoë Zebra and Mabel Canary},
title = {Health and Safety when Handling Mind-Controlling
Cookies},
institution = {Secret Lab of Experimental Stuff},
month = {22 } # MAR,
year = 2014
}
@manual{canary2015,
author = {Mabel Canary},
title = {Ray Gun User Guide},
organization = {Secret Lab of Experimental Stuff},
edition = "2nd",
year = 2015
}
@book{fan1992,
author = {Éli-Fant, Nellie},
title = {The Duckinator},
publisher = {Duck Duck Goose},
year = 1992,
note = {A cyborg from the future travels to the past
to scramble some eggs.}
}
@misc{henpecked,
title = {Henpecked: Time for a Coup in the Coop!},
howpublished = {Flyer}
}
7.10.2. Tabulate Bib Data[link]
\cite
). If the required entries are simply
selected with \nocite
then this simply provides a convenient
way to convert the data from the bib file into a format
compatible with datatool.
, it displays
the \DTLbibliography
{mybib}Author
and Title
values in a table. This can
be done with \DTLdisplaydb
but the Author
field will
be a comma-separated list with each element in the form
{
, which
will result in the name elements running together. This can be dealt
with by adjusting }{ }{ }{ }\DTLdisplaydbAddItem
so that it encapsulates
the Author
value with \DTLformatbibnamelist
(if
it’s not null). This assumes the Author
column is the first
column in the table (which it will be if it’s the first item in the
only-keys
list):
Note that the above won’t work if store-datum has been set,
which it isn’t by default. The data can now be displayed:
\RenewDocumentCommand
\DTLdisplaydbAddItem
{ m m m m m m m m }
{%
\DTLifnull
{#2}%
{\appto
#1{---}}% do a dash if null
{%
\ifnum
#7=1
\appto
#1{\DTLformatbibnamelist
{#2}{\value
{DTLmaxauthors}}{\DTLformatauthor
}}%
\else
\appto
#1{#3{#2}}%
\fi
}%
}
The document build is the same as before as BibTeX is still needed
to fetch the data from the bib file. Since
\DTLdisplaydb*
[only-keys
={Author,Title}]{mybib}
\DTLformatauthor
is set by the style and the style has been set
to abbrv, the forenames are abbreviated. The result is shown in
Example 180.
7.10.3. Publications Since a Given Year[link]
TEXMFHOME
tree
/bibtex/bib/. I could look through this file,
work out the labels for all the publications whose year field
is greater or equal to 2013, and
create a file with a \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 use databib to convert my publication data into
a datatool database:
Next is the instruction to BibTeX to select all the citations in the
bib file:
\documentclass
{article}
\usepackage
{databib}
Since my own bib file isn’t available (and is too
long to include), I’m going to use the sample1.bib file:
\nocite
{*}
The database is then sorted in reverse chronological order:
\DTLloadbbl
{mybib}{sample1}
If the bibliography database is large, sorting and creating
the bibliography may take a while. For large
bib files or complex requirements, consider using
biblatex and biber instead.
\DTLsortdata
{mybib}{Year=descending
,Month=descending
}
This is a string comparison, rather than a numerical
comparison, but since all the years are four digits it’s sufficient.
The result is shown in Example 181.
\DTLbibliography
[\DTLbibfieldisge
{Year}{2013}]{mybib}
7.10.4. Five Most Recent Publications[link]
This is just a different condition in the optional argument. Note
that the condition is evaluated before the DTLbibrow counter
is incremented (as it’s only incremented if the condition is true).
\DTLbibliography
[\value
{DTLbibrow}<5]{mybib}
\DTLendbibitem
to show the
ISBN
and Url
fields, if they have been set:
Note that this will require a package that defines \renewcommand
{\DTLendbibitem
}{%
\DTLifbibfieldexists
{ISBN}%
{ ISBN: \DTLbibfield
{ISBN}.}{}%
\DTLifbibfieldexists
{Url}%
{ \DTLencapbibfield
{\url
}{Url}}{}%
}
\url
. In
this case, I’ve used the url package, but this may be replaced
with hyperref if hyperlinks are required.
The result is shown in Example 182.
\dtlbreak
. This is done by replacing
\DTLbibliography
with:
\begin{DTLthebibliography}
{mybib}
\DTLforeachbibentry
{mybib}
{%
\DTLbibitem
\DTLformatbibentry
\DTLendbibitem
\ifthenelse
{\value
{DTLbibrow}=5}{\dtlbreak
}{}% terminate after row 5
}
\end{DTLthebibliography}
7.10.5. Compact Bibliography[link]
or using:
\usepackage
[style=abbrv]{databib}
Note that in the second case, the style must be set before the
bibliography is displayed, otherwise they will have no effect.
\DTLbibliographystyle
{abbrv}
Now I can load the bibliography. For this example, I’m
using both sample files (described earlier):
\renewcommand
*{\DTLtwoand
}{ \& }
\renewcommand
*{\DTLandlast
}{, \& }
\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}
This time the database is sorted alphabetically by the title:
\DTLloadbbl
{mybib}{sample1,sample2}
Remember that the required references need to be cited with
\DTLsortdata
{mybib}{Title}
\cite
or \nocite
. For simplicity, I have again used:
to select them all. As with the previous examples, the bibliography
is displayed with:
\nocite
{*}
The first page is shown in Example 183.
\DTLbibliography
{mybib}
7.10.7. Separate Bib Types[link]
All entries are selected by BibTeX:
\DTLloadbbl
{mybib}{sample1}
\DTLsortdata
{mybib}{Year=descending
,Month=descending
}
The journal papers are in the first section. I’m using the
article class, which provides \nocite
{*}
\refname
for the
bibliography title, so that can be redefined as applicable:
Next the widest label is computed for all entries that have
article in the \renewcommand
*{\refname
}{Journal Papers}
EntryType
column:
This will define my custom \DTLcomputewidestbibentry
{\equal
{\DBIBentrytype
}{article}}
{mybib}{J\theDTLbibrow
}{\widest
}
\widest
command to the widest
label, which can then be passed to the thebibliography
environment.
Similarly for the conference papers:
\begin{thebibliography}
{\widest
}
\DTLforeachbibentry
[\equal
{\DBIBentrytype
}{article}]{mybib}{%
\bibitem
[J\theDTLbibrow
]{\DBIBcitekey
} \DTLformatbibentry
}
\end{thebibliography}
The result is shown in Example 185. Note that this
involves multiple iterations over the database. It would be more
efficient to gather the required information (that is, testing and calculating
the widest labels) in one iteration. However, that’s more
complicated to code.
\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}
7.10.8. Multiple Bibliographies[link]
\DTLcite
and \DTLmbibliography
ensures that all the
cross-referencing labels (and hyperlinks if they are enabled)
are unique. As with the previous examples, I’m using the
article class to keep it simple. The auto
option can be used to automatically run BibTeX:
The following preamble command will create the files
nonfiction.aux and fiction.aux:
\usepackage
[auto]{databib}
The bbl files may be loaded anywhere before the databases need
to be referenced:
\DTLmultibibs
{nonfiction,fiction}
The databases can then be sorted, if required. In this case, the full
bibliography is sorted chronologically, but the other databases
aren’t sorted, so they will be in order of citation:
\DTLloadmbbl
{nonfiction}{nonfictionDB}{sample1}
\DTLloadmbbl
{fiction}{fictionDB}{sample1}
\DTLloadbbl
{fullDB}{sample1}
The document is as follows:
\DTLsortdata
{fullDB}{Year,Month}
Finally, all entries are selected for the main list:
\section
{Non Fiction}
In this section I'm going to describe some \LaTeX
work,
and in the process I'm going to cite some related
papers \DTLcite
{nonfiction}{tugboat2016,Talbot2012a}.
\DTLmbibliography
{nonfiction}{nonfictionDB}
\section
{Fiction}
In this section I'm going to describe my fiction, and in the process, I'm going
to cite some books \DTLcite
{fiction}{Talbot2013b,Talbot2012b}
\DTLmbibliography
{fiction}{fictionDB}
If the document source is in myDoc.tex, then the build
process with the default auto=false is:
\nocite
{*}
\renewcommand
{\refname
}{Complete List of Publications}
\DTLbibliography
{fullDB}
pdflatex myDoc
bibtex myDoc
bibtex nonfiction
bibtex fiction
pdflatex myDoc
pdflatex myDoc
With auto=true, the shell escape is required.
Since bibtex is normally on the restricted list and the
restricted shell escape is normally on by default, the build process
is then:
pdflatex myDoc
pdflatex myDoc
pdflatex myDoc
The resulting document is shown in Example 186.
7.11. Localisation[link]
. For example,
/ databibdatabib-english.ldf provides the option
short-month-style, which may have the value dotted
(abbreviated month names are followed by a dot) or
dotless (three letter abbreviation month names with no dot).
For example, to switch to dotless:
Or:
\DTLsetLocaleOptions
[en]{databib}{short-month-style=dotless}
\DTLsetLocaleOptions
{en/databib}{short-month-style=dotless}
8. Creating an index, glossary or list of abbreviations
(datagidx package)[link]
\printnoidxglossary
to
the glossaries package in 2014 (which uses TeX to sort and
collate) and \printunsrtglossary
to the glossaries-extra
package in 2016 (which doesn’t sort or collate). To avoid
duplication of effort, I don’t intend providing new features for
datagidx. The most flexible solution is to use
glossaries-extra and bib2gls, see the Dickimaw
Books Gallery for examples.
\DTLforeach
has been replaced with \DTLmapdata
. A
number of bugs have also been fixed, which may cause some
differences in the output. You may need to delete the temporary
files before rebuilding after upgrading to v3.0.
Rollback to version 2.32 is available:
Note that if datatool hasn’t already been loaded, this will
also apply rollback to datatool. Problems may occur if a newer
release of datatool has already been loaded.
\usepackage
{datagidx}[=2.32]
datagidx
which contains a list of each index/glossary with its associated settings. Whenever you define a new
index/glossary database with \newgidx
(see
§8.2), a new row is added to the datagidx
database and a new database is created in which to store each entry
associated with the particular index or glossary.
\useentry
the relevant information is looked up in the database. A mapping
exists between the entry label and the index/glossary database
label to ensure that the correct database is referenced. Unlike some
of the other supplementary packages provided with datatool, the
datagidx package doesn’t use the default-name setting,
but instead has its own way of identifying the default index/glossary database, which is independent of default-name.
\printterms
, which firsts sorts the database using
\DTLsortdata
.
8.1. Options[link]
\DTLsetup
). Additionally, the
package options described in §8.1.1 are
specific to datagidx.
\DTLsetup
option
index:
This may be used to set any of the options listed
§8.1.2.
\DTLsetup
{index={}
}8.1.1. Package Options[link]
8.1.1.1. Global Options[link]
sort
option for the relevant glossaries and manually
sort using \DTLsortdata
or \dtlsort
before the glossary is displayed.
See §8.8.3.1 for further details.
warn
option in the
index sub-setting.
compositor
option.
counter
option.
8.1.1.2. Style Options[link]
\printterms
.
\printterms
. This value may also be set after the
package has loaded with the columns
option.
\printterms
, where the value may be
named (show the child’s name) or noname (only show
the numeric label, as given by \DTLgidxChildCountLabel
, not the child’s
name). This value may also be set after the package has loaded with
the child
option.
\printterms
, where the value may be
nochange, uc, lc, firstuc
or capitalise. This value may also be set after the
package has loaded with the namecase
or name-case
option.
\printterms
.
This value may also be set after the package has loaded with the
postname
or post-name
option.
\printterms
, where the
value may be one of: none or dot. This value may
also be set after the package has loaded with the postdesc
or post-desc
option.
\printterms
,
where the value may be none, enspace,
space, dotfill or hfill. This value may
also be set after the package has loaded with the
prelocation
or pre-location
option.
\printterms
, where the
value may be one of: hide, list or first.
This value may also be set after the package has loaded with the
location
option.
\printterms
, where the
value may be one of: comma, brackets,
dot, space, nosep, semicolon,
or location. This value may also
be set after the package has loaded with the see
option.
\printterms
, where the
value may be one of: symbol, desc,
(symbol) desc, desc (symbol), symbol desc,
or desc symbol. This value may also be set after the
package has loaded with the symboldesc
or
symbol-desc
option.
8.1.2. Post-Package Options[link]
\DTLsetup
{index={style
=gloss,columns
=1}}
8.1.2.1. General[link]
\newgidx
or
\printterms
. Ideally they should be set in the preamble.
8.1.2.2. Database Creation and Display[link]
\newgidx
and
\printterms
. They may be set in the optional arguments of those
commands or set with index in \DTLsetup
.
If used in the optional argument of \newgidx
, they set the default for
that database, which can then be overridden by the optional argument
of \printterms
, if necessary. Any options not explicitly set in
\newgidx
will use the current setting.
columns
value is greater than 1, balance columns.
That is, the unstarred multicols environment (provided by the
multicol package) will be used.
If balance
=false, then \twocolumn
will be used
if columns
=2 or, if more than two columns, the multicols*
environment will be used. The balance
option has no
effect with columns
=1.
post-heading
.
sort
code.
show-groups
.
\printterms
. The default is:
The \DTLsortdata
[ save-group-key
=LetterGroup ]
{\DTLgidxCurrentdb
}
{HierSort={replacements
={Sort}},FirstId}
option is
needed to support letter groups. If you omit it from save-group-key
=LetterGroup\DTLsortdata
(or if you use \dtlsort
instead) then no letter group information will be
available. See §8.10 for the list of
column keys, which may be referenced in \DTLsortdata
.
\printterms
(see §8.8.2).
8.1.2.3. Display Only[link]
\printterms
. They can’t be
passed in the optional argument of \newgidx
. If not provided in
\printterms
, the current settings will be used.
\DTLgidxChildCountLabel
, not the child’s name).
This setting may also be passed as a package option.
\Children
(which will be the
order of definition).
child-sort
.
balance
setting, except where both
columns
=2 and balance
=false, in which
case \twocolumn
will be used.
This setting may also be passed as a package option.
columns
setting is used as a package option or
within the index setting, it’s equivalent to setting the
number of columns with \DTLgidxSetColumns
. If passed as an
option to \printterms
the effect is localised.
\ifthenelse
(see
§2.4.2). Note that
condition
={ is equivalent to:
}include-if
={\ifthenelse
{ }{#1}{}}
\DTLgidxSetDefaultDB
. If passed as an option to
\printterms
the effect is localised. If no default has been
set, \newgidx
will automatically set
the default to its argument. So if you only have one
database, there is no need to explicitly set the default.
\loadgidx
, then the default database will automatically be set to
\dtllastloadeddb
.
condition
option, this defines the
filter command used by \printterms
to , which
should expand to its sole argument (#1
) if the given row of data should be
included in the list and do nothing otherwise. This may be used as
an alternative to include-if-fn
or condition
.
condition
option, this
sets the filter command, which should take one argument, to the
given . The definition of should
expand to its argument if the given row of data should be included
in \printterms
and do nothing otherwise.
\datagidxlocationwidth
dimension.
location-width
.
\xmakefirstuc
),
or capitalise (capitalise each word with
\xcapitalisewords
). See the mfirstuc documentation for
further details of the last two. This setting redefines
\DTLgidxNameCase
to use the applicable command.
name-case
.
This setting (but not name-case
) may also be passed as a package option.
\DTLgidxNameFont
:
\renewcommand
*{\DTLgidxNameFont
}[1]{{ {#1}}}
name-font
.
This setting (but not name-font
) may also be passed as a package option.
\DTLgidxPostName
to the given .
post-name
.
This setting (but not post-name
) may also be passed as a package option.
\DTLgidxPostDescription
according to the given value.
post-desc
.
This setting (but not post-desc
) may also be passed as a package option.
\enspace
),
space (a normal space), dotfill (dotted leader,
created with \dotfill
), hfill (filled space, created
with \hfill
). This setting redefines \DTLgidxPreLocation
according to its value.
pre-location
.
This setting (but not pre-location
) may also be passed as a package option.
pre-location
content followed by the
cross-reference), or
nosep (insert the
cross-reference without any leading punctuation or space).
In all cases, the cross-reference is obtained with:
\DTLgidxFormatSee
{\seename
}{\See
}
symbol
: symbol only;
desc
: description only;
(symbol) desc
: the symbol in parentheses followed by the
description;
desc (symbol)
: the description followed by the symbol in parentheses;
symbol desc
: the symbol followed by the
description;
desc symbol
: the description followed by the symbol.
symbol-desc
.
This setting (but not symbol-desc
) may also be passed as a package option.
\datagidxsymbolwidth
dimension.
symbol-width
.
8.2. Defining Index/Glossary Databases[link]
\printterms
.
For example:
The optional argument is a = list of options, which may be
any of those described in §8.1.2.2.
\newgidx
{index}{Index of Terms}
\newgidx
{abbr}{Abbreviations}
\DTLnewdb
as it also adds a line to the cataloguing database with the provided
and all applicable settings (see
§8.10 for further details).
It also takes into account the optimize setting (see
§8.8.3.1).
\newgidx
will automatically set the default to (so you won’t
need to specify database
in \printterms
if you only
have one database). Note that this isn’t the same as the
datatool default-name setting.
8.3. Loading Data Created by datatooltk[link]
\newgidx
, described in
§8.2. This command automatically sets the
default database to the loaded database. You can change the default
database using \DTLgidxSetDefaultDB
or with the database
setting.
\loadgidx
is intended for use with presorted databases,
this implements sort
={} which means that
\printterms
won’t sort the database.
8.4. Defining Terms[link]
\printterms
. The optional argument is a
= list of options, described below.
(See §8.6 if you want additional fields
with associated options.)
\newterm
will write a confirmation line in the transcript. This may be used
to double-check the default values for the label,
database and sort settings.
\useentry
and \gls
. If
hyperlinks are required, the label is also used to construct the
anchor. If a label is not provided in the optional argument, the
label will be created as described in §8.4.2.
\gls
. If omitted, the
is used.
\glspl
. If omitted, the
plural is constructed by appending “s” to the text
value.
\glssym
. It may also be shown
in \printterms
, depending on the symbol-desc
setting.
\printterms
, if
applicable.
\printterms
, the label of the cross-reference term should be
set with the see option. The value may also be a
comma-separated list of cross-referenced labels.
\printterms
, the label of the cross-reference term should be
set with the seealso option. The value may also be a
comma-separated list of cross-referenced labels.
sort
code at the start of
\printterms
. If you change the \printterms
sort
code, use Sort as the column key to reference this value.
However, if you have child entries, you may prefer to sort by the
HierSort column first with the Sort column as the
replacement.
\datatoolctrlboundary
\datatoolasciistart
\newacro
, which
internally uses \newterm
. Whilst they can be explicitly used
in \newterm
, \newacro
is a convenient wrapper that will
encapsulate the short and long forms in the provided abbreviation
style commands. See §8.7 for further details.
8.4.1. Markup Commands for Terms[link]
This is equivalent to:
\newterm
{%
\DTLgidxOffice
{bishop \DTLgidxParticle
{of}{Bayeux}}% office
{\DTLgidxName
{Henry}\DTLgidxParticle
{de}{Beaumont}}% name
}
\newterm
[
label={deBeaumont},
sort={Beaumont.\datatoolpersoncomma
Henry\datatoolpersoncomma
bishop Bayeux.}
]{%
\DTLgidxOffice
{bishop \DTLgidxParticle
{of}{Bayeux}}% office
{\DTLgidxName
{Henry}\DTLgidxParticle
{de}{Beaumont}}% name
}
\printterms
and also in the construction of the
default label and sort values. For
example:
This is essentially like:
\newterm
{\DTLgidxName
{John}{Smith}}
\newterm
[
label={Smith},
sort={Smith\datatoolpersoncomma
John},
text={John Smith}
]{Smith, John}
This is essentially like:
\newterm
{James~
\DTLgidxNameNum
{6}}
\newterm
[
label={James VI},
sort={James 06},
text={James~
VI}
]{James~
VI}
\printterms
and also in the construction of the default
label and sort values.
For example:
This is essentially like:
\newterm
{\DTLgidxPlace
{USA}{New York}}
\newterm
[
label={New York USA},
sort={New York\datatoolplacecomma
USA},
text={New York}
]{New York, USA}
\printterms
and also in the construction of the default
label and sort values.
For example:
This is equivalent to:
\newterm
{\DTLgidxSubject
{population}{New York}}
which is essentially like:
\newterm
[
label={New York population},
sort={New York\datatoolsubjectcomma
population}
]{\DTLgidxSubject
{population}{New York}}
In this case, this leads to a long label, so you may prefer to set
a shorter label explicitly. If you redefine \newterm
[
label={New York population},
sort={New York\datatoolsubjectcomma
population},
text={New York}
]{New York, population}
\DTLgidxSubject
, it
will only affect how the text appears in the main body of the
document, not within \printterms
.
, but it expands differently within
( )
\printterms
and also in the construction of the default
label and sort values. For example:
This is equivalent to:
\newterm
{\DTLgidxOffice
{Rollo}{ruler of Normandy}}
which is essentially like:
\newterm
[
label={ruler of Normandy},
sort={ruler of Normandy\datatoolpersoncomma
Rollo}
]{\DTLgidxOffice
{Rollo}{ruler of Normandy}}
If you redefine \newterm
[
label={ruler of Normandy},
sort={ruler of Normandy\datatoolpersoncomma
Rollo},
text={Rollo (ruler of Normandy)}
]{ruler of Normandy, Rollo}
\DTLgidxOffice
, it
will only affect how the text appears in the main body of the
document, not within \printterms
.
,
but it expands differently within the construction of the default
label and sort values.
For example:
~
This is equivalent to:
\newterm
{\DTLgidxRank
{Sir}{John}}
Note that this doesn’t have a different definition within
\newterm
[
label={Sir John},
sort={John.}
]{\DTLgidxRank
{Sir}{John}}
\printterms
.
,
but it expands differently within the construction of the default
label and sort values.
For example:
~
This is equivalent to:
\newterm
{\DTLgidxParticle
{de}{Winter}}
Note that this doesn’t have a different definition within
\newterm
[
label={deWinter},
sort={Winter.}
]{\DTLgidxParticle
{de}{Winter}}
\printterms
.
This is equivalent to:
\newterm
{\DTLgidxMac
{Mc}Coy}
\newterm
[
label={McCoy},
sort={MacCoy}
]{\DTLgidxMac
{Mc}Coy}
This is equivalent to:
\newterm
{\DTLgidxSaint
{St}~
James}
\newterm
[
label={St James},
sort={Saint James}
]{\DTLgidxSaint
{St}~
James}
This is equivalent to:
\newterm
{0\DTLgidxParen
{zero}}
\newterm
[
label={0},
sort={0\datatoolparenstart
zero}
]{0\DTLgidxParen
{zero}}
This is equivalent to:
\newterm
{de\DTLgidxIgnore
{-}escalate}
Note that in this case, the letter sort handler \newterm
[
label={de-escalate},
sort={deescalate},
]{de\DTLgidxIgnore
{-}escalate}
\DTLsortletterhandler
can be used to strip hyphens.
\cs_to_str:N
.
8.4.2. Commands to Assist Label Creation[link]
If the name doesn’t contain any markup, as in the above example, it
can be a bit repetitive to have to explicitly set the label. To
avoid this repetition, \newterm
[label=duck]{duck}
\newterm
will create a label based on
the name if the label option isn’t set. If you want to
double-check the label value, switch on verbose mode and
\newterm
will write information, including the label, to the transcript.
If the name contains fragile
commands, either explicitly set the label value or
redefine \newterm
{duck}
\newtermlabelhook
to locally change the fragile
commands to expand to nothing or to something suitable for a label.
\glsadd
will be redefined to ignore its argument.
Various commands are redefined to \DTLgidxNoFormat
, which
simply expands to its argument. This is largely redundant now, since
the purification step will strip any non-expandable commands.
Commands such as \& are replaced via
\datagidxconvertchars
.
\DTLgidxParen
(discards its
argument), \DTLgidxName
and \DTLgidxOffice
(expands to
just the second argument), \DTLgidxPlace
and
\DTLgidxSubject
(inverted), and \DTLgidxParticle
(expands
both arguments without any separator).
\alpha
) to words (via \datagidxwordifygreek
).
8.4.3. Commands to Assist Sorting[link]
is equivalent to:
\newterm
{duck}
Some processing is performed on the name to assist the creation of a
missing sort value. If the name contains fragile
commands, either explicitly set the sort value or
redefine \newterm
[sort=duck]{duck}
\newtermsorthook
to locally change the fragile
commands to expand to nothing or to something suitable for sorting.
If you want to double-check the sort value, switch on verbose
mode and \newterm
will write information, including the sort
value, to the transcript.
\glsadd
will be redefined to ignore its argument.
Various commands are redefined to \DTLgidxNoFormat
, which
simply expands to its argument. This is largely redundant now, since
the purification step will strip any non-expandable commands.
Commands such as \& are replaced via
\datagidxconvertchars
.
and
\DTLgidxName
{ }{ }
expand to
\DTLgidxOffice
{ }{ }
;
\datatoolpersoncomma
expands to
\DTLgidxPlace
{ }{ }
;
\datatoolplacecomma
expands to
\DTLgidxSubject
{ }{ }
;
\datatoolsubjectcomma
expands to
\DTLgidxParen
{ }
;
\datatoolparenstart
expands to “Mac”,
ignoring its argument;
\DTLgidxMac
{ }
expands to “Saint”,
ignoring its argument;
\DTLgidxSaint
{ }
expands to nothing;
\DTLgidxIgnore
{ }
and
\DTLgidxRank
{ }{ }
expand to
\DTLgidxParticle
{ }{ } (that is, they ignore their first argument
and insert “ .
.
” after the second argument);
expands to its numeric argument
zero-padded to two digits.
\DTLgidxNameNum
{ }\alpha
) to words (via \datagidxwordifygreek
).
8.5. Referencing Terms[link]
\newterm
can be referenced in
the document with:
I can now reference this term in the document:
\newterm
{reptile}
or if I want the plural, I can use:
\useentry
{reptile}{Text}
There is also a sentence case command:
This makes the first letter of the field value uppercase (using the mfirstuc
package) or for all caps:
This converts all the text obtained from the field to uppercase.
\useentry
{reptile}{Plural}
\printterms
). You can
suppress this action for individual cases by using one of the
following analogous commands instead. (To suppress all hyperlinks,
use \DTLgidxDisableHyper
.)
\useentry
but with no hyperlink. If the hyperref package
hasn’t been loaded, this is equivalent to \useentry
.
\Useentry
but with no hyperlink. If the hyperref package
hasn’t been loaded, this is equivalent to \Useentry
.
\USEentry
but with no hyperlink. If the hyperref package
hasn’t been loaded, this is equivalent to \USEentry
.
\useentry
but displays the provided text instead of
the value of a field.
\printterms
).
Note that the command (\useentry
{[textbf]reptile}{Text}
\textbf
in the above example) should take
one argument (the location). If you attempt to use a
declaration (such as \bfseries
) the effect won’t be localised.
\useentry
but it doesn’t index or create a
hyperlink.
\Useentry
but it doesn’t index or create a
hyperlink.
\DTLassignfirstmatch
or select row
, to fetch
information. However, you will need to specify the database name,
which isn’t required with \DTLgidxFetchEntry
(since it uses the
label to database mapping created by \newterm
).
\useentry
, maybe in the form
[
where ]{ } is the name of a
control sequence without the leading backslash.
\glsaddall
and using \glsadd
on all entries in the database.
In the case of \glsadd
a location is added to the location list
for that entry. However in the case of \glsaddall
no location is
added to each entry’s location list, but the location list is set to
non-null so the entry will appear in the index/glossary.
8.5.1. Shortcut Commands[link]
.
\useentry
{ }{Text}
.
\useentry
{ }{Plural}
.
\useentrynl
{ }{Text}
.
\useentrynl
{ }{Plural}
.
\Useentry
{ }{Text}
.
\Useentry
{ }{Plural}
.
\Useentrynl
{ }{Text}
.
\Useentrynl
{ }{Plural}
.
\useentry
{ }{Symbol}
.
\Useentry
{ }{Symbol}8.5.2. Locations[link]
\printterms
is, by default, the page number on
which the term was referenced.
The counter used for the location is obtained by expanding:
counter
option redefines \DTLgidxCounter
to the given
value (with a check to determine that the supplied name is valid).
record-nameref
package option and bib2gls.
\printterms
using
\DTLgidxLocation
(which is modified by the location
option). The entire content of the Location
field is encapsulated with the special marker \dtlspecialvalue
.
compositor
option or with:
8.6. Adding Extra Fields[link]
\newterm
.
This can be done with:
\newgidx
will be iterated over.
\DTLgidxAssignList
. If is
omitted, it will be formed from the column key. Note that the
command must not already be defined.
\newterm
(or \newacro
) to set the new field,
and is the default value to use if the new
option isn’t provided. Note that this will only affect subsequent
instances of \newterm
or \newacro
.
\newterm
option name (not the
database column key).
This adds a new column with the label AltPlural to each
defined index/glossary database and adds a new key called
altplural that I can now use in the optional argument of \newtermaddfield
{AltPlural}{altplural}{}
\newterm
.
The default is set to empty. Now I can define terms with an alternative plural:
In the document, I can use \newterm
[altplural=kine]{cow}
to display
“cow”,
\gls
{cow}
to display “cows” and
\glspl
{cow}
to display “kine”. To make life a
little easier, I can define a new command to save typing:
\useentry
{cow}{AltPlural}
Now I can just do \newcommand
*{\glsaltpl
}[1]{\useentry
{#1}{AltPlural}}
\glsaltpl{cow}
to display “kine”.
This adds a new column labelled Ed and defines a new key called
ed that can be used with \newtermaddfield
{Ed}{ed}{\field
{text}ed}
\newterm
. Now I can define some
verbs:
\newterm
{jump}
\newterm
[ed=went]{go}
This new field can now be referenced in the document:
\newcommand
*{\glsed
}[1]{\useentry
{#1}{Ed}}
He
\glsed
{jump} over the gate.
She \glsed
{go} to the shop.
8.7. Abbreviations[link]
\newterm
to define an
abbreviation:
where is converted to uppercase, and
\newterm
[
description={\capitalisewords
{ }},
short={\acronymfont
{ }},
long={,
}text={\DTLgidxAcrStyle
{ }{\acronymfont
{ }}},
plural={\DTLgidxAcrStyle
{ s}{\acronymfont
{ s}}},
sort={,
}
]
{ }
\capitalisewords
is defined in mfirstuc (which is automatically
loaded by datagidx).
\newacro
.
8.7.1. Using Abbreviations[link]
\useentry
. For example, if you define the following in the
preamble:
then later in the text you can use:
\newacro
{css}{cascading style sheet}
to access the short form and
\useentry
{css}{Short}
to access the long form. You can also use
\useentry
{css}{Long}
(or \useentry
{css}{Text}
) to access the full version. However with
abbreviations, you may prefer to have only the full form on first use and just
the short form on subsequent use. The following commands are
provided to do that. The singular form is obtained using:
This robust command does:
\gls
{css}\ifentryused
{ }{\useentry
{ }{Short}}
{\DTLgidxFormatAcr
{ }{Long}{Short}}
\ifentryused
{ }{\useentry
{ }{ShortPlural}}
{\DTLgidxFormatAcr
{ }{LongPlural}{ShortPlural}}
\acr
isn’t the
same as \gls
. With datagidx, \gls
always references
the Text value. There is no “first” field.
\acr
and \acrpl
with beamer. Using overlays can
cause problems with first use expansions.
\ifentryused
{ }{\Useentry
{ }{Short}}
{\DTLgidxFormatAcrUC
{ }{Long}{Short}}
\ifentryused
{ }{\Useentry
{ }{ShortPlural}}
{\DTLgidxFormatAcrUC
{ }{LongPlural}{ShortPlural}}
\DTLgidxAcrStyle
{\glsdispentry
{ }{ }}
{\useentry
{ }{ }}
Note that \DTLgidxAcrStyle
{\Glsdispentry
{ }{ }}
{\useentry
{ }{ }}
\DTLgidxFormatAcrUC
will need to be redefined if
\DTLgidxAcrStyle
is redefined to show the short form first.
8.7.2. Unsetting and Resetting Abbreviations[link]
\newgidx
.
8.8. Displaying the Index or Glossary[link]
\newgidx
can be displayed with:
\printterms
defines:
This will expand to the database’s name (as identified by
database
).
\printterms
.
The style is set with \datagidxsetstyle
. Note that this means
that any redefinitions of style commands made before
\printterms
will be overridden.
sort
option is used to sort the
database (which should be referenced with \DTLgidxCurrentdb
).
The special markup commands \DTLgidxName
, \DTLgidxPlace
,
\DTLgidxSubject
, and \DTLgidxOffice
are redefined to
invert their arguments (see §8.4.1).
\printterms
will then iterate over the database
using \DTLgidxForeachEntry
where the argument is simply \datagidxitem
, which is set by
the style.
\DTLgidxForeachEntry
(which
are obtained by expanding \DTLgidxAssignList
) may be referenced in the
condition
option or the include-if
or
include-if-fn
definitions to filter rows from the database.
However, note that \DTLgidxForeachEntry
automatically filters
out any row that has a non-null \Parent
regardless of the
condition. Other rows will also be automatically filtered if they
have null Location, See and SeeAlso
fields (that is, the term hasn’t been indexed).
sort
code, which uses
save-group-key
=LetterGroup to obtain and save the
letter group. If the sort
code is changed to omit this
option then \datagidxcurrentgroup
will be null (see
§3.10 for information about null values).
show-groups
(or showgroups
) setting is on,
\datagidxcurrentgroup
will be expanded at the start of each
iteration and, at the end of the iteration (after ),
the expanded value will be saved in \datagidxprevgroup
.
\datagidxcurrentgroup
with \datagidxprevgroup
to determine if the letter group has
changed. If the values have changed, a
letter group heading can be inserted where the group title is obtained with:
\datagidx
, if it exists,
or simply name otherwise.
\printterms
does:
This will format each entry that both satisfies \DTLgidxForeachEntry
{\datagidxitem
}
condition
(or include-if
or include-if-fn
) and
has a null \Parent
according to the current style.
It’s up to the style to determine whether or not to display the
child entries along with their parent entry. (The list of child
labels can be obtained by expanding \Children
).
\printterms
does \datagidxend
, which is again
defined by the style and should close any groups that were opened
with \datagidxstart
. If \twocolumn
was issued by a
combination of columns
=2 and
balance
=false, and two-column mode wasn’t already in
effect before \printterms
, then one column mode will be
restored with:
\onecolumn
.
8.8.1. Hooks and Associated Commands[link]
child
or post-name
.
columns
option uses this command. The value must be
greater than 0.
\Name
placeholder, and is
intended for case change. If redefined, it should take into account
that its argument will be a command not the actual text. The
name-case
option redefines \DTLgidxNameCase
to use
the applicable command. The default definition simply expands to its
argument (that is, not case-change is applied).
and is used to
apply a font change. The \DTLgidxNameCase
{\Name
}name-font
option redefines
\DTLgidxNameFont
. The default definition is to use
\textnormal
.
\datagidxtarget
, which will create a
hyper-target, if supported. After that will be the post-name hook.
\Parent
. The post-name
option
redefines \DTLgidxPostName
.
\Parent
). The default definition is simply \DTLgidxPostName
.
\DTLgidxNameFont
and
\DTLgidxNameCase
) and post-name hook
(\DTLgidxPostChildName
). The default definition simply expands
to its argument. The child
=noname setting redefines
\DTLgidxChildStyle
to ignore its argument and expand to
\DTLgidxChildCountLabel
. The child
=noname setting redefines
\DTLgidxChildStyle
to expand to its argument (that is, back to
its original definition).
(that is,
the value of the child counter, followed by a closing parenthesis
and space).
\theDTLgidxChildCount
)␣symbol-desc
setting.
\Description
placeholder.
\par \smallskip
(which creates a paragraph break
and a small vertical gap).
location
setting. The location
=hide setting
will omit the location list and the pre and post location hooks.
pre-location
setting redefines this command.
\See
placeholder.
\DTLgidxFormatSee
but a pre hook before
the tag and a post hook after the list, which are determined by the
style.
\DTLgidxFormatSee
and \DTLgidxFormatSeeAlso
.
By default, this uses \emph
.
\DTLgidxFormatSee
, this command is defined
by language packages, such as babel, but will be provided by
datagidx if not already defined.
\alsoname
, if that command exists, or to “see
also” otherwise.
symbol-width
option, but
may also be changed with \setlength
. If zero or negative, the
symbol will just occupy its natural space, otherwise the styles that
support this setting will allocate this width for the location list.
location-width
option, but
may also be changed with \setlength
. If zero or negative, the
location list will just occupy its natural space, otherwise the
styles that support this setting will allocate this width for the location
list.
8.8.2. Index or Glossary Styles[link]
\printterms
is specified with the style
option.
The default is style
=index.
8.8.2.1. index[link]
symbol-width
and location-width
settings.
8.8.2.2. indexalign[link]
8.8.2.3. align[link]
symbol-width
and location-width
settings,
but will require an initial iteration over the
database to calculate the alignment.
8.8.2.4. gloss[link]
8.8.2.5. dict[link]
show-groups
=true, the group headers will be
inserted with \DTLgidxDictHead
.
\renewcommand
.
\chapter
if it has
been defined or \section
otherwise. The title is obtained
with \DTLgidxGroupHeaderTitle
.
8.8.3. Sorting the Index or Glossary Database[link]
\printterms
will automatically sort
the database according to the sort
option. The default
code is:
This sorts by the HierSort column first. If the value isn’t
set, the value from the Sort column will be used.
In the event that two rows being compared have identical sort
values, the FirstId column will be compared.
Note that \DTLsortdata
[save-group-key
=LetterGroup]
{\DTLgidxCurrentdb
}% current database
{HierSort={replacements
=Sort},FirstId}
\DTLgidxCurrentdb
is used to identify the database.
sort
code was:
Note that this is less efficient than using the newer
\dtlsort
{Sort,FirstId}{\DTLgidxCurrentdb
}{\dtlwordindexcompare
}
\DTLsortdata
and there was no HierSort column.
However, if you want to revert back to this behaviour without using
rollback, you can do:
\printterms
[sort
=
\dtlsort
{Sort,FirstId}{\DTLgidxCurrentdb
}{\dtlwordindexcompare
}
]
sort
to an
empty value:
\printterms
[sort
=]
8.8.3.1. Optimization[link]
sort
=key to empty.
\printterms
sort
=key, rather than
by explicitly sorting the database with commands like
\DTLsortdata
somewhere else in the document.
\printterms
sort
=key. Don’t use this option if you
want to edit the index/glossary database.
8.9. Supplementary Commands[link]
\datagidxtarget
and \datagidxlink
back to their
default behaviour, which tests for the existence of \hypertarget
and \hyperlink
.
\datagidxtarget
and \datagidxlink
to simply expand to their
argument.
8.9.1. Conditionals and Loops[link]
\DTLgidxCurrentdb
) using \DTLmapdata
with
read-only
=true. This command is primarily provided for use
within \printterms
. If you want to use it explicitly, make sure
that \DTLgidxCurrentdb
expands to the required database name.
condition
or include-if
or include-if-fn
setting is true.
\Label
will be added
to a global list of referenced labels, which is used at the end of the
document to check if a rerun is required.
\datagidxcurrentgroup
with \datagidxprevgroup
to determine if the letter group has
changed.
[breakable]
If new fields are added with \Name
=Name,
\Description
=Description,
\Used
=Used,
\Symbol
=Symbol,
\Long
=Long,
\Short
=Short,
\LongPlural
=LongPlural,
\ShortPlural
=ShortPlural,
\Location
=Location,
\See
=See,
\SeeAlso
=SeeAlso,
\Text
=Text,
\Plural
=Plural,
\CurrentLocation
=CurrentLocation,
\Label
=Label,
\Parent
=Parent,
\Children
=Child,
\FirstId
=FirstId,
\HierSort
=HierSort,
\Sort
=Sort,
\datagidxcurrentgroup
=LetterGroup
\newtermaddfield
, the supplied
placeholder command will be added to the assignment list. If you
manually add columns, using commands like \DTLaddcolumn
, you
can append your own custom placeholders to this list if they need to
be referenced.
\DTLgidxAssignList
so that it omits the essential
placeholder commands referenced by \printterms
and its
underlying hooks, errors will occur.
\DTLgidxForeachEntry
but is provided
for use by the styles to iterate over all entries in the current
database (typically to calculate the width of certain field values).
Unlike \DTLgidxForeachEntry
, the letter group
commands aren’t updated and the list of referenced labels isn’t
updated.
8.9.2. New Terms[link]
\newterm
:
\newterm
will define:
to expand to the term’s label. This may be used to reference the
term within the hook.
\newterm
automatically generates the
label and
sort values (if omitted, see
§§8.4.2 & 8.4.3) certain commands are
locally set to:
\@firstofone
).
This simply expands to nothing (equivalent to
\@gobble
).
\alpha
:
8.9.3. Styles[link]
\printterms
to set the current style,
which means that any redefinitions of the style commands listed
below will be overridden. If you want to make any adjustments to
these commands, you will need to define a new style.
This defines a new style called . The
argument may start with
if
only minor modifications to an existing style ( ) are required.
\datagidxsetstyle
{ }\Label
placeholder. This
will generate a hypertarget with the label as the
target name, if supported, and display .
\datagidxtarget
and
\datagidxlink
to insert a prefix.
child
=noname setting redefines \DTLgidxChildStyle
to use \DTLgidxChildCountLabel
, ignoring its argument.
8.10. Database Structures[link]
8.10.1. The Catalogue Database[link]
\newgidx
along with their particular
settings. The datagidx database has the following column
keys:
\newgidx
);
\printterms
(the argument
of \newgidx
);
\printterms
(which can be set with the heading
option);
\printterms
(which can be set with the
post-heading
option);
\printterms
for multiple columns
(balance
=true sets this value to multicols*
and balance
=false sets this value to
multicols);
\printterms
should use to sort the data before displaying it
(which can be set with the sort
option);
\printterms
should use to displaying the data
(which can be set with the style
option);
show-groups
setting (that is, true or
false).
8.10.2. The Term Databases[link]
\newgidx
contains each defined term
or abbreviation associated with that database. The column keys used
to store the information are
listed below. The placeholder commands used in the column value assignments
in the expansion text of the default definition of \DTLgidxAssignList
are shown in parentheses.
The following columns are primarily intended for use in
\Label
): the unique label that
identifies the entry;
\Text
): the entry’s text for use by
commands like \gls
;
\Plural
): the entry’s plural text
for use by commands like \glspl
;
\Symbol
): the entry’s symbol for use by
commands like \glssym
, if applicable;
\Short
): the entry’s short
(abbreviated) form for use by commands like \acr
, if applicable;
\ShortPlural
): the entry’s short
plural form for use by commands like \acrpl
, if applicable;
\Long
): the entry’s long form for use by
commands like \acr
, if applicable;
\LongPlural
): the entry’s long
plural form for use by commands like \acrpl
, if applicable;
\printterms
:
The following are considered internal fields, but may be referenced
in the sorting or filtering code.
\Name
): the entry’s name, as it
should appear in \printterms
;
\Description
): the entry’s
description, as it should appear in \printterms
,
if applicable;
\See
): the entry’s “see” cross-reference,
if applicable;
\SeeAlso
): the entry’s “see also” cross-reference,
if applicable;
\Parent
): the entry’s parent label,
if applicable;
\Children
): a comma-separated list of
child labels, which is updated whenever a new entry is defined
identifying this entry as its parent;
\Location
): the location list
obtained from the previous run;
\datagidxcurrentgroup
): the entry’s
letter group, as obtained by \DTLsortdata
with the default
sort
setting.
\Sort
): the entry’s sort value (which
normally defaults to the name but may be explicitly set with the
sort option);
\HierSort
): the entry’s
hierarchical sort value, if applicable, which is obtained from the sort value
appended the parent’s hierarchical sort value;
\FirstId
): a numeric value
corresponding to the first reference (indexing) of the term, so sorting by this
column will normally result in an order of use listing;
\Used
): a column that will contain
either 0 (unused) or 1 (used) marked up as a special value (see
§3.11) to indicate whether or not the entry
has been used in the current run.
\CurrentLocation
): the location list
obtained from the current run, which may be one off due to the
delayed output routine;
\DTLgidxAssignList
as it’s only used to
check if the location list has changed from the previous run to
determine whether or not to issue a rerun warning.
8.11. Examples[link]
The hyperref package is also used:
\usepackage
[locales=en]{datagidx}
The database is created and populated in the preamble:
\usepackage
[colorlinks]{hyperref}
The document text consists of:
\newgidx
{index}Index% define a database for the index
\DTLgidxSetDefaultDB
{index}% set this as the default
\newterm
{macédoine}
\newterm
{macramé}
\newterm
{élite}
\newterm
{reptile}
\newterm
[seealso=reptile]crocodylian
\newterm
[parent=crocodylian]crocodile
\newterm
[parent=crocodylian]alligator
\newterm
[
parent=crocodylian,
description={(also cayman)}
]
caiman
\newterm
[see=caiman]cayman
Here are some words containing accents:
The index is displayed with:
\gls
{macédoine},
\gls
{macramé} and \gls
{élite}. \Gls
{élite} starts with an uppercase
letter. A \gls
{crocodylian} is the family of
\glspl
{reptile} that includes \glspl
{crocodile}, \glspl
{alligator}
and \glspl
{caiman}.
\printterms
[
heading
={\section
*},
database
=index,
prelocation
=dotfill,
showgroups
]
The database is created and populated in the preamble:
\usepackage
{datagidx}
\usepackage
[colorlinks]{hyperref}
The following overrides the default description:
\newgidx
{abbreviations}Abbreviations
\DTLgidxSetDefaultDB
{abbreviations}
\newacro
{html}{hyper-text markup language}
\newacro
{css}{cascading style sheet}
The document text is:
\newacro
[description={eXtensible Markup Language}]
{xml}{extensible markup language}
First use:
The list of abbreviations is displayed with:
\acr
{xml} and \acr
{css}.
Next use: \acr
{xml} and \acr
{css}.
Full form: \gls
{xml} and \gls
{css}.
\printterms
[
postdesc
=dot,% put a full stop after the description
columns
=1,% one column page layout
namefont
={\textbf
},% put the name (i.e. the abbreviation) in bold
namecase
=uc,% make the name upper case
style
=align% use the 'align' style
]
9. Referencing People (person package)[link]
\foreachperson
, no longer use \@for
. This will only make a
difference if you have used the xfor commands to break the
loop.
\malelabels
and \femalelabels
. They have been replaced
with comma-separated list variables. Use \PersonSetMaleLabels
and \PersonSetFemaleLabels
to replace the lists if required.
Note that if datatool hasn’t already been loaded, this will
also apply rollback to datatool. Problems may occur if a newer
release of datatool has already been loaded.
\usepackage
{person}[=2.32]
\usepackage
[locales=en-GB]{person}
9.1. Package Options[link]
\DTLsetup
.
\DTLsetup
:
\DTLsetup
{person={shortcuts}}
9.2. Other Options[link]
\DTLsetup
. For example:
\DTLsetup
{person={global}}
\newperson
have a local effect.
9.3. Defining and Undefining People[link]
See the descriptions of the fullname, name
and gender options for further details.
\newperson*
[ ]{
expand-fullname={,
}expand-name={,
}gender={
}
}\personname
so with the local setting on, this is
useful in a scoped context to create a temporary person without the
need to assign a new label.
\newperson
.
There are no required settings. If all are omitted, then the person
will have an empty name and unknown gender.
\persontitlesurnamesep
and then the title, otherwise the full name will be set to just the
surname.
\datatool_if_null_or_empty:nTF
. If it’s null, unknown will
be assumed, otherwise will be fully expanded
and tested against the recognised gender labels (see
§9.4). If is omitted or
expands to empty, unknown will be assumed.
9.4. Genders[link]
\newperson
or
for the gender option in \newperson*
(regardless
of whether or not it is included in the allowed list of alternative
male labels).
\newperson
, may be provided as a comma-separated list in the
argument of:
\PersonAddMaleLabel
This will expand the label before adding it to the internal list.
Both commands have a global effect, regardless of the
local setting.
\addmalelabel
is now
deprecated and will do \PersonAddMaleLabel
. The older command
\malelabels
which stored the list has been replaced
with \g_person_male_label_clist
. If you have a pre-v3.0
document that redefined \malelabels
, replace the redefinition
with \PersonSetMaleLabels
.
\newperson
or
for the gender option in \newperson*
(regardless
of whether or not it is included in the allowed list of alternative
female labels).
\newperson
, may be provided as a comma-separated list in the
argument of:
\PersonAddFemaleLabel
This will expand the label before adding it to the internal list.
Both commands have a global effect, regardless of the
local setting.
\addfemalelabel
is now
deprecated and will do \PersonAddFemaleLabel
. The older command
\femalelabels
which stored the list has been replaced
with \g_person_female_label_clist
. If you have a pre-v3.0
document that redefined \femalelabels
, replace the redefinition
with \PersonSetFemaleLabels
.
\newperson
or
for the gender option in \newperson*
(regardless
of whether or not it is included in the allowed list of alternative
non-binary labels).
\newperson
, may be provided as a comma-separated list in the
argument of:
\PersonAddNonBinaryLabel
This will expand the label before adding it to the internal list.
Both commands have a global effect, regardless of the
local setting.
\newperson
, the
gender label may be set to unknown or empty. There are no
alternative labels as this category is provided for instances where
the information isn’t provided.
\ifmalelabel
.)
\iffemalelabel
.)
9.5. Displaying Information[link]
\person
show the
applicable language-sensitive text according to the gender of the
person identified by the label. If the label is omitted,
anon is assumed. The commands that start with
\Person
are the sentence case equivalents.
\people
show the plural form
according to the gender of the group of all defined people. If all
people were defined with the same gender, then the plural form for
that gender is used, otherwise the plural form for the unknown
gender will be used. If only one person has been defined, then
resulting text will be equivalent to the analogous \person
command. The commands that start with
\People
are the sentence case equivalents.
\PersonSetLocalisation
. For example:
\PersonSetLocalisation
{unknown}{pronoun2}{thou}
\PersonSetLocalisation
{unknown}{objpronoun2}{thee}
\PersonSetLocalisation
{unknown}{possadj2}{thy}
\PersonSetLocalisation
{unknown}{posspronoun2}{thine}
9.5.0.1. Grammar[link]
Shortcut Command
Equivalent Command
\they
\peoplepronoun
\They
\Peoplepronoun
\them
\peopleobjpronoun
\Them
\Peopleobjpronoun
\their
\peoplepossadj
\Their
\Peoplepossadj
\theirs
\peopleposspronoun
\Theirs
\Peopleposspronoun
\you
\peoplepronounii
\You
\Peoplepronounii
\thee
\peopleobjpronounii
\Thee
\Peopleobjpronounii
\your
\peoplepossadjii
\Your
\Peoplepossadjii
\yours
\peopleposspronounii
\Yours
\Peopleposspronounii
\children
\peoplechild
\Children
\Peoplechild
\parents
\peopleparent
\Parents
\Peopleparent
\siblings
\peoplesibling
\Siblings
\Peoplesibling
\newperson*
{name=Zoë,gender=female}
\personpronoun
\
sees the duck
\personpronoun
but starts with a capital.
\personpronoun
.
With the shortcuts option, you can use \they
instead.
\peoplepronoun
but starts with a capital.
With the shortcuts option, you can use \They
instead.
\personpronounii
but starts with a capital.
\personpronounii
.
With the shortcuts option, you can use \you
instead.
\peoplepronounii
but starts with a capital.
With the shortcuts option, you can use \You
instead.
\newperson*
{name=Zoë,gender=female}
the duck sees \personobjpronoun
\personobjpronoun
but starts with a capital.
\personobjpronoun
.
With the shortcuts option, you can use \them
instead.
\peopleobjpronoun
but starts with a capital.
With the shortcuts option, you can use \Them
instead.
\personobjpronounii
but starts with a capital.
\personobjpronounii
.
With the shortcuts option, you can use \thee
instead (as opposed to \you
for the subjective pronoun).
\peopleobjpronounii
but starts with a capital.
With the shortcuts option, you can use \Thee
instead (as opposed to \You
for the subjective pronoun).
\newperson*
{name=Zoë,gender=female}
\personpossadj
\
book
\personpossadj
but starts with a capital.
\personpossadj
.
In English, there’s no difference between singular and plural
possessive adjectives.
With the shortcuts option, you can use \their
instead.
\peoplepossadj
but starts with a capital.
With the shortcuts option, you can use \Their
instead.
\personpossadjii
but starts with a capital.
\personpossadjii
.
In English, there’s no difference between singular and plural
possessive adjectives.
With the shortcuts option, you can use \your
instead.
\peoplepossadjii
but starts with a capital.
With the shortcuts option, you can use \Your
instead.
\newperson*
{name=Zoë,gender=female}
the book is \personposspronoun
\personposspronoun
but starts with a capital.
\personposspronoun
.
With the shortcuts option, you can use \theirs
instead.
\peopleposspronoun
but starts with a capital.
With the shortcuts option, you can use \Theirs
instead.
\personposspronounii
but starts with a capital.
\personposspronounii
.
With the shortcuts option, you can use \yours
instead.
\peopleposspronounii
but starts with a capital.
With the shortcuts option, you can use \Yours
instead.
9.5.0.2. Relationships[link]
\personchild
but starts with a capital.
\personchild
.
With the shortcuts option, you can use \children
instead.
\peoplechild
but starts with a capital.
With the shortcuts option, you can use \Children
instead.
\personparent
but starts with a capital.
\personparent
.
With the shortcuts option, you can use \parents
instead.
\peopleparent
but starts with a capital.
With the shortcuts option, you can use \Parents
instead.
\personsibling
but starts with a capital.
\personsibling
.
With the shortcuts option, you can use \siblings
instead.
\peoplesibling
but starts with a capital.
With the shortcuts option, you can use \Siblings
instead.
9.5.1. Accessing Individual Information[link]
\peoplefullname
if you want a list of all
defined people showing their full name.
\peoplename
if you want a list of all
defined people showing their name.
\peopleforenames
if you want a list of all
defined people showing their forenames.
\peoplesurname
if you want a list of all
defined people showing their surname.
\peopletitlesurname
if you want a list of all
defined people showing their title and surname.
9.5.2. List People[link]
\DTLlistformatlastsep
.
Inserted between the final pair when the list contains more that two
elements. This is defined to:
Inserted between people for all but the last pair. This is simply defined
to \DTLlistformatoxford
\DTLlistformatlastsep
\DTLlistformatsep
.
\personfullname
for an individual.
\personname
for an individual.
\personforenames
for an individual.
\personsurname
for an individual.
\persontitlesurname
for an individual.
9.6. Examples[link]
9.6.1. Mail Merging[link]
The shortcuts option is used to provide the simpler
shortcut commands:
\documentclass
{letter}
The data is iterated over using \usepackage
[shortcuts]{person}
\DTLmapdata
. I’ve used a
mixture of \DTLmapgetvalues
and \DTLmapget
. You may prefer
to get the parent, score and award values within \DTLmapgetvalues
along
with the other values.
The \begin{DTLenvmapdata}
\begin{letter}
{}
\DTLmapgetvalues
{
\Forename
=forename, \Surname
=surname, \Gender
=gender
}
\newperson*
{
expand-once-name=\Forename
,
expand-once-surname=\Surname
,
gender=\Gender
}
\opening
{Dear \DTLmapget
{key
=parent}}
Your \personchild
\␣\personfullname
\␣
received a score of \DTLmapget
{key
=score}
and was awarded a scholarship of
\DTLmapget
{key
=award}. We look forward to seeing
\them
\␣on \their
\␣arrival.
\closing
{Yours Sincerely}
\end{letter}
\end{DTLenvmapdata}
\personfullname
command can be replaced with
\Forename\␣\Surname
. The advantage of
the person package is that the gender-dependent text can more
easily be produced.
\Gender
command will be null on that iteration. The
gender option will detect this and set the gender to
unknown. By way of contrast, the student Evelyn has the
gender set to one of the non-binary labels, which means that the
gender will be set to nonbinary. This doesn’t make a
noticeable difference between the two letters (aside from their
names, the names of their parents, the score and award) as the
language-sensitive text is the same in both cases.
9.6.2. Order of Service[link]
\newperson
.
Only one person is defined so the default anon label can be
used, which means there’s no need to supply the label.
\usepackage
[base-only]{person}
This is a simple document for demonstration purposes. A real
document would benefit from a custom class that provides better
styling. This is just to illustrate the person package
commands:
\newperson*
{
forenames=Mary Jane,
name=Mary,
surname=Doe,
gender=f
}
\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.
\Peoplepronoun
may be used instead of \Personpronoun
even
if only one person has been defined.
This allows the use of the plural shortcut commands, which makes the
code slightly more readable:
\usepackage
[base-only,shortcuts]{person}
\begin{center}
\Large
In Memory of \peoplefullname
\end{center}
We are gathered here to remember our \siblings
\␣\peoplename
.
\They
\␣will be much missed, and \their
\␣
family are in our prayers.
In this case, two people are defined. This means that unique labels need to be
supplied:
\usepackage
[base-only]{person}
Again, this is a simple document for demonstration purposes where
I’ve used \newperson*
[john]{
forenames=John Joseph,
name=John,
gender=male
}
\newperson*
[jane]{
forenames=Jane Mary,
name=Jane,
gender=female
}
\title
and \author
with \maketitle
to
show the title. A real
document would benefit from a custom class that provides better
styling. This is just to illustrate the person package
commands:
Note that \␣ (backslash space) is required after
\title
Baptism of
\author
\peopleforenames
\maketitle
Today we welcome \peoplename
\␣into God's family, may He guide
and protect \peopleobjpronoun
.
\peoplename
to force a space.
and
=symbol to switch.
The datetime2 package also uses tracklang for its
localisation support. This means that if it’s loaded as well, and
datetime2-english is also installed, then it can also pick
up the localisation but beware of the ordering.
\usepackage
[
base-only, % no datatool.sty
locales=en-GB, % (requires datatool-english)
shortcuts
]{person}
or load person first with regional support:
\usepackage
[en-GB]{datetime2}
\usepackage
[
base-only, % no datatool.sty
shortcuts
]{person}
Alternatively:
\usepackage
[
base-only, % no datatool.sty
locales=en-GB, % (requires datatool-english)
shortcuts
]{person}
\usepackage
[useregional]{datetime2}
Or:
\documentclass
[en-GB]{article}
\usepackage
[useregional]{datetime2}
\usepackage
[
base-only, % no datatool.sty
shortcuts
]{person}
\documentclass
{article}
\usepackage
[british]{babel}
\usepackage
[useregional]{datetime2}
\usepackage
[
base-only, % no datatool.sty
shortcuts
]{person}
Today we welcome
\peoplename
into God's family, may He guide
and protect \them
.
9.7. Advanced Commands[link]
\newperson
:
\person_remove_appto:n
code.
9.7.1. Conditionals[link]
\PersonTotalCount
with
\PersonMaleCount
.
\PersonTotalCount
with
\PersonFemaleCount
.
\PersonTotalCount
with
\PersonNonBinaryCount
.
\PersonTotalCount
with
\PersonUnknownGenderCount
.
\tl_if_eq:NNTF
) against the constants
\c_person_male_label_tl
, \c_person_female_label_tl
,
\c_person_nonbinary_label_tl
, and \c_person_unknown_label_tl
and does the applicable case or if no match.
\person_gender_case:Nnnnnn
. The invalid case
triggers an error and does the same as the unknown case.
\PersonTotalCount
with
\PersonMaleCount
, \PersonFemaleCount
and
\PersonNonBinaryCount
.
9.7.2. Iterating Through Defined People[link]
\@for
. This means that you
can no longer break out of the loop using the methods provided by
xfor. Instead you can break the loop with:
\seq_break:
or \clist_break:
depending on the context.
is optional. If omitted
the list of all defined people is assumed.
\in
{ }9.7.3. Localisation[link]
\DTLsetLocaleOptions
.
The argument is essentially a property name where the
plural alternative is as the singular but prefixed with
“plural”.
\PersonSetLocalisation
{male}{pronoun}{he}
\PersonSetLocalisation
{female}{pronoun}{she}
\PersonSetLocalisation
{nonbinary}{pronoun}{they}
\PersonSetLocalisation
{unknown}{pronoun}{they}
\PersonSetLocalisation
{male}{pluralpronoun}{they}
\PersonSetLocalisation
{female}{pluralpronoun}{they}
\PersonSetLocalisation
{nonbinary}{pluralpronoun}{they}
\PersonSetLocalisation
{unknown}{pluralpronoun}{they}
\newperson
but is used by \foreachperson
,
\getpersongender
, \persongender
and \Persongender
.
\PersonSetMaleLabels
,
\PersonSetFemaleLabels
and \PersonSetNonBinaryLabels
to
the locale gender labels for use in \newperson
.
\personpronoun
is defined as:
\NewDocumentCommand
\personpronoun
{ O{anon} }
{
\person_language_text:nn
{ #1 } { pronoun }
}
\Personpronoun
is defined as:
\NewDocumentCommand
\Personpronoun
{ O{anon} }
{
\person_Language_text:nn
{ #1 } { pronoun }
}
plural
according to the group gender
(unknown for a mixture); if only one person is defined,
this uses the text for according to the gender of that
person; otherwise it triggers a warning and uses the plural.
For example, \peoplepronoun
is defined as:
\NewDocumentCommand
\peoplepronoun
{ }
{
\person_language_all_text:n
{ pronoun }
}
\Peoplepronoun
is defined as:
\NewDocumentCommand
\Peoplepronoun
{ }
{
\person_Language_all_text:n
{ pronoun }
}
9.7.4. Hooks[link]
\newperson
.
\newperson
(after the label has been added to the internal sequence, and after
the internal integer variables used to keep track of totals are incremented).
Within you can set an attribute with
\person_set_attribute:nnn
.
\removeperson
and also
for each iteration in \removepeople
and \removeallpeople
.
You can use \person_unset_attribute:nn
in to undefine
a custom attribute. Note that \removeallpeople
zeroes the
internal integer variables and clears the internal sequence at the end, whereas
\removepeople
decrements the variables and pops the label off
the sequence at each iteration.
\newperson*
, the
keys are defined with \keys_define:nn
(l3keys) and
module datatool/person
. For example, to add a key to set the
person’s date of birth (replace mypkg
as applicable):
\tl_new:N
\l__mypkg_dob_tl
\person_new_appto_start:n
{
\tl_clear:N
\l__mypkg_dob_tl
}
\person_new_appto_end:n
{
\person_set_attribute:nnV
\l_person_label_tl
{ dob } \l__mypkg_dob_tl
}
\person_remove_appto:n
{
\person_unset_attribute:nn
\l_person_label_tl
{ dob }
}
\keys_define:nn
{ datatool/person }
{
dob .tl_set:N = \l__mypkg_dob_tl
}
10. Acknowledgements[link]
Symbols[link]
Glossary[link]
^^J
, but you may first need to set its category code appropriately.\DTLsetnumberchars
, optionally prefixed with a currency symbol. Note that the number group character is optional but, if present, if must be at intervals of three digits.\DTLsetnumberchars
.\text_purify:n
function. See “The LaTeX3 Interfaces” documentation for further details.\DTLsortwordlist
consisting of a marker, the original element, the sort value used for sorting, and the corresponding letter group.Command Summary[link]
A[link]
\acr
but sentence case. §8.7.1; 604
\newacro
. §8.7; 602
\acrpl
but sentence case. §8.7.1; 604
\PersonAddFemaleLabel
and may be removed in future. §9.4; 630
\PersonAddMaleLabel
and may be removed in future. §9.4; 629
C[link]
\DTLstringtype
, which is the older command.
\peoplechild
. §9.5.0.1; Table 9.1
\printterms
that expands to the current entry’s Child value. §8.9.1; 616
\Peoplechild
. §9.5.0.1; Table 9.1
\printterms
that expands to the current entry’s CurrentLocation value. §8.9.1; 616
D[link]
\newterm
when creating a label or sort value. §8.9.2; 617
\printterms
that expands to the current entry’s LetterGroup value. §8.9.1; 616
\printterms
at the end of the list.
\printterms
.
\newterm
to expand to the new term’s label. §8.9.2; 616
style
setting. §8.9.3; 617
\DTLgidxForeachEntry
to the letter group for the previous term. §8.9.1; 615
\printterms
to set the current style. §8.9.3; 617
\printterms
at the start of the list.
\newterm
when creating a label or sort value. §8.9.2; 617
\DTLplotatbegintikz
this may be used to restore \DTLplot
’s transformation matrix if the hook has altered it. §6.3; 507
\DTLplot
hooks to return the total number of database names. §6.3.1; 508
\l_dataplot_legend_tl
. §6.3.3; 510
\l_dataplot_legend_tl
. §6.3.3; 511
\DTLplot
hooks to return the total number of items given in the x list. §6.3.1; 508
\DTLplot
hooks to return the total number of items given in the y list. §6.3.1; 508
\datatool_prefix_adjust_sign:nnn
and \datatool_suffix_adjust_sign:nnn
to format the sign. §2.6; 128
\dtlwordindexcompare
, \dtlletterindexcompare
and \DTLsortwordlist
. §2.9.5.3; 166
\dtlwordindexcompare
, \dtlletterindexcompare
and \DTLsortwordlist
. §2.9.5.3; 166
\dtlwordindexcompare
, \dtlletterindexcompare
and \DTLsortwordlist
. §2.9.5.3; 166
\datatool_currency_symbol_region_prefix:n
to format the tag. Simply expands to by default. §2.3.2; 45
\datatoolcurrencysymbolprefixfmt
. §2.3.2; 45
parse
=auto-format to format a date. The arguments should all be integers, but may be empty. By default, simply uses \DTLCurrentLocaleFormatDate
. §2.7; 138
parse
=auto-format to format timestamps. The arguments may either be empty or the appropriate arguments to pass to \DataToolDateFmt
( should be { }{ }{ }{ }), \DataToolTimeFmt
( should be { }{ }{ }) and \DataToolTimeZoneFmt
( should be { }{ }). §2.7; 137
\datatool_def_currency:nnnn
with the first argument set to \dtlcurrdefaultfmt
. §2.6; 125
\DTLdefcurrency
to define a new currency. Note that, unlike \DTLdefcurrency
, no category code change is performed so make sure that the final argument contains the appropriate category code. §2.6; 125
\datatool_get_first_grapheme:nN
but will skip leading punctuation. §2.8.3; 148
\datatool_if_any_int_datum_type:nTF
{
} { } { }datatool-base v3.0+\datatool_if_any_int_datum_type_p:n
{ } { } { }\datatool_if_number_only_datum_type:nTF
{
} { } { }datatool-base v3.0+\datatool_if_number_only_datum_type_p:n
{ } { } { }\datatool_if_numeric_datum_type:nTF
{
} { } { }datatool-base v3.0+\datatool_if_numeric_datum_type_p:n
{ } { } { }\datatool_if_row_start:nnTF
{
} { } { } { }datatool v3.0+\datatool_if_row_start_p:nn
{ } { } { } { }\DTLdisplaydbAddItem
, this tests if the given combination of and corresponds to the first column of the tabular or longtable environment, taking the per-row
setting into account. §3.7.2; 256
\datatool_if_temporal_datum_type:nTF
{
} { } { }datatool-base v3.0+\datatool_if_temporal_datum_type_p:n
{ } { } { }\datatool_if_valid_datum_type:nTF
{
} { } { }datatool-base v3.0+\datatool_if_valid_datum_type_p:n
{ } { } { }{
where }{ }{ }{ } is the column key, is the column index, is the data type (\(-1\) for unknown) and is the column header. §3.16.2; 371
#1
references the column key, #2
references the column index, #3
references the data type (\(-1\) for unknown) and #4
references the column header. §3.16.2; 371
\l_datatool_measure_hook_tl
to locally disable problematic commands. §2.8.3; 147
\settodepth
to measure the depth of but first implements \l_datatool_measure_hook_tl
to locally disable problematic commands. §2.8.3; 147
\settoheight
to measure the height of but first implements \l_datatool_measure_hook_tl
to locally disable problematic commands. §2.8.3; 147
\l_datatool_measure_hook_tl
to locally disable problematic commands. §2.8.3; 147
\settowidth
to measure the width of but first implements \l_datatool_measure_hook_tl
to locally disable problematic commands. §2.8.3; 147
normally but expands to nothing within \space
( )\dtlwordindexcompare
, \dtlletterindexcompare
and \DTLsortwordlist
. §2.9.5.3; 167
\space
normally but expands to the character 0x1F inside \dtlwordindexcompare
, \dtlletterindexcompare
and \DTLsortwordlist
. §2.9.5.3; 167
,
normally but expands to the character 0x1C inside \space
\dtlwordindexcompare
, \dtlletterindexcompare
and \DTLsortwordlist
. §2.9.5.3; 166
,
normally but expands to the character 0x1D inside \space
\dtlwordindexcompare
, \dtlletterindexcompare
and \DTLsortwordlist
. §2.9.5.3; 166
\dtlcurrprefixfmt
this tests if starts with a plus (+
) or minus (-
) and, if so, shifts the sign in front of the symbol and encapsulates the sign with \datatool_adjust_sign_fmt:n
. §2.6; 128
\l_datatool_region_set_currency_bool
and only set the currency if true. §2.3.2; 45
\l_datatool_region_set_numberchars_bool
and only set the number group character and decimal character if true. §2.3.2; 45
\datatoolcurrencysymbolprefixfmt
. §2.3.2; 44
\datatool_set_numberchars:nn
but uses an apostrophe character for the number group character when formatting, and allows either straight apostrophe (U+27) or curly apostrophe (U+2019) as the number group character when parsing. The decimal character for both formatting and parsing is set to . §2.3.2; 43
\datatool_set_numberchars_regex_tl:nnnn
{
}{ }{ }{ }variants: VVnn Vnnn nVnn nVnV nnnV
; datatool-base v3.0+\datatool_set_numberchars_tl_regex:nnnn
{
}{ }{ }{ }variants: VVnn Vnnn nVnn VnVn nnVn
; datatool-base v3.0+\datatool_set_numberchars:nn
but uses \, (thin space) for the number group character when formatting, and allows \, or a normal space or the Unicode character U+2009 (thin space) as the number group character when parsing. The decimal character for both formatting and parsing is set to . §2.3.2; 43
\datatool_set_numberchars:nn
but uses \_ for the number group character when formatting, and allows \_ or the underscore character as the number group character when parsing. The decimal character for both formatting and parsing is set to . §2.3.2; 43
,
normally but expands to the character 0x1E inside \space
\dtlwordindexcompare
, \dtlletterindexcompare
and \DTLsortwordlist
. §2.9.5.3; 166
\dtlcurrsuffixfmt
this tests if starts with a plus (+
) or minus (-
) and, if so, encapsulates it with \datatool_adjust_sign_fmt:n
. The separator and symbol are placed after the value. §2.6; 128
parse
=auto-format to format a time. The arguments should all be integers, but may be empty. By default, simply uses \DTLCurrentLocaleFormatTime
. §2.7; 138
\DTLCurrentLocaleTimeStampFmtSep
. §2.7; 137
\DataToolDateTimeFmt
if { } and { } are both not empty, but is empty. By default, simply uses \DTLCurrentLocaleFormatTimeStampNoZone
. §2.7; 137
\DataToolDateTimeFmt
if { } and { } and are all not empty. By default, simply uses \DTLCurrentLocaleFormatTimeStampWithZone
. §2.7; 137
parse
=auto-format to format a time zone offset. The arguments should all be integers. By default, simply uses \DTLCurrentLocaleFormatTimeZone
. §2.7; 138
\DTLformatthisbibentry
and \DTLforeachbibentry
that should expand to the cite key identifying the required row of the database. §7.8; 546
\DTLformatthisbibentry
and \DTLforeachbibentry
that should expand to the entry type obtained from the EntryType field of the current row. §7.8; 546
\DTLformatthisbibentry
and \DTLforeachbibentry
that should expand to database name supplied in the argument of those commands.
\printterms
that expands to the current entry’s Description value. §8.9.1; 615
\DTLdisplaydb
and \DTLdisplaylongdb
to add the appropriate column alignment specifier to the token list variable. Not used if the align-specs
option is set. §3.7.2; 256
\DTLdisplaydb
and \DTLdisplaylongdb
to add the appropriate column alignment specifier for the header row to the token list variable. Not used if the header-row
option is set. §3.7.1.3; 247
\DTLdisplaydb
and \DTLdisplaylongdb
at the end of the alignment specification. Ignored if the align-specs
option is set. §3.7.2; 255
\DTLinitials
and \DTLstoreinitials
after an initial before a hyphen. §2.8.2; 142
\DTLinitials
and \DTLstoreinitials
after the initials. §2.8.2; 141
\dtlcurrentrow
is set. §3.16.1; 367
\andname
if that command was defined when datatool-base was loaded otherwise expands to \& or the applicable localisation text. §2.9.2; 152
\DTLstoreinitials
to markup initials from words with an apostrophe. §2.8.2; 141
\dtlcurrentrow
for the column identified by . The row must not already contain an element in the given column. The column data is updated according to (the global option is checked). §3.16.1; 370
\DTLforeach
, this command will append an entry to the current row with the given value for the column identified by . §3.8.2.1; 297
\dtlgetrow
) and globally defines the commands in the assignment list for the row identified by the row index in the database identified by . This command is not affected by the global option. If you prefer a local assignment, use \dtlgetrow
and \DTLassignfromcurrentrow
instead. §3.16.1; 369
\dtlcurrentrow
) to the provided placeholder commands in the . §3.16.1; 368
\DTLsortwordlist
and \DTLsortdata
to assign the letter group based on the actual or sort value. §2.9.5; 157
\DTLbarchart
and \DTLmultibarchart
at the start of the tikzpicture environment. §5.4.4; 445
\DTLbarchart
and \DTLmultibarchart
at the end of the tikzpicture environment. §5.4.4; 445
\DTLbarchart
). §5.4.2; 439
\pgftext
alignment options for the \(x\)-axis bar group labels. §5.4.2; 441
\DTLmultibarchart
, this is reset at the start of each group. §5.4.2; 439
\DTLbarXupperlabelalign
and optionally redefine \DTLbarXnegupperlabelalign
. §5.4.2; 441
\path
when drawing or filling a bar. It may be redefined to apply additional styling. §5.4.1; 438
\DTLmultibarchart
, this will expand to the total number of variables (that is, the number of bars per group) for the current bar chart. §5.4.4; 446
\pgftext
alignment options for the \(x\)-axis bar labels. §5.4.2; 439
\pgftext
alignment options for the lower labels of bars with negative values. §5.4.2; 440
\pgftext
alignment options for the upper labels of bars with negative values. §5.4.2; 440
\pgftext
alignment options for the upper labels of bars with positive values. §5.4.2; 440
\pgftext
alignment options for the \(y\)-axis tick labels. §5.4.2; 441
\DTLdisplaydb
and \DTLdisplaylongdb
at the start of the alignment specification. Ignored if the align-specs
option is set. §3.7.2; 255
\dtlcurrentrow
is set. §3.16.1; 367
\DTLdisplaydb
and \DTLdisplaylongdb
between the column alignment specifiers. Ignored if the align-specs
option is set. §3.7.2; 255
\DTLinitials
and \DTLstoreinitials
between initials. §2.8.2; 141
\DTLbiburldate
. §7.7.1; 545
\DTLbibfield
but is specifically used for Date
and UrlDate
. §7.8; 547
\DTLloadbbl
that should expand to the name of the databib database containing the bibliography data. §7.4; 533
DOI
field (which should already be detokenized). §7.7.1; 544
\DTLbibdoi
in the formation of the hyperlink, if applicable. §7.7.1; 544
\DTLbibdoi
. §7.7.1; 544
Eprints
field (which should already be detokenized). §7.7.1; 544
\DTLforeachbibentry
, this expands to the value of the column identified by in the current iteration. Expands to nothing if the field isn’t set or doesn’t exist. §7.8; 546
\ifthenelse
, this conditional tests if the value of the named field for the current row contains . §7.6; 537
\ifthenelse
, this conditional tests if the named field exists (the column is defined and the value is not null) for the current row. §7.6; 536
\ifthenelse
, this conditional tests if the value of the named field for the current row is equal to . §7.6; 537
\ifthenelse
, this conditional tests if the value of the named field for the current row is lexicographically greater than or equal to . §7.6; 538
\ifthenelse
, this conditional tests if the value of the named field for the current row is lexicographically greater than . §7.6; 538
\ifthenelse
, this conditional tests if the value of the named field for the current row is lexicographically less than or equal to . §7.6; 537
\ifthenelse
, this conditional tests if the value of the named field for the current row is lexicographically less than . §7.6; 537
\DTLforeachbibentry
, this sets the command (token list variable) to the value of the column identified by in the current iteration. §7.8; 547
PubMed
, DOI
, Url
and Eprints
fields. §7.7.1; 543
\DTLbibliography
at the start of each iteration. §7.7.1; 542
\DTLforeachbibentry*
, formatting each item according to the current style (as set by \DTLbibliographystyle
). The supplied arguments are provided to both the DTLthebibliography environment and \DTLforeachbibentry
. §7.6; 536
PubMed
field. §7.7.1; 543
\DTLbibpubmed
in the formation of the hyperlink, if applicable. §7.7.1; 544
\DTLbibpubmed
. §7.7.1; 543
encap
sort option to convert the comma-separated name lists in the Author and Editor fields to a format better suited for a sort value. Each element in the list will be encapsulated with \DTLbibsortname
and separated by \DTLbibsortnamesep
. §7.5; 535
\DTLbibsortencap
, this command should expand to the format of the name best suited for sorting. §7.5; 535
\DTLbibsortencap
. §7.5; 535
Url
field (which should already be detokenized). §7.7.1; 544
UrlDate
field. §7.7.1; 545
\DTLforeach
, this command will cause the loop to terminate at the end of the current iteration. §3.8.2; 296
except that the cite information is written to the auxiliary file associated with the multi-bib (as identified in \cite
[ ]{ }\DTLmultibibs
). The cross-referencing label is constructed from both and the label to allow the same citation to appear in multiple bibliographies. §7.9; 549
\dtlclip
and stores the result as a formatted number in the control sequence . §2.5.2; 112
\DTLforeachkeyinrow
to the current column index. §3.8.2; 297
\DTLdisplaydb
and \DTLdisplaylongdb
to align the column headers. §3.7.1.3; 247
0
indicates the strings are the same, -1
means that comes before (less than) and 1
means that comes after (greater than) (case-sensitive) . §2.9.5.1; 163
\DTLcurr
if defined or to otherwise. §2.6; 126
\dtlcurrprefixfmt
). §2.6; 128
\DTLfmtcurrency
with the default currency symbol. §2.6; 129
\DTLdisplaydb
and \DTLdisplaylongdb
for columns with the currency data type. Ignored if the align-specs
option is set. §3.7.2; 254
\DTLdisplaydb
and \DTLdisplaylongdb
to format entries in currency columns. Defined to use \dtlnumericformat
by default. §3.7.2; 253
\DTLassignlettergroup
to identify currency groups. §2.3.3; 53
\DTLforeach
to expand to the current iteration index. §3.8.2; 296
\DTLdecimaltocurrency
should round to. This command should be redefined by the appropriate localisation hooks. §2.3.2; 46
\DTLassignlettergroup
to determine whether to obtain the letter group from the actual or sort value. Localisation support should redefine this as appropriate and may further process the value to ensure that the first character matches the appropriate group. §2.3.3; 49
\DTLGetInitialLetter
and \DTLassignlettergroup
. §2.3.3; 49
\DTLforeach
or \dtlgetrow
, the row content can then be referenced or modified by commands like \dtlreplaceentryincurrentrow
. §3.16.1; 367
\dtlcurrfmtsep
when \DTLcurrCodeOrSymOrChar
expands to either its second or third argument. §2.6; 129
\DTLdefcurrency
. §2.6; 124
\datatool_prefix_adjust_sign:nnn
. §2.6; 128
\datatool_suffix_adjust_sign:nnn
. §2.6; 128
\DTLassignlettergroup
to identify date groups.
\DTLassignlettergroup
to identify datetime groups.
\DTLparse
or \DTLxparse
. §2.2.3; 17
\DTLparse
or \DTLxparse
. §2.2.3; 17
\DTLparse
or \DTLxparse
(as a plain number). §2.2.3; 17
\dtldbrowreconstruct
. §3.15.1.3; 345
\dtldbcolreconstruct
. §3.15.1.3; 345
\DTLreconstructdatabase
. §3.15.1.3; 344
where is the default-name. §3.15.1.2; 339
\DTLnewdbentry
{ }{ }{ }
where is the default-name. §3.15.1.2; 339
\DTLnewrow
{ }\DTLreconstructdatabase
. §3.15.1.3; 344
\DTLreconstructdatabase
. §3.15.1.3; 345
where is the default-name. §3.15.1.2; 340
\DTLsetheader
{ }{ }{ }\dtldbcolreconstruct
. §3.15.1.3; 345
\DTLread
. §3.15.2; 346
\dtlcurrdefaultfmt
if omitted. §2.6; 123
\DTLdisplaydb
and \DTLdisplaylongdb
to insert content after the header. §3.7.2; 253
\DTLdisplaydb
and \DTLdisplaylongdb
to insert a new line. §3.7.2; 255
\DTLdisplaydb
to add the start of the tabular environment to . §3.7.2; 257
\DTLdisplaydb
to add the end of the tabular environment to . §3.7.2; 257
\DTLdisplaydb
and \DTLdisplaylongdb
. §3.7.2; 255
\DTLdisplaydb
. §3.7.2; 253
\DTLdisplaydb
and \DTLdisplaylongdb
to insert content before the end of the environment. §3.7.2; 253
\DTLdisplaylongdb
to add the start of the tabular environment to . §3.7.2; 258
\DTLdisplaylongdb
to add the end of the tabular environment to . §3.7.2; 258
\DTLdisplaylongdb
. §3.7.2; 254
\DTLmultibarchart
. §5.4.2; 442
\DTLdisplaydb
and \DTLdisplaylongdb
to insert content at the start of each row. §3.7.2; 253
\DTLdisplaydb
and \DTLdisplaylongdb
to insert content before the header. §3.7.2; 253
row-idx-map-function
, this command expands to a row index that will arrange data rows from top to bottom instead of left to right when per-row
is greater than 1. Note that this is only designed to work when no rows are omitted. §3.7.2; 258
\DTLmultibarchart
. §5.4.2; 442
\DTLdisplaydb
. §3.7.2; 253
where is obtained by expanding \color
{ }
if the value is non-negative or omitted and to \DTLgetbarcolor
{ }
, otherwise. Does nothing if an empty colour specification has been applied to the given bar index. §5.4.3; 443
\DTLgetnegbarcolor
{ }\DTLdobarcolor
for the current bar index. §5.4.3; 443
\color
) to that associated with the th segment. §4.6; 392
but encapsulates the value with . Expands to nothing if the field isn’t set or doesn’t exist. §7.8; 546
\DTLbibfield
{ }\DTLbibliography
and \DTLmbibliography
at the end of each iteration. Does nothing by default. §7.7.1; 542
\DTLeverybarhook
, this expands to the end point of the current bar along its mid-axis as a pgf point. §5.4.4; 445
\DTLmultibarchart
at the end of every bar group. §5.4.4; 445
\DTLbarchart
and \DTLmultibarchart
after the current bar is drawn. §5.4.4; 444
\DTLbarchart
and \DTLmultibarchart
before the current bar is drawn. §5.4.4; 444
\DTLifstringgt
to compare the original and . §2.9.5; 159
\DTLforeach
(or \DTLforeach*
for the starred form), setting up the placeholder commands \DBIBname
, \DBIBcitekey
and \DBIBentrytype
and, for each row that satisfies the given (ifthen) condition, increments DTLbibrow and does . Locally assigns placeholder commands. §7.8; 545
\DTLforeach
, defines to the value in the current column, and does .
\DTLforeach
nested level. §3.8.2; 294
\DTLformatforenames
but converts the forenames to initials with \DTLstoreinitials
. §7.7.1; 540
\DTLformatauthor
. §7.7.1; 541
\DTLbibliography
to format the database row in the current iteration of \DTLforeachbibentry
. §7.8; 547
\DTLformatauthorlist
and \DTLformateditorlist
to format the list of names. Each element in the list must be in the form {
and }{ }{ }{ } must have those four arguments for its syntax. If the list has more than items, it will be truncated with \etalname
. §7.7.1; 541
Date
field if set, or from the Year
and Month
fields (if set). §7.7.1; 542
\DTLformateditor
. §7.7.1; 541
\DTLformatbibentry
but for the row identified by in the given database . §7.8; 548
\DTLabs
but globally defines . §2.5.2; 111
\DTLadd
but globally defines . §2.5.2; 108
\DTLaddall
but globally defines . §2.5.2; 110
\DTLclip
but globally defines . §2.5.2; 112
\DTLdiv
but globally defines . §2.5.2; 110
\DTLaction
in the current scope, and stores the value in the token list control sequence . Leave the optional argument empty (or omit) for the main return value, otherwise should identify the particular value when there are multiple return values. §3.3; 205
white
if not set. This takes the color-style setting into account. §5.4.3; 443
\dtlcurrentrow
and locally defines the control sequence to that value. This is just a shortcut that uses \dtlgetentryfromrow
. §3.16.1; 368
white
if not set. §4.6; 392
\dtlcurrentrow
with preceding rows in \dtlbeforerow
and following rows in \dtlafterrow
. The row index is stored in \dtlrownum
, and the database label is stored in \dtldbname
. This command assumes that the given row exists. Assignments are local. This command does not check the global option. §3.16.1; 368
\dtlgetrow
but gets the row where the entry in the column identified by its index matches . §3.16.1; 368
\DTLgetrowindex
but doesn’t produce an error if not found. §3.16; 365
\dtlforint
but globally sets the count register. §3.16.2; 371
\DTLgidxForeachEntry
, which is internally used by \printterms
. §8.9.1; 615
style
=dict, this encapsulates the “category” child name. §8.8.2.5; 612
style
=dict between “category” child entries. §8.8.2.5; 612
child
=noname to show the child index instead of the name. §8.8.1; 608
style
=gloss. §8.8.2.4; 611
\printterms
to the name of the current database. §8.8; 606
style
=dict, this inserts the group header. §8.8.2.5; 612
\printterms
to iterate over the database. §8.9.1; 615
\acr
and \acrpl
to format the full form. §8.7.1; 604
\Acr
and \Acrpl
to format the full form. §8.7.1; 605
\newterm
when creating a label or sort value, expands to nothing. §8.9.2; 617
\newterm
when creating a label or sort value, simply expands to . §8.9.2; 617
style
=gloss. §8.8.2.4; 611
\DTLgidxFormatSee
. §8.8.1; 609
style
=dict between sub-category child entries. §8.8.2.5; 612
\DTLmax
but globally defines . §2.5.2; 113
\DTLmaxall
but globally defines . §2.5.2; 113
\DTLmeanforall
but globally defines . §2.5.2; 113
\DTLmin
but globally defines . §2.5.2; 112
\DTLminall
but globally defines . §2.5.2; 113
\DTLmul
but globally defines . §2.5.2; 110
\DTLneg
but globally defines . §2.5.2; 111
\DTLround
but globally defines . §2.5.2; 112
\DTLsdforall
but globally defines . §2.5.2; 114
\DTLsqrt
but globally defines . §2.5.2; 111
\DTLsub
but globally defines . §2.5.2; 110
\DTLtrunc
but globally defines . §2.5.2; 112
\DTLvarianceforall
but globally defines . §2.5.2; 114
\DTLforeachkeyinrow
to the current column header. §3.8.2; 297
\dtlcolumnheader
to apply any font change to the header text. §3.7.2; 252
0
indicates the strings are the same, -1
means that comes before (less than) and 1
means that comes after (greater than) (case-insensitive) . §2.9.5.1; 163
\DTLforeachbibentry
, this tests if any of the given fields exists (that is, if both the column is defined and the value is not null) for the current iteration. §7.8; 547
\DTLforeachbibentry
, this tests if the given field exists (that is, if both the column is defined and the value is not null) for the current iteration. §7.8; 547
\DTLifnumclosedbetween
or \DTLifstringclosedbetween
depending on the data type of , and . The starred version ignores case if \DTLifstringclosedbetween
is required. §2.4.1.5; 88
\DTLifnumeq
or \DTLifstringeq
depending on the data type of both and . The starred version ignores case if \DTLifstringeq
is required. §2.4.1.5; 87
\DTLforeach
, this command does if the current row is the first iteration of the loop (that is, where DTLrow is 1), otherwise it does false. Note that if \DTLforeach
has a condition, this references the loop index which may not match the actual row index. §3.8.2; 296
\dtlifnumclosedbetween
. §2.4.1.4; 84
\dtlifnumopenbetween
. §2.4.1.4; 83
\DTLifnumgt
or \DTLifstringgt
depending on the data type of both and . The starred version ignores case if \DTLifstringgt
is required. §2.4.1.5; 88
\DTLforeach
, this command does if the current loop is on the last row. §3.8.2; 296
\DTLifnumlt
or \DTLifstringlt
depending on the data type of both and . The starred version ignores case if \DTLifstringlt
is required. §2.4.1.5; 87
\DTLforeach
, this command does if the current loop index is odd. §3.8.2; 296
\DTLifnumopenbetween
or \DTLifstringopenbetween
depending on the data type of , and . The starred version ignores case if \DTLifstringopenbetween
is required. §2.4.1.5; 88
\DTLinitials
and \DTLstoreinitials
where a hyphen occurs. §2.8.2; 142
\DTLstoreinitials
to markup initials. §2.8.2; 141
\DTLstoreinitials
. §2.8.2; 140
\DTLdisplaydb
and \DTLdisplaylongdb
for columns with the integer data type. Ignored if the align-specs
option is set. §3.7.2; 254
\DTLdisplaydb
and \DTLdisplaylongdb
to format entries in integer columns. Defined to use \dtlnumericformat
by default. §3.7.2; 252
\DTLifclosedbetween
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 92
\DTLifcurrency
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 90
\DTLifcurrencyunit
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 90
\DTLifeq
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 90
\DTLisnumclosedbetween
. §2.4.2; 93
\DTLisnumeq
. §2.4.2; 90
\DTLisnumgt
. §2.4.2; 92
\DTLisnumgteq
. §2.4.2; 92
\DTLisnumlt
. §2.4.2; 91
\DTLisnumlteq
. §2.4.2; 91
\DTLisnumopenbetween
. §2.4.2; 92
\DTLifgt
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 91
\DTLifclosedbetween*
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 92
\DTLifeq*
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 90
\DTLifgt*
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 91
\DTLiflt*
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 91
\DTLifinlist
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 93
\DTLifint
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 89
\DTLifopenbetween*
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 92
\DTLifStartsWith*
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 93
\DTLifSubString*
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 93
\DTLifEndsWith*
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 93
\DTLiflt
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 91
\DTLifnumclosedbetween
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 93
\DTLifnumeq
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 90
\DTLifnumerical
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 90
\DTLifnumgt
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 91
\ifthenelse
. §2.4.2; 92
\DTLifnumlt
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 91
\ifthenelse
. §2.4.2; 91
\DTLifnumopenbetween
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 92
\DTLifopenbetween
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 92
\DTLifStartsWith
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 93
\DTLifreal
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 90
\DTLifstring
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 90
\DTLifSubString
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 93
\DTLifEndsWith
but for use in the conditional part of commands like \ifthenelse
. §2.4.2; 93
\DTLforeachkeyinrow
to the current column key. §3.8.2; 297
\DTLread
. §3.15.3; 359
\DTLassignlettergroup
to identify alphabetical letter groups. §2.3.3; 52
\dtlsortlist
. §2.9.5.1; 162
\DTLlistformatlastsep
. Expands either to \DTLandname
or to \&, depending on the and
option in the lists setting. §2.9.2; 152
\DTLformatlist
. §2.9.2; 151
\DTLformatlist
. §2.9.2; 151
\DTLlistformatlastsep
if the list contains more than two items. §2.9.2; 152
\DTLformatlist
. §2.9.2; 151
, creates a new database called (and defines the placeholder command \bibliographystyle
{databib}\DTLBIBdbname
to ), and inputs the given , which is expected to be in the format created by the databib.bst bibtex style file. The identifies the list of bib files that bibtex needs to read in order to create the . If the optional argument is omitted,
is assumed. If the argument is empty, the default database name will be used. §7.3; 532
\jobname
.bbl\DTLloadbbl
but for multiple bibliographies. §7.9; 549
\dtlrownum
. Values can be accessed with \DTLmapget
or iterated over with \DTLmaprow
. §3.8.1
\DTLmapdata
and DTLenvmapdata. The starred version will discard any pending edits. §3.8.1; 286
\DTLmapdata
(or DTLenvmapdata) to access a value in the current iteration row. §3.8.1.1; 287
\DTLmapdata
(or DTLenvmapdata) to access values in the current iteration row. The starred form won’t trigger an error if a column key in isn’t defined. §3.8.1.1; 289
\DTLmapdata
or the environment body of DTLenvmapdata, this command iterates over each column in the current \DTLmapdata
row, sets \dtlcolumnnum
to the column index and to the column value and does . §3.8.1.1; 288
\DTLmaprow
. §3.8.1.1; 289
\DTLplot
hooks, this expands to the maximum \(x\) value of the plot bounds. §6.3.1; 507
\DTLplot
hooks, this expands to the maximum \(y\) value of the plot bounds. §6.3.1; 508
\DTLmbibliography
at the start of each iteration. §7.7.1; 542
\DTLbibliography
but for the given multi-bib database, which should have been loaded with \DTLloadmbbl
. §7.9; 549
\DTLeverybarhook
, this expands to the mid point of the current bar as a pgf point. §5.4.4; 445
\DTLplot
hooks, this expands to the minimum \(x\) value of the plot bounds. §6.3.1; 507
\DTLplot
hooks, this expands to the minimum \(y\) value of the plot bounds. §6.3.1; 507
\DTLloadbbl
, this adds a new value to the last row in the database identified by \DTLBIBdbname
(without checking for existence). Internally uses \DTLnewdbentry*
, so it obeys the general database options. §7.4; 533
\DTLnewbibitem
but the item has literal content. §7.4; 534
\DTLloadbbl
, this creates a new row in the database identified by \DTLBIBdbname
(without checking for existence). Internally uses \DTLnewrow*
, so it obeys the general database options. §7.4; 533
\DTLgnewdb
. §3.4; 232
\DTLcite
but analogous to \nocite
. §7.9; 549
expand-value
and expand-once-value
action settings. §3.1; 179
\DTLassignlettergroup
to identify non-letter groups. §2.3.3; 53
\DTLassignlettergroup
to identify number groups. §2.3.3; 53
\DTLdisplaydb
and \DTLdisplaylongdb
to format entries in numeric columns. §3.7.2; 252
\two@digits
, the may be a decimal. The expansion is also a plain number. The argument should be in the range 1–7. §2.5.1; 98
\dtlpadleadingzeros
if the value is negative. §2.5.1; 98
\dtlpadleadingzeros
if the value is positive. §2.5.1; 98
\par
. For use in “short” arguments where \par
isn’t permitted. §3.4; 235
\DTLusedatum
, \DTLdatumvalue
, \DTLdatumcurrency
or \DTLdatumtype
. §2.2.3; 16
\DTLpiechart
at the start of the tikzpicture environment. §4.7; 394
\DTLpiechart
at the end of the tikzpicture environment. §4.7; 394
\DTLplot
. §6.3; 506
\DTLplot
. §6.3; 507
\DTLplotdisplayXticklabel
and \DTLplotdisplayYticklabel
to format the \(x\) and \(y\) tick labels. §6.4.3; 519
\DTLplot
hooks, this resets the pgf transformation matrix and uses
. §6.5; 520
\pgfplothandlermark
{ }\DTLplotlegendsetname
. §6.3.3; 512
\DTLplotlegendname
. §6.3.3; 513
\DTLplotlegendname
should use instead of . §6.3.3; 512
\DTLplotlegendx
should use instead of the column header. §6.3.3; 513
\DTLplotlegendy
should use instead of the column header. §6.3.3; 514
\DTLplotlegendxy
show the \(x\) label in the legend. The default definition is to show the header for the column identified by unless a mapping has been provided with \DTLplotlegendsetxlabel
. The optional arguments are ignored. §6.3.3; 513
\DTLplotlegendsetylabel
. The optional arguments are ignored. §6.3.3; 514
\pagename
or \pagesname
(before the page number). §7.7.1; 542
\DTLassignlettergroup
to pre-process the currency group, where contains the numeric value and contains the currency symbol. This is performed before encapsulation with \dtlcurrencygroup
. §2.9.5; 158
\DTLassignlettergroup
to pre-process the (decimal) numeric group stored in the given token list variable . This is performed before encapsulation with \dtlnumbergroup
. §2.9.5; 158
\DTLassignlettergroup
to pre-process the (integer) numeric group stored in the given token list variable . This is performed before encapsulation with \dtlnumbergroup
. §2.9.5; 157
\DTLassignlettergroup
to pre-process the (alphabetical) letter group stored in the given token list variable . This is performed after \DTLCurrentLocaleGetInitialLetter
and before encapsulation with \dtllettergroup
. §2.9.5; 158
\DTLassignlettergroup
to pre-process the (symbol/punctuation) non-letter group stored in the given token list variable . This is performed before encapsulation with \dtlnonlettergroup
. §2.9.5; 158
\DTLsaverawdb
but designed for database with fragile commands. §3.15.4; 361
csv-content
=literal setting. §3.15.2; 349
\DTLdisplaydb
and \DTLdisplaylongdb
for columns with the decimal (real) data type. Ignored if the align-specs
option is set. §3.7.2; 254
\DTLdisplaydb
and \DTLdisplaylongdb
to format entries in decimal columns. Defined to use \dtlnumericformat
by default. §3.7.2; 252
\dtldbname
) from \dtlbeforerow
, \dtlcurrentrow
and \dtlafterrow
. This command checks the global option. §3.16.1; 369
\dtlrecombine
but omits the current row (that is, the current row is deleted from the database). §3.16.1; 369
\DTLreconstructdatabase
.
\DTLforeach
, this command will remove the current row. §3.8.2.1; 298
\DTLforeach
, this command will remove the entry in the current row for the column identified by . §3.8.2.1; 297
\dtlcurrentrow
. §3.16.1; 370
\DTLforeach
, this command will replace the entry in the current row with the given value for the column identified by . §3.8.2.1; 297
\dtlcurrentrow
with the given value . The column data is updated according to the new value honouring the global option (but \dtlcurrentrow
will only be locally changed). §3.16.1; 370
\DTLmapdata
and read-only
=false, this command will remove a column from the current iteration row. §3.8.1.2; 290
\DTLmapdata
and read-only
=false, this command will remove the current iteration row. §3.8.1.2; 290
\dtlforeachlevel
. §3.8.2; 295
\dtlforeachlevel
. §3.8.2; 295
\DTLforeach
in . §3.8.2; 294
otherwise it will just expand to . §2.2.1; 14
\num
{value}\DTLmapdata
and read-only
=false, this command will set a column in the current iteration row. §3.8.1.2; 291
for easy conversion to an l3fp variable. §2.2.3; 18
\datatool_datum_fp:nnn
{ }{ }{ }\dtlsort
to sort the given database. The starred version uses \dtlicompare
as the handler function, and the unstarred version uses \dtlcompare
. §3.14.2; 335
\DTLsortwordlist
. §2.9.5; 159
\DTLsortwordlist
. §2.9.5; 159
\DTLsortwordlist
. §2.9.5; 159
\DTLsortwordlist
. Expands , strips hyphens and spaces, then applies \DTLDefaultLocaleWordHandler
and purifies the result. §2.9.5.2; 165
\DTLsortwordlist
. Expands and converts to lowercase, strips hyphens and spaces, then applies \DTLDefaultLocaleWordHandler
and purifies the result. §2.9.5.2; 165
{
where }{ }{ } is a count register and and are two elements to compare. §2.9.5; 156
\DTLsortwordlist
. Expands , then applies \DTLDefaultLocaleWordHandler
and purifies the result. §2.9.5.2; 164
\DTLsortwordlist
, \dtlwordindexcompare
and \dtlletterindexcompare
. §2.9.5.3; 168
\DTLsortwordlist
and \dtlwordindexcompare
and \dtlletterindexcompare
. Expands and converts to lowercase, then applies \DTLDefaultLocaleWordHandler
and purifies the result. §2.9.5.2; 164
where { }{ } is the original value and is a token list control sequence in which to store the byte sequence. §2.9.5; 156
\DTLwrite
will allow it to expand for DBTEX formats during the write operation, even if expand
=none is on. §3.11; 317
\DTLeverybarhook
, this expands to the starting point of the current bar along its mid-axis as a pgf point. §5.4.4; 444
\DTLstoreinitials
to get the initial letter of . Default definition just uses \DTLGetInitialLetter
. §2.8.2; 141
\DTLdisplaydb
and \DTLdisplaylongdb
for columns with the string data type. Ignored if the align-specs
option is set. §3.7.2; 254
\DTLdisplaydb
and \DTLdisplaylongdb
to format entries in string columns. §3.7.2; 252
\dtlcurrentrow
. §3.16.1; 370
\DTLsortwordlist
. §2.9.5.3; 165
\theDTLrow
where is one more than \dtlforeachlevel
. §3.8.2; 295
\DTLassignlettergroup
to identify time groups.
\DTLmultibarchart
, this will expand to the total number of bar groups in the current bar chart. §5.4.4; 446
\DTLforeachkeyinrow
to the current column type. §3.8.2; 297
\dtlappendentrytocurrentrow
, if there is no entry for the given column in the current row, otherwise updates the entry. §3.16.1; 370
\DTLaction
in the current scope. Leave the argument empty for the main return value, otherwise should identify the particular value when there are multiple return values. §3.3; 205
\DTLparse
(or the expanded value for \DTLxparse
). §2.2.3; 17
\dtlsortlist
. §2.9.5.1; 163
name
option in the file called . If the file extension is omitted, the default for the given format is used. §3.15.4; 360
\DTLparse
but first fully expands . §2.2.3; 16
\DTLsplitstring
but expands and once. §2.8.1; 139
E[link]
\dtlgetrowforvalue
but first expands .
F[link]
\femalelabels
expanded to the comma-separated list of recognised female gender labels. This command was replaced with \g_person_female_label_clist
variable in version 3.0 to reduce the possibility of a command name clash. Now only available with rollback. Use \PersonSetFemaleLabels
to reset the list or \PersonAddFemaleLabel
to append to the list. §9.4; 630
\newtermaddfield
to reference the value of another field. §8.6; 600
\printterms
that expands to the current entry’s FirstId value. §8.9.1; 616
is optional. If omitted the list of all defined people is assumed. §9.7.2; 653
\in
{ }G[link]
\DTLforeachbibentry
but performs global assignments. §7.8; 545
\DTLformatbibentry
but performs global changes. §7.8; 547
. §8.5.1; 598
\Useentry
{ }{Text}
. §8.5.1; 598
\useentry
{ }{Text}\Glsdispentry
but converts the value to sentence case. §8.5; 597
\useentry
but displays the provided text instead of the value of a field. §8.5; 596
. §8.5.1; 599
\Useentrynl
{ }{Text}
. §8.5.1; 598
\useentrynl
{ }{Text}
. §8.5.1; 599
\Useentry
{ }{Plural}
. §8.5.1; 598
\useentry
{ }{Plural}
. §8.5.1; 599
\Useentrynl
{ }{Plural}
. §8.5.1; 598
\useentrynl
{ }{Plural}
. §8.5.1; 599
\Useentry
{ }{Symbol}
. §8.5.1; 599
\useentry
{ }{Symbol}H[link]
\printterms
that expands to the current entry’s HierSort value. §8.9.1; 616
I[link]
load-action
option instead. §3.15.2; 356
\PersonIfFemaleLabel
instead. §9.4; 631
\PersonIfMaleLabel
instead. §9.4; 631
L[link]
\printterms
that expands to the current entry’s Label value. §8.9.1; 616
\DTLplotlegendname
and modified by \DTLplotlegendsetname
. §6.3.3; 512
\l_dataplot_legend_names_prop
property list. §6.3.3; 512
\DTLplotlegendx
and modified by \DTLplotlegendsetxlabel
. §6.3.3; 513
\l_dataplot_legend_xlabels_prop
property list. §6.3.3; 513
\DTLplotlegendy
and modified by \DTLplotlegendsetylabel
. §6.3.3; 514
\l_dataplot_legend_ylabels_prop
property list. §6.3.3; 514
\DTLplot
to keep track of the index of the x list. §6.3.2; 510
\DTLplot
to keep track of the index of the y list. §6.3.2; 510
”, if supported by the current encoding, or “
A
” otherwise. §2.3.1; 38
”, if supported by the current encoding, or “
A
” otherwise. §2.3.1; 38
”, if supported by the current encoding, or “
B
” otherwise. §2.3.1; 33
”, if supported by the current encoding, or “
B
” otherwise. §2.3.1; 33
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 41
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 41
caption
key. §3.7.2; 259
”, if supported by the current encoding, or “
S
” otherwise. §2.3.1; 39
”, if supported by the current encoding, or “
S
” otherwise. §2.3.1; 39
”, if supported by the current encoding, or “
c
” otherwise. §2.3.1; 32
”, if supported by the current encoding, or “
c
” otherwise. §2.3.1; 32
”, if supported by the current encoding, or “
C
” otherwise. §2.3.1; 34
”, if supported by the current encoding, or “
C
” otherwise. §2.3.1; 34
cont-caption
key. §3.7.2; 259
”, if supported by the current encoding, or “
Cr
” otherwise. §2.3.1; 34
”, if supported by the current encoding, or “
Cr
” otherwise. §2.3.1; 34
”, if supported by the current encoding, or “
#
” otherwise. §2.3.1; 32
”, if supported by the current encoding, or “
#
” otherwise. §2.3.1; 32
per-row
option. §3.7.2; 259
per-row
rounded up. §3.7.2; 259
”, if supported by the current encoding, or “
d
” otherwise. §2.3.1; 36
”, if supported by the current encoding, or “
d
” otherwise. §2.3.1; 36
”, if supported by the current encoding, or “
Dr
” otherwise. §2.3.1; 37
”, if supported by the current encoding, or “
Dr
” otherwise. §2.3.1; 37
”, if supported by the current encoding, or “
CE
” otherwise. §2.3.1; 33
”, if supported by the current encoding, or “
CE
” otherwise. §2.3.1; 34
”, if supported by the current encoding, or “
E
” otherwise. §2.3.1; 36
”, if supported by the current encoding, or “
E
” otherwise. §2.3.1; 37
”, if supported by the current encoding, or “
f
” otherwise. §2.3.1; 33
”, if supported by the current encoding, or “
f
” otherwise. §2.3.1; 33
foot
key. §3.7.2; 259
”, if supported by the current encoding, or “
F
” otherwise. §2.3.1; 34
”, if supported by the current encoding, or “
F
” otherwise. §2.3.1; 34
”, if supported by the current encoding, or “
p
” otherwise. §2.3.1; 37
”, if supported by the current encoding, or “
p
” otherwise. §2.3.1; 38
”, if supported by the current encoding, or “
G.
” otherwise. §2.3.1; 38
”, if supported by the current encoding, or “
G.
” otherwise. §2.3.1; 38
”, if supported by the current encoding, or “
S
” otherwise. §2.3.1; 38
”, if supported by the current encoding, or “
S
” otherwise. §2.3.1; 39
no-header
key. §3.7.2; 259
”, if supported by the current encoding, or “
R
” otherwise. §2.3.1; 40
”, if supported by the current encoding, or “
R
” otherwise. §2.3.1; 40
”, if supported by the current encoding, or “
K
” otherwise. §2.3.1; 37
”, if supported by the current encoding, or “
K
” otherwise. §2.3.1; 37
label
key. §3.7.2; 259
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 41
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 41
last-foot
key. §3.7.2; 259
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 34
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 35
”, if supported by the current encoding, or “
lt
” otherwise. §2.3.1; 39
”, if supported by the current encoding, or “
lt
” otherwise. §2.3.1; 39
”, if supported by the current encoding, or “
M
” otherwise. §2.3.1; 40
”, if supported by the current encoding, or “
M
” otherwise. §2.3.1; 41
\datatool_measure_height:Nn
, \datatool_measure_width:Nn
and \datatool_measure_depth:Nn
. §2.8.3; 147
”, if supported by the current encoding, or “
.
” otherwise. §2.3.1; 33
”, if supported by the current encoding, or “
.
” otherwise. §2.3.1; 33
”, if supported by the current encoding, or “
m
” otherwise. §2.3.1; 35
”, if supported by the current encoding, or “
m
” otherwise. §2.3.1; 35
”, if supported by the current encoding, or “
N
” otherwise. §2.3.1; 35
”, if supported by the current encoding, or “
N
” otherwise. §2.3.1; 35
”, if supported by the current encoding, or “
M
” otherwise. §2.3.1; 40
”, if supported by the current encoding, or “
M
” otherwise. §2.3.1; 40
”, if supported by the current encoding, or “
Pts
” otherwise. §2.3.1; 35
”, if supported by the current encoding, or “
Pts
” otherwise. §2.3.1; 35
”, if supported by the current encoding, or “
P
” otherwise. §2.3.1; 38
”, if supported by the current encoding, or “
P
” otherwise. §2.3.1; 38
post-head
key. §3.7.2; 259
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 32
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 32
region-currency
option, which should be checked by region files. §2.3.2; 45
region-number-chars
option, which should be checked by region files. §2.3.2; 45
”, if supported by the current encoding, or “
R
” otherwise. §2.3.1; 41
”, if supported by the current encoding, or “
R
” otherwise. §2.3.1; 41
”, if supported by the current encoding, or “
Rs
” otherwise. §2.3.1; 35
”, if supported by the current encoding, or “
Rs
” otherwise. §2.3.1; 36
”, if supported by the current encoding, or “
S
” otherwise. §2.3.1; 36
”, if supported by the current encoding, or “
S
” otherwise. §2.3.1; 36
short-caption
key. §3.7.2; 259
”, if supported by the current encoding, or “
c
” otherwise. §2.3.1; 41
”, if supported by the current encoding, or “
c
” otherwise. §2.3.1; 42
”, if supported by the current encoding, or “
Sm
” otherwise. §2.3.1; 39
”, if supported by the current encoding, or “
Sm
” otherwise. §2.3.1; 39
csv-content
=literal setting. §3.15.2; 349
”, if supported by the current encoding, or “
T
” otherwise. §2.3.1; 39
”, if supported by the current encoding, or “
T
” otherwise. §2.3.1; 40
”, if supported by the current encoding, or “
T
” otherwise. §2.3.1; 37
”, if supported by the current encoding, or “
T
” otherwise. §2.3.1; 37
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 40
”, if supported by the current encoding, or “
L
” otherwise. §2.3.1; 40
”, if supported by the current encoding, or “
W
” otherwise. §2.3.1; 36
”, if supported by the current encoding, or “
W
” otherwise. §2.3.1; 36
”, if supported by the current encoding, or “
Y
” otherwise. §2.3.1; 32
”, if supported by the current encoding, or “
Y
” otherwise. §2.3.1; 33
\printterms
that expands to the current entry’s Location value. §8.9.1; 616
\printterms
that expands to the current entry’s Long value. §8.9.1; 615
\printterms
that expands to the current entry’s LongPlural value. §8.9.1; 615
\newperson
hooks. §9.7.4; 656
M[link]
\malelabels
expanded to the comma-separated list of recognised male gender labels. This command was replaced with \g_person_male_label_clist
variable in version 3.0 to reduce the possibility of a command name clash. Now only available with rollback. Use \PersonSetMaleLabels
to reset the list or \PersonAddMaleLabel
to append to the list. §9.4; 629
N[link]
\printterms
that expands to the current entry’s Name value. §8.9.1; 615
\newterm
. §8.7; 602
anon
. The may be “unknown” or empty, if not known, or a valid gender label. The starred form \newperson*
uses a = interface. §9.3; 626
anon
. §9.3; 626
\newterm
when creating a label. §8.4.2; 593
\newterm
when creating a sort value. §8.4.3; 595
P[link]
\printterms
that expands to the current entry’s Parent value. §8.9.1; 616
\Peopleparent
. §9.5.0.1; Table 9.1
\peopleparent
. §9.5.0.1; Table 9.1
\peoplechild
but starts with a capital. §9.5.0.2; 638
\peopleobjpronoun
, but sentence-case. §9.5.0.1; 635
\peopleobjpronounii
, but sentence-case. §9.5.0.1; 635
\peopleparent
but starts with a capital. §9.5.0.2; 639
\peoplepossadj
, but sentence-case. §9.5.0.1; 636
\peoplepossadjii
, but sentence-case. §9.5.0.1; 637
\peopleposspronoun
, but sentence-case. §9.5.0.1; 637
\peopleposspronounii
, but sentence-case. §9.5.0.1; 638
\peoplepronoun
, but sentence-case. §9.5.0.1; 634
\peoplepronounii
, but sentence-case. §9.5.0.1; 634
\peoplesibling
but starts with a capital. §9.5.0.2; 639
\personchild
but starts with a capital. §9.5.0.2; 638
\persongender
but starts with a capital.
\person_gender_case:Nnnnnn
but issues an error for the invalid case and treats it as unknown. §9.7.1; 652
\person_gender_case:Nnnnn
but the gender label is supplied as a token list. §9.7.1; 652
\tl_if_eq:NNTF
) against the constants \c_person_male_label_tl
, \c_person_female_label_tl
, \c_person_nonbinary_label_tl
, and \c_person_unknown_label_tl
and does the applicable case or if no match. §9.7.1; 651
\person_gender_case:Nnnnnn
but the gender label is supplied as a token list. §9.7.1; 652
\PersonTotalCount
is equal to \PersonFemaleCount
. §9.7.1; 651
\PersonTotalCount
is equal to \PersonMaleCount
. §9.7.1; 650
\PersonTotalCount
is equal to \PersonNonBinaryCount
. §9.7.1; 651
\PersonTotalCount
is equal to \PersonUnknownGenderCount
. §9.7.1; 651
\person_language_all_text:n
but converts to sentence case. §9.7.3; 656
plural
) if more than one person is defined otherwise uses the singular form . §9.7.3; 656
\person_language_text:nn
but converts the text to sentence case. §9.7.3; 656
\newperson
. §9.7.4; 657
\newperson
. §9.7.4; 657
\personobjpronoun
, but sentence-case. §9.5.0.1; 635
\personobjpronounii
, but sentence-case. §9.5.0.1; 635
\personparent
but starts with a capital. §9.5.0.2; 638
\personpossadj
, but sentence-case. §9.5.0.1; 636
\personpossadjii
, but sentence-case. §9.5.0.1; 636
\personposspronoun
, but sentence-case. §9.5.0.1; 637
\personposspronounii
, but sentence-case. §9.5.0.1; 637
\personpronoun
, but sentence-case. §9.5.0.1; 632
\personpronounii
, but sentence-case. §9.5.0.1; 634
\removeperson
and \removepeople
. §9.7.4; 657
\personsibling
but starts with a capital. §9.5.0.2; 639
\printterms
that expands to the current entry’s Plural value. §8.9.1; 616
\newterm
. §8.9.2; 616
\twocolumn
was issued by \printterms
and two-column mode wasn’t already in effect. §8.8; 607
R[link]
S[link]
\printterms
that expands to the current entry’s See value. §8.9.1; 616
\printterms
that expands to the current entry’s SeeAlso value. §8.9.1; 616
\alsoname
if that is defined or to “see also” otherwise. §8.8.1; 610
\printterms
that expands to the current entry’s Short value. §8.9.1; 615
\printterms
that expands to the current entry’s ShortPlural value. §8.9.1; 616
\Peoplesibling
. §9.5.0.1; Table 9.1
\peoplesibling
. §9.5.0.1; Table 9.1
\printterms
that expands to the current entry’s Sort value. §8.9.1; 616
\printterms
that expands to the current entry’s Symbol value. §8.9.1; 615
T[link]
\printterms
that expands to the current entry’s Text value. §8.9.1; 616
\Peopleobjpronounii
. §9.5.0.1; Table 9.1
\peopleobjpronounii
. §9.5.0.1; Table 9.1
\Peoplepossadj
. §9.5.0.1; Table 9.1
\peoplepossadj
. §9.5.0.1; Table 9.1
\Peopleposspronoun
. §9.5.0.1; Table 9.1
\peopleposspronoun
. §9.5.0.1; Table 9.1
\Peopleobjpronoun
. §9.5.0.1; Table 9.1
\peopleobjpronoun
. §9.5.0.1; Table 9.1
\Peoplepronoun
. §9.5.0.1; Table 9.1
\peoplepronoun
. §9.5.0.1; Table 9.1
U[link]
\printterms
that expands to the current entry’s Used value. §8.9.1; 615
\useentry
but the text is converted to uppercase. §8.5; 596
\useentry
but the text is converted to sentence case. §8.5; 596
\printterms
. §8.5; 595
\USEentry
but doesn’t create a hyperlink. §8.5; 596
\Useentry
but doesn’t create a hyperlink. §8.5; 596
\useentry
but doesn’t create a hyperlink. §8.5; 596
V[link]
X[link]
\dtlgetrowindex
but expands the value. §3.16; 366
\DTLinitials
. §2.8.2; 140
Y[link]
\Peoplepronounii
. §9.5.0.1; Table 9.1
\peoplepronounii
. §9.5.0.1; Table 9.1
\Peoplepossadjii
. §9.5.0.1; Table 9.1
\peoplepossadjii
. §9.5.0.1; Table 9.1
\Peopleposspronounii
. §9.5.0.1; Table 9.1
\peopleposspronounii
. §9.5.0.1; Table 9.1
Environment Summary[link]
\DTLforeach
. §3.8.2; 293
\DTLforeach*
. §3.8.2; 294
\dtlgforint
where leading and trailing spaces are trimmed from the environment body. §3.16.2; 372
\dtlgforint
where leading and trailing spaces aren’t trimmed from the environment body. §3.16.2; 372
but leading and trailing spaces are trimmed from the body. §3.8.1; 286
\DTLmapdata
[ ]{ }Package Option Summary[link]
\TrackLanguageTag
) and will load the corresponding localisation files if they are installed. §2.1; 10
\directlua
is available, in which case the default is lua. §2.1; 8
\directlua
for floating point arithmetic. 8
Index[link]
Symbols[link]
@[link]
A[link]
B[link]
C[link]
,
D[link]
\dtlcurrentrow
§3.16.1; 212, 214, 216, 219, 244, 296, 318, 320, 367, 368–370, 684–686, 690, 699, 716, 717, 758, 759, 768\DTLdisplaylongdb
§3.7; 223, 242, 241–260, 305, 683, 684, 690, 695, 697, 705, 706, 707, 708, 735, 751, 757, 767\DTLforeach
§3.8.2; 211, 219, 221, 238, 264, 285, 286, 288, 293–298, 301, 302, 304, 318, 366, 369, 373, 390, 393, 395, 444, 447, 522, 536, 545, 573, 685, 694, 698, 699, 711, 712, 729, 730, 732, 758–760, 820\DTLforeachbibentry
§7.8; 522, 532, 538, 539, 545, 546, 548, 549, 567, 682, 691–693, 712, 713, 728, 774\dtlletterindexcompare
§2.9.5.1; 162, 163, 165, 166, 169, 173, 174, 670, 677, 681, 741, 765, \dtlwordindexcompare
\DTLmapdata
edit options\DTLmultibarchart
§5; 396, 397, 402–405, 407, 410, 411, 415, 423, 424, 439, 441, 442, 444–446, 686, 688, 707, 708, 710, 748, 769\DTLparse
§2.2.3; 10, 11, 14, 16, 17, 19, 26, 44, 62, 63, 114, 116, 119, 137, 228, 273, 703, 751, 770, 772\DTLread
§3.15.3; 177, 181, 184, 188, 200, 203, 232, 239, 336–339, 344, 346–348, 350–358, 359, 360, 705, 740, 757\DTLsortdata
§3.14.1; 162, 164, 223, 325, 326–328, 334, 335, 522, 534, 539, 556, 574, 578, 612–614, 620, 686, 764\DTLsortdata
column criteria options\DTLsortwordlist
§2.9.5; 51, 150, 151, 156, 157, 159, 162–167, 171, 173, 174, 325, 663, 670, 677, 681, 686, 764, 765, 769\dtlwordindexcompare
§2.9.5.1; 163, 165, 166, 169, 173, 174, 613, 670, 677, 681, 765, 771, \dtlwordindexcompare
E[link]
F[link]
G[link]
H[link]
I[link]
J[link]
L[link]
M[link]
N[link]
O[link]
P[link]
R[link]
S[link]
T[link]
U[link]
V[link]
W[link]
X[link]
Y[link]
1Many thanks to Morten Høgholm for providing the new code.
2Thanks to Morten Høgholm for the design.