1 ;;; newsticker-reader.el --- Generic RSS reader functions.
3 ;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
6 ;; This file is part of GNU Emacs.
8 ;; Author: Ulf Jasper <ulf.jasper@web.de>
9 ;; Filename: newsticker-reader.el
10 ;; URL: http://www.nongnu.org/newsticker
11 ;; Time-stamp: "7. Juni 2008, 15:34:08 (ulf)"
12 ;; CVS-Version: $Id: newsticker-reader.el,v 1.3 2008/06/10 03:08:58 gm Exp $
14 ;; ======================================================================
16 ;; GNU Emacs is free software: you can redistribute it and/or modify
17 ;; it under the terms of the GNU General Public License as published by
18 ;; the Free Software Foundation, either version 3 of the License, or
19 ;; (at your option) any later version.
21 ;; GNU Emacs is distributed in the hope that it will be useful,
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 ;; GNU General Public License for more details.
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
29 ;; ======================================================================
34 ;; ======================================================================
37 (require 'newsticker-backend
)
39 ;; ======================================================================
41 ;; ======================================================================
42 (defun newsticker--set-customvar-formatting (symbol value
)
43 "Set newsticker-variable SYMBOL value to VALUE.
44 Calls all actions which are necessary in order to make the new
46 (if (or (not (boundp symbol
))
47 (equal (symbol-value symbol
) value
))
49 ;; something must have changed
51 (when (fboundp 'newsticker--forget-preformatted
)
52 (newsticker--forget-preformatted))))
54 ;; ======================================================================
56 (defgroup newsticker-reader nil
57 "Settings for the feed reader."
60 (defcustom newsticker-frontend
62 "Newsticker frontend for reading news.
63 This must be one of the functions `newsticker-plainview' or
64 `newsticker-treeview'."
65 :type
'(choice :tag
"Frontend"
66 (const :tag
"Single buffer (plainview)" newsticker-plainview
)
67 (const :tag
"Tree view (treeview)" newsticker-treeview
))
68 :group
'newsticker-reader
)
70 ;; image related things
71 (defcustom newsticker-enable-logo-manipulations
73 "If non-nil newsticker manipulates logo images.
74 This enables the following image properties: heuristic mask for all
75 logos, and laplace-conversion for images without new items."
77 :group
'newsticker-reader
)
79 (defcustom newsticker-justification
81 "How to fill item descriptions.
82 If non-nil newsticker calls `fill-region' to wrap long lines in
83 item descriptions. However, if an item description contains HTML
84 text and `newsticker-html-renderer' is non-nil, filling is not
86 :type
'(choice :tag
"Justification"
87 (const :tag
"No filling" nil
)
88 (const :tag
"Left" left
)
89 (const :tag
"Right" right
)
90 (const :tag
"Center" center
)
91 (const :tag
"Full" full
))
92 :set
'newsticker--set-customvar-formatting
93 :group
'newsticker-reader
)
95 (defcustom newsticker-use-full-width
97 "Decides whether to use the full window width when filling.
98 If non-nil newsticker sets `fill-column' so that the whole
99 window is used when filling. See also `newsticker-justification'."
101 :set
'newsticker--set-customvar-formatting
102 :group
'newsticker-reader
)
104 (defcustom newsticker-html-renderer
106 "Function for rendering HTML contents.
107 If non-nil, newsticker.el will call this function whenever it finds
108 HTML-like tags in item descriptions. Possible functions are, for
109 example, `w3m-region', `w3-region', and (if you have htmlr.el installed)
110 `newsticker-htmlr-render'.
112 In order to make sure that the HTML renderer is loaded when you
113 run newsticker, you should add one of the following statements to
114 your .emacs. If you use w3m,
116 (autoload 'w3m-region \"w3m\"
117 \"Render region in current buffer and replace with result.\" t)
119 (autoload 'w3m-toggle-inline-image \"w3m\"
120 \"Toggle the visibility of an image under point.\" t)
129 :type
'(choice :tag
"Function"
130 (const :tag
"None" nil
)
131 (const :tag
"w3" w3-region
)
132 (const :tag
"w3m" w3m-region
)
133 (const :tag
"htmlr" newsticker-htmlr-render
))
134 :set
'newsticker--set-customvar-formatting
135 :group
'newsticker-reader
)
137 (defcustom newsticker-date-format
139 "Format for the date part in item and feed lines.
140 See `format-time-string' for a list of valid specifiers."
142 :set
'newsticker--set-customvar-formatting
143 :group
'newsticker-reader
)
145 ;; ======================================================================
146 ;;; Utility functions
147 ;; ======================================================================
148 (defun newsticker--insert-enclosure (item keymap
)
149 "Insert enclosure element of a news ITEM into the current buffer.
150 KEYMAP will be applied."
151 (let ((enclosure (newsticker--enclosure item
))
154 (let ((url (cdr (assoc 'url enclosure
)))
155 (length (string-to-number (or (cdr (assoc 'length enclosure
))
157 (type (cdr (assoc 'type enclosure
))))
158 (cond ((> length
1048576)
159 (insert (format "Enclosed file (%s, %1.2f MBytes)" type
160 (/ length
1048576))))
162 (insert (format "Enclosed file (%s, %1.2f KBytes)" type
165 (insert (format "Enclosed file (%s, %1.2f Bytes)" type
168 (insert (format "Enclosed file (%s, unknown size)" type
))))
169 (add-text-properties beg
(point)
170 (list 'mouse-face
'highlight
173 "mouse-2: visit (%s)" url
)
179 (defun newsticker--print-extra-elements (item keymap
)
180 "Insert extra-elements of ITEM in a pretty form into the current buffer.
182 (let ((ignored-elements '(items link title description content
183 content
:encoded dc
:subject
184 dc
:date entry item guid pubDate
187 (left-column-width 1))
188 (mapc (lambda (extra-element)
189 (when (listp extra-element
) ;; take care of broken xml
191 (unless (memq (car extra-element
) ignored-elements
)
192 (setq left-column-width
(max left-column-width
194 (car extra-element
))))))))
195 (newsticker--extra item
))
196 (mapc (lambda (extra-element)
197 (when (listp extra-element
) ;; take care of broken xml
199 (unless (memq (car extra-element
) ignored-elements
)
200 (newsticker--do-print-extra-element extra-element
203 (newsticker--extra item
))))
205 (defun newsticker--do-print-extra-element (extra-element width keymap
)
206 "Actually print an EXTRA-ELEMENT using the given WIDTH.
208 (let ((name (symbol-name (car extra-element
))))
209 (insert (format "%s: " name
))
210 (insert (make-string (- width
(length name
)) ?
)))
211 (let (;;(attributes (cadr extra-element)) ;FIXME!!!!
212 (contents (cddr extra-element
)))
213 (cond ((listp contents
)
216 (string-match "^http://.*" i
))
218 (insert i
" ") ; avoid self-reference from the
222 (list 'mouse-face
'highlight
225 (format "mouse-2: visit (%s)" i
)
227 (insert (format "%s" i
))))
230 (insert (format "%s" contents
))))
233 (defun newsticker--image-read (feed-name-symbol disabled
)
234 "Read the cached image for FEED-NAME-SYMBOL from disk.
235 If DISABLED is non-nil the image will be converted to a disabled look
236 \(unless `newsticker-enable-logo-manipulations' is not t\).
238 (let ((image-name (concat newsticker-imagecache-dirname
"/"
239 (symbol-name feed-name-symbol
)))
241 (when (file-exists-p image-name
)
242 (condition-case error-data
243 (setq img
(create-image
245 :conversion
(and newsticker-enable-logo-manipulations
248 :mask
(and newsticker-enable-logo-manipulations
252 (message "Error: cannot create image for %s: %s"
253 feed-name-symbol error-data
))))
256 ;; the functions we need for retrieval and display
258 (defun newsticker-show-news ()
259 "Start reading news. You may want to bind this to a key."
261 (newsticker-start t
) ;; will start only if not running
262 (funcall newsticker-frontend
))
264 ;; ======================================================================
266 ;; ======================================================================
267 (defconst newsticker--next-item-image
268 (and (fboundp 'image-type-available-p
)
269 (image-type-available-p 'xpm
)
270 (create-image "/* XPM */
271 static char * next_xpm[] = {
341 "Image for the next item button.")
343 (defconst newsticker--previous-item-image
344 (and (fboundp 'image-type-available-p
)
345 (image-type-available-p 'xpm
)
346 (create-image "/* XPM */
347 static char * previous_xpm[] = {
414 "Image for the previous item button.")
416 (defconst newsticker--previous-feed-image
417 (and (fboundp 'image-type-available-p
)
418 (image-type-available-p 'xpm
)
419 (create-image "/* XPM */
420 static char * prev_feed_xpm[] = {
485 \" .&. .~[}>{*=-. \",
500 "Image for the previous feed button.")
502 (defconst newsticker--next-feed-image
503 (and (fboundp 'image-type-available-p
)
504 (image-type-available-p 'xpm
)
505 (create-image "/* XPM */
506 static char * next_feed_xpm[] = {
576 \" .&*=12'3~. .-. \",
591 "Image for the next feed button.")
593 (defconst newsticker--mark-read-image
594 (and (fboundp 'image-type-available-p
)
595 (image-type-available-p 'xpm
)
596 (create-image "/* XPM */
597 static char * mark_read_xpm[] = {
669 "Image for the mark read button.")
671 (defconst newsticker--mark-immortal-image
672 (and (fboundp 'image-type-available-p
)
673 (image-type-available-p 'xpm
)
674 (create-image "/* XPM */
675 static char * mark_immortal_xpm[] = {
774 \" $ @ % & * * = - + + \",
775 \" @ ; > , ' ) ' ! * - ~ @ \",
776 \" @ { > ! ] ^ / / ( ' * ; _ : \",
777 \" < _ ; [ ) / } | } / ] , 1 2 3 4 \",
778 \" 5 6 7 , ] 8 9 9 9 } ^ ! = ~ 0 a \",
779 \" b c 6 - , ] 8 9 9 9 } ^ ! % ~ 0 d 5 \",
780 \" : e _ ; * ) / 8 } } / ] , 1 2 3 f 5 \",
781 \" : g h { = i j ^ / ^ ] ! * ; k e l m \",
782 \" : f n o ; > , ' ) ' ! * - 2 0 p q r \",
783 \" : s g 0 6 ; % > * * = - ~ h t l u r \",
784 \" v u w x y k ~ z A z B o C D E F G b \",
785 \" 5 H I J e 0 h K h C c x L M N . \",
786 \" 4 O P q Q d g x g J L R H S T < \",
787 \" @ T U P F q V q M H N W X + \",
788 \" @ Y T O W G G W O X Y @ \",
789 \" 4 Z ` Y Y Y .` 4 4 \",
796 "Image for the mark immortal button.")
798 (defconst newsticker--narrow-image
799 (and (fboundp 'image-type-available-p
)
800 (image-type-available-p 'xpm
)
801 (create-image "/* XPM */
802 static char * narrow_xpm[] = {
855 \" .................. \",
856 \" .+@#$%&*=*-;>,')!. \",
857 \" .................. \",
860 \" .................. \",
861 \" .~{]^/(___:<[}|12. \",
862 \" .................. \",
865 \" .................. \",
866 \" .!3@45>666789'0ab. \",
867 \" .................. \",
870 \" .................. \",
871 \" .cccdefghhgficccc. \",
872 \" .................. \",
878 "Image for the narrow image button.")
880 (defconst newsticker--get-all-image
881 (and (fboundp 'image-type-available-p
)
882 (image-type-available-p 'xpm
)
883 (create-image "/* XPM */
884 static char * get_all_xpm[] = {
960 \" ................... \",
961 \" .+@#$%&*=*&-;>,')!. \",
962 \" ................... \",
964 \" ................... \",
965 \" .~{]^/(___:<[}|123. \",
966 \" ................... \",
968 \" ................... \",
969 \" .45678909abcdefg. \",
970 \" .h5icj7jklmeno. \",
982 "Image for the get all image button.")
984 (defconst newsticker--update-image
985 (and (fboundp 'image-type-available-p
)
986 (image-type-available-p 'xpm
)
987 (create-image "/* XPM */
988 static char * update_xpm[] = {
1053 "Image for the update button.")
1055 (defconst newsticker--browse-image
1056 (and (fboundp 'image-type-available-p
)
1057 (image-type-available-p 'xpm
)
1058 (create-image "/* XPM */
1059 static char * visit_xpm[] = {
1108 \" .++.%%%#&.++. \",
1109 \" .++.$%%%#*=.++. \",
1110 \" .++.-@;##$*>,.++. \",
1111 \" .++.')!&@@*=~{].++. \",
1112 \" .++.^{~>---)/(_:<.++. \",
1113 \" .++.^[,~/~'(_}|.++. \",
1114 \" .++.]_1[12^:|.++. \",
1115 \" .++.:}33:45.++. \",
1116 \" .++.<5567.++. \",
1126 "Image for the browse button.")
1128 (provide 'newsticker-reader
)
1130 ;; arch-tag: c604b701-bdf1-4fc1-8d05-5fabd1939533
1131 ;;; newsticker-reader.el ends here