@blcklab/yuirinx 0.1.1 → 0.1.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.
- package/README.md +47 -64
- package/dist/cjs/core/index.cjs +36 -7
- package/dist/cjs/index.cjs +37 -8
- package/dist/cjs/languages/c.cjs +1 -1
- package/dist/cjs/languages/cpp.cjs +1 -1
- package/dist/cjs/languages/csharp.cjs +1 -1
- package/dist/cjs/languages/css.cjs +2 -2
- package/dist/cjs/languages/dart.cjs +1 -1
- package/dist/cjs/languages/go.cjs +1 -1
- package/dist/cjs/languages/java.cjs +1 -1
- package/dist/cjs/languages/javascript.cjs +65 -6
- package/dist/cjs/languages/jsx.cjs +65 -6
- package/dist/cjs/languages/kotlin.cjs +1 -1
- package/dist/cjs/languages/markdown.cjs +30 -6
- package/dist/cjs/languages/php.cjs +1 -1
- package/dist/cjs/languages/python.cjs +1 -1
- package/dist/cjs/languages/ruby.cjs +1 -1
- package/dist/cjs/languages/rust.cjs +1 -1
- package/dist/cjs/languages/scss.cjs +2 -2
- package/dist/cjs/languages/sql.cjs +1 -1
- package/dist/cjs/languages/swift.cjs +1 -1
- package/dist/cjs/languages/tsx.cjs +65 -6
- package/dist/cjs/languages/typescript.cjs +65 -6
- package/dist/esm/core/create-highlighter.js +132 -0
- package/dist/esm/core/errors.js +10 -0
- package/dist/esm/core/escape.js +17 -0
- package/dist/esm/core/grammar.js +103 -0
- package/dist/esm/core/index.js +4 -536
- package/dist/esm/core/renderer.js +215 -0
- package/dist/esm/core/tokenizer.js +107 -0
- package/dist/esm/core/types.js +0 -0
- package/dist/esm/index.js +8 -558
- package/dist/esm/languages/bash.js +9 -21
- package/dist/esm/languages/c.js +2 -82
- package/dist/esm/languages/cpp.js +2 -82
- package/dist/esm/languages/csharp.js +2 -82
- package/dist/esm/languages/css.js +2 -64
- package/dist/esm/languages/dart.js +2 -82
- package/dist/esm/languages/dockerfile.js +3 -12
- package/dist/esm/languages/go.js +2 -82
- package/dist/esm/languages/graphql.js +8 -20
- package/dist/esm/languages/html.js +2 -44
- package/dist/esm/languages/ini.js +2 -5
- package/dist/esm/languages/java.js +2 -82
- package/dist/esm/languages/javascript.js +2 -229
- package/dist/esm/languages/json.js +2 -5
- package/dist/esm/languages/jsx.js +2 -229
- package/dist/esm/languages/kotlin.js +2 -82
- package/dist/esm/languages/markdown.js +32 -11
- package/dist/esm/languages/nginx.js +2 -5
- package/dist/esm/languages/php.js +3 -83
- package/dist/esm/languages/plaintext.js +1 -2
- package/dist/esm/languages/python.js +10 -25
- package/dist/esm/languages/ruby.js +9 -24
- package/dist/esm/languages/rust.js +2 -82
- package/dist/esm/languages/scss.js +2 -64
- package/dist/esm/languages/shared/c-family.js +55 -0
- package/dist/esm/languages/shared/css.js +48 -0
- package/dist/esm/languages/shared/ecmascript.js +261 -0
- package/dist/esm/languages/shared/helpers.js +52 -0
- package/dist/esm/languages/shared/markup.js +41 -0
- package/dist/esm/languages/shell.js +1 -115
- package/dist/esm/languages/sql.js +11 -32
- package/dist/esm/languages/svelte.js +2 -44
- package/dist/esm/languages/swift.js +2 -82
- package/dist/esm/languages/toml.js +2 -5
- package/dist/esm/languages/tsx.js +2 -229
- package/dist/esm/languages/typescript.js +2 -229
- package/dist/esm/languages/vue.js +2 -44
- package/dist/esm/languages/xml.js +2 -44
- package/dist/esm/languages/yaml.js +2 -5
- package/dist/esm/singleton.js +24 -0
- package/dist/esm/themes/index.js +3 -188
- package/dist/esm/themes/yuirinx-aurora.js +1 -2
- package/dist/esm/themes/yuirinx-noir.js +1 -2
- package/dist/esm/themes/yuirinx-pearl.js +1 -2
- package/dist/types/core/errors.d.cts +1 -1
- package/dist/types/core/errors.d.ts +1 -1
- package/dist/types/core/index.d.cts +1 -1
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/types.d.cts +5 -1
- package/dist/types/core/types.d.ts +5 -1
- package/dist/types/singleton.d.cts +1 -1
- package/dist/types/singleton.d.ts +1 -1
- package/package.json +4 -4
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -163,6 +163,18 @@ var BUILTINS = [
|
|
|
163
163
|
"process",
|
|
164
164
|
"window"
|
|
165
165
|
];
|
|
166
|
+
function canStartRegex(source, offset) {
|
|
167
|
+
const before = source.slice(0, offset).trimEnd();
|
|
168
|
+
if (!before) return true;
|
|
169
|
+
const previous = before[before.length - 1] ?? "";
|
|
170
|
+
if (/[([{,:;=!?&|+\-*%^~<>]/.test(previous)) return true;
|
|
171
|
+
const word = /[A-Za-z_$][\w$]*$/.exec(before)?.[0];
|
|
172
|
+
return Boolean(
|
|
173
|
+
word && /^(?:await|case|delete|do|else|in|instanceof|new|of|return|throw|typeof|void|yield)$/.test(
|
|
174
|
+
word
|
|
175
|
+
)
|
|
176
|
+
);
|
|
177
|
+
}
|
|
166
178
|
function createEcmaGrammar(options) {
|
|
167
179
|
const keywordValues = options.typescript ? [...JS_KEYWORDS, ...TS_KEYWORDS] : JS_KEYWORDS;
|
|
168
180
|
const rootRules = [
|
|
@@ -173,16 +185,23 @@ function createEcmaGrammar(options) {
|
|
|
173
185
|
{ type: "string", pattern: /`/, push: "template" }
|
|
174
186
|
];
|
|
175
187
|
if (options.jsx) {
|
|
188
|
+
if (options.typescript) {
|
|
189
|
+
rootRules.push({
|
|
190
|
+
type: "operator",
|
|
191
|
+
pattern: /<(?=[A-Za-z_$][\w$]*(?:\s+extends\s+[^>]+)?,?>\s*\()/
|
|
192
|
+
});
|
|
193
|
+
}
|
|
176
194
|
rootRules.push({
|
|
177
195
|
type: "tag.punctuation",
|
|
178
|
-
pattern:
|
|
179
|
-
push: "
|
|
196
|
+
pattern: /<(?=[A-Za-z_$>])/,
|
|
197
|
+
push: "jsxTagName"
|
|
180
198
|
});
|
|
181
199
|
}
|
|
182
200
|
rootRules.push(
|
|
183
201
|
{
|
|
184
202
|
type: "regex",
|
|
185
|
-
pattern: /\/(?![/*\s])(?:\\.|\[(?:\\.|[^\]\\])*\]|[^/\\\r\n])+\/[dgimsuvy]
|
|
203
|
+
pattern: /\/(?![/*\s])(?:\\.|\[(?:\\.|[^\]\\])*\]|[^/\\\r\n])+\/[dgimsuvy]*/,
|
|
204
|
+
when: (_match, context) => canStartRegex(context.source, context.offset)
|
|
186
205
|
},
|
|
187
206
|
numberRule,
|
|
188
207
|
{ type: "boolean", pattern: /\b(?:true|false)\b/ },
|
|
@@ -228,14 +247,54 @@ function createEcmaGrammar(options) {
|
|
|
228
247
|
{ include: "root" }
|
|
229
248
|
]
|
|
230
249
|
},
|
|
231
|
-
|
|
250
|
+
jsxTagName: {
|
|
251
|
+
rules: [
|
|
252
|
+
{ type: "tag.punctuation", pattern: />/, next: "jsxChildren" },
|
|
253
|
+
{ type: "tag.punctuation", pattern: /\/>/, pop: true },
|
|
254
|
+
whitespaceRule,
|
|
255
|
+
{
|
|
256
|
+
type: "tag",
|
|
257
|
+
pattern: /[A-Za-z_$][\w$.-]*/,
|
|
258
|
+
next: "jsxAttributes"
|
|
259
|
+
},
|
|
260
|
+
punctuationRule
|
|
261
|
+
]
|
|
262
|
+
},
|
|
263
|
+
jsxAttributes: {
|
|
232
264
|
rules: [
|
|
233
|
-
{ type: "tag.punctuation", pattern:
|
|
265
|
+
{ type: "tag.punctuation", pattern: /\/>/, pop: true },
|
|
266
|
+
{ type: "tag.punctuation", pattern: />/, next: "jsxChildren" },
|
|
234
267
|
whitespaceRule,
|
|
235
268
|
{ type: "attribute.value", pattern: /"(?:\\.|[^"\\])*"?/ },
|
|
236
269
|
{ type: "attribute.value", pattern: /'(?:\\.|[^'\\])*'?/ },
|
|
237
270
|
{ type: "punctuation", pattern: /{/, push: "jsxExpression" },
|
|
238
271
|
{ type: "operator", pattern: /=/ },
|
|
272
|
+
{ type: "attribute", pattern: /[A-Za-z_$][\w$.-]*/ },
|
|
273
|
+
punctuationRule
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
jsxChildren: {
|
|
277
|
+
fallbackType: "plain",
|
|
278
|
+
rules: [
|
|
279
|
+
{
|
|
280
|
+
type: "tag.punctuation",
|
|
281
|
+
pattern: /<\/(?=[A-Za-z_$>])/,
|
|
282
|
+
push: "jsxClosingTag"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
type: "tag.punctuation",
|
|
286
|
+
pattern: /<(?=[A-Za-z_$>])/,
|
|
287
|
+
push: "jsxTagName"
|
|
288
|
+
},
|
|
289
|
+
{ type: "punctuation", pattern: /{/, push: "jsxExpression" },
|
|
290
|
+
{ type: "plain", pattern: /[^<{]+/ },
|
|
291
|
+
{ type: "plain", pattern: /[<{]/ }
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
jsxClosingTag: {
|
|
295
|
+
rules: [
|
|
296
|
+
{ type: "tag.punctuation", pattern: />/, pop: 2 },
|
|
297
|
+
whitespaceRule,
|
|
239
298
|
{ type: "tag", pattern: /[A-Za-z_$][\w$.-]*/ },
|
|
240
299
|
punctuationRule
|
|
241
300
|
]
|
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -28,20 +28,39 @@ module.exports = __toCommonJS(markdown_exports);
|
|
|
28
28
|
var whitespaceRule = { type: "plain", pattern: /\s+/ };
|
|
29
29
|
|
|
30
30
|
// src/languages/markdown.ts
|
|
31
|
+
var atLineStart = (_match, context) => context.offset === 0 || /[\r\n]/.test(context.source[context.offset - 1] ?? "");
|
|
31
32
|
var markdown = {
|
|
32
33
|
id: "markdown",
|
|
33
34
|
aliases: ["md", "mdown"],
|
|
34
35
|
states: {
|
|
35
36
|
root: {
|
|
36
37
|
rules: [
|
|
37
|
-
{
|
|
38
|
-
|
|
38
|
+
{
|
|
39
|
+
type: "meta",
|
|
40
|
+
pattern: / {0,3}```[^\r\n]*(?:\r?\n|$)/,
|
|
41
|
+
when: atLineStart,
|
|
42
|
+
push: "fence"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: "heading",
|
|
46
|
+
pattern: / {0,3}#{1,6}[ \t]+[^\r\n]*/,
|
|
47
|
+
when: atLineStart
|
|
48
|
+
},
|
|
39
49
|
{
|
|
40
50
|
type: "heading",
|
|
41
|
-
pattern: /[^\r\n]+\r?\n(?:===+|---+)[ \t]*(?:\r?\n|$)
|
|
51
|
+
pattern: /[^\r\n]+\r?\n {0,3}(?:===+|---+)[ \t]*(?:\r?\n|$)/,
|
|
52
|
+
when: atLineStart
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: "quote",
|
|
56
|
+
pattern: / {0,3}>[ \t]?[^\r\n]*/,
|
|
57
|
+
when: atLineStart
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: "list",
|
|
61
|
+
pattern: / {0,3}(?:[-+*]|\d+[.)])[ \t]+/,
|
|
62
|
+
when: atLineStart
|
|
42
63
|
},
|
|
43
|
-
{ type: "quote", pattern: />[ \t]?[^\r\n]*/ },
|
|
44
|
-
{ type: "list", pattern: /(?:[-+*]|\d+[.)])[ \t]+/ },
|
|
45
64
|
{ type: "important", pattern: /!\[[^\]\r\n]*\]\([^\r\n)]*\)/ },
|
|
46
65
|
{ type: "link", pattern: /\[[^\]\r\n]+\]\([^\r\n)]*\)/ },
|
|
47
66
|
{ type: "url", pattern: /https?:\/\/[^\s<>()]+/ },
|
|
@@ -57,7 +76,12 @@ var markdown = {
|
|
|
57
76
|
fence: {
|
|
58
77
|
fallbackType: "code",
|
|
59
78
|
rules: [
|
|
60
|
-
{
|
|
79
|
+
{
|
|
80
|
+
type: "meta",
|
|
81
|
+
pattern: / {0,3}```[ \t]*(?:\r?\n|$)/,
|
|
82
|
+
when: atLineStart,
|
|
83
|
+
pop: true
|
|
84
|
+
},
|
|
61
85
|
{ type: "code", pattern: /[^`]+/ },
|
|
62
86
|
{ type: "code", pattern: /`/ }
|
|
63
87
|
]
|
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -32,7 +32,7 @@ var punctuationRule = {
|
|
|
32
32
|
};
|
|
33
33
|
var operatorRule = {
|
|
34
34
|
type: "operator",
|
|
35
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
35
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
36
36
|
};
|
|
37
37
|
var doubleStringRule = {
|
|
38
38
|
type: "string",
|
|
@@ -61,7 +61,7 @@ function createCssGrammar(options) {
|
|
|
61
61
|
{ type: "number", pattern: /(?:\b\d*\.\d+|\b\d+)(?:e[+-]?\d+)?/i },
|
|
62
62
|
{
|
|
63
63
|
type: "unit",
|
|
64
|
-
pattern: /(
|
|
64
|
+
pattern: /(?:%(?![\w-])|(?:px|r?em|vh|vw|vmin|vmax|ch|ex|cm|mm|in|pt|pc|s|ms|deg|rad|turn)\b)/i
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
type: "selector",
|
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -163,6 +163,18 @@ var BUILTINS = [
|
|
|
163
163
|
"process",
|
|
164
164
|
"window"
|
|
165
165
|
];
|
|
166
|
+
function canStartRegex(source, offset) {
|
|
167
|
+
const before = source.slice(0, offset).trimEnd();
|
|
168
|
+
if (!before) return true;
|
|
169
|
+
const previous = before[before.length - 1] ?? "";
|
|
170
|
+
if (/[([{,:;=!?&|+\-*%^~<>]/.test(previous)) return true;
|
|
171
|
+
const word = /[A-Za-z_$][\w$]*$/.exec(before)?.[0];
|
|
172
|
+
return Boolean(
|
|
173
|
+
word && /^(?:await|case|delete|do|else|in|instanceof|new|of|return|throw|typeof|void|yield)$/.test(
|
|
174
|
+
word
|
|
175
|
+
)
|
|
176
|
+
);
|
|
177
|
+
}
|
|
166
178
|
function createEcmaGrammar(options) {
|
|
167
179
|
const keywordValues = options.typescript ? [...JS_KEYWORDS, ...TS_KEYWORDS] : JS_KEYWORDS;
|
|
168
180
|
const rootRules = [
|
|
@@ -173,16 +185,23 @@ function createEcmaGrammar(options) {
|
|
|
173
185
|
{ type: "string", pattern: /`/, push: "template" }
|
|
174
186
|
];
|
|
175
187
|
if (options.jsx) {
|
|
188
|
+
if (options.typescript) {
|
|
189
|
+
rootRules.push({
|
|
190
|
+
type: "operator",
|
|
191
|
+
pattern: /<(?=[A-Za-z_$][\w$]*(?:\s+extends\s+[^>]+)?,?>\s*\()/
|
|
192
|
+
});
|
|
193
|
+
}
|
|
176
194
|
rootRules.push({
|
|
177
195
|
type: "tag.punctuation",
|
|
178
|
-
pattern:
|
|
179
|
-
push: "
|
|
196
|
+
pattern: /<(?=[A-Za-z_$>])/,
|
|
197
|
+
push: "jsxTagName"
|
|
180
198
|
});
|
|
181
199
|
}
|
|
182
200
|
rootRules.push(
|
|
183
201
|
{
|
|
184
202
|
type: "regex",
|
|
185
|
-
pattern: /\/(?![/*\s])(?:\\.|\[(?:\\.|[^\]\\])*\]|[^/\\\r\n])+\/[dgimsuvy]
|
|
203
|
+
pattern: /\/(?![/*\s])(?:\\.|\[(?:\\.|[^\]\\])*\]|[^/\\\r\n])+\/[dgimsuvy]*/,
|
|
204
|
+
when: (_match, context) => canStartRegex(context.source, context.offset)
|
|
186
205
|
},
|
|
187
206
|
numberRule,
|
|
188
207
|
{ type: "boolean", pattern: /\b(?:true|false)\b/ },
|
|
@@ -228,14 +247,54 @@ function createEcmaGrammar(options) {
|
|
|
228
247
|
{ include: "root" }
|
|
229
248
|
]
|
|
230
249
|
},
|
|
231
|
-
|
|
250
|
+
jsxTagName: {
|
|
251
|
+
rules: [
|
|
252
|
+
{ type: "tag.punctuation", pattern: />/, next: "jsxChildren" },
|
|
253
|
+
{ type: "tag.punctuation", pattern: /\/>/, pop: true },
|
|
254
|
+
whitespaceRule,
|
|
255
|
+
{
|
|
256
|
+
type: "tag",
|
|
257
|
+
pattern: /[A-Za-z_$][\w$.-]*/,
|
|
258
|
+
next: "jsxAttributes"
|
|
259
|
+
},
|
|
260
|
+
punctuationRule
|
|
261
|
+
]
|
|
262
|
+
},
|
|
263
|
+
jsxAttributes: {
|
|
232
264
|
rules: [
|
|
233
|
-
{ type: "tag.punctuation", pattern:
|
|
265
|
+
{ type: "tag.punctuation", pattern: /\/>/, pop: true },
|
|
266
|
+
{ type: "tag.punctuation", pattern: />/, next: "jsxChildren" },
|
|
234
267
|
whitespaceRule,
|
|
235
268
|
{ type: "attribute.value", pattern: /"(?:\\.|[^"\\])*"?/ },
|
|
236
269
|
{ type: "attribute.value", pattern: /'(?:\\.|[^'\\])*'?/ },
|
|
237
270
|
{ type: "punctuation", pattern: /{/, push: "jsxExpression" },
|
|
238
271
|
{ type: "operator", pattern: /=/ },
|
|
272
|
+
{ type: "attribute", pattern: /[A-Za-z_$][\w$.-]*/ },
|
|
273
|
+
punctuationRule
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
jsxChildren: {
|
|
277
|
+
fallbackType: "plain",
|
|
278
|
+
rules: [
|
|
279
|
+
{
|
|
280
|
+
type: "tag.punctuation",
|
|
281
|
+
pattern: /<\/(?=[A-Za-z_$>])/,
|
|
282
|
+
push: "jsxClosingTag"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
type: "tag.punctuation",
|
|
286
|
+
pattern: /<(?=[A-Za-z_$>])/,
|
|
287
|
+
push: "jsxTagName"
|
|
288
|
+
},
|
|
289
|
+
{ type: "punctuation", pattern: /{/, push: "jsxExpression" },
|
|
290
|
+
{ type: "plain", pattern: /[^<{]+/ },
|
|
291
|
+
{ type: "plain", pattern: /[<{]/ }
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
jsxClosingTag: {
|
|
295
|
+
rules: [
|
|
296
|
+
{ type: "tag.punctuation", pattern: />/, pop: 2 },
|
|
297
|
+
whitespaceRule,
|
|
239
298
|
{ type: "tag", pattern: /[A-Za-z_$][\w$.-]*/ },
|
|
240
299
|
punctuationRule
|
|
241
300
|
]
|
|
@@ -38,7 +38,7 @@ var punctuationRule = {
|
|
|
38
38
|
};
|
|
39
39
|
var operatorRule = {
|
|
40
40
|
type: "operator",
|
|
41
|
-
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])
|
|
41
|
+
pattern: /(?:===|!==|>>>|<<=|>>=|=>|==|!=|<=|>=|&&|\|\||\?\?|\?\.|\+\+|--|\+=|-=|\*=|\/=|%=|\*\*|<<|>>|[+\-*/%=&|!<>^~?])/
|
|
42
42
|
};
|
|
43
43
|
var numberRule = {
|
|
44
44
|
type: "number",
|
|
@@ -163,6 +163,18 @@ var BUILTINS = [
|
|
|
163
163
|
"process",
|
|
164
164
|
"window"
|
|
165
165
|
];
|
|
166
|
+
function canStartRegex(source, offset) {
|
|
167
|
+
const before = source.slice(0, offset).trimEnd();
|
|
168
|
+
if (!before) return true;
|
|
169
|
+
const previous = before[before.length - 1] ?? "";
|
|
170
|
+
if (/[([{,:;=!?&|+\-*%^~<>]/.test(previous)) return true;
|
|
171
|
+
const word = /[A-Za-z_$][\w$]*$/.exec(before)?.[0];
|
|
172
|
+
return Boolean(
|
|
173
|
+
word && /^(?:await|case|delete|do|else|in|instanceof|new|of|return|throw|typeof|void|yield)$/.test(
|
|
174
|
+
word
|
|
175
|
+
)
|
|
176
|
+
);
|
|
177
|
+
}
|
|
166
178
|
function createEcmaGrammar(options) {
|
|
167
179
|
const keywordValues = options.typescript ? [...JS_KEYWORDS, ...TS_KEYWORDS] : JS_KEYWORDS;
|
|
168
180
|
const rootRules = [
|
|
@@ -173,16 +185,23 @@ function createEcmaGrammar(options) {
|
|
|
173
185
|
{ type: "string", pattern: /`/, push: "template" }
|
|
174
186
|
];
|
|
175
187
|
if (options.jsx) {
|
|
188
|
+
if (options.typescript) {
|
|
189
|
+
rootRules.push({
|
|
190
|
+
type: "operator",
|
|
191
|
+
pattern: /<(?=[A-Za-z_$][\w$]*(?:\s+extends\s+[^>]+)?,?>\s*\()/
|
|
192
|
+
});
|
|
193
|
+
}
|
|
176
194
|
rootRules.push({
|
|
177
195
|
type: "tag.punctuation",
|
|
178
|
-
pattern:
|
|
179
|
-
push: "
|
|
196
|
+
pattern: /<(?=[A-Za-z_$>])/,
|
|
197
|
+
push: "jsxTagName"
|
|
180
198
|
});
|
|
181
199
|
}
|
|
182
200
|
rootRules.push(
|
|
183
201
|
{
|
|
184
202
|
type: "regex",
|
|
185
|
-
pattern: /\/(?![/*\s])(?:\\.|\[(?:\\.|[^\]\\])*\]|[^/\\\r\n])+\/[dgimsuvy]
|
|
203
|
+
pattern: /\/(?![/*\s])(?:\\.|\[(?:\\.|[^\]\\])*\]|[^/\\\r\n])+\/[dgimsuvy]*/,
|
|
204
|
+
when: (_match, context) => canStartRegex(context.source, context.offset)
|
|
186
205
|
},
|
|
187
206
|
numberRule,
|
|
188
207
|
{ type: "boolean", pattern: /\b(?:true|false)\b/ },
|
|
@@ -228,14 +247,54 @@ function createEcmaGrammar(options) {
|
|
|
228
247
|
{ include: "root" }
|
|
229
248
|
]
|
|
230
249
|
},
|
|
231
|
-
|
|
250
|
+
jsxTagName: {
|
|
251
|
+
rules: [
|
|
252
|
+
{ type: "tag.punctuation", pattern: />/, next: "jsxChildren" },
|
|
253
|
+
{ type: "tag.punctuation", pattern: /\/>/, pop: true },
|
|
254
|
+
whitespaceRule,
|
|
255
|
+
{
|
|
256
|
+
type: "tag",
|
|
257
|
+
pattern: /[A-Za-z_$][\w$.-]*/,
|
|
258
|
+
next: "jsxAttributes"
|
|
259
|
+
},
|
|
260
|
+
punctuationRule
|
|
261
|
+
]
|
|
262
|
+
},
|
|
263
|
+
jsxAttributes: {
|
|
232
264
|
rules: [
|
|
233
|
-
{ type: "tag.punctuation", pattern:
|
|
265
|
+
{ type: "tag.punctuation", pattern: /\/>/, pop: true },
|
|
266
|
+
{ type: "tag.punctuation", pattern: />/, next: "jsxChildren" },
|
|
234
267
|
whitespaceRule,
|
|
235
268
|
{ type: "attribute.value", pattern: /"(?:\\.|[^"\\])*"?/ },
|
|
236
269
|
{ type: "attribute.value", pattern: /'(?:\\.|[^'\\])*'?/ },
|
|
237
270
|
{ type: "punctuation", pattern: /{/, push: "jsxExpression" },
|
|
238
271
|
{ type: "operator", pattern: /=/ },
|
|
272
|
+
{ type: "attribute", pattern: /[A-Za-z_$][\w$.-]*/ },
|
|
273
|
+
punctuationRule
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
jsxChildren: {
|
|
277
|
+
fallbackType: "plain",
|
|
278
|
+
rules: [
|
|
279
|
+
{
|
|
280
|
+
type: "tag.punctuation",
|
|
281
|
+
pattern: /<\/(?=[A-Za-z_$>])/,
|
|
282
|
+
push: "jsxClosingTag"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
type: "tag.punctuation",
|
|
286
|
+
pattern: /<(?=[A-Za-z_$>])/,
|
|
287
|
+
push: "jsxTagName"
|
|
288
|
+
},
|
|
289
|
+
{ type: "punctuation", pattern: /{/, push: "jsxExpression" },
|
|
290
|
+
{ type: "plain", pattern: /[^<{]+/ },
|
|
291
|
+
{ type: "plain", pattern: /[<{]/ }
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
jsxClosingTag: {
|
|
295
|
+
rules: [
|
|
296
|
+
{ type: "tag.punctuation", pattern: />/, pop: 2 },
|
|
297
|
+
whitespaceRule,
|
|
239
298
|
{ type: "tag", pattern: /[A-Za-z_$][\w$.-]*/ },
|
|
240
299
|
punctuationRule
|
|
241
300
|
]
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { compileGrammar, normalizeId } from "./grammar.js";
|
|
2
|
+
import { YuirinxError } from "./errors.js";
|
|
3
|
+
import { renderColorLines, renderTokens } from "./renderer.js";
|
|
4
|
+
import { tokenizeCompiled } from "./tokenizer.js";
|
|
5
|
+
const plaintextGrammar = {
|
|
6
|
+
id: "plaintext",
|
|
7
|
+
aliases: ["text", "txt", "plain"],
|
|
8
|
+
states: {
|
|
9
|
+
root: {
|
|
10
|
+
rules: [{ type: "plain", pattern: /[\s\S]+/ }]
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
function themeId(theme) {
|
|
15
|
+
return normalizeId(theme.id);
|
|
16
|
+
}
|
|
17
|
+
function createHighlighter(options = {}) {
|
|
18
|
+
const grammars = /* @__PURE__ */ new Map();
|
|
19
|
+
const canonicalIds = /* @__PURE__ */ new Set();
|
|
20
|
+
const themes = /* @__PURE__ */ new Map();
|
|
21
|
+
const requestedMaxStateDepth = options.maxStateDepth ?? 64;
|
|
22
|
+
if (!Number.isFinite(requestedMaxStateDepth) || !Number.isInteger(requestedMaxStateDepth) || requestedMaxStateDepth < 2) {
|
|
23
|
+
throw new YuirinxError(
|
|
24
|
+
"YUIRINX_INVALID_OPTION",
|
|
25
|
+
"maxStateDepth must be a finite integer greater than or equal to 2."
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
const maxStateDepth = requestedMaxStateDepth;
|
|
29
|
+
const compiledPlaintext = compileGrammar(plaintextGrammar);
|
|
30
|
+
const plaintextIds = /* @__PURE__ */ new Set([
|
|
31
|
+
normalizeId(plaintextGrammar.id),
|
|
32
|
+
...(plaintextGrammar.aliases ?? []).map(normalizeId)
|
|
33
|
+
]);
|
|
34
|
+
const registerLanguage = (grammar) => {
|
|
35
|
+
const compiled = compileGrammar(grammar);
|
|
36
|
+
const id = compiled.id;
|
|
37
|
+
if (grammars.has(id)) {
|
|
38
|
+
throw new YuirinxError(
|
|
39
|
+
"YUIRINX_DUPLICATE_LANGUAGE",
|
|
40
|
+
`Language "${id}" is already registered.`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
const aliases = (grammar.aliases ?? []).map(normalizeId).filter(Boolean);
|
|
44
|
+
for (const alias of aliases) {
|
|
45
|
+
if (alias === id || grammars.has(alias)) {
|
|
46
|
+
throw new YuirinxError(
|
|
47
|
+
"YUIRINX_DUPLICATE_ALIAS",
|
|
48
|
+
`Alias "${alias}" for language "${id}" is already registered.`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
grammars.set(id, compiled);
|
|
53
|
+
canonicalIds.add(id);
|
|
54
|
+
for (const alias of aliases) grammars.set(alias, compiled);
|
|
55
|
+
};
|
|
56
|
+
const registerTheme = (theme) => {
|
|
57
|
+
const id = themeId(theme);
|
|
58
|
+
if (!id)
|
|
59
|
+
throw new YuirinxError(
|
|
60
|
+
"YUIRINX_DUPLICATE_THEME",
|
|
61
|
+
"A theme must have a non-empty id."
|
|
62
|
+
);
|
|
63
|
+
if (themes.has(id)) {
|
|
64
|
+
throw new YuirinxError(
|
|
65
|
+
"YUIRINX_DUPLICATE_THEME",
|
|
66
|
+
`Theme "${id}" is already registered.`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
themes.set(id, theme);
|
|
70
|
+
};
|
|
71
|
+
for (const grammar of options.languages ?? []) registerLanguage(grammar);
|
|
72
|
+
for (const theme of options.themes ?? []) registerTheme(theme);
|
|
73
|
+
const resolveGrammar = (language) => {
|
|
74
|
+
if (typeof language !== "string") {
|
|
75
|
+
return { grammar: compileGrammar(language), unavailable: false };
|
|
76
|
+
}
|
|
77
|
+
const id = normalizeId(language);
|
|
78
|
+
const registered = grammars.get(id);
|
|
79
|
+
if (registered) return { grammar: registered, unavailable: false };
|
|
80
|
+
return {
|
|
81
|
+
grammar: compiledPlaintext,
|
|
82
|
+
unavailable: !plaintextIds.has(id)
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
const resolveTheme = (theme) => {
|
|
86
|
+
if (!theme)
|
|
87
|
+
return options.defaultTheme ? themes.get(normalizeId(options.defaultTheme)) : void 0;
|
|
88
|
+
return typeof theme === "string" ? themes.get(normalizeId(theme)) : theme;
|
|
89
|
+
};
|
|
90
|
+
const tokenize = (code, language) => tokenizeCompiled(code, resolveGrammar(language).grammar, maxStateDepth);
|
|
91
|
+
const render = (tokens, renderOptions = {}) => renderTokens(tokens, renderOptions, resolveTheme(renderOptions.theme));
|
|
92
|
+
const highlight = (code, highlightOptions = {}) => {
|
|
93
|
+
const language = highlightOptions.lang ?? options.defaultLanguage ?? "plaintext";
|
|
94
|
+
const resolved = resolveGrammar(language);
|
|
95
|
+
const theme = resolveTheme(highlightOptions.theme);
|
|
96
|
+
const renderOptions = {
|
|
97
|
+
...highlightOptions,
|
|
98
|
+
language: typeof language === "string" ? language : language.id
|
|
99
|
+
};
|
|
100
|
+
const fallback = highlightOptions.fallback ?? options.defaultFallback ?? "plaintext";
|
|
101
|
+
if (resolved.unavailable && fallback === "color-lines") {
|
|
102
|
+
return renderColorLines(code, renderOptions, theme);
|
|
103
|
+
}
|
|
104
|
+
const tokens = tokenizeCompiled(code, resolved.grammar, maxStateDepth);
|
|
105
|
+
return renderTokens(tokens, renderOptions, theme);
|
|
106
|
+
};
|
|
107
|
+
return {
|
|
108
|
+
highlight,
|
|
109
|
+
tokenize,
|
|
110
|
+
render,
|
|
111
|
+
registerLanguage,
|
|
112
|
+
registerTheme,
|
|
113
|
+
hasLanguage: (language) => {
|
|
114
|
+
const id = normalizeId(language);
|
|
115
|
+
return plaintextIds.has(id) || grammars.has(id);
|
|
116
|
+
},
|
|
117
|
+
hasTheme: (theme) => themes.has(normalizeId(theme)),
|
|
118
|
+
getLanguage: (language) => {
|
|
119
|
+
const id = normalizeId(language);
|
|
120
|
+
return grammars.get(id)?.source ?? (plaintextIds.has(id) ? plaintextGrammar : void 0);
|
|
121
|
+
},
|
|
122
|
+
getTheme: (theme) => themes.get(normalizeId(theme)),
|
|
123
|
+
listLanguages: () => Object.freeze([
|
|
124
|
+
"plaintext",
|
|
125
|
+
...[...canonicalIds].filter((id) => id !== "plaintext")
|
|
126
|
+
]),
|
|
127
|
+
listThemes: () => Object.freeze([...themes.keys()])
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
export {
|
|
131
|
+
createHighlighter
|
|
132
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const HTML_ESCAPE_RE = /[&<>"']/g;
|
|
2
|
+
const HTML_ENTITIES = {
|
|
3
|
+
"&": "&",
|
|
4
|
+
"<": "<",
|
|
5
|
+
">": ">",
|
|
6
|
+
'"': """,
|
|
7
|
+
"'": "'"
|
|
8
|
+
};
|
|
9
|
+
function escapeHtml(value) {
|
|
10
|
+
return value.replace(
|
|
11
|
+
HTML_ESCAPE_RE,
|
|
12
|
+
(character) => HTML_ENTITIES[character] ?? character
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
escapeHtml
|
|
17
|
+
};
|