@haklex/rich-litexml 0.39.3 → 0.39.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/dist/browser.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as createDefaultRegistry, c as LitexmlRegistry, d as registerParseHTML, i as deserializeNodesFromXml, l as registerCustomReaders, n as serializeToXml, o as registerCustomWriters, r as deserializeFromXml, s as registerBuiltinWriters, t as serializeNodesToXml, u as registerBuiltinReaders } from "./src-h5Q0X5zw.js";
1
+ import { a as createDefaultRegistry, c as LitexmlRegistry, d as registerParseHTML, i as deserializeNodesFromXml, l as registerCustomReaders, n as serializeToXml, o as registerCustomWriters, r as deserializeFromXml, s as registerBuiltinWriters, t as serializeNodesToXml, u as registerBuiltinReaders } from "./src-D18H2iDy.js";
2
2
  //#region src/index-browser.ts
3
3
  registerParseHTML((html) => new DOMParser().parseFromString(html, "text/html"));
4
4
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"deserializer.d.ts","sourceRoot":"","sources":["../src/deserializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAG5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAwElD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,qBAAqB,CAkBhG;AAED,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,eAAe,GACxB,qBAAqB,EAAE,CAKzB"}
1
+ {"version":3,"file":"deserializer.d.ts","sourceRoot":"","sources":["../src/deserializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAG5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAyElD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,qBAAqB,CAkBhG;AAED,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,eAAe,GACxB,qBAAqB,EAAE,CAKzB"}
package/dist/node.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as createDefaultRegistry, c as LitexmlRegistry, d as registerParseHTML, i as deserializeNodesFromXml, l as registerCustomReaders, n as serializeToXml, o as registerCustomWriters, r as deserializeFromXml, s as registerBuiltinWriters, t as serializeNodesToXml, u as registerBuiltinReaders } from "./src-h5Q0X5zw.js";
1
+ import { a as createDefaultRegistry, c as LitexmlRegistry, d as registerParseHTML, i as deserializeNodesFromXml, l as registerCustomReaders, n as serializeToXml, o as registerCustomWriters, r as deserializeFromXml, s as registerBuiltinWriters, t as serializeNodesToXml, u as registerBuiltinReaders } from "./src-D18H2iDy.js";
2
2
  import { parseHTML } from "linkedom";
3
3
  //#region src/index-node.ts
4
4
  registerParseHTML((html) => parseHTML(html).document);
@@ -1 +1 @@
1
- {"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../src/readers/builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgBnD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAiLtE"}
1
+ {"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../src/readers/builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgBnD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CA0LtE"}
@@ -38,14 +38,15 @@ function registerBuiltinReaders(registry) {
38
38
  }));
