diff --git a/ChangeLog b/ChangeLog index d3da955..e0e6659 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,11 @@ -2021-09-16 Michael Herstine +2021-10-08 Michael Herstine + + Address Issue-18. + This commit adds a new field to each rule type: :comment. Since + Lisp source comments are discarded on read, this provides a way + for rule authors to attach a note, or docstring, to each rule. + +2021-09-24 Michael Herstine elfeed-score 1.0. The last obsolete symbols have been removed, with the exception of @@ -7,6 +14,8 @@ 2021-09-15 Michael Herstine + Fixing release workflow + Remove all symbols made obsolete as of release 0.2.0. Revising test suite. diff --git a/NEWS b/NEWS index b62752d..f05503a 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,14 @@ elfeed-score News -- history of user-visible changes -*- outline -*- +* elfeed-score 1.1 + +** Changes in elfeed-score 1.1.0 + +*** New Features + +**** address issue 18 + +Add a :comment field to all rule types. * elfeed-score 1.0 ** Changes to elfeed-score 1.0.0 @@ -281,7 +290,7 @@ Fixed. modeled on that of `elfeed' itself. -* Changes in elfeed-score 0.3.0 +* elfeed-score 0.3 ** New Features @@ -301,7 +310,7 @@ A new type of scoring rule is introduced: `title-or-content'. Such a rule perfor `elfeed-score' now provides an `elfeed-search-print-entry-function' compliant function that will display each entry's score in the first column of the search view. The score format can be controlled by the customization variable `elfeed-score-score-format'. See the README for instructions. -* Changes in elfeed-score 0.2.0 +* elfeed-score 0.2 ** New Features @@ -313,10 +322,6 @@ Loading the package no longer affects Elfeed; the package must be enabled via a The naming scheme for public symbols changed from "elfeed-score/" to "elfeed-score-" (in accordance with the Emacs Lisp Coding Conventions. Aliases are defined for all 0.1 symbols. -* elfeed-score 0.1.0 +* elfeed-score 0.1 Initial release of the `elfeed-score' package. - -Local Variables: -eval: (visual-line-mode) -End: diff --git a/README.org b/README.org index 2c04a8d..e2e265b 100644 --- a/README.org +++ b/README.org @@ -2,7 +2,7 @@ #+DESCRIPTION: Gnus-style scoring for Elfeed #+AUTHOR: Michael Herstine #+EMAIL: sp1ff@pobox.com -#+DATE: <2021-09-16 Thu 08:53> +#+DATE: <2021-10-08 Fri 15:56> #+AUTODATE: t #+OPTIONS: toc:nil org-md-headline-style:setext *:t ^:nil #+STARTUP: overview @@ -23,27 +23,28 @@ While you can manually assign a score to an entry, you will likely find it more For instance, here's a subset of my scoring file at the moment: #+BEGIN_SRC elisp - ;;; Elfeed score file -*- lisp -*- - (("title" - (:text "OPEN THREAD" :value -1000 :type S) - (:text "raymond c\\(hen\\)?" :value 250 :type r) :tags (t .(@dev))) - ("content" - (:text "type erasure" :value 500 :type s)) - ("title-or-content" - (:text "california" 150 100 :type s) - (:text "china" 150 100 :type w)) - ("feed" - (:text "Essays in Idleness" :value 250 :type S :attr t) - (:text "Irreal" :value 250 :type S :attr t) - (:text "Julia Evans" :value 100 :type :type s :attr t) - (:text "National Weather Service" :value 400 :type S :attr t) - (:text "emacs-news – sacha chua" :value 350 :type S :attr t)) - ("authors" - (:text "Jim Geraghty" :value 500 :type s)) - ("tag" - (:tags (t . reddit-question) - :value 750)) - (mark -2500)) + ;;; Elfeed score file -*- lisp -*- + (("title" + (:text "OPEN THREAD" :value -1000 :type S) + (:text "raymond c\\(hen\\)?" :value 250 :type r) :tags (t .(@dev))) + ("content" + (:text "type erasure" :value 500 :type s)) + ("title-or-content" + (:text "california" 150 100 :type s) + (:text "china" 150 100 :type w)) + ("feed" + (:text "Essays in Idleness" :value 250 :type S :attr t) + (:text "Irreal" :value 250 :type S :attr t) + (:text "Julia Evans" :value 100 :type :type s :attr t) + (:text "National Weather Service" :value 400 :type S :attr t) + (:text "emacs-news – sacha chua" :value 350 :type S :attr t :comment "Essential!")) + ("authors" + (:text "Jim Geraghty" :value 500 :type s)) + ("tag" + (:tags (t . reddit-question) + :value 750 + :comment "Add 750 points to any entry with a tag of reddit-question")) + (mark -2500)) #+END_SRC Like Gnus scoring, this may look like Lisp code, but it is not directly eval'd. It will be read by the Lisp reader, so it must at least be a valid Lisp s-expression. @@ -72,7 +73,7 @@ The easiest way to install elfeed-score is [[https://github.com/melpa/melpa][MEL If you would prefer to install the package manually, you can also download the Emacs package file on the GitHub releases [[https://github.com/sp1ff/elfeed-score/releases][page]] or from my personal [[https://www.unwoundstack/distros.html][page]]. Then say: #+BEGIN_SRC elisp -(package-install-file "elfeed-score-1.0.0.tar") +(package-install-file "elfeed-score-1.1.0.tar") #+END_SRC ** Autotools Source Distributions @@ -81,8 +82,8 @@ You can also download Autotools source tarballs (again available either on the G #+BEGIN_SRC bash cd /tmp -curl -L --output elfeed-score-1.0.0.tar.gz https://github.com/sp1ff/elfeed-score/releases/download/1.0.0/elfeed-score-1.0.0.tar.gz -tar xvf elfeed-score-1.0.0.tar.gz && cd elfeed-score-1.0.0 +curl -L --output elfeed-score-1.1.0.tar.gz https://github.com/sp1ff/elfeed-score/releases/download/1.1.0/elfeed-score-1.1.0.tar.gz +tar xvf elfeed-score-1.1.0.tar.gz && cd elfeed-score-1.1.0 export EMACSLOADPATH=$HOME/.emacs.d/elpa/elfeed-20200209.1942:$EMACSLOADPATH ./configure make @@ -97,16 +98,16 @@ The unit tests require some macros defined by the [[https://github.com/skeeto/el #+BEGIN_SRC bash cd /tmp git clone https://github.com/skeeto/elfeed.git -curl -L --output=elfeed-score-1.0.0.tar.gz https://github.com/sp1ff/elfeed-score/releases/download/1.0.0/elfeed-score-1.0.0.tar.gz -tar xvf elfeed-score-1.0.0.tar.gz && cd elfeed-score-1.0.0 -export EMACSLOADPATH=/tmp/elfeed-score-1.0.0:/tmp/elfeed:/tmp/elfeed/tests:$EMACSLOADPATH +curl -L --output=elfeed-score-1.1.0.tar.gz https://github.com/sp1ff/elfeed-score/releases/download/1.1.0/elfeed-score-1.1.0.tar.gz +tar xvf elfeed-score-1.1.0.tar.gz && cd elfeed-score-1.1.0 +export EMACSLOADPATH=/tmp/elfeed-score-1.1.0:/tmp/elfeed:/tmp/elfeed/tests:$EMACSLOADPATH ./configure make make check sudo make install #+END_SRC -Again, unless you already use =EMACSLOADPATH=, you'll need to set =EMACSLOADPATH= appropriately to your system, something like =EMACSLOADPATH=/tmp/elfeed-score-1.0.0:/tmp/elfeed:/tmp/elfeed/tests:/usr/share/emacs/25.2/lisp=. +Again, unless you already use =EMACSLOADPATH=, you'll need to set =EMACSLOADPATH= appropriately to your system, something like =EMACSLOADPATH=/tmp/elfeed-score-1.1.0:/tmp/elfeed:/tmp/elfeed/tests:/usr/share/emacs/25.2/lisp=. ** Building From Source Finally, you can of course just clone this repo & build there. I've started a [[https://github.com/sp1ff/elfeed-score/wiki][wiki]], whose intended audience are people looking to hack on elfeed-score, that includes build instructions. diff --git a/configure.ac b/configure.ac index 334e232..529f223 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ([2.69]) -AC_INIT([elfeed-score], [1.0.0], [sp1ff@pobox.com], [elfeed-score], [https://github.com/sp1ff/elfeed-score]) +AC_INIT([elfeed-score], [1.1.0], [sp1ff@pobox.com], [elfeed-score], [https://github.com/sp1ff/elfeed-score]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_SRCDIR([./elfeed-score.el]) AC_PROG_MAKE_SET diff --git a/doc/elfeed-score.texi b/doc/elfeed-score.texi index c5771ab..c7e916c 100644 --- a/doc/elfeed-score.texi +++ b/doc/elfeed-score.texi @@ -371,7 +371,8 @@ The score file is plain-text file containing a single Lisp form. Under the hood, elfeed-score opens your file, inserts its contents into a temporary buffer, and calls @code{read-from-string} (@pxref{Input Functions, read-from-string, read-from-string, elisp, Emacs Lisp}) on -the contents. +the contents. Note that this means any comments will be discarded; use +the @code{:comment} field to attach notes to your rules, instead. The form is a list of lists; each sub-list begins with a symbol or a string identifying that sub-list's nature & purpose. The sub-list @@ -582,6 +583,13 @@ Rules by Feed} for how to do that. This property is optional. +@item +@code{:comment}: Rule comment + +An optional, free-form note on this rule. Since Lisp comments will be +lost on read, this provides a way for the score file author to +annotate rules. + @end enumerate So, for instance, the following rule: @@ -627,6 +635,9 @@ represented by seven properties: @item @code{:feeds} Feed scoping rules +@item +@code{:comment} Comment + @end enumerate As @ref{title Rules, above, above}, only the first three elements are @@ -669,6 +680,9 @@ The value by which an entry's score will be adjusted when the @item @code{:feeds} Feed scoping rules +@item +@code{:comment} Comment + @end enumerate Note that both entry attributes are checked, so both score values have @@ -720,6 +734,9 @@ You may wish to apply this rule only to entries that have certain tags (or that do @emph{not} have certain tags). See @ref{Scoping Rules by Tags, below, below} for how to do that. +@item +@code{:comment} Comment + @end enumerate For example, this rule: @@ -772,6 +789,9 @@ You may wish to apply this rule only to entries that came from certain feeds (or did @emph{not} come from certain feeds). See @ref{Scoping Rules by Feed, below, below} for how to do that. +@item +@code{:comment} Comment + @end enumerate @node tag Rules @@ -811,6 +831,9 @@ will apply to entries who posses @emph{none} of the tags in The amount by which an entry's score shall be adjusted should this rule match. +@item +@code{:comment} Comment + @end enumerate @node link Rules @@ -842,6 +865,9 @@ represented by seven properties: @item @code{:feeds} Feed scoping rules +@item +@code{:comment} Comment + @end enumerate As @ref{title Rules, above, above}, only the first three elements are @@ -898,6 +924,9 @@ If @code{switch} is @code{t} & the rule applies, @code{tags} (either a single tag or a list of tags) will be added to the entry; if @code{switch} is @code{nil}, they will be removed +@item +@code{:comment} Comment + @end enumerate For example, the following rules: diff --git a/doc/version.texi b/doc/version.texi index 16e40f2..6dd65f4 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 16 September 2021 -@set UPDATED-MONTH September 2021 -@set EDITION 1.0.0 -@set VERSION 1.0.0 +@set UPDATED 8 October 2021 +@set UPDATED-MONTH October 2021 +@set EDITION 1.1.0 +@set VERSION 1.1.0 diff --git a/elfeed-score-pkg.el b/elfeed-score-pkg.el index a6b3784..c40f2ce 100644 --- a/elfeed-score-pkg.el +++ b/elfeed-score-pkg.el @@ -1,5 +1,5 @@ (define-package "elfeed-score" - "1.0.0" + "1.1.0" "Gnus-style scoring for Elfeed" '((emacs "26.1") (elfeed "3.3.0"))) diff --git a/elfeed-score-rules.el b/elfeed-score-rules.el index 6b78a28..23865cb 100644 --- a/elfeed-score-rules.el +++ b/elfeed-score-rules.el @@ -38,7 +38,7 @@ ;; always make sense. (:constructor elfeed-score-title-rule--create - (&key text value type tags feeds + (&key text value type tags feeds comment &aux (_ (unless (and (stringp text) (> (length text) 0)) @@ -97,8 +97,14 @@ only to feeds entitled foo or from https://bar/com/feed\" Making the first element nil means \"do not apply this rule if the feed is - either foo or bar\"." - text value type tags feeds) + either foo or bar\". + + - comment :: An optional, free-form note on this rule. Since + Lisp comments will be lost on read, this + provides a way for the score file author to + annotate rules." + + text value type tags feeds comment) (cl-defstruct (elfeed-score-title-explanation (:constructor nil) @@ -133,7 +139,7 @@ ;; always make sense. (:constructor elfeed-score-feed-rule--create - (&key text value type attr tags + (&key text value type attr tags comment &aux (_ (unless (and (stringp text) (> (length text) 0)) @@ -176,8 +182,13 @@ scoping. E.g. (t . (a b)) means \"apply this rule if either of tags a & b are present\". Making the first element nil means \"do not apply this rule if - any of a and b are present\"." - text value type attr tags) + any of a and b are present\". + + - comment :: An optional, free-form note on this rule. Since + Lisp comments will be lost on read, this + provides a way for the score file author to + annotate rules." + text value type attr tags comment) (cl-defstruct (elfeed-score-feed-explanation (:constructor nil) @@ -213,7 +224,7 @@ ;; always make sense. (:constructor elfeed-score-content-rule--create - (&key text value type tags feeds + (&key text value type tags feeds comment &aux (_ (unless (and (stringp text) (> (length text) 0)) @@ -272,8 +283,13 @@ only to feeds entitled foo or from https://bar/com/feed\" Making the first element nil means \"do not apply this rule if the feed is - either foo or bar\"." - text value type tags feeds) + either foo or bar\". + + - comment :: An optional, free-form note on this rule. Since + Lisp comments will be lost on read, this + provides a way for the score file author to + annotate rules." + text value type tags feeds comment) (cl-defstruct (elfeed-score-content-explanation (:constructor nil) @@ -308,7 +324,7 @@ ;; always make sense. (:constructor elfeed-score-title-or-content-rule--create - (&key text title-value content-value type tags feeds + (&key text title-value content-value type tags feeds comment &aux (_ (unless (and (stringp text) (> (length text) 0)) @@ -382,8 +398,13 @@ defining a single rule for both. only to feeds entitled foo or from https://bar/com/feed\" Making the first element nil means \"do not apply this rule if the feed is - either foo or bar\"." - text title-value content-value type tags feeds) + either foo or bar\". + + - comment :: An optional, free-form note on this rule. Since + Lisp comments will be lost on read, this + provides a way for the score file author to + annotate rules." + text title-value content-value type tags feeds comment) (cl-defstruct (elfeed-score-title-or-content-explanation (:constructor nil) @@ -424,7 +445,7 @@ defining a single rule for both. ;; always make sense. (:constructor elfeed-score-authors-rule--create - (&key text value type tags feeds + (&key text value type tags feeds comment &aux (_ (unless (and (stringp text) (> (length text) 0)) @@ -485,8 +506,13 @@ defining a single rule for both. only to feeds entitled foo or from https://bar/com/feed\" Making the first element nil means \"do not apply this rule if the feed is - either foo or bar\"." - text value type tags feeds) + either foo or bar\". + + - comment :: An optional, free-form note on this rule. Since + Lisp comments will be lost on read, this + provides a way for the score file author to + annotate rules." + text value type tags feeds comment) (cl-defstruct (elfeed-score-authors-explanation (:constructor nil) @@ -521,7 +547,7 @@ defining a single rule for both. ;; always make sense. (:constructor elfeed-score-tag-rule--create - (&key tags value + (&key tags value comment &aux (_ (unless (and (listp tags)) @@ -541,8 +567,13 @@ defining a single rule for both. if any of a and b are present\". - value :: integral value (positive or negative) by which to - adjust the entry score if this rule matches" - tags value) + adjust the entry score if this rule matches + + - comment :: An optional, free-form note on this rule. Since + Lisp comments will be lost on read, this + provides a way for the score file author to + annotate rules." + tags value comment) (cl-defstruct (elfeed-score-tags-explanation (:constructor nil) @@ -576,7 +607,7 @@ defining a single rule for both. ;; always make sense. (:constructor elfeed-score-link-rule--create - (&key text value type tags feeds + (&key text value type tags feeds comment &aux (_ (unless (and (stringp text) (> (length text) 0)) @@ -635,8 +666,13 @@ defining a single rule for both. only to feeds entitled foo or from https://bar/com/feed\" Making the first element nil means \"do not apply this rule if the feed is - either foo or bar\"." - text value type tags feeds) + either foo or bar\". + + - comment :: An optional, free-form note on this rule. Since + Lisp comments will be lost on read, this + provides a way for the score file author to + annotate rules." + text value type tags feeds comment) (cl-defstruct (elfeed-score-link-explanation (:constructor nil) @@ -671,7 +707,7 @@ defining a single rule for both. ;; always make sense. (:constructor elfeed-score-adjust-tags-rule--create - (&key threshold tags + (&key threshold tags comment &aux (_ (unless (listp threshold) @@ -693,8 +729,13 @@ a cons cell")))))) is t, and this rule matches, the tags in B will be added to the entry. If A is nil & this rule matches, the list of tags in B shall be removed - from the entry." - threshold tags) + from the entry. + + - comment :: An optional, free-form note on this rule. Since + Lisp comments will be lost on read, this + provides a way for the score file author to + annotate rules." + threshold tags comment) (defun elfeed-score-rules-pp-rule-to-string (rule) "Pretty-print RULE; return as a string." diff --git a/elfeed-score-serde.el b/elfeed-score-serde.el index 2ff2d13..8a258c9 100644 --- a/elfeed-score-serde.el +++ b/elfeed-score-serde.el @@ -40,7 +40,7 @@ deserialization of scoring rules." :group 'elfeed-score :type 'file) -(defconst elfeed-score-serde-current-format 8 +(defconst elfeed-score-serde-current-format 9 "The most recent score file format version.") (defvar elfeed-score-serde-title-rules nil @@ -892,12 +892,12 @@ with the following keys: :link links))) (defun elfeed-score-serde--parse-scoring-sexp-8 (sexp) - "Interpret the S-expression SEXP as scoring rules version 8. + "Interpret the S-expression SEXP as scoring rules version 8 or 9. -Parse version 8 of the scoring S-expression. With version 8 of -the score file format, the rule stats are stored separately, so -this file won't load them. However, it will still return lists -of cons cells (with the cdr set to nil) to allow uniform +Parse versions 8 & 9 of the scoring S-expression. With version 8 +of the score file format, the rule stats are stored separately, +so this file won't load them. However, it will still return +lists of cons cells (with the cdr set to nil) to allow uniform processing in our caller): - :title : list of cons cells each of whose car is an @@ -932,7 +932,7 @@ processing in our caller): (rest (cdr raw-item))) (cond ((string= key "version") - (unless (eq 8 (car rest)) + (unless (or (eq 9 (car rest)) (eq 8 (car rest))) (error "Unsupported score file version %s" (car rest)))) ((string= key "title") (setq @@ -1090,6 +1090,12 @@ processing in our caller): (elfeed-score-serde--parse-scoring-sexp-6 sexps)) ((eq version 7) (elfeed-score-serde--parse-scoring-sexp-7 sexps)) + ((eq version 8) + (elfeed-score-serde--parse-scoring-sexp-8 sexps)) + ;; Again not a typo-- version 9 adds a new optional field + ;; (:comment) to the end of each struct type; so old versions of + ;; elfeed-score will silently ignore, which I don't think we + ;; want. ((eq version elfeed-score-serde-current-format) (elfeed-score-serde--parse-scoring-sexp-8 sexps)) (t diff --git a/elfeed-score.el b/elfeed-score.el index ac02993..d904c36 100644 --- a/elfeed-score.el +++ b/elfeed-score.el @@ -3,7 +3,7 @@ ;; Copyright (C) 2019-2021 Michael Herstine ;; Author: Michael Herstine -;; Version: 1.0.0 +;; Version: 1.1.0 ;; Package-Requires: ((emacs "26.1") (elfeed "3.3.0")) ;; Keywords: news ;; URL: https://github.com/sp1ff/elfeed-score @@ -44,7 +44,7 @@ (require 'elfeed-score-scoring) (require 'elfeed-score-maint) -(defconst elfeed-score-version "1.0.0") +(defconst elfeed-score-version "1.1.0") (defgroup elfeed-score nil "Gnus-style scoring for Elfeed entries." diff --git a/test/smoke-test-core.el b/test/smoke-test-core.el index e8e6e84..c5415fe 100644 --- a/test/smoke-test-core.el +++ b/test/smoke-test-core.el @@ -173,9 +173,9 @@ ;; from 100 => 200 (with-temp-file elfeed-score-score-file - (insert "((version 8) + (insert "((version 9) (\"title\" - (:text \".*\" :value 200 :type r)) + (:text \".*\" :value 200 :type r :comment \"foo!\")) (\"content\" (:text \".*\" :value 10 :type r)) (\"feed\" @@ -209,6 +209,13 @@ (elfeed-score-maint-display-rules-by-last-match) (elfeed-score-maint-display-rules-by-match-hits) +;; Make sure the deser still contains comments: +(cl-assert + (equal + (elfeed-score-title-rule-comment + (car elfeed-score-serde-title-rules)) + "foo!")) + ;; OK-- now let's use the interactive rule functions to add some ;; rules, non-interactively. In this case, all defaults will be ;; respected, but the score file should be re-written & the current @@ -357,11 +364,11 @@ the Elfeed entry to be used in the test." ;; negative test-- try adding a rule with a dirty score file: (with-temp-file elfeed-score-score-file - (insert "((version 8) + (insert "((version 9) (\"title\" (:text \".*\" :value 200 :type r)) (\"content\" - (:text \".*\" :value 10 :type r)) + (:text \".*\" :value 10 :type r :comment \"content rule!\")) (\"feed\" (:text \"emacs-reddit\" :value 75 :type s :attr t))) ")) diff --git a/test/test-serde.el b/test/test-serde.el index 7888ab5..9844736 100644 --- a/test/test-serde.el +++ b/test/test-serde.el @@ -655,6 +655,37 @@ cf. `test-issue-12'." nil)) :version 8))))) +(ert-deftest test-format-version-9 () + "Smoke tests for format version 9. + +Version 9 added support for the :comment field." + (let* ((score-entries + '((version 9) + ("title" + (:text "hoping" :value -1000 :type s :comment "foo!")) + ("link" + (:text "foo" :value 100 :type r :comment "bar!")))) + (score-text (pp-to-string score-entries)) + (score-file (make-temp-file "elfeed-score-test-" nil nil score-text)) + (score-entries-read (elfeed-score-serde--parse-score-file score-file))) + (should (equal score-entries-read + (list :mark nil :adjust-tags nil :feeds nil + :titles + (list + (cons + (elfeed-score-title-rule--create + :text "hoping" :value -1000 :type 's :comment "foo!") + nil)) + :content nil :title-or-content nil + :authors nil :tag nil + :link + (list + (cons + (elfeed-score-link-rule--create + :text "foo" :value 100 :type 'r :comment "bar!") + nil)) + :version 9))))) + (ert-deftest test-add-rule () "Tests for `elfeed-score-serde-add-rule'." (with-elfeed-score-test