[net.sources] Weed out undesired articles with newsweed

ken@turtlevax.UUCP (05/19/84)

<Hurrah for information hierarchy>
Now that turtlevax can post articles to the net again, I'm resubmitting
the newsweed package.  Newsweed lets you look at the titles of unread
articles, and delete all those that aren't interesting.  When you exit
the editor, newsweed updates your .newsrc to reflect your decision.
Get back at those people who don't use titles, or use the "Orphaned
Response" title.
--
Ken Turkowski @ CADLINC, Palo Alto, CA
UUCP: {amd70,decwrl,flairvax}!turtlevax!ken

-----------------------------------------------------------------
echo x - newsweed.1
cat >newsweed.1 <<'!Funky!Stuff!'
.TH NEWSWEED 1 local
.SH NAME
newsweed
.SH SYNOPSIS
.B newsweed
[readnews options]
.br
.B readnews
.SH DESCRIPTION
.I Newsweed
is a program to help in managing the vast number of articles
in the network news.
It is used to delete articles that are not interesting
before using
.I readnews
to read them.
.PP
A while after invoking
.I newsweed,
the user is presented with a list of titles of news articles
in his preferred editor,
as indicated by the environment variable EDITOR
(\fIvi\fR is the default).
Then the user deletes lines containing titles of undesired articles,
writes the file,
and lets
.I newsweed
modify the
.I .newsrc
file so that the undesired articles will not be presented.
The previous
.I .newsrc
is saved as
.I .newsrc.old.
.PP
Typically, one ends up deleting 80% of new news,
and saving an immense amount of time.
.SH FILES
~/.newsrc
.SH SEE ALSO
readnews(1), checknews(1)
.SH AUTHOR
Ken Turkowski
.SH BUGS
The title file is presented in alphabetical order
and should remain in alphabetical order;
otherwise not all of the uninteresting articles will be deleted.
.PP
It may take a long time to generate the titles file if
.I newsweed
is used to catch up on a backlog of news,
as after returning from vacation;
the csh ^Z stop signal is useful to put newsweed into the background
during phases other than the EDIT phase.
!Funky!Stuff!
echo x - newsweed
cat >newsweed <<'!Funky!Stuff!'
TEMP=/tmp/weed$$
NEWSRC=$HOME/.newsrc
AWKFILE=/usr/local/lib/newsweed.awk
trap 'rm ${TEMP}?; exit' 0 2
echo Making list of article titles
readnews -l $* | sort -o ${TEMP}a
if test -s ${TEMP}a
then
    cp ${TEMP}a ${TEMP}b
    echo Please remove article titles which you do not wish to read
    sleep 1
    reset	# So that vi's CRLF doesn't get trashed
    ${EDITOR-vi} ${TEMP}b
    if cmp -s ${TEMP}a ${TEMP}b
    then
	echo No articles deleted.
    else
	comm -23 ${TEMP}a ${TEMP}b | sed 's/ .*//' > ${TEMP}c
	echo Removing unwanted articles
	cp $NEWSRC $NEWSRC.old
	awk -f $AWKFILE $NEWSRC.old ${TEMP}c > ${TEMP}d
	cp ${TEMP}d $NEWSRC
    fi
else
    echo No news.
fi
!Funky!Stuff!
echo x - newsweed.awk
cat >newsweed.awk <<'!Funky!Stuff!'
BEGIN	{
	groupcount = 1
    }

/^options/	{
	options = $0
    }

/^[^/]*:/	{			# .newsrc input -- subscribed group
	j = index($0, ":")
	group = substr($0, 1, j-1)
	i = groupindex[group] = groupcount++
	newsgroup[i] = group
	grouptype[i] = ":"
	newsread[i] = substr($0, j+2)	# list of articles read
    }

/^[^/]*!/	{			# .newsrc input -- unsubscribed group
	j = index($0, "!")
	group = substr($0, 1, j-1)
	i = groupindex[group] = groupcount++
	newsgroup[i] = group
	grouptype[i] = "!"
	newsread[i] = substr($0, j+2)	# list of articles read
    }

/^[^ /]+\/[0-9]+/	{		# readnews -l output
	j = index($0, "/")
	group = substr($0, 1, j-1)
	i = groupindex[group]
	if (!i) {		# not previously encountered
	    i = groupindex[group] = groupcount++
	    newsgroup[i] = group
	    grouptype[i] = ":"
	}
	k = index($0, " ")
	if (k == 0)
	    article = substr($0, j+1)
	else
	    article = substr($0, j+1, k-j-1)
	if (newsread[i])
	    newsread[i] = newsread[i] "," article
	else
	    newsread[i] = article
    }

END	{
	if (options != 0)
	    print options
	for (i = 1; i < groupcount; i++) {
	    n = split(newsread[i], artlist, ",")
	    for (j = 1; j <= n; j++) {
		if (split(artlist[j], range, "-") == 1) {
		    rangelist[j] = artlist[j]
		}
		else {
		    artlist[j] = range[1]
		    rangelist[j] = range[2]
		}
	    }
	    # sort articles
	    sorted = 0
	    start = 1
	    while (sorted == 0) {
		sorted = 1
		for (j = start; j < n; j++) {
		    if (j == start && !artlist[start]) {
			start++
			continue
		    }
		    if (artlist[j+1] < artlist[j]) {	# swap
			temp = artlist[j+1]
			artlist[j+1] = artlist[j]
			artlist[j] = temp
			temp = rangelist[j+1]
			rangelist[j+1] = rangelist[j]
			rangelist[j] = temp
			sorted = 0
		    }
		    if (artlist[j] && rangelist[j]+1 == artlist[j+1]) {	# merge
			artlist[j+1] = artlist[j]
			artlist[j] = ""
			rangelist[j] = ""
		    }
		}
	    }
	    printf "%s%s", newsgroup[i], grouptype[i]
	    first = 1
	    for (j = start; j <= n; j++) {
		if (artlist[j]) {
		    if (first == 0) printf ","
		    else printf " "
		    first = 0
		    if (artlist[j] != rangelist[j])
			printf "%d-%d", artlist[j], rangelist[j]
		    else
			printf "%d", artlist[j]
		}
	    }
	    printf "\n"
	}
    }
!Funky!Stuff!