@sushichan044/kg-core 0.10.1 → 0.11.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.
@@ -1,4 +1,4 @@
1
- import { _ as readonlyArray, a as CLOSING_BRACKETS, c as graphemeSegmenter, g as nonNegativeInteger, h as TextRange, i as TATE_CHU_YOKO_MARKS, m as ManuscriptRange, o as OPENING_BRACKETS, p as NamespacedId, r as DIVIDING_PUNCTUATION, s as characterClass, t as questionOrExclamationSpacings, u as ManuscriptResult, v as readonlyObject } from "./question-or-exclamation-spacing-Cp3eOGlA.mjs";
1
+ import { _ as nonNegativeInteger, a as CLOSING_BRACKETS, c as assertNever, d as ManuscriptResult, g as TextRange, h as ManuscriptRange, i as TATE_CHU_YOKO_MARKS, l as graphemeSegmenter, m as NamespacedId, o as OPENING_BRACKETS, r as DIVIDING_PUNCTUATION, s as characterClass, t as questionOrExclamationSpacings, v as readonlyArray, y as readonlyObject } from "./question-or-exclamation-spacing-C5cFLeKr.mjs";
2
2
  import * as v from "valibot";
3
3
  import { eastAsianWidth } from "get-east-asian-width";
4
4
  const BoldAnnotation = { schema: readonlyObject({
@@ -99,6 +99,24 @@ const ParsedManuscript = {
99
99
  })))
100
100
  };
101
101
  //#endregion
102
+ //#region src/appearance/a5-page-format.ts
103
+ const A5_PAGE_FORMAT = {
104
+ fontSizeQ: 12.7,
105
+ flow: {
106
+ lineLengthEm: 27,
107
+ linesPerStage: 23,
108
+ stagesPerPage: 2
109
+ },
110
+ page: {
111
+ lineGapMm: 1.825,
112
+ stageGapMm: 10,
113
+ topMm: 12,
114
+ bottomMm: 16.55,
115
+ innerMm: 21.825,
116
+ outerMm: 13
117
+ }
118
+ };
119
+ //#endregion
102
120
  //#region src/appearance/font-preset-id.ts
103
121
  const FontPresetIdSchema = v.picklist(["mincho", "gothic"]);
