home *** CD-ROM | disk | FTP | other *** search
/ BURKS 2 / BURKS_AUG97.ISO / BURKS / LANGUAGE / ADA / LOVELACE / mklesson < prev    next >
Text File  |  1997-04-08  |  29KB  |  847 lines

  1. #!/usr/local/bin/perl -s
  2. # This is mklesson, a `lesson compiler.'
  3. # Mklesson takes a lesson file (.les) as its sole argument, and uses it to
  4. # generate a set of hypertext tutor files in HTML (.html) format.
  5. # The generated files are created in the current directory.
  6. # Status information is sent to standard output (which is usually the screen).
  7. #
  8. # Usage Example:
  9. #     mklesson lesson9.les
  10. #
  11. # Options:
  12. #   -a  alphabetic filenames (use "s" instead of "-" in
  13. #       generated filenames)
  14. #   -b  book
  15. #   -d  define (not implemented)
  16. #   -s  short filenames (.htm instead of .html)
  17. #
  18. # If you're generating ISO 9660 CD-ROMS, use "-s -a".
  19. #
  20. # $Id: mklesson,v 1.15 1995/08/09 21:07:40 wheeler Exp $
  21. #
  22. # See the user's guide in file userg.html and formatmk.txt.
  23. #
  24. # Input:
  25. #   (argument 1) -- filename of lesson (.les) file.
  26. #   template -- file with templates used for file generation.
  27. #   default  -- if this file exists, it is read to find default settings
  28. #               (its format is identical to a lesson header section).
  29. #
  30. # Output: The program generates files with the following naming patterns:
  31. #    sLESSON-SECTION.html  - text for lesson number LESSON, section SECTION.
  32. #                            If this is the last one, SECTION is "f" (final)
  33. #                            so that the next lesson can always link
  34. #                            backwards correctly (didn't use "l" for last,
  35. #                            because it looks too much like a "1").
  36. #    sLESSON-SECTIONrRESPONSENUMBER.html - text for response RESPONSENUMBER
  37. #    lessonLESSON.html    - lesson outline.
  38. #
  39. #    With the "-a" option, the dashes above become "s".
  40. #
  41. #
  42. # This program is written in the programming language perl because it's
  43. # a relatively short program that performs text processing (a perl strength),
  44. # and I wanted it to be VERY portable (perl is widely available).
  45. # Perl has some disadvantages, in particular, please be careful modifying
  46. # this program because the Perl language syntax is so awful that it's
  47. # as though it was designed to maximize error creation.
  48. #
  49. # Copyright (C) 1994 David A. Wheeler.
  50. #
  51. #    This program is free software; you can redistribute it and/or modify
  52. #    it under the terms of the GNU General Public License as published by
  53. #    the Free Software Foundation; either version 2 of the License, or
  54. #    (at your option) any later version.
  55. #
  56. #    This program is distributed in the hope that it will be useful,
  57. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  58. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  59. #    GNU General Public License for more details.
  60. #
  61. #    You should have received a copy of the GNU General Public License
  62. #    along with this program; if not, write to the Free Software
  63. #    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  64. #
  65. # Since mklesson is free software, if you modify this program and
  66. # then distribute it (or results generated from it) you ARE REQUIRED
  67. # to distribute & permit anyone to copy the modified version of this program.
  68. #
  69. # You CAN use this program to generate
  70. # proprietary tutorials, just as you can use gcc to generate
  71. # proprietary executables. See the GPL for more information.
  72.  
  73.  
  74. # START OF MAIN PROGRAM
  75.  
  76. if (defined($s)) {
  77.    # a "-s" option uses Short extension names (.htm).
  78.    $html_extension = ".htm";
  79. }
  80. else {
  81.    # without a "-s" option, generate ".html" extensions.
  82.    $html_extension = ".html";
  83. }
  84.  
  85. # This version has primitive support for preprocessing commands of form:
  86. # <IFDEF BOOK>
  87. # [<ELSE> ... ]
  88. # <ENDIF>
  89. # In the long term I'd like to support arbitrary preprocessing "define"
  90. # flags, but for now there only one flag, "BOOK".
  91. # You can set "BOOK" with the "-b" flag.
  92. # Eventually there will be another parameter to set arbitrary flags.
  93.  
  94. #  -b ("book") option.
  95. $is_book = 0;
  96. if (defined($b)) {
  97.  $is_book = 1;
  98. }
  99.  
  100. # book_state has one of three values:
  101. #   0 = normal text.
  102. #   1 = inside an <IFDEF BOOK>. Print only if $is_book.
  103. #   2 = inside an <ELSE> of <IFDEF BOOK>. Print only if not $is_book.
  104. $book_state = 0;
  105.  
  106. #  -a ("alphabetic") option.
  107. $alphabetic = 0;
  108. $separator= '-';
  109. if (defined($a)) {
  110.  $alphabetic = 1;
  111.  $separator= 's';
  112. }
  113.  
  114.  
  115. &initialize_variables;
  116. &read_in_template;  # Load the template file into memory.
  117. &read_in_defaults;  # Load the contents of file "default".
  118.  
  119. # Open & process the lesson file.
  120. $lesson_source=shift;
  121. &open_lesson_file;
  122. &process_input_header;
  123. &process_input_body;
  124. &change_timestamp_file($lesson_source);
  125.  
  126. &move_in_new_files;
  127.  
  128. # END OF MAIN PROGRAM
  129.  
  130.  
  131. # SUBROUTINES:
  132.  
  133. sub process_input_header {
  134.  # Process input file as a lesson header section.
  135.  # Stop processing at end-of-file or a <SECTION> marker.
  136.  # (The input file could be a "lesson" file or "default" file)
  137.  
  138.  while (&read_line) {
  139.   if (m/^ *<TUTOR .*NAME="([^"]*)"/i) {
  140.     if (($tutor_name ne "") && ($tutor_name ne $1) )
  141.        {die "Cannot redefine tutor name"};
  142.     $tutor_name=$1;
  143.     print "Tutor name is $tutor_name\n";
  144.     }
  145.   elsif (m/^ *<LESSON .*NUMBER=([0-9]+)/i) {
  146.    if ($lesson_number != 0) {die "Cannot redefine lesson number"};
  147.    $lesson_number=$1;
  148.    $lesson_outline_URL = "lesson${lesson_number}" . $html_extension;
  149.    print "Lesson number is $lesson_number\n";
  150.    }
  151.   elsif (m/^ *<AUTHOR .*NAME="([^"]*)".*EMAIL="([^"]*)"/i) {
  152.    $author_name=$1;
  153.    $author_email=$2;
  154.    print "Author name is $author_name\n";
  155.    print "Author email (address) is $author_email\n";
  156.    }
  157.   elsif (m/^ *<AUTHOR .*ADDRESS="(.*)">$/i) {
  158.    # Note: this format is slightly different, grabbing the ENTIRE line.
  159.    # This is so that the address can include anchors and such, which
  160.    # require the use of " and > characters.
  161.    $author_address=$1;
  162.    print "Author address is $author_address\n";
  163.    }
  164.   elsif (m/^ *<PREVIOUS_LESSON .*LOCATION="([^"]*)"/i) {
  165.    if ($previous_lesson_location_set != 0)
  166.        {die "Cannot redefine previous lesson location"};
  167.    $previous_lesson_location = $1;
  168.    $previous_lesson_location_set = 1;
  169.    print "Previous lesson location is $previous_lesson_location\n";
  170.    }
  171.   elsif (m/^ *<NEXT_LESSON .*LOCATION="([^"]*)"/i) {
  172.    if ($next_lesson_location_set != 0)
  173.       {die "Cannot redefine next lesson location"};
  174.    $next_lesson_location = $1;
  175.    $next_lesson_location_set = 1;
  176.    print "Next lesson location is $next_lesson_location\n";
  177.    }
  178.   elsif (m/^ *<MASTER_OUTLINE .*HREF="([^"]*)"/i) {
  179.    if ($master_outline_URL_set != 0)
  180.      {die "Cannot redefine master lesson outline URL"};
  181.    $master_outline_URL = $1;
  182.    $master_outline_URL_set = 1;
  183.    print "Master outline URL is $master_outline_URL\n";
  184.    }
  185.   elsif (m/^ *<TUTOR_HOME_PAGE .*HREF="([^"]*)"/i) {
  186.    if ($tutor_home_page_set != 0) {die "Cannot redefine tutor home page URL"};
  187.    $tutor_home_page_URL = $1;
  188.    $tutor_home_page_URL_set = 1;
  189.    print "Tutor home page URL is $tutor_home_page_URL\n";
  190.    }
  191.   elsif (m/^ *<TUTOR_MASTER_COPY_URL .*HREF="([^"]*)"/i) {
  192.    if ($tutor_master_copy_URL_set != 0)
  193.      {die "Cannot redefine tutor master copy URL"};
  194.    $tutor_master_copy_URL = $1;
  195.    $tutor_master_copy_URL_set = 1;
  196.    print "Tutor master copy URL is $tutor_master_copy_URL\n";
  197.    }
  198.   elsif (m/^<SECTION /i) {last}
  199.   elsif (m/^ *$/) {} # Do nothing with blank lines.
  200.   else {
  201.     print "WARNING: LINE IN HEADER OF FILE IGNORED, TEXT IS:";
  202.     print $_;
  203.   }
  204.  }
  205.  # We found a SECTION header or end of file. Stop processing lesson header.
  206. }
  207.  
  208. sub process_input_body {
  209.   # Process body of a lesson file (it should have 2 or more sections).
  210.  
  211.   # Errorcheck - we should have gotten TUTOR, LESSON, and AUTHOR.
  212.  
  213.   if ($lesson_number < 1)
  214.      {die "Sorry, no valid lesson number encountered!"};
  215.  
  216.   # Set up constants used in the rest of the program & open outline file.
  217.   # This is the filename for the generated outline.
  218.   $lesson_outline = "lesson${lesson_number}" . $html_extension;
  219.   if (!open(OUTLINE, ">${lesson_outline}.new"))
  220.     {die "Sorry, cannot open output lesson outline file ${lesson_outline}"};
  221.   &substitute_and_append("outline.head", "outline");
  222.  
  223.   # Process body of .les file.
  224.  
  225.   while ($_ ne "") {  # While there's still some text to process.
  226.     if (m/^<SECTION /i) { &process_section; }
  227.     else { print "Warning: text ignored outside of a