Initial commit - gopher2html - AWK script that converts a Gopher response to HTML
 (HTM) hg clone https://bitbucket.org/iamleot/gopher2html
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) changeset c314b6f4148185f1f024e0a343be661bfe93d52b
 (HTM) Author: Leonardo Taccari <iamleot@gmail.com>
       Date:   Sun, 14 Jan 2018 22:16:39 
       
       Initial commit
       
       Diffstat:
        gopher2html.awk |  97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        1 files changed, 97 insertions(+), 0 deletions(-)
       ---
       diff -r 000000000000 -r c314b6f41481 gopher2html.awk
       --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
       +++ b/gopher2html.awk   Sun Jan 14 22:16:39 2018 +0100
       @@ -0,0 +1,97 @@
       +#!/usr/bin/awk -f
       +
       +function urlize(type, selector, host, port)
       +{
       +
       +       return "gopher://" host ":" port "/" type selector
       +}
       +
       +function encode(html)
       +{
       +
       +       gsub(/&/, "\\&amp;", html)
       +       gsub(/</, "\\&lt;", html)
       +       gsub(/>/, "\\&gt;", html)
       +
       +       return html
       +}
       +
       +BEGIN {
       +       FS = "\t"
       +       # XXX: Strictly speaking RS should be `\r\n'. However, in the wild it
       +       # XXX: can happens that the `\r' is missing. Address that and then strip
       +       # XXX: trailing `\r' when parsing responses.
       +       RS = "\n"
       +
       +       TYPE["file"] = "0"
       +       TYPE["directory"] = "1"
       +       TYPE["error"] = "3"
       +       TYPE["search"] = "7"
       +       TYPE["html"] = "h"
       +       TYPE["info"] = "i"
       +       TYPE["picture"] = "p"
       +       TYPE["sound"] = "s"
       +
       +       # Print the header
       +       print "<html>"
       +       print "<body>"
       +       print "<pre>"
       +}
       +
       +{
       +       sub(/^\r/, "")
       +       sub(/\r$/, "")
       +
       +       type = substr($1, 1, 1)
       +       user_name = substr($1, 2)
       +       selector = $2
       +       host = $3
       +       port = $4
       +}
       +
       +$0 == "." {
       +       # (nothing)
       +       next
       +}
       +
       +# Text entry (euristically!)
       +NF != 4 {
       +       printf("%s\n", encode($0))
       +       next
       +}
       +
       +type == TYPE["file"] || type == TYPE["directory"] {
       +       printf("<a href='%s'>%s</a>\n", urlize(type, selector, host, port), encode(user_name))
       +}
       +
       +type == TYPE["error"] {
       +       # TODO
       +}
       +
       +type == TYPE["search"] {
       +       printf("<form action='%s'>", urlize(type, selector, host, port))
       +       printf("<input type='text' />")
       +       printf("<input type='submit' />")
       +       printf("</form>\n")
       +}
       +
       +type == TYPE["info"] {
       +       printf("%s\n", encode(user_name))
       +}
       +
       +type == TYPE["html"] {
       +       url = substr(selector, 5)       # strip `URL:' prefix
       +       printf("<a href='%s'>%s</a>\n", url, encode(user_name))
       +}
       +
       +type == TYPE["picture"] {
       +       printf("<img src='%s' alt='%s' />\n",
       +          urlize(type, selector, host, port), user_name)
       +}
       +
       +END {
       +       # Print the footer
       +       print "</pre>"
       +       print "</body>"
       +       print "</html>"
       +}