@jackens/nnn 2025.12.13 → 2025.12.23
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 +58 -70
- package/nnn.js +58 -10
- package/package.json +8 -5
- package/readme.md +113 -107
package/nnn.d.ts
CHANGED
|
@@ -62,7 +62,6 @@ export declare const c: (root: CRoot, splitter?: string) => string;
|
|
|
62
62
|
* - `height` (optional, default `1`): number of vertical cells the element spans.
|
|
63
63
|
*/
|
|
64
64
|
export declare const rwd: (root: CRoot, selector: string, cell_width_px: number, cell_height_px: number, ...specs: [number, number?, number?][]) => void;
|
|
65
|
-
|
|
66
65
|
/**
|
|
67
66
|
* Parses a CSV string into a two-dimensional array of strings.
|
|
68
67
|
*
|
|
@@ -81,11 +80,10 @@ export declare const rwd: (root: CRoot, selector: string, cell_width_px: number,
|
|
|
81
80
|
* A 2D array where each inner array represents a row of fields.
|
|
82
81
|
*/
|
|
83
82
|
export declare const csv_parse: (csv: string, separator?: string) => string[][];
|
|
84
|
-
|
|
85
83
|
/**
|
|
86
84
|
* A map from value constructors (or `null`/`undefined`) to escape functions.
|
|
87
85
|
*
|
|
88
|
-
* Used by {@link escape_values} and {@link
|
|
86
|
+
* Used by {@link escape_values} and {@link new_escape}.
|
|
89
87
|
*/
|
|
90
88
|
export type EscapeMap = Map<unknown, (value?: unknown) => string>;
|
|
91
89
|
/**
|
|
@@ -105,26 +103,17 @@ export type EscapeMap = Map<unknown, (value?: unknown) => string>;
|
|
|
105
103
|
*/
|
|
106
104
|
export declare const escape_values: (escape_map: EscapeMap, values: unknown[]) => string[];
|
|
107
105
|
/**
|
|
108
|
-
*
|
|
106
|
+
* Creates a tag function for escaping interpolated values in template literals.
|
|
109
107
|
*
|
|
110
108
|
* @param escape_map
|
|
111
109
|
*
|
|
112
110
|
* A map where keys are constructors and values are escape functions.
|
|
113
111
|
*
|
|
114
|
-
* @param template
|
|
115
|
-
*
|
|
116
|
-
* The template strings array from the tagged template.
|
|
117
|
-
*
|
|
118
|
-
* @param values
|
|
119
|
-
*
|
|
120
|
-
* The interpolated values to escape.
|
|
121
|
-
*
|
|
122
112
|
* @returns
|
|
123
113
|
*
|
|
124
|
-
*
|
|
114
|
+
* A tag function that escapes interpolated values using the provided escape map.
|
|
125
115
|
*/
|
|
126
|
-
export declare const
|
|
127
|
-
|
|
116
|
+
export declare const new_escape: (escape_map: EscapeMap) => (template: TemplateStringsArray, ...values: unknown[]) => string;
|
|
128
117
|
/**
|
|
129
118
|
* Applies Polish-specific typographic corrections to a DOM subtree.
|
|
130
119
|
*
|
|
@@ -138,7 +127,6 @@ export declare const escape: (escape_map: EscapeMap, template: TemplateStringsAr
|
|
|
138
127
|
* except those inside `IFRAME`, `NOSCRIPT`, `PRE`, `SCRIPT`, `STYLE`, or `TEXTAREA` elements.
|
|
139
128
|
*/
|
|
140
129
|
export declare const fix_typography: (node: Node) => void;
|
|
141
|
-
|
|
142
130
|
/**
|
|
143
131
|
* Single argument type for the {@link h} and {@link s} helpers.
|
|
144
132
|
*/
|
|
@@ -221,7 +209,6 @@ export declare const s: {
|
|
|
221
209
|
* An `SVGSVGElement` containing a `<use>` element.
|
|
222
210
|
*/
|
|
223
211
|
export declare const svg_use: (id: string, ...args: HArgs1[]) => SVGSVGElement;
|
|
224
|
-
|
|
225
212
|
/**
|
|
226
213
|
* Checks whether an object has the specified key as its own property.
|
|
227
214
|
*
|
|
@@ -240,7 +227,6 @@ export declare const svg_use: (id: string, ...args: HArgs1[]) => SVGSVGElement;
|
|
|
240
227
|
* `true` if `ref` is not nullish and has `key` as an own property, `false` otherwise.
|
|
241
228
|
*/
|
|
242
229
|
export declare const has_own: (ref: unknown, key: unknown) => boolean;
|
|
243
|
-
|
|
244
230
|
/**
|
|
245
231
|
* Checks whether the argument is an array.
|
|
246
232
|
*
|
|
@@ -301,7 +287,6 @@ export declare const is_record: (arg: unknown) => arg is Record<PropertyKey, unk
|
|
|
301
287
|
* `true` if `typeof arg === 'string'`, `false` otherwise.
|
|
302
288
|
*/
|
|
303
289
|
export declare const is_string: (arg: unknown) => arg is string;
|
|
304
|
-
|
|
305
290
|
/**
|
|
306
291
|
* Parses JSON with support for handler-based value transformation (“JavaScript ON”).
|
|
307
292
|
*
|
|
@@ -321,7 +306,19 @@ export declare const is_string: (arg: unknown) => arg is string;
|
|
|
321
306
|
* The parsed value with handler substitutions applied.
|
|
322
307
|
*/
|
|
323
308
|
export declare const js_on_parse: (handlers: Record<PropertyKey, Function>, text: string) => any;
|
|
324
|
-
|
|
309
|
+
/**
|
|
310
|
+
* A Monokai-inspired color scheme for use with the {@link c} helper and {@link nanolight_ts} tokenizer.
|
|
311
|
+
*
|
|
312
|
+
* Defines CSS custom properties for eight colors (`--black`, `--blue`, `--green`, `--grey`,
|
|
313
|
+
* `--purple`, `--red`, `--white`, `--yellow`) with both light and dark mode variants.
|
|
314
|
+
*
|
|
315
|
+
* @remarks
|
|
316
|
+
*
|
|
317
|
+
* - In light mode, `--black` is a light background and `--white` is dark text.
|
|
318
|
+
* - In dark mode (via `prefers-color-scheme: dark`), the palette inverts to a dark background with light text.
|
|
319
|
+
* - Includes base styles for `body`, `pre` and `code>span.*` (syntax highlighting).
|
|
320
|
+
*/
|
|
321
|
+
export declare const monokai: CRoot;
|
|
325
322
|
/**
|
|
326
323
|
* A TypeScript/JavaScript syntax highlighting tokenizer built using {@link new_tokenizer}.
|
|
327
324
|
*
|
|
@@ -331,37 +328,34 @@ export declare const js_on_parse: (handlers: Record<PropertyKey, Function>, text
|
|
|
331
328
|
*
|
|
332
329
|
* @returns
|
|
333
330
|
*
|
|
334
|
-
* An array of {@link HArgs1} elements suitable for rendering with {@link h}
|
|
331
|
+
* An array of {@link HArgs1} elements suitable for rendering with {@link h}.
|
|
335
332
|
*/
|
|
336
333
|
export declare const nanolight_ts: (code: string) => HArgs1[];
|
|
337
|
-
|
|
338
334
|
/**
|
|
339
|
-
*
|
|
335
|
+
* Creates a function that returns the appropriate Polish noun form based on a numeric value.
|
|
340
336
|
*
|
|
341
|
-
*
|
|
337
|
+
* Polish has three plural forms depending on the number:
|
|
338
|
+
* - Singular: used for exactly 1.
|
|
339
|
+
* - “Plural 2-4”: used for 2, 3, 4, 22, 23, 24, etc. (but not 12, 13, 14).
|
|
340
|
+
* - “Plural 5+”: used for 0, 5–21, 25–31, etc.
|
|
342
341
|
*
|
|
343
|
-
*
|
|
344
|
-
* and optionally the `metadata` associated with the pattern that produced the match.
|
|
345
|
-
* For unmatched text between patterns, `metadata` is `undefined`.
|
|
342
|
+
* @param singular
|
|
346
343
|
*
|
|
347
|
-
*
|
|
344
|
+
* The singular form (e.g., “auto” for “car”).
|
|
348
345
|
*
|
|
349
|
-
*
|
|
350
|
-
* - `metadata`: arbitrary data (e.g., a CSS class name) passed to `decorator` when the pattern matches.
|
|
351
|
-
* - `pattern`: a `string` or `RegExp` to match against the input.
|
|
346
|
+
* @param plural_2
|
|
352
347
|
*
|
|
353
|
-
*
|
|
348
|
+
* The form for 2, 3, 4 (e.g., “auta”).
|
|
354
349
|
*
|
|
355
|
-
*
|
|
350
|
+
* @param plural_5
|
|
356
351
|
*
|
|
357
|
-
*
|
|
352
|
+
* The form for 5+ (e.g., “aut”).
|
|
358
353
|
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
354
|
+
* @returns
|
|
355
|
+
*
|
|
356
|
+
* A function that takes a numeric value and returns the appropriate noun form.
|
|
362
357
|
*/
|
|
363
|
-
export declare const
|
|
364
|
-
|
|
358
|
+
export declare const new_noun_form: (singular: string, plural_2: string, plural_5: string) => (value: number) => string;
|
|
365
359
|
/**
|
|
366
360
|
* Creates a new object containing only the specified keys from the source object.
|
|
367
361
|
*
|
|
@@ -398,53 +392,47 @@ export declare const pick: <T, K extends keyof T>(ref: T, keys: K[]) => Pick<T,
|
|
|
398
392
|
* A new object without the specified keys.
|
|
399
393
|
*/
|
|
400
394
|
export declare const omit: <T, K extends keyof T>(ref: T, keys: unknown[]) => Omit<T, K>;
|
|
401
|
-
|
|
402
395
|
/**
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
* Polish has three plural forms depending on the number:
|
|
406
|
-
* - Singular: used for exactly 1.
|
|
407
|
-
* - “Plural 2-4”: used for 2, 3, 4, 22, 23, 24, etc. (but not 12, 13, 14).
|
|
408
|
-
* - “Plural 5+”: used for 0, 5–21, 25–31, etc.
|
|
409
|
-
*
|
|
410
|
-
* @param singular
|
|
411
|
-
*
|
|
412
|
-
* The singular form (e.g., “auto” for “car”).
|
|
413
|
-
*
|
|
414
|
-
* @param plural_2
|
|
415
|
-
*
|
|
416
|
-
* The form for 2, 3, 4 (e.g., “auta”).
|
|
417
|
-
*
|
|
418
|
-
* @param plural_5
|
|
396
|
+
* A Proxy-based helper for auto-vivification of nested object structures.
|
|
419
397
|
*
|
|
420
|
-
*
|
|
398
|
+
* Accessing any property on the returned proxy automatically creates an empty object if the property does not exist,
|
|
399
|
+
* allowing deep assignments without explicit null checks.
|
|
421
400
|
*
|
|
422
|
-
* @param
|
|
401
|
+
* @param ref
|
|
423
402
|
*
|
|
424
|
-
* The
|
|
403
|
+
* The root object to wrap.
|
|
425
404
|
*
|
|
426
405
|
* @returns
|
|
427
406
|
*
|
|
428
|
-
*
|
|
407
|
+
* A proxy that auto-creates nested objects on property access.
|
|
429
408
|
*/
|
|
430
|
-
export declare const
|
|
431
|
-
|
|
409
|
+
export declare const pro: (ref: unknown) => any;
|
|
432
410
|
/**
|
|
433
|
-
* A
|
|
411
|
+
* A helper for building simple tokenizers (see also {@link nanolight_ts}).
|
|
434
412
|
*
|
|
435
|
-
*
|
|
436
|
-
* allowing deep assignments without explicit null checks.
|
|
413
|
+
* @param decorator
|
|
437
414
|
*
|
|
438
|
-
*
|
|
415
|
+
* A function that wraps each matched chunk. It receives the matched text (`chunk`)
|
|
416
|
+
* and optionally the `metadata` associated with the pattern that produced the match.
|
|
417
|
+
* For unmatched text between patterns, `metadata` is `undefined`.
|
|
439
418
|
*
|
|
440
|
-
*
|
|
419
|
+
* @param specs
|
|
420
|
+
*
|
|
421
|
+
* An array of tuples `[metadata, pattern]` where:
|
|
422
|
+
* - `metadata`: arbitrary data (e.g., a CSS class name) passed to `decorator` when the pattern matches.
|
|
423
|
+
* - `pattern`: a `string` or `RegExp` to match against the input.
|
|
441
424
|
*
|
|
442
425
|
* @returns
|
|
443
426
|
*
|
|
444
|
-
* A
|
|
427
|
+
* A tokenizer function that accepts a code string and returns an array of decorated tokens.
|
|
428
|
+
*
|
|
429
|
+
* @remarks
|
|
430
|
+
*
|
|
431
|
+
* 1. Matches starting at an earlier position take precedence.
|
|
432
|
+
* 2. Among matches at the same position, the longer one wins.
|
|
433
|
+
* 3. Among matches of the same position and length, the one defined earlier wins.
|
|
445
434
|
*/
|
|
446
|
-
export declare const
|
|
447
|
-
|
|
435
|
+
export declare const new_tokenizer: <M, T>(decorator: (chunk: string, metadata?: M) => T, ...specs: [M, string | RegExp][]) => (code: string) => T[];
|
|
448
436
|
/**
|
|
449
437
|
* Generates a UUID v1 (time-based) identifier.
|
|
450
438
|
*
|
package/nnn.js
CHANGED
|
@@ -94,7 +94,7 @@ var csv_parse = (csv, separator = ",") => {
|
|
|
94
94
|
};
|
|
95
95
|
// src/nnn/escape.ts
|
|
96
96
|
var escape_values = (escape_map, values) => values.map((value) => (value == null ? escape_map.get(value) : escape_map.get(value?.constructor))?.(value) ?? "");
|
|
97
|
-
var
|
|
97
|
+
var new_escape = (escape_map) => (template, ...values) => String.raw(template, ...escape_values(escape_map, values));
|
|
98
98
|
// src/nnn/h.ts
|
|
99
99
|
var _h = (namespace_uri) => {
|
|
100
100
|
const create_element = namespace_uri == null ? (tag) => document.createElement(tag) : (tag) => document.createElementNS(namespace_uri, tag);
|
|
@@ -209,7 +209,54 @@ var js_on_parse = (handlers, text) => JSON.parse(text, (key, value) => {
|
|
|
209
209
|
}
|
|
210
210
|
return value;
|
|
211
211
|
});
|
|
212
|
-
// src/nnn/
|
|
212
|
+
// src/nnn/monokai.ts
|
|
213
|
+
var monokai = {
|
|
214
|
+
":root": {
|
|
215
|
+
__black: "$faf4f2",
|
|
216
|
+
__blue: "#1c8ca8",
|
|
217
|
+
__green: "#269d69",
|
|
218
|
+
__grey: "#918c8e",
|
|
219
|
+
__purple: "#7058be",
|
|
220
|
+
__red: "#e14775",
|
|
221
|
+
__white: "#29242a",
|
|
222
|
+
__yellow: "#cc7a0a"
|
|
223
|
+
},
|
|
224
|
+
body$$monokai: {
|
|
225
|
+
backgroundColor: "var(--black)",
|
|
226
|
+
color: "var(--white)"
|
|
227
|
+
},
|
|
228
|
+
"code>span.": {
|
|
229
|
+
black: { color: "var(--black)" },
|
|
230
|
+
blue: { color: "var(--blue)" },
|
|
231
|
+
green: { color: "var(--green)" },
|
|
232
|
+
grey: { color: "var(--grey)" },
|
|
233
|
+
purple: { color: "var(--purple)" },
|
|
234
|
+
red: { color: "var(--red)" },
|
|
235
|
+
white: { color: "var(--white)" },
|
|
236
|
+
yellow: { color: "var(--yellow)" }
|
|
237
|
+
},
|
|
238
|
+
pre: {
|
|
239
|
+
margin: 0,
|
|
240
|
+
overflow: "visible",
|
|
241
|
+
" code": {
|
|
242
|
+
fontFamily: '"Source Code Pro"',
|
|
243
|
+
padding: 0
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
"@media only screen and (prefers-color-scheme: dark)": {
|
|
247
|
+
":root": {
|
|
248
|
+
__black: "#2d2a2e",
|
|
249
|
+
__blue: "#66d9ef",
|
|
250
|
+
__green: "#a9dc76",
|
|
251
|
+
__grey: "#727072",
|
|
252
|
+
__purple: "#ae81ff",
|
|
253
|
+
__red: "#ff6188",
|
|
254
|
+
__white: "#fcfcfa",
|
|
255
|
+
__yellow: "#ffd866"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
// src/nnn/tokenizer.ts
|
|
213
260
|
var new_tokenizer = (decorator, ...specs) => (code) => {
|
|
214
261
|
const result = [];
|
|
215
262
|
while (code.length > 0) {
|
|
@@ -256,16 +303,16 @@ var PURPLE = "purple";
|
|
|
256
303
|
var RED = "red";
|
|
257
304
|
var WHITE = "white";
|
|
258
305
|
var YELLOW = "yellow";
|
|
259
|
-
var nanolight_ts = /* @__PURE__ */ new_tokenizer((chunk, name) => name != null ? ["span", { class: name }, chunk] : chunk, [YELLOW, /".*?"/], [YELLOW, /'.*?'/], [YELLOW, /`[\s\S]*?`/], [GREY, "("], [GREY, ")"], [GREY, ","], [GREY, "."], [GREY, ":"], [GREY, ";"], [GREY, "
|
|
260
|
-
// src/nnn/
|
|
261
|
-
var
|
|
262
|
-
var omit = (ref, keys) => Object.fromEntries(Object.entries(ref).filter(([key]) => !keys.includes(key)));
|
|
263
|
-
// src/nnn/pl_ural.ts
|
|
264
|
-
var pl_ural = (singular, plural_2, plural_5, value) => {
|
|
306
|
+
var nanolight_ts = /* @__PURE__ */ new_tokenizer((chunk, name) => name != null ? ["span", { class: name }, chunk] : chunk, [YELLOW, /".*?"/], [YELLOW, /'.*?'/], [YELLOW, /`[\s\S]*?`/], [RED, "?"], [RED, /(?<=\s):/], [GREY, "("], [GREY, ")"], [GREY, ","], [GREY, "."], [GREY, ":"], [GREY, ";"], [GREY, "?."], [GREY, "["], [GREY, "]"], [GREY, "{"], [GREY, "}"], [GREY, /\/\*[\s\S]*?\*\//], [GREY, /(?<!\\)\/\/.*?(?=\n)/], [RED, "!"], [RED, "!="], [RED, "!=="], [RED, "%"], [RED, "%="], [RED, "&&"], [RED, "&&="], [RED, "&"], [RED, "&="], [RED, "*"], [RED, "**"], [RED, "**="], [RED, "*="], [RED, "+"], [RED, "++"], [RED, "+="], [RED, "-"], [RED, "--"], [RED, "-="], [RED, "..."], [RED, "/"], [RED, "/="], [RED, ":"], [RED, "<"], [RED, "<<"], [RED, "<<="], [RED, "<="], [RED, "="], [RED, "=="], [RED, "==="], [RED, "=>"], [RED, ">"], [RED, ">="], [RED, ">>"], [RED, ">>="], [RED, ">>>"], [RED, ">>>="], [RED, "?"], [RED, "??"], [RED, "??="], [RED, "^"], [RED, "^="], [RED, "as"], [RED, "async"], [RED, "await"], [RED, "break"], [RED, "case"], [RED, "catch"], [RED, "class"], [RED, "const"], [RED, "continue"], [RED, "debugger"], [RED, "default"], [RED, "delete"], [RED, "do"], [RED, "else"], [RED, "export"], [RED, "extends"], [RED, "finally"], [RED, "for"], [RED, "from"], [RED, "function"], [RED, "function*"], [RED, "goto"], [RED, "if"], [RED, "import"], [RED, "in"], [RED, "instanceof"], [RED, "is"], [RED, "keyof"], [RED, "let"], [RED, "new"], [RED, "of"], [RED, "package"], [RED, "return"], [RED, "super"], [RED, "switch"], [RED, "this"], [RED, "throw"], [RED, "try"], [RED, "type"], [RED, "typeof"], [RED, "var"], [RED, "void"], [RED, "while"], [RED, "with"], [RED, "yield"], [RED, "yield*"], [RED, "|"], [RED, "|="], [RED, "||"], [RED, "||="], [RED, "~"], [RED, "~="], [PURPLE, "false"], [PURPLE, "Infinity"], [PURPLE, "NaN"], [PURPLE, "null"], [PURPLE, "true"], [PURPLE, "undefined"], [PURPLE, /0b[01_]+/], [PURPLE, /0o[01234567_]+/], [PURPLE, /0x[\dabcdef_]+/], [PURPLE, /[\p{Lu}_$][\p{Lu}\d_$]+/u], [PURPLE, /\d[\d_]*(\.[\d_]+)?(e[+-]?[\d_]+)?/], [BLUE, "any"], [BLUE, "bigint"], [BLUE, "boolean"], [BLUE, "eval"], [BLUE, "number"], [BLUE, "string"], [BLUE, "symbol"], [BLUE, "unknown"], [GREEN, /[\p{L}_$][\p{L}\d_$]+(?=\()/u], [BLUE, /\p{Lu}[\p{L}\d_$]+/u], [WHITE, /[\p{L}_$][\p{L}\d_$]+/u]);
|
|
307
|
+
// src/nnn/noun_form.ts
|
|
308
|
+
var new_noun_form = (singular, plural_2, plural_5) => (value) => {
|
|
265
309
|
const abs_value = Math.abs(value);
|
|
266
310
|
const abs_value_mod_10 = abs_value % 10;
|
|
267
311
|
return value === 1 ? singular : (abs_value_mod_10 === 2 || abs_value_mod_10 === 3 || abs_value_mod_10 === 4) && abs_value !== 12 && abs_value !== 13 && abs_value !== 14 ? plural_2 : plural_5;
|
|
268
312
|
};
|
|
313
|
+
// src/nnn/omit_pick.ts
|
|
314
|
+
var pick = (ref, keys) => Object.fromEntries(Object.entries(ref).filter(([key]) => keys.includes(key)));
|
|
315
|
+
var omit = (ref, keys) => Object.fromEntries(Object.entries(ref).filter(([key]) => !keys.includes(key)));
|
|
269
316
|
// src/nnn/uuid_v1.ts
|
|
270
317
|
var ZEROS = /* @__PURE__ */ "0".repeat(16);
|
|
271
318
|
var counter = 0;
|
|
@@ -280,11 +327,13 @@ export {
|
|
|
280
327
|
s,
|
|
281
328
|
rwd,
|
|
282
329
|
pro,
|
|
283
|
-
pl_ural,
|
|
284
330
|
pick,
|
|
285
331
|
omit,
|
|
286
332
|
new_tokenizer,
|
|
333
|
+
new_noun_form,
|
|
334
|
+
new_escape,
|
|
287
335
|
nanolight_ts,
|
|
336
|
+
monokai,
|
|
288
337
|
js_on_parse,
|
|
289
338
|
is_string,
|
|
290
339
|
is_record,
|
|
@@ -295,7 +344,6 @@ export {
|
|
|
295
344
|
h,
|
|
296
345
|
fix_typography,
|
|
297
346
|
escape_values,
|
|
298
|
-
escape,
|
|
299
347
|
csv_parse,
|
|
300
348
|
c
|
|
301
349
|
};
|
package/package.json
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
"keywords": [
|
|
5
5
|
"c",
|
|
6
6
|
"CSS-in-JS",
|
|
7
|
-
"CSV",
|
|
8
|
-
"csv_parse",
|
|
7
|
+
"CSV parse",
|
|
9
8
|
"DOM",
|
|
10
9
|
"escape",
|
|
11
10
|
"h",
|
|
@@ -20,15 +19,19 @@
|
|
|
20
19
|
"is_record",
|
|
21
20
|
"is_string",
|
|
22
21
|
"JS-to-CSS",
|
|
23
|
-
"JSON",
|
|
24
22
|
"js_on_parse",
|
|
23
|
+
"JSON",
|
|
24
|
+
"Monokai",
|
|
25
25
|
"nanolight",
|
|
26
26
|
"nnn",
|
|
27
|
+
"noun form",
|
|
27
28
|
"omit",
|
|
28
29
|
"pick",
|
|
29
|
-
"RWD",
|
|
30
30
|
"Responsive Web Design",
|
|
31
|
+
"RWD",
|
|
31
32
|
"SVG",
|
|
33
|
+
"tokenize",
|
|
34
|
+
"tokenizer",
|
|
32
35
|
"typography",
|
|
33
36
|
"uuid",
|
|
34
37
|
"uuidv1"
|
|
@@ -38,5 +41,5 @@
|
|
|
38
41
|
"name": "@jackens/nnn",
|
|
39
42
|
"type": "module",
|
|
40
43
|
"types": "nnn.d.ts",
|
|
41
|
-
"version": "2025.12.
|
|
44
|
+
"version": "2025.12.23"
|
|
42
45
|
}
|
package/readme.md
CHANGED
|
@@ -35,7 +35,6 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
35
35
|
- [`HArgs1`](#HArgs1): Single argument type for the [`h`](#h) and [`s`](#s) helpers.
|
|
36
36
|
- [`c`](#c): A minimal CSS-in-JS helper that converts a JavaScript object hierarchy into a CSS string.
|
|
37
37
|
- [`csv_parse`](#csv_parse): Parses a CSV string into a two-dimensional array of strings.
|
|
38
|
-
- [`escape`](#escape): Escapes interpolated values in a tagged template literal using the provided escape map.
|
|
39
38
|
- [`escape_values`](#escape_values): Escapes an array of values using the provided escape map.
|
|
40
39
|
- [`fix_typography`](#fix_typography): Applies Polish-specific typographic corrections to a DOM subtree.
|
|
41
40
|
- [`h`](#h): A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper
|
|
@@ -46,11 +45,13 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
46
45
|
- [`is_record`](#is_record): Checks whether the argument is a plain object (not `null` and not an array).
|
|
47
46
|
- [`is_string`](#is_string): Checks whether the argument is a string.
|
|
48
47
|
- [`js_on_parse`](#js_on_parse): Parses JSON with support for handler-based value transformation (“JavaScript ON”).
|
|
48
|
+
- [`monokai`](#monokai): A Monokai-inspired color scheme for use with the [`c`](#c) helper and [`nanolight_ts`](#nanolight_ts) tokenizer.
|
|
49
49
|
- [`nanolight_ts`](#nanolight_ts): A TypeScript/JavaScript syntax highlighting tokenizer built using [`new_tokenizer`](#new_tokenizer).
|
|
50
|
+
- [`new_escape`](#new_escape): Creates a tag function for escaping interpolated values in template literals.
|
|
51
|
+
- [`new_noun_form`](#new_noun_form): Creates a function that returns the appropriate Polish noun form based on a numeric value.
|
|
50
52
|
- [`new_tokenizer`](#new_tokenizer): A helper for building simple tokenizers (see also [`nanolight_ts`](#nanolight_ts)).
|
|
51
53
|
- [`omit`](#omit): Creates a new object excluding the specified keys from the source object.
|
|
52
54
|
- [`pick`](#pick): Creates a new object containing only the specified keys from the source object.
|
|
53
|
-
- [`pl_ural`](#pl_ural): Returns the appropriate Polish noun form based on a numeric value.
|
|
54
55
|
- [`pro`](#pro): A Proxy-based helper for auto-vivification of nested object structures.
|
|
55
56
|
- [`rwd`](#rwd): A responsive web design helper that generates CSS rules for a grid-like layout.
|
|
56
57
|
- [`s`](#s): A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper
|
|
@@ -83,7 +84,7 @@ type EscapeMap = Map<unknown, (value?: unknown) => string>;
|
|
|
83
84
|
|
|
84
85
|
A map from value constructors (or `null`/`undefined`) to escape functions.
|
|
85
86
|
|
|
86
|
-
Used by [`escape_values`](#escape_values) and [`
|
|
87
|
+
Used by [`escape_values`](#escape_values) and [`new_escape`](#new_escape).
|
|
87
88
|
|
|
88
89
|
### HArgs
|
|
89
90
|
|
|
@@ -368,58 +369,6 @@ expect(csv_parse(text)).to.deep.equal([
|
|
|
368
369
|
])
|
|
369
370
|
```
|
|
370
371
|
|
|
371
|
-
### escape
|
|
372
|
-
|
|
373
|
-
```ts
|
|
374
|
-
const escape: (escape_map: EscapeMap, template: TemplateStringsArray, ...values: unknown[]) => string;
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
Escapes interpolated values in a tagged template literal using the provided escape map.
|
|
378
|
-
|
|
379
|
-
#### escape_map
|
|
380
|
-
|
|
381
|
-
A map where keys are constructors and values are escape functions.
|
|
382
|
-
|
|
383
|
-
#### template
|
|
384
|
-
|
|
385
|
-
The template strings array from the tagged template.
|
|
386
|
-
|
|
387
|
-
#### values
|
|
388
|
-
|
|
389
|
-
The interpolated values to escape.
|
|
390
|
-
|
|
391
|
-
#### Returns
|
|
392
|
-
|
|
393
|
-
The resulting string with all interpolated values escaped.
|
|
394
|
-
|
|
395
|
-
#### Usage Examples
|
|
396
|
-
|
|
397
|
-
```ts
|
|
398
|
-
const escape_map: EscapeMap = new Map([
|
|
399
|
-
[null, () => 'NULL'],
|
|
400
|
-
[undefined, () => 'NULL'],
|
|
401
|
-
[Array, (values: unknown[]) => escape_values(escape_map, values).join(', ')],
|
|
402
|
-
[Boolean, (value: boolean) => `b'${+value}'`],
|
|
403
|
-
[Date, (value: Date) => `'${value.toISOString().replace(/^(.+)T(.+)\..*$/, '$1 $2')}'`],
|
|
404
|
-
[Number, (value: number) => `${value}`],
|
|
405
|
-
[String, (value: string) => `'${value.replace(/'/g, "''")}'`]
|
|
406
|
-
])
|
|
407
|
-
|
|
408
|
-
const sql = escape.bind(null, escape_map)
|
|
409
|
-
|
|
410
|
-
const actual = sql`
|
|
411
|
-
SELECT *
|
|
412
|
-
FROM table_name
|
|
413
|
-
WHERE column_name IN (${[true, null, undefined, 42, '42', "4'2", /42/, new Date(323325000000)]})`
|
|
414
|
-
|
|
415
|
-
const expected = `
|
|
416
|
-
SELECT *
|
|
417
|
-
FROM table_name
|
|
418
|
-
WHERE column_name IN (b'1', NULL, NULL, 42, '42', '4''2', NULL, '1980-03-31 04:30:00')`
|
|
419
|
-
|
|
420
|
-
expect(actual).to.deep.equal(expected)
|
|
421
|
-
```
|
|
422
|
-
|
|
423
372
|
### escape_values
|
|
424
373
|
|
|
425
374
|
```ts
|
|
@@ -833,6 +782,23 @@ const expected = [
|
|
|
833
782
|
expect(actual).to.deep.equal(expected)
|
|
834
783
|
```
|
|
835
784
|
|
|
785
|
+
### monokai
|
|
786
|
+
|
|
787
|
+
```ts
|
|
788
|
+
const monokai: CRoot;
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
A Monokai-inspired color scheme for use with the [`c`](#c) helper and [`nanolight_ts`](#nanolight_ts) tokenizer.
|
|
792
|
+
|
|
793
|
+
Defines CSS custom properties for eight colors (`--black`, `--blue`, `--green`, `--grey`,
|
|
794
|
+
`--purple`, `--red`, `--white`, `--yellow`) with both light and dark mode variants.
|
|
795
|
+
|
|
796
|
+
#### Remarks
|
|
797
|
+
|
|
798
|
+
- In light mode, `--black` is a light background and `--white` is dark text.
|
|
799
|
+
- In dark mode (via `prefers-color-scheme: dark`), the palette inverts to a dark background with light text.
|
|
800
|
+
- Includes base styles for `body`, `pre` and `code>span.*` (syntax highlighting).
|
|
801
|
+
|
|
836
802
|
### nanolight_ts
|
|
837
803
|
|
|
838
804
|
```ts
|
|
@@ -847,7 +813,7 @@ The source code string to tokenize.
|
|
|
847
813
|
|
|
848
814
|
#### Returns
|
|
849
815
|
|
|
850
|
-
An array of [`HArgs1`](#HArgs1) elements suitable for rendering with [`h`](#h)
|
|
816
|
+
An array of [`HArgs1`](#HArgs1) elements suitable for rendering with [`h`](#h).
|
|
851
817
|
|
|
852
818
|
#### Usage Examples
|
|
853
819
|
|
|
@@ -877,6 +843,97 @@ expect(nanolight_ts(code_js)).to.deep.equal([
|
|
|
877
843
|
])
|
|
878
844
|
```
|
|
879
845
|
|
|
846
|
+
### new_escape
|
|
847
|
+
|
|
848
|
+
```ts
|
|
849
|
+
const new_escape: (escape_map: EscapeMap) => (template: TemplateStringsArray, ...values: unknown[]) => string;
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
Creates a tag function for escaping interpolated values in template literals.
|
|
853
|
+
|
|
854
|
+
#### escape_map
|
|
855
|
+
|
|
856
|
+
A map where keys are constructors and values are escape functions.
|
|
857
|
+
|
|
858
|
+
#### Returns
|
|
859
|
+
|
|
860
|
+
A tag function that escapes interpolated values using the provided escape map.
|
|
861
|
+
|
|
862
|
+
#### Usage Examples
|
|
863
|
+
|
|
864
|
+
```ts
|
|
865
|
+
const escape_map: EscapeMap = new Map([
|
|
866
|
+
[null, () => 'NULL'],
|
|
867
|
+
[undefined, () => 'NULL'],
|
|
868
|
+
[Array, (values: unknown[]) => escape_values(escape_map, values).join(', ')],
|
|
869
|
+
[Boolean, (value: boolean) => `b'${+value}'`],
|
|
870
|
+
[Date, (value: Date) => `'${value.toISOString().replace(/^(.+)T(.+)\..*$/, '$1 $2')}'`],
|
|
871
|
+
[Number, (value: number) => `${value}`],
|
|
872
|
+
[String, (value: string) => `'${value.replace(/'/g, "''")}'`]
|
|
873
|
+
])
|
|
874
|
+
|
|
875
|
+
const sql = new_escape(escape_map)
|
|
876
|
+
|
|
877
|
+
const actual = sql`
|
|
878
|
+
SELECT *
|
|
879
|
+
FROM table_name
|
|
880
|
+
WHERE column_name IN (${[true, null, undefined, 42, '42', "4'2", /42/, new Date(323325000000)]})`
|
|
881
|
+
|
|
882
|
+
const expected = `
|
|
883
|
+
SELECT *
|
|
884
|
+
FROM table_name
|
|
885
|
+
WHERE column_name IN (b'1', NULL, NULL, 42, '42', '4''2', NULL, '1980-03-31 04:30:00')`
|
|
886
|
+
|
|
887
|
+
expect(actual).to.deep.equal(expected)
|
|
888
|
+
```
|
|
889
|
+
|
|
890
|
+
### new_noun_form
|
|
891
|
+
|
|
892
|
+
```ts
|
|
893
|
+
const new_noun_form: (singular: string, plural_2: string, plural_5: string) => (value: number) => string;
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
Creates a function that returns the appropriate Polish noun form based on a numeric value.
|
|
897
|
+
|
|
898
|
+
Polish has three plural forms depending on the number:
|
|
899
|
+
- Singular: used for exactly 1.
|
|
900
|
+
- “Plural 2-4”: used for 2, 3, 4, 22, 23, 24, etc. (but not 12, 13, 14).
|
|
901
|
+
- “Plural 5+”: used for 0, 5–21, 25–31, etc.
|
|
902
|
+
|
|
903
|
+
#### singular
|
|
904
|
+
|
|
905
|
+
The singular form (e.g., “auto” for “car”).
|
|
906
|
+
|
|
907
|
+
#### plural_2
|
|
908
|
+
|
|
909
|
+
The form for 2, 3, 4 (e.g., “auta”).
|
|
910
|
+
|
|
911
|
+
#### plural_5
|
|
912
|
+
|
|
913
|
+
The form for 5+ (e.g., “aut”).
|
|
914
|
+
|
|
915
|
+
#### Returns
|
|
916
|
+
|
|
917
|
+
A function that takes a numeric value and returns the appropriate noun form.
|
|
918
|
+
|
|
919
|
+
#### Usage Examples
|
|
920
|
+
|
|
921
|
+
```ts
|
|
922
|
+
const auto = new_noun_form('auto', 'auta', 'aut')
|
|
923
|
+
|
|
924
|
+
expect(auto(0)).to.deep.equal('aut')
|
|
925
|
+
expect(auto(1)).to.deep.equal('auto')
|
|
926
|
+
expect(auto(17)).to.deep.equal('aut')
|
|
927
|
+
expect(auto(42)).to.deep.equal('auta')
|
|
928
|
+
|
|
929
|
+
const car = new_noun_form('car', 'cars', 'cars')
|
|
930
|
+
|
|
931
|
+
expect(car(0)).to.deep.equal('cars')
|
|
932
|
+
expect(car(1)).to.deep.equal('car')
|
|
933
|
+
expect(car(17)).to.deep.equal('cars')
|
|
934
|
+
expect(car(42)).to.deep.equal('cars')
|
|
935
|
+
```
|
|
936
|
+
|
|
880
937
|
### new_tokenizer
|
|
881
938
|
|
|
882
939
|
```ts
|
|
@@ -967,57 +1024,6 @@ const obj = { a: 42, b: '42', c: 17 }
|
|
|
967
1024
|
expect(pick(obj, ['a', 'b'])).to.deep.equal({ a: 42, b: '42' })
|
|
968
1025
|
```
|
|
969
1026
|
|
|
970
|
-
### pl_ural
|
|
971
|
-
|
|
972
|
-
```ts
|
|
973
|
-
const pl_ural: (singular: string, plural_2: string, plural_5: string, value: number) => string;
|
|
974
|
-
```
|
|
975
|
-
|
|
976
|
-
Returns the appropriate Polish noun form based on a numeric value.
|
|
977
|
-
|
|
978
|
-
Polish has three plural forms depending on the number:
|
|
979
|
-
- Singular: used for exactly 1.
|
|
980
|
-
- “Plural 2-4”: used for 2, 3, 4, 22, 23, 24, etc. (but not 12, 13, 14).
|
|
981
|
-
- “Plural 5+”: used for 0, 5–21, 25–31, etc.
|
|
982
|
-
|
|
983
|
-
#### singular
|
|
984
|
-
|
|
985
|
-
The singular form (e.g., “auto” for “car”).
|
|
986
|
-
|
|
987
|
-
#### plural_2
|
|
988
|
-
|
|
989
|
-
The form for 2, 3, 4 (e.g., “auta”).
|
|
990
|
-
|
|
991
|
-
#### plural_5
|
|
992
|
-
|
|
993
|
-
The form for 5+ (e.g., “aut”).
|
|
994
|
-
|
|
995
|
-
#### value
|
|
996
|
-
|
|
997
|
-
The numeric value to evaluate.
|
|
998
|
-
|
|
999
|
-
#### Returns
|
|
1000
|
-
|
|
1001
|
-
The appropriate noun form for the given value.
|
|
1002
|
-
|
|
1003
|
-
#### Usage Examples
|
|
1004
|
-
|
|
1005
|
-
```ts
|
|
1006
|
-
const auto = pl_ural.bind(null, 'auto', 'auta', 'aut')
|
|
1007
|
-
|
|
1008
|
-
expect(auto(0)).to.deep.equal('aut')
|
|
1009
|
-
expect(auto(1)).to.deep.equal('auto')
|
|
1010
|
-
expect(auto(17)).to.deep.equal('aut')
|
|
1011
|
-
expect(auto(42)).to.deep.equal('auta')
|
|
1012
|
-
|
|
1013
|
-
const car = pl_ural.bind(null, 'car', 'cars', 'cars')
|
|
1014
|
-
|
|
1015
|
-
expect(car(0)).to.deep.equal('cars')
|
|
1016
|
-
expect(car(1)).to.deep.equal('car')
|
|
1017
|
-
expect(car(17)).to.deep.equal('cars')
|
|
1018
|
-
expect(car(42)).to.deep.equal('cars')
|
|
1019
|
-
```
|
|
1020
|
-
|
|
1021
1027
|
### pro
|
|
1022
1028
|
|
|
1023
1029
|
```ts
|