@markuplint/ml-ast 4.4.10 → 4.4.11
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.
- package/ARCHITECTURE.ja.md +314 -0
- package/ARCHITECTURE.md +314 -0
- package/CHANGELOG.md +4 -0
- package/README.md +6 -0
- package/SKILL.md +124 -0
- package/docs/maintenance.ja.md +215 -0
- package/docs/maintenance.md +215 -0
- package/docs/node-reference.ja.md +485 -0
- package/docs/node-reference.md +485 -0
- package/lib/types.d.ts +191 -0
- package/package.json +2 -2
|
@@ -0,0 +1,314 @@
|
|
|
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
|
+
+startOffset: number
|
|
57
|
+
+endOffset: number
|
|
58
|
+
+startLine: number
|
|
59
|
+
+endLine: number
|
|
60
|
+
+startCol: number
|
|
61
|
+
+endCol: number
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
class MLASTAbstractNode {
|
|
65
|
+
<<interface>>
|
|
66
|
+
+type: MLASTNodeType
|
|
67
|
+
+nodeName: string
|
|
68
|
+
+parentNode: MLASTParentNode | null
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
class MLASTDoctype {
|
|
72
|
+
<<interface>>
|
|
73
|
+
+type: "doctype"
|
|
74
|
+
+depth: number
|
|
75
|
+
+name: string
|
|
76
|
+
+publicId: string
|
|
77
|
+
+systemId: string
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
class MLASTElement {
|
|
81
|
+
<<interface>>
|
|
82
|
+
+type: "starttag"
|
|
83
|
+
+depth: number
|
|
84
|
+
+namespace: string
|
|
85
|
+
+elementType: ElementType
|
|
86
|
+
+attributes: MLASTAttr[]
|
|
87
|
+
+childNodes: MLASTChildNode[]
|
|
88
|
+
+pairNode: MLASTElementCloseTag | null
|
|
89
|
+
+isGhost: boolean
|
|
90
|
+
+isFragment: boolean
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
class MLASTElementCloseTag {
|
|
94
|
+
<<interface>>
|
|
95
|
+
+type: "endtag"
|
|
96
|
+
+depth: number
|
|
97
|
+
+parentNode: null
|
|
98
|
+
+pairNode: MLASTElement
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
class MLASTComment {
|
|
102
|
+
<<interface>>
|
|
103
|
+
+type: "comment"
|
|
104
|
+
+depth: number
|
|
105
|
+
+isBogus: boolean
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
class MLASTText {
|
|
109
|
+
<<interface>>
|
|
110
|
+
+type: "text"
|
|
111
|
+
+depth: number
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
class MLASTPreprocessorSpecificBlock {
|
|
115
|
+
<<interface>>
|
|
116
|
+
+type: "psblock"
|
|
117
|
+
+conditionalType: ...ConditionalType
|
|
118
|
+
+depth: number
|
|
119
|
+
+childNodes: MLASTChildNode[]
|
|
120
|
+
+isBogus: boolean
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
class MLASTInvalid {
|
|
124
|
+
<<interface>>
|
|
125
|
+
+type: "invalid"
|
|
126
|
+
+depth: number
|
|
127
|
+
+kind: MLASTChildNode type
|
|
128
|
+
+isBogus: true
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
class MLASTHTMLAttr {
|
|
132
|
+
<<interface>>
|
|
133
|
+
+type: "attr"
|
|
134
|
+
+name: MLASTToken
|
|
135
|
+
+value: MLASTToken
|
|
136
|
+
+isDynamicValue: boolean
|
|
137
|
+
+isDirective: boolean
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
class MLASTSpreadAttr {
|
|
141
|
+
<<interface>>
|
|
142
|
+
+type: "spread"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
MLASTToken <|-- MLASTAbstractNode
|
|
146
|
+
MLASTAbstractNode <|-- MLASTDoctype
|
|
147
|
+
MLASTAbstractNode <|-- MLASTElement
|
|
148
|
+
MLASTAbstractNode <|-- MLASTElementCloseTag
|
|
149
|
+
MLASTAbstractNode <|-- MLASTComment
|
|
150
|
+
MLASTAbstractNode <|-- MLASTText
|
|
151
|
+
MLASTAbstractNode <|-- MLASTPreprocessorSpecificBlock
|
|
152
|
+
MLASTAbstractNode <|-- MLASTInvalid
|
|
153
|
+
MLASTToken <|-- MLASTHTMLAttr
|
|
154
|
+
MLASTToken <|-- MLASTSpreadAttr
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## 共用体型
|
|
158
|
+
|
|
159
|
+
```mermaid
|
|
160
|
+
flowchart TD
|
|
161
|
+
subgraph MLASTNode ["MLASTNode(全ノード型)"]
|
|
162
|
+
subgraph MLASTNodeTreeItem ["MLASTNodeTreeItem"]
|
|
163
|
+
MLASTDoctype["MLASTDoctype"]
|
|
164
|
+
subgraph MLASTChildNode ["MLASTChildNode"]
|
|
165
|
+
subgraph MLASTTag ["MLASTTag"]
|
|
166
|
+
MLASTElement["MLASTElement"]
|
|
167
|
+
MLASTElementCloseTag["MLASTElementCloseTag"]
|
|
168
|
+
end
|
|
169
|
+
MLASTText["MLASTText"]
|
|
170
|
+
MLASTComment["MLASTComment"]
|
|
171
|
+
MLASTPreprocessorSpecificBlock["MLASTPreprocessorSpecificBlock"]
|
|
172
|
+
MLASTInvalid["MLASTInvalid"]
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
subgraph MLASTAttr ["MLASTAttr"]
|
|
176
|
+
MLASTHTMLAttr["MLASTHTMLAttr"]
|
|
177
|
+
MLASTSpreadAttr["MLASTSpreadAttr"]
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
style MLASTElement fill:#e1f5fe
|
|
182
|
+
style MLASTPreprocessorSpecificBlock fill:#e1f5fe
|
|
183
|
+
|
|
184
|
+
note1["MLASTParentNode = MLASTElement | MLASTPreprocessorSpecificBlock\n(青でハイライト)"]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## ノード型一覧
|
|
188
|
+
|
|
189
|
+
| 型 | `type` 値 | 代表例 | 説明 |
|
|
190
|
+
| -------------------------------- | ------------ | ---------------------- | ---------------------------------------- |
|
|
191
|
+
| `MLASTDoctype` | `'doctype'` | `<!DOCTYPE html>` | DOCTYPE 宣言 |
|
|
192
|
+
| `MLASTElement` | `'starttag'` | `<div class="foo">` | 開始タグ。属性・子ノード・名前空間を保持 |
|
|
193
|
+
| `MLASTElementCloseTag` | `'endtag'` | `</div>` | 閉じタグ。開始タグとペア |
|
|
194
|
+
| `MLASTComment` | `'comment'` | `<!-- ... -->` | HTML コメント。bogus フラグ付き |
|
|
195
|
+
| `MLASTText` | `'text'` | テキスト内容 | 要素間の文字データ |
|
|
196
|
+
| `MLASTPreprocessorSpecificBlock` | `'psblock'` | `{#if}`, `<% %>` | テンプレートエンジン構文 |
|
|
197
|
+
| `MLASTInvalid` | `'invalid'` | パース不能マークアップ | 不正ノード。意図された種別のヒント付き |
|
|
198
|
+
| `MLASTHTMLAttr` | `'attr'` | `class="foo"` | 完全分解された HTML 属性 |
|
|
199
|
+
| `MLASTSpreadAttr` | `'spread'` | `{...props}` | JSX スプレッド属性 |
|
|
200
|
+
|
|
201
|
+
各型の詳細は[ノードリファレンス](docs/node-reference.ja.md)を参照してください。
|
|
202
|
+
|
|
203
|
+
## AST から MLDOM へのマッピング
|
|
204
|
+
|
|
205
|
+
各 AST ノードは、最終的に `@markuplint/ml-core` によって **MLDOM** ノードに変換されます。MLDOM は [DOM Standard](https://dom.spec.whatwg.org/) に準拠しており、各クラスは対応する DOM インターフェース(`Node`、`Element`、`DocumentType`、`Comment`、`Text` など)を実装しているため、リントルールは標準 DOM API を使って検査できます。
|
|
206
|
+
|
|
207
|
+
| AST 型(`ml-ast`) | MLDOM クラス(`ml-core`) | DOM インターフェース | `nodeType` |
|
|
208
|
+
| ------------------------------------ | -------------------------- | ------------------------ | ---------- |
|
|
209
|
+
| `MLASTDoctype` | `MLDocumentType` | `DocumentType` | `10` |
|
|
210
|
+
| `MLASTElement` | `MLElement` | `Element`, `HTMLElement` | `1` |
|
|
211
|
+
| `MLASTComment` | `MLComment` | `Comment` | `8` |
|
|
212
|
+
| `MLASTText` | `MLText` | `Text` | `3` |
|
|
213
|
+
| `MLASTPreprocessorSpecificBlock` | `MLBlock` | _(markuplint 独自)_ | `101` |
|
|
214
|
+
| `MLASTInvalid`(`kind: 'starttag'`) | `MLElement`(`x-invalid`) | `Element`, `HTMLElement` | `1` |
|
|
215
|
+
| `MLASTInvalid`(その他) | `MLText` | `Text` | `3` |
|
|
216
|
+
| `MLASTHTMLAttr` / `MLASTSpreadAttr` | `MLAttr` | `Attr` | `2` |
|
|
217
|
+
|
|
218
|
+
**特殊なノード:**
|
|
219
|
+
|
|
220
|
+
- **`MLBlock`**(`nodeType: 101`)は DOM Standard に相当するものがない markuplint 独自の拡張です。透過的なコンテナとして機能し、子ノードはツリー走査時に親に属するものとして扱われます。
|
|
221
|
+
- **`MLElementCloseTag`** は `createNode()` で生成されません。代わりに `MLElement` が内部で `pairNode` 参照から生成します。ペアとなる要素の付属物としてのみ存在し、DOM ツリー走査の対象ではありません。
|
|
222
|
+
- **`MLASTInvalid`** はリカバリノードです。MLDOM にそのまま保持されることはなく、`kind` フィールドに応じて `MLElement`(タグ名 `x-invalid`)または `MLText` に変換されます。
|
|
223
|
+
|
|
224
|
+
詳細は[ノードリファレンス -- AST から MLDOM へのマッピング](docs/node-reference.ja.md#ast-から-mldom-へのマッピング)を参照してください。
|
|
225
|
+
|
|
226
|
+
## 属性分解モデル
|
|
227
|
+
|
|
228
|
+
`MLASTHTMLAttr` は各属性を完全な位置情報を持つ個別のトークンに分解します:
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
·class="container"
|
|
232
|
+
↑ ↑↑ ↑
|
|
233
|
+
│ ││ └─ endQuote
|
|
234
|
+
│ │└─ value
|
|
235
|
+
│ └─ startQuote
|
|
236
|
+
│ equal
|
|
237
|
+
└─ spacesBeforeName
|
|
238
|
+
name
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
これにより、リントルールは `=` 前後のホワイトスペース、引用符スタイル、属性命名規則を正確なソース位置で検証できます。完全なフィールドドキュメントは[ノードリファレンス](docs/node-reference.ja.md#mlasthtmlattr)を参照してください。
|
|
242
|
+
|
|
243
|
+
## パーサーインターフェース
|
|
244
|
+
|
|
245
|
+
| 型 | 説明 |
|
|
246
|
+
| ------------------------ | -------------------------------------------------------- |
|
|
247
|
+
| `MLParser` | markuplint 互換パーサーのインターフェース |
|
|
248
|
+
| `MLParserModule` | パーサーインスタンスをエクスポートするモジュールラッパー |
|
|
249
|
+
| `MLMarkupLanguageParser` | 非推奨(v5 で削除予定)。代わりに `MLParser` を使用 |
|
|
250
|
+
| `Parse` | 非推奨。パース関数シグネチャの型エイリアス |
|
|
251
|
+
|
|
252
|
+
`MLParser` は `MLASTDocument` を返す `parse(sourceCode, options?)` メソッドを必要とします。オプションフィールドには `endTag`(終了タグ処理戦略)、`booleanish`(ブール属性検出)、`tagNameCaseSensitive`(XHTML/JSX 用)があります。
|
|
253
|
+
|
|
254
|
+
## 設定型
|
|
255
|
+
|
|
256
|
+
| 型 | 説明 |
|
|
257
|
+
| ----------------------------------------- | ---------------------------------------------------------------------- |
|
|
258
|
+
| `MLASTNodeType` | ノード種別の判別共用体タグ |
|
|
259
|
+
| `ElementType` | 要素分類:`'html' \| 'web-component' \| 'authored'` |
|
|
260
|
+
| `EndTagType` | 終了タグ戦略:`'xml' \| 'omittable' \| 'never'` |
|
|
261
|
+
| `Namespace` | 短い名前空間識別子:`'html' \| 'svg' \| 'mml' \| 'xlink'` |
|
|
262
|
+
| `NamespaceURI` | HTML、SVG、MathML、XLink の完全な名前空間 URI |
|
|
263
|
+
| `ParserOptions` | パーサーに渡すオプション(`ignoreFrontMatter`、`authoredElementName`) |
|
|
264
|
+
| `ParserAuthoredElementNameDistinguishing` | 著者定義要素を区別するための設定 |
|
|
265
|
+
| `Walker<Node>` | AST ノードを走査するコールバック |
|
|
266
|
+
|
|
267
|
+
## 外部依存関係
|
|
268
|
+
|
|
269
|
+
なし。このパッケージはランタイム依存関係がゼロです。TypeScript の型定義のみをエクスポートします。
|
|
270
|
+
|
|
271
|
+
## 統合ポイント
|
|
272
|
+
|
|
273
|
+
```mermaid
|
|
274
|
+
flowchart TD
|
|
275
|
+
subgraph upstream ["上流(パーサー)"]
|
|
276
|
+
htmlParser["@markuplint/html-parser"]
|
|
277
|
+
parserUtils["@markuplint/parser-utils"]
|
|
278
|
+
jsxParser["@markuplint/jsx-parser"]
|
|
279
|
+
astroParser["@markuplint/astro-parser"]
|
|
280
|
+
vueParser["@markuplint/vue-parser"]
|
|
281
|
+
svelteParser["@markuplint/svelte-parser"]
|
|
282
|
+
pugParser["@markuplint/pug-parser"]
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
subgraph pkg ["@markuplint/ml-ast"]
|
|
286
|
+
astTypes["型定義"]
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
subgraph downstream ["下流"]
|
|
290
|
+
mlCore["@markuplint/ml-core"]
|
|
291
|
+
mlConfig["@markuplint/ml-config"]
|
|
292
|
+
mlSpec["@markuplint/ml-spec"]
|
|
293
|
+
fileResolver["@markuplint/file-resolver"]
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
upstream -->|"MLParser を実装\nMLASTDocument を生成"| astTypes
|
|
297
|
+
astTypes -->|"MLASTNode 型\nMLParser インターフェース"| downstream
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### 上流
|
|
301
|
+
|
|
302
|
+
すべてのパーサーは `MLParser` インターフェースを実装し、このパッケージで定義された AST ノード型を含む `MLASTDocument` インスタンスを生成します。
|
|
303
|
+
|
|
304
|
+
### 下流
|
|
305
|
+
|
|
306
|
+
- **`@markuplint/ml-core`** は AST ノードを消費し、`createNode()` を通じて DOM ノードにマッピングします。`MLASTElement` が `MLElement` に、`MLASTText` が `MLText` になるなど、主要な統合ポイントです。
|
|
307
|
+
- **`@markuplint/ml-config`** は設定スキーマ定義で AST 型を参照します。
|
|
308
|
+
- **`@markuplint/ml-spec`** は名前空間と要素型の定義を使用します。
|
|
309
|
+
- **`@markuplint/file-resolver`** はパーサー関連の型を参照します。
|
|
310
|
+
|
|
311
|
+
## ドキュメントマップ
|
|
312
|
+
|
|
313
|
+
- [ノードリファレンス](docs/node-reference.ja.md) -- 各 AST ノード型の詳細ドキュメント
|
|
314
|
+
- [メンテナンスガイド](docs/maintenance.ja.md) -- コマンド、レシピ、トラブルシューティング
|
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
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
|
+
+startOffset: number
|
|
57
|
+
+endOffset: number
|
|
58
|
+
+startLine: number
|
|
59
|
+
+endLine: number
|
|
60
|
+
+startCol: number
|
|
61
|
+
+endCol: number
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
class MLASTAbstractNode {
|
|
65
|
+
<<interface>>
|
|
66
|
+
+type: MLASTNodeType
|
|
67
|
+
+nodeName: string
|
|
68
|
+
+parentNode: MLASTParentNode | null
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
class MLASTDoctype {
|
|
72
|
+
<<interface>>
|
|
73
|
+
+type: "doctype"
|
|
74
|
+
+depth: number
|
|
75
|
+
+name: string
|
|
76
|
+
+publicId: string
|
|
77
|
+
+systemId: string
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
class MLASTElement {
|
|
81
|
+
<<interface>>
|
|
82
|
+
+type: "starttag"
|
|
83
|
+
+depth: number
|
|
84
|
+
+namespace: string
|
|
85
|
+
+elementType: ElementType
|
|
86
|
+
+attributes: MLASTAttr[]
|
|
87
|
+
+childNodes: MLASTChildNode[]
|
|
88
|
+
+pairNode: MLASTElementCloseTag | null
|
|
89
|
+
+isGhost: boolean
|
|
90
|
+
+isFragment: boolean
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
class MLASTElementCloseTag {
|
|
94
|
+
<<interface>>
|
|
95
|
+
+type: "endtag"
|
|
96
|
+
+depth: number
|
|
97
|
+
+parentNode: null
|
|
98
|
+
+pairNode: MLASTElement
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
class MLASTComment {
|
|
102
|
+
<<interface>>
|
|
103
|
+
+type: "comment"
|
|
104
|
+
+depth: number
|
|
105
|
+
+isBogus: boolean
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
class MLASTText {
|
|
109
|
+
<<interface>>
|
|
110
|
+
+type: "text"
|
|
111
|
+
+depth: number
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
class MLASTPreprocessorSpecificBlock {
|
|
115
|
+
<<interface>>
|
|
116
|
+
+type: "psblock"
|
|
117
|
+
+conditionalType: ...ConditionalType
|
|
118
|
+
+depth: number
|
|
119
|
+
+childNodes: MLASTChildNode[]
|
|
120
|
+
+isBogus: boolean
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
class MLASTInvalid {
|
|
124
|
+
<<interface>>
|
|
125
|
+
+type: "invalid"
|
|
126
|
+
+depth: number
|
|
127
|
+
+kind: MLASTChildNode type
|
|
128
|
+
+isBogus: true
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
class MLASTHTMLAttr {
|
|
132
|
+
<<interface>>
|
|
133
|
+
+type: "attr"
|
|
134
|
+
+name: MLASTToken
|
|
135
|
+
+value: MLASTToken
|
|
136
|
+
+isDynamicValue: boolean
|
|
137
|
+
+isDirective: boolean
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
class MLASTSpreadAttr {
|
|
141
|
+
<<interface>>
|
|
142
|
+
+type: "spread"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
MLASTToken <|-- MLASTAbstractNode
|
|
146
|
+
MLASTAbstractNode <|-- MLASTDoctype
|
|
147
|
+
MLASTAbstractNode <|-- MLASTElement
|
|
148
|
+
MLASTAbstractNode <|-- MLASTElementCloseTag
|
|
149
|
+
MLASTAbstractNode <|-- MLASTComment
|
|
150
|
+
MLASTAbstractNode <|-- MLASTText
|
|
151
|
+
MLASTAbstractNode <|-- MLASTPreprocessorSpecificBlock
|
|
152
|
+
MLASTAbstractNode <|-- MLASTInvalid
|
|
153
|
+
MLASTToken <|-- MLASTHTMLAttr
|
|
154
|
+
MLASTToken <|-- MLASTSpreadAttr
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Union Types
|
|
158
|
+
|
|
159
|
+
```mermaid
|
|
160
|
+
flowchart TD
|
|
161
|
+
subgraph MLASTNode ["MLASTNode (all node types)"]
|
|
162
|
+
subgraph MLASTNodeTreeItem ["MLASTNodeTreeItem"]
|
|
163
|
+
MLASTDoctype["MLASTDoctype"]
|
|
164
|
+
subgraph MLASTChildNode ["MLASTChildNode"]
|
|
165
|
+
subgraph MLASTTag ["MLASTTag"]
|
|
166
|
+
MLASTElement["MLASTElement"]
|
|
167
|
+
MLASTElementCloseTag["MLASTElementCloseTag"]
|
|
168
|
+
end
|
|
169
|
+
MLASTText["MLASTText"]
|
|
170
|
+
MLASTComment["MLASTComment"]
|
|
171
|
+
MLASTPreprocessorSpecificBlock["MLASTPreprocessorSpecificBlock"]
|
|
172
|
+
MLASTInvalid["MLASTInvalid"]
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
subgraph MLASTAttr ["MLASTAttr"]
|
|
176
|
+
MLASTHTMLAttr["MLASTHTMLAttr"]
|
|
177
|
+
MLASTSpreadAttr["MLASTSpreadAttr"]
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
style MLASTElement fill:#e1f5fe
|
|
182
|
+
style MLASTPreprocessorSpecificBlock fill:#e1f5fe
|
|
183
|
+
|
|
184
|
+
note1["MLASTParentNode = MLASTElement | MLASTPreprocessorSpecificBlock\n(highlighted in blue)"]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Node Types at a Glance
|
|
188
|
+
|
|
189
|
+
| Type | `type` Value | Example | Description |
|
|
190
|
+
| -------------------------------- | ------------ | ------------------- | -------------------------------------------------------- |
|
|
191
|
+
| `MLASTDoctype` | `'doctype'` | `<!DOCTYPE html>` | DOCTYPE declaration |
|
|
192
|
+
| `MLASTElement` | `'starttag'` | `<div class="foo">` | Opening element tag with attributes, children, namespace |
|
|
193
|
+
| `MLASTElementCloseTag` | `'endtag'` | `</div>` | Closing element tag, paired with its opening tag |
|
|
194
|
+
| `MLASTComment` | `'comment'` | `<!-- ... -->` | HTML comment, with bogus flag |
|
|
195
|
+
| `MLASTText` | `'text'` | text content | Character data between elements |
|
|
196
|
+
| `MLASTPreprocessorSpecificBlock` | `'psblock'` | `{#if}`, `<% %>` | Template engine constructs |
|
|
197
|
+
| `MLASTInvalid` | `'invalid'` | unparsable markup | Invalid node with intended kind hint |
|
|
198
|
+
| `MLASTHTMLAttr` | `'attr'` | `class="foo"` | Fully decomposed HTML attribute |
|
|
199
|
+
| `MLASTSpreadAttr` | `'spread'` | `{...props}` | JSX spread attribute |
|
|
200
|
+
|
|
201
|
+
See [Node Reference](docs/node-reference.md) for detailed documentation of each type.
|
|
202
|
+
|
|
203
|
+
## AST to MLDOM Mapping
|
|
204
|
+
|
|
205
|
+
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.
|
|
206
|
+
|
|
207
|
+
| AST Type (`ml-ast`) | MLDOM Class (`ml-core`) | DOM Interface | `nodeType` |
|
|
208
|
+
| ----------------------------------- | ------------------------- | ------------------------ | ---------- |
|
|
209
|
+
| `MLASTDoctype` | `MLDocumentType` | `DocumentType` | `10` |
|
|
210
|
+
| `MLASTElement` | `MLElement` | `Element`, `HTMLElement` | `1` |
|
|
211
|
+
| `MLASTComment` | `MLComment` | `Comment` | `8` |
|
|
212
|
+
| `MLASTText` | `MLText` | `Text` | `3` |
|
|
213
|
+
| `MLASTPreprocessorSpecificBlock` | `MLBlock` | _(markuplint-specific)_ | `101` |
|
|
214
|
+
| `MLASTInvalid` (`kind: 'starttag'`) | `MLElement` (`x-invalid`) | `Element`, `HTMLElement` | `1` |
|
|
215
|
+
| `MLASTInvalid` (other) | `MLText` | `Text` | `3` |
|
|
216
|
+
| `MLASTHTMLAttr` / `MLASTSpreadAttr` | `MLAttr` | `Attr` | `2` |
|
|
217
|
+
|
|
218
|
+
**Special nodes:**
|
|
219
|
+
|
|
220
|
+
- **`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.
|
|
221
|
+
- **`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.
|
|
222
|
+
- **`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.
|
|
223
|
+
|
|
224
|
+
See [Node Reference -- AST to MLDOM Mapping](docs/node-reference.md#ast-to-mldom-mapping) for details.
|
|
225
|
+
|
|
226
|
+
## Attribute Decomposition Model
|
|
227
|
+
|
|
228
|
+
`MLASTHTMLAttr` decomposes each attribute into individual tokens with full positional information:
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
·class="container"
|
|
232
|
+
↑ ↑↑ ↑
|
|
233
|
+
│ ││ └─ endQuote
|
|
234
|
+
│ │└─ value
|
|
235
|
+
│ └─ startQuote
|
|
236
|
+
│ equal
|
|
237
|
+
└─ spacesBeforeName
|
|
238
|
+
name
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
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.
|
|
242
|
+
|
|
243
|
+
## Parser Interface
|
|
244
|
+
|
|
245
|
+
| Type | Description |
|
|
246
|
+
| ------------------------ | ------------------------------------------------------ |
|
|
247
|
+
| `MLParser` | Interface for a markuplint-compatible parser |
|
|
248
|
+
| `MLParserModule` | Module wrapper that exports a parser instance |
|
|
249
|
+
| `MLMarkupLanguageParser` | Deprecated (v5 removal). Use `MLParser` instead |
|
|
250
|
+
| `Parse` | Deprecated type alias for the parse function signature |
|
|
251
|
+
|
|
252
|
+
`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).
|
|
253
|
+
|
|
254
|
+
## Configuration Types
|
|
255
|
+
|
|
256
|
+
| Type | Description |
|
|
257
|
+
| ----------------------------------------- | ---------------------------------------------------------------------- |
|
|
258
|
+
| `MLASTNodeType` | Discriminant union tag for node kinds |
|
|
259
|
+
| `ElementType` | Element classification: `'html' \| 'web-component' \| 'authored'` |
|
|
260
|
+
| `EndTagType` | End tag strategy: `'xml' \| 'omittable' \| 'never'` |
|
|
261
|
+
| `Namespace` | Short namespace identifiers: `'html' \| 'svg' \| 'mml' \| 'xlink'` |
|
|
262
|
+
| `NamespaceURI` | Full namespace URIs for HTML, SVG, MathML, XLink |
|
|
263
|
+
| `ParserOptions` | Options passed to parsers (`ignoreFrontMatter`, `authoredElementName`) |
|
|
264
|
+
| `ParserAuthoredElementNameDistinguishing` | Configuration for distinguishing authored elements |
|
|
265
|
+
| `Walker<Node>` | Callback for walking AST nodes |
|
|
266
|
+
|
|
267
|
+
## External Dependencies
|
|
268
|
+
|
|
269
|
+
None. This package has zero runtime dependencies. It exports only TypeScript type definitions.
|
|
270
|
+
|
|
271
|
+
## Integration Points
|
|
272
|
+
|
|
273
|
+
```mermaid
|
|
274
|
+
flowchart TD
|
|
275
|
+
subgraph upstream ["Upstream (Parsers)"]
|
|
276
|
+
htmlParser["@markuplint/html-parser"]
|
|
277
|
+
parserUtils["@markuplint/parser-utils"]
|
|
278
|
+
jsxParser["@markuplint/jsx-parser"]
|
|
279
|
+
astroParser["@markuplint/astro-parser"]
|
|
280
|
+
vueParser["@markuplint/vue-parser"]
|
|
281
|
+
svelteParser["@markuplint/svelte-parser"]
|
|
282
|
+
pugParser["@markuplint/pug-parser"]
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
subgraph pkg ["@markuplint/ml-ast"]
|
|
286
|
+
astTypes["Type Definitions"]
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
subgraph downstream ["Downstream"]
|
|
290
|
+
mlCore["@markuplint/ml-core"]
|
|
291
|
+
mlConfig["@markuplint/ml-config"]
|
|
292
|
+
mlSpec["@markuplint/ml-spec"]
|
|
293
|
+
fileResolver["@markuplint/file-resolver"]
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
upstream -->|"implement MLParser\nproduce MLASTDocument"| astTypes
|
|
297
|
+
astTypes -->|"MLASTNode types\nMLParser interface"| downstream
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Upstream
|
|
301
|
+
|
|
302
|
+
All parsers implement the `MLParser` interface and produce `MLASTDocument` instances containing the AST node types defined in this package.
|
|
303
|
+
|
|
304
|
+
### Downstream
|
|
305
|
+
|
|
306
|
+
- **`@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.
|
|
307
|
+
- **`@markuplint/ml-config`** references AST types in configuration schema definitions.
|
|
308
|
+
- **`@markuplint/ml-spec`** uses namespace and element type definitions.
|
|
309
|
+
- **`@markuplint/file-resolver`** references parser-related types.
|
|
310
|
+
|
|
311
|
+
## Documentation Map
|
|
312
|
+
|
|
313
|
+
- [Node Reference](docs/node-reference.md) -- Detailed documentation of each AST node type
|
|
314
|
+
- [Maintenance Guide](docs/maintenance.md) -- Commands, recipes, and troubleshooting
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
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
|
+
## [4.4.11](https://github.com/markuplint/markuplint/compare/@markuplint/ml-ast@4.4.10...@markuplint/ml-ast@4.4.11) (2026-02-10)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @markuplint/ml-ast
|
|
9
|
+
|
|
6
10
|
## [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
11
|
|
|
8
12
|
### 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
|