@markuplint/ml-ast 4.4.10 → 5.0.0-alpha.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.
@@ -0,0 +1,310 @@
1
+ # @markuplint/ml-ast
2
+
3
+ ## 概要
4
+
5
+ `@markuplint/ml-ast` は、markuplint の言語非依存な抽象構文木(AST)中間表現を定義する純粋な型定義パッケージです。**ランタイムコードはゼロ**、**依存関係もゼロ**で、すべてのパーサーが生成し、すべての下流パッケージが消費する TypeScript 型定義のみを含みます。
6
+
7
+ すべてのマークアップ言語パーサー(HTML、JSX、Vue、Svelte、Astro、Pug など)はソースコードをここで定義された型にパースし、markuplint のコアとルールがソース言語に関係なく統一された AST 上で動作できるようにします。
8
+
9
+ ## ディレクトリ構成
10
+
11
+ ```
12
+ src/
13
+ ├── index.ts — types.ts からすべての型を再エクスポート
14
+ └── types.ts — すべての型定義(約470行)
15
+ ```
16
+
17
+ ## アーキテクチャ図
18
+
19
+ ```mermaid
20
+ flowchart TD
21
+ subgraph parsers ["パーサー(上流)"]
22
+ html["@markuplint/html-parser"]
23
+ jsx["@markuplint/jsx-parser"]
24
+ vue["@markuplint/vue-parser"]
25
+ svelte["@markuplint/svelte-parser"]
26
+ astro["@markuplint/astro-parser"]
27
+ pug["@markuplint/pug-parser"]
28
+ parserUtils["@markuplint/parser-utils"]
29
+ end
30
+
31
+ subgraph ast ["@markuplint/ml-ast"]
32
+ types["型定義\n(MLASTDocument, MLASTElement,\nMLASTComment, MLASTText, ...)"]
33
+ end
34
+
35
+ subgraph downstream ["下流"]
36
+ mlCore["@markuplint/ml-core\n(AST → DOM マッピング)"]
37
+ mlConfig["@markuplint/ml-config"]
38
+ mlSpec["@markuplint/ml-spec"]
39
+ rules["@markuplint/rules"]
40
+ fileResolver["@markuplint/file-resolver"]
41
+ end
42
+
43
+ parsers -->|"生成"| types
44
+ types -->|"消費"| downstream
45
+ mlCore -->|"DOM ノードを作成"| types
46
+ ```
47
+
48
+ ## 型継承図
49
+
50
+ ```mermaid
51
+ classDiagram
52
+ class MLASTToken {
53
+ <<interface>>
54
+ +uuid: string
55
+ +raw: string
56
+ +offset: number
57
+ +line: number
58
+ +col: number
59
+ }
60
+
61
+ class MLASTAbstractNode {
62
+ <<interface>>
63
+ +type: MLASTNodeType
64
+ +nodeName: string
65
+ +parentNode: MLASTParentNode | null
66
+ }
67
+
68
+ class MLASTDoctype {
69
+ <<interface>>
70
+ +type: "doctype"
71
+ +depth: number
72
+ +name: string
73
+ +publicId: string
74
+ +systemId: string
75
+ }
76
+
77
+ class MLASTElement {
78
+ <<interface>>
79
+ +type: "starttag"
80
+ +depth: number
81
+ +namespace: string
82
+ +elementType: ElementType
83
+ +attributes: MLASTAttr[]
84
+ +childNodes: MLASTChildNode[]
85
+ +blockBehavior: MLASTBlockBehavior | null
86
+ +pairNode: MLASTElementCloseTag | null
87
+ +isGhost: boolean
88
+ +isFragment: boolean
89
+ }
90
+
91
+ class MLASTElementCloseTag {
92
+ <<interface>>
93
+ +type: "endtag"
94
+ +depth: number
95
+ +parentNode: null
96
+ +pairNode: MLASTElement
97
+ }
98
+
99
+ class MLASTComment {
100
+ <<interface>>
101
+ +type: "comment"
102
+ +depth: number
103
+ +isBogus: boolean
104
+ }
105
+
106
+ class MLASTText {
107
+ <<interface>>
108
+ +type: "text"
109
+ +depth: number
110
+ }
111
+
112
+ class MLASTPreprocessorSpecificBlock {
113
+ <<interface>>
114
+ +type: "psblock"
115
+ +blockBehavior: MLASTBlockBehavior | null
116
+ +depth: number
117
+ +childNodes: MLASTChildNode[]
118
+ +isBogus: boolean
119
+ }
120
+
121
+ class MLASTInvalid {
122
+ <<interface>>
123
+ +type: "invalid"
124
+ +depth: number
125
+ +kind: MLASTChildNode type
126
+ +isBogus: true
127
+ }
128
+
129
+ class MLASTHTMLAttr {
130
+ <<interface>>
131
+ +type: "attr"
132
+ +name: MLASTToken
133
+ +value: MLASTToken
134
+ +isDynamicValue: boolean
135
+ +isDirective: boolean
136
+ }
137
+
138
+ class MLASTSpreadAttr {
139
+ <<interface>>
140
+ +type: "spread"
141
+ }
142
+
143
+ MLASTToken <|-- MLASTAbstractNode
144
+ MLASTAbstractNode <|-- MLASTDoctype
145
+ MLASTAbstractNode <|-- MLASTElement
146
+ MLASTAbstractNode <|-- MLASTElementCloseTag
147
+ MLASTAbstractNode <|-- MLASTComment
148
+ MLASTAbstractNode <|-- MLASTText
149
+ MLASTAbstractNode <|-- MLASTPreprocessorSpecificBlock
150
+ MLASTAbstractNode <|-- MLASTInvalid
151
+ MLASTToken <|-- MLASTHTMLAttr
152
+ MLASTToken <|-- MLASTSpreadAttr
153
+ ```
154
+
155
+ ## 共用体型
156
+
157
+ ```mermaid
158
+ flowchart TD
159
+ subgraph MLASTNode ["MLASTNode(全ノード型)"]
160
+ subgraph MLASTNodeTreeItem ["MLASTNodeTreeItem"]
161
+ MLASTDoctype["MLASTDoctype"]
162
+ subgraph MLASTChildNode ["MLASTChildNode"]
163
+ subgraph MLASTTag ["MLASTTag"]
164
+ MLASTElement["MLASTElement"]
165
+ MLASTElementCloseTag["MLASTElementCloseTag"]
166
+ end
167
+ MLASTText["MLASTText"]
168
+ MLASTComment["MLASTComment"]
169
+ MLASTPreprocessorSpecificBlock["MLASTPreprocessorSpecificBlock"]
170
+ MLASTInvalid["MLASTInvalid"]
171
+ end
172
+ end
173
+ subgraph MLASTAttr ["MLASTAttr"]
174
+ MLASTHTMLAttr["MLASTHTMLAttr"]
175
+ MLASTSpreadAttr["MLASTSpreadAttr"]
176
+ end
177
+ end
178
+
179
+ style MLASTElement fill:#e1f5fe
180
+ style MLASTPreprocessorSpecificBlock fill:#e1f5fe
181
+
182
+ note1["MLASTParentNode = MLASTElement | MLASTPreprocessorSpecificBlock\n(青でハイライト)"]
183
+ ```
184
+
185
+ ## ノード型一覧
186
+
187
+ | 型 | `type` 値 | 代表例 | 説明 |
188
+ | -------------------------------- | ------------ | ---------------------- | ---------------------------------------- |
189
+ | `MLASTDoctype` | `'doctype'` | `<!DOCTYPE html>` | DOCTYPE 宣言 |
190
+ | `MLASTElement` | `'starttag'` | `<div class="foo">` | 開始タグ。属性・子ノード・名前空間を保持 |
191
+ | `MLASTElementCloseTag` | `'endtag'` | `</div>` | 閉じタグ。開始タグとペア |
192
+ | `MLASTComment` | `'comment'` | `<!-- ... -->` | HTML コメント。bogus フラグ付き |
193
+ | `MLASTText` | `'text'` | テキスト内容 | 要素間の文字データ |
194
+ | `MLASTPreprocessorSpecificBlock` | `'psblock'` | `{#if}`, `<% %>` | テンプレートエンジン構文 |
195
+ | `MLASTInvalid` | `'invalid'` | パース不能マークアップ | 不正ノード。意図された種別のヒント付き |
196
+ | `MLASTHTMLAttr` | `'attr'` | `class="foo"` | 完全分解された HTML 属性 |
197
+ | `MLASTSpreadAttr` | `'spread'` | `{...props}` | JSX スプレッド属性 |
198
+
199
+ 各型の詳細は[ノードリファレンス](docs/node-reference.ja.md)を参照してください。
200
+
201
+ ## AST から MLDOM へのマッピング
202
+
203
+ 各 AST ノードは、最終的に `@markuplint/ml-core` によって **MLDOM** ノードに変換されます。MLDOM は [DOM Standard](https://dom.spec.whatwg.org/) に準拠しており、各クラスは対応する DOM インターフェース(`Node`、`Element`、`DocumentType`、`Comment`、`Text` など)を実装しているため、リントルールは標準 DOM API を使って検査できます。
204
+
205
+ | AST 型(`ml-ast`) | MLDOM クラス(`ml-core`) | DOM インターフェース | `nodeType` |
206
+ | ------------------------------------ | -------------------------- | ------------------------ | ---------- |
207
+ | `MLASTDoctype` | `MLDocumentType` | `DocumentType` | `10` |
208
+ | `MLASTElement` | `MLElement` | `Element`, `HTMLElement` | `1` |
209
+ | `MLASTComment` | `MLComment` | `Comment` | `8` |
210
+ | `MLASTText` | `MLText` | `Text` | `3` |
211
+ | `MLASTPreprocessorSpecificBlock` | `MLBlock` | _(markuplint 独自)_ | `101` |
212
+ | `MLASTInvalid`(`kind: 'starttag'`) | `MLElement`(`x-invalid`) | `Element`, `HTMLElement` | `1` |
213
+ | `MLASTInvalid`(その他) | `MLText` | `Text` | `3` |
214
+ | `MLASTHTMLAttr` / `MLASTSpreadAttr` | `MLAttr` | `Attr` | `2` |
215
+
216
+ **特殊なノード:**
217
+
218
+ - **`MLBlock`**(`nodeType: 101`)は DOM Standard に相当するものがない markuplint 独自の拡張です。透過的なコンテナとして機能し、子ノードはツリー走査時に親に属するものとして扱われます。
219
+ - **`MLElementCloseTag`** は `createNode()` で生成されません。代わりに `MLElement` が内部で `pairNode` 参照から生成します。ペアとなる要素の付属物としてのみ存在し、DOM ツリー走査の対象ではありません。
220
+ - **`MLASTInvalid`** はリカバリノードです。MLDOM にそのまま保持されることはなく、`kind` フィールドに応じて `MLElement`(タグ名 `x-invalid`)または `MLText` に変換されます。
221
+
222
+ 詳細は[ノードリファレンス -- AST から MLDOM へのマッピング](docs/node-reference.ja.md#ast-から-mldom-へのマッピング)を参照してください。
223
+
224
+ ## 属性分解モデル
225
+
226
+ `MLASTHTMLAttr` は各属性を完全な位置情報を持つ個別のトークンに分解します:
227
+
228
+ ```
229
+ ·class="container"
230
+ ↑ ↑↑ ↑
231
+ │ ││ └─ endQuote
232
+ │ │└─ value
233
+ │ └─ startQuote
234
+ │ equal
235
+ └─ spacesBeforeName
236
+ name
237
+ ```
238
+
239
+ これにより、リントルールは `=` 前後のホワイトスペース、引用符スタイル、属性命名規則を正確なソース位置で検証できます。完全なフィールドドキュメントは[ノードリファレンス](docs/node-reference.ja.md#mlasthtmlattr)を参照してください。
240
+
241
+ ## パーサーインターフェース
242
+
243
+ | 型 | 説明 |
244
+ | ---------------- | -------------------------------------------------------- |
245
+ | `MLParser` | markuplint 互換パーサーのインターフェース |
246
+ | `MLParserModule` | パーサーインスタンスをエクスポートするモジュールラッパー |
247
+
248
+ `MLParser` は `MLASTDocument` を返す `parse(sourceCode, options?)` メソッドを必要とします。オプションフィールドには `endTag`(終了タグ処理戦略)、`booleanish`(ブール属性検出)、`tagNameCaseSensitive`(XHTML/JSX 用)があります。
249
+
250
+ ## 設定型
251
+
252
+ | 型 | 説明 |
253
+ | ----------------------------------------- | ---------------------------------------------------------------------- |
254
+ | `MLASTNodeType` | ノード種別の判別共用体タグ |
255
+ | `ElementType` | 要素分類:`'html' \| 'web-component' \| 'authored'` |
256
+ | `EndTagType` | 終了タグ戦略:`'xml' \| 'omittable' \| 'never'` |
257
+ | `Namespace` | 短い名前空間識別子:`'html' \| 'svg' \| 'mml' \| 'xlink'` |
258
+ | `NamespaceURI` | HTML、SVG、MathML、XLink の完全な名前空間 URI |
259
+ | `ParserOptions` | パーサーに渡すオプション(`ignoreFrontMatter`、`authoredElementName`) |
260
+ | `ParserAuthoredElementNameDistinguishing` | 著者定義要素を区別するための設定 |
261
+ | `Walker<Node>` | AST ノードを走査するコールバック |
262
+
263
+ ## 外部依存関係
264
+
265
+ なし。このパッケージはランタイム依存関係がゼロです。TypeScript の型定義のみをエクスポートします。
266
+
267
+ ## 統合ポイント
268
+
269
+ ```mermaid
270
+ flowchart TD
271
+ subgraph upstream ["上流(パーサー)"]
272
+ htmlParser["@markuplint/html-parser"]
273
+ parserUtils["@markuplint/parser-utils"]
274
+ jsxParser["@markuplint/jsx-parser"]
275
+ astroParser["@markuplint/astro-parser"]
276
+ vueParser["@markuplint/vue-parser"]
277
+ svelteParser["@markuplint/svelte-parser"]
278
+ pugParser["@markuplint/pug-parser"]
279
+ end
280
+
281
+ subgraph pkg ["@markuplint/ml-ast"]
282
+ astTypes["型定義"]
283
+ end
284
+
285
+ subgraph downstream ["下流"]
286
+ mlCore["@markuplint/ml-core"]
287
+ mlConfig["@markuplint/ml-config"]
288
+ mlSpec["@markuplint/ml-spec"]
289
+ fileResolver["@markuplint/file-resolver"]
290
+ end
291
+
292
+ upstream -->|"MLParser を実装\nMLASTDocument を生成"| astTypes
293
+ astTypes -->|"MLASTNode 型\nMLParser インターフェース"| downstream
294
+ ```
295
+
296
+ ### 上流
297
+
298
+ すべてのパーサーは `MLParser` インターフェースを実装し、このパッケージで定義された AST ノード型を含む `MLASTDocument` インスタンスを生成します。
299
+
300
+ ### 下流
301
+
302
+ - **`@markuplint/ml-core`** は AST ノードを消費し、`createNode()` を通じて DOM ノードにマッピングします。`MLASTElement` が `MLElement` に、`MLASTText` が `MLText` になるなど、主要な統合ポイントです。
303
+ - **`@markuplint/ml-config`** は設定スキーマ定義で AST 型を参照します。
304
+ - **`@markuplint/ml-spec`** は名前空間と要素型の定義を使用します。
305
+ - **`@markuplint/file-resolver`** はパーサー関連の型を参照します。
306
+
307
+ ## ドキュメントマップ
308
+
309
+ - [ノードリファレンス](docs/node-reference.ja.md) -- 各 AST ノード型の詳細ドキュメント
310
+ - [メンテナンスガイド](docs/maintenance.ja.md) -- コマンド、レシピ、トラブルシューティング
@@ -0,0 +1,310 @@
1
+ # @markuplint/ml-ast
2
+
3
+ ## Overview
4
+
5
+ `@markuplint/ml-ast` is a pure type-definition package that defines the language-independent Abstract Syntax Tree (AST) intermediate representation for markuplint. It contains **zero runtime code** and **zero dependencies** -- only TypeScript type definitions that all parsers must produce and all downstream packages consume.
6
+
7
+ Every markup language parser (HTML, JSX, Vue, Svelte, Astro, Pug, etc.) parses source code into the types defined here, enabling markuplint's core and rules to operate on a unified AST regardless of the source language.
8
+
9
+ ## Directory Structure
10
+
11
+ ```
12
+ src/
13
+ ├── index.ts — Re-exports all types from types.ts
14
+ └── types.ts — All type definitions (~470 lines)
15
+ ```
16
+
17
+ ## Architecture Diagram
18
+
19
+ ```mermaid
20
+ flowchart TD
21
+ subgraph parsers ["Parsers (upstream)"]
22
+ html["@markuplint/html-parser"]
23
+ jsx["@markuplint/jsx-parser"]
24
+ vue["@markuplint/vue-parser"]
25
+ svelte["@markuplint/svelte-parser"]
26
+ astro["@markuplint/astro-parser"]
27
+ pug["@markuplint/pug-parser"]
28
+ parserUtils["@markuplint/parser-utils"]
29
+ end
30
+
31
+ subgraph ast ["@markuplint/ml-ast"]
32
+ types["Type Definitions\n(MLASTDocument, MLASTElement,\nMLASTComment, MLASTText, ...)"]
33
+ end
34
+
35
+ subgraph downstream ["Downstream"]
36
+ mlCore["@markuplint/ml-core\n(AST → DOM mapping)"]
37
+ mlConfig["@markuplint/ml-config"]
38
+ mlSpec["@markuplint/ml-spec"]
39
+ rules["@markuplint/rules"]
40
+ fileResolver["@markuplint/file-resolver"]
41
+ end
42
+
43
+ parsers -->|"produce"| types
44
+ types -->|"consumed by"| downstream
45
+ mlCore -->|"creates DOM nodes from"| types
46
+ ```
47
+
48
+ ## Type Inheritance Diagram
49
+
50
+ ```mermaid
51
+ classDiagram
52
+ class MLASTToken {
53
+ <<interface>>
54
+ +uuid: string
55
+ +raw: string
56
+ +offset: number
57
+ +line: number
58
+ +col: number
59
+ }
60
+
61
+ class MLASTAbstractNode {
62
+ <<interface>>
63
+ +type: MLASTNodeType
64
+ +nodeName: string
65
+ +parentNode: MLASTParentNode | null
66
+ }
67
+
68
+ class MLASTDoctype {
69
+ <<interface>>
70
+ +type: "doctype"
71
+ +depth: number
72
+ +name: string
73
+ +publicId: string
74
+ +systemId: string
75
+ }
76
+
77
+ class MLASTElement {
78
+ <<interface>>
79
+ +type: "starttag"
80
+ +depth: number
81
+ +namespace: string
82
+ +elementType: ElementType
83
+ +attributes: MLASTAttr[]
84
+ +childNodes: MLASTChildNode[]
85
+ +blockBehavior: MLASTBlockBehavior | null
86
+ +pairNode: MLASTElementCloseTag | null
87
+ +isGhost: boolean
88
+ +isFragment: boolean
89
+ }
90
+
91
+ class MLASTElementCloseTag {
92
+ <<interface>>
93
+ +type: "endtag"
94
+ +depth: number
95
+ +parentNode: null
96
+ +pairNode: MLASTElement
97
+ }
98
+
99
+ class MLASTComment {
100
+ <<interface>>
101
+ +type: "comment"
102
+ +depth: number
103
+ +isBogus: boolean
104
+ }
105
+
106
+ class MLASTText {
107
+ <<interface>>
108
+ +type: "text"
109
+ +depth: number
110
+ }
111
+
112
+ class MLASTPreprocessorSpecificBlock {
113
+ <<interface>>
114
+ +type: "psblock"
115
+ +blockBehavior: MLASTBlockBehavior | null
116
+ +depth: number
117
+ +childNodes: MLASTChildNode[]
118
+ +isBogus: boolean
119
+ }
120
+
121
+ class MLASTInvalid {
122
+ <<interface>>
123
+ +type: "invalid"
124
+ +depth: number
125
+ +kind: MLASTChildNode type
126
+ +isBogus: true
127
+ }
128
+
129
+ class MLASTHTMLAttr {
130
+ <<interface>>
131
+ +type: "attr"
132
+ +name: MLASTToken
133
+ +value: MLASTToken
134
+ +isDynamicValue: boolean
135
+ +isDirective: boolean
136
+ }
137
+
138
+ class MLASTSpreadAttr {
139
+ <<interface>>
140
+ +type: "spread"
141
+ }
142
+
143
+ MLASTToken <|-- MLASTAbstractNode
144
+ MLASTAbstractNode <|-- MLASTDoctype
145
+ MLASTAbstractNode <|-- MLASTElement
146
+ MLASTAbstractNode <|-- MLASTElementCloseTag
147
+ MLASTAbstractNode <|-- MLASTComment
148
+ MLASTAbstractNode <|-- MLASTText
149
+ MLASTAbstractNode <|-- MLASTPreprocessorSpecificBlock
150
+ MLASTAbstractNode <|-- MLASTInvalid
151
+ MLASTToken <|-- MLASTHTMLAttr
152
+ MLASTToken <|-- MLASTSpreadAttr
153
+ ```
154
+
155
+ ## Union Types
156
+
157
+ ```mermaid
158
+ flowchart TD
159
+ subgraph MLASTNode ["MLASTNode (all node types)"]
160
+ subgraph MLASTNodeTreeItem ["MLASTNodeTreeItem"]
161
+ MLASTDoctype["MLASTDoctype"]
162
+ subgraph MLASTChildNode ["MLASTChildNode"]
163
+ subgraph MLASTTag ["MLASTTag"]
164
+ MLASTElement["MLASTElement"]
165
+ MLASTElementCloseTag["MLASTElementCloseTag"]
166
+ end
167
+ MLASTText["MLASTText"]
168
+ MLASTComment["MLASTComment"]
169
+ MLASTPreprocessorSpecificBlock["MLASTPreprocessorSpecificBlock"]
170
+ MLASTInvalid["MLASTInvalid"]
171
+ end
172
+ end
173
+ subgraph MLASTAttr ["MLASTAttr"]
174
+ MLASTHTMLAttr["MLASTHTMLAttr"]
175
+ MLASTSpreadAttr["MLASTSpreadAttr"]
176
+ end
177
+ end
178
+
179
+ style MLASTElement fill:#e1f5fe
180
+ style MLASTPreprocessorSpecificBlock fill:#e1f5fe
181
+
182
+ note1["MLASTParentNode = MLASTElement | MLASTPreprocessorSpecificBlock\n(highlighted in blue)"]
183
+ ```
184
+
185
+ ## Node Types at a Glance
186
+
187
+ | Type | `type` Value | Example | Description |
188
+ | -------------------------------- | ------------ | ------------------- | -------------------------------------------------------- |
189
+ | `MLASTDoctype` | `'doctype'` | `<!DOCTYPE html>` | DOCTYPE declaration |
190
+ | `MLASTElement` | `'starttag'` | `<div class="foo">` | Opening element tag with attributes, children, namespace |
191
+ | `MLASTElementCloseTag` | `'endtag'` | `</div>` | Closing element tag, paired with its opening tag |
192
+ | `MLASTComment` | `'comment'` | `<!-- ... -->` | HTML comment, with bogus flag |
193
+ | `MLASTText` | `'text'` | text content | Character data between elements |
194
+ | `MLASTPreprocessorSpecificBlock` | `'psblock'` | `{#if}`, `<% %>` | Template engine constructs |
195
+ | `MLASTInvalid` | `'invalid'` | unparsable markup | Invalid node with intended kind hint |
196
+ | `MLASTHTMLAttr` | `'attr'` | `class="foo"` | Fully decomposed HTML attribute |
197
+ | `MLASTSpreadAttr` | `'spread'` | `{...props}` | JSX spread attribute |
198
+
199
+ See [Node Reference](docs/node-reference.md) for detailed documentation of each type.
200
+
201
+ ## AST to MLDOM Mapping
202
+
203
+ Each AST node is ultimately converted into an **MLDOM** node by `@markuplint/ml-core`. MLDOM conforms to the [DOM Standard](https://dom.spec.whatwg.org/) -- each class implements the corresponding DOM interface (`Node`, `Element`, `DocumentType`, `Comment`, `Text`, etc.), so lint rules can use standard DOM APIs for inspection.
204
+
205
+ | AST Type (`ml-ast`) | MLDOM Class (`ml-core`) | DOM Interface | `nodeType` |
206
+ | ----------------------------------- | ------------------------- | ------------------------ | ---------- |
207
+ | `MLASTDoctype` | `MLDocumentType` | `DocumentType` | `10` |
208
+ | `MLASTElement` | `MLElement` | `Element`, `HTMLElement` | `1` |
209
+ | `MLASTComment` | `MLComment` | `Comment` | `8` |
210
+ | `MLASTText` | `MLText` | `Text` | `3` |
211
+ | `MLASTPreprocessorSpecificBlock` | `MLBlock` | _(markuplint-specific)_ | `101` |
212
+ | `MLASTInvalid` (`kind: 'starttag'`) | `MLElement` (`x-invalid`) | `Element`, `HTMLElement` | `1` |
213
+ | `MLASTInvalid` (other) | `MLText` | `Text` | `3` |
214
+ | `MLASTHTMLAttr` / `MLASTSpreadAttr` | `MLAttr` | `Attr` | `2` |
215
+
216
+ **Special nodes:**
217
+
218
+ - **`MLBlock`** (`nodeType: 101`) is a markuplint-specific extension with no DOM Standard equivalent. It acts as a transparent container -- its children are treated as belonging to the parent for tree traversal.
219
+ - **`MLElementCloseTag`** is not created by `createNode()`. Instead, `MLElement` internally creates it from its `pairNode` reference. It exists only as a satellite of its paired element and is not part of the DOM tree traversal.
220
+ - **`MLASTInvalid`** is a recovery node -- it is never preserved as-is in MLDOM, but converted to either an `MLElement` (with tag name `x-invalid`) or an `MLText`, depending on its `kind` field.
221
+
222
+ See [Node Reference -- AST to MLDOM Mapping](docs/node-reference.md#ast-to-mldom-mapping) for details.
223
+
224
+ ## Attribute Decomposition Model
225
+
226
+ `MLASTHTMLAttr` decomposes each attribute into individual tokens with full positional information:
227
+
228
+ ```
229
+ ·class="container"
230
+ ↑ ↑↑ ↑
231
+ │ ││ └─ endQuote
232
+ │ │└─ value
233
+ │ └─ startQuote
234
+ │ equal
235
+ └─ spacesBeforeName
236
+ name
237
+ ```
238
+
239
+ This enables lint rules to validate whitespace around `=`, quoting style, and attribute naming conventions with precise source locations. See [Node Reference](docs/node-reference.md#mlasthtmlattr) for complete field documentation.
240
+
241
+ ## Parser Interface
242
+
243
+ | Type | Description |
244
+ | ---------------- | --------------------------------------------- |
245
+ | `MLParser` | Interface for a markuplint-compatible parser |
246
+ | `MLParserModule` | Module wrapper that exports a parser instance |
247
+
248
+ `MLParser` requires a `parse(sourceCode, options?)` method that returns an `MLASTDocument`. Optional fields include `endTag` (end tag handling strategy), `booleanish` (boolean attribute detection), and `tagNameCaseSensitive` (for XHTML/JSX).
249
+
250
+ ## Configuration Types
251
+
252
+ | Type | Description |
253
+ | ----------------------------------------- | ---------------------------------------------------------------------- |
254
+ | `MLASTNodeType` | Discriminant union tag for node kinds |
255
+ | `ElementType` | Element classification: `'html' \| 'web-component' \| 'authored'` |
256
+ | `EndTagType` | End tag strategy: `'xml' \| 'omittable' \| 'never'` |
257
+ | `Namespace` | Short namespace identifiers: `'html' \| 'svg' \| 'mml' \| 'xlink'` |
258
+ | `NamespaceURI` | Full namespace URIs for HTML, SVG, MathML, XLink |
259
+ | `ParserOptions` | Options passed to parsers (`ignoreFrontMatter`, `authoredElementName`) |
260
+ | `ParserAuthoredElementNameDistinguishing` | Configuration for distinguishing authored elements |
261
+ | `Walker<Node>` | Callback for walking AST nodes |
262
+
263
+ ## External Dependencies
264
+
265
+ None. This package has zero runtime dependencies. It exports only TypeScript type definitions.
266
+
267
+ ## Integration Points
268
+
269
+ ```mermaid
270
+ flowchart TD
271
+ subgraph upstream ["Upstream (Parsers)"]
272
+ htmlParser["@markuplint/html-parser"]
273
+ parserUtils["@markuplint/parser-utils"]
274
+ jsxParser["@markuplint/jsx-parser"]
275
+ astroParser["@markuplint/astro-parser"]
276
+ vueParser["@markuplint/vue-parser"]
277
+ svelteParser["@markuplint/svelte-parser"]
278
+ pugParser["@markuplint/pug-parser"]
279
+ end
280
+
281
+ subgraph pkg ["@markuplint/ml-ast"]
282
+ astTypes["Type Definitions"]
283
+ end
284
+
285
+ subgraph downstream ["Downstream"]
286
+ mlCore["@markuplint/ml-core"]
287
+ mlConfig["@markuplint/ml-config"]
288
+ mlSpec["@markuplint/ml-spec"]
289
+ fileResolver["@markuplint/file-resolver"]
290
+ end
291
+
292
+ upstream -->|"implement MLParser\nproduce MLASTDocument"| astTypes
293
+ astTypes -->|"MLASTNode types\nMLParser interface"| downstream
294
+ ```
295
+
296
+ ### Upstream
297
+
298
+ All parsers implement the `MLParser` interface and produce `MLASTDocument` instances containing the AST node types defined in this package.
299
+
300
+ ### Downstream
301
+
302
+ - **`@markuplint/ml-core`** consumes AST nodes and maps them to DOM nodes via `createNode()`. This is the primary integration point where `MLASTElement` becomes `MLElement`, `MLASTText` becomes `MLText`, etc.
303
+ - **`@markuplint/ml-config`** references AST types in configuration schema definitions.
304
+ - **`@markuplint/ml-spec`** uses namespace and element type definitions.
305
+ - **`@markuplint/file-resolver`** references parser-related types.
306
+
307
+ ## Documentation Map
308
+
309
+ - [Node Reference](docs/node-reference.md) -- Detailed documentation of each AST node type
310
+ - [Maintenance Guide](docs/maintenance.md) -- Commands, recipes, and troubleshooting
package/CHANGELOG.md CHANGED
@@ -3,6 +3,51 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [5.0.0-alpha.0](https://github.com/markuplint/markuplint/compare/v4.14.1...v5.0.0-alpha.0) (2026-02-20)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **ml-core:** improve detection of namespace ([5b507ad](https://github.com/markuplint/markuplint/commit/5b507ad7c19c5015b8ce587845d901e31dfa6518))
11
+
12
+ - feat(ml-ast)!: simplify AST token properties and restructure block types ([78f8a77](https://github.com/markuplint/markuplint/commit/78f8a77c76728df8090fcf54c7c5541bedb56f9d))
13
+
14
+ ### BREAKING CHANGES
15
+
16
+ - Multiple breaking changes to AST interfaces:
17
+
18
+ Token property renames (MLASTToken):
19
+
20
+ - startOffset -> offset
21
+ - startLine -> line
22
+ - startCol -> col
23
+ - Remove endOffset, endLine, endCol (derive via helpers)
24
+
25
+ Element changes (MLASTElement):
26
+
27
+ - Remove selfClosingSolidus property
28
+ - Add blockBehavior: MLASTBlockBehavior | null
29
+
30
+ Block changes (MLASTPreprocessorSpecificBlock):
31
+
32
+ - Remove conditionalType property
33
+ - Add blockBehavior: MLASTBlockBehavior | null
34
+
35
+ New types:
36
+
37
+ - MLASTBlockBehavior interface (type + expression)
38
+ - MLASTBlockBehaviorType (replaces MLASTPreprocessorSpecificBlockConditionalType)
39
+
40
+ Removed deprecated types:
41
+
42
+ - MLMarkupLanguageParser interface
43
+ - Parse type alias
44
+
45
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
46
+
47
+ ## [4.4.11](https://github.com/markuplint/markuplint/compare/@markuplint/ml-ast@4.4.10...@markuplint/ml-ast@4.4.11) (2026-02-10)
48
+
49
+ **Note:** Version bump only for package @markuplint/ml-ast
50
+
6
51
  ## [4.4.10](https://github.com/markuplint/markuplint/compare/@markuplint/ml-ast@4.4.9...@markuplint/ml-ast@4.4.10) (2025-08-13)
7
52
 
8
53
  ### Bug Fixes
package/README.md CHANGED
@@ -16,3 +16,9 @@ $ yarn add @markuplint/ml-ast
16
16
  ```
17
17
 
18
18
  </details>
19
+
20
+ ## Documentation
21
+
22
+ - [Architecture](ARCHITECTURE.md) -- Package overview, type hierarchy diagrams, and integration points
23
+ - [Node Reference](docs/node-reference.md) -- Detailed documentation of each AST node type
24
+ - [Maintenance Guide](docs/maintenance.md) -- Commands, recipes, and troubleshooting