@jackens/nnn 2025.11.11 → 2025.11.28

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.
Files changed (4) hide show
  1. package/nnn.d.ts +10 -4
  2. package/nnn.js +16 -21
  3. package/package.json +1 -1
  4. package/readme.md +32 -23
package/nnn.d.ts CHANGED
@@ -60,6 +60,16 @@ export declare const h: {
60
60
  <N extends Node>(node: N, ...args1: HArgs1[]): N;
61
61
  (tag_or_node: string | Node, ...args1: HArgs1[]): Node;
62
62
  };
63
+ /**
64
+ * Generic syntax highlighting helper (see also `nanolight_ts`).
65
+ *
66
+ * - Each entry in `config` is a tuple of:
67
+ * - CSS class name to apply
68
+ * - regular expression pattern to match (should include exactly one capturing group that matches the entire desired text).
69
+ */
70
+ export declare const nanolight: (...config: [string, RegExp][]) => (code: string) => HArgs1[];
71
+ /** TypeScript syntax highlighting helper (built on `nanolight`). */
72
+ export declare const nanolight_ts: (code: string) => HArgs1[];
63
73
  /**
64
74
  * A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
65
75
  *
@@ -109,10 +119,6 @@ export declare const is_string: (arg: unknown) => arg is string;
109
119
  * ```
110
120
  */
111
121
  export declare const js_on_parse: (handlers: Record<PropertyKey, Function>, text: string) => any;
112
- /** Generic syntax highlighting helper (see also `nanolight_js`). */
113
- export declare const nanolight: (pattern: RegExp, highlighters: ((chunk: string, index: number) => HArgs1)[], code: string) => HArgs1[];
114
- /** JavaScript syntax highlighting helper (built on `nanolight`). */
115
- export declare const nanolight_js: (code: string) => HArgs1[];
116
122
  /** Runtime implementation of TypeScript’s `Pick` (see also `omit`). */
117
123
  export declare const pick: <T, K extends keyof T>(ref: T, keys: K[]) => Pick<T, K>;
118
124
  /** Runtime implementation of TypeScript’s `Omit` (see also `pick`). */
package/nnn.js CHANGED
@@ -168,6 +168,21 @@ var _h = (namespace_uri) => {
168
168
  return h;
169
169
  };
170
170
  var h = _h();
