logo

Convert SCSS to Sass and vice versa

In the previous episode, we introduced the syntax_tree adapter for synvert-ruby, highlighting its applicability not just to Ruby but also to JavaScript. In this episode, I’ll demonstrate how to utilize the gonzales_pe adapter to convert SCSS to Sass and vice versa.

Let’s start by generating a snippet using synvert-javascript with the command:

synvert-javascript --generate css/convert-scss-to-sass

Then, run the test command:

npm run watch:test test/css/convert-scss-to-sass.spec.js

Next, update input and output in test/css/convert-scss-to-sass.spec.js

const snippet = "css/convert-scss-to-sass";
const { assertConvert } = require("../utils");

describe(snippet, () => {
  const input = `
    @import "../styles/imports";
    $col-primary: #f39900;
    @mixin center_horizontal() {
      display: flex;
      justify-content: center;
    }

    .container {
      @include center_horizontal();
      border: 1px solid darken($col-background, 10);

      .item {
        color: $col-primary;
      }
    }
  `;

  const output = `
    @import "../styles/imports"
    $col-primary: #f39900
    @mixin center_horizontal()
      display: flex
      justify-content: center

    .container
      @include center_horizontal()
      border: 1px solid darken($col-background, 10)

      .item
        color: $col-primary
  `;

  assertConvert({
    path: "code.scss",
    input,
    output,
    snippet,
  });
});

Now test failed. To resolve the failed test, closely examine the failures and address the following two issues:

  1. Remove semicolons at the end of each line.
  2. Remove curly braces.

Now let’s proceed with the steps to address the issues in the snippet located at lib/css/convert-scss-to-sass.js.

1. Change the parser from TYPESCRIPT to GONZALES_PE:

configure({ parser: Synvert.Parser.GONZALES_PE });

2. Find all SCSS files:

withinFiles(Synvert.ALL_SCSS_FILES, function () {
});

3. Remove semicolons at the end of each line. If you take a look at the ast generated by gonzales_pe, you will notice that all semicolon are declarationDelimiter nodes. So we can use NQL to find all declarationDelimiter nodes and remove them.

findNode(".declarationDelimiter", () => {
  remove();
});

4. Remove curly braces. all curly braces are leftCurlyBracket and rightCurlyBracket nodes. So we just need to find all leftCurlyBracket and rightCurlyBracket nodes, and remove them.

findNode(".block", () => {
   delete("leftCurlyBracket");
   delete("rightCurlyBracket", { wholeLine: true });
});

Now that all tests have passed, let’s consider renaming SCSS files to Sass files using the renameFile API:

Assert new path is code.sass in test code:

assertConvert({
 path: "code.scss",
 input,
 output,
 snippet,
 newPath: "code.sass",
});

And rename all scss files to sass files in lib/css/convert-scss-to-sass.js:

renameFile(Synvert.ALL_SCSS_FILES, (filePath) => filePath.replace(/\.scss$/, ".sass"));

Tests are still passed.

Although GUI and VSCode extensions might not yet support CSS, SCSS, or Sass, you can still use the CLI synvert-javascript to convert SCSS to Sass:

synvert-javascript --run lib/css/convert-scss-to-sass.js --root-path ~/Sites/xinminlabs/awesomecode.io

Verify the changes using the Git diff:

diff --git a/app/javascript/anonymous/styles/app.sass b/app/javascript/anonymous/styles/app.sass
new file mode 100644
index 00000000..0f08dc84
--- /dev/null
+++ b/app/javascript/anonymous/styles/app.sass
@@ -0,0 +1,3 @@
+@import "./vendor"
+@import "./layout"
+@import "./common"
diff --git a/app/javascript/anonymous/styles/app.scss b/app/javascript/anonymous/styles/app.scss
deleted file mode 100644
index 5adaf27e..00000000
--- a/app/javascript/anonymous/styles/app.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-@import "./vendor";
-@import "./layout";
-@import "./common";
diff --git a/app/javascript/awesomecode/styles/subscription.sass b/app/javascript/awesomecode/styles/subscription.sass
new file mode 100644
index 00000000..b2935a98
--- /dev/null
+++ b/app/javascript/awesomecode/styles/subscription.sass
@@ -0,0 +1,9 @@
+/**********************
+ * Subscription/Index *
+ **********************/
+#subscription
+  .row
+    margin: 10px 0
+  .your-plan
+    font-size: 1rem
+    padding: 10px
diff --git a/app/javascript/awesomecode/styles/subscription.scss b/app/javascript/awesomecode/styles/subscription.scss
deleted file mode 100644
index a899e3b8..00000000
--- a/app/javascript/awesomecode/styles/subscription.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-/**********************
- * Subscription/Index *
- **********************/
-#subscription {
-  .row {
-    margin: 10px 0;
-  }
-  .your-plan {
-    font-size: 1rem;
-    padding: 10px;
-  }
-}

By following these steps, we’ve successfully converted all SCSS files to Sass files. If you wish to reverse the process and convert Sass to SCSS, you can create a new snippet, insert semicolons, curly braces, and adjust the file extensions accordingly.