Removed code using pipes for decompression and simplified decompress_data.
[elinks.git] / contrib / lua / bm.lua
blob362c174d7c1d2c227de38d0f97d541185fff328d
1 -- Bookmark system for Links-Lua.
3 -----------------------------------------------------------------------
4 -- User options
5 ---------------------------------------------------------------------
7 -- Default location to save and load bookmarks from.
8 bm_bookmark_file = elinks_home.."/bookmark.lst"
10 -- Set to non-`nil' to see URLs in the generated page.
11 bm_display_urls = nil
13 -- Set to non-`nil' to show links to category headers.
14 -- Only useful while sorting categories, otherwise just annoying.
15 bm_display_category_links = 1
17 -- Set to non-`nil' to automatically sort bookmarks alphabetically.
18 -- Do not set this if you care about the sorting of your bookmarks!
19 bm_auto_sort_bookmarks = nil
22 ----------------------------------------------------------------------
23 -- Implementation
24 ----------------------------------------------------------------------
26 -- We use a special syntax that looks like
27 -- user:bookmark/1 (for categories)
28 -- user:bookmark/1,2/http://some.phony.url/ (for bookmarks)
29 bm_marker = 'user:bookmark'
32 if not bm_bookmarks then
33 -- If the user reloads this script, we don't want to
34 -- lose all the bookmarks! :-)
35 bm_bookmarks = {}
36 end
39 function bm_is_category (str)
40 local _,n = string.gsub (str, bm_marker..'/%d+$', '')
41 return n ~= 0
42 end
45 function bm_is_bookmark (str)
46 local _,n = string.gsub (str, bm_marker..'/%d+,%d+/', '')
47 return n ~= 0
48 end
51 function bm_decode_info (str)
52 if bm_is_category (str) then
53 str = string.gsub (str, '.-/(%d+)', 'return %1')
54 else
55 str = string.gsub (str, '.-/(%d+),(%d+)/(.*)', 'return %1,%2,"%3"')
56 end
57 return dostring (str)
58 end
61 function bm_find_category (cat)
62 for i = 1, table.getn (bm_bookmarks) do
63 local table = bm_bookmarks[i]
64 if table.category == cat then return table end
65 end
66 end
69 function bm_sort_bookmarks ()
70 if not bm_auto_sort_bookmarks then return end
71 table.sort (bm_bookmarks, function (a, b) return a.category < b.category end)
72 foreachi (bm_bookmarks,
73 function (i, v)
74 table.sort (v, function (a, b) return a.name < b. name end)
75 end)
76 end
79 function bm_generate_html ()
80 local s = '<html><head><title>Bookmarks</title></head>'
81 ..'<body link=blue>\n'
82 for i = 1, table.getn (bm_bookmarks) do
83 local table = bm_bookmarks[i]
84 s = s..'<h3>'
85 if bm_display_category_links then
86 s = s..'<a href="'..bm_marker..'/'..i..'">'
87 end
88 s = s..'<font color=gray>'..table.category..'</font>'
89 if bm_display_category_links then
90 s = s..'</a>'
91 end
92 s = s..'</h3>\n<ul>\n'
93 for j = 1, table.getn (table) do
94 local bm = table[j]
95 s = s..'<li><a href="'..bm_marker..'/'..i..','..j..'/'
96 ..bm.url..'">'..bm.name..'</a>\n'
97 if bm_display_urls then s = s..'<br>'..bm.url..'\n' end
98 end
99 s = s..'</ul>\n'
101 s = s..'<hr>'..os.date ()..'\n'
102 return s..'</body></html>\n'
106 -- Write bookmarks to disk.
107 function bm_save_bookmarks (filename)
108 if bm_dont_save then return end
110 function esc (str)
111 return string.gsub (str, "([^-%w \t_@#:/'().])",
112 function (s)
113 return string.format ("\\%03d", string.byte (s))
114 end)
117 if not filename then filename = bm_bookmark_file end
118 local tab = ' '
119 writeto (filename)
120 write ('return {\n')
121 for i = 1, table.getn (bm_bookmarks) do
122 local table = bm_bookmarks[i]
123 write (tab..'{\n'..tab..tab..'category = "'
124 ..esc (table.category)..'";\n')
125 for i = 1, table.getn (table) do
126 local bm = table[i]
127 write (tab..tab..'{ name = "'..esc (bm.name)..'", url = "'
128 ..esc (bm.url)..'" },\n')
130 write (tab..'},\n')
132 write ('}\n')
133 writeto ()
137 -- Load bookmarks from disk.
138 function bm_load_bookmarks (filename)
139 if not filename then filename = bm_bookmark_file end
140 local tmp = dofile (filename)
141 if type (tmp) == 'table' then
142 bm_bookmarks = tmp
143 bm_sort_bookmarks ()
144 bm_dont_save = nil
145 else
146 _ALERT ("Error loading "..filename)
147 bm_dont_save = 1
152 -- Return the URL of a bookmark.
153 function bm_get_bookmark_url (bm)
154 if bm_is_bookmark (bm) then
155 local _,_,url = bm_decode_info (bm)
156 return url
161 -- Bind this to a key to display bookmarks.
162 function bm_view_bookmarks ()
163 local tmp = tmpname()..'.html'
164 writeto (tmp)
165 write (bm_generate_html ())
166 writeto ()
167 table.insert (tmp_files, tmp)
168 return 'goto_url', tmp
172 function bm_do_add_bookmark (cat, name, url)
173 if cat == "" or name == "" or url == "" then
174 _ALERT ("Bad bookmark entry")
176 local table = bm_find_category (cat)
177 if not table then
178 table = { category = cat }
179 table.insert (bm_bookmarks, table)
181 table.insert (table, { name = name, url = url })
182 bm_sort_bookmarks ()
186 -- Bind this to a key to add a bookmark.
187 function bm_add_bookmark ()
188 edit_bookmark_dialog ('', current_title () or '', current_url () or '',
189 function (cat, name, url)
190 bm_do_add_bookmark (cat, name, url)
191 if current_title () == 'Bookmarks' then
192 return bm_view_bookmarks ()
194 end)
198 -- Bind this to a key to edit the currently highlighted bookmark.
199 function bm_edit_bookmark ()
200 local bm = current_link ()
201 if not bm then
202 elseif bm_is_category (bm) then
203 local i = bm_decode_info (bm)
204 edit_bookmark_dialog (bm_bookmarks[i].category, '', '',
205 function (cat)
206 if cat == '' then
207 _ALERT ('Bad input')
208 elseif bm_bookmarks[i].category ~= cat then
209 local j = bm_find_category (cat)
210 if not j then
211 bm_bookmarks[i].category = cat
212 else
213 local tmp = bm_bookmarks[i]
214 for i = 1, table.getn (tmp) do
215 bm_do_add_bookmark (cat, tmp[i].name, tmp[i].url)
217 bm_delete_bookmark (i)
219 return bm_view_bookmarks ()
221 end)
223 elseif bm_is_bookmark (bm) then
224 local i,j = bm_decode_info (bm)
225 local entry = bm_bookmarks[i][j]
226 edit_bookmark_dialog (bm_bookmarks[i].category,
227 entry.name, entry.url,
228 function (cat, name, url)
229 if cat == '' or name == '' or url == '' then
230 _ALERT ('Bad input')
231 else
232 if cat ~= bm_bookmarks[i].category then
233 bm_do_delete_bookmark (i, j)
234 bm_do_add_bookmark (cat, name, url)
235 else
236 entry.name = name
237 entry.url = url
239 return bm_view_bookmarks ()
241 end)
246 function bm_do_delete_bookmark (i, j)
247 if not j then
248 table.remove (bm_bookmarks, i)
249 else
250 table.remove (bm_bookmarks[i], j)
251 if table.getn (bm_bookmarks[i]) == 0 then table.remove (bm_bookmarks, i) end
256 -- Bind this to a key to delete the currently highlighted bookmark.
257 function bm_delete_bookmark ()
258 local bm = current_link ()
259 if bm and (bm_is_category (bm) or bm_is_bookmark (bm)) then
260 local i,j = bm_decode_info (bm)
261 bm_do_delete_bookmark (i, j)
262 return bm_view_bookmarks ()
267 function bm_do_move_bookmark (dir)
268 function tswap (t, i, j)
269 if i > 0 and j > 0 and i <= table.getn (t) and j <= table.getn (t) then
270 local x = t[i]; t[i] = t[j]; t[j] = x
271 return 1
275 local bm = current_link ()
276 if not bm then
277 elseif bm_is_category (bm) then
278 local i = bm_decode_info (bm)
279 if tswap (bm_bookmarks, i, i+dir) then
280 return bm_view_bookmarks ()
282 elseif bm_is_bookmark (bm) then
283 local i,j = bm_decode_info (bm)
284 if bm_bookmarks[i] and tswap (bm_bookmarks[i], j, j+dir) then
285 return bm_view_bookmarks ()
291 -- Bind this to a key to move the currently highlighted bookmark up.
292 function bm_move_bookmark_up ()
293 if not bm_auto_sort_bookmarks then return bm_do_move_bookmark (-1) end
297 -- Bind this to a key to move the currently highlighted bookmark down.
298 function bm_move_bookmark_down ()
299 if not bm_auto_sort_bookmarks then return bm_do_move_bookmark (1) end
303 function bookmarks_follow_url_hook (url)
304 if bm_is_category (url) then
305 return nil,true
306 else
307 url = bm_get_bookmark_url (url)
308 if url then return url,true end
311 return url,nil
313 table.insert(follow_url_hooks, bookmarks_follow_url_hook)
316 function bookmarks_quit_hook ()
317 bm_save_bookmarks ()
319 table.insert(quit_hooks, bookmarks_quit_hook)
322 -- Be careful not to load bookmarks if this script is being
323 -- reloaded while in ELinks, or we will lose unsaved changes.
324 if not bm_bookmarks or table.getn (bm_bookmarks) == 0 then
325 bm_load_bookmarks ()
329 -- My bookmark key bindings.
330 -- bind_key ('main', 'a', bm_add_bookmark)
331 -- bind_key ('main', 's', bm_view_bookmarks)
332 -- bind_key ('main', 'Alt-e', bm_edit_bookmark)
333 -- bind_key ('main', 'Alt-d', bm_delete_bookmark)
334 -- bind_key ('main', 'Alt-k', bm_move_bookmark_up)
335 -- bind_key ('main', 'Alt-j', bm_move_bookmark_down)
338 -- vim: shiftwidth=4 softtabstop=4