grapho/md2html

177 lines
3.3 KiB
Awk
Executable File

#!/usr/bin/awk -f
BEGIN {
indent = 0
prefix = "html/body/"
print("<!DOCTYPE html>")
level("html/head")
}
function headers() {
printf("%0" indent "s<meta charset=UTF-8>\n", "")
if (meta["title"]) printf("%0" indent "s<title>%s</title>\n", "", escape(meta["title"]))
if (meta["author"]) printf("%0" indent "s<meta name=author content=\"%s\">\n", "", escape(meta["author"]))
if (stylesheet) printf("%0" indent "s<link href=\"%s\" rel=stylesheet type=text/css media=all>\n", "", stylesheet)
if (javascript) printf("%0" indent "s<script src=\"/%s\"></script>\n", "", escape(javascript))
}
function oneliner(tag, str, args) {
printf("%0" indent "s<%s>%s</%s>\n", "", tag args, inline(str), tag)
}
function level(new) {
split(new, a, "/")
split(old, b, "/")
for (common = 0; common < 10; common++) {
if (common >= length(a)) break
if (common >= length(b)) break
if (a[common] != b[common]) break
}
for (i = length(b); i >= common; --i) {
if (b[i]) {
if (b[i] == "head") headers()
indent = indent - 2
if (b[i]=="pre") {
printf("</%s>\n", b[i])
} else {
printf("%0" indent "s</%s>\n", "", b[i])
}
}
}
for (i = common; i < length(a); i++) {
if (a[i]) {
printf("%0" indent "s<%s>\n", "", a[i])
indent = indent + 2
}
}
old = new
}
function escape(text) {
gsub(/&/, "\\&amp;", text)
gsub(/</, "\\&lt;", text)
gsub(/>/, "\\&gt;", text)
gsub(/\"/, "\\&quot;", text)
return text
}
function inline(text) {
text = escape(text)
text = gensub(/\*\*([^\*]*)\*\*/, "<strong>\\1</strong>", "g", text)
text = gensub(/\*([^\*]*)\*/, "<em>\\1</em>", "g", text)
text = gensub(/`([^`]*)`/, "<code>\\1</code>", "g", text)
text = gensub(/\[(.*)\]\((.*)\)/, "<a href=\"\\2\">\\1</a>", "g", text)
return text
}
/^---$/ {
parse_meta = !parse_meta
next
}
{
if(parse_meta) {
split($0, r, ": ")
gsub(/(^"|"$)/, "", r[2])
meta[r[1]]=r[2]
next
}
}
/^```/ {
if (old == prefix "pre") {
level(prefix)
} else {
level(prefix "pre")
}
next
}
{
if (old == prefix "pre") {
printf("%s\n", escape($0))
next
}
}
/^- / {
level(prefix "ul")
level(prefix "ul/li")
gsub(/^- /, "", $0)
printf("%0" indent "s%s\n", "", inline($0))
next
}
/^\s*\* / {
level(prefix "ul")
level(prefix "ul/li")
gsub(/^\s*\* /, "", $0)
printf("%0" indent "s%s\n", "", inline($0))
next
}
/^> / {
level(prefix "quote")
gsub(/^> /, "", $0)
printf("%0" indent "s%s\n", "", inline($0))
}
/^ / {
level(prefix "blockquote")
printf("%0" indent "s%s\n", "", inline($0))
}
/^ / {
if (old == prefix) level(prefix "p")
printf("%0" indent "s%s\n", "", inline($0))
next
}
/^# / {
gsub(/^#* /, "", $0)
if (!meta["title"]) meta["title"] = $0
level(prefix)
oneliner("h1", $0)
next
}
/^## / {
gsub(/^#* /, "", $0)
level(prefix)
oneliner("h2", $0)
next
}
/^### / {
gsub(/^#* /, "", $0)
level(prefix)
oneliner("h3", $0)
next
}
/^$/ {
if (old != "html/head") level(prefix)
next
}
/^!\[.*\]\(.*\)$/ {
txt = $0
filenam = $0
gsub(/(^!\[|\].*$)/, "", txt)
gsub(/(^!.*\(|\)$)/, "", filenam)
oneliner("img",""," src=\"" escape(filenam) "\" alt=\"" escape(txt) "\"")
next
}
{
level(prefix "p")
printf("%0" indent "s%s\n", "", inline($0))
next
}
END {
level("")
}