Items marked as done can be moved to the Archive project, and with a Preferences option enabled the project in which they resided can be added in a @project tag when doing this.
I would like to move entries to projects different from Archive (e.g. a “Maybe Later” project) and have the same feature to add the project tag.
How do I go about creating a script that does that?
Here’s TaskPaper’s code for implementing “Archive Done”:
archiveDone = (editor) ->
outline = editor.outline
selection = editor.selection
startItem = selection.startItem
endItem = selection.endItem
archive = outline.evaluateItemPath("//@text = Archive:")[0]
doneItems = Item.getCommonAncestors(outline.evaluateItemPath("//@done except //@text = Archive://@done"))
removeExtraTags = Birch.preferences.get('BRemoveExtraTagsWhenArchivingDone')
addProjectTag = Birch.preferences.get('BIncludeProjectWhenArchivingDone')
outline.groupUndoAndChanges ->
unless archive
outline.root.appendChildren(archive = outline.createItem('Archive:'))
for each in doneItems
if removeExtraTags
for eachName in each.attributeNames
if eachName.indexOf('data-') is 0 and eachName isnt 'data-type' and eachName isnt 'data-done'
each.removeAttribute(eachName)
if addProjectTag
if projects = (eachProject.bodyContentString for eachProject in outline.evaluateItemPath('ancestor::@type=project', each)).join(' / ')
each.setAttribute('data-project', projects)
if (each is startItem or each.contains(startItem)) or (each is endItem or each.contains(endItem))
if previousItem = editor.getPreviousDisplayedItem(startItem)
selection = startItem: previousItem, startOffset: -1
else
selection = start: 0
archive.insertChildrenBefore(doneItems, archive.firstChild)
editor.moveSelectionToItems(selection)
Note that the code is Coffee Script, but that’s translated into JavaScript during compile process. So syntax will be different when converting to JavaScript, but all the same API should be present. Anyway I hope that gets you started.
Here is the script translated into Javascript (automatically, so code is a bit messy, but functional) and wrapped in script that will run from Script Editor app:
var TaskPaper = Application('TaskPaper')
function TaskPaperContext(editor, options) {
let outline = editor.outline;
let selection = editor.selection;
let startItem = selection.startItem;
let endItem = selection.endItem;
let archive = outline.evaluateItemPath("//@text = Archive:")[0];
let doneItems = Item.getCommonAncestors(outline.evaluateItemPath("//@done except //@text = Archive://@done"));
let removeExtraTags = Birch.preferences.get('BRemoveExtraTagsWhenArchivingDone');
let addProjectTag = Birch.preferences.get('BIncludeProjectWhenArchivingDone');
outline.groupUndoAndChanges(() => {
var each, eachName, eachProject, i, j, len, len1, previousItem, projects, ref;
if (!archive) {
outline.root.appendChildren(archive = outline.createItem('Archive:'));
}
for (i = 0, len = doneItems.length; i < len; i++) {
each = doneItems[i];
if (removeExtraTags) {
ref = each.attributeNames;
for (j = 0, len1 = ref.length; j < len1; j++) {
eachName = ref[j];
if (eachName.indexOf('data-') === 0 && eachName !== 'data-type' && eachName !== 'data-done') {
each.removeAttribute(eachName);
}
}
}
if (addProjectTag) {
if (projects = ((function() {
var k, len2, ref1, results;
ref1 = outline.evaluateItemPath('ancestor::@type=project', each);
results = [];
for (k = 0, len2 = ref1.length; k < len2; k++) {
eachProject = ref1[k];
results.push(eachProject.bodyContentString);
}
return results;
})()).join(' / ')) {
each.setAttribute('data-project', projects);
}
}
if ((each === startItem || each.contains(startItem)) || (each === endItem || each.contains(endItem))) {
if (previousItem = editor.getPreviousDisplayedItem(startItem)) {
selection = {
startItem: previousItem,
startOffset: -1
};
} else {
selection = {
start: 0
};
}
}
}
return archive.insertChildrenBefore(doneItems, archive.firstChild);
});
return editor.moveSelectionToItems(selection);
}
var text = TaskPaper.documents[0].evaluate({
script: TaskPaperContext.toString()
});
TaskPaper.includeStandardAdditions = true
TaskPaper.setTheClipboardTo(text)