Copy link to clipboard
Copied
Hi,
I have a book file consisting of over 300 documents, and I've realized the need to replace certain words and phrases with their corrected and modified versions. Going through the Find/Replace window for each document individually is time-consuming and tedious. Is there a way to automate this process for all documents in the book using a script or possibly GREP?
You should be able to do it by storing the pairs in a nested array—the format would be:
//A nested array in this format [["search1", "change1"], ["search2","change2"],...]
var sa = [["indesign", "InDesign"], ["script panel","Script Panel"], ["graphic objects", "artworks"]]
searchBooks()
function searchBooks(){
try {
var b = app.activeBook
}catch(e) {
alert("No Open Books")
retur
Copy link to clipboard
Copied
You need enough RAM.
Open all documents and find & replace in all document.
Copy link to clipboard
Copied
Unfortunately, I don't have sufficient RAM – only 4GB! If a script could handle the task by opening and closing documents individually for modification, that would be ideal.
Copy link to clipboard
Copied
To work professional with InDesign you need to expand the RAM. 4GB is enought to select the text tool, but not more.
Copy link to clipboard
Copied
"Hahaha, I agree, and you're right. I should consider the old machine.
Copy link to clipboard
Copied
4GB? That's not enough for the operating system and recent versions of InDesign won't even install.
Copy link to clipboard
Copied
That's correct, Bob. I rarely use ID on this old PC, but it still works well for handling documents, particularly those that involve text boxes rather than high-resolution artworks.
But despite the weak hardware, I'd like to know what professionals do in this scenario. Do they use Find/Replace for each document in a book file that includes many documents, or do they use specific plugins or scripts?
Copy link to clipboard
Copied
I recently had to do something similar, and it seems that InDesign will not open more than 99 documents at once. I have 32GB and there was plenty left.
Quite dangerous actually, because I thought I had opened all documents and made the change in all of them. Afterwards I realized that only a fraction of the documents had been changed... I redid the operation to see what had happened, and that's where I get the number 99 from.
Copy link to clipboard
Copied
I wonder if it is still memory related? I can run a script that creates over 99 new documents without a problem :
var doc;
for (var i = 0; i < 115; i++){
doc = app.documents.add();
};
iMac with 72GB:
Copy link to clipboard
Copied
Yup, I'm also managing to open more than 99 docs now (I reopened those documents that I thought failed last time, and they opened successfully), so I must be wrong about the 99-doc limit. Maybe I had more apps open at the time and it was indeed a memory issue...
Copy link to clipboard
Copied
I did the test only last week in 2024 in Windows 10, 32Gb ram. InDesign made it to 137 documents. Maybe the wind blew from the right direction. It's a ludicrous limitation.
But for Rob's script it's immaterial because he opens and closes documents.
The only area where it really matters is when you want to do an index in a book of 99+/115+/130+ documents, because InDesign needs all book documents open to generate the index (unlike the toc, which polls the documents).
Copy link to clipboard
Copied
Hi @Masoud Moghaddam , For a simple text find and change you could try this—replace "Foo" and "Bar" with your find and change text. Should work at least back to CS6:
var gf = "Foo"
var gr = "Bar"
searchBooks()
function searchBooks(){
try {
var b = app.activeBook
}catch(e) {
alert("No Open Books")
return
}
var bp = b.bookContents.everyItem().fullName;
var d;
for (i = 0; i < bp.length; i++) {
d = app.open(bp[i]);
grepSearch(gf,gr)
d.close(SaveOptions.YES);
}
}
/**
* Document Grep find and change
* @ param f the find grep string
* @ param c the change grep string
* @ return void
*/
function grepSearch(f,c){
app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
app.findChangeGrepOptions.properties = {includeFootnotes:true, includeHiddenLayers:true, includeMasterPages:true, wholeWord:false}
app.findGrepPreferences.findWhat = f;
app.changeGrepPreferences.changeTo = c;
app.activeDocument.changeGrep( true )
}
If you are using Grep strings, back slashes have to be escaped so, for example, to find multiple tabs this:
"\t+"
Needs to be this:
Copy link to clipboard
Copied
Nice one, Rob. Just one comment: it's more efficient to keep the two lines that set the find/change preferences and options outside the for-loop because you need to set them just once.
P.
Copy link to clipboard
Copied
Thanks Peter, you‘re right, no need for the grepSearch() function, which I usually use for stringing together multiple searches—not sure if @Masoud Moghaddam needs more than one search. This would be better for a single search:
var gf = "Bar"
var gr = "Foo"
searchBooks()
function searchBooks(){
try {
var b = app.activeBook
}catch(e) {
alert("No Open Books")
return
}
var bp = b.bookContents.everyItem().fullName;
app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
app.findChangeGrepOptions.properties = {includeFootnotes:true, includeHiddenLayers:true, includeMasterPages:true, wholeWord:false}
var d;
for (i = 0; i < bp.length; i++) {
d = app.open(bp[i]);
app.findGrepPreferences.findWhat = gf;
app.changeGrepPreferences.changeTo = gr;
app.activeDocument.changeGrep( true )
d.close(SaveOptions.YES);
}
}
Copy link to clipboard
Copied
"Great job, @rob day ! The script works well, but there's one thing I'm curious about. Is it possible to include more words for find and replace within a single script? I'm hoping the script could search for multiple old entries and replace them with corresponding new entries, rather than creating different scripts for each pair of words or phrases.
For instance, is it feasible to add more variations for finds and replaces like the ones below the initial ones in your script, all in one go?
var gf1 = "indesign"
var gr1 = "InDesign"
var gf2 = "script panel"
var gr2 = "Script Panel"
var gf3 = "graphic objects"
var gr3 = "artworks"
And so on...
I attempted it for a single word, and I'm wondering if it's possible to instruct the script to find at least ten words and replace them with new ones in a single execution without interruption.
Copy link to clipboard
Copied
You should be able to do it by storing the pairs in a nested array—the format would be:
//A nested array in this format [["search1", "change1"], ["search2","change2"],...]
var sa = [["indesign", "InDesign"], ["script panel","Script Panel"], ["graphic objects", "artworks"]]
searchBooks()
function searchBooks(){
try {
var b = app.activeBook
}catch(e) {
alert("No Open Books")
return
}
var bp = b.bookContents.everyItem().fullName;
var d;
for (i = 0; i < bp.length; i++) {
d = app.open(bp[i]);
for (var j = 0; j < sa.length; j++){
grepSearch(sa[j][0],sa[j][1])
};
d.close(SaveOptions.YES);
}
}
/**
* Document Grep find and change
* @ param f the find grep string
* @ param c the change grep string
* @ return void
*/
function grepSearch(f,c){
app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
app.findChangeGrepOptions.properties = {includeFootnotes:true, includeHiddenLayers:true, includeMasterPages:true, wholeWord:false}
app.findGrepPreferences.findWhat = f;
app.changeGrepPreferences.changeTo = c;
app.activeDocument.changeGrep( true )
}
Copy link to clipboard
Copied
Great job, @rob day ! It works perfectly for multiple search find-and-replace operations in a single go.