postext 1.15.1 → 1.16.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 (421) hide show
  1. package/dist/__tests__/arabic/harakatProfile.test.d.ts +2 -0
  2. package/dist/__tests__/arabic/harakatProfile.test.d.ts.map +1 -0
  3. package/dist/__tests__/arabic/harakatProfile.test.js +105 -0
  4. package/dist/__tests__/arabic/harakatProfile.test.js.map +1 -0
  5. package/dist/__tests__/bundleLocaleAndBytes.test.js +9 -9
  6. package/dist/__tests__/bundleLocaleAndBytes.test.js.map +1 -1
  7. package/dist/__tests__/chineseLocale.test.js +10 -5
  8. package/dist/__tests__/chineseLocale.test.js.map +1 -1
  9. package/dist/__tests__/cjk/annotationsRender.test.js +5 -2
  10. package/dist/__tests__/cjk/annotationsRender.test.js.map +1 -1
  11. package/dist/__tests__/cjk/chipTracking.test.d.ts +2 -0
  12. package/dist/__tests__/cjk/chipTracking.test.d.ts.map +1 -0
  13. package/dist/__tests__/cjk/chipTracking.test.js +52 -0
  14. package/dist/__tests__/cjk/chipTracking.test.js.map +1 -0
  15. package/dist/__tests__/cjk/japaneseHtml.test.d.ts +2 -0
  16. package/dist/__tests__/cjk/japaneseHtml.test.d.ts.map +1 -0
  17. package/dist/__tests__/cjk/japaneseHtml.test.js +163 -0
  18. package/dist/__tests__/cjk/japaneseHtml.test.js.map +1 -0
  19. package/dist/__tests__/cjk/japaneseMarks.test.d.ts +2 -0
  20. package/dist/__tests__/cjk/japaneseMarks.test.d.ts.map +1 -0
  21. package/dist/__tests__/cjk/japaneseMarks.test.js +289 -0
  22. package/dist/__tests__/cjk/japaneseMarks.test.js.map +1 -0
  23. package/dist/__tests__/cjk/japaneseMarksRender.test.d.ts +2 -0
  24. package/dist/__tests__/cjk/japaneseMarksRender.test.d.ts.map +1 -0
  25. package/dist/__tests__/cjk/japaneseMarksRender.test.js +161 -0
  26. package/dist/__tests__/cjk/japaneseMarksRender.test.js.map +1 -0
  27. package/dist/__tests__/cjk/japaneseRuby.test.d.ts +2 -0
  28. package/dist/__tests__/cjk/japaneseRuby.test.d.ts.map +1 -0
  29. package/dist/__tests__/cjk/japaneseRuby.test.js +457 -0
  30. package/dist/__tests__/cjk/japaneseRuby.test.js.map +1 -0
  31. package/dist/__tests__/cjk/japaneseSegmentLanguage.test.d.ts +2 -0
  32. package/dist/__tests__/cjk/japaneseSegmentLanguage.test.d.ts.map +1 -0
  33. package/dist/__tests__/cjk/japaneseSegmentLanguage.test.js +50 -0
  34. package/dist/__tests__/cjk/japaneseSegmentLanguage.test.js.map +1 -0
  35. package/dist/__tests__/cjk/japaneseSpacing.test.d.ts +2 -0
  36. package/dist/__tests__/cjk/japaneseSpacing.test.d.ts.map +1 -0
  37. package/dist/__tests__/cjk/japaneseSpacing.test.js +417 -0
  38. package/dist/__tests__/cjk/japaneseSpacing.test.js.map +1 -0
  39. package/dist/__tests__/cjk/kanbunKunten.test.d.ts +2 -0
  40. package/dist/__tests__/cjk/kanbunKunten.test.d.ts.map +1 -0
  41. package/dist/__tests__/cjk/kanbunKunten.test.js +230 -0
  42. package/dist/__tests__/cjk/kanbunKunten.test.js.map +1 -0
  43. package/dist/__tests__/cjk/kanbunKuntenRender.test.d.ts +2 -0
  44. package/dist/__tests__/cjk/kanbunKuntenRender.test.d.ts.map +1 -0
  45. package/dist/__tests__/cjk/kanbunKuntenRender.test.js +127 -0
  46. package/dist/__tests__/cjk/kanbunKuntenRender.test.js.map +1 -0
  47. package/dist/__tests__/cjk/kinsokuJa.test.d.ts +2 -0
  48. package/dist/__tests__/cjk/kinsokuJa.test.d.ts.map +1 -0
  49. package/dist/__tests__/cjk/kinsokuJa.test.js +388 -0
  50. package/dist/__tests__/cjk/kinsokuJa.test.js.map +1 -0
  51. package/dist/__tests__/cjk/kinsokuJaBuild.test.d.ts +2 -0
  52. package/dist/__tests__/cjk/kinsokuJaBuild.test.d.ts.map +1 -0
  53. package/dist/__tests__/cjk/kinsokuJaBuild.test.js +38 -0
  54. package/dist/__tests__/cjk/kinsokuJaBuild.test.js.map +1 -0
  55. package/dist/__tests__/cjk/resourceAnnotations.test.d.ts +2 -0
  56. package/dist/__tests__/cjk/resourceAnnotations.test.d.ts.map +1 -0
  57. package/dist/__tests__/cjk/resourceAnnotations.test.js +223 -0
  58. package/dist/__tests__/cjk/resourceAnnotations.test.js.map +1 -0
  59. package/dist/__tests__/defaults/cjk.test.js +10 -2
  60. package/dist/__tests__/defaults/cjk.test.js.map +1 -1
  61. package/dist/__tests__/exports.test.js +36 -0
  62. package/dist/__tests__/exports.test.js.map +1 -1
  63. package/dist/__tests__/headingLetterSpacing.test.js +2 -1
  64. package/dist/__tests__/headingLetterSpacing.test.js.map +1 -1
  65. package/dist/__tests__/indexChinese.test.js +1 -1
  66. package/dist/__tests__/indexJapanese.test.d.ts +2 -0
  67. package/dist/__tests__/indexJapanese.test.d.ts.map +1 -0
  68. package/dist/__tests__/indexJapanese.test.js +242 -0
  69. package/dist/__tests__/indexJapanese.test.js.map +1 -0
  70. package/dist/__tests__/japaneseHeadings.test.d.ts +2 -0
  71. package/dist/__tests__/japaneseHeadings.test.d.ts.map +1 -0
  72. package/dist/__tests__/japaneseHeadings.test.js +319 -0
  73. package/dist/__tests__/japaneseHeadings.test.js.map +1 -0
  74. package/dist/__tests__/japaneseLocale.test.d.ts +2 -0
  75. package/dist/__tests__/japaneseLocale.test.d.ts.map +1 -0
  76. package/dist/__tests__/japaneseLocale.test.js +201 -0
  77. package/dist/__tests__/japaneseLocale.test.js.map +1 -0
  78. package/dist/__tests__/japaneseNotes.test.d.ts +2 -0
  79. package/dist/__tests__/japaneseNotes.test.d.ts.map +1 -0
  80. package/dist/__tests__/japaneseNotes.test.js +336 -0
  81. package/dist/__tests__/japaneseNotes.test.js.map +1 -0
  82. package/dist/__tests__/japaneseNumbering.test.d.ts +2 -0
  83. package/dist/__tests__/japaneseNumbering.test.d.ts.map +1 -0
  84. package/dist/__tests__/japaneseNumbering.test.js +292 -0
  85. package/dist/__tests__/japaneseNumbering.test.js.map +1 -0
  86. package/dist/__tests__/pipeline/citationsJapanese.test.d.ts +2 -0
  87. package/dist/__tests__/pipeline/citationsJapanese.test.d.ts.map +1 -0
  88. package/dist/__tests__/pipeline/citationsJapanese.test.js +110 -0
  89. package/dist/__tests__/pipeline/citationsJapanese.test.js.map +1 -0
  90. package/dist/__tests__/pipeline/paragraphStyleFaces.test.js +1 -1
  91. package/dist/__tests__/pipeline/paragraphStyleFaces.test.js.map +1 -1
  92. package/dist/__tests__/pipeline/safeArea.test.d.ts +2 -0
  93. package/dist/__tests__/pipeline/safeArea.test.d.ts.map +1 -0
  94. package/dist/__tests__/pipeline/safeArea.test.js +207 -0
  95. package/dist/__tests__/pipeline/safeArea.test.js.map +1 -0
  96. package/dist/__tests__/vertical/compositionPaint.test.js +6 -5
  97. package/dist/__tests__/vertical/compositionPaint.test.js.map +1 -1
  98. package/dist/__tests__/vertical/japaneseVertical.test.d.ts +2 -0
  99. package/dist/__tests__/vertical/japaneseVertical.test.d.ts.map +1 -0
  100. package/dist/__tests__/vertical/japaneseVertical.test.js +247 -0
  101. package/dist/__tests__/vertical/japaneseVertical.test.js.map +1 -0
  102. package/dist/__tests__/vertical/verticalSpans.d.ts +2 -1
  103. package/dist/__tests__/vertical/verticalSpans.d.ts.map +1 -1
  104. package/dist/__tests__/vertical/verticalSpans.js +3 -2
  105. package/dist/__tests__/vertical/verticalSpans.js.map +1 -1
  106. package/dist/__tests__/video.test.d.ts +2 -0
  107. package/dist/__tests__/video.test.d.ts.map +1 -0
  108. package/dist/__tests__/video.test.js +305 -0
  109. package/dist/__tests__/video.test.js.map +1 -0
  110. package/dist/arabicMarks.d.ts +11 -1
  111. package/dist/arabicMarks.d.ts.map +1 -1
  112. package/dist/arabicMarks.js +72 -5
  113. package/dist/arabicMarks.js.map +1 -1
  114. package/dist/bundle/adapters.d.ts +6 -0
  115. package/dist/bundle/adapters.d.ts.map +1 -1
  116. package/dist/bundle/adapters.js +30 -0
  117. package/dist/bundle/adapters.js.map +1 -1
  118. package/dist/bundle/codec.d.ts.map +1 -1
  119. package/dist/bundle/codec.js +67 -3
  120. package/dist/bundle/codec.js.map +1 -1
  121. package/dist/bundle/index.d.ts +2 -2
  122. package/dist/bundle/index.d.ts.map +1 -1
  123. package/dist/bundle/index.js +2 -2
  124. package/dist/bundle/index.js.map +1 -1
  125. package/dist/bundle/manifest.d.ts +8 -0
  126. package/dist/bundle/manifest.d.ts.map +1 -1
  127. package/dist/bundle/manifest.js +48 -1
  128. package/dist/bundle/manifest.js.map +1 -1
  129. package/dist/bundle/types.d.ts +5 -0
  130. package/dist/bundle/types.d.ts.map +1 -1
  131. package/dist/bundle/zip.js +1 -1
  132. package/dist/bundle/zip.js.map +1 -1
  133. package/dist/canvas-backend/annotations.d.ts +20 -5
  134. package/dist/canvas-backend/annotations.d.ts.map +1 -1
  135. package/dist/canvas-backend/annotations.js +59 -6
  136. package/dist/canvas-backend/annotations.js.map +1 -1
  137. package/dist/canvas-backend/blockRender.d.ts.map +1 -1
  138. package/dist/canvas-backend/blockRender.js +29 -3
  139. package/dist/canvas-backend/blockRender.js.map +1 -1
  140. package/dist/canvas-backend/renderResourceBlock.d.ts +6 -1
  141. package/dist/canvas-backend/renderResourceBlock.d.ts.map +1 -1
  142. package/dist/canvas-backend/renderResourceBlock.js +124 -5
  143. package/dist/canvas-backend/renderResourceBlock.js.map +1 -1
  144. package/dist/canvas-backend/verticalText.d.ts +9 -4
  145. package/dist/canvas-backend/verticalText.d.ts.map +1 -1
  146. package/dist/canvas-backend/verticalText.js +20 -9
  147. package/dist/canvas-backend/verticalText.js.map +1 -1
  148. package/dist/chineseNumerals.d.ts +3 -2
  149. package/dist/chineseNumerals.d.ts.map +1 -1
  150. package/dist/chineseNumerals.js +11 -8
  151. package/dist/chineseNumerals.js.map +1 -1
  152. package/dist/citations/bibtex.d.ts.map +1 -1
  153. package/dist/citations/bibtex.js +4 -0
  154. package/dist/citations/bibtex.js.map +1 -1
  155. package/dist/citations/data.d.ts.map +1 -1
  156. package/dist/citations/data.js +6 -1
  157. package/dist/citations/data.js.map +1 -1
  158. package/dist/citations/types.d.ts +8 -0
  159. package/dist/citations/types.d.ts.map +1 -1
  160. package/dist/cjkMarks.d.ts +23 -14
  161. package/dist/cjkMarks.d.ts.map +1 -1
  162. package/dist/cjkMarks.js +251 -49
  163. package/dist/cjkMarks.js.map +1 -1
  164. package/dist/configWarnings.js +9 -3
  165. package/dist/configWarnings.js.map +1 -1
  166. package/dist/defaults/cjk.d.ts +64 -14
  167. package/dist/defaults/cjk.d.ts.map +1 -1
  168. package/dist/defaults/cjk.js +203 -29
  169. package/dist/defaults/cjk.js.map +1 -1
  170. package/dist/defaults/footnotes.d.ts +27 -4
  171. package/dist/defaults/footnotes.d.ts.map +1 -1
  172. package/dist/defaults/footnotes.js +95 -36
  173. package/dist/defaults/footnotes.js.map +1 -1
  174. package/dist/defaults/headings.d.ts +5 -0
  175. package/dist/defaults/headings.d.ts.map +1 -1
  176. package/dist/defaults/headings.js +46 -1
  177. package/dist/defaults/headings.js.map +1 -1
  178. package/dist/defaults/index.d.ts +3 -2
  179. package/dist/defaults/index.d.ts.map +1 -1
  180. package/dist/defaults/index.js +12 -3
  181. package/dist/defaults/index.js.map +1 -1
  182. package/dist/defaults/indexConfig.d.ts.map +1 -1
  183. package/dist/defaults/indexConfig.js +7 -4
  184. package/dist/defaults/indexConfig.js.map +1 -1
  185. package/dist/defaults/paragraphStyles.d.ts.map +1 -1
  186. package/dist/defaults/paragraphStyles.js +4 -0
  187. package/dist/defaults/paragraphStyles.js.map +1 -1
  188. package/dist/defaults/resourceTypes.d.ts +16 -3
  189. package/dist/defaults/resourceTypes.d.ts.map +1 -1
  190. package/dist/defaults/resourceTypes.js +56 -8
  191. package/dist/defaults/resourceTypes.js.map +1 -1
  192. package/dist/defaults/shared.d.ts.map +1 -1
  193. package/dist/defaults/shared.js +21 -0
  194. package/dist/defaults/shared.js.map +1 -1
  195. package/dist/defaults/tableStyle.d.ts.map +1 -1
  196. package/dist/defaults/tableStyle.js +4 -1
  197. package/dist/defaults/tableStyle.js.map +1 -1
  198. package/dist/defaults/videoStyle.d.ts +9 -0
  199. package/dist/defaults/videoStyle.d.ts.map +1 -0
  200. package/dist/defaults/videoStyle.js +130 -0
  201. package/dist/defaults/videoStyle.js.map +1 -0
  202. package/dist/design/placeholders.d.ts.map +1 -1
  203. package/dist/design/placeholders.js +5 -3
  204. package/dist/design/placeholders.js.map +1 -1
  205. package/dist/html-backend.d.ts +13 -0
  206. package/dist/html-backend.d.ts.map +1 -1
  207. package/dist/html-backend.js +233 -26
  208. package/dist/html-backend.js.map +1 -1
  209. package/dist/htmlAnnotations.d.ts +47 -9
  210. package/dist/htmlAnnotations.d.ts.map +1 -1
  211. package/dist/htmlAnnotations.js +89 -17
  212. package/dist/htmlAnnotations.js.map +1 -1
  213. package/dist/index.d.ts +13 -7
  214. package/dist/index.d.ts.map +1 -1
  215. package/dist/index.js +8 -4
  216. package/dist/index.js.map +1 -1
  217. package/dist/japaneseNumerals.d.ts +44 -0
  218. package/dist/japaneseNumerals.d.ts.map +1 -0
  219. package/dist/japaneseNumerals.js +100 -0
  220. package/dist/japaneseNumerals.js.map +1 -0
  221. package/dist/knuthPlass/richAdapter.d.ts +5 -1
  222. package/dist/knuthPlass/richAdapter.d.ts.map +1 -1
  223. package/dist/knuthPlass/richAdapter.js +2 -0
  224. package/dist/knuthPlass/richAdapter.js.map +1 -1
  225. package/dist/locale.d.ts +19 -12
  226. package/dist/locale.d.ts.map +1 -1
  227. package/dist/locale.js +24 -12
  228. package/dist/locale.js.map +1 -1
  229. package/dist/measure/cache.d.ts.map +1 -1
  230. package/dist/measure/cache.js +17 -8
  231. package/dist/measure/cache.js.map +1 -1
  232. package/dist/measure/canvas.d.ts +21 -0
  233. package/dist/measure/canvas.d.ts.map +1 -1
  234. package/dist/measure/canvas.js +82 -0
  235. package/dist/measure/canvas.js.map +1 -1
  236. package/dist/measure/cjk.d.ts +3 -1
  237. package/dist/measure/cjk.d.ts.map +1 -1
  238. package/dist/measure/cjk.js +4 -2
  239. package/dist/measure/cjk.js.map +1 -1
  240. package/dist/measure/cjkAnnotate.d.ts +62 -3
  241. package/dist/measure/cjkAnnotate.d.ts.map +1 -1
  242. package/dist/measure/cjkAnnotate.js +99 -2
  243. package/dist/measure/cjkAnnotate.js.map +1 -1
  244. package/dist/measure/cjkClasses.d.ts +93 -13
  245. package/dist/measure/cjkClasses.d.ts.map +1 -1
  246. package/dist/measure/cjkClasses.js +204 -14
  247. package/dist/measure/cjkClasses.js.map +1 -1
  248. package/dist/measure/cjkCompose.d.ts +10 -4
  249. package/dist/measure/cjkCompose.d.ts.map +1 -1
  250. package/dist/measure/cjkCompose.js +715 -75
  251. package/dist/measure/cjkCompose.js.map +1 -1
  252. package/dist/measure/cjkPunctuation.d.ts +68 -14
  253. package/dist/measure/cjkPunctuation.d.ts.map +1 -1
  254. package/dist/measure/cjkPunctuation.js +96 -21
  255. package/dist/measure/cjkPunctuation.js.map +1 -1
  256. package/dist/measure/plain.js +2 -2
  257. package/dist/measure/plain.js.map +1 -1
  258. package/dist/measure/rich.d.ts +12 -2
  259. package/dist/measure/rich.d.ts.map +1 -1
  260. package/dist/measure/rich.js +46 -8
  261. package/dist/measure/rich.js.map +1 -1
  262. package/dist/measure/rubyJis.d.ts +96 -0
  263. package/dist/measure/rubyJis.d.ts.map +1 -0
  264. package/dist/measure/rubyJis.js +245 -0
  265. package/dist/measure/rubyJis.js.map +1 -0
  266. package/dist/measure/vertical.d.ts +13 -5
  267. package/dist/measure/vertical.d.ts.map +1 -1
  268. package/dist/measure/vertical.js +16 -6
  269. package/dist/measure/vertical.js.map +1 -1
  270. package/dist/numberWords.d.ts +4 -3
  271. package/dist/numberWords.d.ts.map +1 -1
  272. package/dist/numberWords.js +15 -5
  273. package/dist/numberWords.js.map +1 -1
  274. package/dist/numbering.d.ts +24 -12
  275. package/dist/numbering.d.ts.map +1 -1
  276. package/dist/numbering.js +57 -11
  277. package/dist/numbering.js.map +1 -1
  278. package/dist/parse/annotations.d.ts +21 -18
  279. package/dist/parse/annotations.d.ts.map +1 -1
  280. package/dist/parse/annotations.js +140 -51
  281. package/dist/parse/annotations.js.map +1 -1
  282. package/dist/parse/index.d.ts +1 -1
  283. package/dist/parse/index.d.ts.map +1 -1
  284. package/dist/parse/index.js.map +1 -1
  285. package/dist/parse/indexMarks.d.ts.map +1 -1
  286. package/dist/parse/indexMarks.js +42 -0
  287. package/dist/parse/indexMarks.js.map +1 -1
  288. package/dist/parse/inlineFormatting.d.ts +4 -3
  289. package/dist/parse/inlineFormatting.d.ts.map +1 -1
  290. package/dist/parse/inlineFormatting.js +9 -8
  291. package/dist/parse/inlineFormatting.js.map +1 -1
  292. package/dist/parse/types.d.ts +93 -5
  293. package/dist/parse/types.d.ts.map +1 -1
  294. package/dist/pipeline/annotations.d.ts +25 -15
  295. package/dist/pipeline/annotations.d.ts.map +1 -1
  296. package/dist/pipeline/annotations.js +102 -16
  297. package/dist/pipeline/annotations.js.map +1 -1
  298. package/dist/pipeline/build.d.ts.map +1 -1
  299. package/dist/pipeline/build.js +284 -31
  300. package/dist/pipeline/build.js.map +1 -1
  301. package/dist/pipeline/buildBlockKind.js +2 -1
  302. package/dist/pipeline/buildBlockKind.js.map +1 -1
  303. package/dist/pipeline/buildHelpers.d.ts +2 -0
  304. package/dist/pipeline/buildHelpers.d.ts.map +1 -1
  305. package/dist/pipeline/buildHelpers.js +17 -0
  306. package/dist/pipeline/buildHelpers.js.map +1 -1
  307. package/dist/pipeline/buildMeasurement.d.ts +3 -0
  308. package/dist/pipeline/buildMeasurement.d.ts.map +1 -1
  309. package/dist/pipeline/buildMeasurement.js +1 -0
  310. package/dist/pipeline/buildMeasurement.js.map +1 -1
  311. package/dist/pipeline/calloutLayout.d.ts +2 -0
  312. package/dist/pipeline/calloutLayout.d.ts.map +1 -1
  313. package/dist/pipeline/calloutLayout.js +5 -5
  314. package/dist/pipeline/calloutLayout.js.map +1 -1
  315. package/dist/pipeline/citations.d.ts +1 -1
  316. package/dist/pipeline/citations.d.ts.map +1 -1
  317. package/dist/pipeline/citations.js +15 -7
  318. package/dist/pipeline/citations.js.map +1 -1
  319. package/dist/pipeline/columnBalancing.d.ts +22 -0
  320. package/dist/pipeline/columnBalancing.d.ts.map +1 -1
  321. package/dist/pipeline/columnBalancing.js +80 -3
  322. package/dist/pipeline/columnBalancing.js.map +1 -1
  323. package/dist/pipeline/config.d.ts.map +1 -1
  324. package/dist/pipeline/config.js +3 -2
  325. package/dist/pipeline/config.js.map +1 -1
  326. package/dist/pipeline/contentWarnings.d.ts.map +1 -1
  327. package/dist/pipeline/contentWarnings.js +19 -0
  328. package/dist/pipeline/contentWarnings.js.map +1 -1
  329. package/dist/pipeline/continuation.d.ts.map +1 -1
  330. package/dist/pipeline/continuation.js +3 -3
  331. package/dist/pipeline/continuation.js.map +1 -1
  332. package/dist/pipeline/crossRefs.d.ts.map +1 -1
  333. package/dist/pipeline/crossRefs.js +3 -0
  334. package/dist/pipeline/crossRefs.js.map +1 -1
  335. package/dist/pipeline/footnotes.d.ts +20 -12
  336. package/dist/pipeline/footnotes.d.ts.map +1 -1
  337. package/dist/pipeline/footnotes.js +62 -16
  338. package/dist/pipeline/footnotes.js.map +1 -1
  339. package/dist/pipeline/headingStyles.js +1 -1
  340. package/dist/pipeline/headingStyles.js.map +1 -1
  341. package/dist/pipeline/indexDirective.d.ts.map +1 -1
  342. package/dist/pipeline/indexDirective.js +89 -12
  343. package/dist/pipeline/indexDirective.js.map +1 -1
  344. package/dist/pipeline/indexGroups.d.ts +5 -3
  345. package/dist/pipeline/indexGroups.d.ts.map +1 -1
  346. package/dist/pipeline/indexGroups.js +9 -4
  347. package/dist/pipeline/indexGroups.js.map +1 -1
  348. package/dist/pipeline/indexJapanese.d.ts +75 -0
  349. package/dist/pipeline/indexJapanese.d.ts.map +1 -0
  350. package/dist/pipeline/indexJapanese.js +264 -0
  351. package/dist/pipeline/indexJapanese.js.map +1 -0
  352. package/dist/pipeline/lineSpan.d.ts +36 -0
  353. package/dist/pipeline/lineSpan.d.ts.map +1 -0
  354. package/dist/pipeline/lineSpan.js +36 -0
  355. package/dist/pipeline/lineSpan.js.map +1 -0
  356. package/dist/pipeline/lists.js +2 -2
  357. package/dist/pipeline/lists.js.map +1 -1
  358. package/dist/pipeline/measureContentBlock.d.ts +4 -0
  359. package/dist/pipeline/measureContentBlock.d.ts.map +1 -1
  360. package/dist/pipeline/measureContentBlock.js +54 -5
  361. package/dist/pipeline/measureContentBlock.js.map +1 -1
  362. package/dist/pipeline/outline.d.ts.map +1 -1
  363. package/dist/pipeline/outline.js +3 -1
  364. package/dist/pipeline/outline.js.map +1 -1
  365. package/dist/pipeline/paragraphContainers.d.ts +25 -2
  366. package/dist/pipeline/paragraphContainers.d.ts.map +1 -1
  367. package/dist/pipeline/paragraphContainers.js +82 -2
  368. package/dist/pipeline/paragraphContainers.js.map +1 -1
  369. package/dist/pipeline/parts.d.ts +2 -2
  370. package/dist/pipeline/parts.js +3 -3
  371. package/dist/pipeline/parts.js.map +1 -1
  372. package/dist/pipeline/placement.d.ts.map +1 -1
  373. package/dist/pipeline/placement.js +2 -2
  374. package/dist/pipeline/placement.js.map +1 -1
  375. package/dist/pipeline/resourceLayout.d.ts +6 -0
  376. package/dist/pipeline/resourceLayout.d.ts.map +1 -1
  377. package/dist/pipeline/resourceLayout.js +85 -15
  378. package/dist/pipeline/resourceLayout.js.map +1 -1
  379. package/dist/pipeline/resourceNumbering.d.ts +5 -2
  380. package/dist/pipeline/resourceNumbering.d.ts.map +1 -1
  381. package/dist/pipeline/resourceNumbering.js +12 -7
  382. package/dist/pipeline/resourceNumbering.js.map +1 -1
  383. package/dist/pipeline/safeArea.d.ts +29 -0
  384. package/dist/pipeline/safeArea.d.ts.map +1 -0
  385. package/dist/pipeline/safeArea.js +89 -0
  386. package/dist/pipeline/safeArea.js.map +1 -0
  387. package/dist/pipeline/styles.d.ts +12 -0
  388. package/dist/pipeline/styles.d.ts.map +1 -1
  389. package/dist/pipeline/styles.js +7 -1
  390. package/dist/pipeline/styles.js.map +1 -1
  391. package/dist/pipeline/verse.d.ts +3 -0
  392. package/dist/pipeline/verse.d.ts.map +1 -1
  393. package/dist/pipeline/verse.js +1 -1
  394. package/dist/pipeline/verse.js.map +1 -1
  395. package/dist/pipeline/verticalMetrics.d.ts.map +1 -1
  396. package/dist/pipeline/verticalMetrics.js +4 -0
  397. package/dist/pipeline/verticalMetrics.js.map +1 -1
  398. package/dist/pipeline/videoOverlay.d.ts +24 -0
  399. package/dist/pipeline/videoOverlay.d.ts.map +1 -0
  400. package/dist/pipeline/videoOverlay.js +134 -0
  401. package/dist/pipeline/videoOverlay.js.map +1 -0
  402. package/dist/types.d.ts +567 -50
  403. package/dist/types.d.ts.map +1 -1
  404. package/dist/uprightArabic.js +1 -1
  405. package/dist/uprightArabic.js.map +1 -1
  406. package/dist/vdt.d.ts +221 -17
  407. package/dist/vdt.d.ts.map +1 -1
  408. package/dist/vdt.js.map +1 -1
  409. package/dist/video/qr.d.ts +21 -0
  410. package/dist/video/qr.d.ts.map +1 -0
  411. package/dist/video/qr.js +326 -0
  412. package/dist/video/qr.js.map +1 -0
  413. package/dist/video/url.d.ts +62 -0
  414. package/dist/video/url.d.ts.map +1 -0
  415. package/dist/video/url.js +206 -0
  416. package/dist/video/url.js.map +1 -0
  417. package/dist/writingMode.d.ts +74 -20
  418. package/dist/writingMode.d.ts.map +1 -1
  419. package/dist/writingMode.js +146 -27
  420. package/dist/writingMode.js.map +1 -1
  421. package/package.json +1 -1
