sugar-high 0.4.2 → 0.4.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/lib/index.mjs +90 -31
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  Super lightweight JSX syntax highlighter, around 1KB after minified and gzipped
5
5
 
6
- ![img](https://repository-images.githubusercontent.com/453236442/94994be5-72fa-479f-8b87-2dc14fe40329)
6
+ ![img](https://repository-images.githubusercontent.com/453236442/1d63a6ff-aa11-422c-a36c-ca16fc102f18)
7
7
 
8
8
  ### Usage
9
9
 
package/lib/index.mjs CHANGED
@@ -144,8 +144,16 @@ function isIdentifier(str) {
144
144
  return isIdentifierChar(str[0]) && (str.length === 1 || isWord(str.slice(1)))
145
145
  }
146
146
 
147
+ function isStrTemplateChr(chr) {
148
+ return chr === '`'
149
+ }
150
+
151
+ function isSingleQuotes(chr) {
152
+ return chr === '"' || chr === "'"
153
+ }
154
+
147
155
  function isStringQuotation(chr) {
148
- return chr === '"' || chr === "'" || chr === '`'
156
+ return isSingleQuotes(chr) || isStrTemplateChr(chr)
149
157
  }
150
158
 
151
159
  function isCommentStart(str) {
@@ -184,6 +192,13 @@ export function tokenize(code) {
184
192
  const inJsxTag = () => __jsxTag && !__jsxChild()
185
193
  const inJsxLiterals = () => !__jsxTag && __jsxChild() && !__jsxExpr && __jsxStack > 0
186
194
 
195
+ /** @type {string | 0} */
196
+ let __strQuote = 0
197
+ let __strTemplateExprStack = 0
198
+ let __strTemplateQuoteStack = 0
199
+ const inStrTemplateLiterals = () => (__strTemplateQuoteStack > __strTemplateExprStack)
200
+ const inStrTemplateExpr = () => __strTemplateQuoteStack > 0 && (__strTemplateQuoteStack === __strTemplateExprStack)
201
+
187
202
  /**
188
203
  *
189
204
  * @param {string} token
@@ -204,11 +219,14 @@ export function tokenize(code) {
204
219
  } else if (isCls(token)) {
205
220
  return inJsxTag() ? T_IDENTIFIER : T_CLS_NUMBER
206
221
  } else {
207
- return isIdentifier(token) ? T_IDENTIFIER : T_STRING
222
+ return isIdentifier(token) && !inStrTemplateLiterals() && (__strQuote !== `"` && __strQuote !== `'`) ? T_IDENTIFIER : T_STRING
208
223
  }
209
224
  }
210
225
 
211
- const append = (_type) => {
226
+ const append = (_type, _token) => {
227
+ if (_token) {
228
+ current = _token
229
+ }
212
230
  if (current) {
213
231
  type = _type || classify(current)
214
232
  /** @type [number, string] */
@@ -227,12 +245,59 @@ export function tokenize(code) {
227
245
  const p_c = prev + curr // previous and current
228
246
  const c_n = curr + next // current and next
229
247
 
248
+ if (isSingleQuotes(curr)) {
249
+ append()
250
+ if (prev !== `\\`) {
251
+ if (__strQuote && curr === __strQuote) {
252
+ __strQuote = 0
253
+ } else if (!__strQuote) {
254
+ __strQuote = curr
255
+ }
256
+ }
257
+
258
+ append(T_STRING, curr)
259
+ continue
260
+ }
261
+
262
+ if (!inStrTemplateLiterals()) {
263
+ if (prev !== '\\n' && isStrTemplateChr(curr)) {
264
+ append()
265
+ append(T_STRING, curr)
266
+ __strTemplateQuoteStack++
267
+ continue
268
+ }
269
+ }
270
+
271
+ if (inStrTemplateLiterals()) {
272
+ if (prev !== '\\n' && isStrTemplateChr(curr)) {
273
+ if (__strTemplateQuoteStack > 0) {
274
+ append()
275
+ __strTemplateQuoteStack--
276
+ append(T_STRING, curr)
277
+ continue
278
+ }
279
+ }
280
+
281
+ if (c_n === '${') {
282
+ __strTemplateExprStack++
283
+ append(T_STRING)
284
+ append(T_SIGN, c_n)
285
+ i++
286
+ continue
287
+ }
288
+ }
289
+
290
+ if (inStrTemplateExpr() && curr === '}') {
291
+ append()
292
+ __strTemplateExprStack--
293
+ append(T_SIGN, curr)
294
+ continue
295
+ }
230
296
 
231
297
  if (__jsxChild()) {
232
298
  if (curr === '{') {
233
299
  append()
234
- current = curr
235
- append(T_SIGN)
300
+ append(T_SIGN, curr)
236
301
  __jsxExpr = true
237
302
  continue
238
303
  }
@@ -254,7 +319,8 @@ export function tokenize(code) {
254
319
  }
255
320
  if (__jsxTag) {
256
321
  // >: open tag close sign or closing tag closing sign
257
- if (curr === '>' && prev !== '/') {
322
+ // and it's not `=>` or `/>`
323
+ if (curr === '>' && !'/='.includes(prev)) {
258
324
  append()
259
325
  if (__jsxTag === 1) {
260
326
  __jsxTag = 0
@@ -263,8 +329,7 @@ export function tokenize(code) {
263
329
  __jsxTag = 0
264
330
  __jsxEnter = false
265
331
  }
266
- current = curr
267
- append(T_SIGN)
332
+ append(T_SIGN, curr)
268
333
  continue
269
334
  }
270
335
 
@@ -303,9 +368,14 @@ export function tokenize(code) {
303
368
  }
304
369
 
305
370
  const isQuotationChar = isStringQuotation(curr)
371
+ const isStringTemplateLiterals = inStrTemplateLiterals()
306
372
  const isRegexChar = !__jsxEnter && isRegexStart(c_n)
307
373
  const isJsxLiterals = inJsxLiterals()
308
- if (isQuotationChar || isRegexChar) {
374
+
375
+ // string quotation
376
+ if (isQuotationChar || isStringTemplateLiterals || isSingleQuotes(__strQuote)) {
377
+ current += curr
378
+ } else if (isRegexChar) {
309
379
  append()
310
380
  const [lastType, lastToken] = last
311
381
  // Special cases that are not considered as regex:
@@ -323,34 +393,23 @@ export function tokenize(code) {
323
393
  append()
324
394
  continue
325
395
  }
396
+
326
397
  const start = i++
327
- const leftQuote = code[start]
328
- let foundClose = false
329
398
 
330
399
  // end of line of end of file
331
400
  const isEof = () => i >= code.length
332
401
  const isEol = () => isEof() || code[i] === '\n'
333
- // string quotation
334
- if (isQuotationChar) {
335
- for (; !isEof(); i++) {
336
- // handle single quotes
337
- if ((leftQuote === "'" || leftQuote === '"') && code[i] === '\n') break
338
- if (isStringQuotation(code[i]) && code[i] === leftQuote) {
339
- foundClose = true
340
- break
341
- }
342
- }
343
- } else {
344
- // regex
345
- for (; !isEol(); i++) {
346
- if (code[i] === '/' && code[i - 1] !== '\\') {
347
- foundClose = true
348
- // append regex flags
349
- while (start !== i && /^[a-z]$/.test(code[i + 1]) && !isEol()) {
350
- i++
351
- }
352
- break
402
+
403
+ let foundClose = false
404
+ // regex
405
+ for (; !isEol(); i++) {
406
+ if (code[i] === '/' && code[i - 1] !== '\\') {
407
+ foundClose = true
408
+ // append regex flags
409
+ while (start !== i && /^[a-z]$/.test(code[i + 1]) && !isEol()) {
410
+ i++
353
411
  }
412
+ break
354
413
  }
355
414
  }
356
415
  if (start !== i && foundClose) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sugar-high",
3
- "version": "0.4.2",
3
+ "version": "0.4.5",
4
4
  "type": "module",
5
5
  "exports": "./lib/index.mjs",
6
6
  "description": "Super lightweight JSX syntax highlighter",
@@ -16,7 +16,7 @@
16
16
  "build": "next build docs"
17
17
  },
18
18
  "devDependencies": {
19
- "codice": "^0.0.9",
19
+ "codice": "^0.0.10",
20
20
  "next": "12.1.6-canary.6",
21
21
  "react": "18.0.0",
22
22
  "react-dom": "18.0.0",