chaffjs 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/detectors/acronym-context.d.ts +17 -3
  2. package/dist/detectors/acronym-context.d.ts.map +1 -1
  3. package/dist/detectors/acronym-context.js +25 -32
  4. package/dist/detectors/acronym-context.js.map +1 -1
  5. package/dist/detectors/acronym-expansion.d.ts.map +1 -1
  6. package/dist/detectors/acronym-expansion.js +33 -6
  7. package/dist/detectors/acronym-expansion.js.map +1 -1
  8. package/dist/detectors/char-shape.d.ts.map +1 -1
  9. package/dist/detectors/char-shape.js +22 -36
  10. package/dist/detectors/char-shape.js.map +1 -1
  11. package/dist/detectors/conjugated-form.d.ts +3 -0
  12. package/dist/detectors/conjugated-form.d.ts.map +1 -0
  13. package/dist/detectors/conjugated-form.js +29 -0
  14. package/dist/detectors/conjugated-form.js.map +1 -0
  15. package/dist/detectors/enumerated-runs.d.ts +22 -0
  16. package/dist/detectors/enumerated-runs.d.ts.map +1 -0
  17. package/dist/detectors/enumerated-runs.js +53 -0
  18. package/dist/detectors/enumerated-runs.js.map +1 -0
  19. package/dist/detectors/middle-dot.d.ts +6 -0
  20. package/dist/detectors/middle-dot.d.ts.map +1 -0
  21. package/dist/detectors/middle-dot.js +9 -0
  22. package/dist/detectors/middle-dot.js.map +1 -0
  23. package/dist/detectors/orthography.d.ts.map +1 -1
  24. package/dist/detectors/orthography.js +19 -1
  25. package/dist/detectors/orthography.js.map +1 -1
  26. package/dist/detectors/place-run.d.ts +8 -0
  27. package/dist/detectors/place-run.d.ts.map +1 -0
  28. package/dist/detectors/place-run.js +54 -0
  29. package/dist/detectors/place-run.js.map +1 -0
  30. package/dist/detectors/polite-word.d.ts +4 -0
  31. package/dist/detectors/polite-word.d.ts.map +1 -0
  32. package/dist/detectors/polite-word.js +10 -0
  33. package/dist/detectors/polite-word.js.map +1 -0
  34. package/dist/detectors/register.d.ts +34 -0
  35. package/dist/detectors/register.d.ts.map +1 -0
  36. package/dist/detectors/register.js +64 -0
  37. package/dist/detectors/register.js.map +1 -0
  38. package/dist/detectors/roman-numeral.d.ts +6 -0
  39. package/dist/detectors/roman-numeral.d.ts.map +1 -0
  40. package/dist/detectors/roman-numeral.js +6 -0
  41. package/dist/detectors/roman-numeral.js.map +1 -0
  42. package/dist/detectors/sentence-ending.d.ts.map +1 -1
  43. package/dist/detectors/sentence-ending.js +28 -29
  44. package/dist/detectors/sentence-ending.js.map +1 -1
  45. package/dist/detectors/signals.d.ts.map +1 -1
  46. package/dist/detectors/signals.js +21 -7
  47. package/dist/detectors/signals.js.map +1 -1
  48. package/dist/detectors/structure.d.ts.map +1 -1
  49. package/dist/detectors/structure.js +2 -1
  50. package/dist/detectors/structure.js.map +1 -1
  51. package/dist/number-name.d.ts +10 -0
  52. package/dist/number-name.d.ts.map +1 -0
  53. package/dist/number-name.js +76 -0
  54. package/dist/number-name.js.map +1 -0
  55. package/dist/orthography.d.ts +6 -2
  56. package/dist/orthography.d.ts.map +1 -1
  57. package/dist/orthography.js +78 -17
  58. package/dist/orthography.js.map +1 -1
  59. package/dist/plugin.d.ts +2 -0
  60. package/dist/plugin.d.ts.map +1 -1
  61. package/dist/preamble-paragraphs.d.ts +7 -0
  62. package/dist/preamble-paragraphs.d.ts.map +1 -0
  63. package/dist/preamble-paragraphs.js +7 -0
  64. package/dist/preamble-paragraphs.js.map +1 -0
  65. package/dist/structure/build.d.ts.map +1 -1
  66. package/dist/structure/build.js +7 -4
  67. package/dist/structure/build.js.map +1 -1
  68. package/dist/structure/heading-leaves.d.ts +7 -0
  69. package/dist/structure/heading-leaves.d.ts.map +1 -0
  70. package/dist/structure/heading-leaves.js +6 -0
  71. package/dist/structure/heading-leaves.js.map +1 -0
  72. package/package.json +3 -3
  73. package/rules/duplicate-definition.yaml +2 -2
  74. package/rules/latin-spacing.yaml +4 -2
  75. package/rules/max-kanji-continuous.yaml +2 -0
  76. package/rules/no-nakaguro-parallel.yaml +2 -2
  77. package/rules/undefined-acronym.yaml +2 -0
  78. package/src/detectors/acronym-context.ts +40 -33
  79. package/src/detectors/acronym-expansion.ts +34 -6
  80. package/src/detectors/char-shape.ts +14 -33
  81. package/src/detectors/conjugated-form.ts +40 -0
  82. package/src/detectors/enumerated-runs.ts +68 -0
  83. package/src/detectors/middle-dot.ts +10 -0
  84. package/src/detectors/orthography.ts +22 -2
  85. package/src/detectors/place-run.ts +63 -0
  86. package/src/detectors/polite-word.ts +14 -0
  87. package/src/detectors/register.ts +87 -0
  88. package/src/detectors/roman-numeral.ts +5 -0
  89. package/src/detectors/sentence-ending.ts +43 -30
  90. package/src/detectors/signals.ts +24 -7
  91. package/src/detectors/structure.ts +2 -1
  92. package/src/number-name.ts +96 -0
  93. package/src/orthography.ts +76 -15
  94. package/src/plugin.ts +2 -0
  95. package/src/preamble-paragraphs.ts +9 -0
  96. package/src/structure/build.ts +13 -10
  97. package/src/structure/heading-leaves.ts +7 -0
