@markuplint/parser-utils 3.13.0 → 4.0.0-alpha.10
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/LICENSE +1 -1
- package/lib/attr-tokenizer.d.ts +18 -0
- package/lib/attr-tokenizer.js +169 -0
- package/lib/const.d.ts +9 -2
- package/lib/const.js +12 -9
- package/lib/debugger.d.ts +3 -2
- package/lib/debugger.js +38 -39
- package/lib/decision.js +6 -11
- package/lib/detect-element-type.d.ts +1 -5
- package/lib/detect-element-type.js +4 -8
- package/lib/enums.d.ts +16 -0
- package/lib/enums.js +18 -0
- package/lib/get-location.d.ts +4 -17
- package/lib/get-location.js +11 -31
- package/lib/idl-attributes.d.ts +2 -2
- package/lib/idl-attributes.js +5 -10
- package/lib/ignore-block.d.ts +4 -3
- package/lib/ignore-block.js +75 -131
- package/lib/ignore-front-matter.d.ts +4 -1
- package/lib/ignore-front-matter.js +15 -10
- package/lib/index.d.ts +7 -16
- package/lib/index.js +7 -19
- package/lib/parser-error.d.ts +19 -24
- package/lib/parser-error.js +8 -15
- package/lib/parser.d.ts +108 -0
- package/lib/parser.js +1076 -0
- package/lib/script-parser.d.ts +6 -0
- package/lib/script-parser.js +22 -0
- package/lib/sort-nodes.d.ts +2 -0
- package/lib/sort-nodes.js +18 -0
- package/lib/types.d.ts +50 -12
- package/lib/types.js +1 -2
- package/package.json +17 -8
- package/lib/create-token.d.ts +0 -9
- package/lib/create-token.js +0 -35
- package/lib/flatten-nodes.d.ts +0 -2
- package/lib/flatten-nodes.js +0 -251
- package/lib/get-space-before.d.ts +0 -1
- package/lib/get-space-before.js +0 -13
- package/lib/idl-attributes.test.d.ts +0 -1
- package/lib/idl-attributes.test.js +0 -45
- package/lib/parse-attr.d.ts +0 -27
- package/lib/parse-attr.js +0 -150
- package/lib/remove-deprecated-node.d.ts +0 -7
- package/lib/remove-deprecated-node.js +0 -43
- package/lib/siblings-correction.d.ts +0 -9
- package/lib/siblings-correction.js +0 -26
- package/lib/tag-splitter.d.ts +0 -7
- package/lib/tag-splitter.js +0 -92
- package/lib/walker.d.ts +0 -2
- package/lib/walker.js +0 -22
- package/test/create-token.spec.js +0 -17
- package/test/flatten-nodes.spec.js +0 -31
- package/test/get-location.spec.js +0 -38
- package/test/ignore-block.spec.js +0 -274
- package/test/ignore-front-matter.spec.js +0 -20
- package/test/parse-attr.spec.js +0 -68
package/lib/ignore-block.js
CHANGED
|
@@ -1,28 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const create_token_1 = require("./create-token");
|
|
6
|
-
const get_location_1 = require("./get-location");
|
|
7
|
-
const siblings_correction_1 = require("./siblings-correction");
|
|
8
|
-
function ignoreBlock(source, tags, maskChar = const_1.MASK_CHAR) {
|
|
1
|
+
import { MASK_CHAR } from './const.js';
|
|
2
|
+
import { getCol, getLine } from './get-location.js';
|
|
3
|
+
import { ParserError } from './parser-error.js';
|
|
4
|
+
export function ignoreBlock(source, tags, maskChar = MASK_CHAR) {
|
|
9
5
|
let replaced = source;
|
|
10
6
|
const stack = [];
|
|
11
7
|
for (const tag of tags) {
|
|
12
|
-
// Replace tags in attributes
|
|
13
|
-
const attr = maskText(prepend(tag.start, '(?<=(?:"|\'))'), append(tag.end, '(?=(?:"|\'))'), replaced, (startTag, taggedCode, endTag) => {
|
|
14
|
-
const mask = maskChar.repeat(startTag.length) +
|
|
15
|
-
taggedCode.replace(/[^\n]/g, maskChar) +
|
|
16
|
-
maskChar.repeat((endTag !== null && endTag !== void 0 ? endTag : '').length);
|
|
17
|
-
return mask;
|
|
18
|
-
});
|
|
19
|
-
replaced = attr.replaced;
|
|
20
|
-
stack.push(...attr.stack.map(res => ({ ...res, type: tag.type })));
|
|
21
|
-
// Replace tags in other nodes
|
|
22
8
|
const text = maskText(tag.start, tag.end, replaced, (startTag, taggedCode, endTag) => {
|
|
23
9
|
const mask = maskChar.repeat(startTag.length) +
|
|
24
|
-
taggedCode.
|
|
25
|
-
maskChar.repeat((endTag
|
|
10
|
+
taggedCode.replaceAll(/[^\n]/g, maskChar) +
|
|
11
|
+
maskChar.repeat((endTag ?? '').length);
|
|
26
12
|
const taggedMask = `<!${mask.slice(2).slice(0, -1)}>`;
|
|
27
13
|
return taggedMask;
|
|
28
14
|
});
|
|
@@ -37,7 +23,6 @@ function ignoreBlock(source, tags, maskChar = const_1.MASK_CHAR) {
|
|
|
37
23
|
maskChar,
|
|
38
24
|
};
|
|
39
25
|
}
|
|
40
|
-
exports.ignoreBlock = ignoreBlock;
|
|
41
26
|
function maskText(start, end, replaced, masking) {
|
|
42
27
|
const stack = [];
|
|
43
28
|
start = removeGlobalOption(start);
|
|
@@ -52,121 +37,56 @@ function maskText(start, end, replaced, masking) {
|
|
|
52
37
|
index,
|
|
53
38
|
startTag,
|
|
54
39
|
taggedCode,
|
|
55
|
-
endTag: endTag
|
|
40
|
+
endTag: endTag ?? null,
|
|
41
|
+
resolved: false,
|
|
56
42
|
});
|
|
57
43
|
/**
|
|
58
44
|
* It will not replace line breaks because detects line number.
|
|
59
45
|
*/
|
|
60
|
-
replaced = above + masking(startTag, taggedCode, endTag) + (below
|
|
46
|
+
replaced = above + masking(startTag, taggedCode, endTag) + (below ?? '');
|
|
61
47
|
}
|
|
62
48
|
return {
|
|
63
49
|
replaced,
|
|
64
50
|
stack,
|
|
65
51
|
};
|
|
66
52
|
}
|
|
67
|
-
function restoreNode(
|
|
53
|
+
export function restoreNode(
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
55
|
+
parser, nodeList,
|
|
68
56
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
nodeList = nodeList.slice();
|
|
57
|
+
ignoreBlock, throwErrorWhenTagHasUnresolved = true) {
|
|
58
|
+
const newNodeList = [...nodeList];
|
|
72
59
|
const { source, stack, maskChar } = ignoreBlock;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
uuid: (0, create_token_1.uuid)(),
|
|
95
|
-
type: 'text',
|
|
96
|
-
raw,
|
|
97
|
-
startOffset,
|
|
98
|
-
endOffset,
|
|
99
|
-
startLine,
|
|
100
|
-
endLine,
|
|
101
|
-
startCol,
|
|
102
|
-
endCol,
|
|
103
|
-
};
|
|
104
|
-
if ((_b = node.prevNode) === null || _b === void 0 ? void 0 : _b.nextNode) {
|
|
105
|
-
node.prevNode.nextNode = textNode;
|
|
106
|
-
}
|
|
107
|
-
if ((_c = node.nextNode) === null || _c === void 0 ? void 0 : _c.prevNode) {
|
|
108
|
-
node.nextNode.prevNode = textNode;
|
|
109
|
-
}
|
|
110
|
-
insertList.push(textNode);
|
|
111
|
-
}
|
|
112
|
-
if (body) {
|
|
113
|
-
const offset = node.startOffset + pointer + above.length;
|
|
114
|
-
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = (0, get_location_1.sliceFragment)(source, offset, offset + body.length);
|
|
115
|
-
const bodyNode = {
|
|
116
|
-
uuid: (0, create_token_1.uuid)(),
|
|
117
|
-
type: 'psblock',
|
|
118
|
-
nodeName: `#ps:${tag.type}`,
|
|
119
|
-
raw,
|
|
120
|
-
parentNode: node.parentNode,
|
|
121
|
-
prevNode: null,
|
|
122
|
-
nextNode: null,
|
|
123
|
-
isFragment: node.isFragment,
|
|
124
|
-
isGhost: false,
|
|
125
|
-
startOffset,
|
|
126
|
-
endOffset,
|
|
127
|
-
startLine,
|
|
128
|
-
endLine,
|
|
129
|
-
startCol,
|
|
130
|
-
endCol,
|
|
131
|
-
};
|
|
132
|
-
if ((_d = node.prevNode) === null || _d === void 0 ? void 0 : _d.nextNode) {
|
|
133
|
-
node.prevNode.nextNode = bodyNode;
|
|
134
|
-
}
|
|
135
|
-
if ((_e = node.nextNode) === null || _e === void 0 ? void 0 : _e.prevNode) {
|
|
136
|
-
node.nextNode.prevNode = bodyNode;
|
|
137
|
-
}
|
|
138
|
-
insertList.push(bodyNode);
|
|
139
|
-
}
|
|
140
|
-
text = below;
|
|
141
|
-
pointer = start + body.length;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (text) {
|
|
145
|
-
const offset = node.endOffset - text.length;
|
|
146
|
-
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = (0, get_location_1.sliceFragment)(source, offset, offset + text.length);
|
|
147
|
-
const textNode = {
|
|
148
|
-
...node,
|
|
149
|
-
uuid: (0, create_token_1.uuid)(),
|
|
150
|
-
type: 'text',
|
|
151
|
-
raw,
|
|
152
|
-
startOffset,
|
|
153
|
-
endOffset,
|
|
154
|
-
startLine,
|
|
155
|
-
endLine,
|
|
156
|
-
startCol,
|
|
157
|
-
endCol,
|
|
158
|
-
};
|
|
159
|
-
insertList.push(textNode);
|
|
160
|
-
}
|
|
161
|
-
(0, siblings_correction_1.siblingsCorrection)(insertList);
|
|
162
|
-
if (parentNode) {
|
|
163
|
-
parentNode.childNodes = insertList;
|
|
164
|
-
}
|
|
165
|
-
nodeList.splice(index, 1, ...insertList);
|
|
60
|
+
if (stack.length === 0) {
|
|
61
|
+
return newNodeList;
|
|
62
|
+
}
|
|
63
|
+
for (const tag of stack) {
|
|
64
|
+
const node = newNodeList.find(node => node.startOffset === tag.index);
|
|
65
|
+
if (!node) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const raw = `${tag.startTag}${tag.taggedCode}${tag.endTag ?? ''}`;
|
|
69
|
+
const token = parser.createToken(raw, node.startOffset, node.startLine, node.startCol);
|
|
70
|
+
const psNode = {
|
|
71
|
+
...token,
|
|
72
|
+
type: 'psblock',
|
|
73
|
+
depth: node.depth,
|
|
74
|
+
nodeName: `#ps:${tag.type}`,
|
|
75
|
+
parentNode: node.parentNode,
|
|
76
|
+
childNodes: [],
|
|
77
|
+
isBogus: false,
|
|
78
|
+
};
|
|
79
|
+
if (node.type !== 'doctype' && node.parentNode?.childNodes) {
|
|
80
|
+
parser.replaceChild(node.parentNode, node, psNode);
|
|
166
81
|
}
|
|
82
|
+
const index = newNodeList.indexOf(node);
|
|
83
|
+
newNodeList.splice(index, 1, psNode);
|
|
84
|
+
tag.resolved = true;
|
|
85
|
+
}
|
|
86
|
+
for (const node of newNodeList) {
|
|
167
87
|
if (node.type === 'starttag') {
|
|
168
88
|
for (const attr of node.attributes) {
|
|
169
|
-
if (attr.type === '
|
|
89
|
+
if (attr.type === 'spread' || attr.value.raw === '' || !hasIgnoreBlock(attr.value.raw, maskChar)) {
|
|
170
90
|
continue;
|
|
171
91
|
}
|
|
172
92
|
for (const tag of stack) {
|
|
@@ -176,16 +96,40 @@ nodeList, ignoreBlock) {
|
|
|
176
96
|
const offset = tag.index - attr.value.startOffset;
|
|
177
97
|
const above = attr.value.raw.slice(0, offset);
|
|
178
98
|
const below = attr.value.raw.slice(offset + length);
|
|
179
|
-
attr.value
|
|
180
|
-
attr
|
|
99
|
+
parser.updateRaw(attr.value, above + raw + below);
|
|
100
|
+
parser.updateAttr(attr, { isDynamicValue: true });
|
|
101
|
+
tag.resolved = true;
|
|
181
102
|
}
|
|
103
|
+
parser.updateRaw(attr, attr.name.raw +
|
|
104
|
+
attr.spacesBeforeEqual.raw +
|
|
105
|
+
attr.equal.raw +
|
|
106
|
+
attr.spacesAfterEqual.raw +
|
|
107
|
+
attr.startQuote.raw +
|
|
108
|
+
attr.value.raw +
|
|
109
|
+
attr.endQuote.raw);
|
|
182
110
|
}
|
|
111
|
+
// Update node raw
|
|
112
|
+
const length = attr.raw.length;
|
|
113
|
+
const offset = attr.startOffset - node.startOffset;
|
|
114
|
+
const above = node.raw.slice(0, offset);
|
|
115
|
+
const below = node.raw.slice(offset + length);
|
|
116
|
+
parser.updateRaw(node, above + attr.raw + below);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (throwErrorWhenTagHasUnresolved) {
|
|
121
|
+
for (const tag of stack) {
|
|
122
|
+
if (!tag.resolved) {
|
|
123
|
+
throw new ParserError('Parsing failed. Unsupported syntax detected', {
|
|
124
|
+
line: getLine(source, tag.index),
|
|
125
|
+
col: getCol(source, tag.index),
|
|
126
|
+
raw: tag.startTag + tag.taggedCode + (tag.endTag ?? ''),
|
|
127
|
+
});
|
|
183
128
|
}
|
|
184
129
|
}
|
|
185
130
|
}
|
|
186
|
-
return
|
|
131
|
+
return newNodeList;
|
|
187
132
|
}
|
|
188
|
-
exports.restoreNode = restoreNode;
|
|
189
133
|
function snap(str, reg) {
|
|
190
134
|
const matched = reg.exec(str);
|
|
191
135
|
if (!matched) {
|
|
@@ -198,14 +142,14 @@ function snap(str, reg) {
|
|
|
198
142
|
return [index, above, snapPoint, below];
|
|
199
143
|
}
|
|
200
144
|
function removeGlobalOption(reg) {
|
|
145
|
+
if (typeof reg === 'string') {
|
|
146
|
+
return new RegExp(escapeRegExpForStr(reg));
|
|
147
|
+
}
|
|
201
148
|
return new RegExp(reg.source, reg.ignoreCase ? 'i' : '');
|
|
202
149
|
}
|
|
203
|
-
function prepend(reg, str) {
|
|
204
|
-
return new RegExp(str + reg.source, reg.ignoreCase ? 'i' : '');
|
|
205
|
-
}
|
|
206
|
-
function append(reg, str) {
|
|
207
|
-
return new RegExp(reg.source + str, reg.ignoreCase ? 'i' : '');
|
|
208
|
-
}
|
|
209
150
|
function hasIgnoreBlock(textContent, maskChar) {
|
|
210
151
|
return textContent.includes(maskChar);
|
|
211
152
|
}
|
|
153
|
+
function escapeRegExpForStr(str) {
|
|
154
|
+
return str.replaceAll(/[!$()*+./:=?[\\\]^{|}]/g, '\\$&');
|
|
155
|
+
}
|
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.ignoreFrontMatter = void 0;
|
|
4
|
-
function ignoreFrontMatter(code) {
|
|
5
|
-
const reStart = /^(?:\s*\r?\n)?---\r?\n/.exec(code);
|
|
1
|
+
export function ignoreFrontMatter(code) {
|
|
2
|
+
const reStart = /^(?:\s*\n)?---\r?\n/.exec(code);
|
|
6
3
|
if (!reStart) {
|
|
7
|
-
return
|
|
4
|
+
return {
|
|
5
|
+
code,
|
|
6
|
+
frontMatter: null,
|
|
7
|
+
};
|
|
8
8
|
}
|
|
9
9
|
const startPoint = reStart[0].length;
|
|
10
10
|
const afterStart = code.slice(startPoint);
|
|
11
11
|
const reEnd = /\r?\n---\r?\n/.exec(afterStart);
|
|
12
12
|
if (!reEnd) {
|
|
13
|
-
return
|
|
13
|
+
return {
|
|
14
|
+
code,
|
|
15
|
+
frontMatter: null,
|
|
16
|
+
};
|
|
14
17
|
}
|
|
15
18
|
const endPoint = startPoint + reEnd.index + reEnd[0].length;
|
|
16
19
|
const frontMatter = code.slice(0, endPoint);
|
|
17
20
|
const afterCode = code.slice(endPoint);
|
|
18
|
-
const masked = frontMatter.
|
|
19
|
-
return
|
|
21
|
+
const masked = frontMatter.replaceAll(/[^\n\r]/g, ' ');
|
|
22
|
+
return {
|
|
23
|
+
code: masked + afterCode,
|
|
24
|
+
frontMatter,
|
|
25
|
+
};
|
|
20
26
|
}
|
|
21
|
-
exports.ignoreFrontMatter = ignoreFrontMatter;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './get-space-before';
|
|
9
|
-
export * from './idl-attributes';
|
|
10
|
-
export * from './ignore-block';
|
|
11
|
-
export * from './ignore-front-matter';
|
|
12
|
-
export * from './parse-attr';
|
|
13
|
-
export * from './parser-error';
|
|
14
|
-
export * from './remove-deprecated-node';
|
|
15
|
-
export * from './tag-splitter';
|
|
16
|
-
export * from './walker';
|
|
1
|
+
export * from './debugger.js';
|
|
2
|
+
export * from './enums.js';
|
|
3
|
+
export * from './idl-attributes.js';
|
|
4
|
+
export * from './parser-error.js';
|
|
5
|
+
export * from './parser.js';
|
|
6
|
+
export * from './script-parser.js';
|
|
7
|
+
export * from './types.js';
|
package/lib/index.js
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
tslib_1.__exportStar(require("./detect-element-type"), exports);
|
|
9
|
-
tslib_1.__exportStar(require("./flatten-nodes"), exports);
|
|
10
|
-
tslib_1.__exportStar(require("./get-location"), exports);
|
|
11
|
-
tslib_1.__exportStar(require("./get-space-before"), exports);
|
|
12
|
-
tslib_1.__exportStar(require("./idl-attributes"), exports);
|
|
13
|
-
tslib_1.__exportStar(require("./ignore-block"), exports);
|
|
14
|
-
tslib_1.__exportStar(require("./ignore-front-matter"), exports);
|
|
15
|
-
tslib_1.__exportStar(require("./parse-attr"), exports);
|
|
16
|
-
tslib_1.__exportStar(require("./parser-error"), exports);
|
|
17
|
-
tslib_1.__exportStar(require("./remove-deprecated-node"), exports);
|
|
18
|
-
tslib_1.__exportStar(require("./tag-splitter"), exports);
|
|
19
|
-
tslib_1.__exportStar(require("./walker"), exports);
|
|
1
|
+
export * from './debugger.js';
|
|
2
|
+
export * from './enums.js';
|
|
3
|
+
export * from './idl-attributes.js';
|
|
4
|
+
export * from './parser-error.js';
|
|
5
|
+
export * from './parser.js';
|
|
6
|
+
export * from './script-parser.js';
|
|
7
|
+
export * from './types.js';
|
package/lib/parser-error.d.ts
CHANGED
|
@@ -1,32 +1,27 @@
|
|
|
1
1
|
export type ParserErrorInfo = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
readonly line?: number;
|
|
3
|
+
readonly col?: number;
|
|
4
|
+
readonly raw?: string;
|
|
5
|
+
readonly stack?: string;
|
|
5
6
|
};
|
|
6
7
|
export declare class ParserError extends Error {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
readonly col: number;
|
|
9
|
+
readonly line: number;
|
|
10
|
+
name: string;
|
|
11
|
+
readonly raw: string;
|
|
12
|
+
constructor(message: string, info: ParserErrorInfo);
|
|
12
13
|
}
|
|
13
14
|
export declare class TargetParserError extends ParserError {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
readonly nodeName?: string | null;
|
|
20
|
-
},
|
|
21
|
-
);
|
|
15
|
+
name: string;
|
|
16
|
+
readonly nodeName: string | null;
|
|
17
|
+
constructor(message: string, info: ParserErrorInfo & {
|
|
18
|
+
readonly nodeName?: string | null;
|
|
19
|
+
});
|
|
22
20
|
}
|
|
23
21
|
export declare class ConfigParserError extends ParserError {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
readonly filePath: string;
|
|
30
|
-
},
|
|
31
|
-
);
|
|
22
|
+
readonly filePath: string;
|
|
23
|
+
name: string;
|
|
24
|
+
constructor(message: string, info: ParserErrorInfo & {
|
|
25
|
+
readonly filePath: string;
|
|
26
|
+
});
|
|
32
27
|
}
|
package/lib/parser-error.js
CHANGED
|
@@ -1,30 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ConfigParserError = exports.TargetParserError = exports.ParserError = void 0;
|
|
4
|
-
class ParserError extends Error {
|
|
1
|
+
export class ParserError extends Error {
|
|
5
2
|
constructor(message, info) {
|
|
6
|
-
var _a, _b, _c;
|
|
7
3
|
super(message);
|
|
8
4
|
this.name = 'ParserError';
|
|
9
|
-
this.line =
|
|
10
|
-
this.col =
|
|
11
|
-
this.raw =
|
|
5
|
+
this.line = info.line ?? 1;
|
|
6
|
+
this.col = info.col ?? 0;
|
|
7
|
+
this.raw = info.raw ?? '';
|
|
8
|
+
this.stack = info.stack ?? this.stack;
|
|
12
9
|
}
|
|
13
10
|
}
|
|
14
|
-
|
|
15
|
-
class TargetParserError extends ParserError {
|
|
11
|
+
export class TargetParserError extends ParserError {
|
|
16
12
|
constructor(message, info) {
|
|
17
|
-
var _a;
|
|
18
13
|
const errMsg = info.nodeName
|
|
19
14
|
? `The ${info.nodeName} is invalid element (${info.line}:${info.col}): ${message}`
|
|
20
15
|
: message;
|
|
21
16
|
super(errMsg, info);
|
|
22
17
|
this.name = 'TargetParserError';
|
|
23
|
-
this.nodeName =
|
|
18
|
+
this.nodeName = info.nodeName ?? null;
|
|
24
19
|
}
|
|
25
20
|
}
|
|
26
|
-
|
|
27
|
-
class ConfigParserError extends ParserError {
|
|
21
|
+
export class ConfigParserError extends ParserError {
|
|
28
22
|
constructor(message, info) {
|
|
29
23
|
const pos = info.line != null && info.line != null ? `(${info.line}:${info.col})` : '';
|
|
30
24
|
const file = ` in ${info.filePath}${pos}`;
|
|
@@ -34,4 +28,3 @@ class ConfigParserError extends ParserError {
|
|
|
34
28
|
this.filePath = info.filePath;
|
|
35
29
|
}
|
|
36
30
|
}
|
|
37
|
-
exports.ConfigParserError = ConfigParserError;
|
package/lib/parser.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { Token, ChildToken, QuoteSet, ParseOptions, ParserOptions, Tokenized } from './types.js';
|
|
2
|
+
import type { EndTagType, MLASTDocument, MLASTParentNode, MLParser, ParserAuthoredElementNameDistinguishing, MLASTElement, MLASTElementCloseTag, MLASTToken, MLASTNodeTreeItem, MLASTTag, MLASTText, MLASTAttr, MLASTChildNode, MLASTSpreadAttr, ElementType, Walker, MLASTHTMLAttr } from '@markuplint/ml-ast';
|
|
3
|
+
import { AttrState } from './enums.js';
|
|
4
|
+
import { ParserError } from './parser-error.js';
|
|
5
|
+
export declare abstract class Parser<Node extends {} = {}, State extends unknown = null> implements MLParser {
|
|
6
|
+
#private;
|
|
7
|
+
state: State;
|
|
8
|
+
get authoredElementName(): ParserAuthoredElementNameDistinguishing | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Detect value as a true if its attribute is booleanish value and omitted.
|
|
11
|
+
*
|
|
12
|
+
* Ex:
|
|
13
|
+
* ```jsx
|
|
14
|
+
* <Component aria-hidden />
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* In the above, the `aria-hidden` is `true`.
|
|
18
|
+
*/
|
|
19
|
+
get booleanish(): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The end tag omittable type.
|
|
22
|
+
*
|
|
23
|
+
* - `"xml"`: Must need an end tag or must self-close
|
|
24
|
+
* - `"omittable"`: May omit
|
|
25
|
+
* - `"never"`: Never need
|
|
26
|
+
*/
|
|
27
|
+
get endTag(): EndTagType;
|
|
28
|
+
get rawCode(): string;
|
|
29
|
+
get tagNameCaseSensitive(): boolean;
|
|
30
|
+
constructor(options?: ParserOptions, defaultState?: State);
|
|
31
|
+
tokenize(): Tokenized<Node, State>;
|
|
32
|
+
beforeParse(rawCode: string, options?: ParseOptions): string;
|
|
33
|
+
parse(rawCode: string, options?: ParseOptions): MLASTDocument;
|
|
34
|
+
afterParse(nodeList: readonly MLASTNodeTreeItem[], options?: ParseOptions): readonly MLASTNodeTreeItem[];
|
|
35
|
+
parseError(error: any): ParserError;
|
|
36
|
+
traverse(originNodes: readonly Node[], parentNode: MLASTParentNode | null | undefined, depth: number): {
|
|
37
|
+
childNodes: readonly MLASTChildNode[];
|
|
38
|
+
siblings: readonly MLASTNodeTreeItem[];
|
|
39
|
+
};
|
|
40
|
+
afterTraverse(nodeTree: readonly MLASTNodeTreeItem[]): readonly MLASTNodeTreeItem[];
|
|
41
|
+
nodeize(originNode: Node, parentNode: MLASTParentNode | null, depth: number): readonly MLASTNodeTreeItem[];
|
|
42
|
+
afterNodeize(siblings: readonly MLASTNodeTreeItem[], parentNode: MLASTParentNode | null, depth: number): {
|
|
43
|
+
siblings: MLASTChildNode[];
|
|
44
|
+
ancestors: MLASTNodeTreeItem[];
|
|
45
|
+
};
|
|
46
|
+
flattenNodes(nodeTree: readonly MLASTNodeTreeItem[]): readonly MLASTNodeTreeItem[];
|
|
47
|
+
afterFlattenNodes(nodeList: readonly MLASTNodeTreeItem[], options?: {
|
|
48
|
+
readonly exposeInvalidNode?: boolean;
|
|
49
|
+
readonly exposeWhiteSpace?: boolean;
|
|
50
|
+
readonly concatText?: boolean;
|
|
51
|
+
}): readonly MLASTNodeTreeItem[];
|
|
52
|
+
visitDoctype(token: ChildToken & {
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly publicId: string;
|
|
55
|
+
readonly systemId: string;
|
|
56
|
+
}): readonly MLASTNodeTreeItem[];
|
|
57
|
+
visitComment(token: ChildToken, options?: {
|
|
58
|
+
readonly isBogus?: boolean;
|
|
59
|
+
}): readonly MLASTNodeTreeItem[];
|
|
60
|
+
visitText(token: ChildToken, options?: {
|
|
61
|
+
readonly researchTags?: boolean;
|
|
62
|
+
readonly invalidTagAsText?: boolean;
|
|
63
|
+
}): readonly MLASTNodeTreeItem[];
|
|
64
|
+
visitElement(token: ChildToken & {
|
|
65
|
+
readonly nodeName: string;
|
|
66
|
+
readonly namespace: string;
|
|
67
|
+
}, childNodes?: readonly Node[], options?: {
|
|
68
|
+
readonly createEndTagToken?: (startTag: MLASTElement) => ChildToken | null;
|
|
69
|
+
readonly namelessFragment?: boolean;
|
|
70
|
+
readonly overwriteProps?: Partial<MLASTElement>;
|
|
71
|
+
}): readonly MLASTNodeTreeItem[];
|
|
72
|
+
visitPsBlock(token: ChildToken & {
|
|
73
|
+
readonly nodeName: string;
|
|
74
|
+
}, childNodes?: readonly Node[], originBlockNode?: Node): readonly MLASTNodeTreeItem[];
|
|
75
|
+
visitChildren(children: readonly Node[], parentNode: MLASTParentNode | null): readonly MLASTNodeTreeItem[];
|
|
76
|
+
visitSpreadAttr(token: Token): MLASTSpreadAttr | null;
|
|
77
|
+
visitAttr(token: Token, options?: {
|
|
78
|
+
readonly quoteSet?: readonly QuoteSet[];
|
|
79
|
+
readonly quoteInValueChars?: readonly QuoteSet[];
|
|
80
|
+
readonly endOfUnquotedValueChars?: readonly string[];
|
|
81
|
+
readonly startState?: AttrState;
|
|
82
|
+
}): MLASTAttr & {
|
|
83
|
+
__rightText?: string;
|
|
84
|
+
};
|
|
85
|
+
parseCodeFragment(token: ChildToken, options?: {
|
|
86
|
+
readonly namelessFragment?: boolean;
|
|
87
|
+
}): (MLASTTag | MLASTText)[];
|
|
88
|
+
updateLocation(node: MLASTNodeTreeItem, props: Partial<Pick<MLASTNodeTreeItem, 'startOffset' | 'startLine' | 'startCol' | 'depth'>>): void;
|
|
89
|
+
/**
|
|
90
|
+
* Set new raw code to target node.
|
|
91
|
+
*
|
|
92
|
+
* Replace the raw code and update the start/end offset/line/column.
|
|
93
|
+
*
|
|
94
|
+
* @param node target node
|
|
95
|
+
* @param raw new raw code
|
|
96
|
+
*/
|
|
97
|
+
updateRaw(node: MLASTToken, raw: string): void;
|
|
98
|
+
updateElement(el: MLASTElement, props: Partial<Pick<MLASTElement, 'nodeName' | 'elementType'>>): void;
|
|
99
|
+
updateElement(el: MLASTElementCloseTag, props: Partial<Pick<MLASTElementCloseTag, 'nodeName'>>): void;
|
|
100
|
+
updateAttr(attr: MLASTHTMLAttr, props: Partial<Pick<MLASTHTMLAttr, 'isDynamicValue' | 'isDirective' | 'potentialName' | 'potentialValue' | 'valueType' | 'candidate' | 'isDuplicatable'>>): void;
|
|
101
|
+
detectElementType(nodeName: string, defaultPattern?: ParserAuthoredElementNameDistinguishing): ElementType;
|
|
102
|
+
createToken(token: Token): MLASTToken;
|
|
103
|
+
createToken(token: string, startOffset: number, startLine: number, startCol: number): MLASTToken;
|
|
104
|
+
sliceFragment(start: number, end?: number): Token;
|
|
105
|
+
walk<Node extends MLASTNodeTreeItem>(nodeList: readonly Node[], walker: Walker<Node>, depth?: number): void;
|
|
106
|
+
appendChild(parentNode: MLASTParentNode | null, ...childNodes: readonly MLASTChildNode[]): void;
|
|
107
|
+
replaceChild(parentNode: MLASTParentNode, oldChildNode: MLASTChildNode, newChildNode: MLASTChildNode): void;
|
|
108
|
+
}
|