ExtendScript/JavaScript Snippets

Get the path to the currently running script (ExtendScript)

var scriptFile = File($.fileName);

This assumes that the currently running script is in a file. If you run a script via app.doScript() there is no file name. In those cases, you need to pass that information in from the calling script.

Get the folder containing the currently running script (ExtendScript)

var scriptFolder = File($.fileName).parent;

This assumes that the currently running script is in a file. If you run a script via app.doScript() there is no file name. In those cases, you need to pass that information in from the calling script.

Loop for a certain time (JavaScript)

var now = new Date().getTime(); 
var millisecondsToRunFor = 2000; 
do {
  // Do something
}
while (new Date().getTime() - now < millisecondsToRunFor);

// ES Sample
var now = new Date().getTime(); 
var millisecondsToRunFor = 2000; 
do {
  $.sleep(0.5);
  $.writeln('busy');
}
while (new Date().getTime() - now < millisecondsToRunFor);
$.writeln('done');

Measure runtime (ExtendScript)

// Merely using $.hiresTimer resets it to 0. Ignore the return value
$.hiresTimer;
// Do stuff
// $.hiresTimer returns microseconds since last time it was called
alert("That took " + $.hiresTimer/1000000 + " seconds");

Where to store persistent data (ExtendScript)

var FOLDER_STORE = Folder(Folder.userData.fsName + "/com.rorohiko.whateverproject"); 
if (! FOLDER_STORE.exists) { 
  FOLDER_STORE.create(); 
}

Where is the desktop (ExtendScript)

var DESKTOP = Folder("~/Desktop");

Where are the application fonts in InDesign (ExtendScript)

var appFontsFolder = Folder(app.filePath.fsName + "/Fonts");

What platform are we running on (Win or Mac)? (ExtendScript)

var isMac = $.os.charAt(0) == 'M';

Despace a string (JavaScript)

Make sure to store the RegExps in some global or closure rather than use explicit constants. Compiling RegExp has a performance cost, and compiling them once can help speed up things.

Utils.kDespaceRegExp                    = /\s+/g;
...
var despaced = str.replace(Utils.kDespaceRegExp, "");

Trim a string (JavaScript)

Utils.kTrimRegExp                       = /^\s*(.*?)\s*$/;
...
var trimmed = str.replace(Utils.kTrimRegExp, "");

Nasty, quick-and-dirty JSON parsing (JavaScript)

Do not do this on data that came from ‘outside’; this code then becomes a security risk.

You have to be absolutely sure the jsonString is not potentially harmful. If in any doubt, use json2.js (https://github.com/douglascrockford/JSON-js) instead.

var data;
var jsonScript = "data = " + jsonString;
eval(jsonScript);
retVal = data;

I use this to pass complex data between CEP and ExtendScript, or between two ExtendScript engines.

There is also uneval, which needs additional quoting to be useful.

a = {b:"a", c:"d\ne"};

eval("x = " + uneval(a)); // uh-oh. no go.

Wrap an escaped string into single or double quotes (JavaScript)

// sQ: Wrap a string in double quotes
function dQ(s) {
    return '"' + s.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r") + '"';
}

// sQ: Wrap a string in single quotes
function sQ(s) {
    return "'" + s.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,"\\r") + "'";
}

var s1 = "abc\n\r\"'";
var s2;
eval("s2 = " + dQ(s1));

Escape/unescape (JavaScript) do similar stuff to dQ/eval

console.log(unescape(escape("abc\n\r\"'")));

Usable date string (e.g. for logs):

function zeroPrefixFill(value, length)
{
    if (! value || ! (("number" == typeof value) || ("string" == typeof value)))
    {
        value = "0";
    }
    else
    {
        value = Math.round(value);
    }
    value = "" + value;
    while (value.length < length)
    {
        value = "0" + value;
    }
    if (value.length > length)
    {
        value = value.substr(value.length - length);
    }

    return value;
}


function dateToISO8601(date)
{  
    var year = date.getUTCFullYear();
    var month = date.getUTCMonth() + 1;
    var day = date.getUTCDate();
    var hour = date.getUTCHours();
    var minute = date.getUTCMinutes();
    var second = date.getUTCSeconds();
    var retVal = 
    zeroPrefixFill(year,4) + "-" + 
    zeroPrefixFill(month,2) + "-" + 
    zeroPrefixFill(day,2) + "T" + 
    zeroPrefixFill(hour,2) + ":" + 
    zeroPrefixFill(minute,2) + ":" + 
    zeroPrefixFill(second,2) + "Z";

    return retVal;
}

dateToISO8601(new Date());

Wrap a whole script into a single undo in InDesign (ExtendScript)

app.doScript("someFunctionCall()", ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Describe what you did");

Save and restore the measurement units (InDesign ExtendScript)

 var savedHorizontalMeasurementUnits = theDoc.viewPreferences.horizontalMeasurementUnits;
  var savedVerticalMeasurementUnits = theDoc.viewPreferences.verticalMeasurementUnits;

  theDoc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.POINTS;
  theDoc.viewPreferences.verticalMeasurementUnits = MeasurementUnits.POINTS;
  try {
  ...
  catch (err) {
  }

  theDoc.viewPreferences.horizontalMeasurementUnits = savedHorizontalMeasurementUnits;
  theDoc.viewPreferences.verticalMeasurementUnits = savedVerticalMeasurementUnits;

Suppress dialogs while script is running (InDesign ExtendScript)

app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
...
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;

Create or access a global variable from inside a function (ExtendScript)

function somewhereNested() {
  $.global.theVar = "bla";
}

creates a global variable theVar

Read a file into a string (ExtendScript)


var f = File("~/Desktop/input.txt"); // Sample file on Desktop
f.encoding="UTF8"; // Reading UTF-8 text
f.open("r"); // a = append, w = write, r  = read
var s = f.read();
f.close();

Write to a text file (ExtendScript)

var f = File(Folder.temp + "/output.txt"); // Sample file in temp folder
f.encoding="UTF8"; // Writing UTF-8 text
f.open("a"); // a = append, w = write
f.writeln(msg);
f.close();

Get current engine name (ExtendScript)

targetengine "myEngine"
var f = File("~/Desktop/t.txt");
f.open("a");
f.writeln($.engineName);
f.close();