39
39
  registry.registerReader("blockquote", (el, ctx) => {
40
40
  const attribution = el.getAttribute("attribution");
41
+ const isRichQuote = el.getAttribute("rich") !== null || attribution !== null;
41
42
  const base = {
42
43
  ...extractBlockId$1(el),
43
44
  children: ctx.parseChildren(el),
44
45
  ...ELEMENT_DEFAULTS
45
46
  };
46
- if (attribution !== null) return {
47
+ if (isRichQuote) return {
47
48
  type: "rich-quote",
48
- attribution,
49
+ attribution: attribution?.trim() ? attribution : null,
49
50
  ...base
50
51
  };
51
52
  return {
@@ -100,7 +101,7 @@ function registerBuiltinReaders(registry) {
100
101
  url: el.getAttribute("href") ?? "",
101
102
  target: el.getAttribute("target") ?? null,
102
103
  title: el.getAttribute("title") ?? null,
103
- rel: null,
104
+ rel: el.getAttribute("rel"),
104
105
  children: ctx.parseChildren(el),
105
106
  direction: "ltr",
106
107
  format: "",
@@ -621,7 +622,10 @@ function registerBuiltinWriters(registry) {
621
622
  const writeQuote = (node, ctx) => {
622
623
  const n = node;
623
624
  const attrs = { ...blockId$1(n) };
624
- if (typeof n.attribution === "string" && n.attribution.trim() !== "") attrs.attribution = n.attribution;
625
+ if (n.type === "rich-quote") {
626
+ if ((typeof n.attribution === "string" ? n.attribution.trim() : "") !== "") attrs.attribution = n.attribution;
627
+ else attrs.rich = "true";
628
+ }
625
629
  return {
626
630
  tag: "blockquote",
627
631
  attrs,
@@ -660,9 +664,10 @@ function registerBuiltinWriters(registry) {
660
664
  });
661
665
  registry.registerWriter("link", (node, ctx) => {
662
666
  const n = node;
663
- const attrs = { href: n.url ?? "" };
664
- if (n.target) attrs.target = n.target;
665
- if (n.title) attrs.title = n.title;
667
+ const attrs = { href: typeof n.url === "string" ? n.url : "" };
668
+ if (typeof n.target === "string" && n.target !== "") attrs.target = n.target;
669
+ if (typeof n.title === "string" && n.title !== "") attrs.title = n.title;
670
+ if (typeof n.rel === "string" && n.rel !== "") attrs.rel = n.rel;
666
671
  return {
667
672
  tag: "a",
668
673
  attrs,
@@ -1149,6 +1154,114 @@ function getFormatBit(tagName) {
1149
1154
  return FORMAT_TAG_TO_BIT[tagName.toLowerCase()] ?? 0;
1150
1155
  }
1151
1156
  //#endregion
1157
+ //#region src/xml-utils.ts
1158
+ var ESCAPE_MAP = {
1159
+ "&": "&",
1160
+ "<": "&lt;",
1161
+ ">": "&gt;",
1162
+ "\"": "&quot;",
1163
+ "'": "&apos;"
1164
+ };
1165
+ function escapeXml(text) {
1166
+ return text.replaceAll(/["&'<>]/g, (ch) => ESCAPE_MAP[ch]);
1167
+ }
1168
+ function buildAttrs(attrs) {
1169
+ return Object.entries(attrs).filter(([, v]) => v !== void 0 && v !== "").map(([k, v]) => ` ${k}="${escapeXml(v)}"`).join("");
1170
+ }
1171
+ function isCdata(item) {
1172
+ return typeof item === "object" && "cdata" in item;
1173
+ }
1174
+ function renderCdata(item) {
1175
+ return `<![CDATA[${item.cdata}]]>`;
1176
+ }
1177
+ /** Render XmlContent tree to XML string. */
1178
+ function renderXml(content, indent = 0, options = {}) {
1179
+ const lines = [];
1180
+ for (const item of content) if (typeof item === "string") lines.push(escapeXml(item));
1181
+ else if (isCdata(item)) lines.push(renderCdata(item));
1182
+ else lines.push(renderElement(item, indent, options));
1183
+ return lines.join("");
1184
+ }
1185
+ function renderElement(el, indent, options) {
1186
+ const attrs = el.attrs ? buildAttrs(el.attrs) : "";
1187
+ const compact = options.compact === true;
1188
+ if (el.selfClosing) return compact ? `<${el.tag}${attrs} />` : `${pad(indent)}<${el.tag}${attrs} />\n`;
1189
+ if (!el.children || el.children.length === 0) return compact ? `<${el.tag}${attrs} />` : `${pad(indent)}<${el.tag}${attrs} />\n`;
1190
+ if (el.children.every((c) => typeof c === "string" || isCdata(c) || isInlineElement(c))) {
1191
+ const inner = el.children.map((c) => {
1192
+ if (typeof c === "string") return escapeXml(c);
1193
+ if (isCdata(c)) return renderCdata(c);
1194
+ return renderInline(c);
1195
+ }).join("");
1196
+ return compact ? `<${el.tag}${attrs}>${inner}</${el.tag}>` : `${pad(indent)}<${el.tag}${attrs}>${inner}</${el.tag}>\n`;
1197
+ }
1198
+ if (compact) {
1199
+ const inner = el.children.map((c) => {
1200
+ if (typeof c === "string") return escapeXml(c);
1201
+ if (isCdata(c)) return renderCdata(c);
1202
+ return renderElement(c, indent + 1, options);
1203
+ }).join("");
1204
+ return `<${el.tag}${attrs}>${inner}</${el.tag}>`;
1205
+ }
1206
+ const inner = el.children.map((c) => {
1207
+ if (typeof c === "string") return `${pad(indent + 1)}${escapeXml(c)}\n`;
1208
+ if (isCdata(c)) return `${pad(indent + 1)}${renderCdata(c)}\n`;
1209
+ return renderElement(c, indent + 1, options);
1210
+ }).join("");
1211
+ return `${pad(indent)}<${el.tag}${attrs}>\n${inner}${pad(indent)}</${el.tag}>\n`;
1212
+ }
1213
+ function renderInline(el) {
1214
+ const attrs = el.attrs ? buildAttrs(el.attrs) : "";
1215
+ if (el.selfClosing || !el.children || el.children.length === 0) return `<${el.tag}${attrs} />`;
1216
+ const inner = el.children.map((c) => {
1217
+ if (typeof c === "string") return escapeXml(c);
1218
+ if (isCdata(c)) return renderCdata(c);
1219
+ return renderInline(c);
1220
+ }).join("");
1221
+ return `<${el.tag}${attrs}>${inner}</${el.tag}>`;
1222
+ }
1223
+ /**
1224
+ * Elements that sit inside a text run without forcing a line break, so the
1225
+ * serializer keeps them on the same line as their siblings and the reader does
1226
+ * not mistake the surrounding indentation for content.
1227
+ *
1228
+ * The void elements (`br`, `img`) belong here: a paragraph holding a line break
1229
+ * or an inline image is still a single line of prose.
1230
+ */
1231
+ var INLINE_TAGS = /* @__PURE__ */ new Set([
1232
+ "b",
1233
+ "i",
1234
+ "u",
1235
+ "s",
1236
+ "code",
1237
+ "sub",
1238
+ "sup",
1239
+ "mark",
1240
+ "strong",
1241
+ "em",
1242
+ "del",
1243
+ "a",
1244
+ "mention",
1245
+ "tag",
1246
+ "spoiler",
1247
+ "ruby",
1248
+ "math",
1249
+ "footnote",
1250
+ "comment",
1251
+ "br",
1252
+ "img"
1253
+ ]);
1254
+ /** Tags rendered inline (no line break between siblings). */
1255
+ function isInlineTag(tag) {
1256
+ return INLINE_TAGS.has(tag.toLowerCase());
1257
+ }
1258
+ function isInlineElement(el) {
1259
+ return isInlineTag(el.tag);
1260
+ }
1261
+ function pad(indent) {
1262
+ return " ".repeat(indent);
1263
+ }
1264
+ //#endregion
1152
1265
  //#region src/deserializer.ts
1153
1266
  /**
1154
1267
  * HTML5 void elements — tags the HTML parser already treats as self-closing
@@ -1256,7 +1369,8 @@ function isBlockContainer(element) {
1256
1369
  function createReaderContext(registry) {
1257
1370
  const ctx = {
1258
1371
  parseChildren(element) {
1259
- const blockLevel = isBlockContainer(element);
1372
+ const holdsBlockChild = [...element.children].some((child) => !isInlineTag(child.tagName));
1373
+ const blockLevel = isBlockContainer(element) || holdsBlockChild;
1260
1374
  const nodes = [];
1261
1375
  let pendingText = "";
1262
1376
  const flushText = () => {
@@ -1345,99 +1459,6 @@ function makeTextNode(text, format) {
1345
1459
  };
1346
1460
  }
1347
1461
  //#endregion
1348
- //#region src/xml-utils.ts
1349
- var ESCAPE_MAP = {
1350
- "&": "&amp;",
1351
- "<": "&lt;",
1352
- ">": "&gt;",
1353
- "\"": "&quot;",
1354
- "'": "&apos;"
1355
- };
1356
- function escapeXml(text) {
1357
- return text.replaceAll(/["&'<>]/g, (ch) => ESCAPE_MAP[ch]);
1358
- }
1359
- function buildAttrs(attrs) {
1360
- return Object.entries(attrs).filter(([, v]) => v !== void 0 && v !== "").map(([k, v]) => ` ${k}="${escapeXml(v)}"`).join("");
1361
- }
1362
- function isCdata(item) {
1363
- return typeof item === "object" && "cdata" in item;
1364
- }
1365
- function renderCdata(item) {
1366
- return `<![CDATA[${item.cdata}]]>`;
1367
- }
1368
- /** Render XmlContent tree to XML string. */
1369
- function renderXml(content, indent = 0, options = {}) {
1370
- const lines = [];
1371
- for (const item of content) if (typeof item === "string") lines.push(escapeXml(item));
1372
- else if (isCdata(item)) lines.push(renderCdata(item));
1373
- else lines.push(renderElement(item, indent, options));
1374
- return lines.join("");
1375
- }
1376
- function renderElement(el, indent, options) {
1377
- const attrs = el.attrs ? buildAttrs(el.attrs) : "";
1378
- const compact = options.compact === true;
1379
- if (el.selfClosing) return compact ? `<${el.tag}${attrs} />` : `${pad(indent)}<${el.tag}${attrs} />\n`;
1380
- if (!el.children || el.children.length === 0) return compact ? `<${el.tag}${attrs} />` : `${pad(indent)}<${el.tag}${attrs} />\n`;
1381
- if (el.children.every((c) => typeof c === "string" || isCdata(c) || isInlineElement(c))) {
1382
- const inner = el.children.map((c) => {
1383
- if (typeof c === "string") return escapeXml(c);
1384
- if (isCdata(c)) return renderCdata(c);
1385
- return renderInline(c);
1386
- }).join("");
1387
- return compact ? `<${el.tag}${attrs}>${inner}</${el.tag}>` : `${pad(indent)}<${el.tag}${attrs}>${inner}</${el.tag}>\n`;
1388
- }
1389
- if (compact) {
1390
- const inner = el.children.map((c) => {
1391
- if (typeof c === "string") return escapeXml(c);
1392
- if (isCdata(c)) return renderCdata(c);
1393
- return renderElement(c, indent + 1, options);
1394
- }).join("");
1395
- return `<${el.tag}${attrs}>${inner}</${el.tag}>`;
1396
- }
1397
- const inner = el.children.map((c) => {
1398
- if (typeof c === "string") return `${pad(indent + 1)}${escapeXml(c)}\n`;
1399
- if (isCdata(c)) return `${pad(indent + 1)}${renderCdata(c)}\n`;
1400
- return renderElement(c, indent + 1, options);
1401
- }).join("");
1402
- return `${pad(indent)}<${el.tag}${attrs}>\n${inner}${pad(indent)}</${el.tag}>\n`;
1403
- }
1404
- function renderInline(el) {
1405
- const attrs = el.attrs ? buildAttrs(el.attrs) : "";
1406
- if (el.selfClosing || !el.children || el.children.length === 0) return `<${el.tag}${attrs} />`;
1407
- const inner = el.children.map((c) => {
1408
- if (typeof c === "string") return escapeXml(c);
1409
- if (isCdata(c)) return renderCdata(c);
1410
- return renderInline(c);
1411
- }).join("");
1412
- return `<${el.tag}${attrs}>${inner}</${el.tag}>`;
1413
- }
1414
- function isInlineElement(el) {
1415
- return (/* @__PURE__ */ new Set([
1416
- "b",
1417
- "i",
1418
- "u",
1419
- "s",
1420
- "code",
1421
- "sub",
1422
- "sup",
1423
- "mark",
1424
- "strong",
1425
- "em",
1426
- "del",
1427
- "a",
1428
- "mention",
1429
- "tag",
1430
- "spoiler",
1431
- "ruby",
1432
- "math",
1433
- "footnote",
1434
- "comment"
1435
- ])).has(el.tag);
1436
- }
1437
- function pad(indent) {
1438
- return " ".repeat(indent);
1439
- }
1440
- //#endregion
1441
1462
  //#region src/serializer.ts
1442
1463
  function serializeToXml(state, registry, options = {}) {
1443
1464
  const children = state.root.children ?? [];
@@ -1 +1 @@
1
- {"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../src/writers/builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAOnD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAwHtE"}
1
+ {"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../src/writers/builtin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAOnD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAoJtE"}
@@ -6,4 +6,6 @@ export declare function escapeXml(text: string): string;
6
6
  export declare function buildAttrs(attrs: Record<string, string>): string;
7
7
  /** Render XmlContent tree to XML string. */
8
8
  export declare function renderXml(content: XmlContent[], indent?: number, options?: XmlRenderOptions): string;
9
+ /** Tags rendered inline (no line break between siblings). */
10
+ export declare function isInlineTag(tag: string): boolean;
9
11
  //# sourceMappingURL=xml-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"xml-utils.d.ts","sourceRoot":"","sources":["../src/xml-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,UAAU,EAAc,MAAM,SAAS,CAAC;AAEhE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAUD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAKhE;AAUD,4CAA4C;AAC5C,wBAAgB,SAAS,CACvB,OAAO,EAAE,UAAU,EAAE,EACrB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,gBAAqB,GAC7B,MAAM,CAYR"}
1
+ {"version":3,"file":"xml-utils.d.ts","sourceRoot":"","sources":["../src/xml-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,UAAU,EAAc,MAAM,SAAS,CAAC;AAEhE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAUD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAKhE;AAUD,4CAA4C;AAC5C,wBAAgB,SAAS,CACvB,OAAO,EAAE,UAAU,EAAE,EACrB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,gBAAqB,GAC7B,MAAM,CAYR;AAqGD,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haklex/rich-litexml",
3
- "version": "0.39.3",
3
+ "version": "0.39.5",
4
4
  "description": "Bidirectional Lexical SerializedNode <-> XML conversion with plugin registry",
5
5
  "repository": {
6
6
  "type": "git",