コンテンツにスキップ

意味的リンターと構文リンター

contextlint のタグラインは「markdownlint for syntax. contextlint for meaning.」です。これは markdownlint と機能が重なるツールを作ったわけではなく、異なるレイヤーを担当する補完関係 にあることを示しています。このページでは、意味的リンター(semantic linter)と構文リンター(syntax linter)の違いを整理します。

リンターは検証する対象によってレイヤーが分かれます。

レイヤー 検証する対象
構文 (syntax) 表記が文法に従っているか 見出しレベル、リスト記法、テーブル構文
フォーマット (format) 表記スタイルが統一されているか 行末スペース、リスト記号の統一
意味 (semantic) 内容が論理的に整合しているか 必須カラムの有無、ID の一意性、参照先の存在

markdownlint は 構文とフォーマット を担当します。contextlint は 意味的な整合性とファイル間の整合性 を担当します。両者は競合せず、レイヤーが違います。

観点 markdownlint contextlint
Markdown の構文
フォーマット・スタイル
見出しレベルの一貫性
テーブル構文の正しさ
テーブル内のデータ整合性
必須セクションの存在
必須セクションの順序
ID の一意性
ファイル間の参照整合性
依存グラフの検証
用語の一貫性

同じテーブルに対して、両者は別の側面を検証します。

| ID | Status | Description |
| ----------- | ------ | ----------- |
| REQ-AUTH-01 | | ログイン要件 |
| REQ-AUTH-01 | stable | |
  • markdownlint が見るもの: パイプの数、区切り行の整形、空白の扱い — テーブルが Markdown として有効か
  • contextlint が見るもの:
    • Status カラムが空のセルがある (TBL-002)
    • ID カラムに重複がある (TBL-006)
    • Description カラムが空のセルがある (TBL-002)
    • テーブルの内容が業務上の整合性を保っているか

両者を組み合わせることで、書き方の正しさ + 中身の正しさ を両側からカバーできます。

なぜ意味的リンターが必要なのか

Section titled “なぜ意味的リンターが必要なのか”

構文リンターだけではカバーできない領域は、ドキュメントが規模を増すほど顕在化します。

  • リンクは Markdown として正しい記法で書かれていても、リンク先のファイルが存在しない ことがある
  • テーブルは Markdown として正しい構文でも、必須カラムが欠落している ことがある
  • 同じ ID が複数のファイルで定義されていても、Markdown としては何の問題もない
  • 安定 (stable) の要件が、ドラフト (draft) の要件に依存していても、Markdown 構文上はエラーにならない

これらは Markdown レイヤーでは検出不可能 な問題です。文法ではなく 意味のレイヤー にあるため、別のリンターが必要になります。

contextlint は markdownlint を置き換えません。両者は併用することで初めて、ドキュメントを多層的に検証できます。

  • markdownlint — 「Markdown として正しく書けているか」
  • contextlint — 「ドキュメントの中身が整合しているか」

CI パイプラインでは両方を順番に実行することを推奨します。markdownlint で構文を、contextlint で意味を — それぞれの得意領域に分担させるのが自然な使い方です。