Basic script to add selected text to TaskPaper 3 “Inbox”

Hi there. I’ve been trying (and failing) to come up with a script that will add selected text to a saved TaskPaper file, like the old “Add to TaskPaper Inbox” OS X service that TP 2 had. I am a complete amateur when it comes to coding, except for a little bit of PHP, and I am trying to learn JavaScript, so I thought attempting to interact with the new TaskPaper API would be a good way of learning.

But I am having trouble. I am sure the problems I have coming up against are extremely simple to solve, but would anyone be willing to give me some pointers? I’d love to be able to write scripts myself for TaskPaper and FoldingText. I have had some success with AppleScript, but it seems AppleScript is becoming a little deprecated these days?

Thanks in advance!

Here’s a start:

I think the TaskPaper part is good. But the “Get Selected Text” part seems inconsistent. I’m just running it from ScriptEditor… and that might be the problem. I think when Script Editor runs a script, it first deselects all text. So I think this might run OK from a keyboard shortcut.

var TaskPaper = Application('TaskPaper')
var SystemEvents = Application('System Events') 

// Get Selected Text (not quite working)
SystemEvents.keystroke('c', { using: 'command down' });
var app = Application.currentApplication();
app.includeStandardAdditions = true;
var selectedText = app.theClipboard()

// Send it to TaskPaper Inbox
TaskPaper.documents[0].evaluate({
	script: TPContext.toString(),
	withOptions: {text: selectedText }
});

function TPContext(editor, options) {
	var outline = editor.outline;
	var inbox = outline.evaluateItemPath("//Inbox:")[0];
	var items = ItemSerializer.deserializeItems(options.text, outline, ItemSerializer.TEXTMimeType);
	
	if (!inbox) {
		inbox = outline.createItem("Inbox:");
		outline.root.insertChildrenBefore(inbox, outline.root.firstChild);
	}
	
	inbox.insertChildrenBefore(items, inbox.firstChild);
}
2 Likes

Might timing be an issue ?

( Sometimes inserting a very brief pause after the keystroke allows time for the clipboard to be updated )

I actually tried that… and thats when I realized that Script Editor clears the selection before running the script. I think it might work fine outside of script editor.

How about using your script in Automator as a Service via ‘Run JavaScript’? Would that not avoid the copy to clipboard stuff and a shortcut could be set in System Preferences/Keyboard/Shortcuts/Services.

[code]function run(input, parameters) {

var selectedText = input[0]
var TaskPaper = Application(‘TaskPaper’)

// Send it to TaskPaper Inbox
TaskPaper.documents[0].evaluate({
script: TPContext.toString(),
withOptions: {text: selectedText }
});

function TPContext(editor, options) {
var outline = editor.outline;
var inbox = outline.evaluateItemPath("//Inbox:")[0];
var items = ItemSerializer.deserializeItems(options.text, outline, ItemSerializer.TEXTMimeType);

if (!inbox) {
	inbox = outline.createItem("Inbox:");
	outline.root.insertChildrenBefore(inbox, outline.root.firstChild);
}

inbox.insertChildrenBefore(items, inbox.firstChild);

}
return input;
}[/code]

I followed the instructions for the javascript example rudi posted. I added one little thing that I think could be helpful to others…

withOptions: {text: ("- " + selectedText) }

This adds the - checkbox to make it a task.

Thanks for this, it’s really helpful @jessegrosjean and @rudi

1 Like

Thanks so much, guys!

1 Like

I’ve been working on adapting this for a redo of the PopClip extension for TP3, but not having much luck parsing the input. Anyone see anything glaring that’s wrong in the input portion of the script?

function run(input, parameters) {
ObjC.import('stdlib')
var selectedText = $.getenv('POPCLIP_TEXT')
var TaskPaper = Application('TaskPaper')
// Send it to TaskPaper Inbox
TaskPaper.documents[0].evaluate({
	script: TPContext.toString(),
	withOptions: {text: ("- " + selectedText) }
});
function TPContext(editor, options) {
    var outline = editor.outline;
    var inbox = outline.evaluateItemPath('//Inbox:')[0];
    var items = ItemSerializer.deserializeItems(options.text, outline, ItemSerializer.TEXTMimeType);

    if (!inbox) {
        inbox = outline.createItem('Inbox:');
        outline.root.insertChildrenBefore(inbox, outline.root.firstChild);
    }
    
    inbox.insertChildrenBefore(items, inbox.firstChild);
    
    return true;
}
}

Thanks,
Brad

1 Like