Repository: maizzle/framework (js)

Issue:
Add proper indentation for HTML comments
- Maizzle Version: 4.6.0
- Node.js Version: 16.13.1

One of my most common use case with Maizzle is to build emails to then hand off to clients so they can either edit them manually or import on their own ESP or anything. As such, I like to be able to hand off a _clean_ HTML with proper indentation. While this mostly work great by default, it seems off with HTML comments (including `mso` conditionnal comments). The first line of an HTML is properly indented where it should be. But all the other lines miss one or more indentations.

```html
                        <div>
                          <a href="https://example.com" style="display: inline-block; border-radius: 4px; background-color: #4338ca; padding: 16px 24px; font-size: 16px; font-weight: 600; line-height: 1; color: #f8fafc; text-decoration: none">
                            <!--[if mso]>
      <i style="mso-font-width: -100%; letter-spacing: 32px; mso-text-raise: 30px" hidden>&nbsp;</i>
    <![endif]-->
                            <span style="mso-text-raise: 16px">
                          Read more &rarr;
                        </span>
                            <!--[if mso]>
      <i style="mso-font-width: -100%; letter-spacing: 32px;" hidden>&nbsp;</i>
    <![endif]-->
                          </a>
                        </div>
```

Not a big issue as this is purely code cosmetic, but I'd love if there were a quick fix here.

Pull request:
feat: use prettier for prettify transformer
This PR changes the `prettify` transformer from `pretty` to `prettier` (which makes sense if you think about it 😂).

Main reason behind this is for HTML/MSO comments to be correctly indented too.

Closes #1071.


Patch:
diff --git a/package-lock.json b/package-lock.json
index 9416912..bc83229 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -39,7 +39,7 @@
         "posthtml-postcss-merge-longhand": "^2.0.1",
         "posthtml-safe-class-names": "^3.0.0",
         "posthtml-url-parameters": "^2.0.0",
-        "pretty": "^2.0.0",
+        "prettier": "^3.1.1",
         "query-string": "^7.1.3",
         "string-remove-widows": "^2.1.0",
         "string-strip-html": "^8.2.0",
@@ -1427,11 +1427,6 @@
       "dev": true,
       "peer": true
     },
-    "node_modules/abbrev": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
-      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
-    },
     "node_modules/accepts": {
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -3236,30 +3231,6 @@
         "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14"
       }
     },
-    "node_modules/condense-newlines": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz",
-      "integrity": "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==",
-      "dependencies": {
-        "extend-shallow": "^2.0.1",
-        "is-whitespace": "^0.3.0",
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/condense-newlines/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/config-chain": {
       "version": "1.1.13",
       "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
@@ -4003,47 +3974,6 @@
         "node": ">= 0.8.0"
       }
     },
-    "node_modules/editorconfig": {
-      "version": "0.15.3",
-      "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
-      "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==",
-      "dependencies": {
-        "commander": "^2.19.0",
-        "lru-cache": "^4.1.5",
-        "semver": "^5.6.0",
-        "sigmund": "^1.0.1"
-      },
-      "bin": {
-        "editorconfig": "bin/editorconfig"
-      }
-    },
-    "node_modules/editorconfig/node_modules/commander": {
-      "version": "2.20.3",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
-    },
-    "node_modules/editorconfig/node_modules/lru-cache": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
-      "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
-      "dependencies": {
-        "pseudomap": "^1.0.2",
-        "yallist": "^2.1.2"
-      }
-    },
-    "node_modules/editorconfig/node_modules/semver": {
-      "version": "5.7.2",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
-      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/editorconfig/node_modules/yallist": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
-      "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
-    },
     "node_modules/ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -5438,6 +5368,7 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
       "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+      "dev": true,
       "dependencies": {
         "is-extendable": "^0.1.0"
       },
@@ -7268,7 +7199,8 @@
     "node_modules/is-buffer": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
-      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+      "dev": true
     },
     "node_modules/is-callable": {
       "version": "1.2.7",
@@ -7374,6 +7306,7 @@
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
       "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -7872,14 +7805,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/is-whitespace": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz",
-      "integrity": "sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -8026,62 +7951,6 @@
         "jiti": "bin/jiti.js"
       }
     },
