summary refs log tree commit diff stats
path: root/gmi2html.awk
blob: cba6c20b10f40b25e182e86cce3f7e7869d8c0e8 (plain) (blame)
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#
# gmi2html.awk -- AWK script to convert a file from text/gemini to text/html
#
# Copyright (c) 2021 Rodrigo S. Canibano (dracometallium)
# Copyright (c) 2021 Jeremy Potter (jwinnie)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# usage:
#   $ awk -f gmi2html.awk \
#       -v title=<title> \
#       -v css=<css> \
#       -v original=<original> < path/to/gmi > path/to/html
#
# parameters:
#   <title>: the title of the document, used in the HTML <title>
#   <css>: relative path to a CSS stylesheet
#   <original>: URL of the original Gemini document, linked in the footer

# Begin HTML document
BEGIN {
    printf "\
<!DOCTYPE html>\
<head>\
<meta charset=\"utf-8\">\
<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\
<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\">\
<title>%s</title>\
</head>\
<body>", css, title

    pre = 0
    list = 0
}

# Escape left and right angle brackets
{
    gsub(/</, "\\&lt;")
    gsub(/>/, "\\&gt;")
}

# Detect beginning of code block
/^```/ && (pre == 0) {
    pre = 1
    printf "<pre><code>"
    next
}

# Detect end of code block
/^```/ && (pre == 1) {
    pre = 0
    printf "</code></pre>"
    next
}

# Output verbatim text inside of code block
(pre == 1) {
    print $0
    next
}

# Detect list item
/\* / {
    # Detect if this is the first item in
    # the list. If so, start a new <ul>.
    if (list == 0) {
        list = 1
        printf "<ul>"
    }

    sub(/\* [ \t]*/, "")

    printf "<li>%s</li>", $0
    next
}

# Detect end of list
(list == 1) {
    list = 0
    printf "</ul>"
}

# Detect heading 3
/^###/ {
    sub(/^#[#]*[ \t]*/, "")

    printf "<h3>%s</h3>", $0
    next
}

# Detect heading 2
/^##/ {
    sub(/^#[#]*[ \t]*/, "")

    printf "<h2>%s</h2>", $0
    next
}

# Detect heading 1
/^#/ {
    sub(/^#[#]*[ \t]*/, "")

    printf "<h1>%s</h1>", $0
    next
}

# Detect blockquote
/^&gt;/ {
    sub(/^&gt;[ \t]*/, "")

    printf "<blockquote>%s</blockquote>", $0
    next
}

# Detect link
/^=&gt;/ {
    sub(/^=&gt;[ \t]*/, "")

    url = $0
    sub(/[ \t].*$/, "", url)

    text = $0
    sub(url, "", text)
    sub(/[ \t]*$/, "", text)
    sub(/^[ \t]*/, "", text)

    # If linking to a Gemini page, change the extension from
    # .gmi to .html
    if ((url !~ /^[a-zA-Z]*:\/\//) && ((url ~ /\.gmi$/) || (url ~ /\.gemini$/))) {
        sub(/\.gmi$/, ".html", url)
        sub(/\.gemini$/, ".html", url)
    }

    # Show URL if no link text is provided
    if (text == "") {
        text = url
    }

    printf "<p><a href=\"%s\">%s</a></p>", url, text
    next
}

# For everything else, just use a <p> element
{
    printf "<p>%s</p>", $0
}

# End HTML document
END {
    # End all the remaining lists
    if (list == 1) {
        printf "</ul>"
    }

    # Add a footer pointing back to the original Gemini site,
    # and advertising Gemini as a better protocol
    printf "\
<hr>\
<footer>\
<small>\
Also available on <a href=\"gemini://%s\">Gemini</a>\
&mdash; a simpler, more secure World Wide Web.\
</small>\
</footer>\
</body>\
</html>", original
}