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

Issue:
Prettier removes content from script block
When I use this fenced code block snippet in a markdown file and save the file

````markdown
```svelte
<style>
  h1 {
    color: green;
  }

  p {
    font-style: italic;
  }
</style>

<script>
  let role = "developer";
</script>

<h1>Hello, {role}!</h1>

<p>I hope you are having a good day!</p>

```
````

it removes the content of the `<script>` block and changes it to 

```
<script 1>

</script>
```

Not sure if this is related to `prettier-plugin-svelte` but it makes it impossible to use fenced code blocks with svelte, one workaround is to use html as code block language instead.

Pull request:
Fix markdown print
Prettier sets the preprocessed text as the originalText in case the Svelte formatter is called directly. In case it's called as an embedded parser (for example when there's a Svelte code block inside markdown), the originalText is not updated after preprocessing. Therefore we update the originalText ourselves.
Fixes #129

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 370474a..f584ea6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 * Rework of the tag breaking logic with the goal to be more in line with how Prettier formats HTML. This includes respecting the user's decision to have child tags in seperate lines even if they don't exceed the maximum line width ([#143](https://github.com/sveltejs/prettier-plugin-svelte/issues/143), [#117](https://github.com/sveltejs/prettier-plugin-svelte/issues/117)). This is a breaking change because tags are broken up differently now than before.
 * Default sort order is now `scripts-markup-styles`. This is a breaking change.
+* Fix formatting of fenced Svelte code blocks inside markdown ([#129](https://github.com/sveltejs/prettier-plugin-svelte/issues/129))
 
 ## 1.4.2
 
diff --git a/src/index.ts b/src/index.ts
index 53fa93c..d1b11f6 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -28,7 +28,7 @@ export const parsers: Record<string, Parser> = {
                 return <ASTNode>{ ...require(`svelte/compiler`).parse(text), __isRoot: true };
             } catch (err) {
                 if (err.start != null && err.end != null) {
-                    // Prettier expects error objects to have loc.start and loc.end fields. 
+                    // Prettier expects error objects to have loc.start and loc.end fields.
                     // Svelte uses start and end directly on the error.
                     err.loc = {
                         start: err.start,
@@ -39,10 +39,17 @@ export const parsers: Record<string, Parser> = {
                 throw err;
             }
         },
-        preprocess: (text) => {
+        preprocess: (text, options) => {
             text = snipTagContent('style', text);
             text = snipTagContent('script', text, '{}');
-            return text.trim();
+            text = text.trim();
+            // Prettier sets the preprocessed text as the originalText in case
+            // the Svelte formatter is called directly. In case it's called
+            // as an embedded parser (for example when there's a Svelte code block
+            // inside markdown), the originalText is not updated after preprocessing.
+            // Therefore we do it ourselves here.
+            options.originalText = text;
+            return text;
         },
         locStart,
         locEnd,


Test patch:
diff --git a/test/printer/index.ts b/test/printer/index.ts
index 149deba..8165b56 100644
--- a/test/printer/index.ts
+++ b/test/printer/index.ts
@@ -2,8 +2,10 @@ import test from 'ava';
 import { readdirSync, readFileSync, existsSync } from 'fs';
 import { format } from 'prettier';
 
-let files = readdirSync('test/printer/samples').filter((name) => name.endsWith('.html'));
-const endsWithOnly = (f: string): boolean => f.endsWith('.only.html');
+let files = readdirSync('test/printer/samples').filter(
+    (name) => name.endsWith('.html') || name.endsWith('.md'),
+);
+const endsWithOnly = (f: string): boolean => f.endsWith('.only.html') || f.endsWith('.only.md');
 const hasOnly = files.some(endsWithOnly);
 files = !hasOnly ? files : files.filter(endsWithOnly);
 
@@ -12,12 +14,15 @@ if (process.env.CI && hasOnly) {
 }
 
 for (const file of files) {
+    const ending = file.split('.').pop();
     const input = readFileSync(`test/printer/samples/${file}`, 'utf-8').replace(/\r?\n/g, '\n');
-    const options = readOptions(`test/printer/samples/${file.replace('.html', '.options.json')}`);
+    const options = readOptions(
+        `test/printer/samples/${file.replace(`.${ending}`, '.options.json')}`,
+    );
 
-    test(`printer: ${file.slice(0, file.length - '.html'.length)}`, (t) => {
+    test(`printer: ${file.slice(0, file.length - `.${ending}`.length)}`, (t) => {
         const actualOutput = format(input, {
-            parser: 'svelte' as any,
+            parser: (ending === 'html' ? 'svelte' : 'markdown') as any,
             plugins: [require.resolve('../../src')],
             tabWidth: 4,
             ...options,
diff --git a/test/printer/samples/markdown.md b/test/printer/samples/markdown.md
new file mode 100644
index 0000000..c7ba83e
--- /dev/null
+++ b/test/printer/samples/markdown.md
@@ -0,0 +1,21 @@
+This is a markdown file with embedded Svelte content. Prettier can format this
+by offloading the formatting of the fenced code block to prettier-plugin-svelte.
+
+```svelte
+<script context="module">
+    const greeting = "Hello";
+</script>
+
+<script>
+    const name = "world";
+</script>
+
+<h1>{greeting}, {name}!</h1>
+
+<style>
+    h1 {
+        color: green;
+    }
+</style>
+
+```