#!/usr/bin/perl5 # Create an HTML quiz. There are two output files-- the quiz and the # result files-- and one input file. The input file has these tags: # >>QUIZ-TITLE the titles of the output files # >>QUIZ-NAME <name> names the form and output files (name.html and # name_result.html # >>QUIZ-HEAD # <line>+ the leading text in the quiz # >>QUIZ-FOOT # <line>+ the trailing text in the quiz # >>QUIZ-RHEAD # <line>+ the leading text in the result # >>QUIZ-RFOOT # <line>+ the trailing text in the result # >>QUIZ-QUEST quiz question # Q <line>+ text of question # [CR][WR]<line>+ column or row, wrong or right response # R <line>+ text to print for correct answer # W <line>+ text to print for wrong answer # B <line>+ text to print for either answer $state = 'start'; $fields = 0; while(<>) { if(/^>>QUIZ-([A-Z]+)\W/) { if($1 eq 'TITLE') { m/^>>QUIZ-TITLE\s+(\w.+)$/; $title = $1; }elsif($1 eq 'NAME') { m/^>>QUIZ-NAME\s+(\w.+)$/; $name = $1; }elsif($1 eq 'HEAD') { $state = 'head'; }elsif($1 eq 'FOOT') { $state = 'foot'; }elsif($1 eq 'RHEAD') { $state = 'rhead'; }elsif($1 eq 'RFOOT') { $state = 'rfoot'; }elsif($1 eq 'QUEST') { $state = 'quest'; $quest = (defined $quest) ? $quest+1 : 0; $row = 0; $col = 0; $ans= 0; } } elsif($state eq 'head') { $head[++$#head] = $_; } elsif($state eq 'rhead') { $rhead[++$#rhead] = $_; } elsif($state eq 'foot') { $foot[++$#foot] = $_; } elsif($state eq 'rfoot') { $rfoot[++$#rfoot] = $_; } elsif($state eq 'quest') { # A quiz question, which consists of: # the text of the query, tagged by a leading Q # the answers, tagged by a leading [RC][RW]: # R means start a new row of answers # C means start a new column of answers # R means this answer is correct # W means this answer is wrong # text of the question grading, tagged by [RWB] # The order in which the questions and the answers to each question # are encountered in the input stream is the order in which they # appear in the output. # The data is stored thusly: # $quest is the question number, 0-based # $ans is the answer number, 0-based # $questText[$quest] is question text # $questAns[$quest][$ans] # $questIndex[$quest] is the index of the correct answer # $quest{Row,Col}[$quest][$ans] is the {row,column} of the answer if(/^Q\s+(\S.*)$/) { $questText[$quest] .= $1 . " "; } elsif(/^([RWB])\s+(\S.*)$/) { # gradeText[][0] is printed for a correct answer. # gradeText[][1] is printed for a wrong answer. # gradeText[][2] is printed for both, afterwards. $gradeText[$quest][($1 eq 'R') ? 0 : (($1 eq 'W') ? 1 : 2)] .= $2 . " "; } else { m/^(.)(.)\s+(\S.*)$/; $questAns[$quest][$ans] = $3; $questIndex[$quest] = $ans if($2 eq 'R'); $questRow[$quest][$ans] = $row; $questCol[$quest][$ans] = $col; $fields++ if($col > $fields); if($1 eq 'C') { $col++; } else { $row++; $col = 0; } $ans++; } } # state eq 'quest' } # loop on input lines # Validate. for($quest = 0; defined $questText[$quest]; $quest++) { die "No correct answer for question $quest ($questText[$quest]).\n" if(!defined $questIndex[$quest]); } $title = 'Quiz' if(!defined $title); $name = 'quiz' if(!defined $name); open(QUIZ, ">${name}.html") || die "Can't open ${name}.html for write.\n"; open(R, ">${name}_result.html") || die "Can't open ${name}_result.html for write.\n"; # Emit the code. # Header. print QUIZ <<"HTML"; <html> <head> <title>$title

$title

HTML print QUIZ @head; print QUIZ <<"HTML";
HTML # Body. for($quest = 0; defined $questText[$quest]; $quest++) { local($ans, $qi, $multiCol, $fi); print QUIZ "\n\n"; $qi = $quest+1; $fi = $fields+1; print QUIZ " \n"; print QUIZ " \n"; print QUIZ "\n"; # We really only support two formats right now: all the questions on one # row, or each question on a different row. Figure out which this is. $multiCol = ($questRow[$quest][0] == $questRow[$quest][1]); # Emit the answers, building new rows as necessary. print QUIZ "\n \n"; for ($ans = 0; defined $questAns[$quest][$ans]; $ans++) { print QUIZ ($multiCol) ? " \n\n \n \n"; } # loop on answers print QUIZ "\n"; } # loop on questions # Trailer. print QUIZ <<"HTML";
$qi.$questText[$quest]
" : "
"; print QUIZ " $questAns[$quest][$ans]
HTML print QUIZ @foot; print QUIZ "\n\n"; close(QUIZ); # Emit the results. # Header. print R <<"HTML"; $title Results

$title Results

HTML print R @rhead; print R <<"HTML"; \n"; # Trailer. print R @rfoot; print R "\n\n"; close(R);