@sushichan044/kg-core 0.10.0 → 0.10.2

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.
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { _ as readonlyObject, c as ValidationIssue, f as NamespacedId, l as ManuscriptResult, p as ManuscriptRange, s as graphemeSegmenter, u as ManuscriptDiagnostic } from "./question-or-exclamation-spacing-Bv-mF2ZE.mjs";
2
- import { a as PaperSize, d as ManuscriptOffsets, f as ManuscriptAppearanceSettings, g as ParsedManuscript, h as FontPresetId, i as ManuscriptGeometry, l as NovelCompositionSettings, m as FontSizePt, n as novelComposer, p as PaperSizeId, u as NovelFlowSettings } from "./novel-composer-C0EqiM0f.mjs";
3
- import { n as assertNever, t as describeCause } from "./describe-cause-BV8mZ3Um.mjs";
1
+ import { c as assertNever, d as ManuscriptResult, f as ManuscriptDiagnostic, h as ManuscriptRange, l as graphemeSegmenter, m as NamespacedId, u as ValidationIssue, y as readonlyObject } from "./question-or-exclamation-spacing-C5cFLeKr.mjs";
2
+ import { a as PaperSize, d as ManuscriptOffsets, f as ManuscriptAppearanceSettings, g as ParsedManuscript, h as FontPresetId, i as ManuscriptGeometry, l as NovelCompositionSettings, m as FontSizePt, n as novelComposer, p as PaperSizeId, u as NovelFlowSettings } from "./novel-composer-CHNWyvn8.mjs";
3
+ import { t as describeCause } from "./describe-cause-SABI_1ex.mjs";
4
4
  import * as v from "valibot";
5
5
  const Rejection = { schema: readonlyObject({ reason: v.string() }) };
6
6
  //#endregion
package/dist/lint.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { _ as readonlyObject, a as OPENING_BRACKETS, c as ValidationIssue, d as DiagnosticSeverity, f as NamespacedId, g as readonlyArray, i as CLOSING_BRACKETS, l as ManuscriptResult, n as leadingSpaces, o as characterClass, p as ManuscriptRange, s as graphemeSegmenter, t as questionOrExclamationSpacings, u as ManuscriptDiagnostic } from "./question-or-exclamation-spacing-Bv-mF2ZE.mjs";
2
- import { n as assertNever, t as describeCause } from "./describe-cause-BV8mZ3Um.mjs";
1
+ import { a as CLOSING_BRACKETS, c as assertNever, d as ManuscriptResult, f as ManuscriptDiagnostic, h as ManuscriptRange, l as graphemeSegmenter, m as NamespacedId, n as leadingSpaces, o as OPENING_BRACKETS, p as DiagnosticSeverity, s as characterClass, t as questionOrExclamationSpacings, u as ValidationIssue, v as readonlyArray, y as readonlyObject } from "./question-or-exclamation-spacing-C5cFLeKr.mjs";
2
+ import { t as describeCause } from "./describe-cause-SABI_1ex.mjs";
3
3
  import * as v from "valibot";
4
4
  //#region src/proofreading/invalid-rule-options.ts
5
5
  const InvalidRuleOptions = { describe: (error) => `ルール ${error.ruleId} のオプション "${error.option}" が不正です: ${error.issues.map(({ message }) => message).join(", ")}` };