@@ -1,13 +1,27 @@
1
1
  /**
2
2
  * 大文字の語が略語ではなく、決まった書き方の一部として読める所(3:30 PM、1pm ET、USD 1,000、Kansas City, MO 64108)。
3
3
  * どれも閉じた集合で、しかも隣の数字があるときだけ認める。PM(project manager)、CT、CA(certificate authority)は
4
- * 数字の隣でなければ略語のまま数える。
4
+ * 数字の隣でなければ略語のまま数える。語は言語パッケージの語彙表から読み、書き方の組み立てだけをここに置く。
5
5
  */
6
6
  type Span = {
7
7
  readonly start: number;
8
8
  readonly end: number;
9
9
  };
10
- /** 文の中で、略語として数えない大文字を含む範囲。略語は範囲にまるごと入るときだけ外れるので、語の境目は見なくてよい(NOTE の中の NOT)。 */
11
- export declare const notAcronymSpans: (text: string) => Span[];
10
+ /** 言語パッケージの語彙表から読む、数字の隣でだけ略語から外す語と、単独で強調として書かれる語。字面どおりに照らす。 */
11
+ export type NotationWords = {
12
+ readonly meridiem: readonly string[];
13
+ readonly timeZones: readonly string[];
14
+ readonly currencies: readonly string[];
15
+ readonly usStates: readonly string[];
16
+ readonly emphasis: readonly string[];
17
+ /** 番号を後ろに書く、文書の区切りの名前(Part、Section、Title)。 */
18
+ readonly divisions: readonly string[];
19
+ };
20
+ export type NotAcronymSpans = (text: string) => Span[];
21
+ /**
22
+ * 文の中で、略語として数えない大文字を含む範囲。語彙表から一度だけ組み立てて、文ごとに呼ぶ。
23
+ * 略語は範囲にまるごと入るときだけ外れるので、語の境目は見なくてよい(NOTE の中の NOT)。
24
+ */
25
+ export declare const notAcronymSpansOf: (words: NotationWords) => NotAcronymSpans;
12
26
  export {};
13
27
  //# sourceMappingURL=acronym-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"acronym-context.d.ts","sourceRoot":"","sources":["../../src/detectors/acronym-context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,KAAK,IAAI,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AA4C7D,8EAA8E;AAC9E,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,IAAI,EACsF,CAAC"}