171
+ var nanolight = (...config) => {
172
+ const pattern = new RegExp(config.map((item) => `${item[1]}`.slice(1, -1)).join("|"));
173
+ const length = config.length + 1;
174
+ return (code) => {
175
+ const result = [];
176
+ code.split(pattern).forEach((chunk, index) => {
177
+ if (chunk != null && chunk !== "") {
178
+ index %= length;
179
+ result.push(index > 0 ? ["span", { class: config[index - 1][0] }, chunk] : chunk);
180
+ }
181
+ });
182
+ return result;
183
+ };
184
+ };
185
+ var nanolight_ts = nanolight(["yellow", /('.*?'|".*?"|`[\s\S]*?`)/], ["grey", /(\/\/.*?\n|\/\*[\s\S]*?\*\/)/], ["red", /(?<!\w)(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|export|extends|finally|for|from|function|goto|if|import|in|instanceof|is|keyof|let|new|of|package|return|super|switch|this|throw|try|type|typeof|var|void|while|with|yield)(?!\w)/], ["purple", /(?<!\w)(false|Infinity|NaN|null|true|undefined)(?!\w)/], ["blue", /(?<!\w)(any|bigint|boolean|eval|number|string|symbol|unknown)(?!\w)/], ["red", /([=<>&|!^~*/%+-]|\?\?|\?(?=\s)|(?<=\s):)/], ["grey", /([()[\]{}.,?:;])/], ["purple", /(0x[\dabcdef_]+|0o[01234567_]+|0b[01_]+|\d[\d_]*(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?)/], ["green", /(?<!\w)([$\w]+)(?=\()/], ["purple", /(?<!\w)([A-Z_$][A-Z0-9_$]+)(?!\w)/], ["blue", /(?<!\w)([A-Z][$\w]+)(?!\w)/], ["white", /(?<!\w)([$\w]+)(?!\w)/]);
171
186
  var s = _h("http://www.w3.org/2000/svg");
172
187
  var svg_use = (id, ...args) => s("svg", ["use", { "xlink:href": "#" + id }], ...args);
173
188
  var has_own = (ref, key) => ref != null && Object.hasOwn(ref, key);
@@ -193,26 +208,6 @@ var js_on_parse = (handlers, text) => JSON.parse(text, (key, value) => {
193
208
  }
194
209
  return value;
195
210
  });
196
- var nanolight = (pattern, highlighters, code) => {
197
- const result = [];
198
- code.split(pattern).forEach((chunk, index) => {
199
- if (chunk != null && chunk !== "") {
200
- index %= highlighters.length;
201
- result.push(highlighters[index](chunk, index));
202
- }
203
- });
204
- return result;
205
- };
206
- var nanolight_js = nanolight.bind(0, /('.*?'|".*?"|`[\s\S]*?`)|(\/\/.*?\n|\/\*[\s\S]*?\*\/)|(any|bigint|break|boolean|case|catch|class|const|continue|debugger|default|delete|do|else|eval|export|extends|false|finally|for|from|function|goto|if|import|in|instanceof|is|keyof|let|NaN|new|number|null|package|return|string|super|switch|symbol|this|throw|true|try|type|typeof|undefined|unknown|var|void|while|with|yield)(?!\w)|([<>=.?:&|!^~*/%+-])|(0x[\dabcdef_]+|0o[01234567_]+|0b[01_]+|\d[\d_]*(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?)|([$\w]+)(?=\()|([$\wąćęłńóśżźĄĆĘŁŃÓŚŻŹ]+)/, [
207
- (chunk) => chunk,
208
- (chunk) => ["span", { class: "string" }, chunk],
209
- (chunk) => ["span", { class: "comment" }, chunk],
210
- (chunk) => ["span", { class: "keyword" }, chunk],
211
- (chunk) => ["span", { class: "operator" }, chunk],
212
- (chunk) => ["span", { class: "number" }, chunk],
213
- (chunk) => ["span", { class: "function" }, chunk],
214
- (chunk) => ["span", { class: "literal" }, chunk]
215
- ]);
216
211
  var pick = (ref, keys) => Object.fromEntries(Object.entries(ref).filter(([key]) => keys.includes(key)));
217
212
  var omit = (ref, keys) => Object.fromEntries(Object.entries(ref).filter(([key]) => !keys.includes(key)));
218
213
  var pl_ural = (singular, plural_2, plural_5, value) => {
@@ -241,7 +236,7 @@ export {
241
236
  pl_ural,
242
237
  pick,
243
238
  omit,
244
- nanolight_js,
239
+ nanolight_ts,
245
240
  nanolight,
246
241
  js_on_parse,
247
242
  is_string,
package/package.json CHANGED
@@ -38,5 +38,5 @@
38
38
  "name": "@jackens/nnn",
39
39
  "type": "module",
40
40
  "types": "nnn.d.ts",
41
- "version": "2025.11.11"
41
+ "version": "2025.11.28"
42
42
  }
package/readme.md CHANGED
@@ -46,8 +46,8 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
46
46
  - [`is_record`](#is_record): Checks whether the argument is a plain object record.
47
47
  - [`is_string`](#is_string): Checks whether the argument is a string.
48
48
  - [`js_on_parse`](#js_on_parse): `JSON.parse` with “JavaScript turned on”.
49
- - [`nanolight`](#nanolight): Generic syntax highlighting helper (see also `nanolight_js`).
50
- - [`nanolight_js`](#nanolight_js): JavaScript syntax highlighting helper (built on `nanolight`).
49
+ - [`nanolight`](#nanolight): Generic syntax highlighting helper (see also `nanolight_ts`).
50
+ - [`nanolight_ts`](#nanolight_ts): TypeScript syntax highlighting helper (built on `nanolight`).
51
51
  - [`omit`](#omit): Runtime implementation of TypeScript’s `Omit` (see also `pick`).
52
52
  - [`pick`](#pick): Runtime implementation of TypeScript’s `Pick` (see also `omit`).
53
53
  - [`pl_ural`](#pl_ural): Chooses the appropriate Polish noun form based on a numeric value.
@@ -584,7 +584,7 @@ expect(is_number(42)).to.be.true
584
584
  expect(is_number(Number(42))).to.be.true
585
585
  expect(is_number(new Number(42))).to.be.false
586
586
  expect(is_number(NaN)).to.be.true
587
- expect(is_finite_number(Infinity)).to.be.true
587
+ expect(is_number(Infinity)).to.be.true
588
588
  ```
589
589
 
590
590
  ### is_record
@@ -696,39 +696,48 @@ expect(actual).to.deep.equal(expected)
696
696
  ### nanolight
697
697
 
698
698
  ```ts
699
- const nanolight: (pattern: RegExp, highlighters: ((chunk: string, index: number) => HArgs1)[], code: string) => HArgs1[];
699
+ const nanolight: (...config: [string, RegExp][]) => (code: string) => HArgs1[];
700
700
  ```
701
701
 
702
- Generic syntax highlighting helper (see also `nanolight_js`).
702
+ Generic syntax highlighting helper (see also `nanolight_ts`).
703
703
 
704
- ### nanolight_js
704
+ - Each entry in `config` is a tuple of:
705
+ - CSS class name to apply
706
+ - regular expression pattern to match (should include exactly one capturing group that matches the entire desired text).
707
+
708
+ ### nanolight_ts
705
709
 
706
710
  ```ts
707
- const nanolight_js: (code: string) => HArgs1[];
711
+ const nanolight_ts: (code: string) => HArgs1[];
708
712
  ```
709
713
 
710
- JavaScript syntax highlighting helper (built on `nanolight`).
714
+ TypeScript syntax highlighting helper (built on `nanolight`).
711
715
 
712
716
  #### Usage Examples
713
717
 
714
718
  ```ts
715
719
  const code_js = "const answer_to_life_the_universe_and_everything = { 42: 42 }['42'] /* 42 */"
716
720
 
717
- expect(nanolight_js(code_js)).to.deep.equal([
718
- ['span', { class: 'keyword' }, 'const'],
721
+ expect(nanolight_ts(code_js)).to.deep.equal([
722
+ ['span', { class: 'red' }, 'const'],
723
+ ' ',
724
+ ['span', { class: 'white' }, 'answer_to_life_the_universe_and_everything'],
725
+ ' ',
726
+ ['span', { class: 'red' }, '='],
727
+ ' ',
728
+ ['span', { class: 'grey' }, '{'],
729
+ ' ',
730
+ ['span', { class: 'purple' }, '42'],
731
+ ['span', { class: 'grey' }, ':'],
719
732
  ' ',
720
- ['span', { class: 'literal' }, 'answer_to_life_the_universe_and_everything'],
733
+ ['span', { class: 'purple' }, '42'],
721
734
  ' ',
722
- ['span', { class: 'operator' }, '='],
723
- ' { ',
724
- ['span', { class: 'number' }, '42'],
725
- ['span', { class: 'operator' }, ':'],
735
+ ['span', { class: 'grey' }, '}'],
736
+ ['span', { class: 'grey' }, '['],
737
+ ['span', { class: 'yellow' }, "'42'"],
738
+ ['span', { class: 'grey' }, ']'],
726
739
  ' ',
727
- ['span', { class: 'number' }, '42'],
728
- ' }[',
729
- ['span', { class: 'string' }, "'42'"],
730
- '] ',
731
- ['span', { class: 'comment' }, '/* 42 */']
740
+ ['span', { class: 'grey' }, '/* 42 */']
732
741
  ])
733
742
  ```
734
743
 
@@ -846,7 +855,7 @@ A responsive‑web‑design helper that generates CSS rules for a grid layout.
846
855
  #### Usage Examples
847
856
 
848
857
  ```ts
849
- const css: CRoot = {
858
+ const style: CRoot = {
850
859
  body: {
851
860
  margin: 0
852
861
  },
@@ -858,9 +867,9 @@ const css: CRoot = {
858
867
  }
859
868
  }
860
869
 
861
- rwd(css, '.r6', 200, 50, [6], [3], [1, 1, 2])
870
+ rwd(style, '.r6', 200, 50, [6], [3], [1, 1, 2])
862
871
 
863
- expect(css).to.deep.equal({
872
+ expect(style).to.deep.equal({
864
873
  body: {
865
874
  margin: 0
866
875
  },