Hello Hello,
My name is George and I’m just getting into applescript(translatation I know very little). For productivity I use Omnifocus 2 and TaskPaper and I found an that trigger’s a script over at github https://github.com/RobTrew/tree-tools/tree/7e96d5748388dd870606ebba1e636654e2fb47a3/OmniFocus%20scripts/TaskPaper%20scripts which basically imports TaskPaper projects and tasks into Omnifocus just like that Project is a Project in Omnifocus and the Project Tasks are the Project Task in Omnifocus but the scrip is creating another top level item in the task like.
Below is how it looks in Taskpaper so Test is the Project name and the items preceded by the dash are the task
When I run the script I get these this pop ups alerting of what’s going to up
So far so good but when I go to Omnifocus to see the result of the import it looks like so:
Notice how the “one” is a sub project of Test and then task are all under “one” So basically the script is indenting the 1st task and I’m trying to figure how to amend the script so it doesn’t do this and it treats all the task as task. Any help or guidance would extremely appreciated. I would also consider some monetary remuneration ($20) for a fix as well - payment via paypal.
Thanks
George
property pTitle : "Text from file or clipboard to OF"
property pVer : "0.51"
property pBanner : pTitle & " Ver. " & pVer
property pClipImport : "Import this text into OF"
property plstExtensions : {"txt", "taskpaper"}
property plstLines : {}
property plstLevelParents : {}
-- FUNCTION Imports Taskpaper formatted text as OmniFocus projects and (indented) actions
-- USAGE:
-- EITHER 1. Copy text into the clipboard and run this script
-- OR 2. Select one or more .txt or .taskpaper files in Finder, Copy [Cmd C], and run this script
-- OR 3. Drag one or more .txt or .taskpaper files onto the icon of this script
-- NOTE: I use it in a KeyBoard Maestro Action which precedes it with a Copy action.
-- This allows me to select some text in an editor, (or some files in a Finder window),
-- and send things straight into OF with one keystroke.
-- CHANGE LOG
-- ver .51 Corrected handling of multiple files dropped on the droplet
-- ver .52 Corrects handling of selected text
on run
-- Read the clipboard contents
try
set strLines to ((the clipboard) as text)
on error
tell application id "com.apple.systemevents"
activate
display dialog "No text in the clipboard" buttons {"OK"} with title pBanner
end tell
return
end try
-- and the Finder selection
tell application id "com.apple.finder"
set lstSeln to selection as list
if length of lstSeln > 1 then
set strFinderSeln to ""
set blnFirst to true
repeat with i from 1 to length of (lstSeln)
if blnFirst then
set blnFirst to false
else
set strFinderSeln to strFinderSeln & return
end if
set strFinderSeln to strFinderSeln & name of item i of lstSeln
end repeat
else
set strFinderSeln to ""
end if
end tell
-- IF the text in the clipboard is the return delimited list of names of files selected in Finder
-- Then get the lines from all of the selected files that have the right extension
if strLines = strFinderSeln then
-- IMPORT CONTENTS OF ANY TEXT FILES
set strLines to ""
tell application id "com.apple.finder"
repeat with i from 1 to length of lstSeln
set strFileName to (item i of lstSeln) as string
set blnOK to my CheckExtension(strFileName, plstExtensions)
set refFile to (a reference to (file strFileName))
if blnOK then set strLines to strLines & my ReadTextFile(refFile)
end repeat
end tell
ImportLines(strLines, strFinderSeln)
else
-- OFFER TO IMPORT THE TEXT
tell application id "com.apple.systemevents"
activate
set varResponse to display dialog strLines buttons {"Esc", pClipImport} default button pClipImport cancel button "Esc" with title pBanner
if varResponse is false then return
end tell
ImportLines(strLines, "the Clipboard:")
end if
set plstLines to {}
set plstLevelParents to {}
end run
on open lstFiles
set strLines to ""
set blnOK to true
tell application id "com.apple.finder"
repeat with i from 1 to length of lstFiles
set strFileName to (item i of lstFiles) as string
set blnOK to my CheckExtension(strFileName, plstExtensions)
if blnOK then
set refFile to (a reference to (file strFileName))
set strLines to strLines & my ReadTextFile(refFile)
else
exit repeat
end if
end repeat
end tell
if blnOK then
ImportLines(strLines, lstFiles as text)
else
tell application id "com.apple.systemevents"
activate
display dialog "Expects one of following file extensions: " & return & return & my ExtensionList() buttons {"OK"} with title pBanner
end tell
end if
set plstLines to {}
set plstLevelParents to {}
end open
on ExtensionList()
set text item delimiters to " ."
set strList to "." & plstExtensions as text
set text item delimiters to space
strList
end ExtensionList
on CheckExtension(strFileName, lstExtensions)
set text item delimiters to "."
set lstParts to text items of strFileName
set lngParts to length of lstParts
if lngParts < 2 then
return false
else
ignoring case
set strSuffix to (item lngParts of lstParts)
return (lstExtensions contains strSuffix)
end ignoring
end if
end CheckExtension
on ImportLines(strLines, strSource)
tell application "OmniFocus"
set oDoc to default document
tell oDoc
if number of document window is 0 then
make new document window with properties {bounds:{0, 0, 1000, 500}}
end if
set fldrImport to make new folder with properties {name:"Taskpaper Import " & (current date)}
end tell
end tell
set recStats to TP_OF(strLines, oDoc, fldrImport)
set strMsg to (("Imported from:" & return & return & strSource & return & return & " Inbox tasks: " & (Inbox of recStats) as string) & return ¬
& " Projects: " & (Projects of recStats) as string) & return ¬
& " Project tasks: " & (Tasks of recStats) as string
tell application id "com.apple.systemevents"
activate
display dialog strMsg buttons {"OK"} with title pBanner
end tell
end ImportLines
on GetImportFolder(oDoc, fldrImport)
try
set m to fldrImport
on error
tell oDoc
set fldrImport to make new folder with properties {name:"Taskpaper Import " & (current date)}
end tell
end try
return fldrImport
end GetImportFolder
on ReadTextFile(theFile)
open for access theFile
try
set fileContents to (read theFile)
on error
set fileContents to ""
end try
close access theFile
return fileContents
end ReadTextFile
on TP_OF(strLines, oDoc, fldrImport)
set lngInbox to 0
set lngProjects to 0
set lngTasks to 0
set plstLines to paragraphs of strLines
tell application "OmniFocus"
tell oDoc
set will autosave to false
end tell
-- Read the file line by line
-- Establish current destinations for:
---- NOTES (promoted to tasks in
---- TASKS
-- (Before a PROJECT has been encountered, we assume that
-- the default destination is the inbox)
set oTaskParent to oDoc
set oNoteParent to missing value
set plstLevelParents to {}
ignoring case
repeat with strLine in plstLines
-- trim off leading and trailing space characters (not tabs)
set strLine to my Trim(strLine)
-- Count any leading TABS and extract remaining line
set {lngLevel, strLine} to my ParseLevel(strLine)
-- skip empty lines
set lngChars to length of strLine
if lngChars > 0 then
-- distinguish between tasks, notes, and project headers
if first character of strLine ≠"-" then
if last character of strLine ≠":" then
-- NOTE
if oNoteParent ≠missing value then
-- append this text to current note
set note of oNoteParent to note of oNoteParent & strLine & return
else -- "Note" at start of doc - interpret as inbox task
tell oDoc to parse tasks into with transport text strLine without as single task
set lngInbox to lngInbox + 1
end if
else -- HEADER: NEW PROJECT
if lngChars > 1 then
set strProjectName to text 1 thru -2 of strLine
-- Distinguish between normal projects and
-- instances of "Inbox:"
if strProjectName ≠"Inbox" then
-- PROJECT:
tell fldrImport
set oProject to make new project with properties {name:strProjectName}
set lngProjects to lngProjects + 1
set oNoteParent to oProject
set oTaskParent to oProject
-- Specify this as the parent of any Level 1 tasks which follow
set plstLevelParents to {oProject}
-- Record how many tabs precede the project header
end tell
else -- INBOX:
set oTaskParent to oDoc
-- Notes can not be attached to the Inbox
-- We will treat any note lines as Inbox Tasks
set oNoteParent to missing value
end if
end if
end if
else -- First character is "-"
if lngChars > 1 then
if second character of strLine ≠" " then
-- NOTE
set note of oNoteParent to note of oNoteParent & strLine & return
else -- TASK
-- drop the leading "- "
set strLine to text 3 thru -1 of strLine
set lngParents to length of plstLevelParents
-- Parse any tags into a record of properties
set recProps to my ParseTask(oDoc, strLine)
set cParent to class of oTaskParent
if cParent ≠document then
-- and identify its parent (correcting any over-indentation)
if lngLevel > lngParents then
set lngLevel to lngParents
end if
set oTaskParent to item lngLevel of plstLevelParents
tell oTaskParent
set oTask to make new task with properties recProps
set lngTasks to lngTasks + 1
end tell
else -- cParent is document
tell oTaskParent
set oTask to make new inbox task with properties recProps
set lngInbox to lngInbox + 1
end tell
end if
-- Record this task as the parent of any note which follows
set oNoteParent to oTask
-- Record this task as the parent of any tasks at the next level of indentation
set lngNextLevel to lngLevel + 1
if lngNextLevel > lngParents then
set end of plstLevelParents to oTask
else
set item lngNextLevel of plstLevelParents to oTask
end if
end if
end if
end if
end if
end repeat
end ignoring
tell oDoc
set will autosave to true
end tell
end tell
return {Inbox:lngInbox, Projects:lngProjects, Tasks:lngTasks}
end TP_OF
on Trim(someText)
local someText
repeat until someText does not start with " "
if (length of someText) > 1 then
set someText to text 2 thru -1 of someText
else
set someText to ""
end if
end repeat
repeat until someText does not end with " "
if length of someText > 1 then
set someText to text 1 thru -2 of someText
else
set someText to ""
end if
end repeat
return someText
end Trim
on RTrim(someText)
local someText
repeat until someText does not end with return
if length of someText > 1 then
set someText to text 1 thru -2 of someText
else
set someText to ""
end if
end repeat
return someText
end RTrim
on ParseLevel(strLine)
set lngLevel to 1 --Assume project headings and inboxes are zero
repeat while strLine starts with tab
set lngLevel to lngLevel + 1
if length of strLine > 1 then
set strLine to text 2 thru -1 of strLine
else
set strLine to ""
exit repeat
end if
end repeat
return {lngLevel, strLine}
end ParseLevel
on ParseTask(oDoc, strTask)
-- Return recTask as property list for an Omnifocus Task
set recTask to {}
if length of strTask > 0 then
set strOldDelims to text item delimiters
set text item delimiters to " @"
set lstParts to text items of strTask
set recTask to {name:(item 1 of lstParts) as string} & recTask
set lngParts to count of lstParts
set blnContextSet to false
if lngParts > 1 then
set text item delimiters to "("
ignoring case
using terms from application "OmniFocus"
repeat with strPart in rest of lstParts
set lstTagVal to text items of strPart
set strTag to item 1 of lstTagVal
if (count of lstTagVal) > 1 then
set strVal to text 1 thru -2 of (item 2 of lstTagVal)
else
set strVal to ""
end if
if length of strTag > 0 then
if strTag ≠"done" then
if strTag ≠"start" then
if strTag ≠"due" then
if strTag ≠"mins" then
if (strTag ≠"flag") then
if blnContextSet then
--Skip any additional context
else
set oCat to my GetContext(oDoc, strTag)
if oCat ≠missing value then
set recTask to {context:oCat} & recTask
end if
end if
else -- flagged
-- set flag of recTask to true
set recTask to {flagged:true} & recTask
end if
else -- mins
try
set lngMins to strVal as integer
-- set mins of recTask to strVal
set recTask to {estimated minutes:lngMins} & recTask
end try
end if
else -- due
-- set due of recTask to strVal
set dteDue to my ParseDate(strVal)
if dteDue ≠0 then
set recTask to {due date:dteDue} & recTask
end if
end if
else -- start()
set dteStart to my ParseDate(strVal)
if dteStart ≠0 then
set recTask to {defer date:dteStart} & recTask
end if
end if
else -- done
-- set zapped of recTask to true
set recTask to {completed:true} & recTask
end if
end if
end repeat
end using terms from
end ignoring
else -- very short
set recTask to {name:strTask}
end if
set text item delimiters to strOldDelims
end if
return recTask
end ParseTask
on GetContext(oDoc, strTag)
using terms from application "OmniFocus"
set strSum to strTag as string
tell oDoc
set oContexts to complete strTag as context maximum matches 1
if length of oContexts > 0 then
set oContext to context id (id of item 1 of oContexts)
else --
set oContext to make new context with properties {name:strTag}
end if
end tell
end using terms from
return oContext
end GetContext
on ParseDate(strDate)
try
set dte to date strDate
set blnDate to true
on error
set strOldDelims to text item delimiters
set text item delimiters to " "
--try
set lstDateTime to text items of strDate
set blnDate to true
try
set strDate to item 1 of lstDateTime
set text item delimiters to "-"
set lstDateParts to text items of strDate
set lngYear to item 1 of lstDateParts as integer
set lngMonth to item 2 of lstDateParts as integer
set lngDay to item 3 of lstDateParts as integer
on error
set blnDate to false
end try
set blnTime to true
try
set strTime to item 2 of lstDateTime
set text item delimiters to ":"
set lstTimeParts to text items of strTime
set lngHours to item 1 of lstTimeParts as integer
set lngMins to item 2 of lstTimeParts as integer
on error
set blnTime to false
end try
if blnDate then
set dte to current date
set hours of dte to 0
set minutes of dte to 0
set seconds of dte to 0
set year of dte to lngYear
set day of dte to 1 -- (All months have 1st, some lack 29-31)
set month of dte to lngMonth
set day of dte to lngDay -- (and now the day we want)
if blnTime then
if lngHours > 0 or lngMinutes > 0 then
set hours of dte to lngHours
set minutes of dte to lngMins
end if
end if
end if
set text item delimiters to strOldDelims
end try
if blnDate then
return dte
else
return 0
end if
end ParseDate