about summary refs log tree commit diff stats
path: root/ht.awk
blob: 53283618d9bcdaeb72f1df9a1aa29b462a4006a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/awk -f
# HAT TRICK
# (C) 2022 C. Duckworth

# ht.awk converts mostly-html (with some conveniences) to actual html

function bufpush(s) {
    BUF = BUF (BUF ? "\n" : "") s;
}

function buflush() {
    if (BUF) print BUF;
    BUF = "";
    if (tag && (tag != "html")) print "</" tag ">";
}

function esc(t) {
    gsub(/&/, "\\&amp;", t);
    gsub(/</, "\\&lt;", t);
    gsub(/>/, "\\&gt;", t);
    return t;
}

/^;/ { sub(/^;/,""); print "<!--", esc($0), "-->"; next; }

/^</ { # Raw HTML
    if (! (tag == "html")) tag = "html";
    bufpush($0);
    next;
}

/^=>/ { # Links (Gemini-style)
    link = "<a href=\"" esc($2) "\">" esc($3);
    for (i=4;i<=NF;i++) link = link " " esc($i);
    link = link "</a>";
    bufpush(link);
    next;
}

/^-/ { # Unordered lists
    if (! (tag == "ul")) tag = "ul";
    esc($0);
    sub(/^-[ \t]*/, "<li>");
}

/^[0-9]+\./ { # Ordered lists
    if (! (tag == "ol")) tag = "ol";
    esc($0);
    sub(/^[0-9]+\.[ \t]/, "<li>");
}

/^>/ { # Blockquotes
    if (! (tag == "blockquote")) tag = "blockquote";
    sub(/^>[ \t]*/,"");
    esc($0);
}

/^#+/ { # Headers
    match($0, /^#+/);
    if (! (tag == "h" RLENGTH)) {
        buflush();
        tag = "h" RLENGTH;
    }
    sub(/^#+[ \t]*/,"");
    esc($0);
}

/^$/ {
    buflush();
    tag = "";
}

/./ {
    if (! tag) tag = "p";
    if (! BUF) bufpush("<" tag ">");
    bufpush($0);
}

END { buflush(); }