From: Frédéric Perrin Date: Mon, 1 Apr 2024 20:05:58 +0000 (+0100) Subject: Use plist for optional arguments X-Git-Url: https://gitweb.fperrin.net/?p=atom.el.git;a=commitdiff_plain;h=839c46bcd6ebdfd548fde8a7a88dd84f420bf3af Use plist for optional arguments --- diff --git a/atom-tests.el b/atom-tests.el index 3c5330c..a725a55 100644 --- a/atom-tests.el +++ b/atom-tests.el @@ -31,15 +31,16 @@ (ert-deftest text-feed () (let* ((user-full-name "John Smith") (user-mail-address "john.smith@example.org") - (my-atom-feed (atom-create "My feed" "http://example.org")) - (now (current-time))) + (now (current-time)) + (my-atom-feed (atom-create "My feed" "http://example.org" + (list :updated now)))) ;; A simple, text-only entry (atom-add-text-entry my-atom-feed "Hello world" "http://example.org/hello" "Hello the world!" - now) + (list :updated now)) ;; ;; @@ -71,6 +72,11 @@ (goto-char (point-min)) (should (re-search-forward exp-string)))) (goto-char (point-min)) + ;; there will be two updated elements, for the feed and the entry + (re-search-forward "updated>\\(.*\\)") + (let* ((updated-string (match-string 1)) + (updated-time (atom-parse-time updated-string))) + (should (equal updated-time (seq-take now 2)))) (re-search-forward "updated>\\(.*\\)") (let* ((updated-string (match-string 1)) (updated-time (atom-parse-time updated-string))) @@ -101,19 +107,35 @@ (ert-deftest atom-opt-elements () (let ((my-atom-feed (atom-create "My Feed" "http://example.org" - "Feed subtitle" ; subtitle - "http://example.org/feed.atom" ; self link - "urn:example-id" ; id - (cons "Author name" "Author addr") - "2024-04-23T01:02:03+04:00" ; updated - ))) + (list :subtitle "Feed subtitle" + :self "http://example.org/feed.atom" + :id "urn:example-id:1" + :author (list "Author name" "Author@example.org") + :updated (atom-parse-time "2024-03-23T01:02:03+04:00"))))) (atom-add-text-entry my-atom-feed "A text entry" "http://example.org/text" "Some text" - "2024-04-23T01:02:03+04:00" ; updated - (atom-generate-id "http://example.org/text" (current-time))))) + (list :updated (atom-parse-time "2024-03-23T01:02:04+0400") + :summary "summary")) + (atom-add-html-entry + my-atom-feed + "A HTLM entry" + "http://example.org/html" + "

Some text

" + (list :updated (atom-parse-time "2024-03-23T01:02:05+04:00") + :summary "

summary...

")) + (atom-add-xhtml-entry + my-atom-feed + "A XHTML entry" + "http://example.org/xhtml" + "

Some text

" + (list :updated (atom-parse-time "2024-03-23T01:02:06+04:00") + :summary "

summary...

