@kensio/colophon 2.3.0 → 2.4.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 (301) hide show
  1. package/README.md +62 -801
  2. package/dist/background.d.ts +7 -2
  3. package/dist/background.d.ts.map +1 -1
  4. package/dist/background.js +44 -1
  5. package/dist/background.js.map +1 -1
  6. package/dist/cli/args.d.ts +1 -1
  7. package/dist/cli/args.d.ts.map +1 -1
  8. package/dist/cli/args.js +1 -1
  9. package/dist/cli/config.d.ts +1 -1
  10. package/dist/cli/config.js +1 -1
  11. package/dist/config/defaults.d.ts +8 -7
  12. package/dist/config/defaults.d.ts.map +1 -1
  13. package/dist/config/defaults.js +8 -8
  14. package/dist/config/defaults.js.map +1 -1
  15. package/dist/config/index.d.ts.map +1 -1
  16. package/dist/config/index.js +5 -3
  17. package/dist/config/index.js.map +1 -1
  18. package/dist/config/resolve.d.ts +7 -0
  19. package/dist/config/resolve.d.ts.map +1 -1
  20. package/dist/config/resolve.js +16 -0
  21. package/dist/config/resolve.js.map +1 -1
  22. package/dist/config/size.d.ts +1 -1
  23. package/dist/config/size.d.ts.map +1 -1
  24. package/dist/config/size.js +3 -2
  25. package/dist/config/size.js.map +1 -1
  26. package/dist/content/props.d.ts +2 -2
  27. package/dist/content/props.js +2 -2
  28. package/dist/content/slug.d.ts +5 -5
  29. package/dist/content/slug.js +6 -6
  30. package/dist/content/slug.js.map +1 -1
  31. package/dist/content/walk.d.ts +1 -1
  32. package/dist/content/walk.js +1 -1
  33. package/dist/fonts/index.d.ts +3 -2
  34. package/dist/fonts/index.d.ts.map +1 -1
  35. package/dist/fonts/index.js +3 -2
  36. package/dist/fonts/index.js.map +1 -1
  37. package/dist/fonts/resolve.js +1 -1
  38. package/dist/generate/extra.js +4 -4
  39. package/dist/generate/extra.js.map +1 -1
  40. package/dist/generate/options.d.ts +1 -1
  41. package/dist/generate/outputs.d.ts +4 -4
  42. package/dist/generate/outputs.js +4 -4
  43. package/dist/highlight/language.d.ts +2 -3
  44. package/dist/highlight/language.d.ts.map +1 -1
  45. package/dist/highlight/language.js +3 -4
  46. package/dist/highlight/language.js.map +1 -1
  47. package/dist/highlight/normalise.d.ts +2 -2
  48. package/dist/highlight/normalise.js +2 -2
  49. package/dist/image/index.d.ts +18 -0
  50. package/dist/image/index.d.ts.map +1 -0
  51. package/dist/image/index.js +42 -0
  52. package/dist/image/index.js.map +1 -0
  53. package/dist/image/jpeg.d.ts +10 -0
  54. package/dist/image/jpeg.d.ts.map +1 -0
  55. package/dist/image/jpeg.js +57 -0
  56. package/dist/image/jpeg.js.map +1 -0
  57. package/dist/image/load.d.ts +4 -0
  58. package/dist/image/load.d.ts.map +1 -0
  59. package/dist/image/load.js +60 -0
  60. package/dist/image/load.js.map +1 -0
  61. package/dist/image/media.d.ts +10 -0
  62. package/dist/image/media.d.ts.map +1 -0
  63. package/dist/image/media.js +37 -0
  64. package/dist/image/media.js.map +1 -0
  65. package/dist/image/resolve.d.ts +13 -0
  66. package/dist/image/resolve.d.ts.map +1 -0
  67. package/dist/image/resolve.js +38 -0
  68. package/dist/image/resolve.js.map +1 -0
  69. package/dist/image/size.d.ts +22 -0
  70. package/dist/image/size.d.ts.map +1 -0
  71. package/dist/image/size.js +60 -0
  72. package/dist/image/size.js.map +1 -0
  73. package/dist/image/svg.d.ts +12 -0
  74. package/dist/image/svg.d.ts.map +1 -0
  75. package/dist/image/svg.js +61 -0
  76. package/dist/image/svg.js.map +1 -0
  77. package/dist/image/uri.d.ts +9 -0
  78. package/dist/image/uri.d.ts.map +1 -0
  79. package/dist/image/uri.js +22 -0
  80. package/dist/image/uri.js.map +1 -0
  81. package/dist/index.d.ts +6 -2
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +5 -1
  84. package/dist/index.js.map +1 -1
  85. package/dist/layout/block.d.ts +37 -0
  86. package/dist/layout/block.d.ts.map +1 -0
  87. package/dist/layout/block.js +26 -0
  88. package/dist/layout/block.js.map +1 -0
  89. package/dist/layout/box.d.ts +20 -0
  90. package/dist/layout/box.d.ts.map +1 -0
  91. package/dist/layout/box.js +61 -0
  92. package/dist/layout/box.js.map +1 -0
  93. package/dist/layout/distribute.d.ts +15 -0
  94. package/dist/layout/distribute.d.ts.map +1 -0
  95. package/dist/layout/distribute.js +30 -0
  96. package/dist/layout/distribute.js.map +1 -0
  97. package/dist/layout/image.d.ts +42 -0
  98. package/dist/layout/image.d.ts.map +1 -0
  99. package/dist/layout/image.js +34 -0
  100. package/dist/layout/image.js.map +1 -0
  101. package/dist/layout/index.d.ts +40 -0
  102. package/dist/layout/index.d.ts.map +1 -0
  103. package/dist/layout/index.js +30 -0
  104. package/dist/layout/index.js.map +1 -0
  105. package/dist/layout/lines.d.ts +45 -0
  106. package/dist/layout/lines.d.ts.map +1 -0
  107. package/dist/layout/lines.js +71 -0
  108. package/dist/layout/lines.js.map +1 -0
  109. package/dist/layout/measure.d.ts +11 -0
  110. package/dist/layout/measure.d.ts.map +1 -0
  111. package/dist/layout/measure.js +11 -0
  112. package/dist/layout/measure.js.map +1 -0
  113. package/dist/layout/panel.d.ts +20 -0
  114. package/dist/layout/panel.d.ts.map +1 -0
  115. package/dist/layout/panel.js +22 -0
  116. package/dist/layout/panel.js.map +1 -0
  117. package/dist/layout/row.d.ts +15 -0
  118. package/dist/layout/row.d.ts.map +1 -0
  119. package/dist/layout/row.js +20 -0
  120. package/dist/layout/row.js.map +1 -0
  121. package/dist/layout/scrim.d.ts +23 -0
  122. package/dist/layout/scrim.d.ts.map +1 -0
  123. package/dist/layout/scrim.js +38 -0
  124. package/dist/layout/scrim.js.map +1 -0
  125. package/dist/layout/stack.d.ts +14 -0
  126. package/dist/layout/stack.d.ts.map +1 -0
  127. package/dist/layout/stack.js +19 -0
  128. package/dist/layout/stack.js.map +1 -0
  129. package/dist/layout/types.d.ts +49 -0
  130. package/dist/layout/types.d.ts.map +1 -0
  131. package/dist/layout/types.js +2 -0
  132. package/dist/layout/types.js.map +1 -0
  133. package/dist/manifest/build.d.ts +1 -1
  134. package/dist/manifest/build.js +1 -1
  135. package/dist/manifest/index.d.ts +1 -1
  136. package/dist/manifest/index.js +1 -1
  137. package/dist/manifest/order.d.ts +1 -1
  138. package/dist/manifest/order.js +1 -1
  139. package/dist/manifest/page.d.ts +2 -2
  140. package/dist/manifest/page.js +3 -3
  141. package/dist/measure/estimate.d.ts +10 -0
  142. package/dist/measure/estimate.d.ts.map +1 -0
  143. package/dist/measure/estimate.js +58 -0
  144. package/dist/measure/estimate.js.map +1 -0
  145. package/dist/measure/faces.d.ts +15 -0
  146. package/dist/measure/faces.d.ts.map +1 -0
  147. package/dist/measure/faces.js +70 -0
  148. package/dist/measure/faces.js.map +1 -0
  149. package/dist/measure/index.d.ts +16 -0
  150. package/dist/measure/index.d.ts.map +1 -0
  151. package/dist/measure/index.js +0 -0
  152. package/dist/measure/index.js.map +1 -0
  153. package/dist/measure/runs.d.ts +17 -0
  154. package/dist/measure/runs.d.ts.map +1 -0
  155. package/dist/measure/runs.js +39 -0
  156. package/dist/measure/runs.js.map +1 -0
  157. package/dist/measure/select.d.ts +13 -0
  158. package/dist/measure/select.d.ts.map +1 -0
  159. package/dist/measure/select.js +47 -0
  160. package/dist/measure/select.js.map +1 -0
  161. package/dist/meta/tags.d.ts +6 -6
  162. package/dist/meta/tags.js +6 -6
  163. package/dist/meta/url.d.ts +4 -4
  164. package/dist/meta/url.js +4 -4
  165. package/dist/placement/check.d.ts +1 -1
  166. package/dist/placement/check.js +1 -1
  167. package/dist/placement/index.js +1 -1
  168. package/dist/placement/relative.d.ts +3 -3
  169. package/dist/placement/relative.js +3 -3
  170. package/dist/pool.d.ts +2 -2
  171. package/dist/pool.js +3 -3
  172. package/dist/pool.js.map +1 -1
  173. package/dist/props.d.ts +7 -0
  174. package/dist/props.d.ts.map +1 -0
  175. package/dist/props.js +17 -0
  176. package/dist/props.js.map +1 -0
  177. package/dist/render/svg.d.ts +4 -2
  178. package/dist/render/svg.d.ts.map +1 -1
  179. package/dist/render/svg.js +19 -4
  180. package/dist/render/svg.js.map +1 -1
  181. package/dist/stamp/config-digest.d.ts.map +1 -1
  182. package/dist/stamp/config-digest.js +20 -1
  183. package/dist/stamp/config-digest.js.map +1 -1
  184. package/dist/stamp/index.js +2 -2
  185. package/dist/stamp/index.js.map +1 -1
  186. package/dist/stamp/read.d.ts +1 -1
  187. package/dist/stamp/read.js +4 -4
  188. package/dist/templates/attribution.d.ts +17 -0
  189. package/dist/templates/attribution.d.ts.map +1 -0
  190. package/dist/templates/attribution.js +39 -0
  191. package/dist/templates/attribution.js.map +1 -0
  192. package/dist/templates/banner/badge.d.ts.map +1 -1
  193. package/dist/templates/banner/badge.js +3 -6
  194. package/dist/templates/banner/badge.js.map +1 -1
  195. package/dist/templates/banner/index.d.ts +3 -0
  196. package/dist/templates/banner/index.d.ts.map +1 -1
  197. package/dist/templates/banner/index.js +37 -35
  198. package/dist/templates/banner/index.js.map +1 -1
  199. package/dist/templates/banner/lines.d.ts +7 -12
  200. package/dist/templates/banner/lines.d.ts.map +1 -1
  201. package/dist/templates/banner/lines.js +23 -34
  202. package/dist/templates/banner/lines.js.map +1 -1
  203. package/dist/templates/banner/version.d.ts +9 -0
  204. package/dist/templates/banner/version.d.ts.map +1 -0
  205. package/dist/templates/banner/version.js +21 -0
  206. package/dist/templates/banner/version.js.map +1 -0
  207. package/dist/templates/card/index.d.ts +4 -1
  208. package/dist/templates/card/index.d.ts.map +1 -1
  209. package/dist/templates/card/index.js +37 -25
  210. package/dist/templates/card/index.js.map +1 -1
  211. package/dist/templates/card/lines.d.ts +17 -13
  212. package/dist/templates/card/lines.d.ts.map +1 -1
  213. package/dist/templates/card/lines.js +24 -20
  214. package/dist/templates/card/lines.js.map +1 -1
  215. package/dist/templates/code/chrome.d.ts +7 -3
  216. package/dist/templates/code/chrome.d.ts.map +1 -1
  217. package/dist/templates/code/chrome.js +12 -11
  218. package/dist/templates/code/chrome.js.map +1 -1
  219. package/dist/templates/code/clip.d.ts +1 -1
  220. package/dist/templates/code/clip.js +1 -1
  221. package/dist/templates/code/fit.d.ts +2 -2
  222. package/dist/templates/code/fit.d.ts.map +1 -1
  223. package/dist/templates/code/fit.js +4 -4
  224. package/dist/templates/code/fit.js.map +1 -1
  225. package/dist/templates/code/index.d.ts.map +1 -1
  226. package/dist/templates/code/index.js +7 -6
  227. package/dist/templates/code/index.js.map +1 -1
  228. package/dist/templates/code/layout.d.ts +1 -1
  229. package/dist/templates/code/layout.d.ts.map +1 -1
  230. package/dist/templates/code/layout.js +6 -6
  231. package/dist/templates/code/layout.js.map +1 -1
  232. package/dist/templates/code/panel.d.ts +13 -0
  233. package/dist/templates/code/panel.d.ts.map +1 -1
  234. package/dist/templates/code/panel.js +34 -2
  235. package/dist/templates/code/panel.js.map +1 -1
  236. package/dist/templates/code/plate.d.ts +3 -1
  237. package/dist/templates/code/plate.d.ts.map +1 -1
  238. package/dist/templates/code/plate.js +11 -9
  239. package/dist/templates/code/plate.js.map +1 -1
  240. package/dist/templates/code/spans.js +1 -1
  241. package/dist/templates/code/spans.js.map +1 -1
  242. package/dist/templates/code/width.d.ts +10 -0
  243. package/dist/templates/code/width.d.ts.map +1 -0
  244. package/dist/templates/code/width.js +26 -0
  245. package/dist/templates/code/width.js.map +1 -0
  246. package/dist/templates/footer.d.ts +8 -0
  247. package/dist/templates/footer.d.ts.map +1 -1
  248. package/dist/templates/footer.js +11 -1
  249. package/dist/templates/footer.js.map +1 -1
  250. package/dist/templates/index.d.ts +1 -1
  251. package/dist/templates/index.d.ts.map +1 -1
  252. package/dist/templates/index.js +1 -1
  253. package/dist/templates/index.js.map +1 -1
  254. package/dist/templates/logo.d.ts +15 -0
  255. package/dist/templates/logo.d.ts.map +1 -0
  256. package/dist/templates/logo.js +30 -0
  257. package/dist/templates/logo.js.map +1 -0
  258. package/dist/templates/measure.d.ts +11 -0
  259. package/dist/templates/measure.d.ts.map +1 -0
  260. package/dist/templates/measure.js +11 -0
  261. package/dist/templates/measure.js.map +1 -0
  262. package/dist/templates/props.d.ts +2 -2
  263. package/dist/templates/props.js +2 -2
  264. package/dist/templates/text.d.ts +37 -0
  265. package/dist/templates/text.d.ts.map +1 -0
  266. package/dist/templates/text.js +26 -0
  267. package/dist/templates/text.js.map +1 -0
  268. package/dist/text/break.d.ts +11 -0
  269. package/dist/text/break.d.ts.map +1 -0
  270. package/dist/text/break.js +30 -0
  271. package/dist/text/break.js.map +1 -0
  272. package/dist/text/fit.d.ts +30 -0
  273. package/dist/text/fit.d.ts.map +1 -0
  274. package/dist/text/fit.js +29 -0
  275. package/dist/text/fit.js.map +1 -0
  276. package/dist/text/index.d.ts +5 -3
  277. package/dist/text/index.d.ts.map +1 -1
  278. package/dist/text/index.js +3 -2
  279. package/dist/text/index.js.map +1 -1
  280. package/dist/text/wrap.d.ts +17 -7
  281. package/dist/text/wrap.d.ts.map +1 -1
  282. package/dist/text/wrap.js +25 -17
  283. package/dist/text/wrap.js.map +1 -1
  284. package/dist/types.d.ts +161 -45
  285. package/dist/types.d.ts.map +1 -1
  286. package/dist/validate/index.d.ts +1 -1
  287. package/dist/validate/index.d.ts.map +1 -1
  288. package/dist/validate/index.js +3 -2
  289. package/dist/validate/index.js.map +1 -1
  290. package/dist/validate/keys.d.ts +19 -2
  291. package/dist/validate/keys.d.ts.map +1 -1
  292. package/dist/validate/keys.js +40 -3
  293. package/dist/validate/keys.js.map +1 -1
  294. package/dist/validate/suggest.d.ts.map +1 -1
  295. package/dist/validate/suggest.js +21 -3
  296. package/dist/validate/suggest.js.map +1 -1
  297. package/dist/validate/values.d.ts +2 -2
  298. package/dist/validate/values.d.ts.map +1 -1
  299. package/dist/validate/values.js +17 -3
  300. package/dist/validate/values.js.map +1 -1
  301. package/package.json +7 -1
