#!/bin/awk -f
# aux/emparse -- parse em source
function beginblock(name) {
if (name == "nl") printf "
\n"
else printf "<%s>\n", name
}
function endblock(name) {
if (name == "nl") printf "
\n"
else printf "%s>\n", name
}
function newblock(name) {
beginblock(name)
openblock = name
openitem = 0
expectblock = 0
}
function breakblock() {
if (openitem) {
printf "\n"
while (itemlevel-- > 1)
endblock(openblock)
itemlevel = 1
}
if (opendef) printf "\n"
if (openblock) endblock(openblock)
openitem = 0
opendef = 0
openblock = 0
expectblock = 1
}
function heading(level, line) {
sub("^=* ", "", line)
sub(" =*$", "", line)
printf "%s\n", level, line, level
# should inline formatting be supported in headings?
}
function item(level, type, line) {
if (openitem) printf ""
openitem = 1
if (level > itemlevel) printf "\n"
if (level < itemlevel) printf "
\n"
itemlevel = level
if (type == "ul") {
sub("^ +- ", "")
printf ""
}
if (type == "ol") {
match($0, "[0-9a-z]+\.")
v = substr($0, RSTART, RLENGTH-1)
sub("^ +[0-9a-z]+\. ", "")
printf "", v
}
if (type == "nl") {
match($0, "\\[[0-9a-z]+\\]")
v = substr($0, RSTART+1, RLENGTH-2)
sub("^ +\\[[0-9a-z]+\\] ", "")
printf "", v, v
}
}
function term(line, t) { # t is a local variable
if (opendef) printf ""
opendef = 1
t = $0; d = $0
sub("^ ", "", t)
sub(": .*$", "", t)
sub("^ [^:]+: ", "")
printf "%s", t
}
function ref(v) {
if (ENVIRON["ref" v] != "")
return "(" linktext ")"
else
return "[" v "]"
}
function format(line) {
n = split(line, w, "[ ]")
for (i = 0; i <= n; i++) {
if (w[i] == "") continue;
if (match(w[i], "^\\[[0-9a-z]+\\]$"))
w[i] = ref(substr(w[i], 2, RLENGTH-2))
else if (match(w[i], "^\\[[0-9a-z]+\\][.,:;?!)]$"))
w[i] = ref(substr(w[i], 2, RLENGTH-3)) substr(w[i], RLENGTH)
else if (match(w[i], "^\\[[0-9a-z]+\\]\\)[.,:;?!]$"))
w[i] = ref(substr(w[i], 2, RLENGTH-4)) substr(w[i], RLENGTH-1)
if (match(w[i], "^`"))
w[i] = "" substr(w[i], 2)
else if (match(w[i], "^\\*"))
w[i] = "" substr(w[i], 2)
else if (match(w[i], "^_"))
w[i] = "" substr(w[i], 2)
else if (match(w[i], "^\\(`"))
w[i] = "(" substr(w[i], 3)
else if (match(w[i], "^\\(\\*"))
w[i] = "(" substr(w[i], 3)
else if (match(w[i], "^\\(_"))
w[i] = "(" substr(w[i], 3)
if (match(w[i], "`$"))
w[i] = substr(w[i], 1, RSTART-1) ""
else if (match(w[i], "\\*$"))
w[i] = substr(w[i], 1, RSTART-1) ""
else if (match(w[i], "_$"))
w[i] = substr(w[i], 1, RSTART-1) ""
else if (match(w[i], "`[.,:;?!)]$"))
w[i] = substr(w[i], 1, RSTART-1) "" substr(w[i], RSTART+1)
else if (match(w[i], "\\*[.,:;?!)]$"))
w[i] = substr(w[i], 1, RSTART-1) "" substr(w[i], RSTART+1)
else if (match(w[i], "_[.,:;?!)]$"))
w[i] = substr(w[i], 1, RSTART-1) "" substr(w[i], RSTART+1)
else if (match(w[i], "`\\)[.,:;?!]$"))
w[i] = substr(w[i], 1, RSTART-1) "" substr(w[i], RSTART+1)
else if (match(w[i], "\\*\\)[.,:;?!]$"))
w[i] = substr(w[i], 1, RSTART-1) "" substr(w[i], RSTART+1)
else if (match(w[i], "_\\)[.,:;?!]$"))
w[i] = substr(w[i], 1, RSTART-1) "" substr(w[i], RSTART+1)
printf "%s", w[i]
if (i < n) printf " "
}
printf "\n"
}
BEGIN {
expectblock = 1
itemlevel = 1
linktext = ENVIRON["linktext"]
if (!linktext) linktext = "link"
}
END { breakblock() }
/^$/ { breakblock(); getline }
expectblock && /^ / { newblock("table") }
expectblock && /^ - / { newblock("ul") }
expectblock && /^ [0-9a-z]+\. / { newblock("ol") }
expectblock && /^ \[[0-9a-z]\]+ / { newblock("nl") }
expectblock && /^ .*: / { newblock("dl") }
expectblock && /^ / { newblock("pre"); sub("^ ", "") }
expectblock && /^---$/ { expectblock = 0; printf "
\n"; next }
expectblock && /^= .* =$/ { heading(1, $0); next }
expectblock && /^== .* ==$/ { heading(3, $0); next }
expectblock && /^=== .* ===$/ { heading(3, $0); next }
expectblock && /^==== .* ====$/ { heading(4, $0); next }
expectblock && /^===== .* =====$/ { heading(5, $0); next }
expectblock && /^====== .* ======$/ { heading(6, $0); next }
expectblock { newblock("p") }
block = "ul" && /^ - / { item(1, "ul", line) }
block = "ol" && /^ [0-9a-z]+\. / { item(1, "ol", line) }
block = "nl" && /^ \[[0-9a-z]\]+ [^ ]+$/ { next } # hyperlink reference
block = "nl" && /^ \[[0-9a-z]\]+ / { item(1, "nl", line) } # text reference
block = "dl" && /^ .*: / { term(line) }
block = "ul" && /^ -/ { item(2, "ul", line) }
block = "ol" && /^ [0-9a-z]+\./ { item(2, "ol", line) }
block = "ul" && /^ -/ { item(3, "ul", line) }
block = "ol" && /^ [0-9a-z]+\./ { item(3, "ol", line) }
block = "ul" && /^ -/ { item(4, "ul", line) }
block = "ol" && /^ [0-9a-z]+\./ { item(4, "ol", line) }
block = "ul" && /^ -/ { item(5, "ul", line) }
block = "ol" && /^ [0-9a-z]+\./ { item(5, "ol", line) }
block = "ul" && /^ -/ { item(6, "ul", line) }
block = "ol" && /^ [0-9a-z]+\./ { item(6, "ol", line) }
block = "pre" && /^ / { sub("^ ", ""); printf "%s\n", $0; next }
{ format($0) }