@markuplint/ml-core 4.13.2 → 4.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/ARCHITECTURE.ja.md +467 -0
  2. package/ARCHITECTURE.md +467 -0
  3. package/CHANGELOG.md +14 -2
  4. package/README.md +5 -0
  5. package/SKILL.md +61 -0
  6. package/docs/linting-pipeline.ja.md +303 -0
  7. package/docs/linting-pipeline.md +303 -0
  8. package/docs/maintenance.ja.md +210 -0
  9. package/docs/maintenance.md +210 -0
  10. package/docs/ml-dom/attr.ja.md +95 -0
  11. package/docs/ml-dom/attr.md +95 -0
  12. package/docs/ml-dom/block.ja.md +272 -0
  13. package/docs/ml-dom/block.md +272 -0
  14. package/docs/ml-dom/document.ja.md +141 -0
  15. package/docs/ml-dom/document.md +141 -0
  16. package/docs/ml-dom/element.ja.md +176 -0
  17. package/docs/ml-dom/element.md +176 -0
  18. package/docs/ml-dom/helpers.ja.md +203 -0
  19. package/docs/ml-dom/helpers.md +203 -0
  20. package/docs/ml-dom/node.ja.md +200 -0
  21. package/docs/ml-dom/node.md +200 -0
  22. package/docs/ml-dom/others.ja.md +119 -0
  23. package/docs/ml-dom/others.md +119 -0
  24. package/docs/ml-dom/overview.ja.md +102 -0
  25. package/docs/ml-dom/overview.md +102 -0
  26. package/docs/ml-dom/pretender.ja.md +269 -0
  27. package/docs/ml-dom/pretender.md +269 -0
  28. package/docs/ml-dom/rule-mapping.ja.md +371 -0
  29. package/docs/ml-dom/rule-mapping.md +371 -0
  30. package/docs/ml-dom.ja.md +18 -0
  31. package/docs/ml-dom.md +18 -0
  32. package/docs/rule-system.ja.md +270 -0
  33. package/docs/rule-system.md +270 -0
  34. package/lib/convert-ruleset.d.ts +7 -0
  35. package/lib/convert-ruleset.js +7 -0
  36. package/lib/debug.d.ts +4 -0
  37. package/lib/debug.js +4 -0
  38. package/lib/ml-core.d.ts +36 -0
  39. package/lib/ml-core.js +29 -0
  40. package/lib/ml-dom/helper/get-indent.d.ts +4 -1
  41. package/lib/ml-dom/helper/get-indent.js +4 -1
  42. package/lib/ml-dom/node/attr.d.ts +65 -4
  43. package/lib/ml-dom/node/attr.js +53 -4
  44. package/lib/ml-dom/node/block.d.ts +21 -0
  45. package/lib/ml-dom/node/block.js +14 -0
  46. package/lib/ml-dom/node/child-node.d.ts +9 -0
  47. package/lib/ml-dom/node/child-node.js +9 -0
  48. package/lib/ml-dom/node/comment.d.ts +7 -0
  49. package/lib/ml-dom/node/comment.js +7 -0
  50. package/lib/ml-dom/node/document-fragment.d.ts +8 -0
  51. package/lib/ml-dom/node/document-fragment.js +8 -0
  52. package/lib/ml-dom/node/document-type.d.ts +22 -0
  53. package/lib/ml-dom/node/document-type.js +13 -0
  54. package/lib/ml-dom/node/document.d.ts +98 -4
  55. package/lib/ml-dom/node/document.js +87 -2
  56. package/lib/ml-dom/node/element.d.ts +164 -11
  57. package/lib/ml-dom/node/element.js +135 -6
  58. package/lib/ml-dom/node/node.d.ts +23 -0
  59. package/lib/ml-dom/node/node.js +29 -0
  60. package/lib/ml-dom/node/text.d.ts +12 -0
  61. package/lib/ml-dom/node/text.js +12 -0
  62. package/lib/ml-dom/node/types.d.ts +68 -0
  63. package/lib/ml-dom/token/token.d.ts +42 -0
  64. package/lib/ml-dom/token/token.js +36 -0
  65. package/lib/ml-rule/create-rule.d.ts +9 -0
  66. package/lib/ml-rule/create-rule.js +9 -0
  67. package/lib/ml-rule/ml-rule.d.ts +33 -0
  68. package/lib/ml-rule/ml-rule.js +30 -0
  69. package/lib/ml-rule/types.d.ts +41 -0
  70. package/lib/plugin/plugin.d.ts +8 -0
  71. package/lib/plugin/plugin.js +8 -0
  72. package/lib/plugin/types.d.ts +21 -0
  73. package/lib/ruleset/index.d.ts +10 -0
  74. package/lib/ruleset/index.js +7 -0
  75. package/lib/test/index.d.ts +42 -1
  76. package/lib/test/index.js +35 -1
  77. package/lib/types.d.ts +8 -0
  78. package/lib/violation-collector.d.ts +33 -0
  79. package/lib/violation-collector.js +33 -0
  80. package/package.json +14 -14
