ExtendScript: ESTK Line Endings

In a previous post I described how I set up my ExtendScript development environment. This is a quick follow up to help maintain compatibility between ESTK and your text editor of choice (I believe this issue is Mac specific, so if you are using windows hopefully you won’t encounter it).

On a OSX, The default line endings setting in ESTK is “Macintosh” (which seems logical). That being said, ESTK is quite old software, and OSX has changed the way they represent new lines in text files. This meant that any file I saved in ESTK and subsequently opened in Atom would be collapsed onto a single line.

Arghh!

Continue reading ExtendScript: ESTK Line Endings

Site Mailing List

If you have been following along with the content here at creationautomation.com and find it useful, I just added an email list sign-up feature. The list will be used to notify readers when new content is added to the site.

If you are interested in signing up, scroll to the bottom of this page and you will find a sign-up form.

Cheers,
Sid

ExtendScript: Setting up a Development Environment

Note: This post explains the development environment I use on OSX High Sierra. If you are using Windows your mileage may vary.

While it is possible to write scripts using the simplest of text editor and run those scripts from the menu’s of Photoshop, this development environment would be less than ideal. In an effort to improve upon this, Adobe released the ExtendScript ToolKit (ESTK). While it may have been great in its heyday, ESTK hasn’t been updated in years and tends to freeze frequently on my system. That being said, it does provide debugging capabilities not available by other means so I suggest installing it (see this post see this post for instructions) and using it when needed but not as your primary text editor.

Continue reading ExtendScript: Setting up a Development Environment

ExtendScript: Avoiding Gotchas #1 (Changing Iterators)

This post is the first in a series I’m calling “Avoiding Gotchas”, which will each focus on a tip that will help you prevent a subtle or tricky bug from ruining your day

Here is the situation. You have a Photoshop file with lots of layers (and layerSets). You would like to perform some operation to each of those layers, modifying them in some way. For example, perhaps you want to flatten each layerSet into individual layers.

Example layer-stack

Seems simple enough, right? One might write the following code:

var layerSets = app.activeDocument.layerSets;
for(var i = 0; i < layerSets.length; i++){
    layerSets[i].merge();
    }

We first get the collection of layerSets and then iterate over that collection, merging each of them as we go. Do you spot the bug? When we run that code on the example, it produces the following layer stack:

Uh oh!

What?! Group 1 and Group 3 were merged, but group 2 was not. Let me explain what is going on here. The problem has to do with the fact that we used the layerSets collection length as the end condition in our for loop. This is a problem because every time we call LayerSet.merge() on one of our layerSets, that collection shrinks by one. So, let’s walk through what happens:

– 1st iteration: i = 0, layerSets.length = 3, Group 1 is merged
– 2nd iteration: i = 1, layerSets.length = 2, Group 3 is merged (Group 1 no longer exists, so Group 3 has now shifted to layerSets[1])
– 3rd iteration: i = 2, layerSets.length = 1, i > layerSets.length, loop terminated

The gotcha here is: Be extra careful operating on an object being used within the termination condition for a loop. Modifying that object could have unintended side effects!

How can we fix our issue so that the code performs as intended? One option is to iterate in reverse, starting with the last element in layerSets, and working our way backwards to the first as follows:

var layerSets = app.activeDocument.layerSets;
for(var i = layerSets.length - 1; i >= 0; i--){
    layerSets[i].merge();
    }

It is important to note that layerSets.length still shrinks with each iteration, but this time it is okay because the corresponding layerSet has already been handled. Once again, let’s walk through each iteration:

– 1st iteration: i = 2, layerSets.length = 3, Group 3 is merged
– 2nd iteration: i = 1, layerSets.length = 2, Group 2 is merged
– 3rd iteration: i = 0, layerSets.length = 1, Group 1 is merged
– 4th iteration: i = -1, layerSets.length = 0, i < 0, loop terminated

Hooray!

Hopefully this helps save you some debugging time in the future.

If you have additional gotchas that you have encountered in the past and solved (or even ones that are still stumping you) comment below and I’ll write up a post on them in this series!

ExtendScript: Logging (Continued)

A few weeks ago, I posted about how to do some simple logging using ExtendScript. If you haven’t read that post, it can be found here. This post will go a bit deeper on this topic and provide some additional techniques for improved logging capabilities.

Oftentimes is useful to create one (or multiple) unique log file(s) for each time a script is executed. Rather than having to rewrite this type of functionality into every script I work on, I created a simple logging utility that can be reused across projects to make creating and using logs simple. The code for this library can be found in this repository on my GitHub.

Continue reading ExtendScript: Logging (Continued)

Actions in Extendscript (Part 3): Cleaning ScriptingListener Code

Note: This is the final post of a three-part series on how to use actions and the action manager to augment the capabilities of ExtendScript.

In the previous post, I explained how to utilize leverage an Adobe plugin called ScriptingListener to generate log files containing code for just about any Photoshop action that can be integrated directly into ExtendScript scripts. While powerful, this technique often produces code which is difficult to read and understand. This post will cover one tool that can be used to clean up the ScriptingListener code to make it more usable and maintainable.

Continue reading Actions in Extendscript (Part 3): Cleaning ScriptingListener Code

Actions in Extendscript (Part 2): Action Manager

Note: This is part two of a three-part series on how to use actions and the action manager to augment the capabilities of ExtendScript.

In the previous post I explained how to utilize actions to provide access to Photoshop features not included in the ExtendScript API. In this post I will take this one step further, utilizing a feature called the Action Manager. The official documentation for Action Manager is a bit… sparse* which can make using it tricky (some people call it “black magic”), but when used judiciously it can be another powerful tool in your toolbox.

Continue reading Actions in Extendscript (Part 2): Action Manager

Actions in Extendscript (Part 1): Normal Actions

Note: This is part one of a three-part series on how to use actions and the action manager to augment the capabilities of ExtendScript.

ExtendScript provides access to a significant portion of Photoshop’s functionality via its application programming interface (API). That being said, there are some features which either (1) Adobe decided not include or (2) which were released after the current version of the API was defined.

Continue reading Actions in Extendscript (Part 1): Normal Actions

ExtendScript: Importing Libraries

As scripts to automate your workflows become more complex, there becomes a need to break out commonly reused code into functions. This helps to avoid repeating code, leading to a solution that is much easier to maintain.

Functions within ExtendScript work as expected if you are familiar with JavaScript and if we define them in the same file as our main script, we can use them directly. For example:

#target photoshop

standardFunction();

function standardFunction(){
    $.writeln("The standard function was executed!");
    }

This code will print “The standard function was executed!” to the ExtendScript Toolkit console, indicating that the standardFunction() was successfully called.

Continue reading ExtendScript: Importing Libraries

ExtendScript: Logging (“Error: Console is Undefined”)

Okay, you have started to write some ExtendScript code to automate all sorts of tedious tasks, but your script isn’t working quite right. You need to debug it! Likely, this process will involve examining the values of certain variables while the script is running.

If this were JavaScript running in a browser, one obvious option that almost all developers will be familiar with is to log the objects of interest using console.log() and to open up the developer tools in the browser of choice to view the output. If this approach is taken for ExtendScript, the following error pops up:

Continue reading ExtendScript: Logging (“Error: Console is Undefined”)