File: bm.lua

package info (click to toggle)
links 0.96.20020409-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 3,540 kB
  • ctags: 3,800
  • sloc: ansic: 30,344; sh: 2,095; makefile: 269; awk: 81; perl: 34
file content (304 lines) | stat: -rw-r--r-- 7,757 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
-- Bookmark system for Links-Lua.
-- $Id: bm.lua,v 1.4 2002/01/29 00:31:27 tjaden Exp $

-----------------------------------------------------------------------
--  User options
---------------------------------------------------------------------

-- Default location to save and load bookmarks from.
bm_bookmark_file = home_dir.."/.links/bookmark.lst"

-- Set to non-`nil' to see URLs in the generated page.
bm_display_urls = nil

-- Set to non-`nil' to show links to category headers.
-- Only useful while sorting categories, otherwise just annoying.
bm_display_category_links = 1

-- Set to non-`nil' to automatically sort bookmarks alphabetically.
-- Do not set this if you care about the sorting of your bookmarks!
bm_auto_sort_bookmarks = nil


----------------------------------------------------------------------
--  Implementation
----------------------------------------------------------------------

-- We use a special syntax that looks like
-- user:bookmark/1			     (for categories)
-- user:bookmark/1,2/http://some.phony.url/  (for bookmarks)
bm_marker = 'user:bookmark'


if not bm_bookmarks then
    -- If the user reloads this script, we don't want to
    -- lose all the bookmarks! :-)
    bm_bookmarks = {}
end


function bm_is_category (str)
    local _,n = gsub (str, bm_marker..'/%d+$', '')
    return n ~= 0
end


function bm_is_bookmark (str)
    local _,n = gsub (str, bm_marker..'/%d+,%d+/', '')
    return n ~= 0
end


function bm_decode_info (str)
    if bm_is_category (str) then
	str = gsub (str, '.-/(%d+)', 'return %1')
    else
	str = gsub (str, '.-/(%d+),(%d+)/(.*)', 'return %1,%2,"%3"')
    end
    return dostring (str)
end


function bm_find_category (cat)
    for i = 1, getn (bm_bookmarks) do
	local table = bm_bookmarks[i]
	if table.category == cat then return table end
    end
end


function bm_sort_bookmarks ()
    if not bm_auto_sort_bookmarks then return end
    sort (bm_bookmarks, function (a, b) return a.category < b.category end)
    foreachi (bm_bookmarks,
		function (i, v) 
		    sort (v, function (a, b) return a.name < b. name end)
		end)
end


function bm_generate_html ()
    local s = '<html><head><title>Bookmarks</title></head>'
		..'<body link=blue>\n'
    for i = 1, getn (bm_bookmarks) do
	local table = bm_bookmarks[i]
	s = s..'<h3>'
	if bm_display_category_links then
	    s = s..'<a href="'..bm_marker..'/'..i..'">'
	end
	s = s..'<font color=gray>'..table.category..'</font>'
	if bm_display_category_links then
	    s = s..'</a>'
	end
	s = s..'</h3>\n<ul>\n'
	for j = 1, getn (table) do
	    local bm = table[j]
	    s = s..'<li><a href="'..bm_marker..'/'..i..','..j..'/'
		..bm.url..'">'..bm.name..'</a>\n'
	    if bm_display_urls then s = s..'<br>'..bm.url..'\n' end
	end
	s = s..'</ul>\n'
    end
    s = s..'<hr>'..date ()..'\n'
    return s..'</body></html>\n'
end


-- Write bookmarks to disk.
function bm_save_bookmarks (filename)
    if bm_dont_save then return end

    function esc (str)
	return gsub (str, "([^-%w \t_@#:/'().])",
		     function (s) 
			 return format ("\\%03d", strbyte (s))
		     end)
    end

    if not filename then filename = bm_bookmark_file end
    local tab = '  '
    writeto (filename)
    write ('return {\n')
    for i = 1, getn (bm_bookmarks) do
	local table = bm_bookmarks[i]
	write (tab..'{\n'..tab..tab..'category = "'
		..esc (table.category)..'";\n')
	for i = 1, getn (table) do
	    local bm = table[i]
	    write (tab..tab..'{ name = "'..esc (bm.name)..'", url = "'
		    ..esc (bm.url)..'" },\n')
	end
	write (tab..'},\n')
    end
    write ('}\n')
    writeto ()
end


-- Load bookmarks from disk.
function bm_load_bookmarks (filename)
    if not filename then filename = bm_bookmark_file end
    local tmp = dofile (filename)
    if type (tmp) == 'table' then
	bm_bookmarks = tmp
	bm_sort_bookmarks ()
	bm_dont_save = nil
    else
	_ALERT ("Error loading "..filename)
	bm_dont_save = 1
    end
end


-- Return the URL of a bookmark.
function bm_get_bookmark_url (bm)
    if bm_is_bookmark (bm) then
	local _,_,url = bm_decode_info (bm)
	return url
    end
end


-- Bind this to a key to display bookmarks.
function bm_view_bookmarks ()
    local tmp = tmpname()..'.html'
    writeto (tmp)
    write (bm_generate_html ())
    writeto ()
    tinsert (tmp_files, tmp)
    return 'goto_url', tmp
end


function bm_do_add_bookmark (cat, name, url)
    if cat == "" or name == "" or url == "" then
	_ALERT ("Bad bookmark entry")
    end
    local table = bm_find_category (cat)
    if not table then
        table = { category = cat }
        tinsert (bm_bookmarks, table)
    end
    tinsert (table, { name = name, url = url })
    bm_sort_bookmarks ()
end


-- Bind this to a key to add a bookmark.
function bm_add_bookmark ()
    edit_bookmark_dialog ('', current_title () or '', current_url () or '',
			    function (cat, name, url)
				bm_do_add_bookmark (cat, name, url)
				if current_title () == 'Bookmarks' then
				    return bm_view_bookmarks ()
				end
			    end)
end


-- Bind this to a key to edit the currently highlighted bookmark.
function bm_edit_bookmark ()
    local bm = current_link ()
    if not bm then
    elseif bm_is_category (bm) then
	local i = bm_decode_info (bm)
	edit_bookmark_dialog (bm_bookmarks[i].category, '', '',
	    function (cat)
		if cat == '' then
		    _ALERT ('Bad input')
		elseif bm_bookmarks[%i].category ~= cat then
		    local j = bm_find_category (cat)
		    if not j then
			bm_bookmarks[%i].category = cat
		    else
			local tmp = bm_bookmarks[%i]
			for i = 1, getn (tmp) do
			    bm_do_add_bookmark (cat, tmp[i].name, tmp[i].url)
			end
			bm_delete_bookmark (%i)
		    end	
		    return bm_view_bookmarks ()
		end
	    end)

    elseif bm_is_bookmark (bm) then
	local i,j = bm_decode_info (bm)
	local entry = bm_bookmarks[i][j]
	edit_bookmark_dialog (bm_bookmarks[i].category, 
			     entry.name, entry.url,
			     function (cat, name, url)
				if cat == '' or name == '' or url == '' then
				    _ALERT ('Bad input')
				else
				    if cat ~= bm_bookmarks[%i].category then
					bm_do_delete_bookmark (%i, %j)
					bm_do_add_bookmark (cat, name, url)
				    else
					%entry.name = name
					%entry.url = url
				    end
				    return bm_view_bookmarks ()
				end
			     end)
    end
end


function bm_do_delete_bookmark (i, j)
    if not j then
	tremove (bm_bookmarks, i)
    else
	tremove (bm_bookmarks[i], j)
	if getn (bm_bookmarks[i]) == 0 then tremove (bm_bookmarks, i) end
    end
end


-- Bind this to a key to delete the currently highlighted bookmark.
function bm_delete_bookmark ()
    local bm = current_link ()
    if bm and (bm_is_category (bm) or bm_is_bookmark (bm)) then
	local i,j = bm_decode_info (bm)
	bm_do_delete_bookmark (i, j)
	return bm_view_bookmarks ()
    end
end


function bm_do_move_bookmark (dir)
    function tswap (t, i, j)
	if i > 0 and j > 0 and i <= getn (t) and j <= getn (t) then
	    local x = t[i]; t[i] = t[j]; t[j] = x
	    return 1
	end
    end

    local bm = current_link ()
    if not bm then
    elseif bm_is_category (bm) then
	local i = bm_decode_info (bm)
	if tswap (bm_bookmarks, i, i+dir) then
	    return bm_view_bookmarks ()
	end
    elseif bm_is_bookmark (bm) then
	local i,j = bm_decode_info (bm)
	if bm_bookmarks[i] and tswap (bm_bookmarks[i], j, j+dir) then
	    return bm_view_bookmarks ()
	end
    end
end


-- Bind this to a key to move the currently highlighted bookmark up.
function bm_move_bookmark_up ()
    if not bm_auto_sort_bookmarks then return bm_do_move_bookmark (-1) end
end


-- Bind this to a key to move the currently highlighted bookmark down.
function bm_move_bookmark_down ()
    if not bm_auto_sort_bookmarks then return bm_do_move_bookmark (1) end
end


-- vim: shiftwidth=4 softtabstop=4