@@ -1 +1 @@
1
- {"version":3,"file":"footer.js","sourceRoot":"","sources":["../../src/templates/footer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAgB/C,yDAAyD;AACzD,MAAM,UAAU,SAAS,CAAC,MAAsB;IAC9C,OAAO,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAsB,EACtB,SAA0B;IAE1B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,WAAW,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE;QACtC,CAAC,EAAE,SAAS,CAAC,CAAC;QACd,CAAC,EAAE,SAAS,CAAC,CAAC;QACd,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ,EAAE,SAAS,CAAC,QAAQ;QAC5B,UAAU,EAAE,GAAG;QACf,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;QAC9B,WAAW,EAAE,SAAS,CAAC,OAAO;QAC9B,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;KACpE,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"footer.js","sourceRoot":"","sources":["../../src/templates/footer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAgB9D;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,GAAW,EACX,QAAgB;IAEhB,OAAO,WAAW,CAAC,MAAM,GAAG,GAAG,GAAG,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,SAAS,CAAC,MAAsB;IAC9C,OAAO,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAsB,EACtB,SAA0B;IAE1B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,WAAW,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE;QACtC,CAAC,EAAE,SAAS,CAAC,CAAC;QACd,CAAC,EAAE,SAAS,CAAC,CAAC;QACd,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ,EAAE,SAAS,CAAC,QAAQ;QAC5B,UAAU,EAAE,GAAG;QACf,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;QAC9B,WAAW,EAAE,SAAS,CAAC,OAAO;QAC9B,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;KACpE,CAAC,CAAC;AACL,CAAC"}
@@ -7,5 +7,5 @@ export declare const builtinTemplates: Readonly<Record<string, Template>>;
7
7
  export { bannerTemplate } from "./banner/index.js";
8
8
  export { cardTemplate } from "./card/index.js";
9
9
  export { codeTemplate } from "./code/index.js";
10
- export { optionalString } from "./props.js";
10
+ export { optionalString } from "../props.js";
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK5C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAI/D,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK5C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAI/D,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -13,5 +13,5 @@ export const builtinTemplates = {
13
13
  export { bannerTemplate } from "./banner/index.js";
14
14
  export { cardTemplate } from "./card/index.js";
15
15
  export { codeTemplate } from "./code/index.js";
16
- export { optionalString } from "./props.js";
16
+ export { optionalString } from "../props.js";
17
17
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAuC;IAClE,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,cAAc;IACrC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,YAAY;IACjC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,YAAY;CAClC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAuC;IAClE,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,cAAc;IACrC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,YAAY;IACjC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,YAAY;CAClC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Rect } from "../layout/index.js";
2
+ import type { Dimensions, ImageAsset } from "../types.js";
3
+ /**
4
+ * Where the logo goes, or nothing where there is none.
5
+ *
6
+ * Its height comes from the image being drawn rather than from the logo's own
7
+ * pixels, so the same file works on a square and a landscape, and its width
8
+ * follows from the proportions of the picture. A logo whose format does not
9
+ * state its size is drawn in a square, where a wordmark will sit small in the
10
+ * middle rather than being stretched to fit.
11
+ */
12
+ export declare function logoRect(logo: ImageAsset | undefined, dimensions: Dimensions, pad: number, align: "start" | "middle"): Rect | undefined;
13
+ /** The logo drawn in the rectangle it was given, whole rather than cropped. */
14
+ export declare function logoElement(logo: ImageAsset | undefined, rect: Rect | undefined): string;
15
+ //# sourceMappingURL=logo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logo.d.ts","sourceRoot":"","sources":["../../src/templates/logo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK1D;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,GAAG,QAAQ,GACxB,IAAI,GAAG,SAAS,CAalB;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CACzB,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,MAAM,CAIR"}
@@ -0,0 +1,30 @@
1
+ import { image } from "../layout/index.js";
2
+ /** The logo's height, as a fraction of the image's. */
3
+ const logoScale = 0.075;
4
+ /**
5
+ * Where the logo goes, or nothing where there is none.
6
+ *
7
+ * Its height comes from the image being drawn rather than from the logo's own
8
+ * pixels, so the same file works on a square and a landscape, and its width
9
+ * follows from the proportions of the picture. A logo whose format does not
10
+ * state its size is drawn in a square, where a wordmark will sit small in the
11
+ * middle rather than being stretched to fit.
12
+ */
13
+ export function logoRect(logo, dimensions, pad, align) {
14
+ if (logo === undefined) {
15
+ return undefined;
16
+ }
17
+ const height = Math.round(dimensions.height * logoScale);
18
+ const width = Math.round(height * logo.aspect);
19
+ const x = align === "middle"
20
+ ? Math.round((dimensions.width - width) / 2)
21
+ : dimensions.width - pad - width;
22
+ return { x, y: pad, width, height };
23
+ }
24
+ /** The logo drawn in the rectangle it was given, whole rather than cropped. */
25
+ export function logoElement(logo, rect) {
26
+ return logo === undefined || rect === undefined
27
+ ? ""
28
+ : image(rect, logo.href, { fit: "contain" });
29
+ }
30
+ //# sourceMappingURL=logo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logo.js","sourceRoot":"","sources":["../../src/templates/logo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,uDAAuD;AACvD,MAAM,SAAS,GAAG,KAAK,CAAC;AAExB;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACtB,IAA4B,EAC5B,UAAsB,EACtB,GAAW,EACX,KAAyB;IAEzB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,CAAC,GACL,KAAK,KAAK,QAAQ;QAChB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5C,CAAC,CAAC,UAAU,CAAC,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC;IAErC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACtC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CACzB,IAA4B,EAC5B,IAAsB;IAEtB,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAC7C,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { MeasureAt } from "../text/index.js";
2
+ import type { MeasureText } from "../types.js";
3
+ /**
4
+ * Bind a measurer to one family and weight, leaving only the size open.
5
+ *
6
+ * That is the shape fitting text wants, since choosing a size is the whole of
7
+ * what it varies, and it keeps a template from repeating the family and weight
8
+ * on every call.
9
+ */
10
+ export declare function measureIn(measure: MeasureText, fontFamily: string, fontWeight: number): MeasureAt;
11
+ //# sourceMappingURL=measure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../src/templates/measure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,SAAS,CAGX"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Bind a measurer to one family and weight, leaving only the size open.
3
+ *
4
+ * That is the shape fitting text wants, since choosing a size is the whole of
5
+ * what it varies, and it keeps a template from repeating the family and weight
6
+ * on every call.
7
+ */
8
+ export function measureIn(measure, fontFamily, fontWeight) {
9
+ return (text, fontSize) => measure(text, { fontFamily, fontSize, fontWeight });
10
+ }
11
+ //# sourceMappingURL=measure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure.js","sourceRoot":"","sources":["../../src/templates/measure.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,OAAoB,EACpB,UAAkB,EAClB,UAAkB;IAElB,OAAO,CAAC,IAAY,EAAE,QAAgB,EAAU,EAAE,CAChD,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;AACxD,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Read a prop as a string, coercing the scalar types YAML frontmatter yields
3
- * (numbers, booleans) and returning `undefined` for anything else — templates
4
- * treat "not a usable string" and "absent" the same way.
3
+ * (numbers, booleans) and returning `undefined` for anything else, since
4
+ * templates treat "not a usable string" and "absent" the same way.
5
5
  */
6
6
  export declare function optionalString(value: unknown): string | undefined;
7
7
  //# sourceMappingURL=props.d.ts.map
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Read a prop as a string, coercing the scalar types YAML frontmatter yields
3
- * (numbers, booleans) and returning `undefined` for anything else — templates
4
- * treat "not a usable string" and "absent" the same way.
3
+ * (numbers, booleans) and returning `undefined` for anything else, since
4
+ * templates treat "not a usable string" and "absent" the same way.
5
5
  */
6
6
  export function optionalString(value) {
7
7
  if (typeof value === "string") {
@@ -0,0 +1,37 @@
1
+ import type { MeasureText } from "../types.js";
2
+ /** One group of a template's text: the space it has and how it is drawn. */
3
+ export interface TextBlock {
4
+ readonly maxWidth: number;
5
+ readonly maxLines: number;
6
+ readonly fontSize: number;
7
+ /**
8
+ * Fraction of `fontSize` this group may shrink to before it is cut instead.
9
+ * The title of a layout has the furthest to fall, because it is the line
10
+ * worth keeping whole; a subtitle that has shrunk much has stopped being
11
+ * readable in a feed, so it may as well lose its tail.
12
+ */
13
+ readonly floor: number;
14
+ readonly fontWeight: number;
15
+ }
16
+ /** A block along with how the lines it produces are drawn. */
17
+ export interface StyledBlock extends TextBlock {
18
+ readonly opacity: number;
19
+ /** Space inserted before the group's first line, to separate it from the last. */
20
+ readonly gapBefore?: number;
21
+ }
22
+ /** One line of a template's text block, ready to be stacked and drawn. */
23
+ export interface TextLine {
24
+ readonly text: string;
25
+ readonly fontSize: number;
26
+ readonly fontWeight: number;
27
+ readonly opacity: number;
28
+ readonly gapBefore?: number;
29
+ }
30
+ /**
31
+ * Fit one group of a template's text, from a prop that may not be there, and
32
+ * return its lines. Each group is fitted on its own, so a long title shrinking
33
+ * does not drag the subtitle down with it. A group whose prop is absent or
34
+ * empty produces no lines at all.
35
+ */
36
+ export declare function blockLines(value: unknown, measure: MeasureText, fontFamily: string, block: StyledBlock): TextLine[];
37
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/templates/text.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,4EAA4E;AAC5E,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,8DAA8D;AAC9D,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,0EAA0E;AAC1E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,WAAW,GACjB,QAAQ,EAAE,CAoBZ"}
@@ -0,0 +1,26 @@
1
+ import { fitText } from "../text/index.js";
2
+ import { measureIn } from "./measure.js";
3
+ import { optionalString } from "./props.js";
4
+ /**
5
+ * Fit one group of a template's text, from a prop that may not be there, and
6
+ * return its lines. Each group is fitted on its own, so a long title shrinking
7
+ * does not drag the subtitle down with it. A group whose prop is absent or
8
+ * empty produces no lines at all.
9
+ */
10
+ export function blockLines(value, measure, fontFamily, block) {
11
+ const fitted = fitText(optionalString(value) ?? "", measureIn(measure, fontFamily, block.fontWeight), {
12
+ maxWidth: block.maxWidth,
13
+ maxLines: block.maxLines,
14
+ fontSize: block.fontSize,
15
+ minFontSize: Math.round(block.fontSize * block.floor),
16
+ });
17
+ return fitted.lines.map((text, index) => ({
18
+ text,
19
+ fontSize: fitted.fontSize,
20
+ fontWeight: block.fontWeight,
21
+ opacity: block.opacity,
22
+ ...(index === 0 &&
23
+ block.gapBefore !== undefined && { gapBefore: block.gapBefore }),
24
+ }));
25
+ }
26
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/templates/text.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAiC5C;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,KAAc,EACd,OAAoB,EACpB,UAAkB,EAClB,KAAkB;IAElB,MAAM,MAAM,GAAe,OAAO,CAChC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,EAC3B,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,EAChD;QACE,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;KACtD,CACF,CAAC;IAEF,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACxC,IAAI;QACJ,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG,CAAC,KAAK,KAAK,CAAC;YACb,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;KACnE,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { MeasureLine } from "./wrap.js";
2
+ /**
3
+ * Break one word across as many lines as it takes, for a word that is wider
4
+ * than the line it has to fit on. A URL, a compound German noun, or a whole
5
+ * Japanese sentence, which has no spaces to break at in the first place.
6
+ *
7
+ * Always returns at least one piece, even where a single character is wider
8
+ * than the line: overflowing by one glyph beats looping forever.
9
+ */
10
+ export declare function breakWord(word: string, maxWidth: number, measure: MeasureLine): string[];
11
+ //# sourceMappingURL=break.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"break.d.ts","sourceRoot":"","sources":["../../src/text/break.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAS7C;;;;;;;GAOG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GACnB,MAAM,EAAE,CAgBV"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Grapheme segmentation, so a break never lands inside an emoji or between a
3
+ * letter and the accent that belongs to it. Built once, since a build breaks
4
+ * a great many words and the segmenter carries locale data with it.
5
+ */
6
+ const graphemes = new Intl.Segmenter(undefined, { granularity: "grapheme" });
7
+ /**
8
+ * Break one word across as many lines as it takes, for a word that is wider
9
+ * than the line it has to fit on. A URL, a compound German noun, or a whole
10
+ * Japanese sentence, which has no spaces to break at in the first place.
11
+ *
12
+ * Always returns at least one piece, even where a single character is wider
13
+ * than the line: overflowing by one glyph beats looping forever.
14
+ */
15
+ export function breakWord(word, maxWidth, measure) {
16
+ const pieces = [];
17
+ let current = "";
18
+ for (const { segment } of graphemes.segment(word)) {
19
+ const next = current + segment;
20
+ if (current !== "" && measure(next) > maxWidth) {
21
+ pieces.push(current);
22
+ current = segment;
23
+ }
24
+ else {
25
+ current = next;
26
+ }
27
+ }
28
+ return current === "" ? [word] : [...pieces, current];
29
+ }
30
+ //# sourceMappingURL=break.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"break.js","sourceRoot":"","sources":["../../src/text/break.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;AAE7E;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CACvB,IAAY,EACZ,QAAgB,EAChB,OAAoB;IAEpB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC;QAE/B,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,OAAO,GAAG,OAAO,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,30 @@
1
+ /** The width a run of text would be drawn at, at a given font size. */
2
+ export type MeasureAt = (text: string, fontSize: number) => number;
3
+ /** The space a block of text has, and the sizes it may be drawn at. */
4
+ export interface FitOptions {
5
+ readonly maxWidth: number;
6
+ readonly maxLines: number;
7
+ /** The size to draw at when the text fits at it. */
8
+ readonly fontSize: number;
9
+ /** The size below which shrinking costs more legibility than it is worth. */
10
+ readonly minFontSize: number;
11
+ }
12
+ /** A block of text with the size it turned out to fit at. */
13
+ export interface FittedText {
14
+ readonly lines: readonly string[];
15
+ readonly fontSize: number;
16
+ }
17
+ /**
18
+ * Wrap text into the space it has, shrinking it until it fits.
19
+ *
20
+ * The alternative, and what Colophon did before it could measure anything, is
21
+ * to wrap at one size and drop whatever is left over. That reads as a mistake
22
+ * rather than a design: a long title loses its last few words, and the image
23
+ * says something the post does not. Shrinking keeps the words.
24
+ *
25
+ * It only shrinks so far, because a title small enough to fit anything is a
26
+ * title nobody reads in a feed. Text that still does not fit at the floor is
27
+ * cut to `maxLines` as before.
28
+ */
29
+ export declare function fitText(text: string, measure: MeasureAt, options: FitOptions): FittedText;
30
+ //# sourceMappingURL=fit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fit.d.ts","sourceRoot":"","sources":["../../src/text/fit.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;AAEnE,uEAAuE;AACvE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,6DAA6D;AAC7D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,UAAU,GAClB,UAAU,CAiBZ"}
@@ -0,0 +1,29 @@
1
+ import { wrapText } from "./wrap.js";
2
+ /** How much of the size is given up each time the text does not fit. */
3
+ const shrinkStep = 0.94;
4
+ /**
5
+ * Wrap text into the space it has, shrinking it until it fits.
6
+ *
7
+ * The alternative, and what Colophon did before it could measure anything, is
8
+ * to wrap at one size and drop whatever is left over. That reads as a mistake
9
+ * rather than a design: a long title loses its last few words, and the image
10
+ * says something the post does not. Shrinking keeps the words.
11
+ *
12
+ * It only shrinks so far, because a title small enough to fit anything is a
13
+ * title nobody reads in a feed. Text that still does not fit at the floor is
14
+ * cut to `maxLines` as before.
15
+ */
16
+ export function fitText(text, measure, options) {
17
+ const { maxWidth, maxLines, minFontSize } = options;
18
+ let fontSize = options.fontSize;
19
+ let lines = wrapText(text, maxWidth, (line) => measure(line, fontSize));
20
+ while (lines.length > maxLines && fontSize > minFontSize) {
21
+ // Both terms are here to guarantee progress: the proportional step is what
22
+ // makes the search short, and the whole pixel is what stops it stalling
23
+ // once the sizes are small enough for rounding to swallow the step.
24
+ fontSize = Math.max(minFontSize, Math.min(fontSize - 1, Math.floor(fontSize * shrinkStep)));
25
+ lines = wrapText(text, maxWidth, (line) => measure(line, fontSize));
26
+ }
27
+ return { lines: lines.slice(0, maxLines), fontSize };
28
+ }
29
+ //# sourceMappingURL=fit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fit.js","sourceRoot":"","sources":["../../src/text/fit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAqBrC,wEAAwE;AACxE,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO,CACrB,IAAY,EACZ,OAAkB,EAClB,OAAmB;IAEnB,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IACpD,IAAI,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAChC,IAAI,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAExE,OAAO,KAAK,CAAC,MAAM,GAAG,QAAQ,IAAI,QAAQ,GAAG,WAAW,EAAE,CAAC;QACzD,2EAA2E;QAC3E,wEAAwE;QACxE,oEAAoE;QACpE,QAAQ,GAAG,IAAI,CAAC,GAAG,CACjB,WAAW,EACX,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,CAC1D,CAAC;QACF,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;AACvD,CAAC"}
@@ -1,7 +1,9 @@
1
1
  export { escapeXml } from "./escape.js";
2
2
  export { textElement } from "./element.js";
3
3
  export type { TextAttributes } from "./element.js";
4
- export { layoutStack } from "./stack.js";
5
- export type { PlacedLine, StackLine } from "./stack.js";
6
- export { estimateCharsPerLine, wrapText } from "./wrap.js";
4
+ export { breakWord } from "./break.js";
5
+ export { fitText } from "./fit.js";
6
+ export type { FitOptions, FittedText, MeasureAt } from "./fit.js";
7
+ export { wrapText } from "./wrap.js";
8
+ export type { MeasureLine } from "./wrap.js";
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/text/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/text/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { escapeXml } from "./escape.js";
2
2
  export { textElement } from "./element.js";
3
- export { layoutStack } from "./stack.js";
4
- export { estimateCharsPerLine, wrapText } from "./wrap.js";
3
+ export { breakWord } from "./break.js";
4
+ export { fitText } from "./fit.js";
5
+ export { wrapText } from "./wrap.js";
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/text/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/text/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC"}
@@ -1,12 +1,22 @@
1
1
  /**
2
- * Naive greedy word-wrap by character count. Words longer than the limit are
3
- * kept intact on their own line rather than being split.
2
+ * The width a run of text will be drawn at, in the same units as the space it
3
+ * has to fit. Bound to a font and a size by whoever is doing the wrapping.
4
4
  */
5
- export declare function wrapText(text: string, charactersPerLine: number): string[];
5
+ export type MeasureLine = (text: string) => number;
6
6
  /**
7
- * Estimate how many characters of the given font size fit within `widthPx`.
8
- * The `widthFactor` approximates average glyph width as a fraction of the font
9
- * size (bolder/wider faces want a larger factor).
7
+ * Greedy word-wrap to a width rather than to a character count.
8
+ *
9
+ * Wrapping by characters means assuming every glyph is the same fraction of
10
+ * the font size, which is wrong by a little for Latin text and wrong by half
11
+ * for anything wider. Measuring the words is what puts the break where it
12
+ * belongs.
13
+ *
14
+ * A single word too wide for the line is broken, since the alternative is a
15
+ * line that runs off the image. Text written without spaces, which is most of
16
+ * how Japanese and Chinese are set, is one long word by this reckoning and so
17
+ * breaks at whatever character reaches the edge. That is a plain wrap rather
18
+ * than a correct one: it does not know that a line should not begin with
19
+ * closing punctuation.
10
20
  */
11
- export declare function estimateCharsPerLine(widthPx: number, fontSize: number, widthFactor?: number): number;
21
+ export declare function wrapText(text: string, maxWidth: number, measure: MeasureLine): string[];
12
22
  //# sourceMappingURL=wrap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../src/text/wrap.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM,EAAE,CAsB1E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,SAAO,GACjB,MAAM,CAER"}
1
+ {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../src/text/wrap.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GACnB,MAAM,EAAE,CA6BV"}
package/dist/text/wrap.js CHANGED
@@ -1,33 +1,41 @@
1
+ import { breakWord } from "./break.js";
1
2
  /**
2
- * Naive greedy word-wrap by character count. Words longer than the limit are
3
- * kept intact on their own line rather than being split.
3
+ * Greedy word-wrap to a width rather than to a character count.
4
+ *
5
+ * Wrapping by characters means assuming every glyph is the same fraction of
6
+ * the font size, which is wrong by a little for Latin text and wrong by half
7
+ * for anything wider. Measuring the words is what puts the break where it
8
+ * belongs.
9
+ *
10
+ * A single word too wide for the line is broken, since the alternative is a
11
+ * line that runs off the image. Text written without spaces, which is most of
12
+ * how Japanese and Chinese are set, is one long word by this reckoning and so
13
+ * breaks at whatever character reaches the edge. That is a plain wrap rather
14
+ * than a correct one: it does not know that a line should not begin with
15
+ * closing punctuation.
4
16
  */
5
- export function wrapText(text, charactersPerLine) {
6
- const limit = Math.max(1, Math.floor(charactersPerLine));
17
+ export function wrapText(text, maxWidth, measure) {
7
18
  const words = text.split(/\s+/).filter((word) => word !== "");
8
19
  const lines = [];
9
20
  let currentLine = "";
10
21
  for (const word of words) {
11
22
  const nextLine = currentLine === "" ? word : `${currentLine} ${word}`;
12
- if (nextLine.length > limit && currentLine !== "") {
13
- lines.push(currentLine);
14
- currentLine = word;
15
- }
16
- else {
23
+ if (measure(nextLine) <= maxWidth) {
17
24
  currentLine = nextLine;
25
+ continue;
26
+ }
27
+ if (currentLine !== "") {
28
+ lines.push(currentLine);
18
29
  }
30
+ // The word starts a line of its own, and is only broken up if it cannot
31
+ // fit on one even there.
32
+ const pieces = breakWord(word, maxWidth, measure);
33
+ lines.push(...pieces.slice(0, -1));
34
+ currentLine = pieces.at(-1) ?? "";
19
35
  }
20
36
  if (currentLine !== "") {
21
37
  lines.push(currentLine);
22
38
  }
23
39
  return lines;
24
40
  }
25
- /**
26
- * Estimate how many characters of the given font size fit within `widthPx`.
27
- * The `widthFactor` approximates average glyph width as a fraction of the font
28
- * size (bolder/wider faces want a larger factor).
29
- */
30
- export function estimateCharsPerLine(widthPx, fontSize, widthFactor = 0.58) {
31
- return Math.max(1, Math.floor(widthPx / (fontSize * widthFactor)));
32
- }
33
41
  //# sourceMappingURL=wrap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.js","sourceRoot":"","sources":["../../src/text/wrap.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,iBAAyB;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,WAAW,GAAG,EAAE,CAAC;IAErB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,IAAI,EAAE,CAAC;QAEtE,IAAI,QAAQ,CAAC,MAAM,GAAG,KAAK,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACxB,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,QAAQ,CAAC;QACzB,CAAC;IACH,CAAC;IAED,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAe,EACf,QAAgB,EAChB,WAAW,GAAG,IAAI;IAElB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"wrap.js","sourceRoot":"","sources":["../../src/text/wrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAY,EACZ,QAAgB,EAChB,OAAoB;IAEpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,WAAW,GAAG,EAAE,CAAC;IAErB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,IAAI,EAAE,CAAC;QAEtE,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,EAAE,CAAC;YAClC,WAAW,GAAG,QAAQ,CAAC;YACvB,SAAS;QACX,CAAC;QAED,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;QAED,wEAAwE;QACxE,yBAAyB;QACzB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;IAED,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}