head 1.17; access; symbols; locks; strict; comment @# @; 1.17 date 2018.08.19.15.02.57; author roderick; state Exp; branches; next 1.16; 1.16 date 2006.12.22.02.48.05; author roderick; state Exp; branches; next 1.15; 1.15 date 2006.12.06.14.41.22; author roderick; state Exp; branches; next 1.14; 1.14 date 2005.07.11.09.39.28; author roderick; state Exp; branches; next 1.13; 1.13 date 2005.01.23.12.59.21; author roderick; state Exp; branches; next 1.12; 1.12 date 2004.04.26.16.47.29; author roderick; state Exp; branches; next 1.11; 1.11 date 2003.07.11.14.46.19; author roderick; state Exp; branches; next 1.10; 1.10 date 2003.03.26.14.27.26; author roderick; state Exp; branches; next 1.9; 1.9 date 2002.12.20.14.54.14; author roderick; state Exp; branches; next 1.8; 1.8 date 2002.04.26.20.45.11; author roderick; state Exp; branches; next 1.7; 1.7 date 2002.03.04.13.47.24; author roderick; state Exp; branches; next 1.6; 1.6 date 2001.09.13.18.31.09; author roderick; state Exp; branches; next 1.5; 1.5 date 2001.09.03.17.31.32; author roderick; state Exp; branches; next 1.4; 1.4 date 2001.09.03.17.24.49; author roderick; state Exp; branches; next 1.3; 1.3 date 2000.04.19.21.13.56; author roderick; state Exp; branches; next 1.2; 1.2 date 99.11.18.15.19.02; author roderick; state Exp; branches; next 1.1; 1.1 date 99.09.30.13.38.06; author roderick; state Exp; branches; next ; desc @#!/usr/bin/perl5 -w @ 1.17 log @tweak @ text @#!/usr/bin/perl -w use strict; # $Id: books-gen,v 1.16 2006-12-21 21:48:05-05 roderick Exp roderick $ # # Roderick Schertler # Copyright (C) 1999 Roderick Schertler # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # For a copy of the GNU General Public License write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # This program converts my text-file database of books read to HTML # pages. Input data (read with <>) is in the form # # start-date end-date \ # <tab><author>[<tab><author>]... # # eg # # - 19891228 - n ---- The Golden Apple Shea R. Wilson R. A. # - 19920516 2 n 1972 A Transatlantic Tunnel Hurrah! Harrison Harry # 19950717 19950726 7 n 1974 The Mote in God's Eye Niven Larry Pournelle Jerry # 19990915 - 8 n 1965 Dune Herbert Frank # # The fields up until the title are whitespace-separated, the rest have # to be separated with tabs (since they can contain spaces). Blank # lines and comments are skipped. my %Type = ( b => 'bio', h => 'humor', x => 'nonfic', g => 'comic', n => 'novel', s => 'shortfic', o => 'other', ); my %Rating = ( '' => -5, # amount applied to rescale regular ratings 'a' => -6, '-' => -7, ); use RS::Handy qw(data_dump inverse_hash xdie); my $Debug = 0; my $Exit = 0; my %Rating_rev = inverse_hash %Rating; my @@Head = ('-s', '', '-r', '-y', '-d', '-t', '-a'); my %Link = ( '-s' => 'Started', '' => 'Finished', '-r' => 'Rating', '-y' => 'Type', '-d' => 'Copyright', '-t' => 'Title', '-a' => 'Author', ); sub F_START () { 0 } sub F_END () { 1 } sub F_RATING () { 2 } sub F_TYPE () { 3 } sub F_COPYRIGHT () { 4 } sub F_TITLE () { 5 } sub F_AUTHOR () { 6 } sub xwarn { RS::Handy::xwarn @@_; $Exit ||= 1; } sub preamble { print <<EOF <html><head><title>Books I've Read

Back to index

Here's a list of most of the non-technical books I've read since 1990, with significant gaps between 2013 and 2018.

Rating
0 is an average enjoyable read, positive is better than average and negative is worse. "a" (for abandoned) is a book I chose not to finish. I didn't start out with strict guidelines for the scale, but I've never gone over +3 or under -3. I have a lot more positive ratings than negative, I've presumed this is because I'm unlikely to pick up a book which I don't think I'll like.

