@gmb/bitmark-parser 6.2.0 → 6.3.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/dist/legacy.cjs CHANGED
@@ -119,7 +119,7 @@ function initLegacyNode(wasm2) {
119
119
  // src/generated/package_info.ts
120
120
  var PACKAGE_INFO = {
121
121
  "name": "@gmb/bitmark-parser",
122
- "version": "6.2.0",
122
+ "version": "6.3.1",
123
123
  "author": "Get More Brain Ltd <info@getmorebrain.com>",
124
124
  "license": "ISC",
125
125
  "description": "A parser for bitmark text, powered by WebAssembly."
@@ -150,16 +150,14 @@ function validateVersionOptions(opts) {
150
150
  }
151
151
  function validateBitmarkOptions(o) {
152
152
  if (o.explicitTextFormat) unsupportedOption("bitmarkOptions.explicitTextFormat");
153
- if (o.prettifyJson !== void 0 && o.prettifyJson !== false) {
154
- unsupportedOption("bitmarkOptions.prettifyJson", "embedded-JSON body prettification is not supported");
153
+ if (o.cardSetVersion === 1) {
154
+ unsupportedOption("bitmarkOptions.cardSetVersion: 1", V3_ONLY);
155
155
  }
156
- if (o.cardSetVersion === 1) unsupportedOption("bitmarkOptions.cardSetVersion: 1", V3_ONLY);
157
156
  if (o.debugGenerationInline) unsupportedOption("bitmarkOptions.debugGenerationInline");
158
157
  if (o.noBreakscaping) unsupportedOption("bitmarkOptions.noBreakscaping");
159
158
  }
160
159
  function validateJsonOptions(o) {
161
160
  if (o.textAsPlainText) unsupportedOption("jsonOptions.textAsPlainText", V3_ONLY);
162
- if (o.excludeUnknownProperties) unsupportedOption("jsonOptions.excludeUnknownProperties");
163
161
  if (o.debugGenerationInline) unsupportedOption("jsonOptions.debugGenerationInline");
164
162
  }
165
163
  function prettyIndent(prettify) {
@@ -195,6 +193,14 @@ function isPseudoAst(v) {
195
193
  return v !== null && typeof v === "object" && (PSEUDO_AST_MARKER in v || Array.isArray(v.bits));
196
194
  }
197
195
 
196
+ // src/legacy/generated/resource-collection-keys.ts
197
+ var RESOURCE_COLLECTION_KEYS = {
198
+ "extractor-image": { key: "images", resourceType: "image" },
199
+ "extractor-image-collapsible": { key: "images", resourceType: "image" },
200
+ "images-logo-grave": { key: "logos", resourceType: "image" },
201
+ "prototype-images": { key: "images", resourceType: "image" }
202
+ };
203
+
198
204
  // src/legacy/builder.ts
199
205
  var BUILT_BIT_PARSER = /* @__PURE__ */ Symbol.for("@gmb/bitmark-parser/legacy-built-bit-parser");
200
206
  var DATA_KEY_TO_JSON_KEY = {
@@ -207,6 +213,13 @@ var DEPRECATED_TEXT_FORMATS = {
207
213
  "bitmark--": "bitmark++",
208
214
  "bitmark+": "bitmark++"
209
215
  };
216
+ var CONFIG_BODY_FORMAT_TO_TEXT_FORMAT = {
217
+ bitmark: "bitmark++",
218
+ text: "text",
219
+ json: "json",
220
+ latex: "latex",
221
+ xml: "xml"
222
+ };
210
223
  var TAG_TEXT_KEYS = [
211
224
  "title",
212
225
  "subtitle",
@@ -239,16 +252,20 @@ var Builder = class {
239
252
  * NOTE (documented divergences from bpg):
240
253
  * - the return value is bit JSON, not bpg's internal AST node model;
241
254
  * - `resourceType` (an inference hint in bpg) is not carried into the
242
- * JSON — the attached `resource` object is authoritative;
243
- * - more than one entry in `resources` passes through under a
244
- * `resources` key (kept visible, not silently dropped) — the canonical
245
- * single attachment is `resource`.
255
+ * JSON — the attached `resource` object is authoritative.
256
+ *
257
+ * `resources` follows bpg's JsonGenerator routing: on a bit whose config
258
+ * maps a repeatable resource tag group onto a collection key (e.g.
259
+ * `images` / `logos` — see the generated RESOURCE_COLLECTION_KEYS), the
260
+ * matching-type entries land under that key; on every other bit the first
261
+ * entry becomes the canonical single `resource` (as bpg: "if there is
262
+ * more than one resource, use the first one").
246
263
  */
247
264
  buildBit(data, _options) {
248
265
  const wasm2 = getLegacyWasm();
249
266
  const src = { ...data };
250
267
  const bitType = src.bitType;
251
- this.assertKnownBitType(bitType);
268
+ const bitConfig = this.getBitConfig(bitType);
252
269
  const bit = {};
253
270
  bit.type = bitType;
254
271
  if (src.isCommented) {
@@ -261,6 +278,8 @@ var Builder = class {
261
278
  if (textFormat !== void 0) {
262
279
  bit.format = DEPRECATED_TEXT_FORMATS[textFormat] ?? textFormat;
263
280
  delete src.textFormat;
281
+ } else {
282
+ bit.format = CONFIG_BODY_FORMAT_TO_TEXT_FORMAT[bitConfig.bodyFormat ?? ""] ?? "bitmark++";
264
283
  }
265
284
  delete src.resourceType;
266
285
  const body = src.body;
@@ -278,12 +297,15 @@ var Builder = class {
278
297
  delete src.__isDefaultExample;
279
298
  }
280
299
  const resources = src.resources;
281
- if (resources !== void 0) {
282
- if (Array.isArray(resources)) {
283
- if (resources.length === 1) bit.resource = resources[0];
284
- else if (resources.length > 1) bit.resources = resources;
285
- } else {
286
- bit.resource = resources;
300
+ if (resources !== void 0 && bitType !== void 0) {
301
+ const list = Array.isArray(resources) ? resources : [resources];
302
+ const collection = RESOURCE_COLLECTION_KEYS[bitType];
303
+ if (collection) {
304
+ bit[collection.key] = list.filter(
305
+ (r) => r !== null && typeof r === "object" && r.type === collection.resourceType
306
+ );
307
+ } else if (list.length >= 1) {
308
+ bit.resource = list[0];
287
309
  }
288
310
  delete src.resources;
289
311
  }
@@ -301,7 +323,7 @@ var Builder = class {
301
323
  }
302
324
  }
303
325
  this.parseStringTexts(bit);
304
- const out = wasm2.convert(JSON.stringify([{ bit }]), "json", "json", "optimized", false, 2, 1);
326
+ const out = wasm2.convert(JSON.stringify([{ bit }]), "json", "json", "optimized", false, 2, 1, false);
305
327
  if (out.startsWith("error:")) {
306
328
  throw new Error(out.slice("error:".length).trim());
307
329
  }
@@ -349,6 +371,12 @@ var Builder = class {
349
371
  * (inline marks become TextAst marks); the composer would otherwise treat
350
372
  * them as literal text. Converts top-level JsonText fields in place.
351
373
  * Nested (card-content) strings are left literal — documented divergence.
374
+ *
375
+ * A string body is dispatched on the bit's resolved text format, as bpg's
376
+ * buildBody: bitmark text is parsed to TextAst, `json` is JSON.parsed
377
+ * (unparseable → null), and plain-text formats (text/latex/xml) stay
378
+ * verbatim. Tag texts are always bitmark text, independent of body format
379
+ * (bpg TextParser.toAst ignores format; only location matters).
352
380
  */
353
381
  parseStringTexts(bit) {
354
382
  const wasm2 = getLegacyWasm();
@@ -363,29 +391,36 @@ var Builder = class {
363
391
  };
364
392
  const format = bit.format;
365
393
  const bitmarkBody = format === void 0 || format === "bitmark++" || format === "bitmark+";
366
- if (typeof bit.body === "string" && bitmarkBody) {
367
- bit.body = toAst(bit.body, "body");
394
+ if (typeof bit.body === "string") {
395
+ if (format === "json") {
396
+ try {
397
+ bit.body = JSON.parse(bit.body);
398
+ } catch {
399
+ bit.body = null;
400
+ }
401
+ } else if (bitmarkBody) {
402
+ bit.body = toAst(bit.body, "body");
403
+ }
368
404
  }
369
405
  for (const key of TAG_TEXT_KEYS) {
370
406
  const v = bit[key];
371
407
  if (typeof v === "string") bit[key] = toAst(v, "tag");
372
408
  }
373
409
  }
374
- /** Throw bpg's exact unknown-bit-type error (`Config.getBitConfig` parity). */
375
- assertKnownBitType(bitType) {
410
+ /**
411
+ * Look up the bit's config (`wasm.info`); throws bpg's exact
412
+ * unknown-bit-type error (`Config.getBitConfig` parity).
413
+ */
414
+ getBitConfig(bitType) {
376
415
  const wasm2 = getLegacyWasm();
377
- let known = false;
378
416
  if (bitType !== void 0) {
379
417
  try {
380
418
  const info = JSON.parse(wasm2.info("bit", "json", bitType, false, 2));
381
- known = info.error === void 0;
419
+ if (info.error === void 0) return info;
382
420
  } catch {
383
- known = false;
384
421
  }
385
422
  }
386
- if (!known) {
387
- throw new Error(`No config found for bit: ${bitType}`);
388
- }
423
+ throw new Error(`No config found for bit: ${bitType}`);
389
424
  }
390
425
  };
391
426
  function stripUndefined(src, exclude) {
@@ -425,8 +460,10 @@ var BitmarkParserGenerator = class {
425
460
  const outputFormat = opts.outputFormat ?? (isBitmark ? "json" : "bitmark");
426
461
  const coreFormat = outputFormat === "ast" ? "json" : outputFormat;
427
462
  const { pretty, indent } = prettyIndent(jsonOptions.prettify);
463
+ const emit = coreFormat === "bitmark" ? prettyIndent(bitmarkOptions.prettifyJson) : { pretty, indent };
428
464
  const spaces = spacesAround(bitmarkOptions.spacesAroundValues);
429
- const out = wasm2.convert(source, isBitmark ? "bitmark" : "json", coreFormat, "optimized", pretty, indent, spaces);
465
+ const includeUnknown = !jsonOptions.excludeUnknownProperties;
466
+ const out = wasm2.convert(source, isBitmark ? "bitmark" : "json", coreFormat, "optimized", emit.pretty, emit.indent, spaces, includeUnknown);
430
467
  this.throwOnError(out);
431
468
  if (outputFormat === "bitmark" || outputFormat === "text") {
432
469
  return this.deliver(out, opts.outputFile, opts.fileOptions);
@@ -456,7 +493,9 @@ var BitmarkParserGenerator = class {
456
493
  this.checkBrowserFileWrite(opts.outputFile);
457
494
  const wasm2 = getLegacyWasm();
458
495
  const { source, isBitmark } = this.resolveInput(input, opts.inputFormat);
459
- const { pretty, indent } = prettyIndent(jsonOptions.prettify);
496
+ const { pretty, indent } = prettyIndent(
497
+ isBitmark ? bitmarkOptions.prettifyJson : jsonOptions.prettify
498
+ );
460
499
  const spaces = spacesAround(bitmarkOptions.spacesAroundValues);
461
500
  const out = wasm2.canonicalize(source, isBitmark ? "bitmark" : "json", "optimized", pretty, indent, spaces);
462
501
  this.throwOnError(out);
@@ -508,7 +547,7 @@ var BitmarkParserGenerator = class {
508
547
  const isHtmlInput = opts.inputFormat === "html" || opts.inputFormat === void 0 && typeof input === "string" && /<table[\s>]/iu.test(inStr);
509
548
  if (!isHtmlInput) {
510
549
  const { source, isBitmark } = this.resolveInput(input, void 0);
511
- const out2 = wasm2.convert(source, isBitmark ? "bitmark" : "json", "html", "optimized", false, 2, 1);
550
+ const out2 = wasm2.convert(source, isBitmark ? "bitmark" : "json", "html", "optimized", false, 2, 1, false);
512
551
  this.throwOnError(out2);
513
552
  return this.deliver(extractHtmlTables(out2).join("\n"), opts.outputFile, opts.fileOptions);
514
553
  }
@@ -518,12 +557,12 @@ var BitmarkParserGenerator = class {
518
557
  const { pretty, indent } = prettyIndent(jsonOptions.prettify);
519
558
  const spaces = spacesAround(bitmarkOptions.spacesAroundValues);
520
559
  if (outputFormat === "html") {
521
- const out2 = wasm2.convert(wrapped, "html", "html", "optimized", false, 2, 1);
560
+ const out2 = wasm2.convert(wrapped, "html", "html", "optimized", false, 2, 1, false);
522
561
  this.throwOnError(out2);
523
562
  return this.deliver(extractHtmlTables(out2).join("\n"), opts.outputFile, opts.fileOptions);
524
563
  }
525
564
  const coreFormat = outputFormat === "ast" ? "json" : outputFormat;
526
- const out = wasm2.convert(wrapped, "html", coreFormat, "optimized", pretty, indent, spaces);
565
+ const out = wasm2.convert(wrapped, "html", coreFormat, "optimized", pretty, indent, spaces, false);
527
566
  this.throwOnError(out);
528
567
  if (outputFormat === "bitmark" || outputFormat === "text") {
529
568
  return this.deliver(out, opts.outputFile, opts.fileOptions);
@@ -548,7 +587,7 @@ var BitmarkParserGenerator = class {
548
587
  const opts = Object.assign({}, options);
549
588
  const wasm2 = getLegacyWasm();
550
589
  const { source, isBitmark } = this.resolveInput(input, opts.inputFormat);
551
- const out = wasm2.convert(source, isBitmark ? "bitmark" : "json", "json", "optimized", false, 2, 1);
590
+ const out = wasm2.convert(source, isBitmark ? "bitmark" : "json", "json", "optimized", false, 2, 1, true);
552
591
  this.throwOnError(out);
553
592
  return makePseudoAst(JSON.parse(out));
554
593
  }
@@ -655,7 +694,7 @@ var BitmarkParserGenerator = class {
655
694
  }
656
695
  }
657
696
  const { source, isBitmark } = this.resolveInput(input, void 0);
658
- const out = wasm2.convert(source, isBitmark ? "bitmark" : "json", "text", "optimized", false, 2, 1);
697
+ const out = wasm2.convert(source, isBitmark ? "bitmark" : "json", "text", "optimized", false, 2, 1, false);
659
698
  this.throwOnError(out);
660
699
  return out;
661
700
  }