DEV Community

Pacharapol Withayasakpunt
Pacharapol Withayasakpunt

Posted on • Edited on

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

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.