@@ -1,4 +1,4 @@
1
- import { _ as readonlyObject, a as OPENING_BRACKETS, f as NamespacedId, g as readonlyArray, h as nonNegativeInteger, i as CLOSING_BRACKETS, l as ManuscriptResult, m as TextRange, p as ManuscriptRange, r as DIVIDING_PUNCTUATION, s as graphemeSegmenter, t as questionOrExclamationSpacings } from "./question-or-exclamation-spacing-Bv-mF2ZE.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({
@@ -363,26 +363,69 @@ const BoundaryRule = { resolve: (left, right, profile, context) => {
363
363
  const ASCII_ALPHANUMERIC = /^[A-Za-z0-9]$/u;
364
364
  const ASCII_TWO_DIGITS = /^[0-9]{2}$/u;
365
365
  const UPRIGHT_LATIN_ABBREVIATION = /^(?:[A-Z]+|[A-Z][a-z]{1,2})$/u;
366
+ const TATE_CHU_YOKO_MARK = new RegExp(`^[${characterClass(TATE_CHU_YOKO_MARKS)}]$`, "u");
366
367
  const FULLWIDTH_ALPHANUMERIC = /^[A-Za-z0-9]$/u;
368
+ const ASCII_TEXT = /^[ -~]$/u;
369
+ const ASCII_WORD = /^[!-~]$/u;
370
+ const WESTERN_CONTEXT = /[A-Za-z0-9][^A-Za-z0-9]+[A-Za-z0-9]/u;
371
+ function stretchEnd(graphemes, start, pattern) {
372
+ let end = start + 1;
373
+ while (pattern.test(graphemes[end]?.value ?? "")) end += 1;
374
+ return end;
375
+ }
376
+ function presentationOf(text) {
377
+ if (ASCII_ALPHANUMERIC.test(text[0] ?? "")) {
378
+ if (ASCII_TWO_DIGITS.test(text)) return "tate-chu-yoko";
379
+ return text.length === 1 || UPRIGHT_LATIN_ABBREVIATION.test(text) ? "upright" : "sideways";
380
+ }
381
+ return FULLWIDTH_ALPHANUMERIC.test(text) ? "upright" : "mixed";
382
+ }
383
+ /**
384
+ * Recognize sentence-wide presentation while keeping words as separate line-break units. Standalone
385
+ * dotted abbreviations retain the existing per-token presentation.
386
+ */
367
387
  function recognize(graphemes) {
368
388
  const runs = [];
369
- let cursor = 0;
370
- while (cursor < graphemes.length) {
371
- const first = graphemes[cursor];
372
- if (first === void 0) break;
373
- const start = cursor;
374
- cursor += 1;
375
- const ascii = ASCII_ALPHANUMERIC.test(first.value);
376
- if (ascii) while (ASCII_ALPHANUMERIC.test(graphemes[cursor]?.value ?? "")) cursor += 1;
377
- const members = graphemes.slice(start, cursor);
378
- const text = members.map(({ value }) => value).join("");
379
- const presentation = ascii ? ASCII_TWO_DIGITS.test(text) ? "tate-chu-yoko" : text.length === 1 || UPRIGHT_LATIN_ABBREVIATION.test(text) ? "upright" : "sideways" : FULLWIDTH_ALPHANUMERIC.test(first.value) ? "upright" : "mixed";
389
+ const push = (members, presentation) => {
380
390
  const range = ManuscriptRange.merge(members.map((member) => member.range));
381
391
  if (range !== null) runs.push({
382
392
  range,
383
393
  presentation,
384
394
  members
385
395
  });
396
+ };
397
+ let cursor = 0;
398
+ let checkedThrough = 0;
399
+ while (cursor < graphemes.length) {
400
+ const first = graphemes[cursor];
401
+ if (first === void 0) break;
402
+ if (cursor >= checkedThrough && ASCII_TEXT.test(first.value)) {
403
+ const contextEnd = stretchEnd(graphemes, cursor, ASCII_TEXT);
404
+ checkedThrough = contextEnd;
405
+ const text = graphemes.slice(cursor, contextEnd).map(({ value }) => value).join("");
406
+ const abbreviationParts = text.trim().replace(/\.$/u, "").split(".");
407
+ const standaloneDottedAbbreviation = abbreviationParts.length > 1 && abbreviationParts.every((part) => UPRIGHT_LATIN_ABBREVIATION.test(part));
408
+ if (/[A-Za-z]/u.test(text) && WESTERN_CONTEXT.test(text) && !standaloneDottedAbbreviation) {
409
+ while (cursor < contextEnd) {
410
+ const end = ASCII_WORD.test(graphemes[cursor]?.value ?? "") ? stretchEnd(graphemes, cursor, ASCII_WORD) : cursor + 1;
411
+ push(graphemes.slice(cursor, end), "sideways");
412
+ cursor = end;
413
+ }
414
+ continue;
415
+ }
416
+ }
417
+ if (TATE_CHU_YOKO_MARK.test(first.value)) {
418
+ const end = stretchEnd(graphemes, cursor, TATE_CHU_YOKO_MARK);
419
+ const members = graphemes.slice(cursor, end);
420
+ if (members.length === 2 || members.length === 3) push(members, "tate-chu-yoko");
421
+ else for (const member of members) push([member], "mixed");
422
+ cursor = end;
423
+ continue;
424
+ }
425
+ const end = ASCII_ALPHANUMERIC.test(first.value) ? stretchEnd(graphemes, cursor, ASCII_ALPHANUMERIC) : cursor + 1;
426
+ const members = graphemes.slice(cursor, end);
427
+ push(members, presentationOf(members.map(({ value }) => value).join("")));
428
+ cursor = end;
386
429
  }
387
430
  return runs;
388
431
  }
@@ -914,6 +957,7 @@ const OPENING = /* @__PURE__ */ new Set(`${OPENING_BRACKETS}【〘〝⦅«`);
914
957
  const CLOSING = /* @__PURE__ */ new Set(`${CLOSING_BRACKETS}】〙〟⦆»`);
915
958
  const HYPHENS = /* @__PURE__ */ new Set("‐‑⁃–");
916
959
  const DIVIDING_MARKS = new Set(DIVIDING_PUNCTUATION);
960
+ const COMBINED_DIVIDING_MARKS = new Set(TATE_CHU_YOKO_MARKS);
917
961
  const MIDDLE_DOTS = /* @__PURE__ */ new Set("・:;");
918
962
  const SMALL_KANA = /* @__PURE__ */ new Set("ァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖ");
919
963
  const ITERATION_MARKS = /* @__PURE__ */ new Set("ヽヾゝゞ々〻");
@@ -928,7 +972,8 @@ const WESTERN = /^[\p{Script=Latin}\p{Script=Greek}\p{Script=Cyrillic}]$/u;
928
972
  /**
929
973
  * Order matters: a character inside a tate-chu-yoko group is cl-30 (3.2.5) and an upright Latin
930
974
  * letter or Arabic numeral is cl-19 (3.2.4), whatever either would be on its own; anything left
931
- * unmatched is cl-19 too, the class JLReq reserves for kanji and the like.
975
+ * unmatched is cl-19 too, the class JLReq reserves for kanji and the like. A tate-chu-yoko `!?`
976
+ * stays cl-04, the class JLReq gives `⁉`, so it still may not open a line.
932
977
  *
933
978
  * The quarter em 3.2.6 sets between Japanese and a Western character or numeral applies only to a
934
979
  * character rotated 90 degrees in vertical writing mode or mixed into horizontal writing mode —
@@ -937,29 +982,35 @@ const WESTERN = /^[\p{Script=Latin}\p{Script=Greek}\p{Script=Cyrillic}]$/u;
937
982
  * the same as a tate-chu-yoko run's 3.2.5.
938
983
  */
939
984
  function classify({ value, presentation }) {
940
- if (presentation === "tate-chu-yoko") return "cl-30";
941
- if (presentation === "upright") return "cl-19";
942
- if (OPENING.has(value)) return "cl-01";
943
- if (CLOSING.has(value)) return "cl-02";
944
- if (HYPHENS.has(value)) return "cl-03";
945
- if (DIVIDING_MARKS.has(value)) return "cl-04";
946
- if (MIDDLE_DOTS.has(value)) return "cl-05";
947
- if (value === "。" || value === ".") return "cl-06";
948
- if (value === "、" || value === ",") return "cl-07";
949
- if (INSEPARABLE.has(value)) return "cl-08";
950
- if (ITERATION_MARKS.has(value)) return "cl-09";
951
- if (value === "ー") return "cl-10";
952
- if (SMALL_KANA.has(value)) return "cl-11";
953
- if (PREFIXED_ABBREVIATIONS.has(value)) return "cl-12";
954
- if (POSTFIXED_ABBREVIATIONS.has(value)) return "cl-13";
955
- if (value === " ") return "cl-14";
956
- if (HIRAGANA.test(value)) return "cl-15";
957
- if (KATAKANA.test(value)) return "cl-16";
958
- if (GROUPED_NUMERAL.test(value)) return "cl-24";
959
- if (UNIT_SYMBOLS.has(value)) return "cl-25";
960
- if (value === " ") return "cl-26";
961
- if (WESTERN.test(value)) return "cl-27";
962
- return "cl-19";
985
+ switch (presentation) {
986
+ case "tate-chu-yoko": return COMBINED_DIVIDING_MARKS.has(value) ? "cl-04" : "cl-30";
987
+ case "upright": return "cl-19";
988
+ case "sideways":
989
+ case "mixed":
990
+ if (presentation === "sideways" && /^[!-~]$/u.test(value) && !/^[A-Za-z0-9]$/u.test(value)) return "cl-27";
991
+ if (OPENING.has(value)) return "cl-01";
992
+ if (CLOSING.has(value)) return "cl-02";
993
+ if (HYPHENS.has(value)) return "cl-03";
994
+ if (DIVIDING_MARKS.has(value)) return "cl-04";
995
+ if (MIDDLE_DOTS.has(value)) return "cl-05";
996
+ if (value === "。" || value === ".") return "cl-06";
997
+ if (value === "、" || value === ",") return "cl-07";
998
+ if (INSEPARABLE.has(value)) return "cl-08";
999
+ if (ITERATION_MARKS.has(value)) return "cl-09";
1000
+ if (value === "ー") return "cl-10";
1001
+ if (SMALL_KANA.has(value)) return "cl-11";
1002
+ if (PREFIXED_ABBREVIATIONS.has(value)) return "cl-12";
1003
+ if (POSTFIXED_ABBREVIATIONS.has(value)) return "cl-13";
1004
+ if (value === " ") return "cl-14";
1005
+ if (HIRAGANA.test(value)) return "cl-15";
1006
+ if (KATAKANA.test(value)) return "cl-16";
1007
+ if (GROUPED_NUMERAL.test(value)) return "cl-24";
1008
+ if (UNIT_SYMBOLS.has(value)) return "cl-25";
1009
+ if (value === " ") return "cl-26";
1010
+ if (WESTERN.test(value)) return "cl-27";
1011
+ return "cl-19";
1012
+ default: return assertNever(presentation);
1013
+ }
963
1014
  }
964
1015
  /**
965
1016
  * 無印 in 表1 with no colour in 表6: the pair is set solid and line adjustment leaves it alone.
@@ -1727,9 +1778,28 @@ const MeasurementSession = { create: (provider, settings) => {
1727
1778
  renderSpan: cluster.renderSpan,
1728
1779
  value: text.slice(cluster.textRange.start, cluster.textRange.end)
1729
1780
  }));
1781
+ const segments = [...graphemeSegmenter.segment(text)];
1782
+ if (kind === "base" && presentation === "tate-chu-yoko") {
1783
+ const advanceEm = full.advanceEm / segments.length;
1784
+ return segments.map(({ segment, index }, position) => {
1785
+ const span = {
1786
+ offsetEm: position * advanceEm,
1787
+ advanceEm
1788
+ };
1789
+ return {
1790
+ value: segment,
1791
+ textRange: MeasurementTextRange.of({
1792
+ start: index,
1793
+ end: index + segment.length
1794
+ }),
1795
+ layoutSpan: span,
1796
+ renderSpan: span
1797
+ };
1798
+ });
1799
+ }
1730
1800
  const pieces = [];
1731
1801
  let offsetEm = 0;
1732
- for (const { segment, index } of graphemeSegmenter.segment(text)) {
1802
+ for (const { segment, index } of segments) {
1733
1803
  const measured = get(segment, kind, presentation);
1734
1804
  if (measured === void 0) return void 0;
1735
1805
  const cluster = measured.kind === "clustered" ? measured.clusters[0] : void 0;
@@ -2772,7 +2842,7 @@ const logicalRunMeasurer = (request) => {
2772
2842
  const segments = [...graphemeSegmenter.segment(request.text)];
2773
2843
  return {
2774
2844
  kind: "advance",
2775
- advanceEm: (request.kind === "base" && request.presentation === "upright" ? segments.length : segments.reduce((total, { segment }) => total + graphemeWidth(segment), 0)) * request.scale
2845
+ advanceEm: (request.kind === "base" && request.presentation === "upright" ? segments.length : request.kind === "base" && request.presentation === "tate-chu-yoko" ? 1 : segments.reduce((total, { segment }) => total + graphemeWidth(segment), 0)) * request.scale
2776
2846
  };
2777
2847
  };
2778
2848
  //#endregion
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-DCgXI574.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";
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 { _ as readonlyObject, c as ValidationIssue, f as NamespacedId, l as ManuscriptResult } from "./question-or-exclamation-spacing-Bv-mF2ZE.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-C0EqiM0f.mjs";
1
+ import { d as ManuscriptResult, m as NamespacedId, u as ValidationIssue, y as readonlyObject } from "./question-or-exclamation-spacing-C5cFLeKr.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-CHNWyvn8.mjs";
3
3
  import * as v from "valibot";
4
4
  const PresentationKind = { schema: v.picklist([
5
5
  "mixed",
@@ -12202,57 +12202,6 @@ declare const novelComposer: Readonly<{
12202
12202
  }> | null;
12203
12203
  inlineSizeEm: number;
12204
12204
  readonly items: readonly (Readonly<{
12205
- kind: "glue";
12206
- origin: "generated";
12207
- offsetEm: number;
12208
- widthEm: number;
12209
- naturalWidthEm: number;
12210
- adjustment: "natural" | "shrunk" | "stretched";
12211
- }> | Readonly<{
12212
- kind: "glue";
12213
- origin: "source";
12214
- value: string;
12215
- readonly range: Readonly<{
12216
- source: Readonly<{
12217
- start: number;
12218
- end: number;
12219
- }> & import("valibot").Brand<"SourceRange">;
12220
- display: Readonly<{
12221
- start: number;
12222
- end: number;
12223
- }> & import("valibot").Brand<"DisplayRange">;
12224
- graphemes: Readonly<{
12225
- start: number;
12226
- end: number;
12227
- }> & import("valibot").Brand<"GraphemeRange">;
12228
- }>;
12229
- offsetEm: number;
12230
- widthEm: number;
12231
- naturalWidthEm: number;
12232
- adjustment: "natural" | "shrunk" | "stretched";
12233
- }> | Readonly<{
12234
- kind: "kern";
12235
- offsetEm: number;
12236
- widthEm: number;
12237
- }> | Readonly<{
12238
- kind: "suppressed";
12239
- value: string;
12240
- readonly range: Readonly<{
12241
- source: Readonly<{
12242
- start: number;
12243
- end: number;
12244
- }> & import("valibot").Brand<"SourceRange">;
12245
- display: Readonly<{
12246
- start: number;
12247
- end: number;
12248
- }> & import("valibot").Brand<"DisplayRange">;
12249
- graphemes: Readonly<{
12250
- start: number;
12251
- end: number;
12252
- }> & import("valibot").Brand<"GraphemeRange">;
12253
- }>;
12254
- reason: "question-or-exclamation-gap";
12255
- }> | Readonly<{
12256
12205
  value: string;
12257
12206
  readonly range: Readonly<{
12258
12207
  source: Readonly<{
@@ -12388,6 +12337,57 @@ declare const novelComposer: Readonly<{
12388
12337
  kind: "combined-glyph";
12389
12338
  presentation: "sideways" | "tate-chu-yoko";
12390
12339
  disposition: "placed";
12340
+ }> | Readonly<{
12341
+ kind: "glue";
12342
+ origin: "generated";
12343
+ offsetEm: number;
12344
+ widthEm: number;
12345
+ naturalWidthEm: number;
12346
+ adjustment: "natural" | "shrunk" | "stretched";
12347
+ }> | Readonly<{
12348
+ kind: "glue";
12349
+ origin: "source";
12350
+ value: string;
12351
+ readonly range: Readonly<{
12352
+ source: Readonly<{
12353
+ start: number;
12354
+ end: number;
12355
+ }> & import("valibot").Brand<"SourceRange">;
12356
+ display: Readonly<{
12357
+ start: number;
12358
+ end: number;
12359
+ }> & import("valibot").Brand<"DisplayRange">;
12360
+ graphemes: Readonly<{
12361
+ start: number;
12362
+ end: number;
12363
+ }> & import("valibot").Brand<"GraphemeRange">;
12364
+ }>;
12365
+ offsetEm: number;
12366
+ widthEm: number;
12367
+ naturalWidthEm: number;
12368
+ adjustment: "natural" | "shrunk" | "stretched";
12369
+ }> | Readonly<{
12370
+ kind: "kern";
12371
+ offsetEm: number;
12372
+ widthEm: number;
12373
+ }> | Readonly<{
12374
+ kind: "suppressed";
12375
+ value: string;
12376
+ readonly range: Readonly<{
12377
+ source: Readonly<{
12378
+ start: number;
12379
+ end: number;
12380
+ }> & import("valibot").Brand<"SourceRange">;
12381
+ display: Readonly<{
12382
+ start: number;
12383
+ end: number;
12384
+ }> & import("valibot").Brand<"DisplayRange">;
12385
+ graphemes: Readonly<{
12386
+ start: number;
12387
+ end: number;
12388
+ }> & import("valibot").Brand<"GraphemeRange">;
12389
+ }>;
12390
+ reason: "question-or-exclamation-gap";
12391
12391
  }>)[];
12392
12392
  break: Readonly<{
12393
12393
  kind: "natural";
@@ -12649,57 +12649,6 @@ declare const novelComposer: Readonly<{
12649
12649
  }> | null;
12650
12650
  inlineSizeEm: number;
12651
12651
  readonly items: readonly (Readonly<{
12652
- kind: "glue";
12653
- origin: "generated";
12654
- offsetEm: number;
12655
- widthEm: number;
12656
- naturalWidthEm: number;
12657
- adjustment: "natural" | "shrunk" | "stretched";
12658
- }> | Readonly<{
12659
- kind: "glue";
12660
- origin: "source";
12661
- value: string;
12662
- readonly range: Readonly<{
12663
- source: Readonly<{
12664
- start: number;
12665
- end: number;
12666
- }> & import("valibot").Brand<"SourceRange">;
12667
- display: Readonly<{
12668
- start: number;
12669
- end: number;
12670
- }> & import("valibot").Brand<"DisplayRange">;
12671
- graphemes: Readonly<{
12672
- start: number;
12673
- end: number;
12674
- }> & import("valibot").Brand<"GraphemeRange">;
12675
- }>;
12676
- offsetEm: number;
12677
- widthEm: number;
12678
- naturalWidthEm: number;
12679
- adjustment: "natural" | "shrunk" | "stretched";
12680
- }> | Readonly<{
12681
- kind: "kern";
12682
- offsetEm: number;
12683
- widthEm: number;
12684
- }> | Readonly<{
12685
- kind: "suppressed";
12686
- value: string;
12687
- readonly range: Readonly<{
12688
- source: Readonly<{
12689
- start: number;
12690
- end: number;
12691
- }> & import("valibot").Brand<"SourceRange">;
12692
- display: Readonly<{
12693
- start: number;
12694
- end: number;
12695
- }> & import("valibot").Brand<"DisplayRange">;
12696
- graphemes: Readonly<{
12697
- start: number;
12698
- end: number;
12699
- }> & import("valibot").Brand<"GraphemeRange">;
12700
- }>;
12701
- reason: "question-or-exclamation-gap";
12702
- }> | Readonly<{
12703
12652
  value: string;
12704
12653
  readonly range: Readonly<{
12705
12654
  source: Readonly<{
@@ -12835,6 +12784,57 @@ declare const novelComposer: Readonly<{
12835
12784
  kind: "combined-glyph";
12836
12785
  presentation: "sideways" | "tate-chu-yoko";
12837
12786
  disposition: "placed";
12787
+ }> | Readonly<{
12788
+ kind: "glue";
12789
+ origin: "generated";
12790
+ offsetEm: number;
12791
+ widthEm: number;
12792
+ naturalWidthEm: number;
12793
+ adjustment: "natural" | "shrunk" | "stretched";
12794
+ }> | Readonly<{
12795
+ kind: "glue";
12796
+ origin: "source";
12797
+ value: string;
12798
+ readonly range: Readonly<{
12799
+ source: Readonly<{
12800
+ start: number;
12801
+ end: number;
12802
+ }> & import("valibot").Brand<"SourceRange">;
12803
+ display: Readonly<{
12804
+ start: number;
12805
+ end: number;
12806
+ }> & import("valibot").Brand<"DisplayRange">;
12807
+ graphemes: Readonly<{
12808
+ start: number;
12809
+ end: number;
12810
+ }> & import("valibot").Brand<"GraphemeRange">;
12811
+ }>;
12812
+ offsetEm: number;
12813
+ widthEm: number;
12814
+ naturalWidthEm: number;
12815
+ adjustment: "natural" | "shrunk" | "stretched";
12816
+ }> | Readonly<{
12817
+ kind: "kern";
12818
+ offsetEm: number;
12819
+ widthEm: number;
12820
+ }> | Readonly<{
12821
+ kind: "suppressed";
12822
+ value: string;
12823
+ readonly range: Readonly<{
12824
+ source: Readonly<{
12825
+ start: number;
12826
+ end: number;
12827
+ }> & import("valibot").Brand<"SourceRange">;
12828
+ display: Readonly<{
12829
+ start: number;
12830
+ end: number;
12831
+ }> & import("valibot").Brand<"DisplayRange">;
12832
+ graphemes: Readonly<{
12833
+ start: number;
12834
+ end: number;
12835
+ }> & import("valibot").Brand<"GraphemeRange">;
12836
+ }>;
12837
+ reason: "question-or-exclamation-gap";
12838
12838
  }>)[];
12839
12839
  break: Readonly<{
12840
12840
  kind: "natural";
@@ -171,6 +171,15 @@ const ValidationIssue = {
171
171
  */
172
172
  const graphemeSegmenter = new Intl.Segmenter("ja", { granularity: "grapheme" });
173
173
  //#endregion
174
+ //#region src/internal/assert-never.ts
175
+ /**
176
+ * Marks a branch the compiler proved unreachable. Reaching it at runtime means a variant was added
177
+ * to a union without updating the switch that produced this call.
178
+ */
179
+ function assertNever(value) {
180
+ throw new TypeError(`unhandled variant: ${JSON.stringify(value)}`);
181
+ }
182
+ //#endregion
174
183
  //#region src/internal/japanese-brackets.ts
175
184
  /**
176
185
  * Brackets and quotes a Japanese paragraph may open with. Halfwidth forms are included because a
@@ -195,6 +204,10 @@ function characterClass(characters) {
195
204
  * neutral.
196
205
  */
197
206
  const DIVIDING_PUNCTUATION = "!?‼⁇⁈⁉";
207
+ /**
208
+ * The marks a short run of which is set as one tate-chu-yoko cell, `!?` reading as `⁉`.
209
+ */
210
+ const TATE_CHU_YOKO_MARKS = "!?!?";
198
211
  //#endregion
199
212
  //#region src/internal/japanese-spaces.ts
200
213
  const LEADING_SPACES = /^[  \t]+/u;
@@ -255,4 +268,4 @@ function questionOrExclamationSpacings(line) {
255
268
  return [...line.matchAll(MARKS)].map((marks) => analyzeMatch(line, marks)).filter((spacing) => spacing !== void 0);
256
269
  }
257
270
  //#endregion
258
- export { readonlyObject as _, OPENING_BRACKETS as a, ValidationIssue as c, DiagnosticSeverity as d, NamespacedId as f, readonlyArray as g, nonNegativeInteger as h, CLOSING_BRACKETS as i, ManuscriptResult as l, TextRange as m, leadingSpaces as n, characterClass as o, ManuscriptRange as p, DIVIDING_PUNCTUATION as r, graphemeSegmenter as s, questionOrExclamationSpacings as t, ManuscriptDiagnostic as u };
271
+ export { nonNegativeInteger as _, CLOSING_BRACKETS as a, assertNever as c, ManuscriptResult as d, ManuscriptDiagnostic as f, TextRange as g, ManuscriptRange as h, TATE_CHU_YOKO_MARKS as i, graphemeSegmenter as l, NamespacedId as m, leadingSpaces as n, OPENING_BRACKETS as o, DiagnosticSeverity as p, DIVIDING_PUNCTUATION as r, characterClass as s, questionOrExclamationSpacings as t, ValidationIssue as u, readonlyArray as v, readonlyObject as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sushichan044/kg-core",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "Framework-independent parsing, composition, and proofreading for Japanese manuscripts",
5
5
  "keywords": [
6
6
  "japanese",
@@ -1,18 +0,0 @@
1
- //#region src/internal/assert-never.ts
2
- /**
3
- * Marks a branch the compiler proved unreachable. Reaching it at runtime means a variant was added
4
- * to a union without updating the switch that produced this call.
5
- */
6
- function assertNever(value) {
7
- throw new TypeError(`unhandled variant: ${JSON.stringify(value)}`);
8
- }
9
- //#endregion
10
- //#region src/internal/describe-cause.ts
11
- /**
12
- * Renders an unknown throwable for display, without assuming it is an Error.
13
- */
14
- function describeCause(cause) {
15
- return cause instanceof Error ? cause.message : String(cause);
16
- }
17
- //#endregion
18
- export { assertNever as n, describeCause as t };