#!/usr/bin/ruby -W require 'cgi' require 'rdoc/template' class String def without_leading_article sub( /^(A|An|The) /, '' ) end end class Items < Array def initialize( type, filename ) file = File.open(filename, 'r') artist_line = nil file.each_line { |line| line.chomp! item = nil case type when :cds if ( line.sub!( /^\s+/, '' ) ) item = CD.new( artist_line, line ) else artist_line = line end when :books item = Book.new( line ) artist_line = nil when :movies item = Movie.new( line ) artist_line = nil else raise "Unknown classname #{classname}\n" end # case self << item if item } # each_line end def titles() return self.sort_by{ |a| a.title_sortkey }.map { |item| { 'title' => item.title_display, 'author' => item.author_display } } end def titles_by_letter() letters = Hash.new{ |h,k| h[k]=[] } self.sort_by{|a|a.title_sortkey}.each{|item| letters[ item.title_sortkey[0,1] ] << item } return letters.keys.sort.map { |letter| { 'index_letter' => letter, 'titles' => letters[letter].map{|x|x.title_display}.join( ', ' ) } } end def titles_by_author() works = Hash.new{ |h,k| h[k]=[] } self.each { |item| tuple = [ item.author_sortkey, item.author_display ] works[tuple] << item.title_display } authors = works.keys.sort_by{ |tuple| tuple[0] } return authors.map { |tuple| { 'author' => tuple[1], 'titles' => works[tuple].join( '; ' ) } } end end class Item def title_display() return @title end def author_display() return @author ? @author.sub( /\^/, '' ) : '' end def title_sortkey() return @title.without_leading_article end def author_sortkey() return @author.without_leading_article.sub( /(.+)\^(.+)/, '\2 \1' ) end end class Book < Item def initialize( line ) line =~ /(.+), by (.+)/ @title = $1 @author = $2 @isbn = @author.sub!( / \((.+)\)/, '' ) ? $1 : nil end end class CD < Item def initialize( artist_line, title_line ) @author = artist_line @title = title_line end end class Movie < Item def initialize( line ) @title = line end end books = Items.new( :books, 'books.txt' ); cds = Items.new( :cds, 'cds.txt' ); movies = Items.new( :movies, 'movies-rent.txt' ); HTML = %{ Andy's Want List
CDs Books
START:cds

%author%: %titles%

END:cds
START:books

%title%, by %author%

END:books
Movies to rent
START:movies

%index_letter% %titles%

END:movies
(Ruby source code) } data = { 'cds' => cds.titles_by_author, 'books' => books.titles, 'movies' => movies.titles_by_letter, } cgi = CGI.new( 'html4' ) print cgi.header( 'type' => 'text/html' ) t = TemplatePage.new(HTML) t.write_html_on(STDOUT,data) # ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: