@bendyline/squisq-formats 2.2.0 → 2.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/NOTICE.md CHANGED
@@ -6,14 +6,13 @@ Third-party components remain under their respective license terms.
6
6
 
7
7
  ## Runtime dependencies
8
8
 
9
- | Package | Version | License | Repository |
10
- | ----------------- | ------- | ----------------------- | ----------------------------------- |
11
- | @bendyline/squisq | 2.1.0 | MIT | https://github.com/bendyline/squisq |
12
- | @pdf-lib/upng | 1.0.1 | MIT | https://github.com/Hopding/upng |
13
- | @xmldom/xmldom | 0.9.10 | MIT | https://github.com/xmldom/xmldom |
14
- | jszip | 3.10.1 | MIT OR GPL-3.0-or-later | https://github.com/Stuk/jszip |
15
- | pdf-lib | 1.17.1 | MIT | https://pdf-lib.js.org |
16
- | pdfjs-dist | 4.10.38 | Apache-2.0 | https://mozilla.github.io/pdf.js |
9
+ | Package | Version | License | Repository |
10
+ | -------------- | ------- | ----------------------- | -------------------------------- |
11
+ | @pdf-lib/upng | 1.0.1 | MIT | https://github.com/Hopding/upng |
12
+ | @xmldom/xmldom | 0.9.10 | MIT | https://github.com/xmldom/xmldom |
13
+ | jszip | 3.10.1 | MIT OR GPL-3.0-or-later | https://github.com/Stuk/jszip |
14
+ | pdf-lib | 1.17.1 | MIT | https://pdf-lib.js.org |
15
+ | pdfjs-dist | 4.10.38 | Apache-2.0 | https://mozilla.github.io/pdf.js |
17
16
 
18
17
  Squisq uses jszip under its MIT license option. Copyright and complete license
19
18
  texts for these dependencies are included in their respective npm
