home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl -s
- #
- # This is mklesson, a `lesson compiler.'
- # Mklesson takes a lesson file (.les) as its sole argument, and uses it to
- # generate a set of hypertext tutor files in HTML (.html) format.
- # The generated files are created in the current directory.
- # Status information is sent to standard output (which is usually the screen).
- #
- # Usage Example:
- # mklesson lesson9.les
- #
- # $Id: mklesson,v 1.15 1995/08/09 21:07:40 wheeler Exp $
- #
- # See the user's guide in file userg.html and formatmk.txt.
- #
- # Input:
- # (argument 1) -- filename of lesson (.les) file.
- # template -- file with templates used for file generation.
- # default -- if this file exists, it is read to find default settings
- # (its format is identical to a lesson header section).
- #
- #
- # Output: The program generates files with the following naming patterns:
- # sLESSON-SECTION.html - text for lesson number LESSON, section SECTION.
- # If this is the last one, SECTION is "f" (final)
- # so that the next lesson can always link
- # backwards correctly (didn't use "l" for last,
- # because it looks too much like a "1").
- # sLESSON-SECTIONrRESPONSENUMBER.html - text for response RESPONSENUMBER
- # lessonLESSON.html - lesson outline.
- #
- #
- # This program is written in the programming language perl because it's
- # a relatively short program that performs text processing (a perl strength),
- # and I wanted it to be VERY portable (perl is widely available).
- # Perl has some disadvantages, in particular, please be careful modifying
- # this program because the Perl language syntax is so awful that it's
- # as though it was designed to maximize error creation.
- #
- # Copyright (C) 1994 David A. Wheeler.
- #
- # 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.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- #
- # Since mklesson is free software, if you modify this program and
- # then distribute it (or results generated from it) you ARE REQUIRED
- # to distribute & permit anyone to copy the modified version of this program.
- #
- # You CAN use this program to generate
- # proprietary tutorials, just as you can use gcc to generate
- # proprietary executables. See the GPL for more information.
-
-
- # START OF MAIN PROGRAM
-
- if (defined($s)) {
- # a "-s" option uses Short extension names (.htm).
- $html_extension = ".htm";
- }
- else {
- # without a "-s" option, generate ".html" extensions.
- $html_extension = ".html";
- }
-
- &initialize_variables;
- &read_in_template; # Load the template file into memory.
- &read_in_defaults; # Load the contents of file "default".
-
- # Open & process the lesson file.
- $lesson_source=shift;
- &open_lesson_file;
- &process_input_header;
- &process_input_body;
- &change_timestamp_file($lesson_source);
-
- &move_in_new_files;
-
- # END OF MAIN PROGRAM
-
-
- # SUBROUTINES:
-
- sub process_input_header {
- # Process input file as a lesson header section.
- # Stop processing at end-of-file or a <SECTION> marker.
- # (The input file could be a "lesson" file or "default" file)
-
- while (&read_line) {
- if (m/^ *<TUTOR .*NAME="([^"]*)"/i) {
- if (($tutor_name ne "") && ($tutor_name ne $1) )
- {die "Cannot redefine tutor name"};
- $tutor_name=$1;
- print "Tutor name is $tutor_name\n";
- }
- elsif (m/^ *<LESSON .*NUMBER=([0-9]+)/i) {
- if ($lesson_number != 0) {die "Cannot redefine lesson number"};
- $lesson_number=$1;
- $lesson_outline_URL = "lesson${lesson_number}" . $html_extension;
- print "Lesson number is $lesson_number\n";
- }
- elsif (m/^ *<AUTHOR .*NAME="([^"]*)".*EMAIL="([^"]*)"/i) {
- $author_name=$1;
- $author_email=$2;
- print "Author name is $author_name\n";
- print "Author email (address) is $author_email\n";
- }
- elsif (m/^ *<AUTHOR .*ADDRESS="(.*)">$/i) {
- # Note: this format is slightly different, grabbing the ENTIRE line.
- # This is so that the address can include anchors and such, which
- # require the use of " and > characters.
- $author_address=$1;
- print "Author address is $author_address\n";
- }
- elsif (m/^ *<PREVIOUS_LESSON .*LOCATION="([^"]*)"/i) {
- if ($previous_lesson_location_set != 0)
- {die "Cannot redefine previous lesson location"};
- $previous_lesson_location = $1;
- $previous_lesson_location_set = 1;
- print "Previous lesson location is $previous_lesson_location\n";
- }
- elsif (m/^ *<NEXT_LESSON .*LOCATION="([^"]*)"/i) {
- if ($next_lesson_location_set != 0)
- {die "Cannot redefine next lesson location"};
- $next_lesson_location = $1;
- $next_lesson_location_set = 1;
- print "Next lesson location is $next_lesson_location\n";
- }
- elsif (m/^ *<MASTER_OUTLINE .*HREF="([^"]*)"/i) {
- if ($master_outline_URL_set != 0)
- {die "Cannot redefine master lesson outline URL"};
- $master_outline_URL = $1;
- $master_outline_URL_set = 1;
- print "Master outline URL is $master_outline_URL\n";
- }
- elsif (m/^ *<TUTOR_HOME_PAGE .*HREF="([^"]*)"/i) {
- if ($tutor_home_page_set != 0) {die "Cannot redefine tutor home page URL"};
- $tutor_home_page_URL = $1;
- $tutor_home_page_URL_set = 1;
- print "Tutor home page URL is $tutor_home_page_URL\n";
- }
- elsif (m/^<SECTION /i) {last}
- elsif (m/^ *$/) {} # Do nothing with blank lines.
- else {
- print "WARNING: LINE IN HEADER OF FILE IGNORED, TEXT IS:";
- print $_;
- }
- }
- # We found a SECTION header or end of file. Stop processing lesson header.
- }
-
- sub process_input_body {
- # Process body of a lesson file (it should have 2 or more sections).
-
- # Errorcheck - we should have gotten TUTOR, LESSON, and AUTHOR.
-
- if ($lesson_number < 1)
- {die "Sorry, no valid lesson number encountered!"};
-
- # Set up constants used in the rest of the program & open outline file.
- # This is the filename for the generated outline.
- $lesson_outline = "lesson${lesson_number}" . $html_extension;
- if (!open(OUTLINE, ">${lesson_outline}.new"))
- {die "Sorry, cannot open output lesson outline file ${lesson_outline}"};
- &substitute_and_append("outline.head", "outline");
-
- # Process body of .les file.
-
- while ($_ ne "") { # While there's still some text to process.
- if (m/^<SECTION /i) { &process_section; }
- else { print "Warning: text ignored outside of a section: $_" };
- &read_line; # Done processing; read in the next line.
- }
-
- # Done with all sections; close everything up.
- &close_section_if_necessary;
- &substitute_and_append("outline.tail", "outline");
- close(OUTLINE);
- close(IN);
- }
-
- sub process_section {
- # Process a single section from a lesson file.
- # Precondition: current line should have a SECTION command.
- &close_section_if_necessary; # Close previous section if necessary.
- $section_number++;
- # In the last section, use "f" as the section number in the filename
- # so that the next lesson can link back to it correctly.
- if ($section_number == $number_of_sections)
- {$section_number_file_rep = "f"}
- else
- {$section_number_file_rep = $section_number};
- # The only way to get here is if $_ contains <SECTION ...>; get its name.
- $title= $_;
- $title =~ s/^<SECTION .*NAME="([^"]*)".*$/$1/i;
- chop($title);
- print "Processing Section ${lesson_number}.${section_number}, ";
- print "Name (Title) = $title\n";
- $section_filename="s${lesson_number}-${section_number_file_rep}" .
- $html_extension;
- if (!open(SECTION, ">${section_filename}.new"))
- {die "Sorry, cannot open section file ${section_filename}"};
- $section_file_open = 1;
-
- &determine_next_section_URL;
- &determine_previous_section_URL;
- $section_question_URL = "s${lesson_number}-" .
- "${section_number_file_rep}" . $html_extension .
- "#quiz";
- $section_has_question = 0; # We haven't seen section question yet.
-
- print OUTLINE '<LI><A HREF="', ${section_filename}, '">', ${title}, "</A>\n";
-
- &reset_set_response;
- # Insert the section header.
- &substitute_and_append("section.head", "section");
-
- while (!eof(IN)) {
- &read_line;
-
- # Is this the start of a question?
- if (m/^<QUESTION[ >]/i) {&process_question;};
-
- # Is this the end of the section?
- if (m/^<SECTION /i) {&process_section; last}; # recurse.
- if (m/^<\/SECTION /i) {&close_section_if_necessary; last};
-
- # Normal text, just append it into the section.
- print SECTION $_;
- }
- }
-
-
- sub close_section_if_necessary {
- if ($section_file_open == 1) {
- if ($section_has_question == 0) {
- # No quiz question - insert the no_question template.
- &substitute_and_append("section.no_question", "section");
- }
- &substitute_and_append("section.tail", "section");
- close(SECTION);
- $section_file_open = 0;
- }
- }
-
- sub substitute_and_append {
- local($template_chunk, $file_to_append) = @_;
-
- # Append to $file_to_append the contents of $template_chunk
- # after performing appropriate substitutions.
-
- # $template_chunk is a string containing the name of the template chunk
- # from the template file to read in & perform substitutions on.
- # $file_to_append is a string containing the name of the file handler
- # to append to. This is a kludge; ideally we would pass in
- # actual file handle, but perl apparantly can't pass file
- # handles, so we pass in a string instead.
-
- local($template_text) = $template{ $template_chunk };
-
- # Substitute markers in the template with their current values.
-
- $template_text =~ s/\[TUTOR_NAME\]/${tutor_name}/g;
- $template_text =~
- s/\[FULL_SECTION_NUMBER\]/${lesson_number}.${section_number}/g;
- $template_text =~ s/\[SECTION_TITLE\]/${title}/g;
- $template_text =~ s/\[SECTION_NAME\]/${title}/g; # likely misspelling
- $template_text =~ s/\[AUTHOR_EMAIL\]/${author_email}/g;
- $template_text =~ s/\[AUTHOR_ADDRESS\]/${author_address}/g;
- $template_text =~ s/\[AUTHOR_NAME\]/${author_name}/g;
- $template_text =~ s/\[ANSWER_NUMBER\]/${current_response}/g;
- $template_text =~ s/\[LESSON_NUMBER\]/${lesson_number}/g;
- $template_text =~ s/\[LESSON_OUTLINE_URL\]/${lesson_outline_URL}/g;
- $template_text =~ s/\[TUTOR_HOME_PAGE_URL\]/${tutor_home_page_URL}/g;
-
- $template_text =~ s/\[MASTER_OUTLINE_URL\]/${master_outline_URL}/g;
- $template_text =~ s/\[TODAYS_DATE\]/${todays_date}/g;
- $template_text =~ s/\[TODAYS_YEAR\]/${todays_year}/g;
-
- # These values may change from section to section.
- $template_text =~ s/\[NEXT_SECTION_URL\]/${next_section_URL}/g;
- $template_text =~ s/\[PREVIOUS_SECTION_URL\]/${previous_section_URL}/g;
- $template_text =~
- s/\[THE_PREVIOUS_SECTION_OR_HOME\]/${the_previous_section_or_home}/g;
- $template_text =~
- s/\[CONFIRM_SKIP_SECTION_URL\]/${confirm_skip_section_URL}/g;
- $template_text =~
- s/\[SECTION_QUESTION_URL\]/${section_question_URL}/g;
-
-
- # Determine where to append this line & append it.
- if ($file_to_append eq "section") {print SECTION $template_text;}
- elsif ($file_to_append eq "response") {print RESPONSE $template_text;}
- elsif ($file_to_append eq "outline") {print OUTLINE $template_text;}
- else {die "Unexpected append parameter value $file_to_append!"};
- }
-
- sub process_question {
- # Process the question in the section.
-
- $section_has_question = 1;
- &substitute_and_append("section.question.head", "section");
-
- # Eliminate marker. If there's text left on this line, use it.
- s/<QUESTION[^>]*> *//i;
- chop;
- if ($_ ne "") {print SECTION "$_\n"};
-
- # Copy text until there's a <CHOICES> marker.
- while (!eof(IN)) {
- &read_line;
- if (/^<CHOICES/) {last};
- if (/^<SECTION/) {die "Error - previous question had no choices."};
- print SECTION;
- }
-
- # We've sent out the question to its end.
-
- &process_choices;
- &process_optional_responses;
- &generate_default_responses;
- }
-
-
- sub read_line {
- # Read line from file handle <IN>. Sets $_ to its new value, and returns it.
- # Discards <COMMENT > lines.
- $_ = $input_line = <IN>;
- if (/^ *<COMMENT /i) {&read_line}; # Don't include COMMENT lines.
- if (/^ *<TEXT /i) {&read_textfile}
- else {$input_line;} # Return the value of the line read in.
- }
-
- sub read_textfile {
- # Read in an entire non-HTML text file.
- # Sets $_ to the file contents, and returns $_'s value.
- # Performs substitutions so that "special" HTML characters
- # come out correctly (&, <, etc.)
- m/^ *<TEXT .*FILE="([^"]*)"/i;
- $text_filename=$1;
- if (m/FONT=PRE/i) {$use_pre=1}
- else {$use_pre=0};
- $file_contents = "";
- if ($use_pre) {$file_contents .= "<PRE>\n"};
- print " Incorporating text (non-HTML) file ${text_filename}.\n";
- if (!open(TEXTFILE, "<${text_filename}"))
- {die "Sorry, cannot open text file ${text_filename}"};
- while (<TEXTFILE>) {
- # Substitute special HTML characters.
- s/\&/&/g; # & becomes &
- s/\</</g; # < becomes <
- s/\>/>/g; # > becomes >
- # Do _NOT_ substitute the double-quote character (" into ")
- # Windows NCSA Mosaic version 2.0 alpha 2 doesn't handle it,
- # and all the browsers I can find can display them quite well.
- # s/\"/"/g; # " becomes "
- $file_contents .= $_; # Add the contents.
- }
- close(TEXTFILE);
- if ($use_pre) {$file_contents .= "</PRE>\n"};
- $_ = $file_contents; # Set the value, and return it.
- }
-
- sub process_choices {
- # Process the choices portion of a question in a section.
-
- # It must be of the form:
- # <CHOICES>
- # <CHOICE ANS=1>Text_IO
- # </CHOICES>
- # <ANSWER ANS=2>
- # Note: the numbers in the <CHOICE> item are ignored.
-
- die "CHOICES section expected." unless /^<CHOICES/;
-
- print SECTION "<OL>\n";
- $choice_number = 0;
- while (!eof(IN)) {
- &read_line;
- if (/^<\/CHOICES/) {last};
- if (/^<CHOICE/) {
- $choice_number++;
- s/^<CHOICE[^>]*> *//i;
- chop;
- print SECTION '<LI><A HREF="' .
- "s${lesson_number}-${section_number_file_rep}" .
- "r${choice_number}${html_extension}\">";
- print SECTION $_;
- print SECTION "</A>\n";
- }
- else {die "Sorry, choice text must be on the same line as <CHOICE>."}
- }
- $number_of_choices = $choice_number;
-
- die "A Choice section must end with </CHOICES>" unless (/^<\/CHOICES>/i);
- &read_line;
-
- if (/^<ANSWER .*ANS=([0-9])+>/i) {
- $correct_answer = $1 + 0;
- } else {
- die "A Choice section must be followed with the answer, " .
- "format: <ANSWER ANS=number>";
- }
- &read_line; # Get the next line for the callee.
-
- &substitute_and_append("section.question.tail", "section");
- }
-
- sub process_optional_responses {
- # Process the optional response portion of a section:
- # <RESPONSES>
- # <WHEN ANS=1> ..text..
- # </RESPONSES>
- # A <SECTION> could also follow.
-
- # Skip blank lines, if any.
- while ($_ || !eof(IN)) {
- if (/<RESPONSES>/i) {last};
- if (/<SECTION/i) {last};
- chop;
- if ($_ ne "") {print "Warning: line ignored: $_\n"};
- &read_line;
- }
-
- if (/<RESPONSES>/i) {
- # We have a response section.
- $current_response = 0;
- while (&read_line) {
- if (/<\/RESPONSES>/i) {&read_line; last};
- if (/<WHEN .*>/i) {
- &close_response_if_necessary;
- if (/<WHEN ANS=[0-9]*>/i) {
- $current_response = $_;
- $current_response =~ s/^<WHEN *ANS=([0-9]+)>.*$/$1/i;
- chop($current_response);
- }
- else {
- if (/<WHEN CORRECT>/i) {$current_response = $correct_answer}
- else {die "Invalid WHEN clause"}
- };
- $set_response[$current_response] = 1; # Mark this response as found
- &open_response;
-
- # If there's text on the same line as the WHEN clause, put it
- # in the response file.
- s/^ *<WHEN[^>]*> *//i;
- chop;
- if ($_ ne "") {print RESPONSE "$_\n"};
- } else {
- # We got some text, presumably part of a response.
- if ($current_response == 0) {
- print "Warning: Responses not associated with a specific answer\n";
- print "Text is: $_";
- } else {
- print RESPONSE;
- }
- }
- }
- &close_response_if_necessary;
- }
- }
-
- sub open_response {
- # Open the response file & set the variable names referring to it.
- $response_filename="s${lesson_number}-${section_number_file_rep}" .
- "r${current_response}${html_extension}";
- if (!open(RESPONSE, ">${response_filename}.new"))
- {die "Sorry, cannot open response file ${response_filename}.new"};
- print " Opened response file ${response_filename}\n";
- $response_file_open = 1;
- &substitute_and_append("response.head", "response");
- }
-
- sub close_response_if_necessary {
- if ($response_file_open == 1) {
- if ($current_response == $correct_answer)
- {&substitute_and_append("response.correct.tail", "response");}
- else
- {&substitute_and_append("response.incorrect.tail", "response");};
- &substitute_and_append("response.tail", "response");
- close(RESPONSE);
- $response_file_open = 0;
- }
- }
-
- sub generate_default_responses {
- $current_response = 1;
- while ($current_response <= $number_of_choices) {
- if ($set_response[$current_response] == 0) {
- &open_response;
- # insert default text.
- if ($current_response == $correct_answer) {
- &substitute_and_append("response.correct.default", "response");
- } else {
- &substitute_and_append("response.incorrect.default", "response");
- }
- &close_response_if_necessary;
- }
- $current_response++;
- }
- }
-
- sub determine_next_section_URL {
- # Set $next_section_URL, $confirm_skip_to_next_section_URL
- if ($section_number == $number_of_sections) {
- $next_prefix = $next_lesson_location;
- $next_lesson_number = $lesson_number + 1;
- $next_section_file_rep = "1";
- }
- else {
- $next_prefix = "";
- $next_lesson_number = $lesson_number;
- $next_section_file_rep = $section_number + 1;
- if ($next_section_file_rep == $number_of_sections)
- {$next_section_file_rep = "f"};
- }
- $next_section_URL = "${next_prefix}s${next_lesson_number}" .
- "-${next_section_file_rep}${html_extension}";
-
- # Set $confirm_skip_to_next_section_URL, the URL to go to if
- # the user selects "skip" from a section.
-
- if ($lesson_number == 1 && $section_number == 1) {
- # For lesson 1, section 1, confirm the skipping of the quiz
- # by linking to the special file "skip1-1.html".
- $confirm_skip_section_URL = 'skip1-1' . $html_extension;
- } else {
- $confirm_skip_section_URL = $next_section_URL;
- };
- }
-
- sub determine_previous_section_URL {
- # Determine & set the value of:
- # $previous_section_URL
- # $the_previous_section_or_home
-
- $the_previous_section_or_home = $template{"the_previous_section_is_not_home"};
- if ( $the_previous_section_or_home == "" )
- { $the_previous_section_or_home = "the previous section" };
- local($template_text) = $template{ $template_chunk };
- if ($section_number == 1) {
- $previous_lesson_number = $lesson_number - 1;
- if ($lesson_number == 1) {
- # lesson 1, section 1 - the "previous" section is the home page.
- $previous_section_URL= $tutor_home_page_URL;
- $the_previous_section_or_home =
- $template{"the_previous_section_is_home"};
- if ( $the_previous_section_or_home == "" )
- { $the_previous_section_or_home = "the tutorial home page" };
- } elsif ($previous_lesson_location_set == 1) {
- $previous_section_URL= $previous_lesson_location . '/' .
- 's' . $previous_lesson_number . '-f' . $html_extension;
- } else {
- # No previous location set; must be current directory.
- $previous_section_URL= 's' . $previous_lesson_number . '-f' .
- $html_extension;
- }
- } else {
- $previous_lesson_number = $lesson_number;
- $previous_section_number = $section_number - 1;
- $previous_section_URL= 's' . $previous_lesson_number . '-' .
- $previous_section_number . $html_extension;
- }
-
- }
-
-
- sub move_in_new_files {
- # Move in all files with .new extensions to replace original files.
- # If desired, this can be modified so it only replaces "changed" files.
- print "\n";
- print "Replacing changed files, if any.\n";
- while (<*.new>) {
- $oldname = $_;
- $newname = $_;
- $newname =~ s/\.new$//;
- if (system("cmp -s $oldname $newname") != 0) {
- # The new file is different, remove the older one.
- print " Replacing $newname (with $oldname)\n";
- rename($newname, "${newname}.BAK"); # Keep older one, just in case.
- rename($oldname, $newname);
- } else {
- unlink($oldname);
- }
- }
- }
-
- sub change_timestamp_file {
- # Change the timestamp file. Parameter 1 is the input filename.
- # The timestamp is used so we'll know when this file was last generated.
- local($infile_name) = @_;
- $timestamp_filename = $infile_name;
- $timestamp_filename =~ s/\.les$//;
- $timestamp_filename .= ".tim";
- if (!open(TIMESTAMP_FILE, ">${timestamp_filename}"))
- {die "Sorry, cannot create timestamp file ${timestamp_filename}"};
- print TIMESTAMP_FILE "Lesson Generated.\n";
- close(TIMESTAMP_FILE);
- }
-
- sub read_in_template {
- # Read in file "template", putting results in associative array %template
- local($current_template_unit);
- $current_template_unit = "garbage";
- if (!open(TEMPLATE, "<template"))
- {die "Sorry, cannot find a local file named template."};
- while (<TEMPLATE>) {
- if (/^===== (\S+) =====/)
- {$current_template_unit = $1;}
- elsif ($current_template_unit eq "comment")
- {} # Do nothing with comments.
- elsif ($current_template_unit eq "garbage")
- {print "WARNING: Garbage line in file template: $_";}
- else { $template{$current_template_unit} .= $_; } # Append to assoc array.
- };
- close(TEMPLATE);
-
- # If debug on, print out the %template contents.
- if ($debug_template == 1) {
- print "DEBUG: Printing out template contents as read:\n";
- foreach $i (%template) {
- print "=====\n";
- print $i;
- print "\n";
- }
- }
- }
-
- sub reset_set_response {
- # Reset array "set_response", which stores the list of responses
- # set in this section by the user. This is used to determine
- # which responses should have "default" responses set for them.
-
- # Assume no more than 9 responses.
- @set_response = ( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
- $choice_number = 0;
- }
-
- sub initialize_variables {
- # Note - these are GLOBAL variables.
- $lesson_number = 0;
- $section_number = 0;
- $tutor_name="";
- $author_name="";
- $author_email="";
- $author_address="";
- $section_has_question = 0; # Does this section have a question? 0=false.
-
- $previous_lesson_location_set = 0;
- $previous_lesson_location ="";
-
- $next_lesson_location_set = 0;
- $next_lesson_location ="";
-
- $master_outline_set = 0;
- $master_outline_URL ="";
-
- $tutor_home_page_set = 0;
- $tutor_home_page_URL = "";
-
- $section_file_open = 0; # 0=false, 1=true.
- $response_file_open = 0;
- $current_response = 0;
-
- # Determine today's date and year.
- ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
- localtime(time);
- $mon++; # Month was returned as 0-11, so we need to fix it.
- # Determine 4-digit year; recode in 2090.
- if ($year < 90) { $year += 2000 } else { $year += 1900 };
- $todays_date = $year . "." . $mon . "." . $mday . " (YY.MM.DD)";
- $todays_year = $year;
- print "Today's date is ${todays_date}; year is $todays_year\n";
- }
-
- sub open_lesson_file {
- # Get lesson file name and find out how many sections it has.
- if (!open(IN, "<$lesson_source"))
- {die "Sorry, cannot open input file ${lesson_source}"};
- $number_of_sections=0;
- while (<IN>) {
- if (m/^<SECTION /i) {$number_of_sections++};
- };
- close(IN);
- print "There are $number_of_sections sections in " .
- "lesson file ${lesson_source}.\n";
- if (!open(IN, "<$lesson_source"))
- {die "Cannot re-open input file ${lesson_source}"};
- }
-
- sub read_in_defaults {
- # If it exists, load in the file "defaults" as a lesson header file.
- # This makes it easier to create 'standard defaults' for a specific
- # tutorial.
- if (open(IN, "<default")) {
- print "Default file found; processing it first.\n";
- &process_input_header;
- close(IN);
- } else {
- print "(No default file found.)\n";
- }
- }
-
-
- # Potential projects:
- # ?? Process <INCLUDE >
- # ?? Clean up code (use perl shortcuts, examine for EOF).
- # ?? Error check input. For head, warn of unused.
- # ?? More error checking in body processing.
-