UNPKG

textlint-rule-preset-ai-writing

Version:

textlintプリセット:AIっぽい記述パターンを検出し、より自然な日本語表現を促すルール集

86 lines (80 loc) 3.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _regexpStringMatcher = require("@textlint/regexp-string-matcher"); const rule = (context, options = {}) => { const { Syntax, RuleError, report, getSource, locator } = context; const allows = options.allows ?? []; const disableBoldListItems = options.disableBoldListItems ?? false; const disableEmojiListItems = options.disableEmojiListItems ?? false; // Pattern to detect "flashy" emojis commonly used in AI-generated content // Using explicit list of decorative emojis that give mechanical impression const flashyEmojis = [ // Check marks and status indicators "✅", "❌", "⭐", "✨", "💯", // Warning and attention symbols "⚠️", "❗", "❓", "💥", // Energy and fire symbols "🔥", "⚡", "💪", "🚀", // Ideas and thinking "💡", "🤔", "💭", "🧠", // Targets and goals "🎯", "📈", "📊", "🏆", // Common decorative symbols "👍", "👎", "😊", "😎", "🎉", "🌟", // Work and productivity "📝", "📋", "✏️", "🖊️", "💼"]; // Create pattern from explicit emoji list // Need to escape special regex characters const escapedEmojis = flashyEmojis.map(emoji => emoji.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")); const flashyEmojiPattern = new RegExp(`(${escapedEmojis.join("|")})`); return { [Syntax.ListItem](node) { const text = getSource(node); // Check if text matches any allowed patterns if (allows.length > 0) { const matches = (0, _regexpStringMatcher.matchPatterns)(text, allows); if (matches.length > 0) { return; } } // Check for bold list item pattern: - **text**: description if (!disableBoldListItems) { const boldListPattern = /^[\s]*[-*+]\s+\*\*([^*]+)\*\*\s*:/; const boldMatch = text.match(boldListPattern); if (boldMatch) { const matchStart = boldMatch.index ?? 0; const matchEnd = matchStart + boldMatch[0].length; const matchRange = [matchStart, matchEnd]; const ruleError = new RuleError("リストアイテムで強調(**)とコロン(:)の組み合わせは機械的な印象を与える可能性があります。より自然な表現を検討してください。", { padding: locator.range(matchRange) }); report(node, ruleError); } } // Check for emoji list items if (!disableEmojiListItems) { const emojiMatch = text.match(flashyEmojiPattern); if (emojiMatch) { const emoji = emojiMatch[0]; const emojiIndex = emojiMatch.index ?? 0; const matchRange = [emojiIndex, emojiIndex + emoji.length]; const ruleError = new RuleError(`リストアイテムでの絵文字「${emoji}」の使用は、読み手によっては機械的な印象を与える場合があります。テキストベースの表現も検討してみてください。`, { padding: locator.range(matchRange) }); report(node, ruleError); } } } }; }; var _default = exports.default = rule; //# sourceMappingURL=no-ai-list-formatting.js.map