Admin/page/bin/genpage
changeset 16302 322e2a3335d4
parent 16301 f9f2e1643593
child 16303 fee0a02f61bb
equal deleted inserted replaced
16301:f9f2e1643593 16302:322e2a3335d4
     1 #!/usr/bin/perl -w
       
     2 
       
     3 # Genpage - Webpage Generator.
       
     4 #
       
     5 # Copyright (C) Joe Vaughan <joev@freddyfrog.com> 1998-1999
       
     6 # Some portions Copyright (C)  Ronan Waide <waider@waider.ie> 1999
       
     7 # Some portions Copyright (C)  Rocco Caputo <troc@netrus.net> 1999
       
     8 # 
       
     9 #   This program is free software; you can redistribute it and/or modify
       
    10 #   it under the terms of the GNU General Public License as published by
       
    11 #   the Free Software Foundation; either version 2 of the License, or
       
    12 #   (at your option) any later version.
       
    13 #   
       
    14 #   This program is distributed in the hope that it will be useful,
       
    15 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    16 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    17 #   GNU General Public License for more details.
       
    18 #   
       
    19 #   You should have received a copy of the GNU General Public License
       
    20 #   along with this program; if not, write to the Free Software
       
    21 #   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
       
    22 
       
    23 $|=1;
       
    24 
       
    25 $version = "1.0b3";
       
    26 
       
    27 # following fix for Mac Perl submitted by Dair Grant <dair@webthing.net>
       
    28 # I shoulda thought of this, but I don't have a mac :) Thanks Dair.
       
    29 #  
       
    30 # dair, construct a path procedurally
       
    31 sub build_path
       
    32 {
       
    33 
       
    34     # Retrieve our parameters
       
    35     #
       
    36     my $thePath = $_[0];
       
    37     my $theItem = $_[1];
       
    38 
       
    39 
       
    40 
       
    41     # If we're running on a Mac, munge the path/item/separator
       
    42     #
       
    43     if ($^O eq "MacOS")
       
    44         {
       
    45         $thePath =~ s/:$//;     # Strip off trailing ':'
       
    46         $theItem =~ s/^:$//;    # Drop theItem == ':'
       
    47         $pathDiv  = ":";        # Use Mac separator
       
    48         }
       
    49     else
       
    50         {
       
    51         $pathDiv = "/";         # Use Unix separator
       
    52         }
       
    53 
       
    54 
       
    55 
       
    56     # Return the path to the item
       
    57     #
       
    58     return($thePath . $pathDiv . $theItem);
       
    59 }
       
    60 
       
    61 
       
    62 
       
    63 # Some handy variables.
       
    64 $numfiles = 0;
       
    65 $numcontentfiles = 0;
       
    66 $numignoredfiles = 0;
       
    67 $numskippedfiles = 0;
       
    68 $numcpfiles = 0;
       
    69 $numdirfiles =0;
       
    70 
       
    71 use Getopt::Std;
       
    72 use File::Find;
       
    73 use File::Copy 'cp';
       
    74 
       
    75 # Current Working Dir.
       
    76 $pwd = `pwd`;
       
    77 chomp ($pwd);
       
    78 
       
    79 getopts('dt:c:o:fqhi:') || die "Invalid args, use $0 -h for help\n";
       
    80 
       
    81 # $opt_d is debug flag
       
    82 # $opt_t is template file. If not set, use standard template.
       
    83 # $opt_c is content directory. If not set, use standard content dir.
       
    84 # $opt_o is output dir, if not set, use standard output dir.
       
    85 # $opt_q sets quiet mode (no stdout output)
       
    86 # $opt_f sets a force flag - force generation even if output file is present
       
    87 #        and newer.
       
    88 # $opt_h runs usage and exits
       
    89     
       
    90 # dair, build paths procedurally
       
    91 $opt_t ||= build_path("", "layout") . build_path("", "template.html");
       
    92 $opt_c ||= build_path("", "content");
       
    93 $opt_o ||= build_path("", "www");
       
    94 $opt_f ||= 0;
       
    95 $opt_d ||= 0;
       
    96 $opt_q ||= 0;
       
    97 $opt_h ||= 0;
       
    98 $opt_i ||= 'CVS|.*,v$';
       
    99 
       
   100 # dair, build paths procedurally
       
   101 $opt_t = build_path($pwd, $opt_t);
       
   102 $opt_c = build_path($pwd, $opt_c);
       
   103 $opt_o = build_path($pwd, $opt_o);
       
   104 
       
   105 
       
   106 if ($opt_h) { &usage; }
       
   107 
       
   108 if (!$opt_q) { 
       
   109   print "Genpage, version $version starting run...\n";
       
   110 }
       
   111 
       
   112 if ($opt_d) { print "pwd = $pwd\n"; }
       
   113 
       
   114 #Swallow template file whole... 
       
   115 open( TEMPLATE, "<$opt_t" ) || die "Can\'t open template file $opt_t: $!\n";
       
   116 { 
       
   117 local $/;
       
   118 undef $/;
       
   119 $template = <TEMPLATE>;
       
   120 close( TEMPLATE );
       
   121 }
       
   122 if (!$opt_q) {print "Using template file: $opt_t\n";}
       
   123 
       
   124 # Go through files in content dir and if it's a content file then 
       
   125 # process it otherwise, copy it (and it's dir structure) to the output dir.
       
   126 
       
   127 # if the output dir doesn't exist, create it.
       
   128 if (! -d $opt_o)
       
   129 { 
       
   130   mkdir $opt_o, 0755;
       
   131   if (!$opt_q) 
       
   132     {
       
   133       print "Creating output directory: $opt_o\n"; 
       
   134     }
       
   135 }
       
   136 
       
   137 if (!$opt_q) 
       
   138   {
       
   139     print "Processing files:\n"; 
       
   140   }
       
   141 
       
   142 if (! -d $opt_c) { die "Can\'t open content dir\n" }
       
   143 
       
   144 find( \&process_file, $opt_c );
       
   145 
       
   146 if (!$opt_q) 
       
   147   {
       
   148     #numfiles reports one too many...
       
   149     $numfiles--;
       
   150     print "\nFinished.\n\n";
       
   151     print "Run Summary.\n===========\n";
       
   152     print "$numfiles total files and directories processed.\n";
       
   153     print "$numcontentfiles content files parsed.\n";
       
   154     print "$numskippedfiles content files skipped.\n"; 
       
   155     print "$numcpfiles files copied.\n"; 
       
   156     print "$numdirfiles directories created\n"; 
       
   157     print "$numignoredfiles files or directories ignored.\n";
       
   158   }
       
   159 
       
   160 exit;
       
   161 
       
   162 ##############################################################################
       
   163 # Process_file the current file.
       
   164 ##############################################################################
       
   165 sub process_file
       
   166   {
       
   167     if (!$opt_q) 
       
   168       {
       
   169 	print "."; 
       
   170       }
       
   171 
       
   172     $numfiles++;
       
   173     my $filename = $_;
       
   174     my $dir = $File::Find::dir;
       
   175     (undef,$reldir) = split( $opt_c, $dir);
       
   176     if (!defined ($reldir) ) { $reldir = ""; }
       
   177 
       
   178     # dair, build paths procedurally
       
   179     $outdir  = build_path($opt_o,  $reldir);
       
   180     $outfile = build_path($outdir, $filename);
       
   181     $infile  = build_path($dir,    $filename);
       
   182 
       
   183     # Ignore CVS stuff, ./ etc.
       
   184     if ($infile =~ /$opt_i/) {
       
   185       $numignoredfiles++;
       
   186       return;
       
   187     }
       
   188 
       
   189     # Find returns ./ in each directory... avoid.
       
   190 
       
   191     if ($infile =~ /\/.$/) {
       
   192       return;
       
   193     }
       
   194     
       
   195     # Ok, If the file is a dir, we create it (if necessary)
       
   196     # if it's a content file, we parse it, otherwise, we
       
   197     # copy it to the appropriate location.
       
   198     
       
   199     if ( -d $infile ) {
       
   200       if ($opt_d) { print "Making dir $outfile\n"; };
       
   201       mkdir $outfile, 0755 unless -d $outfile;
       
   202       $numdirfiles++;
       
   203       return;
       
   204     }
       
   205     
       
   206     if ($filename =~ /^(.*)\.content$/) 
       
   207       {
       
   208 
       
   209     # dair, build paths procedurally
       
   210     $outfile = build_path($outdir, "$1.html");
       
   211 
       
   212 	if ($opt_d) {print "Parsing: $infile\n Outputing to: $outfile\n";};
       
   213 	process_content($infile,$outfile);
       
   214       }
       
   215     else
       
   216       {
       
   217 	if ($opt_d) { print "Copying: $infile => $outfile\n"; };
       
   218 	cp($infile,$outfile);
       
   219 	$numcpfiles++;
       
   220       }
       
   221     $_ = $filename; # because we broke it...
       
   222   }
       
   223 
       
   224 ##############################################################################
       
   225 # Process the tags in the template, substituting in the content file 
       
   226 # components and other things like inline function definitions and 
       
   227 # "include" directives
       
   228 ##############################################################################
       
   229  
       
   230 sub process_content
       
   231   {
       
   232     
       
   233     $inputfile = shift;
       
   234     $outputfile = shift;
       
   235     my @content = "";
       
   236    
       
   237     $temp = $template;
       
   238 
       
   239     if ($opt_d) { print "processing $inputfile to $outputfile\n";}
       
   240 
       
   241 # Make-like check for last modification times to see if it's necessary
       
   242 # to re-gen this page.
       
   243 
       
   244     if ( -f $outputfile) 
       
   245       {
       
   246 	   
       
   247 	if (!$opt_f && ( -M $outputfile < -M $inputfile)) 
       
   248 	  {
       
   249 	    $numskippedfiles++;
       
   250 	    if ($opt_d) { 
       
   251 	      print "skipping $inputfile because $outputfile is newer\n";
       
   252 	    }
       
   253 	    return;
       
   254 	  }
       
   255       }
       
   256     # Read content file
       
   257     open( CONTENT, "<$inputfile" ) || die $!;
       
   258     @content = <CONTENT>;
       
   259     close( CONTENT );
       
   260 
       
   261     $numcontentfiles++;
       
   262 
       
   263     undef %page;
       
   264     undef $tag;
       
   265     foreach $line ( @content )
       
   266       {
       
   267 	if ( $line =~ /^\s*\%(.+)\%/ )
       
   268 	{
       
   269 	  $tag = $1;
       
   270 	  next;
       
   271 	}
       
   272 	next if !defined( $tag );
       
   273 	
       
   274 	 $line .= "\n" if $line !~ /\n$/;
       
   275 	
       
   276 	if ( defined( $page{ $tag } ))
       
   277 	  {
       
   278 	    $page{ $tag } .= $line;
       
   279 	  }
       
   280 	else
       
   281 	  {
       
   282 	    $page{ $tag } = $line;
       
   283 	  }
       
   284       }
       
   285     
       
   286     open( HTML, ">$outputfile" ) || die $1;
       
   287     
       
   288     while ($temp =~ /^(.*?)<!--\s*_GP_\s*(.*?)\s*-->(.*)$/s)
       
   289       {
       
   290 	local $replacement = "";
       
   291 	my ($left, $middle, $right) = ($1, $2, $3);
       
   292         if (!defined($replacement = eval ($middle))) 
       
   293 	  { 
       
   294 	    $replacement = "";
       
   295 	  }
       
   296 	
       
   297 	if ($@) {
       
   298           $middle =~ s/\s+/ /g;
       
   299           print STDERR "error evaluating { $middle }: $@\n";
       
   300         }
       
   301         else {
       
   302           if ($opt_d) {
       
   303 	    print "evaluation output: $replacement\n";
       
   304 	  }
       
   305         }
       
   306 	
       
   307 	$temp = $left . $replacement . $right;
       
   308       }
       
   309     print HTML $temp;
       
   310     close( HTML );
       
   311   }
       
   312 
       
   313 
       
   314 sub include
       
   315   {
       
   316     my ($file) = shift;
       
   317     my ($section) = shift;
       
   318 
       
   319     if ($opt_d) { 
       
   320       print "include: file = $file\n"; 
       
   321     }
       
   322     if (!open( INCLUDE, "<$file" )) { 
       
   323       return "<!-- include: file not found: $file -->";
       
   324     }
       
   325     
       
   326     if (defined($section)) {
       
   327     undef %incpage;
       
   328     undef $inctag;
       
   329 
       
   330       @content = <INCLUDE>;
       
   331       close (INCLUDE);
       
   332 
       
   333       foreach $line ( @content )
       
   334 	{
       
   335 	  if ( $line =~ /^\s*\%(.+)\%/ )
       
   336 	    {
       
   337 	      $inctag = $1; 
       
   338 	      next;
       
   339 	    }
       
   340 	  next if !defined( $inctag );
       
   341 	  $line .= "\n" if $line !~ /\n$/;
       
   342 
       
   343 	  if ( defined( $incpage{ $inctag } ))
       
   344 	    {
       
   345 	      $incpage{ $inctag } .= $line;
       
   346 	    }
       
   347 	  else
       
   348 	    {
       
   349 	      $incpage{ $inctag } = $line;
       
   350 	    }
       
   351 	}
       
   352       if (defined( $incpage{$section}) ) {
       
   353 	$inline = $incpage{$section};
       
   354       }
       
   355       else {
       
   356 	$inline = "<!-- include: no such section - $section - in $file -->";  
       
   357       }
       
   358     } 
       
   359     else
       
   360       {	
       
   361 	local $/;
       
   362 	undef $/;
       
   363 	$inline = <INCLUDE>;
       
   364 	close( INCLUDE );
       
   365       }
       
   366     return "$inline";
       
   367   }
       
   368 
       
   369 sub content
       
   370   {
       
   371     my $tag = shift;
       
   372 
       
   373     if ($opt_d) { print "content: tag = $tag\n"; }
       
   374     if (defined( $page{ $tag } ))
       
   375       {      
       
   376 	$output = $page { $tag };
       
   377 	if ($opt_d) { print "content: output = $output\n"; }
       
   378 	return "$output";
       
   379       }
       
   380     else
       
   381       {
       
   382 	return "<!-- content: undefined tag: $tag -->";
       
   383       }
       
   384   }
       
   385 
       
   386 sub version
       
   387   {
       
   388     return ( "<a href=\"http://www.mnemonic.org/genpage/\">Genpage</a> - Version: $version" );
       
   389   }
       
   390 
       
   391 sub usage
       
   392   {
       
   393     print <<EOT;
       
   394 usage: genpage [-dqfh] [-c <content dir>] [-o <output dir>] 
       
   395                [-t <template file>] [ -i <ignore regexp> ]
       
   396 
       
   397 
       
   398        -d debug mode.     Turn on debugging (very verbose!)
       
   399        -q quiet mode.     Don't print anything while running.
       
   400        -f force mode.     Force the parsing of content files.
       
   401        -h help.           Print this help text.
       
   402        -c <content dir>   The directory where your content tree exists.
       
   403                           Defaults to ./content.
       
   404        -o <output dir>    The directory to put the output website.
       
   405                           Defaults to ./www
       
   406        -t <template file> The template to use to generate the site.
       
   407                           Defaults to ./layout/template.html
       
   408        -i <ignore regexp> Regular expression telling genpage to ignore certain
       
   409                           files or directories. defaults to "CVS|.*,v$"
       
   410 
       
   411        Genpage $version Copyright (C) Joe Vaughan <joev\@mnemonic.org> 1999
       
   412        This program is released under the terms of the GNU Public License
       
   413        Please read the accompanying COPYING file for details.
       
   414 
       
   415        For detailed instructions on how to use Genpage, please consult the 
       
   416        accompanying documentation. If you have questions, comments or 
       
   417        suggestions for Genpage please contact the author.
       
   418 EOT
       
   419 exit;
       
   420 }