about summary refs log blame commit diff stats
path: root/adapter/format/gopher2html.nim
blob: da2dfc90ddb4a178207dd63ecd95632c9b971c28 (plain) (tree)
1
2
3
4
5
6
7
8
9



                                                

                   
                      
 
                   
 











































                                                                                   
                   

                               


















                                                               
                   























                                                                             
# This file is dedicated to the public domain.
# Gopher directory -> HTML converter for Chawan.

import std/os
import std/strutils

include ../gophertypes

import utils/twtstr

const ControlPercentEncodeSet = {char(0x00)..char(0x1F), char(0x7F)..char(0xFF)}
const QueryPercentEncodeSet = (ControlPercentEncodeSet + {' ', '"', '#', '<', '>'})
const PathPercentEncodeSet = (QueryPercentEncodeSet + {'?', '`', '{', '}'})
const HexCharsUpper = "0123456789ABCDEF"
proc percentEncode(s: string): string =
  result = ""
  for c in s:
    if c notin PathPercentEncodeSet:
      result &= c
    else:
      result &= '%'
      result &= HexCharsUpper[uint8(c) shr 4]
      result &= HexCharsUpper[uint8(c) and 0xF]

# returns URL
proc parseParams(): string =
  result = ""
  let params = commandLineParams()
  var was_u = false
  for param in params:
    if was_u:
      result = param
      was_u = false
    elif param == "-h" or param == "--help":
      stdout.write("Usage: gopher2html [-u URL]")
      quit(0)
    elif param == "-u":
      was_u = true
    else:
      stdout.write("Usage: gopher2html [-u URL]")
      quit(1)

proc main() =
  let url = parseParams()
  let escapedURL = htmlEscape(url)
  stdout.write("""
<!DOCTYPE HTML>
<HTML>
<HEAD>
<BASE HREF="""" & url & """">
<TITLE>Index of """ & escapedURL & """</TITLE>
</HEAD>
<BODY>
<H1>Index of """ & escapedURL & """</H1>""")
  var ispre = false
  while not stdin.endOfFile:
    let line = stdin.readLine()
    if line.len == 0:
      break # invalid
    let tc = line[0]
    if tc == '.':
      break # end
    var i = 1
    template get_field(): string =
      let s = line.until('\t', i)
      i += s.len
      if i >= line.len or line[i] != '\t':
        break # invalid
      inc i
      s
    let t = gopherType(tc)
    let name = get_field()
    var file = get_field()
    let host = get_field()
    let port = line.until('\t', i) # ignore anything after port
    var outs = ""
    if t == gtInfo:
      if not ispre:
        outs &= "<PRE>"
        ispre = true
      outs &= htmlEscape(name) & '\n'
    else:
      if ispre:
        outs &= "</PRE>"
        ispre = false
      let ts = $t
      var names = ""
      if ts != "":
        names &= '[' & ts & ']'
      names &= htmlEscape(name)
      let ourls = if not file.startsWith("URL:"):
        if file.len == 0 or file[0] != '/':
          file = '/' & file
        let pefile = percentEncode(file)
        "gopher://" & host & ":" & port & "/" & tc & pefile
      else:
        file.substr("URL:".len)
      outs &= "<A HREF=\"" & htmlEscape(ourls) & "\">" & names & "</A><BR>\n"
    stdout.write(outs)

main()