@markuplint/ml-core 5.0.0-alpha.1 → 5.0.0-alpha.3
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 +158 -5
- package/ARCHITECTURE.md +209 -6
- package/CHANGELOG.md +25 -0
- package/docs/ml-dom/document.ja.md +7 -14
- package/docs/ml-dom/document.md +7 -14
- package/docs/ml-dom/element.ja.md +9 -24
- package/docs/ml-dom/element.md +9 -24
- package/docs/rule-system.ja.md +1 -1
- package/docs/rule-system.md +1 -1
- package/lib/cursor-offset.d.ts +13 -0
- package/lib/cursor-offset.js +34 -0
- package/lib/fix-applier.d.ts +32 -0
- package/lib/fix-applier.js +75 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +2 -0
- package/lib/ml-core.d.ts +53 -8
- package/lib/ml-core.js +197 -59
- package/lib/ml-dom/helper/get-indent.d.ts +0 -1
- package/lib/ml-dom/helper/get-indent.js +5 -18
- package/lib/ml-dom/node/attr.d.ts +2 -13
- package/lib/ml-dom/node/attr.js +3 -35
- package/lib/ml-dom/node/block.js +2 -1
- package/lib/ml-dom/node/character-data.d.ts +35 -0
- package/lib/ml-dom/node/character-data.js +35 -6
- package/lib/ml-dom/node/document.d.ts +2 -27
- package/lib/ml-dom/node/document.js +7 -46
- package/lib/ml-dom/node/dom-token-list.d.ts +0 -1
- package/lib/ml-dom/node/dom-token-list.js +3 -3
- package/lib/ml-dom/node/element-close-tag.d.ts +1 -1
- package/lib/ml-dom/node/element-close-tag.js +2 -16
- package/lib/ml-dom/node/element.d.ts +2 -19
- package/lib/ml-dom/node/element.js +3 -65
- package/lib/ml-dom/token/token.d.ts +3 -18
- package/lib/ml-dom/token/token.js +7 -28
- package/lib/ml-rule/index.d.ts +1 -0
- package/lib/ml-rule/index.js +1 -0
- package/lib/ml-rule/ml-rule-context.d.ts +2 -31
- package/lib/ml-rule/ml-rule-context.js +18 -18
- package/lib/ml-rule/ml-rule.d.ts +6 -11
- package/lib/ml-rule/ml-rule.js +36 -37
- package/lib/ml-rule/rule-fixer.d.ts +20 -0
- package/lib/ml-rule/rule-fixer.js +38 -0
- package/lib/ml-rule/types.d.ts +1 -2
- package/lib/test/index.d.ts +1 -10
- package/lib/test/index.js +0 -11
- package/package.json +12 -12
|
@@ -81,7 +81,6 @@ export class MLDocument extends MLParentNode {
|
|
|
81
81
|
* Rules use this as a fallback when their own options do not specify a value.
|
|
82
82
|
*/
|
|
83
83
|
ruleCommonSettings;
|
|
84
|
-
#tokenList = null;
|
|
85
84
|
/**
|
|
86
85
|
* @param ast node list of markuplint AST
|
|
87
86
|
* @param ruleset ruleset object
|
|
@@ -108,9 +107,9 @@ export class MLDocument extends MLParentNode {
|
|
|
108
107
|
return createNode(astNode, this);
|
|
109
108
|
})
|
|
110
109
|
.filter((n) => !!n));
|
|
111
|
-
this
|
|
110
|
+
this.#pretending(options?.pretenders);
|
|
112
111
|
try {
|
|
113
|
-
this
|
|
112
|
+
this.#ruleMapping(ruleset);
|
|
114
113
|
}
|
|
115
114
|
catch (error) {
|
|
116
115
|
if (error instanceof InvalidSelectorError) {
|
|
@@ -2040,7 +2039,6 @@ export class MLDocument extends MLParentNode {
|
|
|
2040
2039
|
* @implements DOM API: `Document`
|
|
2041
2040
|
*/
|
|
2042
2041
|
getElementById(elementId) {
|
|
2043
|
-
// TODO:
|
|
2044
2042
|
return this.querySelector(`#${elementId}`);
|
|
2045
2043
|
}
|
|
2046
2044
|
/**
|
|
@@ -2088,27 +2086,6 @@ export class MLDocument extends MLParentNode {
|
|
|
2088
2086
|
getSelection() {
|
|
2089
2087
|
throw new UnexpectedCallError('Not supported "getSelection" method');
|
|
2090
2088
|
}
|
|
2091
|
-
/**
|
|
2092
|
-
* Returns a flat, offset-sorted list of all tokens in the document,
|
|
2093
|
-
* including element close tags. The result is cached after the first call.
|
|
2094
|
-
*
|
|
2095
|
-
* @implements `@markuplint/ml-core` API: `MLDocument`
|
|
2096
|
-
* @returns A frozen array of tokens sorted by their starting offset
|
|
2097
|
-
*/
|
|
2098
|
-
getTokenList() {
|
|
2099
|
-
if (this.#tokenList) {
|
|
2100
|
-
return this.#tokenList;
|
|
2101
|
-
}
|
|
2102
|
-
const tokens = [];
|
|
2103
|
-
for (const node of this.nodeList) {
|
|
2104
|
-
tokens.push(node);
|
|
2105
|
-
if (node.is(node.ELEMENT_NODE) && node.closeTag) {
|
|
2106
|
-
tokens.push(node.closeTag);
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
this.#tokenList = Object.freeze(tokens.toSorted((a, b) => a.startOffset - b.startOffset));
|
|
2110
|
-
return this.#tokenList;
|
|
2111
|
-
}
|
|
2112
2089
|
/**
|
|
2113
2090
|
* **IT THROWS AN ERROR WHEN CALLING THIS.**
|
|
2114
2091
|
*
|
|
@@ -2250,29 +2227,13 @@ export class MLDocument extends MLParentNode {
|
|
|
2250
2227
|
throw new UnexpectedCallError('Not supported "startViewTransition" method');
|
|
2251
2228
|
}
|
|
2252
2229
|
/**
|
|
2253
|
-
* Returns
|
|
2254
|
-
* returns the document with all lint fixes applied by substituting
|
|
2255
|
-
* fixed token content at the appropriate offsets.
|
|
2230
|
+
* Returns the raw string representation of the document.
|
|
2256
2231
|
*
|
|
2257
2232
|
* @implements `@markuplint/ml-core` API: `MLDocument`
|
|
2258
|
-
* @param fixed - When true, returns the fixed content; otherwise returns the original raw content
|
|
2259
2233
|
* @returns The string content of the document
|
|
2260
2234
|
*/
|
|
2261
|
-
toString(
|
|
2262
|
-
|
|
2263
|
-
return this.raw;
|
|
2264
|
-
}
|
|
2265
|
-
let raw = this.raw;
|
|
2266
|
-
let offset = 0;
|
|
2267
|
-
for (const node of this.getTokenList()) {
|
|
2268
|
-
const nodeRaw = node.toString(true);
|
|
2269
|
-
if (nodeRaw === node.raw) {
|
|
2270
|
-
continue;
|
|
2271
|
-
}
|
|
2272
|
-
raw = raw.slice(0, node.startOffset + offset) + nodeRaw + raw.slice(node.endOffset + offset);
|
|
2273
|
-
offset += nodeRaw.length - (node.endOffset - node.startOffset);
|
|
2274
|
-
}
|
|
2275
|
-
return raw;
|
|
2235
|
+
toString() {
|
|
2236
|
+
return this.raw;
|
|
2276
2237
|
}
|
|
2277
2238
|
walkOn(type, walker, skipWhenRuleIsDisabled = true) {
|
|
2278
2239
|
return sequentialWalker(this.nodeList, node => {
|
|
@@ -2319,7 +2280,7 @@ export class MLDocument extends MLParentNode {
|
|
|
2319
2280
|
*
|
|
2320
2281
|
* @param pretenders - Optional pretender configurations from the document options
|
|
2321
2282
|
*/
|
|
2322
|
-
|
|
2283
|
+
#pretending(pretenders) {
|
|
2323
2284
|
if (docLog.enabled) {
|
|
2324
2285
|
docLog('Pretending: %O', pretenders);
|
|
2325
2286
|
}
|
|
@@ -2336,7 +2297,7 @@ export class MLDocument extends MLParentNode {
|
|
|
2336
2297
|
*
|
|
2337
2298
|
* @param ruleset - The ruleset containing rules, nodeRules, and childNodeRules
|
|
2338
2299
|
*/
|
|
2339
|
-
|
|
2300
|
+
#ruleMapping(ruleset) {
|
|
2340
2301
|
if (docLog.enabled) {
|
|
2341
2302
|
docLog('Rule Mapping: %O', Object.keys(ruleset.rules));
|
|
2342
2303
|
}
|
|
@@ -45,7 +45,7 @@ export class MLDomTokenList extends Array {
|
|
|
45
45
|
if (!token) {
|
|
46
46
|
break;
|
|
47
47
|
}
|
|
48
|
-
const loc = this
|
|
48
|
+
const loc = this.#pick(token, offset);
|
|
49
49
|
if (!loc) {
|
|
50
50
|
offset = 0;
|
|
51
51
|
continue;
|
|
@@ -74,7 +74,7 @@ export class MLDomTokenList extends Array {
|
|
|
74
74
|
* @implements `@markuplint/ml-core` API: `MLDomTokenList`
|
|
75
75
|
*/
|
|
76
76
|
pick(token) {
|
|
77
|
-
const r = this
|
|
77
|
+
const r = this.#pick(token);
|
|
78
78
|
if (!r) {
|
|
79
79
|
return null;
|
|
80
80
|
}
|
|
@@ -101,7 +101,7 @@ export class MLDomTokenList extends Array {
|
|
|
101
101
|
toggle(token, force) {
|
|
102
102
|
throw new UnexpectedCallError('Not supported "toggle" method');
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
#pick(token, _offset = 0) {
|
|
105
105
|
token = token.trim().split(/\s+/)[0] ?? '';
|
|
106
106
|
if (!token) {
|
|
107
107
|
return null;
|
|
@@ -23,21 +23,7 @@ export class MLElementCloseTag extends MLNode {
|
|
|
23
23
|
get rawName() {
|
|
24
24
|
return this._astToken.nodeName;
|
|
25
25
|
}
|
|
26
|
-
toString(
|
|
27
|
-
|
|
28
|
-
return this.raw;
|
|
29
|
-
}
|
|
30
|
-
if (this.nodeName.startsWith('#')) {
|
|
31
|
-
return this.raw;
|
|
32
|
-
}
|
|
33
|
-
if (this.pair.isOmitted) {
|
|
34
|
-
return this.raw;
|
|
35
|
-
}
|
|
36
|
-
return [
|
|
37
|
-
this.pair.tagOpenChar,
|
|
38
|
-
this.pair.tagOpenChar === '' ? '' : '/',
|
|
39
|
-
this.pair.fixedNodeName === this.pair.rawName ? this.rawName : this.pair.fixedNodeName,
|
|
40
|
-
this.pair.tagCloseChar,
|
|
41
|
-
].join('');
|
|
26
|
+
toString() {
|
|
27
|
+
return this.raw;
|
|
42
28
|
}
|
|
43
29
|
}
|
|
@@ -632,13 +632,6 @@ export declare class MLElement<T extends RuleConfigValue, O extends PlainData =
|
|
|
632
632
|
* @implements DOM API: `Element`
|
|
633
633
|
*/
|
|
634
634
|
get enterKeyHint(): string;
|
|
635
|
-
/**
|
|
636
|
-
* Returns the fixed (potentially corrected) node name, which may differ from the
|
|
637
|
-
* original node name after lint fixes such as case normalization.
|
|
638
|
-
*
|
|
639
|
-
* @implements `@markuplint/ml-core` API: `MLElement`
|
|
640
|
-
*/
|
|
641
|
-
get fixedNodeName(): string;
|
|
642
635
|
/**
|
|
643
636
|
* Whether this element has any spread attributes (e.g., `{...props}` in JSX).
|
|
644
637
|
*/
|
|
@@ -1819,13 +1812,6 @@ export declare class MLElement<T extends RuleConfigValue, O extends PlainData =
|
|
|
1819
1812
|
* @implements DOM API: `Element`
|
|
1820
1813
|
*/
|
|
1821
1814
|
computedStyleMap(): StylePropertyMapReadOnly;
|
|
1822
|
-
/**
|
|
1823
|
-
* Overrides the fixed node name for this element, used when the element's
|
|
1824
|
-
* tag name needs to be corrected during linting (e.g., case normalization).
|
|
1825
|
-
*
|
|
1826
|
-
* @param name - The new node name to set
|
|
1827
|
-
*/
|
|
1828
|
-
fixNodeName(name: string): void;
|
|
1829
1815
|
/**
|
|
1830
1816
|
* **IT THROWS AN ERROR WHEN CALLING THIS.**
|
|
1831
1817
|
*
|
|
@@ -2252,15 +2238,12 @@ export declare class MLElement<T extends RuleConfigValue, O extends PlainData =
|
|
|
2252
2238
|
*/
|
|
2253
2239
|
toNormalizeString(): string;
|
|
2254
2240
|
/**
|
|
2255
|
-
* Returns
|
|
2256
|
-
* returns the element with any lint fixes applied to the tag name,
|
|
2257
|
-
* attributes, and embedded comment nodes.
|
|
2241
|
+
* Returns the raw string representation of this element.
|
|
2258
2242
|
*
|
|
2259
2243
|
* @implements `@markuplint/ml-core` API: `MLElement`
|
|
2260
|
-
* @param fixed - When true, returns the fixed content; otherwise returns the original raw content
|
|
2261
2244
|
* @returns The string content of this element
|
|
2262
2245
|
*/
|
|
2263
|
-
toString(
|
|
2246
|
+
toString(): string;
|
|
2264
2247
|
/**
|
|
2265
2248
|
* **IT THROWS AN ERROR WHEN CALLING THIS.**
|
|
2266
2249
|
*
|
|
@@ -34,7 +34,6 @@ export class MLElement extends MLParentNode {
|
|
|
34
34
|
* - `authored`: Authored element (JSX Element etc.) through the view framework or the template engine.
|
|
35
35
|
*/
|
|
36
36
|
elementType;
|
|
37
|
-
#fixedNodeName;
|
|
38
37
|
#getChildElementsAndTextNodeWithoutWhitespacesCache = null;
|
|
39
38
|
/**
|
|
40
39
|
* Whether this element belongs to a non-HTML namespace (e.g., SVG or MathML).
|
|
@@ -123,7 +122,6 @@ export class MLElement extends MLParentNode {
|
|
|
123
122
|
this.elementType = astNode.elementType;
|
|
124
123
|
this.#localName = ns.localName;
|
|
125
124
|
this.isForeignElement = this.namespaceURI !== HTML_NAMESPACE;
|
|
126
|
-
this.#fixedNodeName = astNode.nodeName;
|
|
127
125
|
this.isOmitted = astNode.isGhost;
|
|
128
126
|
this.tagOpenChar = astNode.tagOpenChar;
|
|
129
127
|
this.tagCloseChar = astNode.tagCloseChar;
|
|
@@ -850,15 +848,6 @@ export class MLElement extends MLParentNode {
|
|
|
850
848
|
get enterKeyHint() {
|
|
851
849
|
throw new UnexpectedCallError('Not supported "enterKeyHint" property');
|
|
852
850
|
}
|
|
853
|
-
/**
|
|
854
|
-
* Returns the fixed (potentially corrected) node name, which may differ from the
|
|
855
|
-
* original node name after lint fixes such as case normalization.
|
|
856
|
-
*
|
|
857
|
-
* @implements `@markuplint/ml-core` API: `MLElement`
|
|
858
|
-
*/
|
|
859
|
-
get fixedNodeName() {
|
|
860
|
-
return this.#fixedNodeName;
|
|
861
|
-
}
|
|
862
851
|
/**
|
|
863
852
|
* Whether this element has any spread attributes (e.g., `{...props}` in JSX).
|
|
864
853
|
*/
|
|
@@ -2385,15 +2374,6 @@ export class MLElement extends MLParentNode {
|
|
|
2385
2374
|
computedStyleMap() {
|
|
2386
2375
|
throw new UnexpectedCallError('Not supported "computedStyleMap" method');
|
|
2387
2376
|
}
|
|
2388
|
-
/**
|
|
2389
|
-
* Overrides the fixed node name for this element, used when the element's
|
|
2390
|
-
* tag name needs to be corrected during linting (e.g., case normalization).
|
|
2391
|
-
*
|
|
2392
|
-
* @param name - The new node name to set
|
|
2393
|
-
*/
|
|
2394
|
-
fixNodeName(name) {
|
|
2395
|
-
this.#fixedNodeName = name;
|
|
2396
|
-
}
|
|
2397
2377
|
/**
|
|
2398
2378
|
* **IT THROWS AN ERROR WHEN CALLING THIS.**
|
|
2399
2379
|
*
|
|
@@ -2745,7 +2725,6 @@ export class MLElement extends MLParentNode {
|
|
|
2745
2725
|
insertAdjacentElement(where,
|
|
2746
2726
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
2747
2727
|
element) {
|
|
2748
|
-
// TODO:
|
|
2749
2728
|
throw new UnexpectedCallError('Does not implement "insertAdjacentElement" method yet');
|
|
2750
2729
|
}
|
|
2751
2730
|
/**
|
|
@@ -2756,7 +2735,6 @@ export class MLElement extends MLParentNode {
|
|
|
2756
2735
|
* @see https://w3c.github.io/DOM-Parsing/#widl-Element-insertAdjacentHTML-void-DOMString-position-DOMString-text
|
|
2757
2736
|
*/
|
|
2758
2737
|
insertAdjacentHTML(position, text) {
|
|
2759
|
-
// TODO:
|
|
2760
2738
|
throw new UnexpectedCallError('Does not implement "insertAdjacentHTML" method yet');
|
|
2761
2739
|
}
|
|
2762
2740
|
/**
|
|
@@ -2767,7 +2745,6 @@ export class MLElement extends MLParentNode {
|
|
|
2767
2745
|
* @see https://dom.spec.whatwg.org/#dom-element-insertadjacenttext
|
|
2768
2746
|
*/
|
|
2769
2747
|
insertAdjacentText(where, data) {
|
|
2770
|
-
// TODO:
|
|
2771
2748
|
throw new UnexpectedCallError('Does not implement "insertAdjacentText" method yet');
|
|
2772
2749
|
}
|
|
2773
2750
|
/**
|
|
@@ -3176,52 +3153,13 @@ export class MLElement extends MLParentNode {
|
|
|
3176
3153
|
return normalizedString;
|
|
3177
3154
|
}
|
|
3178
3155
|
/**
|
|
3179
|
-
* Returns
|
|
3180
|
-
* returns the element with any lint fixes applied to the tag name,
|
|
3181
|
-
* attributes, and embedded comment nodes.
|
|
3156
|
+
* Returns the raw string representation of this element.
|
|
3182
3157
|
*
|
|
3183
3158
|
* @implements `@markuplint/ml-core` API: `MLElement`
|
|
3184
|
-
* @param fixed - When true, returns the fixed content; otherwise returns the original raw content
|
|
3185
3159
|
* @returns The string content of this element
|
|
3186
3160
|
*/
|
|
3187
|
-
toString(
|
|
3188
|
-
|
|
3189
|
-
return this.raw;
|
|
3190
|
-
}
|
|
3191
|
-
if (this.pretenderContext?.type === 'pretender') {
|
|
3192
|
-
return this.raw;
|
|
3193
|
-
}
|
|
3194
|
-
if (this.nodeName.startsWith('#')) {
|
|
3195
|
-
return this.raw;
|
|
3196
|
-
}
|
|
3197
|
-
if (this.isOmitted) {
|
|
3198
|
-
return this.raw;
|
|
3199
|
-
}
|
|
3200
|
-
let raw = this.raw;
|
|
3201
|
-
let offset = 0;
|
|
3202
|
-
const overriddenCommentNodes = this.ownerMLDocument.nodeList.filter(node => {
|
|
3203
|
-
if (node.is(node.COMMENT_NODE)) {
|
|
3204
|
-
return this.startOffset < node.startOffset && node.endOffset < this.endOffset;
|
|
3205
|
-
}
|
|
3206
|
-
return false;
|
|
3207
|
-
});
|
|
3208
|
-
const nodes = [
|
|
3209
|
-
{
|
|
3210
|
-
toString: () => this.tagOpenChar + this.fixedNodeName,
|
|
3211
|
-
startOffset: this.startOffset,
|
|
3212
|
-
endOffset: this.startOffset + this.tagOpenChar.length + this.nodeName.length,
|
|
3213
|
-
},
|
|
3214
|
-
...overriddenCommentNodes,
|
|
3215
|
-
...this.attributes,
|
|
3216
|
-
];
|
|
3217
|
-
for (const node of nodes) {
|
|
3218
|
-
const before = raw.slice(0, node.startOffset + offset - this.startOffset);
|
|
3219
|
-
const rawCode = node.toString(true);
|
|
3220
|
-
const after = raw.slice(node.endOffset + offset - this.startOffset);
|
|
3221
|
-
raw = before + rawCode + after;
|
|
3222
|
-
offset += rawCode.length - (node.endOffset - node.startOffset);
|
|
3223
|
-
}
|
|
3224
|
-
return raw;
|
|
3161
|
+
toString() {
|
|
3162
|
+
return this.raw;
|
|
3225
3163
|
}
|
|
3226
3164
|
/**
|
|
3227
3165
|
* **IT THROWS AN ERROR WHEN CALLING THIS.**
|
|
@@ -2,7 +2,7 @@ import type { MLASTToken } from '@markuplint/ml-ast';
|
|
|
2
2
|
/**
|
|
3
3
|
* Represents a single token in the markuplint AST.
|
|
4
4
|
* Wraps an AST token with positional information (line, column, offset)
|
|
5
|
-
* and provides
|
|
5
|
+
* and provides the raw string representation.
|
|
6
6
|
*
|
|
7
7
|
* @template A - The AST token type this token wraps
|
|
8
8
|
*/
|
|
@@ -40,12 +40,6 @@ export declare class MLToken<A extends MLASTToken = MLASTToken> {
|
|
|
40
40
|
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
41
41
|
*/
|
|
42
42
|
get endOffset(): number;
|
|
43
|
-
/**
|
|
44
|
-
* The fixed (potentially modified) string content of this token.
|
|
45
|
-
*
|
|
46
|
-
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
47
|
-
*/
|
|
48
|
-
get fixed(): string;
|
|
49
43
|
/**
|
|
50
44
|
* The original raw string content of this token from the source.
|
|
51
45
|
*
|
|
@@ -71,19 +65,10 @@ export declare class MLToken<A extends MLASTToken = MLASTToken> {
|
|
|
71
65
|
*/
|
|
72
66
|
get startOffset(): number;
|
|
73
67
|
/**
|
|
74
|
-
*
|
|
75
|
-
* used when applying lint fixes.
|
|
76
|
-
*
|
|
77
|
-
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
78
|
-
* @param raw - The new string content to set as the fixed value
|
|
79
|
-
*/
|
|
80
|
-
fix(raw: string): void;
|
|
81
|
-
/**
|
|
82
|
-
* Returns the string representation of this token.
|
|
68
|
+
* Returns the raw string representation of this token.
|
|
83
69
|
*
|
|
84
70
|
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
85
|
-
* @param fixed - When true, returns the fixed content; otherwise returns the original raw content
|
|
86
71
|
* @returns The string content of this token
|
|
87
72
|
*/
|
|
88
|
-
toString(
|
|
73
|
+
toString(): string;
|
|
89
74
|
}
|
|
@@ -2,12 +2,11 @@ import { getEndCol, getEndLine } from '@markuplint/parser-utils/location';
|
|
|
2
2
|
/**
|
|
3
3
|
* Represents a single token in the markuplint AST.
|
|
4
4
|
* Wraps an AST token with positional information (line, column, offset)
|
|
5
|
-
* and provides
|
|
5
|
+
* and provides the raw string representation.
|
|
6
6
|
*
|
|
7
7
|
* @template A - The AST token type this token wraps
|
|
8
8
|
*/
|
|
9
9
|
export class MLToken {
|
|
10
|
-
#fixed;
|
|
11
10
|
#raw;
|
|
12
11
|
/**
|
|
13
12
|
* The unique identifier for this token.
|
|
@@ -25,7 +24,6 @@ export class MLToken {
|
|
|
25
24
|
constructor(astToken) {
|
|
26
25
|
this._astToken = astToken;
|
|
27
26
|
this.#raw = astToken.raw;
|
|
28
|
-
this.#fixed = astToken.raw;
|
|
29
27
|
this.uuid = astToken.uuid;
|
|
30
28
|
}
|
|
31
29
|
/**
|
|
@@ -34,7 +32,7 @@ export class MLToken {
|
|
|
34
32
|
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
35
33
|
*/
|
|
36
34
|
get endCol() {
|
|
37
|
-
return getEndCol(this.
|
|
35
|
+
return getEndCol(this.raw, this.startCol);
|
|
38
36
|
}
|
|
39
37
|
/**
|
|
40
38
|
* The ending line number (1-based) of this token in the source.
|
|
@@ -42,7 +40,7 @@ export class MLToken {
|
|
|
42
40
|
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
43
41
|
*/
|
|
44
42
|
get endLine() {
|
|
45
|
-
return getEndLine(this.
|
|
43
|
+
return getEndLine(this.raw, this.startLine);
|
|
46
44
|
}
|
|
47
45
|
/**
|
|
48
46
|
* The ending character offset (0-based) of this token in the source.
|
|
@@ -50,15 +48,7 @@ export class MLToken {
|
|
|
50
48
|
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
51
49
|
*/
|
|
52
50
|
get endOffset() {
|
|
53
|
-
return this.startOffset + this.
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* The fixed (potentially modified) string content of this token.
|
|
57
|
-
*
|
|
58
|
-
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
59
|
-
*/
|
|
60
|
-
get fixed() {
|
|
61
|
-
return this.#fixed;
|
|
51
|
+
return this.startOffset + this.raw.length;
|
|
62
52
|
}
|
|
63
53
|
/**
|
|
64
54
|
* The original raw string content of this token from the source.
|
|
@@ -93,23 +83,12 @@ export class MLToken {
|
|
|
93
83
|
return this._astToken.offset;
|
|
94
84
|
}
|
|
95
85
|
/**
|
|
96
|
-
*
|
|
97
|
-
* used when applying lint fixes.
|
|
86
|
+
* Returns the raw string representation of this token.
|
|
98
87
|
*
|
|
99
88
|
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
100
|
-
* @param raw - The new string content to set as the fixed value
|
|
101
|
-
*/
|
|
102
|
-
fix(raw) {
|
|
103
|
-
this.#fixed = raw;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Returns the string representation of this token.
|
|
107
|
-
*
|
|
108
|
-
* @implements `@markuplint/ml-core` API: `MLDOMToken`
|
|
109
|
-
* @param fixed - When true, returns the fixed content; otherwise returns the original raw content
|
|
110
89
|
* @returns The string content of this token
|
|
111
90
|
*/
|
|
112
|
-
toString(
|
|
113
|
-
return
|
|
91
|
+
toString() {
|
|
92
|
+
return this.#raw;
|
|
114
93
|
}
|
|
115
94
|
}
|
package/lib/ml-rule/index.d.ts
CHANGED
package/lib/ml-rule/index.js
CHANGED
|
@@ -8,40 +8,12 @@ export declare class MLRuleContext<T extends RuleConfigValue, O extends PlainDat
|
|
|
8
8
|
readonly locale: string;
|
|
9
9
|
readonly translate: Translator;
|
|
10
10
|
constructor(document: MLDocument<T, O>, locale: LocaleSet);
|
|
11
|
-
get reports():
|
|
12
|
-
message: string;
|
|
13
|
-
line: number;
|
|
14
|
-
col: number;
|
|
15
|
-
raw: string;
|
|
16
|
-
} | {
|
|
17
|
-
message: string;
|
|
18
|
-
scope: import("@markuplint/ml-config").Scope<T, O>;
|
|
19
|
-
} | {
|
|
20
|
-
message: string;
|
|
21
|
-
scope: import("@markuplint/ml-config").Scope<T, O>;
|
|
22
|
-
line: number;
|
|
23
|
-
col: number;
|
|
24
|
-
raw: string;
|
|
25
|
-
})[];
|
|
11
|
+
get reports(): Report<T, O>[];
|
|
26
12
|
provide(): {
|
|
27
13
|
document: MLDocument<T, O>;
|
|
28
14
|
translate: Translator;
|
|
29
15
|
t: Translator;
|
|
30
|
-
reports:
|
|
31
|
-
message: string;
|
|
32
|
-
line: number;
|
|
33
|
-
col: number;
|
|
34
|
-
raw: string;
|
|
35
|
-
} | {
|
|
36
|
-
message: string;
|
|
37
|
-
scope: import("@markuplint/ml-config").Scope<T, O>;
|
|
38
|
-
} | {
|
|
39
|
-
message: string;
|
|
40
|
-
scope: import("@markuplint/ml-config").Scope<T, O>;
|
|
41
|
-
line: number;
|
|
42
|
-
col: number;
|
|
43
|
-
raw: string;
|
|
44
|
-
})[];
|
|
16
|
+
reports: Report<T, O>[];
|
|
45
17
|
report: {
|
|
46
18
|
(report: Report<T, O>): undefined;
|
|
47
19
|
(report: CheckerReport<T, O>): boolean;
|
|
@@ -49,5 +21,4 @@ export declare class MLRuleContext<T extends RuleConfigValue, O extends PlainDat
|
|
|
49
21
|
};
|
|
50
22
|
report(report: Report<T, O>): undefined;
|
|
51
23
|
report(report: CheckerReport<T, O>): boolean;
|
|
52
|
-
private _push;
|
|
53
24
|
}
|
|
@@ -3,6 +3,7 @@ export class MLRuleContext {
|
|
|
3
3
|
document;
|
|
4
4
|
locale;
|
|
5
5
|
#reports = [];
|
|
6
|
+
#reportKeys = new Set();
|
|
6
7
|
translate;
|
|
7
8
|
constructor(
|
|
8
9
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
@@ -12,10 +13,7 @@ export class MLRuleContext {
|
|
|
12
13
|
this.locale = locale.locale;
|
|
13
14
|
}
|
|
14
15
|
get reports() {
|
|
15
|
-
return this.#reports
|
|
16
|
-
...report,
|
|
17
|
-
message: finish(report.message, this.locale),
|
|
18
|
-
}));
|
|
16
|
+
return this.#reports;
|
|
19
17
|
}
|
|
20
18
|
provide() {
|
|
21
19
|
return {
|
|
@@ -30,16 +28,21 @@ export class MLRuleContext {
|
|
|
30
28
|
if (typeof report === 'function') {
|
|
31
29
|
const r = report(this.translate);
|
|
32
30
|
if (r) {
|
|
33
|
-
this
|
|
31
|
+
this.#push(r);
|
|
34
32
|
return true;
|
|
35
33
|
}
|
|
36
34
|
return false;
|
|
37
35
|
}
|
|
38
|
-
this
|
|
36
|
+
this.#push(report);
|
|
39
37
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
#push(report) {
|
|
39
|
+
const key = reportKey(report);
|
|
40
|
+
if (!this.#reportKeys.has(key)) {
|
|
41
|
+
this.#reportKeys.add(key);
|
|
42
|
+
this.#reports.push({
|
|
43
|
+
...report,
|
|
44
|
+
message: finish(report.message, this.locale),
|
|
45
|
+
});
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
}
|
|
@@ -51,15 +54,12 @@ function finish(message, locale = 'en') {
|
|
|
51
54
|
}
|
|
52
55
|
return message;
|
|
53
56
|
}
|
|
54
|
-
function
|
|
55
|
-
if ('col' in
|
|
56
|
-
return
|
|
57
|
+
function reportKey(report) {
|
|
58
|
+
if ('col' in report && report.col != null) {
|
|
59
|
+
return `${report.line}:${report.col}:${report.message}:${report.raw}`;
|
|
57
60
|
}
|
|
58
|
-
if ('scope' in
|
|
59
|
-
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
return r1.scope === r2.scope && r1.message === r2.message;
|
|
61
|
+
if ('scope' in report) {
|
|
62
|
+
return `${report.scope.startLine}:${report.scope.startCol}:${report.message}`;
|
|
63
63
|
}
|
|
64
|
-
return
|
|
64
|
+
return report.message;
|
|
65
65
|
}
|
package/lib/ml-rule/ml-rule.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { GlobalRuleInfo, SpecConformance, PlainData, Rule, RuleConfigValue,
|
|
|
12
12
|
export declare class MLRule<T extends RuleConfigValue, O extends PlainData = undefined> {
|
|
13
13
|
#private;
|
|
14
14
|
/**
|
|
15
|
-
* For virtual rules, the name of the base rule whose verify
|
|
15
|
+
* For virtual rules, the name of the base rule whose verify logic is reused.
|
|
16
16
|
* When set, violations report this as `ruleId` for backwards compatibility.
|
|
17
17
|
*/
|
|
18
18
|
readonly baseRuleId?: string;
|
|
@@ -37,24 +37,19 @@ export declare class MLRule<T extends RuleConfigValue, O extends PlainData = und
|
|
|
37
37
|
readonly groupName?: string;
|
|
38
38
|
});
|
|
39
39
|
/**
|
|
40
|
-
* Creates a virtual rule that reuses this rule's verify
|
|
40
|
+
* Creates a virtual rule that reuses this rule's verify logic
|
|
41
41
|
* under a different name (alias). Used by named nodeRules to produce
|
|
42
42
|
* independent rule instances that can be individually configured.
|
|
43
43
|
*
|
|
44
44
|
* @param aliasName - The alias name (must contain `/`)
|
|
45
45
|
* @param options - Override options for the virtual rule
|
|
46
|
-
* @returns A new MLRule instance sharing the same verify
|
|
46
|
+
* @returns A new MLRule instance sharing the same verify logic
|
|
47
47
|
*/
|
|
48
48
|
createAlias(aliasName: string, options?: {
|
|
49
49
|
readonly defaultSeverity?: Severity;
|
|
50
50
|
readonly specConformance?: SpecConformance;
|
|
51
51
|
readonly groupName?: string;
|
|
52
52
|
}): MLRule<T, O>;
|
|
53
|
-
/**
|
|
54
|
-
* The following getter is unused internally,
|
|
55
|
-
* only for extending from 3rd party library
|
|
56
|
-
*/
|
|
57
|
-
protected get f(): RuleSeed<T, O>['fix'];
|
|
58
53
|
/**
|
|
59
54
|
* The following getter is unused internally,
|
|
60
55
|
* only for extending from 3rd party library
|
|
@@ -78,16 +73,16 @@ export declare class MLRule<T extends RuleConfigValue, O extends PlainData = und
|
|
|
78
73
|
*/
|
|
79
74
|
optimizeOption(configSettings: Rule<T, O> | null | undefined): RuleInfo<T, O>;
|
|
80
75
|
/**
|
|
81
|
-
* Executes this rule's verify
|
|
76
|
+
* Executes this rule's verify function against a document,
|
|
82
77
|
* then collects and returns the resulting violations.
|
|
78
|
+
* When `fix` is true, fix callbacks on reports are executed to produce {@link FixData}.
|
|
83
79
|
*
|
|
84
80
|
* @param document - The parsed document to verify
|
|
85
81
|
* @param locale - The locale set for translating violation messages
|
|
86
|
-
* @param fix - Whether to
|
|
82
|
+
* @param fix - Whether to execute fix callbacks and attach FixData to violations
|
|
87
83
|
* @returns An array of violations found by this rule
|
|
88
84
|
*/
|
|
89
85
|
verify(document: MLDocument<T, O>, locale: LocaleSet, fix: boolean): Promise<Violation[]>;
|
|
90
|
-
private _optimize;
|
|
91
86
|
}
|
|
92
87
|
/**
|
|
93
88
|
* An MLRule with any value and option types. Used when the specific types are not known.
|