TaskPaper: Importing/Exporting

TaskPaper is a plain text to-do list creation and editing application used to define projects and their tasks. It’s simple text-format is supported by many personal management applications such as OmniFocus, and is often used as a transfer format between various applications.

TaskPaper support in OmniFocus is detailed in this TaskPaper Reference.

The following example scripts and plug-ins use the built-in URL support in OmniFocus to import and export TaskPaper data to and from your OmniFocus database.

Import Chosen TaskPaper File

In the following example script, instances of the FilePicker and FileType classes are used to read the contents of a chosen TaskPaper document and include the read data in an OmniFocus URL that will upon execution, will place the translated TaskPaper data in the OmniFocus Inbox.

omnifocus://localhost/omnijs-run?script=%28async%20%28%29%20%3D%3E%20%7B%0A%09try%20%7B%0A%09%09picker%20%3D%20new%20FilePicker%28%29%0A%09%09picker%2Efolders%20%3D%20false%0A%09%09picker%2Emultiple%20%3D%20false%0A%09%09aFileType%20%3D%20new%20FileType%28%22com%2Etaskpaper%2Etext%22%29%0A%09%09picker%2Etypes%20%3D%20%5BaFileType%5D%0A%09%09urlsArray%20%3D%20await%20picker%2Eshow%28%29%0A%09%09fileURL%20%3D%20urlsArray%5B0%5D%0A%09%09fileURL%2Efetch%28function%28data%29%7B%0A%09%09%09TaskPaperText%20%3D%20data%2EtoString%28%29%0A%09%09%09TaskPaperText%20%3D%20encodeURIComponent%28TaskPaperText%29%0A%09%09%09urlStr%20%3D%20%60omnifocus%3A%2F%2F%2Fpaste%3Ftarget%3Dinbox%26content%3D%24%7BTaskPaperText%7D%60%0A%09%09%09URL%2EfromString%28urlStr%29%2Eopen%28%29%0A%09%09%7D%29%0A%09%7D%0A%09catch%28err%29%7B%0A%09%09if%28%21err%2EcausedByUserCancelling%29%7B%0A%09%09%09console%2Eerror%28err%2Ename%2C%20err%2Emessage%29%0A%09%09%09new%20Alert%28err%2Ename%2C%20err%2Emessage%29%2Eshow%28%29%0A%09%09%7D%0A%09%7D%0A%7D%29%28%29%3B
Import TaskPaper File
 

(async () => { try { picker = new FilePicker() picker.folders = false picker.multiple = false aFileType = new FileType("com.taskpaper.text") picker.types = [aFileType] urlsArray = await picker.show() fileURL = urlsArray[0] fileURL.fetch(function(data){ TaskPaperText = data.toString() TaskPaperText = encodeURIComponent(TaskPaperText) urlStr = `omnifocus:///paste?target=inbox&content=${TaskPaperText}` URL.fromString(urlStr).open() }) } catch(err){ if(!err.causedByUserCancelling){ console.error(err.name, err.message) new Alert(err.name, err.message).show() } } })();

Import TaskPaper Document Plug-In

The previous script is placed within an Omni Automation plug-in template to create an easy-to-use tool for selecting and importing TaskPaper documents.

Import Chosen TaskPaper Document
   