")) + + (atom-print my-atom-feed) + (atom-print-as-rss my-atom-feed))) (provide 'atom-tests) ;;; atom-tests.el ends here diff --git a/atom.el b/atom.el index d573347..39bfef7 100644 --- a/atom.el +++ b/atom.el @@ -50,13 +50,14 @@ ;; (atom-print-as-rss my-atom-feed)) ;; Full documentation is available at . +;; See ;;; Code: (require 'xml) (require 'url-parse) -(defun atom-create (title link &optional subtitle self id author updated) +(defun atom-create (title link &optional props) "Create a new atom structure. TITLE is the title for the feed, a short, text-only, human @@ -65,29 +66,33 @@ readable string. LINK is the URL of a page responible for the content of this feed. -SUBTITLE is a subtitle for the feed; it can be a bit longer than -TITLE, maybe a paragraph long. +PROPS is an optional plist with the following properties: -SELF is the canonical URL to this feed. +- :subtitle is a subtitle for the feed; it can be a bit longer than + TITLE, maybe a paragraph long. -ID is a unique identifier for this feed. If not given, it -defaults to SELF. +- :self is the canonical URL to this feed. -AUTHOR is the author of the feed. See `atom-massage-author' for +- :id is a unique identifier for this feed. If not given, it + defaults to :self. + +- :author is the author of the feed. See `atom-massage-author' for the possible ways to specify it. In particular, `nil' uses `user-full-name' and `user-mail-address'. -UPDATED is the date the feed was last updated. If not given, +- :updated is the date the feed was last updated. If not given, `(current-time)' is used." (let ((atom-feed (list (list 'title nil title)))) (atom-modify-entry atom-feed 'link `(((href . ,link)))) - (atom-modify-entry atom-feed 'author (atom-massage-author author)) - (if subtitle (atom-modify-entry atom-feed 'subtitle subtitle)) - (if self (atom-modify-entry atom-feed 'link - `(((href . ,self) (rel . "self") - (type . "application/atom+xml"))))) - (atom-modify-entry atom-feed 'updated (atom-format-time updated)) - (atom-modify-entry atom-feed 'id (or id self link)) + (atom-modify-entry atom-feed 'author (atom-massage-author (plist-get props :author))) + (if (plist-member props :subtitle) + (atom-modify-entry atom-feed 'subtitle (plist-get props :subtitle))) + (if (plist-member props :self) + (atom-modify-entry atom-feed 'link + `(((href . ,(plist-get props :self)) (rel . "self") + (type . "application/atom+xml"))))) + (atom-modify-entry atom-feed 'updated (atom-format-time (plist-get props :updated))) + (atom-modify-entry atom-feed 'id (or (plist-get props :id) (plist-get props :self) link)) atom-feed)) (defun atom-push-entry (atom entry) @@ -101,8 +106,7 @@ UPDATED is the date the feed was last updated. If not given, (cons name val)))) (nconc entry (list elem)))) -(defun atom-add-entry (atom title link content - &optional updated id summary) +(defun atom-add-entry (atom title link content &optional props) "Add an entry to the atom flux ATOM. Return the newly added entry. @@ -125,9 +129,10 @@ not change between successive generations of the atom feed, even when the content of the entry changes." (let ((entry (list (list 'title nil title)))) (atom-modify-entry entry 'link (list (list (cons 'href link)))) - (atom-modify-entry entry 'id (or id link)) - (atom-modify-entry entry 'updated (atom-format-time updated)) - (if summary (atom-modify-entry entry 'summary summary)) + (atom-modify-entry entry 'id (or (plist-get props :id) link)) + (atom-modify-entry entry 'updated (atom-format-time (plist-get props :updated))) + (if (plist-member props :summary) + (atom-modify-entry entry 'summary (plist-get props :summary))) (atom-modify-entry entry 'content content) (atom-push-entry atom entry) entry)) @@ -136,29 +141,21 @@ when the content of the entry changes." "Add an entry to ATOM, with a textual content. See `atom-add-entry' for details.") -(defun atom-add-html-entry (atom title link content - &optional updated id summary) +(defun atom-add-html-entry (atom title link content &optional props) "Add an entry to ATOM, with some HTML content. CONTENT should be a string enconding a valid HTML fragment. See `atom-add-entry' for additional details." - (atom-add-entry atom - title link (atom-massage-html content) - updated id (and summary (atom-massage-html summary)))) + (if (plist-member props :summary) + (plist-put props :summary (atom-massage-html (plist-get props :summary)))) + (atom-add-entry atom title link (atom-massage-html content) props)) -(defun atom-add-xhtml-entry (atom title link content - &optional updated id summary noconvert) +(defun atom-add-xhtml-entry (atom title link content &optional props) "Add an entry to ATOM, with some XHTML content. CONTENT may be given either as a string, or as an XML tree, of a valid XHTML -fragment. See `atom-add-entry' for additional details. - -If NOCONVERT is nil, translate all links in CONTENT so that they -are no longer relative to LINK." - (let ((xhtml-content (atom-massage-xhtml content))) - (unless noconvert - (atom-xhtml-convert-links (cadr xhtml-content) link)) - (atom-add-entry atom - title link xhtml-content - updated id (and summary (atom-massage-xhtml summary))))) +fragment. See `atom-add-entry' for additional details." + (if (plist-member props :summary) + (plist-put props :summary (atom-massage-xhtml (plist-get props :summary)))) + (atom-add-entry atom title link (atom-massage-xhtml content) props)) (defun atom-print (atom) "Print the Atom feed ATOM in the current buffer." @@ -324,7 +321,9 @@ absolute, in the context of BASE, an URL." (defun atom-generate-id (link creation-date) "Generate a string suitable for use as an atom:id element. This implements Mark Pilgrom's tag: URI method, using the -CREATION-DATE of the entry, and the domain part of LINK." +CREATION-DATE of the entry, and the domain part of LINK. + +See ." (format "tag:%s,%s:/%s" (url-host (url-generic-parse-url link)) (format-time-string "%Y-%m-%d" creation-date)