diff options
Diffstat (limited to 'bin/markup')
| -rwxr-xr-x | bin/markup | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/bin/markup b/bin/markup new file mode 100755 index 0000000..5b2ca88 --- /dev/null +++ b/bin/markup @@ -0,0 +1,198 @@ +#!/bin/gawk -f + +BEGIN { + list = "" + quote = 0 + code = 0 +} + +function handle_meta( i, n, cats, link) +{ + if ($0 ~ /^; /) { + if (meta_count == 0) { + } else if (meta_count == 1) { + sub(/^; /, "") + n = split($0, cats, " ") + printf "<nav class=\"categories\">" + printf "#<a class=\"category\" href=\"/writings/\">all</a> " + for (i = 1; i <= n; i++) { + link = "/writings/" cats[i] + printf "<a class=\"category\" href=\"" link "\">#" cats[i] "</a> " + } + print "</nav>" + } else if (meta_count == 2) { + sub(/^; /, "") + print "<p class=\"date\">" $0 "</p>" + } + meta_count++ + next + } +} +function handle_list_item(condition, type) +{ + if ($0 ~ condition) { + if (list != type) { + if (list != "") print "</" list ">" + print "<" type ">" + list = type + } + sub(condition, "") + print "<li>" $0 "</li>" + next + } +} + +function handle_quote() +{ + if ($0 == "\"\"\"") { + if (quote == 0) { + print "<blockquote>" + quote = 1 + } else { + print "</blockquote>" + quote = 0 + } + next + } +} + +function handle_codeblock() +{ + if ($0 ~ /^'''/) { + if (code == 0) { + if (list != "") { + print "</" list ">" + list = "" + } + print "<pre><code>" + code = 1 + } else { + print "</code></pre>" + code = 0 + } + next + } + + if (code == 1) { + gsub(/&/, "\\&") + gsub(/</, "\\<") + gsub(/>/, "\\>") + print + next + } +} + +function inline(delim, tag, escaped, pattern) +{ + escaped = delim + gsub(/\*/, "\\*", escaped) + gsub(/\./, "\\.", escaped) + + pattern = escaped "([^" escaped "]+)" escaped + while (match($0, pattern)) { + $0 = substr($0, 1, RSTART-1) \ + "<" tag ">" substr($0, RSTART+length(delim), \ + RLENGTH-length(delim)*2) "</" tag ">" \ + substr($0, RSTART+RLENGTH) + } +} + +function inline_link(pattern, result, pre, arr) +{ + pattern = "\\[([^]]+)\\]\\(([^)]+)\\)" + result = "" + while (match($0, pattern, arr)) { + pre = substr($0, 1, RSTART-1) + result = result pre "<a href=\"" arr[2] "\">" arr[1] "</a>" + $0 = substr($0, RSTART+RLENGTH) + } + $0 = result $0 +} + +function inline_image(pattern, result, pre, arr) +{ + pattern = "!\\[([^]]+)\\]\\(([^)]+)\\)" + result = "" + while (match($0, pattern, arr)) { + pre = substr($0, 1, RSTART-1) + result = result pre "<a href=\"" arr[2] "\">" "<img alt=\"" \ + arr[1] "\" src=\"" arr[2] "\">" "</a>" + $0 = substr($0, RSTART+RLENGTH) + } + $0 = result $0 +} + +function inline_footnote_ref(pattern, result, pre, arr) +{ + pattern = ".\\[\\^([^]]+)\\]" + result = "" + while (match($0, pattern, arr)) { + pre = substr($0, 1, RSTART) + result = result pre "<sup id=\"fnref-" \ + arr[1] "\"><a href=\"#fn-" arr[1] "\">" arr[1] "</a></sup>" + $0 = substr($0, RSTART+RLENGTH) + } + $0 = result $0 +} + +function handle_header(i, level) +{ + if ($0 ~ /^#+[ ]/) { + level = 0 + while (substr($0, level+1, 1) == "#") level++ + sub(/^#+[ ]+/, "") + print "<h" level ">" $0 "</h" level ">" + next + } +} + +function handle_footnote(pattern, arr) +{ + pattern = "^\\[\\^([^]]+)\\]:[ ]*(.*)" + if (match($0, pattern, arr)) { + if (footnote != 1) { + print "<ol class=\"footnotes\">" + footnote = 1 + } + print "<li id=\"fn-" arr[1] "\">" arr[2] \ + "<a href=\"#fnref-" arr[1] "\">↩</a></li>" + list = "ol" + next + } +} + +{ + handle_meta() + handle_quote() + handle_codeblock() + + inline("**", "b") + inline("*", "em") + inline("--", "s") + inline("'''", "code") + + inline_image() + inline_link() + + inline_footnote_ref() + + handle_list_item("^- ", "ul") + handle_list_item("^[0-9]+\\.[ ]+", "ol") + handle_footnote() + + if (list != "") { + print "</" list ">" + list = "" + } + + handle_header() + + if ($0 != "") { + print "<p>" $0 "</p>" + } +} + +END { + if (list != "") + print "</" list ">" +} |
