# imakeidx \see clash with \backmatter

I wonder if someone could explain what's happening in the following MWE, where the use of \backmatter will make disappear the index crossed-refs (\see and \seealso commands); try uncommenting \backmatter and you will see. I never had this problem with ye old indexing packages, but now that I am enjoying imakeidx, it would be good to solve this. Thanks in advance!

%!TEX TS-program = xelatex
%!TEX encoding = UTF-8 Unicode

\documentclass{book}
\usepackage{imakeidx}
\makeindex

\begin{document}
bla bla \index{bla} bla

\newpage
...relativity\index{relativity} ... Einstein\index{Einstein, Albert}...bla bla \index{bla} bla bla more bla bla \index{bla} bla

And this is the end of the story.

%\backmatter
\index{scientist|see{Einstein, Albert}}

\printindex

\end{document}

• Indeed it does, thank you. But I'm just wondering what would be a way to preserve the current document structure. I guess it must be a little clash between the definition of \backmatter and something in imakeidx, and I guess it must also be very simple to spot for those who know the innards of imakeidx. – Juan del Acebo Mar 5 '15 at 17:10
• Juan del Acebo: I try to figure out, but our top-rep user egreg is the author and maintainer of imakeidx, perhaps he knows more – user31729 Mar 5 '15 at 17:11
• Add a word between \backmatter and \index{scientist...} and it will work. This has to do with the delayed writing: in your example there's no page the index entry can refer to. – egreg Mar 5 '15 at 17:33
• Thanks @egreg for trying. It does make the trick, but the problem with adding a word (I tried adding \textit{ }) is that a new unwanted page is generated before the index. – Juan del Acebo Mar 5 '15 at 17:54
• @JuandelAcebo What's the reason for adding \index after \backmatter without any accompanying text? I see none. Just put \index before \backmatter – egreg Mar 5 '15 at 18:40

The writing of an index entry in the .idx file happens when the page where the \index command eventually appears.

In order to be able to compile the index on the fly, that is using MakeIndex for transforming the .idx file into the .ind file containing LaTeX instructions, imakeidx closes the .idx file when LaTeX encounters \printindex.

In your example, \backmatter issues \cleardoublepage, so TeX is on a fresh page. The command \index{scientist|see{Einstein, Albert}} doesn't produce any box on this page. After this, \printindex closes the .idx file, so the \index command has had no chance of being written on this file, because no page has been shipped out since the command has been processed.

If you want to add “see” entries in a single place, the solution is to put them before \backmatter, or else to disable the automatic run of MakeIndex with the option noautomatic to imakeidx (which requires manually running MakeIndex and then rerunning LaTeX).

I'd probably put them after \begin{document} or in an external file to be \input after \begin{document}.

Just as an exercise, but don't take it too seriously, here's a way for adding the index cross references just before \printindex.

\documentclass{book}
\usepackage{imakeidx}
\usepackage{etoolbox}

\makeindex

\makeatletter
\newenvironment{crossreferences}
{\patchcmd{\protected@write}{\let\thepage\relax}{}{}{}%
\patchcmd{\protected@write}{\write}{\immediate\write}{}{}}
{}{}
\makeatother

\begin{document}
bla bla \index{bla} bla

\newpage
...relativity\index{relativity} ... Einstein\index{Einstein, Albert}...bla bla \index{bla} bla bla more bla bla \index{bla} bla

And this is the end of the story.

\backmatter
\begin{crossreferences}
\index{scientist|see{Einstein, Albert}}
\end{crossreferences}

\printindex

\end{document}


Inside the crossreferences environment, \write is changed into \immediate\write and the setting that \protected@write does to \thepage is removed. Don't add “real” index entries in the environment (it wouldn't make much sense anyway).