#! /usr/bin/perl -T # # This script is used for formatting the GNO FAQ. # # $Id: mkfaq,v 1.10 1998/01/22 14:53:10 gdr Exp $ # $src = "FAQ.gno.src"; # the name of the FAQ source file $dest = "csa2g.FAQ.txt"; # the name of the text output file $html = "csa2g.FAQ.html"; # the name of the html output file $ContactName = "Devin Reade"; $ContactEmail = "gdr\@eddore.myrias.com"; $totalSections = 0; # the number of sections in the FAQ $totalQuestions = 0; $currentQuestion = 0; $tocLines = 0; # number of lines in table of contents $lastmapping = 0; # used in &map() $SectionNumber = 0; # number of the current section $MaxSections = 0; # total number of sections # # open the output files # open (outfp, "> $dest") || die("couldn't open output file $dest"); open (outfp2, "> $html") || die("couldn't open output file $html"); $faq = "GNO Frequently Asked Questions (FAQ) List"; printf(outfp2 "\n" . "\n" . "" . $faq . "\n" . "\n" . "\n" . "

" . $faq . "

\n"); # # First pass -- get the table of contents and figure out what the # question number mappings are. # open (fp, $src) || die("couldn't open $src (1)"); $_ = ; do { chop; if ( /^%Section%\s*(.+):/ ) { &addSection($1); &addSectionHTML($1); } elsif ( /^Q\#(\d+):\s+(.*)/ ) { $originalLine = int($1); $newLine = &map($originalLine); $question = $2; while () { (/^\s*$/) && last; $question .= $_; } if (defined($orgLineList[$originalLine])) { printf(stderr "%s:%d: duplicate question number Q\#%d\n", $src, $. -1, $originalLine); } else { $orgLineList[$originalLine] = 1; } &addTOCEntryHTML ($newLine, $question); $junk = sprintf("Q\#%s", $newLine); if (length($junk) < 7) { $padding = "\t"; } else { $padding = " "; } $question = sprintf("\t%s:%s%s\n", $junk, $padding, &fmt(2,$question)); &addTOCEntry ($question); } elsif ( /^%RCS-ID%\S+\s+\S+\s+(\S+)\s+(\S+)\s(\S+)/ ) { $version = $1; $date = $2; $time = $3; } } while (); close(fp); # # Second pass -- print out the results, doing mappings as necessary # $SectionNumber = 0; open (fp, $src) || die("couldn't open $src (2)"); $in_header = 0; $in_body = 0; while() { if (/^%Header-start%\s*$/) { $in_header = 1; printf(outfp2 "Version: %s
\n" . "Last Modified: %s %s
\n" . "
\n" . "

Preamble

