Converting HTML to Pug
Tags: pug, html, webdev
Published: 2022-05-18 19:46:42

Hey everybody. I recently created an online app for converting HTML to Pug. Your can check it out here: [https://pugify.dev](https://pugify.dev)

## Why?
This was a fun side-project for me.  I had been using some other solutions for a long while, but wanted one that was ad-free and tracker-free (which this one is).


## What is Pug?
Pug is an elegant, feature-rich, and high-performance template engine for writing markup. Simply put, it makes HTML easier and faster to write, read, and understand. And it makes life easier for developers of all shapes, sizes and experience levels.

## What if I'm new to Pug?
If you're new to Pug or just getting started with HTML you should start at the [official website](https://pugjs.org/api/getting-started.html) or [this Medium article](https://medium.com/jspoint/pug-js-to-make-your-life-easier-with-html-templates-9c62273626e0).

## Why did you build this?
Partly for the love of crafting something useful, partly because this is the tool I wanted to use but couldn't find (without ads, & trackers), and partly because it was a great chance to brush up on some of the particulars of Pug, the Dom, and related minutia that I hadn't thought about in a minute. (Like the DocumentType Node -- did you know Pug had [9 different shortcuts for Doctypes](https://pugjs.org/language/doctype.html)?)

Most of all, I wanted a quick and easy stand-alone web-based pug-to-html converter. And I wanted it to be 1) secure, 2) free of ads, 3) free of trackers, 4) fast, 5) and tell me who built it and why.

## How do you make an HTML to Pug converter?
This one was written from scratch in Typescript with, Pug, and TailwindCSS.

I intentionally avoided looking at how similar tools are built. That may have made things move more quickly, but since this was a side-project with no deadline pressures I wanted to start with a clean-slate and see if I could solve all of the inherent challenges on my own.

My first impulse way back when this was just a thought experiment was to imagine if an html document could be parsed and understood and translated in its string state (not parsed as HTML by a browser). It didn't take long to determine that it could be done (this is what browsers do), but probably wasn't the best approach. While one should be able to search and replace html tags quite easily by recognizing them as string patterns, it would be very difficult tracking the hierarchy of elements... and, of course, hierarchy is absolutely fundamental to HTML and Pug.

The approach I settled on was to massage the string content from the input field in a couple of minor ways to deal with things like DocumentType elements, and preventing media in the HTML from trying to render, then insert it as HTML inside an temporary div (kept outside the DOM for security), then parse it and translate it into Pug node by node.

## Is it opinionated?
Yes, somewhat.

When converting Pug to HTML there are some choices to be made, and I made them.

For example, Pug supports class literals and id literals. Meaning classes and ids don't always have to be inside a class="..." or id="..." statement inside parentheses. They can be put inline like this:

`div.foo#bar ...`

which compiles to this HTML:

`<div class="foo" id="bar">...<div>`

In fact, when there is a valid id or class literal and the element is a div, then the tag name can be dropped entirely. Like this:

`.foo#bar Text`

This helps to make Pug more concise and easier to visually parse.

Unfortunately, class and id literals do not support special characters. For example, take this class from tailwindCSS: `w-1/2`. It contains a slash which would throw an error if attempted in a class literal.

What I decided to do with the converter is to present every class or id as literal if possible, otherwise put it inside of the parenthesis in an attribute statement. That means some HTML that looks like this:

`<div id='demo' class="w-1/2 hidden">...</div>`

comes out like this:

`#demo.hidden(class="w-1/2") ...`

## Why should I trust that this tool is safe and secure?
When it comes to security you shouldn't take my word for it, or anyone's. But there are a few things I've done to make the experience 'more honest' and more secure from my point of view.

First, all of the compilation happens in the front-end, on your browser, in your machine. Meaning: your code never touches my server.

Secondly, your browser can help you confirm that it isn't storing any cookies, or using any trackers. 

Also, you can use the dev tools built into your browser to confirm that it isn't making any extraneous image calls (e.g. pixel trackers) and it isn't calling any 3rd party scripts or extensions. There's just the (1) markup file, the (1) css file and the (1) javascript file.

## Are there other tools that already do this?
Absolutely. Some of them quite good. One particularly handy alternative is the Pug to HTML VSCode extension, which allows for HTML to Pug conversion right in the editor. Unfortunately, that doesn't appear to have been updated in a long while, and the results can be mixed.

## Do people still use / need Pug in 2022?
There are a lot of alternatives in this day and age and it is perhaps less popular than it was a few years back.  However it still has a devoted user-base, and I still prefer it over other options. I've used Pug with Vue in recent projects and find it to be quite an improvement over Vue templating with straight HTML. 

That being said, I think it is also fair for someone to say this tool is about 4-5 years too late to be an innovation of any kind.  That's true, and I wouldn't claim it be anything groundbreaking. Just my own take on a familiar tool.

## What's next?
I believe it could provide some value to folks as a VSCode extension. And if enough folks agree, that might be the next step for this.