# Automatically italicise index entries with subitems

I would like to produce an index that has italic entries with subitems, as outlined in this answer. But, I would like to add the italic format in the background, i.e. I would like to pass index!subitem and have that converted to index@\textit{index}!subitem@\textit{subitem} before being passed to \index.

Here's what I tried:

MWE:

\documentclass{book}
\usepackage{xparse}
\usepackage{makeidx}
\NewDocumentCommand{\italicise}{ >{\SplitList{!}} m }{%
\ixtestfalse
\ProcessList{#1}{\italiciseone}%
}
\newif\ifixtest
\NewDocumentCommand{\italiciseone}{m}{%
\ifixtest !\else\ixtesttrue\fi
#1@\textit{#1}}
\makeindex
\begin{document}
test
\index{Manual@\textit{Manual}!italics@\textit{italics}}
\index{\italicise{Automated!italics}}
\printindex
\end{document}


I think I'm halfway there, but it looks as if the \italicise command needs to be expanded when/before passed to \index, as the idx-file suggests:

\indexentry{Manual@\textit{Manual}!italics@\textit{italics}}{1}
\indexentry{\italicise{Automated!italics}}{1}


Output:

For sake of completeness, the ind-file:

\begin{theindex}

\item \italicise{Automated
\subitem italics}, 1

\indexspace

\item \textit{Manual}
\subitem \textit{italics}, 1

\end{theindex}


BTW, I don't have to use xparse, but these days, I always try that first.

EDIT

I now found a solution without using xparse, but I'd still be interested to see if this can be done via xparse or LaTeX3-Syntax.

• @egreg, in my opinion, is the person that can answer to your question. I have searched some material in CTAN and... I have found his name. ;-) – Giacomo Alessandroni Sep 10 '17 at 16:10
• @GiacomoAlessandroni Thanks. I found a plain solution now, but it will be interesting to see if anyone comes up with something regarding xparse ... – takrl Sep 11 '17 at 8:41

Found a solution myself now, without using xparse. This produces extra spaces in the idx-File (see below), but I think this is uncritical.

\documentclass{book}
\usepackage{makeidx}
\makeatletter
% split an index entry in two parts at the first !
\def\@splitentry#1!#2\@nil
{%
\def\@front{#1}%
\def\@back{#2}%
}%
\newtoks\@ixtoks
\newtoks\@splittok
% generate tokens for italicised index entry
\def\generate@tokens#1{%
\@ixtoks={}%
\def\@back{#1}%
\loop
\expandafter\@splitentry\@back\@nil
% if \@back is empty, this is the last item -> don't append the ! separator
\ifx\@back\empty\@splittok={}\else\@splittok={!}\fi
\edef\@settoks{\@ixtoks={\the\@ixtoks\@front @\noexpand\textit{\@front}\the\@splittok}}\@settoks
% terminate if \@back is empty -> we're finished
\unless\ifx\@back\empty
\repeat
}
\def\italicisedindex#1{%
% process with a manual trailing !, otherwise we get an error at the last entry
\generate@tokens{#1!}%
\edef\ixit{\noexpand\index{\the\@ixtoks}}\ixit
}
\makeatother
\makeindex
\begin{document}
\index{Manual@\textit{Manual}!italics@\textit{italics}}
\italicisedindex{Automated!italics}
\italicisedindex{Three!level!italics}
\printindex
\end{document}


Output:

Idx-File:

\indexentry{Manual@\textit{Manual}!italics@\textit{italics}}{1}
\indexentry{Second@\textit  {Second}!italics@\textit  {italics}!sub@\textit  {sub}!subsub@\textit  {subsub}}{1}
\indexentry{Automated@\textit  {Automated}!italics@\textit  {italics}!sub@\textit  {sub}}{1}


Ind-File:

\begin{theindex}

\item \textit  {Automated}
\subitem \textit  {italics}
\subsubitem \textit  {sub}, 1

\indexspace

\item \textit{Manual}
\subitem \textit{italics}, 1

\end{theindex}


Another way to do this is with imakeidx and an index style file (.ist). Here's a similar answer I gave elsewhere.

So to control the formatting of the indexing universally you can create an index style file which is read and its code is interjected as you dictate into the .ind file that becomes your index code. For what you want to achieve, I believe this combination should work.

(1) Make a .txt file with the following and save it as an .ist or change its ending in your file manager (Finder or Windows Explorer etc.).

item_0 "\\indexspace \n \\item \\noindent "
item_x1 "\n \\subitem \\textit{"
item_1 " \n \\subitem \\textit{"
item_x2 "\n} \\subitem "
item_2 "\n \\subitem "

delim_0 "\\hfill"
delim_1 "} \\hfill"
delim_2 "\\hfill"


(2) Have this in your TeX file. This should cut down on the material in your preamble.

\documentclass[a4paper]{book}
\usepackage{imakeidx}

\makeindex[name=itindex3,title=Example Index Title, options = -s itindex3.ist]

\makeindex
\begin{document}

This is a test.

\index[itindex3]{some stuff!some other stuff}
\index[itindex3]{Item 0!Item 1!Item 2}
\index[itindex3]{example!this .ist code requires a sub-item to work, since it closes the textit environment with a second curly bracket}
\index[itindex3]{Italics}

\printindex[itindex3]
\end{document}


When you edit the .ist file, be sure to make sure your text editor doesn't chagne straight quotes to curly quotes (this will cause all sorts of snafus). Also see this for info on the keys you can use in .ist files.

Here is the .ind file this produces:

\begin{theindex}
\indexspace
\item \noindent example
\subitem \textit{this .ist code requires a sub-item to work, since it closes the textit environment with a second curly bracket} \hfill
1

\indexspace
\indexspace
\item \noindent Italics\hfill1\indexspace
\item \noindent Item 0
\subitem \textit{Item 1
} \subitem Item 2\hfill1

\indexspace
\indexspace
\item \noindent some stuff
\subitem \textit{some other stuff} \hfill1

\end{theindex}