postext 0.3.19 → 0.3.21

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 (297) hide show
  1. package/dist/__tests__/columnBalancing.test.js +36 -2
  2. package/dist/__tests__/columnBalancing.test.js.map +1 -1
  3. package/dist/__tests__/defaults/calloutStyles.test.d.ts +2 -0
  4. package/dist/__tests__/defaults/calloutStyles.test.d.ts.map +1 -0
  5. package/dist/__tests__/defaults/calloutStyles.test.js +201 -0
  6. package/dist/__tests__/defaults/calloutStyles.test.js.map +1 -0
  7. package/dist/__tests__/defaults/captionStyle.test.d.ts +2 -0
  8. package/dist/__tests__/defaults/captionStyle.test.d.ts.map +1 -0
  9. package/dist/__tests__/defaults/captionStyle.test.js +87 -0
  10. package/dist/__tests__/defaults/captionStyle.test.js.map +1 -0
  11. package/dist/__tests__/defaults/pageSizePreset.test.d.ts +2 -0
  12. package/dist/__tests__/defaults/pageSizePreset.test.d.ts.map +1 -0
  13. package/dist/__tests__/defaults/pageSizePreset.test.js +24 -0
  14. package/dist/__tests__/defaults/pageSizePreset.test.js.map +1 -0
  15. package/dist/__tests__/defaults/paragraphStyles.test.d.ts +2 -0
  16. package/dist/__tests__/defaults/paragraphStyles.test.d.ts.map +1 -0
  17. package/dist/__tests__/defaults/paragraphStyles.test.js +93 -0
  18. package/dist/__tests__/defaults/paragraphStyles.test.js.map +1 -0
  19. package/dist/__tests__/design/pageAnchors.test.d.ts +2 -0
  20. package/dist/__tests__/design/pageAnchors.test.d.ts.map +1 -0
  21. package/dist/__tests__/design/pageAnchors.test.js +140 -0
  22. package/dist/__tests__/design/pageAnchors.test.js.map +1 -0
  23. package/dist/__tests__/directives.test.js +58 -0
  24. package/dist/__tests__/directives.test.js.map +1 -1
  25. package/dist/__tests__/exports.test.js +19 -0
  26. package/dist/__tests__/exports.test.js.map +1 -1
  27. package/dist/__tests__/mirroredMargins.test.d.ts +2 -0
  28. package/dist/__tests__/mirroredMargins.test.d.ts.map +1 -0
  29. package/dist/__tests__/mirroredMargins.test.js +136 -0
  30. package/dist/__tests__/mirroredMargins.test.js.map +1 -0
  31. package/dist/__tests__/numbering.test.js +54 -0
  32. package/dist/__tests__/numbering.test.js.map +1 -1
  33. package/dist/__tests__/openerTitleSource.test.d.ts +2 -0
  34. package/dist/__tests__/openerTitleSource.test.d.ts.map +1 -0
  35. package/dist/__tests__/openerTitleSource.test.js +108 -0
  36. package/dist/__tests__/openerTitleSource.test.js.map +1 -0
  37. package/dist/__tests__/overStretch.test.d.ts +2 -0
  38. package/dist/__tests__/overStretch.test.d.ts.map +1 -0
  39. package/dist/__tests__/overStretch.test.js +35 -0
  40. package/dist/__tests__/overStretch.test.js.map +1 -0
  41. package/dist/__tests__/pageRoles.test.d.ts +2 -0
  42. package/dist/__tests__/pageRoles.test.d.ts.map +1 -0
  43. package/dist/__tests__/pageRoles.test.js +95 -0
  44. package/dist/__tests__/pageRoles.test.js.map +1 -0
  45. package/dist/__tests__/parse/containers.test.d.ts +2 -0
  46. package/dist/__tests__/parse/containers.test.d.ts.map +1 -0
  47. package/dist/__tests__/parse/containers.test.js +204 -0
  48. package/dist/__tests__/parse/containers.test.js.map +1 -0
  49. package/dist/__tests__/parse/headingAttrs.test.d.ts +2 -0
  50. package/dist/__tests__/parse/headingAttrs.test.d.ts.map +1 -0
  51. package/dist/__tests__/parse/headingAttrs.test.js +62 -0
  52. package/dist/__tests__/parse/headingAttrs.test.js.map +1 -0
  53. package/dist/__tests__/parse/inlineRef.test.js +26 -0
  54. package/dist/__tests__/parse/inlineRef.test.js.map +1 -1
  55. package/dist/__tests__/parts.test.d.ts +2 -0
  56. package/dist/__tests__/parts.test.d.ts.map +1 -0
  57. package/dist/__tests__/parts.test.js +405 -0
  58. package/dist/__tests__/parts.test.js.map +1 -0
  59. package/dist/__tests__/pipeline/calloutLayout.test.d.ts +2 -0
  60. package/dist/__tests__/pipeline/calloutLayout.test.d.ts.map +1 -0
  61. package/dist/__tests__/pipeline/calloutLayout.test.js +273 -0
  62. package/dist/__tests__/pipeline/calloutLayout.test.js.map +1 -0
  63. package/dist/__tests__/pipeline/calloutPlacement.test.d.ts +2 -0
  64. package/dist/__tests__/pipeline/calloutPlacement.test.d.ts.map +1 -0
  65. package/dist/__tests__/pipeline/calloutPlacement.test.js +239 -0
  66. package/dist/__tests__/pipeline/calloutPlacement.test.js.map +1 -0
  67. package/dist/__tests__/pipeline/captionLayout.test.d.ts +2 -0
  68. package/dist/__tests__/pipeline/captionLayout.test.d.ts.map +1 -0
  69. package/dist/__tests__/pipeline/captionLayout.test.js +269 -0
  70. package/dist/__tests__/pipeline/captionLayout.test.js.map +1 -0
  71. package/dist/__tests__/pipeline/inlineRefRender.test.js +53 -0
  72. package/dist/__tests__/pipeline/inlineRefRender.test.js.map +1 -1
  73. package/dist/__tests__/pipeline/orderedSeparator.test.d.ts +2 -0
  74. package/dist/__tests__/pipeline/orderedSeparator.test.d.ts.map +1 -0
  75. package/dist/__tests__/pipeline/orderedSeparator.test.js +196 -0
  76. package/dist/__tests__/pipeline/orderedSeparator.test.js.map +1 -0
  77. package/dist/__tests__/pipeline/paragraphStyles.test.d.ts +2 -0
  78. package/dist/__tests__/pipeline/paragraphStyles.test.d.ts.map +1 -0
  79. package/dist/__tests__/pipeline/paragraphStyles.test.js +172 -0
  80. package/dist/__tests__/pipeline/paragraphStyles.test.js.map +1 -0
  81. package/dist/__tests__/pipeline/spanBands.test.d.ts +2 -0
  82. package/dist/__tests__/pipeline/spanBands.test.d.ts.map +1 -0
  83. package/dist/__tests__/pipeline/spanBands.test.js +303 -0
  84. package/dist/__tests__/pipeline/spanBands.test.js.map +1 -0
  85. package/dist/__tests__/pipeline/spanBlocks.test.d.ts +2 -0
  86. package/dist/__tests__/pipeline/spanBlocks.test.d.ts.map +1 -0
  87. package/dist/__tests__/pipeline/spanBlocks.test.js +407 -0
  88. package/dist/__tests__/pipeline/spanBlocks.test.js.map +1 -0
  89. package/dist/__tests__/placeholders.test.d.ts +2 -0
  90. package/dist/__tests__/placeholders.test.d.ts.map +1 -0
  91. package/dist/__tests__/placeholders.test.js +130 -0
  92. package/dist/__tests__/placeholders.test.js.map +1 -0
  93. package/dist/__tests__/table/model.test.js +24 -0
  94. package/dist/__tests__/table/model.test.js.map +1 -1
  95. package/dist/__tests__/tracking.test.d.ts +2 -0
  96. package/dist/__tests__/tracking.test.d.ts.map +1 -0
  97. package/dist/__tests__/tracking.test.js +37 -0
  98. package/dist/__tests__/tracking.test.js.map +1 -0
  99. package/dist/__tests__/urlBreaks.test.d.ts +2 -0
  100. package/dist/__tests__/urlBreaks.test.d.ts.map +1 -0
  101. package/dist/__tests__/urlBreaks.test.js +57 -0
  102. package/dist/__tests__/urlBreaks.test.js.map +1 -0
  103. package/dist/canvas-backend/blockRender.d.ts.map +1 -1
  104. package/dist/canvas-backend/blockRender.js +20 -1
  105. package/dist/canvas-backend/blockRender.js.map +1 -1
  106. package/dist/canvas-backend/decorations.d.ts +3 -0
  107. package/dist/canvas-backend/decorations.d.ts.map +1 -1
  108. package/dist/canvas-backend/decorations.js +14 -8
  109. package/dist/canvas-backend/decorations.js.map +1 -1
  110. package/dist/canvas-backend/headerFooter.d.ts.map +1 -1
  111. package/dist/canvas-backend/headerFooter.js +23 -0
  112. package/dist/canvas-backend/headerFooter.js.map +1 -1
  113. package/dist/canvas-backend/index.d.ts.map +1 -1
  114. package/dist/canvas-backend/index.js +4 -2
  115. package/dist/canvas-backend/index.js.map +1 -1
  116. package/dist/canvas-backend/renderResourceBlock.d.ts.map +1 -1
  117. package/dist/canvas-backend/renderResourceBlock.js +33 -5
  118. package/dist/canvas-backend/renderResourceBlock.js.map +1 -1
  119. package/dist/columnRule.d.ts +19 -0
  120. package/dist/columnRule.d.ts.map +1 -0
  121. package/dist/columnRule.js +36 -0
  122. package/dist/columnRule.js.map +1 -0
  123. package/dist/defaults/bodyText.js +1 -1
  124. package/dist/defaults/bodyText.js.map +1 -1
  125. package/dist/defaults/calloutStyles.d.ts +61 -0
  126. package/dist/defaults/calloutStyles.d.ts.map +1 -0
  127. package/dist/defaults/calloutStyles.js +292 -0
  128. package/dist/defaults/calloutStyles.js.map +1 -0
  129. package/dist/defaults/captionStyle.d.ts +11 -1
  130. package/dist/defaults/captionStyle.d.ts.map +1 -1
  131. package/dist/defaults/captionStyle.js +127 -2
  132. package/dist/defaults/captionStyle.js.map +1 -1
  133. package/dist/defaults/headerFooter.d.ts.map +1 -1
  134. package/dist/defaults/headerFooter.js +3 -0
  135. package/dist/defaults/headerFooter.js.map +1 -1
  136. package/dist/defaults/headings.d.ts +3 -0
  137. package/dist/defaults/headings.d.ts.map +1 -1
  138. package/dist/defaults/headings.js +33 -6
  139. package/dist/defaults/headings.js.map +1 -1
  140. package/dist/defaults/index.d.ts +4 -1
  141. package/dist/defaults/index.d.ts.map +1 -1
  142. package/dist/defaults/index.js +28 -1
  143. package/dist/defaults/index.js.map +1 -1
  144. package/dist/defaults/orderedLists.d.ts +9 -8
  145. package/dist/defaults/orderedLists.d.ts.map +1 -1
  146. package/dist/defaults/orderedLists.js +66 -4
  147. package/dist/defaults/orderedLists.js.map +1 -1
  148. package/dist/defaults/page.d.ts.map +1 -1
  149. package/dist/defaults/page.js +14 -3
  150. package/dist/defaults/page.js.map +1 -1
  151. package/dist/defaults/paragraphStyles.d.ts +10 -0
  152. package/dist/defaults/paragraphStyles.d.ts.map +1 -0
  153. package/dist/defaults/paragraphStyles.js +67 -0
  154. package/dist/defaults/paragraphStyles.js.map +1 -0
  155. package/dist/defaults/parts.d.ts +22 -0
  156. package/dist/defaults/parts.d.ts.map +1 -0
  157. package/dist/defaults/parts.js +139 -0
  158. package/dist/defaults/parts.js.map +1 -0
  159. package/dist/defaults/shared.d.ts.map +1 -1
  160. package/dist/defaults/shared.js +110 -17
  161. package/dist/defaults/shared.js.map +1 -1
  162. package/dist/defaults/tableStyle.d.ts.map +1 -1
  163. package/dist/defaults/tableStyle.js +6 -0
  164. package/dist/defaults/tableStyle.js.map +1 -1
  165. package/dist/design/layout.d.ts +27 -1
  166. package/dist/design/layout.d.ts.map +1 -1
  167. package/dist/design/layout.js +39 -8
  168. package/dist/design/layout.js.map +1 -1
  169. package/dist/design/placeholders.d.ts +21 -4
  170. package/dist/design/placeholders.d.ts.map +1 -1
  171. package/dist/design/placeholders.js +38 -7
  172. package/dist/design/placeholders.js.map +1 -1
  173. package/dist/html-backend.d.ts.map +1 -1
  174. package/dist/html-backend.js +75 -16
  175. package/dist/html-backend.js.map +1 -1
  176. package/dist/index.d.ts +13 -9
  177. package/dist/index.d.ts.map +1 -1
  178. package/dist/index.js +7 -4
  179. package/dist/index.js.map +1 -1
  180. package/dist/knuthPlass/breakpoints.d.ts.map +1 -1
  181. package/dist/knuthPlass/breakpoints.js +4 -2
  182. package/dist/knuthPlass/breakpoints.js.map +1 -1
  183. package/dist/knuthPlass/constants.d.ts +7 -0
  184. package/dist/knuthPlass/constants.d.ts.map +1 -1
  185. package/dist/knuthPlass/constants.js +7 -0
  186. package/dist/knuthPlass/constants.js.map +1 -1
  187. package/dist/knuthPlass/richAdapter.d.ts +2 -0
  188. package/dist/knuthPlass/richAdapter.d.ts.map +1 -1
  189. package/dist/knuthPlass/richAdapter.js +6 -6
  190. package/dist/knuthPlass/richAdapter.js.map +1 -1
  191. package/dist/measure/cache.js +2 -2
  192. package/dist/measure/cache.js.map +1 -1
  193. package/dist/measure/rich.d.ts +8 -0
  194. package/dist/measure/rich.d.ts.map +1 -1
  195. package/dist/measure/rich.js +54 -10
  196. package/dist/measure/rich.js.map +1 -1
  197. package/dist/measure/types.d.ts +4 -0
  198. package/dist/measure/types.d.ts.map +1 -1
  199. package/dist/measure/types.js.map +1 -1
  200. package/dist/parse/attrs.d.ts +10 -0
  201. package/dist/parse/attrs.d.ts.map +1 -0
  202. package/dist/parse/attrs.js +20 -0
  203. package/dist/parse/attrs.js.map +1 -0
  204. package/dist/parse/blockParser.d.ts +8 -4
  205. package/dist/parse/blockParser.d.ts.map +1 -1
  206. package/dist/parse/blockParser.js +134 -20
  207. package/dist/parse/blockParser.js.map +1 -1
  208. package/dist/parse/index.d.ts +2 -2
  209. package/dist/parse/index.d.ts.map +1 -1
  210. package/dist/parse/index.js +1 -1
  211. package/dist/parse/index.js.map +1 -1
  212. package/dist/parse/inlineFormatting.d.ts +17 -1
  213. package/dist/parse/inlineFormatting.d.ts.map +1 -1
  214. package/dist/parse/inlineFormatting.js +56 -7
  215. package/dist/parse/inlineFormatting.js.map +1 -1
  216. package/dist/parse/sourceMapping.d.ts.map +1 -1
  217. package/dist/parse/sourceMapping.js +13 -1
  218. package/dist/parse/sourceMapping.js.map +1 -1
  219. package/dist/parse/types.d.ts +55 -5
  220. package/dist/parse/types.d.ts.map +1 -1
  221. package/dist/pipeline/bandCaps.d.ts +86 -0
  222. package/dist/pipeline/bandCaps.d.ts.map +1 -0
  223. package/dist/pipeline/bandCaps.js +142 -0
  224. package/dist/pipeline/bandCaps.js.map +1 -0
  225. package/dist/pipeline/build.d.ts +41 -0
  226. package/dist/pipeline/build.d.ts.map +1 -1
  227. package/dist/pipeline/build.js +675 -168
  228. package/dist/pipeline/build.js.map +1 -1
  229. package/dist/pipeline/buildBlockKind.d.ts +8 -0
  230. package/dist/pipeline/buildBlockKind.d.ts.map +1 -1
  231. package/dist/pipeline/buildBlockKind.js +40 -11
  232. package/dist/pipeline/buildBlockKind.js.map +1 -1
  233. package/dist/pipeline/buildHelpers.d.ts +23 -1
  234. package/dist/pipeline/buildHelpers.d.ts.map +1 -1
  235. package/dist/pipeline/buildHelpers.js +50 -6
  236. package/dist/pipeline/buildHelpers.js.map +1 -1
  237. package/dist/pipeline/calloutLayout.d.ts +107 -0
  238. package/dist/pipeline/calloutLayout.d.ts.map +1 -0
  239. package/dist/pipeline/calloutLayout.js +498 -0
  240. package/dist/pipeline/calloutLayout.js.map +1 -0
  241. package/dist/pipeline/columnBalancing.d.ts +26 -8
  242. package/dist/pipeline/columnBalancing.d.ts.map +1 -1
  243. package/dist/pipeline/columnBalancing.js +50 -18
  244. package/dist/pipeline/columnBalancing.js.map +1 -1
  245. package/dist/pipeline/config.d.ts.map +1 -1
  246. package/dist/pipeline/config.js +17 -5
  247. package/dist/pipeline/config.js.map +1 -1
  248. package/dist/pipeline/headerFooter.d.ts +37 -2
  249. package/dist/pipeline/headerFooter.d.ts.map +1 -1
  250. package/dist/pipeline/headerFooter.js +231 -15
  251. package/dist/pipeline/headerFooter.js.map +1 -1
  252. package/dist/pipeline/lists.d.ts +15 -0
  253. package/dist/pipeline/lists.d.ts.map +1 -1
  254. package/dist/pipeline/lists.js +73 -16
  255. package/dist/pipeline/lists.js.map +1 -1
  256. package/dist/pipeline/measureContentBlock.d.ts +65 -0
  257. package/dist/pipeline/measureContentBlock.d.ts.map +1 -0
  258. package/dist/pipeline/measureContentBlock.js +134 -0
  259. package/dist/pipeline/measureContentBlock.js.map +1 -0
  260. package/dist/pipeline/pageRoles.d.ts +23 -0
  261. package/dist/pipeline/pageRoles.d.ts.map +1 -0
  262. package/dist/pipeline/pageRoles.js +54 -0
  263. package/dist/pipeline/pageRoles.js.map +1 -0
  264. package/dist/pipeline/paragraphContainers.d.ts +32 -0
  265. package/dist/pipeline/paragraphContainers.d.ts.map +1 -0
  266. package/dist/pipeline/paragraphContainers.js +61 -0
  267. package/dist/pipeline/paragraphContainers.js.map +1 -0
  268. package/dist/pipeline/parts.d.ts +47 -0
  269. package/dist/pipeline/parts.d.ts.map +1 -0
  270. package/dist/pipeline/parts.js +230 -0
  271. package/dist/pipeline/parts.js.map +1 -0
  272. package/dist/pipeline/placeholders.d.ts +46 -1
  273. package/dist/pipeline/placeholders.d.ts.map +1 -1
  274. package/dist/pipeline/placeholders.js +93 -11
  275. package/dist/pipeline/placeholders.js.map +1 -1
  276. package/dist/pipeline/placement.d.ts +61 -7
  277. package/dist/pipeline/placement.d.ts.map +1 -1
  278. package/dist/pipeline/placement.js +151 -12
  279. package/dist/pipeline/placement.js.map +1 -1
  280. package/dist/pipeline/resourceLayout.d.ts +18 -5
  281. package/dist/pipeline/resourceLayout.d.ts.map +1 -1
  282. package/dist/pipeline/resourceLayout.js +145 -23
  283. package/dist/pipeline/resourceLayout.js.map +1 -1
  284. package/dist/pipeline/styles.d.ts +9 -1
  285. package/dist/pipeline/styles.d.ts.map +1 -1
  286. package/dist/pipeline/styles.js +50 -0
  287. package/dist/pipeline/styles.js.map +1 -1
  288. package/dist/table/model.d.ts.map +1 -1
  289. package/dist/table/model.js +16 -2
  290. package/dist/table/model.js.map +1 -1
  291. package/dist/types.d.ts +468 -2
  292. package/dist/types.d.ts.map +1 -1
  293. package/dist/vdt.d.ts +132 -4
  294. package/dist/vdt.d.ts.map +1 -1
  295. package/dist/vdt.js +2 -1
  296. package/dist/vdt.js.map +1 -1
  297. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"placement.d.ts","sourceRoot":"","sources":["../../src/pipeline/placement.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,SAAS,EACf,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EAAE,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,EAAE,CAMX;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAOT;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,GAAG,SAAS,CAElF;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAClC,IAAI,CAsBN;AAED;;;0BAG0B;AAC1B,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAClC,IAAI,CAQN;AAED;;;;;;;;;;0EAU0E;AAC1E,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,kBAAkB,GACzB,IAAI,CAqCN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,MAAM,CAkBR;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,eAAe,GACtB,IAAI,CAeN"}
