@markuplint/parser-utils 5.0.0-alpha.0 → 5.0.0-alpha.1
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 +1 -1
- package/ARCHITECTURE.md +1 -1
- package/CHANGELOG.md +6 -0
- package/docs/parser-class.ja.md +1 -1
- package/docs/parser-class.md +1 -1
- package/lib/parser.js +29 -4
- package/package.json +6 -6
package/ARCHITECTURE.ja.md
CHANGED
|
@@ -148,7 +148,7 @@ ParserError (基底クラス)
|
|
|
148
148
|
|
|
149
149
|
## IDL 属性マッピング
|
|
150
150
|
|
|
151
|
-
`searchIDLAttribute` は React スタイルの IDL 属性名と HTML コンテンツ属性名の双方向マッピングを提供します(例: `className` → `class`、`htmlFor` → `for`)。spec が `
|
|
151
|
+
`searchIDLAttribute` は React スタイルの IDL 属性名と HTML コンテンツ属性名の双方向マッピングを提供します(例: `className` → `class`、`htmlFor` → `for`)。spec が `acceptedAttrNames`(`'idl'` または `'both'`)を設定している場合に、`@markuplint/ml-core` の `MLAttr` コンストラクタから呼び出されます。
|
|
152
152
|
|
|
153
153
|
## 外部依存
|
|
154
154
|
|
package/ARCHITECTURE.md
CHANGED
|
@@ -174,7 +174,7 @@ Additionally, `debug.ts` provides `PerformanceTimer` for measuring parse phase d
|
|
|
174
174
|
|
|
175
175
|
## IDL Attribute Mapping
|
|
176
176
|
|
|
177
|
-
`searchIDLAttribute` maps between React-style IDL attribute names and HTML content attribute names. It is called by `@markuplint/ml-core`'s `MLAttr` constructor when the spec sets `
|
|
177
|
+
`searchIDLAttribute` maps between React-style IDL attribute names and HTML content attribute names. It is called by `@markuplint/ml-core`'s `MLAttr` constructor when the spec sets `acceptedAttrNames` (either `'idl'` or `'both'`). It maintains a comprehensive mapping table derived from React's `possibleStandardNames.js`, covering:
|
|
178
178
|
|
|
179
179
|
- HTML attributes (e.g., `className` -> `class`, `htmlFor` -> `for`, `tabIndex` -> `tabindex`)
|
|
180
180
|
- SVG attributes (e.g., `strokeWidth` -> `stroke-width`, `clipPath` -> `clip-path`)
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
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.1](https://github.com/markuplint/markuplint/compare/v5.0.0-alpha.0...v5.0.0-alpha.1) (2026-02-22)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **parser-utils:** skip text trimming when text node is a descendant of the next node ([1bfcede](https://github.com/markuplint/markuplint/commit/1bfcedebbd115ea817df76a979b4e10a26d0a2b2))
|
|
11
|
+
|
|
6
12
|
# [5.0.0-alpha.0](https://github.com/markuplint/markuplint/compare/v4.14.1...v5.0.0-alpha.0) (2026-02-20)
|
|
7
13
|
|
|
8
14
|
### Bug Fixes
|
package/docs/parser-class.ja.md
CHANGED
|
@@ -173,7 +173,7 @@ afterFlattenNodes(
|
|
|
173
173
|
1. **残留ノードの露出** — 既知のノード間の空白と無効なマークアップを発見する
|
|
174
174
|
2. **孤立終了タグ → ボーガス** — 対応する開始タグがない終了タグを `invalid` ノードに変換する
|
|
175
175
|
3. **テキストの結合** — 同じオフセットにある隣接する `#text` ノードをマージする
|
|
176
|
-
4. **テキストのトリム** —
|
|
176
|
+
4. **テキストのトリム** — フラットリスト上で次のノードとソース範囲が重複するテキストノードをトリムする。テキストノードがツリー上で次のノードの子孫である場合はスキップする(Markdown 等の合成パーサーでは、子要素が親要素と同じソース範囲を共有することがあるため)
|
|
177
177
|
|
|
178
178
|
### ステップ 9: restoreNode()
|
|
179
179
|
|
package/docs/parser-class.md
CHANGED
|
@@ -173,7 +173,7 @@ Performs four cleanup passes:
|
|
|
173
173
|
1. **Expose remnant nodes** — discovers whitespace and invalid markup between known nodes
|
|
174
174
|
2. **Orphan end tags → bogus** — converts unmatched end tags to `invalid` nodes
|
|
175
175
|
3. **Concatenate text** — merges adjacent `#text` nodes at the same offset
|
|
176
|
-
4. **Trim text** — trims
|
|
176
|
+
4. **Trim text** — trims text nodes whose source range overlaps with the next node in the flat list. Skips trimming when the text node is a tree-descendant of the next node, which can occur with synthetic parsers (e.g., Markdown) where child elements share the same source range as their parent
|
|
177
177
|
|
|
178
178
|
### Step 9: restoreNode()
|
|
179
179
|
|
package/lib/parser.js
CHANGED
|
@@ -1011,6 +1011,24 @@ export class Parser {
|
|
|
1011
1011
|
col: getEndCol(token.raw, token.col),
|
|
1012
1012
|
};
|
|
1013
1013
|
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Checks whether a node is a descendant of another node by walking up
|
|
1016
|
+
* the parent chain.
|
|
1017
|
+
*
|
|
1018
|
+
* @param node - The node to test.
|
|
1019
|
+
* @param potentialAncestor - The node that may be an ancestor.
|
|
1020
|
+
* @returns `true` if `node` is a descendant of `potentialAncestor`.
|
|
1021
|
+
*/
|
|
1022
|
+
#isDescendantOf(node, potentialAncestor) {
|
|
1023
|
+
let current = 'parentNode' in node ? node.parentNode : null;
|
|
1024
|
+
while (current) {
|
|
1025
|
+
if (current === potentialAncestor) {
|
|
1026
|
+
return true;
|
|
1027
|
+
}
|
|
1028
|
+
current = current.parentNode;
|
|
1029
|
+
}
|
|
1030
|
+
return false;
|
|
1031
|
+
}
|
|
1014
1032
|
#orphanEndTagToBogusMark(nodeList) {
|
|
1015
1033
|
const newNodeList = [];
|
|
1016
1034
|
for (let node of nodeList) {
|
|
@@ -1304,10 +1322,17 @@ export class Parser {
|
|
|
1304
1322
|
this.#originalRawCode = originalRawCode ?? this.#originalRawCode;
|
|
1305
1323
|
}
|
|
1306
1324
|
/**
|
|
1307
|
-
*
|
|
1325
|
+
* Trims text nodes whose source range overlaps with the next node in
|
|
1326
|
+
* the flat list. This prevents text content from bleeding into adjacent
|
|
1327
|
+
* elements that occupy a later (or overlapping) source range.
|
|
1328
|
+
*
|
|
1329
|
+
* Skips trimming when the text node is a descendant of the next node
|
|
1330
|
+
* in the tree hierarchy, because synthetic parsers (e.g., Markdown)
|
|
1331
|
+
* can produce child elements that share the same source range as their
|
|
1332
|
+
* parent and therefore appear before the parent in offset-sorted order.
|
|
1308
1333
|
*
|
|
1309
|
-
* @param nodeList
|
|
1310
|
-
* @returns
|
|
1334
|
+
* @param nodeList - The flat, offset-sorted node list to process.
|
|
1335
|
+
* @returns A new node list with overlapping text nodes trimmed.
|
|
1311
1336
|
*/
|
|
1312
1337
|
#trimText(nodeList) {
|
|
1313
1338
|
const newNodeList = [];
|
|
@@ -1318,7 +1343,7 @@ export class Parser {
|
|
|
1318
1343
|
node.raw.length > 0) {
|
|
1319
1344
|
const prevNodeEndOffset = prevNode.offset + prevNode.raw.length;
|
|
1320
1345
|
const nodeStartOffset = node.offset;
|
|
1321
|
-
if (prevNodeEndOffset > nodeStartOffset) {
|
|
1346
|
+
if (prevNodeEndOffset > nodeStartOffset && !this.#isDescendantOf(prevNode, node)) {
|
|
1322
1347
|
const prevNodeRaw = prevNode.raw;
|
|
1323
1348
|
const prevNodeTrimmedRaw = prevNodeRaw.slice(0, nodeStartOffset - prevNode.offset);
|
|
1324
1349
|
this.updateRaw(prevNode, prevNodeTrimmedRaw);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/parser-utils",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.1",
|
|
4
4
|
"description": "Utility module for markuplint parser plugin",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
"clean": "tsc --build --clean tsconfig.build.json"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@markuplint/ml-ast": "5.0.0-alpha.
|
|
35
|
-
"@markuplint/ml-spec": "5.0.0-alpha.
|
|
36
|
-
"@markuplint/types": "5.0.0-alpha.
|
|
34
|
+
"@markuplint/ml-ast": "5.0.0-alpha.1",
|
|
35
|
+
"@markuplint/ml-spec": "5.0.0-alpha.1",
|
|
36
|
+
"@markuplint/types": "5.0.0-alpha.1",
|
|
37
37
|
"debug": "4.4.3",
|
|
38
|
-
"espree": "11.1.
|
|
38
|
+
"espree": "11.1.1",
|
|
39
39
|
"type-fest": "5.4.4"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@typescript-eslint/typescript-estree": "8.56.0"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "78a295e73a097a1ce09c777c06fa21ab68136387"
|
|
45
45
|
}
|