Hi,
I’m a novice when it comes to scripting, so I’m wondering if anyone could provide any guidance at writing a script that would calculate the number of days it took to complete a task based on the dates listed in the @start and @done tags within a task?
Not sure how to do that or where to start since a TaskPaper doc has multiple @start and @done tags.
Thanks for the consideration!
You want each task which has both a @start
and a @done
tag to acquire something like a @days(n)
tag, (where n
is some number of days) ?
For that kind of thing you could begin by pasting the whole of the following rough draft into Script Editor, and setting the language selector at top left to JavaScript
, before hitting the run button.
(Experiment first with dummy data to make sure that it’s doing what you want).
( ⌘Z to reverse the effects of the script )
Expand disclosure triangle to view JS source
(() => {
"use strict";
// Add a @days(n) tag in any lines which have both
// @start(date) and @done(date) tags
// Draft 0.4
// ------------ JS FOR AUTOMATION CONTEXT ------------
// main :: IO ()
const main = () => {
const doc = Application("TaskPaper").documents.at(0);
return doc.exists()
? doc.evaluate({
script: `${TaskPaperContext}`,
withOptions: { docName: doc.name() }
})
: "No document open in TaskPaper.";
};
// ---------------- TASKPAPER CONTEXT ----------------
const TaskPaperContext = (editor, options) => {
const
outline = editor.outline,
day = 24 * 60 * 60 * 1000,
docName = options.docName;
// accumulation :: (Int, Item) -> IO Int
const accumulation = (sofar, item) =>
["start", "done"].every(
tag => item.hasAttribute(`data-${tag}`)
)
? daysElapsed(sofar, item)
: sofar
// daysElapsed :: (Int, Item) -> IO Int
const daysElapsed = (sofar, item) => {
const
dates = ["done", "start"].map(
k => new Date(item.getAttribute(`data-${k}`))
),
elapsed = Math.round(
(dates[0] - dates[1]) / day
);
return (
item.setAttribute("data-days", elapsed),
sofar + elapsed
);
};
let nDocumentDays = 0;
return (
outline.groupUndoAndChanges(() => {
nDocumentDays = outline.items.reduce(
accumulation,
nDocumentDays
)
}),
`Sum of task days in "${docName}": ${nDocumentDays}`
);
};
// MAIN ---
return main();
})();
See: Using Scripts · TaskPaper
2 Likes