104
122
  const FontPresetId = {
@@ -106,17 +124,11 @@ const FontPresetId = {
106
124
  is: (value) => v.is(FontPresetIdSchema, value)
107
125
  };
108
126
  //#endregion
109
- //#region src/appearance/font-size-pt.ts
110
- const RANGE = {
111
- min: 6,
112
- max: 24,
113
- step: .5
114
- };
115
- const FontSizePtSchema = v.pipe(v.number(), v.finite(), v.minValue(RANGE.min), v.maxValue(RANGE.max), v.multipleOf(RANGE.step));
116
- const FontSizePt = {
117
- schema: FontSizePtSchema,
118
- range: RANGE,
119
- is: (value) => v.is(FontSizePtSchema, value)
127
+ //#region src/appearance/font-size-q.ts
128
+ const FontSizeQSchema = v.pipe(v.number(), v.finite(), v.minValue(Number.MIN_VALUE));
129
+ const FontSizeQ = {
130
+ schema: FontSizeQSchema,
131
+ is: (value) => v.is(FontSizeQSchema, value)
120
132
  };
121
133
  //#endregion
122
134
  //#region src/appearance/paper-size-id.ts
@@ -135,12 +147,12 @@ const PaperSizeId = {
135
147
  const ManuscriptAppearanceSettings = {
136
148
  schema: readonlyObject({
137
149
  paperSize: PaperSizeId.schema,
138
- fontSizePt: FontSizePt.schema,
150
+ fontSizeQ: FontSizeQ.schema,
139
151
  fontPreset: FontPresetId.schema
140
152
  }),
141
153
  defaults: {
142
154
  paperSize: "a5",
143
- fontSizePt: 9,
155
+ fontSizeQ: A5_PAGE_FORMAT.fontSizeQ,
144
156
  fontPreset: "mincho"
145
157
  }
146
158
  };
@@ -152,6 +164,110 @@ const LineOffset = {
152
164
  total: (offset) => offset.leading + offset.trailing
153
165
  };
154
166
  //#endregion
167
+ //#region src/appearance/paper-size.ts
168
+ const PAPER_SIZES = {
169
+ a4: {
170
+ id: "a4",
171
+ label: "A4",
172
+ widthMm: 210,
173
+ heightMm: 297
174
+ },
175
+ a5: {
176
+ id: "a5",
177
+ label: "A5",
178
+ widthMm: 148,
179
+ heightMm: 210
180
+ },
181
+ a6: {
182
+ id: "a6",
183
+ label: "A6(文庫)",
184
+ widthMm: 105,
185
+ heightMm: 148
186
+ },
187
+ "jis-b5": {
188
+ id: "jis-b5",
189
+ label: "B5(JIS)",
190
+ widthMm: 182,
191
+ heightMm: 257
192
+ },
193
+ "jis-b6": {
194
+ id: "jis-b6",
195
+ label: "B6(JIS)",
196
+ widthMm: 128,
197
+ heightMm: 182
198
+ },
199
+ shinsho: {
200
+ id: "shinsho",
201
+ label: "新書",
202
+ widthMm: 106,
203
+ heightMm: 173
204
+ }
205
+ };
206
+ const PaperSize = {
207
+ of: (id) => PAPER_SIZES[id],
208
+ all: Object.values(PAPER_SIZES)
209
+ };
210
+ //#endregion
211
+ //#region src/composer/page-settings.ts
212
+ const length$1 = () => v.pipe(v.number(), v.finite(), v.minValue(0));
213
+ const ManuscriptPageSettings = {
214
+ schema: readonlyObject({
215
+ lineGapMm: length$1(),
216
+ stageGapMm: length$1(),
217
+ topMm: length$1(),
218
+ bottomMm: length$1(),
219
+ innerMm: length$1(),
220
+ outerMm: length$1()
221
+ }),
222
+ defaults: A5_PAGE_FORMAT.page,
223
+ /**
224
+ * Centre a non-A5 text grid using half-cell line gaps and two-cell stage gaps.
225
+ */
226
+ centered: (flow, appearance) => {
227
+ const cell = appearance.fontSizeQ / 4;
228
+ const paper = PaperSize.of(appearance.paperSize);
229
+ const lineGapMm = cell / 2;
230
+ const stageGapMm = cell * 2;
231
+ const horizontal = (paper.widthMm - flow.linesPerStage * cell - (flow.linesPerStage - 1) * lineGapMm) / 2;
232
+ const vertical = (paper.heightMm - flow.stagesPerPage * flow.lineLengthEm * cell - (flow.stagesPerPage - 1) * stageGapMm) / 2;
233
+ return {
234
+ lineGapMm,
235
+ stageGapMm,
236
+ topMm: vertical,
237
+ bottomMm: vertical,
238
+ innerMm: horizontal,
239
+ outerMm: horizontal
240
+ };
241
+ }
242
+ };
243
+ //#endregion
244
+ //#region src/composer/manuscript-geometry.ts
245
+ const length = () => v.pipe(v.number(), v.finite(), v.minValue(0));
246
+ const ManuscriptGeometry = {
247
+ schema: readonlyObject({
248
+ ...ManuscriptPageSettings.schema.entries,
249
+ paperWidthMm: length(),
250
+ paperHeightMm: length(),
251
+ cellSizeMm: length(),
252
+ fontSizeQ: FontSizeQ.schema,
253
+ contentWidthMm: length(),
254
+ contentHeightMm: length()
255
+ }),
256
+ of: (flow, appearance, page) => {
257
+ const paper = PaperSize.of(appearance.paperSize);
258
+ const cellSizeMm = appearance.fontSizeQ / 4;
259
+ return {
260
+ ...page,
261
+ paperWidthMm: paper.widthMm,
262
+ paperHeightMm: paper.heightMm,
263
+ cellSizeMm,
264
+ fontSizeQ: appearance.fontSizeQ,
265
+ contentWidthMm: flow.linesPerStage * cellSizeMm + (flow.linesPerStage - 1) * page.lineGapMm,
266
+ contentHeightMm: flow.stagesPerPage * flow.lineLengthEm * cellSizeMm + (flow.stagesPerPage - 1) * page.stageGapMm
267
+ };
268
+ }
269
+ };
270
+ //#endregion
155
271
  //#region src/composer/manuscript-offsets.ts
156
272
  const MAX_DOCUMENT_OFFSET = 1e4;
157
273
  const ManuscriptOffsets = {
@@ -210,25 +326,49 @@ const NovelFlowSettings = {
210
326
  stagesPerPage: boundedCount(RANGES.stagesPerPage)
211
327
  }),
212
328
  ranges: RANGES,
213
- defaults: {
214
- lineLengthEm: 27,
215
- linesPerStage: 23,
216
- stagesPerPage: 2
217
- }
329
+ defaults: A5_PAGE_FORMAT.flow
218
330
  };
219
331
  //#endregion
220
332
  //#region src/composer/composition-settings.ts
221
333
  const NovelCompositionSettingsSchema = v.pipe(readonlyObject({
222
334
  flow: NovelFlowSettings.schema,
223
335
  offsets: ManuscriptOffsets.schema,
224
- appearance: ManuscriptAppearanceSettings.schema
225
- }), v.check(({ flow, offsets }) => LineOffset.total(offsets.stage) <= ManuscriptOffsets.maxStageTotal(flow) && LineOffset.total(offsets.page) <= ManuscriptOffsets.maxPageTotal(flow, offsets.stage), "page or stage offsets leave no usable novel lines"));
336
+ appearance: ManuscriptAppearanceSettings.schema,
337
+ page: ManuscriptPageSettings.schema
338
+ }), v.check(({ flow, offsets }) => LineOffset.total(offsets.stage) <= ManuscriptOffsets.maxStageTotal(flow) && LineOffset.total(offsets.page) <= ManuscriptOffsets.maxPageTotal(flow, offsets.stage), "page or stage offsets leave no usable novel lines"), v.check(({ flow, appearance, page }) => {
339
+ const geometry = ManuscriptGeometry.of(flow, appearance, page);
340
+ return Math.abs(geometry.contentHeightMm + page.topMm + page.bottomMm - geometry.paperHeightMm) <= 1e-6 && Math.abs(geometry.contentWidthMm + page.innerMm + page.outerMm - geometry.paperWidthMm) <= 1e-6;
341
+ }, "text dimensions and margins must match the paper dimensions"), v.check(({ appearance, page }) => page.lineGapMm + 1e-6 >= appearance.fontSizeQ / 8, "line gap must leave room for half-size annotations"), v.check(({ flow, appearance, page }) => appearance.paperSize !== "a5" || appearance.fontSizeQ === A5_PAGE_FORMAT.fontSizeQ && flow.lineLengthEm === A5_PAGE_FORMAT.flow.lineLengthEm && flow.linesPerStage === A5_PAGE_FORMAT.flow.linesPerStage && flow.stagesPerPage === A5_PAGE_FORMAT.flow.stagesPerPage && page.lineGapMm === A5_PAGE_FORMAT.page.lineGapMm && page.stageGapMm === A5_PAGE_FORMAT.page.stageGapMm && page.topMm === A5_PAGE_FORMAT.page.topMm && page.bottomMm === A5_PAGE_FORMAT.page.bottomMm && page.innerMm === A5_PAGE_FORMAT.page.innerMm && page.outerMm === A5_PAGE_FORMAT.page.outerMm, "A5 uses the fixed 12.7Q, 27-character, 23-line, two-stage format"));
226
342
  const NovelCompositionSettings = {
227
343
  schema: NovelCompositionSettingsSchema,
228
344
  defaults: {
229
345
  flow: NovelFlowSettings.defaults,
230
346
  offsets: ManuscriptOffsets.defaults,
231
- appearance: ManuscriptAppearanceSettings.defaults
347
+ appearance: ManuscriptAppearanceSettings.defaults,
348
+ page: ManuscriptPageSettings.defaults
349
+ },
350
+ /**
351
+ * Select the fixed A5 format, or centre the current grid on another paper size.
352
+ */
353
+ forPaper: (paperSize, settings) => {
354
+ const appearance = {
355
+ ...settings.appearance,
356
+ paperSize
357
+ };
358
+ if (paperSize === "a5") return {
359
+ ...settings,
360
+ flow: A5_PAGE_FORMAT.flow,
361
+ appearance: {
362
+ ...appearance,
363
+ fontSizeQ: A5_PAGE_FORMAT.fontSizeQ
364
+ },
365
+ page: A5_PAGE_FORMAT.page
366
+ };
367
+ return {
368
+ ...settings,
369
+ appearance,
370
+ page: ManuscriptPageSettings.centered(settings.flow, appearance)
371
+ };
232
372
  },
233
373
  is: (value) => v.is(NovelCompositionSettingsSchema, value)
234
374
  };
