postext 1.19.2 → 1.20.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 (251) hide show
  1. package/dist/__tests__/comics/art.test.d.ts +2 -0
  2. package/dist/__tests__/comics/art.test.d.ts.map +1 -0
  3. package/dist/__tests__/comics/art.test.js +96 -0
  4. package/dist/__tests__/comics/art.test.js.map +1 -0
  5. package/dist/__tests__/comics/build.test.d.ts +2 -0
  6. package/dist/__tests__/comics/build.test.d.ts.map +1 -0
  7. package/dist/__tests__/comics/build.test.js +215 -0
  8. package/dist/__tests__/comics/build.test.js.map +1 -0
  9. package/dist/__tests__/comics/canvas.test.d.ts +2 -0
  10. package/dist/__tests__/comics/canvas.test.d.ts.map +1 -0
  11. package/dist/__tests__/comics/canvas.test.js +161 -0
  12. package/dist/__tests__/comics/canvas.test.js.map +1 -0
  13. package/dist/__tests__/comics/config.test.d.ts +2 -0
  14. package/dist/__tests__/comics/config.test.d.ts.map +1 -0
  15. package/dist/__tests__/comics/config.test.js +97 -0
  16. package/dist/__tests__/comics/config.test.js.map +1 -0
  17. package/dist/__tests__/comics/geometry.test.d.ts +2 -0
  18. package/dist/__tests__/comics/geometry.test.d.ts.map +1 -0
  19. package/dist/__tests__/comics/geometry.test.js +118 -0
  20. package/dist/__tests__/comics/geometry.test.js.map +1 -0
  21. package/dist/__tests__/comics/html.test.d.ts +2 -0
  22. package/dist/__tests__/comics/html.test.d.ts.map +1 -0
  23. package/dist/__tests__/comics/html.test.js +253 -0
  24. package/dist/__tests__/comics/html.test.js.map +1 -0
  25. package/dist/__tests__/comics/lettering.test.d.ts +2 -0
  26. package/dist/__tests__/comics/lettering.test.d.ts.map +1 -0
  27. package/dist/__tests__/comics/lettering.test.js +241 -0
  28. package/dist/__tests__/comics/lettering.test.js.map +1 -0
  29. package/dist/__tests__/comics/script.test.d.ts +2 -0
  30. package/dist/__tests__/comics/script.test.d.ts.map +1 -0
  31. package/dist/__tests__/comics/script.test.js +147 -0
  32. package/dist/__tests__/comics/script.test.js.map +1 -0
  33. package/dist/__tests__/comics/split.test.d.ts +2 -0
  34. package/dist/__tests__/comics/split.test.d.ts.map +1 -0
  35. package/dist/__tests__/comics/split.test.js +120 -0
  36. package/dist/__tests__/comics/split.test.js.map +1 -0
  37. package/dist/__tests__/comics/spread.test.d.ts +2 -0
  38. package/dist/__tests__/comics/spread.test.d.ts.map +1 -0
  39. package/dist/__tests__/comics/spread.test.js +161 -0
  40. package/dist/__tests__/comics/spread.test.js.map +1 -0
  41. package/dist/__tests__/comics/strip.test.d.ts +2 -0
  42. package/dist/__tests__/comics/strip.test.d.ts.map +1 -0
  43. package/dist/__tests__/comics/strip.test.js +231 -0
  44. package/dist/__tests__/comics/strip.test.js.map +1 -0
  45. package/dist/__tests__/exports.test.js +89 -0
  46. package/dist/__tests__/exports.test.js.map +1 -1
  47. package/dist/__tests__/parse/containers.test.js +1 -1
  48. package/dist/__tests__/parse/containers.test.js.map +1 -1
  49. package/dist/canvas-backend/comic.d.ts +32 -0
  50. package/dist/canvas-backend/comic.d.ts.map +1 -0
  51. package/dist/canvas-backend/comic.js +216 -0
  52. package/dist/canvas-backend/comic.js.map +1 -0
  53. package/dist/canvas-backend/headerFooter.d.ts +4 -1
  54. package/dist/canvas-backend/headerFooter.d.ts.map +1 -1
  55. package/dist/canvas-backend/headerFooter.js +3 -1
  56. package/dist/canvas-backend/headerFooter.js.map +1 -1
  57. package/dist/canvas-backend/index.d.ts.map +1 -1
  58. package/dist/canvas-backend/index.js +7 -1
  59. package/dist/canvas-backend/index.js.map +1 -1
  60. package/dist/comics/art.d.ts +72 -0
  61. package/dist/comics/art.d.ts.map +1 -0
  62. package/dist/comics/art.js +154 -0
  63. package/dist/comics/art.js.map +1 -0
  64. package/dist/comics/fonts.d.ts +20 -0
  65. package/dist/comics/fonts.d.ts.map +1 -0
  66. package/dist/comics/fonts.js +42 -0
  67. package/dist/comics/fonts.js.map +1 -0
  68. package/dist/comics/geometry.d.ts +87 -0
  69. package/dist/comics/geometry.d.ts.map +1 -0
  70. package/dist/comics/geometry.js +272 -0
  71. package/dist/comics/geometry.js.map +1 -0
  72. package/dist/comics/index.d.ts +29 -0
  73. package/dist/comics/index.d.ts.map +1 -0
  74. package/dist/comics/index.js +18 -0
  75. package/dist/comics/index.js.map +1 -0
  76. package/dist/comics/layoutPage.d.ts +156 -0
  77. package/dist/comics/layoutPage.d.ts.map +1 -0
  78. package/dist/comics/layoutPage.js +697 -0
  79. package/dist/comics/layoutPage.js.map +1 -0
  80. package/dist/comics/lettering/__tests__/harness.test.d.ts +2 -0
  81. package/dist/comics/lettering/__tests__/harness.test.d.ts.map +1 -0
  82. package/dist/comics/lettering/__tests__/harness.test.js +273 -0
  83. package/dist/comics/lettering/__tests__/harness.test.js.map +1 -0
  84. package/dist/comics/lettering/__tests__/letterPanel.test.d.ts +2 -0
  85. package/dist/comics/lettering/__tests__/letterPanel.test.d.ts.map +1 -0
  86. package/dist/comics/lettering/__tests__/letterPanel.test.js +224 -0
  87. package/dist/comics/lettering/__tests__/letterPanel.test.js.map +1 -0
  88. package/dist/comics/lettering/__tests__/polish.test.d.ts +2 -0
  89. package/dist/comics/lettering/__tests__/polish.test.d.ts.map +1 -0
  90. package/dist/comics/lettering/__tests__/polish.test.js +357 -0
  91. package/dist/comics/lettering/__tests__/polish.test.js.map +1 -0
  92. package/dist/comics/lettering/__tests__/round2.test.d.ts +2 -0
  93. package/dist/comics/lettering/__tests__/round2.test.d.ts.map +1 -0
  94. package/dist/comics/lettering/__tests__/round2.test.js +289 -0
  95. package/dist/comics/lettering/__tests__/round2.test.js.map +1 -0
  96. package/dist/comics/lettering/__tests__/shapeText.test.d.ts +2 -0
  97. package/dist/comics/lettering/__tests__/shapeText.test.d.ts.map +1 -0
  98. package/dist/comics/lettering/__tests__/shapeText.test.js +98 -0
  99. package/dist/comics/lettering/__tests__/shapeText.test.js.map +1 -0
  100. package/dist/comics/lettering/__tests__/shapes.test.d.ts +2 -0
  101. package/dist/comics/lettering/__tests__/shapes.test.d.ts.map +1 -0
  102. package/dist/comics/lettering/__tests__/shapes.test.js +137 -0
  103. package/dist/comics/lettering/__tests__/shapes.test.js.map +1 -0
  104. package/dist/comics/lettering/__tests__/stubMeasure.d.ts +5 -0
  105. package/dist/comics/lettering/__tests__/stubMeasure.d.ts.map +1 -0
  106. package/dist/comics/lettering/__tests__/stubMeasure.js +47 -0
  107. package/dist/comics/lettering/__tests__/stubMeasure.js.map +1 -0
  108. package/dist/comics/lettering/__tests__/text.test.d.ts +2 -0
  109. package/dist/comics/lettering/__tests__/text.test.d.ts.map +1 -0
  110. package/dist/comics/lettering/__tests__/text.test.js +86 -0
  111. package/dist/comics/lettering/__tests__/text.test.js.map +1 -0
  112. package/dist/comics/lettering/geom.d.ts +78 -0
  113. package/dist/comics/lettering/geom.d.ts.map +1 -0
  114. package/dist/comics/lettering/geom.js +376 -0
  115. package/dist/comics/lettering/geom.js.map +1 -0
  116. package/dist/comics/lettering/index.d.ts +7 -0
  117. package/dist/comics/lettering/index.d.ts.map +1 -0
  118. package/dist/comics/lettering/index.js +8 -0
  119. package/dist/comics/lettering/index.js.map +1 -0
  120. package/dist/comics/lettering/letter.d.ts +7 -0
  121. package/dist/comics/lettering/letter.d.ts.map +1 -0
  122. package/dist/comics/lettering/letter.js +397 -0
  123. package/dist/comics/lettering/letter.js.map +1 -0
  124. package/dist/comics/lettering/placement.d.ts +117 -0
  125. package/dist/comics/lettering/placement.d.ts.map +1 -0
  126. package/dist/comics/lettering/placement.js +889 -0
  127. package/dist/comics/lettering/placement.js.map +1 -0
  128. package/dist/comics/lettering/presets.d.ts +15 -0
  129. package/dist/comics/lettering/presets.d.ts.map +1 -0
  130. package/dist/comics/lettering/presets.js +61 -0
  131. package/dist/comics/lettering/presets.js.map +1 -0
  132. package/dist/comics/lettering/shape-text.d.ts +72 -0
  133. package/dist/comics/lettering/shape-text.d.ts.map +1 -0
  134. package/dist/comics/lettering/shape-text.js +550 -0
  135. package/dist/comics/lettering/shape-text.js.map +1 -0
  136. package/dist/comics/lettering/shapes.d.ts +83 -0
  137. package/dist/comics/lettering/shapes.d.ts.map +1 -0
  138. package/dist/comics/lettering/shapes.js +512 -0
  139. package/dist/comics/lettering/shapes.js.map +1 -0
  140. package/dist/comics/lettering/text.d.ts +79 -0
  141. package/dist/comics/lettering/text.d.ts.map +1 -0
  142. package/dist/comics/lettering/text.js +488 -0
  143. package/dist/comics/lettering/text.js.map +1 -0
  144. package/dist/comics/lettering/types.d.ts +270 -0
  145. package/dist/comics/lettering/types.d.ts.map +1 -0
  146. package/dist/comics/lettering/types.js +9 -0
  147. package/dist/comics/lettering/types.js.map +1 -0
  148. package/dist/comics/page.d.ts +37 -0
  149. package/dist/comics/page.d.ts.map +1 -0
  150. package/dist/comics/page.js +285 -0
  151. package/dist/comics/page.js.map +1 -0
  152. package/dist/comics/paint.d.ts +65 -0
  153. package/dist/comics/paint.d.ts.map +1 -0
  154. package/dist/comics/paint.js +219 -0
  155. package/dist/comics/paint.js.map +1 -0
  156. package/dist/comics/script.d.ts +42 -0
  157. package/dist/comics/script.d.ts.map +1 -0
  158. package/dist/comics/script.js +302 -0
  159. package/dist/comics/script.js.map +1 -0
  160. package/dist/comics/split.d.ts +135 -0
  161. package/dist/comics/split.d.ts.map +1 -0
  162. package/dist/comics/split.js +514 -0
  163. package/dist/comics/split.js.map +1 -0
  164. package/dist/comics/spread.d.ts +36 -0
  165. package/dist/comics/spread.d.ts.map +1 -0
  166. package/dist/comics/spread.js +172 -0
  167. package/dist/comics/spread.js.map +1 -0
  168. package/dist/comics/strip.d.ts +77 -0
  169. package/dist/comics/strip.d.ts.map +1 -0
  170. package/dist/comics/strip.js +89 -0
  171. package/dist/comics/strip.js.map +1 -0
  172. package/dist/comics/transform.d.ts +37 -0
  173. package/dist/comics/transform.d.ts.map +1 -0
  174. package/dist/comics/transform.js +161 -0
  175. package/dist/comics/transform.js.map +1 -0
  176. package/dist/comics/types.d.ts +143 -0
  177. package/dist/comics/types.d.ts.map +1 -0
  178. package/dist/comics/types.js +13 -0
  179. package/dist/comics/types.js.map +1 -0
  180. package/dist/comics/warnings.d.ts +14 -0
  181. package/dist/comics/warnings.d.ts.map +1 -0
  182. package/dist/comics/warnings.js +94 -0
  183. package/dist/comics/warnings.js.map +1 -0
  184. package/dist/configWarnings.d.ts.map +1 -1
  185. package/dist/configWarnings.js +42 -0
  186. package/dist/configWarnings.js.map +1 -1
  187. package/dist/defaults/comics.d.ts +51 -0
  188. package/dist/defaults/comics.d.ts.map +1 -0
  189. package/dist/defaults/comics.js +385 -0
  190. package/dist/defaults/comics.js.map +1 -0
  191. package/dist/defaults/index.d.ts +1 -0
  192. package/dist/defaults/index.d.ts.map +1 -1
  193. package/dist/defaults/index.js +9 -0
  194. package/dist/defaults/index.js.map +1 -1
  195. package/dist/design/layout.d.ts +13 -1
  196. package/dist/design/layout.d.ts.map +1 -1
  197. package/dist/design/layout.js +17 -0
  198. package/dist/design/layout.js.map +1 -1
  199. package/dist/html-backend.d.ts +3 -0
  200. package/dist/html-backend.d.ts.map +1 -1
  201. package/dist/html-backend.js +44 -8
  202. package/dist/html-backend.js.map +1 -1
  203. package/dist/htmlComic.d.ts +69 -0
  204. package/dist/htmlComic.d.ts.map +1 -0
  205. package/dist/htmlComic.js +179 -0
  206. package/dist/htmlComic.js.map +1 -0
  207. package/dist/index.d.ts +8 -2
  208. package/dist/index.d.ts.map +1 -1
  209. package/dist/index.js +4 -0
  210. package/dist/index.js.map +1 -1
  211. package/dist/parse/blockParser.d.ts.map +1 -1
  212. package/dist/parse/blockParser.js +25 -1
  213. package/dist/parse/blockParser.js.map +1 -1
  214. package/dist/parse/indexMarks.d.ts.map +1 -1
  215. package/dist/parse/indexMarks.js +3 -0
  216. package/dist/parse/indexMarks.js.map +1 -1
  217. package/dist/parse/types.d.ts +7 -1
  218. package/dist/parse/types.d.ts.map +1 -1
  219. package/dist/pipeline/build.d.ts.map +1 -1
  220. package/dist/pipeline/build.js +251 -9
  221. package/dist/pipeline/build.js.map +1 -1
  222. package/dist/pipeline/config.d.ts.map +1 -1
  223. package/dist/pipeline/config.js +4 -1
  224. package/dist/pipeline/config.js.map +1 -1
  225. package/dist/pipeline/contentWarnings.d.ts.map +1 -1
  226. package/dist/pipeline/contentWarnings.js +58 -0
  227. package/dist/pipeline/contentWarnings.js.map +1 -1
  228. package/dist/pipeline/floatSlots.js +1 -1
  229. package/dist/pipeline/floatSlots.js.map +1 -1
  230. package/dist/pipeline/headerFooter.d.ts +6 -2
  231. package/dist/pipeline/headerFooter.d.ts.map +1 -1
  232. package/dist/pipeline/headerFooter.js +11 -3
  233. package/dist/pipeline/headerFooter.js.map +1 -1
  234. package/dist/pipeline/pageRoles.d.ts +1 -0
  235. package/dist/pipeline/pageRoles.d.ts.map +1 -1
  236. package/dist/pipeline/pageRoles.js +3 -0
  237. package/dist/pipeline/pageRoles.js.map +1 -1
  238. package/dist/pipeline/placement.d.ts +3 -3
  239. package/dist/pipeline/placement.d.ts.map +1 -1
  240. package/dist/pipeline/placement.js +4 -4
  241. package/dist/pipeline/placement.js.map +1 -1
  242. package/dist/types.d.ts +338 -1
  243. package/dist/types.d.ts.map +1 -1
  244. package/dist/vdt.d.ts +271 -2
  245. package/dist/vdt.d.ts.map +1 -1
  246. package/dist/vdt.js.map +1 -1
  247. package/dist/worker/fonts.d.ts +2 -1
  248. package/dist/worker/fonts.d.ts.map +1 -1
  249. package/dist/worker/fonts.js +11 -1
  250. package/dist/worker/fonts.js.map +1 -1
  251. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script.js","sourceRoot":"","sources":["../../src/comics/script.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * The split grammar of a comic page (`:::page{split="30 [30 | 20 | *] / *"}`,
3
+ * #555): how the page's frame is cut into panels.
4
+ *
5
+ * ```
6
+ * list := item (SEP item)* SEP is '/' (rows, stacked top to bottom)
7
+ * or '|' (columns, from the start side)
8
+ * item := size [ '[' list ']' ] a bracketed list splits that cell on the
9
+ * other axis
10
+ * size := number ['%'] ['~' number ['%']] | '*' | ''
11
+ * ```
12
+ *
13
+ * A size is the cell's extent along its list's axis, in percent of the
14
+ * parent cell; the split lines sit at the running sums. `*` takes an equal
15
+ * share of what is left; an empty size is a `*`. `30~40` slants the cell's
16
+ * far edge: 30 % at the start of the cross axis (the top, for columns; the
17
+ * start side, for rows), 40 % at its other end. The last cell of a list
18
+ * runs to 100 % whatever its size says.
19
+ *
20
+ * Everything here is pure: the parser keeps the source offsets of every
21
+ * size so the Sandbox can rewrite one number in place, and the editing
22
+ * functions (`moveComicSplitLine`, `splitComicCell`, `mergeComicCells`)
23
+ * take a `split` value and return the new one.
24
+ */
25
+ /** The axis a list splits its cell along: `'rows'` stacks tiers top to
26
+ * bottom, `'columns'` sets cells side by side from the start side. */
27
+ export type ComicSplitAxis = 'rows' | 'columns';
28
+ /** A size as written. */
29
+ export interface ComicSplitSize {
30
+ /** `*`, or an empty size (`implicit`). */
31
+ star: boolean;
32
+ /** The size was left empty (`[*|*] / *`): a `*` that serialises as
33
+ * nothing. */
34
+ implicit?: boolean;
35
+ /** Percent at the start end. Unset for a star. */
36
+ start?: number;
37
+ /** Percent at the far end, when the size is slanted (`30~40`). */
38
+ end?: number;
39
+ /** Written with a `%` sign. */
40
+ percent?: boolean;
41
+ /** Offsets of the size in the source (empty at the item's start for an
42
+ * implicit size). */
43
+ sourceStart: number;
44
+ sourceEnd: number;
45
+ }
46
+ /** One cell of a list, with the list that splits it further. */
47
+ export interface ComicSplitItem {
48
+ size: ComicSplitSize;
49
+ children?: ComicSplitList;
50
+ sourceStart: number;
51
+ sourceEnd: number;
52
+ }
53
+ /** A list of cells sharing one axis. A one-item list has none. */
54
+ export interface ComicSplitList {
55
+ axis?: ComicSplitAxis;
56
+ items: ComicSplitItem[];
57
+ sourceStart: number;
58
+ sourceEnd: number;
59
+ }
60
+ /** A size token with where it sits in the tree: `path` is the list's path
61
+ * (the indices of the items walked down from the top list), `index` the
62
+ * item's in that list. */
63
+ export interface ComicSplitToken {
64
+ path: number[];
65
+ index: number;
66
+ size: ComicSplitSize;
67
+ }
68
+ /** Something the grammar could not read as written. */
69
+ export interface ComicSplitIssue {
70
+ kind: 'syntax' | 'overflow';
71
+ message: string;
72
+ sourceStart: number;
73
+ sourceEnd: number;
74
+ /** `overflow`: the sum of the list's sizes (percent). */
75
+ total?: number;
76
+ }
77
+ export interface ComicSplitParse {
78
+ tree: ComicSplitList;
79
+ tokens: ComicSplitToken[];
80
+ issues: ComicSplitIssue[];
81
+ }
82
+ /** The smallest share a cell keeps (percent) when the sizes of its list
83
+ * overflow, and the least a drag leaves a cell. */
84
+ export declare const COMIC_MIN_CELL_PERCENT = 5;
85
+ /** Parse a `split` value. Never throws: what cannot be read is reported in
86
+ * `issues` and the rest is kept (an empty or unreadable value is one
87
+ * cell, a splash page). */
88
+ export declare function parseComicSplit(src: string): ComicSplitParse;
89
+ /** The axis a list's children split on: its own, or for a one-item list
90
+ * the cross axis of its parent (rows at the top). */
91
+ export declare function crossAxis(axis: ComicSplitAxis): ComicSplitAxis;
92
+ /**
93
+ * The line positions of a list (cumulative percent of its cell) at each end
94
+ * of the cross axis: `lines[b]` is the line between items `b` and `b + 1`.
95
+ * Stars share what the fixed sizes leave; sizes past 100 are scaled down so
96
+ * every star keeps {@link COMIC_MIN_CELL_PERCENT}; the last item runs to
97
+ * 100. Lines never run backwards.
98
+ */
99
+ export declare function comicSplitLines(list: ComicSplitList): {
100
+ start: number[];
101
+ end: number[];
102
+ };
103
+ /** The list at `path` (item indices walked down from the top list). */
104
+ export declare function comicSplitListAt(tree: ComicSplitList, path: readonly number[]): ComicSplitList | undefined;
105
+ /** Leaf cells in reading order (tree order), each with its item path. */
106
+ export declare function comicSplitLeaves(tree: ComicSplitList): number[][];
107
+ /** Write a tree back as a `split` value: ` / ` between rows, ` | ` between
108
+ * columns, numbers with at most one decimal. */
109
+ export declare function serializeComicSplit(tree: ComicSplitList): string;
110
+ /**
111
+ * Move the split line between children `boundary` and `boundary + 1` of the
112
+ * list at `path` to `newPercentAtStart` (cumulative percent of the parent
113
+ * cell). With `newPercentAtEnd` the far end goes there (a slant); without
114
+ * it the line keeps its slant, both ends moving by the same amount. The
115
+ * line is clamped so every cell keeps {@link COMIC_MIN_CELL_PERCENT}. Only
116
+ * the sizes that change are rewritten, in place; `*` stays where the
117
+ * result allows. Returns `src` unchanged when the path names no line.
118
+ */
119
+ export declare function moveComicSplitLine(src: string, path: readonly number[], boundary: number, newPercentAtStart: number, newPercentAtEnd?: number): string;
120
+ /**
121
+ * Split the cell at `cellPath` (item indices walked down from the top list)
122
+ * in two along `axis` (`'rows'`: one above the other). A cell whose list
123
+ * runs along `axis` gets a sibling after it, the two sharing its size; any
124
+ * other cell is split by a bracketed list (`30` → `30 [* | *]`). Returns the
125
+ * new `split` value, re-serialised (`serializeComicSplit`).
126
+ */
127
+ export declare function splitComicCell(src: string, cellPath: readonly number[], axis: ComicSplitAxis): string;
128
+ /**
129
+ * Merge children `boundary` and `boundary + 1` of the list at `path` into one
130
+ * cell spanning both (the split line between them goes). The merged cell
131
+ * keeps the first one's own split, if any. A bracketed list left with one
132
+ * cell loses its brackets. Returns the new `split` value, re-serialised.
133
+ */
134
+ export declare function mergeComicCells(src: string, path: readonly number[], boundary: number): string;
135
+ //# sourceMappingURL=split.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../src/comics/split.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,514 @@
1
+ /**
2
+ * The split grammar of a comic page (`:::page{split="30 [30 | 20 | *] / *"}`,
3
+ * #555): how the page's frame is cut into panels.
4
+ *
5
+ * ```
6
+ * list := item (SEP item)* SEP is '/' (rows, stacked top to bottom)
7
+ * or '|' (columns, from the start side)
8
+ * item := size [ '[' list ']' ] a bracketed list splits that cell on the
9
+ * other axis
10
+ * size := number ['%'] ['~' number ['%']] | '*' | ''
11
+ * ```
12
+ *
13
+ * A size is the cell's extent along its list's axis, in percent of the
14
+ * parent cell; the split lines sit at the running sums. `*` takes an equal
15
+ * share of what is left; an empty size is a `*`. `30~40` slants the cell's
16
+ * far edge: 30 % at the start of the cross axis (the top, for columns; the
17
+ * start side, for rows), 40 % at its other end. The last cell of a list
18
+ * runs to 100 % whatever its size says.
19
+ *
20
+ * Everything here is pure: the parser keeps the source offsets of every
21
+ * size so the Sandbox can rewrite one number in place, and the editing
22
+ * functions (`moveComicSplitLine`, `splitComicCell`, `mergeComicCells`)
23
+ * take a `split` value and return the new one.
24
+ */
25
+ /** The smallest share a cell keeps (percent) when the sizes of its list
26
+ * overflow, and the least a drag leaves a cell. */
27
+ export const COMIC_MIN_CELL_PERCENT = 5;
28
+ const NUMBER_RE = /^[0-9]+(?:\.[0-9]*)?|^\.[0-9]+/;
29
+ /** Parse a `split` value. Never throws: what cannot be read is reported in
30
+ * `issues` and the rest is kept (an empty or unreadable value is one
31
+ * cell, a splash page). */
32
+ export function parseComicSplit(src) {
33
+ const issues = [];
34
+ const tokens = [];
35
+ let at = 0;
36
+ const skip = () => {
37
+ while (at < src.length && /\s/.test(src[at]))
38
+ at++;
39
+ };
40
+ const issue = (message, start, end = start + 1) => {
41
+ issues.push({ kind: 'syntax', message, sourceStart: start, sourceEnd: Math.max(start, Math.min(end, src.length)) });
42
+ };
43
+ const parseNumber = () => {
44
+ const m = NUMBER_RE.exec(src.slice(at));
45
+ if (!m)
46
+ return undefined;
47
+ at += m[0].length;
48
+ return Number(m[0]);
49
+ };
50
+ const parseSize = () => {
51
+ skip();
52
+ const start = at;
53
+ if (src[at] === '*') {
54
+ at++;
55
+ return { star: true, sourceStart: start, sourceEnd: at };
56
+ }
57
+ const a = parseNumber();
58
+ if (a === undefined)
59
+ return { star: true, implicit: true, sourceStart: start, sourceEnd: start };
60
+ let percent = false;
61
+ if (src[at] === '%') {
62
+ at++;
63
+ percent = true;
64
+ }
65
+ const size = { star: false, start: a, sourceStart: start, sourceEnd: at };
66
+ if (src[at] === '~') {
67
+ at++;
68
+ const b = parseNumber();
69
+ if (b === undefined) {
70
+ issue('a slant needs a number after "~"', at - 1, at);
71
+ }
72
+ else {
73
+ if (src[at] === '%') {
74
+ at++;
75
+ percent = true;
76
+ }
77
+ size.end = b;
78
+ }
79
+ }
80
+ if (percent)
81
+ size.percent = true;
82
+ size.sourceEnd = at;
83
+ return size;
84
+ };
85
+ const parseList = (path, closer) => {
86
+ skip();
87
+ const list = { items: [], sourceStart: at, sourceEnd: at };
88
+ let sep;
89
+ for (;;) {
90
+ skip();
91
+ const itemStart = at;
92
+ const index = list.items.length;
93
+ const size = parseSize();
94
+ skip();
95
+ const item = { size, sourceStart: itemStart, sourceEnd: at };
96
+ if (src[at] === '[') {
97
+ const open = at;
98
+ at++;
99
+ item.children = parseList([...path, index], ']');
100
+ skip();
101
+ if (src[at] === ']')
102
+ at++;
103
+ else
104
+ issue('"[" is never closed', open, at);
105
+ }
106
+ item.sourceEnd = at;
107
+ list.items.push(item);
108
+ tokens.push({ path, index, size });
109
+ // The separator after the item, past anything unreadable.
110
+ let next = 'end';
111
+ for (;;) {
112
+ skip();
113
+ const c = src[at];
114
+ if (c === '/' || c === '|') {
115
+ if (sep === undefined)
116
+ sep = c;
117
+ else if (sep !== c)
118
+ issue('a list mixes "/" and "|": put one of them inside brackets', at);
119
+ at++;
120
+ next = 'sep';
121
+ break;
122
+ }
123
+ if (c === undefined || c === closer)
124
+ break;
125
+ // Anything else: report it and skip to the next separator or closer.
126
+ const bad = at;
127
+ at++;
128
+ while (at < src.length && !'/|'.includes(src[at]) && src[at] !== closer)
129
+ at++;
130
+ issue(`"${src.slice(bad, at).trim()}" is not a size`, bad, at);
131
+ }
132
+ if (next === 'end')
133
+ break;
134
+ }
135
+ list.sourceEnd = at;
136
+ if (sep !== undefined && list.items.length > 1)
137
+ list.axis = sep === '/' ? 'rows' : 'columns';
138
+ return list;
139
+ };
140
+ const tree = parseList([], undefined);
141
+ skip();
142
+ if (at < src.length)
143
+ issue(`"${src.slice(at)}" is left over`, at, src.length);
144
+ tokens.sort((x, y) => x.size.sourceStart - y.size.sourceStart);
145
+ checkAxes(tree, undefined, issues);
146
+ checkOverflow(tree, issues);
147
+ return { tree, tokens, issues };
148
+ }
149
+ /** A bracketed list on its parent's axis (`30 [10 / 20] / *`). */
150
+ function checkAxes(list, parentAxis, issues) {
151
+ if (parentAxis !== undefined && list.axis === parentAxis) {
152
+ issues.push({
153
+ kind: 'syntax',
154
+ message: `a bracketed list splits its cell on the other axis: use "${parentAxis === 'rows' ? '|' : '/'}" inside it`,
155
+ sourceStart: list.sourceStart,
156
+ sourceEnd: list.sourceEnd,
157
+ });
158
+ }
159
+ for (const item of list.items)
160
+ if (item.children)
161
+ checkAxes(item.children, list.axis ?? parentAxis, issues);
162
+ }
163
+ function checkOverflow(list, issues) {
164
+ if (list.items.length > 1) {
165
+ for (const end of ['start', 'end']) {
166
+ const total = list.items.reduce((sum, it) => sum + (it.size.star ? 0 : sizeAt(it.size, end)), 0);
167
+ if (total > 100 + 1e-6) {
168
+ issues.push({ kind: 'overflow', message: `the sizes add up to ${round1(total)} %`, total: round1(total), sourceStart: list.sourceStart, sourceEnd: list.sourceEnd });
169
+ break;
170
+ }
171
+ }
172
+ }
173
+ for (const item of list.items)
174
+ if (item.children)
175
+ checkOverflow(item.children, issues);
176
+ }
177
+ function sizeAt(size, end) {
178
+ const v = end === 'end' ? size.end ?? size.start : size.start;
179
+ return Math.max(0, v ?? 0);
180
+ }
181
+ /** The axis a list's children split on: its own, or for a one-item list
182
+ * the cross axis of its parent (rows at the top). */
183
+ export function crossAxis(axis) {
184
+ return axis === 'rows' ? 'columns' : 'rows';
185
+ }
186
+ /**
187
+ * The line positions of a list (cumulative percent of its cell) at each end
188
+ * of the cross axis: `lines[b]` is the line between items `b` and `b + 1`.
189
+ * Stars share what the fixed sizes leave; sizes past 100 are scaled down so
190
+ * every star keeps {@link COMIC_MIN_CELL_PERCENT}; the last item runs to
191
+ * 100. Lines never run backwards.
192
+ */
193
+ export function comicSplitLines(list) {
194
+ return { start: linesAt(list, 'start'), end: linesAt(list, 'end') };
195
+ }
196
+ function linesAt(list, end) {
197
+ const sizes = resolvedSizes(list, end);
198
+ const out = [];
199
+ let sum = 0;
200
+ for (let i = 0; i < sizes.length - 1; i++) {
201
+ sum += sizes[i];
202
+ out.push(Math.min(100, Math.max(out[i - 1] ?? 0, sum)));
203
+ }
204
+ return out;
205
+ }
206
+ /** The sizes of a list's items at one end, in percent, before the last item
207
+ * is stretched to 100. */
208
+ function resolvedSizes(list, end) {
209
+ const stars = list.items.filter((it) => it.size.star).length;
210
+ const fixed = list.items.reduce((sum, it) => sum + (it.size.star ? 0 : sizeAt(it.size, end)), 0);
211
+ const room = 100 - stars * (stars > 0 ? COMIC_MIN_CELL_PERCENT : 0);
212
+ const scale = fixed > (stars > 0 ? room : 100) && fixed > 0 ? (stars > 0 ? room : 100) / fixed : 1;
213
+ const left = Math.max(0, 100 - fixed * scale);
214
+ return list.items.map((it) => (it.size.star ? left / stars : sizeAt(it.size, end) * scale));
215
+ }
216
+ /** The list at `path` (item indices walked down from the top list). */
217
+ export function comicSplitListAt(tree, path) {
218
+ let list = tree;
219
+ for (const i of path) {
220
+ list = list?.items[i]?.children;
221
+ if (!list)
222
+ return undefined;
223
+ }
224
+ return list;
225
+ }
226
+ /** Leaf cells in reading order (tree order), each with its item path. */
227
+ export function comicSplitLeaves(tree) {
228
+ const out = [];
229
+ const walk = (list, path) => {
230
+ list.items.forEach((item, i) => {
231
+ if (item.children && item.children.items.length > 0)
232
+ walk(item.children, [...path, i]);
233
+ else
234
+ out.push([...path, i]);
235
+ });
236
+ };
237
+ walk(tree, []);
238
+ return out;
239
+ }
240
+ // ---------------------------------------------------------------------------
241
+ // Serialising
242
+ // ---------------------------------------------------------------------------
243
+ /** A number with at most one decimal, no trailing `.0`. */
244
+ function round1(n) {
245
+ return Math.round(n * 10) / 10;
246
+ }
247
+ function formatNumber(n) {
248
+ return String(round1(n));
249
+ }
250
+ function formatSize(size) {
251
+ if (size.star)
252
+ return size.implicit ? '' : '*';
253
+ const pct = size.percent ? '%' : '';
254
+ const a = `${formatNumber(size.start ?? 0)}${pct}`;
255
+ if (size.end === undefined || round1(size.end) === round1(size.start ?? 0))
256
+ return a;
257
+ return `${a}~${formatNumber(size.end)}${pct}`;
258
+ }
259
+ /** Write a tree back as a `split` value: ` / ` between rows, ` | ` between
260
+ * columns, numbers with at most one decimal. */
261
+ export function serializeComicSplit(tree) {
262
+ const list = (l) => l.items.map(item).join(l.axis === 'columns' ? ' | ' : ' / ');
263
+ const item = (it) => {
264
+ const size = formatSize(it.size);
265
+ if (!it.children || it.children.items.length === 0)
266
+ return size === '' ? '*' : size;
267
+ return `${size}${size === '' ? '' : ' '}[${list(it.children)}]`;
268
+ };
269
+ return list(tree);
270
+ }
271
+ // ---------------------------------------------------------------------------
272
+ // Editing
273
+ // ---------------------------------------------------------------------------
274
+ const EPS = 0.06;
275
+ /** Whether giving `edits` to the list puts its lines at the targets. */
276
+ function linesMatch(list, edits, start, end) {
277
+ const items = list.items.map((it, i) => {
278
+ const e = edits.find((x) => x.index === i);
279
+ return e ? { ...it, size: e.size } : it;
280
+ });
281
+ const lines = comicSplitLines({ ...list, items });
282
+ return lines.start.every((v, i) => Math.abs(v - start[i]) < EPS) && lines.end.every((v, i) => Math.abs(v - end[i]) < EPS);
283
+ }
284
+ function fixedSize(old, a, b) {
285
+ const size = { star: false, start: round1(Math.max(0, a)), sourceStart: old.sourceStart, sourceEnd: old.sourceEnd };
286
+ if (Math.abs(round1(b) - round1(a)) > 1e-9)
287
+ size.end = round1(Math.max(0, b));
288
+ if (old.percent)
289
+ size.percent = true;
290
+ return size;
291
+ }
292
+ /** The fewest size edits that put a list's lines at `start` / `end`,
293
+ * keeping `*` sizes where the result allows. */
294
+ function editsFor(list, start, end, touched) {
295
+ const n = list.items.length;
296
+ const want = (i) => [
297
+ (i < n - 1 ? start[i] : 100) - (i > 0 ? start[i - 1] : 0),
298
+ (i < n - 1 ? end[i] : 100) - (i > 0 ? end[i - 1] : 0),
299
+ ];
300
+ const fixedEdit = (i) => {
301
+ const [a, b] = want(i);
302
+ return { index: i, size: fixedSize(list.items[i].size, a, b) };
303
+ };
304
+ // 1. Only the touched items that are not stars.
305
+ const candidates = [];
306
+ const nonStars = touched.filter((i) => !list.items[i].size.star).map(fixedEdit);
307
+ candidates.push(nonStars);
308
+ // 2. One touched star written out, the other kept.
309
+ for (const i of touched)
310
+ if (list.items[i].size.star)
311
+ candidates.push([...nonStars, fixedEdit(i)]);
312
+ // 3. Every touched item fixed.
313
+ candidates.push(touched.map(fixedEdit));
314
+ for (const edits of candidates)
315
+ if (linesMatch(list, edits, start, end))
316
+ return edits;
317
+ // 4. Every item fixed.
318
+ return list.items.map((_, i) => fixedEdit(i));
319
+ }
320
+ function applyEdits(src, list, edits) {
321
+ const sorted = [...edits].sort((x, y) => list.items[y.index].size.sourceStart - list.items[x.index].size.sourceStart);
322
+ let out = src;
323
+ for (const e of sorted) {
324
+ const old = list.items[e.index].size;
325
+ let text = formatSize(e.size);
326
+ // An implicit size followed by its bracket needs a space.
327
+ if (old.implicit && src[old.sourceEnd] === '[')
328
+ text += ' ';
329
+ out = out.slice(0, old.sourceStart) + text + out.slice(old.sourceEnd);
330
+ }
331
+ return out;
332
+ }
333
+ /**
334
+ * Move the split line between children `boundary` and `boundary + 1` of the
335
+ * list at `path` to `newPercentAtStart` (cumulative percent of the parent
336
+ * cell). With `newPercentAtEnd` the far end goes there (a slant); without
337
+ * it the line keeps its slant, both ends moving by the same amount. The
338
+ * line is clamped so every cell keeps {@link COMIC_MIN_CELL_PERCENT}. Only
339
+ * the sizes that change are rewritten, in place; `*` stays where the
340
+ * result allows. Returns `src` unchanged when the path names no line.
341
+ */
342
+ export function moveComicSplitLine(src, path, boundary, newPercentAtStart, newPercentAtEnd) {
343
+ const { tree } = parseComicSplit(src);
344
+ const list = comicSplitListAt(tree, path);
345
+ if (!list || boundary < 0 || boundary >= list.items.length - 1)
346
+ return src;
347
+ const lines = comicSplitLines(list);
348
+ const start = [...lines.start];
349
+ const end = [...lines.end];
350
+ const lo = (arr) => (boundary > 0 ? arr[boundary - 1] : 0) + COMIC_MIN_CELL_PERCENT;
351
+ const hi = (arr) => (boundary < arr.length - 1 ? arr[boundary + 1] : 100) - COMIC_MIN_CELL_PERCENT;
352
+ const clamp = (v, arr) => Math.max(lo(arr), Math.min(hi(arr), v));
353
+ let s;
354
+ let e;
355
+ if (newPercentAtEnd === undefined) {
356
+ const delta = newPercentAtStart - start[boundary];
357
+ const minDelta = Math.max(lo(start) - start[boundary], lo(end) - end[boundary]);
358
+ const maxDelta = Math.min(hi(start) - start[boundary], hi(end) - end[boundary]);
359
+ const d = Math.max(minDelta, Math.min(maxDelta, delta));
360
+ s = start[boundary] + d;
361
+ e = end[boundary] + d;
362
+ }
363
+ else {
364
+ s = clamp(newPercentAtStart, start);
365
+ e = clamp(newPercentAtEnd, end);
366
+ }
367
+ start[boundary] = round1(s);
368
+ end[boundary] = round1(e);
369
+ const edits = editsFor(list, start, end, [boundary, boundary + 1]);
370
+ return applyEdits(src, list, edits);
371
+ }
372
+ function cloneList(list) {
373
+ return {
374
+ ...list,
375
+ items: list.items.map((it) => ({ ...it, size: { ...it.size }, ...(it.children ? { children: cloneList(it.children) } : {}) })),
376
+ };
377
+ }
378
+ /** The sizes of a list rewritten as fixed numbers (each end), its lines
379
+ * unchanged — for edits that add or remove an item. */
380
+ function sizesOf(list) {
381
+ const lines = comicSplitLines(list);
382
+ const n = list.items.length;
383
+ return list.items.map((_, i) => ({
384
+ start: (i < n - 1 ? lines.start[i] : 100) - (i > 0 ? lines.start[i - 1] : 0),
385
+ end: (i < n - 1 ? lines.end[i] : 100) - (i > 0 ? lines.end[i - 1] : 0),
386
+ }));
387
+ }
388
+ function sizeFrom(a, b, like) {
389
+ return fixedSize({ star: false, sourceStart: 0, sourceEnd: 0, ...(like?.percent ? { percent: true } : {}) }, a, b);
390
+ }
391
+ const STAR = { star: true, sourceStart: 0, sourceEnd: 0 };
392
+ /**
393
+ * Split the cell at `cellPath` (item indices walked down from the top list)
394
+ * in two along `axis` (`'rows'`: one above the other). A cell whose list
395
+ * runs along `axis` gets a sibling after it, the two sharing its size; any
396
+ * other cell is split by a bracketed list (`30` → `30 [* | *]`). Returns the
397
+ * new `split` value, re-serialised (`serializeComicSplit`).
398
+ */
399
+ export function splitComicCell(src, cellPath, axis) {
400
+ const { tree } = parseComicSplit(src);
401
+ const root = cloneList(tree);
402
+ if (cellPath.length === 0)
403
+ return src;
404
+ const parentPath = cellPath.slice(0, -1);
405
+ const index = cellPath[cellPath.length - 1];
406
+ const list = comicSplitListAt(root, parentPath);
407
+ const item = list?.items[index];
408
+ if (!list || !item)
409
+ return src;
410
+ // The axis of the list above `list` (a list may not repeat it).
411
+ const grand = parentPath.length > 0 ? comicSplitListAt(root, parentPath.slice(0, -1)) : undefined;
412
+ const grandAxis = grand?.axis;
413
+ const listAxis = list.axis ?? (grandAxis ? crossAxis(grandAxis) : undefined);
414
+ if (listAxis === undefined || listAxis === axis) {
415
+ // A sibling on the list's own axis.
416
+ const stars = list.items.filter((it) => it.size.star).length;
417
+ let first;
418
+ let second;
419
+ if (item.size.star && stars === 1) {
420
+ const s = sizesOf(list)[index];
421
+ first = sizeFrom(s.start / 2, s.end / 2);
422
+ second = { ...STAR };
423
+ }
424
+ else if (item.size.star) {
425
+ // Several stars: the others keep their share if this one is written
426
+ // out as two halves.
427
+ const s = sizesOf(list)[index];
428
+ first = sizeFrom(s.start / 2, s.end / 2);
429
+ second = sizeFrom(s.start / 2, s.end / 2);
430
+ }
431
+ else {
432
+ const a = (item.size.start ?? 0) / 2;
433
+ const b = (item.size.end ?? item.size.start ?? 0) / 2;
434
+ first = sizeFrom(a, b, item.size);
435
+ second = sizeFrom(a, b, item.size);
436
+ // The last item of a list runs to 100: keep it a star when it was
437
+ // stretched, so the line stays put.
438
+ if (index === list.items.length - 1) {
439
+ const s = sizesOf(list)[index];
440
+ first = sizeFrom(s.start / 2, s.end / 2, item.size);
441
+ second = { ...STAR };
442
+ }
443
+ }
444
+ const firstItem = { ...item, size: first };
445
+ const secondItem = { size: second, sourceStart: 0, sourceEnd: 0 };
446
+ list.items.splice(index, 1, firstItem, secondItem);
447
+ list.axis = axis;
448
+ return serializeComicSplit(root);
449
+ }
450
+ // Across the list's axis: a bracketed list inside the cell.
451
+ if (item.children && item.children.items.length > 1) {
452
+ // Already split that way: one more child at the end.
453
+ const kids = item.children;
454
+ const last = kids.items[kids.items.length - 1];
455
+ const s = sizesOf(kids)[kids.items.length - 1];
456
+ kids.items[kids.items.length - 1] = { ...last, size: sizeFrom(s.start / 2, s.end / 2, last.size.star ? undefined : last.size) };
457
+ kids.items.push({ size: { ...STAR }, sourceStart: 0, sourceEnd: 0 });
458
+ return serializeComicSplit(root);
459
+ }
460
+ item.children = {
461
+ axis,
462
+ items: [{ size: { ...STAR }, sourceStart: 0, sourceEnd: 0 }, { size: { ...STAR }, sourceStart: 0, sourceEnd: 0 }],
463
+ sourceStart: 0,
464
+ sourceEnd: 0,
465
+ };
466
+ if (item.size.implicit)
467
+ item.size = { ...STAR };
468
+ return serializeComicSplit(root);
469
+ }
470
+ /**
471
+ * Merge children `boundary` and `boundary + 1` of the list at `path` into one
472
+ * cell spanning both (the split line between them goes). The merged cell
473
+ * keeps the first one's own split, if any. A bracketed list left with one
474
+ * cell loses its brackets. Returns the new `split` value, re-serialised.
475
+ */
476
+ export function mergeComicCells(src, path, boundary) {
477
+ const { tree } = parseComicSplit(src);
478
+ const root = cloneList(tree);
479
+ const list = comicSplitListAt(root, path);
480
+ if (!list || boundary < 0 || boundary >= list.items.length - 1)
481
+ return src;
482
+ const sizes = sizesOf(list);
483
+ const a = list.items[boundary];
484
+ const b = list.items[boundary + 1];
485
+ // The lines that stay, which the merged size must keep where they are.
486
+ const lines = comicSplitLines(list);
487
+ const keep = (arr) => arr.filter((_, i) => i !== boundary);
488
+ const fixed = sizeFrom(sizes[boundary].start + sizes[boundary + 1].start, sizes[boundary].end + sizes[boundary + 1].end, a.size.star ? (b.size.star ? undefined : b.size) : a.size);
489
+ const trial = (size) => {
490
+ const items = [...list.items];
491
+ items.splice(boundary, 2, { ...a, size });
492
+ const got = comicSplitLines({ ...list, items });
493
+ const start = keep(lines.start);
494
+ const end = keep(lines.end);
495
+ return got.start.every((v, i) => Math.abs(v - start[i]) < EPS) && got.end.every((v, i) => Math.abs(v - end[i]) < EPS);
496
+ };
497
+ const size = a.size.star || b.size.star ? (trial({ ...STAR }) ? { ...STAR } : fixed) : fixed;
498
+ const merged = { ...a, size };
499
+ list.items.splice(boundary, 2, merged);
500
+ if (list.items.length === 1) {
501
+ delete list.axis;
502
+ // A bracketed list of one cell: the brackets go.
503
+ if (path.length > 0) {
504
+ const parent = comicSplitListAt(root, path.slice(0, -1));
505
+ const owner = parent.items[path[path.length - 1]];
506
+ if (merged.children && merged.children.items.length > 1)
507
+ owner.children = merged.children;
508
+ else
509
+ delete owner.children;
510
+ }
511
+ }
512
+ return serializeComicSplit(root);
513
+ }
514
+ //# sourceMappingURL=split.js.map