2

When I build the following, the index ends up with two of the ZZZ item and one of them sorts before the AAA item. How do I make the index see and operate on the expanded value of the macro rather than the un-expanded form?

\title{Test}
\author{Me}
\documentclass[12pt]{article}

\usepackage{datatool}
\usepackage{imakeidx}

\makeindex[intoc]

\DTLgnewdb{MyDB}
\newcommand{\NameLabel}[2]{
  \DTLnewrow{MyDB}
  \DTLnewdbentry{MyDB}{label}{#1}
  \DTLnewdbentry{MyDB}{name}{#2}
}
\newcommand{\GetName}[1]{%
  \DTLforeach*[\DTLiseq{\caLabel}{#1}]{MyDB}{\caLabel=label,\caName=name}{\caName\dtlbreak}%
}

\newenvironment{MyRef}[1]{
  \index{\protect\GetName{#1}}   %%%% <<<< This line
  \item[\GetName{#1}:]
}{
}

\begin{document}

\section{One}
\index{AAA Sorts First}
\index{ZZZ Sorts Last}

\NameLabel{TheThing}{ZZZ Sorts Last}

\begin{description}
  \begin{MyRef}{TheThing} lorem ipsum \end{MyRef}
\end{description}

\printindex

\end{document}

I think this has something to do with things getting sorted before they are fully epxanded. If I look at test.idx, I see:

\indexentry{AAA Sorts First}{1}
\indexentry{ZZZ Sorts Last}{1}
\indexentry{\GetName {TheThing}}{1}

I've tried a bunch of different permutations to try and get the macro expansion to happen before the value gets to the indexing, but they all either don't work (broken build) or have no effect.

NOTE: This is a rather stripped version of the real thing which might explain some oddities.

4
  • Welcome to TeX.SE!
    – Mensch
    Dec 2, 2021 at 21:22
  • the command is not expandable you could use \index{ZZ@\protect\GetName{#1}} to make it sort as ZZ if you know what text you need at that point Dec 2, 2021 at 22:32
  • No joy. The text of the index item needs to be what \GetName explains to and I can't know at this point where to sort it so I can't add stuff. Furthermore, the fact that the lookup and the literal value (that show the same in the index) end up being different clusters was the thing that got me digging into this and is really what I started out trying to avoid.
    – BCS
    Dec 2, 2021 at 22:48
  • What dictates what is expandable? Is it something in my control? If so, how do I make it expandable?
    – BCS
    Dec 2, 2021 at 22:49

1 Answer 1

2

Your \GetName macro isn't expandable. Instead, extract the name corresponding to some label first by storing it in a macro. Then you can pass that along to \index and/or reuse it elsewhere.

The example code below does that thanks to

\DTLgetvalueforkey
  {<cmd>}% Macro to store the result in
  {<key>}% Key (column) to extract content from
  {<db>}% Database to search
  {<ref key>}% Reference key (column) to search for content
  {<ref val>}% Reference value to find in <ref key>

rather than manually processing every element via \DTLforeach.

\documentclass{article}

\usepackage{datatool}
\usepackage{imakeidx}

\makeindex[intoc]

\DTLgnewdb{MyDB}
\newcommand{\NameLabel}[2]{%
  \DTLnewrow{MyDB}%
  \DTLnewdbentry{MyDB}{label}{#1}%
  \DTLnewdbentry{MyDB}{name}{#2}%
}
\newcommand{\GetName}[1]{%
  \DTLgetvalueforkey{\LabelName}{name}{MyDB}{label}{#1}%
}

\newenvironment{MyRef}[1]{%
  \GetName{#1}%
  \item[\LabelName:]\index{\LabelName}%
}{%
}

\begin{document}

\section{One}
\index{AAA Sorts First}
\index{ZZZ Sorts Last}

\NameLabel{TheThing}{ZZZ Sorts Last}

\begin{description}
  \begin{MyRef}{TheThing} lorem ipsum \end{MyRef}
\end{description}

\printindex

\end{document}
1
  • I could have sworn I looked for that functionality in the docs...
    – BCS
    Dec 3, 2021 at 0:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .