]> code.delx.au - gnu-emacs/blob - lisp/net/newst-reader.el
Add 2012 to FSF copyright years for Emacs files (do not merge to trunk)
[gnu-emacs] / lisp / net / newst-reader.el
1 ;;; newst-reader.el --- Generic RSS reader functions.
2
3 ;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5
6 ;; Author: Ulf Jasper <ulf.jasper@web.de>
7 ;; Filename: newst-reader.el
8 ;; URL: http://www.nongnu.org/newsticker
9 ;; Time-stamp: "6. Dezember 2009, 19:16:38 (ulf)"
10
11 ;; ======================================================================
12
13 ;; This file is part of GNU Emacs.
14
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
36 (require 'newst-backend)
37
38 ;; ======================================================================
39 ;;; Customization
40 ;; ======================================================================
41 (defun newsticker--set-customvar-formatting (symbol value)
42 "Set newsticker-variable SYMBOL value to VALUE.
43 Calls all actions which are necessary in order to make the new
44 value 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.
62 This 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.
73 This enables the following image properties: heuristic mask for all
74 logos, 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.
81 If non-nil newsticker calls `fill-region' to wrap long lines in
82 item descriptions. However, if an item description contains HTML
83 text and `newsticker-html-renderer' is non-nil, filling is not
84 done."
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.
97 If non-nil newsticker sets `fill-column' so that the whole
98 window 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.
106 If non-nil, newsticker.el will call this function whenever it finds
107 HTML-like tags in item descriptions. Possible functions are, for
108 example, `w3m-region', `w3-region', and (if you have htmlr.el installed)
109 `newsticker-htmlr-render'.
110
111 In order to make sure that the HTML renderer is loaded when you
112 run newsticker, you should add one of the following statements to
113 your .emacs. If you use w3m,
114
115 (autoload 'w3m-region \"w3m\"
116 \"Render region in current buffer and replace with result.\" t)
117
118 (autoload 'w3m-toggle-inline-image \"w3m\"
119 \"Toggle the visibility of an image under point.\" t)
120
121 or, if you use w3,
122
123 (require 'w3-auto)
124
125 or, if you use htmlr
126
127 (require 'htmlr)"
128 :type '(choice :tag "Function"
129 (const :tag "None" nil)
130 (const :tag "w3" w3-region)
131 (const :tag "w3m" w3m-region)
132 (const :tag "htmlr" newsticker-htmlr-render))
133 :set 'newsticker--set-customvar-formatting
134 :group 'newsticker-reader)
135
136 (defcustom newsticker-date-format
137 "(%A, %H:%M)"
138 "Format for the date part in item and feed lines.
139 See `format-time-string' for a list of valid specifiers."
140 :type 'string
141 :set 'newsticker--set-customvar-formatting
142 :group 'newsticker-reader)
143
144 (defgroup newsticker-faces nil
145 "Settings for the faces of the feed reader."
146 :group 'newsticker-reader)
147
148 (defface newsticker-feed-face
149 '((((class color) (background dark))
150 (:family "helvetica" :bold t :height 1.2 :foreground "misty rose"))
151 (((class color) (background light))
152 (:family "helvetica" :bold t :height 1.2 :foreground "black")))
153 "Face for news feeds."
154 :group 'newsticker-faces)
155
156 (defface newsticker-extra-face
157 '((((class color) (background dark))
158 (:italic t :foreground "gray50" :height 0.8))
159 (((class color) (background light))
160 (:italic t :foreground "gray50" :height 0.8)))
161 "Face for newsticker dates."
162 :group 'newsticker-faces)
163
164 (defface newsticker-enclosure-face
165 '((((class color) (background dark))
166 (:bold t :background "orange"))
167 (((class color) (background light))
168 (:bold t :background "orange")))
169 "Face for enclosed elements."
170 :group 'newsticker-faces)
171
172 ;; ======================================================================
173 ;;; Utility functions
174 ;; ======================================================================
175 (defun newsticker--insert-enclosure (item keymap)
176 "Insert enclosure element of a news ITEM into the current buffer.
177 KEYMAP will be applied."
178 (let ((enclosure (newsticker--enclosure item))
179 (beg (point)))
180 (when enclosure
181 (let ((url (cdr (assoc 'url enclosure)))
182 (length (string-to-number (or (cdr (assoc 'length enclosure))
183 "-1")))
184 (type (cdr (assoc 'type enclosure))))
185 (cond ((> length 1048576)
186 (insert (format "Enclosed file (%s, %1.2f MBytes)" type
187 (/ length 1048576))))
188 ((> length 1024)
189 (insert (format "Enclosed file (%s, %1.2f KBytes)" type
190 (/ length 1024))))
191 ((> length 0)
192 (insert (format "Enclosed file (%s, %1.2f Bytes)" type
193 length)))
194 (t
195 (insert (format "Enclosed file (%s, unknown size)" type))))
196 (add-text-properties beg (point)
197 (list 'mouse-face 'highlight
198 'nt-link url
199 'help-echo (format
200 "mouse-2: visit (%s)" url)
201 'keymap keymap
202 'nt-face 'enclosure
203 'nt-type 'desc))
204 (insert "\n")))))
205
206 (defun newsticker--print-extra-elements (item keymap)
207 "Insert extra-elements of ITEM in a pretty form into the current buffer.
208 KEYMAP is applied."
209 (let ((ignored-elements '(items link title description content
210 content:encoded dc:subject
211 dc:date entry item guid pubDate
212 published updated
213 enclosure))
214 (left-column-width 1))
215 (mapc (lambda (extra-element)
216 (when (listp extra-element) ;; take care of broken xml
217 ;; data, 2007-05-25
218 (unless (memq (car extra-element) ignored-elements)
219 (setq left-column-width (max left-column-width
220 (length (symbol-name
221 (car extra-element))))))))
222 (newsticker--extra item))
223 (mapc (lambda (extra-element)
224 (when (listp extra-element) ;; take care of broken xml
225 ;; data, 2007-05-25
226 (unless (memq (car extra-element) ignored-elements)
227 (newsticker--do-print-extra-element extra-element
228 left-column-width
229 keymap))))
230 (newsticker--extra item))))
231
232 (defun newsticker--do-print-extra-element (extra-element width keymap)
233 "Actually print an EXTRA-ELEMENT using the given WIDTH.
234 KEYMAP is applied."
235 (let ((name (symbol-name (car extra-element))))
236 (insert (format "%s: " name))
237 (insert (make-string (- width (length name)) ? )))
238 (let (;;(attributes (cadr extra-element)) ;FIXME!!!!
239 (contents (cddr extra-element)))
240 (cond ((listp contents)
241 (mapc (lambda (i)
242 (if (and (stringp i)
243 (string-match "^http://.*" i))
244 (let ((pos (point)))
245 (insert i " ") ; avoid self-reference from the
246 ; nt-link thing
247 (add-text-properties
248 pos (point)
249 (list 'mouse-face 'highlight
250 'nt-link i
251 'help-echo
252 (format "mouse-2: visit (%s)" i)
253 'keymap keymap)))
254 (insert (format "%s" i))))
255 contents))
256 (t
257 (insert (format "%s" contents))))
258 (insert "\n")))
259
260 (defun newsticker--image-read (feed-name-symbol disabled)
261 "Read the cached image for FEED-NAME-SYMBOL from disk.
262 If DISABLED is non-nil the image will be converted to a disabled look
263 \(unless `newsticker-enable-logo-manipulations' is not t\).
264 Return the image."
265 (let ((image-name (concat (newsticker--images-dir)
266 (symbol-name feed-name-symbol)))
267 (img nil))
268 (when (file-exists-p image-name)
269 (condition-case error-data
270 (setq img (create-image
271 image-name nil nil
272 :conversion (and newsticker-enable-logo-manipulations
273 disabled
274 'disabled)
275 :mask (and newsticker-enable-logo-manipulations
276 'heuristic)
277 :ascent 70))
278 (error
279 (message "Error: cannot create image for %s: %s"
280 feed-name-symbol error-data))))
281 img))
282
283 ;; the functions we need for retrieval and display
284 ;;;###autoload
285 (defun newsticker-show-news ()
286 "Start reading news. You may want to bind this to a key."
287 (interactive)
288 (newsticker-start t) ;; will start only if not running
289 (funcall newsticker-frontend))
290
291 ;; ======================================================================
292 ;;; Toolbar
293 ;; ======================================================================
294 (defconst newsticker--next-item-image
295 (and (fboundp 'image-type-available-p)
296 (image-type-available-p 'xpm)
297 (create-image "/* XPM */
298 static char * next_xpm[] = {
299 \"24 24 42 1\",
300 \" c None\",
301 \". c #000000\",
302 \"+ c #7EB6DE\",
303 \"@ c #82BBE2\",
304 \"# c #85BEE4\",
305 \"$ c #88C1E7\",
306 \"% c #8AC3E8\",
307 \"& c #87C1E6\",
308 \"* c #8AC4E9\",
309 \"= c #8CC6EA\",
310 \"- c #8CC6EB\",
311 \"; c #88C2E7\",
312 \"> c #8BC5E9\",
313 \", c #8DC7EB\",
314 \"' c #87C0E6\",
315 \") c #8AC4E8\",
316 \"! c #8BC5EA\",
317 \"~ c #8BC4E9\",
318 \"{ c #88C1E6\",
319 \"] c #89C3E8\",
320 \"^ c #86BFE5\",
321 \"/ c #83BBE2\",
322 \"( c #82BBE1\",
323 \"_ c #86C0E5\",
324 \": c #87C0E5\",
325 \"< c #83BCE2\",
326 \"[ c #81B9E0\",
327 \"} c #81BAE1\",
328 \"| c #78B0D9\",
329 \"1 c #7BB3DB\",
330 \"2 c #7DB5DD\",
331 \"3 c #7DB6DD\",
332 \"4 c #72A9D4\",
333 \"5 c #75ACD6\",
334 \"6 c #76AED7\",
335 \"7 c #77AFD8\",
336 \"8 c #6BA1CD\",
337 \"9 c #6EA4CF\",
338 \"0 c #6FA6D1\",
339 \"a c #6298C6\",
340 \"b c #659BC8\",
341 \"c c #5C91C0\",
342 \" \",
343 \" \",
344 \" . \",
345 \" .. \",
346 \" .+. \",
347 \" .@#. \",
348 \" .#$%. \",
349 \" .&*=-. \",
350 \" .;>,,,. \",
351 \" .;>,,,=. \",
352 \" .')!==~;. \",
353 \" .#{]*%;^/. \",
354 \" .(#_':#<. \",
355 \" .+[@</}. \",
356 \" .|1232. \",
357 \" .4567. \",
358 \" .890. \",
359 \" .ab. \",
360 \" .c. \",
361 \" .. \",
362 \" . \",
363 \" \",
364 \" \",
365 \" \"};
366 "
367 'xpm t))
368 "Image for the next item button.")
369
370 (defconst newsticker--previous-item-image
371 (and (fboundp 'image-type-available-p)
372 (image-type-available-p 'xpm)
373 (create-image "/* XPM */
374 static char * previous_xpm[] = {
375 \"24 24 39 1\",
376 \" c None\",
377 \". c #000000\",
378 \"+ c #7BB3DB\",
379 \"@ c #83BCE2\",
380 \"# c #7FB8DF\",
381 \"$ c #89C2E7\",
382 \"% c #86BFE5\",
383 \"& c #83BBE2\",
384 \"* c #8CC6EA\",
385 \"= c #8BC4E9\",
386 \"- c #88C2E7\",
387 \"; c #85BEE4\",
388 \"> c #8DC7EB\",
389 \", c #89C3E8\",
390 \"' c #8AC4E8\",
391 \") c #8BC5EA\",
392 \"! c #88C1E6\",
393 \"~ c #8AC4E9\",
394 \"{ c #8AC3E8\",
395 \"] c #86C0E5\",
396 \"^ c #87C0E6\",
397 \"/ c #87C0E5\",
398 \"( c #82BBE2\",
399 \"_ c #81BAE1\",
400 \": c #7FB7DF\",
401 \"< c #7DB6DD\",
402 \"[ c #7DB5DD\",
403 \"} c #7CB4DC\",
404 \"| c #79B1DA\",
405 \"1 c #76ADD7\",
406 \"2 c #77AFD8\",
407 \"3 c #73AAD4\",
408 \"4 c #70A7D1\",
409 \"5 c #6EA5D0\",
410 \"6 c #6CA2CE\",
411 \"7 c #689ECB\",
412 \"8 c #6399C7\",
413 \"9 c #6095C4\",
414 \"0 c #5C90C0\",
415 \" \",
416 \" \",
417 \" . \",
418 \" .. \",
419 \" .+. \",
420 \" .@#. \",
421 \" .$%&. \",
422 \" .*=-;. \",
423 \" .>>*,%. \",
424 \" .>>>*,%. \",
425 \" .')**=-;. \",
426 \" .;!,~{-%&. \",
427 \" .;]^/;@#. \",
428 \" .(@&_:+. \",
429 \" .<[}|1. \",
430 \" .2134. \",
431 \" .567. \",
432 \" .89. \",
433 \" .0. \",
434 \" .. \",
435 \" . \",
436 \" \",
437 \" \",
438 \" \"};
439 "
440 'xpm t))
441 "Image for the previous item button.")
442
443 (defconst newsticker--previous-feed-image
444 (and (fboundp 'image-type-available-p)
445 (image-type-available-p 'xpm)
446 (create-image "/* XPM */
447 static char * prev_feed_xpm[] = {
448 \"24 24 52 1\",
449 \" c None\",
450 \". c #000000\",
451 \"+ c #70A7D2\",
452 \"@ c #75ADD6\",
453 \"# c #71A8D3\",
454 \"$ c #79B1DA\",
455 \"% c #7BB3DB\",
456 \"& c #7DB5DD\",
457 \"* c #83BBE2\",
458 \"= c #7EB6DE\",
459 \"- c #78B0D9\",
460 \"; c #7FB7DE\",
461 \"> c #88C2E7\",
462 \", c #85BEE4\",
463 \"' c #80B9E0\",
464 \") c #80B8DF\",
465 \"! c #8CC6EA\",
466 \"~ c #89C3E8\",
467 \"{ c #86BFE5\",
468 \"] c #81BAE1\",
469 \"^ c #7CB4DC\",
470 \"/ c #7FB8DF\",
471 \"( c #8DC7EB\",
472 \"_ c #7BB3DC\",
473 \": c #7EB7DE\",
474 \"< c #8BC4E9\",
475 \"[ c #8AC4E9\",
476 \"} c #8AC3E8\",
477 \"| c #87C0E6\",
478 \"1 c #87C0E5\",
479 \"2 c #83BCE2\",
480 \"3 c #75ACD6\",
481 \"4 c #7FB7DF\",
482 \"5 c #77AED8\",
483 \"6 c #71A8D2\",
484 \"7 c #70A7D1\",
485 \"8 c #76ADD7\",
486 \"9 c #6CA2CE\",
487 \"0 c #699FCC\",
488 \"a c #73AAD4\",
489 \"b c #6BA1CD\",
490 \"c c #669CC9\",
491 \"d c #6298C5\",
492 \"e c #689ECB\",
493 \"f c #6499C7\",
494 \"g c #6095C3\",
495 \"h c #5C91C0\",
496 \"i c #5E93C2\",
497 \"j c #5B90C0\",
498 \"k c #588CBC\",
499 \"l c #578CBC\",
500 \"m c #5589BA\",
501 \" \",
502 \" \",
503 \" ... . \",
504 \" .+. .. \",
505 \" .@. .#. \",
506 \" .$. .%@. \",
507 \" .&. .*=-. \",
508 \" .;. .>,'%. \",
509 \" .). .!~{]^. \",
510 \" ./. .(!~{]_. \",
511 \" .:. .!!<>,'%. \",
512 \" .&. .~[}>{*=-. \",
513 \" .$. .|1,2/%@. \",
514 \" .3. .*]4%56. \",
515 \" .7. .^$8#9. \",
516 \" .0. .a7bc. \",
517 \" .d. .efg. \",
518 \" .h. .ij. \",
519 \" .k. .l. \",
520 \" .m. .. \",
521 \" ... . \",
522 \" \",
523 \" \",
524 \" \"};
525 "
526 'xpm t))
527 "Image for the previous feed button.")
528
529 (defconst newsticker--next-feed-image
530 (and (fboundp 'image-type-available-p)
531 (image-type-available-p 'xpm)
532 (create-image "/* XPM */
533 static char * next_feed_xpm[] = {
534 \"24 24 57 1\",
535 \" c None\",
536 \". c #000000\",
537 \"+ c #6CA2CE\",
538 \"@ c #75ADD6\",
539 \"# c #71A8D3\",
540 \"$ c #79B1DA\",
541 \"% c #7EB7DE\",
542 \"& c #7DB5DD\",
543 \"* c #81BAE1\",
544 \"= c #85BEE4\",
545 \"- c #78B0D9\",
546 \"; c #7FB7DE\",
547 \"> c #83BCE3\",
548 \", c #87C1E6\",
549 \"' c #8AC4E9\",
550 \") c #7BB3DB\",
551 \"! c #80B8DF\",
552 \"~ c #88C2E7\",
553 \"{ c #8BC5E9\",
554 \"] c #8DC7EB\",
555 \"^ c #7CB4DC\",
556 \"/ c #7FB8DF\",
557 \"( c #84BDE3\",
558 \"_ c #7BB3DC\",
559 \": c #83BCE2\",
560 \"< c #87C0E6\",
561 \"[ c #8AC4E8\",
562 \"} c #8BC5EA\",
563 \"| c #8CC6EA\",
564 \"1 c #88C1E6\",
565 \"2 c #89C3E8\",
566 \"3 c #8AC3E8\",
567 \"4 c #7EB6DE\",
568 \"5 c #82BBE1\",
569 \"6 c #86C0E5\",
570 \"7 c #87C0E5\",
571 \"8 c #75ACD6\",
572 \"9 c #7AB2DA\",
573 \"0 c #81B9E0\",
574 \"a c #82BBE2\",
575 \"b c #71A8D2\",
576 \"c c #70A7D1\",
577 \"d c #74ACD6\",
578 \"e c #699FCC\",
579 \"f c #6EA5D0\",
580 \"g c #72A9D4\",
581 \"h c #669CC9\",
582 \"i c #6298C5\",
583 \"j c #679DCA\",
584 \"k c #6BA1CD\",
585 \"l c #6095C3\",
586 \"m c #5C91C0\",
587 \"n c #5F94C2\",
588 \"o c #5B90C0\",
589 \"p c #588CBC\",
590 \"q c #578CBC\",
591 \"r c #5589BA\",
592 \" \",
593 \" \",
594 \" . ... \",
595 \" .. .+. \",
596 \" .@. .#. \",
597 \" .$%. .@. \",
598 \" .&*=. .-. \",
599 \" .;>,'. .). \",
600 \" .!=~{]. .^. \",
601 \" ./(~{]]. ._. \",
602 \" .%:<[}||. .). \",
603 \" .&*=12'3~. .-. \",
604 \" .$45=6<7. .@. \",
605 \" .8940a:. .b. \",
606 \" .cd-)&. .+. \",
607 \" .efg8. .h. \",
608 \" .ijk. .l. \",
609 \" .mn. .o. \",
610 \" .p. .q. \",
611 \" .. .r. \",
612 \" . ... \",
613 \" \",
614 \" \",
615 \" \"};
616 "
617 'xpm t))
618 "Image for the next feed button.")
619
620 (defconst newsticker--mark-read-image
621 (and (fboundp 'image-type-available-p)
622 (image-type-available-p 'xpm)
623 (create-image "/* XPM */
624 static char * mark_read_xpm[] = {
625 \"24 24 44 1\",
626 \" c None\",
627 \". c #C20000\",
628 \"+ c #BE0000\",
629 \"@ c #C70000\",
630 \"# c #CE0000\",
631 \"$ c #C90000\",
632 \"% c #BD0000\",
633 \"& c #CB0000\",
634 \"* c #D10000\",
635 \"= c #D70000\",
636 \"- c #D30000\",
637 \"; c #CD0000\",
638 \"> c #C60000\",
639 \", c #D40000\",
640 \"' c #DA0000\",
641 \") c #DE0000\",
642 \"! c #DB0000\",
643 \"~ c #D60000\",
644 \"{ c #D00000\",
645 \"] c #DC0000\",
646 \"^ c #E00000\",
647 \"/ c #E40000\",
648 \"( c #E10000\",
649 \"_ c #DD0000\",
650 \": c #D80000\",
651 \"< c #E50000\",
652 \"[ c #E70000\",
653 \"} c #E60000\",
654 \"| c #E20000\",
655 \"1 c #E90000\",
656 \"2 c #E80000\",
657 \"3 c #E30000\",
658 \"4 c #DF0000\",
659 \"5 c #D90000\",
660 \"6 c #CC0000\",
661 \"7 c #C10000\",
662 \"8 c #C30000\",
663 \"9 c #BF0000\",
664 \"0 c #B90000\",
665 \"a c #BC0000\",
666 \"b c #BB0000\",
667 \"c c #B80000\",
668 \"d c #B50000\",
669 \"e c #B70000\",
670 \" \",
671 \" \",
672 \" \",
673 \" . + \",
674 \" +@# $.% \",
675 \" &*= -;> \",
676 \" ,') !~{ \",
677 \" ]^/ (_: \",
678 \" (<[ }|) \",
679 \" <[1 2<| \",
680 \" }222[< \",
681 \" }}}< \",
682 \" 333| \",
683 \" _4^4)] \",
684 \" ~:' 5=- \",
685 \" 6{- *#$ \",
686 \" 7>$ @89 \",
687 \" 0a+ %bc \",
688 \" ddc edd \",
689 \" ddd ddd \",
690 \" d d \",
691 \" \",
692 \" \",
693 \" \"};
694 "
695 'xpm t))
696 "Image for the mark read button.")
697
698 (defconst newsticker--mark-immortal-image
699 (and (fboundp 'image-type-available-p)
700 (image-type-available-p 'xpm)
701 (create-image "/* XPM */
702 static char * mark_immortal_xpm[] = {
703 \"24 24 93 2\",
704 \" c None\",
705 \". c #171717\",
706 \"+ c #030303\",
707 \"@ c #000000\",
708 \"# c #181818\",
709 \"$ c #090909\",
710 \"% c #FFC960\",
711 \"& c #FFCB61\",
712 \"* c #FFCB62\",
713 \"= c #FFC961\",
714 \"- c #FFC75F\",
715 \"; c #FFC65E\",
716 \"> c #FFCA61\",
717 \", c #FFCD63\",
718 \"' c #FFCF65\",
719 \") c #FFD065\",
720 \"! c #FFCE64\",
721 \"~ c #FFC35C\",
722 \"{ c #FFC45D\",
723 \"] c #FFD166\",
724 \"^ c #FFD267\",
725 \"/ c #FFD368\",
726 \"( c #FFD167\",
727 \"_ c #FFC05A\",
728 \": c #010101\",
729 \"< c #040404\",
730 \"[ c #FFCC62\",
731 \"} c #FFD569\",
732 \"| c #FFD56A\",
733 \"1 c #FFC860\",
734 \"2 c #FFC25B\",
735 \"3 c #FFBB56\",
736 \"4 c #020202\",
737 \"5 c #060606\",
738 \"6 c #FFC15B\",
739 \"7 c #FFC85F\",
740 \"8 c #FFD469\",
741 \"9 c #FFD66A\",
742 \"0 c #FFBC57\",
743 \"a c #1B1B1B\",
744 \"b c #070707\",
745 \"c c #FFBA55\",
746 \"d c #FFB451\",
747 \"e c #FFB954\",
748 \"f c #FFB350\",
749 \"g c #FFB652\",
750 \"h c #FFBE58\",
751 \"i c #FFCD64\",
752 \"j c #FFD066\",
753 \"k c #FFC059\",
754 \"l c #FFB14E\",
755 \"m c #0B0B0B\",
756 \"n c #FFBB55\",
757 \"o c #FFC15A\",
758 \"p c #FFB552\",
759 \"q c #FFAD4B\",
760 \"r c #080808\",
761 \"s c #FFAF4C\",
762 \"t c #FFB853\",
763 \"u c #FFA948\",
764 \"v c #050505\",
765 \"w c #FFB04E\",
766 \"x c #FFB753\",
767 \"y c #FFBC56\",
768 \"z c #FFC55D\",
769 \"A c #FFC55E\",
770 \"B c #FFC45C\",
771 \"C c #FFBD57\",
772 \"D c #FFB854\",
773 \"E c #FFB34F\",
774 \"F c #FFAB4A\",
775 \"G c #FFA545\",
776 \"H c #FFAA49\",
777 \"I c #FFB04D\",
778 \"J c #FFB551\",
779 \"K c #FFBF58\",
780 \"L c #FFB24F\",
781 \"M c #FFAC4A\",
782 \"N c #FFA646\",
783 \"O c #FFA344\",
784 \"P c #FFA848\",
785 \"Q c #FFB14F\",
786 \"R c #FFAF4D\",
787 \"S c #FFA546\",
788 \"T c #FFA243\",
789 \"U c #FFA445\",
790 \"V c #FFAE4C\",
791 \"W c #FFA444\",
792 \"X c #FFA142\",
793 \"Y c #FF9F41\",
794 \"Z c #0A0A0A\",
795 \"` c #FF9E40\",
796 \" . c #FF9F40\",
797 \" \",
798 \" \",
799 \" \",
800 \" . + @ @ + # \",
801 \" $ @ % & * * = - + + \",
802 \" @ ; > , ' ) ' ! * - ~ @ \",
803 \" @ { > ! ] ^ / / ( ' * ; _ : \",
804 \" < _ ; [ ) / } | } / ] , 1 2 3 4 \",
805 \" 5 6 7 , ] 8 9 9 9 } ^ ! = ~ 0 a \",
806 \" b c 6 - , ] 8 9 9 9 } ^ ! % ~ 0 d 5 \",
807 \" : e _ ; * ) / 8 } } / ] , 1 2 3 f 5 \",
808 \" : g h { = i j ^ / ^ ] ! * ; k e l m \",
809 \" : f n o ; > , ' ) ' ! * - 2 0 p q r \",
810 \" : s g 0 6 ; % > * * = - ~ h t l u r \",
811 \" v u w x y k ~ z A z B o C D E F G b \",
812 \" 5 H I J e 0 h K h C c x L M N . \",
813 \" 4 O P q Q d g x g J L R H S T < \",
814 \" @ T U P F q V q M H N W X + \",
815 \" @ Y T O W G G W O X Y @ \",
816 \" 4 Z ` Y Y Y .` 4 4 \",
817 \" 5 : : @ @ Z \",
818 \" \",
819 \" \",
820 \" \"};
821 "
822 'xpm t))
823 "Image for the mark immortal button.")
824
825 (defconst newsticker--narrow-image
826 (and (fboundp 'image-type-available-p)
827 (image-type-available-p 'xpm)
828 (create-image "/* XPM */
829 static char * narrow_xpm[] = {
830 \"24 24 48 1\",
831 \" c None\",
832 \". c #000000\",
833 \"+ c #969696\",
834 \"@ c #9E9E9E\",
835 \"# c #A4A4A4\",
836 \"$ c #AAAAAA\",
837 \"% c #AEAEAE\",
838 \"& c #B1B1B1\",
839 \"* c #B3B3B3\",
840 \"= c #B4B4B4\",
841 \"- c #B2B2B2\",
842 \"; c #AFAFAF\",
843 \"> c #ABABAB\",
844 \", c #A6A6A6\",
845 \"' c #A0A0A0\",
846 \") c #989898\",
847 \"! c #909090\",
848 \"~ c #73AAD4\",
849 \"{ c #7AB2DA\",
850 \"] c #7FB8DF\",
851 \"^ c #84BDE3\",
852 \"/ c #88C2E7\",
853 \"( c #8BC5E9\",
854 \"_ c #8DC7EB\",
855 \": c #8CC6EA\",
856 \"< c #89C3E8\",
857 \"[ c #86BFE5\",
858 \"} c #81BAE1\",
859 \"| c #7BB3DC\",
860 \"1 c #75ACD6\",
861 \"2 c #6DA4CF\",
862 \"3 c #979797\",
863 \"4 c #A3A3A3\",
864 \"5 c #A8A8A8\",
865 \"6 c #ADADAD\",
866 \"7 c #ACACAC\",
867 \"8 c #A9A9A9\",
868 \"9 c #A5A5A5\",
869 \"0 c #9A9A9A\",
870 \"a c #929292\",
871 \"b c #8C8C8C\",
872 \"c c #808080\",
873 \"d c #818181\",
874 \"e c #838383\",
875 \"f c #848484\",
876 \"g c #858585\",
877 \"h c #868686\",
878 \"i c #828282\",
879 \" \",
880 \" \",
881 \" \",
882 \" .................. \",
883 \" .+@#$%&*=*-;>,')!. \",
884 \" .................. \",
885 \" \",
886 \" \",
887 \" .................. \",
888 \" .~{]^/(___:<[}|12. \",
889 \" .................. \",
890 \" \",
891 \" \",
892 \" .................. \",
893 \" .!3@45>666789'0ab. \",
894 \" .................. \",
895 \" \",
896 \" \",
897 \" .................. \",
898 \" .cccdefghhgficccc. \",
899 \" .................. \",
900 \" \",
901 \" \",
902 \" \"};
903 "
904 'xpm t))
905 "Image for the narrow image button.")
906
907 (defconst newsticker--get-all-image
908 (and (fboundp 'image-type-available-p)
909 (image-type-available-p 'xpm)
910 (create-image "/* XPM */
911 static char * get_all_xpm[] = {
912 \"24 24 70 1\",
913 \" c None\",
914 \". c #000000\",
915 \"+ c #F3DA00\",
916 \"@ c #F5DF00\",
917 \"# c #F7E300\",
918 \"$ c #F9E700\",
919 \"% c #FAEA00\",
920 \"& c #FBEC00\",
921 \"* c #FBED00\",
922 \"= c #FCEE00\",
923 \"- c #FAEB00\",
924 \"; c #F9E800\",
925 \"> c #F8E500\",
926 \", c #F6E000\",
927 \"' c #F4DB00\",
928 \") c #F1D500\",
929 \"! c #EFD000\",
930 \"~ c #B7CA00\",
931 \"{ c #BFD100\",
932 \"] c #C5D700\",
933 \"^ c #CBDB00\",
934 \"/ c #CFDF00\",
935 \"( c #D2E200\",
936 \"_ c #D4E400\",
937 \": c #D3E300\",
938 \"< c #D0E000\",
939 \"[ c #CCDD00\",
940 \"} c #C7D800\",
941 \"| c #C1D300\",
942 \"1 c #BACC00\",
943 \"2 c #B1C500\",
944 \"3 c #A8BC00\",
945 \"4 c #20A900\",
946 \"5 c #22AF00\",
947 \"6 c #24B500\",
948 \"7 c #26B900\",
949 \"8 c #27BC00\",
950 \"9 c #27BE00\",
951 \"0 c #28BF00\",
952 \"a c #27BD00\",
953 \"b c #26BA00\",
954 \"c c #25B600\",
955 \"d c #23B100\",
956 \"e c #21AB00\",
957 \"f c #1FA400\",
958 \"g c #1C9B00\",
959 \"h c #21AA00\",
960 \"i c #24B300\",
961 \"j c #25B800\",
962 \"k c #25B700\",
963 \"l c #24B400\",
964 \"m c #23B000\",
965 \"n c #1FA500\",
966 \"o c #1D9E00\",
967 \"p c #20A800\",
968 \"q c #21AC00\",
969 \"r c #23B200\",
970 \"s c #22AD00\",
971 \"t c #1D9F00\",
972 \"u c #20A700\",
973 \"v c #1EA100\",
974 \"w c #1C9C00\",
975 \"x c #1DA000\",
976 \"y c #1B9800\",
977 \"z c #1A9600\",
978 \"A c #1A9700\",
979 \"B c #1A9500\",
980 \"C c #199200\",
981 \"D c #189100\",
982 \"E c #178C00\",
983 \" \",
984 \" \",
985 \" \",
986 \" \",
987 \" ................... \",
988 \" .+@#$%&*=*&-;>,')!. \",
989 \" ................... \",
990 \" \",
991 \" ................... \",
992 \" .~{]^/(___:<[}|123. \",
993 \" ................... \",
994 \" \",
995 \" ................... \",
996 \" .45678909abcdefg. \",
997 \" .h5icj7jklmeno. \",
998 \" .pq5drrmshft. \",
999 \" .fu4h4pnvw. \",
1000 \" .oxvxtwy. \",
1001 \" .zAAzB. \",
1002 \" .CCD. \",
1003 \" .E. \",
1004 \" . \",
1005 \" \",
1006 \" \"};
1007 "
1008 'xpm t))
1009 "Image for the get all image button.")
1010
1011 (defconst newsticker--update-image
1012 (and (fboundp 'image-type-available-p)
1013 (image-type-available-p 'xpm)
1014 (create-image "/* XPM */
1015 static char * update_xpm[] = {
1016 \"24 24 37 1\",
1017 \" c None\",
1018 \". c #076D00\",
1019 \"+ c #0A8600\",
1020 \"@ c #0A8800\",
1021 \"# c #098400\",
1022 \"$ c #087200\",
1023 \"% c #087900\",
1024 \"& c #098500\",
1025 \"* c #098100\",
1026 \"= c #087600\",
1027 \"- c #097E00\",
1028 \"; c #097F00\",
1029 \"> c #0A8700\",
1030 \", c #0A8C00\",
1031 \"' c #097C00\",
1032 \") c #098300\",
1033 \"! c #0A8900\",
1034 \"~ c #0A8E00\",
1035 \"{ c #0B9200\",
1036 \"] c #087700\",
1037 \"^ c #076E00\",
1038 \"/ c #076C00\",
1039 \"( c #076B00\",
1040 \"_ c #076A00\",
1041 \": c #076900\",
1042 \"< c #076800\",
1043 \"[ c #066700\",
1044 \"} c #066500\",
1045 \"| c #066400\",
1046 \"1 c #066300\",
1047 \"2 c #066600\",
1048 \"3 c #066200\",
1049 \"4 c #076700\",
1050 \"5 c #065E00\",
1051 \"6 c #066100\",
1052 \"7 c #065F00\",
1053 \"8 c #066000\",
1054 \" \",
1055 \" \",
1056 \" \",
1057 \" . +@@@+# \",
1058 \" $% &@ +* \",
1059 \" =-# ; \",
1060 \" %*>, ' \",
1061 \" ')!~{ = \",
1062 \" ]$ \",
1063 \" ^ ^ \",
1064 \" . . \",
1065 \" / ( \",
1066 \" _ : \",
1067 \" < [ \",
1068 \" } | \",
1069 \" [[ \",
1070 \" 1 $.:23 \",
1071 \" 3 4}35 \",
1072 \" 6 655 \",
1073 \" 76 85 55 \",
1074 \" 5555555 5 \",
1075 \" \",
1076 \" \",
1077 \" \"};
1078 "
1079 'xpm t))
1080 "Image for the update button.")
1081
1082 (defconst newsticker--browse-image
1083 (and (fboundp 'image-type-available-p)
1084 (image-type-available-p 'xpm)
1085 (create-image "/* XPM */
1086 static char * visit_xpm[] = {
1087 \"24 24 39 1\",
1088 \" c None\",
1089 \". c #000000\",
1090 \"+ c #FFFFFF\",
1091 \"@ c #00E63D\",
1092 \"# c #00E83E\",
1093 \"$ c #00E73D\",
1094 \"% c #00E93E\",
1095 \"& c #00E63C\",
1096 \"* c #00E53C\",
1097 \"= c #00E23B\",
1098 \"- c #00E33B\",
1099 \"; c #00E83D\",
1100 \"> c #00E13A\",
1101 \", c #00DD38\",
1102 \"' c #00DE38\",
1103 \") c #00E23A\",
1104 \"! c #00E43C\",
1105 \"~ c #00DF39\",
1106 \"{ c #00DB37\",
1107 \"] c #00D634\",
1108 \"^ c #00D734\",
1109 \"/ c #00E039\",
1110 \"( c #00DC37\",
1111 \"_ c #00D835\",
1112 \": c #00D332\",
1113 \"< c #00CD2F\",
1114 \"[ c #00DB36\",
1115 \"} c #00D433\",
1116 \"| c #00CF30\",
1117 \"1 c #00DA36\",
1118 \"2 c #00D936\",
1119 \"3 c #00D533\",
1120 \"4 c #00D131\",
1121 \"5 c #00CE2F\",
1122 \"6 c #00CC2F\",
1123 \"7 c #00CA2D\",
1124 \"8 c #00C62B\",
1125 \"9 c #00C52A\",
1126 \"0 c #00BE27\",
1127 \" \",
1128 \" \",
1129 \" . \",
1130 \" .+. \",
1131 \" .+++. \",
1132 \" .++.++. \",
1133 \" .++.@.++. \",
1134 \" .++.##$.++. \",
1135 \" .++.%%%#&.++. \",
1136 \" .++.$%%%#*=.++. \",
1137 \" .++.-@;##$*>,.++. \",
1138 \" .++.')!&@@*=~{].++. \",
1139 \" .++.^{~>---)/(_:<.++. \",
1140 \" .++.^[,~/~'(_}|.++. \",
1141 \" .++.]_1[12^:|.++. \",
1142 \" .++.:}33:45.++. \",
1143 \" .++.<5567.++. \",
1144 \" .++.889.++. \",
1145 \" .++.0.++. \",
1146 \" .++.++. \",
1147 \" .+++. \",
1148 \" .+. \",
1149 \" . \",
1150 \" \"};
1151 "
1152 'xpm t))
1153 "Image for the browse button.")
1154
1155 (defun newsticker-browse-url-item (feed item)
1156 "Convert FEED ITEM to html and call `browse-url' on result."
1157 (interactive)
1158 (let ((t-file (make-temp-file "newsticker")))
1159 (with-temp-file t-file
1160 (insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>
1161 <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
1162 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
1163 <html xmlns=\"http://www.w3.org/1999/xhtml\">
1164 <body>")
1165 (insert "<h1>" feed ": " (newsticker--title item) "</h1>")
1166 (insert (format-time-string newsticker-date-format
1167 (newsticker--time item)))
1168 (insert "<br/>")
1169 (insert (or (newsticker--desc item) "[No Description]"))
1170 (when (newsticker--enclosure item)
1171 (insert "<br/><hr/><i>")
1172 (newsticker--insert-enclosure item nil)
1173 (insert "</i>"))
1174 (when (newsticker--extra item)
1175 (insert "<br/><hr/><tt>")
1176 (newsticker--print-extra-elements item nil)
1177 (insert "</tt>"))
1178 (insert "</body></html>"))
1179 (browse-url t-file)))
1180
1181 (provide 'newst-reader)
1182
1183 ;; arch-tag: c604b701-bdf1-4fc1-8d05-5fabd1939533
1184 ;;; newst-reader.el ends here