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

Using an Action to run JavaScript that runs another Action... or other solutions?

Community Beginner ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

Greatings! I've recently started teaching myself JavaScript for Illustrator and the community has been a vital resource, thank you!

 

My real goal is to flip everything 180 degrees if its required. When selecting, grouping, and trasforming/rotating everything Ive run into issues when Clipping Masks and Placed Items are invovled. The newest method I have tried works prefectly besides this issue. 

 

I am having issues running an action from a script that is initated by another action. Is it possible? I want to be able to run the script with a hotkey, which so far seems to require it to run from an action. I also want the script to run another action should some conditions be met. 

 

Draging and dropping the .jsx file onto Illustrator seems to run the action, as the art is selected and deselected, but not rotated as it should be. Not so worried about this.

 

Going to (File -> Scripts) and running from a preloaded script or a script that was selected from (.->Other Scripts) preforms the action that is called with no issues.

 

Simplified Version:

1. Action (All In One) runs (All_In_One.jsx). 

2. (All_In_One.jsx) contains (app.doScript("Flip Everything", "My Actions");)

3. Illustrator stops responding.

 

Below is the full version of code. The code also "talks" with Maco Express Pro for other functions (such as flipping it, currently) via text doucuments created and read between them. Any new tips and tricks are appreciated!

 

//Creates registration marks (if applicable) and labels including known information.

//Please Note: Some variable names have been changed for posting. Some parts may not function as anticipated because of string length. Specificly: MainClient info and OtherTag info.

