Script critique: Archive only top-level tasks

Hey all, I was hoping I could get some critique on a script. This is my first attempt at scripting TaskPaper with JavaScript so I’m mostly curious if anything here could be more idiomatic or failure-tolerant.

Goal: the script archives “done” tasks to an Archive project, but only if that task is a “top-level” task. This is maybe an overly simplistic definition of top-level, but I’m assuming any task with a depth of 2 is a child of a project, and not a child of a project-less task. (This script lets me archive without disconnecting children from their parent tasks.)

var TaskPaper = Application('TaskPaper');

function fn(editor, options) {
	var outline = editor.outline;
	var archive = outline.evaluateItemPath("//Archive:")[0];
	
	outline.groupUndoAndChanges(() => {
		if (typeof archive === "undefined") {
			archive = outline.createItem("Archive:");
			outline.root.appendChildren(archive);
		}
	
		var topLevelItems = outline.evaluateItemPath("@done except Archive//*").filter(i => i.depth === 2)

		topLevelItems.map(item => {
			item.removeFromParent();
			archive.appendChildren(item)
		});
	});
}

TaskPaper.documents[0].evaluate({
	script: fn.toString()
})

Thank you!

Might be cleaner to incorporate the filter logic into the item path itself like this:

var topLevelItems = outline.evaluateItemPath("/*/@done except Archive//*")

If you wan to find only @done items that are direct descendent of projects you can use this item path:

var topLevelItems = outline.evaluateItemPath("project/@done except Archive//*")

Then you don’t need to hard code the items depth into the script. And it will work if you have nested projects. Anyway, but different logic, but maybe useful.

1 Like

Much more info on item path capability and syntax can be found: Searches · TaskPaper User's Guide