@bendyline/squisq-formats 2.1.0 → 2.2.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.
Files changed (195) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +20 -0
  3. package/README.md +1 -1
  4. package/dist/{chunk-NNHKUXKA.js → chunk-26ISNJ7Y.js} +85 -65
  5. package/dist/{chunk-NKAJPJ4G.js → chunk-2JJ5RFDZ.js} +0 -1
  6. package/dist/{chunk-WQSHGBLN.js → chunk-3NKXBZSR.js} +193 -42
  7. package/dist/{chunk-KURGXM4I.js → chunk-4V3KCHAP.js} +3 -4
  8. package/dist/{chunk-MLX2BOJC.js → chunk-6RQOV3B3.js} +1 -2
  9. package/dist/{chunk-EW54IRRS.js → chunk-6S6GU3ZG.js} +5 -6
  10. package/dist/{chunk-FE6OJV6O.js → chunk-7AWFHP5U.js} +1 -1
  11. package/dist/{chunk-RFAPOKHJ.js → chunk-AD2WT564.js} +59 -9
  12. package/dist/{chunk-O3GVVND4.js → chunk-AONELFLA.js} +0 -1
  13. package/dist/{chunk-SC67HYQJ.js → chunk-EJTNGKEA.js} +5 -8
  14. package/dist/chunk-GX7RAUME.js +121 -0
  15. package/dist/{chunk-SSUPBUF5.js → chunk-IIQYS2YH.js} +0 -1
  16. package/dist/{chunk-RLU7UFYU.js → chunk-IPN56VLW.js} +83 -58
  17. package/dist/{chunk-DTDF6QDP.js → chunk-JE6LSIHE.js} +81 -20
  18. package/dist/{chunk-U4MRIFKL.js → chunk-JU2RHXUB.js} +0 -1
  19. package/dist/{chunk-4VUWTSGM.js → chunk-K6XRMVPW.js} +64 -31
  20. package/dist/{chunk-ODL3SSPT.js → chunk-KXOZMWBS.js} +0 -1
  21. package/dist/chunk-OGS5VCGJ.js +446 -0
  22. package/dist/{chunk-GVS2XXV6.js → chunk-PJXJI2LY.js} +449 -57
  23. package/dist/{chunk-74GO3FVS.js → chunk-PU7REGWV.js} +5 -8
  24. package/dist/{chunk-PN52A5AA.js → chunk-SBUW7NHR.js} +0 -1
  25. package/dist/{chunk-QFLDYKCR.js → chunk-TAAENIRB.js} +5 -8
  26. package/dist/{chunk-7ARKUCQT.js → chunk-X2DEAXNK.js} +54 -2
  27. package/dist/container/index.js +1 -2
  28. package/dist/csv/index.d.ts +27 -2
  29. package/dist/csv/index.js +1 -2
  30. package/dist/docx/index.d.ts +5 -1
  31. package/dist/docx/index.js +9 -11
  32. package/dist/epub/index.d.ts +2 -0
  33. package/dist/epub/index.js +5 -6
  34. package/dist/{export-D2NkylDT.d.ts → export-D9msROJS.d.ts} +18 -6
  35. package/dist/extract-MN7LA3NL.js +13 -0
  36. package/dist/html/index.d.ts +11 -4
  37. package/dist/html/index.js +3 -4
  38. package/dist/images-ESPQKVTW.js +6 -0
  39. package/dist/{import-K8mfc0fz.d.ts → import-C3htUTss.d.ts} +5 -1
  40. package/dist/{import-DTkDxHmZ.d.ts → import-C8whCC7_.d.ts} +6 -0
  41. package/dist/index.d.ts +7 -7
  42. package/dist/index.js +28 -26
  43. package/dist/infer/index.d.ts +3 -3
  44. package/dist/infer/index.js +7 -9
  45. package/dist/{layouts-BHrgZ5FS.d.ts → layouts-CTdPlB-u.d.ts} +1 -1
  46. package/dist/layouts-DRWZGSPD.js +10 -0
  47. package/dist/{mapTheme-IR27S6IV.js → mapTheme-4TWH25FT.js} +1 -2
  48. package/dist/ooxml/index.d.ts +3 -3
  49. package/dist/ooxml/index.js +14 -13
  50. package/dist/pdf/index.d.ts +18 -0
  51. package/dist/pdf/index.js +2 -3
  52. package/dist/pptx/index.d.ts +4 -4
  53. package/dist/pptx/index.js +11 -13
  54. package/dist/{reader-B9L8Ucbj.d.ts → reader-B_m1aKZC.d.ts} +30 -1
  55. package/dist/registry/index.d.ts +21 -5
  56. package/dist/registry/index.js +9 -6
  57. package/dist/{themeReader-DJKErl_j.d.ts → themeReader-DCtwC83Q.d.ts} +1 -1
  58. package/dist/xlsx/index.d.ts +3 -3
  59. package/dist/xlsx/index.js +6 -7
  60. package/package.json +6 -3
  61. package/dist/chunk-4VUWTSGM.js.map +0 -1
  62. package/dist/chunk-6M7Z25LA.js +0 -46
  63. package/dist/chunk-6M7Z25LA.js.map +0 -1
  64. package/dist/chunk-74GO3FVS.js.map +0 -1
  65. package/dist/chunk-7ARKUCQT.js.map +0 -1
  66. package/dist/chunk-DTDF6QDP.js.map +0 -1
  67. package/dist/chunk-EW54IRRS.js.map +0 -1
  68. package/dist/chunk-FE6OJV6O.js.map +0 -1
  69. package/dist/chunk-GVS2XXV6.js.map +0 -1
  70. package/dist/chunk-KURGXM4I.js.map +0 -1
  71. package/dist/chunk-MLX2BOJC.js.map +0 -1
  72. package/dist/chunk-NKAJPJ4G.js.map +0 -1
  73. package/dist/chunk-NNHKUXKA.js.map +0 -1
  74. package/dist/chunk-O3GVVND4.js.map +0 -1
  75. package/dist/chunk-ODL3SSPT.js.map +0 -1
  76. package/dist/chunk-PN52A5AA.js.map +0 -1
  77. package/dist/chunk-QFLDYKCR.js.map +0 -1
  78. package/dist/chunk-RFAPOKHJ.js.map +0 -1
  79. package/dist/chunk-RLU7UFYU.js.map +0 -1
  80. package/dist/chunk-SC67HYQJ.js.map +0 -1
  81. package/dist/chunk-SSUPBUF5.js.map +0 -1
  82. package/dist/chunk-U4MRIFKL.js.map +0 -1
  83. package/dist/chunk-UGYF5AZE.js +0 -275
  84. package/dist/chunk-UGYF5AZE.js.map +0 -1
  85. package/dist/chunk-WQSHGBLN.js.map +0 -1
  86. package/dist/chunk-YRT7GQ5Y.js +0 -28
  87. package/dist/chunk-YRT7GQ5Y.js.map +0 -1
  88. package/dist/container/index.js.map +0 -1
  89. package/dist/csv/index.js.map +0 -1
  90. package/dist/docx/index.js.map +0 -1
  91. package/dist/epub/index.js.map +0 -1
  92. package/dist/extract-OJ7ZQV6P.js +0 -15
  93. package/dist/extract-OJ7ZQV6P.js.map +0 -1
  94. package/dist/html/index.js.map +0 -1
  95. package/dist/images-7FBWPKE3.js +0 -7
  96. package/dist/images-7FBWPKE3.js.map +0 -1
  97. package/dist/index.js.map +0 -1
  98. package/dist/infer/index.js.map +0 -1
  99. package/dist/layouts-5VDIRPIJ.js +0 -12
  100. package/dist/layouts-5VDIRPIJ.js.map +0 -1
  101. package/dist/mapTheme-IR27S6IV.js.map +0 -1
  102. package/dist/ooxml/index.js.map +0 -1
  103. package/dist/pdf/index.js.map +0 -1
  104. package/dist/pptx/index.js.map +0 -1
  105. package/dist/registry/index.js.map +0 -1
  106. package/dist/xlsx/index.js.map +0 -1
  107. package/src/__tests__/container.test.ts +0 -230
  108. package/src/__tests__/convert.test.ts +0 -495
  109. package/src/__tests__/csvImport.test.ts +0 -84
  110. package/src/__tests__/docxExport.test.ts +0 -491
  111. package/src/__tests__/docxImport.test.ts +0 -531
  112. package/src/__tests__/epub.test.ts +0 -649
  113. package/src/__tests__/exportThemeReconciliation.test.ts +0 -87
  114. package/src/__tests__/formatRegistry.test.ts +0 -174
  115. package/src/__tests__/html.test.ts +0 -439
  116. package/src/__tests__/htmlImport.test.ts +0 -57
  117. package/src/__tests__/inferTheme.test.ts +0 -135
  118. package/src/__tests__/lossyWarnings.test.ts +0 -146
  119. package/src/__tests__/ooxml.test.ts +0 -271
  120. package/src/__tests__/ooxmlCancellation.test.ts +0 -113
  121. package/src/__tests__/ooxmlThemeReader.test.ts +0 -92
  122. package/src/__tests__/pdfExport.test.ts +0 -322
  123. package/src/__tests__/pdfImport.test.ts +0 -384
  124. package/src/__tests__/plainHtml.test.ts +0 -417
  125. package/src/__tests__/plainHtmlBundle.test.ts +0 -253
  126. package/src/__tests__/pptxExport.test.ts +0 -138
  127. package/src/__tests__/pptxImport.test.ts +0 -145
  128. package/src/__tests__/pptxInferFixtures.ts +0 -314
  129. package/src/__tests__/pptxLayoutInfer.test.ts +0 -395
  130. package/src/__tests__/roundTrip.test.ts +0 -201
  131. package/src/__tests__/roundTripAssets.test.ts +0 -50
  132. package/src/__tests__/roundTripMatrix.fixtures.ts +0 -86
  133. package/src/__tests__/roundTripMatrix.helpers.ts +0 -154
  134. package/src/__tests__/roundTripMatrix.test.ts +0 -142
  135. package/src/__tests__/sharedContainer.test.ts +0 -41
  136. package/src/__tests__/sharedImages.test.ts +0 -61
  137. package/src/__tests__/xlsxExport.test.ts +0 -164
  138. package/src/__tests__/xlsxImport.test.ts +0 -80
  139. package/src/__tests__/zipSafety.test.ts +0 -317
  140. package/src/container/index.ts +0 -94
  141. package/src/csv/index.ts +0 -188
  142. package/src/docx/export.ts +0 -1375
  143. package/src/docx/import.ts +0 -1250
  144. package/src/docx/index.ts +0 -26
  145. package/src/docx/styles.ts +0 -145
  146. package/src/epub/export.ts +0 -968
  147. package/src/epub/index.ts +0 -20
  148. package/src/html/docsHtmlBundle.ts +0 -373
  149. package/src/html/htmlTemplate.ts +0 -385
  150. package/src/html/imageUtils.ts +0 -61
  151. package/src/html/import.ts +0 -297
  152. package/src/html/index.ts +0 -212
  153. package/src/html/plainHtml.ts +0 -790
  154. package/src/html/plainHtmlBundle.ts +0 -421
  155. package/src/index.ts +0 -109
  156. package/src/infer/extract.ts +0 -127
  157. package/src/infer/index.ts +0 -199
  158. package/src/infer/mapTheme.ts +0 -176
  159. package/src/infer/types.ts +0 -27
  160. package/src/ooxml/index.ts +0 -111
  161. package/src/ooxml/namespaces.ts +0 -217
  162. package/src/ooxml/readUtils.ts +0 -44
  163. package/src/ooxml/reader.ts +0 -318
  164. package/src/ooxml/themeReader.ts +0 -197
  165. package/src/ooxml/types.ts +0 -103
  166. package/src/ooxml/writer.ts +0 -339
  167. package/src/ooxml/xmlUtils.ts +0 -123
  168. package/src/pdf/export.ts +0 -1084
  169. package/src/pdf/import.ts +0 -1164
  170. package/src/pdf/index.ts +0 -29
  171. package/src/pdf/styles.ts +0 -180
  172. package/src/pptx/export.ts +0 -1184
  173. package/src/pptx/import.ts +0 -455
  174. package/src/pptx/index.ts +0 -52
  175. package/src/pptx/layouts.ts +0 -1222
  176. package/src/pptx/styles.ts +0 -96
  177. package/src/pptx/templates.ts +0 -187
  178. package/src/registry/convert.ts +0 -433
  179. package/src/registry/defaultFormats.ts +0 -413
  180. package/src/registry/errors.ts +0 -46
  181. package/src/registry/index.ts +0 -43
  182. package/src/registry/registry.ts +0 -48
  183. package/src/registry/types.ts +0 -170
  184. package/src/shared/boundedZipArchive.ts +0 -383
  185. package/src/shared/container.ts +0 -28
  186. package/src/shared/fidelity.ts +0 -130
  187. package/src/shared/images.ts +0 -44
  188. package/src/shared/inlineRuns.ts +0 -99
  189. package/src/shared/text.ts +0 -41
  190. package/src/shared/zipEntryCount.ts +0 -151
  191. package/src/shared/zipLimits.ts +0 -296
  192. package/src/shared/zipSafety.ts +0 -19
  193. package/src/xlsx/export.ts +0 -253
  194. package/src/xlsx/import.ts +0 -160
  195. package/src/xlsx/index.ts +0 -35
@@ -1,21 +1,20 @@
1
1
  import {
2
2
  inferThemeFromFile
3
- } from "../chunk-EW54IRRS.js";
4
- import "../chunk-ODL3SSPT.js";
3
+ } from "../chunk-6S6GU3ZG.js";
4
+ import "../chunk-KXOZMWBS.js";
5
5
  import {
6
6
  extractDocxTheme,
7
7
  extractPptxTheme,
8
8
  extractXlsxTheme
9
- } from "../chunk-74GO3FVS.js";
9
+ } from "../chunk-PU7REGWV.js";
10
10
  import {
11
11
  colorHintsFromExtraction,
12
12
  compileExtractedTheme,
13
13
  extractedThemeToPartial
14
- } from "../chunk-NKAJPJ4G.js";
15
- import "../chunk-SC67HYQJ.js";
16
- import "../chunk-YRT7GQ5Y.js";
17
- import "../chunk-7ARKUCQT.js";
18
- import "../chunk-FE6OJV6O.js";
14
+ } from "../chunk-2JJ5RFDZ.js";
15
+ import "../chunk-EJTNGKEA.js";
16
+ import "../chunk-X2DEAXNK.js";
17
+ import "../chunk-7AWFHP5U.js";
19
18
  export {
20
19
  colorHintsFromExtraction,
21
20
  compileExtractedTheme,
@@ -25,4 +24,3 @@ export {
25
24
  extractedThemeToPartial,
26
25
  inferThemeFromFile
27
26
  };
28
- //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import { CustomTemplateDefinition } from '@bendyline/squisq/schemas';
2
- import { O as OoxmlOpenOptions, a as OoxmlPackage } from './reader-B9L8Ucbj.js';
2
+ import { O as OoxmlOpenOptions, a as OoxmlPackage } from './reader-B_m1aKZC.js';
3
3
 
4
4
  /**
5
5
  * PPTX slide-layout inference — reads the layouts/masters a deck actually
@@ -0,0 +1,10 @@
1
+ import {
2
+ analyzePptxLayouts,
3
+ inspectPptxLayouts
4
+ } from "./chunk-TAAENIRB.js";
5
+ import "./chunk-X2DEAXNK.js";
6
+ import "./chunk-7AWFHP5U.js";
7
+ export {
8
+ analyzePptxLayouts,
9
+ inspectPptxLayouts
10
+ };
@@ -2,10 +2,9 @@ import {
2
2
  colorHintsFromExtraction,
3
3
  compileExtractedTheme,
4
4
  extractedThemeToPartial
5
- } from "./chunk-NKAJPJ4G.js";
5
+ } from "./chunk-2JJ5RFDZ.js";
6
6
  export {
7
7
  colorHintsFromExtraction,
8
8
  compileExtractedTheme,
9
9
  extractedThemeToPartial
10
10
  };
11
- //# sourceMappingURL=mapTheme-IR27S6IV.js.map
@@ -1,7 +1,7 @@
1
- import { R as Relationship, C as CoreProperties } from '../reader-B9L8Ucbj.js';
2
- export { b as ContentTypeMap, O as OoxmlOpenOptions, a as OoxmlPackage, P as PackagePart, c as PendingRelationship, g as getCoreProperties, d as getPartBinary, e as getPartRelationships, f as getPartXml, o as openPackage } from '../reader-B9L8Ucbj.js';
1
+ import { R as Relationship, C as CoreProperties } from '../reader-B_m1aKZC.js';
2
+ export { b as ContentTypeMap, O as OoxmlOpenOptions, a as OoxmlPackage, P as PackagePart, c as PendingRelationship, g as getCoreProperties, d as getPartBinary, e as getPartRelationships, f as getPartXml, o as openPackage, r as requireMainPartPath, h as resolveMainPartPath } from '../reader-B_m1aKZC.js';
3
3
  export { Z as ZipSafetyError, a as ZipSafetyErrorCode, b as ZipSafetyErrorOptions, c as ZipSafetyLimits } from '../zipLimits-BOKCB7qk.js';
4
- export { O as OoxmlColorScheme, a as OoxmlFontScheme, b as OoxmlTheme, p as parseThemeXml, r as readThemePart } from '../themeReader-DJKErl_j.js';
4
+ export { O as OoxmlColorScheme, a as OoxmlFontScheme, b as OoxmlTheme, p as parseThemeXml, r as readThemePart } from '../themeReader-DCtwC83Q.js';
5
5
 
6
6
  /**
7
7
  * Shared DOM-read helpers for OOXML importers.
@@ -1,16 +1,10 @@
1
1
  import {
2
2
  parseThemeXml,
3
3
  readThemePart
4
- } from "../chunk-SC67HYQJ.js";
5
- import {
6
- attrNS,
7
- baseDirOf,
8
- findRelByType,
9
- resolveTarget
10
- } from "../chunk-YRT7GQ5Y.js";
4
+ } from "../chunk-EJTNGKEA.js";
11
5
  import {
12
6
  createPackage
13
- } from "../chunk-KURGXM4I.js";
7
+ } from "../chunk-4V3KCHAP.js";
14
8
  import {
15
9
  attrString,
16
10
  escapeXml,
@@ -18,7 +12,7 @@ import {
18
12
  textElement,
19
13
  xmlDeclaration,
20
14
  xmlElement
21
- } from "../chunk-U4MRIFKL.js";
15
+ } from "../chunk-JU2RHXUB.js";
22
16
  import {
23
17
  CONTENT_TYPE_CORE_PROPERTIES,
24
18
  CONTENT_TYPE_DOCX_DOCUMENT,
@@ -65,15 +59,21 @@ import {
65
59
  REL_STYLES,
66
60
  REL_THEME,
67
61
  REL_WORKSHEET,
62
+ attrNS,
63
+ baseDirOf,
64
+ findRelByType,
68
65
  getCoreProperties,
69
66
  getPartBinary,
70
67
  getPartRelationships,
71
68
  getPartXml,
72
- openPackage
73
- } from "../chunk-7ARKUCQT.js";
69
+ openPackage,
70
+ requireMainPartPath,
71
+ resolveMainPartPath,
72
+ resolveTarget
73
+ } from "../chunk-X2DEAXNK.js";
74
74
  import {
75
75
  ZipSafetyError
76
- } from "../chunk-FE6OJV6O.js";
76
+ } from "../chunk-7AWFHP5U.js";
77
77
  export {
78
78
  CONTENT_TYPE_CORE_PROPERTIES,
79
79
  CONTENT_TYPE_DOCX_DOCUMENT,
@@ -134,10 +134,11 @@ export {
134
134
  openPackage,
135
135
  parseThemeXml,
136
136
  readThemePart,
137
+ requireMainPartPath,
138
+ resolveMainPartPath,
137
139
  resolveTarget,
138
140
  selfClosingElement,
139
141
  textElement,
140
142
  xmlDeclaration,
141
143
  xmlElement
142
144
  };
143
- //# sourceMappingURL=index.js.map
@@ -29,6 +29,8 @@ type PdfPageSize = 'letter' | 'a4';
29
29
  * Options for PDF export.
30
30
  */
31
31
  interface PdfExportOptions {
32
+ /** Cancel at bounded export checkpoints. */
33
+ signal?: AbortSignal;
32
34
  /** Document title (PDF metadata). */
33
35
  title?: string;
34
36
  /** Document author (PDF metadata). */
@@ -47,6 +49,14 @@ interface PdfExportOptions {
47
49
  themeId?: string;
48
50
  /** Explicit caller-owned registry for non-document custom themes. */
49
51
  themeRegistry?: ThemeRegistry;
52
+ /**
53
+ * Receives non-fatal notes about the export — today, the one-shot summary
54
+ * raised when characters outside the standard PDF fonts' WinAnsi encoding
55
+ * had to be substituted. When omitted, such notes go to `console.warn`.
56
+ * The registry passes a collector so the message reaches
57
+ * `ConversionResult.warnings` instead.
58
+ */
59
+ onWarning?: (message: string) => void;
50
60
  }
51
61
  /**
52
62
  * Convert a MarkdownDocument to a PDF ArrayBuffer.
@@ -85,6 +95,14 @@ declare function docToPdf(doc: Doc, options?: PdfExportOptions): Promise<ArrayBu
85
95
  * Options for PDF import.
86
96
  */
87
97
  interface PdfImportOptions {
98
+ /** Cancel between pages and image operations. */
99
+ signal?: AbortSignal;
100
+ /** Maximum pages processed. Default: 5,000. */
101
+ maxPages?: number;
102
+ /** Maximum positioned text items processed. Default: 1,000,000. */
103
+ maxTextItems?: number;
104
+ /** Maximum cumulative decoded image pixels. Default: 100 megapixels. */
105
+ maxImagePixels?: number;
88
106
  /**
89
107
  * Hint for the body font size used in the PDF (in points).
90
108
  * Text items larger than this are considered headings.
package/dist/pdf/index.js CHANGED
@@ -5,8 +5,8 @@ import {
5
5
  pdfToContainer,
6
6
  pdfToDoc,
7
7
  pdfToMarkdownDoc
8
- } from "../chunk-GVS2XXV6.js";
9
- import "../chunk-SSUPBUF5.js";
8
+ } from "../chunk-PJXJI2LY.js";
9
+ import "../chunk-IIQYS2YH.js";
10
10
  export {
11
11
  configurePdfWorker,
12
12
  docToPdf,
@@ -15,4 +15,3 @@ export {
15
15
  pdfToDoc,
16
16
  pdfToMarkdownDoc
17
17
  };
18
- //# sourceMappingURL=index.js.map
@@ -1,9 +1,9 @@
1
- import { a as PptxImportOptions } from '../import-K8mfc0fz.js';
2
- export { P as PptxExportOptions, d as docToPptx, m as markdownDocToPptx, b as pptxToContainer, p as pptxToMarkdownDoc } from '../import-K8mfc0fz.js';
1
+ import { a as PptxImportOptions } from '../import-C3htUTss.js';
2
+ export { P as PptxExportOptions, d as docToPptx, m as markdownDocToPptx, b as pptxToContainer, p as pptxToMarkdownDoc } from '../import-C3htUTss.js';
3
3
  import { Doc } from '@bendyline/squisq/schemas';
4
- export { A as AnalyzePptxLayoutsOptions, a as AnalyzedLayout, E as ExtractedPlaceholder, b as ExtractedSlideLayout, I as InspectPptxLayoutsOptions, L as LayoutVerdict, P as PptxColorHints, c as PptxLayoutInference, d as PptxLayoutSummary, e as analyzePptxLayouts, i as inspectPptxLayouts } from '../layouts-BHrgZ5FS.js';
4
+ export { A as AnalyzePptxLayoutsOptions, a as AnalyzedLayout, E as ExtractedPlaceholder, b as ExtractedSlideLayout, I as InspectPptxLayoutsOptions, L as LayoutVerdict, P as PptxColorHints, c as PptxLayoutInference, d as PptxLayoutSummary, e as analyzePptxLayouts, i as inspectPptxLayouts } from '../layouts-CTdPlB-u.js';
5
5
  import '@bendyline/squisq/markdown';
6
- import '../reader-B9L8Ucbj.js';
6
+ import '../reader-B_m1aKZC.js';
7
7
  import '../zipLimits-BOKCB7qk.js';
8
8
  import '@bendyline/squisq/storage';
9
9
 
@@ -4,21 +4,20 @@ import {
4
4
  pptxToContainer,
5
5
  pptxToDoc,
6
6
  pptxToMarkdownDoc
7
- } from "../chunk-RLU7UFYU.js";
7
+ } from "../chunk-IPN56VLW.js";
8
8
  import {
9
9
  analyzePptxLayouts,
10
10
  inspectPptxLayouts
11
- } from "../chunk-QFLDYKCR.js";
12
- import "../chunk-6M7Z25LA.js";
13
- import "../chunk-PN52A5AA.js";
14
- import "../chunk-YRT7GQ5Y.js";
15
- import "../chunk-KURGXM4I.js";
16
- import "../chunk-U4MRIFKL.js";
17
- import "../chunk-7ARKUCQT.js";
18
- import "../chunk-FE6OJV6O.js";
19
- import "../chunk-SSUPBUF5.js";
20
- import "../chunk-MLX2BOJC.js";
21
- import "../chunk-O3GVVND4.js";
11
+ } from "../chunk-TAAENIRB.js";
12
+ import "../chunk-GX7RAUME.js";
13
+ import "../chunk-SBUW7NHR.js";
14
+ import "../chunk-4V3KCHAP.js";
15
+ import "../chunk-JU2RHXUB.js";
16
+ import "../chunk-X2DEAXNK.js";
17
+ import "../chunk-7AWFHP5U.js";
18
+ import "../chunk-IIQYS2YH.js";
19
+ import "../chunk-6RQOV3B3.js";
20
+ import "../chunk-AONELFLA.js";
22
21
  export {
23
22
  analyzePptxLayouts,
24
23
  docToPptx,
@@ -28,4 +27,3 @@ export {
28
27
  pptxToDoc,
29
28
  pptxToMarkdownDoc
30
29
  };
31
- //# sourceMappingURL=index.js.map
@@ -104,6 +104,35 @@ type OoxmlOpenOptions = ZipSafetyLimits;
104
104
  * @returns A parsed OoxmlPackage
105
105
  */
106
106
  declare function openPackage(data: ArrayBuffer | Blob, limits?: OoxmlOpenOptions): Promise<OoxmlPackage>;
107
+ /**
108
+ * Resolve a package's main part (the "office document" part).
109
+ *
110
+ * Per OPC (ECMA-376 Part 2), the main part is whatever the **root**
111
+ * `officeDocument` relationship targets — the conventional paths
112
+ * (`word/document.xml`, `xl/workbook.xml`, `ppt/presentation.xml`) are a
113
+ * convention, not a rule. Real generators (and some Office save paths) emit
114
+ * e.g. `word/document2.xml`; reading the conventional path literally imports
115
+ * such a package as an empty document with no error.
116
+ *
117
+ * Resolution order:
118
+ * 1. The root `officeDocument` relationship target, when that part exists.
119
+ * 2. The conventional path, when it exists (covers packages with a missing
120
+ * or malformed root relationship).
121
+ * 3. `null` — no main part; callers must fail loudly rather than return empty.
122
+ *
123
+ * @param pkg - The opened package.
124
+ * @param conventionalPath - The format's by-convention main part path.
125
+ * @returns The resolved part path within the archive, or `null` if absent.
126
+ */
127
+ declare function resolveMainPartPath(pkg: OoxmlPackage, conventionalPath: string): string | null;
128
+ /**
129
+ * Like {@link resolveMainPartPath}, but throws when no main part exists.
130
+ *
131
+ * @param pkg - The opened package.
132
+ * @param conventionalPath - The format's by-convention main part path.
133
+ * @param formatLabel - Human-readable format name for the error message.
134
+ */
135
+ declare function requireMainPartPath(pkg: OoxmlPackage, conventionalPath: string, formatLabel: string): string;
107
136
  /**
108
137
  * Parse relationships for a specific part.
109
138
  *
@@ -137,4 +166,4 @@ declare function getPartBinary(pkg: OoxmlPackage, partPath: string): Promise<Arr
137
166
  */
138
167
  declare function getCoreProperties(pkg: OoxmlPackage): Promise<CoreProperties>;
139
168
 
140
- export { type CoreProperties as C, type OoxmlOpenOptions as O, type PackagePart as P, type Relationship as R, type OoxmlPackage as a, type ContentTypeMap as b, type PendingRelationship as c, getPartBinary as d, getPartRelationships as e, getPartXml as f, getCoreProperties as g, openPackage as o };
169
+ export { type CoreProperties as C, type OoxmlOpenOptions as O, type PackagePart as P, type Relationship as R, type OoxmlPackage as a, type ContentTypeMap as b, type PendingRelationship as c, getPartBinary as d, getPartRelationships as e, getPartXml as f, getCoreProperties as g, resolveMainPartPath as h, openPackage as o, requireMainPartPath as r };
@@ -3,15 +3,29 @@ import { TransformStyleInput, TransformStyleRegistry } from '@bendyline/squisq/t
3
3
  import { ParseOptions, StringifyOptions, MarkdownDocument } from '@bendyline/squisq/markdown';
4
4
  import { ContentContainer } from '@bendyline/squisq/storage';
5
5
  import { DocxImportOptions, DocxExportOptions } from '../docx/index.js';
6
- import { a as PptxImportOptions, P as PptxExportOptions } from '../import-K8mfc0fz.js';
7
- import { a as XlsxImportOptions, X as XlsxExportOptions } from '../export-D2NkylDT.js';
6
+ import { a as PptxImportOptions, P as PptxExportOptions } from '../import-C3htUTss.js';
7
+ import { a as XlsxImportOptions, X as XlsxExportOptions } from '../export-D9msROJS.js';
8
8
  import { CsvImportOptions, CsvExportOptions } from '../csv/index.js';
9
9
  import { PdfImportOptions, PdfExportOptions } from '../pdf/index.js';
10
- import { a as HtmlImportOptions, H as HtmlExportOptions } from '../import-DTkDxHmZ.js';
10
+ import { a as HtmlImportOptions, H as HtmlExportOptions } from '../import-C8whCC7_.js';
11
11
  import { EpubExportOptions } from '../epub/index.js';
12
12
  import { ContainerToZipOptions } from '../container/index.js';
13
13
  import { c as ZipSafetyLimits } from '../zipLimits-BOKCB7qk.js';
14
- import '../reader-B9L8Ucbj.js';
14
+ import '../reader-B_m1aKZC.js';
15
+
16
+ interface ConversionLimits {
17
+ maxInputBytes: number;
18
+ maxMarkdownBytes: number;
19
+ maxMarkdownNodes: number;
20
+ maxMarkdownDepth: number;
21
+ maxTableCells: number;
22
+ maxBlocks: number;
23
+ maxBlockDepth: number;
24
+ maxDurationSeconds: number;
25
+ maxAudioSegments: number;
26
+ }
27
+ declare const DEFAULT_CONVERSION_LIMITS: Readonly<ConversionLimits>;
28
+ declare function resolveConversionLimits(limits?: Partial<ConversionLimits>): ConversionLimits;
15
29
 
16
30
  /**
17
31
  * Format registry — shared types.
@@ -77,6 +91,8 @@ interface NormalizedInput {
77
91
  interface ConvertOptions {
78
92
  /** Cancel normalization, transformation, or export at the next bounded work boundary. */
79
93
  signal?: AbortSignal;
94
+ /** Cross-format safety limits. Pass false only for explicitly trusted input. */
95
+ limits?: Partial<ConversionLimits> | false;
80
96
  /** Registry to resolve formats against. Defaults to `defaultRegistry()`. */
81
97
  registry?: FormatRegistry;
82
98
  /** Explicit source format id (skips extension/byte sniffing). */
@@ -216,4 +232,4 @@ declare function prepareConversion(source: ConvertSource, options?: ConvertOptio
216
232
  */
217
233
  declare function convert(source: ConvertSource, to: FormatId, options?: ConvertOptions): Promise<ConversionResult>;
218
234
 
219
- export { BUILTIN_FORMAT_IDS, type BuiltinFormatOptions, ConversionError, type ConversionErrorCode, type ConversionErrorOptions, type ConversionResult, type ConvertOptions, type ConvertSource, type DbkFormatOptions, type FormatDefinition, type FormatId, type FormatRegistry, type MarkdownFormatOptions, type NormalizedInput, type PreparedConversion, type PreparedExportOptions, convert, createRegistry, defaultFormats, defaultRegistry, prepareConversion };
235
+ export { BUILTIN_FORMAT_IDS, type BuiltinFormatOptions, ConversionError, type ConversionErrorCode, type ConversionErrorOptions, type ConversionLimits, type ConversionResult, type ConvertOptions, type ConvertSource, DEFAULT_CONVERSION_LIMITS, type DbkFormatOptions, type FormatDefinition, type FormatId, type FormatRegistry, type MarkdownFormatOptions, type NormalizedInput, type PreparedConversion, type PreparedExportOptions, convert, createRegistry, defaultFormats, defaultRegistry, prepareConversion, resolveConversionLimits };
@@ -1,22 +1,25 @@
1
1
  import {
2
2
  BUILTIN_FORMAT_IDS,
3
+ DEFAULT_CONVERSION_LIMITS,
3
4
  convert,
4
5
  createRegistry,
5
6
  defaultFormats,
6
7
  defaultRegistry,
7
- prepareConversion
8
- } from "../chunk-WQSHGBLN.js";
8
+ prepareConversion,
9
+ resolveConversionLimits
10
+ } from "../chunk-3NKXBZSR.js";
9
11
  import {
10
12
  ConversionError
11
- } from "../chunk-ODL3SSPT.js";
12
- import "../chunk-FE6OJV6O.js";
13
+ } from "../chunk-KXOZMWBS.js";
14
+ import "../chunk-7AWFHP5U.js";
13
15
  export {
14
16
  BUILTIN_FORMAT_IDS,
15
17
  ConversionError,
18
+ DEFAULT_CONVERSION_LIMITS,
16
19
  convert,
17
20
  createRegistry,
18
21
  defaultFormats,
19
22
  defaultRegistry,
20
- prepareConversion
23
+ prepareConversion,
24
+ resolveConversionLimits
21
25
  };
22
- //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { a as OoxmlPackage } from './reader-B9L8Ucbj.js';
1
+ import { a as OoxmlPackage } from './reader-B_m1aKZC.js';
2
2
 
3
3
  /**
4
4
  * OOXML theme reader — parses a `theme1.xml` part (DrawingML `a:theme`)
@@ -1,8 +1,8 @@
1
1
  import { Doc } from '@bendyline/squisq/schemas';
2
- import { a as XlsxImportOptions } from '../export-D2NkylDT.js';
3
- export { X as XlsxExportOptions, d as docToXlsx, m as markdownDocToXlsx, x as xlsxToMarkdownDoc } from '../export-D2NkylDT.js';
2
+ import { a as XlsxImportOptions } from '../export-D9msROJS.js';
3
+ export { X as XlsxExportOptions, d as docToXlsx, m as markdownDocToXlsx, x as xlsxToMarkdownDoc } from '../export-D9msROJS.js';
4
4
  import '@bendyline/squisq/markdown';
5
- import '../reader-B9L8Ucbj.js';
5
+ import '../reader-B_m1aKZC.js';
6
6
  import '../zipLimits-BOKCB7qk.js';
7
7
 
8
8
  /**
@@ -3,16 +3,15 @@ import {
3
3
  markdownDocToXlsx,
4
4
  xlsxToDoc,
5
5
  xlsxToMarkdownDoc
6
- } from "../chunk-UGYF5AZE.js";
7
- import "../chunk-PN52A5AA.js";
8
- import "../chunk-KURGXM4I.js";
9
- import "../chunk-U4MRIFKL.js";
10
- import "../chunk-7ARKUCQT.js";
11
- import "../chunk-FE6OJV6O.js";
6
+ } from "../chunk-OGS5VCGJ.js";
7
+ import "../chunk-SBUW7NHR.js";
8
+ import "../chunk-4V3KCHAP.js";
9
+ import "../chunk-JU2RHXUB.js";
10
+ import "../chunk-X2DEAXNK.js";
11
+ import "../chunk-7AWFHP5U.js";
12
12
  export {
13
13
  docToXlsx,
14
14
  markdownDocToXlsx,
15
15
  xlsxToDoc,
16
16
  xlsxToMarkdownDoc
17
17
  };
18
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/squisq-formats",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Document format converters — DOCX, PDF, OOXML import/export",
5
5
  "license": "MIT",
6
6
  "author": "Bendyline",
@@ -29,7 +29,9 @@
29
29
  "types": "./dist/index.d.ts",
30
30
  "files": [
31
31
  "dist",
32
- "src"
32
+ "!dist/**/*.map",
33
+ "LICENSE",
34
+ "NOTICE.md"
33
35
  ],
34
36
  "exports": {
35
37
  ".": {
@@ -99,8 +101,9 @@
99
101
  "typecheck": "tsc --noEmit"
100
102
  },
101
103
  "dependencies": {
104
+ "@pdf-lib/upng": "1.0.1",
102
105
  "@xmldom/xmldom": "0.9.10",
103
- "@bendyline/squisq": "2.1.0",
106
+ "@bendyline/squisq": "2.2.0",
104
107
  "jszip": "3.10.1",
105
108
  "pdf-lib": "1.17.1",
106
109
  "pdfjs-dist": "4.10.38"
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/epub/export.ts"],"sourcesContent":["/**\n * EPUB 3 Export\n *\n * Converts a MarkdownDocument (or Doc) to an EPUB 3 file (.epub).\n *\n * An EPUB is a ZIP archive containing XHTML chapter files, images,\n * a package manifest (content.opf), and a navigation document (toc.xhtml).\n * Content is split into chapters at H1/H2 heading boundaries.\n *\n * Uses JSZip for packaging (already a dependency), escapeXml from the\n * OOXML utils, and image utilities from the HTML exporter.\n *\n * @example\n * ```ts\n * import { markdownDocToEpub } from '@bendyline/squisq-formats/epub';\n *\n * const epub = await markdownDocToEpub(markdownDoc, {\n * title: 'My Book',\n * author: 'Jane Doe',\n * });\n * ```\n */\n\nimport JSZip from 'jszip';\nimport type { Doc, AudioSegment, ThemeRegistry } from '@bendyline/squisq/schemas';\nimport { resolveFontFamily } from '@bendyline/squisq/schemas';\nimport { resolveThemeForDoc } from '@bendyline/squisq/doc';\nimport type {\n MarkdownDocument,\n MarkdownBlockNode,\n MarkdownInlineNode,\n MarkdownHeading,\n MarkdownParagraph,\n MarkdownListItem,\n MarkdownTable,\n MarkdownTableRow,\n MarkdownTableCell,\n} from '@bendyline/squisq/markdown';\nimport { readFrontmatterThemeId, sanitizeUrl } from '@bendyline/squisq/markdown';\nimport { escapeXml } from '../ooxml/xmlUtils.js';\nimport { inferMimeType, extractFilename } from '../html/imageUtils.js';\nimport { extractPlainText } from '../shared/text.js';\n\n// ── Public API ────────────────────────────────────────────────────\n\nexport interface EpubExportOptions {\n /** Book title (default: 'Untitled') */\n title?: string;\n /** Author name */\n author?: string;\n /** Book description / summary */\n description?: string;\n /** BCP-47 language code (default: 'en') */\n language?: string;\n /** Publisher name */\n publisher?: string;\n /** Squisq theme ID for CSS styling */\n themeId?: string;\n /** Explicit caller-owned registry for non-document custom themes. */\n themeRegistry?: ThemeRegistry;\n /** Pre-resolved image data keyed by relative path as it appears in the markdown */\n images?: Map<string, ArrayBuffer>;\n /** Cover image data (JPEG or PNG) */\n coverImage?: ArrayBuffer;\n /**\n * Audio narration data keyed by segment src/name.\n * When provided alongside audioSegments, EPUB 3 Media Overlays (SMIL)\n * are generated for synchronized audio playback.\n */\n audio?: Map<string, ArrayBuffer>;\n /**\n * Audio segment metadata (from Doc.audio.segments).\n * Required together with `audio` to generate Media Overlays.\n * Each segment's duration and startTime are used to build SMIL timing.\n */\n audioSegments?: AudioSegment[];\n /** Total document duration in seconds (used for Media Overlay metadata) */\n totalDuration?: number;\n}\n\n/**\n * Convert a MarkdownDocument to an EPUB 3 file.\n *\n * Chapters are split at H1/H2 heading boundaries. All referenced images\n * (provided via `options.images`) are embedded in the archive.\n */\nexport async function markdownDocToEpub(\n doc: MarkdownDocument,\n options: EpubExportOptions = {},\n): Promise<ArrayBuffer> {\n const fmTitle = doc.frontmatter?.title;\n const fmAuthor = doc.frontmatter?.author;\n const title = options.title ?? (typeof fmTitle === 'string' ? fmTitle : 'Untitled');\n const author = options.author ?? (typeof fmAuthor === 'string' ? fmAuthor : '');\n const language = options.language ?? 'en';\n const description = options.description ?? '';\n const publisher = options.publisher ?? '';\n const uuid = createEpubUuid();\n\n // Split document into chapters\n const chapters = splitIntoChapters(doc.children);\n\n // Collect images referenced in the document, deduplicating filenames\n const imageEntries = collectDocImages(doc.children);\n const resolvedImages = new Map<string, { data: ArrayBuffer; mime: string; filename: string }>();\n const usedImageNames = new Set<string>();\n if (options.images) {\n for (const src of imageEntries) {\n const data = options.images.get(src);\n if (data) {\n const filename = uniqueFilename(safeArchiveBasename(src, 'image'), usedImageNames);\n usedImageNames.add(filename);\n resolvedImages.set(src, { data, mime: inferMimeType(filename), filename });\n }\n }\n }\n\n // Generate theme CSS — honor an explicit themeId, else the doc's frontmatter\n // theme (`squisq-theme` / legacy), mirroring the other export formats.\n const css = generateStylesheet(\n options.themeId ?? readFrontmatterThemeId(doc.frontmatter),\n doc,\n options.themeRegistry,\n );\n\n // Build the ZIP\n const zip = new JSZip();\n\n // mimetype must be first entry, stored (not compressed)\n zip.file('mimetype', 'application/epub+zip', { compression: 'STORE' });\n\n // META-INF/container.xml\n zip.file('META-INF/container.xml', CONTAINER_XML);\n\n // OEBPS/styles.css\n zip.file('OEBPS/styles.css', css);\n\n // OEBPS/images/*\n for (const [, img] of resolvedImages) {\n zip.file(`OEBPS/images/${img.filename}`, img.data);\n }\n\n // Cover image — detect PNG vs JPEG from magic bytes.\n // When provided, generates a cover.xhtml page in the spine so e-readers\n // (especially Kindle) display the cover as both thumbnail and first page.\n let coverFilename: string | undefined;\n if (options.coverImage) {\n const bytes = new Uint8Array(options.coverImage);\n const isPng =\n bytes.length >= 4 &&\n bytes[0] === 0x89 &&\n bytes[1] === 0x50 &&\n bytes[2] === 0x4e &&\n bytes[3] === 0x47;\n coverFilename = uniqueFilename(isPng ? 'cover.png' : 'cover.jpg', usedImageNames);\n usedImageNames.add(coverFilename);\n zip.file(`OEBPS/images/${coverFilename}`, options.coverImage);\n\n // Generate cover XHTML page — full-bleed image, no margins\n const coverXhtml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n<head>\n <meta charset=\"UTF-8\"/>\n <title>Cover</title>\n <style>\n body { margin: 0; padding: 0; text-align: center; }\n img { max-width: 100%; max-height: 100%; }\n </style>\n</head>\n<body>\n <img src=\"../images/${escapeXml(coverFilename)}\" alt=\"Cover\"/>\n</body>\n</html>`;\n zip.file('OEBPS/chapters/cover.xhtml', coverXhtml);\n }\n\n // ── Audio narration ──────────────────────────────────────────────\n const audioMap = options.audio;\n const audioSegments = options.audioSegments;\n const hasAudio = audioMap && audioSegments && audioSegments.length > 0;\n // Per-segment audio file info, indexed by segment index (null if data missing)\n const segmentAudioFiles: ({ filename: string; mime: string } | null)[] = [];\n const allAudioFiles: { filename: string; mime: string }[] = [];\n const audioFilenameBySource = new Map<string, string>();\n const usedAudioFilenames = new Set<string>();\n\n if (hasAudio) {\n for (const seg of audioSegments) {\n const data = audioMap.get(seg.src) ?? audioMap.get(seg.name);\n if (data) {\n const sourceKey = seg.src || seg.name;\n let finalName = audioFilenameBySource.get(sourceKey);\n let isNewFile = false;\n if (!finalName) {\n const basename = safeArchiveBasename(sourceKey || 'narration', 'narration');\n const withExtension = basename.includes('.') ? basename : `${basename}.mp3`;\n finalName = uniqueFilename(withExtension, usedAudioFilenames);\n audioFilenameBySource.set(sourceKey, finalName);\n usedAudioFilenames.add(finalName);\n zip.file(`OEBPS/audio/${finalName}`, data);\n isNewFile = true;\n }\n const info = { filename: finalName, mime: inferMimeType(finalName) };\n segmentAudioFiles.push(info);\n if (isNewFile) allAudioFiles.push(info);\n } else {\n segmentAudioFiles.push(null);\n }\n }\n }\n\n // Build chapter-to-audio mapping for SMIL overlays\n const chapterAudio: (ChapterAudioInfo | null)[] = [];\n if (hasAudio && allAudioFiles.length > 0) {\n if (chapters.length !== audioSegments.length) {\n console.warn(\n `EPUB: ${chapters.length} chapters but ${audioSegments.length} audio segments — ` +\n `extra chapters will reuse the last segment's audio`,\n );\n }\n for (let i = 0; i < chapters.length; i++) {\n const segIdx = Math.min(i, audioSegments.length - 1);\n const seg = audioSegments[segIdx];\n const audioFile = segmentAudioFiles[segIdx];\n if (audioFile) {\n chapterAudio.push({\n audioFilename: audioFile.filename,\n clipStart: 0,\n clipEnd: seg.duration,\n duration: seg.duration,\n });\n } else {\n chapterAudio.push(null);\n }\n }\n }\n\n // OEBPS/chapters/*.xhtml + optional SMIL overlays\n const chapterFiles: ChapterFileInfo[] = [];\n for (let i = 0; i < chapters.length; i++) {\n const chap = chapters[i];\n const num = String(i + 1).padStart(3, '0');\n const id = `chapter-${num}`;\n const filename = `${id}.xhtml`;\n const audioInfo = chapterAudio[i] ?? null;\n\n // Render XHTML with element IDs for SMIL references when audio is present\n const xhtml = renderChapterXhtml(chap.nodes, title, resolvedImages, audioInfo !== null);\n zip.file(`OEBPS/chapters/${filename}`, xhtml);\n\n let smilFilename: string | undefined;\n if (audioInfo) {\n smilFilename = `${id}.smil`;\n const smil = generateSmil(filename, audioInfo, chap.nodes);\n zip.file(`OEBPS/chapters/${smilFilename}`, smil);\n }\n\n chapterFiles.push({\n id,\n filename,\n title: chap.title,\n smilFilename,\n duration: audioInfo?.duration,\n });\n }\n\n // OEBPS/toc.xhtml (EPUB 3 nav)\n zip.file('OEBPS/toc.xhtml', generateTocXhtml(chapterFiles, title));\n\n // OEBPS/content.opf\n zip.file(\n 'OEBPS/content.opf',\n generateContentOpf({\n uuid,\n title,\n author,\n language,\n description,\n publisher,\n chapters: chapterFiles,\n images: resolvedImages,\n coverFilename,\n audioFiles: allAudioFiles,\n totalDuration: options.totalDuration,\n }),\n );\n\n const blob = await zip.generateAsync({\n type: 'arraybuffer',\n compression: 'DEFLATE',\n compressionOptions: { level: 6 },\n // mimetype was already set to STORE above; JSZip respects per-file options\n });\n\n return blob;\n}\n\n/**\n * Convert a squisq Doc to an EPUB 3 file.\n *\n * Convenience wrapper: Doc → MarkdownDocument → EPUB.\n * When the Doc has audio segments and `options.audio` is provided,\n * EPUB 3 Media Overlays are generated for narrated playback.\n */\nexport async function docToEpub(doc: Doc, options: EpubExportOptions = {}): Promise<ArrayBuffer> {\n const { docToMarkdown } = await import('@bendyline/squisq/doc');\n const markdownDoc = docToMarkdown(doc);\n\n // Thread audio segment metadata from the Doc into options\n const epubOptions: EpubExportOptions = { ...options };\n if (doc.audio?.segments?.length && !epubOptions.audioSegments) {\n epubOptions.audioSegments = doc.audio.segments;\n }\n if (doc.duration && !epubOptions.totalDuration) {\n epubOptions.totalDuration = doc.duration;\n }\n\n return markdownDocToEpub(markdownDoc, epubOptions);\n}\n\n// ── Chapter Splitting ─────────────────────────────────────────────\n\ninterface Chapter {\n title: string;\n nodes: MarkdownBlockNode[];\n}\n\ninterface ChapterFileInfo {\n id: string;\n filename: string;\n title: string;\n smilFilename?: string;\n duration?: number;\n}\n\ninterface ChapterAudioInfo {\n audioFilename: string;\n clipStart: number;\n clipEnd: number;\n duration: number;\n}\n\nfunction splitIntoChapters(nodes: MarkdownBlockNode[]): Chapter[] {\n const chapters: Chapter[] = [];\n let currentNodes: MarkdownBlockNode[] = [];\n let currentTitle = 'Untitled';\n\n for (const node of nodes) {\n if (node.type === 'heading' && node.depth <= 2) {\n // Flush previous chapter\n if (currentNodes.length > 0) {\n chapters.push({ title: currentTitle, nodes: currentNodes });\n }\n currentTitle = extractHeadingText(node);\n currentNodes = [node];\n } else {\n currentNodes.push(node);\n }\n }\n\n // Flush remaining\n if (currentNodes.length > 0) {\n chapters.push({ title: currentTitle, nodes: currentNodes });\n }\n\n // If no chapters were created, wrap everything as one\n if (chapters.length === 0) {\n chapters.push({ title: 'Untitled', nodes: [] });\n }\n\n return chapters;\n}\n\nfunction extractHeadingText(heading: MarkdownHeading): string {\n return extractPlainText(heading.children);\n}\n\n// ── Image Collection ──────────────────────────────────────────────\n\nfunction collectDocImages(nodes: MarkdownBlockNode[]): Set<string> {\n const images = new Set<string>();\n\n function walkBlock(node: MarkdownBlockNode): void {\n switch (node.type) {\n case 'paragraph':\n case 'heading':\n node.children.forEach(walkInline);\n break;\n case 'blockquote':\n node.children.forEach(walkBlock);\n break;\n case 'list':\n node.children.forEach((item) => item.children.forEach(walkBlock));\n break;\n case 'table':\n node.children.forEach((row) =>\n row.children.forEach((cell) => cell.children.forEach(walkInline)),\n );\n break;\n default:\n break;\n }\n }\n\n function walkInline(node: MarkdownInlineNode): void {\n if (node.type === 'image' && node.url && !node.url.startsWith('data:')) {\n images.add(node.url);\n }\n if ('children' in node && Array.isArray(node.children)) {\n (node.children as MarkdownInlineNode[]).forEach(walkInline);\n }\n }\n\n nodes.forEach(walkBlock);\n return images;\n}\n\n// ── XHTML Rendering ───────────────────────────────────────────────\n\ntype ImageMap = Map<string, { data: ArrayBuffer; mime: string; filename: string }>;\n\nfunction renderChapterXhtml(\n nodes: MarkdownBlockNode[],\n bookTitle: string,\n images: ImageMap,\n addIds = false,\n): string {\n let elementCounter = 0;\n const nextId = () => `p${++elementCounter}`;\n const body = nodes.map((n) => blockToXhtml(n, images, addIds ? nextId : undefined)).join('\\n');\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n<head>\n <meta charset=\"UTF-8\"/>\n <title>${escapeXml(bookTitle)}</title>\n <link rel=\"stylesheet\" type=\"text/css\" href=\"../styles.css\"/>\n</head>\n<body>\n${body}\n</body>\n</html>`;\n}\n\nfunction blockToXhtml(node: MarkdownBlockNode, images: ImageMap, nextId?: () => string): string {\n const idAttr = nextId ? ` id=\"${nextId()}\"` : '';\n\n switch (node.type) {\n case 'heading': {\n const tag = `h${node.depth}`;\n return `<${tag}${idAttr}>${inlinesToXhtml(node.children, images)}</${tag}>`;\n }\n\n case 'paragraph':\n return `<p${idAttr}>${inlinesToXhtml(node.children, images)}</p>`;\n\n case 'blockquote':\n return `<blockquote${idAttr}>\\n${node.children.map((c) => blockToXhtml(c, images, nextId)).join('\\n')}\\n</blockquote>`;\n\n case 'list': {\n const tag = node.ordered ? 'ol' : 'ul';\n const startAttr =\n node.ordered && node.start && node.start !== 1 ? ` start=\"${node.start}\"` : '';\n const items = node.children.map((item) => listItemToXhtml(item, images)).join('\\n');\n return `<${tag}${idAttr}${startAttr}>\\n${items}\\n</${tag}>`;\n }\n\n case 'code': {\n const langAttr = node.lang ? ` class=\"language-${escapeXml(node.lang)}\"` : '';\n return `<pre${idAttr}><code${langAttr}>${escapeXml(node.value)}</code></pre>`;\n }\n\n case 'thematicBreak':\n return `<hr${idAttr}/>`;\n\n case 'table':\n return tableToXhtml(node as MarkdownTable, images, idAttr);\n\n case 'htmlBlock':\n // Strip HTML tags for XHTML safety — raw HTML may not be well-formed XML\n return `<p${idAttr}>${escapeXml(node.rawHtml.replace(/<[^>]+>/g, ''))}</p>`;\n\n case 'math':\n return `<p${idAttr} class=\"math\">${escapeXml(node.value)}</p>`;\n\n default:\n return '';\n }\n}\n\nfunction listItemToXhtml(item: MarkdownListItem, images: ImageMap): string {\n const content = item.children.map((c) => blockToXhtml(c, images)).join('\\n');\n // Unwrap single <p> inside <li> for cleaner output\n const unwrapped =\n item.children.length === 1 && item.children[0].type === 'paragraph'\n ? inlinesToXhtml((item.children[0] as MarkdownParagraph).children, images)\n : content;\n return `<li>${unwrapped}</li>`;\n}\n\nfunction tableToXhtml(table: MarkdownTable, images: ImageMap, idAttr = ''): string {\n const rows = table.children;\n if (rows.length === 0) return `<table${idAttr}></table>`;\n\n const headerRow = rows[0];\n const bodyRows = rows.slice(1);\n const align = table.align ?? [];\n\n function cellToXhtml(cell: MarkdownTableCell, tag: 'th' | 'td', colIndex: number): string {\n const a = align[colIndex];\n const style = a ? ` style=\"text-align: ${a}\"` : '';\n return `<${tag}${style}>${inlinesToXhtml(cell.children, images)}</${tag}>`;\n }\n\n const thead = `<thead><tr>${headerRow.children.map((c, i) => cellToXhtml(c, 'th', i)).join('')}</tr></thead>`;\n const tbody =\n bodyRows.length > 0\n ? `<tbody>${bodyRows.map((row: MarkdownTableRow) => `<tr>${row.children.map((c, i) => cellToXhtml(c, 'td', i)).join('')}</tr>`).join('')}</tbody>`\n : '';\n\n return `<table${idAttr}>${thead}${tbody}</table>`;\n}\n\nfunction inlinesToXhtml(nodes: MarkdownInlineNode[], images: ImageMap): string {\n return nodes.map((n) => inlineToXhtml(n, images)).join('');\n}\n\nfunction inlineToXhtml(node: MarkdownInlineNode, images: ImageMap): string {\n switch (node.type) {\n case 'text':\n return escapeXml(node.value);\n\n case 'strong':\n return `<strong>${inlinesToXhtml(node.children, images)}</strong>`;\n\n case 'emphasis':\n return `<em>${inlinesToXhtml(node.children, images)}</em>`;\n\n case 'delete':\n return `<del>${inlinesToXhtml(node.children, images)}</del>`;\n\n case 'inlineCode':\n return `<code>${escapeXml(node.value)}</code>`;\n\n case 'link': {\n const href = sanitizeUrl(node.url, 'link');\n if (!href) return inlinesToXhtml(node.children, images);\n const titleAttr = node.title ? ` title=\"${escapeXml(node.title)}\"` : '';\n return `<a href=\"${escapeXml(href)}\"${titleAttr}>${inlinesToXhtml(node.children, images)}</a>`;\n }\n\n case 'image': {\n const alt = escapeXml(node.alt ?? '');\n const resolved = images.get(node.url);\n const safeSrc = resolved ? `../images/${resolved.filename}` : sanitizeUrl(node.url, 'media');\n if (!safeSrc) return alt;\n const src = escapeXml(safeSrc);\n return `<img src=\"${src}\" alt=\"${alt}\"/>`;\n }\n\n case 'break':\n return '<br/>';\n\n case 'inlineMath':\n return `<span class=\"math\">${escapeXml(node.value)}</span>`;\n\n case 'htmlInline':\n // Strip tags for XHTML safety\n return escapeXml(node.rawHtml.replace(/<[^>]+>/g, ''));\n\n default:\n return '';\n }\n}\n\n/**\n * Produce an EPUB identifier without assuming `crypto.randomUUID()` exists.\n * `randomUUID` is unavailable in older/non-secure browser contexts; use\n * `getRandomValues` when possible and retain a non-cryptographic last resort\n * because this UUID is an identifier, not a security token.\n */\nfunction createEpubUuid(): string {\n const webCrypto = globalThis.crypto;\n if (typeof webCrypto?.randomUUID === 'function') return webCrypto.randomUUID();\n\n const bytes = new Uint8Array(16);\n if (typeof webCrypto?.getRandomValues === 'function') {\n webCrypto.getRandomValues(bytes);\n } else {\n let seed = Date.now() ^ Math.floor(Math.random() * 0x7fffffff);\n for (let i = 0; i < bytes.length; i++) {\n seed = Math.imul(seed ^ (seed >>> 15), 1 | seed);\n bytes[i] = seed & 0xff;\n }\n }\n // RFC 4122 version 4 / variant 1 bits.\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\n/** Flatten an external path to a safe archive basename. */\nfunction safeArchiveBasename(path: string, fallback: string): string {\n const filename = extractFilename(path.replace(/\\\\/g, '/'));\n const safe = Array.from(filename, (character) => {\n const codePoint = character.codePointAt(0) ?? 0;\n return character === '\\\\' || character === '/' || codePoint < 0x20 || codePoint === 0x7f\n ? '_'\n : character;\n })\n .join('')\n .trim();\n return !safe || safe === '.' || safe === '..' ? fallback : safe;\n}\n\n/** Return a basename that does not collide with a prior archive member. */\nfunction uniqueFilename(filename: string, used: ReadonlySet<string>): string {\n if (!used.has(filename)) return filename;\n const dot = filename.lastIndexOf('.');\n const base = dot > 0 ? filename.slice(0, dot) : filename;\n const ext = dot > 0 ? filename.slice(dot) : '';\n let suffix = 2;\n while (used.has(`${base}-${suffix}${ext}`)) suffix++;\n return `${base}-${suffix}${ext}`;\n}\n\n// ── SMIL Media Overlays ───────────────────────────────────────────\n\n/**\n * Generate an EPUB 3 Media Overlay (SMIL) file for a chapter.\n * Maps block-level elements to audio clip ranges for synchronized narration.\n */\nfunction generateSmil(\n chapterFilename: string,\n audioInfo: ChapterAudioInfo,\n nodes: MarkdownBlockNode[],\n): string {\n // Count block elements to match the IDs generated by blockToXhtml.\n // Must mirror blockToXhtml's recursion: each block gets an ID,\n // blockquote children recurse (they pass nextId), but list items do not.\n let elementCount = 0;\n function countBlocks(node: MarkdownBlockNode): void {\n elementCount++;\n if (node.type === 'blockquote') node.children.forEach(countBlocks);\n }\n nodes.forEach(countBlocks);\n\n if (elementCount === 0) elementCount = 1;\n\n // Distribute audio duration evenly across elements (best effort without word-level timing)\n const clipDuration = audioInfo.duration / elementCount;\n const pars: string[] = [];\n\n for (let i = 0; i < elementCount; i++) {\n const clipStart = formatTime(audioInfo.clipStart + i * clipDuration, true);\n const clipEnd = formatTime(audioInfo.clipStart + (i + 1) * clipDuration, true);\n pars.push(\n ` <par id=\"par-${i + 1}\">` +\n `\\n <text src=\"${chapterFilename}#p${i + 1}\"/>` +\n `\\n <audio src=\"../audio/${escapeXml(audioInfo.audioFilename)}\" clipBegin=\"${clipStart}\" clipEnd=\"${clipEnd}\"/>` +\n `\\n </par>`,\n );\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<smil xmlns=\"http://www.w3.org/ns/SMIL\" xmlns:epub=\"http://www.idpf.org/2007/ops\" version=\"3.0\">\n <body>\n <seq id=\"seq-1\" epub:textref=\"${chapterFilename}\">\n${pars.join('\\n')}\n </seq>\n </body>\n</smil>`;\n}\n\nfunction formatTime(seconds: number, fractional = false): string {\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = seconds % 60;\n const sPart = fractional ? s.toFixed(3).padStart(6, '0') : String(Math.floor(s)).padStart(2, '0');\n return `${h}:${String(m).padStart(2, '0')}:${sPart}`;\n}\n\n// ── Package Documents ─────────────────────────────────────────────\n\nconst CONTAINER_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\n <rootfiles>\n <rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\"/>\n </rootfiles>\n</container>`;\n\ninterface OpfParams {\n uuid: string;\n title: string;\n author: string;\n language: string;\n description: string;\n publisher: string;\n chapters: ChapterFileInfo[];\n images: ImageMap;\n coverFilename?: string;\n audioFiles?: { filename: string; mime: string }[];\n totalDuration?: number;\n}\n\nfunction generateContentOpf(params: OpfParams): string {\n const {\n uuid,\n title,\n author,\n language,\n description,\n publisher,\n chapters,\n images,\n coverFilename,\n audioFiles,\n totalDuration,\n } = params;\n const modified = new Date().toISOString().replace(/\\.\\d+Z$/, 'Z');\n const hasOverlays = chapters.some((c) => c.smilFilename);\n\n // Manifest items\n const manifestItems: string[] = [\n ' <item id=\"toc\" href=\"toc.xhtml\" media-type=\"application/xhtml+xml\" properties=\"nav\"/>',\n ' <item id=\"css\" href=\"styles.css\" media-type=\"text/css\"/>',\n ];\n\n if (coverFilename) {\n const mime = inferMimeType(coverFilename);\n manifestItems.push(\n ` <item id=\"cover-image\" href=\"images/${escapeXml(coverFilename)}\" media-type=\"${mime}\" properties=\"cover-image\"/>`,\n );\n manifestItems.push(\n ' <item id=\"cover-page\" href=\"chapters/cover.xhtml\" media-type=\"application/xhtml+xml\"/>',\n );\n }\n\n for (const chap of chapters) {\n const overlayAttr = chap.smilFilename ? ` media-overlay=\"${chap.id}-overlay\"` : '';\n manifestItems.push(\n ` <item id=\"${chap.id}\" href=\"chapters/${escapeXml(chap.filename)}\" media-type=\"application/xhtml+xml\"${overlayAttr}/>`,\n );\n if (chap.smilFilename) {\n manifestItems.push(\n ` <item id=\"${chap.id}-overlay\" href=\"chapters/${escapeXml(chap.smilFilename)}\" media-type=\"application/smil+xml\"/>`,\n );\n }\n }\n\n // Audio files in manifest\n if (audioFiles) {\n const usedAudioNames = new Set<string>();\n for (const af of audioFiles) {\n if (usedAudioNames.has(af.filename)) continue;\n usedAudioNames.add(af.filename);\n const audioId = `audio-${af.filename.replace(/[^a-zA-Z0-9]/g, '-')}`;\n manifestItems.push(\n ` <item id=\"${audioId}\" href=\"audio/${escapeXml(af.filename)}\" media-type=\"${af.mime}\"/>`,\n );\n }\n }\n\n const usedFilenames = new Set<string>();\n for (const [, img] of images) {\n if (usedFilenames.has(img.filename)) continue;\n usedFilenames.add(img.filename);\n const imgId = `img-${img.filename.replace(/[^a-zA-Z0-9]/g, '-')}`;\n manifestItems.push(\n ` <item id=\"${imgId}\" href=\"images/${escapeXml(img.filename)}\" media-type=\"${img.mime}\"/>`,\n );\n }\n\n // Spine — cover page first (if present), then chapters\n const spineEntries: string[] = [];\n if (coverFilename) {\n spineEntries.push(' <itemref idref=\"cover-page\"/>');\n }\n for (const chap of chapters) {\n spineEntries.push(` <itemref idref=\"${chap.id}\"/>`);\n }\n const spineItems = spineEntries.join('\\n');\n\n // Metadata\n const metaParts = [\n ` <dc:identifier id=\"uid\">urn:uuid:${uuid}</dc:identifier>`,\n ` <dc:title>${escapeXml(title)}</dc:title>`,\n ` <dc:language>${escapeXml(language)}</dc:language>`,\n ` <meta property=\"dcterms:modified\">${modified}</meta>`,\n ];\n if (author) metaParts.push(` <dc:creator>${escapeXml(author)}</dc:creator>`);\n if (description) metaParts.push(` <dc:description>${escapeXml(description)}</dc:description>`);\n if (publisher) metaParts.push(` <dc:publisher>${escapeXml(publisher)}</dc:publisher>`);\n\n // Media Overlay metadata\n if (hasOverlays && totalDuration) {\n metaParts.push(` <meta property=\"media:duration\">${formatTime(totalDuration)}</meta>`);\n metaParts.push(' <meta property=\"media:active-class\">epub-media-overlay-active</meta>');\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<package xmlns=\"http://www.idpf.org/2007/opf\" version=\"3.0\" unique-identifier=\"uid\">\n <metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n${metaParts.join('\\n')}\n </metadata>\n <manifest>\n${manifestItems.join('\\n')}\n </manifest>\n <spine>\n${spineItems}\n </spine>\n</package>`;\n}\n\nfunction generateTocXhtml(chapters: ChapterFileInfo[], bookTitle: string): string {\n const navItems = chapters\n .map(\n (chap) =>\n ` <li><a href=\"chapters/${escapeXml(chap.filename)}\">${escapeXml(chap.title)}</a></li>`,\n )\n .join('\\n');\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n<head>\n <meta charset=\"UTF-8\"/>\n <title>${escapeXml(bookTitle)}</title>\n <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\"/>\n</head>\n<body>\n <nav epub:type=\"toc\">\n <h1>Table of Contents</h1>\n <ol>\n${navItems}\n </ol>\n </nav>\n</body>\n</html>`;\n}\n\n// ── Stylesheet ────────────────────────────────────────────────────\n\nfunction generateStylesheet(\n themeId: string | undefined,\n doc?: MarkdownDocument,\n registry?: ThemeRegistry,\n): string {\n let themeVars = '';\n if (themeId) {\n const theme = resolveThemeForDoc(doc, themeId, registry);\n themeVars = `\n --epub-bg: ${theme.colors.background};\n --epub-text: ${theme.colors.text};\n --epub-primary: ${theme.colors.primary};\n --epub-heading-font: ${resolveFontFamily(theme.typography.titleFont, 'serif')};\n --epub-body-font: ${resolveFontFamily(theme.typography.bodyFont, 'sans-serif')};`;\n }\n\n return `/* Squisq EPUB Stylesheet */\n:root {${themeVars}\n}\n\nbody {\n font-family: var(--epub-body-font, Georgia, 'Times New Roman', serif);\n color: var(--epub-text, #1a1a1a);\n line-height: 1.7;\n margin: 1em 2em;\n max-width: 40em;\n}\n\nh1, h2, h3, h4, h5, h6 {\n font-family: var(--epub-heading-font, system-ui, sans-serif);\n color: var(--epub-primary, #1a1a1a);\n margin-top: 1.5em;\n margin-bottom: 0.5em;\n line-height: 1.3;\n}\n\nh1 { font-size: 2em; }\nh2 { font-size: 1.5em; }\nh3 { font-size: 1.25em; }\n\np {\n margin: 0.8em 0;\n}\n\na {\n color: var(--epub-primary, #2563eb);\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\npre {\n background: #f5f5f5;\n padding: 1em;\n overflow-x: auto;\n border-radius: 4px;\n font-size: 0.9em;\n line-height: 1.4;\n}\n\ncode {\n font-family: 'Courier New', Courier, monospace;\n font-size: 0.9em;\n}\n\np > code, li > code {\n background: #f0f0f0;\n padding: 0.1em 0.3em;\n border-radius: 3px;\n}\n\nblockquote {\n border-left: 3px solid var(--epub-primary, #d1d5db);\n margin: 1em 0;\n padding: 0.5em 1em;\n color: #4b5563;\n}\n\ntable {\n border-collapse: collapse;\n width: 100%;\n margin: 1em 0;\n}\n\nth, td {\n border: 1px solid #d1d5db;\n padding: 0.5em 0.75em;\n text-align: left;\n}\n\nth {\n background: #f3f4f6;\n font-weight: 600;\n}\n\nhr {\n border: none;\n border-top: 1px solid #d1d5db;\n margin: 2em 0;\n}\n\nul, ol {\n margin: 0.8em 0;\n padding-left: 1.5em;\n}\n\nli {\n margin: 0.3em 0;\n}\n\n.math {\n font-family: 'Courier New', Courier, monospace;\n font-style: italic;\n}\n\n/* Media Overlay active highlight (narration sync) */\n.epub-media-overlay-active {\n background-color: rgba(37, 99, 235, 0.12);\n}\n`;\n}\n"],"mappings":"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","names":[]}
@@ -1,46 +0,0 @@
1
- import {
2
- stripHtmlTags
3
- } from "./chunk-PN52A5AA.js";
4
-
5
- // src/shared/inlineRuns.ts
6
- function inlineNodesToRuns(nodes, handlers, format = {}) {
7
- let out = "";
8
- for (const node of nodes) {
9
- out += inlineNodeToRuns(node, handlers, format);
10
- }
11
- return out;
12
- }
13
- function inlineNodeToRuns(node, handlers, format) {
14
- switch (node.type) {
15
- case "text":
16
- return handlers.run(node.value, format);
17
- case "strong":
18
- return inlineNodesToRuns(node.children, handlers, { ...format, bold: true });
19
- case "emphasis":
20
- return inlineNodesToRuns(node.children, handlers, { ...format, italic: true });
21
- case "delete":
22
- return inlineNodesToRuns(node.children, handlers, { ...format, strike: true });
23
- case "inlineCode":
24
- return handlers.run(node.value, { ...format, code: true });
25
- case "inlineMath":
26
- return handlers.run(node.value, { ...format, code: true });
27
- case "htmlInline":
28
- return handlers.run(stripHtmlTags(node.rawHtml), format);
29
- case "link":
30
- return handlers.link(node, format);
31
- case "image":
32
- return handlers.image(node, format);
33
- case "break":
34
- return handlers.lineBreak();
35
- case "footnoteReference":
36
- return handlers.footnoteRef ? handlers.footnoteRef(node) : "";
37
- default:
38
- return "";
39
- }
40
- }
41
-
42
- export {
43
- inlineNodesToRuns,
44
- inlineNodeToRuns
45
- };
46
- //# sourceMappingURL=chunk-6M7Z25LA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/shared/inlineRuns.ts"],"sourcesContent":["/**\n * Shared inline walker for the \"run-based\" exporters.\n *\n * DOCX (`<w:r>`) and PPTX (`<a:r>`) both render inline markdown by threading an\n * active character-format object DOWN through nested nodes (strong → bold,\n * emphasis → italic, …) and emitting flat styled runs at the leaves — as\n * opposed to the HTML exporters, which WRAP children in tags, or the PDF\n * exporter, which accumulates positioned spans. That control flow is identical\n * between DOCX and PPTX; only the leaf serialization differs.\n *\n * This module owns the traversal once. Each exporter supplies the handful of\n * leaf handlers (`run`, `link`, `image`, `lineBreak`, optional `footnoteRef`)\n * via {@link InlineRunHandlers}. Because the handler interface is typed, adding\n * a new inline node type here forces both exporters to be considered — there's\n * no longer a per-exporter `default:` that can silently drift.\n */\n\nimport type {\n MarkdownInlineNode,\n MarkdownLink,\n MarkdownImage,\n MarkdownFootnoteReference,\n} from '@bendyline/squisq/markdown';\nimport { stripHtmlTags } from './text.js';\n\n/** Active character formatting threaded down through nested inline nodes. */\nexport interface InlineRunFormat {\n bold?: boolean;\n italic?: boolean;\n strike?: boolean;\n code?: boolean;\n /** Explicit run color (hex without `#`); only some exporters use this. */\n color?: string;\n}\n\n/**\n * Per-format leaf handlers. The walker handles the shared format-threading\n * control flow; these turn the leaves into the target dialect's markup.\n */\nexport interface InlineRunHandlers {\n /** Emit a styled text run for `text`, given the active format. */\n run(text: string, format: InlineRunFormat): string;\n /** Emit a hyperlink (the handler manages its own child rendering). */\n link(node: MarkdownLink, format: InlineRunFormat): string;\n /** Emit an inline image. */\n image(node: MarkdownImage, format: InlineRunFormat): string;\n /** Emit a hard line break. */\n lineBreak(): string;\n /** Emit a footnote reference. Omit to drop footnote refs (PPTX). */\n footnoteRef?(node: MarkdownFootnoteReference): string;\n}\n\n/** Walk a list of inline nodes, concatenating each rendered run. */\nexport function inlineNodesToRuns(\n nodes: MarkdownInlineNode[],\n handlers: InlineRunHandlers,\n format: InlineRunFormat = {},\n): string {\n let out = '';\n for (const node of nodes) {\n out += inlineNodeToRuns(node, handlers, format);\n }\n return out;\n}\n\n/** Render a single inline node under the active format. */\nexport function inlineNodeToRuns(\n node: MarkdownInlineNode,\n handlers: InlineRunHandlers,\n format: InlineRunFormat,\n): string {\n switch (node.type) {\n case 'text':\n return handlers.run(node.value, format);\n case 'strong':\n return inlineNodesToRuns(node.children, handlers, { ...format, bold: true });\n case 'emphasis':\n return inlineNodesToRuns(node.children, handlers, { ...format, italic: true });\n case 'delete':\n return inlineNodesToRuns(node.children, handlers, { ...format, strike: true });\n case 'inlineCode':\n return handlers.run(node.value, { ...format, code: true });\n case 'inlineMath':\n return handlers.run(node.value, { ...format, code: true });\n case 'htmlInline':\n return handlers.run(stripHtmlTags(node.rawHtml), format);\n case 'link':\n return handlers.link(node, format);\n case 'image':\n return handlers.image(node, format);\n case 'break':\n return handlers.lineBreak();\n case 'footnoteReference':\n return handlers.footnoteRef ? handlers.footnoteRef(node) : '';\n default:\n // linkReference, imageReference, textDirective, inlineIcon, … — skip.\n return '';\n }\n}\n"],"mappings":";;;;;AAqDO,SAAS,kBACd,OACA,UACA,SAA0B,CAAC,GACnB;AACR,MAAI,MAAM;AACV,aAAW,QAAQ,OAAO;AACxB,WAAO,iBAAiB,MAAM,UAAU,MAAM;AAAA,EAChD;AACA,SAAO;AACT;AAGO,SAAS,iBACd,MACA,UACA,QACQ;AACR,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,SAAS,IAAI,KAAK,OAAO,MAAM;AAAA,IACxC,KAAK;AACH,aAAO,kBAAkB,KAAK,UAAU,UAAU,EAAE,GAAG,QAAQ,MAAM,KAAK,CAAC;AAAA,IAC7E,KAAK;AACH,aAAO,kBAAkB,KAAK,UAAU,UAAU,EAAE,GAAG,QAAQ,QAAQ,KAAK,CAAC;AAAA,IAC/E,KAAK;AACH,aAAO,kBAAkB,KAAK,UAAU,UAAU,EAAE,GAAG,QAAQ,QAAQ,KAAK,CAAC;AAAA,IAC/E,KAAK;AACH,aAAO,SAAS,IAAI,KAAK,OAAO,EAAE,GAAG,QAAQ,MAAM,KAAK,CAAC;AAAA,IAC3D,KAAK;AACH,aAAO,SAAS,IAAI,KAAK,OAAO,EAAE,GAAG,QAAQ,MAAM,KAAK,CAAC;AAAA,IAC3D,KAAK;AACH,aAAO,SAAS,IAAI,cAAc,KAAK,OAAO,GAAG,MAAM;AAAA,IACzD,KAAK;AACH,aAAO,SAAS,KAAK,MAAM,MAAM;AAAA,IACnC,KAAK;AACH,aAAO,SAAS,MAAM,MAAM,MAAM;AAAA,IACpC,KAAK;AACH,aAAO,SAAS,UAAU;AAAA,IAC5B,KAAK;AACH,aAAO,SAAS,cAAc,SAAS,YAAY,IAAI,IAAI;AAAA,IAC7D;AAEE,aAAO;AAAA,EACX;AACF;","names":[]}