sugar-high 0.4.7 → 0.5.1

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 +10 -0
  2. package/lib/index.mjs +40 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -71,6 +71,16 @@ pre code {
71
71
  }
72
72
  ```
73
73
 
74
+ #### CSS Class Names
75
+
76
+ You can use `.sh__token--<token type>` to customize the output node of each token.
77
+
78
+ ```css
79
+ .sh__token--keyword {
80
+ background: #f47067;
81
+ }
82
+ ```
83
+
74
84
  ### LICENSE
75
85
 
76
86
  MIT
package/lib/index.mjs CHANGED
@@ -76,7 +76,7 @@ const signs = new Set([
76
76
  ...jsxBrackets,
77
77
  ])
78
78
 
79
- export const types = [
79
+ const types = [
80
80
  'identifier',
81
81
  'keyword',
82
82
  'string',
@@ -141,8 +141,12 @@ function hasUnicode(s) {
141
141
  return /[^\u0000-\u007f]/.test(s);
142
142
  }
143
143
 
144
+ function isAlpha(chr) {
145
+ return /^[a-zA-Z]$/.test(chr)
146
+ }
147
+
144
148
  function isIdentifierChar(chr) {
145
- return /^[a-zA-Z_$]$/.test(chr) || hasUnicode(chr)
149
+ return isAlpha(chr) || hasUnicode(chr)
146
150
  }
147
151
 
148
152
  function isIdentifier(str) {
@@ -174,7 +178,7 @@ function isRegexStart(str) {
174
178
  * @param {string} code
175
179
  * @return {Array<[number, string]>}
176
180
  */
177
- export function tokenize(code) {
181
+ function tokenize(code) {
178
182
  let current = ''
179
183
  let type = -1
180
184
  /** @type {[number | null, string | null]} */
@@ -182,12 +186,13 @@ export function tokenize(code) {
182
186
  /** @type {Array<[number, string]>} */
183
187
  const tokens = []
184
188
 
189
+ /** @type boolean if entered jsx tag, inside <open tag> or </close tag> */
185
190
  let __jsxEnter = false
186
191
  /**
187
192
  * @type {0 | 1 | 2}
188
- * 0 for not in jsx
189
- * 1 for open jsx tag
190
- * 2 for closing jsx tag
193
+ * 0 for not in jsx;
194
+ * 1 for open jsx tag;
195
+ * 2 for closing jsx tag;
191
196
  **/
192
197
  let __jsxTag = 0
193
198
  let __jsxExpr = false
@@ -212,6 +217,7 @@ export function tokenize(code) {
212
217
  * @returns {number}
213
218
  */
214
219
  function classify(token) {
220
+ const isLineBreak = token === '\n'
215
221
  if (inJsxTag() && inStringQuotes()) {
216
222
  return T_STRING
217
223
  }
@@ -220,7 +226,7 @@ export function tokenize(code) {
220
226
  return T_JSX_LITERALS
221
227
  } else if (keywords.has(token)) {
222
228
  return last[1] === '.' ? T_IDENTIFIER : T_KEYWORD
223
- } else if (token === '\n') {
229
+ } else if (isLineBreak) {
224
230
  return T_BREAK
225
231
  } else if (isSpaces(token)) {
226
232
  return T_SPACE
@@ -320,14 +326,18 @@ export function tokenize(code) {
320
326
 
321
327
  if (__jsxEnter) {
322
328
  // <: open tag sign
329
+ // new '<' not inside jsx
323
330
  if (!__jsxTag && curr === '<') {
324
331
  append()
325
- __jsxTag = 1
326
- current = curr
327
332
  if (next === '/') {
333
+ // close tag
328
334
  __jsxTag = 2
329
335
  current = c_n
330
336
  i++
337
+ } else {
338
+ // open tag
339
+ __jsxTag = 1
340
+ current = curr
331
341
  }
332
342
  append(T_SIGN)
333
343
  continue
@@ -350,11 +360,14 @@ export function tokenize(code) {
350
360
 
351
361
  // >: tag self close sign or close tag sign
352
362
  if (c_n === '/>' || c_n === '</') {
353
- append()
363
+ // if current token is not part of close tag sign, push it first
364
+ if (current !== '<' || current !== '<') {
365
+ append()
366
+ }
354
367
  if (c_n === '/>') {
355
368
  __jsxTag = 0
356
- }
357
- if (c_n === '</') {
369
+ } else {
370
+ // is '</'
358
371
  __jsxStack--
359
372
  }
360
373
  current = c_n
@@ -377,7 +390,8 @@ export function tokenize(code) {
377
390
  if (!__jsxTag && (curr === '<' && isIdentifierChar(next) || c_n === '</')) {
378
391
  __jsxTag = next === '/' ? 2 : 1
379
392
 
380
- if (curr === '<' && next !== '/') {
393
+ // current and next char can form a jsx open or close tag
394
+ if (curr === '<' && (next === '/' || isAlpha(next))) {
381
395
  __jsxEnter = true
382
396
  }
383
397
  }
@@ -514,7 +528,7 @@ function generate(tokens) {
514
528
  function flushLine(tokens) {
515
529
  linesHtml.push(createLine(
516
530
  tokens.map(([type, value]) => (
517
- `<span style="color: var(--sh-${types[type]})">${encode(value)}</span>`
531
+ `<span class="sh__token--${types[type]}" style="color: var(--sh-${types[type]})">${encode(value)}</span>`
518
532
  ))
519
533
  .join('')
520
534
  ))
@@ -555,8 +569,19 @@ function generate(tokens) {
555
569
  * @param {string} code
556
570
  * @returns {string}
557
571
  */
558
- export function highlight(code) {
572
+ function highlight(code) {
559
573
  const tokens = tokenize(code)
560
574
  const output = generate(tokens).join('\n')
561
575
  return output
576
+ }
577
+
578
+ // namespace
579
+ const SugarHigh = {
580
+ TokenTypes: types,
581
+ }
582
+
583
+ export {
584
+ highlight,
585
+ tokenize,
586
+ SugarHigh,
562
587
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sugar-high",
3
- "version": "0.4.7",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "exports": "./lib/index.mjs",
6
6
  "description": "Super lightweight JSX syntax highlighter",