6

I came across datagidx package, which is part of the datatool bundle, the killing feature of this package is that you can use it independently, not relying on external indexing applications, e.g., xindy or makeidx. One more feature, is that you can use it to address index, glossary (definitions), acronyms (abbreviations), notations, and it can be further extended to include customized databases as well, all by one package. I tend to keep the databases separate in different tex files and use \input{<filenamen>} in the main file to call for these databases.
Sometimes, one would like to do different things with different keywords in the text, the following possibilities might be in need:

  • some words to appear in glossary + index
  • some words to appear in acronyms + index
  • some words to appear in glossary + acronyms + index

Question:
How to address this need for these different possibilities using one command at a time? keeping in mind, and to make life easier, one would like to use always the short version of the entry in the text flow (to avoid typos as much as possible), while displaying the long version in the target list.

Notes:
Please Make sure to have at least version 2.13 of datatool bundle which will load datagidx

  • The xargs and xparse packages allow for complex macro construction. – jon Jun 10 '13 at 20:16
12

The example below defines some commands that allow you to add entries to multiple databases. You can then use the example command \xgls instead of \gls and it will index the entries for each of the databases. So if pdf is in the glossary, acronym and index database, \xgls{pdf} will add a location to each database, whereas if html is only in the acronym and index database, \xgls{html} will only add locations to those two database.

Edit: \newacronymentry has an extra argument to indicate the description to be used in the glossary.

\documentclass{article}

\usepackage{datagidx}
\usepackage[colorlinks]{hyperref}

\newgidx{glossary}{Glossary}
\newgidx{acronyms}{Acronyms}
\newgidx{index}{Index}

% Syntax: \newacronym[options]{short}{long}
% Defines an acronym that also has an entry in the index

