About me: My name is Solène Rapenne. I like learning and sharing my knowledge related to IT stuff. Hobbies: '(BSD OpenBSD h+ Lisp cmdline gaming internet-stuff). I love percent and lambda characters. OpenBSD developer solene@.

Contact me: solene on Freenode, solene+www at dataswamp dot org or solene@bsd.network (mastodon). If for some reason you want to give me some money, I accept paypal at the 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 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"
    }
}