Copy link to clipboard
Copied
Dear forum,
I encountered this problem while writing a complex script that imitates the find-change dialog. Its purpose is to find RegExes at the beginning and/or end of lines (which InDesign doesn’t allow).
Let’s illustrate my issue with an example. (I attached a test document below).
I simplified things to make my question as clear as possible.
First, I set find what to ra\> (ra at the end of a word) and change format to, say, blue color.
And run this script:
main();
function main() {
var txt, changed,
doc = app.activeDocument,
found = doc.findGrep(false);
for (var i = 0; i < found.length; i++) {
txt = found[i];
changed = txt.changeGrep();
$.writeln( i + " - " + changed.length);
}
}
It works as expected: all 6 found items are changed one by one:
Now let’s change find what to a regex with look behind: (?<=illo)ra
And run the script again. As before, 6 items were found, but were not changed:
When I change it manually in InDesign one by one, it works.
The same happens with regexes using look ahead and /K, for example:
Any ideas why this happens?
Thanks for your replies, Uwe and Brian!
It seems I found a workaround: reapply findWhat to the found text and after that apply change:
main();
function main() {
var txt, changed,
doc = app.activeDocument,
found = doc.findGrep(false);
for (var i = 0; i < found.length; i++) {
txt = found[i];
app.findGrepPreferences.findWhat = txt.contents;
changed = txt.changeGrep();
$.writeln( i + " - " + changed.length);
}
}
Hi Kasyan,
Any ideas why this happens?
If you analyze your procedure more closely you'll realize this is not a bug. Indeed, each found Text considered separately no longer satisfies the lookbehind assertion! So your command changed=txt.changeGrep(); has no effect.
Take a look at the following example:
The GREP I use here is `(?<=e)qu.` so it captures every `qu.` pattern iff it is prefixed by 'e'. The frame above shows the final result of Find/Change executed from InDesign—the qui, quo, qua matchi
...Copy link to clipboard
Copied
Take a look at this reply here:
https://community.adobe.com/t5/indesign-discussions/positive-lookahead-not-working/m-p/8730391#M3217...
Marc also wrote this: GREP ≠ ExtendScript RegExp ≄ JavaScript RegExp
Copy link to clipboard
Copied
Thanks, Jean-Claude! I will study this post.
Copy link to clipboard
Copied
Hi Jean-Claude,
but in Kasyan's sample we do not deal with ExtendScript's RegExp or JavaScript RegExp.
It's the GREP implementation with InDesign's ExtendScript.
Tested Kasyan's case and I see the same issue with my German InDesign 2022 on Windows 10.
The thing that does work is, change all found instances in one go:
app.documents[0].changeGrep();
But perhaps that's not the thing Kasyan is after ?!
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
I think it has something to do with how the value of the Text for your find is only ra, but changeGrep is probably still trying to execute a change based on a findWhat with the lookbehind. That's why doc.changeGrep() works, but changeGrep() on a Text object of only "ra" would not. A workaround would be to take the Text object and manually apply the change features to it. Basically, I think .changeGrep() still executes its own .findGrep() on the object it's being called on, if that makes sense. It kind of has to, since you can call .changeGrep() without calling .findGrep() first.
Copy link to clipboard
Copied
Thanks for your replies, Uwe and Brian!
It seems I found a workaround: reapply findWhat to the found text and after that apply change:
main();
function main() {
var txt, changed,
doc = app.activeDocument,
found = doc.findGrep(false);
for (var i = 0; i < found.length; i++) {
txt = found[i];
app.findGrepPreferences.findWhat = txt.contents;
changed = txt.changeGrep();
$.writeln( i + " - " + changed.length);
}
}
Copy link to clipboard
Copied
Good solution!
Copy link to clipboard
Copied
Hi Brian,
interesting deliberations.
Of course we can do the following to check if the found first word of a found text is at the beginning of a line of text:
main();
function main()
{
var txt, changed,
doc = app.activeDocument,
found = doc.findGrep(false);
for (var i = 0; i < found.length; i++)
{
if( found[i].words[0] == found[i].lines[0].words[0] )
{
$.writeln( i +" - "+ found[i].words[0].contents );
}
}
}
But what next?
And here I'm not sure what the user's expectation is for Kasyan's main script:
Should the change be applied as the user has defined it in the GREP Find/Change GUI of InDesign?
How would you do this now when found[i].changeGrep() fails?
Should we go to app.changeGrepPreferences.properties and check every value and then apply it to the found text?
Regards,
Uwe Laubender
( ACP )
//EDITED
Copy link to clipboard
Copied
Hi Kasyan,
Any ideas why this happens?
If you analyze your procedure more closely you'll realize this is not a bug. Indeed, each found Text considered separately no longer satisfies the lookbehind assertion! So your command changed=txt.changeGrep(); has no effect.
Take a look at the following example:
The GREP I use here is `(?<=e)qu.` so it captures every `qu.` pattern iff it is prefixed by 'e'. The frame above shows the final result of Find/Change executed from InDesign—the qui, quo, qua matching texts are styled in blue.
Now, what are the Text strings resulting from doc.findGrep(false)? The alert box shows them, based on:
(function( doc,found,i,txt,changed)
{
doc = app.properties.activeDocument;
found = doc.findGrep(false);
/*
for( var i = 0; i < found.length; i++ )
{
txt = found[i];
changed = txt.changeGrep();
$.writeln( i + " - " + changed.length);
}
*/
// Display the `found` strings.
// ---
for
(
i=found.length ;
i-- ;
found[i]=found[i].texts[0].contents
);
alert( found.join('\r') );
})();
You can see that each found[i] as such—namely “qui”, “quo”, “qua”—is not preceded by 'e'. This explains why found[i].changeGrep() has no effect.
Hope that helps.
Marc
Copy link to clipboard
Copied
Hi Marc,
Thank you very much for your explanation! Now it's clear to me.
Sorry for my late reply! I just saw your answer.
Copy link to clipboard
Copied
Forgot to mention: I've already published the first version of the script I mentioned in the original post and continue working on it.