diff --git a/.changeset/friendly-lobsters-shop.md b/.changeset/friendly-lobsters-shop.md new file mode 100644 index 0000000..98abd18 --- /dev/null +++ b/.changeset/friendly-lobsters-shop.md @@ -0,0 +1,5 @@ +--- +'prettier-plugin-astro': patch +--- + +Fix: format indented sass diff --git a/src/printer.ts b/src/printer.ts index cb2211d..fcff436 100644 --- a/src/printer.ts +++ b/src/printer.ts @@ -607,7 +607,7 @@ function embed( // format script element if (node.type === 'element' && node.name === 'script') { - const scriptContent = node.children[0].value; + const scriptContent = printRaw(node); let formatttedScript = textToDoc(scriptContent, { ...opts, parser: 'typescript', @@ -640,7 +640,7 @@ function embed( // format style element if (node.type === 'element' && node.name === 'style') { - const styleTagContent = node.children[0].value.trim(); + const styleTagContent = printRaw(node); const supportedStyleLangValues = ['css', 'scss', 'sass']; let parserLang = 'css'; diff --git a/src/utils.ts b/src/utils.ts index 0f350f9..ebaeb3d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -209,7 +209,7 @@ export function printRaw( export function isNodeWithChildren( node: anyNode ): node is anyNode & NodeWithChildren { - return node && Array.isArray(node.children); + return node && 'children' in node && Array.isArray(node.children); } export function isInlineElement( @@ -638,56 +638,45 @@ export function trimTextNodeRight(node: TextNode): void { // }); // } -// https://github.com/dmnd/dedent/blob/master/dist/dedent.js -export function manualDedent(input: string) { - // first, perform interpolation - let result = ''; - for (let i = 0; i < input.length; i++) { - result += input[i] - // join lines when there is a suppressed newline - .replace(/\\\n[ \t]*/g, '') - // handle escaped backticks - .replace(/\\`/g, '`'); - - if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) { - // eslint-disable-next-line prefer-rest-params - result += arguments.length <= i + 1 ? undefined : arguments[i + 1]; +/** dedent string & return tabSize (the last part is what we need) */ +export function manualDedent(input: string): { + tabSize: number; + char: string; + result: string; +} { + let minTabSize = Infinity; + let result = input; + // 1. normalize + result = result.replace(/\r\n/g, '\n'); + + // 2. count tabSize + let char = ''; + for (const line of result.split('\n')) { + if (!line) continue; + // if any line begins with a non-whitespace char, minTabSize is 0 + if (line[0] && /^[^\s]/.test(line[0])) { + minTabSize = 0; + break; + } + const match = line.match(/^(\s+)\S+/); // \S ensures we don’t count lines of pure whitespace + if (match) { + if (match[1] && !char) char = match[1][0]; + if (match[1].length < minTabSize) minTabSize = match[1].length; } } - // now strip indentation - const lines = result.split('\n'); - let mindent: number | null = null; - lines.forEach(function (l) { - const m = l.match(/^(\s+)\S+/); - if (m) { - const indent = m[1].length; - if (!mindent) { - // this is the first indented line - mindent = indent; - } else { - mindent = Math.min(mindent, indent); - } - } - }); - - if (mindent !== null) { - (function () { - const m = mindent; // appease Flow - result = lines - .map(function (l) { - return l[0] === ' ' ? l.slice(m) : l; - }) - .join('\n'); - })(); + // 3. reformat string + if (minTabSize > 0 && Number.isFinite(minTabSize)) { + result = result.replace( + new RegExp(`^${new Array(minTabSize + 1).join(char)}`, 'gm'), + '' + ); } return { - result: result - // dedent eats leading and trailing whitespace too - .trim() - // handle escaped newlines at the end to ensure they don't get stripped too - .replace(/\\n/g, '\n'), + tabSize: minTabSize === Infinity ? 0 : minTabSize, + char, + result, }; } diff --git a/test/fixtures/styles/single-style-element-with-sass-lang/input.astro b/test/fixtures/styles/single-style-element-with-sass-lang/input.astro deleted file mode 100644 index e33405b..0000000 --- a/test/fixtures/styles/single-style-element-with-sass-lang/input.astro +++ /dev/null @@ -1,31 +0,0 @@ - diff --git a/test/fixtures/styles/single-style-element-with-sass-lang/output.astro b/test/fixtures/styles/single-style-element-with-sass-lang/output.astro deleted file mode 100644 index eb78797..0000000 --- a/test/fixtures/styles/single-style-element-with-sass-lang/output.astro +++ /dev/null @@ -1,25 +0,0 @@ - diff --git a/test/fixtures/styles/single-style-element-with-scss-lang/input.astro b/test/fixtures/styles/single-style-element-with-scss-lang/input.astro deleted file mode 100644 index 8c893c3..0000000 --- a/test/fixtures/styles/single-style-element-with-scss-lang/input.astro +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/test/fixtures/styles/single-style-element-with-scss-lang/output.astro b/test/fixtures/styles/single-style-element-with-scss-lang/output.astro deleted file mode 100644 index 0625d27..0000000 --- a/test/fixtures/styles/single-style-element-with-scss-lang/output.astro +++ /dev/null @@ -1,30 +0,0 @@ - diff --git a/test/fixtures/styles/with-indented-sass/input.astro b/test/fixtures/styles/with-indented-sass/input.astro index dd46119..994bf82 100644 --- a/test/fixtures/styles/with-indented-sass/input.astro +++ b/test/fixtures/styles/with-indented-sass/input.astro @@ -1,17 +1,4 @@ - - -
- - - -This is a paragraph.
+ + + + + diff --git a/test/fixtures/styles/with-styles/input.astro b/test/fixtures/styles/with-styles/input.astro index d485365..68fc72d 100644 --- a/test/fixtures/styles/with-styles/input.astro +++ b/test/fixtures/styles/with-styles/input.astro @@ -1,17 +1,4 @@ - - - - - - -