summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/datatool
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-01-15 23:01:04 +0000
committerKarl Berry <karl@freefriends.org>2013-01-15 23:01:04 +0000
commit6d3800d3b164704c4038f84408b27f759a4ea744 (patch)
tree6d56ebd38457cb5f2d7bcbe628157f861fecdaae /Master/texmf-dist/source/latex/datatool
parent607c25d782c2e57a60ab2f2ecf30c12e238b44ec (diff)
datatool (15jan13)
git-svn-id: svn://tug.org/texlive/trunk@28844 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/datatool')
-rw-r--r--Master/texmf-dist/source/latex/datatool/datatool.dtx7217
-rw-r--r--Master/texmf-dist/source/latex/datatool/datatool.ins8
2 files changed, 7017 insertions, 208 deletions
diff --git a/Master/texmf-dist/source/latex/datatool/datatool.dtx b/Master/texmf-dist/source/latex/datatool/datatool.dtx
index 32bb1dc4705..2b0a0fe9044 100644
--- a/Master/texmf-dist/source/latex/datatool/datatool.dtx
+++ b/Master/texmf-dist/source/latex/datatool/datatool.dtx
@@ -6,6 +6,7 @@
% -src "datatool-fp.sty\Z=>datatool-fp.sty"
% -src "datatool-pgfmath.sty\Z=>datatool-pgfmath.sty"
% -src "datatool.sty\Z=>datatool.sty"
+% -src "datagidx.sty\Z=>datagidx.sty"
% -src "databib.sty\Z=>databib.sty"
% -src "databar.sty\Z=>databar.sty"
% -src "datapie.sty\Z=>datapie.sty"
@@ -16,7 +17,7 @@
% -author "Nicola Talbot"
% -codetitle ""
% datatool
-% Created on 2012/10/6 20:31
+% Created on 2013/1/15 15:04
%\fi
%\iffalse
%<*package>
@@ -39,11 +40,11 @@
%\fi
% \iffalse
% Doc-Source file to use with LaTeX2e
-% Copyright (C) 2012 Nicola Talbot, all rights reserved.
+% Copyright (C) 2013 Nicola Talbot, all rights reserved.
% \fi
% \iffalse
%<*driver>
-\documentclass[report]{nlctdoc}
+\documentclass[report,widecs]{nlctdoc}
\iffalse
datatool-manual.tex is a stub file used by makedtx to create
@@ -63,7 +64,7 @@ datatool.dtx
\doxitem{Counter}{counter}{counters}
\doxitem{Option}{option}{package options}
-\CheckSum{17056}
+\CheckSum{22429}
\RecordChanges
\PageIndex
@@ -76,11 +77,11 @@ datatool.dtx
%\fi
%\MakeShortVerb{"}
%
-%\title{Documented Code for datatool v2.11}
+%\title{Documented Code for datatool v2.13}
%\author{Nicola L. C. Talbot\\
%\url{http://www.dickimaw-books.com/}}
%
-%\date{2012-09-25}
+%\date{2013-01-15}
%\maketitle
%
%\pagenumbering{roman}
@@ -115,7 +116,7 @@ datatool.dtx
%
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{datatool-base}[2012/10/06 v2.12 (NLCT)]
+\ProvidesPackage{datatool-base}[2013/01/15 v2.13 (NLCT)]
% \end{macrocode}
% Required packages:
% \begin{macrocode}
@@ -237,6 +238,59 @@ datatool.dtx
% \end{macrocode}
%\end{macro}
%
+%\begin{macro}{\dtlifintopenbetween}
+%\begin{definition}
+%\cs{dtlifintopenbetween}\marg{num}\marg{min}\marg{max}\marg{true
+%part}\marg{false part}
+%\end{definition}
+% If we're dealing with integers it's more efficient to use \TeX's
+% \cs{ifnum}.
+% \begin{macrocode}
+\newcommand{\dtlifintopenbetween}[5]{%
+ \ifnum#1>#2\relax
+% \end{macrocode}
+% Greater than minimum value. Is it less than the maximum?
+% \begin{macrocode}
+ \ifnum#1<#3\relax
+ #4%
+ \else
+ #5%
+ \fi
+ \else
+ #5%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtlifintclosedbetween}
+%\begin{definition}
+%\cs{dtlifintclosedbetween}\marg{num}\marg{min}\marg{max}\marg{true
+%part}\marg{false part}
+%\end{definition}
+% If we're dealing with integers it's more efficient to use \TeX's
+% \cs{ifnum}.
+% \begin{macrocode}
+\newcommand{\dtlifintclosedbetween}[5]{%
+ \dtlifintopenbetween{#1}{#2}{#3}{#4}%
+ {%
+% \end{macrocode}
+% Check end points.
+% \begin{macrocode}
+ \ifnum#1=#2\relax
+ #4%
+ \else
+ \ifnum#1=#3\relax
+ #4%
+ \else
+ #5%
+ \fi
+ \fi
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
%\begin{macro}{\long@collect@body}
% Need long versions of \isty{amsmath}'s \cs{collect@body}. These macros are
% adapted from the macros defined by \sty{amsmath}.
@@ -909,12 +963,12 @@ datatool.dtx
%
%\begin{macro}{\@dtl@decimaltolocalefrac}
% Convert the fractional part (store in \cs{@dtl@fracpart})
-% \begin{macrocode}
-% \end{macrocode}
+% \begin{macrocode}
\def\@dtl@decimaltolocalefrac#1.\relax{%
\def\@dtl@fracpart{#1}%
\@dtl@choptrailingzeroes{\@dtl@fracpart}%
}
+% \end{macrocode}
%\end{macro}
%
%\begin{macro}{\DTLdecimaltocurrency}
@@ -2807,20 +2861,30 @@ datatool.dtx
\newcommand*{\dtl@setcharcode}[2]{%
\ifstrempty{#1}%
{%
+% \end{macrocode}
+% Empty argument. Set code to $-1$.
+% \begin{macrocode}
#2=-1\relax
}%
{%
- \ifx#1\space\relax
+ \ifx#1\@dtl@wordbreak\relax
+% \end{macrocode}
+% Reached a word break. Set to character code of a space.
+%\changes{2.13}{2013-01-15}{change from check for space and tilde to check
+%for \cs{@dtl@wordbreak}}
+% \begin{macrocode}
#2=`\ \relax
\else
- \ifx#1~\relax
- #2=`\ \relax
+ \ifcat\noexpand#1\relax
+% \end{macrocode}
+% Argument is a control sequence, so set to 0.
+% \begin{macrocode}
+ #2=0\relax
\else
- \ifcat\noexpand#1\relax
- #2=-1\relax
- \else
- #2=`#1\relax
- \fi
+% \end{macrocode}
+% Argument is a character, so set to the character code.
+% \begin{macrocode}
+ #2=`#1\relax
\fi
\fi
}%
@@ -2840,19 +2904,38 @@ datatool.dtx
\newcommand*{\dtl@setlccharcode}[2]{%
\ifstrempty{#1}%
{%
+% \end{macrocode}
+% String is empty so set to $-1$.
+% \begin{macrocode}
#2=-1\relax
}%
{%
- \ifx#1\space\relax
+% \end{macrocode}
+% Do we have a word break?
+%\changes{2.13}{2013-01-15}{changed to test for \cs{@dtl@wordbreak} instead
+%of \cs{space} and tilde}
+% \begin{macrocode}
+ \ifx#1\@dtl@wordbreak\relax
#2=`\ \relax
\else
- \ifx#1~\relax
- #2=`\ \relax
+ \ifcat\noexpand#1\relax%
+% \end{macrocode}
+% Argument is a control sequence, so set to 0.
+% \begin{macrocode}
+ #2=0\relax
\else
- \ifcat\noexpand#1\relax%
- #2=-1\relax
- \else
- #2=\lccode`#1\relax
+% \end{macrocode}
+% Argument is a character, so set to the lower case code.
+% \begin{macrocode}
+ #2=\lccode`#1\relax
+% \end{macrocode}
+% If the result is zero, which means the character doesn't have a lower case
+% equivalent. So set to the character code.
+%\changes{2.13}{2013-01-15}{fixed bug where characters without a lower case
+%equivalent were all considered equal}
+% \begin{macrocode}
+ \ifnum#2=0\relax
+ #2=`#1\relax
\fi
\fi
\fi
@@ -2874,90 +2957,687 @@ datatool.dtx
{%
\ifdefempty{\@dtl@argB}%
{%
+% \end{macrocode}
+% Both are empty, so they are equal.
+% \begin{macrocode}
#1=0\relax
}%
{%
+% \end{macrocode}
+% The first string is empty, but the second isn't. Therefore the
+% first string is less than the second string.
+% \begin{macrocode}
#1=-1\relax
}%
}%
{%
\ifdefempty{\@dtl@argB}%
{%
+% \end{macrocode}
+% The second string is empty, but the first isn't. Therefore the
+% first string is greater than the second string.
+% \begin{macrocode}
#1=1\relax
}%
{%
- \DTLsubstituteall{\@dtl@argA}{ }{\space }%
- \DTLsubstituteall{\@dtl@argB}{ }{\space }%
+% \end{macrocode}
+% Identify all word breaks.
+%\changes{2.13}{2013-01-15}{now using \cs{dtl@setwordbreaksnohyphens} to
+%deal with spaces}
+% \begin{macrocode}
+ \dtl@setwordbreaksnohyphens{\@dtl@argA}{\@dtl@wordbreak}%
+ \let\@dtl@argA\dtl@string
+ \dtl@setwordbreaksnohyphens{\@dtl@argB}{\@dtl@wordbreak}%
+ \let\@dtl@argB\dtl@string
+% \end{macrocode}
+% Get the first object and the remaining text.
+% \begin{macrocode}
\expandafter\dtl@getfirst\@dtl@argA\end
\let\dtl@firstA=\dtl@first
\let\dtl@restA=\dtl@rest
\expandafter\dtl@getfirst\@dtl@argB\end
\let\dtl@firstB=\dtl@first
\let\dtl@restB=\dtl@rest
- \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}{%
- \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}{%
- \expandafter\dtl@setlccharcode\expandafter{\dtl@firstA}{\dtl@codeA}%
- \expandafter\dtl@setlccharcode\expandafter{\dtl@firstB}{\dtl@codeB}%
- \ifnum\dtl@codeA=-1\relax
- \ifnum\dtl@codeB=-1\relax
- \protected@edef\dtl@donext{%
- \noexpand\dtlicompare{\noexpand#1}{\dtl@restA}{\dtl@restB}}%
- \dtl@donext
- \else
- \protected@edef\dtl@donext{%
- \noexpand\dtlicompare
- {\noexpand#1}{\dtl@restA}{\dtl@firstB\dtl@restB}}%
- \dtl@donext
- \fi
+% \end{macrocode}
+% Is the first object of \meta{string1} a single character or a group?
+% \begin{macrocode}
+ \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}%
+ {%
+% \end{macrocode}
+% It's a single character. Is the first object of \meta{string2} a
+% single character or a group?
+% \begin{macrocode}
+ \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}%
+ {%
+% \end{macrocode}
+% Both are a single character. Get the lower case character code.
+% \begin{macrocode}
+ \expandafter\dtl@setlccharcode\expandafter{\dtl@firstA}{\dtl@codeA}%
+ \expandafter\dtl@setlccharcode\expandafter{\dtl@firstB}{\dtl@codeB}%
+ \ifnum\dtl@codeA=-1\relax
+ \ifnum\dtl@codeB=-1\relax
+ \protected@edef\dtl@donext{%
+ \noexpand\dtlicompare{\noexpand#1}{\dtl@restA}{\dtl@restB}}%
+ \dtl@donext
+ \else
+ \protected@edef\dtl@donext{%
+ \noexpand\dtlicompare
+ {\noexpand#1}{\dtl@restA}{\dtl@firstB\dtl@restB}}%
+ \dtl@donext
+ \fi
+ \else
+ \ifnum\dtl@codeB=-1\relax
+ \protected@edef\dtl@donext{%
+ \noexpand\dtlicompare
+ {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@restB}}%
+ \dtl@donext
+ \else
+ \ifnum\dtl@codeA<\dtl@codeB
+ #1=-1\relax
+ \else
+ \ifnum\dtl@codeA>\dtl@codeB
+ #1=1\relax
+ \else
+ \ifdefempty{\dtl@restA}%
+ {%
+ \ifdefempty{\dtl@restB}%
+ {%
+ #1=0\relax
+ }%
+ {%
+ #1=-1\relax
+ }%
+ }%
+ {%
+ \ifdefempty{\restB}%
+ {%
+ #1=1\relax
+ }%
+ {%
+ \protected@edef\dtl@donext{%
+ \noexpand\dtlicompare
+ {\noexpand#1}{\dtl@restA}{\dtl@restB}}%
+ \dtl@donext
+ }%
+ }%
+ \fi
+ \fi
+ \fi
+ \fi
+ }%
+ {%
+% \end{macrocode}
+% The first object in \meta{string1} is a single character, but the
+% first object in \meta{string2} isn't a single character.
+% \begin{macrocode}
+ \protected@edef\dtl@donext{%
+ \noexpand\dtlicompare
+ {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
+ \dtl@donext
+ }%
+ }%
+ {%
+% \end{macrocode}
+% Neither object is a single character.
+% \begin{macrocode}
+ \protected@edef\dtl@donext{%
+ \noexpand\dtlicompare
+ {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
+ \dtl@donext
+ }%
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtlwordindexcompare}
+% Word breaks come before all other letters of the alphabet.
+% \begin{macrocode}
+\newcommand*{\dtlwordindexcompare}[3]{%
+ \@dtldictcompare{#1}{#2}{#3}{\@dtl@wordbreak}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtlletterindexcompare}
+% Word breaks are ignored.
+% \begin{macrocode}
+\newcommand*{\dtlletterindexcompare}[3]{%
+ \@dtldictcompare{#1}{#2}{#3}{}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@dtldictcompare}
+% Word or letter compare. Fourth argument should be
+% \cs{@dtl@wordbreak} for word compare or empty for letter compare.
+% \begin{macrocode}
+\newcommand*{\@dtldictcompare}[4]{%
+ \dtl@subnobrsp{#2}{\@dtl@argA}%
+ \dtl@subnobrsp{#3}{\@dtl@argB}%
+ \ifdefempty{\@dtl@argA}%
+ {%
+ \ifdefempty{\@dtl@argB}%
+ {%
+ #1=0\relax
+ }%
+ {%
+ #1=-1\relax
+ }%
+ }%
+ {%
+ \ifdefempty{\@dtl@argB}%
+ {%
+ #1=1\relax
+ }%
+ {%
+% \end{macrocode}
+% Alphabetizing continues until a comma indicates inverted order.
+% This assumes that an actual comma indicates that the comma forms part of
+% the text (e.g.\ in a title of a play). Inversion commas should be
+% indicated using commands such as \ics{datatoolpersoncomma}.
+% There are three types of
+% inverted order: people, places and subjects (concepts or objects).
+% We also need to treat parenthetical material in a similar way.
+% Find if the first string has an inverted order.
+% \begin{macrocode}
+ \expandafter\DTLsplitstring\expandafter
+ {\@dtl@argA}{\datatoolpersoncomma}{\@dtl@beforepart}{\@dtl@afterpart}%
+ \ifdefempty{\@dtl@replaced}%
+ {%
+ \expandafter\DTLsplitstring\expandafter
+ {\@dtl@argA}{\datatoolplacecomma}{\@dtl@beforepart}{\@dtl@afterpart}%
+ \ifdefempty{\@dtl@replaced}%
+ {%
+ \expandafter\DTLsplitstring\expandafter
+ {\@dtl@argA}{\datatoolsubjectcomma}{\@dtl@beforepart}{\@dtl@afterpart}%
+ \ifdefempty{\@dtl@replaced}%
+ {%
+ \expandafter\DTLsplitstring\expandafter
+ {\@dtl@argA}{\datatoolparenstart}{\@dtl@beforepart}{\@dtl@afterpart}%
+ \ifdefempty{\@dtl@replaced}%
+ {%
+ \def\@dtl@A@comma{0}%
+ \let\@dtl@A@before\@dtl@argA
+ \def\@dtl@A@after{}%
+ }%
+ {%
+ \let\@dtl@A@comma\@dtl@replaced
+ \let\@dtl@A@before\@dtl@beforepart
+ \let\@dtl@A@after\@dtl@afterpart
+ }%
+ }%
+ {%
+ \let\@dtl@A@comma\@dtl@replaced
+ \let\@dtl@A@before\@dtl@beforepart
+ \let\@dtl@A@after\@dtl@afterpart
+ }%
+ }%
+ {%
+ \let\@dtl@A@comma\@dtl@replaced
+ \let\@dtl@A@before\@dtl@beforepart
+ \let\@dtl@A@after\@dtl@afterpart
+ }%
+ }%
+ {%
+ \let\@dtl@A@comma\@dtl@replaced
+ \let\@dtl@A@before\@dtl@beforepart
+ \let\@dtl@A@after\@dtl@afterpart
+ }%
+% \end{macrocode}
+% Now find if the second string has an inverted order.
+% \begin{macrocode}
+ \expandafter\DTLsplitstring\expandafter
+ {\@dtl@argB}{\datatoolpersoncomma}{\@dtl@beforepart}{\@dtl@afterpart}%
+ \ifdefempty{\@dtl@replaced}%
+ {%
+ \expandafter\DTLsplitstring\expandafter
+ {\@dtl@argB}{\datatoolplacecomma}{\@dtl@beforepart}{\@dtl@afterpart}%
+ \ifdefempty{\@dtl@replaced}%
+ {%
+ \expandafter\DTLsplitstring\expandafter
+ {\@dtl@argB}{\datatoolsubjectcomma}{\@dtl@beforepart}{\@dtl@afterpart}%
+ \ifdefempty{\@dtl@replaced}%
+ {%
+ \expandafter\DTLsplitstring\expandafter
+ {\@dtl@argB}{\datatoolparenstart}{\@dtl@beforepart}{\@dtl@afterpart}%
+ \ifdefempty{\@dtl@replaced}%
+ {%
+ \def\@dtl@B@comma{0}%
+ \let\@dtl@B@before\@dtl@argB
+ \def\@dtl@B@after{}%
+ }%
+ {%
+ \let\@dtl@B@comma\@dtl@replaced
+ \let\@dtl@B@before\@dtl@beforepart
+ \let\@dtl@B@after\@dtl@afterpart
+ }%
+ }%
+ {%
+ \let\@dtl@B@comma\@dtl@replaced
+ \let\@dtl@B@before\@dtl@beforepart
+ \let\@dtl@B@after\@dtl@afterpart
+ }%
+ }%
+ {%
+ \let\@dtl@B@comma\@dtl@replaced
+ \let\@dtl@B@before\@dtl@beforepart
+ \let\@dtl@B@after\@dtl@afterpart
+ }%
+ }%
+ {%
+ \let\@dtl@B@comma\@dtl@replaced
+ \let\@dtl@B@before\@dtl@beforepart
+ \let\@dtl@B@after\@dtl@afterpart
+ }%
+% \end{macrocode}
+% Get the first letter and find out if it's a letter, digit or
+% symbol.
+% \begin{macrocode}
+ \expandafter\dtl@ifcasechargroup\@dtl@A@before\dtl@end@ifcasechargroup
+ {\def\@dtl@A@chargroup{2}}%
+ {\def\@dtl@A@chargroup{1}}%
+ {\def\@dtl@A@chargroup{0}}%
+ \expandafter\dtl@ifcasechargroup\@dtl@B@before\dtl@end@ifcasechargroup
+ {\def\@dtl@B@chargroup{2}}%
+ {\def\@dtl@B@chargroup{1}}%
+ {\def\@dtl@B@chargroup{0}}%
+% \end{macrocode}
+% Are they in the same group?
+% \begin{macrocode}
+ \ifnum\@dtl@A@chargroup<\@dtl@B@chargroup
+ #1=-1\relax
\else
- \ifnum\dtl@codeB=-1\relax
- \protected@edef\dtl@donext{%
- \noexpand\dtlicompare
- {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@restB}}%
- \dtl@donext
+ \ifnum\@dtl@A@chargroup>\@dtl@B@chargroup
+ #1=1\relax
\else
- \ifnum\dtl@codeA<\dtl@codeB
- #1=-1\relax
- \else
- \ifnum\dtl@codeA>\dtl@codeB
- #1=1\relax
+% \end{macrocode}
+% In the same group. Which group are they in?
+% \begin{macrocode}
+ \ifcase\@dtl@A@chargroup
+% \end{macrocode}
+% Symbol group
+% \begin{macrocode}
+ \protected@edef\dtl@donext{%
+ \noexpand\dtlcompare
+ {\noexpand#1}{\@dtl@A@before}{\@dtl@B@before}}%
+ \dtl@donext
+% \end{macrocode}
+% Number.
+% \begin{macrocode}
+ \or
+ \ifnum\@dtl@A@before<\@dtl@B@before\relax
+ #1=-1\relax
\else
- \ifdefempty{\dtl@restA}%
- {%
- \ifdefempty{\dtl@restB}%
- {%
- #1=0\relax
- }%
- {%
- #1=-1\relax
- }%
- }%
- {%
- \ifdefempty{\restB}%
- {%
- #1=1\relax
- }%
- {%
- \protected@edef\dtl@donext{%
- \noexpand\dtlicompare
- {\noexpand#1}{\dtl@restA}{\dtl@restB}}%
- \dtl@donext
- }%
- }%
+ \ifnum\@dtl@A@before>\@dtl@B@before\relax
+ #1=1\relax
+ \else
+ #1=0\relax
+ \fi
+ \fi
+ \or
+% \end{macrocode}
+% Word or phrase.
+% \begin{macrocode}
+ \@dtlwordindexcompare{#1}{\@dtl@A@before}{\@dtl@B@before}
+ {\dtlicomparewords}{#4}%
+% \end{macrocode}
+% If they are equal, do we have an inverted order?
+% \begin{macrocode}
+ \ifnum#1=0\relax
+% \end{macrocode}
+% Temporarily redefine the inversion commas to numbers to make the
+% comparisons easier.
+% \begin{macrocode}
+ \let\@org@dtl@person@comma\datatoolpersoncomma
+ \let\@org@dtl@place@comma\datatoolplacecomma
+ \let\@org@dtl@subject@comma\datatoolsubjectcomma
+ \let\@org@dtl@paren@start\datatoolparenstart
+% \end{macrocode}
+% People first, then places, then subjects, then no inversion, then
+% parenthetical.
+% \begin{macrocode}
+ \def\datatoolpersoncomma{3}%
+ \def\datatoolplacecomma{2}%
+ \def\datatoolsubjectcomma{1}%
+ \def\datatoolparenstart{-1}%
+% \end{macrocode}
+% Now compare:
+% \begin{macrocode}
+ \ifnum\@dtl@A@comma>\@dtl@B@comma\relax
+ #1=-1\relax
+ \else
+ \ifnum\@dtl@A@comma<\@dtl@B@comma\relax
+ #1=1\relax
+ \else
+% \end{macrocode}
+% They are the same type. First do a reverse case sensitive comparison.
+% \begin{macrocode}
+ \@dtlwordindexcompare{#1}{\@dtl@B@before}{\@dtl@A@before}
+ {\dtlcomparewords}{#4}%
+% \end{macrocode}
+% Are they still equal?
+% \begin{macrocode}
+ \ifnum#1=0\relax
+% \end{macrocode}
+% So sort on inversion.
+% \begin{macrocode}
+ \@dtlwordindexcompare{#1}{\@dtl@A@after}{\@dtl@B@after}
+ {\dtlicomparewords}{#4}%
+ \fi
+ \fi
+ \fi
+% \end{macrocode}
+% Restore original definitions.
+% \begin{macrocode}
+ \let\datatoolpersoncomma\@org@dtl@person@comma
+ \let\datatoolplacecomma\@org@dtl@place@comma
+ \let\datatoolsubjectcomma\@org@dtl@subject@comma
+ \let\datatoolparenstart\@org@dtl@paren@start
\fi
\fi
\fi
\fi
- }{%
- \protected@edef\dtl@donext{%
- \noexpand\dtlicompare
- {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
- \dtl@donext
- }}{%
- \protected@edef\dtl@donext{%
- \noexpand\dtlicompare
- {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
- \dtl@donext
+ }%
+ }%
+}%
+% \end{macrocode}
+%\end{macro}
+%
+% Need to indicate type of inversion.
+%\begin{macro}{\datatoolpersoncomma}
+% \begin{macrocode}
+\newcommand*{\datatoolpersoncomma}{,\space}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datatoolplacecomma}
+% \begin{macrocode}
+\newcommand*{\datatoolplacecomma}{,\space}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datatoolsubjectcomma}
+% \begin{macrocode}
+\newcommand*{\datatoolsubjectcomma}{,\space}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datatoolparenstart}
+% \begin{macrocode}
+\newcommand*{\datatoolparenstart}{\space}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\@dtlwordindexcompare}
+%\begin{definition}
+%\cs{@dtlwordindexcompare}\marg{count}\marg{cs A}\marg{cs
+%B}\marg{word comparison handler}\marg{word break replacement}
+%\end{definition}
+% \begin{macrocode}
+\newcommand*{\@dtlwordindexcompare}[5]{%
+% \end{macrocode}
+% Word or phrase. Replace word breaks.
+% \begin{macrocode}
+ \dtl@setwordbreaks{#2}{#5}%
+ \let#2\dtl@string
+% \end{macrocode}
+% And again for the second string.
+% \begin{macrocode}
+ \dtl@setwordbreaks{#3}{}%
+ \let#3\dtl@string
+% \end{macrocode}
+% Now compare both strings.
+% \begin{macrocode}
+% \@dtl@dict@compare{#1}{#2}{#3}{#4}%
+ \edef\@dtl@do@compare{%
+ \noexpand#4{\noexpand#1}%
+ {\expandonce#2}{\expandonce#3}%
+ }%
+ \@dtl@do@compare
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@dtl@dict@compare}
+%\begin{definition}
+%\cs{@dtl@dict@compare}\marg{count}\marg{cs A}\marg{cs
+%B}\marg{word comparison handler}
+%\end{definition}
+% Now that all the word breaks have been identified with
+% \cs{@dtl@wordbreak} compare both strings.
+% \begin{macrocode}
+\newcommand*{\@dtl@dict@compare}[4]{%
+% \end{macrocode}
+% Are either empty?
+% \begin{macrocode}
+ \ifdefempty{#2}%
+ {%
+% \end{macrocode}
+% A is empty. Is B empty?
+% \begin{macrocode}
+ \ifdefempty{#3}%
+ {%
+% \end{macrocode}
+% Both are empty.
+% \begin{macrocode}
+ #1=0\relax
+ }%
+ {%
+% \end{macrocode}
+% A is empty but B isn't
+% \begin{macrocode}
+ #1=-1\relax
+ }%
+ }%
+ {%
+% \end{macrocode}
+% A isn't empty. Is B empty?
+% \begin{macrocode}
+ \ifdefempty{#3}%
+ {%
+% \end{macrocode}
+% B is empty but A isn't.
+% \begin{macrocode}
+ #1=1\relax
+ }%
+ {%
+% \end{macrocode}
+% Neither are empty. Grab first word from A.
+% \begin{macrocode}
+ \expandafter\dtl@grabword#2\@dtl@endgrabword\dtl@A@first\dtl@A@remain
+% \end{macrocode}
+% Grab first word from B.
+% \begin{macrocode}
+ \expandafter\dtl@grabword#3\@dtl@endgrabword\dtl@B@first\dtl@B@remain
+% \end{macrocode}
+% Compare A and B.
+% \begin{macrocode}
+ \edef\@dtl@do@compare{%
+ \noexpand#4{\noexpand#1}%
+ {\expandonce\dtl@A@first}{\expandonce\dtl@B@first}%
+ }%
+ \@dtl@do@compare
+% \end{macrocode}
+% Are they the same?
+% \begin{macrocode}
+ \ifnum#1=0\relax
+% \end{macrocode}
+% They are, so compare on the next word.
+% \begin{macrocode}
+ \@dtl@dict@compare{#1}{\dtl@A@remain}{\dtl@B@remain}{#4}%
+ \fi
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtl@grabword}
+% Grab first word from phrase.
+% \begin{macrocode}
+\def\dtl@grabword#1\@dtl@wordbreak#2\@dtl@endgrabword#3#4{%
+ \def#3{#1}%
+ \def#4{#2}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtlicomparewords}
+%\begin{definition}
+%\cs{dtlicomparewords}\marg{count}\marg{word A}\marg{word B}
+%\end{definition}
+%This does a case insensitive comparison.
+% \begin{macrocode}
+\newcommand{\dtlicomparewords}[3]{%
+ \dtlicompare{#1}{#2}{#3}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtlcomparewords}
+%\begin{definition}
+%\cs{dtlcomparewords}\marg{count}\marg{word A}\marg{word B}
+%\end{definition}
+%This does a case sensitive comparison.
+% \begin{macrocode}
+\newcommand{\dtlcomparewords}[3]{%
+ \dtlcompare{#1}{#2}{#3}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtl@setwordbreaks}
+% Replace word breaks (space, \cs{space}, \cs{\space}, \verb|~| and
+% hyphen \texttt{-}) with the second argument (either
+% \cs{@dtl@wordbreak} for letter sort or nothing for word sort). Result is stored in
+% \cs{dtl@string}.
+% \begin{macrocode}
+\newcommand*{\dtl@setwordbreaks}[2]{%
+ \expandafter\dtl@subnobrsp\expandafter{#1}{\dtl@string}%
+ \DTLsubstituteall{\dtl@string}{~}{#2}%
+ \DTLsubstituteall{\dtl@string}{\ }{#2}%
+ \DTLsubstituteall{\dtl@string}{\space}{#2}%
+ \DTLsubstituteall{\dtl@string}{-}{#2}%
+% \end{macrocode}
+% Now deal with actual spaces.
+% \begin{macrocode}
+ \toks@{#2}%
+ \edef\dtl@do@setwordbreaks{%
+ \noexpand\@dtl@setwordbreaks{\the\toks@}\expandonce\dtl@string\space\noexpand\@nil}%
+ \def\dtl@string{}%
+ \dtl@do@setwordbreaks
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@dtl@setwordbreaks}
+% \begin{macrocode}
+\def\@dtl@setwordbreaks#1#2 #3{%
+ \def\dtl@tmp{#3}%
+ \ifx\@nnil\dtl@tmp
+% \end{macrocode}
+% Reached end of loop.
+% \begin{macrocode}
+ \let\@dtl@setwordbreaks@next\@gobbletwo
+ \appto\dtl@string{#2}%
+ \else
+ \let\@dtl@setwordbreaks@next\@dtl@setwordbreaks
+ \appto\dtl@string{#2#1}%
+ \fi
+ \@dtl@setwordbreaks@next{#1}#3%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@dtl@setwordbreaksnohyphens}
+% As \cs{dtl@setwordbreaks} but excludes hyphens.
+% \begin{macrocode}
+\newcommand*{\dtl@setwordbreaksnohyphens}[2]{%
+ \expandafter\dtl@subnobrsp\expandafter{#1}{\dtl@string}%
+ \DTLsubstituteall{\dtl@string}{~}{#2}%
+ \DTLsubstituteall{\dtl@string}{\ }{#2}%
+ \DTLsubstituteall{\dtl@string}{\space}{#2}%
+% \end{macrocode}
+% Now deal with actual spaces.
+% \begin{macrocode}
+ \toks@{#2}%
+ \edef\dtl@do@setwordbreaks{%
+ \noexpand\@dtl@setwordbreaks{\the\toks@}\expandonce\dtl@string\space\noexpand\@nil}%
+ \def\dtl@string{}%
+ \dtl@do@setwordbreaks
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@dtl@wordbreak}
+% \begin{macrocode}
+\newcommand*{\@dtl@wordbreak}{ }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtl@ifcasechargroup}
+% Determine if first character is a letter, a digit or a symbol.
+% \begin{macrocode}
+\def\dtl@ifcasechargroup#1#2\dtl@end@ifcasechargroup#3#4#5{%
+ \dtlifcasechargroup{#1}%
+ {#3}%
+ {%
+% \end{macrocode}
+% Starts with a digit. Is the whole thing an integer?
+% \begin{macrocode}
+ \DTLifint{#1#2}
+ {%
+ #4%
+ }%
+ {%
+% \end{macrocode}
+% No, it isn't. Consider it a string.
+% \begin{macrocode}
+ #3%
+ }%
+ }%
+ {#5}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{macro}
+%\begin{definition}
+%\cs{dtlifcasechargroup}\marg{char}\marg{case letter}\marg{case
+%digit}\marg{case symbol}
+%\end{definition}
+% \begin{macrocode}
+\newcommand*{\dtlifcasechargroup}[4]{%
+ \count@=`#1\relax
+ \dtlifintclosedbetween{\number\count@}{48}{57}%
+ {%
+% \end{macrocode}
+% It's a digit.
+% \begin{macrocode}
+ #3%
+ }%
+ {%
+ \dtlifintclosedbetween{\number\count@}{97}{122}%
+ {%
+% \end{macrocode}
+% Lower case letter
+% \begin{macrocode}
+ #2%
+ }%
+ {%
+ \dtlifintclosedbetween{\number\count@}{65}{90}%
+ {%
+% \end{macrocode}
+% Upper case letter
+% \begin{macrocode}
+ #2%
+ }%
+ {%
+% \end{macrocode}
+% Other
+% \begin{macrocode}
+ #4%
}%
}%
}%
@@ -2965,6 +3645,43 @@ datatool.dtx
% \end{macrocode}
%\end{macro}
%
+%\begin{macro}{\dtlparsewords}
+%\changes{2.13}{2013-01-15}{new}
+%\begin{definition}
+%\cs{dtlparsewords}\marg{phrase}\marg{handler cs}
+%\end{definition}
+% Iterates through the given phrase. Hyphens are considered word
+% boundaries.
+% \begin{macrocode}
+\newcommand*{\dtlparsewords}[2]{%
+ \dtl@subnobrsp{#1}{\dtl@string}%
+ \DTLsubstituteall{\dtl@string}{~}{ }%
+ \DTLsubstituteall{\dtl@string}{\ }{ }%
+ \DTLsubstituteall{\dtl@string}{\space}{ }%
+ \DTLsubstituteall{\dtl@string}{-}{ }%
+ \let\dtl@parsewordshandler#2\relax
+ \edef\dtl@donext{%
+ \noexpand\@dtl@parse@words\expandonce\dtl@string\space\noexpand\@nil}%
+ \dtl@donext
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@dtl@parse@words}
+% \begin{macrocode}
+\def\@dtl@parse@words#1 #2{%
+ \def\dtl@tmp{#2}%
+ \ifx\@nnil\dtl@tmp
+ \let\parse@wordsnext=\@gobble
+ \else
+ \let\parse@wordsnext=\@dtl@parse@words
+ \fi
+ \dlt@parsewordshandler{#1}%
+ \parse@wordsnext#2%
+}
+% \end{macrocode}
+%\end{macro}
+%
%\begin{macro}{\DTLifstringlt}
%\begin{definition}
%\cs{DTLifstringlt}\marg{string1}\marg{string2}\marg{true part}\marg{false part}
@@ -3235,9 +3952,9 @@ datatool.dtx
%\changes{1.01}{2007 Aug 17}{new}
% \begin{macrocode}
\newcommand*{\DTLifSubString}[4]{%
- \protected@edef\@dtl@tmp{\noexpand\dtl@testifsubstring
+ \protected@edef\@dtl@dotestifsubstring{\noexpand\dtl@testifsubstring
{#1}{#2}}%
- \@dtl@tmp
+ \@dtl@dotestifsubstring
\if@dtl@condition
#3%
\else
@@ -3251,6 +3968,22 @@ datatool.dtx
\newcommand*{\dtl@testifsubstring}[2]{%
\dtl@subnobrsp{#1}{\@dtl@argA}%
\dtl@subnobrsp{#2}{\@dtl@argB}%
+% \end{macrocode}
+% Identify all word breaks.
+%\changes{2.13}{2013-01-15}{now using \cs{dtl@setwordbreaksnohyphens} to
+%deal with spaces}
+% \begin{macrocode}
+ \dtl@setwordbreaksnohyphens{\@dtl@argA}{\@dtl@wordbreak}%
+ \let\@dtl@argA\dtl@string
+ \dtl@setwordbreaksnohyphens{\@dtl@argB}{\@dtl@wordbreak}%
+ \let\@dtl@argB\dtl@string
+ \edef\dtl@donext{%
+ \noexpand\@dtl@testifsubstring{\expandonce\@dtl@argA}{\expandonce\@dtl@argB}}%
+ \dtl@donext
+}
+\newcommand*{\@dtl@testifsubstring}[2]{%
+ \def\@dtl@argA{#1}%
+ \def\@dtl@argB{#2}%
\ifdefempty{\@dtl@argB}%
{%
\@dtl@conditiontrue
@@ -3261,16 +3994,15 @@ datatool.dtx
\@dtl@conditionfalse
}%
{%
- \dtl@teststartswith{#1}{#2}%
+ \@dtl@teststartswith{#1}{#2}%
\if@dtl@condition
\else
- \DTLsubstituteall{\@dtl@argA}{ }{\space }%
\expandafter\dtl@getfirst\@dtl@argA\end
\expandafter\dtl@ifsingle\expandafter{\dtl@first}{%
- \expandafter\dtl@testifsubstring\expandafter{\dtl@rest}{#2}%
+ \expandafter\@dtl@testifsubstring\expandafter{\dtl@rest}{#2}%
}{%
- \protected@edef\@dtl@donext{\noexpand\dtl@testifsubstring
- {\dtl@first\dtl@rest}{\@dtl@argB}}%
+ \protected@edef\@dtl@donext{\noexpand\@dtl@testifsubstring
+ {\expandonce\dtl@first\expandonce\dtl@rest}{\expandonce\@dtl@argB}}%
\@dtl@donext
}%
\fi
@@ -3307,11 +4039,29 @@ datatool.dtx
%\cs{dtl@teststartswith}\marg{string}\marg{prefix}
%\end{definition}
% Tests if \meta{string} starts with \meta{prefix}. This sets
-% \cs{if@dtl@condition}.
+% \cs{if@dtl@condition}. First substitute all word breaks with
+% \cs{dtl@setwordbreaksnohyphen}
% \begin{macrocode}
\newcommand*{\dtl@teststartswith}[2]{%
\dtl@subnobrsp{#1}{\@dtl@argA}%
\dtl@subnobrsp{#2}{\@dtl@argB}%
+% \end{macrocode}
+% Identify all word breaks.
+%\changes{2.13}{2013-01-15}{now using \cs{dtl@setwordbreaksnohyphens} to
+%deal with spaces}
+% \begin{macrocode}
+ \dtl@setwordbreaksnohyphens{\@dtl@argA}{\@dtl@wordbreak}%
+ \let\@dtl@argA\dtl@string
+ \dtl@setwordbreaksnohyphens{\@dtl@argB}{\@dtl@wordbreak}%
+ \let\@dtl@argB\dtl@string
+ \edef\dtl@donext{%
+ \noexpand\@dtl@teststartswith{\expandonce\@dtl@argA}{\expandonce\@dtl@argB}}%
+ \dtl@donext
+}
+
+\newcommand*{\@dtl@teststartswith}[2]{%
+ \def\@dtl@argA{#1}%
+ \def\@dtl@argB{#2}%
\ifdefempty{\@dtl@argA}%
{%
\ifdefempty{\@dtl@argB}%
@@ -3328,54 +4078,79 @@ datatool.dtx
\@dtl@conditiontrue
}%
{%
- \DTLsubstituteall{\@dtl@argA}{ }{\space }%
- \DTLsubstituteall{\@dtl@argB}{ }{\space }%
\expandafter\dtl@getfirst\@dtl@argA\end
+% \end{macrocode}
+% Get the first object and the remaining text.
+% \begin{macrocode}
\let\dtl@firstA=\dtl@first
\let\dtl@restA=\dtl@rest
\expandafter\dtl@getfirst\@dtl@argB\end
\let\dtl@firstB=\dtl@first
\let\dtl@restB=\dtl@rest
- \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}{%
- \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}{%
- \expandafter\dtl@setcharcode\expandafter{\dtl@firstA}{\dtl@codeA}%
- \expandafter\dtl@setcharcode\expandafter{\dtl@firstB}{\dtl@codeB}%
- \ifnum\dtl@codeA=-1\relax
- \ifnum\dtl@codeB=-1\relax
- \protected@edef\dtl@donext{%
- \noexpand\dtl@teststartswith{\dtl@restA}{\dtl@restB}}%
- \dtl@donext
- \else
- \protected@edef\dtl@donext{%
- \noexpand\dtl@teststartswith
- {\dtl@restA}{\dtl@firstB\dtl@restB}}%
- \dtl@donext
- \fi
- \else
- \ifnum\dtl@codeB=-1\relax
- \protected@edef\dtl@donext{%
- \noexpand\dtl@teststartswith
- {\dtl@firstA\dtl@restA}{\dtl@restB}}%
- \dtl@donext
- \else
- \ifnum\dtl@codeA=\dtl@codeB
- \protected@edef\dtl@donext{%
- \noexpand\dtl@teststartswith{\dtl@restA}{\dtl@restB}}%
- \dtl@donext
+% \end{macrocode}
+% Is the first object of \meta{string1} a single character or a group?
+% \begin{macrocode}
+ \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}%
+ {%
+% \end{macrocode}
+% It's a single character. Is the first object of \meta{string2} a
+% single character or a group?
+% \begin{macrocode}
+ \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}%
+ {%
+% \end{macrocode}
+% Both are a single character. Get the lower case character code.
+% \begin{macrocode}
+ \expandafter\dtl@setcharcode\expandafter{\dtl@firstA}{\dtl@codeA}%
+ \expandafter\dtl@setcharcode\expandafter{\dtl@firstB}{\dtl@codeB}%
+ \ifnum\dtl@codeA=-1\relax
+ \ifnum\dtl@codeB=-1\relax
+ \protected@edef\dtl@donext{%
+ \noexpand\@dtl@teststartswith{\expandonce\dtl@restA}{\expandonce\dtl@restB}}%
+ \dtl@donext
+ \else
+ \protected@edef\dtl@donext{%
+ \noexpand\@dtl@teststartswith
+ {\expandonce\dtl@restA}{\expandonce\dtl@firstB\expandonce\dtl@restB}}%
+ \dtl@donext
+ \fi
\else
- \@dtl@conditionfalse
+ \ifnum\dtl@codeB=-1\relax
+ \protected@edef\dtl@donext{%
+ \noexpand\@dtl@teststartswith
+ {\expandonce\dtl@firstA\expandonce\dtl@restA}{\expandonce\dtl@restB}}%
+ \dtl@donext
+ \else
+ \ifnum\dtl@codeA=\dtl@codeB
+ \protected@edef\dtl@donext{%
+ \noexpand\@dtl@teststartswith{\expandonce\dtl@restA}{\expandonce\dtl@restB}}%
+ \dtl@donext
+ \else
+ \@dtl@conditionfalse
+ \fi
+ \fi
\fi
- \fi
- \fi
- }{%
- \protected@edef\dtl@donext{%
- \noexpand\dtl@teststartswith
- {\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
- \dtl@donext
- }}{%
- \protected@edef\dtl@donext{%
- \noexpand\dtl@teststartswith
- {\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
+ }%
+ {%
+% \end{macrocode}
+% The first object in \meta{string1} is a single character, but the
+% first object in \meta{string2} isn't a single character.
+% \begin{macrocode}
+ \protected@edef\dtl@donext{%
+ \noexpand\@dtl@teststartswith
+ {\expandonce\dtl@firstA\expandonce\dtl@restA}%
+ {\expandonce\dtl@firstB\expandonce\dtl@restB}}%
+ \dtl@donext
+ }%
+ }%
+ {%
+% \end{macrocode}
+% Neither object is a single character.
+% \begin{macrocode}
+ \protected@edef\dtl@donext{%
+ \noexpand\@dtl@teststartswith
+ {\expandonce\dtl@firstA\expandonce\dtl@restA}%
+ {\expandonce\dtl@firstB\expandonce\dtl@restB}}%
}%
}%
}%
@@ -4380,7 +5155,7 @@ datatool.dtx
% Definitions of fixed-point commands that use the \sty{fp} package.
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{datatool-fp}[2012/09/25 v2.11 (NLCT)]
+\ProvidesPackage{datatool-fp}[2013/01/15 v2.13 (NLCT)]
% \end{macrocode}
% Required packages:
% \begin{macrocode}
@@ -4669,7 +5444,7 @@ datatool.dtx
% Definitions of fixed-point commands that use the \sty{pgfmath} package.
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{datatool-pgfmath}[2012/10/06 v2.12 (NLCT)]
+\ProvidesPackage{datatool-pgfmath}[2013/01/15 v2.13 (NLCT)]
% \end{macrocode}
% Required packages:
% \begin{macrocode}
@@ -4926,7 +5701,7 @@ datatool.dtx
%\section{Package Declaration}
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{datatool}[2012/09/25 v2.11 (NLCT)]
+\ProvidesPackage{datatool}[2013/01/15 v2.13 (NLCT)]
% \end{macrocode}
% Load required packages:
% \begin{macrocode}
@@ -5112,11 +5887,13 @@ datatool.dtx
%\begin{option}{math}
% Determine whether to use \sty{fp} or \sty{pgfmath} for the
% arithmetic commands. The default is to use \sty{fp}.
+%\changes{2.13}{2013-01-15}{changed \cs{newcommand} to
+%\cs{providecommand}}
% \begin{macrocode}
\define@choicekey{datatool.sty}{math}[\val\nr]{fp,pgfmath}{%
\renewcommand*\@dtl@mathprocessor{#1}%
}
-\newcommand*{\@dtl@mathprocessor}{fp}
+\providecommand*{\@dtl@mathprocessor}{fp}
% \end{macrocode}
%\end{option}
%
@@ -5284,6 +6061,101 @@ datatool.dtx
% \end{macrocode}
%\end{macro}
%
+%\begin{macro}{\DTLgnewdb}
+%\begin{definition}
+% \cs{DTLnewdb}\marg{db name}
+%\end{definition}
+%\changes{2.13}{2013-01-15}{new}
+% Initialises a database called \meta{name}. (Global version.)
+% \begin{macrocode}
+\newcommand*{\DTLgnewdb}[1]{%
+% \end{macrocode}
+% Check if there is already a database with this name.
+% \begin{macrocode}
+ \DTLifdbexists{#1}%
+ {%
+ \PackageError{datatool}{Database `#1' already exists}{}%
+ }%
+ {%
+% \end{macrocode}
+% Define new database. Add information message if in verbose
+% mode.
+% \begin{macrocode}
+ \dtl@message{Creating database `#1'}%
+% \end{macrocode}
+% Define token register used to store the contents of the database.
+% \begin{macrocode}
+ \expandafter\global\expandafter\newtoks\csname dtldb@#1\endcsname
+% \end{macrocode}
+% Define token register used to store the column header information.
+% \begin{macrocode}
+ \expandafter\global\expandafter\newtoks\csname dtlkeys@#1\endcsname{}%
+% \end{macrocode}
+% Define count register used to store the row count.
+% \begin{macrocode}
+ \expandafter\global\expandafter\newcount\csname dtlrows@#1\endcsname
+% \end{macrocode}
+% Define count register used to store the column count.
+% \begin{macrocode}
+ \expandafter\global\expandafter\newcount\csname dtlcols@#1\endcsname
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\DTLgdeletedb}
+%\begin{definition}
+% \cs{DTLgdeletedb}\marg{db name}
+%\end{definition}
+% Deletes a database. (Global version.)
+%\changes{2.13}{2013-01-15}{new}
+% \begin{macrocode}
+\newcommand*{\DTLgdeletedb}[1]{%
+ \DTLifdbexists{#1}%
+ {%
+ \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)\in{#1}\do
+ {%
+ \expandafter\global\expandafter\let\csname dtl@ci@#1@\@dtl@key\endcsname\undefined
+ }%
+ \expandafter\global\expandafter\let\csname dtldb@#1\endcsname\undefined
+ \expandafter\global\expandafter\let\csname dtlkeys@#1\endcsname\undefined
+ \expandafter\global\expandafter\let\csname dtlrows@#1\endcsname\undefined
+ \expandafter\global\expandafter\let\csname dtlcols@#1\endcsname\undefined
+ }%
+ {%
+ \PackageError{Can't delete database `#1':
+ database doesn't exist}{}{}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\DTLgcleardb}
+%\begin{definition}
+% \cs{DTLgcleardb}\marg{db name}
+%\end{definition}
+% Clears the database. (Global version.)
+%\changes{2.13}{2013-01-15}{new}
+% \begin{macrocode}
+\newcommand*{\DTLgcleardb}[1]{%
+ \DTLifdbexists{#1}%
+ {%
+ \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)\in{#1}\do
+ {%
+ \expandafter\global\expandafter\let\csname dtl@ci@#1@\@dtl@key\endcsname\undefined
+ }%
+ \expandafter\global\csname dtldb@#1\endcsname{}%
+ \expandafter\global\csname dtlkeys@#1\endcsname{}%
+ \expandafter\global\csname dtlrows@#1\endcsname=0\relax
+ \expandafter\global\csname dtlcols@#1\endcsname=0\relax
+ }%
+ {%
+ \PackageError{Can't clear database `#1':
+ database doesn't exist}{}{}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%
%\begin{macro}{\DTLrowcount}
%\begin{definition}
% \cs{DTLrowcount}\marg{db name}
@@ -5362,11 +6234,12 @@ datatool.dtx
%\end{definition}
% Add a new row to named database. (Checks for the existance
% of the database.)
+%\changes{2.13}{2013-01-15}{fixed typo in \cs{PackageError}}
% \begin{macrocode}
\newcommand*{\@DTLnewrow}[1]{%
\DTLifdbexists{#1}%
{\@sDTLnewrow{#1}}%
- {\PackageErrors{datatool}{Can't add new row to database `#1':
+ {\PackageError{datatool}{Can't add new row to database `#1':
database doesn't exist}{}}%
}
% \end{macrocode}
@@ -6057,12 +6930,13 @@ datatool.dtx
\newcommand*{\@dtl@setheaderforindex}[3]{%
% \end{macrocode}
% Get the properties for this column
+%\changes{2.13}{2013-01-15}{removed spurious space}
% \begin{macrocode}
\edef\@dtl@dogetprops{\noexpand\@dtl@getprops
{\noexpand\@dtl@key}{\noexpand\@dtl@type}%
{\noexpand\@dtl@colhead}{\noexpand\@dtl@before}%
{\noexpand\@dtl@after}{\the\csname dtlkeys@#1\endcsname}%
- {\number#2}}
+ {\number#2}}%
\@dtl@dogetprops
% \end{macrocode}
% Store the header in \cs{@dtl@toks}
@@ -6171,7 +7045,7 @@ datatool.dtx
%\changes{2.03}{2009 November 15}{value can be expanded before
% adding to database}%
% \begin{macrocode}
- \@dtl@setnewvalue{#3}%
+ \@dtl@setnewvalue{#3}%
% \end{macrocode}
% There are no entries in this row for the given column.
% Add this entry.
@@ -6354,7 +7228,7 @@ datatool.dtx
%
%\begin{macro}{\@dtl@setnull}
%\cs{@dtl@setnull}\marg{cmd}\marg{id} sets \meta{cmd} to either
-% \cs{DTLstringnull} or \cs{DTLnumbernull} depending on the data
+% \cs{@dtlstringnull} or \cs{@dtlnumbernull} depending on the data
% type for \meta{id}. (Database
% name should be stored in \cs{@dtl@dbname} prior to use.)
%\changes{2.0}{2009 February 27}{modified to use new database
@@ -6411,31 +7285,49 @@ datatool.dtx
%\begin{macro}{\DTLstringnull}
% String null value:
% \begin{macrocode}
-\newcommand*{\DTLstringnull}{NULL}
+\newcommand*{\DTLstringnull}{\@dtlstringnull}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@dtlstringnull}
+%\changes{2.13}{2013-01-15}{new}
+% String null value:
+% \begin{macrocode}
+\newcommand*{\@dtlstringnull}{NULL}
% \end{macrocode}
%\end{macro}
%\begin{macro}{\DTLnumbernull}
% Number null value:
% \begin{macrocode}
-\newcommand*{\DTLnumbernull}{0}
+\newcommand*{\DTLnumbernull}{\@dtlnumbernull}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@dtlnumbernull}
+%\changes{2.13}{2013-01-15}{new}
+% Number null value:
+% \begin{macrocode}
+\newcommand*{\@dtlnumbernull}{0}
% \end{macrocode}
%\end{macro}
%\begin{macro}{\DTLifnull}
%\begin{definition}
-%\cs{DTLifnull}\marg{value}\marg{true part}\marg{false part}
+%\cs{DTLifnull}\marg{command}\marg{true part}\marg{false part}
%\end{definition}
-% Checks if \meta{value} is null (either \cs{DTLstringnull} or
+% Checks if \meta{command} is null (either \cs{DTLstringnull} or
% \cs{DTLnumbernull}) if true, does \meta{true part} otherwise
% does \meta{false part}.
% \begin{macrocode}
\newcommand*{\DTLifnull}[3]{%
- \ifx\DTLstringnull#1\relax
+ \ifx#1\dtlnovalue
#2%
\else
- \ifx\DTLnumbernull#1\relax
+ \ifx#1\DTLstringnull
#2%
\else
- #3%
+ \ifx#1\DTLnumbernull
+ #2%
+ \else
+ #3%
+ \fi
\fi
\fi
}
@@ -7267,7 +8159,8 @@ datatool.dtx
%\end{definition}
% Iterates through all the keys in database \meta{db}. In each
% iteration, \meta{key cs} stores the key, \meta{col cs} stores the
-% column index and \meta{type cs} stores the data type.
+% column index,\meta{type cs} stores the data type and \meta{header
+% cs} stores the header.
% \begin{macrocode}
\long\def\dtlforeachkey(#1,#2,#3,#4)\in#5\do#6{%
\gdef\@dtl@loopbody{#6}%
@@ -7425,11 +8318,11 @@ datatool.dtx
% Iterates through the column with index <col num> in database <db>.
% Starred version doesn't check if database exists.
%\changes{2.0}{2009 February 27}{new}
-% \begin{macrocode}
+% \begin{macrocode}
\newcommand*{\dtlforcolumnidx}{%
\@ifstar\@sdtlforcolumnidx\@dtlforcolumnidx
}
-% \end{macrocode}
+% \end{macrocode}
%\end{macro}
%
%\begin{macro}{\@dtlforcolumnidx}
@@ -7471,7 +8364,7 @@ datatool.dtx
}%
\@dtl@doforcol
}
-% \end{macrocode}
+% \end{macrocode}
%\end{macro}
%
%\begin{macro}{\dtl@forcolumn}
@@ -7722,11 +8615,12 @@ datatool.dtx
\DTLiflastrow
% \end{macrocode}
% Define current \cs{DTLiflastrow}
+%\changes{2.12}{2012-11-30}{fixed bug in \cs{DTLiflastrow}}
% \begin{macrocode}
\gdef\DTLiflastrow##1##2{%
\expandafter\ifnum
\csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
- =\csname dtlcols@#2\endcsname\relax
+ =\csname dtlrows@#2\endcsname\relax
##1%
\else
##2%
@@ -7991,11 +8885,12 @@ datatool.dtx
\DTLiflastrow
% \end{macrocode}
% Define current \cs{DTLiflastrow}
+%\changes{2.12}{2012-11-30}{fixed bug in \cs{DTLiflastrow}}
% \begin{macrocode}
\gdef\DTLiflastrow##1##2{%
\expandafter\ifnum
\csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
- =\csname dtlcols@#2\endcsname\relax
+ =\csname dtlrows@#2\endcsname\relax
##1%
\else
##2%
@@ -8495,9 +9390,10 @@ datatool.dtx
\newcommand{\DTLaddentryforrow}[5]{%
% \end{macrocode}
% Iterate through the data base until condition is met
+%\changes{2.13}{2013-01-15}{removed spurious space}
% \begin{macrocode}
\DTLifdbexists{#1}%
- {
+ {%
\def\@dtl@notdone{\PackageError{datatool}{Unable to add entry
given by key `#4': condition not met for any row in database
`#1'}{}}%
@@ -8572,14 +9468,16 @@ datatool.dtx
\ifx#1\dtlnovalue
\ifnum0\dtltype=0\relax
% \end{macrocode}
+%\changes{2.13}{2013-01-15}{changed to use \cs{@dtlstringnull} and
+%\cs{@dtlnumbernull}}%
% Data type is \meta{empty} or 0, so set to string null.
% \begin{macrocode}
- \let#1=\DTLstringnull
+ \let#1=\@dtlstringnull
\else
% \end{macrocode}
% Data type is numerical, so set to number null.
% \begin{macrocode}
- \let#1=\DTLnumbernull
+ \let#1=\@dtlnumbernull
\fi
\fi
% \end{macrocode}
@@ -8880,9 +9778,10 @@ datatool.dtx
% \end{macrocode}
% Initialise:
% only want "&" between columns
+%\changes{2.13}{2013-01-15}{removed spurious space}
% \begin{macrocode}
- \def\@dtl@doamp{\gdef\@dtl@doamp{&}}
- \def\@dtl@resetdoamp{\gdef\@dtl@doamp{\gdef\@dtl@doamp{&}}}
+ \def\@dtl@doamp{\gdef\@dtl@doamp{&}}%
+ \def\@dtl@resetdoamp{\gdef\@dtl@doamp{\gdef\@dtl@doamp{&}}}%
% \end{macrocode}
% Store maximum number of columns
% \begin{macrocode}
@@ -8905,7 +9804,10 @@ datatool.dtx
{}%
{%
\dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols
- }
+% \end{macrocode}
+%\changes{2.13}{2013-01-15}{removed spurious space}
+% \begin{macrocode}
+ }%
}%
% \end{macrocode}
% Begin tabular environment
@@ -9066,9 +9968,10 @@ datatool.dtx
\setkeys{displaylong}{#1}%
% \end{macrocode}
% Only want "&" between columns
+%\changes{2.13}{2013-01-15}{removed spurious space}
% \begin{macrocode}
- \def\@dtl@doamp{\gdef\@dtl@doamp{&}}
- \def\@dtl@resetdoamp{\gdef\@dtl@doamp{\gdef\@dtl@doamp{&}}}
+ \def\@dtl@doamp{\gdef\@dtl@doamp{&}}%
+ \def\@dtl@resetdoamp{\gdef\@dtl@doamp{\gdef\@dtl@doamp{&}}}%
\@dtl@resetdostartrow
% \end{macrocode}
% Store maximum number of columns
@@ -9648,7 +10551,7 @@ datatool.dtx
% Divide total by number of elements summed.
% \begin{macrocode}
\ifnum\@dtl@elements=0\relax
-% \PackageError{datatool}{Unable to evaluate mean: no data}{}%
+ \PackageError{datatool}{Unable to evaluate mean: no data}{}%
\else
\edef\@dtl@n{\number\@dtl@elements}%
\DTLdiv{#4}{#4}{\@dtl@n}%
@@ -10249,32 +11152,7 @@ datatool.dtx
% Unstarred (case sensitive) version.
% \begin{macrocode}
\newcommand{\@DTLsort}[3][]{%
-% \end{macrocode}
-% Check the database exists
-% \begin{macrocode}
- \DTLifdbexists{#3}%
- {%
-% \end{macrocode}
-% Store replacement keys in \cs{@dtl@replacementkeys}.
-% \begin{macrocode}
- \edef\@dtl@replacementkeys{#1}%
-% \end{macrocode}
-% Store sort order in \cs{@dtl@sortorder}.
-% \begin{macrocode}
- \edef\@dtl@sortorder{#2}%
-% \end{macrocode}
-% Set \cs{@dtl@comparecs} to the required string comparison
-% function. (Using case sensitive comparison macro \cs{dtlcompare}.)
-% \begin{macrocode}
- \let\@dtl@comparecs=\dtlcompare
-% \end{macrocode}
-% Sort the database.
-% \begin{macrocode}
- \dtl@sortdata{#3}%
- }%
- {%
- \PackageError{datatool}{Database `#3' doesn't exist}{}%
- }%
+ \dtlsort[#1]{#2}{#3}{\dtlicompare}%
}
% \end{macrocode}
%\end{macro}
@@ -10282,12 +11160,30 @@ datatool.dtx
%\begin{macro}{\@sDTLsort}
% Starred (case insensitive) version.
% \begin{macrocode}
-\newcommand{\@sDTLsort}[3][]{%
+\newcommand*{\@sDTLsort}[3][]{%
+ \dtlsort[#1]{#2}{#3}{\dtlicompare}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtlsort}
+%\changes{2.13}{2013-01-15}{new}
+%\begin{definition}
+%\cs{dtlsort}\oarg{replacement keys}\marg{sort criteria}\marg{db
+%name}\marg{handler}
+%\end{definition}
+% More general version where user supplies a handler for the
+% comparison.
+% \begin{macrocode}
+\newcommand{\dtlsort}[4][]{%
% \end{macrocode}
% Check the database exists
% \begin{macrocode}
\DTLifdbexists{#3}%
{%
+ \ifnum\DTLrowcount{#3}>100\relax
+ \typeout{Sorting `#3' - this may take a while.}%
+ \fi
% \end{macrocode}
% Store replacement keys in \cs{@dtl@replacementkeys}.
% \begin{macrocode}
@@ -10301,7 +11197,7 @@ datatool.dtx
% function. (Using case insensitive comparison macro
% \cs{dtlicompare}.)
% \begin{macrocode}
- \let\@dtl@comparecs=\dtlicompare
+ \let\@dtl@comparecs=#4%
% \end{macrocode}
% Sort the database.
% \begin{macrocode}
@@ -10349,7 +11245,7 @@ datatool.dtx
% \end{macrocode}
% Iterate through each row and insert into sorted list.
% \begin{macrocode}
- \@dtlforeachrow(\@dtl@rowAnum,\@dtl@rowAcontents)\in{#1}\do{%
+ \@dtlforeachrow(\@dtl@rowAnum,\@dtl@rowAcontents)\in\@dtl@dbname\do{%
\@dtl@rowa=\expandafter{\@dtl@rowAcontents}%
% \end{macrocode}
% Create a temporary list
@@ -10372,7 +11268,8 @@ datatool.dtx
\db@row@id@w \@nil\db@row@id@end@%
\db@row@id@w \@nil\db@row@id@end@%
\db@row@elt@end@%
- \@@{\@dtl@rowBnum}{\@dtl@rowBcontents}{%
+ \@@{\@dtl@rowBnum}{\@dtl@rowBcontents}%
+ {%
% \end{macrocode}
% Store row B in a token register
% \begin{macrocode}
@@ -10511,7 +11408,8 @@ datatool.dtx
% \end{macrocode}
% Iterate through the sort order.
% \begin{macrocode}
- \@for\@dtl@level:=\@dtl@sortorder\do{%
+ \@for\@dtl@level:=\@dtl@sortorder\do
+ {%
% \end{macrocode}
% Set \cs{@dtl@sortdirection} to $-1$ (ascending) or $+1$
% (descending). Key is stored in \cs{@dtl@key}.
@@ -10729,8 +11627,9 @@ datatool.dtx
one of `ascending' or `descending'}%
% \end{macrocode}
% Assume ascending.
+%\changes{2.13}{2013-01-15}{removed spurious space}
% \begin{macrocode}
- \def\@dtl@sortdirection{-1}
+ \def\@dtl@sortdirection{-1}%
\fi
\fi
}%
@@ -10750,9 +11649,9 @@ datatool.dtx
% \end{macrocode}
%\end{macro}
%\begin{macro}{\@dtl@toksB}
-% \begin{macrocode}
+% \begin{macrocode}
\newtoks\@dtl@toksB
-% \end{macrocode}
+% \end{macrocode}
%\end{macro}
%\begin{macro}{\dtl@compare}
%\begin{definition}
@@ -11057,6 +11956,168 @@ datatool.dtx
% \end{macrocode}
%\end{macro}
%
+%\begin{macro}{\dtl@saverawdbhook}
+% Hook used by \cs{DTLsaverawdb}.
+% \begin{macrocode}
+\newcommand*{\dtl@saverawdbhook}{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLsaverawdb}
+% Saves given database in its internal form. Not easy for a human to
+% read, but much faster to load.
+%\changes{2.13}{2013-01-15}{new}
+% \begin{macrocode}
+\newcommand*{\DTLsaverawdb}[2]{%
+ \DTLifdbexists{#1}%
+ {%
+% \end{macrocode}
+% Open output file
+% \begin{macrocode}
+ \openout\@dtl@write=#2\relax
+% \end{macrocode}
+% Add code at the start of the output file to check for the
+% existence of the database:
+% \begin{macrocode}
+ \protected@write{\@dtl@write}{}{%
+ \string\DTLifdbexists{#1}\expandafter\@gobble\string\%^^J%
+ {%
+ \string\PackageError{datatool}{Database `#1' ^^Jalready exists}{}%
+ \expandafter\@gobble\string\%^^J%
+ \string\aftergroup\string\endinput
+ }%
+ {%
+ }\expandafter\@gobble\string\%
+ }%
+% \end{macrocode}
+% Scope need to localise definitions:
+% \begin{macrocode}
+ {%
+% \end{macrocode}
+% \TeX\ automatically breaks the line every 80 characters when
+% writing to a file. This may break a control sequence. This is a
+% patch that puts the row and column markers on a new line.
+% (Problems may still occur if the database contains very long
+% entries, but I'm not sure how to get around that.)
+% \begin{macrocode}
+ \def\db@row@elt@w{\expandafter\@gobble\string\%^^J\string\db@row@elt@w\space}%
+ \def\db@row@elt@end@{\expandafter\@gobble\string\%^^J\string\db@row@elt@end@\space}%
+ \def\db@row@id@w{\expandafter\@gobble\string\%^^J\string\db@row@id@w\space}%
+ \def\db@row@id@end@{\expandafter\@gobble\string\%^^J\string\db@row@id@end@\space}%
+ \def\db@col@elt@w{\expandafter\@gobble\string\%^^J\string\db@col@elt@w\space}%
+ \def\db@col@elt@end@{\expandafter\@gobble\string\%^^J\string\db@col@elt@end@\space}%
+ \def\db@col@id@w{\expandafter\@gobble\string\%^^J\string\db@col@id@w\space}%
+ \def\db@col@id@end@{\expandafter\@gobble\string\%^^J\string\db@col@id@end@\space}%
+%
+ \def\db@plist@elt@w{\expandafter\@gobble\string\%^^J\string\db@plist@elt@w\space}%
+ \def\db@plist@elt@end@{\expandafter\@gobble\string\%^^J\string\db@plist@elt@end@\space}%
+ \def\db@key@id@w{\expandafter\@gobble\string\%^^J\string\db@key@id@w\space}%
+ \def\db@key@id@end@{\expandafter\@gobble\string\%^^J\string\db@key@id@end@\space}%
+ \def\db@type@id@w{\expandafter\@gobble\string\%^^J\string\db@type@id@w\space}%
+ \def\db@type@id@end@{\expandafter\@gobble\string\%^^J\string\db@type@id@end@\space}%
+ \def\db@header@id@w{\expandafter\@gobble\string\%^^J\string\db@header@id@w\space}%
+ \def\db@header@id@end@{\expandafter\@gobble\string\%^^J\string\db@header@id@end@\space}%
+% \end{macrocode}
+% Need to ensure the @ character can be used so \ics{makeatletter}
+% is required, but localise the effect.
+% \begin{macrocode}
+ \protected@write{\@dtl@write}{}{\string\bgroup\string\makeatletter}%
+% \end{macrocode}
+% If in verbose mode, add a message to let the user know what's
+% happening when the file is later loaded.
+% \begin{macrocode}
+ \protected@write{\@dtl@write}{}{\string\dtl@message{Reconstructing database
+ ^^J`#1'}\expandafter\@gobble\string\%}%
+% \end{macrocode}
+% Save the contents of the token register that holds the column
+% information (column id, header, type). (The write is delayed,
+% so the contents are first expanded and stored in a temporary
+% (global) macro to ensure its in the correct format when the write happens.)
+% \begin{macrocode}
+ \protected@write{\@dtl@write}{}{%
+ \string\expandafter
+ \string\global\string\expandafter^^J\string\newtoks
+ \string\csname\space dtlkeys@#1\string\endcsname}%
+ \protected@write{\@dtl@write}{}{%
+ \string\expandafter
+ \string\global^^J
+ \string\csname\space dtlkeys@#1\string\endcsname
+ =\expandafter\@gobble\string\{\expandafter\@gobble\string\%}%
+ \expandafter\protected@xdef\csname dtl@rawwritedbkeys@#1\endcsname{%
+ \the\csname dtlkeys@#1\endcsname}%
+ \protected@write{\@dtl@write}{}{\csname dtl@rawwritedbkeys@#1\endcsname}%
+ \protected@write{\@dtl@write}{}{\expandafter\@gobble\string\}\expandafter\@gobble\string\%}%
+% \end{macrocode}
+% Hook used by \sty{datagidx}:
+% \begin{macrocode}
+ \dtl@saverawdbhook
+% \end{macrocode}
+% Save the contents of the token register that holds the database
+% body.
+% \begin{macrocode}
+ \protected@write{\@dtl@write}{}{%
+ \string\expandafter\string\global
+ \string\expandafter^^J\string\newtoks
+ \string\csname\space dtldb@#1\string\endcsname}%
+ \protected@write{\@dtl@write}{}{%
+ \string\expandafter
+ \string\global^^J\string\csname\space dtldb@#1\string\endcsname
+ =\expandafter\@gobble\string\{\expandafter\@gobble\string\%}%
+ \expandafter\protected@xdef\csname dtl@rawwritedb@#1\endcsname{\the\csname dtldb@#1\endcsname}%
+ \protected@write{\@dtl@write}{}{\csname dtl@rawwritedb@#1\endcsname}%
+ \protected@write{\@dtl@write}{}{\expandafter\@gobble\string\}\expandafter\@gobble\string\%}%
+% \end{macrocode}
+% Now for the count register that keeps track of the row count.
+% \begin{macrocode}
+ \protected@write{\@dtl@write}{}{\string\expandafter\string\global^^J
+ \string\expandafter\string\newcount
+ \string\csname\space dtlrows@#1\string\endcsname}%
+ \protected@write{\@dtl@write}{}{\string\expandafter\string\global^^J
+ \string\csname\space dtlrows@#1\string\endcsname
+ =\expandafter\number\csname dtlrows@#1\endcsname\string\relax}%
+% \end{macrocode}
+% Similarly for the column count.
+% \begin{macrocode}
+ \protected@write{\@dtl@write}{}{\string\expandafter\string\global^^J
+ \string\expandafter\string\newcount
+ \string\csname\space dtlcols@#1\string\endcsname}%
+ \protected@write{\@dtl@write}{}{\string\expandafter\string\global^^J
+ \string\csname\space dtlcols@#1\string\endcsname
+ =\expandafter\number\csname dtlcols@#1\endcsname\string\relax}%
+% \end{macrocode}
+% Add key mappings
+% \begin{macrocode}
+ \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)\in{#1}\do
+ {%
+ \edef\dtl@tmp{%
+ \string\expandafter^^J
+ \string\gdef
+ \string\csname\space dtl@ci@#1@\@dtl@key\string\endcsname
+ {\csname dtl@ci@#1@\@dtl@key\endcsname}\expandafter\@gobble\string\%
+ }%
+ \expandafter\write\expandafter\@dtl@write\expandafter{\dtl@tmp}%
+ }%
+% \end{macrocode}
+% End the scope for \ics{makeatletter:}
+% \begin{macrocode}
+ \protected@write{\@dtl@write}{}{\string\egroup}%
+% \end{macrocode}
+% End current scope:
+% \begin{macrocode}
+ }%
+% \end{macrocode}
+% Close output file
+% \begin{macrocode}
+ \closeout\@dtl@write
+ }%
+ {%
+ \PackageError{datatool}{Can't save database `#1': no such
+ database}{}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
%\section{Loading a database from an external file}
%
%\begin{macro}{\@dtl@read}
@@ -11133,6 +12194,7 @@ datatool.dtx
% and stores in \meta{cs}.
% \begin{macrocode}
\newcommand*{\@dtl@readline}[2]{%
+% \end{macrocode}
% Read a line from "#1" and store in "#2"
% \begin{macrocode}
\read#1 to #2%
@@ -11144,7 +12206,10 @@ datatool.dtx
}%
{%
\dtl@trim#2%
- }
+% \end{macrocode}
+%\changes{2.13}{2013-01-15}{removed spurious space}
+% \begin{macrocode}
+ }%
}
% \end{macrocode}
%\end{macro}
@@ -11157,6 +12222,7 @@ datatool.dtx
% applies mappings and stores in \meta{cs}.
% \begin{macrocode}
\newcommand*{\@dtl@readrawline}[2]{%
+% \end{macrocode}
% Read a line from "#1" and store in "#2"
% \begin{macrocode}
\@dtl@rawread#1 to #2%
@@ -11172,6 +12238,19 @@ datatool.dtx
% \end{macrocode}
%\end{macro}
%
+%\begin{macro}{\ifDTLnewdbonload}
+% Governs whether or not the database should be defined by
+% \ics{DTLloaddb} and \ics{DTLloadrawdb}.
+%\changes{2.13}{2013-01-15}{new}
+% \begin{macrocode}
+\newif\ifDTLnewdbonload
+% \end{macrocode}
+% Ensure compatibility with previous versions:
+% \begin{macrocode}
+\DTLnewdbonloadtrue
+% \end{macrocode}
+%\end{macro}
+%
%\begin{macro}{\DTLloaddb}
%\begin{definition}
% \cs{DTLloaddb}\oarg{options}\marg{db name}\marg{filename}
@@ -11229,9 +12308,11 @@ datatool.dtx
\read\@dtl@read to \@dtl@line
\repeat
% \end{macrocode}
-% Create the new database.
+% Create the database if required.
% \begin{macrocode}
- \DTLnewdb{#2}%
+ \ifDTLnewdbonload
+ \DTLnewdb{#2}%
+ \fi
% \end{macrocode}
% Check if the file is empty.
% \begin{macrocode}
@@ -11663,8 +12744,11 @@ datatool.dtx
\def\@dtl@rawmappings{{#1}{#2}}%
}%
{%
- \def\@dtl@tmp{{#1}{#2}}
- \protected@edef\@dtl@rawmappings{\the\@dtl@toks,\@dtl@tmp}
+% \end{macrocode}
+%\changes{2.13}{2013-01-15}{removed spurious space}
+% \begin{macrocode}
+ \def\@dtl@tmp{{#1}{#2}}%
+ \protected@edef\@dtl@rawmappings{\the\@dtl@toks,\@dtl@tmp}%
}%
}
% \end{macrocode}
@@ -11740,6 +12824,5729 @@ datatool.dtx
%\fi
%\iffalse
% \begin{macrocode}
+%<*datagidx.sty>
+% \end{macrocode}
+%\fi
+%\chapter{datagidx.sty}
+%\changes{2.13}{2013-01-15}{added datagidx package}
+% This package provides a means to produces indices and glossaries
+% without the need for an external indexing application, such as
+% \app{makeindex} or \app{xindy}. However, the code here has
+% been developed to implement the word order style described by the
+% Oxford Style Manual. If you are not writing in English, this may
+% not be applicable to your needs. You may be able to define your
+% own comparison handler to use with \cs{dtlsort}. If not, you'll
+% need to use \app{xindy} with a package such as
+% \sty{glossaries}.
+%
+% Declare package:
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{datagidx}[2013/01/15 v2.13 (NLCT)]
+% \end{macrocode}
+% Required packages:
+% \begin{macrocode}
+\RequirePackage{datatool}
+\RequirePackage{etoolbox}
+\RequirePackage{xkeyval}
+\RequirePackage{mfirstuc}
+\RequirePackage{xfor}
+\RequirePackage{multicol}
+\RequirePackage{textcase}
+% \end{macrocode}
+%
+%\section{Default Settings}
+% These commands need to be defined before the package options are
+% used.
+%\begin{macro}{\datagidx@columns}
+% The number of columns to use for the index/glossary.
+% \begin{macrocode}
+\newcommand*{\datagidx@columns}{2}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSetColumns}
+% \begin{macrocode}
+\newcommand*{\DTLgidxSetColumns}[1]{%
+ \DTLifint{#1}%
+ {%
+ \def\datagidx@columns{#1}%
+ }%
+ {%
+ \PackageError{datagidx}%
+ {Number of columns must be an integer}%
+ {%
+ You have requested `#1' columns, which can't be parsed as a
+ number%
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{counter}{DTLgidxChildCount}
+% Child counter.
+% \begin{macrocode}
+\newcounter{DTLgidxChildCount}
+% \end{macrocode}
+%\end{counter}
+%\begin{macro}{\theHDTLgidxChildCount}
+% Reduce duplicate identifier warnings if \sty{hyperref} in use.
+% \begin{macrocode}
+\def\theHDTLgidxChildCount{\Label.\arabic{DTLgidxChildCount}}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxChildCountLabel}
+% Label for child counter.
+% \begin{macrocode}
+\newcommand*{\DTLgidxChildCountLabel}{\theDTLgidxChildCount) }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxChildStyle}
+% Should the child name be displayed? (Default: show name.)
+% If the name shouldn't be displayed, replace with a number.
+% \begin{macrocode}
+\newcommand*{\DTLgidxChildStyle}[1]{#1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@setchildstyle}
+% \begin{macrocode}
+\newcommand*{\datagidx@setchildstyle}[1]{%
+ \ifcase#1\relax
+ \renewcommand*{\DTLgidxChildStyle}[1]{##1}%
+ \or
+ \renewcommand*{\DTLgidxChildStyle}[1]{%
+ \DTLgidxChildCountLabel
+ }%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@foreachchild}
+% Iterate through each child label
+% \begin{macrocode}
+\newcommand{\datagidx@foreachchild}{%
+ \datagidx@sort@foreachchild
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@setchildsort}
+% \begin{macrocode}
+\newcommand*{\datagidx@setchildsort}[1]{%
+ \ifcase#1\relax
+ \renewcommand*{\datagidx@foreachchild}{%
+ \datagidx@sort@foreachchild
+ }%
+ \or
+ \renewcommand*{\datagidx@foreachchild}{%
+ \datagidx@unsort@foreachchild
+ }%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxPostName}
+% What to put after the name. (Defaults to space.)
+% \begin{macrocode}
+\newcommand*{\DTLgidxPostName}{ }
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\DTLgidxPostChildName}
+% What to put after the child name.
+% \begin{macrocode}
+\newcommand*{\DTLgidxPostChildName}{\DTLgidxPostName}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxNameCase}
+% Should the name have a case change in the index/glossary?
+% (Default: no change.)
+% \begin{macrocode}
+\newcommand*{\DTLgidxNameCase}[1]{#1}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidx@setnamecase}
+% \begin{macrocode}
+\newcommand*{\datagidx@setnamecase}[1]{%
+ \ifcase#1\relax
+ \renewcommand*{\DTLgidxNameCase}[1]{##1}%
+ \or
+ \let\DTLgidxNameCase\MakeTextUppercase
+ \or
+ \let\DTLgidxNameCase\MakeTextLowercase
+ \or
+ \let\DTLgidxNameCase\xmakefirstuc
+ \or
+ \let\DTLgidxNameCase\xcapitalisewords
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxNameFont}
+% The font to use for the name in the index/glossary.
+% (Default: normal font.)
+% \begin{macrocode}
+\newcommand*{\DTLgidxNameFont}[1]{\textnormal{#1}}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxPostDescription}
+% What to put after the description. (Defaults to nothing.)
+% \begin{macrocode}
+\newcommand*{\DTLgidxPostDescription}{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@setpostdesc}
+% \begin{macrocode}
+\newcommand*{\datagidx@setpostdesc}[1]{%
+ \ifcase#1\relax
+ \renewcommand*{\DTLgidxPostDescription}{}%
+ \or
+ \renewcommand*{\DTLgidxPostDescription}{.}%
+ \fi
+ }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxPreLocation}
+% What to put before the location list. (Defaults to en-space.)
+% \begin{macrocode}
+\newcommand*{\DTLgidxPreLocation}{\enspace}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@setprelocation}
+% \begin{macrocode}
+\newcommand*{\datagidx@setprelocation}[1]{%
+ \ifcase#1\relax
+ \renewcommand*{\DTLgidxPreLocation}{}%
+ \or
+ \renewcommand*{\DTLgidxPreLocation}{\enspace}%
+ \or
+ \renewcommand*{\DTLgidxPreLocation}{ }%
+ \or
+ \renewcommand*{\DTLgidxPreLocation}{\dotfill}%
+ \or
+ \renewcommand*{\DTLgidxPreLocation}{\hfill}%
+ \fi
+ }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxLocation}
+% How to display the location. (Defaults to show the location list.)
+% \begin{macrocode}
+\newcommand*{\DTLgidxLocation}{\dtldolocationlist}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@setlocation}
+% Should the location list be displayed?
+% \begin{macrocode}
+\newcommand*{\datagidx@setlocation}[1]{%
+ \ifcase#1\relax
+ \renewcommand*{\DTLgidxLocation}{}%
+ \or
+ \renewcommand*{\DTLgidxLocation}{\dtldolocationlist}%
+ \or
+ \renewcommand*{\DTLgidxLocation}{\dtldofirstlocation}%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSee}
+% How to display the cross-reference list.
+% \begin{macrocode}
+\newcommand*{\DTLgidxSee}{%
+ \DTLifnull{\See}%
+ {}%
+ {%
+ \DTLgidxPreLocation
+ \DTLgidxFormatSee{\seename}{\See}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\DTLgidxSeeAlso}
+% How to display the ``see also'' list.
+% \begin{macrocode}
+\newcommand*{\DTLgidxSeeAlso}{%
+ \DTLifnull{\SeeAlso}%
+ {}%
+ {%
+ \DTLgidxFormatSeeAlso{\seealsoname}{\SeeAlso}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxChildrenSeeAlso}
+% Display the children and the see also attributes.
+% \begin{macrocode}
+\newcommand*{\DTLgidxChildrenSeeAlso}{%
+ \DTLgidxChildren
+ \DTLgidxSeeAlso
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@setsee}
+% How should cross-references appear?
+% \begin{macrocode}
+\newcommand*{\datagidx@setsee}[1]{%
+ \ifcase#1\relax
+ \renewcommand*{\DTLgidxSee}{%
+ \DTLifnull{\See}{}%
+ {%
+ , \DTLgidxFormatSee{\seename}{\See}%
+ }%
+ }%
+ \or
+ \renewcommand*{\DTLgidxSee}{%
+ \DTLifnull{\See}{}
+ {%
+ \space(\DTLgidxFormatSee{\seename}{\See})%
+ }%
+ }%
+ \or
+ \renewcommand*{\DTLgidxSee}{%
+ \DTLifnull{\See}{}%
+ {%
+ . \DTLgidxFormatSee{\xmakefirstuc{\seename}}{\See}%
+ }%
+ }%
+ \or
+ \renewcommand*{\DTLgidxSee}{%
+ \DTLifnull{\See}{}
+ {%
+ \space\DTLgidxFormatSee{\seename}{\See}%
+ }%
+ }%
+ \or
+ \renewcommand*{\DTLgidxSee}{%
+ \DTLifnull{\See}{}
+ {%
+ \DTLgidxFormatSee{\seename}{\See}%
+ }%
+ }%
+ \or
+ \renewcommand*{\DTLgidxSee}{%
+ \DTLifnull{\See}{}
+ {%
+ ; \DTLgidxFormatSee{\seename}{\See}%
+ }%
+ }%
+ \or
+ \renewcommand*{\DTLgidxSee}{%
+ \DTLifnull{\See}{}
+ {%
+ \DTLgidxPreLocation\DTLgidxFormatSee{\seename}{\See}%
+ }%
+ }%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSymDescSep}
+% Separator character between symbol and description if both are
+% present.
+% \begin{macrocode}
+\newcommand*{\DTLgidxSymDescSep}{\space}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxsymbolwidth}
+% Space to allocate for the symbol. If zero or negative, symbol just
+% occupies its natural space.
+% \begin{macrocode}
+\newlength\datagidxsymbolwidth
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxlocationwidth}
+% Space to allocate for the location list. If zero or negative, the
+% list just occupies its natural space.
+% \begin{macrocode}
+\newlength\datagidxlocationwidth
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxFormatDesc}
+% How to format the description.
+% \begin{macrocode}
+\newcommand{\DTLgidxFormatDesc}[1]{#1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSymbolDescription}
+% How to format the symbol and description fields.
+% \begin{macrocode}
+\newcommand*{\DTLgidxSymbolDescription}{%
+ \DTLgidxSymbolDescLeft
+ \DTLgidxSymbolDescRight
+}
+\newcommand*{\DTLgidxSymbolDescLeft}{%
+ \ifdefempty{\Symbol}{}{(\Symbol)\DTLgidxSymDescSep}%
+}
+\newcommand*{\DTLgidxSymbolDescRight}{%
+ \ifdefempty{\Description}{}%
+ {%
+ \DTLgidxFormatDesc{\Description}\DTLgidxPostDescription
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\if@datagidxsymbolleft}
+% Identifies whether the symbol has been set to left or right.
+% \begin{macrocode}
+\newif\if@datagidxsymbolleft
+\@datagidxsymbollefttrue
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@formatsymdesc}
+% \begin{macrocode}
+\newcommand*{\datagidx@formatsymdesc}[1]{%
+ \ifcase#1\relax
+% \end{macrocode}
+% Only symbol
+% \begin{macrocode}
+ \renewcommand*{\DTLgidxSymbolDescLeft}{%
+ \ifdefempty{\Symbol}{}{\Symbol}%
+ }%
+ \renewcommand*{\DTLgidxSymbolDescRight}{}%
+ \@datagidxsymbollefttrue
+ \or
+% \end{macrocode}
+% Only description
+% \begin{macrocode}
+ \renewcommand*{\DTLgidxSymbolDescLeft}{%
+ \ifdefempty{\Description}{}%
+ {%
+ \DTLgidxFormatDesc{\Description}\DTLgidxPostDescription
+ }%
+ }%
+ \renewcommand*{\DTLgidxSymbolDescRight}{}%
+ \@datagidxsymbolleftfalse
+ \or
+% \end{macrocode}
+% (symbol) description
+% \begin{macrocode}
+ \renewcommand*{\DTLgidxSymbolDescLeft}{%
+ \ifdefempty{\Symbol}{}{(\Symbol)\DTLgidxSymDescSep}%
+ }%
+ \renewcommand*{\DTLgidxSymbolDescRight}{%
+ \ifdefempty{\Description}{}%
+ {%
+ \DTLgidxFormatDesc{\Description}\DTLgidxPostDescription
+ }%
+ }%
+ \@datagidxsymbollefttrue
+ \or
+% \end{macrocode}
+% description (symbol)
+% \begin{macrocode}
+ \renewcommand*{\DTLgidxSymbolDescLeft}{%
+ \ifdefempty{\Description}{}%
+ {%
+ \DTLgidxFormatDesc{\Description}%
+ \DTLgidxPostDescription\DTLgidxSymDescSep
+ }%
+ }%
+ \renewcommand*{\DTLgidxSymbolDescRight}{%
+ \ifdefempty{\Symbol}{}{(\Symbol)}%
+ }%
+ \@datagidxsymbolleftfalse
+ \or
+% \end{macrocode}
+% symbol description
+% \begin{macrocode}
+ \renewcommand*{\DTLgidxSymbolDescLeft}{%
+ \ifdefempty{\Symbol}{}{\Symbol\DTLgidxSymDescSep}%
+ }%
+ \renewcommand*{\DTLgidxSymbolDescRight}{%
+ \ifdefempty{\Description}{}%
+ {%
+ \DTLgidxFormatDesc{\Description}%
+ \DTLgidxPostDescription
+ }%
+ }%
+ \@datagidxsymbollefttrue
+ \or
+% \end{macrocode}
+% description symbol
+% \begin{macrocode}
+ \renewcommand*{\DTLgidxSymbolDescLeft}{%
+ \ifdefempty{\Description}{}%
+ {%
+ \DTLgidxFormatDesc{\Description}%
+ \DTLgidxPostDescription\DTLgidxSymDescSep
+ }%
+ }%
+ \renewcommand*{\DTLgidxSymbolDescRight}{%
+ \ifdefempty{\Symbol}{}{\Symbol}%
+ }%
+ \@datagidxsymbolleftfalse
+ \fi
+ }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSetCompositor}
+%\begin{definition}
+%\cs{DTLgidxSetCompositor}\marg{symbol}
+%\end{definition}
+%Set the location compositor.
+% \begin{macrocode}
+\newcommand*{\DTLgidxSetCompositor}[1]{%
+ \undef\datagidx@docomplist
+ \DeclareListParser{\datagidx@docomplist}{#1}%
+ \def\datagidx@compositor{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%Set the default compositor to \texttt{.} (full stop).
+% \begin{macrocode}
+\DTLgidxSetCompositor{.}
+% \end{macrocode}
+%
+% Sorting can take a long time (especially with large databases) but
+% two \LaTeX\ runs are usually required to get the index or glossary
+% up-to-date, so we usually don't need to worry about sorting on the
+% first run (unless the order in some way affects the document,
+% e.g.\ the group headings are to appear in the table of contents).
+% It may also be that some modifications are done to the document
+% that don't require a re-sort. The optimize setting tries to
+% minimize the amount of sorting done to help speed up document
+% compilation.
+%
+% There are to optimization levels: low and high. The low level
+% optimization just sorts every other \LaTeX\ run. This is done by
+% writing to the aux file to determine whether or not the sort
+% should be done next run. This is a cheap and easy hack that won't
+% work if sorting makes the document out-of-date (for example, if
+% the sorted index or glossary affects the table of contents by,
+% say, making the group headings a sectional unit).
+%
+% The high level optimization is more complicated and involves
+% writing the sorted database to an external file and reading it in
+% on the next run. This requires checks to see if the location lists
+% have changed, in which case a new sort may be required.
+%
+%\begin{important}
+% The optimization function is only implemented when the sorting is
+% specified via the sort key. Any explicit sorting done by the user
+% via commands such as \ics{dltsort} are not effected by the
+% optimization setting.
+%\end{important}
+%
+%\begin{macro}{\datagidx@do@sort}
+% Indicate what to do when it's time to sort the index/glossary.
+% This defaults to un-optimised setting to avoid confusing users who
+% don't like to read the manual.
+% \begin{macrocode}
+\newcommand*{\datagidx@do@sort}{\datagidx@sort}
+% \end{macrocode}
+%\end{macro}
+%
+% First deal with the low-level optimization as it's easier to
+% implement.
+%
+%\begin{macro}{\datagidx@optimize@sort}
+% The code to perform when the low optimize setting is on.
+% If the command \ics{datagidx@do@optimize@sort} has been defined,
+% do the sort. If it hasn't been defined, don't sort. If a sort
+% isn't performed, the command definition is written to the aux
+% file. If a sort is performed, the command definition isn't written
+% to the aux file. This will do the sort every other run.
+% \begin{macrocode}
+\newcommand*{\datagidx@optimize@sort}{%
+% \end{macrocode}
+% First, has \cs{datagidx@do@optimize@sort} been defined?
+% \begin{macrocode}
+ \ifdef\datagidx@do@optimize@sort
+ {%
+% \end{macrocode}
+% It has been defined so go ahead and do the sort.
+% \begin{macrocode}
+ \datagidx@sort
+ }%
+ {%
+% \end{macrocode}
+% It hasn't been defined so don't sort. Write the command definition
+% into the aux file for the next run.
+% \begin{macrocode}
+ \protected@write\@auxout{}{%
+ \string\gdef\string\datagidx@do@optimize@sort{}%
+ }%
+% \end{macrocode}
+% Let the user know they need to recompile the document.
+% \begin{macrocode}
+ \global\let\@datagidx@dorerun@warn@sort\@data@rerun@warn@sort
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@datagidx@dorerun@warn}
+% \begin{macrocode}
+\newcommand*\@datagidx@dorerun@warn{}
+\AtEndDocument{\@datagidx@dorerun@warn}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@datagidx@dorerun@warn@sort}
+% \begin{macrocode}
+\newcommand*\@datagidx@dorerun@warn@sort{}
+\AtEndDocument{\@datagidx@dorerun@warn@sort}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@datagidx@rerun@warn@sort}
+% Warning issued when a rerun is required to sort the index or
+% glossary.
+% \begin{macrocode}
+\newcommand*\@data@rerun@warn@sort{%
+ \PackageWarningNoLine{datagidx}{Rerun required to sort the
+ index/glossary databases}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@datagidx@rerun@warn}
+% Warning issued when a rerun is required to update the location
+% lists.
+% \begin{macrocode}
+\newcommand*\@data@rerun@warn{%
+ \PackageWarningNoLine{datagidx}{Rerun required to ensure the
+ index/glossary location lists are up-to-date}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%The high optimize setting is more complicated.
+% This involves writing each database to an external file (named
+% \cs{jobname}-\meta{db label}.gidx). The sort is only performed if
+% new terms are added or used.
+%
+%\begin{macro}{\datagidx@do@highopt@optimize}
+% \begin{macrocode}
+\newcommand*{\datagidx@do@highopt@optimize}{%
+ \renewcommand*{\datagidx@do@sort}{%
+% \end{macrocode}
+% Only sort if database has changed.
+% \begin{macrocode}
+ \ifcsdef{datagidx@do@highopt@sort@\DTLgidxCurrentdb}%
+ {%
+ \csuse{datagidx@do@highopt@sort@\DTLgidxCurrentdb}%
+ }%
+ {%
+% \end{macrocode}
+% Do nothing
+% \begin{macrocode}
+ }%
+% \end{macrocode}
+% Save the database to file.
+% \begin{macrocode}
+ \bgroup
+% \end{macrocode}
+% Hook into write macro to clear certain fields and protect commands
+% like \ics{DTLgidxName}.
+% \begin{macrocode}
+ \def\dtl@saverawdbhook{%
+ \let\db@col@id@w\@datagidx@db@col@id@w
+ \def\DTLgidxName{\string\DTLgidxName\space}%
+ \def\DTLgidxMac{\string\DTLgidxMac\space}%
+ \def\DTLgidxRank{\string\DTLgidxRank\space}%
+ \def\DTLgidxParen{\string\DTLgidxParen\space}%
+ \def\DTLgidxParticle{\string\DTLgidxParticle\space}%
+ \def\DTLgidxOffice{\string\DTLgidxOffice\space}%
+ \def\DTLgidxSaint{\string\DTLgidxSaint\space}%
+ \def\DTLgidxPlace{\string\DTLgidxPlace\space}%
+ \def\DTLgidxIgnore{\string\DTLgidxIgnore\space}%
+ \def\DTLgidxNameNum{\string\DTLgidxNameNum\space}%
+ \def\DTLgidxSubject{\string\DTLgidxSubject\space}%
+ }%
+ \DTLsaverawdb{\DTLgidxCurrentdb}{\datagidxhighoptfilename\DTLgidxCurrentdb}%
+ \egroup
+ }%
+% \end{macrocode}
+% Change the behaviour of \cs{newgidx}
+% \begin{macrocode}
+ \def\newgidx{\datagidx@highopt@newgidx}%
+% \end{macrocode}
+% Change the behaviour of \cs{newterm}
+% \begin{macrocode}
+ \def\newterm{\datagidx@highopt@newterm}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@datagidx@db@col@id@w}
+% A bit of trickery is need to clear the Used and Location fields when
+% writing the raw database to file.
+% \begin{macrocode}
+\def\@datagidx@db@col@id@w#1\db@col@id@end@\db@col@elt@w#2\db@col@elt@end@\db@col@id@w#3\db@col@id@end@{%
+ \expandafter\@gobble\string\%^^J
+ \string\db@col@id@w\space #1%
+ \expandafter\@gobble\string\%^^J
+ \string\db@col@id@end@\space
+ \expandafter\@gobble\string\%^^J
+ \string\db@col@elt@w\space
+ \expandafter\ifnum\csname dtl@ci@\DTLgidxCurrentdb @Used\endcsname=#1\space
+ 0%
+ \else
+ \expandafter\ifnum\csname dtl@ci@\DTLgidxCurrentdb @Location\endcsname=#1\space
+ \else
+ \expandafter\ifnum\csname dtl@ci@\DTLgidxCurrentdb @CurrentLocation\endcsname=#1\space
+ \else
+% \end{macrocode}
+% We also want to prevent the first character of the sort field from
+% being expanded to help get the group correct (in case the user
+% wants to sort on, say, the tilde character).
+% \begin{macrocode}
+ \expandafter\ifnum\csname dtl@ci@\DTLgidxCurrentdb @Sort\endcsname=#1\space
+ \protect#2%
+ \else
+ #2%
+ \fi
+ \fi
+ \fi
+ \fi
+ \expandafter\@gobble\string\%^^J
+ \string\db@col@elt@end@\space
+ \expandafter\@gobble\string\%^^J
+ \string\db@col@id@w\space #3%
+ \expandafter\@gobble\string\%^^J
+ \string\db@col@id@end@\space
+}
+% \end{macrocode}
+%\end{macro}
+%
+% With the `highopt optimize' setting, whenever a location is written to the aux
+% file, if no location has been defined the database needs sorting.
+%
+%\begin{macro}{\datagidx@do@highopt@update}
+% Default does nothing. (Argument is the entry's label.)
+% \begin{macrocode}
+\newcommand*{\datagidx@do@highopt@update}[1]{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxhighoptfilename}
+% Expands to the name of the filename associated with the database
+% identified by the argument for the `highopt' setting.
+% \begin{macrocode}
+\newcommand*{\datagidxhighoptfilename}[1]{\jobname-#1.gidx}
+% \end{macrocode}
+%\end{macro}
+%
+%\section{Package Options}
+%
+%\begin{option}{optimize}
+% A boolean option indicating whether or not to optimize the sort.
+% This is only available as a global option. If you want to optimize
+% some glossaries but not others, switch on the optimize function
+% and clear the sort key for the relevant glossaries and manually
+% sort using \ics{dtlsort} before the glossary is displayed.
+% \begin{macrocode}
+\define@choicekey{datagidx.sty}{optimize}[\val\nr]%
+ {off,low,high}[high]%
+ {%
+ \ifcase\nr\relax
+ \renewcommand*{\datagidx@do@sort}{\datagidx@sort}
+ \or
+ \renewcommand*{\datagidx@do@sort}{\datagidx@optimize@sort}
+ \or
+ \datagidx@do@highopt@optimize
+ \fi
+ }
+% \end{macrocode}
+%\end{option}
+%
+% These options govern the general layout of the glossary/index.
+%\begin{option}{columns}
+% The number of columns used by \env{multicols} (or
+% \env{multicols*}). If only one column is specified,
+% \env{multicols} (or \env{multicols*}) isn't used.
+% \begin{macrocode}
+\define@key{datagidx.sty}{columns}%
+{%
+ \DTLgidxSetColumns{#1}%
+}
+% \end{macrocode}
+%\end{option}
+%\begin{option}{child}
+% Indicates whether or not to show the name in child entries.
+% \begin{macrocode}
+\define@choicekey{datagidx.sty}{child}[\val\nr]%
+ {named,noname}%
+ {%
+ \datagidx@setchildstyle\nr
+ }
+% \end{macrocode}
+%\end{option}
+%\begin{option}{namecase}
+% Options for name case.
+% \begin{macrocode}
+\define@choicekey{datagidx.sty}{namecase}[\val\nr]%
+ {nochange,uc,lc,firstuc,capitalise}%
+ {%
+ \datagidx@setnamecase\nr
+ }
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{namefont}
+% Option to set the name font.
+% \begin{macrocode}
+\define@key{datagidx.sty}{namefont}%
+{%
+ \renewcommand*{\DTLgidxNameFont}[1]{{#1{##1}}}%
+}
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{postname}
+% What to put after the name.
+% \begin{macrocode}
+\define@key{datagidx.sty}{postname}
+{%
+ \renewcommand*{\DTLgidxPostName}{#1}%
+}
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{postdesc}
+% what to put after the description.
+% \begin{macrocode}
+\define@choicekey{datagidx.sty}{postdesc}[\val\nr]%
+ {none,dot}%
+ {%
+ \datagidx@setpostdesc\nr
+ }
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{prelocation}
+% What to put before the location list.
+% \begin{macrocode}
+\define@choicekey{datagidx.sty}{prelocation}[\val\nr]%
+ {none,enspace,space,dotfill,hfill}%
+ {%
+ \datagidx@setprelocation\nr
+ }
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{location}
+% How to display the location list.
+% \begin{macrocode}
+\define@choicekey{datagidx.sty}{location}[\val\nr]%
+ {hide,list,first}%
+ {\datagidx@setlocation\nr}
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{see}
+% How to display the cross-reference list.
+% \begin{macrocode}
+\define@choicekey{datagidx.sty}{see}[\val\nr]%
+ {comma,brackets,dot,space,nosep,semicolon,location}%
+ {\datagidx@setsee\nr}
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{symbol}
+% How to format the symbol in relation to the description.
+% \begin{macrocode}
+\define@choicekey{datagidx.sty}{symboldesc}[\val\nr]%
+ {symbol,desc,(symbol) desc,desc (symbol),symbol desc,desc symbol}%
+ {\datagidx@formatsymdesc\nr}
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{compositor}
+% Location compositor.
+% \begin{macrocode}
+\define@key{datagidx.sty}{compositor}%
+{%
+ \DTLgidxSetCompositor{#1}%
+}%
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{final}
+% \begin{macrocode}
+\DeclareOptionX{final}{%
+ \let\datagidxshowifdraft\@gobble
+}
+% \end{macrocode}
+% Set as default:
+% \begin{macrocode}
+\let\datagidxshowifdraft\@gobble
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{draft}
+% \begin{macrocode}
+\DeclareOptionX{draft}{%
+ \let\datagidxshowifdraft\@firstofone
+}
+% \end{macrocode}
+%\end{option}
+%
+%\begin{option}{verbose}
+% \begin{macrocode}
+\define@choicekey{datagidx.sty}{verbose}[\val\nr]%
+ {true,false}[true]%
+ {%
+ \csuse{dtlverbose\val}%
+ }
+% \end{macrocode}
+%\end{option}
+%
+% Process package options:
+% \begin{macrocode}
+\ProcessOptionsX
+% \end{macrocode}
+%
+% Database to keep track of all the defined terms.
+% \begin{macrocode}
+\DTLnewdb{datagidx}
+% \end{macrocode}
+%
+%\section{Glossary/Index Formatting}
+%\begin{macro}{\seename}
+% \begin{macrocode}
+\providecommand*{\seename}{see}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\seealsoname}
+% \begin{macrocode}
+\providecommand*{\seealsoname}{see also}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSeeTagFont}
+% \begin{macrocode}
+\newcommand*{\DTLgidxSeeTagFont}[1]{\emph{#1}}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxFormatSee}
+%\begin{definition}
+%\cs{DTLgidxFormatSee}\marg{tag}\marg{label list}
+%\end{definition}
+% \begin{macrocode}
+\newcommand*{\DTLgidxFormatSee}[2]{%
+ \DTLgidxSeeTagFont{#1} \DTLgidxSeeList{#2}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxFormatSeeAlso}
+%\begin{definition}
+%\cs{DTLgidxFormatSeeAlso}\marg{tag}\marg{label list}
+%\end{definition}
+% \begin{macrocode}
+\newcommand*{\DTLgidxFormatSeeAlso}[2]{%
+ \datagidxdoseealso
+ {%
+ \DTLgidxSeeTagFont{#1} \DTLgidxSeeList{#2}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxdoseealso}
+% \begin{macrocode}
+\newcommand*{\datagidxdoseealso}[1]{%
+ \datagidxseealsostart
+ #1%
+ \datagidxseealsoend
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSeeList}
+%\begin{definition}
+%\cs{DTLgidxSeeList}\marg{label list}
+%\end{definition}
+% \begin{macrocode}
+\newcommand*{\DTLgidxSeeList}[1]{%
+ \def\datagidx@sep{}%
+ \@for\dtl@thislabel:=#1\do
+ {%
+ \ifx\@xfor@nextelement\@nnil
+% \end{macrocode}
+% Last iteration.
+% \begin{macrocode}
+ \ifdefempty{\datagidx@sep}%
+ {%
+% \end{macrocode}
+% Only one element in the list.
+% \begin{macrocode}
+ }%
+ {%
+% \end{macrocode}
+% Not the only element in the list.
+% \begin{macrocode}
+ \DTLidxSeeLastSep
+ }%
+ \else
+% \end{macrocode}
+% Not last iteration
+% \begin{macrocode}
+ \datagidx@sep
+ \let\datagidx@sep\DTLidxSeeSep
+ \fi
+ \DTLidxFormatSeeItem{\dtl@thislabel}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLidxFormatSeeItem}
+%\begin{definition}
+%\cs{DTLidxFormatSeeItem}\marg{label}
+%\end{definition}
+% \begin{macrocode}
+\newcommand*{\DTLidxFormatSeeItem}[1]{%
+ \DTLgidxFetchEntry{\datagidx@value}{#1}{Name}%
+ \datagidxlink{#1}%
+ {%
+ \datagidx@value
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLidxSeeSep}
+% Separator in cross-reference list.
+% \begin{macrocode}
+\newcommand*{\DTLidxSeeSep}{, }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLidxSeeLastSep}
+% Final separator in cross-reference list.
+% \begin{macrocode}
+\newcommand*{\DTLidxSeeLastSep}{ \& }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxDoSeeOrLocation}
+% You should have both a ``see'' list and a location list. This
+% checks if \cs{See} is null. If it isn't null, it does the ``see''
+% part, otherwise it deals with the location list.
+% \begin{macrocode}
+\newcommand*{\DTLgidxDoSeeOrLocation}{%
+ \DTLifnull\See
+ {%
+% \end{macrocode}
+% \cs{See} is null. Do we have a location?
+% \begin{macrocode}
+ \ifdefempty\Location
+ {%
+ }%
+ {%
+ \DTLgidxPreLocation
+ \DTLgidxLocation
+ }%
+ }%
+ {%
+% \end{macrocode}
+% \cs{See} is not null, so do the cross-reference.
+% \begin{macrocode}
+ \DTLgidxSee
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@sortchildren}
+% The list of child labels needs to be sorted so that the child list
+% follows the same ordering as the database.
+% \begin{macrocode}
+\newcommand*{\datagidx@sortchildren}{%
+ \def\datagidx@sortedlist{}%
+ \@for\Label:=\Children\do
+ {%
+ \edef\do@getrow{%
+ \noexpand\dtlgetrowforvalue
+ {\DTLgidxCurrentdb}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Label}}%
+ {\Label}%
+ }%
+ \do@getrow
+% \end{macrocode}
+% Row index is stored in \cs{dtlrownum}. Is the sorted list empty?
+% \begin{macrocode}
+ \ifdefempty\datagidx@sortedlist
+ {%
+% \end{macrocode}
+% Yes, it's empty.
+% \begin{macrocode}
+ \edef\datagidx@newsortedlist{{\number\dtlrownum}{\Label}}%
+ }%
+ {%
+% \end{macrocode}
+% No, it's not empty. Need to insert into list.
+% \begin{macrocode}
+ \def\datagidx@newsortedlist{}%
+ \@for\@datagidx@thisval:=\datagidx@sortedlist\do
+ {%
+% \end{macrocode}
+% Get the index:
+% \begin{macrocode}
+ \edef\datagidx@thisidx{\expandafter\@firstoftwo\@datagidx@thisval}%
+% \end{macrocode}
+% Is index greater than \cs{dtlrownum}?
+% \begin{macrocode}
+ \ifnum\datagidx@thisidx>\dtlrownum\relax
+% \end{macrocode}
+% Yes, it is. So insert here.
+% \begin{macrocode}
+ \ifdefempty\datagidx@newsortedlist
+ {%
+ \eappto\datagidx@newsortedlist
+ {%
+ {\number\dtlrownum}{\Label},\@datagidx@thisval
+ }%
+ }%
+ {%
+ \eappto\datagidx@newsortedlist
+ {%
+ ,{\number\dtlrownum}{\Label},\@datagidx@thisval
+ }%
+ }%
+% \end{macrocode}
+% Break out of inner loop.
+% \begin{macrocode}
+ \@endfortrue
+ \else
+ \ifdefempty\datagidx@newsortedlist
+ {%
+ \edef\datagidx@newsortedlist{%
+ \@datagidx@thisval
+ }%
+ }%
+ {%
+ \eappto\datagidx@newsortedlist
+ {%
+ ,\@datagidx@thisval
+ }%
+ }%
+ \fi
+ }%
+% \end{macrocode}
+% Was the loop ended prematurely?
+% \begin{macrocode}
+ \if@endfor
+% \end{macrocode}
+% If loop was ended on the last iteration, \cs{@forremainder} will
+% be empty and there's nothing left to do.
+% \begin{macrocode}
+ \ifdefempty\@forremainder
+ {%
+ }%
+ {%
+% \end{macrocode}
+% Loop prematurely ended, so append remainder to list.
+ \eappto\datagidx@newsortedlist{,\@forremainder}%
+% \begin{macrocode}
+ }%
+ \else
+% \end{macrocode}
+% Loop wasn't prematurely terminated, so new value hasn't been
+% added. Add now.
+% \begin{macrocode}
+ \ifdefempty\datagidx@newsortedlist
+ {%
+ \edef\datagidx@newsortedlist{{\number\dtlrownum}{\Label}}%
+ }%
+ {%
+ \eappto\datagidx@newsortedlist{,{\number\dtlrownum}{\Label}}%
+ }%
+ \fi
+ }%
+% \end{macrocode}
+% Update.
+% \begin{macrocode}
+ \let\datagidx@sortedlist\datagidx@newsortedlist
+% \end{macrocode}
+% Don't break out of outer loop.
+% \begin{macrocode}
+ \@endforfalse
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@sort@foreachchild}
+% Sorted iteration through all the child labels.
+% \begin{macrocode}
+\newcommand{\datagidx@sort@foreachchild}[1]{%
+ \datagidx@sortchildren
+% \end{macrocode}
+% Sorted list stored in \cs{datagidx@sortedlist}
+% \begin{macrocode}
+ \@for\@datagidx@thisval:=\datagidx@sortedlist\do
+ {%
+ \edef\Label{\expandafter\@secondoftwo\@datagidx@thisval}%
+ #1%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@unsort@foreachchild}
+% Unsorted iteration through all the child labels.
+% \begin{macrocode}
+\newcommand{\datagidx@unsort@foreachchild}[1]{%
+ \@for\Label:=\Children\do
+ {%
+ #1%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\DTLgidxChildren}
+% How to display the children
+% \begin{macrocode}
+\newcommand*{\DTLgidxChildren}{%
+ \bgroup
+ \DTLifnull\Children
+ {}%
+ {%
+ \advance\datagidx@level by 1\relax
+ \datagidxchildstart
+ \let\Parent\Label
+ \datagidx@foreachchild
+ {%
+ \edef\do@getrow{%
+ \noexpand\dtlgetrowforvalue
+ {\DTLgidxCurrentdb}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Label}}%
+ {\Label}%
+ }%
+ \do@getrow
+ \dtlgetentryfromcurrentrow
+ {\Location}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Location}}%
+ \dtlgetentryfromcurrentrow
+ {\See}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{See}}%
+ \dtlgetentryfromcurrentrow
+ {\SeeAlso}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{SeeAlso}}%
+ \DTLifnull\Location
+ {%
+ \DTLifnull\See
+ {%
+ \DTLifnull\SeeAlso
+ {}%
+ {%
+ \datagidx@displaychild
+ }%
+ }%
+ {%
+ \datagidx@displaychild
+ }%
+ }%
+ {%
+ \datagidx@displaychild
+ }%
+ }%
+ \datagidxchildend
+ }%
+ \egroup
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxgetchildfields}
+% Get the child fields from the current row.
+% \begin{macrocode}
+\newcommand*{\datagidxgetchildfields}{%
+ \dtlgetentryfromcurrentrow
+ {\Name}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Name}}%
+ \dtlgetentryfromcurrentrow
+ {\Description}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Description}}%
+ \dtlgetentryfromcurrentrow
+ {\Symbol}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Symbol}}%
+ \dtlgetentryfromcurrentrow
+ {\Long}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Long}}%
+ \dtlgetentryfromcurrentrow
+ {\Short}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Short}}%
+ \dtlgetentryfromcurrentrow
+ {\Text}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Text}}%
+ \dtlgetentryfromcurrentrow
+ {\Plural}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Plural}}%
+ \dtlgetentryfromcurrentrow
+ {\Short}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Used}}%
+ \dtlgetentryfromcurrentrow
+ {\Children}%
+ {\dtlcolumnindex{\DTLgidxCurrentdb}{Child}}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@displaychild}
+% \begin{macrocode}
+\newcommand*{\datagidx@displaychild}{%
+ \datagidxgetchildfields
+ \datagidxchilditem
+}
+% \end{macrocode}
+%\end{macro}
+%
+%
+% Define some keys for \ics{newgloss}:
+%\begin{macro}{\datagidx@heading}
+% Indicates how to format the heading in the glossary/index.
+% \begin{macrocode}
+\ifdef{\chapter}
+{%
+ \newcommand*{\datagidx@heading}{\chapter*}
+}%
+{%
+ \newcommand*{\datagidx@heading}{\section*}
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\DTLgidxNoHeading}
+% Allow user to suppress the heading. (So to suppress the
+% heading do \texttt{heading=\cs{DTLgidxNoHeading}}).
+% \begin{macrocode}
+\let\DTLgidxNoHeading\@gobble
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@postheading}
+% Indicates what to do immediately after the heading.
+% \begin{macrocode}
+\newcommand*{\datagidx@postheading}{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@multicols}
+% Should we use \env{multicols} or \env{multicols*}?
+% \begin{macrocode}
+\newcommand*{\datagidx@multicols}{multicols}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@sort}
+% Indicates how to sort the glossary/index.
+% Defaults to word order.
+% \begin{macrocode}
+\newcommand*{\datagidx@sort}{%
+ \dtlsort{Sort,FirstId}{\DTLgidxCurrentdb}{\dtlwordindexcompare}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidxstart}
+% Indicates what to do at the start of the glossary/index.
+% \begin{macrocode}
+\newcommand*{\datagidxstart}%
+{%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \let\item\@idxitem
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidxend}
+% Indicates what to do at the end of the glossary/index.
+% \begin{macrocode}
+\newcommand*{\datagidxend}{\egroup}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxtarget}
+% Provide a means to add a hypertarget if \ics{hypertarget} has been
+% defined.
+% \begin{macrocode}
+\newcommand*{\@datagidxtarget}[2]{%
+ \ifdef\hypertarget
+ {%
+ \bgroup
+ \let\glsadd\@gobble
+ \settoheight\dimen@{#2}%
+ \raisebox{\dimen@}{\hypertarget{#1}{}}%
+ \egroup
+ }%
+ {%
+ }%
+ #2%
+}
+\newcommand*{\datagidxtarget}{\@datagidxtarget}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxlink}
+% Provide a means to add a link if \ics{hyperlink} has been
+% defined.
+% \begin{macrocode}
+\newcommand*{\@datagidxlink}[2]{%
+ \ifdef\hyperlink
+ {%
+ \hyperlink{#1}{#2}%
+ }%
+ {%
+ #2%
+ }%
+}
+\newcommand*{\datagidxlink}{\@datagidxlink}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxEnableHyper}
+% Enable hyperlinks (if they are defined).
+% \begin{macrocode}
+\newcommand*{\DTLgidxEnableHyper}{%
+ \let\datagidxtarget\@datagidxtarget
+ \let\datagidxlink\@datagidxlink
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxDisableHyper}
+% Disable hyperlinks (if they are defined).
+% \begin{macrocode}
+\newcommand*{\DTLgidxDisableHyper}{%
+ \let\datagidxtarget\@secondoftwo
+ \let\datagidxlink\@secondoftwo
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxgroupsep}
+% Indicates what to do between groups (after the previous group and
+% before the header of the next group).
+% \begin{macrocode}
+\newcommand*{\datagidxgroupsep}{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxgroupheader}
+% Indicates what to do at the start of a group. (The current group
+% label can be accessed via \cs{datagidxcurrentgroup} and the previous
+% group label can be accessed via \cs{datagidxprevgroup}.)
+% \begin{macrocode}
+\newcommand*{\datagidxgroupheader}{}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\datagidxitem}
+% Indicates what to do at the start of each item of the glossary/index.
+% \begin{macrocode}
+\newcommand*{\datagidxitem}{}%
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxchildstart}
+% Indicates what to do at the start of the child glossary/index.
+% \begin{macrocode}
+\newcommand*{\datagidxchildstart}{}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidxchildend}
+% Indicates what to do at the end of the child glossary/index.
+% \begin{macrocode}
+\newcommand*{\datagidxchildend}{}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidxchilditem}
+% Indicates what to do at the start of each item of the child glossary/index.
+% \begin{macrocode}
+\newcommand*{\datagidxchilditem}{}%
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxseealsostart}
+% Indicates what to do at the start of the ``see also'' list.
+% \begin{macrocode}
+\newcommand*{\datagidxseealsostart}{}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidxseealsoend}
+% Indicates what to do at the end of the ``see also'' list.
+% \begin{macrocode}
+\newcommand*{\datagidxseealsoend}{}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\datagidx@doifsymlocwidth}
+%\begin{definition}
+%\cs{datagidx@doifsymlocwidth}\marg{indent}\marg{Name code}\marg{Location code}
+%\end{definition}
+% What to do if both the symbol width and the location width have
+% been set.
+% \begin{macrocode}
+\newcommand*{\datagidx@doifsymlocwidth}[3]{%
+% \end{macrocode}
+% Calculate remaining space left for the description.
+% \begin{macrocode}
+ \setlength{\dtl@tmplength}{\linewidth}%
+ \addtolength{\dtl@tmplength}{-#1}%
+ \settowidth{\dimen@}{#2}%
+ \addtolength{\dtl@tmplength}{-\dimen@}%
+ \addtolength{\dtl@tmplength}{-\datagidxsymbolwidth}%
+ \addtolength{\dtl@tmplength}{-\datagidxlocationwidth}%
+ \settowidth{\dimen@}{\DTLgidxPreLocation}%
+ \addtolength{\dtl@tmplength}{-\dimen@}%
+ \settowidth{\dimen@}{\DTLgidxSymDescSep}%
+ \addtolength{\dtl@tmplength}{-\dimen@}%
+ \if@datagidxsymbolleft
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\dtl@tmplength}%
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescRight
+ \end{minipage}%
+ \else
+ \begin{minipage}[t]{\dtl@tmplength}%
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescRight
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \fi
+ \DTLgidxPreLocation
+ \begin{minipage}[t]{\datagidxlocationwidth}%
+ \datagidxlocalign
+ \let\DTLgidxPreLocation\@empty
+ #3%
+ \end{minipage}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@doiflocwidth}
+%\begin{definition}
+%\cs{datagidx@doiflocwidth}\marg{indent}\marg{Name code}\marg{Location code}
+%\end{definition}
+% What to do if only the location width has
+% been set.
+% \begin{macrocode}
+\newcommand*{\datagidx@doiflocwidth}[3]{%
+% \end{macrocode}
+% Calculate remaining space left for the symbol and description.
+% \begin{macrocode}
+ \setlength{\dtl@tmplength}{\linewidth}%
+ \addtolength{\dtl@tmplength}{-#1}%
+ \settowidth{\dimen@}{#2}%
+ \addtolength{\dtl@tmplength}{-\dimen@}%
+ \addtolength{\dtl@tmplength}{-\datagidxlocationwidth}%
+ \settowidth{\dimen@}{\DTLgidxPreLocation}%
+ \addtolength{\dtl@tmplength}{-\dimen@}%
+ \begin{minipage}[t]{\dtl@tmplength}%
+ \DTLgidxSymbolDescription
+ \end{minipage}%
+ \DTLgidxPreLocation
+ \begin{minipage}[t]{\datagidxlocationwidth}%
+ \datagidxlocalign
+ \let\DTLgidxPreLocation\@empty
+ #3%
+ \end{minipage}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@doifsymwidth}
+%\begin{definition}
+%\cs{datagidx@doifsymwidth}\marg{indent}\marg{Name code}\marg{Location code}
+%\end{definition}
+% What to do if only the location width has
+% been set.
+% \begin{macrocode}
+\newcommand*{\datagidx@doifsymwidth}[3]{%
+% \end{macrocode}
+% Calculate remaining space left for the description and location.
+% \begin{macrocode}
+ \setlength{\dtl@tmplength}{\linewidth}%
+ \addtolength{\dtl@tmplength}{-#1}%
+ \settowidth{\dimen@}{#2}%
+ \addtolength{\dtl@tmplength}{-\dimen@}%
+ \addtolength{\dtl@tmplength}{-\datagidxsymbolwidth}%
+ \settowidth{\dimen@}{\DTLgidxSymDescSep}%
+ \addtolength{\dtl@tmplength}{-\dimen@}%
+ \if@datagidxsymbolleft
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\dtl@tmplength}%
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescRight
+ #3%
+ \end{minipage}%
+ \else
+ \begin{minipage}[t]{\dtl@tmplength}%
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescRight
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+% \end{macrocode}
+% This arrangement may look a bit weird.
+% \begin{macrocode}
+ #3%
+ \end{minipage}%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxlocalign}
+% Alignment of the location when the location width has been set.
+% \begin{macrocode}
+\newcommand*{\datagidxlocalign}{\raggedleft}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxsymalign}
+% Alignment of the symbol when the symbol width has been set.
+% \begin{macrocode}
+\newcommand*{\datagidxsymalign}{\centering}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\subsection{Predefined styles}
+%
+%\begin{macro}{\datagidxsetstyle}
+% Sets the current index/glossary style
+% \begin{macrocode}
+\newcommand*{\datagidxsetstyle}[1]{%
+ \ifcsdef{datagidx@style@#1}%
+ {%
+ \csuse{datagidx@style@#1}%
+ }%
+ {%
+ \PackageError{datagidx}{Unknown style `#1'}{}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\subsubsection{index}
+%\begin{macro}{\datagidx@style@index}
+% Basic index style.
+% \begin{macrocode}
+\newcommand*{\datagidx@style@index}{%
+ \renewcommand*{\datagidxstart}%
+ {%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+% \end{macrocode}
+% Index columns are usually too narrow for fully justified text.
+% \begin{macrocode}
+ \raggedright
+ \let\item\@idxitem
+% \end{macrocode}
+% Have the symbol or location widths been set?
+% \begin{macrocode}
+ \ifdim\datagidxsymbolwidth>0pt\relax
+% \end{macrocode}
+% Symbol width has been set
+% Has the location width been set?
+% \begin{macrocode}
+ \ifdim\datagidxlocationwidth>0pt\relax
+% \end{macrocode}
+% Both have been set.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \datagidx@doifsymlocwidth{0pt}%
+ {\DTLgidxNameFont{\DTLgidxNameCase{\Name}}}%
+ {%
+ \DTLgidxDoSeeOrLocation
+ }%
+ }%
+ \else
+% \end{macrocode}
+% Location width hasn't been set.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \datagidx@doiflocwidth{0pt}%
+ {\DTLgidxNameFont{\DTLgidxNameCase{\Name}}}%
+ {%
+ \DTLgidxDoSeeOrLocation
+ }%
+ }%
+ \fi
+ \else
+% \end{macrocode}
+% Symbol width hasn't been set
+% Has the location width been set?
+% \begin{macrocode}
+ \ifdim\datagidxlocationwidth>0pt\relax
+% \end{macrocode}
+% Location width has been set.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \datagidx@doiflocwidth{0pt}%
+ {\DTLgidxNameFont{\DTLgidxNameCase{\Name}}}%
+ {%
+ \DTLgidxDoSeeOrLocation
+ }%
+ }%
+ \else
+% \end{macrocode}
+% Neither have been set.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \DTLgidxSymbolDescription
+ \DTLgidxDoSeeOrLocation
+ }%
+ \fi
+ \fi
+ }%
+ \renewcommand*{\datagidxend}{\egroup}%
+ \renewcommand*{\datagidxgroupsep}{\ifdatagidxshowgroups\indexspace\fi}%
+ \renewcommand{\datagidxgroupheader}{%
+ \ifdatagidxshowgroups
+ \item
+ \makebox[\linewidth]%
+ {%
+ \textbf{\DTLgidxGroupHeaderTitle{\datagidxcurrentgroup}}%
+ }%
+ \DTLpar\nobreak\@afterheading
+ \fi
+ }%
+ \renewcommand*{\datagidxitem}{%
+% \end{macrocode}
+% Is this the start of a new group?
+% \begin{macrocode}
+ \ifdefempty\datagidxprevgroup
+ {%
+% \end{macrocode}
+% First item of the list.
+% \begin{macrocode}
+ \datagidxgroupheader
+ }%
+ {%
+% \end{macrocode}
+% Not the first item of the list. Is this item's group the same as
+% the last item's group?
+% \begin{macrocode}
+ \ifdefequal\datagidxcurrentgroup\datagidxprevgroup
+ {%
+% \end{macrocode}
+% Same, so do nothing.
+% \begin{macrocode}
+ }%
+ {%
+% \end{macrocode}
+% Different, so do the separator and the header.
+% \begin{macrocode}
+ \datagidxgroupsep
+ \datagidxgroupheader
+ }%
+ }%
+% \end{macrocode}
+% Now get on with this item.
+% \begin{macrocode}
+ \item
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ }%
+ \DTLgidxPostName
+ \datagidx@item@body
+ \DTLgidxChildrenSeeAlso
+ }%
+ \renewcommand*{\datagidxchildstart}%
+ {%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \let\item\@idxitem
+ }%
+ \renewcommand*{\datagidxchildend}{\egroup}%
+ \renewcommand*{\datagidxchilditem}{%
+ \setlength{\dimen@}{\datagidxindent}%
+ \multiply\dimen@ by \datagidx@level\relax
+ \@idxitem\hspace*{\dimen@}%
+ \refstepcounter{DTLgidxChildCount}%
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxChildStyle
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ \DTLgidxPostChildName
+ }%
+ }%
+ \DTLgidxSymbolDescription
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ }%
+ \renewcommand*{\datagidxseealsostart}%
+ {%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \setlength{\dimen@}{\datagidxindent}%
+ \advance\datagidx@level by 1\relax
+ \multiply\dimen@ by \datagidx@level\relax
+ \@idxitem\hspace*{\dimen@}%
+ }%
+ \renewcommand{\datagidxseealsoend}{\egroup}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%Make this the default style:
+% \begin{macrocode}
+\datagidx@style@index
+% \end{macrocode}
+%
+%\subsubsection{indexalign}
+% Similar to index style but aligns the descriptions.
+%\begin{macro}{\datagidx@style@indexalign}
+% \begin{macrocode}
+\newcommand*{\datagidx@style@indexalign}{%
+ \renewcommand*{\datagidxstart}%
+ {%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \setlength{\datagidxnamewidth}{0pt}%
+ \DTLforeach*{\DTLgidxCurrentdb}%
+ {\Name=Name,\Location=Location,\See=See,\SeeAlso=SeeAlso,%
+ \Parent=Parent}%
+ {%
+ \DTLifnull{\Parent}%
+ {%
+ \datagidx@doifdisplayed
+ {%
+ \settowidth{\dimen@}{\DTLgidxNameFont{\DTLgidxNameCase{\Name}}}%
+ \ifdim\dimen@>\datagidxnamewidth\relax
+ \datagidxnamewidth=\dimen@\relax
+ \fi
+ }%
+ }%
+ {}%
+ }%
+ \settowidth{\dimen@}{\DTLgidxPostName}%
+ \addtolength{\datagidxnamewidth}{\dimen@}%
+ \setlength{\datagidxdescwidth}{\linewidth}%
+ \addtolength{\datagidxdescwidth}{-\datagidxnamewidth}%
+ \ifdim\datagidxsymbolwidth>0pt\relax
+ \addtolength{\datagidxdescwidth}{-\datagidxsymbolwidth}%
+ \settowidth{\dimen@}{\DTLgidxSymDescSep}%
+ \addtolength{\datagidxdescwidth}{-\dimen@}%
+ \fi
+ \ifdim\datagidxlocationwidth>0pt\relax
+ \addtolength{\datagidxdescwidth}{-\datagidxlocationwidth}%
+ \settowidth{\dimen@}{\DTLgidxPreLocation}%
+ \addtolength{\datagidxdescwidth}{-\dimen@}%
+ \fi
+% \end{macrocode}
+% Has the symbol width been set?
+% \begin{macrocode}
+ \ifdim\datagidxsymbolwidth>0pt\relax
+% \end{macrocode}
+% Yes, symbol width has been set.
+% Has the location width been set?
+% \begin{macrocode}
+ \ifdim\datagidxlocationwidth>0pt\relax
+% \end{macrocode}
+% Both symbol and location widths have been set.
+% \begin{macrocode}
+ \if@datagidxsymbolleft
+% \end{macrocode}
+% Symbol is on the left.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \let\DTLgidxSymDescSep\@empty
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescRight
+ \end{minipage}%
+ \DTLgidxPreLocation
+ \begin{minipage}[t]{\datagidxlocationwidth}%
+ \datagidxlocalign
+ \let\DTLgidxPreLocation\@empty
+ \DTLgidxDoSeeOrLocation
+ \end{minipage}%
+ }%
+ \else
+% \end{macrocode}
+% Symbol is on the right.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescRight
+ \end{minipage}%
+ \DTLgidxPreLocation
+ \begin{minipage}[t]{\datagidxlocationwidth}%
+ \datagidxlocalign
+ \let\DTLgidxPreLocation\@empty
+ \DTLgidxDoSeeOrLocation
+ \end{minipage}%
+ }%
+ \fi
+ \else
+% \end{macrocode}
+% Location width hasn't been set. (Only symbol width has been set.)
+% \begin{macrocode}
+ \if@datagidxsymbolleft
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \let\DTLgidxSymDescSep\@empty
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescRight
+ \DTLgidxDoSeeOrLocation
+ \end{minipage}%
+ }%
+ \else
+% \end{macrocode}
+% Symbol is on the right.
+% This combination may look weird.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescRight
+ \DTLgidxDoSeeOrLocation
+ \end{minipage}%
+ }%
+ \fi
+ \fi
+ \else
+% \end{macrocode}
+% Symbol width hasn't been set.
+% Has the location width been set?
+% \begin{macrocode}
+ \ifdim\datagidxlocationwidth>0pt\relax
+% \end{macrocode}
+% Only location width has been set.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescription
+ \end{minipage}%
+ \DTLgidxPreLocation
+ \begin{minipage}[t]{\datagidxlocationwidth}%
+ \datagidxlocalign
+ \let\DTLgidxPreLocation\@empty
+ \DTLgidxDoSeeOrLocation
+ }%
+ \else
+% \end{macrocode}
+% Neither location nor symbol widths have been set.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescription
+ \DTLgidxDoSeeOrLocation
+ \end{minipage}%
+ }%
+ \fi
+ \fi
+ }%
+ \renewcommand*{\datagidxend}{\egroup}%
+ \renewcommand*{\datagidxgroupsep}{}%
+ \renewcommand*{\datagidxgroupheader}{}%
+ \renewcommand*{\datagidxitem}{%
+% \end{macrocode}
+% Is this the start of a new group?
+% \begin{macrocode}
+ \ifdefempty\datagidxprevgroup
+ {%
+% \end{macrocode}
+% First item of the list.
+% \begin{macrocode}
+ \datagidxgroupheader
+ }%
+ {%
+% \end{macrocode}
+% Not the first item of the list. Is this item's group the same as
+% the last item's group?
+% \begin{macrocode}
+ \ifdefequal\datagidxcurrentgroup\datagidxprevgroup
+ {%
+% \end{macrocode}
+% Same, so do nothing.
+% \begin{macrocode}
+ }%
+ {%
+% \end{macrocode}
+% Different, so do the separator and the header.
+% \begin{macrocode}
+ \datagidxgroupsep
+ \datagidxgroupheader
+ }%
+ }%
+% \end{macrocode}
+% Get on with this item
+% \begin{macrocode}
+ \hangindent0pt\relax
+ \parindent0pt\relax
+ \makebox[\datagidxnamewidth][l]%
+ {%
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ \DTLgidxPostName
+ }%
+ }%
+ \datagidx@item@body
+ \par
+ \DTLgidxChildrenSeeAlso
+ \par
+ }%
+ \renewcommand*{\datagidxchildstart}%
+ {%
+ \bgroup
+ \setlength{\dimen@}{\datagidxindent}%
+ \multiply\dimen@ by \datagidx@level\relax
+ \setlength{\dtl@tmplength}{\linewidth}%
+ \addtolength{\dtl@tmplength}{-\dimen@}%
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \edef\item{\noexpand\parshape=1 \the\dimen@ \the\dtl@tmplength}%
+ \setlength{\datagidxnamewidth}{0pt}%
+ \DTLforeach*{\DTLgidxCurrentdb}%
+ {\Name=Name,\Location=Location,\See=See,\SeeAlso=SeeAlso,%
+ \Parent=Parent}%
+ {%
+ \DTLifnull{\Parent}%
+ {%
+ \datagidx@doifdisplayed
+ {%
+ \settowidth{\dimen@}%
+ {%
+ \DTLgidxChildStyle
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ }%
+ }%
+ \ifdim\dimen@>\datagidxnamewidth\relax
+ \datagidxnamewidth=\dimen@\relax
+ \fi
+ }%
+ }%
+ {}%
+ }%
+ \settowidth{\dimen@}{\DTLgidxChildStyle\DTLgidxPostChildName}%
+ \addtolength{\datagidxnamewidth}{\dimen@}%
+ \setlength{\datagidxdescwidth}{\dtl@tmplength}%
+ \addtolength{\datagidxdescwidth}{-\datagidxnamewidth}%
+ }%
+ \renewcommand{\datagidxchildend}{\egroup}%
+ \renewcommand*{\datagidxchilditem}{%
+ \item
+ \refstepcounter{DTLgidxChildCount}%
+ \makebox[\datagidxnamewidth][l]%
+ {%
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxChildStyle
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ \DTLgidxPostChildName
+ }%
+ }%
+ }%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescription
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ \end{minipage}%
+ \par
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidxindent}
+% Indent used by "index" and "indexalign" styles.
+% \begin{macrocode}
+\newlength\datagidxindent
+\setlength\datagidxindent{10\p@}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\subsubsection{align}
+%\begin{macro}{\datagidxnamewidth}
+% Length used by "align" and "indexalign" style name.
+% \begin{macrocode}
+\newlength\datagidxnamewidth
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxdescwidth}
+% Length used by "align" and "indexalign" style description.
+% \begin{macrocode}
+\newlength\datagidxdescwidth
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@style@align}
+% \begin{macrocode}
+\newcommand*{\datagidx@style@align}{%
+ \renewcommand*{\datagidxstart}%
+ {%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \setlength{\datagidxnamewidth}{0pt}%
+ \DTLforeach*{\DTLgidxCurrentdb}%
+ {\Name=Name,\Location=Location,\See=See,\SeeAlso=SeeAlso,%
+ \Parent=Parent}%
+ {%
+ \DTLifnull{\Parent}%
+ {%
+ \datagidx@doifdisplayed
+ {%
+ \settowidth{\dimen@}{\DTLgidxNameFont{\DTLgidxNameCase{\Name}}}%
+ \ifdim\dimen@>\datagidxnamewidth\relax
+ \datagidxnamewidth=\dimen@\relax
+ \fi
+ }%
+ }%
+ {}%
+ }%
+ \settowidth{\dimen@}{\DTLgidxPostName}%
+ \addtolength{\datagidxnamewidth}{\dimen@}%
+ \setlength{\datagidxdescwidth}{\linewidth}%
+ \addtolength{\datagidxdescwidth}{-\datagidxnamewidth}%
+ \ifdim\datagidxsymbolwidth>0pt\relax
+ \addtolength{\datagidxdescwidth}{-\datagidxsymbolwidth}%
+ \settowidth{\dimen@}{\DTLgidxSymDescSep}%
+ \addtolength{\datagidxdescwidth}{-\dimen@}%
+ \fi
+ \ifdim\datagidxlocationwidth>0pt\relax
+ \addtolength{\datagidxdescwidth}{-\datagidxlocationwidth}%
+ \settowidth{\dimen@}{\DTLgidxPreLocation}%
+ \addtolength{\datagidxdescwidth}{-\dimen@}%
+ \fi
+% \end{macrocode}
+% Has the symbol width been set?
+% \begin{macrocode}
+ \ifdim\datagidxsymbolwidth>0pt\relax
+% \end{macrocode}
+% Yes, symbol width has been set.
+% Has the location width been set?
+% \begin{macrocode}
+ \ifdim\datagidxlocationwidth>0pt\relax
+% \end{macrocode}
+% Both symbol and location widths have been set.
+% \begin{macrocode}
+ \if@datagidxsymbolleft
+% \end{macrocode}
+% Symbol is on the left.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \let\DTLgidxSymDescSep\@empty
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescRight
+ \end{minipage}%
+ \DTLgidxPreLocation
+ \begin{minipage}[t]{\datagidxlocationwidth}%
+ \datagidxlocalign
+ \let\DTLgidxPreLocation\@empty
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ \end{minipage}%
+ }%
+ \else
+% \end{macrocode}
+% Symbol is on the right.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescRight
+ \end{minipage}%
+ \DTLgidxPreLocation
+ \begin{minipage}[t]{\datagidxlocationwidth}%
+ \datagidxlocalign
+ \let\DTLgidxPreLocation\@empty
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ \end{minipage}%
+ }%
+ \fi
+ \else
+% \end{macrocode}
+% Location width hasn't been set. (Only symbol width has been set.)
+% \begin{macrocode}
+ \if@datagidxsymbolleft
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \let\DTLgidxSymDescSep\@empty
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescRight
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ \end{minipage}%
+ }%
+ \else
+% \end{macrocode}
+% Symbol is on the right.
+% This combination may look weird.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \let\DTLgidxSymDescSep\@empty
+ \DTLgidxSymbolDescLeft
+ \end{minipage}%
+ \DTLgidxSymDescSep
+ \begin{minipage}[t]{\datagidxsymbolwidth}%
+ \datagidxsymalign
+ \let\DTLgidxSymDescSep\@empty
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescRight
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ \end{minipage}%
+ }%
+ \fi
+ \fi
+ \else
+% \end{macrocode}
+% Symbol width hasn't been set.
+% Has the location width been set?
+% \begin{macrocode}
+ \ifdim\datagidxlocationwidth>0pt\relax
+% \end{macrocode}
+% Only location width has been set.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescription
+ \end{minipage}%
+ \DTLgidxPreLocation
+ \begin{minipage}[t]{\datagidxlocationwidth}%
+ \datagidxlocalign
+ \let\DTLgidxPreLocation\@empty
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ \end{minipage}%
+ }%
+ \else
+% \end{macrocode}
+% Neither location nor symbol widths have been set.
+% \begin{macrocode}
+ \def\datagidx@item@body{%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescription
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ \end{minipage}%
+ }%
+ \fi
+ \fi
+ }%
+ \renewcommand*{\datagidxend}{\egroup}%
+ \renewcommand*{\datagidxgroupsep}{\ifdatagidxshowgroups\indexspace\fi}%
+ \renewcommand{\datagidxgroupheader}{%
+ \ifdatagidxshowgroups
+ \item
+ \makebox[\linewidth]%
+ {%
+ \textbf{\DTLgidxGroupHeaderTitle{\datagidxcurrentgroup}}%
+ }%
+ \DTLpar\nobreak\@afterheading
+ \fi
+ }%
+ \renewcommand*{\datagidxitem}{%
+% \end{macrocode}
+% Is this the start of a new group?
+% \begin{macrocode}
+ \ifdefempty\datagidxprevgroup
+ {%
+% \end{macrocode}
+% First item of the list.
+% \begin{macrocode}
+ \datagidxgroupheader
+ }%
+ {%
+% \end{macrocode}
+% Not the first item of the list. Is this item's group the same as
+% the last item's group?
+% \begin{macrocode}
+ \ifdefequal\datagidxcurrentgroup\datagidxprevgroup
+ {%
+% \end{macrocode}
+% Same, so do nothing.
+% \begin{macrocode}
+ }%
+ {%
+% \end{macrocode}
+% Different, so do the separator and the header.
+% \begin{macrocode}
+ \datagidxgroupsep
+ \datagidxgroupheader
+ }%
+ }%
+ \hangindent0pt\relax
+ \parindent0pt\relax
+ \makebox[\datagidxnamewidth][l]%
+ {%
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ \DTLgidxPostName
+ }%
+ }%
+ \datagidx@item@body
+ \par
+ }%
+ \renewcommand*{\datagidxchildstart}%
+ {%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \setlength{\datagidxnamewidth}{0pt}%
+ \DTLforeach*{\DTLgidxCurrentdb}%
+ {\Name=Name,\Location=Location,\See=See,\SeeAlso=SeeAlso,%
+ \Parent=Parent}%
+ {%
+ \DTLifnull{\Parent}%
+ {%
+ \datagidx@doifdisplayed
+ {%
+ \settowidth{\dimen@}%
+ {%
+ \DTLgidxChildStyle
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ }%
+ }%
+ \ifdim\dimen@>\datagidxnamewidth\relax
+ \datagidxnamewidth=\dimen@\relax
+ \fi
+ }%
+ }%
+ {}%
+ }%
+ \settowidth{\dimen@}{\DTLgidxChildStyle\DTLgidxPostChildName}%
+ \addtolength{\datagidxnamewidth}{\dimen@}%
+ \setlength{\datagidxdescwidth}{\linewidth}%
+ \addtolength{\datagidxdescwidth}{-\datagidxnamewidth}%
+ }%
+ \renewcommand{\datagidxchildend}{\egroup}%
+ \renewcommand*{\datagidxchilditem}{%
+ \hangindent0pt\relax
+ \parindent0pt\relax
+ \refstepcounter{DTLgidxChildCount}%
+ \makebox[\datagidxnamewidth][l]%
+ {%
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxChildStyle
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ \DTLgidxPostChildName
+ }%
+ }%
+ }%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \DTLgidxSymbolDescription
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ \end{minipage}%
+ \par
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\subsubsection{gloss}
+%\begin{macro}{\datagidx@style@gloss}
+% \begin{macrocode}
+\newcommand*{\datagidx@style@gloss}{%
+ \renewcommand*{\datagidxstart}%
+ {%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \setlength{\datagidxnamewidth}{0pt}%
+ \DTLforeach*{\DTLgidxCurrentdb}%
+ {\Name=Name,\Location=Location,\See=See,\SeeAlso=SeeAlso,%
+ \Parent=Parent}%
+ {%
+ \DTLifnull{\Parent}%
+ {%
+ \datagidx@doifdisplayed
+ {%
+ \settowidth{\dimen@}{\DTLgidxNameFont{\DTLgidxNameCase{\Name}}}%
+ \ifdim\dimen@>\datagidxnamewidth\relax
+ \datagidxnamewidth=\dimen@\relax
+ \fi
+ }%
+ }%
+ {}%
+ }%
+ \settowidth{\dimen@}{\DTLgidxPostName}%
+ \addtolength{\datagidxnamewidth}{\dimen@}%
+ \setlength{\datagidxdescwidth}{\linewidth}%
+ \addtolength{\datagidxdescwidth}{-\datagidxnamewidth}%
+ }%
+ \renewcommand*{\datagidxend}{\egroup}%
+ \renewcommand*{\datagidxgroupsep}{\ifdatagidxshowgroups\indexspace\fi}%
+ \renewcommand{\datagidxgroupheader}{%
+ \ifdatagidxshowgroups
+ \item
+ \makebox[\linewidth]%
+ {%
+ \textbf{\DTLgidxGroupHeaderTitle{\datagidxcurrentgroup}}%
+ }%
+ \DTLpar\nobreak\@afterheading
+ \fi
+ }%
+ \renewcommand*{\datagidxitem}{%
+% \end{macrocode}
+% Is this the start of a new group?
+% \begin{macrocode}
+ \ifdefempty\datagidxprevgroup
+ {%
+% \end{macrocode}
+% First item of the list.
+% \begin{macrocode}
+ \datagidxgroupheader
+ }%
+ {%
+% \end{macrocode}
+% Not the first item of the list. Is this item's group the same as
+% the last item's group?
+% \begin{macrocode}
+ \ifdefequal\datagidxcurrentgroup\datagidxprevgroup
+ {%
+% \end{macrocode}
+% Same, so do nothing.
+% \begin{macrocode}
+ }%
+ {%
+% \end{macrocode}
+% Different, so do the separator and the header.
+% \begin{macrocode}
+ \datagidxgroupsep
+ \datagidxgroupheader
+ }%
+ }%
+ \hangindent0pt\relax
+ \parindent0pt\relax
+ \makebox[\datagidxnamewidth][l]%
+ {%
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ \DTLgidxPostName
+ }%
+ }%
+ \begin{minipage}[t]{\datagidxdescwidth}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \@tempswatrue
+ \ifdefempty{\Description}%
+ {%
+ \ifdefempty{\Symbol}%
+ {%
+ \ifdefempty{\Location}{\@tempswafalse}{}%
+ }%
+ {}%
+ }%
+ {}%
+ \if@tempswa
+ \DTLgidxSymbolDescription
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxSeeAlso
+ \else
+ \mbox{}%
+ \fi
+ \DTLgidxChildrenSeeAlso
+ \end{minipage}%
+ \par
+ }%
+ \renewcommand*{\datagidxchildstart}%
+ {%
+ \bgroup
+ \def\datagidx@childsep{}%
+ \setcounter{DTLgidxChildCount}{0}%
+ }%
+ \renewcommand{\datagidxchildend}{\DTLgidxPostChild\egroup}%
+ \renewcommand*{\datagidxchilditem}{%
+ \datagidx@childsep
+ \refstepcounter{DTLgidxChildCount}%
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxChildStyle
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ \DTLgidxPostChildName
+ }%
+ }%
+ \DTLgidxSymbolDescription
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ \let\datagidx@childsep\DTLgidxChildSep
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxChildSep}
+% Separator between child entries for gloss style.
+% \begin{macrocode}
+\newcommand*{\DTLgidxChildSep}{ }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxPostChild}
+%What to put at the end of child entries for gloss style.
+% \begin{macrocode}
+\newcommand*{\DTLgidxPostChild}{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxDictHead}
+% Group header for dict style.
+% \begin{macrocode}
+\ifdef\chapter
+{%
+ \newcommand\DTLgidxDictHead{%
+ \chapter{\DTLgidxGroupHeaderTitle{\datagidxcurrentgroup}}%
+ }%
+}%
+{%
+ \newcommand\DTLgidxDictHead{%
+ \section{\DTLgidxGroupHeaderTitle{\datagidxcurrentgroup}}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxCategoryNameFont}
+% Font used for `category' entries with `dict' style.
+% \begin{macrocode}
+\newcommand*{\DTLgidxCategoryNameFont}[1]{#1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxCategorySep}
+% Separator used with `dict' style.
+% \begin{macrocode}
+\newcommand*{\DTLgidxCategorySep}{\space}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSubCategorySep}
+% Separator used with `dict' style.
+% \begin{macrocode}
+\newcommand*{\DTLgidxSubCategorySep}{\space}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxdictindent}
+% Indent used by `dict' style.
+% \begin{macrocode}
+\newcommand*{\datagidxdictindent}{1em}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxDictPostItem}
+% What to do at the end of each item in the `dict' style.
+% \begin{macrocode}
+\newcommand{\DTLgidxDictPostItem}{\par}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@style@dict}
+% Dictionary style. This assumes 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" key is
+% ignored in this style. The symbol is ignored. The location and
+% symbols widths are also ignored.
+% \begin{macrocode}
+\newcommand*{\datagidx@style@dict}{%
+ \renewcommand*{\datagidxstart}%
+ {%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \dimen@=\linewidth
+ \advance\dimen@ by -\datagidxdictindent\relax
+ \dtl@tmplength=\datagidxdictindent\relax
+ \xdef\datagidxdictparshape{%
+ \noexpand\parshape=2 0pt \the\linewidth\space
+ \the\dtl@tmplength\space \the\dimen@\relax
+ }%
+ \datagidx@level=1\relax
+% \end{macrocode}
+% Index columns are usually too narrow for fully justified text.
+% \begin{macrocode}
+ \raggedright
+ }%
+ \renewcommand*{\datagidxend}{\egroup}%
+ \renewcommand*{\datagidxgroupsep}{}%
+ \renewcommand{\datagidxgroupheader}{%
+ \ifdatagidxshowgroups
+ \datagidxend
+ \datagidx@postend
+ \DTLgidxDictHead
+ \datagidx@prestart
+ \datagidxstart
+ \fi
+ }%
+ \renewcommand*{\datagidxitem}{%
+% \end{macrocode}
+% Is this the start of a new group?
+% \begin{macrocode}
+ \ifdefempty\datagidxprevgroup
+ {%
+% \end{macrocode}
+% First item of the list.
+% \begin{macrocode}
+ \datagidxgroupheader
+ }%
+ {%
+% \end{macrocode}
+% Not the first item of the list. Is this item's group the same as
+% the last item's group?
+% \begin{macrocode}
+ \ifdefequal\datagidxcurrentgroup\datagidxprevgroup
+ {%
+% \end{macrocode}
+% Same, so do nothing.
+% \begin{macrocode}
+ }%
+ {%
+% \end{macrocode}
+% Different, so do the separator and the header.
+% \begin{macrocode}
+ \datagidxgroupsep
+ \datagidxgroupheader
+ }%
+ }%
+% \end{macrocode}
+% Now get on with this item.
+% \begin{macrocode}
+ \datagidxdictparshape
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxNameFont{\DTLgidxNameCase{\Name}}%
+ }%
+ \DTLgidxPostName
+% \end{macrocode}
+% Initialise category separator to do nothing.
+% \begin{macrocode}
+ \let\datagidx@catsep\@empty
+ \let\datagidx@subcatsep\@empty
+ \DTLgidxSymbolDescription
+% \end{macrocode}
+% No location list.
+% \begin{macrocode}
+ \DTLgidxChildrenSeeAlso
+ \DTLgidxDictPostItem
+ }%
+ \renewcommand*{\datagidxchildstart}%
+ {%
+ \bgroup
+ }%
+ \renewcommand*{\datagidxchildend}{\egroup}%
+ \renewcommand*{\datagidxchilditem}{%
+% \end{macrocode}
+% Which level are we on?
+% \begin{macrocode}
+ \ifnum\datagidx@level=2\relax
+% \end{macrocode}
+% Category entry
+% \begin{macrocode}
+ \datagidx@catsep
+ \let\datagidx@catsep\DTLgidxCategorySep
+ \let\datagidx@subcapsep\@empty
+ \datagidxtarget{\Label}%
+ {%
+ \DTLgidxChildStyle
+ {%
+ \DTLgidxCategoryNameFont{\DTLgidxNameCase{\Name}}%
+ \DTLgidxPostChildName
+ }%
+ }%
+ \setcounter{DTLgidxChildCount}{0}%
+ \else
+% \end{macrocode}
+% Sub Category entry
+% \begin{macrocode}
+ \datagidx@subcatsep
+ \let\datagidx@subcatsep\DTLgidxSubCategorySep
+ \refstepcounter{DTLgidxChildCount}%
+ \DTLgidxChildCountLabel
+ \DTLgidxPostChildName
+ \fi
+ \DTLgidxSymbolDescription
+ \DTLgidxDoSeeOrLocation
+ \DTLgidxChildrenSeeAlso
+ }%
+ \renewcommand*{\datagidxseealsostart}%
+ {%
+ \bgroup
+ \setlength{\parindent}{0pt}%
+ \setlength{\parskip}{0pt plus 0.3pt}%
+ \setlength{\dimen@}{\datagidxindent}%
+ \advance\datagidx@level by 1\relax
+ \multiply\dimen@ by \datagidx@level\relax
+ \@idxitem\hspace*{\dimen@}%
+ }%
+ \renewcommand{\datagidxseealsoend}{\egroup}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\subsection{Location Lists}
+%\begin{macro}{\dtldofirstlocation}
+% Only display the first location in the list.
+% \begin{macrocode}
+\newcommand*{\dtldofirstlocation}{%
+ \@for\dtl@thisloc:=\Location\do{%
+ \ifdefempty\dtl@thisloc
+ {}%
+ {%
+ \expandafter\datagidx@getlocation\dtl@thisloc
+ \datagidxlink{\datagidx@current@target}%
+ {%
+ \datagidx@formatlocation
+ \datagidx@current@format\datagidx@current@locationstring
+ }%
+% \end{macrocode}
+% Only interested in the first item, so break out of loop.
+% \begin{macrocode}
+ \@endfortrue
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@formatlocation}
+% \begin{macrocode}
+\newcommand*{\datagidx@formatlocation}[2]{%
+ \ifdefempty{#1}%
+ {#2}%
+ {%
+ \ifcsdef{#1}%
+ {%
+ \csuse{#1}{#2}%
+ }%
+ {%
+ \PackageWarning{datagidx}{Unknown format `#1'}%
+ #2%
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\dtldolocationlist}
+% Display the location list.
+% \begin{macrocode}
+\newcommand*{\dtldolocationlist}{%
+ \DTLifnull{\Location}%
+ {}%
+ {%
+ \def\datagidx@prev@location{-1}%
+ \def\datagidx@prev@locationstring{}%
+ \def\datagidx@prev@format{}%
+ \def\datagidx@prev@locationformat{}%
+ \def\datagidx@prev@prefix{}%
+ \def\datagidx@prev@target{}%
+ \def\datagidx@location@sep{}%
+ \def\datagidx@location@start{-1}%
+ \expandafter\forcsvlist\expandafter\datagidx@parse@location
+ \expandafter{\Location}%
+ \do@prevlocation % tidy up loose ends
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\if@dtl@sequential}
+% Conditional to keep track of sequences.
+% \begin{macrocode}
+\newif\if@dtl@sequential
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidx@getlocdo}
+% Handler for \cs{datagidx@docomplist}
+% \begin{macrocode}
+\newcommand*\datagidx@getlocdo[1]{%
+ \ifdefempty\datagidx@current@location
+ {}%
+ {%
+ \eappto\datagidx@current@prefix{%
+ \datagidx@current@location\datagidx@compositor
+ }%
+ }%
+ \def\datagidx@current@location{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@getlocation}
+% Get the location and store in \cs{current@location}:
+% \begin{macrocode}
+\def\datagidx@getlocation[#1]#2#3{%
+% \end{macrocode}
+% Store the original value.
+% \begin{macrocode}
+ \def\datagidx@current@locationstring{#2}%
+% \end{macrocode}
+% \begin{macrocode}
+ \bgroup
+ \datagidx@escapelocationformat
+ \xdef\datagidx@current@locationformat{#2}%
+ \datagidx@clearlocationformat
+ \xdef\datagidx@current@location{#2}%
+ \egroup
+% \end{macrocode}
+% If the location contains a compositor, we need to get the final
+% element and store the rest as a prefix:
+% \begin{macrocode}
+ \let\datagidx@list\datagidx@current@location
+ \def\datagidx@current@prefix{}%
+ \def\datagidx@current@location{}%
+ \let\do\datagidx@getlocdo
+ \expandafter\datagidx@docomplist
+ \expandafter{\datagidx@list}%
+% \end{macrocode}
+% Store the format:
+% \begin{macrocode}
+ \def\datagidx@current@format{#1}%
+% \end{macrocode}
+% Store the target:
+% \begin{macrocode}
+ \def\datagidx@current@target{#3}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@parse@location}
+% Parses the location list (given in the argument).
+% \begin{macrocode}
+\newcommand*{\datagidx@parse@location}[1]{%
+% \end{macrocode}
+% Parse location format.
+% \begin{macrocode}
+ \datagidx@getlocation#1\relax
+% \end{macrocode}
+% If this is the same as the previous location, do nothing.
+% \begin{macrocode}
+ \ifdefequal{\datagidx@prev@locationstring}{\datagidx@current@locationstring}%
+ {%
+% \end{macrocode}
+% If the format is different, let the non-empty format over-ride
+% the empty format.
+% \begin{macrocode}
+ \ifstrequal{\datagidx@prev@format}{\datagidx@current@format}
+ {%
+ }%
+ {%
+ \ifdefempty{\datagidx@current@format}
+ {%
+% \end{macrocode}
+% Current format is empty, so keep previous unchanged.
+% \begin{macrocode}
+ }%
+ {%
+ \ifdefempty{\datagidx@prev@format}
+ {%
+% \end{macrocode}
+% Previous format is empty, so update.
+% \begin{macrocode}
+ \let\datagidx@prev@format\datagidx@current@format
+ }%
+ {%
+ \PackageWarning{datagidx}%
+ {%
+ Conflicting location formats `\datagidx@prev@format' and
+ `\datagidx@current@format' for location `\datagidx@current@location'%
+ }%
+ }%
+ }%
+ }%
+ }%
+ {%
+ \@datagidx@parse@location
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@datagidx@parse@location}
+% \begin{macrocode}
+\newcommand*{\@datagidx@parse@location}{%
+% \end{macrocode}
+% Check if we have a sequence.
+% \begin{macrocode}
+ \@dtl@sequentialtrue
+% \end{macrocode}
+% A change in font format breaks the sequence.
+% \begin{macrocode}
+ \ifdefequal{\datagidx@prev@format}{\datagidx@current@format}
+ {%
+% \end{macrocode}
+% A change in location format breaks the sequence.
+% \begin{macrocode}
+ \ifdefequal{\datagidx@prev@locationformat}{\datagidx@current@locationformat}
+ {%
+% \end{macrocode}
+% A change in prefix breaks the sequence.
+% \begin{macrocode}
+ \ifdefequal{\datagidx@prev@prefix}{\datagidx@current@prefix}
+ {%
+ }%
+ {%
+% \end{macrocode}
+% Prefixes are different, so not a sequence.
+% \begin{macrocode}
+ \@dtl@sequentialfalse
+ }%
+ }%
+ {%
+% \end{macrocode}
+% Formats are different, so not a sequence.
+% \begin{macrocode}
+ \@dtl@sequentialfalse
+ }%
+ }%
+ {%
+% \end{macrocode}
+% Formats are different, so not a sequence.
+% \begin{macrocode}
+ \@dtl@sequentialfalse
+ }%
+ \if@dtl@sequential
+% \end{macrocode}
+% Is this location one more than the previous location?
+% \begin{macrocode}
+ \ifnumequal{\datagidx@prev@location+1}{\datagidx@current@location}%
+ {%
+% \end{macrocode}
+% It is one more than previous value.
+% Is this location the same type as the previous location?
+% \begin{macrocode}
+ \ifdefequal
+ \datagidx@current@locationformat
+ \datagidx@prev@locationformat
+ {%
+% \end{macrocode}
+% They are the same, so we have a sequence.
+% \begin{macrocode}
+ \@dtl@sequentialtrue
+ }%
+ {%
+% \end{macrocode}
+% They aren't the same, so we don't have a sequence.
+% \begin{macrocode}
+ \@dtl@sequentialfalse
+ }%
+ }%
+ {%
+ \@dtl@sequentialfalse
+ }%
+ \fi
+% \end{macrocode}
+% Has the sequence flag been set?
+% \begin{macrocode}
+ \if@dtl@sequential
+% \end{macrocode}
+% Yes, we have a sequence.
+% Has the start of the sequence been set?
+% \begin{macrocode}
+ \ifnumequal{\datagidx@location@start}{-1}%
+ {%
+% \end{macrocode}
+% No it hasn't, so set it
+% \begin{macrocode}
+ \let\datagidx@location@start\datagidx@prev@location
+ \let\datagidx@location@startval\datagidx@prev@locationstring
+ \let\datagidx@location@format\datagidx@prev@format
+ \let\datagidx@location@target\datagidx@prev@target
+ }%
+ {%
+ }%
+ \else
+% \end{macrocode}
+% We don't have a sequence, so do the previous location.
+% \begin{macrocode}
+ \do@prevlocation
+ \fi
+% \end{macrocode}
+% Update previous location macros to this location.
+% \begin{macrocode}
+ \let\datagidx@prev@location\datagidx@current@location
+ \let\datagidx@prev@format\datagidx@current@format
+ \let\datagidx@prev@prefix\datagidx@current@prefix
+ \let\datagidx@prev@locationformat\datagidx@current@locationformat
+ \let\datagidx@prev@locationstring\datagidx@current@locationstring
+ \let\datagidx@prev@target\datagidx@current@target
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxLocationSep}
+% Separator between locations.
+% \begin{macrocode}
+\newcommand*{\DTLgidxLocationSep}{, }
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\DTLgidxLocationF}
+% How to format a location list consisting of only two locations.
+% \begin{macrocode}
+\newcommand*{\DTLgidxLocationF}[2]{%
+ #1\DTLgidxLocationSep#2%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\DTLgidxLocationFF}
+% How to format a location list consisting of three or more locations.
+% \begin{macrocode}
+\newcommand*{\DTLgidxLocationFF}[2]{%
+ #1--#2%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\do@prevlocation}
+% Do the previous location in the current list.
+% \begin{macrocode}
+\newcommand*{\do@prevlocation}{%
+% \end{macrocode}
+% Have we come to the end of a sequence?
+% \begin{macrocode}
+ \ifnumequal{\datagidx@location@start}{-1}%
+ {%
+% \end{macrocode}
+% Not the end of a sequence.
+% \begin{macrocode}
+ \ifdefempty{\datagidx@prev@locationstring}%
+ {}%
+ {%
+ \datagidx@location@sep
+ \datagidxlink{\datagidx@prev@target}%
+ {%
+ \datagidx@formatlocation
+ \datagidx@prev@format\datagidx@prev@locationstring
+ }%
+ \def\datagidx@location@sep{\DTLgidxLocationSep}%
+ }%
+ }%
+ {%
+% \end{macrocode}
+% At the end of a sequence.
+% \begin{macrocode}
+ \datagidx@location@sep
+ \do@locrange
+ \def\datagidx@location@sep{\DTLgidxLocationSep}%
+ \def\datagidx@location@start{-1}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\do@locrange}
+% Format the location range.
+% \begin{macrocode}
+\newcommand*{\do@locrange}{%
+% \end{macrocode}
+% Are the start and end locations 2 or more apart?
+% \begin{macrocode}
+ \ifnumgreater{\datagidx@prev@location}{\datagidx@location@start+1}%
+ {%
+% \end{macrocode}
+% Yes, they are, so form a range:
+% \begin{macrocode}
+ \DTLgidxLocationFF
+ {%
+ \datagidxlink{\datagidx@location@target}%
+ {%
+ \datagidx@formatlocation
+ \datagidx@location@format\datagidx@location@startval
+ }%
+ }%
+ {%
+ \datagidxlink{\datagidx@prev@target}%
+ {%
+ \datagidx@formatlocation
+ \datagidx@prev@format\datagidx@prev@locationstring
+ }%
+ }%
+ }%
+ {%
+% \end{macrocode}
+% No, they aren't so don't form a range:
+% \begin{macrocode}
+ \DTLgidxLocationF
+ {
+ \datagidxlink{\datagidx@location@target}%
+ {%
+ \datagidx@formatlocation
+ \datagidx@location@format\datagidx@location@startval
+ }%
+ }%
+ {%
+ \datagidxlink{\datagidx@prev@target}%
+ {%
+ \datagidx@formatlocation
+ \datagidx@prev@format\datagidx@prev@locationstring
+ }%
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\section{Defining New Glossary/Index Databases}
+%
+%\begin{macro}{\datagidx@defaultdatabase}
+% The default database to which terms should be added.
+% \begin{macrocode}
+\newcommand*{\datagidx@defaultdatabase}{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSetDefaultDB}
+% Allow user to set the default database
+% \begin{macrocode}
+\newcommand*{\DTLgidxSetDefaultDB}[1]{%
+ \renewcommand*{\datagidx@defaultdatabase}{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%Define keys for \cs{newgidx}:
+% \begin{macrocode}
+\define@key{newgloss}{heading}{\renewcommand*{\datagidx@heading}{#1}}
+\define@key{newgloss}{postheading}{%
+ \renewcommand*{\datagidx@postheading}{#1}%
+}
+\define@choicekey{newgloss}{balance}[\val\nr]{true,false}[true]{%
+ \ifcase\nr\relax
+ \renewcommand*{\datagidx@multicols}{multicols}%
+ \or
+ \renewcommand*{\datagidx@multicols}{multicols*}%
+ \fi
+}
+\define@key{newgloss}{sort}{\renewcommand*{\datagidx@sort}{#1}}
+% \end{macrocode}
+% Default style is `index':
+% \begin{macrocode}
+\newcommand*{\datagidx@style}{index}
+\define@key{newgloss}{style}{\renewcommand*{\datagidx@style}{#1}}
+% \end{macrocode}
+% Define conditional to determine whether or not to show group
+% headers and do sep. (Default is false.)
+%\begin{macro}{\ifdatagidxshowgroups}
+% \begin{macrocode}
+\newif\ifdatagidxshowgroups
+\newcommand*{\datagidx@showgroups}{false}
+% \end{macrocode}
+%\end{macro}
+% \begin{macrocode}
+\define@choicekey{newgloss}{showgroups}{true,false}[true]%
+{%
+ \renewcommand{\datagidx@showgroups}{#1}%
+}%
+% \end{macrocode}
+%
+%\begin{macro}{\newgidx}
+%\begin{definition}
+% \cs{newgloss}\oarg{options}\marg{database name}\marg{title}
+%\end{definition}
+% Define \cs{newgidx} if it hasn't already been defined by the
+% `highopt' optimize setting.
+% \begin{macrocode}
+\ifundef\newgidx
+{%
+ \newcommand*{\newgidx}{\datagidx@newgidx}
+}%
+{}
+% \end{macrocode}
+% May only be used in the preamble (otherwise the entries will be
+% undefined when their locations are read from the aux file).
+% \begin{macrocode}
+\@onlypreamble\newgidx
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@highopt@newgidx}
+% The behaviour of \cs{newgidx} when the `highopt' optimize option has
+% been set.
+% \begin{macrocode}
+\newcommand*{\datagidx@highopt@newgidx}[3][]{%
+% \end{macrocode}
+% Get the file name:
+% \begin{macrocode}
+ \edef\datagidx@indexfilename{\datagidxhighoptfilename{#2}}%
+% \end{macrocode}
+% Has the file been created?
+% \begin{macrocode}
+ \IfFileExists{\datagidx@indexfilename}%
+ {%
+% \end{macrocode}
+% File does exists. Load it.
+% \begin{macrocode}
+ \input{\datagidx@indexfilename}%
+% \end{macrocode}
+% Update the `datagidx' database.
+% \begin{macrocode}
+ \bgroup
+ \setkeys{newgloss}{#1}%
+ \datagidx@newgidx@update{#2}{#3}%
+ \egroup
+ }%
+ {%
+% \end{macrocode}
+% File doesn't exist. Behave as normal.
+% \begin{macrocode}
+ \datagidx@newgidx[#1]{#2}{#3}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@newgidx}
+% The normal behaviour of \cs{newgidx}
+% \begin{macrocode}
+\newcommand*{\datagidx@newgidx}[3][]{%
+\bgroup
+ \setkeys{newgloss}{#1}%
+% \end{macrocode}
+% If no default database has been identified, set the default to
+% this database.
+% \begin{macrocode}
+ \ifdefempty{\datagidx@defaultdatabase}%
+ {\xdef\datagidx@defaultdatabase{#2}}%
+ {}%
+ \DTLgnewdb{#2}%
+ \DTLaddcolumn{#2}{Label}%
+ \DTLaddcolumn{#2}{Location}%
+ \DTLaddcolumn{#2}{CurrentLocation}%
+ \DTLaddcolumn{#2}{FirstId}%
+ \DTLaddcolumn{#2}{Name}%
+ \DTLaddcolumn{#2}{Text}%
+ \DTLaddcolumn{#2}{Parent}%
+ \DTLaddcolumn{#2}{Child}%
+ \DTLaddcolumn{#2}{Description}%
+ \DTLaddcolumn{#2}{Used}%
+ \DTLaddcolumn{#2}{Symbol}%
+ \DTLaddcolumn{#2}{Long}%
+ \DTLaddcolumn{#2}{Short}%
+ \DTLaddcolumn{#2}{See}%
+ \DTLaddcolumn{#2}{SeeAlso}%
+ \datagidx@newgidx@update{#2}{#3}%
+\egroup
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@newgidx@update}
+% Update the `datagidx' database.
+% \begin{macrocode}
+\newcommand*{\datagidx@newgidx@update}[2]{%
+ \DTLnewrow{datagidx}%
+ \DTLnewdbentry{datagidx}{Glossary}{#1}%
+ \DTLnewdbentry{datagidx}{Title}{#2}%
+ {%
+ \dtlexpandnewvalue
+ \DTLnewdbentry{datagidx}{Heading}{\expandonce\datagidx@heading}%
+ \DTLnewdbentry{datagidx}{PostHeading}{\expandonce\datagidx@postheading}%
+ \DTLnewdbentry{datagidx}{MultiCols}{\expandonce\datagidx@multicols}%
+ \DTLnewdbentry{datagidx}{Sort}{\expandonce\datagidx@sort}%
+ \DTLnewdbentry{datagidx}{Style}{\expandonce\datagidx@style}%
+ \DTLnewdbentry{datagidx}{ShowGroups}{\expandonce\datagidx@showgroups}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\section{Defining New Terms}
+%
+%\subsection{Options}
+% Define some keys for \cs{newterm}:
+%\begin{macro}{\newterm@label}
+% \begin{macrocode}
+\newcommand*{\newterm@label}{}
+\define@key{newterm}{label}{\renewcommand*{\newterm@label}{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@parent}
+% \begin{macrocode}
+\newcommand*{\newterm@parent}{}
+\define@key{newterm}{parent}{\renewcommand*{\newterm@parent}{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@text}
+% \begin{macrocode}
+\newcommand*{\newterm@text}{}
+\define@key{newterm}{text}{\renewcommand*{\newterm@text}{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@description}
+% \begin{macrocode}
+\newcommand*{\newterm@description}{}
+\define@key{newterm}{description}{%
+ \renewcommand*{\newterm@description}{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@plural}
+% \begin{macrocode}
+\define@key{newterm}{plural}{\def\newterm@plural{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@sort}
+% \begin{macrocode}
+\newcommand*{\newterm@sort}{}
+\define@key{newterm}{sort}{\renewcommand*{\newterm@sort}{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@symbol}
+% \begin{macrocode}
+\newcommand*{\newterm@symbol}{}
+\define@key{newterm}{symbol}{\renewcommand*{\newterm@symbol}{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@database}
+% \begin{macrocode}
+\newcommand*{\newterm@database}{}
+\define@key{newterm}{database}{\renewcommand*{\newterm@database}{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@long}
+% \begin{macrocode}
+\newcommand*{\newterm@long}{}
+\define@key{newterm}{long}{%
+ \renewcommand*{\newterm@long}{#1}%
+ \def\newterm@longplural{#1s}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@short}
+% \begin{macrocode}
+\newcommand*{\newterm@short}{}
+\define@key{newterm}{short}{%
+ \renewcommand*{\newterm@short}{#1}%
+ \def\newterm@shortplural{#1s}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@longplural}
+% \begin{macrocode}
+\define@key{newterm}{longplural}{%
+ \def\newterm@longplural{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\newterm@shortplural}
+% \begin{macrocode}
+\define@key{newterm}{shortplural}{%
+ \def\newterm@shortplural{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\newterm@see}
+% ``see'' should not be used with a location list. If you have a
+% location list and want a cross-reference use ``see also'' instead.
+% \begin{macrocode}
+\newcommand*{\newterm@see}{}
+\define@key{newterm}{see}{%
+ \renewcommand*{\newterm@see}{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\newterm@seealso}
+% ``see also'' should be used with a location list (or with child
+% entries with location lists). If an entry has no location list and
+% not child entries use ``see'' instead.
+% \begin{macrocode}
+\newcommand*{\newterm@seealso}{}
+\define@key{newterm}{seealso}{%
+ \renewcommand*{\newterm@seealso}{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\subsection{New Terms}
+%
+%\begin{macro}{\newterm@defaultshook}
+% \begin{macrocode}
+\newcommand*{\newterm@defaultshook}{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\newterm@extrafields}
+% \begin{macrocode}
+\newcommand*{\newterm@extrafields}{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxAssignList}
+% Assignment list used by \ics{printterms}
+% \begin{macrocode}
+\newcommand*{\DTLgidxAssignList}{%
+ \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,\Sort=Sort%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxtermkeys}
+% Keys defined for \cs{newterm} corresponding to fields (``name'' is
+% added for convenience).
+% \begin{macrocode}
+\newcommand*{\datagidxtermkeys}{%
+ name,description,symbol,long,short,see,seealso,text,plural,%
+ label,parent,sort%
+}
+% \end{macrocode}
+%\end{macro}
+% Access keys corresponding to given fields
+% \begin{macrocode}
+\newcommand*\@datagidx@fieldkey@Name{name}%
+\newcommand*\@datagidx@fieldkey@Description{description}%
+\newcommand*\@datagidx@fieldkey@Symbol{symbol}%
+\newcommand*\@datagidx@fieldkey@Long{long}%
+\newcommand*\@datagidx@fieldkey@Short{short}%
+\newcommand*\@datagidx@fieldkey@See{see}%
+\newcommand*\@datagidx@fieldkey@SeeAlso{seealso}%
+\newcommand*\@datagidx@fieldkey@Text{text}%
+\newcommand*\@datagidx@fieldkey@Plural{plural}%
+\newcommand*\@datagidx@fieldkey@Label{label}%
+\newcommand*\@datagidx@fieldkey@Parent{parent}%
+\newcommand*\@datagidx@fieldkey@Sort{sort}%
+% \end{macrocode}
+%
+%\begin{macro}{\newtermaddfield}
+%\begin{definition}
+%\cs{newtermaddfield}\oarg{db list}\marg{column key}\marg{new term
+%key}\marg{default value}
+%\end{definition}
+% The default value may contain \ics{field}\marg{key} to get the
+% value of another field.
+% \begin{macrocode}
+\newcommand*{\newtermaddfield}[4][]{%
+% \end{macrocode}
+% If optional argument not specified, iterate over all defined
+% glossaries/indices
+% \begin{macrocode}
+ \ifstrempty{#1}%
+ {%
+ \dtlforcolumn{\datagidx@thisidx}{datagidx}{Glossary}%
+ {%
+ \DTLaddcolumn{\datagidx@thisidx}{#2}%
+ }%
+ }%
+ {%
+ \@for\datagidx@thisidx:=#1\do
+ {%
+ \DTLaddcolumn{\datagidx@thisidx}{#2}%
+ }%
+ }%
+ \expandafter\gdef\csname newterm@#3\endcsname{}%
+ \define@key{newterm}{#3}%
+ {%
+ \expandafter\def\csname newterm@#3\endcsname{##1}%
+ }%
+ \gappto\newterm@defaultshook
+ {%
+ \expandafter\protected@edef\csname newterm@#3\endcsname{#4}%
+ }%
+ \gappto\newterm@extrafields
+ {%
+ \protected@edef\datagidx@value{\csname newterm@#3\endcsname}%
+ \DTLnewdbentry{\newterm@database}{#2}{\expandonce\datagidx@value}%
+ }%
+ \xappto\DTLgidxAssignList
+ {%
+ ,\expandafter\noexpand\csname#2\endcsname=#2%
+ }%
+ \xappto\datagidxtermkeys{,#3}%
+ \expandafter\xdef\csname @datagidx@fieldkey@#2\endcsname{#3}%
+ \xappto\datagidxgetchildfields
+ {%
+ \noexpand\dtlgetentryfromcurrentrow
+ {\expandafter\noexpand\csname#2\endcsname}%
+ {\noexpand\dtlcolumnindex{\noexpand\DTLgidxCurrentdb}{#2}}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\newtermlabelhook}
+% \begin{macrocode}
+\newcommand*{\newtermlabelhook}{}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\DTLgidxNoFormat}
+% \begin{macrocode}
+\newcommand*{\DTLgidxNoFormat}[1]{#1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxGobble}
+% \begin{macrocode}
+\newcommand*{\DTLgidxGobble}[1]{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxStripBackslash}
+% Argument must be a control sequence. This is stringified and the
+% first character (The backslash) is removed).
+% \begin{macrocode}
+\newcommand*{\DTLgidxStripBackslash}[1]{%
+ \expandafter\@gobble\string#1%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxName}
+%\begin{definition}
+%\cs{DTLgidxName}\marg{forenames}\marg{surname}
+%\end{definition}
+% How to format a person's name in the text.
+% \begin{macrocode}
+\newcommand*{\DTLgidxName}[2]{%
+ #1\space #2%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxNameNum}
+%\begin{definition}
+%\cs{DTLgidxNameNum}\marg{n}
+%\end{definition}
+% The argument \meta{n} should be a number applied to a name
+% (e.g.\ \verb*"James "\cs{DTLgidxNameNum}{1}). This is converted to
+% a two-digit number for sorting but a Roman numeral for the label
+% and in the text.
+% \begin{macrocode}
+\newcommand*{\DTLgidxNameNum}[1]{\@Roman{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidx@namenum}
+% Conversion for sort key.
+% \begin{macrocode}
+\newcommand*{\datagidx@namenum}[1]{\two@digits{#1}}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxPlace}
+%\begin{definition}
+%\cs{DTLgidxPlace}\marg{country}\marg{town/city}
+%\end{definition}
+% How to format a place in the text.
+% \begin{macrocode}
+\newcommand*{\DTLgidxPlace}[2]{%
+ #2%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSubject}
+%\begin{definition}
+%\cs{DTLgidxSubject}\marg{main}\marg{category}
+%\end{definition}
+% How to format a subject in the text. Ignore the main part in the
+% text.
+% \begin{macrocode}
+\newcommand*{\DTLgidxSubject}[2]{%
+ #2%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxOffice}
+%\begin{definition}
+%\cs{DTLgidxOffice}\marg{office}\marg{name}
+%\end{definition}
+% Put the office in parentheses in the document text.
+% \begin{macrocode}
+\newcommand*{\DTLgidxOffice}[2]{%
+ #2 (#1)%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxIgnore}
+% Show argument in document text, but disregard in the sort and
+% label.
+% \begin{macrocode}
+\newcommand*{\DTLgidxIgnore}[1]{#1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxMac}
+%\begin{definition}
+%\cs{DTLgidxMac}\marg{text}
+%\end{definition}
+% In the document, just does \meta{text}, but gets converted to
+% ``Mac'' in the sort key. (Unless overridden by the user.)
+% \begin{macrocode}
+\newcommand*{\DTLgidxMac}[1]{#1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@mac}
+%\cs{DTLgidxMac} gets temporarily redefined to \cs{datagidx@mac}
+%when construction the sort key.
+% \begin{macrocode}
+\newcommand*{\datagidx@mac}[1]{Mac}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxSaint}
+%\begin{definition}
+%\cs{DTLgidxSaint}\marg{text}
+%\end{definition}
+% In the document, just does \meta{text}, but gets converted to
+% ``Saint'' in the sort key. (Unless overridden by the user.)
+% \begin{macrocode}
+\newcommand*{\DTLgidxSaint}[1]{#1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@saint}
+%\cs{DTLgidxMac} gets temporarily redefined to \cs{datagidx@saint}
+%when construction the sort key.
+% \begin{macrocode}
+\newcommand*{\datagidx@saint}[1]{Saint}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxRank}
+%\begin{definition}
+%\cs{DTLgidxRank}\marg{rank}\marg{forenames}
+%\end{definition}
+% A person's title, rank or sanctity should be ignored when sorting.
+% \begin{macrocode}
+\newcommand*{\DTLgidxRank}[2]{#1~#2}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@rank}
+%\cs{DTLidxRank} gets temporarily redefined to \cs{datagidx@rank}
+%when constructing the sort key. An extra dot is added to the end to
+%ensure names without a rank are sorted before identical names with
+%a rank.
+% \begin{macrocode}
+\newcommand*{\datagidx@rank}[2]{#2.}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxParticle}
+%\begin{definition}
+%\cs{DTLgidxParticle}\marg{particle}\marg{surname}
+%\end{definition}
+% A particle such as ``of'', ``de'' or ``von'' should be ignored when sorting.
+% \begin{macrocode}
+\newcommand*{\DTLgidxParticle}[2]{#1~#2}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@particle}
+%\cs{DTLidxParticle} gets temporarily redefined to \cs{datagidx@particle}
+%when constructing the sort key. An extra dot is added to the end to
+%ensure names without a particle are sorted before identical names with
+%a particle.
+% \begin{macrocode}
+\newcommand*{\datagidx@particle}[2]{#2.}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@bothoftwo}
+% \begin{macrocode}
+\newcommand*{\datagidx@bothoftwo}[2]{#1#2}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@person}
+% Used when constructing the sort key for a name.
+% \begin{macrocode}
+\newcommand*{\datagidx@person}[2]{#2\noexpand\datatoolpersoncomma #1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@place}
+% Used when constructing the sort key for a place.
+% \begin{macrocode}
+\newcommand*{\datagidx@place}[2]{#2\noexpand\datatoolplacecomma #1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@subject}
+% Used when constructing the sort key for a place.
+% \begin{macrocode}
+\newcommand*{\datagidx@subject}[2]{#2\noexpand\datatoolsubjectcomma #1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@paren}
+% Used when constructing the sort key for a parenthesis.
+% \begin{macrocode}
+\newcommand*{\datagidx@paren}[1]{\noexpand\datatoolparenstart #1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@invert}
+% \begin{macrocode}
+\newcommand*{\datagidx@invert}[2]{#2, #1}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxParen}
+% Parenthetical material.
+% \begin{macrocode}
+\newcommand*{\DTLgidxParen}[1]{\space(#1)}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxwordifygreek}
+% Convert commands like \ics{alpha} into words for indexing and
+% labelling purposes.
+% \begin{macrocode}
+\newcommand*{\datagidxwordifygreek}{%
+ \def\alpha{alpha}%
+ \def\beta{beta}%
+ \def\gamma{gamma}%
+ \def\delta{delta}%
+ \def\epsilon{epsilon}%
+ \def\varepsilon{epsilon}%
+ \def\zeta{zeta}%
+ \def\eta{eta}%
+ \def\theta{theta}%
+ \def\vartheta{theta}%
+ \def\iota{iota}%
+ \def\kappa{kappa}%
+ \def\lambda{lambda}%
+ \def\mu{mu}%
+ \def\nu{nu}%
+ \def\xi{xi}%
+ \def\pi{pi}%
+ \def\varpi{pi}%
+ \def\rho{rho}%
+ \def\varrho{rho}%
+ \def\sigma{sigma}%
+ \def\varsigma{sigma}%
+ \def\tau{tau}%
+ \def\upsilon{upsilon}%
+ \def\phi{phi}%
+ \def\varphi{phi}%
+ \def\chi{chi}%
+ \def\psi{psi}%
+ \def\omega{omega}%
+ \def\Gamma{Gamma}%
+ \def\Delta{Delta}%
+ \def\Theta{Theta}%
+ \def\Lambda{Lambda}%
+ \def\Xi{Xi}%
+ \def\Pi{Pi}%
+ \def\Sigma{Sigma}%
+ \def\Upsilon{Upsilon}%
+ \def\Phi{Phi}%
+ \def\Psi{Psi}%
+ \def\Omega{Omega}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidxstripaccents}
+% Strip accents so they don't interfere with the label and sort.
+% If you want to write your own comparison handler macro, you'll
+% need to redefine this if you want accented letters to be sorted
+% differently from the unaccented version.
+% \begin{macrocode}
+\newcommand*{\datagidxstripaccents}{%
+ \expandafter\def\csname \encodingdefault-cmd\endcsname##1##2##3{##3}%
+ \expandafter\def\csname OT1-cmd\endcsname##1##2##3{##3}%
+ \expandafter\def\csname T1-cmd\endcsname##1##2##3{##3}%
+ \expandafter\def\csname PD1-cmd\endcsname##1##2##3{##3}%
+ \def\IeC##1{\@gobbletwo##1}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\newterm}
+%\begin{definition}
+% \cs{newterm}\oarg{options}{name}
+%\end{definition}
+% Defaults to normal behaviour.
+% \begin{macrocode}
+\ifdef\newterm
+{%
+}%
+{%
+ \newcommand{\newterm}{\datagidx@newterm}
+}
+% \end{macrocode}
+%\end{macro}
+%
+%May only be used in the preamble. (Terms must be defined before the
+%aux file is read.)
+% \begin{macrocode}
+\@onlypreamble\newterm
+% \end{macrocode}
+%
+%\begin{macro}{\datagidx@setfieldvalues}
+% Sets the values for all the field.
+% \begin{macrocode}
+\newcommand{\datagidx@setfieldvalues}[2]{%
+% \end{macrocode}
+% Set defaults.
+% \begin{macrocode}
+ \def\newterm@name{#2}%
+ \renewcommand*\newterm@label{#2}%
+ \renewcommand*\newterm@text{#2}%
+ \undef\newterm@plural
+ \renewcommand*{\newterm@description}{}%
+ \renewcommand*{\newterm@sort}{#2}%
+ \renewcommand*{\newterm@symbol}{}%
+ \let\newterm@database\datagidx@defaultdatabase
+ \renewcommand*{\newterm@short}{#2}%
+ \undef\newterm@shortplural
+ \renewcommand*{\newterm@long}{#2}%
+ \undef\newterm@longplural
+ \renewcommand*{\newterm@see}{}%
+ \renewcommand*{\newterm@seealso}{}%
+ \renewcommand*{\newterm@parent}{}%
+% \end{macrocode}
+% Allow hook to access other fields.
+% \begin{macrocode}
+ \let\datagidx@orgfield\field
+ \def\field##1{\expandafter\noexpand\csname newterm@##1\endcsname}%
+% \end{macrocode}
+% Hook to make it easier to add extra fields.
+% \begin{macrocode}
+ \newterm@defaultshook
+ \let\field\datagidx@orgfield
+% \end{macrocode}
+% Assign values given in optional argument.
+% \begin{macrocode}
+ \setkeys{newterm}{#1}%
+% \end{macrocode}
+% Temporary redefine commands likely to be contained in the name
+% that may interfere with the label and sort.
+% \begin{macrocode}
+ \bgroup
+% \end{macrocode}
+% Allow users to, say, specify the name as
+% \meta{name}\ics{glsadd}\marg{other label} without having to specify
+% a separate label.
+% \begin{macrocode}
+ \let\glsadd\@gobble
+% \end{macrocode}
+% Strip common formatting commands.
+% \begin{macrocode}
+ \let\MakeUppercase\DTLgidxNoFormat
+ \let\MakeTextUppercase\DTLgidxNoFormat
+ \let\MakeLowercase\DTLgidxNoFormat
+ \let\MakeTextLowercase\DTLgidxNoFormat
+ \let\acronymfont\DTLgidxNoFormat
+ \let\textrm\DTLgidxNoFormat
+ \let\texttt\DTLgidxNoFormat
+ \let\textsf\DTLgidxNoFormat
+ \let\textsc\DTLgidxNoFormat
+ \let\textbf\DTLgidxNoFormat
+ \let\textmd\DTLgidxNoFormat
+ \let\textit\DTLgidxNoFormat
+ \let\textsl\DTLgidxNoFormat
+ \let\emph\DTLgidxNoFormat
+ \let\textsuperscript\DTLgidxNoFormat
+ \let~\space
+ \ifdef\andname
+ {%
+ \let\&\andname
+ }%
+ {%
+ \def\&{and}%
+ }%
+% \end{macrocode}
+% Strip \cs{ensuremath}.
+% \begin{macrocode}
+ \let\ensuremath\DTLgidxNoFormat
+% \end{macrocode}
+% Ensure that inversions are dealt with for the label.
+% \begin{macrocode}
+ \let\DTLgidxParen\@gobble
+ \let\DTLgidxName\@secondoftwo
+ \let\DTLgidxPlace\datagidx@invert
+ \let\DTLgidxSubject\datagidx@invert
+ \let\DTLgidxOffice\@secondoftwo
+ \let\DTLgidxParticle\datagidx@bothoftwo
+% \end{macrocode}
+% Convert Greek maths (such as \cs{alpha}) to text.
+% \begin{macrocode}
+ \datagidxwordifygreek
+% \end{macrocode}
+% Strip accent commands so they don't interfere with the label.
+% \begin{macrocode}
+ \datagidxstripaccents
+% \end{macrocode}
+% Allow user to hook into this.
+% \begin{macrocode}
+ \newtermlabelhook
+ \protected@xdef\newterm@label{\newterm@label}%
+% \end{macrocode}
+% These commands behave differently for the sort key:
+% \begin{macrocode}
+ \let\DTLgidxName\datagidx@person
+ \let\DTLgidxPlace\datagidx@place
+ \let\DTLgidxSubject\datagidx@subject
+ \let\DTLgidxOffice\datagidx@person
+ \let\DTLgidxParen\datagidx@paren
+ \let\DTLgidxMac\datagidx@mac
+ \let\DTLgidxSaint\datagidx@saint
+ \let\DTLgidxIgnore\@gobble
+ \let\DTLgidxRank\datagidx@rank
+ \let\DTLgidxParticle\datagidx@particle
+ \let\DTLgidxNameNum\datagidx@namenum
+ \protected@xdef\newterm@sort{\newterm@sort}%
+ \egroup
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@add@term}
+% Add term (once all fields have been set. Argument is the name
+% field.
+% \begin{macrocode}
+\newcommand*{\datagidx@add@term}[1]{%
+ \global\cslet{datagidxentry@\newterm@label}{\newterm@database}%
+ \DTLnewrow{\newterm@database}%
+ \DTLnewdbentry{\newterm@database}{Name}{#1}%
+ \DTLnewdbentry{\newterm@database}{Used}{0}%
+ {%
+ \dtlexpandnewvalue
+ \DTLnewdbentry{\newterm@database}{Text}{\expandonce\newterm@text}%
+ \DTLnewdbentry{\newterm@database}{Description}{\expandonce\newterm@description}%
+ \DTLnewdbentry{\newterm@database}{Label}{\expandonce\newterm@label}%
+ \DTLnewdbentry{\newterm@database}{Sort}{\expandonce\newterm@sort}%
+ \DTLnewdbentry{\newterm@database}{Symbol}{\expandonce\newterm@symbol}%
+ \DTLnewdbentry{\newterm@database}{Short}{\expandonce\newterm@short}%
+ \DTLnewdbentry{\newterm@database}{Long}{\expandonce\newterm@long}%
+ \ifundef\newterm@plural
+ {%
+ \DTLnewdbentry{\newterm@database}{Plural}{\expandonce\newterm@text s}%
+ }%
+ {%
+ \DTLnewdbentry{\newterm@database}{Plural}{\expandonce\newterm@plural}%
+ }%
+ \ifundef\newterm@shortplural
+ {%
+ \DTLnewdbentry{\newterm@database}{ShortPlural}{\expandonce\newterm@short s}%
+ }%
+ {%
+ \DTLnewdbentry{\newterm@database}{ShortPlural}{\expandonce\newterm@shortplural}%
+ }%
+ \ifundef\newterm@longplural
+ {%
+ \DTLnewdbentry{\newterm@database}{LongPlural}{\expandonce\newterm@long s}%
+ }%
+ {%
+ \DTLnewdbentry{\newterm@database}{LongPlural}{\expandonce\newterm@longplural}%
+ }%
+ \ifdefempty{\newterm@see}%
+ {}%
+ {\DTLnewdbentry{\newterm@database}{See}{\newterm@see}}%
+ \ifdefempty{\newterm@seealso}%
+ {}%
+ {\DTLnewdbentry{\newterm@database}{SeeAlso}{\newterm@seealso}}%
+% \end{macrocode}
+% Hook to make it easier to add extra fields.
+% \begin{macrocode}
+ \newterm@extrafields
+% \end{macrocode}
+% Add parent, if supplied.
+% \begin{macrocode}
+ \ifdefempty{\newterm@parent}%
+ {}%
+ {%
+ \iftermexists{\newterm@parent}%
+ {%
+ \edef\newterm@parentdatabase{\csuse{datagidxentry@\newterm@parent}}%
+% \end{macrocode}
+% Parent entry must belong to same database as child entry.
+% \begin{macrocode}
+ \ifthenelse{\equal{\newterm@parentdatabase}{\newterm@database}}
+ {%
+ \DTLnewdbentry{\newterm@database}{Parent}{\newterm@parent}%
+ \datagidx@addchild{\newterm@database}{\newterm@parent}{\newterm@label}%
+ }%
+ {%
+ \PackageError{datagidx}%
+ {%
+ Parent entry `\newterm@parent' must belong to the
+ same database as child entry `\newterm@label'%
+ }%
+ {%
+ Parent entry is in database
+ `\newterm@parentdatabase' and child entry is in
+ database `\newterm@database'%
+ }%
+ }%
+ }%
+ {%
+ \PackageError{datagidx}%
+ {%
+ Can't assign parent to `\newterm@label':
+ `\newterm@parent' doesn't exist%
+ }%
+ {}%
+ }%
+ }%
+ }%
+% \end{macrocode}
+% Provide user with a means to access the label of the latest defined
+% term:
+% \begin{macrocode}
+ \global\let\datagidxlastlabel\newterm@label
+}%
+%\end{macro}
+%
+%\begin{macro}{\datagidx@newterm}
+% Normal behaviour for \cs{newterm}
+% \begin{macrocode}
+\newcommand{\datagidx@newterm}[2][]{%
+% \end{macrocode}
+% Assign values to all the fields.
+% \begin{macrocode}
+ \datagidx@setfieldvalues{#1}{#2}%
+% \end{macrocode}
+% Check if database exists.
+% \begin{macrocode}
+ \DTLifdbexists{\newterm@database}%
+ {%
+% \end{macrocode}
+% Database exists. Check if term already exists.
+% \begin{macrocode}
+ \iftermexists{\newterm@label}%
+ {%
+ \PackageError{datagidx}{Term `\newterm@label' already
+ exists in database `\newterm@database'}{}%
+ }%
+ {%
+% \end{macrocode}
+% Add this entry to the database.
+% \begin{macrocode}
+ \datagidx@add@term{#2}%
+ }%
+ }%
+ {%
+% \end{macrocode}
+% Database doesn't exist.
+% \begin{macrocode}
+ \PackageError{datagidx}%
+ {Glossary/index data base `\newterm@database' doesn't exist}%
+ {%
+ You must define the glossary/index data base before you can
+ add any terms to it.%
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidx@highopt@newterm}
+% Used when high optimized setting enabled. This setting must be
+% switched off if the user wants to modify the database.
+% \begin{macrocode}
+\newcommand{\datagidx@highopt@newterm}[2][]{%
+% \end{macrocode}
+% Assign values to all the fields.
+% \begin{macrocode}
+ \datagidx@setfieldvalues{#1}{#2}%
+% \end{macrocode}
+% Check if database exists.
+% \begin{macrocode}
+ \DTLifdbexists{\newterm@database}%
+ {%
+% \end{macrocode}
+% Database exists. If this is the first run, we need to add the term
+% as usual, otherwise we just need to define
+% \cs{datagidxentry@}\meta{label}
+% \begin{macrocode}
+ \edef\dtl@dogetrow{%
+ \noexpand\dtlgetrowindex
+ {\noexpand\dtl@rowidx}%
+ {\newterm@database}%
+ {%
+ \dtlcolumnindex{\newterm@database}{Label}%
+ }%
+ {\newterm@label}}%
+ \dtl@dogetrow
+ \ifx\dtl@rowidx\dtlnovalue
+% \end{macrocode}
+% Hasn't been defined so add.
+% \begin{macrocode}
+ \datagidx@add@term{#2}%
+% \end{macrocode}
+% Database will need to be sorted.
+% \begin{macrocode}
+ \csdef{datagidx@do@highopt@sort@\newterm@database}{\datagidx@sort}%
+ \else
+% \end{macrocode}
+% Has been defined, so just define \cs{datagidxentry@}\meta{label}
+% and \cs{datagidxlastlabel}
+% \begin{macrocode}
+ \global\cslet{datagidxentry@\newterm@label}{\newterm@database}%
+ \global\let\datagidxlastlabel\newterm@label
+ \fi
+ }%
+ {%
+% \end{macrocode}
+% Database doesn't exist.
+% \begin{macrocode}
+ \PackageError{datagidx}%
+ {Glossary/index data base `\newterm@database' doesn't exist}%
+ {%
+ You must define the glossary/index data base before you can
+ add any terms to it.%
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\datagidx@addchild}
+% \begin{macrocode}
+\newcommand*{\datagidx@addchild}[3]{%
+ \edef\dtl@dogetrow{%
+ \noexpand\dtlgetrowforvalue
+ {#1}%
+ {%
+ \dtlcolumnindex{\newterm@database}{Label}%
+ }%
+ {#2}}%
+ \dtl@dogetrow
+ \dtlgetentryfromcurrentrow
+ {\datagidx@child}%
+ {\dtlcolumnindex{#1}{Child}}%
+ \ifx\datagidx@child\dtlnovalue
+ \edef\datagidx@child{#3}%
+ \else
+ \edef\datagidx@child{\datagidx@child,#3}%
+ \fi
+ \edef\do@update{\noexpand\dtlupdateentryincurrentrow
+ {Child}{\datagidx@child}}%
+ \do@update
+ \dtlrecombine
+}
+% \end{macrocode}
+%\end{macro}
+%\subsection{Defining Acronyms}
+%\begin{macro}{\newacro}
+%\begin{definition}
+%\cs{newacro}\oarg{options}\marg{short}\marg{long}
+%\end{definition}
+% Shortcut command for acronyms.
+% \begin{macrocode}
+\newcommand{\newacro}[3][]{%
+ \newterm
+ [%
+ description={\capitalisewords{#3}},%
+ short={\acronymfont{#2}},%
+ long={#3},%
+ text={\DTLgidxAcrStyle{#3}{\acronymfont{#2}}},%
+ plural={\DTLgidxAcrStyle{#3s}{\acronymfont{#2s}}},%
+ sort={#2},%
+ #1%
+ ]%
+ {\MakeTextUppercase{#2}}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\acronymfont}
+% The font to use for the acronym.
+% \begin{macrocode}
+\newcommand*{\acronymfont}[1]{#1}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\DTLgidxAcrStyle}
+%\begin{definition}
+%\cs{DTLgidxAcrStyle}\marg{long}\marg{short}
+%\end{definition}
+% \begin{macrocode}
+\newcommand*{\DTLgidxAcrStyle}[2]{#1 (#2)}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\section{Conditionals}
+%
+%\begin{macro}{\iftermexists}
+%\begin{definition}
+% \cs{iftermexists}\marg{label}\marg{true part}\marg{false part}
+%\end{definition}
+% Check if term with given label exists.
+% \begin{macrocode}
+\newcommand{\iftermexists}[3]{%
+ \ifcsdef{datagidxentry@#1}{#2}{#3}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\ifentryused}
+%\begin{definition}
+% \cs{ifentryused}\marg{label}\marg{true part}\marg{false part}
+%\end{definition}
+% Check if entry with given label has been used.
+% \begin{macrocode}
+\newcommand*{\ifentryused}[3]{%
+ \letcs{\newterm@database}{datagidxentry@#1}%
+% \end{macrocode}
+% \cs{dtlgetrowforvalue} doesn't expand the value when it checks for
+% a match, so make sure label is fully expanded.
+% \begin{macrocode}
+ \edef\dtl@dogetrow{%
+ \noexpand\dtlgetrowforvalue
+ {\newterm@database}%
+ {%
+ \dtlcolumnindex{\newterm@database}{Label}%
+ }%
+ {#1}}%
+ \dtl@dogetrow
+ \dtlgetentryfromcurrentrow
+ {\datagidx@value}%
+ {\dtlcolumnindex{\newterm@database}{Used}}%
+ \ifnum\datagidx@value=1\relax
+ #2%
+ \else
+ #3%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\section{Unsetting and Resetting}
+%
+%\begin{macro}{\glsreset}
+%\begin{definition}
+%\cs{glsunset}\marg{label}
+%\end{definition}
+% Mark as un-used.
+% \begin{macrocode}
+\newcommand*{\glsreset}[1]{%
+% \end{macrocode}
+% Fetch the name of the database with which this entry is
+% associated.
+% \begin{macrocode}
+ \letcs{\newterm@database}{datagidxentry@#1}%
+% \end{macrocode}
+% Get the row associated with this label and make it the current row.
+% \begin{macrocode}
+ \edef\do@getrow{%
+ \noexpand\dtlgetrowforvalue
+ {\newterm@database}%
+ {\dtlcolumnindex{\newterm@database}{Label}}%
+ {#1}%
+ }%
+ \do@getrow
+% \end{macrocode}
+% Update the "Used" field.
+% \begin{macrocode}
+ \dtlreplaceentryincurrentrow
+ {0}{\dtlcolumnindex{\newterm@database}{Used}}%
+% \end{macrocode}
+% Current row has been edited, so we need to merge the current row
+% back into the database.
+% \begin{macrocode}
+ \dtlrecombine
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\glsunset}
+%\begin{definition}
+%\cs{glsunset}\marg{label}
+%\end{definition}
+% Mark as used without affecting location.
+% \begin{macrocode}
+\newcommand*{\glsunset}[1]{%
+% \end{macrocode}
+% Fetch the name of the database with which this entry is
+% associated.
+% \begin{macrocode}
+ \letcs{\newterm@database}{datagidxentry@#1}%
+% \end{macrocode}
+% Get the row associated with this label and make it the current row.
+% \begin{macrocode}
+ \edef\do@getrow{%
+ \noexpand\dtlgetrowforvalue
+ {\newterm@database}%
+ {\dtlcolumnindex{\newterm@database}{Label}}%
+ {#1}%
+ }%
+ \do@getrow
+% \end{macrocode}
+% Update the "Used" field.
+% \begin{macrocode}
+ \dtlreplaceentryincurrentrow
+ {1}{\dtlcolumnindex{\newterm@database}{Used}}%
+% \end{macrocode}
+% Current row has been edited, so we need to merge the current row
+% back into the database.
+% \begin{macrocode}
+ \dtlrecombine
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\glsresetall}
+%\begin{definition}
+%\cs{glsresetall}\marg{db}
+%\end{definition}
+% Resets all entries in the given database.
+% \begin{macrocode}
+\newcommand*{\glsresetall}[1]{%
+ \def\datagidx@list{}%
+ \dtlforcolumn{\datagidx@label}{#1}{Label}%
+ {%
+ \ifdefempty\datagidx@list
+ {%
+ \let\datagidx@list\datagidx@label
+ }%
+ {%
+ \eappto\datagidx@list{,\datagidx@label}%
+ }%
+ }%
+ \@for\datagidx@thislabel:=\datagidx@list\do
+ {%
+ \glsreset{\datagidx@thislabel}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\glsunsetall}
+%\begin{definition}
+%\cs{glsunsetall}\marg{db}
+%\end{definition}
+% Resets all entries in the given database.
+% \begin{macrocode}
+\newcommand*{\glsunsetall}[1]{%
+ \def\datagidx@list{}%
+ \dtlforcolumn{\datagidx@label}{#1}{Label}%
+ {%
+ \ifdefempty\datagidx@list
+ {%
+ \let\datagidx@list\datagidx@label
+ }%
+ {%
+ \eappto\datagidx@list{,\datagidx@label}%
+ }%
+ }%
+ \@for\datagidx@thislabel:=\datagidx@list\do
+ {%
+ \glsunset{\datagidx@thislabel}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\section{Accessing Entry Information}
+%
+%\begin{macro}{\datagidx@anchorcount}
+% Register to make unique anchors.
+% \begin{macrocode}
+\newcount\datagidx@anchorcount
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidx@formatanchor}
+% Format number using six digits.
+% \begin{macrocode}
+\newcommand*{\datagidx@formatanchor}[1]{%
+ \ifnum#1<10000
+ 0%
+ \ifnum#1<1000
+ 0%
+ \ifnum#1<100
+ 0%
+ \ifnum#1<10
+ 0%
+ \fi
+ \fi
+ \fi
+ \fi
+ \number#1%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@datagidx@escloc}
+% \begin{macrocode}
+\newcommand*{\@datagidx@escloc}[2]{%
+ \expandafter\string\csname#1\endcsname{\noexpand\number#2}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@escapelocation}
+% \begin{macrocode}
+\newcommand*{\datagidx@escapelocation}{%
+ \def\@arabic{\@datagidx@escloc{@arabic}}%
+ \def\@roman{\@datagidx@escloc{@roman}}%
+ \def\@Roman{\@datagidx@escloc{@Roman}}%
+ \def\@alph{\@datagidx@escloc{@alph}}%
+ \def\@Alph{\@datagidx@escloc{@Alph}}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidx@escapelocationformat}
+% \begin{macrocode}
+\newcommand*{\datagidx@escapelocationformat}{%
+ \def\@arabic##1{arabic}%
+ \def\@roman##1{roman}%
+ \def\@Roman##1{Roman}%
+ \def\@alph##1{alph}%
+ \def\@Alph##1{Alph}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\datagidx@clearlocationformat}
+% \begin{macrocode}
+\newcommand*{\datagidx@clearlocationformat}{%
+ \let\@arabic\@firstofone
+ \let\@roman\@firstofone
+ \let\@Roman\@firstofone
+ \let\@alph\@firstofone
+ \let\@Alph\@firstofone
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxAddLocationType}
+% Allow user to add their own location type. Argument must be
+% control sequence name without initial backslash.
+% \begin{macrocode}
+\newcommand*{\DTLgidxAddLocationType}[1]{%
+ \gappto\datagidx@escapelocation{%
+ \expandafter\def\csname#1\endcsname{\@datagidx@escloc{#1}}%
+ }%
+ \gappto\datagidx@escapelocationformat{%
+ \expandafter\def\csname#1\endcsname##1{#1}%
+ }%
+ \gappto\datagidx@clearlocationformat{%
+ \expandafter\let\csname#1\endcsname\@firstofone
+ }%
+}
+% \end{macrocode}
+% May only be used in the preamble. (Needs to be set before the aux
+% file is read.)
+% \begin{macrocode}
+\@onlypreamble\DTLgidxAddLocationType
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@target}
+%\begin{definition}
+%\cs{datagidx@target}\marg{label}\marg{format}\marg{location}\marg{text}
+%\end{definition}
+% Make a target if \cs{hypertarget} has been defined.
+% \begin{macrocode}
+\newcommand*{\datagidx@target}[4]{%
+ \global\advance\datagidx@anchorcount by 1\relax
+ \edef\@datagidx@target{datagidx.\datagidx@formatanchor\datagidx@anchorcount}%
+ \ifstrempty{#3}
+ {%
+ \datagidx@write@usedentry{#1}{}%
+ }%
+ {%
+ \bgroup
+ \datagidx@escapelocation
+ \protected@edef\@datagidx@dowriteaux{%
+ \noexpand\datagidx@write@usedentry{#1}%
+ {[#2]{#3}{\@datagidx@target}}%
+ }%
+ \@datagidx@dowriteaux
+ \egroup
+ }%
+ \ifdef\hypertarget
+ {%
+% \end{macrocode}
+% Make sure the current line doesn't scroll off the top of the
+% screen.
+% \begin{macrocode}
+ \datagidxshowifdraft
+ {%
+ [\@datagidx@target]%
+ \discretionary{}{}{}%
+ }%
+ \bgroup
+ \let\glsadd\@gobble
+ \settoheight\dimen@{#4}%
+ \raisebox{\dimen@}%
+ {%
+ \datagidxtarget{\@datagidx@target}{}%
+ }%
+ \egroup
+ }%
+ {%
+ }%
+ \datagidxshowifdraft{[#1]\discretionary{}{}{}}%
+ #4%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\glsdispentry}
+%\begin{definition}
+%\cs{glsdispentry}\marg{label}\marg{field}
+%\end{definition}
+% Short cut that fetches and displays a value.
+% \begin{macrocode}
+\DeclareRobustCommand*{\glsdispentry}[2]{%
+ \DTLgidxFetchEntry{\datagidx@dispentryval}{#1}{#2}%
+ \datagidx@dispentryval
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\Glsdispentry}
+%\begin{definition}
+%\cs{Glsdispentry}\marg{label}\marg{field}
+%\end{definition}
+% As previous but makes the first letter upper case.
+% \begin{macrocode}
+\DeclareRobustCommand*{\Glsdispentry}[2]{%
+ \DTLgidxFetchEntry{\datagidx@dispentryval}{#1}{#2}%
+ \xmakefirstuc\datagidx@dispentryval
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxFetchEntry}
+% Fetch value for the given field for the term identified by
+% \meta{label} and store the value in \meta{cs} (a control sequence).
+% \begin{macrocode}
+\newcommand*{\DTLgidxFetchEntry}[3]{%
+% \end{macrocode}
+% Does this entry exist?
+% \begin{macrocode}
+ \ifcsdef{datagidxentry@#2}%
+ {%
+% \end{macrocode}
+% Fetch the name of the database with which this entry is
+% associated.
+% \begin{macrocode}
+ \letcs{\newterm@database}{datagidxentry@#2}%
+% \end{macrocode}
+% Get the row associated with this label and make it the current row.
+% \begin{macrocode}
+ \edef\do@getrow{%
+ \noexpand\dtlgetrowforvalue
+ {\newterm@database}%
+ {\dtlcolumnindex{\newterm@database}{Label}}%
+ {#2}%
+ }%
+ \do@getrow
+% \end{macrocode}
+% Get the entry for the given field in the current row and store in
+% \meta{cs}.
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {#1}%
+ {\dtlcolumnindex{\newterm@database}{#3}}%
+ }%
+ {%
+% \end{macrocode}
+% Entry hasn't been defined.
+% \begin{macrocode}
+ \PackageError{datagidx}{No term `#2' defined}{}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@parse@formatlabel}
+%\begin{definition}
+%\cs{parse@formatlabel}\marg{\oarg{format}label}
+%\end{definition}
+% Separate format and label from argument.
+% \begin{macrocode}
+\newcommand*{\datagidx@parse@formatlabel}[1]{%
+ \datagidx@parse@format@label@#1\@endparse@formatlabel@
+}
+\newcommand*\datagidx@parse@format@label@{%
+ \@ifnextchar[{\datagidx@parse@formatlabel@}{\datagidx@parse@formatlabel@[]}%
+}
+\def\datagidx@parse@formatlabel@[#1]#2\@endparse@formatlabel@{%
+ \def\datagidx@format{#1}%
+ \def\datagidx@label{#2}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@use@entry}
+%\begin{definition}
+%\cs{use@entry}\marg{field}\marg{link text}
+%\end{definition}
+% The label and format should have been stored in
+% \cs{datagidx@label} and \cs{datagidx@format} before calling this
+% macro.
+% \begin{macrocode}
+\newcommand*{\datagidx@use@entry}[2]{%
+% \end{macrocode}
+% Does this term exist?
+% \begin{macrocode}
+ \ifcsundef{datagidxentry@\datagidx@label}
+ {%
+ \PackageError{datagidx}{Entry `\datagidx@label' doesn't exist}{}%
+ }%
+ {%
+% \end{macrocode}
+% Fetch the name of the database with which this entry is
+% associated.
+% \begin{macrocode}
+ \letcs{\newterm@database}{datagidxentry@\datagidx@label}%
+% \end{macrocode}
+% Get the row associated with this label and make it the current row.
+% \begin{macrocode}
+ \edef\do@getrow{%
+ \noexpand\dtlgetrowforvalue
+ {\newterm@database}%
+ {\dtlcolumnindex{\newterm@database}{Label}}%
+ {\datagidx@label}%
+ }%
+ \do@getrow
+% \end{macrocode}
+% Get the entry for the "FirstId" field and store in \cs{datagidx@id}
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {\datagidx@id}%
+ {\dtlcolumnindex{\newterm@database}{FirstId}}%
+% \end{macrocode}
+% If it hasn't been defined set it.
+% \begin{macrocode}
+ \DTLifnull\datagidx@id
+ {%
+% \end{macrocode}
+% Count register hasn't been updated yet.
+% \begin{macrocode}
+ \count@=\datagidx@anchorcount\relax
+ \advance\count@ by 1\relax
+ \dtlappendentrytocurrentrow{FirstId}{\datagidx@formatanchor\count@}%
+ }%
+ {}%
+% \end{macrocode}
+% Get the entry for the given field in the current row and store in
+% \cs{datagidx@value}.
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {\datagidx@value}%
+ {\dtlcolumnindex{\newterm@database}{#1}}%
+% \end{macrocode}
+% Update the "Used" field.
+% \begin{macrocode}
+ \dtlreplaceentryincurrentrow
+ {1}{\dtlcolumnindex{\newterm@database}{Used}}%
+% \end{macrocode}
+% Get the parent entry label (if one exists).
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {\datagidx@parent}%
+ {\dtlcolumnindex{\newterm@database}{Parent}}%
+% \end{macrocode}
+% Current row has been edited, so we need to merge the current row
+% back into the database.
+% \begin{macrocode}
+ \dtlrecombine
+% \end{macrocode}
+% If parent hasn't be used, give it an empty location.
+% \begin{macrocode}
+ \datagidx@markparent{\newterm@database}{\datagidx@parent}%
+% \end{macrocode}
+% Write the location to the auxiliary file and display value of
+% field.
+% \begin{macrocode}
+ \datagidx@target{\datagidx@label}{\datagidx@format}%
+ {\csuse{the\DTLgidxCounter}}{#2}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxCounter}
+% The counter used for the location lists.
+% \begin{macrocode}
+\newcommand*{\DTLgidxCounter}{page}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@markparent}
+% Assign empty location to parent, if location of that parent is null.
+% (Recursive).
+% \begin{macrocode}
+\newcommand*{\datagidx@markparent}[2]{%
+ \ifx#2\dtlnovalue
+% \end{macrocode}
+% Null parent, so break out of recursion.
+% \begin{macrocode}
+ \else
+% \end{macrocode}
+% Write empty location to the auxiliary file.
+% \begin{macrocode}
+ \datagidx@target{#2}{}{}{}%
+% \end{macrocode}
+% Fetch this parent's parent entry.
+% Get the row associated with this and make it the current row.
+% \begin{macrocode}
+ \edef\do@getrow{%
+ \noexpand\dtlgetrowforvalue
+ {#1}%
+ {\dtlcolumnindex{#1}{Label}}%
+ {#2}}%
+ \do@getrow
+% \end{macrocode}
+% Get the entry for the "FirstId" field and store in \cs{datagidx@id}
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {\datagidx@id}%
+ {\dtlcolumnindex{\newterm@database}{FirstId}}%
+% \end{macrocode}
+% If it hasn't been defined set it.
+% \begin{macrocode}
+ \DTLifnull\datagidx@id
+ {%
+ \dtlappendentrytocurrentrow{FirstId}{\datagidx@formatanchor\datagidx@anchorcount}%
+ }%
+ {}%
+% \end{macrocode}
+% Get the parent
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {\datagidx@parent}%
+ {\dtlcolumnindex{#1}{Parent}}%
+% \end{macrocode}
+% Current row has been edited, so we need to merge the current row
+% back into the database.
+% \begin{macrocode}
+ \dtlrecombine
+% \end{macrocode}
+% Recurse
+% \begin{macrocode}
+ \datagidx@markparent{#1}{\datagidx@parent}%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@write@usedentry}
+% Write out location to aux file and add location to the location
+% list for the current run.
+% \begin{macrocode}
+\newcommand*{\datagidx@write@usedentry}[2]{%
+% \end{macrocode}
+% Do update if `highopt optimize' setting is on.
+% \begin{macrocode}
+ \datagidx@do@highopt@update{#1}%
+% \end{macrocode}
+% Write out location to aux file.
+% \begin{macrocode}
+ \protected@write{\@auxout}{}%
+ {%
+ \string\datagidx@usedentry{#1}{#2}%
+ }%
+% \end{macrocode}
+% Add to this run's location field.
+% \begin{macrocode}
+ \protected@edef\datagidx@do@usedentry{%
+ \noexpand\datagidx@usedentry[CurrentLocation]{#1}{#2}%
+ }%
+ \datagidx@do@usedentry
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@usedentry}
+%\begin{definition}
+%\cs{datagidx@usedentry}\oarg{location tag}\marg{label}\marg{location}
+%\end{definition}
+% Add to the location list for the given entry.
+% \begin{macrocode}
+\newcommand*{\datagidx@usedentry}[3][Location]{%
+% \end{macrocode}
+% Check if label exists. (It may have been deleted or had a label
+% change.)
+% \begin{macrocode}
+ \ifcsundef{datagidxentry@#2}%
+ {%
+ \PackageWarning{datagidx}{No term `#2' defined. Ignoring}%
+ }%
+ {%
+% Fetch the name of the database with which this entry is
+% associated.
+% \begin{macrocode}
+ \letcs{\newterm@database}{datagidxentry@#2}%
+% \end{macrocode}
+% Get the row associated with this label and make it the current row.
+% \begin{macrocode}
+ \edef\do@getrow{%
+ \noexpand\dtlgetrowforvalue
+ {\newterm@database}%
+ {\dtlcolumnindex{\newterm@database}{Label}}%
+ {#2}%
+ }%
+ \do@getrow
+% \end{macrocode}
+% \begin{macrocode}
+% Get the entry for the \meta{location tag} field in the current row and store in
+% \cs{datagidx@loc}.
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {\datagidx@loc}%
+ {\dtlcolumnindex{\newterm@database}{#1}}%
+% \end{macrocode}
+% Check the success of the previous command.
+% \begin{macrocode}
+ \ifx\datagidx@loc\dtlnovalue
+% \end{macrocode}
+% There's no \meta{location tag} field in the current row, so add one with
+% the given location.
+% \begin{macrocode}
+ \def\datagidx@loc{#3}%
+ \dtlappendentrytocurrentrow{#1}{\expandonce\datagidx@loc}%
+ \else
+% \end{macrocode}
+% There is a \meta{location tag} field in the current row, so append the
+% given location to the list, unless one or the other is empty.
+% \begin{macrocode}
+ \ifdefempty{\datagidx@loc}%
+ {%
+ \def\datagidx@loc{#3}%
+ }%
+ {%
+ \ifstrempty{#3}%
+ {}%
+ {%
+ \appto\datagidx@loc{,#3}%
+ }%
+ }%
+% \end{macrocode}
+% and update the entry in the current row.
+% \begin{macrocode}
+ \expandafter\dtlreplaceentryincurrentrow\expandafter
+ {\datagidx@loc}%
+ {\dtlcolumnindex{\newterm@database}{#1}}%
+ \fi
+% \end{macrocode}
+% Current row has been edited, so we need to merge the current row
+% back into the database.
+% \begin{macrocode}
+ \dtlrecombine
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@save@loc}
+% Store the current location from the previous run.
+% \begin{macrocode}
+\newcommand*{\datagidx@save@loc}[2]{%
+ \bgroup
+ \datagidx@escapelocation
+ \xdef\datagidx@tmp{#2}%
+ \egroup
+ \expandafter\xdef\csname datagidx@prev@loc@#1\endcsname{\datagidx@tmp}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\glsadd}
+%\begin{definition}
+%\cs{glsadd}\marg{\oarg{format}label}
+%\end{definition}
+% \begin{macrocode}
+\newcommand*{\glsadd}[1]{%
+ \NoCaseChange{\@glsadd{#1}}%
+}
+\DeclareRobustCommand*{\@glsadd}[1]{%
+% \end{macrocode}
+% Check term has been defined.
+% \begin{macrocode}
+ \ifcsundef{datagidxentry@\datagidx@label}%
+ {%
+ \PackageError{datagidx}{Term `\datagidx@label' doesn't exist}{}%
+ }%
+ {%
+% \end{macrocode}
+% \begin{macrocode}
+ \datagidx@parse@formatlabel{#1}%
+% \end{macrocode}
+% Write the location to the auxiliary file.
+% \begin{macrocode}
+ \datagidx@target{\datagidx@label}{\datagidx@format}%
+ {\csuse{the\DTLgidxCounter}}{}%
+% \end{macrocode}
+% Fetch the name of the database with which this entry is
+% associated.
+% \begin{macrocode}
+ \letcs{\newterm@database}{datagidxentry@\datagidx@label}%
+% \end{macrocode}
+% Get the row associated with this label and make it the current row.
+% \begin{macrocode}
+ \edef\do@getrow{%
+ \noexpand\dtlgetrowforvalue
+ {\newterm@database}%
+ {\dtlcolumnindex{\newterm@database}{Label}}%
+ {\datagidx@label}%
+ }%
+ \do@getrow
+% \end{macrocode}
+% Update the "Used" field.
+% \begin{macrocode}
+ \dtlreplaceentryincurrentrow
+ {1}{\dtlcolumnindex{\newterm@database}{Used}}%
+% \end{macrocode}
+% Get the entry for the "FirstId" field and store in \cs{datagidx@id}
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {\datagidx@id}%
+ {\dtlcolumnindex{\newterm@database}{FirstId}}%
+% \end{macrocode}
+% If it hasn't been defined set it.
+% \begin{macrocode}
+ \DTLifnull\datagidx@id
+ {%
+ \dtlappendentrytocurrentrow{FirstId}{\datagidx@formatanchor\datagidx@anchorcount}%
+ }%
+ {}%
+% \end{macrocode}
+% Current row has been edited, so we need to merge the current row
+% back into the database.
+% \begin{macrocode}
+ \dtlrecombine
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@count}
+% Loop counter used by \cs{glsaddall}
+% \begin{macrocode}
+\newcount\datagidx@count
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\glsaddall}
+%\begin{definition}
+%\cs{glsaddall}\marg{db}
+%\end{definition}
+% Adds all entries in the given database.
+% \begin{macrocode}
+\newcommand*{\glsaddall}[1]{%
+ \DTLifdbexists{#1}%
+ {%
+ \edef\datagidx@rowcount{\number\DTLrowcount{#1}}%
+ \datagidx@count=0\relax
+ \loop
+ \advance\datagidx@count by 1\relax
+ \dtlgetrow{#1}{\datagidx@count}%
+% \end{macrocode}
+% Get the label for this row.
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {\datagidx@label}%
+ {\dtlcolumnindex{\newterm@database}{Label}}%
+% \end{macrocode}
+% Write blank location to the auxiliary file but temporarily undefine
+% \cs{hypertarget} as it doesn't make sense to have a target here.
+% \begin{macrocode}
+ \bgroup
+ \undef\hypertarget
+ \datagidx@target{\datagidx@label}{}{}{}%
+ \egroup
+% \end{macrocode}
+% Update the "Used" field.
+% \begin{macrocode}
+ \dtlreplaceentryincurrentrow
+ {1}{\dtlcolumnindex{\newterm@database}{Used}}%
+% \end{macrocode}
+% Get the entry for the "FirstId" field and store in \cs{datagidx@id}
+% \begin{macrocode}
+ \dtlgetentryfromcurrentrow
+ {\datagidx@id}%
+ {\dtlcolumnindex{\newterm@database}{FirstId}}%
+% \end{macrocode}
+% If it hasn't been defined set it.
+% \begin{macrocode}
+ \DTLifnull\datagidx@id
+ {%
+ \dtlappendentrytocurrentrow{FirstId}{\datagidx@formatanchor\datagidx@anchorcount}%
+ }%
+ {}%
+% \end{macrocode}
+% Current row has been edited, so we need to merge the current row
+% back into the database.
+% \begin{macrocode}
+ \dtlrecombine
+% \end{macrocode}
+% Repeat loop if not finished.
+% \begin{macrocode}
+ \ifnum\datagidx@count<\datagidx@rowcount
+ \repeat
+ }%
+ {%
+ \PackageError{datagidx}{Database `#1' doesn't exist}{}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\useentry}
+%\begin{definition}
+%\cs{useentry}\marg{label}\marg{field}
+%\end{definition}
+% Fetch and use the given field for the given entry.
+% \begin{macrocode}
+\DeclareRobustCommand*{\useentry}[2]{%
+ \datagidx@parse@formatlabel{#1}%
+ \DTLgidxFetchEntry{\datagidx@value}{\datagidx@label}{#2}%
+ \datagidxlink{\datagidx@label}%
+ {%
+ \datagidx@use@entry{#2}{\datagidx@value}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\Useentry}
+%\begin{definition}
+%\cs{Useentry}\marg{label}\marg{field}
+%\end{definition}
+% As \cs{useentry}, but capitalise the first word.
+% \begin{macrocode}
+\DeclareRobustCommand*{\Useentry}[2]{%
+ \datagidx@parse@formatlabel{#1}%
+ \DTLgidxFetchEntry{\datagidx@value}{\datagidx@label}{#2}%
+ \datagidxlink{\datagidx@label}%
+ {%
+ \datagidx@use@entry{#2}{\xmakefirstuc{\datagidx@value}}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\USEentry}
+%\begin{definition}
+%\cs{USEentry}\marg{label}\marg{field}
+%\end{definition}
+% As \cs{useentry}, but make the whole term upper case.
+% \begin{macrocode}
+\DeclareRobustCommand*{\USEentry}[2]{%
+ \datagidx@parse@formatlabel{#1}%
+ \DTLgidxFetchEntry{\datagidx@value}{\datagidx@label}{#2}%
+ \datagidxlink{\datagidx@label}%
+ {%
+ \datagidx@use@entry{#2}{\MakeTextUppercase{\datagidx@value}}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\useentrynl}
+%\begin{definition}
+%\cs{useentrynl}\marg{label}\marg{field}
+%\end{definition}
+% Fetch and use the given field for the given entry without creating
+% a hyperlink.
+% \begin{macrocode}
+\DeclareRobustCommand*{\useentrynl}[2]{%
+ \datagidx@parse@formatlabel{#1}%
+ \DTLgidxFetchEntry{\datagidx@value}{\datagidx@label}{#2}%
+ \datagidx@use@entry{#2}{\datagidx@value}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\Useentrynl}
+%\begin{definition}
+%\cs{Useentrynl}\marg{label}\marg{field}
+%\end{definition}
+% As \cs{useentry}, but capitalise the first word.
+% \begin{macrocode}
+\DeclareRobustCommand*{\Useentrynl}[2]{%
+ \datagidx@parse@formatlabel{#1}%
+ \DTLgidxFetchEntry{\datagidx@value}{\datagidx@label}{#2}%
+ \datagidx@use@entry{#2}{\xmakefirstuc{\datagidx@value}}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\USEentrynl}
+%\begin{definition}
+%\cs{USEentrynl}\marg{label}\marg{field}
+%\end{definition}
+% As \cs{useentry}, but make the whole term upper case.
+% \begin{macrocode}
+\DeclareRobustCommand*{\USEentrynl}[2]{%
+ \datagidx@parse@formatlabel{#1}%
+ \DTLgidxFetchEntry{\datagidx@value}{\datagidx@label}{#2}%
+ \datagidx@use@entry{#2}{\MakeTextUppercase{\datagidx@value}}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%
+% Short cuts to common fields.
+%\begin{macro}{\gls}
+% \begin{macrocode}
+\DeclareRobustCommand*{\gls}[1]{\useentry{#1}{Text}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\glspl}
+% \begin{macrocode}
+\DeclareRobustCommand*{\glspl}[1]{\useentry{#1}{Plural}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\Gls}
+% \begin{macrocode}
+\DeclareRobustCommand*{\Gls}[1]{\Useentry{#1}{Text}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\Glspl}
+% \begin{macrocode}
+\DeclareRobustCommand*{\Glspl}[1]{\Useentry{#1}{Plural}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\glsnl}
+% \begin{macrocode}
+\DeclareRobustCommand*{\glsnl}[1]{\useentrynl{#1}{Text}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\glsplnl}
+% \begin{macrocode}
+\DeclareRobustCommand*{\glsplnl}[1]{\useentrynl{#1}{Plural}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\Glsnl}
+% \begin{macrocode}
+\DeclareRobustCommand*{\Glsnl}[1]{\Useentrynl{#1}{Text}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\Glsplnl}
+% \begin{macrocode}
+\DeclareRobustCommand*{\Glsplnl}[1]{\Useentrynl{#1}{Plural}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\glssym}
+% \begin{macrocode}
+\DeclareRobustCommand*{\glssym}[1]{\useentry{#1}{Symbol}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\Glssym}
+% \begin{macrocode}
+\DeclareRobustCommand*{\Glssym}[1]{\Useentry{#1}{Symbol}}
+% \end{macrocode}
+%\end{macro}
+%
+%\subsection{Using Acronyms}
+%\begin{macro}{\DTLgidxFormatAcr}
+%\begin{definition}
+%\cs{DTLgidxFormatAcr}\marg{label}\marg{long field}\marg{short field}
+%\end{definition}
+% \begin{macrocode}
+\newcommand*{\DTLgidxFormatAcr}[3]{%
+ \DTLgidxAcrStyle{\glsdispentry{#1}{#2}}{\useentry{#1}{#3}}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxFormatAcrUC}
+%\begin{definition}
+%\cs{DTLgidxFormatAcr}\marg{label}\marg{long field}\marg{short field}
+%\end{definition}
+%As previous but capitalise first word.
+% \begin{macrocode}
+\newcommand*{\DTLgidxFormatAcrUC}[3]{%
+ \DTLgidxAcrStyle{\Glsdispentry{#1}{#2}}{\useentry{#1}{#3}}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\acr}
+% \begin{macrocode}
+\DeclareRobustCommand*{\acr}[1]{%
+ \ifentryused{#1}%
+ {\useentry{#1}{Short}}%
+ {\DTLgidxFormatAcr{#1}{Long}{Short}}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\acrpl}
+% \begin{macrocode}
+\DeclareRobustCommand*{\acrpl}[1]{%
+ \ifentryused{#1}%
+ {\useentry{#1}{ShortPlural}}%
+ {\DTLgidxFormatAcr{#1}{LongPlural}{ShortPlural}}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\Acr}
+% \begin{macrocode}
+\DeclareRobustCommand*{\Acr}[1]{%
+ \ifentryused{#1}%
+ {\Useentry{#1}{Short}}%
+ {\DTLgidxFormatAcrUC{#1}{Long}{Short}}%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\Acrpl}
+% \begin{macrocode}
+\DeclareRobustCommand*{\Acrpl}[1]{%
+ \ifentryused{#1}%
+ {\Useentry{#1}{ShortPlural}}%
+ {\DTLgidxFormatAcrUC{#1}{LongPlural}{ShortPlural}}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\section{Displaying Glossaries, Lists of Acronyms, Indices}
+% Define keys for \cs{printterms}:
+% \begin{macrocode}
+\define@key{printterms}{database}{\renewcommand*{\newterm@database}{#1}}
+% \end{macrocode}
+% Options for post description.
+% \begin{macrocode}
+\define@choicekey{printterms}{postdesc}[\val\nr]%
+ {none,dot}%
+ {%
+ \datagidx@setpostdesc\nr
+ }
+% \end{macrocode}
+% Options for pre-location.
+% \begin{macrocode}
+\define@choicekey{printterms}{prelocation}[\val\nr]%
+ {none,enspace,space,dotfill,hfill}%
+ {%
+ \datagidx@setprelocation\nr
+ }
+% \end{macrocode}
+% How to display the location list.
+% \begin{macrocode}
+\define@choicekey{printterms}{location}[\val\nr]%
+ {hide,list,first}%
+ {\datagidx@setlocation\nr}
+% \end{macrocode}
+% How to format the symbol in relation to the description.
+% \begin{macrocode}
+\define@choicekey{printterms}{symboldesc}[\val\nr]%
+ {symbol,desc,(symbol) desc,desc (symbol),symbol desc,desc symbol}%
+ {\datagidx@formatsymdesc\nr}
+% \end{macrocode}
+% How many columns to have.
+% \begin{macrocode}
+\define@key{printterms}{columns}%
+{%
+ \DTLgidxSetColumns{#1}%
+}
+% \end{macrocode}
+% How to format the name.
+% \begin{macrocode}
+\define@choicekey{printterms}{namecase}[\val\nr]%
+ {nochange,uc,lc,firstuc,capitalise}%
+ {%
+ \datagidx@setnamecase\nr
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\define@key{printterms}{namefont}%
+{%
+ \renewcommand*{\DTLgidxNameFont}[1]{{#1{##1}}}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\define@key{printterms}{postname}
+{%
+ \renewcommand*{\DTLgidxPostName}{#1}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\define@choicekey{printterms}{see}[\val\nr]%
+ {comma,brackets,dot,space,nosep,semicolon,location}%
+ {\datagidx@setsee\nr}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\define@choicekey{printterms}{child}[\val\nr]%
+ {named,noname}%
+ {%
+ \datagidx@setchildstyle\nr
+ }
+% \end{macrocode}
+% Symbol width
+% \begin{macrocode}
+\define@key{printterms}{symbolwidth}%
+{%
+ \setlength{\datagidxsymbolwidth}{#1}%
+}
+% \end{macrocode}
+% Location width
+% \begin{macrocode}
+\define@key{printterms}{locationwidth}%
+{%
+ \setlength{\datagidxlocationwidth}{#1}%
+}
+% \end{macrocode}
+% Child sort:
+% \begin{macrocode}
+\define@choicekey{printterms}{childsort}[\val\nr]%
+ {true,false}[true]%
+ {%
+ \datagidx@setchildsort\nr
+ }
+% \end{macrocode}
+% Change style:
+% \begin{macrocode}
+\define@choicekey{printterms}{showgroups}{true,false}[true]{%
+ \appto\newterm@styles{showgroups={#1},}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\define@key{printterms}{style}{\appto\newterm@styles{style={#1},}}
+% \end{macrocode}
+% \begin{macrocode}
+\define@key{printterms}{heading}{\appto\newterm@styles{heading={#1},}}
+% \end{macrocode}
+% \begin{macrocode}
+\define@key{printterms}{postheading}{%
+ \appto\newterm@styles{postheading={#1},}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\define@key{printterms}{sort}{\appto\newterm@styles{sort={#1},}}
+% \end{macrocode}
+% \begin{macrocode}
+\define@choicekey{printterms}{balance}[\val\nr]{true,false}[true]{%
+ \ifcase\nr\relax
+ \appto\newterm@styles{balance=true,}%
+ \or
+ \appto\newterm@styles{balance=false,}%
+ \fi
+}
+% \end{macrocode}
+%
+%\begin{macro}{\printterms}
+%\begin{definition}
+%\cs{printterms}[options]
+%\end{definition}
+% Print the list of terms
+% \begin{macrocode}
+\newcommand{\printterms}[1][]{%
+\bgroup
+% \end{macrocode}
+% Set default database.
+% \begin{macrocode}
+ \let\newterm@database\datagidx@defaultdatabase
+% \end{macrocode}
+% Initialise key list for style:
+% \begin{macrocode}
+ \let\newterm@styles\@empty
+% \end{macrocode}
+% Set options:
+% \begin{macrocode}
+ \setkeys{printterms}{#1}%
+% \end{macrocode}
+% Check if database exists.
+% \begin{macrocode}
+ \DTLifdbexists{\newterm@database}%
+ {%
+% \end{macrocode}
+% Provide user the means to access the current database name.
+% \begin{macrocode}
+ \edef\DTLgidxCurrentdb{\newterm@database}%
+% \end{macrocode}
+% Get the fields from datagidx:
+% \begin{macrocode}
+ \edef\do@getrow{\noexpand\dtlgetrowforvalue
+ {datagidx}%
+ {\dtlcolumnindex{datagidx}{Glossary}}%
+ {\newterm@database}%
+ }%
+ \do@getrow
+ \dtlgetentryfromcurrentrow
+ {\datagidx@title}%
+ {\dtlcolumnindex{datagidx}{Title}}%
+ \dtlgetentryfromcurrentrow
+ {\datagidx@heading}%
+ {\dtlcolumnindex{datagidx}{Heading}}%
+ \dtlgetentryfromcurrentrow
+ {\datagidx@postheading}%
+ {\dtlcolumnindex{datagidx}{PostHeading}}%
+ \dtlgetentryfromcurrentrow
+ {\datagidx@multicols}%
+ {\dtlcolumnindex{datagidx}{MultiCols}}%
+ \dtlgetentryfromcurrentrow
+ {\datagidx@sort}%
+ {\dtlcolumnindex{datagidx}{Sort}}%
+ \dtlgetentryfromcurrentrow
+ {\datagidx@style}%
+ {\dtlcolumnindex{datagidx}{Style}}%
+ \dtlgetentryfromcurrentrow
+ {\datagidx@showgroups}%
+ {\dtlcolumnindex{datagidx}{ShowGroups}}%
+% \end{macrocode}
+% Allow user to override style here.
+% \begin{macrocode}
+ \edef\dtl@do@setkeys{\noexpand\setkeys{newgloss}{\expandonce\newterm@styles}}%
+ \dtl@do@setkeys
+% \end{macrocode}
+% Do we need to use \env{multicols}?
+% \begin{macrocode}
+ \ifnum\datagidx@columns>1\relax
+ \edef\datagidx@prestart{%
+ \noexpand\begin{\datagidx@multicols}{\datagidx@columns}%
+ }%
+ \edef\datagidx@postend{%
+ \noexpand\end{\datagidx@multicols}%
+ }%
+ \else
+ \def\datagidx@prestart{}%
+ \def\datagidx@postend{}%
+ \fi
+ \let\@dtl@dbname\DTLgidxCurrentdb
+% \end{macrocode}
+% Set the style
+% \begin{macrocode}
+ \csuse{datagidxshowgroups\datagidx@showgroups}%
+ \datagidxsetstyle{\datagidx@style}%
+% \end{macrocode}
+% Now display the glossary/index:
+% \begin{macrocode}
+ \def\datagidx@labellist{}%
+ \datagidx@heading{\datagidx@title}%
+ \datagidx@postheading
+ \datagidx@do@sort
+ \datagidx@prestart
+ \datagidxstart
+ \let\DTLgidxName\datagidx@invert
+ \let\DTLgidxPlace\datagidx@invert
+ \let\DTLgidxSubject\datagidx@invert
+ \let\DTLgidxOffice\datagidx@invert
+ \DTLgidxForeachEntry
+ {%
+ \datagidxitem
+ }%
+ \datagidxend
+ \datagidx@postend
+ }%
+ {%
+% \end{macrocode}
+% Database doesn't exist.
+% \begin{macrocode}
+ \PackageError{datagidx}%
+ {Glossary/index data base `\newterm@database' doesn't exist}%
+ {%
+ You must define the glossary/index data base before you can
+ use it.%
+ }%
+ }%
+\egroup
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@getgroup}
+% Get the current group.
+% \begin{macrocode}
+\def\datagidx@getgroup#1#2\datagidx@endgetgroup{%
+ \dtl@setcharcode{#1}{\count@}%
+ \dtlifintclosedbetween{\count@}{48}{57}%
+ {%
+ \gdef\datagidxcurrentgroup{Numbers}%
+ }%
+ {%
+ \dtlifintclosedbetween{\count@}{97}{122}%
+ {%
+ \advance\count@ by -96\relax
+ \xdef\datagidxcurrentgroup{\@Alph\count@}%
+ }%
+ {%
+ \dtlifintclosedbetween{\count@}{65}{90}%
+ {%
+ \gdef\datagidxcurrentgroup{#1}%
+ }%
+ {%
+ \gdef\datagidxcurrentgroup{Symbols}%
+ }%
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\DTLgidxGroupHeaderTitle}
+% Produce the group title from the group label.
+% \begin{macrocode}
+\newcommand*{\DTLgidxGroupHeaderTitle}[1]{%
+ \ifcsdef{datagidx#1name}
+ {%
+ \csuse{datagidx#1name}%
+ }%
+ {%
+ #1%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\DTLgidxForeachEntry}
+%\begin{definition}
+%\cs{DTLgidxForeachEntry}\marg{body}
+%\end{definition}
+% Iterate through the current database, but only do \meta{body}
+% if there is a location or cross-reference.
+% \begin{macrocode}
+\newcommand{\DTLgidxForeachEntry}[1]{%
+ \def\datagidxprevgroup{}%
+ \edef\datagidx@doforeachentry{%
+ \noexpand\DTLforeach*{\DTLgidxCurrentdb}%
+ {\expandonce\DTLgidxAssignList}
+ }%
+ \datagidx@doforeachentry
+ {%
+% \end{macrocode}
+% Iterate through top-level entries.
+% \begin{macrocode}
+ \DTLifnull{\Parent}%
+ {%
+% \end{macrocode}
+% If there's no location, but there is a current location, then
+% document needs updating.
+% \begin{macrocode}
+ \DTLifnull\Location
+ {%
+ \DTLifnull\CurrentLocation
+ {%
+ }%
+ {%
+% \end{macrocode}
+% We have a current location but not a location.
+% \begin{macrocode}
+ \global\let\@datagidx@dorerun@warn\@data@rerun@warn
+ }%
+ }%
+ {%
+% \end{macrocode}
+% We have a location. Is it up-to-date?
+% \begin{macrocode}
+ \ifcsdef{datagidx@prev@loc@\Label}%
+ {%
+% \end{macrocode}
+% Current location was saved in the previous run. Has it changed?
+% \begin{macrocode}
+ \ifcsequal{datagidx@prev@loc@\Label}{CurrentLocation}%
+ {}%
+ {%
+ \global\let\@datagidx@dorerun@warn\@data@rerun@warn
+ }%
+ }%
+ {%
+% \end{macrocode}
+% Current location wasn't saved last run, so rerun required.
+% \begin{macrocode}
+ \global\let\@datagidx@dorerun@warn\@data@rerun@warn
+ }%
+ }%
+ \datagidx@doifdisplayed
+ {%
+% \end{macrocode}
+% Write current location to file to compare current and previous
+% lists. (Can't compare \cs{Location} with \cs{CurrentLocation} as
+% there may be locations occurring across a page boundary.)
+% \begin{macrocode}
+ \edef\datagidx@dowrite{%
+ \noexpand\protected@write\noexpand\@auxout{}%
+ {%
+ \string\datagidx@save@loc{\Label}{\CurrentLocation}%
+ }%
+ }%
+ \datagidx@dowrite
+% \end{macrocode}
+% Initialise level.
+% \begin{macrocode}
+ \datagidx@level=1\relax
+ \expandafter\datagidx@getgroup\Sort{}\datagidx@endgetgroup
+ #1%
+ \global\let\datagidxprevgroup\datagidxcurrentgroup
+ }%
+ }%
+ {}%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@doifdisplayed}
+%\begin{definition}
+%\cs{datagidx@doifdisplayed}\marg{body}
+%\end{definition}
+% Do \meta{body} if entry should appear in the glossary/index.
+% \cs{Location}, \cs{See} and \cs{SeeAlso} must be set before use.
+% \begin{macrocode}
+\newcommand{\datagidx@doifdisplayed}[1]{%
+ \DTLifnull{\Location}%
+ {%
+ \DTLifnull{\See}
+ {%
+ \DTLifnull{\SeeAlso}{}%
+ {%
+ #1%
+ }%
+ }%
+ {%
+% \end{macrocode}
+% "See" is not null, but have any of the cross-referenced items been
+% used?
+% \begin{macrocode}
+ \@for\dtl@thislabel:=\See\do
+ {%
+% \end{macrocode}
+% Does the cross-referenced term exist?
+% \begin{macrocode}
+ \iftermexists{\dtl@thislabel}%
+ {%
+% \end{macrocode}
+% Has it been used?
+% \begin{macrocode}
+ \ifentryused{\dtl@thislabel}%
+ {%
+ #1%
+% \end{macrocode}
+% Break out of loop.
+% \begin{macrocode}
+ \@endfortrue
+ }%
+ {}%
+ }%
+ {%
+ }%
+ }%
+ }%
+ }%
+ {%
+ #1%
+ }%
+}%
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\datagidx@level}
+% Keep track of current level
+% \begin{macrocode}
+\newcount\datagidx@level
+% \end{macrocode}
+%\end{macro}
+%\iffalse
+% \begin{macrocode}
+%</datagidx.sty>
+% \end{macrocode}
+%\fi
+%\iffalse
+% \begin{macrocode}
%<*databib.sty>
% \end{macrocode}
%\fi
@@ -11748,7 +18555,7 @@ datatool.dtx
%\section{Package Declaration}
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{databib}[2012/09/25 v2.11 (NLCT)]
+\ProvidesPackage{databib}[2013/01/15 v2.13 (NLCT)]
% \end{macrocode}
% Load required packages:
% \begin{macrocode}
@@ -14455,7 +21262,7 @@ already exists}{}}}}
% Declare package:
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{databar}[2012/09/25 v2.11 (NLCT)]
+\ProvidesPackage{databar}[2013/01/15 v2.13 (NLCT)]
% \end{macrocode}
% Require \sty{xkeyval} package
% \begin{macrocode}
@@ -15756,7 +22563,7 @@ already exists}{}}}}
% Declare package:
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{datapie}[2012/09/25 v2.11 (NLCT)]
+\ProvidesPackage{datapie}[2013/01/15 v2.13 (NLCT)]
% \end{macrocode}
% Require \sty{xkeyval} package
% \begin{macrocode}
@@ -16434,7 +23241,7 @@ Try #2-#1 instead of #1-#2}%
% Declare package:
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{dataplot}[2012/09/25 v2.11 (NLCT)]
+\ProvidesPackage{dataplot}[2013/01/15 v2.13 (NLCT)]
% \end{macrocode}
% Required packages
% \begin{macrocode}
@@ -17863,7 +24670,7 @@ east,southeast,south,southwest,west,northwest}[northeast]{%
% Package identification:
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{person}[2012/09/25 v2.11 (NLCT)]
+\ProvidesPackage{person}[2013/01/15 v2.13 (NLCT)]
% \end{macrocode}
% Requires the \sty{ifthen} package.
% \begin{macrocode}
diff --git a/Master/texmf-dist/source/latex/datatool/datatool.ins b/Master/texmf-dist/source/latex/datatool/datatool.ins
index 54ea5c65490..bb4789b5e04 100644
--- a/Master/texmf-dist/source/latex/datatool/datatool.ins
+++ b/Master/texmf-dist/source/latex/datatool/datatool.ins
@@ -1,10 +1,10 @@
-% datatool.ins generated using makedtx version 0.94b 2012/10/6 20:31
+% datatool.ins generated using makedtx version 0.94b 2013/1/15 15:04
\input docstrip
\preamble
datatool.dtx
- Copyright 2012 Nicola Talbot
+ Copyright 2013 Nicola Talbot
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
@@ -18,7 +18,7 @@
The Current Maintainer of this work is Nicola Talbot.
- This work consists of the files datatool.dtx and datatool.ins and the derived files datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.sty, databib.bst.
+ This work consists of the files datatool.dtx and datatool.ins and the derived files datatool-base.sty, datatool-fp.sty, datatool-pgfmath.sty, datatool.sty, datagidx.sty, databib.sty, databar.sty, datapie.sty, dataplot.sty, person.sty, databib.bst.
\endpreamble
@@ -32,6 +32,8 @@
\usepostamble\defaultpostamble\from{datatool.dtx}{datatool-pgfmath.sty,package}}
\file{datatool.sty}{\usepreamble\defaultpreamble
\usepostamble\defaultpostamble\from{datatool.dtx}{datatool.sty,package}}
+\file{datagidx.sty}{\usepreamble\defaultpreamble
+\usepostamble\defaultpostamble\from{datatool.dtx}{datagidx.sty,package}}
\file{databib.sty}{\usepreamble\defaultpreamble
\usepostamble\defaultpostamble\from{datatool.dtx}{databib.sty,package}}
\file{databar.sty}{\usepreamble\defaultpreamble