sugar-high 1.2.1 → 1.3.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 +13 -3
- package/lib/index.d.ts +2 -0
- package/lib/index.js +33 -8
- package/lib/presets/index.d.ts +2 -0
- package/lib/presets/index.js +1 -0
- package/lib/presets/lang/json.js +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Sugar High
|
|
2
2
|
|
|
3
|
-
[![
|
|
3
|
+
[![version][npm-version-badge]][npm]
|
|
4
|
+
[![downloads][npm-downloads-badge]][npm]
|
|
4
5
|
|
|
5
6
|
Super lightweight syntax highlighter for JavaScript and JSX—about **1 kB** minified and gzipped. Works in the browser or any JS runtime that can set HTML strings.
|
|
6
7
|
|
|
@@ -33,7 +34,15 @@ import { rust } from 'sugar-high/presets'
|
|
|
33
34
|
const html = highlight(source, { ...rust })
|
|
34
35
|
```
|
|
35
36
|
|
|
36
|
-
Available presets: `c`, `css`, `diff`, `go`, `java`, `python`, and `rust`.
|
|
37
|
+
Available presets: `c`, `css`, `diff`, `go`, `java`, `json`, `python`, and `rust`.
|
|
38
|
+
|
|
39
|
+
The `json` preset highlights quoted object keys as `property` tokens, keeping them distinct from string values:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import { json } from 'sugar-high/presets'
|
|
43
|
+
|
|
44
|
+
const html = highlight('{"name": "Alice"}', json)
|
|
45
|
+
```
|
|
37
46
|
|
|
38
47
|
For more language presets and syntax color themes, see **[sugar-high.vercel.app](https://sugar-high.vercel.app/)**.
|
|
39
48
|
|
|
@@ -108,6 +117,7 @@ MIT
|
|
|
108
117
|
|
|
109
118
|
<!-- Definitions -->
|
|
110
119
|
|
|
111
|
-
[npm-badge]: https://img.shields.io/npm/v/sugar-high
|
|
120
|
+
[npm-version-badge]: https://img.shields.io/npm/v/sugar-high?style=flat&colorA=000000&colorB=000000
|
|
121
|
+
[npm-downloads-badge]: https://img.shields.io/npm/dt/sugar-high.svg?style=flat&colorA=000000&colorB=000000
|
|
112
122
|
|
|
113
123
|
[npm]: https://www.npmjs.com/package/sugar-high
|
package/lib/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ type HighlightOptions = {
|
|
|
11
11
|
* or null/undefined or a number below 1 for default JS single-quoted string rules.
|
|
12
12
|
*/
|
|
13
13
|
onQuote?: (curr: string, i: number, code: string) => number | null | undefined
|
|
14
|
+
/** Highlight quoted object keys followed by `:` as `property` tokens. */
|
|
15
|
+
quotedKeys?: boolean
|
|
14
16
|
lineClassName?: (line: string, index: number) => string | null | undefined
|
|
15
17
|
}
|
|
16
18
|
|
package/lib/index.js
CHANGED
|
@@ -235,13 +235,18 @@ function isSign(ch) {
|
|
|
235
235
|
return Signs.has(ch)
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
const HtmlEntities = /** @type {Record<string, string>} */ ({
|
|
239
|
+
'&': '&',
|
|
240
|
+
'<': '<',
|
|
241
|
+
'>': '>',
|
|
242
|
+
'"': '"',
|
|
243
|
+
"'": ''',
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
/** @param {string} str */
|
|
238
247
|
function encode(str) {
|
|
239
|
-
return str
|
|
240
|
-
|
|
241
|
-
.replace(/</g, '<')
|
|
242
|
-
.replace(/>/g, '>')
|
|
243
|
-
.replace(/"/g, '"')
|
|
244
|
-
.replace(/'/g, ''')
|
|
248
|
+
if (!/[&<>"']/.test(str)) return str
|
|
249
|
+
return str.replace(/[&<>"']/g, chr => HtmlEntities[chr])
|
|
245
250
|
}
|
|
246
251
|
|
|
247
252
|
function isWord(chr) {
|
|
@@ -301,6 +306,12 @@ function isRegexStart(str) {
|
|
|
301
306
|
return str[0] === '/' && !isCommentStart_Js(str[0], str[1])
|
|
302
307
|
}
|
|
303
308
|
|
|
309
|
+
function isPropertyKey(code, quoteEnd) {
|
|
310
|
+
let i = quoteEnd + 1
|
|
311
|
+
while (i < code.length && /\s/.test(code[i])) i++
|
|
312
|
+
return code[i] === ':'
|
|
313
|
+
}
|
|
314
|
+
|
|
304
315
|
/**
|
|
305
316
|
* @param {string} code
|
|
306
317
|
* @param {{
|
|
@@ -309,6 +320,7 @@ function isRegexStart(str) {
|
|
|
309
320
|
* onCommentStart?: (curr: string, next: string) => number | boolean
|
|
310
321
|
* onCommentEnd?: (prev: string, curr: string) => number | boolean
|
|
311
322
|
* onQuote?: (curr: string, i: number, code: string) => number | null | undefined
|
|
323
|
+
* quotedKeys?: boolean
|
|
312
324
|
* lineClassName?: (line: string, index: number) => string | null | undefined
|
|
313
325
|
* } | undefined} options
|
|
314
326
|
* Optional `onQuote(curr, i, code)` at `code[i] === "'"`: return length to consume from `i` (>= 1),
|
|
@@ -364,6 +376,7 @@ function tokenize(code, options) {
|
|
|
364
376
|
|
|
365
377
|
/** @type {string | null} */
|
|
366
378
|
let __strQuote = null
|
|
379
|
+
let __strTokenStart = 0
|
|
367
380
|
let __regexQuoteStart = false
|
|
368
381
|
let __strTemplateExprStack = 0
|
|
369
382
|
let __strTemplateQuoteStack = 0
|
|
@@ -479,15 +492,23 @@ function tokenize(code, options) {
|
|
|
479
492
|
// Inside jsx literals or template literals, string quotation is still part of it.
|
|
480
493
|
if (isSingleQuotes(curr) && !inJsxLiterals() && !inStrTemplateLiterals()) {
|
|
481
494
|
append()
|
|
495
|
+
let isStringClose = false
|
|
482
496
|
if (prev !== `\\`) {
|
|
483
497
|
if (__strQuote && curr === __strQuote) {
|
|
484
498
|
__strQuote = null
|
|
499
|
+
isStringClose = true
|
|
485
500
|
} else if (!__strQuote) {
|
|
486
501
|
__strQuote = curr
|
|
502
|
+
__strTokenStart = tokens.length
|
|
487
503
|
}
|
|
488
504
|
}
|
|
489
505
|
|
|
490
506
|
append(T_STRING, curr)
|
|
507
|
+
if (mergedOptions.quotedKeys && isStringClose && isPropertyKey(code, i)) {
|
|
508
|
+
for (let tokenIndex = __strTokenStart; tokenIndex < tokens.length; tokenIndex++) {
|
|
509
|
+
tokens[tokenIndex][0] = T_PROPERTY
|
|
510
|
+
}
|
|
511
|
+
}
|
|
491
512
|
continue
|
|
492
513
|
}
|
|
493
514
|
|
|
@@ -770,8 +791,11 @@ function tokenize(code, options) {
|
|
|
770
791
|
isJsxLiterals
|
|
771
792
|
)
|
|
772
793
|
) {
|
|
773
|
-
|
|
774
|
-
|
|
794
|
+
let end = i + 1
|
|
795
|
+
while (code[end] === ' ') end++
|
|
796
|
+
current += code.slice(i, end)
|
|
797
|
+
i = end - 1
|
|
798
|
+
if (code[end] === '<') {
|
|
775
799
|
append()
|
|
776
800
|
}
|
|
777
801
|
} else {
|
|
@@ -966,6 +990,7 @@ function toHtml(lines) {
|
|
|
966
990
|
* onCommentStart?: (curr: string, next: string) => number | boolean
|
|
967
991
|
* onCommentEnd?: (curr: string, prev: string) => number | boolean
|
|
968
992
|
* onQuote?: (curr: string, i: number, code: string) => number | null | undefined
|
|
993
|
+
* quotedKeys?: boolean
|
|
969
994
|
* lineClassName?: (line: string, index: number) => string | null | undefined
|
|
970
995
|
* } | undefined} options
|
|
971
996
|
* `onQuote` same as `tokenize`.
|
package/lib/presets/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ type LanguageConfig = {
|
|
|
4
4
|
onCommentStart?(curr: string, next: string): 0 | 1 | 2
|
|
5
5
|
onCommentEnd?(prev: string, curr: string): 0 | 1 | 2
|
|
6
6
|
onQuote?(curr: string, i: number, code: string): number | null | undefined
|
|
7
|
+
quotedKeys?: boolean
|
|
7
8
|
lineClassName?(line: string, index: number): string | null | undefined
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -14,3 +15,4 @@ export const c: LanguageConfig
|
|
|
14
15
|
export const go: LanguageConfig
|
|
15
16
|
export const java: LanguageConfig
|
|
16
17
|
export const diff: LanguageConfig
|
|
18
|
+
export const json: LanguageConfig
|
package/lib/presets/index.js
CHANGED