Skip to content

feat: add no-ai-colon-continuation rule with kuromojin morphological analysis #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,54 @@ AIライティングで過度に使用されがちな誇張表現やハイプ的

AIが機械的に生成しがちな強調パターンを検出します。

### no-ai-colon-continuation

コロンの直後にブロック要素が続く英語的なパターンを検出します。日本語として自然な表現を促進するルールです。

このルールは形態素解析(kuromojin)を使用して、コロンの前の文が述語(動詞・形容詞・助動詞)で終わっているかを判定します。「使用方法:」のような名詞で終わる表現は自然な日本語として許可され、「実行します:」のような述語で終わる表現のみを検出します。

#### 検出される例

````markdown
実行します:

```bash
command
```

説明します:

- 項目1
- 項目2

例えば:

- 具体的な例
````

#### より自然な日本語表現

````markdown
実行方法は以下の通りです。

```bash
command
```

説明の内容は以下の通りです。

- 項目1
- 項目2

たとえば、次のような例があります。

- 具体的な例

例:

- 具体的な例
````

### ai-tech-writing-guideline

テクニカルライティングのベストプラクティスに基づいて、文書品質の改善提案を行います。
Expand Down Expand Up @@ -279,6 +327,13 @@ AIを利用しやすくするプラットフォームです。
"disableAbstractPatterns": false,
"disabledPredictivePatterns": false
},
"no-ai-colon-continuation": {
"allows": ["許可したいテキスト", "/正規表現パターン/"],
"disableCodeBlock": false,
"disableList": false,
"disableQuote": false,
"disableTable": false
},
"ai-tech-writing-guideline": {
"severity": "info", // サジェストとして扱う
"allows": ["許可したいテキスト", "/正規表現パターン/"],
Expand All @@ -304,6 +359,16 @@ AIを利用しやすくするプラットフォームです。
- `disableBoldListItems`: `true`にすると強調リストアイテムの検出を無効にする
- `disableEmojiListItems`: `true`にすると絵文字リストアイテムの検出を無効にする

#### no-ai-colon-continuation

- `allows`: 指定したパターンにマッチする場合、エラーを報告しません
- 文字列: `"許可したいテキスト"`
- 正規表現: `"/パターン/フラグ"` (例: `"/使用方法.*/i"`)
- `disableCodeBlock`: `true`にするとコロン後のコードブロック検出を無効にする
- `disableList`: `true`にするとコロン後のリスト検出を無効にする
- `disableQuote`: `true`にするとコロン後の引用検出を無効にする
- `disableTable`: `true`にするとコロン後のテーブル検出を無効にする

### 正規表現パターンの使用例

`allows`オプションでは、[regexp-string-matcher](https://github.com/textlint/regexp-string-matcher)の形式で正規表現パターンを指定できます。
Expand Down
19 changes: 1 addition & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
},
"dependencies": {
"@textlint/regexp-string-matcher": "^2.0.2",
"kuromojin": "^3.0.1",
"textlint-util-to-string": "^3.3.4"
},
"packageManager": "npm@10.9.2+sha512.8ab88f10f224a0c614cb717a7f7c30499014f77134120e9c1f0211ea3cf3397592cbe483feb38e0c4b3be1c54e347292c76a1b5edb94a3289d5448484ab8ac81"
Expand Down
7 changes: 5 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@ import noAiListFormatting from "./rules/no-ai-list-formatting";
import noAiHypeExpressions from "./rules/no-ai-hype-expressions";
import noAiEmphasisPatterns from "./rules/no-ai-emphasis-patterns";
import aiTechWritingGuideline from "./rules/ai-tech-writing-guideline";
import noAiColonContinuation from "./rules/no-ai-colon-continuation";

const preset = {
rules: {
"no-ai-list-formatting": noAiListFormatting,
"no-ai-hype-expressions": noAiHypeExpressions,
"no-ai-emphasis-patterns": noAiEmphasisPatterns,
"ai-tech-writing-guideline": aiTechWritingGuideline
"ai-tech-writing-guideline": aiTechWritingGuideline,
"no-ai-colon-continuation": noAiColonContinuation
},
rulesConfig: {
"no-ai-list-formatting": true,
"no-ai-hype-expressions": true,
"no-ai-emphasis-patterns": true,
"ai-tech-writing-guideline": {
severity: "info"
}
},
"no-ai-colon-continuation": true
}
};

Expand Down
16 changes: 7 additions & 9 deletions src/rules/ai-tech-writing-guideline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ const rule: TextlintRuleModule<Options> = (context, options = {}) => {

/**
* 機械的な段落と箇条書きの組み合わせパターンを検出
* 注意: コロン関連のパターンは no-ai-colon-continuation ルールで処理されます
*/
const detectMechanicalListIntroPattern = (node: any) => {
const children = node.children || [];
Expand All @@ -213,14 +214,10 @@ const rule: TextlintRuleModule<Options> = (context, options = {}) => {
let isDetected = false;
let message = "";

// パターン1: コロン(:、:)で終わる段落
if (/[::][\s]*$/.test(paragraphText.trim())) {
isDetected = true;
message =
"【構造化】コロン(:)で終わる文の直後の箇条書きは機械的な印象を与える可能性があります。「たとえば、次のような点があります。」のような導入文を使った自然な表現を検討してください。";
}
// パターン2: 「例えば。」「具体的には。」など、接続表現+句点で終わる段落
else if (/(?:例えば|具体的には|詳細には|以下|次に|また)。[\s]*$/.test(paragraphText.trim())) {
// 注意: コロンパターンは no-ai-colon-continuation で処理されるため削除

// パターン: 「例えば。」「具体的には。」など、接続表現+句点で終わる段落
if (/(?:例えば|具体的には|詳細には|以下|次に|また)。[\s]*$/.test(paragraphText.trim())) {
isDetected = true;
message =
"【構造化】接続表現と句点で終わる文の直後の箇条書きは機械的な印象を与える可能性があります。「たとえば、次のような点があります。」のような自然な導入文を検討してください。";
Expand Down Expand Up @@ -254,7 +251,8 @@ const rule: TextlintRuleModule<Options> = (context, options = {}) => {
return;
}

// コロン + 箇条書きパターンの検出
// 接続表現 + 箇条書きパターンの検出
// 注意: コロン + ブロック要素パターンは no-ai-colon-continuation ルールで処理
detectMechanicalListIntroPattern(node);
// 将来的にここに他の文書レベルの構造化パターンを追加できます
// 例:
Expand Down
Loading