• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

I Discovered a Bug or Limitation in InDesign JavaScript GREP Options

Enthusiast ,
Aug 22, 2021 Aug 22, 2021

Copy link to clipboard

Copied

Hi Experts, While I'm Still Learning and Discovering InDesign JavaScript I Discover a Maybe Bug or Limitation in InDesign JavaScript , I Discovered that Master Page Option not Working with One Page or Page Range at all, See this Simple Example, if you change PageRange to Range or One Page, the Master Page Options will Ignore Both!, So items in Master Pages Will not Affected!! even if its true ! :

 

 

app.findChangeGrepOptions.includeMasterPages = true;

 

 

 See (Example Demo and Try to Change the PageRange or OnePage, I left the Variable with the Same Name for Easy test):

 

 

//--One Page or Page Range Not Supported in Master Page GREP Option !
//Bug or Limitation in InDesign JavaScript!
//grep options
app.findChangeGrepOptions.includeMasterPages = true; //not Supported in Page Range nor One Page
app.findChangeGrepOptions.includeFootnotes = true; //Supported
app.findChangeGrepOptions.includeHiddenLayers = true; //Supported
app.findChangeGrepOptions.includeLockedLayersForFind = true; //Supported
app.findChangeGrepOptions.includeLockedStoriesForFind = true; //Supported

//itemByRange and Show Text
var myDoc = app.activeDocument;
//--Page Range Not Supported in Master Page GREP Option 
//var pageRange = myDoc.pages.itemByRange(0, 2).textFrames.everyItem().paragraphs.everyItem();
//or
//--One Page Not Supported in Master Page GREP Option 
var pageRange = myDoc.pages[0].textFrames.everyItem().paragraphs.everyItem(); //--Master Page GREP Option not supported

var myFind = "\\(.+?\\)";
var myChange = "BB";
//Clear Grep Prefrences
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = ({findWhat: myFind});
app.changeGrepPreferences.properties = ({changeTo: myChange});
var myFoundTextParagraphs = pageRange.findGrep();
// a new array to store the found texts
var myFoundTexts = [];

// nested loop to grab all the found texts in a new "flat" array
for (var i = 0; i < myFoundTextParagraphs.length; i++) {
    for (var j = 0; j < myFoundTextParagraphs[i].length; j++) {
        // add the actual found text item to the new array
        myFoundTexts.push(myFoundTextParagraphs[i][j]);
    }
}
// and you can iterate over it in a single loop:
for (var i = 0; i < myFoundTexts.length; i++) {
    //myFoundTexts[i].showText(); // not necessary here?
    myFoundTexts[i].changeGrep();
}
app.findGrepPreferences = app.changeGrepPreferences = null;

 

 

So Did I Really Discovered a Bug! or it Just a Limitation? or I Miss Understand!, I'm Waiting Experts Opinion and Thanks in Advance. 

Best
Mohammad Hasanin
TOPICS
Scripting

Views

368

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 3 Correct answers

Community Expert , Aug 22, 2021 Aug 22, 2021

You are executing findGrep only on paragraphs of an actual page, not its appled master. It would be as if you were finding/changing on a Selection on the actual user interface. It won't look at the applied master page because you are not asking it to. Again you'd have to use mine or Uwe's suggestions from the previous thread to execute your findGrep. You could also run a second findGrep on ...pages[0].appliedMaster.textFrames...

Votes

Translate

Translate
Community Expert , Aug 22, 2021 Aug 22, 2021
var pageMaster = myDoc.pages.itemByRange(0, 2).appliedMaster;

returns an Array of MasterSpread objects. You'll need to consider and execute on each separately. Beware of a None master applied: 

