cronli5 0.1.2 → 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 +89 -0
- package/cli.js +9 -0
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +280 -64
- package/dist/cronli5.js +280 -64
- package/dist/lang/de.cjs +227 -42
- package/dist/lang/de.js +227 -42
- package/dist/lang/en.cjs +216 -50
- package/dist/lang/en.js +216 -50
- package/dist/lang/es.cjs +259 -54
- package/dist/lang/es.js +259 -54
- package/dist/lang/fi.cjs +230 -69
- package/dist/lang/fi.js +230 -69
- package/dist/lang/zh.cjs +190 -19
- package/dist/lang/zh.js +190 -19
- package/package.json +3 -1
- package/src/core/analyze.ts +7 -0
- package/src/core/ir.ts +1 -1
- package/src/core/normalize.ts +94 -4
- package/src/core/util.ts +31 -1
- package/src/lang/de/index.ts +449 -46
- package/src/lang/en/index.ts +433 -63
- package/src/lang/es/index.ts +505 -63
- package/src/lang/fi/index.ts +455 -89
- package/src/lang/zh/index.ts +393 -30
- package/types/core/ir.d.ts +1 -1
- package/types/core/util.d.ts +6 -1
package/dist/lang/fi.cjs
CHANGED
|
@@ -40,6 +40,42 @@ function clockDigits(time, { sep, pad: padHour, lean }) {
|
|
|
40
40
|
return head + sep + pad(time.minute) + (time.second ? sep + pad(time.second) : "");
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
// src/core/specs.ts
|
|
44
|
+
var weekdayNumbers = {
|
|
45
|
+
SUN: 0,
|
|
46
|
+
MON: 1,
|
|
47
|
+
TUE: 2,
|
|
48
|
+
WED: 3,
|
|
49
|
+
THU: 4,
|
|
50
|
+
FRI: 5,
|
|
51
|
+
SAT: 6
|
|
52
|
+
};
|
|
53
|
+
var maxClockTimes = 6;
|
|
54
|
+
|
|
55
|
+
// src/core/util.ts
|
|
56
|
+
function isNonNegativeInteger(value) {
|
|
57
|
+
const digits = /^\d+$/;
|
|
58
|
+
return digits.test(value);
|
|
59
|
+
}
|
|
60
|
+
function arithmeticStep(values) {
|
|
61
|
+
if (values.length < 5) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const interval = values[1] - values[0];
|
|
65
|
+
if (interval < 2) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
69
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { start: values[0], interval, last: values[values.length - 1] };
|
|
74
|
+
}
|
|
75
|
+
function toFieldNumber(token, numberMap) {
|
|
76
|
+
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
77
|
+
}
|
|
78
|
+
|
|
43
79
|
// src/lang/fi/dialects.ts
|
|
44
80
|
var dialects = {
|
|
45
81
|
fi: {
|
|
@@ -166,40 +202,19 @@ var monthStems = [
|
|
|
166
202
|
"marras",
|
|
167
203
|
"joulu"
|
|
168
204
|
];
|
|
169
|
-
var monthTokens = {
|
|
170
|
-
JAN: 1,
|
|
171
|
-
FEB: 2,
|
|
172
|
-
MAR: 3,
|
|
173
|
-
APR: 4,
|
|
174
|
-
MAY: 5,
|
|
175
|
-
JUN: 6,
|
|
176
|
-
JUL: 7,
|
|
177
|
-
AUG: 8,
|
|
178
|
-
SEP: 9,
|
|
179
|
-
OCT: 10,
|
|
180
|
-
NOV: 11,
|
|
181
|
-
DEC: 12
|
|
182
|
-
};
|
|
183
|
-
var weekdayTokens = {
|
|
184
|
-
SUN: 0,
|
|
185
|
-
MON: 1,
|
|
186
|
-
TUE: 2,
|
|
187
|
-
WED: 3,
|
|
188
|
-
THU: 4,
|
|
189
|
-
FRI: 5,
|
|
190
|
-
SAT: 6
|
|
191
|
-
};
|
|
192
205
|
var units = {
|
|
193
206
|
minute: {
|
|
194
207
|
mark: "joka tunti",
|
|
195
208
|
anchor: "jokaisen tunnin",
|
|
196
209
|
ela: "minuutista",
|
|
210
|
+
ill: "minuuttiin",
|
|
197
211
|
gen: "minuutin"
|
|
198
212
|
},
|
|
199
213
|
second: {
|
|
200
214
|
mark: "joka minuutti",
|
|
201
215
|
anchor: "jokaisen minuutin",
|
|
202
216
|
ela: "sekunnista",
|
|
217
|
+
ill: "sekuntiin",
|
|
203
218
|
gen: "sekunnin"
|
|
204
219
|
}
|
|
205
220
|
};
|
|
@@ -255,26 +270,61 @@ function renderSecondsWithinMinute(ir, plan, opts) {
|
|
|
255
270
|
}
|
|
256
271
|
return secondsLeadClause(ir, opts) + ", " + atMarks(minuteField, units.minute, true) + trailingQualifier(ir, opts);
|
|
257
272
|
}
|
|
273
|
+
function composeSecondsOverMinuteStep(ir, freq, opts) {
|
|
274
|
+
const seg = stepSegment(ir.analyses.segments.minute);
|
|
275
|
+
const stepPhrase = stepCycle60(seg, units.minute, opts);
|
|
276
|
+
if (freq.hours.kind === "during" && minuteStepIsAnchored(seg)) {
|
|
277
|
+
const bareHours = kloFromTimes(ir, freq.hours.times, opts);
|
|
278
|
+
return hoursFirstMinutes(bareHours, ir, opts) + ", " + secondsLeadClause(ir, opts) + trailingQualifier(ir, opts);
|
|
279
|
+
}
|
|
280
|
+
let hourClause = "";
|
|
281
|
+
if (freq.hours.kind === "during") {
|
|
282
|
+
hourClause = " " + hourWindowsFromTimes(ir, freq.hours.times, opts);
|
|
283
|
+
} else if (freq.hours.kind === "window") {
|
|
284
|
+
hourClause = " " + hourWindow(freq.hours, opts);
|
|
285
|
+
} else if (freq.hours.kind === "step") {
|
|
286
|
+
hourClause = " " + everyNthHour(stepSegment(ir.analyses.segments.hour), opts);
|
|
287
|
+
}
|
|
288
|
+
return stepPhrase + ", " + secondsLeadClause(ir, opts) + hourClause + trailingQualifier(ir, opts);
|
|
289
|
+
}
|
|
290
|
+
function composeHourCadence(ir, plan, opts) {
|
|
291
|
+
const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
|
|
292
|
+
return clockRest && ir.shapes.minute === "single" ? hourCadence(ir, +ir.pattern.minute, opts) : null;
|
|
293
|
+
}
|
|
258
294
|
function renderComposeSeconds(ir, plan, opts) {
|
|
295
|
+
const cadence = composeHourCadence(ir, plan, opts);
|
|
296
|
+
if (cadence !== null) {
|
|
297
|
+
return cadence;
|
|
298
|
+
}
|
|
259
299
|
if (plan.rest.kind === "minuteFrequency" && ir.pattern.second !== "*") {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
} else if (freq.hours.kind === "during" && !minuteStepIsAnchored(seg)) {
|
|
268
|
-
hourClause = " " + hourWindowsFromTimes(ir, freq.hours.times, opts);
|
|
269
|
-
} else if (freq.hours.kind === "window") {
|
|
270
|
-
hourClause = " " + hourWindow(freq.hours, opts);
|
|
271
|
-
} else if (freq.hours.kind === "step") {
|
|
272
|
-
hourClause = " " + everyNthHour(stepSegment(ir.analyses.segments.hour), opts);
|
|
273
|
-
}
|
|
274
|
-
return stepPhrase + ", " + secondsLeadClause(ir, opts) + hourClause + trailingQualifier(ir, opts);
|
|
300
|
+
return composeSecondsOverMinuteStep(ir, plan.rest, opts);
|
|
301
|
+
}
|
|
302
|
+
if (plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0)) {
|
|
303
|
+
return composeMinuteZero(ir, plan.rest, opts);
|
|
304
|
+
}
|
|
305
|
+
if (isEveryOtherMinuteSeconds(ir, plan)) {
|
|
306
|
+
return secondsLeadClause(ir, opts) + " joka toisena minuuttina";
|
|
275
307
|
}
|
|
276
308
|
return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
|
|
277
309
|
}
|
|
310
|
+
function isEveryOtherMinuteSeconds(ir, plan) {
|
|
311
|
+
if (plan.rest.kind !== "minuteFrequency" || ir.pattern.second !== "*" || ir.shapes.hour !== "wildcard") {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
const seg = stepSegment(ir.analyses.segments.minute);
|
|
315
|
+
return seg.startToken === "*" && seg.interval === 2;
|
|
316
|
+
}
|
|
317
|
+
function composeMinuteZero(ir, rest, opts) {
|
|
318
|
+
const clocks = rest.times.map(function clock(time) {
|
|
319
|
+
return clockDigits(
|
|
320
|
+
{ hour: time.hour, minute: time.minute },
|
|
321
|
+
{ sep: opts.style.sep }
|
|
322
|
+
);
|
|
323
|
+
});
|
|
324
|
+
const frame = clocks.length === 1 ? "minuutin " + clocks[0] : "minuuttien " + joinList(clocks);
|
|
325
|
+
const dayTrail = leadingQualifier(ir, opts).trimEnd();
|
|
326
|
+
return secondsLeadClause(ir, opts) + " " + frame + " aikana" + (dayTrail ? ", " + dayTrail : "");
|
|
327
|
+
}
|
|
278
328
|
function secondsLeadClause(ir, opts) {
|
|
279
329
|
const secondField = ir.pattern.second;
|
|
280
330
|
const shape = ir.shapes.second;
|
|
@@ -292,7 +342,7 @@ function secondsLeadClause(ir, opts) {
|
|
|
292
342
|
if (shape === "single") {
|
|
293
343
|
return atMarks(secondField, units.second, marked);
|
|
294
344
|
}
|
|
295
|
-
return atMarks(
|
|
345
|
+
return strideFromSegments(ir.analyses.segments.second, units.second, opts) ?? atMarks(
|
|
296
346
|
joinList(segmentWords(ir.analyses.segments.second)),
|
|
297
347
|
units.second,
|
|
298
348
|
marked
|
|
@@ -305,20 +355,20 @@ function renderSingleMinute(ir, plan, opts) {
|
|
|
305
355
|
return atMarks(ir.pattern.minute, units.minute, true) + trailingQualifier(ir, opts);
|
|
306
356
|
}
|
|
307
357
|
function renderRangeOfMinutes(ir, plan, opts) {
|
|
308
|
-
return minutesList(ir) + trailingQualifier(ir, opts);
|
|
358
|
+
return minutesList(ir, opts) + trailingQualifier(ir, opts);
|
|
309
359
|
}
|
|
310
360
|
function renderMultipleMinutes(ir, plan, opts) {
|
|
311
|
-
return minutesList(ir) + trailingQualifier(ir, opts);
|
|
361
|
+
return minutesList(ir, opts) + trailingQualifier(ir, opts);
|
|
312
362
|
}
|
|
313
|
-
function minutesList(ir) {
|
|
314
|
-
return atMarks(
|
|
363
|
+
function minutesList(ir, opts) {
|
|
364
|
+
return strideFromSegments(ir.analyses.segments.minute, units.minute, opts) ?? atMarks(
|
|
315
365
|
joinList(segmentWords(ir.analyses.segments.minute)),
|
|
316
366
|
units.minute,
|
|
317
367
|
true
|
|
318
368
|
);
|
|
319
369
|
}
|
|
320
|
-
function bareMinutes(ir) {
|
|
321
|
-
return atMarks(
|
|
370
|
+
function bareMinutes(ir, opts) {
|
|
371
|
+
return strideFromSegments(ir.analyses.segments.minute, units.minute, opts) ?? atMarks(
|
|
322
372
|
joinList(segmentWords(ir.analyses.segments.minute)),
|
|
323
373
|
units.minute,
|
|
324
374
|
false
|
|
@@ -349,7 +399,11 @@ function hoursAreRangeIsolated(segments) {
|
|
|
349
399
|
}
|
|
350
400
|
return hasRange && hasSingle;
|
|
351
401
|
}
|
|
352
|
-
function hoursFirstMinutes(hoursStr, ir) {
|
|
402
|
+
function hoursFirstMinutes(hoursStr, ir, opts) {
|
|
403
|
+
const stride = strideFromSegments(ir.analyses.segments.minute, units.minute, opts);
|
|
404
|
+
if (stride) {
|
|
405
|
+
return hoursStr + " aina " + stride;
|
|
406
|
+
}
|
|
353
407
|
return hoursStr + " aina minuuttien " + joinList(segmentWords(ir.analyses.segments.minute)) + " kohdalla";
|
|
354
408
|
}
|
|
355
409
|
function hourSegmentTimesWithSeka(ir, minute, second, opts) {
|
|
@@ -372,7 +426,7 @@ function renderMinuteFrequency(ir, plan, opts) {
|
|
|
372
426
|
if (plan.hours.kind === "during") {
|
|
373
427
|
if (minuteStepIsAnchored(seg)) {
|
|
374
428
|
const bareHours = kloFromTimes(ir, plan.hours.times, opts);
|
|
375
|
-
return hoursFirstMinutes(bareHours, ir) + trailingQualifier(ir, opts);
|
|
429
|
+
return hoursFirstMinutes(bareHours, ir, opts) + trailingQualifier(ir, opts);
|
|
376
430
|
}
|
|
377
431
|
return stepCycle60(seg, units.minute, opts) + " " + hourWindowsFromTimes(ir, plan.hours.times, opts) + trailingQualifier(ir, opts);
|
|
378
432
|
}
|
|
@@ -385,6 +439,9 @@ function renderMinuteFrequency(ir, plan, opts) {
|
|
|
385
439
|
return phrase + trailingQualifier(ir, opts);
|
|
386
440
|
}
|
|
387
441
|
function renderMinuteSpanInHour(ir, plan, opts) {
|
|
442
|
+
if (ir.pattern.minute === "*") {
|
|
443
|
+
return "joka minuutti kello " + plan.hour + " aikana" + trailingQualifier(ir, opts);
|
|
444
|
+
}
|
|
388
445
|
return "joka minuutti " + kloRange(
|
|
389
446
|
{ hour: plan.hour, minute: plan.span[0] },
|
|
390
447
|
{ hour: plan.hour, minute: plan.span[1] },
|
|
@@ -396,10 +453,10 @@ function renderMinutesAcrossHours(ir, plan, opts) {
|
|
|
396
453
|
return "joka minuutti " + hourWindowsFromTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
397
454
|
}
|
|
398
455
|
if (hoursAreRangeIsolated(ir.analyses.segments.hour)) {
|
|
399
|
-
return bareMinutes(ir) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
456
|
+
return bareMinutes(ir, opts) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
400
457
|
}
|
|
401
458
|
const hoursStr = kloFromTimes(ir, plan.times, opts);
|
|
402
|
-
return hoursFirstMinutes(hoursStr, ir) + trailingQualifier(ir, opts);
|
|
459
|
+
return hoursFirstMinutes(hoursStr, ir, opts) + trailingQualifier(ir, opts);
|
|
403
460
|
}
|
|
404
461
|
function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
405
462
|
const segment = stepSegment(ir.analyses.segments.hour);
|
|
@@ -408,9 +465,9 @@ function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
|
408
465
|
}
|
|
409
466
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
410
467
|
const hoursStr = kloList(segment.fires, opts);
|
|
411
|
-
return hoursFirstMinutes(hoursStr, ir) + trailingQualifier(ir, opts);
|
|
468
|
+
return hoursFirstMinutes(hoursStr, ir, opts) + trailingQualifier(ir, opts);
|
|
412
469
|
}
|
|
413
|
-
return bareMinutes(ir) + hourStepTail(segment, opts) + trailingQualifier(ir, opts);
|
|
470
|
+
return bareMinutes(ir, opts) + hourStepTail(segment, opts) + trailingQualifier(ir, opts);
|
|
414
471
|
}
|
|
415
472
|
function plainHourStep(segment) {
|
|
416
473
|
return segment.startToken === "*" && 24 % segment.interval === 0;
|
|
@@ -468,7 +525,7 @@ function renderHourRange(ir, plan, opts) {
|
|
|
468
525
|
return "joka minuutti " + window + trailingQualifier(ir, opts);
|
|
469
526
|
}
|
|
470
527
|
if (plan.minuteForm === "range") {
|
|
471
|
-
return hoursFirstMinutes(window, ir) + trailingQualifier(ir, opts);
|
|
528
|
+
return hoursFirstMinutes(window, ir, opts) + trailingQualifier(ir, opts);
|
|
472
529
|
}
|
|
473
530
|
if (ir.pattern.minute === "0") {
|
|
474
531
|
return "joka tunti " + window + trailingQualifier(ir, opts);
|
|
@@ -480,7 +537,7 @@ function renderHourRange(ir, plan, opts) {
|
|
|
480
537
|
opts
|
|
481
538
|
) + trailingQualifier(ir, opts);
|
|
482
539
|
}
|
|
483
|
-
return hoursFirstMinutes(window, ir) + trailingQualifier(ir, opts);
|
|
540
|
+
return hoursFirstMinutes(window, ir, opts) + trailingQualifier(ir, opts);
|
|
484
541
|
}
|
|
485
542
|
function renderHourStep(ir, plan, opts) {
|
|
486
543
|
return stepHours(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
|
|
@@ -496,6 +553,12 @@ function hourWindow(window, opts) {
|
|
|
496
553
|
);
|
|
497
554
|
}
|
|
498
555
|
function renderClockTimes(ir, plan, opts) {
|
|
556
|
+
if (ir.shapes.minute === "single") {
|
|
557
|
+
const cadence = hourCadence(ir, +ir.pattern.minute, opts);
|
|
558
|
+
if (cadence !== null) {
|
|
559
|
+
return cadence;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
499
562
|
if (plan.times.length === 1) {
|
|
500
563
|
const time = plan.times[0];
|
|
501
564
|
return leadingQualifier(ir, opts) + timeWord(time.hour, time.minute, time.second, opts);
|
|
@@ -506,6 +569,12 @@ function renderClockTimes(ir, plan, opts) {
|
|
|
506
569
|
return leadingQualifier(ir, opts) + "klo " + joinList(digits);
|
|
507
570
|
}
|
|
508
571
|
function renderCompactClockTimes(ir, plan, opts) {
|
|
572
|
+
if (plan.fold) {
|
|
573
|
+
const cadence = hourCadence(ir, plan.minute, opts);
|
|
574
|
+
if (cadence !== null) {
|
|
575
|
+
return cadence;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
509
578
|
const hourSegs = ir.analyses.segments.hour;
|
|
510
579
|
if (hoursAreRangeIsolated(hourSegs)) {
|
|
511
580
|
if (plan.fold) {
|
|
@@ -516,14 +585,14 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
516
585
|
opts
|
|
517
586
|
);
|
|
518
587
|
}
|
|
519
|
-
const phrase2 = bareMinutes(ir) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
588
|
+
const phrase2 = bareMinutes(ir, opts) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
520
589
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase2 : phrase2;
|
|
521
590
|
}
|
|
522
591
|
if (plan.fold) {
|
|
523
592
|
return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
|
|
524
593
|
}
|
|
525
594
|
const hoursStr = hourSegmentTimes(ir, 0, null, opts);
|
|
526
|
-
const phrase = hoursFirstMinutes(hoursStr, ir) + trailingQualifier(ir, opts);
|
|
595
|
+
const phrase = hoursFirstMinutes(hoursStr, ir, opts) + trailingQualifier(ir, opts);
|
|
527
596
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
|
|
528
597
|
}
|
|
529
598
|
var renderers = {
|
|
@@ -546,20 +615,48 @@ var renderers = {
|
|
|
546
615
|
singleMinute: renderSingleMinute,
|
|
547
616
|
standaloneSeconds: renderStandaloneSeconds
|
|
548
617
|
};
|
|
618
|
+
function renderStride(stride, opts) {
|
|
619
|
+
const { interval, start, last, cycle, unit } = stride;
|
|
620
|
+
const cadence = genitive(interval, opts) + " " + unit.gen + " v\xE4lein";
|
|
621
|
+
const tiles = cycle % interval === 0;
|
|
622
|
+
if (start === 0 && tiles) {
|
|
623
|
+
return cadence;
|
|
624
|
+
}
|
|
625
|
+
if (start < interval && tiles) {
|
|
626
|
+
return cadence + " " + unit.anchor + " " + unit.ela + " " + start + " alkaen";
|
|
627
|
+
}
|
|
628
|
+
return cadence + " " + unit.ela + " " + start + " " + unit.ill + " " + last;
|
|
629
|
+
}
|
|
630
|
+
function strideFromSegments(segments, unit, opts) {
|
|
631
|
+
const values = singleValues(segments);
|
|
632
|
+
const step = values && arithmeticStep(values);
|
|
633
|
+
return step ? renderStride({ ...step, cycle: 60, unit }, opts) : null;
|
|
634
|
+
}
|
|
635
|
+
function singleValues(segments) {
|
|
636
|
+
const values = [];
|
|
637
|
+
for (const segment of segments) {
|
|
638
|
+
if (segment.kind !== "single") {
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
values.push(+segment.value);
|
|
642
|
+
}
|
|
643
|
+
return values;
|
|
644
|
+
}
|
|
549
645
|
function stepCycle60(segment, unit, opts) {
|
|
550
646
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
551
647
|
return atMarks(joinList(wordList(segment.fires)), unit, true);
|
|
552
648
|
}
|
|
553
649
|
const start = segment.startToken === "*" ? 0 : +segment.startToken;
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
if (start !== 0) {
|
|
557
|
-
if (segment.fires.length <= 3) {
|
|
558
|
-
return atMarks(joinList(wordList(segment.fires)), unit, true);
|
|
559
|
-
}
|
|
560
|
-
return cadence + " " + unit.anchor + " " + unit.ela + " " + start + " alkaen";
|
|
650
|
+
if (start !== 0 && segment.fires.length <= 3) {
|
|
651
|
+
return atMarks(joinList(wordList(segment.fires)), unit, true);
|
|
561
652
|
}
|
|
562
|
-
return
|
|
653
|
+
return renderStride({
|
|
654
|
+
interval: segment.interval,
|
|
655
|
+
start,
|
|
656
|
+
last: segment.fires[segment.fires.length - 1],
|
|
657
|
+
cycle: 60,
|
|
658
|
+
unit
|
|
659
|
+
}, opts);
|
|
563
660
|
}
|
|
564
661
|
function stepHours(segment, opts) {
|
|
565
662
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
@@ -576,6 +673,71 @@ function stepHours(segment, opts) {
|
|
|
576
673
|
}
|
|
577
674
|
return cadence + " klo " + hourElatives[start] + " alkaen";
|
|
578
675
|
}
|
|
676
|
+
function hourStrideCadence(stride, opts) {
|
|
677
|
+
const { start, interval, last } = stride;
|
|
678
|
+
const cadence = genitive(interval, opts) + " tunnin v\xE4lein";
|
|
679
|
+
const tiles = 24 % interval === 0;
|
|
680
|
+
if (start === 0 && tiles) {
|
|
681
|
+
return cadence;
|
|
682
|
+
}
|
|
683
|
+
if (start < interval && tiles) {
|
|
684
|
+
return cadence + " klo " + hourElatives[start] + " alkaen";
|
|
685
|
+
}
|
|
686
|
+
return cadence + " " + kloRange({ hour: start, minute: 0 }, { hour: last, minute: 0 }, opts);
|
|
687
|
+
}
|
|
688
|
+
function hourStride(ir) {
|
|
689
|
+
const segments = ir.analyses.segments.hour;
|
|
690
|
+
if (!segments) {
|
|
691
|
+
return null;
|
|
692
|
+
}
|
|
693
|
+
if (segments.length === 1 && segments[0].kind === "step") {
|
|
694
|
+
const segment = segments[0];
|
|
695
|
+
const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
|
|
696
|
+
return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
|
|
697
|
+
}
|
|
698
|
+
const values = singleValues(segments);
|
|
699
|
+
const step = values && arithmeticStep(values);
|
|
700
|
+
return step || null;
|
|
701
|
+
}
|
|
702
|
+
function subMinuteSecond(ir) {
|
|
703
|
+
return ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
704
|
+
}
|
|
705
|
+
function hourCadenceLead(ir, minute, opts) {
|
|
706
|
+
if (minute === 0) {
|
|
707
|
+
if (subMinuteSecond(ir)) {
|
|
708
|
+
return secondsLeadClause(ir, opts) + " minuutin ajan";
|
|
709
|
+
}
|
|
710
|
+
return secondsLeadClause(ir, opts);
|
|
711
|
+
}
|
|
712
|
+
const minutePhrase = atMarks(String(minute), units.minute, false);
|
|
713
|
+
if (ir.pattern.second === "0") {
|
|
714
|
+
return minutePhrase;
|
|
715
|
+
}
|
|
716
|
+
return secondsLeadClause(ir, opts) + ", " + minutePhrase;
|
|
717
|
+
}
|
|
718
|
+
function hourCadence(ir, minute, opts) {
|
|
719
|
+
const stride = hourStride(ir);
|
|
720
|
+
if (!stride) {
|
|
721
|
+
return null;
|
|
722
|
+
}
|
|
723
|
+
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
724
|
+
if (ir.pattern.second === "0" && fires <= maxClockTimes) {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
const segment = ir.analyses.segments.hour[0];
|
|
728
|
+
const confined = minute === 0 && subMinuteSecond(ir) && ir.analyses.segments.hour.length === 1 && segment.kind === "step" && cleanHourStride(segment);
|
|
729
|
+
if (confined) {
|
|
730
|
+
return secondsLeadClause(ir, opts) + " minuutin ajan " + everyNthHour(segment, opts) + trailingQualifier(ir, opts);
|
|
731
|
+
}
|
|
732
|
+
return hourCadenceLead(ir, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
|
|
733
|
+
}
|
|
734
|
+
function cleanHourStride(segment) {
|
|
735
|
+
if (segment.startToken.indexOf("-") !== -1) {
|
|
736
|
+
return false;
|
|
737
|
+
}
|
|
738
|
+
const start = segment.startToken === "*" ? 0 : +segment.startToken;
|
|
739
|
+
return 24 % segment.interval === 0 && start < segment.interval;
|
|
740
|
+
}
|
|
579
741
|
function kloList(hours, opts) {
|
|
580
742
|
if (hours.length === 1) {
|
|
581
743
|
return timeWord(hours[0], 0, null, opts);
|
|
@@ -840,13 +1002,10 @@ function quartzWeekdayPhrase(weekdayField) {
|
|
|
840
1002
|
}
|
|
841
1003
|
}
|
|
842
1004
|
function weekdayNumber(token) {
|
|
843
|
-
|
|
844
|
-
return weekdayTokens[token];
|
|
845
|
-
}
|
|
846
|
-
return +token % 7;
|
|
1005
|
+
return toFieldNumber("" + token, weekdayNumbers) % 7;
|
|
847
1006
|
}
|
|
848
1007
|
function monthNumber(token) {
|
|
849
|
-
return
|
|
1008
|
+
return +token;
|
|
850
1009
|
}
|
|
851
1010
|
function applyYear(description, ir, opts) {
|
|
852
1011
|
const yearField = ir.pattern.year;
|
|
@@ -928,7 +1087,9 @@ var fi = {
|
|
|
928
1087
|
fallback: "tunnistamaton cron-lauseke",
|
|
929
1088
|
options: normalizeOptions,
|
|
930
1089
|
reboot: "j\xE4rjestelm\xE4n k\xE4ynnistyess\xE4",
|
|
931
|
-
|
|
1090
|
+
// A description ending in a period already carries it, so closing the
|
|
1091
|
+
// sentence must not double it.
|
|
1092
|
+
sentence: (description) => "Suoritetaan " + description + (description.endsWith(".") ? "" : ".")
|
|
932
1093
|
};
|
|
933
1094
|
var index_default = fi;
|
|
934
1095
|
module.exports = module.exports.default;
|