@gmb/bitmark-parser-generator 5.14.0 → 5.16.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/dist/browser/bitmark-parser-generator.min.js +1 -1
- package/dist/browser/bundle-report.html +2 -2
- package/dist/browser/cjs/index.cjs +1669 -1446
- package/dist/browser/cjs/index.cjs.map +1 -1
- package/dist/browser/cjs/index.d.cts +51 -2
- package/dist/browser/esm/index.d.ts +51 -2
- package/dist/browser/esm/index.js +1668 -1446
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/cli/main.js +523 -6
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +488 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -2
- package/dist/index.d.ts +51 -2
- package/dist/index.js +487 -6
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
package/dist/cli/main.js
CHANGED
|
@@ -1176,6 +1176,7 @@ var propertyKeys = {
|
|
|
1176
1176
|
property_availableClassifications: "@availableClassifications",
|
|
1177
1177
|
property_brandColor: "@brandColor",
|
|
1178
1178
|
property_brandColorName: "@brandColorName",
|
|
1179
|
+
property_backgroundImage: "@backgroundImage",
|
|
1179
1180
|
property_blockId: "@blockId",
|
|
1180
1181
|
property_book: "@book",
|
|
1181
1182
|
property_bookAlias: "@bookAlias",
|
|
@@ -1469,7 +1470,8 @@ var resourceKeys = {
|
|
|
1469
1470
|
resource_imagePlaceholder: "&imagePlaceholder",
|
|
1470
1471
|
resource_previewImage: "&previewImage",
|
|
1471
1472
|
resource_previewVideo: "&previewVideo",
|
|
1472
|
-
resource_coverImage: "&coverImage"
|
|
1473
|
+
resource_coverImage: "&coverImage",
|
|
1474
|
+
resource_backgroundImage: "&backgroundImage"
|
|
1473
1475
|
};
|
|
1474
1476
|
|
|
1475
1477
|
// src/utils/StringUtils.ts
|
|
@@ -1696,7 +1698,8 @@ var ResourceType = {
|
|
|
1696
1698
|
platformBackgroundImage: "platformBackgroundImage",
|
|
1697
1699
|
previewImage: "previewImage",
|
|
1698
1700
|
previewVideo: "previewVideo",
|
|
1699
|
-
coverImage: "coverImage"
|
|
1701
|
+
coverImage: "coverImage",
|
|
1702
|
+
backgroundImage: "backgroundImage"
|
|
1700
1703
|
};
|
|
1701
1704
|
function resourceTypeToConfigKey(type) {
|
|
1702
1705
|
return `&${stringUtils.kebabToCamel(type)}`;
|
|
@@ -3735,6 +3738,22 @@ var GROUPS = {
|
|
|
3735
3738
|
}
|
|
3736
3739
|
]
|
|
3737
3740
|
},
|
|
3741
|
+
{
|
|
3742
|
+
key: ConfigKey.property_backgroundImage,
|
|
3743
|
+
description: "The background image(s) of the book",
|
|
3744
|
+
format: TagFormat.plainText,
|
|
3745
|
+
maxCount: Count.infinity
|
|
3746
|
+
},
|
|
3747
|
+
{
|
|
3748
|
+
key: ConfigKey.resource_backgroundImage,
|
|
3749
|
+
description: "The background image of the book",
|
|
3750
|
+
chain: [
|
|
3751
|
+
{
|
|
3752
|
+
key: ConfigKey.group_resourceImageCommon,
|
|
3753
|
+
description: "Common image properties for the background image resource"
|
|
3754
|
+
}
|
|
3755
|
+
]
|
|
3756
|
+
},
|
|
3738
3757
|
{
|
|
3739
3758
|
key: ConfigKey.property_coverColor,
|
|
3740
3759
|
description: "The cover color of the book",
|
|
@@ -10857,7 +10876,7 @@ var instance2 = new Config();
|
|
|
10857
10876
|
// src/generated/package_info.ts
|
|
10858
10877
|
var PACKAGE_INFO = {
|
|
10859
10878
|
"name": "@gmb/bitmark-parser-generator",
|
|
10860
|
-
"version": "5.
|
|
10879
|
+
"version": "5.16.0",
|
|
10861
10880
|
"license": "ISC"};
|
|
10862
10881
|
var Environment = {
|
|
10863
10882
|
unknown: "",
|
|
@@ -11215,6 +11234,8 @@ var NodeType = {
|
|
|
11215
11234
|
avatarImage: "avatarImage",
|
|
11216
11235
|
backgroundWallpaper: "backgroundWallpaper",
|
|
11217
11236
|
backgroundWallpaperValue: "backgroundWallpaperValue",
|
|
11237
|
+
backgroundImage: "backgroundImage",
|
|
11238
|
+
backgroundImageValue: "backgroundImageValue",
|
|
11218
11239
|
bitLevel: "bitLevel",
|
|
11219
11240
|
// bit level
|
|
11220
11241
|
bitmarkAst: "bitmarkAst",
|
|
@@ -23339,6 +23360,7 @@ var ResourceBuilder = class extends BaseBuilder {
|
|
|
23339
23360
|
case ResourceType.platformBackgroundImage:
|
|
23340
23361
|
case ResourceType.previewImage:
|
|
23341
23362
|
case ResourceType.coverImage:
|
|
23363
|
+
case ResourceType.backgroundImage:
|
|
23342
23364
|
node = this.imageResource(context, finalData, type);
|
|
23343
23365
|
break;
|
|
23344
23366
|
// case ResourceType.imageResponsive: {
|
|
@@ -24614,6 +24636,12 @@ var Builder = class extends BaseBuilder {
|
|
|
24614
24636
|
data.coverColor,
|
|
24615
24637
|
options
|
|
24616
24638
|
),
|
|
24639
|
+
backgroundImage: typeof data.backgroundImage === "string" || Array.isArray(data.backgroundImage) ? this.toAstProperty(
|
|
24640
|
+
bitType,
|
|
24641
|
+
ConfigKey.property_backgroundImage,
|
|
24642
|
+
instance4.asArray(data.backgroundImage),
|
|
24643
|
+
options
|
|
24644
|
+
) : this.toImageResource(context, data.backgroundImage),
|
|
24617
24645
|
publications: this.toAstProperty(
|
|
24618
24646
|
bitType,
|
|
24619
24647
|
ConfigKey.property_publications,
|
|
@@ -28671,6 +28699,62 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
|
|
|
28671
28699
|
ignoreTrue: propertyConfig.defaultValue === "true"
|
|
28672
28700
|
});
|
|
28673
28701
|
}
|
|
28702
|
+
// bitmarkAst -> bits -> bitsValue -> backgroundImage (when it's a resource object or property array)
|
|
28703
|
+
enter_backgroundImage(node, route) {
|
|
28704
|
+
const value = node.value;
|
|
28705
|
+
if (value && typeof value === "object" && !Array.isArray(value) && "type" in value) {
|
|
28706
|
+
const resource = value;
|
|
28707
|
+
this.writeNL();
|
|
28708
|
+
this.writePropertyStyleResource(node.key, resource);
|
|
28709
|
+
return true;
|
|
28710
|
+
}
|
|
28711
|
+
if (Array.isArray(value)) {
|
|
28712
|
+
if (value == null) return true;
|
|
28713
|
+
const parent = this.getParentNode(route);
|
|
28714
|
+
if (parent?.key !== NodeType.bitsValue) return true;
|
|
28715
|
+
const bitType = this.getBitType(route);
|
|
28716
|
+
if (!bitType) return true;
|
|
28717
|
+
const config = instance2.getBitConfig(bitType);
|
|
28718
|
+
const propertyConfig = instance2.getTagConfigForTag(
|
|
28719
|
+
config.tags,
|
|
28720
|
+
ConfigKey.property_backgroundImage
|
|
28721
|
+
);
|
|
28722
|
+
if (!propertyConfig) return true;
|
|
28723
|
+
this.writeNL_IfNotChain(route);
|
|
28724
|
+
this.writeProperty(propertyConfig.tag, value, route, {
|
|
28725
|
+
format: propertyConfig.format ?? TagFormat.plainText,
|
|
28726
|
+
array: propertyConfig.array ?? false,
|
|
28727
|
+
writeEmpty: true,
|
|
28728
|
+
ignoreFalse: propertyConfig.defaultValue === "false",
|
|
28729
|
+
ignoreTrue: propertyConfig.defaultValue === "true"
|
|
28730
|
+
});
|
|
28731
|
+
}
|
|
28732
|
+
return true;
|
|
28733
|
+
}
|
|
28734
|
+
// bitmarkAst -> bits -> bitsValue -> backgroundImage (when it's a property string)
|
|
28735
|
+
// This is called when backgroundImage is a simple string value
|
|
28736
|
+
leaf_backgroundImage(node, route) {
|
|
28737
|
+
const value = node.value;
|
|
28738
|
+
if (value == null) return;
|
|
28739
|
+
const parent = this.getParentNode(route);
|
|
28740
|
+
if (parent?.key !== NodeType.bitsValue) return;
|
|
28741
|
+
const bitType = this.getBitType(route);
|
|
28742
|
+
if (!bitType) return;
|
|
28743
|
+
const config = instance2.getBitConfig(bitType);
|
|
28744
|
+
const propertyConfig = instance2.getTagConfigForTag(
|
|
28745
|
+
config.tags,
|
|
28746
|
+
ConfigKey.property_backgroundImage
|
|
28747
|
+
);
|
|
28748
|
+
if (!propertyConfig) return;
|
|
28749
|
+
this.writeNL_IfNotChain(route);
|
|
28750
|
+
this.writeProperty(propertyConfig.tag, node.value, route, {
|
|
28751
|
+
format: propertyConfig.format ?? TagFormat.plainText,
|
|
28752
|
+
array: propertyConfig.array ?? false,
|
|
28753
|
+
writeEmpty: true,
|
|
28754
|
+
ignoreFalse: propertyConfig.defaultValue === "false",
|
|
28755
|
+
ignoreTrue: propertyConfig.defaultValue === "true"
|
|
28756
|
+
});
|
|
28757
|
+
}
|
|
28674
28758
|
exit_imagePlaceholder(_node, _route) {
|
|
28675
28759
|
}
|
|
28676
28760
|
// bitmarkAst -> bits -> bitsValue -> posterImage
|
|
@@ -30277,6 +30361,12 @@ var JsonGenerator = class extends AstWalkerGenerator {
|
|
|
30277
30361
|
array: Array.isArray(node.value)
|
|
30278
30362
|
});
|
|
30279
30363
|
}
|
|
30364
|
+
// bitmarkAst -> bits -> bitsValue -> backgroundImage
|
|
30365
|
+
enter_backgroundImage(node, route) {
|
|
30366
|
+
return this.standardHandler(node, route, NodeType.bitsValue, {
|
|
30367
|
+
array: Array.isArray(node.value)
|
|
30368
|
+
});
|
|
30369
|
+
}
|
|
30280
30370
|
// bitmarkAst -> bits -> bitsValue -> resources
|
|
30281
30371
|
enter_resources(node, route) {
|
|
30282
30372
|
const resources = node.value;
|
|
@@ -34645,7 +34735,7 @@ function resourceContentProcessor(context, _contentDepth, tagsConfig, content, t
|
|
|
34645
34735
|
...tags2
|
|
34646
34736
|
});
|
|
34647
34737
|
if (resource) {
|
|
34648
|
-
if (configKey === ConfigKey.resource_backgroundWallpaper || configKey === ConfigKey.resource_imagePlaceholder || configKey === ConfigKey.resource_platformIcon || configKey === ConfigKey.resource_platformLogo || configKey === ConfigKey.resource_platformBackgroundImage || configKey === ConfigKey.resource_previewImage || configKey === ConfigKey.resource_previewVideo || configKey === ConfigKey.resource_coverImage) {
|
|
34738
|
+
if (configKey === ConfigKey.resource_backgroundWallpaper || configKey === ConfigKey.resource_imagePlaceholder || configKey === ConfigKey.resource_platformIcon || configKey === ConfigKey.resource_platformLogo || configKey === ConfigKey.resource_platformBackgroundImage || configKey === ConfigKey.resource_previewImage || configKey === ConfigKey.resource_previewVideo || configKey === ConfigKey.resource_coverImage || configKey === ConfigKey.resource_backgroundImage) {
|
|
34649
34739
|
if (target.propertyStyleResources) {
|
|
34650
34740
|
if (target.propertyStyleResources[resourceType]) {
|
|
34651
34741
|
if (!Array.isArray(target.propertyStyleResources[resourceType])) {
|
|
@@ -39204,6 +39294,265 @@ var JsonFileGenerator = class {
|
|
|
39204
39294
|
this.generator.generateSync(_ast);
|
|
39205
39295
|
}
|
|
39206
39296
|
};
|
|
39297
|
+
|
|
39298
|
+
// src/generator/plainText/PlainTextGenerator.ts
|
|
39299
|
+
var TEXT_NODE_TYPES = new Set(Object.values(TextNodeType));
|
|
39300
|
+
var PlainTextGenerator = class {
|
|
39301
|
+
/**
|
|
39302
|
+
* Generate plain text from a string or JSON object.
|
|
39303
|
+
*
|
|
39304
|
+
* @param input - A string (plain or JSON-encoded) or a parsed JSON value.
|
|
39305
|
+
* @returns The extracted plain text.
|
|
39306
|
+
*/
|
|
39307
|
+
generate(input) {
|
|
39308
|
+
let data = input;
|
|
39309
|
+
if (typeof data === "string") {
|
|
39310
|
+
try {
|
|
39311
|
+
data = JSON.parse(data);
|
|
39312
|
+
} catch (_e) {
|
|
39313
|
+
return data;
|
|
39314
|
+
}
|
|
39315
|
+
}
|
|
39316
|
+
return this.walk(data).trim();
|
|
39317
|
+
}
|
|
39318
|
+
// ---------------------------------------------------------------------------
|
|
39319
|
+
// Private helpers
|
|
39320
|
+
// ---------------------------------------------------------------------------
|
|
39321
|
+
walk(value) {
|
|
39322
|
+
if (value == null) return "";
|
|
39323
|
+
if (typeof value === "string") return value;
|
|
39324
|
+
if (typeof value !== "object") return "";
|
|
39325
|
+
if (Array.isArray(value)) {
|
|
39326
|
+
if (value.length === 0) return "";
|
|
39327
|
+
if (this.isTextAst(value)) {
|
|
39328
|
+
return this.textAstToPlainText(value);
|
|
39329
|
+
}
|
|
39330
|
+
return value.map((v) => this.walk(v)).filter(Boolean).join("\n");
|
|
39331
|
+
}
|
|
39332
|
+
const obj = value;
|
|
39333
|
+
if (this.isTextNode(obj)) {
|
|
39334
|
+
return this.textNodeToPlainText(obj);
|
|
39335
|
+
}
|
|
39336
|
+
if (this.isBitWrapper(obj)) {
|
|
39337
|
+
return this.walk(obj["bit"]);
|
|
39338
|
+
}
|
|
39339
|
+
const parts = [];
|
|
39340
|
+
for (const val of Object.values(obj)) {
|
|
39341
|
+
if (val == null || typeof val !== "object") continue;
|
|
39342
|
+
const text = this.walk(val);
|
|
39343
|
+
if (text) parts.push(text);
|
|
39344
|
+
}
|
|
39345
|
+
return parts.join("\n");
|
|
39346
|
+
}
|
|
39347
|
+
// -- Type guards -----------------------------------------------------------
|
|
39348
|
+
isTextNode(obj) {
|
|
39349
|
+
return typeof obj["type"] === "string" && TEXT_NODE_TYPES.has(obj["type"]);
|
|
39350
|
+
}
|
|
39351
|
+
isTextAst(arr) {
|
|
39352
|
+
const first = arr[0];
|
|
39353
|
+
return typeof first === "object" && first !== null && !Array.isArray(first) && this.isTextNode(first);
|
|
39354
|
+
}
|
|
39355
|
+
isBitWrapper(obj) {
|
|
39356
|
+
return "bit" in obj && typeof obj["bit"] === "object" && obj["bit"] !== null && !Array.isArray(obj["bit"]);
|
|
39357
|
+
}
|
|
39358
|
+
// -- TextNode extraction ---------------------------------------------------
|
|
39359
|
+
textAstToPlainText(ast) {
|
|
39360
|
+
return ast.map((node) => this.textNodeToPlainText(node)).join("\n");
|
|
39361
|
+
}
|
|
39362
|
+
textNodeToPlainText(node) {
|
|
39363
|
+
const { type, text, content } = node;
|
|
39364
|
+
switch (type) {
|
|
39365
|
+
case TextNodeType.text:
|
|
39366
|
+
return this.textWithMarks(node);
|
|
39367
|
+
case TextNodeType.hardBreak:
|
|
39368
|
+
return "\n";
|
|
39369
|
+
// Block elements whose children are joined without extra separator
|
|
39370
|
+
case TextNodeType.paragraph:
|
|
39371
|
+
case TextNodeType.heading:
|
|
39372
|
+
case TextNodeType.section:
|
|
39373
|
+
case TextNodeType.gap:
|
|
39374
|
+
case TextNodeType.select:
|
|
39375
|
+
case TextNodeType.highlight:
|
|
39376
|
+
case TextNodeType.mark:
|
|
39377
|
+
case TextNodeType.codeBlock:
|
|
39378
|
+
return content ? content.map((c) => this.textNodeToPlainText(c)).join("") : text ?? "";
|
|
39379
|
+
// List items are handled by listToPlainText with indent context
|
|
39380
|
+
case TextNodeType.listItem:
|
|
39381
|
+
return content ? content.map((c) => this.textNodeToPlainText(c)).join("") : text ?? "";
|
|
39382
|
+
// Task item – handled by taskListToPlainText, but fallback if encountered standalone
|
|
39383
|
+
case TextNodeType.taskItem: {
|
|
39384
|
+
const checked = node.attrs?.checked ?? false;
|
|
39385
|
+
const prefix = checked ? "[x] " : "[ ] ";
|
|
39386
|
+
const itemText = content ? content.map((c) => this.textNodeToPlainText(c)).join("") : text ?? "";
|
|
39387
|
+
return `${prefix}${itemText}`;
|
|
39388
|
+
}
|
|
39389
|
+
// List containers – rendered with indent-aware helper
|
|
39390
|
+
case TextNodeType.noBulletList:
|
|
39391
|
+
case TextNodeType.bulletList:
|
|
39392
|
+
case TextNodeType.orderedList:
|
|
39393
|
+
case TextNodeType.orderedListRoman:
|
|
39394
|
+
case TextNodeType.orderedListRomanLower:
|
|
39395
|
+
case TextNodeType.letteredList:
|
|
39396
|
+
case TextNodeType.letteredListLower:
|
|
39397
|
+
return this.listToPlainText(node, 0);
|
|
39398
|
+
// Task list – rendered with indent-aware helper
|
|
39399
|
+
case TextNodeType.taskList:
|
|
39400
|
+
return this.taskListToPlainText(node, 0);
|
|
39401
|
+
// Images – return alt text when available
|
|
39402
|
+
case TextNodeType.image:
|
|
39403
|
+
case TextNodeType.imageInline: {
|
|
39404
|
+
const attrs = node.attrs;
|
|
39405
|
+
return attrs?.alt ?? "";
|
|
39406
|
+
}
|
|
39407
|
+
// LaTeX – return the formula source
|
|
39408
|
+
case TextNodeType.latex: {
|
|
39409
|
+
const latexAttrs = node.attrs;
|
|
39410
|
+
return latexAttrs?.formula ?? "";
|
|
39411
|
+
}
|
|
39412
|
+
default:
|
|
39413
|
+
return content ? content.map((c) => this.textNodeToPlainText(c)).join("") : text ?? "";
|
|
39414
|
+
}
|
|
39415
|
+
}
|
|
39416
|
+
listToPlainText(node, depth) {
|
|
39417
|
+
const { type, content } = node;
|
|
39418
|
+
if (!content || content.length === 0) return "";
|
|
39419
|
+
const indent = " ".repeat(depth);
|
|
39420
|
+
const start = node.attrs?.start ?? 1;
|
|
39421
|
+
const displayStart = start < 1 ? start + 1 : start;
|
|
39422
|
+
return content.map((child, i) => {
|
|
39423
|
+
const { inline, nested } = this.splitListItemContent(child, depth);
|
|
39424
|
+
const prefix = this.listItemPrefix(type, displayStart + i);
|
|
39425
|
+
const line = `${indent}${prefix}${inline}`;
|
|
39426
|
+
return nested ? `${line}
|
|
39427
|
+
${nested}` : line;
|
|
39428
|
+
}).join("\n");
|
|
39429
|
+
}
|
|
39430
|
+
taskListToPlainText(node, depth) {
|
|
39431
|
+
const { content } = node;
|
|
39432
|
+
if (!content || content.length === 0) return "";
|
|
39433
|
+
const indent = " ".repeat(depth);
|
|
39434
|
+
return content.map((child) => {
|
|
39435
|
+
const checked = child.attrs?.checked ?? false;
|
|
39436
|
+
const prefix = checked ? "[x] " : "[ ] ";
|
|
39437
|
+
const { inline, nested } = this.splitListItemContent(child, depth);
|
|
39438
|
+
const line = `${indent}${prefix}${inline}`;
|
|
39439
|
+
return nested ? `${line}
|
|
39440
|
+
${nested}` : line;
|
|
39441
|
+
}).join("\n");
|
|
39442
|
+
}
|
|
39443
|
+
splitListItemContent(item, depth) {
|
|
39444
|
+
const children = item.content ?? [];
|
|
39445
|
+
const inlineParts = [];
|
|
39446
|
+
const nestedParts = [];
|
|
39447
|
+
for (const child of children) {
|
|
39448
|
+
if (this.isListType(child.type)) {
|
|
39449
|
+
nestedParts.push(this.renderNestedList(child, depth + 1));
|
|
39450
|
+
} else {
|
|
39451
|
+
inlineParts.push(this.textNodeToPlainText(child));
|
|
39452
|
+
}
|
|
39453
|
+
}
|
|
39454
|
+
return {
|
|
39455
|
+
inline: inlineParts.join(""),
|
|
39456
|
+
nested: nestedParts.join("\n")
|
|
39457
|
+
};
|
|
39458
|
+
}
|
|
39459
|
+
isListType(type) {
|
|
39460
|
+
return type === TextNodeType.bulletList || type === TextNodeType.orderedList || type === TextNodeType.orderedListRoman || type === TextNodeType.orderedListRomanLower || type === TextNodeType.letteredList || type === TextNodeType.letteredListLower || type === TextNodeType.noBulletList || type === TextNodeType.taskList;
|
|
39461
|
+
}
|
|
39462
|
+
renderNestedList(node, depth) {
|
|
39463
|
+
if (node.type === TextNodeType.taskList) {
|
|
39464
|
+
return this.taskListToPlainText(node, depth);
|
|
39465
|
+
}
|
|
39466
|
+
return this.listToPlainText(node, depth);
|
|
39467
|
+
}
|
|
39468
|
+
listItemPrefix(listType, index) {
|
|
39469
|
+
switch (listType) {
|
|
39470
|
+
case TextNodeType.bulletList:
|
|
39471
|
+
return "\u2022 ";
|
|
39472
|
+
case TextNodeType.orderedList:
|
|
39473
|
+
return `${index}. `;
|
|
39474
|
+
case TextNodeType.orderedListRoman:
|
|
39475
|
+
return `${this.toRoman(index)}. `;
|
|
39476
|
+
case TextNodeType.orderedListRomanLower:
|
|
39477
|
+
return `${this.toRoman(index).toLowerCase()}. `;
|
|
39478
|
+
case TextNodeType.letteredList:
|
|
39479
|
+
return `${this.toLetter(index)}. `;
|
|
39480
|
+
case TextNodeType.letteredListLower:
|
|
39481
|
+
return `${this.toLetter(index).toLowerCase()}. `;
|
|
39482
|
+
case TextNodeType.noBulletList:
|
|
39483
|
+
default:
|
|
39484
|
+
return "";
|
|
39485
|
+
}
|
|
39486
|
+
}
|
|
39487
|
+
toRoman(num) {
|
|
39488
|
+
const romanNumerals = [
|
|
39489
|
+
[1e3, "M"],
|
|
39490
|
+
[900, "CM"],
|
|
39491
|
+
[500, "D"],
|
|
39492
|
+
[400, "CD"],
|
|
39493
|
+
[100, "C"],
|
|
39494
|
+
[90, "XC"],
|
|
39495
|
+
[50, "L"],
|
|
39496
|
+
[40, "XL"],
|
|
39497
|
+
[10, "X"],
|
|
39498
|
+
[9, "IX"],
|
|
39499
|
+
[5, "V"],
|
|
39500
|
+
[4, "IV"],
|
|
39501
|
+
[1, "I"]
|
|
39502
|
+
];
|
|
39503
|
+
let result = "";
|
|
39504
|
+
let remaining = num;
|
|
39505
|
+
for (const [value, numeral] of romanNumerals) {
|
|
39506
|
+
while (remaining >= value) {
|
|
39507
|
+
result += numeral;
|
|
39508
|
+
remaining -= value;
|
|
39509
|
+
}
|
|
39510
|
+
}
|
|
39511
|
+
return result;
|
|
39512
|
+
}
|
|
39513
|
+
toLetter(num) {
|
|
39514
|
+
let result = "";
|
|
39515
|
+
let remaining = num;
|
|
39516
|
+
while (remaining > 0) {
|
|
39517
|
+
remaining--;
|
|
39518
|
+
result = String.fromCharCode(65 + remaining % 26) + result;
|
|
39519
|
+
remaining = Math.floor(remaining / 26);
|
|
39520
|
+
}
|
|
39521
|
+
return result;
|
|
39522
|
+
}
|
|
39523
|
+
textWithMarks(node) {
|
|
39524
|
+
const { text, marks } = node;
|
|
39525
|
+
const parts = [];
|
|
39526
|
+
const linkMark = marks?.find((m) => m.type === "link");
|
|
39527
|
+
const href = linkMark?.attrs?.href;
|
|
39528
|
+
if (text && href && text !== href) {
|
|
39529
|
+
const hrefBare = href.replace(/^https?:\/\//, "");
|
|
39530
|
+
if (text.includes(hrefBare)) {
|
|
39531
|
+
parts.push(text.replace(hrefBare, href));
|
|
39532
|
+
} else if (text.includes(href)) {
|
|
39533
|
+
parts.push(text);
|
|
39534
|
+
} else {
|
|
39535
|
+
parts.push(`${text} ${href}`);
|
|
39536
|
+
}
|
|
39537
|
+
} else if (text) {
|
|
39538
|
+
parts.push(text);
|
|
39539
|
+
} else if (href) {
|
|
39540
|
+
parts.push(href);
|
|
39541
|
+
}
|
|
39542
|
+
if (marks) {
|
|
39543
|
+
for (const mark of marks) {
|
|
39544
|
+
if (mark.type === "footnote") {
|
|
39545
|
+
const footnote = mark;
|
|
39546
|
+
if (footnote.attrs?.content) {
|
|
39547
|
+
const footnoteText = footnote.attrs.content.map((c) => this.textNodeToPlainText(c)).join("");
|
|
39548
|
+
if (footnoteText) parts.push(footnoteText);
|
|
39549
|
+
}
|
|
39550
|
+
}
|
|
39551
|
+
}
|
|
39552
|
+
}
|
|
39553
|
+
return parts.join(" ");
|
|
39554
|
+
}
|
|
39555
|
+
};
|
|
39207
39556
|
var normalizeCardKey = (cardSetKey) => stringUtils.camelToKebab(cardSetKey);
|
|
39208
39557
|
var ConfigBuilder = class {
|
|
39209
39558
|
build(options) {
|
|
@@ -39905,7 +40254,25 @@ var Output = {
|
|
|
39905
40254
|
/**
|
|
39906
40255
|
* Output AST as a plain JS object, or a file
|
|
39907
40256
|
*/
|
|
39908
|
-
ast: "ast"
|
|
40257
|
+
ast: "ast",
|
|
40258
|
+
/**
|
|
40259
|
+
* Output plain text as a string, or a file
|
|
40260
|
+
*/
|
|
40261
|
+
text: "text"
|
|
40262
|
+
};
|
|
40263
|
+
var InputFormat = {
|
|
40264
|
+
/**
|
|
40265
|
+
* Input is bitmark
|
|
40266
|
+
*/
|
|
40267
|
+
bitmark: "bitmark",
|
|
40268
|
+
/**
|
|
40269
|
+
* Input is bitmarkText
|
|
40270
|
+
*/
|
|
40271
|
+
bitmarkText: "bitmarkText",
|
|
40272
|
+
/**
|
|
40273
|
+
* Input is plain text
|
|
40274
|
+
*/
|
|
40275
|
+
plainText: "plainText"
|
|
39909
40276
|
};
|
|
39910
40277
|
var BitmarkParserGenerator = class {
|
|
39911
40278
|
ast = new Ast();
|
|
@@ -39989,6 +40356,12 @@ var BitmarkParserGenerator = class {
|
|
|
39989
40356
|
* - input(JSON/AST) ==> output(bitmark)
|
|
39990
40357
|
* - input(bitmark) ==> output(JSON)
|
|
39991
40358
|
*
|
|
40359
|
+
* Output type can be overridden to one of the following:
|
|
40360
|
+
* - bitmark: output bitmark string
|
|
40361
|
+
* - json: output JSON as a plain JS object, or a file
|
|
40362
|
+
* - ast: output AST as a plain JS object, or a file
|
|
40363
|
+
* - text: output plain text as a string, or a file
|
|
40364
|
+
*
|
|
39992
40365
|
* By default, the result is returned as a string for bitmark, or a plain JS object for JSON/AST.
|
|
39993
40366
|
*
|
|
39994
40367
|
* The options can be used to write the output to a file and to set conversion options or override defaults.
|
|
@@ -40011,6 +40384,7 @@ var BitmarkParserGenerator = class {
|
|
|
40011
40384
|
const outputBitmark = outputFormat === Output.bitmark;
|
|
40012
40385
|
const outputJson = outputFormat === Output.json;
|
|
40013
40386
|
const outputAst = outputFormat === Output.ast;
|
|
40387
|
+
const outputText = outputFormat === Output.text;
|
|
40014
40388
|
const bitmarkParserType = BitmarkParserType.peggy;
|
|
40015
40389
|
let inStr = input;
|
|
40016
40390
|
const inputIsString = typeof input === "string";
|
|
@@ -40057,6 +40431,22 @@ var BitmarkParserGenerator = class {
|
|
|
40057
40431
|
}
|
|
40058
40432
|
}
|
|
40059
40433
|
};
|
|
40434
|
+
const bitmarkToText = (bitmarkStr) => {
|
|
40435
|
+
ast = this.bitmarkParser.toAst(bitmarkStr, {
|
|
40436
|
+
parserType: bitmarkParserType
|
|
40437
|
+
});
|
|
40438
|
+
const jsonGenerator = new JsonObjectGenerator(opts);
|
|
40439
|
+
const json = jsonGenerator.generateSync(ast);
|
|
40440
|
+
const textGenerator = new PlainTextGenerator();
|
|
40441
|
+
const str = textGenerator.generate(json);
|
|
40442
|
+
if (opts.outputFile) {
|
|
40443
|
+
fs3.writeFileSync(opts.outputFile, str, {
|
|
40444
|
+
encoding: "utf8"
|
|
40445
|
+
});
|
|
40446
|
+
} else {
|
|
40447
|
+
res = str;
|
|
40448
|
+
}
|
|
40449
|
+
};
|
|
40060
40450
|
const astToBitmark = (astJson) => {
|
|
40061
40451
|
if (opts.outputFile) {
|
|
40062
40452
|
const generator = new BitmarkFileGenerator(opts.outputFile, opts);
|
|
@@ -40079,6 +40469,19 @@ var BitmarkParserGenerator = class {
|
|
|
40079
40469
|
res = this.jsonStringifyPrettify(json, jsonOptions);
|
|
40080
40470
|
}
|
|
40081
40471
|
};
|
|
40472
|
+
const astToText = (astJson) => {
|
|
40473
|
+
const jsonGenerator = new JsonObjectGenerator(opts);
|
|
40474
|
+
const json = jsonGenerator.generateSync(astJson);
|
|
40475
|
+
const textGenerator = new PlainTextGenerator();
|
|
40476
|
+
const str = textGenerator.generate(json);
|
|
40477
|
+
if (opts.outputFile) {
|
|
40478
|
+
fs3.writeFileSync(opts.outputFile, str, {
|
|
40479
|
+
encoding: "utf8"
|
|
40480
|
+
});
|
|
40481
|
+
} else {
|
|
40482
|
+
res = str;
|
|
40483
|
+
}
|
|
40484
|
+
};
|
|
40082
40485
|
const jsonToBitmark = (astJson) => {
|
|
40083
40486
|
if (opts.outputFile) {
|
|
40084
40487
|
const generator = new BitmarkFileGenerator(opts.outputFile, opts);
|
|
@@ -40091,6 +40494,19 @@ var BitmarkParserGenerator = class {
|
|
|
40091
40494
|
const jsonToAst = (astJson) => {
|
|
40092
40495
|
res = this.jsonStringifyPrettify(astJson, jsonOptions);
|
|
40093
40496
|
};
|
|
40497
|
+
const jsonToText = (astJson) => {
|
|
40498
|
+
const jsonGenerator = new JsonObjectGenerator(opts);
|
|
40499
|
+
const json = jsonGenerator.generateSync(astJson);
|
|
40500
|
+
const textGenerator = new PlainTextGenerator();
|
|
40501
|
+
const str = textGenerator.generate(json);
|
|
40502
|
+
if (opts.outputFile) {
|
|
40503
|
+
fs3.writeFileSync(opts.outputFile, str, {
|
|
40504
|
+
encoding: "utf8"
|
|
40505
|
+
});
|
|
40506
|
+
} else {
|
|
40507
|
+
res = str;
|
|
40508
|
+
}
|
|
40509
|
+
};
|
|
40094
40510
|
const jsonToJson = (astJson) => {
|
|
40095
40511
|
astToJson(astJson);
|
|
40096
40512
|
};
|
|
@@ -40099,6 +40515,8 @@ var BitmarkParserGenerator = class {
|
|
|
40099
40515
|
bitmarkToBitmark(inStr);
|
|
40100
40516
|
} else if (outputAst) {
|
|
40101
40517
|
bitmarkToAst(inStr);
|
|
40518
|
+
} else if (outputText) {
|
|
40519
|
+
bitmarkToText(inStr);
|
|
40102
40520
|
} else {
|
|
40103
40521
|
bitmarkToJson(inStr);
|
|
40104
40522
|
}
|
|
@@ -40108,6 +40526,8 @@ var BitmarkParserGenerator = class {
|
|
|
40108
40526
|
astToAst(ast);
|
|
40109
40527
|
} else if (outputJson) {
|
|
40110
40528
|
astToJson(ast);
|
|
40529
|
+
} else if (outputText) {
|
|
40530
|
+
astToText(ast);
|
|
40111
40531
|
} else {
|
|
40112
40532
|
astToBitmark(ast);
|
|
40113
40533
|
}
|
|
@@ -40117,6 +40537,8 @@ var BitmarkParserGenerator = class {
|
|
|
40117
40537
|
jsonToJson(ast);
|
|
40118
40538
|
} else if (outputAst) {
|
|
40119
40539
|
jsonToAst(ast);
|
|
40540
|
+
} else if (outputText) {
|
|
40541
|
+
jsonToText(ast);
|
|
40120
40542
|
} else {
|
|
40121
40543
|
jsonToBitmark(ast);
|
|
40122
40544
|
}
|
|
@@ -40245,7 +40667,7 @@ var BitmarkParserGenerator = class {
|
|
|
40245
40667
|
return res;
|
|
40246
40668
|
}
|
|
40247
40669
|
/**
|
|
40248
|
-
* Convert bitmark text
|
|
40670
|
+
* Convert bitmark text to JSON, or JSON to bitmark text.
|
|
40249
40671
|
*
|
|
40250
40672
|
* Input type is detected automatically and may be:
|
|
40251
40673
|
* - string: bitmark text or JSON
|
|
@@ -40319,6 +40741,54 @@ var BitmarkParserGenerator = class {
|
|
|
40319
40741
|
}
|
|
40320
40742
|
return res;
|
|
40321
40743
|
}
|
|
40744
|
+
extractPlainText(input, options) {
|
|
40745
|
+
const dataIn = input;
|
|
40746
|
+
const inputFormat = options?.inputFormat;
|
|
40747
|
+
const isString2 = typeof input === "string";
|
|
40748
|
+
let data;
|
|
40749
|
+
const parseAutomatically = () => {
|
|
40750
|
+
let dataOut = dataIn;
|
|
40751
|
+
if (typeof dataIn === "string") {
|
|
40752
|
+
try {
|
|
40753
|
+
dataOut = JSON.parse(dataIn);
|
|
40754
|
+
} catch (_e) {
|
|
40755
|
+
let isBitmark = false;
|
|
40756
|
+
const bitmarkData = this.convert(dataIn, {
|
|
40757
|
+
outputFormat: Output.json
|
|
40758
|
+
});
|
|
40759
|
+
if (bitmarkData.length > 0) {
|
|
40760
|
+
const isError = bitmarkData[0].bit.type === BitType._error;
|
|
40761
|
+
if (!isError) {
|
|
40762
|
+
isBitmark = true;
|
|
40763
|
+
dataOut = bitmarkData;
|
|
40764
|
+
}
|
|
40765
|
+
}
|
|
40766
|
+
if (!isBitmark) {
|
|
40767
|
+
dataOut = this.convertText(dataIn, {
|
|
40768
|
+
textFormat: TextFormat.bitmarkText
|
|
40769
|
+
});
|
|
40770
|
+
}
|
|
40771
|
+
}
|
|
40772
|
+
}
|
|
40773
|
+
return dataOut;
|
|
40774
|
+
};
|
|
40775
|
+
if (inputFormat === InputFormat.bitmark) {
|
|
40776
|
+
data = this.convert(dataIn, {
|
|
40777
|
+
outputFormat: Output.json
|
|
40778
|
+
});
|
|
40779
|
+
} else if (inputFormat === InputFormat.bitmarkText) {
|
|
40780
|
+
data = this.convertText(dataIn, {
|
|
40781
|
+
textFormat: TextFormat.bitmarkText
|
|
40782
|
+
});
|
|
40783
|
+
} else if (inputFormat === InputFormat.plainText) {
|
|
40784
|
+
if (isString2) data = String(input);
|
|
40785
|
+
} else {
|
|
40786
|
+
data = parseAutomatically();
|
|
40787
|
+
}
|
|
40788
|
+
const generator = new PlainTextGenerator();
|
|
40789
|
+
const res = generator.generate(data);
|
|
40790
|
+
return res;
|
|
40791
|
+
}
|
|
40322
40792
|
/**
|
|
40323
40793
|
* Breakscape bitmark text.
|
|
40324
40794
|
*
|
|
@@ -40426,6 +40896,16 @@ var BitmarkParserGenerator = class {
|
|
|
40426
40896
|
}
|
|
40427
40897
|
return;
|
|
40428
40898
|
}
|
|
40899
|
+
textAstToPlainText(textAst, _options) {
|
|
40900
|
+
const textGenerator = new TextGenerator(BitmarkVersion.v3, {
|
|
40901
|
+
//
|
|
40902
|
+
});
|
|
40903
|
+
const res = textGenerator.generateSync(textAst, TextFormat.bitmarkText, TextLocation.body, {
|
|
40904
|
+
noBreakscaping: true,
|
|
40905
|
+
noMarkup: true
|
|
40906
|
+
});
|
|
40907
|
+
return res;
|
|
40908
|
+
}
|
|
40429
40909
|
/**
|
|
40430
40910
|
* Stringify / prettify a plain JS object to a JSON string, depending on the JSON options
|
|
40431
40911
|
*
|
|
@@ -40683,6 +41163,42 @@ Examples:
|
|
|
40683
41163
|
);
|
|
40684
41164
|
return cmd;
|
|
40685
41165
|
}
|
|
41166
|
+
var INPUT_FORMAT_CHOICES = enumChoices(InputFormat);
|
|
41167
|
+
function createExtractPlainTextCommand() {
|
|
41168
|
+
const bpg = new BitmarkParserGenerator();
|
|
41169
|
+
const cmd = new Command("extractPlainText").description("Extract plain text from bitmark, bitmark text, or JSON").argument(
|
|
41170
|
+
"[input]",
|
|
41171
|
+
"file to read, or text or json string. If not specified, input will be from <stdin>"
|
|
41172
|
+
).addOption(
|
|
41173
|
+
new Option(
|
|
41174
|
+
"-f, --inputFormat <format>",
|
|
41175
|
+
"force input format (auto-detected by default)"
|
|
41176
|
+
).choices([...INPUT_FORMAT_CHOICES])
|
|
41177
|
+
).option("-a, --append", "append to the output file (default is to overwrite)").option("-o, --output <file>", "output file. If not specified, output will be to <stdout>").action(async (input, options) => {
|
|
41178
|
+
try {
|
|
41179
|
+
const dataIn = await readInput(input);
|
|
41180
|
+
const result = bpg.extractPlainText(dataIn, {
|
|
41181
|
+
inputFormat: Enum(InputFormat).fromValue(options.inputFormat)
|
|
41182
|
+
});
|
|
41183
|
+
await writeOutput(result ?? "", options.output, options.append);
|
|
41184
|
+
} catch (error) {
|
|
41185
|
+
console.error("Error:", error instanceof Error ? error.message : String(error));
|
|
41186
|
+
process.exit(1);
|
|
41187
|
+
}
|
|
41188
|
+
}).addHelpText(
|
|
41189
|
+
"after",
|
|
41190
|
+
`
|
|
41191
|
+
Examples:
|
|
41192
|
+
$ bitmark-parser extractPlainText '[{"type":"paragraph","content":[{"text":"Hello World","type":"text"}],"attrs":{}}]'
|
|
41193
|
+
|
|
41194
|
+
$ bitmark-parser extractPlainText input.json
|
|
41195
|
+
|
|
41196
|
+
$ bitmark-parser extractPlainText input.json -o output.txt
|
|
41197
|
+
|
|
41198
|
+
$ bitmark-parser extractPlainText -f bitmark input.bitmark`
|
|
41199
|
+
);
|
|
41200
|
+
return cmd;
|
|
41201
|
+
}
|
|
40686
41202
|
var INFO_TYPE_CHOICES = (() => {
|
|
40687
41203
|
const choices = new Set(enumChoices(InfoType));
|
|
40688
41204
|
const ordered = [];
|
|
@@ -40810,6 +41326,7 @@ async function asyncInit() {
|
|
|
40810
41326
|
});
|
|
40811
41327
|
program.addCommand(createConvertCommand());
|
|
40812
41328
|
program.addCommand(createConvertTextCommand());
|
|
41329
|
+
program.addCommand(createExtractPlainTextCommand());
|
|
40813
41330
|
program.addCommand(createBreakscapeCommand());
|
|
40814
41331
|
program.addCommand(createUnbreakscapeCommand());
|
|
40815
41332
|
program.addCommand(createInfoCommand());
|