asksuite-core
Version:
501 lines (476 loc) • 14.1 kB
JavaScript
/**
* Created by Avell on 15/12/2016.
*/
/* Date Parser */
function Dates(knwl) {
this.languages = {
english: true,
};
this.year = {};
this.year.lookForYear = function (pos) {
/*
Attempts to find year in string through ranking:
1. Proximity to trigger source
2. Punctuation syntax
*/
const potential = [];
let fall = 1.0; // ranking fall
for (let ee = pos; ee > pos - 20; ee--) {
if (dates.db.wordsWithPunc[ee] === undefined) {
break;
}
if (dates.db.wordsWithPunc[ee].search(/[,;:]/g) !== -1) {
// rank lower if comma seperates results
fall += 4;
} else if (dates.db.wordsWithPunc[ee].search(/[.?!]/g) !== -1) {
// rank much lower if in another sentence
fall += 72;
}
const curWord = dates.db.wordsWithPunc[ee].replace(/[.,!?\(\)]/g, ''); // cleanup
if (isNaN(parseInt(curWord)) === false) {
const parsedWord = parseInt(curWord);
if (parsedWord.toString().length === 4) {
potential.push({
offset: (pos - ee) * fall,
year: parseInt(curWord),
});
break;
}
}
}
fall = 1.0; // reset ranking fall
for (let ee = pos; ee < pos + 20; ee++) {
if (dates.db.wordsWithPunc[ee] === undefined) {
break;
}
const curWord = dates.db.wordsWithPunc[ee].replace(/[.,!?\(\)]/g, ''); // cleanup
if (isNaN(parseInt(curWord)) === false) {
const parsedWord = parseInt(curWord);
if (parsedWord.toString().length === 4) {
potential.push({
offset: (ee - pos) * fall,
year: parseInt(curWord),
});
break;
}
}
if (dates.db.wordsWithPunc[ee].search(/[,;:]/g) !== -1) {
// rank lower if comma seperates results
fall += 4;
} else if (dates.db.wordsWithPunc[ee].search(/[.?!]/g) !== -1) {
// rank much lower if in another sentence
fall += 72;
}
}
if (potential.length > 0) {
const sortedByPotential = potential.sort(function (a, b) {
return a.offset - b.offset;
});
return sortedByPotential[0].year;
} else {
return 'unknown';
}
};
this.day = {};
this.day.prefix = ['twenty', 'thirty'];
this.day.suffix = [
'primeir',
'segundo',
'terceiro',
'quarto',
'quinto',
'sexto',
'sétimo',
'ouitavo',
'nineth',
'tenth',
'eleventh',
'twelfth',
'thirteenth',
'fourteenth',
'fifteenth',
'sixteenth',
'seventeenth',
'eighteenth',
'nineteenth',
];
this.months = [
'janeiro',
'fevereiro',
'março',
'abril',
'maio',
'junho',
'julho',
'agosto',
'setembro',
'outubro',
'novembro',
'dezembro',
];
this.monthAbbrs = [
'jan',
'fev',
'mar',
'apr',
'mai',
'jun',
'jul',
'ago',
'set',
'out',
'nov',
'dez',
];
this.holidays = [
['black', 'friday'],
['natal'],
['ano', 'novo'],
['independencia'],
['dia', 'do', 'trabalhador'],
['dia', 'da', 'mentira'],
];
this.holidaysD = [
[28, 11],
[25, 12],
[1, 1],
[4, 7],
[31, 10],
[1, 4],
];
this.dateObj = new Date();
this.constructDateObj = function (year, month, day) {
return {
year,
month,
day,
preview: null,
};
};
this.getDay = function (word) {
if (word === undefined) {
return 'unknown';
}
// word (twenty-first)
const pieces = word.toLowerCase().split('-');
let numberStr = '';
for (let ii = 0; ii < pieces.length; ii++) {
let foundPrefix = false;
if (ii === 0) {
for (let ee = 0; ee < dates.day.prefix.length; ee++) {
if (pieces[ii] === dates.day.prefix[ee]) {
if (dates.day.prefix[ee] === 'twenty') {
numberStr += '2';
} else if (dates.day.prefix[ee] === 'thirty') {
numberStr += '3';
}
foundPrefix = true;
break;
}
}
if (foundPrefix === false) {
for (let ee = 0; ee < dates.day.suffix.length; ee++) {
if (pieces[ii] === dates.day.suffix[ee]) {
numberStr += ee + 1;
break;
}
}
break;
}
} else {
for (let ee = 0; ee < dates.day.suffix.length; ee++) {
if (pieces[ii] === dates.day.suffix[ee]) {
numberStr += ee + 1;
break;
}
}
}
}
if (numberStr.length > 0) {
return parseInt(numberStr);
}
// number (21st)
if (
parseInt(word.replace(/[^0-9\.]+/g, '')) > 0 &&
parseInt(word.replace(/[^0-9\.]+/g, '')) < 32
) {
const parsed = parseInt(word);
if (isNaN(parsed) === true) {
return 'unknown';
}
return parsed;
}
};
this.day.lookForDay = function (pos) {
/*
Attempts to find day in string through ranking:
1. Proximity to trigger source
2. Punctuation syntax
*/
const potential = [];
let fall = 1.0; // ranking fall
for (let ee = pos; ee > pos - 10; ee--) {
if (dates.db.wordsWithPunc[ee] === undefined) {
break;
}
if (dates.db.wordsWithPunc[ee].search(/[?!.]/g) !== -1) {
// if reached end of previous sentence
break;
}
if (dates.db.wordsWithPunc[ee].search(/[,;:]/g) !== -1) {
// rank lower if comma seperates results
fall += 4;
}
const curWord = dates.db.wordsWithPunc[ee].replace(/[.,!?\(\)]/g, ''); // cleanup
if (curWord.length - curWord.replace(/[^0-9\.]+/g, '').length === 2) {
const testDay = dates.getDay(curWord);
if (testDay !== 'unknown' && testDay !== undefined) {
potential.push({
offset: (pos - ee) * fall,
day: testDay,
});
break;
}
}
}
fall = 1.0; // reset ranking fall
for (let ee = pos; ee < pos + 10; ee++) {
if (dates.db.wordsWithPunc[ee] === undefined) {
break;
}
let shouldBreak = false;
if (dates.db.wordsWithPunc[ee].search(/[?!.]/g) !== -1) {
// if reached end of previous sentence
shouldBreak = true;
}
const curWord = dates.db.wordsWithPunc[ee].replace(/[.,!?\(\)]/g, ''); // cleanup
if (curWord.length - curWord.replace(/[^0-9\.]+/g, '').length === 2) {
const testDay = dates.getDay(curWord);
if (testDay !== 'unknown' && testDay !== undefined) {
potential.push({
offset: (ee - pos) * fall,
day: testDay,
});
break;
}
}
if (shouldBreak) {
break;
}
if (dates.db.wordsWithPunc[ee].search(/[,;:]/g) !== -1) {
// rank lower if comma seperates results
fall += 4;
}
}
if (potential.length > 0) {
const sortedByPotential = potential.sort(function (a, b) {
return a.offset - b.offset;
});
return sortedByPotential[0].day;
} else {
return 'unknown';
// return dates.dateObj.getFullYear();
}
};
this.getMonth = function (word, typeD) {
if (!isNaN(word) && typeD === 'mdy') {
return parseInt(word);
} else {
for (let i = 0; i < dates.months.length; i++) {
if (dates.months[i] === word) {
return i + 1;
}
}
for (let i = 0; i < dates.monthAbbrs.length; i++) {
if (dates.monthAbbrs[i] === word) {
return i + 1;
}
}
}
};
this.db = {};
this.db.words = [];
this.db.wordsWithPunc = [];
this.calls = function () {
const words = knwl.words.get('words');
const wordsWithPunc = knwl.words.get('linkWords');
dates.db.words = words;
dates.db.wordsWithPunc = wordsWithPunc;
const results = [];
// for dates like "july 16th 1999" one
let dateObj = {};
for (let i = 0; i < words.length; i++) {
let year;
const month = dates.getMonth(words[i]);
if (month !== undefined) {
let day = dates.getDay(words[i + 1]);
if (day === undefined) {
day = dates.day.lookForDay(i);
}
let shouldContinue = true;
if (day === undefined || day === 'unknown') {
if (month === undefined || year === undefined) {
shouldContinue = false;
}
shouldContinue = false;
}
if (shouldContinue === true) {
year = dates.year.lookForYear(i);
dateObj = dates.constructDateObj(year, month, day);
dateObj.preview = knwl.tasks.preview(i);
dateObj.found = i;
results.push(dateObj);
}
}
}
// for dates like "7/16/1999" two
dateObj = {};
for (let i = 0; i < words.length; i++) {
let word = words[i].replace('(', ''); // remove parenth--- if they are present
word = word.replace(')', ''); // remove parenth--- if they are present
const testDate = word.split('/');
if (testDate.length === 3) {
let isAllNums = 0;
for (let z = 0; z < testDate.length; z++) {
if (!isNaN(testDate[z]) && testDate[z] !== '') {
isAllNums++;
}
}
if (isAllNums === 3) {
const day = dates.getDay(testDate[0]);
const month = dates.getMonth(testDate[1], 'mdy');
const year = parseInt(testDate[2]);
if (month > 12) {
// month cannot be over 12
break;
}
dateObj = dates.constructDateObj(year, month, day);
dateObj.preview = knwl.tasks.preview(i);
dateObj.found = i;
results.push(dateObj);
}
}
}
// for dates like "15/11" two
dateObj = {};
for (let i = 0; i < words.length; i++) {
let word = words[i].replace('(', ''); // remove parenth--- if they are present
word = word.replace(')', ''); // remove parenth--- if they are present
const testDate = word.split('/');
if (testDate.length === 2) {
let isAllNums = 0;
for (let z = 0; z < testDate.length; z++) {
if (!isNaN(testDate[z]) && testDate[z] !== '') {
isAllNums++;
}
}
if (isAllNums === 2) {
const day = dates.getDay(testDate[0]);
const month = dates.getMonth(testDate[1], 'mdy');
const year = new Date().getFullYear();
if (month > 12) {
// month cannot be over 12
break;
}
dateObj = dates.constructDateObj(year, month, day);
dateObj.preview = knwl.tasks.preview(i);
dateObj.found = i;
results.push(dateObj);
}
}
}
// for dates like "24th of december" three
dateObj = {};
for (let i = 0; i < words.length; i++) {
if (words[i + 1] === 'de') {
if (words[i + 2] !== undefined) {
const day = dates.getDay(words[i]);
const month = dates.getMonth(words[i + 2]);
let year = dates.dateObj.getFullYear();
if (month !== undefined && day !== undefined) {
// make sure month and day defined
year = dates.year.lookForYear(i);
dateObj = dates.constructDateObj(year, month, day);
dateObj.preview = knwl.tasks.preview(i);
dateObj.found = i;
results.push(dateObj);
}
} // finish check if month and day defined
}
}
// for dates like "thanksgiving", "christmas", or "new years"
dateObj = {};
for (let i = 0; i < words.length; i++) {
for (let e = 0; e < dates.holidays.length; e++) {
const curHol = dates.holidays[e];
let pos = i;
if (words[pos] === curHol[0]) {
for (let x = 0; x < curHol.length; x++) {
if (words[pos] === curHol[x]) {
if (x === curHol.length - 1) {
if (dates.dateObj.getMonth() <= dates.holidaysD[e][1] + 1) {
dateObj = dates.constructDateObj(
dates.year.lookForYear(i),
dates.holidaysD[e][1],
dates.holidaysD[e][0],
);
dateObj.preview = knwl.tasks.preview(i);
dateObj.found = i;
} else {
dateObj = dates.constructDateObj(
dates.year.lookForYear(i),
dates.holidaysD[e][1],
dates.holidaysD[e][0],
);
dateObj.preview = knwl.tasks.preview(i);
dateObj.found = i;
}
results.push(dateObj);
}
} else {
break;
}
pos++;
}
}
}
}
// for dates like "2013-12-15" (YMD)
dateObj = {};
for (let i = 0; i < words.length; i++) {
const temp = words[i].split(/[-]+/);
if (temp.length === 3) {
let numSets = 0;
for (let x = 0; x < temp.length; x++) {
if (isNaN(temp[x]) === false) {
numSets++;
}
}
if (numSets === 3) {
if (
temp[0].length === 4 &&
(temp[1].length === 2 || temp[1].length === 1) &&
(temp[2].length === 2 || temp[2].length === 1)
) {
for (let x = 0; x < temp.length; x++) {
temp[x] = parseInt(temp[x]);
}
if (temp[1] > 0 && temp[1] < 13) {
if (temp[2] > 0 && temp[2] < 32) {
if (temp[0] > 0) {
dateObj = dates.constructDateObj(temp[0], temp[1], temp[2]);
dateObj.preview = knwl.tasks.preview(i, words);
dateObj.found = i;
results.push(dateObj);
}
}
}
}
}
}
}
return results;
};
const dates = this;
}
module.exports = Dates;