var pageMaster = app.activeDocument.pages.itemByRange(0, 2).appliedMaster;
for (var i = 0; i < pageMaster.length; i++) {
    if (pageMaster[i] && pageMaster[i].isValid) {
        alert(pageMaster[i].constructor.name);
        alert(pageMaster[i].name);
    }
    else {
        alert("NONE master applied")
...

Votes

Translate

Translate
Community Expert , Aug 23, 2021 Aug 23, 2021

You are calling findGrep() on PageMaster, which is an array as we have discussed previously. An Array does not have the findGrep method. The following will give you a multiarray of a single master page's found texts. Run it through a function to push it into your array. Clearly, your code is not correct if throwing errors. 

 

var pushToArr = function(foundArr, multiArr) {
   for (var i = 0; i < multiArr.length; i++) { 
       for (var j = 0; j < multiArr[i].length; j++) {
           foundArr.pus
...

Votes

Translate

Translate
Community Expert ,
Aug 22, 2021 Aug 22, 2021

Copy link to clipboard

Copied

You are executing findGrep only on paragraphs of an actual page, not its appled master. It would be as if you were finding/changing on a Selection on the actual user interface. It won't look at the applied master page because you are not asking it to. Again you'd have to use mine or Uwe's suggestions from the previous thread to execute your findGrep. You could also run a second findGrep on ...pages[0].appliedMaster.textFrames...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 22, 2021 Aug 22, 2021

Copy link to clipboard

Copied

Thanks for your reply, Please Can you Give me the Discussing Thread to Read About that and Can I also Use AppliedMaster within page ranges?, and Thanks in Advance

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 22, 2021 Aug 22, 2021

Copy link to clipboard

Copied

https://community.adobe.com/t5/indesign/trying-to-change-grep-in-paragraphs-between-pages-range-incl...

 

You'd need to examine/hash the appliedMasters of the range. You could lock all objects on all masters except those masters using Uwe's suggestion, or check if the foundText parentPage in my suggestion is an instanceof one of those spreads. Maybe someone has a cleaner approach. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 22, 2021 Aug 22, 2021

Copy link to clipboard

Copied

Thanks a lot @brianp311  , I will do my best 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 22, 2021 Aug 22, 2021

Copy link to clipboard

Copied

Hi @brianp311 , I Succeeded in Adding Second Loop for the One Page as following :

 

//One Page Only Works Great and Correct for One Page and Master
//grep options
app.findChangeGrepOptions.includeMasterPages = true; 
app.findChangeGrepOptions.includeFootnotes = true; 
app.findChangeGrepOptions.includeHiddenLayers = true; 
app.findChangeGrepOptions.includeLockedLayersForFind = true; 
app.findChangeGrepOptions.includeLockedStoriesForFind = true; 

var myDoc = app.activeDocument;
var pageRange = myDoc.pages[0].textFrames.everyItem().paragraphs.everyItem();
var pageMaster = myDoc.pages[0].appliedMaster.textFrames.everyItem().paragraphs.everyItem();  

var myFind = "\\(.+?\\)";
var myChange = "BB";
//Clear Grep Prefrences
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = ({findWhat: myFind});
app.changeGrepPreferences.properties = ({changeTo: myChange});
var myFoundTextParagraphs = pageRange.findGrep();
var myFoundTextMaster = pageMaster.findGrep();
//-------------------------------------------------------------------------------------
// a new array to store the found texts
var myFoundTexts = [];
var myFoundMaster = [];

// First nested loop to grab all the found texts in a new "flat" array
for (var i = 0; i < myFoundTextParagraphs.length; i++) {
    for (var j = 0; j < myFoundTextParagraphs[i].length; j++) {
        // add the actual found text item to the new array
        myFoundTexts.push(myFoundTextParagraphs[i][j]);
        // nested loop to grab all the found texts in a new "flat" array
    }
}
//Second nested Loop for MasterPage
for (var k = 0; k < myFoundTextMaster.length; k++) {
    for (var l = 0; l < myFoundTextMaster[k].length; l++) {
        // add the actual found text item to the new array
        myFoundMaster.push(myFoundTextMaster[k][l]);
    }
}


//-------------------------------------------------------------------------------------
// and you can iterate over it in a single loop:
for (var i = 0; i < myFoundTexts.length; i++) {
    myFoundTexts[i].changeGrep();
    // and you can iterate over it in a single loop:
for (var n = 0;n < myFoundMaster.length; n++) {
    myFoundMaster[n].changeGrep();
}
}
alert("GREP Replaced is "+Number(myFoundTexts.length+myFoundMaster.length)+" Total"); //Correct Loop for One Page
app.findGrepPreferences = app.changeGrepPreferences = null;

 

but i didnt figure how to add second loop for the Page Ranges Because i didn't know how to call the Correct Variable of (AppliedMaster)..

i tried to use :

 

var pageMaster = myDoc.pages.itemByRange(0, 2).appliedMaster.textFrames.everyItem().paragraphs.everyItem();;
var pageMaster = myDoc.pages.masterPageItems.itemByRange(0, 2).textFrames.everyItem().paragraphs.everyItem();

 

but none of them working and it gives errors!, I tried to search the DOM but no Luck!, Please Help and Thanks in Advance.

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 22, 2021 Aug 22, 2021

Copy link to clipboard

Copied

var pageMaster = myDoc.pages.itemByRange(0, 2).appliedMaster;

returns an Array of MasterSpread objects. You'll need to consider and execute on each separately. Beware of a None master applied: 

var pageMaster = app.activeDocument.pages.itemByRange(0, 2).appliedMaster;
for (var i = 0; i < pageMaster.length; i++) {
    if (pageMaster[i] && pageMaster[i].isValid) {
        alert(pageMaster[i].constructor.name);
        alert(pageMaster[i].name);
    }
    else {
        alert("NONE master applied");
    }
}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 23, 2021 Aug 23, 2021

Copy link to clipboard

Copied

Thanks a lot @brianp311 I will try to loop inside masters

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 23, 2021 Aug 23, 2021

Copy link to clipboard

Copied

Hi @brianp311 , I hope i dont be annoying! , i just still learning javascript and methods, any way my script not working, if you please can identify what the error inside the script, also here i tried to make a second loop for the page ranges m but not working!, give errors, and thanks in advance  :

 

//grep options
app.findChangeGrepOptions.includeMasterPages = true; 
app.findChangeGrepOptions.includeFootnotes = true; 
app.findChangeGrepOptions.includeHiddenLayers = true; 
app.findChangeGrepOptions.includeLockedLayersForFind = true; 
app.findChangeGrepOptions.includeLockedStoriesForFind = true; 

var myDoc = app.activeDocument;
var pgStart = 0; 
var pgEnd =  2;
var pageRange = myDoc.pages.itemByRange(pgStart, pgEnd).textFrames.everyItem().paragraphs.everyItem();
var pageMaster = myDoc.pages.itemByRange(pgStart, pgEnd).appliedMaster;
      
var myFind = "\\(.+?\\)";
var myChange = "BB";
//Clear Grep Prefrences
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = ({findWhat: myFind});
app.changeGrepPreferences.properties = ({changeTo: myChange});
var myFoundTextParagraphs = pageRange.findGrep();
//var myMasterTextFrames = pageMaster.findGrep();
// a new array to store the found texts
var myFoundTexts = [];
var myFoundMaster = [];
// First nested loop to grab all the found texts in a new "flat" array
for (var i = 0; i < myFoundTextParagraphs.length; i++) {
    for (var j = 0; j < myFoundTextParagraphs[i].length; j++) {
        // add the actual found text item to the new array
        myFoundTexts.push(myFoundTextParagraphs[i][j]);
        // nested loop to grab all the found texts in a new "flat" array
    }
}
//Second nested Loop for MasterPage
for (var n = 0; n < pageMaster.length; n++) {
     for (var k = 0; k < pageMaster[n].length; k++) {
        for (var l = 0; l < myMasterTextFrames[n][k].length; l++) {
        pageMaster[n] =  myDoc.masterSpreads.item(n).name //Correct
        //Equal  Example: myDoc.pages.itemByRange(myStartPage, myEndPage).appliedMaster = myDoc.masterSpreads.item("B-Master");
        pageMaster[n][k] = myDoc.masterSpreads.everyItem().textFrames.everyItem().getElements()
        // add the actual found text item to the new array
        myFoundMaster.push(myMasterTextFrames[n][k][l]);
        //var myMasterTextFrames = pageMaster.findGrep();
        myMasterTextFrames[n][k][l] = pageMaster.findGrep();
        }
    }
}

for (var i = 0; i < myFoundTexts.length; i++) {
    myFoundTexts[i].changeGrep();
for (var i = 0;i < myFoundMaster.length; i++) {
    myFoundMaster[n].changeGrep();
}
}
alert("GREP Replaced is "+Number(myFoundTexts.length+myFoundMaster.length)+" Total"); 
app.findGrepPreferences = app.changeGrepPreferences = null;

 

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 23, 2021 Aug 23, 2021

Copy link to clipboard

Copied

What are the errors? 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 23, 2021 Aug 23, 2021

Copy link to clipboard

Copied

If i leave the  findgrep above like

PageMaster.findgrep()

It give me PageMaster.findgrep() not a function error and if i put it down like the example it give me error object not defined

Do you think script is correct or need some tweaks ? 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 23, 2021 Aug 23, 2021

Copy link to clipboard

Copied

You are calling findGrep() on PageMaster, which is an array as we have discussed previously. An Array does not have the findGrep method. The following will give you a multiarray of a single master page's found texts. Run it through a function to push it into your array. Clearly, your code is not correct if throwing errors. 

 

var pushToArr = function(foundArr, multiArr) {
   for (var i = 0; i < multiArr.length; i++) { 
       for (var j = 0; j < multiArr[i].length; j++) {
           foundArr.push(multiArr[i][j]);
       }
   }
}

var foundMasterTexts = [];
for (var n = 0; n < pageMaster.length; n++) {
    var aMasterPagesFoundParagraphs = pageMaster[n].textFrames.everyItem().paragraphs.everyItem().findGrep();
    pushToArr(foundMasterTexts, aMasterPagesFoundParagraphs);
}

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 23, 2021 Aug 23, 2021

Copy link to clipboard

Copied

Hi @brianp311 , Thanks a lot for your help, I did change the Script and test it , it hang indesign  a little and changed some random entries and applied the GREP to all Document Pages Realted to Master-A not only the Range (0,2) , Did i do something wrong here ?, and Thanks again

//grep options
app.findChangeGrepOptions.includeMasterPages = true; 
app.findChangeGrepOptions.includeFootnotes = true; 
app.findChangeGrepOptions.includeHiddenLayers = true; 
app.findChangeGrepOptions.includeLockedLayersForFind = true; 
app.findChangeGrepOptions.includeLockedStoriesForFind = true; 

var myDoc = app.activeDocument;
var pgStart = 0; 
var pgEnd =  2;
var pageRange = myDoc.pages.itemByRange(pgStart, pgEnd).textFrames.everyItem().paragraphs.everyItem();
var pageMaster = myDoc.pages.itemByRange(pgStart, pgEnd).appliedMaster;
      
var myFind = "\\(.+?\\)";
var myChange = "BB";

//Clear Grep Prefrences
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = ({findWhat: myFind});
app.changeGrepPreferences.properties = ({changeTo: myChange});
var myFoundTextParagraphs = pageRange.findGrep();
var myFoundTexts = [];

// First nested loop to grab all the found texts
for (var i = 0; i < myFoundTextParagraphs.length; i++) {
    for (var j = 0; j < myFoundTextParagraphs[i].length; j++) {
        myFoundTexts.push(myFoundTextParagraphs[i][j]);
    }
}
//Second nested Loop for MasterPage
var pushToArr = function(foundArr, multiArr) {
   for (var i = 0; i < multiArr.length; i++) { 
       for (var j = 0; j < multiArr[i].length; j++) {
           foundArr.push(multiArr[i][j]);
       }
   }
}

var foundMasterTexts = [];
for (var n = 0; n < pageMaster.length; n++) {
    var aMasterPagesFoundParagraphs = pageMaster[n].textFrames.everyItem().paragraphs.everyItem().findGrep();
    pushToArr(foundMasterTexts, aMasterPagesFoundParagraphs);
}

for (var i = 0; i < myFoundTexts.length; i++) {
    myFoundTexts[i].changeGrep();
for (var i = 0;i < foundMasterTexts.length; i++) {
    foundMasterTexts[i].changeGrep();
}
}
alert("GREP Replaced is "+Number(myFoundTexts.length+myFoundMaster.length)+" Total");
app.findGrepPreferences = app.changeGrepPreferences = null;

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 23, 2021 Aug 23, 2021

Copy link to clipboard

Copied

Your searches are very greedy. As noted earlier, you don't need to search paragraphs; you can just search textFrames, or use Uwe's suggestion to lock everything then search the whole doc. And if you don't want to change the text in the underlying master page, then the text frames would need to be overridden to the applied page. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 23, 2021 Aug 23, 2021

Copy link to clipboard

Copied

Thank you @brianp311 for your reply , i tried the method of override, its fast and good, but i was thinking in different way to keep everything as is to gain new skills 🙂 , i will try to make script wait until finish every loop by dividing them in two function or i will try Uwe's suggestion to lock everything then search the whole doc, thanks again for everything.

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 24, 2021 Aug 24, 2021

Copy link to clipboard

Copied

LATEST

Mr @brianp311 , the Script Work after little tweaks!, and the Greedy search is kept too 🙂 with high performance searching!, here is the code after tweaking :

 

//grep options
app.findChangeGrepOptions.includeMasterPages = true; 
app.findChangeGrepOptions.includeFootnotes = true; 
app.findChangeGrepOptions.includeHiddenLayers = true; 
app.findChangeGrepOptions.includeLockedLayersForFind = true; 
app.findChangeGrepOptions.includeLockedStoriesForFind = true; 

var myDoc = app.activeDocument;
var pgStart = 0; 
var pgEnd =  2;
var pageRange = myDoc.pages.itemByRange(pgStart, pgEnd).textFrames.everyItem().paragraphs.everyItem();
var pageMaster = myDoc.pages.itemByRange(pgStart, pgEnd).appliedMaster;
      
      
var myFind = "\\(.+?\\)";
var myChange = "BB";

//Clear Grep Prefrences
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.properties = ({findWhat: myFind});
app.changeGrepPreferences.properties = ({changeTo: myChange});
var myFoundTextParagraphs = pageRange.findGrep();
var myFoundTexts = [];

// First nested loop to grab all the found texts
for (var i = 0; i < myFoundTextParagraphs.length; i++) {
    for (var j = 0; j < myFoundTextParagraphs[i].length; j++) {
        myFoundTexts.push(myFoundTextParagraphs[i][j]);
    }
}
//Second nested Loop for MasterPage
var pushToArr = function(foundArr, multiArr) {
   for (var k = 0; k < multiArr.length; k++) { 
       for (var l = 0; l < multiArr[k].length; l++) {
           foundArr.push(multiArr[k][l]);
       }
   }
}

var foundMasterTexts = [];
for (var n = 0; n < pageMaster.length; n++) {
    var aMasterPagesFoundParagraphs = pageMaster[n].textFrames.everyItem().paragraphs.everyItem().findGrep();
    pushToArr(foundMasterTexts, aMasterPagesFoundParagraphs);
    //now Change the Grep
    foundMasterTexts[n].changeGrep();

}

for (var i = 0; i < myFoundTexts.length; i++) {
    myFoundTexts[i].changeGrep();
}

alert("GREP Replaced is "+Number(myFoundTexts.length+foundMasterTexts.length)+" Total");
app.findGrepPreferences = app.changeGrepPreferences = null;

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines