usfm3 0.1.0 → 0.1.5
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/README.md +90 -0
- package/node.js +10 -0
- package/package.json +17 -4
- package/usfm3_wasm.d.ts +2 -0
- package/usfm3_wasm.js +30 -2
- package/usfm3_wasm_bg.wasm +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# usfm3
|
|
2
|
+
|
|
3
|
+
An error-tolerant [USFM 3.x](https://docs.usfm.bible/usfm/3.1.1/index.html) parser for JavaScript and TypeScript. Outputs [USJ](https://docs.usfm.bible/usfm/3.1.1/usj/index.html) (JSON), [USX](https://docs.usfm.bible/usfm/3.1.1/usx/index.html) (XML), normalized USFM, and vref format (a key-value map of verse references to text).
|
|
4
|
+
|
|
5
|
+
Built in Rust and compiled to WebAssembly. Works in browsers, Node.js, Deno, and Bun.
|
|
6
|
+
|
|
7
|
+
Also available as a [Rust crate](https://crates.io/crates/usfm3) and [Python package](https://pypi.org/project/usfm3/).
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install usfm3
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
WASM is automatically initialized in Node.js, Deno, and Bun. In a browser, call `init()` first:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import init from "usfm3";
|
|
21
|
+
await init(); // browser only
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Then parse USFM text:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { parse } from "usfm3";
|
|
28
|
+
|
|
29
|
+
const result = parse(usfmText);
|
|
30
|
+
|
|
31
|
+
if (result.hasErrors()) {
|
|
32
|
+
console.error("Document has errors");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Output formats (lazy — only serialized when called)
|
|
36
|
+
const usj = result.toUsj(); // USJ object
|
|
37
|
+
const usx = result.toUsx(); // USX XML string
|
|
38
|
+
const usfm = result.toUsfm(); // Normalized USFM string
|
|
39
|
+
const vref = result.toVref(); // Vref pairs like { "GEN 1:1": "In the beginning...", ... }
|
|
40
|
+
|
|
41
|
+
// Diagnostics
|
|
42
|
+
for (const d of result.diagnostics) {
|
|
43
|
+
console.log(`[${d.severity}] ${d.message} (${d.start}..${d.end})`);
|
|
44
|
+
// d.code is a machine-readable string like "UnknownMarker", "ImplicitClose", etc.
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Skip semantic validation
|
|
48
|
+
const result2 = parse(usfmText, { validate: false });
|
|
49
|
+
|
|
50
|
+
// Free WASM memory when done
|
|
51
|
+
result.free();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## API
|
|
55
|
+
|
|
56
|
+
### `parse(usfm: string, options?: ParseOptions): ParseResult`
|
|
57
|
+
|
|
58
|
+
Parse a USFM string. Returns a `ParseResult` with lazy output methods and diagnostics.
|
|
59
|
+
|
|
60
|
+
**ParseOptions:**
|
|
61
|
+
|
|
62
|
+
| Field | Type | Default | Description |
|
|
63
|
+
|---|---|---|---|
|
|
64
|
+
| `validate` | `boolean` | `true` | Run semantic validation after parsing |
|
|
65
|
+
|
|
66
|
+
### `ParseResult`
|
|
67
|
+
|
|
68
|
+
| Method / Property | Returns | Description |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `toUsj()` | `object` | USJ (Unified Scripture JSON) |
|
|
71
|
+
| `toUsx()` | `string` | USX (Unified Scripture XML) |
|
|
72
|
+
| `toUsfm()` | `string` | Normalized USFM |
|
|
73
|
+
| `toVref()` | `Record<string, string>` | Verse reference to plain text map |
|
|
74
|
+
| `hasErrors()` | `boolean` | True if any error-severity diagnostics |
|
|
75
|
+
| `diagnostics` | `Diagnostic[]` | Parser and validation diagnostics |
|
|
76
|
+
| `free()` | `void` | Free WASM memory |
|
|
77
|
+
|
|
78
|
+
### `Diagnostic`
|
|
79
|
+
|
|
80
|
+
| Property | Type | Description |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `severity` | `string` | `"error"`, `"warning"`, or `"info"` |
|
|
83
|
+
| `code` | `string` | Machine-readable code (e.g. `"UnknownMarker"`) |
|
|
84
|
+
| `message` | `string` | Human-readable message |
|
|
85
|
+
| `start` | `number` | Start byte offset in source |
|
|
86
|
+
| `end` | `number` | End byte offset in source |
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
MIT
|
package/node.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { initSync } from "./usfm3_wasm.js";
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const wasmBytes = readFileSync(join(__dirname, "usfm3_wasm_bg.wasm"));
|
|
8
|
+
initSync({ module: wasmBytes });
|
|
9
|
+
|
|
10
|
+
export { parse, ParseResult } from "./usfm3_wasm.js";
|
package/package.json
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "usfm3",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.5",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/jcuenod/usfm3"
|
|
8
|
+
},
|
|
5
9
|
"files": [
|
|
6
10
|
"usfm3_wasm_bg.wasm",
|
|
7
11
|
"usfm3_wasm.js",
|
|
8
|
-
"usfm3_wasm.d.ts"
|
|
12
|
+
"usfm3_wasm.d.ts",
|
|
13
|
+
"node.js"
|
|
9
14
|
],
|
|
10
15
|
"main": "usfm3_wasm.js",
|
|
11
16
|
"types": "usfm3_wasm.d.ts",
|
|
12
17
|
"sideEffects": [
|
|
13
18
|
"./snippets/*"
|
|
14
|
-
]
|
|
15
|
-
|
|
19
|
+
],
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"node": {
|
|
23
|
+
"import": "./node.js"
|
|
24
|
+
},
|
|
25
|
+
"default": "./usfm3_wasm.js"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
package/usfm3_wasm.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export class ParseResult {
|
|
|
8
8
|
toUsj(): any;
|
|
9
9
|
toUsx(): string;
|
|
10
10
|
toUsfm(): string;
|
|
11
|
+
toVref(): Record<string, string>;
|
|
11
12
|
}
|
|
12
13
|
export function parse(usfm: string, options?: ParseOptions): ParseResult;
|
|
13
14
|
|
|
@@ -52,6 +53,7 @@ export interface InitOutput {
|
|
|
52
53
|
readonly parseresult_toUsfm: (a: number) => [number, number];
|
|
53
54
|
readonly parseresult_toUsj: (a: number) => [number, number, number];
|
|
54
55
|
readonly parseresult_toUsx: (a: number) => [number, number, number, number];
|
|
56
|
+
readonly parseresult_toVref: (a: number) => [number, number, number];
|
|
55
57
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
56
58
|
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
57
59
|
readonly __wbindgen_externrefs: WebAssembly.Table;
|
package/usfm3_wasm.js
CHANGED
|
@@ -83,6 +83,17 @@ export class ParseResult {
|
|
|
83
83
|
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns a verse reference map: `{ "GEN 1:1": "In the beginning ...", ... }`.
|
|
88
|
+
* @returns {any}
|
|
89
|
+
*/
|
|
90
|
+
toVref() {
|
|
91
|
+
const ret = wasm.parseresult_toVref(this.__wbg_ptr);
|
|
92
|
+
if (ret[2]) {
|
|
93
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
94
|
+
}
|
|
95
|
+
return takeFromExternrefTable0(ret[0]);
|
|
96
|
+
}
|
|
86
97
|
}
|
|
87
98
|
if (Symbol.dispose) ParseResult.prototype[Symbol.dispose] = ParseResult.prototype.free;
|
|
88
99
|
|
|
@@ -136,6 +147,10 @@ function __wbg_get_imports() {
|
|
|
136
147
|
const ret = typeof(val) === 'object' && val !== null;
|
|
137
148
|
return ret;
|
|
138
149
|
},
|
|
150
|
+
__wbg___wbindgen_is_string_cd444516edc5b180: function(arg0) {
|
|
151
|
+
const ret = typeof(arg0) === 'string';
|
|
152
|
+
return ret;
|
|
153
|
+
},
|
|
139
154
|
__wbg___wbindgen_is_undefined_9e4d92534c42d778: function(arg0) {
|
|
140
155
|
const ret = arg0 === undefined;
|
|
141
156
|
return ret;
|
|
@@ -197,6 +212,10 @@ function __wbg_get_imports() {
|
|
|
197
212
|
const ret = new Array();
|
|
198
213
|
return ret;
|
|
199
214
|
},
|
|
215
|
+
__wbg_new_dca287b076112a51: function() {
|
|
216
|
+
const ret = new Map();
|
|
217
|
+
return ret;
|
|
218
|
+
},
|
|
200
219
|
__wbg_new_dd2b680c8bf6ae29: function(arg0) {
|
|
201
220
|
const ret = new Uint8Array(arg0);
|
|
202
221
|
return ret;
|
|
@@ -204,6 +223,10 @@ function __wbg_get_imports() {
|
|
|
204
223
|
__wbg_prototypesetcall_bdcdcc5842e4d77d: function(arg0, arg1, arg2) {
|
|
205
224
|
Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
|
|
206
225
|
},
|
|
226
|
+
__wbg_set_1eb0999cf5d27fc8: function(arg0, arg1, arg2) {
|
|
227
|
+
const ret = arg0.set(arg1, arg2);
|
|
228
|
+
return ret;
|
|
229
|
+
},
|
|
207
230
|
__wbg_set_3f1d0b984ed272ed: function(arg0, arg1, arg2) {
|
|
208
231
|
arg0[arg1] = arg2;
|
|
209
232
|
},
|
|
@@ -215,12 +238,17 @@ function __wbg_get_imports() {
|
|
|
215
238
|
const ret = arg0;
|
|
216
239
|
return ret;
|
|
217
240
|
},
|
|
218
|
-
__wbindgen_cast_0000000000000002: function(arg0
|
|
241
|
+
__wbindgen_cast_0000000000000002: function(arg0) {
|
|
242
|
+
// Cast intrinsic for `I64 -> Externref`.
|
|
243
|
+
const ret = arg0;
|
|
244
|
+
return ret;
|
|
245
|
+
},
|
|
246
|
+
__wbindgen_cast_0000000000000003: function(arg0, arg1) {
|
|
219
247
|
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
220
248
|
const ret = getStringFromWasm0(arg0, arg1);
|
|
221
249
|
return ret;
|
|
222
250
|
},
|
|
223
|
-
|
|
251
|
+
__wbindgen_cast_0000000000000004: function(arg0) {
|
|
224
252
|
// Cast intrinsic for `U64 -> Externref`.
|
|
225
253
|
const ret = BigInt.asUintN(64, arg0);
|
|
226
254
|
return ret;
|
package/usfm3_wasm_bg.wasm
CHANGED
|
Binary file
|