gemini: links
This commit is contained in:
parent
712d80e48a
commit
a9e400bbb4
120
gemini.tlv
120
gemini.tlv
|
@ -177,12 +177,49 @@
|
||||||
> window:addstr(line[i])
|
> window:addstr(line[i])
|
||||||
> end
|
> end
|
||||||
>end
|
>end
|
||||||
|
- __teliva_timestamp: original
|
||||||
|
render_link:
|
||||||
|
>function render_link(window, y, line)
|
||||||
|
> local rendered_line = string.gsub(line, '=>%s*%S*%s*', '')
|
||||||
|
> if trim(rendered_line) == '' then
|
||||||
|
> rendered_line = line
|
||||||
|
> end
|
||||||
|
> render_line(window, y, rendered_line)
|
||||||
|
>end
|
||||||
|
- __teliva_timestamp: original
|
||||||
|
state:
|
||||||
|
>state = {
|
||||||
|
> lines={},
|
||||||
|
> highlight_index=0,
|
||||||
|
> source=false, -- show source (link urls, etc.)
|
||||||
|
>}
|
||||||
- __teliva_timestamp: original
|
- __teliva_timestamp: original
|
||||||
render_page:
|
render_page:
|
||||||
>function render_page(window, lines)
|
>function render_page(window)
|
||||||
> local y = 0
|
> local y = 0
|
||||||
> for _, line in pairs(lines) do
|
> window:attron(curses.color_pair(6))
|
||||||
> render_line(window, y, line)
|
> print(state.url)
|
||||||
|
> window:attroff(curses.color_pair(6))
|
||||||
|
> y = y+2
|
||||||
|
>--? dbg(window, state.highlight_index)
|
||||||
|
> for i, line in pairs(state.lines) do
|
||||||
|
> if not state.source and string.find(line, '=> ') == 1 then
|
||||||
|
> if state.highlight_index == 0 or i == state.highlight_index then
|
||||||
|
> -- highlighted link
|
||||||
|
> state.highlight_index = i -- TODO: ugly state update while rendering, just for first render after gemini_get
|
||||||
|
> curses.attron(curses.A_REVERSE)
|
||||||
|
> render_link(window, y, line)
|
||||||
|
> curses.attroff(curses.A_REVERSE)
|
||||||
|
> else
|
||||||
|
> -- link
|
||||||
|
> curses.attron(curses.A_BOLD)
|
||||||
|
> render_link(window, y, line)
|
||||||
|
> curses.attroff(curses.A_BOLD)
|
||||||
|
> end
|
||||||
|
> else
|
||||||
|
> -- non-link
|
||||||
|
> render_line(window, y, line)
|
||||||
|
> end
|
||||||
> y = y+1
|
> y = y+1
|
||||||
> end
|
> end
|
||||||
>end
|
>end
|
||||||
|
@ -197,7 +234,9 @@
|
||||||
- __teliva_timestamp: original
|
- __teliva_timestamp: original
|
||||||
menu:
|
menu:
|
||||||
>menu = {}
|
>menu = {}
|
||||||
>menu['^g'] = 'go'
|
>menu['^g'] = 'enter url'
|
||||||
|
>menu['enter'] = 'go to highlight'
|
||||||
|
>menu['^u'] = 'view source'
|
||||||
- __teliva_timestamp: original
|
- __teliva_timestamp: original
|
||||||
edit_line:
|
edit_line:
|
||||||
>function edit_line(window)
|
>function edit_line(window)
|
||||||
|
@ -241,11 +280,51 @@
|
||||||
> end
|
> end
|
||||||
> end
|
> end
|
||||||
>end
|
>end
|
||||||
|
- __teliva_timestamp: original
|
||||||
|
is_link:
|
||||||
|
>function is_link(line)
|
||||||
|
> return string.find(line, '=>%s*%S*%s*') == 1
|
||||||
|
>end
|
||||||
|
- __teliva_timestamp: original
|
||||||
|
next_link:
|
||||||
|
>function next_link()
|
||||||
|
> local new_index = state.highlight_index
|
||||||
|
> while true do
|
||||||
|
> new_index = new_index+1
|
||||||
|
> if new_index > #state.lines then return end
|
||||||
|
> if is_link(state.lines[new_index]) then break end
|
||||||
|
> end
|
||||||
|
> state.highlight_index = new_index
|
||||||
|
>end
|
||||||
|
- __teliva_timestamp: original
|
||||||
|
previous_link:
|
||||||
|
>function previous_link()
|
||||||
|
> local new_index = state.highlight_index
|
||||||
|
> while true do
|
||||||
|
> new_index = new_index - 1
|
||||||
|
> if new_index < 1 then return end
|
||||||
|
> if is_link(state.lines[new_index]) then break end
|
||||||
|
> end
|
||||||
|
> state.highlight_index = new_index
|
||||||
|
>end
|
||||||
- __teliva_timestamp: original
|
- __teliva_timestamp: original
|
||||||
update:
|
update:
|
||||||
>function update(window, lines)
|
>function update(window)
|
||||||
> local key = curses.getch()
|
> local key = curses.getch()
|
||||||
> local screen_rows, screen_cols = window:getmaxyx()
|
> local screen_rows, screen_cols = window:getmaxyx()
|
||||||
|
> if key == 258 then -- down arrow
|
||||||
|
> next_link()
|
||||||
|
> end
|
||||||
|
> if key == 259 then -- up arrow
|
||||||
|
> previous_link()
|
||||||
|
> end
|
||||||
|
> if key == 21 then -- ctrl-u
|
||||||
|
> state.source = not state.source
|
||||||
|
> end
|
||||||
|
> if key == 10 then -- enter
|
||||||
|
> local s, e, new_url = string.find(state.lines[state.highlight_index], '=>%s*(%S*)')
|
||||||
|
> gemini_get(url.absolute(state.url, new_url))
|
||||||
|
> end
|
||||||
> if key == 7 then -- ctrl-g
|
> if key == 7 then -- ctrl-g
|
||||||
> window:mvaddstr(screen_rows-2, 0, '')
|
> window:mvaddstr(screen_rows-2, 0, '')
|
||||||
> window:clrtoeol()
|
> window:clrtoeol()
|
||||||
|
@ -255,8 +334,8 @@
|
||||||
> curses.curs_set(2)
|
> curses.curs_set(2)
|
||||||
> local new_url = edit_line(window)
|
> local new_url = edit_line(window)
|
||||||
> if new_url then
|
> if new_url then
|
||||||
> local new_lines = gemini_get(new_url)
|
> state.url = new_url
|
||||||
> zap(lines, new_lines)
|
> gemini_get(new_url)
|
||||||
> end
|
> end
|
||||||
> curses.curs_set(0)
|
> curses.curs_set(0)
|
||||||
> end
|
> end
|
||||||
|
@ -283,8 +362,8 @@
|
||||||
> local lines = {}
|
> local lines = {}
|
||||||
> local url = ''
|
> local url = ''
|
||||||
> if #arg > 0 then
|
> if #arg > 0 then
|
||||||
> url = arg[1]
|
> state.url = arg[1]
|
||||||
> lines = gemini_get(url)
|
> lines = gemini_get(state.url)
|
||||||
> end
|
> end
|
||||||
> while true do
|
> while true do
|
||||||
> render(window, lines)
|
> render(window, lines)
|
||||||
|
@ -355,21 +434,19 @@
|
||||||
- __teliva_timestamp: original
|
- __teliva_timestamp: original
|
||||||
parse_gemini_body:
|
parse_gemini_body:
|
||||||
>function parse_gemini_body(conn, type)
|
>function parse_gemini_body(conn, type)
|
||||||
> local result = {}
|
|
||||||
> if type == 'text/gemini' then
|
> if type == 'text/gemini' then
|
||||||
> while true do
|
> while true do
|
||||||
> local line, err = conn:receive()
|
> local line, err = conn:receive()
|
||||||
> if line == nil then break end
|
> if line == nil then break end
|
||||||
> table.insert(result, line)
|
> table.insert(state.lines, line)
|
||||||
> end
|
> end
|
||||||
> elseif string.sub(type, 1, 5) == 'text/' then
|
> elseif string.sub(type, 1, 5) == 'text/' then
|
||||||
> while true do
|
> while true do
|
||||||
> local line, err = conn:receive()
|
> local line, err = conn:receive()
|
||||||
> if line == nil then break end
|
> if line == nil then break end
|
||||||
> table.insert(result, line)
|
> table.insert(state.lines, line)
|
||||||
> end
|
> end
|
||||||
> end
|
> end
|
||||||
> return result
|
|
||||||
>end
|
>end
|
||||||
- __teliva_timestamp: original
|
- __teliva_timestamp: original
|
||||||
gemini_get:
|
gemini_get:
|
||||||
|
@ -395,18 +472,23 @@
|
||||||
> os.exit(1)
|
> os.exit(1)
|
||||||
> end
|
> end
|
||||||
> conn:dohandshake()
|
> conn:dohandshake()
|
||||||
>
|
|
||||||
> conn:send(url .. "\r\n")
|
> conn:send(url .. "\r\n")
|
||||||
|
> clear(state.lines)
|
||||||
|
> state.highlight_index = 0 -- highlighted link not computed yet
|
||||||
> local line, err = conn:receive()
|
> local line, err = conn:receive()
|
||||||
> if line == nil then return {err} end
|
> if line == nil then
|
||||||
|
> table.insert(state.lines, err)
|
||||||
|
> return
|
||||||
|
> end
|
||||||
> local status, meta = string.match(line, "(%S+) (%S+)")
|
> local status, meta = string.match(line, "(%S+) (%S+)")
|
||||||
> if status[1] == '2' then
|
> if status[1] == '2' then
|
||||||
> return parse_gemini_body(conn, meta)
|
> parse_gemini_body(conn, meta)
|
||||||
|
> state.url = url
|
||||||
> elseif status[1] == '3' then
|
> elseif status[1] == '3' then
|
||||||
> return gemini_get(socket.url.absolute(url, meta))
|
> gemini_get(socket.url.absolute(url, meta))
|
||||||
> elseif status[1] == '4' or line[1] == '5' then
|
> elseif status[1] == '4' or line[1] == '5' then
|
||||||
> return {'Error: '..meta}
|
> table.insert(state.lines, 'Error: '..meta)
|
||||||
> else
|
> else
|
||||||
> return {'invalid response from server: '..line}
|
> table.insert(state.lines, 'invalid response from server: '..line)
|
||||||
> end
|
> end
|
||||||
>end
|
>end
|
||||||
|
|
Loading…
Reference in New Issue