@markuplint/pug-parser 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/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/parser.d.ts +4 -29
- package/lib/parser.js +32 -35
- package/lib/pug-parser/index.d.ts +0 -9
- package/lib/pug-parser/index.js +6 -104
- package/lib/types.d.ts +0 -29
- package/lib/utils/get-offset-from-line-and-col.d.ts +1 -8
- package/lib/utils/get-offset-from-line-and-col.js +1 -8
- package/package.json +6 -6
- package/ARCHITECTURE.ja.md +0 -438
- package/ARCHITECTURE.md +0 -438
- package/SKILL.md +0 -118
- package/docs/maintenance.ja.md +0 -188
- package/docs/maintenance.md +0 -188
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
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.5](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.4...v5.0.0-rc.5) (2026-08-28)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **markdown-parser,pug-parser:** force fragment parsing for embedded HTML ([57c4172](https://github.com/markuplint/markuplint/commit/57c4172d5a68adb7e20a4f4e4d8dbe802983e3ca)), closes [#3844](https://github.com/markuplint/markuplint/issues/3844)
|
|
11
|
+
- **markdown-parser,pug-parser:** forward embedded HTML parseErrors to outer document ([9ec7988](https://github.com/markuplint/markuplint/commit/9ec79882840cbedd76c5b8f774ff10c876d2c858)), closes [#3844](https://github.com/markuplint/markuplint/issues/3844)
|
|
12
|
+
|
|
13
|
+
# [5.0.0-rc.4](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.3...v5.0.0-rc.4) (2026-04-19)
|
|
14
|
+
|
|
15
|
+
**Note:** Version bump only for package @markuplint/pug-parser
|
|
16
|
+
|
|
17
|
+
# [5.0.0-rc.3](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.2...v5.0.0-rc.3) (2026-04-19)
|
|
18
|
+
|
|
19
|
+
**Note:** Version bump only for package @markuplint/pug-parser
|
|
20
|
+
|
|
6
21
|
# [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
22
|
|
|
8
23
|
**Note:** Version bump only for package @markuplint/pug-parser
|
package/lib/index.d.ts
CHANGED
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
* Pug template parser for markuplint. Provides a parser that transforms Pug (formerly Jade)
|
|
4
4
|
* template syntax into markuplint's AST, handling indentation-based nesting, tag interpolation,
|
|
5
5
|
* inline HTML, Pug attributes, mixins, conditionals, and other Pug-specific constructs.
|
|
6
|
+
* The upstream pug-lexer and pug-parser dependencies implement the Pug 3 syntax specification.
|
|
6
7
|
*/
|
|
7
8
|
export { parser } from './parser.js';
|
package/lib/index.js
CHANGED
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
* Pug template parser for markuplint. Provides a parser that transforms Pug (formerly Jade)
|
|
4
4
|
* template syntax into markuplint's AST, handling indentation-based nesting, tag interpolation,
|
|
5
5
|
* inline HTML, Pug attributes, mixins, conditionals, and other Pug-specific constructs.
|
|
6
|
+
* The upstream pug-lexer and pug-parser dependencies implement the Pug 3 syntax specification.
|
|
6
7
|
*/
|
|
7
8
|
export { parser } from './parser.js';
|
package/lib/parser.d.ts
CHANGED
|
@@ -17,30 +17,8 @@ declare class PugParser extends Parser<ASTNode> {
|
|
|
17
17
|
isFragment: boolean;
|
|
18
18
|
};
|
|
19
19
|
parseError(error: any): ParserError;
|
|
20
|
-
/**
|
|
21
|
-
* Converts a Pug AST node into markuplint node tree items.
|
|
22
|
-
* Handles Doctype, Text (including inline HTML and tag interpolation),
|
|
23
|
-
* Comment, BlockComment, Tag (with attributes and child blocks),
|
|
24
|
-
* and other Pug-specific constructs (mixins, conditionals, etc.)
|
|
25
|
-
* which are mapped to preprocessor-specific blocks.
|
|
26
|
-
*
|
|
27
|
-
* @param originNode - The Pug AST node to convert
|
|
28
|
-
* @param parentNode - The parent node in the markuplint tree, or null for root nodes
|
|
29
|
-
* @param depth - The nesting depth of the node
|
|
30
|
-
* @returns An array of markuplint node tree items
|
|
31
|
-
*/
|
|
32
20
|
nodeize(originNode: ASTNode, parentNode: MLASTParentNode | null, depth: number): readonly MLASTNodeTreeItem[];
|
|
33
21
|
afterFlattenNodes(nodeList: readonly MLASTNodeTreeItem[]): readonly MLASTNodeTreeItem[];
|
|
34
|
-
/**
|
|
35
|
-
* Visits an element token for Pug, constructing a start tag node with
|
|
36
|
-
* pre-parsed attributes (including `&attributes` spread syntax) and
|
|
37
|
-
* visiting child nodes within the Pug block.
|
|
38
|
-
*
|
|
39
|
-
* @param token - The child token with tag metadata
|
|
40
|
-
* @param childNodes - The child Pug AST nodes within the tag's block
|
|
41
|
-
* @param options - Options containing pre-parsed attribute overrides
|
|
42
|
-
* @returns An array of markuplint node tree items for the element and its children
|
|
43
|
-
*/
|
|
44
22
|
visitElement(token: ChildToken & {
|
|
45
23
|
readonly nodeName: string;
|
|
46
24
|
readonly isFragment: false;
|
|
@@ -49,15 +27,12 @@ declare class PugParser extends Parser<ASTNode> {
|
|
|
49
27
|
readonly attributes: readonly MLASTAttr[];
|
|
50
28
|
};
|
|
51
29
|
}): MLASTNodeTreeItem[];
|
|
52
|
-
visitSpreadAttr(): null;
|
|
53
30
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* @param token - The token representing the attribute
|
|
59
|
-
* @returns The parsed attribute node with Pug-specific metadata
|
|
31
|
+
* Intentionally a no-op: `&attributes` spread syntax is converted inline
|
|
32
|
+
* in the `Tag` case of `nodeize()`, so the base-class spread attribute
|
|
33
|
+
* visitor must not produce a node.
|
|
60
34
|
*/
|
|
35
|
+
visitSpreadAttr(): null;
|
|
61
36
|
visitAttr(token: Token): MLASTAttr;
|
|
62
37
|
}
|
|
63
38
|
export declare const parser: PugParser;
|
package/lib/parser.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { HtmlParser } from '@markuplint/html-parser';
|
|
2
2
|
import { ParserError, Parser, AttrState, scriptParser, getNamespace } from '@markuplint/parser-utils';
|
|
3
3
|
import { pugParse } from './pug-parser/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* Internal HTML parser used for inline HTML content within Pug templates.
|
|
6
|
-
* Extends the standard HTML parser to handle Pug tag interpolation syntax (`#[...]`),
|
|
7
|
-
* treating interpolated tags as preprocessor-specific blocks.
|
|
8
|
-
*/
|
|
9
4
|
class HtmlInPugParser extends HtmlParser {
|
|
10
5
|
constructor() {
|
|
11
6
|
super({
|
|
@@ -35,6 +30,7 @@ class HtmlInPugParser extends HtmlParser {
|
|
|
35
30
|
class PugParser extends Parser {
|
|
36
31
|
constructor() {
|
|
37
32
|
super({
|
|
33
|
+
// Pug expresses nesting through indentation and never emits explicit closing tags.
|
|
38
34
|
endTagType: 'never',
|
|
39
35
|
});
|
|
40
36
|
}
|
|
@@ -56,18 +52,6 @@ class PugParser extends Parser {
|
|
|
56
52
|
}
|
|
57
53
|
return super.parseError(error);
|
|
58
54
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Converts a Pug AST node into markuplint node tree items.
|
|
61
|
-
* Handles Doctype, Text (including inline HTML and tag interpolation),
|
|
62
|
-
* Comment, BlockComment, Tag (with attributes and child blocks),
|
|
63
|
-
* and other Pug-specific constructs (mixins, conditionals, etc.)
|
|
64
|
-
* which are mapped to preprocessor-specific blocks.
|
|
65
|
-
*
|
|
66
|
-
* @param originNode - The Pug AST node to convert
|
|
67
|
-
* @param parentNode - The parent node in the markuplint tree, or null for root nodes
|
|
68
|
-
* @param depth - The nesting depth of the node
|
|
69
|
-
* @returns An array of markuplint node tree items
|
|
70
|
-
*/
|
|
71
55
|
nodeize(
|
|
72
56
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
73
57
|
originNode, parentNode, depth) {
|
|
@@ -79,6 +63,8 @@ class PugParser extends Parser {
|
|
|
79
63
|
depth,
|
|
80
64
|
parentNode,
|
|
81
65
|
name: originNode.raw ?? '',
|
|
66
|
+
// Pug doctypes use shorthand keywords (e.g. `doctype html`),
|
|
67
|
+
// so no public/system IDs exist in the source.
|
|
82
68
|
publicId: '',
|
|
83
69
|
systemId: '',
|
|
84
70
|
});
|
|
@@ -99,7 +85,17 @@ class PugParser extends Parser {
|
|
|
99
85
|
offsetLine: originNode.line,
|
|
100
86
|
offsetColumn: originNode.column ?? parentNode?.col,
|
|
101
87
|
depth,
|
|
88
|
+
// HTML emitted by a single Pug line is always a partial —
|
|
89
|
+
// Pug itself owns the document boundary (`doctype html`,
|
|
90
|
+
// `html(...)`, etc.). Force fragment parsing so parse5
|
|
91
|
+
// doesn't fire `missing-doctype` on every inline HTML
|
|
92
|
+
// chunk.
|
|
93
|
+
documentMode: 'fragment',
|
|
102
94
|
});
|
|
95
|
+
// Surface tokenizer-level parse errors from the embedded
|
|
96
|
+
// HtmlInPugParser so users who opt in via
|
|
97
|
+
// `severity.parseError` see them on the outer Pug document.
|
|
98
|
+
this.accumulateParseErrors(htmlDoc.parseErrors);
|
|
103
99
|
const newNodeList = [];
|
|
104
100
|
for (const node of htmlDoc.nodeList) {
|
|
105
101
|
if (node.nodeName === '#ps:tag-interpolation') {
|
|
@@ -147,6 +143,10 @@ class PugParser extends Parser {
|
|
|
147
143
|
attr.offset === attr.endOffset &&
|
|
148
144
|
typeof attr.val === 'string') {
|
|
149
145
|
/**
|
|
146
|
+
* pug-parser reports shorthand `#id`/`.class` attributes with a
|
|
147
|
+
* zero-width location span (offset === endOffset), so the end
|
|
148
|
+
* offset must be recalculated from the value length.
|
|
149
|
+
*
|
|
150
150
|
* #value =>
|
|
151
151
|
* {
|
|
152
152
|
* name: 'id',
|
|
@@ -221,16 +221,6 @@ class PugParser extends Parser {
|
|
|
221
221
|
exposeWhiteSpace: false,
|
|
222
222
|
});
|
|
223
223
|
}
|
|
224
|
-
/**
|
|
225
|
-
* Visits an element token for Pug, constructing a start tag node with
|
|
226
|
-
* pre-parsed attributes (including `&attributes` spread syntax) and
|
|
227
|
-
* visiting child nodes within the Pug block.
|
|
228
|
-
*
|
|
229
|
-
* @param token - The child token with tag metadata
|
|
230
|
-
* @param childNodes - The child Pug AST nodes within the tag's block
|
|
231
|
-
* @param options - Options containing pre-parsed attribute overrides
|
|
232
|
-
* @returns An array of markuplint node tree items for the element and its children
|
|
233
|
-
*/
|
|
234
224
|
visitElement(token,
|
|
235
225
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
236
226
|
childNodes, options) {
|
|
@@ -253,17 +243,14 @@ class PugParser extends Parser {
|
|
|
253
243
|
const siblings = this.visitChildren(childNodes, startTag);
|
|
254
244
|
return [startTag, ...siblings];
|
|
255
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* Intentionally a no-op: `&attributes` spread syntax is converted inline
|
|
248
|
+
* in the `Tag` case of `nodeize()`, so the base-class spread attribute
|
|
249
|
+
* visitor must not produce a node.
|
|
250
|
+
*/
|
|
256
251
|
visitSpreadAttr() {
|
|
257
252
|
return null;
|
|
258
253
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Visits an attribute token, handling Pug-specific syntax including
|
|
261
|
-
* shorthand `#id` and `.class` notation, quoted attribute names,
|
|
262
|
-
* unescaped attribute names (trailing `!`), and JavaScript expression values.
|
|
263
|
-
*
|
|
264
|
-
* @param token - The token representing the attribute
|
|
265
|
-
* @returns The parsed attribute node with Pug-specific metadata
|
|
266
|
-
*/
|
|
267
254
|
visitAttr(token) {
|
|
268
255
|
if (token.raw[0] === '#' || token.raw[0] === '.') {
|
|
269
256
|
const attr = super.visitAttr(token, {
|
|
@@ -293,11 +280,21 @@ class PugParser extends Parser {
|
|
|
293
280
|
if (attr.name.raw.toLowerCase() === 'class') {
|
|
294
281
|
this.updateAttr(attr, { isDuplicatable: true });
|
|
295
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Pug allows attribute names to be wrapped in quotes (e.g. `'data-value'="foo"`).
|
|
285
|
+
*
|
|
286
|
+
* @see https://pugjs.org/language/attributes.html#quoted-attributes
|
|
287
|
+
*/
|
|
296
288
|
if (attr.name.raw.startsWith("'") && attr.name.raw.endsWith("'")) {
|
|
297
289
|
this.updateAttr(attr, {
|
|
298
290
|
potentialName: attr.name.raw.slice(1, -1),
|
|
299
291
|
});
|
|
300
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* A trailing `!` on the attribute name marks the value as unescaped.
|
|
295
|
+
*
|
|
296
|
+
* @see https://pugjs.org/language/attributes.html#unescaped-attributes
|
|
297
|
+
*/
|
|
301
298
|
if (attr.name.raw.endsWith('!')) {
|
|
302
299
|
this.updateAttr(attr, {
|
|
303
300
|
potentialName: attr.name.raw.slice(0, -1),
|
|
@@ -1,11 +1,2 @@
|
|
|
1
1
|
import type { ASTBlock } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Parses a Pug template string into an optimized AST with computed offsets
|
|
4
|
-
* and location data by lexing with pug-lexer, parsing with pug-parser,
|
|
5
|
-
* and then enriching each node with raw source, offsets, and end positions.
|
|
6
|
-
*
|
|
7
|
-
* @param pug - The raw Pug template source code
|
|
8
|
-
* @param useOffset - Whether to strip indent/outdent tokens (used when parsing at a non-zero offset)
|
|
9
|
-
* @returns The optimized Pug AST block containing enriched nodes
|
|
10
|
-
*/
|
|
11
2
|
export declare function pugParse(pug: string, useOffset?: boolean): ASTBlock;
|
package/lib/pug-parser/index.js
CHANGED
|
@@ -3,19 +3,13 @@ import lexer from 'pug-lexer';
|
|
|
3
3
|
import parser from 'pug-parser';
|
|
4
4
|
import { getOffsetFromLineAndCol } from '../utils/get-offset-from-line-and-col.js';
|
|
5
5
|
import { getOffsetsFromCode } from '@markuplint/parser-utils/location';
|
|
6
|
-
/**
|
|
7
|
-
* Parses a Pug template string into an optimized AST with computed offsets
|
|
8
|
-
* and location data by lexing with pug-lexer, parsing with pug-parser,
|
|
9
|
-
* and then enriching each node with raw source, offsets, and end positions.
|
|
10
|
-
*
|
|
11
|
-
* @param pug - The raw Pug template source code
|
|
12
|
-
* @param useOffset - Whether to strip indent/outdent tokens (used when parsing at a non-zero offset)
|
|
13
|
-
* @returns The optimized Pug AST block containing enriched nodes
|
|
14
|
-
*/
|
|
15
6
|
export function pugParse(pug, useOffset = false) {
|
|
16
7
|
let lexOrigin = lexer(pug);
|
|
17
8
|
/**
|
|
18
|
-
* Exclude indent and outdent tokens when offset is received to avoid indentation errors
|
|
9
|
+
* Exclude indent and outdent tokens when offset is received to avoid indentation errors:
|
|
10
|
+
* a sub-template parsed at a non-zero offset (e.g. tag interpolation content) inherits
|
|
11
|
+
* its indentation context from the parent template, so its own indent/outdent tokens
|
|
12
|
+
* are spurious.
|
|
19
13
|
*/
|
|
20
14
|
if (useOffset) {
|
|
21
15
|
const newLexOrigin = [];
|
|
@@ -27,18 +21,13 @@ export function pugParse(pug, useOffset = false) {
|
|
|
27
21
|
}
|
|
28
22
|
lexOrigin = newLexOrigin;
|
|
29
23
|
}
|
|
24
|
+
// pug-parser mutates the token array it consumes, so clone the tokens first to keep
|
|
25
|
+
// an independent reference for correlating AST nodes with lexer tokens afterwards.
|
|
30
26
|
const lex = structuredClone(lexOrigin);
|
|
31
27
|
const originAst = parser(lexOrigin);
|
|
32
28
|
const ast = optimizeAST(originAst, lex, pug);
|
|
33
29
|
return ast;
|
|
34
30
|
}
|
|
35
|
-
/**
|
|
36
|
-
* Computes the cumulative character offset at the end of each line
|
|
37
|
-
* in the given source string.
|
|
38
|
-
*
|
|
39
|
-
* @param pug - The raw Pug template source code
|
|
40
|
-
* @returns An array where each index corresponds to a line and the value is the cumulative offset
|
|
41
|
-
*/
|
|
42
31
|
function getOffsetsFromLines(pug) {
|
|
43
32
|
const lines = pug.split(/\n/);
|
|
44
33
|
let chars = 0;
|
|
@@ -48,14 +37,6 @@ function getOffsetsFromLines(pug) {
|
|
|
48
37
|
});
|
|
49
38
|
return result;
|
|
50
39
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Merges consecutive Text nodes into a single Text node, combining
|
|
53
|
-
* their raw source and extending the end location of the first node.
|
|
54
|
-
*
|
|
55
|
-
* @param nodes - The array of AST nodes to process
|
|
56
|
-
* @param pug - The raw Pug template source code
|
|
57
|
-
* @returns A new array with adjacent Text nodes merged together
|
|
58
|
-
*/
|
|
59
40
|
function mergeTextNode(
|
|
60
41
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
61
42
|
nodes, pug) {
|
|
@@ -73,16 +54,6 @@ nodes, pug) {
|
|
|
73
54
|
}
|
|
74
55
|
return baseNodes;
|
|
75
56
|
}
|
|
76
|
-
/**
|
|
77
|
-
* Transforms the raw pug-parser AST into an optimized AST by computing
|
|
78
|
-
* accurate source offsets, raw text slices, and end positions for each node.
|
|
79
|
-
* Recursively processes child blocks and merges adjacent text nodes.
|
|
80
|
-
*
|
|
81
|
-
* @param originalAST - The raw AST block from pug-parser, or null
|
|
82
|
-
* @param tokens - The lexed token list from pug-lexer
|
|
83
|
-
* @param pug - The raw Pug template source code
|
|
84
|
-
* @returns The optimized AST block with enriched location data
|
|
85
|
-
*/
|
|
86
57
|
function optimizeAST(
|
|
87
58
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
88
59
|
originalAST,
|
|
@@ -500,17 +471,6 @@ tokens, pug) {
|
|
|
500
471
|
line: originalAST.line,
|
|
501
472
|
};
|
|
502
473
|
}
|
|
503
|
-
/**
|
|
504
|
-
* Recursively processes conditional node chains (`else if` / `else`) in the Pug AST,
|
|
505
|
-
* computing location data for each alternate branch.
|
|
506
|
-
*
|
|
507
|
-
* @param node - The Pug conditional AST node with potential alternate branches
|
|
508
|
-
* @param tokens - The lexed token list from pug-lexer
|
|
509
|
-
* @param pug - The raw Pug template source code
|
|
510
|
-
* @param offsets - Precomputed line offset array
|
|
511
|
-
* @param depth - The current recursion depth for tracking nested conditionals
|
|
512
|
-
* @returns An array of optimized conditional nodes for the alternate branches
|
|
513
|
-
*/
|
|
514
474
|
function optimizeASTOfConditionalNode(
|
|
515
475
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
516
476
|
node,
|
|
@@ -588,17 +548,6 @@ tokens, pug, offsets, depth) {
|
|
|
588
548
|
}
|
|
589
549
|
return altNodes;
|
|
590
550
|
}
|
|
591
|
-
/**
|
|
592
|
-
* Finds the matching lexer token for a node at the given position and returns
|
|
593
|
-
* its end location and length.
|
|
594
|
-
*
|
|
595
|
-
* @param offset - The character offset of the node's start
|
|
596
|
-
* @param line - The 1-based line number of the node
|
|
597
|
-
* @param column - The 1-based column number of the node
|
|
598
|
-
* @param tokens - The lexed token list from pug-lexer
|
|
599
|
-
* @param tokenType - Optional token type(s) to filter by
|
|
600
|
-
* @returns An object with endLine, endColumn, endOffset, and length
|
|
601
|
-
*/
|
|
602
551
|
function getLocationFromToken(offset, line, column,
|
|
603
552
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
604
553
|
tokens, tokenType) {
|
|
@@ -623,17 +572,6 @@ tokens, tokenType) {
|
|
|
623
572
|
length,
|
|
624
573
|
};
|
|
625
574
|
}
|
|
626
|
-
/**
|
|
627
|
-
* Extracts and enriches attribute data from the original Pug AST attributes
|
|
628
|
-
* by correlating each attribute with its corresponding lexer token to compute
|
|
629
|
-
* accurate offsets and raw source slices.
|
|
630
|
-
*
|
|
631
|
-
* @param originalAttrs - The original attribute list from the Pug AST
|
|
632
|
-
* @param tokens - The lexed token list from pug-lexer
|
|
633
|
-
* @param offsets - Precomputed line offset array
|
|
634
|
-
* @param pug - The raw Pug template source code
|
|
635
|
-
* @returns An array of enriched attribute objects with computed location data
|
|
636
|
-
*/
|
|
637
575
|
function getAttrs(
|
|
638
576
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
639
577
|
originalAttrs,
|
|
@@ -671,25 +609,11 @@ tokens, offsets, pug) {
|
|
|
671
609
|
}
|
|
672
610
|
return attrs;
|
|
673
611
|
}
|
|
674
|
-
/**
|
|
675
|
-
* Determines the end position of a tag node including its attributes
|
|
676
|
-
* by scanning lexer tokens that follow the tag's position and precede
|
|
677
|
-
* non-attribute tokens.
|
|
678
|
-
*
|
|
679
|
-
* @param nodeName - The tag name of the element
|
|
680
|
-
* @param offset - The character offset of the tag's start
|
|
681
|
-
* @param line - The 1-based line number of the tag
|
|
682
|
-
* @param column - The 1-based column number of the tag
|
|
683
|
-
* @param tokens - The lexed token list from pug-lexer
|
|
684
|
-
* @param offsets - Precomputed line offset array
|
|
685
|
-
* @returns An object with endOffset, endLine, and endColumn
|
|
686
|
-
*/
|
|
687
612
|
function getEndAttributeLocation(nodeName, offset, line, column,
|
|
688
613
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
689
614
|
tokens, offsets) {
|
|
690
615
|
let beforeNewlineToken = null;
|
|
691
616
|
for (const token of tokens) {
|
|
692
|
-
// Searching token after the tag node.
|
|
693
617
|
if (beforeNewlineToken &&
|
|
694
618
|
(token.loc.start.line > line || (token.loc.start.line >= line && token.loc.start.column > column)) &&
|
|
695
619
|
token.type !== 'attribute' &&
|
|
@@ -713,15 +637,6 @@ tokens, offsets) {
|
|
|
713
637
|
endColumn: column + nodeName.length,
|
|
714
638
|
};
|
|
715
639
|
}
|
|
716
|
-
/**
|
|
717
|
-
* Detects whether a Text node is part of a pipeless text block (indented
|
|
718
|
-
* text content below a tag) and returns its full span if so.
|
|
719
|
-
*
|
|
720
|
-
* @param node - The Pug Text AST node to check
|
|
721
|
-
* @param pug - The raw Pug template source code
|
|
722
|
-
* @param tokens - The lexed token list from pug-lexer
|
|
723
|
-
* @returns Location data for the pipeless text span, or null if not pipeless text
|
|
724
|
-
*/
|
|
725
640
|
function getPipelessText(
|
|
726
641
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
727
642
|
node, pug,
|
|
@@ -758,19 +673,6 @@ tokens) {
|
|
|
758
673
|
}
|
|
759
674
|
return null;
|
|
760
675
|
}
|
|
761
|
-
/**
|
|
762
|
-
* Extracts raw text content and computes accurate end locations for a Text node
|
|
763
|
-
* by walking through lexer tokens from the node's start position. Handles
|
|
764
|
-
* multi-line text, piped text detection, and indentation tracking.
|
|
765
|
-
*
|
|
766
|
-
* @param val - The text value from the Pug AST node
|
|
767
|
-
* @param offset - The character offset where the text starts
|
|
768
|
-
* @param line - The 1-based start line number
|
|
769
|
-
* @param column - The 1-based start column number
|
|
770
|
-
* @param tokens - The lexed token list from pug-lexer
|
|
771
|
-
* @param pug - The raw Pug template source code
|
|
772
|
-
* @returns An array of ASTText nodes with computed location data
|
|
773
|
-
*/
|
|
774
676
|
function getRawTextAndLocationEnd(val, offset, line, column,
|
|
775
677
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
776
678
|
tokens, pug) {
|
package/lib/types.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Additional location and raw source data that is computed during AST optimization
|
|
3
|
-
* and appended to the original Pug AST node types.
|
|
4
|
-
*/
|
|
5
1
|
export type AdditionalASTData = {
|
|
6
2
|
raw: string;
|
|
7
3
|
offset: number;
|
|
@@ -9,84 +5,59 @@ export type AdditionalASTData = {
|
|
|
9
5
|
endLine: number;
|
|
10
6
|
endColumn: number;
|
|
11
7
|
};
|
|
12
|
-
/** Union of all optimized Pug AST node types that the parser can produce. */
|
|
13
8
|
export type ASTNode = ASTDoctype | ASTComment | ASTBlockComment | ASTText | ASTTag | ASTInterpolatedTag | ASTCode | ASTConditional | ASTCase | ASTWhen | ASTWhile | ASTEach | ASTMixin | ASTMixinBlock | ASTYieldBlock | ASTFileReference | ASTInclude | ASTRawInclude | ASTIncludeFilter | ASTExtends | ASTNamedBlock | ASTFilter;
|
|
14
|
-
/** Represents a Pug block containing an ordered list of child nodes. */
|
|
15
9
|
export type ASTBlock = {
|
|
16
10
|
type: 'Block';
|
|
17
11
|
nodes: readonly ASTNode[];
|
|
18
12
|
line: number;
|
|
19
13
|
};
|
|
20
|
-
/** An optimized Pug doctype node with computed location data. */
|
|
21
14
|
export type ASTDoctype = PugAST.Doctype & AdditionalASTData;
|
|
22
|
-
/** An optimized Pug single-line comment node with computed location data. */
|
|
23
15
|
export type ASTComment = PugAST.Comments.Comment & AdditionalASTData;
|
|
24
|
-
/** An optimized Pug block comment node with computed location data and an optimized child block. */
|
|
25
16
|
export type ASTBlockComment = Omit<PugAST.Comments.BlockComment, 'block'> & {
|
|
26
17
|
block: ASTBlock | null;
|
|
27
18
|
} & AdditionalASTData;
|
|
28
|
-
/** An optimized Pug text node with computed location data. */
|
|
29
19
|
export type ASTText = PugAST.Text & AdditionalASTData;
|
|
30
|
-
/** An optimized Pug tag node with computed attributes and child block. */
|
|
31
20
|
export type ASTTag = Omit<PugAST.Tag, 'attrs' | 'block'> & {
|
|
32
21
|
attrs: readonly ASTAttr[];
|
|
33
22
|
block: ASTBlock | null;
|
|
34
23
|
} & AdditionalASTData;
|
|
35
|
-
/** An optimized Pug interpolated tag node with computed child block. */
|
|
36
24
|
export type ASTInterpolatedTag = Omit<PugAST.InterpolatedTag, 'block'> & {
|
|
37
25
|
block: ASTBlock | null;
|
|
38
26
|
} & AdditionalASTData;
|
|
39
|
-
/** An optimized Pug code node (unbuffered/buffered JavaScript) with computed child block. */
|
|
40
27
|
export type ASTCode = Omit<PugAST.Code, 'block'> & {
|
|
41
28
|
block: ASTBlock | null;
|
|
42
29
|
} & AdditionalASTData;
|
|
43
|
-
/** An optimized Pug conditional (`if`/`else if`/`else`) node with computed child block. */
|
|
44
30
|
export type ASTConditional = Omit<PugAST.CodeHelpers.Conditional, 'consequent' | 'alternate'> & {
|
|
45
31
|
block: ASTBlock | null;
|
|
46
32
|
} & AdditionalASTData;
|
|
47
|
-
/** An optimized Pug `case` node with computed child block. */
|
|
48
33
|
export type ASTCase = Omit<PugAST.CodeHelpers.CaseWhen.Case, 'block'> & {
|
|
49
34
|
block: ASTBlock | null;
|
|
50
35
|
} & AdditionalASTData;
|
|
51
|
-
/** An optimized Pug `when` node with computed child block. */
|
|
52
36
|
export type ASTWhen = Omit<PugAST.CodeHelpers.CaseWhen.When, 'block'> & {
|
|
53
37
|
block: ASTBlock | null;
|
|
54
38
|
} & AdditionalASTData;
|
|
55
|
-
/** An optimized Pug `while` loop node with computed location data. */
|
|
56
39
|
export type ASTWhile = PugAST.While & AdditionalASTData;
|
|
57
|
-
/** An optimized Pug `each` iteration node with computed child block. */
|
|
58
40
|
export type ASTEach = Omit<PugAST.Each, 'block' | 'alternate'> & {
|
|
59
41
|
block: ASTBlock | null;
|
|
60
42
|
} & AdditionalASTData;
|
|
61
|
-
/** An optimized Pug mixin (definition or call) node with computed child block. */
|
|
62
43
|
export type ASTMixin = Omit<PugAST.Mixin, 'block'> & {
|
|
63
44
|
block: ASTBlock | null;
|
|
64
45
|
} & AdditionalASTData;
|
|
65
|
-
/** An optimized Pug `block` placeholder inside a mixin definition. */
|
|
66
46
|
export type ASTMixinBlock = PugAST.MixinBlock & AdditionalASTData;
|
|
67
|
-
/** An optimized Pug `yield` block placeholder. */
|
|
68
47
|
export type ASTYieldBlock = PugAST.YieldBlock & AdditionalASTData;
|
|
69
|
-
/** An optimized Pug file reference node with computed location data. */
|
|
70
48
|
export type ASTFileReference = PugAST.FileOperations.FileReference & AdditionalASTData;
|
|
71
|
-
/** An optimized Pug `include` node with computed child block. */
|
|
72
49
|
export type ASTInclude = Omit<PugAST.FileOperations.Include, 'block'> & {
|
|
73
50
|
block: ASTBlock | null;
|
|
74
51
|
} & AdditionalASTData;
|
|
75
|
-
/** An optimized Pug raw `include` node with computed location data. */
|
|
76
52
|
export type ASTRawInclude = PugAST.FileOperations.RawInclude & AdditionalASTData;
|
|
77
|
-
/** An optimized Pug include filter node with computed location data. */
|
|
78
53
|
export type ASTIncludeFilter = PugAST.FileOperations.IncludeFilter & AdditionalASTData;
|
|
79
|
-
/** An optimized Pug `extends` node with computed location data. */
|
|
80
54
|
export type ASTExtends = PugAST.FileOperations.Extends & AdditionalASTData;
|
|
81
|
-
/** An optimized Pug named block node with computed child nodes. */
|
|
82
55
|
export type ASTNamedBlock = Omit<PugAST.FileOperations.NamedBlock, 'nodes'> & {
|
|
83
56
|
nodes: readonly ASTNode[];
|
|
84
57
|
} & AdditionalASTData;
|
|
85
|
-
/** An optimized Pug filter node with computed child block. */
|
|
86
58
|
export type ASTFilter = Omit<PugAST.Filter, 'block'> & {
|
|
87
59
|
block: ASTBlock | null;
|
|
88
60
|
} & AdditionalASTData;
|
|
89
|
-
/** An optimized Pug attribute with computed location and raw source data. */
|
|
90
61
|
export type ASTAttr = PugAST.AbstractNodeTypes.Attribute & AdditionalASTData;
|
|
91
62
|
export declare namespace PugAST {
|
|
92
63
|
/**
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* and 1-based column number. Handles multi-byte characters correctly
|
|
4
|
-
* by splitting lines into individual characters.
|
|
5
|
-
*
|
|
6
|
-
* @param str - The source string to compute the offset within
|
|
7
|
-
* @param line - The 1-based line number
|
|
8
|
-
* @param col - The 1-based column number
|
|
9
|
-
* @returns The 0-based character offset corresponding to the given line and column
|
|
2
|
+
* `line` and `col` are 1-based; the returned offset is 0-based.
|
|
10
3
|
*/
|
|
11
4
|
export declare function getOffsetFromLineAndCol(str: string, line: number, col: number): number;
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* and 1-based column number. Handles multi-byte characters correctly
|
|
4
|
-
* by splitting lines into individual characters.
|
|
5
|
-
*
|
|
6
|
-
* @param str - The source string to compute the offset within
|
|
7
|
-
* @param line - The 1-based line number
|
|
8
|
-
* @param col - The 1-based column number
|
|
9
|
-
* @returns The 0-based character offset corresponding to the given line and column
|
|
2
|
+
* `line` and `col` are 1-based; the returned offset is 0-based.
|
|
10
3
|
*/
|
|
11
4
|
export function getOffsetFromLineAndCol(str, line, col) {
|
|
12
5
|
const lines = str.split('\n').slice(0, line);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/pug-parser",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.5",
|
|
4
4
|
"description": "Pug parser for markuplint",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"engines": {
|
|
13
|
-
"node": ">=
|
|
13
|
+
"node": ">=24"
|
|
14
14
|
},
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"clean": "tsc --build --clean tsconfig.build.json"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@markuplint/html-parser": "5.0.0-rc.
|
|
32
|
-
"@markuplint/ml-ast": "5.0.0-rc.
|
|
33
|
-
"@markuplint/parser-utils": "5.0.0-rc.
|
|
31
|
+
"@markuplint/html-parser": "5.0.0-rc.5",
|
|
32
|
+
"@markuplint/ml-ast": "5.0.0-rc.5",
|
|
33
|
+
"@markuplint/parser-utils": "5.0.0-rc.5",
|
|
34
34
|
"pug-lexer": "5.0.1",
|
|
35
35
|
"pug-parser": "6.0.0"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "8d87463af2ff3f1b83fb28da20f1819362cf3555"
|
|
38
38
|
}
|