A macro for TaskPaper 3 and Day One 2 (or 1)
TaskPaper 3 archive @done and log to Day One ver 1 or 2.kmmacros (26.5 KB)
(Contains a JavaScript for Automation translation of an earlier AppleScript by Brett Terpstra.
Brett's original script was for TaskPaper 2 and Day One 1)
This macro:
- Moves items tagged as @done to an Archive: project in the same TaskPaper 3 file
- Logs a record of the completed items to Day One version one or two (whichever is installed)
- Gives a notification
JavaScript for Automation Source of the main action:
// VER 0.05
// TASKPAPER 3 ARCHIVE DONE AND LOG TO DAY ONE Ver 1 or 2
// A JavaScript for Applications translation of an orginal script by Brett Terpstra
// http://brettterpstra.com/2012/02/23/log-taskpaper-archives-to-day-one/
// For TaskPaper 3, and DayOne version 1 or 2
(function (dctOptions) { // For option keys and their values, see end of script
'use strict';
// TASKPAPER 3 EVALUATION CONTEXT:
function fn(editor, options) {
// Task with some of its tags removed
function tagsPruned(oTask, lstNoiseTags) {
return lstNoiseTags.reduce(function (t, strTag) {
var strAttrib = 'data-' + strTag;
if (t.hasAttribute(strAttrib)) {
t.removeAttribute(strAttrib);
}
return t;
}, oTask);
}
// Task with a @project(strProjName) tag added (if not found)
function projectTagged(oTask) {
if (!oTask.hasAttribute('data-project')) {
if (oTask.getAttribute('data-type') !== 'project') {
var project = taskProject(oTask),
strProj = project ? (function () {
var strText = project.bodyString;
return strText.slice(0, strText.indexOf(':'));
})() : '';
if (strProj) oTask.setAttribute('data-project', strProj);
}
}
return oTask;
}
// Immediately enclosing project of the task
function taskProject(oTask) {
var p = oTask,
blnFound = false;
while (!(blnFound = (p.getAttribute('data-type') === 'project'))) {
p = p.parent;
}
return blnFound ? p : undefined;
}
// ARCHIVE AND LOG
var outline = editor.outline,
// EXISTING OR NEW ARCHIVE PROJECT ?
as = editor.outline.evaluateItemPath(
'/(Archive and @type=project)[-1]'
),
archive = as.length > 0 ? as[0] : (function () {
var newArchive = outline.createItem('Archive:');
outline.groupUndoAndChanges(function () {
outline.root.appendChildren(
newArchive
);
});
return newArchive;
})(),
oFirstChild = archive.firstChild || (function () {
outline.groupUndoAndChanges(function () {
archive.appendChildren(outline.createItem());
});
return archive.firstChild;
})();
// COMPLETED BUT UNARCHIVED TASKS ?
tasks = outline.evaluateItemPath('@done except /Archive//*');
// ARCHIVED AND LISTED
if (tasks.length > 0) {
// If we have a non-circular destination, make the move ...
if (oFirstChild && (tasks.indexOf(oFirstChild) === -1)) {
var lstNoise = options.tagsToStrip,
strProjectPrefix = options.projectPrefix;
// project-tagged and noise-tag-pruned
outline.groupUndoAndChanges(function () {
outline.insertItemsBefore(
tasks.map(function (x) {
return projectTagged(tagsPruned(
x,
lstNoise));
}),
oFirstChild
);
});
// loggable string
return tasks.map(function (t) {
return (
t.getAttribute(
'data-type'
) === 'project' ? strProjectPrefix : ''
) + t.bodyString;
})
.join('\n');
} else return [];
} else return '';
}
// JS FOR APPLICATIONS EVALUATION CONTEXT:
var ds = Application("com.hogbaysoftware.TaskPaper3")
.documents,
d = ds.length ? ds[0] : undefined,
strFileName = d ? d.name() : '',
strHeader = dctOptions.fileNameAsHeader && d ? (
'## ' + strFileName + '\n\n'
) : '',
strArchive = d ? d.evaluate({
script: fn.toString(),
withOptions: {
tagsToStrip: ['na', 'next', 'priority', 'waiting'],
projectPrefix: dctOptions.projectPrefix
}
}) : '';
// Submits the string to Day One through the command line tool at:
// http://dayoneapp.com/faq/#commandlineinterface
//
// Day One Ver 1 may need:
// Run `ln -s "/Applications/Day One/Day One.app/Contents/MacOS/dayone" /usr/local/bin/dayone`
// to make it available on that path
// Day One Ver 2:
// -- The CLI will generates an error unless we specify a default journal
// You may need to run:
// $ alias dayone='/usr/local/bin/dayone -j=\"~/Library/Group\ Containers/5U8NS4GX82.dayoneapp2/Data/Auto\ Import/Default\ Journal.dayone\"'
if (strArchive) {
var a = Application.currentApplication();
(a.includeStandardAdditions = true, a)
.doShellScript(
'/usr/local/bin/dayone' + (dctOptions.dayOneVersion > 1 ? (
' -j="~/Library/Group\ Containers/5U8NS4GX82.dayoneapp2/Data/Auto\ Import/Default\ Journal.dayone"'
) : '') +
' new <<T3DY2_END\n' + strHeader + strArchive +
'\nT3DY2_END'
);
return JSON.stringify({
fileName: strFileName,
logged: strArchive
}, null, 2);
} else return '';
// OPTIONS
})({ // Precede each log with TaskPaper filename as header ?
fileNameAsHeader: true,
projectPrefix: '### ', // Day One prefix for projects ? ( '' to skip )
// Day One Version (auto-detects) or manually specify 1 or 2
dayOneVersion: parseInt(
Application("Day One")
.version()
.charAt(0), 10
)
})