arche-highlight 0.1.0 → 0.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.
@@ -0,0 +1,346 @@
1
+ /**
2
+ * ArcheHighlight may be freely distributed under the CFOSS license.
3
+ */
4
+
5
+ function testOperatorSymbol(c) {
6
+ return c === "+" || c === "-" || c === "*" || c === "/" || c === "=" || c === "&" || c === "|" || c === "<" || c === ">" || c === "~" || c === "^" || c === "!" || c === "?" || c === ":"
7
+ }
8
+
9
+ // testComment(term string) -> boolean
10
+ function testComment(term) {
11
+ return (term[0] === "/" && term[1] === "/")
12
+ || (term[0] === "/" && term[1] === "*")
13
+ }
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, index number, text string) -> ()
21
+ function pushWordTerm(parsedElements, term, index, text) {
22
+ if (term == "process" || term == "require" || term == "console" || term == "window" || term == "global" || term == "globalThis" || term == "isNaN") {
23
+ parsedElements.push(Span({ class: "global-object" }, term))
24
+ } else if (term == "undefined") {
25
+ parsedElements.push(Span({ class: "undefined" }, term))
26
+ } else if (term == "null") {
27
+ parsedElements.push(Span({ class: "null" }, term))
28
+ } else if (term == "true" || term == "false") {
29
+ parsedElements.push(Span({ class: "boolean" }, term))
30
+ } else if (term == "NaN") {
31
+ parsedElements.push(Span({ class: "not-a-number" }, term))
32
+ } else {
33
+ let c = text[index]
34
+ while (c === " " || c === "\n") {
35
+ index += 1
36
+ c = text[index]
37
+ }
38
+ if (c === "(") {
39
+ parsedElements.push(Span({ class: "function-name" }, term))
40
+ } else {
41
+ parsedElements.push(term)
42
+ }
43
+ }
44
+ }
45
+
46
+ function parseJavaScript(text) {
47
+ const parsedElements = []
48
+
49
+ let index = 0
50
+ let term = ""
51
+ let isSingleLineComment = false
52
+ let isMultiLineComment = false
53
+ let isNumber = false
54
+ let isOperator = false
55
+ let isStringSingleQuote = false
56
+ let isStringDoubleQuote = false
57
+ let isTemplateLiteral = false
58
+ let isTernaryOperator = false
59
+ let isFunctionDeclaration = false
60
+
61
+ while (index < text.length) {
62
+ let c = text[index]
63
+
64
+ if (isSingleLineComment && c === "\n") {
65
+ isSingleLineComment = false
66
+ parsedElements.push(Span({ class: "comment" }, term))
67
+ term = ""
68
+ } else if (isMultiLineComment && term[term.length - 1] === "*" && c === "/") {
69
+ isMultiLineComment = false
70
+ term += c
71
+ index += 1
72
+ c = text[index]
73
+ parsedElements.push(Span({ class: "comment" }, term))
74
+ term = ""
75
+ } else if (isNumber && !/[\dn]/.test(c)) {
76
+ isNumber = false
77
+ if (term[term.length - 1] === "n") {
78
+ parsedElements.push(Span({ class: "bigint" }, term))
79
+ } else if (term.includes("n")) {
80
+ parsedElements.push(term)
81
+ } else {
82
+ parsedElements.push(Span({ class: "number" }, term))
83
+ }
84
+ term = ""
85
+ } else if (isOperator && !testOperatorSymbol(c)) {
86
+ isOperator = false
87
+ if (term == "=>") {
88
+ parsedElements.push(Span({ class: "arrow-function-operator" }, term))
89
+ } else if (term == "?") {
90
+ isTernaryOperator = true
91
+ parsedElements.push(Span({ class: "operator" }, term))
92
+ } else if (term == ":") {
93
+ if (isTernaryOperator) {
94
+ parsedElements.push(Span({ class: "operator" }, term))
95
+ isTernaryOperator = false
96
+ } else {
97
+ parsedElements.push(Span({ class: "object-colon" }, term))
98
+ }
99
+ } else {
100
+ parsedElements.push(Span({ class: "operator" }, term))
101
+ }
102
+ term = ""
103
+ } else if (isStringSingleQuote && c === "'") {
104
+ isStringSingleQuote = false
105
+ term += c
106
+ index += 1
107
+ c = text[index]
108
+ parsedElements.push(Span({ class: "string" }, term))
109
+ term = ""
110
+ } else if (isStringDoubleQuote && c === "\"") {
111
+ isStringDoubleQuote = false
112
+ term += c
113
+ index += 1
114
+ c = text[index]
115
+ parsedElements.push(Span({ class: "string" }, term))
116
+ term = ""
117
+ } else if (isTemplateLiteral && c === "`") {
118
+ isTemplateLiteral = false
119
+ term += c
120
+ index += 1
121
+ c = text[index]
122
+ parsedElements.push(Span({ class: "template-literal" }, term))
123
+ term = ""
124
+ }
125
+
126
+ if (isSingleLineComment) {
127
+ term += c
128
+ index += 1
129
+ } else if (isMultiLineComment) {
130
+ term += c
131
+ index += 1
132
+ } else if (isNumber) {
133
+ term += c
134
+ index += 1
135
+ } else if (isOperator) {
136
+ term += c
137
+ index += 1
138
+ } else if (isStringSingleQuote) {
139
+ term += c
140
+ index += 1
141
+ } else if (isStringDoubleQuote) {
142
+ term += c
143
+ index += 1
144
+ } else if (isTemplateLiteral) {
145
+ if (c === "$") {
146
+ let templateVariable = c
147
+ index += 1
148
+ c = text[index]
149
+ if (c === "{") {
150
+ parsedElements.push(Span({ class: "template-literal" }, term))
151
+ while (c !== "}") {
152
+ templateVariable += c
153
+ index += 1
154
+ c = text[index]
155
+ }
156
+ templateVariable += c
157
+ parsedElements.push(Span({ class: "template-variable" }, templateVariable))
158
+ term = ""
159
+ index += 1
160
+ } else {
161
+ term += c
162
+ index += 1
163
+ }
164
+ } else {
165
+ term += c
166
+ index += 1
167
+ }
168
+ } else if (c === "/" && text[index + 1] === "/") {
169
+ isSingleLineComment = true
170
+ term += c
171
+ index += 1
172
+ } else if (c === "/" && text[index + 1] === "*") {
173
+ isMultiLineComment = true
174
+ term += c
175
+ index += 1
176
+ } else if (term.length == 0 && /\d/.test(c)) {
177
+ isNumber = true
178
+ term += c
179
+ index += 1
180
+ } else if (term.length == 0 && testOperatorSymbol(c)) {
181
+ isOperator = true
182
+ term += c
183
+ index += 1
184
+ } else if (testOperatorSymbol(c)) {
185
+ if (term.length > 0) {
186
+ pushWordTerm(parsedElements, term, index, text)
187
+ }
188
+ isOperator = true
189
+ term = c
190
+ index += 1
191
+ } else if (c === ":") {
192
+ parsedElements.push(term)
193
+ if (isTernaryOperator) {
194
+ parsedElements.push(Span({ class: "operator" }, term))
195
+ isTernaryOperator = false
196
+ } else {
197
+ parsedElements.push(Span({ class: "object-colon" }, c))
198
+ }
199
+ term = ""
200
+ index += 1
201
+ } else if (term.length == 0 && c === "'") {
202
+ isStringSingleQuote = true
203
+ term += c
204
+ index += 1
205
+ } else if (term.length == 0 && c === "\"") {
206
+ isStringDoubleQuote = true
207
+ term += c
208
+ index += 1
209
+ } else if (term.length == 0 && c === "`") {
210
+ isTemplateLiteral = true
211
+ term += c
212
+ index += 1
213
+ } else if (c === " " || c === "\n") {
214
+ if (term.length == 0) {
215
+ parsedElements.push(c)
216
+ index += 1
217
+ } else if (term == "const" || term == "let" || term == "var") {
218
+ parsedElements.push(Span({ class: "variable-declaration-keyword" }, term))
219
+ parsedElements.push(c)
220
+ term = ""
221
+ index += 1
222
+ } else if (term == "import" || term == "new" || term == "async" || term == "await" || term == "for" || term == "while" || term == "of") {
223
+ parsedElements.push(Span({ class: "keyword" }, term))
224
+ parsedElements.push(c)
225
+ term = ""
226
+ index += 1
227
+ } else if (term == "function") {
228
+ isFunctionDeclaration = true
229
+ parsedElements.push(Span({ class: "function-keyword" }, term))
230
+ parsedElements.push(c)
231
+ term = ""
232
+ index += 1
233
+ } else if (/^\d+$/.test(term)) {
234
+ parsedElements.push(Span({ class: "number" }, term))
235
+ parsedElements.push(c)
236
+ term = ""
237
+ index += 1
238
+ }
239
+ else if (isFunctionDeclaration) {
240
+ isFunctionDeclaration = false
241
+ parsedElements.push(Span({ class: "function-name" }, term))
242
+ parsedElements.push(c)
243
+ term = ""
244
+ index += 1
245
+ }
246
+ else {
247
+ if (term.length > 0) {
248
+ pushWordTerm(parsedElements, term, index, text)
249
+ }
250
+ parsedElements.push(c)
251
+ term = ""
252
+ index += 1
253
+ }
254
+ } else if (c === ".") {
255
+ if (term.length > 0) {
256
+ pushWordTerm(parsedElements, term, index, text)
257
+ }
258
+ term = c
259
+ index += 1
260
+ c = text[index]
261
+ while (c === ".") {
262
+ term += c
263
+ index += 1
264
+ c = text[index]
265
+ }
266
+ if (term.length === 1) {
267
+ parsedElements.push(Span({ class: "property-accessor" }, term))
268
+ } else {
269
+ parsedElements.push(Span({ class: "spread-operator" }, term))
270
+ }
271
+ term = ""
272
+ }
273
+ else if (c === "(") {
274
+ if (term === "") {
275
+ // skip
276
+ } else if (term == "require" || term == "isNaN") {
277
+ parsedElements.push(Span({ class: "global-object" }, term))
278
+ } else if (term == "while" || term == "for") {
279
+ parsedElements.push(Span({ class: "keyword" }, term))
280
+ } else {
281
+ parsedElements.push(Span({ class: "function-name" }, term))
282
+ isFunctionDeclaration = false
283
+ }
284
+ parsedElements.push(Span({ class: "opening-parentheses" }, c))
285
+ term = ""
286
+ index += 1
287
+ } else if (c === ",") {
288
+ if (term.length > 0) {
289
+ pushWordTerm(parsedElements, term, index, text)
290
+ }
291
+ parsedElements.push(c)
292
+ term = ""
293
+ index += 1
294
+ } else if (c === ")") {
295
+ if (term.length > 0) {
296
+ pushWordTerm(parsedElements, term, index, text)
297
+ }
298
+ parsedElements.push(Span({ class: "closing-parentheses" }, c))
299
+ term = ""
300
+ index += 1
301
+ } else if (c === "{") {
302
+ if (term.length > 0) {
303
+ pushWordTerm(parsedElements, term, index, text)
304
+ }
305
+ parsedElements.push(c)
306
+ term = ""
307
+ index += 1
308
+ } else if (c === "}") {
309
+ if (term.length > 0) {
310
+ pushWordTerm(parsedElements, term, index, text)
311
+ }
312
+ parsedElements.push(c)
313
+ term = ""
314
+ index += 1
315
+ } else if (c === "[") {
316
+ if (term.length > 0) {
317
+ pushWordTerm(parsedElements, term, index, text)
318
+ }
319
+ parsedElements.push(c)
320
+ term = ""
321
+ index += 1
322
+ } else if (c === "]") {
323
+ if (term.length > 0) {
324
+ pushWordTerm(parsedElements, term, index, text)
325
+ }
326
+ parsedElements.push(c)
327
+ term = ""
328
+ index += 1
329
+ } else {
330
+ term += c
331
+ index += 1
332
+ }
333
+ }
334
+
335
+ if (term.length > 0) {
336
+ pushWordTerm(parsedElements, term, index, text)
337
+ }
338
+
339
+ return parsedElements
340
+ }
341
+
342
+ const ArcheHighlight = {
343
+ parseJavaScript,
344
+ }
345
+
346
+ export default ArcheHighlight
package/ArcheHighlight.js CHANGED
@@ -1,5 +1,344 @@
1
+ /**
2
+ * ArcheHighlight may be freely distributed under the CFOSS license.
3
+ */
4
+
5
+ (function (root, ArcheHighlight) {
6
+ if (typeof module == 'object') (module.exports = ArcheHighlight) // CommonJS
7
+ else if (typeof define == 'function') define(() => ArcheHighlight) // AMD
8
+ else (root.ArcheHighlight = ArcheHighlight) // Browser
9
+ }(typeof globalThis == 'object' ? globalThis : this, (function () { 'use strict'
10
+
11
+ function testOperatorSymbol(c) {
12
+ return c === "+" || c === "-" || c === "*" || c === "/" || c === "=" || c === "&" || c === "|" || c === "<" || c === ">" || c === "~" || c === "^" || c === "!" || c === "?" || c === ":"
13
+ }
14
+
15
+ // testComment(term string) -> boolean
16
+ function testComment(term) {
17
+ return (term[0] === "/" && term[1] === "/")
18
+ || (term[0] === "/" && term[1] === "*")
19
+ }
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) {
28
+ if (term == "process" || term == "require" || term == "console" || term == "window" || term == "global" || term == "globalThis" || term == "isNaN") {
29
+ parsedElements.push(Span({ class: "global-object" }, term))
30
+ } else if (term == "undefined") {
31
+ parsedElements.push(Span({ class: "undefined" }, term))
32
+ } else if (term == "null") {
33
+ parsedElements.push(Span({ class: "null" }, term))
34
+ } else if (term == "true" || term == "false") {
35
+ parsedElements.push(Span({ class: "boolean" }, term))
36
+ } else if (term == "NaN") {
37
+ parsedElements.push(Span({ class: "not-a-number" }, term))
38
+ } else {
39
+ parsedElements.push(term)
40
+ }
41
+ }
42
+
43
+ function parseJavaScript(text) {
44
+ const parsedElements = []
45
+
46
+ let index = 0
47
+ let term = ""
48
+ let isSingleLineComment = false
49
+ let isMultiLineComment = false
50
+ let isNumber = false
51
+ let isOperator = false
52
+ let isStringSingleQuote = false
53
+ let isStringDoubleQuote = false
54
+ let isTemplateLiteral = false
55
+ let isTernaryOperator = false
56
+ let isFunctionDeclaration = false
57
+
58
+ while (index < text.length) {
59
+ let c = text[index]
60
+
61
+ if (isSingleLineComment && c === "\n") {
62
+ isSingleLineComment = false
63
+ parsedElements.push(Span({ class: "comment" }, term))
64
+ term = ""
65
+ } else if (isMultiLineComment && term[term.length - 1] === "*" && c === "/") {
66
+ isMultiLineComment = false
67
+ term += c
68
+ index += 1
69
+ c = text[index]
70
+ parsedElements.push(Span({ class: "comment" }, term))
71
+ term = ""
72
+ } else if (isNumber && !/[\dn]/.test(c)) {
73
+ isNumber = false
74
+ if (term[term.length - 1] === "n") {
75
+ parsedElements.push(Span({ class: "bigint" }, term))
76
+ } else if (term.includes("n")) {
77
+ parsedElements.push(term)
78
+ } else {
79
+ parsedElements.push(Span({ class: "number" }, term))
80
+ }
81
+ term = ""
82
+ } else if (isOperator && !testOperatorSymbol(c)) {
83
+ isOperator = false
84
+ if (term == "=>") {
85
+ parsedElements.push(Span({ class: "arrow-function-operator" }, term))
86
+ } else if (term == "?") {
87
+ isTernaryOperator = true
88
+ parsedElements.push(Span({ class: "operator" }, term))
89
+ } else if (term == ":") {
90
+ if (isTernaryOperator) {
91
+ parsedElements.push(Span({ class: "operator" }, term))
92
+ isTernaryOperator = false
93
+ } else {
94
+ parsedElements.push(Span({ class: "object-colon" }, term))
95
+ }
96
+ } else {
97
+ parsedElements.push(Span({ class: "operator" }, term))
98
+ }
99
+ term = ""
100
+ } else if (isStringSingleQuote && c === "'") {
101
+ isStringSingleQuote = false
102
+ term += c
103
+ index += 1
104
+ c = text[index]
105
+ parsedElements.push(Span({ class: "string" }, term))
106
+ term = ""
107
+ } else if (isStringDoubleQuote && c === "\"") {
108
+ isStringDoubleQuote = false
109
+ term += c
110
+ index += 1
111
+ c = text[index]
112
+ parsedElements.push(Span({ class: "string" }, term))
113
+ term = ""
114
+ } else if (isTemplateLiteral && c === "`") {
115
+ isTemplateLiteral = false
116
+ term += c
117
+ index += 1
118
+ c = text[index]
119
+ parsedElements.push(Span({ class: "template-literal" }, term))
120
+ term = ""
121
+ }
122
+
123
+ if (isSingleLineComment) {
124
+ term += c
125
+ index += 1
126
+ } else if (isMultiLineComment) {
127
+ term += c
128
+ index += 1
129
+ } else if (isNumber) {
130
+ term += c
131
+ index += 1
132
+ } else if (isOperator) {
133
+ term += c
134
+ index += 1
135
+ } else if (isStringSingleQuote) {
136
+ term += c
137
+ index += 1
138
+ } else if (isStringDoubleQuote) {
139
+ term += c
140
+ index += 1
141
+ } else if (isTemplateLiteral) {
142
+ if (c === "$") {
143
+ let templateVariable = c
144
+ index += 1
145
+ c = text[index]
146
+ if (c === "{") {
147
+ parsedElements.push(Span({ class: "template-literal" }, term))
148
+ while (c !== "}") {
149
+ templateVariable += c
150
+ index += 1
151
+ c = text[index]
152
+ }
153
+ templateVariable += c
154
+ parsedElements.push(Span({ class: "template-variable" }, templateVariable))
155
+ term = ""
156
+ index += 1
157
+ } else {
158
+ term += c
159
+ index += 1
160
+ }
161
+ } else {
162
+ term += c
163
+ index += 1
164
+ }
165
+ } else if (c === "/" && text[index + 1] === "/") {
166
+ isSingleLineComment = true
167
+ term += c
168
+ index += 1
169
+ } else if (c === "/" && text[index + 1] === "*") {
170
+ isMultiLineComment = true
171
+ term += c
172
+ index += 1
173
+ } else if (term.length == 0 && /\d/.test(c)) {
174
+ isNumber = true
175
+ term += c
176
+ index += 1
177
+ } else if (term.length == 0 && testOperatorSymbol(c)) {
178
+ isOperator = true
179
+ term += c
180
+ index += 1
181
+ } else if (testOperatorSymbol(c)) {
182
+ if (term.length > 0) {
183
+ pushWordTerm(parsedElements, term, index, text)
184
+ }
185
+ isOperator = true
186
+ term = c
187
+ index += 1
188
+ } else if (c === ":") {
189
+ parsedElements.push(term)
190
+ if (isTernaryOperator) {
191
+ parsedElements.push(Span({ class: "operator" }, term))
192
+ isTernaryOperator = false
193
+ } else {
194
+ parsedElements.push(Span({ class: "object-colon" }, c))
195
+ }
196
+ term = ""
197
+ index += 1
198
+ } else if (term.length == 0 && c === "'") {
199
+ isStringSingleQuote = true
200
+ term += c
201
+ index += 1
202
+ } else if (term.length == 0 && c === "\"") {
203
+ isStringDoubleQuote = true
204
+ term += c
205
+ index += 1
206
+ } else if (term.length == 0 && c === "`") {
207
+ isTemplateLiteral = true
208
+ term += c
209
+ index += 1
210
+ } else if (c === " " || c === "\n") {
211
+ if (term.length == 0) {
212
+ parsedElements.push(c)
213
+ index += 1
214
+ } else if (term == "const" || term == "let" || term == "var") {
215
+ parsedElements.push(Span({ class: "variable-declaration-keyword" }, term))
216
+ parsedElements.push(c)
217
+ term = ""
218
+ index += 1
219
+ } else if (term == "import" || term == "new" || term == "async" || term == "await" || term == "for" || term == "while" || term == "of") {
220
+ parsedElements.push(Span({ class: "keyword" }, term))
221
+ parsedElements.push(c)
222
+ term = ""
223
+ index += 1
224
+ } else if (term == "function") {
225
+ isFunctionDeclaration = true
226
+ parsedElements.push(Span({ class: "function-keyword" }, term))
227
+ parsedElements.push(c)
228
+ term = ""
229
+ index += 1
230
+ } else if (/^\d+$/.test(term)) {
231
+ parsedElements.push(Span({ class: "number" }, term))
232
+ parsedElements.push(c)
233
+ term = ""
234
+ index += 1
235
+ }
236
+ else if (isFunctionDeclaration) {
237
+ isFunctionDeclaration = false
238
+ parsedElements.push(Span({ class: "function-name" }, term))
239
+ parsedElements.push(c)
240
+ term = ""
241
+ index += 1
242
+ }
243
+ else {
244
+ if (term.length > 0) {
245
+ pushWordTerm(parsedElements, term, index, text)
246
+ }
247
+ parsedElements.push(c)
248
+ term = ""
249
+ index += 1
250
+ }
251
+ } else if (c === ".") {
252
+ if (term.length > 0) {
253
+ pushWordTerm(parsedElements, term, index, text)
254
+ }
255
+ term = c
256
+ index += 1
257
+ c = text[index]
258
+ while (c === ".") {
259
+ term += c
260
+ index += 1
261
+ c = text[index]
262
+ }
263
+ if (term.length === 1) {
264
+ parsedElements.push(Span({ class: "property-accessor" }, term))
265
+ } else {
266
+ parsedElements.push(Span({ class: "spread-operator" }, term))
267
+ }
268
+ term = ""
269
+ }
270
+ else if (c === "(") {
271
+ if (term === "") {
272
+ // skip
273
+ } else if (term == "require" || term == "isNaN") {
274
+ parsedElements.push(Span({ class: "global-object" }, term))
275
+ } else if (term == "while" || term == "for") {
276
+ parsedElements.push(Span({ class: "keyword" }, term))
277
+ } else {
278
+ parsedElements.push(Span({ class: "function-name" }, term))
279
+ isFunctionDeclaration = false
280
+ }
281
+ parsedElements.push(Span({ class: "opening-parentheses" }, c))
282
+ term = ""
283
+ index += 1
284
+ } else if (c === ",") {
285
+ if (term.length > 0) {
286
+ pushWordTerm(parsedElements, term, index, text)
287
+ }
288
+ parsedElements.push(c)
289
+ term = ""
290
+ index += 1
291
+ } else if (c === ")") {
292
+ if (term.length > 0) {
293
+ pushWordTerm(parsedElements, term, index, text)
294
+ }
295
+ parsedElements.push(Span({ class: "closing-parentheses" }, c))
296
+ term = ""
297
+ index += 1
298
+ } else if (c === "{") {
299
+ if (term.length > 0) {
300
+ pushWordTerm(parsedElements, term, index, text)
301
+ }
302
+ parsedElements.push(c)
303
+ term = ""
304
+ index += 1
305
+ } else if (c === "}") {
306
+ if (term.length > 0) {
307
+ pushWordTerm(parsedElements, term, index, text)
308
+ }
309
+ parsedElements.push(c)
310
+ term = ""
311
+ index += 1
312
+ } else if (c === "[") {
313
+ if (term.length > 0) {
314
+ pushWordTerm(parsedElements, term, index, text)
315
+ }
316
+ parsedElements.push(c)
317
+ term = ""
318
+ index += 1
319
+ } else if (c === "]") {
320
+ if (term.length > 0) {
321
+ pushWordTerm(parsedElements, term, index, text)
322
+ }
323
+ parsedElements.push(c)
324
+ term = ""
325
+ index += 1
326
+ } else {
327
+ term += c
328
+ index += 1
329
+ }
330
+ }
331
+
332
+ if (term.length > 0) {
333
+ pushWordTerm(parsedElements, term, index, text)
334
+ }
335
+
336
+ return parsedElements
337
+ }
338
+
1
339
  const ArcheHighlight = {
2
- parseJavaScript: require("./parseJavaScript"),
340
+ parseJavaScript,
3
341
  }
4
342
 
5
- module.exports = ArcheHighlight
343
+ return ArcheHighlight
344
+ }())))
@@ -0,0 +1,346 @@
1
+ /**
2
+ * ArcheHighlight may be freely distributed under the CFOSS license.
3
+ */
4
+
5
+ function testOperatorSymbol(c) {
6
+ return c === "+" || c === "-" || c === "*" || c === "/" || c === "=" || c === "&" || c === "|" || c === "<" || c === ">" || c === "~" || c === "^" || c === "!" || c === "?" || c === ":"
7
+ }
8
+
9
+ // testComment(term string) -> boolean
10
+ function testComment(term) {
11
+ return (term[0] === "/" && term[1] === "/")
12
+ || (term[0] === "/" && term[1] === "*")
13
+ }
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, index number, text string) -> ()
21
+ function pushWordTerm(parsedElements, term, index, text) {
22
+ if (term == "process" || term == "require" || term == "console" || term == "window" || term == "global" || term == "globalThis" || term == "isNaN") {
23
+ parsedElements.push(Span({ class: "global-object" }, term))
24
+ } else if (term == "undefined") {
25
+ parsedElements.push(Span({ class: "undefined" }, term))
26
+ } else if (term == "null") {
27
+ parsedElements.push(Span({ class: "null" }, term))
28
+ } else if (term == "true" || term == "false") {
29
+ parsedElements.push(Span({ class: "boolean" }, term))
30
+ } else if (term == "NaN") {
31
+ parsedElements.push(Span({ class: "not-a-number" }, term))
32
+ } else {
33
+ let c = text[index]
34
+ while (c === " " || c === "\n") {
35
+ index += 1
36
+ c = text[index]
37
+ }
38
+ if (c === "(") {
39
+ parsedElements.push(Span({ class: "function-name" }, term))
40
+ } else {
41
+ parsedElements.push(term)
42
+ }
43
+ }
44
+ }
45
+
46
+ function parseJavaScript(text) {
47
+ const parsedElements = []
48
+
49
+ let index = 0
50
+ let term = ""
51
+ let isSingleLineComment = false
52
+ let isMultiLineComment = false
53
+ let isNumber = false
54
+ let isOperator = false
55
+ let isStringSingleQuote = false
56
+ let isStringDoubleQuote = false
57
+ let isTemplateLiteral = false
58
+ let isTernaryOperator = false
59
+ let isFunctionDeclaration = false
60
+
61
+ while (index < text.length) {
62
+ let c = text[index]
63
+
64
+ if (isSingleLineComment && c === "\n") {
65
+ isSingleLineComment = false
66
+ parsedElements.push(Span({ class: "comment" }, term))
67
+ term = ""
68
+ } else if (isMultiLineComment && term[term.length - 1] === "*" && c === "/") {
69
+ isMultiLineComment = false
70
+ term += c
71
+ index += 1
72
+ c = text[index]
73
+ parsedElements.push(Span({ class: "comment" }, term))
74
+ term = ""
75
+ } else if (isNumber && !/[\dn]/.test(c)) {
76
+ isNumber = false
77
+ if (term[term.length - 1] === "n") {
78
+ parsedElements.push(Span({ class: "bigint" }, term))
79
+ } else if (term.includes("n")) {
80
+ parsedElements.push(term)
81
+ } else {
82
+ parsedElements.push(Span({ class: "number" }, term))
83
+ }
84
+ term = ""
85
+ } else if (isOperator && !testOperatorSymbol(c)) {
86
+ isOperator = false
87
+ if (term == "=>") {
88
+ parsedElements.push(Span({ class: "arrow-function-operator" }, term))
89
+ } else if (term == "?") {
90
+ isTernaryOperator = true
91
+ parsedElements.push(Span({ class: "operator" }, term))
92
+ } else if (term == ":") {
93
+ if (isTernaryOperator) {
94
+ parsedElements.push(Span({ class: "operator" }, term))
95
+ isTernaryOperator = false
96
+ } else {
97
+ parsedElements.push(Span({ class: "object-colon" }, term))
98
+ }
99
+ } else {
100
+ parsedElements.push(Span({ class: "operator" }, term))
101
+ }
102
+ term = ""
103
+ } else if (isStringSingleQuote && c === "'") {
104
+ isStringSingleQuote = false
105
+ term += c
106
+ index += 1
107
+ c = text[index]
108
+ parsedElements.push(Span({ class: "string" }, term))
109
+ term = ""
110
+ } else if (isStringDoubleQuote && c === "\"") {
111
+ isStringDoubleQuote = false
112
+ term += c
113
+ index += 1
114
+ c = text[index]
115
+ parsedElements.push(Span({ class: "string" }, term))
116
+ term = ""
117
+ } else if (isTemplateLiteral && c === "`") {
118
+ isTemplateLiteral = false
119
+ term += c
120
+ index += 1
121
+ c = text[index]
122
+ parsedElements.push(Span({ class: "template-literal" }, term))
123
+ term = ""
124
+ }
125
+
126
+ if (isSingleLineComment) {
127
+ term += c
128
+ index += 1
129
+ } else if (isMultiLineComment) {
130
+ term += c
131
+ index += 1
132
+ } else if (isNumber) {
133
+ term += c
134
+ index += 1
135
+ } else if (isOperator) {
136
+ term += c
137
+ index += 1
138
+ } else if (isStringSingleQuote) {
139
+ term += c
140
+ index += 1
141
+ } else if (isStringDoubleQuote) {
142
+ term += c
143
+ index += 1
144
+ } else if (isTemplateLiteral) {
145
+ if (c === "$") {
146
+ let templateVariable = c
147
+ index += 1
148
+ c = text[index]
149
+ if (c === "{") {
150
+ parsedElements.push(Span({ class: "template-literal" }, term))
151
+ while (c !== "}") {
152
+ templateVariable += c
153
+ index += 1
154
+ c = text[index]
155
+ }
156
+ templateVariable += c
157
+ parsedElements.push(Span({ class: "template-variable" }, templateVariable))
158
+ term = ""
159
+ index += 1
160
+ } else {
161
+ term += c
162
+ index += 1
163
+ }
164
+ } else {
165
+ term += c
166
+ index += 1
167
+ }
168
+ } else if (c === "/" && text[index + 1] === "/") {
169
+ isSingleLineComment = true
170
+ term += c
171
+ index += 1
172
+ } else if (c === "/" && text[index + 1] === "*") {
173
+ isMultiLineComment = true
174
+ term += c
175
+ index += 1
176
+ } else if (term.length == 0 && /\d/.test(c)) {
177
+ isNumber = true
178
+ term += c
179
+ index += 1
180
+ } else if (term.length == 0 && testOperatorSymbol(c)) {
181
+ isOperator = true
182
+ term += c
183
+ index += 1
184
+ } else if (testOperatorSymbol(c)) {
185
+ if (term.length > 0) {
186
+ pushWordTerm(parsedElements, term, index, text)
187
+ }
188
+ isOperator = true
189
+ term = c
190
+ index += 1
191
+ } else if (c === ":") {
192
+ parsedElements.push(term)
193
+ if (isTernaryOperator) {
194
+ parsedElements.push(Span({ class: "operator" }, term))
195
+ isTernaryOperator = false
196
+ } else {
197
+ parsedElements.push(Span({ class: "object-colon" }, c))
198
+ }
199
+ term = ""
200
+ index += 1
201
+ } else if (term.length == 0 && c === "'") {
202
+ isStringSingleQuote = true
203
+ term += c
204
+ index += 1
205
+ } else if (term.length == 0 && c === "\"") {
206
+ isStringDoubleQuote = true
207
+ term += c
208
+ index += 1
209
+ } else if (term.length == 0 && c === "`") {
210
+ isTemplateLiteral = true
211
+ term += c
212
+ index += 1
213
+ } else if (c === " " || c === "\n") {
214
+ if (term.length == 0) {
215
+ parsedElements.push(c)
216
+ index += 1
217
+ } else if (term == "const" || term == "let" || term == "var") {
218
+ parsedElements.push(Span({ class: "variable-declaration-keyword" }, term))
219
+ parsedElements.push(c)
220
+ term = ""
221
+ index += 1
222
+ } else if (term == "import" || term == "new" || term == "async" || term == "await" || term == "for" || term == "while" || term == "of") {
223
+ parsedElements.push(Span({ class: "keyword" }, term))
224
+ parsedElements.push(c)
225
+ term = ""
226
+ index += 1
227
+ } else if (term == "function") {
228
+ isFunctionDeclaration = true
229
+ parsedElements.push(Span({ class: "function-keyword" }, term))
230
+ parsedElements.push(c)
231
+ term = ""
232
+ index += 1
233
+ } else if (/^\d+$/.test(term)) {
234
+ parsedElements.push(Span({ class: "number" }, term))
235
+ parsedElements.push(c)
236
+ term = ""
237
+ index += 1
238
+ }
239
+ else if (isFunctionDeclaration) {
240
+ isFunctionDeclaration = false
241
+ parsedElements.push(Span({ class: "function-name" }, term))
242
+ parsedElements.push(c)
243
+ term = ""
244
+ index += 1
245
+ }
246
+ else {
247
+ if (term.length > 0) {
248
+ pushWordTerm(parsedElements, term, index, text)
249
+ }
250
+ parsedElements.push(c)
251
+ term = ""
252
+ index += 1
253
+ }
254
+ } else if (c === ".") {
255
+ if (term.length > 0) {
256
+ pushWordTerm(parsedElements, term, index, text)
257
+ }
258
+ term = c
259
+ index += 1
260
+ c = text[index]
261
+ while (c === ".") {
262
+ term += c
263
+ index += 1
264
+ c = text[index]
265
+ }
266
+ if (term.length === 1) {
267
+ parsedElements.push(Span({ class: "property-accessor" }, term))
268
+ } else {
269
+ parsedElements.push(Span({ class: "spread-operator" }, term))
270
+ }
271
+ term = ""
272
+ }
273
+ else if (c === "(") {
274
+ if (term === "") {
275
+ // skip
276
+ } else if (term == "require" || term == "isNaN") {
277
+ parsedElements.push(Span({ class: "global-object" }, term))
278
+ } else if (term == "while" || term == "for") {
279
+ parsedElements.push(Span({ class: "keyword" }, term))
280
+ } else {
281
+ parsedElements.push(Span({ class: "function-name" }, term))
282
+ isFunctionDeclaration = false
283
+ }
284
+ parsedElements.push(Span({ class: "opening-parentheses" }, c))
285
+ term = ""
286
+ index += 1
287
+ } else if (c === ",") {
288
+ if (term.length > 0) {
289
+ pushWordTerm(parsedElements, term, index, text)
290
+ }
291
+ parsedElements.push(c)
292
+ term = ""
293
+ index += 1
294
+ } else if (c === ")") {
295
+ if (term.length > 0) {
296
+ pushWordTerm(parsedElements, term, index, text)
297
+ }
298
+ parsedElements.push(Span({ class: "closing-parentheses" }, c))
299
+ term = ""
300
+ index += 1
301
+ } else if (c === "{") {
302
+ if (term.length > 0) {
303
+ pushWordTerm(parsedElements, term, index, text)
304
+ }
305
+ parsedElements.push(c)
306
+ term = ""
307
+ index += 1
308
+ } else if (c === "}") {
309
+ if (term.length > 0) {
310
+ pushWordTerm(parsedElements, term, index, text)
311
+ }
312
+ parsedElements.push(c)
313
+ term = ""
314
+ index += 1
315
+ } else if (c === "[") {
316
+ if (term.length > 0) {
317
+ pushWordTerm(parsedElements, term, index, text)
318
+ }
319
+ parsedElements.push(c)
320
+ term = ""
321
+ index += 1
322
+ } else if (c === "]") {
323
+ if (term.length > 0) {
324
+ pushWordTerm(parsedElements, term, index, text)
325
+ }
326
+ parsedElements.push(c)
327
+ term = ""
328
+ index += 1
329
+ } else {
330
+ term += c
331
+ index += 1
332
+ }
333
+ }
334
+
335
+ if (term.length > 0) {
336
+ pushWordTerm(parsedElements, term, index, text)
337
+ }
338
+
339
+ return parsedElements
340
+ }
341
+
342
+ const ArcheHighlight = {
343
+ parseJavaScript,
344
+ }
345
+
346
+ export default ArcheHighlight
package/README.md CHANGED
@@ -1,2 +1,2 @@
1
1
  # ArcheHighlight
2
- Syntax highlighting for [vanilla microfrontends](https://arche.gallery/)
2
+ Syntax highlighting for [vanilla microfrontends](https://arche.gallery/).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arche-highlight",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Syntax highlighting for vanilla microfrontends",
5
5
  "author": "Richard Tong",
6
6
  "license": "CFOSS",
@@ -15,6 +15,7 @@
15
15
  },
16
16
  "files": [
17
17
  "ArcheHighlight.js",
18
+ "ArcheHighlight.es.js",
18
19
  "ArcheHighlight.mjs",
19
20
  "package.json"
20
21
  ],