Skip to content

Commit

Permalink
feat(embed): Add support for formatting JSON, Markdown etc script tags (
Browse files Browse the repository at this point in the history
#342)

* feat(embed): Add support for formatting JSON, Markdown etc script tags

* chore: changeset
  • Loading branch information
Princesseuh committed May 18, 2023
1 parent ba2b0d4 commit d2a2c26
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/great-peaches-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'prettier-plugin-astro': minor
---

Add support for formatting script tags containing JSON, Markdown and other content
12 changes: 10 additions & 2 deletions src/printer/embed.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Buffer } from 'node:buffer';
import { BuiltInParsers, Doc, ParserOptions } from 'prettier';
import { BuiltInParsers, Doc, ParserOptions, type BuiltInParserName } from 'prettier';
import _doc from 'prettier/doc';
import { SassFormatter, SassFormatterConfig } from 'sass-formatter';
import { AttributeNode, ExpressionNode, FragmentNode, Node } from './nodes';
Expand All @@ -8,6 +8,7 @@ import {
atSignReplace,
closingBracketReplace,
dotReplace,
inferParserByTypeAttribute,
isNodeWithChildren,
isTagLikeNode,
isTextNode,
Expand Down Expand Up @@ -115,10 +116,17 @@ export function embed(

// Script tags
if (node.type === 'element' && node.name === 'script') {
const typeAttribute = node.attributes.find((attr) => attr.name === 'type')?.value;

let parser: BuiltInParserName = 'babel-ts';
if (typeAttribute) {
parser = inferParserByTypeAttribute(typeAttribute);
}

const scriptContent = printRaw(node);
let formattedScript = wrapParserTryCatch(textToDoc, scriptContent, {
...opts,
parser: 'typescript',
parser: parser,
});

formattedScript = stripTrailingHardline(formattedScript);
Expand Down
39 changes: 36 additions & 3 deletions src/printer/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { createRequire } from 'node:module';
import { AstPath as AstP, Doc, ParserOptions as ParserOpts } from 'prettier';
import { AstPath as AstP, BuiltInParserName, Doc, ParserOptions as ParserOpts } from 'prettier';
import { createSyncFn } from 'synckit';
import { blockElements, formattableAttributes, TagName } from './elements';
import { TagName, blockElements, formattableAttributes } from './elements';
import {
anyNode,
CommentNode,
ExpressionNode,
Node,
ParentLikeNode,
TagLikeNode,
TextNode,
anyNode,
} from './nodes';

export type printFn = (path: AstPath) => Doc;
Expand Down Expand Up @@ -329,3 +329,36 @@ export function getPreferredQuote(rawContent: string, preferredQuote: string): Q

return result;
}

// Adapted from: https://github.com/prettier/prettier/blob/20ab6d6f1c5bd774621230b493a3b71d39383a2c/src/language-html/utils/index.js#LL336C1-L369C2
export function inferParserByTypeAttribute(type: string): BuiltInParserName {
if (!type) {
return 'babel-ts';
}

switch (type) {
case 'module':
case 'text/javascript':
case 'text/babel':
case 'application/javascript':
return 'babel';

case 'application/x-typescript':
return 'babel-ts';

case 'text/markdown':
return 'markdown';

case 'text/html':
return 'html';

case 'text/x-handlebars-template':
return 'glimmer';

default:
if (type.endsWith('json') || type.endsWith('importmap') || type === 'speculationrules') {
return 'json';
}
return 'babel-ts';
}
}
8 changes: 8 additions & 0 deletions test/fixtures/other/script-types/input.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react",
"react-dom": "https://esm.sh/react-dom"
}
}
</script>
8 changes: 8 additions & 0 deletions test/fixtures/other/script-types/output.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react",
"react-dom": "https://esm.sh/react-dom"
}
}
</script>
2 changes: 2 additions & 0 deletions test/tests/other.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ test('Autocloses open tags.', files, 'other/autocloses-open-tags');

test('Can format an Astro file with a script tag inside it', files, 'other/with-script');

test('Can format an Astro file with scripts in different languages', files, 'other/script-types');

test(
'Can format an Astro file with a HTML style prettier ignore comment: https://prettier.io/docs/en/ignore.html',
files,
Expand Down

0 comments on commit d2a2c26

Please sign in to comment.