I see that iOS version is getting some interesting Taskpaper > OmniFocus import and export capabilities. I wonder if there are existing scripts to do the same on the Mac. I am aware of Rob Trew’s script for Taskpaper import, but it no longer seems to work with current versions. It does not import projects and the hierarchy is messed up:
Taskpaper Project:
- task one
- task two
- task three
OmniFocus output
Taskpaper Project
- task one
- task two
- task three
```
In other words, the script makes tasks children when they shouldn't be and does not create projects, only tasks.
Has anyone updated this script? Or are there plans to re-create the iOS task paper functionality on the Mac?
The Taskpaper support is currently for iOS only. I can’t speculate about the future, but I do know it isn’t on the Mac side as of our latest release, version 2.5.1. I agree that it would be useful. :)
It would be so useful. I’ve always wanted to have the ability to define a template with various dates and offsets to them (long story). Anyway, I got so happy when I saw that the iOS version would get TaskPaper import support that I wrote some code to create TaskPaper projects based on a template. Since I’m mostly using OF on OS X I would really like the ability to import this on my laptop.
You can paste taskpaper into OF now, but the thing I really need is to be able to replace «tag» in the taskpaper - so I can reuse my iOS templates on OSX. Ideally, I’d be able to set up something like ‘launcher’ to make it a ‘click to instigate’ type of situation.
In an ideal word, OF would natively understand the format used in iOS, be able to read the .taskpaper file and would do the same as the editorial/python iOS solution, and I’d be able to assign a button to my OF menu to initiate it all.
If there is a demo of keyboard maestro that I can try this with, there will be a sale.
Its a bit of a shame their OF doesn’t understand any template format with fields to complete ‘natively’ in either OSX or iOS - but this should be a decent patch.
After all the work of finding the template and replacing the values, all it does is copy the processed template to the clipboard. You need to select the destination folder and paste.
I’ll work on creating a version that prompts you for the destination folder and pastes it in for you.
Re: the difference between taskpaperTemplateFilePath vs Raw:
The file path variable says where the TaskPaper template is located (it’s just a file name).
The raw variable is the actual content of the template in that file path.
Leave those fields empty; the macro will take care of filling those in. (I added those variables at the top in order to clear the values out, because I was having problems with them being sticky across invocations.) The macro will prompt you for the right file each time its run.
This is what I just settled on (I changed my extension to *.txt so that Workflow on iOS would read the same templates)
I have a Python script that does the substitution:
#encoding: utf-8
from os import listdir, chdir, getcwd
from os.path import isfile, join
import re
import codecs
# Needed for clipboard
import subprocess
# Change this as needed
template_dir = "/path/to/Omnifocus Templates"
template_ext = ".txt"
def write_to_clipboard(output):
""" Sends a string to the clipboard"""
process = subprocess.Popen(
'pbcopy', env={'LANG': 'en_US.UTF-8'}, stdin=subprocess.PIPE)
process.communicate(output.encode('utf-8'))
def read_from_clipboard():
""" Read a string from the clipboard """
return subprocess.check_output(
'pbpaste', env={'LANG': 'en_US.UTF-8'}).decode('utf-8')
ext_len=-len(template_ext)
def inputNumber(message,max):
while True:
valid = False
while ( not valid ):
try:
userInput = int(input(message))
except ValueError:
print ("Type a number")
continue
else:
valid = (0 <= userInput <= max )
if valid :
return userInput
else:
print("Choose from above options")
old_dir = getcwd()
try:
chdir(template_dir)
dirs = listdir(getcwd())
print("\n"+"Here are the templates that you have available:"+"\n")
n=0
filelist = []
for file in dirs:
# Only show taskpaper files
if template_ext in file:
# Remove the file extension
file = file[:ext_len]
print(str(n).rjust(4) + ". " + file)
filelist.append(file)
n += 1
print("\n" + str(n).rjust(4) + ". Exit")
choice = inputNumber("\n"+"Which template? : ",n)
if (choice<n):
filechoice = filelist[choice] + template_ext
print("\n" + "Using template " + filechoice)
f = codecs.open(filechoice,encoding='utf-8')
templ=[]
known_placeholders = set()
placeholders = []
fields = []
for line in f:
templ.append(line)
# Find placeholders
for placeholder_match in re.finditer(u"«(.+?)»", line):
placeholder = placeholder_match.group(1)
if placeholder not in known_placeholders:
known_placeholders.add(placeholder)
placeholders.append(placeholder)
fields.append({'type': 'text', 'title': placeholder, 'key': placeholder})
if len(placeholders) == 0:
print("No template placeholders were found")
else:
print(placeholders)
replacement=[]
for item in placeholders:
question = "What should I use for «"+item+"» ? "
value=input("\n" + question.rjust(50))
replacement.append(value)
print("\n")
counter = 0
for item in placeholders:
replace=replacement[counter]
item = "«" + item + "»"
templ = [t.replace(item,replace) for t in templ]
counter+=1
final_out=""
for item in templ:
final_out+=item
print("Copy the following and paste it into Omnifocus")
print("--------NOT THIS LINE-------------------------------------"+"\n")
print(final_out)
print("\n"+"--------NOT THIS LINE-------------------------------------")
print("You should find that the output is already in the clipboard")
write_to_clipboard(final_out)
finally:
chdir(old_dir)
I initiate this from the terminal prompt with a script called ‘omni’
#!/bin/ksh
cd ~/path/to/'Omnifocus Templates'
python3 omni.py
Keyboard Maestro has two entries:
‘Activate Terminal’ and ‘Insert Text by Typing’ (text inserted - omni and carriagereturn’).
It may be a little clunky, but it does the immediate job - I’ll implement your update as well and compare.
I’ve said it before, but It’d all be a lot nicer if Omnifocus understood the template format and all we had to do was point it at the directory!