@@ -365,6 +505,9 @@ const ASCII_TWO_DIGITS = /^[0-9]{2}$/u;
365
505
  const UPRIGHT_LATIN_ABBREVIATION = /^(?:[A-Z]+|[A-Z][a-z]{1,2})$/u;
366
506
  const TATE_CHU_YOKO_MARK = new RegExp(`^[${characterClass(TATE_CHU_YOKO_MARKS)}]$`, "u");
367
507
  const FULLWIDTH_ALPHANUMERIC = /^[A-Za-z0-9]$/u;
508
+ const ASCII_TEXT = /^[ -~]$/u;
509
+ const ASCII_WORD = /^[!-~]$/u;
510
+ const WESTERN_CONTEXT = /[A-Za-z0-9][^A-Za-z0-9]+[A-Za-z0-9]/u;
368
511
  function stretchEnd(graphemes, start, pattern) {
369
512
  let end = start + 1;
370
513
  while (pattern.test(graphemes[end]?.value ?? "")) end += 1;
@@ -377,6 +520,10 @@ function presentationOf(text) {
377
520
  }
378
521
  return FULLWIDTH_ALPHANUMERIC.test(text) ? "upright" : "mixed";
379
522
  }
523
+ /**
524
+ * Recognize sentence-wide presentation while keeping words as separate line-break units. Standalone
525
+ * dotted abbreviations retain the existing per-token presentation.
526
+ */
380
527
  function recognize(graphemes) {
381
528
  const runs = [];
382
529
  const push = (members, presentation) => {
@@ -388,9 +535,25 @@ function recognize(graphemes) {
388
535
  });
389
536
  };
