JXA: Creating a .kmactions plist file from a JavaScript object

With Peter's help, here is a JavaScript for Automation function which writes out a .kmactions file (plist format) from a set of Keyboard Maestro Action properties gathered in a JavaScript Object.

// writeKMActionplist :: Object -> String -> file IO ()
function writeKMActionplist(dctAction, strPath) {
            .stringByStandardizingPath, true

If for example, taking inspiration from Chris Stone's dated comment action macro Keyboard Maestro “Paste Dated Attribution Action v1.0” Macro we define the action we want in a JavaScript form (with a few computed or variable-retrieved elements) like this:

    var dctAction = {

        ActionColor: 'Orange',
        ActionName: 'A Macro by ' + strName,
        MacroActionType: 'Comment',
        Text: 'Authored by ' + strName + ' ' + strEmail +
            '\n' + 'Created: ' + strNow + '\n' +
            'Modified: ' + strNow


We can then save the JS object as a string to a KM variable

and/or write it out as a .kmActions plist file:


For a full example, here is a variant of Chris's original macro which defines the custom Comment action as a collection of JavaScript key-value pairs, and then writes them out as a .kmActions file using writeKMActionplist()

kmActions .plist file from JavaScript object.kmmacros (22.5 KB)

For a few related tools and methods, see Executing JavaScript Object versions of actions and macros – some simple tools

Not sure how to word this correctly, so I hope you can understand what I'm asking: Why is your method better than just building the plist using variables and text, like this:

My example here is certainly more readable, isn't it?

Not arguing here - just trying to understand. :slight_smile:

I guess the value of a tool is largely the ease with which it comes to a particular hand.

Working with JS objects is certainly flexible if there is any run-time computed element, interacts well with JavaScript for Automation, and happens to be the idiom in which I am personally most at home, but other tools may well work better for others.

I like XML, don’t personally find it all that readable though
(But the languages I find most readable are simply those I have read most of :slight_smile: )

(I also find it helpful, incidentally, to have the broad type-checking done by the JS compiler - easy to get minor glitches in the XML string, and the JS REPL loop (checking that objects are well formed) is just a little faster and lighter).

No particular preference for how others do it :slight_smile:

Thanks for your explanation, and I totally get it.

I really appreciate your eagerness to help others learn; you have a special gift for explaining things. I was reading some of your comments in another thread in which you were offering suggestions as to how someone could “clean up” their code example. I’m a developer also, and I was thinking similar things to what you said, but I never could have voiced them in the simple and non-threatening way you did.

So just so you know, I hold your opinion in the highest regard, and if I ever sound otherwise, it’s just because my special gift is to sound like I’m attacking or at least criticizing, when all I wanted to do was understand. :slight_smile:

1 Like

Wow. Highly educational and entertaining. Probably useful too :grin:.

1 Like

PS in case anyone finds that brevity helps readability, I realise in retrospect that we can also write it more simply as:

// writeKMActionplist Object -> String -> file IO ()
function writeKMActionplist(dctAction, strPath) {
            .stringByStandardizingPath, true

( See the $() operator under ‘Wrapping and Unwrapping’ in the JavaScript for Automation Release Notes)


1 Like