\n" . "
\n", $version, $date, $time);
    } elsif (/^%Header-end%\s*$/) {
	$in_header = 0;
	printf(outfp2 "
\n

\n"); } elsif (/^%FAQ-http-addr%(.*)%$/) { $faq_http = $1; } elsif (/^%FAQ-ftp-addr%(.*)%$/) { $faq_ftp = $1; } elsif (/^%FAQ-log-http-addr%(.*)%$/) { $faqlog_http = $1; } elsif (/^%FAQ-log-ftp-addr%(.*)%$/) { $faqlog_ftp = $1; # } elsif (/%Version%\s*$/) { # printf(outfp "Version:\t%s\n", $version); # } elsif (/%Last-Modified%\s*$/) { # printf(outfp "Modified:\t%s %s\n\n", $date, $time); } elsif (/^%TOC%\s*$/) { &printTOC(); } elsif (/^%Section%\s*(.+):\s*$/) { # found a section header $SectionNumber++; &PrintSection($1); $_ = ; # ditch the old underlining $in_body = 1; } elsif ($in_header || $in_body) { s,\%Version\%,$version,; s,\%Last\-Modified\%,$date $time,; s,\%FAQ-FTP\%,$faq_ftp,; s,\%FAQ-HTTP\%,$faq_http,; s,\%LOG-FTP\%,$faqlog_ftp,; s,\%LOG-HTTP\%,$faqlog_http,; &PrintLine($_); } } # print trailing info printf(outfp2 "
\n" . "%s\n" . "<%s>\n" . "\n" . "\n", $ContactName, $ContactEmail, $ContactEmail); # clean up close(fp); close(outfp); close(outfp2); # # Subroutines # sub map { local ($old); $old = @_[0]; if ($mappings[$old] == 0) { $lastmapping++; $mappings[$old] = sprintf("%d.%d", $SectionNumber, $lastmapping); } return $mappings[$old]; } sub addTOCEntry { local($line, $first, $num, $num2, $last); $line = $_[0]; $toc[$tocLines++] = $line; $tocLines++; } sub addTOCEntryHTML { local($line, $num, $entry); local($first, $num2, $last); $num = $_[0]; $line = $_[1]; $line = &text2html($line); $line =~ s/[\s\n]+/ /g; $tag = $num; $tag =~ s/\./_/g; $entry = sprintf("
  • Q%s: %s\n", $tag, $num, $line); $htmlQuestion{$num} = "$line"; push(@htmlTOC, "$entry"); return 0; } sub addSection { local ($underline, $len, $i); &addTOCEntry ("\n\t" . @_[0] . "\n"); $underline = "\t"; $len = length(@_[0]); for ($i = 0; $i < $len; $i++) { $underline .= '^'; } $underline .= "\n"; $lastmapping = 0; # reset the question numbers for new section &addTOCEntry ($underline); } sub addSectionHTML { local ($entry, $arg, $tail); $arg = $_[0]; $arg = &text2html($arg); $MaxSections++; $SectionNumber++; $SectionNames[$SectionNumber] = $arg; $tail = ''; ($SectionNumber > 1) && ($tail = ""); $entry = sprintf("%s\n" . "

    Section %d: %s

    \n" . "
      \n", $tail, $SectionNumber, $SectionNumber, $arg); push(@htmlTOC, "$entry"); } sub printTOC { local ($i, $l); # print out the text TOC printf (outfp "Table of Contents\n" . "=================\n"); for ($i=0; $i < $tocLines; $i++) { printf (outfp "%s", $toc[$i]); } printf(outfp "\n"); # print the html TOC printf (outfp2 "

      Table of Contents

      \n"); print outfp2 @htmlTOC; printf (outfp2 "


    \n\n"); # finish off the last list } # # Print the section name. For the text version, underline the name. # Takes one argument, the section name. # sub PrintSection { local($sname, $len, $i); $sname = @_[0]; # Do the text version printf(outfp "%s\n", $sname); $len = length($sname); for ($i=0; $i<$len; $i++) { printf (outfp "-"); } printf(outfp "\n"); # Do the html version $sname = &text2html($sname); ($SectionNumber > 1) && printf(outfp2 "\n"); printf(outfp2 "\n
    \n\n" . "

    Section %d: %s

    \n\n", $SectionNumber, $SectionNumber, $sname); } # # Print a line that's in the header or body. Takes one argument, the # raw line. # sub PrintLine { local($line, $rest); $line = @_[0]; # do a concheck and print out the text version $qora = ''; if ($line =~ /^([QA])\#\d+:(.*)/) { $qora = $1; $rest = $2; ($rest =~ /^\t/) || printf(stderr "%s:%d: missing leading tab\n", $src, $. -1); } $line =~ s/([QA])\#(\d+)/"$1#".&map($2)/ge; printf (outfp "%s", $line); if ($qora eq 'Q') { do { $line = ; $line =~ s/([QA])\#(\d+)/"$1#".&map($2)/ge; printf (outfp "%s", $line); } until ($line =~ /^\s*$/); } # do the html version $line = &text2html(@_[0]); if ($line =~ /^([QA])\#(\d+):(.*)/) { # start of a question or answer $qora = $1; $num = $2; $rest = $3; if ($qora eq 'Q') { printf(outfp2 "

    Q\#%s: %s

    \n
    \n", 
    		   &mapnum(&map($num)), &map($num), $htmlQuestion{&map($num)})
    	} else {
    	    $rest =~ s,Q\#(\d+),
    	    'Q#'.&map($1).'',ge;
    	    $rest =~ s/^\t//;
    	    printf(outfp2 "%s\n", $rest);
    	}
        } else {
    	$line =~ s,Q\#(\d+),'Q#'.&map($1).
    	    '',ge;
    	$line =~ s/^\t//;
    
    	# replace http:// and ftp:// with the link equivalents
    	$line =~ s,(http|ftp)://(\S+),''.$1.'://'.$2.'',ge;
    
    #	$line =~ s,ftp://(\S+),'http://'.$1.'',ge;
    	printf (outfp2 "%s", $line);
        }
    
    }
    
    sub mapnum {
        local($num);
    
        $num = @_[0];
        $num =~ s/\./_/g;
        return $num
    }
    
    #
    # &fmt (tabs, text)
    #
    # This routine formats the specified text to fall within 76 columns,
    # and indents the text with the specified number of tabs (considered
    # to be 8 characters wide).
    #
    # The first line will _not_ be preceeded by any tabs, even though
    # the length will be calculated as if it is.
    #
    sub fmt {
        local (@array, $tabs, $line, $columns, $result, $tablen, $linelen);
        local ($word, $len, $i);
        $tabs = int(@_[0]);
        $line = @_[1];
        $columns = 76;		# maximum column number to print
        $tablen  = 8;		# spaces per tab
    
        $line =~ s/\s+/ /g;
    
        @array = split ("[ \t]+", $line);
        $result = '';
        $linelen = 0;
        for ($i = 0; $i < $tabs; $i++) {
    	$linelen += $tablen;
        }
        foreach $word (@array) {
    	$len = length($word);
    	if ($columns - $linelen > $len) {
    	    # add it into the current line
    	    if ($linelen == $tablen * $tabs) {
    		$result .= $word;
    		$linelen += $len;
    	    } else {
    		$result .= ' ' . $word;
    		$linelen += $len + 1;
    	    }
    	} else {
    	    # start a new line
    	    $result .= "\n";
    	    $linelen = 0;
    	    for ($i = 0; $i < $tabs; $i++) {
    		$result .= "\t";
    		$linelen += $tablen;
    	    }
    	    $result .= $word;
    	    $linelen += $len;
    	}
        }
        return $result;
    }
    
    #
    # Translates HTML special character sequences into their "escaped" formats
    #
    sub text2html {
        local($line);
    
        $line = @_[0];
    
        $line =~ s//>/g;
        $line =~ s/"/"/g;
        return $line;
    }