wyreframe 0.2.2 → 0.4.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,2 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+ /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
@@ -0,0 +1,34 @@
1
+ // FixTypes.res
2
+ // Type definitions for the auto-fix functionality
3
+
4
+ /**
5
+ * Describes a single fix that was applied to the source text
6
+ */
7
+ type fixedIssue = {
8
+ original: ErrorTypes.t,
9
+ description: string,
10
+ line: int,
11
+ column: int,
12
+ }
13
+
14
+ /**
15
+ * Result of a successful fix operation
16
+ */
17
+ type fixSuccess = {
18
+ text: string,
19
+ fixed: array<fixedIssue>,
20
+ remaining: array<ErrorTypes.t>,
21
+ }
22
+
23
+ /**
24
+ * Result type for fix operations
25
+ */
26
+ type fixResult = result<fixSuccess, array<ErrorTypes.t>>
27
+
28
+ /**
29
+ * Strategy for fixing a specific error type
30
+ */
31
+ type fixStrategy = {
32
+ canFix: ErrorTypes.errorCode => bool,
33
+ apply: (string, ErrorTypes.t) => option<(string, fixedIssue)>,
34
+ }
@@ -0,0 +1,24 @@
1
+ /* TypeScript file generated from Fixer.res by genType. */
2
+
3
+ /* eslint-disable */
4
+ /* tslint:disable */
5
+
6
+ import * as FixerJS from './Fixer.mjs';
7
+
8
+ import type {fixResult as FixTypes_fixResult} from './FixTypes.gen';
9
+
10
+ /** * Main fix function - attempts to fix all errors in the text
11
+ *
12
+ * This function:
13
+ * 1. Parses the text to get errors/warnings
14
+ * 2. Attempts to fix each fixable error
15
+ * 3. Re-parses after each fix to get updated positions
16
+ * 4. Returns the fixed text and list of applied fixes
17
+ *
18
+ * @param text The wireframe markdown text
19
+ * @returns FixResult with fixed text and details */
20
+ export const fix: (text:string) => FixTypes_fixResult = FixerJS.fix as any;
21
+
22
+ /** * Convenience function - fix and return just the fixed text
23
+ * Returns the original text if nothing was fixed */
24
+ export const fixOnly: (text:string) => string = FixerJS.fixOnly as any;
@@ -0,0 +1,447 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Parser from "../Parser.mjs";
4
+ import * as Core__Array from "@rescript/core/src/Core__Array.mjs";
5
+
6
+ function splitLines(text) {
7
+ return text.split("\n");
8
+ }
9
+
10
+ function joinLines(lines) {
11
+ return lines.join("\n");
12
+ }
13
+
14
+ function getLine(lines, row) {
15
+ return lines[row];
16
+ }
17
+
18
+ function replaceLine(lines, row, newLine) {
19
+ return lines.map((line, idx) => {
20
+ if (idx === row) {
21
+ return newLine;
22
+ } else {
23
+ return line;
24
+ }
25
+ });
26
+ }
27
+
28
+ function insertAt(str, col, chars) {
29
+ let before = str.slice(0, col);
30
+ let after = str.slice(col);
31
+ return before + chars + after;
32
+ }
33
+
34
+ function removeAt(str, col, count) {
35
+ let before = str.slice(0, col);
36
+ let after = str.slice(col + count | 0);
37
+ return before + after;
38
+ }
39
+
40
+ function replaceCharAt(str, col, char) {
41
+ let before = str.slice(0, col);
42
+ let after = str.slice(col + 1 | 0);
43
+ return before + char + after;
44
+ }
45
+
46
+ function fixMisalignedPipe(text, error) {
47
+ let match = error.code;
48
+ if (match.TAG !== "MisalignedPipe") {
49
+ return;
50
+ }
51
+ let actualCol = match.actualCol;
52
+ let expectedCol = match.expectedCol;
53
+ let position = match.position;
54
+ let lines = text.split("\n");
55
+ let line = lines[position.row];
56
+ if (line === undefined) {
57
+ return;
58
+ }
59
+ let diff = expectedCol - actualCol | 0;
60
+ let newLine;
61
+ if (diff > 0) {
62
+ newLine = insertAt(line, actualCol, " ".repeat(diff));
63
+ } else {
64
+ let removeCount = Math.abs(diff);
65
+ let beforePipe = line.slice(actualCol + diff | 0, actualCol);
66
+ newLine = beforePipe.trim() === "" ? removeAt(line, actualCol + diff | 0, removeCount) : line;
67
+ }
68
+ if (newLine === line) {
69
+ return;
70
+ }
71
+ let newLines = replaceLine(lines, position.row, newLine);
72
+ let fixedText = newLines.join("\n");
73
+ return [
74
+ fixedText,
75
+ {
76
+ original: error,
77
+ description: `Aligned pipe at line ` + (position.row + 1 | 0).toString() + ` to column ` + (expectedCol + 1 | 0).toString(),
78
+ line: position.row + 1 | 0,
79
+ column: expectedCol + 1 | 0
80
+ }
81
+ ];
82
+ }
83
+
84
+ function fixMisalignedClosingBorder(text, error) {
85
+ let match = error.code;
86
+ if (match.TAG !== "MisalignedClosingBorder") {
87
+ return;
88
+ }
89
+ let actualCol = match.actualCol;
90
+ let expectedCol = match.expectedCol;
91
+ let position = match.position;
92
+ let lines = text.split("\n");
93
+ let line = lines[position.row];
94
+ if (line === undefined) {
95
+ return;
96
+ }
97
+ let diff = expectedCol - actualCol | 0;
98
+ let newLine;
99
+ if (diff > 0) {
100
+ newLine = insertAt(line, actualCol, " ".repeat(diff));
101
+ } else {
102
+ let removeCount = Math.abs(diff);
103
+ let beforePipe = line.slice(actualCol + diff | 0, actualCol);
104
+ newLine = beforePipe.trim() === "" ? removeAt(line, actualCol + diff | 0, removeCount) : line;
105
+ }
106
+ if (newLine === line) {
107
+ return;
108
+ }
109
+ let newLines = replaceLine(lines, position.row, newLine);
110
+ let fixedText = newLines.join("\n");
111
+ return [
112
+ fixedText,
113
+ {
114
+ original: error,
115
+ description: `Aligned closing border at line ` + (position.row + 1 | 0).toString() + ` to column ` + (expectedCol + 1 | 0).toString(),
116
+ line: position.row + 1 | 0,
117
+ column: expectedCol + 1 | 0
118
+ }
119
+ ];
120
+ }
121
+
122
+ function fixUnusualSpacing(text, error) {
123
+ let match = error.code;
124
+ if (match.TAG !== "UnusualSpacing") {
125
+ return;
126
+ }
127
+ let issue = match.issue;
128
+ if (!(issue.includes("tab") || issue.includes("Tab"))) {
129
+ return;
130
+ }
131
+ let position = match.position;
132
+ let lines = text.split("\n");
133
+ let line = lines[position.row];
134
+ if (line === undefined) {
135
+ return;
136
+ }
137
+ let newLine = line.replaceAll("\t", " ");
138
+ if (newLine === line) {
139
+ return;
140
+ }
141
+ let newLines = replaceLine(lines, position.row, newLine);
142
+ let fixedText = newLines.join("\n");
143
+ return [
144
+ fixedText,
145
+ {
146
+ original: error,
147
+ description: `Replaced tabs with spaces at line ` + (position.row + 1 | 0).toString(),
148
+ line: position.row + 1 | 0,
149
+ column: position.col + 1 | 0
150
+ }
151
+ ];
152
+ }
153
+
154
+ function fixUnclosedBracket(text, error) {
155
+ let match = error.code;
156
+ if (match.TAG !== "UnclosedBracket") {
157
+ return;
158
+ }
159
+ let opening = match.opening;
160
+ let lines = text.split("\n");
161
+ let line = lines[opening.row];
162
+ if (line === undefined) {
163
+ return;
164
+ }
165
+ let trimmedLine = line.trimEnd();
166
+ if (trimmedLine.endsWith("]")) {
167
+ return;
168
+ }
169
+ let newLine = trimmedLine + " ]";
170
+ let newLines = replaceLine(lines, opening.row, newLine);
171
+ let fixedText = newLines.join("\n");
172
+ return [
173
+ fixedText,
174
+ {
175
+ original: error,
176
+ description: `Added closing bracket at line ` + (opening.row + 1 | 0).toString(),
177
+ line: opening.row + 1 | 0,
178
+ column: trimmedLine.length + 2 | 0
179
+ }
180
+ ];
181
+ }
182
+
183
+ function fixMismatchedWidth(text, error) {
184
+ let match = error.code;
185
+ if (match.TAG !== "MismatchedWidth") {
186
+ return;
187
+ }
188
+ let bottomWidth = match.bottomWidth;
189
+ let topWidth = match.topWidth;
190
+ let topLeft = match.topLeft;
191
+ let lines = text.split("\n");
192
+ let diff = topWidth - bottomWidth | 0;
193
+ if (diff === 0) {
194
+ return;
195
+ }
196
+ let findBottomRow = _row => {
197
+ while (true) {
198
+ let row = _row;
199
+ if (row >= lines.length) {
200
+ return;
201
+ }
202
+ let line = lines[row];
203
+ if (line === undefined) {
204
+ return;
205
+ }
206
+ let col = topLeft.col;
207
+ if (col < line.length) {
208
+ let char = line.charAt(col);
209
+ if (char === "+" && row > topLeft.row) {
210
+ return row;
211
+ }
212
+ _row = row + 1 | 0;
213
+ continue;
214
+ }
215
+ _row = row + 1 | 0;
216
+ continue;
217
+ };
218
+ };
219
+ let bottomRow = findBottomRow(topLeft.row + 1 | 0);
220
+ if (bottomRow === undefined) {
221
+ return;
222
+ }
223
+ let bottomLine = lines[bottomRow];
224
+ if (bottomLine === undefined) {
225
+ return;
226
+ }
227
+ if (diff > 0) {
228
+ let closingPlusCol = (topLeft.col + bottomWidth | 0) - 1 | 0;
229
+ if (!(closingPlusCol >= 0 && closingPlusCol < bottomLine.length)) {
230
+ return;
231
+ }
232
+ let before = bottomLine.slice(0, closingPlusCol);
233
+ let after = bottomLine.slice(closingPlusCol);
234
+ let dashes = "-".repeat(diff);
235
+ let newLine = before + dashes + after;
236
+ let newLines = replaceLine(lines, bottomRow, newLine);
237
+ let fixedText = newLines.join("\n");
238
+ return [
239
+ fixedText,
240
+ {
241
+ original: error,
242
+ description: `Extended bottom border at line ` + (bottomRow + 1 | 0).toString() + ` by ` + diff.toString() + ` characters`,
243
+ line: bottomRow + 1 | 0,
244
+ column: closingPlusCol + 1 | 0
245
+ }
246
+ ];
247
+ }
248
+ let topLine = lines[topLeft.row];
249
+ if (topLine === undefined) {
250
+ return;
251
+ }
252
+ let closingPlusCol$1 = (topLeft.col + topWidth | 0) - 1 | 0;
253
+ if (!(closingPlusCol$1 >= 0 && closingPlusCol$1 < topLine.length)) {
254
+ return;
255
+ }
256
+ let before$1 = topLine.slice(0, closingPlusCol$1);
257
+ let after$1 = topLine.slice(closingPlusCol$1);
258
+ let dashes$1 = "-".repeat(Math.abs(diff));
259
+ let newLine$1 = before$1 + dashes$1 + after$1;
260
+ let newLines$1 = replaceLine(lines, topLeft.row, newLine$1);
261
+ let fixedText$1 = newLines$1.join("\n");
262
+ return [
263
+ fixedText$1,
264
+ {
265
+ original: error,
266
+ description: `Extended top border at line ` + (topLeft.row + 1 | 0).toString() + ` by ` + Math.abs(diff).toString() + ` characters`,
267
+ line: topLeft.row + 1 | 0,
268
+ column: closingPlusCol$1 + 1 | 0
269
+ }
270
+ ];
271
+ }
272
+
273
+ let fixStrategies = [
274
+ [
275
+ "MisalignedPipe",
276
+ code => code.TAG === "MisalignedPipe",
277
+ fixMisalignedPipe
278
+ ],
279
+ [
280
+ "MisalignedClosingBorder",
281
+ code => code.TAG === "MisalignedClosingBorder",
282
+ fixMisalignedClosingBorder
283
+ ],
284
+ [
285
+ "UnusualSpacing",
286
+ code => code.TAG === "UnusualSpacing",
287
+ fixUnusualSpacing
288
+ ],
289
+ [
290
+ "UnclosedBracket",
291
+ code => code.TAG === "UnclosedBracket",
292
+ fixUnclosedBracket
293
+ ],
294
+ [
295
+ "MismatchedWidth",
296
+ code => code.TAG === "MismatchedWidth",
297
+ fixMismatchedWidth
298
+ ]
299
+ ];
300
+
301
+ function tryFixError(text, error) {
302
+ return Core__Array.reduce(fixStrategies, undefined, (acc, param) => {
303
+ if (acc !== undefined) {
304
+ return acc;
305
+ } else if (param[1](error.code)) {
306
+ return param[2](text, error);
307
+ } else {
308
+ return;
309
+ }
310
+ });
311
+ }
312
+
313
+ function isFixable(code) {
314
+ return fixStrategies.some(param => param[1](code));
315
+ }
316
+
317
+ function fix(text) {
318
+ let _currentText = text;
319
+ let _fixedSoFar = [];
320
+ let _iteration = 0;
321
+ while (true) {
322
+ let iteration = _iteration;
323
+ let fixedSoFar = _fixedSoFar;
324
+ let currentText = _currentText;
325
+ if (iteration >= 100) {
326
+ return {
327
+ TAG: "Ok",
328
+ _0: {
329
+ text: currentText,
330
+ fixed: fixedSoFar,
331
+ remaining: []
332
+ }
333
+ };
334
+ }
335
+ let parseResult = Parser.parse(currentText);
336
+ if (parseResult.TAG === "Ok") {
337
+ let warnings = parseResult._0[1];
338
+ let fixableWarnings = warnings.filter(w => isFixable(w.code));
339
+ if (fixableWarnings.length === 0) {
340
+ return {
341
+ TAG: "Ok",
342
+ _0: {
343
+ text: currentText,
344
+ fixed: fixedSoFar,
345
+ remaining: warnings.filter(w => !isFixable(w.code))
346
+ }
347
+ };
348
+ }
349
+ let warning = fixableWarnings[0];
350
+ if (warning === undefined) {
351
+ return {
352
+ TAG: "Ok",
353
+ _0: {
354
+ text: currentText,
355
+ fixed: fixedSoFar,
356
+ remaining: warnings
357
+ }
358
+ };
359
+ }
360
+ let match = tryFixError(currentText, warning);
361
+ if (match === undefined) {
362
+ return {
363
+ TAG: "Ok",
364
+ _0: {
365
+ text: currentText,
366
+ fixed: fixedSoFar,
367
+ remaining: warnings
368
+ }
369
+ };
370
+ }
371
+ let newFixed = fixedSoFar.concat([match[1]]);
372
+ _iteration = iteration + 1 | 0;
373
+ _fixedSoFar = newFixed;
374
+ _currentText = match[0];
375
+ continue;
376
+ }
377
+ let errors = parseResult._0;
378
+ let fixableErrors = errors.filter(e => isFixable(e.code));
379
+ if (fixableErrors.length === 0) {
380
+ return {
381
+ TAG: "Ok",
382
+ _0: {
383
+ text: currentText,
384
+ fixed: fixedSoFar,
385
+ remaining: errors.filter(e => !isFixable(e.code))
386
+ }
387
+ };
388
+ }
389
+ let error = fixableErrors[0];
390
+ if (error === undefined) {
391
+ return {
392
+ TAG: "Ok",
393
+ _0: {
394
+ text: currentText,
395
+ fixed: fixedSoFar,
396
+ remaining: errors
397
+ }
398
+ };
399
+ }
400
+ let match$1 = tryFixError(currentText, error);
401
+ if (match$1 === undefined) {
402
+ return {
403
+ TAG: "Ok",
404
+ _0: {
405
+ text: currentText,
406
+ fixed: fixedSoFar,
407
+ remaining: errors
408
+ }
409
+ };
410
+ }
411
+ let newFixed$1 = fixedSoFar.concat([match$1[1]]);
412
+ _iteration = iteration + 1 | 0;
413
+ _fixedSoFar = newFixed$1;
414
+ _currentText = match$1[0];
415
+ continue;
416
+ };
417
+ }
418
+
419
+ function fixOnly(text) {
420
+ let match = fix(text);
421
+ if (match.TAG === "Ok") {
422
+ return match._0.text;
423
+ } else {
424
+ return text;
425
+ }
426
+ }
427
+
428
+ export {
429
+ splitLines,
430
+ joinLines,
431
+ getLine,
432
+ replaceLine,
433
+ insertAt,
434
+ removeAt,
435
+ replaceCharAt,
436
+ fixMisalignedPipe,
437
+ fixMisalignedClosingBorder,
438
+ fixUnusualSpacing,
439
+ fixUnclosedBracket,
440
+ fixMismatchedWidth,
441
+ fixStrategies,
442
+ tryFixError,
443
+ isFixable,
444
+ fix,
445
+ fixOnly,
446
+ }
447
+ /* Parser Not a pure module */