-    "node_modules/js-beautify": {
-      "version": "1.14.7",
-      "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.7.tgz",
-      "integrity": "sha512-5SOX1KXPFKx+5f6ZrPsIPEY7NwKeQz47n3jm2i+XeHx9MoRsfQenlOP13FQhWvg8JRS0+XLO6XYUQ2GX+q+T9A==",
-      "dependencies": {
-        "config-chain": "^1.1.13",
-        "editorconfig": "^0.15.3",
-        "glob": "^8.0.3",
-        "nopt": "^6.0.0"
-      },
-      "bin": {
-        "css-beautify": "js/bin/css-beautify.js",
-        "html-beautify": "js/bin/html-beautify.js",
-        "js-beautify": "js/bin/js-beautify.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/js-beautify/node_modules/brace-expansion": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
-      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
-      "dependencies": {
-        "balanced-match": "^1.0.0"
-      }
-    },
-    "node_modules/js-beautify/node_modules/glob": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
-      "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^5.0.1",
-        "once": "^1.3.0"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/js-beautify/node_modules/minimatch": {
-      "version": "5.1.6",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
-      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
-      "dependencies": {
-        "brace-expansion": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/js-string-escape": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
@@ -9535,20 +9404,6 @@
         "node": ">=12.19"
       }
     },
-    "node_modules/nopt": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
-      "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
-      "dependencies": {
-        "abbrev": "^1.0.0"
-      },
-      "bin": {
-        "nopt": "bin/nopt.js"
-      },
-      "engines": {
-        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
-      }
-    },
     "node_modules/normalize-package-data": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
@@ -12634,15 +12489,14 @@
       }
     },
     "node_modules/prettier": {
-      "version": "2.8.7",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
-      "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
-      "dev": true,
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
+      "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==",
       "bin": {
-        "prettier": "bin-prettier.js"
+        "prettier": "bin/prettier.cjs"
       },
       "engines": {
-        "node": ">=10.13.0"
+        "node": ">=14"
       },
       "funding": {
         "url": "https://github.com/prettier/prettier?sponsor=1"
@@ -12660,19 +12514,6 @@
         "node": ">=6.0.0"
       }
     },
-    "node_modules/pretty": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz",
-      "integrity": "sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==",
-      "dependencies": {
-        "condense-newlines": "^0.2.1",
-        "extend-shallow": "^2.0.1",
-        "js-beautify": "^1.6.12"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/pretty-ms": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz",
@@ -12710,11 +12551,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/pseudomap": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
-      "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="
-    },
     "node_modules/pump": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -13900,11 +13736,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/sigmund": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
-      "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g=="
-    },
     "node_modules/signal-exit": {
       "version": "3.0.7",
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -16703,6 +16534,21 @@
         "node": ">=6"
       }
     },
+    "node_modules/xo/node_modules/prettier": {
+      "version": "2.8.8",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+      "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
+      }
+    },
     "node_modules/xo/node_modules/to-regex-range": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
@@ -17934,11 +17780,6 @@
       "dev": true,
       "peer": true
     },
-    "abbrev": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
-      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
-    },
     "accepts": {
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -19233,26 +19074,6 @@
         "well-known-symbols": "^2.0.0"
       }
     },
-    "condense-newlines": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz",
-      "integrity": "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==",
-      "requires": {
-        "extend-shallow": "^2.0.1",
-        "is-whitespace": "^0.3.0",
-        "kind-of": "^3.0.2"
-      },
-      "dependencies": {
-        "kind-of": {
-          "version": "3.2.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-          "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
-          "requires": {
-            "is-buffer": "^1.1.5"
-          }
-        }
-      }
-    },
     "config-chain": {
       "version": "1.1.13",
       "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
@@ -19780,43 +19601,6 @@
         "chalk": "4.1.2"
       }
     },
