UNPKG

elliptical-datetime

Version:

Elliptical phrases to handle natural language dates and times

344 lines (299 loc) 11.6 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.InternalTime = exports.Time = exports.TimeOfDay = undefined; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _moment = require('moment'); var _moment2 = _interopRequireDefault(_moment); var _elliptical = require('elliptical'); var _ellipticalNumber = require('elliptical-number'); var _helpers = require('./helpers'); var _duration = require('./duration'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** @jsx createElement */ const TimeOfDay = exports.TimeOfDay = { describe() { return (0, _elliptical.createElement)( 'placeholder', { label: 'time of day' }, (0, _elliptical.createElement)('list', { items: [{ text: 'early morning', value: { default: 6, impliedAMPM: 'am' } }, { text: 'morning', value: { default: 8, impliedAMPM: 'am' } }, { text: 'late morning', value: { default: 10, impliedAMPM: 'am' } }, { text: 'afternoon', value: { default: 12, impliedAMPM: 'pm' } }, { text: 'late afternoon', value: { default: 15, impliedAMPM: 'pm' } }, { text: 'evening', value: { default: 17, impliedAMPM: 'pm' } }, { text: 'night', value: { default: 20, impliedAMPM: 'pm' } }] }) ); } }; function getTimeResult(result) { return { hour: result.hour, minute: result.minute, second: result.second }; } function getTimeOptions(option, props) { return _lodash2.default.assign({}, option, { result: getTimeResult(option.result) }); } const Time = exports.Time = { id: 'elliptical-datetime:Time', defaultProps: { named: true, recurse: true, relative: true, prepositions: false, seconds: false, nullify: false, label: 'time' }, describe({ props }) { if (props.nullify) return null; return (0, _elliptical.createElement)( 'map', { outbound: option => getTimeOptions(option, props), skipIncomplete: true }, (0, _elliptical.createElement)(InternalTime, props) ); } }; const InternalTime = exports.InternalTime = { defaultProps: { named: true, recurse: true, relative: true, prepositions: false, seconds: false, nullify: false, label: 'time' }, describe({ props }) { if (props.nullify) return null; return (0, _elliptical.createElement)( 'choice', null, (0, _elliptical.createElement)( 'sequence', null, props.prepositions ? (0, _elliptical.createElement)( 'choice', { limit: 1 }, (0, _elliptical.createElement)('literal', { text: 'at ', decorate: true }), (0, _elliptical.createElement)('literal', { text: 'from ' }) ) : 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)(AbsoluteNumeric, null), (0, _elliptical.createElement)(AbsoluteRelativeHour, null), (0, _elliptical.createElement)(AbsoluteNamed, null) ) ) ), (0, _elliptical.createElement)( 'placeholder', { label: props.label, arguments: props.phraseArguments || (props.phraseArguments ? [props.phraseArgument] : [props.label]) }, (0, _elliptical.createElement)( 'choice', null, props.named ? (0, _elliptical.createElement)(RelativeNamed, null) : null, props.relative ? (0, _elliptical.createElement)(RelativeTime, null) : null, props.recurse ? (0, _elliptical.createElement)(RecursiveTime, null) : null ) ) ); } }; const RelativeTime = { mapResult(result) { const duration = result.direction === -1 ? (0, _helpers.negateDuration)(result.duration) : result.duration; return (0, _helpers.relativeTime)(duration); }, describe({ props }) { return (0, _elliptical.createElement)( 'choice', null, (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)('literal', { text: 'in ', id: 'direction', value: 1 }), (0, _elliptical.createElement)(_duration.TimeDuration, { id: 'duration', seconds: props.seconds }) ), (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)(_duration.TimeDuration, { id: 'duration', seconds: props.seconds }), (0, _elliptical.createElement)('literal', { text: ' from now', id: 'direction', value: 1 }) ), (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)(_duration.TimeDuration, { id: 'duration', seconds: props.seconds }), (0, _elliptical.createElement)('literal', { text: ' ago', id: 'direction', value: -1 }) ) ); } }; const RelativeNamed = { mapResult(result) { return (0, _helpers.relativeTime)(result); }, describe() { return (0, _elliptical.createElement)('list', { items: [{ text: 'now', value: {} }, { text: 'right now', value: {} }], limit: 1 }); } }; const AbsoluteTimeOfDay = { mapValue(result) { return (0, _helpers.coerceAmbiguousTime)(result.ambiguousTime, result.timeOfDay.range); }, describe() { return (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)( 'choice', { id: 'ambiguousTime' }, (0, _elliptical.createElement)(AmbiguousAbsoluteNumeric, { seconds: props.seconds }), (0, _elliptical.createElement)(AmbiguousAbsoluteRelativeHour, null) ), (0, _elliptical.createElement)('literal', { text: ' in the ' }), (0, _elliptical.createElement)(TimeOfDay, { id: 'timeOfDay' }) ); } }; const AbsoluteNamed = { mapResult(result) { return (0, _helpers.absoluteTime)(result); }, describe() { return (0, _elliptical.createElement)('list', { items: [{ text: 'midnight', value: { hour: 0 } }, { text: 'noon', value: { hour: 12 } }] }); } }; const AbsoluteNumeric = { mapResult(result) { const trueHour = parseInt(result.hour, 10); const trueResult = _lodash2.default.assign({}, result, { hour: trueHour, minute: result.minute, second: result.second || 0 }); if (trueResult.ampm) { const actualTime = (0, _helpers.ambiguousTime)(trueResult, trueResult.ampm); return actualTime ? _lodash2.default.assign({}, actualTime, { _specificAMPM: trueResult.ampm }) : null; } else { if (trueResult.hour > 12) { return (0, _helpers.ambiguousTime)(trueResult); } else if (trueResult.hour === 0) { return (0, _helpers.ambiguousTime)(trueResult); } else { return _lodash2.default.assign({}, trueResult, { _ambiguousAMPM: true }); } } }, filterResult(result) { // console.log(result) if (!result) { return false; } if (result.hour > 23) { return false; } return true; }, defaultProps: { minutes: true, seconds: false }, describe({ props }) { return (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)(Hour, { id: 'hour' }), (0, _elliptical.createElement)( 'choice', { ellipsis: true, id: 'minute', limit: 1 }, (0, _elliptical.createElement)('literal', { text: ':00', decorate: true, value: 0 }), props.minutes ? (0, _elliptical.createElement)( 'sequence', { optional: true, limited: true, merge: true }, (0, _elliptical.createElement)('literal', { text: ':' }), (0, _elliptical.createElement)(MinutesOrSeconds, { merge: true }) ) : null ), (0, _elliptical.createElement)('list', { unique: true, id: 'ampm', limit: 2, items: [{ text: ' am', value: 'am' }, { text: 'am', value: 'am' }, { text: ' a', value: 'am' }, { text: 'a', value: 'am' }, { text: ' a.m.', value: 'am' }, { text: 'a.m.', value: 'am' }, { text: ' a.m', value: 'am' }, { text: 'a.m', value: 'am' }, { text: ' pm', value: 'pm' }, { text: 'pm', value: 'pm' }, { text: ' p', value: 'pm' }, { text: 'p', value: 'pm' }, { text: ' p.m.', value: 'pm' }, { text: 'p.m.', value: 'pm' }, { text: ' p.m', value: 'pm' }, { text: 'p.m', value: 'pm' }] }) ); } }; const AmbiguousAbsoluteRelativeHour = { describe() { return (0, _elliptical.createElement)(BaseAbsoluteRelativeHour, { ambiguous: true }); } }; const AbsoluteRelativeHour = { describe() { return (0, _elliptical.createElement)(BaseAbsoluteRelativeHour, null); } }; const BaseAbsoluteRelativeHour = { defaultProps: { ambiguous: false }, mapResult(result) { const duration = result.direction === -1 ? (0, _helpers.negateDuration)(result.duration) : result.duration; return (0, _helpers.relativeTime)(duration, result.absolute); }, describe() { return (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)( 'placeholder', { label: 'number', id: 'duration' }, (0, _elliptical.createElement)( 'choice', null, (0, _elliptical.createElement)('list', { id: 'minutes', items: [{ text: 'quarter', value: 15 }, { text: 'half', value: 30 }] }), (0, _elliptical.createElement)(_ellipticalNumber.Integer, { allowWordForm: true, id: 'minutes', min: 1, max: 59, merge: true, limit: 1 }) ) ), (0, _elliptical.createElement)('list', { limit: 2, id: 'direction', items: [{ text: ' past ', value: 1 }, { text: ' to ', value: -1 }, { text: ' of ', value: -1 }, { text: ' til ', value: -1 }, { text: ' before ', value: -1 }, { text: ' from ', value: -1 }] }), (0, _elliptical.createElement)( 'placeholder', { label: 'hour', id: 'absolute' }, (0, _elliptical.createElement)( 'choice', null, (0, _elliptical.createElement)(AbsoluteNumeric, { minutes: false }), (0, _elliptical.createElement)(AbsoluteNamed, null) ) ) ); } }; const RecursiveTime = { mapResult(result) { const duration = result.direction === -1 ? (0, _helpers.negateDuration)(result.duration) : result.duration; return (0, _helpers.relativeTime)(duration, result.time); }, describe() { return (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)( 'sequence', { merge: true }, (0, _elliptical.createElement)(_duration.TimeDuration, { id: 'duration' }), (0, _elliptical.createElement)('list', { id: 'direction', items: [{ text: ' before ', value: -1 }, { text: ' after ', value: 1 }, { text: ' from ', value: 1 }, { text: ' past ', value: 1 }, { text: ' to ', value: -1 }, { text: ' of ', value: -1 }, { text: ' til ', value: -1 }], limit: 2 }) ), (0, _elliptical.createElement)(Time, { recurse: false, relative: false, id: 'time' }) ); } }; const MinutesOrSeconds = { mapResult(result) { return parseInt(result, 10); }, describe() { return (0, _elliptical.createElement)(_ellipticalNumber.DigitString, { label: 'minutes', max: 59, minLength: 2, maxLength: 2 }); } }; const Hour = { describe() { return (0, _elliptical.createElement)(_ellipticalNumber.DigitString, { label: 'hour', min: 0, max: 24, maxLength: 2, minLength: 1, allowLeadingZeros: true }); } };