Copy link to clipboard
Copied
Hello Everyone,
I use a lot of Find/Change in my routine work to speed up my work. I also make use of ChainGREP JavaScript to collect all my GREP queries in one single JavaScript. The only problem with that Script is that it searches only once. So, if there’s something in the text that is occurring more than one time, then I have to run the script again and again until I guess that all the instances would have been replaced.
A similar thing happens with this code below. I have to run the JavaScript again and again until all the duplicate entries are gone.
This example JavaScript (created using ChainGREP) has only one GREP Find/Change Query. Three are other scripts with me with multiple GREP Find/Change Queries. If I get to know the loop, then I'll try to add it to my other Find/Change queries.
Can someone, add a loop to the JavaScript so that it can search again and again until the last occurrence is replaced.
main();
function main() {
if (app.layoutWindows.length == 0) return;
if (app.selection.length != 1 || !app.selection[0].hasOwnProperty('changeGrep')) {
alert('Please select only one textframe or text range!');
return;
}
var changeObject = app.selection[0].parentStory;
if (changeObject.hasOwnProperty('characters') && changeObject.characters.length == 0) return;
var doc = app.documents[0];
var style;
var options = app.findChangeGrepOptions.properties;
app.findGrepPreferences = NothingEnum.NOTHING;
app.changeGrepPreferences = NothingEnum.NOTHING;
// Query [[mc2001_Remove Duplicates]] -- If you delete this comment you break the update function
try {
app.findChangeGrepOptions.properties = ({includeFootnotes:true, kanaSensitive:true, widthSensitive:true});
app.findGrepPreferences.properties = ({findWhat:"(^.+\\n.+?,)(.+\\r)\\1(.+\\r)"});
app.changeGrepPreferences.properties = ({changeTo:"$1$2", fillColor:"C=75 M=5 Y=100 K=0"});
changeObject.changeGrep();
} catch (e) {alert(e)}
app.findChangeGrepOptions.properties = options;
app.findGrepPreferences = NothingEnum.NOTHING;
app.changeGrepPreferences = NothingEnum.NOTHING;
};
function getStyleByString(root, string, property) {
stringResult = string.match (/^(.*?[^\\]):(.*)$/);
var cStyleName = (stringResult) ? stringResult[1] : string;
cStyleName = cStyleName.replace (/\\:/g, ':');
remainingString = (stringResult) ? stringResult[2] : '';
var newProperty = (stringResult) ? property.replace(/s$/, '') + 'Groups' : property;
var cStyle = root[newProperty].itemByName(cStyleName);
if (remainingString.length > 0 && cStyle.isValid) cStyle = getStyleByString (cStyle, remainingString, property);
return cStyle;
};
Thanks.
Masood,
What Peter implied is tha,t generally it should not be needed to repeat the grep as it can be handled in the grep expression itself, an example being the use of + in the double space case. Now if you absolutely want to loop then give the following a try
function grepSearch(f,c){
app.findGrepPreferences.findWhat=NothingEnum.NOTHING
app.changeGrepPreferences.changeTo=NothingEnum.NOTHING
app.findGrepPreferences.findWhat = f;
app.changeGrepPreferences.changeTo = c;
do{
var a =...
Copy link to clipboard
Copied
You might try something like this where the grep find and change preferences are setup in a function, and then you run the function on the entire document—app.activeDocument.changeGrep()—for each find and change. So this example would run 3 searches to remove extra white space:
//replaces multiple tabs with single tab
grepSearch("\\t+", "\\t");
//removes any white space at the start of a paragraph including multiple returns
grepSearch("^\\s*", "")
//replaces multiple spaces with one space
grepSearch("\\p{zs}{2,}", "\\s")
function grepSearch(f,c){
app.findGrepPreferences.findWhat=NothingEnum.NOTHING
app.changeGrepPreferences.changeTo=NothingEnum.NOTHING
app.findGrepPreferences.findWhat = f;
app.changeGrepPreferences.changeTo = c;
app.activeDocument.changeGrep( true )
}
You could build other parameters into the function, this would replace plus change the fill color:
grepSearch("Hello", "Hello yourself", "ProcessM");
grepSearch("Goodbye", "Ciao", "ProcessC");
//text to find, change text, change fill color swatch name
function grepSearch(f,c,fc){
app.findGrepPreferences.findWhat=NothingEnum.NOTHING
app.changeGrepPreferences.changeTo=NothingEnum.NOTHING
app.findGrepPreferences.findWhat = f;
app.changeGrepPreferences.changeTo = c;
app.changeGrepPreferences.fillColor = fc;
app.activeDocument.changeGrep( true )
}
Copy link to clipboard
Copied
Hi Rob,
Many thanks for the suggestions. I tried your first code and it is executing all the Find/Change queries. However, I think I didn't explain the requirements very well.
I want to add a loop to this code.
For example, if I run the below script, it will replace the first double spaces to a single space. So to remove all the double spaces, I have to run the script again and again until all the instances of double spaces are replaced by a single space. I have just taken an example of a double space here, my queries are bit complex.
Can you please add a loop to this code so that it runs again and again until all the instances are done.
//Replaces Double Spaces to Single Space
grepSearch(" "," ");
/*//Removes Duplicates
grepSearch("(^.+\\n.+?,)(.+\\r)\\1(.+\\r)","$1$2");
*/
/*Add multiple queries like this:
//removes any white space at the start of a paragraph including multiple returns
grepSearch("^\\s*", "")
//replaces multiple spaces with one space
grepSearch("\\p{zs}{2,}", "\\s")
*/
function grepSearch(f,c){
app.findGrepPreferences.findWhat=NothingEnum.NOTHING
app.changeGrepPreferences.changeTo=NothingEnum.NOTHING
app.findGrepPreferences.findWhat = f;
app.changeGrepPreferences.changeTo = c;
app.activeDocument.changeGrep( true )
}
alert("Duplicates Removed!\rRun the Script again and again and check manually for any duplicte entries.");
Copy link to clipboard
Copied
Hi Masood,
It seems there is surely a disconnect in what you want and what you are explaining. The example Rob gave, will remove all the instances of the double space to a single space with just a single run of the script. If you use the following modified version of the script, it will alert the no. of changes made
grepSearch(" "," ");
function grepSearch(f,c){
app.findGrepPreferences.findWhat=NothingEnum.NOTHING
app.changeGrepPreferences.changeTo=NothingEnum.NOTHING
app.findGrepPreferences.findWhat = f;
app.changeGrepPreferences.changeTo = c;
var a = app.activeDocument.changeGrep( true )
alert(a.length + " instances replaced")
}
I have created a demo video showing what happens using the Find/Change dialog and also the script. The document has three instances of double space, I find/change them using the Find/Change dialog, then undo the operation and run Rob's script example, it also does the find/change in a single run. To prove it, I again try to find the double space in the document and I get none.
-Manan
Copy link to clipboard
Copied
What Mamood probably means is that after replacing two spaces with one, there are still some two-space strings left. So what he really wants is to replace strings of two or more space with a single space:
grepSearch(" +"," ");
P.
Copy link to clipboard
Copied
Hi Peter, I know the use of a repeat metacharacter. As I said in my first post that I want to add a loop to my Find/Change script.
I also said that: "I have just taken an example of a double space here, my queries are bit complex." like this:
grepSearch("(^.+\\n.+?,)(.+\\r)\\1(.+\\r)","$1$2");In simple plain language. I want my script to run again and again until it finds zero instance.
Hope I'm clear now.
Copy link to clipboard
Copied
No, Masood, you're not really clear. You replied that the multiple-space example was just a simple one to show what you mean, and that your real data are more complex. Then in reply to Manan you show an example that suggests that you're interested in the spaces after all.
So tell us what you want to do. "I want to add a loop " is not an answer, because maybe you don't need a loop. Your grep expression
"(^.+\\n.+?,)(.+\\r)\\1(.+\\r)","$1$2")
looks for a line ending in a forced line break followed by some characters and a comma -- that's var 1. Then you continue to match characters to the end of the paragraph -- that's var 2. In your example, so far you matched "40502\\nAndover Dr 325," (var 1) and "[lots of spaces]Kant . . . $1,000,000." (var 2).
Then you try to match var 1 again (\1), followed by the rest of the paragraph.
Still not clear to me what you want to achieve here. Remove identical entries? Parts of identical entries? Please explain. Before and after illustrations would be useful.
P.
Copy link to clipboard
Copied
Thanks, Manan for the video and adding the alert. I watched the video and noticed that there were only three instances with double spaces, but if you add more spaces, eg 5+, and run the script again, you'll see what I'm trying to say.
In my example document, I had to run the script five times to see the message "0 instances replaced".
Copy link to clipboard
Copied
Ahh, this seems to be the situation that Peter mentioned, change the function call with what he sent, i.e. the complete script would be as follows
grepSearch(" +"," ");
function grepSearch(f,c){
app.findGrepPreferences.findWhat=NothingEnum.NOTHING
app.changeGrepPreferences.changeTo=NothingEnum.NOTHING
app.findGrepPreferences.findWhat = f;
app.changeGrepPreferences.changeTo = c;
var a = app.activeDocument.changeGrep( true )
alert(a.length + " instances replaced")
}
Try it and share the test results, if it still does not work then share a sample document with the issue.
-Manan
Copy link to clipboard
Copied
Sorry, Manan. I replied to Peter's suggestion.
Copy link to clipboard
Copied
Masood,
What Peter implied is tha,t generally it should not be needed to repeat the grep as it can be handled in the grep expression itself, an example being the use of + in the double space case. Now if you absolutely want to loop then give the following a try
function grepSearch(f,c){
app.findGrepPreferences.findWhat=NothingEnum.NOTHING
app.changeGrepPreferences.changeTo=NothingEnum.NOTHING
app.findGrepPreferences.findWhat = f;
app.changeGrepPreferences.changeTo = c;
do{
var a = app.activeDocument.changeGrep( true )
}while(a.length != 0);
app.findGrepPreferences.findWhat=NothingEnum.NOTHING
app.changeGrepPreferences.changeTo=NothingEnum.NOTHING
}
-Manan
Copy link to clipboard
Copied
Hi Manan, That's exactly, what I was looking for. MILLION thanks.
Thanks Rob, for giving the idea to start from. Much appreciated.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more