-    "editorconfig": {
-      "version": "0.15.3",
-      "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
-      "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==",
-      "requires": {
-        "commander": "^2.19.0",
-        "lru-cache": "^4.1.5",
-        "semver": "^5.6.0",
-        "sigmund": "^1.0.1"
-      },
-      "dependencies": {
-        "commander": {
-          "version": "2.20.3",
-          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-          "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
-        },
-        "lru-cache": {
-          "version": "4.1.5",
-          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
-          "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
-          "requires": {
-            "pseudomap": "^1.0.2",
-            "yallist": "^2.1.2"
-          }
-        },
-        "semver": {
-          "version": "5.7.2",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
-          "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
-        },
-        "yallist": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
-          "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
-        }
-      }
-    },
     "ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -20857,6 +20641,7 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
       "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+      "dev": true,
       "requires": {
         "is-extendable": "^0.1.0"
       }
@@ -22179,7 +21964,8 @@
     "is-buffer": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
-      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+      "dev": true
     },
     "is-callable": {
       "version": "1.2.7",
@@ -22253,7 +22039,8 @@
     "is-extendable": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
-      "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="
+      "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+      "dev": true
     },
     "is-extglob": {
       "version": "2.1.1",
@@ -22590,11 +22377,6 @@
         "call-bind": "^1.0.2"
       }
     },
-    "is-whitespace": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz",
-      "integrity": "sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg=="
-    },
     "is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -22703,47 +22485,6 @@
       "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz",
       "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA=="
     },
-    "js-beautify": {
-      "version": "1.14.7",
-      "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.7.tgz",
-      "integrity": "sha512-5SOX1KXPFKx+5f6ZrPsIPEY7NwKeQz47n3jm2i+XeHx9MoRsfQenlOP13FQhWvg8JRS0+XLO6XYUQ2GX+q+T9A==",
-      "requires": {
-        "config-chain": "^1.1.13",
-        "editorconfig": "^0.15.3",
-        "glob": "^8.0.3",
-        "nopt": "^6.0.0"
-      },
-      "dependencies": {
-        "brace-expansion": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
-          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
-          "requires": {
-            "balanced-match": "^1.0.0"
-          }
-        },
-        "glob": {
-          "version": "8.1.0",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
-          "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
-          "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^5.0.1",
-            "once": "^1.3.0"
-          }
-        },
-        "minimatch": {
-          "version": "5.1.6",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
-          "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
-          "requires": {
-            "brace-expansion": "^2.0.1"
-          }
-        }
-      }
-    },
     "js-string-escape": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
@@ -23825,14 +23566,6 @@
       "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==",
       "dev": true
     },
-    "nopt": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
-      "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
-      "requires": {
-        "abbrev": "^1.0.0"
-      }
-    },
     "normalize-package-data": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
@@ -25910,10 +25643,9 @@
       "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA=="
     },
     "prettier": {
-      "version": "2.8.7",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
-      "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
-      "dev": true
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
+      "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw=="
     },
     "prettier-linter-helpers": {
       "version": "1.0.0",
@@ -25924,16 +25656,6 @@
         "fast-diff": "^1.1.2"
       }
     },
-    "pretty": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz",
-      "integrity": "sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==",
-      "requires": {
-        "condense-newlines": "^0.2.1",
-        "extend-shallow": "^2.0.1",
-        "js-beautify": "^1.6.12"
-      }
-    },
     "pretty-ms": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz",
@@ -25959,11 +25681,6 @@
       "integrity": "sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==",
       "dev": true
     },
-    "pseudomap": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
-      "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="
-    },
     "pump": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -26863,11 +26580,6 @@
         "object-inspect": "^1.9.0"
       }
     },
-    "sigmund": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
-      "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g=="
-    },
     "signal-exit": {
       "version": "3.0.7",
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -29008,6 +28720,12 @@
           "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
           "dev": true
         },
