bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#18308: 24.4.50; Info viewer cannot follow menu entry for '(texinfo)


From: Tom Tromey
Subject: bug#18308: 24.4.50; Info viewer cannot follow menu entry for '(texinfo) @- @hyphenation'
Date: Sun, 24 Aug 2014 20:07:27 -0600
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4.50 (gnu/linux)

Stefan> The only vaguely related project I've heard of recently is the one that
Stefan> provided an Info-mode-like behavior to view Texinfo docs in your
Stefan> web browser.

Ages ago I wrote a bit of this.
I've appended a patch that adds a few more Info-ish key bindings to eww.
(The patch won't apply as-is because parts of it are already in trunk.)

Most of the bindings from Info-mode will be pretty easy to replicate.

Searching isn't insurmountable but will require a bit of work.

Dealing with the index is maybe the hardest thing.  Here perhaps a new
'rel="index"' attribute would work ok -- this would let the "i" binding
know which links represent the indices, and then enable searching of
those.

Tom

=== modified file 'lisp/net/eww.el'
--- lisp/net/eww.el     2013-06-18 18:04:09 +0000
+++ lisp/net/eww.el     2013-06-19 19:30:57 +0000
@@ -56,6 +56,17 @@
   "Title of current page.")
 (defvar eww-history nil)
 
