@markuplint/parser-utils 5.0.0-rc.1 → 5.0.0-rc.2
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 +20 -0
- package/SKILL.md +1 -0
- package/docs/maintenance.ja.md +21 -0
- package/docs/maintenance.md +21 -0
- package/docs/parser-class.ja.md +11 -0
- package/docs/parser-class.md +11 -0
- package/lib/attr-tokenizer.d.ts +1 -0
- package/lib/attr-tokenizer.js +6 -1
- package/lib/const.js +1 -0
- package/lib/get-location.d.ts +0 -8
- package/lib/get-location.js +0 -13
- package/package.json +12 -8
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
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-rc.2](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.1...v5.0.0-rc.2) (2026-04-15)
|
|
7
|
+
|
|
8
|
+
- fix(parser-utils)!: align unquoted attribute value tokenizer with HTML spec ([5168c04](https://github.com/markuplint/markuplint/commit/5168c041a1d37a7080f12e3c7569b5bbacd5a2f1))
|
|
9
|
+
- build!: remove ESLint and replace with oxlint ([1e0a337](https://github.com/markuplint/markuplint/commit/1e0a337707f76b903b16beeeb8c4d4fc0d8fc9e4))
|
|
10
|
+
- feat(parser-utils)!: remove deprecated getLine and getCol functions ([51cd7a2](https://github.com/markuplint/markuplint/commit/51cd7a28b7fcdd4a9d52d57f35c55b97b3b196fe))
|
|
11
|
+
|
|
12
|
+
### BREAKING CHANGES
|
|
13
|
+
|
|
14
|
+
- The default `endOfUnquotedValueChars` no longer includes `/`.
|
|
15
|
+
Unquoted attribute values preserve `/` as part of the value, matching the
|
|
16
|
+
WHATWG HTML "attribute value (unquoted) state". Consumers that relied on `/`
|
|
17
|
+
as a terminator must pass `endOfUnquotedValueChars: ['\t', '\n', '\f', '\r',
|
|
18
|
+
' ', '/', '>']` explicitly to `visitAttr()` / `attrTokenizer()`.
|
|
19
|
+
|
|
20
|
+
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
|
21
|
+
|
|
22
|
+
- ESLint is no longer used. Use oxlint instead.
|
|
23
|
+
- getLine() and getCol() have been removed.
|
|
24
|
+
Use getPosition() instead.
|
|
25
|
+
|
|
6
26
|
# [5.0.0-rc.1](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.0...v5.0.0-rc.1) (2026-03-27)
|
|
7
27
|
|
|
8
28
|
**Note:** Version bump only for package @markuplint/parser-utils
|
package/SKILL.md
CHANGED
|
@@ -101,6 +101,7 @@ Customize attribute parsing behavior for a specific parser. Follow recipe #4 in
|
|
|
101
101
|
- `quoteSet` -- custom quote delimiters (e.g., `{` `}` for JSX)
|
|
102
102
|
- `startState` -- initial AttrState (usually `BeforeName`)
|
|
103
103
|
- `noQuoteValueType` -- value type for unquoted values
|
|
104
|
+
- `endOfUnquotedValueChars` -- characters that terminate an unquoted value (default: whitespace and `>`, matching the WHATWG HTML spec)
|
|
104
105
|
|
|
105
106
|
### Step 2: Post-process
|
|
106
107
|
|
package/docs/maintenance.ja.md
CHANGED
|
@@ -120,6 +120,27 @@ visitAttr(token: Token) {
|
|
|
120
120
|
}
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
+
#### 引用符なし属性値の終端文字のカスタマイズ
|
|
124
|
+
|
|
125
|
+
`endOfUnquotedValueChars` のデフォルトは WHATWG HTML の "attribute value (unquoted) state" に準拠し、空白類と `>` のみが値を終端する。`/` は値の一部として扱われる。
|
|
126
|
+
|
|
127
|
+
ホスト言語が異なる規則を要求する場合はカスタムリストを渡す:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
// Pug: 文字による終端を無効化 — Pug レクサが属性境界を既に区切っている
|
|
131
|
+
super.visitAttr(token, {
|
|
132
|
+
quoteSet: [],
|
|
133
|
+
endOfUnquotedValueChars: [],
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
// `/` を終端文字として扱う(例: `a=x/>` を属性 `a="x"` + 自己閉じ `/>` として読む)
|
|
139
|
+
super.visitAttr(token, {
|
|
140
|
+
endOfUnquotedValueChars: ['\t', '\n', '\f', '\r', ' ', '/', '>'],
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
123
144
|
### 5. IDL属性マッピングの追加
|
|
124
145
|
|
|
125
146
|
IDL属性マップは `src/idl-attributes.ts` で定義されています。新しいマッピングを追加するには:
|
package/docs/maintenance.md
CHANGED
|
@@ -120,6 +120,27 @@ visitAttr(token: Token) {
|
|
|
120
120
|
}
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
+
#### Customizing Unquoted Value Terminators
|
|
124
|
+
|
|
125
|
+
The default `endOfUnquotedValueChars` follows the WHATWG HTML "attribute value (unquoted) state": only whitespace and `>` terminate the value. `/` is part of the value.
|
|
126
|
+
|
|
127
|
+
Pass a custom list when the host language requires different rules:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
// Pug: never terminate by character — the Pug lexer already delimits attrs
|
|
131
|
+
super.visitAttr(token, {
|
|
132
|
+
quoteSet: [],
|
|
133
|
+
endOfUnquotedValueChars: [],
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
// Treat `/` as a terminator (e.g., to read `a=x/>` as attribute `a="x"` + self-closing `/>`)
|
|
139
|
+
super.visitAttr(token, {
|
|
140
|
+
endOfUnquotedValueChars: ['\t', '\n', '\f', '\r', ' ', '/', '>'],
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
123
144
|
### 5. Adding an IDL Attribute Mapping
|
|
124
145
|
|
|
125
146
|
The IDL attribute map is defined in `src/idl-attributes.ts`. To add a new mapping:
|
package/docs/parser-class.ja.md
CHANGED
|
@@ -282,6 +282,17 @@ visitAttr(
|
|
|
282
282
|
|
|
283
283
|
また、`visitSpreadAttr()` を通じてスプレッド属性の検出も試みます。
|
|
284
284
|
|
|
285
|
+
#### オプション
|
|
286
|
+
|
|
287
|
+
| オプション | デフォルト | 説明 |
|
|
288
|
+
| ------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
289
|
+
| `quoteSet` | `[{ start: '"', end: '"', type: 'string' }, { start: "'", end: "'", type: 'string' }]` | 属性値として認識される引用符のセット。JSX / Vue / Svelte / Astro / MDX では `{` `}` を `type: 'script'` として追加する。 |
|
|
290
|
+
| `noQuoteValueType` | `'string'` | 引用符で囲まれていない値に割り当てられる値の型。 |
|
|
291
|
+
| `endOfUnquotedValueChars` | `['\t', '\n', '\f', '\r', ' ', '>']` | 引用符なし属性値を終端する文字。WHATWG HTML の "attribute value (unquoted) state" に準拠し、空白類と `>` のみ。`/` は終端ではなく値に含まれる(自己閉じの `/` は前段の before/after attribute name state で処理される)。終端判定を完全に無効化するには `[]` を渡す(Pug で利用)。 |
|
|
292
|
+
| `startState` | `AttrState.BeforeName` | 属性トークナイザの初期状態。JSX の `{...spread}` のような式のみの属性を扱う場合は `AttrState.BeforeValue` を指定する。 |
|
|
293
|
+
|
|
294
|
+
> 参照: [WHATWG HTML — attribute value (unquoted) state](<https://html.spec.whatwg.org/multipage/parsing.html#attribute-value-(unquoted)-state>)
|
|
295
|
+
|
|
285
296
|
### visitSpreadAttr()
|
|
286
297
|
|
|
287
298
|
```ts
|
package/docs/parser-class.md
CHANGED
|
@@ -282,6 +282,17 @@ If the raw string contains multiple attributes, only the first is parsed and the
|
|
|
282
282
|
|
|
283
283
|
Also attempts to detect spread attributes via `visitSpreadAttr()`.
|
|
284
284
|
|
|
285
|
+
#### Options
|
|
286
|
+
|
|
287
|
+
| Option | Default | Description |
|
|
288
|
+
| ------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
289
|
+
| `quoteSet` | `[{ start: '"', end: '"', type: 'string' }, { start: "'", end: "'", type: 'string' }]` | Quote delimiters recognized for the attribute value. Override to add expression delimiters such as `{` `}` (JSX / Vue / Svelte / Astro / MDX) with `type: 'script'`. |
|
|
290
|
+
| `noQuoteValueType` | `'string'` | Value type assigned when the value is unquoted. |
|
|
291
|
+
| `endOfUnquotedValueChars` | `['\t', '\n', '\f', '\r', ' ', '>']` | Characters that terminate an unquoted attribute value. Matches the WHATWG HTML "attribute value (unquoted) state" — whitespace and `>` only. `/` is NOT a terminator and is included in the value (self-closing `/` is handled earlier, in the before/after attribute name state). Pass `[]` to disable termination entirely (used by Pug). |
|
|
292
|
+
| `startState` | `AttrState.BeforeName` | Initial state of the attribute tokenizer. Use `AttrState.BeforeValue` to start directly at the value (e.g., for bare expression attributes like JSX `{...spread}`). |
|
|
293
|
+
|
|
294
|
+
> See: [WHATWG HTML — attribute value (unquoted) state](<https://html.spec.whatwg.org/multipage/parsing.html#attribute-value-(unquoted)-state>)
|
|
295
|
+
|
|
285
296
|
### visitSpreadAttr()
|
|
286
297
|
|
|
287
298
|
```ts
|
package/lib/attr-tokenizer.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { AttrState } from './enums.js';
|
|
|
4
4
|
* @see https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
|
|
5
5
|
* @see https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state
|
|
6
6
|
* @see https://html.spec.whatwg.org/multipage/parsing.html#attribute-name-state
|
|
7
|
+
* @see https://html.spec.whatwg.org/multipage/parsing.html#attribute-value-(unquoted)-state
|
|
7
8
|
*/
|
|
8
9
|
export declare function attrTokenizer(raw: string, quoteSet?: readonly QuoteSet[], startState?: AttrState, noQuoteValueType?: ValueType, endOfUnquotedValueChars?: ReadonlyArray<string>): {
|
|
9
10
|
spacesBeforeAttrName: string;
|
package/lib/attr-tokenizer.js
CHANGED
|
@@ -11,8 +11,13 @@ const EQUAL = '=';
|
|
|
11
11
|
* @see https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
|
|
12
12
|
* @see https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state
|
|
13
13
|
* @see https://html.spec.whatwg.org/multipage/parsing.html#attribute-name-state
|
|
14
|
+
* @see https://html.spec.whatwg.org/multipage/parsing.html#attribute-value-(unquoted)-state
|
|
14
15
|
*/
|
|
15
|
-
export function attrTokenizer(raw, quoteSet = defaultQuoteSet, startState = AttrState.BeforeName, noQuoteValueType = 'string',
|
|
16
|
+
export function attrTokenizer(raw, quoteSet = defaultQuoteSet, startState = AttrState.BeforeName, noQuoteValueType = 'string',
|
|
17
|
+
// Default follows the spec referenced above: only whitespace and `>` terminate
|
|
18
|
+
// the value. `/` is handled by the outer tag tokenizer (before/after attribute
|
|
19
|
+
// name state), not here.
|
|
20
|
+
endOfUnquotedValueChars = [...defaultSpaces, '>']) {
|
|
16
21
|
let state = startState;
|
|
17
22
|
let spacesBeforeAttrName = '';
|
|
18
23
|
let attrName = '';
|
package/lib/const.js
CHANGED
|
@@ -94,6 +94,7 @@ export const svgElementList = [
|
|
|
94
94
|
'tref',
|
|
95
95
|
'vkern',
|
|
96
96
|
];
|
|
97
|
+
// eslint-disable-next-line no-control-regex -- WHATWG HTML spec requires matching NULL character
|
|
97
98
|
export const reTagName = /^[a-z][^\0\t\n\f />]*/i;
|
|
98
99
|
export const reSplitterTag = /<[^>]+>/g;
|
|
99
100
|
/**
|
package/lib/get-location.d.ts
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
export { getPosition } from '@markuplint/shared';
|
|
2
|
-
/**
|
|
3
|
-
* @deprecated Use {@link getPosition} instead. Will be removed in v5.0.0.
|
|
4
|
-
*/
|
|
5
|
-
export declare function getLine(rawCodeFragment: string, startOffset: number): number;
|
|
6
|
-
/**
|
|
7
|
-
* @deprecated Use {@link getPosition} instead. Will be removed in v5.0.0.
|
|
8
|
-
*/
|
|
9
|
-
export declare function getCol(rawCodeFragment: string, startOffset: number): number;
|
|
10
2
|
export declare function getEndLine(rawCodeFragment: string, startLine: number): number;
|
|
11
3
|
export declare function getEndCol(rawCodeFragment: string, startCol: number): number;
|
|
12
4
|
/**
|
package/lib/get-location.js
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
export { getPosition } from '@markuplint/shared';
|
|
2
2
|
const LINE_BREAK = '\n';
|
|
3
|
-
/**
|
|
4
|
-
* @deprecated Use {@link getPosition} instead. Will be removed in v5.0.0.
|
|
5
|
-
*/
|
|
6
|
-
export function getLine(rawCodeFragment, startOffset) {
|
|
7
|
-
return rawCodeFragment.slice(0, startOffset).split(LINE_BREAK).length;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* @deprecated Use {@link getPosition} instead. Will be removed in v5.0.0.
|
|
11
|
-
*/
|
|
12
|
-
export function getCol(rawCodeFragment, startOffset) {
|
|
13
|
-
const lines = rawCodeFragment.slice(0, startOffset).split(LINE_BREAK);
|
|
14
|
-
return (lines.at(-1) ?? '').length + 1;
|
|
15
|
-
}
|
|
16
3
|
export function getEndLine(rawCodeFragment, startLine) {
|
|
17
4
|
return rawCodeFragment.split(LINE_BREAK).length - 1 + startLine;
|
|
18
5
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/parser-utils",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.2",
|
|
4
4
|
"description": "Utility module for markuplint parser plugin",
|
|
5
|
-
"repository":
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/markuplint/markuplint.git",
|
|
8
|
+
"directory": "packages/@markuplint/parser-utils"
|
|
9
|
+
},
|
|
6
10
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
7
11
|
"license": "MIT",
|
|
8
12
|
"engines": {
|
|
@@ -31,16 +35,16 @@
|
|
|
31
35
|
"clean": "tsc --build --clean tsconfig.build.json"
|
|
32
36
|
},
|
|
33
37
|
"dependencies": {
|
|
34
|
-
"@markuplint/ml-ast": "5.0.0-rc.
|
|
35
|
-
"@markuplint/ml-spec": "5.0.0-rc.
|
|
36
|
-
"@markuplint/shared": "5.0.0-rc.
|
|
37
|
-
"@markuplint/types": "5.0.0-rc.
|
|
38
|
+
"@markuplint/ml-ast": "5.0.0-rc.2",
|
|
39
|
+
"@markuplint/ml-spec": "5.0.0-rc.2",
|
|
40
|
+
"@markuplint/shared": "5.0.0-rc.2",
|
|
41
|
+
"@markuplint/types": "5.0.0-rc.2",
|
|
38
42
|
"debug": "4.4.3",
|
|
39
43
|
"espree": "11.2.0",
|
|
40
44
|
"type-fest": "5.5.0"
|
|
41
45
|
},
|
|
42
46
|
"devDependencies": {
|
|
43
|
-
"@typescript-eslint/typescript-estree": "8.
|
|
47
|
+
"@typescript-eslint/typescript-estree": "8.58.2"
|
|
44
48
|
},
|
|
45
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "e43763858d9234c417053becc73dbd088c1e7ea6"
|
|
46
50
|
}
|