prettier-plugin-astro 0.14.0 → 1.0.0-beta.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 +22 -4
- package/dist/index.js +928 -690
- package/dist/index.js.map +1 -1
- package/package.json +14 -12
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,688 @@ 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, run, 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
|
-
|
|
185
|
-
if (
|
|
471
|
+
if (container.type === 'JSXElement' && hasSetDirective(container))
|
|
472
|
+
return true;
|
|
473
|
+
if (isExtractedStyle(boundary.prev) || isExtractedStyle(boundary.next))
|
|
186
474
|
return true;
|
|
187
|
-
|
|
475
|
+
const tag = container.type === 'JSXElement' ? tagNameOf(container) : null;
|
|
476
|
+
if (loneChild && tag !== null && isComponentName(tag))
|
|
188
477
|
return true;
|
|
189
|
-
|
|
478
|
+
if (mode === 'html') {
|
|
479
|
+
if (loneChild)
|
|
480
|
+
return true;
|
|
481
|
+
if (tag === 'head')
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
return false;
|
|
190
485
|
}
|
|
191
|
-
function
|
|
192
|
-
|
|
486
|
+
function mayAlterRenderedWhitespace(boundary) {
|
|
487
|
+
const { sensitivity } = boundary.context;
|
|
488
|
+
if (sensitivity === 'ignore')
|
|
489
|
+
return true;
|
|
490
|
+
if (sensitivity === 'strict')
|
|
491
|
+
return false;
|
|
492
|
+
return boundary.sides.every((side) => !isInlineDisplay(displayOf(side ?? boundary.container)));
|
|
193
493
|
}
|
|
194
|
-
function
|
|
195
|
-
return
|
|
494
|
+
function isSlotFallback(boundary) {
|
|
495
|
+
return (boundary.container.type === 'JSXElement' &&
|
|
496
|
+
tagNameOf(boundary.container) === 'slot' &&
|
|
497
|
+
boundary.loneChild);
|
|
196
498
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
+
stripParenthesizedExpressions(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;
|
|
205
526
|
}
|
|
206
|
-
function
|
|
207
|
-
|
|
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;
|
|
208
534
|
}
|
|
209
|
-
function
|
|
210
|
-
|
|
535
|
+
function stripParenthesizedExpressions(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
|
+
}
|
|
548
|
+
});
|
|
211
549
|
}
|
|
212
|
-
function
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
550
|
+
function unwrapParens(node) {
|
|
551
|
+
let current = node;
|
|
552
|
+
while (isNode(current) && current.type === 'ParenthesizedExpression') {
|
|
553
|
+
current = current.expression;
|
|
554
|
+
}
|
|
555
|
+
return current;
|
|
556
|
+
}
|
|
557
|
+
function repairSpans(root) {
|
|
558
|
+
walk(root, (node) => {
|
|
559
|
+
if (node.type !== 'JSXElement')
|
|
560
|
+
return;
|
|
561
|
+
const script = node.children.find((child) => child.type === 'AstroScript');
|
|
562
|
+
if (!script)
|
|
563
|
+
return;
|
|
564
|
+
script.start = node.openingElement.end;
|
|
565
|
+
script.end = node.closingElement?.start ?? node.end;
|
|
217
566
|
});
|
|
218
|
-
return formattedLines.join('\n');
|
|
219
567
|
}
|
|
220
|
-
function
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
568
|
+
function markAttributes(root, source) {
|
|
569
|
+
walk(root, (node) => {
|
|
570
|
+
if (node.type !== 'JSXAttribute')
|
|
571
|
+
return;
|
|
572
|
+
const value = node.value;
|
|
573
|
+
if (!value)
|
|
574
|
+
return;
|
|
575
|
+
if (value.type === 'Literal' && typeof value.value === 'string') {
|
|
576
|
+
const name = node.name.name;
|
|
577
|
+
const text = name === 'class' ? printClassNames(value.value) : value.value;
|
|
578
|
+
if (value.raw === null || text !== value.value) {
|
|
579
|
+
value.value = text;
|
|
580
|
+
value.raw = `"${text.replaceAll('"', '"')}"`;
|
|
581
|
+
}
|
|
582
|
+
return;
|
|
231
583
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
584
|
+
if (value.type !== 'JSXExpressionContainer')
|
|
585
|
+
return;
|
|
586
|
+
if (source[node.start] === '{')
|
|
587
|
+
node.astroShorthand = true;
|
|
588
|
+
if (source[value.start] === '`')
|
|
589
|
+
node.astroBacktick = true;
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
function applyPrettierIgnore(root) {
|
|
593
|
+
walk(root, (node) => {
|
|
594
|
+
const children = node.type === 'AstroRoot' ? node.body : childrenOf(node);
|
|
595
|
+
if (children === null)
|
|
596
|
+
return;
|
|
597
|
+
for (const [index, child] of children.entries()) {
|
|
598
|
+
if (child.type !== 'AstroComment')
|
|
599
|
+
continue;
|
|
600
|
+
if (String(child.value).trim() !== 'prettier-ignore')
|
|
601
|
+
continue;
|
|
602
|
+
const target = children.slice(index + 1).find((sibling) => sibling.type !== 'JSXText');
|
|
603
|
+
if (target)
|
|
604
|
+
target.astroIgnored = true;
|
|
238
605
|
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
function templateFragment(root, body) {
|
|
609
|
+
const start = body[0]?.start ?? root.end;
|
|
610
|
+
const end = body.at(-1)?.end ?? root.end;
|
|
243
611
|
return {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
612
|
+
type: 'JsExpressionRoot',
|
|
613
|
+
start,
|
|
614
|
+
end,
|
|
615
|
+
node: {
|
|
616
|
+
type: 'JSXFragment',
|
|
617
|
+
start,
|
|
618
|
+
end,
|
|
619
|
+
astroRoot: true,
|
|
620
|
+
openingFragment: { type: 'JSXOpeningFragment', start, end: start, [synthetic]: true },
|
|
621
|
+
children: body,
|
|
622
|
+
closingFragment: { type: 'JSXClosingFragment', start: end, end, [synthetic]: true },
|
|
623
|
+
},
|
|
247
624
|
};
|
|
248
625
|
}
|
|
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
|
-
|
|
626
|
+
function pairUp(node, tag) {
|
|
627
|
+
node.openingElement.selfClosing = false;
|
|
628
|
+
node.closingElement = {
|
|
629
|
+
type: 'JSXClosingElement',
|
|
630
|
+
start: node.end,
|
|
631
|
+
end: node.end,
|
|
632
|
+
name: { type: 'JSXIdentifier', name: tag, start: node.end, end: node.end },
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
function printsNothing(child) {
|
|
636
|
+
const raw = String(child.raw ?? '');
|
|
637
|
+
return child.type === 'JSXText' && raw.trim() === '' && /[\n\r]/.test(raw);
|
|
638
|
+
}
|
|
639
|
+
function normalizeTagPairs(body, source) {
|
|
640
|
+
walk(body, (node) => {
|
|
641
|
+
if (node.type !== 'JSXElement')
|
|
642
|
+
return;
|
|
643
|
+
const tag = tagNameOf(node);
|
|
644
|
+
if (tag === null)
|
|
645
|
+
return;
|
|
646
|
+
const children = node.children;
|
|
647
|
+
const closing = node.closingElement;
|
|
648
|
+
const component = isComponentName(tag);
|
|
649
|
+
if (rawTextElements.has(tag) && !component) {
|
|
650
|
+
if (!closing)
|
|
651
|
+
pairUp(node, tag);
|
|
652
|
+
else if (source.slice(node.openingElement.end, closing.start).trim() === '') {
|
|
653
|
+
children.length = 0;
|
|
277
654
|
}
|
|
655
|
+
return;
|
|
278
656
|
}
|
|
657
|
+
const selfClosable = component || voidElements.has(tag) || tag === 'slot' || hasSetDirective(node);
|
|
658
|
+
if (children.every(printsNothing) && selfClosable && closing) {
|
|
659
|
+
node.openingElement.selfClosing = true;
|
|
660
|
+
node.closingElement = null;
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
function resolveBlankContainers(template, settings) {
|
|
665
|
+
walk(template, (node) => {
|
|
666
|
+
if (node.type !== 'JSXElement' && node.type !== 'JSXFragment')
|
|
667
|
+
return;
|
|
668
|
+
if (node.type === 'JSXElement' && opensRawSubtree(node))
|
|
669
|
+
return;
|
|
670
|
+
const children = node.children;
|
|
671
|
+
if (children.length === 0)
|
|
672
|
+
return;
|
|
673
|
+
const blank = children.every((child) => child.type === 'JSXText' && String(child.raw ?? '').trim() === '');
|
|
674
|
+
if (!blank)
|
|
675
|
+
return;
|
|
676
|
+
const run = children.map((child) => String(child.raw ?? '')).join('');
|
|
677
|
+
const free = blankContentIsFree(node, run, node.astroRoot === true, settings);
|
|
678
|
+
children.length = 0;
|
|
679
|
+
if (!free) {
|
|
680
|
+
children.push({ type: 'JSXText', start: node.start, end: node.start, raw: ' ', value: ' ' });
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
function claimChildren(template) {
|
|
685
|
+
walk(template, (node) => {
|
|
686
|
+
if (node.type !== 'JSXElement' && node.type !== 'JSXFragment')
|
|
687
|
+
return;
|
|
688
|
+
if (node.type === 'JSXElement' && opensRawSubtree(node))
|
|
689
|
+
return;
|
|
690
|
+
takeOverChildren(node);
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
function printableComments(root) {
|
|
694
|
+
const comments = root.comments ?? [];
|
|
695
|
+
if (comments.length === 0)
|
|
696
|
+
return comments;
|
|
697
|
+
const frontmatter = root.frontmatter;
|
|
698
|
+
const skipped = [];
|
|
699
|
+
if (frontmatter.end > 0)
|
|
700
|
+
skipped.push([frontmatter.start, frontmatter.end]);
|
|
701
|
+
walk(root, (node) => {
|
|
702
|
+
if (node.astroIgnored) {
|
|
703
|
+
skipped.push([node.start, node.end]);
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
if (!opensRawSubtree(node))
|
|
707
|
+
return;
|
|
708
|
+
const closing = node.closingElement;
|
|
709
|
+
skipped.push([node.openingElement.end, closing?.start ?? node.end]);
|
|
710
|
+
});
|
|
711
|
+
return comments.filter((comment) => !skipped.some(([start, end]) => comment.start >= start && comment.end <= end));
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
const estree = printers$1.estree;
|
|
715
|
+
|
|
716
|
+
const { fill, group: group$1, hardline: hardline$2, indent: indent$1, line, softline } = doc.builders;
|
|
717
|
+
const leadingWhitespace = /^[\t\n\f\r ]+/;
|
|
718
|
+
const trailingWhitespace = /[\t\n\f\r ]+$/;
|
|
719
|
+
const whitespaceRun = /[\t\n\f\r ]+/;
|
|
720
|
+
function docFor(separator) {
|
|
721
|
+
switch (separator) {
|
|
722
|
+
case 'none':
|
|
723
|
+
return null;
|
|
724
|
+
case 'soft':
|
|
725
|
+
return softline;
|
|
726
|
+
case 'space':
|
|
727
|
+
return line;
|
|
728
|
+
case 'break':
|
|
729
|
+
return hardline$2;
|
|
730
|
+
case 'blank':
|
|
731
|
+
return [hardline$2, hardline$2];
|
|
279
732
|
}
|
|
280
|
-
return null;
|
|
281
733
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
734
|
+
function collect(children, docs) {
|
|
735
|
+
const items = [];
|
|
736
|
+
const runs = [];
|
|
737
|
+
let pending = '';
|
|
738
|
+
for (const [index, child] of children.entries()) {
|
|
739
|
+
if (child.type !== 'JSXText') {
|
|
740
|
+
runs.push(pending);
|
|
741
|
+
items.push({ node: child, words: null, doc: docs[index] });
|
|
742
|
+
pending = '';
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
const raw = String(child.raw ?? '');
|
|
746
|
+
if (raw.trim() === '') {
|
|
747
|
+
pending += raw;
|
|
748
|
+
continue;
|
|
749
|
+
}
|
|
750
|
+
const lead = leadingWhitespace.exec(raw)?.[0] ?? '';
|
|
751
|
+
const trail = trailingWhitespace.exec(raw)?.[0] ?? '';
|
|
752
|
+
runs.push(pending + lead);
|
|
753
|
+
items.push({
|
|
754
|
+
node: child,
|
|
755
|
+
words: raw.slice(lead.length, raw.length - trail.length).split(whitespaceRun),
|
|
756
|
+
doc: '',
|
|
757
|
+
});
|
|
758
|
+
pending = trail;
|
|
759
|
+
}
|
|
760
|
+
runs.push(pending);
|
|
761
|
+
return { items, runs };
|
|
762
|
+
}
|
|
763
|
+
function printChildren(path, options, print) {
|
|
764
|
+
const container = path.node;
|
|
765
|
+
const docs = [];
|
|
766
|
+
path.each((child) => {
|
|
767
|
+
docs.push(child.node.type === 'JSXText' ? '' : print());
|
|
768
|
+
}, 'astroChildren');
|
|
769
|
+
const { items, runs } = collect(container.astroChildren, docs);
|
|
770
|
+
if (items.length === 0)
|
|
771
|
+
return runs[0] === '' ? '' : ' ';
|
|
772
|
+
const isRoot = container.astroRoot === true;
|
|
773
|
+
const settings = {
|
|
774
|
+
mode: options.astroCompressHTML,
|
|
775
|
+
sensitivity: options.htmlWhitespaceSensitivity,
|
|
776
|
+
};
|
|
777
|
+
const separatorAt = (index, edge) => docFor(separatorFor(runs[index], {
|
|
778
|
+
container,
|
|
779
|
+
prev: items[index - 1]?.node ?? null,
|
|
780
|
+
next: items[index]?.node ?? null,
|
|
781
|
+
isRoot,
|
|
782
|
+
loneChild: false,
|
|
783
|
+
edge,
|
|
784
|
+
}, settings));
|
|
785
|
+
const parts = [''];
|
|
786
|
+
const append = (content) => parts.push([parts.pop(), content]);
|
|
787
|
+
const separate = (separator) => {
|
|
788
|
+
if (separator !== null)
|
|
789
|
+
parts.push(separator, '');
|
|
790
|
+
};
|
|
791
|
+
for (const [position, item] of items.entries()) {
|
|
792
|
+
if (position > 0)
|
|
793
|
+
separate(separatorAt(position, false));
|
|
794
|
+
if (item.words === null) {
|
|
795
|
+
append(item.doc);
|
|
796
|
+
continue;
|
|
797
|
+
}
|
|
798
|
+
for (const [wordPosition, word] of item.words.entries()) {
|
|
799
|
+
if (wordPosition > 0)
|
|
800
|
+
separate(line);
|
|
801
|
+
append(word);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
const body = fill(parts);
|
|
805
|
+
if (isRoot)
|
|
806
|
+
return body;
|
|
807
|
+
return group$1([indent$1([separatorAt(0, true) ?? '', body]), separatorAt(items.length, true) ?? '']);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
const { group, hardline: hardline$1, indent, join } = doc.builders;
|
|
811
|
+
const { replaceEndOfLine: replaceEndOfLine$1 } = doc.utils;
|
|
812
|
+
const styleParsers = {
|
|
813
|
+
css: 'css',
|
|
814
|
+
scss: 'scss',
|
|
815
|
+
less: 'less',
|
|
287
816
|
};
|
|
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;
|
|
817
|
+
async function surfacingErrors(textToDoc, text, options) {
|
|
818
|
+
try {
|
|
819
|
+
return await textToDoc(text, options);
|
|
820
|
+
}
|
|
821
|
+
catch (error) {
|
|
822
|
+
process.env.PRETTIER_DEBUG = 'true';
|
|
823
|
+
throw error;
|
|
298
824
|
}
|
|
299
|
-
return result;
|
|
300
825
|
}
|
|
301
826
|
function inferParserByTypeAttribute(type) {
|
|
302
|
-
if (!type) {
|
|
303
|
-
return 'babel-ts';
|
|
304
|
-
}
|
|
305
827
|
switch (type) {
|
|
828
|
+
case null:
|
|
306
829
|
case 'module':
|
|
307
830
|
case 'text/javascript':
|
|
308
831
|
case 'text/babel':
|
|
@@ -323,476 +846,207 @@ function inferParserByTypeAttribute(type) {
|
|
|
323
846
|
return 'babel-ts';
|
|
324
847
|
}
|
|
325
848
|
}
|
|
326
|
-
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
849
|
+
function contentOf(node, options) {
|
|
850
|
+
const start = node.openingElement.end;
|
|
851
|
+
const end = node.closingElement?.start ?? node.end;
|
|
852
|
+
return options.originalText.slice(start, end);
|
|
853
|
+
}
|
|
854
|
+
function wrapContent(print, content, isEmpty) {
|
|
855
|
+
return [
|
|
856
|
+
print('openingElement'),
|
|
857
|
+
indent([isEmpty ? '' : hardline$1, content]),
|
|
858
|
+
isEmpty ? '' : hardline$1,
|
|
859
|
+
print('closingElement'),
|
|
860
|
+
];
|
|
861
|
+
}
|
|
862
|
+
function embedSass(source, options) {
|
|
863
|
+
const sassOptions = {
|
|
864
|
+
tabSize: options.tabWidth,
|
|
865
|
+
insertSpaces: !options.useTabs,
|
|
866
|
+
lineEnding: options.endOfLine.toUpperCase() === 'CRLF' ? 'CRLF' : 'LF',
|
|
867
|
+
};
|
|
868
|
+
const { result } = manualDedent(source);
|
|
869
|
+
return join(hardline$1, SassFormatter.Format(result, sassOptions).trim().split('\n'));
|
|
870
|
+
}
|
|
871
|
+
function embed(path, options) {
|
|
330
872
|
const node = path.node;
|
|
331
|
-
if (
|
|
332
|
-
return
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
873
|
+
if (node.astroIgnored)
|
|
874
|
+
return undefined;
|
|
875
|
+
if (node.type === 'AstroFrontmatter') {
|
|
876
|
+
if (node.end === 0 || options.astroSkipFrontmatter)
|
|
877
|
+
return undefined;
|
|
878
|
+
const fence = options.originalText.indexOf('---', node.start);
|
|
879
|
+
const source = options.originalText.slice(fence + 3, node.end - 3);
|
|
880
|
+
if (!source.trim())
|
|
881
|
+
return undefined;
|
|
882
|
+
return async (textToDoc) => [
|
|
883
|
+
'---',
|
|
884
|
+
hardline$1,
|
|
885
|
+
await surfacingErrors(textToDoc, source, { ...options, parser: 'babel-ts' }),
|
|
886
|
+
hardline$1,
|
|
887
|
+
'---',
|
|
342
888
|
];
|
|
343
889
|
}
|
|
344
|
-
if (
|
|
345
|
-
return
|
|
890
|
+
if (node.type !== 'JSXElement')
|
|
891
|
+
return estree.embed(path, options);
|
|
892
|
+
const tag = tagNameOf(node);
|
|
893
|
+
if (tag === null || !node.closingElement)
|
|
894
|
+
return estree.embed(path, options);
|
|
895
|
+
const source = contentOf(node, options);
|
|
896
|
+
const isEmpty = source.trim() === '';
|
|
897
|
+
if (tag === 'script') {
|
|
898
|
+
if (isEmpty)
|
|
899
|
+
return estree.embed(path, options);
|
|
900
|
+
const parser = inferParserByTypeAttribute(attributeStringValue(node, 'type'));
|
|
901
|
+
return async (textToDoc, print) => wrapContent(print, await surfacingErrors(textToDoc, source, { ...options, parser }), false);
|
|
346
902
|
}
|
|
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}"!`);
|
|
903
|
+
if (tag === 'style') {
|
|
904
|
+
if (isEmpty)
|
|
905
|
+
return estree.embed(path, options);
|
|
906
|
+
const lang = attributeStringValue(node, 'lang')?.toLowerCase() ?? 'css';
|
|
907
|
+
if (lang === 'sass') {
|
|
908
|
+
return (_textToDoc, print) => wrapContent(print, embedSass(source, options), false);
|
|
539
909
|
}
|
|
910
|
+
const parser = styleParsers[lang];
|
|
911
|
+
if (!parser)
|
|
912
|
+
return printVerbatim(source);
|
|
913
|
+
return async (textToDoc, print) => wrapContent(print, await surfacingErrors(textToDoc, source, { ...options, parser }), false);
|
|
540
914
|
}
|
|
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];
|
|
915
|
+
if (opensRawSubtree(node)) {
|
|
916
|
+
return (_textToDoc, print) => [
|
|
917
|
+
print('openingElement'),
|
|
918
|
+
replaceEndOfLine$1(source),
|
|
919
|
+
print('closingElement'),
|
|
920
|
+
];
|
|
557
921
|
}
|
|
558
|
-
return
|
|
922
|
+
return estree.embed(path, options);
|
|
923
|
+
}
|
|
924
|
+
function printVerbatim(source) {
|
|
925
|
+
return (_textToDoc, print) => group([print('openingElement'), replaceEndOfLine$1(source), print('closingElement')]);
|
|
559
926
|
}
|
|
560
927
|
|
|
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, '}'];
|
|
928
|
+
const { hardline } = doc.builders;
|
|
929
|
+
const { replaceEndOfLine } = doc.utils;
|
|
930
|
+
function printDoctype(value) {
|
|
931
|
+
const trimmed = value.trim();
|
|
932
|
+
const space = trimmed.search(/\s/);
|
|
933
|
+
const name = space === -1 ? trimmed : trimmed.slice(0, space);
|
|
934
|
+
const rest = space === -1 ? '' : trimmed.slice(space);
|
|
935
|
+
return `<!doctype ${name.toLowerCase()}${rest}>`;
|
|
936
|
+
}
|
|
937
|
+
function printAstroNode(path, options, print) {
|
|
938
|
+
const node = path.node;
|
|
939
|
+
switch (node.type) {
|
|
940
|
+
case 'AstroRoot': {
|
|
941
|
+
const template = node.template;
|
|
942
|
+
const hasTemplate = template.node.children.length > 0;
|
|
943
|
+
const parts = [];
|
|
944
|
+
if (node.frontmatter.end > 0) {
|
|
945
|
+
parts.push(print('frontmatter'));
|
|
946
|
+
if (hasTemplate)
|
|
947
|
+
parts.push(hardline, hardline);
|
|
608
948
|
}
|
|
609
|
-
|
|
949
|
+
if (hasTemplate)
|
|
950
|
+
parts.push(print('template'));
|
|
951
|
+
return [parts, hardline];
|
|
610
952
|
}
|
|
611
|
-
|
|
612
|
-
const
|
|
613
|
-
...options,
|
|
614
|
-
parser: 'astroExpressionParser',
|
|
615
|
-
});
|
|
616
|
-
return [line, '{...', spreadContent, '}'];
|
|
617
|
-
}
|
|
618
|
-
if (node.type === 'frontmatter') {
|
|
953
|
+
case 'AstroFrontmatter': {
|
|
954
|
+
const body = node.program.body;
|
|
619
955
|
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
|
-
}
|
|
956
|
+
const fence = options.originalText.indexOf('---', node.start);
|
|
957
|
+
return replaceEndOfLine(options.originalText.slice(fence, node.end));
|
|
659
958
|
}
|
|
660
|
-
return
|
|
959
|
+
return body.length > 0
|
|
960
|
+
? ['---', hardline, print('program'), '---']
|
|
961
|
+
: ['---', hardline, '---'];
|
|
661
962
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
process.env.PRETTIER_DEBUG = 'true';
|
|
671
|
-
throw e;
|
|
963
|
+
case 'AstroScript':
|
|
964
|
+
return node.program.body.length > 0 ? print('program') : '';
|
|
965
|
+
case 'AstroDoctype':
|
|
966
|
+
return printDoctype(node.value);
|
|
967
|
+
case 'AstroComment':
|
|
968
|
+
return `<!--${node.value}-->`;
|
|
969
|
+
default:
|
|
970
|
+
return '';
|
|
672
971
|
}
|
|
673
972
|
}
|
|
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
|
-
}, []);
|
|
973
|
+
function printAttribute(path, options, print) {
|
|
974
|
+
const node = path.node;
|
|
975
|
+
const name = node.name.name;
|
|
976
|
+
const value = node.value;
|
|
977
|
+
if (node.astroShorthand)
|
|
978
|
+
return ['{', print(['value', 'expression']), '}'];
|
|
979
|
+
if (node.astroBacktick)
|
|
980
|
+
return [name, '=', print(['value', 'expression'])];
|
|
981
|
+
const expression = value?.type === 'JSXExpressionContainer' ? value.expression : null;
|
|
982
|
+
if (options.astroAllowShorthand &&
|
|
983
|
+
expression?.type === 'Identifier' &&
|
|
984
|
+
expression.name === name) {
|
|
985
|
+
return ['{', print(['value', 'expression']), '}'];
|
|
723
986
|
}
|
|
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;
|
|
987
|
+
return null;
|
|
988
|
+
}
|
|
989
|
+
function unwrapFragmentIndent(printed) {
|
|
990
|
+
const group = printed;
|
|
991
|
+
if (group.type !== 'group')
|
|
992
|
+
return printed;
|
|
993
|
+
if (group.expandedStates) {
|
|
994
|
+
const states = group.expandedStates.map(unwrapFragmentIndent);
|
|
995
|
+
return { ...group, contents: states[0], expandedStates: states };
|
|
742
996
|
}
|
|
997
|
+
const parts = group.contents;
|
|
998
|
+
if (!Array.isArray(parts) || parts.length !== 4)
|
|
999
|
+
return printed;
|
|
1000
|
+
const indented = parts[1];
|
|
1001
|
+
if (indented.type !== 'indent' || !indented.contents)
|
|
1002
|
+
return printed;
|
|
1003
|
+
return indented.contents[1];
|
|
743
1004
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
'</style>',
|
|
762
|
-
];
|
|
1005
|
+
const printer = {
|
|
1006
|
+
...estree,
|
|
1007
|
+
embed,
|
|
1008
|
+
getVisitorKeys(node, nonTraversableKeys) {
|
|
1009
|
+
const keys = astroVisitorKeys[node.type] ?? estree.getVisitorKeys(node, nonTraversableKeys);
|
|
1010
|
+
return node.astroChildren
|
|
1011
|
+
? keys.map((key) => (key === 'children' ? 'astroChildren' : key))
|
|
1012
|
+
: keys;
|
|
1013
|
+
},
|
|
1014
|
+
print(path, options, print, args) {
|
|
1015
|
+
const node = path.node;
|
|
1016
|
+
if (node[ownChildren])
|
|
1017
|
+
return path.callParent(() => printChildren(path, options, print));
|
|
1018
|
+
if (node[synthetic])
|
|
1019
|
+
return '';
|
|
1020
|
+
if (node.astroIgnored) {
|
|
1021
|
+
return replaceEndOfLine(options.originalText.slice(node.start, node.end));
|
|
763
1022
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
const
|
|
1023
|
+
if (astroVisitorKeys[node.type])
|
|
1024
|
+
return printAstroNode(path, options, print);
|
|
1025
|
+
if (node.type === 'JSXAttribute') {
|
|
1026
|
+
const attribute = printAttribute(path, options, print);
|
|
1027
|
+
if (attribute)
|
|
1028
|
+
return attribute;
|
|
1029
|
+
}
|
|
1030
|
+
if (node.type === 'JSXElement' &&
|
|
1031
|
+
node.closingElement &&
|
|
1032
|
+
node.children.length > 0 &&
|
|
1033
|
+
opensRawSubtree(node)) {
|
|
1034
|
+
const start = node.openingElement.end;
|
|
1035
|
+
const end = node.closingElement.start;
|
|
776
1036
|
return [
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
'</style>',
|
|
1037
|
+
print('openingElement'),
|
|
1038
|
+
replaceEndOfLine(options.originalText.slice(start, end)),
|
|
1039
|
+
print('closingElement'),
|
|
781
1040
|
];
|
|
782
1041
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
return Buffer.from(options.originalText)
|
|
787
|
-
.subarray(options.locStart(node), options.locEnd(node))
|
|
788
|
-
.toString();
|
|
789
|
-
}
|
|
790
|
-
return undefined;
|
|
1042
|
+
const printed = estree.print(path, options, print, args);
|
|
1043
|
+
if (node.openingFragment?.[synthetic]) {
|
|
1044
|
+
return unwrapFragmentIndent(printed);
|
|
791
1045
|
}
|
|
792
|
-
|
|
793
|
-
}
|
|
1046
|
+
return printed;
|
|
1047
|
+
},
|
|
1048
|
+
};
|
|
794
1049
|
|
|
795
|
-
const babelParser = prettierPluginBabel.parsers['babel-ts'];
|
|
796
1050
|
const languages = [
|
|
797
1051
|
{
|
|
798
1052
|
name: 'astro',
|
|
@@ -803,30 +1057,14 @@ const languages = [
|
|
|
803
1057
|
];
|
|
804
1058
|
const parsers = {
|
|
805
1059
|
astro: {
|
|
806
|
-
parse
|
|
1060
|
+
parse,
|
|
807
1061
|
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
|
-
},
|
|
1062
|
+
locStart: (node) => node.start,
|
|
1063
|
+
locEnd: (node) => node.end,
|
|
823
1064
|
},
|
|
824
1065
|
};
|
|
825
1066
|
const printers = {
|
|
826
|
-
astro:
|
|
827
|
-
print,
|
|
828
|
-
embed,
|
|
829
|
-
},
|
|
1067
|
+
astro: printer,
|
|
830
1068
|
};
|
|
831
1069
|
const defaultOptions = {
|
|
832
1070
|
tabWidth: 2,
|