A draft script which places a sorted Markdown list of all your Keyboard Maestro macros, by group and name, in the clipboard.
( Marked 2 can generate rich text and PDF from markdown clipboards )
(If the first action is a comment, also includes the comment title and text).
Reads the main Keyboard Maestro Macros.plist directly, so the script should not be used unless that file is fully backed up.
Yosemite only β uses Javascript for Applications.
Markdown listing of all macros, with any initial comments.kmmacros (20.2 KB)
Uncompressed source:
// Markdown listing of Keyboard Maestro library
// Sorted by Groups and Macro names
// Includes any initial comment (i.e. if first action of Macro is comment)
// CAUTION: Reads directly from the user's main Keyboard Maestro Macros.plist.
//
// Even read-only operations should only be done on important data
// IF IT IS WELL BACKED UP
// Back up your KM data **before** running this script
/****
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****/
// Rob Trew, MIT license, 2015
// draft 0.3 Add comments, slight tidy
function run() {
var a = Application.currentApplication(),
sa = (a.includeStandardAdditions = true, a);
// Keyboard Maestro Macros.plist or specified file read to Markdown
// MaybePath || PathToMain plist --> Markdown --> Markdown Clipboard
function kmMacrosMarkDown(strPlistPath) {
strPlistPath = strPlistPath || sa.pathTo(
'application support', {
from: 'user domain'
}
) + "/Keyboard Maestro/Keyboard Maestro Macros.plist";
var strGroupHdr = '\n#### ',
strMacroHdr = '- ';
// Objects ranked by any .name string
// a --> b --> (-1 | 0 | 1)
var nameSort = function (a, b) {
var aName = a.name,
bName = b.name;
a = aName ? aName.toLowerCase() : '';
b = bName ? bName.toLowerCase() : '';
return (a < b) ? -1 : (a > b ? 1 : 0);
};
var lstGroups = ObjC.deepUnwrap(
$.NSDictionary.dictionaryWithContentsOfFile(strPlistPath)
).MacroGroups,
// Unsorted list of Group objects with name and Markdown macro listings
lstG = lstGroups.reduce(
function (lstG, g) {
// Unsorted list of Macro objects with name and MD for any starting comment
var oMacros = g.Macros,
lstMacros = oMacros ? oMacros.reduce(
function (lstM, m) {
var oActions = m.Actions,
dctFirstAction = (oActions && oActions.length) ?
oActions[0] : null;
// MACRO OBJECT with name and any initial comment
return lstM.push({
name: m.Name,
comment: "Comment" === (
dctFirstAction ? dctFirstAction.MacroActionType : ""
) ? "\t<b>" + dctFirstAction.Title + "</b>\n\t" + (
dctFirstAction.Text.split("\n").join("\n\t") + "\n"
) : ""
}), lstM;
}, []
) : [];
// GROUP OBJECT with name and MD for sorted macros
return (lstG.push({
name: g.Name,
macros: (lstMacros.sort(nameSort), lstMacros).reduce(
function (s, m) {
return s + strMacroHdr + m.name + '\n' + m.comment + '\n';
}, ''
)
}), lstG);
}, []
);
// Markdown listing of sorted Groups, with their sorted macros
return (lstG.sort(nameSort), lstG).reduce(
function (s, g) {
return s + strGroupHdr + g.name + '\n' + g.macros;
}, ''
);
}
// Defaults to reading:
// ~/Library/Application Support/Keyboard Maestro/Keyboard Maestro Macros.plist
var strReport = kmMacrosMarkDown();
return (
sa.setTheClipboardTo(strReport), strReport
);
}