sugar-high 2.2.0 → 2.2.2

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/core.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
 
3
3
  import {
4
- assemble, generate, SugarHigh, toHtml, T_BREAK, T_CLASS, T_COMMENT, T_IDENTIFIER,
4
+ assemble, generate, render, SugarHigh, T_BREAK, T_CLASS, T_COMMENT, T_IDENTIFIER,
5
5
  T_KEYWORD, T_PROPERTY, T_SIGN, T_SPACE, T_STRING,
6
6
  } from './shared.js'
7
7
 
@@ -147,11 +147,6 @@ function parse(code, options) {
147
147
  return parsed
148
148
  }
149
149
 
150
- /** @param {ParsedCode} parsed @param {DisplayOptions | undefined} options */
151
- function render(parsed, options) {
152
- return toHtml(generate(parsed, options))
153
- }
154
-
155
150
  export { generate, parse, render, SugarHigh, tokenize }
156
151
 
157
152
  /**
package/lib/index.js CHANGED
@@ -4,12 +4,7 @@ import {
4
4
  parse,
5
5
  render,
6
6
  } from './core.js'
7
- import { languages } from './lang.js'
8
-
9
- /** @param {string | undefined} name */
10
- function configFor(name) {
11
- return languages.find(({ id }) => id === (name || 'javascript'))?.config
12
- }
7
+ import { configFor } from './presets/configs.js'
13
8
 
14
9
  /** @param {string} code @param {HighlightOptions | undefined} options */
15
10
  function highlight(code, options) {
package/lib/lang.js CHANGED
@@ -1,32 +1,10 @@
1
1
  // @ts-check
2
2
 
3
- import * as c from './lang/c.js'
4
- import * as cpp from './lang/cpp.js'
5
- import * as csharp from './lang/csharp.js'
6
- import * as css from './lang/css.js'
7
- import * as diff from './lang/diff.js'
8
- import * as dockerfile from './lang/dockerfile.js'
9
- import * as go from './lang/go.js'
10
- import * as html from './lang/html.js'
11
- import * as graphql from './lang/graphql.js'
12
- import * as hcl from './lang/hcl.js'
13
- import * as java from './lang/java.js'
14
- import * as json from './lang/json.js'
15
- import * as javascript from './lang/javascript.js'
16
- import * as kotlin from './lang/kotlin.js'
17
- import * as markdown from './lang/markdown.js'
18
- import * as php from './lang/php.js'
19
- import * as plaintext from './lang/plaintext.js'
20
- import * as powershell from './lang/powershell.js'
21
- import * as python from './lang/python.js'
22
- import * as ruby from './lang/ruby.js'
23
- import * as rust from './lang/rust.js'
24
- import * as shell from './lang/shell.js'
25
- import * as sql from './lang/sql.js'
26
- import * as swift from './lang/swift.js'
27
- import * as toml from './lang/toml.js'
28
- import * as typescript from './lang/typescript.js'
29
- import * as yaml from './lang/yaml.js'
3
+ import {
4
+ c, cpp, csharp, css, diff, dockerfile, go, graphql, hcl, html, java, javascript, json,
5
+ kotlin, markdown, nonJavaScript, php, plaintext, powershell, python, ruby, rust, shell, sql,
6
+ swift, toml, typescript, yaml,
7
+ } from './presets/configs.js'
30
8
 
31
9
  /**
32
10
  * @typedef {import('./core.js').ParseOptions} ParseOptions
@@ -38,20 +16,6 @@ import * as yaml from './lang/yaml.js'
38
16
  * }} Language
39
17
  */
40
18
 
41
- /**
42
- * Disable JavaScript-only scanner modes for a non-JavaScript language.
43
- * @param {ParseOptions} config
44
- * @returns {ParseOptions}
45
- */
46
- function nonJavaScript(config) {
47
- return {
48
- ...config,
49
- jsx: false,
50
- regex: false,
51
- templateStrings: false,
52
- }
53
- }
54
-
55
19
  /** @type {readonly Language[]} */
56
20
  const languages = [
57
21
  { id: 'javascript', extension: 'js', aliases: ['js', 'jsx', 'node'], config: javascript },
@@ -0,0 +1,88 @@
1
+ // @ts-check
2
+
3
+ import * as c from '../lang/c.js'
4
+ import * as cpp from '../lang/cpp.js'
5
+ import * as csharp from '../lang/csharp.js'
6
+ import * as css from '../lang/css.js'
7
+ import * as diff from '../lang/diff.js'
8
+ import * as dockerfile from '../lang/dockerfile.js'
9
+ import * as go from '../lang/go.js'
10
+ import * as graphql from '../lang/graphql.js'
11
+ import * as hcl from '../lang/hcl.js'
12
+ import * as html from '../lang/html.js'
13
+ import * as java from '../lang/java.js'
14
+ import * as javascript from '../lang/javascript.js'
15
+ import * as json from '../lang/json.js'
16
+ import * as kotlin from '../lang/kotlin.js'
17
+ import * as markdown from '../lang/markdown.js'
18
+ import * as php from '../lang/php.js'
19
+ import * as plaintext from '../lang/plaintext.js'
20
+ import * as powershell from '../lang/powershell.js'
21
+ import * as python from '../lang/python.js'
22
+ import * as ruby from '../lang/ruby.js'
23
+ import * as rust from '../lang/rust.js'
24
+ import * as shell from '../lang/shell.js'
25
+ import * as sql from '../lang/sql.js'
26
+ import * as swift from '../lang/swift.js'
27
+ import * as toml from '../lang/toml.js'
28
+ import * as typescript from '../lang/typescript.js'
29
+ import * as yaml from '../lang/yaml.js'
30
+
31
+ /**
32
+ * Disable JavaScript-only scanner modes for a non-JavaScript language.
33
+ * @param {import('../core.js').ParseOptions} config
34
+ * @returns {import('../core.js').ParseOptions}
35
+ */
36
+ function nonJavaScript(config) {
37
+ return {
38
+ ...config,
39
+ jsx: false,
40
+ regex: false,
41
+ templateStrings: false,
42
+ }
43
+ }
44
+
45
+ function createConfigs() {
46
+ return {
47
+ javascript,
48
+ typescript,
49
+ css: nonJavaScript(css),
50
+ python: nonJavaScript(python),
51
+ c: nonJavaScript(c),
52
+ go: nonJavaScript(go),
53
+ java: nonJavaScript(java),
54
+ rust: nonJavaScript(rust),
55
+ json: nonJavaScript(json),
56
+ diff: nonJavaScript(diff),
57
+ shell: nonJavaScript(shell),
58
+ cpp: nonJavaScript(cpp),
59
+ csharp: nonJavaScript(csharp),
60
+ sql: nonJavaScript(sql),
61
+ html,
62
+ yaml: nonJavaScript(yaml),
63
+ markdown: nonJavaScript(markdown),
64
+ plaintext: nonJavaScript(plaintext),
65
+ ruby: nonJavaScript(ruby),
66
+ kotlin: nonJavaScript(kotlin),
67
+ swift: nonJavaScript(swift),
68
+ php: nonJavaScript(php),
69
+ toml: nonJavaScript(toml),
70
+ powershell: nonJavaScript(powershell),
71
+ dockerfile: nonJavaScript(dockerfile),
72
+ graphql: nonJavaScript(graphql),
73
+ hcl: nonJavaScript(hcl),
74
+ }
75
+ }
76
+
77
+ const configs = /* @__PURE__ */ createConfigs()
78
+
79
+ /** @param {string | undefined} name */
80
+ function configFor(name) {
81
+ return configs[name || 'javascript']
82
+ }
83
+
84
+ export {
85
+ c, configFor, configs, cpp, csharp, css, diff, dockerfile, go, graphql, hcl, html, java,
86
+ javascript, json, kotlin, markdown, nonJavaScript, php, plaintext, powershell, python, ruby,
87
+ rust, shell, sql, swift, toml, typescript, yaml,
88
+ }
package/lib/shared.js CHANGED
@@ -64,6 +64,42 @@ function assemble(value, tokens) {
64
64
  return { value, lines }
65
65
  }
66
66
 
67
+ /**
68
+ * @param {import('./core.js').ParsedLine} parsedLine
69
+ * @param {import('./core.js').DisplayOptions['markLine']} markLine
70
+ */
71
+ function createLine(parsedLine, markLine) {
72
+ const line = {
73
+ index: parsedLine.index,
74
+ value: parsedLine.value,
75
+ tokens: parsedLine.tokens,
76
+ annotations: parsedLine.annotations,
77
+ className: `sh__line${parsedLine.annotations.map(annotation => ` sh__line--${annotation}`).join('')}`,
78
+ style: {},
79
+ properties: {},
80
+ }
81
+ markLine?.(line)
82
+ return line
83
+ }
84
+
85
+ /**
86
+ * @param {import('./core.js').ParsedToken} parsedToken
87
+ * @param {import('./core.js').DisplayOptions['cx']} cx
88
+ * @param {import('./core.js').DisplayOptions['mark']} mark
89
+ */
90
+ function createToken({ type, value }, cx, mark) {
91
+ const extraClassName = cx?.[type]
92
+ const token = {
93
+ type,
94
+ value,
95
+ className: `sh__token--${type}${extraClassName ? ` ${extraClassName}` : ''}`,
96
+ style: { color: `var(--sh-${type})` },
97
+ properties: {},
98
+ }
99
+ mark?.(token)
100
+ return token
101
+ }
102
+
67
103
  /**
68
104
  * @param {import('./core.js').ParsedCode} parsed
69
105
  * @param {import('./core.js').DisplayOptions | undefined} options
@@ -74,30 +110,13 @@ function generate(parsed, options) {
74
110
  const markLine = options?.markLine
75
111
 
76
112
  return parsed.lines.map((parsedLine) => {
77
- const line = {
78
- index: parsedLine.index,
79
- value: parsedLine.value,
80
- tokens: parsedLine.tokens,
81
- annotations: parsedLine.annotations,
82
- className: `sh__line${parsedLine.annotations.map(annotation => ` sh__line--${annotation}`).join('')}`,
83
- style: {},
84
- properties: {},
85
- }
86
- markLine?.(line)
113
+ const line = createLine(parsedLine, markLine)
87
114
 
88
115
  return {
89
116
  type: 'element',
90
117
  tagName: 'span',
91
- children: parsedLine.tokens.map(({ type, value }) => {
92
- const extraClassName = cx?.[type]
93
- const token = {
94
- type,
95
- value,
96
- className: `sh__token--${type}${extraClassName ? ` ${extraClassName}` : ''}`,
97
- style: { color: `var(--sh-${type})` },
98
- properties: {},
99
- }
100
- mark?.(token)
118
+ children: parsedLine.tokens.map((parsedToken) => {
119
+ const token = createToken(parsedToken, cx, mark)
101
120
  return {
102
121
  type: 'element',
103
122
  tokenType: token.type,
@@ -119,6 +138,46 @@ function generate(parsed, options) {
119
138
  })
120
139
  }
121
140
 
141
+ /**
142
+ * Render parsed lines directly while preserving generate()'s markup and mutable display hooks.
143
+ * @param {import('./core.js').ParsedCode} parsed
144
+ * @param {import('./core.js').DisplayOptions | undefined} options
145
+ */
146
+ function render(parsed, options) {
147
+ const cx = options?.cx
148
+ const mark = options?.mark
149
+ const markLine = options?.markLine
150
+
151
+ if (!cx && !mark && !markLine) {
152
+ return parsed.lines.map((line) => {
153
+ const className = `sh__line${line.annotations.map(annotation => ` sh__line--${annotation}`).join('')}`
154
+ const children = line.tokens.map(({ type, value }) => (
155
+ `<span class="sh__token--${type}" style="color:var(--sh-${type})">${encode(value)}</span>`
156
+ )).join('')
157
+ return `<span class="${encode(className)}">${children}</span>`
158
+ }).join('\n')
159
+ }
160
+
161
+ return parsed.lines.map((parsedLine) => {
162
+ const line = createLine(parsedLine, markLine)
163
+
164
+ const children = parsedLine.tokens.map((parsedToken) => {
165
+ const token = createToken(parsedToken, cx, mark)
166
+ return `<span ${attributes({
167
+ ...token.properties,
168
+ className: token.className,
169
+ style: token.style,
170
+ })}>${encode(token.value)}</span>`
171
+ }).join('')
172
+
173
+ return `<span ${attributes({
174
+ ...line.properties,
175
+ className: line.className,
176
+ style: line.style,
177
+ })}>${children}</span>`
178
+ }).join('\n')
179
+ }
180
+
122
181
  const entities = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' }
123
182
  /** @param {string} value */
124
183
  const encode = (value) => value.replace(/[&<>"']/g, character => entities[character])
@@ -133,17 +192,7 @@ function attributes(values) {
133
192
  return `class="${encode(values.className || '')}"${style ? ` style="${encode(style)}"` : ''}${properties ? ` ${properties}` : ''}`
134
193
  }
135
194
 
136
- /** @param {Array<any>} lines */
137
- function toHtml(lines) {
138
- return lines.map(line => {
139
- const children = line.children.map(token => {
140
- return `<${token.tagName} ${attributes(token.properties)}>${encode(token.children[0].value)}</${token.tagName}>`
141
- }).join('')
142
- return `<${line.tagName} ${attributes(line.properties)}>${children}</${line.tagName}>`
143
- }).join('\n')
144
- }
145
-
146
195
  export {
147
- assemble, encode, generate, SugarHigh, toHtml, TokenTypes, T_BREAK, T_CLASS, T_COMMENT, T_ENTITY, T_IDENTIFIER,
196
+ assemble, encode, generate, render, SugarHigh, TokenTypes, T_BREAK, T_CLASS, T_COMMENT, T_ENTITY, T_IDENTIFIER,
148
197
  T_JSX_LITERALS, T_KEYWORD, T_PROPERTY, T_SIGN, T_SPACE, T_STRING,
149
198
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sugar-high",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/huozhi/sugar-high.git",
@@ -40,6 +40,7 @@
40
40
  "scripts": {
41
41
  "test": "vitest",
42
42
  "build": "echo 'package requires no build'",
43
- "benchmark": "node scripts/benchmark.mjs"
43
+ "benchmark": "node scripts/benchmark.mjs",
44
+ "benchmark:large": "node scripts/benchmark-large.mjs"
44
45
  }
45
46
  }