@markuplint/ml-core 5.0.0-alpha.1 → 5.0.0-alpha.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.
Files changed (39) hide show
  1. package/ARCHITECTURE.ja.md +125 -5
  2. package/ARCHITECTURE.md +125 -5
  3. package/CHANGELOG.md +14 -0
  4. package/docs/ml-dom/document.ja.md +7 -14
  5. package/docs/ml-dom/document.md +7 -14
  6. package/docs/ml-dom/element.ja.md +9 -24
  7. package/docs/ml-dom/element.md +9 -24
  8. package/docs/rule-system.ja.md +1 -1
  9. package/docs/rule-system.md +1 -1
  10. package/lib/fix-applier.d.ts +30 -0
  11. package/lib/fix-applier.js +70 -0
  12. package/lib/index.d.ts +2 -0
  13. package/lib/index.js +1 -0
  14. package/lib/ml-core.d.ts +14 -2
  15. package/lib/ml-core.js +25 -4
  16. package/lib/ml-dom/helper/get-indent.d.ts +0 -1
  17. package/lib/ml-dom/helper/get-indent.js +5 -18
  18. package/lib/ml-dom/node/attr.d.ts +2 -13
  19. package/lib/ml-dom/node/attr.js +3 -35
  20. package/lib/ml-dom/node/document.d.ts +2 -13
  21. package/lib/ml-dom/node/document.js +3 -41
  22. package/lib/ml-dom/node/element-close-tag.d.ts +1 -1
  23. package/lib/ml-dom/node/element-close-tag.js +2 -16
  24. package/lib/ml-dom/node/element.d.ts +2 -19
  25. package/lib/ml-dom/node/element.js +3 -62
  26. package/lib/ml-dom/token/token.d.ts +3 -18
  27. package/lib/ml-dom/token/token.js +7 -28
  28. package/lib/ml-rule/index.d.ts +1 -0
  29. package/lib/ml-rule/index.js +1 -0
  30. package/lib/ml-rule/ml-rule-context.d.ts +2 -30
  31. package/lib/ml-rule/ml-rule-context.js +15 -15
  32. package/lib/ml-rule/ml-rule.d.ts +6 -10
  33. package/lib/ml-rule/ml-rule.js +32 -33
  34. package/lib/ml-rule/rule-fixer.d.ts +25 -0
  35. package/lib/ml-rule/rule-fixer.js +32 -0
  36. package/lib/ml-rule/types.d.ts +1 -2
  37. package/lib/test/index.d.ts +1 -10
  38. package/lib/test/index.js +0 -11
  39. package/package.json +12 -12
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Applies a set of text edits to the source code.
3
+ *
4
+ * **Constraint**: Edits within a single FixData must not overlap each other,
5
+ * and should ideally be ordered by range[0]. Inter-FixData overlap is handled
6
+ * by the skip mechanism, but intra-FixData overlap leads to undefined behavior.
7
+ *
8
+ * Algorithm (modeled after ESLint's SourceCodeFixer):
9
+ * 1. Flatten all FixData.edits into individual edits, each tagged with its parent FixData
10
+ * 2. Sort by range[0] ascending (ties broken by range[1] descending)
11
+ * 3. Apply edits sequentially; skip any edit whose range overlaps a previously applied edit
12
+ * 4. Classify each FixData as applied (all edits applied) or skipped (any edit skipped)
13
+ *
14
+ * @param sourceCode - The original source code
15
+ * @param fixes - The fix data to apply
16
+ * @returns The result containing the fixed code and applied/skipped classification
17
+ */
18
+ export function applyFixes(sourceCode, fixes) {
19
+ if (fixes.length === 0) {
20
+ return { output: sourceCode, applied: [], skipped: [] };
21
+ }
22
+ // Tag each edit with its parent FixData index
23
+ const taggedEdits = [];
24
+ for (const [i, fix] of fixes.entries()) {
25
+ for (const edit of fix.edits) {
26
+ taggedEdits.push({ edit, fixIndex: i });
27
+ }
28
+ }
29
+ // Sort: range[0] ascending, then range[1] descending (so larger ranges come first at the same start)
30
+ taggedEdits.sort((a, b) => {
31
+ const startDiff = a.edit.range[0] - b.edit.range[0];
32
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
33
+ return startDiff || b.edit.range[1] - a.edit.range[1];
34
+ });
35
+ // Track which FixData indices had at least one skipped edit
36
+ const skippedFixIndices = new Set();
37
+ let lastAppliedEnd = -1;
38
+ const parts = [];
39
+ let cursor = 0;
40
+ for (const { edit, fixIndex } of taggedEdits) {
41
+ const [start, end] = edit.range;
42
+ // Overlap check: if this edit starts before the end of the last applied edit, skip it
43
+ if (start < lastAppliedEnd) {
44
+ skippedFixIndices.add(fixIndex);
45
+ continue;
46
+ }
47
+ // Append the source text between the last edit and this one
48
+ parts.push(sourceCode.slice(cursor, start), edit.text);
49
+ cursor = end;
50
+ lastAppliedEnd = end;
51
+ }
52
+ // Append remaining source text
53
+ parts.push(sourceCode.slice(cursor));
54
+ // Classify FixData as applied or skipped
55
+ const applied = [];
56
+ const skipped = [];
57
+ for (const [i, fix] of fixes.entries()) {
58
+ if (skippedFixIndices.has(i)) {
59
+ skipped.push(fix);
60
+ }
61
+ else {
62
+ applied.push(fix);
63
+ }
64
+ }
65
+ return {
66
+ output: parts.join(''),
67
+ applied,
68
+ skipped,
69
+ };
70
+ }
package/lib/index.d.ts CHANGED
@@ -2,6 +2,8 @@ export type { RuleInfo, RuleConfig, RuleConfigValue } from '@markuplint/ml-confi
2
2
  export { ariaSpecs, contentModelCategoryToTagNames, getAttrSpecs, getComputedRole, getImplicitRole, getPermittedRoles, getRoleSpec, getSpec, resolveNamespace, } from '@markuplint/ml-spec';
3
3
  export { Ruleset } from './ruleset/index.js';
4
4
  export { enableDebug } from './debug.js';
5
+ export { applyFixes } from './fix-applier.js';
6
+ export type { FixResult } from './fix-applier.js';
5
7
  export { getIndent } from './ml-dom/helper/get-indent.js';
6
8
  export * from './convert-ruleset.js';
7
9
  export * from './ml-core.js';
package/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { ariaSpecs, contentModelCategoryToTagNames, getAttrSpecs, getComputedRole, getImplicitRole, getPermittedRoles, getRoleSpec, getSpec, resolveNamespace, } from '@markuplint/ml-spec';
2
2
  export { Ruleset } from './ruleset/index.js';
3
3
  export { enableDebug } from './debug.js';
4
+ export { applyFixes } from './fix-applier.js';
4
5
  export { getIndent } from './ml-dom/helper/get-indent.js';
5
6
  export * from './convert-ruleset.js';
6
7
  export * from './ml-core.js';
package/lib/ml-core.d.ts CHANGED
@@ -2,6 +2,15 @@ import type { MLFabric } from './types.js';
2
2
  import type { PlainData, RuleConfigValue, Violation } from '@markuplint/ml-config';
3
3
  import { ParserError } from '@markuplint/parser-utils';
4
4
  import { Document } from './ml-dom/index.js';
5
+ /**
6
+ * The result of running {@link MLCore.verify}.
7
+ */
8
+ export type VerifyResult = {
9
+ /** Violations found during verification */
10
+ readonly violations: readonly Violation[];
11
+ /** The source code after applying fixes. `undefined` when fix is not enabled. */
12
+ readonly fixedCode: string | undefined;
13
+ };
5
14
  /**
6
15
  * Parameters for constructing an {@link MLCore} instance.
7
16
  * Extends {@link MLFabric} with the source code, filename, and debug flag.
@@ -46,10 +55,13 @@ export declare class MLCore {
46
55
  * If the document failed to parse, a single parse-error violation is returned
47
56
  * (unless parse errors are suppressed via severity options).
48
57
  *
58
+ * When `fix` is true, fix callbacks are executed and the resulting TextEdits
59
+ * are applied to produce `fixedCode`.
60
+ *
49
61
  * @param fix - Whether to attempt auto-fixing violations
50
- * @returns An array of violations found during verification
62
+ * @returns Violations and the (possibly fixed) source code
51
63
  */
52
- verify(fix?: boolean): Promise<Violation[]>;
64
+ verify(fix?: boolean): Promise<VerifyResult>;
53
65
  private _createDocument;
54
66
  private _createParseError;
55
67
  private _parse;
package/lib/ml-core.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ParserError } from '@markuplint/parser-utils';
2
2
  import { log, enableDebug } from './debug.js';
