elliptical-datetime
Version:
Elliptical phrases to handle natural language dates and times
619 lines (539 loc) • 19.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.InternalDate = exports.Date = exports.Day = exports.InternalDay = undefined;
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _elliptical = require('elliptical');
var _moment = require('moment');
var _moment2 = _interopRequireDefault(_moment);
var _duration2 = require('./duration');
var _ellipticalNumber = require('elliptical-number');
var _time = require('./time');
var _month = require('./month');
var _year = require('./year');
var _weekday = require('./weekday');
var _helpers = require('./helpers');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _marked = [mapDate].map(_regenerator2.default.mark); /** @jsx createElement */
var InternalDay = exports.InternalDay = {
defaultProps: {
recurse: true,
label: 'day'
},
describe: function describe(_ref) {
var props = _ref.props;
if (props.nullify) return;
return (0, _elliptical.createElement)(
'choice',
null,
props.recurse ? (0, _elliptical.createElement)(
'placeholder',
{
label: props.label,
arguments: props.phraseArguments || (props.phraseArguments ? [props.phraseArgument] : [props.label]) },
(0, _elliptical.createElement)(RecursiveDay, { label: props.label })
) : null,
(0, _elliptical.createElement)(
'sequence',
null,
props.prepositions ? (0, _elliptical.createElement)('literal', { text: 'on ', decorate: true }) : null,
(0, _elliptical.createElement)(
'placeholder',
{
label: props.label,
arguments: props.phraseArguments || (props.phraseArguments ? [props.phraseArgument] : [props.label]),
merge: true },
(0, _elliptical.createElement)(
'choice',
null,
(0, _elliptical.createElement)(DayAlone, null),
(0, _elliptical.createElement)(AmbiguousAbsoluteDay, null),
(0, _elliptical.createElement)(AmbiguousAbsoluteNamedMonth, null)
)
)
)
);
}
};
var Day = exports.Day = {
id: 'elliptical-datetime:Day',
defaultProps: {
recurse: true,
label: 'day'
},
describe: function describe(_ref2) {
var props = _ref2.props;
return (0, _elliptical.createElement)(InternalDay, props);
}
};
function mapDate(option) {
var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result;
return _regenerator2.default.wrap(function mapDate$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context.prev = 3;
_iterator = (0, _helpers.possibleDates)(option.result)[Symbol.iterator]();
case 5:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context.next = 12;
break;
}
result = _step.value;
_context.next = 9;
return _lodash2.default.assign({}, option, { result: result });
case 9:
_iteratorNormalCompletion = true;
_context.next = 5;
break;
case 12:
_context.next = 18;
break;
case 14:
_context.prev = 14;
_context.t0 = _context['catch'](3);
_didIteratorError = true;
_iteratorError = _context.t0;
case 18:
_context.prev = 18;
_context.prev = 19;
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
case 21:
_context.prev = 21;
if (!_didIteratorError) {
_context.next = 24;
break;
}
throw _iteratorError;
case 24:
return _context.finish(21);
case 25:
return _context.finish(18);
case 26:
case 'end':
return _context.stop();
}
}
}, _marked[0], this, [[3, 14, 18, 26], [19,, 21, 25]]);
}
var Date = exports.Date = {
id: 'elliptical-datetime:Date',
defaultProps: {
recurse: true,
prepositions: false,
nullify: false,
past: true,
future: true,
label: 'date'
},
filterResult: function filterResult(result, _ref3) {
var props = _ref3.props;
if (!props.past && (0, _moment2.default)(result).isBefore((0, _moment2.default)())) {
return false;
}
if (!props.future && (0, _moment2.default)(result).isAfter((0, _moment2.default)())) {
return false;
}
// if (result._ambiguousMonth) {
// return false
// }
return true;
},
describe: function describe(_ref4) {
var props = _ref4.props;
return (0, _elliptical.createElement)(
'map',
{ outbound: mapDate, skipIncomplete: true, limit: 1 },
(0, _elliptical.createElement)(InternalDate, props)
);
}
};
var InternalDate = exports.InternalDate = {
defaultProps: {
recurse: true,
prepositions: false,
nullify: false,
past: true,
future: true,
label: 'date'
},
describe: function describe(_ref5) {
var props = _ref5.props;
if (props.nullify) return;
return (0, _elliptical.createElement)(
'choice',
null,
(0, _elliptical.createElement)(
'placeholder',
{
label: props.label,
arguments: props.phraseArguments || (props.phraseArguments ? [props.phraseArgument] : [props.label]) },
(0, _elliptical.createElement)(
'choice',
null,
(0, _elliptical.createElement)(RelativeNamed, null),
(0, _elliptical.createElement)(RelativeNumbered, { prepositions: props.prepositions }),
(0, _elliptical.createElement)(DayWithYear, { prepositions: props.prepositions }),
(0, _elliptical.createElement)(RelativeAdjacent, null),
props.recurse ? (0, _elliptical.createElement)(RecursiveDate, { label: props.label }) : null
)
),
(0, _elliptical.createElement)(
'sequence',
null,
props.prepositions ? (0, _elliptical.createElement)('literal', { text: 'on ', decorate: true }) : null,
(0, _elliptical.createElement)(
'placeholder',
{
label: props.label,
arguments: props.phraseArguments || (props.phraseArguments ? [props.phraseArgument] : [props.label]),
merge: true },
(0, _elliptical.createElement)(
'choice',
null,
(0, _elliptical.createElement)(RelativeWeekday, null),
(0, _elliptical.createElement)(AbsoluteDay, null)
)
)
)
);
}
};
var DayWithYear = {
mapResult: function mapResult(result) {
var day = result.day;
var year = result.year;
if (year) {
var date = (0, _helpers.absoluteDate)(_lodash2.default.assign({ year: year.year }, day));
return { date: date, _ambiguousCentury: year._ambiguousCentury };
} else {
return {
date: (0, _helpers.absoluteDate)(day),
_ambiguousMonth: day._ambiguousMonth,
_ambiguousYear: true
};
}
},
describe: function describe(_ref6) {
var props = _ref6.props;
return (0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(Day, { prepositions: props.prepositions, id: 'day', recurse: false, ellipsis: true }),
(0, _elliptical.createElement)(
'sequence',
{ merge: true },
(0, _elliptical.createElement)('list', { items: [', ', ' in ', ' '], limit: 1 }),
(0, _elliptical.createElement)(_year.Year, { id: 'year' })
)
);
}
};
var ExtraDateDuration = {
mapResult: function mapResult(result) {
return (0, _defineProperty3.default)({}, result.type, result.multiplier || 1);
},
describe: function describe() {
return (0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(
'placeholder',
{ label: 'number' },
(0, _elliptical.createElement)('literal', { text: 'the ' })
),
(0, _elliptical.createElement)(
'placeholder',
{ label: 'time period', merge: true },
(0, _elliptical.createElement)('list', { items: [{ text: 'day', value: { type: 'days' } }, { text: 'fortnight', value: { type: 'days', multiplier: 14 } }, { text: 'week', value: { type: 'days', multiplier: 7 } }, { text: 'month', value: { type: 'months' } }, { text: 'year', value: { type: 'years' } }] })
)
);
}
};
var RecursiveDay = {
mapResult: function mapResult(result) {
var duration = result.direction === -1 ? (0, _helpers.negateDuration)(result.duration) : result.duration;
return (0, _helpers.relativeDay)(duration, result.day);
},
describe: function describe(_ref8) {
var props = _ref8.props;
return (0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(
'placeholder',
{ label: 'offset', merge: true },
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(
'choice',
{ id: 'duration' },
(0, _elliptical.createElement)(ExtraDateDuration, null),
(0, _elliptical.createElement)(_duration2.DateDuration, null)
),
(0, _elliptical.createElement)('list', { merge: true, id: 'direction', items: [{ text: ' before', value: -1 }, { text: ' after', value: 1 }, { text: ' from', value: 1 }], limit: 2 })
)
),
(0, _elliptical.createElement)('literal', { text: ' ' }),
(0, _elliptical.createElement)(
'placeholder',
{ label: 'day', id: 'day' },
(0, _elliptical.createElement)(Day, { recurse: false, prepositions: false, label: props.label })
)
);
}
};
var RecursiveDate = {
mapResult: function mapResult(result) {
var duration = result.direction === -1 ? (0, _helpers.negateDuration)(result.duration) : result.duration;
return _lodash2.default.assign({}, result.date, {
date: (0, _helpers.relativeDate)(duration, result.date.date)
});
},
describe: function describe(_ref9) {
var props = _ref9.props;
return (0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(
'placeholder',
{ label: 'offset', merge: true },
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(
'choice',
{ id: 'duration' },
(0, _elliptical.createElement)(ExtraDateDuration, null),
(0, _elliptical.createElement)(_duration2.DateDuration, null)
),
(0, _elliptical.createElement)('list', { merge: true, id: 'direction', items: [{ text: ' before', value: -1 }, { text: ' after', value: 1 }, { text: ' from', value: 1 }], limit: 2 })
)
),
(0, _elliptical.createElement)('literal', { text: ' ' }),
(0, _elliptical.createElement)(InternalDate, { id: 'date', label: props.label, recurse: false, prepositions: false })
);
}
};
var RelativeNamed = {
mapResult: function mapResult(result) {
return { date: (0, _helpers.relativeDate)(result) };
},
describe: function describe() {
return (0, _elliptical.createElement)('list', { items: [{ text: 'today', value: { days: 0 } }, { text: 'tomorrow', value: { days: 1 } }, { text: 'yesterday', value: { days: -1 } }, { text: 'now', value: { days: 0 } }, { text: 'right now', value: { days: 0 } }], limit: 3 });
}
};
var RelativeNumbered = {
mapResult: function mapResult(result) {
var duration = result.direction === -1 ? (0, _helpers.negateDuration)(result.duration) : result.duration;
return { date: (0, _helpers.relativeDate)(duration) };
},
describe: function describe(_ref10) {
var props = _ref10.props;
return (0, _elliptical.createElement)(
'choice',
null,
props.prepositions ? (0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)('literal', { text: 'in ', id: 'direction', value: 1 }),
(0, _elliptical.createElement)(_duration2.DateDuration, { id: 'duration' })
) : null,
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(_duration2.DateDuration, { id: 'duration' }),
(0, _elliptical.createElement)('literal', { text: ' ago', id: 'direction', value: -1 })
)
);
}
};
var RelativeAdjacent = {
mapResult: function mapResult(result) {
var duration = (0, _defineProperty3.default)({}, result.type, result.num * (result.multiplier || 1));
return { date: (0, _helpers.relativeDate)(duration) };
},
describe: function describe() {
return (0, _elliptical.createElement)(
'placeholder',
{ label: 'time period' },
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)('list', { id: 'num', items: [{ text: 'next ', value: 1 }, { text: 'last ', value: -1 }] }),
(0, _elliptical.createElement)(
'placeholder',
{ label: 'time period', merge: true },
(0, _elliptical.createElement)('list', { items: [{ text: 'week', value: { type: 'days', multiplier: 7 } }, { text: 'month', value: { type: 'months' } }, { text: 'year', value: { type: 'years' } }] })
)
)
);
}
};
function dateFromRelative(distance, weekday) {
var day = distance * 7 + weekday;
return (0, _moment2.default)().day(day).toDate();
}
var RelativeWeekday = {
mapResult: function mapResult(result) {
var date = dateFromRelative(result.distance || 0, result.weekday);
if (result.distance == null) {
return { date: date, _ambiguousWeek: true };
} else {
return { date: date };
}
},
describe: function describe() {
return (0, _elliptical.createElement)(
'choice',
null,
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)('list', { optional: true, id: 'distance', items: [{ text: 'last ', value: -1 }, { text: 'this ', value: 0 }, { text: 'next ', value: 1 }, { text: 'this upcoming ', value: 1 }], limit: 1 }),
(0, _elliptical.createElement)(_weekday.Weekday, { id: 'weekday' })
),
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)('literal', { text: 'the ' }),
(0, _elliptical.createElement)(
'placeholder',
{ label: 'relative weekday', merge: true },
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(_weekday.Weekday, { id: 'weekday' }),
(0, _elliptical.createElement)('list', { id: 'distance', items: [{ text: ' after next', value: 2 }, { text: ' after this', value: 1 }, { text: ' before this', value: -1 }, { text: ' before last', value: -2 }] })
)
)
)
);
}
};
function leapYear(year) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
var MonthNumber = {
mapResult: function mapResult(result) {
return parseInt(result, 10) - 1;
},
describe: function describe() {
return (0, _elliptical.createElement)(_ellipticalNumber.DigitString, { maxLength: 2, max: 12, min: 1, label: 'mm' });
}
};
var DayNumber = {
mapResult: function mapResult(result) {
return parseInt(result, 10);
},
describe: function describe() {
return (0, _elliptical.createElement)(_ellipticalNumber.DigitString, { maxLength: 2, max: 31, min: 1, label: 'dd' });
}
};
var AbsoluteDay = {
mapResult: function mapResult(result) {
var date = (0, _helpers.absoluteDate)(_lodash2.default.assign({}, result, { year: result.year.year }));
return { date: date, _ambiguousCentury: result.year._ambiguousCentury };
},
filterResult: function filterResult(result) {
var years = result._ambiguousCentury ? [0, 100, -100] : [0];
return _lodash2.default.some(years, function (year) {
var date = _lodash2.default.assign({}, result, { year: result.date.getFullYear() + year });
return (0, _helpers.validateDay)(date);
});
},
describe: function describe() {
return (0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(AmbiguousAbsoluteDay, { merge: true }),
(0, _elliptical.createElement)('list', { items: ['/'], limit: 1 }),
(0, _elliptical.createElement)(_year.Year, { id: 'year' })
);
}
};
var DayAlone = {
mapResult: function mapResult(result) {
return {
month: (0, _moment2.default)().month(),
day: result,
_ambiguousMonth: true
};
},
describe: function describe() {
return (0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)('literal', { text: 'the ', optional: true, preferred: true, limited: true }),
(0, _elliptical.createElement)(
'choice',
{ limit: 1, merge: true },
(0, _elliptical.createElement)(_ellipticalNumber.Integer, { allowWordForm: true, max: 31, min: 1, limit: 1, allowLeadingZero: false }),
(0, _elliptical.createElement)(_ellipticalNumber.Ordinal, { allowWordForm: true, max: 31, limit: 1 })
)
);
}
};
var AmbiguousAbsoluteDay = {
describe: function describe() {
return (0, _elliptical.createElement)(
'filter',
{ 'function': _helpers.validateDay },
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(MonthNumber, { id: 'month' }),
(0, _elliptical.createElement)('list', { items: ['/'], limit: 1 }),
(0, _elliptical.createElement)(DayNumber, { id: 'day' })
)
);
}
};
var AmbiguousAbsoluteNamedMonth = {
filterResult: function filterResult(result) {
return (0, _helpers.validateDay)(result);
},
describe: function describe() {
return (0, _elliptical.createElement)(
'choice',
null,
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)(_month.Month, { id: 'month' }),
(0, _elliptical.createElement)('list', { items: [' ', ' the '], limit: 1 }),
(0, _elliptical.createElement)(
'choice',
{ id: 'day', limit: 1 },
(0, _elliptical.createElement)(_ellipticalNumber.Integer, { allowWordForm: true, max: 31, min: 1, limit: 1 }),
(0, _elliptical.createElement)(_ellipticalNumber.Ordinal, { allowWordForm: true, max: 31, limit: 1 })
)
),
(0, _elliptical.createElement)(
'sequence',
null,
(0, _elliptical.createElement)('literal', { text: 'the ' }),
(0, _elliptical.createElement)(
'choice',
{ id: 'day', limit: 1 },
(0, _elliptical.createElement)(_ellipticalNumber.Integer, { allowWordForm: true, max: 31, min: 1, limit: 1 }),
(0, _elliptical.createElement)(_ellipticalNumber.Ordinal, { allowWordForm: true, max: 31, limit: 1 })
),
(0, _elliptical.createElement)('list', { items: [' of ', ' '], limit: 1 }),
(0, _elliptical.createElement)(_month.Month, { id: 'month' })
)
);
}
};