package/README.md CHANGED
@@ -299,7 +299,7 @@ Also exported: `createRegistry` / `defaultRegistry` / `defaultFormats`, `BUILTIN
299
299
 
300
300
  The package root re-exports the common converters; `./container`, the plain-HTML/bundle functions, `docxToContainer`, `pdfToContainer`, `PdfPageSize`, and the image utilities are subpath-only.
301
301
 
302
- See the full [API Reference](../../docs/API.md#bendylinesquisq-formats) for every signature and options interface.
302
+ See the full [API Reference](https://github.com/bendyline/squisq/blob/main/docs/API.md#bendylinesquisq-formats) for every signature and options interface.
303
303
 
304
304
  ## Related Packages
305
305
 
@@ -0,0 +1,8 @@
1
+ THIRD-PARTY LICENSES FOR @bendyline/squisq-formats
2
+
3
+ Generated from the actual esbuild input graph. Package-local license, copying,
4
+ and notice files are reproduced verbatim. When an npm tarball omits its
5
+ repository license, the pinned upstream copy is vendored and identified below.
6
+
7
+ COMPONENTS
8
+
@@ -1046,7 +1046,20 @@ function hexToRgb(hex) {
1046
1046
  // src/pdf/import.ts
1047
1047
  import { markdownToDoc } from "@bendyline/squisq/doc";
1048
1048
  import { stringifyMarkdown } from "@bendyline/squisq/markdown";
1049
+
1050
+ // src/pdf/upng.ts
1049
1051
  import UPNG from "@pdf-lib/upng";
1052
+ function isUpngEncoder(value) {
1053
+ return typeof value === "object" && value !== null && "encode" in value && typeof value.encode === "function";
1054
+ }
1055
+ function resolveUpngEncoder(value) {
1056
+ if (isUpngEncoder(value)) return value;
1057
+ if (typeof value !== "object" || value === null || !("default" in value)) return null;
1058
+ return isUpngEncoder(value.default) ? value.default : null;
1059
+ }
1060
+ var upngEncoder = resolveUpngEncoder(UPNG);
1061
+
1062
+ // src/pdf/import.ts
1050
1063
  async function pdfToMarkdownDoc(data, options = {}) {
1051
1064
  options.signal?.throwIfAborted();
1052
1065
  const bytes = data instanceof Blob ? new Uint8Array(await data.arrayBuffer()) : data instanceof ArrayBuffer ? new Uint8Array(data) : data;
@@ -1206,7 +1219,8 @@ function imageDataToPng(img) {
1206
1219
  }
1207
1220
  const owned = new Uint8Array(rgba.byteLength);
1208
1221
  owned.set(rgba);
1209
- return UPNG.encode([owned.buffer], img.width, img.height, 0);
1222
+ if (!upngEncoder) return null;
1223
+ return upngEncoder.encode([owned.buffer], img.width, img.height, 0);
1210
1224
  } catch {
1211
1225
  return null;
1212
1226
  }
@@ -1255,6 +1269,22 @@ function insertImageBlocks(blocks, blockPages, images) {
1255
1269
  }
1256
1270
  return result;
1257
1271
  }
1272
+ function hasInterItemSpace(previous, current) {
1273
+ if (!previous) return false;
1274
+ if (/\s$/.test(previous.str) || /^\s/.test(current.str)) return false;
1275
+ const gap = current.x - (previous.x + previous.width);
1276
+ const referenceHeight = Math.min(previous.height, current.height);
1277
+ return gap > Math.max(0.5, referenceHeight * 0.08);
1278
+ }
1279
+ function joinTextItems(items) {
1280
+ let text = "";
1281
+ for (let index = 0; index < items.length; index++) {
1282
+ const item = items[index];
1283
+ if (hasInterItemSpace(items[index - 1], item)) text += " ";
1284
+ text += item.str;
1285
+ }
1286
+ return text;
1287
+ }
1258
1288
  function configurePdfWorker(workerSrc) {
1259
1289
  _workerSrc = workerSrc;
1260
1290
  }
@@ -1337,7 +1367,7 @@ async function extractTextLines(pdf, options) {
1337
1367
  const fontNames = lineItems.map((i) => i.fontName);
1338
1368
  const fontName = modeStr(fontNames) || "";
1339
1369
  const minX = Math.min(...lineItems.map((i) => i.x));
1340
- const text = lineItems.map((i) => i.str).join(" ");
1370
+ const text = joinTextItems(lineItems);
1341
1371
  allLines.push({
1342
1372
  items: lineItems,
1343
1373
  y: key,
@@ -1538,9 +1568,13 @@ function isItalicFont(fontName) {
1538
1568
  function buildInlineNodes(line, options) {
1539
1569
  const nodes = [];
1540
1570
  const detectLinksOpt = options.detectLinks !== false;
1541
- for (const item of line.items) {
1571
+ for (let itemIndex = 0; itemIndex < line.items.length; itemIndex++) {
1572
+ const item = line.items[itemIndex];
1542
1573
  const text = item.str;
1543
1574
  if (!text || text.trim().length === 0) continue;
1575
+ if (hasInterItemSpace(line.items[itemIndex - 1], item)) {
1576
+ nodes.push({ type: "text", value: " " });
1577
+ }
1544
1578
  const bold = isBoldFont(item.fontName);
1545
1579
  const italic = isItalicFont(item.fontName);
1546
1580
  const mono = isMonospaceItem(item);
@@ -167,10 +167,11 @@ ${mode === "static" ? "#squisq-root{display:block}" : ""}
167
167
  </head>
168
168
  <body>
169
169
  <div id="squisq-root"></div>
170
+ <script type="application/json" id="squisq-doc" data-squisq-doc="1">${docJson}</script>
170
171
  <script>${escapeForScript(playerScript)}</script>
171
172
  <script>
172
173
  (function(){
173
- var doc = JSON.parse(${JSON.stringify(docJson)});
174
+ var doc = JSON.parse(document.getElementById("squisq-doc").textContent);
174
175
  var images = JSON.parse(${JSON.stringify(imageMapJson)});
175
176
  // Re-expand path/basename aliases that share a payload (see
176
177
  // buildInlineImageMaps) so \`images\` has every key the resolver may ask for.
@@ -221,10 +222,11 @@ ${mode === "static" ? "#squisq-root{display:block}" : ""}
221
222
  </head>
222
223
  <body>
223
224
  <div id="squisq-root"></div>
225
+ <script type="application/json" id="squisq-doc" data-squisq-doc="1">${docJson}</script>
224
226
  <script src="${escapeHtml(playerScriptPath)}"></script>
225
227
  <script>
226
228
  (function(){
227
- var doc = JSON.parse(${JSON.stringify(docJson)});
229
+ var doc = JSON.parse(document.getElementById("squisq-doc").textContent);
228
230
  var images = JSON.parse(${JSON.stringify(imageMapJson)});
229
231
  var audio = ${audioMapJson};
230
232
  SquisqPlayer.mount(document.getElementById("squisq-root"), doc, {
@@ -1223,6 +1225,7 @@ import {
1223
1225
  sanitizeHtmlNodes as sanitizeHtmlNodes2,
1224
1226
  stringifyMarkdown
1225
1227
  } from "@bendyline/squisq/markdown";
1228
+ import { docToMarkdown } from "@bendyline/squisq/doc";
1226
1229
  var HEADINGS = {
1227
1230
  h1: 1,
1228
1231
  h2: 2,
@@ -1409,6 +1412,33 @@ function toHtmlString(data) {
1409
1412
  const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
1410
1413
  return new TextDecoder("utf-8").decode(bytes);
1411
1414
  }
1415
+ function findEmbeddedSquisqDoc(nodes) {
1416
+ for (const node of nodes) {
1417
+ if (!isElement(node)) continue;
1418
+ if (node.tagName.toLowerCase() === "script" && "data-squisq-doc" in node.attributes) {
1419
+ return node;
1420
+ }
1421
+ const nested = findEmbeddedSquisqDoc(node.children);
1422
+ if (nested) return nested;
1423
+ }
1424
+ return void 0;
1425
+ }
1426
+ function parseEmbeddedSquisqDoc(script) {
1427
+ const version = script.attributes["data-squisq-doc"];
1428
+ if (version !== "1") {
1429
+ throw new Error(`Unsupported embedded Squisq Doc version "${version || "(missing)"}"`);
1430
+ }
1431
+ let value;
1432
+ try {
1433
+ value = JSON.parse(textContent(script));
1434
+ } catch {
1435
+ throw new SyntaxError("Invalid embedded Squisq Doc JSON");
1436
+ }
1437
+ if (value === null || typeof value !== "object" || typeof value.articleId !== "string" || !Number.isFinite(value.duration) || !Array.isArray(value.blocks) || value.audio === null || typeof value.audio !== "object") {
1438
+ throw new TypeError("Embedded Squisq Doc has an invalid shape");
1439
+ }
1440
+ return value;
1441
+ }
1412
1442
  function htmlToMarkdownDocSync(html, options = {}) {
1413
1443
  options.signal?.throwIfAborted();
1414
1444
  const maxInputChars = options.maxInputChars ?? 16 * 1024 * 1024;
@@ -1419,6 +1449,8 @@ function htmlToMarkdownDocSync(html, options = {}) {
1419
1449
  throw new RangeError(`HTML exceeds the ${maxInputChars}-character safety limit`);
1420
1450
  }
1421
1451
  let nodes = parseHtmlToNodes(html);
1452
+ const embedded = findEmbeddedSquisqDoc(nodes);
1453
+ if (embedded) return docToMarkdown(parseEmbeddedSquisqDoc(embedded));
1422
1454
  if (options.sanitize !== false) nodes = sanitizeHtmlNodes2(nodes);
1423
1455
  return { type: "document", children: blocksFromNodes(nodes) };
1424
1456
  }
@@ -9,7 +9,7 @@ import {
9
9
  markdownDocToPlainHtml,
10
10
  markdownDocsToHtmlBundle,
11
11
  markdownDocsToPlainHtmlBundle
12
- } from "../chunk-JE6LSIHE.js";
12
+ } from "../chunk-T7M52LHF.js";
13
13
  import {
14
14
  arrayBufferToBase64DataUrl,
15
15
  extractFilename,
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  defaultRegistry,
12
12
  prepareConversion,
13
13
  resolveConversionLimits
14
- } from "./chunk-3NKXBZSR.js";
14
+ } from "./chunk-LBHZSY7N.js";
15
15
  import {
16
16
  inferThemeFromFile
17
17
  } from "./chunk-6S6GU3ZG.js";
@@ -62,7 +62,7 @@ import {
62
62
  markdownDocToPdf,
63
63
  pdfToDoc,
64
64
  pdfToMarkdownDoc
65
- } from "./chunk-PJXJI2LY.js";
65
+ } from "./chunk-GYIVES2E.js";
66
66
  import "./chunk-IIQYS2YH.js";
67
67
  import {
68
68
  collectImagePaths,
@@ -71,7 +71,7 @@ import {
71
71
  htmlToMarkdown,
72
72
  htmlToMarkdownDoc,
73
73
  htmlToMarkdownDocSync
74
- } from "./chunk-JE6LSIHE.js";
74
+ } from "./chunk-T7M52LHF.js";
75
75
  import "./chunk-6RQOV3B3.js";
76
76
  import "./chunk-AONELFLA.js";
77
77
  export {
package/dist/pdf/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  pdfToContainer,
6
6
  pdfToDoc,
7
7
  pdfToMarkdownDoc
8
- } from "../chunk-PJXJI2LY.js";
8
+ } from "../chunk-GYIVES2E.js";
9
9
  import "../chunk-IIQYS2YH.js";
10
10
  export {
11
11
  configurePdfWorker,
@@ -7,7 +7,7 @@ import {
7
7
  defaultRegistry,
8
8
  prepareConversion,
9
9
  resolveConversionLimits
10
- } from "../chunk-3NKXBZSR.js";
10
+ } from "../chunk-LBHZSY7N.js";
11
11
  import {
12
12
  ConversionError
13
13
  } from "../chunk-KXOZMWBS.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/squisq-formats",
3
- "version": "2.2.0",
3
+ "version": "2.3.1",
4
4
  "description": "Document format converters — DOCX, PDF, OOXML import/export",
5
5
  "license": "MIT",
6
6
  "author": "Bendyline",
@@ -24,6 +24,9 @@
24
24
  "access": "public"
25
25
  },
26
26
  "type": "module",
27
+ "engines": {
28
+ "node": ">=22.14.0"
29
+ },
27
30
  "main": "./dist/index.js",
28
31
  "module": "./dist/index.js",
29
32
  "types": "./dist/index.d.ts",
@@ -31,7 +34,8 @@
31
34
  "dist",
32
35
  "!dist/**/*.map",
33
36
  "LICENSE",
34
- "NOTICE.md"
37
+ "NOTICE.md",
38
+ "THIRD_PARTY_LICENSES.txt"
35
39
  ],
36
40
  "exports": {
37
41
  ".": {
@@ -96,14 +100,14 @@
96
100
  }
97
101
  },
98
102
  "scripts": {
99
- "build": "tsup",
103
+ "build": "tsup && node ../../scripts/generate-bundle-licenses.mjs . && node ../../scripts/remove-empty-chunks.mjs dist",
100
104
  "dev": "concurrently -n js,dts -c blue,gray -r \"tsup --watch --no-dts --no-clean\" \"tsup --watch --dts-only --no-clean\"",
101
105
  "typecheck": "tsc --noEmit"
102
106
  },
103
107
  "dependencies": {
104
108
  "@pdf-lib/upng": "1.0.1",
105
109
  "@xmldom/xmldom": "0.9.10",
106
- "@bendyline/squisq": "2.2.0",
110
+ "@bendyline/squisq": "2.3.1",
107
111
  "jszip": "3.10.1",
108
112
  "pdf-lib": "1.17.1",
109
113
  "pdfjs-dist": "4.10.38"
File without changes