1 ;;; eww.el --- Emacs Web Wowser
3 ;; Copyright (C) 2013 Free Software Foundation, Inc.
5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
27 (eval-when-compile (require 'cl))
31 (defvar eww-current-url nil)
32 (defvar eww-history nil)
35 "Fetch URL and render the page."
36 (interactive "sUrl: ")
37 (url-retrieve url 'eww-render (list url)))
39 (defun eww-render (status url &optional point)
40 (let* ((headers (eww-parse-headers))
42 (mail-header-parse-content-type
43 (or (cdr (assoc "content-type" headers))
47 (or (cdr (assq 'charset (cdr content-type)))
49 (data-buffer (current-buffer)))
53 ((equal (car content-type) "text/html")
54 (eww-display-html charset url))
55 ((string-match "^image/" (car content-type))
58 (eww-display-raw charset)))
61 (kill-buffer data-buffer))))
63 (defun eww-parse-headers ()
65 (while (and (not (eobp))
67 (when (looking-at "\\([^:]+\\): *\\(.*\\)")
68 (push (cons (downcase (match-string 1))
76 (defun eww-display-html (charset url)
77 (unless (eq charset 'utf8)
78 (decode-coding-region (point) (point-max) charset))
81 'base (list (cons 'href url))
82 (libxml-parse-html-region (point) (point-max)))))
84 (setq eww-current-url url)
85 (let ((inhibit-read-only t))
86 (shr-insert-document document))
87 (goto-char (point-min))))
89 (defun eww-display-raw (charset)
90 (let ((data (buffer-substring (point) (point-max))))
92 (let ((inhibit-read-only t))
94 (goto-char (point-min))))
96 (defun eww-display-image ()
97 (let ((data (buffer-substring (point) (point-max))))
99 (let ((inhibit-read-only t))
100 (shr-put-image data nil))
101 (goto-char (point-min))))
103 (defun eww-setup-buffer ()
104 (pop-to-buffer (get-buffer-create "*eww*"))
105 (let ((inhibit-read-only t))
110 (let ((map (make-sparse-keymap)))
111 (suppress-keymap map)
112 (define-key map "q" 'eww-quit)
113 (define-key map [tab] 'widget-forward)
114 (define-key map [backtab] 'widget-backward)
115 (define-key map [delete] 'scroll-down-command)
116 (define-key map "\177" 'scroll-down-command)
117 (define-key map " " 'scroll-up-command)
118 (define-key map "p" 'eww-previous-url)
119 ;;(define-key map "n" 'eww-next-url)
123 "Mode for browsing the web.
127 (setq major-mode 'eww-mode
129 (set (make-local-variable 'eww-current-url) 'author)
130 (set (make-local-variable 'browse-url-browser-function) 'eww-browse-url)
131 (setq buffer-read-only t)
132 (use-local-map eww-mode-map))
134 (defun eww-browse-url (url &optional new-window)
135 (push (list eww-current-url (point))
140 "Exit the Emacs Web Wowser."
142 (setq eww-history nil)
143 (kill-buffer (current-buffer)))
145 (defun eww-previous-url ()
146 "Go to the previously displayed page."
148 (when (zerop (length eww-history))
149 (error "No previous page"))
150 (let ((prev (pop eww-history)))
151 (url-retrieve (car prev) 'eww-render (list (car prev) (cadr prev)))))