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