Skip to main content
ali u
Inspiring
December 23, 2022
Answered

batch adding cross-references

  • December 23, 2022
  • 5 replies
  • 1158 views

I'm trying to list my grep results as cross-references, this is what I have this far; it works only if there is only one found item, can you point me in the right direction to fix it?

var doc = app.activeDocument;
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.pointSize = 20;
app.findGrepPreferences.findWhat = '';

var results = doc.findGrep(true);

for (var i=0; i < results.length; i++) {
var text = results[i].texts.firstItem();

$.writeln(text.contents);
dest = doc.hyperlinkTextDestinations.add(text, {name: text.contents});

var xRefForm = doc.crossReferenceFormats.item("Paragraph Text & Page Number");
var source = doc.crossReferenceSources.add(app.selection[0],xRefForm);
var xref = doc.hyperlinks.add(source,dest);
}

 

This topic has been closed for replies.
Correct answer Peter Kahrel

@ali u 

Pretty good effort! Here are some comments and a shorter version of your script.

No need to create the text destinations in a separate loop, you can cretae them in the main loop (as you had it originally, in fact).

Similarly, there's no need to create placeholders as a separate step. It, too, can be handled in the main loop.

Don't define variables inside a loop: define them outside the loop, then refer to them inside the loop.

Similarly, don't call InDesign's DOM when you don't have to, it slows things down. So create a reference to the cross-reference format only once, then use that reference.

Peter

var doc = app.activeDocument;
var story = doc.stories[0];
var xRefForm = doc.crossReferenceFormats.item ('Paragraph Text & Page Number');

var source;
var desto;

app.findGrepPreferences = null;  
app.findGrepPreferences.pointSize = 20;  
var results = story.findGrep(true);  

for (var i = 0; i < results.length; i++) {
  story.insertionPoints[0].contents = '\r';
  desto = doc.hyperlinkTextDestinations.add (results[i], {name: 'dest' + i});
  source = doc.crossReferenceSources.add (story.insertionPoints[0], xRefForm);
  doc.hyperlinks.add (source, desto);
}

5 replies

Peter Kahrel
Community Expert
Peter KahrelCommunity ExpertCorrect answer
Community Expert
December 26, 2022

@ali u 

Pretty good effort! Here are some comments and a shorter version of your script.

No need to create the text destinations in a separate loop, you can cretae them in the main loop (as you had it originally, in fact).

Similarly, there's no need to create placeholders as a separate step. It, too, can be handled in the main loop.

Don't define variables inside a loop: define them outside the loop, then refer to them inside the loop.

Similarly, don't call InDesign's DOM when you don't have to, it slows things down. So create a reference to the cross-reference format only once, then use that reference.

Peter

var doc = app.activeDocument;
var story = doc.stories[0];
var xRefForm = doc.crossReferenceFormats.item ('Paragraph Text & Page Number');

var source;
var desto;

app.findGrepPreferences = null;  
app.findGrepPreferences.pointSize = 20;  
var results = story.findGrep(true);  

for (var i = 0; i < results.length; i++) {
  story.insertionPoints[0].contents = '\r';
  desto = doc.hyperlinkTextDestinations.add (results[i], {name: 'dest' + i});
  source = doc.crossReferenceSources.add (story.insertionPoints[0], xRefForm);
  doc.hyperlinks.add (source, desto);
}
ali u
ali uAuthor
Inspiring
December 27, 2022

@Peter Kahrel 

Thank you very much, this looks beautiful and works way faster. It's a privilege to learn from you.

ali u
ali uAuthor
Inspiring
December 26, 2022

Thank you all! I got it working by changing the source for every destination, the script works now but I still feel I'm doing some stuff wrong or doing unnecessary things 🙂 here is the code, if you feel like help me improve/optimize it, and again thank you @Robert at ID-Tasker @Peter Kahrel @brian_p_dts.

ali u
ali uAuthor
Inspiring
December 26, 2022
var doc = app.activeDocument;  
    
app.findGrepPreferences = app.changeGrepPreferences = null;  
app.findGrepPreferences.pointSize = 20;  
app.findGrepPreferences.findWhat = '';  
  
var results = app.activeDocument.findGrep(true);  

aded = results.length


  
for (var i=0; i < results.length; i++) {  
    var text = results[i].texts.firstItem();  
          

    destname = "dest" + i
    dest = doc.hyperlinkTextDestinations.add(text, {name: destname});   

} 

ali = ""
for (var i=0; i < aded; i++) {  
ali = "source" + i + "<p>" + ali 
} 
app.activeDocument.stories[0].paragraphs[0].contents = ali




app.findGrepPreferences=app.changeGrepPreferences=null;
app.findGrepPreferences.findWhat= "<p>";
app.changeGrepPreferences.changeTo="\r";
app.activeDocument.changeGrep();

for (var i=0; i < aded; i++) {  

desto = doc.hyperlinkTextDestinations[i];
var xRefForm = doc.crossReferenceFormats.item("Paragraph Text & Page Number");

app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.nothing;
	app.findGrepPreferences.findWhat = "source" + i;
	var sourcetexts = doc.findGrep();
	
    var sourcetext = sourcetexts[0].texts.firstItem();  
   
var source = doc.crossReferenceSources.add(sourcetext,xRefForm);

var xref = doc.hyperlinks.add(source,desto);
    
} 







 


Peter Kahrel
Community Expert
Community Expert
December 23, 2022

As Brian said, perfectly doable and good practice ground. But you need to sort out the problem that each piece of text (e.g. a word) can be the source of only one cross-reference.

 

Once you solved that problem the script shouldn't be too difficult to fix.

Peter Kahrel
Community Expert
Community Expert
December 23, 2022

Robert is right: you're trying to create multiple cross-reference sources at the same text (the selected text), and that's not possible. 

In addition, in this line:

dest = doc.hyperlinkTextDestinations.add(text, {name: text.contents});

you run the risk of trying to create a text destination with a name that already exists. And that, too, is not possible.

 

Robert at ID-Tasker
Legend
December 23, 2022

Thanks 🙂 

 

I think it would be possible - same source - if each time there was an extra character included - previously created reference point?

 

Peter Kahrel
Community Expert
Community Expert
December 23, 2022

True, but then it'd be difficult to figure out where to click.

Robert at ID-Tasker
Legend
December 23, 2022

Not sure but looks like you are adding same source to many destinations??