1
+ {"version":3,"file":"placement.d.ts","sourceRoot":"","sources":["../../src/pipeline/placement.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  import { createBoundingBox, createVDTPage, createVDTColumn, } from '../vdt';
2
2
  import { computeColumnBboxes } from './config';
3
+ import { contentAreaForPage, mirrorContentArea } from './buildHelpers';
4
+ import { dimensionToPx } from '../units';
3
5
  export function resetLinePositions(lines, lineHeightPx) {
4
6
  return lines.map((line, i) => ({
5
7
  ...line,
@@ -8,16 +10,150 @@ export function resetLinePositions(lines, lineHeightPx) {
8
10
  }));
9
11
  }
10
12
  export function createPageWithColumns(pageIndex, resolved, contentArea, pageWidthPx, pageHeightPx) {
11
- const page = createVDTPage(pageIndex, pageWidthPx, pageHeightPx);
12
- const colBboxes = computeColumnBboxes(contentArea, resolved);
13
+ // `contentArea` is the recto (odd-page) area; mirrored margins swap the
14
+ // inner/outer margins on even pages. `pageIndex` is the page's position in
15
+ // `doc.pages`, so page number = index + 1.
16
+ const pageArea = contentAreaForPage({ contentArea, pageWidthPx }, resolved, pageIndex);
17
+ const page = createVDTPage(pageIndex, pageWidthPx, pageHeightPx, pageArea);
18
+ const colBboxes = computeColumnBboxes(pageArea, resolved);
13
19
  for (let i = 0; i < colBboxes.length; i++) {
14
20
  page.columns.push(createVDTColumn(i, colBboxes[i]));
15
21
  }
16
22
  return page;
17
23
  }
24
+ /** Turn a freshly opened (empty) page into a part-divider page: a single
25
+ * body column inset from the trim box by `parts.margins` (mirrored on even
26
+ * pages when `parts.margins.mirror` is on), `page.contentArea` set to that
27
+ * area, `partInfo` stamped and the role fixed to `'part'`. The opener
28
+ * design is laid out later by `buildHeadersAndFooters` against the full
29
+ * trim box and never reserves body space. */
30
+ export function createPartPage(page, metrics, resolved, info) {
31
+ const dpi = resolved.page.dpi;
32
+ const m = resolved.parts.margins;
33
+ const trim = metrics.trimBox;
34
+ const top = dimensionToPx(m.top, dpi);
35
+ const bottom = dimensionToPx(m.bottom, dpi);
36
+ const left = dimensionToPx(m.left, dpi);
37
+ const right = dimensionToPx(m.right, dpi);
38
+ let area = createBoundingBox(trim.x + left, trim.y + top, Math.max(0, trim.width - left - right), Math.max(0, trim.height - top - bottom));
39
+ const isEvenPage = (page.index + 1) % 2 === 0;
40
+ if (m.mirror && isEvenPage)
41
+ area = mirrorContentArea(area, metrics.pageWidthPx);
42
+ page.contentArea = area;
43
+ page.columns = [createVDTColumn(0, area)];
44
+ page.partInfo = {
45
+ number: info.number,
46
+ title: info.title,
47
+ titleSourceStart: info.titleSourceStart,
48
+ titleSourceEnd: info.titleSourceEnd,
49
+ };
50
+ page.role = 'part';
51
+ return page;
52
+ }
18
53
  export function currentColumn(doc, cursor) {
19
54
  return doc.pages[cursor.pageIndex].columns[cursor.columnIndex];
20
55
  }
56
+ /** Whether any column of the page — text or span — holds a placed block.
57
+ * Floats live outside the columns and do not count. */
58
+ export function pageHasContent(page) {
59
+ return page.columns.some((c) => c.blocks.length > 0);
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // Column bands (page-span blocks, stage 1)
63
+ //
64
+ // `page.columns` stays a flat array in reading order. A page-span inline
65
+ // block occupies its own full-width column (`kind: 'span'`); the text
66
+ // columns of the band it interrupts are closed at the cut line and a fresh
67
+ // band of text columns (`band + 1`) is appended below it with the same
68
+ // x / width and the same bottom as the closed band. Column indices are
69
+ // monotonic — columns are only ever appended — so `block.columnIndex` keeps
70
+ // addressing `page.columns[i]` and renderers need no drawing changes: each
71
+ // column clips to its own bbox.
72
+ // ---------------------------------------------------------------------------
73
+ /** Text columns of `band` in reading order (span columns excluded). */
74
+ export function bandColumns(page, band) {
75
+ return page.columns.filter((c) => c.kind !== 'span' && (c.band ?? 0) === band);
76
+ }
77
+ /** Band the cursor's column belongs to (`0` for the plain single-band page). */
78
+ export function currentBand(page, cursor) {
79
+ return page.columns[cursor.columnIndex]?.band ?? 0;
80
+ }
81
+ /** True when every column of the band has consumed the same height (within
82
+ * 0.5px) — the page top, right after an opener heading (which reserves its
83
+ * band in every column), right after another span block, or right after a
84
+ * top float band. Used height = `bbox.height − availableHeight`. */
85
+ export function isBandLevel(cols) {
86
+ if (cols.length === 0)
87
+ return false;
88
+ const used0 = cols[0].bbox.height - cols[0].availableHeight;
89
+ return cols.every((c) => Math.abs((c.bbox.height - c.availableHeight) - used0) <= 0.5);
90
+ }
91
+ /** Lowest used bottom (absolute y) across the band's columns — where a
92
+ * full-width block can start without covering placed content. */
93
+ export function bandUsedBottom(cols) {
94
+ let bottom = -Infinity;
95
+ for (const c of cols) {
96
+ bottom = Math.max(bottom, c.bbox.y + (c.bbox.height - c.availableHeight));
97
+ }
98
+ return bottom;
99
+ }
100
+ /**
101
+ * Close the band formed by `cols` at `cutY`, insert a full-width span column
102
+ * holding `block` right below the cut, and open a fresh band of text columns
103
+ * under it. The band's columns are clamped to `cutY` — a column whose top
104
+ * already sits at the cut becomes zero-height — and keep only the slack
105
+ * between their used bottom and the cut in `availableHeight` (zero when the
106
+ * band is level on the grid; whole lines when a band cap cut the band with
107
+ * its last column short, so column balancing can still fill them). The span
108
+ * column is `{ kind: 'span', band }` at `contentArea.x / width`, `needPx`
109
+ * tall (the block plus its spacing, already rounded to the grid by the
110
+ * caller); `block` is placed inside it at `spacingBefore` below the cut with
111
+ * height `blockHeight` (default: the rest of the band), so `block.pageIndex`
112
+ * / `columnIndex` address the span column.
113
+ *
114
+ * The new text columns (`band + 1`) copy each closed column's x / width and
115
+ * keep its original bottom (so a bottom float band reserved on one column
116
+ * still constrains its successor). A column with no room left (bottom
117
+ * within 0.5px of the new band's top) is not created; when none is, the
118
+ * cursor stays on the span column — which is full — so the next placement
119
+ * advances to a new page. Otherwise the cursor moves to the first new
120
+ * column. Returns the span column.
121
+ */
122
+ export function closeBandAndInsertSpan(page, cols, cutY, block, needPx, cursor, spacingBefore = 0, blockHeight = needPx - spacingBefore) {
123
+ const band = cols[0]?.band ?? 0;
124
+ const bottoms = cols.map((c) => c.bbox.y + c.bbox.height);
125
+ for (const c of cols) {
126
+ const used = c.bbox.height - c.availableHeight;
127
+ c.band = band;
128
+ c.bbox.height = Math.max(0, cutY - c.bbox.y);
129
+ c.availableHeight = Math.max(0, c.bbox.height - used);
130
+ }
131
+ const spanCol = createVDTColumn(page.columns.length, createBoundingBox(page.contentArea.x, cutY, page.contentArea.width, needPx));
132
+ spanCol.kind = 'span';
133
+ spanCol.band = band;
134
+ page.columns.push(spanCol);
135
+ cursor.pageIndex = page.index;
136
+ cursor.columnIndex = spanCol.index;
137
+ if (spacingBefore > 0)
138
+ spanCol.availableHeight -= spacingBefore;
139
+ placeBlockInColumn(block, blockHeight, spanCol, cursor);
140
+ spanCol.availableHeight = 0;
141
+ const newTop = cutY + needPx;
142
+ let firstNew;
143
+ cols.forEach((c, i) => {
144
+ const height = bottoms[i] - newTop;
145
+ if (height < 0.5)
146
+ return;
147
+ const next = createVDTColumn(page.columns.length, createBoundingBox(c.bbox.x, newTop, c.bbox.width, height));
148
+ next.band = band + 1;
149
+ page.columns.push(next);
150
+ if (!firstNew)
151
+ firstNew = next;
152
+ });
153
+ if (firstNew)
154
+ cursor.columnIndex = firstNew.index;
155
+ return spanCol;
156
+ }
21
157
  export function advanceToNextColumn(doc, cursor, resolved, contentArea, pageWidthPx, pageHeightPx, onNewPage) {
22
158
  const page = doc.pages[cursor.pageIndex];
23
159
  if (cursor.columnIndex < page.columns.length - 1) {
@@ -41,9 +177,9 @@ export function advanceToNextColumn(doc, cursor, resolved, contentArea, pageWidt
41
177
  * emitting a blank leading page when a `:::pagebreak` directive lands
42
178
  * before any content. */
43
179
  export function advanceToNextPageBoundary(doc, cursor, resolved, contentArea, pageWidthPx, pageHeightPx, onNewPage) {
44
- const curPage = doc.pages[cursor.pageIndex];
45
- const curPageEmpty = curPage.columns.every((c) => c.blocks.length === 0);
46
- if (curPageEmpty)
180
+ // Span columns hold their block like any other column, so a page whose
181
+ // only content is a page-span block counts as non-empty here.
182
+ if (!pageHasContent(doc.pages[cursor.pageIndex]))
47
183
  return;
48
184
  const startPageIndex = cursor.pageIndex;
49
185
  do {
@@ -101,18 +237,19 @@ export function enforcePageParity(doc, cursor, resolved, contentArea, pageWidthP
101
237
  }
102
238
  }
103
239
  /**
104
- * Place a resource block (image / svg / table + caption) keeping it together as
105
- * one atomic unit (issue #49 §7 — Placement). Resources never split mid-content
106
- * for v1: if the group's combined height fits the remaining column space it is
107
- * placed there; otherwise the cursor advances to the next column/page (without
108
- * emitting a leading blank page when the current column is empty), and the
109
- * resource is force-placed there even when it exceeds a single column's height.
240
+ * Place an atomic block — a resource group (image / svg / table + caption,
241
+ * issue #49 §7) or a callout frame keeping it together as one unit. Atomic
242
+ * blocks never split mid-content for v1: if the group's combined height fits
243
+ * the remaining column space it is placed there; otherwise the cursor advances
244
+ * to the next column/page (without emitting a leading blank page when the
245
+ * current column is empty), and the block is force-placed there even when it
246
+ * exceeds a single column's height.
110
247
  *
111
248
  * `spacingBefore` is consumed from the target column's available height before
112
249
  * placement (collapsed against the previous block's bottom margin by the
113
250
  * caller). Returns the height actually reserved for the block.
114
251
  */
115
- export function placeResourceBlock(block, groupHeight, spacingBefore, cursor, doc, resolved, contentArea, pageWidthPx, pageHeightPx) {
252
+ export function placeAtomicBlock(block, groupHeight, spacingBefore, cursor, doc, resolved, contentArea, pageWidthPx, pageHeightPx) {
116
253
  let col = currentColumn(doc, cursor);
117
254
  const isFirstInColumn = col.blocks.length === 0;
118
255
  const effectiveSpacing = isFirstInColumn ? 0 : spacingBefore;
@@ -130,6 +267,8 @@ export function placeResourceBlock(block, groupHeight, spacingBefore, cursor, do
130
267
  placeBlockInColumn(block, groupHeight, col, cursor);
131
268
  return groupHeight;
132
269
  }
270
+ /** @deprecated Use {@link placeAtomicBlock}. */
271
+ export const placeResourceBlock = placeAtomicBlock;
133
272
  export function placeBlockInColumn(block, blockHeight, col, cursor) {
134
273
  const y = col.bbox.y + (col.bbox.height - col.availableHeight);
135
274
  block.bbox = createBoundingBox(col.bbox.x, y, col.bbox.width, blockHeight);
@@ -1 +1 @@
1
- {"version":3,"file":"placement.js","sourceRoot":"","sources":["../../src/pipeline/placement.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"placement.js","sourceRoot":"","sources":["../../src/pipeline/placement.ts"],"names":[],"mappings":"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"}
@@ -10,17 +10,23 @@
10
10
  * - bitmap / svg: scale to the column width, preserving aspect ratio. The
11
11
  * height follows from the intrinsic dimensions; svgs without intrinsic
12
12
  * dimensions fall back to a 4:3 box at column width.
13
- * - table: equal column split; each cell measured via the shared rich-text
14
- * measurer; row height = max cell height (rowspans distribute across rows).
13
+ * - table: columns split by `TableModel.columnWidths` weights (equal split
14
+ * when unset); each cell measured via the shared rich-text measurer; row
15
+ * height = max cell height (rowspans distribute across rows).
15
16
  * - caption: measured via the rich-text measurer with the caption font, with
16
17
  * the type's caption prefix + number prepended. Inline `:ref` spans resolve
17
18
  * to their computed label and are tagged so renderers can colour / link them.
19
+ * Sits below the body by default or above it (`captionStyle.position`),
20
+ * optionally on a background bar spanning the block width. A resource type
21
+ * may override the caption style partially (`ResourceType.captionStyle`).
22
+ * - note: an optional smaller run (`Resource.note`) placed under the body when
23
+ * the caption is above, otherwise under the caption.
18
24
  *
19
- * Resource + caption are measured as one group; `totalHeight` is what goes to
20
- * placement (resources paginate atomically — no mid-split for v1).
25
+ * Resource + caption + note are measured as one group; `totalHeight` is what
26
+ * goes to placement (resources paginate atomically — no mid-split for v1).
21
27
  */
22
28
  import type { InlineSpan } from '../parse';
23
- import type { Resource, ResourceType } from '../types';
29
+ import type { Resource, ResourceType, TableModel } from '../types';
24
30
  import type { ResolvedConfig, ResolvedResourceBlock } from '../vdt';
25
31
  import type { ResourceNumberingMap } from './resourceNumbering';
26
32
  export interface ResourceLayoutInput {
@@ -45,6 +51,13 @@ export declare function resolveRefSpans(spans: InlineSpan[], resourceNumbering:
45
51
  bold: boolean;
46
52
  italic: boolean;
47
53
  }): InlineSpan[];
54
+ /**
55
+ * Column x-edges (length = columnCount + 1) for a table model laid out at
56
+ * `columnWidth`. `TableModel.columnWidths` are relative weights, normalised so
57
+ * they always fill the width exactly; a missing array, a wrong length, or any
58
+ * non-positive / non-finite weight falls back to an equal split.
59
+ */
60
+ export declare function computeColumnEdges(model: TableModel, columnWidth: number): number[];
48
61
  /**
49
62
  * Measure a resource block (image / svg / table) plus its caption into a
50
63
  * placement-ready {@link ResolvedResourceBlock}. Returns the block and its
@@ -1 +1 @@
1
- {"version":3,"file":"resourceLayout.d.ts","sourceRoot":"","sources":["../../src/pipeline/resourceLayout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EAIb,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAItB,MAAM,QAAQ,CAAC;AAMhB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAMhE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,YAAY,GAAG,SAAS,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC;IACzB,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,iBAAiB,EAAE,oBAAoB,CAAC;IACxC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED;wEACwE;AACxE,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EACnC,iBAAiB,EAAE,oBAAoB,EACvC,aAAa,EAAE,YAAY,EAAE,EAC7B,SAAS,EAAE,QAAQ,EAAE,GACpB,MAAM,CAcR;AAWD;;6EAE6E;AAC7E,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EAAE,EACnB,iBAAiB,EAAE,oBAAoB,EACvC,aAAa,EAAE,YAAY,EAAE,EAC7B,SAAS,EAAE,QAAQ,EAAE,EACrB,QAAQ,CAAC,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC5C,UAAU,EAAE,CAcd;AA+LD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,mBAAmB,GAAG;IAC/D,KAAK,EAAE,qBAAqB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB,CA2KA"}
1
+ {"version":3,"file":"resourceLayout.d.ts","sourceRoot":"","sources":["../../src/pipeline/resourceLayout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAEV,QAAQ,EACR,YAAY,EACZ,UAAU,EAIX,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAItB,MAAM,QAAQ,CAAC;AAOhB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAMhE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,YAAY,GAAG,SAAS,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC;IACzB,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,iBAAiB,EAAE,oBAAoB,CAAC;IACxC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED;wEACwE;AACxE,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EACnC,iBAAiB,EAAE,oBAAoB,EACvC,aAAa,EAAE,YAAY,EAAE,EAC7B,SAAS,EAAE,QAAQ,EAAE,GACpB,MAAM,CAcR;AA4BD;;6EAE6E;AAC7E,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EAAE,EACnB,iBAAiB,EAAE,oBAAoB,EACvC,aAAa,EAAE,YAAY,EAAE,EAC7B,SAAS,EAAE,QAAQ,EAAE,EACrB,QAAQ,CAAC,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC5C,UAAU,EAAE,CAcd;AAuDD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBnF;AAkJD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,mBAAmB,GAAG;IAC/D,KAAK,EAAE,qBAAqB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB,CA6PA"}
@@ -10,19 +10,26 @@
10
10
  * - bitmap / svg: scale to the column width, preserving aspect ratio. The
11
11
  * height follows from the intrinsic dimensions; svgs without intrinsic
12
12
  * dimensions fall back to a 4:3 box at column width.
13
- * - table: equal column split; each cell measured via the shared rich-text
14
- * measurer; row height = max cell height (rowspans distribute across rows).
13
+ * - table: columns split by `TableModel.columnWidths` weights (equal split
14
+ * when unset); each cell measured via the shared rich-text measurer; row
15
+ * height = max cell height (rowspans distribute across rows).
15
16
  * - caption: measured via the rich-text measurer with the caption font, with
16
17
  * the type's caption prefix + number prepended. Inline `:ref` spans resolve
17
18
  * to their computed label and are tagged so renderers can colour / link them.
19
+ * Sits below the body by default or above it (`captionStyle.position`),
20
+ * optionally on a background bar spanning the block width. A resource type
21
+ * may override the caption style partially (`ResourceType.captionStyle`).
22
+ * - note: an optional smaller run (`Resource.note`) placed under the body when
23
+ * the caption is above, otherwise under the caption.
18
24
  *
19
- * Resource + caption are measured as one group; `totalHeight` is what goes to
20
- * placement (resources paginate atomically — no mid-split for v1).
25
+ * Resource + caption + note are measured as one group; `totalHeight` is what
26
+ * goes to placement (resources paginate atomically — no mid-split for v1).
21
27
  */
22
28
  import { createBoundingBox } from '../vdt';
23
29
  import { measureRichBlock, buildFontString } from '../measure';
24
30
  import { dimensionToPx } from '../units';
25
31
  import { extractInlineRefs, injectRefSpans, parseInlineFormatting } from '../parse/inlineFormatting';
32
+ import { mergeCaptionStyle } from '../defaults/captionStyle';
26
33
  import { resolveBodyStyle } from './styles';
27
34
  /** Non-breaking space used to glue a resolved `:ref` label into a single
28
35
  * atomic text token, so a post-measurement pass can tag it reliably. */
@@ -39,13 +46,30 @@ export function resolveRefLabel(ref, resourceNumbering, resourceTypes, resources
39
46
  const resource = resources.find((r) => r.id === ref.resourceId);
40
47
  const type = resource ? resourceTypes.find((t) => t.id === resource.typeId) : undefined;
41
48
  if (ref.style === 'full') {
42
- const name = type?.name ?? type?.shortLabel ?? '';
49
+ const name = applyRefCase(type?.name ?? type?.shortLabel ?? '', ref.case);
43
50
  return name ? `${name}${NBSP}${number}` : number;
44
51
  }
45
52
  // default: short label + number (e.g. "Fig. 1.7")
46
- const short = type?.shortLabel ?? type?.name ?? '';
53
+ const short = applyRefCase(type?.shortLabel ?? type?.name ?? '', ref.case);
47
54
  return short ? `${short}${NBSP}${number}` : number;
48
55
  }
56
+ /** Apply a `:ref{case=…}` transform to the label part of a computed
57
+ * reference (`Fig.` / `Figure`). The number is never touched — the caller
58
+ * joins it afterwards — and `text=` overrides bypass this entirely. */
59
+ function applyRefCase(label, refCase) {
60
+ if (refCase === undefined || label.length === 0)
61
+ return label;
62
+ switch (refCase) {
63
+ case 'lower':
64
+ return label.toLocaleLowerCase();
65
+ case 'upper':
66
+ return label.toLocaleUpperCase();
67
+ case 'capitalize': {
68
+ const first = [...label][0];
69
+ return first.toLocaleUpperCase() + label.slice(first.length);
70
+ }
71
+ }
72
+ }
49
73
  /** Parse caption / table-cell content into inline spans, recognising the same
50
74
  * inline `:ref{…}` microformat as body text so references inside captions and
51
75
  * cells resolve to their computed labels (the cell/caption is self-contained,
@@ -93,17 +117,51 @@ function fitWidth(intrinsicW, intrinsicH, columnWidth) {
93
117
  const height = (intrinsicH / intrinsicW) * width;
94
118
  return { width, height };
95
119
  }
96
- /** Lay out an HTML-table resource: equal column split, per-cell rich-text
97
- * measurement, row height = max measured cell height. Rowspans reserve their
98
- * primary cell's full vertical extent. */
120
+ /** Smallest border thickness (px) we let through: thinner rules would vanish
121
+ * on screen, but 0.5pt (≈0.67px at 96dpi) hairlines must survive intact
122
+ * the previous `max(1, round(px))` rounded them up to a full pixel. */
123
+ const MIN_BORDER_PX = 0.25;
124
+ /**
125
+ * Column x-edges (length = columnCount + 1) for a table model laid out at
126
+ * `columnWidth`. `TableModel.columnWidths` are relative weights, normalised so
127
+ * they always fill the width exactly; a missing array, a wrong length, or any
128
+ * non-positive / non-finite weight falls back to an equal split.
129
+ */
130
+ export function computeColumnEdges(model, columnWidth) {
131
+ const colCount = model.rows.length > 0 ? Math.max(...model.rows.map((r) => r.length)) : 0;
132
+ const weights = model.columnWidths;
133
+ const valid = weights !== undefined
134
+ && weights.length === colCount
135
+ && weights.every((w) => Number.isFinite(w) && w > 0);
136
+ const edges = [0];
137
+ if (colCount === 0)
138
+ return edges;
139
+ if (!valid) {
140
+ const colWidth = columnWidth / colCount;
141
+ for (let c = 1; c <= colCount; c++)
142
+ edges.push(c * colWidth);
143
+ return edges;
144
+ }
145
+ const total = weights.reduce((sum, w) => sum + w, 0);
146
+ let acc = 0;
147
+ for (let c = 0; c < colCount; c++) {
148
+ acc += (weights[c] / total) * columnWidth;
149
+ edges.push(acc);
150
+ }
151
+ // Snap the last edge so floating-point drift never leaves a sliver.
152
+ edges[colCount] = columnWidth;
153
+ return edges;
154
+ }
155
+ /** Lay out an HTML-table resource: weighted column split (see
156
+ * {@link computeColumnEdges}), per-cell rich-text measurement, row height =
157
+ * max measured cell height. Rowspans reserve their primary cell's full
158
+ * vertical extent. */
99
159
  function layoutTable(model, columnWidth, style, resourceNumbering, resourceTypes, resources, refStyle) {
100
160
  const { body, header, borderColor, borderWidthPx, cellPaddingPx } = style;
101
161
  const rowCount = model.rows.length;
102
162
  const colCount = rowCount > 0 ? Math.max(...model.rows.map((r) => r.length)) : 0;
103
- const colWidth = colCount > 0 ? columnWidth / colCount : columnWidth;
104
- const columnEdges = [];
105
- for (let c = 0; c <= colCount; c++)
106
- columnEdges.push(c * colWidth);
163
+ const columnEdges = computeColumnEdges(model, columnWidth);
164
+ const spanWidth = (col, colSpan) => (columnEdges[Math.min(col + colSpan, colCount)] ?? columnWidth) - (columnEdges[col] ?? 0);
107
165
  const measured = [];
108
166
  const rowMinHeight = new Array(rowCount).fill(body.lineHeightPx);
109
167
  for (let r = 0; r < rowCount; r++) {
@@ -116,7 +174,7 @@ function layoutTable(model, columnWidth, style, resourceNumbering, resourceTypes
116
174
  const rowSpan = Math.max(1, cell.rowSpan ?? 1);
117
175
  const isHeader = cell.isHeader ?? r < (model.headerRowCount ?? 0);
118
176
  const set = isHeader ? header : body;
119
- const cellWidth = colSpan * colWidth - cellPaddingPx * 2;
177
+ const cellWidth = spanWidth(c, colSpan) - cellPaddingPx * 2;
120
178
  const spans = resolveRefSpans(parseRefAwareSpans(cell.content), resourceNumbering, resourceTypes, resources, refStyle);
121
179
  const m = measureRichBlock(spans, set.fontString, set.boldFontString, set.italicFontString, set.boldItalicFontString, Math.max(1, cellWidth), set.lineHeightPx, { textAlign: cell.align === 'center' ? 'center' : cell.align === 'right' ? 'left' : 'left' });
122
180
  const contentHeight = Math.max(set.lineHeightPx, m.totalHeight) + cellPaddingPx * 2;
@@ -193,6 +251,7 @@ function layoutTable(model, columnWidth, style, resourceNumbering, resourceTypes
193
251
  cells,
194
252
  columnEdges,
195
253
  rowEdges,
254
+ rules: style.rules,
196
255
  };
197
256
  return { layout, height: tableHeight };
198
257
  }
@@ -266,22 +325,25 @@ export function layoutResourceBlock(input) {
266
325
  lineHeightPx: headerFontPx * lineHeightRatio,
267
326
  },
268
327
  borderColor: ts.borderColor.hex,
269
- borderWidthPx: ts.borders ? Math.max(1, Math.round(dimensionToPx(ts.borderWidth, dpi))) : 0,
328
+ borderWidthPx: ts.borders && ts.rules !== 'none'
329
+ ? Math.max(MIN_BORDER_PX, dimensionToPx(ts.borderWidth, dpi))
330
+ : 0,
270
331
  cellPaddingPx: dimensionToPx(ts.cellPadding, dpi, bodyFontPx),
271
332
  headerBackground: ts.headerBackgroundEnabled ? ts.headerBackground.hex : undefined,
272
333
  bodyBackground: ts.bodyBackgroundEnabled ? ts.bodyBackground.hex : undefined,
334
+ rules: ts.rules,
273
335
  };
274
336
  const { layout, height } = layoutTable(resource.table.model, columnWidth, style, resourceNumbering, resourceTypes, resources, refStyle);
275
337
  table = layout;
276
338
  bodyWidth = columnWidth;
277
339
  bodyHeight = height;
278
340
  }
279
- const bodyRect = createBoundingBox(0, 0, bodyWidth, bodyHeight);
280
341
  // --- Caption -----------------------------------------------------------
281
- const cs = resolved.captionStyle;
342
+ const cs = mergeCaptionStyle(resolved.captionStyle, resourceType?.captionStyle, resolved.colorPalette);
282
343
  const captionFontPx = dimensionToPx(cs.fontSize, dpi);
283
344
  const captionLineHeightPx = captionFontPx * lineHeightRatio;
284
345
  const captionGapPx = dimensionToPx(cs.gap, dpi, captionFontPx);
346
+ const captionPaddingPx = cs.backgroundEnabled ? dimensionToPx(cs.padding, dpi, captionFontPx) : 0;
285
347
  // Caption font set (label + description share one typeface/size; weight and
286
348
  // slant vary per span).
287
349
  const captionFontString = buildFontString(cs.fontFamily, captionFontPx, normalWeight);
@@ -292,7 +354,8 @@ export function layoutResourceBlock(input) {
292
354
  // Inline `:ref` labels render in the configured reference colour (defaults to
293
355
  // the emphasis/bold colour).
294
356
  const linkColor = resolved.bodyText.referenceColor.hex;
295
- let captionLines = [];
357
+ // Caption lines measured at the block origin (y = 0); positioned below.
358
+ let measuredCaption = [];
296
359
  const captionText = resource.caption ?? '';
297
360
  const hasCaption = captionText.trim().length > 0 || captionPrefix.length > 0;
298
361
  if (hasCaption) {
@@ -308,13 +371,65 @@ export function layoutResourceBlock(input) {
308
371
  const allSpans = prefixText.length > 0
309
372
  ? [{ text: prefixText, bold: cs.labelBold, italic: cs.labelItalic, captionLabel: true }, ...descSpans]
310
373
  : descSpans;
311
- const measured = measureRichBlock(allSpans, captionFontString, captionBoldFontString, captionItalicFontString, captionBoldItalicFontString, Math.max(1, columnWidth), captionLineHeightPx, { textAlign: cs.align });
312
- captionLines = shiftLines(measured.lines, 0, bodyHeight + captionGapPx);
374
+ const measured = measureRichBlock(allSpans, captionFontString, captionBoldFontString, captionItalicFontString, captionBoldItalicFontString, Math.max(1, columnWidth - captionPaddingPx * 2), captionLineHeightPx, { textAlign: cs.align });
375
+ measuredCaption = measured.lines;
376
+ }
377
+ const captionTextHeight = measuredCaption.length * captionLineHeightPx;
378
+ // Height of the caption band: the text plus the bar padding on both sides.
379
+ const captionBandHeight = measuredCaption.length > 0
380
+ ? captionTextHeight + captionPaddingPx * 2
381
+ : 0;
382
+ const captionHeight = captionBandHeight > 0 ? captionBandHeight + captionGapPx : 0;
383
+ // --- Note --------------------------------------------------------------
384
+ const noteFontPx = dimensionToPx(cs.note.fontSize, dpi);
385
+ const noteLineHeightPx = noteFontPx * lineHeightRatio;
386
+ const noteGapPx = dimensionToPx(cs.note.gap, dpi, noteFontPx);
387
+ const noteFontString = buildFontString(cs.fontFamily, noteFontPx, normalWeight);
388
+ const noteBoldFontString = buildFontString(cs.fontFamily, noteFontPx, boldWeight);
389
+ const noteItalicFontString = buildFontString(cs.fontFamily, noteFontPx, normalWeight, 'italic');
390
+ const noteBoldItalicFontString = buildFontString(cs.fontFamily, noteFontPx, boldWeight, 'italic');
391
+ let measuredNote = [];
392
+ const noteText = resource.note ?? '';
393
+ if (noteText.trim().length > 0) {
394
+ const noteSpans = resolveRefSpans(parseRefAwareSpans(noteText), resourceNumbering, resourceTypes, resources, refStyle);
395
+ const slanted = cs.note.italic
396
+ ? noteSpans.map((s) => ({ ...s, italic: s.italic || true }))
397
+ : noteSpans;
398
+ const measured = measureRichBlock(slanted, noteFontString, noteBoldFontString, noteItalicFontString, noteBoldItalicFontString, Math.max(1, columnWidth), noteLineHeightPx, { textAlign: cs.note.align });
399
+ measuredNote = measured.lines;
313
400
  }
314
- const captionHeight = captionLines.length > 0
315
- ? captionLines.length * captionLineHeightPx + captionGapPx
401
+ const noteHeight = measuredNote.length > 0
402
+ ? measuredNote.length * noteLineHeightPx + noteGapPx
316
403
  : 0;
317
- const totalHeight = bodyHeight + captionHeight;
404
+ // --- Vertical stacking -------------------------------------------------
405
+ // above: [caption band] gap [body] noteGap [note]
406
+ // below: [body] gap [caption band] noteGap [note]
407
+ const captionAbove = cs.position === 'above' && captionBandHeight > 0;
408
+ const captionBandY = captionAbove ? 0 : bodyHeight + (captionBandHeight > 0 ? captionGapPx : 0);
409
+ const bodyY = captionAbove ? captionHeight : 0;
410
+ const bodyRect = createBoundingBox(0, bodyY, bodyWidth, bodyHeight);
411
+ // Table cells were laid out with the table's top at y = 0; when the caption
412
+ // sits above, move them down with the body (block-relative, like captions).
413
+ if (table && bodyY > 0) {
414
+ table = {
415
+ ...table,
416
+ cells: table.cells.map((cell) => ({
417
+ ...cell,
418
+ rect: createBoundingBox(cell.rect.x, cell.rect.y + bodyY, cell.rect.width, cell.rect.height),
419
+ lines: shiftLines(cell.lines, 0, bodyY),
420
+ })),
421
+ };
422
+ }
423
+ const captionLines = shiftLines(measuredCaption, captionPaddingPx, captionBandY + captionPaddingPx);
424
+ const captionBar = cs.backgroundEnabled && captionBandHeight > 0
425
+ ? {
426
+ rect: createBoundingBox(0, captionBandY, columnWidth, captionBandHeight),
427
+ background: cs.background.hex,
428
+ }
429
+ : undefined;
430
+ const noteY = (captionAbove ? bodyY + bodyHeight : bodyHeight + captionHeight) + noteGapPx;
431
+ const noteLines = shiftLines(measuredNote, 0, noteY);
432
+ const totalHeight = bodyHeight + captionHeight + noteHeight;
318
433
  const block = {
319
434
  resource,
320
435
  kind: resource.kind,
@@ -332,6 +447,13 @@ export function layoutResourceBlock(input) {
332
447
  captionLabelColor: cs.labelColor.hex,
333
448
  linkColor,
334
449
  table,
450
+ captionBar,
451
+ noteLines,
452
+ noteFontString,
453
+ noteBoldFontString,
454
+ noteItalicFontString,
455
+ noteBoldItalicFontString,
456
+ noteColor: cs.note.color.hex,
335
457
  };
336
458
  return { block, totalHeight };
337
459
  }