UNPKG

chrono-node

Version:

A natural language date parser in Javascript

342 lines • 11.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TIME_UNITS_PATTERN = exports.TIME_UNIT_CONNECTOR_PATTERN = exports.YEAR_PATTERN = exports.ORDINAL_NUMBER_PATTERN = exports.NUMBER_PATTERN = exports.DUAL_TIME_UNIT_DICTIONARY = exports.TIME_UNIT_DICTIONARY = exports.ORDINAL_WORD_DICTIONARY = exports.INTEGER_WORD_DICTIONARY = exports.MONTH_DICTIONARY = exports.FULL_MONTH_NAME_DICTIONARY = exports.WEEKDAY_DICTIONARY = exports.REGEX_PARTS = void 0; exports.toWesternDigits = toWesternDigits; exports.parseNumberPattern = parseNumberPattern; exports.parseOrdinalNumberPattern = parseOrdinalNumberPattern; exports.parseYear = parseYear; exports.parseDuration = parseDuration; const pattern_1 = require("../../utils/pattern"); const years_1 = require("../../calculation/years"); exports.REGEX_PARTS = { leftBoundary: "([^\\p{L}\\p{N}_]|^)", rightBoundary: "(?=[^\\p{L}\\p{N}_]|$)", flags: "iu", }; function toWesternDigits(text) { return text.replace(/[٠-٩]/g, (d) => (d.charCodeAt(0) - 1632).toString()); } exports.WEEKDAY_DICTIONARY = { "الأحد": 0, "الاحد": 0, "أحد": 0, "احد": 0, "الإثنين": 1, "الاثنين": 1, "إثنين": 1, "اثنين": 1, "الثلاثاء": 2, "ثلاثاء": 2, "الأربعاء": 3, "الاربعاء": 3, "أربعاء": 3, "اربعاء": 3, "الخميس": 4, "خميس": 4, "الجمعة": 5, "جمعة": 5, "السبت": 6, "سبت": 6, }; exports.FULL_MONTH_NAME_DICTIONARY = { "يناير": 1, "فبراير": 2, "مارس": 3, "أبريل": 4, "ابريل": 4, "مايو": 5, "يونيو": 6, "يوليو": 7, "أغسطس": 8, "اغسطس": 8, "سبتمبر": 9, "أكتوبر": 10, "اكتوبر": 10, "نوفمبر": 11, "ديسمبر": 12, "كانون الثاني": 1, "شباط": 2, "آذار": 3, "اذار": 3, "نيسان": 4, "أيار": 5, "ايار": 5, "حزيران": 6, "تموز": 7, "آب": 8, "اب": 8, "أيلول": 9, "ايلول": 9, "تشرين الأول": 10, "تشرين الاول": 10, "تشرين الثاني": 11, "كانون الأول": 12, "كانون الاول": 12, }; exports.MONTH_DICTIONARY = Object.assign({}, exports.FULL_MONTH_NAME_DICTIONARY); exports.INTEGER_WORD_DICTIONARY = { "واحد": 1, "واحدة": 1, "اثنان": 2, "اثنين": 2, "اثنتان": 2, "اثنتين": 2, "ثلاثة": 3, "ثلاث": 3, "أربعة": 4, "اربعة": 4, "أربع": 4, "اربع": 4, "خمسة": 5, "خمس": 5, "ستة": 6, "ست": 6, "سبعة": 7, "سبع": 7, "ثمانية": 8, "ثماني": 8, "ثمان": 8, "تسعة": 9, "تسع": 9, "عشرة": 10, "عشر": 10, "أحد عشر": 11, "احد عشر": 11, "إحدى عشرة": 11, "احدى عشرة": 11, "اثنا عشر": 12, "اثني عشر": 12, "اثنتا عشرة": 12, "اثنتي عشرة": 12, "نصف": 0.5, "نص": 0.5, "ربع": 0.25, }; exports.ORDINAL_WORD_DICTIONARY = { "الأول": 1, "الاول": 1, "الأولى": 1, "الاولى": 1, "أول": 1, "اول": 1, "حادي": 1, "الحادي": 1, "الثاني": 2, "الثانية": 2, "ثاني": 2, "الثالث": 3, "الثالثة": 3, "ثالث": 3, "الرابع": 4, "الرابعة": 4, "رابع": 4, "الخامس": 5, "الخامسة": 5, "خامس": 5, "السادس": 6, "السادسة": 6, "سادس": 6, "السابع": 7, "السابعة": 7, "سابع": 7, "الثامن": 8, "الثامنة": 8, "ثامن": 8, "التاسع": 9, "التاسعة": 9, "تاسع": 9, "العاشر": 10, "العاشرة": 10, "عاشر": 10, "الحادي عشر": 11, "الحادية عشرة": 11, "الثاني عشر": 12, "الثانية عشرة": 12, "الثالث عشر": 13, "الثالثة عشرة": 13, "الرابع عشر": 14, "الرابعة عشرة": 14, "الخامس عشر": 15, "الخامسة عشرة": 15, "السادس عشر": 16, "السادسة عشرة": 16, "السابع عشر": 17, "السابعة عشرة": 17, "الثامن عشر": 18, "الثامنة عشرة": 18, "التاسع عشر": 19, "التاسعة عشرة": 19, "العشرون": 20, "العشرين": 20, "الحادي والعشرون": 21, "الحادية والعشرون": 21, "الواحد والعشرون": 21, "الثاني والعشرون": 22, "الثانية والعشرون": 22, "الثالث والعشرون": 23, "الثالثة والعشرون": 23, "الرابع والعشرون": 24, "الرابعة والعشرون": 24, "الخامس والعشرون": 25, "الخامسة والعشرون": 25, "السادس والعشرون": 26, "السادسة والعشرون": 26, "السابع والعشرون": 27, "السابعة والعشرون": 27, "الثامن والعشرون": 28, "الثامنة والعشرون": 28, "التاسع والعشرون": 29, "التاسعة والعشرون": 29, "الثلاثون": 30, "الثلاثين": 30, "الحادي والثلاثون": 31, "الحادية والثلاثون": 31, "الواحد والثلاثون": 31, }; exports.TIME_UNIT_DICTIONARY = { "ثانية": "second", "ثانيةً": "second", "ثواني": "second", "ثوان": "second", "ثوانٍ": "second", "دقيقة": "minute", "دقيقةً": "minute", "دقائق": "minute", "ساعة": "hour", "ساعةً": "hour", "ساعات": "hour", "يوم": "day", "يوماً": "day", "يوما": "day", "أيام": "day", "ايام": "day", "أسبوع": "week", "اسبوع": "week", "أسبوعاً": "week", "أسبوعا": "week", "اسبوعاً": "week", "اسبوعا": "week", "أسابيع": "week", "اسابيع": "week", "شهر": "month", "شهراً": "month", "شهرا": "month", "أشهر": "month", "اشهر": "month", "شهور": "month", "سنة": "year", "سنةً": "year", "سنوات": "year", "سنين": "year", "عام": "year", "عاماً": "year", "عاما": "year", "أعوام": "year", "اعوام": "year", }; exports.DUAL_TIME_UNIT_DICTIONARY = { "ثانيتان": "second", "ثانيتين": "second", "دقيقتان": "minute", "دقيقتين": "minute", "ساعتان": "hour", "ساعتين": "hour", "يومان": "day", "يومين": "day", "أسبوعان": "week", "اسبوعان": "week", "أسبوعين": "week", "اسبوعين": "week", "شهران": "month", "شهرين": "month", "سنتان": "year", "سنتين": "year", "عامان": "year", "عامين": "year", }; exports.NUMBER_PATTERN = `(?:${(0, pattern_1.matchAnyPattern)(exports.INTEGER_WORD_DICTIONARY)}|[0-9٠-٩]+|[0-9٠-٩]+[\\.,][0-9٠-٩]+|\\s{0,3})`; function parseNumberPattern(match) { const clean = match.trim(); if (exports.INTEGER_WORD_DICTIONARY[clean] !== undefined) { return exports.INTEGER_WORD_DICTIONARY[clean]; } if (clean === "") { return 1; } const western = toWesternDigits(clean).replace(",", "."); return parseFloat(western); } exports.ORDINAL_NUMBER_PATTERN = `(?:${(0, pattern_1.matchAnyPattern)(exports.ORDINAL_WORD_DICTIONARY)}|[0-9٠-٩]{1,2})`; function parseOrdinalNumberPattern(match) { const clean = match.trim(); if (exports.ORDINAL_WORD_DICTIONARY[clean] !== undefined) { return exports.ORDINAL_WORD_DICTIONARY[clean]; } const western = toWesternDigits(clean); return parseInt(western, 10); } const yearSuffix = "(?:\\s*(?:ميلادية|ميلادي|م))?"; const bcSuffix = "(?:\\s*(?:قبل الميلاد|ق\\.م))"; exports.YEAR_PATTERN = `(?:[1-9١-٩][0-9٠-٩]{0,3}${yearSuffix}${bcSuffix}|[1-2١-٢][0-9٠-٩]{3}${yearSuffix}|[5-9٥-٩][0-9٠-٩]${yearSuffix})`; function parseYear(match) { let clean = match.trim(); const isBC = /(قبل الميلاد|ق\.م)/i.test(clean); clean = clean.replace(/(قبل الميلاد|ق\.م|ميلادية|ميلادي|م)/gi, "").trim(); const western = toWesternDigits(clean); const rawYearNumber = parseInt(western, 10); if (isBC) { return -rawYearNumber; } return (0, years_1.findMostLikelyADYear)(rawYearNumber); } const DUAL_UNIT_PATTERN = `(${(0, pattern_1.matchAnyPattern)(exports.DUAL_TIME_UNIT_DICTIONARY)})`; const NUMBER_WITH_UNIT_PATTERN = `(?:(${exports.NUMBER_PATTERN})\\s{0,3})?(${(0, pattern_1.matchAnyPattern)(exports.TIME_UNIT_DICTIONARY)})`; const HALF_UNIT_PATTERN = `(?:و\\s*)?(نصف|نص|ربع)`; const SINGLE_TIME_UNIT_PATTERN = `(?:${DUAL_UNIT_PATTERN}|${NUMBER_WITH_UNIT_PATTERN}|${HALF_UNIT_PATTERN})`; const SINGLE_TIME_UNIT_REGEX = new RegExp(SINGLE_TIME_UNIT_PATTERN, exports.REGEX_PARTS.flags); exports.TIME_UNIT_CONNECTOR_PATTERN = `\\s{0,5},?(?:\\s*و)?\\s{0,5}`; exports.TIME_UNITS_PATTERN = (0, pattern_1.repeatedTimeunitPattern)(`(?:(?:خلال|في غضون|في خلال|حوالي|تقريباً|تقريبا)\\s{0,3})?`, SINGLE_TIME_UNIT_PATTERN, exports.TIME_UNIT_CONNECTOR_PATTERN); function parseDuration(timeunitText) { const fragments = {}; let remainingText = timeunitText; let match = SINGLE_TIME_UNIT_REGEX.exec(remainingText); let lastUnit; while (match) { lastUnit = collectDateTimeFragment(fragments, match, lastUnit); remainingText = remainingText.substring(match.index + match[0].length).trim(); if (!remainingText) break; match = SINGLE_TIME_UNIT_REGEX.exec(remainingText); } return fragments; } function collectDateTimeFragment(fragments, match, lastUnit) { if (match[1]) { const dualWord = match[1].trim(); const unit = exports.DUAL_TIME_UNIT_DICTIONARY[dualWord]; if (unit) { fragments[unit] = (fragments[unit] || 0) + 2; return unit; } } else if (match[3]) { const numStr = match[2] ? match[2].trim() : ""; const num = parseNumberPattern(numStr); const unitWord = match[3].trim(); const unit = exports.TIME_UNIT_DICTIONARY[unitWord]; if (unit) { fragments[unit] = (fragments[unit] || 0) + num; return unit; } } else if (match[4]) { const fracWord = match[4].trim(); const frac = fracWord === "ربع" ? 0.25 : 0.5; if (lastUnit) { fragments[lastUnit] = (fragments[lastUnit] || 0) + frac; return lastUnit; } } return lastUnit; } //# sourceMappingURL=constants.js.map