ho risolto il problema facendo un giro un po’ largo. In sostanza ho scritto un programmino (in c++ perché lo conosco, ma andrebbe ugualmente bene un altro linguaggio) che manipola il file .ind prodotto da makeindex inserendo i comandi per creare i bookmark di hyperref per il pdf.
nel file .sty ho inserito questi comandi (ok il mio latex fa schifo, ma soprassediamo)
`
headings_flag 1
heading_prefix “\\vspace\{-6pt\}\\parbox\{\\columnwidth\}\{\\hspace\{0\\columnwidth\}\\centering\{\\normalsize — \\textbf\{”
heading_suffix “\} –\}\}\\vspace\{3pt\}\\nopagebreak\n\%bookmark\n”
`
il codice del programma c++ è questo:
`
#include
#include
#include
using namespace std;
const string bookmarks[] = {“A-C”, “D-F”, “G-I”, “J-L”,
“M-O”, “P-R”, “S-U”, “V-X”, “Y-Z”};
const string token(“– \\textbf{“);
int main(int argc, char *argv[])
{
if(argc==1)
{
cout << "error: input file not specified";
return 1;
}
ifstream inputFile;
ofstream outputFile;
string inputFileName(argv[1]);
string outputFileName("temp.txt");
inputFile.open(inputFileName.c_str(), ios::in);
if(inputFile.is_open())
{
cout << inputFileName << " opened for reading\n";
}
else
{
cout << "failed to open " + inputFileName;
return 1;
}
outputFile.open(outputFileName.c_str(), ios::out);
if(outputFile.is_open())
{
cout << "temporary file opened for reading\n";
}
else
{
cout << "failed to open " + outputFileName;
return 1;
}
string currentLine;
char buffer[1024];
int lines=0;
bool changeNextLine = false;
bool changeThisLine = false;
size_t found;
int bookPos;
while(!inputFile.eof())
{
changeThisLine = changeNextLine;
changeNextLine = false;
inputFile.getline(buffer, 1024);
currentLine = buffer;
found = currentLine.find(token);
if(found!=string::npos)
{
int pos = int(found)+token.length();
char letter = currentLine[pos];
if((letter-'A')%3 == 0)
{
bookPos = (letter-'A')/3;
cout << "Found letter " << letter << endl;
changeNextLine = true;
}
}
outputFile << buffer << endl;
if(changeThisLine)
{
outputFile << "\\phantomsection\n";
outputFile << "\\pdfbookmark[1]{" << bookmarks[bookPos] << "}"
<< "{indexbookmark" << bookmarks[bookPos][0] << "}\n";
}
lines++;
}
inputFile.close();
outputFile.close();
remove(inputFileName.c_str());
rename(outputFileName.c_str(), inputFileName.c_str());
cout << inputFileName << " succesfully modified\n";
cout << lines << " lines processed\n";
return EXIT_SUCCESS;
}
`
dopo la sua esecuzione il file .ind diventa questo (ad esempio)
`
\begin{theindex}
\vspace{-6pt}\parbox{\columnwidth}{\hspace{0\columnwidth}\centering{\normalsize -- \textbf{A} --}}\vspace{3pt}\nopagebreak
%bookmark
\phantomsection
\pdfbookmark[1]{A-C}{indexbookmarkA}`
Praticamente cerca le righe nelle quali c'è una delle lettere di intestazione e una volta ogni tre aggiunge un bookmark. Il programma andrebbe richiamato dopo makeindex, passandogli come parametro il file .ind da questo ottenuto. Per automatizzare (uso TexnicCenter) ho copiato l'eseguibile del mio programma in "C:\Program Files" (ma qualsiasi posto va bene) e poi impostato il preprocessor di TexnicCenter in modo che lo richiami ogni volta prima di invocare Latex. L'immagine allegata mostra l'impostazione.
[attachment=500]proprocessore.png[/attachment]
In questo modo l'indice generale rimane pulito, mentre nel pdf si vedono i riferimenti che tutto sommato sono utili, e il procedimento funziona senza pensarci ogni volta che si compila il documento.
[attachment=499]acrobat.png[/attachment]
il programmino è fatto velocemente, non fornisce i risultati corretti se manca qualche lettera (ad esempio se nessuna voce comincia per "D" il segnalibro "D-F" non viene inserito... volendo comunque ci si mette poco a perfezionarlo.
ciao
Davide