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

Call other scripts with Extendscript?

Explorer ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

I've been trying to find a way to call scripts from other scripts but can't seem to find any documentation on it.

 

I found this: https://community.adobe.com/t5/illustrator/a-way-to-call-an-illustrator-file-script-from-another-scr...

 

... but it turns out it's very limited and doesn't behave like you'd expect. There are two major limitations that I've noticed so far:

var f = new File("path/to/jsx/script");
f.execute();

1. On Windows, if the default application that .jsx files are set to open in is anything but Illustrator (or whatever other Adobe app), then they won't execute in Illustrator at all and instead literally open in another program, like a code editor.

2. One script calling another simply executes the second script after the first script is completely done executing no matter where in the code you call for the execution. This coupled with the fact that the only thing that f.execute(); can return is true if the second script was executed successfully. So you can't pass data between scripts when you want to.

 

Is there a proper way to call other scripts with Extendscript?

TOPICS
Scripting

Views

3.9K

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 Expert , Jan 12, 2021 Jan 12, 2021

Hello,

1. Specify the target engine to execute the the script in Illustror or another Adone application.

 

2. execute() method will exceute the script. You should first include the script. To better understand please follow following steps.

 

Steps to follow:

 

1. Create one file "script1.jsx" file on Desktop and paste following code.

#target "illustrtor"
#include "script2.jsx"

function main(){
    callMethodOfSecondSript("I am coming from First Script");
    alert("I am back in script 1");
}

...

Votes

Translate

Translate
Adobe
Valorous Hero ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

You want to use this cool trick:

 

eval("#include 'Path/ToMy/Script/Script.jsx'");

 

The Script.jsx file would have your functions and then you can use them like usual and pass-in/get variables.

 

To call VBS or AppleScripts, there are techniques using file.execute():

For Mac, you can package up an "Executor.app" .app which is set to read dynamically-written .scpt files and execute them as AppleScript.

For Windows, you can simply call file.execute() on a .vbs or a .bat file (I believe).

 

Both of those methods are easiest to use data-wise by simply writing a text file to the filesystem and using sleep time-outs to wait a certain period before giving up on finding the written text file.

However, JSX scripts could be written with a 'back door' pattern whereby if there are arguments passed into the wrapper function, it will execute differently than without arguments.
So the user can execute the regular wrapper function "test()" with no arguments to have the JSX script produce a UI Dialog. But then the user pushes some buttons in the dialog and it performs a web-fetch to collect web data and fill some of the UI elements with it in the dialog. For this, the script would write some instructions down and use file.execute() on the respective file in either the Mac or Windows setup. The VBS/.app would then read the instructions (this is a synchronous process because the JSX file would have written the instructions just prior) and will get the web data. At this point the JSX UI dialog is dismissed and it disappears.
After it has gotten the web data, the Win/Mac script then does a VBS AiApp.DoJavaScriptFile command or AppleScript "do javascript... whatever the syntax was) command to trigger the test() JSX function from the jsx script. This time it will suppy arguments to the JSX function via Windows' COM Array of arguments or Mac's "with arguments..." keyword to produce effectively this: "test(args)" where args is usually most conveniently a single JSON string which can contain many separate key/values. (JSON VBS code exists to help create and parse JSON in VBS, and in AppleScript we can use 'jxa' (Apple's flavor of javascript which is poorly documented) to do the same).

Now, with the arguments supplied, the test(args) JSX function will follow a different execution flow and this time it will show the dialog box but it will have the new web-data showing inside some of the inputs. Those web-data values would have been supplied inside the 'args' parameter.

Votes

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
Explorer ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

Thanks! It seems to work properly.

 

Although the syntax to me is a little off-putting, especially since having to enter a function like this just seems really weird:

eval("#include 'Path/ToMy/Script/Script.jsx' someFunc()");

 

The other reply by @Charu Rajput seems to also work with no functional difference that I've noticed and has more standard syntax. So I think that is the best solution here unless there is anything else magical that eval() does.

Votes

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
Valorous Hero ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

The sumFunc() is usable outside the eval statement - matter of fact all the functions inside will now be available.

Yes, the default way of including other scripts is through a plain #include statement. However, this is not dynamic so you are limited to how your script file is written before it is ran.

For most cases this is just fine, but when you are looking to execute an arbitrary script at run-time, eval could be the solution..

Note on #includes: where it gets problematic is in more advanced scripts that make ScriptUI-based floating panels. Using VSCode and RenderTom's ScriptRunner extension for it, launching a script that is comprised of #include statements and launches a floating panel causes the panel to immediately disappear (despite the '#targetengine main' directive at the top).

To work around this issue I was able to create a "launcher.jsx" file with a single #include statement that has a file path to the main script which in turn has several #include statements that piece together one big script from multiple constituent files. This workaround works and keeps the panel from going away.

 

Votes

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 ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

Hello,

1. Specify the target engine to execute the the script in Illustror or another Adone application.

 

2. execute() method will exceute the script. You should first include the script. To better understand please follow following steps.

 

Steps to follow:

 

1. Create one file "script1.jsx" file on Desktop and paste following code.

#target "illustrtor"
#include "script2.jsx"

function main(){
    callMethodOfSecondSript("I am coming from First Script");
    alert("I am back in script 1");
}

main()

 

2. Create another file with name "script2.jsx" file on Desktop and paste the following code

#target "illustrator"
function callMethodOfSecondSript(msg){
    alert("I am inside script 2");
    alert(msg);
}

 

3. Now execute the script1.jsx

 

Summary : When you execute the script1.jsx, this script knows about the script2.jsx, because we have included that script in our code. So when method of script2.jsx will be called from script1.jsx you can pass the parameter.

 

Hope it helps.

 

Best regards

Votes

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
Explorer ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

This works perfectly thanks!

 

For some strange reason though (not that it actually affects anything functionally) I get a syntax warning in Visual Studio Code (red squiggly underlined text) on: #include "script2.jsx"

Hovering over it displays the following message: "Private identifiers are not allowed outside class bodies. ts(18016)"

But running the program does not produce errors / the program runs perfectly normally. So I don't know if you've seen this before or if I should be wary about it. I guess I'll just ignore it since it doesn't affect execution.

Votes

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
Valorous Hero ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

You can get rid of ugly VSCode errors by replacing the # symbol with //@:

Before: #include

After: //@include

It will work the same way!

However I do not like this option because it makes the include statements like the rest of the green comments, so it's more difficult to discern where an include statement and a real comment is by quickly looking. Therefore I opt to have the ugly squiggly lines, so I can tell really fast when I am looking at my main file.

Votes

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
Explorer ,
Jan 12, 2021 Jan 12, 2021

Copy link to clipboard

Copied

LATEST

Good thinking. I'll stick with the red squigglies. I'm so glad you seem to know so much about literally every problem I have apparently and that you're always able to help me. Infinite thanks!

Votes

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