//Check for a single artboard.
if (app.activeDocument.artboards.length == 1) {

//Only 1 Artboard was detected.
// Define Variables.
var active_Doc = app.activeDocument;
var file_Name = active_Doc.name;
var file_Name_Large = file_Name.toUpperCase();
var file_Path = String(active_Doc.path);
var entire_Name = String(active_Doc.fullName);
var artboard_Size = "None Selected"
var chest_Placement = 0;
var flip_Art = "No";
var bag_On_DTS = "No";
var problem_Flipping = "No";

//Discover ArtboarSize, Client, and PO. Save the file.
//Discover Artboard Size. Read 1st line of text document.

if (file_Name.indexOf("LTS-A.ai") !== -1){
var artboard_Size = "LTS-A";
}

if (file_Name.indexOf("LTS-M.ai") !== -1){
var artboard_Size = "LTS-M";
}

if (file_Name.indexOf("DTS-A.ai") !== -1){
var artboard_Size = "DTS-A";
}

//Read File Input for artboard_Size.
if (artboard_Size == "None Selected") {
var artboard_Text_File = new File(Folder.desktop + "/abVariable.txt");
artboard_Text_File.open();
var artboard_Size = artboard_Text_File.readln("r");
artboard_Text_File.close();
var artboard_Size = artboard_Size.toUpperCase();

//Get Direct Input for artboard_Size.
if (artboard_Size !== "LTS-A" && artboard_Size !== "LTS-M" && artboard_Size !== "DTS-A") {
var artboard_Size = prompt("Enter artboard_Size (LTS-A, LTS-M, or DTS-A):")
var artboard_Size = artboard_Size.toUpperCase();
}
}

//Check for correct style.
if (artboard_Size == "LTS-A" || artboard_Size == "LTS-M" || artboard_Size == "DTS-A") {

//Set Artboard to DTS-A, LTS-M, or LTS-A.
if (artboard_Size == "LTS-A") {
var ab_Width = 1296;
var ab_Height = 1584;
var flip_Art = "Yes";
}
if (artboard_Size == "LTS-M") {
var ab_Width = 1116;
var ab_Height = 1242;
}
if (artboard_Size == "DTS-A") {
var ab_Width = 1152;
var ab_Height = 1440;
}


var text_Client = "text_Client";
var text_PO = "NumbersHere";
var start_Index = file_Path.indexOf("Client%20Folder");
if (start_Index !== -1){
var text_Client = "Main Client";
var start_Index = start_Index + 13;
var text_PO = file_Path.substring(start_Index);
if (file_Name.indexOf("LTS-A") == -1 && file_Name.indexOf("LTS-M") == -1 && file_Name.indexOf("DTS-A") == -1){
var entire_Name = entire_Name.replace(".ai", "_" + artboard_Size + ".ai");
var new_Saved_File = File(entire_Name);
active_Doc.saveAs(new_Saved_File);
var file_Name = active_Doc.name;
}
}
else{

//Get Client information. Read 1st line of text document.
var client_Text_File = new File(Folder.desktop + "/clientVariable.txt");
client_Text_File.open();
var text_Client = client_Text_File.readln("r");
client_Text_File.close();
if (text_Client == "") {
var text_Client = prompt("Enter Client:");
}

//Get PO information. Read 1st line of text document.
var po_Text_File = new File(Folder.desktop + "/poVariable.txt");
po_Text_File.open();
var text_PO = po_Text_File.readln("r");
po_Text_File.close();
if (text_PO == "") {
var text_PO = prompt("Enter PO:");
}
if (file_Name.indexOf("LTS-A") == -1 && file_Name.indexOf("LTS-M") == -1 && file_Name.indexOf("DTS-A") == -1){
var new_file_Name = file_Name_Large.replace("_BOARD.AI", "_" + artboard_Size + ".ai");
var new_file_Name = new_file_Name.replace("-BOARD.AI", "_" + artboard_Size + ".ai");
var new_file_Path = file_Path.replace("BOARDS", "FINAL");
var new_file_Path = new_file_Path.replace("BOARD", "FINAL");
var new_Saved_File = File(new_file_Path + "/" + new_file_Name);
active_Doc.saveAs(new_Saved_File);
var file_Name = active_Doc.name;
}
}

//Delete All Unused Swatches Action. (Causes crash?)
//app.doScript ("Delete Swatches", "My Actions");

//Get Placement information. Read 1st line of text document.
var placement_Text_File = new File(Folder.desktop + "/placementVariable.txt");
placement_Text_File.open();
var text_Placement = placement_Text_File.readln("r");
placement_Text_File.close();
if (text_Placement !== "") {
var text_Placement = text_Placement.toUpperCase();
if (text_Placement == "LEFTCHEST" || text_Placement == "LEFT_CHEST" || text_Placement == "LC") {
var text_Placement = "LEFT CHEST";
}
if (text_Placement == "RIGHTCHEST" || text_Placement == "RIGHT_CHEST" || text_Placement == "RC") {
var text_Placement = "RIGHT CHEST";
}
if (text_Placement == "LEFTSLEEVE" || text_Placement == "LEFT_SLEEVE" || text_Placement == "LS") {
var text_Placement = "LEFT SLEEVE";
}
if (text_Placement == "RIGHTSLEEVE" || text_Placement == "RIGHT_SLEEVE" || text_Placement == "RS") {
var text_Placement = "RIGHT SLEEVE";
}
if (text_Placement == "LEFTLEG" || text_Placement == "LEFT_LEG" || text_Placement == "LLEG") {
var text_Placement = "LEFT LEG";
}
if (text_Placement == "RIGHTLEG" || text_Placement == "RIGHT_LEG" || text_Placement == "RLEG") {
var text_Placement = "RIGHT LEG";
}
if (text_Placement == "LEFTHIP" || text_Placement == "LEFT_HIP" || text_Placement == "LHIP") {
var text_Placement = "LEFT HIP";
}
if (text_Placement == "RIGHTHIP" || text_Placement == "RIGHT_HIP" || text_Placement == "RHIP") {
var text_Placement = "RIGHT HIP";
}
if (text_Placement == "LOCKERPATCH" || text_Placement == "LOCKER_PATCH" || text_Placement == "LP") {
var text_Placement = "LOCKER PATCH";
}
}

else {
//Discover Placements.
var text_Placement = "PlacementHere";

//Fronts.
if (file_Name_Large.indexOf("FRONT") !== -1) {
var text_Placement = "FULL FRONT";
}

//Backs.
if (file_Name_Large.indexOf("BACK") !== -1) {
var text_Placement = "FULL BACK";
}

//Locker Patch.
if (file_Name_Large.indexOf("LOCKERPATCH") !== -1 || file_Name_Large.indexOf("LOCKER_PATCH") !== -1 || file_Name_Large.indexOf("LP") !== -1) {
var text_Placement = "LOCKER PATCH";
}

//Left Chests.
if (file_Name_Large.indexOf("LEFTCHEST") !== -1 || file_Name_Large.indexOf("LEFT_CHEST") !== -1 || file_Name_Large.indexOf("LC") !== -1) {
var text_Placement = "LEFT CHEST";
}
//Right Chests.
if (file_Name_Large.indexOf("RIGHTCHEST") !== -1 || file_Name_Large.indexOf("RIGHT_CHEST") !== -1 || file_Name_Large.indexOf("RC") !== -1) {
var text_Placement = "RIGHT CHEST";
}

//Sleeves.
if (file_Name_Large.indexOf("SLEEVES") !== -1) {
var text_Placement = "SLEEVES";
}

// Left Sleeves.
if (file_Name_Large.indexOf("LEFTSLEEVE") !== -1 || file_Name_Large.indexOf("LEFT_SLEEVE") !== -1 || file_Name_Large.indexOf("LS") !== -1) {
var text_Placement = "LEFT SLEEVE";
}

//Right Sleeves.
if (file_Name_Large.indexOf("RIGHTSLEEVE") !== -1 || file_Name_Large.indexOf("RIGHT_SLEEVE") !== -1 || file_Name_Large.indexOf("RS") !== -1) {
var text_Placement = "RIGHT SLEEVE";
}

//Left Legs.
if (file_Name_Large.indexOf("LEFTLEG") !== -1 || file_Name_Large.indexOf("LEFT_LEG") !== -1 || file_Name_Large.indexOf("LLEG") !== -1) {
var text_Placement = "LEFT LEG";
}

//Right Legs.
if (file_Name_Large.indexOf("RIGHTLEG") !== -1 || file_Name_Large.indexOf("RIGHT_LEG") !== -1 || file_Name_Large.indexOf("RLEG") !== -1) {
var text_Placement = "RIGHT LEG";
}

//Left Hips.
if (file_Name_Large.indexOf("LEFTHIP") !== -1 || file_Name_Large.indexOf("LEFT_HIP") !== -1 || file_Name_Large.indexOf("LHIP") !== -1) {
var text_Placement = "LEFT HIP";
}

//Right Hips.
if (file_Name_Large.indexOf("RIGHTHIP") !== -1 || file_Name_Large.indexOf("RIGHT_HIP") !== -1 || file_Name_Large.indexOf("RHIP") !== -1) {
var text_Placement = "RIGHT HIP";
}

//Bags.
if (file_Name_Large.indexOf("BAG") !== -1) {
var text_Placement = "BAG";
}

//Pockets.
if (file_Name_Large.indexOf("POCKET") !== -1) {
var text_Placement = "POCKET";
}
//Hats.
if (file_Name_Large.indexOf("HAT") !== -1) {
var text_Placement = "HAT";
}
}
if (text_Placement.indexOf("SLEEVE") !== -1 || text_Placement.indexOf("LEG") !== -1 || text_Placement.indexOf("BAG") !== -1 || text_Placement.indexOf("POCKET") !== -1 || text_Placement.indexOf("HIP") !== -1 || text_Placement.indexOf("HAT") !== -1) {
var flip_Art = "Yes";
}
if (text_Placement.indexOf("LEFT") !== -1 && text_Placement.indexOf("CHEST") !== -1){
var chest_Placement = -288;
}
if (text_Placement.indexOf("RIGHT") !== -1 && text_Placement.indexOf("CHEST") !== -1){
var chest_Placement = 288;
}

//Detect White.
var white_Index = 0;
for (white_Index = 0; white_Index < active_Doc.swatches.length; white_Index++) {
if (active_Doc.swatches[white_Index].name == "White") {
active_Doc.swatches[white_Index].remove();
break;
}
}

//Detect Black.
var black_Index = 0;
for (black_Index = 0; black_Index < active_Doc.swatches.length; black_Index++) {
if (active_Doc.swatches[black_Index].name == "Black") {
active_Doc.swatches[black_Index].remove();
break;
}
}

//Detect White (ind. w/ 100% Magenta).
var white_IWM_Index = 0;
for (white_IWM_Index = 0; white_IWM_Index < active_Doc.swatches.length; white_IWM_Index++) {
if (active_Doc.swatches[white_IWM_Index].name == "White ind. w/ Magenta") {
active_Doc.swatches[white_IWM_Index].name = "White Ink";
break;
}
}

//Detect Black Swatch.
var black_Swatch_Index = 0;
for (black_Swatch_Index = 0; black_Swatch_Index < active_Doc.swatches.length; black_Swatch_Index++) {
if (active_Doc.swatches[black_Swatch_Index].name == "Black Swatch") {
active_Doc.swatches[black_Swatch_Index].name = "Black Ink";
break;
}
}

//Detect Registration Swatch.
var reg_Swatch_Index = 0;
for (reg_Swatch_Index = 0; reg_Swatch_Index < active_Doc.swatches.length; reg_Swatch_Index++) {
if (active_Doc.swatches[reg_Swatch_Index].name.indexOf("[Registration]") !== -1) {
break;
}
}

//Detect None Swatch.
var none_Swatch_Index = 0;
for (none_Swatch_Index = 0; none_Swatch_Index < active_Doc.swatches.length; none_Swatch_Index++) {
if (active_Doc.swatches[none_Swatch_Index].name.indexOf("[None]") !== -1) {
break;
}
}

//Choose Font and Size.
var font_Number = 0;
var chosen_Font = app.textFonts[font_Number];
for (font_Number = 0; font_Number < app.textFonts.length; font_Number ++) {
if (app.textFonts[font_Number].name == "ArialNarrow-Bold") {
var chosen_Font = app.textFonts[font_Number];
break;
}
}
var chosen_Size = 12;
//Flip Art using Flip Everything Action.
if (flip_Art == "Yes") {
app.doScript("Flip Everything", "My Actions");
}
//Reset Origin
app.executeMenuCommand("Fit Artboard to artwork bounds");
app.executeMenuCommand("fitall");
active_Doc.rulerOrigin = [0, 0];

//Registration Marks for multi-colors.
if (active_Doc.swatches.length > 3) {
var reggie_Mark_One = active_Doc.placedItems.add();
reggie_Mark_One.file = File("/ReggieMark.ai");
reggie_Mark_One.position = Array(-72, (active_Doc.height));

var reggie_Mark_Two = active_Doc.placedItems.add();
reggie_Mark_Two.file = File("/ReggieMark.ai");
reggie_Mark_Two.position = Array(-72, 36);

var reggie_Mark_Three = active_Doc.placedItems.add();
reggie_Mark_Three.file = File("/ReggieMark.ai");
reggie_Mark_Three.position = Array(active_Doc.width + 36, (active_Doc.height));

var reggie_Mark_Four = active_Doc.placedItems.add();
reggie_Mark_Four.file = File("/ReggieMark.ai");
reggie_Mark_Four.position = Array(active_Doc.width + 36, 36);
}
//Calculate adjustments.
var original_Size = active_Doc.artboards[0].artboardRect;
var left_right_Adjusment = (((ab_Width - original_Size[2]) * 0.5));
var up_Adjustment = (original_Size[1] + 54);
if (flip_Art == "Yes" && text_Placement.indexOf("BAG") !== -1 && artboard_Size == "DTS-A") {
var bag_On_DTS = "Yes";
var up_Adjustment = ((0.5 * original_Size[1]) + 396);
}
var down_Adjustment = (-(ab_Height - up_Adjustment));

//Set Artboard to DTS-A, LTS-M, or LTS-A with art in its placement.
active_Doc.artboards[0].artboardRect = [((-left_right_Adjusment) + chest_Placement), up_Adjustment, ((original_Size[2] + left_right_Adjusment) + chest_Placement), down_Adjustment];

//Reset Origin
active_Doc.rulerOrigin = [0, 0];
app.executeMenuCommand("fitall");

//Discorvered Colors.
var textcolors = "ColorHere";
if (active_Doc.swatches.length > 2 && active_Doc.swatches.length < 15) {
var textcolors = ((active_Doc.swatches.length - 2) + " COLOR");
var swatch_Label_Index = 0;
for (swatch_Label_Index = 0; swatch_Label_Index < active_Doc.swatches.length; swatch_Label_Index++) {
if (swatch_Label_Index !== reg_Swatch_Index && swatch_Label_Index !== none_Swatch_Index) {
var swatch_Label = active_Doc.textFrames.add();
var swatch_Label_Content = (active_Doc.swatches[swatch_Label_Index].name);
if (active_Doc.swatches[swatch_Label_Index].name.indexOf("-") !== -1) {
var swatch_Label_Content = active_Doc.swatches[swatch_Label_Index].name.substring((active_Doc.swatches[swatch_Label_Index].name.indexOf("-") + 2));
var swatch_Content_Length = (swatch_Label_Content.length - 1);
var swatch_Part_One = swatch_Label_Content.substring(0, swatch_Content_Length);
var swatch_Part_Two = swatch_Label_Content.substring(swatch_Content_Length);
var swatch_Label_Content = (swatch_Part_One + " " + swatch_Part_Two);
}

swatch_Label.contents = swatch_Label_Content.toUpperCase();
swatch_Label.textRange.characterAttributes.textFont = chosen_Font;
swatch_Label.textRange.characterAttributes.size = chosen_Size;
swatch_Label.textRange.characterAttributes.filled = true;
swatch_Label.textRange.characterAttributes.stroked = false;
swatch_Label.textRange.characterAttributes.overprintFill = true;
swatch_Label.textRange.characterAttributes.fillColor = active_Doc.swatches[swatch_Label_Index].color;
if (bag_On_DTS == "Yes") {
swatch_Label.position = [(active_Doc.width * 0.5 - 234 - chest_Placement), (active_Doc.height - 354.6 + (0.5 * original_Size[1]))];
}
else {
swatch_Label.position = [(active_Doc.width * 0.5 - 234 - chest_Placement), (active_Doc.height - 12.6)];
}
}
}
}

//Create the 1st Text Frame containing known information. (Client / Placement / PO / # of Colors)
var label_One = active_Doc.textFrames.add();
label_One.contents = (text_Client + " / " + text_Placement + " / PO: " + text_PO + " / " + textcolors);
label_One.textRange.characterAttributes.textFont = chosen_Font;
label_One.textRange.characterAttributes.size = chosen_Size;
label_One.textRange.characterAttributes.filled = true;
label_One.textRange.characterAttributes.stroked = false;
label_One.textRange.characterAttributes.fillColor = active_Doc.swatches[reg_Swatch_Index].color;
if (bag_On_DTS == "Yes") {
label_One.position = [(active_Doc.width * 0.5 - 234 - chest_Placement), (active_Doc.height - 345.6 + (0.5 * original_Size[1]))];
}
else {
label_One.position = [(active_Doc.width * 0.5 - 234 - chest_Placement), (active_Doc.height - 3.6)];
}

//Create the 2nd Text Frame containing known information. File (Name)
var file_Name = active_Doc.name;
var label_Two = active_Doc.textFrames.add();
label_Two.contents = (file_Name);
label_Two.textRange.characterAttributes.textFont = chosen_Font;
label_Two.textRange.characterAttributes.size = chosen_Size;
label_Two.textRange.characterAttributes.filled = true;
label_Two.textRange.characterAttributes.stroked = false;
label_Two.paragraphs[0].paragraphAttributes.justification = Justification.RIGHT;
label_Two.textRange.characterAttributes.fillColor = active_Doc.swatches[reg_Swatch_Index].color;
if (bag_On_DTS == "Yes") {
label_Two.position = [(active_Doc.width * 0.5 + 234 - label_Two.width - chest_Placement), (active_Doc.height - 354.6 + (0.5 * original_Size[1]))];
}
else {
label_Two.position = [(active_Doc.width * 0.5 + 234 - label_Two.width - chest_Placement), (active_Doc.height - 12.6)];
}

//Create Other Tag.
if (text_Client !== "Main Client"){
var other_Tag = active_Doc.textFrames.add();
other_Tag.contents = ("Other: " + file_Name.substring(0, 9));
other_Tag.textRange.characterAttributes.textFont = chosen_Font;
other_Tag.textRange.characterAttributes.size = chosen_Size;
other_Tag.textRange.characterAttributes.filled = true;
other_Tag.textRange.characterAttributes.stroked = false;
other_Tag.paragraphs[0].paragraphAttributes.justification = Justification.RIGHT;
other_Tag.textRange.characterAttributes.fillColor = active_Doc.swatches[reg_Swatch_Index].color;
if (bag_On_DTS == "Yes") {
other_Tag.position = [(active_Doc.width * 0.5 + 234 - other_Tag.width - chest_Placement), (active_Doc.height - 345.6 + (0.5 * original_Size[1]))];
}
else {
other_Tag.position = [(active_Doc.width * 0.5 + 234 - other_Tag.width - chest_Placement), (active_Doc.height - 3.6)];
}
}

// Draw Center Mark
var center_Mark = active_Doc.pathItems.add();
center_Mark.filled = true;
center_Mark.stroked = false;
center_Mark.fillColor = active_Doc.swatches[reg_Swatch_Index].color;
center_Mark.setEntirePath([[0, 0], [0, 1.8], [17.1, 1.8], [17.1, 9], [18.9, 9], [18.9, 1.8], [36, 1.8], [36, 0], [0, 0]]);
if (bag_On_DTS == "Yes") {
center_Mark.position = [((0.5 * active_Doc.width) - (0.5 * center_Mark.width) - chest_Placement), (active_Doc.height - 355 + (0.5 * original_Size[1]))];
}
else {
center_Mark.position = [((0.5 * active_Doc.width) - (0.5 * center_Mark.width) - chest_Placement), (active_Doc.height - 15)];
}

active_Doc.save();
//Discover screen_Room_Measurement
app.executeMenuCommand("fitall");
var screen_Room_Measurement = (original_Size[1] / 72 + .8).toFixed(1);
//Figure out to alert the user or not. Read 1st line of text document.
var screen_Room_Text_File = new File(Folder.desktop + "/suppressScreenRoomAlert.txt");
screen_Room_Text_File.open();
var screen_Room_Alert = screen_Room_Text_File.readln("r");
screen_Room_Text_File.close();
if (screen_Room_Alert == "") {
alert("Screen Room Measurement: " + screen_Room_Measurement + " inches")
}

//Create Completion File.
var work_Complete_File = new File(Folder.desktop + "/workComplete.txt");
work_Complete_File.open("e", "TEXT");
work_Complete_File.writeln(artboard_Size + "/" + text_Client + "/" + text_Placement + "/" + text_PO + "/" + textcolors + "/" + file_Name + "/" + screen_Room_Measurement + "/");
work_Complete_File.close();
if (problem_Flipping == "Yes") {
alert("It appears the file must be filpped still...");
}

}

else {
alert("Incorrect artboard_Size!");
}
}
//If no Artboard or more than 1 was detected, alert the user.
else {
alert("Requires Exactly One (1) Artboard!");
}

