cronli5 0.2.1 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +109 -0
- package/README.md +4 -4
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +471 -383
- package/dist/cronli5.js +471 -383
- package/dist/lang/de.cjs +286 -215
- package/dist/lang/de.js +286 -215
- package/dist/lang/en.cjs +413 -327
- package/dist/lang/en.js +413 -327
- package/dist/lang/es.cjs +303 -265
- package/dist/lang/es.js +303 -265
- package/dist/lang/fi.cjs +311 -266
- package/dist/lang/fi.js +311 -266
- package/dist/lang/zh.cjs +320 -240
- package/dist/lang/zh.js +320 -240
- package/package.json +6 -6
- package/src/core/analyze.ts +12 -12
- package/src/core/cadence.ts +164 -0
- package/src/core/index.ts +3 -1
- package/src/core/normalize.ts +3 -3
- package/src/core/parse.ts +1 -1
- package/src/core/{ir.ts → schedule.ts} +17 -18
- package/src/core/specs.ts +1 -1
- package/src/core/util.ts +3 -165
- package/src/core/validate.ts +1 -1
- package/src/core/weekday.ts +54 -0
- package/src/cronli5.ts +5 -5
- package/src/lang/de/index.ts +329 -219
- package/src/lang/en/dialects.ts +1 -1
- package/src/lang/en/index.ts +521 -372
- package/src/lang/es/index.ts +338 -286
- package/src/lang/es/notes.md +1 -1
- package/src/lang/fi/dialects.ts +1 -1
- package/src/lang/fi/index.ts +365 -299
- package/src/lang/fi/notes.md +23 -8
- package/src/lang/fi/status.json +1 -1
- package/src/lang/zh/index.ts +386 -245
- package/src/types.ts +6 -6
- package/types/core/analyze.d.ts +3 -3
- package/types/core/cadence.d.ts +33 -0
- package/types/core/index.d.ts +3 -1
- package/types/core/normalize.d.ts +1 -1
- package/types/core/parse.d.ts +1 -1
- package/types/core/{ir.d.ts → schedule.d.ts} +11 -16
- package/types/core/specs.d.ts +1 -1
- package/types/core/util.d.ts +1 -30
- package/types/core/weekday.d.ts +10 -0
- package/types/lang/de/index.d.ts +1 -1
- package/types/lang/en/dialects.d.ts +1 -1
- package/types/lang/en/index.d.ts +1 -1
- package/types/lang/es/index.d.ts +1 -1
- package/types/lang/fi/dialects.d.ts +1 -1
- package/types/lang/fi/index.d.ts +1 -1
- package/types/lang/zh/index.d.ts +1 -1
- package/types/types.d.ts +5 -5
package/dist/lang/es.cjs
CHANGED
|
@@ -57,6 +57,16 @@ function isNonNegativeInteger(value) {
|
|
|
57
57
|
const digits = /^\d+$/;
|
|
58
58
|
return digits.test(value);
|
|
59
59
|
}
|
|
60
|
+
function toFieldNumber(token, numberMap) {
|
|
61
|
+
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/core/shapes.ts
|
|
65
|
+
function isOpenStep(field) {
|
|
66
|
+
return field.indexOf("/") !== -1 && field.indexOf("-") === -1 && field.indexOf(",") === -1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/core/cadence.ts
|
|
60
70
|
function arithmeticStep(values) {
|
|
61
71
|
if (values.length < 5) {
|
|
62
72
|
return null;
|
|
@@ -72,34 +82,11 @@ function arithmeticStep(values) {
|
|
|
72
82
|
}
|
|
73
83
|
return { start: values[0], interval, last: values[values.length - 1] };
|
|
74
84
|
}
|
|
75
|
-
function
|
|
76
|
-
return
|
|
85
|
+
function segmentsOf(schedule, field) {
|
|
86
|
+
return schedule.analyses.segments[field] ?? [];
|
|
77
87
|
}
|
|
78
|
-
function
|
|
79
|
-
|
|
80
|
-
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
81
|
-
return { kind: "single", value: "" + value };
|
|
82
|
-
}) : [segment];
|
|
83
|
-
});
|
|
84
|
-
function key(segment) {
|
|
85
|
-
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
86
|
-
}
|
|
87
|
-
return flattened.map(function index(segment, position) {
|
|
88
|
-
return [segment, position];
|
|
89
|
-
}).sort(function byDisplayKey(a, b) {
|
|
90
|
-
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
91
|
-
}).map(function unwrap(pair) {
|
|
92
|
-
return pair[0];
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
function toFieldNumber(token, numberMap) {
|
|
96
|
-
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
97
|
-
}
|
|
98
|
-
function segmentsOf(ir, field) {
|
|
99
|
-
return ir.analyses.segments[field] ?? [];
|
|
100
|
-
}
|
|
101
|
-
function stepSegment(ir, field) {
|
|
102
|
-
return segmentsOf(ir, field)[0];
|
|
88
|
+
function stepSegment(schedule, field) {
|
|
89
|
+
return segmentsOf(schedule, field)[0];
|
|
103
90
|
}
|
|
104
91
|
function singleValues(segments) {
|
|
105
92
|
const values = [];
|
|
@@ -114,6 +101,17 @@ function singleValues(segments) {
|
|
|
114
101
|
function offsetCleanStride(stride) {
|
|
115
102
|
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
116
103
|
}
|
|
104
|
+
function renderStride(spec, parts) {
|
|
105
|
+
const { start, interval, cycle } = spec;
|
|
106
|
+
const tiles = cycle % interval === 0;
|
|
107
|
+
if (start === 0 && tiles) {
|
|
108
|
+
return parts.bare();
|
|
109
|
+
}
|
|
110
|
+
if (start < interval && tiles) {
|
|
111
|
+
return parts.offset();
|
|
112
|
+
}
|
|
113
|
+
return parts.bounded();
|
|
114
|
+
}
|
|
117
115
|
function hourListStride(values) {
|
|
118
116
|
if (values.length < 2) {
|
|
119
117
|
return null;
|
|
@@ -133,9 +131,26 @@ function hourListStride(values) {
|
|
|
133
131
|
return { interval, last: values[values.length - 1], start: values[0] };
|
|
134
132
|
}
|
|
135
133
|
|
|
136
|
-
// src/core/
|
|
137
|
-
function
|
|
138
|
-
return
|
|
134
|
+
// src/core/weekday.ts
|
|
135
|
+
function weekdayDisplayKey(value) {
|
|
136
|
+
return value === 0 ? 7 : value;
|
|
137
|
+
}
|
|
138
|
+
function orderWeekdaysForDisplay(segments) {
|
|
139
|
+
const flattened = segments.flatMap(function flat(segment) {
|
|
140
|
+
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
141
|
+
return { kind: "single", value: "" + value };
|
|
142
|
+
}) : [segment];
|
|
143
|
+
});
|
|
144
|
+
function key(segment) {
|
|
145
|
+
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
146
|
+
}
|
|
147
|
+
return flattened.map(function index(segment, position) {
|
|
148
|
+
return [segment, position];
|
|
149
|
+
}).sort(function byDisplayKey(a, b) {
|
|
150
|
+
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
151
|
+
}).map(function unwrap(pair) {
|
|
152
|
+
return pair[0];
|
|
153
|
+
});
|
|
139
154
|
}
|
|
140
155
|
|
|
141
156
|
// src/lang/es/dialects.ts
|
|
@@ -215,107 +230,107 @@ function normalizeOptions(options) {
|
|
|
215
230
|
years: !!options.years
|
|
216
231
|
};
|
|
217
232
|
}
|
|
218
|
-
function describe(
|
|
219
|
-
return applyYear(render(
|
|
233
|
+
function describe(schedule, opts) {
|
|
234
|
+
return applyYear(render(schedule, schedule.plan, opts), schedule, opts);
|
|
220
235
|
}
|
|
221
|
-
function render(
|
|
222
|
-
const phrase = renderers[plan.kind](
|
|
223
|
-
if (!isDateWeekdayUnion(
|
|
236
|
+
function render(schedule, plan, opts) {
|
|
237
|
+
const phrase = renderers[plan.kind](schedule, plan, opts);
|
|
238
|
+
if (!isDateWeekdayUnion(schedule)) {
|
|
224
239
|
return phrase;
|
|
225
240
|
}
|
|
226
|
-
const lead = unionMonthLeadFull(
|
|
227
|
-
return (lead ? lead + " " : "") + phrase + unionYaseaSuffix(
|
|
241
|
+
const lead = unionMonthLeadFull(schedule);
|
|
242
|
+
return (lead ? lead + " " : "") + phrase + unionYaseaSuffix(schedule, opts);
|
|
228
243
|
}
|
|
229
|
-
function renderEverySecond(
|
|
230
|
-
return "cada segundo" + trailingQualifier(
|
|
244
|
+
function renderEverySecond(schedule, plan, opts) {
|
|
245
|
+
return "cada segundo" + trailingQualifier(schedule, opts);
|
|
231
246
|
}
|
|
232
|
-
function renderStandaloneSeconds(
|
|
233
|
-
return secondsLeadClause(
|
|
247
|
+
function renderStandaloneSeconds(schedule, plan, opts) {
|
|
248
|
+
return secondsLeadClause(schedule, opts) + trailingQualifier(schedule, opts);
|
|
234
249
|
}
|
|
235
|
-
function renderSecondPastMinute(
|
|
236
|
-
return "en el segundo " +
|
|
250
|
+
function renderSecondPastMinute(schedule, plan, opts) {
|
|
251
|
+
return "en el segundo " + schedule.pattern.second + " de cada minuto" + trailingQualifier(schedule, opts);
|
|
237
252
|
}
|
|
238
|
-
function renderSecondsWithinMinute(
|
|
239
|
-
const minuteField =
|
|
253
|
+
function renderSecondsWithinMinute(schedule, plan, opts) {
|
|
254
|
+
const minuteField = schedule.pattern.minute;
|
|
240
255
|
if (plan.singleSecond) {
|
|
241
|
-
return "en el minuto " + minuteField + " y el segundo " +
|
|
256
|
+
return "en el minuto " + minuteField + " y el segundo " + schedule.pattern.second + " de cada hora" + trailingQualifier(schedule, opts);
|
|
242
257
|
}
|
|
243
|
-
return secondsLeadClause(
|
|
258
|
+
return secondsLeadClause(schedule, opts) + ", en el minuto " + minuteField + " de cada hora" + trailingQualifier(schedule, opts);
|
|
244
259
|
}
|
|
245
|
-
function secondsListAtClock(
|
|
260
|
+
function secondsListAtClock(schedule, rest, opts) {
|
|
246
261
|
const clockPhrases = rest.times.map(function clock(time) {
|
|
247
262
|
return atTime(timePhrase(time.hour, time.minute, null, opts));
|
|
248
263
|
});
|
|
249
264
|
const grouped = groupClockTimesByArticle(clockPhrases);
|
|
250
265
|
const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
|
|
251
|
-
const stride = strideFromSegments(segmentsOf(
|
|
252
|
-
const secondsPhrase = stride ?? "en los segundos " + joinList(segmentWords(segmentsOf(
|
|
253
|
-
const dayFrame = trailingQualifier(
|
|
266
|
+
const stride = strideFromSegments(segmentsOf(schedule, "second"), "segundo", "", opts);
|
|
267
|
+
const secondsPhrase = stride ?? "en los segundos " + joinList(segmentWords(segmentsOf(schedule, "second")));
|
|
268
|
+
const dayFrame = trailingQualifier(schedule, opts);
|
|
254
269
|
return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
|
|
255
270
|
}
|
|
256
|
-
function composeHourCadence(
|
|
271
|
+
function composeHourCadence(schedule, plan, opts) {
|
|
257
272
|
const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
|
|
258
|
-
if (!clockRest ||
|
|
273
|
+
if (!clockRest || schedule.shapes.minute !== "single") {
|
|
259
274
|
return null;
|
|
260
275
|
}
|
|
261
|
-
const minute = +
|
|
262
|
-
return hourCadence(
|
|
276
|
+
const minute = +schedule.pattern.minute;
|
|
277
|
+
return hourCadence(schedule, minute, opts) ?? hourRangeCadence(schedule, minute, opts);
|
|
263
278
|
}
|
|
264
|
-
function isPinnedMinuteSeconds(
|
|
265
|
-
return plan.rest.kind === "clockTimes" && (
|
|
279
|
+
function isPinnedMinuteSeconds(schedule, plan) {
|
|
280
|
+
return plan.rest.kind === "clockTimes" && (schedule.shapes.second === "wildcard" || schedule.shapes.second === "step");
|
|
266
281
|
}
|
|
267
|
-
function renderComposeSeconds(
|
|
268
|
-
const hourCad = composeHourCadence(
|
|
282
|
+
function renderComposeSeconds(schedule, plan, opts) {
|
|
283
|
+
const hourCad = composeHourCadence(schedule, plan, opts);
|
|
269
284
|
if (hourCad !== null) {
|
|
270
285
|
return hourCad;
|
|
271
286
|
}
|
|
272
|
-
if (isPinnedMinuteSeconds(
|
|
273
|
-
return pinnedMinuteSeconds(
|
|
287
|
+
if (isPinnedMinuteSeconds(schedule, plan)) {
|
|
288
|
+
return pinnedMinuteSeconds(schedule, plan.rest, opts);
|
|
274
289
|
}
|
|
275
|
-
if (plan.rest.kind === "clockTimes" &&
|
|
276
|
-
return secondsListAtClock(
|
|
290
|
+
if (plan.rest.kind === "clockTimes" && schedule.shapes.second === "list") {
|
|
291
|
+
return secondsListAtClock(schedule, plan.rest, opts);
|
|
277
292
|
}
|
|
278
|
-
if (plan.rest.kind === "hourRange" &&
|
|
293
|
+
if (plan.rest.kind === "hourRange" && schedule.shapes.second === "step" && schedule.pattern.weekday !== "*") {
|
|
279
294
|
const restNode = plan.rest;
|
|
280
295
|
const window = hourWindow(boundedWindow(restNode), opts);
|
|
281
|
-
const dayFrame = weekdayQualifier(
|
|
282
|
-
const cadence = "cada " + numero(stepSegment(
|
|
296
|
+
const dayFrame = weekdayQualifier(schedule) + monthScope(schedule);
|
|
297
|
+
const cadence = "cada " + numero(stepSegment(schedule, "second").interval, opts) + " segundos del minuto " + schedule.pattern.minute;
|
|
283
298
|
return dayFrame + ", " + window + ", " + cadence;
|
|
284
299
|
}
|
|
285
|
-
if (isEveryOtherMinuteSeconds(
|
|
286
|
-
return secondsLeadClause(
|
|
300
|
+
if (isEveryOtherMinuteSeconds(schedule, plan)) {
|
|
301
|
+
return secondsLeadClause(schedule, opts) + " de " + render(schedule, plan.rest, opts);
|
|
287
302
|
}
|
|
288
|
-
const restOwnsLead = plan.rest.kind === "compactClockTimes" &&
|
|
289
|
-
const lead = restOwnsLead ? "" : secondsLeadClause(
|
|
290
|
-
return lead + render(
|
|
303
|
+
const restOwnsLead = plan.rest.kind === "compactClockTimes" && schedule.analyses.clockSecond;
|
|
304
|
+
const lead = restOwnsLead ? "" : secondsLeadClause(schedule, opts) + ", ";
|
|
305
|
+
return lead + render(schedule, plan.rest, opts);
|
|
291
306
|
}
|
|
292
|
-
function isEveryOtherMinuteSeconds(
|
|
293
|
-
if (plan.rest.kind !== "minuteFrequency" ||
|
|
307
|
+
function isEveryOtherMinuteSeconds(schedule, plan) {
|
|
308
|
+
if (plan.rest.kind !== "minuteFrequency" || schedule.shapes.second !== "wildcard" || schedule.shapes.hour !== "wildcard") {
|
|
294
309
|
return false;
|
|
295
310
|
}
|
|
296
|
-
const minuteStep = stepSegment(
|
|
311
|
+
const minuteStep = stepSegment(schedule, "minute");
|
|
297
312
|
return minuteStep.startToken === "*" && minuteStep.interval === 2;
|
|
298
313
|
}
|
|
299
|
-
function pinnedMinuteSeconds(
|
|
300
|
-
const dayTrail = leadingQualifier(
|
|
314
|
+
function pinnedMinuteSeconds(schedule, rest, opts) {
|
|
315
|
+
const dayTrail = leadingQualifier(schedule, opts).trimEnd();
|
|
301
316
|
const trail = dayTrail ? ", " + dayTrail : "";
|
|
302
|
-
if (+rest.times[0].minute === 0 &&
|
|
303
|
-
return secondsLeadClause(
|
|
317
|
+
if (+rest.times[0].minute === 0 && schedule.shapes.minute === "single") {
|
|
318
|
+
return secondsLeadClause(schedule, opts) + " durante un minuto " + durationHourList(rest.times, opts) + trail;
|
|
304
319
|
}
|
|
305
|
-
return secondsLeadClause(
|
|
320
|
+
return secondsLeadClause(schedule, opts) + " de " + explicitClockList(rest.times, opts) + trail;
|
|
306
321
|
}
|
|
307
|
-
function secondsLeadClause(
|
|
308
|
-
return secondsClause(
|
|
322
|
+
function secondsLeadClause(schedule, opts) {
|
|
323
|
+
return secondsClause(schedule, "minuto", opts);
|
|
309
324
|
}
|
|
310
|
-
function secondsClause(
|
|
311
|
-
const secondField =
|
|
312
|
-
const shape =
|
|
325
|
+
function secondsClause(schedule, anchor, opts) {
|
|
326
|
+
const secondField = schedule.pattern.second;
|
|
327
|
+
const shape = schedule.shapes.second;
|
|
313
328
|
if (secondField === "*") {
|
|
314
329
|
return "cada segundo";
|
|
315
330
|
}
|
|
316
331
|
if (shape === "step") {
|
|
317
332
|
return stepCycle60(
|
|
318
|
-
stepSegment(
|
|
333
|
+
stepSegment(schedule, "second"),
|
|
319
334
|
"segundo",
|
|
320
335
|
anchor,
|
|
321
336
|
opts
|
|
@@ -329,31 +344,31 @@ function secondsClause(ir, anchor, opts) {
|
|
|
329
344
|
return "en el segundo " + secondField + " de cada " + anchor;
|
|
330
345
|
}
|
|
331
346
|
return strideFromSegments(
|
|
332
|
-
segmentsOf(
|
|
347
|
+
segmentsOf(schedule, "second"),
|
|
333
348
|
"segundo",
|
|
334
349
|
anchor,
|
|
335
350
|
opts
|
|
336
|
-
) ?? "en los segundos " + joinList(segmentWords(segmentsOf(
|
|
351
|
+
) ?? "en los segundos " + joinList(segmentWords(segmentsOf(schedule, "second"))) + " de cada " + anchor;
|
|
337
352
|
}
|
|
338
|
-
function renderEveryMinute(
|
|
339
|
-
return "cada minuto" + trailingQualifier(
|
|
353
|
+
function renderEveryMinute(schedule, plan, opts) {
|
|
354
|
+
return "cada minuto" + trailingQualifier(schedule, opts);
|
|
340
355
|
}
|
|
341
|
-
function renderSingleMinute(
|
|
342
|
-
return "en el minuto " +
|
|
356
|
+
function renderSingleMinute(schedule, plan, opts) {
|
|
357
|
+
return "en el minuto " + schedule.pattern.minute + " de cada hora" + trailingQualifier(schedule, opts);
|
|
343
358
|
}
|
|
344
|
-
function renderRangeOfMinutes(
|
|
345
|
-
return minuteRangeLead(
|
|
359
|
+
function renderRangeOfMinutes(schedule, plan, opts) {
|
|
360
|
+
return minuteRangeLead(schedule.pattern.minute) + " de cada hora" + trailingQualifier(schedule, opts);
|
|
346
361
|
}
|
|
347
|
-
function renderMultipleMinutes(
|
|
348
|
-
return minutesList(
|
|
362
|
+
function renderMultipleMinutes(schedule, plan, opts) {
|
|
363
|
+
return minutesList(schedule, opts) + trailingQualifier(schedule, opts);
|
|
349
364
|
}
|
|
350
|
-
function minutesList(
|
|
365
|
+
function minutesList(schedule, opts) {
|
|
351
366
|
return strideFromSegments(
|
|
352
|
-
segmentsOf(
|
|
367
|
+
segmentsOf(schedule, "minute"),
|
|
353
368
|
"minuto",
|
|
354
369
|
"hora",
|
|
355
370
|
opts
|
|
356
|
-
) ?? "en los minutos " + joinList(segmentWords(segmentsOf(
|
|
371
|
+
) ?? "en los minutos " + joinList(segmentWords(segmentsOf(schedule, "minute"))) + " de cada hora";
|
|
357
372
|
}
|
|
358
373
|
function minuteRangeLead(minuteField) {
|
|
359
374
|
const bounds = minuteField.split("-");
|
|
@@ -408,86 +423,86 @@ function spanHours(hours) {
|
|
|
408
423
|
return (hour === 1 ? "la " : "las ") + hour;
|
|
409
424
|
}));
|
|
410
425
|
}
|
|
411
|
-
function renderMinuteFrequency(
|
|
426
|
+
function renderMinuteFrequency(schedule, plan, opts) {
|
|
412
427
|
let phrase = stepCycle60(
|
|
413
|
-
stepSegment(
|
|
428
|
+
stepSegment(schedule, "minute"),
|
|
414
429
|
"minuto",
|
|
415
430
|
"hora",
|
|
416
431
|
opts
|
|
417
432
|
);
|
|
418
433
|
if (plan.hours.kind === "during") {
|
|
419
|
-
const cadence = unevenHourCadence(
|
|
434
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
420
435
|
if (cadence) {
|
|
421
436
|
phrase += ", " + cadence;
|
|
422
437
|
} else {
|
|
423
|
-
phrase += singleHourStep(
|
|
438
|
+
phrase += singleHourStep(schedule.analyses.segments.hour) ? ", " + stepHourSpan(stepSegment(schedule, "hour"), opts) : " " + hourSpanFromTimes(schedule, plan.hours.times, opts);
|
|
424
439
|
}
|
|
425
440
|
} else if (plan.hours.kind === "window") {
|
|
426
441
|
phrase += " " + hourWindow(plan.hours, opts);
|
|
427
442
|
} else if (plan.hours.kind === "step") {
|
|
428
|
-
phrase += ", " + stepHourSpan(stepSegment(
|
|
443
|
+
phrase += ", " + stepHourSpan(stepSegment(schedule, "hour"), opts);
|
|
429
444
|
}
|
|
430
|
-
return phrase + trailingQualifier(
|
|
445
|
+
return phrase + trailingQualifier(schedule, opts);
|
|
431
446
|
}
|
|
432
|
-
function renderMinuteSpanInHour(
|
|
433
|
-
if (
|
|
434
|
-
return "cada minuto de la hora " + fromTime(timePhrase(plan.hour, 0, null, opts)) + trailingQualifier(
|
|
447
|
+
function renderMinuteSpanInHour(schedule, plan, opts) {
|
|
448
|
+
if (schedule.pattern.minute === "*") {
|
|
449
|
+
return "cada minuto de la hora " + fromTime(timePhrase(plan.hour, 0, null, opts)) + trailingQualifier(schedule, opts);
|
|
435
450
|
}
|
|
436
451
|
return "cada minuto " + timeRange(
|
|
437
452
|
{ hour: plan.hour, minute: plan.span[0] },
|
|
438
453
|
{ hour: plan.hour, minute: plan.span[1] },
|
|
439
454
|
opts
|
|
440
|
-
) + trailingQualifier(
|
|
455
|
+
) + trailingQualifier(schedule, opts);
|
|
441
456
|
}
|
|
442
|
-
function renderMinutesAcrossHours(
|
|
443
|
-
const cadence = unevenHourCadence(
|
|
457
|
+
function renderMinutesAcrossHours(schedule, plan, opts) {
|
|
458
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
444
459
|
if (plan.form === "wildcard") {
|
|
445
460
|
if (cadence !== null) {
|
|
446
|
-
return "cada minuto, " + cadence + trailingQualifier(
|
|
461
|
+
return "cada minuto, " + cadence + trailingQualifier(schedule, opts);
|
|
447
462
|
}
|
|
448
|
-
if (singleHourStep(
|
|
449
|
-
return "cada minuto, " + stepHourSpan(stepSegment(
|
|
463
|
+
if (singleHourStep(schedule.analyses.segments.hour)) {
|
|
464
|
+
return "cada minuto, " + stepHourSpan(stepSegment(schedule, "hour"), opts) + trailingQualifier(schedule, opts);
|
|
450
465
|
}
|
|
451
|
-
return "cada minuto " + hourSpanFromTimes(
|
|
466
|
+
return "cada minuto " + hourSpanFromTimes(schedule, plan.times, opts) + trailingQualifier(schedule, opts);
|
|
452
467
|
}
|
|
453
|
-
const lead = plan.form === "range" ? minuteRangeLead(
|
|
468
|
+
const lead = plan.form === "range" ? minuteRangeLead(schedule.pattern.minute) : minutesList(schedule, opts);
|
|
454
469
|
if (cadence !== null) {
|
|
455
|
-
return lead + ", " + cadence + trailingQualifier(
|
|
470
|
+
return lead + ", " + cadence + trailingQualifier(schedule, opts);
|
|
456
471
|
}
|
|
457
|
-
return lead + ", " + atHourTimes(
|
|
472
|
+
return lead + ", " + atHourTimes(schedule, plan.times, opts) + trailingQualifier(schedule, opts);
|
|
458
473
|
}
|
|
459
|
-
function renderMinuteSpanAcrossHourStep(
|
|
460
|
-
const segment = stepSegment(
|
|
461
|
-
const cadence = unevenHourCadence(
|
|
474
|
+
function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
|
|
475
|
+
const segment = stepSegment(schedule, "hour");
|
|
476
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
462
477
|
if (plan.form === "wildcard") {
|
|
463
|
-
return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(
|
|
478
|
+
return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(schedule, opts);
|
|
464
479
|
}
|
|
465
|
-
const lead = plan.form === "list" ? minutesList(
|
|
466
|
-
return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(
|
|
480
|
+
const lead = plan.form === "list" ? minutesList(schedule, opts) : minuteRangeLead(schedule.pattern.minute);
|
|
481
|
+
return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(schedule, opts);
|
|
467
482
|
}
|
|
468
|
-
function renderEveryHour(
|
|
469
|
-
return "cada hora" + trailingQualifier(
|
|
483
|
+
function renderEveryHour(schedule, plan, opts) {
|
|
484
|
+
return "cada hora" + trailingQualifier(schedule, opts);
|
|
470
485
|
}
|
|
471
|
-
function renderHourRange(
|
|
486
|
+
function renderHourRange(schedule, plan, opts) {
|
|
472
487
|
const window = hourWindow(boundedWindow(plan), opts);
|
|
473
488
|
if (plan.minuteForm === "wildcard") {
|
|
474
|
-
return "cada minuto " + window + trailingQualifier(
|
|
489
|
+
return "cada minuto " + window + trailingQualifier(schedule, opts);
|
|
475
490
|
}
|
|
476
491
|
if (plan.minuteForm === "range") {
|
|
477
|
-
return minuteRangeLead(
|
|
492
|
+
return minuteRangeLead(schedule.pattern.minute) + ", " + window + trailingQualifier(schedule, opts);
|
|
478
493
|
}
|
|
479
|
-
if (
|
|
480
|
-
return "cada hora " + window + trailingQualifier(
|
|
494
|
+
if (schedule.pattern.minute === "0") {
|
|
495
|
+
return "cada hora " + window + trailingQualifier(schedule, opts);
|
|
481
496
|
}
|
|
482
|
-
const lead =
|
|
483
|
-
return lead + ", " + window + trailingQualifier(
|
|
497
|
+
const lead = schedule.shapes.minute === "single" ? "en el minuto " + schedule.pattern.minute + " de cada hora" : minutesList(schedule, opts);
|
|
498
|
+
return lead + ", " + window + trailingQualifier(schedule, opts);
|
|
484
499
|
}
|
|
485
|
-
function renderHourStep(
|
|
486
|
-
const cadence = unevenHourCadence(
|
|
500
|
+
function renderHourStep(schedule, plan, opts) {
|
|
501
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
487
502
|
if (cadence !== null) {
|
|
488
|
-
return cadence + trailingQualifier(
|
|
503
|
+
return cadence + trailingQualifier(schedule, opts);
|
|
489
504
|
}
|
|
490
|
-
return stepHours(stepSegment(
|
|
505
|
+
return stepHours(stepSegment(schedule, "hour"), opts) + trailingQualifier(schedule, opts);
|
|
491
506
|
}
|
|
492
507
|
function boundedWindow(plan) {
|
|
493
508
|
const last = plan.minuteForm === "wildcard" ? plan.boundMinute ?? 0 : 0;
|
|
@@ -500,42 +515,46 @@ function hourWindow(window, opts) {
|
|
|
500
515
|
opts
|
|
501
516
|
);
|
|
502
517
|
}
|
|
503
|
-
function isDateWeekdayUnion(
|
|
504
|
-
return
|
|
518
|
+
function isDateWeekdayUnion(schedule) {
|
|
519
|
+
return schedule.pattern.date !== "*" && schedule.pattern.weekday !== "*";
|
|
505
520
|
}
|
|
506
|
-
function unionMonthLeadFull(
|
|
507
|
-
if (
|
|
521
|
+
function unionMonthLeadFull(schedule) {
|
|
522
|
+
if (schedule.pattern.month === "*") {
|
|
508
523
|
return "";
|
|
509
524
|
}
|
|
510
|
-
const lead = monthPhrase(
|
|
511
|
-
const segments = flattenSteps(segmentsOf(
|
|
512
|
-
const isEnumeration = !monthRanged(
|
|
525
|
+
const lead = monthPhrase(schedule, monthRanged(schedule) ? "de " : "en ");
|
|
526
|
+
const segments = flattenSteps(segmentsOf(schedule, "month"));
|
|
527
|
+
const isEnumeration = !monthRanged(schedule) && segments.length >= 2;
|
|
513
528
|
return isEnumeration ? lead + "," : lead;
|
|
514
529
|
}
|
|
515
|
-
function domArm(
|
|
516
|
-
const date =
|
|
530
|
+
function domArm(schedule, opts) {
|
|
531
|
+
const date = schedule.pattern.date;
|
|
517
532
|
const quartz = quartzDatePhrase(date);
|
|
518
533
|
if (quartz) {
|
|
519
534
|
return quartz;
|
|
520
535
|
}
|
|
536
|
+
const parity = parityDayPredicate(date);
|
|
537
|
+
if (parity) {
|
|
538
|
+
return parity;
|
|
539
|
+
}
|
|
521
540
|
if (isOpenStep(date)) {
|
|
522
541
|
return stepDates(date, opts);
|
|
523
542
|
}
|
|
524
|
-
const segments = segmentsOf(
|
|
543
|
+
const segments = segmentsOf(schedule, "date");
|
|
525
544
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
526
545
|
return "del " + segments[0].bounds[0] + " al " + segments[0].bounds[1] + " del mes";
|
|
527
546
|
}
|
|
528
547
|
if (segments.length === 1 && segments[0].kind === "single") {
|
|
529
|
-
return
|
|
548
|
+
return schedule.pattern.month === "*" ? "el " + segments[0].value + " de cada mes" : "el d\xEDa " + segments[0].value;
|
|
530
549
|
}
|
|
531
550
|
return "los d\xEDas " + joinList(segmentWords(segments)) + " del mes";
|
|
532
551
|
}
|
|
533
|
-
function dowArm(
|
|
534
|
-
const quartz = quartzWeekdayPhrase(
|
|
552
|
+
function dowArm(schedule) {
|
|
553
|
+
const quartz = quartzWeekdayPhrase(schedule.pattern.weekday);
|
|
535
554
|
if (quartz) {
|
|
536
555
|
return quartz;
|
|
537
556
|
}
|
|
538
|
-
const segments = orderWeekdaysForDisplay(segmentsOf(
|
|
557
|
+
const segments = orderWeekdaysForDisplay(segmentsOf(schedule, "weekday"));
|
|
539
558
|
const allSingles = segments.every(function single(segment) {
|
|
540
559
|
return segment.kind === "single";
|
|
541
560
|
});
|
|
@@ -548,19 +567,19 @@ function dowArm(ir) {
|
|
|
548
567
|
}));
|
|
549
568
|
}
|
|
550
569
|
if (segments.length === 1) {
|
|
551
|
-
return weekdayRange(segments[0]);
|
|
570
|
+
return "cualquier d\xEDa " + weekdayRange(segments[0]);
|
|
552
571
|
}
|
|
553
572
|
return joinList(segments.map(function name(segment) {
|
|
554
573
|
return segment.kind === "range" ? weekdayRange(segment) : "los " + pluralWeekday(segment.value);
|
|
555
574
|
}));
|
|
556
575
|
}
|
|
557
|
-
function unionYaseaSuffix(
|
|
558
|
-
return ", ya sea " + domArm(
|
|
576
|
+
function unionYaseaSuffix(schedule, opts) {
|
|
577
|
+
return ", ya sea " + domArm(schedule, opts) + " o " + dowArm(schedule);
|
|
559
578
|
}
|
|
560
|
-
function renderClockTimes(
|
|
561
|
-
if (
|
|
562
|
-
const minute = +
|
|
563
|
-
const cadence = hourCadence(
|
|
579
|
+
function renderClockTimes(schedule, plan, opts) {
|
|
580
|
+
if (schedule.shapes.minute === "single") {
|
|
581
|
+
const minute = +schedule.pattern.minute;
|
|
582
|
+
const cadence = hourCadence(schedule, minute, opts) ?? hourRangeCadence(schedule, minute, opts);
|
|
564
583
|
if (cadence !== null) {
|
|
565
584
|
return cadence;
|
|
566
585
|
}
|
|
@@ -568,7 +587,7 @@ function renderClockTimes(ir, plan, opts) {
|
|
|
568
587
|
const phrases = plan.times.map(function clock(time) {
|
|
569
588
|
return atTime(timePhrase(time.hour, time.minute, time.second, opts));
|
|
570
589
|
});
|
|
571
|
-
return leadingQualifier(
|
|
590
|
+
return leadingQualifier(schedule, opts) + groupClockTimes(phrases);
|
|
572
591
|
}
|
|
573
592
|
function explicitClockList(times, opts) {
|
|
574
593
|
const phrases = times.map(function clock(time) {
|
|
@@ -744,23 +763,33 @@ function groupClockTimesByArticle(phrases) {
|
|
|
744
763
|
const connector = doubleY ? ", " : " y ";
|
|
745
764
|
return laPart + connector + lasPart;
|
|
746
765
|
}
|
|
747
|
-
function renderCompactClockTimes(
|
|
766
|
+
function renderCompactClockTimes(schedule, plan, opts) {
|
|
748
767
|
if (plan.fold) {
|
|
749
|
-
const cadence2 = hourCadence(
|
|
768
|
+
const cadence2 = hourCadence(schedule, plan.minute, opts) ?? hourRangeCadence(schedule, plan.minute, opts);
|
|
750
769
|
if (cadence2 !== null) {
|
|
751
770
|
return cadence2;
|
|
752
771
|
}
|
|
753
|
-
const ranged = segmentsOf(
|
|
772
|
+
const ranged = segmentsOf(schedule, "hour").some(function range(segment) {
|
|
754
773
|
return segment.kind === "range";
|
|
755
774
|
});
|
|
756
|
-
if (ranged && !
|
|
757
|
-
return "cada hora " + hourSegmentTimes(
|
|
775
|
+
if (ranged && !schedule.analyses.clockSecond) {
|
|
776
|
+
return "cada hora " + hourSegmentTimes(
|
|
777
|
+
schedule,
|
|
778
|
+
plan.minute,
|
|
779
|
+
schedule.analyses.clockSecond,
|
|
780
|
+
opts
|
|
781
|
+
) + trailingQualifier(schedule, opts);
|
|
758
782
|
}
|
|
759
|
-
return leadingQualifier(
|
|
783
|
+
return leadingQualifier(schedule, opts) + hourSegmentTimes(
|
|
784
|
+
schedule,
|
|
785
|
+
plan.minute,
|
|
786
|
+
schedule.analyses.clockSecond,
|
|
787
|
+
opts
|
|
788
|
+
);
|
|
760
789
|
}
|
|
761
|
-
const cadence = unevenHourCadence(
|
|
762
|
-
const phrase = cadence ? minutesList(
|
|
763
|
-
return
|
|
790
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
791
|
+
const phrase = cadence ? minutesList(schedule, opts) + ", " + cadence + trailingQualifier(schedule, opts) : minutesList(schedule, opts) + ", " + hourContextTimes(schedule, opts) + trailingQualifier(schedule, opts);
|
|
792
|
+
return schedule.analyses.clockSecond ? secondsLeadClause(schedule, opts) + ", " + phrase : phrase;
|
|
764
793
|
}
|
|
765
794
|
var renderers = {
|
|
766
795
|
clockTimes: renderClockTimes,
|
|
@@ -782,18 +811,15 @@ var renderers = {
|
|
|
782
811
|
singleMinute: renderSingleMinute,
|
|
783
812
|
standaloneSeconds: renderStandaloneSeconds
|
|
784
813
|
};
|
|
785
|
-
function
|
|
814
|
+
function renderStride2(stride, opts) {
|
|
786
815
|
const { interval, start, last, cycle, unit, anchor } = stride;
|
|
787
816
|
const cadence = "cada " + numero(interval, opts) + " " + unit + "s";
|
|
788
|
-
const tiles = cycle % interval === 0;
|
|
789
|
-
if (start === 0 && tiles) {
|
|
790
|
-
return cadence;
|
|
791
|
-
}
|
|
792
817
|
const tail = anchor ? " de cada " + anchor : "";
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
818
|
+
return renderStride({ start, interval, cycle }, {
|
|
819
|
+
bare: () => cadence,
|
|
820
|
+
offset: () => cadence + " a partir del " + unit + " " + start + tail,
|
|
821
|
+
bounded: () => cadence + " del " + unit + " " + start + " al " + last + tail
|
|
822
|
+
});
|
|
797
823
|
}
|
|
798
824
|
function stepCycle60(segment, unit, anchor, opts) {
|
|
799
825
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
@@ -803,7 +829,7 @@ function stepCycle60(segment, unit, anchor, opts) {
|
|
|
803
829
|
if (start !== 0 && segment.fires.length <= 3) {
|
|
804
830
|
return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
|
|
805
831
|
}
|
|
806
|
-
return
|
|
832
|
+
return renderStride2({
|
|
807
833
|
interval: segment.interval,
|
|
808
834
|
start,
|
|
809
835
|
last: segment.fires[segment.fires.length - 1],
|
|
@@ -815,7 +841,7 @@ function stepCycle60(segment, unit, anchor, opts) {
|
|
|
815
841
|
function strideFromSegments(segments, unit, anchor, opts) {
|
|
816
842
|
const values = singleValues(segments);
|
|
817
843
|
const step = values && arithmeticStep(values);
|
|
818
|
-
return step ?
|
|
844
|
+
return step ? renderStride2({ ...step, cycle: 60, unit, anchor }, opts) : null;
|
|
819
845
|
}
|
|
820
846
|
function stepHours(segment, opts) {
|
|
821
847
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
@@ -834,24 +860,21 @@ function stepHours(segment, opts) {
|
|
|
834
860
|
function hourStrideCadence(stride, opts) {
|
|
835
861
|
const { start, interval, last } = stride;
|
|
836
862
|
const cadence = "cada " + numero(interval, opts) + " horas";
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
return cadence + " a partir de " + timePhrase(start, 0, null, opts);
|
|
843
|
-
}
|
|
844
|
-
return cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts);
|
|
863
|
+
return renderStride({ start, interval, cycle: 24 }, {
|
|
864
|
+
bare: () => cadence,
|
|
865
|
+
offset: () => cadence + " a partir de " + timePhrase(start, 0, null, opts),
|
|
866
|
+
bounded: () => cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts)
|
|
867
|
+
});
|
|
845
868
|
}
|
|
846
|
-
function unevenHourCadence(
|
|
847
|
-
const stride = hourStride(
|
|
869
|
+
function unevenHourCadence(schedule, opts) {
|
|
870
|
+
const stride = hourStride(schedule);
|
|
848
871
|
if (!stride || offsetCleanStride(stride)) {
|
|
849
872
|
return null;
|
|
850
873
|
}
|
|
851
874
|
return hourStrideCadence(stride, opts);
|
|
852
875
|
}
|
|
853
|
-
function hourStride(
|
|
854
|
-
const segments = segmentsOf(
|
|
876
|
+
function hourStride(schedule) {
|
|
877
|
+
const segments = segmentsOf(schedule, "hour");
|
|
855
878
|
if (segments.length === 1 && segments[0].kind === "step") {
|
|
856
879
|
const segment = segments[0];
|
|
857
880
|
if (segment.fires.length < 2) {
|
|
@@ -863,64 +886,64 @@ function hourStride(ir) {
|
|
|
863
886
|
const values = singleValues(segments);
|
|
864
887
|
return values && hourListStride(values);
|
|
865
888
|
}
|
|
866
|
-
function subMinuteSecond(
|
|
867
|
-
return
|
|
889
|
+
function subMinuteSecond(schedule) {
|
|
890
|
+
return schedule.pattern.second === "*" || schedule.shapes.second === "step";
|
|
868
891
|
}
|
|
869
|
-
function hourCadenceLead(
|
|
892
|
+
function hourCadenceLead(schedule, minute, opts) {
|
|
870
893
|
if (minute === 0) {
|
|
871
|
-
if (subMinuteSecond(
|
|
872
|
-
return secondsClause(
|
|
894
|
+
if (subMinuteSecond(schedule)) {
|
|
895
|
+
return secondsClause(schedule, "minuto", opts) + " durante un minuto";
|
|
873
896
|
}
|
|
874
|
-
return secondsClause(
|
|
897
|
+
return secondsClause(schedule, "hora", opts);
|
|
875
898
|
}
|
|
876
899
|
const minutePhrase = "en el minuto " + minute;
|
|
877
|
-
if (
|
|
900
|
+
if (schedule.pattern.second === "0") {
|
|
878
901
|
return minutePhrase;
|
|
879
902
|
}
|
|
880
|
-
return secondsClause(
|
|
903
|
+
return secondsClause(schedule, "minuto", opts) + ", " + minutePhrase;
|
|
881
904
|
}
|
|
882
|
-
function hourCadence(
|
|
883
|
-
const stride = hourStride(
|
|
905
|
+
function hourCadence(schedule, minute, opts) {
|
|
906
|
+
const stride = hourStride(schedule);
|
|
884
907
|
if (!stride) {
|
|
885
908
|
return null;
|
|
886
909
|
}
|
|
887
910
|
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
888
|
-
if (
|
|
911
|
+
if (schedule.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
|
|
889
912
|
return null;
|
|
890
913
|
}
|
|
891
|
-
const confinement = minute === 0 && subMinuteSecond(
|
|
914
|
+
const confinement = minute === 0 && subMinuteSecond(schedule) && cleanStrideSegment(schedule);
|
|
892
915
|
if (confinement) {
|
|
893
|
-
return secondsClause(
|
|
916
|
+
return secondsClause(schedule, "minuto", opts) + " durante un minuto, " + stepHourSpan(confinement, opts) + trailingQualifier(schedule, opts);
|
|
894
917
|
}
|
|
895
|
-
if (minute === 0 &&
|
|
896
|
-
return hourStrideCadence(stride, opts) + trailingQualifier(
|
|
918
|
+
if (minute === 0 && schedule.pattern.second === "0") {
|
|
919
|
+
return hourStrideCadence(stride, opts) + trailingQualifier(schedule, opts);
|
|
897
920
|
}
|
|
898
|
-
return hourCadenceLead(
|
|
921
|
+
return hourCadenceLead(schedule, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(schedule, opts);
|
|
899
922
|
}
|
|
900
|
-
function cleanStrideSegment(
|
|
901
|
-
const segments = segmentsOf(
|
|
923
|
+
function cleanStrideSegment(schedule) {
|
|
924
|
+
const segments = segmentsOf(schedule, "hour");
|
|
902
925
|
const segment = segments.length === 1 && segments[0];
|
|
903
926
|
if (!segment || segment.kind !== "step" || segment.startToken.indexOf("-") !== -1) {
|
|
904
927
|
return null;
|
|
905
928
|
}
|
|
906
929
|
return segment;
|
|
907
930
|
}
|
|
908
|
-
function hasHourWindow(
|
|
909
|
-
return segmentsOf(
|
|
931
|
+
function hasHourWindow(schedule) {
|
|
932
|
+
return segmentsOf(schedule, "hour").some(function range(segment) {
|
|
910
933
|
return segment.kind === "range";
|
|
911
934
|
});
|
|
912
935
|
}
|
|
913
|
-
function hourRangeCadence(
|
|
914
|
-
if (minute !== 0 || !hasHourWindow(
|
|
936
|
+
function hourRangeCadence(schedule, minute, opts) {
|
|
937
|
+
if (minute !== 0 || !hasHourWindow(schedule) || schedule.pattern.second === "0") {
|
|
915
938
|
return null;
|
|
916
939
|
}
|
|
917
|
-
if (subMinuteSecond(
|
|
918
|
-
return secondsClause(
|
|
940
|
+
if (subMinuteSecond(schedule)) {
|
|
941
|
+
return secondsClause(schedule, "minuto", opts) + " durante un minuto, durante las horas " + hourSegmentTimes(schedule, 0, null, opts) + trailingQualifier(schedule, opts);
|
|
919
942
|
}
|
|
920
|
-
return hourCadenceLead(
|
|
943
|
+
return hourCadenceLead(schedule, minute, opts) + ", " + hourSegmentTimes(schedule, 0, null, opts) + trailingQualifier(schedule, opts);
|
|
921
944
|
}
|
|
922
|
-
function hourContextTimes(
|
|
923
|
-
const segments = segmentsOf(
|
|
945
|
+
function hourContextTimes(schedule, opts) {
|
|
946
|
+
const segments = segmentsOf(schedule, "hour");
|
|
924
947
|
const points = [];
|
|
925
948
|
const hasRange = segments.some(function range(segment) {
|
|
926
949
|
return segment.kind === "range";
|
|
@@ -966,25 +989,25 @@ function atTimes(hours, opts) {
|
|
|
966
989
|
return atTime(timePhrase(hour, 0, null, opts));
|
|
967
990
|
});
|
|
968
991
|
}
|
|
969
|
-
function atHourTimes(
|
|
992
|
+
function atHourTimes(schedule, times, opts) {
|
|
970
993
|
if (times.kind === "fires") {
|
|
971
994
|
return groupClockTimesByArticle(atTimes(times.fires, opts));
|
|
972
995
|
}
|
|
973
|
-
return hourSegmentTimes(
|
|
996
|
+
return hourSegmentTimes(schedule, 0, null, opts);
|
|
974
997
|
}
|
|
975
|
-
function hourSpanFromTimes(
|
|
998
|
+
function hourSpanFromTimes(schedule, times, opts) {
|
|
976
999
|
if (times.kind === "fires" && times.fires.length > 3) {
|
|
977
1000
|
return "durante las horas " + hourSpanList(times.fires, opts);
|
|
978
1001
|
}
|
|
979
|
-
return hourWindowsFromTimes(
|
|
1002
|
+
return hourWindowsFromTimes(schedule, times, opts);
|
|
980
1003
|
}
|
|
981
|
-
function hourWindowsFromTimes(
|
|
1004
|
+
function hourWindowsFromTimes(schedule, times, opts) {
|
|
982
1005
|
if (times.kind === "fires") {
|
|
983
1006
|
return joinList(times.fires.map(function window(hour) {
|
|
984
1007
|
return hourAsWindow(hour, opts);
|
|
985
1008
|
}));
|
|
986
1009
|
}
|
|
987
|
-
return joinList(segmentsOf(
|
|
1010
|
+
return joinList(segmentsOf(schedule, "hour").map(function window(segment) {
|
|
988
1011
|
if (segment.kind === "range") {
|
|
989
1012
|
return timeRange(
|
|
990
1013
|
{ hour: +segment.bounds[0], minute: 0 },
|
|
@@ -1000,10 +1023,10 @@ function hourWindowsFromTimes(ir, times, opts) {
|
|
|
1000
1023
|
return hourAsWindow(+segment.value, opts);
|
|
1001
1024
|
}));
|
|
1002
1025
|
}
|
|
1003
|
-
function hourSegmentTimes(
|
|
1026
|
+
function hourSegmentTimes(schedule, minute, second, opts) {
|
|
1004
1027
|
const pieces = [];
|
|
1005
1028
|
const fromRange = [];
|
|
1006
|
-
segmentsOf(
|
|
1029
|
+
segmentsOf(schedule, "hour").forEach(function clock(segment) {
|
|
1007
1030
|
if (segment.kind === "step") {
|
|
1008
1031
|
segment.fires.forEach(function each(hour) {
|
|
1009
1032
|
pieces.push(atTime(timePhrase(hour, minute, second, opts)));
|
|
@@ -1115,47 +1138,47 @@ function dayPeriod(hour, opts) {
|
|
|
1115
1138
|
}
|
|
1116
1139
|
return "de la tarde";
|
|
1117
1140
|
}
|
|
1118
|
-
function leadingQualifier(
|
|
1119
|
-
const pattern =
|
|
1141
|
+
function leadingQualifier(schedule, opts) {
|
|
1142
|
+
const pattern = schedule.pattern;
|
|
1120
1143
|
if (pattern.date !== "*" && pattern.weekday !== "*") {
|
|
1121
1144
|
return "";
|
|
1122
1145
|
}
|
|
1123
1146
|
if (pattern.date !== "*") {
|
|
1124
|
-
return datePhrase(
|
|
1147
|
+
return datePhrase(schedule, opts) + " ";
|
|
1125
1148
|
}
|
|
1126
1149
|
if (pattern.weekday !== "*") {
|
|
1127
|
-
return weekdayQualifier(
|
|
1150
|
+
return weekdayQualifier(schedule) + monthScope(schedule) + " ";
|
|
1128
1151
|
}
|
|
1129
1152
|
if (pattern.month !== "*") {
|
|
1130
|
-
return "todos los d\xEDas " + monthPhrase(
|
|
1153
|
+
return "todos los d\xEDas " + monthPhrase(schedule, "de ") + " ";
|
|
1131
1154
|
}
|
|
1132
1155
|
return "todos los d\xEDas ";
|
|
1133
1156
|
}
|
|
1134
|
-
function trailingQualifier(
|
|
1135
|
-
const pattern =
|
|
1157
|
+
function trailingQualifier(schedule, opts) {
|
|
1158
|
+
const pattern = schedule.pattern;
|
|
1136
1159
|
if (pattern.date !== "*" && pattern.weekday !== "*") {
|
|
1137
1160
|
return "";
|
|
1138
1161
|
}
|
|
1139
1162
|
if (pattern.date !== "*") {
|
|
1140
|
-
return " " + datePhrase(
|
|
1163
|
+
return " " + datePhrase(schedule, opts);
|
|
1141
1164
|
}
|
|
1142
1165
|
if (pattern.weekday !== "*") {
|
|
1143
|
-
return " " + weekdayQualifier(
|
|
1166
|
+
return " " + weekdayQualifier(schedule) + monthScope(schedule);
|
|
1144
1167
|
}
|
|
1145
1168
|
if (pattern.month !== "*") {
|
|
1146
|
-
return " " + monthPhrase(
|
|
1169
|
+
return " " + monthPhrase(schedule, "en ");
|
|
1147
1170
|
}
|
|
1148
1171
|
return "";
|
|
1149
1172
|
}
|
|
1150
|
-
function datePhrase(
|
|
1151
|
-
const pattern =
|
|
1173
|
+
function datePhrase(schedule, opts) {
|
|
1174
|
+
const pattern = schedule.pattern;
|
|
1152
1175
|
if (quartzDatePhrase(pattern.date) || isOpenStep(pattern.date)) {
|
|
1153
|
-
return dateClause(
|
|
1176
|
+
return dateClause(schedule, "", opts) + monthScope(schedule);
|
|
1154
1177
|
}
|
|
1155
|
-
return dateClause(
|
|
1178
|
+
return dateClause(schedule, dateMonthPart(schedule), opts);
|
|
1156
1179
|
}
|
|
1157
|
-
function dateClause(
|
|
1158
|
-
const pattern =
|
|
1180
|
+
function dateClause(schedule, monthPart, opts) {
|
|
1181
|
+
const pattern = schedule.pattern;
|
|
1159
1182
|
const quartz = quartzDatePhrase(pattern.date);
|
|
1160
1183
|
if (quartz) {
|
|
1161
1184
|
return quartz;
|
|
@@ -1163,31 +1186,31 @@ function dateClause(ir, monthPart, opts) {
|
|
|
1163
1186
|
if (isOpenStep(pattern.date)) {
|
|
1164
1187
|
return stepDates(pattern.date, opts);
|
|
1165
1188
|
}
|
|
1166
|
-
const segments = segmentsOf(
|
|
1189
|
+
const segments = segmentsOf(schedule, "date");
|
|
1167
1190
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
1168
|
-
return "del " + segments[0].bounds[0] + " al " + segments[0].bounds[1] + monthPart + foldedYear(
|
|
1191
|
+
return "del " + segments[0].bounds[0] + " al " + segments[0].bounds[1] + monthPart + foldedYear(schedule);
|
|
1169
1192
|
}
|
|
1170
1193
|
if (segments.length === 1 && segments[0].kind === "single") {
|
|
1171
|
-
return "el " + segments[0].value + monthPart + foldedYear(
|
|
1194
|
+
return "el " + segments[0].value + monthPart + foldedYear(schedule);
|
|
1172
1195
|
}
|
|
1173
|
-
return "los d\xEDas " + joinList(segmentWords(segments)) + monthPart + foldedYear(
|
|
1196
|
+
return "los d\xEDas " + joinList(segmentWords(segments)) + monthPart + foldedYear(schedule);
|
|
1174
1197
|
}
|
|
1175
|
-
function monthRanged(
|
|
1176
|
-
return
|
|
1198
|
+
function monthRanged(schedule) {
|
|
1199
|
+
return schedule.pattern.month !== "*" && segmentsOf(schedule, "month").some(function range(segment) {
|
|
1177
1200
|
return segment.kind === "range";
|
|
1178
1201
|
});
|
|
1179
1202
|
}
|
|
1180
|
-
function dateMonthPart(
|
|
1181
|
-
if (
|
|
1203
|
+
function dateMonthPart(schedule) {
|
|
1204
|
+
if (schedule.pattern.month === "*") {
|
|
1182
1205
|
return " de cada mes";
|
|
1183
1206
|
}
|
|
1184
|
-
if (monthRanged(
|
|
1185
|
-
return " de cada mes, " + monthPhrase(
|
|
1207
|
+
if (monthRanged(schedule)) {
|
|
1208
|
+
return " de cada mes, " + monthPhrase(schedule, "de ");
|
|
1186
1209
|
}
|
|
1187
|
-
return " " + monthPhrase(
|
|
1210
|
+
return " " + monthPhrase(schedule, "de ");
|
|
1188
1211
|
}
|
|
1189
|
-
function foldedYear(
|
|
1190
|
-
const yearField =
|
|
1212
|
+
function foldedYear(schedule) {
|
|
1213
|
+
const yearField = schedule.pattern.year;
|
|
1191
1214
|
if (yearField === "*" || yearField.indexOf("/") !== -1 || yearField.indexOf("-") !== -1 || yearField.indexOf(",") !== -1) {
|
|
1192
1215
|
return "";
|
|
1193
1216
|
}
|
|
@@ -1218,12 +1241,12 @@ function quartzWeekdayPhrase(weekdayField) {
|
|
|
1218
1241
|
return "el \xFAltimo " + weekdayName(weekdayField.slice(0, -1)) + " del mes";
|
|
1219
1242
|
}
|
|
1220
1243
|
}
|
|
1221
|
-
function weekdayQualifier(
|
|
1222
|
-
const quartz = quartzWeekdayPhrase(
|
|
1244
|
+
function weekdayQualifier(schedule) {
|
|
1245
|
+
const quartz = quartzWeekdayPhrase(schedule.pattern.weekday);
|
|
1223
1246
|
if (quartz) {
|
|
1224
1247
|
return quartz;
|
|
1225
1248
|
}
|
|
1226
|
-
const segments = orderWeekdaysForDisplay(segmentsOf(
|
|
1249
|
+
const segments = orderWeekdaysForDisplay(segmentsOf(schedule, "weekday"));
|
|
1227
1250
|
const allSingles = segments.every(function single(segment) {
|
|
1228
1251
|
return segment.kind === "single";
|
|
1229
1252
|
});
|
|
@@ -1249,8 +1272,8 @@ function flattenSteps(segments) {
|
|
|
1249
1272
|
}) : [segment];
|
|
1250
1273
|
});
|
|
1251
1274
|
}
|
|
1252
|
-
function monthPhrase(
|
|
1253
|
-
const segments = flattenSteps(segmentsOf(
|
|
1275
|
+
function monthPhrase(schedule, lead) {
|
|
1276
|
+
const segments = flattenSteps(segmentsOf(schedule, "month"));
|
|
1254
1277
|
const ranged = segments.some(function range(segment) {
|
|
1255
1278
|
return segment.kind === "range";
|
|
1256
1279
|
});
|
|
@@ -1266,11 +1289,26 @@ function monthPhrase(ir, lead) {
|
|
|
1266
1289
|
return lead + monthName(segment.value);
|
|
1267
1290
|
}));
|
|
1268
1291
|
}
|
|
1269
|
-
function monthScope(
|
|
1270
|
-
if (
|
|
1292
|
+
function monthScope(schedule) {
|
|
1293
|
+
if (schedule.pattern.month === "*") {
|
|
1271
1294
|
return "";
|
|
1272
1295
|
}
|
|
1273
|
-
return (monthRanged(
|
|
1296
|
+
return (monthRanged(schedule) ? ", " : " ") + monthPhrase(schedule, "de ");
|
|
1297
|
+
}
|
|
1298
|
+
function parityDayPredicate(dateField) {
|
|
1299
|
+
if (!isOpenStep(dateField)) {
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
const [start, step] = dateField.split("/");
|
|
1303
|
+
if (+step !== 2) {
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
if (start === "*" || start === "1") {
|
|
1307
|
+
return "un d\xEDa impar del mes";
|
|
1308
|
+
}
|
|
1309
|
+
if (start === "2") {
|
|
1310
|
+
return "un d\xEDa par del mes";
|
|
1311
|
+
}
|
|
1274
1312
|
}
|
|
1275
1313
|
function stepDates(dateField, opts) {
|
|
1276
1314
|
const parts = dateField.split("/");
|
|
@@ -1280,15 +1318,15 @@ function stepDates(dateField, opts) {
|
|
|
1280
1318
|
}
|
|
1281
1319
|
return phrase;
|
|
1282
1320
|
}
|
|
1283
|
-
function applyYear(description,
|
|
1284
|
-
const yearField =
|
|
1321
|
+
function applyYear(description, schedule, opts) {
|
|
1322
|
+
const yearField = schedule.pattern.year;
|
|
1285
1323
|
if (yearField === "*") {
|
|
1286
1324
|
return description;
|
|
1287
1325
|
}
|
|
1288
1326
|
if (yearField.indexOf("/") !== -1) {
|
|
1289
1327
|
return description + " " + stepYears(yearField, opts);
|
|
1290
1328
|
}
|
|
1291
|
-
if (foldedYear(
|
|
1329
|
+
if (foldedYear(schedule) && schedule.pattern.date !== "*") {
|
|
1292
1330
|
return description;
|
|
1293
1331
|
}
|
|
1294
1332
|
if (yearField.indexOf(",") !== -1) {
|