#!/usr/local/bin/perl # make_faq v. 15 Nov 94, Dave Schweisguth # Usage: make_faq [-name foo] [-test] file # or cat file | make_faq -name foo [-test] # parts/{70-hyphens,header.{pointer,real,test},preamble,trailer} must exist! ### Preliminaries require "ctime.pl"; ($whatami = $0) =~ s|.*/||; # `basename $0` $isatty = -t STDIN; chop($date = &ctime(time)); $header = 'real'; while ($ARGV[0] =~ /^-/) { if ($ARGV[0] eq '-test') { shift; $header = 'test'; } elsif ($ARGV[0] eq '-name') { shift; $group = shift; die "$whatami: -name requires an argument.\n" unless $group ne ''; } else { die "$whatami: $ARGV[0] is not a valid option.\n"; } } if (@ARGV == 0) { die "$whatami: Please provide an input FAQ via STDIN or on the command line.\n" if $isatty; die "$whatami: You must specify a name with -name.\n" unless $group ne ''; $file = 'STDIN'; } elsif (@ARGV == 1) { $file = $ARGV[0]; open($file, $file) || die "$whatami: Can't open $file!\n"; ($group = $file) =~ s|.*/|| unless $group ne ''; # `basename $file` } else { die "$whatami: Please specify one and only one file.\n"; } # Use pointer header for pointer FAQ if ($header eq 'real' && $group eq 'pointer') { $header = $group; } ### Process and print stuff # Header/preamble &sub_and_print("parts/header.$header", 'parts/preamble'); # Body # Read FAQ into @body, reformatting Subject: lines and joining cont. lines $/ = "\n\n"; # Paragraph mode $* = 1; # Multi-line matching while (<$file>) { # Identify header paras and split them up if ((($mark, $subject, $date) = /^Subject:\s*([+!\-]?)\s*([\s\S]*)\n(Date:.*\n\n)/) || (($mark, $subject, $date) = /^Subject:\s*([+!\-]?)\s*([\s\S]*)\n(\n)/)) { $subject =~ s/\s*\n\s*/ /g; # Join continuation lines push(@body, # Rebuild subject line into @body 'Subject: ' . ($mark || ' ') . # +, ! or ' ' ' ' x (3 - length(++$item)) . # Pad out to two digits "-$item- $subject", # Item number and subject text $date); # Date gets its own @body element } else { push(@body, $_); # Just save into @body } } $/ = "\n"; # Back to line mode $* = 0; # Back to single-line matching # TOC format NO_SUBJECT = ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $line ~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $line . $~ = 'NO_SUBJECT'; # Bind NO_SUBJECT format to STDOUT foreach (@body) { next unless /^Subject: /; $line = $'; # The rest of the line write; } # 70-hyphen line (i.e. stuff between the TOC and body) open(IN, 'parts/70-hyphens') || die "$whatami: Couldn't open parts/70-hyphens!\n"; print ; close IN; # Print @body, filling Subject: lines as we go format SUBJECT = ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $line ~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $line . $~ = 'SUBJECT'; # Bind SUBJECT format to STDOUT foreach (@body) { if (/^Subject:/) { $line = $_; write; # format will use $_ } else { print; # Not a subject; leave it alone } } # Trailer &sub_and_print('parts/trailer'); ### Subroutines # Do substitutions in and print files in @_ sub sub_and_print { @ARGV = @_; while (<>) { s/DATE/$date/g; # `sed s/DATE/$date/g` s/GROUP/$group/g; # `sed s/GROUP/$group/g` print; } }