|
|
@@ -0,0 +1,245 @@ |
|
|
|
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) |