Passing multiple options from the Keyboard Maestro GUI to 'Execute JavaScript for Automation' and 'Execute AppleScript' actions can sometimes involve using several KM variables, inflating Keyboard Maestro's list of variable names.
Keyboard Maestro 8's new Dictionaries now provides a good way of passing a set of key-value option pairs to a script in the form of a single dictionary, rather than as a list of separate variables.
For example, TaskPaper scripts typically involve passing a dictionary of key:value pairs as the withOptions argument to the evaluate() function.
We can now obtain this JavaScript options dictionary directly from the set of keyValue pairs in a single Keyboard Maestro dictionary.
If a section of our macro sets these up:
A generic kmDict function can convert the Keyboard Maestro dictionary to a JavaScript dictionary for us.
ES6 (Sierra onwards) JavaScript example:
(() => {
'use strict';
// GENERIC FUNCTION ------------------------------------------------------
// kmDict :: String -> Dict
const kmDict = strName => {
const kmd = Application('Keyboard Maestro Engine')
.dictionaries[strName].dictionaryKeys;
return Object.keys(kmd)
.reduce((a, k) => {
const kv = kmd[k];
return (
a[kv.name()] = kv.value()
.trim(),
a
);
}, {});
};
// TEST ------------------------------------------------------------------
return kmDict('tp3Toggle');
// --> {"parseValueAsDateTime":"1", "subTree":"0", "tag":"incubate"}
})();
( And if we wanted, we could also derive an AppleScript record from a Keyboard Maestro dictionary, though AS records are always a little bit harder to deal with than JS Dictionaries )
use framework "Foundation"
use scripting additions
-- kmDict :: String -> Record
on kmDict(strName)
tell application ("Keyboard Maestro Engine")
set ca to current application
set dict to dictionary named strName
script kv
on |λ|(a, k)
set nsDct to (ca's NSMutableDictionary's dictionaryWithDictionary:a)
nsDct's setValue:(value of dictionary key k of dict) forKey:k
item 1 of ((ca's NSArray's arrayWithObject:nsDct) as list)
end |λ|
end script
my foldl(kv, {name:""}, name of dictionary keys of dict)
end tell
end kmDict
-- TEST ----------------------------------------------------------------------
on run
kmDict("tp3Toggle")
--> {notify:"1", parseValueAsDateTime:"1", tag:"incubate", subTree:"0"}
end run
-- GENERIC FUNCTIONS ---------------------------------------------------------
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn