sugar-high 0.0.4 → 0.0.8

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 +43 -4
  2. package/lib/index.mjs +49 -29
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,14 +1,16 @@
1
1
  # Sugar High
2
- > Super lightweight JSX syntax highlighter
2
+ ### Introduction
3
3
 
4
- ### Install
4
+ Super lightweight JSX syntax highlighter, around 1KB after minified and gzipped
5
+
6
+ > ⚠️ Still in experiment! Use it in production with caution!
7
+
8
+ ### Usage
5
9
 
6
10
  ```sh
7
11
  npm install --save sugar-high
8
12
  ```
9
13
 
10
- ### Usage
11
-
12
14
  ```js
13
15
  import { highlight } from 'sugar-high'
14
16
 
@@ -17,6 +19,43 @@ const codeHTML = highlight(code)
17
19
  document.querySelector('pre > code').innerHTML = codeHTML
18
20
  ```
19
21
 
22
+ ### Highlight with CSS
23
+
24
+ Then make your own theme with customized colors by token type and put in global CSS. The corresponding class names star with `sh__` prefix.
25
+
26
+ ```css
27
+ /**
28
+ * Types that sugar-high have:
29
+ *
30
+ * identifier
31
+ * keyword
32
+ * string
33
+ * Class, number and null
34
+ * sign
35
+ * comment
36
+ *
37
+ */
38
+ .sh__class {
39
+ color: #2d5e9d;
40
+ }
41
+ .sh__identifier {
42
+ color: #2d333b;
43
+ }
44
+ .sh__sign {
45
+ color: #8996a3;
46
+ }
47
+ .sh__string {
48
+ color: #00a99a;
49
+ }
50
+ .sh__keyword {
51
+ color: #f47067;
52
+ }
53
+ .sh__comment {
54
+ color: #a19595;
55
+ }
56
+
57
+ ```
58
+
20
59
  ### LICENSE
21
60
 
22
61
  MIT
