@thi.ng/proctext 0.1.2 → 0.2.0
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 +13 -1
- package/README.md +12 -2
- package/api.d.ts +7 -1
- package/generate.d.ts +46 -1
- package/generate.js +24 -6
- package/package.json +27 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2024-
|
|
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.
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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.
|
|
3
|
+
"version": "0.2.0",
|
|
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.
|
|
40
|
-
"@thi.ng/arrays": "^2.9.
|
|
41
|
-
"@thi.ng/
|
|
42
|
-
"@thi.ng/
|
|
43
|
-
"@thi.ng/
|
|
44
|
-
"@thi.ng/
|
|
45
|
-
"@thi.ng/
|
|
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.49",
|
|
46
|
+
"@thi.ng/random": "^4.0.2",
|
|
47
|
+
"@thi.ng/strings": "^3.8.2"
|
|
46
48
|
},
|
|
47
49
|
"devDependencies": {
|
|
48
|
-
"@microsoft/api-extractor": "^7.47.
|
|
50
|
+
"@microsoft/api-extractor": "^7.47.5",
|
|
49
51
|
"esbuild": "^0.23.0",
|
|
50
|
-
"typedoc": "^0.26.
|
|
51
|
-
"typescript": "^5.5.
|
|
52
|
+
"typedoc": "^0.26.5",
|
|
53
|
+
"typescript": "^5.5.4"
|
|
52
54
|
},
|
|
53
55
|
"keywords": [
|
|
54
|
-
"
|
|
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": "
|
|
99
|
+
"gitHead": "ec78f98d015e4d214a0b840e72e497407807daf3\n"
|
|
86
100
|
}
|