Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to sort the index entries independent of case.

Initially I was getting (code provided in MWE) the image on the left. So, that seemed like an easy fix: just apply \lowercase (uncomment the \def in the MWE) but that yields the image on the right:

enter image description here enter image description here

So, how do I get these sorted alphabetically, and get the two entries for zero to be displayed as a sub-entries under a single heading?

Failed Attempts:

  1. I thought this was an explansion issue, so I tried to use

    \edef\LowerCaseWord{\lowercase{#2}}
    \index{\LowerCaseWord!#1}
    

    but this also yielded results identical to the image on the right.

  2. Since a wise member here (who I think no longer wants to be associated with this comment :-)) once alluded that a few carefully placed \expandafters should fix anything I tried this and it also does not change the output:

    \edef\LowerCaseWord{\lowercase{#2}}
    \expandafter\index{\LowerCaseWord!#1}
    

Code:

%\def\UseLowercase{}% Uncomment to use lowercase

\documentclass{article}
\usepackage{imakeidx}

\ifdefined\UseLowercase% Select whether we use lowercase or not
    \newcommand{\IndexTitle}{Index (lowercase)}%
\else
    \newcommand{\IndexTitle}{Index}%
    \renewcommand{\lowercase}[1]{#1}%
\fi

\newcommand*{\AddIndexEntry}[2]{%
    % #1 = indexed term, #2 = word to index this under
    \par\noindent
    Indexing: #2
    \index{\lowercase{#2}!#1}
}%

\makeindex[title={\IndexTitle},columns=1]

\begin{document}
    \AddIndexEntry{aardvark}{aardvark}
    \AddIndexEntry{Saved by Zero}{Saved}
    \AddIndexEntry{Saved by Zero}{Zero}
    \AddIndexEntry{zero}{zero}
    \printindex
\end{document}
share|improve this question
    
\lowercase isn't expandable, so no amount of \expandafter can do. But there's something that can be done. Be patient. :) –  egreg Apr 12 '12 at 19:22
add comment

1 Answer

up vote 10 down vote accepted

I'd say that

\newcommand*{\AddIndexEntry}[2]{%
    % #1 = indexed term, #2 = word to index this under
    \par\noindent
    \lowercase{\def\temp{#2}}%
    Indexing: #2%
    \expandafter\index\expandafter{\temp!#1}%
}

should be what you need.

How does \lowercase works? It sends its argument to a further processor (it's not a macro, so it doesn't its work in TeX's “mouth”); the token list is converted using the \lccode table: each character token that hasn't a zero \lccode is converted to its lowercase correspondent, but symbolic tokens such as \def or \temp are untouched. The token list so obtained is put back in the input as if it had been there from the beginning. There's no expansion during this process: so if TeX finds \lowercase{\def\temp{Xyz}} when it's executing things, then it "waits" a bit, processes the token list as explained, then it processes

\def\temp{xyz}

and goes along.


In case you have more than one index, you can use a modified form:

\documentclass{article}
\usepackage{imakeidx}

\newcommand*{\AddIndexEntry}[3][]{%
  % #1 = indexed term, #2 = word to index this under
  \par\noindent
  \lowercase{\def\temp{#3}}%
  Indexing: #3%
  \if!#1!
    \expandafter\index\expandafter{\temp!#2}%
  \else
    \expandafter\indexopt\expandafter{\temp!#2}{#1}
  \fi
}
\newcommand{\indexopt}[2]{\index[#2]{#1}}

\makeindex
\makeindex[name=Name,title=Title,columns=1]

\begin{document}

\AddIndexEntry{aardvark}{aardvark}
\AddIndexEntry{Saved by Zero}{Saved}
\AddIndexEntry{Saved by Zero}{Zero}
\AddIndexEntry[Name]{zero}{zero}

\printindex
\printindex[Name]

\end{document}

The \indexopt macro takes care of switching the arguments, so that the \expandafter doesn't need to jump over the optional argument to \index.

share|improve this answer
    
Well, it definitely does what I need, but have to ask: what does it mean to apply a macro like \lowercase to a \def? Don't think I have seen that kind of voodoo magic before. –  Peter Grill Apr 12 '12 at 19:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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