@@ -0,0 +1,467 @@
1
+ # @markuplint/ml-core
2
+
3
+ ## 概要
4
+
5
+ `@markuplint/ml-core` は markuplint のコアリンティングエンジンです。パースされた AST(`MLASTDocument`)を DOM ツリー(`MLDOM`)に変換し、設定されたルールをノードに適用して違反を収集します。パッケージは 3 つのサブシステムで構成されます:**MLDOM**(DOM 抽象化レイヤー)、**MLRule**(ルール実行フレームワーク)、**MLCore**(オーケストレーションエンジン)。
6
+
7
+ ## ディレクトリ構造
8
+
9
+ ```
10
+ src/
11
+ ├── index.ts — 公開 API の再エクスポート
12
+ ├── ml-core.ts — MLCore エンジンクラス
13
+ ├── types.ts — MLFabric, MLSchema 型定義
14
+ ├── convert-ruleset.ts — Config → Ruleset 変換
15
+ ├── debug.ts — デバッグログユーティリティ
16
+ ├── violation-collector.ts — 複数ファイルの違反集約
17
+ ├── ml-dom/
18
+ │ ├── index.ts — MLDOM 公開エクスポート
19
+ │ ├── node/
20
+ │ │ ├── document.ts — MLDocument(ルートノード、ルールマッピング、pretender 初期化)
21
+ │ │ ├── element.ts — MLElement(属性、セレクタ、名前空間)
22
+ │ │ ├── node.ts — MLNode(全ノードの抽象基底クラス)
23
+ │ │ ├── parent-node.ts — MLParentNode(querySelector, children)
24
+ │ │ ├── character-data.ts — MLCharacterData(テキスト系の抽象基底)
25
+ │ │ ├── text.ts — MLText
26
+ │ │ ├── comment.ts — MLComment
27
+ │ │ ├── attr.ts — MLAttr(属性トークン)
28
+ │ │ ├── block.ts — MLBlock(プリプロセッサブロック)
29
+ │ │ ├── document-fragment.ts — MLDocumentFragment
30
+ │ │ ├── document-type.ts — MLDocumentType
31
+ │ │ ├── element-close-tag.ts — MLElementCloseTag
32
+ │ │ ├── rule-mapper.ts — RuleMapper(ルールセット → ノードマッピング)
33
+ │ │ ├── types.ts — ノード型定数、AccessibilityProperties
34
+ │ │ ├── node-list.ts — NodeList/HTMLCollection ユーティリティ
35
+ │ │ └── unexpected-call-error.ts — 未サポート DOM メソッドのエラー
36
+ │ ├── token/
37
+ │ │ └── token.ts — MLToken(位置情報付き基底トークン)
38
+ │ ├── helper/
39
+ │ │ ├── accname.ts — アクセシブル名の計算
40
+ │ │ ├── create-node.ts — AST → MLDOM ノードファクトリ
41
+ │ │ ├── walkers.ts — ツリー走査(同期/非同期ウォーカー)
42
+ │ │ ├── get-indent.ts — インデント解析
43
+ │ │ └── debug.ts — デバッグマップ生成
44
+ │ └── manipulations/
45
+ │ ├── child-node-methods.ts — ChildNode インターフェーススタブ
46
+ │ └── get-children.ts — 要素の子要素抽出
47
+ ├── ml-rule/
48
+ │ ├── ml-rule.ts — MLRule クラス(ルール実行)
49
+ │ ├── ml-rule-context.ts — MLRuleContext(レポート収集)
50
+ │ ├── create-rule.ts — createRule ファクトリ
51
+ │ ├── create-test-rule.ts — テスト用ルールファクトリ
52
+ │ └── types.ts — RuleSeed, Checker 型
53
+ ├── ruleset/
54
+ │ └── index.ts — Ruleset クラス(rules + nodeRules + childNodeRules)
55
+ ├── plugin/
56
+ │ ├── plugin.ts — createPlugin ファクトリ
57
+ │ ├── types.ts — Plugin, PluginCreator 型
58
+ │ └── index.ts — Plugin エクスポート
59
+ ├── test/
60
+ │ └── index.ts — createTestDocument, createTestElement, dummySchemas
61
+ └── utils/
62
+ ├── index.ts — ユーティリティエクスポート
63
+ ├── get-location-from-chars.ts — 文字位置解決
64
+ └── string-splice.ts — 文字列スプライスヘルパー
65
+ ```
66
+
67
+ ## アーキテクチャ図
68
+
69
+ ```mermaid
70
+ flowchart TD
71
+ subgraph upstream ["上流依存パッケージ"]
72
+ mlAst["@markuplint/ml-ast\n(AST 型)"]
73
+ mlConfig["@markuplint/ml-config\n(Config, RuleConfigValue)"]
74
+ mlSpec["@markuplint/ml-spec\n(HTML/ARIA 仕様)"]
75
+ htmlSpec["@markuplint/html-spec\n(デフォルト仕様データ)"]
76
+ htmlParser["@markuplint/html-parser\n(デフォルトパーサー)"]
77
+ parserUtils["@markuplint/parser-utils\n(ParserOptions)"]
78
+ selector["@markuplint/selector\n(CSS セレクタマッチング)"]
79
+ i18n["@markuplint/i18n\n(ロケール、翻訳)"]
80
+ shared["@markuplint/shared\n(ユーティリティ)"]
81
+ configPresets["@markuplint/config-presets\n(組み込みプリセット)"]
82
+ end
83
+
84
+ subgraph pkg ["@markuplint/ml-core"]
85
+ subgraph mldom ["MLDOM"]
86
+ document["MLDocument"]
87
+ element["MLElement"]
88
+ node["MLNode / MLToken"]
89
+ ruleMapper["RuleMapper"]
90
+ end
91
+
92
+ subgraph mlRule ["MLRule"]
93
+ rule["MLRule"]
94
+ ruleContext["MLRuleContext"]
95
+ createRule["createRule()"]
96
+ end
97
+
98
+ subgraph engine ["エンジン"]
99
+ core["MLCore"]
100
+ ruleset["Ruleset"]
101
+ convertRuleset["convertRuleset()"]
102
+ end
103
+
104
+ subgraph extras ["その他"]
105
+ plugin["Plugin / createPlugin()"]
106
+ testUtils["テストユーティリティ"]
107
+ end
108
+ end
109
+
110
+ subgraph downstream ["下流"]
111
+ rules["@markuplint/rules\n(組み込みルール)"]
112
+ markuplint["markuplint\n(CLI & API)"]
113
+ end
114
+
115
+ upstream -->|"型、パース、仕様"| pkg
116
+ core --> document
117
+ core --> rule
118
+ document --> ruleMapper
119
+ rule --> ruleContext
120
+ pkg -->|"MLDOM, MLRule, MLCore"| downstream
121
+ ```
122
+
123
+ ## リンティングパイプライン
124
+
125
+ `MLCore.verify()` メソッドがリンティング全体を制御します:
126
+
127
+ ```mermaid
128
+ flowchart LR
129
+ A["MLCore\nコンストラクタ"]
130
+ B["_parse()\nParser → MLASTDocument"]
131
+ C["_createDocument()\nMLASTDocument → MLDocument"]
132
+ D["verify(fix?)\n各ルールに対して:"]
133
+ E["document.setRule(rule)\nRuleMapper で設定をノードにマッピング"]
134
+ F["rule.verify(document)\nMLRuleContext で報告を収集"]
135
+ G["Violations[]"]
136
+
137
+ A --> B --> C --> D --> E --> F --> G
138
+ ```
139
+
140
+ ### ステップごとの説明
141
+
142
+ 1. **パース**: `MLCore` は設定されたパーサー(`MLParser`)を呼び出し、`MLASTDocument` を生成
143
+ 2. **ドキュメント作成**: AST を `MLDocument` でラップし、`createNode()` ファクトリで MLDOM ツリー全体を構築。`RuleMapper` が各ノードのルール設定を解決
144
+ 3. **検証**: 各 `MLRule` に対して、`document.setRule(rule)` を呼び出した後 `rule.verify(document)` を実行。ルールは `document.walkOn()` で対象ノードを走査し、`MLRuleContext` を通じて違反を報告
145
+ 4. **修正**(オプション): `fix=true` の場合、ルールが `node.fix()` でトークン内容を変更。`document.toString(true)` で修正後のソースを生成
146
+
147
+ ## MLDOM クラス階層
148
+
149
+ ```
150
+ MLToken<A extends MLASTToken>
151
+ └── MLNode<T, O, A extends MLASTNode>
152
+ ├── MLAttr<T, O>
153
+ ├── MLCharacterData<T, O, A> (abstract)
154
+ │ ├── MLText<T, O>
155
+ │ └── MLComment<T, O>
156
+ ├── MLDocumentType<T, O>
157
+ ├── MLBlock<T, O>
158
+ ├── MLElementCloseTag<T, O>
159
+ └── MLParentNode<T, O, A> (abstract)
160
+ ├── MLElement<T, O>
161
+ ├── MLDocumentFragment<T, O>
162
+ └── MLDocument<T, O>
163
+ ```
164
+
165
+ ### クラスの責務
166
+
167
+ | クラス | DOM インターフェース | 主な責務 |
168
+ | -------------------- | -------------------- | ------------------------------------------------------------------------------------ |
169
+ | `MLToken` | — | 位置情報付き基底トークン(`startLine`, `endCol`, `raw`, `fixed`)、`fix()` メソッド |
170
+ | `MLNode` | `Node` | ツリー構造(`parentNode`, `childNodes`, `nextSibling`)、ルール格納、`is()` 型ガード |
171
+ | `MLAttr` | `Attr` | 属性名・値トークン、`isDynamicValue`, `isDirective`, `valueType`, `tokenList` |
172
+ | `MLCharacterData` | `CharacterData` | テキスト内容ノードの抽象基底(`data`, `nodeValue`) |
173
+ | `MLText` | `Text` | テキストノード、`isWhitespace()`, `isRawTextElementContent()` |
174
+ | `MLComment` | `Comment` | コメントノード(`textContent`) |
175
+ | `MLDocumentType` | `DocumentType` | `<!DOCTYPE>`(`name`, `publicId`, `systemId`) |
176
+ | `MLBlock` | — | プリプロセッサ固有ブロック(if/each/switch)、`conditionalType`, `isTransparent` |
177
+ | `MLElementCloseTag` | — | 開始タグ要素とペアになる閉じタグ |
178
+ | `MLParentNode` | `ParentNode` | `querySelector()`, `querySelectorAll()`, `children`, `childElementCount` |
179
+ | `MLElement` | `Element` | 属性、セレクタ、名前空間、pretender コンテキスト、`elementType`, `closeTag` |
180
+ | `MLDocumentFragment` | `DocumentFragment` | フラグメントルートノード |
181
+ | `MLDocument` | `Document` | ルートノード、`nodeList`, `walkOn()`, `setRule()`, ルールマッピング、仕様アクセス |
182
+
183
+ ## MLDocument
184
+
185
+ `MLDocument` は MLDOM ツリーのルートであり、ルール実行の主要インターフェースです。
186
+
187
+ ### コンストラクション
188
+
189
+ コンストラクタは `MLASTDocument`、`Ruleset`、`MLSchema` タプルを受け取ります。処理内容:
190
+
191
+ 1. AST を走査し、各 AST ノードに対して `createNode()` を呼び出してフラットな `nodeList` を構築
192
+ 2. `RuleMapper` を初期化して各ノードにルール設定を配布
193
+ 3. pretender 定義が提供されている場合、pretender コンテキストをセットアップ
194
+
195
+ ### 主要プロパティ
196
+
197
+ | プロパティ | 型 | 説明 |
198
+ | ------------- | ----------------------- | ------------------------------------------------------- |
199
+ | `nodeList` | `ReadonlyArray<MLNode>` | ドキュメント順の全ノードのフラットリスト |
200
+ | `specs` | `MLMLSpec` | HTML/ARIA 仕様データ |
201
+ | `isFragment` | `boolean` | ドキュメントがフラグメントかどうか |
202
+ | `currentRule` | `MLRule \| null` | 現在評価中のルール |
203
+ | `endTag` | `EndTagType` | 終了タグ処理モード(`'xml'`, `'omittable'`, `'never'`) |
204
+
205
+ ### 主要メソッド
206
+
207
+ | メソッド | 説明 |
208
+ | --------------------------------- | --------------------------------------------------------------------------------------------- |
209
+ | `walkOn(type, walker)` | 指定した型(`'Element'`, `'Text'`, `'Comment'`, `'Attr'`, `'ElementCloseTag'`)のノードを走査 |
210
+ | `setRule(rule)` | 現在のルールを設定(検証時に `MLCore` が使用) |
211
+ | `getTokenList()` | ソース再構築用の全トークンを返す |
212
+ | `searchNodeByLocation(line, col)` | 指定したソース位置のノードを検索 |
213
+ | `getAccessibilityProp(node)` | ARIA アクセシビリティプロパティを計算 |
214
+ | `toString(fixed?)` | ソースコードを再構築(オプションで修正適用) |
215
+
216
+ ## MLElement
217
+
218
+ `MLElement` は HTML/SVG/MathML 要素を表し、属性アクセスとセレクタマッチングを完全にサポートします。
219
+
220
+ ### 主要プロパティ
221
+
222
+ | プロパティ | 型 | 説明 |
223
+ | ------------------ | --------------------------- | ------------------------------------------------ |
224
+ | `localName` | `string` | 小文字のタグ名(HTML の場合) |
225
+ | `namespaceURI` | `NamespaceURI` | 要素の名前空間(HTML, SVG, MathML) |
226
+ | `attributes` | `MLNamedNodeMap` | 名前付き属性コレクション |
227
+ | `elementType` | `ElementType` | `'html'`, `'web-component'`, または `'authored'` |
228
+ | `closeTag` | `MLElementCloseTag \| null` | ペアの閉じタグ |
229
+ | `pretenderContext` | `PretenderContext \| null` | pretender マッピングコンテキスト |
230
+ | `isForeignElement` | `boolean` | SVG/MathML 要素の場合 `true` |
231
+ | `isOmitted` | `boolean` | 暗黙的に挿入された要素の場合 `true` |
232
+
233
+ ### 主要メソッド
234
+
235
+ | メソッド | 説明 |
236
+ | ---------------------------- | -------------------------------------------------------------- |
237
+ | `getAttribute(name)` | 属性値または `null` を返す |
238
+ | `getAttributeToken(name)` | 名前付き属性の `MLAttr[]` を返す |
239
+ | `hasAttribute(name)` | 属性の存在を確認 |
240
+ | `matches(selector)` | CSS セレクタマッチング |
241
+ | `matchMLSelector(selector)` | 拡張 markuplint セレクタマッチング(`RegexSelector` サポート) |
242
+ | `querySelector(selector)` | 最初にマッチする子孫を検索 |
243
+ | `querySelectorAll(selector)` | マッチするすべての子孫を検索 |
244
+
245
+ ## ルールシステム
246
+
247
+ ### MLRule
248
+
249
+ `MLRule<T, O>` はリンティングルールを検証およびオプションの修正ロジックとともにカプセル化します。
250
+
251
+ | プロパティ/メソッド | 説明 |
252
+ | --------------------------------- | ---------------------------------------- |
253
+ | `name` | ルール識別子(例:`"attr-duplication"`) |
254
+ | `defaultSeverity` | デフォルトの重大度レベル |
255
+ | `defaultValue` / `defaultOptions` | デフォルト設定 |
256
+ | `verify(document, locale, fix)` | ルールを実行して違反を返す |
257
+ | `optimizeOption(settings)` | 生のルール設定を `RuleInfo` に正規化 |
258
+
259
+ ### RuleSeed
260
+
261
+ `RuleSeed<T, O>` 型はルールの実装を定義します:
262
+
263
+ ```typescript
264
+ type RuleSeed<T, O> = {
265
+ meta?: {
266
+ category?: 'validation' | 'style' | 'naming-convention' | 'a11y' | 'maintainability';
267
+ };
268
+ defaultSeverity?: Severity;
269
+ defaultValue?: T;
270
+ defaultOptions?: O;
271
+ verify(context): void | Promise<void>;
272
+ fix?(context): void | Promise<void>;
273
+ };
274
+ ```
275
+
276
+ ### createRule
277
+
278
+ `createRule(seed)` は型安全なルールシード作成のためのファクトリ関数です。シードをそのまま返し、主に型ヘルパーとして機能します。
279
+
280
+ ### MLRuleContext
281
+
282
+ `MLRuleContext<T, O>` はルールの実行コンテキストを提供します:
283
+
284
+ - `document` — 現在の `MLDocument`
285
+ - `translate` / `t` — ロケール対応のメッセージ翻訳
286
+ - `report(report)` — ノード、メッセージ、オプションの修正とともに違反を報告
287
+
288
+ `provide()` メソッドは `RuleSeed.verify()` と `RuleSeed.fix()` に渡されるコンテキストオブジェクトを返します。
289
+
290
+ ### ルール設定の解決
291
+
292
+ ルールは `RuleMapper` によって 3 つのレベルで設定されます:
293
+
294
+ 1. **グローバルルール**(`rules`)— すべてのノードに適用。最低優先度
295
+ 2. **ノードルール**(`nodeRules`)— セレクタにマッチするノードに適用。中優先度
296
+ 3. **子ノードルール**(`childNodeRules`)— セレクタにマッチするノードの子に適用。最高優先度
297
+
298
+ 複数のルールがマッチする場合、`RuleMapper` は CSS セレクタの詳細度を使って競合を解決します。マッピングは `MLDocument` の構築時に一度計算され、各 `MLNode.rules` に格納されます。
299
+
300
+ ### ルール実行フロー
301
+
302
+ ```mermaid
303
+ flowchart TD
304
+ A["MLCore.verify()"] --> B["各 MLRule に対して"]
305
+ B --> C["document.setRule(rule)"]
306
+ C --> D["rule.verify(document, locale, fix)"]
307
+ D --> E["rule.getRuleInfo(ruleset)\nグローバル設定を解決"]
308
+ E --> F["document.walkOn(type, walker)\nマッチするノードを走査"]
309
+ F --> G["context.report()\nノードごとに違反を収集"]
310
+ G --> H["Violation[] を返す"]
311
+ ```
312
+
313
+ ## Pretender システム
314
+
315
+ pretender システムにより、コンポーネントをリンティング時にセマンティック HTML 要素として扱うことができます。これにより、ルールがカスタムコンポーネント(例:`<MyButton>`)を標準要素(例:`<button>`)として検証できます。
316
+
317
+ ### 設定
318
+
319
+ pretender は markuplint 設定で `Pretender` オブジェクトの配列として定義されます:
320
+
321
+ ```typescript
322
+ type Pretender = {
323
+ selector: string; // コンポーネントにマッチする CSS セレクタ
324
+ as: string; // 偽装する HTML 要素
325
+ aria?: PretenderARIA; // オプションの ARIA オーバーライド
326
+ };
327
+ ```
328
+
329
+ ### 動作の仕組み
330
+
331
+ 1. `MLDocument` の構築時に pretender 定義が処理される
332
+ 2. pretender セレクタにマッチする各 `MLElement` は `type: 'pretender'` の `pretenderContext` を取得
333
+ 3. 対象の HTML 要素は `type: 'origin'` の `pretenderContext` を取得
334
+ 4. ルールは `element.pretenderContext` にアクセスしてセマンティックマッピングを確認可能
335
+ 5. アクセシビリティ計算はロール/名前の解決に pretender コンテキストを使用
336
+
337
+ ## 条件付き子ノード
338
+
339
+ テンプレートエンジン(Pug, EJS, Nunjucks など)はプリプロセッサ固有のブロックを生成し、`MLBlock` ノードで表現されます。これらのブロックは子ノードを条件付きでラップできます:
340
+
341
+ | `conditionalType` | テンプレート構文 | 説明 |
342
+ | ----------------- | ----------------- | ------------------ |
343
+ | `'if:start'` | `{% if %}` | 条件ブロックの開始 |
344
+ | `'if:else'` | `{% else %}` | 代替分岐 |
345
+ | `'if:end'` | `{% endif %}` | 条件ブロックの終了 |
346
+ | `'each:start'` | `{% for %}` | ループの開始 |
347
+ | `'each:end'` | `{% endfor %}` | ループの終了 |
348
+ | `'switch:start'` | `{% switch %}` | switch の開始 |
349
+ | `'switch:case'` | `{% case %}` | switch ケース |
350
+ | `'switch:end'` | `{% endswitch %}` | switch の終了 |
351
+
352
+ `MLNode.conditionalChildNodes()` は `NodeListOf` 配列の配列を返します(条件分岐ごとに 1 つ)。これにより、ルールは各分岐を独立して分析できます。
353
+
354
+ ## プラグインシステム
355
+
356
+ プラグインはカスタムルールと共有設定で markuplint を拡張します。
357
+
358
+ ### Plugin 型
359
+
360
+ ```typescript
361
+ type Plugin = {
362
+ readonly name: string;
363
+ readonly rules?: Record<string, RuleSeed<any, any>>;
364
+ readonly configs?: Record<string, Config>;
365
+ };
366
+ ```
367
+
368
+ ### PluginCreator
369
+
370
+ 設定を受け付けるプラグイン用:
371
+
372
+ ```typescript
373
+ type PluginCreator<S> = {
374
+ readonly name: string;
375
+ create(setting: S): Omit<Plugin, 'name'>;
376
+ };
377
+ ```
378
+
379
+ `createPlugin(creator)` は型安全なプラグインクリエーター定義のためのファクトリ関数です。
380
+
381
+ ## テストユーティリティ
382
+
383
+ `test/` モジュールはルールテスト用のヘルパーを提供します:
384
+
385
+ | 関数 | 説明 |
386
+ | ------------------------------------------- | ------------------------------------------------ |
387
+ | `createTestDocument(sourceCode, options?)` | ソースをテスト用 `MLDocument` にパース |
388
+ | `createTestElement(sourceCode, options?)` | ソースをパースして最初の `MLElement` を返す |
389
+ | `createTestNodeList(sourceCode, options?)` | パースされたソースのフラットノードリストを返す |
390
+ | `createTestTokenList(sourceCode, options?)` | パースされたソースのフラットトークンリストを返す |
391
+ | `dummySchemas()` | デフォルト HTML 仕様をスキーマタプルとして返す |
392
+
393
+ `CreateTestOptions` は `config`, `parser`, `specs`, `pretenders` のオーバーライドを受け付けます。
394
+
395
+ ## 外部依存パッケージ
396
+
397
+ | 依存パッケージ | 用途 |
398
+ | ---------------------------- | ------------------------------------------------------ |
399
+ | `@markuplint/ml-ast` | AST 型定義(`MLASTDocument`, `MLASTNode` など) |
400
+ | `@markuplint/ml-config` | 設定型(`Config`, `RuleConfigValue`, `Pretender`) |
401
+ | `@markuplint/ml-spec` | HTML/ARIA 仕様アクセス(`MLMLSpec`, ロール/属性仕様) |
402
+ | `@markuplint/html-spec` | デフォルト HTML 仕様データ |
403
+ | `@markuplint/html-parser` | デフォルト HTML パーサー(テストユーティリティで使用) |
404
+ | `@markuplint/parser-utils` | パーサーオプションと型 |
405
+ | `@markuplint/selector` | CSS および拡張セレクタマッチング |
406
+ | `@markuplint/i18n` | 国際化(`LocaleSet`, `Translator`) |
407
+ | `@markuplint/shared` | 共有ユーティリティ |
408
+ | `@markuplint/config-presets` | 組み込み設定プリセット |
409
+ | `debug` | デバッグログ |
410
+ | `is-plain-object` | プレーンオブジェクト型チェック |
411
+ | `type-fest` | TypeScript ユーティリティ型 |
412
+
413
+ ## 統合ポイント
414
+
415
+ ```mermaid
416
+ flowchart TD
417
+ subgraph upstream ["上流"]
418
+ mlAst["@markuplint/ml-ast"]
419
+ mlConfig["@markuplint/ml-config"]
420
+ mlSpec["@markuplint/ml-spec"]
421
+ htmlSpec["@markuplint/html-spec"]
422
+ htmlParser["@markuplint/html-parser"]
423
+ parserUtils["@markuplint/parser-utils"]
424
+ selector["@markuplint/selector"]
425
+ i18n["@markuplint/i18n"]
426
+ shared["@markuplint/shared"]
427
+ configPresets["@markuplint/config-presets"]
428
+ end
429
+
430
+ subgraph pkg ["@markuplint/ml-core"]
431
+ core["MLCore エンジン"]
432
+ end
433
+
434
+ subgraph downstream ["下流"]
435
+ rules["@markuplint/rules\n(組み込みルール実装)"]
436
+ markuplint["markuplint\n(CLI, API, MLEngine)"]
437
+ end
438
+
439
+ upstream -->|"型、パース、仕様、i18n"| core
440
+ core -->|"MLDOM クラス, MLRule,\ncreateRule, テストユーティリティ"| rules
441
+ core -->|"MLCore, ViolationCollector,\nconvertRuleset, Plugin 型"| markuplint
442
+ ```
443
+
444
+ ### 上流
445
+
446
+ - **`@markuplint/ml-ast`** — MLDOM ツリー構築に使用される AST 型
447
+ - **`@markuplint/ml-config`** — 設定およびルール設定型
448
+ - **`@markuplint/ml-spec`** — 要素検証、ロール計算用の HTML/ARIA 仕様
449
+ - **`@markuplint/html-spec`** — デフォルト仕様データバンドル
450
+ - **`@markuplint/html-parser`** — テストユーティリティで使用されるデフォルトパーサー
451
+ - **`@markuplint/parser-utils`** — パーサーオプション型
452
+ - **`@markuplint/selector`** — `querySelector`, `matches`, `RegexSelector` 用の CSS セレクタエンジン
453
+ - **`@markuplint/i18n`** — ルールメッセージ用のロケールセットと翻訳
454
+ - **`@markuplint/shared`** — 共有ユーティリティ関数
455
+ - **`@markuplint/config-presets`** — 組み込み設定プリセット
456
+
457
+ ### 下流
458
+
459
+ - **`@markuplint/rules`** — 組み込みルール実装のために MLDOM クラス、`createRule`, `MLRuleContext`, テストユーティリティをインポート
460
+ - **`markuplint`** — CLI と API を提供するために `MLCore`, `ViolationCollector`, `convertRuleset`, プラグイン型をインポート
461
+
462
+ ## ドキュメントマップ
463
+
464
+ - [MLDOM リファレンス](docs/ml-dom.ja.md) ([English](docs/ml-dom.md)) — クラス階層、ノードプロパティ、ツリー走査
465
+ - [ルールシステム](docs/rule-system.ja.md) ([English](docs/rule-system.md)) — MLRule、RuleSeed、MLRuleContext、設定解決
466
+ - [リンティングパイプライン](docs/linting-pipeline.ja.md) ([English](docs/linting-pipeline.md)) — MLCore エンジン、verify フロー、pretender、プラグインシステム
467
+ - [メンテナンスガイド](docs/maintenance.ja.md) ([English](docs/maintenance.md)) — コマンド、レシピ、トラブルシューティング