prettier-plugin-astro 0.0.11 → 0.1.0-next.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/CHANGELOG.md +21 -0
- package/README.md +2 -2
- package/dist/index.js +195 -469
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -2,44 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var makeSynchronous = require('make-synchronous');
|
|
6
6
|
var _doc = require('prettier/doc');
|
|
7
7
|
var sassFormatter = require('sass-formatter');
|
|
8
|
-
var prettier = require('prettier');
|
|
9
8
|
|
|
10
9
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
10
|
|
|
11
|
+
var makeSynchronous__default = /*#__PURE__*/_interopDefaultLegacy(makeSynchronous);
|
|
12
12
|
var _doc__default = /*#__PURE__*/_interopDefaultLegacy(_doc);
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
description: 'markup | styles',
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
value: 'styles | markup',
|
|
30
|
-
description: 'styles | markup',
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
|
-
astroAllowShorthand: {
|
|
35
|
-
since: '0.0.10',
|
|
36
|
-
category: 'Astro',
|
|
37
|
-
type: 'boolean',
|
|
38
|
-
default: true,
|
|
39
|
-
description: 'Enable/disable attribute shorthand if attribute name and expression are the same',
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
const parseSortOrder = (sortOrder) => sortOrder.split(' | ');
|
|
14
|
+
const parseSync = makeSynchronous__default["default"](async (source) => {
|
|
15
|
+
const dynamicImport = new Function('file', 'return import(file)');
|
|
16
|
+
const { parse } = await dynamicImport('@astrojs/compiler');
|
|
17
|
+
try {
|
|
18
|
+
const { ast } = await parse(source);
|
|
19
|
+
return ast;
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
console.error(e);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const parse = (text) => parseSync(text);
|
|
43
26
|
|
|
44
27
|
const blockElementsT = [
|
|
45
28
|
'address',
|
|
@@ -75,70 +58,48 @@ const blockElementsT = [
|
|
|
75
58
|
'section',
|
|
76
59
|
'table',
|
|
77
60
|
'ul',
|
|
61
|
+
'title',
|
|
62
|
+
'html',
|
|
78
63
|
];
|
|
79
64
|
const blockElements = [...blockElementsT];
|
|
80
65
|
const selfClosingTags = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
|
|
81
66
|
|
|
67
|
+
const serializeSync = makeSynchronous__default["default"](async (node) => {
|
|
68
|
+
const dynamicImport = new Function('file', 'return import(file)');
|
|
69
|
+
const { serialize } = await dynamicImport('@astrojs/compiler/utils');
|
|
70
|
+
try {
|
|
71
|
+
return await serialize(node);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
console.error(e);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
const serialize = (node) => serializeSync(node);
|
|
78
|
+
|
|
82
79
|
const formattableAttributes = [];
|
|
83
|
-
const rootNodeKeys = new Set(['html', 'css', 'module']);
|
|
84
|
-
const isASTNode = (node) => typeof node === 'object' && Object.keys(node).filter((key) => rootNodeKeys.has(key)).length === rootNodeKeys.size;
|
|
85
80
|
const isEmptyTextNode = (node) => {
|
|
86
|
-
return !!node && node.type === '
|
|
81
|
+
return !!node && node.type === 'text' && getUnencodedText(node).trim() === '';
|
|
87
82
|
};
|
|
88
83
|
const isPreTagContent = (path) => {
|
|
89
84
|
if (!path || !path.stack || !Array.isArray(path.stack))
|
|
90
85
|
return false;
|
|
91
|
-
return path.stack.some((node) => (node.type === '
|
|
86
|
+
return path.stack.some((node) => (node.type === 'element' && node.name.toLowerCase() === 'pre') || (node.type === 'attribute' && !formattableAttributes.includes(node.name)));
|
|
92
87
|
};
|
|
93
|
-
function isLoneMustacheTag(node) {
|
|
94
|
-
return node !== true && node.length === 1 && node[0].type === 'MustacheTag';
|
|
95
|
-
}
|
|
96
|
-
function isAttributeShorthand(node) {
|
|
97
|
-
return node !== true && node.length === 1 && node[0].type === 'AttributeShorthand';
|
|
98
|
-
}
|
|
99
|
-
function isOrCanBeConvertedToShorthand(node, opts) {
|
|
100
|
-
if (!opts.astroAllowShorthand)
|
|
101
|
-
return false;
|
|
102
|
-
if (isAttributeShorthand(node.value)) {
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
if (isLoneMustacheTag(node.value)) {
|
|
106
|
-
const expression = node.value[0].expression;
|
|
107
|
-
return expression.codeChunks[0] === node.name;
|
|
108
|
-
}
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
88
|
function getText(node, opts) {
|
|
112
|
-
|
|
89
|
+
var _a, _b, _c;
|
|
90
|
+
return opts.originalText.slice(((_a = node.position) === null || _a === void 0 ? void 0 : _a.start.offset) + 1, (_c = (_b = node.position) === null || _b === void 0 ? void 0 : _b.end) === null || _c === void 0 ? void 0 : _c.offset);
|
|
113
91
|
}
|
|
114
92
|
function getUnencodedText(node) {
|
|
115
|
-
return node.
|
|
93
|
+
return node.value;
|
|
116
94
|
}
|
|
117
|
-
function
|
|
118
|
-
const parts = [];
|
|
119
|
-
for (const part of text.split('\n')) {
|
|
120
|
-
if (parts.length > 0) {
|
|
121
|
-
parts.push(replacement);
|
|
122
|
-
}
|
|
123
|
-
if (part.endsWith('\r')) {
|
|
124
|
-
parts.push(part.slice(0, -1));
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
parts.push(part);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return parts;
|
|
131
|
-
}
|
|
132
|
-
function printRaw(node, originalText, stripLeadingAndTrailingNewline = false) {
|
|
95
|
+
function printRaw(node, stripLeadingAndTrailingNewline = false) {
|
|
133
96
|
if (!isNodeWithChildren(node)) {
|
|
134
97
|
return '';
|
|
135
98
|
}
|
|
136
99
|
if (node.children.length === 0) {
|
|
137
100
|
return '';
|
|
138
101
|
}
|
|
139
|
-
|
|
140
|
-
const lastChild = node.children[node.children.length - 1];
|
|
141
|
-
let raw = originalText.substring(firstChild.start, lastChild.end);
|
|
102
|
+
let raw = node.children.reduce((prev, curr) => prev + serialize(curr), '');
|
|
142
103
|
if (!stripLeadingAndTrailingNewline) {
|
|
143
104
|
return raw;
|
|
144
105
|
}
|
|
@@ -157,10 +118,10 @@ function isNodeWithChildren(node) {
|
|
|
157
118
|
return node && Array.isArray(node.children);
|
|
158
119
|
}
|
|
159
120
|
function isInlineElement(path, opts, node) {
|
|
160
|
-
return node && node.type === '
|
|
121
|
+
return node && node.type === 'element' && !isBlockElement(node, opts) && !isPreTagContent(path);
|
|
161
122
|
}
|
|
162
123
|
function isBlockElement(node, opts) {
|
|
163
|
-
return node && node.type === '
|
|
124
|
+
return node && node.type === 'element' && opts.htmlWhitespaceSensitivity !== 'strict' && (opts.htmlWhitespaceSensitivity === 'ignore' || blockElements.includes(node.name));
|
|
164
125
|
}
|
|
165
126
|
function isTextNodeStartingWithLinebreak(node, nrLines = 1) {
|
|
166
127
|
return startsWithLinebreak(getUnencodedText(node), nrLines);
|
|
@@ -172,10 +133,10 @@ function endsWithLinebreak(text, nrLines = 1) {
|
|
|
172
133
|
return new RegExp(`(\\n[\\t\\f\\r ]*){${nrLines}}$`).test(text);
|
|
173
134
|
}
|
|
174
135
|
function isTextNodeStartingWithWhitespace(node) {
|
|
175
|
-
return node.type === '
|
|
136
|
+
return node.type === 'text' && /^\s/.test(getUnencodedText(node));
|
|
176
137
|
}
|
|
177
138
|
function isTextNodeEndingWithWhitespace(node) {
|
|
178
|
-
return node.type === '
|
|
139
|
+
return node.type === 'text' && /\s$/.test(getUnencodedText(node));
|
|
179
140
|
}
|
|
180
141
|
function forceIntoExpression(statement) {
|
|
181
142
|
return `(${statement}\n)`;
|
|
@@ -205,8 +166,7 @@ function shouldHugEnd(node, opts) {
|
|
|
205
166
|
if (children.length === 0) {
|
|
206
167
|
return true;
|
|
207
168
|
}
|
|
208
|
-
|
|
209
|
-
return !isTextNodeEndingWithWhitespace(lastChild);
|
|
169
|
+
return false;
|
|
210
170
|
}
|
|
211
171
|
function canOmitSoftlineBeforeClosingTag(path, opts) {
|
|
212
172
|
return isLastChildWithinParentBlockElement(path, opts);
|
|
@@ -224,179 +184,49 @@ function isLastChildWithinParentBlockElement(path, opts) {
|
|
|
224
184
|
return lastChild === path.getNode();
|
|
225
185
|
}
|
|
226
186
|
function trimTextNodeLeft(node) {
|
|
227
|
-
node.
|
|
228
|
-
node.data = node.data && node.data.trimLeft();
|
|
187
|
+
node.value = node.value && node.value.trimStart();
|
|
229
188
|
}
|
|
230
189
|
function trimTextNodeRight(node) {
|
|
231
|
-
node.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
for (
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (isTextNode(n)) {
|
|
252
|
-
trimTextNodeLeft(n);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
for (let i = children.length - 1; i >= lastNonEmptyNode; i--) {
|
|
256
|
-
const n = children[i];
|
|
257
|
-
if (isTextNode(n)) {
|
|
258
|
-
trimTextNodeRight(n);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
function isHardline(docToCheck) {
|
|
263
|
-
return docToCheck === prettier.doc.builders.hardline || deepEqual(docToCheck, prettier.doc.builders.hardline);
|
|
264
|
-
}
|
|
265
|
-
function deepEqual(x, y) {
|
|
266
|
-
if (x === y) {
|
|
267
|
-
return true;
|
|
268
|
-
}
|
|
269
|
-
else if (typeof x == 'object' && x != null && typeof y == 'object' && y != null) {
|
|
270
|
-
if (Object.keys(x).length != Object.keys(y).length)
|
|
271
|
-
return false;
|
|
272
|
-
for (var prop in x) {
|
|
273
|
-
if (Object.prototype.hasOwnProperty.call(y, prop)) {
|
|
274
|
-
if (!deepEqual(x[prop], y[prop]))
|
|
275
|
-
return false;
|
|
190
|
+
node.value = node.value && node.value.trimEnd();
|
|
191
|
+
}
|
|
192
|
+
function manualDedent(input) {
|
|
193
|
+
let result = '';
|
|
194
|
+
for (var i = 0; i < input.length; i++) {
|
|
195
|
+
result += input[i]
|
|
196
|
+
.replace(/\\\n[ \t]*/g, '')
|
|
197
|
+
.replace(/\\`/g, '`');
|
|
198
|
+
if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {
|
|
199
|
+
result += arguments.length <= i + 1 ? undefined : arguments[i + 1];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const lines = result.split('\n');
|
|
203
|
+
let mindent = null;
|
|
204
|
+
lines.forEach(function (l) {
|
|
205
|
+
var m = l.match(/^(\s+)\S+/);
|
|
206
|
+
if (m) {
|
|
207
|
+
var indent = m[1].length;
|
|
208
|
+
if (!mindent) {
|
|
209
|
+
mindent = indent;
|
|
276
210
|
}
|
|
277
211
|
else {
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return true;
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
function isLine(docToCheck) {
|
|
288
|
-
return (isHardline(docToCheck) ||
|
|
289
|
-
(typeof docToCheck === 'object' && isDocCommand(docToCheck) && docToCheck.type === 'line') ||
|
|
290
|
-
(typeof docToCheck === 'object' && isDocCommand(docToCheck) && docToCheck.type === 'concat' && docToCheck.parts.every(isLine)));
|
|
291
|
-
}
|
|
292
|
-
function isEmptyDoc(doc) {
|
|
293
|
-
if (typeof doc === 'string') {
|
|
294
|
-
return doc.length === 0;
|
|
295
|
-
}
|
|
296
|
-
if (Array.isArray(doc)) {
|
|
297
|
-
return doc.length === 0;
|
|
298
|
-
}
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
301
|
-
function trim(docs, isWhitespace) {
|
|
302
|
-
trimLeft(docs, isWhitespace);
|
|
303
|
-
trimRight(docs, isWhitespace);
|
|
304
|
-
return docs;
|
|
305
|
-
}
|
|
306
|
-
function trimLeft(group, isWhitespace) {
|
|
307
|
-
let firstNonWhitespace = group.findIndex((doc) => !isEmptyDoc(doc) && !isWhitespace(doc));
|
|
308
|
-
if (firstNonWhitespace < 0 && group.length) {
|
|
309
|
-
firstNonWhitespace = group.length;
|
|
310
|
-
}
|
|
311
|
-
if (firstNonWhitespace > 0) {
|
|
312
|
-
const removed = group.splice(0, firstNonWhitespace);
|
|
313
|
-
if (removed.every(isEmptyDoc)) {
|
|
314
|
-
return trimLeft(group, isWhitespace);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
const parts = getParts(group[0]);
|
|
319
|
-
if (parts) {
|
|
320
|
-
return trimLeft(parts, isWhitespace);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
function trimRight(group, isWhitespace) {
|
|
325
|
-
let lastNonWhitespace = group.length ? findLastIndex((doc) => !isEmptyDoc(doc) && !isWhitespace(doc), group) : 0;
|
|
326
|
-
if (lastNonWhitespace < group.length - 1) {
|
|
327
|
-
const removed = group.splice(lastNonWhitespace + 1);
|
|
328
|
-
if (removed.every(isEmptyDoc)) {
|
|
329
|
-
return trimRight(group, isWhitespace);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
else {
|
|
333
|
-
const parts = getParts(group[group.length - 1]);
|
|
334
|
-
if (parts) {
|
|
335
|
-
return trimRight(parts, isWhitespace);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
function getParts(doc) {
|
|
340
|
-
if (typeof doc === 'object') {
|
|
341
|
-
if (Array.isArray(doc)) {
|
|
342
|
-
return doc;
|
|
343
|
-
}
|
|
344
|
-
if (doc.type === 'fill' || doc.type === 'concat') {
|
|
345
|
-
return doc.parts;
|
|
346
|
-
}
|
|
347
|
-
if (doc.type === 'group') {
|
|
348
|
-
return getParts(doc.contents);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
function attachCommentsHTML(node) {
|
|
353
|
-
if (!isNodeWithChildren(node) || !node.children.some(({ type }) => type === 'Comment'))
|
|
354
|
-
return;
|
|
355
|
-
const nodesToRemove = [];
|
|
356
|
-
for (let n = 0; n < node.children.length - 1; n++) {
|
|
357
|
-
if (!node.children[n])
|
|
358
|
-
continue;
|
|
359
|
-
if (node.children[n].type === 'Comment') {
|
|
360
|
-
let next = n + 1;
|
|
361
|
-
while (isEmptyTextNode(node.children[next])) {
|
|
362
|
-
nodesToRemove.push(next);
|
|
363
|
-
next++;
|
|
212
|
+
mindent = Math.min(mindent, indent);
|
|
364
213
|
}
|
|
365
|
-
prettier.util.addLeadingComment(node.children[next], node.children[n]);
|
|
366
214
|
}
|
|
367
|
-
}
|
|
368
|
-
nodesToRemove.reverse();
|
|
369
|
-
nodesToRemove.forEach((index) => {
|
|
370
|
-
node.children.splice(index, 1);
|
|
371
215
|
});
|
|
372
|
-
|
|
373
|
-
function
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
if (line[0] && /^[^\s]/.test(line[0])) {
|
|
382
|
-
minTabSize = 0;
|
|
383
|
-
break;
|
|
384
|
-
}
|
|
385
|
-
const match = line.match(/^(\s+)\S+/);
|
|
386
|
-
if (match) {
|
|
387
|
-
if (match[1] && !char)
|
|
388
|
-
char = match[1][0];
|
|
389
|
-
if (match[1].length < minTabSize)
|
|
390
|
-
minTabSize = match[1].length;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
if (minTabSize > 0 && Number.isFinite(minTabSize)) {
|
|
394
|
-
result = result.replace(new RegExp(`^${new Array(minTabSize + 1).join(char)}`, 'gm'), '');
|
|
216
|
+
if (mindent !== null) {
|
|
217
|
+
(function () {
|
|
218
|
+
var m = mindent;
|
|
219
|
+
result = lines
|
|
220
|
+
.map(function (l) {
|
|
221
|
+
return l[0] === ' ' ? l.slice(m) : l;
|
|
222
|
+
})
|
|
223
|
+
.join('\n');
|
|
224
|
+
})();
|
|
395
225
|
}
|
|
396
226
|
return {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
227
|
+
result: result
|
|
228
|
+
.trim()
|
|
229
|
+
.replace(/\\n/g, '\n'),
|
|
400
230
|
};
|
|
401
231
|
}
|
|
402
232
|
function getMarkdownName(script) {
|
|
@@ -423,119 +253,27 @@ function getMarkdownName(script) {
|
|
|
423
253
|
return new Set(['Markdown']);
|
|
424
254
|
}
|
|
425
255
|
function isTextNode(node) {
|
|
426
|
-
return node.type === '
|
|
427
|
-
}
|
|
428
|
-
function isDocCommand(doc) {
|
|
429
|
-
if (typeof doc === 'string')
|
|
430
|
-
return false;
|
|
431
|
-
if (Array.isArray(doc))
|
|
432
|
-
return false;
|
|
433
|
-
return true;
|
|
434
|
-
}
|
|
435
|
-
function isInsideQuotedAttribute(path) {
|
|
436
|
-
const stack = path.stack;
|
|
437
|
-
return stack.some((node) => node.type === 'Attribute' && !isLoneMustacheTag(node.value));
|
|
256
|
+
return node.type === 'text';
|
|
438
257
|
}
|
|
439
258
|
|
|
440
259
|
const { builders: { breakParent, dedent, fill, group, hardline, indent, join, line, literalline, softline }, utils: { removeLines, stripTrailingHardline }, } = _doc__default["default"];
|
|
441
|
-
function printTopLevelParts(node, path, opts, print) {
|
|
442
|
-
let docs = [];
|
|
443
|
-
const normalize = (doc) => [stripTrailingHardline(doc), hardline];
|
|
444
|
-
if (node.module) {
|
|
445
|
-
const subDoc = normalize(path.call(print, 'module'));
|
|
446
|
-
docs.push(subDoc);
|
|
447
|
-
}
|
|
448
|
-
for (const section of parseSortOrder(opts.astroSortOrder)) {
|
|
449
|
-
switch (section) {
|
|
450
|
-
case 'markup': {
|
|
451
|
-
const subDoc = path.call(print, 'html');
|
|
452
|
-
if (!isEmptyDoc(subDoc))
|
|
453
|
-
docs.push(normalize(subDoc));
|
|
454
|
-
break;
|
|
455
|
-
}
|
|
456
|
-
case 'styles': {
|
|
457
|
-
const subDoc = path.call(print, 'css');
|
|
458
|
-
if (!isEmptyDoc(subDoc))
|
|
459
|
-
docs.push(normalize(subDoc));
|
|
460
|
-
break;
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
return join(softline, docs);
|
|
465
|
-
}
|
|
466
|
-
function printAttributeNodeValue(path, print, quotes, node) {
|
|
467
|
-
const valueDocs = path.map((childPath) => childPath.call(print), 'value');
|
|
468
|
-
if (!quotes || !formattableAttributes.includes(node.name)) {
|
|
469
|
-
return valueDocs;
|
|
470
|
-
}
|
|
471
|
-
else {
|
|
472
|
-
return indent(group(trim(valueDocs, isLine)));
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
function printJS(path, print, name, { forceSingleQuote, forceSingleLine }) {
|
|
476
|
-
path.getValue()[name].isJS = true;
|
|
477
|
-
path.getValue()[name].forceSingleQuote = forceSingleQuote;
|
|
478
|
-
path.getValue()[name].forceSingleLine = forceSingleLine;
|
|
479
|
-
return path.call(print, name);
|
|
480
|
-
}
|
|
481
260
|
function printComment(commentPath, options) {
|
|
482
261
|
return commentPath;
|
|
483
262
|
}
|
|
484
263
|
function print(path, opts, print) {
|
|
485
|
-
var _a, _b;
|
|
486
264
|
const node = path.getValue();
|
|
487
|
-
const isMarkdownSubDoc = opts.parentParser === 'markdown';
|
|
488
265
|
if (!node) {
|
|
489
266
|
return '';
|
|
490
267
|
}
|
|
491
268
|
if (typeof node === 'string') {
|
|
492
269
|
return node;
|
|
493
270
|
}
|
|
494
|
-
if (Array.isArray(node)) {
|
|
495
|
-
return path.map((childPath) => childPath.call(print));
|
|
496
|
-
}
|
|
497
|
-
if (isASTNode(node)) {
|
|
498
|
-
return printTopLevelParts(node, path, opts, print);
|
|
499
|
-
}
|
|
500
|
-
if (!isPreTagContent(path) && !isMarkdownSubDoc) {
|
|
501
|
-
attachCommentsHTML(node);
|
|
502
|
-
}
|
|
503
271
|
switch (node.type) {
|
|
504
|
-
case '
|
|
505
|
-
|
|
506
|
-
if (text.length === 0) {
|
|
507
|
-
return '';
|
|
508
|
-
}
|
|
509
|
-
if (!isNodeWithChildren(node) || node.children.every(isEmptyTextNode))
|
|
510
|
-
return '';
|
|
511
|
-
const hasInlineComponent = node.children.filter((x) => x.type === 'InlineComponent').length > 0;
|
|
512
|
-
if (text.indexOf('{') === -1 && !hasInlineComponent) {
|
|
513
|
-
node.__isRawHTML = true;
|
|
514
|
-
node.content = text;
|
|
515
|
-
return path.call(print);
|
|
516
|
-
}
|
|
517
|
-
if (!isPreTagContent(path)) {
|
|
518
|
-
trimChildren(node.children);
|
|
519
|
-
const output = trim([path.map(print, 'children')], (n) => isLine(n) ||
|
|
520
|
-
(typeof n === 'string' && n.trim() === '') ||
|
|
521
|
-
n === breakParent);
|
|
522
|
-
if (output.every((doc) => isEmptyDoc(doc))) {
|
|
523
|
-
return '';
|
|
524
|
-
}
|
|
525
|
-
return group([...output, hardline]);
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
return group(path.map(print, 'children'));
|
|
529
|
-
}
|
|
272
|
+
case 'root': {
|
|
273
|
+
return [stripTrailingHardline(path.map(print, 'children')), hardline];
|
|
530
274
|
}
|
|
531
|
-
case '
|
|
275
|
+
case 'text': {
|
|
532
276
|
const rawText = getUnencodedText(node);
|
|
533
|
-
if (isPreTagContent(path)) {
|
|
534
|
-
if (((_a = path.getParentNode()) === null || _a === void 0 ? void 0 : _a.type) === 'Attribute') {
|
|
535
|
-
return replaceEndOfLineWith(rawText, literalline);
|
|
536
|
-
}
|
|
537
|
-
return rawText;
|
|
538
|
-
}
|
|
539
277
|
if (isEmptyTextNode(node)) {
|
|
540
278
|
const hasWhiteSpace = rawText.trim().length < getUnencodedText(node).length;
|
|
541
279
|
const hasOneOrMoreNewlines = /\n/.test(getUnencodedText(node));
|
|
@@ -553,37 +291,20 @@ function print(path, opts, print) {
|
|
|
553
291
|
}
|
|
554
292
|
return fill(splitTextToDocs(node));
|
|
555
293
|
}
|
|
556
|
-
case '
|
|
557
|
-
case '
|
|
558
|
-
case '
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
if (isSelfClosingTag) {
|
|
563
|
-
return group(['<', node.name, indent(group(attributes)), line, `/>`]);
|
|
294
|
+
case 'component':
|
|
295
|
+
case 'fragment':
|
|
296
|
+
case 'element': {
|
|
297
|
+
let isEmpty;
|
|
298
|
+
if (!node.children) {
|
|
299
|
+
isEmpty = true;
|
|
564
300
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
const attributesWithLowercaseHTML = attributes.map((attribute) => {
|
|
568
|
-
if (typeof attribute === 'string')
|
|
569
|
-
return attribute;
|
|
570
|
-
if (isDocCommand(attribute))
|
|
571
|
-
return attribute;
|
|
572
|
-
attribute = attribute.map((attrValue) => {
|
|
573
|
-
if (typeof attrValue !== 'string')
|
|
574
|
-
return attrValue;
|
|
575
|
-
if (attrValue.toLowerCase() === 'html') {
|
|
576
|
-
attrValue = attrValue.toLowerCase();
|
|
577
|
-
}
|
|
578
|
-
return attrValue;
|
|
579
|
-
});
|
|
580
|
-
return attribute;
|
|
581
|
-
});
|
|
582
|
-
return group(['<', node.name.toUpperCase(), ...attributesWithLowercaseHTML, `>`]);
|
|
583
|
-
}
|
|
301
|
+
else {
|
|
302
|
+
isEmpty = node.children.every((child) => isEmptyTextNode(child));
|
|
584
303
|
}
|
|
585
|
-
|
|
586
|
-
|
|
304
|
+
const isSelfClosingTag = isEmpty && (node.type !== 'element' || selfClosingTags.indexOf(node.name) !== -1);
|
|
305
|
+
const attributes = node.attributes ? path.map(print, 'attributes') : [];
|
|
306
|
+
if (isSelfClosingTag) {
|
|
307
|
+
return group(['<', node.name, indent(group(attributes)), line, `/>`]);
|
|
587
308
|
}
|
|
588
309
|
if (node.children) {
|
|
589
310
|
const children = node.children;
|
|
@@ -602,7 +323,7 @@ function print(path, opts, print) {
|
|
|
602
323
|
() => softline;
|
|
603
324
|
}
|
|
604
325
|
else if (isPreTagContent(path)) {
|
|
605
|
-
body = () => printRaw(node
|
|
326
|
+
body = () => printRaw(node);
|
|
606
327
|
}
|
|
607
328
|
else if (isInlineElement(path, opts, node) && !isPreTagContent(path)) {
|
|
608
329
|
body = () => path.map(print, 'children');
|
|
@@ -635,7 +356,7 @@ function print(path, opts, print) {
|
|
|
635
356
|
}
|
|
636
357
|
if (!hugEnd && lastChild && isTextNode(lastChild)) {
|
|
637
358
|
if (isInlineElement(path, opts, node) && !didSetEndSeparator) {
|
|
638
|
-
noHugSeparatorEnd =
|
|
359
|
+
noHugSeparatorEnd = softline;
|
|
639
360
|
}
|
|
640
361
|
trimTextNodeRight(lastChild);
|
|
641
362
|
}
|
|
@@ -651,57 +372,35 @@ function print(path, opts, print) {
|
|
|
651
372
|
}
|
|
652
373
|
return group([...openingTag, '>', indent([noHugSeparatorStart, body()]), noHugSeparatorEnd, `</${node.name}>`]);
|
|
653
374
|
}
|
|
375
|
+
return '';
|
|
376
|
+
}
|
|
377
|
+
case 'attribute': {
|
|
378
|
+
const name = node.name.trim();
|
|
379
|
+
const quote = opts.singleQuote ? "'" : '"';
|
|
380
|
+
switch (node.kind) {
|
|
381
|
+
case 'empty':
|
|
382
|
+
return [line, name];
|
|
383
|
+
case 'expression':
|
|
384
|
+
return '';
|
|
385
|
+
case 'quoted':
|
|
386
|
+
return [line, name, '=', quote, node.value, quote];
|
|
387
|
+
case 'shorthand':
|
|
388
|
+
return [line, '{', name, '}'];
|
|
389
|
+
case 'spread':
|
|
390
|
+
return [line, '{...', name, '}'];
|
|
391
|
+
case 'template-literal':
|
|
392
|
+
return [line, name, '=', '`', node.value, '`'];
|
|
393
|
+
}
|
|
394
|
+
return '';
|
|
654
395
|
}
|
|
655
|
-
case '
|
|
656
|
-
return node.
|
|
396
|
+
case 'directive': {
|
|
397
|
+
return [line, node.name];
|
|
657
398
|
}
|
|
658
|
-
case '
|
|
659
|
-
|
|
660
|
-
return [line, '{', node.name, '}'];
|
|
661
|
-
}
|
|
662
|
-
else {
|
|
663
|
-
if (node.value === true) {
|
|
664
|
-
return [line, node.name];
|
|
665
|
-
}
|
|
666
|
-
const quotes = !isLoneMustacheTag(node.value);
|
|
667
|
-
const attrNodeValue = printAttributeNodeValue(path, print, quotes, node);
|
|
668
|
-
if (quotes) {
|
|
669
|
-
return [line, node.name, '=', '"', attrNodeValue, '"'];
|
|
670
|
-
}
|
|
671
|
-
else {
|
|
672
|
-
return [line, node.name, '=', attrNodeValue];
|
|
673
|
-
}
|
|
674
|
-
}
|
|
399
|
+
case 'doctype': {
|
|
400
|
+
return ['<!DOCTYPE html>', hardline];
|
|
675
401
|
}
|
|
676
|
-
case '
|
|
677
|
-
return [];
|
|
678
|
-
case 'MustacheTag':
|
|
679
|
-
return [
|
|
680
|
-
'{',
|
|
681
|
-
printJS(path, print, 'expression', {
|
|
682
|
-
forceSingleLine: isInsideQuotedAttribute(path),
|
|
683
|
-
forceSingleQuote: opts.jsxSingleQuote,
|
|
684
|
-
}),
|
|
685
|
-
'}',
|
|
686
|
-
];
|
|
687
|
-
case 'Spread':
|
|
688
|
-
return [
|
|
689
|
-
line,
|
|
690
|
-
'{...',
|
|
691
|
-
printJS(path, print, 'expression', {
|
|
692
|
-
forceSingleQuote: true,
|
|
693
|
-
forceSingleLine: false,
|
|
694
|
-
}),
|
|
695
|
-
'}',
|
|
696
|
-
];
|
|
697
|
-
case 'Comment':
|
|
402
|
+
case 'comment':
|
|
698
403
|
return ['<!--', getUnencodedText(node), '-->'];
|
|
699
|
-
case 'CodeSpan':
|
|
700
|
-
return getUnencodedText(node);
|
|
701
|
-
case 'CodeFence': {
|
|
702
|
-
console.debug(node);
|
|
703
|
-
return [node.metadata, hardline, node.data, hardline, '```', hardline];
|
|
704
|
-
}
|
|
705
404
|
default: {
|
|
706
405
|
throw new Error(`Unhandled node type "${node.type}"!`);
|
|
707
406
|
}
|
|
@@ -726,7 +425,7 @@ function splitTextToDocs(node) {
|
|
|
726
425
|
return docs;
|
|
727
426
|
}
|
|
728
427
|
function expressionParser(text, parsers, opts) {
|
|
729
|
-
const ast = parsers.babel(text,
|
|
428
|
+
const ast = parsers.babel(text, opts);
|
|
730
429
|
return { ...ast, program: ast.program.body[0].expression };
|
|
731
430
|
}
|
|
732
431
|
let markdownComponentName = new Set();
|
|
@@ -736,47 +435,52 @@ function embed(path, print, textToDoc, opts) {
|
|
|
736
435
|
const node = path.getValue();
|
|
737
436
|
if (!node)
|
|
738
437
|
return null;
|
|
739
|
-
if (node.
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
if (node.forceSingleQuote) {
|
|
745
|
-
embeddedopts.singleQuote = true;
|
|
746
|
-
}
|
|
747
|
-
const docs = textToDoc(forceIntoExpression(getText(node, opts)), embeddedopts);
|
|
748
|
-
return node.forceSingleLine ? removeLines(docs) : docs;
|
|
749
|
-
}
|
|
750
|
-
catch (e) {
|
|
751
|
-
return getText(node, opts);
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
if (node.type === 'Script' && node.context === 'setup') {
|
|
755
|
-
markdownComponentName = getMarkdownName(node.content);
|
|
756
|
-
return group(['---', hardline, textToDoc(node.content, { ...opts, parser: 'typescript' }), '---', hardline]);
|
|
757
|
-
}
|
|
758
|
-
if (isTextNode(node)) {
|
|
759
|
-
const parent = path.getParentNode();
|
|
760
|
-
if (parent && parent.type === 'Element' && parent.name === 'script') {
|
|
761
|
-
const formatttedScript = textToDoc(node.data, { ...opts, parser: 'typescript' });
|
|
762
|
-
return stripTrailingHardline(formatttedScript);
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
if (node.type === 'Style' || (node.type === 'Element' && node.name === 'style')) {
|
|
766
|
-
let styleTagContent = '';
|
|
767
|
-
if (node.type === 'Style') {
|
|
768
|
-
styleTagContent = node.content.styles;
|
|
769
|
-
}
|
|
770
|
-
else if (node.children) {
|
|
771
|
-
const children = node.children[0];
|
|
772
|
-
styleTagContent = getUnencodedText(children);
|
|
438
|
+
if (node.type === 'expression') {
|
|
439
|
+
const textContent = getText(node, opts);
|
|
440
|
+
let content;
|
|
441
|
+
if (node.children.length === 1) {
|
|
442
|
+
content = textContent;
|
|
773
443
|
}
|
|
444
|
+
else {
|
|
445
|
+
content = textToDoc(textContent, { ...opts, parser: 'babel-ts', semi: false });
|
|
446
|
+
content = stripTrailingHardline(content);
|
|
447
|
+
}
|
|
448
|
+
return [
|
|
449
|
+
'{',
|
|
450
|
+
content,
|
|
451
|
+
'}',
|
|
452
|
+
];
|
|
453
|
+
}
|
|
454
|
+
if (node.type === 'attribute' && node.kind === 'expression') {
|
|
455
|
+
const value = node.value.trim();
|
|
456
|
+
const name = node.name.trim();
|
|
457
|
+
let attrNodeValue = textToDoc(forceIntoExpression(value), { ...opts, parser: expressionParser, semi: false });
|
|
458
|
+
attrNodeValue = stripTrailingHardline(attrNodeValue);
|
|
459
|
+
if (name === value && opts.astroAllowShorthand) {
|
|
460
|
+
return [line, '{', attrNodeValue, '}'];
|
|
461
|
+
}
|
|
462
|
+
return [line, name, '=', '{', attrNodeValue, '}'];
|
|
463
|
+
}
|
|
464
|
+
if (node.type === 'frontmatter') {
|
|
465
|
+
markdownComponentName = getMarkdownName(node.value);
|
|
466
|
+
return [group(['---', hardline, textToDoc(node.value, { ...opts, parser: 'typescript' }), '---', hardline]), hardline];
|
|
467
|
+
}
|
|
468
|
+
if (node.type === 'element' && node.name === 'script') {
|
|
469
|
+
const scriptContent = node.children[0].value;
|
|
470
|
+
let formatttedScript = textToDoc(scriptContent, { ...opts, parser: 'typescript' });
|
|
471
|
+
formatttedScript = stripTrailingHardline(formatttedScript);
|
|
472
|
+
const attributes = node.attributes ? path.map(print, 'attributes') : [];
|
|
473
|
+
const openingTag = group(['<script', indent(group(attributes)), softline, '>']);
|
|
474
|
+
return [openingTag, indent([hardline, formatttedScript]), hardline, '</script>'];
|
|
475
|
+
}
|
|
476
|
+
if (node.type === 'element' && node.name === 'style') {
|
|
477
|
+
let styleTagContent = node.children[0].value.trim();
|
|
774
478
|
const supportedStyleLangValues = ['css', 'scss', 'sass'];
|
|
775
479
|
let parserLang = 'css';
|
|
776
|
-
if (
|
|
480
|
+
if (node.attributes) {
|
|
777
481
|
const langAttribute = node.attributes.filter((x) => x.name === 'lang');
|
|
778
482
|
if (langAttribute.length) {
|
|
779
|
-
const styleLang = langAttribute[0].value
|
|
483
|
+
const styleLang = langAttribute[0].value.toLowerCase();
|
|
780
484
|
if (supportedStyleLangValues.includes(styleLang))
|
|
781
485
|
parserLang = styleLang;
|
|
782
486
|
}
|
|
@@ -786,8 +490,10 @@ function embed(path, print, textToDoc, opts) {
|
|
|
786
490
|
case 'scss': {
|
|
787
491
|
let formattedStyles = textToDoc(styleTagContent, { ...opts, parser: parserLang });
|
|
788
492
|
formattedStyles = stripTrailingHardline(formattedStyles);
|
|
789
|
-
const attributes = path.map(print, 'attributes');
|
|
790
|
-
const
|
|
493
|
+
const attributes = node.attributes ? path.map(print, 'attributes') : [];
|
|
494
|
+
const directives = node.directives ? path.map(print, 'directives') : [];
|
|
495
|
+
const attrAndDirectives = directives.concat(attributes);
|
|
496
|
+
const openingTag = group(['<style', indent(group(attrAndDirectives)), softline, '>']);
|
|
791
497
|
return [openingTag, indent([hardline, formattedStyles]), hardline, '</style>'];
|
|
792
498
|
}
|
|
793
499
|
case 'sass': {
|
|
@@ -797,17 +503,17 @@ function embed(path, print, textToDoc, opts) {
|
|
|
797
503
|
insertSpaces: !opts.useTabs,
|
|
798
504
|
lineEnding,
|
|
799
505
|
};
|
|
800
|
-
const { result: raw } =
|
|
506
|
+
const { result: raw } = manualDedent(styleTagContent);
|
|
801
507
|
let formattedSassIndented = sassFormatter.SassFormatter.Format(raw, sassOptions).trim();
|
|
802
508
|
const formattedSass = join(hardline, formattedSassIndented.split('\n'));
|
|
803
|
-
const attributes = path.map(print, 'attributes');
|
|
509
|
+
const attributes = node.attributes ? path.map(print, 'attributes') : [];
|
|
804
510
|
const openingTag = group(['<style', indent(group(attributes)), softline, '>']);
|
|
805
511
|
return [openingTag, indent(group([hardline, formattedSass])), hardline, '</style>'];
|
|
806
512
|
}
|
|
807
513
|
}
|
|
808
514
|
}
|
|
809
|
-
if (node.type === '
|
|
810
|
-
let content = printRaw(node
|
|
515
|
+
if (node.type === 'component' && markdownComponentName.has(node.name)) {
|
|
516
|
+
let content = printRaw(node);
|
|
811
517
|
content = content.replace(/\r\n/g, '\n');
|
|
812
518
|
const contentArr = content.split('\n').map((s) => s.trimStart());
|
|
813
519
|
content = contentArr.join('\n');
|
|
@@ -817,17 +523,10 @@ function embed(path, print, textToDoc, opts) {
|
|
|
817
523
|
const openingTag = group([`<${node.name}`, indent(group(attributes)), softline, '>']);
|
|
818
524
|
return [openingTag, indent(group([hardline, formatttedMarkdown])), hardline, `</${node.name}>`];
|
|
819
525
|
}
|
|
820
|
-
if (node.__isRawHTML) {
|
|
821
|
-
return textToDoc(node.content, { ...opts, parser: 'html' });
|
|
822
|
-
}
|
|
823
526
|
return null;
|
|
824
527
|
}
|
|
825
528
|
function hasPrettierIgnore(path) {
|
|
826
|
-
|
|
827
|
-
if (!node || !Array.isArray(node.comments))
|
|
828
|
-
return false;
|
|
829
|
-
const hasIgnore = node.comments.some((comment) => comment.data.includes('prettier-ignore') && !comment.data.includes('prettier-ignore-start') && !comment.data.includes('prettier-ignore-end'));
|
|
830
|
-
return hasIgnore;
|
|
529
|
+
return false;
|
|
831
530
|
}
|
|
832
531
|
const printer = {
|
|
833
532
|
print,
|
|
@@ -836,6 +535,33 @@ const printer = {
|
|
|
836
535
|
hasPrettierIgnore,
|
|
837
536
|
};
|
|
838
537
|
|
|
538
|
+
const options = {
|
|
539
|
+
astroSortOrder: {
|
|
540
|
+
since: '0.0.1',
|
|
541
|
+
category: 'Astro',
|
|
542
|
+
type: 'choice',
|
|
543
|
+
default: 'markup | styles',
|
|
544
|
+
description: 'Sort order for markup, scripts, and styles',
|
|
545
|
+
choices: [
|
|
546
|
+
{
|
|
547
|
+
value: 'markup | styles',
|
|
548
|
+
description: 'markup | styles',
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
value: 'styles | markup',
|
|
552
|
+
description: 'styles | markup',
|
|
553
|
+
},
|
|
554
|
+
],
|
|
555
|
+
},
|
|
556
|
+
astroAllowShorthand: {
|
|
557
|
+
since: '0.0.10',
|
|
558
|
+
category: 'Astro',
|
|
559
|
+
type: 'boolean',
|
|
560
|
+
default: true,
|
|
561
|
+
description: 'Enable/disable attribute shorthand if attribute name and expression are the same',
|
|
562
|
+
},
|
|
563
|
+
};
|
|
564
|
+
|
|
839
565
|
const languages = [
|
|
840
566
|
{
|
|
841
567
|
name: 'astro',
|