+(defvar eww-next-url nil)
+(defvar eww-previous-url nil)
+(defvar eww-up-url nil)
+(defvar eww-home-url nil)
+(defvar eww-start-url nil)
+(defvar eww-contents-url nil)
+(defvar eww-index-url nil)
+(defvar eww-info-like-menu nil)
+(defvar eww-xrefs nil)
+(defvar eww-in-menu-class nil)
+
 ;;;###autoload
 (defun eww (url)
   "Fetch URL and render the page."
@@ -64,10 +75,26 @@
     (setq url (concat "http://"; url)))
   (url-retrieve url 'eww-render (list url)))
 
+;;;###autoload
+(defun eww-open-file (file)
+  "Render a file using EWW."
+  (interactive "fFile: ")
+  (eww (concat "file://" (expand-file-name file))))
+
 (defun eww-render (status url &optional point)
   (let ((redirect (plist-get status :redirect)))
     (when redirect
       (setq url redirect)))
+  (set (make-local-variable 'eww-next-url) nil)
+  (set (make-local-variable 'eww-previous-url) nil)
+  (set (make-local-variable 'eww-up-url) nil)
+  (set (make-local-variable 'eww-home-url) nil)
+  (set (make-local-variable 'eww-start-url) nil)
+  (set (make-local-variable 'eww-contents-url) nil)
+  (set (make-local-variable 'eww-index-url) nil)
+  (set (make-local-variable 'eww-info-like-menu) nil)
+  (set (make-local-variable 'eww-xrefs) nil)
+  (set (make-local-variable 'eww-in-menu-class) nil)
   (let* ((headers (eww-parse-headers))
         (shr-target-id
          (and (string-match "#\\(.*\\)" url)
@@ -146,11 +173,62 @@
             (input . eww-tag-input)
             (textarea . eww-tag-textarea)
             (body . eww-tag-body)
-            (select . eww-tag-select))))
+            (select . eww-tag-select)
+            (link . eww-tag-link)
+            (a . eww-tag-a)
+            (table . eww-tag-table))))
       (shr-insert-document document)
       (eww-convert-widgets))
     (goto-char (point-min))))
 
+(defun eww-handle-link (cont)
+  (let* ((rel (assq :rel cont))
+       (href (assq :href cont))
+       (where (assoc
+               ;; The text associated with :rel is case-insensitive.
+               (if rel (downcase (cdr rel)))
+                     '(("next" . eww-next-url)
+                       ;; Texinfo uses "previous", but HTML specifies
+                       ;; "prev", so recognize both.
+                       ("previous" . eww-previous-url)
+                       ("prev" . eww-previous-url)
+                       ;; HTML specifies "start" but also "contents",
+                       ;; and Gtk seems to use "home".  Recognize
+                       ;; them all; but store them in different
+                       ;; variables so that we can readily choose the
+                       ;; "best" one.
+                       ("start" . eww-start-url)
+                       ("home" . eww-home-url)
+                       ("contents" . eww-contents-url)
+                       ("up" . eww-up-url)
+                       ("index" . eww-index-url)))))
+    (and href
+        where
+        (set (cdr where) (cdr href)))))
+
+(defun eww-tag-table (cont)
+  (let ((eww-in-menu-class (equal (cdr (assq :class cont)) "menu")))
+    (if eww-in-menu-class
+       (setq eww-info-like-menu nil))
+    (shr-tag-table cont)
+    (if eww-in-menu-class
+       (setq eww-info-like-menu (nreverse eww-info-like-menu)))))
+
+(defun eww-tag-link (cont)
+  (eww-handle-link cont)
+  (shr-generic cont))
+
+(defun eww-tag-a (cont)
+  (eww-handle-link cont)
+  (let ((start (point))
+       (href (cdr (assoc :href cont))))
+    (shr-tag-a cont)
+    (if href
+       (let ((text (buffer-substring start (point))))
+         (if eww-in-menu-class
+             (push (cons text href) eww-info-like-menu)
+           (push (cons text href) eww-xrefs))))))
+
 (defun eww-update-header-line-format ()
   (if eww-header-line-format
       (setq header-line-format (format-spec eww-header-line-format
@@ -208,7 +286,7 @@
     (erase-buffer))
   (eww-mode))
 
-(defvar eww-mode-map
+(setq eww-mode-map
   (let ((map (make-sparse-keymap)))
     (suppress-keymap map)
     (define-key map "q" 'eww-quit)
@@ -218,8 +296,25 @@
     (define-key map [delete] 'scroll-down-command)
     (define-key map "\177" 'scroll-down-command)
     (define-key map " " 'scroll-up-command)
+    (define-key map "l" 'eww-back-url)
+    (define-key map "n" 'eww-next-url)
     (define-key map "p" 'eww-previous-url)
-    ;;(define-key map "n" 'eww-next-url)
+    (define-key map "u" 'eww-up-url)
+    (define-key map "t" 'eww-top-url)
+    (define-key map "<" 'eww-top-url)
+    (define-key map "T" 'eww-toc)
+    (define-key map "m" 'eww-menu)
+    (define-key map "f" 'eww-follow-reference)
+    (define-key map "1" 'eww-nth-menu-item)
+    (define-key map "2" 'eww-nth-menu-item)
+    (define-key map "3" 'eww-nth-menu-item)
+    (define-key map "4" 'eww-nth-menu-item)
+    (define-key map "5" 'eww-nth-menu-item)
+    (define-key map "6" 'eww-nth-menu-item)
+    (define-key map "7" 'eww-nth-menu-item)
+    (define-key map "8" 'eww-nth-menu-item)
+    (define-key map "9" 'eww-nth-menu-item)
+    (define-key map "0" 'undefined)
     map))
 
 (define-derived-mode eww-mode nil "eww"
@@ -240,7 +335,7 @@
   (setq eww-history nil)
   (kill-buffer (current-buffer)))
 
-(defun eww-previous-url ()
+(defun eww-back-url ()
   "Go to the previously displayed page."
   (interactive)
   (when (zerop (length eww-history))
@@ -248,6 +343,77 @@
   (let ((prev (pop eww-history)))
     (url-retrieve (car prev) 'eww-render (list (car prev) (cadr prev)))))
 
+(defun eww-next-url ()
+  "Go to the page marked `next'.
+A page is marked `next' if rel=\"next\" appears in a <link>
+or <a> tag."
+  (interactive)
+  (if eww-next-url
+      (eww-browse-url (shr-expand-url eww-next-url eww-current-url))
+    (error "No `next' on this page")))
+
+(defun eww-previous-url ()
+  "Go to the page marked `previous'.
+A page is marked `previous' if rel=\"previous\" appears in a <link>
+or <a> tag."
+  (interactive)
+  (if eww-previous-url
+      (eww-browse-url (shr-expand-url eww-previous-url eww-current-url))
+    (error "No `previous' on this page")))
+
+(defun eww-up-url ()
+  "Go to the page marked `up'.
+A page is marked `up' if rel=\"up\" appears in a <link>
+or <a> tag."
+  (interactive)
+  (if eww-up-url
+      (eww-browse-url (shr-expand-url eww-up-url eww-current-url))
+    (error "No `up' on this page")))
+
+(defun eww-top-url ()
+  "Go to the page marked `top'.
+A page is marked `top' if rel=\"start\", rel=\"home\", or rel=\"contents\"
+appears in a <link> or <a> tag."
+  (interactive)
+  (let ((best-url (or eww-start-url
+                     eww-contents-url
+                     eww-home-url)))
+    (if best-url
+       (eww-browse-url (shr-expand-url best-url eww-current-url))
+      (error "No `top' for this page"))))
+
+(defun eww-toc ()
+  "Go to the page marked `contents'.
+A page is marked `contents' if rel=\"contents\" appears in a <link>
+or <a> tag."
+  (interactive)
+  (if eww-contents-url
+      (eww-browse-url (shr-expand-url eww-contents-url eww-current-url))
+    (error "No `contents' on this page")))
+
+(defun eww-follow-reference (ref)
+  (interactive
+   (list (completing-read "Menu item: " eww-xrefs nil t))) ;; FIXME history
+  (eww-browse-url (shr-expand-url (cdr (assoc ref eww-xrefs))
+                                 eww-current-url)))
+
+(defun eww-menu (ref)
+  (interactive
+   (list (completing-read "Menu item: " eww-info-like-menu nil t))) ;; FIXME 
history
+  (eww-browse-url (shr-expand-url (cdr (assoc ref eww-info-like-menu))
+                                 eww-current-url)))
+
+(defun eww-nth-menu-item ()
+  (interactive)
+  (let* ((n
+         (- (aref (this-command-keys) (1- (length (this-command-keys)))) ?1))
+        (menu-item (nth n eww-info-like-menu)))
+    (if menu-item
+       (eww-browse-url (shr-expand-url (cdr menu-item) eww-current-url))
+      (if eww-info-like-menu
+         (error "Too few items in menu")
+       (error "No menu in this page")))))
+
 (defun eww-reload ()
   "Reload the current page."
   (interactive)






reply via email to

[Prev in Thread] Current Thread [Next in Thread]