home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BURKS 2
/
BURKS_AUG97.ISO
/
BURKS
/
LANGUAGE
/
ADA
/
LOVELACE
/
mklesson
< prev
next >
Wrap
Text File
|
1997-04-08
|
29KB
|
847 lines
#!/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
#
# Options:
# -a alphabetic filenames (use "s" instead of "-" in
# generated filenames)
# -b book
# -d define (not implemented)
# -s short filenames (.htm instead of .html)
#
# If you're generating ISO 9660 CD-ROMS, use "-s -a".
#
# $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.
#
# With the "-a" option, the dashes above become "s".
#
#
# 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";
}
# This version has primitive support for preprocessing commands of form:
# <IFDEF BOOK>
# [<ELSE> ... ]
# <ENDIF>
# In the long term I'd like to support arbitrary preprocessing "define"
# flags, but for now there only one flag, "BOOK".
# You can set "BOOK" with the "-b" flag.
# Eventually there will be another parameter to set arbitrary flags.
# -b ("book") option.
$is_book = 0;
if (defined($b)) {
$is_book = 1;
}
# book_state has one of three values:
# 0 = normal text.
# 1 = inside an <IFDEF BOOK>. Print only if $is_book.
# 2 = inside an <ELSE> of <IFDEF BOOK>. Print only if not $is_book.
$book_state = 0;
# -a ("alphabetic") option.
$alphabetic = 0;
$separator= '-';
if (defined($a)) {
$alphabetic = 1;
$separator= 's';
}
&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/^ *<TUTOR_MASTER_COPY_URL .*HREF="([^"]*)"/i) {
if ($tutor_master_copy_URL_set != 0)
{die "Cannot redefine tutor master copy URL"};
$tutor_master_copy_URL = $1;
$tutor_master_copy_URL_set = 1;
print "Tutor master copy URL is $tutor_master_copy_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