Copy link to clipboard
Copied
I've been trying to modify this script to ignore case (so it works with uppercase and lowercase) as well as work when there are line breaks between words. Often some of the longer terms have a line break between them such as:
Arabian
Desert
And I want to still replace the term with my target language (with no line break would be fine).
I've tried modifying the script to work with RegEx but I can't get it to work. Any help would be greatly appreciated.
function FindAndReplaceScript_AllOpenDocuments(){
for(var i=app.documents.length -1; i > -1; i--){
app.documents.activate();
var aDoc = app.documents;
//List of words to replace
var mapObj = {
"Damascus":"ដាម៉ាស",
"Rabbah":"រ៉ាបាត",
"Samaria": "សាម៉ារី",
"Arabian Desert": "ទីរហោស្ថានអារ៉ាប់"
};
var theTF = aDoc.textFrames;
if (theTF.length > 0) {
for (var j = 0 ; j <theTF.length; j++) {
var aTF = theTF
; for (var re in mapObj) {
var newString = aTF.contents.replace(re, mapObj[re])
if (newString != aTF.contents) {
theTF
.contents = newString; }
}
}
}
}
};
FindAndReplaceScript_AllOpenDocuments();
Unfortunately that is not so easy.
I rarely work with object-objects in [JS]
I don't know how to change the keys in object (wordlist). Only that's why I use this cumbersome workaround with a second object.
Hope this helps a little:
...// https://forums.adobe.com/message/10023166#10023166
FindAndReplaceScript_AllOpenDocuments ();
function FindAndReplaceScript_AllOpenDocuments () {
for(var i=app.documents.length -1; i > -1; i--) {
app.documents.activate();
var aDoc = app.documents;
//List of words
Copy link to clipboard
Copied
You may have to use the reg exps to solve this problem.
aTF.contents.replace(new RegExp(re.replace(" ", "[\r\n\s\t]"), "ig"), mapObj[re])
In this attempt, a new RegExp is formed to be the argument for your contents.replace().
A new RegExpt takes arguments of a string-version of a regular expression as well as a string of flags. "ig" has "i" for ignore case and "g" for global.
The arguments to the RegExp have the 'search string' variable with replaced spaces by a regular expression character collection: Arabian[\r\n\s\t]Desert
The idea is to match "Arabian Desert" in the contents with possibility of a single (\r) carriage return, (\n) soft-return, (\s) a space, and (\t) a tab. Hopefully this will work and match the strings as desired!
Copy link to clipboard
Copied
Silly-V wrote
You may have to use the reg exps to solve this problem.
aTF.contents.replace(new RegExp(re.replace(" ", "[\r\n\s\t]"), "ig"), mapObj[re])
In this attempt, a new RegExp is formed to be the argument for your contents.replace().
A new RegExpt takes arguments of a string-version of a regular expression as well as a string of flags. "ig" has "i" for ignore case and "g" for global.
The arguments to the RegExp have the 'search string' variable with replaced spaces by a regular expression character collection: Arabian[\r\n\s\t]DesertThe idea is to match "Arabian Desert" in the contents with possibility of a single (\r) carriage return, (\n) soft-return, (\s) a space, and (\t) a tab. Hopefully this will work and match the strings as desired!
Thanks - this is getting closer.
But it I just realized there are sometimes three spaces in terms like this:
Sea ofGalilee
I tried to modify the script like this (placing the \s in the search term instead of in the RegEx):
function FindAndReplaceScript_AllOpenDocuments(){
for(var i=app.documents.length -1; i > -1; i--){
app.documents.activate();
var aDoc = app.documents;
//List of words to replace
var mapObj = {
"Sea\sof\sGalilee":"សមុទ្រកាលីឡេ",
"Bethel":"បេត-អែល"
};
var theTF = aDoc.textFrames;
if (theTF.length > 0) {
for (var j = 0 ; j <theTF.length; j++) {
var aTF = theTF
; for (var re in mapObj) {
var newString = aTF.contents.replace(new RegExp(re.replace(" "), "i"), mapObj[re])
if (newString != aTF.contents) {
theTF
.contents = newString; }
}
}
}
}
};
FindAndReplaceScript_AllOpenDocuments();
But it still doesn't find the term. I'll keep working on it. Any ideas?
Copy link to clipboard
Copied
How about this, change:
new RegExp(re.replace(" ", "[\r\n\s\t]")
To
new RegExp(re.replace(/\s/g, "[\r\n\s\t]")
Copy link to clipboard
Copied
Still doesn't work...very strange. And now it isn't even replacing terms with one space (like "Dead Sea").
Copy link to clipboard
Copied
Okay, with my latest suggestion, can you try with escaping the backlashes:
var rx = new RegExp(str.replace(/\s/g, "[\\r\\n\\s\\t]"), "gi");
Copy link to clipboard
Copied
That worked!
Thank you so much @Silly-V!
Copy link to clipboard
Copied
Hi Silly-V,
you are near.
Be sure in regex \r \n and \t is included in \s
But sometimes Illustrator scripting don't like \n
Try to avoid this line break in your documents.
That's why you only need
function FindAndReplaceScript_AllOpenDocuments() {
for(var i=app.documents.length -1; i > -1; i--) {
app.documents.activate();
var aDoc = app.documents;
//List of words to replace
var mapObj = {
"Lorem ipsum dolor":"TEXT#1",
"consectetuer adipiscing elit":"TEXT#2",
"sed diam nonummy":"TEXT#3",
};
var theTF = aDoc.textFrames;
if (theTF.length > 0) {
for (var j = 0 ; j <theTF.length; j++) {
var aTF = theTF
; for (var re in mapObj) {
var newString = aTF.contents.replace(new RegExp(re.replace(/ /g, "[\\s]"), "gi"), mapObj[re]);
if (newString != aTF.contents) {
theTF
.contents = newString; }
}
}
}
}
};
FindAndReplaceScript_AllOpenDocuments();
Your regex knowledgebase will be better and better.
Have fun
Copy link to clipboard
Copied
One more question. How would I go about changing the regex to only match whole words? Currently it will find "ur" in "captured" and replace the ur with Khmer (I'm working on maps of the Ancient Near East): captអ៊ើរed
But I'd rather it let partial matches go and only replace whole words. Is that possible?
Copy link to clipboard
Copied
Would making it case-sensitive solve this?
Copy link to clipboard
Copied
The problem is sometimes some terms are all caps (like ARABIAN DESERT and Arabian Desert) and I want to replace both (my target language has no capitalization so I replace the same term both times regardless). Any way around that?
Copy link to clipboard
Copied
Okay, I will use the site regexpal.com to test additions to our regular expression. Can you, say, provide me a sample paragraph which contains one of these problematic word scenarios?
Copy link to clipboard
Copied
Yeah, I can get it to work in a non-illustrator environment see here https://regex101.com/r/Ly13ZO/1
The issue is I can't figure out how to use \b in the script...
Copy link to clipboard
Copied
Please show us your
List of words to replace
- //List of words to replace
- var mapObj = {
- "Lorem ipsum dolor":"TEXT#1",
- "consectetuer adipiscing elit":"TEXT#2",
- "sed diam nonummy":"TEXT#3",
- };
We need exact examples.
Copy link to clipboard
Copied
Sure, here's the script as I have it now (with some words redacted as the list is very long):
function FindAndReplaceScript_AllOpenDocuments(){
for(var i=app.documents.length -1; i > -1; i--){
app.documents.activate();
var aDoc = app.documents;
//List of words to replace
var mapObj = {
"Arabian Desert":"ទីរហោស្ថានអារ៉ាប់",
"Damascus":"ដាម៉ាស",
"Dead Sea":"សមុទ្រស្លាប់",
"On":"អូ ",
"Ur":"អ៊ើរ"
};
var theTF = aDoc.textFrames;
if (theTF.length > 0) {
for (var j = 0 ; j <theTF.length; j++) {
var aTF = theTF
; for (var re in mapObj) {
var newString = aTF.contents.replace(new RegExp(re.replace(/ /g, "[\\s]"), "gi"), mapObj[re]);
//var newString = aTF.contents.replace(re, mapObj[re])
if (newString != aTF.contents) {
theTF
.contents = newString; }
}
}
}
}
};
FindAndReplaceScript_AllOpenDocuments();
Then make a document with this text:
ARABIAN DESERT
Arabian Desert
Captured
UR
ur
Ur
deception
The desired result would be that "Captured" and "deception" would be left alone, while the others would be replaced.
I've tried adding a word boundary \b but can't get it to work in the regex code in Illustrator. I can get it to work in plain regex though.
Copy link to clipboard
Copied
I've tried this, but I can't seem to get InDesign to understand \b (and probably because I don't understand!).
RegExp(re.replace(/\b[ ]\b/g, "[\\s]"), "gi"), mapObj[re]);
Copy link to clipboard
Copied
Unfortunately that is not so easy.
I rarely work with object-objects in [JS]
I don't know how to change the keys in object (wordlist). Only that's why I use this cumbersome workaround with a second object.
Hope this helps a little:
// https://forums.adobe.com/message/10023166#10023166
FindAndReplaceScript_AllOpenDocuments ();
function FindAndReplaceScript_AllOpenDocuments () {
for(var i=app.documents.length -1; i > -1; i--) {
app.documents.activate();
var aDoc = app.documents;
//List of words to replace
/*
var mapObj = {
"Arabian Desert":"ទីរហោស្ថានអារ៉ាប់",
"Damascus":"ដាម៉ាស",
"Dead Sea":"សមុទ្រស្លាប់",
"On":"អូ ",
"Ur":"អ៊ើរ"
};
*/
var mapObj = {
"Arabian Desert":"AD_replaced_AD",
"Damascus":"D_replaced_D",
"Dead Sea":"DS_replaced_DS",
"On":"O_replaced_O ",
"Ur":"U_replaced_U"
};
var mapObj2 ={};
mapObj2 = createObjBasedOnFirstObj (mapObj, mapObj2);
var theTF = aDoc.textFrames;
if (theTF.length > 0) {
for (var j = 0 ; j <theTF.length; j++) {
var aTF = theTF
; //for (var re in mapObj) {
for (var re in mapObj2) {
//var newString = aTF.contents.replace(new RegExp(re.replace(/ /g, "[\\s]"), "gi"), mapObj2[re]);
var newString = aTF.contents.replace(new RegExp(re, "gi"), mapObj2[re]);
if (newString != aTF.contents) {
theTF
.contents = newString; }
}
}
}
}
};
function createObjBasedOnFirstObj (obj1, obj2) {
// regards pixxxel schubser
for (var re0 in obj1 /*mapObj*/) {
var re1 = re0.split(' ');
for (k = 0; k <re1.length; k++) {
re1
= "\\b"+re1 +"\\b"; }
re1 = re1.join("\\s");
obj2[re1] = obj1[re0];
}
return obj2;
};
Have fun
Copy link to clipboard
Copied
Thanks! That does the trick. Funny how complex it has to be But now everything is working great!