@markuplint/parser-utils 3.0.0-dev.25 → 3.0.0-dev.300
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/lib/const.d.ts +3 -0
- package/lib/const.js +6 -5
- package/lib/create-token.js +11 -17
- package/lib/debugger.js +7 -8
- package/lib/decision.js +6 -11
- package/lib/detect-element-type.js +6 -10
- package/lib/flatten-nodes.d.ts +2 -0
- package/lib/flatten-nodes.js +245 -0
- package/lib/get-location.js +6 -14
- package/lib/get-space-before.d.ts +1 -0
- package/lib/get-space-before.js +8 -0
- package/lib/idl-attributes.js +25 -10
- package/lib/ignore-block.d.ts +2 -2
- package/lib/ignore-block.js +24 -28
- package/lib/ignore-front-matter.js +1 -5
- package/lib/index.d.ts +16 -10
- package/lib/index.js +16 -13
- package/lib/parse-attr.d.ts +24 -0
- package/lib/parse-attr.js +144 -0
- package/lib/parser-error.d.ts +19 -6
- package/lib/parser-error.js +26 -11
- package/lib/remove-deprecated-node.d.ts +7 -0
- package/lib/remove-deprecated-node.js +39 -0
- package/lib/siblings-correction.js +8 -7
- package/lib/tag-splitter.d.ts +7 -0
- package/lib/tag-splitter.js +89 -0
- package/lib/types.d.ts +12 -12
- package/lib/types.js +1 -2
- package/lib/walker.d.ts +1 -1
- package/lib/walker.js +4 -6
- package/package.json +17 -13
- package/lib/get-space-before-attr-name.d.ts +0 -2
- package/lib/get-space-before-attr-name.js +0 -12
- package/lib/idl-attributes.test.d.ts +0 -1
- package/lib/idl-attributes.test.js +0 -45
- package/tsconfig.test.json +0 -3
- package/tsconfig.tsbuildinfo +0 -1
package/lib/ignore-block.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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 { uuid } from './create-token.js';
|
|
3
|
+
import { sliceFragment } from './get-location.js';
|
|
4
|
+
import { siblingsCorrection } from './siblings-correction.js';
|
|
5
|
+
export function ignoreBlock(source, tags, maskChar = MASK_CHAR) {
|
|
9
6
|
let replaced = source;
|
|
10
7
|
const stack = [];
|
|
11
8
|
for (const tag of tags) {
|
|
@@ -13,7 +10,7 @@ function ignoreBlock(source, tags, maskChar = const_1.MASK_CHAR) {
|
|
|
13
10
|
const attr = maskText(prepend(tag.start, '(?<=(?:"|\'))'), append(tag.end, '(?=(?:"|\'))'), replaced, (startTag, taggedCode, endTag) => {
|
|
14
11
|
const mask = maskChar.repeat(startTag.length) +
|
|
15
12
|
taggedCode.replace(/[^\n]/g, maskChar) +
|
|
16
|
-
maskChar.repeat((endTag
|
|
13
|
+
maskChar.repeat((endTag ?? '').length);
|
|
17
14
|
return mask;
|
|
18
15
|
});
|
|
19
16
|
replaced = attr.replaced;
|
|
@@ -22,7 +19,7 @@ function ignoreBlock(source, tags, maskChar = const_1.MASK_CHAR) {
|
|
|
22
19
|
const text = maskText(tag.start, tag.end, replaced, (startTag, taggedCode, endTag) => {
|
|
23
20
|
const mask = maskChar.repeat(startTag.length) +
|
|
24
21
|
taggedCode.replace(/[^\n]/g, maskChar) +
|
|
25
|
-
maskChar.repeat((endTag
|
|
22
|
+
maskChar.repeat((endTag ?? '').length);
|
|
26
23
|
const taggedMask = `<!${mask.slice(2).slice(0, -1)}>`;
|
|
27
24
|
return taggedMask;
|
|
28
25
|
});
|
|
@@ -37,7 +34,6 @@ function ignoreBlock(source, tags, maskChar = const_1.MASK_CHAR) {
|
|
|
37
34
|
maskChar,
|
|
38
35
|
};
|
|
39
36
|
}
|
|
40
|
-
exports.ignoreBlock = ignoreBlock;
|
|
41
37
|
function maskText(start, end, replaced, masking) {
|
|
42
38
|
const stack = [];
|
|
43
39
|
start = removeGlobalOption(start);
|
|
@@ -52,20 +48,21 @@ function maskText(start, end, replaced, masking) {
|
|
|
52
48
|
index,
|
|
53
49
|
startTag,
|
|
54
50
|
taggedCode,
|
|
55
|
-
endTag: endTag
|
|
51
|
+
endTag: endTag ?? null,
|
|
56
52
|
});
|
|
57
53
|
/**
|
|
58
54
|
* It will not replace line breaks because detects line number.
|
|
59
55
|
*/
|
|
60
|
-
replaced = above + masking(startTag, taggedCode, endTag) + (below
|
|
56
|
+
replaced = above + masking(startTag, taggedCode, endTag) + (below ?? '');
|
|
61
57
|
}
|
|
62
58
|
return {
|
|
63
59
|
replaced,
|
|
64
60
|
stack,
|
|
65
61
|
};
|
|
66
62
|
}
|
|
67
|
-
function restoreNode(
|
|
68
|
-
|
|
63
|
+
export function restoreNode(
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
65
|
+
nodeList, ignoreBlock) {
|
|
69
66
|
nodeList = nodeList.slice();
|
|
70
67
|
const { source, stack, maskChar } = ignoreBlock;
|
|
71
68
|
for (const node of nodeList) {
|
|
@@ -81,15 +78,15 @@ function restoreNode(nodeList, ignoreBlock) {
|
|
|
81
78
|
for (const tag of stack) {
|
|
82
79
|
if (node.startOffset <= tag.index && tag.index < node.endOffset) {
|
|
83
80
|
const start = tag.index - node.startOffset;
|
|
84
|
-
const body = tag.startTag + tag.taggedCode + (tag.endTag
|
|
81
|
+
const body = tag.startTag + tag.taggedCode + (tag.endTag ?? '');
|
|
85
82
|
const above = node.raw.slice(pointer, start);
|
|
86
83
|
const below = text.slice(above.length + body.length);
|
|
87
84
|
if (above) {
|
|
88
85
|
const offset = node.startOffset + pointer;
|
|
89
|
-
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } =
|
|
86
|
+
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = sliceFragment(source, offset, offset + above.length);
|
|
90
87
|
const textNode = {
|
|
91
88
|
...node,
|
|
92
|
-
uuid:
|
|
89
|
+
uuid: uuid(),
|
|
93
90
|
type: 'text',
|
|
94
91
|
raw,
|
|
95
92
|
startOffset,
|
|
@@ -99,19 +96,19 @@ function restoreNode(nodeList, ignoreBlock) {
|
|
|
99
96
|
startCol,
|
|
100
97
|
endCol,
|
|
101
98
|
};
|
|
102
|
-
if (
|
|
99
|
+
if (node.prevNode?.nextNode) {
|
|
103
100
|
node.prevNode.nextNode = textNode;
|
|
104
101
|
}
|
|
105
|
-
if (
|
|
102
|
+
if (node.nextNode?.prevNode) {
|
|
106
103
|
node.nextNode.prevNode = textNode;
|
|
107
104
|
}
|
|
108
105
|
insertList.push(textNode);
|
|
109
106
|
}
|
|
110
107
|
if (body) {
|
|
111
108
|
const offset = node.startOffset + pointer + above.length;
|
|
112
|
-
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } =
|
|
109
|
+
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = sliceFragment(source, offset, offset + body.length);
|
|
113
110
|
const bodyNode = {
|
|
114
|
-
uuid:
|
|
111
|
+
uuid: uuid(),
|
|
115
112
|
type: 'psblock',
|
|
116
113
|
nodeName: `#ps:${tag.type}`,
|
|
117
114
|
raw,
|
|
@@ -127,10 +124,10 @@ function restoreNode(nodeList, ignoreBlock) {
|
|
|
127
124
|
startCol,
|
|
128
125
|
endCol,
|
|
129
126
|
};
|
|
130
|
-
if (
|
|
127
|
+
if (node.prevNode?.nextNode) {
|
|
131
128
|
node.prevNode.nextNode = bodyNode;
|
|
132
129
|
}
|
|
133
|
-
if (
|
|
130
|
+
if (node.nextNode?.prevNode) {
|
|
134
131
|
node.nextNode.prevNode = bodyNode;
|
|
135
132
|
}
|
|
136
133
|
insertList.push(bodyNode);
|
|
@@ -141,10 +138,10 @@ function restoreNode(nodeList, ignoreBlock) {
|
|
|
141
138
|
}
|
|
142
139
|
if (text) {
|
|
143
140
|
const offset = node.endOffset - text.length;
|
|
144
|
-
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } =
|
|
141
|
+
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = sliceFragment(source, offset, offset + text.length);
|
|
145
142
|
const textNode = {
|
|
146
143
|
...node,
|
|
147
|
-
uuid:
|
|
144
|
+
uuid: uuid(),
|
|
148
145
|
type: 'text',
|
|
149
146
|
raw,
|
|
150
147
|
startOffset,
|
|
@@ -156,7 +153,7 @@ function restoreNode(nodeList, ignoreBlock) {
|
|
|
156
153
|
};
|
|
157
154
|
insertList.push(textNode);
|
|
158
155
|
}
|
|
159
|
-
|
|
156
|
+
siblingsCorrection(insertList);
|
|
160
157
|
if (parentNode) {
|
|
161
158
|
parentNode.childNodes = insertList;
|
|
162
159
|
}
|
|
@@ -183,7 +180,6 @@ function restoreNode(nodeList, ignoreBlock) {
|
|
|
183
180
|
}
|
|
184
181
|
return nodeList;
|
|
185
182
|
}
|
|
186
|
-
exports.restoreNode = restoreNode;
|
|
187
183
|
function snap(str, reg) {
|
|
188
184
|
const matched = reg.exec(str);
|
|
189
185
|
if (!matched) {
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ignoreFrontMatter = void 0;
|
|
4
|
-
function ignoreFrontMatter(code) {
|
|
1
|
+
export function ignoreFrontMatter(code) {
|
|
5
2
|
const reStart = /^(?:\s*\r?\n)?---\r?\n/.exec(code);
|
|
6
3
|
if (!reStart) {
|
|
7
4
|
return code;
|
|
@@ -18,4 +15,3 @@ function ignoreFrontMatter(code) {
|
|
|
18
15
|
const masked = frontMatter.replace(/[^\r\n]/g, ' ');
|
|
19
16
|
return masked + afterCode;
|
|
20
17
|
}
|
|
21
|
-
exports.ignoreFrontMatter = ignoreFrontMatter;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
9
|
-
export * from './
|
|
10
|
-
export * from './
|
|
1
|
+
export * from './const.js';
|
|
2
|
+
export * from './create-token.js';
|
|
3
|
+
export * from './debugger.js';
|
|
4
|
+
export * from './decision.js';
|
|
5
|
+
export * from './detect-element-type.js';
|
|
6
|
+
export * from './flatten-nodes.js';
|
|
7
|
+
export * from './get-location.js';
|
|
8
|
+
export * from './get-space-before.js';
|
|
9
|
+
export * from './idl-attributes.js';
|
|
10
|
+
export * from './ignore-block.js';
|
|
11
|
+
export * from './ignore-front-matter.js';
|
|
12
|
+
export * from './parse-attr.js';
|
|
13
|
+
export * from './parser-error.js';
|
|
14
|
+
export * from './remove-deprecated-node.js';
|
|
15
|
+
export * from './tag-splitter.js';
|
|
16
|
+
export * from './walker.js';
|
package/lib/index.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
export * from './const.js';
|
|
2
|
+
export * from './create-token.js';
|
|
3
|
+
export * from './debugger.js';
|
|
4
|
+
export * from './decision.js';
|
|
5
|
+
export * from './detect-element-type.js';
|
|
6
|
+
export * from './flatten-nodes.js';
|
|
7
|
+
export * from './get-location.js';
|
|
8
|
+
export * from './get-space-before.js';
|
|
9
|
+
export * from './idl-attributes.js';
|
|
10
|
+
export * from './ignore-block.js';
|
|
11
|
+
export * from './ignore-front-matter.js';
|
|
12
|
+
export * from './parse-attr.js';
|
|
13
|
+
export * from './parser-error.js';
|
|
14
|
+
export * from './remove-deprecated-node.js';
|
|
15
|
+
export * from './tag-splitter.js';
|
|
16
|
+
export * from './walker.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { MLASTHTMLAttr } from '@markuplint/ml-ast';
|
|
2
|
+
type ParseAttrOptions = {
|
|
3
|
+
readonly booleanish?: boolean;
|
|
4
|
+
readonly valueDelimiters?: readonly ValueDelimiter[];
|
|
5
|
+
readonly equal?: string;
|
|
6
|
+
};
|
|
7
|
+
type ValueDelimiter = {
|
|
8
|
+
readonly start: string;
|
|
9
|
+
readonly end: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const defaultValueDelimiters: readonly ValueDelimiter[];
|
|
12
|
+
export declare function parseAttr(raw: string, offset: number, html: string, options?: ParseAttrOptions): MLASTHTMLAttr;
|
|
13
|
+
export declare function tokenize(raw: string, options?: ParseAttrOptions): {
|
|
14
|
+
beforeName: string;
|
|
15
|
+
name: string;
|
|
16
|
+
afterName: string;
|
|
17
|
+
equal: string;
|
|
18
|
+
beforeValue: string;
|
|
19
|
+
startQuote: string;
|
|
20
|
+
value: string;
|
|
21
|
+
endQuote: string;
|
|
22
|
+
afterAttr: string;
|
|
23
|
+
};
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { createTokenFromRawCode, tokenizer, uuid } from './create-token.js';
|
|
2
|
+
export const defaultValueDelimiters = [
|
|
3
|
+
{
|
|
4
|
+
start: "'",
|
|
5
|
+
end: "'",
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
start: '"',
|
|
9
|
+
end: '"',
|
|
10
|
+
},
|
|
11
|
+
];
|
|
12
|
+
const defaultEqual = '=';
|
|
13
|
+
const spaceRegex = /^\s$/;
|
|
14
|
+
export function parseAttr(raw, offset, html, options) {
|
|
15
|
+
const tokens = tokenize(raw, options);
|
|
16
|
+
tokens.beforeName;
|
|
17
|
+
const attrToken = createTokenFromRawCode(raw, offset, html);
|
|
18
|
+
const spacesBeforeName = tokenizer(tokens.beforeName, attrToken.startLine, attrToken.startCol, attrToken.startOffset);
|
|
19
|
+
const name = tokenizer(tokens.name, spacesBeforeName.endLine, spacesBeforeName.endCol, spacesBeforeName.endOffset);
|
|
20
|
+
const spacesBeforeEqual = tokenizer(tokens.afterName, name.endLine, name.endCol, name.endOffset);
|
|
21
|
+
const equal = tokenizer(tokens.equal, spacesBeforeEqual.endLine, spacesBeforeEqual.endCol, spacesBeforeEqual.endOffset);
|
|
22
|
+
const spacesAfterEqual = tokenizer(tokens.beforeValue, equal.endLine, equal.endCol, equal.endOffset);
|
|
23
|
+
const startQuote = tokenizer(tokens.startQuote, spacesAfterEqual.endLine, spacesAfterEqual.endCol, spacesAfterEqual.endOffset);
|
|
24
|
+
const value = tokenizer(tokens.value, startQuote.endLine, startQuote.endCol, startQuote.endOffset);
|
|
25
|
+
const endQuote = tokenizer(tokens.endQuote, value.endLine, value.endCol, value.endOffset);
|
|
26
|
+
const attr = {
|
|
27
|
+
type: 'html-attr',
|
|
28
|
+
uuid: uuid(),
|
|
29
|
+
raw: attrToken.raw,
|
|
30
|
+
startOffset: attrToken.startOffset,
|
|
31
|
+
endOffset: attrToken.endOffset,
|
|
32
|
+
startLine: attrToken.startLine,
|
|
33
|
+
endLine: attrToken.endLine,
|
|
34
|
+
startCol: attrToken.startCol,
|
|
35
|
+
endCol: attrToken.endCol,
|
|
36
|
+
spacesBeforeName,
|
|
37
|
+
name,
|
|
38
|
+
spacesBeforeEqual,
|
|
39
|
+
equal,
|
|
40
|
+
spacesAfterEqual,
|
|
41
|
+
startQuote,
|
|
42
|
+
value,
|
|
43
|
+
endQuote,
|
|
44
|
+
isDuplicatable: false,
|
|
45
|
+
nodeName: name.raw,
|
|
46
|
+
parentNode: null,
|
|
47
|
+
nextNode: null,
|
|
48
|
+
prevNode: null,
|
|
49
|
+
isFragment: false,
|
|
50
|
+
isGhost: false,
|
|
51
|
+
};
|
|
52
|
+
return attr;
|
|
53
|
+
}
|
|
54
|
+
export function tokenize(raw, options) {
|
|
55
|
+
const valueDelimiters = options?.valueDelimiters ?? defaultValueDelimiters;
|
|
56
|
+
const equalDelimiter = options?.equal ?? defaultEqual;
|
|
57
|
+
let state = 'b-name';
|
|
58
|
+
const charactors = raw.split('');
|
|
59
|
+
let beforeName = '';
|
|
60
|
+
let name = '';
|
|
61
|
+
let afterName = '';
|
|
62
|
+
let equal = '';
|
|
63
|
+
let valueDelimiter = null;
|
|
64
|
+
let beforeValue = '';
|
|
65
|
+
let startQuote = '';
|
|
66
|
+
let value = '';
|
|
67
|
+
let endQuote = '';
|
|
68
|
+
let afterAttr = '';
|
|
69
|
+
while (charactors.length > 0) {
|
|
70
|
+
const charactor = charactors.shift();
|
|
71
|
+
if (state === 'b-name') {
|
|
72
|
+
if (spaceRegex.test(charactor)) {
|
|
73
|
+
beforeName += charactor;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
name += charactor;
|
|
77
|
+
state = 'name';
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (state === 'name') {
|
|
81
|
+
if (equalDelimiter === charactor) {
|
|
82
|
+
equal = equalDelimiter;
|
|
83
|
+
state = 'value-start';
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (spaceRegex.test(charactor)) {
|
|
87
|
+
afterName += charactor;
|
|
88
|
+
state = 'a-name';
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
name += charactor;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (state === 'a-name') {
|
|
95
|
+
if (equalDelimiter === charactor) {
|
|
96
|
+
equal = equalDelimiter;
|
|
97
|
+
state = 'value-start';
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (spaceRegex.test(charactor)) {
|
|
101
|
+
afterName += charactor;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
if (state === 'value-start') {
|
|
107
|
+
if (spaceRegex.test(charactor)) {
|
|
108
|
+
beforeValue += charactor;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
valueDelimiter = valueDelimiters.find(d => d.start === charactor) ?? null;
|
|
112
|
+
if (valueDelimiter) {
|
|
113
|
+
startQuote += valueDelimiter.start;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
value += beforeValue + charactor;
|
|
117
|
+
beforeValue = '';
|
|
118
|
+
}
|
|
119
|
+
state = 'value';
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (state !== 'value') {
|
|
123
|
+
throw new Error('ParseError: unknown parse state in the attribute');
|
|
124
|
+
}
|
|
125
|
+
value += charactor;
|
|
126
|
+
}
|
|
127
|
+
if (valueDelimiter) {
|
|
128
|
+
const endQuoteIndex = value.lastIndexOf(valueDelimiter.end);
|
|
129
|
+
endQuote = value.slice(endQuoteIndex, endQuoteIndex + 1);
|
|
130
|
+
afterAttr = value.slice(endQuoteIndex + 1);
|
|
131
|
+
value = value.slice(0, endQuoteIndex);
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
beforeName,
|
|
135
|
+
name,
|
|
136
|
+
afterName,
|
|
137
|
+
equal,
|
|
138
|
+
beforeValue,
|
|
139
|
+
startQuote,
|
|
140
|
+
value,
|
|
141
|
+
endQuote,
|
|
142
|
+
afterAttr,
|
|
143
|
+
};
|
|
144
|
+
}
|
package/lib/parser-error.d.ts
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
|
+
export type ParserErrorInfo = {
|
|
2
|
+
readonly line?: number;
|
|
3
|
+
readonly col?: number;
|
|
4
|
+
readonly raw?: string;
|
|
5
|
+
};
|
|
1
6
|
export declare class ParserError extends Error {
|
|
2
7
|
readonly col: number;
|
|
3
8
|
readonly line: number;
|
|
4
9
|
name: string;
|
|
5
|
-
readonly nodeName: string | null;
|
|
6
10
|
readonly raw: string;
|
|
7
|
-
constructor(message: string,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
constructor(message: string, info: ParserErrorInfo);
|
|
12
|
+
}
|
|
13
|
+
export declare class TargetParserError extends ParserError {
|
|
14
|
+
name: string;
|
|
15
|
+
readonly nodeName: string | null;
|
|
16
|
+
constructor(message: string, info: ParserErrorInfo & {
|
|
17
|
+
readonly nodeName?: string | null;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export declare class ConfigParserError extends ParserError {
|
|
21
|
+
readonly filePath: string;
|
|
22
|
+
name: string;
|
|
23
|
+
constructor(message: string, info: ParserErrorInfo & {
|
|
24
|
+
readonly filePath: string;
|
|
12
25
|
});
|
|
13
26
|
}
|
package/lib/parser-error.js
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class ParserError extends Error {
|
|
5
|
-
constructor(message, { line = 1, col = 0, raw = '', nodeName = null, }) {
|
|
6
|
-
super(nodeName ? `The ${nodeName} is invalid element (${line}:${col}): ${message}` : message);
|
|
1
|
+
export class ParserError extends Error {
|
|
2
|
+
constructor(message, info) {
|
|
3
|
+
super(message);
|
|
7
4
|
this.name = 'ParserError';
|
|
8
|
-
this.line = line;
|
|
9
|
-
this.col = col;
|
|
10
|
-
this.raw = raw;
|
|
11
|
-
|
|
5
|
+
this.line = info.line ?? 1;
|
|
6
|
+
this.col = info.col ?? 0;
|
|
7
|
+
this.raw = info.raw ?? '';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class TargetParserError extends ParserError {
|
|
11
|
+
constructor(message, info) {
|
|
12
|
+
const errMsg = info.nodeName
|
|
13
|
+
? `The ${info.nodeName} is invalid element (${info.line}:${info.col}): ${message}`
|
|
14
|
+
: message;
|
|
15
|
+
super(errMsg, info);
|
|
16
|
+
this.name = 'TargetParserError';
|
|
17
|
+
this.nodeName = info.nodeName ?? null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class ConfigParserError extends ParserError {
|
|
21
|
+
constructor(message, info) {
|
|
22
|
+
const pos = info.line != null && info.line != null ? `(${info.line}:${info.col})` : '';
|
|
23
|
+
const file = ` in ${info.filePath}${pos}`;
|
|
24
|
+
const errMsg = `${message}${file}`;
|
|
25
|
+
super(errMsg, info);
|
|
26
|
+
this.name = 'ConfigParserError';
|
|
27
|
+
this.filePath = info.filePath;
|
|
12
28
|
}
|
|
13
29
|
}
|
|
14
|
-
exports.ParserError = ParserError;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @disruptive
|
|
4
|
+
* @param nodeOrders [Disruptive change]
|
|
5
|
+
*/
|
|
6
|
+
export function removeDeprecatedNode(
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
8
|
+
nodeOrders) {
|
|
9
|
+
/**
|
|
10
|
+
* sorting
|
|
11
|
+
*/
|
|
12
|
+
nodeOrders.sort((a, b) => {
|
|
13
|
+
if (a.isGhost || b.isGhost) {
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
return a.startOffset - b.startOffset;
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* remove duplicated node
|
|
20
|
+
*/
|
|
21
|
+
const stack = {};
|
|
22
|
+
const removeIndexes = [];
|
|
23
|
+
nodeOrders.forEach((node, i) => {
|
|
24
|
+
if (node.isGhost) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const id = `${node.startLine}:${node.startCol}:${node.endLine}:${node.endCol}`;
|
|
28
|
+
if (stack[id] != null) {
|
|
29
|
+
removeIndexes.push(i);
|
|
30
|
+
}
|
|
31
|
+
stack[id] = i;
|
|
32
|
+
});
|
|
33
|
+
let r = nodeOrders.length;
|
|
34
|
+
while (r-- > 0) {
|
|
35
|
+
if (removeIndexes.includes(r)) {
|
|
36
|
+
nodeOrders.splice(r, 1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.siblingsCorrection = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Correct the references to prevNode and nextNode in the order listed.
|
|
6
3
|
*
|
|
@@ -8,13 +5,17 @@ exports.siblingsCorrection = void 0;
|
|
|
8
5
|
* @affects nodeList[].prevNode
|
|
9
6
|
* @affects nodeList[].nextNode
|
|
10
7
|
*/
|
|
11
|
-
function siblingsCorrection(
|
|
8
|
+
export function siblingsCorrection(
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
10
|
+
nodeList) {
|
|
12
11
|
for (let i = 0; i < nodeList.length; i++) {
|
|
13
|
-
const prevNode = nodeList[i - 1]
|
|
12
|
+
const prevNode = nodeList[i - 1] ?? null;
|
|
14
13
|
const node = nodeList[i];
|
|
15
|
-
|
|
14
|
+
if (!node) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const nextNode = nodeList[i + 1] ?? null;
|
|
16
18
|
node.prevNode = prevNode;
|
|
17
19
|
node.nextNode = nextNode;
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
|
-
exports.siblingsCorrection = siblingsCorrection;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { reSplitterTag, reTagName } from './const.js';
|
|
2
|
+
import { getEndCol, getEndLine } from '@markuplint/parser-utils';
|
|
3
|
+
export default function tagSplitter(raw, line, col) {
|
|
4
|
+
return withLocation(tagSplitterAsString(raw), line, col);
|
|
5
|
+
}
|
|
6
|
+
function tagSplitterAsString(raw) {
|
|
7
|
+
const tagMatches = raw.match(reSplitterTag);
|
|
8
|
+
if (!tagMatches) {
|
|
9
|
+
return [raw];
|
|
10
|
+
}
|
|
11
|
+
const tokens = Array.from(tagMatches);
|
|
12
|
+
tokens.unshift(); // remove all match
|
|
13
|
+
const nodes = [];
|
|
14
|
+
let rest = raw;
|
|
15
|
+
for (const token of tokens) {
|
|
16
|
+
const index = rest.indexOf(token);
|
|
17
|
+
let length = token.length;
|
|
18
|
+
if (index > 0) {
|
|
19
|
+
const text = rest.slice(0, index);
|
|
20
|
+
nodes.push(text);
|
|
21
|
+
length += text.length;
|
|
22
|
+
}
|
|
23
|
+
nodes.push(token);
|
|
24
|
+
rest = rest.slice(length);
|
|
25
|
+
}
|
|
26
|
+
if (rest) {
|
|
27
|
+
nodes.push(rest);
|
|
28
|
+
}
|
|
29
|
+
return nodes;
|
|
30
|
+
}
|
|
31
|
+
function withLocation(nodes, line, col) {
|
|
32
|
+
const result = [];
|
|
33
|
+
for (const node of nodes) {
|
|
34
|
+
if (node[0] !== '<') {
|
|
35
|
+
result.push({
|
|
36
|
+
type: 'text',
|
|
37
|
+
raw: node,
|
|
38
|
+
line,
|
|
39
|
+
col,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const label = node.slice(1).slice(0, -1);
|
|
44
|
+
if (reTagName.test(label)) {
|
|
45
|
+
result.push({
|
|
46
|
+
type: 'starttag',
|
|
47
|
+
raw: node,
|
|
48
|
+
line,
|
|
49
|
+
col,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else if (label[0] === '/') {
|
|
53
|
+
result.push({
|
|
54
|
+
type: 'endtag',
|
|
55
|
+
raw: node,
|
|
56
|
+
line,
|
|
57
|
+
col,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else if (label[0] === '!') {
|
|
61
|
+
result.push({
|
|
62
|
+
type: 'comment',
|
|
63
|
+
raw: node,
|
|
64
|
+
line,
|
|
65
|
+
col,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
else if (label[0] === '?') {
|
|
69
|
+
result.push({
|
|
70
|
+
type: 'boguscomment',
|
|
71
|
+
raw: node,
|
|
72
|
+
line,
|
|
73
|
+
col,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
result.push({
|
|
78
|
+
type: 'text',
|
|
79
|
+
raw: node,
|
|
80
|
+
line,
|
|
81
|
+
col,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
line = getEndLine(node, line);
|
|
86
|
+
col = getEndCol(node, col);
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|