@sushichan044/kg-core 0.11.1 → 0.11.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/README.md +27 -3
- package/dist/index.d.mts +307 -307
- package/dist/index.mjs +2 -2
- package/dist/lint.d.mts +5 -7
- package/dist/lint.mjs +29 -18
- package/dist/{novel-composer-z0cv8OHb.mjs → novel-composer-tcseYHc8.mjs} +59 -18
- package/dist/plugin.d.mts +1 -1
- package/dist/plugin.mjs +2 -2
- package/dist/{presentation-kind-CvlmQ3AY.d.mts → presentation-kind-DnJkvxHU.d.mts} +1003 -989
- package/dist/{question-or-exclamation-spacing-C5cFLeKr.mjs → question-or-exclamation-spacing-D7TSDUG8.mjs} +38 -22
- package/package.json +1 -1
package/dist/lint.d.mts
CHANGED
|
@@ -440,13 +440,11 @@ export declare function createParagraphOpeningRule(options?: ParagraphOpeningOpt
|
|
|
440
440
|
export declare const punctuationBeforeClosingQuoteRule: () => ParsedProofreadingRule;
|
|
441
441
|
//#endregion
|
|
442
442
|
//#region src/proofreading/rules/space-after-question-or-exclamation.d.ts
|
|
443
|
-
/**
|
|
444
|
-
* The gap that follows every run of ! or ? (区切り約物, JLReq 3.1.6). A dividing punctuation mark ends a
|
|
445
|
-
* sentence without a full stop, so a full em of white stands in for the one a 句点 would have
|
|
446
|
-
* carried. A run at the end of a line or right before a closing bracket is already separated from
|
|
447
|
-
* what follows and needs no gap; anywhere else it takes exactly one ideographic space.
|
|
448
|
-
*/
|
|
449
443
|
export declare const spaceAfterQuestionOrExclamationRule: () => ParsedProofreadingRule;
|
|
444
|
+
type SpaceAfterQuestionOrExclamationOptions = Readonly<{
|
|
445
|
+
additionalSentenceEndingMarks?: string;
|
|
446
|
+
}>;
|
|
447
|
+
export declare function createSpaceAfterQuestionOrExclamationRule(options?: SpaceAfterQuestionOrExclamationOptions): ManuscriptResult<ParsedProofreadingRule, InvalidRuleOptions>;
|
|
450
448
|
//#endregion
|
|
451
449
|
//#region src/proofreading/rules/variant-character.d.ts
|
|
452
450
|
/**
|
|
@@ -458,4 +456,4 @@ export declare const spaceAfterQuestionOrExclamationRule: () => ParsedProofreadi
|
|
|
458
456
|
*/
|
|
459
457
|
export declare const variantCharacterRule: () => ParsedProofreadingRule;
|
|
460
458
|
//#endregion
|
|
461
|
-
export type { ComposedProofreadingRule, ConsistentKanjiOpeningOptions, DashOptions, KanjiOpeningPair, MaxArabicNumeralDigitsOptions, ParagraphOpeningOptions, ParsedProofreadingRule, ProofreadOptions, ProofreadingReport, ProofreadingRule, ProofreadingRuleContext, ProofreadingRuleMessages };
|
|
459
|
+
export type { ComposedProofreadingRule, ConsistentKanjiOpeningOptions, DashOptions, KanjiOpeningPair, MaxArabicNumeralDigitsOptions, ParagraphOpeningOptions, ParsedProofreadingRule, ProofreadOptions, ProofreadingReport, ProofreadingRule, ProofreadingRuleContext, ProofreadingRuleMessages, SpaceAfterQuestionOrExclamationOptions };
|
package/dist/lint.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { _ as ManuscriptRange, a as characterClass, b as readonlyArray, d as graphemeSegmenter, f as ValidationIssue, g as NamespacedId, h as DiagnosticSeverity, i as OPENING_BRACKETS, l as validAdditionalSentenceEndingMarks, m as ManuscriptDiagnostic, n as leadingSpaces, p as ManuscriptResult, r as CLOSING_BRACKETS, t as questionOrExclamationSpacings, u as assertNever, x as readonlyObject } from "./question-or-exclamation-spacing-D7TSDUG8.mjs";
|
|
2
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
|
|
@@ -333,7 +333,7 @@ const DEFAULT_PAIRS = [
|
|
|
333
333
|
* Reports the first kanji occurrence of every pair the manuscript also writes in kana. Whether the
|
|
334
334
|
* two spellings are a deliberate distinction is the author's call, so the finding is a warning.
|
|
335
335
|
*/
|
|
336
|
-
function build$
|
|
336
|
+
function build$4(pairs) {
|
|
337
337
|
return defineParsedRule(RULE_ID$5, MESSAGE, (manuscript, report) => {
|
|
338
338
|
for (const { closed, opened } of pairs) {
|
|
339
339
|
if (!manuscript.displayText.includes(opened)) continue;
|
|
@@ -349,7 +349,7 @@ function build$3(pairs) {
|
|
|
349
349
|
}
|
|
350
350
|
});
|
|
351
351
|
}
|
|
352
|
-
const consistentKanjiOpeningRule = () => build$
|
|
352
|
+
const consistentKanjiOpeningRule = () => build$4(DEFAULT_PAIRS);
|
|
353
353
|
function createConsistentKanjiOpeningRule(options = {}) {
|
|
354
354
|
if (options.pairs === void 0) return ManuscriptResult.succeed(consistentKanjiOpeningRule());
|
|
355
355
|
const pairs = v.safeParse(PairsSchema, options.pairs);
|
|
@@ -359,7 +359,7 @@ function createConsistentKanjiOpeningRule(options = {}) {
|
|
|
359
359
|
option: "pairs",
|
|
360
360
|
issues: ValidationIssue.from(pairs.issues)
|
|
361
361
|
});
|
|
362
|
-
return ManuscriptResult.succeed(build$
|
|
362
|
+
return ManuscriptResult.succeed(build$4(pairs.output));
|
|
363
363
|
}
|
|
364
364
|
//#endregion
|
|
365
365
|
//#region src/proofreading/rules/internal/mixed-width.ts
|
|
@@ -431,7 +431,7 @@ function messageIdFor(run, preferred) {
|
|
|
431
431
|
* must match, since only a repeat of the same character joins without a seam. JLReq classes the
|
|
432
432
|
* dash as 分離禁止文字 (cl-08) for the same reason: the pair must not be split across lines.
|
|
433
433
|
*/
|
|
434
|
-
function build$
|
|
434
|
+
function build$3(preferred) {
|
|
435
435
|
const messages = {
|
|
436
436
|
character: `ダッシュには「${preferred}」を使ってください`,
|
|
437
437
|
"even-count": EVEN_COUNT_MESSAGE
|
|
@@ -462,7 +462,7 @@ function build$2(preferred) {
|
|
|
462
462
|
}
|
|
463
463
|
};
|
|
464
464
|
}
|
|
465
|
-
const dashRule = () => build$
|
|
465
|
+
const dashRule = () => build$3(DEFAULT_PREFERRED);
|
|
466
466
|
function createDashRule(options = {}) {
|
|
467
467
|
if (options.preferred === void 0) return ManuscriptResult.succeed(dashRule());
|
|
468
468
|
const preferred = v.safeParse(DashCharacterSchema, options.preferred);
|
|
@@ -472,7 +472,7 @@ function createDashRule(options = {}) {
|
|
|
472
472
|
option: "preferred",
|
|
473
473
|
issues: ValidationIssue.from(preferred.issues)
|
|
474
474
|
});
|
|
475
|
-
return ManuscriptResult.succeed(build$
|
|
475
|
+
return ManuscriptResult.succeed(build$3(preferred.output));
|
|
476
476
|
}
|
|
477
477
|
//#endregion
|
|
478
478
|
//#region src/proofreading/rules/ellipsis-character.ts
|
|
@@ -582,7 +582,7 @@ const MaxDigitsSchema = v.pipe(v.number(), v.finite(), v.integer(), v.minValue(1
|
|
|
582
582
|
* upright inside one em, but a longer one has nowhere to go: it either turns the line sideways or
|
|
583
583
|
* breaks across it. The usual limit is two digits, past which a novel spells the number in kanji.
|
|
584
584
|
*/
|
|
585
|
-
function build$
|
|
585
|
+
function build$2(maxDigits) {
|
|
586
586
|
return defineMatchRule({
|
|
587
587
|
id: RULE_ID$2,
|
|
588
588
|
pattern: /([0-90-9]+)(?:[..]([0-90-9]+))?/gu,
|
|
@@ -590,7 +590,7 @@ function build$1(maxDigits) {
|
|
|
590
590
|
message: `${maxDigits}桁を超えるアラビア数字が使われています`
|
|
591
591
|
});
|
|
592
592
|
}
|
|
593
|
-
const maxArabicNumeralDigitsRule = () => build$
|
|
593
|
+
const maxArabicNumeralDigitsRule = () => build$2(DEFAULT_MAX_DIGITS);
|
|
594
594
|
function createMaxArabicNumeralDigitsRule(options = {}) {
|
|
595
595
|
if (options.maxDigits === void 0) return ManuscriptResult.succeed(maxArabicNumeralDigitsRule());
|
|
596
596
|
const maxDigits = v.safeParse(MaxDigitsSchema, options.maxDigits);
|
|
@@ -600,7 +600,7 @@ function createMaxArabicNumeralDigitsRule(options = {}) {
|
|
|
600
600
|
option: "maxDigits",
|
|
601
601
|
issues: ValidationIssue.from(maxDigits.issues)
|
|
602
602
|
});
|
|
603
|
-
return ManuscriptResult.succeed(build$
|
|
603
|
+
return ManuscriptResult.succeed(build$2(maxDigits.output));
|
|
604
604
|
}
|
|
605
605
|
//#endregion
|
|
606
606
|
//#region src/proofreading/rules/minus-before-number.ts
|
|
@@ -664,7 +664,7 @@ const OpeningBracketsSchema = v.pipe(v.string(), v.nonEmpty());
|
|
|
664
664
|
* The three findings are branches of that one decision rather than separate rules, so a line can
|
|
665
665
|
* never collect two of them at once.
|
|
666
666
|
*/
|
|
667
|
-
function build(openingBrackets) {
|
|
667
|
+
function build$1(openingBrackets) {
|
|
668
668
|
return {
|
|
669
669
|
kind: "parsed",
|
|
670
670
|
meta: {
|
|
@@ -693,7 +693,7 @@ function build(openingBrackets) {
|
|
|
693
693
|
}
|
|
694
694
|
};
|
|
695
695
|
}
|
|
696
|
-
const paragraphOpeningRule = () => build(OPENING_BRACKETS);
|
|
696
|
+
const paragraphOpeningRule = () => build$1(OPENING_BRACKETS);
|
|
697
697
|
function createParagraphOpeningRule(options = {}) {
|
|
698
698
|
if (options.openingBrackets === void 0) return ManuscriptResult.succeed(paragraphOpeningRule());
|
|
699
699
|
const brackets = v.safeParse(OpeningBracketsSchema, options.openingBrackets);
|
|
@@ -703,7 +703,7 @@ function createParagraphOpeningRule(options = {}) {
|
|
|
703
703
|
option: "openingBrackets",
|
|
704
704
|
issues: ValidationIssue.from(brackets.issues)
|
|
705
705
|
});
|
|
706
|
-
return ManuscriptResult.succeed(build(brackets.output));
|
|
706
|
+
return ManuscriptResult.succeed(build$1(brackets.output));
|
|
707
707
|
}
|
|
708
708
|
//#endregion
|
|
709
709
|
//#region src/proofreading/rules/punctuation-before-closing-quote.ts
|
|
@@ -722,8 +722,8 @@ const punctuationBeforeClosingQuoteRule = () => defineMatchRule({
|
|
|
722
722
|
//#region src/proofreading/rules/space-after-question-or-exclamation.ts
|
|
723
723
|
const RULE_ID = "kg/space-after-question-or-exclamation";
|
|
724
724
|
const MESSAGES = {
|
|
725
|
-
default: "
|
|
726
|
-
"space-width": "
|
|
725
|
+
default: "文末記号の直後には全角スペースか閉じ括弧が必要です",
|
|
726
|
+
"space-width": "文末記号の直後の空白は全角スペース1字にしてください",
|
|
727
727
|
"before-closing-bracket": "閉じ括弧の直前に空白を置くことはできません"
|
|
728
728
|
};
|
|
729
729
|
/**
|
|
@@ -732,7 +732,7 @@ const MESSAGES = {
|
|
|
732
732
|
* carried. A run at the end of a line or right before a closing bracket is already separated from
|
|
733
733
|
* what follows and needs no gap; anywhere else it takes exactly one ideographic space.
|
|
734
734
|
*/
|
|
735
|
-
const
|
|
735
|
+
const build = (additionalSentenceEndingMarks = "") => ({
|
|
736
736
|
kind: "parsed",
|
|
737
737
|
meta: {
|
|
738
738
|
id: RULE_ID,
|
|
@@ -745,7 +745,7 @@ const spaceAfterQuestionOrExclamationRule = () => ({
|
|
|
745
745
|
messageId
|
|
746
746
|
});
|
|
747
747
|
};
|
|
748
|
-
for (const line of splitDisplayLines(manuscript.displayText)) for (const spacing of questionOrExclamationSpacings(line.text)) switch (spacing.kind) {
|
|
748
|
+
for (const line of splitDisplayLines(manuscript.displayText)) for (const spacing of questionOrExclamationSpacings(line.text, additionalSentenceEndingMarks)) switch (spacing.kind) {
|
|
749
749
|
case "valid": break;
|
|
750
750
|
case "missing":
|
|
751
751
|
report(line.start + spacing.marks.start, line.start + spacing.marks.end, "default");
|
|
@@ -760,6 +760,17 @@ const spaceAfterQuestionOrExclamationRule = () => ({
|
|
|
760
760
|
}
|
|
761
761
|
}
|
|
762
762
|
});
|
|
763
|
+
const spaceAfterQuestionOrExclamationRule = () => build();
|
|
764
|
+
function createSpaceAfterQuestionOrExclamationRule(options = {}) {
|
|
765
|
+
const result = v.safeParse(v.pipe(v.string(), v.check(validAdditionalSentenceEndingMarks)), options.additionalSentenceEndingMarks === void 0 ? "" : options.additionalSentenceEndingMarks);
|
|
766
|
+
if (!result.success) return ManuscriptResult.fail({
|
|
767
|
+
kind: "InvalidRuleOptions",
|
|
768
|
+
ruleId: RULE_ID,
|
|
769
|
+
option: "additionalSentenceEndingMarks",
|
|
770
|
+
issues: ValidationIssue.from(result.issues)
|
|
771
|
+
});
|
|
772
|
+
return ManuscriptResult.succeed(build(result.output));
|
|
773
|
+
}
|
|
763
774
|
//#endregion
|
|
764
775
|
//#region src/proofreading/rules/variant-character.ts
|
|
765
776
|
/**
|
|
@@ -809,4 +820,4 @@ function createDefaultProofreadingRules() {
|
|
|
809
820
|
];
|
|
810
821
|
}
|
|
811
822
|
//#endregion
|
|
812
|
-
export { InvalidRuleOptions, ProofreadError, ProofreadingRuleMeta, consistentKanjiOpeningRule, consistentLatinWidthRule, consistentNumeralWidthRule, createConsistentKanjiOpeningRule, createDashRule, createDefaultProofreadingRules, createMaxArabicNumeralDigitsRule, createParagraphOpeningRule, dashRule, ellipsisCharacterRule, evenEllipsisRule, fullwidthJapanesePunctuationRule, maxArabicNumeralDigitsRule, minusBeforeNumberRule, noConsecutiveInterpunctRule, noConsecutivePunctuationRule, paragraphOpeningRule, proofreadManuscript, punctuationBeforeClosingQuoteRule, spaceAfterQuestionOrExclamationRule, variantCharacterRule };
|
|
823
|
+
export { InvalidRuleOptions, ProofreadError, ProofreadingRuleMeta, consistentKanjiOpeningRule, consistentLatinWidthRule, consistentNumeralWidthRule, createConsistentKanjiOpeningRule, createDashRule, createDefaultProofreadingRules, createMaxArabicNumeralDigitsRule, createParagraphOpeningRule, createSpaceAfterQuestionOrExclamationRule, dashRule, ellipsisCharacterRule, evenEllipsisRule, fullwidthJapanesePunctuationRule, maxArabicNumeralDigitsRule, minusBeforeNumberRule, noConsecutiveInterpunctRule, noConsecutivePunctuationRule, paragraphOpeningRule, proofreadManuscript, punctuationBeforeClosingQuoteRule, spaceAfterQuestionOrExclamationRule, variantCharacterRule };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { _ as ManuscriptRange, a as characterClass, b as readonlyArray, c as isSentenceEndingMark, d as graphemeSegmenter, g as NamespacedId, i as OPENING_BRACKETS, l as validAdditionalSentenceEndingMarks, o as SENTENCE_ENDING_MARKS, p as ManuscriptResult, r as CLOSING_BRACKETS, s as TATE_CHU_YOKO_MARKS, t as questionOrExclamationSpacings, u as assertNever, v as TextRange, x as readonlyObject, y as nonNegativeInteger } from "./question-or-exclamation-spacing-D7TSDUG8.mjs";
|
|
2
2
|
import * as v from "valibot";
|
|
3
3
|
import { eastAsianWidth } from "get-east-asian-width";
|
|
4
4
|
const BoldAnnotation = { schema: readonlyObject({
|
|
@@ -116,6 +116,22 @@ const A5_PAGE_FORMAT = {
|
|
|
116
116
|
outerMm: 13
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
|
+
const A6_PAGE_FORMAT = {
|
|
120
|
+
fontSizeQ: 12,
|
|
121
|
+
flow: {
|
|
122
|
+
lineLengthEm: 41,
|
|
123
|
+
linesPerStage: 17,
|
|
124
|
+
stagesPerPage: 1
|
|
125
|
+
},
|
|
126
|
+
page: {
|
|
127
|
+
lineGapMm: 7 / 4,
|
|
128
|
+
stageGapMm: 0,
|
|
129
|
+
topMm: 12.5,
|
|
130
|
+
bottomMm: 12.5,
|
|
131
|
+
innerMm: 16,
|
|
132
|
+
outerMm: 10
|
|
133
|
+
}
|
|
134
|
+
};
|
|
119
135
|
//#endregion
|
|
120
136
|
//#region src/appearance/font-preset-id.ts
|
|
121
137
|
const FontPresetIdSchema = v.picklist(["mincho", "gothic"]);
|
|
@@ -331,6 +347,7 @@ const NovelFlowSettings = {
|
|
|
331
347
|
//#endregion
|
|
332
348
|
//#region src/composer/composition-settings.ts
|
|
333
349
|
const NovelCompositionSettingsSchema = v.pipe(readonlyObject({
|
|
350
|
+
additionalSentenceEndingMarks: v.optional(v.pipe(v.string(), v.check(validAdditionalSentenceEndingMarks))),
|
|
334
351
|
flow: NovelFlowSettings.schema,
|
|
335
352
|
offsets: ManuscriptOffsets.schema,
|
|
336
353
|
appearance: ManuscriptAppearanceSettings.schema,
|
|
@@ -338,7 +355,10 @@ const NovelCompositionSettingsSchema = v.pipe(readonlyObject({
|
|
|
338
355
|
}), 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
356
|
const geometry = ManuscriptGeometry.of(flow, appearance, page);
|
|
340
357
|
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 }) =>
|
|
358
|
+
}, "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 }) => {
|
|
359
|
+
const format = appearance.paperSize === "a5" ? A5_PAGE_FORMAT : appearance.paperSize === "a6" ? A6_PAGE_FORMAT : null;
|
|
360
|
+
return format === null || appearance.fontSizeQ === format.fontSizeQ && flow.lineLengthEm === format.flow.lineLengthEm && flow.linesPerStage === format.flow.linesPerStage && flow.stagesPerPage === format.flow.stagesPerPage && page.lineGapMm === format.page.lineGapMm && page.stageGapMm === format.page.stageGapMm && page.topMm === format.page.topMm && page.bottomMm === format.page.bottomMm && page.innerMm === format.page.innerMm && page.outerMm === format.page.outerMm;
|
|
361
|
+
}, "A5 and A6 use their fixed page formats"));
|
|
342
362
|
const NovelCompositionSettings = {
|
|
343
363
|
schema: NovelCompositionSettingsSchema,
|
|
344
364
|
defaults: {
|
|
@@ -348,21 +368,22 @@ const NovelCompositionSettings = {
|
|
|
348
368
|
page: ManuscriptPageSettings.defaults
|
|
349
369
|
},
|
|
350
370
|
/**
|
|
351
|
-
* Select the fixed A5 format, or centre the current grid on another paper size.
|
|
371
|
+
* Select the fixed A5 or A6 format, or centre the current grid on another paper size.
|
|
352
372
|
*/
|
|
353
373
|
forPaper: (paperSize, settings) => {
|
|
354
374
|
const appearance = {
|
|
355
375
|
...settings.appearance,
|
|
356
376
|
paperSize
|
|
357
377
|
};
|
|
358
|
-
|
|
378
|
+
const format = paperSize === "a5" ? A5_PAGE_FORMAT : paperSize === "a6" ? A6_PAGE_FORMAT : null;
|
|
379
|
+
if (format !== null) return {
|
|
359
380
|
...settings,
|
|
360
|
-
flow:
|
|
381
|
+
flow: format.flow,
|
|
361
382
|
appearance: {
|
|
362
383
|
...appearance,
|
|
363
|
-
fontSizeQ:
|
|
384
|
+
fontSizeQ: format.fontSizeQ
|
|
364
385
|
},
|
|
365
|
-
page:
|
|
386
|
+
page: format.page
|
|
366
387
|
};
|
|
367
388
|
return {
|
|
368
389
|
...settings,
|
|
@@ -524,7 +545,7 @@ function presentationOf(text) {
|
|
|
524
545
|
* Recognize sentence-wide presentation while keeping words as separate line-break units. Standalone
|
|
525
546
|
* dotted abbreviations retain the existing per-token presentation.
|
|
526
547
|
*/
|
|
527
|
-
function
|
|
548
|
+
function recognizeText(graphemes) {
|
|
528
549
|
const runs = [];
|
|
529
550
|
const push = (members, presentation) => {
|
|
530
551
|
const range = ManuscriptRange.merge(members.map((member) => member.range));
|
|
@@ -569,6 +590,25 @@ function recognize(graphemes) {
|
|
|
569
590
|
}
|
|
570
591
|
return runs;
|
|
571
592
|
}
|
|
593
|
+
/**
|
|
594
|
+
* Split configured symbols before recognizing western words and presentation runs.
|
|
595
|
+
*/
|
|
596
|
+
function recognize(graphemes, additionalSentenceEndingMarks = "") {
|
|
597
|
+
const runs = [];
|
|
598
|
+
let start = 0;
|
|
599
|
+
for (const [index, grapheme] of graphemes.entries()) {
|
|
600
|
+
if (!isSentenceEndingMark(grapheme.value, additionalSentenceEndingMarks) || isSentenceEndingMark(grapheme.value)) continue;
|
|
601
|
+
runs.push(...recognizeText(graphemes.slice(start, index)));
|
|
602
|
+
runs.push({
|
|
603
|
+
range: grapheme.range,
|
|
604
|
+
members: [grapheme],
|
|
605
|
+
presentation: "mixed"
|
|
606
|
+
});
|
|
607
|
+
start = index + 1;
|
|
608
|
+
}
|
|
609
|
+
runs.push(...recognizeText(graphemes.slice(start)));
|
|
610
|
+
return runs;
|
|
611
|
+
}
|
|
572
612
|
const CompositionRun = { recognize };
|
|
573
613
|
//#endregion
|
|
574
614
|
//#region src/composer/internal/emphasis-placement.ts
|
|
@@ -1096,7 +1136,7 @@ const boundaryClasses = [
|
|
|
1096
1136
|
const OPENING = /* @__PURE__ */ new Set(`${OPENING_BRACKETS}【〘〝⦅«`);
|
|
1097
1137
|
const CLOSING = /* @__PURE__ */ new Set(`${CLOSING_BRACKETS}】〙〟⦆»`);
|
|
1098
1138
|
const HYPHENS = /* @__PURE__ */ new Set("‐‑⁃–");
|
|
1099
|
-
const DIVIDING_MARKS = new Set(
|
|
1139
|
+
const DIVIDING_MARKS = new Set(SENTENCE_ENDING_MARKS);
|
|
1100
1140
|
const COMBINED_DIVIDING_MARKS = new Set(TATE_CHU_YOKO_MARKS);
|
|
1101
1141
|
const MIDDLE_DOTS = /* @__PURE__ */ new Set("・:;");
|
|
1102
1142
|
const SMALL_KANA = /* @__PURE__ */ new Set("ァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖ");
|
|
@@ -2688,8 +2728,8 @@ const RubyLineLayout = {
|
|
|
2688
2728
|
};
|
|
2689
2729
|
//#endregion
|
|
2690
2730
|
//#region src/composer/internal/source-space.ts
|
|
2691
|
-
const SourceSpace = { collect: (graphemes, advancesEm) => {
|
|
2692
|
-
const gaps = new Set(questionOrExclamationSpacings(graphemes.map(({ value }) => value).join("")).filter((spacing) => spacing.kind === "valid").map(({ gap }) => gap.start));
|
|
2731
|
+
const SourceSpace = { collect: (graphemes, advancesEm, additionalSentenceEndingMarks = "") => {
|
|
2732
|
+
const gaps = new Set(questionOrExclamationSpacings(graphemes.map(({ value }) => value).join(""), additionalSentenceEndingMarks).filter((spacing) => spacing.kind === "valid").map(({ gap }) => gap.start));
|
|
2693
2733
|
let offset = 0;
|
|
2694
2734
|
return graphemes.flatMap((grapheme, index) => {
|
|
2695
2735
|
const separator = gaps.has(offset);
|
|
@@ -2854,7 +2894,7 @@ function graphemeWidth(grapheme) {
|
|
|
2854
2894
|
for (const character of grapheme) {
|
|
2855
2895
|
const codePoint = character.codePointAt(0);
|
|
2856
2896
|
if (codePoint !== void 0) {
|
|
2857
|
-
const characterWidth =
|
|
2897
|
+
const characterWidth = SENTENCE_ENDING_MARKS.includes(character) ? 2 : eastAsianWidth(codePoint, { ambiguousAsWide: true });
|
|
2858
2898
|
width = Math.max(width, characterWidth);
|
|
2859
2899
|
}
|
|
2860
2900
|
}
|
|
@@ -2889,8 +2929,8 @@ function displayedLines(graphemes) {
|
|
|
2889
2929
|
if (lines.length > 1 && endedWithLineBreak) lines.pop();
|
|
2890
2930
|
return lines;
|
|
2891
2931
|
}
|
|
2892
|
-
function measureSourceLine(sourceLine, annotations, measurements) {
|
|
2893
|
-
const runs = CompositionRun.recognize(sourceLine);
|
|
2932
|
+
function measureSourceLine(sourceLine, annotations, measurements, additionalSentenceEndingMarks) {
|
|
2933
|
+
const runs = CompositionRun.recognize(sourceLine, additionalSentenceEndingMarks);
|
|
2894
2934
|
const rubyAssociations = RubyAssociation.collect(annotations, sourceLine);
|
|
2895
2935
|
const atoms = [];
|
|
2896
2936
|
for (const [runIndex, run] of runs.entries()) {
|
|
@@ -2907,11 +2947,12 @@ function measureSourceLine(sourceLine, annotations, measurements) {
|
|
|
2907
2947
|
const first = memberIndex === 0;
|
|
2908
2948
|
const renderAdvanceEm = first ? piece.renderSpan.advanceEm : 0;
|
|
2909
2949
|
const measuredAdvanceEm = first ? piece.layoutSpan.advanceEm : 0;
|
|
2910
|
-
const
|
|
2950
|
+
const sentenceEndingMark = isSentenceEndingMark(grapheme.value, additionalSentenceEndingMarks);
|
|
2951
|
+
const characterClass = sentenceEndingMark ? "cl-04" : TYPESETTING_PROFILE.classify({
|
|
2911
2952
|
value: grapheme.value,
|
|
2912
2953
|
presentation: run.presentation
|
|
2913
2954
|
});
|
|
2914
|
-
const metrics = TYPESETTING_PROFILE.boxMetrics(characterClass, measuredAdvanceEm);
|
|
2955
|
+
const metrics = TYPESETTING_PROFILE.boxMetrics(characterClass, sentenceEndingMark && !combineRun ? 1 : measuredAdvanceEm);
|
|
2915
2956
|
atoms.push({
|
|
2916
2957
|
grapheme,
|
|
2917
2958
|
runIndex,
|
|
@@ -2965,7 +3006,7 @@ function measureSourceLine(sourceLine, annotations, measurements) {
|
|
|
2965
3006
|
});
|
|
2966
3007
|
}
|
|
2967
3008
|
}
|
|
2968
|
-
const sourceSpaces = SourceSpace.collect(sourceLine, atoms.map(({ boxAdvanceEm }) => boxAdvanceEm));
|
|
3009
|
+
const sourceSpaces = SourceSpace.collect(sourceLine, atoms.map(({ boxAdvanceEm }) => boxAdvanceEm), additionalSentenceEndingMarks);
|
|
2969
3010
|
return {
|
|
2970
3011
|
atoms,
|
|
2971
3012
|
runs,
|
|
@@ -3408,7 +3449,7 @@ function createCompose(provider) {
|
|
|
3408
3449
|
return (manuscript, settings) => {
|
|
3409
3450
|
const measurements = MeasurementSession.create(provider, settings);
|
|
3410
3451
|
const sourceLines = displayedLines(manuscript.graphemes);
|
|
3411
|
-
const measured = sourceLines.map((line) => measureSourceLine(line, manuscript.annotations, measurements));
|
|
3452
|
+
const measured = sourceLines.map((line) => measureSourceLine(line, manuscript.annotations, measurements, settings.additionalSentenceEndingMarks ?? ""));
|
|
3412
3453
|
if (measured.some((line) => line === void 0)) return ManuscriptResult.fail({ reason: "run measurer returned invalid metrics or cluster mappings" });
|
|
3413
3454
|
const manuscriptLines = [];
|
|
3414
3455
|
for (const line of measured) {
|
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, f as ManuscriptComposer, m as Rejection, o as logicalRunMeasurer, p as ManuscriptParser, r as createNovelComposer, s as RunMeasurement, t as PresentationKind } from "./presentation-kind-
|
|
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-DnJkvxHU.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 {
|
|
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-
|
|
1
|
+
import { f as ValidationIssue, g as NamespacedId, p as ManuscriptResult, x as readonlyObject } from "./question-or-exclamation-spacing-D7TSDUG8.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-tcseYHc8.mjs";
|
|
3
3
|
import * as v from "valibot";
|
|
4
4
|
const PresentationKind = { schema: v.picklist([
|
|
5
5
|
"mixed",
|