Is it possible to execute JSX scripts from outside ExtendScript?
For Windows users, you can use a vbs script. Pass arguments to the .jsx script by providing arguments to the cscript
command like so: cscript test.vbs "hello"
. test.vbs could look like so:
Dim appRef
Dim javaScriptFile
Dim argsArr()
Dim fsObj : Set fsObj = CreateObject("Scripting.FileSystemObject")
Dim jsxFile : Set jsxFile = fsObj.OpenTextFile("C:\Users\path\test.jsx", 1, False)
Dim fileContents : fileContents = jsxFile.ReadAll
jsxFile.Close
Set jsxFile = Nothing
Set fsObj = Nothing
javascriptFile = fileContents & "main(arguments);"
Set appRef = CreateObject("Illustrator.Application")
ReDim argsArr(Wscript.Arguments.length-1)
For i = 0 To Wscript.Arguments.length-1
argsArr(i) = Wscript.Arguments(i)
Next
Wscript.Echo appRef.DoJavaScript(javascriptFile, argsArr, 1)
The Wscript.Echo
will return the last line returned by the .jsx file. A .jsx file example could be:
function main(argv) {
alert(argv[0]);
return "test";
}
When ran, you should seee Illustrator (or whatever adobe program) alert "hello" and then "test" will be returned to stdout (you should see it in the command prompt window).
Are you on a Mac? If so, you can use AppleScript with the osascript
tool to execute your JavaScript. Here are some examples:
Running JSX and Returning a Value
Save this as ~/temp/foo.scpt:
tell application "Adobe Illustrator"
-- 'do javascript' runs any arbitrary JS.
-- We're using the #include feature to run another
-- file. (That's an Adobe extension to JS.)
--
-- You have to pass a full, absolute path to #include.
--
-- The documentation alleges that 'do javascript'
-- can be passed an AppleScript file object, but
-- I wasn't able to get that to work.
do javascript "#include ~/temp/foo.jsx"
end tell
And save this as ~/temp/foo.jsx:
var doc = app.activeDocument;
var numLayers = doc.layers.length;
// The last value in the JSX file will be printed out by
// osascript.
numLayers;
Now, from the command line run osascript ~/temp/foo.scpt
It will print the number of layers in the active Illustrator document.
Getting data out of the JavaScript is limiting. You can't print to stdout from within the JavaScript. Instead, place the value you want to return as the last statement of the JSX file; it will be printed by osascript
. (Here's why: The last value in the JSX file is the return value of the do javascript
AppleScript statement. That is also the last value in the AppleScript file, and osascript
prints the final value.)
The value you return from JavaScript can be a number, a string, an array, or anything else that retains its value when converted to a string. If you want to return a complex object, you'll need to #include a JSON library and call .toJSONString()
on the object.
Passing Arguments to JSX
To pass arguments to the JSX code, follow this example:
File ~/temp/args.scpt:
on run argv
tell application "Adobe Illustrator"
set js to "#include '~/temp/args.jsx';" & return
set js to js & "main(arguments);" & return
do javascript js with arguments argv
end tell
end run
File ~/temp/args.jsx
function main(argv) {
var layer = app.activeDocument.activeLayer;
app.defaultStroked = true;
app.defaultFilled = true;
// Top, left, width, height (in points).
// Note that parameters start at argv[0].
layer.pathItems.rectangle(argv[0], argv[1], argv[2], argv[3]);
}
And then run osascript args.scpt 50 30 10 80
Debugging
The do javascript
command also has options for launching the ExtendScript debugger. For details, open the Illustrator dictionary in AppleScript Editor.