Skip to main content
WarlordAkamu67
Inspiring
July 28, 2022
Answered

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

  • July 28, 2022
  • 2 replies
  • 16221 views

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!");
}

This topic has been closed for replies.
Correct answer WarlordAkamu67

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

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!

2 replies

schroef
Inspiring
July 28, 2022

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?

Disposition_Dev
Community Expert
July 28, 2022

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?

jduncan
Community Expert
July 28, 2022

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.

Disposition_Dev
Community Expert
July 28, 2022

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.

WarlordAkamu67
Inspiring
July 29, 2022

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!