sugar-high 0.1.2 → 0.2.0
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 +4 -2
- package/lib/index.mjs +45 -38
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Then make your own theme with customized colors by token type and put in global
|
|
|
33
33
|
* Class, number and null
|
|
34
34
|
* sign
|
|
35
35
|
* comment
|
|
36
|
-
*
|
|
36
|
+
* jsxliterals
|
|
37
37
|
*/
|
|
38
38
|
.sh__class {
|
|
39
39
|
color: #2d5e9d;
|
|
@@ -53,7 +53,9 @@ Then make your own theme with customized colors by token type and put in global
|
|
|
53
53
|
.sh__comment {
|
|
54
54
|
color: #a19595;
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
.sh__jsxliterals {
|
|
57
|
+
color: #03066e;
|
|
58
|
+
}
|
|
57
59
|
```
|
|
58
60
|
|
|
59
61
|
### LICENSE
|
package/lib/index.mjs
CHANGED
|
@@ -74,7 +74,7 @@ const signs = new Set([
|
|
|
74
74
|
'\\',
|
|
75
75
|
])
|
|
76
76
|
|
|
77
|
-
const types = [
|
|
77
|
+
export const types = [
|
|
78
78
|
'identifier',
|
|
79
79
|
'keyword',
|
|
80
80
|
'string',
|
|
@@ -83,6 +83,7 @@ const types = [
|
|
|
83
83
|
'comment',
|
|
84
84
|
'break',
|
|
85
85
|
'space',
|
|
86
|
+
'jsxliterals'
|
|
86
87
|
]
|
|
87
88
|
|
|
88
89
|
/**
|
|
@@ -95,6 +96,7 @@ const types = [
|
|
|
95
96
|
* 5 - comment
|
|
96
97
|
* 6 - break
|
|
97
98
|
* 7 - space
|
|
99
|
+
* 8 - jsx literals
|
|
98
100
|
*
|
|
99
101
|
*/
|
|
100
102
|
const [
|
|
@@ -106,6 +108,7 @@ const [
|
|
|
106
108
|
T_COMMENT,
|
|
107
109
|
T_BREAK,
|
|
108
110
|
T_SPACE,
|
|
111
|
+
T_JSX_LITERALS,
|
|
109
112
|
] = types.map((_, i) => i)
|
|
110
113
|
|
|
111
114
|
function isSpaces(str) {
|
|
@@ -124,7 +127,11 @@ function encode(str) {
|
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
function isIdentifierChar(chr) {
|
|
127
|
-
return
|
|
130
|
+
return /^[\w_$]$/.test(chr)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function isIdentifier(str) {
|
|
134
|
+
return /[a-zA-Z_$]/.test(str[0]) && (str.length === 1 || /^[\w_$]+$/.test(str.slice(1)))
|
|
128
135
|
}
|
|
129
136
|
|
|
130
137
|
function isStringQuotation(chr) {
|
|
@@ -160,27 +167,16 @@ export function tokenize(code) {
|
|
|
160
167
|
const inJsxLiterals = () => !jsx.tag && jsx.child && !jsx.expr
|
|
161
168
|
|
|
162
169
|
function classify(token) {
|
|
163
|
-
const
|
|
164
|
-
if (
|
|
165
|
-
return T_COMMENT
|
|
166
|
-
} else if (keywords.has(token)) {
|
|
170
|
+
const chr0 = token[0]
|
|
171
|
+
if (keywords.has(token)) {
|
|
167
172
|
return T_KEYWORD
|
|
168
173
|
} else if (token === '\n') {
|
|
169
174
|
return T_BREAK
|
|
170
|
-
} else if (token
|
|
175
|
+
} else if (isSpaces(token)) {
|
|
171
176
|
return T_SPACE
|
|
172
177
|
} else if (token.split('').every(ch => signs.has(ch))) {
|
|
173
178
|
return T_SIGN
|
|
174
179
|
} else if (
|
|
175
|
-
(
|
|
176
|
-
// is quoted string
|
|
177
|
-
(isStringQuotation(chr0) && !isStringQuotation(chr1)) ||
|
|
178
|
-
// is regex
|
|
179
|
-
(!jsx.tag && isRegexStart(chr0 + chr1) && token[token.length - 1] === '/')
|
|
180
|
-
)
|
|
181
|
-
) {
|
|
182
|
-
return T_STRING
|
|
183
|
-
} else if (
|
|
184
180
|
!inJsxLiterals() &&
|
|
185
181
|
(
|
|
186
182
|
isIdentifierChar(chr0) &&
|
|
@@ -190,13 +186,13 @@ export function tokenize(code) {
|
|
|
190
186
|
) {
|
|
191
187
|
return T_CLS_NUMBER
|
|
192
188
|
} else {
|
|
193
|
-
return T_IDENTIFIER
|
|
189
|
+
return isIdentifier(token) ? T_IDENTIFIER : inJsxLiterals() ? T_JSX_LITERALS : T_STRING
|
|
194
190
|
}
|
|
195
191
|
}
|
|
196
192
|
|
|
197
|
-
const append = () => {
|
|
193
|
+
const append = (_type) => {
|
|
198
194
|
if (current) {
|
|
199
|
-
type = classify(current)
|
|
195
|
+
type = _type || classify(current)
|
|
200
196
|
/** @type [number, string] */
|
|
201
197
|
const pair = [type, current]
|
|
202
198
|
if (type !== T_SPACE && type !== T_BREAK) {
|
|
@@ -226,40 +222,51 @@ export function tokenize(code) {
|
|
|
226
222
|
jsx.child = false
|
|
227
223
|
}
|
|
228
224
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
) {
|
|
225
|
+
const isQuotationChar = isStringQuotation(curr)
|
|
226
|
+
const isRegexChar = !jsx.tag && isRegexStart(c_n)
|
|
227
|
+
if (isQuotationChar || isRegexChar) {
|
|
232
228
|
append()
|
|
233
229
|
const [lastType, lastToken] = last
|
|
234
|
-
|
|
230
|
+
// Special cases that are not considered as regex:
|
|
231
|
+
// * (expr) / expr: `()[]` before `/` is still in expression
|
|
232
|
+
// * <non comment start>/ expr: non comment start before `/` is not regex
|
|
233
|
+
if (
|
|
234
|
+
isRegexChar &&
|
|
235
|
+
lastType &&
|
|
236
|
+
!(
|
|
237
|
+
(lastType === T_SIGN && !'()[]'.includes(lastToken)) ||
|
|
238
|
+
lastType === T_COMMENT
|
|
239
|
+
)
|
|
240
|
+
) {
|
|
235
241
|
current = curr
|
|
236
242
|
append()
|
|
237
243
|
continue
|
|
238
244
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const
|
|
245
|
+
const start = i++
|
|
246
|
+
|
|
247
|
+
const isInline = () => i < code.length && code[i] !== '\n'
|
|
242
248
|
// string quotation
|
|
243
|
-
if (
|
|
244
|
-
for (;
|
|
245
|
-
if (isStringQuotation(code[
|
|
246
|
-
strEnd = j
|
|
249
|
+
if (isQuotationChar) {
|
|
250
|
+
for (; isInline(); i++) {
|
|
251
|
+
if (isStringQuotation(code[i])) {
|
|
247
252
|
break
|
|
248
253
|
}
|
|
249
254
|
}
|
|
250
255
|
} else {
|
|
251
256
|
// regex
|
|
252
|
-
for (;
|
|
253
|
-
if (code[
|
|
254
|
-
|
|
257
|
+
for (; isInline(); i++) {
|
|
258
|
+
if (code[i] === '/' && code[i - 1] !== '\\') {
|
|
259
|
+
// append regex flags
|
|
260
|
+
while (start !== i && /^[a-z]$/.test(code[i + 1]) && isInline()) {
|
|
261
|
+
i++
|
|
262
|
+
};
|
|
255
263
|
break
|
|
256
264
|
}
|
|
257
265
|
}
|
|
258
266
|
}
|
|
259
|
-
if (
|
|
260
|
-
current = code.slice(
|
|
261
|
-
append()
|
|
262
|
-
i = j
|
|
267
|
+
if (start !== i) {
|
|
268
|
+
current = code.slice(start, i + 1)
|
|
269
|
+
append(T_STRING)
|
|
263
270
|
} else {
|
|
264
271
|
current = curr
|
|
265
272
|
append()
|
|
@@ -272,7 +279,7 @@ export function tokenize(code) {
|
|
|
272
279
|
for (; i < code.length && code[i - 1] + code[i] !== '*/'; i++);
|
|
273
280
|
}
|
|
274
281
|
current = code.slice(start, i + 1)
|
|
275
|
-
append()
|
|
282
|
+
append(T_COMMENT)
|
|
276
283
|
} else if (curr === ' ' || curr === '\n') {
|
|
277
284
|
if (
|
|
278
285
|
curr === ' ' &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sugar-high",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./lib/index.mjs",
|
|
6
6
|
"description": "Super lightweight JSX syntax highlighter",
|
|
@@ -11,10 +11,12 @@
|
|
|
11
11
|
],
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"scripts": {
|
|
14
|
+
"test": "vitest run",
|
|
14
15
|
"dev": "vite docs",
|
|
15
16
|
"build": "vite build docs"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
|
-
"vite": "2.
|
|
19
|
+
"vite": "^2.8.6",
|
|
20
|
+
"vitest": "^0.5.9"
|
|
19
21
|
}
|
|
20
22
|
}
|