+(defun atom-to-rss (atom &optional rss-self)
+ "Translate Atom feed ATOM into an RSS one, returning the translation.
+
+If RSS-SELF is given, it is used as self link of the RSS feed.
+
+Some information may be lost or approximated."
+ (let ((rss (list (assoc 'title atom))))
+ (if rss-self
+ (atom-modify-entry rss 'atom:link
+ `(((href . ,rss-self) (rel . "self")
+ (type . "application/atom+xml")))))
+ (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 the Atom entry 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)))
+ (setcar (cdr descr) nil))
+ `(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 &optional rss-self)
+ "Convert Atom feed ATOM to RSS in the current buffer.
+
+If RSS-SELF is given, it is used as self link of the RSS feed."
+ (let ((rss (atom-to-rss atom rss-self)))
+ (insert atom-xml-declaration)
+ ;; xmlns:atom included in order to allow the atom:link rel=self element
+ (insert "<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n")
+ (insert " <channel>\n")
+ (xml-print rss " ")
+ (insert "\n </channel>\n")
+ (insert "</rss>")))
+
+(defun atom-to-rss-time (time)
+ "Translate TIME from the format used by Atom into the format used by RSS.
+
+TIME is a string."
+ (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 &optional rss-self)
+ "Save ATOM as a RSS feed into FILENAME.
+
+If RSS-SELF is given, it is used as self link of the RSS feed."
+ (with-temp-buffer
+ (atom-print-as-rss atom rss-self)
+ (write-file 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")
+