cronli5 0.3.4 → 0.7.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 +97 -0
- package/README.md +39 -6
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +13 -6
- package/dist/cronli5.js +13 -6
- package/dist/lang/de.cjs +13 -6
- package/dist/lang/de.js +13 -6
- package/dist/lang/en.cjs +13 -6
- package/dist/lang/en.js +13 -6
- package/dist/lang/es.cjs +13 -6
- package/dist/lang/es.js +13 -6
- package/dist/lang/fi.cjs +13 -6
- package/dist/lang/fi.js +13 -6
- package/dist/lang/fr.cjs +1210 -0
- package/dist/lang/fr.js +1186 -0
- package/dist/lang/pt.cjs +1591 -0
- package/dist/lang/pt.js +1567 -0
- package/dist/lang/zh.cjs +57 -9
- package/dist/lang/zh.js +57 -9
- package/package.json +13 -2
- package/src/core/cadence.ts +25 -12
- package/src/lang/de/index.ts +2 -2
- package/src/lang/en/index.ts +2 -2
- package/src/lang/es/index.ts +2 -2
- package/src/lang/fi/index.ts +2 -2
- package/src/lang/fr/dialects.ts +49 -0
- package/src/lang/fr/index.ts +2115 -0
- package/src/lang/fr/notes.md +280 -0
- package/src/lang/fr/status.json +8 -0
- package/src/lang/pt/dialects.ts +56 -0
- package/src/lang/pt/index.ts +2803 -0
- package/src/lang/pt/notes.md +199 -0
- package/src/lang/pt/status.json +8 -0
- package/src/lang/zh/index.ts +60 -5
- package/src/lang/zh/notes.md +16 -4
- package/src/lang/zh/status.json +10 -1
- package/types/core/cadence.d.ts +1 -0
- package/types/lang/fr/dialects.d.ts +11 -0
- package/types/lang/fr/index.d.ts +4 -0
- package/types/lang/pt/dialects.d.ts +13 -0
- package/types/lang/pt/index.d.ts +4 -0
package/dist/lang/zh.cjs
CHANGED
|
@@ -59,13 +59,20 @@ function singleValues(segments) {
|
|
|
59
59
|
function offsetCleanStride(stride) {
|
|
60
60
|
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
61
61
|
}
|
|
62
|
+
function lastTileOf(start, interval, cycle) {
|
|
63
|
+
return cycle - 1 - (cycle - 1 - start) % interval;
|
|
64
|
+
}
|
|
62
65
|
function renderStride(spec, parts) {
|
|
63
|
-
const { start, interval, cycle } = spec;
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
+
const { start, interval, last, cycle } = spec;
|
|
67
|
+
const open = cycle % interval === 0 && last === lastTileOf(
|
|
68
|
+
start,
|
|
69
|
+
interval,
|
|
70
|
+
cycle
|
|
71
|
+
);
|
|
72
|
+
if (start === 0 && open) {
|
|
66
73
|
return parts.bare();
|
|
67
74
|
}
|
|
68
|
-
if (start < interval &&
|
|
75
|
+
if (start < interval && open) {
|
|
69
76
|
return parts.offset();
|
|
70
77
|
}
|
|
71
78
|
return parts.bounded();
|
|
@@ -165,6 +172,35 @@ function resolveDialect(dialect) {
|
|
|
165
172
|
// src/lang/zh/index.ts
|
|
166
173
|
var UNITS = { hour: "\u5C0F\u65F6", minute: "\u5206\u949F", second: "\u79D2" };
|
|
167
174
|
var WEEKDAYS = ["\u5468\u65E5", "\u5468\u4E00", "\u5468\u4E8C", "\u5468\u4E09", "\u5468\u56DB", "\u5468\u4E94", "\u5468\u516D"];
|
|
175
|
+
var HANT = {
|
|
176
|
+
\u4E2A: "\u500B",
|
|
177
|
+
\u4ECE: "\u5F9E",
|
|
178
|
+
\u5185: "\u5167",
|
|
179
|
+
\u522B: "\u5225",
|
|
180
|
+
\u52A8: "\u52D5",
|
|
181
|
+
\u5355: "\u55AE",
|
|
182
|
+
\u53CC: "\u96D9",
|
|
183
|
+
\u540E: "\u5F8C",
|
|
184
|
+
\u542F: "\u555F",
|
|
185
|
+
\u5468: "\u9031",
|
|
186
|
+
\u6570: "\u6578",
|
|
187
|
+
\u65E0: "\u7121",
|
|
188
|
+
\u65F6: "\u6642",
|
|
189
|
+
\u70B9: "\u9EDE",
|
|
190
|
+
\u7EDF: "\u7D71",
|
|
191
|
+
\u8BC6: "\u8B58",
|
|
192
|
+
\u8FBE: "\u9054",
|
|
193
|
+
\u8FD0: "\u904B",
|
|
194
|
+
\u949F: "\u9418",
|
|
195
|
+
\u95F4: "\u9593"
|
|
196
|
+
};
|
|
197
|
+
function toVariant(text, variant) {
|
|
198
|
+
if (variant !== "Hant") {
|
|
199
|
+
return text;
|
|
200
|
+
}
|
|
201
|
+
return Array.from(text, (glyph) => HANT[glyph] ?? glyph).join("");
|
|
202
|
+
}
|
|
203
|
+
var activeVariant = "Hans";
|
|
168
204
|
function joinAnd(items) {
|
|
169
205
|
if (items.length < 2) {
|
|
170
206
|
return items.join("");
|
|
@@ -177,7 +213,7 @@ function cadence(interval, unit) {
|
|
|
177
213
|
function renderStride2(stride) {
|
|
178
214
|
const { interval, start, last, cycle, unit, mark, anchor } = stride;
|
|
179
215
|
const lead = anchor + "\u4ECE" + start + mark + "\u8D77" + cadence(interval, unit);
|
|
180
|
-
return renderStride({ start, interval, cycle }, {
|
|
216
|
+
return renderStride({ start, interval, last, cycle }, {
|
|
181
217
|
bare: () => cadence(interval, unit),
|
|
182
218
|
offset: () => lead,
|
|
183
219
|
bounded: () => lead + "\uFF0C\u81F3" + last + mark
|
|
@@ -873,6 +909,9 @@ function hourCadenceApplies(schedule) {
|
|
|
873
909
|
return hourCadenceText(schedule) !== null;
|
|
874
910
|
}
|
|
875
911
|
function describe(schedule, opts) {
|
|
912
|
+
return toVariant(describeHans(schedule, opts), opts.style.variant);
|
|
913
|
+
}
|
|
914
|
+
function describeHans(schedule, opts) {
|
|
876
915
|
const { kind } = schedule.plan;
|
|
877
916
|
const core = render(schedule, schedule.plan, opts);
|
|
878
917
|
let composed = core;
|
|
@@ -901,21 +940,30 @@ function describe(schedule, opts) {
|
|
|
901
940
|
}
|
|
902
941
|
function normalizeOptions(options) {
|
|
903
942
|
options = options || {};
|
|
943
|
+
const style = resolveDialect(options.dialect);
|
|
944
|
+
activeVariant = style.variant;
|
|
904
945
|
return {
|
|
905
946
|
ampm: typeof options.ampm === "boolean" ? options.ampm : false,
|
|
906
947
|
lenient: !!options.lenient,
|
|
907
948
|
seconds: !!options.seconds,
|
|
908
949
|
short: !!options.short,
|
|
909
|
-
style
|
|
950
|
+
style,
|
|
910
951
|
years: !!options.years
|
|
911
952
|
};
|
|
912
953
|
}
|
|
913
954
|
var zh2 = {
|
|
914
955
|
describe,
|
|
915
|
-
fallback
|
|
956
|
+
// `reboot`/`fallback` are contract-fixed strings the core reads without
|
|
957
|
+
// `opts`; getters honor the variant `options()` latched, keeping the shared
|
|
958
|
+
// Language contract unchanged while the Traditional dialect still applies.
|
|
959
|
+
get fallback() {
|
|
960
|
+
return toVariant("\u65E0\u6CD5\u8BC6\u522B\u7684 cron \u8868\u8FBE\u5F0F", activeVariant);
|
|
961
|
+
},
|
|
916
962
|
options: normalizeOptions,
|
|
917
|
-
reboot
|
|
918
|
-
|
|
963
|
+
get reboot() {
|
|
964
|
+
return toVariant("\u7CFB\u7EDF\u542F\u52A8\u65F6", activeVariant);
|
|
965
|
+
},
|
|
966
|
+
sentence: (description) => toVariant("\u8FD0\u884C\u65F6\u95F4\uFF1A", activeVariant) + description + "\u3002"
|
|
919
967
|
};
|
|
920
968
|
var index_default = zh2;
|
|
921
969
|
module.exports = module.exports.default;
|
package/dist/lang/zh.js
CHANGED
|
@@ -33,13 +33,20 @@ function singleValues(segments) {
|
|
|
33
33
|
function offsetCleanStride(stride) {
|
|
34
34
|
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
35
35
|
}
|
|
36
|
+
function lastTileOf(start, interval, cycle) {
|
|
37
|
+
return cycle - 1 - (cycle - 1 - start) % interval;
|
|
38
|
+
}
|
|
36
39
|
function renderStride(spec, parts) {
|
|
37
|
-
const { start, interval, cycle } = spec;
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
+
const { start, interval, last, cycle } = spec;
|
|
41
|
+
const open = cycle % interval === 0 && last === lastTileOf(
|
|
42
|
+
start,
|
|
43
|
+
interval,
|
|
44
|
+
cycle
|
|
45
|
+
);
|
|
46
|
+
if (start === 0 && open) {
|
|
40
47
|
return parts.bare();
|
|
41
48
|
}
|
|
42
|
-
if (start < interval &&
|
|
49
|
+
if (start < interval && open) {
|
|
43
50
|
return parts.offset();
|
|
44
51
|
}
|
|
45
52
|
return parts.bounded();
|
|
@@ -139,6 +146,35 @@ function resolveDialect(dialect) {
|
|
|
139
146
|
// src/lang/zh/index.ts
|
|
140
147
|
var UNITS = { hour: "\u5C0F\u65F6", minute: "\u5206\u949F", second: "\u79D2" };
|
|
141
148
|
var WEEKDAYS = ["\u5468\u65E5", "\u5468\u4E00", "\u5468\u4E8C", "\u5468\u4E09", "\u5468\u56DB", "\u5468\u4E94", "\u5468\u516D"];
|
|
149
|
+
var HANT = {
|
|
150
|
+
\u4E2A: "\u500B",
|
|
151
|
+
\u4ECE: "\u5F9E",
|
|
152
|
+
\u5185: "\u5167",
|
|
153
|
+
\u522B: "\u5225",
|
|
154
|
+
\u52A8: "\u52D5",
|
|
155
|
+
\u5355: "\u55AE",
|
|
156
|
+
\u53CC: "\u96D9",
|
|
157
|
+
\u540E: "\u5F8C",
|
|
158
|
+
\u542F: "\u555F",
|
|
159
|
+
\u5468: "\u9031",
|
|
160
|
+
\u6570: "\u6578",
|
|
161
|
+
\u65E0: "\u7121",
|
|
162
|
+
\u65F6: "\u6642",
|
|
163
|
+
\u70B9: "\u9EDE",
|
|
164
|
+
\u7EDF: "\u7D71",
|
|
165
|
+
\u8BC6: "\u8B58",
|
|
166
|
+
\u8FBE: "\u9054",
|
|
167
|
+
\u8FD0: "\u904B",
|
|
168
|
+
\u949F: "\u9418",
|
|
169
|
+
\u95F4: "\u9593"
|
|
170
|
+
};
|
|
171
|
+
function toVariant(text, variant) {
|
|
172
|
+
if (variant !== "Hant") {
|
|
173
|
+
return text;
|
|
174
|
+
}
|
|
175
|
+
return Array.from(text, (glyph) => HANT[glyph] ?? glyph).join("");
|
|
176
|
+
}
|
|
177
|
+
var activeVariant = "Hans";
|
|
142
178
|
function joinAnd(items) {
|
|
143
179
|
if (items.length < 2) {
|
|
144
180
|
return items.join("");
|
|
@@ -151,7 +187,7 @@ function cadence(interval, unit) {
|
|
|
151
187
|
function renderStride2(stride) {
|
|
152
188
|
const { interval, start, last, cycle, unit, mark, anchor } = stride;
|
|
153
189
|
const lead = anchor + "\u4ECE" + start + mark + "\u8D77" + cadence(interval, unit);
|
|
154
|
-
return renderStride({ start, interval, cycle }, {
|
|
190
|
+
return renderStride({ start, interval, last, cycle }, {
|
|
155
191
|
bare: () => cadence(interval, unit),
|
|
156
192
|
offset: () => lead,
|
|
157
193
|
bounded: () => lead + "\uFF0C\u81F3" + last + mark
|
|
@@ -847,6 +883,9 @@ function hourCadenceApplies(schedule) {
|
|
|
847
883
|
return hourCadenceText(schedule) !== null;
|
|
848
884
|
}
|
|
849
885
|
function describe(schedule, opts) {
|
|
886
|
+
return toVariant(describeHans(schedule, opts), opts.style.variant);
|
|
887
|
+
}
|
|
888
|
+
function describeHans(schedule, opts) {
|
|
850
889
|
const { kind } = schedule.plan;
|
|
851
890
|
const core = render(schedule, schedule.plan, opts);
|
|
852
891
|
let composed = core;
|
|
@@ -875,21 +914,30 @@ function describe(schedule, opts) {
|
|
|
875
914
|
}
|
|
876
915
|
function normalizeOptions(options) {
|
|
877
916
|
options = options || {};
|
|
917
|
+
const style = resolveDialect(options.dialect);
|
|
918
|
+
activeVariant = style.variant;
|
|
878
919
|
return {
|
|
879
920
|
ampm: typeof options.ampm === "boolean" ? options.ampm : false,
|
|
880
921
|
lenient: !!options.lenient,
|
|
881
922
|
seconds: !!options.seconds,
|
|
882
923
|
short: !!options.short,
|
|
883
|
-
style
|
|
924
|
+
style,
|
|
884
925
|
years: !!options.years
|
|
885
926
|
};
|
|
886
927
|
}
|
|
887
928
|
var zh2 = {
|
|
888
929
|
describe,
|
|
889
|
-
fallback
|
|
930
|
+
// `reboot`/`fallback` are contract-fixed strings the core reads without
|
|
931
|
+
// `opts`; getters honor the variant `options()` latched, keeping the shared
|
|
932
|
+
// Language contract unchanged while the Traditional dialect still applies.
|
|
933
|
+
get fallback() {
|
|
934
|
+
return toVariant("\u65E0\u6CD5\u8BC6\u522B\u7684 cron \u8868\u8FBE\u5F0F", activeVariant);
|
|
935
|
+
},
|
|
890
936
|
options: normalizeOptions,
|
|
891
|
-
reboot
|
|
892
|
-
|
|
937
|
+
get reboot() {
|
|
938
|
+
return toVariant("\u7CFB\u7EDF\u542F\u52A8\u65F6", activeVariant);
|
|
939
|
+
},
|
|
940
|
+
sentence: (description) => toVariant("\u8FD0\u884C\u65F6\u95F4\uFF1A", activeVariant) + description + "\u3002"
|
|
893
941
|
};
|
|
894
942
|
var index_default = zh2;
|
|
895
943
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cronli5",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "Cron Like I'm Five: A Cron to English Utility",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,6 +37,16 @@
|
|
|
37
37
|
"import": "./dist/lang/fi.js",
|
|
38
38
|
"require": "./dist/lang/fi.cjs"
|
|
39
39
|
},
|
|
40
|
+
"./lang/fr": {
|
|
41
|
+
"types": "./types/lang/fr/index.d.ts",
|
|
42
|
+
"import": "./dist/lang/fr.js",
|
|
43
|
+
"require": "./dist/lang/fr.cjs"
|
|
44
|
+
},
|
|
45
|
+
"./lang/pt": {
|
|
46
|
+
"types": "./types/lang/pt/index.d.ts",
|
|
47
|
+
"import": "./dist/lang/pt.js",
|
|
48
|
+
"require": "./dist/lang/pt.cjs"
|
|
49
|
+
},
|
|
40
50
|
"./lang/zh": {
|
|
41
51
|
"types": "./types/lang/zh/index.d.ts",
|
|
42
52
|
"import": "./dist/lang/zh.js",
|
|
@@ -61,6 +71,7 @@
|
|
|
61
71
|
"build": "node scripts/build.mjs && npm run types",
|
|
62
72
|
"docs": "node --import tsx scripts/docs.mjs",
|
|
63
73
|
"conciseness": "node --import tsx tooling/scripts/conciseness.mjs",
|
|
74
|
+
"divergence": "node --import tsx tooling/scripts/cronstrue-divergence.mjs",
|
|
64
75
|
"fuzz": "node --import tsx scripts/fuzz-lang.mjs",
|
|
65
76
|
"lint": "eslint src test cli.js eslint.config.js scripts tooling/scripts",
|
|
66
77
|
"metamorphic": "node --import tsx tooling/scripts/metamorphic.mjs",
|
|
@@ -75,7 +86,7 @@
|
|
|
75
86
|
"prepublishOnly": "npm run lint && npm run typecheck && npm run test:types && npm run build && npm test"
|
|
76
87
|
},
|
|
77
88
|
"engines": {
|
|
78
|
-
"node": ">=
|
|
89
|
+
"node": ">=20"
|
|
79
90
|
},
|
|
80
91
|
"keywords": [
|
|
81
92
|
"cron",
|
package/src/core/cadence.ts
CHANGED
|
@@ -94,28 +94,41 @@ interface StrideParts {
|
|
|
94
94
|
bounded(): string;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
// The last value a stride reaches within `[0, cycle)`: the largest value below
|
|
98
|
+
// the cycle that is congruent to `start` modulo `interval`. A clean, full-field
|
|
99
|
+
// stride runs to this tile; a bounded one (`a-b/n`) stops short of it, and that
|
|
100
|
+
// shortfall is what distinguishes the open cadence from a bounded set.
|
|
101
|
+
function lastTileOf(start: number, interval: number, cycle: number): number {
|
|
102
|
+
return cycle - 1 - (cycle - 1 - start) % interval;
|
|
103
|
+
}
|
|
104
|
+
|
|
97
105
|
// Choose the stride/cadence branch for a step over a `cycle`-long field and
|
|
98
|
-
// emit the renderer's words for it. A clean stride from the top of the cycle
|
|
99
|
-
//
|
|
106
|
+
// emit the renderer's words for it. A clean stride from the top of the cycle is
|
|
107
|
+
// the bare cadence; a uniform offset (start within the first interval, the
|
|
100
108
|
// interval still tiling the cycle) names only its start, since it wraps cleanly
|
|
101
|
-
// with no distinct endpoint; a non-uniform stride (start >= interval,
|
|
102
|
-
// interval that does not tile the cycle
|
|
103
|
-
//
|
|
104
|
-
//
|
|
109
|
+
// with no distinct endpoint; a non-uniform stride (start >= interval, an
|
|
110
|
+
// interval that does not tile the cycle, or one whose last fire stops short of
|
|
111
|
+
// the cycle's final tile — a bounded `a-b/n`) pins both endpoints so the
|
|
112
|
+
// bounded, non-wrapping set reads unambiguously. This is the one decision tree
|
|
113
|
+
// every renderer's `renderStride`/`hourStrideCadence` shared (cycle 60 for
|
|
105
114
|
// minute/second, 24 for the hour); the branch lives here once, the prose in
|
|
106
115
|
// each language's `parts`.
|
|
107
116
|
function renderStride(
|
|
108
|
-
spec: {start: number; interval: number; cycle: number},
|
|
117
|
+
spec: {start: number; interval: number; last: number; cycle: number},
|
|
109
118
|
parts: StrideParts
|
|
110
119
|
): string {
|
|
111
|
-
const {start, interval, cycle} = spec;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
120
|
+
const {start, interval, last, cycle} = spec;
|
|
121
|
+
// A stride wraps the full field only when it both tiles the cycle and runs to
|
|
122
|
+
// the cycle's last tile; one that stops short (`0-20/2`, last 20 of 22) is a
|
|
123
|
+
// bounded set, not the open `*/n`, so it keeps its endpoint-pinning cadence.
|
|
124
|
+
const open = cycle % interval === 0 && last === lastTileOf(start, interval,
|
|
125
|
+
cycle);
|
|
126
|
+
|
|
127
|
+
if (start === 0 && open) {
|
|
115
128
|
return parts.bare();
|
|
116
129
|
}
|
|
117
130
|
|
|
118
|
-
if (start < interval &&
|
|
131
|
+
if (start < interval && open) {
|
|
119
132
|
return parts.offset();
|
|
120
133
|
}
|
|
121
134
|
|
package/src/lang/de/index.ts
CHANGED
|
@@ -90,7 +90,7 @@ function renderStride(stride: Stride): string {
|
|
|
90
90
|
// the cadence keeps its endpoints but drops the "jeder Stunde" tail.
|
|
91
91
|
const tail = anchor ? ' ' + anchor : '';
|
|
92
92
|
|
|
93
|
-
return chooseStride({start, interval, cycle}, {
|
|
93
|
+
return chooseStride({start, interval, last, cycle}, {
|
|
94
94
|
bare: () => cadence,
|
|
95
95
|
offset: () => cadence + ' ab ' + unit.singular + ' ' + start + tail,
|
|
96
96
|
bounded: () =>
|
|
@@ -1019,7 +1019,7 @@ function hourStrideCadence(
|
|
|
1019
1019
|
const {start, interval, last} = stride;
|
|
1020
1020
|
const cadence = everyN(interval, UNITS.hour);
|
|
1021
1021
|
|
|
1022
|
-
return chooseStride({start, interval, cycle: 24}, {
|
|
1022
|
+
return chooseStride({start, interval, last, cycle: 24}, {
|
|
1023
1023
|
bare: () => cadence,
|
|
1024
1024
|
offset: () => cadence + ' ab ' + start + ' Uhr',
|
|
1025
1025
|
bounded: () => cadence + ' von ' + start + ' bis ' + last + ' Uhr'
|
package/src/lang/en/index.ts
CHANGED
|
@@ -1313,7 +1313,7 @@ function renderStride(stride: Stride, opts: NormalizedOptions): string {
|
|
|
1313
1313
|
const {interval, start, last, cycle, unit, anchor} = stride;
|
|
1314
1314
|
const cadence = 'every ' + getNumber(interval, opts) + ' ' + unit + 's';
|
|
1315
1315
|
|
|
1316
|
-
return chooseStride({start, interval, cycle}, {
|
|
1316
|
+
return chooseStride({start, interval, last, cycle}, {
|
|
1317
1317
|
bare: () => cadence,
|
|
1318
1318
|
|
|
1319
1319
|
// A clean wrap from a non-zero offset: name the start, no endpoint.
|
|
@@ -1419,7 +1419,7 @@ function hourStrideCadence(stride: {start: number; interval: number;
|
|
|
1419
1419
|
const {start, interval, last} = stride;
|
|
1420
1420
|
const cadence = 'every ' + getNumber(interval, opts) + ' hours';
|
|
1421
1421
|
|
|
1422
|
-
return chooseStride({start, interval, cycle: 24}, {
|
|
1422
|
+
return chooseStride({start, interval, last, cycle: 24}, {
|
|
1423
1423
|
bare: () => cadence,
|
|
1424
1424
|
offset: () => cadence + ' from ' + getTime({hour: start, minute: 0}, opts),
|
|
1425
1425
|
bounded: () =>
|
package/src/lang/es/index.ts
CHANGED
|
@@ -1326,7 +1326,7 @@ function renderStride(stride: Stride, opts: Opts): string {
|
|
|
1326
1326
|
// the cadence keeps its endpoints but drops the "de cada <anchor>" tail.
|
|
1327
1327
|
const tail = anchor ? ' de cada ' + anchor : '';
|
|
1328
1328
|
|
|
1329
|
-
return chooseStride({start, interval, cycle}, {
|
|
1329
|
+
return chooseStride({start, interval, last, cycle}, {
|
|
1330
1330
|
bare: () => cadence,
|
|
1331
1331
|
offset: () => cadence + ' a partir del ' + unit + ' ' + start + tail,
|
|
1332
1332
|
bounded: () =>
|
|
@@ -1429,7 +1429,7 @@ function hourStrideCadence(
|
|
|
1429
1429
|
const {start, interval, last} = stride;
|
|
1430
1430
|
const cadence = 'cada ' + numero(interval, opts) + ' horas';
|
|
1431
1431
|
|
|
1432
|
-
return chooseStride({start, interval, cycle: 24}, {
|
|
1432
|
+
return chooseStride({start, interval, last, cycle: 24}, {
|
|
1433
1433
|
bare: () => cadence,
|
|
1434
1434
|
offset: () => cadence + ' a partir de ' + timePhrase(start, 0, null, opts),
|
|
1435
1435
|
bounded: () => cadence + ' de ' + timePhrase(start, 0, null, opts) + ' a ' +
|
package/src/lang/fi/index.ts
CHANGED
|
@@ -1108,7 +1108,7 @@ function renderStride(stride: Stride, opts: NormalizedOptions): string {
|
|
|
1108
1108
|
const {interval, start, last, cycle, unit} = stride;
|
|
1109
1109
|
const cadence = genitive(interval, opts) + ' ' + unit.gen + ' välein';
|
|
1110
1110
|
|
|
1111
|
-
return chooseStride({start, interval, cycle}, {
|
|
1111
|
+
return chooseStride({start, interval, last, cycle}, {
|
|
1112
1112
|
bare: () => cadence,
|
|
1113
1113
|
offset: () =>
|
|
1114
1114
|
cadence + ' ' + unit.anchor + ' ' + unit.ela + ' ' + start + ' alkaen',
|
|
@@ -1206,7 +1206,7 @@ function hourStrideCadence(
|
|
|
1206
1206
|
const {start, interval, last} = stride;
|
|
1207
1207
|
const cadence = genitive(interval, opts) + ' tunnin välein';
|
|
1208
1208
|
|
|
1209
|
-
return chooseStride({start, interval, cycle: 24}, {
|
|
1209
|
+
return chooseStride({start, interval, last, cycle: 24}, {
|
|
1210
1210
|
bare: () => cadence,
|
|
1211
1211
|
offset: () => cadence + ' klo ' + hourElatives[start] + ' alkaen',
|
|
1212
1212
|
bounded: () => cadence + ' ' +
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// French dialect style tables. Dialect names are language-scoped; the default
|
|
2
|
+
// `fr` style is anchored to the fr-FR norm (Imprimerie nationale / Académie
|
|
3
|
+
// française, plus cronstrue `fr`); see notes.md. Custom objects merge over the
|
|
4
|
+
// `fr` defaults. fr-CA is a future dialect axis (notes.md §"Dialect axis"); no
|
|
5
|
+
// regional dialect ships yet.
|
|
6
|
+
import type {Cronli5Options} from '../../types.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* French's own resolved style shape: a separator and the spacing of the `h`
|
|
10
|
+
* clock mark. fr is 24-hour only, so there is no `ampm`/`meridiem` axis.
|
|
11
|
+
*/
|
|
12
|
+
export interface FrenchStyle {
|
|
13
|
+
// The mark between hour and minute on the default clock. fr-FR writes the
|
|
14
|
+
// typographic "h" ("9 h 30"); a custom style can opt into a colon or other
|
|
15
|
+
// separator ("9:30"), which replaces the spaced "h" form entirely.
|
|
16
|
+
sep: string;
|
|
17
|
+
// When `sep` is the default "h", whether to drop the surrounding spaces. The
|
|
18
|
+
// spaced "9 h 30" is the ratified fr-FR default; the unspaced "9h30" is the
|
|
19
|
+
// opt-in casual register (notes.md §Dialect axis).
|
|
20
|
+
unspaced: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// The fr-FR default: the spaced "h" clock mark.
|
|
24
|
+
const fr: FrenchStyle = {
|
|
25
|
+
sep: 'h',
|
|
26
|
+
unspaced: false
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// One `fr` table today = fr-FR. fr-CA is a future dialect axis (notes.md);
|
|
30
|
+
// it would clear its own native panel before shipping, so it is not declared
|
|
31
|
+
// here yet.
|
|
32
|
+
const dialects: {[name: string]: FrenchStyle} = {
|
|
33
|
+
fr,
|
|
34
|
+
// France is the default; named explicitly so it is a recognized choice and
|
|
35
|
+
// has a home if it ever diverges.
|
|
36
|
+
'fr-FR': fr
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Resolve the `dialect` option to a style table.
|
|
40
|
+
function resolveDialect(dialect: Cronli5Options['dialect']): FrenchStyle {
|
|
41
|
+
if (typeof dialect === 'object' && dialect !== null) {
|
|
42
|
+
return {...dialects.fr, ...dialect};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// A string dialect indexes the table; unknown names fall back to `fr`.
|
|
46
|
+
return dialects[dialect as string] || dialects.fr;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export {resolveDialect};
|