Run illustrator extendscript through automator applescript or bash? - applescript

The following command will run the SCRIPT_ABC.jsx which is located on my desktop. Is there a way to take the contents of the SCRIPT_ABC.jsx and put the javascript extendscript exclusively inside automator so when I save it out as an application it will be included within the program?
on run {input, parameters}
tell application "Adobe Illustrator" to open file "Macintosh HD:Users:NAME:Desktop:SCRIPT_ABC.jsx"
return input
end run

Paste the entire jsx into your applescript as a text body, then use the do javascript command to run it. Applescript has a great benefit of being able to pass in arguments to the jsx (do javascript myScript with arguments { textVariableHere, anotherOneHere }) and obtain the returned result too!
Elaborated edit:
set myJavascript to "
#target illustrator
function test(args){
var docName = app.activeDocument.name;
alert(\"Hello from Adobe JSX. Current document name is: '\" + docName + \"'\\n\" + args[0]);
return docName;
};
test(arguments);
"
set myInputVar to "The input string here."
tell application "Adobe Illustrator"
set myResult to do javascript myJavascript with arguments {myInputVar}
end tell
display alert ("Returned Document Name is: '" & myResult & "'")
So what you see here is an example of a javascript embedded inside the applescript as a string. Lucky for me, I have AppleScript Debugger app which I paid for a long time ago and is well-worth it, and it has the "Paste as string literal" function which auto-escapes the quotes and stuff. Very helpful.
But you can see the magic of passing in a variable to the javascript as applescript arguments which prevents a lot of issues one could have doing string-building inside applescript to put variables in.
Although you don't have to use AppleScript arguments to put data into the jsx, as you can use the string-building mentioned above (which I do not recommend when the arguments way is available for use), the huge payoff is actually getting the returned jsx data back into the applescript. Really neat stuff.
So there you have it, the whole enchilada! I would be curious to see if there's a comparable native way to do a similar setup with Windows and VBS + JSX combo - if anyone is aware of something like this please let me know in the comments below.
Thanks!
PS:
The word arguments used in the function call of the main function of the jsx script is actually a key-word used by AppleScript and it has to be spelled out like so, otherwise it will not work.
More Edit:
Okay, so maybe you don't wanna paste no huge jsx into your applescript and escape all the quotes, etc.
I get it. No worries! You can do the following:
Ensure your jsx is somewhere installed along with you app (it could be binary), so save the following code which represents your jsx body as a jsx file wherever:
var docName = app.activeDocument.name;
alert("Hello from Adobe JSX. Current document name is: '" + docName + "'\n" + args[0]);
return docName;
And in your AppleScript you simply change the jsx portion to the following:
set myJavascript to "
#target illustrator
function test(args){
#include '/Users/YourName/Wherever/myAppleScriptJsxTest.jsx'
};
test(arguments);
"
BOOM! Works exactly the same! Isn't that something?

You can copy the .jsx file to the Contents/Resources folder of your Automator application bundle, and use a Run AppleScript action to get the resource
on run {input, parameters}
try
set thePath to path for resource "SCRIPT_ABC" extension "jsx"
tell application "Adobe Illustrator" to open (thePath as POSIX file)
on error errmess
display dialog errmess
end try
return input
end run
Note: You will need to copy the file in question again to the bundle /Contents/Resource folder when you recreate your application bundle since Automator creates a fresh bundle each time you save it.
Also, it may be required to close Automator/the Script Editor after you have added the file. Finally, test the resulting app and see if it launches the file in the requested app.

Here is the AppleScript that executes ~/script.jsx (there can be any jsx script) via Adobe Illustrator:
tell application "Adobe Illustrator"
do javascript "(function(){//#include '~/script.jsx'}());"
end tell
Or you can set Adobe Illustrator to open all jsx files by default. After that a double click on any jsx file will make Illustrator to execute the script. It works on Windows and MacOS.

Related

MacOS render images from PDFs (no third party render lib)

I'm trying to render 50k images using a Mac Mini. I don't know much about the system, but I need to use the built-in renderer like the Preview.app.
I currently tested to set up an Automator script that could take files selected in the Finder window, render images, and move them to another directory.
But running that script with 50k single-page PDFs does not work. Instead, it seems to use the memory to store the PDFs or something like that.
I have never written any AppleScript, Swift, or similar code, but I'm well versed in Bash and Java, so if I could do this from the command line, then it would be ideal, but if someone has a suggestion on an AppleScript that could solve this issue I'm all ears.
Thank you for reading this.
-- 1) Create --> **Quick Action** (that is, service)
-- 2) Set: **Workflow receives current PDFs in Finder.app**
-- 3) Add action **Run AppleScript** with following content.
-- 4) Save this service with name like "Render images from single_page PDFs".
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "Quartz"
use framework "QuartzCore"
on run {input, parameters}
set destinationFolder to (choose folder with prompt "Please, choose Destination Folder")
set destFolderPosixPath to POSIX path of destinationFolder
repeat with aPDF in (get input)
(my rasterPDF:aPDF savingToFolder:destFolderPosixPath)
end repeat
return input
end run
on rasterPDF:aPDF savingToFolder:destFolderPosixPath
set aURL to (|NSURL|'s fileURLWithPath:(POSIX path of aPDF))
set fileName to aURL's lastPathComponent()
set baseName to fileName's stringByDeletingPathExtension()
set aPDFdoc to PDFDocument's alloc()'s initWithURL:aURL
set doc to (NSImage's alloc()'s initWithData:((aPDFdoc's pageAtIndex:0)'s dataRepresentation()))
if doc = missing value then error "Error in getting image from PDF"
set theData to doc's TIFFRepresentation()
set aNSBitmapImageRep to (NSBitmapImageRep's imageRepsWithData:theData)'s objectAtIndex:0
set outNSURL to |NSURL|'s fileURLWithPath:(destFolderPosixPath & baseName & ".png")
set outputPNGData to aNSBitmapImageRep's representationUsingType:NSPNGFileType |properties|:{NSImageCompressionFactor:0.8, NSImageProgressive:false}
outputPNGData's writeToURL:outNSURL atomically:true
end rasterPDF:savingToFolder:
NOTE: 1) the script renders image from first page of multiple_page PDFs as well. 2) with using repeat loop and with changing pageAtIndex property, someone can adapt my script to render images from all PDF pages.

Automated importing/sizing of image illustrator

I’m trying to find a way to place an image into an illustrator document with AppleScript, but I can’t find a place image command that works.
Ideally I would give the AppleScript my image’s file path, and it would place said image in a file when executed.
Anybody do this before?
Do you have the Adobe Illustrator CC 2017 Reference PDF? This example is straight out of it:
-- This function adds a new placed item to a document from a file reference,
-- fileToPlace, which is passed in during the function call, fileToPlace is an
-- alias or file reference to an art file, which must be set up before calling this
-- function, itemPosition is a fixed point at which to position the placed item
on PlacedItemCreate(fileToPlace)
tell application "Adobe Illustrator"
set itemPosition to {100.0, 200.0}
set placedRef to make new placed item in document 1 ¬
with properties {file path:fileToPlace, position:itemPosition}
end tell
end PlacedItemCreate

Getting the Filename of a pdf print dialog in osx automator

I'm creating an automator pdf print plugin.
When you choose the print plugin the filename to the pdf is the input (normally /var/something /documentName.pdf)
I would like to get the documentName to use it later in an Rename Finder Item.
I'm using atm applescript to accomplish this.
on run {input, parameters}
tell application "Finder"
set fileName to name of ((POSIX file input) as alias)
end tell
return fileName as string
end run
The problem is that this only works when I put an Ask for Text Action before the applescript which displays the posix path.
If I remove the Ask for Text action the applescript fails.
The workflow is at https://www.dropbox.com/s/jp4t9pen3gvtyiq/Rename-Action.workflow.zip
I guess it is something simple but this is the first applescript / automator workflow I'm creating.
As I fail on commenting
Solution is
on run {input, parameters}
tell application "Finder"
set fileName to ((name of first item of input) as string)
end tell
return fileName
end run
as by #Ken post below.
Thanks!
I created a test workflow with this AppleScript:
on run {input, parameters}
tell app "System Events"
display dialog ((class of input) as string)
end
return input
end run
That displayed "list". I then modified it to:
on run {input, parameters}
tell application "System Events"
display dialog ((class of first item of input) as string)
end tell
return input
end run
That displayed "alias".
So, the input to a PDF workflow is a list of aliases. Write your script with that in mind and it should work. For example, this works:
on run {input, parameters}
tell application "System Events"
display dialog ((name of first item of input) as string)
end tell
return input
end run
When working with AppleScript, it can really help to forget everything you know about file paths. If you think in paths, you will be doing path-math in your head and all of it is unnecessary work. What you want to work with is objects. When doing file operations, you work with alias objects.
If you look at the PDF you are working with in Finder, and go File ▶ Make Alias then you’ll create an alias file. You can drag that alias file all around the file system of the disk it is on, put it in any folder, and when you open the alias file, it will still always open your original PDF, even if you forget what path name your original PDF file has, and even more importantly: the alias will open the PDF even if the PDF has moved to somewhere else in the file system. An alias does all that work for you. You don’t need to know the path names.
In AppleScript, rather than working with files, you work with aliases, and whatever you do to an alias is also done to the original file. So you don’t need to know the path name of a file to change its name — you only have to have an alias of it to work on. You store that alias in a variable.
So what you want to do is set the input PDF alias to a variable, and then later, that variable is what you give Finder to rename. You don’t have to know any paths. It doesn’t matter where the input PDF is stored on the file system — the alias will take care of that.
Here is an example AppleScript that demonstrates the principle of taking an alias as input, and then later renaming that alias (and thus, the original file:)
tell application "Finder"
set theInputFile to (choose file)
-- do a workflow here
set the name of theInputFile to "Renamed" & "." & the name extension of theInputFile
end tell
Here is a line-by-line description of the above script:
the opening tell block that specifies we are talking to Finder
show the user a choose file dialog box, and set the alias that is returned by that dialog box to a variable called “theInputFile”
a comment that is a placeholder for whatever workflow steps you might want to do
rename theInputFile to “Renamed” and its original file extension
quit talking to Finder
And even where you want to work with the folder that contains your original input file, or want to know what disk the input file is on, you still don’t need to work with path names:
tell application "Finder"
set theInputFile to (choose file)
set theContainingFolder to open the container of theInputFile
set theInputFileDisk to the disk of theInputFile
end tell
And if you want to know what kind of file the input file is, you don’t have to look at the filename extension and figure it out, you can just say:
set theInputFileKind to the kind of theInputFile
if theInputFileKind is equal to "Portable Document Format (PDF)" then
-- do stuff
end if
And if you want to work in specific folders, such as the home folder, there are special properties for that, like “the path to the home folder” so that the following script opens “~/Public/Drop Box” on any system, no matter what the user name:
tell application "Finder"
activate
set theHomeFolder to the path to the home folder as alias
set theDropBoxFolder to folder "Drop Box" of folder "Public" of theHomeFolder
open theDropBoxFolder
end tell
You can walk around disks and folder structures as objects as shown above, so again, there is no need to think in paths. Think in terms of setting variables to objects that you want to interact with.
Solution is
on run {input, parameters}
tell application "Finder"
set fileName to ((name of first item of input) as string)
end tell
return fileName
end run
as by #Ken's post
Thanks!

How to pass data from a FileMaker field to an Applescript

I need to delete a file off of my Cincinnati Laser from FileMaker. It gets it there via a FMScript that export field contents of a container to this location. So I know the file name and the path its all built in a calculation field on that record. But I don't know how to get that info into an Applescript using the FM12 "Perform AppleScript" script step
When I hard code the path and file name (Shown Below) it works.
set xpath to "Titanium Brain:Users:smartin:Desktop:Laser:1512-clr-c.cnc"
tell application "Finder"
delete file xpath
end tell
When I try to pass the field contents (Shown Below) it doesn't work.
set xpath to Laser::gCNCPath
tell application "Finder"
delete file xpath
end tell
What am I missing?
The problem with Perform AppleScript with calculations is always the managing of quotes and returns. Putting exactly the following into the 'Calculated Applescript' box of the 'Perform Applescript' script step should work for you:
"set xpath to " & Quote ( Laser::gCNCPath ) & ¶ &
"tell application \"Finder\"¶" &
"delete file xpath¶" &
"end tell"
Honestly, though, the whole thing gets pretty ugly pretty quickly. If you have security locked down appropriately, I'd be more inclined to put the whole script into the Laser::gCNCPath field
set xpath to "Titanium Brain:Users:smartin:Desktop:Laser:1512-clr-c.cnc"
tell application "Finder"
delete file xpath
end tell
And then, for the Perform Applescript, you only need to call the field:
Laser::gCNCPath
Whenever I've needed to pass information from FileMaker to AppleScript (and I'll admit, it's been a while since I've done so), I've used the Native AppleScript field in the Perform AppleScript dialog box and used a global field to store the "parameter" that AppleScript needs and used AppleScript to pull that information.
set xpath to cell "gCNCPath" of layout "Laser" of current file -- double check this syntax, I'm working from memory
tell app "Finder" to delete file xpath

