Skip to content

Instantly share code, notes, and snippets.

@philgruneich
Last active September 28, 2018 06:28
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philgruneich/cd501266d54c6cf65cb4 to your computer and use it in GitHub Desktop.
Save philgruneich/cd501266d54c6cf65cb4 to your computer and use it in GitHub Desktop.
Natural language parsing for Drafts 4
// Script steps run short Javascripts
// For documentation and examples, visit:
// http://help.agiletortoise.com
var findWeekday = new RegExp( "\\s(Sun|Sunday|Mon|Monday|Tue|Tuesday|Wed|Wednesday|Thu|Thursday|Fri|Friday|Sat|Saturday|tomorrow|today)", "gim" ),
findMonth = new RegExp( "\\s(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)\\s(\\d{1,2})(st|nd|rd|th)?", "gim" ),
findDate = new RegExp( "\\s(\\d{1,2})/(\\d{1,2})/?(\\d{2,4})?", "gim" ),
findNoon = new RegExp( "\\s(noon|evening|afternoon|midnight|morning)", "gim" ),
findTime = new RegExp( "(in\\s)?(\\d{1,2})(\\s|:)?(\\d{2})?\\s?(am|pm)?", "gim" ),
findInTime = new RegExp( "(in\\s)(\\d+)\\s(minute|hour|day|week|month|year)s?", "gim" ),
grabTask = new RegExp( "^(in|at|tomorrow|today|Sun|Sunday|Mon|Monday|Tue|Tuesday|Wed|Wednesday|Thu|Thursday|Fri|Friday|Sat|Saturday|Jan|January|Feb|February|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December|noon|morning|afternoon|evening|on|\\d.*)$", "im" ) ;
// Script variables
var weekdays = {"sun": 0, "sunday": 0, "mon": 1, "monday": 1, "tue": 2, "tuesday": 2, "wed": 3, "wednesday": 3, "thu": 4, "thursday": 4, "fri": 5, "friday": 5, "sat": 6, "saturday": 6},
months = {"jan": 0, "january": 0, "feb": 1, "february": 1, "mar": 2, "march": 2, "apr": 3, "april": 3, "may": 4, "jun": 5, "june": 5, "jul": 6, "july": 6, "aug": 7, "august": 7, "sep": 8, "september": 8, "oct": 9, "october": 9, "nov": 10, "november": 10, "dec": 11, "december": 11},
times = {"default": "12", "noon": "12", "morning": "9", "afternoon": "16", "evening": "20", "defaultmin": "00"},
units = {"minute": 60000, "hour": 3600000, "day": 86400000, "week": 604800000, "month": 2592000000, "year": 2592000000 * 12},
dateArray,
timeArray,
relArray,
taskArray,
taskLength,
i,
relTime,
relUnit,
task,
weekDifference,
weekLower,
eventDay,
eventMonth,
eventYear,
eventDate,
eventTime,
eventMinute,
eventHour,
eventPM,
currentString,
outputString,
thisDraft,
notes,
today = new Date(),
todayDay = today.getDate(),
todayWeek = today.getDay(),
todayMonth = today.getMonth(),
displayMonth = todayMonth;
todayYear = today.getFullYear(),
todayEpoch = Date.parse(today);
// Manipulating the draft
thisDraft = draft.content.split("\n");
currentString = thisDraft[0];
if (thisDraft.length > 1) {
notes = thisDraft.slice(1).join("\n");
} else {
notes = "";
}
// Looking for the date
if (currentString.match(findWeekday)) {
dateArray = findWeekday.exec(currentString);
weekLower = dateArray[1].toLowerCase();
if (weekLower === "today") {
weekDifference = 0;
} else if (weekLower === "tomorrow") {
weekDifference = 86400000;
} else {
week = weekdays[weekLower];
if (todayWeek < week) {
weekDifference = (week - todayWeek) * 86400000;
} else {
weekDifference = ((week - todayWeek) + 7) * 86400000;
}
}
eventDate = new Date(todayEpoch + weekDifference);
eventDay = eventDate.getDate();
eventMonth = eventDate.getMonth();
displayMonth++;
eventYear = eventDate.getFullYear() || todayYear;
} else if (currentString.match(findMonth)) {
dateArray = findMonth.exec(currentString);
eventMonth = months[dateArray[1].toLowerCase()];
displayMonth++
eventDay = dateArray[13];
eventYear = todayYear;
} else if (currentString.match(findDate)) {
dateArray = findDate.exec(currentString);
displayMonth = dateArray[1];
eventMonth = displayMonth - 1;
eventDay = dateArray[2];
eventYear = dateArray[5] || todayYear;
} else {
eventMonth = todayMonth;
displayMonth++;
eventDay = todayDay;
eventYear = todayYear;
}
// Removes the date from the string
if (typeof dateArray != 'undefined') {
outputString = currentString.replace(dateArray[0], "//");
} else {
outputString = currentString;
}
// Looking for the time
if (outputString.match(findNoon)) {
timeArray = findNoon.exec(outputString);
eventHour = times[timeArray[1].toLowerCase()];
eventMinute = times["defaultmin"];
} else if (outputString.match(findTime)) {
timeArray = findTime.exec(outputString);
if (timeArray[1]) {
relArray = findInTime.exec(outputString);
relTime = parseInt(relArray[2]);
relUnit = units[relArray[3]];
eventTime = new Date(todayEpoch + (relTime * relUnit));
eventDay = eventTime.getDate();
eventMonth = eventTime.getMonth();
displayMonth = eventMonth + 1;
eventYear = eventTime.getFullYear();
eventHour = eventTime.getHours();
eventMinute = eventTime.getMinutes();
} else {
eventHour = timeArray[2] || times["default"];
eventMinute = timeArray[4] || times["defaultmin"];
eventPM = timeArray[5];
if (typeof(eventPM) === "string") {
if (eventPM.toLowerCase() === "pm" && eventHour < 12) {
eventHour = parseInt(eventHour) + 12;
} else if (eventPM.toLowerCase() === "am" && eventHour == 12) {
eventHour = "00";
}
}
}
}
// Converts year if the date you inserted is before today.
if (todayMonth > eventMonth) {
eventYear++;
} else if (todayMonth === eventMonth) {
if (todayDay > eventDay) {
eventYear++;
}
}
// Grabs the task
taskArray = currentString.split(' ');
taskLength = taskArray.length;
for (i = 0; i < taskLength; i++) {
if (taskArray[i].match(grabTask)) {
break;
}
}
task = taskArray.slice(0,i).join(' ');
// Adds the zero in front of values, when needed.
function zero(number) {
return ("0" + number).slice(-2);
}
// Creates the tags
draft.defineTag("task", task);
draft.defineTag("notes", notes);
draft.defineTag("dueDate", eventYear + "-" + zero(displayMonth) + "-" + zero(eventDay));
draft.defineTag("dueTime", zero(eventHour) + ":" + zero(eventMinute));
draft.defineTag("due", eventYear + "-" + zero(displayMonth) + "-" + zero(eventDay) + " " + zero(eventHour) + ":" + zero(eventMinute));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment