added mdbrowse and mdparse.

This commit is contained in:
Izaya 2017-11-22 02:36:20 +11:00
父節點 555081ca98
當前提交 b54cf24294
共有 3 個文件被更改,包括 308 次插入1 次删除

查看文件

@ -1,3 +1,15 @@
# mdgopher
Gopher + Markdown. Kinda defeats the purpose but hey whatever.
Gopher + Markdown. Kinda defeats the purpose but hey whatever.
## mdbrowse
A terrible lua-curses and luasocket based markdown browser.
Gopher menu support is experimental but markdown support should work fairly well.
### keybinds
- j and k for scrolling
- f to follow a link (marked by a [number])
- o to open a URL
- s for settings (terminal size and etc.)
- q to quit

245
mdbrowse.lua Normal file
查看文件

@ -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)

50
mdparse.lua Normal file
查看文件

@ -0,0 +1,50 @@
local md = {}
function md.parse(md)
local it = {}
it.l = {}
it[#it+1] = {["content"]="",["bold"]=false,["italic"]=false}
local lc,llc = "",""
local function newpart()
it[#it+1] = {["content"]="",["bold"]=it[#it].bold,["italic"]=it[#it].italic}
end
newpart()
local lm = false
for c in md:gmatch(".") do
if c == "*" then
if lc == "*" then
it[#it].italic = false
it[#it].italic = it[#it-1].italic
it[#it].bold = not it[#it].bold
else
newpart()
it[#it].italic = not it[#it].italic
end
elseif c == "[" then
newpart()
elseif c == "(" and lc == "]" then
lm = true
it[#it].content = it[#it].content:sub(1,-2)
it[#it].address = ""
elseif c == ")" and lm then
lm = false
it.l[#it.l+1] = it[#it].address
it[#it].addrid = #it.l
newpart()
else
if not lm then
it[#it].content = it[#it].content .. c
else
it[#it].address = it[#it].address .. c
end
end
llc = lc
lc = c
end
for k,v in pairs(it) do
if v.content then
v.content = v.content:gsub("\n","\r\n")
end
end
return it
end
return md