prettier-plugin-astro 0.0.8 → 0.0.12
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 +40 -0
- package/README.md +5 -3
- package/dist/index.js +872 -0
- package/dist/index.js.map +1 -0
- package/package.json +29 -11
- package/.changeset/README.md +0 -8
- package/.changeset/config.json +0 -10
- package/.eslintrc +0 -9
- package/.github/CODEOWNERS +0 -1
- package/.github/ISSUE_TEMPLATE/---01-bug-report.yml +0 -31
- package/.github/ISSUE_TEMPLATE/---02-feature-request.yml +0 -50
- package/.github/ISSUE_TEMPLATE/---03-documentation.md +0 -7
- package/.github/ISSUE_TEMPLATE/config.yml +0 -8
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -15
- package/.github/dependabot.yml +0 -10
- package/.github/workflows/ci.yml +0 -24
- package/.github/workflows/format.yml +0 -29
- package/.github/workflows/release.yml +0 -52
- package/.gitpod.yml +0 -9
- package/.prettierignore +0 -1
- package/.prettierrc.json +0 -7
- package/jsconfig.json +0 -3
- package/src/index.d.ts +0 -9
- package/src/index.js +0 -38
- package/src/options.js +0 -24
- package/src/parse.js +0 -8
- package/src/printer.js +0 -452
- package/src/utils.js +0 -558
- package/test/astro-prettier.test.mjs +0 -123
- package/test/fixtures/in/attribute-with-embedded-expr.astro +0 -6
- package/test/fixtures/in/basic.astro +0 -13
- package/test/fixtures/in/converts-to-shorthand.astro +0 -5
- package/test/fixtures/in/doctype-with-embedded-expr.astro +0 -26
- package/test/fixtures/in/doctype-with-extra-attributes.astro +0 -26
- package/test/fixtures/in/embedded-expr.astro +0 -26
- package/test/fixtures/in/embedded-in-markdown.md +0 -332
- package/test/fixtures/in/expr-and-html-comment.astro +0 -20
- package/test/fixtures/in/frontmatter.astro +0 -18
- package/test/fixtures/in/html-comment.astro +0 -5
- package/test/fixtures/in/maximum-call-stack-size-exceeded.astro +0 -1
- package/test/fixtures/in/preserve-tag-case.astro +0 -8
- package/test/fixtures/in/single-style-element.astro +0 -9
- package/test/fixtures/in/unclosed-tag.astro +0 -42
- package/test/fixtures/in/with-codespans.astro +0 -19
- package/test/fixtures/in/with-indented-sass.astro +0 -20
- package/test/fixtures/in/with-script.astro +0 -8
- package/test/fixtures/in/with-scss.astro +0 -24
- package/test/fixtures/in/with-styles.astro +0 -21
- package/test/fixtures/out/attribute-with-embedded-expr.astro +0 -6
- package/test/fixtures/out/basic.astro +0 -12
- package/test/fixtures/out/converts-to-shorthand.astro +0 -6
- package/test/fixtures/out/doctype-with-embedded-expr.astro +0 -23
- package/test/fixtures/out/doctype-with-extra-attributes.astro +0 -23
- package/test/fixtures/out/embedded-expr.astro +0 -22
- package/test/fixtures/out/embedded-in-markdown.md +0 -336
- package/test/fixtures/out/expr-and-html-comment.astro +0 -5
- package/test/fixtures/out/frontmatter.astro +0 -16
- package/test/fixtures/out/html-comment.astro +0 -5
- package/test/fixtures/out/maximum-call-stack-size-exceeded.astro +0 -2
- package/test/fixtures/out/preserve-tag-case.astro +0 -8
- package/test/fixtures/out/single-style-element.astro +0 -9
- package/test/fixtures/out/unclosed-tag.astro +0 -34
- package/test/fixtures/out/with-codespans.astro +0 -17
- package/test/fixtures/out/with-indented-sass.astro +0 -17
- package/test/fixtures/out/with-script.astro +0 -8
- package/test/fixtures/out/with-scss.astro +0 -21
- package/test/fixtures/out/with-styles.astro +0 -18
- package/test/package.json +0 -3
- package/test/test-utils.mjs +0 -35
package/src/parse.js
DELETED
package/src/printer.js
DELETED
|
@@ -1,452 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
builders: { join, fill, line, literalline, hardline, softline, group, conditionalGroup, breakParent, indent, dedent },
|
|
3
|
-
utils: { removeLines },
|
|
4
|
-
} = require('prettier/doc');
|
|
5
|
-
|
|
6
|
-
const { parseSortOrder } = require('./options');
|
|
7
|
-
const {
|
|
8
|
-
isASTNode,
|
|
9
|
-
isEmptyTextNode,
|
|
10
|
-
isPreTagContent,
|
|
11
|
-
isInlineElement,
|
|
12
|
-
isEmptyDoc,
|
|
13
|
-
isTextNodeStartingWithWhitespace,
|
|
14
|
-
isTextNodeStartingWithLinebreak,
|
|
15
|
-
isTextNodeEndingWithWhitespace,
|
|
16
|
-
trimTextNodeLeft,
|
|
17
|
-
trimTextNodeRight,
|
|
18
|
-
isLoneMustacheTag,
|
|
19
|
-
isAttributeShorthand,
|
|
20
|
-
isOrCanBeConvertedToShorthand,
|
|
21
|
-
selfClosingTags,
|
|
22
|
-
formattableAttributes,
|
|
23
|
-
getUnencodedText,
|
|
24
|
-
replaceEndOfLineWith,
|
|
25
|
-
forceIntoExpression,
|
|
26
|
-
shouldHugStart,
|
|
27
|
-
shouldHugEnd,
|
|
28
|
-
canOmitSoftlineBeforeClosingTag,
|
|
29
|
-
startsWithLinebreak,
|
|
30
|
-
endsWithLinebreak,
|
|
31
|
-
printRaw,
|
|
32
|
-
trim,
|
|
33
|
-
isLine,
|
|
34
|
-
trimChildren,
|
|
35
|
-
flatten,
|
|
36
|
-
getText,
|
|
37
|
-
} = require('./utils');
|
|
38
|
-
|
|
39
|
-
const supportedStyleLangValues = ['css', 'scss'];
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
*
|
|
43
|
-
* @param {import('@astrojs/parser').Ast} node
|
|
44
|
-
* @param {import('prettier').AstPath<import('@astrojs/parser').Ast>} path
|
|
45
|
-
* @param {import('prettier').Parseropts<any>} opts
|
|
46
|
-
* @param {(path: import('prettier').AstPath<any>) => import('prettier').Doc} print
|
|
47
|
-
*/
|
|
48
|
-
const printTopLevelParts = (node, path, opts, print) => {
|
|
49
|
-
const parts = {
|
|
50
|
-
frontmatter: [],
|
|
51
|
-
markup: [],
|
|
52
|
-
styles: [],
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
if (node.module) {
|
|
56
|
-
parts.frontmatter.push(path.call(print, 'module'));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (node.css) {
|
|
60
|
-
parts.styles.push(path.call(print, 'css'));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (node.html) {
|
|
64
|
-
parts.markup.push(path.call(print, 'html'));
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const docs = flatten([parts.frontmatter, ...parseSortOrder(opts.astroSortOrder).map((p) => parts[p])]).filter((doc) => '' !== doc);
|
|
68
|
-
return group([join(hardline, docs)]);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const printAttributeNodeValue = (path, print, quotes, node) => {
|
|
72
|
-
const valueDocs = path.map((childPath) => childPath.call(print), 'value');
|
|
73
|
-
|
|
74
|
-
if (!quotes || !formattableAttributes.includes(node.name)) {
|
|
75
|
-
return valueDocs;
|
|
76
|
-
} else {
|
|
77
|
-
return indent(group(trim(valueDocs, isLine)));
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
function printJS(path, print, name, { forceSingleQuote, forceSingleLine }) {
|
|
82
|
-
path.getValue()[name].isJS = true;
|
|
83
|
-
path.getValue()[name].forceSingleQuote = forceSingleQuote;
|
|
84
|
-
path.getValue()[name].forceSingleLine = forceSingleLine;
|
|
85
|
-
return path.call(print, name);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** @type {import('prettier').Printer['print']} */
|
|
89
|
-
const print = (path, opts, print) => {
|
|
90
|
-
const node = path.getValue();
|
|
91
|
-
|
|
92
|
-
switch (true) {
|
|
93
|
-
case !node:
|
|
94
|
-
return '';
|
|
95
|
-
case typeof node === 'string':
|
|
96
|
-
return node;
|
|
97
|
-
case Array.isArray(node):
|
|
98
|
-
return path.map((childPath) => childPath.call(print));
|
|
99
|
-
case isASTNode(node):
|
|
100
|
-
return printTopLevelParts(node, path, opts, print);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
switch (node.type) {
|
|
104
|
-
case 'Fragment': {
|
|
105
|
-
const text = getText(node, opts);
|
|
106
|
-
if (text.length === 0) {
|
|
107
|
-
return '';
|
|
108
|
-
}
|
|
109
|
-
// If we don't see any JSX expressions, this is just embedded HTML
|
|
110
|
-
// and we can skip a bunch of work. Hooray!
|
|
111
|
-
const hasInlineComponent = node.children.filter((x) => x.type === 'InlineComponent').length > 0;
|
|
112
|
-
if (text.indexOf('{') === -1 && !hasInlineComponent) {
|
|
113
|
-
node.__isRawHTML = true;
|
|
114
|
-
node.content = text;
|
|
115
|
-
return path.call(print);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const children = node.children;
|
|
119
|
-
|
|
120
|
-
if (children.length === 0 || children.every(isEmptyTextNode)) {
|
|
121
|
-
return '';
|
|
122
|
-
}
|
|
123
|
-
if (!isPreTagContent(path)) {
|
|
124
|
-
trimChildren(node.children, path);
|
|
125
|
-
const output = trim(
|
|
126
|
-
[path.map(print, 'children')],
|
|
127
|
-
(n) =>
|
|
128
|
-
isLine(n) ||
|
|
129
|
-
(typeof n === 'string' && n.trim() === '') ||
|
|
130
|
-
// Because printChildren may append this at the end and
|
|
131
|
-
// may hide other lines before it
|
|
132
|
-
n === breakParent
|
|
133
|
-
);
|
|
134
|
-
if (output.every((doc) => isEmptyDoc(doc))) {
|
|
135
|
-
return '';
|
|
136
|
-
}
|
|
137
|
-
return group([...output, hardline]);
|
|
138
|
-
} else {
|
|
139
|
-
return group(path.map(print, 'children'));
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
case 'Text':
|
|
143
|
-
if (!isPreTagContent(path)) {
|
|
144
|
-
if (isEmptyTextNode(node)) {
|
|
145
|
-
const hasWhiteSpace = getUnencodedText(node).trim().length < getUnencodedText(node).length;
|
|
146
|
-
const hasOneOrMoreNewlines = /\n/.test(getUnencodedText(node));
|
|
147
|
-
const hasTwoOrMoreNewlines = /\n\r?\s*\n\r?/.test(getUnencodedText(node));
|
|
148
|
-
if (hasTwoOrMoreNewlines) {
|
|
149
|
-
return [hardline, hardline];
|
|
150
|
-
}
|
|
151
|
-
if (hasOneOrMoreNewlines) {
|
|
152
|
-
return hardline;
|
|
153
|
-
}
|
|
154
|
-
if (hasWhiteSpace) {
|
|
155
|
-
return line;
|
|
156
|
-
}
|
|
157
|
-
return '';
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* For non-empty text nodes each sequence of non-whitespace characters (effectively,
|
|
162
|
-
* each "word") is joined by a single `line`, which will be rendered as a single space
|
|
163
|
-
* until this node's current line is out of room, at which `fill` will break at the
|
|
164
|
-
* most convenient instance of `line`.
|
|
165
|
-
*/
|
|
166
|
-
return fill(splitTextToDocs(node));
|
|
167
|
-
} else {
|
|
168
|
-
const rawText = getUnencodedText(node);
|
|
169
|
-
if (path.getParentNode().type === 'Attribute') {
|
|
170
|
-
// Direct child of attribute value -> add literallines at end of lines
|
|
171
|
-
// so that other things don't break in unexpected places
|
|
172
|
-
return replaceEndOfLineWith(rawText, literalline);
|
|
173
|
-
}
|
|
174
|
-
return rawText;
|
|
175
|
-
}
|
|
176
|
-
case 'Element':
|
|
177
|
-
case 'InlineComponent':
|
|
178
|
-
case 'Slot':
|
|
179
|
-
case 'SlotTemplate':
|
|
180
|
-
case 'Window':
|
|
181
|
-
case 'Head':
|
|
182
|
-
case 'Title': {
|
|
183
|
-
const isEmpty = node.children.every((child) => isEmptyTextNode(child));
|
|
184
|
-
const isSelfClosingTag = isEmpty && (node.type !== 'Element' || selfClosingTags.indexOf(node.name) !== -1);
|
|
185
|
-
const attributes = path.map((childPath) => childPath.call(print), 'attributes');
|
|
186
|
-
|
|
187
|
-
if (isSelfClosingTag) {
|
|
188
|
-
return group(['<', node.name, indent(group([...attributes, opts.jsxBracketNewLine ? dedent(line) : ''])), ...[opts.jsxBracketNewLine ? '' : ' ', `/>`]]);
|
|
189
|
-
}
|
|
190
|
-
try {
|
|
191
|
-
if (node.name.toLowerCase() === '!doctype') {
|
|
192
|
-
attributesWithLowercaseHTML = attributes.map((attribute) => {
|
|
193
|
-
if (attribute[0].type === 'line' && attribute[1].toLowerCase() === 'html') {
|
|
194
|
-
attribute[1] = attribute[1].toLowerCase();
|
|
195
|
-
return attribute;
|
|
196
|
-
}
|
|
197
|
-
return attribute;
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
return group(['<', node.name.toUpperCase(), ...attributesWithLowercaseHTML, `>`]);
|
|
201
|
-
}
|
|
202
|
-
} catch (e) {
|
|
203
|
-
console.warn(`error ${e} in the doctype printing`);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const children = node.children;
|
|
207
|
-
const firstChild = children[0];
|
|
208
|
-
const lastChild = children[children.length - 1];
|
|
209
|
-
|
|
210
|
-
const hugStart = shouldHugStart(node, opts);
|
|
211
|
-
const hugEnd = shouldHugEnd(node, opts);
|
|
212
|
-
|
|
213
|
-
let body;
|
|
214
|
-
|
|
215
|
-
if (isEmpty) {
|
|
216
|
-
body =
|
|
217
|
-
isInlineElement(path, opts, node) && node.children.length && isTextNodeStartingWithWhitespace(node.children[0]) && !isPreTagContent(path)
|
|
218
|
-
? () => line
|
|
219
|
-
: () => (opts.jsxBracketNewLine ? '' : softline);
|
|
220
|
-
} else if (isPreTagContent(path)) {
|
|
221
|
-
body = () => printRaw(node, opts.originalText);
|
|
222
|
-
} else if (isInlineElement(path, opts, node) && !isPreTagContent(path)) {
|
|
223
|
-
body = () => path.map(print, 'children');
|
|
224
|
-
} else {
|
|
225
|
-
body = () => path.map(print, 'children');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const openingTag = ['<', node.name, indent(group([...attributes, hugStart ? '' : opts.jsxBracketNewLine && !isPreTagContent(path) ? dedent(softline) : '']))];
|
|
229
|
-
|
|
230
|
-
if (hugStart && hugEnd) {
|
|
231
|
-
const huggedContent = [softline, group(['>', body(), `</${node.name}`])];
|
|
232
|
-
const omitSoftlineBeforeClosingTag = (isEmpty && opts.jsxBracketNewLine) || canOmitSoftlineBeforeClosingTag(node, path, opts);
|
|
233
|
-
return group([...openingTag, isEmpty ? group(huggedContent) : group(indent(huggedContent)), omitSoftlineBeforeClosingTag ? '' : softline, '>']);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// No hugging of content means it's either a block element and/or there's whitespace at the start/end
|
|
237
|
-
let noHugSeparatorStart = softline;
|
|
238
|
-
let noHugSeparatorEnd = softline;
|
|
239
|
-
if (isPreTagContent(path)) {
|
|
240
|
-
noHugSeparatorStart = '';
|
|
241
|
-
noHugSeparatorEnd = '';
|
|
242
|
-
} else {
|
|
243
|
-
let didSetEndSeparator = false;
|
|
244
|
-
|
|
245
|
-
if (!hugStart && firstChild && firstChild.type === 'Text') {
|
|
246
|
-
if (isTextNodeStartingWithLinebreak(firstChild) && firstChild !== lastChild && (!isInlineElement(path, opts, node) || isTextNodeEndingWithWhitespace(lastChild))) {
|
|
247
|
-
noHugSeparatorStart = hardline;
|
|
248
|
-
noHugSeparatorEnd = hardline;
|
|
249
|
-
didSetEndSeparator = true;
|
|
250
|
-
} else if (isInlineElement(path, opts, node)) {
|
|
251
|
-
noHugSeparatorStart = line;
|
|
252
|
-
}
|
|
253
|
-
trimTextNodeLeft(firstChild);
|
|
254
|
-
}
|
|
255
|
-
if (!hugEnd && lastChild && lastChild.type === 'Text') {
|
|
256
|
-
if (isInlineElement(path, opts, node) && !didSetEndSeparator) {
|
|
257
|
-
noHugSeparatorEnd = line;
|
|
258
|
-
}
|
|
259
|
-
trimTextNodeRight(lastChild);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (hugStart) {
|
|
264
|
-
return group([...openingTag, indent([softline, group(['>', body()])]), noHugSeparatorEnd, `</${node.name}>`]);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (hugEnd) {
|
|
268
|
-
return group([
|
|
269
|
-
...openingTag,
|
|
270
|
-
'>',
|
|
271
|
-
indent([noHugSeparatorStart, group([body(), `</${node.name}`])]),
|
|
272
|
-
canOmitSoftlineBeforeClosingTag(node, path, opts) ? '' : softline,
|
|
273
|
-
'>',
|
|
274
|
-
]);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
if (isEmpty) {
|
|
278
|
-
return group([...openingTag, '>', body(), `</${node.name}>`]);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return group([...openingTag, '>', indent([noHugSeparatorStart, body()]), noHugSeparatorEnd, `</${node.name}>`]);
|
|
282
|
-
}
|
|
283
|
-
case 'AttributeShorthand': {
|
|
284
|
-
return node.expression.name;
|
|
285
|
-
}
|
|
286
|
-
case 'Attribute': {
|
|
287
|
-
if (isOrCanBeConvertedToShorthand(node)) {
|
|
288
|
-
return [line, '{', node.name, '}'];
|
|
289
|
-
} else {
|
|
290
|
-
if (node.value === true) {
|
|
291
|
-
return [line, node.name];
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const quotes = !isLoneMustacheTag(node.value);
|
|
295
|
-
const attrNodeValue = printAttributeNodeValue(path, print, quotes, node);
|
|
296
|
-
if (quotes) {
|
|
297
|
-
return [line, node.name, '=', '"', attrNodeValue, '"'];
|
|
298
|
-
} else {
|
|
299
|
-
return [line, node.name, '=', attrNodeValue];
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
case 'Expression':
|
|
304
|
-
return;
|
|
305
|
-
case 'MustacheTag':
|
|
306
|
-
return [
|
|
307
|
-
'{',
|
|
308
|
-
printJS(path, print, 'expression', {
|
|
309
|
-
forceSingleLine: true,
|
|
310
|
-
forceSingleQuote: false,
|
|
311
|
-
}),
|
|
312
|
-
'}',
|
|
313
|
-
];
|
|
314
|
-
case 'Spread':
|
|
315
|
-
return [
|
|
316
|
-
line,
|
|
317
|
-
'{...',
|
|
318
|
-
printJS(path, print, 'expression', {
|
|
319
|
-
forceSingleQuote: true,
|
|
320
|
-
forceSingleLine: false,
|
|
321
|
-
}),
|
|
322
|
-
'}',
|
|
323
|
-
];
|
|
324
|
-
case 'Comment':
|
|
325
|
-
return [`<!--`, getUnencodedText(node), `-->`];
|
|
326
|
-
case 'CodeSpan':
|
|
327
|
-
return getUnencodedText(node);
|
|
328
|
-
case 'CodeFence':
|
|
329
|
-
console.debug(node);
|
|
330
|
-
return getUnencodedText(node);
|
|
331
|
-
// We should use `node.metadata` to select a parser to embed with... something like return [node.metadata, hardline textToDoc(node.getMetadataLanguage()), hardline, `\`\`\``];
|
|
332
|
-
default: {
|
|
333
|
-
throw new Error(`Unhandled node type "${node.type}"!`);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Split the text into words separated by whitespace. Replace the whitespaces by lines,
|
|
340
|
-
* collapsing multiple whitespaces into a single line.
|
|
341
|
-
*
|
|
342
|
-
* If the text starts or ends with multiple newlines, two of those should be kept.
|
|
343
|
-
*/
|
|
344
|
-
function splitTextToDocs(node) {
|
|
345
|
-
const text = getUnencodedText(node);
|
|
346
|
-
let docs = text.split(/[\t\n\f\r ]+/);
|
|
347
|
-
|
|
348
|
-
docs = join(line, docs).parts.filter((s) => s !== '');
|
|
349
|
-
|
|
350
|
-
if (startsWithLinebreak(text)) {
|
|
351
|
-
docs[0] = hardline;
|
|
352
|
-
}
|
|
353
|
-
if (startsWithLinebreak(text, 2)) {
|
|
354
|
-
docs = [hardline, ...docs];
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
if (endsWithLinebreak(text)) {
|
|
358
|
-
docs[docs.length - 1] = hardline;
|
|
359
|
-
}
|
|
360
|
-
if (endsWithLinebreak(text, 2)) {
|
|
361
|
-
docs = [...docs, hardline];
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
return docs;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
function expressionParser(text, parsers, opts) {
|
|
368
|
-
const ast = parsers.babel(text, parsers, opts);
|
|
369
|
-
|
|
370
|
-
return { ...ast, program: ast.program.body[0].expression };
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/** @type {import('prettier').Printer['embed']} */
|
|
374
|
-
const embed = (path, print, textToDoc, opts) => {
|
|
375
|
-
const node = path.getValue();
|
|
376
|
-
|
|
377
|
-
if (!node) return null;
|
|
378
|
-
|
|
379
|
-
if (node.isJS) {
|
|
380
|
-
try {
|
|
381
|
-
const embeddedopts = {
|
|
382
|
-
parser: expressionParser,
|
|
383
|
-
};
|
|
384
|
-
if (node.forceSingleQuote) {
|
|
385
|
-
embeddedopts.singleQuote = true;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
const docs = textToDoc(forceIntoExpression(getText(node, opts)), embeddedopts);
|
|
389
|
-
return node.forceSingleLine ? removeLines(docs) : docs;
|
|
390
|
-
} catch (e) {
|
|
391
|
-
return getText(node, opts);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (node.type === 'Script' && node.context === 'setup') {
|
|
396
|
-
return group(['---', hardline, textToDoc(node.content, { ...opts, parser: 'typescript' }), '---', hardline]);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// format <script type="module"> content
|
|
400
|
-
if (node.type === 'Text') {
|
|
401
|
-
const parent = path.getParentNode();
|
|
402
|
-
if (parent.type === 'Element' && parent.name === 'script') {
|
|
403
|
-
const [formatttedScript, _] = textToDoc(node.data, { ...opts, parser: 'typescript' });
|
|
404
|
-
return group(formatttedScript);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (node.type === 'Style') {
|
|
409
|
-
let styleLang = '';
|
|
410
|
-
let parserLang = '';
|
|
411
|
-
|
|
412
|
-
if ('attributes' in node) {
|
|
413
|
-
const langAttribute = node.attributes.filter((x) => x.name === 'lang');
|
|
414
|
-
if (langAttribute.length === 0) styleLang = 'css';
|
|
415
|
-
else {
|
|
416
|
-
styleLang = langAttribute[0].value[0].raw.toLowerCase();
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
if (styleLang in supportedStyleLangValues) parserLang = styleLang;
|
|
420
|
-
// TODO(obnoxiousnerd): Provide error handling in case of unrecognized
|
|
421
|
-
// styles language.
|
|
422
|
-
else parserLang = 'css';
|
|
423
|
-
|
|
424
|
-
// the css parser appends an extra indented hardline, which we want outside of the `indent()`,
|
|
425
|
-
// so we remove the last element of the array
|
|
426
|
-
const [formatttedStyles, _] = textToDoc(node.content.styles, { ...opts, parser: parserLang });
|
|
427
|
-
return group([styleLang !== 'css' ? `<style lang="${styleLang}">` : '<style>', indent([hardline, formatttedStyles]), hardline, '</style>', hardline]);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
if (node.__isRawHTML) {
|
|
431
|
-
return textToDoc(node.content, { ...opts, parser: 'html' });
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
return null;
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
/** @type {import('prettier').Printer['hasPrettierIgnore']} */
|
|
438
|
-
const hasPrettierIgnore = (path) => {
|
|
439
|
-
const node = path.getNode();
|
|
440
|
-
const isSimpleIgnore = (comment) =>
|
|
441
|
-
comment.value.includes('prettier-ignore') && !comment.value.includes('prettier-ignore-start') && !comment.value.includes('prettier-ignore-end');
|
|
442
|
-
return node && node.comments && node.comments.length > 0 && node.comments.some(isSimpleIgnore);
|
|
443
|
-
};
|
|
444
|
-
|
|
445
|
-
/** @type {import('prettier').Printer} */
|
|
446
|
-
const printer = {
|
|
447
|
-
print,
|
|
448
|
-
embed,
|
|
449
|
-
hasPrettierIgnore,
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
module.exports = printer;
|