prettier-plugin-astro 0.1.0-next.1 → 0.1.0-next.4

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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # prettier-plugin-astro
2
2
 
3
+ ## 0.1.0-next.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 3afbf2f: Update the internal sync engine to synckit
8
+
9
+ ## 0.1.0-next.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 73e81bd: Set astroAllowShorthand default option to false
14
+
15
+ ## 0.1.0-next.2
16
+
17
+ ### Patch Changes
18
+
19
+ - f244f83: Move from ava to vitest
20
+ - 67341e7: Format directives
21
+ - 0ed661a: Fix: Format expression
22
+ - 87b0508: Change prettier width from 180 to 80
23
+ - ace9861: Remove node 12 from ci
24
+
3
25
  ## 0.1.0-next.1
4
26
 
5
27
  ### Patch Changes
package/README.md CHANGED
@@ -1,33 +1,77 @@
1
- # Beta Prettier Plugin for [Astro](https://github.com/withastro/astro)
1
+ # Beta [Prettier Plugin](https://www.npmjs.com/package/prettier-plugin-astro) for [Astro](https://github.com/withastro/astro)
2
2
 
3
- ## Install [prettier-plugin-astro](https://www.npmjs.com/package/prettier-plugin-astro)
3
+ Format your Astro files using Prettier.
4
4
 
