prettier-plugin-astro 0.14.1 → 1.0.0-beta.1
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 +22 -4
- package/dist/index.js +938 -690
- package/dist/index.js.map +1 -1
- package/package.json +47 -41
package/dist/index.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import { parse } from '@astrojs/compiler
|
|
2
|
-
import
|
|
3
|
-
import 'prettier';
|
|
4
|
-
import { serialize } from '@astrojs/compiler/utils';
|
|
5
|
-
import _doc from 'prettier/doc';
|
|
6
|
-
import { Buffer } from 'node:buffer';
|
|
1
|
+
import { parse as parse$1 } from '@astrojs/compiler-rs';
|
|
2
|
+
import { doc } from 'prettier';
|
|
3
|
+
import { printers as printers$1 } from 'prettier/plugins/estree';
|
|
7
4
|
import { SassFormatter } from 'sass-formatter';
|
|
8
5
|
|
|
9
6
|
const options = {
|
|
@@ -19,9 +16,114 @@ const options = {
|
|
|
19
16
|
default: false,
|
|
20
17
|
description: 'Skips the formatting of the frontmatter.',
|
|
21
18
|
},
|
|
19
|
+
astroCompressHTML: {
|
|
20
|
+
category: 'Astro',
|
|
21
|
+
type: 'choice',
|
|
22
|
+
default: 'jsx',
|
|
23
|
+
description: "Mirror of Astro's compressHTML config. Tells the formatter which whitespace the compiler will collapse.",
|
|
24
|
+
choices: [
|
|
25
|
+
{
|
|
26
|
+
value: 'jsx',
|
|
27
|
+
description: "Astro's default since 7.0.0. Whitespace runs containing a newline are dropped; same-line spaces are content.",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
value: 'html',
|
|
31
|
+
description: 'Browser HTML whitespace rules. Equivalent to compressHTML: true.',
|
|
32
|
+
},
|
|
33
|
+
{ value: 'none', description: 'No collapsing. Equivalent to compressHTML: false.' },
|
|
34
|
+
{ value: true, redirect: 'html' },
|
|
35
|
+
{ value: false, redirect: 'none' },
|
|
36
|
+
],
|
|
37
|
+
},
|
|
22
38
|
};
|
|
23
39
|
|
|
24
|
-
const
|
|
40
|
+
const synthetic = Symbol.for('prettier-plugin-astro.synthetic');
|
|
41
|
+
const ownChildren = Symbol.for('prettier-plugin-astro.ownChildren');
|
|
42
|
+
const astroVisitorKeys = {
|
|
43
|
+
AstroRoot: ['frontmatter', 'template'],
|
|
44
|
+
AstroFrontmatter: ['program'],
|
|
45
|
+
AstroScript: ['program'],
|
|
46
|
+
AstroDoctype: [],
|
|
47
|
+
AstroComment: [],
|
|
48
|
+
};
|
|
49
|
+
const isNode = (value) => typeof value === 'object' && value !== null && typeof value.type === 'string';
|
|
50
|
+
function tagNameOf(node) {
|
|
51
|
+
if (node.type !== 'JSXElement')
|
|
52
|
+
return null;
|
|
53
|
+
const name = node.openingElement?.name;
|
|
54
|
+
return name?.type === 'JSXIdentifier' ? name.name : null;
|
|
55
|
+
}
|
|
56
|
+
const isComponentName = (name) => name === null || /^[A-Z]/.test(name) || name.includes('.');
|
|
57
|
+
function attributesOf(node) {
|
|
58
|
+
const opening = node.openingElement;
|
|
59
|
+
return opening?.attributes ?? [];
|
|
60
|
+
}
|
|
61
|
+
function attributeNamed(node, name) {
|
|
62
|
+
return attributesOf(node).find((attribute) => attribute.type === 'JSXAttribute' && attribute.name.name === name);
|
|
63
|
+
}
|
|
64
|
+
function attributeStringValue(node, name) {
|
|
65
|
+
const value = attributeNamed(node, name)?.value;
|
|
66
|
+
return value?.type === 'Literal' && typeof value.value === 'string' ? value.value : null;
|
|
67
|
+
}
|
|
68
|
+
const hasAttribute = (node, name) => attributeNamed(node, name) !== undefined;
|
|
69
|
+
const hasSetDirective = (node) => hasAttribute(node, 'set:html') || hasAttribute(node, 'set:text');
|
|
70
|
+
function childrenOf(node) {
|
|
71
|
+
if (node.type === 'JSXElement' || node.type === 'JSXFragment') {
|
|
72
|
+
return node.astroChildren ?? node.children;
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
function takeOverChildren(node) {
|
|
77
|
+
const children = node.children;
|
|
78
|
+
if (children.length === 0)
|
|
79
|
+
return;
|
|
80
|
+
node.astroChildren = children;
|
|
81
|
+
node.children = [
|
|
82
|
+
{
|
|
83
|
+
type: 'JSXExpressionContainer',
|
|
84
|
+
start: node.start,
|
|
85
|
+
end: node.end,
|
|
86
|
+
[ownChildren]: true,
|
|
87
|
+
expression: {
|
|
88
|
+
type: 'TemplateLiteral',
|
|
89
|
+
start: node.start,
|
|
90
|
+
end: node.end,
|
|
91
|
+
quasis: [],
|
|
92
|
+
expressions: [],
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
function walk(node, visit) {
|
|
98
|
+
if (Array.isArray(node)) {
|
|
99
|
+
for (const item of node)
|
|
100
|
+
walk(item, visit);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (!isNode(node))
|
|
104
|
+
return;
|
|
105
|
+
visit(node);
|
|
106
|
+
for (const key of Object.keys(node)) {
|
|
107
|
+
if (key !== 'type')
|
|
108
|
+
walk(node[key], visit);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const rawTextElements = new Set([
|
|
113
|
+
'pre',
|
|
114
|
+
'listing',
|
|
115
|
+
'iframe',
|
|
116
|
+
'noembed',
|
|
117
|
+
'noframes',
|
|
118
|
+
'math',
|
|
119
|
+
'plaintext',
|
|
120
|
+
'script',
|
|
121
|
+
'style',
|
|
122
|
+
'textarea',
|
|
123
|
+
'title',
|
|
124
|
+
'xmp',
|
|
125
|
+
]);
|
|
126
|
+
const voidElements = new Set([
|
|
25
127
|
'area',
|
|
26
128
|
'base',
|
|
27
129
|
'basefont',
|
|
@@ -42,267 +144,692 @@ const selfClosingTags = [
|
|
|
42
144
|
'meta',
|
|
43
145
|
'nextid',
|
|
44
146
|
'param',
|
|
45
|
-
'slot',
|
|
46
147
|
'source',
|
|
47
148
|
'track',
|
|
48
149
|
'wbr',
|
|
49
|
-
];
|
|
50
|
-
const
|
|
51
|
-
'
|
|
52
|
-
'
|
|
53
|
-
'
|
|
54
|
-
'
|
|
55
|
-
'
|
|
56
|
-
'
|
|
57
|
-
'
|
|
58
|
-
'
|
|
59
|
-
'
|
|
60
|
-
'
|
|
61
|
-
'
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
'
|
|
68
|
-
'
|
|
69
|
-
'
|
|
70
|
-
'
|
|
71
|
-
'
|
|
72
|
-
'
|
|
73
|
-
'
|
|
74
|
-
'
|
|
75
|
-
'
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
'
|
|
79
|
-
'
|
|
80
|
-
'
|
|
81
|
-
'
|
|
82
|
-
'
|
|
83
|
-
'
|
|
84
|
-
'
|
|
85
|
-
'
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
150
|
+
]);
|
|
151
|
+
const cssDisplay = {
|
|
152
|
+
area: 'none',
|
|
153
|
+
base: 'none',
|
|
154
|
+
basefont: 'none',
|
|
155
|
+
datalist: 'none',
|
|
156
|
+
head: 'none',
|
|
157
|
+
link: 'none',
|
|
158
|
+
meta: 'none',
|
|
159
|
+
noembed: 'none',
|
|
160
|
+
noframes: 'none',
|
|
161
|
+
param: 'block',
|
|
162
|
+
rp: 'none',
|
|
163
|
+
script: 'block',
|
|
164
|
+
style: 'none',
|
|
165
|
+
template: 'inline',
|
|
166
|
+
title: 'none',
|
|
167
|
+
html: 'block',
|
|
168
|
+
body: 'block',
|
|
169
|
+
address: 'block',
|
|
170
|
+
blockquote: 'block',
|
|
171
|
+
center: 'block',
|
|
172
|
+
dialog: 'block',
|
|
173
|
+
div: 'block',
|
|
174
|
+
figure: 'block',
|
|
175
|
+
figcaption: 'block',
|
|
176
|
+
footer: 'block',
|
|
177
|
+
form: 'block',
|
|
178
|
+
header: 'block',
|
|
179
|
+
hr: 'block',
|
|
180
|
+
legend: 'block',
|
|
181
|
+
listing: 'block',
|
|
182
|
+
main: 'block',
|
|
183
|
+
p: 'block',
|
|
184
|
+
plaintext: 'block',
|
|
185
|
+
pre: 'block',
|
|
186
|
+
search: 'block',
|
|
187
|
+
xmp: 'block',
|
|
188
|
+
slot: 'contents',
|
|
189
|
+
ruby: 'ruby',
|
|
190
|
+
rt: 'ruby-text',
|
|
191
|
+
article: 'block',
|
|
192
|
+
aside: 'block',
|
|
193
|
+
h1: 'block',
|
|
194
|
+
h2: 'block',
|
|
195
|
+
h3: 'block',
|
|
196
|
+
h4: 'block',
|
|
197
|
+
h5: 'block',
|
|
198
|
+
h6: 'block',
|
|
199
|
+
hgroup: 'block',
|
|
200
|
+
nav: 'block',
|
|
201
|
+
section: 'block',
|
|
202
|
+
dir: 'block',
|
|
203
|
+
dd: 'block',
|
|
204
|
+
dl: 'block',
|
|
205
|
+
dt: 'block',
|
|
206
|
+
menu: 'block',
|
|
207
|
+
ol: 'block',
|
|
208
|
+
ul: 'block',
|
|
209
|
+
li: 'list-item',
|
|
210
|
+
table: 'table',
|
|
211
|
+
caption: 'table-caption',
|
|
212
|
+
colgroup: 'table-column-group',
|
|
213
|
+
col: 'table-column',
|
|
214
|
+
thead: 'table-header-group',
|
|
215
|
+
tbody: 'table-row-group',
|
|
216
|
+
tfoot: 'table-footer-group',
|
|
217
|
+
tr: 'table-row',
|
|
218
|
+
td: 'table-cell',
|
|
219
|
+
th: 'table-cell',
|
|
220
|
+
input: 'inline-block',
|
|
221
|
+
button: 'inline-block',
|
|
222
|
+
fieldset: 'block',
|
|
223
|
+
details: 'block',
|
|
224
|
+
summary: 'block',
|
|
225
|
+
marquee: 'inline-block',
|
|
226
|
+
source: 'block',
|
|
227
|
+
track: 'block',
|
|
228
|
+
meter: 'inline-block',
|
|
229
|
+
progress: 'inline-block',
|
|
230
|
+
object: 'inline-block',
|
|
231
|
+
video: 'inline-block',
|
|
232
|
+
audio: 'inline-block',
|
|
233
|
+
select: 'inline-block',
|
|
234
|
+
option: 'block',
|
|
235
|
+
optgroup: 'block',
|
|
133
236
|
};
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
function isTextNodeStartingWithLinebreak(node, nrLines = 1) {
|
|
138
|
-
return startsWithLinebreak(getUnencodedText(node), nrLines);
|
|
237
|
+
const inlineLevel = new Set(['inline', 'inline-block', 'ruby', 'ruby-text', 'contents']);
|
|
238
|
+
function displayOfTag(tag) {
|
|
239
|
+
return cssDisplay[tag] ?? 'inline';
|
|
139
240
|
}
|
|
140
|
-
function
|
|
141
|
-
return
|
|
241
|
+
function isInlineDisplay(display) {
|
|
242
|
+
return inlineLevel.has(display);
|
|
142
243
|
}
|
|
143
|
-
|
|
144
|
-
|
|
244
|
+
|
|
245
|
+
function manualDedent(input) {
|
|
246
|
+
let minTabSize = Infinity;
|
|
247
|
+
let result = input;
|
|
248
|
+
result = result.replace(/\r\n/g, '\n');
|
|
249
|
+
let char = '';
|
|
250
|
+
for (const line of result.split('\n')) {
|
|
251
|
+
if (!line)
|
|
252
|
+
continue;
|
|
253
|
+
if (line[0] && /^\S/.test(line[0])) {
|
|
254
|
+
minTabSize = 0;
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
const match = /^(\s+)\S+/.exec(line);
|
|
258
|
+
if (match) {
|
|
259
|
+
if (match[1] && !char)
|
|
260
|
+
char = match[1][0];
|
|
261
|
+
if (match[1].length < minTabSize)
|
|
262
|
+
minTabSize = match[1].length;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (minTabSize > 0 && Number.isFinite(minTabSize)) {
|
|
266
|
+
result = result.replace(new RegExp(`^${new Array(minTabSize + 1).join(char)}`, 'gm'), '');
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
tabSize: minTabSize === Infinity ? 0 : minTabSize,
|
|
270
|
+
char,
|
|
271
|
+
result,
|
|
272
|
+
};
|
|
145
273
|
}
|
|
146
|
-
function
|
|
147
|
-
|
|
274
|
+
function printClassNames(value) {
|
|
275
|
+
const lines = value.trim().split(/[\r\n]+/);
|
|
276
|
+
const formattedLines = lines.map((line) => {
|
|
277
|
+
const spaces = /^\s+/.exec(line);
|
|
278
|
+
return (spaces ? spaces[0] : '') + line.trim().split(/\s+/).join(' ');
|
|
279
|
+
});
|
|
280
|
+
return formattedLines.join('\n');
|
|
148
281
|
}
|
|
149
|
-
|
|
150
|
-
|
|
282
|
+
|
|
283
|
+
const leadingWhitespace$1 = /^[\t\n\f\r ]+/;
|
|
284
|
+
const trailingWhitespace$1 = /[\t\n\f\r ]+$/;
|
|
285
|
+
const hasNewline = (run) => /[\n\r]/.test(run);
|
|
286
|
+
const isText = (node) => node?.type === 'JSXText';
|
|
287
|
+
const rawTextOf = (node) => node.raw ?? '';
|
|
288
|
+
const isWhitespaceOnly = (node) => isText(node) && rawTextOf(node).trim().length === 0;
|
|
289
|
+
function opensRawSubtree(node) {
|
|
290
|
+
if (node.type !== 'JSXElement')
|
|
291
|
+
return false;
|
|
292
|
+
if (hasAttribute(node, 'is:raw'))
|
|
293
|
+
return true;
|
|
294
|
+
const tag = tagNameOf(node);
|
|
295
|
+
return tag !== null && !isComponentName(tag) && rawTextElements.has(tag);
|
|
151
296
|
}
|
|
152
|
-
|
|
153
|
-
|
|
297
|
+
const isExtractedStyle = (node) => node !== null && tagNameOf(node) === 'style' && !hasAttribute(node, 'is:inline');
|
|
298
|
+
function displayOf(node) {
|
|
299
|
+
if (node.type !== 'JSXElement')
|
|
300
|
+
return 'inline';
|
|
301
|
+
const tag = tagNameOf(node);
|
|
302
|
+
if (tag === null || isComponentName(tag) || tag.includes('-'))
|
|
303
|
+
return 'inline';
|
|
304
|
+
return displayOfTag(tag);
|
|
154
305
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
306
|
+
const isBlankRun = (run) => /[\n\r][^\S\n\r]*[\n\r]/.test(run);
|
|
307
|
+
function sidesFor(boundary) {
|
|
308
|
+
if (boundary.edge)
|
|
309
|
+
return [null];
|
|
310
|
+
const sides = [];
|
|
311
|
+
if (boundary.prev === null)
|
|
312
|
+
sides.push(null);
|
|
313
|
+
else if (boundary.prev.type !== 'JSXText')
|
|
314
|
+
sides.push(boundary.prev);
|
|
315
|
+
if (boundary.next === null)
|
|
316
|
+
sides.push(null);
|
|
317
|
+
else if (boundary.next.type !== 'JSXText')
|
|
318
|
+
sides.push(boundary.next);
|
|
319
|
+
return sides.length > 0 ? sides : null;
|
|
158
320
|
}
|
|
159
|
-
function
|
|
160
|
-
|
|
321
|
+
function blankContentIsFree(container, isRoot, settings) {
|
|
322
|
+
const tag = container.type === 'JSXElement' ? tagNameOf(container) : null;
|
|
323
|
+
if (tag === 'slot')
|
|
161
324
|
return false;
|
|
162
|
-
|
|
163
|
-
if (!isNodeWithChildren(node)) {
|
|
325
|
+
if (tag !== null && !isComponentName(tag) && tag.includes('-'))
|
|
164
326
|
return false;
|
|
327
|
+
const boundary = {
|
|
328
|
+
container,
|
|
329
|
+
context: { ...settings, isRoot, inRaw: false },
|
|
330
|
+
prev: null,
|
|
331
|
+
next: null,
|
|
332
|
+
sides: [null],
|
|
333
|
+
atStart: true,
|
|
334
|
+
atEnd: true,
|
|
335
|
+
loneChild: true,
|
|
336
|
+
};
|
|
337
|
+
return isFree(boundary) || mayAlterRenderedWhitespace(boundary);
|
|
338
|
+
}
|
|
339
|
+
function separatorFor(run, boundary, settings) {
|
|
340
|
+
const sides = sidesFor(boundary);
|
|
341
|
+
const internal = {
|
|
342
|
+
container: boundary.container,
|
|
343
|
+
context: { ...settings, isRoot: boundary.isRoot, inRaw: false },
|
|
344
|
+
prev: boundary.prev,
|
|
345
|
+
next: boundary.next,
|
|
346
|
+
sides: sides ?? [],
|
|
347
|
+
atStart: boundary.prev === null,
|
|
348
|
+
atEnd: boundary.next === null,
|
|
349
|
+
loneChild: boundary.loneChild,
|
|
350
|
+
};
|
|
351
|
+
if (isSlotFallback(internal))
|
|
352
|
+
return run === '' ? 'none' : 'space';
|
|
353
|
+
const free = isFree(internal) || (sides !== null && mayAlterRenderedWhitespace(internal));
|
|
354
|
+
if (boundary.edge) {
|
|
355
|
+
if (free)
|
|
356
|
+
return 'soft';
|
|
357
|
+
return run === '' ? 'none' : 'space';
|
|
165
358
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
359
|
+
if (isBlankRun(run))
|
|
360
|
+
return 'blank';
|
|
361
|
+
if (hasNewline(run))
|
|
362
|
+
return 'break';
|
|
363
|
+
if (free)
|
|
364
|
+
return 'soft';
|
|
365
|
+
return run === '' ? 'none' : 'space';
|
|
366
|
+
}
|
|
367
|
+
function normalizeWhitespace(template, options) {
|
|
368
|
+
visit(template, { ...options, isRoot: true, inRaw: false });
|
|
369
|
+
}
|
|
370
|
+
function visit(container, context) {
|
|
371
|
+
const children = childrenOf(container);
|
|
372
|
+
if (children === null)
|
|
373
|
+
return;
|
|
374
|
+
if (!context.inRaw)
|
|
375
|
+
collapseRuns(container, children, context);
|
|
376
|
+
for (const child of children) {
|
|
377
|
+
visit(child, {
|
|
378
|
+
...context,
|
|
379
|
+
isRoot: false,
|
|
380
|
+
inRaw: context.inRaw || opensRawSubtree(child),
|
|
381
|
+
});
|
|
169
382
|
}
|
|
170
|
-
const firstChild = children[0];
|
|
171
|
-
return !isTextNodeStartingWithWhitespace(firstChild);
|
|
172
383
|
}
|
|
173
|
-
function
|
|
174
|
-
|
|
175
|
-
|
|
384
|
+
function collapseRuns(container, children, context) {
|
|
385
|
+
const dropped = new Set();
|
|
386
|
+
for (const [index, child] of children.entries()) {
|
|
387
|
+
if (!isText(child))
|
|
388
|
+
continue;
|
|
389
|
+
const prev = children[index - 1] ?? null;
|
|
390
|
+
const next = children[index + 1] ?? null;
|
|
391
|
+
if (isWhitespaceOnly(child)) {
|
|
392
|
+
const decision = decide(rawTextOf(child), {
|
|
393
|
+
container,
|
|
394
|
+
context,
|
|
395
|
+
prev,
|
|
396
|
+
next,
|
|
397
|
+
sides: [prev, next],
|
|
398
|
+
atStart: prev === null,
|
|
399
|
+
atEnd: next === null,
|
|
400
|
+
loneChild: children.length === 1,
|
|
401
|
+
});
|
|
402
|
+
const text = resolve(rawTextOf(child), decision);
|
|
403
|
+
if (text === '')
|
|
404
|
+
dropped.add(child);
|
|
405
|
+
else
|
|
406
|
+
setText(child, text);
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
const raw = rawTextOf(child);
|
|
410
|
+
const lead = leadingWhitespace$1.exec(raw)?.[0] ?? '';
|
|
411
|
+
const trail = trailingWhitespace$1.exec(raw)?.[0] ?? '';
|
|
412
|
+
const body = raw.slice(lead.length, raw.length - trail.length);
|
|
413
|
+
const leadDecision = decide(lead, {
|
|
414
|
+
container,
|
|
415
|
+
context,
|
|
416
|
+
prev,
|
|
417
|
+
next: child,
|
|
418
|
+
sides: [prev],
|
|
419
|
+
atStart: prev === null,
|
|
420
|
+
atEnd: false,
|
|
421
|
+
loneChild: false,
|
|
422
|
+
});
|
|
423
|
+
const trailDecision = decide(trail, {
|
|
424
|
+
container,
|
|
425
|
+
context,
|
|
426
|
+
prev: child,
|
|
427
|
+
next,
|
|
428
|
+
sides: [next],
|
|
429
|
+
atStart: false,
|
|
430
|
+
atEnd: next === null,
|
|
431
|
+
loneChild: false,
|
|
432
|
+
});
|
|
433
|
+
setText(child, resolve(lead, leadDecision) + body + resolve(trail, trailDecision));
|
|
176
434
|
}
|
|
177
|
-
if (
|
|
178
|
-
|
|
435
|
+
if (dropped.size > 0) {
|
|
436
|
+
const kept = children.filter((child) => !dropped.has(child));
|
|
437
|
+
children.length = 0;
|
|
438
|
+
children.push(...kept);
|
|
179
439
|
}
|
|
180
|
-
|
|
181
|
-
|
|
440
|
+
}
|
|
441
|
+
function resolve(run, decision) {
|
|
442
|
+
if (decision === 'drop')
|
|
443
|
+
return hasNewline(run) ? run : '';
|
|
444
|
+
if (decision === 'space')
|
|
445
|
+
return ' ';
|
|
446
|
+
return run;
|
|
447
|
+
}
|
|
448
|
+
function setText(node, text) {
|
|
449
|
+
node.raw = text;
|
|
450
|
+
node.value = text;
|
|
451
|
+
}
|
|
452
|
+
function decide(run, boundary) {
|
|
453
|
+
if (run === '')
|
|
454
|
+
return 'keep';
|
|
455
|
+
const { mode } = boundary.context;
|
|
456
|
+
if (isSlotFallback(boundary))
|
|
457
|
+
return 'space';
|
|
458
|
+
if (isFree(boundary))
|
|
459
|
+
return 'drop';
|
|
460
|
+
if (mayAlterRenderedWhitespace(boundary))
|
|
461
|
+
return 'drop';
|
|
462
|
+
if (mode === 'jsx')
|
|
463
|
+
return hasNewline(run) ? 'keep' : 'space';
|
|
464
|
+
return boundary.atStart || boundary.atEnd ? 'space' : 'keep';
|
|
465
|
+
}
|
|
466
|
+
function isFree(boundary) {
|
|
467
|
+
const { container, context, atStart, atEnd, loneChild } = boundary;
|
|
468
|
+
const { mode } = context;
|
|
469
|
+
if (context.isRoot && (atStart || atEnd))
|
|
182
470
|
return true;
|
|
183
|
-
|
|
184
|
-
const lastChild = children[children.length - 1];
|
|
185
|
-
if (isExpressionNode(lastChild))
|
|
471
|
+
if (container.type === 'JSXElement' && hasSetDirective(container))
|
|
186
472
|
return true;
|
|
187
|
-
if (
|
|
473
|
+
if (isExtractedStyle(boundary.prev) || isExtractedStyle(boundary.next))
|
|
188
474
|
return true;
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
475
|
+
const tag = container.type === 'JSXElement' ? tagNameOf(container) : null;
|
|
476
|
+
if (loneChild && tag !== null && isComponentName(tag))
|
|
477
|
+
return true;
|
|
478
|
+
if (mode === 'html') {
|
|
479
|
+
if (loneChild)
|
|
480
|
+
return true;
|
|
481
|
+
if (tag === 'head')
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
return false;
|
|
196
485
|
}
|
|
197
|
-
function
|
|
198
|
-
const
|
|
199
|
-
if (
|
|
486
|
+
function mayAlterRenderedWhitespace(boundary) {
|
|
487
|
+
const { sensitivity } = boundary.context;
|
|
488
|
+
if (sensitivity === 'ignore')
|
|
489
|
+
return true;
|
|
490
|
+
if (sensitivity === 'strict')
|
|
200
491
|
return false;
|
|
201
|
-
|
|
202
|
-
const children = getChildren(parent);
|
|
203
|
-
const lastChild = children[children.length - 1];
|
|
204
|
-
return lastChild === path.getNode();
|
|
492
|
+
return boundary.sides.every((side) => !isInlineDisplay(displayOf(side ?? boundary.container)));
|
|
205
493
|
}
|
|
206
|
-
function
|
|
207
|
-
|
|
494
|
+
function isSlotFallback(boundary) {
|
|
495
|
+
return (boundary.container.type === 'JSXElement' &&
|
|
496
|
+
tagNameOf(boundary.container) === 'slot' &&
|
|
497
|
+
boundary.loneChild);
|
|
208
498
|
}
|
|
209
|
-
|
|
210
|
-
|
|
499
|
+
|
|
500
|
+
function parse(source, options) {
|
|
501
|
+
const { ast, diagnostics } = parse$1(source);
|
|
502
|
+
const failure = diagnostics.find((diagnostic) => diagnostic.severity === 'error');
|
|
503
|
+
if (failure)
|
|
504
|
+
throw syntaxError(failure);
|
|
505
|
+
stripParentheses(ast);
|
|
506
|
+
repairSpans(ast);
|
|
507
|
+
markAttributes(ast, source);
|
|
508
|
+
applyPrettierIgnore(ast);
|
|
509
|
+
const body = ast.body;
|
|
510
|
+
const template = templateFragment(ast, body);
|
|
511
|
+
const settings = {
|
|
512
|
+
mode: options.astroCompressHTML,
|
|
513
|
+
sensitivity: options.htmlWhitespaceSensitivity,
|
|
514
|
+
};
|
|
515
|
+
if (settings.mode === 'jsx')
|
|
516
|
+
normalizeWhitespace(template.node, settings);
|
|
517
|
+
else
|
|
518
|
+
resolveBlankContainers(template.node, settings);
|
|
519
|
+
normalizeTagPairs(body, source);
|
|
520
|
+
if (settings.mode !== 'jsx')
|
|
521
|
+
claimChildren(template.node);
|
|
522
|
+
ast.template = template;
|
|
523
|
+
delete ast.body;
|
|
524
|
+
ast.comments = printableComments(ast);
|
|
525
|
+
return ast;
|
|
211
526
|
}
|
|
212
|
-
function
|
|
213
|
-
const
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
527
|
+
function syntaxError(diagnostic) {
|
|
528
|
+
const label = diagnostic.labels[0];
|
|
529
|
+
const line = label?.line ?? 1;
|
|
530
|
+
const column = (label?.column ?? 0) + 1;
|
|
531
|
+
const error = new SyntaxError(`${diagnostic.text} (${line}:${column})`);
|
|
532
|
+
error.loc = { start: { line, column } };
|
|
533
|
+
return error;
|
|
534
|
+
}
|
|
535
|
+
function stripParentheses(root) {
|
|
536
|
+
walk(root, (node) => {
|
|
537
|
+
for (const key of Object.keys(node)) {
|
|
538
|
+
const value = node[key];
|
|
539
|
+
if (Array.isArray(value)) {
|
|
540
|
+
for (const [index, item] of value.entries()) {
|
|
541
|
+
value[index] = unwrapParens(item);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
else if (isNode(value)) {
|
|
545
|
+
node[key] = unwrapParens(value);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
217
548
|
});
|
|
218
|
-
return formattedLines.join('\n');
|
|
219
549
|
}
|
|
220
|
-
function
|
|
221
|
-
let
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (line[0] && /^[^\s]/.test(line[0])) {
|
|
229
|
-
minTabSize = 0;
|
|
550
|
+
function unwrapParens(node) {
|
|
551
|
+
let current = node;
|
|
552
|
+
while (isNode(current)) {
|
|
553
|
+
if (current.type === 'ParenthesizedExpression')
|
|
554
|
+
current = current.expression;
|
|
555
|
+
else if (current.type === 'TSParenthesizedType')
|
|
556
|
+
current = current.typeAnnotation;
|
|
557
|
+
else
|
|
230
558
|
break;
|
|
559
|
+
}
|
|
560
|
+
return current;
|
|
561
|
+
}
|
|
562
|
+
function repairSpans(root) {
|
|
563
|
+
walk(root, (node) => {
|
|
564
|
+
if (node.type !== 'JSXElement')
|
|
565
|
+
return;
|
|
566
|
+
const script = node.children.find((child) => child.type === 'AstroScript');
|
|
567
|
+
if (!script)
|
|
568
|
+
return;
|
|
569
|
+
script.start = node.openingElement.end;
|
|
570
|
+
script.end = node.closingElement?.start ?? node.end;
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
function markAttributes(root, source) {
|
|
574
|
+
walk(root, (node) => {
|
|
575
|
+
if (node.type !== 'JSXAttribute')
|
|
576
|
+
return;
|
|
577
|
+
const value = node.value;
|
|
578
|
+
if (!value)
|
|
579
|
+
return;
|
|
580
|
+
if (value.type === 'Literal' && typeof value.value === 'string') {
|
|
581
|
+
const name = node.name.name;
|
|
582
|
+
const text = name === 'class' ? printClassNames(value.value) : value.value;
|
|
583
|
+
if (value.raw === null || text !== value.value) {
|
|
584
|
+
value.value = text;
|
|
585
|
+
value.raw = `"${text.replaceAll('"', '"')}"`;
|
|
586
|
+
}
|
|
587
|
+
return;
|
|
231
588
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
589
|
+
if (value.type !== 'JSXExpressionContainer')
|
|
590
|
+
return;
|
|
591
|
+
if (source[node.start] === '{')
|
|
592
|
+
node.astroShorthand = true;
|
|
593
|
+
if (source[value.start] === '`')
|
|
594
|
+
node.astroBacktick = true;
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
function applyPrettierIgnore(root) {
|
|
598
|
+
walk(root, (node) => {
|
|
599
|
+
const children = node.type === 'AstroRoot' ? node.body : childrenOf(node);
|
|
600
|
+
if (children === null)
|
|
601
|
+
return;
|
|
602
|
+
for (const [index, child] of children.entries()) {
|
|
603
|
+
if (child.type !== 'AstroComment')
|
|
604
|
+
continue;
|
|
605
|
+
if (String(child.value).trim() !== 'prettier-ignore')
|
|
606
|
+
continue;
|
|
607
|
+
const target = children.slice(index + 1).find((sibling) => sibling.type !== 'JSXText');
|
|
608
|
+
if (target)
|
|
609
|
+
target.astroIgnored = true;
|
|
238
610
|
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
function templateFragment(root, body) {
|
|
614
|
+
const start = body[0]?.start ?? root.end;
|
|
615
|
+
const end = body.at(-1)?.end ?? root.end;
|
|
243
616
|
return {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
617
|
+
type: 'JsExpressionRoot',
|
|
618
|
+
start,
|
|
619
|
+
end,
|
|
620
|
+
node: {
|
|
621
|
+
type: 'JSXFragment',
|
|
622
|
+
start,
|
|
623
|
+
end,
|
|
624
|
+
astroRoot: true,
|
|
625
|
+
openingFragment: { type: 'JSXOpeningFragment', start, end: start, [synthetic]: true },
|
|
626
|
+
children: body,
|
|
627
|
+
closingFragment: { type: 'JSXClosingFragment', start: end, end, [synthetic]: true },
|
|
628
|
+
},
|
|
247
629
|
};
|
|
248
630
|
}
|
|
249
|
-
function
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if (
|
|
276
|
-
|
|
631
|
+
function pairUp(node, tag) {
|
|
632
|
+
node.openingElement.selfClosing = false;
|
|
633
|
+
node.closingElement = {
|
|
634
|
+
type: 'JSXClosingElement',
|
|
635
|
+
start: node.end,
|
|
636
|
+
end: node.end,
|
|
637
|
+
name: { type: 'JSXIdentifier', name: tag, start: node.end, end: node.end },
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
function printsNothing(child) {
|
|
641
|
+
const raw = String(child.raw ?? '');
|
|
642
|
+
return child.type === 'JSXText' && raw.trim() === '' && /[\n\r]/.test(raw);
|
|
643
|
+
}
|
|
644
|
+
function normalizeTagPairs(body, source) {
|
|
645
|
+
walk(body, (node) => {
|
|
646
|
+
if (node.type !== 'JSXElement')
|
|
647
|
+
return;
|
|
648
|
+
const tag = tagNameOf(node);
|
|
649
|
+
if (tag === null)
|
|
650
|
+
return;
|
|
651
|
+
const children = node.children;
|
|
652
|
+
const closing = node.closingElement;
|
|
653
|
+
const component = isComponentName(tag);
|
|
654
|
+
if (rawTextElements.has(tag) && !component) {
|
|
655
|
+
if (!closing)
|
|
656
|
+
pairUp(node, tag);
|
|
657
|
+
else if (source.slice(node.openingElement.end, closing.start).trim() === '') {
|
|
658
|
+
children.length = 0;
|
|
277
659
|
}
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
const selfClosable = component || voidElements.has(tag) || tag === 'slot' || hasSetDirective(node);
|
|
663
|
+
if (children.every(printsNothing) && selfClosable && closing) {
|
|
664
|
+
node.openingElement.selfClosing = true;
|
|
665
|
+
node.closingElement = null;
|
|
278
666
|
}
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
function resolveBlankContainers(template, settings) {
|
|
670
|
+
walk(template, (node) => {
|
|
671
|
+
if (node.type !== 'JSXElement' && node.type !== 'JSXFragment')
|
|
672
|
+
return;
|
|
673
|
+
if (node.type === 'JSXElement' && opensRawSubtree(node))
|
|
674
|
+
return;
|
|
675
|
+
const children = node.children;
|
|
676
|
+
if (children.length === 0)
|
|
677
|
+
return;
|
|
678
|
+
const blank = children.every((child) => child.type === 'JSXText' && String(child.raw ?? '').trim() === '');
|
|
679
|
+
if (!blank)
|
|
680
|
+
return;
|
|
681
|
+
const free = blankContentIsFree(node, node.astroRoot === true, settings);
|
|
682
|
+
children.length = 0;
|
|
683
|
+
if (!free) {
|
|
684
|
+
children.push({ type: 'JSXText', start: node.start, end: node.start, raw: ' ', value: ' ' });
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
function claimChildren(template) {
|
|
689
|
+
walk(template, (node) => {
|
|
690
|
+
if (node.type !== 'JSXElement' && node.type !== 'JSXFragment')
|
|
691
|
+
return;
|
|
692
|
+
if (node.type === 'JSXElement' && opensRawSubtree(node))
|
|
693
|
+
return;
|
|
694
|
+
takeOverChildren(node);
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
function printableComments(root) {
|
|
698
|
+
const comments = root.comments ?? [];
|
|
699
|
+
if (comments.length === 0)
|
|
700
|
+
return comments;
|
|
701
|
+
const frontmatter = root.frontmatter;
|
|
702
|
+
const skipped = [];
|
|
703
|
+
if (frontmatter.end > 0)
|
|
704
|
+
skipped.push([frontmatter.start, frontmatter.end]);
|
|
705
|
+
walk(root, (node) => {
|
|
706
|
+
if (node.astroIgnored) {
|
|
707
|
+
skipped.push([node.start, node.end]);
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
if (!opensRawSubtree(node))
|
|
711
|
+
return;
|
|
712
|
+
const closing = node.closingElement;
|
|
713
|
+
skipped.push([node.openingElement.end, closing?.start ?? node.end]);
|
|
714
|
+
});
|
|
715
|
+
return comments.filter((comment) => !skipped.some(([start, end]) => comment.start >= start && comment.end <= end));
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
const estree = printers$1.estree;
|
|
719
|
+
|
|
720
|
+
const { fill, group: group$1, hardline: hardline$2, indent: indent$1, line, softline } = doc.builders;
|
|
721
|
+
const leadingWhitespace = /^[\t\n\f\r ]+/;
|
|
722
|
+
const trailingWhitespace = /[\t\n\f\r ]+$/;
|
|
723
|
+
const whitespaceRun = /[\t\n\f\r ]+/;
|
|
724
|
+
function docFor(separator) {
|
|
725
|
+
switch (separator) {
|
|
726
|
+
case 'none':
|
|
727
|
+
return null;
|
|
728
|
+
case 'soft':
|
|
729
|
+
return softline;
|
|
730
|
+
case 'space':
|
|
731
|
+
return line;
|
|
732
|
+
case 'break':
|
|
733
|
+
return hardline$2;
|
|
734
|
+
case 'blank':
|
|
735
|
+
return [hardline$2, hardline$2];
|
|
279
736
|
}
|
|
280
|
-
return null;
|
|
281
737
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
738
|
+
function collect(children, docs) {
|
|
739
|
+
const items = [];
|
|
740
|
+
const runs = [];
|
|
741
|
+
let pending = '';
|
|
742
|
+
for (const [index, child] of children.entries()) {
|
|
743
|
+
if (child.type !== 'JSXText') {
|
|
744
|
+
runs.push(pending);
|
|
745
|
+
items.push({ node: child, words: null, doc: docs[index] });
|
|
746
|
+
pending = '';
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
const raw = String(child.raw ?? '');
|
|
750
|
+
if (raw.trim() === '') {
|
|
751
|
+
pending += raw;
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
const lead = leadingWhitespace.exec(raw)?.[0] ?? '';
|
|
755
|
+
const trail = trailingWhitespace.exec(raw)?.[0] ?? '';
|
|
756
|
+
runs.push(pending + lead);
|
|
757
|
+
items.push({
|
|
758
|
+
node: child,
|
|
759
|
+
words: raw.slice(lead.length, raw.length - trail.length).split(whitespaceRun),
|
|
760
|
+
doc: '',
|
|
761
|
+
});
|
|
762
|
+
pending = trail;
|
|
763
|
+
}
|
|
764
|
+
runs.push(pending);
|
|
765
|
+
return { items, runs };
|
|
766
|
+
}
|
|
767
|
+
function printChildren(path, options, print) {
|
|
768
|
+
const container = path.node;
|
|
769
|
+
const docs = [];
|
|
770
|
+
path.each((child) => {
|
|
771
|
+
docs.push(child.node.type === 'JSXText' ? '' : print());
|
|
772
|
+
}, 'astroChildren');
|
|
773
|
+
const { items, runs } = collect(container.astroChildren, docs);
|
|
774
|
+
if (items.length === 0)
|
|
775
|
+
return runs[0] === '' ? '' : ' ';
|
|
776
|
+
const isRoot = container.astroRoot === true;
|
|
777
|
+
const settings = {
|
|
778
|
+
mode: options.astroCompressHTML,
|
|
779
|
+
sensitivity: options.htmlWhitespaceSensitivity,
|
|
780
|
+
};
|
|
781
|
+
const separatorAt = (index, edge) => docFor(separatorFor(runs[index], {
|
|
782
|
+
container,
|
|
783
|
+
prev: items[index - 1]?.node ?? null,
|
|
784
|
+
next: items[index]?.node ?? null,
|
|
785
|
+
isRoot,
|
|
786
|
+
loneChild: false,
|
|
787
|
+
edge,
|
|
788
|
+
}, settings));
|
|
789
|
+
const parts = [''];
|
|
790
|
+
const append = (content) => parts.push([parts.pop(), content]);
|
|
791
|
+
const separate = (separator) => {
|
|
792
|
+
if (separator !== null)
|
|
793
|
+
parts.push(separator, '');
|
|
794
|
+
};
|
|
795
|
+
for (const [position, item] of items.entries()) {
|
|
796
|
+
if (position > 0)
|
|
797
|
+
separate(separatorAt(position, false));
|
|
798
|
+
if (item.words === null) {
|
|
799
|
+
append(item.doc);
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
for (const [wordPosition, word] of item.words.entries()) {
|
|
803
|
+
if (wordPosition > 0)
|
|
804
|
+
separate(line);
|
|
805
|
+
append(word);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
const body = fill(parts);
|
|
809
|
+
if (isRoot)
|
|
810
|
+
return body;
|
|
811
|
+
return group$1([indent$1([separatorAt(0, true) ?? '', body]), separatorAt(items.length, true) ?? '']);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
const { group, hardline: hardline$1, indent, join } = doc.builders;
|
|
815
|
+
const { replaceEndOfLine: replaceEndOfLine$1 } = doc.utils;
|
|
816
|
+
const styleParsers = {
|
|
817
|
+
css: 'css',
|
|
818
|
+
scss: 'scss',
|
|
819
|
+
less: 'less',
|
|
287
820
|
};
|
|
288
|
-
function
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
const numPreferredQuotes = (rawContent.match(preferred.regex) || []).length;
|
|
296
|
-
const numAlternateQuotes = (rawContent.match(alternate.regex) || []).length;
|
|
297
|
-
result = numPreferredQuotes > numAlternateQuotes ? alternate : preferred;
|
|
821
|
+
async function surfacingErrors(textToDoc, text, options) {
|
|
822
|
+
try {
|
|
823
|
+
return await textToDoc(text, options);
|
|
824
|
+
}
|
|
825
|
+
catch (error) {
|
|
826
|
+
process.env.PRETTIER_DEBUG = 'true';
|
|
827
|
+
throw error;
|
|
298
828
|
}
|
|
299
|
-
return result;
|
|
300
829
|
}
|
|
301
830
|
function inferParserByTypeAttribute(type) {
|
|
302
|
-
if (!type) {
|
|
303
|
-
return 'babel-ts';
|
|
304
|
-
}
|
|
305
831
|
switch (type) {
|
|
832
|
+
case null:
|
|
306
833
|
case 'module':
|
|
307
834
|
case 'text/javascript':
|
|
308
835
|
case 'text/babel':
|
|
@@ -323,476 +850,213 @@ function inferParserByTypeAttribute(type) {
|
|
|
323
850
|
return 'babel-ts';
|
|
324
851
|
}
|
|
325
852
|
}
|
|
326
|
-
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
853
|
+
function inferScriptParser(node) {
|
|
854
|
+
const processed = attributesOf(node).every((attribute) => attribute.type === 'JSXAttribute' && attribute.name.name === 'src');
|
|
855
|
+
if (processed)
|
|
856
|
+
return 'babel-ts';
|
|
857
|
+
return inferParserByTypeAttribute(attributeStringValue(node, 'type'));
|
|
858
|
+
}
|
|
859
|
+
function contentOf(node, options) {
|
|
860
|
+
const start = node.openingElement.end;
|
|
861
|
+
const end = node.closingElement?.start ?? node.end;
|
|
862
|
+
return options.originalText.slice(start, end);
|
|
863
|
+
}
|
|
864
|
+
function wrapContent(print, content, isEmpty) {
|
|
865
|
+
return [
|
|
866
|
+
print('openingElement'),
|
|
867
|
+
indent([hardline$1, content]),
|
|
868
|
+
isEmpty ? '' : hardline$1,
|
|
869
|
+
print('closingElement'),
|
|
870
|
+
];
|
|
871
|
+
}
|
|
872
|
+
function embedSass(source, options) {
|
|
873
|
+
const sassOptions = {
|
|
874
|
+
tabSize: options.tabWidth,
|
|
875
|
+
insertSpaces: !options.useTabs,
|
|
876
|
+
lineEnding: options.endOfLine.toUpperCase() === 'CRLF' ? 'CRLF' : 'LF',
|
|
877
|
+
};
|
|
878
|
+
const { result } = manualDedent(source);
|
|
879
|
+
return join(hardline$1, SassFormatter.Format(result, sassOptions).trim().split('\n'));
|
|
880
|
+
}
|
|
881
|
+
function embed(path, options) {
|
|
330
882
|
const node = path.node;
|
|
331
|
-
if (
|
|
332
|
-
return
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
883
|
+
if (node.astroIgnored)
|
|
884
|
+
return undefined;
|
|
885
|
+
if (node.type === 'AstroFrontmatter') {
|
|
886
|
+
if (node.end === 0 || options.astroSkipFrontmatter)
|
|
887
|
+
return undefined;
|
|
888
|
+
const fence = options.originalText.indexOf('---', node.start);
|
|
889
|
+
const source = options.originalText.slice(fence + 3, node.end - 3);
|
|
890
|
+
if (!source.trim())
|
|
891
|
+
return undefined;
|
|
892
|
+
return async (textToDoc) => [
|
|
893
|
+
'---',
|
|
894
|
+
hardline$1,
|
|
895
|
+
await surfacingErrors(textToDoc, source, { ...options, parser: 'babel-ts' }),
|
|
896
|
+
hardline$1,
|
|
897
|
+
'---',
|
|
342
898
|
];
|
|
343
899
|
}
|
|
344
|
-
if (
|
|
345
|
-
return
|
|
900
|
+
if (node.type !== 'JSXElement')
|
|
901
|
+
return estree.embed(path, options);
|
|
902
|
+
const tag = tagNameOf(node);
|
|
903
|
+
if (tag === null || !node.closingElement)
|
|
904
|
+
return estree.embed(path, options);
|
|
905
|
+
const source = contentOf(node, options);
|
|
906
|
+
const isEmpty = source.trim() === '';
|
|
907
|
+
if (tag === 'script') {
|
|
908
|
+
if (isEmpty)
|
|
909
|
+
return estree.embed(path, options);
|
|
910
|
+
const parser = inferScriptParser(node);
|
|
911
|
+
return async (textToDoc, print) => wrapContent(print, await surfacingErrors(textToDoc, source, { ...options, parser }), false);
|
|
346
912
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
return
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
if (isEmptyTextNode(node)) {
|
|
354
|
-
const hasWhiteSpace = rawText.trim().length < getUnencodedText(node).length;
|
|
355
|
-
const hasOneOrMoreNewlines = /\n/.test(getUnencodedText(node));
|
|
356
|
-
const hasTwoOrMoreNewlines = /\n\r?\s*\n\r?/.test(getUnencodedText(node));
|
|
357
|
-
if (hasTwoOrMoreNewlines) {
|
|
358
|
-
return [hardline$1, hardline$1];
|
|
359
|
-
}
|
|
360
|
-
if (hasOneOrMoreNewlines) {
|
|
361
|
-
return hardline$1;
|
|
362
|
-
}
|
|
363
|
-
if (hasWhiteSpace) {
|
|
364
|
-
return line$1;
|
|
365
|
-
}
|
|
366
|
-
return '';
|
|
367
|
-
}
|
|
368
|
-
return fill(splitTextToDocs(node));
|
|
369
|
-
}
|
|
370
|
-
case 'component':
|
|
371
|
-
case 'fragment':
|
|
372
|
-
case 'custom-element':
|
|
373
|
-
case 'element': {
|
|
374
|
-
let isEmpty;
|
|
375
|
-
if (!node.children) {
|
|
376
|
-
isEmpty = true;
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
isEmpty = node.children.every((child) => isEmptyTextNode(child));
|
|
380
|
-
}
|
|
381
|
-
const isSelfClosingTag = isEmpty &&
|
|
382
|
-
(node.type === 'component' ||
|
|
383
|
-
selfClosingTags.includes(node.name) ||
|
|
384
|
-
hasSetDirectives(node));
|
|
385
|
-
const isSingleLinePerAttribute = opts.singleAttributePerLine && node.attributes.length > 1;
|
|
386
|
-
const attributeLine = isSingleLinePerAttribute ? breakParent : '';
|
|
387
|
-
const attributes = join$1(attributeLine, path.map(print, 'attributes'));
|
|
388
|
-
if (isSelfClosingTag) {
|
|
389
|
-
return group$1(['<', node.name, indent$1(attributes), line$1, `/>`]);
|
|
390
|
-
}
|
|
391
|
-
if (node.children) {
|
|
392
|
-
const children = node.children;
|
|
393
|
-
const firstChild = children[0];
|
|
394
|
-
const lastChild = children[children.length - 1];
|
|
395
|
-
let noHugSeparatorStart = softline$1;
|
|
396
|
-
let noHugSeparatorEnd = softline$1;
|
|
397
|
-
const hugStart = shouldHugStart(node, opts);
|
|
398
|
-
const hugEnd = shouldHugEnd(node, opts);
|
|
399
|
-
let body;
|
|
400
|
-
if (isEmpty) {
|
|
401
|
-
body =
|
|
402
|
-
isInlineElement(path, opts, node) &&
|
|
403
|
-
node.children.length &&
|
|
404
|
-
isTextNodeStartingWithWhitespace(node.children[0]) &&
|
|
405
|
-
!isPreTagContent(path)
|
|
406
|
-
? () => line$1
|
|
407
|
-
: () => softline$1;
|
|
408
|
-
}
|
|
409
|
-
else if (isPreTagContent(path)) {
|
|
410
|
-
body = () => printRaw(node);
|
|
411
|
-
}
|
|
412
|
-
else if (isInlineElement(path, opts, node) && !isPreTagContent(path)) {
|
|
413
|
-
body = () => path.map(print, 'children');
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
body = () => path.map(print, 'children');
|
|
417
|
-
}
|
|
418
|
-
const openingTag = [
|
|
419
|
-
'<',
|
|
420
|
-
node.name,
|
|
421
|
-
indent$1(group$1([
|
|
422
|
-
attributes,
|
|
423
|
-
hugStart
|
|
424
|
-
? ''
|
|
425
|
-
: !isPreTagContent(path) && !opts.bracketSameLine
|
|
426
|
-
? dedent(softline$1)
|
|
427
|
-
: '',
|
|
428
|
-
])),
|
|
429
|
-
];
|
|
430
|
-
if (hugStart && hugEnd) {
|
|
431
|
-
const huggedContent = [
|
|
432
|
-
isSingleLinePerAttribute ? hardline$1 : softline$1,
|
|
433
|
-
group$1(['>', body(), `</${node.name}`]),
|
|
434
|
-
];
|
|
435
|
-
const omitSoftlineBeforeClosingTag = isEmpty || canOmitSoftlineBeforeClosingTag(path, opts);
|
|
436
|
-
return group$1([
|
|
437
|
-
...openingTag,
|
|
438
|
-
isEmpty ? group$1(huggedContent) : group$1(indent$1(huggedContent)),
|
|
439
|
-
omitSoftlineBeforeClosingTag ? '' : softline$1,
|
|
440
|
-
'>',
|
|
441
|
-
]);
|
|
442
|
-
}
|
|
443
|
-
if (isPreTagContent(path)) {
|
|
444
|
-
noHugSeparatorStart = '';
|
|
445
|
-
noHugSeparatorEnd = '';
|
|
446
|
-
}
|
|
447
|
-
else {
|
|
448
|
-
let didSetEndSeparator = false;
|
|
449
|
-
if (!hugStart && firstChild && isTextNode(firstChild)) {
|
|
450
|
-
if (isTextNodeStartingWithLinebreak(firstChild) &&
|
|
451
|
-
firstChild !== lastChild &&
|
|
452
|
-
(!isInlineElement(path, opts, node) || isTextNodeEndingWithWhitespace(lastChild))) {
|
|
453
|
-
noHugSeparatorStart = hardline$1;
|
|
454
|
-
noHugSeparatorEnd = hardline$1;
|
|
455
|
-
didSetEndSeparator = true;
|
|
456
|
-
}
|
|
457
|
-
else if (isInlineElement(path, opts, node)) {
|
|
458
|
-
noHugSeparatorStart = line$1;
|
|
459
|
-
}
|
|
460
|
-
trimTextNodeLeft(firstChild);
|
|
461
|
-
}
|
|
462
|
-
if (!hugEnd && lastChild && isTextNode(lastChild)) {
|
|
463
|
-
if (isInlineElement(path, opts, node) && !didSetEndSeparator) {
|
|
464
|
-
noHugSeparatorEnd = line$1;
|
|
465
|
-
}
|
|
466
|
-
trimTextNodeRight(lastChild);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
if (hugStart) {
|
|
470
|
-
return group$1([
|
|
471
|
-
...openingTag,
|
|
472
|
-
indent$1([softline$1, group$1(['>', body()])]),
|
|
473
|
-
noHugSeparatorEnd,
|
|
474
|
-
`</${node.name}>`,
|
|
475
|
-
]);
|
|
476
|
-
}
|
|
477
|
-
if (hugEnd) {
|
|
478
|
-
return group$1([
|
|
479
|
-
...openingTag,
|
|
480
|
-
'>',
|
|
481
|
-
indent$1([noHugSeparatorStart, group$1([body(), `</${node.name}`])]),
|
|
482
|
-
canOmitSoftlineBeforeClosingTag(path, opts) ? '' : softline$1,
|
|
483
|
-
'>',
|
|
484
|
-
]);
|
|
485
|
-
}
|
|
486
|
-
if (isEmpty) {
|
|
487
|
-
return group$1([...openingTag, '>', body(), `</${node.name}>`]);
|
|
488
|
-
}
|
|
489
|
-
return group$1([
|
|
490
|
-
...openingTag,
|
|
491
|
-
'>',
|
|
492
|
-
indent$1([noHugSeparatorStart, body()]),
|
|
493
|
-
noHugSeparatorEnd,
|
|
494
|
-
`</${node.name}>`,
|
|
495
|
-
]);
|
|
496
|
-
}
|
|
497
|
-
return '';
|
|
498
|
-
}
|
|
499
|
-
case 'attribute': {
|
|
500
|
-
const name = node.name.trim();
|
|
501
|
-
switch (node.kind) {
|
|
502
|
-
case 'empty':
|
|
503
|
-
return [line$1, name];
|
|
504
|
-
case 'expression':
|
|
505
|
-
return '';
|
|
506
|
-
case 'quoted':
|
|
507
|
-
let value = node.value;
|
|
508
|
-
if (node.name === 'class') {
|
|
509
|
-
value = printClassNames(value);
|
|
510
|
-
}
|
|
511
|
-
const unescapedValue = value.replace(/'/g, "'").replace(/"/g, '"');
|
|
512
|
-
const { escaped, quote, regex } = getPreferredQuote(unescapedValue, opts.jsxSingleQuote ? "'" : '"');
|
|
513
|
-
const result = unescapedValue.replace(regex, escaped);
|
|
514
|
-
return [line$1, name, '=', quote, result, quote];
|
|
515
|
-
case 'shorthand':
|
|
516
|
-
return [line$1, '{', name, '}'];
|
|
517
|
-
case 'spread':
|
|
518
|
-
return [line$1, '{...', name, '}'];
|
|
519
|
-
case 'template-literal':
|
|
520
|
-
return [line$1, name, '=', '`', node.value, '`'];
|
|
521
|
-
}
|
|
522
|
-
return '';
|
|
523
|
-
}
|
|
524
|
-
case 'doctype': {
|
|
525
|
-
return ['<!doctype html>', hardline$1];
|
|
526
|
-
}
|
|
527
|
-
case 'comment':
|
|
528
|
-
if (isIgnoreDirective(node)) {
|
|
529
|
-
ignoreNext = true;
|
|
530
|
-
}
|
|
531
|
-
const nextNode = getNextNode(path);
|
|
532
|
-
let trailingLine = '';
|
|
533
|
-
if (nextNode && isTagLikeNode(nextNode)) {
|
|
534
|
-
trailingLine = hardline$1;
|
|
535
|
-
}
|
|
536
|
-
return ['<!--', getUnencodedText(node), '-->', trailingLine];
|
|
537
|
-
default: {
|
|
538
|
-
throw new Error(`Unhandled node type "${node.type}"!`);
|
|
913
|
+
if (tag === 'style') {
|
|
914
|
+
if (isEmpty)
|
|
915
|
+
return estree.embed(path, options);
|
|
916
|
+
const lang = attributeStringValue(node, 'lang')?.toLowerCase() ?? 'css';
|
|
917
|
+
if (lang === 'sass') {
|
|
918
|
+
return (_textToDoc, print) => wrapContent(print, embedSass(source, options), false);
|
|
539
919
|
}
|
|
920
|
+
const parser = styleParsers[lang];
|
|
921
|
+
if (!parser)
|
|
922
|
+
return printVerbatim(source);
|
|
923
|
+
return async (textToDoc, print) => wrapContent(print, await surfacingErrors(textToDoc, source, { ...options, parser }), false);
|
|
540
924
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
docs[0] = hardline$1;
|
|
548
|
-
}
|
|
549
|
-
if (startsWithLinebreak(text, 2)) {
|
|
550
|
-
docs = [hardline$1, ...docs];
|
|
551
|
-
}
|
|
552
|
-
if (endsWithLinebreak(text)) {
|
|
553
|
-
docs[docs.length - 1] = hardline$1;
|
|
554
|
-
}
|
|
555
|
-
if (endsWithLinebreak(text, 2)) {
|
|
556
|
-
docs = [...docs, hardline$1];
|
|
925
|
+
if (opensRawSubtree(node)) {
|
|
926
|
+
return (_textToDoc, print) => [
|
|
927
|
+
print('openingElement'),
|
|
928
|
+
replaceEndOfLine$1(source),
|
|
929
|
+
print('closingElement'),
|
|
930
|
+
];
|
|
557
931
|
}
|
|
558
|
-
return
|
|
932
|
+
return estree.embed(path, options);
|
|
933
|
+
}
|
|
934
|
+
function printVerbatim(source) {
|
|
935
|
+
return (_textToDoc, print) => group([print('openingElement'), replaceEndOfLine$1(source), print('closingElement')]);
|
|
559
936
|
}
|
|
560
937
|
|
|
561
|
-
const {
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
const
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
strings.push(doc);
|
|
582
|
-
}
|
|
583
|
-
});
|
|
584
|
-
if (strings.every((value) => value.startsWith('//'))) {
|
|
585
|
-
return group(['{', content, softline, lineSuffixBoundary, '}']);
|
|
586
|
-
}
|
|
587
|
-
const astroDoc = mapDoc(content, (doc) => {
|
|
588
|
-
if (typeof doc === 'string') {
|
|
589
|
-
doc = doc.replaceAll(openingBracketReplace, '{');
|
|
590
|
-
doc = doc.replaceAll(closingBracketReplace, '}');
|
|
591
|
-
doc = doc.replaceAll(atSignReplace, '@');
|
|
592
|
-
doc = doc.replaceAll(dotReplace, '.');
|
|
593
|
-
doc = doc.replaceAll(interrogationReplace, '?');
|
|
594
|
-
}
|
|
595
|
-
return doc;
|
|
596
|
-
});
|
|
597
|
-
return group(['{', indent([softline, astroDoc]), softline, lineSuffixBoundary, '}']);
|
|
598
|
-
}
|
|
599
|
-
if (node.type === 'attribute' && node.kind === 'expression') {
|
|
600
|
-
const value = node.value.trim();
|
|
601
|
-
const name = node.name.trim();
|
|
602
|
-
const attrNodeValue = await wrapParserTryCatch(textToDoc, value, {
|
|
603
|
-
...options,
|
|
604
|
-
parser: 'astroExpressionParser',
|
|
605
|
-
});
|
|
606
|
-
if (name === value && options.astroAllowShorthand) {
|
|
607
|
-
return [line, '{', attrNodeValue, '}'];
|
|
938
|
+
const { hardline } = doc.builders;
|
|
939
|
+
const { replaceEndOfLine } = doc.utils;
|
|
940
|
+
function printDoctype(value) {
|
|
941
|
+
const trimmed = value.trim();
|
|
942
|
+
const space = trimmed.search(/\s/);
|
|
943
|
+
const name = space === -1 ? trimmed : trimmed.slice(0, space);
|
|
944
|
+
const rest = space === -1 ? '' : trimmed.slice(space);
|
|
945
|
+
return `<!doctype ${name.toLowerCase()}${rest}>`;
|
|
946
|
+
}
|
|
947
|
+
function printAstroNode(path, options, print) {
|
|
948
|
+
const node = path.node;
|
|
949
|
+
switch (node.type) {
|
|
950
|
+
case 'AstroRoot': {
|
|
951
|
+
const template = node.template;
|
|
952
|
+
const hasTemplate = template.node.children.length > 0;
|
|
953
|
+
const parts = [];
|
|
954
|
+
if (node.frontmatter.end > 0) {
|
|
955
|
+
parts.push(print('frontmatter'));
|
|
956
|
+
if (hasTemplate)
|
|
957
|
+
parts.push(hardline, hardline);
|
|
608
958
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
const spreadContent = await wrapParserTryCatch(textToDoc, node.name, {
|
|
613
|
-
...options,
|
|
614
|
-
parser: 'astroExpressionParser',
|
|
615
|
-
});
|
|
616
|
-
return [line, '{...', spreadContent, '}'];
|
|
959
|
+
if (hasTemplate)
|
|
960
|
+
parts.push(print('template'));
|
|
961
|
+
return [parts, hardline];
|
|
617
962
|
}
|
|
618
|
-
|
|
963
|
+
case 'AstroFrontmatter': {
|
|
964
|
+
const body = node.program.body;
|
|
619
965
|
if (options.astroSkipFrontmatter) {
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
const frontmatterContent = await wrapParserTryCatch(textToDoc, node.value, {
|
|
623
|
-
...options,
|
|
624
|
-
parser: 'babel-ts',
|
|
625
|
-
});
|
|
626
|
-
return [group(['---', hardline, frontmatterContent, hardline, '---', hardline]), hardline];
|
|
627
|
-
}
|
|
628
|
-
if (node.type === 'element' && node.name === 'script' && node.children.length) {
|
|
629
|
-
const typeAttribute = node.attributes.find((attr) => attr.name === 'type')?.value;
|
|
630
|
-
let parser = 'babel-ts';
|
|
631
|
-
if (typeAttribute) {
|
|
632
|
-
parser = inferParserByTypeAttribute(typeAttribute);
|
|
633
|
-
}
|
|
634
|
-
const scriptContent = printRaw(node);
|
|
635
|
-
let formattedScript = await wrapParserTryCatch(textToDoc, scriptContent, {
|
|
636
|
-
...options,
|
|
637
|
-
parser: parser,
|
|
638
|
-
});
|
|
639
|
-
formattedScript = stripTrailingHardline(formattedScript);
|
|
640
|
-
const isEmpty = /^\s*$/.test(scriptContent);
|
|
641
|
-
const attributes = path.map(print, 'attributes');
|
|
642
|
-
const openingTag = group(['<script', indent(group(attributes)), softline, '>']);
|
|
643
|
-
return [
|
|
644
|
-
openingTag,
|
|
645
|
-
indent([isEmpty ? '' : hardline, formattedScript]),
|
|
646
|
-
isEmpty ? '' : hardline,
|
|
647
|
-
'</script>',
|
|
648
|
-
];
|
|
649
|
-
}
|
|
650
|
-
if (node.type === 'element' && node.name === 'style') {
|
|
651
|
-
const content = printRaw(node);
|
|
652
|
-
let parserLang = 'css';
|
|
653
|
-
if (node.attributes) {
|
|
654
|
-
const langAttribute = node.attributes.filter((x) => x.name === 'lang');
|
|
655
|
-
if (langAttribute.length) {
|
|
656
|
-
const styleLang = langAttribute[0].value.toLowerCase();
|
|
657
|
-
parserLang = supportedStyleLangValues.includes(styleLang) ? styleLang : undefined;
|
|
658
|
-
}
|
|
966
|
+
const fence = options.originalText.indexOf('---', node.start);
|
|
967
|
+
return replaceEndOfLine(options.originalText.slice(fence, node.end));
|
|
659
968
|
}
|
|
660
|
-
return
|
|
969
|
+
return body.length > 0
|
|
970
|
+
? ['---', hardline, print('program'), '---']
|
|
971
|
+
: ['---', hardline, '---'];
|
|
661
972
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
process.env.PRETTIER_DEBUG = 'true';
|
|
671
|
-
throw e;
|
|
973
|
+
case 'AstroScript':
|
|
974
|
+
return node.program.body.length > 0 ? print('program') : '';
|
|
975
|
+
case 'AstroDoctype':
|
|
976
|
+
return printDoctype(node.value);
|
|
977
|
+
case 'AstroComment':
|
|
978
|
+
return `<!--${node.value}-->`;
|
|
979
|
+
default:
|
|
980
|
+
return '';
|
|
672
981
|
}
|
|
673
982
|
}
|
|
674
|
-
function
|
|
675
|
-
const
|
|
676
|
-
const
|
|
677
|
-
|
|
678
|
-
if (
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
if (isNodeWithChildren(child)) {
|
|
688
|
-
child = makeNodeJSXCompatible(child);
|
|
689
|
-
}
|
|
690
|
-
if ((!previousChildren || isTextNode(previousChildren)) &&
|
|
691
|
-
nextChildren &&
|
|
692
|
-
isTagLikeNode(nextChildren)) {
|
|
693
|
-
childBundle[childBundleIndex].push(child);
|
|
694
|
-
return result;
|
|
695
|
-
}
|
|
696
|
-
if (previousChildren &&
|
|
697
|
-
isTagLikeNode(previousChildren) &&
|
|
698
|
-
nextChildren &&
|
|
699
|
-
isTagLikeNode(nextChildren)) {
|
|
700
|
-
childBundle[childBundleIndex].push(child);
|
|
701
|
-
return result;
|
|
702
|
-
}
|
|
703
|
-
if ((!nextChildren || isTextNode(nextChildren)) &&
|
|
704
|
-
childBundle[childBundleIndex].length > 0) {
|
|
705
|
-
childBundle[childBundleIndex].push(child);
|
|
706
|
-
const parentNode = {
|
|
707
|
-
type: 'fragment',
|
|
708
|
-
name: '',
|
|
709
|
-
attributes: [],
|
|
710
|
-
children: childBundle[childBundleIndex],
|
|
711
|
-
};
|
|
712
|
-
childBundleIndex += 1;
|
|
713
|
-
result.push(parentNode);
|
|
714
|
-
return result;
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
else {
|
|
718
|
-
childBundleIndex += 1;
|
|
719
|
-
}
|
|
720
|
-
result.push(child);
|
|
721
|
-
return result;
|
|
722
|
-
}, []);
|
|
983
|
+
function printAttribute(path, options, print) {
|
|
984
|
+
const node = path.node;
|
|
985
|
+
const name = node.name.name;
|
|
986
|
+
const value = node.value;
|
|
987
|
+
if (node.astroShorthand)
|
|
988
|
+
return ['{', print(['value', 'expression']), '}'];
|
|
989
|
+
if (node.astroBacktick)
|
|
990
|
+
return [name, '=', print(['value', 'expression'])];
|
|
991
|
+
const expression = value?.type === 'JSXExpressionContainer' ? value.expression : null;
|
|
992
|
+
if (options.astroAllowShorthand &&
|
|
993
|
+
expression?.type === 'Identifier' &&
|
|
994
|
+
expression.name === name) {
|
|
995
|
+
return ['{', print(['value', 'expression']), '}'];
|
|
723
996
|
}
|
|
724
|
-
return
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
}
|
|
734
|
-
if (attr.name.includes('.')) {
|
|
735
|
-
attr.name = attr.name.replaceAll('.', dotReplace);
|
|
736
|
-
}
|
|
737
|
-
if (attr.name.includes('?')) {
|
|
738
|
-
attr.name = attr.name.replaceAll('?', interrogationReplace);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
return attr;
|
|
997
|
+
return null;
|
|
998
|
+
}
|
|
999
|
+
function unwrapFragmentIndent(printed) {
|
|
1000
|
+
const group = printed;
|
|
1001
|
+
if (group.type !== 'group')
|
|
1002
|
+
return printed;
|
|
1003
|
+
if (group.expandedStates) {
|
|
1004
|
+
const states = group.expandedStates.map(unwrapFragmentIndent);
|
|
1005
|
+
return { ...group, contents: states[0], expandedStates: states };
|
|
742
1006
|
}
|
|
1007
|
+
const parts = group.contents;
|
|
1008
|
+
if (!Array.isArray(parts) || parts.length !== 4)
|
|
1009
|
+
return printed;
|
|
1010
|
+
const indented = parts[1];
|
|
1011
|
+
if (indented.type !== 'indent' || !indented.contents)
|
|
1012
|
+
return printed;
|
|
1013
|
+
return indented.contents[1];
|
|
743
1014
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
1015
|
+
const printer = {
|
|
1016
|
+
...estree,
|
|
1017
|
+
embed,
|
|
1018
|
+
getVisitorKeys(node, nonTraversableKeys) {
|
|
1019
|
+
const keys = astroVisitorKeys[node.type] ?? estree.getVisitorKeys(node, nonTraversableKeys);
|
|
1020
|
+
return node.astroChildren
|
|
1021
|
+
? keys.map((key) => (key === 'children' ? 'astroChildren' : key))
|
|
1022
|
+
: keys;
|
|
1023
|
+
},
|
|
1024
|
+
print(path, options, print, args) {
|
|
1025
|
+
const node = path.node;
|
|
1026
|
+
if (node[ownChildren])
|
|
1027
|
+
return path.callParent(() => printChildren(path, options, print));
|
|
1028
|
+
if (node[synthetic])
|
|
1029
|
+
return '';
|
|
1030
|
+
if (node.astroIgnored) {
|
|
1031
|
+
return replaceEndOfLine(options.originalText.slice(node.start, node.end));
|
|
1032
|
+
}
|
|
1033
|
+
if (astroVisitorKeys[node.type])
|
|
1034
|
+
return printAstroNode(path, options, print);
|
|
1035
|
+
if (node.type === 'JSXAttribute') {
|
|
1036
|
+
const attribute = printAttribute(path, options, print);
|
|
1037
|
+
if (attribute)
|
|
1038
|
+
return attribute;
|
|
763
1039
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
};
|
|
771
|
-
const { result: raw } = manualDedent(content);
|
|
772
|
-
const formattedSassIndented = SassFormatter.Format(raw, sassOptions).trim();
|
|
773
|
-
const formattedSass = join(hardline, formattedSassIndented.split('\n'));
|
|
774
|
-
const attributes = path.map(print, 'attributes');
|
|
775
|
-
const openingTag = group(['<style', indent(group(attributes)), softline, '>']);
|
|
1040
|
+
if (node.type === 'JSXElement' &&
|
|
1041
|
+
node.closingElement &&
|
|
1042
|
+
node.children.length > 0 &&
|
|
1043
|
+
opensRawSubtree(node)) {
|
|
1044
|
+
const start = node.openingElement.end;
|
|
1045
|
+
const end = node.closingElement.start;
|
|
776
1046
|
return [
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
'</style>',
|
|
1047
|
+
print('openingElement'),
|
|
1048
|
+
replaceEndOfLine(options.originalText.slice(start, end)),
|
|
1049
|
+
print('closingElement'),
|
|
781
1050
|
];
|
|
782
1051
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
return Buffer.from(options.originalText)
|
|
787
|
-
.subarray(options.locStart(node), options.locEnd(node))
|
|
788
|
-
.toString();
|
|
789
|
-
}
|
|
790
|
-
return undefined;
|
|
1052
|
+
const printed = estree.print(path, options, print, args);
|
|
1053
|
+
if (node.openingFragment?.[synthetic]) {
|
|
1054
|
+
return unwrapFragmentIndent(printed);
|
|
791
1055
|
}
|
|
792
|
-
|
|
793
|
-
}
|
|
1056
|
+
return printed;
|
|
1057
|
+
},
|
|
1058
|
+
};
|
|
794
1059
|
|
|
795
|
-
const babelParser = prettierPluginBabel.parsers['babel-ts'];
|
|
796
1060
|
const languages = [
|
|
797
1061
|
{
|
|
798
1062
|
name: 'astro',
|
|
@@ -803,30 +1067,14 @@ const languages = [
|
|
|
803
1067
|
];
|
|
804
1068
|
const parsers = {
|
|
805
1069
|
astro: {
|
|
806
|
-
parse
|
|
1070
|
+
parse,
|
|
807
1071
|
astFormat: 'astro',
|
|
808
|
-
locStart: (node) => node.
|
|
809
|
-
locEnd: (node) => node.
|
|
810
|
-
},
|
|
811
|
-
astroExpressionParser: {
|
|
812
|
-
...babelParser,
|
|
813
|
-
preprocess(text) {
|
|
814
|
-
return `<>{${text}\n}</>`;
|
|
815
|
-
},
|
|
816
|
-
parse(text, opts) {
|
|
817
|
-
const ast = babelParser.parse(text, opts);
|
|
818
|
-
return {
|
|
819
|
-
...ast,
|
|
820
|
-
program: ast.program.body[0].expression.children[0].expression,
|
|
821
|
-
};
|
|
822
|
-
},
|
|
1072
|
+
locStart: (node) => node.start,
|
|
1073
|
+
locEnd: (node) => node.end,
|
|
823
1074
|
},
|
|
824
1075
|
};
|
|
825
1076
|
const printers = {
|
|
826
|
-
astro:
|
|
827
|
-
print,
|
|
828
|
-
embed,
|
|
829
|
-
},
|
|
1077
|
+
astro: printer,
|
|
830
1078
|
};
|
|
831
1079
|
const defaultOptions = {
|
|
832
1080
|
tabWidth: 2,
|