Repository: sveltejs/prettier-plugin-svelte (ts)

Issue:
SyntaxError: Unexpected token svelte:head script
To reproduce try to format this snippet in any svelte file
```svelte
<svelte:head>
  <script>
    {
      "@context": "https://schema.org",
    }
  </script>
</svelte:head>
```

<img width="1057" alt="image" src="https://user-images.githubusercontent.com/49815452/173133117-19366f8e-0d27-492c-8b82-9c7fa4485076.png">

@html nested style content is being replaced with ✂prettier:content✂ + ignore not working

Hello there! I'm trying to use the `@html` template syntax to server render styles in my svelte-kit application. I have prettier auto-fix configured on save.

**My code block is as follows:**
```
<script lang="ts">
	import { getCssText } from '@stitches/core';
</script>

<svelte:head>
	{@html `<style>${getCssText()}</style>`}
	<meta name="google-site-verification" content="" />
</svelte:head>

<slot />
```

When I save the file, my code block, the code inside of `svelte:head` is altered to the following:
```
<svelte:head>
	{@html `<style ✂prettier:content✂="JHtnZXRDc3NUZXh0KCl9"></style>`}
	<meta name="google-site-verification" content="" />
</svelte:head>
``` 
The above issue seems to be the same as #240 


I have attempted to use a prettier ignore to bypass this issue temporarily, but nothing I am trying is working and the file is still being autoformatted on save. This issue seems to be the same as #59 

**I've tried the following:**
```
<svelte:head>
        <!-- prettier-ignore -->
	{@html `<style>${getCssText()}</style>`}
	<meta name="google-site-verification" content="" />
</svelte:head>
```

```
<!-- prettier-ignore -->
<svelte:head>
	{@html `<style>${getCssText()}</style>`}
	<meta name="google-site-verification" content="" />
</svelte:head>
```



**My prettier & svelte dependencies with Node 16.13.2**
```
"prettier": "^2.6.2",
"prettier-plugin-svelte": "^2.7.0",
"svelte": "^3.47.0",
```

Any insight would be much appreciated :)

Pull request description:
[fix] check for snipped content in JS expressions
Check for snipped content in JS expressions
Fixes #290 

Patch:
diff --git a/src/embed.ts b/src/embed.ts
index 565c29e..fca38e3 100644
--- a/src/embed.ts
+++ b/src/embed.ts
@@ -36,7 +36,14 @@ export function embed(
                 embeddedOptions.singleQuote = true;
             }
 
-            let docs = textToDoc(forceIntoExpression(getText(node, options)), embeddedOptions);
+            let docs = textToDoc(
+                forceIntoExpression(
+                    // If we have snipped content, it was done wrongly and we need to unsnip it.
+                    // This happens for example for {@html `<script>{foo}</script>`}
+                    getText(node, options, true),
+                ),
+                embeddedOptions,
+            );
             if (node.forceSingleLine) {
                 docs = removeLines(docs);
             }
@@ -45,7 +52,7 @@ export function embed(
             }
             return docs;
         } catch (e) {
-            return getText(node, options);
+            return getText(node, options, true);
         }
     }
 
diff --git a/src/lib/getText.ts b/src/lib/getText.ts
index 3700076..82e2d14 100644
--- a/src/lib/getText.ts
+++ b/src/lib/getText.ts
@@ -1,15 +1,21 @@
 import { ParserOptions } from 'prettier';
 import { Node } from '../print/nodes';
+import { hasSnippedContent, unsnipContent } from './snipTagContent';
 
-export function getText(node: Node, options: ParserOptions) {
-    const leadingComments: Node[] = (node as any).leadingComments
-
-    return options.originalText.slice(
+export function getText(node: Node, options: ParserOptions, unsnip = false) {
+    const leadingComments: Node[] = (node as any).leadingComments;
+    const text = options.originalText.slice(
         options.locStart(
-            // if there are comments before the node they are not included 
+            // if there are comments before the node they are not included
             // in the `start` of the node itself
-            leadingComments && leadingComments[0] || node,
+            (leadingComments && leadingComments[0]) || node,
         ),
         options.locEnd(node),
     );
+
+    if (!unsnip || !hasSnippedContent(text)) {
+        return text;
+    }
+
+    return unsnipContent(text);
 }


Test patch:
diff --git a/test/printer/samples/no-tag-snippings.html b/test/printer/samples/no-tag-snippings.html
new file mode 100644
index 0000000..d60d00a
--- /dev/null
+++ b/test/printer/samples/no-tag-snippings.html
@@ -0,0 +1,22 @@
+<svelte:head>
+    <script type="application/ld+json">
+        {
+          "@context": "https://schema.org",
+          "@type": "etc..."
+        }
+    </script>
+    {@html `<style>${getCssText()}</style>`}
+</svelte:head>
+
+<pre class="p-2">
+    {`<div>
+        <span>Hello</span>
+        <span>World</span>
+      </div>
+
+      <style lang="postcss">
+        span {
+          @apply text-red-500;
+        }
+      </style>`}
+</pre>