cronli5 0.1.0 → 0.1.2
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 +70 -32
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +70 -44
- package/dist/cronli5.js +70 -44
- package/dist/lang/de.cjs +10 -3
- package/dist/lang/de.js +10 -3
- package/dist/lang/en.cjs +6 -12
- package/dist/lang/en.js +6 -12
- package/dist/lang/es.cjs +6 -12
- package/dist/lang/es.js +6 -12
- package/dist/lang/fi.cjs +8 -16
- package/dist/lang/fi.js +8 -16
- package/dist/lang/zh.cjs +5 -15
- package/dist/lang/zh.js +5 -15
- package/package.json +1 -1
- package/src/core/analyze.ts +69 -31
- package/src/core/ir.ts +6 -0
- package/src/core/normalize.ts +54 -6
- package/src/lang/de/index.ts +12 -3
- package/src/lang/en/index.ts +22 -19
- package/src/lang/es/index.ts +16 -17
- package/src/lang/fi/index.ts +19 -20
- package/src/lang/zh/index.ts +19 -28
- package/types/core/ir.d.ts +1 -0
package/src/lang/fi/index.ts
CHANGED
|
@@ -62,7 +62,6 @@ interface UnitForms {
|
|
|
62
62
|
anchor: string;
|
|
63
63
|
ela: string;
|
|
64
64
|
gen: string;
|
|
65
|
-
restart: string;
|
|
66
65
|
}
|
|
67
66
|
|
|
68
67
|
// Genitive numerals for the "N <unit>in välein" construction, spelled
|
|
@@ -179,15 +178,13 @@ const units: {minute: UnitForms; second: UnitForms} = {
|
|
|
179
178
|
mark: 'joka tunti',
|
|
180
179
|
anchor: 'jokaisen tunnin',
|
|
181
180
|
ela: 'minuutista',
|
|
182
|
-
gen: 'minuutin'
|
|
183
|
-
restart: 'tasatunnista alkaen'
|
|
181
|
+
gen: 'minuutin'
|
|
184
182
|
},
|
|
185
183
|
second: {
|
|
186
184
|
mark: 'joka minuutti',
|
|
187
185
|
anchor: 'jokaisen minuutin',
|
|
188
186
|
ela: 'sekunnista',
|
|
189
|
-
gen: 'sekunnin'
|
|
190
|
-
restart: 'joka minuutti'
|
|
187
|
+
gen: 'sekunnin'
|
|
191
188
|
}
|
|
192
189
|
};
|
|
193
190
|
|
|
@@ -686,7 +683,7 @@ function renderHourRange(
|
|
|
686
683
|
plan: Extract<PlanNode, {kind: 'hourRange'}>,
|
|
687
684
|
opts: NormalizedOptions
|
|
688
685
|
): string {
|
|
689
|
-
const window = hourWindow(plan, opts);
|
|
686
|
+
const window = hourWindow(boundedWindow(plan), opts);
|
|
690
687
|
|
|
691
688
|
if (plan.minuteForm === 'wildcard') {
|
|
692
689
|
return 'joka minuutti ' + window + trailingQualifier(ir, opts);
|
|
@@ -726,6 +723,16 @@ function renderHourStep(
|
|
|
726
723
|
trailingQualifier(ir, opts);
|
|
727
724
|
}
|
|
728
725
|
|
|
726
|
+
// The hour-range plan as a window whose closing minute honors `boundMinute`:
|
|
727
|
+
// a bare close (`null`) lands on the top of the final hour (minute 0), so
|
|
728
|
+
// `kloRange` renders the bare "klo 9–17" form, with the minutes stated
|
|
729
|
+
// separately; a single fire or wildcard names an exact closing minute.
|
|
730
|
+
function boundedWindow(
|
|
731
|
+
plan: Extract<PlanNode, {kind: 'hourRange'}>
|
|
732
|
+
): HourWindow {
|
|
733
|
+
return {from: plan.from, last: plan.boundMinute ?? 0, to: plan.to};
|
|
734
|
+
}
|
|
735
|
+
|
|
729
736
|
// "klo 9.00–17.45": a window from the top of the first hour to the
|
|
730
737
|
// minute field's last fire within the final hour.
|
|
731
738
|
function hourWindow(window: HourWindow, opts: NormalizedOptions): string {
|
|
@@ -848,15 +855,9 @@ function stepCycle60(
|
|
|
848
855
|
' alkaen';
|
|
849
856
|
}
|
|
850
857
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
if (segment.fires.length <= 2) {
|
|
856
|
-
return atMarks(joinList(wordList(segment.fires)), unit, true);
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
return cadence + ' ' + unit.restart;
|
|
858
|
+
// A clean stride from the top of the cycle is the bare cadence. (An uneven
|
|
859
|
+
// stride is rewritten to its fires upstream and never reaches here.)
|
|
860
|
+
return cadence;
|
|
860
861
|
}
|
|
861
862
|
|
|
862
863
|
// "kahden tunnin välein", "klo 0, 10 ja 20", or "viiden tunnin välein
|
|
@@ -870,7 +871,9 @@ function stepHours(segment: StepSegment, opts: NormalizedOptions): string {
|
|
|
870
871
|
const interval = segment.interval;
|
|
871
872
|
const cadence = genitive(interval, opts) + ' tunnin välein';
|
|
872
873
|
|
|
873
|
-
|
|
874
|
+
// A clean stride from midnight is the bare cadence. (An uneven stride is
|
|
875
|
+
// rewritten to its fires upstream and never reaches here.)
|
|
876
|
+
if (start === 0) {
|
|
874
877
|
return cadence;
|
|
875
878
|
}
|
|
876
879
|
|
|
@@ -878,10 +881,6 @@ function stepHours(segment: StepSegment, opts: NormalizedOptions): string {
|
|
|
878
881
|
return kloList(segment.fires, opts);
|
|
879
882
|
}
|
|
880
883
|
|
|
881
|
-
if (start === 0) {
|
|
882
|
-
return cadence + ' keskiyöstä alkaen';
|
|
883
|
-
}
|
|
884
|
-
|
|
885
884
|
return cadence + ' klo ' + hourElatives[start] + ' alkaen';
|
|
886
885
|
}
|
|
887
886
|
|
package/src/lang/zh/index.ts
CHANGED
|
@@ -217,7 +217,12 @@ function hourFrame(ir: IR): string {
|
|
|
217
217
|
|
|
218
218
|
// A repeating minute step, optionally confined to active hours.
|
|
219
219
|
function renderMinuteFrequency(ir: IR, plan: PlanNode): string {
|
|
220
|
-
const
|
|
220
|
+
const minuteStep = stepSegment(ir, 'minute');
|
|
221
|
+
// A "每N分钟" cadence is only faithful from the top of the hour; an offset
|
|
222
|
+
// step (5/6 fires at :05,:11,…) enumerates its fires instead.
|
|
223
|
+
const base = minuteStep.startToken === '*' ?
|
|
224
|
+
cadence(minuteStep.interval, UNITS.minute) :
|
|
225
|
+
renderMinutePast(ir);
|
|
221
226
|
const {hours} = plan as Extract<PlanNode, {kind: 'minuteFrequency'}>;
|
|
222
227
|
|
|
223
228
|
if (hours.kind === 'step') {
|
|
@@ -323,8 +328,9 @@ function renderHourRange(ir: IR, plan: PlanNode): string {
|
|
|
323
328
|
range.last + '分之间,每分钟';
|
|
324
329
|
}
|
|
325
330
|
|
|
326
|
-
// A stepped hour field: "每2小时", or
|
|
327
|
-
//
|
|
331
|
+
// A stepped hour field: "每2小时", or its two fires as clock words when the
|
|
332
|
+
// stride fires only twice. An uneven stride (one that does not divide 24) is
|
|
333
|
+
// rewritten to its fire list upstream and never reaches here.
|
|
328
334
|
function renderHourStep(ir: IR): string {
|
|
329
335
|
const segment = stepSegment(ir, 'hour');
|
|
330
336
|
|
|
@@ -332,16 +338,11 @@ function renderHourStep(ir: IR): string {
|
|
|
332
338
|
return hourList(ir);
|
|
333
339
|
}
|
|
334
340
|
|
|
335
|
-
// A step that fires only twice reads as two clock times ("凌晨0
|
|
341
|
+
// A step that fires only twice reads as two clock times ("凌晨0点和正午").
|
|
336
342
|
if (segment.fires.length <= 2) {
|
|
337
343
|
return joinAnd(segment.fires.map(hourWord));
|
|
338
344
|
}
|
|
339
345
|
|
|
340
|
-
if (24 % segment.interval !== 0) {
|
|
341
|
-
return '从' + hourWord(segment.fires[0]) + '起,' +
|
|
342
|
-
cadence(segment.interval, UNITS.hour);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
346
|
return cadence(segment.interval, UNITS.hour);
|
|
346
347
|
}
|
|
347
348
|
|
|
@@ -423,19 +424,17 @@ function composeSecondsOnHour(ir: IR, plan: PlanNode, opts: Opts): string {
|
|
|
423
424
|
const {rest} = plan as Extract<PlanNode, {kind: 'composeSeconds'}>;
|
|
424
425
|
const restText = render(ir, rest, opts);
|
|
425
426
|
|
|
426
|
-
if (rest.kind === 'everyHour') {
|
|
427
|
-
return sec + ',每小时';
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
if (rest.kind === 'hourStep') {
|
|
431
|
-
return sec + ',' + restText;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
427
|
if ((rest.kind === 'clockTimes' || rest.kind === 'compactClockTimes') &&
|
|
435
428
|
isDaily(ir)) {
|
|
436
429
|
return '每天' + restText + sec;
|
|
437
430
|
}
|
|
438
431
|
|
|
432
|
+
// A stated minute (e.g. minute 0 under a sub-minute second) takes the same
|
|
433
|
+
// "," connector the listed-minute path uses.
|
|
434
|
+
if (rest.kind === 'singleMinute') {
|
|
435
|
+
return restText + ',' + sec;
|
|
436
|
+
}
|
|
437
|
+
|
|
439
438
|
return restText + sec;
|
|
440
439
|
}
|
|
441
440
|
|
|
@@ -460,10 +459,12 @@ function composeSecondsCadence(ir: IR): string {
|
|
|
460
459
|
}
|
|
461
460
|
|
|
462
461
|
// Listed/ranged minute: "每小时<minutes>,每秒", confined by any hour frame.
|
|
462
|
+
// A minute list or range under an hour range closes on the bare hour frame
|
|
463
|
+
// ("在9点至17点之间"), stating its minutes separately, rather than gluing its
|
|
464
|
+
// last fire onto the window end ("…17点30分") and reading as a continuous span.
|
|
463
465
|
function composeSecondsListed(ir: IR): string {
|
|
464
466
|
const sec = secondClause(ir);
|
|
465
467
|
const minutes = '每小时' + valueList(fieldSegments(ir, 'minute'), '分');
|
|
466
|
-
const minuteSegs = fieldSegments(ir, 'minute');
|
|
467
468
|
|
|
468
469
|
if (ir.shapes.hour === 'wildcard') {
|
|
469
470
|
return minutes + ',' + sec;
|
|
@@ -474,16 +475,6 @@ function composeSecondsListed(ir: IR): string {
|
|
|
474
475
|
minutes + ',' + sec;
|
|
475
476
|
}
|
|
476
477
|
|
|
477
|
-
// A minute range under an hour range folds into the window end ("…17点30分").
|
|
478
|
-
if (ir.shapes.hour === 'range' && minuteSegs.length === 1 &&
|
|
479
|
-
minuteSegs[0].kind === 'range') {
|
|
480
|
-
const [from, to] = (fieldSegments(ir, 'hour')[0] as
|
|
481
|
-
Extract<Segment, {kind: 'range'}>).bounds;
|
|
482
|
-
|
|
483
|
-
return '在' + hourWord(+from) + '至' + to + '点' +
|
|
484
|
-
minuteSegs[0].bounds[1] + '分之间,' + sec;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
478
|
return hourFrame(ir) + minutes + ',' + sec;
|
|
488
479
|
}
|
|
489
480
|
|