+        "prettier": {
+          "version": "2.8.8",
+          "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+          "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+          "dev": true
+        },
         "to-regex-range": {
           "version": "2.1.1",
           "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
diff --git a/package.json b/package.json
index 4f8ef44..b60582c 100644
--- a/package.json
+++ b/package.json
@@ -71,14 +71,13 @@
     "posthtml-postcss-merge-longhand": "^2.0.1",
     "posthtml-safe-class-names": "^3.0.0",
     "posthtml-url-parameters": "^2.0.0",
-    "pretty": "^2.0.0",
+    "prettier": "^3.1.1",
     "query-string": "^7.1.3",
     "string-remove-widows": "^2.1.0",
     "string-strip-html": "^8.2.0",
     "tailwindcss": "^3.2.7"
   },
   "devDependencies": {
-    "@types/js-beautify": "^1.14.0",
     "@types/markdown-it": "^13.0.0",
     "ava": "^5.2.0",
     "c8": "^9.0.0",
diff --git a/src/index.d.ts b/src/index.d.ts
index adacafd..b6f23f1 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -1,5 +1,5 @@
 import type {StringifyOptions} from 'query-string';
-import type {CoreBeautifyOptions} from 'js-beautify';
+import type {Config as PrettierOptions} from 'prettier';
 import type {Options as MarkdownItOptions} from 'markdown-it';
 import type {Opts as PlaintextOptions} from 'string-strip-html';
 
@@ -1773,7 +1773,7 @@ declare namespace MaizzleFramework {
     }
     ```
     */
-    prettify?: boolean | CoreBeautifyOptions;
+    prettify?: boolean | PrettierOptions;
 
     /**
     Minify the compiled HTML email code.
@@ -2041,9 +2041,9 @@ declare namespace MaizzleFramework {
   /**
   Pretty print HTML code so that it's nicely indented and more human-readable.
   @param {string} html The HTML string to prettify.
-  @param {CoreBeautifyOptions} [options] Options to pass to the prettifier.
+  @param {PrettierOptions} [options] Options to pass to the prettifier.
   */
-  function prettify(html: string, options?: CoreBeautifyOptions): string;
+  function prettify(html: string, options?: PrettierOptions): string;
 
   /**
   Prepend a string to sources and hrefs in an HTML string.
diff --git a/src/transformers/prettify.js b/src/transformers/prettify.js
index 7106179..566817e 100644
--- a/src/transformers/prettify.js
+++ b/src/transformers/prettify.js
@@ -1,27 +1,39 @@
-/* eslint-disable camelcase */
-const pretty = require('pretty')
+const {format} = require('prettier')
 const {get, merge, isEmpty, isObject} = require('lodash')
 
 module.exports = async (html, config = {}, direct = false) => {
+  config = direct ? config : get(config, 'prettify')
+
   const defaultConfig = {
-    space_around_combinator: true, // Preserve space around CSS selector combinators
-    newline_between_rules: false, // Remove empty lines between CSS rules
-    indent_inner_html: false, // Helps reduce file size
-    extra_liners: [] // Don't add extra new line before any tag
+    parser: 'html',
+    printWidth: 500,
+    htmlWhitespaceSensitivity: 'ignore',
+    xmlMode: get(config, 'posthtml.options.xmlMode', false)
   }
 
-  config = direct ? config : get(config, 'prettify')
-
   // Don't prettify if not explicitly enabled in config
   if (!config || (isObject(config) && isEmpty(config))) {
     return html
   }
 
   if (typeof config === 'boolean' && config) {
-    return pretty(html, defaultConfig)
+    return format(html, defaultConfig).then(html => reFormat(html, defaultConfig))
   }
 
   config = merge(defaultConfig, config)
 
-  return pretty(html, config)
+  return format(html, config).then(html => reFormat(html, config))
+}
+
+const reFormat = (html, config) => {
+  if (/<!doctype html>/i.test(html) && !config.xmlMode) {
+    html = html.replace(/<(.+?)(\s\/)>/g, '<$1>')
+  }
+
+  return html
+    .replace(/,\s*/g, ', ')
+    .replace(/(\s+style="\s+)([\s\S]*?)(\s+")/g, (match, p1, p2, p3) => {
+      const formattedStyle = p2.replace(/\s+/g, ' ').trim()
+      return p1.trim() + formattedStyle + p3.trim()
+    })
 }


Test patch:
diff --git a/test/expected/components/kitchen-sink.html b/test/expected/components/kitchen-sink.html
index aea4cd0..d59ab8c 100644
--- a/test/expected/components/kitchen-sink.html
+++ b/test/expected/components/kitchen-sink.html
@@ -1,73 +1,91 @@
-{{ test }}
-The Website Weekly Newsletter
-bar
-{% capture email_title %}Hey {{customer.first_name}} {{ customer.last_name}}, {% endcapture %}
-<!DOCTYPE html>
+{{ test }} The Website Weekly Newsletter bar {% capture email_title %}Hey {{customer.first_name}} {{ customer.last_name}}, {% endcapture %}
+
+<!doctype html>
 <html lang="en" xmlns:v="urn:schemas-microsoft-com:vml">
-<head>
-  <style>
-  </style>
-</head>
-<body class="bg-red-500">
-  <h1>H1 in fill:template</h1>
-
-  <!-- Expressions -->
-  Compiled: maizzle-ci
-  Ignored: {{ page.env }}
-  Inside component: maizzle-ci
-  Inside component (ignored): {{ page.env }}
-  Inside nested component: maizzle-ci
-  Inside nested component (ignored): {{ page.env }}
-
-  <!-- Component slots -->
-  Slot header
-
-  <!-- Markdown -->
-  <h3>Heading</h3>
-  <pre><code class="language-js">console.log('Hello world!')
+  <head>
+    <style>
+      .text-sm {
+        font-size: 0.875rem;
+        line-height: 1.25rem;
+      }
+    </style>
+  </head>
+
+  <body class="bg-red-500">
+    <h1 class="text-sm">H1 in fill:template</h1>
+
+    <!-- Expressions -->
+    Compiled: maizzle-ci Ignored: {{ page.env }} Inside component: maizzle-ci Inside component (ignored): {{ page.env }} Inside nested component: maizzle-ci Inside nested component (ignored): {{ page.env }}
+
+    <!-- Component slots -->
+
+    Slot header
+
+    <!-- Markdown -->
+    <h3>Heading</h3>
+    <pre><code class="language-js">console.log('Hello world!')
 </code></pre>
-  <h3>Markdown in component</h3>
-
-  <!-- Passing props to component -->
-  Environment: maizzle-ci
-  Environment (ignore expression): {{ page.env }}
-
-  <!-- Nesting components, with props -->
-  Parent
-  Childish
-
-  <!-- <fetch> tag -->
-  <ul>
-    <li>
-      Leanne Graham
-    </li>
-    <li>
-      Ervin Howell
-    </li>
-    <li>
-      Clementine Bauch (last item)
-    </li>
-  </ul>
-
-  <!-- <outlook> tag -->
-
-  <!--[if mso]>in outlook<![endif]-->
-
-  <!-- Conditionals -->
-  <p>Using Maizzle programmatically</p>
-
-  <!-- Loops -->
-  {{ i }} is <i>1</i>
-  {{ i }} is <i>2 (last)</i>
-
-  <!-- Switch -->
-  page.foo is bar
-
-  <!-- Scope -->
-  Author: John
-  Editor: Jane
-
-  <!-- Raw -->
-  Expression should be ignored: {{ foo }}
-</body>
+
+    <h3>Markdown in component</h3>
+
+    <!-- Passing props to component -->
+
+    Environment: maizzle-ci Environment (ignore expression): {{ page.env }}
+
+    <!-- Nesting components, with props -->
+
+    Parent Childish
+
+    <!-- <fetch> tag -->
+
+    <ul>
+      <li>Leanne Graham</li>
+
+      <li>Ervin Howell</li>
+
+      <li>Clementine Bauch (last item)</li>
+    </ul>
+
+    <!-- <outlook> tag -->
+
+    <!--[if mso]>in outlook<![endif]-->
+
+    <!-- Conditionals -->
+
+    <p>Using Maizzle programmatically</p>
+
+    <!-- Loops -->
+
+    {{ i }} is
+    <i>1</i>
+
+    {{ i }} is
+    <i>2 (last)</i>
+
+    <!-- Switch -->
+
+    page.foo is bar
+
+    <!-- Scope -->
+
+    Author: John Editor: Jane
+
+    <!-- Raw -->
+
+    Expression should be ignored: {{ foo }}
+
+    <!-- MSO Comments -->
+
+    <div>
+      <a href="#">
+        <!--[if mso]>
+          <i>&nbsp;</i>
+        <![endif]-->
+        <span>Read more &rarr;</span>
+        <!--[if mso]>
+          <i>&nbsp;</i>
+        <![endif]-->
+      </a>
+    </div>
+  </body>
 </html>
diff --git a/test/fixtures/components/kitchen-sink.html b/test/fixtures/components/kitchen-sink.html
index dbb5970..35d5eb5 100644
--- a/test/fixtures/components/kitchen-sink.html
+++ b/test/fixtures/components/kitchen-sink.html
@@ -19,7 +19,7 @@ roles:
 
 <x-layout>
   <fill:template>
-    <h1>H1 in fill:template</h1>
+    <h1 class="text-sm">H1 in fill:template</h1>
 
     <!-- Expressions -->
     Compiled: {{ page.env }}
@@ -120,5 +120,21 @@ roles:
         Expression should be ignored: {{ foo }}
       </raw>
     </x-bare>
+
+    <!-- MSO Comments -->
+
+    <div>
+      <a href="#">
+        <!--[if mso]>
+<i>&nbsp;</i>
+<![endif]-->
+        <span>
+      Read more &rarr;
+    </span>
+        <!--[if mso]>
+<i>&nbsp;</i>
+<![endif]-->
+      </a>
+    </div>
   </fill:template>
 </x-layout>
diff --git a/test/test-posthtml.js b/test/test-posthtml.js
index 69b0770..d619cc8 100644
--- a/test/test-posthtml.js
+++ b/test/test-posthtml.js
@@ -118,9 +118,10 @@ test.serial('components', async t => {
   }
 
   const html = await renderString(source, options)
+  const expectedHtml = await expected('components/kitchen-sink')
 
   t.is(
-    await prettify(html, {ocd: true}),
-    await expected('components/kitchen-sink')
+    await prettify(html, {printWidth: 500}),
+    expectedHtml + '\n'
   )
 })
diff --git a/test/test-transformers.js b/test/test-transformers.js
index 5fd4a4f..e324c7d 100644
--- a/test/test-transformers.js
+++ b/test/test-transformers.js
@@ -240,23 +240,21 @@ test('base URL (object)', async t => {
 })
 
 test('prettify', async t => {
-  // `prettify: true`
-  const html2 = await Maizzle.prettify('<div><p>test</p></div>', true)
-
   // With custom object config
-  // eslint-disable-next-line
-  const html = await Maizzle.prettify('<div><p>test</p></div>', {indent_inner_result: true})
+  const html = await Maizzle.prettify('<div><p>with options</p></div>', {printWidth: 12})
+  t.is(html, '<div>\n  <p>\n    with\n    options\n  </p>\n</div>\n')
+
+  // `prettify: true`
+  const html2 = await Maizzle.prettify('<!doctype html><meta name="test" /><div><p>prettify: true</p></div>', true)
+  t.is(html2, '<!doctype html>\n<meta name="test">\n<div><p>prettify: true</p></div>\n')
 
   // No config
   const html3 = await Maizzle.prettify('<div><p>test</p></div>')
+  t.is(html3, '<div><p>test</p></div>')
 
   // Empty object config
-  const html4 = await Maizzle.prettify('<div><p>test</p></div>', {})
-
-  t.is(html, '<div>\n  <p>test</p>\n</div>')
-  t.is(html2, '<div>\n  <p>test</p>\n</div>')
-  t.is(html3, '<div><p>test</p></div>')
-  t.is(html4, '<div><p>test</p></div>')
+  const html4 = await Maizzle.prettify('<div><p>empty config</p></div>', {})
+  t.is(html4, '<div><p>empty config</p></div>')
 })
 
 test('minify', async t => {