comparison lisp/packages/webjump.el @ 98:0d2f883870bc r20-1b1

Import from CVS: tag r20-1b1
author cvs
date Mon, 13 Aug 2007 09:13:56 +0200
parents
children 43dd3413c7c7
comparison
equal deleted inserted replaced
97:498bf5da1c90 98:0d2f883870bc
1 ;;; webjump.el --- programmable Web hotlist
2
3 ;; Copyright (C) 1996 Free Software Foundation
4
5 ;; Author: Neil W. Van Dyke <nwv@acm.org>
6 ;; Created: Fri 09 Aug 1996
7 ;; Version: 1.4
8 ;; Keywords: webjump web www browse-url
9 ;; X-URL: http://www.cs.brown.edu/people/nwv/
10
11 ;; This file is not yet part of GNU Emacs.
12
13 ;; This is free software; you can redistribute it and/or modify it under the
14 ;; terms of the GNU General Public License as published by the Free Software
15 ;; Foundation; either version 2, or (at your option) any later version.
16
17 ;; This is distributed in the hope that it will be useful, but WITHOUT ANY
18 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 ;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
20 ;; details.
21
22 ;; You should have received a copy of the GNU General Public License along with
23 ;; GNU Emacs; see the file COPYING. If not, write to the Free Software
24 ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26 ;;; Change Log:
27
28 ;; [Version 1.4, Tue 17 Sep 1995, nwv] Removed the evil "defconst-TEST" that
29 ;; slipped into 1.3. Organized webjump-sample-sites and modified the content a
30 ;; bit.
31
32 ;; [Version 1.3, Fri 30 Aug 1996, nwv] Fixed broken `if' function in
33 ;; `webjump-to-javaapi' (bugfix already posted). Added `webjump-to-iwin'.
34 ;; Added comment on purpose of `webjump-sample-sites'. Added
35 ;; `webjump-read-choice'.
36
37 ;; [Version 1.2, Fri 16 Aug 1996, nwv] Oops, got Gamelan mixed up with Digital
38 ;; Espresso somehow. Added `mirrors' builtin and used it for the sample GNU
39 ;; Archive site. Added some other sample sites. Split sample sites out into
40 ;; separate constant. Misc. small changes. Copyright has been transferred to
41 ;; the FSF.
42
43 ;; [Version 1.1, Sat 10 Aug 1996, nwv] Added missing call to `webjump-url-fix'
44 ;; (thanks to Istvan Marko <mi@bgytf.hu> for pointing this out). Added
45 ;; ``builtins'' concept in order to support `simple-query' builtin for covering
46 ;; the majority of cases. Added a couple more sample sites.
47
48 ;; [Version 1.0, Fri 09 Aug 1996, nwv] Wrote initial version and posted to
49 ;; gnu.emacs.sources.
50
51 ;;; Commentary:
52
53 ;; WebJump provides a sort of ``programmable hotlist'' of Web sites that can
54 ;; quickly be invoked in your Web browser. Each Web site in the hotlist has a
55 ;; name, and you select the desired site name via a completing string prompt in
56 ;; the minibuffer. The URL for each Web site is defined as a static string or
57 ;; a built-in or custom function, allowing interactive prompting for
58 ;; site-specific queries and options.
59
60 ;; Note that WebJump was originally intended to complement your conventional
61 ;; browser-based hotlist, not replace it. (Though there's no reason you
62 ;; couldn't use WebJump for your entire hotlist if you were so inclined.)
63
64 ;; The `webjump-sites' variable, which defines the hotlist, defaults to some
65 ;; example sites. You'll probably want to override it with your own favorite
66 ;; sites. The documentation for the variable describes the syntax.
67
68 ;; You may wish to add something like the following to your `.emacs' file:
69 ;;
70 ;; (load "webjump")
71 ;; (global-set-key "\C-c\C-j" 'webjump)
72 ;; (setq webjump-sites
73 ;; (append '(
74 ;; ("My Home Page" . "www.someisp.net/users/joebobjr/")
75 ;; ("Pop's Site" . "www.joebob-and-son.com/")
76 ;; )
77 ;; webjump-sample-sites))
78 ;;
79 ;; The above loads this package, binds `C-c C-j' to invoke WebJump, and adds
80 ;; your personal favorite sites to the hotlist.
81
82 ;; The `webjump-sample-sites' constant mostly contains sites that are expected
83 ;; to be generally useful to Emacs users or that have some sort of query which
84 ;; can be coded in WebJump. There are two main goals of this sample site list:
85 ;; (1) demonstrate WebJump capabilities and usage; (2) provide definitions for
86 ;; many popular sites so that people don't have to reinvent the wheel. A few
87 ;; assorted other sites have been thrown in on a whim. No commercial sites are
88 ;; included unless they provide a free, generally-useful service. Inclusion of
89 ;; a site does not represent an endorsement. Please contact the maintainer
90 ;; with change requests.
91
92 ;; The `browse-url' package is used to submit URLs to the browser, so any
93 ;; browser-specific configuration should be done there.
94
95 ;; WebJump inherits a small amount code from my `altavista.el' package, and is
96 ;; intended to obsolete that package.
97
98 ;;; Code:
99
100 ;;-------------------------------------------------------- Package Dependencies
101
102 (require 'browse-url)
103
104 ;;------------------------------------------------------ Package Identification
105
106 (defconst webjump-version "1.4")
107 (defconst webjump-author "Neil W. Van Dyke <nwv@acm.org>")
108 (defconst webjump-maintainer-address "nwv@acm.org")
109 (defconst webjump-vc-id
110 "$Id: webjump.el,v 1.1 1997/02/14 19:21:27 steve Exp $")
111
112 ;;------------------------------------------------------------------- Constants
113
114 (defconst webjump-sample-sites
115 '(
116
117 ;; FSF, not including Emacs-specific.
118 ("GNU Project FTP Archive".
119 [mirrors "ftp://prep.ai.mit.edu/pub/gnu/"
120 ;; ASIA:
121 "ftp://ftp.cs.titech.ac.jp"
122 "ftp://tron.um.u-tokyo.ac.jp/pub/GNU/prep"
123 "ftp://cair-archive.kaist.ac.kr/pub/gnu"
124 "ftp://ftp.nectec.or.th/pub/mirrors/gnu"
125 ;; AUSTRALIA:
126 "ftp://archie.au/gnu"
127 "ftp://archie.oz/gnu"
128 "ftp://archie.oz.au/gnu"
129 ;; AFRICA:
130 "ftp://ftp.sun.ac.za/pub/gnu"
131 ;; MIDDLE-EAST:
132 "ftp://ftp.technion.ac.il/pub/unsupported/gnu"
133 ;; EUROPE:
134 "ftp://irisa.irisa.fr/pub/gnu"
135 "ftp://ftp.univ-lyon1.fr/pub/gnu"
136 "ftp://ftp.mcc.ac.uk"
137 "ftp://unix.hensa.ac.uk/mirrors/uunet/systems/gnu"
138 "ftp://src.doc.ic.ac.uk/gnu"
139 "ftp://ftp.ieunet.ie/pub/gnu"
140 "ftp://ftp.eunet.ch"
141 "ftp://nic.switch.ch/mirror/gnu"
142 "ftp://ftp.informatik.rwth-aachen.de/pub/gnu"
143 "ftp://ftp.informatik.tu-muenchen.de"
144 "ftp://ftp.win.tue.nl/pub/gnu"
145 "ftp://ftp.nl.net"
146 "ftp://ftp.etsimo.uniovi.es/pub/gnu"
147 "ftp://ftp.funet.fi/pub/gnu"
148 "ftp://ftp.denet.dk"
149 "ftp://ftp.stacken.kth.se"
150 "ftp://isy.liu.se"
151 "ftp://ftp.luth.se/pub/unix/gnu"
152 "ftp://ftp.sunet.se/pub/gnu"
153 "ftp://archive.eu.net"
154 ;; SOUTH AMERICA:
155 "ftp://ftp.inf.utfsm.cl/pub/gnu"
156 "ftp://ftp.unicamp.br/pub/gnu"
157 ;; WESTERN CANADA:
158 "ftp://ftp.cs.ubc.ca/mirror2/gnu"
159 ;; USA:
160 "ftp://wuarchive.wustl.edu/systems/gnu"
161 "ftp://labrea.stanford.edu"
162 "ftp://ftp.digex.net/pub/gnu"
163 "ftp://ftp.kpc.com/pub/mirror/gnu"
164 "ftp://f.ms.uky.edu/pub3/gnu"
165 "ftp://jaguar.utah.edu/gnustuff"
166 "ftp://ftp.hawaii.edu/mirrors/gnu"
167 "ftp://uiarchive.cso.uiuc.edu/pub/gnu"
168 "ftp://ftp.cs.columbia.edu/archives/gnu/prep"
169 "ftp://gatekeeper.dec.com/pub/GNU"
170 "ftp://ftp.uu.net/systems/gnu"])
171 ("GNU Project Home Page" . "www.fsf.org")
172 ;"www.gnu.ai.mit.edu"
173 ;"agnes.dida.physik.uni-essen.de/~gnu"
174
175 ;; Emacs.
176 ("Eieio" . "ftp.ultranet.com/pub/zappo/")
177 ("Emacs Lisp Archive" .
178 "ftp://archive.cis.ohio-state.edu/pub/gnu/emacs/elisp-archive/")
179 ("Insidious Big Brother Database" . "home.netscape.com/people/jwz/bbdb/")
180 ;"ftp.xemacs.org/pub/bbdb/"
181 ("Mailcrypt" . "cag-www.lcs.mit.edu/mailcrypt/")
182 ("XEmacs Home" . "www.xemacs.org") ; Doesn't hurt to have this here. :)
183 ("Yahoo: Emacs" .
184 "www.yahoo.com/Computers_and_Internet/Software/Editors/Emacs/")
185
186 ;; General interest.
187 ("AltaVista" .
188 [simple-query
189 "www.altavista.digital.com"
190 "www.altavista.digital.com/cgi-bin/query?pg=aq&what=web&fmt=.&q="
191 "&r=&d0=&d1="])
192 ("Archie" .
193 [simple-query "http://hoohoo.ncsa.uiuc.edu/cgi-bin/AA.pl"
194 "http://hoohoo.ncsa.uiuc.edu/cgi-bin/AA.pl?query=" ""])
195 ("Interactive Weather Information Network" . webjump-to-iwin)
196 ("Lycos" .
197 [simple-query "www.lycos.com" "www.lycos.com/cgi-bin/pursuit?query=" ""])
198 ("Usenet FAQs" .
199 [simple-query "www.cis.ohio-state.edu/hypertext/faq/usenet/FAQ-List.html"
200 "www.cis.ohio-state.edu/htbin/search-usenet-faqs/form?find="
201 ""])
202 ("RTFM Usenet FAQs by Group" .
203 "ftp://rtfm.mit.edu/pub/usenet-by-group/")
204 ("RTFM Usenet FAQs by Hierachy" .
205 "ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/")
206 ("Webster" .
207 [simple-query "c.gp.cs.cmu.edu:5103/prog/webster"
208 "gs213.sp.cs.cmu.edu/prog/webster?" ""])
209 ("X Consortium Archive". "ftp.x.org")
210 ("Yahoo" .
211 [simple-query "www.yahoo.com" "search.yahoo.com/bin/search?p=" ""])
212 ("Yahoo: Reference" "www.yahoo.com/Reference/")
213
214 ;; Computer privacy and social issues.
215 ("Computer Professionals for Social Responsibility" . "www.cpsr.org/dox/")
216 ("Electronic Frontier Foundation" . "www.eff.org")
217 ("Pretty Good Privacy" . "web.mit.edu/network/pgp.html")
218 ("Risks Digest" . webjump-to-risks)
219
220 ;; Java.
221 ("Digital Espresso" .
222 [simple-query "www.io.org/~mentor/DigitalEspresso.html"
223 "www.jars.com/cgi-bin/aglimpse/01?query="
224 "&case=on&whole=on&errors=0&maxfiles=100&maxlines=30"])
225 ("Java API" . webjump-to-javaapi)
226
227 ;; Fun.
228 ("Bastard Operator from Hell" . "www.replay.com/bofh/")
229 ("Dilbert" . "www.unitedmedia.com/comics/dilbert/")
230 ("Playboy" . (if (webjump-adult-p) "www.playboy.com" "www.whitehouse.gov"))
231
232 ;; Author's indulgence.
233 ("Brown University" .
234 [simple-query "www.brown.edu" "www.brown.edu/cgi-local/bsearch?" ""])
235
236 )
237 "Sample hotlist for WebJump.")
238
239 (defconst webjump-state-to-postal-alist
240 '(("Alabama" . "al") ("Alaska" . "ak") ("Arizona" . "az") ("Arkansas" . "ar")
241 ("California" . "ca") ("Colorado" . "co") ("Connecticut" . "ct")
242 ("Delaware" . "de") ("Florida" . "fl") ("Georgia" . "ga") ("Hawaii" . "hi")
243 ("Idaho" . "id") ("Illinois" . "il") ("Indiana" . "in") ("Iowa" . "ia")
244 ("Kansas" . "ks") ("Kentucky" . "ky") ("Louisiana" . "la") ("Maine" . "me")
245 ("Maryland" . "md") ("Massachusetts" . "ma") ("Michigan" . "mi")
246 ("Minnesota" . "mn") ("Mississippi" . "ms") ("Missouri" . "mo")
247 ("Montana" . "mt") ("Nebraska" . "ne") ("Nevada" . "nv")
248 ("New Hampshire" . "nh") ("New Jersey" . "nj") ("New Mexico" . "nm")
249 ("New York" . "ny") ("North Carolina" . "nc") ("North Dakota" . "nd")
250 ("Ohio" . "oh") ("Oklahoma" . "ok") ("Oregon" . "or")
251 ("Pennsylvania" . "pa") ("Rhode Island" . "ri") ("South Carolina" . "sc")
252 ("South Dakota" . "sd") ("Tennessee" . "tn") ("Texas" . "tx")
253 ("Utah" . "ut") ("Vermont" . "vt") ("Virginia" . "va")
254 ("Washington" . "wa") ("West Virginia" . "wv") ("Wisconsin" . "wi")
255 ("Wyoming" . "wy")))
256
257 ;;------------------------------------------------------------ Option Variables
258
259 (defvar webjump-sites
260 webjump-sample-sites
261 "*Hotlist for WebJump.
262
263 The hotlist is represented as an association list, with the CAR of each cell
264 being the name of the Web site, and the CDR being the definition for the URL of
265 that site. The URL definition can be a string (the URL), a vector (specifying
266 a special \"builtin\" which returns a URL), a symbol (name of a function which
267 returns a URL), or a list (which when `eval'ed yields a URL).
268
269 If the URL definition is a vector, then a \"builtin\" is used. A builtin has a
270 Lisp-like syntax, with the name as the first element of the vector, and any
271 arguments as the following elements. The three current builtins are `name',
272 which returns the name of the site as the URL, `simple-query', which
273 returns a URL that is a function of a query entered by the user, and `mirrors',
274 which allows the user to select from among multiple mirror sites for the same
275 content.
276
277 The first argument to the `simple-query' builtin is a static URL to use if the
278 user enters a blank query. The second and third arguments are the prefix and
279 suffix, respectively, to add to the encoded query the user enters. This
280 builtin covers Web sites that have single-string searches with the query
281 embedded in the URL.
282
283 The arguments to the `mirrors' builtin are URLs of mirror sites.
284
285 If the symbol of a function is given, then the function will be called with the
286 Web site name (the one you specified in the CAR of the alist cell) as a
287 parameter. This might come in handy for various kludges.
288
289 For convenience, if the `http://', `ftp://', or `file://' prefix is missing
290 from a URL, WebJump will make a guess at what you wanted and prepend it before
291 submitting the URL.")
292
293 ;;------------------------------------------------------- Sample Site Functions
294
295 (defun webjump-to-iwin (name)
296 (let ((prefix "http://iwin.nws.noaa.gov/")
297 (state (webjump-read-choice name "state"
298 (append '(("Puerto Rico" . "pr"))
299 webjump-state-to-postal-alist))))
300 (if state
301 (concat prefix "iwin/" state "/"
302 (webjump-read-choice name "option"
303 '(("Hourly Report" . "hourly")
304 ("State Forecast" . "state")
305 ("Local Forecast" . "local")
306 ("Zone Forecast" . "zone")
307 ("Short-Term Forecast" . "shortterm")
308 ("Weather Summary" . "summary")
309 ("Public Information" . "public")
310 ("Climatic Data" . "climate")
311 ("Aviation Products" . "aviation")
312 ("Hydro Products" . "hydro")
313 ("Special Weather" . "special")
314 ("Watches and Warnings" . "warnings"))
315 "zone")
316 ".html")
317 prefix)))
318
319 (defun webjump-to-javaapi (name)
320 (let* ((prefix "http://www.javasoft.com/products/JDK/CurrentRelease/api/")
321 (packages '(("java.applet") ("java.awt") ("java.awt.image")
322 ("java.awt.peer") ("java.io") ("java.lang") ("java.net")
323 ("java.util") ("sun.tools.debug")))
324 (completion-ignore-case t)
325 (package (completing-read (concat name " package: ") packages nil t)))
326 (if (webjump-null-or-blank-string-p package)
327 (concat prefix "packages.html")
328 (concat prefix "Package-" package ".html"))))
329
330 (defun webjump-to-risks (name)
331 (let (issue volume)
332 (if (and (setq volume (webjump-read-number (concat name " volume")))
333 (setq issue (webjump-read-number (concat name " issue"))))
334 (format "catless.ncl.ac.uk/Risks/%d.%02d.html" volume issue)
335 "catless.ncl.ac.uk/Risks/")))
336
337 ;;-------------------------------------------------------------- Core Functions
338
339 ;;;###autoload
340 (defun webjump ()
341 "Jumps to a Web site from a programmable hotlist.
342
343 See the documentation for the `webjump-sites' variable for how to customize the
344 hotlist.
345
346 Feedback on WebJump can be sent to the author, Neil W. Van Dyke <nwv@acm.org>,
347 or submitted via `\\[webjump-submit-bug-report]'. The latest version can be
348 gotten from `http://www.cs.brown.edu/people/nwv/'."
349 (interactive)
350 (let* ((completion-ignore-case t)
351 (item (assoc (completing-read "WebJump to site: " webjump-sites nil t)
352 webjump-sites))
353 (name (car item))
354 (expr (cdr item)))
355 (funcall browse-url-browser-function
356 (webjump-url-fix
357 (cond ((not expr) "")
358 ((stringp expr) expr)
359 ((vectorp expr) (webjump-builtin expr name))
360 ((listp expr) (eval expr))
361 ((symbolp expr)
362 (if (fboundp expr)
363 (funcall expr name)
364 (error "WebJump URL function \"%s\" undefined." expr)))
365 (t (error "WebJump URL expression for \"%s\" invalid."
366 name)))))))
367
368 (defun webjump-adult-p ()
369 (and (boundp 'age) (integerp age) (>= age 21)))
370
371 (defun webjump-builtin (expr name)
372 (if (< (length expr) 1)
373 (error "WebJump URL builtin for \"%s\" empty." name))
374 (let ((builtin (aref expr 0)))
375 (cond
376 ((eq builtin 'mirrors)
377 (if (= (length expr) 1)
378 (error
379 "WebJump URL builtin \"mirrors\" for \"%s\" needs at least 1 arg."))
380 (webjump-choose-mirror name (cdr (append expr nil))))
381 ((eq builtin 'name)
382 name)
383 ((eq builtin 'simple-query)
384 (webjump-builtin-check-args expr name 3)
385 (webjump-do-simple-query name (aref expr 1) (aref expr 2) (aref expr 3)))
386 (t (error "WebJump URL builtin \"%s\" for \"%s\" invalid."
387 builtin name)))))
388
389 (defun webjump-builtin-check-args (expr name count)
390 (or (= (length expr) (1+ count))
391 (error "WebJump URL builtin \"%s\" for \"%s\" needs %d args."
392 (aref expr 0) name count)))
393
394 (defun webjump-choose-mirror (name urls)
395 (webjump-read-url-choice (concat name " mirror")
396 urls
397 (webjump-mirror-default urls)))
398
399 (defun webjump-do-simple-query (name noquery-url query-prefix query-suffix)
400 (let ((query (webjump-read-string (concat name " query"))))
401 (if query
402 (concat query-prefix (webjump-url-encode query) query-suffix)
403 noquery-url)))
404
405 (defun webjump-mirror-default (urls)
406 ;; Note: This should be modified to apply some simple kludges/heuristics to
407 ;; pick a site which is likely "close". As a tie-breaker among candidates
408 ;; judged equally desirable, randomness should be used.
409 (car urls))
410
411 (defun webjump-read-choice (name what choices &optional default)
412 (let* ((completion-ignore-case t)
413 (choice (completing-read (concat name " " what ": ") choices nil t)))
414 (if (webjump-null-or-blank-string-p choice)
415 default
416 (cdr (assoc choice choices)))))
417
418 (defun webjump-read-number (prompt)
419 ;; Note: I should make this more robust someday.
420 (let ((input (webjump-read-string prompt)))
421 (if input (string-to-number input))))
422
423 (defun webjump-read-string (prompt)
424 (let ((input (read-string (concat prompt ": "))))
425 (if (webjump-null-or-blank-string-p input) nil input)))
426
427 (defun webjump-read-url-choice (what urls &optional default)
428 ;; Note: Convert this to use `webjump-read-choice' someday.
429 (let* ((completions (mapcar (function (lambda (n) (cons n n)))
430 urls))
431 (input (completing-read (concat what
432 ;;(if default " (RET for default)" "")
433 ": ")
434 completions
435 nil
436 t)))
437 (if (webjump-null-or-blank-string-p input)
438 default
439 (car (assoc input completions)))))
440
441 (defun webjump-null-or-blank-string-p (str)
442 (or (null str) (string-match "^[ \t]*$" str)))
443
444 (defun webjump-submit-bug-report ()
445 "Submit via mail a bug report on WebJump."
446 (interactive)
447 (require 'reporter)
448 (reporter-submit-bug-report
449 webjump-maintainer-address
450 (concat "webjump.el " webjump-version " " webjump-vc-id)
451 '(webjump-sites)
452 nil
453 nil
454 (concat
455 "[Dear bug report submitter: Please ensure that the variable dumps\n"
456 "below do not contain any information you consider private.]\n")))
457
458 (defun webjump-url-encode (str)
459 (mapconcat '(lambda (c)
460 (cond ((= c 32) "+")
461 ((or (and (>= c ?a) (<= c ?z))
462 (and (>= c ?A) (<= c ?Z))
463 (and (>= c ?0) (<= c ?9)))
464 (char-to-string c))
465 (t (upcase (format "%%%02x" c)))))
466 str
467 ""))
468
469 (defun webjump-url-fix (url)
470 (if (webjump-null-or-blank-string-p url)
471 ""
472 (webjump-url-fix-trailing-slash
473 (cond
474 ((string-match "^[a-zA-Z]+:" url) url)
475 ((string-match "^/" url) (concat "file://" url))
476 ((string-match "^\\([^\\./]+\\)" url)
477 (concat (if (string= (downcase (match-string 1 url)) "ftp")
478 "ftp"
479 "http")
480 "://"
481 url))
482 (t url)))))
483
484 (defun webjump-url-fix-trailing-slash (url)
485 (if (string-match "^[a-zA-Z]+://[^/]+$" url)
486 (concat url "/")
487 url))
488
489 ;;-----------------------------------------------------------------------------
490
491 (provide 'webjump)
492
493 ;; webjump.el ends here