390
537
  let cursor = 0;
538
+ let checkedThrough = 0;
391
539
  while (cursor < graphemes.length) {
392
540
  const first = graphemes[cursor];
393
541
  if (first === void 0) break;
542
+ if (cursor >= checkedThrough && ASCII_TEXT.test(first.value)) {
543
+ const contextEnd = stretchEnd(graphemes, cursor, ASCII_TEXT);
544
+ checkedThrough = contextEnd;
545
+ const text = graphemes.slice(cursor, contextEnd).map(({ value }) => value).join("");
546
+ const abbreviationParts = text.trim().replace(/\.$/u, "").split(".");
547
+ const standaloneDottedAbbreviation = abbreviationParts.length > 1 && abbreviationParts.every((part) => UPRIGHT_LATIN_ABBREVIATION.test(part));
548
+ if (/[A-Za-z]/u.test(text) && WESTERN_CONTEXT.test(text) && !standaloneDottedAbbreviation) {
549
+ while (cursor < contextEnd) {
550
+ const end = ASCII_WORD.test(graphemes[cursor]?.value ?? "") ? stretchEnd(graphemes, cursor, ASCII_WORD) : cursor + 1;
551
+ push(graphemes.slice(cursor, end), "sideways");
552
+ cursor = end;
553
+ }
554
+ continue;
555
+ }
556
+ }
394
557
  if (TATE_CHU_YOKO_MARK.test(first.value)) {
395
558
  const end = stretchEnd(graphemes, cursor, TATE_CHU_YOKO_MARK);
396
559
  const members = graphemes.slice(cursor, end);
@@ -959,29 +1122,35 @@ const WESTERN = /^[\p{Script=Latin}\p{Script=Greek}\p{Script=Cyrillic}]$/u;
959
1122
  * the same as a tate-chu-yoko run's 3.2.5.
960
1123
  */
961
1124
  function classify({ value, presentation }) {
962
- if (presentation === "tate-chu-yoko") return COMBINED_DIVIDING_MARKS.has(value) ? "cl-04" : "cl-30";
963
- if (presentation === "upright") return "cl-19";
964
- if (OPENING.has(value)) return "cl-01";
965
- if (CLOSING.has(value)) return "cl-02";
966
- if (HYPHENS.has(value)) return "cl-03";
967
- if (DIVIDING_MARKS.has(value)) return "cl-04";
968
- if (MIDDLE_DOTS.has(value)) return "cl-05";
969
- if (value === "。" || value === ".") return "cl-06";
970
- if (value === "、" || value === ",") return "cl-07";
971
- if (INSEPARABLE.has(value)) return "cl-08";
972
- if (ITERATION_MARKS.has(value)) return "cl-09";
973
- if (value === "ー") return "cl-10";
974
- if (SMALL_KANA.has(value)) return "cl-11";
975
- if (PREFIXED_ABBREVIATIONS.has(value)) return "cl-12";
976
- if (POSTFIXED_ABBREVIATIONS.has(value)) return "cl-13";
977
- if (value === " ") return "cl-14";
978
- if (HIRAGANA.test(value)) return "cl-15";
979
- if (KATAKANA.test(value)) return "cl-16";
980
- if (GROUPED_NUMERAL.test(value)) return "cl-24";
981
- if (UNIT_SYMBOLS.has(value)) return "cl-25";
982
- if (value === " ") return "cl-26";
983
- if (WESTERN.test(value)) return "cl-27";
984
- return "cl-19";
1125
+ switch (presentation) {
1126
+ case "tate-chu-yoko": return COMBINED_DIVIDING_MARKS.has(value) ? "cl-04" : "cl-30";
1127
+ case "upright": return "cl-19";
1128
+ case "sideways":
1129
+ case "mixed":
1130
+ if (presentation === "sideways" && /^[!-~]$/u.test(value) && !/^[A-Za-z0-9]$/u.test(value)) return "cl-27";
1131
+ if (OPENING.has(value)) return "cl-01";
1132
+ if (CLOSING.has(value)) return "cl-02";
1133
+ if (HYPHENS.has(value)) return "cl-03";
1134
+ if (DIVIDING_MARKS.has(value)) return "cl-04";
1135
+ if (MIDDLE_DOTS.has(value)) return "cl-05";
1136
+ if (value === "。" || value === ".") return "cl-06";
1137
+ if (value === "、" || value === ",") return "cl-07";
1138
+ if (INSEPARABLE.has(value)) return "cl-08";
1139
+ if (ITERATION_MARKS.has(value)) return "cl-09";
1140
+ if (value === "ー") return "cl-10";
1141
+ if (SMALL_KANA.has(value)) return "cl-11";
1142
+ if (PREFIXED_ABBREVIATIONS.has(value)) return "cl-12";
1143
+ if (POSTFIXED_ABBREVIATIONS.has(value)) return "cl-13";
1144
+ if (value === " ") return "cl-14";
1145
+ if (HIRAGANA.test(value)) return "cl-15";
1146
+ if (KATAKANA.test(value)) return "cl-16";
1147
+ if (GROUPED_NUMERAL.test(value)) return "cl-24";
1148
+ if (UNIT_SYMBOLS.has(value)) return "cl-25";
1149
+ if (value === " ") return "cl-26";
1150
+ if (WESTERN.test(value)) return "cl-27";
1151
+ return "cl-19";
1152
+ default: return assertNever(presentation);
1153
+ }
985
1154
  }
986
1155
  /**
987
1156
  * 無印 in 表1 with no colour in 表6: the pair is set solid and line adjustment leaves it alone.
@@ -1720,7 +1889,7 @@ const MeasurementSession = { create: (provider, settings) => {
1720
1889
  kind,
1721
1890
  presentation,
1722
1891
  fontPreset: settings.appearance.fontPreset,
1723
- fontSizePt: settings.appearance.fontSizePt,
1892
+ fontSizeQ: settings.appearance.fontSizeQ,
1724
1893
  scale: 1,
1725
1894
  writingMode: "vertical-rl"
1726
1895
  } : {
@@ -1728,7 +1897,7 @@ const MeasurementSession = { create: (provider, settings) => {
1728
1897
  kind,
1729
1898
  presentation: "mixed",
1730
1899
  fontPreset: settings.appearance.fontPreset,
1731
- fontSizePt: settings.appearance.fontSizePt,
1900
+ fontSizeQ: settings.appearance.fontSizeQ,
1732
1901
  scale: defaultBookStyle.annotation.sizeEm,
1733
1902
  writingMode: "vertical-rl"
1734
1903
  };
@@ -2549,121 +2718,6 @@ const SourceSpace = { collect: (graphemes, advancesEm) => {
2549
2718
  return [];
2550
2719
  });
2551
2720
  } };
2552
- //#endregion
2553
- //#region src/appearance/paper-size.ts
2554
- const PAPER_SIZES = {
2555
- a4: {
2556
- id: "a4",
2557
- label: "A4",
2558
- widthMm: 210,
2559
- heightMm: 297
2560
- },
2561
- a5: {
2562
- id: "a5",
2563
- label: "A5",
2564
- widthMm: 148,
2565
- heightMm: 210
2566
- },
2567
- a6: {
2568
- id: "a6",
2569
- label: "A6(文庫)",
2570
- widthMm: 105,
2571
- heightMm: 148
2572
- },
2573
- "jis-b5": {
2574
- id: "jis-b5",
2575
- label: "B5(JIS)",
2576
- widthMm: 182,
2577
- heightMm: 257
2578
- },
2579
- "jis-b6": {
2580
- id: "jis-b6",
2581
- label: "B6(JIS)",
2582
- widthMm: 128,
2583
- heightMm: 182
2584
- },
2585
- shinsho: {
2586
- id: "shinsho",
2587
- label: "新書",
2588
- widthMm: 106,
2589
- heightMm: 173
2590
- }
2591
- };
2592
- const PaperSize = {
2593
- of: (id) => PAPER_SIZES[id],
2594
- all: Object.values(PAPER_SIZES)
2595
- };
2596
- //#endregion
2597
- //#region src/internal/length.ts
2598
- const PT_PER_MM = 72 / 25.4;
2599
- function ptToMm(pt) {
2600
- return pt / PT_PER_MM;
2601
- }
2602
- function mmToPt(mm) {
2603
- return mm * PT_PER_MM;
2604
- }
2605
- //#endregion
2606
- //#region src/composer/manuscript-geometry.ts
2607
- const STAGE_GAP_CELLS = 2;
2608
- const LINE_GAP_CELLS = .5;
2609
- const nonNegativeLength = () => v.pipe(v.number(), v.finite(), v.minValue(0));
2610
- const ManuscriptGeometrySchema = readonlyObject({
2611
- paperWidthMm: nonNegativeLength(),
2612
- paperHeightMm: nonNegativeLength(),
2613
- cellSizeMm: nonNegativeLength(),
2614
- lineGapMm: nonNegativeLength(),
2615
- fontSizePt: FontSizePt.schema,
2616
- contentWidthMm: nonNegativeLength(),
2617
- contentHeightMm: nonNegativeLength(),
2618
- marginInlineMm: v.pipe(v.number(), v.finite()),
2619
- marginBlockMm: v.pipe(v.number(), v.finite()),
2620
- fitsPaper: v.boolean()
2621
- });
2622
- /**
2623
- * Every stage stacked vertically, plus the gap between adjacent stages.
2624
- */
2625
- function contentHeightInEm(flow) {
2626
- return flow.stagesPerPage * flow.lineLengthEm + STAGE_GAP_CELLS * (flow.stagesPerPage - 1);
2627
- }
2628
- /**
2629
- * Every vertical line side by side, plus the gap between adjacent lines.
2630
- */
2631
- function contentWidthInEm(flow) {
2632
- return flow.linesPerStage + LINE_GAP_CELLS * (flow.linesPerStage - 1);
2633
- }
2634
- const ManuscriptGeometry = {
2635
- schema: ManuscriptGeometrySchema,
2636
- of: (flow, appearance) => {
2637
- const paper = PaperSize.of(appearance.paperSize);
2638
- const cellSizeMm = ptToMm(appearance.fontSizePt);
2639
- const contentWidthMm = contentWidthInEm(flow) * cellSizeMm;
2640
- const contentHeightMm = contentHeightInEm(flow) * cellSizeMm;
2641
- const marginInlineMm = (paper.widthMm - contentWidthMm) / 2;
2642
- const marginBlockMm = (paper.heightMm - contentHeightMm) / 2;
2643
- return {
2644
- paperWidthMm: paper.widthMm,
2645
- paperHeightMm: paper.heightMm,
2646
- cellSizeMm,
2647
- lineGapMm: LINE_GAP_CELLS * cellSizeMm,
2648
- fontSizePt: appearance.fontSizePt,
2649
- contentWidthMm,
2650
- contentHeightMm,
2651
- marginInlineMm,
2652
- marginBlockMm,
2653
- fitsPaper: marginInlineMm >= 0 && marginBlockMm >= 0
2654
- };
2655
- },
2656
- /**
2657
- * The largest step-aligned point size whose text area still fits the paper.
2658
- */
2659
- maxFontSizePt: (flow, paperSizeId) => {
2660
- const paper = PaperSize.of(paperSizeId);
2661
- const maxCellSizeMm = Math.min(paper.widthMm / contentWidthInEm(flow), paper.heightMm / contentHeightInEm(flow));
2662
- const steps = Math.floor(mmToPt(maxCellSizeMm) / FontSizePt.range.step + 1e-9);
2663
- const aligned = Math.round(steps * FontSizePt.range.step * 1e3) / 1e3;
2664
- return Math.min(FontSizePt.range.max, Math.max(FontSizePt.range.min, aligned));
2665
- }
2666
- };
2667
2721
  const CompositionStatistics = { schema: readonlyObject({
2668
2722
  chars: nonNegativeInteger(),
2669
2723
  sourceLines: nonNegativeInteger(),
@@ -3371,7 +3425,7 @@ function createCompose(provider) {
3371
3425
  ], settings);
3372
3426
  return ManuscriptResult.succeed({
3373
3427
  pages,
3374
- geometry: ManuscriptGeometry.of(settings.flow, settings.appearance),
3428
+ geometry: ManuscriptGeometry.of(settings.flow, settings.appearance, settings.page),
3375
3429
  stats: {
3376
3430
  chars: sourceLines.reduce((total, line) => total + line.length, 0),
3377
3431
  sourceLines: sourceLines.length,
@@ -3390,4 +3444,4 @@ function createNovelComposer(options) {
3390
3444
  }
3391
3445
  const novelComposer = createNovelComposer({ measurer: logicalRunMeasurer });
3392
3446
  //#endregion
3393
- export { PaperSize as a, MeasurementTextRange as c, ManuscriptOffsets as d, ManuscriptAppearanceSettings as f, ParsedManuscript as g, FontPresetId as h, ManuscriptGeometry as i, NovelCompositionSettings as l, FontSizePt as m, novelComposer as n, RunMeasurement as o, PaperSizeId as p, logicalRunMeasurer as r, MeasuredCluster as s, createNovelComposer as t, NovelFlowSettings as u };
3447
+ export { ParsedManuscript as _, MeasuredCluster as a, NovelFlowSettings as c, ManuscriptPageSettings as d, PaperSize as f, FontPresetId as g, FontSizeQ as h, RunMeasurement as i, ManuscriptOffsets as l, PaperSizeId as m, novelComposer as n, MeasurementTextRange as o, ManuscriptAppearanceSettings as p, logicalRunMeasurer as r, NovelCompositionSettings as s, createNovelComposer as t, ManuscriptGeometry as u };
package/dist/plugin.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as ManuscriptResult, i as ParsedManuscript, n as ValidationIssue, r as NamespacedId } from "./composed-manuscript-C0f3mxKs.mjs";
2
- import { a as RunMeasurer, c as MeasurementRequest, d as ManuscriptComposer, f as ManuscriptParser, o as logicalRunMeasurer, p as Rejection, r as createNovelComposer, s as RunMeasurement, t as PresentationKind } from "./presentation-kind-BwIZFSZS.mjs";
2
+ import { a as RunMeasurer, c as MeasurementRequest, f as ManuscriptComposer, m as Rejection, o as logicalRunMeasurer, p as ManuscriptParser, r as createNovelComposer, s as RunMeasurement, t as PresentationKind } from "./presentation-kind-BCQndPoK.mjs";
3
3
  import * as v from "valibot";
4
4
  //#region src/composer/measurement-text-range.d.ts
5
5
  declare const MeasurementTextRangeSchema: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
package/dist/plugin.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { l as ValidationIssue, p as NamespacedId, u as ManuscriptResult, v as readonlyObject } from "./question-or-exclamation-spacing-Cp3eOGlA.mjs";
2
- import { c as MeasurementTextRange, g as ParsedManuscript, h as FontPresetId, m as FontSizePt, o as RunMeasurement, r as logicalRunMeasurer, s as MeasuredCluster, t as createNovelComposer } from "./novel-composer-D_orH6ET.mjs";
1
+ import { d as ManuscriptResult, m as NamespacedId, u as ValidationIssue, y as readonlyObject } from "./question-or-exclamation-spacing-C5cFLeKr.mjs";
2
+ import { _ as ParsedManuscript, a as MeasuredCluster, g as FontPresetId, h as FontSizeQ, i as RunMeasurement, o as MeasurementTextRange, r as logicalRunMeasurer, t as createNovelComposer } from "./novel-composer-z0cv8OHb.mjs";
3
3
  import * as v from "valibot";
4
4
  const PresentationKind = { schema: v.picklist([
5
5
  "mixed",
@@ -12,7 +12,7 @@ const PresentationKind = { schema: v.picklist([
12
12
  const context = {
13
13
  text: v.string(),
14
14
  fontPreset: FontPresetId.schema,
15
- fontSizePt: FontSizePt.schema,
15
+ fontSizeQ: FontSizeQ.schema,
16
16
  scale: v.pipe(v.number(), v.finite(), v.minValue(Number.MIN_VALUE)),
17
17
  writingMode: v.literal("vertical-rl")
18
18
  };