TOPICS
Scripting

Views

500

Likes

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 1 Correct answer

Community Beginner , Jul 29, 2022 Jul 29, 2022

Thank you guys for pointing me in the right direction! 

I downloaded AutoHotkey, did a bit of the tutorials, and then searched for some information.
1. Create my .ahk file

2. Attached is the code pasted into that file. (AHKExampleCode) Source: https://graphicdesign.stackexchange.com/questions/63439/how-to-set-keyboard-shortcut-to-run-script-in-illustrator

3. Added “app.preferences.setBooleanPreference("ShowExternalJSXWarning", false);” to the script, so the warning does not appear. Source: https://helpx.adobe.com/illustrator/using/automation-scripts.html

...

Likes

Translate

Translate
Contributor ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

I ran into this problem earlier this week and have to come to the conclusion that you can't have an action that runs a script that runs an action like below.

 

Action > Script > Action

 

It seems the first action that runs the script just hangs and Illustrator just grinds to a halt. I found an older post on here that mentioned not trying to do this but I can't find it right now.

 

My solution was to instead fire the script using the app Keyboard Maestro (Mac). Keyboard Maestro allows me to tie a keyboard shortcut to any menu command which removes the need for the first action that just fires the script.

 

Note: You can also use BetterTouchTool (Mac) or AutoHotkey (Windows) to fire the script via a keyboard shortcut.

