DEV Community

Pacharapol Withayasakpunt
Pacharapol Withayasakpunt

Posted on • Edited on

5 4

Pug with Markdown is Magic, yet underrated

What is Pug?

Pug is a high-performance template engine heavily influenced by Haml and implemented with JavaScript for Node.js and browsers.

Pug uses whitespace syntax, and is Tab / Space -sensitive, just like Markdown and Python

Pug is mainly a template engine for Node.js, and cannot be installed for Webpack via NPM/Yarn, however there is https://github.com/pugjs/pug#browser-support but it is a very large file. However, I created HyperPug a while ago, and it is relatively small.

GitHub logo patarapolw / hyperpug

Lightweight Pug for browser/Electron. With Pug filters' support, which can also contain indented language like markdown.

Pug with Markdown

Pug integrates nicely with Markdown, via Filters.

div
  :markdown
    ## Hello
Enter fullscreen mode Exit fullscreen mode

This can be enabled with Markdown engines, like Showdown or Markdown-it.

import hyperpug from 'hyperpug'
import showdown from 'showdown'

const mdConverter = new showdown.Converter()

console.log(hyperpug.compile({
  filters: {
    markdown: (s: string) => mdConverter.makeHtml(s)
  }
})(str))
Enter fullscreen mode Exit fullscreen mode

Creating a Markdown extension is easy, with Showdown.js

For an official tutorial, see https://github.com/showdownjs/showdown/wiki/extensions#creating-showdown-extensions

You can even create a Pug extension inside Markdown, with indented-filter

import { createIndentedFilter } from "indented-filter";
import showdown from "showdown";

const mdConverter = new showdown.Converter();

mdConverter.addExtension({
  type: "lang",
  filter: createIndentedFilter("^^pug", (str) => {
    return pug.render(str)
  })
}, "pug");
Enter fullscreen mode Exit fullscreen mode

Now, you can use Pug inside Markdown.

^^pug.
  h1 Hello
Enter fullscreen mode Exit fullscreen mode

A roundabout Pug inside Markdown, and also with Markdown inside Pug is also possible, see https://github.com/patarapolw/zhlab/blob/master/web/utils/make-html.ts#L10

Enabling extended Pug (with Markdown) inside Vue, Nuxt, or simply pug-plain-loader

I made this possible with my new NPM package -- https://github.com/patarapolw/deepfind

// nuxt.config.js

import deepfind from '@patarapolw/deepfind'
import showdown from 'showdown'

const mdConverter = new showdown.Converter()

export default {
  build: {
    /*
    ** You can extend webpack config here
    */
    extend (config, ctx) {
      for (const r of deepfind(config, 'pug-plain-loader')) {
        if (!Array.isArray(r)) {
          r.options = r.options || {}
          r.options.filters = {
            markdown: (s: string) => mdConverter.makeHtml(s)
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
// vue.config.js

const deepfind = require('@patarapolw/deepfind').default
const showdown = require('showdown')

const mdConverter = new showdown.Converter()

module.exports = {
  configureWebpack: (config) => {
    for (const r of deepfind(config, 'pug-plain-loader')) {
      if (!Array.isArray(r)) {
        r.options = r.options || {}
        r.options.filters = {
          markdown: (s: string) => mdConverter.makeHtml(s)
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (2)

Collapse
 
bholmesdev profile image
Ben Holmes

This is exactly what I've been looking for on my personal site! Wanted to find a neat way to mix markdown into my HTML, but writing markup in a raw .md file got messy fast. This is an awesome solution. Thanks for pointing this out 😁

Collapse
 
webdiscus profile image
webdiscus

The modern @webdiscus/pug-loader has build-in filter :markdown with highlighting of a code syntax. This filter use the markdown-it and prismjs for optional highlighting.

Tipp
An .md file can be included in a Pug template, e.g. using :markdown filter:

h1 Readme
include:markdown ./README.md
Enter fullscreen mode Exit fullscreen mode

Here is the demo site for :markdown filter.

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

Instrument, monitor, fix: a hands-on debugging session

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️