starlight-cli 1.1.4 → 1.1.6
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/README.md +215 -85
- package/dist/index.js +9032 -5
- package/package.json +4 -1
- package/src/evaluator.js +59 -2
- package/src/starlight.js +105 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "starlight-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"description": "Starlight Programming Language CLI",
|
|
5
5
|
"bin": {
|
|
6
6
|
"starlight": "index.js"
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"blessed": "^0.1.81",
|
|
16
|
+
"markdown-it": "^14.1.0",
|
|
17
|
+
"markdown-it-footnote": "^4.0.0",
|
|
18
|
+
"markdown-it-task-lists": "^2.1.1",
|
|
16
19
|
"readline-sync": "^1.4.10",
|
|
17
20
|
"starlight-color": "^1.0.4"
|
|
18
21
|
},
|
package/src/evaluator.js
CHANGED
|
@@ -107,7 +107,6 @@ suggest(name, env) {
|
|
|
107
107
|
|
|
108
108
|
return best;
|
|
109
109
|
}
|
|
110
|
-
|
|
111
110
|
formatValue(value, seen = new Set()) {
|
|
112
111
|
const color = require('starlight-color');
|
|
113
112
|
|
|
@@ -152,7 +151,7 @@ formatValue(value, seen = new Set()) {
|
|
|
152
151
|
} catch {
|
|
153
152
|
return color.red('[Unprintable]');
|
|
154
153
|
}
|
|
155
|
-
}
|
|
154
|
+
}
|
|
156
155
|
|
|
157
156
|
|
|
158
157
|
setupBuiltins() {
|
|
@@ -167,6 +166,64 @@ formatValue(value, seen = new Set()) {
|
|
|
167
166
|
if (Array.isArray(arg)) return 'array';
|
|
168
167
|
return typeof arg;
|
|
169
168
|
});
|
|
169
|
+
this.global.define('map', async (array, fn) => {
|
|
170
|
+
if (!Array.isArray(array)) {
|
|
171
|
+
throw new RuntimeError('map() expects an array', null, this.source);
|
|
172
|
+
}
|
|
173
|
+
if (typeof fn !== 'function') {
|
|
174
|
+
throw new RuntimeError('map() expects a function', null, this.source);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const result = [];
|
|
178
|
+
for (let i = 0; i < array.length; i++) {
|
|
179
|
+
result.push(await fn(array[i], i, array));
|
|
180
|
+
}
|
|
181
|
+
return result;
|
|
182
|
+
});
|
|
183
|
+
this.global.define('filter', async (array, fn) => {
|
|
184
|
+
if (!Array.isArray(array)) {
|
|
185
|
+
throw new RuntimeError('filter() expects an array', null, this.source);
|
|
186
|
+
}
|
|
187
|
+
if (typeof fn !== 'function') {
|
|
188
|
+
throw new RuntimeError('filter() expects a function', null, this.source);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const result = [];
|
|
192
|
+
for (let i = 0; i < array.length; i++) {
|
|
193
|
+
if (await fn(array[i], i, array)) {
|
|
194
|
+
result.push(array[i]);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
});
|
|
199
|
+
this.global.define('reduce', async (array, fn, initial) => {
|
|
200
|
+
if (!Array.isArray(array)) {
|
|
201
|
+
throw new RuntimeError('reduce() expects an array', null, this.source);
|
|
202
|
+
}
|
|
203
|
+
if (typeof fn !== 'function') {
|
|
204
|
+
throw new RuntimeError('reduce() expects a function', null, this.source);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let acc;
|
|
208
|
+
let startIndex = 0;
|
|
209
|
+
|
|
210
|
+
if (initial !== undefined) {
|
|
211
|
+
acc = initial;
|
|
212
|
+
} else {
|
|
213
|
+
if (array.length === 0) {
|
|
214
|
+
throw new RuntimeError('reduce() of empty array with no initial value', null, this.source);
|
|
215
|
+
}
|
|
216
|
+
acc = array[0];
|
|
217
|
+
startIndex = 1;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
for (let i = startIndex; i < array.length; i++) {
|
|
221
|
+
acc = await fn(acc, array[i], i, array);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return acc;
|
|
225
|
+
});
|
|
226
|
+
|
|
170
227
|
this.global.define('keys', arg => arg && typeof arg === 'object' ? Object.keys(arg) : []);
|
|
171
228
|
this.global.define('values', arg => arg && typeof arg === 'object' ? Object.values(arg) : []);
|
|
172
229
|
this.global.define('range', (...args) => {
|
package/src/starlight.js
CHANGED
|
@@ -4,12 +4,15 @@ const os = require('os');
|
|
|
4
4
|
const { exec } = require('child_process');
|
|
5
5
|
const readline = require('readline');
|
|
6
6
|
const readlineSync = require('readline-sync');
|
|
7
|
+
const MarkdownIt = require('markdown-it');
|
|
8
|
+
const mdTaskLists = require('markdown-it-task-lists');
|
|
9
|
+
const mdFootnote = require('markdown-it-footnote');
|
|
7
10
|
|
|
8
11
|
const Lexer = require('./lexer');
|
|
9
12
|
const Parser = require('./parser');
|
|
10
13
|
const Evaluator = require('./evaluator');
|
|
11
14
|
|
|
12
|
-
const VERSION = '1.1.
|
|
15
|
+
const VERSION = '1.1.6';
|
|
13
16
|
|
|
14
17
|
const COLOR = {
|
|
15
18
|
reset: '\x1b[0m',
|
|
@@ -35,6 +38,99 @@ function fatal(msg) {
|
|
|
35
38
|
console.error(COLOR.white + msg + COLOR.reset);
|
|
36
39
|
waitAndExit(1);
|
|
37
40
|
}
|
|
41
|
+
function renderMarkdown(mdPath) {
|
|
42
|
+
let markdown;
|
|
43
|
+
try {
|
|
44
|
+
markdown = fs.readFileSync(mdPath, 'utf8');
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.error(COLOR.white + `Failed to read markdown: ${e.message}` + COLOR.reset);
|
|
47
|
+
return waitAndExit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const md = new MarkdownIt({
|
|
51
|
+
html: true,
|
|
52
|
+
linkify: true,
|
|
53
|
+
typographer: true
|
|
54
|
+
})
|
|
55
|
+
.use(mdTaskLists, { enabled: true })
|
|
56
|
+
.use(mdFootnote);
|
|
57
|
+
|
|
58
|
+
const html = `<!DOCTYPE html>
|
|
59
|
+
<html lang="en">
|
|
60
|
+
<head>
|
|
61
|
+
<meta charset="UTF-8">
|
|
62
|
+
<title>${path.basename(mdPath)}</title>
|
|
63
|
+
<style>
|
|
64
|
+
body {
|
|
65
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
66
|
+
padding: 40px;
|
|
67
|
+
max-width: 900px;
|
|
68
|
+
margin: auto;
|
|
69
|
+
background: #0e0e11;
|
|
70
|
+
color: #eaeaea;
|
|
71
|
+
line-height: 1.6;
|
|
72
|
+
}
|
|
73
|
+
h1, h2, h3, h4 {
|
|
74
|
+
border-bottom: 1px solid #2a2a35;
|
|
75
|
+
padding-bottom: 6px;
|
|
76
|
+
}
|
|
77
|
+
pre {
|
|
78
|
+
background: #1e1e2e;
|
|
79
|
+
padding: 16px;
|
|
80
|
+
overflow-x: auto;
|
|
81
|
+
border-radius: 8px;
|
|
82
|
+
}
|
|
83
|
+
code {
|
|
84
|
+
background: #1e1e2e;
|
|
85
|
+
padding: 2px 6px;
|
|
86
|
+
border-radius: 4px;
|
|
87
|
+
color: #f8f8f2;
|
|
88
|
+
}
|
|
89
|
+
table {
|
|
90
|
+
border-collapse: collapse;
|
|
91
|
+
width: 100%;
|
|
92
|
+
margin: 20px 0;
|
|
93
|
+
}
|
|
94
|
+
th, td {
|
|
95
|
+
border: 1px solid #2a2a35;
|
|
96
|
+
padding: 8px;
|
|
97
|
+
}
|
|
98
|
+
th {
|
|
99
|
+
background: #1b1b25;
|
|
100
|
+
}
|
|
101
|
+
a {
|
|
102
|
+
color: #7aa2f7;
|
|
103
|
+
text-decoration: none;
|
|
104
|
+
}
|
|
105
|
+
a:hover {
|
|
106
|
+
text-decoration: underline;
|
|
107
|
+
}
|
|
108
|
+
blockquote {
|
|
109
|
+
border-left: 4px solid #7aa2f7;
|
|
110
|
+
padding-left: 16px;
|
|
111
|
+
color: #c0caf5;
|
|
112
|
+
margin: 20px 0;
|
|
113
|
+
}
|
|
114
|
+
</style>
|
|
115
|
+
</head>
|
|
116
|
+
<body>
|
|
117
|
+
${md.render(markdown)}
|
|
118
|
+
</body>
|
|
119
|
+
</html>`;
|
|
120
|
+
|
|
121
|
+
const tempHtml = path.join(
|
|
122
|
+
os.tmpdir(),
|
|
123
|
+
`starlight-md-${Date.now()}.html`
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
fs.writeFileSync(tempHtml, html, 'utf8');
|
|
127
|
+
|
|
128
|
+
openURL(`file://${tempHtml}`);
|
|
129
|
+
|
|
130
|
+
setTimeout(() => {
|
|
131
|
+
try { fs.unlinkSync(tempHtml); } catch {}
|
|
132
|
+
}, 3000);
|
|
133
|
+
}
|
|
38
134
|
|
|
39
135
|
function highlightCode(line) {
|
|
40
136
|
return line
|
|
@@ -216,5 +312,12 @@ async function runFile(filePath, isTemp = false, callback) {
|
|
|
216
312
|
|
|
217
313
|
|
|
218
314
|
if (!args[0].startsWith('--')) {
|
|
219
|
-
|
|
315
|
+
const file = path.resolve(args[0]);
|
|
316
|
+
const ext = path.extname(file).toLowerCase();
|
|
317
|
+
|
|
318
|
+
if (ext === '.md') {
|
|
319
|
+
renderMarkdown(file);
|
|
320
|
+
} else {
|
|
321
|
+
runFile(file);
|
|
322
|
+
}
|
|
220
323
|
}
|