A script which copies the Tyme.app database of tracked projects and tasks to the clipboard in TaskPaper 3 format.
I use it simply to get the names of some currently tracked items when starting a new TaskPaper file, so that further time counts of tracking from TaskPaper are added to the existing items in Tyme.app.
Can be run from something like Keyboard Maestro or Fastscripts, or, for testing, from Script Editor (Yosemite onwards – this is a JavaScript for Automation script).
var strClip = (function () {
'use strict';
// JSO nested and tagged text nodes -> TaskPaper 3 text
// [dct] -> Integer -> String
function jsoNestTP(lst, lngIndent) {
return lst.reduce(function (txt, node) {
var strType = node.type,
lstNest = node.nest,
dctTags = node.tags,
strTags = (dctTags ? tpTagString(dctTags) : '');
return txt + (lngIndent ? nreps('\t', lngIndent) : '') +
(strType === 'task' ? '- ' : '') + node.txt +
(strType === 'project' ? ":" : '') +
(strTags ? ' ' + strTags : '') + '\n' +
((lstNest && lstNest.length) ? jsoNestTP(lstNest, lngIndent + 1) : '');
}, '');
}
// JSO set of key-value pairs -> TaskPaper 3 tag string
// [(key, value)] --> String
function tpTagString(dctTags) {
return Object.keys(dctTags).map(function (k) {
var v = (k !== 'due') ? dctTags[k] : (
function() {
var strDate = dctTags[k],
lstMatch = strDate.match(/^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}):\d{2}/);
return (lstMatch ? lstMatch[1] + ' ' + lstMatch[2] : strDate);
}
)();
return '@' + k + (v ? '(' + v + ')' : '');
}).join(' ');
}
// Tyme projectTags or taskTags rewritten as JSO dict of key:value pairs
// Tyme Object --> String -> {(key, value)}
function tagSet(oParent, strClass) {
var dctTags = oParent[strClass]()
.reduce(function (a, tag) {
return (a[tag.name()] = "", a);
}, {}),
dte = oParent.duedate();
if (dte !== null) dctTags.due = dte.toISOString();
return (Object.keys(dctTags).length > 0 ? dctTags : undefined);
}
// Substring s repeated n times
// String -> Integer -> String
function nreps(s, n) {
var o = '';
if (n < 1) return o;
while (n > 1) {
if (n & 1) o += s;
n >>= 1;
s += s;
}
return o + s;
}
// MAIN
// Tyme interface -> JSO nest -> TaskPaper 3 text
return jsoNestTP(
Application("Tyme").projects()
.filter(function (p) {
return (p.archived() === false);
})
.map(function (p) {
return { // PROJECT
txt: p.name(),
'type': 'project',
'tags': tagSet(p, 'projecttags'),
nest: p.tasks()
.filter(function (t) {
return (t.archived() === false);
})
.map(function (t) {
return { // TASK
txt: t.name(),
'type': 'task',
'tags': tagSet(t, 'tasktags')
}
})
};
}),
0
);
})();
var a = Application.currentApplication(),
sa = (a.includeStandardAdditions = true, a);
sa.setTheClipboardTo(strClip);
sa.activate;
sa.displayNotification("Tyme.app projects copied as TaskPaper", {withTitle: "Copied to clipboard"})
strClip