Copy link to clipboard
Copied
Hello, first time posting I hope I'm doing this correctly.
Basically, I have a file that requires a text change which is then exported and edited in Photoshop. I recently have started experimenting with Envelope Distorts as it offered me better control over the span of my documents text areas, however when I run my script on the document, it fails to catch any text that is wrapped with an Envelope Distort. I'm assuming it's because the script is searching for textFrames and when part of an Envelope Distort text becomes something else.
Thanks!
Ok, this should do the trick...
Break it and re-make it!
var sel = app.activeDocument.selection;
app.executeMenuCommand ('Release Envelope');
var sel2 = app.activeDocument.selection;
for(var i = 0; i < sel2.length; i++){
if(sel2.typename == "TextFrame"){
sel2.contents = "new text for envelope";
}
}
app.executeMenuCommand ('Make Envelope');
Copy link to clipboard
Copied
Yes, those text frames will be now part of the envelope distort "PluginItem", and I see that the inner text is no longer accessible by script. Maybe you can find a way to apply the envelope distort to text after changing the text content.
Copy link to clipboard
Copied
if you enter isolation mode on the envelope then the text become visible and editable.
you could play with:
app.executeMenuCommand('enterFocus');
app.executeMenuCommand('exitFocus');
but I could not get the above to work.
another option is to have an action to "Toggle Edit Contents"
Copy link to clipboard
Copied
Got it...
app.executeMenuCommand ('Edit Envelope Contents');
Copy link to clipboard
Copied
Qwertyfly...‌ , this seems to work when manually changing the text, but I am not able to have a script see the text frame inside the envelope.
However, I was able to see that variables can be used to change out the text inside an envelope. Then, I tried to see if this is possible the 'quicker' way, by alerting doc.variables[0].pageItems.length, and yet it still said 0. So, there's no referencing the pageItem textframe from the inside-out and trying something like doc.variables[0].pageItems[0].contents = "New text" , unless I am missing something.
So, the more painful way this could be done is by first setting up the file with variables, and binding the variables to appropriate text. Then, save the variable library XML file and make changes in it, and re-import the file to have the changes appear in the text. This may sound even slower than manually changing the text, but actually, after the first set-up step, this all can be done via script. Your script can be set up to just read the XML file and replace variable contents via regexps find & replace, and it can import this file into the illustrator document automatically. Thankfully, if the variables were bound before the envelope was placed, they do update when the XML file is re-imported.
Copy link to clipboard
Copied
Thank you.
This gave me some great leads to search around more for some insight as to how to implement it into the code, but I have been unsuccessful. This is the script I am using:
var active_doc = app.activeDocument;
var search_string = /NAME/gi; // g for global search, remove i to make a case sensitive search
var replace_string = prompt("NAME");
var text_frames = active_doc.textFrames;
if (text_frames.length > 0)
{
for (var i = 0 ; i < text_frames.length; i++)
{
var this_text_frame = text_frames;
var new_string = this_text_frame.contents.replace(search_string, replace_string);
if (new_string != this_text_frame.contents)
{
this_text_frame.contents = new_string;
}
}
}
I've read Illustrator scripting doesn't work as well as it could, I'm wondering if this is one of those cases.
Copy link to clipboard
Copied
Ill have another play.
Will report back‌
Copy link to clipboard
Copied
Oh yes, I forgot one more step of pain for search/replacing the text XML file to update a document in the way I started describing above: the text content would need to be parsed for and then encoded with, an XML string function to make sure special characters are taken care of.
Copy link to clipboard
Copied
Ok, this should do the trick...
Break it and re-make it!
var sel = app.activeDocument.selection;
app.executeMenuCommand ('Release Envelope');
var sel2 = app.activeDocument.selection;
for(var i = 0; i < sel2.length; i++){
if(sel2.typename == "TextFrame"){
sel2.contents = "new text for envelope";
}
}
app.executeMenuCommand ('Make Envelope');
Copy link to clipboard
Copied
In a Mortal Kombat voice: "Well done."
Copy link to clipboard
Copied
Thank you!!
Copy link to clipboard
Copied
‌glad I could help
Copy link to clipboard
Copied
For anyone arriving, like me, nearly 10 years later(!), and finding this answer is still useful, here is an updated version because the forum software slightly mangled @Qwertyfly___'s script. And since I'm here, I've structured it as a function that can set multiple text frames per envelope.
- Mark
/**
* @file Set Envelope Texts.js
*/
(function () {
var doc = app.activeDocument,
item = doc.selection[0];
item = setEnvelopeTexts(item, 'New Text');
})();
/**
* Sets the contents of text frames inside a given
* Envelope item. If there are multiple text frames
* in the envelope, you can supply an Array of Strings
* which will be applied in turn.
*
* Note: the original Envelope will be destroyed
* and a new one created, so this function returns
* a reference to the new one. Also the existing
* selection will be lost.
*
* @author Qwertyfly___ (and parts by m1b)
* @version 2024-07-12
* @param {PluginItem} envelope - the envelope item.
* @param {String|Array<String>} texts - a string or array of strings.
* @returns {PluginItem} - the "new" envelope item.
*/
function setEnvelopeTexts(envelope, texts) {
if (
undefined == envelope
|| 'PluginItem' !== envelope.constructor.name
)
return;
if ('Array' !== texts.constructor.name)
texts = [texts]
app.selection = [];
envelope.selected = true;
app.executeMenuCommand('Release Envelope');
var sel = app.selection;
for (var i = 0; i < sel.length; i++) {
if (0 === texts.length)
break;
if ('TextFrame' === sel[i].constructor.name)
sel[i].contents = texts.shift();
};
app.executeMenuCommand('Make Envelope');
return app.selection[0];
};