Skip to content

Commit ce0573d

Browse files
見出し内の太字パターン(との両方)を検出
1 parent 85953b6 commit ce0573d

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,18 +178,25 @@ AIが機械的に生成しがちな強調パターンを検出します。
178178
```markdown
179179
これは**非常に**重要な項目です。
180180
**注意**してください。
181+
# **重要なお知らせ**
182+
## **太字**の見出し
181183
```
182184

183185
#### より自然な表現
184186

185187
```markdown
186188
これは重要な項目です。
187189
注意してください。
190+
# 重要なお知らせ
191+
## 太字の見出し
188192
```
189193

190194
#### オプション
191195

192196
- `allows`: 指定したパターンにマッチする場合、エラーを報告しません
197+
- `disableEmojiEmphasisPatterns`: `true`にすると絵文字と太字の組み合わせパターンの検出を無効にする
198+
- `disableInfoPatterns`: `true`にすると情報系プレフィックスパターンの検出を無効にする
199+
- `disableHeadingEmphasisPatterns`: `true`にすると見出し内の太字パターンの検出を無効にする
193200

194201
### no-ai-colon-continuation
195202

@@ -315,6 +322,12 @@ command
315322
"disableAbstractPatterns": false,
316323
"disabledPredictivePatterns": false
317324
},
325+
"no-ai-emphasis-patterns": {
326+
"allows": ["許可したいテキスト", "/正規表現パターン/"],
327+
"disableEmojiEmphasisPatterns": false,
328+
"disableInfoPatterns": false,
329+
"disableHeadingEmphasisPatterns": false
330+
},
318331
"no-ai-colon-continuation": {
319332
"allows": ["許可したいテキスト", "/正規表現パターン/"],
320333
"disableCodeBlock": false,

src/rules/no-ai-emphasis-patterns.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ type Options = {
99
disableEmojiEmphasisPatterns?: boolean;
1010
// 情報系プレフィックスパターンの検出を無効にする
1111
disableInfoPatterns?: boolean;
12+
// 見出し内の太字パターンの検出を無効にする
13+
disableHeadingEmphasisPatterns?: boolean;
1214
};
1315

1416
const rule: TextlintRuleModule<Options> = (context: TextlintRuleContext, options = {}) => {
15-
const { Syntax, RuleError, report, getSource, locator } = context;
17+
const { Syntax, RuleError, report, getSource, locator, fixer } = context;
1618
const allows = options.allows ?? [];
1719
const disableEmojiEmphasisPatterns = options.disableEmojiEmphasisPatterns ?? false;
1820
const disableInfoPatterns = options.disableInfoPatterns ?? false;
21+
const disableHeadingEmphasisPatterns = options.disableHeadingEmphasisPatterns ?? false;
1922

2023
// 機械的な情報系プレフィックス
2124
const infoPatterns = [
@@ -178,6 +181,43 @@ const rule: TextlintRuleModule<Options> = (context: TextlintRuleContext, options
178181
}
179182
}
180183
}
184+
},
185+
186+
[Syntax.Heading](node) {
187+
if (disableHeadingEmphasisPatterns) {
188+
return;
189+
}
190+
191+
const text = getSource(node);
192+
193+
// allowsパターンにマッチする場合はスキップ
194+
if (allows.length > 0) {
195+
const matchedResults = matchPatterns(text, allows);
196+
if (matchedResults.length > 0) {
197+
return;
198+
}
199+
}
200+
201+
// 見出し内の太字パターンを検出(**text** または __text__)
202+
const headingEmphasisPattern = /(\*\*|__)(.*?)\1/g;
203+
204+
for (const match of text.matchAll(headingEmphasisPattern)) {
205+
const matchStart = match.index ?? 0;
206+
const matchEnd = matchStart + match[0].length;
207+
const emphasisMark = match[1];
208+
const innerText = match[2];
209+
210+
report(
211+
node,
212+
new RuleError(
213+
`見出し内の太字は不要です。見出し自体が強調のため、追加の太字は冗長です。`,
214+
{
215+
padding: locator.range([matchStart, matchEnd]),
216+
fix: fixer.replaceTextRange([matchStart, matchEnd], innerText)
217+
}
218+
)
219+
);
220+
}
181221
}
182222
};
183223
};

test/rules/no-ai-emphasis-patterns.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,24 @@ tester.run("no-ai-emphasis-patterns", noAiEmphasisPatterns, {
2525
options: {
2626
allows: ["/ℹ️.*注意/"]
2727
}
28+
},
29+
30+
// 見出し内太字(通常のテキストとして)
31+
"# 通常の見出し",
32+
"## 太字なしの見出し",
33+
34+
// 見出し内太字検出を無効化
35+
{
36+
text: "# **太字の見出し**",
37+
options: {
38+
disableHeadingEmphasisPatterns: true
39+
}
40+
},
41+
{
42+
text: "## これは**太字**を含む見出し",
43+
options: {
44+
disableHeadingEmphasisPatterns: true
45+
}
2846
}
2947
],
3048
invalid: [
@@ -135,6 +153,51 @@ tester.run("no-ai-emphasis-patterns", noAiEmphasisPatterns, {
135153
"絵文字と太字の組み合わせは機械的な印象を与える可能性があります。より自然な表現を検討してください。"
136154
}
137155
]
156+
},
157+
158+
// 見出し内の太字パターン
159+
{
160+
text: "# **hoge**",
161+
errors: [
162+
{
163+
message: "見出し内の太字は不要です。見出し自体が強調のため、追加の太字は冗長です。"
164+
}
165+
]
166+
},
167+
{
168+
text: "## **重要な項目**について",
169+
errors: [
170+
{
171+
message: "見出し内の太字は不要です。見出し自体が強調のため、追加の太字は冗長です。"
172+
}
173+
]
174+
},
175+
{
176+
text: "### この見出しには**太字**が含まれています",
177+
errors: [
178+
{
179+
message: "見出し内の太字は不要です。見出し自体が強調のため、追加の太字は冗長です。"
180+
}
181+
]
182+
},
183+
{
184+
text: "# __アンダースコア__で囲まれた太字",
185+
errors: [
186+
{
187+
message: "見出し内の太字は不要です。見出し自体が強調のため、追加の太字は冗長です。"
188+
}
189+
]
190+
},
191+
{
192+
text: "## 複数の**太字**と**強調**がある場合",
193+
errors: [
194+
{
195+
message: "見出し内の太字は不要です。見出し自体が強調のため、追加の太字は冗長です。"
196+
},
197+
{
198+
message: "見出し内の太字は不要です。見出し自体が強調のため、追加の太字は冗長です。"
199+
}
200+
]
138201
}
139202
]
140203
});

0 commit comments

Comments
 (0)