AppleScript "Save As" HTML in TextEdit

I want AppleScript to loop through a set of of RTF files in folder and save them as HTML files.
This is my simple code so far. The XXXX is where I'm struggling:
tell application "Finder"
set source_folder to choose folder
set aList to every file in source_folder
repeat with i from 1 to number of items in aList
tell application "TextEdit"
set aFile to (item i of aList)
save as aFile XXXXXXXXX
end tell
end repeat
end tell
I'm really new to this... any help much appreciated.
You don't need TextEdit for this. There is a command line program textutil which will do the job without all the opening and saving stuff required with TextEdit. We can fix your TextEdit script (it has a few errors) but try this first and let us know if it does the job for you. The html files will have the same name but with the html extension and will be located in source_folder. The ouput path can be changed in the code by using the "-output" switch of textutil. See "man textutil" if you want to look at everything it can do.
And a general question... what is a RTD file? Do you mean rtf or rtfd? Textutil will work with rtf/rtfd but not rtd, so I hope that isn't really your file type.
set source_folder to choose folder with prompt "Choose a source folder."
set output_folder to choose folder with prompt "Choose an output folder."
tell application "Finder"
set theFiles to (files of entire contents of source_folder) as alias list
end tell
repeat with aFile in theFiles
tell application "Finder"
set fileName to name of aFile
set fileExt to name extension of aFile
end tell
set outputPath to (output_folder as text) & text 1 thru -((count of fileExt) + 1) of fileName & "html"
do shell script "/usr/bin/textutil -convert html -output " & quoted form of POSIX path of outputPath & space & quoted form of POSIX path of aFile
end repeat
You mention you are new to applescript, so I'll give you some general pointers you should keep in mind when writing applescript code.
Avoid putting tell blocks of code inside each other. You have tell app TextEdit inside tell app Finder. That's bad. Doing this is a source of many conflicts because you are basically telling the Finder to tell TextEdit to do something. That's not good because commands can get confused and it's really hard to debug these kinds of issues. So keep your tell blocks separate.
Avoid telling an application to perform a command that is not in its applescript dictionary. You should only tell an application to do commands that it knows and an application only knows about the commands in its dictionary. So for example, you are telling the Finder to "choose folder". The Finder does not know that command. That's an applescript command. So doing as you have done is another possible source of errors. In this case that's a simple command and it will work but in general avoid doing this.
Regarding the Finder, you should avoid using it too much. The Finder is a major program on your computer and is often busy doing computer related stuff. As such it's best to only use it when necessary. As an example you can see in my code that I removed the "choose folder" and the repeat loop from the Finder. I purposely appended "as alias list" to the end of the Finder command to make the list of files usable outside of the Finder tell block of code. Of course use the Finder if needed but it's best to not use it if you don't need it.
Use the applescript dictionary of your applications. As mentioned above, the dictionary lists all of the terms and the syntax that an application understands (granted the dictionaries are difficult to understand but you will get better at it the more you use them). Under the file menu of AppleScript Editor choose "Open dictionary" and a list of all the applications that understand applescript is shown. Choose an application from that to see its dictionary. So for example, you are trying to figure out TextEdit's "save as" command. You can usually get good direction from the dictionary so you should take a look at that. Use the search field to search!
So I hope that helps! Good luck.

Resources