@@ -0,0 +1,242 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { buildDocument } from '../pipeline';
3
+ import { expandIndexDirectives } from '../pipeline/indexDirective';
4
+ import { indexGrouping } from '../pipeline/indexGroups';
5
+ import { GOJUON, GOJUON_ROWS, compareJapanese, gojuonRow, japaneseLead, sameJapaneseBase } from '../pipeline/indexJapanese';
6
+ import { computeOutline } from '../pipeline/outline';
7
+ import { parseMarkdown } from '../parse';
8
+ import { resolveAllConfig } from '../pipeline/config';
9
+ import { resolveIndexConfig, stripIndexDefaults } from '../defaults/indexConfig';
10
+ import { resolveBodyTextConfig } from '../defaults/bodyText';
11
+ // The Japanese back-of-book index (#425): readings, JIS X 4061 order and
12
+ // gojūon heads.
13
+ class StubCtx {
14
+ font = '';
15
+ measureText(s) {
16
+ return { width: [...s].length * 7 };
17
+ }
18
+ }
19
+ globalThis.OffscreenCanvas = class {
20
+ getContext() {
21
+ return new StubCtx();
22
+ }
23
+ };
24
+ const pt = (value) => ({ value, unit: 'pt' });
25
+ const base = {
26
+ page: { width: pt(360), height: pt(300), margins: { top: pt(18), bottom: pt(18), left: pt(18), right: pt(18) } },
27
+ layout: { layoutType: 'single' },
28
+ };
29
+ const markEntry = (path, pageIndex, extra = {}) => ({
30
+ kind: 'indexMark', level: 0, title: path.join('!'), number: '', numbered: false, listed: false,
31
+ indexMark: { index: '', path, sourceStart: pageIndex * 100 + path.length, ...extra },
32
+ pageIndex, pageLabel: String(pageIndex + 1), pageFormat: 'decimal',
33
+ });
34
+ /** The entry blocks of an expansion: `[head] text`, `+` where a group
35
+ * starts without a head, two spaces per sub-level. */
36
+ const expanded = (blocks) => blocks.filter((b) => b.index).map((b) => `${' '.repeat(b.index.level)}${b.index.group ? `[${b.index.group}] ` : b.index.groupStart ? '+ ' : ''}${b.text}`);
37
+ const directive = parseMarkdown(':::index');
38
+ const expand = (config, outline) => expandIndexDirectives(directive, outline, resolveAllConfig({ ...base, ...config }));
39
+ const build = (config, outline) => expanded(expand(config, outline).blocks);
40
+ const sorted = (list) => [...list].sort(compareJapanese);
41
+ describe('JIS X 4061 order', () => {
42
+ it('reads katakana as hiragana, hiragana first on a tie', () => {
43
+ expect(sameJapaneseBase('カメラ', 'かめら')).toBe(true);
44
+ expect(sorted(['カキ', 'かき', 'かく', 'カカ'])).toEqual(['カカ', 'かき', 'カキ', 'かく']);
45
+ });
46
+ it('reads voiced kana as plain, 清 < 濁 < 半濁 on a tie', () => {
47
+ expect(sorted(['ぱん', 'はん', 'ばん'])).toEqual(['はん', 'ばん', 'ぱん']);
48
+ // The base letters decide first: ぱい (はい), ばか (はか), はなし.
49
+ expect(sorted(['はなし', 'ばか', 'ぱい'])).toEqual(['ぱい', 'ばか', 'はなし']);
50
+ expect(sorted(['ヴァイオリン', 'うさぎ', 'ういろう'])).toEqual(['ヴァイオリン', 'ういろう', 'うさぎ']);
51
+ });
52
+ it('reads small kana as large, small first on a tie', () => {
53
+ expect(sorted(['きつね', 'きって', 'きつて'])).toEqual(['きって', 'きつて', 'きつね']);
54
+ expect(sorted(['しよう', 'しょう'])).toEqual(['しょう', 'しよう']);
55
+ expect(sameJapaneseBase('ヵ月', 'か月')).toBe(true);
56
+ });
57
+ it('reads ー as the vowel before it, and sets it before the vowel written out', () => {
58
+ // コーヒー reads こおひい: after こうちゃ, before こおり.
59
+ expect(sorted(['こおり', 'コーヒー', 'こうちゃ'])).toEqual(['こうちゃ', 'コーヒー', 'こおり']);
60
+ expect(sameJapaneseBase('カード', 'かあど')).toBe(true);
61
+ expect(sorted(['かあど', 'カード'])).toEqual(['カード', 'かあど']);
62
+ // ン repeats itself; a long mark after the vowel row of や or わ.
63
+ expect(sameJapaneseBase('ヨーヨー', 'よおよお')).toBe(true);
64
+ expect(sameJapaneseBase('ワー', 'わあ')).toBe(true);
65
+ });
66
+ it('expands the iteration marks, before the letter written out on a tie', () => {
67
+ expect(sameJapaneseBase('いすゞ', 'いすず')).toBe(true);
68
+ expect(sameJapaneseBase('こゝろ', 'こころ')).toBe(true);
69
+ expect(sameJapaneseBase('ハヽ', 'はは')).toBe(true);
70
+ expect(sorted(['いすず', 'いすゞ'])).toEqual(['いすゞ', 'いすず']);
71
+ // ー < small < iteration < large.
72
+ expect(sorted(['ああ', 'あゝ', 'あぁ', 'あー'])).toEqual(['あー', 'あぁ', 'あゝ', 'ああ']);
73
+ // かゝ reads かか: after かあ.
74
+ expect(sorted(['かゝ', 'かあ'])).toEqual(['かあ', 'かゝ']);
75
+ });
76
+ it('orders the gojūon rows, ん last', () => {
77
+ const letters = [...GOJUON];
78
+ expect(sorted([...letters].reverse())).toEqual(letters);
79
+ expect(letters.slice(-5)).toEqual(['わ', 'ゐ', 'ゑ', 'を', 'ん']);
80
+ expect(GOJUON_ROWS.map((r) => GOJUON[r.start])).toEqual([...'あかさたなはまやらわ']);
81
+ expect([...'あおかこさそたとなのはほまもやよらろわん'].map((c) => gojuonRow(GOJUON.indexOf(c))))
82
+ .toEqual([0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9]);
83
+ });
84
+ it('sets symbols, digits, Latin, kana, kanji and geta in that order; digit runs by value', () => {
85
+ expect(sorted(['漢字', 'かな', 'Latin', '10章', '2章', '〓', '「題」', ' 空白']))
86
+ .toEqual([' 空白', '「題」', '2章', '10章', 'Latin', 'かな', '漢字', '〓']);
87
+ // Fullwidth and halfwidth forms fold (NFKC).
88
+ expect(sameJapaneseBase('ABC', 'abc')).toBe(true);
89
+ expect(sameJapaneseBase('ガク', 'がく')).toBe(true);
90
+ expect(sorted(['10', '9'])).toEqual(['9', '10']);
91
+ expect(['かな', 'abc', '12', '・', '漢', 'ーあ'].map((k) => japaneseLead(k).kind))
92
+ .toEqual(['kana', 'latin', 'digit', 'symbol', 'kanji', 'symbol']);
93
+ });
94
+ });
95
+ describe('index.groupBy gojuon and kana', () => {
96
+ const outline = () => [
97
+ markEntry(['夏目漱石'], 1, { yomi: 'なつめそうせき' }),
98
+ markEntry(['芥川龍之介'], 2, { yomi: 'あくたがわりゅうのすけ' }),
99
+ markEntry(['森鷗外'], 3, { yomi: 'もりおうがい' }),
100
+ markEntry(['カメラ'], 4),
101
+ markEntry(['樋口一葉'], 5, { yomi: 'ひぐちいちよう' }),
102
+ markEntry(['ガラス'], 6),
103
+ markEntry(['吾輩は猫である'], 7, { yomi: 'わがはいはねこである' }),
104
+ markEntry(['坊っちゃん'], 8, { yomi: 'ぼっちゃん' }),
105
+ markEntry(['こころ'], 9),
106
+ ];
107
+ it('auto groups a Japanese index by gojūon row', () => {
108
+ expect(build({ locale: 'ja' }, outline())).toEqual([
109
+ '[あ行] 芥川龍之介, 3',
110
+ // ガラス reads からす, after カメラ (かめら): め comes before ら.
111
+ '[か行] カメラ, 5', 'ガラス, 7', 'こころ, 10',
112
+ '[な行] 夏目漱石, 2',
113
+ '[は行] 樋口一葉, 6', '坊っちゃん, 9',
114
+ '[ま行] 森鷗外, 4',
115
+ '[わ行] 吾輩は猫である, 8',
116
+ ]);
117
+ expect(build({ locale: 'ja-JP' }, outline())).toEqual(build({ locale: 'ja', index: { groupBy: 'gojuon' } }, outline()));
118
+ expect(expand({ locale: 'ja' }, outline()).warnings).toEqual([]);
119
+ });
120
+ it('kana grouping heads each kana; letter does the same in Japanese', () => {
121
+ const kana = build({ locale: 'ja', index: { groupBy: 'kana' } }, outline());
122
+ expect(kana).toEqual([
123
+ '[あ] 芥川龍之介, 3', '[か] カメラ, 5', 'ガラス, 7', '[こ] こころ, 10', '[な] 夏目漱石, 2',
124
+ '[ひ] 樋口一葉, 6', '[ほ] 坊っちゃん, 9', '[も] 森鷗外, 4', '[わ] 吾輩は猫である, 8',
125
+ ]);
126
+ expect(build({ locale: 'ja', index: { groupBy: 'letter' } }, outline())).toEqual(kana);
127
+ });
128
+ it('none sets no heads, in reading order', () => {
129
+ expect(build({ locale: 'ja', index: { groupBy: 'none' } }, outline())).toEqual([
130
+ '芥川龍之介, 3', 'カメラ, 5', 'ガラス, 7', 'こころ, 10', '夏目漱石, 2', '樋口一葉, 6', '坊っちゃん, 9', '森鷗外, 4', '吾輩は猫である, 8',
131
+ ]);
132
+ });
133
+ it('files symbols, numbers and Latin before the kana, unread kanji after them', () => {
134
+ const list = [
135
+ markEntry(['東京'], 1, { yomi: 'とうきょう' }),
136
+ markEntry(['JIS X 4061'], 2),
137
+ markEntry(['2進法'], 3, { yomi: '2しんほう' }),
138
+ markEntry(['「こころ」'], 4),
139
+ markEntry(['京都'], 5),
140
+ markEntry(['Unicode'], 6),
141
+ markEntry(['大阪'], 7),
142
+ markEntry(['あんず'], 8),
143
+ ];
144
+ const labels = { groups: { symbolsLabel: '記号', numbersLabel: '数字' } };
145
+ expect(build({ locale: 'ja', index: labels }, list)).toEqual([
146
+ '[記号] 「こころ」, 5',
147
+ '[数字] 2進法, 4',
148
+ '[J] JIS X 4061, 3', '[U] Unicode, 7',
149
+ '[あ行] あんず, 9', '[た行] 東京, 2',
150
+ // No reading: after the kana, with no head, by code point.
151
+ '+ 京都, 6', '大阪, 8',
152
+ ]);
153
+ expect(expand({ locale: 'ja' }, list).warnings).toMatchObject([
154
+ { kind: 'indexReadingMissing', term: '京都', index: '' },
155
+ { kind: 'indexReadingMissing', term: '大阪', index: '' },
156
+ ]);
157
+ });
158
+ it('reads yomi first, then the ruby of the marked text, then sort', () => {
159
+ const list = [
160
+ // The reading wins over a sort key.
161
+ markEntry(['日本'], 1, { yomi: 'にほん', sort: 'やまと' }),
162
+ markEntry(['大和'], 2, { rubyYomi: 'やまと', sort: 'だいわ' }),
163
+ markEntry(['生田'], 3, { sort: 'いくた' }),
164
+ ];
165
+ expect(build({ locale: 'ja' }, list)).toEqual(['[あ行] 生田, 4', '[な行] 日本, 2', '[や行] 大和, 3']);
166
+ // A sort key with a kanji is no reading.
167
+ expect(expand({ locale: 'ja' }, [markEntry(['重陽'], 1, { sort: '重陽' })]).warnings)
168
+ .toMatchObject([{ kind: 'indexReadingMissing', term: '重陽' }]);
169
+ });
170
+ it('sorts sub-entries by their readings and names an unread one by its path', () => {
171
+ const list = [
172
+ markEntry(['漱石', '門'], 1, { yomi: 'もん' }),
173
+ markEntry(['漱石', '三四郎'], 2, { yomi: 'さんしろう' }),
174
+ markEntry(['漱石', 'それから'], 3),
175
+ markEntry(['漱石', '草枕'], 4),
176
+ markEntry(['漱石'], 5, { yomi: 'そうせき' }),
177
+ ];
178
+ expect(build({ locale: 'ja' }, list)).toEqual(['[さ行] 漱石, 6', ' 三四郎, 3', ' それから, 4', ' 門, 2', ' 草枕, 5']);
179
+ expect(expand({ locale: 'ja' }, list).warnings).toMatchObject([{ kind: 'indexReadingMissing', term: '漱石!草枕', index: '' }]);
180
+ });
181
+ it('a gojūon grouping sorts by reading in any document language', () => {
182
+ expect(build({ locale: 'en', index: { groupBy: 'gojuon' } }, [markEntry(['東京'], 1, { yomi: 'とうきょう' }), markEntry(['青森'], 2, { yomi: 'あおもり' })]))
183
+ .toEqual(['[あ行] 青森, 3', '[た行] 東京, 2']);
184
+ // yomi alone sorts an index of another language like `sort`.
185
+ expect(build({}, [markEntry(['Zeta'], 1, { yomi: 'alpha' }), markEntry(['beta'], 2)])).toEqual(['[A] Zeta, 2', '[B] beta, 3']);
186
+ });
187
+ it('resolves auto per locale and keeps the new values', () => {
188
+ expect(['ja', 'ja-JP', 'ja_JP', 'ja-Jpan', 'zh', 'en'].map((l) => indexGrouping('auto', l)))
189
+ .toEqual(['gojuon', 'gojuon', 'gojuon', 'gojuon', 'pinyin', 'letter']);
190
+ expect(indexGrouping('kana', 'en')).toBe('kana');
191
+ const body = resolveBodyTextConfig(undefined);
192
+ expect(resolveIndexConfig({ groupBy: 'gojuon' }, body).groupBy).toBe('gojuon');
193
+ expect(resolveIndexConfig({ groupBy: 'kana' }, body).groupBy).toBe('kana');
194
+ expect(stripIndexDefaults({ groupBy: 'kana' })).toEqual({ groupBy: 'kana' });
195
+ });
196
+ });
197
+ describe('index marks: readings', () => {
198
+ const marksOf = (md) => parseMarkdown(md).flatMap((b) => b.indexMarks ?? []);
199
+ it('reads yomi and its alias reading', () => {
200
+ const marks = marksOf('漱石:index{term="夏目漱石" yomi="なつめそうせき"}と鷗外:index{term="森鷗外" reading=" もりおうがい "}。');
201
+ expect(marks.map((m) => [m.path[0], m.yomi])).toEqual([['夏目漱石', 'なつめそうせき'], ['森鷗外', 'もりおうがい']]);
202
+ });
203
+ it('takes the kana ruby of the marked text as its reading', () => {
204
+ const [mark] = marksOf('首都は:index[{東京|とう|きょう}]です。');
205
+ expect(mark.path).toEqual(['東京']);
206
+ expect(mark.rubyYomi).toBe('とうきょう');
207
+ // Kana outside the ruby joins the reading; ruby read in one group too.
208
+ expect(marksOf(':index[お{茶|ちゃ}]')[0].rubyYomi).toBe('おちゃ');
209
+ expect(marksOf(':index[{明日|あした}]')[0].rubyYomi).toBe('あした');
210
+ // The paragraph keeps the ruby.
211
+ const [b] = parseMarkdown('首都は:index[{東京|とう|きょう}]です。');
212
+ expect(b.text).toBe('首都は東京です。');
213
+ expect(b.spans.some((s) => s.ruby)).toBe(true);
214
+ });
215
+ it('gives no ruby reading when a kanji stays unread, a reading is not kana, or the text is not the entry', () => {
216
+ expect(marksOf(':index[{東京|とう|きょう}駅]')[0].rubyYomi).toBeUndefined();
217
+ expect(marksOf(':index[{紅樓|hóng|lóu}]')[0].rubyYomi).toBeUndefined();
218
+ expect(marksOf(':index[{東京|とう|きょう}]{sub="地下鉄"}')[0].rubyYomi).toBeUndefined();
219
+ expect(marksOf(':index[{東京|とう|きょう}]{term="首都"}')[0].rubyYomi).toBeUndefined();
220
+ // An explicit yomi makes the ruby reading moot.
221
+ expect(marksOf(':index[{東京|とう|きょう}]{yomi="とうけい"}')[0]).toMatchObject({ yomi: 'とうけい' });
222
+ expect(marksOf(':index[{東京|とう|きょう}]{yomi="とうけい"}')[0].rubyYomi).toBeUndefined();
223
+ });
224
+ it('carries the readings through the outline into the index', () => {
225
+ const md = '# 本文\n\n:index[{東京|とう|きょう}]、:index[青森]{yomi="あおもり"}、:index[京都]。\n\n# 索引\n\n:::index';
226
+ const outline = computeOutline(parseMarkdown(md), resolveAllConfig({ ...base, locale: 'ja' }));
227
+ expect(outline.filter((e) => e.indexMark).map((e) => [e.title, e.indexMark.yomi ?? e.indexMark.rubyYomi ?? null]))
228
+ .toEqual([['東京', 'とうきょう'], ['青森', 'あおもり'], ['京都', null]]);
229
+ const doc = buildDocument({ markdown: md }, { ...base, locale: 'ja' });
230
+ const warnings = (doc.contentWarnings ?? []).filter((w) => w.kind === 'indexReadingMissing');
231
+ expect(warnings).toMatchObject([{ kind: 'indexReadingMissing', term: '京都', index: '' }]);
232
+ const lines = doc.blocks.flatMap((b) => b.lines.map((l) => l.text));
233
+ const from = lines.indexOf('索引');
234
+ expect(from).toBeGreaterThan(0);
235
+ const at = (s) => lines.findIndex((l, i) => i > from && l.startsWith(s));
236
+ expect(at('あ行')).toBeLessThan(at('青森'));
237
+ expect(at('青森')).toBeLessThan(at('た行'));
238
+ expect(at('た行')).toBeLessThan(at('東京'));
239
+ expect(at('東京')).toBeLessThan(at('京都'));
240
+ });
241
+ });
242
+ //# sourceMappingURL=indexJapanese.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexJapanese.test.js","sourceRoot":"","sources":["../../src/__tests__/indexJapanese.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=japaneseHeadings.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"japaneseHeadings.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/japaneseHeadings.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,319 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { buildDocument } from '../pipeline';
3
+ import { resolveHeadingsConfig, stripHeadingsDefaults } from '../defaults/headings';
4
+ import { resolveParagraphStylesConfig, stripParagraphStylesDefaults } from '../defaults/paragraphStyles';
5
+ import { resolveBodyTextConfig } from '../defaults/bodyText';
6
+ import { resolveAllConfig } from '../pipeline/config';
7
+ import { renderToHtml } from '../html-backend';
8
+ import { installSizedStub } from './vertical/stub';
9
+ // Japanese headings and blocks (#424): 行取り (`lineSpan`), 字下げ (a
10
+ // heading's `indent` in body ems), 字取り (`jidori`), 地付き / 地からN字上げ
11
+ // (`endIndent`, `:::paragraphs{align=end endIndent=N}`), ページの左右中央
12
+ // (`:::pagebreak{center}`) and the even-page exception to keep-with-next
13
+ // (`headings.keepWithNextSpread`). The stub measures kana and kanji 1 em,
14
+ // Latin ½ em; the ideographic centre of every face sits 0.38 em above the
15
+ // baseline.
16
+ installSizedStub();
17
+ const pt = (value) => ({ value, unit: 'pt' });
18
+ const em = (value) => ({ value, unit: 'em' });
19
+ /** 72 dpi: a 10 px body on a 17.5 px pitch (1.75 em, the bunko pitch), a
20
+ * measure of 20 characters and 10 lines a page. */
21
+ const PITCH = 17.5;
22
+ const BODY = 10;
23
+ const config = (extra = {}, levels = []) => ({
24
+ locale: 'ja',
25
+ page: { width: pt(240), height: pt(215), dpi: 72, margins: { top: pt(20), bottom: pt(20), left: pt(20), right: pt(20) } },
26
+ layout: { layoutType: 'single' },
27
+ header: { elements: [] },
28
+ footer: { elements: [] },
29
+ bodyText: { fontSize: pt(BODY), lineHeight: pt(PITCH), textAlign: 'justify', firstLineIndent: pt(0) },
30
+ headings: {
31
+ levels: [
32
+ { level: 1, breakBefore: { enabled: false } },
33
+ { level: 2, fontSize: pt(14), lineHeight: pt(21), marginTop: pt(7), marginBottom: pt(3) },
34
+ ].filter((l) => !levels.some((o) => o.level === l.level)).concat(levels),
35
+ },
36
+ ...extra,
37
+ });
38
+ /** `c` with its headings changed by `patch`. */
39
+ const headingsWith = (c, patch) => ({ ...c, headings: { ...c.headings, ...patch } });
40
+ /** The same type area set vertically: the sheet turned, so a line still
41
+ * holds 20 characters and a page 10 lines. */
42
+ const vertical = (extra = {}, levels = []) => {
43
+ const c = config(extra, levels);
44
+ return { ...c, page: { ...c.page, width: pt(215), height: pt(240) }, layout: { ...c.layout, writingMode: 'vertical-rl' } };
45
+ };
46
+ /** 20 kana: one full line of the measure. */
47
+ const LINE = 'あいうえおかきくけこさしすせそたちつてと';
48
+ const heading = (doc, text) => doc.blocks.find((b) => b.type === 'heading' && (text === undefined || b.lines.some((l) => l.text.includes(text))));
49
+ const paragraphs = (doc) => doc.blocks.filter((b) => b.type === 'paragraph');
50
+ const firstLine = (b) => b.lines[0];
51
+ const columnTop = (doc, b) => doc.pages[b.pageIndex].columns[b.columnIndex ?? 0].bbox.y;
52
+ /** The centre of a horizontal line's characters: its baseline less the
53
+ * face's ideographic centre (0.38 em of the stub). */
54
+ const axis = (line, sizePx) => line.baseline - 0.38 * sizePx;
55
+ describe('行取り: a heading takes N body lines (lineSpan)', () => {
56
+ const span3 = { level: 2, fontSize: pt(14), lineHeight: pt(21), marginTop: pt(7), marginBottom: pt(3), lineSpan: 3 };
57
+ it('holds three grid lines in horizontal text, its characters centred across them', () => {
58
+ const doc = buildDocument({ markdown: `${LINE}${LINE}\n\n## 第一章\n\n${LINE}` }, config({}, [span3]));
59
+ const h = heading(doc);
60
+ const [before, after] = paragraphs(doc);
61
+ const top = columnTop(doc, h);
62
+ // The band opens on the grid line under the paragraph and is three
63
+ // lines tall: the text under it is back on the grid.
64
+ expect(h.bbox.y - top).toBeCloseTo(2 * PITCH, 6);
65
+ expect(h.bbox.height).toBeCloseTo(3 * PITCH, 6);
66
+ expect(firstLine(after).bbox.y - top).toBeCloseTo(5 * PITCH, 6);
67
+ expect(before.lines).toHaveLength(2);
68
+ // Centred as JLReq measures it: the heading's characters halfway
69
+ // between the first and the last body character of the band.
70
+ const bandCentre = h.bbox.y + 0.8 * PITCH - 0.38 * BODY + PITCH;
71
+ expect(axis(firstLine(h), 14)).toBeCloseTo(bandCentre, 6);
72
+ });
73
+ it('keeps its band at the head of a column, where margins vanish', () => {
74
+ const doc = buildDocument({ markdown: `## 第一章\n\n${LINE}` }, config({}, [span3]));
75
+ const h = heading(doc);
76
+ expect(h.bbox.y).toBeCloseTo(columnTop(doc, h), 6);
77
+ expect(firstLine(paragraphs(doc)[0]).bbox.y - h.bbox.y).toBeCloseTo(3 * PITCH, 6);
78
+ expect(axis(firstLine(h), 14)).toBeCloseTo(h.bbox.y + 0.8 * PITCH - 0.38 * BODY + PITCH, 6);
79
+ });
80
+ it('grows to the next whole number of lines when its lines need more room', () => {
81
+ // Two lines of 21 px do not fit one 17.5 px line: three lines.
82
+ const two = { ...span3, lineSpan: 1 };
83
+ const title = 'ながいながいみだしのぶんしょうがつづきますよ';
84
+ const doc = buildDocument({ markdown: `${LINE}\n\n## ${title}\n\n${LINE}` }, config({}, [two]));
85
+ const h = heading(doc);
86
+ expect(h.lines).toHaveLength(2);
87
+ expect(h.bbox.height).toBeCloseTo(3 * PITCH, 6);
88
+ expect(firstLine(paragraphs(doc)[1]).bbox.y - h.bbox.y).toBeCloseTo(3 * PITCH, 6);
89
+ // Its two lines stay together, centred as a block.
90
+ expect(h.lines[1].bbox.y - h.lines[0].bbox.y).toBeCloseTo(21, 6);
91
+ });
92
+ it('centres a vertical heading across its band', () => {
93
+ const doc = buildDocument({ markdown: `${LINE}\n\n## 第一章\n\n${LINE}` }, vertical({}, [span3]));
94
+ const h = heading(doc);
95
+ const top = columnTop(doc, h);
96
+ expect(h.bbox.y - top).toBeCloseTo(PITCH, 6);
97
+ expect(h.bbox.height).toBeCloseTo(3 * PITCH, 6);
98
+ // A vertical line's characters stand in the middle of its line box.
99
+ const line = firstLine(h);
100
+ expect(line.bbox.y + line.bbox.height / 2).toBeCloseTo(h.bbox.y + 1.5 * PITCH, 6);
101
+ expect(firstLine(paragraphs(doc)[1]).bbox.y - top).toBeCloseTo(4 * PITCH, 6);
102
+ });
103
+ it('keeps the character grid (cjk.grid)', () => {
104
+ const grid = { cjk: { grid: { enabled: true, charsPerLine: 20, linesPerPage: 10 } } };
105
+ for (const c of [config(grid, [span3]), vertical(grid, [span3])]) {
106
+ const doc = buildDocument({ markdown: `${LINE}\n\n## 序\n\n${LINE}${LINE}` }, c);
107
+ const h = heading(doc);
108
+ const top = columnTop(doc, h);
109
+ const pitch = 17.5;
110
+ expect((h.bbox.y - top) / pitch).toBeCloseTo(1, 6);
111
+ expect(h.bbox.height / pitch).toBeCloseTo(3, 6);
112
+ for (const line of paragraphs(doc)[1].lines)
113
+ expect(((line.bbox.y - top) / pitch) % 1).toBeCloseTo(0, 6);
114
+ }
115
+ });
116
+ it('starts where the flow is when the heading does not snap to the grid', () => {
117
+ const off = { ...span3, snapToGrid: false };
118
+ const doc = buildDocument({ markdown: `:::paragraphs{style="tight"}\n${LINE}\n:::\n\n## 第一章\n\n${LINE}` }, config({
119
+ paragraphStyles: [{ id: 'tight', lineHeight: pt(15), snapToGrid: false }],
120
+ }, [off]));
121
+ const h = heading(doc);
122
+ expect(h.bbox.y - columnTop(doc, h)).toBeCloseTo(15, 6);
123
+ expect(h.bbox.height).toBeCloseTo(3 * PITCH, 6);
124
+ });
125
+ it('is not read by a page opener or a hidden heading, and leaves other headings as they were', () => {
126
+ const plain = buildDocument({ markdown: `${LINE}\n\n## 第一章\n\n${LINE}` }, config());
127
+ const h = heading(plain);
128
+ expect(h.bbox.y - columnTop(plain, h)).toBeCloseTo(PITCH + 7, 6);
129
+ const opener = buildDocument({ markdown: `# 序\n\n${LINE}` }, config({}, [{ level: 1, span: 'page', breakBefore: { enabled: true }, lineSpan: 3, fontSize: pt(14), lineHeight: pt(21) }]));
130
+ expect(heading(opener).bbox.height).not.toBeCloseTo(3 * PITCH, 3);
131
+ });
132
+ it('resolves and strips only when set', () => {
133
+ expect('lineSpan' in resolveHeadingsConfig({}).levels[1]).toBe(false);
134
+ const r = resolveHeadingsConfig({ levels: [{ level: 2, lineSpan: 3, indent: em(4), jidori: 3 }, { level: 3, lineSpan: 0, jidori: 1 }] });
135
+ expect(r.levels[1]).toMatchObject({ lineSpan: 3, indent: em(4), jidori: 3 });
136
+ expect('lineSpan' in r.levels[2] || 'jidori' in r.levels[2]).toBe(false);
137
+ expect(stripHeadingsDefaults({ levels: [{ level: 2, lineSpan: 3, indent: em(0) }] })).toEqual({ levels: [{ level: 2, lineSpan: 3 }] });
138
+ expect(stripHeadingsDefaults({ keepWithNextSpread: false })).toBeUndefined();
139
+ expect(stripHeadingsDefaults({ keepWithNextSpread: true })).toEqual({ keepWithNextSpread: true });
140
+ expect('keepWithNextSpread' in resolveAllConfig(config()).headings).toBe(false);
141
+ });
142
+ it('is set by a heading style, which may take it off', () => {
143
+ const cfg = config({
144
+ headingStyles: [{ id: 'gyo', lineSpan: 2 }, { id: 'none', lineSpan: 0 }],
145
+ }, [span3]);
146
+ const markdown = `## 甲 {style="gyo"}\n\n${LINE}\n\n## 乙 {style="none"}\n\n${LINE}`;
147
+ const doc = buildDocument({ markdown }, cfg);
148
+ const plain = buildDocument({ markdown }, { ...config(), headingStyles: [{ id: 'gyo' }, { id: 'none' }] });
149
+ expect(heading(doc, '甲').bbox.height).toBeCloseTo(2 * PITCH, 6);
150
+ expect(heading(doc, '乙').bbox).toEqual(heading(plain, '乙').bbox);
151
+ expect(heading(doc, '乙').lines[0].baseline).toBeCloseTo(heading(plain, '乙').lines[0].baseline, 6);
152
+ });
153
+ });
154
+ describe('字下げ: a heading indented in body ems (indent)', () => {
155
+ it('moves the heading off the line start by body characters, in both writing modes', () => {
156
+ const lvl = { level: 2, fontSize: pt(14), lineHeight: pt(21), indent: em(4) };
157
+ for (const c of [config({}, [lvl]), vertical({}, [lvl])]) {
158
+ const doc = buildDocument({ markdown: `## 上 先生と私\n\n${LINE}` }, c);
159
+ const h = heading(doc);
160
+ // 4 body ems (40 px), not 4 heading ems (56 px).
161
+ expect(firstLine(h).bbox.x - h.bbox.x).toBeCloseTo(4 * BODY, 6);
162
+ }
163
+ });
164
+ it('narrows the measure: a centred heading centres in what is left', () => {
165
+ const lvl = { level: 2, fontSize: pt(14), lineHeight: pt(21), indent: em(4) };
166
+ const doc = buildDocument({ markdown: `## 一\n\n${LINE}` }, headingsWith(config({}, [lvl]), { textAlign: 'center' }));
167
+ const h = heading(doc);
168
+ // The renderers centre a line in the room from its start to the end of
169
+ // its block: from the indent on.
170
+ expect(h.textAlign).toBe('center');
171
+ expect(firstLine(h).bbox.x - h.bbox.x).toBeCloseTo(4 * BODY, 6);
172
+ const html = renderToHtml(doc);
173
+ const left = Number(/left:([\d.]+)px;[^"]*">一</.exec(html)?.[1]);
174
+ expect(left).toBeCloseTo((h.bbox.width - 4 * BODY - 14) / 2, 2);
175
+ // 14 characters of 14 px fit what is left of the 20-character measure.
176
+ const long = buildDocument({ markdown: `## ${'見'.repeat(12)}\n\n${LINE}` }, config({}, [lvl]));
177
+ expect(heading(long).lines).toHaveLength(2);
178
+ });
179
+ });
180
+ describe('字取り: a short heading spaced to a width (jidori)', () => {
181
+ const lvl = { level: 2, fontSize: pt(14), lineHeight: pt(21), jidori: 3 };
182
+ it('spaces 序章 to three characters: 序 章', () => {
183
+ for (const c of [config({}, [lvl]), vertical({}, [lvl])]) {
184
+ const doc = buildDocument({ markdown: `## 序章\n\n${LINE}` }, c);
185
+ const h = heading(doc);
186
+ // Two characters, one gap of a whole heading em between them.
187
+ expect(h.letterSpacing).toBeCloseTo(14, 6);
188
+ // The advance holds the tracking after the last character, which the
189
+ // renderers leave out of the alignment (EF-153): 28 + 2 × 14.
190
+ expect(firstLine(h).bbox.width).toBeCloseTo(56, 6);
191
+ }
192
+ });
193
+ it('spreads four characters to five with a third of an em between them, a heading attribute overriding the level', () => {
194
+ const doc = buildDocument({ markdown: `## 終わりに {jidori=5}\n\n${LINE}` }, config({}, [lvl]));
195
+ const h = heading(doc);
196
+ // 4 characters to 5 ems: three gaps of a third of an em.
197
+ expect(h.letterSpacing).toBeCloseTo(14 / 3, 6);
198
+ });
199
+ it('leaves a heading as wide as the width or wider, and one the attribute turns off', () => {
200
+ const doc = buildDocument({ markdown: `## 第一章\n\n${LINE}\n\n## 序章 {jidori=0}\n\n${LINE}` }, config({}, [lvl]));
201
+ expect(heading(doc, '第一章').letterSpacing).toBeUndefined();
202
+ expect(heading(doc, '序章').letterSpacing).toBeUndefined();
203
+ });
204
+ it('counts a numbering prefix as part of the heading', () => {
205
+ const doc = buildDocument({ markdown: `## 序\n\n${LINE}` }, config({}, [{ ...lvl, numberingTemplate: '{2}', numberSeparator: '' }]));
206
+ // "1序": a half-em digit, the quarter em set between a Latin digit and
207
+ // a kanji, and the kanji: 24.5 px, spread to 42 px in one gap.
208
+ expect(heading(doc).letterSpacing).toBeCloseTo(17.5, 6);
209
+ });
210
+ });
211
+ describe('地付き and 地からN字上げ: lines set to the end, raised from it', () => {
212
+ /** How far short of the column's end side a block's box stops: the
213
+ * renderers align and justify its lines against that box. */
214
+ const lineEnd = (doc, b) => {
215
+ const col = doc.pages[b.pageIndex].columns[0];
216
+ return col.bbox.x + col.bbox.width - (b.bbox.x + b.bbox.width);
217
+ };
218
+ it('a fence attribute sets the date flush with the foot, the signature a character above it', () => {
219
+ for (const c of [config(), vertical()]) {
220
+ const doc = buildDocument({ markdown: `${LINE}\n\n:::paragraphs{align=end}\n十月五日\n:::\n\n:::paragraphs{align=end endIndent=1}\n先生より\n:::` }, c);
221
+ const [, date, signature] = paragraphs(doc);
222
+ expect(date.textAlign).toBe('right');
223
+ expect(lineEnd(doc, date)).toBeCloseTo(0, 6);
224
+ expect(lineEnd(doc, signature)).toBeCloseTo(BODY, 6);
225
+ expect(signature.textAlign).toBe('right');
226
+ // The text after the fences is back on the grid.
227
+ expect((firstLine(signature).bbox.y - columnTop(doc, signature)) / PITCH % 1).toBeCloseTo(0, 6);
228
+ }
229
+ });
230
+ it('a paragraph style does the same with endIndent, which narrows the measure', () => {
231
+ const doc = buildDocument({ markdown: `:::paragraphs{style="sign"}\n${LINE}${LINE}\n:::` }, config({
232
+ paragraphStyles: [{ id: 'sign', endIndent: em(2), textAlign: 'end' }],
233
+ }));
234
+ const [p] = paragraphs(doc);
235
+ // 18 characters a line: 40 characters take three lines.
236
+ expect(p.lines).toHaveLength(3);
237
+ expect(lineEnd(doc, p)).toBeCloseTo(2 * BODY, 6);
238
+ // Painted: the last line, set ragged, ends 2 characters short of the
239
+ // column's end.
240
+ const tail = p.lines.at(-1).text;
241
+ const left = Number(new RegExp(`left:([\\d.]+)px;[^"]*">${tail}<`).exec(renderToHtml(doc))?.[1]);
242
+ expect(left).toBeCloseTo(200 - 2 * BODY - BODY * tail.length, 2);
243
+ });
244
+ it('an inner fence takes the enclosing style (a letter indented 1字, its signature raised 2字)', () => {
245
+ const doc = buildDocument({ markdown: `:::paragraphs{style="letter"}\n${LINE}\n\n:::paragraphs{align=end endIndent=2}\nKより\n:::\n:::` }, config({
246
+ paragraphStyles: [{ id: 'letter', indent: em(1), color: { hex: '#333333', model: 'hex' } }],
247
+ }));
248
+ const [body, sign] = paragraphs(doc);
249
+ expect(firstLine(body).bbox.x - body.bbox.x).toBeCloseTo(BODY, 6);
250
+ expect(sign.color).toBe('#333333');
251
+ expect(sign.paragraphStyleId).toBe('letter');
252
+ expect(lineEnd(doc, sign)).toBeCloseTo(2 * BODY, 6);
253
+ });
254
+ it('resolves endIndent only when set', () => {
255
+ const body = resolveBodyTextConfig(undefined);
256
+ const [plain, raised] = resolveParagraphStylesConfig([{ id: 'a' }, { id: 'b', endIndent: em(1) }], body);
257
+ expect('endIndent' in plain).toBe(false);
258
+ expect(raised.endIndent).toEqual(em(1));
259
+ expect(stripParagraphStylesDefaults([{ id: 'a', endIndent: em(0) }, { id: 'b', endIndent: em(1) }])).toEqual([{ id: 'a' }, { id: 'b', endIndent: em(1) }]);
260
+ });
261
+ });
262
+ describe('ページの左右中央: a page centred in the block direction (:::pagebreak{center})', () => {
263
+ it('centres the text of the page the break opens, in both writing modes', () => {
264
+ for (const c of [config(), vertical()]) {
265
+ const doc = buildDocument({ markdown: `${LINE}\n\n:::pagebreak{center}\n\n亡き友に\n\n:::pagebreak\n\n${LINE}` }, c);
266
+ const dedication = paragraphs(doc)[1];
267
+ expect(dedication.pageIndex).toBe(1);
268
+ const col = doc.pages[1].columns[0];
269
+ const line = firstLine(dedication);
270
+ expect(line.bbox.y + line.bbox.height / 2).toBeCloseTo(col.bbox.y + col.bbox.height / 2, 6);
271
+ // The other pages keep their text at the head.
272
+ expect(firstLine(paragraphs(doc)[2]).bbox.y).toBeCloseTo(doc.pages[2].columns[0].bbox.y, 6);
273
+ }
274
+ });
275
+ it('moves a page of several blocks as one, and leaves a full page alone', () => {
276
+ const doc = buildDocument({ markdown: `:::pagebreak{center}\n\n## 献辞\n\n亡き友に\n\nこの書を捧ぐ` }, config());
277
+ const [h, a, b] = [heading(doc), ...paragraphs(doc)];
278
+ const col = doc.pages[0].columns[0];
279
+ const top = firstLine(h).bbox.y;
280
+ const bottom = firstLine(b).bbox.y + PITCH;
281
+ expect((top + bottom) / 2).toBeCloseTo(col.bbox.y + col.bbox.height / 2, 6);
282
+ expect(firstLine(b).bbox.y - firstLine(a).bbox.y).toBeCloseTo(PITCH, 6);
283
+ const full = buildDocument({ markdown: `:::pagebreak{center}\n\n${LINE.repeat(10)}` }, config());
284
+ expect(firstLine(paragraphs(full)[0]).bbox.y).toBeCloseTo(full.pages[0].columns[0].bbox.y, 6);
285
+ });
286
+ it('is off without the attribute and with center=false', () => {
287
+ for (const md of [`${LINE}\n\n:::pagebreak\n\n亡き友に`, `${LINE}\n\n:::pagebreak{center=false}\n\n亡き友に`]) {
288
+ const doc = buildDocument({ markdown: md }, config());
289
+ expect(firstLine(paragraphs(doc)[1]).bbox.y).toBeCloseTo(doc.pages[1].columns[0].bbox.y, 6);
290
+ }
291
+ });
292
+ });
293
+ describe('a heading never ends a page, except at the foot of an even page (keepWithNextSpread)', () => {
294
+ /** A one-line heading, no margins: it takes exactly one grid line. */
295
+ const flat = { level: 2, fontSize: pt(BODY), lineHeight: pt(PITCH), marginTop: pt(0), marginBottom: pt(0) };
296
+ /** `lines` lines of text, then a heading and its text: the heading falls
297
+ * on line `lines + 1` of the flow. */
298
+ const markdown = (lines) => `${LINE.repeat(lines)}\n\n## 二\n\n${LINE.repeat(4)}`;
299
+ const both = [config({}, [flat]), vertical({}, [flat])].map((c) => headingsWith(c, { balancing: { enabled: false } }));
300
+ const withSpread = (c) => headingsWith(c, { keepWithNextSpread: true });
301
+ it('moves a heading off the foot of a page by default', () => {
302
+ for (const c of both)
303
+ expect(heading(buildDocument({ markdown: markdown(19) }, c)).pageIndex).toBe(2);
304
+ });
305
+ it('lets it close an even page with keepWithNextSpread: its text opens the facing page', () => {
306
+ for (const c of both) {
307
+ const doc = buildDocument({ markdown: markdown(19) }, withSpread(c));
308
+ const h = heading(doc);
309
+ expect(h.pageIndex).toBe(1);
310
+ expect(h.bbox.y - columnTop(doc, h)).toBeCloseTo(9 * PITCH, 6);
311
+ expect(paragraphs(doc).at(-1).pageIndex).toBe(2);
312
+ }
313
+ });
314
+ it('still moves it off an odd page', () => {
315
+ for (const c of both)
316
+ expect(heading(buildDocument({ markdown: markdown(29) }, withSpread(c))).pageIndex).toBe(3);
317
+ });
318
+ });
319
+ //# sourceMappingURL=japaneseHeadings.test.js.map