cronli5 0.2.1 → 0.3.1
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 +65 -0
- 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 +308 -236
- package/dist/lang/zh.js +308 -236
- package/package.json +1 -1
- 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 +344 -237
- 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.js
CHANGED
|
@@ -31,6 +31,16 @@ function isNonNegativeInteger(value) {
|
|
|
31
31
|
const digits = /^\d+$/;
|
|
32
32
|
return digits.test(value);
|
|
33
33
|
}
|
|
34
|
+
function toFieldNumber(token, numberMap) {
|
|
35
|
+
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/core/shapes.ts
|
|
39
|
+
function isOpenStep(field) {
|
|
40
|
+
return field.indexOf("/") !== -1 && field.indexOf("-") === -1 && field.indexOf(",") === -1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/core/cadence.ts
|
|
34
44
|
function arithmeticStep(values) {
|
|
35
45
|
if (values.length < 5) {
|
|
36
46
|
return null;
|
|
@@ -46,34 +56,11 @@ function arithmeticStep(values) {
|
|
|
46
56
|
}
|
|
47
57
|
return { start: values[0], interval, last: values[values.length - 1] };
|
|
48
58
|
}
|
|
49
|
-
function
|
|
50
|
-
return
|
|
59
|
+
function segmentsOf(schedule, field) {
|
|
60
|
+
return schedule.analyses.segments[field] ?? [];
|
|
51
61
|
}
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
55
|
-
return { kind: "single", value: "" + value };
|
|
56
|
-
}) : [segment];
|
|
57
|
-
});
|
|
58
|
-
function key(segment) {
|
|
59
|
-
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
60
|
-
}
|
|
61
|
-
return flattened.map(function index(segment, position) {
|
|
62
|
-
return [segment, position];
|
|
63
|
-
}).sort(function byDisplayKey(a, b) {
|
|
64
|
-
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
65
|
-
}).map(function unwrap(pair) {
|
|
66
|
-
return pair[0];
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
function toFieldNumber(token, numberMap) {
|
|
70
|
-
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
71
|
-
}
|
|
72
|
-
function segmentsOf(ir, field) {
|
|
73
|
-
return ir.analyses.segments[field] ?? [];
|
|
74
|
-
}
|
|
75
|
-
function stepSegment(ir, field) {
|
|
76
|
-
return segmentsOf(ir, field)[0];
|
|
62
|
+
function stepSegment(schedule, field) {
|
|
63
|
+
return segmentsOf(schedule, field)[0];
|
|
77
64
|
}
|
|
78
65
|
function singleValues(segments) {
|
|
79
66
|
const values = [];
|
|
@@ -88,6 +75,17 @@ function singleValues(segments) {
|
|
|
88
75
|
function offsetCleanStride(stride) {
|
|
89
76
|
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
90
77
|
}
|
|
78
|
+
function renderStride(spec, parts) {
|
|
79
|
+
const { start, interval, cycle } = spec;
|
|
80
|
+
const tiles = cycle % interval === 0;
|
|
81
|
+
if (start === 0 && tiles) {
|
|
82
|
+
return parts.bare();
|
|
83
|
+
}
|
|
84
|
+
if (start < interval && tiles) {
|
|
85
|
+
return parts.offset();
|
|
86
|
+
}
|
|
87
|
+
return parts.bounded();
|
|
88
|
+
}
|
|
91
89
|
function hourListStride(values) {
|
|
92
90
|
if (values.length < 2) {
|
|
93
91
|
return null;
|
|
@@ -107,9 +105,26 @@ function hourListStride(values) {
|
|
|
107
105
|
return { interval, last: values[values.length - 1], start: values[0] };
|
|
108
106
|
}
|
|
109
107
|
|
|
110
|
-
// src/core/
|
|
111
|
-
function
|
|
112
|
-
return
|
|
108
|
+
// src/core/weekday.ts
|
|
109
|
+
function weekdayDisplayKey(value) {
|
|
110
|
+
return value === 0 ? 7 : value;
|
|
111
|
+
}
|
|
112
|
+
function orderWeekdaysForDisplay(segments) {
|
|
113
|
+
const flattened = segments.flatMap(function flat(segment) {
|
|
114
|
+
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
115
|
+
return { kind: "single", value: "" + value };
|
|
116
|
+
}) : [segment];
|
|
117
|
+
});
|
|
118
|
+
function key(segment) {
|
|
119
|
+
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
120
|
+
}
|
|
121
|
+
return flattened.map(function index(segment, position) {
|
|
122
|
+
return [segment, position];
|
|
123
|
+
}).sort(function byDisplayKey(a, b) {
|
|
124
|
+
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
125
|
+
}).map(function unwrap(pair) {
|
|
126
|
+
return pair[0];
|
|
127
|
+
});
|
|
113
128
|
}
|
|
114
129
|
|
|
115
130
|
// src/lang/es/dialects.ts
|
|
@@ -189,107 +204,107 @@ function normalizeOptions(options) {
|
|
|
189
204
|
years: !!options.years
|
|
190
205
|
};
|
|
191
206
|
}
|
|
192
|
-
function describe(
|
|
193
|
-
return applyYear(render(
|
|
207
|
+
function describe(schedule, opts) {
|
|
208
|
+
return applyYear(render(schedule, schedule.plan, opts), schedule, opts);
|
|
194
209
|
}
|
|
195
|
-
function render(
|
|
196
|
-
const phrase = renderers[plan.kind](
|
|
197
|
-
if (!isDateWeekdayUnion(
|
|
210
|
+
function render(schedule, plan, opts) {
|
|
211
|
+
const phrase = renderers[plan.kind](schedule, plan, opts);
|
|
212
|
+
if (!isDateWeekdayUnion(schedule)) {
|
|
198
213
|
return phrase;
|
|
199
214
|
}
|
|
200
|
-
const lead = unionMonthLeadFull(
|
|
201
|
-
return (lead ? lead + " " : "") + phrase + unionYaseaSuffix(
|
|
215
|
+
const lead = unionMonthLeadFull(schedule);
|
|
216
|
+
return (lead ? lead + " " : "") + phrase + unionYaseaSuffix(schedule, opts);
|
|
202
217
|
}
|
|
203
|
-
function renderEverySecond(
|
|
204
|
-
return "cada segundo" + trailingQualifier(
|
|
218
|
+
function renderEverySecond(schedule, plan, opts) {
|
|
219
|
+
return "cada segundo" + trailingQualifier(schedule, opts);
|
|
205
220
|
}
|
|
206
|
-
function renderStandaloneSeconds(
|
|
207
|
-
return secondsLeadClause(
|
|
221
|
+
function renderStandaloneSeconds(schedule, plan, opts) {
|
|
222
|
+
return secondsLeadClause(schedule, opts) + trailingQualifier(schedule, opts);
|
|
208
223
|
}
|
|
209
|
-
function renderSecondPastMinute(
|
|
210
|
-
return "en el segundo " +
|
|
224
|
+
function renderSecondPastMinute(schedule, plan, opts) {
|
|
225
|
+
return "en el segundo " + schedule.pattern.second + " de cada minuto" + trailingQualifier(schedule, opts);
|
|
211
226
|
}
|
|
212
|
-
function renderSecondsWithinMinute(
|
|
213
|
-
const minuteField =
|
|
227
|
+
function renderSecondsWithinMinute(schedule, plan, opts) {
|
|
228
|
+
const minuteField = schedule.pattern.minute;
|
|
214
229
|
if (plan.singleSecond) {
|
|
215
|
-
return "en el minuto " + minuteField + " y el segundo " +
|
|
230
|
+
return "en el minuto " + minuteField + " y el segundo " + schedule.pattern.second + " de cada hora" + trailingQualifier(schedule, opts);
|
|
216
231
|
}
|
|
217
|
-
return secondsLeadClause(
|
|
232
|
+
return secondsLeadClause(schedule, opts) + ", en el minuto " + minuteField + " de cada hora" + trailingQualifier(schedule, opts);
|
|
218
233
|
}
|
|
219
|
-
function secondsListAtClock(
|
|
234
|
+
function secondsListAtClock(schedule, rest, opts) {
|
|
220
235
|
const clockPhrases = rest.times.map(function clock(time) {
|
|
221
236
|
return atTime(timePhrase(time.hour, time.minute, null, opts));
|
|
222
237
|
});
|
|
223
238
|
const grouped = groupClockTimesByArticle(clockPhrases);
|
|
224
239
|
const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
|
|
225
|
-
const stride = strideFromSegments(segmentsOf(
|
|
226
|
-
const secondsPhrase = stride ?? "en los segundos " + joinList(segmentWords(segmentsOf(
|
|
227
|
-
const dayFrame = trailingQualifier(
|
|
240
|
+
const stride = strideFromSegments(segmentsOf(schedule, "second"), "segundo", "", opts);
|
|
241
|
+
const secondsPhrase = stride ?? "en los segundos " + joinList(segmentWords(segmentsOf(schedule, "second")));
|
|
242
|
+
const dayFrame = trailingQualifier(schedule, opts);
|
|
228
243
|
return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
|
|
229
244
|
}
|
|
230
|
-
function composeHourCadence(
|
|
245
|
+
function composeHourCadence(schedule, plan, opts) {
|
|
231
246
|
const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
|
|
232
|
-
if (!clockRest ||
|
|
247
|
+
if (!clockRest || schedule.shapes.minute !== "single") {
|
|
233
248
|
return null;
|
|
234
249
|
}
|
|
235
|
-
const minute = +
|
|
236
|
-
return hourCadence(
|
|
250
|
+
const minute = +schedule.pattern.minute;
|
|
251
|
+
return hourCadence(schedule, minute, opts) ?? hourRangeCadence(schedule, minute, opts);
|
|
237
252
|
}
|
|
238
|
-
function isPinnedMinuteSeconds(
|
|
239
|
-
return plan.rest.kind === "clockTimes" && (
|
|
253
|
+
function isPinnedMinuteSeconds(schedule, plan) {
|
|
254
|
+
return plan.rest.kind === "clockTimes" && (schedule.shapes.second === "wildcard" || schedule.shapes.second === "step");
|
|
240
255
|
}
|
|
241
|
-
function renderComposeSeconds(
|
|
242
|
-
const hourCad = composeHourCadence(
|
|
256
|
+
function renderComposeSeconds(schedule, plan, opts) {
|
|
257
|
+
const hourCad = composeHourCadence(schedule, plan, opts);
|
|
243
258
|
if (hourCad !== null) {
|
|
244
259
|
return hourCad;
|
|
245
260
|
}
|
|
246
|
-
if (isPinnedMinuteSeconds(
|
|
247
|
-
return pinnedMinuteSeconds(
|
|
261
|
+
if (isPinnedMinuteSeconds(schedule, plan)) {
|
|
262
|
+
return pinnedMinuteSeconds(schedule, plan.rest, opts);
|
|
248
263
|
}
|
|
249
|
-
if (plan.rest.kind === "clockTimes" &&
|
|
250
|
-
return secondsListAtClock(
|
|
264
|
+
if (plan.rest.kind === "clockTimes" && schedule.shapes.second === "list") {
|
|
265
|
+
return secondsListAtClock(schedule, plan.rest, opts);
|
|
251
266
|
}
|
|
252
|
-
if (plan.rest.kind === "hourRange" &&
|
|
267
|
+
if (plan.rest.kind === "hourRange" && schedule.shapes.second === "step" && schedule.pattern.weekday !== "*") {
|
|
253
268
|
const restNode = plan.rest;
|
|
254
269
|
const window = hourWindow(boundedWindow(restNode), opts);
|
|
255
|
-
const dayFrame = weekdayQualifier(
|
|
256
|
-
const cadence = "cada " + numero(stepSegment(
|
|
270
|
+
const dayFrame = weekdayQualifier(schedule) + monthScope(schedule);
|
|
271
|
+
const cadence = "cada " + numero(stepSegment(schedule, "second").interval, opts) + " segundos del minuto " + schedule.pattern.minute;
|
|
257
272
|
return dayFrame + ", " + window + ", " + cadence;
|
|
258
273
|
}
|
|
259
|
-
if (isEveryOtherMinuteSeconds(
|
|
260
|
-
return secondsLeadClause(
|
|
274
|
+
if (isEveryOtherMinuteSeconds(schedule, plan)) {
|
|
275
|
+
return secondsLeadClause(schedule, opts) + " de " + render(schedule, plan.rest, opts);
|
|
261
276
|
}
|
|
262
|
-
const restOwnsLead = plan.rest.kind === "compactClockTimes" &&
|
|
263
|
-
const lead = restOwnsLead ? "" : secondsLeadClause(
|
|
264
|
-
return lead + render(
|
|
277
|
+
const restOwnsLead = plan.rest.kind === "compactClockTimes" && schedule.analyses.clockSecond;
|
|
278
|
+
const lead = restOwnsLead ? "" : secondsLeadClause(schedule, opts) + ", ";
|
|
279
|
+
return lead + render(schedule, plan.rest, opts);
|
|
265
280
|
}
|
|
266
|
-
function isEveryOtherMinuteSeconds(
|
|
267
|
-
if (plan.rest.kind !== "minuteFrequency" ||
|
|
281
|
+
function isEveryOtherMinuteSeconds(schedule, plan) {
|
|
282
|
+
if (plan.rest.kind !== "minuteFrequency" || schedule.shapes.second !== "wildcard" || schedule.shapes.hour !== "wildcard") {
|
|
268
283
|
return false;
|
|
269
284
|
}
|
|
270
|
-
const minuteStep = stepSegment(
|
|
285
|
+
const minuteStep = stepSegment(schedule, "minute");
|
|
271
286
|
return minuteStep.startToken === "*" && minuteStep.interval === 2;
|
|
272
287
|
}
|
|
273
|
-
function pinnedMinuteSeconds(
|
|
274
|
-
const dayTrail = leadingQualifier(
|
|
288
|
+
function pinnedMinuteSeconds(schedule, rest, opts) {
|
|
289
|
+
const dayTrail = leadingQualifier(schedule, opts).trimEnd();
|
|
275
290
|
const trail = dayTrail ? ", " + dayTrail : "";
|
|
276
|
-
if (+rest.times[0].minute === 0 &&
|
|
277
|
-
return secondsLeadClause(
|
|
291
|
+
if (+rest.times[0].minute === 0 && schedule.shapes.minute === "single") {
|
|
292
|
+
return secondsLeadClause(schedule, opts) + " durante un minuto " + durationHourList(rest.times, opts) + trail;
|
|
278
293
|
}
|
|
279
|
-
return secondsLeadClause(
|
|
294
|
+
return secondsLeadClause(schedule, opts) + " de " + explicitClockList(rest.times, opts) + trail;
|
|
280
295
|
}
|
|
281
|
-
function secondsLeadClause(
|
|
282
|
-
return secondsClause(
|
|
296
|
+
function secondsLeadClause(schedule, opts) {
|
|
297
|
+
return secondsClause(schedule, "minuto", opts);
|
|
283
298
|
}
|
|
284
|
-
function secondsClause(
|
|
285
|
-
const secondField =
|
|
286
|
-
const shape =
|
|
299
|
+
function secondsClause(schedule, anchor, opts) {
|
|
300
|
+
const secondField = schedule.pattern.second;
|
|
301
|
+
const shape = schedule.shapes.second;
|
|
287
302
|
if (secondField === "*") {
|
|
288
303
|
return "cada segundo";
|
|
289
304
|
}
|
|
290
305
|
if (shape === "step") {
|
|
291
306
|
return stepCycle60(
|
|
292
|
-
stepSegment(
|
|
307
|
+
stepSegment(schedule, "second"),
|
|
293
308
|
"segundo",
|
|
294
309
|
anchor,
|
|
295
310
|
opts
|
|
@@ -303,31 +318,31 @@ function secondsClause(ir, anchor, opts) {
|
|
|
303
318
|
return "en el segundo " + secondField + " de cada " + anchor;
|
|
304
319
|
}
|
|
305
320
|
return strideFromSegments(
|
|
306
|
-
segmentsOf(
|
|
321
|
+
segmentsOf(schedule, "second"),
|
|
307
322
|
"segundo",
|
|
308
323
|
anchor,
|
|
309
324
|
opts
|
|
310
|
-
) ?? "en los segundos " + joinList(segmentWords(segmentsOf(
|
|
325
|
+
) ?? "en los segundos " + joinList(segmentWords(segmentsOf(schedule, "second"))) + " de cada " + anchor;
|
|
311
326
|
}
|
|
312
|
-
function renderEveryMinute(
|
|
313
|
-
return "cada minuto" + trailingQualifier(
|
|
327
|
+
function renderEveryMinute(schedule, plan, opts) {
|
|
328
|
+
return "cada minuto" + trailingQualifier(schedule, opts);
|
|
314
329
|
}
|
|
315
|
-
function renderSingleMinute(
|
|
316
|
-
return "en el minuto " +
|
|
330
|
+
function renderSingleMinute(schedule, plan, opts) {
|
|
331
|
+
return "en el minuto " + schedule.pattern.minute + " de cada hora" + trailingQualifier(schedule, opts);
|
|
317
332
|
}
|
|
318
|
-
function renderRangeOfMinutes(
|
|
319
|
-
return minuteRangeLead(
|
|
333
|
+
function renderRangeOfMinutes(schedule, plan, opts) {
|
|
334
|
+
return minuteRangeLead(schedule.pattern.minute) + " de cada hora" + trailingQualifier(schedule, opts);
|
|
320
335
|
}
|
|
321
|
-
function renderMultipleMinutes(
|
|
322
|
-
return minutesList(
|
|
336
|
+
function renderMultipleMinutes(schedule, plan, opts) {
|
|
337
|
+
return minutesList(schedule, opts) + trailingQualifier(schedule, opts);
|
|
323
338
|
}
|
|
324
|
-
function minutesList(
|
|
339
|
+
function minutesList(schedule, opts) {
|
|
325
340
|
return strideFromSegments(
|
|
326
|
-
segmentsOf(
|
|
341
|
+
segmentsOf(schedule, "minute"),
|
|
327
342
|
"minuto",
|
|
328
343
|
"hora",
|
|
329
344
|
opts
|
|
330
|
-
) ?? "en los minutos " + joinList(segmentWords(segmentsOf(
|
|
345
|
+
) ?? "en los minutos " + joinList(segmentWords(segmentsOf(schedule, "minute"))) + " de cada hora";
|
|
331
346
|
}
|
|
332
347
|
function minuteRangeLead(minuteField) {
|
|
333
348
|
const bounds = minuteField.split("-");
|
|
@@ -382,86 +397,86 @@ function spanHours(hours) {
|
|
|
382
397
|
return (hour === 1 ? "la " : "las ") + hour;
|
|
383
398
|
}));
|
|
384
399
|
}
|
|
385
|
-
function renderMinuteFrequency(
|
|
400
|
+
function renderMinuteFrequency(schedule, plan, opts) {
|
|
386
401
|
let phrase = stepCycle60(
|
|
387
|
-
stepSegment(
|
|
402
|
+
stepSegment(schedule, "minute"),
|
|
388
403
|
"minuto",
|
|
389
404
|
"hora",
|
|
390
405
|
opts
|
|
391
406
|
);
|
|
392
407
|
if (plan.hours.kind === "during") {
|
|
393
|
-
const cadence = unevenHourCadence(
|
|
408
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
394
409
|
if (cadence) {
|
|
395
410
|
phrase += ", " + cadence;
|
|
396
411
|
} else {
|
|
397
|
-
phrase += singleHourStep(
|
|
412
|
+
phrase += singleHourStep(schedule.analyses.segments.hour) ? ", " + stepHourSpan(stepSegment(schedule, "hour"), opts) : " " + hourSpanFromTimes(schedule, plan.hours.times, opts);
|
|
398
413
|
}
|
|
399
414
|
} else if (plan.hours.kind === "window") {
|
|
400
415
|
phrase += " " + hourWindow(plan.hours, opts);
|
|
401
416
|
} else if (plan.hours.kind === "step") {
|
|
402
|
-
phrase += ", " + stepHourSpan(stepSegment(
|
|
417
|
+
phrase += ", " + stepHourSpan(stepSegment(schedule, "hour"), opts);
|
|
403
418
|
}
|
|
404
|
-
return phrase + trailingQualifier(
|
|
419
|
+
return phrase + trailingQualifier(schedule, opts);
|
|
405
420
|
}
|
|
406
|
-
function renderMinuteSpanInHour(
|
|
407
|
-
if (
|
|
408
|
-
return "cada minuto de la hora " + fromTime(timePhrase(plan.hour, 0, null, opts)) + trailingQualifier(
|
|
421
|
+
function renderMinuteSpanInHour(schedule, plan, opts) {
|
|
422
|
+
if (schedule.pattern.minute === "*") {
|
|
423
|
+
return "cada minuto de la hora " + fromTime(timePhrase(plan.hour, 0, null, opts)) + trailingQualifier(schedule, opts);
|
|
409
424
|
}
|
|
410
425
|
return "cada minuto " + timeRange(
|
|
411
426
|
{ hour: plan.hour, minute: plan.span[0] },
|
|
412
427
|
{ hour: plan.hour, minute: plan.span[1] },
|
|
413
428
|
opts
|
|
414
|
-
) + trailingQualifier(
|
|
429
|
+
) + trailingQualifier(schedule, opts);
|
|
415
430
|
}
|
|
416
|
-
function renderMinutesAcrossHours(
|
|
417
|
-
const cadence = unevenHourCadence(
|
|
431
|
+
function renderMinutesAcrossHours(schedule, plan, opts) {
|
|
432
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
418
433
|
if (plan.form === "wildcard") {
|
|
419
434
|
if (cadence !== null) {
|
|
420
|
-
return "cada minuto, " + cadence + trailingQualifier(
|
|
435
|
+
return "cada minuto, " + cadence + trailingQualifier(schedule, opts);
|
|
421
436
|
}
|
|
422
|
-
if (singleHourStep(
|
|
423
|
-
return "cada minuto, " + stepHourSpan(stepSegment(
|
|
437
|
+
if (singleHourStep(schedule.analyses.segments.hour)) {
|
|
438
|
+
return "cada minuto, " + stepHourSpan(stepSegment(schedule, "hour"), opts) + trailingQualifier(schedule, opts);
|
|
424
439
|
}
|
|
425
|
-
return "cada minuto " + hourSpanFromTimes(
|
|
440
|
+
return "cada minuto " + hourSpanFromTimes(schedule, plan.times, opts) + trailingQualifier(schedule, opts);
|
|
426
441
|
}
|
|
427
|
-
const lead = plan.form === "range" ? minuteRangeLead(
|
|
442
|
+
const lead = plan.form === "range" ? minuteRangeLead(schedule.pattern.minute) : minutesList(schedule, opts);
|
|
428
443
|
if (cadence !== null) {
|
|
429
|
-
return lead + ", " + cadence + trailingQualifier(
|
|
444
|
+
return lead + ", " + cadence + trailingQualifier(schedule, opts);
|
|
430
445
|
}
|
|
431
|
-
return lead + ", " + atHourTimes(
|
|
446
|
+
return lead + ", " + atHourTimes(schedule, plan.times, opts) + trailingQualifier(schedule, opts);
|
|
432
447
|
}
|
|
433
|
-
function renderMinuteSpanAcrossHourStep(
|
|
434
|
-
const segment = stepSegment(
|
|
435
|
-
const cadence = unevenHourCadence(
|
|
448
|
+
function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
|
|
449
|
+
const segment = stepSegment(schedule, "hour");
|
|
450
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
436
451
|
if (plan.form === "wildcard") {
|
|
437
|
-
return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(
|
|
452
|
+
return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(schedule, opts);
|
|
438
453
|
}
|
|
439
|
-
const lead = plan.form === "list" ? minutesList(
|
|
440
|
-
return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(
|
|
454
|
+
const lead = plan.form === "list" ? minutesList(schedule, opts) : minuteRangeLead(schedule.pattern.minute);
|
|
455
|
+
return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(schedule, opts);
|
|
441
456
|
}
|
|
442
|
-
function renderEveryHour(
|
|
443
|
-
return "cada hora" + trailingQualifier(
|
|
457
|
+
function renderEveryHour(schedule, plan, opts) {
|
|
458
|
+
return "cada hora" + trailingQualifier(schedule, opts);
|
|
444
459
|
}
|
|
445
|
-
function renderHourRange(
|
|
460
|
+
function renderHourRange(schedule, plan, opts) {
|
|
446
461
|
const window = hourWindow(boundedWindow(plan), opts);
|
|
447
462
|
if (plan.minuteForm === "wildcard") {
|
|
448
|
-
return "cada minuto " + window + trailingQualifier(
|
|
463
|
+
return "cada minuto " + window + trailingQualifier(schedule, opts);
|
|
449
464
|
}
|
|
450
465
|
if (plan.minuteForm === "range") {
|
|
451
|
-
return minuteRangeLead(
|
|
466
|
+
return minuteRangeLead(schedule.pattern.minute) + ", " + window + trailingQualifier(schedule, opts);
|
|
452
467
|
}
|
|
453
|
-
if (
|
|
454
|
-
return "cada hora " + window + trailingQualifier(
|
|
468
|
+
if (schedule.pattern.minute === "0") {
|
|
469
|
+
return "cada hora " + window + trailingQualifier(schedule, opts);
|
|
455
470
|
}
|
|
456
|
-
const lead =
|
|
457
|
-
return lead + ", " + window + trailingQualifier(
|
|
471
|
+
const lead = schedule.shapes.minute === "single" ? "en el minuto " + schedule.pattern.minute + " de cada hora" : minutesList(schedule, opts);
|
|
472
|
+
return lead + ", " + window + trailingQualifier(schedule, opts);
|
|
458
473
|
}
|
|
459
|
-
function renderHourStep(
|
|
460
|
-
const cadence = unevenHourCadence(
|
|
474
|
+
function renderHourStep(schedule, plan, opts) {
|
|
475
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
461
476
|
if (cadence !== null) {
|
|
462
|
-
return cadence + trailingQualifier(
|
|
477
|
+
return cadence + trailingQualifier(schedule, opts);
|
|
463
478
|
}
|
|
464
|
-
return stepHours(stepSegment(
|
|
479
|
+
return stepHours(stepSegment(schedule, "hour"), opts) + trailingQualifier(schedule, opts);
|
|
465
480
|
}
|
|
466
481
|
function boundedWindow(plan) {
|
|
467
482
|
const last = plan.minuteForm === "wildcard" ? plan.boundMinute ?? 0 : 0;
|
|
@@ -474,42 +489,46 @@ function hourWindow(window, opts) {
|
|
|
474
489
|
opts
|
|
475
490
|
);
|
|
476
491
|
}
|
|
477
|
-
function isDateWeekdayUnion(
|
|
478
|
-
return
|
|
492
|
+
function isDateWeekdayUnion(schedule) {
|
|
493
|
+
return schedule.pattern.date !== "*" && schedule.pattern.weekday !== "*";
|
|
479
494
|
}
|
|
480
|
-
function unionMonthLeadFull(
|
|
481
|
-
if (
|
|
495
|
+
function unionMonthLeadFull(schedule) {
|
|
496
|
+
if (schedule.pattern.month === "*") {
|
|
482
497
|
return "";
|
|
483
498
|
}
|
|
484
|
-
const lead = monthPhrase(
|
|
485
|
-
const segments = flattenSteps(segmentsOf(
|
|
486
|
-
const isEnumeration = !monthRanged(
|
|
499
|
+
const lead = monthPhrase(schedule, monthRanged(schedule) ? "de " : "en ");
|
|
500
|
+
const segments = flattenSteps(segmentsOf(schedule, "month"));
|
|
501
|
+
const isEnumeration = !monthRanged(schedule) && segments.length >= 2;
|
|
487
502
|
return isEnumeration ? lead + "," : lead;
|
|
488
503
|
}
|
|
489
|
-
function domArm(
|
|
490
|
-
const date =
|
|
504
|
+
function domArm(schedule, opts) {
|
|
505
|
+
const date = schedule.pattern.date;
|
|
491
506
|
const quartz = quartzDatePhrase(date);
|
|
492
507
|
if (quartz) {
|
|
493
508
|
return quartz;
|
|
494
509
|
}
|
|
510
|
+
const parity = parityDayPredicate(date);
|
|
511
|
+
if (parity) {
|
|
512
|
+
return parity;
|
|
513
|
+
}
|
|
495
514
|
if (isOpenStep(date)) {
|
|
496
515
|
return stepDates(date, opts);
|
|
497
516
|
}
|
|
498
|
-
const segments = segmentsOf(
|
|
517
|
+
const segments = segmentsOf(schedule, "date");
|
|
499
518
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
500
519
|
return "del " + segments[0].bounds[0] + " al " + segments[0].bounds[1] + " del mes";
|
|
501
520
|
}
|
|
502
521
|
if (segments.length === 1 && segments[0].kind === "single") {
|
|
503
|
-
return
|
|
522
|
+
return schedule.pattern.month === "*" ? "el " + segments[0].value + " de cada mes" : "el d\xEDa " + segments[0].value;
|
|
504
523
|
}
|
|
505
524
|
return "los d\xEDas " + joinList(segmentWords(segments)) + " del mes";
|
|
506
525
|
}
|
|
507
|
-
function dowArm(
|
|
508
|
-
const quartz = quartzWeekdayPhrase(
|
|
526
|
+
function dowArm(schedule) {
|
|
527
|
+
const quartz = quartzWeekdayPhrase(schedule.pattern.weekday);
|
|
509
528
|
if (quartz) {
|
|
510
529
|
return quartz;
|
|
511
530
|
}
|
|
512
|
-
const segments = orderWeekdaysForDisplay(segmentsOf(
|
|
531
|
+
const segments = orderWeekdaysForDisplay(segmentsOf(schedule, "weekday"));
|
|
513
532
|
const allSingles = segments.every(function single(segment) {
|
|
514
533
|
return segment.kind === "single";
|
|
515
534
|
});
|
|
@@ -522,19 +541,19 @@ function dowArm(ir) {
|
|
|
522
541
|
}));
|
|
523
542
|
}
|
|
524
543
|
if (segments.length === 1) {
|
|
525
|
-
return weekdayRange(segments[0]);
|
|
544
|
+
return "cualquier d\xEDa " + weekdayRange(segments[0]);
|
|
526
545
|
}
|
|
527
546
|
return joinList(segments.map(function name(segment) {
|
|
528
547
|
return segment.kind === "range" ? weekdayRange(segment) : "los " + pluralWeekday(segment.value);
|
|
529
548
|
}));
|
|
530
549
|
}
|
|
531
|
-
function unionYaseaSuffix(
|
|
532
|
-
return ", ya sea " + domArm(
|
|
550
|
+
function unionYaseaSuffix(schedule, opts) {
|
|
551
|
+
return ", ya sea " + domArm(schedule, opts) + " o " + dowArm(schedule);
|
|
533
552
|
}
|
|
534
|
-
function renderClockTimes(
|
|
535
|
-
if (
|
|
536
|
-
const minute = +
|
|
537
|
-
const cadence = hourCadence(
|
|
553
|
+
function renderClockTimes(schedule, plan, opts) {
|
|
554
|
+
if (schedule.shapes.minute === "single") {
|
|
555
|
+
const minute = +schedule.pattern.minute;
|
|
556
|
+
const cadence = hourCadence(schedule, minute, opts) ?? hourRangeCadence(schedule, minute, opts);
|
|
538
557
|
if (cadence !== null) {
|
|
539
558
|
return cadence;
|
|
540
559
|
}
|
|
@@ -542,7 +561,7 @@ function renderClockTimes(ir, plan, opts) {
|
|
|
542
561
|
const phrases = plan.times.map(function clock(time) {
|
|
543
562
|
return atTime(timePhrase(time.hour, time.minute, time.second, opts));
|
|
544
563
|
});
|
|
545
|
-
return leadingQualifier(
|
|
564
|
+
return leadingQualifier(schedule, opts) + groupClockTimes(phrases);
|
|
546
565
|
}
|
|
547
566
|
function explicitClockList(times, opts) {
|
|
548
567
|
const phrases = times.map(function clock(time) {
|
|
@@ -718,23 +737,33 @@ function groupClockTimesByArticle(phrases) {
|
|
|
718
737
|
const connector = doubleY ? ", " : " y ";
|
|
719
738
|
return laPart + connector + lasPart;
|
|
720
739
|
}
|
|
721
|
-
function renderCompactClockTimes(
|
|
740
|
+
function renderCompactClockTimes(schedule, plan, opts) {
|
|
722
741
|
if (plan.fold) {
|
|
723
|
-
const cadence2 = hourCadence(
|
|
742
|
+
const cadence2 = hourCadence(schedule, plan.minute, opts) ?? hourRangeCadence(schedule, plan.minute, opts);
|
|
724
743
|
if (cadence2 !== null) {
|
|
725
744
|
return cadence2;
|
|
726
745
|
}
|
|
727
|
-
const ranged = segmentsOf(
|
|
746
|
+
const ranged = segmentsOf(schedule, "hour").some(function range(segment) {
|
|
728
747
|
return segment.kind === "range";
|
|
729
748
|
});
|
|
730
|
-
if (ranged && !
|
|
731
|
-
return "cada hora " + hourSegmentTimes(
|
|
749
|
+
if (ranged && !schedule.analyses.clockSecond) {
|
|
750
|
+
return "cada hora " + hourSegmentTimes(
|
|
751
|
+
schedule,
|
|
752
|
+
plan.minute,
|
|
753
|
+
schedule.analyses.clockSecond,
|
|
754
|
+
opts
|
|
755
|
+
) + trailingQualifier(schedule, opts);
|
|
732
756
|
}
|
|
733
|
-
return leadingQualifier(
|
|
757
|
+
return leadingQualifier(schedule, opts) + hourSegmentTimes(
|
|
758
|
+
schedule,
|
|
759
|
+
plan.minute,
|
|
760
|
+
schedule.analyses.clockSecond,
|
|
761
|
+
opts
|
|
762
|
+
);
|
|
734
763
|
}
|
|
735
|
-
const cadence = unevenHourCadence(
|
|
736
|
-
const phrase = cadence ? minutesList(
|
|
737
|
-
return
|
|
764
|
+
const cadence = unevenHourCadence(schedule, opts);
|
|
765
|
+
const phrase = cadence ? minutesList(schedule, opts) + ", " + cadence + trailingQualifier(schedule, opts) : minutesList(schedule, opts) + ", " + hourContextTimes(schedule, opts) + trailingQualifier(schedule, opts);
|
|
766
|
+
return schedule.analyses.clockSecond ? secondsLeadClause(schedule, opts) + ", " + phrase : phrase;
|
|
738
767
|
}
|
|
739
768
|
var renderers = {
|
|
740
769
|
clockTimes: renderClockTimes,
|
|
@@ -756,18 +785,15 @@ var renderers = {
|
|
|
756
785
|
singleMinute: renderSingleMinute,
|
|
757
786
|
standaloneSeconds: renderStandaloneSeconds
|
|
758
787
|
};
|
|
759
|
-
function
|
|
788
|
+
function renderStride2(stride, opts) {
|
|
760
789
|
const { interval, start, last, cycle, unit, anchor } = stride;
|
|
761
790
|
const cadence = "cada " + numero(interval, opts) + " " + unit + "s";
|
|
762
|
-
const tiles = cycle % interval === 0;
|
|
763
|
-
if (start === 0 && tiles) {
|
|
764
|
-
return cadence;
|
|
765
|
-
}
|
|
766
791
|
const tail = anchor ? " de cada " + anchor : "";
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
792
|
+
return renderStride({ start, interval, cycle }, {
|
|
793
|
+
bare: () => cadence,
|
|
794
|
+
offset: () => cadence + " a partir del " + unit + " " + start + tail,
|
|
795
|
+
bounded: () => cadence + " del " + unit + " " + start + " al " + last + tail
|
|
796
|
+
});
|
|
771
797
|
}
|
|
772
798
|
function stepCycle60(segment, unit, anchor, opts) {
|
|
773
799
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
@@ -777,7 +803,7 @@ function stepCycle60(segment, unit, anchor, opts) {
|
|
|
777
803
|
if (start !== 0 && segment.fires.length <= 3) {
|
|
778
804
|
return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
|
|
779
805
|
}
|
|
780
|
-
return
|
|
806
|
+
return renderStride2({
|
|
781
807
|
interval: segment.interval,
|
|
782
808
|
start,
|
|
783
809
|
last: segment.fires[segment.fires.length - 1],
|
|
@@ -789,7 +815,7 @@ function stepCycle60(segment, unit, anchor, opts) {
|
|
|
789
815
|
function strideFromSegments(segments, unit, anchor, opts) {
|
|
790
816
|
const values = singleValues(segments);
|
|
791
817
|
const step = values && arithmeticStep(values);
|
|
792
|
-
return step ?
|
|
818
|
+
return step ? renderStride2({ ...step, cycle: 60, unit, anchor }, opts) : null;
|
|
793
819
|
}
|
|
794
820
|
function stepHours(segment, opts) {
|
|
795
821
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
@@ -808,24 +834,21 @@ function stepHours(segment, opts) {
|
|
|
808
834
|
function hourStrideCadence(stride, opts) {
|
|
809
835
|
const { start, interval, last } = stride;
|
|
810
836
|
const cadence = "cada " + numero(interval, opts) + " horas";
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
return cadence + " a partir de " + timePhrase(start, 0, null, opts);
|
|
817
|
-
}
|
|
818
|
-
return cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts);
|
|
837
|
+
return renderStride({ start, interval, cycle: 24 }, {
|
|
838
|
+
bare: () => cadence,
|
|
839
|
+
offset: () => cadence + " a partir de " + timePhrase(start, 0, null, opts),
|
|
840
|
+
bounded: () => cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts)
|
|
841
|
+
});
|
|
819
842
|
}
|
|
820
|
-
function unevenHourCadence(
|
|
821
|
-
const stride = hourStride(
|
|
843
|
+
function unevenHourCadence(schedule, opts) {
|
|
844
|
+
const stride = hourStride(schedule);
|
|
822
845
|
if (!stride || offsetCleanStride(stride)) {
|
|
823
846
|
return null;
|
|
824
847
|
}
|
|
825
848
|
return hourStrideCadence(stride, opts);
|
|
826
849
|
}
|
|
827
|
-
function hourStride(
|
|
828
|
-
const segments = segmentsOf(
|
|
850
|
+
function hourStride(schedule) {
|
|
851
|
+
const segments = segmentsOf(schedule, "hour");
|
|
829
852
|
if (segments.length === 1 && segments[0].kind === "step") {
|
|
830
853
|
const segment = segments[0];
|
|
831
854
|
if (segment.fires.length < 2) {
|
|
@@ -837,64 +860,64 @@ function hourStride(ir) {
|
|
|
837
860
|
const values = singleValues(segments);
|
|
838
861
|
return values && hourListStride(values);
|
|
839
862
|
}
|
|
840
|
-
function subMinuteSecond(
|
|
841
|
-
return
|
|
863
|
+
function subMinuteSecond(schedule) {
|
|
864
|
+
return schedule.pattern.second === "*" || schedule.shapes.second === "step";
|
|
842
865
|
}
|
|
843
|
-
function hourCadenceLead(
|
|
866
|
+
function hourCadenceLead(schedule, minute, opts) {
|
|
844
867
|
if (minute === 0) {
|
|
845
|
-
if (subMinuteSecond(
|
|
846
|
-
return secondsClause(
|
|
868
|
+
if (subMinuteSecond(schedule)) {
|
|
869
|
+
return secondsClause(schedule, "minuto", opts) + " durante un minuto";
|
|
847
870
|
}
|
|
848
|
-
return secondsClause(
|
|
871
|
+
return secondsClause(schedule, "hora", opts);
|
|
849
872
|
}
|
|
850
873
|
const minutePhrase = "en el minuto " + minute;
|
|
851
|
-
if (
|
|
874
|
+
if (schedule.pattern.second === "0") {
|
|
852
875
|
return minutePhrase;
|
|
853
876
|
}
|
|
854
|
-
return secondsClause(
|
|
877
|
+
return secondsClause(schedule, "minuto", opts) + ", " + minutePhrase;
|
|
855
878
|
}
|
|
856
|
-
function hourCadence(
|
|
857
|
-
const stride = hourStride(
|
|
879
|
+
function hourCadence(schedule, minute, opts) {
|
|
880
|
+
const stride = hourStride(schedule);
|
|
858
881
|
if (!stride) {
|
|
859
882
|
return null;
|
|
860
883
|
}
|
|
861
884
|
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
862
|
-
if (
|
|
885
|
+
if (schedule.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
|
|
863
886
|
return null;
|
|
864
887
|
}
|
|
865
|
-
const confinement = minute === 0 && subMinuteSecond(
|
|
888
|
+
const confinement = minute === 0 && subMinuteSecond(schedule) && cleanStrideSegment(schedule);
|
|
866
889
|
if (confinement) {
|
|
867
|
-
return secondsClause(
|
|
890
|
+
return secondsClause(schedule, "minuto", opts) + " durante un minuto, " + stepHourSpan(confinement, opts) + trailingQualifier(schedule, opts);
|
|
868
891
|
}
|
|
869
|
-
if (minute === 0 &&
|
|
870
|
-
return hourStrideCadence(stride, opts) + trailingQualifier(
|
|
892
|
+
if (minute === 0 && schedule.pattern.second === "0") {
|
|
893
|
+
return hourStrideCadence(stride, opts) + trailingQualifier(schedule, opts);
|
|
871
894
|
}
|
|
872
|
-
return hourCadenceLead(
|
|
895
|
+
return hourCadenceLead(schedule, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(schedule, opts);
|
|
873
896
|
}
|
|
874
|
-
function cleanStrideSegment(
|
|
875
|
-
const segments = segmentsOf(
|
|
897
|
+
function cleanStrideSegment(schedule) {
|
|
898
|
+
const segments = segmentsOf(schedule, "hour");
|
|
876
899
|
const segment = segments.length === 1 && segments[0];
|
|
877
900
|
if (!segment || segment.kind !== "step" || segment.startToken.indexOf("-") !== -1) {
|
|
878
901
|
return null;
|
|
879
902
|
}
|
|
880
903
|
return segment;
|
|
881
904
|
}
|
|
882
|
-
function hasHourWindow(
|
|
883
|
-
return segmentsOf(
|
|
905
|
+
function hasHourWindow(schedule) {
|
|
906
|
+
return segmentsOf(schedule, "hour").some(function range(segment) {
|
|
884
907
|
return segment.kind === "range";
|
|
885
908
|
});
|
|
886
909
|
}
|
|
887
|
-
function hourRangeCadence(
|
|
888
|
-
if (minute !== 0 || !hasHourWindow(
|
|
910
|
+
function hourRangeCadence(schedule, minute, opts) {
|
|
911
|
+
if (minute !== 0 || !hasHourWindow(schedule) || schedule.pattern.second === "0") {
|
|
889
912
|
return null;
|
|
890
913
|
}
|
|
891
|
-
if (subMinuteSecond(
|
|
892
|
-
return secondsClause(
|
|
914
|
+
if (subMinuteSecond(schedule)) {
|
|
915
|
+
return secondsClause(schedule, "minuto", opts) + " durante un minuto, durante las horas " + hourSegmentTimes(schedule, 0, null, opts) + trailingQualifier(schedule, opts);
|
|
893
916
|
}
|
|
894
|
-
return hourCadenceLead(
|
|
917
|
+
return hourCadenceLead(schedule, minute, opts) + ", " + hourSegmentTimes(schedule, 0, null, opts) + trailingQualifier(schedule, opts);
|
|
895
918
|
}
|
|
896
|
-
function hourContextTimes(
|
|
897
|
-
const segments = segmentsOf(
|
|
919
|
+
function hourContextTimes(schedule, opts) {
|
|
920
|
+
const segments = segmentsOf(schedule, "hour");
|
|
898
921
|
const points = [];
|
|
899
922
|
const hasRange = segments.some(function range(segment) {
|
|
900
923
|
return segment.kind === "range";
|
|
@@ -940,25 +963,25 @@ function atTimes(hours, opts) {
|
|
|
940
963
|
return atTime(timePhrase(hour, 0, null, opts));
|
|
941
964
|
});
|
|
942
965
|
}
|
|
943
|
-
function atHourTimes(
|
|
966
|
+
function atHourTimes(schedule, times, opts) {
|
|
944
967
|
if (times.kind === "fires") {
|
|
945
968
|
return groupClockTimesByArticle(atTimes(times.fires, opts));
|
|
946
969
|
}
|
|
947
|
-
return hourSegmentTimes(
|
|
970
|
+
return hourSegmentTimes(schedule, 0, null, opts);
|
|
948
971
|
}
|
|
949
|
-
function hourSpanFromTimes(
|
|
972
|
+
function hourSpanFromTimes(schedule, times, opts) {
|
|
950
973
|
if (times.kind === "fires" && times.fires.length > 3) {
|
|
951
974
|
return "durante las horas " + hourSpanList(times.fires, opts);
|
|
952
975
|
}
|
|
953
|
-
return hourWindowsFromTimes(
|
|
976
|
+
return hourWindowsFromTimes(schedule, times, opts);
|
|
954
977
|
}
|
|
955
|
-
function hourWindowsFromTimes(
|
|
978
|
+
function hourWindowsFromTimes(schedule, times, opts) {
|
|
956
979
|
if (times.kind === "fires") {
|
|
957
980
|
return joinList(times.fires.map(function window(hour) {
|
|
958
981
|
return hourAsWindow(hour, opts);
|
|
959
982
|
}));
|
|
960
983
|
}
|
|
961
|
-
return joinList(segmentsOf(
|
|
984
|
+
return joinList(segmentsOf(schedule, "hour").map(function window(segment) {
|
|
962
985
|
if (segment.kind === "range") {
|
|
963
986
|
return timeRange(
|
|
964
987
|
{ hour: +segment.bounds[0], minute: 0 },
|
|
@@ -974,10 +997,10 @@ function hourWindowsFromTimes(ir, times, opts) {
|
|
|
974
997
|
return hourAsWindow(+segment.value, opts);
|
|
975
998
|
}));
|
|
976
999
|
}
|
|
977
|
-
function hourSegmentTimes(
|
|
1000
|
+
function hourSegmentTimes(schedule, minute, second, opts) {
|
|
978
1001
|
const pieces = [];
|
|
979
1002
|
const fromRange = [];
|
|
980
|
-
segmentsOf(
|
|
1003
|
+
segmentsOf(schedule, "hour").forEach(function clock(segment) {
|
|
981
1004
|
if (segment.kind === "step") {
|
|
982
1005
|
segment.fires.forEach(function each(hour) {
|
|
983
1006
|
pieces.push(atTime(timePhrase(hour, minute, second, opts)));
|
|
@@ -1089,47 +1112,47 @@ function dayPeriod(hour, opts) {
|
|
|
1089
1112
|
}
|
|
1090
1113
|
return "de la tarde";
|
|
1091
1114
|
}
|
|
1092
|
-
function leadingQualifier(
|
|
1093
|
-
const pattern =
|
|
1115
|
+
function leadingQualifier(schedule, opts) {
|
|
1116
|
+
const pattern = schedule.pattern;
|
|
1094
1117
|
if (pattern.date !== "*" && pattern.weekday !== "*") {
|
|
1095
1118
|
return "";
|
|
1096
1119
|
}
|
|
1097
1120
|
if (pattern.date !== "*") {
|
|
1098
|
-
return datePhrase(
|
|
1121
|
+
return datePhrase(schedule, opts) + " ";
|
|
1099
1122
|
}
|
|
1100
1123
|
if (pattern.weekday !== "*") {
|
|
1101
|
-
return weekdayQualifier(
|
|
1124
|
+
return weekdayQualifier(schedule) + monthScope(schedule) + " ";
|
|
1102
1125
|
}
|
|
1103
1126
|
if (pattern.month !== "*") {
|
|
1104
|
-
return "todos los d\xEDas " + monthPhrase(
|
|
1127
|
+
return "todos los d\xEDas " + monthPhrase(schedule, "de ") + " ";
|
|
1105
1128
|
}
|
|
1106
1129
|
return "todos los d\xEDas ";
|
|
1107
1130
|
}
|
|
1108
|
-
function trailingQualifier(
|
|
1109
|
-
const pattern =
|
|
1131
|
+
function trailingQualifier(schedule, opts) {
|
|
1132
|
+
const pattern = schedule.pattern;
|
|
1110
1133
|
if (pattern.date !== "*" && pattern.weekday !== "*") {
|
|
1111
1134
|
return "";
|
|
1112
1135
|
}
|
|
1113
1136
|
if (pattern.date !== "*") {
|
|
1114
|
-
return " " + datePhrase(
|
|
1137
|
+
return " " + datePhrase(schedule, opts);
|
|
1115
1138
|
}
|
|
1116
1139
|
if (pattern.weekday !== "*") {
|
|
1117
|
-
return " " + weekdayQualifier(
|
|
1140
|
+
return " " + weekdayQualifier(schedule) + monthScope(schedule);
|
|
1118
1141
|
}
|
|
1119
1142
|
if (pattern.month !== "*") {
|
|
1120
|
-
return " " + monthPhrase(
|
|
1143
|
+
return " " + monthPhrase(schedule, "en ");
|
|
1121
1144
|
}
|
|
1122
1145
|
return "";
|
|
1123
1146
|
}
|
|
1124
|
-
function datePhrase(
|
|
1125
|
-
const pattern =
|
|
1147
|
+
function datePhrase(schedule, opts) {
|
|
1148
|
+
const pattern = schedule.pattern;
|
|
1126
1149
|
if (quartzDatePhrase(pattern.date) || isOpenStep(pattern.date)) {
|
|
1127
|
-
return dateClause(
|
|
1150
|
+
return dateClause(schedule, "", opts) + monthScope(schedule);
|
|
1128
1151
|
}
|
|
1129
|
-
return dateClause(
|
|
1152
|
+
return dateClause(schedule, dateMonthPart(schedule), opts);
|
|
1130
1153
|
}
|
|
1131
|
-
function dateClause(
|
|
1132
|
-
const pattern =
|
|
1154
|
+
function dateClause(schedule, monthPart, opts) {
|
|
1155
|
+
const pattern = schedule.pattern;
|
|
1133
1156
|
const quartz = quartzDatePhrase(pattern.date);
|
|
1134
1157
|
if (quartz) {
|
|
1135
1158
|
return quartz;
|
|
@@ -1137,31 +1160,31 @@ function dateClause(ir, monthPart, opts) {
|
|
|
1137
1160
|
if (isOpenStep(pattern.date)) {
|
|
1138
1161
|
return stepDates(pattern.date, opts);
|
|
1139
1162
|
}
|
|
1140
|
-
const segments = segmentsOf(
|
|
1163
|
+
const segments = segmentsOf(schedule, "date");
|
|
1141
1164
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
1142
|
-
return "del " + segments[0].bounds[0] + " al " + segments[0].bounds[1] + monthPart + foldedYear(
|
|
1165
|
+
return "del " + segments[0].bounds[0] + " al " + segments[0].bounds[1] + monthPart + foldedYear(schedule);
|
|
1143
1166
|
}
|
|
1144
1167
|
if (segments.length === 1 && segments[0].kind === "single") {
|
|
1145
|
-
return "el " + segments[0].value + monthPart + foldedYear(
|
|
1168
|
+
return "el " + segments[0].value + monthPart + foldedYear(schedule);
|
|
1146
1169
|
}
|
|
1147
|
-
return "los d\xEDas " + joinList(segmentWords(segments)) + monthPart + foldedYear(
|
|
1170
|
+
return "los d\xEDas " + joinList(segmentWords(segments)) + monthPart + foldedYear(schedule);
|
|
1148
1171
|
}
|
|
1149
|
-
function monthRanged(
|
|
1150
|
-
return
|
|
1172
|
+
function monthRanged(schedule) {
|
|
1173
|
+
return schedule.pattern.month !== "*" && segmentsOf(schedule, "month").some(function range(segment) {
|
|
1151
1174
|
return segment.kind === "range";
|
|
1152
1175
|
});
|
|
1153
1176
|
}
|
|
1154
|
-
function dateMonthPart(
|
|
1155
|
-
if (
|
|
1177
|
+
function dateMonthPart(schedule) {
|
|
1178
|
+
if (schedule.pattern.month === "*") {
|
|
1156
1179
|
return " de cada mes";
|
|
1157
1180
|
}
|
|
1158
|
-
if (monthRanged(
|
|
1159
|
-
return " de cada mes, " + monthPhrase(
|
|
1181
|
+
if (monthRanged(schedule)) {
|
|
1182
|
+
return " de cada mes, " + monthPhrase(schedule, "de ");
|
|
1160
1183
|
}
|
|
1161
|
-
return " " + monthPhrase(
|
|
1184
|
+
return " " + monthPhrase(schedule, "de ");
|
|
1162
1185
|
}
|
|
1163
|
-
function foldedYear(
|
|
1164
|
-
const yearField =
|
|
1186
|
+
function foldedYear(schedule) {
|
|
1187
|
+
const yearField = schedule.pattern.year;
|
|
1165
1188
|
if (yearField === "*" || yearField.indexOf("/") !== -1 || yearField.indexOf("-") !== -1 || yearField.indexOf(",") !== -1) {
|
|
1166
1189
|
return "";
|
|
1167
1190
|
}
|
|
@@ -1192,12 +1215,12 @@ function quartzWeekdayPhrase(weekdayField) {
|
|
|
1192
1215
|
return "el \xFAltimo " + weekdayName(weekdayField.slice(0, -1)) + " del mes";
|
|
1193
1216
|
}
|
|
1194
1217
|
}
|
|
1195
|
-
function weekdayQualifier(
|
|
1196
|
-
const quartz = quartzWeekdayPhrase(
|
|
1218
|
+
function weekdayQualifier(schedule) {
|
|
1219
|
+
const quartz = quartzWeekdayPhrase(schedule.pattern.weekday);
|
|
1197
1220
|
if (quartz) {
|
|
1198
1221
|
return quartz;
|
|
1199
1222
|
}
|
|
1200
|
-
const segments = orderWeekdaysForDisplay(segmentsOf(
|
|
1223
|
+
const segments = orderWeekdaysForDisplay(segmentsOf(schedule, "weekday"));
|
|
1201
1224
|
const allSingles = segments.every(function single(segment) {
|
|
1202
1225
|
return segment.kind === "single";
|
|
1203
1226
|
});
|
|
@@ -1223,8 +1246,8 @@ function flattenSteps(segments) {
|
|
|
1223
1246
|
}) : [segment];
|
|
1224
1247
|
});
|
|
1225
1248
|
}
|
|
1226
|
-
function monthPhrase(
|
|
1227
|
-
const segments = flattenSteps(segmentsOf(
|
|
1249
|
+
function monthPhrase(schedule, lead) {
|
|
1250
|
+
const segments = flattenSteps(segmentsOf(schedule, "month"));
|
|
1228
1251
|
const ranged = segments.some(function range(segment) {
|
|
1229
1252
|
return segment.kind === "range";
|
|
1230
1253
|
});
|
|
@@ -1240,11 +1263,26 @@ function monthPhrase(ir, lead) {
|
|
|
1240
1263
|
return lead + monthName(segment.value);
|
|
1241
1264
|
}));
|
|
1242
1265
|
}
|
|
1243
|
-
function monthScope(
|
|
1244
|
-
if (
|
|
1266
|
+
function monthScope(schedule) {
|
|
1267
|
+
if (schedule.pattern.month === "*") {
|
|
1245
1268
|
return "";
|
|
1246
1269
|
}
|
|
1247
|
-
return (monthRanged(
|
|
1270
|
+
return (monthRanged(schedule) ? ", " : " ") + monthPhrase(schedule, "de ");
|
|
1271
|
+
}
|
|
1272
|
+
function parityDayPredicate(dateField) {
|
|
1273
|
+
if (!isOpenStep(dateField)) {
|
|
1274
|
+
return;
|
|
1275
|
+
}
|
|
1276
|
+
const [start, step] = dateField.split("/");
|
|
1277
|
+
if (+step !== 2) {
|
|
1278
|
+
return;
|
|
1279
|
+
}
|
|
1280
|
+
if (start === "*" || start === "1") {
|
|
1281
|
+
return "un d\xEDa impar del mes";
|
|
1282
|
+
}
|
|
1283
|
+
if (start === "2") {
|
|
1284
|
+
return "un d\xEDa par del mes";
|
|
1285
|
+
}
|
|
1248
1286
|
}
|
|
1249
1287
|
function stepDates(dateField, opts) {
|
|
1250
1288
|
const parts = dateField.split("/");
|
|
@@ -1254,15 +1292,15 @@ function stepDates(dateField, opts) {
|
|
|
1254
1292
|
}
|
|
1255
1293
|
return phrase;
|
|
1256
1294
|
}
|
|
1257
|
-
function applyYear(description,
|
|
1258
|
-
const yearField =
|
|
1295
|
+
function applyYear(description, schedule, opts) {
|
|
1296
|
+
const yearField = schedule.pattern.year;
|
|
1259
1297
|
if (yearField === "*") {
|
|
1260
1298
|
return description;
|
|
1261
1299
|
}
|
|
1262
1300
|
if (yearField.indexOf("/") !== -1) {
|
|
1263
1301
|
return description + " " + stepYears(yearField, opts);
|
|
1264
1302
|
}
|
|
1265
|
-
if (foldedYear(
|
|
1303
|
+
if (foldedYear(schedule) && schedule.pattern.date !== "*") {
|
|
1266
1304
|
return description;
|
|
1267
1305
|
}
|
|
1268
1306
|
if (yearField.indexOf(",") !== -1) {
|