@markuplint/ml-ast 5.0.0-rc.2 → 5.0.0-rc.5
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/CHANGELOG.md +15 -0
- package/README.md +0 -6
- package/lib/index.d.ts +16 -0
- package/lib/index.js +16 -0
- package/lib/types.d.ts +145 -8
- package/package.json +3 -3
- package/ARCHITECTURE.ja.md +0 -309
- package/ARCHITECTURE.md +0 -309
- package/SKILL.md +0 -123
- package/docs/maintenance.ja.md +0 -213
- package/docs/maintenance.md +0 -214
- package/docs/node-reference.ja.md +0 -487
- package/docs/node-reference.md +0 -487
package/ARCHITECTURE.md
DELETED
|
@@ -1,309 +0,0 @@
|
|
|
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
|
-
+parentNodeUuid: string | 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
|
-
+pairNodeUuid: string | null
|
|
87
|
-
+isGhost: boolean
|
|
88
|
-
+isFragment: boolean
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
class MLASTElementCloseTag {
|
|
92
|
-
<<interface>>
|
|
93
|
-
+type: "endtag"
|
|
94
|
-
+depth: number
|
|
95
|
-
+pairNodeUuid: string | null
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
class MLASTComment {
|
|
99
|
-
<<interface>>
|
|
100
|
-
+type: "comment"
|
|
101
|
-
+depth: number
|
|
102
|
-
+isBogus: boolean
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
class MLASTText {
|
|
106
|
-
<<interface>>
|
|
107
|
-
+type: "text"
|
|
108
|
-
+depth: number
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
class MLASTPreprocessorSpecificBlock {
|
|
112
|
-
<<interface>>
|
|
113
|
-
+type: "psblock"
|
|
114
|
-
+blockBehavior: MLASTBlockBehavior | null
|
|
115
|
-
+depth: number
|
|
116
|
-
+childNodes: MLASTChildNode[]
|
|
117
|
-
+isBogus: boolean
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
class MLASTInvalid {
|
|
121
|
-
<<interface>>
|
|
122
|
-
+type: "invalid"
|
|
123
|
-
+depth: number
|
|
124
|
-
+kind: MLASTChildNode type
|
|
125
|
-
+isBogus: true
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
class MLASTHTMLAttr {
|
|
129
|
-
<<interface>>
|
|
130
|
-
+type: "attr"
|
|
131
|
-
+name: MLASTToken
|
|
132
|
-
+value: MLASTToken
|
|
133
|
-
+isDynamicValue: boolean
|
|
134
|
-
+isDirective: boolean
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
class MLASTSpreadAttr {
|
|
138
|
-
<<interface>>
|
|
139
|
-
+type: "spread"
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
MLASTToken <|-- MLASTAbstractNode
|
|
143
|
-
MLASTAbstractNode <|-- MLASTDoctype
|
|
144
|
-
MLASTAbstractNode <|-- MLASTElement
|
|
145
|
-
MLASTAbstractNode <|-- MLASTElementCloseTag
|
|
146
|
-
MLASTAbstractNode <|-- MLASTComment
|
|
147
|
-
MLASTAbstractNode <|-- MLASTText
|
|
148
|
-
MLASTAbstractNode <|-- MLASTPreprocessorSpecificBlock
|
|
149
|
-
MLASTAbstractNode <|-- MLASTInvalid
|
|
150
|
-
MLASTToken <|-- MLASTHTMLAttr
|
|
151
|
-
MLASTToken <|-- MLASTSpreadAttr
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Union Types
|
|
155
|
-
|
|
156
|
-
```mermaid
|
|
157
|
-
flowchart TD
|
|
158
|
-
subgraph MLASTNode ["MLASTNode (all node types)"]
|
|
159
|
-
subgraph MLASTNodeTreeItem ["MLASTNodeTreeItem"]
|
|
160
|
-
MLASTDoctype["MLASTDoctype"]
|
|
161
|
-
subgraph MLASTChildNode ["MLASTChildNode"]
|
|
162
|
-
subgraph MLASTTag ["MLASTTag"]
|
|
163
|
-
MLASTElement["MLASTElement"]
|
|
164
|
-
MLASTElementCloseTag["MLASTElementCloseTag"]
|
|
165
|
-
end
|
|
166
|
-
MLASTText["MLASTText"]
|
|
167
|
-
MLASTComment["MLASTComment"]
|
|
168
|
-
MLASTPreprocessorSpecificBlock["MLASTPreprocessorSpecificBlock"]
|
|
169
|
-
MLASTInvalid["MLASTInvalid"]
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
subgraph MLASTAttr ["MLASTAttr"]
|
|
173
|
-
MLASTHTMLAttr["MLASTHTMLAttr"]
|
|
174
|
-
MLASTSpreadAttr["MLASTSpreadAttr"]
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
style MLASTElement fill:#e1f5fe
|
|
179
|
-
style MLASTPreprocessorSpecificBlock fill:#e1f5fe
|
|
180
|
-
|
|
181
|
-
note1["MLASTParentNode = MLASTElement | MLASTPreprocessorSpecificBlock\n(highlighted in blue)"]
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## Node Types at a Glance
|
|
185
|
-
|
|
186
|
-
| Type | `type` Value | Example | Description |
|
|
187
|
-
| -------------------------------- | ------------ | ------------------- | -------------------------------------------------------- |
|
|
188
|
-
| `MLASTDoctype` | `'doctype'` | `<!DOCTYPE html>` | DOCTYPE declaration |
|
|
189
|
-
| `MLASTElement` | `'starttag'` | `<div class="foo">` | Opening element tag with attributes, children, namespace |
|
|
190
|
-
| `MLASTElementCloseTag` | `'endtag'` | `</div>` | Closing element tag, paired with its opening tag |
|
|
191
|
-
| `MLASTComment` | `'comment'` | `<!-- ... -->` | HTML comment, with bogus flag |
|
|
192
|
-
| `MLASTText` | `'text'` | text content | Character data between elements |
|
|
193
|
-
| `MLASTPreprocessorSpecificBlock` | `'psblock'` | `{#if}`, `<% %>` | Template engine constructs |
|
|
194
|
-
| `MLASTInvalid` | `'invalid'` | unparsable markup | Invalid node with intended kind hint |
|
|
195
|
-
| `MLASTHTMLAttr` | `'attr'` | `class="foo"` | Fully decomposed HTML attribute |
|
|
196
|
-
| `MLASTSpreadAttr` | `'spread'` | `{...props}` | JSX spread attribute |
|
|
197
|
-
|
|
198
|
-
See [Node Reference](docs/node-reference.md) for detailed documentation of each type.
|
|
199
|
-
|
|
200
|
-
## AST to MLDOM Mapping
|
|
201
|
-
|
|
202
|
-
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.
|
|
203
|
-
|
|
204
|
-
| AST Type (`ml-ast`) | MLDOM Class (`ml-core`) | DOM Interface | `nodeType` |
|
|
205
|
-
| ----------------------------------- | ------------------------- | ------------------------ | ---------- |
|
|
206
|
-
| `MLASTDoctype` | `MLDocumentType` | `DocumentType` | `10` |
|
|
207
|
-
| `MLASTElement` | `MLElement` | `Element`, `HTMLElement` | `1` |
|
|
208
|
-
| `MLASTComment` | `MLComment` | `Comment` | `8` |
|
|
209
|
-
| `MLASTText` | `MLText` | `Text` | `3` |
|
|
210
|
-
| `MLASTPreprocessorSpecificBlock` | `MLBlock` | _(markuplint-specific)_ | `101` |
|
|
211
|
-
| `MLASTInvalid` (`kind: 'starttag'`) | `MLElement` (`x-invalid`) | `Element`, `HTMLElement` | `1` |
|
|
212
|
-
| `MLASTInvalid` (other) | `MLText` | `Text` | `3` |
|
|
213
|
-
| `MLASTHTMLAttr` / `MLASTSpreadAttr` | `MLAttr` | `Attr` | `2` |
|
|
214
|
-
|
|
215
|
-
**Special nodes:**
|
|
216
|
-
|
|
217
|
-
- **`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.
|
|
218
|
-
- **`MLElementCloseTag`** is not created by `createNode()`. Instead, `MLElement` internally resolves the `pairNodeUuid` to look up the closing tag's AST node and creates an `MLElementCloseTag` from it. It exists only as a satellite of its paired element and is not part of the DOM tree traversal.
|
|
219
|
-
- **`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.
|
|
220
|
-
|
|
221
|
-
See [Node Reference -- AST to MLDOM Mapping](docs/node-reference.md#ast-to-mldom-mapping) for details.
|
|
222
|
-
|
|
223
|
-
## Attribute Decomposition Model
|
|
224
|
-
|
|
225
|
-
`MLASTHTMLAttr` decomposes each attribute into individual tokens with full positional information:
|
|
226
|
-
|
|
227
|
-
```
|
|
228
|
-
·class="container"
|
|
229
|
-
↑ ↑↑ ↑
|
|
230
|
-
│ ││ └─ endQuote
|
|
231
|
-
│ │└─ value
|
|
232
|
-
│ └─ startQuote
|
|
233
|
-
│ equal
|
|
234
|
-
└─ spacesBeforeName
|
|
235
|
-
name
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
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.
|
|
239
|
-
|
|
240
|
-
## Parser Interface
|
|
241
|
-
|
|
242
|
-
| Type | Description |
|
|
243
|
-
| ---------------- | --------------------------------------------- |
|
|
244
|
-
| `MLParser` | Interface for a markuplint-compatible parser |
|
|
245
|
-
| `MLParserModule` | Module wrapper that exports a parser instance |
|
|
246
|
-
|
|
247
|
-
`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).
|
|
248
|
-
|
|
249
|
-
## Configuration Types
|
|
250
|
-
|
|
251
|
-
| Type | Description |
|
|
252
|
-
| ----------------------------------------- | ---------------------------------------------------------------------- |
|
|
253
|
-
| `MLASTNodeType` | Discriminant union tag for node kinds |
|
|
254
|
-
| `ElementType` | Element classification: `'html' \| 'web-component' \| 'authored'` |
|
|
255
|
-
| `EndTagType` | End tag strategy: `'xml' \| 'omittable' \| 'never'` |
|
|
256
|
-
| `Namespace` | Short namespace identifiers: `'html' \| 'svg' \| 'mml' \| 'xlink'` |
|
|
257
|
-
| `NamespaceURI` | Full namespace URIs for HTML, SVG, MathML, XLink |
|
|
258
|
-
| `ParserOptions` | Options passed to parsers (`ignoreFrontMatter`, `authoredElementName`) |
|
|
259
|
-
| `ParserAuthoredElementNameDistinguishing` | Configuration for distinguishing authored elements |
|
|
260
|
-
| `Walker<Node>` | Callback for walking AST nodes |
|
|
261
|
-
|
|
262
|
-
## External Dependencies
|
|
263
|
-
|
|
264
|
-
None. This package has zero runtime dependencies. It exports only TypeScript type definitions.
|
|
265
|
-
|
|
266
|
-
## Integration Points
|
|
267
|
-
|
|
268
|
-
```mermaid
|
|
269
|
-
flowchart TD
|
|
270
|
-
subgraph upstream ["Upstream (Parsers)"]
|
|
271
|
-
htmlParser["@markuplint/html-parser"]
|
|
272
|
-
parserUtils["@markuplint/parser-utils"]
|
|
273
|
-
jsxParser["@markuplint/jsx-parser"]
|
|
274
|
-
astroParser["@markuplint/astro-parser"]
|
|
275
|
-
vueParser["@markuplint/vue-parser"]
|
|
276
|
-
svelteParser["@markuplint/svelte-parser"]
|
|
277
|
-
pugParser["@markuplint/pug-parser"]
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
subgraph pkg ["@markuplint/ml-ast"]
|
|
281
|
-
astTypes["Type Definitions"]
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
subgraph downstream ["Downstream"]
|
|
285
|
-
mlCore["@markuplint/ml-core"]
|
|
286
|
-
mlConfig["@markuplint/ml-config"]
|
|
287
|
-
mlSpec["@markuplint/ml-spec"]
|
|
288
|
-
fileResolver["@markuplint/file-resolver"]
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
upstream -->|"implement MLParser\nproduce MLASTDocument"| astTypes
|
|
292
|
-
astTypes -->|"MLASTNode types\nMLParser interface"| downstream
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
### Upstream
|
|
296
|
-
|
|
297
|
-
All parsers implement the `MLParser` interface and produce `MLASTDocument` instances containing the AST node types defined in this package.
|
|
298
|
-
|
|
299
|
-
### Downstream
|
|
300
|
-
|
|
301
|
-
- **`@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.
|
|
302
|
-
- **`@markuplint/ml-config`** references AST types in configuration schema definitions.
|
|
303
|
-
- **`@markuplint/ml-spec`** uses namespace and element type definitions.
|
|
304
|
-
- **`@markuplint/file-resolver`** references parser-related types.
|
|
305
|
-
|
|
306
|
-
## Documentation Map
|
|
307
|
-
|
|
308
|
-
- [Node Reference](docs/node-reference.md) -- Detailed documentation of each AST node type
|
|
309
|
-
- [Maintenance Guide](docs/maintenance.md) -- Commands, recipes, and troubleshooting
|
package/SKILL.md
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Perform maintenance tasks for @markuplint/ml-ast
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# ml-ast-maintenance
|
|
6
|
-
|
|
7
|
-
Perform maintenance tasks for `@markuplint/ml-ast`: add AST node types,
|
|
8
|
-
add fields to existing nodes, add conditional type values, and update the parser interface.
|
|
9
|
-
|
|
10
|
-
## Input
|
|
11
|
-
|
|
12
|
-
`$ARGUMENTS` specifies the task. Supported tasks:
|
|
13
|
-
|
|
14
|
-
| Task | Description |
|
|
15
|
-
| ------------------------------ | ---------------------------------------------- |
|
|
16
|
-
| `add-node-type <name>` | Add a new AST node type |
|
|
17
|
-
| `add-field <node> <field>` | Add a field to an existing node type |
|
|
18
|
-
| `add-conditional-type <value>` | Add a conditional type value for psblock nodes |
|
|
19
|
-
| `update-parser-interface` | Modify the MLParser interface |
|
|
20
|
-
|
|
21
|
-
If omitted, defaults to `add-node-type`.
|
|
22
|
-
|
|
23
|
-
## Reference
|
|
24
|
-
|
|
25
|
-
Before executing any task, read `docs/maintenance.md` (or `docs/maintenance.ja.md`)
|
|
26
|
-
for the full guide. The recipes there are the source of truth for procedures.
|
|
27
|
-
|
|
28
|
-
Also read:
|
|
29
|
-
|
|
30
|
-
- `docs/node-reference.md` -- Detailed documentation of each AST node type
|
|
31
|
-
- `ARCHITECTURE.md` -- Package overview, type hierarchy, and integration points
|
|
32
|
-
|
|
33
|
-
## Task: add-node-type
|
|
34
|
-
|
|
35
|
-
Add a new AST node type. Follow recipe #1 in `docs/maintenance.md`.
|
|
36
|
-
|
|
37
|
-
### Step 1: Define the type
|
|
38
|
-
|
|
39
|
-
1. Read `src/types.ts` to understand the existing type hierarchy
|
|
40
|
-
2. Add the type value to `MLASTNodeType`
|
|
41
|
-
3. Define the interface extending `MLASTAbstractNode`
|
|
42
|
-
4. Add to relevant union types (`MLASTNode`, `MLASTChildNode`, etc.)
|
|
43
|
-
|
|
44
|
-
### Step 2: Update downstream
|
|
45
|
-
|
|
46
|
-
1. Update `ml-core`'s `createNode()` in `packages/@markuplint/ml-core/src/ml-dom/helper/create-node.ts`
|
|
47
|
-
2. Add a `case` for the new type value in the `switch` statement
|
|
48
|
-
3. Create or reuse an appropriate DOM node class
|
|
49
|
-
|
|
50
|
-
### Step 3: Build and verify
|
|
51
|
-
|
|
52
|
-
1. Build: `yarn build --scope @markuplint/ml-ast`
|
|
53
|
-
2. Build: `yarn build --scope @markuplint/ml-core`
|
|
54
|
-
3. Check the downstream impact checklist in `docs/maintenance.md`
|
|
55
|
-
|
|
56
|
-
## Task: add-field
|
|
57
|
-
|
|
58
|
-
Add a field to an existing node type. Follow recipe #2 in `docs/maintenance.md`.
|
|
59
|
-
|
|
60
|
-
### Step 1: Add the field
|
|
61
|
-
|
|
62
|
-
1. Read `src/types.ts` and find the target interface
|
|
63
|
-
2. Add the field (prefer optional `?` for backward compatibility)
|
|
64
|
-
3. Add JSDoc documentation for the new field
|
|
65
|
-
|
|
66
|
-
### Step 2: Update consumers
|
|
67
|
-
|
|
68
|
-
1. Update parsers that should populate the new field
|
|
69
|
-
2. Update `ml-core` if the field affects DOM node creation
|
|
70
|
-
|
|
71
|
-
### Step 3: Build and verify
|
|
72
|
-
|
|
73
|
-
1. Build: `yarn build --scope @markuplint/ml-ast`
|
|
74
|
-
2. Build affected packages
|
|
75
|
-
3. Check the downstream impact checklist in `docs/maintenance.md`
|
|
76
|
-
|
|
77
|
-
## Task: add-conditional-type
|
|
78
|
-
|
|
79
|
-
Add a conditional type value for preprocessor-specific blocks. Follow recipe #4 in `docs/maintenance.md`.
|
|
80
|
-
|
|
81
|
-
### Step 1: Add the value
|
|
82
|
-
|
|
83
|
-
1. Read `src/types.ts` and find `MLASTPreprocessorSpecificBlockConditionalType`
|
|
84
|
-
2. Add the new value to the union type
|
|
85
|
-
3. Document the value's semantic meaning in the JSDoc comment
|
|
86
|
-
|
|
87
|
-
### Step 2: Update parsers
|
|
88
|
-
|
|
89
|
-
1. Update the parser that produces blocks with this conditional type
|
|
90
|
-
2. Verify the value follows the naming convention (`category:variant`, e.g., `if:elseif`)
|
|
91
|
-
|
|
92
|
-
### Step 3: Build and verify
|
|
93
|
-
|
|
94
|
-
1. Build: `yarn build --scope @markuplint/ml-ast`
|
|
95
|
-
2. Build the affected parser package
|
|
96
|
-
|
|
97
|
-
## Task: update-parser-interface
|
|
98
|
-
|
|
99
|
-
Modify the `MLParser` interface. Follow recipe #5 in `docs/maintenance.md`.
|
|
100
|
-
|
|
101
|
-
### Step 1: Make changes
|
|
102
|
-
|
|
103
|
-
1. Read `src/types.ts` and find `MLParser`
|
|
104
|
-
2. Make changes (prefer adding optional fields for backward compatibility)
|
|
105
|
-
|
|
106
|
-
### Step 2: Update all parsers
|
|
107
|
-
|
|
108
|
-
1. Update all parser implementations (see the list in `docs/maintenance.md` recipe #5)
|
|
109
|
-
2. Update `@markuplint/parser-utils` if it provides shared implementation
|
|
110
|
-
|
|
111
|
-
### Step 3: Build and verify
|
|
112
|
-
|
|
113
|
-
1. Build all packages: `yarn build`
|
|
114
|
-
2. Run all tests: `yarn test`
|
|
115
|
-
|
|
116
|
-
## Rules
|
|
117
|
-
|
|
118
|
-
1. **All node types extend `MLASTAbstractNode`** (except attributes which extend `MLASTToken`).
|
|
119
|
-
2. **Use `readonly` for all interface fields.** The AST is immutable after parsing.
|
|
120
|
-
3. **Prefer optional fields** when adding to existing interfaces for backward compatibility.
|
|
121
|
-
4. **Always update `createNode()` in `ml-core`** when adding new node types.
|
|
122
|
-
5. **Follow the discriminated union pattern.** Every node must have a unique `type` literal value.
|
|
123
|
-
6. **Add JSDoc comments** to all new exported types and fields.
|
package/docs/maintenance.ja.md
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
# メンテナンスガイド
|
|
2
|
-
|
|
3
|
-
`@markuplint/ml-ast` の実践的な操作・メンテナンスガイドです。
|
|
4
|
-
|
|
5
|
-
## コマンド
|
|
6
|
-
|
|
7
|
-
| コマンド | 説明 |
|
|
8
|
-
| --------------------------------------------- | --------------------------------- |
|
|
9
|
-
| `yarn build --scope @markuplint/ml-ast` | TypeScript を `lib/` にコンパイル |
|
|
10
|
-
| `yarn workspace @markuplint/ml-ast run dev` | ウォッチモードコンパイル |
|
|
11
|
-
| `yarn workspace @markuplint/ml-ast run clean` | コンパイル出力をクリーン |
|
|
12
|
-
|
|
13
|
-
## テスト
|
|
14
|
-
|
|
15
|
-
このパッケージには**テストファイルがありません**。純粋な型定義パッケージのため、正当性はビルド時に TypeScript コンパイラで検証されます。統合テストはこれらの型を消費する下流パッケージで実施されます。
|
|
16
|
-
|
|
17
|
-
型の正当性を検証するには:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
yarn build --scope @markuplint/ml-ast
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## 一般的なレシピ
|
|
24
|
-
|
|
25
|
-
### 1. 新しいノード型の追加
|
|
26
|
-
|
|
27
|
-
新しい AST ノード型(例:仮想的な `MLASTDirective`)を追加する場合:
|
|
28
|
-
|
|
29
|
-
1. **`MLASTNodeType` に型の値を追加**(`src/types.ts`):
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
export type MLASTNodeType =
|
|
33
|
-
| 'doctype'
|
|
34
|
-
| 'starttag'
|
|
35
|
-
// ... 既存の値
|
|
36
|
-
| 'directive'; // ここに追加
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
2. **`MLASTAbstractNode` を継承するインターフェースを定義**:
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
export interface MLASTDirective extends MLASTAbstractNode {
|
|
43
|
-
readonly type: 'directive';
|
|
44
|
-
readonly depth: number;
|
|
45
|
-
// 型固有のフィールドを追加
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
3. **関連する共用体型に追加**:
|
|
50
|
-
- `MLASTNode` -- 常にこの共用体に追加
|
|
51
|
-
- `MLASTChildNode` -- 要素の子になれる場合
|
|
52
|
-
- `MLASTNodeTreeItem` -- `nodeList` のトップレベルに出現できる場合
|
|
53
|
-
- `MLASTParentNode` -- 子ノードを含むことができる場合
|
|
54
|
-
|
|
55
|
-
4. **`ml-core` の `createNode()` を更新**(`packages/@markuplint/ml-core/src/ml-dom/helper/create-node.ts`):
|
|
56
|
-
- `switch` 文に新しい type 値の `case` を追加
|
|
57
|
-
- 適切な DOM ノードクラスを作成または再利用
|
|
58
|
-
|
|
59
|
-
5. **このノード型を生成するパーサーを更新**
|
|
60
|
-
|
|
61
|
-
6. **ビルドして検証**:
|
|
62
|
-
```bash
|
|
63
|
-
yarn build --scope @markuplint/ml-ast
|
|
64
|
-
yarn build --scope @markuplint/ml-core
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### 2. 既存ノード型へのフィールド追加
|
|
68
|
-
|
|
69
|
-
既存のノードインターフェースに新しいフィールドを追加する場合:
|
|
70
|
-
|
|
71
|
-
1. **`src/types.ts` のインターフェースにフィールドを追加**:
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
export interface MLASTElement extends MLASTAbstractNode {
|
|
75
|
-
// ... 既存のフィールド
|
|
76
|
-
readonly newField: string; // 必須フィールド
|
|
77
|
-
readonly optionalField?: boolean; // オプションフィールド(後方互換性のため推奨)
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
2. **後方互換性のためオプションフィールド**(`?`)を推奨 -- フィールドがなくても既存のパーサーが壊れません。
|
|
82
|
-
|
|
83
|
-
3. **新しいフィールドを設定するパーサーを更新**
|
|
84
|
-
|
|
85
|
-
4. **フィールドが DOM ノードの作成や動作に影響する場合は `ml-core` を更新**
|
|
86
|
-
|
|
87
|
-
5. **全チェーンをビルド**:
|
|
88
|
-
```bash
|
|
89
|
-
yarn build --scope @markuplint/ml-ast
|
|
90
|
-
yarn build --scope @markuplint/ml-core
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### 3. 新しい属性バリアントの追加
|
|
94
|
-
|
|
95
|
-
`MLASTHTMLAttr` と `MLASTSpreadAttr` に加えて新しい属性型を追加する場合:
|
|
96
|
-
|
|
97
|
-
1. **`MLASTNodeType` に型の値を追加**(まだない場合)
|
|
98
|
-
|
|
99
|
-
2. **`MLASTToken` を継承するインターフェースを定義**:
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
export interface MLASTNewAttr extends MLASTToken {
|
|
103
|
-
readonly type: 'newattr';
|
|
104
|
-
readonly nodeName: string;
|
|
105
|
-
// 属性固有のフィールドを追加
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
3. **`MLASTAttr` 共用体に追加**:
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
export type MLASTAttr = MLASTHTMLAttr | MLASTSpreadAttr | MLASTNewAttr;
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
4. **属性型で switch する下流の消費者を更新**
|
|
116
|
-
|
|
117
|
-
5. **ビルドして検証**
|
|
118
|
-
|
|
119
|
-
### 4. `MLASTBlockBehaviorType` の値追加
|
|
120
|
-
|
|
121
|
-
プリプロセッサブロックの新しいブロック動作種別を追加する場合:
|
|
122
|
-
|
|
123
|
-
1. **`src/types.ts` の `MLASTBlockBehaviorType` に値を追加**:
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
export type MLASTBlockBehaviorType =
|
|
127
|
-
| 'if'
|
|
128
|
-
| 'if:elseif'
|
|
129
|
-
// ... 既存の値
|
|
130
|
-
| 'newvalue'; // ここに追加
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
2. **この動作種別で `blockBehavior` を設定するパーサーを更新**
|
|
134
|
-
|
|
135
|
-
3. **新しい値が DOM 作成時に特別な処理を必要とする場合は `ml-core` を更新**
|
|
136
|
-
|
|
137
|
-
4. **ビルドして検証**:
|
|
138
|
-
```bash
|
|
139
|
-
yarn build --scope @markuplint/ml-ast
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### 5. `MLParser` インターフェースの変更
|
|
143
|
-
|
|
144
|
-
パーサーインターフェースを変更する場合:
|
|
145
|
-
|
|
146
|
-
1. **`src/types.ts` の `MLParser` を変更**
|
|
147
|
-
|
|
148
|
-
2. **後方互換性を考慮**:
|
|
149
|
-
- オプションフィールドの追加は安全
|
|
150
|
-
- 必須フィールドの追加やシグネチャの変更は破壊的変更
|
|
151
|
-
|
|
152
|
-
3. **すべてのパーサー実装を更新**:
|
|
153
|
-
- `@markuplint/html-parser`
|
|
154
|
-
- `@markuplint/jsx-parser`
|
|
155
|
-
- `@markuplint/vue-parser`
|
|
156
|
-
- `@markuplint/svelte-parser`
|
|
157
|
-
- `@markuplint/astro-parser`
|
|
158
|
-
- `@markuplint/pug-parser`
|
|
159
|
-
- `@markuplint/parser-utils`
|
|
160
|
-
|
|
161
|
-
4. **影響を受けるすべてのパッケージをビルド**:
|
|
162
|
-
```bash
|
|
163
|
-
yarn build
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## 下流影響チェックリスト
|
|
167
|
-
|
|
168
|
-
このパッケージの型を変更する際、以下の下流パッケージがビルド・テストに通ることを確認してください:
|
|
169
|
-
|
|
170
|
-
- [ ] `@markuplint/html-parser` -- HTML パーサー
|
|
171
|
-
- [ ] `@markuplint/parser-utils` -- パーサーユーティリティ関数
|
|
172
|
-
- [ ] `@markuplint/jsx-parser` -- JSX パーサー
|
|
173
|
-
- [ ] `@markuplint/astro-parser` -- Astro パーサー
|
|
174
|
-
- [ ] `@markuplint/vue-parser` -- Vue SFC パーサー
|
|
175
|
-
- [ ] `@markuplint/svelte-parser` -- Svelte パーサー
|
|
176
|
-
- [ ] `@markuplint/pug-parser` -- Pug パーサー
|
|
177
|
-
- [ ] `@markuplint/ml-core` -- コア DOM マッピング(最重要)
|
|
178
|
-
- [ ] `@markuplint/ml-config` -- 設定型
|
|
179
|
-
- [ ] `@markuplint/ml-spec` -- 仕様型
|
|
180
|
-
- [ ] `@markuplint/file-resolver` -- ファイル解決
|
|
181
|
-
|
|
182
|
-
最も重要な下流パッケージは `@markuplint/ml-core` で、`createNode()` -- `node.type` に対する `switch` 文で AST ノードを DOM ノードにマッピングする関数を含みます。
|
|
183
|
-
|
|
184
|
-
## トラブルシューティング
|
|
185
|
-
|
|
186
|
-
### 型変更後のビルドエラー
|
|
187
|
-
|
|
188
|
-
**症状:** 型の変更後、下流パッケージのビルドが失敗する。
|
|
189
|
-
|
|
190
|
-
**診断:**
|
|
191
|
-
|
|
192
|
-
1. まずこのパッケージをビルド:`yarn build --scope @markuplint/ml-ast`
|
|
193
|
-
2. 次に `ml-core` をビルド:`yarn build --scope @markuplint/ml-core`
|
|
194
|
-
3. `switch` の網羅性エラーを確認 -- TypeScript は `node.type` の `switch` で新しい型値のケースが欠けている場合に報告します
|
|
195
|
-
4. 共用体型の不一致を確認 -- 共用体に型を追加すると、既存の絞り込みコードの更新が必要になる場合があります
|
|
196
|
-
|
|
197
|
-
### ml-core の `createNode()` のケース漏れ
|
|
198
|
-
|
|
199
|
-
**症状:** 実行時に `TypeError: Invalid AST node types "newtype"` が発生する。
|
|
200
|
-
|
|
201
|
-
**原因:** 新しいノード型が `MLASTNodeType` と関連する共用体型に追加されたが、`ml-core` の `createNode()` の switch 文が更新されていない。
|
|
202
|
-
|
|
203
|
-
**修正:** `packages/@markuplint/ml-core/src/ml-dom/helper/create-node.ts` に新しい型の `case` を追加してください。
|
|
204
|
-
|
|
205
|
-
### パーサーが期待されるノードを生成しない
|
|
206
|
-
|
|
207
|
-
**症状:** パーサーが新しく追加されたフィールドや型のノードを生成しない。
|
|
208
|
-
|
|
209
|
-
**診断:**
|
|
210
|
-
|
|
211
|
-
1. パーサーの実装が新しいフィールドを設定するように更新されているか確認
|
|
212
|
-
2. オプションフィールドの場合、フィールドが暗黙的に `undefined` になっていないか検証
|
|
213
|
-
3. パーサーとこのパッケージの両方をビルドして型の整合性を確認
|