]>
Commit | Line | Data |
---|---|---|
5d54d408 | 1 | -- Bookmark system for Links-Lua. |
2 | -- $Id$ | |
3 | ||
4 | ----------------------------------------------------------------------- | |
5 | -- User options | |
6 | --------------------------------------------------------------------- | |
7 | ||
8 | -- Default location to save and load bookmarks from. | |
9 | bm_bookmark_file = home_dir.."/.links/bookmark.lst" | |
10 | ||
11 | -- Set to non-`nil' to see URLs in the generated page. | |
12 | bm_display_urls = nil | |
13 | ||
14 | -- Set to non-`nil' to show links to category headers. | |
15 | -- Only useful while sorting categories, otherwise just annoying. | |
16 | bm_display_category_links = 1 | |
17 | ||
18 | -- Set to non-`nil' to automatically sort bookmarks alphabetically. | |
19 | -- Do not set this if you care about the sorting of your bookmarks! | |
20 | bm_auto_sort_bookmarks = nil | |
21 | ||
22 | ||
23 | ---------------------------------------------------------------------- | |
24 | -- Implementation | |
25 | ---------------------------------------------------------------------- | |
26 | ||
27 | -- We use a special syntax that looks like | |
28 | -- user:bookmark/1 (for categories) | |
29 | -- user:bookmark/1,2/http://some.phony.url/ (for bookmarks) | |
30 | bm_marker = 'user:bookmark' | |
31 | ||
32 | ||
33 | if not bm_bookmarks then | |
34 | -- If the user reloads this script, we don't want to | |
35 | -- lose all the bookmarks! :-) | |
36 | bm_bookmarks = {} | |
37 | end | |
38 | ||
39 | ||
40 | function bm_is_category (str) | |
41 | local _,n = gsub (str, bm_marker..'/%d+$', '') | |
42 | return n ~= 0 | |
43 | end | |
44 | ||
45 | ||
46 | function bm_is_bookmark (str) | |
47 | local _,n = gsub (str, bm_marker..'/%d+,%d+/', '') | |
48 | return n ~= 0 | |
49 | end | |
50 | ||
51 | ||
52 | function bm_decode_info (str) | |
53 | if bm_is_category (str) then | |
54 | str = gsub (str, '.-/(%d+)', 'return %1') | |
55 | else | |
56 | str = gsub (str, '.-/(%d+),(%d+)/(.*)', 'return %1,%2,"%3"') | |
57 | end | |
58 | return dostring (str) | |
59 | end | |
60 | ||
61 | ||
62 | function bm_find_category (cat) | |
63 | for i = 1, getn (bm_bookmarks) do | |
64 | local table = bm_bookmarks[i] | |
65 | if table.category == cat then return table end | |
66 | end | |
67 | end | |
68 | ||
69 | ||
70 | function bm_sort_bookmarks () | |
71 | if not bm_auto_sort_bookmarks then return end | |
72 | sort (bm_bookmarks, function (a, b) return a.category < b.category end) | |
73 | foreachi (bm_bookmarks, | |
74 | function (i, v) | |
75 | sort (v, function (a, b) return a.name < b. name end) | |
76 | end) | |
77 | end | |
78 | ||
79 | ||
80 | function bm_generate_html () | |
81 | local s = '<html><head><title>Bookmarks</title></head>' | |
82 | ..'<body link=blue>\n' | |
83 | for i = 1, getn (bm_bookmarks) do | |
84 | local table = bm_bookmarks[i] | |
85 | s = s..'<h3>' | |
86 | if bm_display_category_links then | |
87 | s = s..'<a href="'..bm_marker..'/'..i..'">' | |
88 | end | |
89 | s = s..'<font color=gray>'..table.category..'</font>' | |
90 | if bm_display_category_links then | |
91 | s = s..'</a>' | |
92 | end | |
93 | s = s..'</h3>\n<ul>\n' | |
94 | for j = 1, getn (table) do | |
95 | local bm = table[j] | |
96 | s = s..'<li><a href="'..bm_marker..'/'..i..','..j..'/' | |
97 | ..bm.url..'">'..bm.name..'</a>\n' | |
98 | if bm_display_urls then s = s..'<br>'..bm.url..'\n' end | |
99 | end | |
100 | s = s..'</ul>\n' | |
101 | end | |
102 | s = s..'<hr>'..date ()..'\n' | |
103 | return s..'</body></html>\n' | |
104 | end | |
105 | ||
106 | ||
107 | -- Write bookmarks to disk. | |
108 | function bm_save_bookmarks (filename) | |
109 | if bm_dont_save then return end | |
110 | ||
111 | function esc (str) | |
112 | return gsub (str, "([^-%w \t_@#:/'().])", | |
113 | function (s) | |
114 | return format ("\\%03d", strbyte (s)) | |
115 | end) | |
116 | end | |
117 | ||
118 | if not filename then filename = bm_bookmark_file end | |
119 | local tab = ' ' | |
120 | writeto (filename) | |
121 | write ('return {\n') | |
122 | for i = 1, getn (bm_bookmarks) do | |
123 | local table = bm_bookmarks[i] | |
124 | write (tab..'{\n'..tab..tab..'category = "' | |
125 | ..esc (table.category)..'";\n') | |
126 | for i = 1, getn (table) do | |
127 | local bm = table[i] | |
128 | write (tab..tab..'{ name = "'..esc (bm.name)..'", url = "' | |
129 | ..esc (bm.url)..'" },\n') | |
130 | end | |
131 | write (tab..'},\n') | |
132 | end | |
133 | write ('}\n') | |
134 | writeto () | |
135 | end | |
136 | ||
137 | ||
138 | -- Load bookmarks from disk. | |
139 | function bm_load_bookmarks (filename) | |
140 | if not filename then filename = bm_bookmark_file end | |
141 | local tmp = dofile (filename) | |
142 | if type (tmp) == 'table' then | |
143 | bm_bookmarks = tmp | |
144 | bm_sort_bookmarks () | |
145 | bm_dont_save = nil | |
146 | else | |
147 | _ALERT ("Error loading "..filename) | |
148 | bm_dont_save = 1 | |
149 | end | |
150 | end | |
151 | ||
152 | ||
153 | -- Return the URL of a bookmark. | |
154 | function bm_get_bookmark_url (bm) | |
155 | if bm_is_bookmark (bm) then | |
156 | local _,_,url = bm_decode_info (bm) | |
157 | return url | |
158 | end | |
159 | end | |
160 | ||
161 | ||
162 | -- Bind this to a key to display bookmarks. | |
163 | function bm_view_bookmarks () | |
164 | local tmp = tmpname()..'.html' | |
165 | writeto (tmp) | |
166 | write (bm_generate_html ()) | |
167 | writeto () | |
168 | tinsert (tmp_files, tmp) | |
169 | return 'goto_url', tmp | |
170 | end | |
171 | ||
172 | ||
173 | function bm_do_add_bookmark (cat, name, url) | |
174 | if cat == "" or name == "" or url == "" then | |
175 | _ALERT ("Bad bookmark entry") | |
176 | end | |
177 | local table = bm_find_category (cat) | |
178 | if not table then | |
179 | table = { category = cat } | |
180 | tinsert (bm_bookmarks, table) | |
181 | end | |
182 | tinsert (table, { name = name, url = url }) | |
183 | bm_sort_bookmarks () | |
184 | end | |
185 | ||
186 | ||
187 | -- Bind this to a key to add a bookmark. | |
188 | function bm_add_bookmark () | |
189 | edit_bookmark_dialog ('', current_title () or '', current_url () or '', | |
190 | function (cat, name, url) | |
191 | bm_do_add_bookmark (cat, name, url) | |
192 | if current_title () == 'Bookmarks' then | |
193 | return bm_view_bookmarks () | |
194 | end | |
195 | end) | |
196 | end | |
197 | ||
198 | ||
199 | -- Bind this to a key to edit the currently highlighted bookmark. | |
200 | function bm_edit_bookmark () | |
201 | local bm = current_link () | |
202 | if not bm then | |
203 | elseif bm_is_category (bm) then | |
204 | local i = bm_decode_info (bm) | |
205 | edit_bookmark_dialog (bm_bookmarks[i].category, '', '', | |
206 | function (cat) | |
207 | if cat == '' then | |
208 | _ALERT ('Bad input') | |
209 | elseif bm_bookmarks[%i].category ~= cat then | |
210 | local j = bm_find_category (cat) | |
211 | if not j then | |
212 | bm_bookmarks[%i].category = cat | |
213 | else | |
214 | local tmp = bm_bookmarks[%i] | |
215 | for i = 1, getn (tmp) do | |
216 | bm_do_add_bookmark (cat, tmp[i].name, tmp[i].url) | |
217 | end | |
218 | bm_delete_bookmark (%i) | |
219 | end | |
220 | return bm_view_bookmarks () | |
221 | end | |
222 | end) | |
223 | ||
224 | elseif bm_is_bookmark (bm) then | |
225 | local i,j = bm_decode_info (bm) | |
226 | local entry = bm_bookmarks[i][j] | |
227 | edit_bookmark_dialog (bm_bookmarks[i].category, | |
228 | entry.name, entry.url, | |
229 | function (cat, name, url) | |
230 | if cat == '' or name == '' or url == '' then | |
231 | _ALERT ('Bad input') | |
232 | else | |
233 | if cat ~= bm_bookmarks[%i].category then | |
234 | bm_do_delete_bookmark (%i, %j) | |
235 | bm_do_add_bookmark (cat, name, url) | |
236 | else | |
237 | %entry.name = name | |
238 | %entry.url = url | |
239 | end | |
240 | return bm_view_bookmarks () | |
241 | end | |
242 | end) | |
243 | end | |
244 | end | |
245 | ||
246 | ||
247 | function bm_do_delete_bookmark (i, j) | |
248 | if not j then | |
249 | tremove (bm_bookmarks, i) | |
250 | else | |
251 | tremove (bm_bookmarks[i], j) | |
252 | if getn (bm_bookmarks[i]) == 0 then tremove (bm_bookmarks, i) end | |
253 | end | |
254 | end | |
255 | ||
256 | ||
257 | -- Bind this to a key to delete the currently highlighted bookmark. | |
258 | function bm_delete_bookmark () | |
259 | local bm = current_link () | |
260 | if bm and (bm_is_category (bm) or bm_is_bookmark (bm)) then | |
261 | local i,j = bm_decode_info (bm) | |
262 | bm_do_delete_bookmark (i, j) | |
263 | return bm_view_bookmarks () | |
264 | end | |
265 | end | |
266 | ||
267 | ||
268 | function bm_do_move_bookmark (dir) | |
269 | function tswap (t, i, j) | |
270 | if i > 0 and j > 0 and i <= getn (t) and j <= getn (t) then | |
271 | local x = t[i]; t[i] = t[j]; t[j] = x | |
272 | return 1 | |
273 | end | |
274 | end | |
275 | ||
276 | local bm = current_link () | |
277 | if not bm then | |
278 | elseif bm_is_category (bm) then | |
279 | local i = bm_decode_info (bm) | |
280 | if tswap (bm_bookmarks, i, i+dir) then | |
281 | return bm_view_bookmarks () | |
282 | end | |
283 | elseif bm_is_bookmark (bm) then | |
284 | local i,j = bm_decode_info (bm) | |
285 | if bm_bookmarks[i] and tswap (bm_bookmarks[i], j, j+dir) then | |
286 | return bm_view_bookmarks () | |
287 | end | |
288 | end | |
289 | end | |
290 | ||
291 | ||
292 | -- Bind this to a key to move the currently highlighted bookmark up. | |
293 | function bm_move_bookmark_up () | |
294 | if not bm_auto_sort_bookmarks then return bm_do_move_bookmark (-1) end | |
295 | end | |
296 | ||
297 | ||
298 | -- Bind this to a key to move the currently highlighted bookmark down. | |
299 | function bm_move_bookmark_down () | |
300 | if not bm_auto_sort_bookmarks then return bm_do_move_bookmark (1) end | |
301 | end | |
302 | ||
303 | ||
304 | -- vim: shiftwidth=4 softtabstop=4 |