@elicdavis/node-flow 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/deploy.yml +57 -0
- package/README.md +159 -0
- package/dev.tsconfig.json +18 -0
- package/docs/promotional-image.png +0 -0
- package/esbuild.ts +32 -0
- package/index.html +311 -0
- package/package.json +50 -0
- package/src/camera.ts +30 -0
- package/src/connection.ts +249 -0
- package/src/contextMenu.ts +367 -0
- package/src/draggable.ts +13 -0
- package/src/elements/base.ts +192 -0
- package/src/elements/container.ts +119 -0
- package/src/elements/interfaces.ts +50 -0
- package/src/elements/text.ts +86 -0
- package/src/graph.ts +535 -0
- package/src/graphSubsystem.ts +31 -0
- package/src/index.ts +28 -0
- package/src/input.ts +153 -0
- package/src/markdown/entry.ts +323 -0
- package/src/markdown/lexicalParser.ts +148 -0
- package/src/markdown/markdown.ts +14 -0
- package/src/markdown/syntaxParser.ts +344 -0
- package/src/markdown/token.ts +43 -0
- package/src/metadata.ts +3 -0
- package/src/node.ts +1130 -0
- package/src/nodes/factory.ts +87 -0
- package/src/nodes/publisher.ts +98 -0
- package/src/nodes/subsystem.ts +760 -0
- package/src/notes/note.ts +295 -0
- package/src/notes/subsystem.ts +262 -0
- package/src/organize.ts +181 -0
- package/src/pass/subsystem.ts +64 -0
- package/src/performance.ts +9 -0
- package/src/popup.ts +81 -0
- package/src/popups/form.ts +63 -0
- package/src/popups/string.ts +33 -0
- package/src/port.ts +223 -0
- package/src/quickMenu.ts +330 -0
- package/src/styles/box.ts +104 -0
- package/src/styles/canvasTextAlign.ts +8 -0
- package/src/styles/canvasTextBaseline.ts +9 -0
- package/src/styles/cursor.ts +18 -0
- package/src/styles/stroke.ts +39 -0
- package/src/styles/text.ts +90 -0
- package/src/styles/textBox.ts +82 -0
- package/src/theme.ts +78 -0
- package/src/types/box.ts +126 -0
- package/src/types/list.ts +41 -0
- package/src/types/pool.ts +66 -0
- package/src/types/text.ts +136 -0
- package/src/types/vector2.ts +34 -0
- package/src/utils/color.ts +136 -0
- package/src/utils/html.ts +21 -0
- package/src/utils/math.ts +8 -0
- package/src/utils/string.ts +98 -0
- package/src/widgets/button.ts +107 -0
- package/src/widgets/color.ts +151 -0
- package/src/widgets/factory.ts +46 -0
- package/src/widgets/image.ts +163 -0
- package/src/widgets/number.ts +153 -0
- package/src/widgets/slider.ts +216 -0
- package/src/widgets/string.ts +128 -0
- package/src/widgets/text.ts +92 -0
- package/src/widgets/toggle.ts +205 -0
- package/src/widgets/widget.ts +12 -0
- package/tsconfig.json +15 -0
- package/tsup.config.ts +10 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { FontStyle, FontWeight, TextStyleConfig } from "../styles/text";
|
|
2
|
+
import { Theme } from "../theme";
|
|
3
|
+
import { Text } from "../types/text";
|
|
4
|
+
import { BasicMarkdownEntry, CodeBlockEntry, MarkdownEntry, UnorderedListMarkdownEntry } from "./entry";
|
|
5
|
+
import { MarkdownToken, MarkdownTokenType } from "./token";
|
|
6
|
+
|
|
7
|
+
export class MarkdownSyntaxParser {
|
|
8
|
+
|
|
9
|
+
#tokens: Array<MarkdownToken>;
|
|
10
|
+
|
|
11
|
+
#index: number;
|
|
12
|
+
|
|
13
|
+
#originalText: string;
|
|
14
|
+
|
|
15
|
+
constructor(originalText: string, tokens: Array<MarkdownToken>) {
|
|
16
|
+
this.#originalText = originalText;
|
|
17
|
+
this.#index = 0;
|
|
18
|
+
this.#tokens = tokens;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#current(): MarkdownToken | null {
|
|
22
|
+
if (this.#index > this.#tokens.length - 1) {
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
return this.#tokens[this.#index];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#inc(): void {
|
|
29
|
+
this.#index++
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
#next(): MarkdownToken | null {
|
|
33
|
+
this.#index++
|
|
34
|
+
if (this.#index >= this.#tokens.length - 1) {
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
37
|
+
return this.#tokens[this.#index];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#peak(): MarkdownToken | null {
|
|
41
|
+
if (this.#index + 1 >= this.#tokens.length - 1) {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
return this.#tokens[this.#index + 1];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#peakInto(amount: number): MarkdownToken | null {
|
|
48
|
+
if (this.#index + amount >= this.#tokens.length - 1) {
|
|
49
|
+
return null
|
|
50
|
+
}
|
|
51
|
+
return this.#tokens[this.#index + amount];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#emphasis(): Array<Text> {
|
|
55
|
+
|
|
56
|
+
// Cases to consider
|
|
57
|
+
// =================
|
|
58
|
+
// 1. *a*: <i>a</i>
|
|
59
|
+
// 2. **a**: <b>a</b>
|
|
60
|
+
// 3. **a*: *<i>a</i> <----- fuck this one
|
|
61
|
+
// 4. ***a**: *<b>a</b> <----- fuck this one
|
|
62
|
+
// 5. *a**: <i>a</i>*
|
|
63
|
+
// 6. **a***: <b>a</b>*
|
|
64
|
+
// 7. * a *: * a *
|
|
65
|
+
// 8. ** a **: ** a **
|
|
66
|
+
// 9. **a **: **a **
|
|
67
|
+
// 10. **a f**: <b>a f<b>
|
|
68
|
+
// 11. * Test: <ul>Test</ul>
|
|
69
|
+
|
|
70
|
+
let token = this.#next();
|
|
71
|
+
if (token?.type() === MarkdownTokenType.Space) {
|
|
72
|
+
return [new Text("*")];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let bold = false;
|
|
76
|
+
// Read off all leading stars
|
|
77
|
+
while (token !== null && token.type() === MarkdownTokenType.Star) {
|
|
78
|
+
bold = true;
|
|
79
|
+
token = this.#next();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let textContent = "";
|
|
83
|
+
|
|
84
|
+
let boldClosed = false;
|
|
85
|
+
let startingClose = false;
|
|
86
|
+
let validClose = false;
|
|
87
|
+
while (token !== null && token.type() !== MarkdownTokenType.NewLine) {
|
|
88
|
+
if (token.type() === MarkdownTokenType.Star) {
|
|
89
|
+
|
|
90
|
+
// This is the second star we've seen in a row. We're done!
|
|
91
|
+
if (startingClose) {
|
|
92
|
+
boldClosed = true;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// If we're not bold, we just need a single star to close this off.
|
|
97
|
+
startingClose = true;
|
|
98
|
+
if (bold === false) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (startingClose && token.type() !== MarkdownTokenType.Star) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Add to string content...
|
|
108
|
+
if (token.type() === MarkdownTokenType.Text) {
|
|
109
|
+
textContent += token.lexeme();
|
|
110
|
+
validClose = true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (token.type() === MarkdownTokenType.Space) {
|
|
114
|
+
textContent += token.lexeme();
|
|
115
|
+
validClose = false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
token = this.#next();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const style: TextStyleConfig = {}
|
|
122
|
+
|
|
123
|
+
if (validClose && startingClose) {
|
|
124
|
+
if (boldClosed) {
|
|
125
|
+
style.weight = FontWeight.Bold;
|
|
126
|
+
} else {
|
|
127
|
+
style.style = FontStyle.Italic;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return [new Text(textContent, style)]
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#text(): Array<Text> {
|
|
135
|
+
let contents: Array<Text> = new Array<Text>();
|
|
136
|
+
let textContent = "";
|
|
137
|
+
|
|
138
|
+
let token = this.#current();
|
|
139
|
+
|
|
140
|
+
// Read off all starting whitespace
|
|
141
|
+
while (token !== null && token.type() === MarkdownTokenType.Space) {
|
|
142
|
+
token = this.#next();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
while (token !== null && token.type() !== MarkdownTokenType.NewLine) {
|
|
146
|
+
switch (token.type()) {
|
|
147
|
+
case MarkdownTokenType.Text:
|
|
148
|
+
case MarkdownTokenType.H1:
|
|
149
|
+
case MarkdownTokenType.H2:
|
|
150
|
+
case MarkdownTokenType.H3:
|
|
151
|
+
case MarkdownTokenType.Space:
|
|
152
|
+
textContent += token.lexeme();
|
|
153
|
+
break;
|
|
154
|
+
|
|
155
|
+
case MarkdownTokenType.Star:
|
|
156
|
+
if (textContent !== "") {
|
|
157
|
+
contents.push(new Text(textContent))
|
|
158
|
+
textContent = "";
|
|
159
|
+
}
|
|
160
|
+
let starText = this.#emphasis()
|
|
161
|
+
for (let i = 0; i < starText.length; i++) {
|
|
162
|
+
contents.push(starText[i]);
|
|
163
|
+
}
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
token = this.#next();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (textContent !== "") {
|
|
171
|
+
contents.push(new Text(textContent))
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return contents;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
#h1(): BasicMarkdownEntry {
|
|
178
|
+
// Move off of the header token
|
|
179
|
+
this.#inc();
|
|
180
|
+
|
|
181
|
+
const text = this.#text();
|
|
182
|
+
for (let i = 0; i < text.length; i++) {
|
|
183
|
+
text[i].setColor(Theme.Note.FontColor);
|
|
184
|
+
text[i].setSize(Theme.Note.H1.FontSize);
|
|
185
|
+
text[i].setWeight(FontWeight.Bold);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return new BasicMarkdownEntry(text, true, false);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
#h2(): BasicMarkdownEntry {
|
|
192
|
+
// Move off of the header token
|
|
193
|
+
this.#inc();
|
|
194
|
+
|
|
195
|
+
const text = this.#text();
|
|
196
|
+
for (let i = 0; i < text.length; i++) {
|
|
197
|
+
text[i].setColor(Theme.Note.FontColor);
|
|
198
|
+
text[i].setSize(Theme.Note.H2.FontSize);
|
|
199
|
+
text[i].setWeight(FontWeight.Bold);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return new BasicMarkdownEntry(text, true, false);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
#h3(): BasicMarkdownEntry {
|
|
206
|
+
// Move off of the header token
|
|
207
|
+
this.#inc();
|
|
208
|
+
|
|
209
|
+
const text = this.#text();
|
|
210
|
+
for (let i = 0; i < text.length; i++) {
|
|
211
|
+
text[i].setColor(Theme.Note.FontColor);
|
|
212
|
+
text[i].setSize(Theme.Note.H3.FontSize);
|
|
213
|
+
text[i].setWeight(FontWeight.Bold);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return new BasicMarkdownEntry(text, false, false);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
#starLineStart(): MarkdownEntry {
|
|
220
|
+
if (this.#peak()?.type() !== MarkdownTokenType.Space) {
|
|
221
|
+
const starEntries = this.#text();
|
|
222
|
+
this.#assignStandardStyling(starEntries);
|
|
223
|
+
return new BasicMarkdownEntry(starEntries, false, false);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// We've begun with a space, which means unordered list!
|
|
227
|
+
|
|
228
|
+
const entries = new Array<BasicMarkdownEntry>();
|
|
229
|
+
|
|
230
|
+
while (this.#current()?.type() === MarkdownTokenType.Star && this.#peak()?.type() === MarkdownTokenType.Space) {
|
|
231
|
+
this.#inc();
|
|
232
|
+
const starEntries = this.#text();
|
|
233
|
+
this.#assignStandardStyling(starEntries);
|
|
234
|
+
entries.push(new BasicMarkdownEntry(starEntries, false, false));
|
|
235
|
+
|
|
236
|
+
// Text reads to the end of the line, which means we're at the new
|
|
237
|
+
// line character. Move forward 1.
|
|
238
|
+
this.#inc();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return new UnorderedListMarkdownEntry(entries);
|
|
242
|
+
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
#assignStandardStyling(textEntries: Array<Text>): void {
|
|
246
|
+
for (let i = 0; i < textEntries.length; i++) {
|
|
247
|
+
textEntries[i].setColor(Theme.Note.FontColor);
|
|
248
|
+
textEntries[i].setSize(Theme.Note.FontSize);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
#backtickLineStart(): MarkdownEntry {
|
|
253
|
+
|
|
254
|
+
// If we're not a ```, just treat as regular text
|
|
255
|
+
if (this.#peak()?.type() !== MarkdownTokenType.BackTick || this.#peakInto(2)?.type() !== MarkdownTokenType.BackTick) {
|
|
256
|
+
const starEntries = this.#text();
|
|
257
|
+
this.#assignStandardStyling(starEntries);
|
|
258
|
+
return new BasicMarkdownEntry(starEntries, false, false);
|
|
259
|
+
}
|
|
260
|
+
this.#inc();
|
|
261
|
+
this.#inc();
|
|
262
|
+
|
|
263
|
+
let token = this.#next();
|
|
264
|
+
|
|
265
|
+
// Eat the first new line character
|
|
266
|
+
if (token?.type() === MarkdownTokenType.NewLine) {
|
|
267
|
+
token = this.#next();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
let start = token?.tokenStart();
|
|
271
|
+
let end = start;
|
|
272
|
+
|
|
273
|
+
// Read until we hit another ```
|
|
274
|
+
while (token !== null) {
|
|
275
|
+
|
|
276
|
+
if (
|
|
277
|
+
token.type() === MarkdownTokenType.BackTick &&
|
|
278
|
+
this.#peak()?.type() === MarkdownTokenType.BackTick &&
|
|
279
|
+
this.#peakInto(2)?.type() === MarkdownTokenType.BackTick
|
|
280
|
+
) {
|
|
281
|
+
end = token.tokenEnd() - 1;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
token = this.#next();
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
this.#inc(); // puts us on the 2nd
|
|
289
|
+
this.#inc(); // puts us on the 3rd
|
|
290
|
+
this.#inc(); // puts us on the next token
|
|
291
|
+
|
|
292
|
+
const codeBlockText = this.#originalText.substring(start as number, end);
|
|
293
|
+
const entryText = new Text(codeBlockText);
|
|
294
|
+
this.#assignStandardStyling([entryText])
|
|
295
|
+
return new CodeBlockEntry(entryText)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
parse(): Array<MarkdownEntry> {
|
|
299
|
+
let token = this.#current();
|
|
300
|
+
|
|
301
|
+
const entries = new Array<MarkdownEntry>();
|
|
302
|
+
|
|
303
|
+
while (token !== null) {
|
|
304
|
+
switch (token.type()) {
|
|
305
|
+
case MarkdownTokenType.H1:
|
|
306
|
+
entries.push(this.#h1());
|
|
307
|
+
break;
|
|
308
|
+
|
|
309
|
+
case MarkdownTokenType.H2:
|
|
310
|
+
entries.push(this.#h2());
|
|
311
|
+
break;
|
|
312
|
+
|
|
313
|
+
case MarkdownTokenType.H3:
|
|
314
|
+
entries.push(this.#h3());
|
|
315
|
+
break;
|
|
316
|
+
|
|
317
|
+
case MarkdownTokenType.Text:
|
|
318
|
+
const textEntries = this.#text();
|
|
319
|
+
this.#assignStandardStyling(textEntries);
|
|
320
|
+
entries.push(new BasicMarkdownEntry(textEntries, false, false));
|
|
321
|
+
break;
|
|
322
|
+
|
|
323
|
+
case MarkdownTokenType.Star:
|
|
324
|
+
entries.push(this.#starLineStart());
|
|
325
|
+
break;
|
|
326
|
+
|
|
327
|
+
case MarkdownTokenType.NewLine:
|
|
328
|
+
this.#inc();
|
|
329
|
+
break;
|
|
330
|
+
|
|
331
|
+
case MarkdownTokenType.BackTick:
|
|
332
|
+
entries.push(this.#backtickLineStart());
|
|
333
|
+
break;
|
|
334
|
+
|
|
335
|
+
default:
|
|
336
|
+
this.#inc();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
token = this.#current();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return entries;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export enum MarkdownTokenType {
|
|
2
|
+
Text = "Text",
|
|
3
|
+
H1 = "H1",
|
|
4
|
+
H2 = "H2",
|
|
5
|
+
H3 = "H3",
|
|
6
|
+
NewLine = "New Line",
|
|
7
|
+
Star = "Star",
|
|
8
|
+
Space = "Space",
|
|
9
|
+
BackTick = "`"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class MarkdownToken {
|
|
13
|
+
|
|
14
|
+
#type: MarkdownTokenType;
|
|
15
|
+
|
|
16
|
+
#lexeme: string
|
|
17
|
+
|
|
18
|
+
#tokenStart: number
|
|
19
|
+
|
|
20
|
+
#tokenEnd: number
|
|
21
|
+
|
|
22
|
+
constructor(type: MarkdownTokenType, lexeme: string, tokenStart: number, tokenEnd: number) {
|
|
23
|
+
this.#type = type;
|
|
24
|
+
this.#lexeme = lexeme;
|
|
25
|
+
this.#tokenStart = tokenStart;
|
|
26
|
+
this.#tokenEnd = tokenEnd;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type(): MarkdownTokenType {
|
|
30
|
+
return this.#type;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
lexeme(): string {
|
|
34
|
+
return this.#lexeme;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
tokenStart(): number {
|
|
38
|
+
return this.#tokenStart;
|
|
39
|
+
}
|
|
40
|
+
tokenEnd(): number {
|
|
41
|
+
return this.#tokenEnd;
|
|
42
|
+
}
|
|
43
|
+
}
|
package/src/metadata.ts
ADDED