Use Synvert to convert SCSS to Sass and vice versa

Synvert provides the ability to write code snippets that can automatically rewrite your source code. This video demonstrates how to automatically 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.

0 Comments
Synvert's Substack
Synvert's Substack
Authors
Richard Huang