\newcommand{\newacronym}[3][]{%
  \newterm[database={index},sort={#3},label={index.#2}]%
   {\MakeTextUppercase{#2}}%
  \newacro[database={acronyms},label={acronym.#2},#1]%
   {\MakeTextUppercase{#2}}{#3}%
}

% Syntax: \newentry[options]{label}{name}
% Defines a glossary entry that also appears in the index

\newcommand{\newentry}[3][]{%
  \newterm[database={glossary},label={glossary.#2},#1]{#3}%
  \newterm[database={index},label={index.#2},#1]{#3}%
}

% Syntax: \newacronymentry[options]{short}{long}{description}
% Like \newacronym but also adds the entry to the glossary

\newcommand{\newacronymentry}[4][]{%
  \newterm[database={glossary},label={glossary.#2},%
    sort={#2},#1,description={#4}]%
    {\MakeTextUppercase{#2}}%
  \newterm[database={index},sort={#3},label={index.#2}]%
    {\MakeTextUppercase{#2}}%
  \newacro[database={acronyms},label={acronym.#2},#1]%
    {\MakeTextUppercase{#2}}{#3}%
}

% Syntax: \xgls{label}
% If acronym.#1 exists use that and index
% Otherwise if glossary.#1 exists, use that and index the others.
% Otherwise if index.#1 use index.#1
% If none of the above, just do \gls{label}

\newcommand{\xgls}[1]{%
  \iftermexists{acronym.#1}%
  {%
    \acr{acronym.#1}%
    \iftermexists{glossary.#1}%
    {\glsadd{glossary.#1}}%
    {}%
    \iftermexists{index.#1}%
    {\glsadd{index.#1}}%
    {}%
  }%
  {%
    \iftermexists{glossary.#1}%
    {%
      \gls{glossary.#1}%
      \iftermexists{index.#1}%
      {\glsadd{index.#1}}%
      {}%
    }%
    {%
      \iftermexists{index.#1}%
      {\gls{index.#1}}%
      {%
        \gls{#1}%
      }%
    }%
  }%
}

% Define some acronyms

\newacronym{html}{hypertext markup language}
\newacronym{csv}{comma-separated variable}

% Define some glossary entries

\newentry[description={A typesetting language},sort={TeX}]{tex}{\TeX}
\newentry[description={A format of \TeX},sort={LaTeX}]{latex}{\LaTeX}

% Define some acronyms that also go in the glossary

\newacronymentry{pdf}{portable document format}{A file format}

% Define a term that isn't an acronym or a glossary entry

\newterm[database=index]{sample}

\begin{document}

First use: \xgls{html}.
First use: \xgls{csv}.
First use: \xgls{pdf}.
Reference \xgls{tex}.
Reference \xgls{latex}.
Reference the \xgls{sample} term.

\clearpage

Second use: \xgls{html}.
Second use: \xgls{csv}.
Second use: \xgls{pdf}.
Reference \xgls{tex}.
Reference \xgls{latex}.
Reference the \xgls{sample} term.

\printterms[database=acronyms,columns=1,location=hide]

\printterms[database=glossary,columns=1,location=hide]

\printterms[database=index,columns=1]

\end{document}

Page 1:

Image of first page

Page 2:

Image of second page

Edit 2:

If you're undecided as to whether you want to use datagidx or glossaries, you could try the following approach:

First we have two files, which I'm going to call test-datagidx.tex and test-glossaries.tex. They both define the same control sequences, but the first uses the datagidx package and the second uses the glossaries package. If you stick to using those commands in your document, it should be possible to switch between the two packages. Edit: However, I strongly recommend that you stick to using glossaries as it's much more efficient than datagidx. Although the two packages do similar things, they have a very different internal structure, which means they aren't compatible, so there are some things you can do in one but not the other so stick to just using the test-glossaries.tex code below, if possible.

Here's the first file test-datagidx.tex:

\usepackage{etoolbox}
\usepackage{datagidx}
\usepackage[colorlinks]{hyperref}

\newgidx{glossary}{Glossary}
\newgidx{acronyms}{Acronyms}
\newgidx{index}{Index}

% Syntax: \newacronymterm[options]{short}{long}
% Defines an acronym that also has an entry in the index

\newcommand{\newacronymterm}[3][]{%
  \newterm[database={index},sort={#3},label={index.#2},#1]%
   {\MakeTextUppercase{#2}}%
  \newacro[database={acronyms},label={acronym.#2},#1]%
   {\MakeTextUppercase{#2}}{#3}%
}

% Syntax: \newentry[options]{label}{name}
% Defines a glossary entry that also appears in the index

\newcommand{\newentry}[3][]{%
  \newterm[database={glossary},label={glossary.#2},#1]{#3}%
  \newterm[database={index},label={index.#2},#1]{#3}%
}

% Syntax: \newacronymentry[options]{short}{long}{description}
% Like \newacronym but also adds the entry to the glossary

\newcommand{\newacronymentry}[4][]{%
  \newterm[database={glossary},label={glossary.#2},%
    sort={#2},#1,description={#4}]%
    {\MakeTextUppercase{#2}}%
  \newterm[database={index},sort={#3},label={index.#2},#1]%
    {\MakeTextUppercase{#2}}%
  \newacro[database={acronyms},label={acronym.#2},#1]%
    {\MakeTextUppercase{#2}}{#3}%
}

% Just an index entry
\newcommand{\newindexentry}[2][]{%
   \newterm[database=index,label={index.#2},#1]{#2}%
}

% Syntax: \xgls[format]{label}
% If acronym.#1 exists use that and index
% Otherwise if glossary.#1 exists, use that and index the others.
% Otherwise if index.#1 use index.#1
% If none of the above, just do \gls{label}

\newcommand{\xgls}[2][]{%
  \ifstrempty{#1}{\def\fmtopt{}}{\def\fmtopt{[#1]}}%
  \iftermexists{acronym.#2}%
  {%
    \acr{acronym.#2}%
    \iftermexists{glossary.#2}%
    {\glsadd{glossary.#2}}%
    {}%
    \iftermexists{index.#2}%
    {\expandafter\glsadd\expandafter{\fmtopt index.#2}}%
    {}%
  }%
  {%
    \iftermexists{glossary.#2}%
    {%
      \gls{glossary.#2}%
      \iftermexists{index.#2}%
      {\glsadd{index.#2}}%
      {}%
    }%
    {%
      \iftermexists{index.#2}%
      {\expandafter\gls\expandafter{\fmtopt index.#2}}%
      {%
        \expandafter\gls\expandafter{\fmtopt #2}%
      }%
    }%
  }%
}


\newcommand{\PrintAcronyms}{%
  \printterms[database=acronyms,columns=1,location=hide]%
}

\newcommand{\PrintGlossary}{%
   \printterms[database=glossary,columns=1,location=hide]%
}

\newcommand{\PrintIndex}{%
   \printterms[database=index,showgroups]%
}

Here's the second file (test-glossaries.tex):

\usepackage{etoolbox}
\usepackage{textcase}
\usepackage[colorlinks]{hyperref}
\usepackage[acronym,xindy]{glossaries}
\usepackage{glossary-mcols}

\newglossary[ilg]{index}{ind}{idx}{\indexname}%

\makeglossaries

\SetCustomStyle
\renewcommand{\acrfullformat}[2]{#1 (\MakeTextUppercase{#2})}

% Syntax: \newacronym[options]{short}{long}
% Defines an acronym that also has an entry in the index

\newcommand{\newacronymterm}[3][]{%
  \newacronym[name={\MakeTextUppercase{#2}},#1]{acronym.#2}{#2}{#3}%
  \newglossaryentry{index.#2}{name={\MakeTextUppercase{#2}},%
  type={index},sort={#2},#1,description={\nopostdesc}}%
}

% Syntax: \newentry[options]{label}{name}
% Defines a glossary entry that also appears in the index

\newcommand{\newentry}[3][]{%
  \newglossaryentry{glossary.#2}{name={#3},#1}%
  \newglossaryentry{index.#2}{name={#3},type={index},%
  #1,description={\nopostdesc}}%
}

% Syntax: \newacronymentry[options]{short}{long}{description}
% Like \newacronym but also adds the entry to the glossary

\newcommand{\newacronymentry}[4][]{%
  \newglossaryentry{glossary.#2}{name={\MakeTextUppercase{#2}},%
    sort={#2},description={#4},#1}%
  \newglossaryentry{index.#2}{name={\MakeTextUppercase{#2}},type={index},%
  #1,description={\nopostdesc}}%
  \newacronym[name={\MakeTextUppercase{#2}},#1]{acronym.#2}{#2}{#3}%
}

% Just an index entry
\newcommand{\newindexentry}[2][]{%
  \newglossaryentry{index.#2}{name={#2},%
  type={index},sort={#2},#1,description={\nopostdesc}}%
}

% Syntax: \xgls[format]{label}
% If acronym.#1 exists use that and index
% Otherwise if glossary.#1 exists, use that and index the others.
% Otherwise if index.#1 use index.#1
% If none of the above, just do \gls{label}

\newcommand{\xgls}[2][]{%
  \ifglsentryexists{acronym.#2}%
  {%
    \ifglsentryexists{glossary.#2}%
    {\glsadd{glossary.#2}}%
    {}%
    \ifglsentryexists{index.#2}%
    {\glsadd[#1]{index.#2}}%
    {}%
    \gls[#1]{acronym.#2}%
  }%
  {%
    \ifglsentryexists{glossary.#2}%
    {%
      \ifglsentryexists{index.#2}%
      {\glsadd{index.#2}}%
      {}%
      \gls{glossary.#2}%
    }%
    {%
      \ifglsentryexists{index.#2}%
      {\gls[#1]{index.#2}}%
      {%
        \gls[#1]{#2}%
      }%
    }%
  }%
}

\glsnogroupskiptrue

\newcommand{\PrintAcronyms}{%
  \printglossary[type=\acronymtype,nonumberlist]
}

\newcommand{\PrintGlossary}{%
  \printglossary[type=main,nonumberlist]
}

\newcommand{\PrintIndex}{%
  \bgroup
   \glsnogroupskipfalse
   \renewcommand{\glsnamefont}[1]{\textmd{##1}}%
  \printglossary[type=index,style=mcolindexgroup]
  \egroup
}

Now we have a test document, called test.tex:

\documentclass{article}

\input{test-datagidx}% use datagidx
%\input{test-glossaries}% use glossaries

% Define some acronyms

\newacronymterm{html}{hypertext markup language}
\newacronymterm{csv}{comma-separated variable}

% Define some glossary entries

\newentry[description={A typesetting language},sort={TeX}]{tex}{\TeX}
\newentry[description={A format of \TeX},sort={LaTeX}]{latex}{\LaTeX}

% Define some acronyms that also go in the glossary

\newacronymentry{pdf}{portable document format}{A file format}

% Define some terms that aren't an acronym or a glossary entry

\newindexentry{sample}
\newindexentry{comma}
\newindexentry{cat}

\begin{document}

First use: \xgls{html}.
First use: \xgls{csv}.
First use: \xgls{pdf}.
Reference \xgls{tex}.
Reference \xgls{latex}.
Reference the \xgls{sample} term.
Reference the \xgls{comma} term.
Reference the \xgls{cat} term.

\clearpage

Second use: \xgls{html}.
Second use: \xgls{csv}.
Second use: \xgls{pdf}.
Reference \xgls{tex}.
Reference \xgls{latex}.
Reference the \xgls{sample} term.
Reference the \xgls{comma} term.
Reference the \xgls{cat} term.

\PrintAcronyms
\PrintGlossary
\PrintIndex
\end{document}

This uses datagidx if you have \input{test-datagidx} and it uses glossaries if you have \input{test-glossaries}. (Don't uncomment both at the same time!) With the first approach you need three pdflatex calls. With the second approach you need pdflatex+makeglossaries+pdflatex+pdflatex. When you switch between the two, make sure you delete the .aux file before recompiling.

First approach (\input{test-datagidx}):

Page 1:

Image of page 1

Page 2:

Image of page 2

Second approach (\input{test-glossaries}):

Page 1:

Image of page 1

Page 2:

Image of page 2

There are slight differences in the glossary/acronym/index styles. These can be tweaked depending on how you want the actual output to appear.

Edit: You can adapt the code of \xgls to define analogous commands for variants, such as upper case, plurals, short or long forms. Just change \gls in the definition to the appropriate command. For example, to define \xglspl for the glossaries version:

\newcommand{\xglspl}[2][]{%
  \ifglsentryexists{acronym.#2}%
  {%
    \ifglsentryexists{glossary.#2}%
    {\glsadd{glossary.#2}}%
    {}%
    \ifglsentryexists{index.#2}%
    {\glsadd[#1]{index.#2}}%
    {}%
    \glspl[#1]{acronym.#2}%
  }%
  {%
    \ifglsentryexists{glossary.#2}%
    {%
      \ifglsentryexists{index.#2}%
      {\glsadd{index.#2}}%
      {}%
      \glspl{glossary.#2}%
    }%
    {%
      \ifglsentryexists{index.#2}%
      {\glspl[#1]{index.#2}}%
      {%
        \glspl[#1]{#2}%
      }%
    }%
  }%
}

Note that with the glossaries version, with the above definition you can still have the final optional argument that follows the mandatory argument, but you can't have this for the datagidx version, which is another reason for just sticking with glossaries.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.