@bendyline/squisq-formats 2.4.6 → 2.5.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/{chunk-KN62QJYK.js → chunk-2LT3JL7U.js} +75 -24
- package/dist/{chunk-BVGJ54NV.js → chunk-5PUIFU5I.js} +1 -1
- package/dist/chunk-A6LSCIO5.js +1197 -0
- package/dist/{chunk-DWNNYO5H.js → chunk-A6N6IN3I.js} +5 -1
- package/dist/{chunk-6X5XN3CZ.js → chunk-AVOZAKGP.js} +3 -0
- package/dist/chunk-BXWNU4T5.js +108 -0
- package/dist/{chunk-BGDN7BXK.js → chunk-FIOSE4BO.js} +78 -6
- package/dist/{chunk-XCV242AO.js → chunk-FMQWNPCV.js} +5 -2
- package/dist/{chunk-DNGNODJP.js → chunk-JTGWQK5V.js} +12 -2
- package/dist/{chunk-KT5DX2QP.js → chunk-M7XPXGXW.js} +32 -9
- package/dist/{chunk-N2ZN3MQN.js → chunk-T4PX33AG.js} +262 -14
- package/dist/docx/index.js +4 -3
- package/dist/epub/index.js +3 -2
- package/dist/export-m0tr9r9d.d.ts +130 -0
- package/dist/html/index.js +2 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +11 -10
- package/dist/outside-in/index.d.ts +2 -2
- package/dist/outside-in/index.js +2 -2
- package/dist/pdf/index.js +2 -1
- package/dist/pptx/index.js +3 -3
- package/dist/registry/index.d.ts +3 -3
- package/dist/registry/index.js +1 -1
- package/dist/{types-HDLauUoa.d.ts → types-DByrrXeB.d.ts} +1 -1
- package/dist/xlsx/index.d.ts +2 -2
- package/dist/xlsx/index.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-UIBTXX4L.js +0 -446
- package/dist/export-D9msROJS.d.ts +0 -81
|
@@ -3,6 +3,10 @@ import {
|
|
|
3
3
|
extractFilename,
|
|
4
4
|
inferMimeType
|
|
5
5
|
} from "./chunk-6RQOV3B3.js";
|
|
6
|
+
import {
|
|
7
|
+
FootnoteIndex,
|
|
8
|
+
footnoteIds
|
|
9
|
+
} from "./chunk-BXWNU4T5.js";
|
|
6
10
|
|
|
7
11
|
// src/html/index.ts
|
|
8
12
|
import JSZip3 from "jszip";
|
|
@@ -290,8 +294,9 @@ function markdownDocToPlainHtml(doc, options = {}) {
|
|
|
290
294
|
} = options;
|
|
291
295
|
const resolveId = themeId ?? readFrontmatterThemeId2(doc.frontmatter);
|
|
292
296
|
const theme = options.theme ?? (resolveId ? resolveThemeForDoc(doc, resolveId, options.themeRegistry) : void 0);
|
|
293
|
-
const
|
|
294
|
-
const
|
|
297
|
+
const footnotes = new FootnoteIndex(doc);
|
|
298
|
+
const ctx = { images, links, htmlPolicy, footnotes };
|
|
299
|
+
const body = renderTopLevel(doc.children, ctx) + renderFootnotesSection(footnotes, ctx);
|
|
295
300
|
const fontsLink = theme && externalResources === "allow" ? renderFontsLink(theme) : "";
|
|
296
301
|
const usesIcons = docUsesIcons(doc);
|
|
297
302
|
let iconsLink = "";
|
|
@@ -355,6 +360,28 @@ function renderTopLevel(children, ctx) {
|
|
|
355
360
|
}
|
|
356
361
|
return out.join("\n");
|
|
357
362
|
}
|
|
363
|
+
function renderFootnotesSection(footnotes, ctx) {
|
|
364
|
+
if (footnotes.isEmpty) return "";
|
|
365
|
+
const items = footnotes.ordered().map((fn) => {
|
|
366
|
+
const { def } = footnoteIds(fn.identifier);
|
|
367
|
+
const body = fn.definition ? childrenToHtml(fn.definition, ctx) : "";
|
|
368
|
+
const backlinks = Array.from({ length: Math.max(fn.citations, 1) }, (_unused, i) => {
|
|
369
|
+
const { ref } = footnoteIds(fn.identifier, i + 1);
|
|
370
|
+
const label = fn.citations > 1 ? `\u21A9${String.fromCharCode(65038)}${i + 1}` : "\u21A9";
|
|
371
|
+
return `<a href="#${escapeAttr(ref)}" class="squisq-footnote-backref" aria-label="Back to reference ${fn.number}">${label}</a>`;
|
|
372
|
+
}).join(" ");
|
|
373
|
+
return `<li id="${escapeAttr(def)}">${body}${backlinks}</li>`;
|
|
374
|
+
});
|
|
375
|
+
const lines = [
|
|
376
|
+
"",
|
|
377
|
+
'<section class="squisq-footnotes" data-footnotes><hr>',
|
|
378
|
+
"<ol>",
|
|
379
|
+
...items,
|
|
380
|
+
"</ol>",
|
|
381
|
+
"</section>"
|
|
382
|
+
];
|
|
383
|
+
return lines.join("\n");
|
|
384
|
+
}
|
|
358
385
|
function findSectionEnd(nodes, from) {
|
|
359
386
|
for (let i = from + 1; i < nodes.length; i++) {
|
|
360
387
|
const n = nodes[i];
|
|
@@ -645,6 +672,20 @@ function nodeToHtml(node, ctx) {
|
|
|
645
672
|
return `<em>${childrenToHtml(node, ctx)}</em>`;
|
|
646
673
|
case "delete":
|
|
647
674
|
return `<del>${childrenToHtml(node, ctx)}</del>`;
|
|
675
|
+
case "superscript":
|
|
676
|
+
return `<sup>${childrenToHtml(node, ctx)}</sup>`;
|
|
677
|
+
case "footnoteReference": {
|
|
678
|
+
if (!ctx?.footnotes) {
|
|
679
|
+
return `<sup class="squisq-footnote-ref">${escapeHtml2(node.label ?? node.identifier)}</sup>`;
|
|
680
|
+
}
|
|
681
|
+
const { number, occurrence } = ctx.footnotes.cite(node.identifier);
|
|
682
|
+
const { ref, def } = footnoteIds(node.identifier, occurrence);
|
|
683
|
+
return `<sup class="squisq-footnote-ref"><a href="#${escapeAttr(def)}" id="${escapeAttr(ref)}">${number}</a></sup>`;
|
|
684
|
+
}
|
|
685
|
+
case "footnoteDefinition":
|
|
686
|
+
return "";
|
|
687
|
+
case "subscript":
|
|
688
|
+
return `<sub>${childrenToHtml(node, ctx)}</sub>`;
|
|
648
689
|
case "inlineCode":
|
|
649
690
|
return `<code>${escapeHtml2(node.value ?? "")}</code>`;
|
|
650
691
|
case "code": {
|
|
@@ -1238,6 +1279,199 @@ import {
|
|
|
1238
1279
|
stringifyMarkdown
|
|
1239
1280
|
} from "@bendyline/squisq/markdown";
|
|
1240
1281
|
import { docToMarkdown } from "@bendyline/squisq/doc";
|
|
1282
|
+
|
|
1283
|
+
// src/html/footnoteImport.ts
|
|
1284
|
+
var TRAILING_WHITESPACE = /[ \t\r\n]+$/;
|
|
1285
|
+
var WHITESPACE = /[ \t\r\n]+/;
|
|
1286
|
+
var VARIATION_SELECTORS = /[\ufe0e\ufe0f]/gu;
|
|
1287
|
+
var RETURN_ARROW = /^[ \t\r\n\u2191\u21a9\u21b5^]+$/u;
|
|
1288
|
+
var MARKER_LABEL = /^[ \t[(]*(?:[0-9]{1,4}|[a-z]|[*†‡])[ \t\])]*$/i;
|
|
1289
|
+
function isElement(node) {
|
|
1290
|
+
return node.type === "htmlElement";
|
|
1291
|
+
}
|
|
1292
|
+
function attr(el, name) {
|
|
1293
|
+
return el.attributes[name];
|
|
1294
|
+
}
|
|
1295
|
+
function classList(el) {
|
|
1296
|
+
return (attr(el, "class") ?? "").split(WHITESPACE).filter(Boolean);
|
|
1297
|
+
}
|
|
1298
|
+
function isFootnotesContainer(el) {
|
|
1299
|
+
if (attr(el, "data-footnotes") !== void 0) return true;
|
|
1300
|
+
if (attr(el, "epub:type")?.includes("footnotes")) return true;
|
|
1301
|
+
const tag = el.tagName.toLowerCase();
|
|
1302
|
+
if (tag !== "section" && tag !== "aside" && tag !== "div" && tag !== "ol") return false;
|
|
1303
|
+
return classList(el).some(
|
|
1304
|
+
(c) => c === "footnotes" || c === "footnote-list" || c === "squisq-footnotes"
|
|
1305
|
+
);
|
|
1306
|
+
}
|
|
1307
|
+
function textOf(node) {
|
|
1308
|
+
if (node.type === "htmlText") return node.value;
|
|
1309
|
+
if (!isElement(node)) return "";
|
|
1310
|
+
return node.children.map(textOf).join("");
|
|
1311
|
+
}
|
|
1312
|
+
function isBacklink(el) {
|
|
1313
|
+
if (el.tagName.toLowerCase() !== "a") return false;
|
|
1314
|
+
if (attr(el, "data-footnote-backref") !== void 0) return true;
|
|
1315
|
+
if (classList(el).some((c) => c.includes("backref") || c === "footnote-back")) return true;
|
|
1316
|
+
return RETURN_ARROW.test(textOf(el).replace(VARIATION_SELECTORS, ""));
|
|
1317
|
+
}
|
|
1318
|
+
function findElement(nodes, match) {
|
|
1319
|
+
for (const node of nodes) {
|
|
1320
|
+
if (!isElement(node)) continue;
|
|
1321
|
+
if (match(node)) return node;
|
|
1322
|
+
const nested = findElement(node.children, match);
|
|
1323
|
+
if (nested) return nested;
|
|
1324
|
+
}
|
|
1325
|
+
return null;
|
|
1326
|
+
}
|
|
1327
|
+
function stripBacklinks(nodes) {
|
|
1328
|
+
const out = [];
|
|
1329
|
+
for (const node of nodes) {
|
|
1330
|
+
if (isElement(node)) {
|
|
1331
|
+
if (isBacklink(node)) continue;
|
|
1332
|
+
out.push({ ...node, children: stripBacklinks(node.children) });
|
|
1333
|
+
continue;
|
|
1334
|
+
}
|
|
1335
|
+
out.push(node);
|
|
1336
|
+
}
|
|
1337
|
+
return out;
|
|
1338
|
+
}
|
|
1339
|
+
function removeElement(nodes, target) {
|
|
1340
|
+
const out = [];
|
|
1341
|
+
for (const node of nodes) {
|
|
1342
|
+
if (node === target) continue;
|
|
1343
|
+
if (isElement(node)) {
|
|
1344
|
+
out.push({ ...node, children: removeElement(node.children, target) });
|
|
1345
|
+
continue;
|
|
1346
|
+
}
|
|
1347
|
+
out.push(node);
|
|
1348
|
+
}
|
|
1349
|
+
return out;
|
|
1350
|
+
}
|
|
1351
|
+
function trimTrailingText(nodes) {
|
|
1352
|
+
const out = [...nodes];
|
|
1353
|
+
for (let i = out.length - 1; i >= 0; i--) {
|
|
1354
|
+
const node = out[i];
|
|
1355
|
+
if (node.type === "htmlText") {
|
|
1356
|
+
const trimmed = node.value.replace(TRAILING_WHITESPACE, "");
|
|
1357
|
+
if (trimmed === "") {
|
|
1358
|
+
out.pop();
|
|
1359
|
+
continue;
|
|
1360
|
+
}
|
|
1361
|
+
out[i] = { ...node, value: trimmed };
|
|
1362
|
+
break;
|
|
1363
|
+
}
|
|
1364
|
+
if (isElement(node)) {
|
|
1365
|
+
out[i] = { ...node, children: trimTrailingText(node.children) };
|
|
1366
|
+
}
|
|
1367
|
+
break;
|
|
1368
|
+
}
|
|
1369
|
+
return out;
|
|
1370
|
+
}
|
|
1371
|
+
function collectDefinitionItems(container) {
|
|
1372
|
+
const items = /* @__PURE__ */ new Map();
|
|
1373
|
+
const walk = (nodes) => {
|
|
1374
|
+
for (const node of nodes) {
|
|
1375
|
+
if (!isElement(node)) continue;
|
|
1376
|
+
const id = attr(node, "id");
|
|
1377
|
+
if (node.tagName.toLowerCase() === "li" && id) {
|
|
1378
|
+
items.set(id, trimTrailingText(stripBacklinks(node.children)));
|
|
1379
|
+
continue;
|
|
1380
|
+
}
|
|
1381
|
+
walk(node.children);
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1384
|
+
walk(container.children);
|
|
1385
|
+
return items;
|
|
1386
|
+
}
|
|
1387
|
+
function readableIdentifier(rawId, taken) {
|
|
1388
|
+
const short = rawId.replace(/^user-content-/, "").replace(/^fn[-_:]?/i, "").replace(/^footnote[-_:]?/i, "");
|
|
1389
|
+
if (short === "" || taken.has(short)) return rawId;
|
|
1390
|
+
return short;
|
|
1391
|
+
}
|
|
1392
|
+
function extractFootnoteSection(nodes) {
|
|
1393
|
+
const container = findElement(nodes, isFootnotesContainer);
|
|
1394
|
+
if (!container) return { nodes, bodies: /* @__PURE__ */ new Map() };
|
|
1395
|
+
const raw = collectDefinitionItems(container);
|
|
1396
|
+
if (raw.size === 0) return { nodes, bodies: /* @__PURE__ */ new Map() };
|
|
1397
|
+
const bodies = /* @__PURE__ */ new Map();
|
|
1398
|
+
const identifiers = /* @__PURE__ */ new Map();
|
|
1399
|
+
const taken = /* @__PURE__ */ new Set();
|
|
1400
|
+
for (const [rawId, body] of raw) {
|
|
1401
|
+
const identifier = readableIdentifier(rawId, taken);
|
|
1402
|
+
taken.add(identifier);
|
|
1403
|
+
identifiers.set(rawId, identifier);
|
|
1404
|
+
bodies.set(identifier, body);
|
|
1405
|
+
}
|
|
1406
|
+
return { nodes: removeElement(nodes, container), bodies, identifiers };
|
|
1407
|
+
}
|
|
1408
|
+
function inlineText(nodes) {
|
|
1409
|
+
return nodes.map(
|
|
1410
|
+
(n) => "value" in n && typeof n.value === "string" ? n.value : "children" in n && Array.isArray(n.children) ? inlineText(n.children) : ""
|
|
1411
|
+
).join("");
|
|
1412
|
+
}
|
|
1413
|
+
function isBlockish(node) {
|
|
1414
|
+
switch (node.type) {
|
|
1415
|
+
case "paragraph":
|
|
1416
|
+
case "heading":
|
|
1417
|
+
case "blockquote":
|
|
1418
|
+
case "list":
|
|
1419
|
+
case "listItem":
|
|
1420
|
+
case "table":
|
|
1421
|
+
case "tableRow":
|
|
1422
|
+
case "tableCell":
|
|
1423
|
+
case "code":
|
|
1424
|
+
case "footnoteDefinition":
|
|
1425
|
+
return true;
|
|
1426
|
+
default:
|
|
1427
|
+
return false;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
function linkFootnoteReferences(blocks, known) {
|
|
1431
|
+
const rewriteInlines = (nodes, inSuperscript) => {
|
|
1432
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
1433
|
+
const node = nodes[i];
|
|
1434
|
+
if (node.type === "link") {
|
|
1435
|
+
const id = node.url.startsWith("#") ? node.url.slice(1) : null;
|
|
1436
|
+
const identifier = id ? known.get(id) : void 0;
|
|
1437
|
+
if (identifier && (inSuperscript || MARKER_LABEL.test(inlineText(node.children)))) {
|
|
1438
|
+
nodes[i] = { type: "footnoteReference", identifier };
|
|
1439
|
+
}
|
|
1440
|
+
continue;
|
|
1441
|
+
}
|
|
1442
|
+
if (node.type === "superscript") {
|
|
1443
|
+
rewriteInlines(node.children, true);
|
|
1444
|
+
const only = node.children.length === 1 ? node.children[0] : null;
|
|
1445
|
+
if (only?.type === "footnoteReference") nodes[i] = only;
|
|
1446
|
+
continue;
|
|
1447
|
+
}
|
|
1448
|
+
if ("children" in node && Array.isArray(node.children)) {
|
|
1449
|
+
rewriteInlines(node.children, inSuperscript);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
};
|
|
1453
|
+
const walk = (list) => {
|
|
1454
|
+
for (const block of list) {
|
|
1455
|
+
if (!("children" in block) || !Array.isArray(block.children)) continue;
|
|
1456
|
+
const children = block.children;
|
|
1457
|
+
if (children.length > 0 && children.every(isBlockish)) {
|
|
1458
|
+
walk(children);
|
|
1459
|
+
} else {
|
|
1460
|
+
rewriteInlines(children, false);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
};
|
|
1464
|
+
walk(blocks);
|
|
1465
|
+
}
|
|
1466
|
+
function buildFootnoteDefinitions(bodies) {
|
|
1467
|
+
return [...bodies.entries()].map(([identifier, children]) => ({
|
|
1468
|
+
type: "footnoteDefinition",
|
|
1469
|
+
identifier,
|
|
1470
|
+
children
|
|
1471
|
+
}));
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
// src/html/import.ts
|
|
1241
1475
|
var HEADINGS = {
|
|
1242
1476
|
h1: 1,
|
|
1243
1477
|
h2: 2,
|
|
@@ -1267,8 +1501,10 @@ var DROP = /* @__PURE__ */ new Set(["script", "style", "head", "title", "noscrip
|
|
|
1267
1501
|
var INLINE_STRONG = /* @__PURE__ */ new Set(["strong", "b"]);
|
|
1268
1502
|
var INLINE_EM = /* @__PURE__ */ new Set(["em", "i"]);
|
|
1269
1503
|
var INLINE_DEL = /* @__PURE__ */ new Set(["del", "s", "strike"]);
|
|
1270
|
-
var
|
|
1271
|
-
var
|
|
1504
|
+
var INLINE_SUP = /* @__PURE__ */ new Set(["sup"]);
|
|
1505
|
+
var INLINE_SUB = /* @__PURE__ */ new Set(["sub"]);
|
|
1506
|
+
var INLINE_TRANSPARENT = /* @__PURE__ */ new Set(["span", "font", "abbr", "mark", "small", "u"]);
|
|
1507
|
+
var isElement2 = (n) => n.type === "htmlElement";
|
|
1272
1508
|
var isText = (n) => n.type === "htmlText";
|
|
1273
1509
|
var collapseWs = (s) => s.replace(/\s+/g, " ");
|
|
1274
1510
|
function inlinesFromNodes(nodes) {
|
|
@@ -1279,7 +1515,7 @@ function inlinesFromNodes(nodes) {
|
|
|
1279
1515
|
if (value) out.push({ type: "text", value });
|
|
1280
1516
|
continue;
|
|
1281
1517
|
}
|
|
1282
|
-
if (!
|
|
1518
|
+
if (!isElement2(node)) continue;
|
|
1283
1519
|
const tag = node.tagName.toLowerCase();
|
|
1284
1520
|
if (DROP.has(tag)) continue;
|
|
1285
1521
|
if (tag === "br") {
|
|
@@ -1290,6 +1526,10 @@ function inlinesFromNodes(nodes) {
|
|
|
1290
1526
|
out.push({ type: "emphasis", children: inlinesFromNodes(node.children) });
|
|
1291
1527
|
} else if (INLINE_DEL.has(tag)) {
|
|
1292
1528
|
out.push({ type: "delete", children: inlinesFromNodes(node.children) });
|
|
1529
|
+
} else if (INLINE_SUP.has(tag)) {
|
|
1530
|
+
out.push({ type: "superscript", children: inlinesFromNodes(node.children) });
|
|
1531
|
+
} else if (INLINE_SUB.has(tag)) {
|
|
1532
|
+
out.push({ type: "subscript", children: inlinesFromNodes(node.children) });
|
|
1293
1533
|
} else if (tag === "code" || tag === "kbd" || tag === "samp" || tag === "tt") {
|
|
1294
1534
|
out.push({ type: "inlineCode", value: textContent(node) });
|
|
1295
1535
|
} else if (tag === "a") {
|
|
@@ -1312,7 +1552,7 @@ function inlinesFromNodes(nodes) {
|
|
|
1312
1552
|
}
|
|
1313
1553
|
function textContent(node) {
|
|
1314
1554
|
if (isText(node)) return node.value;
|
|
1315
|
-
if (
|
|
1555
|
+
if (isElement2(node)) return node.children.map(textContent).join("");
|
|
1316
1556
|
return "";
|
|
1317
1557
|
}
|
|
1318
1558
|
var onlyWhitespace = (inlines) => inlines.every((n) => n.type === "text" && n.value.trim() === "");
|
|
@@ -1332,7 +1572,7 @@ function blocksFromNodes(nodes) {
|
|
|
1332
1572
|
inlineBuffer.push(node);
|
|
1333
1573
|
continue;
|
|
1334
1574
|
}
|
|
1335
|
-
if (!
|
|
1575
|
+
if (!isElement2(node)) continue;
|
|
1336
1576
|
const tag = node.tagName.toLowerCase();
|
|
1337
1577
|
if (DROP.has(tag)) continue;
|
|
1338
1578
|
const block = blockForElement(node, tag);
|
|
@@ -1381,7 +1621,7 @@ function blockForElement(node, tag) {
|
|
|
1381
1621
|
function listFromElement(node, ordered) {
|
|
1382
1622
|
const items = [];
|
|
1383
1623
|
for (const child of node.children) {
|
|
1384
|
-
if (
|
|
1624
|
+
if (isElement2(child) && child.tagName.toLowerCase() === "li") {
|
|
1385
1625
|
const blocks = blocksFromNodes(child.children);
|
|
1386
1626
|
items.push({ type: "listItem", children: blocks });
|
|
1387
1627
|
}
|
|
@@ -1399,12 +1639,12 @@ function tableFromElement(node) {
|
|
|
1399
1639
|
const rows = [];
|
|
1400
1640
|
const collectRows = (n) => {
|
|
1401
1641
|
for (const child of n.children) {
|
|
1402
|
-
if (!
|
|
1642
|
+
if (!isElement2(child)) continue;
|
|
1403
1643
|
const t = child.tagName.toLowerCase();
|
|
1404
1644
|
if (t === "tr") {
|
|
1405
1645
|
const cells = [];
|
|
1406
1646
|
for (const cell of child.children) {
|
|
1407
|
-
if (
|
|
1647
|
+
if (isElement2(cell) && (cell.tagName.toLowerCase() === "td" || cell.tagName.toLowerCase() === "th")) {
|
|
1408
1648
|
cells.push({ type: "tableCell", children: inlinesFromNodes(cell.children) });
|
|
1409
1649
|
}
|
|
1410
1650
|
}
|
|
@@ -1426,7 +1666,7 @@ function toHtmlString(data) {
|
|
|
1426
1666
|
}
|
|
1427
1667
|
function findEmbeddedSquisqDoc(nodes) {
|
|
1428
1668
|
for (const node of nodes) {
|
|
1429
|
-
if (!
|
|
1669
|
+
if (!isElement2(node)) continue;
|
|
1430
1670
|
if (node.tagName.toLowerCase() === "script" && "data-squisq-doc" in node.attributes) {
|
|
1431
1671
|
return node;
|
|
1432
1672
|
}
|
|
@@ -1460,11 +1700,19 @@ function htmlToMarkdownDocSync(html, options = {}) {
|
|
|
1460
1700
|
if (html.length > maxInputChars) {
|
|
1461
1701
|
throw new RangeError(`HTML exceeds the ${maxInputChars}-character safety limit`);
|
|
1462
1702
|
}
|
|
1463
|
-
|
|
1703
|
+
const nodes = parseHtmlToNodes(html);
|
|
1464
1704
|
const embedded = findEmbeddedSquisqDoc(nodes);
|
|
1465
1705
|
if (embedded) return docToMarkdown(parseEmbeddedSquisqDoc(embedded));
|
|
1466
|
-
|
|
1467
|
-
|
|
1706
|
+
const { nodes: bodyNodes, bodies, identifiers } = extractFootnoteSection(nodes);
|
|
1707
|
+
const clean = (input) => options.sanitize === false ? input : sanitizeHtmlNodes2(input);
|
|
1708
|
+
const children = blocksFromNodes(clean(bodyNodes));
|
|
1709
|
+
if (bodies.size > 0) {
|
|
1710
|
+
linkFootnoteReferences(children, identifiers ?? /* @__PURE__ */ new Map());
|
|
1711
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
1712
|
+
for (const [id, body] of bodies) definitions.set(id, blocksFromNodes(clean(body)));
|
|
1713
|
+
children.push(...buildFootnoteDefinitions(definitions));
|
|
1714
|
+
}
|
|
1715
|
+
return { type: "document", children };
|
|
1468
1716
|
}
|
|
1469
1717
|
async function htmlToMarkdownDoc(data, options = {}) {
|
|
1470
1718
|
return htmlToMarkdownDocSync(toHtmlString(data), options);
|
package/dist/docx/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
docxToDoc,
|
|
5
5
|
docxToMarkdownDoc,
|
|
6
6
|
markdownDocToDocx
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-FIOSE4BO.js";
|
|
8
|
+
import "../chunk-A6N6IN3I.js";
|
|
9
|
+
import "../chunk-AVOZAKGP.js";
|
|
10
10
|
import "../chunk-ILCJ3WFD.js";
|
|
11
11
|
import "../chunk-JU2RHXUB.js";
|
|
12
12
|
import "../chunk-S5PCVMKU.js";
|
|
@@ -14,6 +14,7 @@ import "../chunk-7AWFHP5U.js";
|
|
|
14
14
|
import "../chunk-IIQYS2YH.js";
|
|
15
15
|
import "../chunk-USU6HTKB.js";
|
|
16
16
|
import "../chunk-AONELFLA.js";
|
|
17
|
+
import "../chunk-BXWNU4T5.js";
|
|
17
18
|
export {
|
|
18
19
|
docToDocx,
|
|
19
20
|
docxToContainer,
|
package/dist/epub/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
docToEpub,
|
|
3
3
|
markdownDocToEpub
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-2LT3JL7U.js";
|
|
5
|
+
import "../chunk-AVOZAKGP.js";
|
|
6
6
|
import "../chunk-JU2RHXUB.js";
|
|
7
7
|
import "../chunk-USU6HTKB.js";
|
|
8
8
|
import "../chunk-6RQOV3B3.js";
|
|
9
9
|
import "../chunk-AONELFLA.js";
|
|
10
|
+
import "../chunk-BXWNU4T5.js";
|
|
10
11
|
export {
|
|
11
12
|
docToEpub,
|
|
12
13
|
markdownDocToEpub
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { MarkdownDocument } from '@bendyline/squisq/markdown';
|
|
2
|
+
import { O as OoxmlOpenOptions } from './reader-B_m1aKZC.js';
|
|
3
|
+
import { Doc } from '@bendyline/squisq/schemas';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* XLSX import — SpreadsheetML (.xlsx) → MarkdownDocument.
|
|
7
|
+
*
|
|
8
|
+
* Reuses the shared ooxml/ reader (zip + DOMParser). Reads the workbook's sheet
|
|
9
|
+
* list, resolves each sheet part via relationships, pulls shared strings, and
|
|
10
|
+
* turns each worksheet into markdown. By default every sheet is imported, each
|
|
11
|
+
* preceded by an H1 of the sheet name; pass `options.sheet` (index or name) to
|
|
12
|
+
* import just one.
|
|
13
|
+
*
|
|
14
|
+
* A sheet is NOT one table. It is usually several tables scattered across the
|
|
15
|
+
* grid with stray labels and notes in the gaps, so by default each worksheet is
|
|
16
|
+
* split into its contiguous data islands (see `regions.ts`) and every island
|
|
17
|
+
* becomes its own block:
|
|
18
|
+
*
|
|
19
|
+
* ```markdown
|
|
20
|
+
* ## Q3 Revenue {[dataTable sheet=Sales anchor=B7]}
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* The `sheet`/`anchor` params on the heading annotation are what let
|
|
24
|
+
* `markdownDocToXlsx` put each table back where it came from, so the round trip
|
|
25
|
+
* reproduces addresses rather than piling everything at A1. A region holding
|
|
26
|
+
* formulas additionally emits a `role=formulas` companion table, and every
|
|
27
|
+
* left-over single cell on a sheet collects into one `role=loose` table.
|
|
28
|
+
*
|
|
29
|
+
* Pass `{ regions: false }` for the historical behavior: one table per sheet,
|
|
30
|
+
* spanning the whole used range.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
interface XlsxImportOptions extends OoxmlOpenOptions {
|
|
34
|
+
/** Which sheet to import (0-based index or sheet name). Default: all sheets. */
|
|
35
|
+
sheet?: number | string;
|
|
36
|
+
/**
|
|
37
|
+
* Split each sheet into its contiguous data islands, one block each, anchored
|
|
38
|
+
* with `{[dataTable sheet=… anchor=…]}`. Default true. Set false for the
|
|
39
|
+
* historical one-table-per-sheet output.
|
|
40
|
+
*/
|
|
41
|
+
regions?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Emit a `role=formulas` companion table for regions that contain formulas.
|
|
44
|
+
* Default true. Ignored when `regions` is false.
|
|
45
|
+
*/
|
|
46
|
+
formulas?: boolean;
|
|
47
|
+
/** Cap on region tables per sheet before the rest fold into loose cells. Default 64. */
|
|
48
|
+
maxRegionsPerSheet?: number;
|
|
49
|
+
/** Smallest island that stays a table of its own. Default 2 — single cells coalesce. */
|
|
50
|
+
minRegionCells?: number;
|
|
51
|
+
}
|
|
52
|
+
declare function xlsxToMarkdownDoc(data: ArrayBuffer | Blob, options?: XlsxImportOptions): Promise<MarkdownDocument>;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* XLSX export — MarkdownDocument → SpreadsheetML (.xlsx).
|
|
56
|
+
*
|
|
57
|
+
* Tables-only fidelity (honestly documented): every `table` node in the
|
|
58
|
+
* markdown AST becomes worksheet cells; all other content (prose, lists,
|
|
59
|
+
* images, …) is dropped, and headings survive only as sheet names and as the
|
|
60
|
+
* carrier of placement metadata.
|
|
61
|
+
*
|
|
62
|
+
* Placement has two modes, decided per table by `workbookPlan.ts`. A table
|
|
63
|
+
* whose heading carries `{[dataTable sheet=… anchor=…]}` — what
|
|
64
|
+
* `xlsxToMarkdownDoc` emits for every data island it finds — is placed on the
|
|
65
|
+
* named sheet at the named cell, so several mini tables share one worksheet at
|
|
66
|
+
* their original addresses and formulas ride along. A table with no such
|
|
67
|
+
* annotation keeps the historical behavior exactly: its own worksheet, named
|
|
68
|
+
* from the nearest preceding heading, starting at A1.
|
|
69
|
+
*
|
|
70
|
+
* Cells are emitted as inline strings (`t="inlineStr"`) by default so no
|
|
71
|
+
* sharedStrings part is needed and identifier-like numbers remain lossless.
|
|
72
|
+
* Callers can explicitly opt into conservative numeric inference. The package
|
|
73
|
+
* is assembled with the shared ooxml/ writer (auto-generates
|
|
74
|
+
* `[Content_Types].xml` + `_rels`), so only the SpreadsheetML-specific parts
|
|
75
|
+
* (workbook, worksheets, styles) are written here.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { parseMarkdown } from '@bendyline/squisq/markdown';
|
|
80
|
+
* import { markdownDocToXlsx } from '@bendyline/squisq-formats/xlsx';
|
|
81
|
+
*
|
|
82
|
+
* const md = parseMarkdown('# Metrics\n\n| A | B |\n| - | - |\n| 1 | 2 |');
|
|
83
|
+
* const buffer = await markdownDocToXlsx(md);
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Options for XLSX export.
|
|
89
|
+
*/
|
|
90
|
+
interface XlsxExportOptions {
|
|
91
|
+
/** Cancel at bounded export checkpoints. */
|
|
92
|
+
signal?: AbortSignal;
|
|
93
|
+
/** Maximum cells emitted. Default: 100,000. */
|
|
94
|
+
maxCells?: number;
|
|
95
|
+
/** Workbook title (written to core properties). */
|
|
96
|
+
title?: string;
|
|
97
|
+
/** Workbook author (written to core properties). */
|
|
98
|
+
author?: string;
|
|
99
|
+
/** Prefix used for auto-named sheets when no heading precedes a table. Default: "Sheet". */
|
|
100
|
+
sheetNamePrefix?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Emit canonical, Excel-safe number strings as numeric cells.
|
|
103
|
+
*
|
|
104
|
+
* Defaults to false for hand-authored documents — markdown tables have no
|
|
105
|
+
* column schema, so preserving authored text is the only lossless choice —
|
|
106
|
+
* and to true when the document carries `sheet=` anchors, which only an XLSX
|
|
107
|
+
* import produces. Leading-zero and >15-significant-digit values remain
|
|
108
|
+
* strings either way. Set explicitly to override both defaults.
|
|
109
|
+
*/
|
|
110
|
+
inferNumericCells?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Called for each non-fatal placement problem (a malformed anchor, an
|
|
113
|
+
* overlapping region, an unusable loose-cell reference). Export never throws
|
|
114
|
+
* for these — a hand-edited markdown file must still convert.
|
|
115
|
+
*/
|
|
116
|
+
onWarning?: (message: string) => void;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Convert a MarkdownDocument to a .xlsx file (tables-only fidelity).
|
|
120
|
+
*
|
|
121
|
+
* Each markdown `table` becomes one worksheet; a document with no tables
|
|
122
|
+
* yields a single empty sheet (a valid, openable file — never throws).
|
|
123
|
+
*/
|
|
124
|
+
declare function markdownDocToXlsx(doc: MarkdownDocument, options?: XlsxExportOptions): Promise<ArrayBuffer>;
|
|
125
|
+
/**
|
|
126
|
+
* Convert a squisq Doc to a .xlsx file (via the markdown table model).
|
|
127
|
+
*/
|
|
128
|
+
declare function docToXlsx(doc: Doc, options?: XlsxExportOptions): Promise<ArrayBuffer>;
|
|
129
|
+
|
|
130
|
+
export { type XlsxExportOptions as X, type XlsxImportOptions as a, docToXlsx as d, markdownDocToXlsx as m, xlsxToMarkdownDoc as x };
|
package/dist/html/index.js
CHANGED
|
@@ -10,13 +10,14 @@ import {
|
|
|
10
10
|
markdownDocToPlainHtml,
|
|
11
11
|
markdownDocsToHtmlBundle,
|
|
12
12
|
markdownDocsToPlainHtmlBundle
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-T4PX33AG.js";
|
|
14
14
|
import {
|
|
15
15
|
arrayBufferToBase64DataUrl,
|
|
16
16
|
extractFilename,
|
|
17
17
|
inferMimeType
|
|
18
18
|
} from "../chunk-6RQOV3B3.js";
|
|
19
19
|
import "../chunk-AONELFLA.js";
|
|
20
|
+
import "../chunk-BXWNU4T5.js";
|
|
20
21
|
export {
|
|
21
22
|
arrayBufferToBase64DataUrl,
|
|
22
23
|
collectImagePaths,
|
package/dist/index.d.ts
CHANGED
|
@@ -6,13 +6,13 @@ export { PdfExportOptions, PdfImportOptions, configurePdfWorker, docToPdf, markd
|
|
|
6
6
|
export { HtmlZipExportOptions, docToHtml, docToHtmlZip } from './html/index.js';
|
|
7
7
|
export { EpubExportOptions, docToEpub, markdownDocToEpub } from './epub/index.js';
|
|
8
8
|
export { ExtractedFileTheme, InferSourceFormat, InferThemeOptions, InferredFileTheme, compileExtractedTheme, inferThemeFromFile } from './infer/index.js';
|
|
9
|
-
export { B as BUILTIN_FORMAT_IDS, a as BuiltinFormatOptions, C as ConversionLimits, b as ConversionResult, c as ConvertOptions, d as ConvertSource, D as DEFAULT_CONVERSION_LIMITS, e as DbkFormatOptions, F as FormatDefinition, f as FormatId, g as FormatRegistry, M as MarkdownFormatOptions, N as NormalizedInput, P as PreparedConversion, h as PreparedExportOptions, r as resolveConversionLimits } from './types-
|
|
9
|
+
export { B as BUILTIN_FORMAT_IDS, a as BuiltinFormatOptions, C as ConversionLimits, b as ConversionResult, c as ConvertOptions, d as ConvertSource, D as DEFAULT_CONVERSION_LIMITS, e as DbkFormatOptions, F as FormatDefinition, f as FormatId, g as FormatRegistry, M as MarkdownFormatOptions, N as NormalizedInput, P as PreparedConversion, h as PreparedExportOptions, r as resolveConversionLimits } from './types-DByrrXeB.js';
|
|
10
10
|
export { ConversionError, ConversionErrorCode, ConversionErrorOptions, convert, createRegistry, defaultFormats, defaultRegistry, prepareConversion } from './registry/index.js';
|
|
11
11
|
export { ImportedOutsideInDocument, OUTSIDE_IN_FORMAT_IDS, OUTSIDE_IN_UPDATE_FROM_MARKDOWN_KEY, OutsideInFormatId, OutsideInLayout, OutsideInMetadata, RenderOutsideInOptions, chooseOutsideInMarkdownPath, importOutsideInDocument, isOutsideInMarkdownEditingEnabled, isOutsideInTargetPath, readOutsideInMetadata, renderOutsideInDocument, resolveOutsideInLayout, withOutsideInMarkdownEditing, withOutsideInMetadata } from './outside-in/index.js';
|
|
12
12
|
export { Z as ZipSafetyError, a as ZipSafetyErrorCode, b as ZipSafetyErrorOptions, c as ZipSafetyLimits } from './zipLimits-BOKCB7qk.js';
|
|
13
13
|
export { H as HtmlExportOptions, a as HtmlImportOptions, c as collectImagePaths, h as htmlToMarkdown, b as htmlToMarkdownDoc, d as htmlToMarkdownDocSync } from './import-B0gBYUmd.js';
|
|
14
14
|
export { P as PptxExportOptions, a as PptxImportOptions, d as docToPptx, m as markdownDocToPptx, p as pptxToMarkdownDoc } from './import-C16E8Y4X.js';
|
|
15
|
-
export { X as XlsxExportOptions, a as XlsxImportOptions, d as docToXlsx, m as markdownDocToXlsx, x as xlsxToMarkdownDoc } from './export-
|
|
15
|
+
export { X as XlsxExportOptions, a as XlsxImportOptions, d as docToXlsx, m as markdownDocToXlsx, x as xlsxToMarkdownDoc } from './export-m0tr9r9d.js';
|
|
16
16
|
import '@bendyline/squisq/schemas';
|
|
17
17
|
import '@bendyline/squisq/markdown';
|
|
18
18
|
import './reader-B_m1aKZC.js';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
docToEpub,
|
|
3
3
|
markdownDocToEpub
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2LT3JL7U.js";
|
|
5
5
|
import {
|
|
6
6
|
BUILTIN_FORMAT_IDS
|
|
7
7
|
} from "./chunk-2P5HJAQL.js";
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
resolveOutsideInLayout,
|
|
21
21
|
withOutsideInMarkdownEditing,
|
|
22
22
|
withOutsideInMetadata
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-5PUIFU5I.js";
|
|
24
24
|
import {
|
|
25
25
|
DEFAULT_CONVERSION_LIMITS,
|
|
26
26
|
convert,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
defaultRegistry,
|
|
30
30
|
prepareConversion,
|
|
31
31
|
resolveConversionLimits
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-JTGWQK5V.js";
|
|
33
33
|
import {
|
|
34
34
|
ConversionError
|
|
35
35
|
} from "./chunk-KXOZMWBS.js";
|
|
@@ -42,22 +42,22 @@ import {
|
|
|
42
42
|
docxToDoc,
|
|
43
43
|
docxToMarkdownDoc,
|
|
44
44
|
markdownDocToDocx
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-FIOSE4BO.js";
|
|
46
46
|
import {
|
|
47
47
|
docToPptx,
|
|
48
48
|
markdownDocToPptx,
|
|
49
49
|
pptxToDoc,
|
|
50
50
|
pptxToMarkdownDoc
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-FMQWNPCV.js";
|
|
52
52
|
import "./chunk-6N2J7C2B.js";
|
|
53
|
-
import "./chunk-
|
|
53
|
+
import "./chunk-A6N6IN3I.js";
|
|
54
54
|
import {
|
|
55
55
|
docToXlsx,
|
|
56
56
|
markdownDocToXlsx,
|
|
57
57
|
xlsxToDoc,
|
|
58
58
|
xlsxToMarkdownDoc
|
|
59
|
-
} from "./chunk-
|
|
60
|
-
import "./chunk-
|
|
59
|
+
} from "./chunk-A6LSCIO5.js";
|
|
60
|
+
import "./chunk-AVOZAKGP.js";
|
|
61
61
|
import {
|
|
62
62
|
csvToDoc,
|
|
63
63
|
csvToMarkdownDoc,
|
|
@@ -77,7 +77,7 @@ import {
|
|
|
77
77
|
markdownDocToPdf,
|
|
78
78
|
pdfToDoc,
|
|
79
79
|
pdfToMarkdownDoc
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-M7XPXGXW.js";
|
|
81
81
|
import "./chunk-IIQYS2YH.js";
|
|
82
82
|
import "./chunk-USU6HTKB.js";
|
|
83
83
|
import {
|
|
@@ -87,9 +87,10 @@ import {
|
|
|
87
87
|
htmlToMarkdown,
|
|
88
88
|
htmlToMarkdownDoc,
|
|
89
89
|
htmlToMarkdownDocSync
|
|
90
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-T4PX33AG.js";
|
|
91
91
|
import "./chunk-6RQOV3B3.js";
|
|
92
92
|
import "./chunk-AONELFLA.js";
|
|
93
|
+
import "./chunk-BXWNU4T5.js";
|
|
93
94
|
export {
|
|
94
95
|
BUILTIN_FORMAT_IDS,
|
|
95
96
|
ConversionError,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { MarkdownDocument } from '@bendyline/squisq/markdown';
|
|
2
2
|
import { ContentContainer } from '@bendyline/squisq/storage';
|
|
3
|
-
import { c as ConvertOptions, b as ConversionResult } from '../types-
|
|
3
|
+
import { c as ConvertOptions, b as ConversionResult } from '../types-DByrrXeB.js';
|
|
4
4
|
import '@bendyline/squisq/schemas';
|
|
5
5
|
import '@bendyline/squisq/transform';
|
|
6
6
|
import '../docx/index.js';
|
|
7
7
|
import '../reader-B_m1aKZC.js';
|
|
8
8
|
import '../zipLimits-BOKCB7qk.js';
|
|
9
9
|
import '../import-C16E8Y4X.js';
|
|
10
|
-
import '../export-
|
|
10
|
+
import '../export-m0tr9r9d.js';
|
|
11
11
|
import '../csv/index.js';
|
|
12
12
|
import '../pdf/index.js';
|
|
13
13
|
import '../import-B0gBYUmd.js';
|