@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.
Files changed (68) hide show
  1. package/.github/workflows/deploy.yml +57 -0
  2. package/README.md +159 -0
  3. package/dev.tsconfig.json +18 -0
  4. package/docs/promotional-image.png +0 -0
  5. package/esbuild.ts +32 -0
  6. package/index.html +311 -0
  7. package/package.json +50 -0
  8. package/src/camera.ts +30 -0
  9. package/src/connection.ts +249 -0
  10. package/src/contextMenu.ts +367 -0
  11. package/src/draggable.ts +13 -0
  12. package/src/elements/base.ts +192 -0
  13. package/src/elements/container.ts +119 -0
  14. package/src/elements/interfaces.ts +50 -0
  15. package/src/elements/text.ts +86 -0
  16. package/src/graph.ts +535 -0
  17. package/src/graphSubsystem.ts +31 -0
  18. package/src/index.ts +28 -0
  19. package/src/input.ts +153 -0
  20. package/src/markdown/entry.ts +323 -0
  21. package/src/markdown/lexicalParser.ts +148 -0
  22. package/src/markdown/markdown.ts +14 -0
  23. package/src/markdown/syntaxParser.ts +344 -0
  24. package/src/markdown/token.ts +43 -0
  25. package/src/metadata.ts +3 -0
  26. package/src/node.ts +1130 -0
  27. package/src/nodes/factory.ts +87 -0
  28. package/src/nodes/publisher.ts +98 -0
  29. package/src/nodes/subsystem.ts +760 -0
  30. package/src/notes/note.ts +295 -0
  31. package/src/notes/subsystem.ts +262 -0
  32. package/src/organize.ts +181 -0
  33. package/src/pass/subsystem.ts +64 -0
  34. package/src/performance.ts +9 -0
  35. package/src/popup.ts +81 -0
  36. package/src/popups/form.ts +63 -0
  37. package/src/popups/string.ts +33 -0
  38. package/src/port.ts +223 -0
  39. package/src/quickMenu.ts +330 -0
  40. package/src/styles/box.ts +104 -0
  41. package/src/styles/canvasTextAlign.ts +8 -0
  42. package/src/styles/canvasTextBaseline.ts +9 -0
  43. package/src/styles/cursor.ts +18 -0
  44. package/src/styles/stroke.ts +39 -0
  45. package/src/styles/text.ts +90 -0
  46. package/src/styles/textBox.ts +82 -0
  47. package/src/theme.ts +78 -0
  48. package/src/types/box.ts +126 -0
  49. package/src/types/list.ts +41 -0
  50. package/src/types/pool.ts +66 -0
  51. package/src/types/text.ts +136 -0
  52. package/src/types/vector2.ts +34 -0
  53. package/src/utils/color.ts +136 -0
  54. package/src/utils/html.ts +21 -0
  55. package/src/utils/math.ts +8 -0
  56. package/src/utils/string.ts +98 -0
  57. package/src/widgets/button.ts +107 -0
  58. package/src/widgets/color.ts +151 -0
  59. package/src/widgets/factory.ts +46 -0
  60. package/src/widgets/image.ts +163 -0
  61. package/src/widgets/number.ts +153 -0
  62. package/src/widgets/slider.ts +216 -0
  63. package/src/widgets/string.ts +128 -0
  64. package/src/widgets/text.ts +92 -0
  65. package/src/widgets/toggle.ts +205 -0
  66. package/src/widgets/widget.ts +12 -0
  67. package/tsconfig.json +15 -0
  68. package/tsup.config.ts +10 -0
