@thi.ng/proctext 0.1.2 → 0.2.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2024-07-22T13:15:57Z
3
+ - **Last updated**: 2024-08-10T15:03:07Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,18 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [0.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/proctext@0.2.0) (2024-08-10)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add `isAre` and `withArticle` modifiers ([b969d12](https://github.com/thi-ng/umbrella/commit/b969d12))
17
+ - add `<empty>` var, update missing var handling ([350bc26](https://github.com/thi-ng/umbrella/commit/350bc26))
18
+ - add `<empty>` special var reference for empty strings
19
+ - add `GeneratorContext.missing` option to provide fallback for missing vars
20
+ - add custom error types
21
+ - fix: add missing `maxHist` default value
22
+ - update deps
23
+
12
24
  ## [0.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/proctext@0.1.0) (2024-07-19)
13
25
 
14
26
  #### 🚀 Features
package/README.md CHANGED
@@ -67,7 +67,15 @@ var...
67
67
  Variables are case-sensitive (i.e. `NAME` is a different var than `name`) and
68
68
  can also be re-defined overridden in different parts of the document.
69
69
 
70
- Variables are referenced via: `<name>`:
70
+ Variables are referenced via: `<name>`. By default, an error will be thrown if a
71
+ variable cannot be resolved. Via the `missing` option given to `generate()` a
72
+ default fallback value can be defined, which when given will **not** trigger an
73
+ error in these cases.
74
+
75
+ > [!NOTE]
76
+ > The special variable reference `<empty>` can be used to produce an empty
77
+ > string (or used as single value placeholder option inside another variable
78
+ > definition). This variable can not be redefined.
71
79
 
72
80
  ```ts tangle:export/readme-intro.ts
73
81
  import { generate } from "@thi.ng/proctext";
@@ -358,13 +366,15 @@ For Node.js REPL:
358
366
  const pro = await import("@thi.ng/proctext");
359
367
  ```
360
368
 
361
- Package sizes (brotli'd, pre-treeshake): ESM: 1.14 KB
369
+ Package sizes (brotli'd, pre-treeshake): ESM: 1.34 KB
362
370
 
363
371
  ## Dependencies
364
372
 
365
373
  - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
366
374
  - [@thi.ng/arrays](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays)
375
+ - [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
367
376
  - [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti)
377
+ - [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
368
378
  - [@thi.ng/object-utils](https://github.com/thi-ng/umbrella/tree/develop/packages/object-utils)
369
379
  - [@thi.ng/parse](https://github.com/thi-ng/umbrella/tree/develop/packages/parse)
370
380
  - [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/develop/packages/random)
package/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Fn, MaybePromise } from "@thi.ng/api";
1
+ import type { Fn, FnU, MaybePromise } from "@thi.ng/api";
2
2
  import type { IRandom } from "@thi.ng/random";
3
3
  export interface Var {
4
4
  opts: string[];
@@ -32,5 +32,11 @@ export interface GeneratorContext {
32
32
  * @defaultValue 10
33
33
  */
34
34
  maxTrials: number;
35
+ /**
36
+ * If given, variable references which cannot be resolved will be replaced
37
+ * by this string. If undefined (default), throws an error when unable to
38
+ * resolve a var.
39
+ */
40
+ missing?: string | FnU<string>;
35
41
  }
36
42
  //# sourceMappingURL=api.d.ts.map
package/generate.d.ts CHANGED
@@ -1,6 +1,51 @@
1
1
  import type { GeneratorContext } from "./api.js";
2
+ export declare const CyclicReferenceError: {
3
+ new (msg?: string | undefined): {
4
+ origMessage: string;
5
+ name: string;
6
+ message: string;
7
+ stack?: string;
8
+ cause?: unknown;
9
+ };
10
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
11
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
12
+ stackTraceLimit: number;
13
+ };
14
+ export declare const UnknownModifierError: {
15
+ new (msg?: string | undefined): {
16
+ origMessage: string;
17
+ name: string;
18
+ message: string;
19
+ stack?: string;
20
+ cause?: unknown;
21
+ };
22
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
23
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
24
+ stackTraceLimit: number;
25
+ };
26
+ export declare const UnknownVariableError: {
27
+ new (msg?: string | undefined): {
28
+ origMessage: string;
29
+ name: string;
30
+ message: string;
31
+ stack?: string;
32
+ cause?: unknown;
33
+ };
34
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
35
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
36
+ stackTraceLimit: number;
37
+ };
2
38
  /**
3
- * Default variable modifiers (capitalize, uppercase, lowercase)
39
+ * Default variable modifiers
40
+ *
41
+ * @remarks
42
+ * Current list:
43
+ *
44
+ * - `cap`: capitalize body
45
+ * - `uc`: uppercase
46
+ * - `lc`: lowercase
47
+ * - `isAre`: append `is` or `are` verb (naive, english only)
48
+ * - `withArticle`: prepend `a` or `an` article (naive, english only)
4
49
  */
5
50
  export declare const DEFAULT_MODIFIERS: GeneratorContext["mods"];
6
51
  /**
package/generate.js CHANGED
@@ -1,15 +1,25 @@
1
1
  import { peek } from "@thi.ng/arrays/peek";
2
+ import { isString } from "@thi.ng/checks/is-string";
2
3
  import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
4
+ import { defError } from "@thi.ng/errors/deferror";
3
5
  import { mergeDeepObj } from "@thi.ng/object-utils/merge-deep";
4
6
  import { defContext } from "@thi.ng/parse/context";
5
7
  import { defGrammar } from "@thi.ng/parse/grammar";
6
8
  import { SYSTEM } from "@thi.ng/random/system";
7
9
  import { pickRandomUnique } from "@thi.ng/random/unique-indices";
8
10
  import { capitalize, lower, upper } from "@thi.ng/strings/case";
11
+ const CyclicReferenceError = defError(
12
+ () => "error expanding variable",
13
+ (id) => `: "${id}" (cycle detected)`
14
+ );
15
+ const UnknownModifierError = defError(() => "unknown modifier");
16
+ const UnknownVariableError = defError(() => "unknown variable");
9
17
  const DEFAULT_MODIFIERS = {
10
18
  cap: capitalize,
11
19
  uc: upper,
12
- lc: lower
20
+ lc: lower,
21
+ withArticle: (x) => (/[aeiou]/i.test(x[0]) ? "an " : "a ") + x,
22
+ isAre: (x) => x + (x.endsWith("s") ? " are" : " is")
13
23
  };
14
24
  const GRAMMAR = defGrammar(`
15
25
  # main parser rule
@@ -46,6 +56,7 @@ const generate = async (src, ctx) => {
46
56
  vars: {},
47
57
  mods: DEFAULT_MODIFIERS,
48
58
  rnd: SYSTEM,
59
+ maxHist: 1,
49
60
  maxTrials: 10
50
61
  },
51
62
  ctx
@@ -117,29 +128,36 @@ const __resolveVarName = (name, ctx) => {
117
128
  };
118
129
  const __expandVar = async ({ children }, ctx) => {
119
130
  const id = __resolveVarName(children[0].result, ctx);
131
+ if (id === "empty") return "";
120
132
  const $var = ctx.vars[id];
121
- if (!$var) throw new Error(`unknown variable: ${id}`);
133
+ if (!$var) {
134
+ if (ctx.missing !== void 0) {
135
+ return isString(ctx.missing) ? ctx.missing : ctx.missing(id);
136
+ }
137
+ throw new UnknownVariableError(id);
138
+ }
122
139
  pickRandomUnique(1, $var.opts, $var.history, ctx.maxTrials, ctx.rnd);
123
140
  if ($var.history.length > ctx.maxHist) $var.history.shift();
124
141
  const choice = peek($var.history);
125
142
  const result = await generate(choice, ctx);
126
143
  if (result.err) {
127
- throw new Error(
128
- result.err.message.includes("recursion") ? `error expanding variable: ${id} (cycle detected)` : result.err.message
129
- );
144
+ throw result.err.message.includes("recursion") ? new CyclicReferenceError(id) : result.err;
130
145
  }
131
146
  let value = result.result;
132
147
  if (children[1].children) {
133
148
  for (let mod of children[1].children) {
134
149
  const modFn = ctx.mods[mod.result];
135
150
  if (modFn) value = await modFn(value);
136
- else throw new Error(`unknown modifier: ${mod.result}`);
151
+ else throw new UnknownModifierError(mod.result);
137
152
  }
138
153
  }
139
154
  return value;
140
155
  };
141
156
  export {
157
+ CyclicReferenceError,
142
158
  DEFAULT_MODIFIERS,
143
159
  GRAMMAR,
160
+ UnknownModifierError,
161
+ UnknownVariableError,
144
162
  generate
145
163
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/proctext",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "Extensible procedural text generation engine with dynamic, mutable state, indirection, randomizable & recursive variable expansions",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -36,22 +36,36 @@
36
36
  "tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@thi.ng/api": "^8.11.7",
40
- "@thi.ng/arrays": "^2.9.13",
41
- "@thi.ng/defmulti": "^3.0.45",
42
- "@thi.ng/object-utils": "^1.1.0",
43
- "@thi.ng/parse": "^2.4.48",
44
- "@thi.ng/random": "^4.0.1",
45
- "@thi.ng/strings": "^3.8.1"
39
+ "@thi.ng/api": "^8.11.8",
40
+ "@thi.ng/arrays": "^2.9.14",
41
+ "@thi.ng/checks": "^3.6.10",
42
+ "@thi.ng/defmulti": "^3.0.46",
43
+ "@thi.ng/errors": "^2.5.14",
44
+ "@thi.ng/object-utils": "^1.1.1",
45
+ "@thi.ng/parse": "^2.4.50",
46
+ "@thi.ng/random": "^4.0.2",
47
+ "@thi.ng/strings": "^3.8.3"
46
48
  },
47
49
  "devDependencies": {
48
- "@microsoft/api-extractor": "^7.47.0",
50
+ "@microsoft/api-extractor": "^7.47.5",
49
51
  "esbuild": "^0.23.0",
50
- "typedoc": "^0.26.3",
51
- "typescript": "^5.5.3"
52
+ "typedoc": "^0.26.5",
53
+ "typescript": "^5.5.4"
52
54
  },
53
55
  "keywords": [
54
- "typescript"
56
+ "ast",
57
+ "bindings",
58
+ "generative",
59
+ "generator",
60
+ "grammar",
61
+ "parser",
62
+ "recursion",
63
+ "rewrite",
64
+ "syntax",
65
+ "template",
66
+ "text",
67
+ "typescript",
68
+ "variable"
55
69
  ],
56
70
  "publishConfig": {
57
71
  "access": "public"
@@ -82,5 +96,5 @@
82
96
  "status": "alpha",
83
97
  "year": 2023
84
98
  },
85
- "gitHead": "bd22b0826134b79064169371665b4d6caa9b6066\n"
99
+ "gitHead": "e914ebbd81c56783c39cf746548c547cbacadc96\n"
86
100
  }