Why does \newcommand not work properly with \index and math argument?

I was going to shorten the \index command (package makeidx) as shown below. I am working on a large document and always forgot to write the normal word additionally before the index entry command \index{}.

But something goes wrong: the arrow is not printed correctly in the index. (Don't forget to compile the minimal example with Makeindex too -- I forgot it too often.) I'm interested in solutions for both engines (XeLaTeX as well as pdfLaTeX), but it has to work only with XeLaTeX.

Why is the downarrow printed as an oversized bracket?

The problem seems to be in my use of the \newcommand with an argument in math mode. It is independent from compiling with pdfLaTeX or compiling with XeLaTeX.

Minimal example:

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

% This is a simple template for a LaTeX document using the "article" class.
% See "book", "report", "letter" for other types of document.

\documentclass[11pt]{article} % use larger type; default would be 10pt

\usepackage[utf8]{inputenc} % set input encoding (not needed with XeLaTeX)

\usepackage{makeidx}
\makeindex

\newcommand{\indiziere}[1]{\emph{#1}\index{#1}}

%%% The "real" document content comes below...

\title{Brief Article}
\author{The Author}
%\date{} % Activate to display a given date or no date (if empty),
% otherwise the current date is printed

\begin{document}
\maketitle

\section{First section}

More text. \emph{1$f(x) \downarrow$}\index{1$f(x) \downarrow$}.\newline
\indiziere{2$f(x) \downarrow$}.

\printindex
\end{document}

• Sep 21 '18 at 14:47

Your command evaluates #1 "too early", so the file content of the .ind file already contains a delimiter (\delimiter 3223379). With \string it works.

Side note: "Both" engines is a bit misleading as there are more engines than just pdf-/XeLaTeX out there (e.g. LuaLaTeX).

%!TeX TS-program=arara
% arara: xelatex
% arara: makeindex
% arara: xelatex
% arara: xelatex
\documentclass[11pt]{article} % use larger type; default would be 10pt

\usepackage{makeidx}
\makeindex

\newcommand{\indiziere}[1]{\emph{#1}\index{\string#1}}

\title{Brief Article}
\author{The Author}

\begin{document}
\maketitle

\section{First section}

More text. \emph{1$f(x) \downarrow$}\index{1$f(x) \downarrow$}.\newline
\indiziere{2$f(x) \string\downarrow$}.

\printindex
\end{document}


When \index is in the argument to a macro, the argument to \index cannot be “sanitized” (that is, treated essentially verbatim).

You can emulate the behavior with \detokenize:

\documentclass[11pt]{article} % use larger type; default would be 10pt

\usepackage[utf8]{inputenc} % set input encoding (not needed with XeLaTeX)

\usepackage{makeidx}
\makeindex

\newcommand{\indiziere}[1]{\emph{#1}\index{\detokenize{#1}}}

%%% The "real" document content comes below...

\title{Brief Article}
\author{The Author}
%\date{} % Activate to display a given date or no date (if empty),
% otherwise the current date is printed

\begin{document}
\maketitle

\section{First section}

More text. \emph{1$f(x) \downarrow$}\index{1$f(x) \downarrow$}.\newline
\indiziere{2$f(x) \downarrow$}.

\printindex
\end{document}


A related problem is described at Symbol index sorted by occurrence