Search code examples
javascriptadobe-indesignextendscript

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,


Solution

  • 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.