+(defun atom-to-rss (atom)
+ "Translate an Atom feed into an RSS one, returning the translation.
+
+Some information may be lost or approximated."
+ (let ((rss (list (assoc 'title atom))))
+ (atom-to-rss-translator atom rss '((subtitle . description)
+ (updated . pubDate)
+ (link . link)))
+ (atom-to-rss-modify-time rss)
+ (atom-to-rss-modify-link rss)
+ (dolist (entry (xml-get-children atom 'entry))
+ (push (atom-to-rss-item entry) rss))
+ (reverse rss)))
+
+(defun atom-to-rss-item (entry)
+ "Translates an Atom entry into an RSS item."
+ (let ((item (list (assoc 'title entry))))
+ (atom-to-rss-translator
+ (xml-node-children entry) item
+ '((id . guid) (content . description) (updated . pubDate) (link . link)))
+ (atom-to-rss-modify-time item)
+ (atom-to-rss-modify-link item)
+ (let ((guid (assoc 'guid item))
+ (descr (assoc 'description item)))
+ (if guid
+ (setcar (cdr guid) (list (cons 'isPermaLink "false"))))
+ (if (and descr
+ (equal (xml-get-attribute descr 'type) "xhtml"))
+ (setcar (cddr descr) (xml-node-as-text descr))))
+ `(item nil ,@item)))
+
+(defun atom-to-rss-translator (source target translations)
+ (dolist (translation translations)
+ (let* ((from (car translation))
+ (to (cdr translation))
+ (data (copy-tree (cdr (assoc from source)))))
+ (when data
+ (atom-modify-entry target to data)))))
+
+(defun atom-to-rss-modify-link (entry)
+ (let* ((link (assoc 'link entry))
+ (link-addr (xml-get-attribute-or-nil link 'href)))
+ (when link
+ (setcar (cdr link) nil)
+ (setcdr (cdr link) (cons link-addr nil)))))
+
+(defun atom-print-as-rss (atom)
+ (let ((rss (atom-to-rss atom)))
+ (insert atom-xml-declaration)
+ (insert "<rss version=\"2.0\">\n")
+ (insert " <channel>\n")
+ (xml-print rss " ")
+ (insert "\n </channel>\n")
+ (insert "</rss>")))
+
+(defun atom-to-rss-time (time)
+ "Translates a string from the format used by Atom into the
+format used by RSS."
+ (let ((system-time-locale "C"))
+ (format-time-string "%a, %d %b %Y %T %z" (atom-parse-time time))))
+
+(defun atom-to-rss-modify-time (entry)
+ "Modify ENTRY, changing the format of the `pubDate' in it."
+ (let ((pubDate (assoc 'pubDate entry)))
+ (setcar (cddr pubDate)
+ (atom-to-rss-time (car (xml-node-children pubDate))))))
+
+(defun atom-to-rss-write-file (atom filename)
+ "Saves ATOM as a RSS feed into FILENAME."
+ (with-temp-buffer
+ (atom-print-as-rss atom)
+ (write-region nil nil filename)))
+
+\f
+(defvar atom-time-format-string "%Y-%m-%dT%T%z"
+ "The format for string representation of dates.")
+
+(defvar atom-xhtml-namespace "http://www.w3.org/1999/xhtml")
+
+(defvar atom-xml-declaration "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
+