A score file is an
emacs-lisp file that normally contains just a
single form. Casual users are not expected to edit these files;
everything can be changed from the summary buffer.
Anyway, if you’d like to dig into it yourself, here’s an example:
(("from" ("Lars Ingebrigtsen" -10000) ("Per Abrahamsen") ("larsi\\|lmi" -50000 nil R)) ("subject" ("Ding is Badd" nil 728373)) ("xref" ("alt.politics" -1000 728372 s)) ("lines" (2 -100 nil <)) (mark 0) (expunge -1000) (mark-and-expunge -10) (read-only nil) (orphan -10) (adapt t) (files "/hom/larsi/News/gnu.SCORE") (exclude-files "all.SCORE") (local (gnus-newsgroup-auto-expire t) (gnus-summary-make-false-root empty)) (eval (ding)))
This example demonstrates most score file elements. See Advanced Scoring, for a different approach.
Even though this looks much like Lisp code, nothing here is actually
evaled. The Lisp reader is used to read this form, though, so it
has to be valid syntactically, if not semantically.
Six keys are supported by this alist:
If the key is a string, it is the name of the header to perform the
match on. Scoring can only be performed on these eight headers:
Date. In addition to
these headers, there are three strings to tell Gnus to fetch the entire
article and do the match on larger parts of the article:
will perform the match on the body of the article,
perform the match on the head of the article, and
perform the match on the entire article. Note that using any of these
last three keys will slow down group entry considerably. The
final “header” you can score on is
Followup. These score
entries will result in new score entries being added for all follow-ups
to articles that matches these score entries.
Following this key is an arbitrary number of score entries, where each score entry has one to four elements.
gnus-score-interactive-default-scorenumber will be used instead. This is 1000 by default.
For most header types, there are the
R (regexp), as
S (substring) types, and
E (exact match), and
w (word match) types. If this
element is not present, Gnus will assume that substring matching should
E differ from the others in
that the matches will be done in a case-sensitive manner. All these
one-letter types are really just abbreviations for the
word types, which you can use
instead, if you feel like.
Just as for the standard string overview headers, if you are using gnus-extra-headers, you can score on these headers’ values. In this case, there is a 5th element in the score entry, being the name of the header to be scored. The following entry is useful in your all.SCORE file in case of spam attacks from a single origin host, if your NNTP server tracks ‘NNTP-Posting-Host’ in overviews:
("111.222.333.444" -1000 nil s "NNTP-Posting-Host")
These two headers use different match types:
These predicates are true if
(PREDICATE HEADER MATCH)
evaluates to non-
nil. For instance, the advanced match
("lines" 4 <) (see Advanced Scoring) will result in the
(< header-value 4)
Or to put it another way: When using
Lines with 4 as
the match, we get the score added if the article has less than 4 lines.
(It’s easy to get confused and think it’s the other way around. But
it’s not. I think.)
When matching on
Lines, be careful because some back ends (like
nndir) do not generate
Lines header, so every article ends
up being marked as having 0 lines. This can lead to strange results if
you happen to lower score of the articles with few lines.
For the Date header we have three kinda silly match types:
after. I can’t really imagine this
ever being useful, but, like, it would feel kinda silly not to provide
this function. Just in case. You never know. Better safe than sorry.
Once burnt, twice shy. Don’t judge a book by its cover. Never not have
sex on a first date. (I have been told that at least one person, and I
quote, “found this function indispensable”, however.)
A more useful match type is
regexp. With it, you can match the
date string using a regular expression. The date is normalized to
ISO8601 compact format first—YYYYMMDD
you want to match all articles that have been posted on April 1st in
every year, you could use ‘....0401.........’ as a match string,
for instance. (Note that the date is kept in its original time zone, so
this will match articles that were posted when it was April 1st where
the article was posted from. Time zones are such wholesome fun for the
whole family, eh?)
Finally, two actually useful match types for dates:
>. These will allow scoring on the relative age (in days) of
the articles. Here’s an example score file using the method:
(("date" (7 10 nil <) (7 -10 nil >) (14 -10 nil >)))
This results in articles less than a week old getting a 10 point increase, articles older than a week getting a 10 point decrease, and articles older than two weeks getting a cumulative 20 point decrease.
The day can also be a floating point number: To score articles less than an hour old, you can say ‘(0.04 10 nil <)’.
These three match keys use the same match types as the
This match key is somewhat special, in that it will match the
From header, and affect the score of not only the matching
articles, but also all followups to the matching articles. This allows
you to increase the score of followups to your own articles, or
decrease the score of followups to the articles of some known
trouble-maker. Uses the same match types as the
uses. (Using this match key will lead to creation of ADAPT
This match key works along the same lines as the
key. If you say that you want to score on a (sub-)thread started by an
article with a
Message-ID x, then you add a ‘thread’
match. This will add a new ‘thread’ match for each article that
has x in its
References header. (These new ‘thread’
matches will use the
Message-IDs of these matching articles.)
This will ensure that you can raise/lower the score of an entire thread,
even though some articles in the thread may not have complete
References headers. Note that using this may lead to
nondeterministic scores of the articles in the thread. (Using this match
key will lead to creation of ADAPT files.)
The value of this entry should be one or more user-defined function names in parentheses. Each function will be called in order and the returned value is required to be an integer.
The user-defined function is called with an associative list with the
number subject from date id refs chars lines xref extra
followed by the article’s score before the function is run.
The following (somewhat contrived) example shows how to use a user-defined function that increases an article’s score by 10 if the year of the article’s date is also mentioned in its subject.
(defun custom-scoring (article-alist score) (let ((subject (cdr (assoc 'subject article-alist))) (date (cdr (assoc 'date article-alist)))) (if (string-match (number-to-string (nth 5 (parse-time-string date))) subject) 10)))
score-fn entries are permanent and can only be added or
modified directly in the
The value of this entry should be a number. Any articles with a score lower than this number will be marked as read.
The value of this entry should be a number. Any articles with a score lower than this number will be removed from the summary buffer.
The value of this entry should be a number. Any articles with a score lower than this number will be marked as read and removed from the summary buffer.
The value of this entry should be a number. All articles that belong to
a thread that has a total score below this number will be marked as read
and removed from the summary buffer.
says how to compute the total score for a thread.
The value of this entry should be any number of file names. These files are assumed to be score files as well, and will be loaded the same way this one was.
The clue of this entry should be any number of files. These files will not be loaded, even though they would normally be so, for some reason or other.
The value of this entry will be
evaled. This element will be
ignored when handling global score files.
Read-only score files will not be updated or saved. Global score files should feature this atom (see Global Score Files). (Note: Global here really means global; not your personal apply-to-all-groups score files.)
The value of this entry should be a number. Articles that do not have parents will get this number added to their scores. Imagine you follow some high-volume newsgroup, like ‘comp.lang.c’. Most likely you will only follow a few of the threads, also want to see any new threads.
You can do this with the following two score file entries:
(orphan -500) (mark-and-expunge -100)
When you enter the group the first time, you will only see the new threads. You then raise the score of the threads that you find interesting (with I T or I S), and ignore (c y) the rest. Next time you enter the group, you will see new articles in the interesting threads, plus any new threads.
I.e., the orphan score atom is for high-volume groups where a few interesting threads which can’t be found automatically by ordinary scoring rules exist.
This entry controls the adaptive scoring. If it is
default adaptive scoring rules will be used. If it is
adaptive scoring will be performed on this group. If it is a list, this
list will be used as the adaptive scoring rules. If it isn’t present,
or is something other than
ignore, the default
adaptive scoring rules will be used. If you want to use adaptive
scoring on most groups, you’d set
t, and insert an
(adapt ignore) in the groups where you do
not want adaptive scoring. If you only want adaptive scoring in a few
groups, you’d set
(adapt t) in the score files of the groups where you want
All adaptive score entries will go to the file named by this entry. It will also be applied when entering the group. This atom might be handy if you want to adapt on several groups at once, using the same adaptive file for a number of groups.
The value of this entry should be a list of
value) pairs. Each var will be made buffer-local to the
current summary buffer, and set to the value specified. This is a
convenient, if somewhat strange, way of setting variables in some
groups if you don’t like hooks much. Note that the value won’t