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 |