#! /usr/local/bin/perl # Script to read a tag-enhanced book of plots # Copyright 1996, 1998 by Alexander Forst # alex@complang.tuwien.ac.at # # This is my first Perl script. You are allowed to point out # errors, make every change you like as long as you notify me # and don't laugh. :-) # # usage: plt2html.pl ... # outputs a number of files: pl0.html, pl1.html,... # # these constants are useful for parsing in different modes # the variable $parseMode must be set to one of these values #open(IN,"plots1.tag") || die("not found"); #open(IN,"tag.txt") || die("not found"); $parsePreamble = "<(author|date|length|genre|type|setting|monster|plot)>"; $parseAuthor = ""; $parseEnd = ""; $parseVillain = "<(stats|list|/villain)>"; $parsePlot = "<(stats|list|villain|/plot)>"; $htmlFooter = <<EOT; <hr> <ADDRESS class="plots"> [<A HREF="index.html">The Net Book of Plots Home Page</A>] </ADDRESS> EOT &initParse; $parseMode = "<title>"; $otherText = ""; # Placeholder for text before and after plots. # This text is stored in the file contents.html $count = 0; &newPlot; while( &nextToken ) { if( $token eq "<title>" ) { $otherText .= $text; # save text before and between plots if( $plotTitle ) { &outPlot; $count++; } &newPlot; &readTitle; } &readAuthor if( $token eq "<author>" ); &readDate if( $token eq "<date>" ); &readLength if( $token eq "<length>" ); &readGenre if( $token eq "<genre>" ); &readType if( $token eq "<type>" ); &readSetting if( $token eq "<setting>" ); &readMonster if( $token eq "<monster>" ); &readPlot if( $token eq "<plot>" ); } $text = $otherText . $text; &parseText; $otherText = $text; # save text after all plots &outPlot; open( INDEX, ">contents.html" ) || die( "Cannot open contents.html" ); print INDEX "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n"; print INDEX "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n"; print INDEX "<html>\n<head>\n<title>Plot Book: Contents\n"; print INDEX "\n"; print INDEX "\n\n"; print INDEX <Note: This page contains editor's notes and any additional text of the Net Books of Plots.

Contents

EOT print INDEX $otherText; print INDEX $htmlFooter; print INDEX "\n"; close( INDEX ); open( INDEX, ">length.html" ) || die( "Cannot open length.html" ); print INDEX "\n"; print INDEX "\n\nPlots by length\n"; print INDEX "\n"; print INDEX "\n

Plots by length

\n"; foreach $key (sort(keys(%lengths))) { print INDEX "

Plots of length \"$key\"

\n"; print INDEX "
    \n"; foreach $pl (unpack("s*",$lengths{$key})) { print INDEX "
  • $titles{$pl}\n"; } print INDEX "
\n\n"; } print INDEX $htmlFooter; print INDEX "\n"; close( INDEX ); open( INDEX, ">genre.html" ) || die( "Cannot open genre.html" ); print INDEX "\n"; print INDEX "\n\nPlots by genre\n"; print INDEX "\n"; print INDEX "\n

Plots by genre

\n"; foreach $key (sort(keys(%genres))) { print INDEX "

Plots of genre \"$key\"

\n"; print INDEX "
    \n"; foreach $pl (unpack("s*",$genres{$key})) { print INDEX "
  • $titles{$pl}\n"; } print INDEX "
\n\n"; } print INDEX $htmlFooter; print INDEX "\n"; close( INDEX ); open( INDEX, ">type.html" ) || die( "Cannot open type.html" ); print INDEX "\n"; print INDEX "\n\nPlots by type\n"; print INDEX "\n"; print INDEX "\n

Plots by type

\n"; foreach $key (sort(keys(%types))) { print INDEX "

Plots of type \"$key\"

\n"; print INDEX "
    \n"; foreach $pl (unpack("s*",$types{$key})) { print INDEX "
  • $titles{$pl}\n"; } print INDEX "
