About me: My name is Solène Rapenne, pronouns she/her. I like learning and sharing knowledge. Hobbies: '(NixOS BSD OpenBSD Lisp cmdline gaming internet-stuff). I love percent and lambda characters. OpenBSD developer solene@.

Contact me: solene+www at dataswamp dot org or @solene@bsd.network (mastodon). If for some reason you want to support my work, this is my paypal address: donate@perso.pw.

Minimalistic markdown subset to html converter using awk

Written by Solène, on 26 August 2019.
Tags: #unix #awk

Comments on Fediverse/Mastodon

Hello

As on my blog I use different markup languages I would like to use a simpler markup language not requiring an extra package. To do so, I wrote an awk script handling titles, paragraphs and code blocks the same way markdown does.

16 December 2019 UPDATE: adc sent me a patch to add ordered and unordered list. Code below contain the addition.

It is very easy to use, like: awk -f mmd file.mmd > output.html

The script is the following:

BEGIN {
	in_code=0
	in_list_unordered=0
	in_list_ordered=0
	in_paragraph=0
}
    
{
	# escape < > characters
	gsub(/</,"\<",$0);
	gsub(/>/,"\>",$0);
    
	# close code blocks
	if(! match($0,/^    /)) {
		if(in_code) {
			in_code=0
			printf "</code></pre>\n"
		}
	}
    
	# close unordered list
	if(! match($0,/^- /)) {
		if(in_list_unordered) {
			in_list_unordered=0
			printf "</ul>\n"
		}
	}
    
	# close ordered list
	if(! match($0,/^[0-9]+\. /)) {
		if(in_list_ordered) {
			in_list_ordered=0
			printf "</ol>\n"
		}
	}
    
	# display titles
	if(match($0,/^#/)) {
		if(match($0,/^(#+)/)) {
			printf "<h%i>%s</h%i>\n", RLENGTH, substr($0,index($0,$2)), RLENGTH
		}
    
	# display code blocks
	} else if(match($0,/^    /)) {
		if(in_code==0) {
			in_code=1
			printf "<pre><code>"
			print substr($0,5)
		} else {
			print substr($0,5)
		}
    
	# display unordered lists
	} else if(match($0,/^- /)) {
		if(in_list_unordered==0) {
			in_list_unordered=1
			printf "<ul>\n"
			printf "<li>%s</li>\n", substr($0,3)
		} else {
			printf "<li>%s</li>\n", substr($0,3)
		}
    
	# display ordered lists
	} else if(match($0,/^[0-9]+\. /)) {
		n=index($0," ")+1
		if(in_list_ordered==0) {
			in_list_ordered=1
			printf "<ol>\n"
			printf "<li>%s</li>\n", substr($0,n)
		} else {
			printf "<li>%s</li>\n", substr($0,n)
		}
    
	# close p if current line is empty
	} else {
		if(length($0) == 0 && in_paragraph == 1 && in_code == 0) {
			in_paragraph=0
			printf "</p>"
		} # we are still in a paragraph
		if(length($0) != 0 && in_paragraph == 1) {
			print
		} # open a p tag if previous line is empty
		if(length(previous_line)==0 && in_paragraph==0) {
			in_paragraph=1
			printf "<p>%s\n", $0
		}
	}
	previous_line = $0
}
    
END {
	if(in_code==1) {
		printf "</code></pre>\n"
	}
	if(in_list_unordered==1) {
		printf "</ul>\n"
	}
	if(in_list_ordered==1) {
		printf "</ol>\n"
	}
	if(in_paragraph==1) {
		printf "</p>\n"
	}
}