@jackens/nnn 2026.8.24 → 2026.8.31
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/nnn.d.ts +0 -37
- package/nnn.js +10 -11
- package/package.json +1 -2
- package/readme.md +1 -79
package/nnn.d.ts
CHANGED
|
@@ -64,43 +64,6 @@ export declare const c: (root: CRoot, splitter?: string) => string;
|
|
|
64
64
|
* using the provided escape map.
|
|
65
65
|
*/
|
|
66
66
|
export declare const createEscape: (escapeFn: (value: any) => string) => (template: TemplateStringsArray, ...values: unknown[]) => string;
|
|
67
|
-
/**
|
|
68
|
-
* Creates a function that
|
|
69
|
-
* returns the appropriate noun form
|
|
70
|
-
* based on a numeric value using `Intl.PluralRules`.
|
|
71
|
-
*
|
|
72
|
-
* Different languages have different plural rules.
|
|
73
|
-
* The `Intl.PluralRules` API provides locale-aware
|
|
74
|
-
* plural category selection.
|
|
75
|
-
* Possible categories are:
|
|
76
|
-
*
|
|
77
|
-
* - `zero`: for zero items
|
|
78
|
-
* (used in some languages like Arabic, Latvian)
|
|
79
|
-
* - `one`: for singular (e.g., 1 item)
|
|
80
|
-
* - `two`: for dual
|
|
81
|
-
* (used in some languages like Arabic, Hebrew)
|
|
82
|
-
* - `few`: for small plurals (e.g., 2-4 in Polish)
|
|
83
|
-
* - `many`: for larger plurals (e.g., 5-21 in Polish)
|
|
84
|
-
* - `other`: fallback category (used by all languages)
|
|
85
|
-
*
|
|
86
|
-
* @param locale
|
|
87
|
-
*
|
|
88
|
-
* A BCP 47 language tag (e.g., `pl`, `en`).
|
|
89
|
-
*
|
|
90
|
-
* @param forms
|
|
91
|
-
*
|
|
92
|
-
* An object mapping plural categories to noun forms.
|
|
93
|
-
* Not all categories need to be provided;
|
|
94
|
-
* if a category is missing,
|
|
95
|
-
* the function falls back to `other`,
|
|
96
|
-
* then to an empty string.
|
|
97
|
-
*
|
|
98
|
-
* @returns
|
|
99
|
-
*
|
|
100
|
-
* A function that takes a numeric value
|
|
101
|
-
* and returns the appropriate noun form.
|
|
102
|
-
*/
|
|
103
|
-
export declare const createPluralRules: (locale: string, forms: Partial<Record<Intl.LDMLPluralRule, string>>) => (value: number) => string;
|
|
104
67
|
/**
|
|
105
68
|
* A helper for building simple tokenizers
|
|
106
69
|
* (see also {@link nanolightTs}).
|
package/nnn.js
CHANGED
|
@@ -6,6 +6,8 @@ var isString = (arg) => typeof arg === "string";
|
|
|
6
6
|
var isRecord = (arg) => typeof arg === "object" && arg != null && !isArray(arg);
|
|
7
7
|
|
|
8
8
|
// src/nnn/c.ts
|
|
9
|
+
var DEFAULT_SPLITTER = "$$";
|
|
10
|
+
var getName = (key, splitter = DEFAULT_SPLITTER) => key.split(splitter)[0].replace(/_/g, "-").replace(/([A-Z])/g, (_, letter) => "-" + letter.toLowerCase());
|
|
9
11
|
var _c = (node, prefix, result, splitter) => {
|
|
10
12
|
const queue = [[node, prefix]];
|
|
11
13
|
while (queue.length > 0) {
|
|
@@ -18,19 +20,19 @@ var _c = (node, prefix, result, splitter) => {
|
|
|
18
20
|
let attributesPushed = false;
|
|
19
21
|
for (const key in style0) {
|
|
20
22
|
const value = style0[key];
|
|
23
|
+
const name = getName(key, splitter);
|
|
21
24
|
if (isString(value) || isNumber(value)) {
|
|
22
25
|
if (!attributesPushed) {
|
|
23
26
|
attributesPushed = true;
|
|
24
27
|
attributes = [];
|
|
25
28
|
todo.push([attributes, prefix0]);
|
|
26
29
|
}
|
|
27
|
-
|
|
28
|
-
attributes.push(`${attribute}:${value}`);
|
|
30
|
+
attributes.push(`${name}:${value}`);
|
|
29
31
|
} else if (value != null) {
|
|
30
32
|
attributesPushed = false;
|
|
31
33
|
const prefixN = [];
|
|
32
|
-
const
|
|
33
|
-
prefix0.split(",").forEach((prefixChunk) =>
|
|
34
|
+
const nameChunks = name.split(",");
|
|
35
|
+
prefix0.split(",").forEach((prefixChunk) => nameChunks.forEach((nameChunk) => prefixN.push(prefixChunk + nameChunk)));
|
|
34
36
|
todo.push([value, prefixN.join()]);
|
|
35
37
|
}
|
|
36
38
|
}
|
|
@@ -38,17 +40,18 @@ var _c = (node, prefix, result, splitter) => {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
};
|
|
41
|
-
var c = (root, splitter =
|
|
43
|
+
var c = (root, splitter = DEFAULT_SPLITTER) => {
|
|
42
44
|
const chunks = [];
|
|
43
45
|
for (const key in root) {
|
|
44
46
|
const value = root[key];
|
|
47
|
+
const name = getName(key, splitter);
|
|
45
48
|
if (value != null) {
|
|
46
49
|
if (key[0] === "@") {
|
|
47
|
-
chunks.push(
|
|
50
|
+
chunks.push(name + "{");
|
|
48
51
|
_c(value, "", chunks, splitter);
|
|
49
52
|
chunks.push("}");
|
|
50
53
|
} else {
|
|
51
|
-
_c(value,
|
|
54
|
+
_c(value, name, chunks, splitter);
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
}
|
|
@@ -56,9 +59,6 @@ var c = (root, splitter = "$$") => {
|
|
|
56
59
|
};
|
|
57
60
|
// src/nnn/createEscape.ts
|
|
58
61
|
var createEscape = (escapeFn) => (template, ...values) => String.raw(template, ...values.map(escapeFn));
|
|
59
|
-
// src/nnn/createPluralRules.ts
|
|
60
|
-
var PLURAL_RULES = {};
|
|
61
|
-
var createPluralRules = (locale, forms) => (value) => forms[(PLURAL_RULES[locale] ??= new Intl.PluralRules(locale)).select(value)] ?? forms.other ?? "";
|
|
62
62
|
// src/nnn/createTokenizer.ts
|
|
63
63
|
var createTokenizer = (decorator, ...specs) => (code) => {
|
|
64
64
|
const result = [];
|
|
@@ -358,7 +358,6 @@ var vivify = (ref) => _vivify({ _: ref }, "_");
|
|
|
358
358
|
export {
|
|
359
359
|
c,
|
|
360
360
|
createEscape,
|
|
361
|
-
createPluralRules as createNounForm,
|
|
362
361
|
createTokenizer,
|
|
363
362
|
csvParse,
|
|
364
363
|
fixPlTypography,
|
package/package.json
CHANGED
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"Monokai",
|
|
26
26
|
"nanolight",
|
|
27
27
|
"nnn",
|
|
28
|
-
"noun form",
|
|
29
28
|
"omit",
|
|
30
29
|
"pick",
|
|
31
30
|
"Responsive Web Design",
|
|
@@ -44,5 +43,5 @@
|
|
|
44
43
|
"name": "@jackens/nnn",
|
|
45
44
|
"type": "module",
|
|
46
45
|
"types": "nnn.d.ts",
|
|
47
|
-
"version": "2026.8.
|
|
46
|
+
"version": "2026.8.31"
|
|
48
47
|
}
|
package/readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nnn
|
|
2
2
|
|
|
3
|
-
A collection of Jackens’ JavaScript helper utilities (version: `2026.8.
|
|
3
|
+
A collection of Jackens’ JavaScript helper utilities (version: `2026.8.31`).
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -20,7 +20,6 @@ npm i @jackens/nnn
|
|
|
20
20
|
import {
|
|
21
21
|
c,
|
|
22
22
|
createEscape,
|
|
23
|
-
createPluralRules,
|
|
24
23
|
createTokenizer,
|
|
25
24
|
csvParse,
|
|
26
25
|
fixPlTypography,
|
|
@@ -64,10 +63,6 @@ import {
|
|
|
64
63
|
- [`createEscape`](#createEscape):
|
|
65
64
|
Creates a tag function
|
|
66
65
|
for escaping interpolated values in template literals.
|
|
67
|
-
- [`createPluralRules`](#createPluralRules):
|
|
68
|
-
Creates a function that
|
|
69
|
-
returns the appropriate noun form
|
|
70
|
-
based on a numeric value using `Intl.PluralRules`.
|
|
71
66
|
- [`createTokenizer`](#createTokenizer):
|
|
72
67
|
A helper for building simple tokenizers
|
|
73
68
|
(see also [`nanolightTs`](#nanolightTs)).
|
|
@@ -466,79 +461,6 @@ const expected = `
|
|
|
466
461
|
expect(actual).to.equal(expected)
|
|
467
462
|
```
|
|
468
463
|
|
|
469
|
-
### createPluralRules
|
|
470
|
-
|
|
471
|
-
```ts
|
|
472
|
-
const createPluralRules: (locale: string, forms: Partial<Record<Intl.LDMLPluralRule, string>>) => (value: number) => string;
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
Creates a function that
|
|
476
|
-
returns the appropriate noun form
|
|
477
|
-
based on a numeric value using `Intl.PluralRules`.
|
|
478
|
-
|
|
479
|
-
Different languages have different plural rules.
|
|
480
|
-
The `Intl.PluralRules` API provides locale-aware
|
|
481
|
-
plural category selection.
|
|
482
|
-
Possible categories are:
|
|
483
|
-
|
|
484
|
-
- `zero`: for zero items
|
|
485
|
-
(used in some languages like Arabic, Latvian)
|
|
486
|
-
- `one`: for singular (e.g., 1 item)
|
|
487
|
-
- `two`: for dual
|
|
488
|
-
(used in some languages like Arabic, Hebrew)
|
|
489
|
-
- `few`: for small plurals (e.g., 2-4 in Polish)
|
|
490
|
-
- `many`: for larger plurals (e.g., 5-21 in Polish)
|
|
491
|
-
- `other`: fallback category (used by all languages)
|
|
492
|
-
|
|
493
|
-
#### locale
|
|
494
|
-
|
|
495
|
-
A BCP 47 language tag (e.g., `pl`, `en`).
|
|
496
|
-
|
|
497
|
-
#### forms
|
|
498
|
-
|
|
499
|
-
An object mapping plural categories to noun forms.
|
|
500
|
-
Not all categories need to be provided;
|
|
501
|
-
if a category is missing,
|
|
502
|
-
the function falls back to `other`,
|
|
503
|
-
then to an empty string.
|
|
504
|
-
|
|
505
|
-
#### Returns
|
|
506
|
-
|
|
507
|
-
A function that takes a numeric value
|
|
508
|
-
and returns the appropriate noun form.
|
|
509
|
-
|
|
510
|
-
#### Usage Examples
|
|
511
|
-
|
|
512
|
-
```ts
|
|
513
|
-
const auto = createPluralRules('pl', {
|
|
514
|
-
one: 'auto',
|
|
515
|
-
few: 'auta',
|
|
516
|
-
other: 'aut',
|
|
517
|
-
})
|
|
518
|
-
|
|
519
|
-
expect(auto(0)).to.equal('aut')
|
|
520
|
-
expect(auto(1)).to.equal('auto')
|
|
521
|
-
expect(auto(17)).to.equal('aut')
|
|
522
|
-
expect(auto(42)).to.equal('auta')
|
|
523
|
-
|
|
524
|
-
const car = createPluralRules('en', {
|
|
525
|
-
one: 'car',
|
|
526
|
-
other: 'cars',
|
|
527
|
-
})
|
|
528
|
-
|
|
529
|
-
expect(car(0)).to.equal('cars')
|
|
530
|
-
expect(car(1)).to.equal('car')
|
|
531
|
-
expect(car(17)).to.equal('cars')
|
|
532
|
-
expect(car(42)).to.equal('cars')
|
|
533
|
-
|
|
534
|
-
const empty = createPluralRules('en', {})
|
|
535
|
-
|
|
536
|
-
expect(empty(0)).to.equal('')
|
|
537
|
-
expect(empty(1)).to.equal('')
|
|
538
|
-
expect(empty(17)).to.equal('')
|
|
539
|
-
expect(empty(42)).to.equal('')
|
|
540
|
-
```
|
|
541
|
-
|
|
542
464
|
### createTokenizer
|
|
543
465
|
|
|
544
466
|
```ts
|