\n\n"; } print INDEX $htmlFooter; print INDEX "\n"; close( INDEX ); open( INDEX, ">setting.html" ) || die( "Cannot open setting.html" ); print INDEX "\n"; print INDEX "\n\nPlots by setting\n"; print INDEX "\n"; print INDEX "\n

Plots by setting

\n"; foreach $key (sort(keys(%settings))) { print INDEX "

Plots of setting \"$key\"

\n"; print INDEX "
    \n"; foreach $pl (unpack("s*",$settings{$key})) { print INDEX "
  • $titles{$pl}\n"; } print INDEX "
\n\n"; } print INDEX $htmlFooter; print INDEX "\n"; close( INDEX ); open( INDEX, ">monster.html" ) || die( "Cannot open monster.html" ); print INDEX "\n"; print INDEX "\n\nPlots with special monster\n"; print INDEX "\n"; print INDEX "\n

Plots with special monsters

\n"; foreach $key (sort(keys(%monsters))) { print INDEX "

Plots with monster \"$key\"

\n"; print INDEX "
    \n"; foreach $pl (unpack("s*",$monsters{$key})) { print INDEX "
  • $titles{$pl}\n"; } print INDEX "
\n\n"; } print INDEX $htmlFooter; print INDEX "\n"; close( INDEX ); sub newPlot { $plotTitle = ""; @plotAuthors = (); $plotDate = ""; $plotLength = ""; @plotGenres = (); @plotTypes = (); @plotSettings = (); @plotMonsters = (); $plotVillains = ""; $plotPlot = ""; } sub outPlot { $, = ", "; open( OUT, ">pl$count.html" ) || die( "Cannot open pl$count.html" ); print OUT "\n"; print OUT "\n\n"; print OUT "\n"; print OUT "Plot Book - $plotTitle\n"; print OUT "\n"; print OUT "\n\n"; print OUT "

$plotTitle

\n"; print OUT "
"; print (OUT "Author: @plotAuthors
\n") if( @plotAuthors ); print OUT "Submission Date: $plotDate
\n" if( $plotDate ); print OUT "Length: $plotLength
\n"; print OUT "Genre: "; print OUT @plotGenres; print OUT "
\n"; print OUT "Type: "; print OUT @plotTypes; print OUT "
\n"; print OUT "Setting: "; print OUT @plotSettings; print OUT "
\n"; print (OUT "Monster: @plotMonsters
\n") if( @plotMonsters ); print OUT "
\n"; print OUT "\n

The Plot

\n

\n$plotPlot"; print OUT "\n

Villains

\n

\n$plotVillains" if( $plotVillains ); print OUT $htmlFooter; print OUT "\n\n\n"; close( OUT ); } sub readTitle { $parseMode = ""; &nextToken; $plotTitle = $text; $parseMode = $parsePreamble; $titles{ $count } = $plotTitle; } sub readAuthor { local($author); local($item,@list); $parseMode = $parseAuthor; do { &nextToken; $author .= " <$text>" if( $token eq "" ); $author = $text if( $token eq "" ); } until( $token eq "" ); $author = $text unless( $author ); push( @plotAuthors, $author ); $parseMode = $parsePreamble; $item = $authors{ $author }; @list = unpack( "s*", $item ); push( @list, $count ); $authors{ $author } = pack( "s*", @list ); } sub readDate { $parseMode = ""; &nextToken; $plotDate = $text; $parseMode = $parsePreamble; } sub readLength { local($item,@list); $parseMode = ""; &nextToken; $plotLength = "$text"; $parseMode = $parsePreamble; $item = $lengths{ $text }; @list = unpack( "s*", $item ); push( @list, $count ); $lengths{ $text } = pack( "s*", @list ); } sub readGenre { local($item,@list); $parseMode = ""; &nextToken; push( @plotGenres, "$text" ); $parseMode = $parsePreamble; $item = $genres{ $text }; @list = unpack( "s*", $item ); push( @list, $count ); $genres{ $text } = pack( "s*", @list ); } sub readType { local($item,@list); $parseMode = ""; &nextToken; push( @plotTypes, "$text" ); $parseMode = $parsePreamble; $item = $types{ $text }; @list = unpack( "s*", $item ); push( @list, $count ); $types{ $text } = pack( "s*", @list ); } sub readSetting { local($item,@list); $parseMode = ""; &nextToken; push( @plotSettings, "$text" ); $parseMode = $parsePreamble; $item = $settings{ $text }; @list = unpack( "s*", $item ); push( @list, $count ); $settings{ $text } = pack( "s*", @list ); } sub readMonster { local($item,@list); $parseMode = ""; &nextToken; push( @plotMonsters, "$text" ); $parseMode = $parsePreamble; $item = $monsters{ $text }; @list = unpack( "s*", $item ); push( @list, $count ); $monsters{ $text } = pack( "s*", @list ); } sub readVillain { $parseMode = $parseVillain; do { &nextToken; if( $token eq "" ) { &parseText; $plotVillains .= $text . "\n

