Google Reader alternative for Emacs Ninjas

With Google Reader being discontinued and everyone looking for alternatives I’ve decided to look for a little less “standard” solution, and hey, it turns out Emacs can be a pretty powerful RSS reader.

Newsticker.el

News Ticker is a built-in Emacs feed reader that doesn’t get much attention for some reason. It is feature-rich, handles both RSS 2.0 and Atom feeds and has quite a bunch of tweakable options.
Here’s a simple setup to start with:

(require 'newsticker)

; W3M HTML renderer isn't essential, but it's pretty useful.
(require 'w3m)
(setq newsticker-html-renderer 'w3m-region)

; We want our feeds pulled every 10 minutes.
(setq newsticker-retrieval-interval 600)

; Setup the feeds. We'll have a look at these in just a second.
(setq newsticker-url-list-defaults nil)
(setq newsticker-url-list '("..."))

; Optionally bind a shortcut for your new RSS reader.
(global-set-key (kbd "C-c r") 'newsticker-treeview)

; Don't forget to start it!
(newsticker-start)

Migration

First of all, you have to export your Google Reader data; you can do this here by following these instructions. Download and unzip it into a safe location.
Now, all you will need to migrate from Google Reader to News Ticker is this little piece of code:

(require 'xml)

(defun assoc-or-error (what where &optional err-string)
  (or (assoc what where)
      (error (or err-string
                 "Suddenly errors! Thousands of them!"))))

(defun google-reader-to-newsticker (filename)
  "Parses your google-reader feed subscription XML
 and returns newsticker compatible feed alist."
  (with-temp-buffer
    (insert-file-contents filename)
    (let* ((opml (assoc-or-error
                  'opml
                  (xml-parse-region (point-min)
                                    (point-max))
                  "Not a valid feed XML!"))
           (body (assoc-or-error
                  'body
                  opml
                  "Not a valid feed XML!"))
           (outlines (delq nil
                           (map 'list
                                (lambda (element)
                                  (and (consp element)
                                       (equal (car element)
                                              'outline)
                                       element))
                                body)))
           (alist
            (map 'list
                 (lambda (outline)
                   (let ((title (assoc-or-error
                                 'title
                                 outline
                                 (concat "No title in an outline "
                                         "- malformed feed XML?"))
                         (feed (assoc-or-error
                                'xmlUrl
                                outline
                                (concat "No feed link in an outline "
                                        '"- check your feed XML!")))
                     (list (cdr title) (cdr feed))))
                 (map 'list
                      #'cadr
                      outlines))))
      alist)))

Simply eval it in your Emacs and run the following lines to import all your Google Reader feeds directly to News Ticker.

(setq newsticker-url-list
  (google-reader-to-newsticker "/path/to/subscriptions.xml"))

You might want to save your feeds for later via Newsticker Url List setting under:

M-x customize-group newsticker-retrieval

As with anything Emacs, you can bend News Ticker to your will and make it do whatever you please. Depending on your Emacs theme it might look something like this:

http://idorobots.files.wordpress.com/2013/03/wpid-feeds.png?w=549

Go ahead, customize all the things!

Extra ninja

If you, like me, read loads of feeds every day you might consider adding a tiny notification thing-a-ma-jigger to your Emacs mode-line, just place the following code in your custom mode-line-format

(setq-default mode-line-format
  (list
    ; ...

    '(:eval (let ((unread (or (newsticker--stat-num-items-total 'new)
                              0)))
              (when (> unread 0)
                (propertize
                  ; Any text will do, be creative!
                  (format "RSS: %d" unread)
                  'face 'some-colorful-font-face
                  'help-echo (format "You have %d unread RSS items!"
                                     unread)
                  'mouse-face 'mode-line-highlight))))))

…and enjoy it popping into existence every now and then (note the use of awesome Font Awesome):

http://idorobots.files.wordpress.com/2013/03/wpid-1unread.png?w=549
Happy procrastinating!

About these ads

18 responses to “Google Reader alternative for Emacs Ninjas

    • I did not. I’m still using 23.3, but I suppose if w3m isn’t included in ELPA you can install it the good old fashioned way – compile it and put all relevant .el files somewhere where Emacs can find them.

    • Not extensively tested, but you with emacs 24, you can try to use the builtin shr (simple html renderer) library. It is not documented anywhere, but something like

      (setq newsticker-html-renderer ‘shr-render-region)

      seems to somehow do the trick, at least for xkcd feeds.

  1. What made Google Reader so important was the synchronization service, not the reader itself. Any reader without the ability to maintain your feed between multiple devices is simply not a replacement for Google Reader.

  2. Excellent information; thank you for sharing this!

    The only issue I encountered is that I can’t find a definition for assoc-or-error anywhere. A google search for “emacs assoc-or-error” didn’t turn anything up. I can figure out what it should be doing from context, but I wanted to bring it to your attention.

    Overall, great solution!

  3. One other tidbit that might be useful:

    The default font configs that newsticker came with in my configuration were the never-very-helpful black-on-black color scheme, rendering most treeview text invisible.

    Throwing these font settings down is a good sanity-check if you try this and your newsticker UI looks to be missing pieces:

    ;; Default font settings just kind of seemed to assume you are not on black background.
    ;; Let’s fix.
    (setq newsticker-extra-face ‘((((class color) (background light)) (:foreground “green” :slant italic :height 0.8))))
    (setq newsticker-feed-face ‘((((class color) (background light)) (:foreground “green” :weight bold :height 1.2 :family “helvetica”))))
    (setq newsticker-treeview-face ‘((t (:foreground “green” :weight normal :family “helvetica”))))
    (setq newsticker-treeview-new-face ‘((((class color) (background light)) (:inherit newsticker-treeview-face :background “darkgreen” :foreground “lightgreen” :weight bold))))

  4. thanks a lot!
    How to show images in newsticker item?

    The status of images in newsticker now are not load but with words like the following:

    Enclosed file (image/jpg, 120.00 KBytes)

  5. It’s also possible to extend Newsticker to use external tool like wget to speed-up headers’ fetch and/or additionally hard-code your feed list like so:

    ;;; newsticker
    (require ‘newsticker)

    (require ‘w3m)
    (setq newsticker-html-renderer ‘w3m-region)

    (setq newsticker-automatically-mark-items-as-old t)
    (setq newsticker-automatically-mark-visited-items-as-old t)

    (setq newsticker-retrieval-interval 3600)
    (setq newsticker-retrieval-method ‘extern)
    (setq newsticker-wget-arguments ‘(“-q” “-O” “-” “–user-agent” “testing”))

    (setq newsticker-treeview-treewindow-width 40)
    (setq newsticker-treeview-listwindow-height 20)

    (setq newsticker-url-list-defaults nil)
    (setq newsticker-url-list
    ‘((“EmacsWiki Recently Change”
    “http://www.emacswiki.org/emacs/index.rss”
    nil nil nil)
    (“Planet Emacsen”
    “http://planet.emacsen.org/atom.xml”
    nil nil nil)
    (“Google Blog Search — Emacs”
    “http://blogsearch.google.com/blogsearch_feeds?hl=en&oe=UTF-8&q=emacs&ie=utf-8&num=100&output=atom”
    nil 86400 nil) ; fetch this feed once a day
    (“Google Blog Search — Haskell”
    “http://blogsearch.google.com/blogsearch_feeds?hl=en&oe=UTF-8&q=haskell&ie=utf-8&num=100&output=atom”
    nil 86400 nil) ; fetch this feed once a day
    ))
    ;; optional key-binding to Newsticker treeview
    (global-set-key (kbd “C-c g”) ‘newsticker-treeview)

    ;; auto-start at the end
    ;(newsticker-start)

  6. Thanks for this article!

    Emacs gnus supports RSS inherently. By pressing G R you can add a feed-url.
    I Like to have one system for mail, news and feeds.

    Does the reader you propose have any significant advantages?

    • > Does the reader you propose have any significant advantages?

      None that I am aware of. It’s fairly lightweight and works well in my setup, tho :)

    • Hi. Assuming your gReader data is in OPML format it’s probaby wiser to use the builtin Newsticker importer – `newsticker-opml-import` (which I didn’t know existed at the moment of writing this post).

      And about the missing parenthesis thing… I’m looking at the code right now and everything appears to be ok. Could you elaborate?

      • Thank you for the reply, I’ll be using the built-in importer.

        About the parenthesis, well, my (Emacs) lisp interpreter tells me that there should be five (instead of three) closing parenthesis at the end of the google-reader-to-newsticker function to make it well-balanced. All I have done really is copy the piece of code into Emacs and call forward-list (C-M-n) on the first opening parenthesis of the function.

  7. Thank you for your great hack. In emacs 24 I have problem in retrieving images. At theire place emacs just shows theire names and nothing more. Do you have any idea about where do I have to look?

    • I would recommend checking your HTML renderers (W3M most likely) settings. Unfortunately, I’m still on Emacs 23.3, so I’m not sure what could’ve changed in the newer release. By the looks of it adding the following code to your W3M config should do the trick.

      (setq w3m-default-display-inline-images t)
      

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s