cronli5 0.1.4 → 0.1.5
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 +25 -0
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +180 -36
- package/dist/cronli5.js +180 -36
- package/dist/lang/de.cjs +172 -8
- package/dist/lang/de.js +172 -8
- package/dist/lang/en.cjs +175 -29
- package/dist/lang/en.js +175 -29
- package/dist/lang/es.cjs +180 -25
- package/dist/lang/es.js +180 -25
- package/dist/lang/fi.cjs +188 -40
- package/dist/lang/fi.js +188 -40
- package/dist/lang/zh.cjs +165 -19
- package/dist/lang/zh.js +165 -19
- package/package.json +2 -1
- package/src/core/analyze.ts +7 -0
- package/src/core/ir.ts +1 -1
- package/src/core/util.ts +31 -1
- package/src/lang/de/index.ts +360 -16
- package/src/lang/en/index.ts +333 -33
- package/src/lang/es/index.ts +373 -40
- package/src/lang/fi/index.ts +404 -72
- package/src/lang/zh/index.ts +327 -35
- package/types/core/ir.d.ts +1 -1
- package/types/core/util.d.ts +6 -1
package/dist/lang/es.js
CHANGED
|
@@ -24,12 +24,28 @@ var weekdayNumbers = {
|
|
|
24
24
|
FRI: 5,
|
|
25
25
|
SAT: 6
|
|
26
26
|
};
|
|
27
|
+
var maxClockTimes = 6;
|
|
27
28
|
|
|
28
29
|
// src/core/util.ts
|
|
29
30
|
function isNonNegativeInteger(value) {
|
|
30
31
|
const digits = /^\d+$/;
|
|
31
32
|
return digits.test(value);
|
|
32
33
|
}
|
|
34
|
+
function arithmeticStep(values) {
|
|
35
|
+
if (values.length < 5) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const interval = values[1] - values[0];
|
|
39
|
+
if (interval < 2) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
43
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { start: values[0], interval, last: values[values.length - 1] };
|
|
48
|
+
}
|
|
33
49
|
function toFieldNumber(token, numberMap) {
|
|
34
50
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
35
51
|
}
|
|
@@ -147,19 +163,31 @@ function renderSecondsWithinMinute(ir, plan, opts) {
|
|
|
147
163
|
}
|
|
148
164
|
return secondsLeadClause(ir, opts) + ", en el minuto " + minuteField + " de cada hora" + trailingQualifier(ir, opts);
|
|
149
165
|
}
|
|
166
|
+
function secondsListAtClock(ir, rest, opts) {
|
|
167
|
+
const clockPhrases = rest.times.map(function clock(time) {
|
|
168
|
+
return atTime(timePhrase(time.hour, time.minute, null, opts));
|
|
169
|
+
});
|
|
170
|
+
const grouped = groupClockTimesByArticle(clockPhrases);
|
|
171
|
+
const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
|
|
172
|
+
const stride = strideFromSegments(fieldSegments(ir, "second"), "segundo", "", opts);
|
|
173
|
+
const secondsPhrase = stride ?? "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second")));
|
|
174
|
+
const dayFrame = trailingQualifier(ir, opts);
|
|
175
|
+
return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
|
|
176
|
+
}
|
|
177
|
+
function composeHourCadence(ir, plan, opts) {
|
|
178
|
+
const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
|
|
179
|
+
return clockRest && ir.shapes.minute === "single" ? hourCadence(ir, +ir.pattern.minute, opts) : null;
|
|
180
|
+
}
|
|
150
181
|
function renderComposeSeconds(ir, plan, opts) {
|
|
182
|
+
const hourCad = composeHourCadence(ir, plan, opts);
|
|
183
|
+
if (hourCad !== null) {
|
|
184
|
+
return hourCad;
|
|
185
|
+
}
|
|
151
186
|
if (plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step")) {
|
|
152
187
|
return pinnedMinuteSeconds(ir, plan.rest, opts);
|
|
153
188
|
}
|
|
154
189
|
if (plan.rest.kind === "clockTimes" && ir.shapes.second === "list") {
|
|
155
|
-
|
|
156
|
-
return atTime(timePhrase(time.hour, time.minute, null, opts));
|
|
157
|
-
});
|
|
158
|
-
const grouped = groupClockTimesByArticle(clockPhrases);
|
|
159
|
-
const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
|
|
160
|
-
const secondsPhrase = "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second")));
|
|
161
|
-
const dayFrame = trailingQualifier(ir, opts);
|
|
162
|
-
return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
|
|
190
|
+
return secondsListAtClock(ir, plan.rest, opts);
|
|
163
191
|
}
|
|
164
192
|
if (plan.rest.kind === "hourRange" && ir.shapes.second === "step" && ir.pattern.weekday !== "*") {
|
|
165
193
|
const restNode = plan.rest;
|
|
@@ -168,8 +196,18 @@ function renderComposeSeconds(ir, plan, opts) {
|
|
|
168
196
|
const cadence = "cada " + numero(stepSegment(ir.analyses.segments.second).interval, opts) + " segundos del minuto " + ir.pattern.minute;
|
|
169
197
|
return dayFrame + ", " + window + ", " + cadence;
|
|
170
198
|
}
|
|
199
|
+
if (isEveryOtherMinuteSeconds(ir, plan)) {
|
|
200
|
+
return secondsLeadClause(ir, opts) + " de " + render(ir, plan.rest, opts);
|
|
201
|
+
}
|
|
171
202
|
return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
|
|
172
203
|
}
|
|
204
|
+
function isEveryOtherMinuteSeconds(ir, plan) {
|
|
205
|
+
if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
const minuteStep = stepSegment(ir.analyses.segments.minute);
|
|
209
|
+
return minuteStep.startToken === "*" && minuteStep.interval === 2;
|
|
210
|
+
}
|
|
173
211
|
function pinnedMinuteSeconds(ir, rest, opts) {
|
|
174
212
|
const dayTrail = leadingQualifier(ir, opts).trimEnd();
|
|
175
213
|
const trail = dayTrail ? ", " + dayTrail : "";
|
|
@@ -179,6 +217,9 @@ function pinnedMinuteSeconds(ir, rest, opts) {
|
|
|
179
217
|
return secondsLeadClause(ir, opts) + " de " + explicitClockList(rest.times, opts) + trail;
|
|
180
218
|
}
|
|
181
219
|
function secondsLeadClause(ir, opts) {
|
|
220
|
+
return secondsClause(ir, "minuto", opts);
|
|
221
|
+
}
|
|
222
|
+
function secondsClause(ir, anchor, opts) {
|
|
182
223
|
const secondField = ir.pattern.second;
|
|
183
224
|
const shape = ir.shapes.second;
|
|
184
225
|
if (secondField === "*") {
|
|
@@ -188,18 +229,23 @@ function secondsLeadClause(ir, opts) {
|
|
|
188
229
|
return stepCycle60(
|
|
189
230
|
stepSegment(ir.analyses.segments.second),
|
|
190
231
|
"segundo",
|
|
191
|
-
|
|
232
|
+
anchor,
|
|
192
233
|
opts
|
|
193
234
|
);
|
|
194
235
|
}
|
|
195
236
|
if (shape === "range") {
|
|
196
237
|
const bounds = secondField.split("-");
|
|
197
|
-
return "cada segundo del " + bounds[0] + " al " + bounds[1] + " de cada
|
|
238
|
+
return "cada segundo del " + bounds[0] + " al " + bounds[1] + " de cada " + anchor;
|
|
198
239
|
}
|
|
199
240
|
if (shape === "single") {
|
|
200
|
-
return "en el segundo " + secondField + " de cada
|
|
241
|
+
return "en el segundo " + secondField + " de cada " + anchor;
|
|
201
242
|
}
|
|
202
|
-
return
|
|
243
|
+
return strideFromSegments(
|
|
244
|
+
fieldSegments(ir, "second"),
|
|
245
|
+
"segundo",
|
|
246
|
+
anchor,
|
|
247
|
+
opts
|
|
248
|
+
) ?? "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second"))) + " de cada " + anchor;
|
|
203
249
|
}
|
|
204
250
|
function renderEveryMinute(ir, plan, opts) {
|
|
205
251
|
return "cada minuto" + trailingQualifier(ir, opts);
|
|
@@ -211,10 +257,15 @@ function renderRangeOfMinutes(ir, plan, opts) {
|
|
|
211
257
|
return minuteRangeLead(ir.pattern.minute) + " de cada hora" + trailingQualifier(ir, opts);
|
|
212
258
|
}
|
|
213
259
|
function renderMultipleMinutes(ir, plan, opts) {
|
|
214
|
-
return minutesList(ir) + trailingQualifier(ir, opts);
|
|
260
|
+
return minutesList(ir, opts) + trailingQualifier(ir, opts);
|
|
215
261
|
}
|
|
216
|
-
function minutesList(ir) {
|
|
217
|
-
return
|
|
262
|
+
function minutesList(ir, opts) {
|
|
263
|
+
return strideFromSegments(
|
|
264
|
+
fieldSegments(ir, "minute"),
|
|
265
|
+
"minuto",
|
|
266
|
+
"hora",
|
|
267
|
+
opts
|
|
268
|
+
) ?? "en los minutos " + joinList(segmentWords(fieldSegments(ir, "minute"))) + " de cada hora";
|
|
218
269
|
}
|
|
219
270
|
function minuteRangeLead(minuteField) {
|
|
220
271
|
const bounds = minuteField.split("-");
|
|
@@ -302,7 +353,7 @@ function renderMinutesAcrossHours(ir, plan, opts) {
|
|
|
302
353
|
}
|
|
303
354
|
return "cada minuto " + hourSpanFromTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
304
355
|
}
|
|
305
|
-
const lead = plan.form === "range" ? minuteRangeLead(ir.pattern.minute) : minutesList(ir);
|
|
356
|
+
const lead = plan.form === "range" ? minuteRangeLead(ir.pattern.minute) : minutesList(ir, opts);
|
|
306
357
|
return lead + ", " + atHourTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
307
358
|
}
|
|
308
359
|
function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
@@ -310,7 +361,8 @@ function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
|
310
361
|
if (plan.form === "wildcard") {
|
|
311
362
|
return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(ir, opts);
|
|
312
363
|
}
|
|
313
|
-
|
|
364
|
+
const lead = plan.form === "list" ? minutesList(ir, opts) : minuteRangeLead(ir.pattern.minute);
|
|
365
|
+
return lead + ", " + stepHours(segment, opts) + trailingQualifier(ir, opts);
|
|
314
366
|
}
|
|
315
367
|
function renderEveryHour(ir, plan, opts) {
|
|
316
368
|
return "cada hora" + trailingQualifier(ir, opts);
|
|
@@ -326,7 +378,7 @@ function renderHourRange(ir, plan, opts) {
|
|
|
326
378
|
if (ir.pattern.minute === "0") {
|
|
327
379
|
return "cada hora " + window + trailingQualifier(ir, opts);
|
|
328
380
|
}
|
|
329
|
-
const lead = ir.shapes.minute === "single" ? "en el minuto " + ir.pattern.minute + " de cada hora" : minutesList(ir);
|
|
381
|
+
const lead = ir.shapes.minute === "single" ? "en el minuto " + ir.pattern.minute + " de cada hora" : minutesList(ir, opts);
|
|
330
382
|
return lead + ", " + window + trailingQualifier(ir, opts);
|
|
331
383
|
}
|
|
332
384
|
function renderHourStep(ir, plan, opts) {
|
|
@@ -400,6 +452,12 @@ function unionYaseaSuffix(ir, opts) {
|
|
|
400
452
|
return ", ya sea " + domArm(ir, opts) + " o " + dowArm(ir);
|
|
401
453
|
}
|
|
402
454
|
function renderClockTimes(ir, plan, opts) {
|
|
455
|
+
if (ir.shapes.minute === "single") {
|
|
456
|
+
const cadence = hourCadence(ir, +ir.pattern.minute, opts);
|
|
457
|
+
if (cadence !== null) {
|
|
458
|
+
return cadence;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
403
461
|
const phrases = plan.times.map(function clock(time) {
|
|
404
462
|
return atTime(timePhrase(time.hour, time.minute, time.second, opts));
|
|
405
463
|
});
|
|
@@ -581,6 +639,10 @@ function groupClockTimesByArticle(phrases) {
|
|
|
581
639
|
}
|
|
582
640
|
function renderCompactClockTimes(ir, plan, opts) {
|
|
583
641
|
if (plan.fold) {
|
|
642
|
+
const cadence = hourCadence(ir, plan.minute, opts);
|
|
643
|
+
if (cadence !== null) {
|
|
644
|
+
return cadence;
|
|
645
|
+
}
|
|
584
646
|
const ranged = hourSegments(ir).some(function range(segment) {
|
|
585
647
|
return segment.kind === "range";
|
|
586
648
|
});
|
|
@@ -589,7 +651,7 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
589
651
|
}
|
|
590
652
|
return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
|
|
591
653
|
}
|
|
592
|
-
const phrase = minutesList(ir) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
654
|
+
const phrase = minutesList(ir, opts) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
593
655
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
|
|
594
656
|
}
|
|
595
657
|
var renderers = {
|
|
@@ -612,19 +674,50 @@ var renderers = {
|
|
|
612
674
|
singleMinute: renderSingleMinute,
|
|
613
675
|
standaloneSeconds: renderStandaloneSeconds
|
|
614
676
|
};
|
|
677
|
+
function renderStride(stride, opts) {
|
|
678
|
+
const { interval, start, last, cycle, unit, anchor } = stride;
|
|
679
|
+
const cadence = "cada " + numero(interval, opts) + " " + unit + "s";
|
|
680
|
+
const tiles = cycle % interval === 0;
|
|
681
|
+
if (start === 0 && tiles) {
|
|
682
|
+
return cadence;
|
|
683
|
+
}
|
|
684
|
+
const tail = anchor ? " de cada " + anchor : "";
|
|
685
|
+
if (start < interval && tiles) {
|
|
686
|
+
return cadence + " a partir del " + unit + " " + start + tail;
|
|
687
|
+
}
|
|
688
|
+
return cadence + " del " + unit + " " + start + " al " + last + tail;
|
|
689
|
+
}
|
|
615
690
|
function stepCycle60(segment, unit, anchor, opts) {
|
|
616
691
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
617
692
|
return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
|
|
618
693
|
}
|
|
619
694
|
const start = segment.startToken === "*" ? 0 : +segment.startToken;
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
695
|
+
if (start !== 0 && segment.fires.length <= 3) {
|
|
696
|
+
return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
|
|
697
|
+
}
|
|
698
|
+
return renderStride({
|
|
699
|
+
interval: segment.interval,
|
|
700
|
+
start,
|
|
701
|
+
last: segment.fires[segment.fires.length - 1],
|
|
702
|
+
cycle: 60,
|
|
703
|
+
unit,
|
|
704
|
+
anchor
|
|
705
|
+
}, opts);
|
|
706
|
+
}
|
|
707
|
+
function strideFromSegments(segments, unit, anchor, opts) {
|
|
708
|
+
const values = singleValues(segments);
|
|
709
|
+
const step = values && arithmeticStep(values);
|
|
710
|
+
return step ? renderStride({ ...step, cycle: 60, unit, anchor }, opts) : null;
|
|
711
|
+
}
|
|
712
|
+
function singleValues(segments) {
|
|
713
|
+
const values = [];
|
|
714
|
+
for (const segment of segments) {
|
|
715
|
+
if (segment.kind !== "single") {
|
|
716
|
+
return null;
|
|
624
717
|
}
|
|
625
|
-
|
|
718
|
+
values.push(+segment.value);
|
|
626
719
|
}
|
|
627
|
-
return
|
|
720
|
+
return values;
|
|
628
721
|
}
|
|
629
722
|
function stepHours(segment, opts) {
|
|
630
723
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
@@ -640,6 +733,68 @@ function stepHours(segment, opts) {
|
|
|
640
733
|
}
|
|
641
734
|
return "cada " + numero(interval, opts) + " horas a partir de " + timePhrase(start, 0, null, opts);
|
|
642
735
|
}
|
|
736
|
+
function hourStrideCadence(stride, opts) {
|
|
737
|
+
const { start, interval, last } = stride;
|
|
738
|
+
const cadence = "cada " + numero(interval, opts) + " horas";
|
|
739
|
+
const tiles = 24 % interval === 0;
|
|
740
|
+
if (start === 0 && tiles) {
|
|
741
|
+
return cadence;
|
|
742
|
+
}
|
|
743
|
+
if (start < interval && tiles) {
|
|
744
|
+
return cadence + " a partir de " + timePhrase(start, 0, null, opts);
|
|
745
|
+
}
|
|
746
|
+
return cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts);
|
|
747
|
+
}
|
|
748
|
+
function hourStride(ir) {
|
|
749
|
+
const segments = fieldSegments(ir, "hour");
|
|
750
|
+
if (segments.length === 1 && segments[0].kind === "step") {
|
|
751
|
+
const segment = segments[0];
|
|
752
|
+
const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
|
|
753
|
+
return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
|
|
754
|
+
}
|
|
755
|
+
const values = singleValues(segments);
|
|
756
|
+
const step = values && arithmeticStep(values);
|
|
757
|
+
return step || null;
|
|
758
|
+
}
|
|
759
|
+
function subMinuteSecond(ir) {
|
|
760
|
+
return ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
761
|
+
}
|
|
762
|
+
function hourCadenceLead(ir, minute, opts) {
|
|
763
|
+
if (minute === 0) {
|
|
764
|
+
if (subMinuteSecond(ir)) {
|
|
765
|
+
return secondsClause(ir, "minuto", opts) + " durante un minuto";
|
|
766
|
+
}
|
|
767
|
+
return secondsClause(ir, "hora", opts);
|
|
768
|
+
}
|
|
769
|
+
const minutePhrase = "en el minuto " + minute;
|
|
770
|
+
if (ir.pattern.second === "0") {
|
|
771
|
+
return minutePhrase;
|
|
772
|
+
}
|
|
773
|
+
return secondsClause(ir, "minuto", opts) + ", " + minutePhrase;
|
|
774
|
+
}
|
|
775
|
+
function hourCadence(ir, minute, opts) {
|
|
776
|
+
const stride = hourStride(ir);
|
|
777
|
+
if (!stride) {
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
780
|
+
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
781
|
+
if (ir.pattern.second === "0" && fires <= maxClockTimes) {
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
const confinement = minute === 0 && subMinuteSecond(ir) && cleanStrideSegment(ir);
|
|
785
|
+
if (confinement) {
|
|
786
|
+
return secondsClause(ir, "minuto", opts) + " durante un minuto, " + stepHourSpan(confinement, opts) + trailingQualifier(ir, opts);
|
|
787
|
+
}
|
|
788
|
+
return hourCadenceLead(ir, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
|
|
789
|
+
}
|
|
790
|
+
function cleanStrideSegment(ir) {
|
|
791
|
+
const segments = fieldSegments(ir, "hour");
|
|
792
|
+
const segment = segments.length === 1 && segments[0];
|
|
793
|
+
if (!segment || segment.kind !== "step" || segment.startToken.indexOf("-") !== -1) {
|
|
794
|
+
return null;
|
|
795
|
+
}
|
|
796
|
+
return segment;
|
|
797
|
+
}
|
|
643
798
|
function atTimes(hours, opts) {
|
|
644
799
|
return hours.map(function each(hour) {
|
|
645
800
|
return atTime(timePhrase(hour, 0, null, opts));
|