Skip to content

Instantly share code, notes, and snippets.

@alienlebarge
Last active April 9, 2023 02:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alienlebarge/4398463 to your computer and use it in GitHub Desktop.
Save alienlebarge/4398463 to your computer and use it in GitHub Desktop.
Parse start and due date for TaskPaper

Information

Original script by Andyferra. You will find information about it here.
Thanks to him !

I've juste modified the script to remove @start() tags if the date has passed.

property dueTag : "due"
property startTag : "start"
property repeatTag : "repeat"
property todayTag : "today"
property pastDueTag : "overdue"
property upcomingTag : "upcoming"
property doneTag : "done"
property inProgressTag : "inprogress"
property errorTag : "error"
property removeTags : {upcomingTag, todayTag, pastDueTag, inProgressTag}
property upcomingDays : 2
property numberSet : {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
global vToday
set vToday to current date
set time of vToday to 0
--Start by converting any due tags with a text description of the date
--to an actual date
my convertDate(dueTag)
my convertDate(startTag)
tell front document of application "TaskPaper"
--Next handle repeat tags. A due tag is not required on these.
repeat with tpRptTag in (every tag of (every entry) whose name is repeatTag)
tell entry of tpRptTag
set tagList to (every tag whose name is dueTag)
set needDue to false
if tagList is {} then
--no due tag, create one, and remember to fill in a date below.
--use today as the start date
set tpDueTag to make new tag with properties {name:dueTag}
copy vToday to vDate
set needDue to true
else
--have a due tag, use that as the start date
set tpDueTag to first item of tagList
set dateString to (get value of tpDueTag)
tell me to set vDate to getDateFromText(dateString)
end if
if not needDue then
set tagList to (every tag whose name is doneTag)
end if
--if there was no due tag, or the entry is marked done,
--the calculate and set the date of the due tag.
if needDue or tagList is not {} then
--Delete all extra tags
repeat with delTag in removeTags
delete (every tag whose name is delTag)
end repeat
--Create a date from the repeat value
set rInfo to (get value of tpRptTag)
if (vDate is not null) then
tell me to set vDate to getRepeatDate(rInfo, vDate)
end if
if vDate is not null then
--fill in the date, make sure it is not marked done
tell me to set vDateText to getTextFromDate(vDate)
set value of tpDueTag to vDateText
delete (every tag whose name is doneTag)
else
--flag unknown repeat value with an error tag
make new tag with properties {name:errorTag, value:"unknown repeat type"}
end if
end if
end tell
end repeat
--Add/update the extra tags based on the due date of items that are not done
repeat with tpDueTag in (every tag of (every entry) whose name is dueTag)
tell entry of tpDueTag
set tagList to (every tag whose name is doneTag)
set errTagList to (every tag whose name is errorTag)
if (tagList is {}) and (errTagList is {}) then
--Not marked done
set inFuture to false
set dateString to (get value of tpDueTag)
tell me to set vDate to getDateFromText(dateString)
set startTagList to (every tag whose name is startTag)
if (startTagList is not {}) then
set tpStartTag to first item of startTagList
set startDateString to (get value of tpStartTag)
tell me to set vStartDate to getDateFromText(startDateString)
set inFuture to ((vToday) - vStartDate < 0)
end if
if vDate is not null then
if inFuture then
delete (every tag whose name is upcomingTag)
delete (every tag whose name is todayTag)
else
set diffDays to (vDate - vToday) / days
if (diffDays < 0) then
set tagList to (every tag whose name is pastDueTag)
if (tagList is {}) then
make new tag with properties {name:pastDueTag}
end if
delete (every tag whose name is upcomingTag)
delete (every tag whose name is todayTag)
else if (diffDays = 0) then
set tagList to (every tag whose name is todayTag)
if (tagList is {}) then
make new tag with properties {name:todayTag}
end if
delete (every tag whose name is upcomingTag)
else if (diffDays ≤ upcomingDays) then
set tagList to (every tag whose name is upcomingTag)
if (tagList is {}) then
make new tag with properties {name:upcomingTag}
delete (every tag whose name is todayTag)
end if
else
delete (every tag whose name is upcomingTag)
delete (every tag whose name is todayTag)
end if
end if
else
--invalid date format
make new tag with properties {name:"error", value:"invalid date format"}
end if
else
--Marked done, delete all extra tags
repeat with delTag in removeTags
delete (every tag whose name is delTag)
end repeat
end if
end tell
end repeat
-- remove start tags if starting has passed
tell me to set vTodayString to getTextFromDate(vToday)
repeat with currentTag in (every tag of (every entry) whose name is startTag)
tell entry of currentTag
set dateString to (get value of currentTag)
if (dateString <= vTodayString) then
delete (every tag whose name is startTag)
end if
end tell
end repeat
end tell
on convertDate(tagLabel)
tell front document of application "TaskPaper"
repeat with myTag in (every tag of (every entry) whose name is tagLabel)
set vDueVal to (value of myTag)
if vDueVal is missing value then
set vDueVal to "today"
end if
if character 1 of vDueVal is not in numberSet then
set vDateString to null
tell me to set vDate to getDateForDueValue(vDueVal)
if vDate is not null then
tell me to set vDateString to getTextFromDate(vDate)
else
tell entry of myTag
make new tag with properties {name:errorTag, value:"Unknown value for " & tagLabel & " tag"}
end tell
end if
if vDateString is not null then
set value of myTag to vDateString
end if
end if
end repeat
end tell
end convertDate
on getDateFromText(dateText)
set vDate to null
set AppleScript's text item delimiters to {"-"}
if (count of text item of dateText) is 3 then
set vYear to text item 1 of dateText
set vMonth to text item 2 of dateText
set vDay to text item 3 of dateText
if (vYear > 1000) and (vMonth > 0 and vMonth < 13) and (vDay > 0 and vDay < 32) then
set vDate to current date
set year of vDate to (vYear as integer)
set month of vDate to vMonth as integer
set day of vDate to vDay as integer
set time of vDate to 0
end if
end if
return vDate
end getDateFromText
on getTextFromDate(vDate)
set dText to ((year of vDate) as text) & "-"
set dayText to (month of vDate as number) as text
if length of dayText is 1 then
set dayText to "0" & dayText
end if
set dText to dText & dayText & "-"
set dayText to (day of vDate as number) as text
if length of dayText is 1 then
set dayText to "0" & dayText
end if
return dText & dayText
end getTextFromDate
on getDateForDueValue(dueValue)
set vDate to null
if character 1 of dueValue is in numberSet then
set vDate to getDateFromText(dueValue)
else
--Special cases for due date not handled in getRepeatDate
if "today" is dueValue then
copy vToday to vDate
else if "tomorrow" starts with dueValue then
copy vToday to vDate
set vDate to vDate + 1 * days
else
set vDate to getRepeatDate(dueValue, vToday)
end if
end if
return vDate
end getDateForDueValue
on getRepeatDate(repeatDesc, fromDate)
copy fromDate to vDate
set AppleScript's text item delimiters to {":"}
set repeatType to text item 1 of repeatDesc
if (count of text items in repeatDesc) > 1 then
set repeatCount to text item 2 of repeatDesc
else
set repeatCount to 1
end if
if repeatType is "day" or repeatType is "week" then
if repeatType is "day" then
set vInterval to days
else
set vInterval to weeks
end if
set vDate to vDate + repeatCount * vInterval
repeat while vDate comes before vToday
set vDate to vDate + repeatCount * vInterval
end repeat
else if repeatType is "month" then
set month of vDate to (month of vDate) + repeatCount
repeat while vDate comes before vToday
set month of vDate to (month of vDate) + repeatCount
end repeat
else if repeatType is "year" then
set year of vDate to (year of vDate) + repeatCount
log "vDate is " & vDate
repeat while vDate comes before vToday
set year of vDate to (year of vDate) + repeatCount
end repeat
else
set rDay to 0
if "sunday" starts with repeatType then
set rDay to Sunday
else if "monday" starts with repeatType then
set rDay to Monday
else if "tuesday" starts with repeatType then
set rDay to Tuesday
else if "wednesday" starts with repeatType then
set rDay to Wednesday
else if "thursday" starts with repeatType then
set rDay to Thursday
else if "friday" starts with repeatType then
set rDay to Friday
else if "saturday" starts with repeatType then
set rDay to Saturday
end if
if rDay > 0 then
--Handle case where vDate is not currect day of week.
set vOffset to rDay - (weekday of vDate)
if vOffset is not 0 then
set vDate to vDate + vOffset * days
if vOffset > 0 then
--If we move forward, count that as 1
set repeatCount to repeatCount - 1
end if
end if
--Find next date after vDate
set vOffset to 7 * repeatCount
set vDate to vDate + vOffset * days
repeat while vDate comes before vToday
set vDate to vDate + vOffset * days
end repeat
else
--Unknown type, return nothing
set vDate to null
end if
end if
return vDate
end getRepeatDate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment