arche-highlight 0.3.1 → 0.5.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.
@@ -12,13 +12,8 @@ function testComment(term) {
12
12
  || (term[0] === "/" && term[1] === "*")
13
13
  }
14
14
 
15
- // testOperator(term string) -> boolean
16
- function testOperator(term) {
17
- return term == "+" || term == "-" || term == "*" || term == "/" || term == "**" || term == "=" || term == "+=" || term == "++" || term == "-=" || term == "*=" || term == "/=" || term == "**=" || term == "==" || term == "===" || term == "!=" || term == "!==" || term == ">" || term == ">=" || term == "<" || term == "<=" || term == "?" || term == ":" || term == "&&" || term == "||" || term == "??" || term == "&" || term == "|" || term == "^" || term == "~" || term == ">>" || term == "<<" || term == "&=" || term == "|=" || term == "^="
18
- }
19
-
20
- // pushWordTerm(parsedElements Array<object|string>, term string) -> ()
21
- function pushWordTerm(parsedElements, term) {
15
+ // pushWordTerm(parsedElements Array<object|string>, term string, index number, text string) -> ()
16
+ function pushWordTerm(parsedElements, term, index, text) {
22
17
  if (term == "process" || term == "require" || term == "console" || term == "window" || term == "global" || term == "globalThis" || term == "isNaN") {
23
18
  parsedElements.push(Span({ class: "global-object" }, term))
24
19
  } else if (term == "undefined") {
@@ -30,8 +25,21 @@ function pushWordTerm(parsedElements, term) {
30
25
  } else if (term == "NaN") {
31
26
  parsedElements.push(Span({ class: "not-a-number" }, term))
32
27
  } else {
33
- parsedElements.push(term)
28
+ const spaces = []
29
+ let c = text[index]
30
+ while (c === " " || c === "\n") {
31
+ spaces.push(c)
32
+ index += 1
33
+ c = text[index]
34
+ }
35
+ if (c === "(") {
36
+ parsedElements.push(Span({ class: "function-name" }, term))
37
+ } else {
38
+ parsedElements.push(term)
39
+ }
40
+ parsedElements.push(...spaces)
34
41
  }
42
+ return index
35
43
  }
36
44
 
37
45
  function parseJavaScript(text) {
@@ -236,7 +244,12 @@ function parseJavaScript(text) {
236
244
  }
237
245
  else {
238
246
  if (term.length > 0) {
239
- pushWordTerm(parsedElements, term, index, text)
247
+ index = pushWordTerm(parsedElements, term, index, text)
248
+ c = text[index]
249
+ if (c !== " " && c !== "\n") {
250
+ term = ""
251
+ continue
252
+ }
240
253
  }
241
254
  parsedElements.push(c)
242
255
  term = ""
@@ -272,7 +285,7 @@ function parseJavaScript(text) {
272
285
  parsedElements.push(Span({ class: "function-name" }, term))
273
286
  isFunctionDeclaration = false
274
287
  }
275
- parsedElements.push(Span({ class: "opening-parentheses" }, c))
288
+ parsedElements.push(c)
276
289
  term = ""
277
290
  index += 1
278
291
  } else if (c === ",") {
@@ -286,7 +299,7 @@ function parseJavaScript(text) {
286
299
  if (term.length > 0) {
287
300
  pushWordTerm(parsedElements, term, index, text)
288
301
  }
289
- parsedElements.push(Span({ class: "closing-parentheses" }, c))
302
+ parsedElements.push(c)
290
303
  term = ""
291
304
  index += 1
292
305
  } else if (c === "{") {
package/ArcheHighlight.js CHANGED
@@ -18,13 +18,8 @@ function testComment(term) {
18
18
  || (term[0] === "/" && term[1] === "*")
19
19
  }
20
20
 
21
- // testOperator(term string) -> boolean
22
- function testOperator(term) {
23
- return term == "+" || term == "-" || term == "*" || term == "/" || term == "**" || term == "=" || term == "+=" || term == "++" || term == "-=" || term == "*=" || term == "/=" || term == "**=" || term == "==" || term == "===" || term == "!=" || term == "!==" || term == ">" || term == ">=" || term == "<" || term == "<=" || term == "?" || term == ":" || term == "&&" || term == "||" || term == "??" || term == "&" || term == "|" || term == "^" || term == "~" || term == ">>" || term == "<<" || term == "&=" || term == "|=" || term == "^="
24
- }
25
-
26
- // pushWordTerm(parsedElements Array<object|string>, term string) -> ()
27
- function pushWordTerm(parsedElements, term) {
21
+ // pushWordTerm(parsedElements Array<object|string>, term string, index number, text string) -> ()
22
+ function pushWordTerm(parsedElements, term, index, text) {
28
23
  if (term == "process" || term == "require" || term == "console" || term == "window" || term == "global" || term == "globalThis" || term == "isNaN") {
29
24
  parsedElements.push(Span({ class: "global-object" }, term))
30
25
  } else if (term == "undefined") {
@@ -36,8 +31,21 @@ function pushWordTerm(parsedElements, term) {
36
31
  } else if (term == "NaN") {
37
32
  parsedElements.push(Span({ class: "not-a-number" }, term))
38
33
  } else {
39
- parsedElements.push(term)
34
+ const spaces = []
35
+ let c = text[index]
36
+ while (c === " " || c === "\n") {
37
+ spaces.push(c)
38
+ index += 1
39
+ c = text[index]
40
+ }
41
+ if (c === "(") {
42
+ parsedElements.push(Span({ class: "function-name" }, term))
43
+ } else {
44
+ parsedElements.push(term)
45
+ }
46
+ parsedElements.push(...spaces)
40
47
  }
48
+ return index
41
49
  }
42
50
 
43
51
  function parseJavaScript(text) {
@@ -242,7 +250,12 @@ function parseJavaScript(text) {
242
250
  }
243
251
  else {
244
252
  if (term.length > 0) {
245
- pushWordTerm(parsedElements, term, index, text)
253
+ index = pushWordTerm(parsedElements, term, index, text)
254
+ c = text[index]
255
+ if (c !== " " && c !== "\n") {
256
+ term = ""
257
+ continue
258
+ }
246
259
  }
247
260
  parsedElements.push(c)
248
261
  term = ""
@@ -278,7 +291,7 @@ function parseJavaScript(text) {
278
291
  parsedElements.push(Span({ class: "function-name" }, term))
279
292
  isFunctionDeclaration = false
280
293
  }
281
- parsedElements.push(Span({ class: "opening-parentheses" }, c))
294
+ parsedElements.push(c)
282
295
  term = ""
283
296
  index += 1
284
297
  } else if (c === ",") {
@@ -292,7 +305,7 @@ function parseJavaScript(text) {
292
305
  if (term.length > 0) {
293
306
  pushWordTerm(parsedElements, term, index, text)
294
307
  }
295
- parsedElements.push(Span({ class: "closing-parentheses" }, c))
308
+ parsedElements.push(c)
296
309
  term = ""
297
310
  index += 1
298
311
  } else if (c === "{") {
@@ -12,13 +12,8 @@ function testComment(term) {
12
12
  || (term[0] === "/" && term[1] === "*")
13
13
  }
14
14
 
15
- // testOperator(term string) -> boolean
16
- function testOperator(term) {
17
- return term == "+" || term == "-" || term == "*" || term == "/" || term == "**" || term == "=" || term == "+=" || term == "++" || term == "-=" || term == "*=" || term == "/=" || term == "**=" || term == "==" || term == "===" || term == "!=" || term == "!==" || term == ">" || term == ">=" || term == "<" || term == "<=" || term == "?" || term == ":" || term == "&&" || term == "||" || term == "??" || term == "&" || term == "|" || term == "^" || term == "~" || term == ">>" || term == "<<" || term == "&=" || term == "|=" || term == "^="
18
- }
19
-
20
- // pushWordTerm(parsedElements Array<object|string>, term string) -> ()
21
- function pushWordTerm(parsedElements, term) {
15
+ // pushWordTerm(parsedElements Array<object|string>, term string, index number, text string) -> ()
16
+ function pushWordTerm(parsedElements, term, index, text) {
22
17
  if (term == "process" || term == "require" || term == "console" || term == "window" || term == "global" || term == "globalThis" || term == "isNaN") {
23
18
  parsedElements.push(Span({ class: "global-object" }, term))
24
19
  } else if (term == "undefined") {
@@ -30,8 +25,21 @@ function pushWordTerm(parsedElements, term) {
30
25
  } else if (term == "NaN") {
31
26
  parsedElements.push(Span({ class: "not-a-number" }, term))
32
27
  } else {
33
- parsedElements.push(term)
28
+ const spaces = []
29
+ let c = text[index]
30
+ while (c === " " || c === "\n") {
31
+ spaces.push(c)
32
+ index += 1
33
+ c = text[index]
34
+ }
35
+ if (c === "(") {
36
+ parsedElements.push(Span({ class: "function-name" }, term))
37
+ } else {
38
+ parsedElements.push(term)
39
+ }
40
+ parsedElements.push(...spaces)
34
41
  }
42
+ return index
35
43
  }
36
44
 
37
45
  function parseJavaScript(text) {
@@ -236,7 +244,12 @@ function parseJavaScript(text) {
236
244
  }
237
245
  else {
238
246
  if (term.length > 0) {
239
- pushWordTerm(parsedElements, term, index, text)
247
+ index = pushWordTerm(parsedElements, term, index, text)
248
+ c = text[index]
249
+ if (c !== " " && c !== "\n") {
250
+ term = ""
251
+ continue
252
+ }
240
253
  }
241
254
  parsedElements.push(c)
242
255
  term = ""
@@ -272,7 +285,7 @@ function parseJavaScript(text) {
272
285
  parsedElements.push(Span({ class: "function-name" }, term))
273
286
  isFunctionDeclaration = false
274
287
  }
275
- parsedElements.push(Span({ class: "opening-parentheses" }, c))
288
+ parsedElements.push(c)
276
289
  term = ""
277
290
  index += 1
278
291
  } else if (c === ",") {
@@ -286,7 +299,7 @@ function parseJavaScript(text) {
286
299
  if (term.length > 0) {
287
300
  pushWordTerm(parsedElements, term, index, text)
288
301
  }
289
- parsedElements.push(Span({ class: "closing-parentheses" }, c))
302
+ parsedElements.push(c)
290
303
  term = ""
291
304
  index += 1
292
305
  } else if (c === "{") {
package/README.md CHANGED
@@ -1,2 +1,88 @@
1
1
  # ArcheHighlight
2
- Syntax highlighting for [vanilla microfrontends](https://arche.gallery/).
2
+ Syntax highlighting for [vanilla microfrontends](https://arche.gallery/). Converts JavaScript code into a React Element or HTML.
3
+
4
+ ```javascript
5
+ const ReactElement = Arche(React)
6
+ window.Span = ReactElement.Span
7
+
8
+ const code = `
9
+ function f() {
10
+ const x = 1
11
+ }
12
+
13
+ f()
14
+ `
15
+
16
+ ArcheHighlight.parseJavaScript(code)
17
+ // '<span class="function-keyword">function</span>',
18
+ // ' ',
19
+ // '<span class="function-name">f</span>',
20
+ // ' ',
21
+ // '(',
22
+ // ')',
23
+ // ' ',
24
+ // '{',
25
+ // '\n',
26
+ // ' ',
27
+ // ' ',
28
+ // '<span class="variable-declaration-keyword">const</span>',
29
+ // ' ',
30
+ // 'x',
31
+ // ' ',
32
+ // '<span class="operator">=</span>',
33
+ // ' ',
34
+ // '<span class="number">1</span>',
35
+ // '\n',
36
+ // '}',
37
+ // '\n',
38
+ // '\n',
39
+ // '<span class="function-name">f</span>',
40
+ // '(',
41
+ // ')',
42
+ // '\n',
43
+ ```
44
+
45
+ ## React Element or HTML
46
+ ArcheHighlight requires a special `Span` function to exist globally on the `globalThis` object on the server or on the `window` object in browsers. The global `Span` function can be from `ReactElement`, which is created from `Arche` and `React`.
47
+ ```
48
+ const ReactElement = Arche(React)
49
+ window.Span = ReactElement.Span
50
+ ```
51
+
52
+ `React` can be the [React](https://react.dev/) library or a server-side polyfill of React. [ArcheHTML](https://github.com/richytong/ArcheHTML) comes installed with a `React` polyfill for server-side rendering.
53
+
54
+ ## Docs
55
+ ```coffeescript [specscript]
56
+ ArcheHighlight.parseJavaScript(code string) -> parsed string|object
57
+ ```
58
+ ArcheHighlight JavaScript parser. Parses code into a React Element or HTML with JavaScript classes.
59
+
60
+ Arguments:
61
+ * `code` - `string` - the JavaScript code to highlight.
62
+
63
+ Return:
64
+ * `parsed` - `string|object` - a React Element or HTML with JavaScript classes.
65
+
66
+ ### JavaScript Classes
67
+ The following JavaScript classes are added to the code as `span` elements of the parsed React Element or HTML:
68
+ * `comment` - single line (`//`) or multi-line comments (`/* */`)
69
+ * `number` - numbers, for example `1`, `0`, `2.5`, `-1`, `100`
70
+ * `string` - strings, for example `"a"`, `'a'`, `"This is a string."`
71
+ * `template-literal` - template literals, for example `\`This is a${x} ${y} literal\``
72
+ * `template-variable` - variables in template literals, for example the `${x}` and `${y}` in the template literal above.
73
+ * `bigint` - JavaScript BigInts, for example `2n`.
74
+ * `variable-declaration-keyword` - `var`, `const`, `let`
75
+ * `keyword` - `import`, `new`, `async`, `await`, `for`, `while`, `of`
76
+ * `function-keyword` - the `function` keyword for function declarations, for example `function f() {}`
77
+ * `arrow-function-operator` - the arrow function operator `=>` for arrow function declarations, for example `const fn = () => {}`
78
+ * `function-name` - the name of a function, either in a function declaration or as the function of a function call, for example in `function f() {}`, `f` would have a `function-name` class, and in `add(1, 2)`, `add` would have a `function-name` class.
79
+ * `operator` - the JavaScript operators `+`, `-`, `*`, `/`, `**`, `=`, `+=`, `++`, `-=`, `*=`, `/=`, `**=`, `==`, `===`, `!=`, `!==`, `>`, `>=`, `<`, `<=`, `?`, `:`, `&&`, `||`, `??`, `&`, `|`, `^`, `~`, `>>`, `<<`, `&=`, `|=`, and `^=`.
80
+
81
+ * `object-colon`
82
+ * `property-accessor`
83
+ * `spread-operator`
84
+ * `global-object` - global objects and functions: `process`, `require`, `console`, `window`, `global`, `globalThis`, `isNaN`
85
+ * `undefined` - the `undefined` value
86
+ * `null` - the `null` object
87
+ * `boolean` - booleans `true` and `false`
88
+ * `not-a-number` - the special numeric value `NaN` that represents an undefined or unrepresentable number, for example `0 / 0`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arche-highlight",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "Syntax highlighting for vanilla microfrontends",
5
5
  "author": "Richard Tong",
6
6
  "license": "CFOSS",