267 lines
5.1 KiB
Bash
Executable File
267 lines
5.1 KiB
Bash
Executable File
#!/bin/sh
|
|
tmpfile=".$$.$1.md2html"
|
|
|
|
awk "$@" '
|
|
BEGIN {
|
|
indent = 0
|
|
prefix = "html/body/"
|
|
print("<!DOCTYPE html>")
|
|
level("html/head")
|
|
toc=0
|
|
}
|
|
|
|
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(/&/, "\\&", text)
|
|
gsub(/</, "\\<", text)
|
|
gsub(/>/, "\\>", text)
|
|
gsub(/\"/, "\\"", 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
|
|
}
|
|
|
|
/^##* / {
|
|
d=length($1)
|
|
gsub(/^#* /, "", $0)
|
|
if (d==1 && !meta["title"]) meta["title"] = $0
|
|
if (d!=1 && toc==0) {
|
|
level(prefix "summary")
|
|
level(prefix)
|
|
toc=1
|
|
}
|
|
id1=$0
|
|
gsub(/[^a-zA-Z0-9]/, "", id1)
|
|
hash[d]=id1
|
|
id = ""
|
|
for (i = 2; i <= d; i++) {
|
|
id = id hash[i]
|
|
}
|
|
if (id != "") id = " id=\"" escape(id) "\""
|
|
level(prefix)
|
|
oneliner("h"d, $0, id)
|
|
next
|
|
}
|
|
|
|
/^$/ {
|
|
if (old != "html/head") level(prefix)
|
|
next
|
|
}
|
|
|
|
/^!\[.*\]\(.*\)$/ {
|
|
txt = $0
|
|
filenam = $0
|
|
gsub(/(^!\[|\].*$)/, "", txt)
|
|
gsub(/(^!.*\(|\)$)/, "", filenam)
|
|
level(prefix "figure")
|
|
oneliner("img",""," src=\"" escape(filenam) "\" alt=\"" escape(txt) "\"")
|
|
oneliner("figcaption", txt, "")
|
|
next
|
|
}
|
|
|
|
{
|
|
level(prefix "p")
|
|
printf("%0" indent "s%s\n", "", inline($0))
|
|
next
|
|
}
|
|
END {
|
|
level("")
|
|
}' > "$tmpfile"
|
|
|
|
|
|
sed -n '/<summary>/!p;//q' "$tmpfile"
|
|
|
|
awk '
|
|
BEGIN {
|
|
indent = 4
|
|
level("summary")
|
|
}
|
|
|
|
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]) {
|
|
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(/&/, "\\&", text)
|
|
gsub(/</, "\\<", text)
|
|
gsub(/>/, "\\>", text)
|
|
gsub(/\"/, "\\"", 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
|
|
}
|
|
|
|
/<h[2-6] / {
|
|
id=$0
|
|
gsub(/^.*id=\"/,"",id)
|
|
gsub(/\">.*$/,"",id)
|
|
d=$1
|
|
gsub(/^<h/, "", d)
|
|
gsub(/ *<[^>]*>/, "", $0)
|
|
trg="summary/ul"
|
|
for(i=2;i<d;i++) trg=trg "/li/ul"
|
|
level(trg)
|
|
level(trg "/li")
|
|
oneliner("a", $0, " href=\"#" id "\"")
|
|
}
|
|
|
|
END {
|
|
level("")
|
|
}
|
|
' < "$tmpfile"
|
|
|
|
sed -e '1,/<\/summary>/ d' "$tmpfile"
|
|
|
|
rm "$tmpfile"
|