package/lib/index.mjs CHANGED
@@ -62,6 +62,7 @@ const signs = new Set([
62
62
  ':',
63
63
  '.',
64
64
  ',',
65
+ ';',
65
66
  `'`,
66
67
  '"',
67
68
  '.',
@@ -73,27 +74,39 @@ const signs = new Set([
73
74
  '\\',
74
75
  ])
75
76
 
77
+ const types = [
78
+ 'identifier',
79
+ 'keyword',
80
+ 'string',
81
+ 'class',
82
+ 'sign',
83
+ 'comment',
84
+ 'break',
85
+ 'space',
86
+ ]
87
+
76
88
  /**
77
89
  *
78
- * 0 - comment
90
+ * 0 - identifier
79
91
  * 1 - keyword
80
- * 2 - break
81
- * 3 - string
82
- * 4 - space
83
- * 5 - sign
84
- * 6 - identifier
92
+ * 2 - string
93
+ * 3 - Class, number and null
94
+ * 4 - sign
95
+ * 5 - comment
96
+ * 6 - break
97
+ * 7 - space
85
98
  *
86
99
  */
87
100
  const [
88
- T_COMMENT,
101
+ T_IDENTIFIER,
89
102
  T_KEYWORD,
90
- T_BREAK,
91
103
  T_STRING,
92
- T_SPACE,
93
- T_SIGN,
94
- T_IDENTIFIER,
95
104
  T_CLS_NUMBER,
96
- ] = Array(8).fill().map((_, i) => i)
105
+ T_SIGN,
106
+ T_COMMENT,
107
+ T_BREAK,
108
+ T_SPACE,
109
+ ] = types.map((_, i) => i)
97
110
 
98
111
  function isSpaces(str) {
99
112
  return /^[^\S\r\n]+$/g.test(str)
@@ -150,8 +163,11 @@ export function tokenize(code) {
150
163
  /** @type {{ tag: boolean; child: boolean; expr: boolean }} */
151
164
  const jsx = { tag: false, child: false, expr: false }
152
165
 
166
+ const inJsxLiterals = () => !jsx.tag && jsx.child && !jsx.expr
167
+
153
168
  function classify(token) {
154
- if (isCommentStart(token[0] + token[1])) {
169
+ const [chr0, chr1] = [token[0], token[1]]
170
+ if (isCommentStart(chr0 + chr1)) {
155
171
  return T_COMMENT
156
172
  } else if (keywords.has(token)) {
157
173
  return T_KEYWORD
@@ -160,19 +176,23 @@ export function tokenize(code) {
160
176
  } else if (
161
177
  (
162
178
  // is quoted string
163
- (isStringQuotation(token[0]) && !isStringQuotation(token[1])) ||
179
+ (isStringQuotation(chr0) && !isStringQuotation(chr1)) ||
164
180
  // is regex
165
- (!jsx.tag && isRegexStart(token[0] + token[1]) && token[token.length - 1] === '/')
181
+ (!jsx.tag && isRegexStart(chr0 + chr1) && token[token.length - 1] === '/')
166
182
  )
167
183
  ) {
168
184
  return T_STRING
169
185
  } else if (token === ' ') {
170
186
  return T_SPACE
171
- } else if (signs.has(token[0])) {
187
+ } else if (signs.has(chr0)) {
172
188
  return T_SIGN
173
189
  } else if (
174
- token[0] === token[0].toUpperCase() ||
175
- token === 'null'
190
+ !inJsxLiterals() &&
191
+ (
192
+ isIdentifierChar(chr0) &&
193
+ chr0 === chr0.toUpperCase() ||
194
+ token === 'null'
195
+ )
176
196
  ) {
177
197
  return T_CLS_NUMBER
178
198
  } else {
@@ -192,8 +212,8 @@ export function tokenize(code) {
192
212
  const prev = code[i - 1]
193
213
  const next = code[i + 1]
194
214
  const c_n = curr + next // current and next
195
- const p_c = prev + curr // previous and current
196
- const isJsxLiterals = jsx.child && !jsx.expr
215
+ const p_c = prev + curr // previous and current
216
+ const isJsxLiterals = inJsxLiterals()
197
217
 
198
218
  if (jsx.tag) {
199
219
  const isOpenElementEnd = curr === '>'
@@ -206,13 +226,6 @@ export function tokenize(code) {
206
226
  jsx.tag = true
207
227
  jsx.child = false
208
228
  }
209
-
210
- if (jsx.child && curr === '{') {
211
- jsx.expr = true
212
- }
213
- if (jsx.child && jsx.expr && curr === '}') {
214
- jsx.expr = false
215
- }
216
229
 
217
230
  if (
218
231
  !string.entered &&
@@ -275,7 +288,7 @@ export function tokenize(code) {
275
288
  } else {
276
289
  append()
277
290
  current = curr
278
- if (c_n === '</') {
291
+ if (c_n === '</' || c_n === '/>') {
279
292
  current = c_n
280
293
  append()
281
294
  i++
@@ -283,6 +296,13 @@ export function tokenize(code) {
283
296
  else if (jsxBrackets.has(curr)) append()
284
297
  }
285
298
  }
299
+
300
+ if (jsx.child && curr === '{') {
301
+ jsx.expr = true
302
+ }
303
+ if (jsx.child && jsx.expr && curr === '}') {
304
+ jsx.expr = false
305
+ }
286
306
  }
287
307
 
288
308
  append()
@@ -301,7 +321,7 @@ function generate(tokens) {
301
321
  output.push(
302
322
  type === T_BREAK
303
323
  ? '<br>'
304
- : `<span class="sh__${type}">${encode(token)}</span>`
324
+ : `<span class="sh__${types[type]}">${encode(token)}</span>`
305
325
  )
306
326
  }
307
327
  return output
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sugar-high",
3
- "version": "0.0.4",
3
+ "version": "0.0.8",
4
4
  "type": "module",
5
5
  "exports": "./lib/index.mjs",
6
6
  "description": "Super lightweight JSX syntax highlighter",