@sushichan044/kg-core 0.11.1 → 0.11.3
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 +46 -3
- package/dist/index.d.mts +344 -317
- package/dist/index.mjs +157 -6
- package/dist/lint.d.mts +5 -7
- package/dist/lint.mjs +29 -18
- package/dist/{novel-composer-z0cv8OHb.mjs → novel-composer-DNsKrJIP.mjs} +141 -56
- package/dist/plugin.d.mts +1 -1
- package/dist/plugin.mjs +6 -2
- package/dist/{presentation-kind-CvlmQ3AY.d.mts → presentation-kind-BmW1Edu7.d.mts} +1068 -1010
- package/dist/{question-or-exclamation-spacing-C5cFLeKr.mjs → question-or-exclamation-spacing-D7TSDUG8.mjs} +38 -22
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { _ as ParsedManuscript, c as NovelFlowSettings, d as ManuscriptPageSettings, f as PaperSize, g as FontPresetId, h as FontSizeQ, l as ManuscriptOffsets, m as PaperSizeId, n as novelComposer, p as ManuscriptAppearanceSettings, s as NovelCompositionSettings, u as ManuscriptGeometry } from "./novel-composer-
|
|
1
|
+
import { _ as ManuscriptRange, d as graphemeSegmenter, f as ValidationIssue, g as NamespacedId, m as ManuscriptDiagnostic, p as ManuscriptResult, u as assertNever, x as readonlyObject } from "./question-or-exclamation-spacing-D7TSDUG8.mjs";
|
|
2
|
+
import { _ as ParsedManuscript, c as NovelFlowSettings, d as ManuscriptPageSettings, f as PaperSize, g as FontPresetId, h as FontSizeQ, l as ManuscriptOffsets, m as PaperSizeId, n as novelComposer, p as ManuscriptAppearanceSettings, s as NovelCompositionSettings, u as ManuscriptGeometry } from "./novel-composer-DNsKrJIP.mjs";
|
|
3
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() }) };
|
|
@@ -598,16 +598,48 @@ function joinIssues(issues) {
|
|
|
598
598
|
}
|
|
599
599
|
//#endregion
|
|
600
600
|
//#region src/appearance/font-preset.ts
|
|
601
|
+
const FIXED_PITCH = {
|
|
602
|
+
features: {
|
|
603
|
+
palt: 0,
|
|
604
|
+
vpal: 0,
|
|
605
|
+
halt: 0,
|
|
606
|
+
vhal: 0,
|
|
607
|
+
vkrn: 0,
|
|
608
|
+
liga: 1
|
|
609
|
+
},
|
|
610
|
+
westernKerning: "normal",
|
|
611
|
+
synthesis: "weight style"
|
|
612
|
+
};
|
|
601
613
|
const FONT_PRESETS = {
|
|
602
614
|
mincho: {
|
|
603
615
|
id: "mincho",
|
|
604
|
-
label: "
|
|
605
|
-
|
|
616
|
+
label: "倫明朝",
|
|
617
|
+
fontName: "KGRinMincho100",
|
|
618
|
+
family: "\"KGRinMincho100\", \"Yu Mincho\", \"Hiragino Mincho ProN\", serif",
|
|
619
|
+
textTransforms: ["combine-kana-voicing-marks"],
|
|
620
|
+
measurement: "browser-shaped",
|
|
621
|
+
rendering: {
|
|
622
|
+
...FIXED_PITCH,
|
|
623
|
+
synthesis: "style"
|
|
624
|
+
}
|
|
606
625
|
},
|
|
607
626
|
gothic: {
|
|
608
627
|
id: "gothic",
|
|
609
628
|
label: "ゴシック",
|
|
610
|
-
|
|
629
|
+
fontName: "",
|
|
630
|
+
family: "\"Yu Gothic\", \"Hiragino Kaku Gothic ProN\", system-ui, sans-serif",
|
|
631
|
+
textTransforms: [],
|
|
632
|
+
measurement: "logical",
|
|
633
|
+
rendering: FIXED_PITCH
|
|
634
|
+
},
|
|
635
|
+
"genei-koburi": {
|
|
636
|
+
id: "genei-koburi",
|
|
637
|
+
label: "源暎こぶり明朝",
|
|
638
|
+
fontName: "KGGenEiKoburi61",
|
|
639
|
+
family: "\"KGGenEiKoburi61\", \"Yu Mincho\", \"Hiragino Mincho ProN\", serif",
|
|
640
|
+
textTransforms: [],
|
|
641
|
+
measurement: "browser-shaped",
|
|
642
|
+
rendering: FIXED_PITCH
|
|
611
643
|
}
|
|
612
644
|
};
|
|
613
645
|
const FontPreset = {
|
|
@@ -615,4 +647,123 @@ const FontPreset = {
|
|
|
615
647
|
all: Object.values(FONT_PRESETS)
|
|
616
648
|
};
|
|
617
649
|
//#endregion
|
|
618
|
-
|
|
650
|
+
//#region src/appearance/internal/font-text-transforms.ts
|
|
651
|
+
const transforms = { "combine-kana-voicing-marks": (text) => text.replace(/([\u3041-\u3096\u30A1-\u30FA\u31F0-\u31FF])([\u309B\u309C])/gu, (_, kana, mark) => kana + (mark === "゛" ? "゙" : "゚")) };
|
|
652
|
+
function applyFontTextTransforms(text, rules) {
|
|
653
|
+
return rules.reduce((value, rule) => transforms[rule](value), text);
|
|
654
|
+
}
|
|
655
|
+
//#endregion
|
|
656
|
+
//#region src/appearance/font-preparation.ts
|
|
657
|
+
function prepareTextForFont(text, fontPreset) {
|
|
658
|
+
return applyFontTextTransforms(text, FontPreset.of(fontPreset).textTransforms);
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Prepare display text after parsing; source and UTF-16 offsets remain unchanged.
|
|
662
|
+
*/
|
|
663
|
+
function prepareManuscriptForFont(parsed, fontPreset) {
|
|
664
|
+
if (FontPreset.of(fontPreset).textTransforms.length === 0) return {
|
|
665
|
+
parsed,
|
|
666
|
+
mapRange: (range) => range
|
|
667
|
+
};
|
|
668
|
+
const boundaries = /* @__PURE__ */ new Set([0, parsed.displayText.length]);
|
|
669
|
+
for (const annotation of parsed.annotations) {
|
|
670
|
+
boundaries.add(annotation.range.display.start);
|
|
671
|
+
boundaries.add(annotation.range.display.end);
|
|
672
|
+
if (annotation.kind === "ruby" && annotation.reading.kind !== "group") for (const member of parsed.graphemes.slice(annotation.range.graphemes.start, annotation.range.graphemes.end)) boundaries.add(member.range.display.start);
|
|
673
|
+
}
|
|
674
|
+
for (const [index, member] of parsed.graphemes.entries()) {
|
|
675
|
+
const previous = parsed.graphemes[index - 1];
|
|
676
|
+
if (previous !== void 0 && previous.range.source.end !== member.range.source.start) boundaries.add(member.range.display.start);
|
|
677
|
+
}
|
|
678
|
+
const ordered = [...boundaries].sort((a, b) => a - b);
|
|
679
|
+
const parts = [];
|
|
680
|
+
const graphemes = [];
|
|
681
|
+
let originalIndex = 0;
|
|
682
|
+
for (let i = 1; i < ordered.length; i += 1) {
|
|
683
|
+
const start = ordered[i - 1];
|
|
684
|
+
const end = ordered[i];
|
|
685
|
+
if (start === void 0 || end === void 0) continue;
|
|
686
|
+
const text = prepareTextForFont(parsed.displayText.slice(start, end), fontPreset);
|
|
687
|
+
parts.push(text);
|
|
688
|
+
for (const { segment, index } of graphemeSegmenter.segment(text)) {
|
|
689
|
+
const displayStart = start + index;
|
|
690
|
+
const displayEnd = displayStart + segment.length;
|
|
691
|
+
while ((parsed.graphemes[originalIndex]?.range.display.end ?? Infinity) <= displayStart) originalIndex += 1;
|
|
692
|
+
const first = parsed.graphemes[originalIndex];
|
|
693
|
+
let last = first;
|
|
694
|
+
while (last !== void 0 && last.range.display.end < displayEnd) {
|
|
695
|
+
originalIndex += 1;
|
|
696
|
+
last = parsed.graphemes[originalIndex];
|
|
697
|
+
}
|
|
698
|
+
if (first === void 0 || last === void 0) throw new Error("Font preparation lost a source member");
|
|
699
|
+
graphemes.push({
|
|
700
|
+
value: segment,
|
|
701
|
+
range: ManuscriptRange.of({
|
|
702
|
+
source: {
|
|
703
|
+
start: first.range.source.start,
|
|
704
|
+
end: last.range.source.end
|
|
705
|
+
},
|
|
706
|
+
display: {
|
|
707
|
+
start: displayStart,
|
|
708
|
+
end: displayEnd
|
|
709
|
+
},
|
|
710
|
+
graphemes: {
|
|
711
|
+
start: graphemes.length,
|
|
712
|
+
end: graphemes.length + 1
|
|
713
|
+
}
|
|
714
|
+
})
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
const boundaryIndex = (offset, end) => {
|
|
719
|
+
let low = 0;
|
|
720
|
+
let high = graphemes.length;
|
|
721
|
+
while (low < high) {
|
|
722
|
+
const mid = Math.floor((low + high) / 2);
|
|
723
|
+
const member = graphemes[mid];
|
|
724
|
+
if (member !== void 0 && (end ? member.range.display.start < offset : member.range.display.end <= offset)) low = mid + 1;
|
|
725
|
+
else high = mid;
|
|
726
|
+
}
|
|
727
|
+
return low;
|
|
728
|
+
};
|
|
729
|
+
const mapRange = (range) => {
|
|
730
|
+
const start = boundaryIndex(range.display.start, false);
|
|
731
|
+
return ManuscriptRange.of({
|
|
732
|
+
...range,
|
|
733
|
+
graphemes: {
|
|
734
|
+
start,
|
|
735
|
+
end: range.display.start === range.display.end ? start : boundaryIndex(range.display.end, true)
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
};
|
|
739
|
+
const annotations = parsed.annotations.map((annotation) => {
|
|
740
|
+
const range = mapRange(annotation.range);
|
|
741
|
+
if (annotation.kind !== "ruby") return {
|
|
742
|
+
...annotation,
|
|
743
|
+
range
|
|
744
|
+
};
|
|
745
|
+
const reading = annotation.reading.kind === "group" ? {
|
|
746
|
+
kind: "group",
|
|
747
|
+
text: prepareTextForFont(annotation.reading.text, fontPreset)
|
|
748
|
+
} : {
|
|
749
|
+
...annotation.reading,
|
|
750
|
+
segments: annotation.reading.segments.map((text) => prepareTextForFont(text, fontPreset))
|
|
751
|
+
};
|
|
752
|
+
return {
|
|
753
|
+
...annotation,
|
|
754
|
+
range,
|
|
755
|
+
reading
|
|
756
|
+
};
|
|
757
|
+
});
|
|
758
|
+
return {
|
|
759
|
+
parsed: v.parse(ParsedManuscript.contractFor(parsed.source), {
|
|
760
|
+
source: parsed.source,
|
|
761
|
+
displayText: parts.join(""),
|
|
762
|
+
graphemes,
|
|
763
|
+
annotations
|
|
764
|
+
}),
|
|
765
|
+
mapRange
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
//#endregion
|
|
769
|
+
export { ComposeError, FontPreset, FontPresetId, FontSizeQ, ManuscriptAppearanceSettings, ManuscriptDiagnostic, ManuscriptGeometry, ManuscriptOffsets, ManuscriptPageSettings, ManuscriptRange, ManuscriptResult, NovelCompositionSettings, NovelFlowSettings, PaperSize, PaperSizeId, ParseError, composeManuscript, kakuyomuParser, novelComposer, parseManuscript, pixivParser, plainTextParser, prepareManuscriptForFont, prepareTextForFont };
|
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 };
|