/*{ "type": "action", "targets": ["omnifocus"], "author": "Otto Automator", "identifier": "com.omni-automation.of.import-taskpaper-file", "version": "1.1", "description": "This action will import the contents of the chosen Taskpaper file to the Inbox.", "label": "Import Taskpaper File", "shortLabel": "Import Taskpaper", "paletteLabel": "Toolbar Item Title", "image": "t.square" }*/ (() => { const action = new PlugIn.Action(async function(selection, sender){ try { picker = new FilePicker() picker.folders = false picker.multiple = false aFileType = new FileType("com.taskpaper.text") picker.types = [aFileType] urlsArray = await picker.show() fileURL = urlsArray[0] fileURL.fetch(function(data){ TaskPaperText = data.toString() TaskPaperText = encodeURIComponent(TaskPaperText) urlStr = `omnifocus:///paste?target=inbox&content=${TaskPaperText}` URL.fromString(urlStr).open() }) } catch(err){ if(!err.causedByUserCancelling){ console.error(err.name, err.message) new Alert(err.name, err.message).show() } } }); action.validate = function(selection, sender){ // selection options: tasks, projects, folders, tags, databaseObjects, allObjects return true }; return action; })();

Import Chosen TaskPaper into Selected Folder

Similar to the previous plug-in, this example imports the contents of a chosen TaskPaper document into the selected OmniFocus folder:

Import TaskPaper into Selected Folder
   

/*{ "type": "action", "targets": ["omnifocus"], "author": "Otto Automator", "identifier": "com.omni-automation.of.import-taskpaper-into-selected-folder", "version": "1.1", "description": "This action will import the contents of a chosen Taskpaper document into the selected folder", "label": "Import Taskpaper File into Folder", "shortLabel": "Taskpaper to Folder", "paletteLabel": "Taskpaper to Folder", "image":"plus.rectangle.on.folder" }*/ (() => { const action = new PlugIn.Action(async function(selection, sender){ try { folder = selection.folders[0] folderName = folder.name picker = new FilePicker() picker.folders = false picker.multiple = false aFileType = new FileType("com.taskpaper.text") picker.types = [aFileType] urlsArray = await picker.show() fileURL = urlsArray[0] fileURL.fetch(function(data){ taskpaperText = data.toString() taskpaperText = encodeURIComponent(taskpaperText) folderName = encodeURIComponent(folderName) urlStr = "omnifocus:///paste?target=/folder/" + folderName + "&content=" + taskpaperText console.log(urlStr) URL.fromString(urlStr).open() }) } catch(err){ if(!err.causedByUserCancelling){ console.error(err.name, err.message) new Alert(err.name, err.message).show() } } }); action.validate = function(selection, sender){ // selection options: tasks, projects, folders, tags, databaseObjects, allObjects return (selection.folders.length === 1) }; return action; })();

Importing Taskpaper Templates

TIP: Be sure to check out the plug-in for importing Taskpaper templates from your iCloud OmniFocus folder.

Export to “TaskPaper-compatible” Format

All Omni applications incorporate the ability to export their content using instances of the FileWrapper class that structure the content in specific formats so they can be written to file. For example, both OmniGraffle and OmniPlan support FileWrappers for exporting content to images.

OmniFocus has a plain-text FileWrapper that is similar to compatible with the data structure used by the TaskPaper application. From the OmniFocus FileWrapper documentation:

Plain Text (.txt)
This is a lightweight plain-text representation of your data, able to be opened in the text editor of your choice. OmniFocus’s plain text export is inspired by TaskPaper, the light to-do application from Hog Bay Software. As such the output should be roughly compatible and able to be imported to TaskPaper with a minimum of fuss.
com.omnigroup.omnifocus2.export-filetype.plain-text

The following script examples use the Plain-Text FileWrapper to convert OmniFocus elements to “TaskPaper-compatible” text.

Converting Objects to Plain-Text

The process of converting OmniFocus abjects to plain-text representations involves the creation of a FileWrapper instance of a specific type. The following examples demonstrate how to create such wrappers and how to use them to save the wrapper data to files.

In the following example, a wrapper is created and its contents are logged to the console as text:

omnifocus://localhost/omnijs-run?script=%28async%20%28%29%20%3D%3E%20%7B%0A%09try%20%7B%0A%09%09fileTypeID%20%3D%20%22com%2Eomnigroup%2Eomnifocus2%2Eexport%2Dfiletype%2Eplain%2Dtext%22%0A%09%09baseName%20%3D%20%22Tasky%2DExport%22%0A%09%09wrapper%20%3D%20await%20document%2EmakeFileWrapper%28baseName%2C%20fileTypeID%29%0A%09%09wrapperContents%20%3D%20wrapper%2Econtents%2EtoString%28%29%0A%09%09console%2Elog%28wrapperContents%29%0A%09%09Pasteboard%2Egeneral%2Estring%20%3D%20wrapperContents%0A%09%09new%20Alert%28%22Completion%22%2C%20%22Contents%20are%20on%20the%20clipboard%2E%22%29%2Eshow%28%29%0A%09%7D%0A%09catch%28err%29%7B%0A%09%09new%20Alert%28err%2Ename%2C%20err%2Emessage%29%2Eshow%28%29%0A%09%7D%0A%7D%29%28%29%3B
Export to Clipboard as Plain-Text
 

(async () => { try { fileTypeID = "com.omnigroup.omnifocus2.export-filetype.plain-text" baseName = "Tasky-Export" wrapper = await document.makeFileWrapper(baseName, fileTypeID) wrapperContents = wrapper.contents.toString() console.log(wrapperContents) Pasteboard.general.string = wrapperContents new Alert("Completion", "Contents are on the clipboard.").show() } catch(err){ new Alert(err.name, err.message).show() } })();

And a variation of the previous script that incorporates the use of a FileSaver instance to save the data to file:

omnifocus://localhost/omnijs-run?script=%28async%20%28%29%20%3D%3E%20%7B%0A%09try%20%7B%0A%09%09%2F%2F%20SAVE%20CONTENTS%20%0A%09%09fileTypeID%20%3D%20%22com%2Eomnigroup%2Eomnifocus2%2Eexport%2Dfiletype%2Eplain%2Dtext%22%0A%09%09baseName%20%3D%20%22Tasky%2DExport%22%0A%09%09wrapper%20%3D%20await%20document%2EmakeFileWrapper%28baseName%2C%20fileTypeID%29%0A%09%09wrapper%2EpreferredFilename%20%3D%20%22Tasky%2DExport%2Etaskpaper%22%0A%09%09wrapperContents%20%3D%20wrapper%2Econtents%2EtoString%28%29%0A%09%09console%2Elog%28wrapperContents%29%0A%09%09%2F%2F%20PROMPT%20FOR%20DESTINATION%0A%09%09filesaver%20%3D%20new%20FileSaver%28%29%0A%09%09urlObj%20%3D%20await%20filesaver%2Eshow%28wrapper%29%0A%09%09console%2Elog%28urlObj%2Estring%29%0A%09%09alert%20%3D%20new%20Alert%28%22FILE%20URL%22%2C%20urlObj%2Estring%29%0A%09%09result%20%3D%20await%20alert%2Eshow%28%29%0A%09%09urlObj%2Eopen%28%29%0A%09%7D%0A%09catch%28err%29%7B%0A%09%09new%20Alert%28err%2Ename%2C%20err%2Emessage%29%2Eshow%28%29%0A%09%7D%0A%7D%29%28%29%3B
Save to File and Open
 

(async () => { try { // SAVE CONTENTS fileTypeID = "com.omnigroup.omnifocus2.export-filetype.plain-text" baseName = "Tasky-Export" wrapper = await document.makeFileWrapper(baseName, fileTypeID) wrapper.preferredFilename = "Tasky-Export.taskpaper" wrapperContents = wrapper.contents.toString() console.log(wrapperContents) // PROMPT FOR DESTINATION filesaver = new FileSaver() urlObj = await filesaver.show(wrapper) console.log(urlObj.string) alert = new Alert("FILE URL", urlObj.string) result = await alert.show() urlObj.open() } catch(err){ new Alert(err.name, err.message).show() } })();

Here’s a variation of the export script that saves the export to the local OmniFocus Documents folder and opens the exported Taskpaper file:

omnifocus://localhost/omnijs-run?script=%28async%20%28%29%20%3D%3E%20%7B%0A%09try%20%7B%0A%09%09fileTypeID%20%3D%20%22com%2Eomnigroup%2Eomnifocus2%2Eexport%2Dfiletype%2Eplain%2Dtext%22%0A%09%09baseName%20%3D%20%22Tasky%2DExport%22%0A%09%09wrapper%20%3D%20await%20document%2EmakeFileWrapper%28baseName%2C%20fileTypeID%29%0A%09%09textData%20%3D%20wrapper%2Econtents%0A%09%09console%2Elog%28textData%29%0A%09%09%0A%09%09folderURL%20%3D%20URL%2EdocumentsDirectory%0A%09%09fileName%20%3D%20%22Tasky%2DExport%2Etaskpaper%22%0A%09%09fileURL%20%3D%20folderURL%2EappendingPathComponent%28fileName%29%0A%09%09wrapper%20%3D%20FileWrapper%2EwithContents%28fileName%2C%20textData%29%0A%09%09wrapper%2Ewrite%28fileURL%2C%20%5BFileWrapper%2EWritingOptions%2EAtomic%5D%2C%20null%29%0A%09%09alert%20%3D%20new%20Alert%28%22FILE%20URL%22%2C%20fileURL%2Estring%29%0A%09%09result%20%3D%20await%20alert%2Eshow%28%29%0A%09%09fileURL%2Eopen%28%29%0A%09%7D%0A%09catch%28err%29%7B%0A%09%09new%20Alert%28err%2Ename%2C%20err%2Emessage%29%2Eshow%28%29%0A%09%7D%0A%7D%29%28%29%3B
Save to OmniFocus Documents folder and Open
 

(async () => { try { fileTypeID = "com.omnigroup.omnifocus2.export-filetype.plain-text" baseName = "Tasky-Export" wrapper = await document.makeFileWrapper(baseName, fileTypeID) textData = wrapper.contents console.log(textData) folderURL = URL.documentsDirectory fileName = "Tasky-Export.taskpaper" fileURL = folderURL.appendingPathComponent(fileName) wrapper = FileWrapper.withContents(fileName, textData) wrapper.write(fileURL, [FileWrapper.WritingOptions.Atomic], null) alert = new Alert("FILE URL", fileURL.string) result = await alert.show() fileURL.open() } catch(err){ new Alert(err.name, err.message).show() } })();

Export to TaskPaper File

Here is the previous script placed within an Omni Automation plug-in that exports the OmniFocus window contents as a TaskPaper document.

Export Contents to TaskPaper File
   

/*{ "type": "action", "targets": ["omnifocus"], "author": "Otto Automator", "identifier": "com.omni-automation.of.export-as-taskpaper", "version": "1.1", "description": "This action will export the window contents or selection as a single TaskPaper file, and then attempt to open the created file in TaskPaper.", "label": "Export Contents or Selection as TaskPaper", "shortLabel": "Export to TaskPaper", "paletteLabel": "Export to TaskPaper", "image": "doc.text" }*/ (() => { const action = new PlugIn.Action(async function(selection, sender){ try { fileTypeID = "com.omnigroup.omnifocus2.export-filetype.plain-text" baseName = "Tasky-Export" wrapper = await document.makeFileWrapper(baseName, fileTypeID) wrapper.preferredFilename = "Taskpaper-Export.taskpaper" wrapperContents = wrapper.contents.toString() console.log(wrapperContents) filesaver = new FileSaver() fileURL = await filesaver.show(wrapper) console.log(fileURL.string) alert = new Alert("FILE URL", fileURL.string) alert.addOption("Open File") alert.addOption("Done") buttonIndex = await alert.show() if(buttonIndex === 0){fileURL.open()} } catch(err){ if(!err.causedByUserCancelling){ console.error(err.name, err.message) new Alert(err.name, err.message).show() } } }); action.validate = function(selection, sender){ return true }; return action; })();