@torpor/prettier 1.0.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/README.md +30 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +320 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# torpor/prettier
|
|
2
|
+
|
|
3
|
+
A [Prettier](https://prettier.io) plugin for formatting Torpor `.torp` files.
|
|
4
|
+
|
|
5
|
+
It formats the JavaScript shell of a component with Prettier's TypeScript
|
|
6
|
+
parser, and the `@render`/`@head` markup and `@style` sections with Torpor's
|
|
7
|
+
own parser (tabs for indentation, attributes wrapped when over the print
|
|
8
|
+
width).
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install --save-dev @torpor/prettier
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
Add the plugin to your `.prettierrc`:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"plugins": ["@torpor/prettier"]
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Then format `.torp` files as usual:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx prettier --write src/App.torp
|
|
30
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import prettier from "prettier";
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
declare const languages: prettier.SupportLanguage[];
|
|
4
|
+
declare const parsers: Record<string, prettier.Parser>;
|
|
5
|
+
declare const printers: Record<string, prettier.Printer>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { languages, parsers, printers };
|
|
8
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;cAMa,WAAW,SAAS;cAQpB,SAAS,eAAe,SAAS;cASjC,UAAU,eAAe,SAAS"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { parse } from "@torpor/view/compile";
|
|
2
|
+
import prettier from "prettier";
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
const languages = [{
|
|
5
|
+
name: "torpor",
|
|
6
|
+
parsers: ["torpor-parser"],
|
|
7
|
+
extensions: [".torp"]
|
|
8
|
+
}];
|
|
9
|
+
const parsers = { "torpor-parser": {
|
|
10
|
+
parse: parse$1,
|
|
11
|
+
astFormat: "torpor-ast",
|
|
12
|
+
locStart,
|
|
13
|
+
locEnd
|
|
14
|
+
} };
|
|
15
|
+
const printers = { "torpor-ast": { print } };
|
|
16
|
+
function parse$1(text, _options) {
|
|
17
|
+
let chunks = [];
|
|
18
|
+
for (let i = 0; i < text.length; i++) if (text[i] === "@") {
|
|
19
|
+
if (text.slice(i + 1).startsWith("render")) {
|
|
20
|
+
const chunk = consumeChunk(text, i, "render");
|
|
21
|
+
chunks.push(chunk);
|
|
22
|
+
i = chunk.end - 1;
|
|
23
|
+
} else if (text.slice(i + 1).startsWith("head")) {
|
|
24
|
+
const chunk = consumeChunk(text, i, "head");
|
|
25
|
+
chunks.push(chunk);
|
|
26
|
+
i = chunk.end - 1;
|
|
27
|
+
} else if (text.slice(i + 1).startsWith("style")) {
|
|
28
|
+
const chunk = consumeChunk(text, i, "style");
|
|
29
|
+
chunks.push(chunk);
|
|
30
|
+
i = chunk.end - 1;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
let shell = "";
|
|
34
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
35
|
+
let start = i > 0 ? chunks[i - 1].end : 0;
|
|
36
|
+
chunks[i].shellStart = shell.length;
|
|
37
|
+
shell += text.substring(start, chunks[i].start) + `/* ${chunks[i].id} */ 1;`;
|
|
38
|
+
}
|
|
39
|
+
shell += text.substring(chunks[chunks.length - 1].end);
|
|
40
|
+
return { chunks: [{
|
|
41
|
+
type: "shell",
|
|
42
|
+
id: "",
|
|
43
|
+
content: shell,
|
|
44
|
+
start: 0,
|
|
45
|
+
end: text.length,
|
|
46
|
+
shellStart: 0,
|
|
47
|
+
formatted: ""
|
|
48
|
+
}, ...chunks] };
|
|
49
|
+
}
|
|
50
|
+
function consumeChunk(text, i, type) {
|
|
51
|
+
let level = 0;
|
|
52
|
+
let j;
|
|
53
|
+
for (j = i; j < text.length; j++) if (text[j] === "{") level++;
|
|
54
|
+
else if (text[j] === "}") {
|
|
55
|
+
level--;
|
|
56
|
+
if (level === 0) break;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
type,
|
|
60
|
+
id: crypto.randomUUID(),
|
|
61
|
+
content: text.substring(i, j + 1),
|
|
62
|
+
start: i,
|
|
63
|
+
end: j + 1,
|
|
64
|
+
shellStart: 0,
|
|
65
|
+
formatted: ""
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function locStart() {
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
function locEnd() {
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
async function print(path, options, _print) {
|
|
75
|
+
const node = path.node;
|
|
76
|
+
for (let chunk of node.chunks) switch (chunk.type) {
|
|
77
|
+
case "shell":
|
|
78
|
+
chunk.formatted = await prettier.format(chunk.content, {
|
|
79
|
+
...options,
|
|
80
|
+
parser: "typescript"
|
|
81
|
+
});
|
|
82
|
+
break;
|
|
83
|
+
case "head":
|
|
84
|
+
case "render":
|
|
85
|
+
chunk.formatted = formatRenderChunk(chunk.type, chunk.content, options);
|
|
86
|
+
break;
|
|
87
|
+
case "style":
|
|
88
|
+
chunk.formatted = formatStyleChunk(chunk.content, options);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
const shell = node.chunks[0];
|
|
92
|
+
for (let i = 1; i < node.chunks.length; i++) shell.formatted = shell.formatted.replace(`/* ${node.chunks[i].id} */ 1;`, node.chunks[i].formatted.trimStart());
|
|
93
|
+
return shell.formatted;
|
|
94
|
+
}
|
|
95
|
+
function formatRenderChunk(type, content, options) {
|
|
96
|
+
const parsed = parse(`
|
|
97
|
+
export default function C() {
|
|
98
|
+
${content}
|
|
99
|
+
}`);
|
|
100
|
+
if (!parsed.ok || !parsed.template) {
|
|
101
|
+
console.log(`Failed to parse render section: ${parsed.errors.map((e) => e.message).join(", ")}`);
|
|
102
|
+
return content;
|
|
103
|
+
}
|
|
104
|
+
let node = type === "head" ? parsed.template.components[0].head : parsed.template.components[0].markup;
|
|
105
|
+
let state = {
|
|
106
|
+
indent: 1,
|
|
107
|
+
output: "",
|
|
108
|
+
preserveWhitespace: false
|
|
109
|
+
};
|
|
110
|
+
formatRenderNode(node, state, options, type);
|
|
111
|
+
return state.output;
|
|
112
|
+
}
|
|
113
|
+
function formatRenderNode(node, state, options, type = "") {
|
|
114
|
+
switch (node.type) {
|
|
115
|
+
case "root":
|
|
116
|
+
formatRootNode(node, state, options, type);
|
|
117
|
+
break;
|
|
118
|
+
case "control":
|
|
119
|
+
formatControlNode(node, state, options);
|
|
120
|
+
break;
|
|
121
|
+
case "element":
|
|
122
|
+
case "component":
|
|
123
|
+
case "special":
|
|
124
|
+
formatElementNode(node, state, options);
|
|
125
|
+
break;
|
|
126
|
+
case "text":
|
|
127
|
+
formatTextNode(node, state, options);
|
|
128
|
+
break;
|
|
129
|
+
case "comment":
|
|
130
|
+
formatCommentNode(node, state, options);
|
|
131
|
+
break;
|
|
132
|
+
default: throw new Error("Unknown node type: " + node.type);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function formatRootNode(node, state, options, type) {
|
|
136
|
+
const indent = " ".repeat(state.indent);
|
|
137
|
+
state.output += `${indent}@${type} {`;
|
|
138
|
+
state.indent++;
|
|
139
|
+
for (let c of node.children) formatRenderNode(c, state, options);
|
|
140
|
+
state.indent--;
|
|
141
|
+
state.output = state.output.replace(/\n\n$/, "\n");
|
|
142
|
+
state.output += `${indent}}`;
|
|
143
|
+
}
|
|
144
|
+
function formatControlNode(node, state, options) {
|
|
145
|
+
const indent = " ".repeat(state.indent);
|
|
146
|
+
switch (node.operation) {
|
|
147
|
+
case "@if group":
|
|
148
|
+
case "@for group":
|
|
149
|
+
for (let c of node.children) formatRenderNode(c, state, options);
|
|
150
|
+
state.output = state.output.replace(/\n\n$/, "\n");
|
|
151
|
+
state.output += `${indent}}`;
|
|
152
|
+
break;
|
|
153
|
+
case "@if":
|
|
154
|
+
case "@for":
|
|
155
|
+
state.output += `${indent}@${node.statement} {`;
|
|
156
|
+
state.indent++;
|
|
157
|
+
for (let c of node.children) formatRenderNode(c, state, options);
|
|
158
|
+
state.indent--;
|
|
159
|
+
break;
|
|
160
|
+
case "@else if":
|
|
161
|
+
case "@else":
|
|
162
|
+
state.output += `${indent}} ${node.statement} {`;
|
|
163
|
+
state.indent++;
|
|
164
|
+
for (let c of node.children) formatRenderNode(c, state, options);
|
|
165
|
+
state.indent--;
|
|
166
|
+
break;
|
|
167
|
+
case "@switch group":
|
|
168
|
+
state.output += `${indent}@${node.statement} {`;
|
|
169
|
+
state.indent++;
|
|
170
|
+
for (let c of node.children) formatRenderNode(c, state, options);
|
|
171
|
+
state.indent--;
|
|
172
|
+
state.output = state.output.replace(/\n\n$/, "\n");
|
|
173
|
+
state.output += `${indent}}`;
|
|
174
|
+
break;
|
|
175
|
+
case "@case":
|
|
176
|
+
case "@default":
|
|
177
|
+
if (node.operation === "@default") state.output += "\n";
|
|
178
|
+
state.output += `${indent}${node.statement} {`;
|
|
179
|
+
state.indent++;
|
|
180
|
+
for (let c of node.children) formatRenderNode(c, state, options);
|
|
181
|
+
state.indent--;
|
|
182
|
+
state.output = state.output.replace(/\n\n$/, "\n");
|
|
183
|
+
state.output += `${indent}}`;
|
|
184
|
+
break;
|
|
185
|
+
case "@key":
|
|
186
|
+
state.output += `${indent}@${node.statement}\n`;
|
|
187
|
+
break;
|
|
188
|
+
default: throw new Error("Unknown control operation: " + node.operation);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function formatElementNode(node, state, options) {
|
|
192
|
+
const indent = " ".repeat(state.indent);
|
|
193
|
+
if (node.tagName === "filldef") {
|
|
194
|
+
for (let c of node.children) formatRenderNode(c, state, options);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
let attrs = node.attributes.map((a) => {
|
|
198
|
+
if (a.value === void 0) return a.name;
|
|
199
|
+
else if (a.value === a.name || a.value.endsWith(`.${a.name}`)) return `{${a.value}}`;
|
|
200
|
+
else {
|
|
201
|
+
let value = a.fullyReactive ? `{${a.value}}` : a.value;
|
|
202
|
+
return `${a.name}=${value}`;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
let attributes = attrs.length ? " " + attrs.join(" ") : "";
|
|
206
|
+
let element = `${indent}<${node.tagName}${attributes}${node.selfClosed ? " /" : ""}>`;
|
|
207
|
+
if (node.attributes.length && element.length > options.printWidth) {
|
|
208
|
+
let attrIndent = `\n${indent}\t`;
|
|
209
|
+
attributes = attrs.join(attrIndent);
|
|
210
|
+
element = `${indent}<${node.tagName}${attrIndent}${attributes}\n${indent}${node.selfClosed ? "/" : ""}>`;
|
|
211
|
+
}
|
|
212
|
+
if (state.output.endsWith("\n")) state.output += indent;
|
|
213
|
+
else if (!state.output.endsWith(">") && !state.output.endsWith("{") && !state.output.endsWith("}")) state.output += " ";
|
|
214
|
+
state.output += element.trimStart();
|
|
215
|
+
if (node.selfClosed) return;
|
|
216
|
+
const oldPreserveWhitespace = state.preserveWhitespace;
|
|
217
|
+
state.preserveWhitespace = node.tagName === "code" || node.tagName === "pre";
|
|
218
|
+
state.indent++;
|
|
219
|
+
for (let c of node.children) formatRenderNode(c, state, options);
|
|
220
|
+
state.indent--;
|
|
221
|
+
state.preserveWhitespace = oldPreserveWhitespace;
|
|
222
|
+
if (state.output.endsWith("\n")) state.output += indent;
|
|
223
|
+
state.output += `</${node.tagName}>`;
|
|
224
|
+
}
|
|
225
|
+
function formatTextNode(node, state, _options) {
|
|
226
|
+
if (state.preserveWhitespace) {
|
|
227
|
+
state.output += node.content;
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const indent = " ".repeat(state.indent);
|
|
231
|
+
let text = node.content.trim();
|
|
232
|
+
if (!text) {
|
|
233
|
+
let newLineCount = 0;
|
|
234
|
+
for (let i = 0; i < node.content.length; i++) if (node.content[i] === "\n") newLineCount++;
|
|
235
|
+
if (newLineCount > 0) {
|
|
236
|
+
if (newLineCount > 1 && !state.output.endsWith("{")) state.output += "\n";
|
|
237
|
+
state.output += "\n";
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
text = text.replaceAll(/\s*\n\s*/g, `\n${indent}`);
|
|
242
|
+
if (/^\s*\n/.test(node.content)) text = "\n" + indent + text;
|
|
243
|
+
else if (/(<\/[^<]+>|\/>)$/i.test(state.output) && /^\s+/.test(node.content)) text = " " + text;
|
|
244
|
+
if (/\n\s*$/.test(node.content)) text += "\n";
|
|
245
|
+
state.output += text;
|
|
246
|
+
}
|
|
247
|
+
function formatCommentNode(node, state, _options) {
|
|
248
|
+
const indent = " ".repeat(state.indent);
|
|
249
|
+
switch (node.commentType) {
|
|
250
|
+
case "html":
|
|
251
|
+
state.output += `${indent}<!--${node.content}-->`;
|
|
252
|
+
break;
|
|
253
|
+
case "line":
|
|
254
|
+
state.output += `${indent}@//${node.content}\n`;
|
|
255
|
+
break;
|
|
256
|
+
case "block":
|
|
257
|
+
state.output += `${indent}@/*${node.content}*/`;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function formatStyleChunk(content, _options) {
|
|
262
|
+
const parsed = parse(`
|
|
263
|
+
export default function C() {
|
|
264
|
+
${content}
|
|
265
|
+
}`);
|
|
266
|
+
if (!parsed.ok || !parsed.template) {
|
|
267
|
+
console.log(`Failed to parse style section: ${parsed.errors.map((e) => e.message).join(", ")}`);
|
|
268
|
+
return content;
|
|
269
|
+
}
|
|
270
|
+
let state = {
|
|
271
|
+
indent: 1,
|
|
272
|
+
output: "",
|
|
273
|
+
preserveWhitespace: false
|
|
274
|
+
};
|
|
275
|
+
const indent = " ".repeat(state.indent);
|
|
276
|
+
state.output += `${indent}@style {`;
|
|
277
|
+
state.indent++;
|
|
278
|
+
for (let c of parsed.template.components[0].style.children) formatStyleNode(c, state);
|
|
279
|
+
state.indent--;
|
|
280
|
+
state.output = state.output.replace(/\n\n$/, "\n");
|
|
281
|
+
state.output += `\n${indent}}`;
|
|
282
|
+
return state.output;
|
|
283
|
+
}
|
|
284
|
+
function formatStyleNode(node, state) {
|
|
285
|
+
if (node.gapBefore && !state.output.endsWith("{")) state.output += "\n";
|
|
286
|
+
switch (node.type) {
|
|
287
|
+
case "block":
|
|
288
|
+
formatStyleBlockNode(node, state);
|
|
289
|
+
break;
|
|
290
|
+
case "attribute":
|
|
291
|
+
formatStyleAttributeNode(node, state);
|
|
292
|
+
break;
|
|
293
|
+
case "comment":
|
|
294
|
+
formatStyleCommentNode(node, state);
|
|
295
|
+
break;
|
|
296
|
+
default: console.log("Unknown style node type: " + node.type);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function formatStyleBlockNode(node, state) {
|
|
300
|
+
const indent = " ".repeat(state.indent);
|
|
301
|
+
state.output += `\n${indent}${node.selector} {`;
|
|
302
|
+
for (let c of node.children) {
|
|
303
|
+
state.indent++;
|
|
304
|
+
formatStyleNode(c, state);
|
|
305
|
+
state.indent--;
|
|
306
|
+
}
|
|
307
|
+
state.output += `\n${indent}}`;
|
|
308
|
+
}
|
|
309
|
+
function formatStyleAttributeNode(node, state) {
|
|
310
|
+
const indent = " ".repeat(state.indent);
|
|
311
|
+
state.output += `\n${indent}${node.name}: ${node.value};`;
|
|
312
|
+
}
|
|
313
|
+
function formatStyleCommentNode(node, state) {
|
|
314
|
+
const indent = " ".repeat(state.indent);
|
|
315
|
+
state.output += `\n${indent}${node.content}`;
|
|
316
|
+
}
|
|
317
|
+
//#endregion
|
|
318
|
+
export { languages, parsers, printers };
|
|
319
|
+
|
|
320
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["parse","parseTorp"],"sources":["../src/index.ts"],"sourcesContent":["import { parse as parseTorp } from \"@torpor/view/compile\";\n// Import from the specific module path to avoid the \"browser\" export condition\n// resolving to the standalone build (which lacks parser plugins)\n//import * as prettier from \"prettier/index.mjs\";\nimport prettier from \"prettier\";\n\nexport const languages: prettier.SupportLanguage[] = [\n\t{\n\t\tname: \"torpor\",\n\t\tparsers: [\"torpor-parser\"],\n\t\textensions: [\".torp\"],\n\t},\n];\n\nexport const parsers: Record<string, prettier.Parser> = {\n\t\"torpor-parser\": {\n\t\tparse,\n\t\tastFormat: \"torpor-ast\",\n\t\tlocStart,\n\t\tlocEnd,\n\t},\n};\n\nexport const printers: Record<string, prettier.Printer> = {\n\t\"torpor-ast\": {\n\t\t// @ts-ignore\n\t\tprint,\n\t},\n};\n\ninterface Chunk {\n\ttype: \"shell\" | \"head\" | \"render\" | \"style\";\n\tid: string;\n\tcontent: string;\n\tstart: number;\n\tend: number;\n\tshellStart: number;\n\tformatted: string;\n}\n\ninterface TorporNode extends prettier.AST {\n\tchunks: Chunk[];\n}\n\nfunction parse(text: string, _options: object): TorporNode {\n\tlet chunks: Chunk[] = [];\n\tfor (let i = 0; i < text.length; i++) {\n\t\tif (text[i] === \"@\") {\n\t\t\tif (text.slice(i + 1).startsWith(\"render\")) {\n\t\t\t\tconst chunk = consumeChunk(text, i, \"render\");\n\t\t\t\tchunks.push(chunk);\n\t\t\t\ti = chunk.end - 1;\n\t\t\t} else if (text.slice(i + 1).startsWith(\"head\")) {\n\t\t\t\tconst chunk = consumeChunk(text, i, \"head\");\n\t\t\t\tchunks.push(chunk);\n\t\t\t\ti = chunk.end - 1;\n\t\t\t} else if (text.slice(i + 1).startsWith(\"style\")) {\n\t\t\t\tconst chunk = consumeChunk(text, i, \"style\");\n\t\t\t\tchunks.push(chunk);\n\t\t\t\ti = chunk.end - 1;\n\t\t\t}\n\t\t}\n\t}\n\tlet shell = \"\";\n\tfor (let i = 0; i < chunks.length; i++) {\n\t\tlet start = i > 0 ? chunks[i - 1].end : 0;\n\t\tchunks[i].shellStart = shell.length;\n\t\tshell += text.substring(start, chunks[i].start) + `/* ${chunks[i].id} */ 1;`;\n\t}\n\tshell += text.substring(chunks[chunks.length - 1].end);\n\n\treturn {\n\t\tchunks: [\n\t\t\t{\n\t\t\t\ttype: \"shell\",\n\t\t\t\tid: \"\",\n\t\t\t\tcontent: shell,\n\t\t\t\tstart: 0,\n\t\t\t\tend: text.length,\n\t\t\t\tshellStart: 0,\n\t\t\t\tformatted: \"\",\n\t\t\t},\n\t\t\t...chunks,\n\t\t],\n\t};\n}\n\nfunction consumeChunk(text: string, i: number, type: \"head\" | \"render\" | \"style\"): Chunk {\n\tlet level = 0;\n\tlet j;\n\tfor (j = i; j < text.length; j++) {\n\t\tif (text[j] === \"{\") {\n\t\t\tlevel++;\n\t\t} else if (text[j] === \"}\") {\n\t\t\tlevel--;\n\t\t\tif (level === 0) break;\n\t\t}\n\t}\n\treturn {\n\t\ttype,\n\t\tid: crypto.randomUUID(),\n\t\tcontent: text.substring(i, j + 1),\n\t\tstart: i,\n\t\tend: j + 1,\n\t\tshellStart: 0,\n\t\tformatted: \"\",\n\t};\n}\n\nfunction locStart(): number {\n\treturn 0;\n}\n\nfunction locEnd(): number {\n\treturn 0;\n}\n\nasync function print(\n\tpath: prettier.AstPath,\n\toptions: object,\n\t_print: (path: prettier.AstPath) => prettier.Doc,\n): Promise<prettier.Doc> {\n\tconst node = path.node as TorporNode;\n\n\tfor (let chunk of node.chunks) {\n\t\tswitch (chunk.type) {\n\t\t\tcase \"shell\": {\n\t\t\t\tchunk.formatted = await prettier.format(chunk.content, {\n\t\t\t\t\t...options,\n\t\t\t\t\tparser: \"typescript\",\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"head\":\n\t\t\tcase \"render\": {\n\t\t\t\tchunk.formatted = formatRenderChunk(chunk.type, chunk.content, options);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"style\": {\n\t\t\t\tchunk.formatted = formatStyleChunk(chunk.content, options);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst shell = node.chunks[0];\n\n\tfor (let i = 1; i < node.chunks.length; i++) {\n\t\tshell.formatted = shell.formatted.replace(\n\t\t\t// TODO: What if prettier strips semicolons??\n\t\t\t`/* ${node.chunks[i].id} */ 1;`,\n\t\t\tnode.chunks[i].formatted.trimStart(),\n\t\t);\n\t}\n\n\treturn shell.formatted;\n}\n\ninterface FormatState {\n\tindent: number;\n\toutput: string;\n\tpreserveWhitespace: any;\n}\n\nfunction formatRenderChunk(type: \"head\" | \"render\", content: string, options: object) {\n\t// HACK: should do this when parsing and convert it into a better AST\n\tconst source = `\nexport default function C() {\n${content}\n}`;\n\tconst parsed = parseTorp(source);\n\tif (!parsed.ok || !parsed.template) {\n\t\tconsole.log(\n\t\t\t`Failed to parse render section: ${parsed.errors.map((e) => e.message).join(\", \")}`,\n\t\t);\n\t\treturn content;\n\t}\n\n\tlet node =\n\t\ttype === \"head\" ? parsed.template.components[0].head : parsed.template.components[0].markup;\n\tlet state: FormatState = {\n\t\t// HACK: this should come from the indentation of the @render\n\t\tindent: 1,\n\t\toutput: \"\",\n\t\tpreserveWhitespace: false,\n\t};\n\tformatRenderNode(node, state, options, type);\n\treturn state.output;\n}\n\n// HACK: no types on internal types\nfunction formatRenderNode(\n\tnode: any,\n\tstate: FormatState,\n\toptions: Record<PropertyKey, any>,\n\ttype = \"\",\n) {\n\tswitch (node.type) {\n\t\tcase \"root\": {\n\t\t\tformatRootNode(node, state, options, type);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"control\": {\n\t\t\tformatControlNode(node, state, options);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"element\":\n\t\tcase \"component\":\n\t\tcase \"special\": {\n\t\t\tformatElementNode(node, state, options);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"text\": {\n\t\t\tformatTextNode(node, state, options);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"comment\": {\n\t\t\tformatCommentNode(node, state, options);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tthrow new Error(\"Unknown node type: \" + node.type);\n\t\t}\n\t}\n}\n\nfunction formatRootNode(\n\tnode: any,\n\tstate: FormatState,\n\toptions: Record<PropertyKey, any>,\n\ttype: string,\n) {\n\tconst indent = \"\\t\".repeat(state.indent);\n\tstate.output += `${indent}@${type} {`;\n\tstate.indent++;\n\tfor (let c of node.children) {\n\t\tformatRenderNode(c, state, options);\n\t}\n\tstate.indent--;\n\tstate.output = state.output.replace(/\\n\\n$/, \"\\n\");\n\tstate.output += `${indent}}`;\n}\n\nfunction formatControlNode(node: any, state: FormatState, options: Record<PropertyKey, any>) {\n\tconst indent = \"\\t\".repeat(state.indent);\n\t// HACK: might be better to change the way these are parsed out...\n\tswitch (node.operation) {\n\t\tcase \"@if group\":\n\t\tcase \"@for group\": {\n\t\t\tfor (let c of node.children) {\n\t\t\t\tformatRenderNode(c, state, options);\n\t\t\t}\n\t\t\tstate.output = state.output.replace(/\\n\\n$/, \"\\n\");\n\t\t\tstate.output += `${indent}}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"@if\":\n\t\tcase \"@for\": {\n\t\t\tstate.output += `${indent}@${node.statement} {`;\n\t\t\tstate.indent++;\n\t\t\tfor (let c of node.children) {\n\t\t\t\tformatRenderNode(c, state, options);\n\t\t\t}\n\t\t\tstate.indent--;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"@else if\":\n\t\tcase \"@else\": {\n\t\t\tstate.output += `${indent}} ${node.statement} {`;\n\t\t\tstate.indent++;\n\t\t\tfor (let c of node.children) {\n\t\t\t\tformatRenderNode(c, state, options);\n\t\t\t}\n\t\t\tstate.indent--;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"@switch group\": {\n\t\t\tstate.output += `${indent}@${node.statement} {`;\n\t\t\tstate.indent++;\n\t\t\tfor (let c of node.children) {\n\t\t\t\tformatRenderNode(c, state, options);\n\t\t\t}\n\t\t\tstate.indent--;\n\t\t\tstate.output = state.output.replace(/\\n\\n$/, \"\\n\");\n\t\t\tstate.output += `${indent}}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"@case\":\n\t\tcase \"@default\": {\n\t\t\t// HACK: need to fix parsing\n\t\t\tif (node.operation === \"@default\") state.output += \"\\n\";\n\t\t\tstate.output += `${indent}${node.statement} {`;\n\t\t\tstate.indent++;\n\t\t\tfor (let c of node.children) {\n\t\t\t\tformatRenderNode(c, state, options);\n\t\t\t}\n\t\t\tstate.indent--;\n\t\t\tstate.output = state.output.replace(/\\n\\n$/, \"\\n\");\n\t\t\tstate.output += `${indent}}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"@key\": {\n\t\t\tstate.output += `${indent}@${node.statement}\\n`;\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tthrow new Error(\"Unknown control operation: \" + node.operation);\n\t\t}\n\t}\n}\n\nfunction formatElementNode(node: any, state: FormatState, options: Record<PropertyKey, any>) {\n\tconst indent = \"\\t\".repeat(state.indent);\n\n\t// HACK: Empty <fill> nodes get inserted behind the scenes and shouldn't be output\n\tif (node.tagName === \"filldef\") {\n\t\tfor (let c of node.children) {\n\t\t\tformatRenderNode(c, state, options);\n\t\t}\n\t\treturn;\n\t}\n\n\t// Build the list of attributes\n\tlet attrs = node.attributes.map((a: any) => {\n\t\tif (a.value === undefined) {\n\t\t\treturn a.name;\n\t\t} else if (a.value === a.name || a.value.endsWith(`.${a.name}`)) {\n\t\t\treturn `{${a.value}}`;\n\t\t} else {\n\t\t\tlet value = a.fullyReactive ? `{${a.value}}` : a.value;\n\t\t\treturn `${a.name}=${value}`;\n\t\t}\n\t});\n\n\t// TODO: Do we need to translate tabs to spaces for print width??\n\t// Let's see if they work on one line\n\tlet attributes = attrs.length ? \" \" + attrs.join(\" \") : \"\";\n\tlet element = `${indent}<${node.tagName}${attributes}${node.selfClosed ? \" /\" : \"\"}>`;\n\tif (node.attributes.length && element.length > options.printWidth) {\n\t\t// They're too long, so let's try that again\n\t\tlet attrIndent = `\\n${indent}\\t`;\n\t\tattributes = attrs.join(attrIndent);\n\t\telement = `${indent}<${node.tagName}${attrIndent}${attributes}\\n${indent}${node.selfClosed ? \"/\" : \"\"}>`;\n\t}\n\n\t// If at a newline, add the indent\n\t// If after an element/brace, add a space\n\tif (state.output.endsWith(\"\\n\")) {\n\t\tstate.output += indent;\n\t} else if (\n\t\t!state.output.endsWith(\">\") &&\n\t\t!state.output.endsWith(\"{\") &&\n\t\t!state.output.endsWith(\"}\")\n\t) {\n\t\tstate.output += \" \";\n\t}\n\n\tstate.output += element.trimStart();\n\n\t// If self-closed, we don't need to add anything else\n\tif (node.selfClosed) {\n\t\treturn;\n\t}\n\n\t// Add the children\n\tconst oldPreserveWhitespace = state.preserveWhitespace;\n\tstate.preserveWhitespace = node.tagName === \"code\" || node.tagName === \"pre\";\n\tstate.indent++;\n\tfor (let c of node.children) {\n\t\tformatRenderNode(c, state, options);\n\t}\n\tstate.indent--;\n\tstate.preserveWhitespace = oldPreserveWhitespace;\n\n\t// Add the closing tag\n\tif (state.output.endsWith(\"\\n\")) {\n\t\tstate.output += indent;\n\t}\n\tstate.output += `</${node.tagName}>`;\n}\n\nfunction formatTextNode(node: any, state: FormatState, _options: Record<PropertyKey, any>) {\n\tif (state.preserveWhitespace) {\n\t\tstate.output += node.content;\n\t\treturn;\n\t}\n\n\tconst indent = \"\\t\".repeat(state.indent);\n\tlet text = node.content.trim();\n\n\t// Check if it's just some newlines and, if so, add them\n\tif (!text) {\n\t\tlet newLineCount = 0;\n\t\tfor (let i = 0; i < node.content.length; i++) {\n\t\t\tif (node.content[i] === \"\\n\") newLineCount++;\n\t\t}\n\t\tif (newLineCount > 0) {\n\t\t\tif (newLineCount > 1 && !state.output.endsWith(\"{\")) {\n\t\t\t\tstate.output += \"\\n\";\n\t\t\t}\n\t\t\tstate.output += \"\\n\";\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Replace indents + newlines with the correct spacing (e.g. if a block of\n\t// text has been moved)\n\ttext = text.replaceAll(/\\s*\\n\\s*/g, `\\n${indent}`);\n\n\t// Add a newline if the text had one at the start\n\t// Add a space if the text is after a closing tag and had any spaces at the start\n\tlet newLineBefore = /^\\s*\\n/.test(node.content);\n\tif (newLineBefore) {\n\t\ttext = \"\\n\" + indent + text;\n\t} else if (/(<\\/[^<]+>|\\/>)$/i.test(state.output) && /^\\s+/.test(node.content)) {\n\t\ttext = \" \" + text;\n\t}\n\n\t// Add a newline if the text had one at the end\n\tlet newLineAfter = /\\n\\s*$/.test(node.content);\n\tif (newLineAfter) {\n\t\ttext += \"\\n\";\n\t}\n\n\tstate.output += text;\n}\n\nfunction formatCommentNode(node: any, state: FormatState, _options: Record<PropertyKey, any>) {\n\tconst indent = \"\\t\".repeat(state.indent);\n\tswitch (node.commentType) {\n\t\tcase \"html\":\n\t\t\tstate.output += `${indent}<!--${node.content}-->`;\n\t\t\tbreak;\n\t\tcase \"line\":\n\t\t\tstate.output += `${indent}@//${node.content}\\n`;\n\t\t\tbreak;\n\t\tcase \"block\":\n\t\t\tstate.output += `${indent}@/*${node.content}*/`;\n\t\t\tbreak;\n\t}\n}\n\nfunction formatStyleChunk(content: string, _options: object) {\n\t// HACK: should do this when parsing and convert it into a better AST\n\tconst source = `\nexport default function C() {\n${content}\n}`;\n\tconst parsed = parseTorp(source);\n\tif (!parsed.ok || !parsed.template) {\n\t\tconsole.log(`Failed to parse style section: ${parsed.errors.map((e) => e.message).join(\", \")}`);\n\t\treturn content;\n\t}\n\n\tlet state: FormatState = {\n\t\t// HACK: this should come from the indentation of the @render\n\t\tindent: 1,\n\t\toutput: \"\",\n\t\tpreserveWhitespace: false,\n\t};\n\n\tconst indent = \"\\t\".repeat(state.indent);\n\tstate.output += `${indent}@style {`;\n\tstate.indent++;\n\tfor (let c of parsed.template.components[0].style!.children) {\n\t\tformatStyleNode(c, state);\n\t}\n\tstate.indent--;\n\tstate.output = state.output.replace(/\\n\\n$/, \"\\n\");\n\tstate.output += `\\n${indent}}`;\n\n\treturn state.output;\n}\n\n// HACK: no types on internal types\nfunction formatStyleNode(node: any, state: FormatState) {\n\tif (node.gapBefore && !state.output.endsWith(\"{\")) {\n\t\tstate.output += \"\\n\";\n\t}\n\tswitch (node.type) {\n\t\tcase \"block\": {\n\t\t\tformatStyleBlockNode(node, state);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"attribute\": {\n\t\t\tformatStyleAttributeNode(node, state);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"comment\": {\n\t\t\tformatStyleCommentNode(node, state);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tconsole.log(\"Unknown style node type: \" + node.type);\n\t\t}\n\t}\n}\n\nfunction formatStyleBlockNode(node: any, state: FormatState) {\n\tconst indent = \"\\t\".repeat(state.indent);\n\n\tstate.output += `\\n${indent}${node.selector} {`;\n\tfor (let c of node.children) {\n\t\tstate.indent++;\n\t\tformatStyleNode(c, state);\n\t\tstate.indent--;\n\t}\n\n\tstate.output += `\\n${indent}}`;\n}\n\nfunction formatStyleAttributeNode(node: any, state: FormatState) {\n\tconst indent = \"\\t\".repeat(state.indent);\n\tstate.output += `\\n${indent}${node.name}: ${node.value};`;\n}\n\nfunction formatStyleCommentNode(node: any, state: FormatState) {\n\tconst indent = \"\\t\".repeat(state.indent);\n\tstate.output += `\\n${indent}${node.content}`;\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@torpor/prettier",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A Prettier plugin for Torpor files",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.mts",
|
|
9
|
+
"import": "./dist/index.mjs",
|
|
10
|
+
"default": "./dist/index.mjs"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"check": "tsgo --noEmit && pnpm dlx oxlint --type-aware",
|
|
21
|
+
"build": "tsgo --noEmit && vp pack",
|
|
22
|
+
"build:watch": "vp pack --watch",
|
|
23
|
+
"test": "vp test"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [],
|
|
26
|
+
"author": "",
|
|
27
|
+
"license": "ISC",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@torpor/view": "workspace:^",
|
|
30
|
+
"prettier": "^3.9.6"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
34
|
+
"tsx": "^4.23.5",
|
|
35
|
+
"vite": "catalog:",
|
|
36
|
+
"vite-plus": "catalog:"
|
|
37
|
+
}
|
|
38
|
+
}
|