How do I translate these AppleScripts to JavaScript?

Hello all,

I have three AppleScripts that I use to perform my GTD weekly review. They are triggered by keyboard shortcuts using Keyboard Maestro. Since I am moving from TaskPaper 2 to TaskPaper 3, I need to update the scripts. Any help is greatly appreciated.

The first AppleScript adds @review to every item:

tell application "TaskPaper"
	tell front document
		repeat with each in entries
			tell each
				make tag with properties {name:"review"}
			end tell
		end repeat
	end tell
end tell

The second AppleScript deletes the @review tag from the current selection:

tell application "TaskPaper"
	tell front document
		tell selected entry
			if (exists tag named "review") then
				delete tag named "review"
			end if
		end tell
	end tell
end tell

The final one removes any @review tags that I missed:

tell application "TaskPaper"
	tell front document
		repeat with each in entries
			tell each
				if (exists tag named "review") then
					delete tag named "review"
				end if
			end tell
		end repeat
	end tell
end tell

How do I translate these to JavaScript?

add review to each task

You could write it like this (adjusting the options at the end if you want to tag projects and/or notes as well as tasks)

(function (dctOptions) {
    'use strict';


    // TASKPAPER CONTEXT:

    function TaskPaperContext(editor, options) {

        var outline = editor.outline;

        // for a single Cmd-Z to undo it all, if required
        outline.groupUndoAndChanges(function () {
         
            var strAttrib = 'data-' + options.tagToAdd;
         
            // Get the list of lines to edit
            outline.evaluateItemPath(options.linesToTag)
            
                // and loop through them setting the data- attribute
                // (user tag) that you want
                .forEach(function (item) {
                    item.setAttribute(
                        strAttrib,
                        options.tagValue
                    );
                });
        })

    }


    // JAVASCRIPT FOR AUTOMATION CONTEXT:

    var ds = Application("TaskPaper")
        .documents,
        d = ds.length ? ds[0] : undefined;

    // Pass the script from JXA to TaskPaper, with options
    return d ? d.evaluate({
        script: TaskPaperContext.toString(),
        withOptions: dctOptions
    }) : undefined;


    // OPTIONS
})({
    linesToTag: '//@type=task',
    tagToAdd: 'review',
    tagValue: ''
});

The second two can be covered by making two copies of one script, editing the selectedOnly option at the end to true for the first case, and false for the case where you want all such tags to be cleared:

(function (dctOptions) {
    'use strict';
    
    // TASKPAPER CONTEXT:

    function TaskPaperContext(editor, options) {

        var outline = editor.outline;

        // for a single Cmd-Z to undo it all, if required
        outline.groupUndoAndChanges(function () {
        
            var strTag = options.tagToClear,
                strAttrib = 'data-' + strTag;
            
            // Either just the selected items,
            // or ALL items with this tag
            // (depending on the .selectedOnly option (true | false)
            var lstItems = options.selectedOnly ? (
                editor
                .selection
                .selectedItems
            ) : outline.evaluateItemPath('//@' + strTag);
             
            lstItems.forEach(function (item) {
                item.removeAttribute(strAttrib);
            });
            

        });

    }
    
     // JAVASCRIPT FOR AUTOMATION CONTEXT:

    var ds = Application("TaskPaper")
        .documents,
        d = ds.length ? ds[0] : undefined;

    return d ? d.evaluate({
        script: TaskPaperContext.toString(),
        withOptions: dctOptions
    }) : undefined;

    // OPTIONS
})({
    tagToClear: 'review',
    selectedOnly: false
});
2 Likes

Thanks @complexpoint!

One question on the add review to each task script: if I want to add the tag to projects and/or notes, how do I do that?

I presume I edit this line:

linesToTag: '//@type=task',

But I am not sure of the syntax.

Generally, when you are drafting a script like this, you can experiment with itemPaths in the search panel until you get a view which shows only the lines that you want to be affected.

In this case, if you simply want to tag all lines you might try:

//*

or permutations of patterns like:

//@type=project or @type=task or @type=note

etc

2 Likes

Perfect—thanks again!

1 Like