summary refs log blame commit diff stats
path: root/gmi2html.awk
blob: cba6c20b10f40b25e182e86cce3f7e7869d8c0e8 (plain) (tree)
1
2
3
4

                                                                            
 
                                                         














                                                                                       
        


                           
                                                           
 


                                                                
                                                                         


                     







                                                                        
                   
 
           
































                                           
                    




                        
 












                            
 






                            
 






                            
 






                            
 
                                            






                           
            

                            
             















                                                                                  
                                                    
















                                                             








                                                     
                  
 
#
# 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
}