package/src/input.ts ADDED
@@ -0,0 +1,153 @@
1
+ import { CopyVector2, SubVector2, Vector2, Zero } from "./types/vector2";
2
+
3
+ export class MouseObserver {
4
+
5
+ #clicked: boolean;
6
+
7
+ #lastTouch: Vector2;
8
+
9
+ #ele: HTMLElement
10
+
11
+ #lastMousePosition: Vector2;
12
+
13
+ #dragCallback: (delta: Vector2) => void
14
+ #moveCallback: (position: Vector2) => void
15
+ #clickStart: (position: Vector2, shiftOrCtrl: boolean) => void
16
+ #clickStop: () => void
17
+ #contextMenu: (position: Vector2) => void
18
+
19
+ constructor(
20
+ ele: HTMLElement,
21
+ dragCallback: (delta: Vector2) => void,
22
+ moveCallback: (position: Vector2) => void,
23
+ clickStart: (position: Vector2, shiftOrCtrl: boolean) => void,
24
+ clickStop: () => void,
25
+ contextMenu: (position: Vector2) => void,
26
+ fileDrop: (file: File) => void
27
+ ) {
28
+ this.#ele = ele;
29
+ this.#dragCallback = dragCallback;
30
+ this.#moveCallback = moveCallback;
31
+ this.#clickStart = clickStart;
32
+ this.#clickStop = clickStop;
33
+ this.#contextMenu = contextMenu;
34
+
35
+ this.#clicked = false;
36
+ this.#lastTouch = Zero();
37
+ this.#lastMousePosition = Zero();
38
+
39
+ // Down
40
+ ele.addEventListener('mousedown', this.#down.bind(this), false);
41
+ ele.addEventListener('touchstart', this.#touchDown.bind(this), false);
42
+
43
+ // Up
44
+ document.addEventListener('mouseup', this.#up.bind(this), false);
45
+ document.addEventListener('touchend', this.#up.bind(this), false);
46
+
47
+ // Move
48
+ ele.addEventListener('mousemove', this.#move.bind(this), false);
49
+ ele.addEventListener('touchmove', this.#moveTouch.bind(this), false);
50
+
51
+ ele.addEventListener('drop', (ev) => {
52
+ ev.preventDefault();
53
+ console.log(ev)
54
+
55
+ if (ev.dataTransfer?.items) {
56
+ // Use DataTransferItemList interface to access the file(s)
57
+ [...ev.dataTransfer.items].forEach((item, i) => {
58
+ // If dropped items aren't files, reject them
59
+ if (item.kind === "file") {
60
+ const file = item.getAsFile();
61
+ if (file) {
62
+ fileDrop(file);
63
+ console.log(file)
64
+ console.log(`… file[${i}].name = ${file.name}`);
65
+ }
66
+ }
67
+ });
68
+ } else if (ev.dataTransfer) {
69
+ // Use DataTransfer interface to access the file(s)
70
+ [...ev.dataTransfer.files].forEach((file, i) => {
71
+ console.log(`… file[${i}].name = ${file.name}`);
72
+ });
73
+ }
74
+ });
75
+
76
+ ele.addEventListener('dragover', (ev) => {
77
+ ev.preventDefault();
78
+ this.#moveCallback(this.#mousePosition(ev));
79
+ // console.log(ev)
80
+ });
81
+
82
+ // Context
83
+ ele.addEventListener('contextmenu', (evt) => {
84
+ contextMenu(this.#mousePosition(evt));
85
+ evt.preventDefault()
86
+ }, false);
87
+ }
88
+
89
+ #mousePosition(event: MouseEvent | DragEvent): Vector2 {
90
+ var rect = this.#ele.getBoundingClientRect();
91
+ return {
92
+ x: event.clientX - rect.left,
93
+ y: event.clientY - rect.top
94
+ }
95
+ }
96
+
97
+ #move(event: MouseEvent): void {
98
+ const pos = this.#mousePosition(event);
99
+
100
+ if (this.#clicked) {
101
+ const delta = Zero();
102
+ SubVector2(delta, pos, this.#lastMousePosition);
103
+ this.#dragCallback(delta)
104
+ }
105
+
106
+ this.#moveCallback(pos);
107
+ CopyVector2(this.#lastMousePosition, pos);
108
+ }
109
+
110
+ #moveTouch(event: TouchEvent): void {
111
+ const rect = this.#ele.getBoundingClientRect();
112
+ const pos = {
113
+ x: event.touches[0].clientX - rect.left,
114
+ y: event.touches[0].clientY - rect.top
115
+ }
116
+ this.#moveCallback(pos);
117
+
118
+ if (this.#clicked) {
119
+ this.#dragCallback({
120
+ x: pos.x - this.#lastTouch.x,
121
+ y: pos.y - this.#lastTouch.y,
122
+ });
123
+ }
124
+
125
+ CopyVector2(this.#lastTouch, pos);
126
+ }
127
+
128
+ #down(event: MouseEvent): void {
129
+ // Only register left clicks
130
+ if (event.button !== 0) {
131
+ return;
132
+ }
133
+ this.#clicked = true;
134
+ this.#clickStart(this.#mousePosition(event), event.ctrlKey || event.shiftKey);
135
+ }
136
+
137
+ #touchDown(event: TouchEvent) {
138
+ this.#clicked = true;
139
+ const rect = this.#ele.getBoundingClientRect();
140
+ this.#lastTouch.x = event.touches[0].clientX - rect.left;
141
+ this.#lastTouch.y = event.touches[0].clientY - rect.top;
142
+ this.#clickStart(this.#lastTouch, false);
143
+ }
144
+
145
+ #up(event: MouseEvent): void {
146
+ // Only register left clicks
147
+ if (event.button !== 0) {
148
+ return;
149
+ }
150
+ this.#clicked = false
151
+ this.#clickStop();
152
+ }
153
+ }
@@ -0,0 +1,323 @@
1
+ import { Theme } from "../theme";
2
+ import { List } from "../types/list";
3
+ import { Text } from "../types/text";
4
+ import { CopyVector2, Vector2, Zero } from "../types/vector2";
5
+
6
+ export interface MarkdownEntry {
7
+ render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number
8
+ }
9
+
10
+ export class CodeBlockEntry {
11
+
12
+ #text: Text
13
+
14
+ #calculatedPositions: List<Vector2>
15
+
16
+ #calculatedEntries: List<Text>
17
+
18
+ #calculatedForWidth: number;
19
+
20
+ constructor(text: Text) {
21
+ this.#text = text;
22
+ this.#calculatedForWidth = -1
23
+
24
+ this.#calculatedEntries = new List<Text>();
25
+ this.#calculatedPositions = new List<Vector2>();
26
+
27
+ document.fonts.addEventListener("loadingdone", (event) => {
28
+ this.#calculatedForWidth = -1
29
+ });
30
+ }
31
+
32
+ #calculateLayout(ctx: CanvasRenderingContext2D, maxWidth: number): void {
33
+ if (this.#calculatedForWidth === maxWidth) {
34
+ return;
35
+ }
36
+
37
+ let adjustedWith = maxWidth;
38
+ adjustedWith -= Theme.Note.CodeBlock.Padding * 2;
39
+
40
+ this.#calculatedEntries.Clear();
41
+ this.#calculatedPositions.Clear();
42
+
43
+ let curHeight = 0;
44
+ const lineInc = this.#text.style().getSize() + Theme.Note.LineSpacing;
45
+
46
+ let entries = this.#text.split("\n")
47
+
48
+ for (let entryIndex = 0; entryIndex < entries.length; entryIndex++) {
49
+ const entry = entries[entryIndex];
50
+
51
+ let lines = entry.breakIntoLines(ctx, adjustedWith);
52
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
53
+
54
+ this.#calculatedEntries.Push(lines[lineIndex])
55
+ this.#calculatedPositions.Push({
56
+ x: 0,
57
+ y: curHeight,
58
+ })
59
+
60
+ curHeight += lineInc;
61
+ }
62
+ }
63
+
64
+ this.#calculatedForWidth = maxWidth;
65
+ }
66
+
67
+ render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number {
68
+ this.#calculateLayout(ctx, maxWidth);
69
+
70
+ let padding = Theme.Note.CodeBlock.Padding * scale;
71
+
72
+ let max = 0;
73
+ for (let i = 0; i < this.#calculatedEntries.Count(); i++) {
74
+ const pos = this.#calculatedPositions.At(i);
75
+ max = Math.max(max, pos.y * scale)
76
+ }
77
+
78
+ const y = position.y + max + (scale * 5)
79
+ ctx.fillStyle = Theme.Note.CodeBlock.BackgroundColor;
80
+ ctx.beginPath();
81
+ ctx.roundRect(
82
+ position.x,
83
+ position.y,
84
+ maxWidth * scale,
85
+ max + (padding * 2),
86
+ Theme.Note.CodeBlock.BorderRadius * scale
87
+ );
88
+ ctx.fill();
89
+
90
+
91
+ for (let i = 0; i < this.#calculatedEntries.Count(); i++) {
92
+ const entry = this.#calculatedEntries.At(i);
93
+ const pos = this.#calculatedPositions.At(i);
94
+
95
+ entry.render(ctx, scale, {
96
+ x: (pos.x * scale) + position.x + padding,
97
+ y: (pos.y * scale) + position.y + padding
98
+ });
99
+
100
+ max = Math.max(max, pos.y * scale)
101
+ }
102
+
103
+
104
+ return max + (padding * 2);
105
+ }
106
+ }
107
+
108
+ export class UnorderedListMarkdownEntry {
109
+
110
+ #entries: Array<BasicMarkdownEntry>;
111
+
112
+ constructor(entries: Array<BasicMarkdownEntry>) {
113
+ this.#entries = entries;
114
+ }
115
+
116
+ render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number {
117
+ let offset = 0;
118
+ let shift = 20;
119
+
120
+ let pos = {
121
+ x: position.x + (shift * scale),
122
+ y: position.y
123
+ }
124
+
125
+ let dot = Theme.Note.DotSize * scale;
126
+
127
+ for (let i = 0; i < this.#entries.length; i++) {
128
+
129
+ ctx.beginPath();
130
+ ctx.arc(position.x + dot, pos.y + (dot * 3), dot, 0, 2 * Math.PI);
131
+ ctx.fill();
132
+
133
+ offset += this.#entries[i].render(ctx, pos, scale, maxWidth - shift) + (scale * Theme.Note.LineSpacing * 2);
134
+ pos.y = position.y + offset;
135
+ }
136
+
137
+ return offset;
138
+ }
139
+ }
140
+
141
+ export class BasicMarkdownEntry {
142
+
143
+ #underline: boolean;
144
+
145
+ #background: boolean;
146
+
147
+ #entries: Array<Text>
148
+
149
+ #calculatedPositions: List<Vector2>
150
+
151
+ #calculatedEntries: List<Text>
152
+
153
+ #calculatedForWidth: number;
154
+
155
+ constructor(lines: Array<Text>, underline: boolean, background: boolean) {
156
+ this.#entries = lines;
157
+ this.#underline = underline;
158
+ this.#background = background;
159
+ this.#calculatedForWidth = -1
160
+
161
+ this.#calculatedEntries = new List<Text>();
162
+ this.#calculatedPositions = new List<Vector2>();
163
+
164
+ document.fonts.addEventListener("loadingdone", (event) => {
165
+ this.#calculatedForWidth = -1
166
+ });
167
+ }
168
+
169
+ #calculateLayout(ctx: CanvasRenderingContext2D, maxWidth: number): void {
170
+ if (this.#calculatedForWidth === maxWidth) {
171
+ return;
172
+ }
173
+
174
+ let adjustedWith = maxWidth;
175
+ if (this.#background) {
176
+ adjustedWith -= Theme.Note.CodeBlock.Padding * 2;
177
+ }
178
+
179
+ this.#calculatedEntries.Clear();
180
+ this.#calculatedPositions.Clear();
181
+
182
+ const curPosition: Vector2 = Zero();
183
+ const texSize: Vector2 = Zero();
184
+
185
+ let currentLineHeight = 0;
186
+ const currentLineText = new List<Text>();
187
+ const currentLineWidths = new List<number>();
188
+
189
+ for (let entryIndex = 0; entryIndex < this.#entries.length; entryIndex++) {
190
+ const entry = this.#entries[entryIndex];
191
+
192
+ let lines = entry.splitAtWidth(ctx, adjustedWith - curPosition.x);
193
+ let i = 0;
194
+ while (lines.length > 1 && i < 100) {
195
+ i++
196
+
197
+ // We can't collapse this thing any further. Break out of the
198
+ // while loop before we have infinite loop on our hands
199
+ // if (lines[0].get() === "" && lines[1].get().length === 1) {
200
+ // lines[0] = lines[1];
201
+ // break;
202
+ // }
203
+
204
+ // We can't collapse this thing any further. Break out of the
205
+ // while loop before we have infinite loop on our hands
206
+ if (lines[0].get() === "" && currentLineText.Count() === 0) {
207
+
208
+ if (lines[1].get().length === 1) {
209
+ lines[0] = lines[1];
210
+ break;
211
+ } else {
212
+ lines = lines[1].splitAtIndex(1);
213
+ }
214
+
215
+ }
216
+
217
+ // This effectiviely finishes off the line we're currenly working on.
218
+ if (lines[0].get() !== "") {
219
+ lines[0].size(ctx, 1, texSize);
220
+ currentLineHeight = Math.max(currentLineHeight, texSize.y);
221
+
222
+ currentLineText.Push(lines[0]);
223
+ currentLineWidths.Push(curPosition.x);
224
+ }
225
+
226
+ curPosition.y += currentLineHeight;
227
+
228
+ // Take everything we're working with and finalize it
229
+ for (let i = 0; i < currentLineText.Count(); i++) {
230
+ this.#calculatedEntries.Push(currentLineText.At(i));
231
+ this.#calculatedPositions.Push({ x: currentLineWidths.At(i), y: curPosition.y })
232
+ }
233
+
234
+ currentLineText.Clear();
235
+ currentLineWidths.Clear();
236
+
237
+ curPosition.y += Theme.Note.LineSpacing;
238
+ currentLineHeight = 0;
239
+ curPosition.x = 0;
240
+
241
+ lines = lines[1].splitAtWidth(ctx, adjustedWith);
242
+ }
243
+ if (i === 100) {
244
+ console.log(lines)
245
+ }
246
+
247
+ lines[0].size(ctx, 1, texSize);
248
+ currentLineHeight = Math.max(currentLineHeight, texSize.y)
249
+
250
+ currentLineText.Push(lines[0]);
251
+ currentLineWidths.Push(curPosition.x);
252
+
253
+ curPosition.x += texSize.x;
254
+ }
255
+
256
+ curPosition.y += currentLineHeight;
257
+
258
+ // Take everything we're working with and finalize it
259
+ for (let i = 0; i < currentLineText.Count(); i++) {
260
+ this.#calculatedEntries.Push(currentLineText.At(i));
261
+ this.#calculatedPositions.Push({ x: currentLineWidths.At(i), y: curPosition.y })
262
+ }
263
+
264
+ this.#calculatedForWidth = maxWidth;
265
+ }
266
+
267
+ render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number {
268
+ this.#calculateLayout(ctx, maxWidth);
269
+
270
+ let padding = 0;
271
+ if (this.#background) {
272
+ padding += Theme.Note.CodeBlock.Padding * scale;
273
+ }
274
+
275
+
276
+ if (this.#background) {
277
+ let max = 0;
278
+ for (let i = 0; i < this.#calculatedEntries.Count(); i++) {
279
+ const pos = this.#calculatedPositions.At(i);
280
+ max = Math.max(max, pos.y * scale)
281
+ }
282
+
283
+ const y = position.y + max + (scale * 5)
284
+ ctx.fillStyle = Theme.Note.CodeBlock.BackgroundColor;
285
+ ctx.beginPath();
286
+ ctx.roundRect(
287
+ position.x,
288
+ position.y,
289
+ maxWidth * scale,
290
+ max + (padding * 2),
291
+ Theme.Note.CodeBlock.BorderRadius * scale
292
+ );
293
+ ctx.fill();
294
+ }
295
+
296
+
297
+ let max = 0;
298
+ for (let i = 0; i < this.#calculatedEntries.Count(); i++) {
299
+ const entry = this.#calculatedEntries.At(i);
300
+ const pos = this.#calculatedPositions.At(i);
301
+
302
+ entry.render(ctx, scale, {
303
+ x: (pos.x * scale) + position.x + padding,
304
+ y: (pos.y * scale) + position.y + padding
305
+ });
306
+
307
+ max = Math.max(max, pos.y * scale)
308
+ }
309
+
310
+ // Add underline
311
+ if (this.#underline) {
312
+ const y = position.y + max + (scale * 5)
313
+ ctx.strokeStyle = Theme.Note.FontColor;
314
+ ctx.lineWidth = Theme.Note.HeaderLineWidth * scale;
315
+ ctx.beginPath();
316
+ ctx.moveTo(position.x, y);
317
+ ctx.lineTo(position.x + (maxWidth * scale), y);
318
+ ctx.stroke();
319
+ }
320
+
321
+ return max + (padding * 2);
322
+ }
323
+ }
@@ -0,0 +1,148 @@
1
+ import { MarkdownToken, MarkdownTokenType } from "./token";
2
+
3
+ export class MarkdownLexicalParser {
4
+
5
+ #body: string;
6
+
7
+ #index: number
8
+
9
+ #tokens: Array<MarkdownToken>;
10
+
11
+ constructor(body: string) {
12
+ this.#index = 0;
13
+ this.#body = body;
14
+ this.#tokens = new Array<MarkdownToken>();
15
+ }
16
+
17
+ tokens(): Array<MarkdownToken> {
18
+ return this.#tokens;
19
+ }
20
+
21
+ #current(): string {
22
+ if (this.#index > this.#body.length - 1) {
23
+ return ""
24
+ }
25
+ return this.#body.charAt(this.#index);
26
+ }
27
+
28
+ #inc(): void {
29
+ this.#index++
30
+ }
31
+
32
+ #next(): string {
33
+ this.#index++
34
+ if (this.#index > this.#body.length - 1) {
35
+ return ""
36
+ }
37
+ return this.#body.charAt(this.#index);
38
+ }
39
+
40
+ #lastToken = 0;
41
+
42
+ #addToken(token: MarkdownTokenType, lexeme: string): void {
43
+ this.#tokens.push(new MarkdownToken(token, lexeme, this.#lastToken, this.#index));
44
+ this.#lastToken = this.#index;
45
+ }
46
+
47
+ #h2(): void {
48
+ let char = this.#next();
49
+ if (char === "#") {
50
+ this.#addToken(MarkdownTokenType.H3, "###");
51
+
52
+ // Move it off the character for the next reading
53
+ this.#inc();
54
+ } else {
55
+ this.#addToken(MarkdownTokenType.H2, "##");
56
+ }
57
+ }
58
+
59
+ #h1(): void {
60
+ let char = this.#next();
61
+ if (char === "#") {
62
+ this.#h2();
63
+ } else {
64
+ this.#addToken(MarkdownTokenType.H1, "#");
65
+ }
66
+ }
67
+
68
+ #whiteSpace(): void {
69
+ let char = this.#current();
70
+
71
+ while (char !== "") {
72
+ if (char !== " " && char !== "\t") {
73
+ break;
74
+ }
75
+ char = this.#next();
76
+ }
77
+
78
+ this.#addToken(MarkdownTokenType.Space, " ")
79
+ }
80
+
81
+ #text(): void {
82
+ let char = this.#current();
83
+
84
+ let started = -1;
85
+
86
+ while (char !== "") {
87
+ if (char === " " || char === "\t") {
88
+
89
+ // Eat white space if we haven't seen anything yet!
90
+ if (started === -1) {
91
+ this.#inc();
92
+ continue;
93
+ }
94
+ }
95
+
96
+ // End of the line!
97
+ if (char === "\n" || char === "*" || char === "`") {
98
+ if (started != -1) {
99
+ this.#addToken(MarkdownTokenType.Text, this.#body.substring(started, this.#index))
100
+ }
101
+ return;
102
+ }
103
+
104
+
105
+ if (started === -1) {
106
+ started = this.#index;
107
+ }
108
+
109
+ char = this.#next();
110
+ }
111
+
112
+ if (started != -1) {
113
+ this.#addToken(MarkdownTokenType.Text, this.#body.substring(started, this.#index))
114
+ }
115
+ }
116
+
117
+ // S( ) => S
118
+ // S(\t) => S
119
+ // S(#) => H1
120
+ // H1(#) => H2
121
+ // H1(!#) => S
122
+ // H2(#) => H3
123
+ // H2(#) => H3
124
+ parse(): void {
125
+ let char = this.#current();
126
+
127
+ while (char !== "") {
128
+ if (char === " " || char === "\t") {
129
+ this.#whiteSpace();
130
+ } else if (char === "#") {
131
+ this.#h1();
132
+ } else if (char === "\n") {
133
+ this.#addToken(MarkdownTokenType.NewLine, "\n");
134
+ this.#inc();
135
+ } else if (char === "*") {
136
+ this.#addToken(MarkdownTokenType.Star, "*");
137
+ this.#inc();
138
+ } else if (char === "`") {
139
+ this.#addToken(MarkdownTokenType.BackTick, "`");
140
+ this.#inc();
141
+ } else {
142
+ this.#text();
143
+ }
144
+
145
+ char = this.#current();
146
+ }
147
+ }
148
+ }
@@ -0,0 +1,14 @@
1
+ import { MarkdownEntry } from "./entry";
2
+ import { MarkdownLexicalParser } from "./lexicalParser";
3
+ import { MarkdownSyntaxParser } from "./syntaxParser";
4
+
5
+ export function BuildMarkdown(data: string): Array<MarkdownEntry> {
6
+ const lexicalParser = new MarkdownLexicalParser(data);
7
+ lexicalParser.parse();
8
+ // console.log(lexicalParser.tokens());
9
+
10
+ const syntaxParser = new MarkdownSyntaxParser(data, lexicalParser.tokens());
11
+ const contents = syntaxParser.parse()
12
+ // console.log(contents);
13
+ return contents;
14
+ }