1
+ {"version":3,"file":"acronym-context.d.ts","sourceRoot":"","sources":["../../src/detectors/acronym-context.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,KAAK,IAAI,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC,CAAC;AA8BF,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,CAAC;AAEvD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,aAAa,KAAG,eAGxD,CAAC"}
@@ -1,26 +1,7 @@
1
- /**
2
- * 大文字の語が略語ではなく、決まった書き方の一部として読める所(3:30 PM、1pm ET、USD 1,000、Kansas City, MO 64108)。
3
- * どれも閉じた集合で、しかも隣の数字があるときだけ認める。PM(project manager)、CT、CA(certificate authority)は
4
- * 数字の隣でなければ略語のまま数える。
5
- */
6
- const MERIDIEM = ["AM", "PM"];
7
- /** 業務文書で説明なしに書かれる時間帯。ここに無いもの(ACT など)は略語として数える。 */
8
- const TIME_ZONE = ["UTC", "GMT", "JST", "ET", "EST", "EDT", "CT", "CST", "CDT", "MT", "MST", "MDT", "PT", "PST", "PDT", "CET", "CEST"];
9
- /** ISO 4217 のうち、業務文書の読み手が説明なしで通じる主要な通貨。CAD は数の隣でも computer-aided design と読める(3 CAD files)ので入れない。 */
10
- const CURRENCY = ["USD", "EUR", "JPY", "GBP", "CNY", "CHF", "AUD", "KRW", "HKD", "SGD", "INR"];
11
- /** 米国の州・特別区・準州の郵便略号。住所の書き方(, CA 94720)の中でだけ見る。 */
12
- const US_STATE = [
13
- ...["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY"],
14
- ...["LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND"],
15
- ...["OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY"],
16
- ...["DC", "PR", "GU", "VI", "AS", "MP"],
17
- ];
18
- /**
19
- * 略語として読む字面を持たない英語の機能語。単独の NOT や AND は強調で、展開するものが無い。
20
- * OR(Oregon、operating room)や IS(International Standard)のように略語でもある語は入れない。
21
- */
22
- const PLAIN_WORD = ["NOT", "AND"];
23
- const oneOf = (words) => `(?:${words.join("|")})`;
1
+ import { escapeRegExp } from "../orthography.js";
2
+ import { ROMAN_NUMERAL } from "./roman-numeral.js";
3
+ // 空の語彙表は「その書き方が無い」。空の選択肢 (?:) は至る所で空文字に当たるので、何にも当たらない形にする。
4
+ const oneOf = (words) => (words.length === 0 ? "(?!)" : `(?:${words.map(escapeRegExp).join("|")})`);
24
5
  const MINUTES = String.raw `:[0-5]\d`;
25
6
  const CLOCK_12 = String.raw `(?<![\d:.])(?:1[0-2]|0?[1-9])(?:${MINUTES})?`;
26
7
  const CLOCK_24 = String.raw `(?<![\d:.])(?:[01]?\d|2[0-3])${MINUTES}`;
@@ -28,15 +9,27 @@ const CLOCK_24 = String.raw `(?<![\d:.])(?:[01]?\d|2[0-3])${MINUTES}`;
28
9
  const ANY_MERIDIEM = String.raw `[AaPp]\.?[Mm]\.?`;
29
10
  /** 桁区切りは 3 桁ずつ揃っているときだけ金額と読む。「item 1, USD」の 1, は金額ではない。 */
30
11
  const AMOUNT = String.raw `(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?`;
12
+ /**
13
+ * 区切りの名前のすぐ後ろのローマ数字は番号(Part II、Section VIII、TITLE IV)。名前は語彙表の書き方か、全部大文字。
14
+ * CD や CI のようにローマ数字としても読める略語は、この位置でなければ略語のまま数える。
15
+ */
16
+ const divisionOf = (words) => oneOf(words.flatMap((word) => [word, word.toUpperCase()]));
31
17
  // 強調の記号は空白に置き換えてある(**3:30** PM)ので、部品の間の空白は数を問わない。
32
- const PATTERNS = [
33
- new RegExp(String.raw `${CLOCK_12}\s*${oneOf(MERIDIEM)}`, "gu"),
34
- new RegExp(String.raw `(?:${CLOCK_24}|${CLOCK_12}\s*${ANY_MERIDIEM})\s*${oneOf(TIME_ZONE)}`, "gu"),
35
- new RegExp(String.raw `${oneOf(CURRENCY)}\s*[$€£¥]?${AMOUNT}`, "gu"),
36
- new RegExp(String.raw `(?<![\w.,])${AMOUNT}\s*${oneOf(CURRENCY)}`, "gu"),
37
- new RegExp(String.raw `,\s+${oneOf(US_STATE)}\s+\d{5}(?:-\d{4})?(?!\d)`, "gu"),
38
- new RegExp(oneOf(PLAIN_WORD), "gu"),
18
+ const patternsOf = (words) => [
19
+ new RegExp(String.raw `${CLOCK_12}\s*${oneOf(words.meridiem)}`, "gu"),
20
+ new RegExp(String.raw `(?:${CLOCK_24}|${CLOCK_12}\s*${ANY_MERIDIEM})\s*${oneOf(words.timeZones)}`, "gu"),
21
+ new RegExp(String.raw `${oneOf(words.currencies)}\s*[$€£¥]?${AMOUNT}`, "gu"),
22
+ new RegExp(String.raw `(?<![\w.,])${AMOUNT}\s*${oneOf(words.currencies)}`, "gu"),
23
+ new RegExp(String.raw `,\s+${oneOf(words.usStates)}\s+\d{5}(?:-\d{4})?(?!\d)`, "gu"),
24
+ new RegExp(oneOf(words.emphasis), "gu"),
25
+ new RegExp(String.raw `(?<![\p{L}\p{N}_])${divisionOf(words.divisions)}\s+${ROMAN_NUMERAL}(?![\p{L}\p{N}_&])`, "gu"),
39
26
  ];
40
- /** 文の中で、略語として数えない大文字を含む範囲。略語は範囲にまるごと入るときだけ外れるので、語の境目は見なくてよい(NOTE の中の NOT)。 */
41
- export const notAcronymSpans = (text) => PATTERNS.flatMap((pattern) => [...text.matchAll(pattern)].map((match) => ({ start: match.index, end: match.index + match[0].length })));
27
+ /**
28
+ * 文の中で、略語として数えない大文字を含む範囲。語彙表から一度だけ組み立てて、文ごとに呼ぶ。
29
+ * 略語は範囲にまるごと入るときだけ外れるので、語の境目は見なくてよい(NOTE の中の NOT)。
30
+ */
31
+ export const notAcronymSpansOf = (words) => {
32
+ const patterns = patternsOf(words);
33
+ return (text) => patterns.flatMap((pattern) => [...text.matchAll(pattern)].map((match) => ({ start: match.index, end: match.index + match[0].length })));
34
+ };
42
35
  //# sourceMappingURL=acronym-context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"acronym-context.js","sourceRoot":"","sources":["../../src/detectors/acronym-context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAE9B,kDAAkD;AAClD,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAEvI,oGAAoG;AACpG,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAE/F,kDAAkD;AAClD,MAAM,QAAQ,GAAG;IACf,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IACzG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IACzG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IACnG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;CACxC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAElC,MAAM,KAAK,GAAG,CAAC,KAAwB,EAAU,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAE7E,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAA,UAAU,CAAC;AACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA,mCAAmC,OAAO,IAAI,CAAC;AAC1E,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA,gCAAgC,OAAO,EAAE,CAAC;AACrE,6CAA6C;AAC7C,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA,kBAAkB,CAAC;AAClD,2DAA2D;AAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA,sCAAsC,CAAC;AAEhE,kDAAkD;AAClD,MAAM,QAAQ,GAAsB;IAClC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,GAAG,QAAQ,MAAM,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAC9D,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,MAAM,QAAQ,IAAI,QAAQ,MAAM,YAAY,OAAO,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC;IACjG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,GAAG,KAAK,CAAC,QAAQ,CAAC,aAAa,MAAM,EAAE,EAAE,IAAI,CAAC;IACnE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,cAAc,MAAM,MAAM,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IACvE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,OAAO,KAAK,CAAC,QAAQ,CAAC,2BAA2B,EAAE,IAAI,CAAC;IAC7E,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC;CACpC,CAAC;AAEF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE,CACtD,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"acronym-context.js","sourceRoot":"","sources":["../../src/detectors/acronym-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAqBnD,2DAA2D;AAC3D,MAAM,KAAK,GAAG,CAAC,KAAwB,EAAU,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE/H,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAA,UAAU,CAAC;AACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA,mCAAmC,OAAO,IAAI,CAAC;AAC1E,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA,gCAAgC,OAAO,EAAE,CAAC;AACrE,6CAA6C;AAC7C,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA,kBAAkB,CAAC;AAClD,2DAA2D;AAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA,sCAAsC,CAAC;AAEhE;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,KAAwB,EAAU,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;AAEpH,kDAAkD;AAClD,MAAM,UAAU,GAAG,CAAC,KAAoB,EAAqB,EAAE,CAAC;IAC9D,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,GAAG,QAAQ,MAAM,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IACpE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,MAAM,QAAQ,IAAI,QAAQ,MAAM,YAAY,OAAO,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC;IACvG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,MAAM,EAAE,EAAE,IAAI,CAAC;IAC3E,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,cAAc,MAAM,MAAM,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC;IAC/E,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,OAAO,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,2BAA2B,EAAE,IAAI,CAAC;IACnF,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;IACvC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,qBAAqB,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,aAAa,oBAAoB,EAAE,IAAI,CAAC;CACpH,CAAC;AAIF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAoB,EAAmB,EAAE;IACzE,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3J,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"acronym-expansion.d.ts","sourceRoot":"","sources":["../../src/detectors/acronym-expansion.ts"],"names":[],"mappings":"AA4CA,iEAAiE;AACjE,MAAM,MAAM,eAAe,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AA6BzG,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;AAEhF,+DAA+D;AAC/D,eAAO,MAAM,WAAW,GAAI,OAAO,eAAe,KAAG,UAGpD,CAAC"}
1
+ {"version":3,"file":"acronym-expansion.d.ts","sourceRoot":"","sources":["../../src/detectors/acronym-expansion.ts"],"names":[],"mappings":"AAuEA,iEAAiE;AACjE,MAAM,MAAM,eAAe,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AA8BzG,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;AAEhF,+DAA+D;AAC/D,eAAO,MAAM,WAAW,GAAI,OAAO,eAAe,KAAG,UAGpD,CAAC"}
@@ -3,10 +3,11 @@ import { escapeRegExp } from "../orthography.js";
3
3
  * 展開は略語の**すぐ隣**にあるときだけ認める。
4
4
  * 60 文字も見ると、同じ文のどこかに括弧があるだけで「説明済み」になり、1 件も出なくなる。
5
5
  *
6
- * 認めるのは 4 つの形。どれも実際によく書かれる。
6
+ * 認めるのは次の形。どれも実際によく書かれる。
7
7
  * CI(継続的インテグレーション) 略語のあとに括弧
8
8
  * Continuous Integration (CI) 括弧の中が略語
9
9
  * Tax Cuts and Jobs Act [TCJA] 角括弧の中が略語で、直前の語の頭文字と揃う
10
+ * Relief Act (RA; P.L. 112-240) 括弧の最初の項目が略語で、直前の語か区切りの後の語の頭文字と揃う
10
11
  * 人事部(以下「HR」という。) 括弧の中が定義の語と略語だけ
11
12
  * 括弧と略語の間には、引用符((“MNDA”)、(「MNDA」))と空白だけを許す。
12
13
  */
@@ -16,6 +17,10 @@ const CLOSES = new RegExp(String.raw `^${WRAP}[))]`, "u");
16
17
  const OPENED = new RegExp(String.raw `[((]${WRAP}$`, "u");
17
18
  const SQUARE_CLOSES = new RegExp(String.raw `^${WRAP}\]`, "u");
18
19
  const SQUARE_OPENED = new RegExp(String.raw `\[${WRAP}$`, "u");
20
+ const ANY_OPENED = new RegExp(String.raw `[(([]${WRAP}$`, "u");
21
+ /** 括弧の最初の項目のあとの区切りと、括弧が閉じるまでの残り((ARRA; P.L. 111-5)、(OP、Originator Profile))。 */
22
+ const SEPARATED = new RegExp(String.raw `^${WRAP}[;;,,、](?<rest>[^()()]*)`, "u");
23
+ const QUOTES = /["“”'‘’「」『』]/gu;
19
24
  /** 括弧と略語の間の幅。空白は 1 つに畳んであるので、(“ MNDA ”) まで収まる。 */
20
25
  const NEAR = 3;
21
26
  /** 定義の語を挟む形で、括弧から略語まで・略語から括弧までに見る幅。(hereinafter referred to as “SLA”) が収まる。 */
@@ -26,15 +31,35 @@ const MARKER_GAP = String.raw `(?![A-Za-z])[\s、,]*`;
26
31
  * 角括弧は引用の印にも使う([IANA]、[1])。直前の語のうち大文字で始まる語の頭文字が
27
32
  * 略語と揃うときだけ展開と見なす。見る語は略語の文字数の 2 倍まで(and や of を挟むため)。
28
33
  */
34
+ const lettersOf = (acronym) => acronym.replaceAll("&", "");
35
+ const initialsOf = (words) => words
36
+ .filter((word) => /^[A-Z]/u.test(word))
37
+ .map((word) => word.charAt(0))
38
+ .join("");
29
39
  const spellsOut = (before, acronym) => {
30
- const letters = acronym.replaceAll("&", "");
40
+ const letters = lettersOf(acronym);
31
41
  const words = before
32
- .replace(SQUARE_OPENED, "")
42
+ .replace(ANY_OPENED, "")
33
43
  .trim()
34
44
  .split(/\s+/u)
35
45
  .slice(-letters.length * 2);
36
- const initials = words.filter((word) => /^[A-Z]/u.test(word)).map((word) => word.charAt(0));
37
- return initials.join("").endsWith(letters);
46
+ return initialsOf(words).endsWith(letters);
47
+ };
48
+ /**
49
+ * 括弧の最初の項目が略語で、区切りのあとに注記が続く形((ARRA; P.L. 111-5)、(OP、Originator Profile))。
50
+ * 同じ形で列挙も書く((MR, handbook, etc.)、(EPA, FDIC, GSA))ので、直前の語か、区切りから括弧が閉じるまでの語の
51
+ * 頭文字が略語と揃うときだけ展開と見なす。区切りの後ろは閉じた括弧の中だけを見て、頭文字がちょうど略語になることを求める。
52
+ */
53
+ const isSeparatedAt = (body, acronym, at) => {
54
+ if (!OPENED.test(body.slice(Math.max(0, at - NEAR), at)))
55
+ return false;
56
+ const separated = SEPARATED.exec(body.slice(at + acronym.length, at + acronym.length + DEFINITION_REACH));
57
+ if (separated === null)
58
+ return false;
59
+ const rest = separated.groups?.["rest"] ?? "";
60
+ const end = at + acronym.length + separated[0].length;
61
+ const closed = CLOSES.test(body.slice(end, end + NEAR));
62
+ return spellsOut(body.slice(0, at), acronym) || (closed && initialsOf(rest.replace(QUOTES, " ").trim().split(/\s+/u)) === lettersOf(acronym));
38
63
  };
39
64
  const oneOf = (words) => (words.length === 0 ? "(?!)" : words.map(escapeRegExp).join("|"));
40
65
  const definitionPatterns = (words) => ({
@@ -57,7 +82,9 @@ const isBracketedAt = (body, acronym, at) => {
57
82
  const before = body.slice(Math.max(0, at - NEAR), at);
58
83
  if (OPENS.test(after) || (OPENED.test(before) && CLOSES.test(after)))
59
84
  return true;
60
- return SQUARE_OPENED.test(before) && SQUARE_CLOSES.test(after) && spellsOut(body.slice(0, at), acronym);
85
+ if (SQUARE_OPENED.test(before) && SQUARE_CLOSES.test(after) && spellsOut(body.slice(0, at), acronym))
86
+ return true;
87
+ return isSeparatedAt(body, acronym, at);
61
88
  };
62
89
  /** body の at にある略語が、その場で展開・定義されているか。語彙表から一度だけ組み立てて、略語ごとに呼ぶ。 */
63
90
  export const expansionAt = (words) => {
@@ -1 +1 @@
1
- {"version":3,"file":"acronym-expansion.js","sourceRoot":"","sources":["../../src/detectors/acronym-expansion.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"acronym-expansion.js","sourceRoot":"","sources":["../../src/detectors/acronym-expansion.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"char-shape.d.ts","sourceRoot":"","sources":["../../src/detectors/char-shape.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA6C,MAAM,cAAc,CAAC;AAgDxF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,QAWhB,CAAC;AAIR;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,QAWjB,CAAC"}
1
+ {"version":3,"file":"char-shape.d.ts","sourceRoot":"","sources":["../../src/detectors/char-shape.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAsC,MAAM,cAAc,CAAC;AA6BjF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,QAatB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,QAWjB,CAAC"}
@@ -1,65 +1,51 @@
1
1
  import { compacted, placeOf } from "./gram-place.js";
2
2
  import { maskAddresses } from "../address-chain.js";
3
+ import { isAddressRun } from "./place-run.js";
3
4
  import { proseText } from "../measure.js";
5
+ import { parallelDotCount } from "./middle-dot.js";
4
6
  /**
5
7
  * 文字の並びを見る検出。漢字の連なりが住所かどうかだけは、形態素解析の地名と数で決める。
6
8
  * 覆った箇所は空白になっているので、proseText で潰してから数える。
7
9
  */
8
10
  const KANJI_RUN = /[一-鿿]+/gu;
9
- /** 地名(Geo)と、地名に付く単位(GeoUnit: 都・県・市・区・町)。 */
10
- const isGeoName = (token) => token?.features?.["NameType"] === "Geo";
11
- const isGeo = (token) => isGeoName(token) || token?.features?.["NameType"] === "GeoUnit";
12
- const isNumber = (token) => token?.features?.["NumType"] === "Card";
13
- /**
14
- * 住所の語: 地名と地名の単位(NameType=Geo / GeoUnit)、数(NumType=Card)、数のすぐ後ろの助数詞(丁目、NounType=Class)。
15
- * 辞書に無い町名(新橋)は、地名の後ろで数の前に来るときだけ住所の一部とする。
16
- */
17
- const isPlacePart = (tokens, index) => isGeo(tokens[index]) ||
18
- isNumber(tokens[index]) ||
19
- (isNumber(tokens[index - 1]) && tokens[index]?.features?.["NounType"] === "Class") ||
20
- (isGeo(tokens[index - 1]) && isNumber(tokens[index + 1]));
21
- /**
22
- * 漢字の連なりが住所か(東京都港区新橋二丁目)。形態素解析が地名と読んだ語で始まり、住所の語だけでできている。
23
- * 住所は決まった形で、ひらがなを挟んで書けない。組織名(日本経済団体連合会)は地名の後ろに普通の語が続くので住所ではない。品詞が無ければ判定しない。
24
- */
25
- const isPlaceName = (sentence, run) => {
11
+ /** 漢字の連なりが住所か(東京都港区新橋二丁目)。形態素解析の地名と数で決める。品詞が無ければ判定しない。 */
12
+ const isPlaceName = (sentence, run, topUnits) => {
26
13
  const tokens = sentence.tokens;
27
14
  const place = tokens === undefined ? undefined : placeOf(compacted(sentence.text, "word"), run);
28
15
  if (tokens === undefined || place === undefined)
29
16
  return false;
30
17
  const [start, end] = [sentence.span.start + place.start, sentence.span.start + place.end];
31
18
  const covering = tokens.flatMap((token, index) => (token.span.start < end && start < token.span.end ? [index] : []));
32
- const first = covering[0];
33
- // 地名が単位を挟まずに続けば(東京大阪名古屋福岡)、住所ではなく地名の並び。
34
- const listed = covering.some((index) => isGeoName(tokens[index]) && isGeoName(tokens[index + 1]));
35
- return first !== undefined && isGeo(tokens[first]) && !listed && covering.every((index) => isPlacePart(tokens, index));
19
+ return isAddressRun(tokens, covering, topUnits);
36
20
  };
37
- const longestKanji = (sentence, profile) => [...maskAddresses(proseText(sentence), profile).matchAll(KANJI_RUN)]
21
+ const longestKanji = (sentence, profile, topUnits) => [...maskAddresses(proseText(sentence), profile).matchAll(KANJI_RUN)]
38
22
  .map((match) => match[0])
39
- .filter((run) => !isPlaceName(sentence, run))
23
+ .filter((run) => !isPlaceName(sentence, run, topUnits))
40
24
  .reduce((longest, run) => (run.length > longest.length ? run : longest), "");
41
25
  /**
42
26
  * 漢字が続くと、どこで語が切れるのか読み手が探すことになる。
43
27
  * 「情報処理推進機構認定試験」は 12 字。ひらがなを 1 つ挟むだけで読める。
44
28
  */
45
- export const kanjiRun = (doc, options) => doc.sentences
46
- .map((sentence) => ({ sentence, run: longestKanji(sentence, doc.profile) }))
47
- .filter(({ run }) => run.length > options.limit)
48
- .map(({ sentence, run }) => ({
49
- rule: "max-kanji-continuous",
50
- severity: "warning",
51
- line: 0,
52
- column: 0,
53
- quote: sentence.text.trim(),
54
- values: { word: run, count: run.length, limit: options.limit, offset: sentence.span.start },
55
- }));
56
- const MIDDLE_DOT = /・/gu;
29
+ export const kanjiRun = (doc, options) => {
30
+ const topUnits = new Set((doc.lexicons["prefecture-unit"] ?? []).map((entry) => entry.pattern));
31
+ return doc.sentences
32
+ .map((sentence) => ({ sentence, run: longestKanji(sentence, doc.profile, topUnits) }))
33
+ .filter(({ run }) => run.length > options.limit)
34
+ .map(({ sentence, run }) => ({
35
+ rule: "max-kanji-continuous",
36
+ severity: "warning",
37
+ line: 0,
38
+ column: 0,
39
+ quote: sentence.text.trim(),
40
+ values: { word: run, count: run.length, limit: options.limit, offset: sentence.span.start },
41
+ }));
42
+ };
57
43
  /**
58
44
  * 中黒で並べると、どこまでが 1 つの項目か分からなくなる。
59
45
  * 「企画・開発・運用・保守体制」は、保守体制が 1 つなのか保守と体制なのか読めない。
60
46
  */
61
47
  export const middleDot = (doc, options) => doc.sentences
62
- .map((sentence) => ({ sentence, count: [...proseText(sentence).matchAll(MIDDLE_DOT)].length }))
48
+ .map((sentence) => ({ sentence, count: parallelDotCount(sentence.text) }))
63
49
  .filter(({ count }) => count > options.limit)
64
50
  .map(({ sentence, count }) => ({
65
51
  rule: "no-nakaguro-parallel",
@@ -1 +1 @@
1
- {"version":3,"file":"char-shape.js","sourceRoot":"","sources":["../../src/detectors/char-shape.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"char-shape.js","sourceRoot":"","sources":["../../src/detectors/char-shape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Sentence } from "../plugin.ts";
2
+ export declare const conjugatedForms: (sentences: readonly Sentence[], bases: readonly string[]) => string[];
3
+ //# sourceMappingURL=conjugated-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conjugated-form.d.ts","sourceRoot":"","sources":["../../src/detectors/conjugated-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAS,MAAM,cAAc,CAAC;AAiCpD,eAAO,MAAM,eAAe,GAAI,WAAW,SAAS,QAAQ,EAAE,EAAE,OAAO,SAAS,MAAM,EAAE,KAAG,MAAM,EAMhG,CAAC"}
@@ -0,0 +1,29 @@
1
+ /** 動詞と、そのすぐ後ろに続く助動詞の、文の中の範囲。 */
2
+ const inflectedRun = (sentence, tokens, index, verb) => {
3
+ const rest = tokens.slice(index + 1);
4
+ const stop = rest.findIndex((token) => token.pos !== "AUX");
5
+ const last = (stop === -1 ? rest : rest.slice(0, stop)).at(-1) ?? verb;
6
+ return { start: verb.span.start - sentence.span.start, end: last.span.end - sentence.span.start };
7
+ };
8
+ const formsAt = (sentence, tokens, index, bases) => {
9
+ const verb = tokens[index];
10
+ const lemma = verb?.lemma;
11
+ if (verb?.pos !== "VERB" || lemma === undefined || lemma === "")
12
+ return [];
13
+ const run = inflectedRun(sentence, tokens, index, verb);
14
+ const before = sentence.text.slice(0, run.start);
15
+ const written = sentence.text.slice(run.start, run.end);
16
+ return bases
17
+ .filter((base) => base.endsWith(lemma))
18
+ .map((base) => base.slice(0, base.length - lemma.length))
19
+ .filter((head) => before.endsWith(head))
20
+ .map((head) => `${head}${written}`);
21
+ };
22
+ export const conjugatedForms = (sentences, bases) => {
23
+ const forms = sentences.flatMap((sentence) => {
24
+ const tokens = sentence.tokens ?? [];
25
+ return tokens.flatMap((_token, index) => formsAt(sentence, tokens, index, bases));
26
+ });
27
+ return [...new Set(forms)];
28
+ };
29
+ //# sourceMappingURL=conjugated-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conjugated-form.js","sourceRoot":"","sources":["../../src/detectors/conjugated-form.ts"],"names":[],"mappings":"AAWA,gCAAgC;AAChC,MAAM,YAAY,GAAG,CAAC,QAAkB,EAAE,MAAwB,EAAE,KAAa,EAAE,IAAW,EAAO,EAAE;IACrG,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACvE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;AACpG,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,QAAkB,EAAE,MAAwB,EAAE,KAAa,EAAE,KAAwB,EAAY,EAAE;IAClH,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;IAC1B,IAAI,IAAI,EAAE,GAAG,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAC3E,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;SACxD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SACvC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,OAAO,EAAE,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,SAA8B,EAAE,KAAwB,EAAY,EAAE;IACpG,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;QACrC,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7B,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { Sentence, Span, StructureNode } from "../plugin.ts";
2
+ /** 番号の付いた行。start は行の始まり(字下げの前)、label は言語パッケージが読んだ番号(「(1)」)。 */
3
+ export type NumberedStart = {
4
+ readonly start: number;
5
+ readonly label: string;
6
+ };
7
+ /**
8
+ * 条の外で、番号の付いた行(言語パッケージが項目と読んだ「(1)」など)。
9
+ * 条の中の番号付きの行は、条の項(条の本文の続き)でもありうるので数えない。
10
+ */
11
+ export declare const numberedStarts: (node: StructureNode, inArticle?: boolean) => NumberedStart[];
12
+ /**
13
+ * 並びの項目として番号を振った行の始まり。番号の直後が助詞(「(1)の金額は」「(2)は対象外」)なら、
14
+ * 番号は項目の印ではなく、項目を指す本文の主語や修飾なので除く。
15
+ */
16
+ export declare const enumeratorStarts: (numbered: readonly NumberedStart[], sentences: readonly Sentence[], source: string) => number[];
17
+ /**
18
+ * 番号で始まる段落が、空行だけを挟んで続く範囲。番号の付いた行を二つ以上含むものだけ。
19
+ * 要件や条件を「(1)…であること。」と並べるのは、段落でも箇条書きと同じ書き方で、本文の調子とは別に揃える。
20
+ */
21
+ export declare const enumeratedRuns: (paragraphs: readonly Span[], starts: readonly number[], source: string) => Span[];
22
+ //# sourceMappingURL=enumerated-runs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enumerated-runs.d.ts","sourceRoot":"","sources":["../../src/detectors/enumerated-runs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAS,MAAM,cAAc,CAAC;AAEzE,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAO/E;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,aAAa,EAAE,mBAAiB,KAAG,aAAa,EAGpF,CAAC;AAgBF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,UAAU,SAAS,aAAa,EAAE,EAAE,WAAW,SAAS,QAAQ,EAAE,EAAE,QAAQ,MAAM,KAAG,MAAM,EACpB,CAAC;AAiBzG;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,YAAY,SAAS,IAAI,EAAE,EAAE,QAAQ,SAAS,MAAM,EAAE,EAAE,QAAQ,MAAM,KAAG,IAAI,EAQ3G,CAAC"}
@@ -0,0 +1,53 @@
1
+ const labelOf = (node) => {
2
+ const label = node.attrs["label"];
3
+ return typeof label === "string" ? label : "";
4
+ };
5
+ /**
6
+ * 条の外で、番号の付いた行(言語パッケージが項目と読んだ「(1)」など)。
7
+ * 条の中の番号付きの行は、条の項(条の本文の続き)でもありうるので数えない。
8
+ */
9
+ export const numberedStarts = (node, inArticle = false) => [
10
+ ...(node.kind === "item" && !inArticle ? [{ start: node.span.start, label: labelOf(node) }] : []),
11
+ ...node.children.flatMap((child) => numberedStarts(child, inArticle || node.kind === "article")),
12
+ ];
13
+ const INDENT = /^[ \t\u3000]*/u;
14
+ const lineAt = (source, start) => {
15
+ const end = source.indexOf("\n", start);
16
+ return source.slice(start, end === -1 ? source.length : end);
17
+ };
18
+ /** 番号の直後の語。字下げと番号と空白を飛ばした先の、最初の語。 */
19
+ const wordAfter = (numbered, sentences, source) => {
20
+ const after = numbered.start + (INDENT.exec(lineAt(source, numbered.start))?.[0].length ?? 0) + numbered.label.length;
21
+ const sentence = sentences.find((candidate) => candidate.span.end > after);
22
+ return sentence?.tokens?.find((token) => token.span.start >= after && token.surface.trim() !== "");
23
+ };
24
+ /**
25
+ * 並びの項目として番号を振った行の始まり。番号の直後が助詞(「(1)の金額は」「(2)は対象外」)なら、
26
+ * 番号は項目の印ではなく、項目を指す本文の主語や修飾なので除く。
27
+ */
28
+ export const enumeratorStarts = (numbered, sentences, source) => numbered.filter((line) => wordAfter(line, sentences, source)?.pos !== "ADP").map((line) => line.start);
29
+ /** 番号の付いた行の始まりと段落の始まりのあいだが字下げだけなら、段落はその行から始まる。 */
30
+ const opensWithItem = (paragraph, starts, source) => starts.some((start) => start <= paragraph.start && source.slice(start, paragraph.start).trim() === "");
31
+ const isBlank = (source, from, to) => source.slice(from, to).trim() === "";
32
+ /** 並びと読むのに要る、番号の付いた行の数。一つだけなら、並びではなく番号で始まる本文の段落かもしれない。 */
33
+ const MIN_ITEMS = 2;
34
+ /** 番号の行の始まりは字下げの前なので、並びの最初の行の頭から数える。 */
35
+ const itemsIn = (run, starts, source) => {
36
+ const lineStart = source.lastIndexOf("\n", run.start - 1) + 1;
37
+ return starts.filter((start) => start >= lineStart && start < run.end).length;
38
+ };
39
+ /**
40
+ * 番号で始まる段落が、空行だけを挟んで続く範囲。番号の付いた行を二つ以上含むものだけ。
41
+ * 要件や条件を「(1)…であること。」と並べるのは、段落でも箇条書きと同じ書き方で、本文の調子とは別に揃える。
42
+ */
43
+ export const enumeratedRuns = (paragraphs, starts, source) => {
44
+ const enumerated = paragraphs.filter((paragraph) => opensWithItem(paragraph, starts, source));
45
+ const runs = enumerated.reduce((joined, paragraph) => {
46
+ const last = joined.at(-1);
47
+ if (last === undefined || !isBlank(source, last.end, paragraph.start))
48
+ return [...joined, paragraph];
49
+ return [...joined.slice(0, -1), { start: last.start, end: paragraph.end }];
50
+ }, []);
51
+ return runs.filter((run) => itemsIn(run, starts, source) >= MIN_ITEMS);
52
+ };
53
+ //# sourceMappingURL=enumerated-runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enumerated-runs.js","sourceRoot":"","sources":["../../src/detectors/enumerated-runs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 項目を並べる中黒の数。箇条書きの印の「・」は数えない。
3
+ * 「・ 水分を補給すること」が何行続いても、どこまでが 1 つの項目かは改行で読める。
4
+ */
5
+ export declare const parallelDotCount: (text: string) => number;
6
+ //# sourceMappingURL=middle-dot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middle-dot.d.ts","sourceRoot":"","sources":["../../src/detectors/middle-dot.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,KAAG,MAAyE,CAAC"}
@@ -0,0 +1,9 @@
1
+ const MIDDLE_DOT = /・/gu;
2
+ /** 文頭か行頭(前に空白だけ)の「・」。前に並べる項目が無いので、箇条書きの印。 */
3
+ const BULLET_DOT = /(^|\n)[^\S\n]*・/gu;
4
+ /**
5
+ * 項目を並べる中黒の数。箇条書きの印の「・」は数えない。
6
+ * 「・ 水分を補給すること」が何行続いても、どこまでが 1 つの項目かは改行で読める。
7
+ */
8
+ export const parallelDotCount = (text) => [...text.replace(BULLET_DOT, "$1").matchAll(MIDDLE_DOT)].length;
9
+ //# sourceMappingURL=middle-dot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middle-dot.js","sourceRoot":"","sources":["../../src/detectors/middle-dot.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG,KAAK,CAAC;AAEzB,6CAA6C;AAC7C,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAEvC;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"orthography.d.ts","sourceRoot":"","sources":["../../src/detectors/orthography.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,cAAc,CAAC;AAGhE,6DAA6D;AAC7D,eAAO,MAAM,aAAa,EAAE,QAc3B,CAAC;AAOF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,QAyB1B,CAAC"}
1
+ {"version":3,"file":"orthography.d.ts","sourceRoot":"","sources":["../../src/detectors/orthography.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,cAAc,CAAC;AAIhE,6DAA6D;AAC7D,eAAO,MAAM,aAAa,EAAE,QAc3B,CAAC;AAoBF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,QA+B1B,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { latinBoundaries, minorityStyle, occurrencesOutside } from "../orthography.js";
2
+ import { digitRunAround, isNumberName, sequenceLabelStarts } from "../number-name.js";
2
3
  /** チームが chaff.yaml の prefer に書いた「使わない書き方」。書いていなければ何も言わない。 */
3
4
  export const preferredTerm = (doc, options) => {
4
5
  const pairs = (options.lexicon ?? []).flatMap((entry) => (entry.instead_of === undefined ? [] : [{ avoid: entry.pattern, use: entry.instead_of }]));
@@ -16,12 +17,29 @@ export const preferredTerm = (doc, options) => {
16
17
  };
17
18
  const KIND_NAME = { letter: "英字", "before-digit": "後ろの数字", "after-digit": "前の数字" };
18
19
  const KINDS = ["letter", "before-digit", "after-digit"];
20
+ /** 境目の隣の数字の、並びの中の 1 字の位置。数字の後ろなら左の字、数字の前なら(空白を越えた)右の字。 */
21
+ const digitBeside = (boundary) => {
22
+ if (boundary.kind === "after-digit")
23
+ return boundary.offset - 1;
24
+ return boundary.spaced ? boundary.offset + 1 : boundary.offset;
25
+ };
26
+ /** 番号・識別子として書かれた数の境目は、空け方の好みではないので数えない(number-name.ts)。 */
27
+ const isCounted = (sentence, boundary, sequence) => {
28
+ if (boundary.kind === "letter")
29
+ return true;
30
+ const run = digitRunAround(sentence.text, digitBeside(boundary));
31
+ return run === undefined || !isNumberName(sentence.text, run, sentence.tokens, sentence.span.start, sequence);
32
+ };
19
33
  /**
20
34
  * 日本語と英字・数字のあいだを、空けるか詰めるか。文書の中で混ざっていたら、少ないほうを指摘する。
21
35
  * どちらが正しいかは決めない。決めるのはチームで、chaff はそろっているかだけを見る。
22
36
  */
23
37
  export const latinSpacing = (doc, options) => {
24
- const located = doc.sentences.flatMap((sentence) => latinBoundaries(sentence.text).map((boundary) => ({ sentence, ...boundary })));
38
+ // 覆った文(prose)で探す。コードの中の「1 件」は並びに入れない。
39
+ const sequence = sequenceLabelStarts(doc.prose ?? doc.source);
40
+ const located = doc.sentences.flatMap((sentence) => latinBoundaries(sentence.text, doc.source.slice(sentence.span.start, sentence.span.end))
41
+ .filter((boundary) => isCounted(sentence, boundary, sequence))
42
+ .map((boundary) => ({ sentence, ...boundary })));
25
43
  return KINDS.flatMap((kind) => {
26
44
  const ofKind = located.filter((entry) => entry.kind === kind);
27
45
  const minority = minorityStyle(ofKind);
@@ -1 +1 @@
1
- {"version":3,"file":"orthography.js","sourceRoot":"","sources":["../../src/detectors/orthography.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"orthography.js","sourceRoot":"","sources":["../../src/detectors/orthography.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Token } from "../plugin.ts";
2
+ /**
3
+ * 漢字の連なりの語(covering: tokens の添字)が住所か(東京都港区新橋二丁目)。地名で始まり、住所の語だけでできている。
4
+ * 住所は決まった形で、ひらがなを挟んで書けない。組織名(日本経済団体連合会)は地名の後ろに普通の語が続くので住所ではない。
5
+ * topUnits は、住所の先頭にしか来ない単位(都道府県)。言語の語彙表から渡す。
6
+ */
7
+ export declare const isAddressRun: (tokens: readonly Token[], covering: readonly number[], topUnits: ReadonlySet<string>) => boolean;
8
+ //# sourceMappingURL=place-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"place-run.d.ts","sourceRoot":"","sources":["../../src/detectors/place-run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAoD1C;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,QAAQ,SAAS,KAAK,EAAE,EAAE,UAAU,SAAS,MAAM,EAAE,EAAE,UAAU,WAAW,CAAC,MAAM,CAAC,KAAG,OAKnH,CAAC"}