# replace folder separation char for index

In index the ! char is used for item separation. I have index strings which contain folders and files.

These index entrys should look like

\index{files!fonts/!fonts.tex}


However I pass these to the index using this command:

\newcommand*{\labelfile}[1]{\index{files!#1}}


which results in

\index{files!fonts/fonts.tex}


thus the replacement of every / in #1 by /! is missing.

How can I replace chars in a string in LaTeX ?

EDIT:

Using the code example from Heiko Oberdiek (which works!) I created the following approach to wrap all items in a \texttt command. Unfortunately my approach fails...

\newcommand*{\labelfile}[1]{%
\StrSubstitute{#1}{/}{,}[\TempIndexFileEntry]%
\def\doc@IndexFileEntry\empty
\def\do##1{%
\edef\@tempa{\zap@space##1 \@empty}%
\ifdefempty{\doc@IndexFileEntry}{
\renewcommand{\doc@IndexFileEntry}{\texttt{\@tempa}}
}{%
\renewcommand{\doc@IndexFileEntry}{\doc@IndexFileEntry/\texttt{\@tempa}}
}%
}%
%% Process csv list with command \do (etoolbox)
\docsvlist{\TempIndexFileEntry}%
%% rename
\let\TempIndexFileEntry\doc@IndexFileEntry
\@bsphack
\StrSubstitute{\TempIndexFileEntry}{/}{/!}[\IndexFileEntry]%
\index{files!\IndexFileEntry}%
\@esphack
}


with

! Use of \TempIndexFileEntry doesn't match its definition.
\@xs@StrSubstitute@@ ...}\@xs@def \@xs@arg@ii {#2}
\@xs@def \@xs@arg@iii {#3}...

-
Shoudn't you escape the ! (usually with "!) –  Peter Breitfeld Aug 5 '12 at 21:56

Package xstring provides \StrSubstitute that can replace a substring by another substring:

\documentclass{article}
\usepackage{makeidx}
\makeindex

\usepackage{xstring}
\newcommand*{\labelfile}[1]{%
\StrSubstitute{#1}{/}{/!}[\IndexFileEntry]%
\index{files!\IndexFileEntry}%
}

\begin{document}
Hello World

\index{files!fonts/!abc.tex}

\labelfile{fonts/xyz.tex}

\printindex
\end{document}


The file test.idx contains:

\indexentry{files!fonts/!abc.tex}{1}
\indexentry{files!fonts/!xyz.tex}{1}


In an more elaborated version of \labelfile, the definition could be surrounded by \@bsphack and \@esphack to preserve the behaviour of \index regarding preceding and following spaces.

\makeatletter
\newcommand*{\labelfile}[1]{%
\@bsphack
...
\@esphack
}
\makeatother


Also some special characters for makeindex can be quoted:

\StrSubstitute{...}{@}{"@}


Or the file names could be put in \texttt, …

Note: Makeindex only supports three levels. Thus the file specification should only contain one slash. Level 0 is used for files, level 1 for the directory and level 2 for the file name.

Edit: A further request is indeed to put the file names in \texttt. I start similar as in the edited questions to make a comma separated list, but I use package kvsetkeys for parsing the comma separated list, because I am more familiar with this package (as author I should be). We need the following structure of the index entry, e.g. for <directory>/<file>:

\index{files!<directory>/@\texttt{<directory>/}!<file>@\texttt{<file>}}


Each directory or file is doubled, first it is used as sort key, then it is formatted using \texttt.

\documentclass{article}
\usepackage{makeidx}
\makeindex

\usepackage{xstring}
\usepackage{kvsetkeys}

\makeatletter
\newcommand*{\labelfile}[1]{%
\StrSubstitute{#1}{/}{/,}[\IndexFileA]%
\let\IndexFileB\@empty
\expandafter
\index{files!\IndexFileB}%
}
\ifx\IndexFileB\@empty
\def\IndexFileB{#1@\texttt{#1}}%
\else
\expandafter\def\expandafter\IndexFileB\expandafter{%
\IndexFileB!%
#1@\texttt{#1}%
}%
\fi
}
\makeatother

\begin{document}
Hello World

\labelfile{fonts/abc.tex}
\labelfile{fonts/xyz.tex}

\printindex
\end{document}


The .idx file:

\indexentry{files!README@\texttt  {README}}{1}
\indexentry{files!fonts/@\texttt  {fonts/}!abc.tex@\texttt  {abc.tex}}{1}
\indexentry{files!fonts/@\texttt  {fonts/}!xyz.tex@\texttt  {xyz.tex}}{1}


The multiple spaces are an artefact of LaTeX's protection mechanisms and do not disturb here.

The index looks like:

-
Works as expected. However putting all file names in \texttt is a bigger problem than I thought. See my edited question for the approach that I took. –  Matthias Pospiech Aug 6 '12 at 18:16

The level character is not fixed if you have a file say myind.ist that has the line

level ;


then ; would be the level separator rather than !. Any suitable character may be used.

You would then process with

makeindex -s myind.ist myfile


to use the myind.ist style.

See for example the index style designed to go with the doc style for documenting latex packages, which is usually installed somewhere like

 texmf-dist/makeindex/latex/gind.ist

-