Hi all,
I’m trying to create a script that moves all @today items to the top of their project and @waiting items to the bottom. I used to have on for TP2, but making one for TP3 / jxa is proving a bit more difficult to start with. Would anyone happen to have some pointers / boilerplate code to start with? I’m somewhat able to code myself, but would appreciate some ideas how to build this!
thanks!
Maarten
2 Likes
Can post your old TP2 script ?
(That would simplify getting the details so that we can sketch a TP3 version for you)
Very crude, but see below. I can’t really see how to include code like this nicely so I’ve included it as preformatted text:
tell application "TaskPaper" tell front document set p to «class STcp» of «class STsy» set move_entry_ids to {} set done_entry_ids to {} repeat with each in every «class TPer» of p if exists («class TPtg» named "waiting" of each) then set done_entry_ids to done_entry_ids & id of each else set move_entry_ids to move_entry_ids & done_entry_ids set done_entry_ids to {} end if end repeat repeat with each in move_entry_ids move «class TPer» id each to end of every «class TPer» of p end repeat end tell end tell
A rough indication – only for testing with dummy data:
(function () {
'use strict';
// TASKPAPER CONTEXT
function TaskPaperContext(editor, options) {
var outline = editor.outline,
projects = outline.evaluateItemPath(
'//@waiting or @today/ancestor::project'
);
outline.groupUndoAndChanges(function () {
projects.forEach(function (p) {
// THREE TYPES OF ITEM IN THE PROJECT
// Where ! means (not ...)
var lstChildren = p.children,
// @waiting (unless also @today)
lstWaiting = lstChildren.filter(function (x) {
return x.hasAttribute('data-waiting') &&
!x.hasAttribute('data-today');
}),
// anything tagged @today
lstToday = lstChildren.filter(function (x) {
return x.hasAttribute('data-today');
}),
// anything with neither @today nor @waiting
lstOther = lstChildren.filter(function (x) {
return !x.hasAttribute('data-today') &&
!x.hasAttribute('data-waiting');
});
// Remove from existing position
lstChildren.forEach(function (x) {
x.removeFromParent();
});
// and reinsert in order
p.appendChildren(lstToday.concat(lstOther, lstWaiting));
})
});
}
// JAVASCRIPT FOR AUTOMATION CONTEXT
var ds = Application('TaskPaper')
.documents;
return ds.length ? ds[0].evaluate({
script: TaskPaperContext.toString(),
withOptions: {}
}) : undefined;
})();
1 Like
This is absolutely terrific! Exactly what I was looking for and a nice way to up my own coding skills a bit by adapting this. Thanks so much! Small dummy question: how do you embed Javascript code in a post, I seem to overlook that option in the forum editor
See under ‘Github fenced code blocks’
```javascript
4 space indented code goes here
```
If you want to experiment with a slightly different approach – possibly quicker to fine-tune – you could try doing it all with paths:
(function () {
'use strict';
// TASKPAPER CONTEXT
function TaskPaperContext(editor, options) {
// concatMap :: (a -> [b]) -> [a] -> [b]
var concatMap = function (f, xs) {
return [].concat.apply([], xs.map(f));
};
var outline = editor.outline,
projects = outline.evaluateItemPath(
'//@waiting or @today/ancestor::project'
);
outline.groupUndoAndChanges(function () {
projects.forEach(function (p) {
// THREE TYPES OF ITEM IN THE PROJECT
var filter = function (strPath) {
return outline.evaluateItemPath(strPath, p);
},
lstOrdered = concatMap(filter, [
'@today',
'not (@waiting or @today)',
'@waiting and not @today'
]);
// Remove from existing position
p.children.forEach(function (x) {
x.removeFromParent();
});
// and reinsert in order
p.appendChildren(lstOrdered);
});
});
}
// JAVASCRIPT FOR AUTOMATION CONTEXT
var ds = Application('TaskPaper')
.documents;
return ds.length ? ds[0].evaluate({
script: TaskPaperContext.toString(),
withOptions: {}
}) : undefined;
})();