5
- 1. `yarn add --dev prettier-plugin-astro` or `npm i -D prettier-plugin-astro`
6
- 1. `yarn prettier .` to check your formatting / `yarn prettier -w .` to fix your formatting.
7
- 1. Add
5
+ ## Format with vscode
6
+
7
+ 1. Install the [Prettier extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
8
+ 1. Install the plugin as a dev dependency:
9
+
10
+ With yarn:
11
+
12
+ ```shell
13
+ yarn add --dev prettier-plugin-astro
14
+ ```
15
+
16
+ With npm:
17
+
18
+ ```shell
19
+ npm i -D prettier-plugin-astro
20
+ ```
21
+
22
+ ## Format with CLI
23
+
24
+ 1. Install Prettier and the plugin as a dev dependency:
25
+
26
+ With yarn:
27
+
28
+ ```shell
29
+ yarn add --dev prettier prettier-plugin-astro
30
+ ```
31
+
32
+ With npm:
33
+
34
+ ```shell
35
+ npm i -D prettier prettier-plugin-astro
36
+ ```
37
+
38
+ 2. `yarn prettier .` to check your formatting / `yarn prettier -w .` to fix your formatting.
39
+ 3. Add
8
40
 
9
41
  ```json
10
42
  "format": "yarn prettier -w .",
11
43
  ```
12
44
 
13
- to your `package.json` and create a `.prettierignore` to ignore any files.
45
+ to your `package.json`. [Read more about it.](https://prettier.io/docs/en/cli.html)
46
+
47
+ ## Options
48
+
49
+ Most [options from Prettier](https://prettier.io/docs/en/options.html) will work with the plugin and can be set in a [configuration file](https://prettier.io/docs/en/configuration.html) or through [CLI flags](https://prettier.io/docs/en/cli.html).
50
+
51
+ ### Astro Sort Order
52
+
53
+ Sort order for markup and styles.
54
+
55
+ Format: join the keywords `markup` and `styles` with a `|` in the order you want.
56
+
57
+ | Default | CLI Override | API Override |
58
+ | --------------------------------- | ----------------------------- | -------------------------- |
59
+ | <code>markup &#124; styles</code> | `--astro-sort-order <string>` | `astroSortOrder: <string>` |
60
+
61
+ ### Astro Allow Shorthand
62
+
63
+ Option to enable/disable component attribute shorthand if attribute name and expression are same.
64
+
65
+ | Default | CLI Override | API Override |
66
+ | ------- | -------------------------------- | ----------------------------- |
67
+ | `false` | `--astro-allow-shorthand <bool>` | `astroAllowShorthand: <bool>` |
14
68
 
15
- ## Contributing
69
+ ## How to make it work with pnpm
16
70
 
17
- To get setup:
71
+ See [comment](https://github.com/withastro/prettier-plugin-astro/issues/97)
18
72
 
19
- 1. `git clone git@github.com:withastro/prettier-plugin-astro.git`
20
- 1. `yarn`
21
- 1. `yarn build`
22
- 1. Run tests with [`yarn test`](https://github.com/avajs/ava/tree/main/docs)
23
- 1. Lint code with `yarn lint`
24
- 1. Format code with `yarn format`
25
- 1. Run `yarn changeset` to add your changes to the changelog on version bump.
26
- Most changes to the plugin should be `patch` changes while we're before `1.0.0`.
73
+ ## Ignore files
27
74
 
28
- ## Resources for contributing
75
+ Create a `.prettierignore` to ignore any files. [Read more about it.](https://prettier.io/docs/en/ignore.html)
29
76
 
30
- - [prettier rationale](https://prettier.io/docs/en/rationale.html)
31
- - [prettier plugin docs](https://prettier.io/docs/en/plugins.html)
32
- - [svelte prettier plugin](https://github.com/sveltejs/prettier-plugin-svelte)
33
- - [prettier html formatter](https://github.com/prettier/prettier/tree/main/src/language-html)
77
+ ## [Contributing](CONTRIBUTING.md)
package/dist/index.js CHANGED
@@ -2,28 +2,15 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var makeSynchronous = require('make-synchronous');
6
5
  var _doc = require('prettier/doc');
7
6
  var sassFormatter = require('sass-formatter');
7
+ var synckit = require('synckit');
8
+ var module$1 = require('module');
8
9
 
9
10
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
11
 
11
- var makeSynchronous__default = /*#__PURE__*/_interopDefaultLegacy(makeSynchronous);
12
12
  var _doc__default = /*#__PURE__*/_interopDefaultLegacy(_doc);
13
13
 
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);
26
-
27
14
  const blockElementsT = [
28
15
  'address',
29
16
  'article',
@@ -62,20 +49,25 @@ const blockElementsT = [
62
49
  'html',
63
50
  ];
64
51
  const blockElements = [...blockElementsT];
65
- const selfClosingTags = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
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);
52
+ const selfClosingTags = [
53
+ 'area',
54
+ 'base',
55
+ 'br',
56
+ 'col',
57
+ 'embed',
58
+ 'hr',
59
+ 'img',
60
+ 'input',
61
+ 'link',
62
+ 'meta',
63
+ 'param',
64
+ 'source',
65
+ 'track',
66
+ 'wbr',
67
+ ];
78
68
 
69
+ const require$2 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.js', document.baseURI).href)));
70
+ const serialize = synckit.createSyncFn(require$2.resolve('../workers/serialize-worker.js'));
79
71
  const formattableAttributes = [];
80
72
  const isEmptyTextNode = (node) => {
81
73
  return !!node && node.type === 'text' && getUnencodedText(node).trim() === '';
@@ -83,12 +75,9 @@ const isEmptyTextNode = (node) => {
83
75
  const isPreTagContent = (path) => {
84
76
  if (!path || !path.stack || !Array.isArray(path.stack))
85
77
  return false;
86
- return path.stack.some((node) => (node.type === 'element' && node.name.toLowerCase() === 'pre') || (node.type === 'attribute' && !formattableAttributes.includes(node.name)));
78
+ return path.stack.some((node) => (node.type === 'element' && node.name.toLowerCase() === 'pre') ||
79
+ (node.type === 'attribute' && !formattableAttributes.includes(node.name)));
87
80
  };
88
- function getText(node, opts) {
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);
91
- }
92
81
  function getUnencodedText(node) {
93
82
  return node.value;
94
83
  }
@@ -118,10 +107,17 @@ function isNodeWithChildren(node) {
118
107
  return node && Array.isArray(node.children);
119
108
  }
120
109
  function isInlineElement(path, opts, node) {
121
- return node && node.type === 'element' && !isBlockElement(node, opts) && !isPreTagContent(path);
110
+ return (node &&
111
+ node.type === 'element' &&
112
+ !isBlockElement(node, opts) &&
113
+ !isPreTagContent(path));
122
114
  }
123
115
  function isBlockElement(node, opts) {
124
- return node && node.type === 'element' && opts.htmlWhitespaceSensitivity !== 'strict' && (opts.htmlWhitespaceSensitivity === 'ignore' || blockElements.includes(node.name));
116
+ return (node &&
117
+ node.type === 'element' &&
118
+ opts.htmlWhitespaceSensitivity !== 'strict' &&
119
+ (opts.htmlWhitespaceSensitivity === 'ignore' ||
120
+ blockElements.includes(node.name)));
125
121
  }
126
122
  function isTextNodeStartingWithLinebreak(node, nrLines = 1) {
127
123
  return startsWithLinebreak(getUnencodedText(node), nrLines);
@@ -191,7 +187,7 @@ function trimTextNodeRight(node) {
191
187
  }
192
188
  function manualDedent(input) {
193
189
  let result = '';
194
- for (var i = 0; i < input.length; i++) {
190
+ for (let i = 0; i < input.length; i++) {
195
191
  result += input[i]
196
192
  .replace(/\\\n[ \t]*/g, '')
197
193
  .replace(/\\`/g, '`');
@@ -202,9 +198,9 @@ function manualDedent(input) {
202
198
  const lines = result.split('\n');
203
199
  let mindent = null;
204
200
  lines.forEach(function (l) {
205
- var m = l.match(/^(\s+)\S+/);
201
+ const m = l.match(/^(\s+)\S+/);
206
202
  if (m) {
207
- var indent = m[1].length;
203
+ const indent = m[1].length;
208
204
  if (!mindent) {
209
205
  mindent = indent;
210
206
  }
@@ -215,7 +211,7 @@ function manualDedent(input) {
215
211
  });
216
212
  if (mindent !== null) {
217
213
  (function () {
218
- var m = mindent;
214
+ const m = mindent;
219
215
  result = lines
220
216
  .map(function (l) {
221
217
  return l[0] === ' ' ? l.slice(m) : l;
@@ -231,15 +227,21 @@ function manualDedent(input) {
231
227
  }
232
228
  function getMarkdownName(script) {
233
229
  let defaultMatch;
234
- while ((defaultMatch = /import\s+([^\s]+)\s+from\s+['|"|`]astro\/components\/Markdown\.astro/g.exec(script))) {
230
+ while ((defaultMatch =
231
+ /import\s+([^\s]+)\s+from\s+['|"|`]astro\/components\/Markdown\.astro/g.exec(script))) {
235
232
  if (defaultMatch[1])
236
233
  return new Set([defaultMatch[1].trim()]);
237
234
  }
238
235
  let namedMatch;
239
- while ((namedMatch = /import\s+\{\s*([^}]+)\}\s+from\s+['|"|`]astro\/components/g.exec(script))) {
236
+ while ((namedMatch =
237
+ /import\s+\{\s*([^}]+)\}\s+from\s+['|"|`]astro\/components/g.exec(script))) {
240
238
  if (namedMatch[1] && !namedMatch[1].includes('Markdown'))
241
239
  continue;
242
- const rawImports = namedMatch[1].trim().replace(/^\{/, '').replace(/\}$/, '').trim();
240
+ const rawImports = namedMatch[1]
241
+ .trim()
242
+ .replace(/^\{/, '')
243
+ .replace(/\}$/, '')
244
+ .trim();
243
245
  let importName = 'Markdown';
244
246
  for (const spec of rawImports.split(',')) {
245
247
  const [original, renamed] = spec.split(' as ').map((s) => s.trim());
@@ -256,7 +258,7 @@ function isTextNode(node) {
256
258
  return node.type === 'text';
257
259
  }
258
260
 
259
- const { builders: { breakParent, dedent, fill, group, hardline, indent, join, line, literalline, softline }, utils: { removeLines, stripTrailingHardline }, } = _doc__default["default"];
261
+ const { builders: { breakParent, dedent, fill, group, hardline, indent, join, line, literalline, softline, }, utils: { removeLines, stripTrailingHardline }, } = _doc__default["default"];
260
262
  function printComment(commentPath, options) {
261
263
  return commentPath;
262
264
  }
@@ -301,8 +303,9 @@ function print(path, opts, print) {
301
303
  else {
302
304
  isEmpty = node.children.every((child) => isEmptyTextNode(child));
303
305
  }
304
- const isSelfClosingTag = isEmpty && (node.type !== 'element' || selfClosingTags.indexOf(node.name) !== -1);
305
- const attributes = node.attributes ? path.map(print, 'attributes') : [];
306
+ const isSelfClosingTag = isEmpty &&
307
+ (node.type !== 'element' || selfClosingTags.indexOf(node.name) !== -1);
308
+ const attributes = path.map(print, 'attributes');
306
309
  if (isSelfClosingTag) {
307
310
  return group(['<', node.name, indent(group(attributes)), line, `/>`]);
308
311
  }
@@ -312,12 +315,15 @@ function print(path, opts, print) {
312
315
  const lastChild = children[children.length - 1];
313
316
  let noHugSeparatorStart = softline;
314
317
  let noHugSeparatorEnd = softline;
315
- let hugStart = shouldHugStart(node, opts);
316
- let hugEnd = shouldHugEnd(node, opts);
318
+ const hugStart = shouldHugStart(node, opts);
319
+ const hugEnd = shouldHugEnd(node, opts);
317
320
  let body;
318
321
  if (isEmpty) {
319
322
  body =
320
- isInlineElement(path, opts, node) && node.children.length && isTextNodeStartingWithWhitespace(node.children[0]) && !isPreTagContent(path)
323
+ isInlineElement(path, opts, node) &&
324
+ node.children.length &&
325
+ isTextNodeStartingWithWhitespace(node.children[0]) &&
326
+ !isPreTagContent(path)
321
327
  ? () => line
322
328
  :
323
329
  () => softline;
@@ -325,17 +331,37 @@ function print(path, opts, print) {
325
331
  else if (isPreTagContent(path)) {
326
332
  body = () => printRaw(node);
327
333
  }
328
- else if (isInlineElement(path, opts, node) && !isPreTagContent(path)) {
334
+ else if (isInlineElement(path, opts, node) &&
335
+ !isPreTagContent(path)) {
329
336
  body = () => path.map(print, 'children');
330
337
  }
331
338
  else {
332
339
  body = () => path.map(print, 'children');
333
340
  }
334
- const openingTag = ['<', node.name, indent(group([...attributes, hugStart ? '' : !isPreTagContent(path) && !opts.bracketSameLine ? dedent(softline) : '']))];
341
+ const openingTag = [
342
+ '<',
343
+ node.name,
344
+ indent(group([
345
+ ...attributes,
346
+ hugStart
347
+ ? ''
348
+ : !isPreTagContent(path) && !opts.bracketSameLine
349
+ ? dedent(softline)
350
+ : '',
351
+ ])),
352
+ ];
335
353
  if (hugStart && hugEnd) {
336
- const huggedContent = [softline, group(['>', body(), `</${node.name}`])];
354
+ const huggedContent = [
355
+ softline,
356
+ group(['>', body(), `</${node.name}`]),
357
+ ];
337
358
  const omitSoftlineBeforeClosingTag = isEmpty || canOmitSoftlineBeforeClosingTag(path, opts);
338
- return group([...openingTag, isEmpty ? group(huggedContent) : group(indent(huggedContent)), omitSoftlineBeforeClosingTag ? '' : softline, '>']);
359
+ return group([
360
+ ...openingTag,
361
+ isEmpty ? group(huggedContent) : group(indent(huggedContent)),
362
+ omitSoftlineBeforeClosingTag ? '' : softline,
363
+ '>',
364
+ ]);
339
365
  }
340
366
  if (isPreTagContent(path)) {
341
367
  noHugSeparatorStart = '';
@@ -344,7 +370,10 @@ function print(path, opts, print) {
344
370
  else {
345
371
  let didSetEndSeparator = false;
346
372
  if (!hugStart && firstChild && isTextNode(firstChild)) {
347
- if (isTextNodeStartingWithLinebreak(firstChild) && firstChild !== lastChild && (!isInlineElement(path, opts, node) || isTextNodeEndingWithWhitespace(lastChild))) {
373
+ if (isTextNodeStartingWithLinebreak(firstChild) &&
374
+ firstChild !== lastChild &&
375
+ (!isInlineElement(path, opts, node) ||
376
+ isTextNodeEndingWithWhitespace(lastChild))) {
348
377
  noHugSeparatorStart = hardline;
349
378
  noHugSeparatorEnd = hardline;
350
379
  didSetEndSeparator = true;
@@ -362,15 +391,32 @@ function print(path, opts, print) {
362
391
  }
363
392
  }
364
393
  if (hugStart) {
365
- return group([...openingTag, indent([softline, group(['>', body()])]), noHugSeparatorEnd, `</${node.name}>`]);
394
+ return group([
395
+ ...openingTag,
396
+ indent([softline, group(['>', body()])]),
397
+ noHugSeparatorEnd,
398
+ `</${node.name}>`,
399
+ ]);
366
400
  }
367
401
  if (hugEnd) {
368
- return group([...openingTag, '>', indent([noHugSeparatorStart, group([body(), `</${node.name}`])]), canOmitSoftlineBeforeClosingTag(path, opts) ? '' : softline, '>']);
402
+ return group([
403
+ ...openingTag,
404
+ '>',
405
+ indent([noHugSeparatorStart, group([body(), `</${node.name}`])]),
406
+ canOmitSoftlineBeforeClosingTag(path, opts) ? '' : softline,
407
+ '>',
408
+ ]);
369
409
  }
370
410
  if (isEmpty) {
371
411
  return group([...openingTag, '>', body(), `</${node.name}>`]);
372
412
  }
373
- return group([...openingTag, '>', indent([noHugSeparatorStart, body()]), noHugSeparatorEnd, `</${node.name}>`]);
413
+ return group([
414
+ ...openingTag,
415
+ '>',
416
+ indent([noHugSeparatorStart, body()]),
417
+ noHugSeparatorEnd,
418
+ `</${node.name}>`,
419
+ ]);
374
420
  }
375
421
  return '';
376
422
  }
@@ -393,9 +439,6 @@ function print(path, opts, print) {
393
439
  }
394
440
  return '';
395
441
  }
396
- case 'directive': {
397
- return [line, node.name];
398
- }
399
442
  case 'doctype': {
400
443
  return ['<!DOCTYPE html>', hardline];
401
444
  }
@@ -408,7 +451,7 @@ function print(path, opts, print) {
408
451
  }
409
452
  function splitTextToDocs(node) {
410
453
  const text = getUnencodedText(node);
411
- let textLines = text.split(/[\t\n\f\r ]+/);
454
+ const textLines = text.split(/[\t\n\f\r ]+/);
412
455
  let docs = join(line, textLines).parts.filter((s) => s !== '');
413
456
  if (startsWithLinebreak(text)) {
414
457
  docs[0] = hardline;
@@ -436,15 +479,14 @@ function embed(path, print, textToDoc, opts) {
436
479
  if (!node)
437
480
  return null;
438
481
  if (node.type === 'expression') {
439
- const textContent = getText(node, opts);
482
+ const textContent = printRaw(node);
440
483
  let content;
441
- if (node.children.length === 1) {
442
- content = textContent;
443
- }
444
- else {
445
- content = textToDoc(textContent, { ...opts, parser: 'babel-ts', semi: false });
446
- content = stripTrailingHardline(content);
447
- }
484
+ content = textToDoc(forceIntoExpression(textContent), {
485
+ ...opts,
486
+ parser: expressionParser,
487
+ semi: false,
488
+ });
489
+ content = stripTrailingHardline(content);
448
490
  return [
449
491
  '{',
450
492
  content,
@@ -454,7 +496,11 @@ function embed(path, print, textToDoc, opts) {
454
496
  if (node.type === 'attribute' && node.kind === 'expression') {
455
497
  const value = node.value.trim();
456
498
  const name = node.name.trim();
457
- let attrNodeValue = textToDoc(forceIntoExpression(value), { ...opts, parser: expressionParser, semi: false });
499
+ let attrNodeValue = textToDoc(forceIntoExpression(value), {
500
+ ...opts,
501
+ parser: expressionParser,
502
+ semi: false,
503
+ });
458
504
  attrNodeValue = stripTrailingHardline(attrNodeValue);
459
505
  if (name === value && opts.astroAllowShorthand) {
460
506
  return [line, '{', attrNodeValue, '}'];
@@ -463,18 +509,40 @@ function embed(path, print, textToDoc, opts) {
463
509
  }
464
510
  if (node.type === 'frontmatter') {
465
511
  markdownComponentName = getMarkdownName(node.value);
466
- return [group(['---', hardline, textToDoc(node.value, { ...opts, parser: 'typescript' }), '---', hardline]), hardline];
512
+ return [
513
+ group([
514
+ '---',
515
+ hardline,
516
+ textToDoc(node.value, { ...opts, parser: 'typescript' }),
517
+ '---',
518
+ hardline,
519
+ ]),
520
+ hardline,
521
+ ];
467
522
  }
468
523
  if (node.type === 'element' && node.name === 'script') {
469
524
  const scriptContent = node.children[0].value;
470
- let formatttedScript = textToDoc(scriptContent, { ...opts, parser: 'typescript' });
525
+ let formatttedScript = textToDoc(scriptContent, {
526
+ ...opts,
527
+ parser: 'typescript',
528
+ });
471
529
  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>'];
530
+ const attributes = path.map(print, 'attributes');
531
+ const openingTag = group([
532
+ '<script',
533
+ indent(group(attributes)),
534
+ softline,
535
+ '>',
536
+ ]);
537
+ return [
538
+ openingTag,
539
+ indent([hardline, formatttedScript]),
540
+ hardline,
541
+ '</script>',
542
+ ];
475
543
  }
476
544
  if (node.type === 'element' && node.name === 'style') {
477
- let styleTagContent = node.children[0].value.trim();
545
+ const styleTagContent = node.children[0].value.trim();
478
546
  const supportedStyleLangValues = ['css', 'scss', 'sass'];
479
547
  let parserLang = 'css';
480
548
  if (node.attributes) {
@@ -488,13 +556,24 @@ function embed(path, print, textToDoc, opts) {
488
556
  switch (parserLang) {
489
557
  case 'css':
490
558
  case 'scss': {
491
- let formattedStyles = textToDoc(styleTagContent, { ...opts, parser: parserLang });
559
+ let formattedStyles = textToDoc(styleTagContent, {
560
+ ...opts,
561
+ parser: parserLang,
562
+ });
492
563
  formattedStyles = stripTrailingHardline(formattedStyles);
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, '>']);
497
- return [openingTag, indent([hardline, formattedStyles]), hardline, '</style>'];
564
+ const attributes = path.map(print, 'attributes');
565
+ const openingTag = group([
566
+ '<style',
567
+ indent(group(attributes)),
568
+ softline,
569
+ '>',
570
+ ]);
571
+ return [
572
+ openingTag,
573
+ indent([hardline, formattedStyles]),
574
+ hardline,
575
+ '</style>',
576
+ ];
498
577
  }
499
578
  case 'sass': {
500
579
  const lineEnding = opts.endOfLine.toUpperCase() === 'CRLF' ? 'CRLF' : 'LF';
@@ -504,11 +583,21 @@ function embed(path, print, textToDoc, opts) {
504
583
  lineEnding,
505
584
  };
506
585
  const { result: raw } = manualDedent(styleTagContent);
507
- let formattedSassIndented = sassFormatter.SassFormatter.Format(raw, sassOptions).trim();
586
+ const formattedSassIndented = sassFormatter.SassFormatter.Format(raw, sassOptions).trim();
508
587
  const formattedSass = join(hardline, formattedSassIndented.split('\n'));
509
- const attributes = node.attributes ? path.map(print, 'attributes') : [];
510
- const openingTag = group(['<style', indent(group(attributes)), softline, '>']);
511
- return [openingTag, indent(group([hardline, formattedSass])), hardline, '</style>'];
588
+ const attributes = path.map(print, 'attributes');
589
+ const openingTag = group([
590
+ '<style',
591
+ indent(group(attributes)),
592
+ softline,
593
+ '>',
594
+ ]);
595
+ return [
596
+ openingTag,
597
+ indent(group([hardline, formattedSass])),
598
+ hardline,
599
+ '</style>',
600
+ ];
512
601
  }
513
602
  }
514
603
  }
@@ -517,11 +606,24 @@ function embed(path, print, textToDoc, opts) {
517
606
  content = content.replace(/\r\n/g, '\n');
518
607
  const contentArr = content.split('\n').map((s) => s.trimStart());
519
608
  content = contentArr.join('\n');
520
- let formatttedMarkdown = textToDoc(content, { ...opts, parser: 'markdown' });
609
+ let formatttedMarkdown = textToDoc(content, {
610
+ ...opts,
611
+ parser: 'markdown',
612
+ });
521
613
  formatttedMarkdown = stripTrailingHardline(formatttedMarkdown);
522
614
  const attributes = path.map(print, 'attributes');
523
- const openingTag = group([`<${node.name}`, indent(group(attributes)), softline, '>']);
524
- return [openingTag, indent(group([hardline, formatttedMarkdown])), hardline, `</${node.name}>`];
615
+ const openingTag = group([
616
+ `<${node.name}`,
617
+ indent(group(attributes)),
618
+ softline,
619
+ '>',
620
+ ]);
621
+ return [
622
+ openingTag,
623
+ indent(group([hardline, formatttedMarkdown])),
624
+ hardline,
625
+ `</${node.name}>`,
626
+ ];
525
627
  }
526
628
  return null;
527
629
  }
@@ -557,11 +659,13 @@ const options = {
557
659
  since: '0.0.10',
558
660
  category: 'Astro',
559
661
  type: 'boolean',
560
- default: true,
662
+ default: false,
561
663
  description: 'Enable/disable attribute shorthand if attribute name and expression are the same',
562
664
  },
563
665
  };
564
666
 
667
+ const require$1 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.js', document.baseURI).href)));
668
+ const parse = synckit.createSyncFn(require$1.resolve('../workers/parse-worker.js'));
565
669
  const languages = [
566
670
  {
567
671
  name: 'astro',
@@ -572,7 +676,7 @@ const languages = [
572
676
  ];
573
677
  const parsers = {
574
678
  astro: {
575
- parse,
679
+ parse: (source) => parse(source),
576
680
  astFormat: 'astro',
577
681
  locStart: (node) => node.start,
578
682
  locEnd: (node) => node.end,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/parse.ts","../src/nodes.ts","../src/syncUtils.ts","../src/utils.ts","../src/printer.ts","../src/options.ts","../src/index.ts"],"sourcesContent":["import makeSynchronous from 'make-synchronous';\n\nconst parseSync = makeSynchronous(async (source: string) => {\n const dynamicImport = new Function('file', 'return import(file)');\n const { parse } = await dynamicImport('@astrojs/compiler');\n try {\n const { ast } = await parse(source);\n return ast;\n } catch (e) {\n console.error(e);\n }\n});\n\nconst parse = (text: string) => parseSync(text);\n\nexport default parse;\n","import {\n Node,\n AttributeNode,\n DirectiveNode,\n RootNode,\n ElementNode,\n ComponentNode,\n CustomElementNode,\n ExpressionNode,\n TextNode,\n FrontmatterNode,\n DoctypeNode,\n CommentNode,\n FragmentNode,\n} from '@astrojs/compiler/types';\n\n// MISSING ATTRIBUTE NODE FROM THE NODE TYPE\n\nexport interface NodeWithText {\n value: string;\n}\n\n// export interface Ast {\n// html: anyNode;\n// css: StyleNode[];\n// module: ScriptNode;\n// meta: {\n// features: number;\n// };\n// }\n\n// export interface BaseNode {\n// start: number;\n// end: number;\n// type: string;\n// children?: anyNode[];\n// // TODO: ADD BETTER TYPE\n// [prop_name: string]: any;\n// }\n\n// export type attributeValue = TextNode[] | AttributeShorthandNode[] | MustacheTagNode[] | true;\n\nexport interface NodeWithChildren {\n // children: anyNode[];\n children: Node[];\n}\n\n// export interface NodeWithText {\n// data: string;\n// raw?: string;\n// }\n\n// export interface FragmentNode extends BaseNode {\n// type: 'Fragment';\n// children: anyNode[];\n// }\n\n// export interface TextNode extends BaseNode {\n// type: 'Text';\n// data: string;\n// raw: string;\n// }\n\n// export interface CodeFenceNode extends BaseNode {\n// type: 'CodeFence';\n// metadata: string;\n// data: string;\n// raw: string;\n// }\n\n// export interface CodeSpanNode extends BaseNode {\n// type: 'CodeSpan';\n// metadata: string;\n// data: string;\n// raw: string;\n// }\n\n// export interface SpreadNode extends BaseNode {\n// type: 'Spread';\n// expression: ExpressionNode;\n// }\n\n// export interface ExpressionNode {\n// type: 'Expression';\n// start: number;\n// end: number;\n// codeChunks: string[];\n// children: anyNode[];\n// }\n\n// export interface ScriptNode extends BaseNode {\n// type: 'Script';\n// context: 'runtime' | 'setup';\n// content: string;\n// }\n\n// export interface StyleNode extends BaseNode {\n// type: 'Style';\n// // TODO: ADD BETTER TYPE\n// attributes: any[];\n// content: {\n// start: number;\n// end: number;\n// styles: string;\n// };\n// }\n\n// export interface AttributeNode extends BaseNode {\n// type: 'Attribute';\n// name: string;\n// value: attributeValue;\n// }\n\n// export interface AttributeShorthandNode extends BaseNode {\n// type: 'AttributeShorthand';\n// expression: IdentifierNode;\n// }\n\n// export interface IdentifierNode extends BaseNode {\n// type: 'Identifier';\n// name: string;\n// }\n\n// export interface MustacheTagNode extends BaseNode {\n// type: 'MustacheTag';\n// expression: ExpressionNode;\n// }\n\n// export interface SlotNode extends BaseNode {\n// type: 'Slot';\n// name: string;\n// attributes: AttributeNode[];\n// }\n\n// export interface CommentNode extends BaseNode {\n// type: 'Comment';\n// data: string;\n// name?: string;\n// leading?: boolean;\n// trailing?: boolean;\n// printed?: boolean;\n// nodeDescription?: string;\n// }\n\n// export interface ElementNode extends BaseNode {\n// type: 'Element';\n// name: string;\n// attributes: AttributeNode[];\n// }\n\n// export interface InlineComponentNode extends BaseNode {\n// type: 'InlineComponent';\n// name: string;\n// attributes: AttributeNode[];\n// }\n\nexport interface BlockElementNode extends ElementNode {\n name: typeof blockElementsT[number];\n}\n\nexport interface InlineElementNode extends ElementNode {\n name: typeof inlineElementsT[number];\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements#Elements\nconst blockElementsT = [\n 'address',\n 'article',\n 'aside',\n 'blockquote',\n 'details',\n 'dialog',\n 'dd',\n 'div',\n 'dl',\n 'dt',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'li',\n 'main',\n 'nav',\n 'ol',\n 'p',\n 'pre',\n 'section',\n 'table',\n 'ul',\n // TODO: WIP\n 'title',\n 'html',\n] as const;\n// https://github.com/microsoft/TypeScript/issues/31018\nexport const blockElements: string[] = [...blockElementsT];\n\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements\nconst inlineElementsT = [\n 'a',\n 'abbr',\n 'acronym',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'br',\n 'button',\n 'canvas',\n 'cite',\n 'code',\n 'data',\n 'datalist',\n 'del',\n 'dfn',\n 'em',\n 'embed',\n 'i',\n 'iframe',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'map',\n 'mark',\n 'meter',\n 'noscript',\n 'object',\n 'output',\n 'picture',\n 'progress',\n 'q',\n 'ruby',\n 's',\n 'samp',\n 'script',\n 'select',\n 'slot',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'sup',\n 'svg',\n 'template',\n 'textarea',\n 'time',\n 'u',\n 'tt',\n 'var',\n 'video',\n 'wbr',\n] as const;\n// https://github.com/microsoft/TypeScript/issues/31018\nexport const inlineElements: string[] = [...inlineElementsT];\n\n// @see http://xahlee.info/js/html5_non-closing_tag.html\nexport const selfClosingTags = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'];\n\nexport type anyNode =\n | RootNode\n | AttributeNode\n | DirectiveNode\n | ElementNode\n | ComponentNode\n | CustomElementNode\n | ExpressionNode\n | TextNode\n | DoctypeNode\n | CommentNode\n | FragmentNode\n | FrontmatterNode;\n\nexport type {\n AttributeNode,\n Node,\n RootNode,\n ElementNode,\n ComponentNode,\n CustomElementNode,\n ExpressionNode,\n TextNode,\n FrontmatterNode,\n DoctypeNode,\n CommentNode,\n FragmentNode,\n} from '@astrojs/compiler/types';\n","import makeSynchronous from 'make-synchronous';\nimport { Node } from './nodes';\n\nconst serializeSync = makeSynchronous(async (node: Node) => {\n const dynamicImport = new Function('file', 'return import(file)');\n const { serialize } = await dynamicImport('@astrojs/compiler/utils');\n try {\n return await serialize(node);\n } catch (e) {\n console.error(e);\n }\n});\n\nexport const serialize = (node: Node): string => serializeSync(node);\n","import { AstPath as AstP, doc, Doc, ParserOptions as ParserOpts, util } from 'prettier';\n\nimport {\n anyNode,\n Node,\n RootNode,\n AttributeNode,\n ElementNode,\n ComponentNode,\n CustomElementNode,\n ExpressionNode,\n TextNode,\n FrontmatterNode,\n DoctypeNode,\n CommentNode,\n NodeWithText,\n blockElements,\n // attributeValue,\n BlockElementNode,\n InlineElementNode,\n // MustacheTagNode,\n NodeWithChildren,\n // NodeWithText,\n // TextNode,\n} from './nodes';\n\nimport { serialize } from './syncUtils';\n\n// import makeSynchronous from 'make-synchronous';\n\ntype ParserOptions = ParserOpts<anyNode>;\ntype AstPath = AstP<anyNode>;\n\n/**\n * HTML attributes that we may safely reformat (trim whitespace, add or remove newlines)\n */\nexport const formattableAttributes: string[] = [\n // None at the moment\n // Prettier HTML does not format attributes at all\n // and to be consistent we leave this array empty for now\n];\n\n// const rootNodeKeys = new Set(['html', 'css', 'module']);\n\n// const isSync = makeSynchronous(async (node: anyNode) => {\n// const dynamicImport = new Function('file', 'return import(file)');\n// const { is } = await dynamicImport('@astrojs/compiler/utils');\n// try {\n// return await is(node);\n// } catch (e) {\n// console.error(e);\n// }\n// });\n\n// export const is = (node: anyNode) => isSync(node);\n\nexport const isRootNode = (node: anyNode): node is RootNode => node.type === 'root';\n\nexport const isEmptyTextNode = (node: Node): boolean => {\n return !!node && node.type === 'text' && getUnencodedText(node).trim() === '';\n};\n\nexport const isPreTagContent = (path: AstPath): boolean => {\n if (!path || !path.stack || !Array.isArray(path.stack)) return false;\n return path.stack.some(\n (node: anyNode) => (node.type === 'element' && node.name.toLowerCase() === 'pre') || (node.type === 'attribute' && !formattableAttributes.includes(node.name))\n );\n};\n\nexport function isLoneMustacheTag(node: AttributeNode): boolean {\n // export function isLoneMustacheTag(node: AttributeNode): node is [MustacheTagNode] {\n return node.kind === 'expression';\n // return node !== true && node.length === 1 && node[0].type === 'MustacheTag';\n}\n\n// function isAttributeShorthand(node: attributeValue): node is [AttributeShorthandNode] {\n// return node !== true && node.length === 1 && node[0].type === 'AttributeShorthand';\n// }\n\n/**\n * True if node is of type `{a}` or `a={a}`\n */\nexport function isOrCanBeConvertedToShorthand(node: AttributeNode, opts: ParserOptions): boolean {\n if (!opts.astroAllowShorthand) return false;\n if (node.kind === 'shorthand') {\n return true;\n }\n // if (isAttributeShorthand(node.value)) {\n // return true;\n // }\n\n if (node.value.trim() === node.name.trim()) {\n return true;\n }\n\n // if (isLoneMustacheTag(node.value)) {\n // const expression = node.value[0].expression;\n // return expression.codeChunks[0].trim() === node.name;\n // // return (expression.type === 'Identifier' && expression.name === node.name) || (expression.type === 'Expression' && expression.codeChunks[0] === node.name);\n // }\n\n return false;\n}\n\n/**\n * True if node is of type `{a}` and astroAllowShorthand is false\n */\nexport function isShorthandAndMustBeConvertedToBinaryExpression(node: AttributeNode, opts: ParserOptions): boolean {\n if (opts.astroAllowShorthand) return false;\n if (node.type === 'attribute' && node.kind === 'shorthand') {\n return true;\n }\n // if (isAttributeShorthand(node.value)) {\n // return true;\n // }\n return false;\n}\n\n// export function flatten<T>(arrays: T[][]): T[] {\n// return ([] as T[]).concat.apply([], arrays);\n// }\n\n// TODO: TEST IF IT'S GETTING THE CORRECT TEXT\nexport function getText(node: anyNode, opts: ParserOptions): string {\n return opts.originalText.slice(node.position?.start.offset! + 1, node.position?.end?.offset);\n // return opts.originalText.slice(opts.locStart(node), opts.locEnd(node));\n}\n\nexport function getUnencodedText(node: NodeWithText): string {\n return node.value;\n}\n\n// export function replaceEndOfLineWith(text: string, replacement: doc.builders.DocCommand): Doc[] {\n// const parts = [];\n// for (const part of text.split('\\n')) {\n// if (parts.length > 0) {\n// parts.push(replacement);\n// }\n// if (part.endsWith('\\r')) {\n// parts.push(part.slice(0, -1));\n// } else {\n// parts.push(part);\n// }\n// }\n// return parts;\n// }\n\n/**\n * Returns the content of the node\n */\nexport function printRaw(node: anyNode, stripLeadingAndTrailingNewline: boolean = false): string {\n if (!isNodeWithChildren(node)) {\n return '';\n }\n\n if (node.children.length === 0) {\n return '';\n }\n\n let raw = node.children.reduce((prev, curr) => prev + serialize(curr), '');\n\n if (!stripLeadingAndTrailingNewline) {\n return raw;\n }\n\n if (startsWithLinebreak(raw)) {\n raw = raw.substring(raw.indexOf('\\n') + 1);\n }\n if (endsWithLinebreak(raw)) {\n raw = raw.substring(0, raw.lastIndexOf('\\n'));\n if (raw.charAt(raw.length - 1) === '\\r') {\n raw = raw.substring(0, raw.length - 1);\n }\n }\n\n return raw;\n}\n\nexport function isNodeWithChildren(node: anyNode): node is anyNode & NodeWithChildren {\n return node && Array.isArray(node.children);\n}\n\nexport function isInlineElement(path: AstPath, opts: ParserOptions, node: anyNode): node is InlineElementNode {\n return node && node.type === 'element' && !isBlockElement(node, opts) && !isPreTagContent(path);\n}\n\nexport function isBlockElement(node: anyNode, opts: ParserOptions): node is BlockElementNode {\n return node && node.type === 'element' && opts.htmlWhitespaceSensitivity !== 'strict' && (opts.htmlWhitespaceSensitivity === 'ignore' || blockElements.includes(node.name));\n}\n\nexport function isTextNodeStartingWithLinebreak(node: TextNode, nrLines: number = 1): node is TextNode {\n return startsWithLinebreak(getUnencodedText(node), nrLines);\n // return node.type === 'Text' && startsWithLinebreak(getUnencodedText(node), nrLines);\n}\n\nexport function startsWithLinebreak(text: string, nrLines: number = 1): boolean {\n return new RegExp(`^([\\\\t\\\\f\\\\r ]*\\\\n){${nrLines}}`).test(text);\n}\n\n// export function isTextNodeEndingWithLinebreak(node: TextNode, nrLines: number = 1) {\n// return node.type === 'text' && endsWithLinebreak(getUnencodedText(node), nrLines);\n// }\n\nexport function endsWithLinebreak(text: string, nrLines: number = 1): boolean {\n return new RegExp(`(\\\\n[\\\\t\\\\f\\\\r ]*){${nrLines}}$`).test(text);\n}\n\nexport function isTextNodeStartingWithWhitespace(node: Node): node is TextNode {\n return node.type === 'text' && /^\\s/.test(getUnencodedText(node));\n}\n\nexport function isTextNodeEndingWithWhitespace(node: Node): node is TextNode {\n return node.type === 'text' && /\\s$/.test(getUnencodedText(node));\n}\n\nexport function forceIntoExpression(statement: string): string {\n // note the trailing newline: if the statement ends in a // comment,\n // we can't add the closing bracket right afterwards\n return `(${statement}\\n)`;\n}\n\n/**\n * Check if given node's starg tag should hug its first child. This is the case for inline elements when there's\n * no whitespace between the `>` and the first child.\n */\nexport function shouldHugStart(node: anyNode, opts: ParserOptions): boolean {\n if (isBlockElement(node, opts)) {\n return false;\n }\n\n if (!isNodeWithChildren(node)) {\n return false;\n }\n\n const children = node.children;\n if (children.length === 0) {\n return true;\n }\n\n const firstChild = children[0];\n return !isTextNodeStartingWithWhitespace(firstChild);\n}\n\n/**\n * Check if given node's end tag should hug its last child. This is the case for inline elements when there's\n * no whitespace between the last child and the `</`.\n */\nexport function shouldHugEnd(node: anyNode, opts: ParserOptions): boolean {\n if (isBlockElement(node, opts)) {\n return false;\n }\n\n if (!isNodeWithChildren(node)) {\n return false;\n }\n\n const children = node.children;\n if (children.length === 0) {\n return true;\n }\n\n return false;\n\n // TODO: WIP\n // const lastChild = children[children.length - 1];\n // return !isTextNodeEndingWithWhitespace(lastChild);\n}\n\n/**\n * Returns true if the softline between `</tagName` and `>` can be omitted.\n */\nexport function canOmitSoftlineBeforeClosingTag(path: AstPath, opts: ParserOptions): boolean {\n return isLastChildWithinParentBlockElement(path, opts);\n // return !hugsStartOfNextNode(node, options) || isLastChildWithinParentBlockElement(path, options);\n // return !options.svelteBracketNewLine && (!hugsStartOfNextNode(node, options) || isLastChildWithinParentBlockElement(path, options));\n}\n\n/**\n * Return true if given node does not hug the next node, meaning there's whitespace\n * or the end of the doc afterwards.\n */\n// function hugsStartOfNextNode(node: anyNode, opts: ParserOptions): boolean {\n// if (node.end === opts.originalText.length) {\n// // end of document\n// return false;\n// }\n\n// return !opts.originalText.substring(node.end).match(/^\\s/);\n// }\n\nfunction getChildren(node: anyNode): Node[] {\n return isNodeWithChildren(node) ? node.children : [];\n}\n\nfunction isLastChildWithinParentBlockElement(path: AstPath, opts: ParserOptions): boolean {\n const parent = path.getParentNode();\n if (!parent || !isBlockElement(parent, opts)) {\n return false;\n }\n\n const children = getChildren(parent);\n const lastChild = children[children.length - 1];\n return lastChild === path.getNode();\n}\n\nexport function trimTextNodeLeft(node: TextNode): void {\n node.value = node.value && node.value.trimStart();\n}\n\nexport function trimTextNodeRight(node: TextNode): void {\n node.value = node.value && node.value.trimEnd();\n}\n\n// export function findLastIndex<T>(isMatch: (item: T, idx: number) => boolean, items: T[]) {\n// for (let i = items.length - 1; i >= 0; i--) {\n// if (isMatch(items[i], i)) {\n// return i;\n// }\n// }\n\n// return -1;\n// }\n\n/**\n * Remove all leading whitespace up until the first non-empty text node,\n * and all trailing whitepsace from the last non-empty text node onwards.\n */\n// export function trimChildren(children: anyNode[]) {\n// // export function trimChildren(children: anyNode[], path: AstPath<anyNode>) {\n// let firstNonEmptyNode = children.findIndex((n) => !isEmptyTextNode(n));\n// // let firstNonEmptyNode = children.findIndex((n) => !isEmptyTextNode(n) && !doesEmbedStartAfterNode(n, path));\n// firstNonEmptyNode = firstNonEmptyNode === -1 ? children.length - 1 : firstNonEmptyNode;\n\n// let lastNonEmptyNode = findLastIndex((n, idx) => {\n// // Last node is ok to end at the start of an embedded region,\n// // if it's not a comment (which should stick to the region)\n// return !isEmptyTextNode(n);\n// // return !isEmptyTextNode(n) && ((idx === children.length - 1 && n.type !== 'Comment') || !doesEmbedStartAfterNode(n, path));\n// }, children);\n// lastNonEmptyNode = lastNonEmptyNode === -1 ? 0 : lastNonEmptyNode;\n\n// for (let i = 0; i <= firstNonEmptyNode; i++) {\n// const n = children[i];\n// if (isTextNode(n)) {\n// trimTextNodeLeft(n);\n// }\n// }\n\n// for (let i = children.length - 1; i >= lastNonEmptyNode; i--) {\n// const n = children[i];\n// if (isTextNode(n)) {\n// trimTextNodeRight(n);\n// }\n// }\n// }\n\n/**\n * Returns siblings, that is, the children of the parent.\n */\n// export function getSiblings(path: AstPath): anyNode[] {\n// let parent = path.getParentNode();\n// if (!parent) return [];\n\n// if (isRootNode(parent)) {\n// parent = parent.html;\n// }\n\n// return getChildren(parent);\n// }\n\n/**\n * Did there use to be any embedded object (that has been snipped out of the AST to be moved)\n * at the specified position?\n */\n// function doesEmbedStartAfterNode(node: anyNode, path: AstPath<anyNode>, siblings = getSiblings(path)): boolean {\n// // If node is not at the top level of html, an embed cannot start after it,\n// // because embeds are only at the top level\n// if (!isNodeTopLevelHTML(node, path)) {\n// return false;\n// }\n\n// const position = node.end;\n// const root = path.stack[0];\n\n// const embeds = [root.module, root.html, root.css];\n\n// const nextNode = siblings[siblings.indexOf(node) + 1];\n// return embeds.find((n) => n && n.start >= position && (!nextNode || n.end <= nextNode.start));\n// }\n\n// function isNodeTopLevelHTML(node: anyNode, path: AstPath<anyNode>) {\n// const root = path.stack[0];\n// return !!root.html && !!root.html.children && root.html.children.includes(node);\n// }\n\n/**\n * Check if doc is a hardline.\n * We can't just rely on a simple equality check because the doc could be created with another\n * runtime version of prettier than what we import, making a reference check fail.\n */\n\n// function isHardline(docToCheck: Doc): boolean {\n// return docToCheck === doc.builders.hardline || deepEqual(docToCheck, doc.builders.hardline);\n// }\n\n/**\n * Simple deep equal function which suits our needs. Only works properly on POJOs without cyclic deps.\n */\n// function deepEqual(x: any, y: any): boolean {\n// if (x === y) {\n// return true;\n// } else if (typeof x == 'object' && x != null && typeof y == 'object' && y != null) {\n// if (Object.keys(x).length != Object.keys(y).length) return false;\n\n// for (var prop in x) {\n// if (Object.prototype.hasOwnProperty.call(y, prop)) {\n// if (!deepEqual(x[prop], y[prop])) return false;\n// } else {\n// return false;\n// }\n// }\n\n// return true;\n// } else {\n// return false;\n// }\n// }\n\n// export function isLine(docToCheck: Doc): boolean {\n// return (\n// isHardline(docToCheck) ||\n// (typeof docToCheck === 'object' && isDocCommand(docToCheck) && docToCheck.type === 'line') ||\n// (typeof docToCheck === 'object' && isDocCommand(docToCheck) && docToCheck.type === 'concat' && docToCheck.parts.every(isLine))\n// );\n// }\n\n/**\n * Check if the doc is empty, i.e. consists of nothing more than empty strings (possibly nested).\n */\n// export function isEmptyDoc(doc: Doc): boolean {\n// if (typeof doc === 'string') {\n// return doc.length === 0;\n// }\n\n// // if (doc.type === 'line') {\n// // return !doc.keepIfLonely;\n// // }\n\n// // Since Prettier 2.3.0, concats are represented as flat arrays\n// if (Array.isArray(doc)) {\n// return doc.length === 0;\n// }\n\n// // const { contents } = doc;\n\n// // if (contents) {\n// // return isEmptyDoc(contents);\n// // }\n\n// // const { parts } = doc;\n\n// // if (parts) {\n// // return isEmptyGroup(parts);\n// // }\n\n// return false;\n// }\n\n// function isEmptyGroup(group: any) {\n// return !group.find((doc: any) => !isEmptyDoc(doc));\n// }\n\n/**\n * Trims both leading and trailing nodes matching `isWhitespace` independent of nesting level\n * (though all trimmed adjacent nodes need to be a the same level). Modifies the `docs` array.\n */\n// export function trim(docs: Doc[], isWhitespace: (doc: Doc) => boolean): Doc[] {\n// trimLeft(docs, isWhitespace);\n// trimRight(docs, isWhitespace);\n\n// return docs;\n// }\n\n/**\n * Trims the leading nodes matching `isWhitespace` independent of nesting level (though all nodes need to be a the same level).\n * If there are empty docs before the first whitespace, they are removed, too.\n */\n// function trimLeft(group: Doc[], isWhitespace: (doc: Doc) => boolean): void {\n// let firstNonWhitespace = group.findIndex((doc) => !isEmptyDoc(doc) && !isWhitespace(doc));\n\n// if (firstNonWhitespace < 0 && group.length) {\n// firstNonWhitespace = group.length;\n// }\n\n// if (firstNonWhitespace > 0) {\n// const removed = group.splice(0, firstNonWhitespace);\n// if (removed.every(isEmptyDoc)) {\n// return trimLeft(group, isWhitespace);\n// }\n// } else {\n// const parts = getParts(group[0]);\n\n// if (parts) {\n// return trimLeft(parts, isWhitespace);\n// }\n// }\n// }\n\n/**\n * Trims the trailing nodes matching `isWhitespace` independent of nesting level (though all nodes need to be a the same level).\n * If there are empty docs after the last whitespace, they are removed, too.\n */\n// function trimRight(group: Doc[], isWhitespace: (doc: Doc) => boolean): void {\n// let lastNonWhitespace = group.length ? findLastIndex((doc: any) => !isEmptyDoc(doc) && !isWhitespace(doc), group) : 0;\n\n// if (lastNonWhitespace < group.length - 1) {\n// const removed = group.splice(lastNonWhitespace + 1);\n// if (removed.every(isEmptyDoc)) {\n// return trimRight(group, isWhitespace);\n// }\n// } else {\n// const parts = getParts(group[group.length - 1]);\n\n// if (parts) {\n// return trimRight(parts, isWhitespace);\n// }\n// }\n// }\n\n// function getParts(doc: Doc): Doc[] | undefined {\n// if (typeof doc === 'object') {\n// // Since Prettier 2.3.0, concats are represented as flat arrays\n// if (Array.isArray(doc)) {\n// return doc;\n// }\n// if (doc.type === 'fill' || doc.type === 'concat') {\n// return doc.parts;\n// }\n// if (doc.type === 'group') {\n// return getParts(doc.contents);\n// }\n// }\n// }\n\n// export const isObjEmpty = (obj: object): boolean => {\n// for (let i in obj) return false;\n// return true;\n// };\n\n/** Shallowly attach comments to children */\n// export function attachCommentsHTML(node: anyNode): void {\n// if (!isNodeWithChildren(node) || !node.children.some(({ type }) => type === 'Comment')) return;\n\n// const nodesToRemove = [];\n\n// // note: the .length - 1 is because we don’t need to read the last node\n// for (let n = 0; n < node.children.length - 1; n++) {\n// if (!node.children[n]) continue;\n\n// // attach comment to the next non-whitespace node\n// if (node.children[n].type === 'Comment') {\n// let next = n + 1;\n// while (isEmptyTextNode(node.children[next])) {\n// nodesToRemove.push(next); // if arbitrary whitespace between comment and node, remove\n// next++; // skip to the next non-whitespace node\n// }\n// const commentNode = node.children[next];\n// if (commentNode) {\n// const comment = node.children[n];\n// util.addLeadingComment(commentNode, comment);\n// }\n// }\n// }\n\n// // remove arbitrary whitespace nodes\n// nodesToRemove.reverse(); // start at back so we aren’t changing indices\n// nodesToRemove.forEach((index) => {\n// node.children.splice(index, 1);\n// });\n// }\n\n// https://github.com/dmnd/dedent/blob/master/dist/dedent.js\nexport function manualDedent(input: string) {\n // first, perform interpolation\n let result = '';\n for (var i = 0; i < input.length; i++) {\n result += input[i]\n // join lines when there is a suppressed newline\n .replace(/\\\\\\n[ \\t]*/g, '')\n // handle escaped backticks\n .replace(/\\\\`/g, '`');\n\n if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {\n result += arguments.length <= i + 1 ? undefined : arguments[i + 1];\n }\n }\n\n // now strip indentation\n const lines = result.split('\\n');\n let mindent: number | null = null;\n lines.forEach(function (l) {\n var m = l.match(/^(\\s+)\\S+/);\n if (m) {\n var indent = m[1].length;\n if (!mindent) {\n // this is the first indented line\n mindent = indent;\n } else {\n mindent = Math.min(mindent, indent);\n }\n }\n });\n\n if (mindent !== null) {\n (function () {\n var m = mindent; // appease Flow\n result = lines\n .map(function (l) {\n return l[0] === ' ' ? l.slice(m) : l;\n })\n .join('\\n');\n })();\n }\n\n return {\n result: result\n // dedent eats leading and trailing whitespace too\n .trim()\n // handle escaped newlines at the end to ensure they don't get stripped too\n .replace(/\\\\n/g, '\\n'),\n };\n}\n\n/** re-indent string by chars */\n// export function indent(input: string, char: string = ' '): string {\n// return input.replace(/^(.)/gm, `${char}$1`);\n// }\n\n/** scan code for Markdown name(s) */\nexport function getMarkdownName(script: string): Set<string> {\n // default import: could be named anything\n let defaultMatch;\n while ((defaultMatch = /import\\s+([^\\s]+)\\s+from\\s+['|\"|`]astro\\/components\\/Markdown\\.astro/g.exec(script))) {\n if (defaultMatch[1]) return new Set([defaultMatch[1].trim()]);\n }\n\n // named component: must have \"Markdown\" in specifier, but can be renamed via \"as\"\n let namedMatch;\n while ((namedMatch = /import\\s+\\{\\s*([^}]+)\\}\\s+from\\s+['|\"|`]astro\\/components/g.exec(script))) {\n if (namedMatch[1] && !namedMatch[1].includes('Markdown')) continue;\n // if \"Markdown\" was imported, find out whether or not it was renamed\n const rawImports = namedMatch[1].trim().replace(/^\\{/, '').replace(/\\}$/, '').trim();\n let importName = 'Markdown';\n for (const spec of rawImports.split(',')) {\n const [original, renamed] = spec.split(' as ').map((s) => s.trim());\n if (original !== 'Markdown') continue;\n importName = renamed || original;\n break;\n }\n return new Set([importName]);\n }\n return new Set(['Markdown']);\n}\n\n// TODO: USE THE COMPILER\n/** True if the node is of type text */\nexport function isTextNode(node: Node): node is TextNode {\n return node.type === 'text';\n}\n\n// export function isMustacheNode(node: anyNode): node is MustacheTagNode {\n// return node.type === 'MustacheTag';\n// }\n\n// export function isDocCommand(doc: Doc): doc is doc.builders.DocCommand {\n// if (typeof doc === 'string') return false;\n// if (Array.isArray(doc)) return false;\n// return true;\n// }\n\nexport function isInsideQuotedAttribute(path: AstPath): boolean {\n const stack = path.stack as anyNode[];\n return stack.some((node) => node.type === 'attribute' && !isLoneMustacheTag(node));\n}\n","import { AstPath as AstP, BuiltInParsers, Doc, ParserOptions as ParserOpts, Printer } from 'prettier';\nimport _doc from 'prettier/doc';\nconst {\n builders: { breakParent, dedent, fill, group, hardline, indent, join, line, literalline, softline },\n utils: { removeLines, stripTrailingHardline },\n} = _doc;\nimport { SassFormatter, SassFormatterConfig } from 'sass-formatter';\n\nimport { parseSortOrder } from './options';\n\nimport { RootNode, Node, AttributeNode, CommentNode, NodeWithText, selfClosingTags, TextNode, anyNode } from './nodes';\n\ntype ParserOptions = ParserOpts<anyNode>;\ntype AstPath = AstP<anyNode>;\n\nimport {\n // attachCommentsHTML,\n canOmitSoftlineBeforeClosingTag,\n manualDedent,\n endsWithLinebreak,\n forceIntoExpression,\n formattableAttributes,\n getMarkdownName,\n getText,\n getUnencodedText,\n isRootNode,\n // isDocCommand,\n // isEmptyDoc,\n isEmptyTextNode,\n isInlineElement,\n isInsideQuotedAttribute,\n // isLine,\n isLoneMustacheTag,\n // isNodeWithChildren,\n isOrCanBeConvertedToShorthand,\n isPreTagContent,\n isShorthandAndMustBeConvertedToBinaryExpression,\n isTextNode,\n isTextNodeEndingWithWhitespace,\n isTextNodeStartingWithLinebreak,\n isTextNodeStartingWithWhitespace,\n printRaw,\n // replaceEndOfLineWith,\n shouldHugEnd,\n shouldHugStart,\n startsWithLinebreak,\n // trim,\n // trimChildren,\n trimTextNodeLeft,\n trimTextNodeRight,\n} from './utils';\n\n// function printTopLevelParts(node: RootNode, path: AstPath, opts: ParserOptions, print: printFn): Doc {\n// let docs = [];\n\n// const normalize = (doc: Doc) => [stripTrailingHardline(doc), hardline];\n\n// // frontmatter always comes first\n// if (node.module) {\n// const subDoc = normalize(path.call(print, 'module'));\n// docs.push(subDoc);\n// }\n\n// // markup and styles follow, whichever the user prefers (default: markup, styles)\n// for (const section of parseSortOrder(opts.astroSortOrder)) {\n// switch (section) {\n// case 'markup': {\n// const subDoc = path.call(print, 'html');\n// if (!isEmptyDoc(subDoc)) docs.push(normalize(subDoc));\n// break;\n// }\n// case 'styles': {\n// const subDoc = path.call(print, 'css');\n// if (!isEmptyDoc(subDoc)) docs.push(normalize(subDoc));\n// break;\n// }\n// }\n// }\n\n// return join(softline, docs);\n// }\n\n// function printAttributeNodeValue(path: AstPath, print: printFn, quotes: boolean, node: AttributeNode): Doc[] | _doc.builders.Indent {\n// const valueDocs = path.map((childPath) => childPath.call(print), 'value');\n\n// if (!quotes || !formattableAttributes.includes(node.name)) {\n// return valueDocs;\n// } else {\n// return indent(group(trim(valueDocs, isLine)));\n// }\n// }\n\n// TODO: USE ASTPATH GENERIC\n// function printJS(path: AstP, print: printFn, name: string, { forceSingleQuote, forceSingleLine }: { forceSingleQuote: boolean; forceSingleLine: boolean }) {\n// path.getValue()[name].isJS = true;\n// path.getValue()[name].forceSingleQuote = forceSingleQuote;\n// path.getValue()[name].forceSingleLine = forceSingleLine;\n// return path.call(print, name);\n// }\n\n// TODO: MAYBE USE THIS TO HANDLE COMMENTS\nfunction printComment(commentPath: AstPath, options: ParserOptions): Doc {\n // note(drew): this isn’t doing anything currently, but Prettier requires it anyway\n // @ts-ignore\n return commentPath;\n}\n\nexport type printFn = (path: AstPath) => Doc;\n\nfunction print(path: AstPath, opts: ParserOptions, print: printFn): Doc {\n const node = path.getValue();\n // const isMarkdownSubDoc = opts.parentParser === 'markdown'; // is this a code block within .md?\n\n // 1. handle special node types\n if (!node) {\n return '';\n }\n\n if (typeof node === 'string') {\n return node;\n }\n\n // if (Array.isArray(node)) {\n // return path.map((childPath) => childPath.call(print));\n // }\n\n // if (isASTNode(node)) {\n // return printTopLevelParts(node, path, opts, print);\n // }\n\n // 2. attach comments shallowly to children, if any (https://prettier.io/docs/en/plugins.html#manually-attaching-a-comment)\n // if (!isPreTagContent(path) && !isMarkdownSubDoc && node.type === 'Fragment') {\n // attachCommentsHTML(node);\n // }\n\n // 3. handle printing\n switch (node.type) {\n case 'root': {\n return [stripTrailingHardline(path.map(print, 'children')), hardline];\n }\n\n // case 'Fragment': {\n // const text = getText(node, opts);\n // if (text.length === 0) {\n // return '';\n // }\n\n // if (!isNodeWithChildren(node) || node.children.every(isEmptyTextNode)) return '';\n\n // if (!isPreTagContent(path)) {\n // trimChildren(node.children);\n // const output = trim(\n // [path.map(print, 'children')],\n // (n) =>\n // isLine(n) ||\n // (typeof n === 'string' && n.trim() === '') ||\n // // Because printChildren may append this at the end and\n // // may hide other lines before it\n // n === breakParent\n // );\n // if (output.every((doc) => isEmptyDoc(doc))) {\n // return '';\n // }\n // return group([...output, hardline]);\n // } else {\n // return group(path.map(print, 'children'));\n // }\n // }\n case 'text': {\n const rawText = getUnencodedText(node);\n\n // TODO: TEST PRE TAGS\n // if (isPreTagContent(path)) {\n // if (path.getParentNode()?.type === 'Attribute') {\n // // Direct child of attribute value -> add literallines at end of lines\n // // so that other things don't break in unexpected places\n // return replaceEndOfLineWith(rawText, literalline);\n // }\n // return rawText;\n // }\n\n if (isEmptyTextNode(node)) {\n const hasWhiteSpace = rawText.trim().length < getUnencodedText(node).length;\n const hasOneOrMoreNewlines = /\\n/.test(getUnencodedText(node));\n const hasTwoOrMoreNewlines = /\\n\\r?\\s*\\n\\r?/.test(getUnencodedText(node));\n if (hasTwoOrMoreNewlines) {\n return [hardline, hardline];\n }\n if (hasOneOrMoreNewlines) {\n return hardline;\n }\n if (hasWhiteSpace) {\n return line;\n }\n return '';\n }\n\n /**\n * For non-empty text nodes each sequence of non-whitespace characters (effectively,\n * each \"word\") is joined by a single `line`, which will be rendered as a single space\n * until this node's current line is out of room, at which `fill` will break at the\n * most convenient instance of `line`.\n */\n return fill(splitTextToDocs(node));\n }\n\n // case 'InlineComponent':\n // case 'Slot':\n case 'component':\n case 'fragment':\n case 'element': {\n // const isEmpty = node.children?.every((child) => isEmptyTextNode(child));\n let isEmpty: boolean;\n if (!node.children) {\n isEmpty = true;\n } else {\n isEmpty = node.children.every((child) => isEmptyTextNode(child));\n }\n const isSelfClosingTag = isEmpty && (node.type !== 'element' || selfClosingTags.indexOf(node.name) !== -1);\n\n const attributes = node.attributes ? path.map(print, 'attributes') : [];\n if (isSelfClosingTag) {\n return group(['<', node.name, indent(group(attributes)), line, `/>`]);\n // return group(['<', node.name, indent(group([...attributes, opts.jsxBracketNewLine ? dedent(line) : ''])), ...[opts.jsxBracketNewLine ? '' : ' ', `/>`]]);\n }\n\n if (node.children) {\n const children = node.children;\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n\n // No hugging of content means it's either a block element and/or there's whitespace at the start/end\n let noHugSeparatorStart: _doc.builders.Concat | _doc.builders.Line | _doc.builders.Softline | string = softline;\n let noHugSeparatorEnd: _doc.builders.Concat | _doc.builders.Line | _doc.builders.Softline | string = softline;\n let hugStart = shouldHugStart(node, opts);\n let hugEnd = shouldHugEnd(node, opts);\n\n let body;\n\n if (isEmpty) {\n body =\n isInlineElement(path, opts, node) && node.children.length && isTextNodeStartingWithWhitespace(node.children[0]) && !isPreTagContent(path)\n ? () => line\n : // () => (opts.jsxBracketNewLine ? '' : softline);\n () => softline;\n } else if (isPreTagContent(path)) {\n body = () => printRaw(node);\n } else if (isInlineElement(path, opts, node) && !isPreTagContent(path)) {\n body = () => path.map(print, 'children');\n } else {\n body = () => path.map(print, 'children');\n }\n\n const openingTag = ['<', node.name, indent(group([...attributes, hugStart ? '' : !isPreTagContent(path) && !opts.bracketSameLine ? dedent(softline) : '']))];\n // const openingTag = ['<', node.name, indent(group([...attributes, hugStart ? '' : opts.jsxBracketNewLine && !isPreTagContent(path) ? dedent(softline) : '']))];\n\n if (hugStart && hugEnd) {\n const huggedContent = [softline, group(['>', body(), `</${node.name}`])];\n\n const omitSoftlineBeforeClosingTag = isEmpty || canOmitSoftlineBeforeClosingTag(path, opts);\n // const omitSoftlineBeforeClosingTag = (isEmpty && opts.jsxBracketNewLine) || canOmitSoftlineBeforeClosingTag(node, path, opts);\n return group([...openingTag, isEmpty ? group(huggedContent) : group(indent(huggedContent)), omitSoftlineBeforeClosingTag ? '' : softline, '>']);\n }\n\n if (isPreTagContent(path)) {\n noHugSeparatorStart = '';\n noHugSeparatorEnd = '';\n } else {\n let didSetEndSeparator = false;\n\n if (!hugStart && firstChild && isTextNode(firstChild)) {\n if (isTextNodeStartingWithLinebreak(firstChild) && firstChild !== lastChild && (!isInlineElement(path, opts, node) || isTextNodeEndingWithWhitespace(lastChild))) {\n noHugSeparatorStart = hardline;\n noHugSeparatorEnd = hardline;\n didSetEndSeparator = true;\n } else if (isInlineElement(path, opts, node)) {\n noHugSeparatorStart = line;\n }\n trimTextNodeLeft(firstChild);\n }\n if (!hugEnd && lastChild && isTextNode(lastChild)) {\n if (isInlineElement(path, opts, node) && !didSetEndSeparator) {\n noHugSeparatorEnd = softline;\n }\n trimTextNodeRight(lastChild);\n }\n }\n\n if (hugStart) {\n return group([...openingTag, indent([softline, group(['>', body()])]), noHugSeparatorEnd, `</${node.name}>`]);\n }\n\n if (hugEnd) {\n return group([...openingTag, '>', indent([noHugSeparatorStart, group([body(), `</${node.name}`])]), canOmitSoftlineBeforeClosingTag(path, opts) ? '' : softline, '>']);\n }\n\n if (isEmpty) {\n return group([...openingTag, '>', body(), `</${node.name}>`]);\n }\n\n return group([...openingTag, '>', indent([noHugSeparatorStart, body()]), noHugSeparatorEnd, `</${node.name}>`]);\n }\n // TODO: WIP\n return '';\n }\n // case 'AttributeShorthand': {\n // return node.expression.name;\n // }\n case 'attribute': {\n const name = node.name.trim();\n const quote = opts.singleQuote ? \"'\" : '\"';\n switch (node.kind) {\n case 'empty':\n return [line, name];\n case 'expression':\n // HANDLED IN EMBED FUNCION\n return '';\n case 'quoted':\n return [line, name, '=', quote, node.value, quote];\n case 'shorthand':\n return [line, '{', name, '}'];\n case 'spread':\n return [line, '{...', name, '}'];\n case 'template-literal':\n return [line, name, '=', '`', node.value, '`'];\n default:\n break;\n }\n return '';\n }\n\n case 'directive': {\n return [line, node.name];\n }\n\n case 'doctype': {\n // https://www.w3.org/wiki/Doctypes_and_markup_styles\n return ['<!DOCTYPE html>', hardline];\n }\n // case 'Expression':\n // // missing test ?\n // return [];\n // case 'MustacheTag':\n // return [\n // '{',\n // printJS(path, print, 'expression', {\n // forceSingleLine: isInsideQuotedAttribute(path),\n // forceSingleQuote: opts.jsxSingleQuote,\n // }),\n // '}',\n // ];\n // case 'Spread':\n // return [\n // line,\n // '{...',\n // printJS(path, print, 'expression', {\n // forceSingleQuote: true,\n // forceSingleLine: false,\n // }),\n // '}',\n // ];\n case 'comment':\n return ['<!--', getUnencodedText(node), '-->'];\n // case 'CodeSpan':\n // return getUnencodedText(node);\n // case 'CodeFence': {\n // console.debug(node);\n // // const lang = node.metadata.slice(3);\n // return [node.metadata, hardline, /** somehow call textToDoc(lang), */ node.data, hardline, '```', hardline];\n\n // // We should use `node.metadata` to select a parser to embed with... something like return [node.metadata, hardline textToDoc(node.getMetadataLanguage()), hardline, `\\`\\`\\``];\n // }\n default: {\n throw new Error(`Unhandled node type \"${node.type}\"!`);\n }\n }\n}\n\n/**\n * Split the text into words separated by whitespace. Replace the whitespaces by lines,\n * collapsing multiple whitespaces into a single line.\n *\n * If the text starts or ends with multiple newlines, two of those should be kept.\n */\nfunction splitTextToDocs(node: NodeWithText): Doc[] {\n const text = getUnencodedText(node);\n\n let textLines = text.split(/[\\t\\n\\f\\r ]+/);\n\n let docs = join(line, textLines).parts.filter((s) => s !== '');\n\n if (startsWithLinebreak(text)) {\n docs[0] = hardline;\n }\n if (startsWithLinebreak(text, 2)) {\n docs = [hardline, ...docs];\n }\n\n if (endsWithLinebreak(text)) {\n docs[docs.length - 1] = hardline;\n }\n if (endsWithLinebreak(text, 2)) {\n docs = [...docs, hardline];\n }\n\n return docs;\n}\n\nfunction expressionParser(text: string, parsers: BuiltInParsers, opts: ParserOptions) {\n const ast = parsers.babel(text, opts);\n // const ast = parsers.babel(text, parsers, opts);\n\n return { ...ast, program: ast.program.body[0].expression };\n}\n\nlet markdownComponentName = new Set();\n\nfunction embed(path: AstPath, print: printFn, textToDoc: (text: string, options: object) => Doc, opts: ParserOptions) {\n // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // @ts-ignore\n if (!opts.__astro) opts.__astro = {};\n\n const node = path.getValue();\n\n if (!node) return null;\n\n if (node.type === 'expression') {\n const textContent = getText(node, opts);\n\n let content: Doc | string;\n\n if (node.children.length === 1) {\n content = textContent;\n } else {\n content = textToDoc(textContent, { ...opts, parser: 'babel-ts', semi: false });\n content = stripTrailingHardline(content);\n }\n\n // if (node.children[0].value) {\n // content = textToDoc(forceIntoExpression(textContent), { parser: expressionParser });\n // } else {\n // content = textToDoc(forceIntoExpression(node.children[0].value), { parser: expressionParser });\n // }\n return [\n '{',\n // printJS(path, print, 'expression', {\n // forceSingleLine: isInsideQuotedAttribute(path),\n // forceSingleQuote: opts.jsxSingleQuote,\n // }),\n content,\n '}',\n ];\n }\n\n // ATTRIBUTE WITH EXPRESSION AS VALUE\n if (node.type === 'attribute' && node.kind === 'expression') {\n const value = node.value.trim();\n const name = node.name.trim();\n let attrNodeValue = textToDoc(forceIntoExpression(value), { ...opts, parser: expressionParser, semi: false });\n attrNodeValue = stripTrailingHardline(attrNodeValue);\n // if (Array.isArray(attrNodeValue) && attrNodeValue[0] === ';') {\n // attrNodeValue = attrNodeValue.slice(1);\n // }\n if (name === value && opts.astroAllowShorthand) {\n return [line, '{', attrNodeValue, '}'];\n }\n return [line, name, '=', '{', attrNodeValue, '}'];\n }\n\n // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // @ts-ignore\n // if (node.isJS) {\n // try {\n // const embeddedopts = {\n // parser: expressionParser,\n // };\n // // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // // @ts-ignore\n // if (node.forceSingleQuote) {\n // // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // // @ts-ignore\n // embeddedopts.singleQuote = true;\n // }\n\n // const docs = textToDoc(forceIntoExpression(getText(node, opts)), embeddedopts);\n // // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // // @ts-ignore\n // return node.forceSingleLine ? removeLines(docs) : docs;\n // } catch (e) {\n // return getText(node, opts);\n // }\n // }\n\n if (node.type === 'frontmatter') {\n markdownComponentName = getMarkdownName(node.value);\n return [group(['---', hardline, textToDoc(node.value, { ...opts, parser: 'typescript' }), '---', hardline]), hardline];\n }\n\n // format script element\n if (node.type === 'element' && node.name === 'script') {\n const scriptContent = node.children[0].value;\n let formatttedScript = textToDoc(scriptContent, { ...opts, parser: 'typescript' });\n formatttedScript = stripTrailingHardline(formatttedScript);\n\n // print\n const attributes = node.attributes ? path.map(print, 'attributes') : [];\n const openingTag = group(['<script', indent(group(attributes)), softline, '>']);\n return [openingTag, indent([hardline, formatttedScript]), hardline, '</script>'];\n }\n // if (isTextNode(node)) {\n // const parent = path.getParentNode();\n\n // if (parent && parent.type === 'Element' && parent.name === 'script') {\n // const formatttedScript = textToDoc(node.data, { ...opts, parser: 'typescript' });\n // return stripTrailingHardline(formatttedScript);\n // }\n // }\n\n // format style element\n if (node.type === 'element' && node.name === 'style') {\n let styleTagContent = node.children[0].value.trim();\n\n const supportedStyleLangValues = ['css', 'scss', 'sass'];\n let parserLang = 'css';\n\n if (node.attributes) {\n const langAttribute = node.attributes.filter((x) => x.name === 'lang');\n if (langAttribute.length) {\n const styleLang = langAttribute[0].value.toLowerCase();\n if (supportedStyleLangValues.includes(styleLang)) parserLang = styleLang;\n }\n }\n\n switch (parserLang) {\n case 'css':\n case 'scss': {\n // the css parser appends an extra indented hardline, which we want outside of the `indent()`,\n // so we remove the last element of the array\n let formattedStyles = textToDoc(styleTagContent, { ...opts, parser: parserLang });\n\n formattedStyles = stripTrailingHardline(formattedStyles);\n\n // print\n const attributes = node.attributes ? path.map(print, 'attributes') : [];\n const directives = node.directives ? path.map(print, 'directives') : [];\n const attrAndDirectives = directives.concat(attributes);\n const openingTag = group(['<style', indent(group(attrAndDirectives)), softline, '>']);\n return [openingTag, indent([hardline, formattedStyles]), hardline, '</style>'];\n }\n case 'sass': {\n const lineEnding = opts.endOfLine.toUpperCase() === 'CRLF' ? 'CRLF' : 'LF';\n const sassOptions: Partial<SassFormatterConfig> = {\n tabSize: opts.tabWidth,\n insertSpaces: !opts.useTabs,\n lineEnding,\n };\n\n // dedent the .sass, otherwise SassFormatter gets indentation wrong\n const { result: raw } = manualDedent(styleTagContent);\n\n // format\n let formattedSassIndented = SassFormatter.Format(raw, sassOptions).trim();\n\n // print\n const formattedSass = join(hardline, formattedSassIndented.split('\\n'));\n const attributes = node.attributes ? path.map(print, 'attributes') : [];\n const openingTag = group(['<style', indent(group(attributes)), softline, '>']);\n return [openingTag, indent(group([hardline, formattedSass])), hardline, '</style>'];\n }\n }\n }\n\n // MARKDOWN COMPONENT\n if (node.type === 'component' && markdownComponentName.has(node.name)) {\n let content = printRaw(node);\n\n // dedent the content\n content = content.replace(/\\r\\n/g, '\\n');\n const contentArr = content.split('\\n').map((s) => s.trimStart());\n content = contentArr.join('\\n');\n\n // format\n let formatttedMarkdown = textToDoc(content, { ...opts, parser: 'markdown' });\n formatttedMarkdown = stripTrailingHardline(formatttedMarkdown);\n\n // return formatttedMarkdown;\n const attributes = path.map(print, 'attributes');\n const openingTag = group([`<${node.name}`, indent(group(attributes)), softline, '>']);\n return [openingTag, indent(group([hardline, formatttedMarkdown])), hardline, `</${node.name}>`];\n }\n\n return null;\n}\n\nfunction hasPrettierIgnore(path: AstP<CommentNode>) {\n // const node = path.getNode();\n\n // if (!node || !Array.isArray(node.comments)) return false;\n\n // const hasIgnore = node.comments.some(\n // (comment: any) => comment.data.includes('prettier-ignore') && !comment.data.includes('prettier-ignore-start') && !comment.data.includes('prettier-ignore-end')\n // );\n // return hasIgnore;\n return false;\n}\n\nconst printer: Printer = {\n print,\n printComment,\n embed,\n hasPrettierIgnore,\n};\n\nexport default printer;\n","import { SupportOption } from 'prettier';\n\ndeclare module 'prettier' {\n interface RequiredOptions extends PluginOptions {}\n}\n\nexport interface PluginOptions {\n astroSortOrder: SortOrder;\n astroAllowShorthand: boolean;\n}\n\nexport const options: Record<keyof PluginOptions, SupportOption> = {\n astroSortOrder: {\n since: '0.0.1',\n category: 'Astro',\n type: 'choice',\n default: 'markup | styles',\n description: 'Sort order for markup, scripts, and styles',\n choices: [\n {\n value: 'markup | styles',\n description: 'markup | styles',\n },\n {\n value: 'styles | markup',\n description: 'styles | markup',\n },\n ],\n },\n astroAllowShorthand: {\n since: '0.0.10',\n category: 'Astro',\n type: 'boolean',\n default: true,\n description: 'Enable/disable attribute shorthand if attribute name and expression are the same',\n },\n};\n\nexport const parseSortOrder = (sortOrder: SortOrder): SortOrderPart[] => sortOrder.split(' | ') as SortOrderPart[];\n\nexport type SortOrder = 'markup | styles' | 'styles | markup';\n\nexport type SortOrderPart = 'markup' | 'styles';\n","import parse from './parse';\nimport printer from './printer';\nimport { options } from './options';\nimport { Parser, Printer, SupportLanguage } from 'prettier';\n\nexport const languages: Partial<SupportLanguage>[] = [\n {\n name: 'astro',\n parsers: ['astro'],\n extensions: ['.astro'],\n vscodeLanguageIds: ['astro'],\n },\n];\n\nexport const parsers: Record<string, Parser> = {\n astro: {\n parse,\n astFormat: 'astro',\n locStart: (node) => node.start,\n locEnd: (node) => node.end,\n },\n};\n\nexport const printers: Record<string, Printer> = {\n astro: printer,\n};\n\nconst defaultOptions = {\n tabWidth: 2,\n};\n\nexport { options, defaultOptions };\n"],"names":["makeSynchronous","_doc","SassFormatter"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/nodes.ts","../src/utils.ts","../src/printer.ts","../src/options.ts","../src/index.ts"],"sourcesContent":["import {\n Node,\n AttributeNode,\n RootNode,\n ElementNode,\n ComponentNode,\n CustomElementNode,\n ExpressionNode,\n TextNode,\n FrontmatterNode,\n DoctypeNode,\n CommentNode,\n FragmentNode,\n} from '@astrojs/compiler/types';\n\n// MISSING ATTRIBUTE NODE FROM THE NODE TYPE\n\nexport interface NodeWithText {\n value: string;\n}\n\n// export interface Ast {\n// html: anyNode;\n// css: StyleNode[];\n// module: ScriptNode;\n// meta: {\n// features: number;\n// };\n// }\n\n// export interface BaseNode {\n// start: number;\n// end: number;\n// type: string;\n// children?: anyNode[];\n// // TODO: ADD BETTER TYPE\n// [prop_name: string]: any;\n// }\n\n// export type attributeValue = TextNode[] | AttributeShorthandNode[] | MustacheTagNode[] | true;\n\nexport interface NodeWithChildren {\n // children: anyNode[];\n children: Node[];\n}\n\n// export interface NodeWithText {\n// data: string;\n// raw?: string;\n// }\n\n// export interface FragmentNode extends BaseNode {\n// type: 'Fragment';\n// children: anyNode[];\n// }\n\n// export interface TextNode extends BaseNode {\n// type: 'Text';\n// data: string;\n// raw: string;\n// }\n\n// export interface CodeFenceNode extends BaseNode {\n// type: 'CodeFence';\n// metadata: string;\n// data: string;\n// raw: string;\n// }\n\n// export interface CodeSpanNode extends BaseNode {\n// type: 'CodeSpan';\n// metadata: string;\n// data: string;\n// raw: string;\n// }\n\n// export interface SpreadNode extends BaseNode {\n// type: 'Spread';\n// expression: ExpressionNode;\n// }\n\n// export interface ExpressionNode {\n// type: 'Expression';\n// start: number;\n// end: number;\n// codeChunks: string[];\n// children: anyNode[];\n// }\n\n// export interface ScriptNode extends BaseNode {\n// type: 'Script';\n// context: 'runtime' | 'setup';\n// content: string;\n// }\n\n// export interface StyleNode extends BaseNode {\n// type: 'Style';\n// // TODO: ADD BETTER TYPE\n// attributes: any[];\n// content: {\n// start: number;\n// end: number;\n// styles: string;\n// };\n// }\n\n// export interface AttributeNode extends BaseNode {\n// type: 'Attribute';\n// name: string;\n// value: attributeValue;\n// }\n\n// export interface AttributeShorthandNode extends BaseNode {\n// type: 'AttributeShorthand';\n// expression: IdentifierNode;\n// }\n\n// export interface IdentifierNode extends BaseNode {\n// type: 'Identifier';\n// name: string;\n// }\n\n// export interface MustacheTagNode extends BaseNode {\n// type: 'MustacheTag';\n// expression: ExpressionNode;\n// }\n\n// export interface SlotNode extends BaseNode {\n// type: 'Slot';\n// name: string;\n// attributes: AttributeNode[];\n// }\n\n// export interface CommentNode extends BaseNode {\n// type: 'Comment';\n// data: string;\n// name?: string;\n// leading?: boolean;\n// trailing?: boolean;\n// printed?: boolean;\n// nodeDescription?: string;\n// }\n\n// export interface ElementNode extends BaseNode {\n// type: 'Element';\n// name: string;\n// attributes: AttributeNode[];\n// }\n\n// export interface InlineComponentNode extends BaseNode {\n// type: 'InlineComponent';\n// name: string;\n// attributes: AttributeNode[];\n// }\n\nexport interface BlockElementNode extends ElementNode {\n name: typeof blockElementsT[number];\n}\n\nexport interface InlineElementNode extends ElementNode {\n name: typeof inlineElementsT[number];\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements#Elements\nconst blockElementsT = [\n 'address',\n 'article',\n 'aside',\n 'blockquote',\n 'details',\n 'dialog',\n 'dd',\n 'div',\n 'dl',\n 'dt',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'li',\n 'main',\n 'nav',\n 'ol',\n 'p',\n 'pre',\n 'section',\n 'table',\n 'ul',\n // TODO: WIP\n 'title',\n 'html',\n] as const;\n// https://github.com/microsoft/TypeScript/issues/31018\nexport const blockElements: string[] = [...blockElementsT];\n\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements\nconst inlineElementsT = [\n 'a',\n 'abbr',\n 'acronym',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'br',\n 'button',\n 'canvas',\n 'cite',\n 'code',\n 'data',\n 'datalist',\n 'del',\n 'dfn',\n 'em',\n 'embed',\n 'i',\n 'iframe',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'map',\n 'mark',\n 'meter',\n 'noscript',\n 'object',\n 'output',\n 'picture',\n 'progress',\n 'q',\n 'ruby',\n 's',\n 'samp',\n 'script',\n 'select',\n 'slot',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'sup',\n 'svg',\n 'template',\n 'textarea',\n 'time',\n 'u',\n 'tt',\n 'var',\n 'video',\n 'wbr',\n] as const;\n// https://github.com/microsoft/TypeScript/issues/31018\nexport const inlineElements: string[] = [...inlineElementsT];\n\n// @see http://xahlee.info/js/html5_non-closing_tag.html\nexport const selfClosingTags = [\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n];\n\nexport type anyNode =\n | RootNode\n | AttributeNode\n | ElementNode\n | ComponentNode\n | CustomElementNode\n | ExpressionNode\n | TextNode\n | DoctypeNode\n | CommentNode\n | FragmentNode\n | FrontmatterNode;\n\nexport type {\n AttributeNode,\n Node,\n RootNode,\n ElementNode,\n ComponentNode,\n CustomElementNode,\n ExpressionNode,\n TextNode,\n FrontmatterNode,\n DoctypeNode,\n CommentNode,\n FragmentNode,\n} from '@astrojs/compiler/types';\n","import {\n AstPath as AstP,\n doc,\n Doc,\n ParserOptions as ParserOpts,\n util,\n} from 'prettier';\n\nimport {\n anyNode,\n Node,\n RootNode,\n AttributeNode,\n ElementNode,\n ComponentNode,\n CustomElementNode,\n ExpressionNode,\n TextNode,\n FrontmatterNode,\n DoctypeNode,\n CommentNode,\n NodeWithText,\n blockElements,\n // attributeValue,\n BlockElementNode,\n InlineElementNode,\n // MustacheTagNode,\n NodeWithChildren,\n // NodeWithText,\n // TextNode,\n} from './nodes';\n\nimport { createSyncFn } from 'synckit';\nimport { createRequire } from 'module';\nconst require = createRequire(import.meta.url);\n\n// the worker path must be absolute\nconst serialize = createSyncFn(\n require.resolve('../workers/serialize-worker.js')\n);\n\n// import makeSynchronous from 'make-synchronous';\n\ntype ParserOptions = ParserOpts<anyNode>;\ntype AstPath = AstP<anyNode>;\n\n/**\n * HTML attributes that we may safely reformat (trim whitespace, add or remove newlines)\n */\nexport const formattableAttributes: string[] = [\n // None at the moment\n // Prettier HTML does not format attributes at all\n // and to be consistent we leave this array empty for now\n];\n\n// const rootNodeKeys = new Set(['html', 'css', 'module']);\n\n// const isSync = makeSynchronous(async (node: anyNode) => {\n// const dynamicImport = new Function('file', 'return import(file)');\n// const { is } = await dynamicImport('@astrojs/compiler/utils');\n// try {\n// return await is(node);\n// } catch (e) {\n// console.error(e);\n// }\n// });\n\n// export const is = (node: anyNode) => isSync(node);\n\nexport const isRootNode = (node: anyNode): node is RootNode =>\n node.type === 'root';\n\nexport const isEmptyTextNode = (node: Node): boolean => {\n return !!node && node.type === 'text' && getUnencodedText(node).trim() === '';\n};\n\nexport const isPreTagContent = (path: AstPath): boolean => {\n if (!path || !path.stack || !Array.isArray(path.stack)) return false;\n return path.stack.some(\n (node: anyNode) =>\n (node.type === 'element' && node.name.toLowerCase() === 'pre') ||\n (node.type === 'attribute' && !formattableAttributes.includes(node.name))\n );\n};\n\nexport function isLoneMustacheTag(node: AttributeNode): boolean {\n // export function isLoneMustacheTag(node: AttributeNode): node is [MustacheTagNode] {\n return node.kind === 'expression';\n // return node !== true && node.length === 1 && node[0].type === 'MustacheTag';\n}\n\n// function isAttributeShorthand(node: attributeValue): node is [AttributeShorthandNode] {\n// return node !== true && node.length === 1 && node[0].type === 'AttributeShorthand';\n// }\n\n/**\n * True if node is of type `{a}` or `a={a}`\n */\nexport function isOrCanBeConvertedToShorthand(\n node: AttributeNode,\n opts: ParserOptions\n): boolean {\n if (!opts.astroAllowShorthand) return false;\n if (node.kind === 'shorthand') {\n return true;\n }\n // if (isAttributeShorthand(node.value)) {\n // return true;\n // }\n\n if (node.value.trim() === node.name.trim()) {\n return true;\n }\n\n // if (isLoneMustacheTag(node.value)) {\n // const expression = node.value[0].expression;\n // return expression.codeChunks[0].trim() === node.name;\n // // return (expression.type === 'Identifier' && expression.name === node.name) || (expression.type === 'Expression' && expression.codeChunks[0] === node.name);\n // }\n\n return false;\n}\n\n/**\n * True if node is of type `{a}` and astroAllowShorthand is false\n */\nexport function isShorthandAndMustBeConvertedToBinaryExpression(\n node: AttributeNode,\n opts: ParserOptions\n): boolean {\n if (opts.astroAllowShorthand) return false;\n if (node.type === 'attribute' && node.kind === 'shorthand') {\n return true;\n }\n // if (isAttributeShorthand(node.value)) {\n // return true;\n // }\n return false;\n}\n\n// export function flatten<T>(arrays: T[][]): T[] {\n// return ([] as T[]).concat.apply([], arrays);\n// }\n\n// TODO: TEST IF IT'S GETTING THE CORRECT TEXT\nexport function getText(node: anyNode, opts: ParserOptions): string {\n if (!node.position) return '';\n return opts.originalText.slice(\n node.position.start.offset + 1,\n node.position.end?.offset\n );\n // return opts.originalText.slice(opts.locStart(node), opts.locEnd(node));\n}\n\nexport function getUnencodedText(node: NodeWithText): string {\n return node.value;\n}\n\n// export function replaceEndOfLineWith(text: string, replacement: doc.builders.DocCommand): Doc[] {\n// const parts = [];\n// for (const part of text.split('\\n')) {\n// if (parts.length > 0) {\n// parts.push(replacement);\n// }\n// if (part.endsWith('\\r')) {\n// parts.push(part.slice(0, -1));\n// } else {\n// parts.push(part);\n// }\n// }\n// return parts;\n// }\n\n/**\n * Returns the content of the node\n */\nexport function printRaw(\n node: anyNode,\n stripLeadingAndTrailingNewline = false\n): string {\n if (!isNodeWithChildren(node)) {\n return '';\n }\n\n if (node.children.length === 0) {\n return '';\n }\n\n let raw = node.children.reduce(\n (prev: string, curr: Node) => prev + serialize(curr),\n ''\n );\n\n if (!stripLeadingAndTrailingNewline) {\n return raw;\n }\n\n if (startsWithLinebreak(raw)) {\n raw = raw.substring(raw.indexOf('\\n') + 1);\n }\n if (endsWithLinebreak(raw)) {\n raw = raw.substring(0, raw.lastIndexOf('\\n'));\n if (raw.charAt(raw.length - 1) === '\\r') {\n raw = raw.substring(0, raw.length - 1);\n }\n }\n\n return raw;\n}\n\nexport function isNodeWithChildren(\n node: anyNode\n): node is anyNode & NodeWithChildren {\n return node && Array.isArray(node.children);\n}\n\nexport function isInlineElement(\n path: AstPath,\n opts: ParserOptions,\n node: anyNode\n): node is InlineElementNode {\n return (\n node &&\n node.type === 'element' &&\n !isBlockElement(node, opts) &&\n !isPreTagContent(path)\n );\n}\n\nexport function isBlockElement(\n node: anyNode,\n opts: ParserOptions\n): node is BlockElementNode {\n return (\n node &&\n node.type === 'element' &&\n opts.htmlWhitespaceSensitivity !== 'strict' &&\n (opts.htmlWhitespaceSensitivity === 'ignore' ||\n blockElements.includes(node.name))\n );\n}\n\nexport function isTextNodeStartingWithLinebreak(\n node: TextNode,\n nrLines = 1\n): node is TextNode {\n return startsWithLinebreak(getUnencodedText(node), nrLines);\n // return node.type === 'Text' && startsWithLinebreak(getUnencodedText(node), nrLines);\n}\n\nexport function startsWithLinebreak(text: string, nrLines = 1): boolean {\n return new RegExp(`^([\\\\t\\\\f\\\\r ]*\\\\n){${nrLines}}`).test(text);\n}\n\n// export function isTextNodeEndingWithLinebreak(node: TextNode, nrLines: number = 1) {\n// return node.type === 'text' && endsWithLinebreak(getUnencodedText(node), nrLines);\n// }\n\nexport function endsWithLinebreak(text: string, nrLines = 1): boolean {\n return new RegExp(`(\\\\n[\\\\t\\\\f\\\\r ]*){${nrLines}}$`).test(text);\n}\n\nexport function isTextNodeStartingWithWhitespace(node: Node): node is TextNode {\n return node.type === 'text' && /^\\s/.test(getUnencodedText(node));\n}\n\nexport function isTextNodeEndingWithWhitespace(node: Node): node is TextNode {\n return node.type === 'text' && /\\s$/.test(getUnencodedText(node));\n}\n\nexport function forceIntoExpression(statement: string): string {\n // note the trailing newline: if the statement ends in a // comment,\n // we can't add the closing bracket right afterwards\n return `(${statement}\\n)`;\n}\n\n/**\n * Check if given node's starg tag should hug its first child. This is the case for inline elements when there's\n * no whitespace between the `>` and the first child.\n */\nexport function shouldHugStart(node: anyNode, opts: ParserOptions): boolean {\n if (isBlockElement(node, opts)) {\n return false;\n }\n\n if (!isNodeWithChildren(node)) {\n return false;\n }\n\n const children = node.children;\n if (children.length === 0) {\n return true;\n }\n\n const firstChild = children[0];\n return !isTextNodeStartingWithWhitespace(firstChild);\n}\n\n/**\n * Check if given node's end tag should hug its last child. This is the case for inline elements when there's\n * no whitespace between the last child and the `</`.\n */\nexport function shouldHugEnd(node: anyNode, opts: ParserOptions): boolean {\n if (isBlockElement(node, opts)) {\n return false;\n }\n\n if (!isNodeWithChildren(node)) {\n return false;\n }\n\n const children = node.children;\n if (children.length === 0) {\n return true;\n }\n\n return false;\n\n // TODO: WIP\n // const lastChild = children[children.length - 1];\n // return !isTextNodeEndingWithWhitespace(lastChild);\n}\n\n/**\n * Returns true if the softline between `</tagName` and `>` can be omitted.\n */\nexport function canOmitSoftlineBeforeClosingTag(\n path: AstPath,\n opts: ParserOptions\n): boolean {\n return isLastChildWithinParentBlockElement(path, opts);\n // return !hugsStartOfNextNode(node, options) || isLastChildWithinParentBlockElement(path, options);\n // return !options.svelteBracketNewLine && (!hugsStartOfNextNode(node, options) || isLastChildWithinParentBlockElement(path, options));\n}\n\n/**\n * Return true if given node does not hug the next node, meaning there's whitespace\n * or the end of the doc afterwards.\n */\n// function hugsStartOfNextNode(node: anyNode, opts: ParserOptions): boolean {\n// if (node.end === opts.originalText.length) {\n// // end of document\n// return false;\n// }\n\n// return !opts.originalText.substring(node.end).match(/^\\s/);\n// }\n\nfunction getChildren(node: anyNode): Node[] {\n return isNodeWithChildren(node) ? node.children : [];\n}\n\nfunction isLastChildWithinParentBlockElement(\n path: AstPath,\n opts: ParserOptions\n): boolean {\n const parent = path.getParentNode();\n if (!parent || !isBlockElement(parent, opts)) {\n return false;\n }\n\n const children = getChildren(parent);\n const lastChild = children[children.length - 1];\n return lastChild === path.getNode();\n}\n\nexport function trimTextNodeLeft(node: TextNode): void {\n node.value = node.value && node.value.trimStart();\n}\n\nexport function trimTextNodeRight(node: TextNode): void {\n node.value = node.value && node.value.trimEnd();\n}\n\n// export function findLastIndex<T>(isMatch: (item: T, idx: number) => boolean, items: T[]) {\n// for (let i = items.length - 1; i >= 0; i--) {\n// if (isMatch(items[i], i)) {\n// return i;\n// }\n// }\n\n// return -1;\n// }\n\n/**\n * Remove all leading whitespace up until the first non-empty text node,\n * and all trailing whitepsace from the last non-empty text node onwards.\n */\n// export function trimChildren(children: anyNode[]) {\n// // export function trimChildren(children: anyNode[], path: AstPath<anyNode>) {\n// let firstNonEmptyNode = children.findIndex((n) => !isEmptyTextNode(n));\n// // let firstNonEmptyNode = children.findIndex((n) => !isEmptyTextNode(n) && !doesEmbedStartAfterNode(n, path));\n// firstNonEmptyNode = firstNonEmptyNode === -1 ? children.length - 1 : firstNonEmptyNode;\n\n// let lastNonEmptyNode = findLastIndex((n, idx) => {\n// // Last node is ok to end at the start of an embedded region,\n// // if it's not a comment (which should stick to the region)\n// return !isEmptyTextNode(n);\n// // return !isEmptyTextNode(n) && ((idx === children.length - 1 && n.type !== 'Comment') || !doesEmbedStartAfterNode(n, path));\n// }, children);\n// lastNonEmptyNode = lastNonEmptyNode === -1 ? 0 : lastNonEmptyNode;\n\n// for (let i = 0; i <= firstNonEmptyNode; i++) {\n// const n = children[i];\n// if (isTextNode(n)) {\n// trimTextNodeLeft(n);\n// }\n// }\n\n// for (let i = children.length - 1; i >= lastNonEmptyNode; i--) {\n// const n = children[i];\n// if (isTextNode(n)) {\n// trimTextNodeRight(n);\n// }\n// }\n// }\n\n/**\n * Returns siblings, that is, the children of the parent.\n */\n// export function getSiblings(path: AstPath): anyNode[] {\n// let parent = path.getParentNode();\n// if (!parent) return [];\n\n// if (isRootNode(parent)) {\n// parent = parent.html;\n// }\n\n// return getChildren(parent);\n// }\n\n/**\n * Did there use to be any embedded object (that has been snipped out of the AST to be moved)\n * at the specified position?\n */\n// function doesEmbedStartAfterNode(node: anyNode, path: AstPath<anyNode>, siblings = getSiblings(path)): boolean {\n// // If node is not at the top level of html, an embed cannot start after it,\n// // because embeds are only at the top level\n// if (!isNodeTopLevelHTML(node, path)) {\n// return false;\n// }\n\n// const position = node.end;\n// const root = path.stack[0];\n\n// const embeds = [root.module, root.html, root.css];\n\n// const nextNode = siblings[siblings.indexOf(node) + 1];\n// return embeds.find((n) => n && n.start >= position && (!nextNode || n.end <= nextNode.start));\n// }\n\n// function isNodeTopLevelHTML(node: anyNode, path: AstPath<anyNode>) {\n// const root = path.stack[0];\n// return !!root.html && !!root.html.children && root.html.children.includes(node);\n// }\n\n/**\n * Check if doc is a hardline.\n * We can't just rely on a simple equality check because the doc could be created with another\n * runtime version of prettier than what we import, making a reference check fail.\n */\n\n// function isHardline(docToCheck: Doc): boolean {\n// return docToCheck === doc.builders.hardline || deepEqual(docToCheck, doc.builders.hardline);\n// }\n\n/**\n * Simple deep equal function which suits our needs. Only works properly on POJOs without cyclic deps.\n */\n// function deepEqual(x: any, y: any): boolean {\n// if (x === y) {\n// return true;\n// } else if (typeof x == 'object' && x != null && typeof y == 'object' && y != null) {\n// if (Object.keys(x).length != Object.keys(y).length) return false;\n\n// for (var prop in x) {\n// if (Object.prototype.hasOwnProperty.call(y, prop)) {\n// if (!deepEqual(x[prop], y[prop])) return false;\n// } else {\n// return false;\n// }\n// }\n\n// return true;\n// } else {\n// return false;\n// }\n// }\n\n// export function isLine(docToCheck: Doc): boolean {\n// return (\n// isHardline(docToCheck) ||\n// (typeof docToCheck === 'object' && isDocCommand(docToCheck) && docToCheck.type === 'line') ||\n// (typeof docToCheck === 'object' && isDocCommand(docToCheck) && docToCheck.type === 'concat' && docToCheck.parts.every(isLine))\n// );\n// }\n\n/**\n * Check if the doc is empty, i.e. consists of nothing more than empty strings (possibly nested).\n */\n// export function isEmptyDoc(doc: Doc): boolean {\n// if (typeof doc === 'string') {\n// return doc.length === 0;\n// }\n\n// // if (doc.type === 'line') {\n// // return !doc.keepIfLonely;\n// // }\n\n// // Since Prettier 2.3.0, concats are represented as flat arrays\n// if (Array.isArray(doc)) {\n// return doc.length === 0;\n// }\n\n// // const { contents } = doc;\n\n// // if (contents) {\n// // return isEmptyDoc(contents);\n// // }\n\n// // const { parts } = doc;\n\n// // if (parts) {\n// // return isEmptyGroup(parts);\n// // }\n\n// return false;\n// }\n\n// function isEmptyGroup(group: any) {\n// return !group.find((doc: any) => !isEmptyDoc(doc));\n// }\n\n/**\n * Trims both leading and trailing nodes matching `isWhitespace` independent of nesting level\n * (though all trimmed adjacent nodes need to be a the same level). Modifies the `docs` array.\n */\n// export function trim(docs: Doc[], isWhitespace: (doc: Doc) => boolean): Doc[] {\n// trimLeft(docs, isWhitespace);\n// trimRight(docs, isWhitespace);\n\n// return docs;\n// }\n\n/**\n * Trims the leading nodes matching `isWhitespace` independent of nesting level (though all nodes need to be a the same level).\n * If there are empty docs before the first whitespace, they are removed, too.\n */\n// function trimLeft(group: Doc[], isWhitespace: (doc: Doc) => boolean): void {\n// let firstNonWhitespace = group.findIndex((doc) => !isEmptyDoc(doc) && !isWhitespace(doc));\n\n// if (firstNonWhitespace < 0 && group.length) {\n// firstNonWhitespace = group.length;\n// }\n\n// if (firstNonWhitespace > 0) {\n// const removed = group.splice(0, firstNonWhitespace);\n// if (removed.every(isEmptyDoc)) {\n// return trimLeft(group, isWhitespace);\n// }\n// } else {\n// const parts = getParts(group[0]);\n\n// if (parts) {\n// return trimLeft(parts, isWhitespace);\n// }\n// }\n// }\n\n/**\n * Trims the trailing nodes matching `isWhitespace` independent of nesting level (though all nodes need to be a the same level).\n * If there are empty docs after the last whitespace, they are removed, too.\n */\n// function trimRight(group: Doc[], isWhitespace: (doc: Doc) => boolean): void {\n// let lastNonWhitespace = group.length ? findLastIndex((doc: any) => !isEmptyDoc(doc) && !isWhitespace(doc), group) : 0;\n\n// if (lastNonWhitespace < group.length - 1) {\n// const removed = group.splice(lastNonWhitespace + 1);\n// if (removed.every(isEmptyDoc)) {\n// return trimRight(group, isWhitespace);\n// }\n// } else {\n// const parts = getParts(group[group.length - 1]);\n\n// if (parts) {\n// return trimRight(parts, isWhitespace);\n// }\n// }\n// }\n\n// function getParts(doc: Doc): Doc[] | undefined {\n// if (typeof doc === 'object') {\n// // Since Prettier 2.3.0, concats are represented as flat arrays\n// if (Array.isArray(doc)) {\n// return doc;\n// }\n// if (doc.type === 'fill' || doc.type === 'concat') {\n// return doc.parts;\n// }\n// if (doc.type === 'group') {\n// return getParts(doc.contents);\n// }\n// }\n// }\n\n// export const isObjEmpty = (obj: object): boolean => {\n// for (let i in obj) return false;\n// return true;\n// };\n\n/** Shallowly attach comments to children */\n// export function attachCommentsHTML(node: anyNode): void {\n// if (!isNodeWithChildren(node) || !node.children.some(({ type }) => type === 'Comment')) return;\n\n// const nodesToRemove = [];\n\n// // note: the .length - 1 is because we don’t need to read the last node\n// for (let n = 0; n < node.children.length - 1; n++) {\n// if (!node.children[n]) continue;\n\n// // attach comment to the next non-whitespace node\n// if (node.children[n].type === 'Comment') {\n// let next = n + 1;\n// while (isEmptyTextNode(node.children[next])) {\n// nodesToRemove.push(next); // if arbitrary whitespace between comment and node, remove\n// next++; // skip to the next non-whitespace node\n// }\n// const commentNode = node.children[next];\n// if (commentNode) {\n// const comment = node.children[n];\n// util.addLeadingComment(commentNode, comment);\n// }\n// }\n// }\n\n// // remove arbitrary whitespace nodes\n// nodesToRemove.reverse(); // start at back so we aren’t changing indices\n// nodesToRemove.forEach((index) => {\n// node.children.splice(index, 1);\n// });\n// }\n\n// https://github.com/dmnd/dedent/blob/master/dist/dedent.js\nexport function manualDedent(input: string) {\n // first, perform interpolation\n let result = '';\n for (let i = 0; i < input.length; i++) {\n result += input[i]\n // join lines when there is a suppressed newline\n .replace(/\\\\\\n[ \\t]*/g, '')\n // handle escaped backticks\n .replace(/\\\\`/g, '`');\n\n if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {\n // eslint-disable-next-line prefer-rest-params\n result += arguments.length <= i + 1 ? undefined : arguments[i + 1];\n }\n }\n\n // now strip indentation\n const lines = result.split('\\n');\n let mindent: number | null = null;\n lines.forEach(function (l) {\n const m = l.match(/^(\\s+)\\S+/);\n if (m) {\n const indent = m[1].length;\n if (!mindent) {\n // this is the first indented line\n mindent = indent;\n } else {\n mindent = Math.min(mindent, indent);\n }\n }\n });\n\n if (mindent !== null) {\n (function () {\n const m = mindent; // appease Flow\n result = lines\n .map(function (l) {\n return l[0] === ' ' ? l.slice(m) : l;\n })\n .join('\\n');\n })();\n }\n\n return {\n result: result\n // dedent eats leading and trailing whitespace too\n .trim()\n // handle escaped newlines at the end to ensure they don't get stripped too\n .replace(/\\\\n/g, '\\n'),\n };\n}\n\n/** re-indent string by chars */\n// export function indent(input: string, char: string = ' '): string {\n// return input.replace(/^(.)/gm, `${char}$1`);\n// }\n\n/** scan code for Markdown name(s) */\nexport function getMarkdownName(script: string): Set<string> {\n // default import: could be named anything\n let defaultMatch;\n while (\n (defaultMatch =\n /import\\s+([^\\s]+)\\s+from\\s+['|\"|`]astro\\/components\\/Markdown\\.astro/g.exec(\n script\n ))\n ) {\n if (defaultMatch[1]) return new Set([defaultMatch[1].trim()]);\n }\n\n // named component: must have \"Markdown\" in specifier, but can be renamed via \"as\"\n let namedMatch;\n while (\n (namedMatch =\n /import\\s+\\{\\s*([^}]+)\\}\\s+from\\s+['|\"|`]astro\\/components/g.exec(script))\n ) {\n if (namedMatch[1] && !namedMatch[1].includes('Markdown')) continue;\n // if \"Markdown\" was imported, find out whether or not it was renamed\n const rawImports = namedMatch[1]\n .trim()\n .replace(/^\\{/, '')\n .replace(/\\}$/, '')\n .trim();\n let importName = 'Markdown';\n for (const spec of rawImports.split(',')) {\n const [original, renamed] = spec.split(' as ').map((s) => s.trim());\n if (original !== 'Markdown') continue;\n importName = renamed || original;\n break;\n }\n return new Set([importName]);\n }\n return new Set(['Markdown']);\n}\n\n// TODO: USE THE COMPILER\n/** True if the node is of type text */\nexport function isTextNode(node: Node): node is TextNode {\n return node.type === 'text';\n}\n\n// export function isMustacheNode(node: anyNode): node is MustacheTagNode {\n// return node.type === 'MustacheTag';\n// }\n\n// export function isDocCommand(doc: Doc): doc is doc.builders.DocCommand {\n// if (typeof doc === 'string') return false;\n// if (Array.isArray(doc)) return false;\n// return true;\n// }\n\nexport function isInsideQuotedAttribute(path: AstPath): boolean {\n const stack = path.stack as anyNode[];\n return stack.some(\n (node) => node.type === 'attribute' && !isLoneMustacheTag(node)\n );\n}\n","import {\n AstPath as AstP,\n BuiltInParsers,\n Doc,\n ParserOptions as ParserOpts,\n Printer,\n} from 'prettier';\nimport _doc from 'prettier/doc';\nconst {\n builders: {\n breakParent,\n dedent,\n fill,\n group,\n hardline,\n indent,\n join,\n line,\n literalline,\n softline,\n },\n utils: { removeLines, stripTrailingHardline },\n} = _doc;\nimport { SassFormatter, SassFormatterConfig } from 'sass-formatter';\n\nimport { parseSortOrder } from './options';\n\nimport {\n RootNode,\n Node,\n AttributeNode,\n CommentNode,\n NodeWithText,\n selfClosingTags,\n TextNode,\n anyNode,\n} from './nodes';\n\ntype ParserOptions = ParserOpts<anyNode>;\ntype AstPath = AstP<anyNode>;\n\nimport {\n // attachCommentsHTML,\n canOmitSoftlineBeforeClosingTag,\n manualDedent,\n endsWithLinebreak,\n forceIntoExpression,\n formattableAttributes,\n getMarkdownName,\n getText,\n getUnencodedText,\n isRootNode,\n // isDocCommand,\n // isEmptyDoc,\n isEmptyTextNode,\n isInlineElement,\n isInsideQuotedAttribute,\n // isLine,\n isLoneMustacheTag,\n // isNodeWithChildren,\n isOrCanBeConvertedToShorthand,\n isPreTagContent,\n isShorthandAndMustBeConvertedToBinaryExpression,\n isTextNode,\n isTextNodeEndingWithWhitespace,\n isTextNodeStartingWithLinebreak,\n isTextNodeStartingWithWhitespace,\n printRaw,\n // replaceEndOfLineWith,\n shouldHugEnd,\n shouldHugStart,\n startsWithLinebreak,\n // trim,\n // trimChildren,\n trimTextNodeLeft,\n trimTextNodeRight,\n} from './utils';\n\n// function printTopLevelParts(node: RootNode, path: AstPath, opts: ParserOptions, print: printFn): Doc {\n// let docs = [];\n\n// const normalize = (doc: Doc) => [stripTrailingHardline(doc), hardline];\n\n// // frontmatter always comes first\n// if (node.module) {\n// const subDoc = normalize(path.call(print, 'module'));\n// docs.push(subDoc);\n// }\n\n// // markup and styles follow, whichever the user prefers (default: markup, styles)\n// for (const section of parseSortOrder(opts.astroSortOrder)) {\n// switch (section) {\n// case 'markup': {\n// const subDoc = path.call(print, 'html');\n// if (!isEmptyDoc(subDoc)) docs.push(normalize(subDoc));\n// break;\n// }\n// case 'styles': {\n// const subDoc = path.call(print, 'css');\n// if (!isEmptyDoc(subDoc)) docs.push(normalize(subDoc));\n// break;\n// }\n// }\n// }\n\n// return join(softline, docs);\n// }\n\n// function printAttributeNodeValue(path: AstPath, print: printFn, quotes: boolean, node: AttributeNode): Doc[] | _doc.builders.Indent {\n// const valueDocs = path.map((childPath) => childPath.call(print), 'value');\n\n// if (!quotes || !formattableAttributes.includes(node.name)) {\n// return valueDocs;\n// } else {\n// return indent(group(trim(valueDocs, isLine)));\n// }\n// }\n\n// TODO: USE ASTPATH GENERIC\n// function printJS(path: AstP, print: printFn, name: string, { forceSingleQuote, forceSingleLine }: { forceSingleQuote: boolean; forceSingleLine: boolean }) {\n// path.getValue()[name].isJS = true;\n// path.getValue()[name].forceSingleQuote = forceSingleQuote;\n// path.getValue()[name].forceSingleLine = forceSingleLine;\n// return path.call(print, name);\n// }\n\n// TODO: MAYBE USE THIS TO HANDLE COMMENTS\nfunction printComment(commentPath: AstPath, options: ParserOptions): Doc {\n // note(drew): this isn’t doing anything currently, but Prettier requires it anyway\n // @ts-ignore\n return commentPath;\n}\n\nexport type printFn = (path: AstPath) => Doc;\n\n// eslint-disable-next-line @typescript-eslint/no-shadow\nfunction print(path: AstPath, opts: ParserOptions, print: printFn): Doc {\n const node = path.getValue();\n // const isMarkdownSubDoc = opts.parentParser === 'markdown'; // is this a code block within .md?\n\n // 1. handle special node types\n if (!node) {\n return '';\n }\n\n if (typeof node === 'string') {\n return node;\n }\n\n // if (Array.isArray(node)) {\n // return path.map((childPath) => childPath.call(print));\n // }\n\n // if (isASTNode(node)) {\n // return printTopLevelParts(node, path, opts, print);\n // }\n\n // 2. attach comments shallowly to children, if any (https://prettier.io/docs/en/plugins.html#manually-attaching-a-comment)\n // if (!isPreTagContent(path) && !isMarkdownSubDoc && node.type === 'Fragment') {\n // attachCommentsHTML(node);\n // }\n\n // 3. handle printing\n switch (node.type) {\n case 'root': {\n return [stripTrailingHardline(path.map(print, 'children')), hardline];\n }\n\n // case 'Fragment': {\n // const text = getText(node, opts);\n // if (text.length === 0) {\n // return '';\n // }\n\n // if (!isNodeWithChildren(node) || node.children.every(isEmptyTextNode)) return '';\n\n // if (!isPreTagContent(path)) {\n // trimChildren(node.children);\n // const output = trim(\n // [path.map(print, 'children')],\n // (n) =>\n // isLine(n) ||\n // (typeof n === 'string' && n.trim() === '') ||\n // // Because printChildren may append this at the end and\n // // may hide other lines before it\n // n === breakParent\n // );\n // if (output.every((doc) => isEmptyDoc(doc))) {\n // return '';\n // }\n // return group([...output, hardline]);\n // } else {\n // return group(path.map(print, 'children'));\n // }\n // }\n case 'text': {\n const rawText = getUnencodedText(node);\n\n // TODO: TEST PRE TAGS\n // if (isPreTagContent(path)) {\n // if (path.getParentNode()?.type === 'Attribute') {\n // // Direct child of attribute value -> add literallines at end of lines\n // // so that other things don't break in unexpected places\n // return replaceEndOfLineWith(rawText, literalline);\n // }\n // return rawText;\n // }\n\n if (isEmptyTextNode(node)) {\n const hasWhiteSpace =\n rawText.trim().length < getUnencodedText(node).length;\n const hasOneOrMoreNewlines = /\\n/.test(getUnencodedText(node));\n const hasTwoOrMoreNewlines = /\\n\\r?\\s*\\n\\r?/.test(\n getUnencodedText(node)\n );\n if (hasTwoOrMoreNewlines) {\n return [hardline, hardline];\n }\n if (hasOneOrMoreNewlines) {\n return hardline;\n }\n if (hasWhiteSpace) {\n return line;\n }\n return '';\n }\n\n /**\n * For non-empty text nodes each sequence of non-whitespace characters (effectively,\n * each \"word\") is joined by a single `line`, which will be rendered as a single space\n * until this node's current line is out of room, at which `fill` will break at the\n * most convenient instance of `line`.\n */\n return fill(splitTextToDocs(node));\n }\n\n // case 'InlineComponent':\n // case 'Slot':\n case 'component':\n case 'fragment':\n case 'element': {\n // const isEmpty = node.children?.every((child) => isEmptyTextNode(child));\n let isEmpty: boolean;\n if (!node.children) {\n isEmpty = true;\n } else {\n isEmpty = node.children.every((child) => isEmptyTextNode(child));\n }\n const isSelfClosingTag =\n isEmpty &&\n (node.type !== 'element' || selfClosingTags.indexOf(node.name) !== -1);\n\n const attributes = path.map(print, 'attributes');\n if (isSelfClosingTag) {\n return group(['<', node.name, indent(group(attributes)), line, `/>`]);\n // return group(['<', node.name, indent(group([...attributes, opts.jsxBracketNewLine ? dedent(line) : ''])), ...[opts.jsxBracketNewLine ? '' : ' ', `/>`]]);\n }\n\n if (node.children) {\n const children = node.children;\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n\n // No hugging of content means it's either a block element and/or there's whitespace at the start/end\n let noHugSeparatorStart:\n | _doc.builders.Concat\n | _doc.builders.Line\n | _doc.builders.Softline\n | string = softline;\n let noHugSeparatorEnd:\n | _doc.builders.Concat\n | _doc.builders.Line\n | _doc.builders.Softline\n | string = softline;\n const hugStart = shouldHugStart(node, opts);\n const hugEnd = shouldHugEnd(node, opts);\n\n let body;\n\n if (isEmpty) {\n body =\n isInlineElement(path, opts, node) &&\n node.children.length &&\n isTextNodeStartingWithWhitespace(node.children[0]) &&\n !isPreTagContent(path)\n ? () => line\n : // () => (opts.jsxBracketNewLine ? '' : softline);\n () => softline;\n } else if (isPreTagContent(path)) {\n body = () => printRaw(node);\n } else if (\n isInlineElement(path, opts, node) &&\n !isPreTagContent(path)\n ) {\n body = () => path.map(print, 'children');\n } else {\n body = () => path.map(print, 'children');\n }\n\n const openingTag = [\n '<',\n node.name,\n indent(\n group([\n ...attributes,\n hugStart\n ? ''\n : !isPreTagContent(path) && !opts.bracketSameLine\n ? dedent(softline)\n : '',\n ])\n ),\n ];\n // const openingTag = ['<', node.name, indent(group([...attributes, hugStart ? '' : opts.jsxBracketNewLine && !isPreTagContent(path) ? dedent(softline) : '']))];\n\n if (hugStart && hugEnd) {\n const huggedContent = [\n softline,\n group(['>', body(), `</${node.name}`]),\n ];\n\n const omitSoftlineBeforeClosingTag =\n isEmpty || canOmitSoftlineBeforeClosingTag(path, opts);\n // const omitSoftlineBeforeClosingTag = (isEmpty && opts.jsxBracketNewLine) || canOmitSoftlineBeforeClosingTag(node, path, opts);\n return group([\n ...openingTag,\n isEmpty ? group(huggedContent) : group(indent(huggedContent)),\n omitSoftlineBeforeClosingTag ? '' : softline,\n '>',\n ]);\n }\n\n if (isPreTagContent(path)) {\n noHugSeparatorStart = '';\n noHugSeparatorEnd = '';\n } else {\n let didSetEndSeparator = false;\n\n if (!hugStart && firstChild && isTextNode(firstChild)) {\n if (\n isTextNodeStartingWithLinebreak(firstChild) &&\n firstChild !== lastChild &&\n (!isInlineElement(path, opts, node) ||\n isTextNodeEndingWithWhitespace(lastChild))\n ) {\n noHugSeparatorStart = hardline;\n noHugSeparatorEnd = hardline;\n didSetEndSeparator = true;\n } else if (isInlineElement(path, opts, node)) {\n noHugSeparatorStart = line;\n }\n trimTextNodeLeft(firstChild);\n }\n if (!hugEnd && lastChild && isTextNode(lastChild)) {\n if (isInlineElement(path, opts, node) && !didSetEndSeparator) {\n noHugSeparatorEnd = softline;\n }\n trimTextNodeRight(lastChild);\n }\n }\n\n if (hugStart) {\n return group([\n ...openingTag,\n indent([softline, group(['>', body()])]),\n noHugSeparatorEnd,\n `</${node.name}>`,\n ]);\n }\n\n if (hugEnd) {\n return group([\n ...openingTag,\n '>',\n indent([noHugSeparatorStart, group([body(), `</${node.name}`])]),\n canOmitSoftlineBeforeClosingTag(path, opts) ? '' : softline,\n '>',\n ]);\n }\n\n if (isEmpty) {\n return group([...openingTag, '>', body(), `</${node.name}>`]);\n }\n\n return group([\n ...openingTag,\n '>',\n indent([noHugSeparatorStart, body()]),\n noHugSeparatorEnd,\n `</${node.name}>`,\n ]);\n }\n // TODO: WIP\n return '';\n }\n // case 'AttributeShorthand': {\n // return node.expression.name;\n // }\n case 'attribute': {\n const name = node.name.trim();\n const quote = opts.singleQuote ? \"'\" : '\"';\n switch (node.kind) {\n case 'empty':\n return [line, name];\n case 'expression':\n // HANDLED IN EMBED FUNCION\n return '';\n case 'quoted':\n return [line, name, '=', quote, node.value, quote];\n case 'shorthand':\n return [line, '{', name, '}'];\n case 'spread':\n return [line, '{...', name, '}'];\n case 'template-literal':\n return [line, name, '=', '`', node.value, '`'];\n default:\n break;\n }\n return '';\n }\n\n case 'doctype': {\n // https://www.w3.org/wiki/Doctypes_and_markup_styles\n return ['<!DOCTYPE html>', hardline];\n }\n // case 'Expression':\n // // missing test ?\n // return [];\n // case 'MustacheTag':\n // return [\n // '{',\n // printJS(path, print, 'expression', {\n // forceSingleLine: isInsideQuotedAttribute(path),\n // forceSingleQuote: opts.jsxSingleQuote,\n // }),\n // '}',\n // ];\n // case 'Spread':\n // return [\n // line,\n // '{...',\n // printJS(path, print, 'expression', {\n // forceSingleQuote: true,\n // forceSingleLine: false,\n // }),\n // '}',\n // ];\n case 'comment':\n return ['<!--', getUnencodedText(node), '-->'];\n // case 'CodeSpan':\n // return getUnencodedText(node);\n // case 'CodeFence': {\n // console.debug(node);\n // // const lang = node.metadata.slice(3);\n // return [node.metadata, hardline, /** somehow call textToDoc(lang), */ node.data, hardline, '```', hardline];\n\n // // We should use `node.metadata` to select a parser to embed with... something like return [node.metadata, hardline textToDoc(node.getMetadataLanguage()), hardline, `\\`\\`\\``];\n // }\n default: {\n throw new Error(`Unhandled node type \"${node.type}\"!`);\n }\n }\n}\n\n/**\n * Split the text into words separated by whitespace. Replace the whitespaces by lines,\n * collapsing multiple whitespaces into a single line.\n *\n * If the text starts or ends with multiple newlines, two of those should be kept.\n */\nfunction splitTextToDocs(node: NodeWithText): Doc[] {\n const text = getUnencodedText(node);\n\n const textLines = text.split(/[\\t\\n\\f\\r ]+/);\n\n let docs = join(line, textLines).parts.filter((s) => s !== '');\n\n if (startsWithLinebreak(text)) {\n docs[0] = hardline;\n }\n if (startsWithLinebreak(text, 2)) {\n docs = [hardline, ...docs];\n }\n\n if (endsWithLinebreak(text)) {\n docs[docs.length - 1] = hardline;\n }\n if (endsWithLinebreak(text, 2)) {\n docs = [...docs, hardline];\n }\n\n return docs;\n}\n\nfunction expressionParser(\n text: string,\n parsers: BuiltInParsers,\n opts: ParserOptions\n) {\n const ast = parsers.babel(text, opts);\n // const ast = parsers.babel(text, parsers, opts);\n\n return { ...ast, program: ast.program.body[0].expression };\n}\n\nlet markdownComponentName = new Set();\n\nfunction embed(\n path: AstPath,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n print: printFn,\n textToDoc: (text: string, options: object) => Doc,\n opts: ParserOptions\n) {\n // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // @ts-ignore\n if (!opts.__astro) opts.__astro = {};\n\n const node = path.getValue();\n\n if (!node) return null;\n\n if (node.type === 'expression') {\n const textContent = printRaw(node);\n\n let content: Doc;\n\n content = textToDoc(forceIntoExpression(textContent), {\n ...opts,\n parser: expressionParser,\n semi: false,\n });\n content = stripTrailingHardline(content);\n\n // if (node.children[0].value) {\n // content = textToDoc(forceIntoExpression(textContent), { parser: expressionParser });\n // } else {\n // content = textToDoc(forceIntoExpression(node.children[0].value), { parser: expressionParser });\n // }\n return [\n '{',\n // printJS(path, print, 'expression', {\n // forceSingleLine: isInsideQuotedAttribute(path),\n // forceSingleQuote: opts.jsxSingleQuote,\n // }),\n content,\n '}',\n ];\n }\n\n // ATTRIBUTE WITH EXPRESSION AS VALUE\n if (node.type === 'attribute' && node.kind === 'expression') {\n const value = node.value.trim();\n const name = node.name.trim();\n let attrNodeValue = textToDoc(forceIntoExpression(value), {\n ...opts,\n parser: expressionParser,\n semi: false,\n });\n attrNodeValue = stripTrailingHardline(attrNodeValue);\n // if (Array.isArray(attrNodeValue) && attrNodeValue[0] === ';') {\n // attrNodeValue = attrNodeValue.slice(1);\n // }\n if (name === value && opts.astroAllowShorthand) {\n return [line, '{', attrNodeValue, '}'];\n }\n return [line, name, '=', '{', attrNodeValue, '}'];\n }\n\n // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // @ts-ignore\n // if (node.isJS) {\n // try {\n // const embeddedopts = {\n // parser: expressionParser,\n // };\n // // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // // @ts-ignore\n // if (node.forceSingleQuote) {\n // // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // // @ts-ignore\n // embeddedopts.singleQuote = true;\n // }\n\n // const docs = textToDoc(forceIntoExpression(getText(node, opts)), embeddedopts);\n // // TODO: ADD TYPES OR FIND ANOTHER WAY TO ACHIVE THIS\n // // @ts-ignore\n // return node.forceSingleLine ? removeLines(docs) : docs;\n // } catch (e) {\n // return getText(node, opts);\n // }\n // }\n\n if (node.type === 'frontmatter') {\n markdownComponentName = getMarkdownName(node.value);\n return [\n group([\n '---',\n hardline,\n textToDoc(node.value, { ...opts, parser: 'typescript' }),\n '---',\n hardline,\n ]),\n hardline,\n ];\n }\n\n // format script element\n if (node.type === 'element' && node.name === 'script') {\n const scriptContent = node.children[0].value;\n let formatttedScript = textToDoc(scriptContent, {\n ...opts,\n parser: 'typescript',\n });\n formatttedScript = stripTrailingHardline(formatttedScript);\n\n // print\n const attributes = path.map(print, 'attributes');\n const openingTag = group([\n '<script',\n indent(group(attributes)),\n softline,\n '>',\n ]);\n return [\n openingTag,\n indent([hardline, formatttedScript]),\n hardline,\n '</script>',\n ];\n }\n // if (isTextNode(node)) {\n // const parent = path.getParentNode();\n\n // if (parent && parent.type === 'Element' && parent.name === 'script') {\n // const formatttedScript = textToDoc(node.data, { ...opts, parser: 'typescript' });\n // return stripTrailingHardline(formatttedScript);\n // }\n // }\n\n // format style element\n if (node.type === 'element' && node.name === 'style') {\n const styleTagContent = node.children[0].value.trim();\n\n const supportedStyleLangValues = ['css', 'scss', 'sass'];\n let parserLang = 'css';\n\n if (node.attributes) {\n const langAttribute = node.attributes.filter((x) => x.name === 'lang');\n if (langAttribute.length) {\n const styleLang = langAttribute[0].value.toLowerCase();\n if (supportedStyleLangValues.includes(styleLang))\n parserLang = styleLang;\n }\n }\n\n switch (parserLang) {\n case 'css':\n case 'scss': {\n // the css parser appends an extra indented hardline, which we want outside of the `indent()`,\n // so we remove the last element of the array\n let formattedStyles = textToDoc(styleTagContent, {\n ...opts,\n parser: parserLang,\n });\n\n formattedStyles = stripTrailingHardline(formattedStyles);\n\n // print\n const attributes = path.map(print, 'attributes');\n const openingTag = group([\n '<style',\n indent(group(attributes)),\n softline,\n '>',\n ]);\n return [\n openingTag,\n indent([hardline, formattedStyles]),\n hardline,\n '</style>',\n ];\n }\n case 'sass': {\n const lineEnding =\n opts.endOfLine.toUpperCase() === 'CRLF' ? 'CRLF' : 'LF';\n const sassOptions: Partial<SassFormatterConfig> = {\n tabSize: opts.tabWidth,\n insertSpaces: !opts.useTabs,\n lineEnding,\n };\n\n // dedent the .sass, otherwise SassFormatter gets indentation wrong\n const { result: raw } = manualDedent(styleTagContent);\n\n // format\n const formattedSassIndented = SassFormatter.Format(\n raw,\n sassOptions\n ).trim();\n\n // print\n const formattedSass = join(hardline, formattedSassIndented.split('\\n'));\n const attributes = path.map(print, 'attributes');\n const openingTag = group([\n '<style',\n indent(group(attributes)),\n softline,\n '>',\n ]);\n return [\n openingTag,\n indent(group([hardline, formattedSass])),\n hardline,\n '</style>',\n ];\n }\n }\n }\n\n // MARKDOWN COMPONENT\n if (node.type === 'component' && markdownComponentName.has(node.name)) {\n let content = printRaw(node);\n\n // dedent the content\n content = content.replace(/\\r\\n/g, '\\n');\n const contentArr = content.split('\\n').map((s) => s.trimStart());\n content = contentArr.join('\\n');\n\n // format\n let formatttedMarkdown = textToDoc(content, {\n ...opts,\n parser: 'markdown',\n });\n formatttedMarkdown = stripTrailingHardline(formatttedMarkdown);\n\n // return formatttedMarkdown;\n const attributes = path.map(print, 'attributes');\n const openingTag = group([\n `<${node.name}`,\n indent(group(attributes)),\n softline,\n '>',\n ]);\n return [\n openingTag,\n indent(group([hardline, formatttedMarkdown])),\n hardline,\n `</${node.name}>`,\n ];\n }\n\n return null;\n}\n\nfunction hasPrettierIgnore(path: AstP<CommentNode>) {\n // const node = path.getNode();\n\n // if (!node || !Array.isArray(node.comments)) return false;\n\n // const hasIgnore = node.comments.some(\n // (comment: any) => comment.data.includes('prettier-ignore') && !comment.data.includes('prettier-ignore-start') && !comment.data.includes('prettier-ignore-end')\n // );\n // return hasIgnore;\n return false;\n}\n\nconst printer: Printer = {\n print,\n printComment,\n embed,\n hasPrettierIgnore,\n};\n\nexport default printer;\n","import { SupportOption } from 'prettier';\n\ndeclare module 'prettier' {\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\n interface RequiredOptions extends PluginOptions {}\n}\n\nexport interface PluginOptions {\n astroSortOrder: SortOrder;\n astroAllowShorthand: boolean;\n}\n\nexport const options: Record<keyof PluginOptions, SupportOption> = {\n astroSortOrder: {\n since: '0.0.1',\n category: 'Astro',\n type: 'choice',\n default: 'markup | styles',\n description: 'Sort order for markup, scripts, and styles',\n choices: [\n {\n value: 'markup | styles',\n description: 'markup | styles',\n },\n {\n value: 'styles | markup',\n description: 'styles | markup',\n },\n ],\n },\n astroAllowShorthand: {\n since: '0.0.10',\n category: 'Astro',\n type: 'boolean',\n default: false,\n description:\n 'Enable/disable attribute shorthand if attribute name and expression are the same',\n },\n};\n\nexport const parseSortOrder = (sortOrder: SortOrder): SortOrderPart[] =>\n sortOrder.split(' | ') as SortOrderPart[];\n\nexport type SortOrder = 'markup | styles' | 'styles | markup';\n\nexport type SortOrderPart = 'markup' | 'styles';\n","import printer from './printer';\nimport { options } from './options';\nimport { Parser, Printer, SupportLanguage } from 'prettier';\nimport { createSyncFn } from 'synckit';\nimport { createRequire } from 'module';\nconst require = createRequire(import.meta.url);\n\n// the worker path must be absolute\nconst parse = createSyncFn(require.resolve('../workers/parse-worker.js'));\n\n// do whatever you want, you will get the result synchronously!\n\nexport const languages: Partial<SupportLanguage>[] = [\n {\n name: 'astro',\n parsers: ['astro'],\n extensions: ['.astro'],\n vscodeLanguageIds: ['astro'],\n },\n];\n\nexport const parsers: Record<string, Parser> = {\n astro: {\n parse: (source) => parse(source),\n astFormat: 'astro',\n locStart: (node) => node.start,\n locEnd: (node) => node.end,\n },\n};\n\nexport const printers: Record<string, Printer> = {\n astro: printer,\n};\n\nconst defaultOptions = {\n tabWidth: 2,\n};\n\nexport { options, defaultOptions };\n"],"names":["require","createRequire","createSyncFn","_doc","SassFormatter"],"mappings":"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"}
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "prettier-plugin-astro",
3
- "version": "0.1.0-next.1",
3
+ "version": "0.1.0-next.4",
4
4
  "type": "commonjs",
5
5
  "description": "A Prettier Plugin for formatting Astro files",
6
6
  "main": "dist/index.js",
7
7
  "files": [
8
- "dist/**"
8
+ "dist/**",
9
+ "workers/*"
9
10
  ],
10
11
  "engines": {
11
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0",
12
+ "node": "^14.13.1 || >=16.0.0",
12
13
  "npm": ">=6.14.0"
13
14
  },
14
15
  "homepage": "https://github.com/snowpackjs/prettier-plugin-astro/",
@@ -29,33 +30,36 @@
29
30
  "scripts": {
30
31
  "build": "rollup -c",
31
32
  "dev": "rollup -c -w",
32
- "test": "ava test/*.test.ts",
33
- "test:w": "ava -w test/*.test.ts",
33
+ "test": "vitest run",
34
+ "test:w": "vitest",
34
35
  "release": "yarn build && changeset publish",
35
36
  "lint": "eslint .",
36
37
  "fix": "yarn lint --fix",
37
38
  "format": "prettier -w ."
38
39
  },
39
40
  "dependencies": {
40
- "@astrojs/compiler": "^0.12.1",
41
- "make-synchronous": "0.1.1",
41
+ "@astrojs/compiler": "^0.13.1",
42
42
  "prettier": "^2.4.1",
43
- "sass-formatter": "^0.7.2"
43
+ "sass-formatter": "^0.7.2",
44
+ "synckit": "^0.6.2"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@changesets/cli": "^2.16.0",
47
48
  "@rollup/plugin-commonjs": "^21.0.0",
48
49
  "@rollup/plugin-node-resolve": "^13.0.5",
49
50
  "@types/prettier": "^2.4.1",
50
- "ava": "4.0.1",
51
+ "@typescript-eslint/eslint-plugin": "^5.16.0",
52
+ "@typescript-eslint/parser": "^5.16.0",
53
+ "@vitest/ui": "^0.7.7",
51
54
  "eslint": "^8.0.0",
52
- "eslint-plugin-ava": "^13.0.0",
53
- "eslint-plugin-node": "^11.1.0",
55
+ "eslint-config-prettier": "^8.5.0",
56
+ "eslint-plugin-prettier": "^4.0.0",
54
57
  "eslint-plugin-prettier-doc": "^1.0.1",
55
58
  "rollup": "^2.58.0",
56
59
  "rollup-plugin-typescript": "^1.0.1",
57
60
  "ts-node": "^10.2.1",
58
61
  "tslib": "^2.3.1",
59
- "typescript": "^4.4.3"
62
+ "typescript": "^4.4.3",
63
+ "vitest": "^0.7.7"
60
64
  }
61
65
  }
@@ -0,0 +1,8 @@
1
+ const { runAsWorker } = require('synckit');
2
+
3
+ runAsWorker(async (source) => {
4
+ const dynamicImport = new Function('file', 'return import(file)');
5
+ const { parse } = await dynamicImport('@astrojs/compiler');
6
+ const { ast } = await parse(source);
7
+ return ast;
8
+ });
@@ -0,0 +1,7 @@
1
+ const { runAsWorker } = require('synckit');
2
+
3
+ runAsWorker(async (node) => {
4
+ const dynamicImport = new Function('file', 'return import(file)');
5
+ const { serialize } = await dynamicImport('@astrojs/compiler/utils');
6
+ return await serialize(node);
7
+ });