";
	    $parseMode = "";
	    &nextToken;
	    $plotVillains .= $text . "
\n"; $parseMode = $parseVillain; } elsif( $token eq "" ) { &parseText; $plotVillains .= $text; $plotVillains .= &parseList; $parseMode = $parseVillain; } } until( $token eq "" ); &parseText; $plotVillains .= $text; } sub readPlot { local($listIndent); $parseMode = $parsePlot; do { &nextToken; if( $token eq "" ) { &parseText; $plotPlot .= $text . "\n
";
	    $parseMode = "";
	    &nextToken;
	    $plotPlot .= $text . "
\n"; $parseMode = $parsePlot; } elsif( $token eq "" ) { &parseText; $plotPlot .= $text; $plotPlot .= &parseList; $parseMode = $parsePlot; } elsif( $token eq "" ) { &parseText; $plotPlot .= "$text

"; &readVillain; $parseMode = $parsePlot; } } until( $token eq "" ); &parseText; $plotPlot .= $text; $parseMode = $parseEnd; } sub parseList { # the token has been already parsed local($listText,$listType,$end); $parseMode = ""; $listText = ""; $listType = ""; $end = 0; do { &nextToken; # searching for the next token if( $token eq "" ) { # there is another list if( $text =~ s/\n\s*[-+\*][):]?/\n

  • /g ) { &parseText; $listText .= $text; $listType = "ul"; } else { $text =~ s/\n\s*([0-9]+[.):]?)/\n
  • /g; $text =~ s/\n\s*([a-zA-Z][.)])/\n
  • /g; &parseText; $listText .= $text; $listType = "ol"; } $listText .= &parseList; } else # end of list reached { if( $text =~ s/\n\s*[-+\*][):]?/\n
  • /g ) { &parseText; $listText .= $text; $listType = "ul"; } else { $text =~ s/\n\s*([0-9]+[.):]?)/\n
  • /g; $text =~ s/\n\s*([a-zA-Z][.)])/\n
  • /g; &parseText; $listText .= $text; $listType = "ol"; } $end = 1; } } until( $end ); "<$listType>$listText"; } sub parseText { $text =~ s/\n([:=\-]+\n+)+/\n
    \n/g; # dividers $text =~ s/\n\s*\n/\n

    \n/g; # paragraphs $text =~ s/([_*+])(\w+)\1/$2<\/em>/g; # emphasis } # read the next token --> $token # the text before the token is stored # in $text sub nextToken { $text =""; # clear the text do { if( $parse ) { # we have a parse line if( $parse =~ m/$parseMode/i ) { # we found a token $text .= $`; # save the text before the token $token = $&; # this is the token $token =~ tr/A-Z/a-z/; # change to lowercase $parse = $'; # parse the rest of the line return 1; # success! } else { $text .= $parse; # save all text $parse = ""; # nothing left to parse } } } while( $parse = <> ); # read next line return 0; # it was the last line } sub initParse { $parse = ""; %titles = (); %authors = (); %lengths = (); %genres = (); %types = (); %settings = (); %monsters = (); }