I have the following minimal(ish) example. This is for a technical book with lots of code samples and lots of code-keywords-appearing-in-running-text. So I have the following goals:
- A macro
\code{foo}
for typesetting code-keywords-in-running-text. I use thelistings
package for typesetting code throughout. I also use theunderscore
package so I don't have to escape underscores in code. - I use the
hyperref
package for cross-references, plus plenty of code keywords appearing in section titles; so I use\texorpdfstring
in the definition of\code
. - Two indices: a main "Index" for English words and concepts, and a second "Index of code samples". I have heard that the
imakeidx
package is the most standard choice for this, so I'm using it. I'm open to alternatives if they can fix my problem. - Many, complicated, index terms. Some terms must be typeset with
\code{foo}
. Some must be secondary entries, as in, "iterator
,std::vector::
: seevector::iterator
."
mce.tex
\documentclass[ebook,10pt,oneside,final]{memoir}
\usepackage{imakeidx}
\makeindex[name=mce,intoc,columns=2]
\makeindex[name=code,intoc,columns=2,name=code,title=Index of code samples]
\usepackage[final]{listings}
\usepackage{hyperref}
\usepackage{underscore}
\newcommand{\code}[1]{\texorpdfstring{\mbox{\lstinline[basicstyle=\ttfamily]`#1`}}{#1}}
\newcommand{\codeblockdefines}[1]{\index[code]{#1@\code{#1}}} % for example, \codeblockdefines{list_of_int}
\newcommand{\codeindex}[1]{\index{#1@\code{#1}}} % for example, \codeindex{const_iterator}
\newcommand{\codeindexstd}[1]{\index{namespace std@\code{namespace std}!#1@\code{#1}}} % for example, \codeindexstd{vector}
\begin{document}
\tableofcontents
Here's an example of using \code{std::vector}.
\codeindexstd{vector}
\codeindex{std::vector}
\codeblockdefines{vector}
\index{std@\code{std}|see {namespace std@\code{namespace std}}}
\printindex[mce]
\printindex[code]
\end{document}
The problem I'm seeing is that \code
and maybe some other macros are getting expanded in the .idx files. When I cat these files I see this:
mce.idx
\indexentry{namespace std@\unhbox \voidb@x \hbox {\lstinline [basicstyle=\ttfamily ]`namespace std`}!vector@\unhbox \voidb@x \hbox {\lstinline [basicstyle=\ttfamily ]`vector`}|hyperpage}{1}
\indexentry{std::vector@\unhbox \voidb@x \hbox {\lstinline [basicstyle=\ttfamily ]`std::vector`}|hyperpage}{1}
\indexentry{std@\code{std}|hyperindexformat{\see {namespace std@\code{namespace std}}}}{1}
code.idx
\indexentry{vector@\unhbox \voidb@x \hbox {\lstinline [basicstyle=\ttfamily ]`vector`}|hyperpage}{1}
How can I make \index
and the rest of my convenience macros (\codeblockdefines
, \codeindex
, \codeindexstd
) do what I want?
imakeidx
before loadinghyperref
.\codeindex
and\codeindexstd
point to a non existent index.