文章校正仕様書
AIを使用しない、ローカルでの形態素解析およびtextlintによる文章校正機能の仕様。
概要
kuromoji.js 等のローカルで動作する形態素解析ライブラリと、プラガブルな文章校正ツールである textlint を使用し、執筆中の小説の校正支援を行う。
AI(LLM)とは異なり、ルールベースで高速かつオフラインで動作し、確実な指摘を行うことを目的とする。
UI仕様
校正パネル (Calibration Panel)
- リーディングバー(サイドバー)に「校正」アイコンを追加。
- クリックすると右ペインに校正パネルを表示。
- パネル内には以下のタブを設ける。
- 指摘 (Issues) - textlintおよび内製チェックの結果
- 頻出語 (Frequency) - 形態素解析による語彙分析
設定画面 (Calibration Settings)
- 「設定」内の「校正」タブから、各ルールの有効・無効を個別に切り替え可能。
- ユーザーは執筆スタイルに合わせて、不要な指摘を抑制できる。
機能詳細
1. 頻出語分析 (Frequency Analysis)
- 目的: 同じ単語の使いすぎを防ぐ、文章の癖を把握する。
- 機能:
- 文章全体の解析を行い、主要な品詞(名詞、動詞、形容詞等)の出現回数をリストアップ。
- 単語をクリックするとエディター内の該当箇所を検索・ハイライト。
2. 文章チェック (Sentence Inspection)
textlint をコアエンジンとして使用し、必要に応じて内製チェックを組み合わせる。
- textlintによるチェック:
- パッケージ版でも安定して動作させるため、ルールモジュールをコード内で直接インポートするプログラム制御方式を採用。
no-dropping-the-ra: ら抜き言葉の検出。no-doubled-joshi: 助詞の連続使用(一文に同じ助詞が複数回出現)を検出。内製の粒子重複チェックから移行・一本化。preset-ja-spacing:ja-no-mixed-period: 句点の混在。ja-no-space-around-parentheses: 括弧周りのスペース。ja-no-space-between-full-width: 全角文字間のスペース。ja-space-after-exclamation: 感嘆符後のスペース。ja-space-after-question: 疑問符後のスペース。ja-space-between-alphabet-and-japanese: 英字と日本語間のスペース(設定により制御)。
3. 内製チェック (Custom Rules)
- 漢字の開き(Kanji Open/Close):
- 本来ひらがなで書くべき形式名詞(こと、とき等)や副詞が漢字で書かれている場合に指摘。
エディター連携 (Editor Integration)
- リアルタイム表示:
- 校正パネルを開いている間、問題箇所にエディター上で波線(Decoration)を表示。
- textlintの指摘も同様に表示する。
- ホバー表示:
- 波線箇所をホバーすると、指摘内容を表示。
- ジャンプ機能:
- パネルのリスト項目をクリックすると、エディターの該当箇所へスクロール・フォーカス。
技術仕様
- 形態素解析:
kuromoji.js - 校正エンジン:
textlint(JavaScript API経由) - 設定管理:
SettingsContextおよびProjectConfigによる一元管理。 - 実行場所: メインプロセス (
CalibrationService)。 - IPC通信: レンダラーからの
calibration:analyze要求に対し、設定値を踏まえた解析結果を返す。
データ構造
interface CalibrationIssue {
id: string;
type:
| 'particle_repetition' // 助詞の連続(textlint: no-doubled-joshi が担当)
| 'consistency'
| 'kanji_open_close' // 漢字の開き(内製)
| 'textlint'; // その他のtextlintルール
message: string;
range: {
startLine: number;
startColumn: number;
endLine: number;
endColumn: number;
};
ranges?: { // 複数箇所をまとめて指摘する場合の範囲
startLine: number;
startColumn: number;
endLine: number;
endColumn: number;
}[];
suggestion?: string; // 置換提案
source?: string; // 指摘元のルールID名
}