Likes

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 ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

When an illustrator script is running, it takes control of everything. nothing else is allowed to happen (and depending on what you want to do, you're not even allowed to shift focus to another app while your script runs, or the script will cross it's arms and enter "well_now_i'm_not doing it.meme" mode.

 

I would bet that when an action calls a script, it's waiting for the script to give some kind of exit status before the action moves onto the next step of the action.

 

So by invoking the initial action, you are necessarily locking up illustrator from being able to do any other commands until the action is complete which can't happen until the script is complete. So when the script attempts to call an action,  the actions panel says "just hold your horses until I'm done with this other task" and the computer starts having a "mechanical calculator trying to divide by zero" existential crisis because you have the call stack equivalent of gridlock. No part of the process can move forward because each part is waiting on a part that can't move until the other part moves. My guess is that deep under the hood, there's logic that knows some process is supposed to be happening, but hasn't yet, so it's continually checking around at the different processes to see whether they're complete. If that's true, that could explain the app hanging unresponsive.

 

I'm fairly certain there are some plugins/extensions available for free or cheap that give access to executing scripts via keyboard shortcuts. Then you can avoid using an action purely as a container for a script, thus leaving your actions panel free and open for any number of things that actions can access while scripts cannot..................... 

 

Anyway, having said that.. I really enjoyed skimming through this code. It reminds me of my early code. Not trying to be mean or critical at all. We all start somewhere and do whatever we can to make sense of learning a whole new language and how to articulate your desires in that language to a listener who refuses to accept any mistake, no matter how small.

 

My unsolicited advice as someone who's been doing this exact work for nearly 8 years now, is to remember these two acronyms. KISS and DRY

 

Keep it simple, stud. If you find yourself typing the same thing over and over, or copying and pasting blocks of text to set character attributes, think about simplifying. See if you can save that information in one place and then use the power of programming to insert it into all of the different items you might want to create.

 

You're writing code, i assume, because you recognize the benefits of not having to manually move art around the artboard like a veritable digital assembly line worker screwing on virtual toothpaste lids... And that's fantastic. But also remind yourself to think about the benefits of not having to manually move/repeat code around the editor in the same way. you're writing scripts to facilitate a process. So, when writing your scripts think about how to write "script scripts" (little automations that make writing your code easier and cleaner). In other words, functions, arrays, and variables. A programming teacher i once had used the phrase "no magic numbers". Meaning that if you're typing a number into the code somewhere, it should virtually always be declared in a variable instead so that: A. its named with something descriptive because another developer might not know what "322" is supposed to represent. Iterations? Inches? Centimeters? People? This is especially true if you're just trying to use some constant like 3.146... Someone who works with math frequently might recognize that as pi to 3 digits of precision, but someone not math focused, it may just as well be a random number. Someone shouldn't have to read the context of the code around the number to know exactly what it is.

 

This very same principle can also be applied to blocks of code or logic (though not always as rigidly. sometimes you just need to write a block of code somewhere to do a thing real quick.) but any time you're doing something that might be done more than once, put it into a function with a name that describes what it does. Even if you think "ah, i'm never gonna use this same logic somewhere else..." you're probably wrong. And if you write it as a function first, then you're not really doing any extra work because you're still writing out the logic that you want to occur. But you're saving future you the effort of copying/pasting and trying to remember (but then forgetting) to change that one part and now you've got a runtime error for trying to access an item that you previously altered or deleted or renamed. I've done it a  million times.

 

Don't Repeat Yourself: Not dissimilar from KISS, but more explicit about avoiding repetitious behavior. Repetition is the computer's job. Your goal is to minimize your participation so the computer can do what it does best. For example, your //detect [color] loops around line 240ish depending on headers and comments and stuff. If you look at each block of code, it's identical except for one string. Any time you see yourself copy/pasting or rewriting the exact same logic... Think to yourself "function.. function.. function". Write the logic once using a variable for the only unique part, the swatch name, then just call on that function and pass the swatch name as an argument, like so: detectSwatch("White"); This will make your code a lot cleaner and more concise, while still telling the reader (or more importantly you, on monday after not having looked at the code all weekend) exactly what it's doing. Another important benefit is that if you discover that your swatch detection logic is faulty, or you've figured out a way to improve it (perhaps with a regex? scary.. i know.. but it's worth the learning curve. trust me) you only have to update one block of code, instead of fixing the logic that finds the "White" swatch and then moving on to fixing the logic that finds the "Black" swatch, etc all the while making the exact same changes to each one. 

 

But we can do even better. The above approach potentially searches through every swatch every time it's executed. For each color you want to find, you're looping through the entire swatch array until a positive result is found. So if you call detectSwatch("White") and then on the next line call detectSwatch("Black") the first function call was likely to have already found the swatch you're looking for now. Or at the very least, the second function call is guaranteed to search through many of the same elements that the first function call just searched through. No matter how you slice it, even if you break out of your loop when the swatch is found, the script is going to be searching through a lot of unnecessary stuff multiple times. Probably not a big deal with swatches, because it's rare to have enough swatches to see a performance issue on this.. But if you apply the same logic to pageItems or pathItems.... the number of elements you're checking could be in the 10,000s or even much much higher. So if you're processing thousands of unnecessary items several times...... well i guess you'll have an excuse for a coffee break. 😉

 

So to improve the useful, but potentially inefficient detectSwatch("name") function... we can and should apply the magic of arrays to get the processor to do the grunt work for us. now, detectSwatches(["name1","name2","name3"]) can find any of the swatches you're looking for while only looping through the search space once, and then looping the array to check for matches. Further performance enhancements could be unlocked with regex to avoid looping each search term for every swatch, since no swatch will be a match for more than one search term.

 

And now with our genericized function you've gone from writing all of the logic for every color you want to find, down to writing the logic once and then one function call for each color, down to logic once, then one funciton call. and while this may sound like a headache at the moment, I promise the headaches associated with duplicate logic and overcomplexity will be far worse as your scripting ambitions inevitably grow.

 

Anyway. Sorry for the novel. This concludes my unsolicited advice. Please feel free to regard or disregard any and all of it at your leisure. 😉

 

Questions or comments more than welcome.

Likes

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 Beginner ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

For the topic: It definitely makes sense that the “action” part of Illustrator is hung up. It even appears to be highlighted still, as well. It seems concurrent actions are not possible. c.c

 

I don't know how to initiate a script in Illustrator besides the (File->Scripts)/Drag+Drop routes. I've been using Atom as my text editor, saving the files, then (File->Scripts->OtherScripts) for testing. Working versions then get loaded into my presets. To hot-key it, I used the action.

 

I downloaded and installed AutoHotKey, but I don't know enough at the moment to have it launch this script in Illustrator... Or make it interact with Illustrator menu commands?

I will attempt a few ways with Macro Express first. I have use Macro Express Pro for 10+ years. Its a nifty programing wizard and direct line editor- it also accepts HTLM/JS/VBScript.

 

Would I consider the “actions” just not working as the final answer for this topic and the advice to find another way to hotkey it, or should it be left open, as my new question is of the alternative ways to launch the script... how do I go about that?

 

Personal Note: It does what I need it to... I can't wait to polish it up :D. I have never heard of “KISS” or “DRY” but the concept doesn't escape me. I have questions regarding ways to clean up this code, launching the script, and more... if you are okay with messaging. Attached are snippets from Macro Express- I also turned them into scripts since learning!

Likes

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 ,
Jul 29, 2022 Jul 29, 2022

Copy link to clipboard

Copied

Definitely ok with messaging. DM me on the forum or send me an email at illustrator.dev.pro@gmail.com and i'm happy to help. I started here on this forum just like you, testing the waters to see what kind of magic i could perform to make my frustration with tedium...... DISAPPEAR! .... Unfortunately, in a way i traded one kind of tedium for another. lol. Now instead of clicking and dragging art around the artboard and copying and pasting and resizing and changing colors, etc..... I'm searching for errant semi colons or a mistaken "=" where there should have been a "==". But it's still definitely for the better. Becuase lots of people can do the clicking and dragging of artwork. Not a lot of people can write effective code (or at least they won't, even if they're technically capable of learning it). 

 

I'm not sure what your role is in the design/print space or what your goals are moving forward.. But I promise that investing this time into learning the basics of programming will make you more valuable and marketable to current or prospective employers. The nice thing about writing code to automate artwork... is that it keeps working after you go to sleep. or when you go on vacation. I have something close to 40 active scripts (some big/complex enough to probably qualify as applications instead of just a script) in use by our production art and product development and print production teams every day. And even when I go on vacation, my impact is still being felt at the company. If you're only pushing art around manually, your productivity stops as soon as you clock out.

 

As you learn and grow with programming, don't forget this. Know your value. This is very powerful stuff at our fingertips that can easily translate to big savings for your employer. And a very small percentage of people are willing or able to do it. I'm happy to help facilitate that and help you maximize your value just like others here helped me.

 

Any old time, if you have a question or an issue. send it my way or post here on the forum. you got this.

Likes

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 ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

Do you can run actions just fine from JSX. Ive tested it and works. Is the action perhaps not available?
You can also add the action itself into the JSX file and delete it afterwards. Im using this method, where an action is loaded into the panel, than it runs and afterwards gets deleted. I found a post here on the forum on how to do this. 

 

Here's an example of that, make the names exactly the same as the folder and action when you have saved the AIA file, otherwise it wont work. Here's a link to that article

// Exit Isolate Mode
// Dynamic Action
function act_ExitIsolateMode() {
    var str = '/version 3' +
        '/name [ 15' +
        ' 4578697449736f6c6174654d6f6465' +
        ']' +
        '/isOpen 1' +
        '/actionCount 1' +
        '/action-1 {' +
        ' /name [ 17' +
        '  457869742049736f6c617465204d6f6465' +
        ' ]' +
        ' /keyIndex 0' +
        ' /colorIndex 0' +
        ' /isOpen 0' +
        ' /eventCount 1' +
        ' /event-1 {' +
        '  /useRulersIn1stQuadrant 0' +
        '  /internalName (ai_plugin_Layer)' +
        '  /localizedName [ 5' +
        '   4c61796572' +
        '  ]' +
        '  /isOpen 0' +
        '  /isOn 1' +
        '  /hasDialog 0' +
        '  /parameterCount 1' +
        '  /parameter-1 {' +
        '   /key 1836411236' +
        '   /showInPalette -1' +
        '   /type (integer)' +
        '   /value 25' +
        '  }' +
        ' }' +
        '}';

    var f = new File('~/ExitIsolateMode.aia');
    f.open('w');
    f.write(str);
    f.close();
    app.loadAction(f);
    f.remove();
    app.doScript("Exit Isolate Mode", "ExitIsolateMode", true); // action name, set name
    app.unloadAction("ExitIsolateMode", ""); // set name
}

 

Likes

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 Beginner ,
Jul 29, 2022 Jul 29, 2022

Copy link to clipboard

Copied

Thank you guys for pointing me in the right direction! 

I downloaded AutoHotkey, did a bit of the tutorials, and then searched for some information.
1. Create my .ahk file

2. Attached is the code pasted into that file. (AHKExampleCode) Source: https://graphicdesign.stackexchange.com/questions/63439/how-to-set-keyboard-shortcut-to-run-script-i...

3. Added “app.preferences.setBooleanPreference("ShowExternalJSXWarning", false);” to the script, so the warning does not appear. Source: https://helpx.adobe.com/illustrator/using/automation-scripts.html

4. Works as intended, mostly. Illustrator is not staying maximized… sometimes? Other than the window being weird, the script and actions are completed as required!

Likes

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 Beginner ,
Jul 29, 2022 Jul 29, 2022

Copy link to clipboard

Copied

While not a hotkey, quick access to menu commands can be found here: http://vectorboom.com/load/articles/theory/shortcuts_to_run_scripts_in_adobe_illustrator/12-1-0-564

 

Alt + F -> R -> ect.

Likes

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 ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

Thats weird, you sure its due to the action. I remade your action and did simple test with 1 line of appDoscript. Works just fine

I tried your action, it will run untill the missing files. So cant test it fully. Could you perhaps link them in this thread?

Likes

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 ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

How did you execute the .jsx with the app.doScript()? From the Scripts menu? VS Code? Or from an action? what version of illustrator are you using?

Likes

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 Beginner ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

I believe DilliamWowling is correct in saying that my use of the action as a container to launch the script is holding up the “actions” end of things; otherwise, when launched it works as intended.

 

It is a ½ x ½ Inch cross hair marking, a simple square with the artboard set to artworkbounds works... For some reason I can not provide it.

Likes

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 ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

Guess it depends sent like all format, you can always zip and then try.

 

Perhaps that's indeed the reason. Using a action to call Jax and then call another action won't work. You could try my method of adding the action inside isx file. But i think it will fail as well because it's basically the same.

 

In Photoshop you can add shortcuts to the scrips in the preset folder. Can remember if illustrator can do the same. You could try that, should work.

 

Ps what is that part for asked Ng for artboard size. I see it loads a text file with variables and then checks that with sizes inside the Jax, is that really needed then?

 

You could make on dialog for all your inputs, makes the setup much faster and convenient 

Likes

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 Beginner ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

The different text files that are sought after are text files that I normally have Macro Express Pro (MEP) generate before executing the script. MEP is a program I have used for many years to do small things... like making Alt + [DirectionalArrowKey] move my mouse 1 pixel in the respective direction... just so I can make sure that tower is right agaisnt the path in Bloons TD ^.^

 

Since then I have been able to do much more and even automated Illustrator a bit with it. I made MEP do what the JS does, before I made the JS. MEP Version came frist. It could do alot but mostly controlled actions. It takes about 45 seconds for the MEP version to do a little less than what the JS does... at the end it saves a text file of a bunch of things, including elapsed time. It records the JS at 1 second mostly- and 2 seconds sometimes. I can share that as well when I return tomorrow.

 

My intention was to create a script that can take variables from MEP. So I have a MEP Script that “talks” to my JS, and then waits around for the JS to respond. This is because I do not know how to have JavaScript remember that last time the code was ran, it was a LTS-M, and should have a radio button of my options selected. I do know how to make MEP remember, and was more successful in getting the two to communicate than getting JS to “save the variables”. I only know the prompt() for asking user input so far. This is the result.

 

Additionally, I wanted the script to be stand alone should it need be. I can run it with my batch MEP script, and its also stand alone! If there were any other user, they would not notice anything odd. It would detect if the file contained the template designation tag. If not, it appears to just prompt the user. I would prefer radio buttons for the art board size and text inputs for the other 2.

Likes

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 ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

Ow i thought that abVariables had just artboard sizes in it and your isx files check which size it needs to apply.

 

You should be able to hotkey scripts which show in the script menu. Try adding one, restart and check the hotkey menu. Them under file>script>YOUR SCRIPT you should be able to hotkey it without the need to run from and action. That should solve your issue with the app getting in non-essential nsive state

Likes

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 ,
Jul 29, 2022 Jul 29, 2022

Copy link to clipboard

Copied

I kinda forgot that Illustrator is way less machured compared to Photoshop. It lacks many features. We also cant hotkey scripts. Only the one to run other script, which i did because i use it a lot.

 

Hope youll succeed with your project. Combining it with those other scripts, looks complicated

Likes

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
Contributor ,
Jul 28, 2022 Jul 28, 2022

Copy link to clipboard

Copied

DilliamWowling is correct. It only happens when you initiate a script via an action and then that script tries to run another action. If your script does anything other than try to run another action it will execute just fine when initiated from an action.

 

As I said above, I ran into this exact issue earlier this week and tried many many ways to work around this but I don't think it's possible.

Likes

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 ,
Jul 29, 2022 Jul 29, 2022

Copy link to clipboard

Copied

LATEST

yea. it's just not possible. it would require multiple simultaneous threads, and Extendscript is single threaded. No process can begin until the previous one finishes, so as long as the script is still running, the action is still running, which means the script cannot call a new action. It's like being out of gas in your car.. the seemingly simple solution is to just go get some gas.. but you can't drive until you get gas, and you can't get gas unless you drive (or figure out a different solution, like walking or calling for a ride). it's circular ad infinitum. 

Likes

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