local curses = require "curses" local md = require "mdparse" local socket = require "socket" local surl = require "socket.url" local sx,sy,pc = 80, 25, "@" local function pgopher(gm) local s = "" for line in gm:gmatch("[^\n]+") do local t = line:sub(1,1) if t == "i" then if line:find("\t") then line=line:sub(1,line:find("\t")) end s=s..line:sub(2).."\n" elseif t == "0" or t == "1" then line=line:gsub("(.)(.+)\t/?([%w%./]+)\t([%w%.]+)\t(%d+)","%1 [%2](gopher://%4:%5/%3")..")" -- we gsub now line=line:gsub("\n","") s=s..line.."\n" else s=s..line.."\n" end end return s end local function geturl(url) local ds = {} ds.scheme = "gopher" ds.port = "70" ds.path = "" local c = "" local ourl = url tURL = surl.parse(url,ds) if not tURL.host then tURL.host = tURL.path tURL.path = "" end local dn, po, pt = tURL.host, tURL.port, tURL.path print(dn,po,pt) if dn and po then local s=socket.tcp() s:connect(dn,po) s:send(pt.."\n") c=s:receive("*a") s:close() local w,tpg = pcall(pgopher,c) if w then print(tpg) c=tpg end else c="Unable to load URL "..ourl end --[[-- else local f=io.open(url,"rb") if not f then return "\r\nPage could not be loaded." end c=f:read("*a") print(c) f:close() end --]]-- return c end local function settings() while true do local scr = curses.initscr () curses.cbreak () curses.echo (false) -- not noecho ! curses.nl (false) -- not nonl ! local selection = 1 while true do local menu = {"Screen width: "..tostring(sx),"Screen height: "..tostring(sy),"Back"} scr:clear() scr:refresh() for k,v in ipairs(menu) do if k == selection then io.write(" * ") end print("\t"..v.."\r") end local ch = scr:getch() if ch == 66 then selection = selection + 1 elseif ch == 65 then selection = selection - 1 elseif ch == 13 then break end if selection > #menu then selection = #menu elseif selection < 1 then selection = 1 end end if selection == 1 then scr:clear() scr:refresh() scr:addstr("New screen width: ") curses.echo (true) scr:refresh() sx = tonumber(scr:getstr()) or 80 curses.echo (false) elseif selection == 2 then scr:clear() scr:refresh() scr:addstr("New screen height: ") curses.echo (true) scr:refresh() sy = tonumber(scr:getstr()) or 80 curses.echo (false) else scr:close() break end end end local function main () local scr = curses.initscr () local mode = 1 local p = false local sc = "#" local history = {} curses.cbreak () curses.echo(false) -- not noecho ! curses.nl(false) -- not nonl ! cy = 1 local ts = [[ **SKS Markdown Gopher Client** See the [SKS gopher hole](gopher://shadowkat.net) for more info. Use *f* to follow a link, *o* to open a URL directly, *j* and *k* to scroll, and *s* for settings. Scrolling test: a b c d e f g h i j k l m n o p q r s t u v w x y z]] local url = "homepage" local lt = {} while true do scr:clear() scr:refresh() local ds = "" local dt = {} lt = md.parse(ts).l for k,v in ipairs(md.parse(ts)) do --[[-- if v.bold then -- note to self: fix bold v.content = "\27[n1"..v.content.."\27[n0" end --]]-- if v.addrid then ds=ds.."["..tostring(v.addrid).."]"..v.content else ds=ds..v.content end end for line in ds:gmatch("[^\n]*") do while line:len() > 0 do dt[#dt+1] = line:sub(1,sx) line = line:sub(sx+1) end end if sy < #dt then ms = sy else ms = #dt end for i = cy, cy+ms do io.write((dt[i] or "").."\r\n") end print("\r\n["..url.." "..tostring(cy).."/"..tostring(#dt).." "..tostring(ts:len()).."]\r") ch = scr:getch() or 0 if ch < 256 then if string.char(ch) == "q" then break elseif string.char(ch) == "s" then settings() elseif string.char(ch) == "o" then scr:addstr("\rURL: ") curses.echo(true) scr:refresh() local nurl = scr:getstr() local w,nts=pcall(geturl,nurl) --print(w,nts) if w then ts = nts url=nurl end local nurl = scr:getstr() elseif string.char(ch) == "f" then scr:addstr("\rLink: ") curses.echo(true) scr:refresh() local nurl = lt[tonumber(scr:getstr())] local w,nts=pcall(geturl,nurl) if w then ts = nts url=nurl end scr:refresh() elseif string.char(ch) == "j" then if cy < #dt then cy = cy + 1 end elseif string.char(ch) == "k" then if cy > 1 then cy = cy - 1 end end end end end local function err (err) curses.endwin () print "Caught an error:" print (debug.traceback (err, 2)) os.exit (2) end xpcall (main, err)