If you largely agree with my rankings and you know a +2 or better which isn't on my list, tell me about it!

Copyright
I'd prefer to track when the book was written, but I don't have a good way to do that. I settled on tracking copyright dates in most cases.
EOF } sub postamble { print < These HTML pages are generated from a text file using my books-gen script.

Roderick Schertler <roderick\@@argon.org>

Back to index EOF } sub parse { my @@book; while (<>) { s/^\s*#.*//; next if /^\s*$/; chomp; my ($start, $end, $rating, $type, $copyright, $rest) = split ' ', $_, 6; my ($title, @@author) = split /\t+/, $rest; defined $author[0] or xdie "no author"; if ($start eq '-') { $start = ''; } else { $start =~ /^(\d\d\d\d)(\d\d)(\d\d)$/ or xdie "invalid start `$start'"; $start = "$1-$2-$3"; } if ($end eq '-') { $end = ''; } else { $end =~ /^(\d\d\d\d)(\d\d)(\d\d)$/ or xdie "invalid end `$end'"; $end = "$1-$2-$3"; } if (defined(my $new = $Rating{$rating})) { $rating = $new; } elsif ($rating =~ /^\d$/) { $rating += $Rating{''}; } else { xdie "invalid rating `$rating'"; } if (!defined $Type{$type}) { xdie "invalid type `$type'"; } if ($copyright =~ /^-+$/) { $copyright = '-1'; } elsif ($copyright !~ /^\d{4}$/) { xdie "invalid copyright `$copyright'"; } push @@book, [$start, $end, $rating, $type, $copyright, $title, \@@author]; } return @@book; } sub page_file { my ($type) = @@_; return "books$type.html"; } sub header { my ($type) = @@_; my $saw_type; print ""; for (@@Head) { if ($type eq $_) { print " $Link{$_}"; $saw_type = 1; } else { print ' $Link{$_}"; } } $saw_type or xdie "invalid type `$type'\n"; } sub table { my ($type, @@book) = @@_; print "

\n"; header $type; for (@@book) { my ($start, $end, $rating, $type, $copyright, $title, $rauthor) = @@$_; $start = ' ' if $start eq ''; $end = ' ' if $end eq ''; if (defined(my $new = $Rating_rev{$rating})) { $rating = $new; } $type = $Type{$type}; $copyright = ' ' if $copyright == -1; my $author = join '
', @@$rauthor; print "", "
$start", " $end", " $rating", " $type", " $copyright", " $title $author\n"; } header $type; print "
\n"; } sub page { my ($type, @@book) = @@_; local *FILE; my $file = page_file $type; print "generating $file\n"; open FILE, ">$file" or xdie "can't create $file:"; my $old_fh = select FILE; preamble; table $type, @@book; postamble; close FILE or xdie "error closing $file:"; select $old_fh; } { my %cache; sub dict ($) { my $s =shift; $cache{$s} ||= do { $s = lc $s; $s =~ tr/'//d; $s =~ tr/a-z/ /cs; $s =~ s/^ //; $s =~ s/ $//; $s =~ s/^(a|an|the) //; #print "$s\n"; $s } } } sub main { my @@book = parse; page '', reverse @@book; page '-s', @@book[sort { $book[$b][F_START] cmp $book[$a][F_START] or $b <=> $a } 0..$#book]; page '-r', @@book[sort { $book[$b][F_RATING] <=> $book[$a][F_RATING] or $b <=> $a } 0..$#book]; page '-y', @@book[sort { $book[$a][F_TYPE] cmp $book[$b][F_TYPE] or $b <=> $a } 0..$#book]; page '-d', @@book[sort { $book[$b][F_COPYRIGHT] <=> $book[$a][F_COPYRIGHT] or $b <=> $a } 0..$#book]; page '-t', @@book[sort { dict $book[$a][F_TITLE] cmp dict $book[$b][F_TITLE] or $b <=> $a } 0..$#book]; # For the author sort, create a separate entry for each author of a # book. my @@author; for my $b (@@book) { my @@a = @@{ $b->[F_AUTHOR] }; for (my $i = 0; $i <= $#a; $i++) { push @@author, [@@$b]; # Rearrange the author list so this author comes first. $author[$#author][F_AUTHOR] = [@@a]; unshift @@{ $author[$#author][F_AUTHOR] }, splice @@{ $author[$#author][F_AUTHOR] }, $i, 1; } } page '-a', @@author[sort { $author[$a][F_AUTHOR][0] cmp $author[$b][F_AUTHOR][0] or $b <=> $a } 0..$#author]; return 0; } $Exit = main || $Exit; $Exit = 1 if $Exit && !($Exit % 256); exit $Exit; # XXX add histograms for ratings, count by year, others? @ 1.16 log @Oops, correct rating adjustment. @ text @d4 1 a4 1 # $Id: books-gen,v 1.15 2006-12-06 09:41:22-05 roderick Exp roderick $ d95 2 a96 1

Here's a list of most of the non-technical books I've read since 1990. @ 1.15 log @Add rating "a" for abandoned. @ text @d4 1 a4 1 # $Id: books-gen,v 1.14 2005-07-11 05:39:28-04 roderick Exp roderick $ d58 1 a58 1 use RS::Handy qw(inverse_hash xdie); d168 1 a168 1 $rating -= $Rating{''}; @ 1.14 log @Tweak sorting. @ text @d4 1 a4 1 # $Id: books-gen,v 1.13 2005-01-23 07:59:21-05 roderick Exp roderick $ d52 7 a58 1 use RS::Handy qw(xdie); d62 1 d102 5 a106 5 and negative is worse. I didn't start out with strict guidelines for the scale, but I've never gone over +3 or under -3. I have a lot more positive ratings than negative, I've presumed this is because I'm unlikely to pick up a book which I don't think I'll like. d164 2 a165 2 if ($rating eq '-') { $rating = -6; d168 1 a168 1 $rating -= 5; d224 3 a226 1 $rating = ' ' if $rating == -6; d313 2 @ 1.13 log @Add type g, comic. @ text @d4 1 a4 1 # $Id: books-gen,v 1.12 2004-04-26 12:47:29-04 roderick Exp roderick $ d256 2 a257 1 $s =~ tr/a-z/ /cd; d260 2 @ 1.12 log @Use "./" rather than "" as link dest. @ text @d4 1 a4 1 # $Id: books-gen,v 1.11 2003-07-11 10:46:19-04 roderick Exp roderick $ d45 1 @ 1.11 log @Comment. @ text @d4 1 a4 1 # $Id: books-gen,v 1.10 2003-03-26 09:27:26-05 roderick Exp roderick $ d85 1 a85 1

Back to index d122 1 a122 1

Back to index @ 1.10 log @Allow - for copyright. @ text @d4 1 a4 1 # $Id: books-gen,v 1.9 2002-12-20 09:54:14-05 roderick Exp roderick $ d36 3 a38 2 # The first 4 fields are space-separated, the rest have to be separated # with tabs. Blank lines and comments are skipped. @ 1.9 log @Add start date. @ text @d4 1 a4 1 # $Id: books-gen,v 1.8 2002-04-26 16:45:11-04 roderick Exp roderick $ d169 1 a169 1 if ($copyright eq '----') { @ 1.8 log @Use perl rather than perl5. @ text @d4 1 a4 1 # $Id: books-gen,v 1.7 2002-03-04 08:47:24-05 roderick Exp roderick $ d26 1 a26 1 # yy-mm-dd \ d31 4 a34 4 # 19891228 - n ---- The Golden Apple Shea R. Wilson R. A. # 19920516 2 n 1972 A Transatlantic Tunnel Hurrah! Harrison Harry # 19950726 7 n 1974 The Mote in God's Eye Niven Larry Pournelle Jerry # 19990923 8 n 1965 Dune Herbert Frank d55 1 a55 1 my @@Head = ('', '-r', '-y', '-d', '-t', '-a'); d57 2 a58 1 '' => 'Finished', d66 7 a72 6 sub F_FIN () { 0 } sub F_RATING () { 1 } sub F_TYPE () { 2 } sub F_COPYRIGHT () { 3 } sub F_TITLE () { 4 } sub F_AUTHOR () { 5 } a89 6

Finished
This is the date I finished reading the book. You can't quite go from this to how long it took me to read it, because sometimes I read more than one book at a time, and I don't track that info. d133 1 a133 1 my ($fin, $rating, $type, $copyright, $rest) = split ' ', $_, 5; d137 17 a153 3 $fin =~ /^(\d\d\d\d)(\d\d)(\d\d)$/ or xdie "invalid fin `$fin'"; $fin = "$1-$2-$3"; d176 1 a176 1 push @@book, [$fin, $rating, $type, $copyright, $title, \@@author]; d212 3 a214 1 my ($fin, $rating, $type, $copyright, $title, $rauthor) = @@$_; d220 2 a221 1 " $fin", d265 2 @ 1.7 log @Change date format from yy-mm-dd to yyyymmdd. @ text @d1 1 a1 1 #!/usr/bin/perl5 -w d4 1 a4 1 # $Id: books-gen,v 1.6 2001-09-13 14:31:09-04 roderick Exp roderick $ @ 1.6 log @Rename RJS::Handy to RS::Handy. @ text @d4 1 a4 1 # $Id: books-gen,v 1.5 2001-09-03 13:31:32-04 roderick Exp roderick $ d31 4 a34 4 # 89-12-28 - n ---- The Golden Apple Shea R. Wilson R. A. # 92-05-16 2 n 1972 A Transatlantic Tunnel Hurrah! Harrison Harry # 95-07-26 7 n 1974 The Mote in God's Eye Niven Larry Pournelle Jerry # 99-09-23 8 n 1965 Dune Herbert Frank d141 1 a141 1 $fin =~ /^(\d\d)-\d\d-\d\d$/ d143 1 a143 1 $fin = $1 >= 89 ? "19$fin" : "20$fin"; @ 1.5 log @Add a link to the books-gen script. @ text @d4 1 a4 1 # $Id: books-gen,v 1.4 2001-09-03 13:24:49-04 roderick Exp roderick $ d50 1 a50 1 use RJS::Handy qw(xdie); d73 1 a73 1 RJS::Handy::xwarn @@_; @ 1.4 log @Add type information. @ text @d4 1 a4 1 # $Id: books-gen,v 1.3 2000-04-19 17:13:56-04 roderick Exp roderick $ d120 3 @ 1.3 log @Comment. @ text @d4 18 a21 1 # $Id$ d23 2 a24 1 # Input data (read with <>) is in the form d26 2 a27 1 # yy-mm-dd <tab><author>[<tab><author>]... d31 4 a34 4 # 89-12-28 - ---- The Golden Apple Shea R. Wilson R. A. # 92-05-16 2 1972 A Transatlantic Tunnel Hurrah! Harrison Harry # 95-07-26 7 1974 The Mote in God's Eye Niven Larry Pournelle Jerry # 99-09-23 8 1965 Dune Herbert Frank d36 1 a36 1 # The first 3 fields are space-separated, the rest have to be separated d39 11 d55 1 a55 1 my @@Head = ('', '-r', '-d', '-t', '-a'); d59 1 d67 4 a70 3 sub F_COPYRIGHT () { 2 } sub F_TITLE () { 3 } sub F_AUTHOR () { 4 } d134 1 a134 1 my ($fin, $rating, $copyright, $rest) = split ' ', $_, 4; d152 4 d163 1 a163 1 push @@book, [$fin, $rating, $copyright, $title, \@@author]; d199 1 a199 1 my ($fin, $rating, $copyright, $title, $rauthor) = @@$_; d201 1 d204 4 a207 1 print "<tr> <td>$fin <td align=right>$rating ", d251 2 @ 1.2 log @entered into RCS @ text @d6 14 @ 1.1 log @Initial revision @ text @d11 15 d97 1 a97 1 $rating = ' '; d107 1 a107 1 $copyright = ' '; d119 23 d143 1 a143 1 my @@book = @@_; d146 1 a146 1 print "<tr> <th>Finished <th>Rating <th>Copyright <th>Title <th>Author\n"; d148 1 a148 1 for (reverse @@book) { d150 2 d158 1 d162 9 a170 1 sub main { d172 1 a172 1 table parse; d174 45 @