Merge from emacs-24; up to 2012-12-06T01:39:03Z!monnier@iro.umontreal.ca
[bpt/emacs.git] / lisp / net / newst-reader.el
CommitLineData
2900b2d8 1;;; newst-reader.el --- Generic RSS reader functions.
2415d4c6 2
ab422c4d 3;; Copyright (C) 2003-2013 Free Software Foundation, Inc.
2415d4c6 4
2415d4c6 5;; Author: Ulf Jasper <ulf.jasper@web.de>
2900b2d8 6;; Filename: newst-reader.el
2415d4c6 7;; URL: http://www.nongnu.org/newsticker
2ac2721a 8;; Time-stamp: "24. September 2011, 15:47:49 (ulf)"
bd78fa1d 9;; Package: newsticker
2415d4c6
UJ
10
11;; ======================================================================
12
faeb9c70
GM
13;; This file is part of GNU Emacs.
14
2415d4c6
UJ
15;; GNU Emacs is free software: you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation, either version 3 of the License, or
18;; (at your option) any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
27
28;; ======================================================================
29;;; Commentary:
30
31;; See newsticker.el
32
33;; ======================================================================
34;;; Code:
35
8e39154d 36(require 'newst-backend)
2415d4c6
UJ
37
38;; ======================================================================
39;;; Customization
40;; ======================================================================
41(defun newsticker--set-customvar-formatting (symbol value)
42 "Set newsticker-variable SYMBOL value to VALUE.
43Calls all actions which are necessary in order to make the new
44value effective."
45 (if (or (not (boundp symbol))
46 (equal (symbol-value symbol) value))
47 (set symbol value)
48 ;; something must have changed
49 (set symbol value)
50 (when (fboundp 'newsticker--forget-preformatted)
51 (newsticker--forget-preformatted))))
52
53;; ======================================================================
54;; reader
55(defgroup newsticker-reader nil
56 "Settings for the feed reader."
57 :group 'newsticker)
58
59(defcustom newsticker-frontend
60 'newsticker-treeview
61 "Newsticker frontend for reading news.
62This must be one of the functions `newsticker-plainview' or
63`newsticker-treeview'."
64 :type '(choice :tag "Frontend"
65 (const :tag "Single buffer (plainview)" newsticker-plainview)
66 (const :tag "Tree view (treeview)" newsticker-treeview))
67 :group 'newsticker-reader)
68
69;; image related things
70(defcustom newsticker-enable-logo-manipulations
71 t
72 "If non-nil newsticker manipulates logo images.
73This enables the following image properties: heuristic mask for all
74logos, and laplace-conversion for images without new items."
75 :type 'boolean
76 :group 'newsticker-reader)
77
78(defcustom newsticker-justification
79 'left
80 "How to fill item descriptions.
81If non-nil newsticker calls `fill-region' to wrap long lines in
82item descriptions. However, if an item description contains HTML
83text and `newsticker-html-renderer' is non-nil, filling is not
84done."
85 :type '(choice :tag "Justification"
86 (const :tag "No filling" nil)
87 (const :tag "Left" left)
88 (const :tag "Right" right)
89 (const :tag "Center" center)
90 (const :tag "Full" full))
91 :set 'newsticker--set-customvar-formatting
92 :group 'newsticker-reader)
93
94(defcustom newsticker-use-full-width
95 t
96 "Decides whether to use the full window width when filling.
97If non-nil newsticker sets `fill-column' so that the whole
98window is used when filling. See also `newsticker-justification'."
99 :type 'boolean
100 :set 'newsticker--set-customvar-formatting
101 :group 'newsticker-reader)
102
103(defcustom newsticker-html-renderer
104 nil
105 "Function for rendering HTML contents.
2ac2721a
UJ
106If non-nil, newsticker.el will call this function whenever it
107finds HTML-like tags in item descriptions. Possible functions
108are `w3m-region', `w3-region', and `newsticker-htmlr-render'.
109Newsticker automatically loads the respective package w3m, w3, or
110htmlr if this option is set."
2415d4c6
UJ
111 :type '(choice :tag "Function"
112 (const :tag "None" nil)
113 (const :tag "w3" w3-region)
114 (const :tag "w3m" w3m-region)
115 (const :tag "htmlr" newsticker-htmlr-render))
116 :set 'newsticker--set-customvar-formatting
117 :group 'newsticker-reader)
118
119(defcustom newsticker-date-format
120 "(%A, %H:%M)"
121 "Format for the date part in item and feed lines.
122See `format-time-string' for a list of valid specifiers."
123 :type 'string
124 :set 'newsticker--set-customvar-formatting
125 :group 'newsticker-reader)
126
0d00764a
UJ
127(defgroup newsticker-faces nil
128 "Settings for the faces of the feed reader."
129 :group 'newsticker-reader)
130
131(defface newsticker-feed-face
4b56d0fe
CY
132 '((default :weight bold :height 1.2)
133 (((class color) (background dark)) :foreground "white")
134 (((class color) (background light)) :foreground "black"))
0d00764a
UJ
135 "Face for news feeds."
136 :group 'newsticker-faces)
137
138(defface newsticker-extra-face
4b56d0fe
CY
139 '((default :slant italic :height 0.8)
140 (((class color) (background dark)) :foreground "gray50")
141 (((class color) (background light)) :foreground "gray50"))
0d00764a
UJ
142 "Face for newsticker dates."
143 :group 'newsticker-faces)
144
145(defface newsticker-enclosure-face
4b56d0fe
CY
146 '((default :weight bold)
147 (((class color) (background dark)) :background "orange")
148 (((class color) (background light)) :background "orange"))
0d00764a
UJ
149 "Face for enclosed elements."
150 :group 'newsticker-faces)
151
2415d4c6
UJ
152;; ======================================================================
153;;; Utility functions
154;; ======================================================================
155(defun newsticker--insert-enclosure (item keymap)
156 "Insert enclosure element of a news ITEM into the current buffer.
157KEYMAP will be applied."
158 (let ((enclosure (newsticker--enclosure item))
159 (beg (point)))
160 (when enclosure
161 (let ((url (cdr (assoc 'url enclosure)))
162 (length (string-to-number (or (cdr (assoc 'length enclosure))
163 "-1")))
164 (type (cdr (assoc 'type enclosure))))
165 (cond ((> length 1048576)
166 (insert (format "Enclosed file (%s, %1.2f MBytes)" type
167 (/ length 1048576))))
168 ((> length 1024)
169 (insert (format "Enclosed file (%s, %1.2f KBytes)" type
170 (/ length 1024))))
171 ((> length 0)
172 (insert (format "Enclosed file (%s, %1.2f Bytes)" type
173 length)))
174 (t
175 (insert (format "Enclosed file (%s, unknown size)" type))))
176 (add-text-properties beg (point)
177 (list 'mouse-face 'highlight
178 'nt-link url
179 'help-echo (format
180 "mouse-2: visit (%s)" url)
181 'keymap keymap
182 'nt-face 'enclosure
183 'nt-type 'desc))
184 (insert "\n")))))
185
186(defun newsticker--print-extra-elements (item keymap)
187 "Insert extra-elements of ITEM in a pretty form into the current buffer.
188KEYMAP is applied."
189 (let ((ignored-elements '(items link title description content
190 content:encoded dc:subject
191 dc:date entry item guid pubDate
192 published updated
193 enclosure))
194 (left-column-width 1))
195 (mapc (lambda (extra-element)
196 (when (listp extra-element) ;; take care of broken xml
197 ;; data, 2007-05-25
198 (unless (memq (car extra-element) ignored-elements)
199 (setq left-column-width (max left-column-width
200 (length (symbol-name
201 (car extra-element))))))))
202 (newsticker--extra item))
203 (mapc (lambda (extra-element)
204 (when (listp extra-element) ;; take care of broken xml
205 ;; data, 2007-05-25
206 (unless (memq (car extra-element) ignored-elements)
207 (newsticker--do-print-extra-element extra-element
208 left-column-width
209 keymap))))
210 (newsticker--extra item))))
211
212(defun newsticker--do-print-extra-element (extra-element width keymap)
213 "Actually print an EXTRA-ELEMENT using the given WIDTH.
214KEYMAP is applied."
215 (let ((name (symbol-name (car extra-element))))
216 (insert (format "%s: " name))
217 (insert (make-string (- width (length name)) ? )))
218 (let (;;(attributes (cadr extra-element)) ;FIXME!!!!
219 (contents (cddr extra-element)))
220 (cond ((listp contents)
221 (mapc (lambda (i)
222 (if (and (stringp i)
223 (string-match "^http://.*" i))
224 (let ((pos (point)))
225 (insert i " ") ; avoid self-reference from the
226 ; nt-link thing
227 (add-text-properties
228 pos (point)
229 (list 'mouse-face 'highlight
230 'nt-link i
231 'help-echo
232 (format "mouse-2: visit (%s)" i)
233 'keymap keymap)))
234 (insert (format "%s" i))))
235 contents))
236 (t
237 (insert (format "%s" contents))))
238 (insert "\n")))
239
240(defun newsticker--image-read (feed-name-symbol disabled)
241 "Read the cached image for FEED-NAME-SYMBOL from disk.
242If DISABLED is non-nil the image will be converted to a disabled look
243\(unless `newsticker-enable-logo-manipulations' is not t\).
244Return the image."
a59c6c51 245 (let ((image-name (concat (newsticker--images-dir)
2415d4c6
UJ
246 (symbol-name feed-name-symbol)))
247 (img nil))
248 (when (file-exists-p image-name)
249 (condition-case error-data
250 (setq img (create-image
251 image-name nil nil
252 :conversion (and newsticker-enable-logo-manipulations
253 disabled
254 'disabled)
255 :mask (and newsticker-enable-logo-manipulations
256 'heuristic)
257 :ascent 70))
258 (error
259 (message "Error: cannot create image for %s: %s"
260 feed-name-symbol error-data))))
261 img))
262
263;; the functions we need for retrieval and display
264;;;###autoload
265(defun newsticker-show-news ()
266 "Start reading news. You may want to bind this to a key."
267 (interactive)
268 (newsticker-start t) ;; will start only if not running
2ac2721a
UJ
269 ;; Load the html rendering packages
270 (if newsticker-html-renderer
271 (cond ((eq newsticker-html-renderer 'w3m-region)
272 (require 'w3m))
273 ((eq newsticker-html-renderer 'w3-region)
274 (require 'w3-auto))
275 ((eq newsticker-html-renderer 'newsticker-htmlr-render)
276 (require 'htmlr))))
2415d4c6
UJ
277 (funcall newsticker-frontend))
278
279;; ======================================================================
280;;; Toolbar
281;; ======================================================================
2415d4c6 282
62c4fff6
UJ
283(defun newsticker-browse-url-item (feed item)
284 "Convert FEED ITEM to html and call `browse-url' on result."
285 (interactive)
286 (let ((t-file (make-temp-file "newsticker")))
287 (with-temp-file t-file
288 (insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>
289 <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
290 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
291 <html xmlns=\"http://www.w3.org/1999/xhtml\">
292 <body>")
293 (insert "<h1>" feed ": " (newsticker--title item) "</h1>")
294 (insert (format-time-string newsticker-date-format
295 (newsticker--time item)))
296 (insert "<br/>")
297 (insert (or (newsticker--desc item) "[No Description]"))
298 (when (newsticker--enclosure item)
299 (insert "<br/><hr/><i>")
300 (newsticker--insert-enclosure item nil)
301 (insert "</i>"))
302 (when (newsticker--extra item)
303 (insert "<br/><hr/><tt>")
304 (newsticker--print-extra-elements item nil)
305 (insert "</tt>"))
306 (insert "</body></html>"))
307 (browse-url t-file)))
308
8e39154d 309(provide 'newst-reader)
041fa0d4 310
2900b2d8 311;;; newst-reader.el ends here