summaryrefslogtreecommitdiff
path: root/bin/markup
diff options
context:
space:
mode:
authorJohannes Herman <johannes.herman@gmail.com>2026-03-16 11:14:21 +0100
committerJohannes Herman <johannes.herman@gmail.com>2026-03-16 11:14:21 +0100
commitcaa30dd45d3ae76405a7f4ecc9641521c1fb8895 (patch)
tree5641956935e8ef6cb487d47456b884443e5118e8 /bin/markup
initial
Diffstat (limited to 'bin/markup')
-rwxr-xr-xbin/markup198
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(/&/, "\\&amp;")
+ gsub(/</, "\\&lt;")
+ gsub(/>/, "\\&gt;")
+ 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 ">"
+}