# Why .ind empty (with error message from xindy although makeindex is used) when index command is inside an align environment?

When compiling the following MWE with texi2dvi -p, the second \index{} command fails with the error message ERROR: CHAR: index 0 should be less than the length of the string (seems like this is because of xindy although imakeidx has default makeindex). The resulting PDF looks fine (but it isn't; see 'Background' below), but the .ind file is empty.

What am I doing wrong?

\documentclass{scrartcl}
\usepackage{bm}
\usepackage{amsmath}
\usepackage{filecontents}
\begin{filecontents*}{makeindexstyle.ist}
\end{filecontents*}
\usepackage{imakeidx}
\makeindex[intoc, options=-s makeindexstyle.ist]

\begin{document}
\index{$\bm{X}$}% works well
\begin{align}
\Pi(\bm{u})=\prod_{j=1}^du_j,\quad\bm{u}\in[0,1]^d,\label{def:pi}\index{$\Pi$}% produces "ERROR: CHAR: index 0 should be less than the length of the string" and "/usr/local/bin/texi2dvi: texindy failed"
\end{align}
\printindex
\end{document}


Background: I have a large document with tons of \index{} commands which used to work well when compiling with texi2dvi -p (even when having complicated symbols as arguments) . Due to another issue, I had to upgrade to a newer version of texi2dvi from https://ftp.gnu.org/gnu/texinfo/ and I then realized (see also my inline comment above) that texindy is used instead of makeindex (although makeindex is the default for imakeidx). Apart from the error, the whole index looks fine, shows the right page numbers, but the hyperlinks (not included in the above MWE) lead to wrong pages. I am (also) wondering whether this has to do with the incompatibility of xindy (which I don't understand why it is used instead of 'makeindex') and hyperref in general, or the above error in particular.

This is on macOS 10.14.1 with pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018). The compilation with texi2dvi -p is done after setting PDFLATEX=pdflatex --shell-escape -synctex=1 -file-line-error.

ERROR: CHAR: index 0 should be less than the length of the string

This error message occurs when Xindy encounters an empty sort value. In the case of \index{$\Pi$} the actual value is $\Pi$. Since there's no sort value specified in this case, the sort value is obtained from the actual value, but all commands and instances of $, { and } are stripped. This means that $\Pi$ ends up as an empty string and Xindy has no way of knowing how to sort it, which is why it generates an error and fails. The solution is to provide Xindy with a sort value that it will accept. For example, \index{P@$\Pi$} which sets the sort value to P. In the case of \index{$\bm{X}$}, the actual value is $\bm{X}$ so the sort value ends up as X, which is valid and so doesn't cause a problem. In the case of makeindex, the sort value (if not provided) is also taken from the actual value, but no adjustment is made, so with \index{$\Pi$} the sort value is $\Pi$, which from makeindex's point of view is a string consisting of five characters: $ \ P i and $. No error occurs in this case and the term ends up in the symbols group since it starts with a non-letter ($).

There may however be another source of conflict in your document build process. The imakeidx package automatically runs makeindex using the shell escape and your provided makeindexstyle.ist style file, but the subsequent texindy call made after the LaTeX call is overwriting the .ind file that was created by makeindex and doesn't recognise the style file. Once the above problem is fixed and the texindy call no longer fails, then the .ind file will then be overwritten by the next LaTeX call which runs makeindex. So you end up with a redundant texindy call and the final index file is the one created by makeindex through the shell escape.

You can prevent imakeidx from automatically running makeindex with the noautomatic option. In which case your makeindexstyle.ist file becomes redundant and instead you need to define \lettergroup. For example:

\newcommand*\lettergroup[1]{%
\par\textbf{\sffamily#1}\par
\nopagebreak
}


The change in texi2dvi seems to stem from replacing the line:

run $makeindex$index_files


with

  if $TEXINDY --version >&6 2>&1; then run$TEXINDY $index_files else run$MAKEINDEX \$index_files
fi


which enforces the use of texindy if it's been installed. There doesn't seem to be any way of changing this as far as I can tell.