sugar-high 0.7.4 → 0.8.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/lib/index.d.ts CHANGED
@@ -1,3 +1,14 @@
1
- export function highlight(code: string): string
2
- export function tokenize(code: string): Array<[number, string]>
1
+ type HighlightOptions = {
2
+ keywords?: Set<string>
3
+ onCommentStart?: (curr: string, next: string) => boolean
4
+ }
5
+
6
+ export function highlight(code: string, options?: HighlightOptions): string
7
+ export function tokenize(code: string, options?: HighlightOptions): Array<[number, string]>
3
8
  export function generate(tokens: Array<[number, string]>): Array<any>
9
+ export const SugarHigh: {
10
+ TokenTypes: {
11
+ [key: number]: string
12
+ }
13
+ TokenMap: Map<string, number>
14
+ }
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
 
3
- const jsxBrackets = new Set(['<', '>', '{', '}', '[', ']'])
4
- const keywords = new Set([
3
+ const JSXBrackets = new Set(['<', '>', '{', '}', '[', ']'])
4
+ const Keywords_Js = new Set([
5
5
  'for',
6
6
  'do',
7
7
  'while',
@@ -45,7 +45,7 @@ const keywords = new Set([
45
45
  'static',
46
46
  ])
47
47
 
48
- const signs = new Set([
48
+ const Signs = new Set([
49
49
  '+',
50
50
  '-',
51
51
  '*',
@@ -73,9 +73,13 @@ const signs = new Set([
73
73
  '#',
74
74
  '@',
75
75
  '\\',
76
- ...jsxBrackets,
76
+ ...JSXBrackets,
77
77
  ])
78
78
 
79
+ const DefaultOptions = {
80
+ keywords: Keywords_Js,
81
+ onCommentStart: isCommentStart_Js,
82
+ }
79
83
 
80
84
  /**
81
85
  *
@@ -92,7 +96,7 @@ const signs = new Set([
92
96
  * 10 - space
93
97
  *
94
98
  */
95
- const types = /** @type {const} */ ([
99
+ const TokenTypes = /** @type {const} */ ([
96
100
  'identifier',
97
101
  'keyword',
98
102
  'string',
@@ -117,14 +121,14 @@ const [
117
121
  T_COMMENT,
118
122
  T_BREAK,
119
123
  T_SPACE,
120
- ] = /** @types {const} */ types.map((_, i) => i)
124
+ ] = /** @types {const} */ TokenTypes.map((_, i) => i)
121
125
 
122
126
  function isSpaces(str) {
123
127
  return /^[^\S\r\n]+$/g.test(str)
124
128
  }
125
129
 
126
130
  function isSign(ch) {
127
- return signs.has(ch)
131
+ return Signs.has(ch)
128
132
  }
129
133
 
130
134
  function encode(str) {
@@ -175,20 +179,26 @@ function isStringQuotation(chr) {
175
179
  return isSingleQuotes(chr) || isStrTemplateChr(chr)
176
180
  }
177
181
 
178
- function isCommentStart(str) {
179
- str = str.slice(0, 2)
182
+ function isCommentStart_Js(curr, next) {
183
+ const str = curr + next
180
184
  return str === '//' || str === '/*'
181
185
  }
182
186
 
183
187
  function isRegexStart(str) {
184
- return str[0] === '/' && !isCommentStart(str[0] + str[1])
188
+ return str[0] === '/' && !isCommentStart_Js(str[0], str[1])
185
189
  }
186
190
 
187
191
  /**
188
192
  * @param {string} code
193
+ * @param {{ keywords: Set<string> }} options
189
194
  * @return {Array<[number, string]>}
190
195
  */
191
- function tokenize(code) {
196
+ function tokenize(code, options) {
197
+ const {
198
+ keywords,
199
+ onCommentStart,
200
+ } = { ...DefaultOptions, ...options }
201
+
192
202
  let current = ''
193
203
  let type = -1
194
204
  /** @type {[number, string]} */
@@ -220,9 +230,11 @@ function tokenize(code) {
220
230
 
221
231
  /** @type {string | null} */
222
232
  let __strQuote = null
233
+ let __regexQuoteStart = false
223
234
  let __strTemplateExprStack = 0
224
235
  let __strTemplateQuoteStack = 0
225
236
  const inStringQuotes = () => __strQuote !== null
237
+ const inRegexQuotes = () => __regexQuoteStart
226
238
  const inStrTemplateLiterals = () => (__strTemplateQuoteStack > __strTemplateExprStack)
227
239
  const inStrTemplateExpr = () => __strTemplateQuoteStack > 0 && (__strTemplateQuoteStack === __strTemplateExprStack)
228
240
  const inStringContent = () => inStringQuotes() || inStrTemplateLiterals()
@@ -275,12 +287,20 @@ function tokenize(code) {
275
287
  }
276
288
  }
277
289
 
278
- const append = (_type, _token) => {
279
- if (_token) {
280
- current = _token
290
+ /**
291
+ *
292
+ * @param {number} type_
293
+ * @param {string} token_
294
+ */
295
+ const append = (type_, token_) => {
296
+ if (type_ || token_) {
297
+ const nType = TokenTypes[type_]
298
+ }
299
+ if (token_) {
300
+ current = token_
281
301
  }
282
302
  if (current) {
283
- type = _type || classify(current)
303
+ type = type_ || classify(current)
284
304
  /** @type [number, string] */
285
305
  const pair = [type, current]
286
306
  if (type !== T_SPACE && type !== T_BREAK) {
@@ -456,7 +476,13 @@ function tokenize(code) {
456
476
 
457
477
  // current and next char can form a jsx open or close tag
458
478
  if (curr === '<' && (next === '/' || isAlpha(next))) {
459
- __jsxEnter = true
479
+ if (
480
+ !inStringContent() &&
481
+ !inJsxLiterals() &&
482
+ !inRegexQuotes()
483
+ ) {
484
+ __jsxEnter = true
485
+ }
460
486
  }
461
487
  }
462
488
 
@@ -487,6 +513,7 @@ function tokenize(code) {
487
513
  continue
488
514
  }
489
515
 
516
+ __regexQuoteStart = true
490
517
  const start = i++
491
518
 
492
519
  // end of line of end of file
@@ -494,17 +521,20 @@ function tokenize(code) {
494
521
  const isEol = () => isEof() || code[i] === '\n'
495
522
 
496
523
  let foundClose = false
497
- // regex
524
+
525
+ // traverse to find closing regex slash
498
526
  for (; !isEol(); i++) {
499
527
  if (code[i] === '/' && code[i - 1] !== '\\') {
500
528
  foundClose = true
501
- // append regex flags
529
+ // end of regex, append regex flags
502
530
  while (start !== i && /^[a-z]$/.test(code[i + 1]) && !isEol()) {
503
531
  i++
504
532
  }
505
533
  break
506
534
  }
507
535
  }
536
+ __regexQuoteStart = false
537
+
508
538
  if (start !== i && foundClose) {
509
539
  // If current line is fully closed with string quotes or regex slashes,
510
540
  // add them to tokens
@@ -516,7 +546,7 @@ function tokenize(code) {
516
546
  append()
517
547
  i = start
518
548
  }
519
- } else if (isCommentStart(c_n)) {
549
+ } else if (onCommentStart(curr, next)) {
520
550
  append()
521
551
  const start = i
522
552
  if (next === '/') {
@@ -551,9 +581,9 @@ function tokenize(code) {
551
581
  __jsxExpr = false
552
582
  } else if (
553
583
  // it's jsx literals and is not a jsx bracket
554
- (isJsxLiterals && !jsxBrackets.has(curr)) ||
584
+ (isJsxLiterals && !JSXBrackets.has(curr)) ||
555
585
  // same type char as previous one in current token
556
- ((isWord(curr) === isWord(current[current.length - 1]) || __jsxChild()) && !signs.has(curr))
586
+ ((isWord(curr) === isWord(current[current.length - 1]) || __jsxChild()) && !Signs.has(curr))
557
587
  ) {
558
588
  current += curr
559
589
  } else {
@@ -571,7 +601,7 @@ function tokenize(code) {
571
601
  append()
572
602
  i++
573
603
  }
574
- else if (jsxBrackets.has(curr)) append()
604
+ else if (JSXBrackets.has(curr)) append()
575
605
  }
576
606
  }
577
607
  }
@@ -618,8 +648,8 @@ function generate(tokens) {
618
648
  value: value, // to encode
619
649
  }],
620
650
  properties: {
621
- className: `sh__token--${types[type]}`,
622
- style: `color: var(--sh-${types[type]})`,
651
+ className: `sh__token--${TokenTypes[type]}`,
652
+ style: `color: var(--sh-${TokenTypes[type]})`,
623
653
  },
624
654
  }
625
655
  ))
@@ -680,10 +710,11 @@ function toHtml(lines) {
680
710
  /**
681
711
  *
682
712
  * @param {string} code
713
+ * @param {{ keywords: Set<string> } | undefined} options
683
714
  * @returns {string}
684
715
  */
685
- function highlight(code) {
686
- const tokens = tokenize(code)
716
+ function highlight(code, options) {
717
+ const tokens = tokenize(code, options)
687
718
  const lines = generate(tokens)
688
719
  const output = toHtml(lines)
689
720
  return output
@@ -691,8 +722,8 @@ function highlight(code) {
691
722
 
692
723
  // namespace
693
724
  const SugarHigh = /** @type {const} */ {
694
- TokenTypes: types,
695
- TokenMap: new Map(types.map((type, i) => [type, i])),
725
+ TokenTypes,
726
+ TokenMap: new Map(TokenTypes.map((type, i) => [type, i])),
696
727
  }
697
728
 
698
729
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sugar-high",
3
- "version": "0.7.4",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "types": "./lib/index.d.ts",
6
6
  "exports": {