andrewpwarren andrewpwarren - 4 months ago 34
Javascript Question

Indesign script GREP messes up when applying hyperlink destination

Stumbled across a very odd issue with scripting, GREP and hyperlinks in InDesign. I am trying to write a script (js) that automates the creation of hyperlinks across a large book (e-book). I have successfully written a glossary hyperlinking script but this is for chapter references. The idea is to have a GREP search that finds all words that match a heading style (underline, 20pt in this case) and then insert a hyperlink destination at that point. The oddity is that when the script runs it messes up the GREP search results finding text from the previous line.




var doc = app.activeDocument;

doc.hyperlinkTextDestinations.everyItem().remove();
doc.hyperlinkTextSources.everyItem().remove();
doc.hyperlinks.everyItem().remove();

app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.pointSize = 20;
app.findGrepPreferences.underline = true;
app.findGrepPreferences.findWhat = '';

var results = app.activeDocument.findGrep();

for (var i=0; i < results.length; i++) {
var text = results[i].texts.firstItem();
$.writeln(text.contents);
doc.hyperlinkTextDestinations.add(
text,
{
name: text.contents
}
);
}





running this script over the following text (indesign styling removed):
A title with trust
some text
Control and certainty
some text
Title
some text
Scripting in InDesign
some text

outputs the following to the console:

A title with trust
Control and certainty

Titl
xt
Scripting in InDesi

The first 2 are correct but its messed up the last 2. if i comment out the call to the add hyperlink destination method I see the correct text in the console:

A title with trust
Control and certainty
Title
Scripting in InDesign

Any help is really appreciated.

Thanks,

Answer

Change the text from end to start instead. Reverse your for loop, or (easier yet) change the order in which found results are returned:

var results = app.activeDocument.findGrep(true);

(see an online reference for the meaning of the Boolean value here).

The reason it does not work start to end is because you are storing the result list into a variable, and it does not get updated when you change the text afterwards. Which, unfortunately, is what 'inserting a hyperlink destination' does: it inserts a hidden character in the running text. From that point on, all previously found locations can no longer be trusted, so you'd have to re-do the findGrep command (and skip the first found result) – or process the results from end to start, so any changes you make do not influence the text that you still need to process.

Comments