1 ;;; w3-hot.el --- Main functions for emacs-w3 on all platforms/versions
2 ;; Author: $Author: fx $
3 ;; Created: $Date: 2001/05/14 15:51:54 $
4 ;; Version: $Revision: 1.4 $
5 ;; Keywords: faces, help, comm, news, mail, processes, mouse, hypermedia
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;; Copyright (c) 1993 - 1996 by William M. Perry <wmperry@cs.indiana.edu>
9 ;;; Copyright (c) 1996 - 1999 Free Software Foundation, Inc.
11 ;;; This file is part of GNU Emacs.
13 ;;; GNU Emacs is free software; you can redistribute it and/or modify
14 ;;; it under the terms of the GNU General Public License as published by
15 ;;; the Free Software Foundation; either version 2, or (at your option)
16 ;;; any later version.
18 ;;; GNU Emacs is distributed in the hope that it will be useful,
19 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;;; GNU General Public License for more details.
23 ;;; You should have received a copy of the GNU General Public License
24 ;;; along with GNU Emacs; see the file COPYING. If not, write to the
25 ;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 ;;; Boston, MA 02111-1307, USA.
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
29 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30 ;;; Structure for hotlists
31 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33 ;;; ("name of item1" . "http://foo.bar.com/") ;; A single item in hotlist
34 ;;; ("name of item2" . ( ;; A sublist
35 ;;; ("name of item3" . "http://www.ack.com/")
37 ;;; ) ; end of hotlist
38 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
42 (eval-when-compile (require 'cl))
44 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
45 ;;; Hotlist Handling Code
46 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47 (defvar w3-html-bookmarks nil)
50 (defun w3-read-html-bookmarks (fname)
51 "Import an HTML file into the Emacs-w3 format."
52 (interactive "fBookmark file: ")
53 (if (not (file-readable-p fname))
54 (error "Can not read %s..." fname))
56 (set-buffer (get-buffer-create " *bookmark-work*"))
58 (insert-file-contents fname)
59 (let* ((w3-debug-html nil)
61 (parse (w3-parse-buffer (current-buffer))))
62 (setq parse w3-last-parse-tree
63 bkmarks (nreverse (w3-grok-html-bookmarks parse))
64 w3-hotlist bkmarks))))
67 (defsubst w3-hot-push-new-menu ()
68 (declare (special cur-stack))
69 (setq cur-stack (cons (list "") cur-stack)))
71 ;; This stores it in menu format
72 '(defsubst w3-hot-push-new-item (title href)
73 (declare (special cur-stack))
74 (setcar cur-stack (cons (vector title (list 'w3-fetch href) t)
77 ;; This stores it in alist format
78 (defsubst w3-hot-push-new-item (title href)
79 (declare (special cur-stack))
80 (setcar cur-stack (cons (cons title href) (car cur-stack))))
82 (defsubst w3-hot-finish-submenu ()
83 (declare (special cur-stack cur-title))
84 (let ((x (nreverse (car cur-stack)))
87 (setq y (pop cur-title)))
89 (setq cur-stack (cdr cur-stack))
91 (setcar cur-stack (cons x (car cur-stack)))
92 (setq cur-stack (list x)))))
95 (defun w3-grok-html-bookmarks-internal (tree)
96 (declare (special cur-stack cur-title))
97 (let (node tag content args)
101 tag (and (listp node) (nth 0 node))
102 args (and (listp node) (nth 1 node))
103 content (and (listp node) (nth 2 node)))
106 (setq cur-title '("------")))
108 (setq cur-title (list (w3-normalize-spaces (car content))))
109 (w3-grok-html-bookmarks-internal content))
110 ((memq tag '(dl ol ul))
111 (w3-hot-push-new-menu)
112 (w3-grok-html-bookmarks-internal content)
113 (w3-hot-finish-submenu))
114 ((and (memq tag '(dt li p))
115 (stringp (car content)))
116 (setq cur-title (cons (w3-normalize-spaces (car content))
119 (stringp (car-safe content))
120 (cdr-safe (assq 'href args)))
121 (w3-hot-push-new-item (w3-normalize-spaces (car-safe content))
122 (cdr-safe (assq 'href args))))
124 (w3-grok-html-bookmarks-internal content))))))
126 (defun w3-grok-html-bookmarks (chunk)
131 (declare (special cur-title cur-stack))
132 (w3-grok-html-bookmarks-internal chunk)
133 (reverse (car cur-stack))))
135 (defun w3-hot-convert-to-alist-mapper (node)
136 (declare (special prefix alist))
139 ;; Top-level node... ignore
141 ((stringp (cdr node))
142 ;; A real hyperlink, push it onto the alist
143 (push (cons (if prefix (concat prefix " / " (car node)) (car node)) (cdr node)) alist))
145 ;; A submenu, add to prefix and recurse
146 (w3-hot-convert-to-alist-internal
147 (cdr node) (if prefix (concat prefix " / " (car node)) (car node))))))
149 (defun w3-hot-convert-to-alist-internal (l &optional prefix)
150 (mapc 'w3-hot-convert-to-alist-mapper l))
152 (defun w3-hot-convert-to-alist (l)
154 (w3-hot-convert-to-alist-internal l)
157 (defun w3-delete-from-alist (x alist)
158 ;; Remove X from ALIST, return new alist
159 (if (eq (assoc x alist) (car alist)) (cdr alist)
160 (delq (assoc x alist) alist)))
162 (defun w3-hotlist-parse-old-mosaic-format ()
163 (let (cur-link cur-alias)
164 (while (re-search-forward "^\n" nil t) (replace-match ""))
167 (re-search-forward "^[^ ]*" nil t)
168 (setq cur-link (buffer-substring (match-beginning 0) (match-end 0)))
169 (setq cur-alias (buffer-substring (progn
176 (if (not (equal cur-alias ""))
177 (setq w3-hotlist (cons (list cur-alias cur-link) w3-hotlist))))))
180 (defun w3-parse-hotlist (&optional fname)
181 "Read in the hotlist specified by FNAME"
182 (if (not fname) (setq fname w3-hotlist-file))
183 (setq w3-hotlist nil)
184 (if (not (file-exists-p fname))
185 (message "%s does not exist!" fname)
186 (let* ((old-buffer (current-buffer))
187 (buffer (get-buffer-create " *HOTW3*"))
188 (case-fold-search t))
191 (insert-file-contents fname)
192 (goto-char (point-min))
194 ((looking-at "ncsa-xmosaic-hotlist-format-1");; Old-style NCSA Mosaic
195 (w3-hotlist-parse-old-mosaic-format))
196 ((or (looking-at "<!DOCTYPE") ; Some HTML style, including netscape
197 (re-search-forward "<a[ \n]+href" nil t))
198 (w3-read-html-bookmarks fname))
200 (message "Cannot determine format of hotlist file: %s" fname)))
201 (set-buffer-modified-p nil)
203 (set-buffer old-buffer))))
206 (defun w3-use-hotlist ()
207 "Possibly go to a link in your W3/Mosaic hotlist.
208 This is part of the emacs World Wide Web browser. It will prompt for
209 one of the items in your 'hotlist'. A hotlist is a list of often
210 visited or interesting items you have found on the World Wide Web."
212 (if (not w3-setup-done) (w3-do-setup))
213 (if (not w3-hotlist) (message "No hotlist in memory!")
214 (let* ((completion-ignore-case t)
215 (hot-alist (w3-hot-convert-to-alist w3-hotlist))
217 (completing-read "Goto Document: " hot-alist nil t)
219 (if (string= "" url) (error "No document specified!"))
223 (defun w3-hotlist-add-document-at-point (pref-arg)
224 "Add the document pointed to by the hyperlink under point to the hotlist."
226 (let ((url (w3-view-this-url t))
227 (widget (widget-at (point)))
229 (or url (error "No link under point."))
230 (if (and (widget-get widget :from)
231 (widget-get widget :to))
232 (setq title (buffer-substring (widget-get widget :from)
233 (widget-get widget :to))))
234 (w3-hotlist-add-document pref-arg (or title url) url)))
237 (defun w3-hotlist-add-document (pref-arg &optional the-title the-url)
238 "Add this documents url to the hotlist"
240 (error "Adding to hotlist not implemented yet."))
243 (defun w3-hotlist-delete ()
244 "Deletes a document from your hotlist file"
246 (error "Deleting from hotlist not implemented yet."))
249 (defun w3-hotlist-refresh ()
250 "Reload the default hotlist file into memory"
256 (defun w3-hotlist-apropos (regexp)
257 "Show hotlist entries matching REGEXP."
258 (interactive "sW3 Hotlist Apropos (regexp): ")
259 (or w3-setup-done (w3-do-setup))
260 (w3-fetch (concat "hotlist:search?regexp=" (url-hexify-string regexp))))
263 (defun w3-hotlist-view ()
266 (w3-fetch "hotlist:view"))