3
+ import { applyFixes } from './fix-applier.js';
3
4
  import { Document } from './ml-dom/index.js';
4
5
  import { expandNamedNodeRules, expandNamedRules } from './virtual-rule.js';
5
6
  const resultLog = log.extend('result');
@@ -138,8 +139,11 @@ export class MLCore {
138
139
  * If the document failed to parse, a single parse-error violation is returned
139
140
  * (unless parse errors are suppressed via severity options).
140
141
  *
142
+ * When `fix` is true, fix callbacks are executed and the resulting TextEdits
143
+ * are applied to produce `fixedCode`.
144
+ *
141
145
  * @param fix - Whether to attempt auto-fixing violations
142
- * @returns An array of violations found during verification
146
+ * @returns Violations and the (possibly fixed) source code
143
147
  */
144
148
  async verify(fix = false) {
145
149
  log('verify: start');
@@ -147,11 +151,11 @@ export class MLCore {
147
151
  if (this.#document instanceof ParserError) {
148
152
  const parseError = this._createParseError(this.#document.message, this.#document.line, this.#document.col, this.#document.raw);
149
153
  if (!parseError) {
150
- return [];
154
+ return { violations: [], fixedCode: fix ? this.#sourceCode : undefined };
151
155
  }
152
156
  violations.push(parseError);
153
157
  log('verify: error %o', this.#document.message);
154
- return violations;
158
+ return { violations, fixedCode: fix ? this.#sourceCode : undefined };
155
159
  }
156
160
  const definedRuleName = new Set(this.#rules.map(rule => rule.name));
157
161
  const setRuleNames = new Set([
@@ -236,8 +240,25 @@ export class MLCore {
236
240
  resultLog('Warning: %d', w);
237
241
  resultLog('Info: %d', i);
238
242
  }
243
+ // Apply fixes if enabled
244
+ let fixedCode;
245
+ if (fix) {
246
+ fixedCode = this.#sourceCode;
247
+ const allFixes = [];
248
+ for (const v of violations) {
249
+ if (v.fix) {
250
+ allFixes.push(v.fix);
251
+ }
252
+ }
253
+ if (allFixes.length > 0) {
254
+ const result = applyFixes(this.#sourceCode, allFixes);
255
+ fixedCode = result.output;
256
+ // TODO(Phase 2): If skipped fixes exist, implement multi-pass re-verify loop
257
+ // (similar to ESLint's 10-pass fix loop) to resolve conflicts iteratively.
258
+ }
259
+ }
239
260
  log('verify: end');
240
- return violations;
261
+ return { violations, fixedCode };
241
262
  }
242
263
  _createDocument() {
243
264
  if (!this.#ast) {
@@ -16,6 +16,5 @@ declare class MLDOMIndentation {
16
16
  get raw(): string;
17
17
  get type(): 'tab' | 'space' | 'mixed' | 'none';
18
18
  get width(): number;
19
- fix(raw: string): void;
20
19
  }
21
20
  export {};
@@ -39,7 +39,6 @@ node) {
39
39
  const matched = isFirstToken(prevToken)
40
40
  ? prevToken.raw.match(/^(?:[\t ]*\r?\n)*([\t ]*)$/)
41
41
  : prevToken.raw.match(/\r?\n([\t ]*)$/);
42
- // console.log({ [`${this}`]: matched, _: prevToken.raw, f: prevToken._isFirstToken() });
43
42
  if (matched) {
44
43
  // Spaces will include empty string.
45
44
  const spaces = matched[1];
@@ -50,7 +49,7 @@ node) {
50
49
  return null;
51
50
  }
52
51
  class MLDOMIndentation {
53
- #fixed;
52
+ #raw;
54
53
  line;
55
54
  #node;
56
55
  #parent;
@@ -62,38 +61,26 @@ class MLDOMIndentation {
62
61
  this.line = line;
63
62
  this.#node = originTextNode;
64
63
  this.#parent = parentNode;
65
- this.#fixed = raw;
64
+ this.#raw = raw;
66
65
  }
67
66
  get raw() {
68
67
  if (!this.#parent.is(this.#parent.TEXT_NODE) && this.line !== this.#node.endLine) {
69
68
  return '';
70
69
  }
71
- return this.#fixed;
70
+ return this.#raw;
72
71
  }
73
72
  get type() {
74
73
  if (!this.#parent.is(this.#parent.TEXT_NODE) && this.line !== this.#node.endLine) {
75
74
  return 'none';
76
75
  }
77
- const raw = this.#fixed;
76
+ const raw = this.#raw;
78
77
  return raw === '' ? 'none' : /^\t+$/.test(raw) ? 'tab' : /^[^\t]+$/.test(raw) ? 'space' : 'mixed';
79
78
  }
80
79
  get width() {
81
80
  if (!this.#parent.is(this.#parent.TEXT_NODE) && this.line !== this.#node.endLine) {
82
81
  return 0;
83
82
  }
84
- return this.#fixed.length;
85
- }
86
- fix(raw) {
87
- const current = this.#fixed;
88
- this.#fixed = raw;
89
- const node = this.#node;
90
- const line = node.startLine;
91
- const lines = node.raw.split(/\r?\n/);
92
- const index = this.line - line;
93
- if (lines[index] != null) {
94
- lines[index] = lines[index].replace(current, this.#fixed);
95
- }
96
- node.fix(lines.join('\n'));
83
+ return this.#raw.length;
97
84
  }
98
85
  }
99
86
  function isFirstToken(
@@ -152,15 +152,6 @@ export declare class MLAttr<T extends RuleConfigValue, O extends PlainData = und
152
152
  * @see https://dom.spec.whatwg.org/#dom-attr-value
153
153
  */
154
154
  get value(): string;
155
- /**
156
- * Fixes the attribute value.
157
- * If the attribute is not a spread attribute, it calls the `fix` method of the `valueNode`.
158
- *
159
- * @implements `@markuplint/ml-core` API: `MLAttr`
160
- *
161
- * @param raw - The raw attribute value.
162
- */
163
- fix(raw: string): void;
164
155
  /**
165
156
  * Returns a normalized string representation of the attribute,
166
157
  * stripping extraneous whitespace around the name, equal sign, and value tokens.
@@ -171,12 +162,10 @@ export declare class MLAttr<T extends RuleConfigValue, O extends PlainData = und
171
162
  */
172
163
  toNormalizeString(): string;
173
164
  /**
174
- * Returns a string representation of the attribute.
165
+ * Returns the raw string representation of the attribute.
175
166
  *
176
167
  * @implements DOM API: `Attr`
177
- *
178
- * @param includesSpacesBeforeName - Whether to include spaces before the attribute name.
179
168
  * @returns The string representation of the attribute.
180
169
  */
181
- toString(fixed?: boolean): string;
170
+ toString(): string;
182
171
  }
@@ -251,21 +251,6 @@ export class MLAttr extends MLNode {
251
251
  get value() {
252
252
  return this.#potentialValue;
253
253
  }
254
- /**
255
- * Fixes the attribute value.
256
- * If the attribute is not a spread attribute, it calls the `fix` method of the `valueNode`.
257
- *
258
- * @implements `@markuplint/ml-core` API: `MLAttr`
259
- *
260
- * @param raw - The raw attribute value.
261
- */
262
- fix(raw) {
263
- if (this.localName === '#spread') {
264
- return;
265
- }
266
- // `valueNode` is not null when it is no spread.
267
- this.valueNode?.fix(raw);
268
- }
269
254
  /**
270
255
  * Returns a normalized string representation of the attribute,
271
256
  * stripping extraneous whitespace around the name, equal sign, and value tokens.
@@ -281,29 +266,12 @@ export class MLAttr extends MLNode {
281
266
  return this.raw;
282
267
  }
283
268
  /**
284
- * Returns a string representation of the attribute.
269
+ * Returns the raw string representation of the attribute.
285
270
  *
286
271
  * @implements DOM API: `Attr`
287
- *
288
- * @param includesSpacesBeforeName - Whether to include spaces before the attribute name.
289
272
  * @returns The string representation of the attribute.
290
273
  */
291
- toString(fixed = false) {
292
- if (!fixed) {
293
- return this.raw;
294
- }
295
- if (this.localName === '#spread') {
296
- return this.raw;
297
- }
298
- const tokens = [this.nameNode?.toString(true) ?? ''];
299
- if (this.equal && this.equal.toString(true) !== '') {
300
- tokens.push(this.spacesBeforeEqual?.toString(true) ?? '', this.equal?.toString(true) ?? '', this.spacesAfterEqual?.toString(true) ?? '', this.startQuote?.toString(true) ?? '', this.valueNode?.toString(true) ?? '', this.endQuote?.toString(true) ?? '');
301
- }
302
- else if (this.valueNode && this.valueNode.toString(true) !== '') {
303
- tokens.push(
304
- //
305
- '=', this.startQuote?.toString(true) || '"', this.valueNode.toString(true), this.endQuote?.toString(true) || '"');
306
- }
307
- return tokens.join('');
274
+ toString() {
275
+ return this.raw;
308
276
  }
309
277
  }
@@ -1577,14 +1577,6 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
1577
1577
  * @implements DOM API: `Document`
1578
1578
  */
1579
1579
  getSelection(): Selection | null;
1580
- /**
1581
- * Returns a flat, offset-sorted list of all tokens in the document,
1582
- * including element close tags. The result is cached after the first call.
1583
- *
1584
- * @implements `@markuplint/ml-core` API: `MLDocument`
1585
- * @returns A frozen array of tokens sorted by their starting offset
1586
- */
1587
- getTokenList(): readonly MLToken<import("@markuplint/ml-ast").MLASTToken>[];
1588
1580
  /**
1589
1581
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
1590
1582
  *
@@ -1693,15 +1685,12 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
1693
1685
  */
1694
1686
  startViewTransition(callbackOptions?: ViewTransitionUpdateCallback): ViewTransition;
1695
1687
  /**
1696
- * Returns a string representation of the entire document. When `fixed` is true,
1697
- * returns the document with all lint fixes applied by substituting
1698
- * fixed token content at the appropriate offsets.
1688
+ * Returns the raw string representation of the document.
1699
1689
  *
1700
1690
  * @implements `@markuplint/ml-core` API: `MLDocument`
1701
- * @param fixed - When true, returns the fixed content; otherwise returns the original raw content
1702
1691
  * @returns The string content of the document
1703
1692
  */
1704
- toString(fixed?: boolean): string;
1693
+ toString(): string;
1705
1694
  /**
1706
1695
  * Walks the document tree, visiting nodes of the specified type and invoking
1707
1696
  * the walker callback for each one. Supports walking Element, Text, Comment,
@@ -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
@@ -2088,27 +2087,6 @@ export class MLDocument extends MLParentNode {
2088
2087
  getSelection() {
2089
2088
  throw new UnexpectedCallError('Not supported "getSelection" method');
2090
2089
  }
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
2090
  /**
2113
2091
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
2114
2092
  *
@@ -2250,29 +2228,13 @@ export class MLDocument extends MLParentNode {
2250
2228
  throw new UnexpectedCallError('Not supported "startViewTransition" method');
2251
2229
  }
2252
2230
  /**
2253
- * Returns a string representation of the entire document. When `fixed` is true,
2254
- * returns the document with all lint fixes applied by substituting
2255
- * fixed token content at the appropriate offsets.
2231
+ * Returns the raw string representation of the document.
2256
2232
  *
2257
2233
  * @implements `@markuplint/ml-core` API: `MLDocument`
2258
- * @param fixed - When true, returns the fixed content; otherwise returns the original raw content
2259
2234
  * @returns The string content of the document
2260
2235
  */
2261
- toString(fixed = false) {
2262
- if (!fixed) {
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;
2236
+ toString() {
2237
+ return this.raw;
2276
2238
  }
2277
2239
  walkOn(type, walker, skipWhenRuleIsDisabled = true) {
2278
2240
  return sequentialWalker(this.nodeList, node => {
@@ -16,5 +16,5 @@ export declare class MLElementCloseTag<T extends RuleConfigValue, O extends Plai
16
16
  * @implements `@markuplint/ml-core` API: `MLElement`
17
17
  */
18
18
  get rawName(): string;
19
- toString(fixed?: boolean): string;
19
+ toString(): string;
20
20
  }
@@ -23,21 +23,7 @@ export class MLElementCloseTag extends MLNode {
23
23
  get rawName() {
24
24
  return this._astToken.nodeName;
25
25
  }
26
- toString(fixed = false) {
27
- if (!fixed) {
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 a string representation of this element. When `fixed` is true,
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(fixed?: boolean): string;
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
  *
@@ -3176,52 +3156,13 @@ export class MLElement extends MLParentNode {
3176
3156
  return normalizedString;
3177
3157
  }
3178
3158
  /**
3179
- * Returns a string representation of this element. When `fixed` is true,
3180
- * returns the element with any lint fixes applied to the tag name,
3181
- * attributes, and embedded comment nodes.
3159
+ * Returns the raw string representation of this element.
3182
3160
  *
3183
3161
  * @implements `@markuplint/ml-core` API: `MLElement`
3184
- * @param fixed - When true, returns the fixed content; otherwise returns the original raw content
3185
3162
  * @returns The string content of this element
3186
3163
  */
3187
- toString(fixed = false) {
3188
- if (!fixed) {
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;
3164
+ toString() {
3165
+ return this.raw;
3225
3166
  }
3226
3167
  /**
3227
3168
  * **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 both raw and fixed string representations.
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
- * Replaces the fixed content of this token with the given string,
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(fixed?: boolean): string;
73
+ toString(): string;
89
74
  }